I'm trying to understand the timing and commands associated with the MMC3 IRQ and where I might be missing something.
Here is my IRQ code:
Here is an example of an IRQ that I use to bankswitch:
The IRQ is pointer is assigned using the following template where "N" is the scanline where I want the IRQ to trigger.
To enable and disable IRQs I have a subroutine in my NMI that considers a bit flag (in FLAG.ENABLE)
This all works fine EXCEPT that I still have to manage the enabling and disabling of the IRQs through SEI/CLI commands OUTSIDE of the NMI.
I was really hoping I could add them to the NMI IRQ subroutine:
But, when I do the IRQs no longer trigger at all. I can't understand why this happens.
Any help or suggestions on how better to handle the MMC3 IRQs would be greatly appreciated.
Thank you!
Here is my IRQ code:
Code:
IRQ:
; Preserves the state of the A, X, Y registers
PHA
TXA
PHA
TYA
PHA
JMP (PTR.IRQJUMP)
IRQ.RETURN:
; Restores registers
PLA
TAY
PLA
TAX
PLA
; Returns control to the CPU from the place where the IRQ triggered.
RTI
; Preserves the state of the A, X, Y registers
PHA
TXA
PHA
TYA
PHA
JMP (PTR.IRQJUMP)
IRQ.RETURN:
; Restores registers
PLA
TAY
PLA
TAX
PLA
; Returns control to the CPU from the place where the IRQ triggered.
RTI
Here is an example of an IRQ that I use to bankswitch:
Code:
LBL.TITLE.IRQ:
STA IRQDISABLE
LDA #$00
STA BANKSELECT
LDA #CHRBANKBGFONT
;Wait until next HBlank
.rept 34
NOP
.endr
; These need to occur in HBlank
; ------------------------------
STA BANKDATA
---------------
JMP IRQ.RETURN
STA IRQDISABLE
LDA #$00
STA BANKSELECT
LDA #CHRBANKBGFONT
;Wait until next HBlank
.rept 34
NOP
.endr
; These need to occur in HBlank
; ------------------------------
STA BANKDATA
---------------
JMP IRQ.RETURN
The IRQ is pointer is assigned using the following template where "N" is the scanline where I want the IRQ to trigger.
Code:
LDA #(N-1)
STA VAR.IRQ.LINE
LDA #<SUB.IRQ
STA PTR.IRQJUMP
LDA #>SUB.IRQ
STA PTR.IRQJUMP+1
STA VAR.IRQ.LINE
LDA #<SUB.IRQ
STA PTR.IRQJUMP
LDA #>SUB.IRQ
STA PTR.IRQJUMP+1
To enable and disable IRQs I have a subroutine in my NMI that considers a bit flag (in FLAG.ENABLE)
Code:
SUB.EnableIRQ:
LDA FLAG.ENABLE
AND #ENABLE.IRQ
BNE LBL.EnableIRQ.Continue
RTS
LBL.EnableIRQ.Continue:
STA IRQDISABLE
LDA VAR.IRQ.LINE
STA IRQLATCH
STA IRQRELOAD
STA IRQDISABLE
STA IRQENABLE
RTS
LDA FLAG.ENABLE
AND #ENABLE.IRQ
BNE LBL.EnableIRQ.Continue
RTS
LBL.EnableIRQ.Continue:
STA IRQDISABLE
LDA VAR.IRQ.LINE
STA IRQLATCH
STA IRQRELOAD
STA IRQDISABLE
STA IRQENABLE
RTS
This all works fine EXCEPT that I still have to manage the enabling and disabling of the IRQs through SEI/CLI commands OUTSIDE of the NMI.
I was really hoping I could add them to the NMI IRQ subroutine:
Code:
SUB.EnableIRQ:
LDA FLAG.ENABLE
AND #ENABLE.IRQ
BNE LBL.EnableIRQ.Continue
SEI
RTS
LBL.EnableIRQ.Continue:
STA IRQDISABLE
LDA VAR.IRQ.LINE
STA IRQLATCH
STA IRQRELOAD
STA IRQDISABLE
STA IRQENABLE
CLI
RTS
LDA FLAG.ENABLE
AND #ENABLE.IRQ
BNE LBL.EnableIRQ.Continue
SEI
RTS
LBL.EnableIRQ.Continue:
STA IRQDISABLE
LDA VAR.IRQ.LINE
STA IRQLATCH
STA IRQRELOAD
STA IRQDISABLE
STA IRQENABLE
CLI
RTS
But, when I do the IRQs no longer trigger at all. I can't understand why this happens.
Any help or suggestions on how better to handle the MMC3 IRQs would be greatly appreciated.
Thank you!