I've made a few shields lately and this has to be the meatiest. From L to R we have a venerable Z80. Next to that is a svelte 32KByte RAM. Continuing on we have the ubiquitous reset button and last - but definitely not least - a little CPLD. In this case it's a Xilinx XC9536XL.
The idea came about after some back-and-forth discussion with a friend about making a Z80 based trainer and what would be involved. The theme of AVRs came up and after a brief dalliance with the idea of putting an Arduino on the nascent Z80 board to act as a communication port it naturally flipped over and the concept of the Z80 shield was born.
The Arduino acts as clock source, CPLD programmer, bootstrap ROM and IO handler. The CPLD performs the fairly ordinary task of being a memory and IO controller. It also has a Dirty Little SecretTM.
The more observant may have noticed that the board is a little unusual as there's no ROM. And no, I didn't just forget it. It's not a problem. All you need to be able to do is get program and data into memory. The bootstrapping of the Z80's program therefore needs to be performed using a little hackery. Which is where the CPLD's DLS comes in.
Hold on - I can't keep referring to the CPLD as 'the CPLD'. That wouldn't be fair. When it arrived from the kindly Mr. Farnell's shoppe it was called 'the CPLD'. But once programmed then I'm sure you'll agree it has become something more than the sum of its parts. A custom chip no less. Amiga has Agnes, the 64 has Sid. If I'm to be true to the board then I must insist that from now on we refer to this fine chip as Alan, the name it chose. OK. Continue.
Alan can store and output a byte upon request. The Arduino can write and read this byte, as can the Z80. Aha! It's starting to come together! As Alan controls the Z80's access to memory then it's a simple matter of casually outputting the content of the latch onto the data bus at opportune moments, rather than the content of memory. Just assert a control line so Alan knows when you'd like this behaviour, and you can deliver instructions to the Z80 at your will. Construct your bootloader such that it doesn't need to read RAM or loop and you are, as some might say, golden.
Alan exposes a read-only copy of the Z80's RD line, which can be used to synchronise writes to the latch. The process goes like this:
Assert Z80s RESET line
Assert 'bootload' signal
Pre-warm the latch with the first byte of your bootstrap program
Release Z80s RESET line
Repeat until all bytes of bootstrap written:
Wait for RD to go low (z80 is reading an instruction, delivered from the latch)
Wait for RD to go high (z80 processing instruction)
Write the next byte of the bootstrap program to the latch
De-assert 'bootload' signal
Reset Z80
From there you have a program stored in RAM which the Z80 happily executes ad infinitum, or until the PC powers down. Whichever is soonest.
The Z80 can instigate data exchange with the Arduino. This is achieved using IO requests. To avoid critical timing constraints I opted to use a cool feature of the Z80 - the ability to pause processing whilst an IO request completes. Alan notices when an IO request is in progress and asserts the Z80's WAIT line, which puts the processor into suspended animation until such time as the line is cleared. At this point normal service is resumes and processing continues as if nothing had happened. The WAIT line is exposed to the Arduino so it can detect when an IO is under way. Used in conjunction with the RD line it can be used to detect both IO writes (Z80 wants to send data to Arduino) and reads (Z80 wants data from Arduino).
Z80 IO read:
IN instruction is detected by Alan
WAIT is asserted
Arduino detects the request & puts data byte into Alan's latch
WAIT is released by arduino
IO instruction completes, data from the latch is taken from the data bus
Z80 IO write:
OUT instruction is detected by Alan, data from the bus is stored in the latch
WAIT is asserted
Arduino detects the request & reads the latch
WAIT is released by arduino
IO instruction completes
The project is still in its infancy, but is working to an encouraging level :D
No comments:
Post a Comment