Magic Disk 64

home to index to text: MD9007-KURSE-INTERRUPTKURS_TEIL_2.txt
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 Unterbrechungsprogramm 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 Begriffen steckt.
IRQ ( Interrupt ReQuest) Dies ist ein sogenannter maskierbarer Interrupt. Maskierbar heißt, daß per Software 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 ausgelö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 andere 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 unerschö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 programmiertechnischen Trick auszuschalten und Graphiken auf der gesamten Bildschirmfläche darzustellen. Diese Entdeckung löste eine einzigartige Experimentierwelle 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 1001 CREW, die mit ihren Werken einen respektablen Bekanntheitsgrad erreichten. Hierzu gehörten schillernde Gestallten wie FLASH, S0 DAN, 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 Einzelheiten 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 Verbindung:
$ 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 gerade 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 Bildschirms 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, Rahmenund 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 Interupts 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 $ D01 A 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 $ D01 A 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 Rasterzeile $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 $ D0193) Will man mehrere Interrupte der Reihe nach auslösen, dann muß der IRQ-Vektor erneut umgestellt werden.
4) Erst jetzt kommt die eigentliche Aufgabe der Unterbrechung. In unserem Beispiel ändern wir nur die Farben.
Sie können aber auch genau so gut eine Musikoder eine Joystick-Routine anspringen.
5) Die Unterbrechung wird abgeschlossen durch einen Sprung zum Ende der normalen IRQ-Routine.
Unser erstes Rasterdemo besteht aus 3 kurzen Routinen die der Reihe nach angesprungen werden und somit den Bildschirm in 3 Farbzonen einteilen. Theoretisch könnte man beliebig viele Routinen aneinander reihen und so den Bildschirm in allen Farben schillern lassen.
Die folgenden Befehle geben dem Benutzer die Möglichkeit die Routine wieder abzuschalten. 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. Versuchen sie doch mal Text mit Hochauflö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 einmal 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 Rahmenund 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 geschied mit großer Geschwindigkeit, denn immerhin wird das Bild 20 mal pro Sekunde erneuert.
Um eine einzige Rasterzeile zu zeichnen," vergehen" im Normalfall genau 63 Taktzyklen. 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 Abstä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 regenerieren.
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 einzige Routine gibt, die fortlaufend angesprungen wird, ist es erforderlich, die Vektoren jedesmal auf sich selbst zu richtenen.
Da wir inzwischen wissen, daß jede achte Rasterzeile ein besonderes ' TIMING' erfordert, 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 Laufzeit um 42 Taktzyklen verlängert.
Bei Adresse $1000 wird das Y-Register mit der Anzahl der Rasterzeilen die dargestellt werden verglichen. Ist der Wert größer, dann erfolgt ein Sprung zum IRQ Ende.
Die Routine erlaubt noch einige Experimente. Aus Adresse $1043 ist ersichtlich, daß sämtliche Farbwerte aus der Tabelle bei $105 C 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 ichsieht das Ganze aus, wenn man sehr weiche Farbverlä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!