ISA Interface Card - a starting point for numerous projects

Aaron Logue Oct 1999

This circuit came from Bruce Eckel's excellent article in the Sep/Oct 1988 issue of Micro Cornucopia. It's been the foundation of most circuits I've connected to a PC's ISA bus. It performs basic I/O port address decoding and data bus buffering, and works well as a building block for more complex circuits and software that use hardware IRQs and DMA to move data.

While the heart of this board is the circuit described on this page, you can see that I've glopped all sorts of other stuff onto this one. On the right is a connector that feeds the output of the two 74LS273 latches to a 16-bit D/A converter for audio, and at top is a connector that brings data in from some circuitry hacked into an audio CD player to let me pull the digital data off of audio CDs before it hits the D/A converter. The smaller chips on the board are glue logic that I added to do some DMA stuff, to issue IRQs, and to generate delayed pulses to tell other circuits when to do something interesting with the data available at the '273s.

ISA bus basics

The ISA bus consists of two connectors, one larger than the other. The larger 62-pin connector contains enough control signals, address, and data lines to support an 8-bit card. The smaller 36-pin connector adds 8 more data lines and additional IRQ and DMA control lines to support 16-bit cards. While I show a 16-bit card utilizing both connectors here, the design is easily adapted to an 8-bit card. This same circuit minus the second 74LS645 and the 74LS273s was the foundation for the 8-bit Z-80 board.
    MOV DX, 220h
    OUT DX, AX

When the above snippet of code is executed, the hex address 220 is placed on the address bus. That is, address lines A9 to A0 have 1000100000 on them. The higher 7 bits, lines A9 to A3 are brought to the 74LS682 chip. Its job is to hold pin 19 high (logic 1) until a match is seen between the address bus and the address selected on the I/O port jumper block. A shorted jumper will match a logic 0, and an open jumper will match a logic 1. The output of pin 19 can then be programmed to go low when any one block of 8 I/O ports is selected. That is, 000h, 008h, 010h, 018h, 020h, 028h, and so forth.

When pin 19 of the 74LS682 goes low, we know that one of the 8 I/O ports that this card sits on has been selected, but we still need to figure out which one, and whether the processor wants to read from it or write to it. To handle writes, I use the signal from pin 19 along with the ~IOW line on the ISA bus to enable a 74LS138 to decode the three remaining address lines and use them to drive one of eight outputs low. When output Y0 of my write-decoding 74LS138 goes low, the 74LS273's latch the contents of the data bus, holding the data for use by whatever circuitry follows. Reads are handled in a similar manner, but using the ~IOR line instead of ~IOW.

In practice, addresses are flying by on the ISA bus all the time, and it's very important that an adapter card does not interfere with the data bus until the processor actually wants it to. That's the job of the 74LS645s. When pin 19 from the 74LS682 is high, the 74LS645s essentially keep the adapter card disconnected from the data bus by remaining in a high impedence state. Only when pin 19 goes low will the 74LS645 buffers pass data in one direction or another depending on the state of ~IOR. I should point out that the use of ~IOR here is important - we want to have the 74LS645 buffers wired so that by default, they are reading from the system's data bus, and that they will only reverse direction and write to it when ~IOR goes low.

For 16-bit adapters, it is also necessary to pull ~IOCS16 low to let the motherboard know that the adapter is making use of the high 8 lines of the data bus. If we don't do this, the motherboard assumes we're an 8-bit card and an OUT AX, DX would try to transfer the word in AX using two 8-bit ~IOWs instead of one 16-bit ~IOW. I use one gate of a 74LS125 to yank on ~IOCS16 so that when the adapter is not selected, it is not interfering with ~IOCS16.

One important control line I've neglected to mention is AEN, or Address Enable. The I/O adapter card needs to wait until AEN is low before it becomes active and thinks the address on the address bus is selecting it, or else it will find itself being erroneously selected by ongoing DMA activity, which also uses the ~IOR line, but not in conjunction with an address. This may sound confusing, but it's pretty straightforward: When a DMA transfer is occurring and ~IOR is low, ~MEMW is also low and the address bus contains a memory address, not an I/O port address. This is how DMA moves a word of data from a hard disk controller's data port to a memory address in one shot, for example. While it's doing this, AEN is high, which our I/O adapter uses to keep from becoming active and corrupting the transfer.

An ISA interface card must perform two basic functions before it becomes minimally useful. The ten lowest address lines, A0-A9, need to be decoded in order to select one of 1024 ports that the card will respond to, and the data bus must be buffered so that the card will not interfere with existing signals on the data bus lines when the card is not selected.

Here are a couple shots of another board's construction.

I typically start by wiring up all the ground and power leads to the IC sockets, add the bypass capacitors, check with a multimeter to be sure there are no shorts or breaks, then add the address decoding lines. At that point, the board is ready for its first powered test.
With only the 74LS682 and the Read and Write 74LS138 chips in, the card is ready for a functionality test. A read or write to the card's IO ports should cause the appropriate 74LS138 output pin to toggle.
I use one of several old 286 or 386 machines I have sitting around. Here, I'm using SYMDEB to test a read of the card. The Y0 pin on the 74LS138 connected to the ISA ~IOR line should toggle once and only once when the IN AL,DX is executed.
My pulse counter verifies that I've performed three reads and one write to the card.

Back to Hardware/Projects page