The one used in
Rockman 3 seems to be good --- the IRQs are reproduced very similar to the original MMC3 cartridge. First, initialize a table:
Code:
LDY #0
STY $7200
STY $7300
STY $00
STY $01
INY
.L1: CLC
LDA $00
ADC #$72
STA $00
LDA $01
ADC #$00
STA $01
LDA $00
STA $7200,Y
LDA $01
STA $7300,Y
INY
BNE .L1
Then, reset and start the counter at the start of the NMI handler:
Code:
LSR $440C ; clear counting flag and reset the counter
LDA #$FF ; set counting flag again to restart the counter, make it count longer than a frame so it will be reset by next NMI before it occurs
STA $440C
STA $440D
Whenever you would write a scanline value to the MMC3's IRQ latch, use the following:
Code:
; A: Absolute scanline number where IRQ shall occur
TAX
LDA $7200,X
STA IRQCount_LSB
LDA $7300,X
STA IRQCount_MSB
LDA IRQCount_LSB
STA $440D
LDA IRQCount_MSB
CLC
ADC #$08 ; Add 2048 cycles for VBlank duration
ORA #$80 ; Set counter enable flag
STA $440C
Code copied from K127 (Rockman 3). The calculation will be a bit off because it uses 114 cycles per scanline; correct would 113+2/3. To accomodate that, you would only have to improve the table generation by slightly unrolling the loop:
Code:
LDY #0
STY $7200
STY $7300
STY $00
STY $01
INY
.L1: CLC
LDA $00
ADC #$71 ; 113
STA $00
LDA $01
ADC #$00
STA $01
LDA $00
STA $7200,Y
LDA $01
STA $7300,Y
INY
BEQ .done
.L2: CLC
LDA $00
ADC #$72 ; 114
STA $00
LDA $01
ADC #$00
STA $01
LDA $00
STA $7200,Y
LDA $01
STA $7300,Y
INY
BEQ .done
.L13 CLC
LDA $00
ADC #$72 ; 114
STA $00
LDA $01
ADC #$00
STA $01
LDA $00
STA $7200,Y
LDA $01
STA $7300,Y
INY
BNE .L1
.done:
Depending on where the counter reset occurs in your NMI handler, you might have to fine-tune the $0800 bias that is added to IRQCount_LSB/MSB.