Now that FAP’s Z80 is free running with hardwired NOP, the next step would be to add some memories so I can store programs into it and thus executed by the CPU. So in this part of the build log I’m going to add some ROM and RAM to my computer.
I purchased a couple of AT28C256 EEPROM as well as HM62256 Static RAM. Both are 32KB chips in DIP, and fairly often used in homebrew computer builds. But before that, some housekeeping to do. Since I’m going to make another card with both memories on it, I need to add another slot on the backplane. And because the backplace strips are 5-wide, which is too close to put another card right next to the CPU card, I bridged it with male double row headers and some jumpers.
Now comes the difficult part, before I start building I need to plan out the memory map of FAP, only when that is done can I start designing memory decoding logic and all the rest of it. After some reading I decided to keep it simple, and the memory map of FAP will be like this: 16KB ROM from address 0x0 to 0x3FFF, and 16KB RAM from 0x4000 to 0x7FFF. Since Z80 can address 64KB of memory directly, that leaves me with 32KB of unmapped memory, which can use for VRAM or some other memory mapped IO device. I guess 16KB is of RAM and ROM is plenty for now, if I needed more I can make another card.
Now comes the memory decoding, I’m going to use address lines for chip select signal, and MREQ’, RD’ and WR’ for OE’ and WE’. For chip select, notice how the most significant two bit of address select the memory. When both A15 and A14 are 0, address are within 0x0000 and 0x3FFF, which selects the ROM. Since both A15 and A14 has to be low for CS’ on ROM chip to be low, it’s easy to see a simple OR gate is enough. Memoy read is enabled when both MREQ’ and RD’ are low, again, OR gate. Memory write is exactly the same, active when both MREQ’ and WR’ are low, another OR gate. 3 OR gates, perfect for one 74HC32, which I have. The CS’ and WE’ signals are shared between two chips. And since we’re using only half of the chip, A14 on each chip is tied to the ground.
Now for selecting RAM, its CS’ needs to be low when A15 is low and A14 is high, which means inverted A15 NAND A14, I can use a 74HC00 for that.
So, below is the schematic for FAP’s memory card, only 4 chips, not bad.
Now comes the question of how to program the EEPROM, fortunately it’s largely not a problem because I can just pull low the BUSREQ’, clock the CPU until BUSACK’ is low, this put the address, data and control lines into high-Z and kicks the CPU off the bus, then I just write to the EEPROM by driving the bus with the STM32 board. Which is much simpler than Veronica‘s solution with a dedicated programmer and bus arbitration switches. Everything is done in the STM32F1 board, which is the big advantage I talked about in my first post.
Time to build the board first on breadboard and test it, there’s not much to write about the building process, apart it consuming my entire collection of jumpers. I also put two LEDs on CS’ lines so I can see which chip is being selected. So does it work? Look at the video below.
In this demo I simply put some address on the bus in 0x1000 increments, you can see the ROM chip select’s LED lights up when address is bewteen 0x0 and 0x3FFF, and RAM’s LED lights up when address is between 0x4000 and 0x7fff.
Next up is trying to read or write some values into the ROM, it’s relatively slow to write to EEPROM, each byte may take up to 10ms, that means it’ll take a whopping 160 seconds to write 16KB into it. It does support page write mode that writes 64 bytes at the same time, but it’s not implemented for now.
As reading EEPROM is fast while writing is slow, I wrote my EEPROM write function to check the existing data first, if they’re the same a costly write can be skipped. In the video below I’m writing the first 256 bytes of the ROM with its address, as in writing 0x1 to address 0x1, 0x2 to address 0x2 etc. In the first pass you can see it’s writing into the EEPROM, the second pass the value is already the same so it’s skipping every single write.
So far so good. Things went a bit wrong when trying to write to SRAM though, the write seems to work, but when read back the data is close, but not exactly the same as what has been written to it. I thought it was the timing difference between the ROM and RAM write, after almost an hour of tinkering with the code to no avail, I decided to check the connection and discovered that I wired two of SRAM’s address lines wrong. I should have known since it’s as you can see it’s such a mess. After correcting the wiring, it worked like a charm, which means it’s time to go on the actual card.
Bit of soldering later, I put ROM and its decoding logic on the card.
Next step is RAM, however if you look at the datasheet, you’ll realize the pinout of the two chips are exactly the same, so instead of soldering another 28 wires I decide to simply piggyback the RAM on top of ROM, a technique Quinn also used in her Veronica.
By soldering every pin of the two chips together apart from the chip select, I can put the piggyback chips back in the socket and only hook up the cs line for the new RAM chip. Below is the completed memory card.
To test it, I loaded up ROM with 0 and let it ran, it was exactly the same as the free run last time, so I didn’t take a video, but it worked nevertheless!
Now the my computer have its own memories, I can finally upload some program into it and let it actually do stuff. However, without any means of input or output, FAP is going to be a hard sell for anyone else. That would be my next step, maybe making a VGA video card, or a UART, or even reading a keyboard! Stay tuned to find out on the next episode of the Adventure of FAP!
As usual, you can find the up-to-date resources on the Github repo of this project.