It’s time for more blatant advertising for Hackaday Projects, the best project hosting site on the Internet. Did we tell you it’s collaborative? That you and your friends can work on projects together? Want more encouragement to join? How about a contest with prizes that include oscilloscopes, FPGA dev boards, soldering and rework stations, Beaglebones and Raspberries and Spark Cores? Oh my!
Oh. We’re also developing a retrocomputer to show off the features of Hackaday Projects. This is the latest update, showing off the architecture of the entire system, the memory map, and the logic glue and buffers. The plan for this project is to have it host another awesome Hackaday site, our retro version, a small off-shoot of the main Hackaday site that’s specifically designed to be loaded by computers built before 1993. There haven’t been many retro successes in the Hackaday tip line recently, so if you manage to get a vintage computer to pull the retro site up, snap a pic and send it in.
The architecture is actually pretty simple; the CPU, a ton of RAM, 64k ROM, and a pair of 6850 ACIAs (yes, I know, but it’s for a good reason…) giving me two serial ports capable of 19.2 kbps. These four parts are the basic system and are probably the most boring parts of the development.
There will be two or three more cards in the backplane for video, a Compact Flash/IDE adapter, and a microcontroller that will talk to a keyboard, an Ethernet module, a cassette tape drive, and probably some other stuff I haven’t thought of yet. All of these cards are connected via four types of control signals. The address bus is unidirectional, coming out of the CPU card. The data bus is bidirectional.
There are two other groups of control signals, most of which were covered in the last post on this project. Note this isn’t the minimal 68000 system I described in that post. I’ll be using interrupt pins. Because I’m using the 6800 peripheral pins, this means I’ll also need to generate a /DTACK signal. This makes the architecture a little more advanced than the basic, “you can build a 68k system on a breadboard” computer I described in the earlier post, but not by much.
The real fun begins when I get to the video and IDE/microcontroller boards. That’s going to be a Yamaha V9938 Video Display Processor that will have a VGA output and also be compatible with the V9958. This has 128kB of DRAM attached to it, out of the CPU’s address space.
The IDE/Compact Flash/Microcontroller card will provide the control logic for a huge chunk of storage on a CF card, or if I’m feeling extremely adventurous, one of those old-school IBM microdrives hard drives. The IDE spec is a 16-bit wide data bus, so that connects directly to the CPU. This board will also have a PS/2 (or ADB) keyboard port, an Ethernet module, and whatever other cruft I can stuff in there.
Here’s a little thought experiment. Connect a LED to one of the address pins on the 68k, kinda like I did in this post. It’ll drive one LED. How about two? Sure. How many more? A dozen? How long until those LEDs stop lighting up?
That’s the problem with connecting the pins on the CPU to RAM, ROM, peripherals, address decoders, and memory logic. Eventually, the CPU won’t be able to drive all the pins. This is why we need buffers and line drivers.
In the last post where I blinked a LED, I was using a simple circuit to drive the LED using a 74HC04 inverter. To drive all the address, data, and control lines, I’ll need something a little more complex. To the surprise of no one, this was a problem solved a long time ago.
For the unidirectional lines, i.e. the address bus, I’ll be using a 74HC373 octal bus driver. Three of these are dedicated to the address lines, and another two for control signals.
The data line is a little bit trickier. These lines are bidirectional, making the switching a little more difficult, but also a solved problem. The 74HC245 is a bidirectional transceiver, allowing me to connect the data lines from the CPU to one side, the data lines on the backplane to the other, and toggling the direction with the R/W line. Very easy, and a one (or two, technically)-chip solution.
There’s one last thing before the CPU can access the RAM, ROM, serial port, and all the other stuff that I’m putting in this tiny blue box of an enclosure. The memory and peripheral chips must be decoded into the correct address space. This means using a surprising variety of logic chips to enable reading and writing of everything attached to the CPU.
Before I explain this, I’m going to say yes, I could do this with a CPLD, GAL, or some other type of programmable logic. When this project comes off a wire-wrapped backplane, that’s what I’ll do. With wire-wrapped circuits, everything is extremely easy to modify and you can, theoretically, make an exact duplicate of the schematic just by looking at the wires. Programmable logic is just another point of failure, and I’m doing this the simple way, anyway.
Decoding the RAM and ROM
Generally, all the ‘big’ chips in this project – the video circuitry, RAM, ROM, communications adapters, whatever – will have three pins that need to be toggled: Chip Select, Read, and Write. These pins must be properly selected when the CPU accesses something. Reading and Writing are pretty easy, and selecting each chip only a little more so.
The usual 6502 et al. way of toggling the Read and Write pins on chips is simply connecting the R/W from the CPU to the chip. This line is high when the CPU is reading, and low when the chip is writing. The 68000 has two additional pins for controlling access to chips: /UDS and /LDS. These pins are active (low) when reading or writing to data bits 8-15 or 0-7, respectively. Luckily, the control logic is a simple two-chip solution:
That’s a quad-OR gate and a single inverter taking care of reading or writing to the high (D8-15) or low (D0-7) parts of RAM, ROM, or whatever. Easy, and easily duplicated across multiple cards in the backplane.
Now the fun stuff. Decoding. This is like a puzzle that has surprisingly strict requirements. I need to use a minimal level of gates to turn the address lines into chip select signals to minimize the delay, but I also need to make sure I’m not decoding into unused space in the memory map.
The RAM will be at the bottom of the address space from $000000 to $3FFFF – a full four megabytes. To do this I’m taking 3 to 8 line decoder and attaching the RAM chips to four of the eight outputs. I should note [lennart] over on the Hackaday Projects page came up with a better circuit for RAM decoding. Thanks.
This circuit will put my eight chips of RAM into the address space at $000000 to $3FFFFF with a minimal amount of delay, but there’s a problem: When the 68000 first boots, it looks for instructions at $000000. Since this is RAM, there won’t be any instructions at that position, the computer will halt, and the world will end. I need some sort of circuit to deselect the RAM and select the ROM for the first few clock ticks.
This means I need to generate a /BOOT signal, or a signal that is active (low) for the first eight clock cycles. I’m doing that with a 74HC164 serial in, parallel out shift register, with /BOOT generated from one of the outputs. By putting this signal on the backplane, I can deselect the RAM with some NOR gates, enable the ROM with an OR gate, and have the CPU read some instructions when it’s reset.
A Memory Map
I might as well go over the memory map in this post, so in no particular order, here we go:
- $000000 to $3FFFFF – RAM
- $FF0000 to $FFFFFF – ROM
- 6850 ACIAs are decoded from $EF0040 to $EF0042. ACIA 1 is even, ACIA 2 is odd. More on that later.
- V9938 is at $DF0000 and $DF0001 for Mode 0 and Mode 1, respectively.
Noticing a pattern with the peripherals? I’m taking the top eight bits of the address space and changing one bit for each peripheral. This simplifies the decoding, as I can use a single 74HC30 eight-input NAND gate for the RAM, and add a single inverter to an address line to decode all the peripherals. Simple, fast, and easily modified and copied across the entire system. This setup of changing one or two of the top four address bits for each part of the system also has another benefit: It’s easy to tell which peripheral is being accessed by putting LEDs on the top four address bits just like I did with the last post.
That’s it for this update, and it unfortunately describes the system well enough that there’s nothing to update until I get a ROM monitor and serial port running on this system. Good news, though: [Bil Herd], creator of the Commodore 128, the cheaper 8-bit Commodores, and generally awesome dude will be making an appearance in the next update.
This is the boring part of system construction. Don’t get me wrong; getting a minimal system running is rewarding, but the real fun in this project is going to happen when I get to the video circuitry, IDE hard drive, microcontroller, and all those crazy peripherals working. After that, it’s even more fun with getting an OS and compiler running. I actually have an idea for an OS that has never been done before, and is still only a twinkle in the eye of the BeOS and Haiku OS designers. That might take a year or two.
Updates to follow, and until then follow this on Hackaday Projects.