Keyboard Interrupts bändigen
von slx » Sa 30. Sep 2017, 22:58Ich arbeite schon seit einiger Zeit daran, das Spiel Shamus auf dem Atari um die zusätzlichen Maps der C64-Version zu erweitern. Das funktioniert, und nun möchte ich noch eine "Pause"-Funktion einfügen.
Auf VBI-Basis habe ich das schon geschafft, aber das kostet 71 cycles pro frame, das meiste davon Systemcode für Vertical Blank-Interrupts, die vom Spiel sonst nicht verwendet werden (funktioniert mit Delay Loops und Display List Interrupts). Vermutlich ist das zwar unmerklich, aber trotzdem eine Änderung des originalen Timings.
Daher habe ich versucht, das alternativ mit Keyboard Interrupt zu lösen. Das Spiel selbst verwendet keine IRQs, es gibt nichts, mit dem ich da in Konflikt kommen könnte. Daher verwende ich nicht den Keyboard-Vektor sondern steige direkt mit dem VIMIRQ-Vektor bei $216/7 in meine Interrupt-Routine ein.
Die checkt dann, ob es auch tatsächlich ein Keyboard Interrupt ist (IRQST bit 7 = 0), wenn nicht wird der Interrupt beendet.
Wenn eine Taste gedrückt wurde, schalte ich IRQs und NMIs aus, mache einen Reset , warte bis VCOUNT am Ende des Bildschirms ist und schalte dann auf meinen eigenen "Pausenbildschirm" um (damit werden auch gleich die DLIs umgangen, und das Spiel wird eingefroren).
Soweit klappt das ganz gut.
Dann wartet ein Loop darauf, dass der Spieler den Feuerknopf drückt und sobald er das tut, wird der Schirm wieder hergestellt, IRQEN nochmals "resettet" und dann werden NMIs und IRQs wiederhergestellt.
Das "Wiederherstellen" funktioniert auch, aber unmittelbar danach wird unabhängig von der Dauer der Pause sofort wieder ein Keyboard Interrupt ausgelöst.
Nach meinem Verständnis sollte Tastenprellen keine Rolle spielen, weil ich IRQs ja sofort ausschalte und IRQEN auf 0 stelle. Interrupts sollten auch nicht gespeichert werden, bzw. durch Schreiben von 0 in IRQEN zurückgesetzt werden.
Hat jemand eine Idee, wo der neuerliche Interrupt herkommen könnte?
(Getestet habe ich das vorerst auf Altirra 2.90)
Auf VBI-Basis habe ich das schon geschafft, aber das kostet 71 cycles pro frame, das meiste davon Systemcode für Vertical Blank-Interrupts, die vom Spiel sonst nicht verwendet werden (funktioniert mit Delay Loops und Display List Interrupts). Vermutlich ist das zwar unmerklich, aber trotzdem eine Änderung des originalen Timings.
Daher habe ich versucht, das alternativ mit Keyboard Interrupt zu lösen. Das Spiel selbst verwendet keine IRQs, es gibt nichts, mit dem ich da in Konflikt kommen könnte. Daher verwende ich nicht den Keyboard-Vektor sondern steige direkt mit dem VIMIRQ-Vektor bei $216/7 in meine Interrupt-Routine ein.
Die checkt dann, ob es auch tatsächlich ein Keyboard Interrupt ist (IRQST bit 7 = 0), wenn nicht wird der Interrupt beendet.
Wenn eine Taste gedrückt wurde, schalte ich IRQs und NMIs aus, mache einen Reset , warte bis VCOUNT am Ende des Bildschirms ist und schalte dann auf meinen eigenen "Pausenbildschirm" um (damit werden auch gleich die DLIs umgangen, und das Spiel wird eingefroren).
Soweit klappt das ganz gut.
Dann wartet ein Loop darauf, dass der Spieler den Feuerknopf drückt und sobald er das tut, wird der Schirm wieder hergestellt, IRQEN nochmals "resettet" und dann werden NMIs und IRQs wiederhergestellt.
Das "Wiederherstellen" funktioniert auch, aber unmittelbar danach wird unabhängig von der Dauer der Pause sofort wieder ein Keyboard Interrupt ausgelöst.
Nach meinem Verständnis sollte Tastenprellen keine Rolle spielen, weil ich IRQs ja sofort ausschalte und IRQEN auf 0 stelle. Interrupts sollten auch nicht gespeichert werden, bzw. durch Schreiben von 0 in IRQEN zurückgesetzt werden.
Hat jemand eine Idee, wo der neuerliche Interrupt herkommen könnte?
(Getestet habe ich das vorerst auf Altirra 2.90)
- Code: Alles auswählen
CHECKKEYS PHA
LDA IRQST
AND #$40
BNE NOKEY
STA IRQEN
STA NMIEN
TXA
PHA
TYA
PHA
WAITVBI LDA VCOUNT
BPL WAITVBI
LDA <PAUSEDLIST
STA DLISTL
LDA >PAUSEDLIST
STA DLISTH
LDA #$00
LDY #$03
KILLAUDIO STA AUDF1,Y
DEY
BPL KILLAUDIO
PAUSING LDA TRIG0
BNE PAUSING
ENDPAUSE LDA #$B8
STA DLISTL
LDA #$35
STA DLISTH
LDA #$C0
STA NMIEN
STA HITCLR
LDA #$00
STA IRQEN
JSR WAIT
LDA #$40
STA IRQEN
EXIT ;
PLA
TAY
PLA
TAX
NOKEY PLA
RTI