home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
utils
/
asmutl
/
relocate.tut
< prev
next >
Wrap
Text File
|
1994-07-13
|
3KB
|
56 lines
TUTORIAL NOTES ON RELOCATABLE CODE
To relocate any code, one identifies the source (where the code is
coming from), the destination (where it's going), and the size (how much
code to move). The common program sequence is:
LD HL,SOURCE
LD DE,DEST
LD BC,SIZE
LDIR
The difficulty arises in that the program in low memory being moved to
high memory will have all its addresses defined by its low memory location.
Programmers have used several successful techniques to compensate for this.
The technique I've gotten accustomed to is the use of offsets. An offset
is provided for every address that is referenced ABSOLUTE but is not
provided for any address referenced RELATIVE. All JP and CALL commands
require an absolute address. All JR and DJNZ commands require a relative
address. A specific address may occasionally require both. Consider as
an example the code below:
OU EQU DEST-SOURCE ; offset
CONIN EQU $+OU ; conin - relocated address (absolute)
CONINL: ; conin - local address (relative)
CALL CONST ; call console status check
JR Z,CONINL ; loop until status says we're ready
CALL 0F600H ; get the byte using upper bios
CP 9BH ; see if it's CMND-F1
JR NZ,CN9C ; (continuous pop-up clk display)
LD A,(CLKFLG) ; prepare to toggle the pop-up flag
CPL ; complement the accumulator
LD (CLKFLG),A ; store the toggled flag
JR CONINL ; go back for next input
CN9C: CP 7FH ; see if it's a "delete"
RET NZ ; if not, return with it the input byte
LD A,08h ; if yes, transform it into ^H
RET ; done with CONIN
CLKFLG EQU $+OU
DB 0 ; flag to see if clock display requested
In this example, CONIN is the absolute address and CONINL is the same
location but in relative terms. The relative address is needed to
support the JR Z,CONINL command. The absolute address is needed to
support the JP CONIN in the bios jump table. Similarly, CLKFLG
is an absolute address because it's the object of a LD A,(CLKFLG)
instruction, while CN9C is a relative address because it's the object
of a JR NZ,CN9C instruction.
The offset is always the difference between the final location
(destination) and the local location (source). Since the $ operand
is by definition the local location, $+OU expands to:
$+OU = ($) + (OU)
= (LOCAL_LOC) + (FINAL_LOC - LOCAL_LOC)
= FINAL_LOC
Hope this helps. R.Gaspari.