The CPU will try to push to a full stack or pull from an empty stack if you tell it to, not caring that it is trashing things. Sometimes it is easy to tell where the stack begins - you look for a TCS command. For example, this is the beginning of Seiken Densetsu 3, where we see the stack pointer being initialized to $00FF:
Code: Select all
FF00 CLC
FF01 XCE
FF02 REP #$10
FF04 REP #$20
FF06 LDA #$00FF
FF09 TCS
Is anyone aware of any SNES games that do not initialize the stack pointer? Is it known whether its value is stable on reset? Whatever it may happen to be, I think the emulator can consider the SP having that value an "empty" stack to protect against stack underflow, but protecting against stack overflows seems more difficult:
As we know that the stack grows towards zero, it appears to be allocated in page zero in SD3. That's easier to see here; it's the 00 in $00FF. On the 65816 the stack pointer need not be confined to page one like the 6502, but it is confined to bank zero. But bank zero is also where non-stack things like hardware vectors live, so a stack overflow warning when the stack pointer becomes equal to its initial value again seems very late in the game; something likely to protect against recursive functions gone haywire, but not much else. What else can be done to figure out where non-stack things live? Look for RTI? That generally tells you where the NMI handler ends. What about where it begins, look in the source code for where the VECTOR segment is? That has the address for where all of the COP, BRK, ABT, NMI, RST, IRQ handlers live, but feels like a kludge. I can't really think of an easy way to implement this.