So, after converting SMB3 disassembled from NESASM to ASM6 (posted here) I've started converting the game from MMC3 to MMC5.
I've already managed to get everything to work, from the banking switches to the IRQ stuff. However, I realized to my dismay that different emulators are behaving differently on me. I assume it's because MMC5 is a pretty complex mapper and not all emulators are in complete agreement about how it should behave.
I've tested four emulators now, and things work neatly in FCEUX and puNES, while I get a different behavior in Mesen and Nintendulator. One thing I noticed is that Mesen and Nintendulator has the exact same "different behavior", which convinces me that this is a pretty simple "gotcha" issue with the MMC5.
The issue happens in the IRQ handler, I've taken screenshots on the title screen to show:
That checkers floor at the bottom of the title screen is in a second nametable (image) and the IRQ is set to trigger at scanline 193. When it triggers, it writes $0B and $00 to the PPUADDR ($2006) to make the PPU jump to the place where the checkers floor tiles are laid out, imposing it there in the same way you'd impose a status bar.
But for some reason I can't explain Mesen and Nintendulator manages to place the checkers floor board at the top of the screen. This could very well be the correct behavior while FCEUX and puNES are wrong. But I'm still pretty puzzled over what's going wrong. It somehow smoothly switches back to the first nametable after the checkered floor.
Experimenting a bit, I commented out the two writes to the PPUADDR, so that the IRQ still triggers at scanline 193 but doesn't make the PPU switch which tiles it's painting, and now I get consistent behavior between all 4 emulators (but obviously the floor becomes black instead of showing the checkers tiles).
So, unless I'm on a wild goose case, the problem seems to be specifically with writing to the PPUADDR during the IRQ interrupt, but only for the MMC5 and not the MMC3. Doing this PPUADDR trick on the MMC3's IRQ handler does not cause the same issue on any emulator.
Does anybody know how these emulators treat MMC5 differently, and what might be causing this behavior?
I've already managed to get everything to work, from the banking switches to the IRQ stuff. However, I realized to my dismay that different emulators are behaving differently on me. I assume it's because MMC5 is a pretty complex mapper and not all emulators are in complete agreement about how it should behave.
I've tested four emulators now, and things work neatly in FCEUX and puNES, while I get a different behavior in Mesen and Nintendulator. One thing I noticed is that Mesen and Nintendulator has the exact same "different behavior", which convinces me that this is a pretty simple "gotcha" issue with the MMC5.
The issue happens in the IRQ handler, I've taken screenshots on the title screen to show:
That checkers floor at the bottom of the title screen is in a second nametable (image) and the IRQ is set to trigger at scanline 193. When it triggers, it writes $0B and $00 to the PPUADDR ($2006) to make the PPU jump to the place where the checkers floor tiles are laid out, imposing it there in the same way you'd impose a status bar.
But for some reason I can't explain Mesen and Nintendulator manages to place the checkers floor board at the top of the screen. This could very well be the correct behavior while FCEUX and puNES are wrong. But I'm still pretty puzzled over what's going wrong. It somehow smoothly switches back to the first nametable after the checkered floor.
Experimenting a bit, I commented out the two writes to the PPUADDR, so that the IRQ still triggers at scanline 193 but doesn't make the PPU switch which tiles it's painting, and now I get consistent behavior between all 4 emulators (but obviously the floor becomes black instead of showing the checkers tiles).
So, unless I'm on a wild goose case, the problem seems to be specifically with writing to the PPUADDR during the IRQ interrupt, but only for the MMC5 and not the MMC3. Doing this PPUADDR trick on the MMC3's IRQ handler does not cause the same issue on any emulator.
Does anybody know how these emulators treat MMC5 differently, and what might be causing this behavior?