home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / asmutl / reloc23.lbr / RELOC.MQC / RELOC.MAC
Text File  |  1986-05-06  |  10KB  |  286 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. ;    VERSION 2.2    13th February 1984
  78. ;    Dispensed with 'illegal' Z80 instructions.
  79. ;
  80. ;    VERSION 2.3    30th December 1984
  81. ;    Added test for system overlays on CP/M+.  A warning message is now
  82. ;    displayed and the user must respond with 'Y' or 'y' to proceed.
  83. ;    The theory behind this is that such activities are potentially more
  84. ;    dangerous on (banked) CP/M+ systems.  Also, a CCP overlay is rather
  85. ;    meaningless!
  86. ;
  87. ;    A new version of this program is planned in the near future.  It will
  88. ;    be a bit smarter about such things.  I have decided that the idea of
  89. ;    checking relocation parameters in the relocator module is pretty
  90. ;    stupid - it is better done in the generator module where so much
  91. ;    more code space is available!
  92. ;
  93. ;------------------------------------------------------------------------------
  94.  
  95.     .comment    \
  96.  
  97. -------------------------------------------------------------------------------
  98.  
  99. COPYRIGHT NOTICE    (C) 1982, 1984   John Hastwell-Batten
  100.  
  101. These programs have been submitted to the public domain via Bill Bolton's STA-
  102. RCPM system and, more recently, via the Tesseract RCPM+ system.
  103.  
  104. These  programs and  the accompanying  documentation may be freely distributed
  105. in original or  modified form so long as a notice giving credit for the method 
  106. is retained in the code.
  107.  
  108.  
  109.                              John Hastwell-Batten
  110.                                Tesseract RCPM+
  111.                                  Dural, NSW
  112.                                   AUSTRALIA
  113.                                 (02) 651-1404
  114.  
  115.                              30th December, 1984
  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    c,12            ;Get CP/M version number
  174.     call    base+5
  175.     ld    de,proceed        ;Set return address
  176.     push    de
  177.     ld    a,h            ;MP/M flag
  178.     or    a            ;Test it
  179.     jr    z,danger
  180.     ld    a,2Fh            ;CP/M Plus version 3.0 or more
  181.     cp    l
  182.     jr    c,danger
  183. proceed:
  184.     ld    a,(base+7)        ;BDOS base page number
  185.     ld    c,a
  186.     ld    a,(codest)        ;Add offset (-8 for CCP, 0 for BDOS
  187.     add    a,c            ;or +14 for BIOS)
  188.     ld    h,a
  189. normal:
  190.     ld    l,0            ;HL now holds code destination address
  191.     pop    bc            ;Retrieve code length
  192.     push    hl            ;Save copy of address for BDOS entry
  193.     push    hl            ;Another copy for code adjustment
  194.     ex    de,hl            ;Destination address to DE,
  195.                     ;Source address to HL
  196.     ld    a,d            ;Destination page number to A
  197.     push    bc            ;Save code length
  198.     ldir                ;Move code up to top of TPA
  199.     sub    2            ;Form bias
  200.     pop    bc            ;Recover code length
  201.     pop    ix            ;Retrieve pointer to relocated code
  202.     push    af            ;Save bias
  203. @newrel:
  204.     ld    e,(hl)            ;Get relocation flags in E
  205.     inc    hl            ;Point at next 8 flags
  206.     ld    d,8            ;Counter
  207. @reloc:
  208.     rlc    e            ;Move a relocation flag into carry
  209.     jr    nc,@asis        ;No change if bit is off, otherwise...
  210.     pop    af            ;Retrieve bias
  211.     push    af            ;Save it again
  212.     add    a,(ix+0)        ;Add bias to address
  213.     ld    (ix+0),a        ;Put back new address byte
  214. @asis:
  215.     inc    ix            ;Point at next code byte
  216.     dec    bc            ;Decrement code length
  217.     ld    a,b            ;Test residual code length
  218.     or    c
  219.     jr    z,@done            ;Exit if finished
  220.     dec    d            ;Count relocation flags
  221.     jr    z,@newrel        ;Get another set if all used up
  222.     jr    @reloc            ;otherwise continue with this lot
  223. @done:
  224.     pop    af            ;Realign stack
  225.     ld    hl,(base+6)        ;Get BDOS vector
  226.     pop    ix            ;Recover address of relocated code
  227.     ld    e,(ix+1)        ;Get program entry point to DE
  228.     ld    d,(ix+2)
  229.     ld    a,(codest+1)        ;Get code destination indicator
  230.     dec    a            ;Explicit or implicit destination?
  231.     jr    z,@CCP            ;If relocation overlayed CCP, BDOS
  232.                     ;or BIOS then simply exit to the CCP
  233.     ld    (ix+1),l        ;Fix up the JP at the start of the code
  234.     ld    (ix+2),h
  235.     jp    p,@enter        ;If explicit destination then don't
  236.                     ;modify the BDOS jump
  237.     ld    a,(codest)        ;Check if relocated under CCP
  238.     or    a
  239.     jr    nz,@enter        ;If so, leave BDOS jump alone
  240.     ld    (base+6),ix        ;Otherwise, mark new TPA size
  241. @enter:
  242.     pop    hl            ;Here we deliberately underflow our own
  243.     ld    sp,hl            ;stack to pick up the stack pointer as
  244.                     ;it was when we started.  This is to
  245.                     ;make the relocation invisible to those
  246.                     ;programs which RETurn to the CCP
  247.                     ;instead of ending with a warm boot.
  248.  
  249.     ex    de,hl            ;New start address to HL
  250.     jp    (hl)            ;Transfer to relocated program
  251.  
  252. danger:
  253.     ld    de,warning        ;Display a message saying that what
  254.     ld    c,9            ;we are doing is very dangerous
  255.     call    base+5            ;with this version of the operating
  256.     ld    c,1            ;system and ask for permission to
  257.     call    base+5            ;proceed.
  258.     and    5Fh
  259.     cp    'Y'
  260.     ret    z            ;Continue if authorised
  261.     jp    0            ;Otherwise stop before we do any damage
  262.  
  263. @CCP:    ld    a,(userdk)        ;Get current user number (high order
  264.                     ; four bits) & disk number (low-order)
  265.     ld    c,a            ;.... then to C for CCP entry
  266.     ld    hl,(base+6)        ;Get BDOS address
  267.     ld    l,0            ;Align to page boundary
  268.     ld    de,3-800h        ;Offset to CCP entry
  269.     add    hl,de            ;Address of CCP warm boot entry
  270.     jp    (hl)            ;Exit to CCP
  271.  
  272. warning:
  273.     defb    'CP/M+ & MP/M OVERLAYS ARE DANGEROUS'
  274.     defb    13,10,"Continue? $"
  275.  
  276.                     ;We can't use our caller's stack 'cause
  277.     defw    0,0            ;we may overlay it and by the time our
  278.     defw    0,0            ;stack overruns the message we won't
  279.                     ;need it.
  280. ccpstack:
  281.     defw    0            ;Temporary hidey-hole for our caller's
  282.                     ;stack pointer.  (Ordinarily, our
  283.                     ;caller would be the CCP.)
  284.  
  285.     end
  286.