Magic Disk 64

home to index to html: MD9007-KURSE-INTERRUPTKURS_TEIL_2.html
MD9007-KURSE-INTERRUPTKURS_TEIL_2.koala.png
         DEN C64'er AUSGEREIZT  (Teil 2)
             INTERRUPTKURS              
             -------------              
 Lassen  Sie  uns das Wichtigste aus dem
ersten Teil des Kurses zusammenfassen.  
a)  Als erste  Unterbrechungsanforderung
   ist der Assemblerbefehl  BRK  ganannt
   worden.Trifft der Prozessor auf solch
   einen Befehl, dann wird indirekt über
   die Adressen  $0316 und $0317 ins Un-
   terbrechungsprogramm gesprungen.     
b)  Als  zweite  Interrupt-Quelle wurden
   die beiden CIAs genannt.             
   Ist IRQ-TIMER  ($DC00)  auf Interrupt
   programmiert, dann wird indirekt über
   die Adressen $0314/$0315 vezweigt.   
c)  Der NMI-TIMER  ($DD00) wird auch als
   Zwilling  des  IRQ-TIMERS  bezeichnet
   und  läßt  sich  auch auf die gleiche
   Weise programmieren.  Der Unterschied
   besteht in der Art des Interrups.    
               IRQ und NMI              
               -----------              
 Zu guter Letzt soll noch geklärt werden
was hinter diesen  unterschiedlichen Be-
griffen steckt.                         
IRQ (Interrupt ReQuest)                 
 Dies ist  ein  sogenannter maskierbarer
Interrupt.Maskierbar heißt,daß per Soft-
ware gesagt werden kann, ob er ausgelöst
werden darf oder nicht.   Das Abschalten
erfogt durch den Assemblerbefehl SEI und
das Einschalten durch CLI.              
NMI (Non Maskable Interrupt)            
Dieser Interrupt ist softwaremäßig nicht
abschaltbar. Ein NMI-Interrupt wird aus-
gelöst, durch Drücken der  RESTORE-Taste
oder durch den NMI-TIMER ($DD00).       
 In beiden Fällen wird indirekt über die
Adressen $0318 und $0319 gesprungen.    
           Der VIDEO-INTERRUPT          
           -------------------          
 Ein Interrupt kann aber auch durch  an-
dere  Ereignisse  als  durch  den Ablauf
eines Timers ausgelöst werden.          
     z.B. LIGHTPEN                      
          SPRITE-SPRITE-KOLLISION       
          SPRITE-HINTERGUND KOLLISION   
          RASTERZEILENINTERRUPT         
 Die ersten drei  Interrupts  sollen uns
hier  nicht  weiter  interessieren.  Den
RASTERINTERRUPT dagegen, könnte man ohne
Übertreibung   als  ein  Reservoir uner-
schöpflicher Möglichkeiten bezeichnen.  
 Wer die zahlreichen neuen Entwicklungen
und Entdeckungen auf dem  Softwaresektor
seit 1985 mitverfolgt hat, der kann sich
vorstellen wovon die Rede ist.          
 Ich denke dabei besonders an die vielen
Demos die seit Jahren den  Public-Domain
Markt unsicher machen.                  
 Einige  dieser  Werke sorgten sogar für
weltweites  Aufsehen.  Man  denke nur an
das  allgemeine  Erstaunen, daß ein DEMO
der 1001 CREW seinerzeit auslöste.   Zum
aller ersten Mal,  seit der  Herstellung
des  C64'er,  hatte es jemand geschafft,
den  Bildschirmrand durch einen program-
miertechnischen Trick auszuschalten  und
Graphiken auf der gesamten   Bildschirm-
fläche  darzustellen.  Diese  Entdeckung
löste eine einzigartige   Experimentier-
welle unter den Freaks aus,    denn  mit
einem Schlag wurde klar,  daß der C64'er
doch etwas mehr zu bieten hatte, als aus
dem mageren Handbuch ersichtlich war. Es
gab zu der Zeit aber  auch  noch  andere
Programmierer(gruppen) wie die 1001CREW,
die mit ihren Werken einen  respektablen
Bekanntheitsgrad erreichten.  Hierzu ge-
hörten schillernde Gestallten wie FLASH,
S0DAN,  THE JUDGES,  THE CREAM CRACKERS,
WOM, STAR FRONTIERS und MEANTEAM.       
 Heutzutage  sind  es  eher  Gruppen wie
HORIZON,  UPFRONT und  BEYOND FORCE, die
versuchen  durch eine immer raffinierter
werdende Ausnutzung der Interrupttechnik
an die Grenzen des guten alten C64'er zu
stoßen. Und  was  da  auf den Bildschirm
gezaubert wird,  stellt  manchmal  sogar
AMIGA und ST in den Schatten.           
 Einige der Routinen,  die den erwähnten
Gruppen  zu  Ruhm  und  Ehre  verhalfen,
werden in dieser und  weiteren  Ausgaben
vorgestellt.      Doch bevor wir uns auf
die  Programmierung  von   komplizierten
Routinen stürzen,wollen wir anhand eines
einfachen Beispiels  die  Funktionsweise
der Raster-Unterbrechung erläutern.     
           DER RASTER-INTERRUPT         
           --------------------         
 Wie Sie vieleicht wissen, wird das Bild
auf dem Monitor oder dem Fernseher durch
einen Elektronenstrahl erzeugt, der  mit
hoher  Geschwindigkeit  Rasterzeile  für
Rasterzeile abarbeitet.   Ohne an dieser
Stelle  allzusehr  in technische Einzel-
heiten einzugehen, soll hier nur erwähnt
werden, das sich der gesamte  Bildschirm
aus 312 Rasterzeilen zusammensetzt.  Von
disen  312  Rasterzeilen  bilden 200 das
Textfenster. Die restlichen 112 befinden
sich im  Rand oder unterhalb des Randes.
Zwei Register des Video-Chips stehen mit
dem Elektronenstrahl in direkter Verbin-
dung:                                   
                  $D011                 
                  $D012                 
Es ist nun so, daß diese beiden Register
eine DOPPELFUNKTION haben:              
 a)Werden sie ausgelesen,  dann erhällt 
   man die aktuelle Rasterzeile, die ge-
   rade aufgebaut wird.                 
 b)Wird ein Wert hineingeschrieben, dann
   ist  die  so  festgelegte Rasterzeile
   der Auslöser des  IRQ.  Bei $D011 ist
   nur Bit 7 von Bedeutung.    Es stellt
   Hi-Byte des Rasterstrahls dar.       
 In dem folgenden Programm,  wird gleich
an  drei verschiedenen Stellen des Bild-
schirms ein Rasterinterrupt ausgelöst.  
;***          RASTER-DEMO 1          ***
;*****       Initialisierung       *****
1000 SEI         ;IRQ sperren           
1001 LDA #$7F    ;Timer-Interrupt       
1003 STA $DC0D   ;abschalten!!!         
1006 LDA $DC0D   ;ICR löschen           
1009 LDA #$00    ;Rasterzeile $00 als   
100B STA $d012   ;IRQ-Auslöser festlegen
100E LDA $D011   ;Bit 7 (Hi-Position)   
1011 AND #$7F    ;löschen               
1013 STA $D011                          
1016 LDA #$01    ;Raster als IRQ-Quelle 
1018 STA $D01A   ;wählen                
101B LDX #$27    ;IRQ-Vektor auf        
101D LDY #$10    ;Interrupt Routine Nr.1
101F STX $0314   ;richten               
1022 STY $0315                          
1025 CLI         ;IRQ freigeben         
1026 RTS                                
;*****      ERSTER INTERRUPT       *****
1027 LDA #$70    ;RASTERZEILE $70 als   
1029 STA $D012   ;IRQ-Auslöser festlegen
102c DEC $D019   ;IRR Register löschen  
102F LDX #$44    ;IRQ-Vektor auf        
1031 LDY #$10    ;RASTER-Routine Nr.2   
1033 STX $0314   ;richten               
1036 STY $0315                          
1039 LDA #$00    ;Rahmen- und           
103B STA $D020   ;Hintergrundfarbe      
103E STA $D021   ;auf schwarz setzen    
1041 JMP $FEBC   ;Return from Interrupt 
;*****      ZWEITER INTERRUPT      *****
1044 LDA #$C0    ;RASTERZELE $c0 als    
1046 STA $D012   ;IRQ-Auslöser festlegen
1049 DEC $D019   ;IRR Register löschen  
104C LDX #$61    ;IRQ-Vektor auf        
104E LDY #$10    ;RASTER-Routine Nr.3   
1050 STX $0314   ;richten               
1053 STY $0315                          
1056 LDA #$02    ;Rahmen- und           
1058 STA $D020   ;Hintergrundfarbe      
105B STA $D021   ;auf rot setzen        
105E JMP $FEBC   ;Return from Interrupt 
;*****      DRITTER INTERRUPT      *****
1061 LDA #$00    ;RASTERZEILE $00 als   
1063 STA $D012   ;IRQ-Auslöser festlegen
1066 DEC $D019   ;IRR Register löschen  
1069 LDX #$27    ;IRQ-Vektor auf        
106B LDY #$10    ;RASTER-Routine Nr.1   
106D STX $0314   ;richten               
1070 STY $0315                          
1073 LDA #$07    ;Rahmen- und           
1075 STA $D020   ;Hintergrundfarbe      
1078 STA $D021   ;auf gelb setzen       
107B JMP $EA31   ;Return from Interrupt 
 Sobald Sie das Programm mit  'SYS 4096'
starten, lösen die Rasterzeilen $00, $70
und $c0 fortlaufend Interrupte aus.     
 Da jeder  Interrupt  dazu benutzt wird,
Rahmen- und  Hintergrundfarbe zu ändern,
entsteht ein  Effekt,   der eine gewisse
Ähnlichkeit mit der deutschen Fahne hat.
 Gleich  zu  Beginn  der Initialisierung
wird der Interrupt gesperrt(SEI) und der
TIMER-IRQ abgeschaltet.                 
 Als nächstes müssen wir festlegen,  daß
RASTERZELE $00 Auslöser des erster Inte-
rupts ist. Zu diesem Zweck  schreibt man
den Wert $0 in $d012 und löscht BIT 7 in
$D011. Dieses BIT stellt die Hi-Position
des  Rasterstrahls  dar und muß nur dann
gesetzt werden, falls der  IRQ  irgendwo
im untern Rand ausgelöst werden soll.   
  Durch Löschen oder Setzen der BITS des
Registers $D01A wird festgelegt, welches
Ereignis  IRQ-Auslöser  sein soll.      
 BIT 0   ;RASTERINTERRUPT        ($D012)
 BIT 1   ;SPRITE-HINTERGR.Koll.  ($D01F)
 BIT 2   ;SPRITE-SPRITE Koll.    ($D01E)
 BIT 3   ;LIGHTPEN sendet Impuls        
 Da wir uns für eine Unterbrechung durch
den Rasterstrahl entschieden haben,  muß
der Wert $1 in $D01A geschrieben werden.
 Zu guter Letzt müssen wir wieder einmal
den IRQ-Vektor $0314/0315 umstellen.    
 Nun müssen wir aber aufpassen, denn die
gleichen Adressen werden auch vom TIMER-
IRQ als Sprungvektoren benutzt.   Hätten
wir den Timer-IRQ nicht abgestellt,   so
würden beide Interrupts abwechselnd  und
völlig unkontrolliert  dieselbe  Routine
anspingen. Das Ergebnis wäre ein totales
Durcheinander,gefolgt von einem Absturz.
 Damit  wären  fast  alle Vorbereitungen
getroffen.   Der Rest liegt nun ganz bei
unserer IRQ-Routine die an Adresse $1027
beginnt.                                
 Sobald der Elektronenstrahl mit Raster-
zeile $00 in  Berührung  kommt, wird der
erste  Interrupt  ausgelöst und die  CPU
führt das Programm an Adresse $1027 aus.
 Die folgende Beschreibung gilt für alle
Routinen die durch einen RASTERINTERRUPT
angesprungen werden:                    
1) Als erstes wird die neue  Rasterzeile
  festgelegt, die als nächstes Interrupt
  auslösen soll.                        
2) IRQ-Request-Register ($D019) löschen.
  Falls der  Interrupt  durch den Raster
  ausgelöst wurde, ist BIT 7 gesetzt.   
  Das  Löschen  erfolgt,   indem man das
  Register ausliest und den selben  Wert
  gleich wieder zurückschreibt.         
    z.B.             LDA $D019          
                     STA $D019          
    oder einfacher:  DEC $D019          
3) Will man mehrere Interrupte der Reihe
  nach auslösen, dann muß der IRQ-Vektor
  erneut umgestellt werden.             
4) Erst jetzt kommt die eigentliche Auf-
  gabe der  Unterbrechung.    In unserem
  Beispiel  ändern  wir  nur die Farben.
  Sie können aber auch genau so gut eine
  Musik- oder eine Joystick-Routine  an-
  springen.                             
5) Die Unterbrechung wird  abgeschlossen
  durch einen  Sprung  zum Ende der nor-
  malen IRQ-Routine.                    
 Unser erstes Rasterdemo  besteht  aus 3
kurzen Routinen die der Reihe nach ange-
sprungen werden und somit den Bildschirm
in 3 Farbzonen einteilen.    Theoretisch
könnte man beliebig viele Routinen anei-
nander reihen und  so den  Bildschirm in
allen Farben schillern lassen.          
Die folgenden Befehle geben dem Benutzer
die Möglichkeit die Routine wieder abzu-
schalten.          Start mit SYS4140    
       SEI        ;IRQ sperren          
       LDA #$81   ;Timer-IRQ            
       STA $DC0D  ;einschalten          
       LDA #$00   ;Raster-IRQ           
       STA $D01A  ;abschlten            
       LDX #$31   ;IRQ-Vektor           
       LDY #$EA   ;auf ursprünglichen   
       STX $0314  ;Wert setzen          
       STY $0315                        
       CLI        ;IRQ freigeben        
       RTS                              
 Der  Rasterinterrupt  erlaubt aber noch
eine große Anzahl weiterer Effekte. Ver-
suchen sie doch mal  Text  mit  Hochauf-
lösender Graphik zu mischen oder mehrere
Zeichensätze  auf  einmal  darzustellen.
Selbst die Darstellung von mehr als acht
Sprites  gleichzeitig  oder das Scrollen
von  einzelnen  Bildschirmteilen  lassen
sich nun (fast) problemlos realisieren. 
 Als nächstes wollen wir uns wieder ein-
mal mit  Farbeffekten  befassen und auch
eine Spezialroutine vorstellen.         
 Wer sich unter  'RASTER-PROGRAMMIERUNG'
nichts konkretes vorstellen kann, sollte
sollte am besten gleich  'RASTER-DEMO 2'
einladen und und mit SYS4096 starten.   
 Diese interessanten  Farbverläufe,  wie
sie in fast allen DEMOS der letzten Zeit
geboten werden, nennt man RASTEREFFEKTE.
Sie entstehen durch  Ändern  von Rahmen-
und  Hintergrundfarbe  zu  Beginn  jeder
Rasterzeile.                            
 Mit dem  nun  folgenden  Source-Listing
ist es möglich solche Rastereffekte  auf
ganz einfache Weise zu programmieren.   
;***          RASTER-DEMO 2          ***
1000 SEI         ;IRQ sperren           
1001 LDA #$7F    ;Timer-Interrupt       
1003 STA $DC0D   ;abschalten!!!         
1006 LDA $DC0D   ;ICR löschen           
1009 LDA #$82    ;Rasterzeile $82 als   
100B STA $d012   ;IRQ-Auslöser festlegen
100E LDA $D011   ;Bit 7 (Hi-Position)   
1011 AND #$7F    ;löschen               
1013 STA $D011                          
1016 LDA #$01    ;Raster als IRQ-Quelle 
1018 STA $D01A   ;wählen                
101B LDX #$27    ;IRQ-Vektor auf        
101D LDY #$10    ;Interrupt Routine Nr.1
101F STX $0314   ;richten               
1022 STY $0315                          
1025 CLI         ;IRQ freigeben         
1026 RTS                                
;---------------------------------------
1027 LDA #$82    ;RASTERZEILE $82 als   
1029 STA $D012   ;IRQ-Auslöser festlegen
102C LDA #$1B                           
102E STA $D011                          
1031 DEC $D019   ;IRR Register löschen  
1034 LDX #$27    ;IRQ-Vektor            
1036 LDY #$10    ;auf sich selbst       
1038 STX $0314   ;richten               
103B STY $0315                          
103E NOP                                
103F LDY #$00    ;ZEILENZÄHLER          
1041 LDX #$08    ;CHARACTER-ZÄHLER      
1043 LDA $1100,Y ;Farbwert aus Tabelle  
1046 STA $D020   ;Rahmen- und           
1049 STA $D021   ;Hintergrund ändern    
104C INY         ;ZEILENZÄHLER+1        
104D DEX         ;CHARACTER-ZEILE ?     
104E BEQ 1041    ;JA? Dann neue Farbe   
1050 LDA $1026   ;Sonst verzögern       
1053 JSR $1026                          
1056 JSR $1026                          
1059 JSR $1026                          
105C CPY #$48    ;Routine beenden       
105E BCC 1043    ;NEIN?? dann neue Farbe
1060 LDA #$0E    ;Sonst IRQ beenden     
1062 STA $D020                          
1065 LDA #$06                           
1067 STA $D021                          
106A JMP $EA31   ;Sprung zum IRQ-Ende   
 Um das obige Listing zu verstehen,  ist
es unbedingt notwendig, sich mit einigen
technischen Besonderheiten des VIC-Chips
und des CPU auseinander zu setzen.      
 Um einen  Assembler-Befehl auszuführen,
braucht der Prozessor eine gewisse Zeit.
Diese Zeit wird in TAKTZYKLEN  gemessen.
Ein Befehl benötigt in der  Regel  2 bis
7 Taktzyklen. Einige 'Illegalen-Opcodes'
benötigen sogar 8 Taktzyklen.           
 Zuvor haben wir erfahren,  daß das Bild
auf dem Monitor oder Fernseher von einem
Elektronenstrahl erstellt wird. Dies ge-
schied mit großer Geschwindigkeit,  denn
immerhin wird das Bild 20mal pro Sekunde
erneuert.                               
Um eine einzige Rasterzeile zu zeichnen,
"vergehen" im Normalfall genau  63 Takt-
zyklen.    Man müßte eigentlich nur eine
Schleife in Maschinensprache  schreiben,
die alle  63 Taktzyklen  die  Bildfarben
ändert.Das alles klingt schon wahnsinnig
kompliziert,    aber es wird gleich noch
komplizierter.Der Haken ist nämlich der,
daß der   Prozessor  in regelmäßigen Ab-
ständen  unterbrochen  wird  und deshalb
ungleichmäßig läuft.                    
 Diese  Unterbrechung  erfolgt  jedesmal
durch den VIC-Chip,der eine gewisse Zeit
benötigt, um die CHARACTER-ZEILEN zu re-
generieren.                             
 Diese  Unterbrechung erfolgt jede achte
Rasterzeile und jedesmal am Anfang einer
CHARACTER-ZEILE für genau 42 Taktzyklen.
 Mit diesen Informationen ist es uns nun
möglich,  den Ablauf des Source-Listings
nachzuvollziehen.                       
 In der Initialisierung wird Rasterzeile
$82 als IRQ-Auslöser festgelegt. Von nun
an laufen alle  IRQs  über unsere eigene
Routine die bei $1027 beginnt.          
 Da es in diesem  Beispiel nur eine ein-
zige Routine gibt,   die fortlaufend an-
gesprungen wird, ist es erforderlich,die
Vektoren  jedesmal  auf  sich  selbst zu
richtenen.                              
 Da wir inzwischen wissen,daß jede achte
Rasterzeile ein besonderes  'TIMING' er-
fordert,  haben wir einfach das  Prinzip
der GESCHACHTELTEN-SCHLEIFEN angewand.  
 Das  Y-Register  ist der Zähler für die
Anzahl der  RASTERZEILEN die durchlaufen
werden.                                 
 Das  X-Register  ist eine Art Indikator
für alle  Rasterzeilen  mit  gesondertem
Timing,  daß in jeder Rasterzeile um den
Wert 1 verringert wird.   Ist der Wert 0
erreicht worden(ZERO-FLAG wird gesetzt),
so erfolgt ein Rücksprung an die Adresse
$1041.   Die so entstandene Schleife hat
genau 21 Taktzyklen.                    
 Sollte das  X-Register  den Wert 0 noch
nicht erreicht haben,  so wird die Lauf-
zeit um 42 Taktzyklen verlängert.       
 Bei  Adresse $1000  wird das Y-Register
mit der Anzahl der Rasterzeilen die dar-
gestellt werden verglichen. Ist der Wert
größer,  dann erfolgt ein Sprung zum IRQ
Ende.                                   
 Die Routine erlaubt noch einige Experi-
mente.Aus Adresse $1043 ist ersichtlich,
daß sämtliche  Farbwerte aus der Tabelle
bei $105C geholt werden (LDA $1100,Y).  
 Wollen  sie  andere  Farben darstellen,
dann müssen Sie mit einem   Monitor  die
Zahlenwerte in dieser Tabelle ändern.   
  Besonders gut  -finde ich-  sieht  das
Ganze aus, wenn man sehr weiche Farbver-
läufe  darstellt  und  diese  zusätzlich
noch bewegt werden.                     
 Sie sehen, der  Raster-Interupt ist ein
sehr interessantes Spielzeug,   das eine
Fülle von  Varriationen   zu bieten hat.
                           (IVO HERZEG) 



Valid HTML 4.0 Transitional Valid CSS!