Building a Z80 Emulator Part 2
1/26/2014 2:58 PM
It’s been a few weeks since my first post regarding my attempt to produce a Z80 emulator and much has changed. What appeared a few weeks ago to be a fairly simple endeavour turned out to be a significantly longer development than I had expected. With this post I will walk you through some of the issues I encountered and how I tackled them, but first the interesting part.
Get the Source
As of the time of this post I have made the source of the Emulator available on my Github HERE.
This version has a vast majority of the Opcodes added and tested, with an example test program that emulates drawing a diagonal line on the screen of a ZX Spectrum 48k.
Getting the Facts
The Zilog Z80 CPU is an extremely well documented core due to its wide use and age, so getting the information I needed to build the emulator was never a challenge. I would give you a large list of links that I found useful, however I’d be wasting your time thanks to this fantastic website: http://www.z80.info/
The purpose of this page and its sub pages about members of Z80 family (and close relatives) is to collect and share information and good ideas. I know there are lots of people out there, who have developed some good utilities and hardware solutions. Now we all can share this information.
This page contain docs, FAQs, source code, (cross-)assemblers, (cross-)compilers, utilities, etc. as well as links to other Z80 relevant stuff.
Something that I have not yet tackled at time of writing this is matching the timings of the processor. The current code available in version 0.1.1 runs as fast as possible which in excess of 10 million instructions per second, is a tad faster than a 4mhz Z80. The easiest way to go about matching the timings would involve implementing waits based on the T state timing information available here http://www.z80.info/z80sean.txt.
Testing the Emulator
One of the hardest parts of building the emulator was ensuring that the opcodes functionality I was writing matched the functionality of the real thing. For this I employed a number of tools.
The first and easily the most important was the Z88dk.
z88dk is a z80 C cross compiler supplied with an assembler/linker and a set of libraries implementing the C standard library for a number of different z80 based machines. The name z88dk originates from the time when the project was founded and targeted only the Cambridge z88 portable.
The compiler featured in z88dk is a much enhanced Small C compiler; the compiler accepts many features of ANSI C and is only deficient in a few areas where implementation on a z80 processor might prove inefficient. The compiler performs simple optimisations, but the bulk of the optimisation is achieved by a set of peep-hole rules, which will typically reduce the size of a large project by up to a third.
The Z88dk allowed me to build simple c programs to test the functionality of my emulator. As I increased the complexity of the test C files, the number of opcodes increased causing a wider range of opcodes to be involved in the programs execution. Running the test programs and stepping through the execution of them whilst watching key sections of memory allowed me to ensure they functioned correctly, or in the event of an error diagnose the issue. To build a c program for the ZX Spectrum as a ROM (including keyboard and interrupt handler) can be achieved with the following line.
zcc +zx -lndos -lm -startup=2 -make-app -otest.bin test.c
The second tool I used was a Z80 core simulator created by OShonSoft
Z80 Simulator IDE is powerful application that supplies Z80 educators and developers with user-friendly graphical development environment for Windows with integrated simulator (emulator), z80 basic compiler, assembler, disassembler and debugger for Zilog Z80 8-bit microprocessor.
Having a simulator that you can compare the running of your emulator against is key. The OshonSoft z80 simulator was fantastic for comparing the state of registers, memory and more.
What’s Next ?
There are still a number of IX IY and ED Opcodes that require implementation, beyond that the next goal of the emulator would be the timings (as discussed above) and emulated Input Output. Getting the Basic editor and running some old and simple app’s would be a significant milestone.
As an added bonus I thought about getting this running on my fantastic little Raspberry PI. All it took was compiling the source with GCC using the line below and it ran first time.
gcc -std=c99 Emulator.c -o bin/run