Magic Disk 64

home to index to html: MD9010-KURSE-ASSEMBLER-KURS_1_TEIL_10.html
          Assembler-Kurs Teil 10        
Wie versprochen, handelt der letzte Teil
dieses   Kurses   von   en   Interrupts.
Interrupt bedeutet  soviel  wie  "Unter-
brechung" des laufenden  Programms.  Der
C64 reagiert auf verschiedene Arten  von
Interrupts, die man in Hard-  und  Soft-
wareinterrups     unterteilen      kann.
Hardware-Interrupts                     
-------------------                     
Es gibt zwei unterschiedliche Arten  von
Hardware-Interrupts, den IRQ  (interrupt
request = Interrupt Anforderung) und den
NMI  (non  maskable  interrupt  =  Nicht
maskierbarer  Interrupt).   Beide   sind
eigentlich Pins am Prozessor,  an  denen
durch  ein  Impuls  ein   entsprechender
Interrupt  ausgelöst  werden  kann.  Die
Reaktion  des   Prozessors   auf   beide
Interrupts  ist  etwas  unterschiedlich.
Grundsätzlich sagt man, daß der NMI  die
höhere Priorität beider  Interrupt-Arten
hat und somit für  die  für  das  System
wichtigen Aufgaben eingesetzt wird.     
a) Ablauf eines NMI:                    
   1.Der momentan zu bearbeitende Befehl
     des laufenden Programms wird noch  
     ausgeführt.                        
   2.Der Programmzähler (program        
     counter), d.h. das Register, das   
     immer auf den nachfolgenden Befehl 
     eines Programms zeigt, wird auf den
     Stack geschoben. Dabei wird zuerst 
     das höherwertige und dann das      
     niederwertige Byte des Programm-   
     zählers  abgelegt.                 
   3.Das Statusregister, das alle Flags 
     enthält, wird auf den Stack        
     gebracht.                          
   4.Der Inhalt der Adressen $FFFA (als 
     niederwertiges Byte) und $FFFB (als
     höherwertiges Byte) wird zusammen- 
     gesetzt und als neuer Programm-    
     zähler benutzt. Ab jetzt wird also 
     das (unterbrechende) Programm an   
     der Stelle ausgeführt, auf die der 
     neue Programmzähler zeigt.         
b) Ablauf eines IRQ:                    
   1.Zunächst scheint der IRQ genauso   
     zu verlaufen, wie der NMI. Der     
     augenblicklich zu bearbeitende     
     Befehl des laufenden Programms wird
     noch vollständig abgearbeitet.     
   2.Anschließend erfolgt eine          
     Überprüfung des Interrupt-Flags    
     (Bit 2 des Statusregisters). Wenn  
     das Bit gesetzt ist, dann wird die 
     Interrupt-Anforderung einfach      
     ignoriert, und der Prozessor fährt 
     fort, als ob nichts geschehen wäre.
     Ist das Interrupt-Bit jedoch       
     gelöscht, so wird der IRQ          
     ausgeführt.                        
   3.Der Programmzähler wird auf den    
     Stack geschrieben.                 
   4.Das Statusregister wird gestackt.  
   5.Nun wird das Interrupt-Flag        
     gesetzt, so daß alle nachfolgenden 
     Interrupt-Anforderungen ignoriert  
     werden. Man bezeichnet diesen      
     Vorgang als 'Sperren' des IRQ.     
   6.Der Inhalt der Adressen $FFFE und  
     $FFFF wird zusammengesetzt und als 
     neuer Programmzähler benutzt.      
Der Hauptunterschied  zwischen  NMI  und
IRQ liegt darin, daß  der  IRQ  maskiert
(d.h. gesperrt) werden kann.            
Wie oben bereits beschrieben, wird  beim
IRQ zuerst  das  I-Flag  untersucht  und
erst  daraufhin  entschieden,   ob   ein
Interrupt auszuführen ist,  oder  nicht.
Dieses  Interrupt-Flag  des   maskierten
Interrupts IRQ  kann  vom  Programmierer
selbst direkt beeinflußt werden.        
Mit dem Befehl SEI (SEt Interrupt  mask)
wird das I-Flag gesetzt und somit werden
alle folgenden IRQs gesperrt. Durch  CLI
(CLear  Interrupt  mask)   kann   dieser
Zustand wieder  aufgehoben  werden,indem
das I-Flag gelöscht wird.  Ein  IRQ  ist
nun für den  nachfolgenden  Programmteil
wieder  zugelassen.  Häufige   Anwendung
finden diese beiden  Befehle  auch  beim
Umschalten   der   Speicherkonfiguration
durch  den   Prozessorport.   Ohne   das
vorherige  Abschalten   der   Interrupts
mittels SEI kann es beim Ausschalten von
ROM-Berichen zum Systemabsturz kommen.  
Wodurch können die Interrupt IRQ und NMI
ausgelöst werden ?                      
Selbstverständlich nur durch  die  Hard-
ware des Computers:                     
 IRQ: a) durch den Videocontroller VIC  
      b) durch den CIA-Baustein ($DC00) 
 NMI: a) durch den CIA-Baustein ($DD00) 
      b) durch die RESTORE-Taste        
Der Software-Interrupt                  
----------------------                  
Software-Interrupts  werden  durch   den
Befehl BRK (BReaK)  ausgelöst.  Das  war
einer der ersten  Befehle,  die  wir  in
diesem  Kurs  kennengelernt  haben.  Nun
wollen  wir   untersuchen,   was   genau
passiert, wenn der Prozessor  auf  einen
BRK-Befehl im Programm stößt:           
 1.Das Break-Flag (Bit 4 des Status-    
   registers) wird gesetzt.             
 2.Der Programmzähler wird auf den Stack
   gebracht.                            
 3.Das Statusregister wird gestackt.    
 4.Nun wird das Interrupt-Flag gesetzt, 
   so daß alle IRQs gesperrt werden.    
 5.Der Inhalt der Adressen $FFFE und    
   $FFFF (dieselben Adressen wie beim   
   IRQ) wird zusammengesetzt und als    
   neuer Programmzähler benutzt.        
Meistens wird der BRK-Interrupt von  den
Assembler-Monitoren dazu genutzt, um das
laufende Programm  abzubrechen  und  das
Statusregister mit den  aktuellen  Flags
anzuzeigen.  Es  wäre  aber  auch   eine
andere   Nutzung    dieses    Interrupts
möglich.                                
Der  Software-Interrupt  BRK  wird  also
im Gegensatz zu den  Hardware-Interrupts
durch einen Assembler-Befehl ausgelöst. 
Egal, ob IRQ,  NMI  oder  der  Software-
interrupt   BRK.   Eines   haben    alle
gemeinsam. Sie lesen alle  einen  Zeiger
aus ($FFFE/FFFF bei IRQ,BRQ; $FFFA/$FFFB
bei NMI) der auf eine ROM-Routine weist.
Diese  ROM-Routinen   werden   nun   als
Interruptprogramm    abgearbeitet    und
führen am Ende einen unbedingten  Sprung
aus. Dieser unbedingt  e  Sprung  beruft
sich auf einen Zeiger, der im RAM steht.
Diese Zeiger sind: für IRQ   $0314/$0315
                   für BRK   $0316/$0317
                   für NMI   $0318/$0319
Diese  Zeiger  sind  schon   mit   einem
bestimmten Wert  initialisiert,  so  daß
der Sprung ohne unser Eingreifen bestens
funktioniert.  Wie   Sie   schon   ahnen
werden,   müssen   wir   diesen   Zeiger
lediglich auf unsere selbstgeschriebenen
Routinen umbiegen, und schon  haben  wir
eigene Interruptroutinen.               
Das Ende der Interrupts: RTI            
----------------------------            
Wenn das Programm durch einen  Interrupt
unterbrochen wurde und der Prozessor nun
eine Interrupt-Routine bearbeitet,  dann
muß ihm auch irgendwie kenntlich gemacht
werden, wann diese Unterbrechung beendet
werden soll. Auch die  Interruptroutinen
benötigen daher  ein  Programmende.  Für
'normale'  Programme   haben   wir   als
Kennzeichnung für das Programmende immer
den    RTS-Befehl    (ohne    vorherigen
JSR-Befehl)  im  Hauptprogramm  benutzt,
wodurch wir zurück ins BASIC kamen.     
Der Befehl für das Ende unser  selbstge-
schriebenen Interrupt-Routine lautet RTI
(ReTurn from Interrupt). Bei  der  Bear-
beitung   dieses   Befehls   läuft   der
umgekehrte Prozeß des  Interrupt-Aufrufs
ab.                                     
 1.Das Statusregister muß vom Stack     
   geholt werden.                       
 2.Der Programmzähler wird vom Stack    
   geholt und wieder als aktueller      
   Zähler benutzt.                      
 3.An der Stelle, auf die der Programm- 
   zähler zeigt, wird das unterbrochene 
   Programm fortgeführt.                
Der Hauptunterschied  zwischen  RTS  und
RTI liegt darin, daß beim RTI zusätzlich
zum Programmzähler auch noch das Status-
register vom Stack geholt werden muß.   
Ein Interrupt hat doch  einige  Ähnlich-
keiten  mit  einem  Unterprogrammaufruf.
Ein Unterprogramm wird jedoch von  einer
klar definierten Stelle im Hauptprogramm
(durch den JSR-Befehl)  aufgerufen.  Die
Interrupts NMI  und  IRQ  werden  jedoch
hardwaremäßig  ausgelöst,  so  daß   die
Unterbrechung  des   Hauptprogramms   an
jeder  beliebigen   Stelle   stattfinden
kann.  Diese  Eigenschaft  erweckt   den
Eindruck, daß die  Interruptroutine  und
das Hauptprogramm parallel arbeiten, was
aber natürlich nicht der Fall ist.      
In dem Begleitprogramm                  
"ASSEMBLER-KURS10"                      
werden  wir  eigene   Interrupt-Routinen
schreiben.  Dabei   geht   es   um   die
Benutzung des Systeminterrupts  und  der
Interrupts  durch  den   Videocontroller
(Rasterzeilen-Interrupt).               
Dies war der letzte Teil des  Assembler-
Kurses.  Ich  hoffe,  er  konnte   Ihnen
einige   Kenntnisse    und    Anregungen
verschaffen.                            
                                   rt/wk



Valid HTML 4.0 Transitional Valid CSS!