Direct Page Memory Access in NMI Handler

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
mrmu
Posts: 2
Joined: Tue Oct 01, 2024 11:27 am

Direct Page Memory Access in NMI Handler

Post by mrmu »

Hi everyone,

I started with building my own SNES emulator from scratch a few weeks ago. I'm making good progress and already get some graphics output.
However, today I stumbled across a problem that I don't really understand and hope, you guys can help me with.
I use SMW-U as my test ROM for development. For comparison, I read through this disassembly https://github.com/IsoFrieze/SMWDisX/bl ... ank_00.asm.

In the NMI handler of SWM, at code $00A488, the devs apparently use memory addresses $00-04 to store some temporary stuff. However, these addresses are not saved and restored. Since direct page access is used, these translate to $7E0000-$7E0004 in RAM.
These adresses are also used in other parts of the game's code, for example, in the routine that jumps to the current game mode.
When NMI gets called in such a routine, the memory at these addresses gets overwritten which leads to undefined behavior.

For example:

Code: Select all

// From game mode jump routine
PLY
STY.B _0
// -> NMI handler
...
RTI
...
LDA.B [_0],Y // This loads an incorrect value since $7E0000 was changed in the NMI handler
Obviously I'm missing something here. Is there anything that prevents this memory corruption I'm not aware of (different address space in NMI handler) or does it rely on the exact timing of VBlanks here? Thank you very much in advance!
Oziphantom
Posts: 1678
Joined: Tue Feb 07, 2017 2:03 am

Re: Direct Page Memory Access in NMI Handler

Post by Oziphantom »

I can't see any logic to change the Direct Page offset, so it probably just relies on everything running in a frame so they never corrupt each other.
mrmu
Posts: 2
Joined: Tue Oct 01, 2024 11:27 am

Re: Direct Page Memory Access in NMI Handler

Post by mrmu »

Thanks for your reply and having a look, too!
Today, I finally stumbled across the lines I was missing all the time:

Code: Select all

GameLoop:
    LDA.B LagFlag
    BEQ GameLoop
    ...
    STZ.B LagFlag
The "LagFlag" variable is incremented in the NMI handler. Therefore all loading code is guaranteed to run shortly after the handler and is therefore not in risk of collision.
Post Reply