Mit der Bildschirmausgabe nimmt das Projekt langsam Form an. Um mit dem Emulator zu interagieren fehlt allerdings noch eine Tastatur.
Diese wird in diesem Teil größtenteils implementiert. Das Mapping der Tasten ist noch statisch, was Raum zur Verbesserung für später offenlässt.
Also los geht's ...
Videoausgabe und Interrupts
Im letzten Teil konnte man die Inhalte, die auf dem Bildschirm dargestellt werden sollten im Speicher erkennen. Jetzt wird es Zeit für den Textmodus eine Bildschirmausgabe zu programmieren.
Nachdem die CPU Befehle initial implementiert wurden geht es an die Tests.
Dazu habe ich die Testfälle von Mike Naberezny als Basis genommen und daraus Tests für Mocha & Chai geschrieben. Damit ist die Anzahl der Tests auf aktuell 667 Tests gewachsen.
Zusätzlich wurde die CPU mit der Test-Suite von Klaus Dormann geprüft, um sämtliche Fehler im Code und in den Testfällen zu beseitigen.
Am Ende ist es möglich die C64 Firmware zu starten und die Willkommens-Nachricht im Speicher ab Position 0x0400 zu finden.
Ein kleiner Zwischenstatus. Die CPU Instruktionen sind vollständig und die Betriebssystem ROM Dateien können geladen werden.
Außerdem kann man beliebige Speicherbereiche betrachten.
Heute habe ich die Addressierungsarten der CPU und eine Opcode-Tabelle implementiert. In der Tabelle sind alle Opcodes mit Namen, Länge in Bytes und Dauer in CPU Zyklen hinterlegt. Mit dieser Tabelle konnte ich in der Statusseite einen einfachen Disassembler einfügen.
Im diesem Artikel beginne ich, den ersten Teil des Emulators zu implementieren.
Der aktuelle Projektstand befindet sich in meinem Gitlab-Projekt TSC64Emu.
Nachdem ich angefangen habe, die C64 CPU Emulation zu programmieren, habe ich schnell festgestellt das ich ein Testframework benötigte. Daher beschreibe ich hier die Einrichtung und die Erstellung von einem Test für eine einfache Memory-Klasse.
In dieser Reihe von Beiträgen habe ich vor, einen C64-Emulator von Grund auf als Webanwendung zu entwickeln.
Die auf dieser Reise gesammelte Erfahrung möchte ich hier dokumentieren. Das Projekt wurde stark von Johan Steenkamp's Blog inspiriert, da ich sein Vorgehen sehr schätze.
Warum beschreibe ich dann mein Vorgehen, wenn es so etwas schon gibt?
Zum einen, weil ich das Projekt in Typescript umsetzen werde und ich nicht immer den gleichen Weg gehen werde.
Zum anderen prüfe ich damit, ob ich das jeweilige Thema verstanden habe, denn wenn ich es verstehe, dann kann ich es auch beschreiben.
Ich werde immer wieder Verweise auf Dokumentation oder andere Blogs einfügen, die mir geholfen haben bestimmte Punkte zu verstehen, die mir noch nicht ganz klar waren.
Also viel Spaß beim lesen ...
NOTE OF THANKS
Hello Johan,
I would like to thank you very much for your blog. So you inspired me to start the journey myself and to write my own C64 emulator.
Your way of explaining the topics that were not known to me until then or only a little bit known helped me to get a better understanding of the subject matter.
I find the implementation of the addressing modes particularly elegant. That helped me a lot, since I first wrote an emulator (Space Invaders Arcade machine with the Intel 8080 CPU) on my first attempt to implement each statement multiple times without a test suite. The debugging was hell, but in the end I was able to run the attract mode, but the cpu had still some bugs that prevented me from playing the game. This is now 3 years ago and at the time I had very little experience of how a CPU works internally.
Today I ventured again to the topic and found your blog. Currently I have reached the point where the emulator boots and I can enter BASIC programs. With that I came further than I ever expected.
Again, many thanks. I will also describe my path in the blog, but in German, because it is easier for me. It should give others the opportunity to devote themselves to this exciting topic.
Greetings from Germany
Sven
My humble beginnings ...
Um einen Webserver mit PHP unter macOS laufen zu lassen benötigt man kein extra Paket mehr, da sowohl der Webserver, als auch PHP in macOS vorhanden sind.
Bei macOS High Sierra (10.13.2) wird der Apache Webserver in der Version 2.4.28 und PHP in der Version 7.1.7 mitgeliefert.
Also richten wir uns eine lokale Umgebung ein, die das Verzeichnis Sites im Verzeichnis unseres Hauptbenutzers freigibt.
In dem vorerst letzten Teil der Serie geht es um die Verarbeitung von Typescript und React. Desweiteren zeige ich wie man Bibliotheken in dem globalen Kontext registriert (z.B. jQuery unter dem Namen $ und jQuery) und wie man Bibliotheken extern einbindet um sie von einem CDN zu laden.
Nachdem in den vorherigen Beiträgen eine grundlegende Struktur aufgebaut wurde, mit der man sein JavaScript-Projekt starten kann, wird dies noch um einige Funktionen erweitert, die die Entwicklung und die Fehlersuche erleichtern.
Dazu gehört der webpack-dev-server, der das Webprojekt zur Verfügung stellt und bei Änderung einer Quelldatei automatisch mittels Hot Module Replacement die Änderungen an den Browser überträgt.
Die Anzeige der Log-Ausgaben und der Status des Übersetzungsvorgangs wird im webpack-dashboard angezeigt.
Außerdem wird die webpack Loader-Konfiguration erweitert. Dazu gehört
- die Erstellung von Source-Maps
- die Verarbeitung von Sass: Syntactically Awesome Style Sheets,
- die automatische Vergabe von Vendor-Prefixen in den Stylesheets und die Minifizierung der finalen Stylesheet-Datei sowie
- die Optimierung von Bildern vor dem Produktionsdeployment.
Los geht's ...
Was haben wir bisher erreicht? Im ersten Teil haben wir mittels webpack unser erstes Applikationsbundle erzeugt und haben im zweiten Teil damit eine kleine Beispielanwendung erstellt.
Hierfür wurde eine Unterscheidung zwischen Entwicklung und Produktion eingeführt, um die Ausgabe für das Produktionsdeployment zu optimieren.
Im diesem Teil führen wir Babel ein, um andere Sprachvarianten in reines JavaScript zu übersetzen. Außerdem wird die Verarbeitung von weiteren Dateitypen behandelt, damit diese wie alle anderen Abhängigkeiten im Code als Modul importiert werden können. Da die webpack-Konfiguration sehr groß wird, wird diese in zwei Dateien aufgeteilt. Einen allgemeinen Teil, und einen speziellen Teil der die unterschiede der beiden Umgebungen (Produktion und Entwicklung) beinhaltet.
Das folgende Projekt basiert auf dem Beispiel aus Webpack from Nothing. Die Applikation liest ein mit Markdown Syntax gefülltes Textfeld ein und gibt den formatierten Text auf der gleichen Seite aus. Um die Webpack Konfiguration zu testen, wird später für jeden Dateityp eine Beispieldatei hinterlegt.
Nachdem das Projekt erstellt wurde, wird die webpack-Konfiguration aufgeteilt, um für Produktion und Entwicklung unterschiedliche Bundles zu erzeugen. Warum sollte man dies tun? Zum Beispiel um in der Produktion das entgültige Applikationsbundle zu minifizierien. Dies spart Bandbreite und schützt den Code etwas vor neugierigen Blicken.
Also lasst uns beginnen...
In diesem und den folgenden Beiträgen geht es um den Aufbau einer Vorlage für moderne Web-Anwendungen. Da drängt sich mir gleich die Frage auf, warum benötige ich eine eigene Vorlage? Es gibt doch für nahezu jedes aktuelle Framework bzw. jede aktuelle Bibliothek, ob React, Angular oder Vue, eine Vorlage bzw. ein Starter Kit.
Das ist richtig, aber ein Starter Kit hilft einem nicht zu verstehen, wie die im Entwicklungsprozess eingesetzten Tools interagieren, bzw. wo sie konfiguriert werden müssen. Kommt es dann zu einem Problem, welche unausweichlich kommen werden, darf man sich das benötigte Wissen anlernen, wenn man gerade keine Zeit dafür hat.
Deshalb lasst uns von vorne beginnen...