IRQ-KURS
"Die Hardware ausgetrickst..."
(Teil 14)
----------------------------------------
Unser Kurs neigt sich langsam dem Ende
zu, und als wahre "Raster-Feinschmecker"
haben wir uns das beste Stückchen Code
ganz für den Schluß aufgehoben. In die-
sem und den nächsten beiden (letzten)
Kursteilen werden wir uns mit Raster-
Tricks beschäftigen, die es uns ermögli-
chen, den Bildschirm des C64 HARDWA-
REMÄSSIG in alle Richtungen zu scrollen.
"Hardwaremässig" heißt, daß wir nicht
etwa die Softscroll-Register des VICs
beschreiben, und dann alle 8 Scollzei-
len/-spalten den gesamten Bildschirm um
8 Pixel (oder einen Charakter) weiterko-
pieren, sondern daß wir vielmehr den VIC
derart austricksen, daß er uns diese
Arbeit von alleine abnimmt, und zwar
ohne, daß wir auch nur einen einzigen
Taktzyklus zum Kopieren von Grafikdaten
verschwenden müssen! Die hierzu notwen-
digen Routinen heißen "VSP", zum verti-
kalen Scrollen, "HSP", zum horizontalen
Scrollen, sowie "AGSP", die eine Kombi-
nation Kombination aus den beiden erste-
ren dartsellt. Mit ihnen können wir den
gesamten Bildschirm ganz problemlos
(auch Hires-Grafiken!) in alle Richtun-
gen verschieben. Im heutigen Kursteil
wollen wir mit der VSP-Routine beginnen:
1) FLD UND VSP - DIE (UN)GLEICHEN BRÜDER
Sie werden sich jetzt sicher wundern,
warum hier der Begriff "FLD", auftaucht,
war das doch eine der "einfacheren" Rou-
tinen, die wir schon zu Anfang dieses
Kurses besprochen hatten. Doch wie ich
schon öfter erwähnte, ist die FLD-
Routine meist der Schlüssel zu den kom-
pexeren Rastertricks, und leistete uns
auch schon manchen guten Dienst um Ti-
mingprobleme extrem zu vereinfachen.
Diesmal jedoch dreht sich alles direkt
um unseren kleinen Helfershelfer, da die
VSP-Routine sehr stark mit ihm verwandt
ist, wenn die Beiden nicht sogar iden-
tisch sind. "VSP" steht für "Vertical
Screen Position", was der einfach Aus-
druck für das ist, was die Routine be-
wirkt: durch sie wird es uns ermöglicht,
den gesamten Bildschirm ohne jeglichen
Kopieraufwand vollkommen frei nach oben
oder unten zu scrollen. Und jetzt der
Clou an der ganzen Sache: FLD und VSP
unterscheiden sich lediglich durch einen
einzigen NOP-Befehl voneinander. Fügt
man Letzterern den Verzögerungs-NOPs
nach der IRQ-Glättung der FLD-Routine
hinzu, so erhält man eine voll funk-
tionstüchtige VSP-Routine, die gleich-
zeitig noch einen FLD-Effekt miteinge-
baut hat. Damit Sie genau wissen, wovon
wir hier sprechen, sollten Sie sich auf
dieser MD einmal die Programmbeispiele
"FLD" und "VSP1" anschauen. Ersteres ist
die FLD-Routine, so wie wir sie zu Be-
ginn dieses Kurses kennengelernt hatten.
Durch Bewegen des Joysticks nach oben
und unten können wir mit ihr den Bild-
schirm nach unten "wegdrücken". Das
Prinzip, das dabei verfolgt wurde war,
daß die FLD-Routine den Beginn der näch-
sten Charakterzeile vor dem Rasterstrahl
herschob, indem sie ihn ständig mit
neuen vertikalen Verschiebeoffsets in
Register $D011 fütterte. Da er deshalb
glaubte, sich noch nicht in der richti-
gen Rasterzeile zu befinden, in der er
die nächste Charakterzeile zu lesen hat-
te, "vergaß" er solange sie zu zeichnen,
bis wir ihm durch Beenden der FLD-
Schleife die Möglichkeit dazu gaben,
endlich die Rasterzeile zu erreichen, in
der er nun tatsächlich die versäumte
Charakterzeile lesen und anzeigen durf-
te. Egal, wieviele Rasterzeilen wir ihn
dadurch "vertrödeln" ließen, er begann
dann immer bei der Charakterzeile, die
er eigentlich als nächstes aufzubauen
gehabt hätte, so als wenn der FLD-Effekt
nie aufgetreten wäre. War das die erste
Charakterzeile des Bildschirms, so konn-
te man auch problemlos den Bildschirm
erst in der Mitte oder am unteren Bild-
schirmrand beginnen lassen (so arbeitet
übrigens auch der Effekt, mit dem Sie
die Seiten, die Sie gerade lesen umblät-
tern).
2) DAS PROGRAMMBEISPIEL VSP1
Wollen wir uns nun einmal die IRQ-
Routine des Programmbeispiels "VSP1"
anschauen. Im Prinzip nichts besonderes,
da sie, wie schon erwähnt, fast iden-
tisch mit der FLD-Routine ist. Sie ist
ab Adresse $1100 zu finden und wird wie
die meisten unserer IRQ-Routinen von der
Border-IRQ-Routine, die wir immer zum
Abschalten des unteren und oberen Bild-
randes benutzen initialisiert:
fld pha ;Prozessorregs.
txa ; auf Stapel retten
pha
tya
pha
dec $d019 ;VIC-ICR löschen
inc $d012 ;Glättungs-IRQ
lda #<irq2 ; vorbereitem
sta $fffe
cli ;IRQs freigeben
ch nop ;Insgesamt 13 NOPs
... ; zum Verzögern bis
nop ; zum nächsten
jmp ch ; Raster-IRQ
irq2 pla ;Statusreg. u.
pla ; IRQ-Adr. vom
pla ; Stapel werfen
dec $d019 ;VIC-ICR freigeben
lda #$f8 ;Rasterpos. f. Bor-
sta $d012 ; der IRQ festlegen
ldx #<bord ;IRQ-Vektoren
ldy #>bord ; auf Border-IRQ
stx $fffe ; zurücksetzen (für
sty $ffff ; nächst. Durchlauf)
nop ;Verzögern bis
nop ; zum Raster-
nop ; zeilenende
nop
nop
nop
nop
lda $d012 ;den letzen Cyclus
cmp $d012 ;korrigieren
bne onecycle
onecycle lda #$18 ;25-Zeilen-Bildschirm
sta $d011; einschalten
nop ;Insgesamt 16 NOPs zum
... ;Verzögern für FLD
Es folgt nun der alles entscheindende
siebzehnte NOP-Befehl, der den VSP-
Effekt auslöst:
nop ;NOP für VSP
Nun gehts weiter mit dem normalen FLD-
Code. Entfernen Sie das obige NOP aus
dem Code, so erhalten Sie wieder eine
ganz normale FLD-Routine!
lda $02 ;Zeilenz. holen
beq fldend ;Wenn 0 -> Ende
ldx #$00 ;Zeiger init.
fldloop lda rollvsp,x ;FLD-Offs. zum
ora #$18 ;Verschieben d.
sta $d011 ; Charakterz.
lda colors1,x ;Blaue Raster
sta $d020 ; im FLD-Be-
sta $d021 ; reich darst.
nop ;Bis Zeilen-
nop ; mitte verzö-
nop ; gern
nop
nop
nop
nop
lda colors2,x ;Rote Raster
sta $d020 ; Im FLD-Be-
sta $d021 ; reich darst.
nop ;Verzögern bis
nop ; Zeilenende
bit $ea
inx ;Zeilenz.+1
cpx $02 ;Mit $02 vgl.
bcc fldloop ;ungl.->weiter
fldend nop ;Verz. bis
nop ; Zeilenende
nop
nop
nop
lda #$0e ;Normale
sta $d020 ; Bildschirm-
lda #$06 ; farben ein-
sta $d021 ; schalten
pla ;Prozessorregs.
tay ; zurückholen
pla
tax
pla
rti ; und ENDE
Die Tabelle "ROLLVSP" enthält Soft-
scroll-Werte für Register $D011 (nur die
untersten 3 Bit sind genutzt), die die
vertikale Verschiebung immer um eine
Rasterzeile vor dem Rasterstrahl her-
schieben, so daß der FLD-Effekt entste-
hen kann.
Die Tabellen "Color1" und "Color2" geben
die Farben an, die die FLD-Routine im
weggedrückten FLD-Bereich darstellt.
Dies ist nur als "Verschönerung" neben-
bei gedacht.
3) DAS FUNKTIONPRINZIP VON VSP
Intern kann man sich die Vorgehensweise
des VIC beim Aufbauen des Bildschirms
mit all seinen Rasterzeilen folgenderma-
ßen vorstellen: Trifft unser armer Gra-
fikchip auf eine Rasterzeile, in der
eigentlich die nächste Charakterzeile
erscheinen sollte, so bereitet er sich
auf den gleich folgenden Zugriff auf das
Video-RAM vor, und zählt schon einmal
einen internen Adresszeiger auf die
gewünschte Adresse um 40 Zeichen nach
oben, um die folgenden 40 Bytes recht-
zeitig lesen zu können. Nun vergleicht
er die Rasterstrahlposition ständig mit
seiner Startposition für den Lesevorgang
und hält beim Erreichen von Selbiger den
Prozessor für 42 Taktzyklen an, um sei-
nen Lesezugriff durchzuführen. Durch die
FLD-Routine wurde nun jedoch der Beginn
der gesamten Charakterzeile ständig vor
dem VIC hergeschoben, weswegen er sie
auch schön brav erst später zeichnete.
Unsere VSP-Routine verfügt nun über ei-
nen einzigen NOP mehr, der hinter der
IRQ-Glättung eingefügt wurde. Das bedeu-
tet, daß der FLD-Schreibzugriff auf Re-
gister $D011, mit dem der vertikale Ver-
schiebeoffset um eins erhöht wird, exakt
2 Taktzyklen später eintritt als sonst.
In genau diesen beiden Taktzyklen aber
hat der VIC schon die interne Adresse
auf das Video-RAM um 40 Zeichen erhöht
und wartet jetzt auf das Erreichen der
Startposition für den Lesevorgang. Da
der in unserem Programm folgende
Schreibzugriff auf $D011 diese Position
für den VIC nun aber eine Rasterzeile
weiterschiebt, kann er diese Position
nie erreichen. Das Endergebnis, das wir
dadurch erhalten ist Folgendes:
* Der FLD-Effekt greift, und wir lassen
den VIC die nächste Charakterzeile
eine Rasterzeile später zeichnen.
* Der interne Adresszeiger des VIC auf
die Daten der nächsten Charakterzeile
wurde um 40 Zeichen (also eine Charak-
terzeile) erhöht.
* Da der VIC beim Erreichen der nächsten
Rasterzeile wieder glaubt, er müsse
sich auf die Charakterzeile vorberei-
ten, zählt er den internen Adresszei-
ger um weitere 40 Bytes nach oben und
wartet auf die richtige Startposition
zum Lesen der nächsten 40 Bytes.
* Lassen wir ihn nun tatsächlich die
Charakterzeile lesen, indem wir die
FLD(VSP)-Routine beenden, so stellt er
zwar, wie beim normalen FLD-Effekt,
wieder Charakterzeilen dar, jedoch
wurde durch das zweimalige Erhöhen des
Adresszeigers um 40 Bytes eine gesamte
Charakterzeile übersprungen! Hatten
wir den FLD-Effekt also z.B. vor Er-
reichen der ersten Charakterzeile ein-
setzen lassen, so zeichnet der VIC nun
nicht die erste, sondern die ZWEITE
Charakterzeile, da er sich ja 40 Bytes
zu weit nach vorne bewegte!!! Die er-
ste Charakterzeile wurde somit ÖBER-
SPRUNGEN!
Im Klartext bedeutet das: für jede Ra-
sterzeile, die wir die FLD(VSP)-Routine
länger laufen lassen, überspringt der
VIC eine Charakterzeile. Auf diese Weise
können wir also auch die Daten, die in
der Mitte des Video-RAMs liegen am An-
fang des Bildschirms anzeigen lassen.
Der VIC liest nun aber pro Rasterdurch-
lauf immer 25 Charakterzeilen. Lassen
wir ihn also durch unseren VSP-Trick 40
Bytes zu spät auf die vermeintliche 1.
Charakterzeile zugreifen (es handelt
sich um die 1. Charakterzeile die auf
dem Bildschirm zu sehen ist, jedoch mit
den Daten, die eigentlich erst in der
zweiten Charakterzeile des Bildschirms
erscheinen sollten), so hört für ihn der
Bildschirm auch 40 Bytes zu spät auf.
Das Ergebnis: in der 25. Bildschirmzeile
liest und stellt der VIC die Daten des
sonst ungenutzten Bereichs des Video-
RAMs im Adressbereich von $07E8 bis
$07FF dar (wenn wir von der Stanard-
Basisadresse des Video-RAMs bei $0400
ausgehen). Dies sind 24 Zeichen, die
somit am Anfang der letzten Bildschirm-
zeile zu sehen sind. Hieraufhin folgen
16 weitere Zeichen, die sich der VIC
wieder aus der Anfangsadresse des Video-
RAMs holt.
Zum besseren Verständnis sollten wir
vielleicht noch klären, wie der VIC auf
das Video-RAM zugreift. Selbiges ist
immer 1024 Bytes (also exakt 1KB) lang,
obwohl der Bildschirm nur 1000 Bytes
groß ist und somit die letzten 24 Bytes
nie sichtbar werden. Wie Sie nun wissen,
kann der VIC immer nur 16KB der 64KB des
C64 adresssieren, wobei die Lage dieses
Bereichs allerdings auch verschoben wer-
den kann. Das heißt also, daß der VIC
insgesamt zwar Adressen in einem 64KB-
Raum (16 Adressbits sind hierzu notwen-
dig) adressieren, aber gleichzeitig im-
mer nur auf 16KB für Grafikdaten zugrei-
fen kann. Möchte man diesen 16KB-Bereich
verschieben, so kann das mit den unter-
sten zwei Bits von Adresse $DD00 getan
werden. Im Normalfall stehen beide auf 0
und lassen den VIC deshalb im Bereich
von $0000 bis $3FFF arbeiten. Diese
Adressen dienen als Basis für den VIC
die ihm von der NMI-CIA in die obersten
zwei Adressbits für seine RAM-Zugriffe
eingeblendet werden. Die Zugriffsadresse
ist also 16 Bit groß, wobei die beiden
Bits 0 und 1 aus $DD00 immer in den
obersten zwei Bits (14 und 15) erschei-
nen. Die Bits 10-13 dieser Adresse be-
stimmen die Basisadresse des Video-RAMs.
Sie werden von den Bits 4-7 der VIC-
Adresse $D018 geliefert. Steht hier der
Bitcode $0001 (so wie nach Einschalten
des Computers), so wird also zusammen
mit den Bits aus $DD00 die Adresse $0400
angesprochen, die im Normalfall die Ba-
sisadresse für das Video-RAM ist. Die
restlichen, zur Adressierung benötigten
10 Bits kommen aus dem oben schon
erwähnten, VIC-internen Adresszähler. Er
ist exakt 10 Bits lang, womit maximal
1KB-Bereiche adressiert werden können.
Dadurch erklärt sich auch, warum der VIC
durch austricksen mit der VSP-Routine,
in der letzten Zeile die 24 sonst unge-
nutzten Zeichen des Video-RAMs dar-
stellt: Da der 10-Bit-Zähler nun auf den
Offset $03E8 zeigt, werden von dort auch
die Daten gelesen. Hierbei findet dann
aber nach dem 24. Byte ein Öberlauf des
10-Bit-Zählers statt, womit selbiger
wieder auf 0 zurückspringt und wieder
den Anfang des Video-RAMs adressiert.
Dadurch erklärt sich auch, warum in der
letzten Bildschirmzeile nach den Zeichen
aus $07E8-$07FF wieder die Zeichen ab
Adresse $0400 erscheinen.
Bleibt noch zu erwähnen, daß dasselbe
für das Color-RAM bei $D800 gilt. Dies
ist immer an einer Fixadresse, wobei die
untersten 10 Bit ebenfalls aus dem Cha-
rakterzeilen-Adresszähler kommen. Das
heißt also, daß die 24 sonst unsichtba-
ren Zeichen ihre Farbe aus dem ebenfalls
sonst ungenutzten Color-RAM-Bereich von
$DBE8-$DBFF erhalten.
5) PROBLEME DIE BEI VSP ENTSTEHEN KÖNNEN
Die Nachteile, die durch die Charakter-
verschiebung entstehen, sollten auch
nicht unerwähnt bleiben:
Durch die Verschiebung der Video-RAM-
Daten am Ende des Bildschirms um 24 Zei-
chen nach rechts, ist natürlich auch die
gesamte Grafik in zwei Teile zerlegt
worden, weswegen ein Scroller nicht ganz
so einfach durchzuführen ist. Um diesen
Fehler auszugleichen müssen wir einen
zweiten Video-RAM-Bereich verwalten, in
dem die gesamte Grafik um 24 Zeichen
versetzt abgelegt sein muß. In diesem
Video-RAM sind dann die ersten 24 Zei-
chen ungenutzt. Durch einen stinknorma-
len Rasterinterrupt können wir dann pro-
blemlos vor Beginn der Charakterzeile,
an der der VIC-Adresszeiger überläuft,
auf das zweite Video-RAM umschalten,
wobei dieses dann zwar an der überlau-
fenden Adresse ausgelesen wird, was je-
doch durch unsere Verschiebung wieder
ausgeglichen wird.
Ein weiterer Nachteil, der bei VSP ent-
steht, liegt auf der Hand: Die letzten
acht Bytes des jetzt sichtbaren Video-
RAMs sind die Adressen, in denen die
Spritepointer abgelegt werden. Das heißt
also, daß wir beim gleichzeitigen Anzei-
gen von Grafikzeichen in diesen acht
Bytes mit der Spriteanzeige Probleme
bekomen. Jedoch auch dies ist zu bewäl-
tigen. Entweder, indem man so geschickt
arbeitet, daß in diesen Bereichen auf
dem Bildschirm nur Zeichen in der Hin-
tergrundfarbe zu sehen sind (bei schwar-
zem Hintergrund einfach das Color-RAM in
den Adressen von $DBF0-$DBFF ebenfalls
auf schwarz setzen). Oder aber indem wir
in diesen Zeichen immer nur dann die
eigentlichen Video-RAM-Werte eintragen,
wenn sie ausgerechnet vom VIC benötigt
werden (also auch exakt vor dem Lesen
der Öberlauf-Charakterzeile), und an-
sonsten die Spritepointer hineinschrei-
ben. Da der VIC schon 42 Taktzyklen nach
Beginn der Rasterzeile, in der die Cha-
rakterzeile beginnen soll, die Video-
RAM-Daten gelesen hat, können wir also
getrost wieder die Spritepointer zurück-
schreiben und haben so lediglich eine
einzige Rasterzeile, in der die Sprites
garnicht (oder nur verstümmelt) darge-
stellt werden können.
Soll der gesamte Bildschirm einmal
durchgescrollt werden können, so muß
davon ausgegangen werden, daß maximal 25
Rasterzeilen am Beginn des Bildschirms
ungenutzt bleiben müssen, da in Ihnen
das Timing für den VSP-Effekt unter-
bracht werden muß. Da pro Rasterzeile
der interne Adresspointer um eine Cha-
rakterzeile weitergezählt wird, muß also
im Maximalfall in 25 Rasterzeilen der
VSP-Effekt eingesetzt werden. Will man
den Bildschirm nun konstant an eine be-
stimmten Position beginnen lassen, so
muß nach der Anzahl der zu überspringen-
den Charakterzeilen wieder eine normale
FLD-Routine (ohne das zusätzlich NOP)
benutzt werden, um bis zur 25. Raster-
zeile nach Bildschirmanfang zu verzö-
gern, OHNE daß gleich alle 25 Charakter-
zeilen übersprungen werden.
6) WEITERE PROGRAMMBEISPIELE
Ausser der oben schon erwähnten "VSP1"-
Routine finden Sie auf dieser MD auch
noch zwei weitere Beispielprogramme, mit
den Namen "VSP2" und "VSP3" (wie alle
unserer Beispiele werden auch sie mit
"SYS4096" startet). In Ersterem haben
wir zusätzlich zum VSP-Effekt die unte-
ren drei Bits von $D011 zum Soft-
scrollen des Bildschirms verwendet, so
daß der Bildschirm weich nach oben und
unten geschoben werden kann. Die Routine
"VSP3" scrollt das gesamte Video-RAM
ununterbrochen durch, wodurch quasi ein
unendlicher Horizontalscroller durch-
geführt werden kann. Die 25 unbenutzten
Rasterzeilen am Bildschirmanfang, die
für das VSP-Timing benötigt werden, sind
mit Sprites hinterlegt, in denen man
z.B. in einem Spiel auch ein Scoreboard
unterbringen kann.
In der nächsten Folge des IRQ-Kurses
werden wir uns den horizonalen Hardwa-
rescroller "HSP" anschauen, bei dem das
VSP-Prinzip auf die Horizontale Bild-
schirmposition umgesetzt wurde. (ih/ub)