Ich habe einen Gameboy Advance (GBA) ROM Dumper entwickelt, mit dessen Hilfe man seine GBA Spiele auf den Computer kopieren kann. Das Ganze funktioniert mit dem Arduino Uno und einem Java-Programm, was sich um die ankommenden Daten kümmert und diese in eine Datei auf den Computer schreibt.

Abbildung 1: GameBoy Advance Rom Dumper mit einem Arduino
Abbildung 1: GameBoy Advance Rom Dumper mit einem Arduino

Wie ich auf die Idee kam

Los ging es eigentlich im Sommer 2015. Da hatte mich wieder einmal das Interesse gepackt, etwas lowleveliges zu entwickeln. Generell finde ich es oft spannend technische Dinge nachzubauen, um zu verstehen, wie diese funktionieren und um herauszufinden, ob ich diese im besten Fall überhaupt selber nachbauen kann.

Im Grunde erfindet man das Rad neu, aber ich kann so am besten Dinge verstehen und lernen und was auch noch hinzukommt, es macht Spaß.

Vor vielen Jahren (2006), als auf meinem Schreibtisch noch ein erster weißer Intel iMac stand, hatte ich bereits versucht ein eigenes Programm auf dem GBA zum Laufen zu bekommen.

Mit Tutorials (wie z. B: TONC) die es im Internet zu finden gab, habe ich es dann auch geschafft, aber da ich von der Architektur solcher Systeme und den Entwicklungstools nur wenig Ahnung hatte, bin ich den meisten Erklärungen praktisch blind gefolgt. Eine Sache, die ich eigentlich gar nicht zufriedenstellend fand und finde.

Mein eigener Emulator in Java

Also wollte ich dieses Mal versuchen einen eigenen GBA Emulator in Java zu schreiben. (Was bis jetzt auch mit Erfolg gekrönt ist und worüber ich vor habe einen weiteren Blog-Post zu schreiben.) Auf jeden Fall fand ich bald darauf den Gedanken interessant, meine eigenen ROM-Dumps auf meinem GBA Java-Emulator laufen zu lassen.

Wieso ich einen Arduino Uno verwende

Da ich zuhause eine Arduino Uno rumliegen hatte, hoffte ich damit die technischen Voraussetzungen zu erfüllen, um erfolgreich mit einem GBA ROM zu kommunizieren. Im Internet bin ich auf das Projekt Arduino Based GBA ROM Dumper von Shiny Quagsire gestoßen, der das Ganze mit einem Arduino Mega umgesetzt hat.

Da ich mir aber keinen Arduino Mega kaufen wollte, musste ich versuchen das Konzept und die Kommunikation zwischen ROM und Arduino Uno nachzubauen, was nach vielen Versuchen tatsächlich funktioniert hat.

So wird der ROM Speicher ausgelesen

Schraubt man ein Spiel-Modul auf, kann man auf der Platine zwei Chips sehen. Je nach Spiel gibt es noch zusätzliche Hardware. Auf dem Bild ist das Spiel-Modul der deutschen Version von Golden Sun zu sehen.

Wie man hier schön beschriftet sieht, befindet sich links der ROM – Chip und auf der rechten Seite der FLASH – Chip für die Spielstände.

Abbildung 2: Geöffnetes GBA Cartridge Module
Abbildung 2: Geöffnetes GBA Cartridge Module

Man kann den ROM Speicher auf zwei Arten auslesen. Die erste Möglichkeit besteht darin eine beliebige Adresse auszulesen. Bei der zweiten Möglichkeit kann man sich die Daten der darauffolgenden Adresse ausgeben lassen.

Abbildung 3: GBA Rom Cartridge Module Pinout
Abbildung 3: GBA Rom Cartridge Module Pinout

1. Zugriff auf eine beliebige Speicheradresse – Nicht sequentieller Speicherzugriff

Möchte man sich die Daten einer beliebigen Speicheradresse ausgeben lassen, geht das wie folgt:

  1. Man setzt CS auf HIGH.
  2. Man setzt RD auf HIGH.
  3. Man legt auf den Adressbus die Speicheradresse.
  4. Man setzt CS auf LOW.
  5. Man setzt RD auf LOW.

Jetzt sollte man auf dem 16 Bit Datenbus zwei Bytes auslesen können. Hinweis: Jede Adresse verweißt auf zwei Bytes. Das bedeutet z.B. Adresse 0 zeigt auf Byte 0 und 1, Adresse 1 zeigt auf Byte 2 und 3, usw.

2. Zugriff auf die nächst höhere Speicheradresse – Sequentieller Speicherzugriff

Hat man bereits eine Speicheradresse nicht sequentiell ausgelsen, kann man recht einfach die nächst höhere (Speicheradresse +1) Adresse auslesen, in dem man folgendes macht:

  1. Man setzt RD auf HIGH.
  2. Man setzt RD auf LOW.

Jetzt sollte man auf dem 16 Bit Datenbus die nächsten zwei Bytes auslesen können.

So sieht der Schaltplan aus

Nachdem ich erklärt habe, wie man den GBA-ROM theoretisch ausließt, muss man sich noch anschauen, wie man das Spiel-Modul praktisch mit dem Arduino verbinden kann.

Auf die Spannung achten

Der Arduino Uno arbeitet mit einer Betriebspannung von 5V und der ROM-Chip des Spiel-Modul mit 3,3V. Prinzipiell könnte eine Spannung von 5V einen 3,3V Chip beschädigen. Der ROM-Chip im GBA Spiel-Modul ist jedoch 5V tolerant.

Der kleine Trick mit der 24 Bit Adressleitung

Es fällt auf, dass der Arduino Uno nicht genügend Ein- und Ausgangspins hat, um jede Leitung vom ROM mit dem Arduino zu verbinden. Da man wie eben beschrieben den ROM auch sequentiell auslesen kann, braucht man die 24 Bit Adressleitung nur beim ersten Zugriff.

Fängt man direkt ab der Adresse 0 an, den ROM-Chip sequentiell auszulesen, muss man nur einmal beim ersten Zugriff alle Pins auf GND legen, um die Adresse 0 auszulesen.

Da die ersten 16 Bit der Adressleitung gleichzeitig auch die 16 Bit der Datenleitung sind, kann man nur auf die acht Leitung verzichten, die allein für die Adressleintung zuständig sind. Diese acht Leitungen verbindet man mit GND.

Quellcode

Meinen noch nicht dokumentierten Java und Arduino Uno Code findet ihr auf GitHub. Wie das Ganze technisch funktioniert werde ich ein anderes mal hier unter den Blog-Post schreiben.