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:
It is a simple task to make things complex, but a complex task to make them simple.
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).
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.
CPU Board, April 1987
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).
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:
|A17||A16||/MAP||MAP||LS37 pin 11||Device selected|
|0||0||0||1||1||1 - ROM 1|
|0||1||0||1||1||1 - ROM 1|
|1||0||0||1||1||3 - ROM 3|
|1||1||0||1||1||3 - ROM 3|
|0||0||1||0||0||0 - RAM|
|0||1||1||0||1||1 - ROM 1|
|1||0||1||0||0||2 - ROM 2|
|1||1||1||0||1||3 - 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).
Memory Board, June 1987
|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.|
Of course one needs I/O as well. I figured that a serial port would have to do for starters, graphics could come later.
My first I/O board has a 6850 UART, a WD1770 floppy controller, and a 58174 real-time clock.
I don't know why I put two inverters there between the OR gate and the LS139 enable. I'm also not so sure that /VPA should be asserted so soon or for the whole FFxxxx block -- the former might be a problem, the latter will do no harm. Each I/O device takes up two kilobytes of memory -- far more than is needed, but it saved a whole lot of TTL.
At the time I figured that RS422 was the way to go, so that's what I used (remember that the Macintosh was new, and it used RS-422. Also, I didn't want to have to supply +12V and -12V just for the serial port).
The Baud Rate Generator uses a 74LS93 and one AND gate to form a divide by 13 counter, which feeds two cascaded 74LS163 counters. The 615 kHz output can be used (in x16 mode) to generate 38.4 kbps, the first seven outputs of the dividers then give everything down to 300 baud.
First I/O Board, June 1987
In January 1989 I did some holiday work work (a requirement, then, when studying engineering) at Truvelo. There they had a Motorola MVME101 system they used for software development, and I ripped a copy of the ROM and the manual for it. I later found that this monitor is very similar to TUTOR and TUTORNEW for the Motorola M68000 Educational Computer Board -- but of course back then I didn't have access to the TUTOR sources.
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). So I designed a second I/O board.
There's nothing interesting about it really, the devices are mapped to 0x00FF0080 to 0x00FF00FF (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).
By now they'd invented the MAX232 (introduced 1987) and that's what I used to get RS-232. But I kept the RS-422 option. I used three MAX232s, one per port, the third being optional to give DTR and DSR for both serial ports.
In the beginning 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 built this fourth board on a wire-wrap 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. Yes, I could have used a bunch of hex to 7-segment decoders and displays but (1) the majority of 74xx and 40xx / 45xx decoders operate on BCD only, not hex, and (2) at this stage of my life I was as fluent in binary as in decimal, so it was no hardship reading the address and data (even now, 30+ years later, it's not that difficult).
I got a small monitor working this way, but I wouldn't recommend it :-). I wrote my own disassembler in C, and after I had got hold of a copy of Dr. Dobbs Toolbook of 68000 Programming I typed in the Tiny Basic interpreter which works well. I wanted to put Forth on there, but I got busy with other things, so it never happened.
Options for a monitor / debugger.
Interfacing the 68000 to dynamic RAM is actually quite easy. Ridiculously easy, in fact -- see PDF page 9 of Designing with Dynamic Memory from Electronics and Wireless World August 1986.
What caught me out is how ridiculously fast modern DRAM is. You see, I happened across a 16 MB 72 pin stick of RAM, with eight HY5117400 4 meg x 4 bit chips. One stick that provides as much memory as the 68000 can address? And it "hidden" refreshes itself? Works for me.
But see pages 4 and 11 -- tRCD(18) can be as little as 20ns but can not be more than 45 ns for this specific device. The E&WW example has a tRCD of 125 ns assuming an 8 MHz clock.
Fortunately, Dallas / Maxim makes a nifty 5-step digital delay line which will clock things along every 20ns and keep everyone happy (I hope).
More when I get around to it.
|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.|
||Back to Wouter's 68000 Page||(This page last modified 2021-05-11)|