Ein bekanntes Format für NES-Roms ist iNES. Dessen erste drei Bereiche sind der Header, der Program ROM (PRG) und der Character ROM (CHR). PRG und CHR sind in Banks unterteilt, welche je 16 * 1024 Byte bzw. 8 * 1024 Byte groß sind.
Der Header besteht aus 16 Byte. Die erste vier lauten immer 0x4e
, 0x45
,
0x53
und 0x1a
, was in ASCII für NES(SUB)
steht. Darauf folgen zwei Byte,
welche je die Anzahl der PRG- und CHR-Banks beinhalten. Die restlichen 10 Byte
sind leer.
Der Program ROM hält die Business Logic.
Tiles liegen im CHR-ROM. Ein Tile ist 8 * 8 Pixel groß und jedes Pixel benötigt 2 Bit, kann also vier Werte annehmen: Transparent oder eine von drei Farben. Demnach sind Tiles 8 * 8 * 2 = 128 Bit = 16 Byte groß. Das ergibt bei einer Banksize von 8 * 1024 dann 8192 / 16 = 512 Tiles pro Bank.
Um die Farben der einzelnen Pixel zu erhalten, wird über die ersten acht Byte eines Tiles iteriert. Die Farbe des i. Pixel der j. Zeile setzt sich aus dem i. Bit des j. Byte und dem i. Bit des j + 8. Byte zusammen. Ersteres ist das niedrigwertige Bit und letzteres das hochwertige.
Zur Verdeutlichung das erste Tile aus Super Mario Bros, bei dem zusammengehörende Bytes nebeneinander stehen:
01234567 01234567
0 00000011 8 00000000
1 00001111 9 00000000
2 00011111 10 00000000
3 00011111 11 00000000
4 00011100 12 00011111
5 00100100 13 00111111
6 00100110 14 00111111
7 01100110 15 01111111
Die fünfte (j = 4) Zeile setzt sich also aus den Bytes j (4, 00011100
) und j +
8 (12, 00011111
) zusammen. Die ersten drei Farben sind 00
(transparenter
Hintergrund), die nächsten drei 11
(Marios Haare) und die letzten zwei 10
(Marios Gesicht). Weitergespielt ergibt sich folgendes Bild:
Beispielhaft ist hier 00
Transparent, 01
Rot, 10
Grün und 11
Blau.
Alle Super Mario Bros Tiles:
Ist die Anzahl der CHR-Banks null, sind Tiles im PRG-ROM gespeichert. So bspw. bei Mega Man. Das zuvor beschriebene Verarbeiten der gesamten Rom zeigt, dass Tiles dort nicht notwendigerweise zusammenhängen müssen (Mega Man Tiles).
Die Informationen stammen von Sadistech und N3S. Eine implementation liegt auf GitHub.