Initial commit - Begun rewrite of website generator
This commit is contained in:
172
pages/2013-01-21-Z80-Tester.md
Normal file
172
pages/2013-01-21-Z80-Tester.md
Normal file
@@ -0,0 +1,172 @@
|
||||
layout: post
|
||||
title: "Z80 Tester"
|
||||
subtitle: "Bouncing buttons"
|
||||
tags: [electronics]
|
||||
|
||||
In the [last post](/2013/01/Z80-Information/) I said we only needed two
|
||||
pieces of support circuits to get a Z80 running, namely a clock and a
|
||||
reset circuit.
|
||||
|
||||
Let's take a look at the most advanced one first; the clock signal
|
||||
generator.
|
||||
|
||||
{: .right}
|
||||
|
||||
Clock signal
|
||||
------------
|
||||
|
||||
The Z80 needs a 5V square clock signal.
|
||||
|
||||
For testing purposes it's ok to generate the clock signal by hand. The
|
||||
easiest way to do this requires only a switch and a resistor configured
|
||||
like the figure on the right.
|
||||
|
||||
Let me just stop you right now and tell you that this won't work.
|
||||
|
||||
Why? Well, take a look at the output in an oscilloscope:
|
||||
|
||||

|
||||
|
||||
Doesn't look so bad, does it? Well, let's take a closer look at that
|
||||
falling edge to the left. Here it is, zoomed in about 250 times:
|
||||
|
||||

|
||||
|
||||
Now that's not pretty. If you used this clock circuit, for every time
|
||||
you press the button, the Z80 will receive a dozen pulses or two. That
|
||||
makes for some very unrepeatable behavior, and repeatability is what
|
||||
computers are all about.
|
||||
|
||||
{: .right}
|
||||
|
||||
A better clock signal
|
||||
---------------------
|
||||
Here's a good clock generator. It requires two switches which are pushed
|
||||
alternately, two pull-up resistors and two NAND gates (e.g. 74HC00).
|
||||
|
||||
This is what's called an S-R-latch (S-R is short for Set-Reset).
|
||||
|
||||
Let's say the clock output is currently HIGH (+5V) and that no switches
|
||||
are pressed. The upper NAND gate then has two HIGH inputs, which means
|
||||
its output is LOW (0V). The lower NAND has one LOW input and one HIGH,
|
||||
which means its output is HIGH. By pushing the top button, one of the
|
||||
inputs to the top NAND is grounded so that its input is (LOW, HIGH)
|
||||
which means it outputs HIGH. This means the lower NAND gets the input
|
||||
(HIGH, HIGH) which makes its output LOW and when the button is released,
|
||||
the top NAND will have the input (HIGH, LOW) and thus still output HIGH.
|
||||
|
||||
It's a bit simpler to understand if you just think about it than if you
|
||||
try to read my messy explanation, but you must assume that the clock
|
||||
signal is either HIGH or LOW before you start thinking.
|
||||
|
||||
{: .left}
|
||||
Anyway, I built this circuit on a bread board and measured it the same
|
||||
way as the last one.
|
||||
|
||||

|
||||
|
||||
Nice and clean. We've got our clock source.
|
||||
|
||||
Reset switch
|
||||
------------
|
||||
When it comes to reset the Z80 is not as picky as with the clock signal.
|
||||
In fact, we can use the first attempt at a clock signal for reset.
|
||||
|
||||
The internal reset circuitry of the Z80 depends on the clock signal,
|
||||
so as long as the clock doesn't move, whatever happens with the reset
|
||||
signal doesn't matter.
|
||||
|
||||
This fact is important to rember for other reasons too; to perform a
|
||||
reset, the reset pin must be pulled low for a few clock cycles.
|
||||
|
||||
In other words: To perform a reset, push the reset button, toggle the
|
||||
clock a handful of times (minimum three), release the reset button.
|
||||
|
||||
That took me a while to figure out and is why you should always read
|
||||
your datasheets carefully, kids.
|
||||
|
||||
A similar note of caution: Don't leave the clock signal in its LOW state
|
||||
for any extended periods of time or the Z80 will forget its state. To be
|
||||
sure, always make the clock HIGH right after making it LOW. You could
|
||||
add an LED to show its current state.
|
||||
|
||||
Let's wire it up
|
||||
|
||||
Z80 tester
|
||||
----------
|
||||

|
||||
|
||||
Here's a Z80 tester circuit wired up on my breadboard.
|
||||
|
||||
The connections are as follows:
|
||||
|
||||
- `D0`-`D7` are pulled low through resistors of ~1kΩ.
|
||||
- `/INT`, `/NMI`, `/WAIT` and `/BUSRQ` are connected to +5V.
|
||||
- `+5V` and `GND` are connected as labeled.
|
||||
- `/RESET` is connected to a pull up resistor and a button as described
|
||||
above.
|
||||
- `CLK` is connected to an Arduino nano which generates a 500 Hz square
|
||||
signal (I felt a bit lazy).
|
||||
- `A0`-`A7` are connected to the logic probes of my oscilloscope.
|
||||
|
||||
But before I power this up, let's think about what we're expecting to see.
|
||||
|
||||
As we release the reset button (after keeping it down for three clock
|
||||
cycles or more) the Z80 starts to read instructions at address `0x0000`.
|
||||
|
||||
Since all data pins are permanently tied low it will read the value
|
||||
`0x00` which corresponds to a `NOP` instruction. This means it skips
|
||||
ahead to address `0x0001` to read its next instruction and so on.
|
||||
|
||||
In other words, we expect the 8 lowest address lines to count upwards
|
||||
binarily from 0 to 255. Since there are 8 address lines we're not
|
||||
monitoring, it should make this count 255 times before getting back to
|
||||
address `0x0000` again. But we won't be able to see the difference
|
||||
between the counts.
|
||||
|
||||
Ok, let's take a look.
|
||||
|
||||

|
||||
Just like that. This Z80 seems to be working fine.
|
||||
|
||||
All 255 addresses didn't quite fit in this picture, but you can see
|
||||
address `0xXX00` to the left and `0xXX7B` to the right.
|
||||
|
||||
Scrolling forwards a bit in time we find something interesting.
|
||||

|
||||
|
||||
See that thing on `A7`? It's not stable, but is pulsing. The same
|
||||
behavior can be seen on `A8`-`A15`. But why?
|
||||
|
||||
Dynamic memory refresh, that's why.
|
||||
|
||||
As I described in the last post; right after fetching an instruction,
|
||||
the Z80 sends a refresh pulse to the memory chips. During this pulse, it
|
||||
also sends an address on the 7 lowest address lines, i.e. `A0`-`A6`. The
|
||||
other address lines are pulled low.
|
||||
|
||||
Let's take a closer look at the signals used.
|
||||
|
||||

|
||||
|
||||
Here I also connected to the oscilloscope
|
||||
- `/M1`
|
||||
- `/MREQ`
|
||||
- `/RD`
|
||||
- `CLK`
|
||||
|
||||
We can clearly see the instruction fetch cycle. `/M1` goes low, followed
|
||||
by `/MREQ` and then `/RD`. Then all three goes high while the processor
|
||||
is decoding the instruction.
|
||||
|
||||
During the decode cycle, we see `/MREQ` go low again. This is the memory
|
||||
refreshing. I didn't connect the `/RFSH` line to the oscilloscope but,
|
||||
trust me, it goes low at about the same time.
|
||||
|
||||
Next is the execute cycle, which for the `NOP` instruction is nothing at
|
||||
all, so the processor jumps right to the next instruction fetch cycle.
|
||||
|
||||
|
||||
Ok... so the Z80 is indeed working as expected.
|
||||
|
||||
Next time we'll look at a control panel.
|
||||
Reference in New Issue
Block a user