Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

The Mpm assembler generates the relocation table, when parsing the source code for compilation of the binary executable code. The relocator routine that is used by Mpm is made available here for convenience:

Code Block
themeEclipse
languagenone
 MODULE relocatorXDEFrelocator
 XDEF relocator, SIZEOF_relocator

; *************************************************************************
;
; This routine will relocate a machine code program.
; A relocation table is placed immediatly after the relocation routine.
;
; The program that is to be relocated and executed are placed immediately
; after the relocation table.
;
; The relocation routine expects IY to point at the start address, entry
; of the relocater. The relocater then calculates the correct origin for
; the relocated program. The BBC BASIC on the Z88 also setups the IY register
; during a BBC BASIC CALL command to execute local machine code.
;
; After completed relocation, the entry of the relocater is patched to
; JP  which jumps directly to the executing program, if the relocated
; code is called again.
;
; The following registers are affected by the initial relocation process:
;         AFBCDEHL/IX../........ same
;         ......../..IY/afbcdehl different
;
; As indicated above the outside world cannot use the alternate registers
; as parameter interface to the relocated program - they are smashed by the
; relocater.
;
.relocator          ex
  af,af'      ex   af,af'          ; preserve AF       ; preserve  AF
          exx                           ; preserve BC, DE, HL
        push iy
        pop  pushhl
iy        ld   bc, #end_relocator-relocator

        popadd  hl,bc                    ; ldabsolute address of bc, #end_relocator-relocatorrelocation table

        ld   e,(hl)
        addinc  hl,bc
        ld   d,(hl)
       ; absolutepush addressde of relocation table                    ; DE ld= total of relocation offset e,(hl)elements
        inc  hl
        ld inc  c,(hl)
        inc   hl
        ld   db,(hl)                   ; total pushsize deof relocation offset elements
        inc  hl
        ;push DEhl = total of relocation offset elements                 ; preserve pointer to incfirst relocation hloffset element
        add  hl,bc
        ld   c,(hl)b,h                      inc; HL hl= pointer to current relocation address
        ld   c,l    ld   b,(hl)               ; BC = program ;ORG, totalfirst sizebyte of relocationprogram
offset
elements.relocate_loop
        ex   (sp),hl         inc  hl       ; HL = pointer to relocation offset element
      push hl ld   a,(hl)
        inc  hl        ; preserve pointer to first relocation offset element        ; ready for next relocation offset pointer
      add  hl,bcor   a
        jr   nz, byte_offset
.extended_offset    ld   b,h  
        ld   e,(hl)
       ; HLinc = pointerhl
to current relocation address      ld   d,(hl)            ld   c,l    ; DE = extended offset pointer to next relocation address
        ;inc BC =hl program ORG, first byte of program  .relocate_loop           ex   (sp),hl ; ready for next relocation offset pointer
        jr  ; HLrelocate_address
= pointer to relocation 
.byte_offset
element        ld   d,0
        ld   e,a   ld   a,(hl)                ; offset pointer to next relocation address
.relocate_address
  inc  hl    ex   (sp),hl                  ; HL = readypointer forto nextcurrent relocation offsetaddress
pointer        add  hl,de                or   a ; new pointer at memory that contains relocation address
        ld   e,(hl)
    jr   nz, byte_offset
.extended_offset inc  hl
        ld   ed,(hl)
        ex   de,hl
        add  hl,bc   inc  hl               ; HL = address relocated to program ORG in BC
 ld   d,(hl)    ex   de,hl
        ld   ;(hl),d
DE = extended offset pointer to next relocation addressdec  hl
        ld   (hl),e            inc  hl     ; update relocated address back to memory

        pop  ;de ready for next relocation offset pointer                 ; DE = pointer to relocation offset
  jr   relocate_address  .byte_offset ex   (sp),hl         ld   d,0      ; HL = index counter
        dec  hl     ld   e,a               ; update index counter
   ; offset pointer to next relocationld address .relocate_address  a,h
      ex  or (sp),hl  l                ; HL = pointer to current relocation address ; all addresses relocated?
        ex   (sp),hl          add  hl,de      ; index counter back on stack
        ;push newde pointer at memory that contains relocation address                ; pointer to relocation offset back on stack
  ld   e,(hl)   jr   nz, relocate_loop
        pop  af
       inc pop hl af                       ; remove ldredundant variables

d,(hl); relocation of program completed. Patch the entry of the relocater to JP  that
; jumps directly to the executing program, if the loaded program exis executed again.
de,hl; Finish with restoring main registers and then execute program.
;
.relocation_finished
        ld      add(iy+0),$C3
  hl,bc      ld   (iy+1),c
        ld  ; HL = address relocated to program ORG in BC (iy+2),b                 ; patch entry to JP , the relocated program
        exexx   de,hl                        ; swap ldback to main (hl)BC,d DE, HL
        ex   af,af'            dec  hl     ; and main AF
        jp   (iy)      ld   (hl),e                   ; updateexecute relocated address back to memory

                         pop  de                       ; DE = pointer to relocation offset
                         ex   (sp),hl                  ; HL = index counter
                         dec  hl                       ; update index counter
                         ld   a,h
                         or   l                        ; all addresses relocated?
                         ex   (sp),hl                  ; index counter back on stack
                         push de                       ; pointer to relocation offset back on stack
                    jr   nz, relocate_loop
                    pop  af
                    pop  af                            ; remove redundant variables

; relocation of program completed. Patch the entry of the relocater to JP  that
; jumps directly to the executing program, if the loaded program is executed again.
; Finish with restoring main registers and then execute program.
;
.relocation_finished
                    ld   (iy+0),$C3
                    ld   (iy+1),c
                    ld   (iy+2),b                 ; patch entry to JP , the relocated program
                    exx                           ; swap back to main BC, DE, HL
                    ex   af,af'                   ; and main AF
                    jp   (iy)                     ; execute relocated program...
.end_relocator

     DEFC SIZEOF_relocator = end_relocator - relocator

; ******************************************************************************
;
; The relocation table is placed here by the Mpm assembler.
; The format of the generated table is:
;
;    total_elements    ds.w 1
;    sizeof_table      ds.w 1
;    patchpointer_0    ds.b 1  --+
;    patchpointer_1    ds.b 1    |
;    ....                        |  sizeof_table
;    ....                        |
;    patchpointer_n    ds.b 1  --+
;
; The first patch pointer is an offset from the start of the program (.routine)
; to the first position of a location that contains a relocatable address.
; The following patchpointers are relative offsets from the current relocated
; address to the next.
; If the offset distance is larger than 255 bytes between two relocatable
; addresses, the following patchpointer is used:
;
;         0,<16bit patchpointer>
;
; which denotes the an offset from the current relocated address to the next.
; The 16 bit patch pointer is stored in the low byte, high byte order.
;

.routine
; the machine code to be relocated is placed immediately after the relocation table

 

...

program...
.end_relocator

DEFC SIZEOF_relocator = end_relocator - relocator

; ******************************************************************************

...


;
; The relocation table is placed here by the Mpm assembler.
; The format of the generated table is:
;
;    total_elements    ds.w 1
;    sizeof_table      ds.w 1
;    patchpointer_0    ds.b 1  --+
;    patchpointer_1    ds.b 1    |
;    ....                        |  sizeof_table
;    ....                        |
;    patchpointer_n    ds.b 1  --+
;
; The first patch pointer is an offset from the start of the program (.routine)
; to the first position of a location that contains a relocatable address.
; The following patchpointers are relative offsets from the current relocated
; address to the next.
; If the offset distance is larger than 255 bytes between two relocatable
; addresses, the following patchpointer is used:
;
;         0,<16bit patchpointer>
;
; which denotes the an offset from the current relocated address to the next.
; The 16 bit patch pointer is stored in the low byte, high byte order.
;

.routine
; the machine code to be relocated is placed immediately after the relocation table