Magic Disk 64

home to index to html: MD9412-KURSE-IRQ-KURS_14.html
                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)
Valid HTML 4.0 Transitional Valid CSS!