IRQ

Aus C64-Wiki
Zur Navigation springenZur Suche springen

Der IRQ (Interrupt ReQuest oder maskierbarer Interrupt) ist wie der NMI eine Interruptleitung der CPU. Im Gegensatz zum NMI ist die Leitung Low-aktiv, und der Prozessor ignoriert bei gesetztem Interrupt-Flag die IRQ-Leitung. Dieses Flag kann mit dem Assembler-Befehl SEI gesetzt und per CLI gelöscht werden. Außerdem setzt die CPU das Flag automatisch bei der Auslösung eines IRQs.

Der Programmteil, der einen IRQ abarbeitet, wird Interrupt Service Routine (ISR) genannt.

Auslösung[Bearbeiten | Quelltext bearbeiten]

Folgende Möglichkeiten bestehen, um einen Low-Pegel (0) auf der IRQ-Leitung zu erzeugen.

Ferner löst der BRK-Befehl einen Interrupt aus, zieht aber nicht die IRQ-Leitung auf Low.

Das Signal an der IRQ-Leitung wird ab dem 2. Takt bis zum letzten Takt einer Instruktion erkannt.
Eine zeitgleich mit einer IRQ-Anforderung anliegende NMI-Anforderung hat Vorrang.[1]

Das Löschen des I-Flags führt üblicherweise dazu, dass eine etwaige bereits wieder anstehende Anforderung zu berücksichtigen ist. Das passiert aber bei den das I-Flag manipulierenden Instruktionen zu unterschiedlichen Zeitpunkten:[2]

  • RTI: unmittelbar nach dem RTI kann bereits zu einer IRQ-Routine verzweigt werden, weil schon während dessen der Status der IRQ-Leitung berücksichtigt wird.
  • CLI, PLP, SEI: Hier wird erst in der folgenden Instruktion der Status der IRQ-Leitung überprüft und damit die folgende Instruktion noch abgearbeitet bevor sich der IRQ auswirkt.

Ablauf[Bearbeiten | Quelltext bearbeiten]

  1. Es wird zunächst der laufende Befehl zu Ende abgearbeitet.
  2. Der Programmzähler (PC) des unterbrochenen Programms wird auf den Stapel abgelegt.
  3. Das Statusregister wird auf den Stapel gelegt und anschließend das Interrupt-Flag gesetzt, was eine neuerliche Unterbrechung der ISR selbst verhindert.
  4. Der Hardware-Vektor $FFFE/$FFFF wird angesprungen (zeigt beim normalen C64-KERNAL auf Adresse $FF48).
  5. Die Interrupt-Service-Routine ab $FF48 wird abgearbeitet.
  6. mit dem Befehl RTI folgt der Rücksprung ins unterbrochene Programm.

ISR des KERNAL[Bearbeiten | Quelltext bearbeiten]

  1. $FF48: im Gegensatz zur NMI-Routine werden die Register gesichert
  2. $FF4D: Break-Flag testen und ggf. zur Break-Routine $FE66 springen
  3. $FF58: Sprung in die IRQ-Routine (normalerweise $EA31) über Vektor $0314
  4. $EA31: Jiffy-Clock (siehe TIME) erhöhen und auf RUN/STOP  prüfen (und ggf. $91 entsprechend setzen)
  5. $EA34: Cursor blinken lassen
  6. $EA61: Datassetten-Motor ggf. anschalten
  7. $EA7B: Tastatur lesen und Tastaturpuffer befüllen (via $EA87)
  8. $EA81: Wiederherstellen der Register und Rücksprung per RTI.

Eigene ISR[Bearbeiten | Quelltext bearbeiten]

Bei der originalen ISR wird bei Adresse $FF58 der Befehl JMP ($0314) ausgeführt. Hier besteht nun die Möglichkeit, diesen Vektor (LSB = $0314 ; MSB = $0315) "umzubiegen", um in eine eigene ISR springen zu können (siehe Beispielprogramm). Alternativ muss bei ausgeblendetem ROM direkt die Adresse der eigenen Interrupt-Service-Routine an den Vektor $FFFE/$FFFF geschrieben werden.

Hardware Vektoren[Bearbeiten | Quelltext bearbeiten]

Vektor-Name Hardware Vektor Adresse
NMI $FFFA / $FFFB $FE43
Reset $FFFC / $FFFD $FCE2
IRQ $FFFE / $FFFF $FF48


Weblinks[Bearbeiten | Quelltext bearbeiten]

Referenzen[Bearbeiten | Quelltext bearbeiten]