Benchmarko Logo
Benchmarko Logo
Home
Projekte
CPCEMU
Software
Download
Kontakt
Links

Englisch
 
zurück

CPCEMU - Die Story

Auf dem Schneider CPC habe ich meine ersten Gehversuche mit Computern unternommen. Jahrelang habe ich mich intensiv mit dem System beschäftigt, im Selbststudium BASIC und Assember gelernt, später Pascal durch Anregung aus der Schule. Ich kannte sozusagen jede Speicherstelle der 64 KB auswendig, war mit dem Kernel, dem "Betriebssystem" des CPC vertraut. Um maximale Geschwindigkeit auf dem 4 MHz-System zu erreichen, habe ich natürlich auch die Hardware direkt programmiert. Es war die ideale Spielwiese zum Tüfteln.

Der Schritt zum PC

Als ich dann Jahre später einen PC bekam, konnte ich mit meinen gesammelten Erfahrungen nichts mehr anfangen. Alles war neu, ich kam mir vor wie ein Anfänger und fühlte mich verloren. Schon recht früh kam mir die Idee, daß es möglich sein müßte, den CPC auf dem PC nachzubilden, also zu emulieren. Und zwar auf der niedrigsten Ebene der Hardware.

Zuerst nur ein Z80...

Also fing ich mit dem Prozessor an, dem Zilog Z80A. In Pascal versuchte ich, auf dem 80x86 den Z80 virtuell nachzubilden. Jeder Z80-Befehl wurde interpretiert und in eine Folge von Anweisungen verwandelt, die auf virtuellen Registern und virtuellem Speicher operierten.

Das klappte zu meiner Überraschung ganz gut, war aber arg langsam. Ich hatte gehört, daß man in C maschinennaher als in Pascal programmieren könnte, also schrieb ich den Emulator in C um. Meine ersten Erfahrungen mit C hatte ich in einem Programmierpraktikum über Turtle-Grafik gesammelt, in dem wir in Teamarbeit einen Logo-Interpreter in C programmierten. Jetzt ging es darum, eine möglichst performante Lösung in C zu finden und alle möglichen Tricks auszunutzen. Monatelang feilte ich daran, wie man die Z80-Befehle möglichst schnell umsetzen kann.

... und schließlich ein richtiger CPC

Einen der größten Erfolge erlebte ich, nachdem ich die Bildschirmausgabe provisorisch simuliert hatte. Ich hatte das originale ROM des CPC 6128 mit einem kleinen Programm ausgelesen und in einer Datei abgespeichert. Da ich sowohl ein 5.25"-Laufwerk am CPC als auch am PC besaß, war es kein Problem für mich, das ROM-Abbild auf den PC zu bekommen. Ich lud es in den Emulator, und -- leider tat sich nichts, es gab noch einige Fehler. Einige Zeit später hatte ich es dann so weit: die Einschaltmeldung des CPC erschien auf meinem PC. Der CPC lebt! Was für ein Erfolg! Er war zwar nur schwarzweiß, aber das war nicht weiter schlimm, am CPC hatte ich ja auch nur einen Grünmonitor. Es war also wirklich möglich!

Einige Tricks erforderte das Banking im CPC. Da der Z80 nur 64 KB adresseren konnte, der CPC 464 aber schon 32 KB ROM + 64 KB RAM besaß (und der CPC 6128 sogar 128 KB RAM), mußte der zusätzliche Speicher in den Adreßraum eingeblendet werden. Ein ähnliches Problem hatte auch der PC, dessen erste CPU 8088 nur 1 MB adressieren konnte. Unter DOS blieben sogar nur 640 KB übrig. Erst durch EMS (Extended Memory System) konnte unter DOS mehr Speicher benutzt werden, indem dieser in ein Adreßfenster unterhalb 1 MB eingeblendet wurde.

Geschwindigkeit ist Trumpf

Aber auch die C-Variante erreichte trotz aller möglichen Optimierungen auf meinem PC 386 mit 33 MHz längst nicht die Geschwindigkeit des Originals. Also mußte ich doch PC-Assembler lernen. Zufällig habe ich ZSIM von Jürgen Weber entdeckt, einem CP/M-Emulator in Assembler, der recht schnell war. Ich erzählte Jürgen von meinem Projekt und er war sofort bereit, mir seinen Quellcode zur Verfügung zu stellen und mich dabei zu unterstützen. Ich hatte ja keinerlei Erfahrung mit 80x86-Assembler, mit Segementregistern und den ganzen Kram. Jürgen war es, der die geniale Idee zu dem Banking-Konzept mit Segmentregistern hatte. Nur durch Ändern der Segmentregister und Addieren eines Offsets konnte man das gesamte Banking-Konzept des CPC nachbilden! Auch RAM unterhalb von ROM wurde so relalisiert, bei dem Lesezugriffe auf das ROM und Scheibzugriffe auf das daruner befindliche RAM gehen.

Ich staunte über die Tricks, die Jürgen in seinem Assembler-Code benutzte, um die enorme Geschwindigkeit hinzubekommen. Es gab z.B. keine zentrale Interpretationsschleife sondern sozusagen für jeden Befehl eine. Die Code zum Holen des nächsten Befehls war ihm direkt angehängt, das sparte jeweils einen Sprung. Und um nicht in einer Tabelle das Sprungziel herauszufischen, waren die Sprungziele speziell ausgerichtet (aligned), so daß sie durch eine einfache Adreßberechnung angesprungen werden konnten.

Ein Z80 als Coprozessor

Ganz wollte ich meine Z80-Emulation in C nicht entsorgen, so beließ ich den Code im Emulator und man konnte wahlweise meinen langsamen Z80 oder Jürgens schnellen Z80 benutzen. Für Testzwecke entsann ich den Modus des Co-Z80, bei der jeder Z80-Befehl simultan von beiden Emulationsarten simuliert wurde. Die Register und die Speicherzellen beider Arten mußten nach jedem simulierten Befehl identisch sein. So konnte ich zahlreiche Unterschiede bei den Emulationen feststellen und Fehler beseitigen. Es war gar nicht so einfach, die undokumentierten Op-Codes und Änderungen der Flags richtig zu simulieren.

Ein neues Design in C++

So wurde ich mit C und Assembler auf dem PC vertraut. Irgendwann wurde das Projekt zu umfangreich, ich verlor so langsam den Überblick. Also bagann ich, die C-Teile in C++ umzuschreiben und ein Klassenmodell der CPC-Hardware zu entwerfen. Übersichtlicherer Code war mir dabei wichtiger als ein paar Prozent mehr Geschwindigkeit. Immerhin gab es jetzt unter C++ auch Inline-Funktionen. So lernte ich zumindest die Grundzüge von C++ kennen.

Und der Emulator wurde immer besser oder zumindest benutzerfreundlicher. Vollständige Kompatibilität zum Original erreichte er allerdings nie vollständig. Für korrekt dargestellte Rasterinterrupts hätte ich die ganze Bildausgabe neu schreiben müssen, das erschien mir zu aufwendig.

Ausblick

So habe ich meine gesammelten Erfahrungen hinübergerettet in die Welt der PCs und vielen CPC-Anwendern den Schritt erleichtert, sich auf dem PC zurechtzufinden.

Ich möchte allen CPC-Enthusiasten danken, die mich dabei unterstützt haben und mich angesport haben, immer neue Verbesserungen einzubauen!

Marco Vieth, September 2001

MV, 04.03.2006 20:51:46