conference logo

Playlist "Gulaschprogrammiernacht 19"

RetroComputing: Emulator VZ200 / Z80

Jürgen Reuter

Z80-Emulatoren gibt es bereits zahlreiche. Meiner, dessen Implementierungsanfänge bis in die späten 90er zurück reichen, ist jedoch in Java implementiert und bringt dabei hohe Emulationsgeschwindigkeit mit hoher Flexibilität beim Befehlssatz der CPU unter einen Hut, so dass sich mit nur geringen Änderungen des Quellcodes auch Emulatoren für ähnliche CPUs recht schnell erzeugen lassen. Architektonisch ist der Emulator als Schichtenmodell implementiert: Auf der Emulation der Z80-CPU setzt als weitere Architekturschicht die Emulation der übrigen Hardware des Z80-basierten VZ200-Rechners auf, einschließlich der Emulation von Sound- und Video-Hardware.

In den frühen 80er Jahren habe ich auf meinem damaligen Z80-basierten Homecomputer „VZ200“ umfangreiche Software entwickelt. Da dieser Rechner mittlerweile leider nicht mehr funktioniert (u.a. mechanisch kaputte Gummitastatur), lagern die entsprechenden Datenträger (Magnetcassettenbänder) seither unbenutzbar herum. Um die Software wieder zum Leben zurück zu erwecken und sie bei Bedarf auf neuere Systeme portieren zu können, entstand die Idee, einen Emulator des kompletten Rechners (Z80-CPU, Videohardware, Audio-/Datenspeicherinterfaces, Betriebssystem, etc.) in Java zu implementieren. In der Session möchte ich die Architektur des Emulators vorstellen sowie exemplarisch einige algorithmisch interessante Aspekte herausgreifen.

Damit die Datenein- und –ausgabe (Lautsprecher, Cassetteninterface, etc.) des Emulators in der Real World dem Verhalten des Originals entspricht, muss für deren Emulation die Abarbeitung der Prozessorbefehle virtuell mit einer relativen Genauigkeit zueinander im Mikrosekundenbereich erreicht werden. Insbesondere muss das Scheduling heutiger Mehrprozessbetriebssysteme mit den daraus resultierenden Abarbeitungspausen berücksichtigt werden, wenn nach außen ein genaues Timing erzielt werden soll. Ich stelle einen Algorithmus vor, der auf Basis einer virtuellen „Processor Wall-Clock Time“ das entsprechende Mikrotiminig gewährleistet.

Ferner werde ich darauf eingehen, wie die einzelnen Teile der zu emulierenden Z80-CPU (Code/Data Fetching, Instruction Decoding & Dispatching, ALU, IRQs, etc.) effizient, aber dennoch generisch (etwa im Hinblick auf die Emulation verwandter Prozessoren wie dem 8080 mit seinen vom Z80 abweichenden Mnemonics) gestaltet werden können. Dabei setze ich Techniken aus dem Compilerbau ein, z.B. die automatische Generierung eines Zustandsautomaten als Tokenizer für das Instruction Decoding aus einer deskriptiven, Bit-Masken-orientierten Spezifikation der Prozessor-Instruktionen.

Das dem Emulator beigefügte Monitor-Programm ermöglicht das Hineindebuggen in den Z80-Assember-Code, um z.B. die als „stack trickery“ in der damaligen Zeit von zahlreichen Softwareentwicklern beliebten (und heute eher von Malware-Autoren eingesetzten) Manipulationen am Aufrufstack verfolgen.

Projektsite auf Github:
https://github.com/soundpaint/VZ200-Emulator

Vorläufiges Demo-Video:
https://www.youtube.com/watch?time_continue=5&v=S65sOWSTnGA

Weitere Demos / Screenshots werden in Kürze auf der Projektsite verlinkt werden.