RC2014 Bootloader for SD Cards

So, the RC2014 is great.  I can run Microsoft BASIC and program it from there, and as long as I am using a terminal emulator, I can copy & paste to save and load programs.  Alternatively, I can write Z80 code using an online compiler then download it, copy it to USB stick, move it to my old Windows 2000 laptop (which has a parallel port) so I can burn it on to EPROM to see if it works, make adjustments and repeat with another EPROM.

I will be the first to admit, however, that this is probably not the most efficient workflow.  Not to mention the time and effort involved in wiping the limited stock of aged EPROMS.

So, I am in the process of designing an SD Card based bootloader.

i (2)

Interfacing a Z80 to an SD card isn’t totally straightforward though.  For starters, the Z80 runs on an 8 bit parallel data bus, but SD cards use a Serial Peripheral Interface (SPI).  The Z80 is 5v, the SD card us 3v3.  And as for using the Z80 to address a particular memory location on the card… well, forget it!

[Sometimes I seriously wonder just how Zilog expected their Z80 to address things like 512GB of SD card when they designed it back in 1975!]

So I’ve decided to use a modern ‘cludge’ to provide the glue to stick the two parts together..  An Atmel ATMEGA328 (Arduino) speaks SPI and has enough pins to provide an 8 bit signal.  I will use the same interfacing technique as I used with the LED Matrix displays so that there’s a buffer between the Z80 and ‘328

IMG_20140911_210721 (2)

I hooked up a rough and ready breadboard & Arduino test to prove the concept, but initially I had lots of Odd Things™ happening, and all but came to giving up.


At the last moment, I spotted the school boy error.  The power rails of my breadboards are divided in to two halves, and despite having things connected to both sides I didn’t have anything to connect the two.  So the decoder chip was being back-fed through the SD card adapter.  Ooops!  In my defence though, it really is bloody stupid for breadboard manufacturers to not join up the power rails all the way through.  It is bad enough that the two sides aren’t linked – although I can appreciate you might want maybe a 5v and a 3v3 volt rail… but splitting it down each side too, well, this has now become a more of a rant than a blog.

Screenshot from 2014-09-14 22:15:22

So, with the Arduino able to put characters on the Z80 data bus that I could read with BASIC, I decided it was time to take it to PCB level.  I’ve got 8 bytes of data input from the ‘328 to the Z80 via a 74HC245 and 3 bits of output from the Z80 to the ‘328 via a 74LS374 selected from a 74LS138.  (There is also 3 output lines going to LEDs for status monitoring).  The hardware should be easy enough, so I’ve laid out the PCB and sent it off to OSHPark to be manufactured.  It is, however, the largest and most complex board on the RC2014 so far.

The software will be the tricky bit for me.  Firstly, I need to write a boot loader in assembly language and burn it to an EPROM (wasn’t this what I was trying to avoid???).  Secondly, I need to write an Arduino sketch that will read an SD card and write it out to the 8 bit parallel bus.  From a timing perspective, I have assumed that the Z80 will write to it’s output so the ‘328 will know to put the first byte of the SD card on the bus.  The Z80 will then read this, write it to RAM and signal to the ‘328 it wants the next byte.  And repeat until done then set the Program Counter to the address in RAM to execute the code.

I have deliberately chosen a request/send model so that timing issues are avoided – partly because I don’t know if there would be timing issues, and partly because one of the things I would like to do is run the Z80 very very slow (so I can see what is going on), and this should still work.

Initially, I will gloss over the issue of file size and memory location by assuming a file size of 1k (with the ‘328 padding with FF to make up the balance) and that all programs are run from 0x8000.  I can, if needed, add in a file on the SD card that defines these parameters that the ‘328 can send as a preamble… but we’ll cross that bridge when we get there!