home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / CPM3 / CCP105P.ARK / LOADER.MAC < prev    next >
Text File  |  1986-10-17  |  14KB  |  567 lines

  1.     .Z80
  2. ;Modified LOADER for CP/M version 3.1
  3. ;
  4. ;This Loader is to be combined with the modified CCP before installing
  5. ;the CCP.  It is especially useful in an RCPM
  6. ;environment.  See CCP+.DOC for more details.
  7. ;
  8. ;This is the modified dissasembled version of the LOADER.
  9. ;
  10. ;Jim Lopushinsky,  Edmonton, Alberta, Canada
  11. ;484-5981 @ 300/1200 bps
  12.  
  13. bdos     EQU    5
  14.  
  15. ;.............
  16. ;
  17. ;RSX header for the loader.
  18. ;
  19. ;
  20. begin:
  21.     ds    4        ;                100H
  22.     dw    end-begin    ;Length of loader module    104H
  23.     JP    LOADER        ;Loader entry point
  24. NEXT:    JP    6        ;modified to JMP BDOS
  25. PREV:    DEFW    7        ;modified to point to prev RSX
  26.     DEFB    0        ;remove flag
  27.     DEFB    0        ;non-banked flag
  28.     DEFB    'LOADER  '    ;The name of this RSX
  29.     DEFB    0FFH        ;Loader flag
  30.     DEFB    0,0        ;reserved
  31.  
  32. ;.........
  33. ;
  34. ;End of RSX header
  35. ;
  36. scbbase:        ;Address of Base of System Control Block
  37.     DEFW    0    ;                    11BH
  38. membase:        ;Address of Base of Common memory
  39.     DEFB    0    ;                    11DH
  40.  
  41. ;...........
  42. ;
  43. ;Jump table for service routines that the CCP uses in the non-relocated
  44. ;version of the loader
  45. ;
  46.  
  47.     JP    chkrsx    ;Remove inactive RSXs            11EH
  48.     JP    reloc    ;Relocate RSX                121H
  49.     JP    setload    ;compute relocate address        124H
  50.     JP    setnext    ;set up next RSX pointer        127H
  51.     JP    setrsx    ;set up RSX chains            12AH
  52. ;
  53. ;save IX and call BDOS                        12DH
  54. ;
  55. xbdos:
  56.     push    ix
  57.     call    bdos
  58.     pop    ix
  59.     ret
  60.  
  61. ;............
  62. ;
  63. ;Loader entry point.  All BDOS calls are intercepted here.  We only
  64. ;need to intercept function 59, Load overlay
  65. ;
  66.  
  67. LOADER:
  68.     LD    A,C        ;Get BDOS function
  69.     CP    59        ;is it Load overlay?
  70.     jr    NZ,NEXT        ;on to BDOS if not
  71.     POP    BC        ;GET RETURN ADDRESS IN [BC]
  72.     PUSH    BC
  73.     LD    (STKSAVE),sp
  74.     LD    SP,LDRSTACK
  75.     PUSH    BC        ;Save return address on stack
  76.     ld    ix,(scbbase)    ;SCB in IX
  77.     EX    DE,HL    
  78.     LD    (LFCBADDR),HL    ;Save Load FCB address
  79.     LD    A,H        ;Test for load address of 0
  80.     OR    L
  81.     PUSH    AF        ;save flags
  82.     CALL    Z,CHKRSX    ;Delete inactive RSXs if 0
  83.     POP    AF        ;restore flags
  84.     CALL    NZ,LOAD        ;if load address non-zero, load the program
  85.     POP    DE        ;Get return address
  86.     LD    HL,100H        ;point to start of .COM file
  87.     LD    A,(HL)        ;Get first byte
  88.     CP    0C9H        ;Is it a return inst?
  89.     jr    Z,DORSX        ;RSXs attached.  Go relocate them
  90.     LD    A,D        ;Test for return address of 100H
  91.     DEC    A
  92.     OR    E
  93.     jr    NZ,NOT100H    ;Jump if not loading a .COM or .PRL file
  94.     LD    A,(PREV+1)    ;Get High byte prev address
  95.     OR    A        ;is it 0?
  96.     jr    NZ,NOT100H    ;Nope
  97.     LD    HL,(NEXT+1)    ;Get next RSX address
  98.     LD    (BDOS+1),HL    ;Save in JMP BDOS in page 0
  99.     LD    (BDOSJMP),HL    ;And save it for us
  100.     CALL    SETTPA        ;Set Top of TPA address in SCB
  101. NOT100H:
  102.     LD    sp,(STKSAVE)        ;Restore callers stack
  103.     XOR    A        ;flag no error
  104.     LD    L,A
  105.     LD    H,A
  106.     RET
  107.  
  108. ;...............
  109. ;
  110. ;HERE IF BAD LOAD ADDRESS
  111. ;
  112. BADADDR:
  113.     LD    DE,0FEH        ;init error code
  114. ERRRET:
  115.     LD    sp,(STKSAVE)    ;restore callers stack
  116.     POP    HL        ;get return address
  117.     PUSH    HL
  118.     DEC    H        ;test for return to 100H (called from CCP)
  119.     LD    A,H
  120.     OR    L
  121.     EX    DE,HL        ;error code in HL
  122.     LD    A,L        ;propagate error code to A and B
  123.     LD    B,H
  124.     RET    NZ        ;return if called by user program (not CCP)
  125. BADADRA:
  126.     LD    C,9        ;print string function
  127.     LD    DE,LOADMSG    ;point to load error message
  128.     CALL    xbdos        ;print the error message
  129.     RST    0        ;and warm boot.
  130.  
  131. ;.................
  132. ;
  133. ;RELOCATE THE RSX
  134. ;
  135. MOVERSX:
  136.     INC    HL
  137.     LD    C,(HL)        ;Get length of RSX into BC
  138.     INC    HL
  139.     LD    B,(HL)
  140.     LD    A,(MEMBASE)    ;Get common memory base
  141.     OR    A        ;Test for banked system
  142.     jr    Z,NONBNK    ;Jump if non-banked system
  143.     INC    HL
  144.     INC    (HL)        ;Test for non-banked only load
  145.     jr    Z,LNOLOAD    ;jump if non-banked only RSX
  146. NONBNK:
  147.     PUSH    DE        ;Save RSX start address
  148.     CALL    SETLOAD        ;Set up relocation address
  149.     POP    HL        ;RSX start address in HL
  150.     CALL    RELOC        ;Relocate the RSX
  151.     CALL    SETRSX        ;Set up the RSX pointers
  152. LNOLOAD:
  153.     POP    HL        ;restore COM header table location
  154.  
  155. ;...............
  156. ;
  157. ;LOAD RSX'S AND ADJUST COM FILE
  158. ;
  159. DORSX:
  160.     LD    DE,16        ;offset in COM file header to start of
  161.                 ;RSX length table
  162.     ADD    HL,DE        ;form address
  163.     PUSH    HL        ;save on stack
  164.     LD    E,(HL)        ;Get start address of RSX in DE
  165.     INC    HL
  166.     LD    D,(HL)
  167.     LD    A,E        ;Test for end of RSX table
  168.     OR    D
  169.     jr    NZ,MOVERSX    ;Go do it if not at end
  170.     CALL    0103H        ;Call init routine in COM file RSX header
  171.     LD    A,(200H)    ;Get first byte of .COM file
  172.     CP    0C9H        ;Is it return inst?
  173.     jr    NZ,NO2NDHDR    ;Jump if no second header page
  174.     set    1,(ix+33h)    ;Set RSX flag
  175.  
  176. ;...........
  177. ;
  178. ;Here to move the COM file down one page
  179. ;
  180. NO2NDHDR:
  181.     LD    bc,(0101H)    ;Get length of COM file into bc
  182.     LD    HL,200H        ;source
  183.     LD    DE,100H        ;destination
  184.     LDIR            ;Move COM file down one page
  185.     jr    NOT100H        ;and process next header
  186.  
  187. ;............
  188. ;
  189. ;SET UP RSX HEADERS.  DE = base of RSX
  190. ;
  191. SETRSX:
  192.     LD    HL,(BDOS+1)    ;get top of TPA
  193.     LD    L,0        ;align on page boundary
  194.     LD    BC,6        ;length of move
  195.     LDIR            ;move Serial number into place
  196.     xor    a
  197.     LD    E,18H        ;point to loader flag
  198.     LD    (DE),A        ;zero the loader flag
  199.     LD    E,0DH        ;High byte of prev address
  200.     LD    (DE),A        ;zero prev high byte
  201.     DEC    DE        ;low byte of prev
  202.     LD    A,7
  203.     LD    (DE),A        ;prev = 0007H
  204.     LD    L,E        ;point to prev in next RSX
  205.     LD    E,0BH        ;next field in this RSX
  206.     LD    (HL),E        ;set prev field of next RSX
  207.     INC    HL        ;to point to this RSX
  208.     LD    (HL),D
  209.  
  210. ;..............
  211. ;
  212. ;SET UP NEXT FIELD IN RSX HEADER
  213. ;HL = base of next RSX, DE= next field in this RSX
  214. ;
  215. SETNEXT:
  216.     EX    DE,HL        ;HL=next field, DE=next RSX
  217.     LD    (HL),D        ;save page number
  218.     DEC    HL        ;point to low byte
  219.     LD    (HL),6        ;always 6
  220. STNEXTA:
  221.     LD    L,6        ;adjust
  222.     LD    (BDOS+1),HL    ;alter JMP BDOS
  223.     LD    (BDOSJMP),HL    ;and save it for us
  224.  
  225. ;.............
  226. ;
  227. ;SET TOP OF TPA IN SCB
  228. ;
  229. SETTPA:
  230.     LD    DE,LSCBPB    ;point to SCB paramater block
  231.  
  232. ;.............
  233. ;
  234. ;GET/SET SCB AT [DE]
  235. ;
  236. LGSSCB:
  237.     LD    C,49        ;get/set SCB
  238.     jp    xbdos        ;Set the Top TPA address in SCB
  239.  
  240. ;.............
  241. ;
  242. ;DELETE ANY INACTIVE RSX'S
  243. ;
  244. CHKRSX:
  245.     LD    HL,(BDOS+1)    ;get top of TPA
  246.     LD    B,H        ;top of TPA page in B
  247. RSXRMLOOP:
  248.     LD    H,B        ;get RSX base page
  249.     LD    L,18H        ;offset to loader flag
  250.     INC    (HL)        ;test loader flag
  251.     DEC    (HL)
  252.     RET    NZ        ;return if at loader
  253.     LD    L,0BH        ;offset to high byte of next field
  254.     LD    B,(HL)        ;get next RSX page into B
  255.     LD    L,0EH        ;point to remove flag
  256.     LD    A,(HL)        ;get remove flag
  257.     OR    A        ;test remove flag
  258.     jr    Z,RSXRMLOOP    ;jump if not to remove this RSX
  259.     LD    L,0CH        ;point to prev field
  260.     LD    E,(HL)        ;get prev address into DE
  261.     INC    HL
  262.     LD    D,(HL)
  263.     LD    A,B        ;get next RSX page
  264.     LD    (DE),A        ;set prev RSX to bypass this RSX
  265.     DEC    DE
  266.     LD    A,6        ;always 6
  267.     LD    (DE),A
  268.     INC    DE        ;back to high byte of prev field
  269.     LD    H,B        ;form address of next RSX
  270.     LD    L,0CH        ;offset to prev field in next RSX
  271.     LD    (HL),E        ;set prev address in next RSX
  272.     INC    HL        ;to bypass this RSX
  273.     LD    (HL),D
  274.     LD    A,D        ;test for page zero prev pointer
  275.     OR    A
  276.     PUSH    BC        ;save RSX page
  277.     CALL    Z,STNEXTA    ;alter location 6 if we just removed
  278.                 ;lowest RSX
  279.     POP    BC        ;restore RSX page
  280.     jr    RSXRMLOOP    ;and loop for more RSXs
  281.  
  282. ;............
  283. ;
  284. ;LOAD THE PROGRAM
  285. ;
  286. LOAD:
  287.     PUSH    HL        ;save FCB address
  288.     LD    DE,DMASCB    ;point to SCB param block for get DMA
  289.     CALL    LGSSCB        ;Get current DMA address
  290.     EX    DE,HL        ;DMA into DE
  291.     ex    (sp),iy        ;restore FCB address, save IY
  292.     bit    7,(ix+25h)    ;test library member load
  293.     jr    z,notlbr
  294.     ld    l,(iy+23h)
  295.     ld    h,(iy+24h)    ;get member length into HL
  296.     ld    (memlen),hl    ;save member length
  297.     jr    load1
  298. notlbr:
  299.     ld    (iy+20h),0    ;zero record count
  300. load1:
  301.     ld    l,(iy+21h)
  302.     ld    h,(iy+22h)    ;get load address into HL
  303.     ex    (sp),iy        ;restore IY, save FCB address
  304.     DEC    H        ;test for load address < 100H
  305.     INC    H
  306.     jp    Z,BADADDR    ;jump if attempt to load below 100H
  307.     PUSH    HL        ;save load address
  308.     PUSH    DE        ;save old DMA address
  309.     PUSH    HL        ;save load address again
  310.     CALL    setusr        ;set up multi-sector count, user number
  311.     POP    HL        ;restore load address
  312.     PUSH    AF        ;save old mult-sector count on stack
  313. MOREREAD:
  314.     LD    A,(BDOS+2)    ;get base page of top of TPA
  315.     DEC    A        ;less one
  316.     SUB    H        ;compare with load address
  317.     jp    C,TOHIGH    ;jump if too high
  318.     jp    Z,tohigh
  319.     LD    (nextaddr),HL    ;save current sector address
  320.     CP    64
  321.     jr    C,ok64
  322.     LD    a,64
  323. ok64:
  324.     PUSH    HL
  325.     LD    d,a
  326.     ADD    A,a
  327.     bit    7,(ix+25h)    ;test library flag
  328.     jr    z,load3
  329.     ld    hl,(memlen)    ;get member length left
  330.     ld    c,a        ;sector count in c
  331.     ld    b,0
  332.     sbc    hl,bc        ;calculate new length left
  333.     jr    nc,load2    ;jump if no overflow
  334.     ld    a,(memlen)    ;get length left
  335.     ld    hl,0
  336. load2:
  337.     ld    (memlen),hl    ;save new length left
  338.     or    a        ;at end of member?
  339.     jr    nz,load3
  340.     pop    hl        ;restore stack
  341.     inc    a        ;A = 1
  342.     jr    readend
  343. load3:
  344.     LD    e,a
  345.     CALL    setmce
  346.     LD    e,0
  347.     POP    HL
  348.     PUSH    HL
  349.     PUSH    DE
  350.     CALL    LREAD        ;read a sector
  351.     POP    DE        ;restore block length
  352.     POP    HL        ;restore sector address
  353.     ADD    HL,DE        ;bump sector address
  354.     jr    Z,MOREREAD    ;jump if no read errors
  355. READEND:
  356.     POP    BC        ;get old multi-sector count
  357.     DEC    A        ;if EOF, A = zero
  358.     LD    E,B        ;old multi-sector count in E
  359.     CALL    SETMCE        ;restore old multi-sector count
  360.     LD    C,26        ;set DMA function
  361.     POP    DE        ;restore old DMA address
  362.     PUSH    AF        ;save read EOF status
  363.     CALL    setous        ;set DMA to old value, restore old user number
  364.     POP    AF        ;restore read EOF status
  365.     LD    de,(ERRCODE)    ;get read error flags
  366.     jp    NZ,ERRRET    ;jump if read error (not EOF)
  367.     POP    DE        ;restore load address into DE
  368.     POP    HL        ;restore FCB address into HL
  369.  
  370. ;.............
  371. ;
  372. ;CHECK FOR PRL FILE (PAGE RELOCATABLE)
  373. ;
  374.  
  375.     bit    6,(ix+25h)    ;is it PRL?
  376.     ret    z
  377.  
  378. ;.............
  379. ;
  380. ;here if .PRL file loaded
  381. ;
  382.     LD    A,E
  383.     OR    A        ;must be on even page boundary
  384.     jp    NZ,BADADDR    ;jump if not on page boundary
  385.     LD    H,D        ;load address into HL
  386.     LD    L,E
  387.     INC    HL        ;point to code length in PRL header
  388.     LD    C,(HL)        ;get code length into BC
  389.     INC    HL
  390.     LD    B,(HL)
  391.     LD    L,E        ;L = 0
  392.  
  393. ;...............
  394. ;
  395. ;RELOCATE THE LOADED MODULE
  396. ;
  397. RELOC:
  398.     INC    H        ;point to start of code
  399.     PUSH    DE        ;save load address
  400.     PUSH    BC        ;save length
  401.     LDIR            ;move the module to target location
  402.                 ;[HL] NOW POINTS TO START OF BIT MAP
  403.     POP    BC        ;restore length
  404.     POP    DE        ;restore target address
  405.     PUSH    DE
  406.     LD    E,D        ;target page into E
  407.     DEC    E        ;adjust relocation offset
  408.     PUSH    HL        ;save bit map address
  409.     LD    H,E        ;relocation offset in H
  410.     LD    E,0        ;init bit offset
  411. RELOCLP:
  412.     LD    A,B        ;test for end
  413.     OR    C
  414.     jr    Z,RELOCDN    ;Jump if done
  415.     DEC    BC        ;Decrement length left
  416.     LD    A,E        ;get number of bits left
  417.     AND    7
  418.     jr    NZ,NOBUMP    ;jump ok
  419.     EX    (SP),HL        ;get bit map address
  420.     LD    A,(HL)        ;get next byte from bit map
  421.     INC    HL        ;bump
  422.     EX    (SP),HL        ;back to stack
  423.     LD    L,A        ;bits in L
  424. NOBUMP:
  425.     RL    l        ;shift into carry
  426.     jr    NC,NOADJUST    ;jump if no need to adjust
  427.     LD    A,(DE)        ;get a byte
  428.     ADD    A,H        ;adjust it
  429.     LD    (DE),A        ;put it back
  430. NOADJUST:
  431.     INC    DE        ;bump pointer
  432.     jr    RELOCLP        ;and loop for more
  433. RELOCDN:        ;relocation complete
  434.     POP    DE        ;adjust stack
  435.     POP    DE
  436.     RET
  437.  
  438. ;................
  439. ;
  440. ;HERE IF LOAD ADDRESS IS TOO HIGH
  441. ;
  442. TOHIGH:
  443.     CALL    SETMSC        ;restore things
  444.     LD    HL,80H        ;point to TBUFF
  445.     CALL    LREAD        ;read one more sector into TBUFF
  446.     jr    NZ,READEND    ;jump if read error
  447.     LD    HL,0FEH        ;set error code
  448.     LD    (ERRCODE),HL    
  449.     jr    READEND        ;and jump to read return
  450.  
  451. ;..............
  452. ;
  453. ;SET UP THE LOAD PARAMETERS
  454. ;
  455. SETLOAD:
  456.     LD    A,(BDOS+2)    ;get top of TPA page
  457.     DEC    A        ;less one
  458.     DEC    BC        ;decrement load length
  459.     SUB    B        ;compute target page
  460.     INC    BC        ;correct load length
  461.     CP    0FH        ;load must start at page 15 or higher
  462.     jp    C,BADADRA    ;jump if too low
  463.     LD    HL,(NEXTADDR)    ;get target address
  464.     CP    H        ;compare with load page
  465.     jp    C,BADADRA    ;jump if target address > load address
  466.     LD    D,A        ;relocation address into DE
  467.     LD    E,0
  468.     RET
  469.  
  470. ;..............
  471. ;
  472. ;RETURN MULTI-SECTOR COUNT IN [A] AND SET IT TO 1
  473. ;
  474. SETMSC:
  475.     LD    E,1        ;set multi-sector count to 1
  476.  
  477. ;...............
  478. ;
  479. ;RETURN MULTI-SECTOR COUNT IN [A] AND SET IT TO [E]
  480. ;
  481. SETMCE:
  482.     LD    A,(ix+66H)    ;get the old multi-sector count
  483.     LD    (ix+66H),E    ;set the new multi-sector count
  484.     RET
  485.  
  486. ;..............
  487. ;
  488. ;SET DMA ADDRESS AND READ a sector
  489. ;
  490. LREAD:
  491.     EX    DE,HL        ;DMA address in DE
  492.     LD    C,26        ;Set DMA function
  493.     CALL    xbdos        ;set the DMA address
  494.     LD    C,20        ;Read sequential function
  495.     LD    HL,(LFCBADDR)    ;point to FCB
  496.     EX    DE,HL        ;    into DE
  497.     CALL    xbdos        ;read a sector
  498.     LD    (ERRCODE),HL    ;save return code
  499.     OR    A        ;set read return flag
  500.     RET
  501.  
  502. ;............
  503. ;
  504. ;set up load user number
  505. ;
  506. SETUSR:
  507.     LD    A,(ix+25H)    ;get load user number
  508.     and    1fh        ;default user number
  509.     jr    Z,setmsc    ;go and set multi-sector count if default
  510.     DEC    A        ;adjust to true user number
  511.     LD    E,A        ;into E for BDOS
  512.     LD    A,(ix+60H)    ;get old user number
  513.     LD    (curusr),A    ;save it
  514.     LD    (ix+60H),E    ;set new user number
  515.     jr    setmsc        ;and on to set multi-sector count
  516.  
  517. ;................
  518. ;
  519. ;restore old user number
  520. ;
  521. setous:
  522.     LD    A,(ix+25H)    ;get load user number
  523.     and    1fh        ;default?
  524.     Jr    Z,setous1    ;on to restore old DMA if default
  525.     LD    A,(curusr)    ;get old user number
  526.     LD    (ix+60H),A    ;restore it
  527. setous1:
  528.     LD    (ix+25H),0    ;set load user to default
  529.     jp    xbdos
  530.  
  531. ;..............
  532. ;
  533. ;LOAD ERROR MESSAGE
  534. ;
  535. LOADMSG:    DEFB    0DH,0AH
  536.         DEFB    'Load Error$'
  537.  
  538. ;............
  539. ;
  540. ;SCB FOR GET DMA ADDRESS
  541. ;
  542. DMASCB:        DEFB    3ch    ;offset to DMA address
  543.         DEFB    0    ;return value from SCB
  544.  
  545. ;...........
  546. ;
  547. ;SCB PARAMETER BLOCK TO SET OFFSET 62H (TOP OF TPA)
  548. ;
  549. LSCBPB:
  550.     DEFB    62h        ;offset to top of TPA address
  551.     DEFB    0FEH        ;set word in SCB
  552.  
  553. end        equ    $
  554.  
  555. BDOSJMP        equ    $    ;Top of TPA address
  556. NEXTADDR    equ    $+2    ;next load sector address
  557. LFCBADDR    equ    $+4    ;load FCB address
  558. STKSAVE        equ    $+6    ;user stack save
  559. ERRCODE        equ    $+8    ;read error return code
  560.                 ;local stack space
  561. LDRSTACK     EQU    $+45
  562. curusr        equ    $+10    ;old user number
  563. memlen        equ    $+11    ;library member length
  564.  
  565.  
  566.     END
  567.