An Arduino-based QuickDisk emulator for the MZ-800
by Geir Øyvind Vælidalo
This page explains how you can put together an SD-card based Quick Disk emulator with simple means.
All components are readily available on eBay (as of late 2016), and can be put together on a breadboard, vero/perf board or even piggybacked on an Arduino.
It is based on an Arduino Mega with an ethernet shield with SD-card, but you can adapt it to any Arduino and any SPI-enabled SD-card “shield”.
The original Quick Disk interface consist mainly of an address decoder and one Z8440 SIO chip. It is the Z8440 SIO that needs to be emulated here. The Quick Disk itself is a rather simple serial data stream provider unit, it need no special emulation other than reading and writing data streams to and from the SD-card.
A lot of the code is borrowed from mz800emu-project by Michael Hucik.
This is the most important part of this DIY-project. Here you will find how to connect the parts!
For this project, you will need some sort of prototyping board, a bunch of wires, maybe some sockets and headers, but these are the main components:
- Arduino Mega 2560 / 1280 or similar. On eBay
- W5100 Ethernet Shield with SD-kort. On eBay
- One 16V8 GAL chip On eBay
- 74245, 3-STATE octal Bus Transceiver. On eBay
- Nokia 5110 LCD, PCD8544. On eBay
- PSP2000 Joystick On eBay
- Five 1kOhm resistors
- One 10k Ohm resistors
- One 330 Ohm resistors
- 50 pin flat ribbon cable on eBay
This is how you connect the different parts. Please verify that that the pinouts are the same on your components.
NB! I take no responsibility whatsoever if something goes wrong!
How to connect stuff
I mounted everything on a small board. Screwed the flat cable, breadboard and the Arduino Mega on to that board. The Ethernet shield is mounted on top of the Arduino.
Pin one on the flatcable i positioned farthest away. The GAL-chip i positioned closest to the camera and the 74245-chip is closest to the screen.
Start by connecting the cables from the flatcable and to the two chips.
- Pin 41 to GAL pin 1 – A0
- Pin 39 to GAL pin 2 – A1
- Pin 37 to GAL pin 3 – A2
- Pin 35 to GAL pin 4 – A3
- Pin 33 to GAL pin 5 – A4
- Pin 31 to GAL pin 6 – A5
- Pin 29 to GAL pin 7 – A6
- Pin 27 to GAL pin 8 – A7
- Pin 12 to 74245 pin 2 – D7
- Pin 10 to 74245 pin 3 – D6
- Pin 8 to 74245 pin 4 – D5
- Pin 7 to 74245 pin 9 – D0
- Pin 6 to 74245 pin 5 – D4
- Pin 5 to 74245 pin 8 – D1
- Pin 4 to 74245 pin 6 – D3
- Pin 3 to 74245 pin 7 – D2
- Pin 42 to GAL pin 19 – Wait signal
- Pin 18 to GAL pin 11 – WR – Write signal
- Pin 20 to GAL pin 12 – RD – Read signal
- Pin 22 to GAL pin 13 – IORQ – Input Output Request
- Pin 43 & 44 to GAL pin 10
- Pin 43 & 44 to 74245 pin 10 and 19 (Data enable)
- Pin 43 & 44 to GND-pin on Arduino
- Pin 1 & 2 to GAL pin 20
- Pin 1 & 2 to 74245 pin 20
- Pin 43 & 44 to 5V-pin on Arduino
That was the connections from the flat cable.
Now we need to connect the two chips with a direction signal.
- GAL pin 16 to 74245 pin 1 – Direction signal
- GAL pin 16 to Arduino pin D3
S0 & S1 / Port address
The S0 and S1 signal specifies which port is addressed.
- GAL Pin 14 to Arduino pin D6 – S0
- GAL Pin 15 to Arduino pin D7 – S1
- GAL pin 17 to GAL pin 18
- GAL pin 18 to Arduino pin D2 (Triggers ChipEnabled-interrupt 🙂 )
This concludes all the connection from the GAL-chip, so lets finish the data-bus!
Data bus Arduino
On the Arduino Mega, we use port A to read/write the whole byte directly. Port A is pins D22 to D29:
- 74245 pin 11 to Arduino pin D22 – D0
- 74245 pin 12 to Arduino pin D23 – D1
- 74245 pin 13 to Arduino pin D24 – D2
- 74245 pin 14 to Arduino pin D25 – D3
- 74245 pin 15 to Arduino pin D26 – D4
- 74245 pin 16 to Arduino pin D27 – D5
- 74245 pin 17 to Arduino pin D28 – D6
- 74245 pin 18 to Arduino pin D29 – D7
Now all of the address, data and control logic is in place. Left is the LCD and the joystick.
- Arduino 3.3V to LCD pin 1 – 3.3V
- Arduino GND to LCD pin 2 – GND
- Arduino D36 via 1k Ohm resistor to LCD pin 3 – SCE – Chip select
- Arduino D38 via 10k Ohm resistor to LCD pin 4 – RST – Reset
- Arduino D40 via 10k Ohm resistor to LCD pin 5 – D/C – Data / Control signal
- Arduino D42 via 10k Ohm resistor to LCD pin 6 – MOSI – Master out Slave in
- Arduino D44 via 10k Ohm resistor to LCD pin 7 – SCLK – SPI Clock.
- Arduino D46 via 330 Ohm resistor to LCD pin 8 – LED. D46 is a PWM-pin.
And finally we have the joystick:
- Arduino A0 to Joystick pin 1 – Left / Right
- Arduino GND to Joystick pin 2 – GND
- Arduino A1 to Joystick pin 3 – Up / Down
- Arduino 5V to Joystick pin 4 – Vcc
And this is it!
Verify that the connections are ok, that there are no short circuits.
Connect the other end of the 50-pin flat cable into the expansion bus on the Sharp motherboard. Pin one is to the right.
Building a more permanent solution
Breadboards are great for prototyping and debugging, but they are not so good as a long term solution.
As soon as I had tested the solution “properly”, I moved the two chips to a perf-board:
Also I replaced the breadboard cables with small flat cables.
The final solution got room inside the Sharp and I managed to fit the LCD and joystick “temporarily” in front of the cassette player.
As a help for you, I’ve included the pinouts for the components:
Sharp MZ-800 Expansion port
3-state octal bustransiever
The address decoder
The pinout for your Nokia LCD might be different, depending on your source, but this is how my pins are:
*IDENTIFICATION QDEMU; *TYPE GAL16V8; *PINS %INPUTS % A0 = 1, % Address bit 0-7. From pin 14-21 on side A on the Sharp expansion bus% A1 = 2, A2 = 3, A3 = 4, A4 = 5, A5 = 6, A6 = 7, A7 = 8, W_EN = 9, % From pin 8 on the Arduino. Used to disable Wait on CE.% % Pin 10 is GND% WR = 11, % Writesignal from Sharp pin 9 on side B. Active low% RD = 12, % Read signal from Sharp pin 10 side B. Active low% IORQ = 13, % IORQ signal from Sharp pin 11 on side B. Active low% CE_IN = 18, % Input from pin 17. Used to overcome limitations in the "number of product terms"% %OUTPUTS % S0 = 14, % Connected to Arduino pin 6% S1 = 15, % Connected to Arduino pin 7% DIR = 16, % Data direction. Connected to pin 3 on the Arduino and pin 1 on the 74245% CE = 17, % Chip Enable. Connects to Pin 2 on the Arduino% WAIT = 19; %Connected to Sharp pin 20 on side B. Makes the Z80 wait while this signal is low% %Pin 20 is VCC% *BOOLEAN-EQUATIONS S0 = A0; S1 = A1; DIR = /WR; CE = IORQ+/A7+/A6+/A5+/A4+A3+/A2+WR*RD; WAIT = CE_IN+W_EN; *END
Precompiled JEDEC file: QDEMUAD.JED
How to program
Buy a cheap EPROM-programmer from eBay. I have a TL866CS.
Buy an inexpensive GAL16V8D.
I use the command line tool minipro for Linux and Mac:
minipro -p "GAL16V8D" -c config -w QDEMUAD.JED
I’m not going to cover how to program the Arduino, but you get the code for this project here: Arduino Code for QD-emulator
This info is not something you will need to know, but are included for those who wants to understand what’s going on under the hood.
Communicating with the Quick Disk is done via Z80 ports $F4-$F7. This is done using special commands IN and OUT (or INP@ and OUT@ in basic). The Z80 supports 255 ports (65k ports is actually possible too) by setting IORQ-signal LOW and sending the port address to address bus bits 0-7.
For more info about the Z8440, registers and all that, you can read about it here: Z8440
$F4 Channel A – Data channel
This is the data channel used for reading and writing to disk.
$F5 Channel B – Data
This channel is unused. Maybe it can be used later on for a menu system?
$F6 Channel A – Ctrl
This is the control port for channel A.
There are 8 write registers and 3 read, however for emulating the Quick Disk, we use 1 read register and 4 write registers.
- Register 0 (READ)
- Bit 0 – RX Character available
- Bit 1 –
- Bit 2 – TX buffer is empty
- Bit 3 – DCD / Drive is present
- Bit 4 – Hunt Phase
- BIt 5 – 0 = Write protected disk
- Bit 6 – CRC Error
- Bit 7 –
- Register 3 – RX control (WRITE)
- Bit 1 – RX enable
- Bit 4 – Hunt phase
- Register 5 – TX control (WRITE)
- Bit 1 – RTS / Writing new frame(?)
- Bit 3 – TX enable
- Bit 4 – Send Break
- Register 6 & 7 – Sync bytes
$F7 Channel B – Ctrl
This is the control port for channel B.
Like for channel A, there are 8 write registers and 3 read, but we use only 2 read register and 3 write registers.
- Register 0 (Read)
- Bit 3 – Head home
- Register 2 (Read & Write)
- Interrupt vector
- Register 3 – RX control (Write)
- Bit 4 – Hunt phase
- Register 5 – TX control (Write)
- Bit 7 – Motor on
mz800emu – The project most of the Z8440-emulation was taken from.