home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / jsage / znode3 / uploads / t12.lbr / T12.MZC / T12.MAC
Encoding:
Text File  |  1993-06-07  |  35.1 KB  |  1,420 lines

  1.     TITLE 'ZLT (Z-system Library Typer), September 16, 1989'
  2. ;
  3. VER    EQU    12        ; Current version number
  4. SubVers    equ    'a'        ; special modification
  5. ;
  6. ; ZLT types normal, crunched or squeezed files, either directly or from
  7. ; .LBR members.  Wildcards access a series of library members OR files.
  8. ;
  9. ; Version 1.2a modifications by Gene Pizzetta, October 3, 1989
  10. ; Removed messages, sign-on and instruction lines, and filename
  11. ; displays.  Error messages and usage screen still operable.
  12. ; Defaults to no paging.  Prints all characters, including control
  13. ; characters (except ^Z), to screen.  This is a special version for
  14. ; graphic screen displays.  No filetype limit.
  15. ;
  16. ; Version 1.2 modifications by Ken Reid, September 16, 1989
  17. ; Installed LZH-decoding module to handle files compressed with CRLZH.
  18. ; No other changes. (UNLZH module courtesy of Roger Warren)
  19. ; Added SMACZLT.COM alias that uses SLRMAC and SLRNK+
  20. ;
  21. ; Version 1.1 modifications by Bruce Morgen, September 12, 1988
  22. ; Installed character delay code like PAGE has, fixed command
  23. ; name print routine to strip high bits.  Re-implemented Howard
  24. ; Goldstein's more frequent pause checking, although I kludged
  25. ; my own code for it, no longer "owning" the LT source.  Made
  26. ; disabling of paging with Control-Z a toggle rather than a
  27. ; permanent cancellation.  Disallowed wildcards within LBR file
  28. ; specifications under CP/M 3.x (for Z3PLUS users).  Truncated
  29. ; long Z3LIB/SYSLIB symbol names to 6 characters so RMAC could
  30. ; by used in addition to M80 or SLRMAC, rebuilt UNC.REL to use
  31. ; the public symbol "UNCOUT" instead of "OUT", which is a taboo
  32. ; reserved word for RMAC.  There are now two sample assembly
  33. ; aliases, M80ZLT (M80 and ZLINK) and RMACZLT (RMAC and LINK).
  34. ; Note:
  35. ;    For unmodified RMAC, rename to ZLTxx.ASM before running
  36. ;     RMACZLT.
  37. ;-----------------------------------------------------------------------
  38. ; December 15, 1987, ZLT Version 1.0
  39. ;
  40. ; LT was always a marginal file extraction tool at best, so I've spun
  41. ; off ZLT as a typer-only program -- for ZCPR3-compatible systems
  42. ; only.  Use Bob Peddicord's LBREXT for extraction-with-uncompression
  43. ; chores.  Eliminating the parser code in favor of a simple Z3LOG
  44. ; call shrinks ZLT to very manageable proportions, while ZCPR 3.3
  45. ; takes care of security matters very competently.  Filetype exclu-
  46. ; sion is the one remaining assembly-time option of any significance,
  47. ; line count limits are still overridden by a non-zero wheel byte.
  48. ;
  49. ; ZLT is basically a Z-ified LT23 with file extraction and parsing
  50. ; code removed and one significant feature added: ZLT handles wild-
  51. ; card filespecs for files in the same manner as for LBR members --
  52. ; LT23 simply settled for the first matching file found by BDOS.
  53. ; The help message routine has been heavily modified to show the
  54. ; actual name of the program and the options available to the user.
  55. ; Other displays screwed up by questionable conditional assemblies
  56. ; in LT2x.MAC have also been (or seem to be) fixed.  ZLT now appears
  57. ; to be fully re-entrant, even from a help-message-only run.
  58. ;
  59. ; In deferrence to the formidable Prof. Falconer, ZLT remains coded
  60. ; in Intel mnemonics and 8080-compatible opcodes for M80 (SLRMAC will
  61. ; undoubtedly handle it just fine too) - use Irv Hoff's XIZ tool to
  62. ; translate it for Zilog-only assemblers.  Linkage with L80 is possi-
  63. ; ble, I suppose, but Echelon's ZLINK (or DRI's LINK) is much better
  64. ; for that job.  Use the ASMZLT alias (for M80 and ZLINK) as a model.
  65. ; In addition to the UNC and WILDEX modules, you'll also need Z3LIB
  66. ; and SYSLIB - almost any vintage of these should be OK.  Make sure
  67. ; to use Z3INS or Z-RIP on ZLT.COM if you still run ZCPR 3.0, or if
  68. ; you intend to use ZLT with a generic-CP/M CCP emulator like LUX77B.
  69. ;
  70. ; To accommodate a ZCPR3 header, the remaining option bytes start at
  71. ; 10Bh, followed by the filetype exclusion table.  Zeroes at the
  72. ; three active bytes turn off linecount limits, filetype exclusion and
  73. ; control-character filtering, in that order.
  74. ;
  75. ;                    Bruce Morgen
  76. ;
  77. ; c/o    NAOG/ZSIG    P.O. Box #2781        Warminster, PA    18974
  78. ;
  79. ; Phone:    215-443-9031    (East Coast business hours only)
  80. ;
  81. ; RAS:    Lillipute Z-Nodes    (312-649-1730, 312-664-1730)
  82. ;    DHN*            (215-623-4040)
  83. ;        (all 300/1200/2400 baud & 24 hours)
  84. ;____________________________________________________________________
  85. ;
  86. ; Revision history of LT (Library Typer) by C.B. Falconer follows:
  87. ;____________________________________________________________________
  88. ;
  89. ; 08/12/87  Fixed to properly handle 0-length files.  Modified to
  90. ;   v23     check for pause and abort from console after every typed
  91. ;        character rather than at the end of each line.  This was
  92. ;        necessary to prevent loss of data on some very slow
  93. ;        terminals such as the one I use, and to enable the typing
  94. ;        of a file with no linefeeds to be aborted.    Also fixed the
  95. ;        tab expansion routine to work correctly with files con-
  96. ;        taining unusual control characters such as backspace, and
  97. ;        made the "turn up one line" feature more foolproof.
  98. ;                    - Howard Goldstein
  99. ;
  100. ; 07/30/87  Added the long needed ZCPR/ZCMD support of maximum user
  101. ;   v22     area.  When the UZCPR option is set, the page 0 value
  102. ;        will be examined to determine if the requested user area
  103. ;        is within the allowable range.  This is primarily useful
  104. ;        on RCP/M's (but I suspect that is where LT is primarily
  105. ;        used).  Added code to allow overriding the line counter
  106. ;        and user area restrictions when the wheel is active.
  107. ;                    - Gary Inman, Sysop
  108. ;                      West Los Angeles RCP/M
  109. ;
  110. ; 07/21/87  When at a [more] pause, the space bar now turns up one
  111. ;   v21     line at a time.  LTxx is often used on RCPM systems as
  112. ;        their general purpose TYPE.COM program.  This makes it
  113. ;        compatible with UNARC16.  These two  programs are used
  114. ;        in the popular LUX program to type ASCII files in ARC,
  115. ;        ARK or LBR files.  I have always liked this feature in
  116. ;        UNARC16 and decided to add it to LT20.  I believe most
  117. ;        users will find this quite useful and hope JB Falconer
  118. ;        does not mind my adding this feature.  This version is
  119. ;        a little over 4k.  If this makes any problem, just use
  120. ;        an earlier version.     - Irv Hoff, Sysop
  121. ;                      PRACSA RCPM
  122. ;
  123. ; 07/17/87  Able to use wheel byte in conjunction with OUTFLG flag.
  124. ;   v20     One byte added in ddt modifiable area at program start.
  125. ;        WHLFLG and/or WHEEL now tested in conjunction with the
  126. ;        OUTFLG flag eliminating need for two copies of program
  127. ;        when used on a remote system.  Found that it would not
  128. ;        assemble properly using M80/L80 because of YES/NO, now
  129. ;        corrected.    Restored program name, version number, and
  130. ;        author credit. Other minor mods to keep code size <4k.
  131. ;                    - G.F. Reding [72436,45]
  132. ;
  133. ; 06/10/87  Change to only display characters between "[" and "]" in
  134. ;   v19     the header of crunched files as other characters in this
  135. ;        area are reserved.    Removed the redundant "IF NOT UNCR"
  136. ;        (marked ";;;;") following an "ELSE" which prevented LT18
  137. ;        from being assembled in its distributed form. Slight text
  138. ;        changes to keep <4k.    - Steven Greenberg
  139. ;
  140. ; 12/28/86  Allows access to .LBR files > 512k.  Was using CPM 1.4
  141. ;   v18     variety of direct access.  Mods to keep under 4k total.
  142. ;        Should CP/M v1.4 check and refusal.
  143. ;                    - C.B. Falconer
  144. ;
  145. ; Previous LT revisions, all by C.B. Falconer:
  146. ;
  147. ; v17, 12/13/86; v16, 11/24/86; v15, 11/17/86; v14, 11/15/86;
  148. ; v13, 2/12/86; v12, 12/5/84; v11, 12/4/84; v10, 10/2/84.
  149. ;
  150. ; Adapted from Steven R. Holtzclaw's "LUXTYP (06/10/83)"
  151. ; for independent use without the complete LUX system.
  152. ;
  153. ;-----------------------------------------------------------------------
  154. ;
  155.     CSEG
  156. ;
  157. NO    EQU    0        ; For conditional assembly
  158. YES    EQU    NOT NO        ; (Some assemblers don't like 0FFh)
  159. ;
  160. ;
  161. ; Assembly time configurable areas.  Each increases COM file size.
  162. ;
  163. LIMITL    EQU    YES        ; Yes allows output line limits
  164.                 ; (if wheel byte is not set)
  165.  
  166. LIMITT    EQU    no        ; Yes allows file type restriction
  167.  
  168. DUSPEC    EQU    YES        ; Use DU/DIR-style drive/user specs?
  169.                 ; (otherwise forces current DU)
  170.  
  171. WHLDU    EQU    YES        ; Make DU specs wheel-dependent?
  172.  
  173. ACREDIT    EQU    YES        ; Want author names in sign-on?
  174.  
  175. NOCTRL    EQU    no        ; Yes to prevent control char. output
  176.  
  177.      IF    WHLDU AND NOT DUSPEC
  178. OOPS    EQU    NOVALUE;MUST HAVE DUSPEC YES IF YOU WANT WHLDU YES!
  179.      ENDIF            ; WHLDU AND NOT DUSPEC
  180. ;
  181. ; Configurable values.
  182. ;
  183. LNMAX    EQU    16H*3        ; 0 for no limit, else max file size (to 255)
  184. ;....
  185. ;
  186. BELL    EQU    07H
  187. BS    EQU    08H
  188. TAB    EQU    09H
  189. LF    EQU    0AH
  190. CR    EQU    0DH
  191. ;
  192. ; CP/M-DOS+-ZRDOS system values
  193. ;
  194. BDOS    EQU    0005H
  195. FCB1    EQU    05CH
  196. FCB2    EQU    06CH
  197. TBUFF    EQU    80H
  198. ;
  199. ; BDOS calls
  200. ;
  201. CIO    EQU    6        ; Direct console I/O
  202. GETVER    EQU    12
  203. OPEN    EQU    15
  204. SRCHF    EQU    17
  205. FREAD    EQU    20
  206. SETDMA    EQU    26
  207. FRDRAN    EQU    33        ; Read random record
  208. ;
  209.     CSEG
  210. ;
  211.     EXTRN    WILDEX        ; Sigi Kluger wildcard expander
  212.     EXTRN    Z3INIT,GETWHL,GETCRT,GETEFCB    ; From Z3LIB
  213.     EXTRN    GETSPEED            ; Added @v1.1
  214.     EXTRN    INITFCB            ; From SYSLIB
  215.     EXTRN    ISDIGIT            ; Added @v1.1
  216.     EXTRN    UNC        ; Falconer-Greenberg UNCR module
  217.     EXTRN    UNL        ; R. Warren UNLZH module
  218.  
  219. ;    NOTE: LINK WILDEX.REL FIRST & UNC.REL LAST!
  220.  
  221.      IF    DUSPEC
  222.     EXTRN    Z3LOG        ; From Z3LIB
  223.     EXTRN    PUTUD,GETUD    ; From SYSLIB
  224.      ENDIF            ; DUSPEC
  225. ;
  226.     PUBLIC    GETBYT,UNCOUT    ; Referenced by UNC
  227.     PUBLIC    GLZHUN,PLZHUN    ; Referenced by UNL
  228. ;
  229. ZLT:    JMP    START
  230.     DB    'Z3ENV',1
  231. Z3EADR:    DW    00
  232. ;
  233. ; Configuration values, even if unused via "limit" options
  234. ;
  235. MAXLIN:    DB    LNMAX        ; Max lines to type, 0 = unlimited
  236. TYPFLG:    DB    LIMITT        ; 0 for all file types, else selective
  237. CTLFLG:    DB    NOCTRL        ; 0 allows control char print
  238. KILLST:    DB    YES        ; Non-zero to disable lister output,
  239. ;                ; reserved for future, not yet used.
  240. ;
  241. ; '?' matches any character. Alpha order for convenience only,
  242. ; a complete sequential scan is done.  An existing name can be
  243. ; made to disappear by setting its high order bit somewhere.
  244.  
  245.      IF    LIMITT        ; Table of invalid file types
  246. BADTBL:    DB    'ABS'        ; Intended to disable
  247.     DB    'ARC'        ; ===================
  248.     DB    'ARK'
  249.     DB    'BAD'
  250.     DB    'CRL'
  251.     DB    'C?M'        ; COM, CQM, CZM
  252.     DB    'E?E'        ; EXE, EQE, EZE   (MSDOS executable)
  253.     DB    'IRL'
  254.     DB    'I?T'        ; INT, IQT, IZT
  255.     DB    'LBR'
  256.     DB    'O?J'        ; OBJ, OQJ, OZR
  257.     DB    'P?D'        ; PCD, PQD, PZD   (executable by RUNPCD)
  258.     DB    'TX#'
  259.     DB    'RBM'
  260.     DB    'R?L'        ; REL, RQL, RZL
  261.     DB    'S?R'        ; SLR, SQR, SZR   (SLR format rel files)
  262.     DB    'SYS'
  263.     DB    'LZH'        ; Spares, for user configuration
  264.     DB    'ZIP'
  265.     DB    0,0,0
  266.     DB    0        ; Table end marker
  267.      ENDIF            ; LIMITT
  268.  
  269. START:    LXI    H,0        ; Set up HL for add to stack
  270.     SHLD    MEMCNT        ; Zero the memory count
  271.     DAD    SP        ; Add stack pointer
  272.     SHLD    STACK        ; Keep stack contents
  273.     LXI    SP,STACK    ; Set up local stack
  274.      IF    DUSPEC
  275.     CALL    PUTUD        ; Stash entry DU for exit
  276.      ENDIF            ; DUSPEC
  277.     LHLD    Z3EADR
  278.     MOV    A,L
  279.     ORA    H
  280.     LXI    D,NOTZ3
  281.     JZ    EXEUNT        ; Assume 0000H ENV is non-Z3
  282.     CALL    Z3INIT
  283.     LDA    FCB1+1
  284.     CPI    '/'
  285.     JZ    HELPER
  286.     CPI    ' '
  287.     JZ    HELPER
  288.     CALL    GETCRT        ; Point current CRT descriptor
  289.     INX    H        ; Bump to "usable lines"
  290.     INX    H
  291.     MOV    A,M
  292.     STA    PAGSIZ        ; Store locally
  293.     LXI    H,ENDU        ; Init. 3 words for re-entrance
  294.     SHLD    NAMPTR
  295.     SHLD    NAMPT1
  296.     LXI    H,65535
  297.     SHLD    RCNT
  298.     LXI    D,FCB1        ; Point target FCB
  299. ;
  300.      IF    DUSPEC        ; "Parse" the command line
  301.      IF    WHLDU
  302.     CALL    GETWHL
  303.     CNZ    Z3LOG        ; Non-wheels get current DU only
  304.      ELSE            ; IF NOT WHLDU
  305.     CALL    Z3LOG        ; Log in as per Z3's parse
  306.      ENDIF            ; WHLDU
  307.      ENDIF            ; DUSPEC
  308. ;
  309.     XRA    A
  310.     STAX    D        ; Force current drive
  311.     STA    PAGLNS        ; Init. line count to 0
  312.     LXI    H,TBUFF        ; Point command tail char. count
  313.     MOV    C,M        ; Get into C
  314.     MOV    B,A        ; Now in BC (A = B = 0)
  315.     DAD    B        ; Add to point HL at char.
  316.     MOV    A,M        ; Get char.
  317.     CALL    ISDIGIT        ; Is it a decimal digit?
  318.     JNZ    NDELAY        ; If not, no inter-char. delay
  319.     MOV    C,A        ; Otherwise save it in C
  320.     DCX    H        ; Point to  previous char.
  321.     MOV    A,M        ; Into A
  322.     CPI    '/'        ; Option delimiter?
  323.     MOV    A,C        ; Get back value
  324.     JZ    GDELAY        ; Use it if we had a delimiter
  325. NDELAY:    XRA    A        ; Otherwise use zero
  326. GDELAY:    STA    CDELAY
  327.     CALL    LBROPN        ; Set up the library name buffer
  328.     STA    LBRFLG        ; Save extract/type flag
  329.     JNZ    START2        ; Type only
  330.     LHLD    MEMCNT        ; Get member count
  331.     MOV    A,L        ; Get member count lsb
  332.     ORA    H        ; Any members?
  333.     LXI    D,NFOUND
  334.     JZ    EXEUNT        ; No - exit
  335.  
  336. START2:
  337.     LDA    LBRFLG
  338.     ORA    A
  339.     JNZ    DUMP        ; Type only
  340. ;
  341. ; Per component loop
  342. ;
  343. NEXT:    CALL    INITLP        ; Initialize the "next" loop
  344.     CALL    GETMEM        ; Get next member FCB
  345.     JC    EXIT        ; All done...
  346.     CALL    LBRSET        ; Set up to read the library file
  347. ;
  348. ; Input setup, do the extraction and/or unsqueezing
  349. ;
  350. DUMP:
  351.      IF    LIMITT        ; Test the type of file
  352.     CALL    TSTTYP
  353.      ENDIF            ; LIMITT
  354.  
  355.     CALL    GET2HL        ; Get the first 2 bytes from the file
  356.     JNZ    ZERPRT        ; Special processing for 0-length file
  357.     MVI    A,076H
  358.     CMP    L
  359.     JNZ    ASPRT        ; Not squeezed - print an ascii file
  360.     MVI    A,0FFH
  361.     CMP    H
  362.     JZ    DUMPSQ        ; Squeezed, dump it
  363.     DCR    A        ; To 0feh
  364.     CMP    H
  365.     JZ    DUMPCR        ; Crunched, dump it
  366.     DCR    A
  367.     CMP    H
  368.     JNZ    ASPRT        ; Not squeezed - print an ascii file
  369. ;
  370. ; Output from a crlzh compressed file
  371. ;
  372.     CALL    NMSHOW        ; Show actual name etc
  373.     LHLD    NAMPTR        ; Free memory area, above names
  374.     CALL    UNL        ; Rel
  375.     LXI    D,BADFILE
  376.     JC    DONEM
  377.     JMP    DONE
  378. ;
  379. ; Output from a crunched file
  380. ;
  381. DUMPCR:
  382.     CALL    NMSHOW        ; Show actual name etc
  383.     LHLD    NAMPTR        ; Free memory area, above names
  384.     CALL    UNC        ; Rel
  385.     LXI    D,BADFILE
  386.     JC    DONEM
  387.     JMP    DONE
  388. ;
  389. ; Output from a squeezed component
  390. ;
  391. DUMPSQ:    CALL    GET2HL        ; Get and discard the next 2 bytes
  392.     CALL    NMSHOW
  393.     CALL    SQSETU        ; Setup the squeezed file
  394. ;
  395. ; List a squeezed component
  396. ;
  397. SQLOOP:    CALL    GETSQB        ; Get a byte from the file
  398.     JC    DONE        ; Eof - get next file name in queue
  399.     CALL    CRTYPE        ; Else print the char
  400.     JMP    SQLOOP        ; And loop for more
  401. ;.....
  402. ;
  403. ; Show UNSQ/UNCR member name, etc.  Optionally revise output name.
  404. ;
  405. NMSHOW:
  406.     lxi    d,outfcb+1
  407. NMSHW2:    PUSH    D        ; Filename area of OUTFCB
  408.     CALL    LBRGET        ; Get character from the file
  409.     POP    D        ; Restore pointer
  410.     ORA    A        ; Check for null
  411.     rz
  412.     inx    d
  413.     jmp    nmshw2
  414. ;.....
  415. ;
  416. ; Output an unsqueezed file/component
  417. ;
  418. ZERPRT:    STA    ZERLEN        ; Save zero length file flag
  419. ASPRT:
  420.     LDA    ZERLEN
  421.     ORA    A
  422.     JNZ    DONE        ; Don't type anything for 0-length file
  423.     MOV    A,L        ; Print
  424.     PUSH    H
  425.     CALL    CRTYPE        ; First
  426.     POP    H        ; (file out clobbers hl)
  427.     MOV    A,H        ; Two
  428.  
  429. ASPRT1:    CALL    CRTYPE        ; Bytes
  430.     CALL    LBRGET        ; Get a byte from the file
  431.     JZ    ASPRT1        ; Not eof, print and get more
  432.     JMP    DONE
  433. ;.....
  434. ;
  435. ; Done, send message
  436. ;
  437. DONEM:    CALL    TSTR
  438. ;
  439. ; Done, no message
  440. ;
  441. DONE:    LXI    SP,STACK    ; SP uncertain here - reset the stack
  442.     LDA    LBRFLG
  443.     ORA    A
  444.     JZ    NEXT
  445.     CALL    TLOOP
  446.     JMP    DUMP
  447. ;.....
  448. ;
  449. ; Initialize the "next" loop
  450. ;
  451. INITLP:            ; now defaults to no paging
  452. ;    LDA    PAGLNS
  453. ;    ORA    A
  454. ;    JNZ    INITL1        ; Paging was not stopped
  455.     xra    a
  456. INITLH:    STA    LINCN1        ; Else clear for fresh start
  457. ;    LDA    PAGSIZ
  458.     STA    PAGLNS        ; Restart any page pauses
  459.  
  460. INITL1:    LXI    H,ZEROS        ; Fill flag area with zeros
  461.     MVI    B,LASTZ-ZEROS    ; Count of zeroes to load
  462. ;
  463. ; Fill (HL) up for (B) with zeroes
  464. ;
  465.     XRA    A
  466.  
  467. INITL2:    MOV    M,A        ; Put a byte
  468.     INX    H        ; Next location
  469.     DCR    B
  470.     JNZ    INITL2        ; Fill all 11 bytes
  471.     RET
  472. ;.....
  473. ;
  474. ; Open the FILENAME.LBR file and the MEMBER.EXT files, returns Z-flag
  475. ; for library extraction, NZ for pure type
  476. ;
  477. LBROPN:    MVI    B,12        ; Field size for .LBR file
  478.     LXI    H,FCB1        ; Move first file FCB
  479.     LXI    D,LBRFCB    ; To LBRFCB
  480.     CALL    MOVE
  481.     XRA    A        ; Set ext & rec # to 0 for proper open
  482.     STA    LBREXT
  483.     STA    LBRSNO
  484.     LXI    H,FCB2+1    ; Source is member FCB name, no drive
  485.     MOV    A,M        ; First member character
  486.     CPI    ' '        ; Is it a space or control ?
  487.     JC    HELPER        ; Control, exit with help
  488.     JZ    TFILE        ; Space, type one file only
  489.     CPI    '/'
  490.     JNZ    ISALBR
  491.     INX    H
  492.     MOV    A,M
  493.     INX    H
  494.     MOV    E,M
  495.     DCX    H
  496.     DCX    H
  497.     CALL    ISDIGIT
  498.     JNZ    ISALBR
  499.     MOV    A,E
  500.     CPI    ' '
  501.     JZ    TFILE
  502. ISALBR:    LXI    D,LBRBUF
  503.     MVI    A,SETDMA    ; Do all I/O thru this buffer
  504.     CALL    SYS
  505.     LXI    D,MEMNAM    ; Move FCB2 to MEMNAM
  506.     MVI    B,11        ; Bytes to move
  507.     CALL    MOVE        ; Member name to local area
  508. ;
  509. ; Open the .LBR file
  510. ;
  511.     LXI    H,'BL'
  512.     SHLD    LBRTYP        ; Force .LBR type
  513.     MVI    A,'R'
  514.     STA    LBRTYP+2
  515.     CALL    FOPNLB        ; Open .LBR file
  516.     INR    A        ; Open ok?
  517.     JZ    NOFILE        ; Failure, abort with help
  518. ;
  519. ; Read the first record of the library directory
  520. ;
  521.     CALL    LBREAD        ; Read a sector
  522.     LHLD    LBRBUF+14    ; Get directory size
  523. ;
  524. ; Test for a valid library file
  525. ;
  526.     LDA    LBRBUF
  527.     ORA    A        ; Test first byte
  528.     LXI    D,CORRPT
  529.     JNZ    EXEUNT        ; Non-zero, bad .LBR file
  530. ;
  531. ; Read the next library directory record
  532. ;
  533. LBROP5:    PUSH    H        ; Save DIRSIZE
  534.     CNZ    LBREAD        ; Read a sector, except 1st pass
  535. ;
  536. ; Search for the member name in the library directory
  537. ;
  538.     LXI    H,LBRBUF    ; Process first entry
  539.     CALL    ADDMEM        ; To memory buffer
  540.     LXI    H,LBRBUF+20H    ; Process second entry
  541.     CALL    ADDMEM        ; To memory buffer
  542.     LXI    H,LBRBUF+40H    ; Process third entry
  543.     CALL    ADDMEM        ; To memory buffer
  544.     LXI    H,LBRBUF+60H    ; Process forth entry
  545.     CALL    ADDMEM        ; To memory buffer
  546.     POP    H        ; Count of dir entries
  547.     DCX    H        ; -1
  548.     MOV    A,H        ; Zero directory entries left ?
  549.     ORA    L
  550.     JNZ    LBROP5        ; No read another directory sector
  551.     RET
  552. ;.....
  553. ;
  554. ; The second parameter is missing, just type the main file, returns NZ
  555. ; flag to signal no library extraction
  556. ;
  557. TFILE:    LXI    D,FCB1        ; Get afn FCB @ 005Ch
  558.     CALL    INITFCB        ; Initialize
  559.     LXI    H,ENDU        ; Point HL at free RAM
  560.     SHLD    WBUFF        ; Stow the pointer for later
  561.     CALL    WILDEX        ; Expand afn to buffer
  562.     JZ    NOFILE        ; Contrary to source, Z=failure
  563.     SHLD    WCOUNT        ; Stow count
  564.     XCHG            ; Over to DE
  565.     LHLD    WBUFF        ; Get buffer start
  566.     LXI    B,16        ; 16 bytes/entry
  567. WBLOOP:    DAD    B        ; Compute end of buffer
  568.     DCX    D
  569.     MOV    A,E
  570.     ORA    D
  571.     JNZ    WBLOOP
  572.     SHLD    NAMPTR        ; Store as start of UNC's buffer
  573.     LXI    D,LBRBUF    ; Now set up DMA to do all I/O
  574.     MVI    A,SETDMA    ; through this buffer
  575.     CALL    SYS
  576.  
  577. TLOOP:    LHLD    WCOUNT        ; "per component loop" :-)
  578.     MOV    A,L        ; Test for no more files.
  579.     ORA    H
  580.     JZ    EXIT        ; If so, break out & quit
  581.     DCX    H        ; Otherwise WCOUNT = WCOUNT-1
  582.     SHLD    WCOUNT        ; Stow new value
  583.     LXI    D,LBRFCB    ; Point working FCB
  584.     PUSH    D        ; Save on stack
  585.     LHLD    WBUFF        ; Point next nfilenametyp@@@@
  586.     MVI    B,16        ; Length of move
  587.     CALL    MOVE        ; Do it, get new pointer back
  588.     SHLD    WBUFF        ; Stow it
  589.     POP    D        ; Restore working FCB
  590.     CALL    INITFCB        ; Initialize for open call
  591.  
  592.     CALL    FOPEN        ; Do the file open
  593.     INR    A
  594.     JZ    NOFILE
  595.  
  596.      IF    LIMITT
  597.     INX    D
  598.     XCHG
  599.     LXI    D,MEMFCB
  600.     MVI    B,11
  601.     CALL    MOVE        ; Name to memnam for checking
  602.      ENDIF            ; LIMITT
  603.  
  604.     CALL    INITLP        ; Other one pass initializers
  605.     ORI    0FFH        ; Set NZ flag
  606.     JMP    INITPT        ; Set up pointers, leave NZ flag
  607. ;.....                ; and return to caller...
  608. ;
  609. LBRSET:
  610.     lxi    h,memfcb+11
  611.     MOV    E,M        ; Get member starting record LSB
  612.     INX    H
  613.     MOV    D,M        ; And MSB
  614.     PUSH    D        ; Save
  615.     INX    H
  616.     MOV    E,M        ; Get member size LSB
  617.     INX    H
  618.     MOV    D,M        ; And MSB
  619.     XCHG            ; Into 'HL'
  620.     INX    H        ; +1
  621.     SHLD    RCNT        ; Save it in record count
  622.     POP    H        ; Restore starting record number
  623.     SHLD    LBRRNO
  624.     XRA    A
  625.     STA    LBRRNO+2    ; Set random rcd no
  626.     STA    LBREXT
  627.     CALL    FOPNLB        ; Open the LBR file again
  628.     INR    A
  629.     JZ    PREEOF        ; Should not happen
  630.     MVI    A,FRDRAN
  631.     CALL    SYS        ; Do a random read to put in sequential
  632.     ORA    A
  633.     JNZ    PREEOF        ; No such record
  634. ;
  635. ; Initialize pointers to read from LBRFCB
  636. ; A, HL  (but not flags)
  637. ;
  638. INITPT:    MVI    A,080H
  639.     STA    CHRCNT        ; Set char count to force read
  640.     LXI    H,LBRBUF-1
  641.     SHLD    BUFPTR
  642.     RET
  643. ;.....
  644. ;
  645. ; Get a byte from the .LBR member. GETBYT for UNCREL use
  646. ; A,F,D,E,H,L
  647. ;
  648. GETBYT:
  649. GLZHUN:
  650. LBRGET:    LDA    CHRCNT        ; Get pointer
  651.     INR    A        ; Point to next position
  652.     STA    CHRCNT        ; Put pointer back
  653.     JP    LBRGE1        ; Buffer not empty
  654.     CALL    ZBUFF        ; Empty, reset pointers, read sector
  655.     LHLD    RCNT        ; Get record count
  656.     DCX    H        ; -1
  657.     SHLD    RCNT        ; Set new record count
  658.     MOV    A,L
  659.     ORA    H
  660.     JZ    LBRGE2        ; If all records read
  661.     CALL    LBREAD        ; Read a sector
  662.     ORA    A
  663.     JNZ    LBRGE2        ; If read was unsuccessful
  664.  
  665. LBRGE1:    LHLD    BUFPTR
  666.     INX    H
  667.     SHLD    BUFPTR
  668.     MOV    A,M        ; No  - get the next byte
  669.     CMP    A        ; Set zero - no error
  670.     RET
  671. ;...
  672. ;
  673. LBRGE2:    MVI    A,0FFH
  674.     ORA    A
  675.     RET            ; Return non-zero for error
  676. ;.....
  677. ;
  678. ; Zero the buffer pointers (for reaccess from start)
  679. ;
  680. ZBUFF:    XRA    A        ; Empty, read another record
  681.     STA    CHRCNT        ; Clear the character count
  682.     LXI    H,LBRBUF-1
  683.     SHLD    BUFPTR
  684.     RET
  685. ;.....
  686. ;
  687. ; Read a sector from library file
  688. ;
  689. LBREAD:    MVI    A,FREAD
  690.     LXI    D,LBRFCB    ; LBR FCB
  691.     JMP    SYS        ; Read a block, and exit
  692. ;.....
  693. ;
  694. ; Get 2 bytes from input file into HL
  695. ;
  696. GET2HL:    CALL    LBRGET        ; Get a byte from the input file
  697.     RNZ            ; May be an empty component
  698.     PUSH    PSW
  699.     CALL    LBRGET        ; Get a byte from the input file
  700.     MOV    H,A
  701.     POP    PSW
  702.     MOV    L,A
  703.     RET
  704. ;.....
  705. ;
  706. NOFILE:    LXI    D,NOFMSG
  707.     JMP    EXEUNT
  708. ;.....
  709. ;
  710. HELPER:
  711.     LXI    D,SIGNON    ; Give name, version, credit
  712.     CALL    TSTR
  713.     LXI    D,USAGE        ; Give help menu
  714.     CALL    TSTRC
  715.     CALL    COMNAM        ; Show actual name of program
  716.  
  717.      IF    WHLDU AND DUSPEC
  718.     CALL    GETWHL
  719.     LXI    D,DUMSG
  720.     PUSH    PSW
  721.     PUSH    D
  722.     CNZ    TSTR
  723.     LXI    D,USAGE1
  724.     CALL    TSTR
  725.     CALL    COMNAM
  726.     POP    D
  727.     POP    PSW
  728.     CNZ    TSTR
  729.      ENDIF            ; WHLDU AND DUSPEC
  730.  
  731.      IF    DUSPEC AND NOT WHLDU
  732.     LXI    D,DUMSG
  733.     PUSH    D
  734.     CALL    TSTR
  735.     LXI    D,USAGE1
  736.     CALL    TSTR
  737.     CALL    COMNAM
  738.     POP    D
  739.     CALL    TSTR
  740.      ENDIF            ; DUSPEC AND NOT WHLDU
  741.  
  742.      IF    NOT DUSPEC
  743.     LXI    D,USAGE1
  744.     CALL    TSTR
  745.      ENDIF            ; NOT DUSPEC
  746.  
  747.     LXI    D,USAGE2
  748.     CALL    TSTR
  749.     XRA    A
  750.     CALL    INITLH
  751.     JMP    EXIT
  752. ;.....
  753. ;
  754. PREEOF:    LXI    D,EOFMSG
  755. ;
  756. ; Error exit, with message (DE)^
  757. ;
  758. EXEUNT:    CALL    TSTRC        ; Print message
  759.  
  760. EXIT:
  761.      IF    DUSPEC
  762.     CALL    GETUD        ; Restore entry conditions
  763.      ENDIF            ; DUSPEC
  764.     LHLD    STACK
  765.     SPHL            ; Restore original stack
  766.     RET            ; --exit-- to cp/m
  767. ;.....
  768. ;
  769. ; Output to CRT.  Entry name "out" for UNC or UNCREL use
  770. ;
  771. UNCOUT:                ; RMAC-compatible, unlike "OUT"
  772. PLZHUN:                 
  773. CRTYPE:
  774.     CPI    01AH
  775.     JZ    DONE        ; EOF on 01Ah for ASCII output
  776.     ANI    7FH        ; Make sure its ASCII
  777.     PUSH    PSW        ; Save the character
  778.     CALL    CRTYP4
  779.     LDA    CDELAY
  780.     CALL    ISDIGIT
  781.     CZ    DDELAY
  782.     POP    PSW
  783.     PUSH    PSW
  784.     CALL    COUT
  785.     POP    PSW        ; Restore character
  786.     CPI    0AH        ; Was it a line feed
  787.     RNZ            ; No - continue
  788.     CALL    GETWHL
  789.     JNZ    CRTYP3        ; Jump around the line count tests
  790.  
  791.      IF    LIMITL        ; Check for too many lines typed
  792.     LDA    LINCNT        ; Advance line counter
  793.     INR    A
  794.     STA    LINCNT
  795.     MOV    B,A        ; Line number in 'B'
  796.     LDA    MAXLIN        ; Max number of lines to type
  797.     ORA    A        ; Test flag
  798.     JZ    CRTYP3        ; If null function
  799.     CMP    B        ; Else compare to max lines
  800.     LXI    D,EXCESS
  801.     JZ    DONEM        ; Announce too much
  802.      ENDIF            ; LIMITL
  803.  
  804. CRTYP3:    LDA    LINCN1        ; Get line counter
  805.     MOV    B,A        ; Keep in 'B'
  806.     LDA    PAGLNS        ; Number of lines per page
  807.     DCR    A        ; Decrement and test flag
  808.     JM    CRTYP4        ; Function is null
  809.  
  810.     CMP    B        ; Compare to lines per page
  811.     JNC    CRTYP4        ; If not at maximum count
  812.     XRA    A        ; Clear lines counter
  813.     STA    LINCN1
  814.     LXI    D,MORE
  815.     CALL    TSTR        ; Announce the pause
  816.     CALL    PAUSE        ; Get input from console
  817.     CPI    ' '-1AH        ; Space for line at a time?
  818.     JNZ    $+8
  819.     MOV    A,B        ; Get original line count back
  820.     DCR    A        ; And set to "one line left"
  821.     STA    LINCN1
  822.     LXI    D,CLEAN
  823.     CALL    TSTR        ; Clear out the "[more]"
  824.  
  825. CRTYP4:    MVI    A,CIO        ; BDOS function
  826.     MVI    E,0FFH        ; BDOS function
  827.     CALL    SYS        ; Direct console in call
  828.     CPI    1AH
  829.     JNZ    NOTPAG
  830.     LDA    PAGLNS
  831.     ORA    A
  832.     LDA    PAGSIZ
  833.     JZ    PAGDR
  834.     XRA    A
  835. PAGDR:    STA    PAGLNS
  836.     RET
  837. NOTPAG:    CALL    ISDIGIT
  838.     JNZ    NOTDIG
  839.     STA    CDELAY
  840.     RET
  841. NOTDIG:    CALL    PSCHK
  842.     CPI    'S'-40H        ; CTL-S to pause?
  843.     JZ    PAUSE
  844.     ANI    5FH
  845.     CPI    'S'
  846.     RNZ            ; Not CTL-S, return
  847. ;
  848. ; Returns input -01Ah.    Aborts on c,C,^C or k,K,^K - next on CTL-X, etc.
  849. ;
  850. PAUSE:    MVI    A,CIO        ; BDOS function
  851.     MVI    E,0FFH
  852.     CALL    SYS        ; Direct console in call
  853.     ORA    A        ; Was a key entered ?
  854.     JZ    PAUSE        ; Not yet
  855.     CALL    PSCHK
  856.     SUI    01AH
  857.     RNZ            ; Not ^Z console entr
  858.     STA    PAGLNS        ; Disable pauses on ^Z
  859.     RET
  860. ;.....
  861. ;
  862. ; Pause check for special characters
  863. ;
  864. PSCHK:    CPI    'C'-40H        ; Want to abort?
  865.     JZ    PSCHK2        ; If yes, quit
  866.     CPI    'K'-40H
  867.     JZ    PSCHK2
  868.     CPI    'X'-40H        ; Jumping to next file?
  869.     JZ    PSCHK1
  870.     CPI    ' '        ; Space for "line at a time"?
  871.     RZ
  872.  
  873.     ANI    5FH        ; Insure in upper case
  874.     CPI    'C'
  875.     JZ    PSCHK2
  876.     CPI    'K'
  877.     JZ    PSCHK2
  878.     CALL    ISDIGIT
  879.     JZ    DDELAY
  880.     CPI    'X'
  881.     RNZ            ; If not, keep going
  882.  
  883. PSCHK1:    CALL    CRLF
  884.     JMP    DONE        ; Next file on CTL-X
  885.  
  886. PSCHK2:    LXI    D,ABRMSG
  887.     CALL    TSTRC
  888.     JMP    EXIT
  889.  
  890. DDELAY:    SUI    '0'
  891.     RZ
  892.     MOV    B,A
  893. DDLP1:    CALL    GETSPEED
  894.     LXI    H,0
  895.     LXI    D,500/4
  896. DDLP2:    DAD    D
  897.     DCR    A
  898.     JNZ    DDLP2
  899. DDLP3:    XTHL
  900.     XTHL
  901.     DCX    H
  902.     MOV    A,L
  903.     ORA    H
  904.     JNZ    DDLP3
  905.     DCR    B
  906.     JNZ    DDLP1
  907.     RET
  908. ;.....
  909. ;
  910. COUT:    MOV    E,A        ; Save output character
  911.     CPI    TAB
  912.     JZ    COUT2        ; Expand a tab
  913.     CPI    CR        ; Carriage return
  914.     JNZ    COUT0A
  915.     XRA    A        ; CR sets COLUMN to 0
  916.     JMP    COUT1A
  917.  
  918. COUT0A:    CPI    BS        ; Is char a backspace?
  919.     JNZ    COUT0B
  920.     LDA    COLUMN        ; Backspace sets COLUMN back one
  921.     DCR    A
  922.     JMP    COUT1A
  923.  
  924. COUT0B:    CPI    ' '        ; 
  925.     JC    COUT1B        ; Other controls don't affect COLUMN
  926.  
  927. COUT1:    LDA    COLUMN        ; Advance column counter
  928.     INR    A
  929.  
  930. COUT1A:    STA    COLUMN
  931.  
  932. COUT1B:    CALL    COUT3        ; Test control
  933.     MOV    A,E        ; Get character back
  934.     JZ    CTYPE        ; Else print the space
  935.     RET            ; Return to caller
  936. ;...
  937. ;
  938. COUT2:    MVI    E,' '
  939.     CALL    COUT1        ; Print a space
  940.     LDA    COLUMN
  941.     ANI    7        ; At next tab stop ?
  942.     JNZ    COUT2        ; Yes, continue
  943.     RET
  944. ;...
  945. ;
  946. COUT3:    LDA    CTLFLG        ; Get controls active
  947.     ORA    A        ; Test flag
  948.     RZ            ; Return if not
  949.     MOV    A,E        ; Get output char
  950.     CPI    ' '
  951.     JNC    COUT4        ; Not control, clear flags
  952.     CPI    CR
  953.     RZ
  954.     CPI    BS
  955.     RZ
  956.     CPI    BELL
  957.     RZ
  958.     CPI    LF
  959.     RET            ; Return with Z-flag set for linefeed
  960. ;...
  961. ;
  962. COUT4:    CMP    A        ; Set Z-flag
  963.     RET
  964. ;.....
  965. ;
  966.      IF    LIMITT        ; Test for type-able file
  967. TSTTYP:    LDA    TYPFLG        ; Get test flag
  968.     ORA    A        ; Test it
  969.     RZ            ; Return if ok to type all types
  970.      ENDIF            ; LIMITT
  971.  
  972.      IF    LIMITT
  973.     MVI    B,3
  974.     LXI    H,BADTBL-3    ; Index bad file type table
  975. TSTTY1:    INX    H        ; Next table address pointer
  976.     DCR    B        ; Bump loop counter
  977.     JNZ    TSTTY1        ; Do until at next table entry
  978.     MOV    A,M        ; Get a byte
  979.     ORA    A        ; End of table
  980.     RZ            ; Yes - ok to type this one
  981.     MVI    B,3        ; 3 char extension
  982.     LXI    D,MEMFCB+8    ; Index file name extension
  983.  
  984. TSTTY2:    LDAX    D        ; Get a byte from extension
  985.     ANI    7FH        ; Make sure its ascii
  986.     CMP    M        ; Same as in table
  987.     JZ    TSTTY3        ; Match, continue scan
  988.     MOV    A,M
  989.     CPI    '?'        ; '?' in table matches all
  990.     JNZ    TSTTY1        ; No match, next entry
  991.  
  992. TSTTY3:    INX    H        ; Bump table address pointer
  993.     INX    D        ; Bump extent pointer
  994.     DCR    B        ; Bump counter
  995.     JNZ    TSTTY2        ; Continue for 3 chars
  996.     LXI    H,MEMFCB+8    ; User name
  997.     LXI    D,CANT
  998.     CALL    TSTR        ; "can't type a '"
  999.     MVI    B,3        ; 3 byte file type
  1000.  
  1001. TSTTY5:    MOV    A,M        ; Get byte
  1002.     CALL    CTYPE        ; Give a chance to abort here
  1003.     INX    H        ; Next byte
  1004.     DCR    B
  1005.     JNZ    TSTTY5        ; Type all 3 bytes
  1006.     LXI    D,CANT2        ; "' FILE ",CR,LF
  1007.     JMP    DONEM        ; And do next file
  1008.      ENDIF            ; LIMITT
  1009. ;.....
  1010. ;
  1011. ; This part is adapted from TYPE109 by David Rand
  1012. ;
  1013. GETSQB:    LDA    RPTCNT        ; Get repeat flag
  1014.     ORA    A        ; Any chars to repeat ?
  1015.     JNZ    GETSQ1        ; Yes - get and count
  1016.     CALL    NXTCH        ; Get a character
  1017.     RC            ; Eof
  1018.     CPI    90H        ; Repeat byte flag
  1019.     JNZ    GETSQ3        ; No -
  1020.     CALL    NXTCH        ; Yes - get another character
  1021.     RC            ; EOF
  1022.     ORA    A        ; If null
  1023.     JNZ    GETSQ2
  1024.     MVI    A,90H        ; Dle is encoded as dle,0
  1025.     RET            ; Return with it, carry clear
  1026. ;...
  1027. ;
  1028. GETSQ2:    DCR    A        ; Bump counter twice
  1029.     JZ    GETSQB        ; 1 repeat is a null event
  1030.  
  1031. GETSQ1:    DCR    A
  1032.     STA    RPTCNT        ; Set repeat count
  1033.     LDA    RPTCHR        ; Return repeat character
  1034.  
  1035. GETSQ3:    STA    RPTCHR        ; Set repeat char
  1036.     ORA    A        ; Clear any carry, not EOF
  1037.     RET
  1038. ;.....
  1039. ;
  1040. ; Next decoded byte from file, ignoring repeat characters
  1041. ;
  1042. NXTCH:    LXI    D,0        ; Pointer @ star of text
  1043.     LDA    CHAR
  1044.     MOV    C,A
  1045.  
  1046. NXTCH1:    LDA    NUMFLT
  1047.     ORA    A
  1048.     JNZ    NXTCH2
  1049.     PUSH    D        ; Save 'DE'
  1050.     CALL    LBRGET        ; Get a byte from the input file
  1051.     JNZ    PREEOF        ; Not expecting an eof here
  1052.     POP    D        ; Restore 'DE'
  1053.     MOV    C,A
  1054.     MVI    A,8        ; 'A' is counter
  1055.  
  1056. NXTCH2:    DCR    A        ; Bump count
  1057.     STA    NUMFLT        ; Save it
  1058.     MOV    A,C        ; Get character
  1059.     RRC            ; Shift right
  1060.     MOV    C,A        ; Save character
  1061.     PUSH    PSW        ; Save character
  1062.     LXI    H,XLATBL    ; Index ram area
  1063.     DAD    D        ; HL=HL+(4*DE)
  1064.     DAD    D
  1065.     DAD    D
  1066.     DAD    D
  1067.     POP    PSW        ; Restore char
  1068.     JNC    NXTCH3        ; If no carry
  1069.     INX    H
  1070.     INX    H
  1071.  
  1072. NXTCH3:    MOV    E,M
  1073.     INX    H
  1074.     MOV    D,M
  1075.     MOV    A,D
  1076.     ANI    80H
  1077.     JZ    NXTCH1
  1078.     MOV    A,C
  1079.     STA    CHAR
  1080.     MOV    A,D
  1081.     CPI    0FEH        ; Special end of file ?
  1082.     MVI    A,1AH        ; Yes - return with EOF character
  1083.     STC
  1084.     RZ            ; And carry for EOF
  1085.  
  1086.     MOV    A,E
  1087.     CMC
  1088.     CMA
  1089.     RET            ; With carry clear, not EOF
  1090. ;.....
  1091. ;
  1092. ; Set up the translation table for the squeezed file
  1093. ;
  1094. SQSETU:    CALL    GET2HL        ; Get 2 bytes from input file into HL
  1095.     LXI    D,XLATBL    ; Index ram area
  1096.  
  1097. SQSET1:    MOV    A,H        ; Get MSB
  1098.     ORA    L        ; Test LSB
  1099.     RZ
  1100.     PUSH    H        ; Save table size counter
  1101.     PUSH    D        ; Save ram area index
  1102.     CALL    GET2HL        ; Get 2 bytes from input file into HL
  1103.     POP    D        ; Restore ram area index
  1104.     XCHG            ; Into 'HL'
  1105.     MOV    M,E        ; Save the LSB byte
  1106.     INX    H
  1107.     MOV    M,D        ; And MSB byte
  1108.     INX    H
  1109.     PUSH    H        ; Bump & save pointer
  1110.     CALL    GET2HL        ; Get 2 bytes from input file into HL
  1111.     XCHG            ; Into DE
  1112.     POP    H        ; Restore pointer
  1113.     MOV    M,E        ; Save the LSB byte
  1114.     INX    H
  1115.     MOV    M,D        ; And the MSB byte
  1116.     INX    H        ; Bump pointer
  1117.     XCHG            ; Restore pointer to 'DE'
  1118.     POP    H        ; Restore table size counter
  1119.     DCX    H        ; Decrement it the byte count
  1120.     JMP    SQSET1        ; And loop for more
  1121. ;.....
  1122. ;
  1123. ; Add a library member to the name queue buffer - only if a match to
  1124. ; MEMNAM
  1125. ;
  1126. ADDMEM:    MOV    A,M        ; Get first byte of member entry
  1127.     ORA    A
  1128.     RNZ            ; Non zero - must be deleted or null entry
  1129. ;
  1130.     INX    H        ; Go to the second byte
  1131.     PUSH    H        ; Save source address for coming 'LDIR'
  1132.     PUSH    H        ; Save it again
  1133.     MVI    B,11        ; 11 byte filename
  1134.  
  1135. ADDME0:    MOV    A,M        ; Get byte
  1136.     CPI    ' '
  1137.     JNZ    ADDME1        ; Not space - continue
  1138.     INX    H        ; Next char
  1139.     DCR    B
  1140.     JNZ    ADDME0        ; Continue searching for spaces
  1141.     POP    H        ; Must be the directory
  1142.     JMP    ADDME4        ; So abort this one
  1143. ;...
  1144. ;
  1145. ADDME1:    POP    H
  1146.     LXI    D,MEMNAM    ; Index member FCB name
  1147.     MVI    B,11        ; 11 byte compare
  1148.  
  1149. ADDME2:    LDAX    D        ; Get byte from member name FCB
  1150.     CPI    '?'        ; '?' matches all entries
  1151.     JZ    ADDME3        ; Match
  1152.     CMP    M        ; Same as member entry?
  1153.     JNZ    ADDME4        ; No - abort this process
  1154.  
  1155. ADDME3:    INX    H
  1156.     INX    D
  1157.     DCR    B
  1158.     JNZ    ADDME2        ; Compare all 11 bytes
  1159.     LHLD    NAMPTR        ; Get destination address
  1160.     XCHG
  1161.     POP    H        ; Get source address back again
  1162.     MVI    B,15
  1163.     CALL    MOVE        ; Move 15 byte block into memory
  1164.     XCHG
  1165.     SHLD    NAMPTR        ; Save name pointer
  1166.     LHLD    MEMCNT        ; Get member number count
  1167.     INX    H        ; Bump it up one
  1168.     SHLD    MEMCNT        ; Set next member memory address
  1169.     RET
  1170.  
  1171. ADDME4:    POP    H        ; Balance stack
  1172.     RET
  1173. ;.....
  1174. ;
  1175. ; Get the next member name from the memory name queue buffer, return
  1176. ; carry set if no more members left
  1177. ;
  1178. GETMEM:    LHLD    MEMCNT        ; Get member count
  1179.     MOV    A,L
  1180.     ORA    H
  1181.     STC
  1182.     RZ            ; Zero count - set error condition
  1183.     DCX    H        ; Bump count down
  1184.     SHLD    MEMCNT        ; And reset member count
  1185.     LHLD    NAMPT1        ; Get source address for move
  1186.     LXI    D,MEMFCB    ; Get destination for move
  1187.     MVI    B,15        ; 11 byte filename + 4 byte file info
  1188.     CALL    MOVE        ; The block
  1189.     SHLD    NAMPT1        ; Reset the next source address
  1190.     ORA    A        ; Clear any cy
  1191.     RET
  1192. ;.....
  1193. ;
  1194. ; Double CRLF to console
  1195. ;
  1196. CRLFLF:    CALL    CRLF
  1197. ;
  1198. ; CR and LF to console
  1199. ; Uses A
  1200. ;
  1201. CRLF:    MVI    A,CR
  1202.     CALL    CTYPE
  1203.     MVI    A,LF
  1204.  
  1205. ; Character to console, preserve all registers
  1206. ;
  1207. CTYPE:    PUSH    PSW
  1208.     PUSH    D
  1209.     MOV    E,A
  1210.     CPI    LF
  1211.     JNZ    CTYPE1
  1212.     LDA    LINCN1
  1213.     INR    A
  1214.     STA    LINCN1
  1215.  
  1216. CTYPE1:    MVI    A,CIO        ; Direct console output
  1217.     CALL    SYS
  1218.     POP    D
  1219.     POP    PSW
  1220.     RET
  1221. ;.....
  1222. ;
  1223. ; CRLF, then fall through to TSTR
  1224. ;
  1225. TSTRC:    CALL    CRLF
  1226. ;
  1227. ; Output string (DE)^
  1228. ; Uses A,F
  1229. ;
  1230. TSTR:    PUSH    D
  1231.  
  1232. TSTR1:    LDAX    D
  1233.     ORA    A
  1234.     JZ    TSTRX
  1235.     CALL    CTYPE
  1236.     INX    D
  1237.     JMP    TSTR1
  1238. ;
  1239. TSTRX:    POP    D
  1240.     RET
  1241. ;.....
  1242. ;
  1243. ; Open LBRFCB file
  1244. ; Uses A,F,D
  1245. ; CP/M 3 apparently does not allow ambiguous file opens, so we
  1246. ; screen them out for the benefit of Z3PLUS users
  1247.  
  1248. FOPNLB:    MVI    A,GETVER
  1249.     CALL    SYS
  1250.     CPI    30H
  1251.     LXI    D,LBRFCB    ; Point LBR's FCB
  1252.     JC    FOPEN        ; If not CPM 3, ambiguous is OK
  1253.     PUSH    D        ; Save it on the stack
  1254.     PUSH    B        ; Save incoming BC
  1255.     MVI    B,11        ; Counter in B
  1256. AFNLP:    INX    D        ; Advance to to char.
  1257.     LDAX    D        ; Get it
  1258.     SBI    '?'        ; A = 0 if ambiguous char.found
  1259.     CMA            ; Now A = FFH if ambiguous
  1260.     JZ    AFNFND        ; Break loop if ambiguous
  1261.     DCR    B        ; Otherwise decrement counter
  1262.     JNZ    AFNLP        ; & loop around
  1263.     DCR    B        ; Cheap NZ flag indication
  1264. AFNFND:    POP    B        ; Restore registers
  1265.     POP    D
  1266.     RZ            ; Return with A = FFH if amb.
  1267. ;
  1268. ; Open file (DE)^, return BDOS response in (A)
  1269. ; Uses A,F
  1270. ;
  1271. FOPEN:    MVI    A,OPEN
  1272. ;
  1273. ; Execute BDOS function (A), preserve registers
  1274. ;
  1275. SYS:    PUSH    H
  1276.     PUSH    D
  1277.     PUSH    B
  1278.     MOV    C,A
  1279.     CALL    BDOS
  1280.     POP    B
  1281.     POP    D
  1282.     POP    H
  1283.     RET
  1284. ;.....
  1285. ;
  1286. ; Move (B) bytes from (HL)^ to (DE)^
  1287. ; Uses A,F,B,D,E,H,L
  1288. ;
  1289. MOVE:    MOV    A,M
  1290.     STAX    D
  1291.     INX    H
  1292.     INX    D
  1293.     DCR    B
  1294.     JNZ    MOVE
  1295.     RET
  1296. ;.....
  1297. ;
  1298. ; Print the actual name of this program if we can determine it,
  1299. ; otherwise print "ZLT", with leading and trailing spaces.
  1300. ; Uses all registers.
  1301. ;
  1302. COMNAM:    MVI    A,' '        ; Print a space
  1303.     CALL    CTYPE
  1304.     CALL    GETEFCB        ; Get ZCPR3's External FCB in HL
  1305.     LXI    D,ZLTNAM    ; Point at "'ZLT ',0"
  1306.     JZ    TSTR        ; Print it if no EFCB
  1307.     MVI    B,8        ; Otherwise load down-counter
  1308. COMNLP:    INX    H        ; Bump pointer to character
  1309.     MOV    A,M        ; Character into A
  1310.     ANI    7FH        ; Strip to ASCII
  1311.     CPI    ' '        ; Is it a space?
  1312.     JZ    CTYPE        ; Just type that and return
  1313.     CALL    CTYPE        ; Otherwise type the non-space
  1314.     DCR    B        ; Decrement the down-counter
  1315.     JNZ    COMNLP        ; and loop if not done
  1316.     MVI    A,' '        ; This does the trailing space
  1317.     JMP    CTYPE        ; for 8-character names only
  1318. ;.....
  1319. ;
  1320. NFOUND:    DB    'Member '
  1321. ;
  1322. NOFMSG:    DB    'Not found',CR,LF,0
  1323.  
  1324. SIGNON:    DB    CR,LF,'ZLT Version ',VER/10+'0','.',VER MOD 10+'0',SubVers
  1325.      IF    ACREDIT
  1326.     DB    ' by C.B.Falconer & B.Morgen'
  1327.      ENDIF            ; ACREDIT
  1328.     DB    CR,LF
  1329.  
  1330. SIGN1:    DB    '^S pauses, ^C aborts, ^X goes to next'
  1331.     DB    ' file, ^Z enables/disables paging, '
  1332.     DB    CR,LF
  1333.     DB    ' Space goes to next line, 0-9 sets inter-character'
  1334.     DB    ' delay, others page',0
  1335.  
  1336. USAGE:    DB    CR,LF,'Types normal/crunched/crlzh/squeezed '
  1337.     DB    'files and LBR members.',CR,LF
  1338.     DB    'Wildcard (*,?) filespecs permitted.',CR,LF,LF
  1339.     DB    'Syntax:',CR,LF,0
  1340.  
  1341.      IF    DUSPEC
  1342. DUMSG:    DB    '[du: or dir:]',0
  1343.      ENDIF            ; DUSPEC
  1344.  
  1345. USAGE1:    DB    'afn.typ [/n]',CR,LF,0
  1346. USAGE2:    DB    'lbrname afn.typ [/n]',CR,LF
  1347.     DB    '"n" = delay between characters',CR,LF,LF
  1348.     db    'This is a special version for screen displays.',CR,LF,0
  1349.  
  1350. EOFMSG:    DB    BELL,'Early EOF,'    ; Fall through to next msg
  1351. ABRMSG:    DB    CR,LF,'<<Aborted!>>',0
  1352. CLEAN:    DB    CR,'       ',CR,0 ; Erase the "more"
  1353. CORRPT:    DB    'LBR file corrupt',0
  1354. MORE:    DB    CR,'[more] ',0
  1355. NOTZ3:    DB    BELL,'ZCPR3 (or equiv.) required',0
  1356. ZLTNAM:    DB    'ZLT ',0
  1357.  
  1358.      IF    LIMITT
  1359. CANT:    DB    BELL,CR,LF,'Can''t type a "',0
  1360. CANT2:    DB    '" file',CR,LF,0
  1361.      ENDIF            ; LIMITT
  1362.  
  1363. BADFILE:DB    BELL,CR,LF,'Corrupt or unknown format file',0
  1364.  
  1365.      IF    LIMITL
  1366. EXCESS:
  1367.     DB    BELL,'Too long, download file',CR,LF,0
  1368.      ENDIF            ; LIMITL
  1369.  
  1370. ;-----------------------------------------------------------------------
  1371.     DSEG
  1372. ;
  1373. ; Temporary storage area
  1374. ;
  1375. BUFPTR:    DS    2
  1376. CHRCNT:    DS    1
  1377.     DS    1
  1378. LINCN1:    DS    1        ; Lines printed since [more]
  1379. PAGLNS:    DS    1        ; Ln/page before pause, 0 causes setup
  1380. PAGSIZ:    DS    1        ; Lines per page, 0 = no pauses
  1381. CDELAY:    DS    1
  1382.  
  1383. NAMPT1:    DS    2        ; NAMBUF, init. to ENDU
  1384. NAMPTR:    DS    2        ; NAMBUF, init. to ENDU
  1385. RCNT:    DS    2        ; Maximum. record count for type, init. 65535
  1386. LBRFLG:    DS    1
  1387. WCOUNT:    DS    2
  1388. WBUFF:    DS    2
  1389. MEMCNT:    DS    2
  1390. LBRFCB:    DS    9
  1391. LBRTYP:    DS    3
  1392. LBREXT:    DS    20        ; Lbrfcb+12; file extent
  1393. LBRSNO:    DS    1        ; Lbrfcb+32; sector #
  1394. LBRRNO:    DS    3        ; Lbrfcb+33; random rcd no.
  1395. MEMFCB:    DS    16
  1396. MEMNAM:    DS    16
  1397. OUTFCB:    DS    13
  1398. ;
  1399. ; Mark start of zeroed area, per component loop
  1400. ;
  1401. ZEROS:
  1402. NUMFLT:    DS    1
  1403. CHAR:    DS    1
  1404. RPTCHR:    DS    1        ; Char to repeat
  1405. RPTCNT:    DS    1        ; Count of repeat characters
  1406. LINCNT:    DS    1        ; Number of lines printed total
  1407. COLUMN:    DS    1        ; Crt column position
  1408. ZERLEN:    DS    1
  1409.  
  1410. LASTZ:    DS    64        ; Mark end of zeroed area, stack space
  1411.  
  1412. STACK:    DS    2        ; Store entry stack pointer
  1413. LBRBUF:    DS    128        ; Member read buffer
  1414. XLATBL:    DS    258*4
  1415.  
  1416.     EXTRN ENDU
  1417.  
  1418.     END
  1419.