Oh blah... I'm sorry Hamtaro -- I feel kind of dumb. For some reason my brain blocked out all the times you mentioned MMC3 (it's even in the thread title)
My apologies.
Anyway setting up an IRQ is pretty simple on MMC3, but there is a big caveat:
All sprites must use right-hand pattern table & BG must use lefthand pattern table.
I believe this is the opposite of how SMB does it. *checks* Yeah it is. You technically can get away with SMB as it is now -- but it's ill advised. Especially if you plan to move to 8x16 sprites -- in which case the BG
MUST be using the left pattern table.
To make this change, simply flip around the CHR in the ROM and change what gets written to $2000 (specifically, you'll need to switch bits 3 and 4). Make sure you catch and fix every $2000 write SMB does -- there probably aren't too many of them.
That caveat aside.. IRQs are pretty simple. You'll need to set up the IRQ counter in VBlank so that it fires on the desired scanline. Then when it fires, you just split the screen's scroll and acknowlege/disable the IRQ:
To enable/set up the IRQs (done in VBlank):
1) Write N to $C000, where 'N' is the number of scanlines you want the IRQ to fire after minus 1. (This sets the reload value)
2) write any value to $C001 (this clears the actual IRQ counter)
3) write any value to $E000 (this enables IRQs)
4) clear the I flag with a CLI instruction
also) I don't think SMB has other IRQ sources enabled, but if it does you may have to disable them. The only one that's a concern really is APU frame IRQs. Just make sure that whenever SMB writes to $4017, bit 6 is set.
To acknowledge/disable IRQs (do in your IRQ routine):
1) write any value to $E001
For example -- if you want the IRQ to happen after 32 ($20) scanlines, you'd do the following:
Code:
; in VBlank (probably in NMI)
LDA #$1F
STA $C000 ; write $20 - 1
STA $C001
STA $E000
; IRQs now up and running
; make sure the CPU doesn't mask them
CLI
; in your IRQ routine, you need to acknowledge the IRQ:
STA $E001 ; that's it!