Adressen: Banks, Pages, Memory-Mapped Input/Output
Das SNES benutzt Memory-Mapped Input/Output.
Aaalso.
Ich habe im vorherigen / in einem der vorherigen Klumpen Basiswissen gesagt, dass man beim Programmieren direkt mit dem Prozessor redet, und der maßgeblich Zahlenwerte in seine drei Register (den Akkumulator, das X- und Y-Register) zieht, sie prüft und eventuell umändert, und dann wieder ablegt.
Dazu benutzt man zum Beispiel den Speicher (engl. Memory).
Stell dir den Speicher als ein ganz ein hässliches, großes, graues Betongebäude ohne Fenster vor, in dem viele, viele Karteischränke stehen. Das ist der Speicher. Du bist jetzt der Akkumulator, und du hast für deinen heutigen Arbeitstag (d. h. Arbeitstakt) den Auftrag bekommen, etwas aus dem Speicher zu holen.
Da dummerweise alles in dem Gebäude gleichaussieht, gibt es keine optischen Orientierungspunkte, nach denen man dir eine Wegbeschreibung hätte geben können, sondern du kannst dich nur nach dem Zettel orientieren, den du dabei hast, auf dem steht,
wo du gucken musst.
Also guckst du auf den Zettel und siehst: "Hol den Inhalt aus dem Karteikasten in der 200. Etage, 148. Regal, dritte Reihe, erste Spalte". Und dann machst du dich auf den Weg. Du stellst fest: Das Haus hat exakt 256 Stockwerke** (da es aufgrund der Brandschutzverordnung Probleme gab, die alle nach oben zu bauen, hat man die meisten unter Tage untergebracht; der Fahrstuhl ist temporarily out of order), pro Stockwerk stehen dort 256 Regalreihen mit Karteikästen, wobei in einer Regalreihe sechzehn mal sechzehn Karteikästen stehen. Mit der knappen Anweisung auf dem Zettel weißt du, der Laufbursche namens Akkumulator, aber dennoch ganz genau, wo du hinmusst.
Du suchst läufst die Treppen, du findest die Regalreihe, du findest den richtigen Karteikasten, du öffnest... und, äh, findest da dann 8 Bit.
Genug von diesem Mumpitz.
Dieses Bild hilft aber in etwa zu verstehen, wie man beim SNES-Programmieren spricht.
Obenbesagter Zettel, den man dem Laufburschen gibt, heißt in Assembler z. B.
"LDA" heißt: "Load Accumulator", Lade in den Akkumulator. Danach folgt die Angabe, von wo er laden soll. Diese Angabe heißt (auch hier): Adresse. Diese Adressen können sechs-, vier- oder zweistellig sein (in diesem Zusammenhang ist es normal, Hexzahlen zu gebrauchen). Dabei stehen, bei oben genanntem Beispiel, die linken beiden Stellen für die sogenannte "Bank" ($C8 in diesem Beispiel, die 200. Etage in meinem Bild), die mittleren beiden Stellen stehen für die "Page" ($94 bzw. das 148. Regal), die letzten sind dann die genaue Angabe des bytegroßen Speicherorts ($20 bzw. die exakte Reihen- und Spaltenangabe im Regal). In jedem dieser "Speicherorte" oder Register, wie sie heißen, findest du dort dann einen Byte.
Ich habe erwähnt, dass die Ladebefehle auch nur z.B. vierstellige Speicheradressen bekommen können. Für den Fall kann man beim Programmieren vermerken, welche Bank (welche Etage) man meint, wenn man keine Angabe zur Bank macht.
Also, wie man sieht, ist der Speicher mit Adressen versehen, sodass man einzelne Bytes direkt ansprechen kann.
Der Speicher ist kartographiert.
Englisch: The memory is mapped.
Kommen wir wieder zum Anfang:
Das SNES benutzt Memory-Mapped Input/Output.
Was ist Input? Was ist Output? Eingabe und Ausgabe. Ja, richtig. Was ist beim SNES Eingabe? Z. B. ein Tastendruck auf dem Controller. Was ist Ausgabe? Zum Beispiel ein Bild auf dem Fernseher. Korrekt.
Bringen wir dieses Wissen jetzt mit obigem zusammen, erklärt sich, was mit "Memory-Mapped Input/Output" gemeint ist:
Die Eingabe- und Ausgabegeräte vom SNES haben Adressen, die so aussehen, als wären sie Speicher. Mit Speicher meine ich ROM, der Platz, wo bei einem Spiel die Grafikdaten liegen oder Programmcode oder dergleichen.
Das heißt: Die Befehle, wo ich etwas aus dem Speicher lade, oder Daten von einem Controller abfrage, sehen komplett gleich aus.
Ich hatte oben bereits als Beispiel mit der fiktiven Speicheradresse $C89420 gebracht. Um den Byte daraus zu lesen, schreibe ich den Befehl
Wenn ich jetzt z. B. prüfen möchte, welche Buttons auf dem Controller 1 gedrückt werden, gucke ich nach, welche Adresse das Register hat (es sind übrigens zwei Register: $4218 und $4219, ich nehme nur mal eins), und sage dann:
Jetzt habe ich die Rohdaten im Akkumulator, und kann sie weiterverarbeiten.*
*Nur als Nebeninformation, was jetzt nicht relevant für das System der Adressen ist:
In den Registern $4218 und $4219 sind jeweils ein Byte, und je nach dem, welcher Button auf dem Controller gedrückt wird, wird ein unterschiedlicher Bit in den Bytes dann auf 1 gesetzt.
** Unsere Leser fragen:
hubbi2 hat geschrieben:... und warum hat das Haus exakt 256 Stockwerke?
Lieber hubbi2,
die Adressen können nicht länger als 24 Bit (also 3 Byte) sein; das hat was mit der Hardware zu tun: Das entsprechende Gerät hat nur für 24 Bit Plätze. Folglich ist der höchste Adressenwert, die jemals angesprochen werden kann, wenn alls Bits auf 1 stehen, das ist $FFFFFF. Die Stockwerke sind eine Verbildlichung für den höchsten Byte dieser Adresse, also die $FFxxxx. Und dieser Byte kann, wie jeder Byte, zwischen 0 und 255 liegen. Das wiederum macht 256 Varianten. Und da ich diesen Byte, wie gesagt, mit einer Stockwerk-Angabe verglichen habe, kann es also nur 256 Stockwerke geben.
Soweit dazu. Ist das verständlich? Habe ich irgendwas vergessen? Irgendwas vollends falsch erklärt? Alles chic? Alles nich-so-chic?