home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / enterprs / cpm / utils / f / rlib12.lbr / RLIB.ZZ0 / RLIB.Z80
Encoding:
Text File  |  1991-10-19  |  26.4 KB  |  1,134 lines

  1. ;    CP/M Z80 library manager - (C) 1988 A.E. Hawley
  2.     .title Z-SYSTEM & CP/M LIBRARY MANAGER
  3.     .SBTTL VERSION, DEFINITIONS
  4.  
  5. ;THIS FILE ASSEMBLES WITH THE ZMAC ASSEMBLER.
  6. ;Use of other assemblers may require translation
  7. ;of some pseudo-op instructions.
  8.  
  9. vers    equ    '1'    ;version number
  10. rev    equ    '2'
  11.  
  12. day    equ    '1'    ;version date
  13. day1    equ    '8'    ;second digit
  14. month    equ    '1'
  15. month1    equ    '2'    ;second digit
  16. year    equ    '8'    ;last digit only
  17.  
  18. ;=====================================================
  19.  
  20. ;references to and from other module(s)
  21.  
  22. ;in libsubs
  23.     ext    BLANK,CLSFIL,CONIN,CONOUT,CRLF
  24.     ext    DEFDU,DELFIL,DOFTYP,ERROR
  25.     ext    MAKFIL,OPNFIL
  26.     ext    REC2WR,RDREC,RENFIL,RETUD,SETDMA
  27.     ext    TYPLIN,WRREC,X128
  28.  
  29. ;in liblib
  30.     ext    fill,fname,getbit,inibit,pkgoff
  31.  
  32. ;bitcnt and getrel are required by getbit
  33.     public    $memry,z3env
  34.  
  35.     .request LIBLIB        ;mREL library made with RLIB
  36.  
  37.     .xlist
  38.     .in    LIBDEF        ;Definitions & Macros source file
  39.     .list
  40.  
  41. ;=====================================================
  42.  
  43.     .SBTTL    'PROGRAM ENTRY & INITIALIZATION'
  44.     PAGE
  45.  
  46. start:    jp    begin
  47.  
  48. ;=====================================================
  49.  
  50.     db    'Z3ENV'        ;identifies program as ZCPR3 utility
  51.     db    1        ;external environment
  52. Z3ENV:    dw    0        ;this address set by Z3INS or ZCPR33
  53.     dw    start        ;for type 3,4 Env
  54.  
  55. ;=====================================================
  56.  
  57. ;place for default options here. Same structure as in ZAS
  58. pgmid:    dc    'RLIB    '    ;program ID for use by configuration pgm
  59. lbopt1:    db    1 shl pubflg    ;first bitmapped config option byte
  60. lbopt2:    db    0,0        ;two more, for spares
  61.  
  62. libext:    db    'REL'        ;default extension for mrel library files
  63. srcext:    db    'REL'        ;default extension for source files
  64. tmpext:    db    '$$$'        ;default ext. for temp. file
  65.  
  66. ;configurable buffer sizes, in number of 128 byte records
  67. libopl:    db    oblen        ;buffer for main rel library file
  68. srcopl:    db    sblen        ;buffer for source (REL) files
  69. cmdopl:    db    cblen        ;buffer for CMD line or CMD file
  70.     ds    3,0        ;for other defaults
  71.  
  72. ;standard initial data for indexed DATA area
  73. inidat:    ds    7,0
  74.     db    5        ;initial names/line in display
  75.     db    20        ;lines/screen for paging
  76. endata:                ;used for length calc
  77.  
  78. ;=====================================================
  79.  
  80.     .sbttl MAIN PROGRAM ROUTINE
  81.     PAGE
  82.  
  83. begin:    ld    (stack),sp        ;save caller stack
  84.     ld    sp,stack        ;and use local stack
  85.     ld    ix,data
  86.     ld    de,signon        ;advertise
  87.     call    typlin
  88.  
  89.     call    zinit            ;if Z3, install pgm name etc.
  90.     call    help
  91.     call    init            ;setup buffer locations
  92.                     ;and init data area
  93.     call    docmd            ;process command tail
  94.     call    dofile            ;Create/open LIB and
  95.                     ;temp output files
  96.     ld    iy,(libbeg)        ;->destination buffer
  97.     bit    pubflg,(ix+outopt)
  98.     call    nz,ptitl1        ;send title line if P option
  99.  
  100. ;=====================================================
  101.  
  102. ;This is the head of the main processing loop, each
  103. ;iteration of which processes one input file, starting
  104. ;with the main LIB input file.
  105.  
  106. psfile:    xor    a
  107.     ld    (fcb+12),A        ;reset the fcb
  108.     ld    (fcb+15),A
  109.     ld    (fcb+32),A
  110.     ld    DE,fcb
  111.     call    opnfil            ;open the file
  112.     jp    z,badfil
  113.  
  114. ;do the first buffer load
  115.     call    bufld            ;return hl->srcbuf
  116.  
  117. ;make sure the current file is a proper mREL file.
  118.     ld    a,(hl)            ;get the first byte
  119.     and    0feh            ;select 7 high bits
  120.     cp    mrlnam            ;must be 84h to be
  121.     jp    nz,badrel        ;a mrel file
  122.     res    eos,(ix+status)        ;erase end-of-source flag
  123.  
  124. ;initialize the getbit routine with the first byte of the
  125. ;file and the address of the 'get-next-byte' (getrel) routine
  126.     ld    a,(hl)            ;recover first byte
  127.     ld    hl,getrel
  128.     call    inibit            ;initialize getbit routine
  129. ;    jp    psrmod            ;the next execution addr.
  130.  
  131. ;=====================================================
  132.     .sbttl REL MODULE PROCESSING
  133.     PAGE
  134.  
  135. ;beginning of loop, each iteration of which processes
  136. ;a REL module until the end of file is reached.
  137. ;Exit is via mREL eof directing execution
  138. ;to ENDFIL.
  139.  
  140. psrmod:    call    psritm            ;do a REL item
  141.     bit    eos,(ix+status)
  142.     jr    nz,srcdon        ;the exit
  143.     bit    eom,(ix+status)
  144.     call    nz,endmod        ;module done
  145.     jr    psrmod            ;do the next item.
  146.  
  147. ;=====================================================
  148.  
  149. ;Process End-of-Module returned by psritm
  150.  
  151. endmod:    bit    pubflg,(ix+outopt)
  152.     call    nz,ccrlfr        ;terminate pubic symbol display
  153.     ld    A,(outopt+data)
  154.     and    1 shl delflg ! 1 shl repflg
  155.     ret    z
  156. ;do the following for Delete/Replace options
  157.     set    namflg,(ix+outopt)
  158.     res    skpflg,(ix+outopt)
  159.     ret
  160.  
  161. ;=====================================================
  162.  
  163. ;Process End-of-File returned from the
  164. ;REL bit stream and return to the main
  165. ;processing loop to do the next file (if any)
  166.  
  167. srcdon:    bit    modflg,(ix+outopt)
  168.     call    nz,ccrlfr        ;terminate module name display
  169.     ld    A,(outopt+data)
  170.     and    1 shl appflg ! 1 shl repflg
  171.     JR    Z,libdon        ;skip if Display or Delete
  172.  
  173.     ld    (ix+outopt),16        ;make Append
  174.     call    appin            ;set up file to append
  175.     jr    nc,psfile        ;go load the file buffer
  176. ;..unless this is the last file, in which case..
  177. ;    jp    libdon            ;finish the library
  178.  
  179. ;=====================================================
  180.     .SBTTL END OF LIBRARY PROCESSING
  181.     PAGE
  182.  
  183. ;All input files have been processed. Clean
  184. ;up output buffers and close files, deleting
  185. ;those that are empty. Rename the temporary
  186. ;file and erase the original REL library.
  187.  
  188. libdon:    ld    A,(outopt+data)
  189.     and    1 shl pubflg ! 1 shl modflg
  190.     jp    nz,mainx        ;quit if display only
  191.  
  192.     bit    0,(ix+wrflg)        ;check for
  193.     jr    nz,ld0            ;an empty
  194.     ld    hl,(libbeg)
  195.     ld    a,(hl)            ;library
  196.     cp    mrleof            ;mREL end-of-file?
  197.     jr    z,ld2            ;delete the temporary file & quit
  198.  
  199. ld0:    res    namflg,(ix+outopt)
  200.     ld    hl,eofbyt
  201.     call    strbyt            ;deposit the mrel eof byte
  202.     ld    de,(libcnt)        ;remaining space in buffer
  203.     ld    hl,(libsiz)        ;buffer size
  204.     or    a
  205.     sbc    hl,de
  206.     jp    z,mainx            ;abort if empty buffer
  207.  
  208.     call    rec2wr            ;convert to number of 128 byte records
  209.  
  210. ld1:    ld    B,L
  211.     call    libwr            ;write out the library
  212.     ld    de,libfcb
  213.     call    clsfil            ;this is still <lib>.$$$
  214.  
  215. ;Prepare to rename the <lib>.$$$ to <lib>.REL
  216.     ld    hl,srcfcb        ;copy lib fn.ft to the..
  217.     ld    de,libcb2        ;rename field
  218.     ld    bc,16
  219.     ldir
  220.  
  221. ;delete the <lib>.REL (original library file)
  222.     ld    de,srcfcb        ;delete the RENAME target
  223.     call    delfil
  224.  
  225. ;rename the <lib>.$$$ file to <lib>.REL
  226.     xor    a
  227.     ld    (libcb2),a        ;must be 0 for RENAME function
  228.     ld    de,libfcb
  229.     call    renfil            ;rename from (fcb) to (fcb+16)
  230.     jp    mainx            ;done. exit
  231.  
  232. ;here when <lib>.$$$ is empty
  233. ld2:    ld    de,libfcb
  234.     call    delfil            ;delete it
  235. mainx:    rst    0            ;main exit
  236.  
  237. ;=====================================================
  238.     .SBTTL    FILE & COMMAND ROUTINES
  239.     PAGE
  240.  
  241. ;    LOAD SOURCE BUFFER FROM FILE
  242.  
  243. bufld:    push    bc
  244.     push    de
  245.     bit    0,(ix+eofflg)
  246.     jp    nz,badrel
  247.  
  248.     ld    a,(srclen)        ;source buffer length
  249.     ld    b,a
  250.     ld    de,(srcbeg)
  251.     jr    bufld1
  252.  
  253. bufld0:    ld    hl,sector        ;cpm record size
  254.     add    hl,de
  255.     ex    de,hl
  256. bufld1:    push    de
  257.     call    setdma
  258.  
  259.     ld    de,fcb
  260.     call    rdrec            ;read record from file
  261.     or    a            ;check for read errors
  262.     pop    de
  263.     jr    nz,buflde        ;jump on eof or bad read
  264.     djnz    bufld0
  265.  
  266. bufldx:    ld    hl,(srcsiz)        ;buffer size
  267.     ld    (srccnt),hl        ;init bytes remaining
  268.     ld    hl,(srcbeg)
  269.     ld    (srcptr),hl        ;init srcptr
  270.     pop    de
  271.     pop    bc
  272.     ret
  273.  
  274. ;exception processing during buffer load
  275. buflde:    cp    2            ;end of file?
  276.     jp    nc,rderr        ;1=physical end of file
  277.  
  278.     set    0,(ix+eofflg)        ;here on eof
  279.     JR    bufldx
  280.  
  281. ;=====================================================
  282.  
  283. ;    PROCESS COMMAND LINE
  284. ;copy the command tail to cmdbuf until Option
  285. ;separator or end-of-command.
  286. ;Set the option if it is present
  287. ;Identify the REL Library name, and put it into
  288. ;the destination FCB and the source FCB, with an
  289. ;extension of $$$ in the first and REL in the second.
  290.  
  291. docmd:    ld    hl,tbuf            ;->cmd tail in tbuf
  292.     ld    B,(HL)            ;GET LENGTH
  293.     inc    hl
  294.     ld    a,spc
  295. dcspc:    cp    (hl)            ;skip leading spaces
  296.     jr    nz,dcspcx        ;..in the command line
  297.     inc    hl
  298.     djnz    dcspc
  299. dcspcx:    ld    de,(cmdbeg)        ;->local cmd buffer
  300.  
  301. dc0:    ld    a,(hl)
  302.     cp    '='
  303.     jr    nz,dc1
  304.     ld    (ix+outopt),1 shl appflg
  305. dc1:    cp    spc            ;end of list?
  306.     jr    z,dcopt            ;yes, if space
  307.     cp    '/'
  308.     jr    z,dcopt            ;..or the option indicator
  309.  
  310.     ld    (DE),A            ;transfer char to cmd buff
  311.     inc    de
  312. dc2:    inc    hl            ;entry to skip cmd buff transfer
  313.     djnz    dc0            ;get another char.
  314.  
  315.     ex    de,hl
  316.     ld    (hl),cr            ;terminate command line
  317.  
  318. dc3:
  319.     ld    hl,(cmdbeg)        ;init fcb, fill with
  320.     ld    de,srcfcb        ;filespec at cmdbeg.
  321.     ld    bc,(defdu)        ;put explicit/default
  322.     call    fname            ;DU at FCB-1 & FCB
  323.     jp    nz,synerr
  324.     ld    a,(hl)
  325.     cp    cr
  326.     jr    z,dc31
  327.     inc    hl            ;->char AFTER the delimiter
  328. dc31:    ld    (cmdptr),hl
  329.     push    af            ;save the terminator
  330.  
  331.     ld    de,srcfcb
  332.     ld    hl,libext
  333.     call    doftyp            ;default or explicit name
  334. ;the fcb for the SOURCE library has been set up.
  335. ;Now set up the Destination FCB with the same name
  336. ;and DU, but with a temporary filetype extension.
  337.  
  338.     ld    hl,srcfcb-1
  339.     ld    de,libfcb-1
  340.     ld    bc,10
  341.     ldir
  342.  
  343.     ld    de,libfty
  344.     ld    hl,tmpext        ;temporary file extension
  345.     ld    bc,3
  346.     ldir
  347.  
  348.     pop    af            ;recover terminator
  349.     cp    '='            ;was it a library spec?
  350.     jr    z,dc4
  351.  
  352.     ld    a,(outopt+data)
  353.     and    1 shl pubflg ! 1 shl modflg
  354.     jp    z,synerr        ;illegal. abort with message
  355.  
  356. ;Set up the System fcb to access the requested
  357. ;library file with the implied or explicit filespec.
  358. dc4:    ld    hl,srcfcb-1        ;include the user#
  359.     ld    de,fcb-1        ;system FCB at 5ch
  360.     ld    bc,13            ;user+dr+fn+ft
  361.     ldir                ;DE -> .typ field
  362.     ret
  363.  
  364. dcopt:    dec    b            ;end of line?
  365.     ld    a,cr
  366.     ld    (de),a            ;terminate cmd line
  367.     jp    z,dc3            ;no options, so continue
  368.  
  369.     inc    hl
  370.     ld    a,(hl)            ;get next char
  371.     cp    '/'
  372.     jr    z,dcopt            ;ignore '/'
  373.     cp    spc
  374.     jr    z,dcopt            ;..and spaces
  375.     call    doopts            ;found possible option char
  376.  
  377.     jr    dc3            ;we did, if here
  378.  
  379. ;=====================================================
  380.  
  381. ;    SET COMMAND LINE OPTION
  382. ;Identify the first character after the option
  383. ;delimiter as the (only) option. Set flags
  384. ;according to the option selected. Use the default
  385. ;option flags if A option or NO option.
  386.  
  387. doopts:    ld    a,(hl)
  388.     exx
  389.     ld    (char),a
  390.     ld    hl,clopts
  391.     ld    bc,cloptv-clopts
  392.     cpir
  393.     add    hl,bc
  394.     add    hl,bc
  395.     add    hl,bc
  396.     ldhlhl
  397.     push    hl
  398.     exx
  399.     ret            ;jump to the routine
  400.  
  401. clopts:    db    'DPMRA'
  402. char:    ds    1        ;the test character is always found.
  403. cloptv:    dw    badopt        ;if none of clopts list
  404.     dw    aopt,ropt,mopt,popt,dopt
  405.  
  406. ;=====================================================
  407.  
  408. dopt:    ld    (ix+outopt),1        ;delete
  409.     set    namflg,(ix+outopt)
  410.     ret
  411. popt:    ld    (ix+outopt),1 shl 1    ;publics
  412.     ret
  413. mopt:    ld    (ix+outopt),1 shl 2    ;modules
  414.     ret
  415. ropt:    ld    (ix+outopt),1 shl 3    ;replace
  416.     set    namflg,(ix+outopt)
  417.     ret
  418. aopt:    ld    (ix+outopt),1 shl 4    ;append
  419.     ret
  420.  
  421. ;..and if none of the above, then..
  422. badopt:    ld    de,optmsg        ;tell about bad option char.
  423.     call    typlin
  424.     ld    de,usemsg        ;show what's right
  425.     jp    error
  426.  
  427. ;=====================================================
  428. ;    set UP LIB & TEMP FILES
  429.  
  430. ;If an option has been set, then ONLY that bit in
  431. ;the data+outopt byte is set. Otherwise (default)
  432. ; the byte contains 00010000b. (Append)
  433. dofile:    ld    a,(outopt+data)
  434.     and    1 shl modflg ! 1 shl pubflg
  435.     jr    nz,dofil1        ;jmp if display only
  436.  
  437. ;erase and remake a temp <lib>.$$$ file
  438.     ld    de,libfcb        ;for a|d|r option
  439.     call    delfil
  440.     call    makfil            ;gets renamed later!
  441.     ;meantime, it's opened for read/write
  442.  
  443. dofil1:
  444. ;fcb contains the <lib>.REL spec
  445.     ld    de,fcb            ;open source fcb for <lib>.rel
  446.     call    opnfil
  447.     ret    nz            ;ok, start reading it
  448.  
  449. ;here when the <LIB>.REL file is not found. If the append flag is
  450. ;set, then go ahead and read source modules into the temporary
  451. ;output file.
  452.     bit    appflg,(ix+outopt)    ;file not found so must be append
  453.     jp    z,badfil        ;if append is not the option,
  454.                     ;then there's something wrong!
  455.  
  456. ;LIB file not found, so create an output file, then
  457. ;open the first REL module file for appending.
  458.  
  459.     ld    hl,(cmdptr)        ;first, make sure there is
  460.     ld    a,(hl)            ;something to append!
  461.     CP    cr
  462.     jp    z,badfil        ;z = no module list
  463.  
  464.     call    appin            ;gets next file, iy->LIBBUF
  465. ;..if cy set, there is no file to append.
  466.     ret
  467.  
  468. ;=====================================================
  469.     .SBTTL MREL BIT STREAM PROCESSING
  470.     PAGE    
  471. ;=====================================================
  472.  
  473. ;read and process a single item from the mREL bit
  474. ;stream in the input buffer. The module name is the
  475. ;first item in the stream. The End-of-module or
  476. ;End-of-file is the last item.
  477.  
  478. psritm:    gbits    1
  479.     dec    a
  480.     jp    m,absbyt
  481.     jr    relitm
  482.  
  483. ;=====================================================
  484.  
  485. ;    PROCESS ABSOLUTE BYTE
  486.  
  487. ABSBYT:    gbits    8
  488.     ret
  489.  
  490. ;=====================================================
  491.  
  492. ;    PROCESS RELOCATABLE ITEM
  493.  
  494. RELITM:    gbits    2
  495.     dec    a
  496.     jp    m,splink
  497.     gbits    16
  498.     ret
  499.  
  500. ;=====================================================
  501.  
  502. ;    GET SPECIAL LINK ITEM
  503.  
  504. SPLINK:    gbits    4
  505.     ld    e,a
  506.     ld    D,0
  507.     ld    hl,sltbl
  508.     add    hl,de
  509.     add    hl,de
  510.     ld    e,(hl)
  511.     inc    hl
  512.     ld    d,(hl)
  513.     ex    de,hl
  514.     jp    (hl)
  515.  
  516. ;=====================================================
  517.  
  518. ;Table of entry points for processing the 16
  519. ;possible special link items of the MREL format.
  520.  
  521. sltbl:    dw    entsym,selcom,prgnam,lisrch
  522.     dw    extlnk,sizcom,chnext,entpnt
  523.     dw    extmo,extpo,sizdat,setloc
  524.     dw    chnadr,sizprg,endprg,endfil
  525.  
  526. ;=====================================================
  527.  
  528. ;    ENTRY SYMBOL
  529.  
  530. entsym:    call    bfield
  531.     bit    pubflg,(ix+outopt)
  532.     ret    z
  533.     call    prtsym            ;display string in symbuf
  534.     ret
  535.  
  536. ;=====================================================
  537.  
  538. ;    SELECT COMMON BLOCK
  539.  
  540. SELCOM:    jp    bfield
  541.  
  542. ;=====================================================
  543.  
  544. ;    PROGRAM NAME
  545.  
  546. prgnam:    call    bfield            ;returns pgmname in symbuf
  547.     res    namflg,(ix+outopt)    ;turn off module name storage
  548.     res    eom,(ix+status)        ;..and end-of-module flag
  549.     ld    hl,nambuf        ;initialize nambuf pointer
  550.     ld    (namptr),hl
  551.  
  552.     bit    modflg,(ix+outopt)    ;display the symbol if one
  553.     jr    nz,pn1            ;of the display options is on.
  554.     inc    (ix+fwid)        ;make this line 1 field wider
  555.     bit    pubflg,(ix+outopt)
  556.     jr    nz,pn1
  557.  
  558.     bit    delflg,(ix+outopt)    ;display symbol with a message
  559.     jr    nz,pn2            ;if this one is to be deleted
  560.     bit    repflg,(ix+outopt)    ;or 'replaced'
  561.     jr    nz,pn2
  562.     ret            ;its an append
  563.  
  564. ;here for one of the display options
  565. PN1:    res    pdone,(ix+status)    ;inhibit leading blanks
  566.     jp    prtsym            ;display string in SYMBUF
  567.  
  568. ;here when deletion or delete/append is the option
  569. pn2:    call    namchk            ;is it named on the cmd line?
  570.     jr    nc,pn3            ;jump if not
  571. ;this is one of the modules named on the cmd line..
  572.     ld    de,delmsg        ;'deleting..'
  573.     call    typlin
  574.     call    prtsym            ;display string in SYMBUF
  575.     set    skpflg,(ix+outopt)    ;delete module by skipping it.
  576.     ret
  577.  
  578. ;here for modules that are to be retained and
  579. ;copied to the new library file (not deleted).
  580. pn3:    ld    b,(ix+symlen)        ;this module wont be skiped
  581.     inc    b
  582.     ld    hl,nambuf        ;so output the name
  583. pn4:    call    strbyt            ;send (nambuf) to dest buffer
  584.     inc    hl
  585.     djnz    pn4
  586.     ret
  587.  
  588. ;=====================================================
  589.  
  590. ;    REQUEST LIBRARY SEARCH
  591.  
  592. lisrch:    call    bfield        ;library search
  593.     ret
  594.  
  595. ;    EXTERNAL LINK ITEM
  596.  
  597. extlnk:    ld    de,elierr        ;external link item
  598.     jp    superr
  599.  
  600. ;=====================================================
  601.  
  602. sizcom:        ;common size
  603. chnext:        ;chain external
  604. entpnt:        ;entry point
  605.     call    afield
  606.     call    bfield
  607.     ret
  608.  
  609. ;=====================================================
  610.  
  611. extmo:        ;external - offset
  612. extpo:        ;external + offset
  613. sizdat:        ;data size
  614. setloc:        ;set location counter
  615. chnadr:        ;chain address
  616. sizprg:        ;program size
  617.     call    afield
  618.     ret
  619.  
  620. ;=====================================================
  621.  
  622. ;    END OF PROGRAM
  623.  
  624. endprg:    call    afield            ;scan through module start addr
  625.     ld    a,l            ;hl=(bitcnt), count in L
  626.     cp    8
  627.     set    eom,(ix+status)        ;indicate end of module
  628.     ret    z            ;done if so.
  629.  
  630.     ld    b,a
  631.     jp    getbit            ;finish out a byte
  632.                     ;and return
  633.  
  634. ;=====================================================
  635.  
  636. ;    END OF FILE
  637.  
  638. endfil:    set    eos,(ix+status)        ;mark mrel end of file
  639.     ret
  640.  
  641. ;=====================================================
  642.  
  643. ;    GET A FIELD
  644. ;reads the 'A' field, ignores the contents
  645.  
  646. afield:    gbits    18
  647.     ret
  648.  
  649. ;=====================================================
  650.  
  651. ;    GET B FIELD HL=NAME
  652. ;Store symbol length in symlen,
  653. ;store symbol name in symbuf
  654. ;Preserve HL
  655.  
  656. bfield:    push    hl
  657.     gbits    3
  658.     dec    a            ;convert 0 length
  659.     and    111b            ;.to 8, allowing up to
  660.     inc    a            ;8 byte names & symbols
  661.     ld    (ix+symlen),a
  662.     ld    (ix+lopcnt),a
  663.     ld    hl,symbuf
  664.  
  665. bfloop:    push    hl
  666.     gbits    8
  667.     pop    hl
  668.     ld    (hl),a
  669.     inc    hl
  670.     dec    (ix+lopcnt)
  671.     jr    nz,bfloop
  672.  
  673. bf2:    pop    hl
  674.     ret
  675.  
  676. ;=====================================================
  677.     .SBTTL MREL SERVICING ROUTINES
  678. ;=====================================================
  679. ;the input byte has been exhausted. Move it
  680. ;to the destination buffer, then get another
  681. ;This Routine is called from GETBIT after it
  682. ;has been initialized with the address of GETREL.
  683.  
  684. ;call WITH
  685. ;    Source & Destination FCBs and buffers valid
  686.     
  687. ;RETURN WITH
  688. ;    HL -> New input byte
  689. ;    A  = (hl)
  690. ;    BC,DE preserved
  691.  
  692. getrel:    ld    hl,(srcptr)
  693.     call    strbyt            ;send to dest or nambuf
  694.                     ;preserves BC,DE,HL
  695.  
  696. getbyt:    push    bc            ;get next byte from SRC buffer
  697.     ld    hl,(srcptr)
  698.     ld    bc,(srccnt)
  699.     cpi                ;inc pointer & test buffer exhausted
  700.     ld    (srccnt),bc
  701.     ld    (srcptr),hl
  702.     call    po,bufld        ;if so, refill from source
  703.     ld    a,(hl)            ;the new input byte
  704.     pop    bc
  705.     ret
  706.  
  707. ;=====================================================
  708.     .sbttl SUBROUTINES
  709.     PAGE
  710.  
  711. ;sets up the FCB for the next file to be
  712. ;processed. The filename is obtained from the
  713. ;list on the command line, now in the local
  714. ;command line buffer.
  715. appin:
  716.     ld    hl,(cmdptr)
  717.     ld    a,(hl)
  718.     CP    cr
  719.     scf                ;in case end of list
  720.     ret    z            ;z = end of list
  721.  
  722.     res    0,(ix+eofflg)
  723.  
  724.     ld    de,fcb            ;get filespec for module
  725.     ld    bc,(defdu)        ;put explicit/default
  726.     call    fname            ;DU at FCB-1 & FCB
  727.     jp    nz,synerr
  728.     ld    a,cr
  729.     cp    (hl)
  730.     jr    z,appin1
  731.     inc    hl            ;->char AFTER the delimiter
  732. appin1:    ld    (cmdptr),hl        ;unless it's a cr (eoc)
  733.  
  734.     ld    de,fcb            ;fill in the filetype
  735.     ld    hl,srcext
  736.     call    doftyp            ;default type if required
  737.  
  738.     ld    de,appmsg        ;'Appending '
  739.     call    typlin
  740.     ld    hl,fcb+1
  741.     call    prtfil            ;send module name (=fn)
  742.     call    crlf
  743.     or    a            ;reset cy
  744.     ret
  745.  
  746. ;=====================================================
  747.  
  748. ;    WRITE OUT LIB BUFFER
  749. ;Write B records from the LIB buffer
  750.  
  751. libwr:    ld    de,(libbeg)
  752.     set    0,(ix+wrflg)        ;indicate write done.
  753. cw1:    call    setdma
  754.     ex    de,hl
  755.     ld    de,libfcb
  756.     call    wrrec
  757.     ld    de,128
  758.     add    hl,de
  759.     ex    de,hl
  760.     djnz    cw1
  761.     ret
  762.  
  763. ;=====================================================
  764.  
  765. ;    PRINT SYMBOL
  766. ;print the string at SYMBUF, length (ix+symlen)
  767.  
  768. prtsym::    bit    pubflg,(ix+outopt)
  769.     jr    z,ps0        ;jmp if not displaying public symbols
  770.     bit    pdone,(ix+status)
  771.     jr    z,ps0        ;jmp if not at start of a new line
  772.     ld    b,10
  773.     call    blank        ;send a blank field at start of new line
  774. ps0:    res    pdone,(ix+status)
  775.     ld    hl,symbuf
  776.     ld    b,(ix+symlen)
  777.     ld    c,10        ;field width for names
  778. ps1:    ld    a,(hl)
  779.     inc    hl
  780.     dec    c
  781.     call    conout
  782.     djnz    ps1
  783. ps2:    ld    b,c
  784.     call    blank            ;left justified in field of 10
  785.     bit    delflg,(ix+outopt)
  786.     jp    nz,crlf
  787.  
  788. ;conditional crlf. include screen pause
  789. ccrlf:    dec    (ix+fwid)
  790.     ret    nz
  791.  
  792. ccrlfr:    ld    (ix+fwid),5        ;print 'em 5 across
  793.     call    crlf            ;start a new line
  794.     bit    pubflg,(ix+outopt)
  795.     jr    z,pause            ;displaying names & entry points?
  796.     set    pdone,(ix+status)    ;yes, set up for leading spaces
  797. pause:    dec    (ix+scrlin)        ;count lines sent to screen
  798.     ret    nz
  799.     ld    a,(inidat+scrlin)
  800.     ld    (ix+scrlin),a        ;reinitialize the screen line counter
  801.     ld    de,pawsm        ;'strike any key..'
  802. ;turn printer off here, if it's active
  803.     call    typlin
  804.     call    conin
  805.     ld    de,epaws        ;erase pause msg - hard on a printer!
  806.     call    typlin
  807. ;turn the printer back on if required
  808.     bit    pubflg,(ix+outopt)    ;module names plus publics?
  809.     ret    z            ;done if not
  810. ptitl1:                    ;..else send a new header line
  811. ;    res    pdone,(ix+status)
  812.     ld    de,titl01        ;send title line
  813.     call    typlin
  814.     ret
  815.  
  816. ;=====================================================
  817.  
  818. ;    STORE REL STREAM BYTE IN LIBBUF OR NAMBUF
  819. ;stores a bit stream byte in the LIB buffer,
  820. ;writing the buffer to disk when it becomes full
  821. ;OR stores the bit stream byte in NAMBUF for later
  822. ;possible transfer to the LIB buffer if this module
  823. ;is not being skipped. That decision is made after
  824. ;the name has been read and analysed.
  825.  
  826. ;call WITH:
  827. ;    iy -> next LIB buffer loc
  828. ;    HL -> byte to store
  829. ;RETURN WITH:
  830. ;    BC,DE,HL preserved
  831. ;    iy -> next LIB buffer loc (may be unchanged)
  832.  
  833. strbyt:    ld    a,(outopt+data)
  834.     and    1 shl pubflg ! 1 shl modflg ! 1 shl namflg ! 1 shl skpflg
  835.     jr    z,ssstor
  836.  
  837. ;here if Public, or Module names, or skipping, or namflg set
  838.     bit    namflg,a        ;doing a module name?
  839.     ret    z            ;return if not
  840.  
  841. ;redirect bit stream byte to the name buffer.
  842. ;It will be transferred later to the LIB buffer if
  843. ;this module is to be included in the new LIB
  844.     push    bc
  845.     ld    bc,(namptr)
  846.     ld    a,(hl)            ;SAVE IN
  847.     ld    (bc),a            ;NAME BUFFER
  848.     inc    bc
  849.     ld    (namptr),bc
  850. pgndon:    pop    bc
  851.     ret
  852.  
  853. ;here if append, delete, or replace
  854. ssstor:    push    bc
  855.     ld    a,(hl)            ;transfer a byte
  856.     ld    (iy+0),a
  857.     INC    iy
  858.  
  859.     ld    bc,(libcnt)        ;maintain 'bytes left'
  860.     dec    bc            ;counter
  861.     ld    (libcnt),bc
  862.  
  863.     ld    a,b            ;test for no space left
  864.     or    c
  865.     jp    nz,ssdone
  866.  
  867.     push    hl            ;write out buffer if
  868.     push    de            ;no space left
  869.     ld    a,(liblen)        ;b = number of records to write
  870.     ld    b,a
  871.     call    libwr
  872.     ld    hl,(libsiz)        ;initialize counter
  873.     ld    (libcnt),hl
  874.     ld    iy,(libbeg)        ;initialize buffer pointer
  875.     pop    de
  876.     pop    hl
  877.  
  878. ssdone:    pop    bc
  879.     ret
  880.  
  881. ;=====================================================
  882.  
  883. ;    CHECK COMMAND LINE FOR NAME IN SYMBUF
  884.  
  885. namchk:    ld    de,(cmdptr)
  886. nc1:    ld    hl,symbuf
  887.     ld    b,(ix+symlen)
  888. nc2:    ld    a,(de)
  889.     inc    de
  890.     cp    (hl)
  891.     inc    hl
  892.     jr    nz,ncskip
  893.     djnz    nc2
  894.  
  895.     ld    a,(de)        ;must have terminator
  896.     cp    ','        ;to be a real match
  897.     jr    z,ncfnd
  898.     cp    cr
  899.     jr    z,ncfnd
  900.     or    a
  901.     ret
  902.  
  903. ncfnd:    scf
  904.     ret
  905.  
  906. ncskip:    ld    a,(de)        ;skip current entry
  907.     inc    de
  908.     cp    ','
  909.     jr    z,nc1
  910.     cp    cr
  911.     ret    z
  912.     jr    ncskip
  913.  
  914. ;=========================================================
  915.     .SBTTL HELP & INITIALIZATION
  916.     PAGE
  917.  
  918. help:
  919. ;help is invoked with an empty command tail, or one or two
  920. ;'/' or '?' characters. The '/' and '?' are interchangeable.
  921.  
  922.     ld    A,(fcb+1)
  923.     cp    ' '        ;if nothing there, show help
  924.     jr    z,prhelp
  925.     and    a,2fh        ;make '/' and '?' equivalent
  926.     cp    '/'        ;possible help request?
  927.     ret    nz    
  928.     ld    a,(fcb+2)
  929.     cp    ' '        ;just one slash means help
  930.     jr    z,prhelp
  931.     and    a,2fh        ;make '/' and '?' equivalent
  932.     cp    '/'        ;also respond to 2 slashes
  933.     ret    nz
  934.  
  935. prhelp:    ld    de,hlpmsg    ;print help message
  936.     call    typlin
  937. ;    jp    mainx        ;done. 
  938.     ld    sp,(stack)    ;recover caller stack
  939.     ret            ;return without warm boot
  940.  
  941. ;=====================================================
  942.  
  943. init:
  944.     call    retud
  945.     ld    de,($memry)
  946. ;allocate buffers and fill in buffer control blocks
  947.     allocb    cmd
  948.     allocb    lib
  949.     allocb    src
  950.  
  951. ;initialize indexed data area
  952.     ld    bc,endata-inidat
  953.     ld    hl,inidat
  954.     ld    de,data
  955.     ldir
  956.     ld    a,(lbopt1)
  957.     ld    (ix+outopt),a
  958.  
  959. ;initialize other data
  960.     ld    hl,nambuf
  961.     ld    (namptr),hl
  962.     ret
  963.  
  964. zinit:    ld    hl,(z3env)
  965.     ld    a,h
  966.     or    l
  967.     ret    z            ;not Z3
  968.  
  969. ;install the name of this program in the help screen
  970.     ld    e,exfcbo    ;Z3 external FCB offset
  971.     call    pkgoff        ;DE -> ext fcb
  972.     ex    de,hl
  973.     inc    hl        ;->filename
  974.     ld    de,myname+7    ;pgm name in help screen
  975.     ld    a,(de)
  976.     cp    spc        ;is the last char blank ?
  977.     ret    nz        ;if not, name is already installed.
  978.  
  979. cpynam:    ld    bc,7
  980.     add    hl,bc        ;hl->last char in fcb name
  981.     ex    de,hl
  982.     sbc    hl,bc        ;->invok1
  983.     ex    de,hl
  984.     ld    b,8
  985.     ld    a,spc
  986.     call    fill        ;increments de to myname+8
  987.     ld    b,8        ;copy up to 8 char.
  988. cpnm1:    ld    a,(hl)
  989.     dec    hl
  990.     cp    spc
  991.     jr    z,cpnm2        ;don't copy spaces
  992.     dec    de        ;dec first to get back into range
  993.     ld    (de),a
  994. cpnm2:    djnz    cpnm1
  995.     ret
  996.  
  997. ;=====================================================
  998.     .SBTTL ERROR HANDLING
  999.     PAGE
  1000.  
  1001. badfil:    ld    hl,fcb+1
  1002.  
  1003. ;entry for other fcb's
  1004. badf2:    ld    de,ermsg1        ;report not found
  1005.     call    typlin
  1006.     call    prtfil
  1007.     ld    a,"'"
  1008.     call    conout
  1009.     jp    mainx
  1010.  
  1011. ;=====================================================
  1012.  
  1013. ;Print a filename.typ on the console
  1014. ;call WITH
  1015. ;    HL -> FN.FT (format xxxxxxxx.xxx, space filled)
  1016.  
  1017. prtfil:    ld    b,8        ;xxxxxxxx
  1018.     call    zl1
  1019.     ld    a,'.'
  1020.     call    conout
  1021.     ld    b,3        ;xxx
  1022.     call    zl1
  1023.     ret
  1024.  
  1025. ;Print up to (b) characters or until spc
  1026. zl1:    ld    a,(hl)
  1027.     inc    hl
  1028.     cp    ' '
  1029.     jr    z,zl2
  1030.  
  1031.     call    conout
  1032.     djnz    zl1
  1033.     ret                ;(b) char sent, hl->next field
  1034.  
  1035. zl2:    dec    hl            ;back up to last char
  1036. zl3:    inc    hl            ;->delimiter
  1037.     djnz    zl3            ;repeat until end of field
  1038.     ret
  1039.  
  1040. ;=====================================================
  1041.  
  1042. ;called from 'load source buffer' if EOFflag
  1043. ;..also used for exit for non-rel file.
  1044. badrel:    ld    hl,fcb+1
  1045.     call    prtfil
  1046.     ld    de,ermsg4
  1047.     jr    error
  1048.  
  1049. rderr:    ld    de,ermsg2
  1050.     jr    error
  1051.  
  1052. superr:    call    typlin
  1053.     ld    de,supmsg        ;not supported!
  1054.     jr    error
  1055.  
  1056. synerr:    ld    de,synmsg        ;syntax error
  1057.     jr    error
  1058.  
  1059. error:    call    typlin
  1060.     jp    mainx
  1061.  
  1062. ;=====================================================
  1063.     .SBTTL MESSAGE POOL
  1064.  
  1065. OPTMSG:    db 'Invalid option specification!',cr,lf,cr,lf,0
  1066.  
  1067. signon:    db cr,lf,lf
  1068.     db 'Z/CPM Library Manager, Version ',vers,'.',rev,' Copyright 1988 '
  1069.     db 'A.E. Hawley',cr,lf,lf,0
  1070.  
  1071. hlpmsg:    db 'Function: Create, Modify, or display contents of',cr,lf
  1072.     db ht,'  a REL format Library file (LIB).',cr,lf,lf
  1073. usemsg:    db 'Syntax:',cr,lf,'     '
  1074. myname:    db '   RLIB    LIB[=MOD[,MOD...]]  [[/]<option>]',cr,lf,lf
  1075.     db '<option> is one of:',cr,lf
  1076.     db ht,'M - Display names of modules in LIB',cr,lf
  1077.     db ht,'P - Display names and public symbols in LIB',cr,lf
  1078.     db ht,'D - Delete modules MOD ',cr,lf
  1079.     db ht,'R - Replace MOD(s) in LIB',cr,lf
  1080.     db ht,'A - Append MOD(s) to LIB, create new LIB if required',cr,lf,lf
  1081.     db 'If no option is present, then',cr,lf
  1082.     db ht,'Default is P if LIB is the only argument (no "="), and',cr,lf
  1083.     db ht,'Default is A if the form "LIB=MOD[,MOD...]" is present.',cr,lf
  1084.     db lf,0
  1085.  
  1086. SYNMSG:    dz    'Syntax error in command line!'
  1087. DELMSG:    dz    'Deleting '
  1088. APPMSG:    dz    'Appending '
  1089. ERMSG1:    dz    'Can''t find file '''
  1090. ERMSG2:    dz    cr,lf,'Read error!'
  1091. ERMSG4:    dz    ' is an invalid rel file!'
  1092. LSERR:     dz    'Library search'
  1093. SUPMSG:    dz    ' not supported!',cr,lf
  1094. ELIERR:    dz    'External link item'
  1095. pawsm:     dz    cr,lf,'CR or Space to continue',cr
  1096. epaws:     dz    '                       ',cr
  1097. titl01:    dz    'module:   Entry Point Symbol(s):',cr,lf
  1098.  
  1099.     .SBTTL    DATA AREA
  1100.     PAGE
  1101. ;---------------------------------------
  1102.  
  1103. data:    ds    9        ;indexed data area
  1104. datae:                ;end, for length calc
  1105. bitcnt:    ds    2        ;used by GETbit or bitS (called by name)
  1106.  
  1107. ;---------------------------------------
  1108.  
  1109. cntr:    ds    2        ;loop counter
  1110.  
  1111. symbuf:    ds    8        ;symbol buffer
  1112.  
  1113. namptr:    ds    2
  1114. nambuf:    ds    10        ;room for first 10 bytes of rel file
  1115.  
  1116. eofbyt:    db    mrleof
  1117.  
  1118. ;---------------------------------------
  1119.  
  1120. ;file and command control blocks here
  1121.     .slist            ;save listing control flags
  1122.     .sall
  1123.     filfab    cmd
  1124.     filfab    lib
  1125.     filfab    src
  1126.     .rlist            ;restore listing controls
  1127. ;---------------------------------------
  1128.  
  1129.     ds    2*20        ;program stack space
  1130. stack:    ds    2        ;callers stack stored here
  1131. $memry:    ds    2        ;place for buffers to start
  1132.  
  1133.     end
  1134.