Ein Vortrag von Jürgen Reuter auf der GPN19.
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.