Saturday, January 19, 2013

Phoenix: CPU


8-bit home computers in the early '80s were predominantly based around the 6502 and Z80 processors. Since I grew up with a ZX Spectrum, I decided to base Phoenix around the Z80 (unlike Veronica, which is 6502-based).

The Z80 is an 8-bit processor, with an 8-bit data bus and 16-bit address bus. The latter means it can address up to 64 KB of memory. CMOS Z80's can run at up to 10 MHz. As a comparison, the ZX Spectrum ran at 3.5 MHz.

Apparently, brand new Z80's are still being made even today, more than 30 years after the chip was first introduced. The one I bought from Digi-Key had a date code of 1229, which if I read it right means it was produced in July of 2012.

To get a Z80 up and running, you need a clock signal (not just a crystal). The final Phoenix design uses a 6 MHz oscillator chip but for this post I used a oscillator made out of some components I had at hand: a 16 MHz ceramic resonator, 74HC00 NAND IC, some resistors and and a 74HC74 dual flip flop.  The resonator, resistors and 74HC00 together produce a 16 MHz clock signal, which is then halved twice by the flip flops down to 4 MHz.

The Z80 needs a reset pulse to properly initialize itself. This can be generated easily using a capacitor to ground and a resistor to 5 V.


In addition to the clock and reset signals, all that's needed is to keep the control signals (interrupt, bus request, etc.) in a defined state. Note that these are active-low so need to be connected to 5 V.

Since the data bus is bidirectional, I hooked up the data pins to ground using 10 kΩ resistors. This way there won't be a short if the Z80 issues a write, and a read cycle will produce all zeroes. Conveniently the 0x00 opcode is NOP, so if all works well the Z80 would just execute a steady stream of NOPs, as if it were connected to 64 KB worth of memory filled with zeroes.

Using my Saleae Logic analyzer, we can observe this in practice:


This looks exactly like the timing diagram in the Z80 data sheet. The first line is the 4 MHz clock signal, and we can see that the other signals repeat every 4 clock cycles. Keep in mind that all these are active-low. The MREQ (memory request) is pulsed twice during each instruction, first together with RD and M1 to read an opcode from memory, and then together with RFSH as a DRAM refresh signal.

Let's try a more interesting instruction. Changing pin D4 from 0 to 1 puts 0x10 on the data bus, which is the DJNZ instruction (decrement and jump if not zero):


Here the pattern takes a whopping 13 clock cycles. It starts out like the last one: first an opcode read (MREQ, M1, RD), followed by a memory refresh (MREQ, RFSH). Then there is another memory read to get the jump displacement (MREQ and RD, but without M1 this time). And then another 5 cycles where nothing happens on the bus and the Z80 executes the jump internally.

As you can see, the Z80 is a relatively slow processor requiring 4 clock cycles for even the simplest instructions, in contrast to the 6502 which could execute instructions in a single cycle. The ZX Spectrum ran at 3.5 MHz Z80 whereas the Commmodore 64 had a 1 MHz 6510.

Here's a picture of the Z80 on my breadboard hooked up as described above. On the left are the two ICs to generate the 4 MHz clock signal and on the right is the big Z80 chip with the logic analyzer probes still attached to it.


Of course, executing the same instruction over and over is not very exciting, so in the next post we'll add some memory.

No comments:

Post a Comment