IRQ
Aus C64-Wiki
Der IRQ (Interrupt ReQuest oder maskierbarer Interrupt) ist wie der NMI eine Interruptleitung der CPU, die "low"-aktiv ist. Im Gegensatz zum NMI kann der IRQ softwaremäßig durch den Assembler-Befehl SEI unterbunden werden.
[bearbeiten] Auslösung
Folgende Möglichkeiten bestehen, um einen Low-Pegel (0) auf der /IRQ-Leitung zu erzeugen.
- extern über den Expansionsport über Pin 4
- durch den BRK-Befehl
- durch entsprechende Programmierung des Interrupt-Kontrollregisters der CIA-Bausteine (Timer CIA1) bzw. durch den VIC (Sprite/Lightpen/Rasterzeilen-Interrupt)
[bearbeiten] Ablauf
- es wird zunächst der laufende Befehl zu Ende abgearbeitet.
- der Programmzähler (PC) wird auf den Stapel abgelegt.
- der Hardware-Vektor $FFFE/$FFFF wird angesprungen (Adresse $FF48).
- die Interrupt-Service-Routine ab $FF48 wird abgearbeitet.
- 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
- Break-Flag testen
$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
[bearbeiten] Eigene Interrupt-Service-Routine (ISR) für den IRQ
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)
[bearbeiten] Hardware Vektoren
| Vektor-Name | Hardware Vektor | Adresse |
|---|---|---|
| NMI | $FFFA / $FFFB | $FE43 |
| Reset | $FFFC / $FFFD | $FCE2 |
| IRQ | $FFFE / $FFFF | $FF48 |
