Ruud's Commodore Site: ISA Expansion Home Email

ISA Expansion

What is it

ISA Epansion is a combination of ideas: replace the 6502 in your Commodore with its big brother, the 65816, and attach the well known Personal Computer ISA bus to it.

The basic ideas

I did some projects before combining the 65816 and ISA bus but some, like PC-card and PC-card 2, ended all up as "too complex to build" and others, like VIC-20 ISA bus, just weren't what I really wanted. What I didn't like about this last project was the way the ISA bus was fitted into the original memory range by using the paging method. Using a 65816 could solve this problem.

So far I only used regular TTL ICs for my designs. For this project I decided to use GALs. I made this decission after ending this project: "The VIC-20 Expanded". One single GAL was capable of replacing a dozen of ICs!

In earlier projects I used a 6522 and a lot of other ICs to deal with the ISA interrupts. Why didn't I use the Intel 8259? I don't know, maybe unfamiliarity? Anyway, I put it into the design as well. And immediatly the use of GALs paid off: in one of my first designs I could use some so far unused outputs to control the 8259.

The design

Have a look at 816ISA.png. As you can see I have choosen for the 16-bits ISA bus, first used in the IBM AT. It has 24 address lines and 16 data lines. The original 8-bits bus, used in the first IBM PCs, has only 20 address lines and 8 data lines. The 65816 is just an 8-bittter so why then still using the 16-bits ISA bus?
I have three reasons:
- It enables you to use the full 16 MB range of the 65816, compared to the 1 MB range of the 8-bits version.
- It enables you to use some interesting 16-bits cards like my favourite, the IDE hard disk card.
- The use of GALs made it quite simple te realise it.

The 16-bits ISA bus has 24 address lines. A0..15 will be supplied by the host system. The address lines A16..23 are supplied by the 65816 using the data bus: the moment PHI0 is (L), it contains the address bits A16..23. I use a 573 to latch them. The way the latch signal is generated will be explained later.

The 16-bits ISA bus has 16 data lines: D0..15. Eight bits, D0..7, are supplied by the host system's data bus and are buffered by a 245. D8..15 are supplied by D0..7 as well but with the help of two 573s as temporary buffer.
In case of a 16 bits write operation, the host system first latches the upper data bits D8..15 into the buffer. Writing the bits D0..7 to the ISA bus causes the PC hardware to read these bits as D0..7 plus plus reading the previously to the buffer written bits as D8..15 at the same time.
In case of a 16-bits read operation, the host system first reads the bits D0..7. D8..15 are stored in the temporary buffer at the same time and can be read at a later moment (but before the next 16-bits read operation).
This double-buffer circuit is used with succes on various cards enabling 8-bits systems to use the IDE hard drives.

As told before, a Intel 8259 Programmable Interrupt Controller takes care of the interrupt lines. Unfortunately it cannot be connected to a 6502 based system like that; it uses the Intel way of having a separate Read and Write line. These signals are generated by a GAL.
Another problem is that its interrupt output is active (H), in contrary to 65xx devices that output an active (L) one. A 7406 inverter gate solve this matter.

The ISA bus uses an active (H) reset signal. This is solved by using another 7406 gate and resistor to invert the original reset signal.

Warning: the design won't be able to handle memory cards that depend on the refresh serviced by the PC !!!

The three GALs - #1

I first need to generate a signal that tells the host system that its own devices, and not the ISA bus, are addressed. The way this signal, named ORG, is used will be explained later.
The Intel processors have a separated memory and I/O range, each with their own opcodes and signals. The 65xx processors don't and you have to map the I/O somewhere inside the total range. For example, for the Commodore 64 this is the well known $D000 - $DFFF range. I decided to make use of a complete 64 KB range for the I/O. That range could include both the PC I/O and the extra needed I/O for the original system.
Regarding the memory part: it is possible to use older 8-bits memory cards in the 16-bits bus because 16-bits and 8-bits cards each have their own memory select signals.
The resulting memory map: - $000000-$00FFFF = the original host system (ORG). - $010000-$017FFF = reserved for extra I/O, like the 16-bits buffer and 8259. - $018000-$01FFFF = reserved for the I/O of the ISA bus, two signals. - $020000-$FFFFFF = to be used as in a real AT computer, four signals.

Originally, just for generating ORG, I would use a 688 8-bits comperator: address lines on one site, the counter pins connected to GND, and the moment $00xxxx was addressed, the 688 would output a (L). But then what about the other signals, just more 688s and/or other ICs? If you haven't guessed it yet, all of these signals are generated by a GAL. And in this case the one and the same GAL.
816isa-1.pld is the source file for programming this GAL. Though the PLD extension may look unfamiliar, it is just plain text and you should be able to open it with any text editor. The files also contains the description of every generated signal.
For more info on PLD files: What are PLD files?

The three GALs - #2

The second GAL takes care of the extra hardware, like the 8259 and 16-bits buffer. There are three free outputs left for future use. 816isa-2.pld is the source file for programming this GAL.
Remark: MEM16 and IO16 tell the system that there is a 16-bits operation going on. I use them to trigger the according signals of the temporary buffer. I could do without them, I think, but that would mean that any ISA read operation, including the 8-bits ones, would overwrite the contents of the buffer.

The three GALs - #3

The third GAL is the smallest one but therefore not the less important one. It could be small because it only needs four inputs:
- the R/W line
- the PHI0 of the original system, here called CLK - the RDY input of the original system - IOCHRDY input of the ISA bus, here called IORDY for short

IOCHRDY is nothing more then the equivalent of RDY: applying a (L) to it will cause the processor to wait until it is released again. In a PC it was at least a must, in Commodores equiped with a 6502 it is not: in the CBM series and the VIC-20 the RDY input is tied to +5V using a resistor. So the question is: do we need this circuit?
I personally don't know of any regular PC card using this feature. But if one uses it, another problem can raise: such a card slows the PCU down using CLK as time base. But normally CLK is at least 4.77 MHz, now only 1 MHz. So we run the risk of a too long slow down. We can now even ask ourself if one needs a slowdown at all in a 1 MHz system!
But for developing hardware or software a debugger can be very handy. And then this circuit is a must! I solved this possible problem in a simple way: I added jumper J1 to disable IOCHRDY if needed.
If you want to know more ins and outs of the Wait circuit: read this article about the 65816 processor.

The GAL has eight outputs, of whom two are for internal use only: you cannot program an asynchronous flipflop inside a GAL, so I used outputs with inside connections to create one. For the technics amongst you: it can be done with one output less but this stuff is new to me and in this way I understand it better :)
The other six signals:
- PHI1, normally generated by a real 6502, generated out of CLK
- PHI2, normally generated by a real 6502, generated out of PHI1 - C573, the clock signal for the A16..23 latch
- PHI0, the new clock for the 65816
- RD, the Intel type read signal needed for the 8259
- WR, the Intel type write signal needed for the 8259
816isa-3.pld is the source file for programming this third GAL.

The ORG signal

The 65816 can address way more memory than the 64 KB a 6502 can handle. But how are we going to tell the original system whether or not is selected?
That purely depends on the system. But the basic idea is: find the decoder(s) that splits the host up in parts and find a way to disable it. In the CBM 30xx and 8032 it is a matter of desoldering two pins and soldering them to the ORG signal. In the VIC-20 a bit more work is needed: we have to add at least an OR gate. But what in case it isn't easy at all to "disable" a system?

The board

With Eagle you cannot only design the schematic but also the board. I use the board design only to find out how to place the sockets.

The extended version

The solution to this question is the so called "extended version". The idea behind it is quite simple: just make the original system think there is a read going on at address $FFFF the moment the 65818 needs to access the ISA bus.
This realised by adding tristate buffers in the R/W, data and address lines. These buffers are enabled by the ORG signal. The moment the 65816 addresses another memory range, the buffers are tristated. Resistors then take care of pulling the R/W and address lines (H) in order to fake a read at $FFFF.
IMHO this solution should work for any 6502 equiped system. Look here for the schematics.

Two Commodore 64 versions

There are two versions: one with only the ISA bus and one with both 65816 and ISA bus.

Having questions or comment? You want more information?
You can email me here.