barnacle wrote:
Does this let you use a stack frame? So you would define variables on your (much larger) stack so that input variables remain at a fixed offset above the current stack pointer, and local variables appear below the stack pointer?
Yup, that's exactly using the Direct Page as a stack frame. Which (if my memory works - but it's been a while) is very similar to how the 16bit x86 BP register was used.
I guess it's convention but I would setup everything to appear above the stack pointer in memory (i.e. inside the stack). So my Direct Page calculation would be:
on entering a function from a JSR / JSL
transfer the Stack Pointer address to A
subtract the amount of memory I need for local variables
transfer A back to the Stack Pointer
and then
push the Direct Page (so I know what it was previously)
transfer A to the Direct Page
The assembly would look something like this:
Code:
FunctionThatDoesStuff:
;preamble
TSC
SEC
SBC #_Local_Variable_Space_needed
TCS
PHD
TCD
Having all local variables and arguments inside the stack means the stack can still be used. Specifically for registers that can only be accessed via the stack: PHB, PLB, PHP, PLP and PHK
For completeness cleaning up and returning from the function is a bit more complicated because the return address for RTS / RTL needs to be the last thing popped off the stack (but unfortunately it sits after any arguments that were pushed)
Assuming a long return:
load A with return address (low and high bytes)
store A over the (first+1) bytes of argument
load A with return address (high and bank bytes)
store A over the first bytes of argument
then
pull the Direct Page
transfer the Stack Pointer address to A
add the amount of memory needed for local variables less 3 bytes
transfer A back to the Stack Pointer
return long
Again the assembly would look like
Code:
;postamble
LDA <_Local_Variable_Space_needed+2 ;RTL hi, RTL lo
STA <_Arguments-1
LDA <_Local_Variable_Space_needed+1 ;RTL b, rtl hi
STA <_Arguments-2
PLD
TSC
CLC
ADC #_Arguments-3
TCS
RTL