My Homebrew 68000 System

While studying at the University of Stellenbosch in 1987 I built a 68000 computer system. I had very little resources, for example I could only get single-sided PCBs made*, and it was difficult to arrange access to equipment like a logic analyser or digital oscilloscope, even an eprom emulator was out of the question. All of these factors influenced the design.

The system ended up as three separate Eurocards (100x160mm)** with DIN41612 A/C connectors. The bus pinouts were chosen to minimise routing problems. All PCBs are single sided, with parallel vertical wire jumpers on the component side. PCB layout was done using smARTWORK.

* Actually not true. Double sided PCBs were available, but through hole plating not. So there wasn't that much sense in having the top layer, it was about the same amount of work to design most of the top layer to consist of straight traces and to then use jumper wires instead of actual traces.

** I had access to a really nice HP A3 plotter. I bought a Rapidograph type pen for that plotter and made gorgeous plots. But at 2:1, A3 paper gives a maximum PCB size of just a little more than a Eurocard, hence the choice.

Page 1 of my black book (Every project should have a black book)

Gore's Law of design engineering:

  1. The primary function of the design engineer is to make things difficult for the fabricator and impossible for the serviceman.
  2. That component of any circuit which has the shortest service life will be placed in the least accessible location.
  3. Any circuit design must contain at least one part which is obsolete, two parts which are unobtainable and three parts which are still under development.
Corollaries:
  1. The project engineer will change the design to suit state-of-the-art.
  2. The changes will not be mentioned in the service manual.

Meyer's Law

It is a simple task to make things complex, but a complex task to make them simple.


OK, with the mental state of the Chief Engineer out of the way, let's get to the design.

The bus

The key design parameter here was expediency. From the processor, through the buffers, to the DIN 41612 connector. Yes, I buffered everything. Overkill, maybe, but in that era you only shorted a pin to ground once to blow the output driver, chips these days are much more forgiving. And cheaper. I used bidirectional (74LS245) drivers throughout. The pinout of the 74LS244 unidirectional driver is a pain, routing was a lot easier with '245s hard-wired to go in one direction only (Actually, single-sided routing with '244s would have been impossible).

C A
+5V1+5V
D02D1
D23D3
D44D5
D65D7
D86D9
D107D11
D128D13
D149D15
A2310A22
A2111A20
A1912A18
A1713A16
A1514A14
A1315A12
A1116A10
A917A8
A718A6
A519A4
A320A2
A121R/W
/LDS22/UDS
/AS23/VMA
/IACK24/IOSEL
/DTACK25/BR
/BG26/BGACK
E27/VPA
CK28/RESET
/6800INT29/IRQ1
/IRQ2/330/IRQ4
/IRQ531/IRQ6
0V320V

CPU board

68000, Interrupt logic, clock, buffers on all data and address lines.

Hand-drawn schematic, of course. I don't think there ever was a final version, but this is close. Changes would mostly have involved mapping gates into packages so that everything fitted on the PCB and could be routed.

This is the CPU PCB plot, with component overlay. Everything had to be checked by hand, smARTWORK didn't do netlists.

Memory

Another Eurocard, with eight 256 kilobit devices -- two 42256 32k x 8 CMOS RAM chips and two, four or six 27C256 32k x 8 EPROMs, for 64K of RAM and 192K of ROM. Yes, only a few of the pictures* on this page will fit into that much (little?) RAM. Moore's law at work.

* And I mean one at a time.

Anyway. The 68000 was different from the Motorola 8-bitters that preceded it. In the case of the 6800, 6809, 6502 and so on, the reset vector lives at the top of memory, at FFFE/FFFF. These two bytes are read into the Program Counter on reset, and program execution then begins at that address.

The 68000, however, stores the initial Stack Pointer and Program Counter at 0x00000000 (16 bit address) to 0x00000007 (eight bytes, two 32-bit addresses). This is followed by pointers to all the exception handlers, including the Interrupt Pointers. It is nice*, but not essential, to use writeable memory so that the exception address can be changed (another option would be to point each exception at a bit of code in Read-Only Memory (ROM) which then fetches a vector from somewhere else. Cumbersome).

* Also, the 68000 also has a short form for accessing memory in the first 32k of address space, so it's a bit faster if you use this short form access for commonly used variables.

So, we need a bit of circuitry to make sure there's ROM at 0x00000000 for the first four cycles, and then to change things around so that the whole area maps to RAM (another approach would be to completely decode the address space and to map ROM to 0x00000000 to 0x00000007 and RAM from there on up, but the cycle counting approach is simpler). This is done with a 74LS164 shift register. The input is tied high (= "1") and the register is cleared at reset. With each address strobe, the 1 advances, eventually gets to the address decoder and changes the mapping (This comes straight from Motorola Application Note AN-897 except that the fourth output is used and not the eight, since the 68008 takes twice as long to fetch memory eight bits at a time).


A note on the side: From the Hackaday 68000 Backplane Computer discussion I learnt that there's another (arguably better) approach (schematic) to the problem -- map a flip-flop to RESET and to the ROM chip select. The first time ROM is selected, the mapping flips and 0x00000000 is mapped to RAM.

Schematic, part 1. From the top left hand side: A23, A21, A22, A18, A19, A20 (the order is of course to make routing easier) and /AS are used to generate /CARDSEL (0x0000000 to 0x0003FFFF, 256 kilobytes. Although the 68k architecture allows for a full 32 bit address bus, the 68000 only uses 24 address bits, something which caused great chaos when the Apple Macintosh got a processor capable of addressing more than 16 megabytes). Effectively, address lines 24-31 are ignored.

/AS and /RESET tickle the LS164 counter, as previously mentioned.

A17 is buffered, since it goes to two inputs on the LS139 address decoder. It works out well, because in the end there are exactly 16 address lines that needs to be buffered (Here's the schematic of the buffers for what it's worth -- the only slightly odd thing is that 68000 A1 goes to ROM/RAM A0, because of course 68000 A0 drives /LDS and /UDS which select one of the two devices). A16 is OR-ed with the MAP signal, giving:

A17A16/MAPMAPLS37 pin 11Device selected
000111 - ROM 1
010111 - ROM 1
100113 - ROM 3
110113 - ROM 3
001000 - RAM
011011 - ROM 1
101002 - ROM 2
111013 - ROM 3

For the first four cycles after reset, A16 and A17 will be zero, so only the first entry and the last four entries are relevant. The other three Can't Happen.

What else? /UDS and /LDS are OR-ed with /CARDSEL to select between the LO and HI banks (because the 27C256 EPROM and 42256 RAM devices are eight bit, you need two per bank). And R/W is buffered with an OR gate because (1) there are no more free buffers after the 16 address lines mentioned above are buffered and (2) there's a spare OR gate. Elegant, if I say so myself.

And then there's the wait state generator. The CMOS RAM is fast enough to keep up with the 68000, but the EPROM isn't. The wait state generator is four flip-flops being held in reset by /AS, inverted. When /AS goes low, the flip-flops start clocking the state of /CARDSEL through, i.e. nothing happens unless the decoding circuitry decides that 0x00000000 to 0x003FFFFF is being accessed). The jumpers on the right hand side determine when /DTACK is asserted to let the processor know it's OK to read data. Since /DTACK is driven from many sources, a 7407 open collector buffer is used here. And since we don't need wait states for RAM, selecting either RAM chip drives /DTACK via one of the other open collector gates.

If I were to do the same thing today, I would strongly consider using a PAL (the technology was available at the time, I just didn't want to complicate matters). Using a PAL would allow the RAM to be mapped at 0x000xxxxx and the EPROMs to all be mapped at 0x00Fxxxxx leaving the whole address space free for RAM expansion. But in those days 640k was still enough for everybody (not really, but it was and still is enough for this tinkerer).

No I didn't cover the EPROM windows to erase-protect them. But believe it or not, the data is still good, 20+ years later.

I/O

Of course one needs I/O as well. I figured that a serial port would have to do for starters, graphics could come later.

By this time (1989) I had completed my second stint of holiday work (a requirement, then, when studying engineering) at Truvelo. There they had a Motorola MVME101 system they used for software development, and I had ripped a copy of the ROM (MVME101BUG) and the manual for it. (I think the statute of limitations applies, and seeing how I lost the binaries when the boat capsized hard drive crashed ages ago I suspect it's OK).

Because of this, my I/O requirements became 6840 PTM, 6821 PIA and 2 x MC68661 EPCI (UART) devices (I used SCN2661s but it's the same thing). With hindsight the more common 6850 would probably have been a better choice.

Anyway, nothing interesting about this board. 6840 PTM, 6821 PIA, and two 2661 EPCIs, mapped to 0x00FF0000 to 0x00FF007F (The MVME101 maps these to 0x00FE00xx but I had this thing about minimising the memory footprint of I/O devices. Also, it saves an inverter, all the high address lines go straight to a 74LS30. In hindsight this doesn't matter that much).

Software

The software development cycle was fun. (OK, so I'm a masochist :-). I used to write assembler code, hand-compile it, type it into a PC, burn two EPROMs, and then take the EPROMs home and stick them in the system. Single-stepping the 68000 is easy since the whole chip is CMOS. The 68K will wait for the data acknowledge signal DTACK forever. I wire-wrapped a fourth card with LEDs on all data and address lines, and a flip-flop wired to a switch to take DTACK low for one cycle at a time. Removed the jumper on the memory card that selects the number of wait states when EPROM is selected, and I could single-step through EPROM while RAM accesses happened in the background.

I got a small monitor working this way, but I wouldn't recommend it :-). I also typed in a crossassembler (in Modula 2) from Dr. Dobbs, and wrote my own disassembler in C. Eventually I got hold of a copy of Dr. Dobbs Tiny Basic for the 68000, (typed it in from Dr. Dobbs Toolbook of 68000 Programming) which works great. I wanted to put Forth on there, but I got busy with other things, so it never happened.

Some day I might resurrect this system and make something like Peter Stark's SK*DOS run on it.

Overclocking

Using a 32 MHz clock module and a dual flip flop to get to 8 MHz meant I had two overclocking options, namely 16 MHz and 32 MHz. 16 MHz actually worked. 32 MHz... didn't.

[Image] Hit Count
hits since 1999-05-27.

Back to Wouter's 68000 Page (This page last modified 2014-03-12)