"Pass by reference" with a data stack
Posted: Mon Jan 30, 2023 3:10 pm
So I have this little routine:
"R0" is a 16bit pseudo-register in ZP. Somewhere in ROM there's an asciiz message constant.
I call the routine like this:
This is works perfectly well. However, for unrelated reasons, my firmware code is starting to get unwieldy, and I thought now would be a good time to implement a ZP data stack like Garth describes and rewrite some of my routines. The ones like _LCD_chrout that just take a byte in .A I will leave alone. But _LCD_strout seemed like a good candidate for reworking, since it takes an address, and is called randomly from all over the place (in addition to using it for output, I also stick it in various places for debugging) which means nothing else can ever use R0, in case a string output call steps on it.
So I'd like to do something like this:
My question is, is there some way to leave the address on the stack while indexing into the string? It seems like I need the equivalent of (STACK,x),y in order to index into the string, and it is not obvious to me how to express that. If I have to pull the address off the stack and into a scratchpad variable it seems like I might as well just keep on using the "pseudo register."
(I have read Garth's page about the magic of inlining parameters, but I'd like to do it this way first, if there is a way.)
Code: Select all
_LCD_strout:
ldy #0
LCD_strout_nextchar:
lda (R0),y
beq LCD_strout_return
jsr _LCD_chrout ; sends the character in .A to the LCD
iny
jmp LCD_strout_nextchar
LCD_strout_return:
rts
Code: Select all
R0 = $80
R0L = $80
R0H = $81
.org $8000
message: .asciiz "Hello, world"
Code: Select all
lda #<message
sta R0L
lda #>message
sta R0H
jsr _LCD_strout
So I'd like to do something like this:
Code: Select all
STACK = $0
STACKL = $0
STACKH = $1
reset:
ldx #$FF
txs ; Hardware stack -> $01FF
dex ; Data stack -> $00FE
; (later on)
lda #<message
sta STACKL,x
lda #>message
sta STACKH,x
dex
dex
jsr _LCD_strout
Code: Select all
_LCD_strout: ; Stack version
ldy #0
inx
inx
LCD_strout_nextchar:
lda (STACK,x),y ; what really goes here?
beq LCD_strout_return
jsr _LCD_chrout ; sends the character in .A to the LCD
iny
jmp LCD_strout_nextchar
LCD_strout_return:
rts