GB Pointer
aus RHWiki, der freien Romhacking-Enzyklopädie
| Inhaltsverzeichnis |
Berechnung
Auf dem Gameboy (Color) werden Rombänke verwendet. Daher unterscheidet man zwischen 2- und 3-Byte Pointern, wobei ein 3-Byte Pointer nichts anderes ist, als ein 2-Byte Pointer, an dem noch die Rombank angehängt wurde.
Umrechnung Offset -> Pointer
Ein 2-Byte Pointer wird wie folgt berechnet:
Pointer = 0x4000 + (Offset And 0x3FFF) (Es werden also nur die rechten 14 Bits genommen und der Rest auf 0 gesetzt.)
Die Rombank kann man berechnen durch:
Rombank = Offset / 0x4000
Außerdem ist 00 als Rombankangabe ungültig, da diese bereits nach 0000-3FFF geladen ist und nicht nochmal geladen werden darf. Für Zugriffe in die Bank 0 wird stattdessen einfach das "+ 0x4000" weggelassen.
Umrechnung Pointer -> Offset
Bei 2-Byte Pointern rechnet man folgendermaßen das Offset innerhalb einer Rombank aus:
Offset = Pointer And 0x3FFF
Wichtig: Das errechnete Offset ist nicht absolut und damit nicht für Angabe in z.B. einem Hexeditor geeignet. Damit das Offset absolut wird, muss noch das Rombank-Offset addiert werden:
Offset = Offset + (0x4000 * Rombank)
Die Rombank kann dabei durch den (3-Byte) Pointer gegeben sein. Ansonten ist es die Bank, in der der Pointer steht.
Zum Schluss werden bei dem 2-Byte Anteil eines Pointers (aufgrund von Little Endian) wieder die Bytes vertauscht. Die Bank wird bei 3-Byte Pointern ungeachtet dessen bei den meisten Spielen immer vorneangehängt.
Schreibweisen
Pointer können ganz normal hintereinander mit Bank und allem geschrieben werden, wie z.B. 1A5F73, wobei 1A die Bank und 5F73 der schon umgedrehte Pointer ist, oder aber 1A:735F. Die Rombank steht vor dem Doppelpunkt und der Pointer wird (nicht umgedreht) dahinter geschrieben. Dieses Format benutzen vor allem Debugger und ASM, u.a. weil sich so leichter die Adressierung verdeutlichen und eingeben lässt.
Beispiele
(Wichtig: Bytevertauschung beachten!)
Pointer | Offset --------+------- 925A | X + 0x1A92 0A0D | 0xD0A 2D4050 | 0xB5040
Technischer Hintergrund
Das Rom wird in Bänke unterteilt, wovon jede 0x4000 Bytes groß ist. Daher müssen auch die Pointer in einem 0x4000 Bytes großen Bereich liegen. Weil außerdem alle Bänke außer Bank 00 nach 0x4000-0x7FFF geladen werden, muss 0x4000 addiert werden.
Aufgrund von Little Endian müssen außerdem die Bytes des 2-Byte Anteils jedes Pointers vertauscht werden.
Bei einem 3-Byte Pointer wird die Bank einfach angehängt.

