Commodore 128 Alive!

Commodore 128 => 128 programmers => Assembly => Topic started by: xlar54 on January 13, 2008, 03:34 PM

Title: JMPing indirectly...but needing to JSR...
Post by: xlar54 on January 13, 2008, 03:34 PM
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.
Title: Re: JMPing indirectly...but needing to JSR...
Post by: nikoniko on January 13, 2008, 08:27 PM
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
Title: Re: JMPing indirectly...but needing to JSR...
Post by: hannenz on January 13, 2008, 11:50 PM

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


Title: Re: JMPing indirectly...but needing to JSR...
Post by: nikoniko on January 14, 2008, 04:58 AM
Thanks for the correction! I knew I shouldn't post code at 4AM with blurry eyes and no sleep. :D
Title: Re: JMPing indirectly...but needing to JSR...
Post by: BigDumbDinosaur on January 14, 2008, 12:51 PM
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?
Title: Re: JMPing indirectly...but needing to JSR...
Post by: 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...
Title: Re: JMPing indirectly...but needing to JSR...
Post by: wte on January 15, 2008, 08:31 AM
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
Title: Re: JMPing indirectly...but needing to JSR...
Post by: smf on January 15, 2008, 08:54 AM
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.
Title: Re: JMPing indirectly...but needing to JSR...
Post by: wte on January 16, 2008, 07:30 AM
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
Title: Re: JMPing indirectly...but needing to JSR...
Post by: BigDumbDinosaur on January 19, 2008, 10:28 AM
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>
EhPortal 1.34 © 2025, WebDev