I would like to return to this topic, now that I am about to begin to transcript the FisherTechnick CPC Basic listings to IS-BASIC.
Let's say that we can make a mixed Basic-MachineCode program on the Enterprise.
One of the most valuables tools to make a subroutine aware of its position is to pass it its own start address. This method was hinted to me
some time ago by Zozo:
If the machine code subroutine has been defined with MC=HEX$("XX,XX,...") then, we can use CALL USR(MC,MC) to pass its start point on the HL register pair. The only drawback is that we lose the option to pass data to the subroutine.
This would be convenient on short routines with a few jumps/calls or fixed positions. But the problems multiply with long code, all the juicy options of the Z80 involve absolute addressing, and it can be a problem to repositioning all the jumps and calls inside a big program.
A solution that I have found is one that has been there all the time: WORD$.
Imagine we have written a MC subroutine to print a text on the screen, for example:
start: ld a, 0 ;Channel to write
ld bc, 5 ;Length of the string
ld de, STRING ;Adress of the string
EXOS 8 ;Write block
ret
STRING: db "Hello"
The Basic program would look like this:
100 ALLOCATE 16
110 CODE TEXTO=HEX$("3E,00,01,05,00,11,XX,XX,F7,08,C9,48,65,6C,6C,6F")
120 CALL USR(TEXTO,0)
But this routine will not work, because we need to give DE the absolute address of the string, which we don't know.... but we already know it, if we modify the line 110:
110 CODE TEXTO=HEX$("3E,00,01,05,00,11")&WORD$(TEXTO+11)&HEX$("F7,08,C9,48,65,6C,6C,6F")
TEXTO is already defined at the start of the line, so when the execution reaches "WORD$(TEXTO+11)" it doesn't give "*** Variable not initialised."
[ Guests cannot view attachments ]
Please don't laugh too hard at me if this is common knowledge....