Bildschirmspeicher
Ü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 |