IRQ

Aus C64-Wiki
Wechseln zu: Navigation, Suche

Der IRQ (Interrupt ReQuest oder maskierbarer Interrupt) ist wie der NMI eine Interruptleitung der CPU, die "low"-aktiv ist. Im Gegensatz zum NMI kann sich ein Programm durch Setzen des Interrupt-Flags mit dem Assembler-Befehl SEI gegen eine IRQ-Anforderung schützen (maskieren) und zu einem späteren Zeitpunkt eine Unterbrechung wieder mit dem Assembler-Befehl CLI zulassen.

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

Auslösung[Bearbeiten]

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

Ablauf[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]

  • im Gegensatz zur NMI-Routine werden die Register gesichert:
 $FF48 PHA          ; Akku sichern
 $FF49 TXA 
 $FF4A PHA          ; X-Register sichern
 $FF4B TYA
 $FF4C PHA          ; Y-Register sichern
$FF4D TSX          ; Stapelzeiger ins X-Register
$FF4E LDA $0104, X ; Break-Flag vom Stapel holen
$FF51 AND #$10     ; und testen
$FF53 BEQ $FF58    ; nicht gesetzt
$FF55 JMP ($0316)  ; Break-Routine $FE66
  • Sprung in die IRQ-Routine:
$FF58 JMP ($0314)  ; IRQ-Routine $EA31
  • Standard IRQ-Routine:
$EA31 ...
$EA34 ...
...
...
$EA81 PLA
$EA82 TAY          ; Y-Register wiederherstellen
$EA83 PLA
$EA84 TAX          ; X-Register wiederherstellen
$EA85 PLA          ; Akkumulator wiederherstellen
  • mit dem Befehl RTI folgt der Rücksprung ins Hauptprogramm:
$EA86 RTI          ; Rücksprung ins Hauptprogramm

Eigene ISR[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]

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