I was trying to learn how the Sega Master System works. The NMI occurs when the pause button on the console is pressed. So I wrote an NMI handler that makes a beep when the NMI occurs, then waits for the user to press A and B at the same time to return from NMI. But I've noticed that pressing the pause button again results in execution jumping back to the start of NMI (&0066
) since I can hear the beep again. The NMI is the only code in my program that calls the necessary code to make the beep.
But what's really strange is that pressing A+B only once will return from NMI immediately, regardless of how many times I've triggered NMI by pressing the pause button. I would have expected to have to press the A+B buttons an equal number of times to the amount of times I "paused" the game, but that's not what happens. Instead execution returns immediately as if I only paused once (I can tell it returned immediately because in my main program the tile graphics are displaying the buttons being pressed and the response is immediate.) Not only that, the stack pointer isn't changing after returning either.
So here's my question: How come I'm getting multiple beeps which means multiple NMIs that are nested, yet pressing A+B to return acts as though I only had one NMI?
The NMI code. (At &0066
is a jump to this routine.)
nmiHandler:
pushall ;macro that pushes all registers
ld a,&40
call ChibiSound
call Delay16_Unsafe
xor a
call ChibiSound ;these lines cause the beep, they're not really relevant.
WaitForUnpause:
call Player_ReadControlsDual ;get player 1 input into H.
bit 5,h ;was B pressed?
jr nz,WaitForUnpause ;if not, keep waiting
bit 4,h ;was A pressed?
jr nz,WaitForUnpause ;if not, keep waiting
popall ;macro that pops all registers
retn
WaitForUnpause
.