Magic Disk 64

home to index to text: MD9408-KURSE-ASSEMBLER_KURS_2_(TEIL_10).txt

Assembler-Kurs Teil 10 Wie versprochen, handelt der letzte Teil dieses Kurses von en Interrupts.
Interrupt bedeutet soviel wie " Unterbrechung" des laufenden Programms. Der C64 reagiert auf verschiedene Arten von Interrupts, die man in Hardund Softwareinterrups 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 Programmzä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 zusammengesetzt und als neuer Programmzä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 Hardware 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 Statusregisters) 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 Softwareinterrupt 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 selbstgeschriebenen Interrupt-Routine lautet RTI ( ReTurn from Interrupt) . Bei der Bearbeitung 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 Programmzä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 Statusregister vom Stack geholt werden muß.
Ein Interrupt hat doch einige Ähnlichkeiten 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.
Im 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!