VIC-II: Speicherbereiche festlegen

weitersagen ...
Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedIn

CBM prg StudioDem VIC-II seinen Speicher zuweisen

Der C64 bietet prinzipiell zwei unterschiedliche Grafikmodi. Direkt nach dem Einschalten befindet er sich im Textmodus, außerdem gibt es noch einen Bitmap-Modus. Wo der VIC-II die jeweils benötigten Daten findet, könnt ihr sehr flexibel einstellen. So habt ihr die Möglichkeit den Speicher des C64 nach euren Vorstellungen zu nutzen.

Wer sich jetzt fragt, warum man den Speicherbereich für den VIC-II verschieben sollte, dem empfehle ich einen Blick auf ‚Landung 009‚. Ganz am Ende des Textes seht ihr, was für Probleme entstehen können, wenn man sich keine Gedanken macht, wo was im Speicher liegt.

 

‚Sichtbaren‚ Speicherbereich festlegen
Wie ihr evtl. schon wisst (ich habe es ja schon hier und da mal erwähnt), kann der VIC-II nur 16KB auf einmal ‘sehen‚. Den Beginn, des für ihn sichtbaren 16KB-Bereichs, könnt selbst festlegen. Dazu werden die insg. 64KB des C64 in vier Blöcke zu je 16KB geteilt. Diese 16KB-Blöcke nennt man auch (Video-)Bank. Die Bank legt ihr über die BITs 0 & 1 des Registers 0 ( $DD00) vom CIA-2 fest.

Wie ihr seht, stimmt die Bank-Nr. nicht mit dem Wert der BITs überein, die man setzen muss, um den entsprechenden Speicherbereich zu wählen. Nach dem Einschalten ist automatisch die Bank 0 aktiv. In Bank 1 und 3 steht euch der ROM-Zeichensatz übrigens nicht zur Verfügung (dazu später mehr)!

Die 16KB-VIC-Bänke
Übersicht, wo die 16KB-VIC-Bänke im Speicher liegen.

Wer jetzt denkt, Bank-2 und 3 seien kaum zu gebrauchen, da dort ja größtenteils das ROM liegt, der irrt. Wir können dort durchaus unsere Daten für den VIC-II ablegen. Zunächstmal lassen sich die ROMs bekanntlich deaktivieren, aber auch bei aktiven ROMs kann der VIC-II den Speicher ansprechen, da dieser nichts vom ROM weiß. Einzige Ausnahme ist das Zeichen-ROM, wie ihr gleich seht. Ihr müsst nur bedenken, dass die CPU beim Zugriff auf einen RAM-Bereich, der von einem ROM überdeckt wird, das RAM zwar beschreiben kann, beim Lesen aber aufs ROM zugreift und dass wir den E/A-Bereich natürlich benötigen, da dort die VIC-Register liegen. Der VIC-II selbst verwendet nur das RAM um an seine Daten zu kommen, einzige Ausnahme ist ein kleiner Bereich für den Zeichsatzspeicher, in den Bänken 0 und 2, das seht ihr in der Grafik noch genauer.

Speicher aus Sicht des VIC-II. In Bank 0 & 2 wird bei den angegebenen Adressen direkt aufs Char-ROM zugegriffen!
Der Speicher aus Sicht des VIC-II.
In Bank 0 & 2 wird, bei den angegebenen Adressen, direkt aufs Zeichen-ROM zugegriffen, auch wenn es sich physikalisch an der Adresse $D000 befindet!!!
Das RAM ist dort also tabu für unsere VIC-Daten!

Auch der RAM-Bereich unter der Ein- / Ausgabe ist nicht verloren. Ihr könnt dort Daten für den VIC ablegen, die sich nicht oder sehr selten ändern, z. B. der Zeichensatz. Deaktiviert dazu über $01 den E/A-Bereich, kopiert euren Zeichensatz dorthin, aktiviert die Ein- / Ausgabe wieder und weist dem VIC schließlich die entsprechenden Bänke zu. Genaueres findet ihr in Kürze in den Beiträgen zu ‚Level 03 – Die Fahrt zur Basis‚ des Spieletutorials ‚L.O.V.E.‚.

 

Um die Bank zu wählen, müssen wir den Datenport-A des CIA-2 verwenden. Diesem sollten wir zur Sicherheit mitteilen, dass wir etwas ins Register schreiben möchten, das machen wir über Register 2 ( $DD02) des CIA-2.

Mit diesem kleinen Programm könnt ihr testen, was beim Umschalten der Speicherbank passiert. Startet ihr obiges Programm, passiert erstmal nichts. Das liegt daran, dass dort die Bank 0 aktiviert wird, die ja auch direkt nach dem Einschalten aktiv ist. Versucht mal die anderen Bänke. Euch fällt dann auf, dass bei Bank 1 und 3 keine Textzeichen auf dem Bildschirm erscheinen. Die Anzeige hängt allerdings vom jeweiligen System und / oder Emulator und der jeweiligen Konfiguration ab. Hier können wir schon sehen, was oben bereits erwähnt wurde, dass der ROM-Zeichensatz in Bank 1 & 3 nicht verfügbar ist.

 

Lage des Bildschirmspeichers festlegen
Wir können als nächstes bestimmen, wo sich, innerhalb der sichtbaren 16KB, der Textbildschimspeicher befinden soll. Dazu werden die sichtbaren 16KB in 16 Blöcke zu je 1KB unterteilt. Diesen Bereich können wir diesmal über die BITs 7-4 im VIC-II Register 24 ( $D018) bestimmen. Die Position lässt sich ganz einfach über den Wert der BITs 7-4 * 1KB ( $0400) berechnen, wenn man diese einzeln betrachtet.

Damit ihr wisst, auf welchen Speicherbereich ihr zugreifen müsst, um etwas auf den Bildschirm zu bringen, müsst ihr zur hier gewählten Position natürlich noch den Beginn der von euch gewählten 16KB-Bank addieren. Nach dem Einschalten erhalten wir so die uns bekannte Adresse  $0400 (Bank 0: ab $0000 + $0400 für die Position des Bildschirmspeichers = $0400).
Falls ihr euch jetzt fragt, was mit dem Farb-RAM ist, das lässt sich nicht verschieben! Ihr findet es immer ab $D800!
Denkt auch daran, dass sich die Sprite-Pointer immer in den letzten acht BYTEs am Ende des Kilobytes, in dem der Bildschimspeicher liegt, befinden. Sprites werden übrigens ausfühlich in ‚Sprites (ASM)‚ behandelt.

Um den Bildschirmspeicher zu positionieren, holen wir zunächst den Inhalt des Registers 24 in den Akku. Blenden dann das obere Nibble per AND aus und setzen es danach durch ORA auf den von uns gewünschten Wert. Hier haben wir wieder den Standardwert vorliegen, so dass nach einem Start anscheinend nichts passiert. Ändert den Wert beim ORA mal auf Null und startet das Programm. Dann habt ihr den Anfang des BS-Speichers in die Zero-Page verschoben und ihr seht, dass sich von Geisterhand einige Zeichen ändern. Daran erkennt ihr, dass ihr beim Positionieren aufpassen müsst. Überdeckt der Bildschirmspeicher wichtige Speicherbereiche und ihr gebt etwas auf dem BS aus, dann wird der C64 früher oder später abstürzen.

 

Zeichspeicher positionieren
Die Möglichkeiten Speicherbereiche festzulegen, reißen einfach nicht ab 😉 . Ihr könnt dem VIC-II auch vorgeben, wo er die Zeichen für die Textausgabe findet. Dabei handelt es sich um 8*8 Punkte große ‚Grafiken‚ die das Aussehen der Zeichen festlegen. Wer sich jetzt fragt, warum man diesen Speicher festlegen kann, schließlich stehen die Zeichen ja im Char-ROM: Man kann seine eigenen Zeichsätze entwerfen! Diese ‘neuen‚ Zeichen müssen dann natürlich im RAM liegen, also müssen wir dem VIC mitteilen, wo er sie findet. Da ein kompletter Zeichensatz 256-Symbole umfasst, benötigen wir also 1 BYTE * 8 Zeilen * 256 Zeichen = 2KB. Die sichtbaren 16KB werden für die Wahl des Beginns des Zeichensatzes in 8 Blöcke zu je 2KB unterteilt. Auch dieser Speicherbereich lässt sich über das Register 24 des VIC-II festlegen. Dazu dienen die BITs 3-1.

Auch hier müsst ihr wieder beachten, dass der Beginn der 16KB-Bank zum Beginn des Zeichensatzes addiert werden muss, um die tatsächliche Adresse zu ermitteln. Nr. 2 und 3 stellen bei Benutzung von Bank 0 und 2 einen Sonderfall dar. Schaut ihr bei diesen Bänken in die Speicherstellen $1000-$1FFF bei Bank 0 bzw.  $9000-$9FFF bei 2, so werdet ihr dort keine Zeichenmuster entdecken. Schreibt ihr etwas in diese Adressen, dann ändert sich der Zeichensatz auch nicht! Das liegt daran, dass der VIC-II bei diesen Werten in Bank 0 & 2 direkt auf das Char-ROM zugreift. Der Speicher steht euch dann ganz fürs Programm (Befehle und Daten) zur Verfügung, die CPU kann problemlos auf diese Adressen zugreifen.
Ihr könnt in diesen Bänken aber keinen eigenen Zeichensatz ablegen! Die CPU kann die Daten zwar dort ablegen, aber der VIC-II sieht sie nicht!

Auch bei der Wahl des Zeichsatzspeichers, setzen wir zunächst per  AND die BITs (hier 3 bis 1) auf null und schreiben danach per  ORA den Standardwert ins Register 24. Ein Start zeigt wieder keine Änderung, sobald ihr aber etwas Anderes eintrag, werden sich die Zeichen auf dem Bildschirm, je nach gewähltem Speicherbereich, in ‚wirre‚ Zeichen ändern. Benutzt ihr wieder die Zero-Page, dann bewegen sich auch einige Pixel der Zeichen.
 

Speicher für Bitmap-Grafik bestimmen
Auch für HiRes-/Bitmap-Grafik kann der benötigte Speicherbereich von uns bestimmt werden. Diese Grafiken benötigen sehr viel Speicher. Sie haben eine max. Auflösung von 320*200 Pixel = 64000 Bildschirmpunkte. Teilt man diese durch acht, um die BYTE-Anzahl zu errechnen, dann kommen wir auf 8000 BYTEs. Daher werden die sichtbaren 16KB in nur zwei 8KB-Bereiche unterteilt. Dieser Speicher wird über BIT-3 im Register 24 ( $D018) bestimmt. Achtet darauf, dass BIT-3 auch für die Position das Zeichenspeichers benötigt wird. Sobald ihr den HiRes-/Bitmap-Modus aktiviert, steuert BIT-3 aber die Position der Grafik.

Wie gehabt, muss wieder der Beginn der 16KB-Bank berücksichtigt werden, um die tatsächliche Adresse zu berechnen. Um dies jetzt zu testen, müssen wir natürlich den Bitmap-Modus aktivieren.

Sobald wir mit dem VIC-II Register 17 ( $D011) den Bitmap-Modus aktiviert haben, wird über BIT-3 im Register 24 ( $D018) die Position des Bitmap-Speichers bestimmt.

 

Abschließend nochmal eine kleine Übersicht, wo ihr etwas, innerhalb einer, für den VIC sichtbaren, 16KB-Bank, ablegen könnt.

Blöcke innerhalb einer VIC-Bank.
Blöcke innerhalb einer VIC-Bank.

Ich brauche wohl nicht extra zu erwähnen, dass ihr darauf achten solltet, dass sich gleichzeitig benötigte Speicherbereiche nicht überscheiden sollten / dürfen. Wählt ihr also z. B. CHAR 0 und BS 0, wird es ‚übel‚ enden. 😉

 


Schrott!!Naja...Geht so...Ganz gut...SUPER! (6 Bewertungen | Ø 4,67 von 5 | 93,33%)

Loading...


 

<<< zurück | weiter >>>

 

weitersagen ...
Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedIn

3 Gedanken zu „VIC-II: Speicherbereiche festlegen“

  1. ah danke für die tolle Erklärung! Ich habe jetzt sowohl bei $D000 als auch bei $D800 einen Zeichensatz liegen und es klappt!:-) Ich hatte ursprünglich versucht, bei ausgeblendetem E/A-Bereich die Zeichensätze direkt an die Zieladresse zu laden, was (nachvollziehbarerweise) nicht geht. Wenn ich sie zuerst an eine andere Adresse lade und dann im Speicher kopiere, gibt es kein Problem.

    >>Der Zeichensatz müsste ja entweder bei $D000 oder bei $D800 liegen, um überhaupt vom VIC addressiert werden zu können.

    Was ich damit meinte, war, dass man bspw. nicht einen 64-Zeichen-Zeichensatz nach $D400 (SID) legen kann, um das vermeintliche Überschreiben des Farbspeichers zu umgehen.

    Viele Grüße!

    Carsten

  2. Hallo Jörn,

    Du schreibst „Auch der RAM-Bereich unter der Ein- / Ausgabe ist nicht verloren. Ihr könnt dort Daten für den VIC ablegen, die sich nicht oder sehr selten ändern, z. B. der Zeichensatz. „.

    Das will mir nicht in den Kopf: Der Zeichensatz müsste ja entweder bei $D000 oder bei $D800 liegen, um überhaupt vom VIC addressiert werden zu können. Bei $D000 liegen doch aber schon die VIC-Register und bei $D800 der Farbspeicher, also beides braucht der VIC selbst! Da kann ich doch dann keinen Zeichensatz ablegen, oder?

    Viele Grüße!

    Carsten

    1. Moin Carsten,
      wie heißt es doch so schön: „Klingt komisch, ist aber so.“ 😉

      Du musst dir vor Augen führen, was der E/A-Bereich wirklich macht. Wenn du z. B. die Hintergrundfarbe über $D021 setzt, dann steht der Wert nicht im RAM an der Adresse $D021! Der E/A-Bereich mappt die Adressen auf die Register / Speicherzellen der Custom-Chips (VIC, SID, CIA usw.). Die Hintergrundfarbe steht also direkt im VIC-II, daher braucht bzw. kennt der VIC selbst die Speicherstelle $D021 auch nicht. Das Farb-RAM verhält sich ähnlich. Es ist ein eigener RAM-Baustein auf dem C64-Board, der direkt mit dem VIC verbunden ist. Schreibst du also etwas nach $D800, dann landet es (bei aktiven E/A-Bereich) im eigenen Farb-RAM. Da dieses RAM lediglich 4-Datenleitungen besitzt, lassen sich dort nur die Werte 0 bis 15 ablegen (also die 16 möglichen Farben des C64). Wenn man so will, hat der C64 also eigentlich 64,5KB. Holt der VIC nun seine Daten (z. B. Sprites oder den Zeichensatz), dann macht er dies immer aus dem normalen Arbeitsspeicher (RAM). Daher kann man, wie oben erwähnt, unter dem Kernal und E/A-Bereich auch entsprechende Daten für den VIC ablegen.

      Vielleicht solltest du dies einmal selbst auszuprobieren:

      • lege (wie oben beschrieben) den Speicherbereich entsprechend fest
      • schalte den E/A-Bereich wie in „Kleine Hardwarekunde“ erwähnt ab
      • kopiere z. B. Spritedaten nach $D000
      • aktiviere den E/A-Bereich wieder
      • und zeige das Sprite an

      Gruß,
      Jörn


      EDIT: Habe noch etwas vergessen.

      Der Zeichensatz müsste ja entweder bei $D000 oder bei $D800 liegen, um überhaupt vom VIC addressiert werden zu können.

      Warum? Der Zeichensatz kann auch noch weiter hinten liegen, sogar $F800 ist möglich.

Schreibe einen Kommentar


Beachtet bitte, dass ich eure Kommentare erst manuell freigegeben muß, bevor sie auf der Seite erscheinen! Da ich nicht pausenlos am Rechner sitze, kann es schon mal etwas dauern, bis ein Kommentar für alle sichtbar ist.

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Protected by WP Anti Spam