Ruud's Commodore Site: 65816-ATX computer Home Email

65816-ATX computer

What is it?

This a computer with the 65816 processor, designed on the ATX board, the same board as used by various PCs. It has six 8-bits and two 16-bits ISA slots and should be able to handle quite some ISA cards.


I always wanted my own 65816 computer, capable of handling ISA cards. After having designed a XT clone on an ATX board, the idea rose to use this design as base for a 65816 system.


The design with logic gates instead of GALs
The design with GALs
The board of the above design


On forehand: bugs and other imperfections

- Only when I received the PCB I noticed the types of the ICs are missing. So you have to look at the board to find out what IC is what.
- Holes are not drilled because I forgot to place the needed symbols.
- The used battery is a battery with attached pins. I had plans to replace it with a battery holder but completely forgot.

The above will be repaired in the future.

The hardware

Because of the possibility to attach ISA cards, I wanted to keep the onboard parts to the minimum. In fact I am more or less using the IBM AT as example:
  • CPU
    - WDC65816
  • Speed
    4 MHz seems to be a nice speed. I know the WDC65816 can go up to 14 MHz but 4 MHz is still four times faster than my Commodore 64 or any of my CBMs. I use an oscillator in a socket anyway so the speed can be changed, if needed.
  • Memory
    960 KB of SRAM, 64 KB of EEPROM (AT29F010)
  • Keyboard and mouse controller
    The VT82C42N, a 8042 compatible controller.
  • Timer
    WDC6522. Not a real timer IC like IBM's 8254, but it has two 16 bits timers on board. An advantage above the 8254: twenty extra I/O pins.
  • Interrupt controller
    No real interrupt controller like the 8259. A 74541 buffer enables us to read the various interrupt lines and eight 7406 OC inverters ar used to feed them to the IRQ input of the 65816. If an interrupt occurs, the first thing the 65816 has to do is to read the status of all interrupt lines and act according to them.
    Is it good enough? It is at least faster than checking all attached devices one by one just to see which one caused the interrupt as the C64 and CBMs have to do.
  • RTC
    Dallas DS12885
  • Sound
    A very simple circuit, see later.
  • DMA
    None. This design also doesn't provide the means to enable it in one or another way because the 65816 and IC3 cannot be tri-stated.

Explanation of the CPU with RDY circuit

A 65816 can handle up 16 MB of memory range, the same amount that can be handled by a 16-bits ISA slot as it has 24 address lines (forget the data lines D8..15). To be able to handle 24 MB, a 74373 or 74573 latch is used to generate the address lines A16..23. Nothing special here so far.

If you wanted to hold a 6502, you negated its RDY input and it stopped. (OK, not during writes, but forget about that.) The 65816 has a RDY input as well. Negate it and it will stop. Even during writes. But it will also stop providing the address lines A16..23 over the data bus when PHI0 is (L).
Normally the latch providing the needed conversion from data to address, is clocked by CLKO through an inverter. But if RDY is involved, something has to stop this clock otherwise random data will be latched instead of the real address. And unfortunately it is not as simple as just using an AND or OR gate.

And there is another problem. WDC is making their own version of the 65816, the WDC65816. For one or another reason they have decided that the RDY pin can have two functions:
- in normal circumstances it behaves as the original RDY input
- when executing the WAI instruction, this pin serves as output and will be negated to tell the outside world that the 65816 is executing this WAI instruction
This last function means it is not possible anymore to connect a TTL output directly to it.

Luckily there is a solution. In contrary to the original 6502 and 65816, the upper half of the clock for the WDC65816 can be stretched without any limit. So when we receive a signal for RDY, we don't feed it to the actual RDY pin but use it to stretch the incoming clock signal as long as needed.
And what to do with the RDY input? We just tie it with a 10 K resistor to +5V. In normal circumstances it pulls RDY (H) and when the WDC65816 has the need to use it as an output, the resistor makes sure that the output circuit won't be damaged.

CLK is the signal originally meant to be fed to the PHI0 input of the 65816.
RDY is the signal originally meant to be fed to the RDY input of the 65816.
PHI0 will be the signal to be fed to the PHI0 input of the 65816.
Latch will be the signal to be fed to the CLK input of the 573 or 373 latch.
      __      ____      ____      ____      ____      ____      ____      __
CLK     |____|    |____|    |____|    |____|    |____|    |____|    |____|

      ____       _________                _____________            _________
RDY       |_____|         |______________|             |__________|         

      __      ____      ________________________      ______________      __
PHI0    |____|    |____|                        |____|              |____|

      _______    _________   ____      ________________    ____    __________
A            |__|         |_|    |____|                |__|    |__|

         _______   ____    ________________      ____   __________   ____
B     __|       |_|    |__|                |____|    |_|          |_|    |__

      _______    _________                  ___________            _________
C            |__|         |________________|           |__________|

OK, all these NAND gates looks quite impressive but the whole can be explained in a simple way. The hart of the circuit is a flipflop made out of IC1A and IC1B. The output at point C will be set to (L) the moment RDY = (L) and CLK = (H). As long as point C = (L), IC2B will keep PHI0 (H).
The flipflop can only be reset if CLK = (H) and RDY = (H).

So in short:
- If there is any action needed, it only can happen if CLK = (H).
- If RDY = (L) at the falling edge of CLK, PHI0 will remain (H) for the coming clock cycle. Otherwise PHI0 will keep following CLK.
- At the end of this cycle RDY will be checked again and the circuit will handle according the previous point.

Explanation of the memory

960 KB of SRAM and 64 KB of EEPROM makes 1024 KB of memory. But then, why an AT29F010, capable of 128 KB? I have three main reasons:
- The main reason is speed: these AT29F010s have a much better access time than any EPROM.
- These AT29F010s can be re-programmed in seconds. It already takes about 15 minutes to erase an EPROM.
- These AT29F010s can even be programmed, if needed, while still in the system.

About using only 64 KB of the full 128 KB: I cannot give you an exact reason, I only can say you it felt better this way. But I must admit that using only 64 KB of the full 128 KB is yet a bit of waist. So I added some jumpers so that each of the two 64 KB parts can be chosen by hand or even by software. The last option enables one to use the complete ROM to store (a part of) the Operating System and then to load it from ROM instead from a much slower device.

Memory range

The system will start up using the next memory range:
$000000 - $00DFFF =  56 KB of RAM
$00E000 - $00EFFF =   4 KB of I/O
$00F000 - $00FFFF =   4 KB of ROM
$010000 - $09FFFF = 576 KB of RAM
$0A0000 - $0EFFFF = 320 KB free for ISA cards, RAM or ROM
$0F0000 - $0FFFFF =  64 KB of ROM
$100000 - $FFFFFF =  23 MB free for 16-bits (self designed) ISA cards
The I/O signals IORD and IOWR are only valid when accessing the I/O range. The 4 KB of this I/O range can be divided up in two parts:
- $00E000 - $00E3FF has been reserved for IBM (compatible) I/O cards. The key singal for this range is AEN. During DMA actions AEN is High, during real I/O actions AEN is Low. A circuit makes sure that AEN is only Low when accessing this range.
- $00E400 - $00EFFF can be used for any other I/O card designed for this system. Such a card must include the address lines A10 and A11 in the address decoding and at least one of these two address lines has to be High. AEN and the address lines A12..23 are not needed. IORD and IOWR should be involved into the decoding as well in one or another way.

But where do the very first 4 KB of ROM come from? From the AT29F010 as well. This little piece of ROM is nothing more than a mirror of the top 4 KB of the 64 KB of ROM: $00F000 - $00FFFF = $0FF000 - $0FFFFF

A keyboard and a mouse

I didn't have to think about this very long: I'm going to use a PS/2 keyboard and mouse. Why? Only a 8042 or equivalent keyboard controller, two connectors and a handful of other little parts are needed. And the 65816 doesn't have to waist its valuable time on scanning rows and columns of a keyboard like, for example, a Commodore 64 has to do.


The system will need some timers. The Commodores used a timer so they could check the keyboard on a regular time base. The PCs used a timer to refresh the dynamic RAM in time. Hmmm, and it seems I just gave two examples that are not valid for this system. Hey, what about generating sound?
Anyway, in the PC the 8253 or 8254 are used and I have thought about it to use one as well. But that sounded a bit like blasphemy in a 65xxx system so I chose for the W65C22. This is the WDC equivalent of the original 6522 but without the bug in its serial register and it can run at 14 MHz. AFAIK the fastest 6522 could run at 3 MHz so I don't have another choice anyway.
And the 6522 has 20 I/O pins, the 8253/4 has none! Eighteen of these pins have been made available using a simple 20-pins header. This header has +5V and GND at the end to power external circuits connected to this header.

Real Time Clock

Any new self respecting system has a RTC on board for obvious reasons. I have chosen for the DS12885 with an external crystal and battery. I could have chosen for the DS12887 with internal crystal and battery but when this battery has been exhausted in 10 years time, you have two choices: replace the IC or hack the IC. The last choice is no joke. I had to do it with the RTCs of 25 years old systems. Replacing the battery is much easier and cheaper.
But then: why this IC? Because it is used en masse by PCs and a lot of other DOY projects, it is easy available. And I'm familiar with how to access it in ML.

The explanation of not choosing for DMA

In the beginning I was thinking about adding DMA. But this won't be a professional system and speed is not of that importance. And what circuit to use? The only ones I know are those of the IBM PC/XT and AT. I did some research but I then ran into one important thing: my heart was not in it to use DMA, I was not convinced that it was a feature that I had to have. So no DMA it was.


I wanted to provide some basic sound in some way. So I provided a small circuit that is able to drive a little speaker. In fact it is the same circuit as used by some PC clones.
Its input is not connected to anything on the board. A suggestion: the shift register, CB2, of the 6522 is known to be used for sound generation. (I never did so I don't know the specific ins and outs)

The glue logic

So far I only described the big "important" ICs. But they have to be connected to each other with what we call the "glue logic". And I intend to use GALs for this. But GALs have a small disadvantage: in a schematic they don't speak to you. So I created two schematics: one using the well known gates to explain the whole to you and one where most of the gates have been replaced by the GALs. So if you see inefficient circuits on the non-GAL schematic, just forget about them; they are only there to make it easier for me to explain the design to you.

The design with logic gates instead of GALs
The design with GALs
The board of the above design

Five GALs will replace most of the smaller logic. The new schematic is therefore much smaller but doesn't look better. The part around GAL2 is a disaster. This has all to do with the fact that this design has been optimized for drawing traces on the board.

The system's first 1 MB segment
For various reasons we need to know whether the 65816 is addressing the very first 1 MB segment or not. Because only four address lines have to be checked, three OR gates will do. OR gate IC19C outputs the signal SEG0 that will be used by other parts. This part is handled by GAL4.

Upper RAM selector
In a PC the range from $0A0000 to $0EFFFF is free to use for video cards, external ROMs, network cards, UMB memory, EMS memory, etc., etc. This system has no onboard video card and my own intention is to start with an MDA card. I see if I can hack a VGA card. But the choice what to use or not is up to you. That means that unused ranges can be occupied by RAM. Dip switch SW1 takes care of that.
How does it work? When the upper half of the first segment is chosen, the 4-to-16 demultiplexer 74LS154, IC21, becomes active. The address lines A15..18 determine which of the sixteen outputs becomes active. Each output represents a block of 32 KB. The first four of these blocks will be filled with RAM anyway. As said before, the ten switches of SW1 determines whether the next ten blocks will be filled with RAM or not. The last two blocks are reserved for ROM.
An huge AND gate created using a 2-input AND gate, a 13-input NAND gate and an inverter will tell the upper RAM, IC6, whether its services are going to be needed or not.
This part is handled by GAL2.

ROM selector
As said above, the last two outputs of the 154 are reserved for the ROM. A 3-input AND gate will combine these outputs with a signal representing the range $00F000 - $00FFFF. The signal will be explained later
This part is handled by GAL2 as well.

ROM block selector
I only needed 64 KB of ROM but for various reasons I explained above I used a 128 KB EEPROM. Because I don't like to waist things, I decided to create a circuit that enabled to take everything out of this EEPROM.
First some jumpers enable a user to select a particular 64 KB block of the EEPROM. When using switches instead of jumpers, one can select a particular BIOS/Kernal before start-up. Just like I did (and still do) in the good old times with my Commodore 64.
I have a C64 where bigger EPROMs are used and signals from the I/O port of the 6510, normally meant for the cassette recorder, are used to select other blocks of the EPROM. This inspired me to use the same trick here, using the CA2 pin of the W65C22.
The four pins in T-shape enable you to select whatever function you like for the address pin A16 of the AT29F010.

I/O range and lower ROM signals
A 74LS138 3-to-8 demultiplexer, IC23, will create a signal at output Y0 that represents the very first 64 KB of the whole memory range of the 65816. Another 74LS138, IC26, will create signal IO at output Y6 that represents the I/O area in the range $00E000..$00EFFF and signal LROM at output Y7 that represents the ROM area in the range $00F000..$00FFFF. This LROM signal is the one mentioned above, the one that is fed into IC14C, the 3-input AND gate.
This part is handled by GAL3.

I/O and memory control signals
Yet another 74LS138, IC27, generates the various signals needed for the ISA slots and the onboard I/O devices.
R/W    I/O   SEG0        IOWR   IORD   MEMW   MEMR   XMEMW   XMEMR
 L	L      L	   L      H      H      H      H       H
 H	L      L	   H      L      H      H      H       H
 L	H      L	   H      H      L      H      L       H
 H   	H      L	   H      H      H      L      H       L
 L	L      H	   invalid
 H	L      H	   invalid
 L	H      H	   H      H      H      H      L       H
 H   	H      H	   H      H      H      H      H       L
In text:
- IORD and IOWR are only activated when the 65816 accesses an address in the I/O range.
- XMEMR and XMEMW (X stands for 'eXtended') are activated in all other cases.
- MEMR and MEMW are activated when the 65816 accesses an address in the first 1 MB segment not being the I/O area.
This part is handled by GAL3.

Lower RAM selector
This circuit is made out of a NOR gate and a 3-input NAND gate. The whole can be translated as: the lower RAM is selected when:
- the very first 1 MB segment has been selected, SEG0 = (L)
- address line A19 = (L)
- neither the I/O range nor the low ROM have bee selected: IO = (H) and LROM = (H)
This part is handled by GAL3.

I/O manager
The I/O manager manages all I/O related actions on the board and controls the four I/O devices on it. The manager knows when an I/O action is going on when signal IO of output Y6 of IC 26 = (L). IO is used to enable IC11A, the first half a 74LS139 dual 2-to-4 demultiplexer. Output Y0 of this half is used to enable the second half, IC11B, and to control AEN.
In a PC AEN tells the I/O devices whether an I/O operation is a real I/O operation, AEN = (L), or a DMA operation, AEN = (H). But this system doesn't have DMA, so why not tying AEN just to GND?. The I/O range from an ISA slot only runs from $000 to $3FF. That's just 1 KB. My I/O range is 4 KB big, just in case I wanted to do more or something extravagant.
But to distinct the PC I/O range from my extra 3 KB? This was where the idea rose to use AEN. Output Y0 of IC11A represents the I/O range $000 to $3FF, ideal to use for AEN. Now I can build my own I/O cards for the range $400 to $FFF. When I address one of my own cards in this extended I/O range, AEN becomes (H) and tells the original PC cards to ignore this I/O operation because it is a " DMA operation".

As said, IC11A controls IC11B which on its turn controls IC34, a 74138. This 138 outputs the enable signals needed for our four onboard I/O devices:
$000 - $00F:  Interrupt controller
$010 - $01F:  W65C22
$020 - $02F:  Keyboard controller
$030 - $03F:  RTC
Because the interrupt controller is read-only, this signal is ORred with IORD using OR gate IC19d.
This part is handled by GAL3.

Real Time Clock
This DS12885 has, IMHO, a weird bus structure. So I'm not going to explain this circuit, just study the datasheet of the MC146818, the original predecessor of this IC, and consider it as "this is the way as it should be because Motorola said so!".
This part is handled by GAL4.

Clock signals.
This board needs three clock signals:
- 14.3181 MHz for the OSC signal on the ISA bus. It is at least needed if you put a CGA card into the system. I don't know if other cards use this signal as well.
- 8 MHz for the keyboard controller. It needs a frequency ranging from 6 to 12 MHz. The next line explains why I use 8 MHz.
- 4 MHz for the 65816, just another oscillator. If you want another frequency, just replace with another value.


Isn't 4 KB a little bit small for a 65816 system? That was my first thought as well but then I realized: one of the first instructions could be to switch to the 65816 native 16-bits mode and make a long jump to $0Fxxxx where we have 64 KB of ROM at hand!

Still under development....

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