Benchmarko Logo
Benchmarko Logo
Home
Projects
CPCEMU
Software
Download
Contact
Links

German
 
back

CPCEMU - The Story

On the Amstrad CPC I did my first steps towards computers. For many years I have intensively used this system. I learned BASIC and Assember in self-instructions, later Pascal by suggestion from school. I nearly knew each storage location of the 64 KB main memory by heart. I called kernel entries, which belong to the low-level "operating system" of the CPC. In order to achieve maximum speed on a 4 MHz system, I directly programmed the hardware. It was an ideal play meadow for fiddling.

The step towards the PC

When I got a PC years later, my experiences were worthless. Everything was so new, I felt myself like a beginner and was somehow lost. Quite early I had an idea: It should be possible to copy the functionality of the CPC to the PC, thus simulating or, speaking about hardware, emulating it. Emulating on the low hardware level.

At first it was only a Z80...

I started simulating the processor, the Zilog Z80A. In Pascal I tried to create a virtual Z80 on the 80x86. Each Z80 instruction was interpreted and simulated by a sequence of 80x86 instructions, operating on virtual registers and memory.

To my surprise, it worked very well, however it was badly slow. When I heard that one could program in C more machine-oriented I converted the emulator code into C. I had gained my first experiences with C in a programming course at University. Our task was to develop Logo-like turtle graphics on an UNIX X Windows system. A little interpreter was also included. It was a nice teamwork to see how our modules finally fit together... For the emulator I wanted to find the most performante solution in C, using all possible programming tricks I could imagine of. I filed months-long on how to convert the Z80 instructions as fast as possible.

... and finally - a real CPC

I enjoyed to see a provisionally simulated screen output of a CPC. To achieve this I wrote a little program to dump the original ROM of the CPC 6128 into a file. Since I owned 5.25" drives for both the CPC and the PC, it was easy to copy the ROM image to the PC. I loaded it into the emulator, and -- it did nothing. Just some error messages. After some more bug fixing it worked: The power-up message of the CPC appeared on my PC. The CPC lives! What a success! It was just black-and-white, but I barely noticed it, my original CPC has also a green monitor only. So it was really possible!

The memory banking in the CPC was a bit tricky. The Z80 can only address 64 KB, but even the CPC 464 has 32 KB ROM + 64 KB RAM (and the CPC 6128 has even more: 128 KB RAM). So the additional memory must be mapped into a 64 KB address area somehow. The early PC had a similar problem: Its first CPU Intel 8088 could only address 1 MB. Under DOS only 640 KB remained. But with EMS (Extended Memory System) it was possible to address all the memory under DOS, mapped into an adress window below 1 MB.

Speed rules

On my PC 386 with 33 MHz the C-variant of the emulator did by far not reach the speed of the original CPC. And that despite of all possible optimizations. Thus I had to learn PC assembler. Coincidentally I discovered ZSIM von Juergen Weber. It was an CP/M emulator written in assembler. And it was quite fast. I told Juergen of my project and he was immediately willing to support me not only with the source code. I had no experiences with Assembler for the 80x86, segment registers and the whole stuff. Juergen had the ingenious idea for the banking concept with segment registers. Just by changing the segment registers and adding an offset we could simulate the entire banking concept of the CPC! Also RAM below ROM was easy (reading from ROM, writing into the RAM below).

I was astonished about the tricks Juergen used in his assembler module, responsible for maximum speed. For example there was no central interpretation loop but one for every instruction. The code for getting the next instruction was attached, which saved always a direct jump. Another example is that the branch destinations were particularly aligned. This allowed to find them by a simple address computation, avoiding to look them up in a jump table.

A Z80 as a coprocessor

Even with the nice assembler module I did not want to completely throw away my Z80 emulation in C. So I left the code in the emulator and you can switch between my slow Z80 simulation or Juergens fast one. For debugging purpose I used a special mode, "coprocessor technique" called CO-Z80. In this mode each Z80 instruction is simulated simultaneously by both kinds of emulation. The registers and the memory cells must be identical after each simulated instruction. So I could determine numerous differences during emulation and remove bugs. It was not easy to simulate all the undocumented Z80 OP-codes and flag register changes correctly.

A new Design in C++

This way I learned C and assembler on the PC very well. But after some time it got harder and harder to keep the overview. Thus I started to rewrite the C parts in C++ and to sketch a class model of the CPC hardware. Clearer code was more important to me than a few percent more speed. Nevertheless there were Inline functions now under C++. Thus I became acquainted with at least the fundamentals of C++.

And the emulator became ever better or at least more user friendly. It achieved a good compatibility to the original, however never completely. For accurate simulated raster interrupts I would have to rewrite whole screen output. This seemed too complex for me.

Finally...

This way I saved my CPC experiences into the world of the PC. And I hope it is more easy for many CPC users to get along on the PC.

I would like to thank all CPC enthusiasts, who supported me and gave me numerous ideas on how to improve the emulator more and more!

Enjoy it!

Marco Vieth, September 2001

MV, 04.03.2006 20:51:46