JMPing indirectly...but needing to JSR...

Started by xlar54, January 13, 2008, 03:34 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

xlar54

I have a case where I need to use JMP's indirect ability, but in a manner similar to JSR/RTS, such as

1F00  do something...
1F40  JMP ($138A)    <--- Jumps to address pointed to by $138A
1F45  continue on...   <---- but i want to somehow come back here when done

Problem is, I want to be able to come back after doing the extra work...much like a JSR/RTS.  Can I somehow use PHP to save where I am, so that I can JMP back to where I came from?  JSR/RTS is what I really need to do, but I need to do it indirectly.

nikoniko

#1
You can manually push the address you want to return to, minus one, on the stack, in this case $1F44. Then when you want to return from the JMPed to code, use an RTS. The RTS gets its return address from the stack, so it will pull whatever you put there ($1F44) and continue from the next address ($1F45).

Eg.,


        LDA #>continue
        PHA
        LDA #<continue-1
        PHA
        JMP (wherever)
continue:
        blah blah blah
....
wherever:
        blah blah blah
        RTS

hannenz


this is right but your posted code should better read like


    lda #>(continue-1)
    pha
    lda #<(continue-1)
    pha
    ...

just in case continue would be e.g. $1000, then your code would produce

    lda #$10
    pha
    lda #$ff
    pha

instead of

    lda #$ff
    pha
    lda #$ff
    pha



nikoniko

Thanks for the correction! I knew I shouldn't post code at 4AM with blurry eyes and no sleep. :D

BigDumbDinosaur

Naw, you guys are making it too difficult with the stack acrobatics.  First, code the following subroutine:

myjsrfar stx vector+1       ;store JSR target address lo
         sty vector+2       ;ditto for high
vector   jmp $0000          ;take the jump

Now, to actually use this:

         ldx #<jsrtarget    ;jsr target lo
         ldy #>jsrtarget    ;jsr target hi
         jsr myjsrfar       ;off you go!

Works like a charm and runs no risk of spanking the stack and causing a crash.  Any questions?
x86?  We ain't got no x86.  We don't need no stinking x86!

hannenz

if one likes self-modifying code...... but you know that there are situations were selfmod is not possible (e.g. ROM)
for my taste i like the stack manipulation more than selfmodding, but thats a matter of taste...

wte

You also can use a jump table:

table:
jmp (wherever1)
jmp (wherever2)
jmp (wherever3)
...

...
do something
jsr (table+0)
continue doing
...

...
wherever1:
do subroutine
RTS
...


So you dont't have to mess around with registers or the stack.

WTE

smf

Quote from: wte on January 15, 2008, 08:31 AM
You also can use a jump table:

yeah, much better although it's much simpler to use a label for each jmp:

jsr table0
jsr table1
jsr table2
rts

table0: jmp (address0)
table1: jmp (address1)
table2: jmp (address2)

If you want to save a few cycles then instead of putting the vector at the specifed address, you could put the jmp instruction itself at that address.

wte

Quote from: smf on January 15, 2008, 08:54 AM
yeah, much better although it's much simpler to use a label for each jmp:

Yeah, but I also didn't want to mess around with labels ;)

Otherwise I had something used like this:

;jump table
i_wherever1: jmp (wherever1)
i_wherever2: jmp (wherever2)
i_wherever3: jmp (wherever3)
...

...
do something
jsr (i_wherever1)
continue doing
...

...
wherever1:
do subroutine
RTS
...


WTE

BigDumbDinosaur

Quote from: hannenz on January 14, 2008, 09:17 PM
if one likes self-modifying code...... but you know that there are situations were selfmod is not possible (e.g. ROM)
for my taste i like the stack manipulation more than selfmodding, but thats a matter of taste...
So, pick a pair of locations for an indirect jump if you want ROMmable code.  Locations $03FE and $03FF are unused in both the C-64 and C-128.  Change JMP $0000 to JMP ($03FE) in the above code and store the JSR target into those locations.  Try not to make something simple so complicated.  <Grin>
x86?  We ain't got no x86.  We don't need no stinking x86!