Espozo wrote:Honestly, I never even use the stack. I originally wanted to use it to store information that would be loaded for the subroutine I was jumping to, but because it stores the value of where you jumped, it's pretty much useless for this, which is about the only thing I would use it for.
I can't find the document anymore, but I was just reading about stack-relative addressing and ways to use it to pass variables to a subroutine. Here's a crude example that I'm probably doing wrong but should work:
Code: Select all
jsr subroutine
.dw value1
.dw value2
returnlabel:
jmp _done
subroutine:
plx ;take the return address back off the stack
inx ;this might not be needed can't remember if jsr pushes return address or return address -1
lda.w $0000, x ;read the first .dw into A
inx
inx
ldy.w $0000, x ;read the second .dw into Y
[...]
jmp returnlabel ;jmp back instead of rts, because the return address is no longer on the stack
Alternately, I guess you can just push all your variables, JSR, pull the return address and store it, pull all the variables off, then push the return address again. That sounds like a better idea. (EDIT: The code I wrote is stupid since it jmps back, it's not a proper subroutine. What you could do to make it work is pass #returnlabel into the subroutine as another .dw, and use it at the end to return.)
My understanding is that using the stack like that may not save in cycles but you might eliminate the need to allocate a variable to store it to? I don't know, I tried to look up a quick example but it seems like there's a dozen different ways of doing this. It didn't seem worth getting into to me...
However, the stack is great for preserving a register you want to restore later. Mostly at the start and end of subroutines and interrupts, but here and there I'll just push A X or Y when I need the register but I'm going to need the value again in a bit, generally only when there's a straight path for the code to follow so you never forget to pull again...