This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Find the origin of a stack value

Find the origin of a stack value
by on (#99353)
I recently encountered a game that specifically uses a stack address value to store various variables etc. However, setting a write bp to the address does not yield what I want. How exactly do I find where something in the stack comes from? This is new territory for me.

LDA $0105,X @ $01FE = #$86
Re: Find the origin of a stack value
by on (#99355)
The stack is just memory, nothing else. The only difference is that this memory CAN be acceded with stack-related instructions (pha, pla, php, plp, jsr, rts) while it can also be acceded like normal memory (like in lda $105,X).

It's highly probable this instruction is precessed by a tsx instruction, which sets X to be equal to the stack pointer. Then $101,X will access the last pushed byte, $102,X the 2nd last pushed byte, etc.... Therefore, if precedded with tsx, this opcode will read the 5th byte in the stack.
If this is inside a subroutine, it could be reading the return address the caller pushed on the stack with the jsr instruction. Some games use this technique to pass many arguments to subroutines while using less bytes than by passing them through zero-page variables, as explained in this post.

I hope this was helpful.
Re: Find the origin of a stack value
by on (#99357)
Yes, you're right. There's a bunch of stack related code before the read.

$FBB2:48 PHA A:00 X:01 Y:10 S:FD P:nvUbdIZC
$FBB3:48 PHA A:00 X:01 Y:10 S:FC P:nvUbdIZC
$FBB4:8A TXA A:00 X:01 Y:10 S:FB P:nvUbdIZC
$FBB5:48 PHA A:01 X:01 Y:10 S:FB P:nvUbdIzC
$FBB6:98 TYA A:01 X:01 Y:10 S:FA P:nvUbdIzC
$FBB7:48 PHA A:10 X:01 Y:10 S:FA P:nvUbdIzC
$FBB8:BA TSX A:10 X:01 Y:10 S:F9 P:nvUbdIzC
$FBB9:BD 05 01 LDA $0105,X @ $01FE = #$86 A:10 X:F9 Y:10 S:F9 P:NvUbdIzC
Re: Find the origin of a stack value
by on (#99360)
The code must 'know' that the stack pointer is going to be at least set to $FA (5 items minimum on the stack). tsx / $105,x is the same access as popping 5 items. The code you posted only shows four items, did you miss a php opcode?

In your case $105,x will access $1FE as indicated.
Re: Find the origin of a stack value
by on (#99364)
The NMI in Galaxian starts with:
NMI:    PHA                     ; push A, X, Y onto stack (why? we prohibit reentering
        TXA                     ;  and we always call from the idle loop that keeps no state in them)
        TSX                     ; S -> X
        CPX #<stack             ; check if stack overflow
        BCC Error               ; carry = S>=$30
        LDA $0100+4,x           ; check 4 bytes above TOS i.e. flags
        AND #$18                ; check if BRK or DECimal was set
        BNE Error
        LDA $0100+6,x           ; check 6 bytes above TOS i.e. MSB of return addr
        CMP #>Reset             ; see where the NMI was called from
        BCC Error               ; carry = NMI called from 0xE000-0xFFFF
So I think [$0105+s] should be the LSB of the return address.
Re: Find the origin of a stack value
by on (#99371)
The code Pennywise shown has two PHA's (I have no idea why), which means, if this is inside an interrupt, that lda $105,X will return the saved status register. Just a guess : pehaps this is to differenciate between IRQ and BRK ?