Finally we’re going to to actually start building the computer! I’m probably going to rather frequently compare what I’m doing to what Quinn Dunki did with Veronica, since a large part of this project’s inspiration comes from hers.
Let’s start from the very basics, the construction material. Quinn etches, drills and solders her own circuit board, I don’t have such luxury here so I’m going to make mine out of prototyping boards, first comes to mind is the perfboard, I already have a couple of them laying around and thought it’s a good idea to use them. As it turns out 3 hours later, no, just say no.
If you don’t know about perfboard, it’s a regular PCB with drilled holes in a square grid of 0.1 inch spacing, and each hole is electrically isolated from each other, and that means you have to either wire wrap, which I don’t have, or use point to point soldering, which means soldering every single connections using 30AWG wires, which is hard to strip and position because they won’t stay in place. It’s alright for smaller projects, but if I did the whole thing using perfboard I might well be dead before even got to the F part of the FAP.
A bit of internet search later, I got some new prototyping boards that I’ll be using to build the computer, first of all is the large “motherboard” or “backplane” where all the modules will be plugged in. It’s a board with 5-hole conductive strips grouped together, so it’s sort of like a stripboard but not really. This board is around 6 x 8 inches, enough for a couple of expansions later on.
Now we have the motherboard, next up is the boards that our modules use, for that I bought what some may call “solderable breadboards”, which is basically PCBs with breadboard patterns. This is much better than perfboard because you can use solder wires to the adjacent pins of components, and it already has power buses available. This board is 5.5 x 3.7 inch, perfect fit for plugging into the backplane vertically.
Now a little bit about bus design, Quinn uses ISA connectors for her Veronica with 31 pins available, it works when you make your own PCB, but obviously not here. So I’m going to go with the tried and true pin headers. Double row female pin headers on the backplane, double row right angle male pin headers on the modules, and it’ll plug right in. And because the two rows are connected on the module card, it will bridge the gap between 5-hole groups on the backplane as well. What’s more, pin header comes 40 pins wide, a nice number for a system bus, and I can add more later if I want.
With the basics done, it’s time to design the bus pinout and the CPU board. Because it’s my first time doing this, I’m going to play it safe and put almost all CPU signals onto the bus. Pin 1 will be 5V, pin 2 to 9 is DATA[0:7], pin 10 to 25 is ADDRESS[0:15], pin 26 to 37 is every single CPU control signals apart from REFRESH and HALT, since we’re not using dynamic memories, pin 40 is GND. This leaves 2 pins free on the 40 pin bus, and have the option to make it even wider by just adding more pin headers, pretty good.
For the CPU board itself, it’s pretty straightforward. ADDRESS and DATA lines are buffered with 3 74HC245s, while control signals are connected to bus directly, if it turns out those needs buffering too I can add them later. Since ADDRESS is output only, the DIR pin on the ‘245 is tied to GND so B side is input. As for bidirectional DATA lines, I connected the DIR pin to WR’. When WR’ is active(low), DATA lines are output, and in 245 data goes from B to A, when WR’ is inactive(high), DATA lines are input, and 245 data goes from A to B. The output enable of the 245s are connected to inverted BUSACK’ signal, so when BUSACK’ is low, output enables are high, ADDR and DATA goes into high impedance, kicking the CPU off the bus. Below is the schematic.
Time to start building. Here are all the chips in place with all the power connections, as well as the DATA line from the buffer to the header. I had to cut a single line off the bottom of the board so the male header actually sticks out.
One hour later, all the connections are done, it looks like a mess, but that’s what happens with this many signals.
Making sure there is no shorts between power buses and all the connection are correct with the continuity tester, the CPU board is done. The logical next thing to do it test it. It’s not as easy as it sounds though, the CPU needs clock signal, data inputs, and 6 control signals, and I need a way to see what’s on the ADDRESS and DATA bus to see what the CPU is doing, we need some way to do all those.
What Quinn did was designing a dedicated clock circuit with monostable 555 for single-step clock, as well as crystal oscillator for full speed clock, and SPDT switch to select between the two. And for visualizing the bus content, the HexOut display module. It’s fun and all designing all those support circuits, but I’m going to skip all that trouble and use a microcontroller to control the FAP in the early stage of the development. Since the microcontroller is programmable I can clock the CPU as fast or slow as I want, put anything I want on the DATA bus, see what’s on the ADDRESS bus, achieve reliable power-on resets, monitor and change all the control signals, and it also acts as a USB power supply. It’s much more robust and customizable than using dedicated circuits, takes much less space, and probably cheaper in the end too.
The microcontroller in question is the STM32F103VCT6 on its Minimum System Development Board from ebay. This little beast of a uC has 5 16-bit GPIO ports, a total of wooping 80 GPIO pins, plenty enough for FAP. It also has 256KB of flash memory and 64 KB of SRAM, which means I can fit the entire addressable space of Z80 inside the flash memory of this uC 4 times if I want. It also runs at 72MHz, 18 times faster than Z80, and has a million peripherals that I’m not going to use in this project. And the best thing about it is that it doesn’t have all the bullshit components tacked on like they do in the Discovery boards ST makes themselves, just a simple minimal working system with all the pin broken out, and nothing else. How much for this? $6.5. If not because of the extensive libraries, there is almost no reason left use Arduino now we have this. All in all, not bad at all.
I thought I would finish the backplane board before testing the CPU board. The blackplane is pretty simple too, all the bus signals goes into the microcontroller, a couple of buttons for reset and clock control, and two UARTs will be used, one for debug output, one for serial LCD. The entire PORTE will be used for ADDRESS, lower 8 bit of PORTD for DATA, PORTC for control signals, PORTB for buttons, and PORTA for 2 UARTS.
The construction is similar to the CPU board, just tons of wires solder, which isn’t very interesting. I needed to cut across two traces so that the double row headers on the controller board doesn’t get connected together.
Finished backplane, the 40-pin double-row header is for CPU card, the controller goes to the lower right, and buttons are for reset, single step, and run/stop.
Well not actually quite finished, I forgot to add the two UART headers. I used a bluetooth module, so I don’t have to attach another wire to it. Here is the really finished board:
Now it’s finally time to test the CPU board. We want the CPU to execute some instructions, but since we don’t actually have any memories, I’ll start with a simple one. What I’ll do is to tie the DATA line to GND, all the control inputs to VCC, hold RESET low for at least 3 clock cycles to properly reset it, then clock it normally. The CPU will start executing from address 0x0, and fetch an instruction from the DATA bus, it will be 0x0 since I tied all of them to GND. The Z80 will therefore execute the 0x0 instruction, which happens to be NOP, which doesn’t do anything at all. It will simply go to the next address and fetch another instruction, which is still 0x0, another NOP. In the end it just keeping going to the next addresses, and we can see the address increase in the ADDRESS bus, this is called free running the CPU, a simple way to make sure my CPU is working.
I set lower 8 bits of PORTD, which is connected to DATA bus, to output 0, and PORTE, connected to ADDRESS bus, as input. The content of ADDRESS and DATA bus are displayed on the LCD screen, and CPU are clocked by pressing a button, or set to run continuously at the press of another button.
Well does it work? See for yourself:
As you can see, I started by single stepping the clock, each time I press the button the clock advances 1 cycle. It takes 4 cycles for the address to advance 1, which is in line with what datasheet states.
After letting it free run for a while, you might notice the address is fluctuating instead of simply going up. This is due to the memory refresh operations that is built into the Z80 so it would be easier to use with the cheaper DRAM. I stopped the clock to single step again, and you can see the address changes every two clock cycles now, just like the what datasheet say again. The first two cycle is PC, and the last two is refresh address.
After thinking long and hard about the design, my FAP finally lives! All is well, I’m glad it works after all the work. Next step is to add some ROM and RAM, so it can actually execute some meaningful instructions. Stay tuned to find out more!
Again, you can find the up-to-date resources on the Github repo of this project.