From Wiki
Jump to navigationJump to search
Z80 SBC Connected
Z80 SBC Layout


  • 2008/09/04 - I've committed the entire contents (I hope) of the original project to Subversion, located here. The username is 'guest', and the password is blank.


At the moment, this is less a resource page, and more a history of getting my Z80 SBC designed.

For years, I've wanted a little CP/M system, about the size of a pack of cigarettes (1 SOAPOC) that had two or more serial ports, 64K SRAM, a boot monitor, mass storage, and ethernet. Compact flash cards fit the bill nicely for the mass storage, being faster than MMC cards, having an IDE interface, and being low power. So I finally decided it was time to do something about it.

It seems a number of people have interfaced IDEs to Z80s and 8051s, but I haven't seen any reports of people getting an OS installed on them. CP/M is a natural candidate for this, as it's a complete, well documented file system (certainly not without limitations, such as lack of precise file sizes, time stamps, and a limit of 8MB per volume), it's pretty easy to write a BIOS for it, and there's tons of software.

Since I wanted a small package, the Z84C15 was a natural, as that's got the CPU core, CTC, SIO, PIO, clock generator, etc all on chip. Using the PIO would be a nice way to interface to the IDE controller, but I hadn't seen such an implementation yet. Typical designs I've seen either use a 8255 or several '373's and '245's to create an interface, and occasionally the '543 (a bidirectional latch arrangement). These would all take up unnecessary board space, so I decided to pursue the PIO approach. I layed out a board (pictures) that implemented the functionality of the Z84C15 in through-hole logic, to make debugging easy (I normally hate doing through-hole, much preferring surface mount).

My first step in the whole process was designing the PAL equations for the GAL22V10, that would handle memory address decoding for the SRAM and FLASH, the bank switch logic, and the IDE read/write strobes. Once I had this, I drew the schematic and layed out the board. The board was then sent off to Advanced Circuits in Colorado to be manufactured.

While the board was being manufactured, I started working on software. I had a copy of SIMH running for a while on my Gentoo box, running CP/M V2.2. The disks images have all your basic tools like M80, L80, DDT, Word Master, etc. I decided that my boot monitor should be written in Forth, as this would allow me to quickly develop words to dump memory, talk to the IDE controller, etc, without reprogramming a FLASH or downloading code to the ROM emulator every time. So I grabbed a copy of CamelForth and made the minor changes necessary to run on my target board (mostly support for the Z80 SIOs, instead of calling BDOS functions. CamelForth is largely written to be easily ROM'ed).

Finally the boards came back (it wasn't really more than 9 days or so, but it seemed longer) and I populated them, after doing basic checks for voltage, etc. I connected up the ROM emulator, downloaded the Forth image, and it mostly ran. I don't remember the details at this point, but I think it took less than 4 hours to get it running as I wanted it, once I debugged a few hardware issues, the largest being that the SIOs weren't connected to the RS-232 drivers because of a oddity in the CAD system (I should have seen this in layout, but I was anxious to get the board in, and overlooked a few things).

I was pleased that the CPU and memory worked pretty much out of the box. The CPU boots up running out of FLASH. At reset, the FLASH is readable, and the SRAM is writable. The boot code copies the Forth kernel from FLASH to SRAM, then toggles a bit that switches to running out of SRAM. I think I had to tweak the PAL equations at some point, but it was pretty minor. Once all this was working, I started debugging the PIO, and found that /IORQ was not connected. The PIO symbol had two pin 38s, something the CAD ERC/DRC should have caught (not to mention that *I* should have caught). Once that was connected, the PIO was readable and writable, and it was time to start seeing if we could talk to the IDE drive.

I used a 32MB CF card with a CF to IDE adapter that I had from another project. Things were not going well. It sort of appeared to work at times, but I think that was hallucination or wishful thinking. Finally I dug out the HP 1630G logic analyzer and connected the pods up. I noticed that when I was writing to the IDE port, I would see a status value that was expected when reading. A careful examination revealed that the /RD and /WR pins on the IDE connector were reversed. Much snarling at the person who had their schematic with the IDE pinout that I used. Reversing that suddenly gave much better (but still not entirely correct) results. Also the A0 and A1 lines on the IDE connector were reversed.

Now I had a working IDE card, so I could spend my time playing software person instead of hardware person. Having the Forth kernel was handy, but every time I hit reset I had to download the Forth code to play with the IDE interface. This wasn't bad in itself, but ProComm (a program that I really like) was being stupid about downloads, and not able to wait for the 'ok' prompt before sending the next line. So I had to take a couple of hours to learn how to write an Aspect script that would handle this. That helped dramtically, and I can click one of the soft keys which completely automates the process.

After a couple days I had code that would identify, read and write the CF card, had a loader written that would load the image from the first several tracks to memory, then jump to a loader that would copy the image over the running Forth kernel (since they're both located in low memory), and jump to the loader. Somewhere in this process, I had taken the CBIOS.MAC file for the SIMH CP/M system and started carving it up for my I/O. The IDE code was all written as macros, as were the debugging routines, so I could keep everything as in-line code while testing. So at some point, I pushed reset, loaded the Forth code, typed 'BOOT', and saw a CP/M signon prompt. Happy day!

Most of the next several days involved writing the IDE code as proper subroutines, improving performance (the initial version wasted 384 bytes of every 512 byte sector to make life easy. I have since added deblocking with some minor cache control), documenting, and testing. I introduced a few problems initially, since certain behavior in the CBIOS.MAC file was left to interpetation, or made presuppositions about register values that were not documented. But as of 2003/11/27, I declared the CBIOS.MAC officially stable, with the exception of not having interrupt driven console I/O (that's next).

One of the bigger nuisances was getting files over to the CF card, so I could actually run software. This is sort of a classic bootstrap issue. I solved this by writing a C program on the Gentoo box that wrote the boot image to the card, along with a list of files and directory entries. I would then 'dd' the image to the CF card, put the CF card in the SBC, and run through the boot process. I can now compile the BIOS and build a bootable image on the SBC.

The typical development cycle went like this: Edit CBIOS.MAC on the Gentoo box. Switch the SIMH window, use the R.COM utility to pull CBIOS.MAC into the virtual disk. 'DO BUILD' to assemble, link, relocate, and build the boot image. Use the W.COM utility to put the image back to the Gentoo side. Run the utility to create the disk image with the tools. sftp the image over to the other Linux box with the USB CF card reader/writer. 'dd' the image to the card, move the card to the SBC, hit reset, click the 'Script' button on the ProComm laptop to download, type 'BOOT', and test the results. All in all, from the time I finished editing, I could test an image in about 3 minutes.

Total computers used: 1 Gentoo box running KDE, for editing and to run SIMH. 1 virtual Z80 machine (SIMH) for assembling the CBIOS. 1 Linux box for the USB CF reader/writer. 1 Win2K laptop as a terminal and script machine to talk to the SBC. 1 SBC as the final target.

This covers most of the highlights. Some details were left out, like where I fought long and hard for an hour or so, getting the utility to create the CF disk image to write files of all sizes correctly. And some hardware debugging details got dropped, along with two weeks or so where I got discouraged by the IDE not working and real work interfered with play time.

All in all, I'm quite pleased. The PIO interface to the IDE is working, and throughput is not unreasonable. It takes a guesstimated 2.5 seconds to write 64K to disk (using "SAVE 255 TEST.BIN" as a test case). I have 3 8MB drives on the 32MB CF card (32MB is not really 32MB. It's really 30MB, and I didn't want a special Disk Parameter Block for the last 6MB). Although I didn't design an expansion connector on to this board, I'm probably going to hack a CS8900A ethernet chip on (since I've decided the SOAPOC needs ethernet, too), and either get some CP/M based software running, or try to get Contiki running. Then I'll layout the SOAPOC board, hopefully with fewer errors than I managed on this one.