Benutzer:Stephan64/Testseite0
Stephan64/Testseite0 | |
---|---|
![]() | |
Entwickler | Stephan Pabst |
aktuelle Version | 1.14.0.4 |
Lizenz | Freeware |
Plattform | MS-DOS (Version 3.3 oder höher) |
Bedienung | |
Formate | PRG, TAP |
Sprache | ![]() ![]() |
Y64 (Yet another Commodore 64 emulator) ist ein Emulator für IBM-kompatible PCs mit dem Betriebssystem MS-DOS, der den Heimcomputer Commodore 64, bis zu 30 Diskettenlaufwerke des Typs VC1541 und eine Datassette emuliert. Das Hauptaugenmerk liegt dabei auf der Analyse und dem Debugging von C64-Programmen. Beispiele für Einsatzgebiete sind das Reverse Engineering von Schnelllade- und Soundausgabe-Routinen, die Entwicklung von Trainern und die Visualisierung von C64-internen Informationen. Für komplexe Untersuchungen lässt sich der Emulator auch über die serielle Schnittstelle fernsteuern, beispielsweise von einen zweiten PC oder einen Arduino aus.
Zahlreiche Artikel, aber auch Animationen und Rekonstruktionen von Musikstücken im C64-Wiki sind unter Verwendung von Y64 entstanden.
Geschichte[Bearbeiten | Quelltext bearbeiten]
Im Herbst 1989 kaufte sich der Autor von Y64 für sein beginnendes Diplomstudium der Wirtschaftsinformatik, zusätzlich zu den bereits vorhandenen Computern vom Typ Commodore 64 und Commodore 128D, einen PC auf Basis eines mit 16 MHz getakteten 80286-Prozessors. Wie von seinen bisherigen Rechnern und deren Prozessoren (MOS 6510 bzw. 8502 und Zilog Z80) gewohnt, brachte er sich anschließend die Maschinensprache der x86-Prozessorfamilie bei und begann, den PC in Assembler zu programmieren.
Begeistert von dem Performancezuwachs gegenüber seinen bisherigen Computern, der sich bei ersten Projekten (unter anderem einem einfachen Crossassembler für den 6502) zeigte, beschloss er 1991, dass sich auch ein kompletter Commodore 64 mit akzeptabler Performance auf dem PC emulieren lassen müsse. Ausgestattet hauptsächlich mit Fachliteratur aus dem Hause Data Becker (dem "Maschinensprachebuch" und dem "Maschinensprachebuch für Fortgeschrittene", dem "Grafikbuch", dem Nachschlagewerk "64 intern" und dem "Anti-Cracker-Buch"), entwickelte er daraufhin zunächst einen Emulator für den 6510-Prozessor, den er nach und nach um Grafikroutinen für die einzelnen Videomodi des Videocontrollers VIC 6569 erweiterte.
Als wertvolle "Testsuite" erwiesen sich hierbei die fast 2.000 während der Schulzeit gesammelten Computerspiele und insbesondere deren Cracktros. Zahlreiche in der Literatur nicht dokumentierte Verhaltensweisen der 6510-CPU, insbesondere hinsichtlich des Timings und der Speicherzugriffe, wurden erst offensichtlich, wenn diese Programme sich auf der realen Hardware und auf dem Emulator unterschiedlich verhielten.
Plattform[Bearbeiten | Quelltext bearbeiten]
Y64 setzt einen IBM-kompatiblen PC mit dem Betriebssystem MS-DOS voraus. Da der Emulator im Protected Mode arbeitet und die CPU und insbesondere deren Speicherverwaltung vollständig kontrolliert, ist zum einen mindestens ein 80286-Prozessor erforderlich, zum anderen muss sich dieser Prozessor beim Start des Emulators im Real Address Mode befinden. Da heutige Betriebssysteme wie Linux oder Windows diese Voraussetzung nicht erfüllen und auch die unter diesen Betriebssystemen verfügbaren "DOS-Boxen" nur eine CPU im Virtual 8086 Mode-Modus bereitstellen, funktioniert Y64 nur unter MS-DOS und nur ohne störende Speichermanager wie "EMM386", "QEMM" oder "386MAX".
Die Darstellung des C64-Bildschirminhalts erfolgt in dem auf allen VGA-Karten verfügbaren Grafikmodus mit 320x200 Pixeln Auflösung mit einer Palette von 256 Einträgen, die allerdings nur 16 Farbtöne codieren. Der Rahmen des C64-Bildschirms und ggf. dort dargestellte Rahmensprites werden nicht angezeigt. Auf älteren Rechnern wird zudem eine zweite, monochrome Grafikkarte (Hercules-Karte) für die Ausgabe von Debug-Informationen unterstützt. Bei neueren Rechnern, die diese Darstellungsmöglichkeit nicht mehr besitzen, kann wahlweise der Debug-Bildschirm anstelle des C64-Videobilds auf dem VGA-Bildschirm angezeigt werden, oder der Inhalt des Debug-Bildschirms kann per RS232-Schnittstelle kontinuierlich an einen zweiten Rechner übermittelt und dort dargestellt werden. Hierbei werden nach der erstmaligen Übertragung des gesamten Bildschirminhalts nur noch zwischenzeitliche Änderungen in einer sehr kompakten Codierung übermittelt.
Für die Soundausgabe nutzt Y64, falls vorhanden, eine "Soundblaster"-kompatible Soundkarte oder ein entsprechendes, in das Mainboard eines Laptops integriertes Modul. Die von den drei Tongeneratoren des SID 6581 erzeugten Klänge werden über je 2 Operatoren des Yamaha OPL2- oder OPL3-Chip ausgegeben, digitalisierte Samples über den DSP. Diese Vorgehensweise ergibt in den meisten Fällen eine zufriedenstellende Wiedergabe von Klängen und Geräuschen; eine Schwachstelle ist die Erzeugung von Rauschen mit unterschiedlichen Frequenzen.
Als Eingabegeräte lassen sich Tastaturen mit DIN- und PS/2-Anschluss sowie einige Typen von Computermäusen mit PS/2- und RS232-Anschluss verwenden. Um auch USB-Geräte wie Joysticks, Tastaturen und USB/RS232-Wandler nutzen zu können, obwohl diese von MS-DOS nicht unterstützt werden, beinhaltet Y64 zudem einen USB-Stack für den UHCI-Chipsatz sowie eine ganze Reihe von zugehörigen Gerätetreibern, so dass auch USB-Tastaturen und die meisten USB-Mäuse verwendet werden können.
Leistungsdaten[Bearbeiten | Quelltext bearbeiten]

Die ursprünglichen Erwartungen hinsichtlich der Performance des Emulators stellten sich insbesondere aufgrund der Komplexität des Videocontrollers als viel zu optimistisch heraus. Obwohl vollständig in handoptimiertem 80x86-Assemblercode geschrieben, erreichte der Emulator auf dem mit 16 MHz getakteten 80286-Prozessor nur rund 8% der Geschwindigkeit eines echten C64 (entsprechend 4 Frames pro Sekunde, mit Bildschirmdarstellung im Monocolor-Textmodus und ohne Sprites). Auch ein Upgrade auf ein Mainboard mit einem mit 25 MHz getakteten 80286 ließ die Performance erwartungsgemäß nur auf etwas mehr als 12% (6 Frames pro Sekunde) ansteigen. Erst 1994, mit dem Kauf eines weiteren PCs auf Basis einer mit 66 MHz getakteten 80486DX2-CPU und mit speziellen 32 Bit-Graphikroutinen, konnte ein Commodore 64 erstmals in voller Geschwindigkeit emuliert werden.
Auf modernen PCs scheitert die Installation des Betriebssystems MS-DOS häufig an fehlenden Voraussetzungen, beispielsweise dem von MS-DOS zwingend vorausgesetzten, aber in dieser Form nicht mehr vorhandenen BIOS. Zudem fehlt die Klangwiedergabe wegen der nicht mehr gegebenen "Soundblaster"-Kompatibilität heutiger Soundsysteme. Die leistungsfähigste Hardware, auf der Y64 bisher mit voller Funktionalität getestet wurde, ist daher ein Laptop auf Basis eines mit 1 GHz getakteten Pentium III-Prozessors. Die Emulation des Startbildschirms mit der Meldung "READY." und dem blinkenden Cursor geschieht hier mit etwas mehr als der 33-fachen Geschwindigkeit des C64 (entsprechend 1660 Frames pro Sekunde); bei komplexeren Bildschirminhalten — zum Beispiel dem Spiel "IO" im Attract Mode — erreicht der Emulator ungedrosselt immerhin noch rund die 9,5-fache Geschwindigkeit des Originals (entsprechend 474 Frames pro Sekunde). Unter Verzicht auf die Soundausgabe kam Y64 auch testweise auf einem Laptop mit einem mit 1,6 GHz getakteten Pentium M-Prozessors zum Einsatz; der Startbildschirm erreichte hier die 82-fachen Geschwindigkeit des C64 (entsprechend rund 4100 Frames pro Sekunde), der Attract Mode des Spiels "IO" noch die 12-fache Geschwindigkeit des Originals (rund 600 Frames pro Sekunde).
Diese Leistungsdaten sind allerdings nicht nur der Lohn für einen vollständig in Assembler geschriebenen Emulator, sondern auch eine Folge von Kompromissen bei den zugrundeliegenden Design-Entscheidungen[1]. So emuliert Y64 den Videocontroller (VIC) des C64 nur Rasterzeile für Rasterzeile, anstatt zyklen-exakt Schreibzugriffe auf die Register des VIC zu berücksichtigen, und verzichtet auf die Darstellung des Bildschirmrahmens. Schreibzugriffe auf den Soundchip (SID) bildet Y64 auf die entsprechenden Register einer "Soundblaster"-kompatiblen Soundkarte ab, und Diskettenlaufwerke werden lediglich auf Basis des IEC-Protokolls emuliert, so dass Schnelllader, die in das RAM der Floppy geladen und von deren CPU ausgeführt werden, ihren Dienst versagen.
Y64 ist damit keine ernstzunehmende Alternative zu existierenden Emulatoren, sondern eher ein mächtiges Werkzeug zur Analyse von Programmen für den C64. Wenn es auf die exakte Emulation eines bestimmten Spezialeffekts ankommt, so greift selbst der Autor von Y64 testweise neben der realen Hardware auch auf eine aktuelle Version des "Versatile Commodore Emulator" (VICE) zurück — wobei diese Vorgehensweise erst kürzlich einen Bug im "VICE" zutage gefördert hat.
Features[Bearbeiten | Quelltext bearbeiten]
Disassembler/Debugger[Bearbeiten | Quelltext bearbeiten]
Statistiken[Bearbeiten | Quelltext bearbeiten]
Speicherabzüge[Bearbeiten | Quelltext bearbeiten]
Y64 speichert beim Beenden üblicherweise den vollständigen Systemzustand des emulierten Commodore 64 in einer Datei. Primär dient der so erzeugte Speicherabzug dazu, einen C64-Programmablauf zu einem späteren Zeitpunkt an exakt der Stelle fortzusetzen, an der er zuvor unterbrochen wurde. Da diese Datei eine feste Länge hat und immer gleich aufgebaut ist, kann sie — oder gegebenenfalls mehrere nacheinander aufgezeichnete Versionen davon — jedoch auch in einfacher Weise verwendet werden, um die Arbeitsweise eines ausgeführten Programms zu analysieren und zu modifizieren:
- Erzeugt man von einem Spielablauf immer dann einen Speicherabzug, wenn die Spielfigur ein Leben einbüßt, und speichert diese unter verschiedenen Dateinamen, so reicht anschließend eine einfache Suche mit der Bedingung "Finde Speicherzeilen, deren Inhalt sich in aufeinanderfolgenden Speicherabzügen jeweils um 1 vermindert", um die Speicheradresse aufzuspüren, an der die Anzahl der Leben abgelegt ist. Startet man anschließend Y64 mit Debug-Unterstützung und setzt auf die so gefundene Speicheradresse einen Breakpoint, so stoppt die Programmausführung üblicherweise bei dem Maschinenbefehl, der die Anzahl der verbleibenden Leben vermindert — und der nur in geeigneter Weise ersetzt zu werden braucht, um einen einfachen Trainer zu implementieren.
- Für komplexere Analysen von Speicherinhalten, bei denen die oben beschriebene Vorgehensweise nicht zum Ziel führt, bietet sich eine Binärsuche durch Kombination zweier Speicherabzüge an. Für eine Suche nach der Speicherzelle, in der die von der Spielfigur verwendete Waffe codiert ist, kann man beispielsweise von zwei Spielsituationen, in denen die Spielfigur unterschiedliche Waffen verwendet, Speicherabzüge "A" und "B" generieren. Durch sukzessives Kombinieren diese beiden Dateien zu einem neuen Speicherabzug, der die ersten X Bytes aus Datei "A" und die weiteren (66.536 - X) Bytes aus Datei "B" enthält, findet sich dann diejenige Grenze Xs, an der die Spielfigur für Xs und (Xs+1) unterschiedliche Waffen besitzt.
- Auf einfache Weise können auch externe "PEEK"- und "POKE"-Kommandos implementiert werden, mit deren Hilfe sich einzelne Speicherzellen oder Speicherbereiche ändern, füllen und betrachten lassen, oder gezielt Speicherbereiche extrahiert und als Binär- oder Hex-Datei geschrieben werden.
Erweiterungsmöglichkeiten[Bearbeiten | Quelltext bearbeiten]
Module (Plugins)[Bearbeiten | Quelltext bearbeiten]
Y64 bietet die Möglichkeit, ein bis zu 20 kByte großes Erweiterungsmodul nachzuladen. Es handelt sich dabei um ein Programmfragment, das in x86-Assembler geschrieben sein muss, an Offset 0x0100 in ein eigenes 16 Bit-Codesegment geladen wird und dessen Routinen sich im Protected Mode ausführen lassen. Für lokale Variablen und Unterprogrammaufrufe besitzt das Modul einen eigenen, 768 Bytes großen Stack.
Am Anfang jedes Moduls stehen eine Reihe von Vektoren (NEAR-Pointer), die auf Routinen oder Datenstrukturen verweisen können. Nicht verwendete Vektoren werden durch den Wert 0x0000 gekennzeichnet.
Module haben Zugriff auf den Hauptspeicher des emulierten C64, auf den VGA-Speicher (den Bildschirm des C64) und auf die zweite Seite der zweiten Grafikkarte (monochrome Hercules-Karte oder Bildschirm eines zweiten Rechners). Sie sind damit in der Lage, wahlweise Zusatzinformationen in die Bildschirmdarstellung des C64 einzublenden oder eine ganze Bildschirmseite, beispielsweise mit einer Darstellung einer Spielwelt, anzuzeigen und mit Daten aus dem Spielgeschehen anzureichern.
Für häufig benötigte Funktionen, wie das Ausgeben von ganzen Zahlen und Prozentangaben auf dem Bildschirm des emulierten C64 oder des Debuggers oder den Zugriff auf Tastatur und Joysticks, existieren Bibliotheksaufrufe, die aus dem Modul heraus genutzt werden können.
![]() |
![]() |
![]() |
Fernzugriff[Bearbeiten | Quelltext bearbeiten]
Über eine RS232-Schnittstelle ist es möglich, den Emulator Y64 von einem zweiten Rechner aus zu steuern sowie auf Speicher- und Bildschirminhalte des emulierten C64 zuzugreifen. Ferner können die momentan ausgeführten Opcodes und Zugriffe auf wählbare I/O-Adressen mitprotokolliert werden.
- Zustand der CPU
Auf eine entsprechende Kommandosequenz hin übermittelt der Emulator für jeden im Debugger angezeigten Befehl die momentanen Registerinhalte an einen angeschlossenen Rechner. Die Datenübertragung nutzt eine kompakte Codierung, um Übertragungsbandbreite zu sparen. Wahlweise kann auch noch ein — ebenfalls kompakt codierter — mikrosekundengenauer Zeitstempel mit übertragen werden. Die folgende Tabelle dokumentiert die ersten vom C64 ausgeführten Befehle nach einem Reset:
Datenbytes (Timestamp) |
Datenbytes (CPU-Status) |
Decodierter Timestamp Sekunden |
Decodierter CPU-Status PC SR A X Y SP |
Nächster ausgeführter Befehl |
---|---|---|---|---|
- | 60 0F 30 E2 FC 00 00 00 00 | - | FCE2 30 00 00 00 00 |
FEC2: LDX #$FF
|
C0 02 | E6 A0 FF | 0.000002 | FCE4 B0 00 FF 00 00 |
FCE4: SEI
|
C0 04 | E5 84 | 0.000004 | FCE5 B4 00 FF 00 00 |
FCE5: TXS
|
C0 06 | 60 08 | 0.000006 | FCE6 B4 00 FF 00 FF |
FCE6: CLD
|
C0 08 | E0 | 0.000008 | FCE7 B4 00 FF 00 FF |
FCE7: JSR FD02
|
C0 0E | 60 0B 02 FD | 0.000014 | FD02 B4 00 FF 00 FD |
FD02: LDX #$05
|
C0 10 | E6 24 05 | 0.000016 | FD04 34 00 05 00 FD |
FD04: LDA FD0F,X
|
C0 14 | E7 14 30 | 0.000020 | FD07 34 30 05 00 FD |
FD07: CMP 8003,X
|
C0 18 | E2 | 0.000024 | FD0A 34 30 05 00 FD |
FD0A: BNE FD0F
|
C0 1B | E3 03 | 0.000027 | FD0F 34 30 05 00 FD |
FD0F: RTS
|
C0 21 | 60 0C EA FC | 0.000033 | FCEA 34 30 05 00 FF |
FCEA: BNE FCEF
|
C0 24 | E3 03 | 0.000036 | FCEF 34 30 05 00 FF |
FCEF: STX D016
|
C0 28 | E2 | 0.000040 | FCF2 34 30 05 00 FF |
...
|
Basierend auf einem solchen Protokoll kann ein zweiter Rechner dann komplexe Triggerbedingungen anwenden und gezielt Informationen über das gerade ausgeführte Programm sammeln.
- I/O-Zugriffe
Auch Lese- und Schreibzugriffe auf Register von I/O-Bausteinen lassen sich auf ähnliche Weise mitprotokollieren, wahlweise mit Timestamp und mit Angabe der Adresse, an der der Lese- oder Schreibbefehl im Speicher steht. Die folgende Tabelle zeigt einen kurzen Ausschnitt aus den Zugriffen auf den Soundchip SID, die im Spiel "Blagger" beim Auffinden eines Schlüssels erfolgen:
Datenbytes (Timestamp) |
Datenbytes (I/O-Zugriff) |
Datenbytes (Befehlsadresse) |
Decodierter Timestamp Sekunden |
Decodierter I/O-Zugriff Adresse (hex), Wert (dez) |
Decodierte Befehlsadresse |
---|---|---|---|---|---|
C2 5D 17 68 | 62 92 00 | 2D 19 | 318.732174 | POKE $D412,0 | $192D |
C0 65 | 62 8F 38 | 33 19 | 318.732182 | POKE $D40F,56 | $1933 |
C0 6D | 62 8E 60 | 39 19 | 318.732190 | POKE $D40E,96 | $1939 |
C0 73 | 62 93 8B | 3E 19 | 318.732196 | POKE $D413,139 | $193E |
C0 79 | 62 92 11 | 43 19 | 318.732202 | POKE $D412,17 | $1943 |
C1 04 1D | 62 8B 20 | D9 16 | 318.733642 | POKE $D40B,32 | $16D9 |
C0 11 | 62 88 0F | DF 16 | 318.733655 | POKE $D408,15 | $16DF |
C0 17 | 62 8D 21 | E4 16 | 318.733661 | POKE $D40D,33 | $16E4 |
C0 1D | 62 8B 11 | E9 16 | 318.733668 | POKE $D40B,17 | $16E9 |
Anhand solcher Protokolle lassen sich durch geeignete Nachbearbeitung in vielen Fällen die Musiknoten der gerade gespielten Melodie rekonstruieren. Alle derzeit in der Kategorie "Noten" verfügbaren Musikstücke aus C64-Spielen wurden auf diese Weise extrahiert. Alternativ können Musikstücke und Geräusche mit hoher zeitlicher Auslösung analysiert werden, um das Zustandekommen besonderer Klangeffekte zu entschlüsseln.
Beispielhaft zeigt die nachfolgende Galerie links die Begleitmelodie des Spiels "Robin of the Wood" in der üblichen Notenschreibweise, und rechts den Anfang der Startmelodie von Green Beret mit einer Auflösung von 500 μs. Letztere veranschaulicht deutlich die Verwendung von Arpeggios in der Melodiestimme (rot) und Vibrato in den Bassstimmen (blau und grün).
![]() |
![]() |
- Animationen
Für die Erstellung komplexer Animationen kann der Emulator, ausgehend vom Startpunkt einer Schlüsselszene, von einem zweiten Rechner gesteuert werden. Der Emulator erzeugt hierbei nach jedem Bildschirmaufbau des VIC einen Screenshot im Bildformat GIF, während der zweite Rechner eine vorbereitete Sequenz von Tastatur- und Joystickeingaben einspeist. Auf diese Weise kann die vom Spieler gesteuerte Figur beispielsweise pixelgenau zu ihrem Ausgangspunkt zurückkehren, so dass sich ein endloser, flüssiger Bewegungsablauf ergibt (linke Animation der nachfolgenden Galerie). Aktionen innerhalb des Spiels, die exaktes Timing und genaue Positionierung verlangen, lassen sich durch sorgfältiges Zusammenstellen der notwendigen Joystickbewegungen vorbereiten und dann automatisiert als animiertes GIF veranschaulichen (rechte Animation).
![]() |
![]() |
Sonstiges[Bearbeiten | Quelltext bearbeiten]
Die Emulation ist komplett in x86-Assembler geschrieben und verwendet keine Bibliotheken aus Fremdquellen.
Weblinks[Bearbeiten | Quelltext bearbeiten]
[[Kategorie:Emulator]] [[Kategorie:1991]]
- ↑ Ben Kuchera: "Accuracy takes power: one man’s 3GHz quest to build a perfect SNES emulator", Ars Technica, 09.10.2011