Relocating MTX Machine Code
Posted: 25 Mar 2019 16:07
This arose from a question Paul asked me.
If writing a program containing mixed Basic and Machine Code, the first line of the program typically looks something like:
This works fine when working on a single machine. However, if you move the code onto a machine with a different amount of memory (32K or 64K) and try and run it, it will fail because all the subroutine calls (and long jumps) are to the wrong address. Before running the code on a different amount of memory you normally have to do "ASSEM 10", and then exit the assembler again to update all the addresses.
I have now worked out how to get the MTX do this automatically. Change the start of the Machine Code to:
(Edit to fix a minor issue with the code above.)
It is still necessary to take account of the entry points changing, so the next two lines of the program should probably be something like:
And the Machine Code calls similar to:
If writing a program containing mixed Basic and Machine Code, the first line of the program typically looks something like:
Code: Select all
10 CODE
4007 RET ; Do nothing when executed
4008 JR ENCODE ; Jump table to M/C routines
400A JR DECODE
I have now worked out how to get the MTX do this automatically. Change the start of the Machine Code to:
Code: Select all
10 CODE
4007 JR REBASE ; This must be JR not JP
4009 JR ENCODE ; Jump table to M/C routines
400B JR DECODE
400D REBASE: LD DE,#FFF9 ; On entry HL contains start address
4010 ADD HL,DE ; We want the start of CODE line, which is 7 bytes earlier
4011 CALL #1BE3 ; Call ROM routine CODETEST (Enter assembler)
4014 RET NZ ; This should never happen
4015 LD A,(#FAD2) ; We now need to call a routine in ROM page 1
4018 PUSH AF ; Save old PAGE register
4019 AND #0F ; Select page 1
401B OR #10
401D LD (#FAD2),A ; Update page register
4020 OUT (#00),A
4022 CALL #2277 ; Call ROM routine LINK (Exit assembler and update addresses)
4025 POP AF ; Restore page register
4026 LD (#FAD2),A
4029 OUT (#00),A
402B RET
; Other M/C routines go here
It is still necessary to take account of the entry points changing, so the next two lines of the program should probably be something like:
Code: Select all
20 LET BASBOT=16384
30 IF (PEEK(64122)=0) THEN LET BASBOT=32768
Code: Select all
3010 LET XERR=USR(BASBOT+11)