I'm not really sure what OP wants here. If you literally want:
move #2,X
jsr "routine(X)"
just do
bsr routine2
If you want to decide at some part of the code whether to later call routine1
or routine2
, I would load that address into an address register and call that whenever you need to (in most circumstances, you should not run short of address registers -- but you have to carefully keep track which register you use in what parts of your code)
; under some condition:
lea routine1(PC),a4
; under another condition:
lea routine2(PC),a4
; later:
jsr (a4)
If you have a variable (in memory or inside a register) and want to call one of two subroutines depending on its value, do some branching like:
tst.w d0 ; lets assume for d0==0 we call routine1, otherwise routine2
bne.s \callr2
bsr routine1
bra.s \continue
\callr2:
bsr routine2
\continue:
; more code
If more code
is just a rts
, replace bne.s \callr2
by bne routine2
and bsr routine1
by bra routine1
(i.e., a tailcall).
Third alternative, if you have a range of values in d0
and you want to branch to a specific method depending on that value, that would be a jump-table, which can be implemented like this (assuming all routines are within a 16bit address range -- you also need to verify that d0
does not contain a value outside the size of your jumptable):
add.w d0,d0 ; multiply d0 by two
move.w jumptable(PC,d0.w),d0 ; d0 contains the offset relative to `jumptable`
jsr jumptable(PC,d0.w) ; do the actual function call
; more code -- if this is just a `rts` use `jmp` instead of `jsr`
; somewhere else:
jumptable:
dc.w routine0-jumptable, routine1-jumptable, routine2-jumptable, ...
If additionally, all routines are exactly the same size (ideally a power of two -- maybe after some padding, or using some trampolines if necessary), you could also directly jump to something like PC+offset+d0*size_of_method
:
lsl.w #4,d0 ; d0 = 16*d0
jsr routine0(PC,d0.w) ; PC = routine0+d0
; more code
routine0:
; exactly 16 bytes of code
routine1:
; exactly 16 bytes of code
routine2:
; exactly 16 bytes of code
routine3:
; (last method could be arbitrary long)