Dropped it in, it doesn't appear to have broken anything!
Meanwhile, a little macro abuse. For reasons I don't know, my assembler doesn't have an override (that I can find) that will let it generate three-byte absolute,x instructions when the address is less than $100. Since I use the x register as a pointer to the local stack, I need that ability whenever I store local variables on the stack.
In most cases, zero page addresses can be used, or shared, for local variables without overlap, but there are half a dozen routines which need to be called recursively and have more than one local 16-bit variable. Pushing and popping works well enough for a single variable, but is a pain once you get past there. It's also handy to be able to refer to a named variable... hence:
Code: Select all
; stack looks like:
; caller param 1 hi ; 0x0105,x
; caller param 2 lo ; 0x0104,x
; return address hi
; return address lo
; pushed x ; stack pointer copied to x
; param 1 hi ; 0x0100,x
; param 1 lo ; 0x00ff,x
; param 2 hi ; 0x00fe,x
; param 2 lo ; 0x00fd,x
; ... ...
LDAZXHI macro p1
db 0xbd
db lo (0x100 - ((p1 - 1) * 2))
db hi (0x100 - ((p1 - 1) * 2))
endm
LDAZXLO macro p1
db 0xbd
db lo (0xff - ((p1 - 1) * 2))
db hi (0xff - ((p1 - 1) * 2))
endm
STAZXHI macro p1
db 0x9d
db lo (0x100 - ((p1 - 1) * 2))
db hi (0x100 - ((p1 - 1) * 2))
endm
STAZXLO macro p1
db 0x9d
db lo (0xff - ((p1 - 1) * 2))
db hi (0xff - ((p1 - 1) * 2))
endm
And in use:
Code: Select all
PUSH $1234 ; caller private
PUSH $5678 ; caller parameter
jsr test
pla
pla
pla
pla
test:
first_p equ 1
second_p equ 2
phx
tsx
PUSH $9ABC ; first_p
PUSH $DEF0 ; second_p
lda CALLER_LO,x
lda CALLER_HI,x
LDAZXHI first_p
LDAZXLO first_p
LDAZXHI second_p
LDAZXLO second_p
lda #0
STAZXHI first_p
STAZXLO first_p
STAZXHI second_p
STAZXLO second_p
plx
plx
plx
plx
plx
rts
And a chunk of generated code
Code: Select all
PUSH $DEF0 ; second_p
ec0d : a9de > lda # hi $DEF0
ec0f : 48 > pha
ec10 : a9f0 > lda # lo $DEF0
ec12 : 48 > pha
ec13 : bd0401 lda CALLER_LO,x
ec16 : bd0501 lda CALLER_HI,x
LDAZXHI first_p
ec19 : bd > db 0xbd
ec1a : 00 > db lo (0x100 - ((first_p - 1) * 2))
ec1b : 01 > db hi (0x100 - ((first_p - 1) * 2))
LDAZXLO first_p
ec1c : bd > db 0xbd
ec1d : ff > db lo (0xff - ((first_p - 1) * 2))
ec1e : 00 > db hi (0xff - ((first_p - 1) * 2))
LDAZXHI second_p
ec1f : bd > db 0xbd
ec20 : fe > db lo (0x100 - ((second_p - 1) * 2))
ec21 : 00 > db hi (0x100 - ((second_p - 1) * 2))
LDAZXLO second_p
ec22 : bd > db 0xbd
ec23 : fd > db lo (0xff - ((second_p - 1) * 2))
ec24 : 00 > db hi (0xff - ((second_p - 1) * 2))
ec25 : a900 lda #0
STAZXHI first_p
ec27 : 9d > db 0x9d
ec28 : 00 > db lo (0x100 - ((first_p - 1) * 2))
ec29 : 01 > db hi (0x100 - ((first_p - 1) * 2))
(Just a chunk from the middle, for brevity, but to show all accesses)
Neil