
One of the issues when writing code to go into an MTX ROM is calling a subroutine which happens to be in a different ROM.
The standard MTX ROMs have a number of solutions for special cases, but the challenge here is to write a completely general purpose routine.
CHALLENGE 1:
Write the routine FARCALL, such that the following code will work:
Code: Select all
; Subroutine A in ROM A
;
sub_a: ...
...
call FARCALL ; Transfer execution to sub_b
db rom_b
dw sub_b
... ; sub_b returns here, preserving registers
...
ret
;
; Subroutine B in ROM B
;
sub_b: ... ; All registers have the same value as when FARCALL called
...
...
ret ; Return to sub_a, preserving all registers
- All registers except PC and SP should have the same value when execution of Subroutine B starts as they had when Subroutine A called FARCALL.
- All registers except PC and SP should have the same values when execution of Subroutine A resumes as they had when Subroutine B returned.
Extra points for small or fast code.
CHALLENGE 2:
As for the above, except that FARCALL must be re-entrant, so that the following code also works:
Code: Select all
; Subroutine A in ROM A
;
sub_a: ...
...
call FARCALL ; Transfer execution to sub_b
db rom_b
dw sub_b
... ; sub_b returns here, preserving registers
...
ret
;
; Subroutine B in ROM B
;
sub_b: ... ; All registers have the same value as when FARCALL called
...
call FARCALL ; Transfer execution to sub_c
db rom_c
dw sub_c
... ; sub_b returns here, preserving registers
...
ret ; Return to sub_a, preserving all registers
;
; Subroutine C in ROM C
;
sub_b: ... ; All registers have the same value as when FARCALL called from sub_b
...
...
ret ; Return to sub_b, preserving all registers
I have at least one solution to this challenge (and therefore also challenge 1), but I don't know whether it is the best.
CHALLENGE 3:
Can you find a solution using less high memory by making use of any of the existing routines in the MTX ROMs.
I don't know whether there is a solution to this.