The RetroChallenge is upon us again!
This time around, I plan on working on my Z80 homebuilt computer, the RC2014. (Website for RC2014
, Order a RC2014
) For a few months now, I've had my RC-2014 computer built, and modified to be an RC2014/LL computer. What this means is, is that I have some modified modules using no additional external hardware.
The above picture shows my RC2014/LL system with its extra RAM module, and the C0 Serial expansion board to the left, with the SD card interface board (SSDD1) on it.
The basics of this design:
Unmodified RC2014 modules:
- Z80 CPU module
- Clock module (* see below)
- Serial console interface
- RAM module (for RAM in the range $8000 through $FFFF
Modified RC2014 modules:
- Second RAM module
- ROM module
- Digital IO module
- Second ACIA Serial port at $C0
- SSDD1 (Serial SD Drive)
(*) While the clock module is unmodified, it technically is modified. I have added a 10 uF (50V) cap between the reset line and ground to be a quick-and-dirty power-on reset circuit. It works perfectly. Every time I power on the computer, it "presses the reset button" for me. ;)
The plans to mod these parts are available here
. This is currently fully functional and tested. The modifications use unused gates on the boards, so that it requires no extra additional hardware or boards to implement. The basic theory to the /LL modifications are as follows:
Bit 0 (0x01) of the Digital IO module is tied to one of the extra bus lines on the backplane. Let's call this "Extra-A". When you do an "out" to that port of "0x01", it will trigger the Extra-A line.
The ROM module "out of the box" is configured such that if there is a memory access, which is a read from address $0000 through $7FFF, it will enable the ROM, and it will put its data on the bus. My modification adds in one extra condition to this. It adds in that only if the Extra-A line is LOW, that the ROM will be enabled. This means that when Extra-A is 0, the ROM works. When Extra-A is 1, it's as though the ROM doesn't exist.
The RAM module "out of the box" sits at the high half of memory space ($8000-$FFFF), and is always enabled on memory READ or WRITE to those addresses. The modification to this module is threefold. First, it sits the RAM at the low half of memory space ($0000-$7FFF). Secondly, it is set up that WRITEs to this memory space will always work, regardless of Extra-A. Thirdly, it is set up that READs to this memory space will ONLY work when Extra-A is HIGH.
The end result of this is that when Extra-A is low, reads in the low half of memory will come from the ROM. When it is high, reads will come from RAM. Writes ALWAYS go to RAM.
This is quirky...
I admit this. It means that you can (and I will) write a bootloader/monitor ROM that is enabled on power-on, will read from a mass-storage device and write into anywhere in RAM... It can load a 64 k byte memory image into RAM, and then switch off the ROM and it will all work. The quirkyness is that you cannot verify the loaded-in memory in the low range of ram, since reads will come out of the ROM. Obviously, you also need to do this routine completely out of registers, as your stack variables will get overwritten if you're not careful.
If you want it to behave like a stock RC2014, remove the jumper from the IO board to Extra-A, and instead add a jumper from ground to Extra-A. I have added a switch to mine to force this in the case where the IO board comes up in the wrong state.
Additionally, I have added a second serial port, which basically follows the circuit for the first port, but it sits at $C0, and does not have an interrupt line wired to it. The RX/TX on that one comes out to a FTDI-like pinout header, which is where my SSDD1 module plugs in. The plans for this serial port are available here
, and can be seen as the brown perf-board on the left of the topmost image of this post.
The SSDD1 module...
The Serial SD Drive module is the mass storage module that I've created for my Z80 to interface with. I know that I can push the FAT filesystem support onto the Z80, but that would require substantial effort. I instead decided to go with the model where I have a smart serial-based device that you tell it "i want this file" and it sends it out. Like a local BBS. ;)
The use of a serial-driven drive is not unprecedented. It's somewhat modeled after the Commodore 64/Vic 20's "IEC" serial interface for floppy drives. It also mirrors it in that the drive has some smarts in it to deal with the drive architecture.
I also went this route for the ultimate form of this computer, which is to run CP/M. CP/M expects drives with a Drive+128 byte Sector layout. While other Z80-CP/M computers implement this by having direct interface to the sectors on the spinny disk/cf/sd card, I will do it by having files on the SD card, for the most amount of flexibility. There will be a "drives" folder on the card containing folders named "A", "B", "C", and so on. These letters are the drives. In each of those will be directories for the tracks, named "0000", "0001", etc and in each of those, files named "0000" "0001" "0002" etc. These files are the simulated sectors on the disks. It will be easy to build virtual drives for other use out of this. It also means that I won't need some special interface on a modern computer to talk with this. I won't have to do 'dd' style transfers to get at the data... It's all just sitting on a FAT filesystem.
The implementation of this module is based on an Arduino with a microSD breakout module. The serial interface communicates directly with it, and it sends the content via serial back to the Z80 host.
The above picture shows the SSDD1 module off of the RC2014/LL expansion board, and instead wired to a breakout board where I have a second FTDI serial-USB interface so that I can debug the hardware more easily.
And that brings me to the current Retro Challenge...
My goals for this month is to do a few things here, to finish up this computer system...
- Finish up the firmware for the SSDD1
- Sector load/save support
- File load/save of intel hex files
- directory create, list, remove
- Write the SSDD1 emulation for the emulator
- Finish up the loader and burn it to a ROM
- Write a CP/M bios that uses the SSDD1 interface
- Build CP/M disk/sector files
- Play Zork
- Extend the NASCOM BASIC to support the SSDD1 for loading and saving.