home *** CD-ROM | disk | FTP | other *** search
- Name ('RELOCATE')
- Title Relocation Module
- Subttl Move a program to top of TPA and run it
- .Z80
-
- Extrn $MEMRY
-
- ;------------------------------------------------------------------------------
- ;
- ; R E L O C A T E
- ; ===============
- ;
- ; When linked at the head of a properly structured program, this module
- ; will move the program to the top of the TPA and transfer control to it.
- ;
- ; The program to be relocated MUST start with the following two items in
- ; the data segment:- (EXCEPTION - see version 2 notes below)
- ;
- ; Dseg ;Data segment
- ;
- ; $MEMRY::
- ; defs 2 ;LINK-80 will fill this in.
- ; ;Used by the relocator module
- ; ;to determine the length of the
- ; ;program.
- ;
- ; jp ntrypt ;where "ntrypt" is the address
- ; ;to which the relocator program
- ; ;will transfer control. The
- ; ;relocator will replace the
- ; ;jump address with the address
- ; ;of the BDOS
- ;
- ;
- ; Version 2 amendments:
- ; --------------------
- ;
- ; This program now supports a variety of destinations for the relocated
- ; code. The destination information is passed to this module in the
- ; 4th and 5th bytes by the self-relocating-program generator.
- ;
- ; If 5th byte (codest+1) is zero then the relocation is performed as in
- ; version 1, i.e. the program is moved to the top of free memory and
- ; executed. If the 4th byte (codest) is 0 then the program is loaded
- ; just below the BDOS and the BDOS jump at base+5,+6,+7 is modified to
- ; reflect a smaller TPA size. However, the SRP generator may set (codest)
- ; to -8 in which case the program is loaded below the CCP and the BDOS
- ; jump is not modified. This feature is useful for loading SRPs which
- ; exit to CP/M by returning control to the CCP instead of doing a warm
- ; boot via a jump to location base+0.
- ;
- ; If (codest+1) is 1 then (codest) is assumed to contain a page offset
- ; from the base of the BDOS (specifically -8, 0 or +14) which causes
- ; an overlay of the CCP, BDOS or BIOS. The relocator module does not
- ; transfer control to the relocated code but returns to CP/M via a jump
- ; to location CCP+3. This facility is particularly useful for generating
- ; a relocatable BIOS so that you may for example have a system disk with
- ; a fairly primitive BIOS but have a more sophisticated BIOS (perhaps too
- ; large to fit on the system tracks of a single-density disk) which loads
- ; from the data tracks. You can even test such a BIOS without going
- ; through a system generation!
- ;
- ; N.B. IN THIS CASE IT IS NOT NECESSARY TO HAVE A JUMP INSTRUCTION AT
- ; THE HEAD OF THE RELOCATABLE CODE.
- ;
- ; If (codest+1) is 2 or more then this module assumes that you want the
- ; program relocated to an address of your choosing. The BDOS jump is
- ; not modified.
- ;
- ; VERSION 2.1 16th November 1982
- ; Corrected CCP entry.
- ;
- ; VERSION 2.1 revisited 27th November 1982
- ; Corrected several problems in exit to CCP and to programs loaded
- ; below the CCP.
- ;
- ;------------------------------------------------------------------------------
-
- .comment \
-
- -------------------------------------------------------------------------------
-
- COPYRIGHT NOTICE (C) 1982 John Hastwell-Batten
-
- These programs have been submitted to the public domain via Bill Bolton's RCPM
- system and comprise a system for simply generating self-relocating programs by
- a method which relies on a linker to generate two object code files which are
- then processed to yield an object program consisting of a relocator, user-
- supplied object code and a relocation bitmap. These programs and the
- accompanying documentation may be freely distributed in original or modified
- form subject to the following conditions:
-
- 1. Although there is no restriction on the sale of self-relocating programs
- generated by the method described herein, these programs or variants
- thereof may not be sold as part of any program package without written
- permission from the author. Neither may any program or program package
- which is dependent for its operation on the use of this method be sold
- without such permission.
-
- 2. The author's name must be retained in all source code (original or
- modified) and as an acknowlegement in any message displayed by these
- programs or variant(s) thereof. An acknowledgement giving credit for the
- method shall contain the author's name or the words "H-B method" or the
- words "Ashby method".
-
- 3. This copyright notice must be included in and retained in all source code
- and documentation pertaining to this system.
-
- John Hastwell-Batten
- 38 Silvia Street
- Hornsby NSW 2077
- AUSTRALIA
- (02) 477 4225
-
- 1st November, 1982
-
- Acknowledgement
-
- In testing those relocations which overlay specified portions of CP/M I have
- made use of John Woolner's CCP protection scheme obtained via Bill Bolton's
- RCPM system. Without the CCP protection the verification of the relocator
- module would have been exceedingly difficult as the standard program testing
- tools all overlay the CCP which, in the case of the CP/M overlays, the
- relocator expects to be intact.
-
- ------------------------------------------------------------------------------\
-
- base equ 0 ;(Some CP/Ms start elsewhere)
- userdk equ base+4 ;Where CP/M keeps track of current
- ;user & disk
-
- aseg
- org base+100h
-
- @@relocate::
- jp $+5 ;Skip over address parameter
- codest:
- defw 0 ;Default is relocate to just below BDOS
-
- ld (ccpstack),sp ;Save caller's stack pointer
- ld sp,ccpstack ;Set up our own
-
- ld de,$memry+2 ;Address of start of code to DE
- ld hl,($memry) ;Address of end of code to HL
- xor a ;Clear borrow flag and A register
- sbc hl,de ;Calculate code length
- push hl ;Save code length
- sub l ;Set carry if length not a multiple
- ;of 256
- ld a,(base+7) ;BDOS base page number
- ld c,a
- ld a,(codest) ;Offset from BDOS
- sbc a,h ;Form code destination page number
- add a,c
- ld h,a ;Code destination page number to H
-
- ; Having got here, the address calculation will have been in vain if
- ; a code destination was specified, i.e. if code destination >= 100h.
- ;
- ; If code destination >= 200h then the destination is explicit and we
- ; load it directly from (codest+1,codest). If code destination is in
- ; the range 100h to 1FFh then (codest) is assumed to be an offset from
- ; BDOS. (Specifically, -8 to overlay CCP, 0 to overlay BDOS or 14 to
- ; overlay BIOS)
-
- ld a,(codest+1) ;Get destination address page number
- dec a ;Test it
- jp m,normal ; 0 => normal relocation
- jr z,implicit ; 1 => CCP, BDOS or BIOS overlay
- ld hl,(codest) ;>1 => explicit address
- jr normal
- implicit:
- ld a,(base+7) ;BDOS base page number
- ld c,a
- ld a,(codest) ;Add offset (-8 for CCP, 0 for BDOS
- add a,c ;or +14 for BIOS)
- ld h,a
- normal:
- ld l,0 ;HL now holds code destination address
- pop bc ;Retrieve code length
- push hl ;Save copy of address
- ex de,hl ;Destination address to DE,
- ;Source address to HL
- ld a,d ;Destination page number to A
- push bc ;Save code length
- ldir ;Move code up to top of TPA
- sub 2 ;Form bias
- defb 0fdh
- ld l,a ;Save in LY
- pop bc ;Recover code length
- pop ix ;Retrieve pointer to relocated code
- push ix ;Save a copy for BDOS entry
- @newrel:
- ld e,(hl) ;Get relocation flags in E
- inc hl ;Point at next 8 flags
- ld d,8 ;Counter
- @reloc:
- rlc e ;Move a relocation flag into carry
- jr nc,@asis ;No change if bit is off, otherwise...
- defb 0fdh
- ld a,l ;Retrieve bias
- nop ;[NOP is so ZSID won't screw up on the
- ; next instruction]
- add a,(ix+0) ;Add bias to address
- ld (ix+0),a ;Put back new address byte
- @asis:
- inc ix ;Point at next code byte
- dec bc ;Decrement code length
- ld a,b ;Test residual code length
- or c
- jr z,@done ;Exit if finished
- dec d ;Count relocation flags
- jr z,@newrel ;Get another set if all used up
- jr @reloc ;otherwise continue with this lot
- @done:
- ld hl,(base+6) ;Get BDOS vector
- pop ix ;Recover address of relocated code
- ld e,(ix+1) ;Get program entry point to DE
- ld d,(ix+2)
- ld a,(codest+1) ;Get code destination indicator
- dec a ;Explicit or implicit destination?
- jr z,@CCP ;If relocation overlayed CCP, BDOS
- ;or BIOS then simply exit to the CCP
- ld (ix+1),l ;Fix up the JP at the start of the code
- ld (ix+2),h
- jp p,@enter ;If explicit destination then don't
- ;modify the BDOS jump
- ld a,(codest) ;Check if relocated under CCP
- or a
- jr nz,@enter ;If so, leave BDOS jump alone
- ld (base+6),ix ;Otherwise, mark new TPA size
- @enter:
- pop hl ;Here we deliberately underflow our own
- ld sp,hl ;stack to pick up the stack pointer as
- ;it was when we started. This is to
- ;make the relocation invisible to those
- ;programs which RETurn to the CCP
- ;instead of ending with a warm boot.
-
- ex de,hl ;New start address to HL
- jp (hl) ;Transfer to relocated program
-
- @CCP: ld a,(userdk) ;Get current user number (high order
- ; four bits) & disk number (low-order)
- ld c,a ;.... then to C for CCP entry
- ld hl,(base+6) ;Get BDOS address
- ld l,0 ;Align to page boundary
- ld de,3-800h ;Offset to CCP entry
- add hl,de ;Address of CCP warm boot entry
- jp (hl) ;Exit to CCP
-
- defw 0,0 ;We don't need much stack space but we
- defw 0,0 ;can't use our caller's because we may
- ;overlay it!
- ccpstack:
- defw 0 ;Temporary hidey-hole for our caller's
- ;stack pointer. (Ordinarily, our
- ;caller would be the CCP.)
-
- end