Hello All ! Long time lurker
I used to have an id here I think but it's been so long..... I've read posts here for years mostly invisibly. You folks are awesome and I appreciate the website and forums esp. very much. Here's something I found from a few years ago while reading reading reading....
I don't know if it can still help the original poster Alarm Siren, it's such an old thread, but I think I see a solution that I did not see from anyone else. And it might add to the ideas for others.
Alarm Siren wrote:
So, here's a brain-tease:
I'm using X for a data stack pointer. All's well. If on the off chance I want to use X for something else, I can temporarily PHX/PLX whilst I do so. A little awkward if I want to call a subroutine that expects X to be the stack pointer whilst I'm using it for something else, but not insurmountable.
HOWEVER!
I have found a situation where I can't think of a solution....
Say I wanted a jump table, which I access using
Code:
LDX #02
JSR ?local
?local:
JMP (TableBase, X)
TableBase:
dw Function1
dw Fucntion2
dw Function3
Obviously I have to save X and put it back when Function2 returns, first otherwise I'll corrupt my stack pointer. However, what if Function2 expects to be able to use X as the data stack pointer? It won't contain it, it'll contain the function offset instead, and there's no opportunity for me to put X back before Function2 starts executing. Function2 could assume that it needs to fetch the stack pointer value off the hardware stack, but that involves a lot of moving things around to achieve and
means I can't generalise Function2 to situations where it isn't called from a jump table.Underlined quote. That's the trick really. To be able to use a vector table method AND inline method.
I thought of this :
Code:
PHX ; or STX zp_somewhere for NMOS
SEC ; flag indicating table method call !
LDX #2
JSR TABLECALL
BVC ?TBLSKIPJMP ; we keep V flag clear for pseudo BRA
?TABLECALL
JMP (TABLEBASE,X)
?TBLSKIPJMP
...<more code>
FUNCTION2:
BCC ?SKPTBL
PLX ; retrieve X stack ptr
?SKPTBL
...<function2 code matching inline method calls>
RTS
This way the Carry is used as a method flag whether inline or table, and very little extra code needed.
THEN I thought of this way -- If you named each function1,2,3 etc with their own assembly labels instead of one
top label, this is possible...
Code:
PHX
LDX #2
JSR -> JMP (TABLEBASE,X) ; for table method calls.
and only the PLX starting each function1,2,3,etc without BCC...
Then for inline function1,2,3 calls with each functions own label/symbol you can
Code:
LDX #2
JSR TABLEFUNCTION2 + 1 ; skips the PLX within the function. BCC never needed.
The latter format is best. One more byte per table method call, and a
assemble-time adjusted inline method call that costs nothing.
=peaceful world