Bildschirmspeicher

Aus C64-Wiki
(Weitergeleitet von Screen-RAM)
Zur Navigation springenZur Suche springen
Bildschirmspeicher mit Adressen für Zeilen und Spalten

Über den 1 KByte großen Bildschirmspeicher (engl. screen RAM, auch Video-RAM), der normal in dem Speicherbereich 1024 ($0400) bis 2023 ($07E7) liegt, können alle 256 Zeichen des C64 direkt in alle 25 Zeilen und 40 Spalten geschrieben werden. Im Multicolor Bitmap-Modus wird das Screen-RAM neben dem Farb-RAM genutzt, um die Farb-Informationen für bestimmte Bit-Kombinationen in der Bitmap zu hinterlegen.

In BASIC kann mit Hilfe des Befehls POKE der Bildschirmspeicher verändert werden. So setzt ein

POKE 1024,1

auf die erste Stelle des Bildschirmspeichers (linkes obersten Zeichen) das Zeichen A.
Ist AD die Anfangsadresse des Bildschirmspeichers, so wird mit der folgenden Anweisung ein "A" in Spalte X, Zeile Y ausgegeben:

POKE AD + X + Y*40, 1

Bei sehr frühen C64-Kernal-Versionen ist das "A" eventuell nicht sichtbar, weil dort die Zeichenfarbe im Farb-RAM standardmäßig identisch mit der Hintergrundfarbe gesetzt wird.


  • Einschränkungen im erweiterten Hintergrundfarbenmodus:
    Eine Veränderung der Zeichensatzgröße erfolgt indirekt durch Nutzung des erweiterten Hintergrundfarbenmodus. In diesem Modus sind nur 64 Zeichen verfügbar. Da ab dem 0., 64., 128., und 192. Zeichencode jeweils die normalen Zeichen (A-Z, 0-9 und Satzzeichen) jeweils eine andere Hintergrundfarbe erhalten.


Verschieben des Bildschirmspeichers[Bearbeiten | Quelltext bearbeiten]

Der Bildschirmspeicher kann verschoben werden. Dies geschieht mit Hilfe des CIA 2 Kontrollregisters 56576 ($DD00) und des VIC-Registers 53272 ($D018):

  • Die Bits 0 und 1 des CIA 2 Kontrollregister 56576 ($DD00) wählen die aktuelle VIC-Bank ($0-$3FFF/$4000-$7FFF/$8000-$BFFF/$C000-$FFFF).
  • Die Bits 4-7 des VIC-Speicher-Kontroll-Register 53272 ($D018) enthalten die Startadresse des Bildschirmspeichers innerhalb der gewählten VIC-Bank.

Häufig wird das Verschieben des Bildschirmspeichers in diversen Grafikmodi benutzt, wo er als Farbspeicher dient. FLI z.B. besitzt bis zu 8 Farbspeicher, von denen in jeder Rasterzeile einer neu gewählt wird.

Leider ist das Verschieben des Bildschirmspeichers im Textmodus zur Implementierung von Double Buffering (Schreiben auf unsichtbaren Bildschirm, dann Umschalten auf denselben und weiteres Schreiben auf nun unsichtbaren Bildschirm, um den Aufbau des Bildes visuell zu verbergen) kaum sinnvoll einsetzbar, da das Farb-RAM nicht umgeschaltet werden kann, das Schreiben von Zeichen mit neuen Farben in den Hintergrund-Bildschirm also auch die Farben des sichtbaren Bildschirms verändert.

In BASIC lässt sich der Bildschirmspeicher innerhalb der aktuellen VIC-Bank wie folgt verschieben:

POKE 53272,(PEEK(53272) AND 15) OR A : POKE 648, A/4 + 64*(PEEK(56576)AND3) : PRINT CHR$(147)

Der Wert für die Variable A kommt aus der unten stehenden Tabelle.

Die Anpassung von Adresse 648 ($0288) dient dazu, dem Bildschirmeditor die geänderte Position des Bildschirmspeichers mitzuteilen, da mit 53272 ($D018) lediglich dem VIC mitgeteilt wird, von wo er die Bildschirmdaten lesen soll, nicht dem Betriebssystem, und der Bildschirmeditor ohne die Anpassung noch den alten Bildschirmspeicher benutzen würde. In Adresse 648 wird immer das High-Byte der Startadresse angegeben. Nach dem Einschalten ist dies 4 für die Startadresse 1024 ($0400). Außerdem muss nach der Änderung von 648 ($0288) der Zeiger 209/210 ($D1/$D2) auf die Bildschirmzeilen neu berechnet werden, was mit der Kernal-Routine $E56C (bei $E9F0) erfolgt. Da diese von einem PRINT mit Zeilenvorschub aufgerufen wird, kann man das durch die sowieso sinnvolle Anweisung PRINT CHR$(147) tun. Achtung: außer bei der Ausgabe von CHR$(147) wirkt das erste solche PRINT noch auf den alten Bildschirm. Statt dessen funktioniert SYS 58732 ($E56C) ohne den Bildschirm zu löschen.

Programmbeispiele für das Verschieben des Bildschirmspeichers findet man im Buch Sheldon Leemon: Mapping the Commodore 64, Compute! Publications im Abschnitt 43-44 und 56576-56577.

Bit 4-7 Variable A Startspeicheradresse (hex) Anmerkung
0000 000 0 ($0000)
0001 016 1024 ($0400) Grundeinstellung
0010 032 2048 ($0800)
0011 048 3072 ($0C00)
0100 064 4096 ($1000) Zeichensatz-ROM
0101 080 5120 ($1400) Zeichensatz-ROM
0110 096 6144 ($1800) Zeichensatz-ROM
0111 112 7168 ($1C00) Zeichensatz-ROM
1000 128 8192 ($2000)
1001 144 9216 ($2400)
1010 160 10240 ($2800)
1011 176 11264 ($2C00)
1100 192 12288 ($3000)
1101 208 13312 ($3400)
1110 224 14336 ($3800)
1111 240 15360 ($3C00)

Der Bereich von 4096 ($1000) bis 8191 ($1FFF) ist effektiv nicht als Bildschirmspeicher nutzbar, da der VIC hier nicht das RAM, sondern sein Zeichensatz-ROM sieht. Dasselbe gilt für den Bereich von 36864 ($9000) bis 40959 ($9FFF).
Innerhalb der VIC-Bänke 0 ($0000-$3FFF) und 2 ($8000-$BFFF) kann man daher auf den System-Zeichensatz zugreifen. Wenn der neue Bildschirmspeicher aber in VIC-Bank 1 ($4000-$7FFF) oder 3 ($C000-$FFFF) liegt, muss man dort selbst einen Zeichensatz erstellen, sonst wird nach dem Umschalten des Bildschirmspeichers nur Durcheinander dargestellt.

Speicheradressen[Bearbeiten | Quelltext bearbeiten]

Hex-Adresse Dez-Adresse Beschreibung
Bildschirmspeicher
$0400 -
$07e7
1024 -
2023
1 kByte (1000 Bytes) Bildschirmspeicher, dient zum Setzen von Buchstaben und Zeichen im Bildschirmcode (Werte: 0-127); wird 128 zu einem Wert hinzu addiert, erscheinen die Inverszeichen (128-255). Alle 40 Spalten in den 25 Zeilen des Bildschirmspeichers sind direkt ansprechbar, z.B. setzt POKE 1024,1 das Zeichen A in die linke obere Ecke des Bildschirms (ohne die Farbe mitzusetzen).
Für die Farbzuweisung siehe Farb-RAM.
$07E8 -
$07F7
2024 -
2039
ungenutzt
Spriteblock-Register
$07F8 2040 Spritepointer für Sprite 0 in Speicherblock: Blocknr.*64
(z.B. Sprite 0 im Kassettenpuffer ab $033C: Blocknr. = 13 (13*64=832, in hex: $0340))
$07F9 2041 Spritepointer für Sprite 1 in Speicherblock: Blocknr.*64
$07FA 2042 Spritepointer für Sprite 2 in Speicherblock: Blocknr.*64
$07FB 2043 Spritepointer für Sprite 3 in Speicherblock: Blocknr.*64
$07FC 2044 Spritepointer für Sprite 4 in Speicherblock: Blocknr.*64
$07FD 2045 Spritepointer für Sprite 5 in Speicherblock: Blocknr.*64
$07FE 2046 Spritepointer für Sprite 6 in Speicherblock: Blocknr.*64
$07FF 2047 Spritepointer für Sprite 7 in Speicherblock: Blocknr.*64