Grundlagen

Soft-Scrolling auf dem C 64

Soft-Scrolling in eigene Programme einzubauen, kann oft zum Problem werden. Wie es gemacht wird, zeigt Ihnen dieser Beitrag.

Jeder kennt bestimmt Defender oder ähnliche Arcade-Games, bei denen die Hintergrundlandschaft über den Bildschirm zieht. Gemeint ist das sogenannte Smooth- oder Soft-Scrolling. Der Unterschied zwischen normalem und Soft-Scrolling ist, daß der Bildschirm beim Soft-Scrolling in Einerschritten (um ein Pixel) und beim normalen in Achterschritten (immer um acht Pixel gleichzeitig) verschoben wird.

Beim Achterscrolling werden einfach die Speicherstellen des Video-RAMs (ab 1024/$0800) um jeweils eine Stelle nach links, rechts, oben oder unten verschoben.

Zum Achterscrolling ein Beispiel in Basic:

TODO PRE

10 REM Beispiel Nr. 1
20 PRINT CHR$(147);TAB(14);
30 PRINT "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
40 FOR I=1064 T0 1024 STEP -1
50 POKE I,PEEK (I-1)
60 NEXT
70 G0T0 40

Dieses Programm arbeitet zwar noch relativ schnell, aber wir werden später diese Aufgabe einem Assemblerprogramm übergeben.

Das Alphabet wird nach dem Eintippen dieses Programms nach rechts herausgeschoben. Dieses Achterscrolling ist aber zu sprunghaft, und falls es schneller läuft, ist die gescrollte Schrift unleserlich.

Das Soft-Scrolling bewirkt, daß die Schrift gleichmäßig fließend und damit leserlich gemacht wird. Wie scrollt man denn nun aber den Bildschirm um nur ein Pixel?

Die Hauptrolle hierbei spielen die Speicherstellen 53248+17 (53248 = Basisadresse des Video-Chips +17 für das vertikale und 53248+22 für das horizontale Scrolling).

Befassen wir uns zunächst mit dem horizontalen Scrolling. Die Speicheradresse 53248+22 ist folgendermaßen aufgebaut:

Bit 7 bis 5 : Sind nicht benutzt

Bit 4 : Zur Umschaltung auf Multicolor
Wichtig sind für unsere Anwendung nur:

Bit 3 : Umschalten von 40 auf 38 Spalten

Bit 0 bis 2 : Horizontales Scrolling

Dazu ein Versuch:
POKE 53248+22,PEEK (53248+22) AND 248 OR 3

Nun müßte sich der Bildschirm um drei Pixels nach rechts verschoben haben.

Einige werden sich jetzt fragen, warum die ANDs und ORs?

Nehmen wir einmal an, im Register 22 des VIC würde die Zahl 107 stehen. Diese Zahl wird mit 248 AND-verknüpft. Beide Zahlen müssen binär aufgeschlüsselt werden:

TODO

107 = 01101011
AND 248 = 11111000
ergibt 01101000

Durch diese AND-Funktion werden also die Bits 0 bis 2 gelöscht. Die Bits 3 bis 7 ändern sich nie. Durch die OR-Funktion werden die entsprechenden Bits gesetzt:

TODO

01101000
OR 3 00000011
ergibt 01101011

Die Bits für das horizontale Scrolling enthalten jetzt den Wert 3. Der höchste mit den Bits 0 bis 2 zu erreichende Wert ist 7, der niedrigste ist 0. Je größer der Wert in diesen drei Bits, desto weiter wird der Bildschirm nach rechts verschoben! Mit dieser Erkenntnis können wir den Bildschirm um sieben Pixels nach rechts rollen!

TODO PRE

10 REM Beispiel Nr. 2
20 FOR 1=0 T0 7
30 POKE 53248+22,PEEK (53248+22) AND248 OR I
40 FOR T=0 T0 1000:NEXT T
50 NEXT I
60 RUN

Dieses Programm verschiebt den Bildschirm langsam von der normalen Position um sieben Pixel nach rechts. Dann wird er wieder auf die normale Position zurückgesetzt und rollt wieder nach rechts. Wie macht man es nun, daß der Bildschirm über das 7. Pixel hinausscrollt?

Dies ist ganz einfach: Nachdem das 7. Pixel erreicht wurde, machen wir ein Achterscrolling, das heißt wir verschieben einen Bildschirmcode um ein Zeichen nach rechts. Gleichzeitig setzen wir das Scrollregister wieder auf Null und haben jetzt das 8. Pixel erreicht.

Bild 1. Grafische Erläuterung des Soft-Scrolling

Jetzt können wir die Prozedur wieder von vorne beginnen (dazu ein Flußdiagramm).

S = SCROLLREGISTER

Dieses Flußdiagramm muß nun noch in ein Programm umgesetzt werden. Würde das gesamte Programm in Basic geschrieben, wäre es ziemlich langsam. Deshalb wird im nachstehenden Listing das Achterscrolling in Assembler realisiert. Es scrollt die erste Zeile in Achterschritten nach rechts. Zuerst die Darstellung in Maschinensprache und dann in DATA-Zeilen:

TODO

LDA $0427 ; STA $FB Speicherstelle 1063 merken
LDX #38 ; Bei Spalte 38 anfangen
LDA $0400,X ; Bildschirmcode laden
INX ; Um 1 erhöhen
STA $0400,X ; DEX Und abspeichern
DEX ; Um 2 erhöhen
CPX #$FF ; Schon fertig ?
BNEV
LDA $FB ; STA $0400 1063 wieder nach 1024
LDA $D016 ; Scrollregister laden
AND #248 ; Scrollbits löschen
STA $D016 ; RTS Zurückspeichern
110

Dieses Maschinenprogramm schiebt die Zeilen, die in der ersten Zeile des Bildschirms stehen, nicht nur nach rechts, sondern macht ein Rundum-Scrolling. Die rechts verschwundene Schrift erscheint also wieder am linken Bildschirmrand. Dies wird durch die ersten und letzten beiden Maschinenprogrammzeilen ermöglicht. Startet man dieses Programm, so ist ab und zu ein leichtes Zucken zu erkennen. Dies liegt daran, daß der Elektronenstrahl, der den Bildschirm 25mal in der Sekunde aufbaut, die erste Zeile schreibt, während sie gescrollt wird. Wie kann man das vermeiden?

Es ist das Register 53248+18, das benötigt wird. In ihm steht die Zeile, in der sich der Elektronenstrahl befindet (nähere Informationen siehe 64’er, Ausgabe 11/84).

Wir brauchen also nur dieses Register auszulesen und die erste Zeile erst dann zu scrollen, nachdem sie vollständig vom Elektronenstrahl aufgebaut wurde.

Die Abfrage muß in Assembler geschehen, da ein Basic-Programm im Verhältnis zur Geschwindigkeit des Elektronenstrahls zu langsam ist. Der richtige Zeitpunkt für den Beginn des Scrollings ist ungefähr dann gegeben, wenn der Strahl die Rasterzeile 100 erreicht hat.

Wir müssen das obige Maschinenprogramm also noch etwas erweitern. Ganz am Anfang muß stehen:

TODO

X LDA 53248+18 ; Rasterzeile auslesen
CMP #160 ; Vergleiche auf 160
BMI X ; Wenn kleiner dann nach X
CMP #190 ; Vergleiche auf 190
BPL X ; Wenn größer dann nach X
RTS

Und nun das gesamte 1-Zeilen-Soft-Scrolling in Basic: (Das dazugehörige Maschinenprogramm ist so geschrieben, daß es in jeden Bereich ge-POKEt werden kann!)

10 REM Beispiel Nr. 3
20 PRINT CHR$(147);GOSUB 100
30 PRINT "Beliebiger Text kleiner als 40 Zeichen"
40 REM Farbe = schwarz
50 FOR I=55296 TO 55296+39:POKE I,0:NEXT
60 FOR I=1 TO 7
70 POKE 53248+22,PEEK (53248+22) AND 248 OR I
80 FOR T=0 TO 5:NEXT
90 NEXT I
100 FOR T=0 TO 3:NEXT
110 SYS32768:REM Achterscrolling
120 GOTO 60
130 REM Masch.PRG einlesen
140 FOR 1=32768 TO 32768+44:REM 44 DATAs
150 READ G:S=S+G:POKE I,G:NEXT
160 IF S=6044 THEN 180
170 PRINT"FEHLERINDATAS!":STOP
180 RETURN
190 DATA 173,18,208,201,160,48,249,201
200 DATA 190,16,245,173,39,4,141,255,207
210 DATA 162,38,189,0,4,232,157,0,4,202
220 DATA 202,224,255,208,243,173,255,207
230 DATA 141,0,4,173,22,208,41,248,9
240 DATA 0,141,22,208,96

Man stellt fest, daß die Zeichen am rechten Rand langsam herauswandern; aber am linken Rand plötzlich auftauchen. Dies läßt sich verhindern, indem man den Bildschirm seitlich verengt (Bit 3 des Registers 53248+22 löschen). Das kann man mit
POKE 53248+22,PEEK(53248+22)AND247 erreichen. Platz dafür wäre zum Beispiel in Zeile 45.

Bild 2. Das Flußdiagramm erläutert die verwendete Scroll-Routine

Basic reicht nicht aus, um eine angemessene Geschwindigkeit zu erreichen. Deshalb steigen wir nun ganz auf Assembler um! Schreiben wir zunächst die Zeilen 60 bis 90 des Beispiels Nummer 3 in Assembler:

M LDA 53248+22 ; Scrollregister laden
AND #7 ; Scrollbits ausfiltern
CMP #7 ; Schon 7 ?
BNE N ; Wenn nicht dann Einerscrolling
JSR ACHTSC ; Achterscrolling
JMP M ; Nächste Verschiebung
N INC 53248+22 ; Scrollreg. erhöhen
LDX #$FF ; Verzögerungsschleife
Q LDY #$30
A INY
BNE A
INX
BNE Q
JMP M ; Nächste Verschiebung

Diese Routine müssen wir nur noch in das obige Achterscrolling einbauen. Für die Basic-Fans haben wir einen Basic-Lader dieses Programms am Schluß abgedruckt. Kommen wir nun zum vertikalen Scrolling:

Im Prinzip funktioniert es wie das horizontale, es wird nur ein anderes Register benutzt.

Das Register für das vertikale Scrolling ist: 53248+17.

Für das Scrolling sind wie beim horizontalen Scrolling die Bits 0 bis 2 verantwortlich.

Einzeilen Soft-Scrolling (DATA-Lader):

TODO PRE

0 DATA173,22,208,41,7,201,7,208,6,32,34,128,76,0,
128,32,68,128,238,22,208
1 DATA162,255,160,160,200,208,253,232,208,248,76,0, H
128,173,39,4,133,251
2 DATA162,38,189,0,4,232,157,0,4,202,202,224,255, ■
208,243,165,251,141,0
3 DATA4,173,22,208,41,248,141,22,208,96,173,18,208,
201,160,48,249,201,190
4 DATA16,245,96,255
10 FOR I=32768 TO 32768+5*16
20 READA:POKEI,A
30 NEXT
40 PRINT"(CLR} HIER KOENNTE EIN TEXT STEHEN.
50 SYS32768
READY

(Frank Barcikowski + Holger Vocke/ah)
PDF Diesen Artikel als PDF herunterladen
Mastodon Diesen Artikel auf Mastodon teilen
← Vorheriger ArtikelNächster Artikel →