home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol135 / reloc.mqc / RELOC.MAC
Encoding:
Text File  |  1985-02-10  |  9.9 KB  |  261 lines

  1.     Name    ('RELOCATE')
  2.     Title    Relocation Module
  3.     Subttl    Move a program to top of TPA and run it
  4.     .Z80
  5.  
  6.     Extrn    $MEMRY
  7.  
  8. ;------------------------------------------------------------------------------
  9. ;
  10. ;                R E L O C A T E
  11. ;                ===============
  12. ;
  13. ;    When linked at the head of a properly structured program, this module
  14. ;    will move the program to the top of the TPA and transfer control to it.
  15. ;
  16. ;    The program to be relocated MUST start with the following two items in
  17. ;    the data segment:-        (EXCEPTION - see version 2 notes below)
  18. ;
  19. ;            Dseg            ;Data segment
  20. ;
  21. ;        $MEMRY::
  22. ;            defs    2        ;LINK-80 will fill this in.
  23. ;                        ;Used by the relocator module
  24. ;                        ;to determine the length of the
  25. ;                        ;program.
  26. ;
  27. ;            jp    ntrypt        ;where "ntrypt" is the address
  28. ;                        ;to which the relocator program
  29. ;                        ;will transfer control.  The
  30. ;                        ;relocator will replace the
  31. ;                        ;jump address with the address
  32. ;                        ;of the BDOS
  33. ;
  34. ;
  35. ;    Version 2 amendments:
  36. ;    --------------------
  37. ;
  38. ;    This program now supports a variety of destinations for the relocated
  39. ;    code.  The destination information is passed to this module in the
  40. ;    4th and 5th bytes by the self-relocating-program generator.
  41. ;
  42. ;    If 5th byte (codest+1) is zero then the relocation is performed as in
  43. ;    version 1, i.e. the program is moved to the top of free memory and
  44. ;    executed.  If the 4th byte (codest) is 0 then the program is loaded
  45. ;    just below the BDOS and the BDOS jump at base+5,+6,+7 is modified to
  46. ;    reflect a smaller TPA size.  However, the SRP generator may set (codest)
  47. ;    to -8 in which case the program is loaded below the CCP and the BDOS
  48. ;    jump is not modified.  This feature is useful for loading SRPs which
  49. ;    exit to CP/M by returning control to the CCP instead of doing a warm
  50. ;    boot via a jump to location base+0.
  51. ;
  52. ;    If (codest+1) is 1 then (codest) is assumed to contain a page offset
  53. ;    from the base of the BDOS (specifically -8, 0 or +14) which causes
  54. ;    an overlay of the CCP, BDOS or BIOS.  The relocator module does not
  55. ;    transfer control to the relocated code but returns to CP/M via a jump
  56. ;    to location CCP+3.  This facility is particularly useful for generating
  57. ;    a relocatable BIOS so that you may for example have a system disk with
  58. ;    a fairly primitive BIOS but have a more sophisticated BIOS (perhaps too
  59. ;    large to fit on the system tracks of a single-density disk) which loads
  60. ;    from the data tracks.  You can even test such a BIOS without going
  61. ;    through a system generation!
  62. ;
  63. ;    N.B.  IN THIS CASE IT IS NOT NECESSARY TO HAVE A JUMP INSTRUCTION AT
  64. ;       THE HEAD OF THE RELOCATABLE CODE.
  65. ;
  66. ;    If (codest+1) is 2 or more then this module assumes that you want the
  67. ;    program relocated to an address of your choosing.  The BDOS jump is
  68. ;    not modified.
  69. ;
  70. ;    VERSION 2.1    16th November 1982
  71. ;    Corrected CCP entry.
  72. ;
  73. ;    VERSION 2.1 revisited    27th November 1982
  74. ;    Corrected several problems in exit to CCP and to programs loaded
  75. ;    below the CCP.
  76. ;
  77. ;------------------------------------------------------------------------------
  78.  
  79.     .comment    \
  80.  
  81. -------------------------------------------------------------------------------
  82.  
  83. COPYRIGHT NOTICE    (C) 1982   John Hastwell-Batten
  84.  
  85. These programs have been submitted to the public domain via Bill Bolton's RCPM 
  86. system and comprise a system for simply generating self-relocating programs by 
  87. a  method which relies on a linker to generate two object code files which are 
  88. then  processed to yield an object program consisting of  a  relocator,  user-
  89. supplied  object  code  and  a relocation  bitmap.   These  programs  and  the 
  90. accompanying  documentation may be freely distributed in original or  modified 
  91. form subject to the following conditions:
  92.  
  93. 1.   Although  there is no restriction on the sale of self-relocating programs 
  94.      generated  by  the method described herein,  these programs  or  variants 
  95.      thereof  may not be sold as part of any program package  without  written 
  96.      permission  from the author.   Neither may any program or program package 
  97.      which  is dependent for its operation on the use of this method  be  sold 
  98.      without such permission.
  99.  
  100. 2.   The  author's  name  must  be retained in all source  code  (original  or 
  101.      modified)  and  as an acknowlegement in any message  displayed  by  these 
  102.      programs or variant(s) thereof.  An acknowledgement giving credit for the 
  103.      method  shall contain the author's name or the words "H-B method" or  the 
  104.      words "Ashby method".
  105.  
  106. 3.   This copyright notice must be included in and retained in all source code 
  107.      and documentation pertaining to this system.
  108.  
  109.                              John Hastwell-Batten
  110.                                38 Silvia Street
  111.                                Hornsby NSW 2077
  112.                                   AUSTRALIA
  113.                                 (02) 477 4225
  114.  
  115.                               1st November, 1982
  116.  
  117. Acknowledgement
  118.  
  119. In  testing those relocations which overlay specified portions of CP/M I  have 
  120. made  use of John Woolner's CCP protection scheme obtained via  Bill  Bolton's 
  121. RCPM  system.   Without  the CCP protection the verification of the  relocator 
  122. module  would have been exceedingly difficult as the standard program  testing 
  123. tools  all  overlay  the CCP which,  in the case of  the  CP/M  overlays,  the 
  124. relocator expects to be intact.
  125.  
  126. ------------------------------------------------------------------------------\
  127.  
  128. base    equ    0            ;(Some CP/Ms start elsewhere)
  129. userdk    equ    base+4            ;Where CP/M keeps track of current
  130.                     ;user & disk
  131.  
  132.     aseg
  133.     org    base+100h
  134.  
  135. @@relocate::
  136.     jp    $+5            ;Skip over address parameter
  137. codest:
  138.     defw    0            ;Default is relocate to just below BDOS
  139.  
  140.     ld    (ccpstack),sp        ;Save caller's stack pointer
  141.     ld    sp,ccpstack        ;Set up our own
  142.  
  143.     ld    de,$memry+2        ;Address of start of code to DE
  144.     ld    hl,($memry)        ;Address of end of code to HL
  145.     xor    a            ;Clear borrow flag and A register
  146.     sbc    hl,de            ;Calculate code length
  147.     push    hl            ;Save code length
  148.     sub    l            ;Set carry if length not a multiple
  149.                     ;of 256
  150.     ld    a,(base+7)        ;BDOS base page number
  151.     ld    c,a
  152.     ld    a,(codest)        ;Offset from BDOS
  153.     sbc    a,h            ;Form code destination page number
  154.     add    a,c
  155.     ld    h,a            ;Code destination page number to H
  156.  
  157. ;    Having got here, the address calculation will have been in vain if
  158. ;    a code destination was specified, i.e. if code destination >= 100h.
  159. ;
  160. ;    If code destination >= 200h then the destination is explicit and we
  161. ;    load it directly from (codest+1,codest).  If code destination is in
  162. ;    the range 100h to 1FFh then (codest) is assumed to be an offset from
  163. ;    BDOS. (Specifically, -8 to overlay CCP, 0 to overlay BDOS or 14 to
  164. ;    overlay BIOS)
  165.  
  166.     ld    a,(codest+1)        ;Get destination address page number
  167.     dec    a            ;Test it
  168.     jp    m,normal        ; 0 => normal relocation
  169.     jr    z,implicit        ; 1 => CCP, BDOS or BIOS overlay
  170.     ld    hl,(codest)        ;>1 => explicit address
  171.     jr    normal
  172. implicit:
  173.     ld    a,(base+7)        ;BDOS base page number
  174.     ld    c,a
  175.     ld    a,(codest)        ;Add offset (-8 for CCP, 0 for BDOS
  176.     add    a,c            ;or +14 for BIOS)
  177.     ld    h,a
  178. normal:
  179.     ld    l,0            ;HL now holds code destination address
  180.     pop    bc            ;Retrieve code length
  181.     push    hl            ;Save copy of address
  182.     ex    de,hl            ;Destination address to DE,
  183.                     ;Source address to HL
  184.     ld    a,d            ;Destination page number to A
  185.     push    bc            ;Save code length
  186.     ldir                ;Move code up to top of TPA
  187.     sub    2            ;Form bias
  188.     defb    0fdh
  189.     ld    l,a            ;Save in LY
  190.     pop    bc            ;Recover code length
  191.     pop    ix            ;Retrieve pointer to relocated code
  192.     push    ix            ;Save a copy for BDOS entry
  193. @newrel:
  194.     ld    e,(hl)            ;Get relocation flags in E
  195.     inc    hl            ;Point at next 8 flags
  196.     ld    d,8            ;Counter
  197. @reloc:
  198.     rlc    e            ;Move a relocation flag into carry
  199.     jr    nc,@asis        ;No change if bit is off, otherwise...
  200.     defb    0fdh
  201.     ld    a,l            ;Retrieve bias
  202.     nop                ;[NOP is so ZSID won't screw up on the
  203.                     ; next instruction]
  204.     add    a,(ix+0)        ;Add bias to address
  205.     ld    (ix+0),a        ;Put back new address byte
  206. @asis:
  207.     inc    ix            ;Point at next code byte
  208.     dec    bc            ;Decrement code length
  209.     ld    a,b            ;Test residual code length
  210.     or    c
  211.     jr    z,@done            ;Exit if finished
  212.     dec    d            ;Count relocation flags
  213.     jr    z,@newrel        ;Get another set if all used up
  214.     jr    @reloc            ;otherwise continue with this lot
  215. @done:
  216.     ld    hl,(base+6)        ;Get BDOS vector
  217.     pop    ix            ;Recover address of relocated code
  218.     ld    e,(ix+1)        ;Get program entry point to DE
  219.     ld    d,(ix+2)
  220.     ld    a,(codest+1)        ;Get code destination indicator
  221.     dec    a            ;Explicit or implicit destination?
  222.     jr    z,@CCP            ;If relocation overlayed CCP, BDOS
  223.                     ;or BIOS then simply exit to the CCP
  224.     ld    (ix+1),l        ;Fix up the JP at the start of the code
  225.     ld    (ix+2),h
  226.     jp    p,@enter        ;If explicit destination then don't
  227.                     ;modify the BDOS jump
  228.     ld    a,(codest)        ;Check if relocated under CCP
  229.     or    a
  230.     jr    nz,@enter        ;If so, leave BDOS jump alone
  231.     ld    (base+6),ix        ;Otherwise, mark new TPA size
  232. @enter:
  233.     pop    hl            ;Here we deliberately underflow our own
  234.     ld    sp,hl            ;stack to pick up the stack pointer as
  235.                     ;it was when we started.  This is to
  236.                     ;make the relocation invisible to those
  237.                     ;programs which RETurn to the CCP
  238.                     ;instead of ending with a warm boot.
  239.  
  240.     ex    de,hl            ;New start address to HL
  241.     jp    (hl)            ;Transfer to relocated program
  242.  
  243. @CCP:    ld    a,(userdk)        ;Get current user number (high order
  244.                     ; four bits) & disk number (low-order)
  245.     ld    c,a            ;.... then to C for CCP entry
  246.     ld    hl,(base+6)        ;Get BDOS address
  247.     ld    l,0            ;Align to page boundary
  248.     ld    de,3-800h        ;Offset to CCP entry
  249.     add    hl,de            ;Address of CCP warm boot entry
  250.     jp    (hl)            ;Exit to CCP
  251.  
  252.     defw    0,0            ;We don't need much stack space but we
  253.     defw    0,0            ;can't use our caller's because we may
  254.                     ;overlay it!
  255. ccpstack:
  256.     defw    0            ;Temporary hidey-hole for our caller's
  257.                     ;stack pointer.  (Ordinarily, our
  258.                     ;caller would be the CCP.)
  259.  
  260.     end
  261.