Benutzer:Stephan64

Aus C64-Wiki
Zur Navigation springenZur Suche springen

Über mich[Bearbeiten | Quelltext bearbeiten]

Mein erster Computer war 1984 ein Commodore 64 mit Datasette, den ich an einem klobigen und stellenweise unscharfen Schwarzweiß-Fernseher betrieben habe — und auf dem ich mit Begeisterung Spiele, aber auch Lernprogramme und Numerik-Routinen entwickelt habe.
Wenige Jahre später konnte ich mir schon — unter anderem vom Erlös meines Spiels Pole Position, das ich in der Zeitschrift Homecomputer veröffentlicht habe — einen Commodore 128D samt Farbmonitor Commodore 1901 leisten. Und während meiner Ausbildung (Diplomstudium Wirtschaftsinformatik und Promotion in Finanzierung) und meiner beruflichen Tätigkeit (Softwareentwickler bei einem großen Automobil-Zulieferer) begegneten und begegnen mir natürlich viel leistungsfähigere Computer in Hülle und Fülle — trotzdem ist der C64 auch heute noch der Computer, der mich am meisten begeistert. Und meine Erfahrungen aus mehr als vier Jahrzehnten Beschäftigung mit diesem faszinierenden Gerät lasse ich nach und nach in meine Artikel (zusammengestellt in dieser Übersichtsliste) einfließen.

Meine Projekte rund um den Commodore 64[Bearbeiten | Quelltext bearbeiten]

Commodore 64-Emulator "Y64" (Yet another Commodore 64 emulator)[Bearbeiten | Quelltext bearbeiten]

Schon 1991 kam ich auf die Idee, dass sich ein Commodore 64 doch auch auf einem PC emulieren lassen müsste. Da mein damaliger Rechner nur über einen 80286-Prozessor verfügte und ich dessen eher bescheidene Rechenleistung bestmöglich ausnutzen wollte, habe ich meinen Emulator komplett in handoptimiertem Intel x86-Assembler geschrieben. Daran hat sich bis heute nichts geändert (inzwischen angewachsen auf rund 40.000 Zeilen Quellcode), und damit ist er extrem schnell und kompakt.

Jahre später musste ich erkennen, dass auch andere C64-Fans ähnliche Ideen hatten, und habe meinen Emulator daher irgendwann "Y64" (Yet another Commodore 64 emulator) getauft. Da der Emulator sich nur unter MS-DOS im Real Address Mode starten lässt (während des Betriebs dann aber in den Protected Mode schaltet und die verschiedenen Speicherkonfigurationen des C64 auf einem 80286-Prozessor über Local Descriptor Tables, auf dem 80386 und anderen 32-Bit-Prozessoren über Paging emuliert), wird er wohl für immer ein Exot und ein Nischenprodukt bleiben — allerdings mit Fähigkeiten, die sich mancher C64-Fan vielleicht schon seit langem für seinen C64 und vielleicht auch für einen Emulator gewünscht hat...

Kopplung meines C64-Emulators mit einem Arduino[Bearbeiten | Quelltext bearbeiten]

Wer heute maschinennahe Programmierung auf einem 8 Bit-System erlernen möchte, wird wahrscheinlich in den seltensten Fällen dafür einen C64 einsetzen, sondern eher ein Arduino-Prototypenboard. Da ist es doch naheliegend, einmal einen (emulierten) C64 und einen Arduino zu einem "generationen-übergreifenden Dialog" zu koppeln:


Kopplung zwischen meinem C64-Emulator "Y64" und einem Arduino Mega 2560 während des Spiels "Starquake"
Kopplung zwischen "Y64" und einem Arduino während des Spiels "Spellbound"



Dabei kann der Arduino auf den Hauptspeicher und alle I/O-Bausteine des emulierten C64 zugreifen und deren Speicherinhalte manipulieren, verarbeiten oder mitprotokollieren. Das linke Bild der obigen Galerie demonstriert eine solche Kopplung, während auf dem C64 das Spiel "Starquake" ausgeführt wird: Der obere Teil des auf den Arduino aufgesteckten TFT-Bildschirms zeigt den Bildschirminhalt des C64, der untere Teil eine symbolische Darstellung des Spielplans (erforschte Räume grün, noch nicht besuchte Räume rot). Im rechten Bild visualisiert der Arduino während des Spiels "Spellbound" den Status aller Charaktere und den Aufenthaltsort aller Gegenstände.

Kopplung meines C64-Emulators mit dem Mess- und Kalibriersystem INCA[Bearbeiten | Quelltext bearbeiten]

INCA ist ein Software-Werkzeug zur Motorenentwicklung, das in der Automobilindustrie weit verbreitet ist. Da ich beruflich unter anderem kundenspezifische Erweiterungen für INCA implementiere und neue Messgeräte integriere, lag es nahe, auch meinen C64-Emulator als "Messgerät" in INCA einzubinden:


Screenshot einer Kopplung zwischen meinem C64-Emulator "Y64" und dem Messsystem INCA während des Spiels "Gribbly's Day Out"



Bei dieser Kopplung liest INCA periodisch Spielparameter, wie etwa die Position der Spielfigur, aber auch Energie, Punktzahl oder Anzahl Leben über eine serielle Schnittstelle aus dem C64-Hauptspeicher im Emulator aus und stellt sie als Messwerte dar. Insbesondere beim Durchstreifen großer Labyrinthe ist es sehr hilfreich, die Position des Charakters innerhalb des gesamten Spielplans verfolgen zu können (im abgebildeten Beispiel ist die Spielfigur "Gribbly Grobbly" rechts unten in der Höhle der Gribblets).

Rekonstruktion der Musiknoten zu Melodien aus C64-Spielen[Bearbeiten | Quelltext bearbeiten]

Mein C64-Emulator unterstützt das gezielte Mitprotokollieren von Zugriffen auf die emulierten I/O-Bausteine des Commdore 64. Besonders interessant ist dies bei Schreibzugriffen auf den Soundchip, anhand derer sich ohne großen Aufwand die Noten einer Melodie rekonstruieren und in ein geeignetes Dateiformat (beispielsweise ABC) überführen lassen. Auf diese Weise habe ich mehr als 600 Melodien aus über 250 Spielen extrahiert und in den zugehörigen Artikeln des C64-Wiki jeweils im Abschnitt "Sonstiges" veröffentlicht. Eine Zusammenstellung dieser Musiknoten findet sich in der Kategorie "Noten".


Musiknoten zum C64-Spiel Robin of the Wood, rekonstruiert durch Mitprotokollieren aller Schreibzugriffe auf den SID



Ganz nebenbei lässt sich dabei noch einiges über die Programmiertechniken der Spieleentwickler lernen. So wird beispielsweise die hier dargestellte Begleitmelodie aus dem Spiel "Robin of the Wood" mit den für NTSC gültigen SID-Frequenzparametern abgespielt, erklingt also auf der PAL-Version des C64 fast einen Halbton tiefer als beabsichtigt.

Bei anderen Spielen beruhen die Frequenzparameter dagegen auf einem mehr oder weniger stark gerundeten Systemtakt, bei Burnin' Rubber beispielsweise auf einer Frequenz von 1,000 Mhz — und auf den zugehörigen, im Datenblatt des SID 6581 abgedruckten Parametern. Während der Programmierung dieses Spiels hat sich der Autor beim Eingeben der Frequenzparameter zudem gleich an zwei Stellen vertippt: Geringfügig falsch sind das A#-3 (235,0 Hz statt 233,1 Hz, weil Parameter $0F66 statt $0F46) und das D#-3 (156,2 Hz statt 155,6 Hz, weil Parameter $0A3C statt $0A32).

Analyse von Soundeffekten aus C64-Spielen[Bearbeiten | Quelltext bearbeiten]

Zahlreiche C64-Spiele untermalen einzelne Ereignisse mit faszinierenden Soundeffekten. Eine hochauflösende Darstellung der Soundausgabe anhand der Schreibzugriffe auf den SID erlaubt eine Analyse dieser Klänge. Die folgende Galerie veranschaulicht beispielsweise eine Reihe von Soundeffekten aus dem Spiel "Paradroid", die erklingen, während der Spieler vergeblich versucht, die Kontrolle über einen feindlichen Roboter zu übernehmen. Diese Klänge werden alle mit nur einer Stimme des SID wiedergegeben; die Schaubilder stellen die zeitliche Entwicklung der Tonhöhe mit einer Auflösung von 0.5 ms (2000 Pixel/s in der Originalauflösung) in einem Notenlinien-Schema dar. Die Skala am oberen und unteren Rand der Schaubilder ist in Abschnitte zu je 10 ms geteilt. Nicht erkennbar ist in dieser Darstellung die Hüllkurve, die beispielsweise ein langsames Ausklingen bewirken kann.


"Transfer" (0.279 s pro Durchgang, erklingt alle 0.479 s)
"Captured" (1.894 s)
"Deadlock" (2.533 s)
"Burnt Out" (1.894 s)



Hintergrundgeräusch im Spiel "Paradroid" (1776 ms pro Durchgang, erklingt alle 1915 ms)



Stammtöne sind in dieser Darstellung an ihrer exakten Position eingezeichnet; Halbtöne mittig zwischen ihren benachbarten Stammtönen (beispielsweise ein Gis in der Mitte zwischen G und A). Bei allen anderen Tönen richtet sich die vertikale Position nach dem exakten Abstand ihrer Frequenz zum nächsthöheren und nächsttieferen Stammton.

Auch interessante Abschnitte aus Melodien lassen sich auf diese Weise analysieren. Das folgende Schaubild zeigt beispielsweise die ersten Takte der Titelmelodie von "Green Beret". Deutlich zu erkennen sind die Arpeggios der Melodiestimme (rot) und das Vibrato der Bassstimmen (grün und blau).


Erste Takte der Titelmelodie von "Green Beret" (4.50 s)



Analyse des ausgeführten Maschinencode[Bearbeiten | Quelltext bearbeiten]

Y64 bietet zahlreiche Statistik-Funktionen, mit denen sich die Arbeit des 6510-Mikroprozessors analysieren lässt. Beispielhaft soll dies hier an einer kurzen, 17 Sekunden dauernden Sequenz aus dem Spiel "Starquake" und einem 29 Sekunden langen Spielzug aus dem Computerschach-Programm "Colossus Chess" vorgestellt werden. In der rechten unteren Ecke ist hierbei jeweils ein Timer eingeblendet, mit dessen Hilfe sich ein zeitlicher Bezug zu den Schaubildern in den nachfolgenden Abschnitten herstellen lässt.


Kurze Sequenz aus dem Spiel "Starquake" (17.00 s)
Ein Zug des Computers im Schachprogramm "Colossus Chess" (29.00 s)



Der MOS 6510-Mikroprozessor des Commodore 64 benötigt pro Instruktion mindestens 2 Systemtakte (zum Beispiel für das unmittelbare Laden einer Konstanten in ein Register) und maximal 7 Takte (zum Beispiel für das Hochzählen einer Speicherzelle mit absolut X-indizierter Adressierung). Bezieht man illegale Opcodes in die Analyse mit ein, so kann die Ausführung eines Maschinenbefehls sogar bis zu 8 Takte (zum Beispiel für den Befehl ISC mit indirekter Y-indizierter Adressierung) dauern.

Eine erste Analyse der im Spiel "Starquake" ausgeführten Maschinenbefehle zeigt, dass der Mikroprozessor während der 17 Sekunden langen Sequenz insgesamt 5.004.475 Instruktionen ausführt, also etwas mehr als 294.000 Instruktionen pro Sekunde. Dies entspricht einer durchschnittlichen Zahl von 3,35 Systemtakten pro Instruktion.

Wie auch bei vielen anderen Spielen spiegeln die oben genannten Leistungswerte bei "Starquake" vor allem die Struktur der Schleife wider, mit der der Computer periodisch auf ein bestimmtes Ereignis — im Fall von Starquake darauf, dass der Elektronenstrahl des Fernsehers den unteren Bildschirmrand erreicht — wartet:

30F8: LDA $D012 ; Nummer der aktuellen Rasterzeile aus VIC-Register 18 lesen
30FB: CMP #$FA  ; und mit Rasterzeile des unteren Bildschirmrands vergleichen
30FD: BNE 30F8  ; Rücksprung, falls unterer Bildschirmrand noch nicht erreicht

Solange die Spielfigur nicht in einen benachbarten Screen wechselt, wird diese Schleife über 1.800 Mal pro Bildschirmaufbau durchlaufen, was die CPU mehr als 80% der Zeit (rund 16.200 von 19.656 Systemtakten pro Bildwiederholung, ohne Berücksichtigung von DMA-Zugriffen des VIC) beschäftigt. Dementsprechend dominieren die hier ausgeführten Befehle auch die Befehlsstatistik (linkes Bild der nachfolgenden Galerie). Rechnet man diese Warteschleife heraus, so zeigt sich, dass die CPU jeweils nur beim Wechsel des Screens voll ausgelastet ist (rechtes Schaubild).


Klassifikation der von der CPU ausgeführten Maschinenbefehle in der Sequenz aus "Starquake"
Prozentuale Auslastung der CPU unter Vernachlässigung der Warteschleife beim Spiel "Starquake"



Beim Schachprogramm "Colossus Chess" ist die CPU dagegen dauerhaft voll ausgelastet, solange der Computer am Zug ist. Das linke Schaubild illustriert wieder die Anteile, die verschiedene Befehlstypen an den von der CPU insgesamt 8060298 ausgeführten Maschineninstruktionen haben (rund 278.000 Instruktionen pro Sekunde, 3,55 Systemtakte pro Instruktion). Das mittlere Diagramm analysiert zusätzlich, welche relative Häufigkeit die verschiedenen Arten bedingter Verzweigungen haben (also aufgrund welchen Flags wie häufig verzweigt bzw. nicht verzweigt wird), das rechte Schaubild zeigt, ob es sich dabei um Vorwärts- (forward) oder Rückwärtssprünge (backward) handelt und ob die Verzweigung tatsächlich durchgeführt wird (taken) oder nicht stattfindet (not taken).

Dass das Befehlspaar BVC/BVS (Verzweigung aufgrund des Overflow-Flags) nur sehr selten ausgeführt wird, deckt sich mit den Beobachtungen aus anderen Spielen: Typischerweise wird dieses Flag vor allem dazu verwendet, um mit Hilfe eines BIT-Befehls das 6. Bit einer Speicherzelle zu testen.

Untypisch ist dagegen die Aufteilung der bedingten Sprünge anhand der Richtung (vorwärts oder rückwärts) und der Frage, ob die getestete Bedingung erfüllt war und der Sprung durchgeführt wurde (taken) oder nicht (not taken). Zahlreiche Spiele enthalten Schleifen, die viele Male durchlaufen werden, so dass der durchgeführte Rückwärtssprung die häufigste Variante ist. Bei "Colossus Chess" gilt dies nur für den Test des Zero Flag, wo die Kombination "backward/taken" mit 30,17% (knapp vor backward/not taken mit 28,82%) an der Spitze liegt.


Klassifikation der von der CPU ausgeführten Maschinenbefehle in der Sequenz aus "Colossus Chess"
Anteile der verschiedenen Branch-Befehle bei "Colossus Chess" (BVC/BVS mit 0,00096% nicht sichtbar)
Anteile für Sprungrichtung und -ausführung bei "Colossus Chess"



Auf dem Commodore 64 könnten solche Untersuchungen für die Optimierung des Maschinencode herangezogen werden, da auf der 6510-CPU eine nicht durchgeführte Verzweigung nur 2, ein durchgeführter Sprung dagegen 3 (und beim Überschreiten einer Seitengrenze sogar 4) Systemtakte benötigt. Auf moderneren Prozessoren sind derartige Statistiken die Grundlage für den Entwurf und den Test der Sprung-Vorhersage (branch prediction)[1][2][3].

Quellen[Bearbeiten | Quelltext bearbeiten]

  1. John L. Hennessy/David A. Patterson: "Computer Architecture — A Quantitative Approach", Morgan Kaufmann Publishers Inc., 1990, S. 272f
  2. Don Anderson/Tom Shanley: "Pentium Processor System Architecture", Mindshare Inc., 1995, S. 149f
  3. Tom Shanley: "Pentium Pro and Pentium II System Architecture", Mindshare Inc., 1998, S. 122f