PLEASE NOTE: I do not sell
production boards. If you would like to buy an M62 Z80 system board/parts kit,
contact Peter Murray,
Peter@39k.ca
I simply provide you with information to build
your own breadboard computer.
Giving credit where it's due
The
Serial Interface board was designed by
Peter Murray to allow the Z80
to communicate on its 8-bit parallel data bus through a 5v Arduino Nano
to your I2C and SPI devices like RTC,
SD, weather sensor, etc.
NOTE:
2019-11-20 I'm still testing the
first version of the PCB that
has returned from fabrication; the 6th item in the adjacent
panel is a picture of it. It seems to work well as long as you use
the upper I2C pins, SDA and SCL. If you wish to use the lower ones,
you'll need to build a solder bridge between the upper and lower SDA
pins and another solder bridge for the upper and lower SCL pins.
NOTE:
2019-12-02 The first 3 adjacent CAD diagrams are for
the second version of the PCB that goes out for fabrication today. Use either design at your own risk.
Overview
If
you attempt to use the Z80 and either an 8255 PPI/PIO or a UART to
communicate with
SPI
or
I2C devices like a Real Time Clock
(RTC) or Barometric/Temperature sensor, etc., you're probably going to
have to
bit-bang the processor to
communicate with these modern modules.
One
alternative to this kind of "pain" is to let a microcontroller like
the Arduino Nano do all the "heavy lifting". Instead of the Z80 sending
one bit at a time serially, it will send 8 bits in parallel on its
Data bus to the Nano. The Nano in turn will send the data using
either the I2C or SPI protocol to communicate with the device.
How does the Z80 write to or read from the Nano?
Z80 -> Nano: The Z80 issues an OUT instruction to the Nano.
This sets the data bus with the data. The addressing circuitry will
trigger a latch holding the Z80 in a Wait state while notifying the Nano and giving it time to a) read the data off the bus, b)
determine the address it was trying to reach, and c) release the
latch allowing the Z80 to resume.
Nano <- Z80: the Z80 issues an IN command to the Nano which
triggers the latch and notifies the Nano. The microcontroller will
read the address and load its data bus with the appropriate
response. The latch is released by the Nano so the Z80 can read the
data via a '244 buffer.
General Operation
During a Z80 write-to-IO-bus operation, '244 IC4 is enabled via the
Nano
A_RD signal to gate the
Z80 D0 to D7 signals onto the Nano bus.
During a
Z80 read-from-IO-bus operation, '244 IC5 is enabled via the
A2Z (Nano to
Z80) signal to gate the Nano A_D0 to A_D7 signals onto the Z80
bus. It was initiated via the Z80
RD signal to the
Nano.
For orderly flow, the
WAIT signal to the
Z80 is used whenever a Z80 (I/O) OUT or IN instruction for the I/O
address range is executed. The Nano was initially interrupted via the
A_INT signal. Normal operation is resumed when the
Nano sees the A_REL
signal.
Operations nitty gritty
Use
schematic 'M62-bus_Serial_IF_Bd_01.png',
Arduino sketch
Z80-Nano_SIF.ino, and the ROM Monitor to enter OUT or IN commands to
the Z80.
Within the sketch in the 'setup()' code,
A_REL (nRELEASE) and
A_RD (nREAD) are both set
high and a low-going interrupt is attached to
A_INT (nINT).
To get the Nano to write or read I/O data, use the Z80's ROM Monitor
to write a value to the I/O address you jumpered on the Serial
Interface board.
In the lower adjacent screenshot "LA
View of Z80 'Write' to Nano", you can see the user has
started up the Monitor and has issued an 'o' or 'O' command to
output a value to an I/O address: the Monitor function uses the Z80
instruction 'OUT (C),A'. The first byte in the Monitor command that follows is '20' to
indicate an I/O address/port of 0x20, and the next byte is '00' to
indicate a value of 0x00.
In the same screenshot in the lower right we can see the Nano
Serial Monitor display "Debug: Z80 wrote 0 to 0", followed by
"Debug: Z80 wrote 0 to 1" meaning the value 0x00 was written to aA0
and aA1 locations of 00 followed by 01 . The Nano is not aware that
the Z80 has been jumpered to a base I/O address other than 0x00.
Using schematic 'M62-bus_Serial_IF_Bd_01.png'
and assuming a base I/O address of 0x20, when Z80 addresses 0x20 to 0x23
are used:
- Z80's A0 and A1 (schematic frame location A3) are read into the Nano as aA0 and aA1 (see
lines 25 and 26 of the Arduino sketch, Nano inputs A6
and A7) which causes a low to go out JP2 (location A6)
- a high goes out IC3D pin 11 which is input to IC3C pin 9 (location B6)
- IC3A Reset is high and so
is A_REL (location
B5) by default
in the Nano sketch. The high into IC3C at pin 10 combined with the
high from IC3D pin 11 causes a low out IC3C pin 8 which triggers the
WAIT line (location
B4) to the Z80.
- This low out IC3C pin 8 also fires a low on
A_INT to the Arduino
Nano; this is an interrupt to the Nano.
- According to the Nano sketch, a routine labeled 'theISR' will now run.
- In summary, the Z80 is holding in a Wait state and the Nano is going to
run an interrupt service routine.
theISR() runs:
- the variable 'address' from procedure 'readAddress()' at line 99 returns the value
of the aA0 and aA1 pins. (You could use the 'Registers' in the
sketch for your own needs, e.g., read the 'seconds' counter from an RTC, etc.)
- the variable 'DataIn' from routine 'readData()' at line 107 sets Nano 'nREAD'
output A_RD (location
D5) to low to
read from the Z80 bus. We see the signal
A_RD gate both halves
of IC4 so that the data queued on the Z80 data bus is gated to the
Nano data bus composed of A_D0 to A_D7. The setDataDir()
procedure at line 109 is set to input, so the 8-bit wide Z80 databus is read bit
by bit into the Nano as value 'temp' in lines 114 to 121. Setting nREAD (A_RD)
high at line 122 at the bottom of readData() ceases the Z80 bus read to the Nano
and the value 'temp' is returned to DataIn.
- the data direction variable, DIR, is read next in theISR(), line 77. DIR is
determined to be high or low by the state of the Z80
RD line, location B4. If DIR is
high (1) in the 'if' statement, then the statement that follows is
true so it's a write (RD
= 1). The comm is from the Z80 to the Nano, hence we see the Serial
Monitor report "Debug: Z80 wrote [DataIn] to [address]." In the
circuit, we see gate IC2B (location C6) gate the Nano bus queued data to the Z80
databus through the '244s.
- if the data direction variable DIR is read to be low (0), then the
statement is false so 'else' in line 85 is executed. The comm is from the Nano
to the Z80 and we'll see the Serial Monitor report "Debug: Z80 read
from [address].
- The Nano has been writing or reading data but the Z80 is still in a wait
state. The last two statements in theISR() routine toggle the
A_REL line low then
high which sets A_INT
high which in turn terminates the
WAIT signal.
There is no loop in the Nano sketch. That is up to you with whatever
device you attach to the I2C or SPI connectors on the SIF board.
The SPI and I2C male
jumpers:
Your Z80
can now talk to SPI- or I2C-based devices.
I2C uses
jumpers JP4, JP6, JP8 and JP10.
SPI uses
jumper JP16. If you wish to add 2 more SPI devices, then disable I2C
(SDA and SCL) with jumpers JP22 and JP23. That will make jumpers
JP18 and JP20 available for SPI for a total of 3 SPI devices.
Termination Resistors:
Both SPI
and I2C can be finicky, especially when it comes to signal
terminations needed for master or slave modes.
As such,
I have provided optional 4.7K pullups for I2C. The original Adafruit
DS1307 RTC I tested with this SIF board had 2.2K pullup resistors. I
removed them and used the SIF board 4.7K resistors and it worked
fine.
Additionally, I have provided optional 10K pullups and 4.7K
pulldowns for SPI. You can see them labelled in the upper part of the
schematic.
What do I need to program the Arduino Nano 5v?
Arduino Code:
Nano-Z80_SIF.ino
How
do I test the Nano Serial Interface (SIF) board?
Upload
the sketch to the Nano, then start up the Arduino IDE's Serial
Monitor function under Tools.
Fire up
your Z80's ROM monitor and issue an OUT instruction to address 0x20
with data 0x00. This is assuming you have jumpered the SIF for I/O
address 0x20. You can see that in the adjacent screenshot,
Z80 Write Nano.
Then try
an IN instruction of address 0x23. You can see that in the adjacent
screenshot,
Z80 Read Nano.
The
Logic Analyzer (LA) view of writes and reads
With a
Z80 write to the Nano, there is no reason to use the A2Z gate.
That's why we see it high in the adjacent "Write" screenshot.
With a
Z80 read from the Nano, the A2Z gate is enabled immediately. That's
what we see in the adjacent "Read" screenshot.
I
see the schematics. Where is the Bill of Materials parts list?
The
BOM is at the bottom of the adjacent panel.
How big is the Serial Interface board and what will the printed circuit board look like?
The
PCB measures 100mm x 100mm (4" x 4") or 100mm x 150mm (4"
x 6"). Click the adjacent
thumbnail
to see a possible parts layout.
Now that I've got the SIF board working, where do I go from here?
Adapt your fave real-time clock (RTC) board like the
DS1307 or the
DS1340 using the to the Nano
sketch above and the Arduino Library
RTC drivers. Then write some Z80
code to read the Registers created in the Nano sketch. We will be
doing this at a later date when we design, build and test a board
containing various I2C and/or SPI devices.
Note: M62 Bus is copyrighted by Peter
Murray of Murray Electronics,
http://www.39k.ca |