Magic Disk 64

home to index to html: MD9410-KURSE-IRQ-KURS_12.1.html
                IRQ-KURS                
     "Die Hardware ausgetrickst..."     
                (Teil 12)               
----------------------------------------
Herzlich Willkommen zu einer neuen Folge
unseres  IRQ-Kurses.  In  dieser Ausgabe
werden wir uns  weiter  mit  der  ESCOS-
Routine des letzten Kursteils beschäfti-
gen. Wir werden hierbei die Routine  mit
einem  Movie-Scroller  verbinden,  um so
einen   bildschirmübergreifenden    Text
scrollen  zu lassen. Dies gestaltet sich
ohne einen speziellen  Trick  gar  nicht
mal so einfach...                       
1) EINLEITUNG                           
Wie Sie sich vielleicht  noch  erinnern,
so  hatten  wir in der letzten Folge des
IRQ-Kurses zuletzt das  Beispielprogramm
"ESCOS2"  besprochen.  Diese Raster-IRQ-
Routine öffnete uns den linken und rech-
ten,  sowie den oberen und unteren Bild-
schirmrand und stellte dann alle 21  Ra-
sterzeilen  eine  neue Reihe mit je acht
Sprites auf dem Bildschirm dar.  Dadurch
hatten  wir insgesamt vierzehn Zeilen zu
je acht Sprites auf dem Bildschirm,  die
alle  nahtlos aneinandergereiht fast den
gesamten  Bildschirm  überdeckten.   Der
einzige  ungenutzte  Bereich war der von
Rasterzeile 294 bis 312,  der  zu  klein
war  um  eine  weitere Spritereihe darin
unterzubringen, aber sowieso  schon  un-
terhalb  der  für  normale Monitore dar-
stellbaren Grenze liegt.                
Der einzige Unterschied der Routine "ES-
COS2" zu "ESCOS1" bestand nun darin, daß
erstere Routine lediglich ein Zeilenoff-
set-Register  für den ersten auszulösen-
den  Raster-IRQ  herunterzählte,  um  so
einen  Scroll-Effekt der Spritereihen zu
erzielen. "ESCOS2" ist also  schon  eine
Art  "Moviescroller".  Der  Grund, warum
sie es nicht wirklich ist, liegt  darin,
daß in jeder Spritezeile dieselben Spri-
tes auf dem Bildschirm zu  sehen  waren.
Wie   wir   aber  von  den  Moviescroll-
Routinen wissen, müssen  wir  für  einen
Scrolltext das Aussehen einer Spritezei-
le ja individuell bestimmen können,  da-
mit  auch  wirklich  ein Text, und nicht
immer dieslbe Zeile, über den Bildschirm
läuft.                                  
2) DAS PROBLEM - DIE LÜSUNG             
"Kein Problem"  werden  Sie  nun  sagen,
"einfach  die Textausgaberoutine der Mo-
viescroller-Routinen vom  IRQ-Kurs  ein-
bauen, und schon haben wir einen Scroll-
text". Diese Feststellung stimmt  schon,
wie  sollte es auch anders gehen, jedoch
stellt sich uns dabei noch  ein  kleines
Problem in den Weg: dadurch nämlich, daß
wir  in  den  ESCOS-Routinen, keine Zwi-
schenräume mehr zwischen  den  einzelnen
Spritezeilen  haben,  gestaltet  es sich
als schwierig, die Sprite-Pointer  zeit-
genau  zu  setzen. Setzen wir diese näm-
lich auf die neu einzuscrollende Sprite-
zeile, noch bevor die letzte Spritezeile
abgearbeitet  wurde,  so  erscheinen die
alten  Sprites  schon  im  Aussehen  der
Neuen.  Umgekehrt können die Spritepoin-
ter auch nicht nach Abarbeiten der letz-
ten  Spritezeile  gesetzt werden da hier
ja schon die  neuen  Sprites  erscheinen
müssen.  Man  könnte  nun versuchen, ein
mega-genaues  Timing  zu  programmieren,
das  innerhalb  der  ersten  Rasterzeile
einer neuen Spritezeile exakt  vor  Dar-
stellen eines neuen Sprites dessen Poin-
ter neu setzt. Dies gestaltet  sich  je-
doch umso umständlicher, wenn wir beach-
ten müssen, daß gleichzeitig  auch  noch
der  linke und rechte Rand geöffnet wer-
den soll. Da dieser ebenfalls ein  exak-
tes  Timing verlangt, würden wir mit dem
Doppeltiming in des Teufels  Küche  kom-
men.  Aber keine Sorge: glücklicherweise
können wir als IRQ-Magier wieder in  die
Raster-Trickkiste  greifen,   und   eine
weitaus einfachere Lösung  des  Problems
anwenden.                               
Wie  Sie  z.B.  schon  von  unseren FLI-
Routinen wissen, hat man mit dem VIC die
Möglichkeit,  das  Video-RAM   innerhalb
seines  Adressbereiches von 16KB zu ver-
schieben. Der Speicherbereich,  den  der
Grafikchip dazu verwendet, um den Inhalt
des  Textbildschirms aufzubauen muß also
nicht zwingenderweise bei $0400  liegen,
wo  er  sonst  nach  dem Einschalten des
Rechners untergebracht  ist.  Durch  die
Bits 4-7 des Registers $D018 können ins-
gesamt 16 verschiedene  Speicherbereiche
gewählt  werden,  deren Basisadressen in
$0400-Schritten von  $0000-$3C00  gehen.
Nun  werden Sie fragen, was denn das Vi-
deo-RAM mit unserer ESCOS-Routine zu tun
hat, zumal wir die Bildschirmdarstellung
doch  sowieso  abgeschaltet  haben,  und
keinen  Text  auf  dem Bildschirm haben?
Nun, ganz einfach: wo befinden sich denn
die Register der Spritepointer normaler-
weise?  Natürlich  in  den  Adressen von
$07F8-$07FF.  Und  genau  diese  Adresse
liegen  am  Ende  des  Video-RAMs.  Ver-
schiebt man nun das  Video-RAM  an  eine
andere  Adresse, so verschiebt man auto-
matisch auch  die  Registeradressen  der
Spritepointer!  Wird  das Video-RAM also
beispielsweise um $0400 Bytes nach $0800
verschoben, so bewegen sich die  Sprite-
pointer-Register   ebenfalls  um  $0400-
Bytes nach vorne. Um nun also das Ausse-
hen der acht Sprites zu definieren, müs-
sen die Adressen $0BF8-$0BFF beschrieben
werden. Und genau  das  ist  die  Lösung
unseres  Problems.  Da  es  während  des
Spriteaufbaus zu lange dauert, alle acht
Spritepointer in den Akku zu  laden  und
in  die  Register zu schreiben, soll das
die Initialisierungsroutine des  Movies-
crollers  übernehmen.  Hierbei  schreibt
letztere die benötigten Werte  für  eine
Spritezeile in die Pointerregister eines
verschobenen   Video-RAMs.  Während  der
Darstellung brauchen wir  nun  nur  noch
durch  Schreiben  eines  einzigen Bytes,
nämlich des ensprechenden Wertes für ein
neues Video-RAM in $D018,  auf  selbiges
umzuschalten.  Dadurch,  daß der VIC für
die neue Spritezeile nun in  einem  ganz
anderen Video-RAM arbeitet, holt er sich
auch  die  Spritepointer  aus  den neuen
Adressen, womit wir  alle  acht  Sprite-
pointer  mit  nur  einem  Schreibzugriff
umgeschaltet hätten!                    
Die Umsetzung dieser Lösung in die  Pra-
xis gestaltet sich für uns sehr einfach.
Sinnigerweise  haben  wir nämlich in den
Routinen  "ESCOS1"  und  "ESCOS2"  schon
Platz  für  diese Änderung gelassen. Wie
Sie sich vielleicht erinnern, hatten wir
zur Darstellung  der  Sprites  innerhalb
der  IRQ-Routine dieser beiden Beispiel-
programme  die   Unterroutine   "OPEN21"
vierzehnmal  aufgerufen.  Sie wird immer
in der ersten  Rasterzeile  einer  neuen
Spritezeile  angesprungen, und übernimmt
das Neusetzen  der  Y-Koordinaten  aller
Sprites,  sowie  das Üffnen des Sidebor-
ders in den folgenden  21  Rasterzeilen.
So  sah  der  Aufruf  in den beiden Bei-
spielprogrammen aus:                    
   nop       ;Diese Befehlsfolge wird   
   jsr open21; insgesamt 14x aufgerufen 
   ...       ; um je 21 Zeilen zu öffnen
   nop       ;Sprite Line 14            
   jsr open21                           
Die "NOP"-Befehle dienten dabei nur  der
Verzögerung  um  zwei  Taktzyklen, damit
die  Änderung  zum  richtigen  Zeitpunkt
eintritt.  Wir  können diese Befehle mit
jedem anderen Befehl ersetzen, der nur 2
Takte in Anspruch nimmt. Diese  Tatsache
machen  wir  uns  für  den Moviescroller
zunutze. Wir ersetzen die NOPs mit  LDA-
Befehlen,  wobei  der  Wert,  der in den
Akku geladen wird, dem Wert  entspricht,
der in Register $D018 geschrieben werden
muß,  um  auf  das  neue Video-RAM umzu-
schalten. Er dient quasi  als  Parameter
für  die "OPEN21"-Routine. Demnach sieht
der Aufruf dieser Routine, aus  dem  Ra-
ster-IRQ heraus, nun folgendermaßen aus:
v00:lda #$00*$10 ;Code für Scr0 ($0000) 
    jsr open21   ;21 Rasterzeilen öffnen
v01:lda #$01*$10 ;Code für Scr0 ($0400) 
    jsr open21   ;21 Rasterzeilen öffnen
v02:lda #$02*$10 ;Code für Scr0 ($0800) 
    jsr open21   ;21 Rasterzeilen öffnen
    ...                                 
v0d:lda #$0d*$10 ;Code für Scr13 ($3400)
    jsr open21   ;21 Rasterzeilen öffnen
Wie  schon  in  den ESCOS-Beispielen, so
wiederholt sich auch hier  die  LDA-JSR-
Befehlsfolge  14  Mal, wobei jeweils der
nächste Video-RAM-Bereich als  Parameter
im Akku übergeben wird. Timingmässig hat
sich  nichts geändert, da der NOP-Befehl
genausolange braucht wie der LDA-Befehl.
Eine ähnliche Modifikation haben wir nun
für  das Schreiben dieses Akku-Wertes in
Register $D018 vorgenommen. Diese Aufga-
be  soll von der Routine "OPEN21" durch-
geführt werden. Hier ein Auszug der  er-
sten  Zeilen dieser Routine aus dem Bei-
spiel "ESCOS2":                         
open21:                                 
   nop         ;Verzögern bis rechter   
   nop         ; Rand erreicht          
   dec $d016   ;38 Spalten (Rand        
   inc $d016   ;40 Spalten   öffnen)    
   lda $1500,y ;$D011-Wert aus Tabelle  
   sta $d011   ; lesen und eintragen    
   iny         ;Tabellen-Index+1        
   jsr cycles+5;24 Zyklen verzögern     
   ...                                  
Wie Sie  sehen,  stehen  hier  ebenfalls
zwei  NOP-Befehle am Anfang der Routine.
Sie benötigen 4 Taktzyklen, was für  ei-
nen   "STA $XXXX"-Befehl  ebenfalls  zu-
trifft. Die zwei  NOPs  wurden  für  den
Moviescroller  nun mit einem "STA $D018"
ersetzt:                                
open21:                                 
   sta $d018   ;VRAM f.SprPtrs. versch. 
   dec $d016   ;38 Spalten (Rand        
   inc $d016   ;40 Spalten   öffnen)    
   lda $1500,y ;$D011-Wert aus Tabelle  
   sta $d011   ; lesen und eintragen    
   iny         ;Tabellen-Index+1        
   jsr cycles+5;24 Zyklen verzögern     
   ...                                  
Damit hätten wir also die  ESCOS-Routine
so  umprogrammiert, daß Sie uns in jeder
der 14 Spritezeilen  auch  neue  Sprite-
pointer  setzt.  Es müssen nun noch zwei
weitere Änderungen gemacht werden, damit
der  Movie-scroller  auch   voll   funk-
tionstüchtig ist.                       
Zunächst  einmal muß die Initialierungs-
routine erweitert werden. Sie  soll  uns
die  Spritepointer  der benutzten Video-
RAM-Adressen auf bestimmte Sprites  vor-
initialisieren,  so  daß später zur Dar-
stellung  einer  bestimmten  Spritereihe
nur  noch  die Nummer des zu benutzenden
Video-RAMs in den Labeln "V00" bis "V0D"
der Raster-IRQ-Routine (siehe oben) ein-
getragen  werden  muß,  und  die Routine
somit automatisch  den  richtigen  Bild-
schirm  zur  korrekten  Darstellung  der
entsprechenden    Spritezeile     wählt.
Zunächst  einmal wollen wir vereinbaren,
daß wir den 16K-Adressbereich  des  VICs
von $0000-$3FFF um eins nach oben in den
Bereich   von  $4000-$7FFF  verschieben.
Dadurch stört uns die Zeropage, die nor-
malerweise  ja  auch im Bereich des VICs
liegt, nicht mehr, und wir  haben  volle
16KB  zur  Speicherung  von  Sprites und
Spritepointer-Video-RAM  zur  Verfügung.
Die  Verschiebung  wird  durch Schreiben
des Wertes 2 in das Portregister  A  von
CIA-B  erreicht.  Innerhalb der Initial-
sierung wurde also  folgende  Befehlsse-
quenz hinzugefügt:                      
LDA #$02                                
STA $DD00                               
Damit befindet sich der Datenbereich für
den VIC nun im Bereich von  $4000-$7FFF.
Beachten  Sie  bitte  auch,  daß nun der
Bytewert, den der  VIC  in  "ausgetrick-
sten" Rasterzeilen darstellt, nicht mehr
in $3FFF, sondern in $7FFF abgelegt wer-
den muß (im Beispielprogramm enthält  er
den  Wert  $81,  womit vertikale Lininen
hinter dem Scrolltext  erscheinen).  Nun
folgt  der  Teil,  der die Spritepointer
setzt. Hier treffen wir die  Konvention,
daß  die  Sprites, die durch die Pointer
einer   Video-RAM-Bereichs   dargestellt
werden  auch innerhalb dieses Video-RAMs
unterbracht werden sollen. Liegt  dieses
also  Beispielsweise  bei $4400, so soll
Spritepointer 0 auf das Sprite bei $4400
(Blocknr. 16), Spritepointer 1  auf  das
Sprite  bei  $4440  (Blocknr. 17), usw.,
zeigen. Dies bewerkstelligt nun der fol-
gende Teil der Init-Routine:            
   lda #$f8       ;ZP-Zgr. $02/03 mit   
   sta $02        ; $43F8 init.         
   lda #$43                             
   sta $03                              
   lda #($0000/64);Ptr. f. Sprite-Line01
   jsr setpoint   ; setzen              
   lda #($0400/64);Ptr. f. Sprite-Line02
   jsr setpoint   ; setzen              
   lda #($0800/64);Ptr. f. Sprite-Line03
   jsr setpoint   ; setzen              
   ...                                  
   lda #($3000/64);Ptr. f. Sprite Line13
   jsr setpoint   ; setzen              
   lda #($3400/64);Ptr. f. Sprite Line14
   jsr setpoint   ; setzen              
Wie Sie sehen wird lediglich ein  Adres-
sierungszeiger in der Zeropage initiali-
siert, und dann 14 Mal die  Unterroutine
"SETPOINT" aufgerufen, wobei im Akku der
Inhalt  für  den  jeweils ersten Sprite-
pointer übergeben  wird.  Hier  nun  die
Routine "SETPOINT", die die eigentlichen
Werte in die Pointerregister schreibt:  
SETPOINT:                               
   ldy #$00   ;Index-Reg. init.         
   sta ($02),y;SprPtr0 ablegen          
   clc        ;Akku=Akku+1              
   adc #$01                             
   iny        ;Index=Index+1            
   sta ($02),y;SprPtr1 ablegen          
   clc        ;Akku=Akku+1              
   adc #$01                             
   iny        ;Index=Index+1            
   sta ($02),y;SprPtr2 ablegen          
   ...                                  
   clc        ;Akku=Akku+1              
   adc #$01                             
   iny        ;Index=Index+1            
   sta ($02),y;SprPtr7 ablegen          
   clc        ;Auf Hi-Byte des $02/$03  
   lda $03    ; Zeigers den Wert 4 add. 
   adc #$04   ; um auf nächstes VRAM zu 
   sta $03    ; positonieren            
   rts                                  
Wie Sie sehen, so wird vom Basiswert des
ersten Spritepointers an, acht  Mal  je-
weils um eins hochgezählt und das Ergeb-
nis über den Vektor bei $02/$03  in  die
entsprechende     Sprite-Pointer-Adresse
geschrieben. Beim ersten Durchlauf zeigt
dieser Vektor auf Adresse $43F8, wo sich
die Spritepointer des ersten  Video-RAM-
Bereichs  befinden. Am Ende der Pointer-
initialisierung wird  die  Vektoradresse
nun  um  $0400  erhöht (auf Hi-Byte wird
$04 addiert), damit beim nächsten Durch-
lauf  die Zeiger des nächsten Video-RAM-
Bereichs gesetzt werden.                
 (Anm.d.Red.: Bitte wählen Sie jetzt den
   zweiten Teil des IRQ-Kurses aus dem  
                Textmenu)               
Valid HTML 4.0 Transitional Valid CSS!