home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / dirutl / sd137.lbr / SD137.AZM / SD137.ASM
Assembly Source File  |  1989-02-04  |  120KB  |  5,471 lines

  1. ;              SUPER DIRECTORY PROGRAM
  2. ;                  SD137
  3. ;                 5 FEB 89
  4. ;
  5. ;    Read SD.INF for detailed instructions on configuring SD for your
  6. ;    system.  For information regarding this utility's modification
  7. ;    history, read SD.HIS.
  8. ;
  9. ;        This program is being distributed ready
  10. ;        to use on a CP/M v2.2 computer with two
  11. ;        disk drives , no Z80DOS, and no ZCPR in use.
  12. ;
  13. ;        (Options often changed for RCPM use are
  14. ;        marked with an asterisk.)  The typical
  15. ;        RCPM Sysop might change only these:
  16. ;
  17. ;            a)    3 options starting at MAXDRV
  18. ;            b)    how many drives at LODRV and
  19. ;            c)    6 options starting at USEF
  20. ;            d)    USELCW needs wheel to prevent
  21. ;               showing archive bits
  22. ;
  23. ;
  24. ;         NOTE:  This version can be assembled with
  25. ;            ASM, LASM, M80, MAC or SLRMAC.
  26. ;
  27. ; SD displays the directory of a CP/M disk, sorted alphabetically, with
  28. ; the file size in k, rounded to the nearest CP/M block size.  It also
  29. ; displays library and archive files with the file size in k, if the $L
  30. ; option is selected.
  31. ;
  32. ; Current versions of SD automatically adjust for any block size and di-
  33. ; rectory length under CP/M 2.2,  3.0 or MP/M.    They can also handle any
  34. ; number of disk drives or skip those not available.  Current features:
  35. ;
  36. ;     1) Automatic pauses when the screen fills up except when the
  37. ;        F, N, or P options are specified
  38. ;     2) Searching individual or multiple drives and/or user areas
  39. ;     3) Unconditional or optional disk system reset before execution
  40. ;        begins
  41. ;     4) Directing output to a disk file called DISK.DIR and append-
  42. ;        ing to that file on subsequent runs
  43. ;     5) Summary line output giving drive and user information, num-
  44. ;        ber of files matched, how much space they consume and free
  45. ;        space remaining on the disk
  46. ;     6) Displaying or suppressing "system" files
  47. ;     7) Accepting ambiguous filenames with or without a drive name
  48. ;     8) Printer output (automatically suppresses the [more] pauses)
  49. ;     9) Optional help menu with '?'
  50. ;    10) Displaying number of records used by files
  51. ;    11) Alphabetization of files sorted by type (extent)
  52. ;    12) Selecting alternate list format - vertical if horizontal
  53. ;        is default, and vice versa.
  54. ;    13) Shows contents of .ARC, .ARK or .LBR files with $L option
  55. ;    14) Summary line output optionally contains name of ZCPR3 named
  56. ;        directory, if selected
  57. ;    15) ZCPR3 named directory may be used in command line instead
  58. ;        of DU: if selected
  59. ;    16) ZCPR3 Public user areas may be displayed with or without
  60. ;        WHEEL byte
  61. ;    17) ZCPR3+ ENViorment support of wheel, maxdrv, maxusr location, and
  62. ;        TCAP for REVID,ULINE string
  63. ;    18) If are using ZCPR34+, then have the capability of
  64. ;        having the program build the LODRV-HIDRV table if DRVVEC
  65. ;        equate is YES
  66. ;    19) Normal multi-page vertical sort or single page vertical sort
  67. ;    20) Choose files based upon attributes 1-4
  68. ;    21) Summary totals now supplied if /A,/D,/H (or combo).
  69. ;    22) Z80DOS time stamping and SETD22 type stamping of .LBR's
  70. ;        supported via Z80DOS equate.
  71. ;    23) With Z80DOS, many features of date specification for file
  72. ;        selection available 
  73. ;-----------------------------------------------------------------------
  74. ;
  75. ;    ASEG            ; Needed for M80 and RMAC, ignore error
  76. ;
  77.     ORG    0100H
  78. ;
  79.     JMP    START
  80. ;
  81. NO    EQU    0
  82. YES    EQU    NOT NO        ; (Some assemblers don't like 0FFh)
  83. ;
  84. ; Define version number
  85. ;
  86. MAIN    EQU    1        ; Main block number
  87. VER    EQU    37        ; Current version
  88. MONTH    EQU    2        ; Month
  89. DAY    EQU    5        ; Day
  90. YEAR    EQU    89        ; Year
  91. ;
  92. ;-----------------------------------------------------------------------
  93. ;                 options
  94. ;
  95. MAXDRV    EQU    NO        ; *Yes if MAXD byte is supported
  96. MAXUR    EQU    NO        ; *Yes if MAXU byte is supported
  97. WHEEL    EQU    NO        ; *Yes if using ZCPR wheel byte
  98.  
  99. ; If using equate ZCPR3P set to YES, then the following 3 will be
  100. ; taken from the ENV descriptor automaticaly if the corresponding
  101. ; MAXDRV, MAXUR, or WHEEL equate is set YES
  102.  
  103. MXDRV    EQU    3DH        ; *Set to max drive address if MAXDRV=Yes
  104. MXUSR    EQU    3FH        ; *Set to max user  address if MAXUR=Yes
  105. WHLOC    EQU    3EH        ; *Set to wheel location if WHEEL=Yes
  106.  
  107. MXZUSR    EQU    15        ; Maximum user # allowed with WHEEL set
  108.                 ; NOTE: OVERRIDES even MXUSR as specified
  109.                 ; in ENV if ZCPR3P and MAXUR is YES
  110.  
  111. PRBRDR    EQU    NO        ; Yes = print quasi-borders for libraries
  112. WMBOOT    EQU    NO        ; If warmboot is needed on exit
  113. VLIST    EQU    YES        ; Yes for vertical alphabetization
  114. VSPAGE    EQU    YES        ; If Vertical sort is to be by page
  115.  
  116. DRVVEC    EQU    NO        ; Set to YES if want support of Z34
  117.                 ; drive vector, NOTE: MUST HAVE
  118.                 ; ZCPR3P SET YES
  119.  
  120.     DB    'Z3ENV'        ; For ZCPR3 Environment ID
  121.     DB    1        ; Class 1, External
  122. Z3ENV:    DW    0        ; Environment Address.    If using ZCPR33
  123.                 ; This can be left as is.
  124. ;-------------------------------
  125. ;
  126. ; Drive/User area lookup table:
  127. ; ----------------------------
  128. ; Change the following table as appropriate for your version of CP/M.
  129. ; You can limit the maximum user area without wheel byte independently
  130. ; for any drive available.  Use 0FFh for drives that are not available.
  131. ;
  132. ;        CP/M  v2.2 has 16 user areas, 0-15
  133. ;        CP/M  v3.0 has 32 user areas, 0-31
  134. ;
  135. ; NOTE: Use your editor to move the "HIDRV" line below the correct
  136. ; number of drives for your system.  This not only saves time when the
  137. ; highest drive has been reached, but will display a drive/user error
  138. ; message which otherwise will not be shown.
  139. ;
  140. LODRV    EQU    $        ; Mark beginning of drive/user table
  141.  
  142.     DB    15        ; Maximum user area for drive A
  143.     DB    15        ; "      "    "    "    "     B
  144.  
  145.      IF    NOT DRVVEC
  146.                 ; Use this as end of table if
  147.                 ; are not using Z34+ drive vector
  148. HIDRV    EQU    $        ; Mark end of drive/user table
  149.      ENDIF        ; NOT DRVVEC
  150.  
  151.     DB    0FFH        ; "      "    "    "    "     C
  152.     DB    0FFH        ; "      "    "    "    "     D
  153.     DB    0FFH        ; "      "    "    "    "     E
  154.     DB    0FFH        ; "      "    "    "    "     F
  155.     DB    0FFH        ; "      "    "    "    "     G
  156.     DB    0FFH        ; "      "    "    "    "     H
  157.     DB    0FFH        ; "      "    "    "    "     I
  158.     DB    0FFH        ; "      "    "    "    "     J
  159.     DB    0FFH        ; "      "    "    "    "     K
  160.     DB    0FFH        ; "      "    "    "    "     L
  161.     DB    0FFH        ; "      "    "    "    "     M
  162.     DB    0FFH        ; "      "    "    "    "     N
  163.     DB    0FFH        ; "      "    "    "    "     O
  164.     DB    0FFH        ; "      "    "    "    "     P
  165.      IF    DRVVEC
  166.                 ; Table filled in automatically if
  167.                 ; using Z34+ drive vector
  168. HIDRV    EQU    $        ; Mark end of drive/user table
  169.      ENDIF        ; DRVVEC
  170. ;
  171. ;-------------------------------
  172. ;
  173. ; Command line options:
  174. ; --------------------
  175. ; If any of the following equates are set NO, it prevents their use by
  176. ; any user (including the SYSOP) unless the wheel byte has been set for
  177. ; SYSOP use.  If running an RCPM, you may wish to say NO for those with
  178. ; an asterisk, such as USEF, USERO, USEP and USES to prevent others from
  179. ; using them - the wheel byte makes them available for SYSOP use.
  180. ;
  181. ; NOTE:  For RCPM use, all 5 would normally be set to "NO" to prevent
  182. ; remote use, but would be available to the Sysop with the WHEEL byte.
  183. ;
  184. USEF    EQU    YES        ; *Allow making a local disk copy?
  185. USEO    EQU    YES        ; *Allow showing only $SYS files?
  186. USEP    EQU    YES        ; *Allow making local printer listing?
  187. USER    EQU    YES        ; *Allow disk system reset?
  188. USES    EQU    YES        ; *Allow showing all, and $SYS files?
  189.  
  190. ; Above note goes for the following
  191. USEA    EQU    YES        ; *Allow specifying attributes 1-4?
  192.  
  193. ;
  194. ;-------------------------------
  195. ;
  196. ; Showing tagged attributes
  197. ; -------------------------
  198. ; Displaying files with tagged attributes ($R/O, $SYS, $ARC etc.) in an
  199. ; in an unique manner so they are easy to find, if present.
  200. ;
  201. ;    Example:
  202. ;        FILENAME.SyS    -  $SYS attribute set
  203. ;        FILENAME.doC    -  $SYS and $R/O both set
  204. ;        FILENAME.com    -  $SYS, $R/O and $ARC all set
  205. ;
  206. ; The following equates will permit SD to display the files with tagged
  207. ; attributes in lower case letters (a-z) as in example above.
  208. ;
  209. USELC    EQU    YES        ; Allow lower case letters (a-z)
  210. USELCW    EQU    YES        ; *Allow lower case without wheel byte?
  211. ;
  212. ;
  213. ;-------------------------------
  214. ;
  215. ; Time/date options
  216. ; -----------------
  217. ; The following equate will get the TIMEON from BYE, if BYE is active.
  218. ; The message "Time on system is xx Minutes" will be displayed.
  219. ;
  220. TIMEON    EQU    NO        ; Yes, gets TIMEON from BYE5
  221. ;
  222. ; The following equate will permit the date to be displayed using the
  223. ; European system DD/MM/YY or the American system MM/DD/YY.  This only
  224. ; shows when using 'V' to display version number.
  225. ;
  226. EDATE    EQU    NO        ; Yes = European, No = American
  227. ;
  228. ;-------------------------------
  229. ;
  230. ; If using Z80DOS and you want date stamping support, set the following
  231. ; to YES.
  232. ;
  233. Z80DOS    EQU    NO
  234. ;
  235. ;-------------------------------
  236. ;
  237. ; If want to be able to specify files to be displayed based upon attribute
  238. ;    1 thru 4 , set the following to yes
  239. ;
  240. FATTRIB    EQU    YES
  241. ;
  242.  
  243. ;-------------------------------
  244. ;
  245. ; Z3CPR options
  246. ; -------------
  247. ;
  248. ZCPR3P    EQU    NO        ; Allow ENV support of MAXDRV,WHEEL,MAXUSR,
  249.                 ; TCAP REVID/ULINE
  250. NDIRS    EQU    NO        ; To display directory names
  251. SHOPUB    EQU    NO        ; To display ZRDOS Public Directories
  252. WHLPUB    EQU    NO        ; To make SHOPUB wheel dependent
  253. ZRDOS    EQU    NO        ; Set to yes if using ZRDOS
  254. Z3DRV    EQU    44        ; Offset from ENV location to find drive max
  255. Z3USR    EQU    45        ; Offset from ENV location to find user max
  256. Z3WHL    EQU    41        ; Offset from ENV location to find wheel address
  257. Z3NDR    EQU    21        ; Offset from ENV location to find NDIR address
  258. ZDRVEC    EQU    34H        ; Offset from ENV location to find DRVVEC
  259. Z3TCAP    EQU    80H        ; Offset from ENV location to find TCAP
  260.  
  261. ;-----------------------------------------------------------------------
  262. ;
  263. ; Reverse video options
  264. ; ---------------------
  265. ; The following equate will permit SD to display the files with tagged
  266. ; attributes in either reverse video or bright/dim modes.  This will al-
  267. ; low any character tagged to be visible, as opposed to the USELD method.
  268. ; Up to 7 bytes for enter and exit video modes are provided.  These can
  269. ; be easily patched with DDT, etc.
  270. ;
  271.      IF    NOT ZCPR3P
  272.                 ; Use this equate to control REVID
  273.                 ; if ARE NOT using ZCPR3+
  274. REVID    EQU    NO        ; Yes = inverse or bright/dim display
  275.      ENDIF
  276.  
  277.      IF    ZCPR3P
  278. REVID    EQU    YES        ; Video codes will be taken from
  279.                 ; ENV TCAP if ZCPR3+
  280.      ENDIF
  281.  
  282. ;------------------------------------------
  283. ;
  284. ; The following equate will allow a SYSOP to control
  285. ; ULINE activation if BYE is active
  286. ; Set to YES if you want BYE running to disable underline
  287. ; Set to NO if you want ULINE to control underline
  288.  
  289. BYEULI    EQU    NO
  290.  
  291. ;
  292. ; The following equate will highlight/underline the summary line
  293. ;
  294.      IF    NOT ZCPR3P
  295.                 ; Use this equate to control REVID
  296.                 ; if ARE NOT using ZCPR3+
  297. ULINE    EQU    NO        ; Yes = highlight/underline summary
  298.      ENDIF    ; NOT ZCPR3P
  299.  
  300.      IF    ZCPR3P
  301. ULINE    EQU    YES        ; ULINE will use SO codes from ENV TCAP
  302.      ENDIF    
  303. ;
  304. ;
  305. ; Reverse video control bytes
  306. ; ---------------------------
  307. ; If byte at RVON is 0, simple lower case will be used to display file
  308. ; attributes.
  309. ;
  310.      IF    REVID OR ZCPR3P
  311.                 ; These will be filled in automatically
  312.                 ; if ZCPR3+
  313.  
  314. RVON:    DB    0,0,0,0,0,0,0    ; Up to 7 characters for ENTER REVERSE
  315.     DB    0        ; String Terminator MUST BE 0
  316. ;
  317. RVOFF:    DB    0,0,0,0,0,0,0    ; Up to 7 characters for EXIT REVERSE
  318.     DB    0        ; String Terminator MUST BE 0
  319.      ENDIF            ; REVID OR ZCPR3P
  320. ;
  321. ; If byte at ULON is 0, no highlighting/underlining will be used in the
  322. ; banner line.
  323. ;
  324.      IF    ULINE OR ZCPR3P
  325.                 ; These will be filled in automatically
  326.                 ; if ZCPR3+
  327. ULON:    DB    0,0,0,0,0,0,0    ; Up to 7 characters for ENTER ULINE
  328.     DB    0        ; String Terminator, MUST BE 0
  329. ;
  330. ULOFF:    DB    0,0,0,0,0,0,0    ; Up to 7 characters for EXIT ULINE
  331.     DB    0        ; String Terminator MUST BE 0
  332.      ENDIF            ; ULINE OR ZCPR3P
  333.  
  334. ;
  335. ;            end of options
  336. ;-----------------------------------------------------------------------
  337. ;
  338. ; Reference items
  339. ; ---------------
  340. RECORD    EQU    36
  341. FRN    EQU    33
  342. FCR    EQU    32
  343. READRN    EQU    33
  344. HDRSIZ    EQU    27
  345. ARCMAR    EQU    26
  346. SBCDE    EQU    52EDH
  347. TMPLT0    EQU    $        ; Start of initialization template
  348.  
  349.      IF    VLIST
  350.     DB    0
  351.      ENDIF            ; VLIST
  352.  
  353.      IF    NOT VLIST
  354.     DB    0FFH
  355.      ENDIF            ; NO VLIST
  356.  
  357.     DB    'A'        ; All-users option flag
  358.     DB    'C'        ; File size in records option
  359.     DB    'D'        ; Multi-disk option flag
  360.  
  361.      IF    USEF
  362.     DB    'F'        ; DISK.DIR file output option
  363.      ENDIF            ; USEF
  364.  
  365.      IF    NOT USEF
  366.     DB    'F'+80H
  367.      ENDIF            ; NOT USEF
  368.  
  369.     DB    'H'        ; Show areas from current to highest
  370.     DB    'L'        ; Display library members flag
  371.     DB    'N'        ; No page-pause option flag
  372.  
  373.      IF    USEO
  374.     DB    'O'        ; To show $SYS files only
  375.      ENDIF            ; USEO
  376.  
  377.      IF    NOT USEO
  378.     DB    'O'+80H
  379.      ENDIF            ; NOT USEO
  380.  
  381.      IF    USEP
  382.     DB    'P'        ; Printer output option
  383.      ENDIF            ; USEP
  384.  
  385.      IF    NOT USEP
  386.     DB    'P'+80H
  387.      ENDIF            ; NOT USEP
  388.  
  389.     DB    'Q'        ; To show only non-$ARC files
  390.  
  391.      IF    USER
  392.     DB    'R'        ; Optional reset of disk system
  393.      ENDIF            ; USER
  394.  
  395.      IF    NOT USER
  396.     DB    'R'+80H
  397.      ENDIF            ; NOT USER
  398.  
  399.      IF    USES
  400.     DB    'S'        ; Include $SYS files
  401.      ENDIF            ; USES
  402.  
  403.      IF    NOT USES
  404.     DB    'S'+80H
  405.      ENDIF            ; NOT USES
  406.  
  407.     DB    'T'        ; Primary sort by file type
  408.     DB    'V'        ; Show SD version
  409.     DB    'X'        ; Alternate alphabetization
  410.  
  411.      IF    Z80DOS
  412.     DB    '='        ; Look for exact match of date given
  413.     DB    '+'        ; Look for files of date GE date given
  414.     DB    '-'        ; Look for files of date LT date given
  415.     DB    '!'        ; Match with creation date
  416.     DB    '%'        ; Match with alteration date
  417.     DB    '@'        ; Match with access date
  418.     DB    'Z'        ; Do not show dates
  419.      ENDIF        ;Z80DOS
  420.  
  421. ;     IF    FATTRIB        ; Allow spec of file attributes 1-4?
  422.      IF    USEA AND FATTRIB
  423.     DB    '1'        ; Only files with attrib 1
  424.      ENDIF        ;USEA
  425.  
  426.      IF    NOT USEA AND FATTRIB
  427.     DB    80H+'1'
  428.      ENDIF        ;NOT USEA
  429.  
  430.      IF    USEA AND FATTRIB
  431.     DB    '2'        ; Only files woth attrib 2
  432.      ENDIF        ;USEA
  433.  
  434.      IF    NOT USEA AND FATTRIB
  435.     DB    80H+'2'
  436.      ENDIF        ;NOT USEA
  437.  
  438.      IF    USEA AND FATTRIB
  439.     DB    '3'        ; Only files with attrib 3
  440.      ENDIF        ;USEA
  441.  
  442.      IF    NOT USEA AND FATTRIB
  443.     DB    80H+'3'
  444.      ENDIF        ;NOT USEA
  445.  
  446.      IF    USEA AND FATTRIB
  447.     DB    '4'        ; Only files with attrib 4
  448.      ENDIF        ;USEA
  449.  
  450.      IF    NOT USEA AND FATTRIB
  451.     DB    80H+'4'
  452.      ENDIF        ;NOT USEA
  453.  
  454. ;     ENDIF        ;FATTRIB
  455. ;
  456. ; End of option lookup table
  457. ;
  458.     DW    OUTBUF        ; Next location in output buffer
  459.     DB    128        ; # of bytes left in output buffer
  460.     DB    0,'DISK    DIR'    ; Output Filename.typ
  461. ;
  462. TMPLT1    EQU    $        ; End of initialization data template
  463.  
  464. VERNAME:DB    13,10,'SD',MAIN+'0'
  465.     DB    VER/10+'0',VER MOD 10+'0',' -- '
  466.  
  467.      IF    NOT EDATE
  468.     DB    MONTH/10+'0',MONTH MOD 10+'0','/'
  469.      ENDIF            ; NOT EDATE
  470.  
  471.     DB    DAY/10+'0',DAY MOD 10+'0','/'
  472.  
  473.      IF    EDATE
  474.     DB    MONTH/10+'0',MONTH MOD 10+'0','/'
  475.      ENDIF            ; EDATE
  476.  
  477.     DB    YEAR/10+'0',YEAR MOD 10+'0'
  478.  
  479.      IF    Z80DOS
  480.     DB    ', Z80DOS'
  481.      ENDIF
  482.  
  483.      IF    ZCPR3P         ;
  484.     DB    ', ZCPR3+/ARC/ARK Version'
  485.      ENDIF            ; ZCPR3 
  486.  
  487.  
  488.     DB    0
  489. ;
  490. ;-----------------------------------------------------------------------
  491. ;             Program starts here
  492. ;-----------------------------------------------------------------------
  493. ;
  494. START:    LXI    H,0
  495.     DAD    SP        ; HL=old stack
  496.     SHLD    STACK        ; Save it
  497.     LXI    SP,STACK    ; Get new stack
  498.  
  499.      IF    ZCPR3P
  500.     LHLD    Z3ENV        ; Get ENV address
  501.     PUSH    H
  502.     LXI    D,Z3DRV        ; Point to max drv byte
  503.     DAD    D
  504.     SHLD    Z3DRVL        ; Save location away, only used if DRVVEC
  505.                 ; equate YES
  506.     POP    H
  507.     PUSH    H
  508.     LXI    D,Z3USR        ; Point to maxuser byte
  509.     DAD    D
  510.     SHLD    Z3USRL        ; Save location away
  511.     POP    H
  512.     PUSH    H
  513.     LXI    D,Z3WHL        ; Point to address pointer of wheel
  514.     DAD    D
  515.     MOV    E,M        ; Get address of wheel byte
  516.     INX    H
  517.     MOV    D,M
  518.     XCHG
  519.     SHLD    Z3WHLL        ; Save it away
  520.     POP    H
  521.     PUSH    H        ; ENV pointer back
  522.     LXI    D,Z3TCAP
  523.     DAD    D        ; point to TCAP
  524.     MOV    A,M
  525.     CPI    ' '+1        ; Any TCAP?
  526.     JC    NOSTND        ; C=NO
  527.     LXI    D,17H        ; And then to CLS string
  528.     DAD    D
  529.     CALL    VIDSKP        ; Move on to SO string
  530.     CALL    VIDSKP
  531.     CALL    VIDSKP
  532.     MOV    A,M
  533.     ORA    A
  534.     JZ    NOSTND        ; Z=no SO string
  535.     LXI    D,RVON        ; Fill in out data base
  536.     LXI    B,ULON
  537. MOVSTO:    MOV    A,M
  538.     ORA    A
  539.     JZ    OSTNDO        ; Z=done
  540.     STAX    B
  541.     STAX    D
  542.     INX    H
  543.     INX    D
  544.     INX    B
  545.     JMP    MOVSTO
  546. OSTNDO:    INX    H        ; Point to SI string
  547.     MOV    A,M
  548.     ORA    A
  549.     JZ    NOSTND        ; Z=none
  550.     LXI    D,RVOFF        ; Fill our data base in
  551.     LXI    B,ULOFF
  552. MOVSTD:    MOV    A,M
  553.     ORA    A
  554.     JZ    NOSTND
  555.     STAX    D
  556.     STAX    B
  557.     INX    H
  558.     INX    D
  559.     INX    B
  560.     JMP    MOVSTD
  561.  
  562. ; FROM VLIB Module Name:  VIDA
  563. ; Author:  Richard Conn
  564. ; VLIB  Version Number:  1.1
  565. ; Module Version Number:  1.1
  566. ;
  567. ;  VIDSKP - Skip over video string pted to by HL; pt to byte after string
  568. ;
  569. vidskp:
  570.     MOV    A,M        ;get next char
  571.     INX    H        ;pt to next
  572.     ORA    A        ;done if zero
  573.     RZ
  574.     CPI    '/'        ;literal value?
  575.     JNZ    VIDSKP        ;continue if not
  576.     INX    H        ;pt to after literal value
  577.     JMP    VIDSKP
  578. NOSTND:
  579.     POP    H
  580.      ENDIF        ; ZCPR3P
  581.  
  582.      IF    DRVVEC AND ZCPR3P
  583.     PUSH    H
  584.     LXI    D,ZDRVEC    ; Add offset to DRVVEC
  585.     DAD    D
  586.     MOV    E,M        ; Get the vector
  587.     INX    H
  588.     MOV    D,M
  589.     LHLD    Z3USRL
  590.     MOV    B,M        ; Get MAXUSER from ENV
  591.  
  592.     LXI    H,LODRV        ; Fill in our drive table
  593.     MVI    C,10H        ; Do 16 drives
  594. STDRVV:
  595.     MOV    A,D        ; Shift the vector right
  596.     ORA    A
  597.     RAR
  598.     MOV    D,A
  599.     MOV    A,E
  600.     RAR
  601.     MOV    E,A
  602.     MVI    M,0FFH        ; Assume no drive
  603.     JNC    NDRVV
  604.     MOV    M,B        ; Drive found, load maxuser allowed
  605. NDRVV:    INX    H
  606.     DCR    C
  607.     JNZ    STDRVV
  608.     POP    H
  609.      ENDIF        ;DRVVEC AND ZCPR3P
  610.  
  611.      IF    NDIRS
  612.     LHLD    Z3ENV        ; Get Environment Address
  613.     LXI    D,Z3NDR        ; Point to named directory space
  614.     DAD    D
  615.     MOV    E,M
  616.     INX    H
  617.     MOV    D,M        ; DE Now contains NDR Address
  618.     INX    H
  619.     MOV    A,M
  620.     ADI    1
  621.     STA    NUMDIR        ; Maximum number of entries plus 1
  622.     XCHG
  623.     SHLD    NAMADR        ; Keep Address for later
  624.      ENDIF            ; NDIRS
  625. ;
  626. ; Clear Public User Areas so they can be displayed
  627. ;
  628.      IF    SHOPUB
  629.     LHLD    0109H        ; Get Environment Address
  630.     MVI    D,0
  631.     MVI    E,07EH
  632.     DAD    D        ; HL Points to Public Drive Byte
  633.     MOV    A,M        ; Get public DRV byte
  634.     STA    PUBDRV
  635.     INX    H
  636.     MOV    A,M        ; Get public USR byte
  637.     STA    PUBUSR
  638.      ENDIF            ; SHOPUB
  639.  
  640. ;     IF    WHLPUB
  641.  
  642.      IF    ZCPR3P AND WHLPUB
  643.     PUSH    H
  644.     LHLD    Z3WHLL        ; Point to ENV
  645.     MOV    A,M        ; Get wheel
  646.     POP    H
  647.      ENDIF        ;ZCPR3P
  648.  
  649.      IF    NOT ZCPR3P AND WHLPUB
  650.     LDA    WHLOC        ; Load wheel byte
  651.      ENDIF        ; NOT ZCPR3P
  652.  
  653.      IF    WHLPUB
  654.     ORA    A
  655.     JZ    NOPUB
  656.      ENDIF            ; WHLPUB
  657.  
  658.      IF    SHOPUB
  659.     DCX    H
  660.     MVI    A,0        ; Clear Public Areas temporarily
  661.     MOV    M,A
  662.     INX    H
  663.     MOV    M,A
  664.      ENDIF        ; SHOPUB
  665.  
  666.      IF    WHLPUB AND SHOPUB
  667. NOPUB:    DS    0
  668.      ENDIF            ; WHLPUB
  669. ;
  670. ; (WHLPUB enabled, the R option is redundant)
  671. ;
  672. ;     ENDIF            ; SHOPUB
  673. ;
  674. ; See if help is wanted
  675. ;
  676.     LXI    H,FCB+1        ; Filename
  677.     MOV    A,M        ; 1st Character
  678.  
  679.      IF    NOT ZCPR3P
  680.     CPI    '?'        ; Is it "?"
  681.     JNZ    INIT        ; No, Continue
  682.     INX    H        ; Yes, Next Char
  683.     MOV    A,M        ; 2nd Character
  684.     CPI    ' '        ; Is it " "
  685.     JNZ    INIT        ; If not, did not want help guide
  686.     LDA    FCB+9        ; Check for any extent
  687.     CPI    ' '
  688.     JZ    HELPME        ; If none, wanted help
  689.      ENDIF        ; NOT ZCPR3P
  690.  
  691.      IF    ZCPR3P
  692.     CPI    '?'        ; Is it "?"
  693.     JNZ    CHKSLH        ; No, Continue
  694.     INX    H        ; Yes, Next Char
  695.     MOV    A,M        ; 2nd Character
  696.     CPI    ' '        ; Is it " "
  697.     JNZ    INIT        ; If not, did not want help guide
  698.     LDA    FCB+9        ; Check for any extent
  699.     CPI    ' '
  700.     JZ    HELPME        ; If none, wanted help
  701.     JMP    INIT
  702. CHKSLH: CPI    '/'        ; Is it a slash?
  703.     JNZ    INIT
  704.     INX    H
  705.     MOV    A,M        ; two slashes gets help
  706.     CPI    '/'
  707.     JZ    HELPME
  708.      ENDIF        ; ZCPR3P
  709.  
  710. ;
  711. ; Zero out the entire initialization data area
  712. ;
  713. INIT:    LXI    H,DATA0        ; Point to start of initialized data area
  714.     PUSH    H        ; Save for non-zero filling later
  715.     MVI    C,DATA1-DATA0    ; Data area length
  716.     XRA    A        ; Clear the "A" register
  717.  
  718. ZFILL:    MOV    M,A        ; Null the address
  719.     INX    H        ; Pointer+1
  720.     DCR    C        ; One less to go
  721.     JNZ    ZFILL
  722.  
  723.      IF    SHOPUB        ; In order for the Public Directories
  724.     MVI    A,0FFH        ; To be displayed, Option 'R' must be
  725.     STA    ROPFLG        ; Forced true.
  726.      ENDIF            ; SHOPUB
  727. ;
  728. ; Now copy non-zero initialization data from the template area
  729. ;
  730.     POP    H        ; Load A(DATA0)
  731.     LXI    D,TMPLT0    ; Load A(TMPLT0)
  732.     MVI    C,TMPLT1-TMPLT0    ; Template area length
  733.  
  734. NZFILL:    LDAX    D        ; Load template byte
  735.     MOV    M,A        ; Move to data area
  736.     INX    D        ; Next location to store data
  737.     INX    H        ; Next location to get data
  738.     DCR    C        ; One less to go
  739.     JNZ    NZFILL
  740.  
  741.     LXI    H,0        ; Clear HL
  742.  
  743.      IF    ZRDOS
  744.     MVI    C,ZRDVER    ; Get ZRDOS version
  745.     CALL    BDOS
  746.     MOV    A,L        ; ZRDOS Version #
  747.     STA    ZRDFLG        ; Save it
  748.      ENDIF            ; ZRDOS
  749.  
  750.     MVI    C,CPMVER    ; Get CP/M  version
  751.     CALL    BDOS
  752.     MOV    A,L        ; CP/M Version number
  753.     STA    VERFLG        ; Save it
  754.     STA    SOHFLG        ; Prevents initial unwanted CRLF
  755.     CPI    20H        ; Set carry if CP/M 1.4
  756.     PUSH    PSW        ; Save for BYE test
  757.     MVI    E,0FFH        ; Load current user number if CP/M 2
  758.     MVI    C,STUSER    ; Fall through with A=0 if not
  759.     CNC    CPM        ; Only if CP/M 2.0 or ZRDOS
  760.     STA    OLDUSR        ; Initial user number
  761.     STA    NEWUSR        ; New user = Initial user
  762.     STA    BASUSR        ; Directories
  763.     POP    PSW        ; Recover Version Flag
  764.     MVI    E,241        ; Special BYE5xx Call
  765.     MVI    C,STUSER    ; Returns 77 if BYE5xx active
  766.     CNC    CPM        ; BYE5nn not on CP/M 1.4 system
  767.     SUI    77        ; Return code expected
  768.     STA    BYEACT        ; BYEACT = 0, BYE5nn active
  769.  
  770.      IF    TIMEON
  771.     CALL    TIME
  772.      ENDIF            ; TIMEON
  773.  
  774.      IF    ZCPR3P
  775.     LDA    FCB+13        ; Point to command line buffer (CLB)
  776.     STA    NEWUSR
  777.      ENDIF            ; ZCPR3P
  778.  
  779.      IF    NOT ZCPR3P
  780.     LXI    H,TBUF+1    ; Point to command line buffer (CLB)
  781.     MOV    A,M        ; CLB Character
  782.     CPI    '['        ; CP/M 3.0 style delimiter
  783.     JZ    CLOK        ; (may follow command in CP/M 3.0)
  784.     INX    H        ; CLB pointer +1
  785.     ORA    A        ; Terminator?
  786.     JNZ    CLOK        ; No, continue
  787.     MOV    M,A        ; Yes, set 2nd terminator
  788.  
  789. CLOK:    LXI    D,FCB        ; A(file control block)
  790.     CALL    FNAME        ; Process filename.typ
  791.     MOV    A,B        ; Disk specification
  792.     CPI    0FFH        ; Current?
  793.     JZ    CLUS        ; Yes
  794.     STAX    D        ; No, set disk specification
  795.  
  796. CLUS:    MOV    A,C        ; User specification
  797.     CPI    0FFH        ; Current?
  798.     JZ    CLNON        ; Yes
  799.     STA    NEWUSR        ; No, set user specification
  800.     STA    BASUSR
  801.      ENDIF            ; NOT ZCPR3P
  802.  
  803. CLNON:    MVI    C,CURDSK
  804.     CALL    CPM        ; Load current disk number
  805.     STA    OLDDSK        ; Save for reset if needed
  806.     INR    A        ; Adjust
  807.     STA    OUTFCB        ; Save directory file drive
  808.     LXI    H,FCB        ; A(file control block)
  809.     MOV    A,M        ; Load directory search drive
  810.     ORA    A        ; Any specified?
  811.     JNZ    START1        ; Yes, skip next routine
  812.     LDA    OLDDSK        ; Otherwise, get default disk
  813.     INR    A        ; Adjust
  814.     JMP    START2
  815.  
  816. START1:    PUSH    PSW        ; Save status
  817.     MVI    A,1
  818.     STA    DRVFLG        ; Set DRVFLG = 1
  819.     POP    PSW        ; Load status
  820.  
  821. START2:    MOV    M,A        ; Absolute drive code in directory FCB
  822. ;
  823. ; If at least one option is allowed,  scan command line for the option
  824. ; field delimiter. The option field delimiter is considered valid only
  825. ; if it is preceded by at least 1 space  (otherwise may be part of the
  826. ; directory filename).     Any unrecognized options/illegal user numbers
  827. ; will be flagged.(We scan the command line buffer rather than the 2nd
  828. ; default FCB because all 8 options + 2 digit user number will not fit
  829. ; in the 2nd FCB name field).
  830. ;
  831.     LXI    H,TBUF        ; CLB pointer
  832.     MOV    B,M        ; CLB length
  833. ;
  834. ; Search for valid command line delimiter, if not found, assume no
  835. ; options.  Show help menu if single "?" entered.
  836. ;
  837. SCNDOL:    INX    H        ; CLB PTR+1
  838.     DCR    B        ; CLB LEN-1
  839.     JM    DOPTN        ; Exit if command line buffer empty
  840.     MOV    A,M        ; CLB Character
  841.     CPI    '['        ; CPM+ style delimiter?
  842.     JZ    OPTDLM        ; Yes
  843.     CPI    '$'        ; CPM2 style delimiter?
  844.     JZ    SPB4        ; Yes
  845.     CPI    '/'        ; ZCPR style delimiter?
  846.     JNZ    SCNDOL        ; No
  847.  
  848. SPB4:    DCX    H        ; '$' found, space must precede
  849.     MOV    A,M        ; Previous character
  850.     INX    H
  851.     CPI    ' '
  852.     JNZ    SCNDOL        ; No space, ignore '$'
  853. ;
  854. ; Valid delimiter found.  Scan the rest of the buffer for options.
  855. ; Errors past this point cause an abort.
  856. ;
  857. OPTDLM:    XCHG            ; DE = CLB pointer (swap pointers)
  858.  
  859. SCNOPT:    INX    D        ; CLB PRT+1
  860.     DCR    B        ; CLB LEN-1
  861.     JM    DOPTN        ; If option field exhausted, exit
  862.  
  863. SCNAGN:    LDAX    D        ; Load option character
  864.     CPI    ' '        ; Is it " "?
  865.  
  866.      IF    Z80DOS
  867.     JZ    LOKDAT        ; Space, go look for date info
  868.      ENDIF        ;Z80DOS
  869.  
  870.      IF    NOT Z80DOS
  871.     JZ    SCNOPT        ; Yes, Ignore it
  872.      ENDIF        ;NOT Z80DOS
  873.  
  874.     CPI    ']'        ; CPM+ style terminator?
  875.     JZ    SCNOPT        ; Options may follow terminator
  876.     LXI    H,OTBL-1    ; OTBL pointer
  877.     MVI    C,OEND-OTBL+1    ; OTLB length
  878.  
  879. NOMACH:    INX    H        ; OTLB pointer+1
  880.     DCR    C        ; OTLB length-1
  881.     JZ    CLERR        ; Error if option table end
  882.  
  883.      IF    WHEEL        ; ZCMD/ZCPR2/ZCPR3?
  884.     PUSH    PSW        ; Save "A" value
  885.      ENDIF        ; WHEEL
  886.  
  887.      IF    ZCPR3P AND WHEEL
  888.     PUSH    H
  889.     LHLD    Z3WHLL        ; Point to ENV
  890.     MOV    A,M        ; Get wheel
  891.     POP    H
  892.      ENDIF        ;ZCPR3P AND WHEEL
  893.  
  894.      IF    NOT ZCPR3P AND WHEEL
  895.     LDA    WHLOC        ; Load wheel byte
  896.      ENDIF        ; NOT ZCPR3P AND WHEEL
  897.  
  898.      IF    WHEEL
  899.     ORA    A        ; Set Flags
  900.     JZ    NOMAC1        ; Not set, so forget it
  901.     MOV    A,M        ; Load the table option
  902.      ENDIF        ;WHEEL
  903.  
  904.      IF    FATTRIB AND WHEEL
  905.     ANI    7FH
  906.      ENDIF        ;FATTRIB
  907.  
  908.      IF    NOT FATTRIB AND WHEEL
  909.     ANI    5FH        ; Allow the option
  910.      ENDIF        ;NOT FATTRIB
  911.  
  912.      IF    WHEEL
  913.     MOV    M,A        ; Stuff back in table
  914.  
  915. NOMAC1:    POP    PSW        ; Restore "A" value
  916.      ENDIF            ; WHEEL
  917.  
  918.     CMP    M        ; Compare with table entry
  919.     JNZ    NOMACH        ; If no match, check next
  920.     MVI    M,0        ; Else, activate the option
  921.     JMP    SCNOPT        ; Continue scan
  922. ;.....
  923. ;
  924. ; Playback the command line up to the character that stopped the scan
  925. ; and exit
  926. ;
  927. CLERR:    XRA    A        ; Clear "A" register
  928.     INX    D        ; Tag end of CLB
  929.     STAX    D        ; With terminator
  930.     CALL    CRLF        ; New line
  931.     LXI    D,ERRMS2    ; 'Error'
  932.     CALL    PUTS
  933.     LXI    D,ERRTAG    ; '->'
  934.     CALL    PUTS
  935.     LXI    H,TBUF+1    ; Playback CLB to error point
  936.  
  937. CLELP:    MOV    A,M        ; Character
  938.     ORA    A        ; Zero?
  939.     JZ    CLEX        ; Yes, exit
  940.     CALL    PUTCHR        ; No, output to console
  941.     INX    H        ; CLB pointer+1
  942.     JMP    CLELP        ; Continue
  943.  
  944. CLEX:    MVI    A,'?'        ; Tag line with a '?' field
  945.     CALL    PUTCHR
  946.     CALL    CRLF        ; New Line
  947.  
  948.      IF    SHOPUB
  949.     CALL    RSTPUB
  950.      ENDIF            ; SHOPUB
  951.  
  952. ;;;;;    JMP    0000H        ; And reset CCP, all finished
  953.     JMP    EXIT2
  954.  
  955.      IF    Z80DOS
  956. LOKDAT:    INX    D
  957.     LDAX    D        ; Check to see if * was entered meaning
  958.     CPI    '*'        ; use current system time
  959.     JNZ    LOKDAT1        ; NZ=no
  960.     CALL    SYSTIM        ; Get the current system time
  961.     JMP    LOKDAT2        ; And continue
  962. LOKDAT1:
  963.     call    eval10        ; convert month to binary
  964.     ORA    A        ; month can't be 0
  965.     JZ    BADDATE
  966.     CPI    13         ; can't be >12
  967.     JNC    BADDATE
  968.     STA    MONTHS        ; store month
  969.     LDAX    D        ; End of input line?
  970.     ORA    A
  971.     JZ    BADDATE        ; Z=yes, a no-no
  972.     INX    D        ; Skip /
  973.     call    eval10        ; convert
  974.     ORA    A        ; day can't be 0
  975.     JZ    BADDATE
  976.     CPI    32        ; or >31
  977.     JNC    BADDATE
  978.     STA    DAYS1        ; store day
  979.     LDAX    D        ; End of input line?
  980.     ORA    A
  981.     JZ    BADDATE        ; Z=yes, a no-no
  982.     INX    D        ; Skip /
  983.     call    eval10
  984.     STA    YEARS1        ; store year
  985.     PUSH    D
  986.     LXI    H,YEARS1    ; pt at date
  987.     CALL    BIN2JUL        ; get jul date in hl
  988.     POP    D
  989. LOKDAT2:
  990.     CALL    DOPLMI        ; Process any + or - operators
  991.     SHLD    DATCHK
  992.     LDAX    D
  993.     CPI    ' '        ; Next char a space?
  994.     JNZ    DOPTN        ; NZ=no, continue
  995. ;    LHLD    DATCH1
  996. ;    MOV    A,H
  997. ;    ORA    L
  998. ;    JZ    CLERR
  999.     LHLD    DATCHK        ; set last input date=first input date
  1000.     SHLD    DATCH1
  1001.     JMP    LOKDAT        ; And go try to get some more dates
  1002.  
  1003. SYSTIM:
  1004.     PUSH    D        ; Save pointer to input line
  1005.     LXI    D,ASCII        ; Tell Z80DOS to put time here
  1006.     MVI    C,105
  1007.     CALL    5        ; Go get the time
  1008.     LXI    D,ASCII
  1009.     LDAX    D        ; Get LSB of JDAY
  1010.     MOV    L,A
  1011.     INX    D
  1012.     LDAX    D        ; Get MSB of JDAY
  1013.     MOV    H,A
  1014.     POP    D        ; Get input pointer back
  1015.     INX    D        ; Point ot next
  1016. DOPLMI:    LDAX    D
  1017.     CPI    '-'        ; Does operator want a subtraction?
  1018.     JZ    SUBDAT
  1019.     CPI    '+'        ; an add?
  1020.     RNZ            ; NZ=no
  1021.     MVI    A,1
  1022.     STA    DATPLS
  1023.     JMP    OPDAT
  1024. SUBDAT:    XRA    A
  1025.     STA    DATPLS
  1026. OPDAT:    INX    D
  1027.     CALL    EVAL10        ; Yes go get number
  1028.     PUSH    D
  1029.     MOV    E,A
  1030.     XRA    A
  1031.     MOV    D,A
  1032.     LDA    DATPLS        ; Chec if adding
  1033.     ORA    A
  1034.     JNZ    DTIPLS        ; NZ=yes
  1035.     MOV    A,L
  1036.     SBB    E
  1037.     MOV    L,A
  1038.     MOV    A,H
  1039.     SBB    D
  1040.     MOV    H,A
  1041.     POP    D
  1042.     RET
  1043. DTIPLS:
  1044.     DAD    D
  1045.     POP    D
  1046.     RET
  1047.  
  1048.  
  1049. EVAL10:
  1050.     XRA    A
  1051.     MOV    B,A        ; B holds current number input
  1052. EVAL1:    LDAX    D        ; Get input
  1053.     CPI    '/'        ; / is seperator
  1054.     JZ    DEVAL10        ; Z= done
  1055.     CPI    ' '
  1056.     JZ    DEVAL10
  1057.     CPI    '+'
  1058.     JZ    DEVAL10
  1059.     CPI    '-'
  1060.     JZ    DEVAL10
  1061.     ORA    A
  1062.     JZ    DEVAL10        ; Z= at end of line
  1063.     SUI    '0'        ; Verify ascii 0-9
  1064.     JC    BADDATE
  1065.     CPI    10
  1066.     JNC    BADDATE
  1067.     INX    D
  1068.     MOV    C,A        ; Old*10+new
  1069.     MOV    A,B
  1070.     ADD    A
  1071.     ADD    A
  1072.     ADD    B
  1073.     ADD    A
  1074.     ADD    C
  1075.     MOV    B,A        ; B has current
  1076.     JMP    EVAL1
  1077. DEVAL10:
  1078.     MOV    A,B
  1079.     RET
  1080. BADDATE:
  1081.     PUSH    D
  1082.     LXI    D,BDTMES
  1083.     CALL    PUTS
  1084.     POP    D
  1085.     JMP    CLERR
  1086. BDTMES:
  1087.     DB    13,10,13,10
  1088.     DB    ' *** Illegal Date Entered, form MM/DD/YY or MM/D/YY or M/DD/YY'
  1089.     DB    13,10,13,10,0
  1090.  
  1091. ;
  1092. ;    Binary to Julian Date routine.
  1093. ;
  1094. ; >>    hl -> yr,mo,da in bin
  1095. ; <<     hl = Julian date
  1096. ;
  1097. ;    Convert to 8080 code from the original
  1098. ;    BCD2JUL
  1099. ;    by Bridger Mitchel and Howard Goldstein - 4/16/88
  1100. ;
  1101. BIN2JUL:
  1102.     PUSH    PSW
  1103.     PUSH    B
  1104.     PUSH    D
  1105.     MOV    A,M        ; A=yr
  1106.     INX    H
  1107.     MOV    C,M        ;c = mo
  1108.     INX    H
  1109.     PUSH    H        ;save ptr to day
  1110.     PUSH    PSW        ;save year
  1111. ;
  1112. ; set hl= initial julian value of 77/12/31
  1113. ;
  1114.     LXI    H,0
  1115.     SUI    78
  1116.     JZ    B2JUL3
  1117.     JNC    B2JUL0
  1118.     ADI    100        ;<78, assume next century
  1119. B2JUL0:    MOV    B,A        ;b = # yrs > 78
  1120.     MVI    A,1        ;init modulo 4 counter
  1121.     LXI    D,365        ;days/yr
  1122. B2JUL1:    DAD    D        ;calc julian val. of  (yr/01/01 - 1)
  1123.     INR    A
  1124.     ANI    3        ;every 4 yrs,
  1125.     JNZ    B2JUL2
  1126.     INX    H        ;..add 1 for leap year
  1127. B2JUL2:    DCR    B
  1128.     JNZ    B2JUL1
  1129. ;
  1130. ;     hl now = # days in years before current year
  1131. ;
  1132. B2JUL3:    POP    PSW
  1133.     ANI    3        ;if current yr == leap year
  1134.     JNZ    B2JUL5
  1135.     MOV    A,C
  1136.     CPI    3        ;..and mo >= march
  1137.     JC    B2JUL5
  1138.     INX    H        ;..add the extra day (Feb 29)
  1139. ;
  1140. B2JUL5:    MOV    B,C        ; b = month = # months +1 to sum
  1141.     LXI    D,DPERMO    ;point at table
  1142.     JMP    B2JUL7
  1143. ;
  1144. B2JUL6:    CALL    ADDHL        ;add # days in this month
  1145.     INX    D        ;bump tbl ptr
  1146. B2JUL7:    DCR    B
  1147.     JNZ    B2JUL6
  1148. ;
  1149.     POP    D        ;ptr to day
  1150.     CALL    ADDHL
  1151.     POP    D
  1152.     POP    B
  1153.     POP    PSW
  1154.     RET
  1155.  
  1156. ADDHL:    LDAX    D        ;add day of current month
  1157. ;
  1158. ADDA2HL:
  1159.     ADD    L
  1160.     MOV    L,A
  1161.     RNC
  1162.     INR    H
  1163.     RET
  1164.  
  1165. ;
  1166. ; table of days per month (non-leap year)
  1167. ;
  1168.  
  1169. DPERMO:    DB    31        ;jan
  1170.     DB    28        ;feb
  1171.     DB    31        ;mar
  1172.     DB    30        ;apr
  1173.     DB    31        ;may
  1174.     DB    30        ;jun
  1175.     DB    31        ;jul
  1176.     DB    31        ;aug
  1177.     DB    30        ;sep
  1178.     DB    31        ;oct
  1179.     DB    30        ;nov
  1180.     DB    31        ;dec
  1181.  
  1182.      ENDIF        ;Z80DOS
  1183.  
  1184.  
  1185.  
  1186. ;.....
  1187. ;
  1188. ; Options input or not specified, and associated flags set.
  1189. ;
  1190. ; If D-option, swap error vectors, then start at drive A if no
  1191. ; drive specified on command line.
  1192. ;
  1193. DOPTN:
  1194.      IF    Z80DOS
  1195.     LHLD    DATCH1
  1196.     MOV    A,H
  1197.     ORA    L
  1198.     JZ    DOPTN1
  1199.     XCHG
  1200.     LHLD    DATCHK
  1201.     ORA    A
  1202.     DW    SBCDE
  1203.     JZ    CLERR
  1204.     JNC    DOPTN1
  1205.     LHLD    DATCHK
  1206.     SHLD    DATCH1
  1207.     XCHG
  1208.     SHLD    DATCHK
  1209. DOPTN1:
  1210.      ENDIF        ; Z80DOS
  1211.  
  1212.     LDA    DOPFLG        ; If multi-disk flag set,
  1213.     ORA    A        ; Need to set error traps
  1214.     JNZ    AOPTN        ; If not, go check A-option
  1215.     CALL    SWAPEM        ; Swap BDOS error vector tables
  1216.     LDA    DRVFLG        ; Directory drive specified?
  1217.     ORA    A
  1218.     JNZ    AOPTN        ; No, don't reset
  1219.     MVI    A,1        ; Yes, Set FCB to A:
  1220.     STA    FCB
  1221. ;
  1222. ; Start user at 0 if A-option selected without U-option
  1223. ;
  1224. AOPTN:    LDA    AOPFLG        ; Check All-users option
  1225.     ORA    A
  1226.     JNZ    COPTN        ; Jump if not
  1227.     LDA    HOPFLG        ; Asking to show all from current?
  1228.     ORA    A
  1229.     JZ    COPTN        ; If yes, do not reset "A" to zero
  1230.     XRA    A        ; No, Start at user 0
  1231.     STA    NEWUSR
  1232.     STA    BASUSR
  1233. ;
  1234. ; Test if C-option and set indicator character 'r', else 'k'
  1235. ;
  1236. COPTN:    LDA    COPFLG        ; File sizes wanted in records?
  1237.     ORA    A
  1238.     MVI    A,'k'
  1239.     JNZ    COPTN1        ; Jump if not
  1240.     MVI    A,'r'
  1241.  
  1242. COPTN1:    STA    FSIZEC        ; Indicator char after size
  1243. ;
  1244. ; Determine whether horizontal or vertical alphabetization.
  1245. ; If X-option selected, use alternate format.
  1246. ; Set flag and fence character accordingly.
  1247. ;
  1248.     LDA    XOPFLG        ; Check for X option
  1249.     ORA    A
  1250.     LDA    VFLAG        ; Get vertical flag
  1251.     JNZ    XOPTN1        ; Jump if no X option
  1252.     CMA            ; Else swap vertical/horizontal indicator
  1253.     STA    VFLAG        ; And change VFLAG other way
  1254.  
  1255. XOPTN1:    DS    0
  1256. ;
  1257. ; The following optionally resets the disk system.  The reset must
  1258. ; be done OUTSIDE of the multiple drive loop if the $F option is
  1259. ; enabled because CP/M 1.4 will clobber the DMA buffer on reset.
  1260. ;
  1261.     LDA    ROPFLG        ; Reset Disk?
  1262.     ORA    A
  1263.     JNZ    NOOPT
  1264. ;
  1265. ; Disk reset if R option entered on command line
  1266. ;
  1267.     MVI    C,RESET
  1268.     CALL    CPM
  1269. ;
  1270. ; Validate drive code and user area numbers from the drive table
  1271. ;
  1272. NOOPT:    LXI    D,DRUMSG    ; Get drive/user error message
  1273.     PUSH    D
  1274.     LDA    FCB        ; Get directory drive code
  1275.     DCR    A        ; Normalize to range of 0-31
  1276.     CPI    HIDRV-LODRV    ; Compare with max drives on-line
  1277.     JNC    ERXIT        ; Drive error exit if out of range
  1278.  
  1279. ;     IF    MAXDRV        ; Look for MXDRV
  1280.  
  1281.      IF    ZCPR3P AND MAXDRV
  1282.     LHLD    Z3DRVL        ; Point to ENV as loaded
  1283.      ENDIF        ;ZCPR3P AND MAXDRV
  1284.  
  1285.      IF    NOT ZCPR3P AND MAXDRV
  1286.     LXI    H,MXDRV        ; A(MXDRV) to HL
  1287.      ENDIF        ;NOT ZCPR3P AND MAXDRV
  1288.  
  1289.      IF    MAXDRV
  1290.     MOV    L,M        ; (MXDRV) to L
  1291.      ENDIF            ; MAXDRV
  1292.  
  1293. ;     IF    MAXDRV
  1294.  
  1295.      IF    NOT ZCPR3P AND MAXDRV
  1296.     INX    H        ; +1
  1297.      ENDIF        ; NOT ZCPR33 AND MAXDRV
  1298.  
  1299.      IF    MAXDRV AND NOT DRVVEC
  1300.     CMP    L        ; Check it
  1301.     JNC    ERXIT        ; Oops if not bigger
  1302.      ENDIF            ; MAXDRV AND NOT DRVVEC
  1303. ;
  1304. ; Skips any drives marked 0FFh, some computers do not have contiguous
  1305. ; drives, such as Heath H89, etc.
  1306. ;
  1307.     MOV    E,A        ; Drive code = table index
  1308.     MVI    D,0
  1309.     LXI    H,LODRV        ; DUTBL Pointer
  1310.     DAD    D        ; DUTBL Pointer+INDEX
  1311.     MOV    A,M        ; User Number
  1312.     ORA    A        ; Set Status
  1313.     JM    NDSK        ; If negative, ignore drive
  1314.  
  1315. ;     IF    WHEEL
  1316.  
  1317.      IF    ZCPR3P AND WHEEL
  1318.     PUSH    H
  1319.     LHLD    Z3WHLL        ; Point to enviorment
  1320.     MOV    A,M        ; Get it
  1321.     POP    H
  1322.      ENDIF        ;ZCPR3P AND WHEEL
  1323.  
  1324.      IF    NOT ZCPR3P AND WHEEL
  1325.     LDA    WHLOC        ; Get wheel byte
  1326.      ENDIF        ;NOT ZCPR3P AND WHEEL
  1327.  
  1328.      IF    WHEEL
  1329.     ORA    A        ; Check it
  1330.     JZ    USRCK        ; If reset, restrict user
  1331.     MVI    A,MXZUSR    ; If set, max user = MXZUSR
  1332.     JMP    USRCK1
  1333.      ENDIF            ; WHEEL
  1334.  
  1335. USRCK:    LXI    H,LODRV        ; DUTBL PTR
  1336.     DAD    D        ; DUTLB PTR+INDEX
  1337.     MOV    A,M        ; Load max user for this drive
  1338.  
  1339.      IF    MAXUR        ; Use low memory values if smaller
  1340.     MOV    H,A        ; Current value of MAXUSR
  1341.      ENDIF        ;MAXUR
  1342.  
  1343.      IF    ZCPR3P AND MAXUR
  1344.     PUSH    H
  1345.     LHLD    Z3USRL        ; Point to ENV
  1346.     MOV    A,M        ; Get user
  1347.     POP    H
  1348.      ENDIF        ;ZCPR3P AND MAXUR
  1349.  
  1350.      IF    NOT ZCPR3P AND MAXUR
  1351.     LDA    MXUSR        ; Alternate value
  1352.      ENDIF        ;NOT ZCPR3P AND MAXUR
  1353.  
  1354. ;     ENDIF            ; MAXUR
  1355.  
  1356.      IF    MAXUR AND NOT ZCPR3P
  1357.     SBI    1        ; MAXUSR is really maximum user+1
  1358.      ENDIF            ; MAXUR AND NOT ZCPR3P
  1359.  
  1360.      IF    MAXUR
  1361.     CMP    H        ; Compare the two
  1362.     JNC    USRCK1        ; OK if MAXU <= table value
  1363.     STA    MAXUSR        ; Else replace it
  1364.      ENDIF            ; MAXUR
  1365.  
  1366. USRCK1:    MOV    B,A        ; Save max user for later testing
  1367.     ANI    1FH        ; Insure in range 0-31
  1368.     STA    MAXUSR        ; Save it for later
  1369.     LXI    H,NEWUSR    ; Point to directory user area
  1370.     CMP    M        ; Compare with the maximum
  1371.     JC    ERXIT        ; User number illegal, error exit
  1372.     POP    D        ; Destroy error message pointer
  1373.     MOV    A,B        ; Check to see if this drive
  1374.     ORA    A        ; Has been mapped out
  1375.     JM    NDSK        ; Yes, skip this drive
  1376.     LXI    H,FCB+1        ; No, point to name
  1377.     MOV    A,M        ; Any name specified?
  1378.     CPI    '$'        ; Delimiter?
  1379.     JZ    WCD        ; Yes, All files
  1380.     CPI    '/'        ; Unix/ZCPR3 delimiter?
  1381.     JZ    WCD        ; Yes, All files
  1382.     CPI    '['        ; CP/M+ delimiter?
  1383.     JZ    WCD
  1384.     CPI    ' '        ; No, Filename specified
  1385.     JNZ    GOTFCB
  1386. ;
  1387. ; No FCB - make FCB all '?'
  1388. ;
  1389. WCD:    MVI    B,11        ; Filename+typ length
  1390.  
  1391. QLOOP:    MVI    M,'?'        ; Store "?" in FCB
  1392.     INX    H        ; FCB pointer+1
  1393.     DCR    B        ; FCB length-1
  1394.     JNZ    QLOOP        ; Continue
  1395.  
  1396. GOTFCB:    MVI    A,'?'        ; Force wild extent
  1397.     STA    FCB+12
  1398.     CALL    SETSRC        ; Set DMA for BDOS media change check
  1399.     LXI    H,FCB        ; Point to FCB drive code for directory
  1400.     MOV    E,M        ; Load drive code from FCB
  1401.     DCR    E        ; Normalize drive code for select
  1402.     MVI    C,SELDSK    ; Select directory drive to retrieve
  1403.     CALL    CPM        ; The proper allocation vector
  1404.     CALL    CKVER        ; Check version
  1405.     JC    V14        ; Pre-2.x...get parameters the 1.4 way
  1406.     MVI    C,DSKPAR    ; If 2.2 or MP/M...request DPB
  1407.     CALL    BDOS
  1408.     INX    H
  1409.     INX    H
  1410.     MOV    A,M        ; Load block shift
  1411.     STA    BLKSHF        ; Block Shift
  1412.     INX    H        ; Bump to block mask
  1413.     MOV    A,M        ; Load block mask
  1414.     STA    BLKMSK        ; Block Mask
  1415.     INX    H
  1416.     INX    H
  1417.     MOV    E,M        ; Get maximum block #
  1418.     INX    H
  1419.     MOV    D,M
  1420.     XCHG
  1421.     SHLD    BLKMAX        ; Maximum Block #
  1422.     XCHG
  1423.     INX    H
  1424.     MOV    E,M        ; Load directory size
  1425.     INX    H
  1426.     MOV    D,M
  1427.     XCHG
  1428.     JMP    FREE
  1429.  
  1430. V14:    LHLD    BDOS+1        ; Get parameters 1.4 style
  1431.     MVI    L,3BH        ; Point to directory size
  1432.     MOV    E,M        ; Get it
  1433.     MVI    D,0        ; Force high order to 0
  1434.     PUSH    D        ; Save for later
  1435.     INX    H        ; Point to block shift
  1436.     MOV    A,M        ; Fetch
  1437.     STA    BLKSHF        ; Save
  1438.     INX    H        ; Point to block mask
  1439.     MOV    A,M        ; Fetch it
  1440.     STA    BLKMSK        ; And save it
  1441.     INX    H
  1442.     MOV    E,M        ; Get maximum block #
  1443.     MVI    D,0
  1444.     XCHG
  1445.     SHLD    BLKMAX        ; Save it
  1446.     POP    H        ; Restore directory size
  1447.     JMP    FREE20        ; Calculate free space from alloc vector
  1448. ;
  1449. ; Calculate number of K free on selected drive now so the FREE figure
  1450. ; will not reflect either creation or additions to the DISK.DIR file.
  1451. ; Note: This routine will not always function correctly as coded.  To
  1452. ; insure the proper calculation when the $F option is specified and
  1453. ; cataloging multiple disks on a single drive, you should do a CTL-C
  1454. ; AFTER the disk to be cataloged has been readied.
  1455. ;
  1456. FREE:    SHLD    DIRMAX        ; Save max number of directory entries
  1457.     LDA    VERFLG        ; Check version number
  1458.     CPI    30H        ; CP/M 3.0?
  1459.     JC    FREE20        ; No, Use old method
  1460.     LDA    FCB        ; Load drive number
  1461.     DCR    A        ; Normalize
  1462.     MOV    E,A        ; Use compute free space BDOS call
  1463.     MVI    C,46        ; Calculate free space
  1464.     CALL    CPM
  1465.     MVI    C,3        ; Answer is a 24-bit integer
  1466.  
  1467. FRE3L1:    LXI    H,TBUF+2    ; Answer in 1st 3 bytes of TBUF
  1468.     MVI    B,3        ; Convert from records to k
  1469.     ORA    A        ; By dividing by 8
  1470.  
  1471. FRE3L2:    MOV    A,M        ; LS byte record count
  1472.     RAR            ; /2
  1473.     MOV    M,A        ; Replace
  1474.     DCX    H        ; Next byte record count
  1475.     DCR    B        ;
  1476.     JNZ    FRE3L2        ; Loop for 3 bytes
  1477.     DCR    C
  1478.     JNZ    FRE3L1        ; Shift 3 times
  1479.     LHLD    TBUF        ; Now get result in k
  1480.     JMP    SAVFRE        ; Save Free Space
  1481.  
  1482. FREE20:    MVI    C,DSKALL    ; Allocation vector address
  1483.     CALL    BDOS
  1484.     XCHG
  1485.     LHLD    BLKMAX        ; Max Block Number
  1486.     INX    H
  1487.     LXI    B,0        ; Init block count = 0
  1488.  
  1489. GSPBYT:    PUSH    D        ; Save allocation address
  1490.     LDAX    D
  1491.     MVI    E,8        ; Set to process 8 blocks
  1492.  
  1493. GSPLUP:    RAL            ; Test bit
  1494.     JC    NOTFRE
  1495.     INX    B
  1496.  
  1497. NOTFRE:    MOV    D,A        ; Save bits
  1498.     DCX    H        ; Count down blocks
  1499.     MOV    A,L
  1500.     ORA    H
  1501.     JZ    ENDALC        ; Quit if out of blocks
  1502.     MOV    A,D        ; Restore bits
  1503.     DCR    E        ; Count down 8 bits
  1504.     JNZ    GSPLUP        ; Do another bit
  1505.     POP    D        ; Bump to next byte of allocation vector
  1506.     INX    D
  1507.     JMP    GSPBYT        ; Process it
  1508.  
  1509. ENDALC:    POP    D        ; Clear stack of allocation vector pointer
  1510.     MOV    L,C        ; Copy blocks to HL
  1511.     MOV    H,B
  1512.     LDA    BLKSHF        ; Load block shift factor
  1513.     SUI    3        ; Convert from records to k
  1514.     JZ    SAVFRE        ; Skip shifts if 1k blocks return free in HL
  1515.  
  1516. FREKLP:    DAD    H        ; Multiply blocks by k/block
  1517.     DCR    A
  1518.     JNZ    FREKLP
  1519. ;
  1520. SAVFRE:    SHLD    FREEBY        ; Save free space for output later
  1521.     XCHG
  1522.     LHLD    TOTFRE
  1523.     DAD    D
  1524.     SHLD    TOTFRE
  1525. ;
  1526. ; Reenter here on subsequent passes while in the all-users mode
  1527. ;
  1528. SETTBL:    LHLD    DIRMAX        ; Load directory maximum size
  1529.     INX    H        ; Directory size is DIRMAX+1
  1530.     DAD    H        ; Double directory size
  1531.     LXI    D,ORDER        ; Too get order table size
  1532.     DAD    D        ; Allocate order table
  1533.     SHLD    TBLOC        ; Name tbl begins where order tbl ends
  1534.     SHLD    NEXTT
  1535.     XCHG
  1536.     LHLD    BDOS+1        ; Insure we have room to continue
  1537.     MOV    A,E
  1538.     SUB    L
  1539.     MOV    A,D
  1540.     SBB    H
  1541.     JNC    OUTMEM
  1542.     CALL    CKVER        ; Set carry if pre-CP/M 2
  1543.     LDA    NEWUSR        ; Load directory user area
  1544.     MOV    E,A
  1545.     MVI    C,STUSER    ; Get the user function
  1546.     CNC    CPM        ; Set new user number if CP/M 2
  1547. ;
  1548. ; Look up the FCB in the directory
  1549. ;
  1550.     MVI    A,'?'        ; Check for wild FCB extent
  1551.     LXI    H,FCB+12
  1552.     MOV    M,A        ; Match all extents
  1553.     INX    H
  1554.     MOV    M,A        ; Match all S1 bytes
  1555.     INX    H
  1556.     MOV    M,A        ; Match all S2 bytes
  1557.     LXI    H,0
  1558.     SHLD    COUNT        ; Initialize match counter
  1559.     SHLD    TOTFIL        ; "  total file counter
  1560.     SHLD    TOTSIZ        ; "  total size counter
  1561.     CALL    SETSRC        ; Set DMA for directory search
  1562.     MVI    C,SRCHF        ; Load 'search first' function
  1563.     JMP    LOOK        ; Go search for 1st match
  1564. ;
  1565. ; Read more directory entries
  1566. ;
  1567. MORDIR:    MVI    C,SRCHN        ; Search next function
  1568.  
  1569. LOOK:    LXI    D,FCB        ; A(file control block)
  1570.     CALL    CPM        ; Read directory entry
  1571.     INR    A        ; End (0FFH)?
  1572.     JZ    SPRINT        ; Yes, sort & print what we have
  1573. ;
  1574. ; Point to directory entry
  1575. ;
  1576.     DCR    A        ; Undo previous INR A
  1577.     ANI    3        ; Make modulus 4
  1578.     ADD    A        ; Multiply
  1579.     ADD    A        ; By 32 because
  1580.     ADD    A        ; Each directory
  1581.     ADD    A        ; Entry is 32
  1582.     ADD    A        ; Bytes long
  1583.     LXI    H,TBUF+1    ; Point to buffer (skip to FN/FT)
  1584.     ADD    L        ; Point to entry
  1585.  
  1586.      IF    FATTRIB
  1587.     MOV    L,A        ; HL now point to file name
  1588.     LDA    ONEFLG        ; Looking for only attribute 1?
  1589.     ORA    A
  1590.     JNZ    NOTONE        ; NZ=no
  1591.     MOV    A,M
  1592.     ORA    A
  1593.     JP    MORDIR        ; P=not attr 1
  1594. NOTONE:    INX    H
  1595.     LDA    TWOFLG        ; Only attribute 2?
  1596.     ORA    A
  1597.     JNZ    NOTTWO        ; NZ=no
  1598.     MOV    A,M
  1599.     ORA    A
  1600.     JP    MORDIR        ; P=not attr 2
  1601. NOTTWO:    INX    H
  1602.     LDA    THRFLG        ; Only attrib 3?
  1603.     ORA    A
  1604.     JNZ    NOTTHR        ; NZ=no
  1605.     MOV    A,M
  1606.     ORA    A
  1607.     JP    MORDIR        ; P= not attr 3
  1608. NOTTHR:    INX    H
  1609.     LDA    FORFLG        ; Only attr 4?
  1610.     ORA    A
  1611.     JNZ    NOTFOR        ; NZ=no
  1612.     MOV    A,M
  1613.     ORA    A
  1614.     JP    MORDIR        ; P= not attr 4
  1615. NOTFOR:    MOV    A,L
  1616.     ADI    6
  1617.      ENDIF        ; FATTRIB
  1618.  
  1619.      IF    NOT FATTRIB
  1620.     ADI    9        ; Point to sys byte
  1621.      ENDIF        ; NOT FATTRIB
  1622.  
  1623.     MOV    L,A        ; Save (can't carry to H)
  1624.     LDA    QOPFLG        ; Find only non-$ARC files?
  1625.     ORA    A
  1626.     JNZ    OSYS        ; No, check for only $SYS files
  1627.     INX    H        ; Yes, get the archive byte
  1628.     MOV    A,M
  1629.     DCX    H
  1630.     ORA    A        ; Check bit 7 for $ARC file
  1631.     JM    MORDIR        ; If set, ignore this filename
  1632.  
  1633. OSYS:    LDA    OOPFLG        ; Find only $SYS files?
  1634.     ORA    A
  1635.     JNZ    CKSYS
  1636.     MOV    A,M        ; Yes, get system byte
  1637.     ORA    A        ; Check bit 7 for $SYS file
  1638.     JP    MORDIR        ; If not set, ignore this filename
  1639.     JMP    SYSFOK        ; Else check for a match
  1640.  
  1641. CKSYS:    LDA    SOPFLG        ; Did user request $SYS files?
  1642.     ORA    A
  1643.     JZ    SYSFOK        ; If yes, exit
  1644.     MOV    A,M        ; Get system byte back
  1645.     ORA    A        ; Check bit 7 for $SYS file
  1646.     JM    MORDIR        ; Skip that file
  1647.  
  1648. SYSFOK:    MOV    A,L        ; Go back now
  1649.     SUI    10        ; Back to user number (allocation flag)
  1650.     MOV    L,A        ; HL points to entry now
  1651.     LDA    NEWUSR        ; Get current user
  1652.     CMP    M
  1653.     JNZ    MORDIR        ; Ignore if different
  1654.     INX    H
  1655.  
  1656.      IF    Z80DOS
  1657.     PUSH    B        ;
  1658.     PUSH    D        ;
  1659.     PUSH    H        ;
  1660.     MVI    C,54        ; Get time stamp from last search
  1661.     CALL    BDOS        ;
  1662.     LXI    D,6        ; Point to last access field
  1663.     LDA    DGOPFL
  1664.     ORA    A
  1665.     JZ    ACCESS        ; Z=what is wanted
  1666.     LXI    D,2        ; Point to last alteration field
  1667.     LDA    DAOPFL
  1668.     ORA    A
  1669.     JZ    ACCESS        ; Z=what is wanted
  1670.     LXI    D,0        ; Point to creation field
  1671.     LDA    DNOPFL
  1672.     ORA    A
  1673.     JZ    ACCESS        ; Z=what is wanted
  1674.  
  1675.     LXI    D,2        ; Didn't say, so give him alteration date
  1676.  
  1677. ACCESS: PUSH    H
  1678.     DAD    D        ; Point to right field in returned database
  1679.     MOV    E,M        ; Get the date in Julian
  1680.     INX    H
  1681.     MOV    D,M
  1682.     MOV    A,D        ; Is requested date 0 for the file?
  1683.     ORA    E
  1684.     JNZ    ACCESS1        ; NZ=no, use it
  1685.     POP    H        
  1686.     MOV    E,M        ; Was zero, use creation date
  1687.     INX    H
  1688.     MOV    D,M
  1689.     PUSH    H
  1690. ACCESS1:
  1691.     XCHG
  1692.     SHLD    DATMOD
  1693.     POP    H
  1694. ;////
  1695.     POP    H
  1696.     POP    D
  1697.     POP    B
  1698.      ENDIF        ;Z80DOS
  1699. ;
  1700. ; Move entry to table
  1701. ;
  1702.     XCHG            ; Entry to DE
  1703.     LHLD    NEXTT        ; Next table entry to HL
  1704.     MVI    B,11        ; Entry length (name, type, extent)
  1705.  
  1706. TMOVE:    LDAX    D        ; Get entry character
  1707.  
  1708.      IF    NOT (USELC OR REVID)
  1709.     ANI    7FH        ; Remove attributes
  1710.      ENDIF            ; NOT (USELC OR REVID)
  1711.  
  1712.     MOV    M,A        ; Store in table
  1713.     INX    D
  1714.     INX    H
  1715.     DCR    B        ; More?
  1716.     JNZ    TMOVE
  1717.     INX    D        ; DE->> S1
  1718.     INX    D        ; DE->> S2
  1719.     LDAX    D        ; Get S2 byte, oflo=int(extents/32)
  1720.     PUSH    H        ; Save HL
  1721.     MOV    L,A        ; Set up 16-bit multiply
  1722.     MVI    H,0
  1723.     MVI    B,5
  1724.     CALL    SHLL        ; HL is now # of oflo extents
  1725.     DCX    D        ; DE->> S1
  1726.     DCX    D        ; DE->> extent
  1727.     LDAX    D        ; Get extent
  1728.     ADD    L
  1729.     MOV    L,A
  1730.     MOV    A,H
  1731.     ACI    0
  1732.     MOV    H,A        ; HL has total extents
  1733.     MVI    B,7
  1734.     CALL    SHLL        ; HL has total records less last ext
  1735.     INX    D        ; DE->> S1
  1736.     INX    D        ; DE->> S2
  1737.     INX    D        ; Point to sector count
  1738.     LDAX    D        ; Get it
  1739.     ADD    L
  1740.     MOV    L,A
  1741.     MOV    A,H
  1742.     ACI    0
  1743.     MOV    H,A        ; HL has total records
  1744.     XTHL            ; Do some fancy shuffling
  1745.     XCHG
  1746.     XTHL
  1747.     XCHG
  1748.     MOV    M,D
  1749.     INX    H
  1750.     MOV    M,E
  1751.     POP    D        ; All back to normal
  1752.     INX    H
  1753.  
  1754.      IF    Z80DOS
  1755.     LDA    DATMOD        ; Get LSB of last modified date
  1756.     MOV    M,A        ;
  1757.     INX    H        ;
  1758.     LDA    DATMOD+1    ; Get MSB of last modified date
  1759.     MOV    M,A        ;
  1760.     INX    H        ;
  1761.      ENDIF        ;Z80DOS
  1762.  
  1763.     SHLD    NEXTT        ; Save updated table address
  1764.     XCHG
  1765.     LHLD    COUNT        ; Bump the # of matches made
  1766.     INX    H
  1767.     SHLD    COUNT
  1768.  
  1769.      IF    Z80DOS
  1770.     LXI    H,15        ; Size of entry include date
  1771.      ENDIF        ;Z80DOS
  1772.  
  1773.      IF    NOT Z80DOS
  1774.     LXI    H,13        ; Size of next entry
  1775.      ENDIF        ;NOT Z80DOS
  1776.  
  1777.     DAD    D
  1778.     XCHG            ; Future NEXTT is in DE
  1779.     LHLD    BDOS+1        ; Pick up TPA end
  1780.     MOV    A,E
  1781.     SUB    L        ; Compare NEXTT-TPA end
  1782.     MOV    A,D
  1783.     SBB    H
  1784.     JC    MORDIR        ; If TPA end > NEXTT, loop back for more
  1785.  
  1786. OUTMEM:    CALL    ERXIT        ; Exit if directory too large
  1787.     DB    'Memory',0
  1788. ;
  1789. ; Shift HL left by B bits
  1790. ;
  1791. SHLL:    DAD    H
  1792.     DCR    B
  1793.     RZ
  1794.     JMP    SHLL
  1795. ;
  1796. ; Sort and print
  1797. ;
  1798. SPRINT:    CALL    SETFOP        ; Return to file output DMA & user #
  1799.     LHLD    COUNT        ; Get file name count
  1800.     MOV    A,L
  1801.     ORA    H        ; Any found?
  1802.     JZ    PRTOTL        ; Exit if no files found
  1803.     PUSH    H        ; Save file count
  1804.     STA    SUPSPC        ; Enable leading zero suppression
  1805. ;
  1806. ; Initialize the order table
  1807. ;
  1808.     LHLD    TBLOC        ; Get start of name table
  1809.     XCHG            ; Into DE
  1810.     LXI    H,ORDER        ; Point to order table
  1811.  
  1812.      IF    Z80DOS
  1813.     LXI    B,15        ; Entry length including date
  1814.      ENDIF        ;Z80DOS
  1815.  
  1816.      IF    NOT Z80DOS
  1817.     LXI    B,13        ; Entry length
  1818.      ENDIF        ;NOT Z80DOS
  1819.  
  1820. BLDORD:    MOV    M,E        ; Save low order address
  1821.     INX    H
  1822.     MOV    M,D        ; Save high order address
  1823.     INX    H
  1824.     XCHG            ; Table address to HL
  1825.     DAD    B        ; Point to next entry
  1826.     XCHG
  1827.     XTHL            ; Save table address, load loop counter
  1828.     DCX    H        ; Count down loop
  1829.     MOV    A,L
  1830.     ORA    H        ; More?
  1831.     XTHL            ; Load table address, save loop counter
  1832.     JNZ    BLDORD        ; Yes, go do another one
  1833.     POP    H        ; Clean loop counter off stack
  1834.     LHLD    COUNT        ; Get count
  1835.     SHLD    SCOUNT        ; Save as # to sort
  1836.     DCX    H        ; Only 1 entry?
  1837.     MOV    A,L
  1838.     ORA    H
  1839.     JZ    DONE        ; Yes, so skip sort
  1840. ;
  1841. ; This sort routine is adapted from SOFTWARE TOOLS
  1842. ;
  1843.     LHLD    SCOUNT        ; Number of entries
  1844.  
  1845. L1:    ORA    A        ; Clear carry
  1846.     MOV    A,H        ; GAP=GAP/2
  1847.     RAR
  1848.     MOV    H,A
  1849.     MOV    A,L
  1850.     RAR
  1851.     MOV    L,A
  1852.     ORA    H        ; Is it zero?
  1853.     JZ    DONE        ; Then none left
  1854.     MOV    A,L        ; Make gap odd
  1855.     ORI    1
  1856.     MOV    L,A
  1857.     SHLD    GAP
  1858.     INX    H        ; I=GAP+1
  1859.  
  1860. L2:    SHLD    I
  1861.     XCHG
  1862.     LHLD    GAP
  1863.     MOV    A,E        ; J=I-GAP
  1864.     SUB    L
  1865.     MOV    L,A
  1866.     MOV    A,D
  1867.     SBB    H
  1868.     MOV    H,A
  1869.  
  1870. L3:    SHLD    J
  1871.     XCHG
  1872.     LHLD    GAP        ; JG=J+GAP
  1873.     DAD    D
  1874.     SHLD    JG
  1875.     CALL    COMPARE        ; Compare (J) and (JG)
  1876. ;
  1877. ; Use carry flag instead of sign flag to test results of COMPARE 
  1878. ; because the sign flag is set to M when the result of a subtraction
  1879. ; is 80h or greater.
  1880. ;
  1881. ;    JP    P,L4        ; If A(J)<=A(JG)
  1882.     JNC    L4        ; <crw>
  1883.     LHLD    J
  1884.     XCHG
  1885.     LHLD    JG
  1886.     CALL    SWAP        ; Exchange a(J) and a(JG)
  1887.     LHLD    J        ; J=J-GAP
  1888.     XCHG
  1889.     LHLD    GAP
  1890.     MOV    A,E
  1891.     SUB    L
  1892.     MOV    L,A
  1893.     MOV    A,D
  1894.     SBB    H
  1895.     MOV    H,A
  1896.     JM    L4        ; If J>0 go to l3
  1897.     ORA    L        ; Check for zero
  1898.     JZ    L4
  1899.     JMP    L3
  1900.  
  1901. L4:    LHLD    SCOUNT        ; For later
  1902.     XCHG
  1903.     LHLD    I        ; I=I+1
  1904.     INX    H
  1905.     MOV    A,E        ; If I<=n go to l2
  1906.     SUB    L
  1907.     MOV    A,D
  1908.     SBB    H
  1909.     JP    L2
  1910.     LHLD    GAP
  1911.     JMP    L1
  1912. ;
  1913. ; Sort is all done - print entries
  1914. ;
  1915. DONE:    LDA    FOPFLG        ; File output flag
  1916.     ORA    A        ; Set?
  1917.     JNZ    NOOUT        ; No, skip open
  1918. ;
  1919. ; If all user option enabled, and we're not on the first pass, then the
  1920. ; output file is already open and positioned, so we can skip the open.
  1921. ;
  1922.     LXI    H,OPNFLG    ; Output file open flag
  1923.     CMP    M        ; A=0,set Z if OPNFLG=0 also
  1924.     JNZ    NOOUT        ; If OPNFLG not zero, skip open
  1925.     DCR    M        ; Else, set OPNFLG for next user #
  1926. ;
  1927. ; First pass on file append - prepare DISK.DIR to receive new
  1928. ; or appended output.
  1929. ;
  1930.     LXI    D,OUTFCB    ; Does output file exist?
  1931.     MVI    C,SRCHF
  1932.     CALL    CPM
  1933.     INR    A
  1934.     JNZ    OPENIT        ; Yes, open for processing
  1935.     MVI    C,MAKE        ; Else, create output file
  1936.     CALL    CPM
  1937.     INR    A        ; Successful?
  1938.     JNZ    NOOUT        ; Yes, Continue
  1939. ;
  1940. ; If make or open fails, declare error
  1941. ;
  1942. OPNERR:    CALL    ERXIT
  1943.     DB    'Open',0
  1944. ;
  1945. WRTERR:    CALL    ERXIT
  1946.     DB    'Write',0
  1947. ;
  1948. ; Output file already exists - open it and position
  1949. ; it to the last record of the last extent.
  1950. ;
  1951. OPENIT:    MVI    C,OPEN        ; Open 1st extent of output file
  1952.     CALL    CPM
  1953.     INR    A
  1954.     JZ    OPNERR        ; Bad deal if 1st won't open
  1955.  
  1956. OPNMOR:    LDA    OUTFCB+15    ; Record count (RC)
  1957.     CPI    128
  1958.     JC    LSTEXT        ; If RC<128, this is last extent
  1959.     LXI    H,OUTFCB+12
  1960.     INR    M        ; Else, increment to next extent
  1961.     MVI    C,OPEN        ; Try to open it
  1962.     CALL    CPM
  1963.     INR    A
  1964.     JNZ    OPNMOR        ; Continue opening extents to end
  1965.     DCR    M        ; Then, reopen preceding extent
  1966.     MVI    C,OPEN
  1967.     CALL    CPM
  1968.     LDA    OUTFCB+15    ; Get RC for the last extent
  1969. ;
  1970. ; At this point, OUTFCB is opened to the last extent of the file, so
  1971. ; read in the last record in the last extent.
  1972. ;
  1973. LSTEXT:    ORA    A        ; Is this extent empty?
  1974.     JZ    NOOUT        ; Yes, starting a clean slate
  1975.     DCR    A        ; Normalize record count
  1976.     STA    OUTFCB+32    ; Set record number to read
  1977.     MVI    C,READ        ; Read last record of file
  1978.     CALL    CPM
  1979.     ORA    A        ; Successful read?
  1980.     JZ    RDOK        ; Yes, scan for EOF mark
  1981.  
  1982. APERR:    CALL    ERXIT
  1983.     DB    'Append',0
  1984. ;
  1985. ; We now have the last record in the file in the buffer. Scan the last
  1986. ; record for the EOF mark, indicate where we can start adding data.
  1987. ;
  1988. RDOK:    LXI    H,OUTBUF    ; Point to output buffer start
  1989.     MVI    B,128        ; Output buffer length
  1990.  
  1991. SCAN:    MOV    A,M        ; Character
  1992.     CPI    'Z'-40H        ; End of file?
  1993.     JZ    RESCR        ; Yes, save pointers and reset CR
  1994.     INX    H        ; Pointer+1
  1995.     DCR    B        ; Length-1
  1996.     JNZ    SCAN        ; Continue to end of buffer
  1997. ;
  1998. ; If an explicit EOF mark or an implied EOF (last record is full) in
  1999. ; the last buffer, move the FCB record and extent pointer back to cor-
  2000. ; rect for the read operation so the first write operation will replace
  2001. ; the last record of the DISK.DIR file.
  2002. ;
  2003. RESCR:    PUSH    H        ; Save EOF buffer pointer
  2004.     PUSH    B        ; Save EOF buffer remaining
  2005.     LXI    H,OUTFCB+32    ; Load current record again
  2006.     DCR    M        ; Record-1
  2007.     JP    SAMEXT        ; If CR>=0, still in same extent
  2008.     LXI    H,OUTFCB+12    ; Else, move to previous extent
  2009.     DCR    M
  2010.     MVI    C,OPEN        ; Then, reopen previous extent
  2011.     CALL    CPM
  2012.     INR    A
  2013.     JZ    APERR        ; Append error if can not reopen
  2014.     LDA    OUTFCB+15    ; Else,
  2015.     DCR    A        ; Position to last record of
  2016.     STA    OUTFCB+32    ; The extent
  2017.  
  2018. SAMEXT:    POP    PSW        ; Recall EOF location in buffer
  2019.     STA    BUFCNT        ; Set buffer counter
  2020.     POP    H        ; Recall next buffer pointer
  2021.     SHLD    BUFPNT        ; Set pointer for first addition
  2022.  
  2023. NOOUT:    LDA    FIRSTT        ; First time through?
  2024.     ORA    A
  2025.     JNZ    NOVOPT        ; No, we've been here before
  2026.     MVI    A,0FFH        ; Yes,
  2027.     STA    FIRSTT        ; Set first time flag
  2028.     LDA    VOPFLG        ; Version display flag
  2029.     ORA    A        ; Set?
  2030.     JNZ    NOVOPT        ; No, skip version print
  2031.     LXI    D,VERNAME    ; Yes, print version
  2032.     CALL    PUTS        ; Print the string
  2033.     CALL    CRLF
  2034.  
  2035. NOVOPT:    LHLD    COUNT
  2036.     SHLD    LCOUNT
  2037.     LXI    H,0
  2038.     SHLD    LBTOTL
  2039.     SHLD    LMTOTL
  2040.     LXI    H,ORDER        ; Initialize order table pointer
  2041.     SHLD    NEXTL
  2042.     SHLD    NEXTT
  2043.     LDA    VFLAG        ; Check display form
  2044.     ORA    A
  2045.     JNZ    NEWLIN        ; Jump if not vertical
  2046.     LHLD    COUNT        ; Code computes end of name table
  2047.     CALL    MULT13        ; (or start of second table
  2048.     XCHG            ; Where files to be stored after
  2049.     LHLD    TBLOC        ; Redundant extents removed)
  2050.     DAD    D
  2051.     SHLD    NEWPTR        ; Save it twice
  2052.     SHLD    XPOINT        ; For later
  2053. ;
  2054. ; Output the directory files we've matched
  2055. ;
  2056. ENTRY:    LHLD    COUNT        ; Files matched count
  2057.     DCX    H        ; Count-1
  2058.     SHLD    COUNT
  2059.     MOV    A,H        ; Is this the last file?
  2060.     ORA    L
  2061.     JZ    OKPRNT        ; Yes, last file so skip compare
  2062. ;
  2063. ; Compare each entry to make sure that it isn't part of a multiple
  2064. ; extent file.    Go only when we have the last extent of the file.
  2065. ;
  2066.     PUSH    B        ; Save number of columns
  2067.     LDA    VFLAG        ; Check display form
  2068.     ORA    A
  2069.     CNZ    CKABRT        ; If horiz, check for abort from keyboard
  2070.     LHLD    NEXTT
  2071.     MVI    A,11
  2072.     CALL    COMPR        ; Does this entry match next one?
  2073.     POP    B        ; Restore number of columns
  2074.     JNZ    OKPRNT        ; No, print it
  2075. NOKPRN:    INX    H
  2076.     INX    H        ; Skip, highest extent last in list
  2077.     SHLD    NEXTT
  2078.     JMP    ENTRY        ; Loop back for next lowest extent
  2079. ;
  2080. ; VLIST substitution. If VLIST option chosen, OKPRINT moves unique
  2081. ; filenames and sizes in "k" to a second table above the first for
  2082. ; use later.
  2083. ;
  2084. OKPRNT:
  2085. ;////
  2086.      IF    Z80DOS
  2087.     PUSH    H
  2088.     PUSH    D
  2089.     PUSH    B
  2090.     LHLD    NEXTT        ; Get order table pointer
  2091.     MOV    E,M        ; Get low order address
  2092.     INX    H
  2093.     MOV    D,M        ; Get high order address
  2094.     LXI    H,13
  2095.     DAD    D
  2096.     MOV    E,M
  2097.     INX    H
  2098.     MOV    D,M
  2099.     LHLD    DATCHK        ; Get the date we are looking for
  2100.     MOV    A,H
  2101.     ORA    L
  2102.     JZ    GDTMTC        ; Z=not looking
  2103.     LHLD    DATCH1
  2104.     MOV    A,H
  2105.     ORA    L
  2106.     JZ    ONEDAT        ; Z=only 1 date on input line
  2107.     DW    SBCDE
  2108.     JZ    GDTMTC        ; Z=file date=low date
  2109.     JNC    NDTMTC        ; NC=file date < low date, no output
  2110.     LHLD    DATCHK
  2111.     ORA    A
  2112.     DW    SBCDE
  2113.     JZ    GDTMTC        ; Z=file date=high date
  2114.     JNC    GDTMTC        ; NC=file date < high date
  2115.     JMP    NDTMTC        ; File date > high date
  2116. ONEDAT:    LHLD    DATCHK
  2117.     MOV    A,H
  2118.     CMP    D        ; Check if given date >,=,< the files date
  2119.     JZ    CHDLOW        ; High EQ, check low
  2120.     JC    DATLT        ; C=LT
  2121.     JMP    DATGE        ; Given date GT file date
  2122. CHDLOW:    MOV    A,L        ; Check low byte of date vs. file date
  2123.     CMP    E
  2124. DATGE:    MVI    A,0        ; Assume EQ
  2125.     JC    DATLT        ; C= given LT files date
  2126.     JZ    DATFLG        ; Z= they are EQ
  2127.     MVI    A,2        ; Given GT files date
  2128.     JMP    DATFLG
  2129. DATLT:    MVI    A,1        ; Given was less than files
  2130. DATFLG:    STA    DTMTCH
  2131.     LDA    DEOPFL        ; What kind of date match?
  2132.     ORA    A
  2133.     JZ    DTEXAC        ; Z=exact
  2134.     LDA    DPOPFL
  2135.     ORA    A
  2136.     JZ    DTABVE        ; Z=GE
  2137.     LDA    DMOPFL        ; LT wanted?
  2138.     ORA    A
  2139.     JNZ    DTEXAC        ; NZ=no, didn't tell us so do anything but gave
  2140.                 ; us a date so assume want exact match
  2141.     LDA    DTMTCH
  2142.     CPI    2
  2143.     JZ    GDTMTC        ; Date was below and they wanted below
  2144. NDTMTC:
  2145.     POP    B
  2146.     POP    D
  2147.     POP    H
  2148.     PUSH    H
  2149.     LHLD    COUNT
  2150.     MOV    A,L
  2151.     ORA    H
  2152.     POP    H
  2153.     JZ    PRTOTL
  2154.     JMP    NOKPRN
  2155.  
  2156. DTEXAC:    LDA    DTMTCH        ; They wanted exact, was it?
  2157.     ORA    A
  2158.     JZ    GDTMTC        ; Z=yes
  2159.     JMP    NDTMTC
  2160. DTABVE:    LDA    DTMTCH        ; They wanted GE
  2161.     CPI    1
  2162.     JZ    GDTMTC        ; Z=G
  2163.     ORA    A
  2164.     JNZ    NDTMTC        ; Must be 2, so not equal
  2165. GDTMTC:    POP    B
  2166.     POP    D
  2167.     POP    H
  2168.      ENDIF        ; Z80DOS
  2169.     
  2170.     LHLD    NEXTT        ; Get order table pointer
  2171.     MOV    E,M        ; Get low order address
  2172.     INX    H
  2173.     MOV    D,M        ; Get high order address
  2174.     INX    H
  2175.     SHLD    NEXTT        ; Save updated table pointer
  2176.     XCHG            ; Table entry to HL
  2177.     LDA    VFLAG        ; Check display form
  2178.     ORA    A
  2179.     JNZ    OKPR1        ; Jump if not vertical
  2180.     PUSH    H        ; Save address of byte to be moved
  2181.     LHLD    NEWPTR        ; Address in new table to put byte
  2182.     PUSH    H        ; Save address
  2183.  
  2184.      IF    Z80DOS
  2185.     LXI    D,15        ; Update address including date
  2186.      ENDIF        ;Z80DOS
  2187.  
  2188.      IF    NOT Z80DOS
  2189.     LXI    D,13        ; Update address
  2190.      ENDIF        ;NOT Z80DOS
  2191.  
  2192.     DAD    D
  2193.     SHLD    NEWPTR        ; Save for later (end of table)
  2194.     POP    H        ; Set current move  to    address
  2195.     XCHG            ; Swap pointers
  2196.     POP    H        ; Set current move from address
  2197.     MVI    B,11        ; Filename.typ length
  2198.     CALL    MOVE        ; Move it
  2199.  
  2200.      IF    Z80DOS
  2201.     PUSH    H
  2202.      ENDIF        ;Z80DOS
  2203.  
  2204.     PUSH    D
  2205.     JMP    OKPR2
  2206.  
  2207. OKPR1:    MVI    B,8        ; Filename length
  2208.     CALL    PUTSB        ; Output
  2209.     MVI    A,'.'        ; Period after filename
  2210.     CALL    PUTCHR        ; Output
  2211.     MVI    B,3        ; Filetype length
  2212.     CALL    PUTSB        ; Output
  2213.  
  2214.      IF    Z80DOS
  2215.     LDA    NODFLG
  2216.     ORA    A
  2217.     JZ    NOD1
  2218.     CALL    DISDAT
  2219. NOD1:
  2220.      ENDIF        ;Z80DOS
  2221.  
  2222. OKPR2:    
  2223.     CALL    SIZEFL
  2224.     LHLD    TOTSIZ        ; DE = rounded size in K
  2225.     DAD    D        ; Add to total used
  2226.     SHLD    TOTSIZ
  2227.     LHLD    TOTFIL        ; Increment filecount
  2228.     INX    H
  2229.     SHLD    TOTFIL
  2230.     XCHG
  2231.     LDA    COPFLG        ; Size wanted in records?
  2232.     ORA    A
  2233.     JNZ    OKPR3        ; Jump if not
  2234.     LHLD    FILERC        ; Else get record count
  2235.  
  2236. OKPR3:    LDA    VFLAG        ; Check display form
  2237.     ORA    A
  2238.     JNZ    OKPR4        ; Jump if not vertical
  2239.     POP    D        ; A(size to go)
  2240.     MOV    A,H        ; Move size to table two
  2241.     STAX    D
  2242.     INX    D
  2243.     MOV    A,L
  2244.     STAX    D
  2245.  
  2246.      IF    Z80DOS
  2247.     POP    H        ; Currently pointing to file size
  2248.     INX    H        ; Skip size
  2249.     INX    H
  2250.     INX    D
  2251.     MOV    A,M        ; Get LSB of date
  2252.     STAX    D        ; Save it away
  2253.     INX    D
  2254.     INX    H
  2255.     MOV    A,M        ; Ditto for MSB of date
  2256.     STAX    D
  2257.      ENDIF        ;Z80DOS
  2258. ;
  2259. ; One File Moved - Test to see if we have to move another
  2260. ;
  2261.     LHLD    COUNT        ; Current file counter
  2262.     MOV    A,H
  2263.     ORA    L
  2264.     JZ    PRTOTL        ; Zero, output summary
  2265.     JMP    ENTRY
  2266. ;
  2267. ; Output the size of the individual file
  2268. ;
  2269. OKPR4:    CALL    DECPRT        ; Print it
  2270.     LDA    FSIZEC        ; Follow with 'k' or 'r'
  2271.     CALL    PUTCHR
  2272. ;
  2273. ; One file output - test to see if we have to output another one.
  2274. ;
  2275.     LHLD    COUNT        ; Current file counter
  2276.     MOV    A,H
  2277.     ORA    L        ; Zero?
  2278.     JZ    PRTOTL        ; Yes, exit to summary output
  2279. ;
  2280. ; At least one more file to output,
  2281. ; can we put it on the current line?
  2282. ;
  2283.     DCR    C
  2284.     PUSH    PSW
  2285.     CNZ    FENCE        ; If room left output fence character
  2286.     POP    PSW
  2287.     JNZ    ENTRY        ; Output another file
  2288. ;
  2289. ; Current line full, start a new one
  2290. ;
  2291. NEWLIN:
  2292.      IF    Z80DOS
  2293.     MVI    C,2        ; 2 names per line
  2294.     LDA    NODFLG
  2295.     ORA    A
  2296.     JNZ    NOD2
  2297.     MVI    C,4
  2298. NOD2:
  2299.      ENDIF        ;Z80DOS
  2300.  
  2301.      IF    NOT Z80DOS
  2302.     MVI    C,4        ; Reset names per line counter
  2303.      ENDIF        ;NOT Z80DOS
  2304.  
  2305.     CALL    CRLF        ; Space down to next line
  2306.     JMP    ENTRY        ; Output another file
  2307. ;.....
  2308. ;
  2309. ; Compute the size of the file/library and update our summary datum.
  2310. ; This has been changed into a subroutine so that both the file size
  2311. ; computation and a library size (when printing out library members)
  2312. ; can be computed in K.
  2313. ;
  2314. SIZEFL:    MOV    D,M
  2315.     INX    H
  2316.     MOV    E,M        ; Size in DE (records)
  2317.     XCHG
  2318.     SHLD    FILERC        ; Save record count
  2319.     XCHG
  2320.     LDA    BLKMSK
  2321.     PUSH    PSW
  2322.     ADD    E
  2323.     MOV    E,A
  2324.     MOV    A,D
  2325.     ACI    0
  2326.     MOV    D,A
  2327.     POP    PSW
  2328.     CMA
  2329.     ANA    E
  2330.     MOV    E,A
  2331.     MVI    B,3
  2332.  
  2333. SHRR:    MOV    A,D
  2334.     ORA    A
  2335.     RAR
  2336.     MOV    D,A
  2337.     MOV    A,E
  2338.     RAR
  2339.     MOV    E,A
  2340.     DCR    B
  2341.     JNZ    SHRR
  2342.     RET
  2343. ;
  2344. ; Print HL in decimal with leading zero suppression
  2345. ;
  2346. DECPRT:    XRA    A        ; Clear leading zero flag
  2347.     STA    LZFLG
  2348.     LXI    D,-10000
  2349.     LDA    SUPSPC
  2350.     PUSH    PSW
  2351.     XRA    A
  2352.     STA    SUPSPC
  2353.     CALL    DIGIT
  2354.     POP    PSW
  2355.     STA    SUPSPC
  2356.     LXI    D,-1000        ; Print 1000's digit
  2357.     CALL    DIGIT
  2358.     LXI    D,-100        ; Etc.
  2359.     CALL    DIGIT
  2360.     LXI    D,-10
  2361.     CALL    DIGIT
  2362.     MVI    A,'0'        ; Get 1's digit
  2363.     ADD    L
  2364.     JMP    PUTCHR
  2365.  
  2366. DIGIT:    MVI    B,'0'        ; Start off with ASCII 0
  2367.  
  2368. DIGLP:    PUSH    H        ; Save current remainder
  2369.     DAD    D        ; Subtract
  2370.     JNC    DIGEX        ; Quit on overflow
  2371.     POP    PSW        ; Throw away remainder
  2372.     INR    B        ; Bump digit
  2373.     JMP    DIGLP        ; Loop back
  2374.  
  2375. DIGEX:    POP    H        ; Restore pointer
  2376.     MOV    A,B
  2377.     CPI    '0'        ; Zero digit?
  2378.     JNZ    DIGNZ        ; No, type it
  2379.     LDA    LZFLG        ; Leading zero?
  2380.     ORA    A
  2381.     MVI    A,'0'
  2382.     JNZ    PUTCHR        ; Print digit
  2383.     LDA    SUPSPC        ; Get space suppression flag
  2384.     ORA    A        ; See if printing file totals
  2385.     RZ            ; Yes, don't give leading spaces
  2386.     JMP    SPACE        ; Leading zero..print space
  2387. ;
  2388. DIGNZ:    STA    LZFLG        ; Leading zero flag set
  2389.     JMP    PUTCHR        ; Print leading zero & digit
  2390. ;.....
  2391. ;
  2392. ;-----------------------------------------------------------------------
  2393. ;          VLIST subroutines begin here
  2394. ;
  2395. ;Multiply contents of HL register by 13
  2396. ;
  2397. MULT13:    MOV    D,H
  2398.     MOV    E,L
  2399.     DAD    H
  2400.     DAD    D
  2401.     DAD    H
  2402.     DAD    H
  2403.     DAD    D
  2404.  
  2405.      IF    Z80DOS
  2406.     DAD    D        ; Actually by 15
  2407.     DAD    D        ;
  2408.      ENDIF    ;Z80DOS
  2409.  
  2410.     RET
  2411. ;.....
  2412. ;
  2413. ; Main VLIST subroutine to output a filename and column delimiter
  2414. ;
  2415. VENTRY:    STA    VSFRST
  2416.     CALL    PFILE1        ; Routine to print a filename
  2417.     RZ            ; If at end of line return with zero set
  2418.     CC    FENCE        ; Print column delimiter if more
  2419.     LHLD    JUMPER        ; Put the jumper back in DE
  2420.     XCHG
  2421.     ORI    1        ; Insure non zero return
  2422.     RET
  2423. ;.....
  2424. ;
  2425. PFILE1:
  2426.     PUSH    H
  2427.     PUSH    D
  2428.     XCHG
  2429.     LHLD    NEWPTR
  2430.     MOV    A,H
  2431.     CMP    D
  2432.     JNC    PFILE2
  2433.     MOV    A,L
  2434.     CMP    E
  2435.     POP    D
  2436.     POP    H
  2437.     RZ
  2438.     JNC    PFILE3
  2439.     XRA    A
  2440.     RET
  2441. PFILE2:    POP    D
  2442.     POP    H
  2443. PFILE3:
  2444.     MOV    A,M        ; Let's see what we have
  2445.     CPI    0FEH
  2446.     RNC
  2447.     ANI    7FH        ; Strip parity bit
  2448.     PUSH    B        ; Save number of columns
  2449.     MVI    B,8        ; Print filename and type
  2450.     CALL    PUTSB
  2451.     MVI    A,'.'
  2452.     CALL    PUTCHR
  2453.     MVI    B,3
  2454.     CALL    PUTSB
  2455.     
  2456.      IF    Z80DOS
  2457.     LDA    NODFLG
  2458.     ORA    A
  2459.     JZ    NOD3
  2460.     CALL    DISDAT        ; Display the date
  2461. NOD3:
  2462.      ENDIF        ;Z80DOS
  2463.  
  2464.     MOV    D,M        ; Get it into DE
  2465.     INX    H
  2466.     MOV    E,M
  2467.     XCHG            ; HL <-> DE
  2468.     CALL    DECPRT        ; Print it out
  2469.     LDA    FSIZEC        ; Follow with 'k' or 'r'
  2470.     CALL    PUTCHR
  2471.     POP    B        ; Load number of columns
  2472.     LHLD    TOTFIL        ; Load number of files left
  2473.     DCX    H        ; # files-1
  2474.     SHLD    TOTFIL        ; Resave it
  2475.     MOV    A,H
  2476.     ORA    L        ; Zero yet?
  2477.     RZ            ; Yes, no more files
  2478.     DCR    C        ; No, decrement it
  2479.     STC            ; Force carry on
  2480.     RET            ; This return
  2481. ;.....
  2482. ;
  2483. ;              End of VLIST routines
  2484. ;-----------------------------------------------------------------------
  2485. ;
  2486. ; Show total space and files used
  2487. ;
  2488. PRTOTL:    
  2489.     XRA    A
  2490.     STA    VSFRST
  2491.     LDA    VFLAG        ; Check display form
  2492.     ORA    A
  2493.     JZ    PRTOT1        ; Jump if vertical
  2494.     LDA    LOPFLG
  2495.     ORA    A
  2496.     JNZ    PRTOT1
  2497.     LHLD    TOTFIL        ; How many files matched?
  2498.     MOV    A,H
  2499.     ORA    L
  2500.     CNZ    PRTLMEM        ; Skip .LBR check if none found
  2501.  
  2502. PRTOT1:    XRA    A        ; Get a zero to
  2503.     STA    SUPSPC        ; Suppress leading spaces in totals
  2504.     LHLD    TOTFIL        ; How many files matched?
  2505.     MOV    A,H
  2506.     ORA    L
  2507.     JZ    NXTUSR        ; Skip summary if none found
  2508.     PUSH    H        ; Save TOTFIL
  2509.     STA    FNDFLG        ; Set file found flag
  2510.     LDA    VFLAG        ; Check display form
  2511.     ORA    A
  2512.     JNZ    PRTOT3        ; Horizontal = 0FFh, exit if not zero
  2513.     LDA    SOHFLG
  2514.     ORA    A
  2515.     JZ    PRTOT2
  2516.     XRA    A
  2517.     STA    SOHFLG
  2518.     JMP    PRTOT3
  2519.  
  2520. PRTOT2:    CALL    CRLF
  2521.  
  2522. PRTOT3:    LXI    D,TOTMS1    ; Print "13,10,' Drive'"
  2523.     CALL    PUTS
  2524.     LDA    FCB
  2525.     ADI    'A'-1
  2526.     CALL    PUTCHR        ; Output the drive code
  2527.     CALL    CKVER
  2528.     JC    NOUSER
  2529.     CALL    PUTUSR        ; Output user number
  2530.  
  2531.      IF    NDIRS
  2532.     MVI    A,' '
  2533.     CALL    PUTCHR
  2534.     CALL    NAMDIR
  2535.      ENDIF            ; NDIRS
  2536.  
  2537.     LDA    USRNR
  2538.     CPI    10
  2539.     LXI    D,NOFMS2
  2540.     JC    $+6
  2541.     LXI    D,NOFMS2+1    ; Print some spaces
  2542.     CALL    PUTS
  2543.  
  2544.      IF    BYEULI
  2545.     LDA    BYEACT        ; BYE active?
  2546.     ORA    A
  2547.     JZ    NOUSER        ; Yes, skip ulcode
  2548.      ENDIF        ; BYEULI
  2549.  
  2550.      IF    ULINE
  2551.     LXI    D,ULON        ; Turn on underline
  2552.     CALL    COUTS        ; If not null
  2553.      ENDIF            ; ULINE
  2554.  
  2555. NOUSER:    LXI    D,TOTMS6    ; Print " Files: "
  2556.     CALL    PUTS
  2557.     POP    H        ; Recall TOTFIL
  2558.     XCHG
  2559.     LHLD    TOTFL1        ; Get total number of files so far        
  2560.     DAD    D        ; Add in number this DU
  2561.     SHLD    TOTFL1        ; And save it away
  2562.     XCHG
  2563.     CALL    DECPRT        ; Print # of files matched
  2564.     LXI    D,TOTMS4    ; No CRLF needed, display > 40
  2565.     CALL    PUTS
  2566.     LHLD    TOTSIZ        ; Total k used by matched files
  2567.     XCHG
  2568.     LHLD    TOTSZ1        ; Get running total of all files
  2569.     DAD    D
  2570.     SHLD    TOTSZ1        ; And put it back
  2571.     XCHG
  2572.     CALL    DECPRT        ; Print file size
  2573.     LXI    D,TOTMS5    ; Print "k"
  2574.     CALL    PUTS
  2575.     CALL    PRTFRE        ; Print free space remaining
  2576.  
  2577.      IF    ULINE AND BYEULI
  2578.     LDA    BYEACT        ; Bye active?
  2579.     ORA    A        ;
  2580.     JZ    NPRNT        ; Yes, skip ULINE off
  2581.      ENDIF        ; ULINE AND BYEULI
  2582.  
  2583.      IF    ULINE
  2584.     LXI    D,ULOFF        ; Turn off underline
  2585.     CALL    COUTS        ; If not null
  2586.      ENDIF            ; ULINE
  2587. ;
  2588. ; Summary line printed, now print detail files, first compute total
  2589. ; printout lines.
  2590. ;
  2591. NPRNT:    LDA    VFLAG        ; Check display form
  2592.     ORA    A
  2593.     JNZ    NXTUSR        ; Jump if horizontal
  2594.  
  2595.      IF    Z80DOS
  2596.     LXI    B,1
  2597.     LDA    NODFLG
  2598.     ORA    A
  2599.     JNZ    NOD4
  2600.     LXI    B,3
  2601. NOD4:
  2602.      ENDIF        ;Z80DOS
  2603.  
  2604.      IF    NOT Z80DOS
  2605.     LXI    B,3
  2606.      ENDIF        ;NOT Z80DOS
  2607.  
  2608.     MOV    A,C        ; Get number of names per line
  2609.     CMA            ; Negative of number of columns
  2610.     MOV    E,A        ; Into DE
  2611.     MVI    D,0FFH
  2612.     LHLD    TOTFIL        ; Load total number of files
  2613.     DAD    B        ; Round up to a full line
  2614.     MVI    C,0FFH
  2615.  
  2616. NPRNT1:    INR    C        ; C-reg will hold number of
  2617.     DAD    D        ; Lines to be displayed
  2618.     JC    NPRNT1
  2619.     MOV    A,C
  2620.     STA    LINES        ; Done, save it for later
  2621.     STA    SUPSPC        ; Allow spaces preceding file sizes
  2622. ;
  2623. ; Number lines times entry size = the number of bytes to skip in the
  2624. ; second table when outputting files in vertical order.
  2625. ;
  2626.      IF    VSPAGE
  2627.     LDA    FOPFLG        ; Check File output
  2628.     ORA    A
  2629.     JZ    NVSORT
  2630.     LDA    POPFLG
  2631.     ORA    A
  2632.     JZ    NVSORT
  2633.     LDA    NOPFLG
  2634.     ORA    A
  2635.     JNZ    VSORT
  2636. NVSORT:    MOV    A,C
  2637.     JMP    OVSORT
  2638. VSORT:
  2639.     LDA    LINCNT        ; Get number of lines currently displayed
  2640.     MOV    B,A
  2641.     MVI    A,22        ; Calc number left
  2642.     SUB    B
  2643.     MOV    B,A
  2644.     MOV    A,C        ; Get how many lines this DU
  2645.     CMP    B
  2646.     JC    OVSORT        ; If C, then this DU will fit on the page whole
  2647.     MOV    A,B        ; This DU won't fit, so calc to fill up page
  2648.     ORA    A
  2649.     JNZ    OVSORT
  2650.     MOV    A,C
  2651.     CPI    23
  2652.     JC    OVSORT
  2653.     MVI    A,23
  2654. OVSORT:
  2655.      ENDIF        ; VSPAGE
  2656.  
  2657.     MOV    L,A        ; Put number of lines into HL
  2658.     MVI    H,0
  2659.     CALL    MULT13
  2660.     SHLD    JUMPER        ; Put it away
  2661.     XRA    A
  2662.     STA    WASHERE        ; Set flag for FENCE that says next calc
  2663.                 ; is for the next page of display
  2664. ;
  2665. ; Fill a record with FF at the end of table 2
  2666. ;
  2667.     LHLD    NEWPTR        ; Now points to end of table 2
  2668.     MVI    B,128
  2669.     MVI    A,0FFH
  2670.  
  2671. NPRNT2:    MOV    M,A
  2672.     INX    H
  2673.     DCR    B
  2674.     JNZ    NPRNT2
  2675. ;
  2676. ; Increment the number of files for use later in VENTRY.  This insures
  2677. ; that a column delimiter will be printed after the last filename, if
  2678. ; the file appears in other than the last column of the display.
  2679. ;
  2680.      IF    NOT Z80DOS
  2681.     LXI    H,TOTFIL
  2682.     INR    M
  2683.      ENDIF        ;NOT Z80DOS
  2684. ;
  2685. ; Print out a line of files
  2686. ;
  2687. NPRNT3:    
  2688.      IF    Z80DOS
  2689.     MVI    C,2
  2690.     LDA    NODFLG
  2691.     ORA    A
  2692.     JNZ    NOD5
  2693.     MVI    C,4
  2694. NOD5:
  2695.      ENDIF        ;Z80DOS
  2696.  
  2697.      IF    NOT Z80DOS
  2698.     MVI    C,4        ; Reset number of columns
  2699.      ENDIF        ;NOT Z80DOS
  2700.  
  2701.     CALL    CRLF        ; Start a new line
  2702.     MVI    A,1
  2703.     STA    VSFRST
  2704.  
  2705. ;
  2706. ; Print first filename
  2707. ;
  2708.     LHLD    XPOINT        ; XPOINT = to start of second table
  2709.     CALL    VENTRY        ; At entry. Below, it is incremented
  2710.                 ; For additional lines of printout
  2711.     JZ    NLINE        ; Either out of columns or out of files
  2712. ;
  2713. ; Print second filename
  2714. ;
  2715.     LHLD    XPOINT
  2716.     DAD    D
  2717.     CALL    VENTRY
  2718.     JZ    NLINE
  2719. ;
  2720. ; Print third filename
  2721. ;
  2722.     LHLD    XPOINT
  2723.     DAD    D
  2724.     DAD    D
  2725.     CALL    VENTRY
  2726.     JZ    NLINE
  2727. ;
  2728. ; Print fourth filename
  2729. ;
  2730.     LHLD    XPOINT
  2731.     DAD    D
  2732.     DAD    D
  2733.     DAD    D
  2734.     CALL    VENTRY
  2735.  
  2736. NLINE:    LHLD    XPOINT        ; Increment XPOINT to next file
  2737.  
  2738.      IF    Z80DOS
  2739.     LXI    D,15
  2740.      ENDIF        ;Z80DOS
  2741.  
  2742.      IF    NOT Z80DOS
  2743.     LXI    D,13
  2744.      ENDIF        ;NOT Z80DOS
  2745.  
  2746.     DAD    D
  2747.     SHLD    XPOINT
  2748.     LHLD    TOTFIL        ; Out of files?
  2749.     MOV    A,H
  2750.     ORA    L
  2751.     JZ    DOLIB        ; Yes, Check for libraries
  2752.     LXI    H,LINES        ; No, just need a new line
  2753.     DCR    M
  2754.     JNZ    NPRNT3
  2755.  
  2756. DOLIB:    LDA    LOPFLG
  2757.     ORA    A
  2758.     JNZ    NXTUSR
  2759.     LHLD    TOTFIL        ; How many files matched?
  2760.     MOV    A,H
  2761.     ORA    L
  2762.  
  2763.      IF    NOT Z80DOS
  2764.     CNZ    PRTLMEM        ; Skip library check if none found
  2765.      ENDIF
  2766.      IF    Z80DOS
  2767.     CALL    PRTLMEM
  2768.      ENDIF
  2769.  
  2770. ;
  2771. ; Directory for one user area completed.  If all users option is select-
  2772. ; ed, then go do another directory on the next user number until we ex-
  2773. ; ceed the maximum user # for the selected drive.
  2774. ;
  2775. NXTUSR:    LDA    AOPFLG        ; All user flag
  2776.     ORA    A        ; Set?
  2777.     JZ    NXTUSU        ; Set if zero, show all user areas
  2778.     LDA    HOPFLG        ; "H" flag to show remaining areas
  2779.     ORA    A
  2780.     JNZ    GOCLZ        ; Non-zero, not set, exit
  2781.  
  2782. NXTUSU:    CALL    CKVER        ; Running CP/M 2?
  2783.     JC    GOCLZ        ; No, Skip user increment
  2784.     CALL    CKABRT        ; Yes, Check for user abort
  2785.     LDA    MAXUSR        ; No abort - get maximum user #
  2786.     LXI    H,NEWUSR    ; Increment directory user number
  2787.     INR    M
  2788.     CMP    M        ; Next user # exceed maximum?
  2789.     JNC    SETTBL        ; No, more user areas to go
  2790.     LDA    BASUSR        ; Reset base user number for
  2791.     MOV    M,A        ; The next directory search
  2792. ;
  2793. ; We've finished all of our outputting. Flush the remainder of the out-
  2794. ; put buffer and close the file before going to exit routine.
  2795. ;
  2796. GOCLZ:    LXI    H,OPNFLG    ; Get file open status, reset flag
  2797.     MOV    A,M        ; To force reopen on next pass
  2798.     MVI    M,0
  2799.     ORA    A        ; File open?
  2800.     JZ    NXTDSK        ; No, Skip closing DISK.DIR
  2801.     LXI    H,BUFCNT
  2802.     MOV    A,M        ; Load # of unflushed characters in
  2803.     MVI    M,128        ; Buffer, force BUFCNT to empty status
  2804.     ORA    A        ; If BUFCNT=128, buffer empty set sign
  2805.     JM    DDCLOS        ; Close DISK.DIR if buffer is empty
  2806.     JZ    FLUSH        ; Write last record to DISK.DIR if full
  2807.     LHLD    BUFPNT        ; Else pad unused buffer with CTL-Z
  2808.  
  2809. PUTAGN:    MVI    M,'Z'-40H    ; EOF marker
  2810.     INX    H        ; Next buffer location
  2811.     DCR    A        ; Count-1
  2812.     JNZ    PUTAGN        ; Continue buffer padding fill
  2813.  
  2814. FLUSH:    LXI    D,OUTFCB    ; Flush the last output buffer
  2815.     MVI    C,WRITE
  2816.     CALL    CPM
  2817.     ORA    A
  2818.     JNZ    WRTERR
  2819.  
  2820. DDCLOS:    LXI    D,OUTFCB    ; Close DISK.DIR output file
  2821.     MVI    C,CLOSE
  2822.     CALL    CPM
  2823. ;
  2824. ; Directory for all user areas finished.  If the multi-disk option is
  2825. ; enabled and selected, reset to the base user area and repeat the
  2826. ; directory for next drive on-line until we either exceed the drives in
  2827. ; our LODRV-HIDRV table, or the BDOS shuts us down with a select or bad
  2828. ; record error, which will be intercepted back to the EXIT module.
  2829. ;
  2830. NXTDSK:    LXI    H,FNDFLG    ; Load file found flag
  2831.     MOV    A,M
  2832.     MVI    M,0        ; Clear found flag for next drive
  2833.     ORA    A
  2834.     JNZ    NDSK        ; Continue if at least 1 file found
  2835.     LXI    H,FOPFLG
  2836.     DCR    M
  2837.     PUSH    H
  2838.     LXI    D,NOFMS1    ; Print 1st part of no files message
  2839.     CALL    PUTS        ; Print it
  2840.     LXI    D,NOFLM
  2841.     CALL    PUTS        ; Print message
  2842.     LDA    FCB
  2843.     ADI    'A'-1
  2844.     CALL    PUTCHR        ; Output the drive
  2845.     CALL    CKVER
  2846.     JC    NOUSR1
  2847.     CALL    PUTUSR        ; Output the user number
  2848.  
  2849. NOUSR1:    LXI    D,NOFMS3    ; Print divider
  2850.     CALL    PUTS
  2851.     CALL    PRTFRE        ; Tag with free message
  2852.     LDA    VFLAG        ; Check display form
  2853.     ORA    A
  2854.     CNZ    CRLF        ; Need another CRLF in horizontal mode
  2855.     POP    H
  2856.     INR    M
  2857.  
  2858. NDSK:    LDA    DOPFLG        ; Multi-disk selected?
  2859.     ORA    A
  2860.     JNZ    NPRT        ; No, skip next check
  2861.     CALL    CKABRT        ; Check for user abort
  2862.     MVI    A,HIDRV-LODRV    ; Load max drive code to search
  2863.     LXI    H,FCB        ; Increment directory FCB drive code
  2864.     INR    M
  2865.     CMP    M        ; Does next disk exceed maximum?
  2866.     JC    NPRT
  2867.  
  2868. ;     IF    MAXDRV
  2869.  
  2870.      IF    ZCPR3P AND MAXDRV
  2871.     PUSH    H
  2872.     LHLD    Z3DRVL        ; Point to ENV
  2873.     MOV    A,M        ; Get it
  2874.     POP    H
  2875.      ENDIF        ;ZCPR3P AND MAXDRV
  2876.  
  2877.      IF    NOT ZCPR3P AND MAXDRV
  2878.     LDA    MXDRV        ; Look at another value limit
  2879.     INR    A
  2880.      ENDIF        ;NOT ZCPR3P AND MAXDRV
  2881.  
  2882.      IF    MAXDRV AND NOT DRVVEC
  2883.     CMP    M        ; Is it lower?
  2884.     JC    NPRT        ; Bail out if too low
  2885.     JMP    NOOPT        ; Search next disk
  2886.      ENDIF            ; MAXDRV AND NOT DRVVEC
  2887.  
  2888.     JNC    NOOPT        ; Search next disk if maxdr not true
  2889. ;
  2890. ; If no printer, fall through to EXIT
  2891. ;
  2892. NPRT:    LDA    POPFLG
  2893.     ORA    A        ; Printer active?
  2894.     JNZ    EXIT        ; No, just exit
  2895.     MVI    C,LIST
  2896.     MVI    E,13        ; Print a CRLF
  2897.     CALL    CPM
  2898.     MVI    E,10        ; Line feed
  2899.     CALL    CPM
  2900.     JMP    EXIT        ; All done - exit to CCP
  2901. ;.....
  2902. ;
  2903. ; Output the user number of the directory in decimal
  2904. ;
  2905. PUTUSR:    LDA    NEWUSR
  2906.     CPI    10        ; User no. < 10?
  2907.     JC    DUX        ; Yes, skip 10's digit
  2908.     STA    USRNR
  2909.     PUSH    B        ; No, process 10's digit
  2910.     MVI    C,'0'-1
  2911.  
  2912. DUY:    INR    C        ; Get tens digit
  2913.     SUI    10
  2914.     JNC    DUY        ; Loop until we've gone too far
  2915.     ADI    10
  2916.     MOV    B,A        ; Save units digit
  2917.     MOV    A,C        ; Print tens digit
  2918.     CALL    PUTCHR
  2919.     MOV    A,B        ; Recall units digit
  2920.     POP    B
  2921.  
  2922. DUX:    ADI    '0'        ; Make it ASCII
  2923.     JMP    PUTCHR
  2924.  
  2925. ;.....
  2926. ;
  2927. ; Force new line on output and check for page pause
  2928. ;
  2929. CRLF:    MVI    A,13        ; Send CR
  2930.     CALL    PUTCHR
  2931.     MVI    A,10        ; Send LF
  2932.     JMP    PUTCHR
  2933. ;.....
  2934. ;
  2935. ; Separate the directory output on a line with a space,
  2936. ; the delimiter, followed by another space.
  2937. ;
  2938. FENCE:    CALL    SPACE
  2939.  
  2940.      IF    Z80DOS
  2941.     LDA    NODFLG
  2942.     ORA    A
  2943.     JZ    FENCE1
  2944.     CALL    SPACE
  2945.     CALL    SPACE
  2946. FENCE1:
  2947.      ENDIF        ;Z80DOS
  2948.  
  2949.     MVI    A,':'        ; Fence character
  2950.     CALL    PUTCHR        ; Print it, then a space character
  2951.  
  2952.      IF    Z80DOS
  2953.     LDA    NODFLG
  2954.     ORA    A
  2955.     JZ    NOD6
  2956.     CALL    SPACE
  2957.     CALL    SPACE
  2958. NOD6:
  2959.      ENDIF        ;Z80DOS
  2960.  
  2961. SPACE:    MVI    A,' '
  2962. ;
  2963. ; Output character in A to console, and optionally to printer
  2964. ; and/or the output file.  Detects user abort request.
  2965. ;
  2966. PUTCHR:    PUSH    B
  2967.     PUSH    D
  2968.     PUSH    H
  2969.     PUSH    PSW        ; Save the character to output
  2970.     CALL    HITYPE        ; Send it to console
  2971.     POP    PSW        ; Restore the output character
  2972.     ANI    7FH        ; Strip parity bit on character
  2973. ;
  2974. ; Test file output mode and skip to page pause test if not active
  2975. ;
  2976.     MOV    B,A        ; Save stripped character to B
  2977.     CPI    10        ; At end of line?
  2978.     CZ    CKABRT        ; Check for user abort request
  2979.     LDA    FOPFLG        ; Is file output active?
  2980.     ORA    A
  2981.     JNZ    NOWRIT        ; Go check for page pause if not
  2982. ;
  2983. ; File output mode active - make sure we have room in buffer to add
  2984. ; the next character. If buffer full, write out current record first
  2985. ; and then start a new record with current character.
  2986. ;
  2987.     LHLD    BUFPNT        ; Load current buffer pointer
  2988.     LDA    BUFCNT        ; Load buffer capacity remaining
  2989.     ORA    A        ; Buffer full?
  2990.     JNZ    PUTBUF        ; No, Continue
  2991.     CALL    SETFOP        ; Yes, Set the DMA address
  2992.     LXI    D,OUTFCB    ; Else, write current buffer out
  2993.     MVI    C,WRITE
  2994.     CALL    CPM        ; (call must save character in B)
  2995.     ORA    A        ; Error?
  2996.     JNZ    WRTERR        ; Yes, exit if disk full or R/O
  2997.     LXI    H,OUTBUF    ; Reset buffer pointer
  2998.     MVI    A,128        ; Reset buffer capacity
  2999.  
  3000. PUTBUF:    MOV    M,B        ; Move char to next buffer position
  3001.     INX    H        ; Bump buffer pointer
  3002.     SHLD    BUFPNT        ; And save it
  3003.     DCR    A        ; Buffer char count-1
  3004.     STA    BUFCNT        ; And save it
  3005.  
  3006. NOWRIT:    MOV    A,B        ; Recall stripped character
  3007.     ANI    7FH        ; Strip parity bit on character
  3008.     MOV    E,A        ; Setup list output call
  3009.     MVI    C,LIST
  3010.     LDA    POPFLG        ; Load printer flag
  3011.     ORA    A        ; Set?
  3012.     CZ    CPM        ; Yes, print character
  3013.     MOV    A,E        ; Recall character
  3014.     CPI    10        ; Do we have a line feed?
  3015.     JNZ    PUTRET        ; Exit if not
  3016.     LDA    NOPFLG        ; Page pause function disabled?
  3017.     ORA    A
  3018.     JZ    PUTRET        ; Yes, exit
  3019.     LDA    POPFLG        ; Load, printer flag
  3020.     ORA    A        ; Set?
  3021.     JZ    PUTRET        ; Yes, skip page pause
  3022.     LDA    FOPFLG        ; File output flag
  3023.     ORA    A        ; Set?
  3024.     JZ    PUTRET        ; Yes, skip page pause
  3025.  
  3026.     LDA    LINCNT        ; Load line count
  3027.     INR    A        ; Bump it
  3028.     STA    LINCNT
  3029.     MVI    L,23        ; Allows use of [more] to finish display
  3030.     CMP    L        ; End of the screen?
  3031.     JC    PUTRET
  3032.  
  3033.     LXI    D,EOSMSG    ; Else, display pause message
  3034.     MVI    C,PRINT        ; Without checking for line feeds
  3035.     CALL    BDOS
  3036.     CALL    GETCH        ; Wait for character
  3037.     CPI    'C'-40H        ; Abort on CTL-C
  3038.     JZ    EXIT1
  3039.     CPI    'K'-40H        ; Or CTL-K
  3040.     JZ    EXIT1
  3041.     CPI    'X'-40H        ; Or CTL-X
  3042.     JZ    EXIT1
  3043.     CPI    ' '        ; See if printing character
  3044.     JC    NOTEOS        ; Exit if not
  3045.  
  3046.      IF    NOT VSPAGE
  3047.     JZ    NOTEOS1        ; If a space, exit to different place
  3048.      ENDIF
  3049.  
  3050.     ANI    5FH        ; Change to upper-case
  3051.     CPI    'C'        ; Can abort with c, C
  3052.     JZ    EXIT1
  3053.     CPI    'K'        ; Can abort with k, K
  3054.     JZ    EXIT1
  3055.     CPI    'X'        ; Can abort with x, X
  3056.     JZ    EXIT1
  3057.  
  3058. NOTEOS:    XRA    A        ; Reset line count
  3059.     STA    WASHERE        ; Say are starting over
  3060.  
  3061. NOTEOS1:STA    LINCNT
  3062.     LXI    D,MORERA    ; Overwrite the [more] display
  3063.     MVI    C,PRINT
  3064.     CALL    BDOS
  3065.  
  3066.      IF    VSPAGE
  3067.     LDA    VSFRST
  3068.     ORA    A
  3069.     JZ    DLINES1
  3070.     LDA    WASHERE        ; Were we here before?
  3071.     ORA    A
  3072.     JZ    WEWERE        ; Z=no
  3073.     CPI    23        ; Yes, must be moving by space bar, see how
  3074.                 ; many times
  3075.     JNZ    DLINES        ; NZ=not a full page worth yet
  3076.     XRA    A        ; A full page, move JUMPER up
  3077.     STA    WASHERE
  3078. WEWERE:    LHLD    JUMPER        ; Get current jumper
  3079.     XCHG
  3080.     LHLD    XPOINT        ; Get current position in array
  3081.     DAD    D        ; Skip the right number of files
  3082.      ENDIF
  3083.      IF    Z80DOS AND VSPAGE
  3084.     LDA    NODFLG
  3085.     ORA    A
  3086.     JNZ    WEWERE1
  3087.     DAD    D
  3088.     DAD    D
  3089. WEWERE1:
  3090.      ENDIF        ; Z80DOS
  3091.  
  3092.      IF    NOT Z80DOS AND VSPAGE
  3093.     DAD    D
  3094.     DAD    D
  3095.      ENDIF        ; NOT Z80DOS
  3096.  
  3097.      IF    VSPAGE
  3098.     SHLD    XPOINT        ; New current poition in output array
  3099.     LXI    H,23        ; Calc new jumper, 23 lines/page
  3100.     LDA    LINES
  3101.     CPI    24
  3102.     JNC    MLINES
  3103.     MOV    L,A
  3104. MLINES:    CALL    MULT13
  3105.     SHLD    JUMPER
  3106. DLINES:
  3107.     LDA    WASHERE
  3108.     INR    A
  3109.     STA    WASHERE
  3110. DLINES1:
  3111.     MVI    A,1
  3112.     STA    VSFRST
  3113.      ENDIF        ; VSPAGE
  3114.  
  3115.     XRA    A        ; Reset the 'A' register
  3116. PUTRET:    POP    H        ; Exit from PUTCHR
  3117.     POP    D
  3118.     POP    B
  3119.     RET
  3120. ;.....
  3121. ;
  3122. ; Output character, with low-case or reverse-video highlighting if high
  3123. ; bit set and conditionals enabled.
  3124. ;
  3125. HITYPE:    DS    0
  3126.  
  3127.      IF    USELC OR REVID
  3128.     ORA    A        ; Check for attributes not set
  3129.     JP    CONOUT        ; No attribute..ignore this one
  3130.     ANI    7FH        ; Attribute set, delete now
  3131.      ENDIF            ; USELC OR REVID
  3132.  
  3133.      IF    NOT USELCW AND WHEEL
  3134.     MOV    E,A        ; Save the character for later
  3135.      ENDIF
  3136.  
  3137.      IF    ZCPR3P AND (NOT USELCW AND WHEEL)
  3138.     PUSH    H
  3139.     LHLD    Z3WHLL        ; Point to enviorment
  3140.     MOV    A,M        ; Get it
  3141.     POP    H
  3142.      ENDIF        ;ZCPR3P AND ( NOT USELCW AND WHEEL)
  3143.  
  3144.      IF    NOT ZCPR3P AND (NOT USELCW AND WHEEL)
  3145.     LDA    WHLOC        ; Get wheel byte
  3146.      ENDIF        ;NOT ZCPR3P AND (NOT USELCW AND WHEEL)
  3147.  
  3148.      IF    NOT USELCW AND WHEEL
  3149.     ORA    A        ; Don't use lower case or REVID
  3150.     MOV    A,E        ; Get back the character to display
  3151.     JZ    CONOUT
  3152.      ENDIF            ; NOT USELCW AND WHEEL
  3153.  
  3154.      IF    REVID
  3155.     PUSH    PSW        ; Save character
  3156.     LXI    D,RVON        ; Turn on reverse video
  3157.     CALL    COUTS        ; If not null
  3158.     POP    PSW        ; Restore character
  3159.      ENDIF            ; REVID
  3160.  
  3161.      IF    USELC
  3162.     CPI    'A'        ; Change only from A-Z
  3163.     JC    TYPEC
  3164.     CPI    'Z'+1
  3165.     JNC    TYPEC        ; Punctuation can change so leave it
  3166.     ORI    20H        ; If attribute, make lower case
  3167.      ENDIF            ; USELC
  3168.  
  3169.      IF    USELC OR REVID
  3170. TYPEC:    CALL    CONOUT        ; Send the processed character
  3171.      ENDIF            ; USELC OR REVID
  3172.  
  3173.      IF    REVID
  3174.     LXI    D,RVOFF        ; Turn off reverse video
  3175.     CALL    COUTS        ; If not null
  3176.      ENDIF            ; REVID
  3177.  
  3178.      IF    USELC OR REVID
  3179.     RET
  3180.      ENDIF            ; USELC OR REVID
  3181. ;.....
  3182. ;
  3183. ; Output character in A to console
  3184. ;
  3185. CONOUT:    MOV    E,A        ; Get character for BDOS entry
  3186.     MVI    C,WRCON
  3187.     JMP    BDOS        ; Console Output
  3188. ;.....
  3189. ;
  3190. ; Output (raw) null-terminated string at (DE) to console.
  3191. ;
  3192.  
  3193. COUTS:    LDAX    D        ; Get byte of string
  3194.     ORA    A        ; Null?
  3195.     RZ            ; Return if so
  3196.     PUSH    D
  3197.     CALL    CONOUT
  3198.     POP    D
  3199.     INX    D        ; Next byte
  3200.     JMP    COUTS
  3201. ;.....
  3202. ;
  3203. ; Output bytes at HL of length B to console/printer/file
  3204. ;
  3205. PUTSB:    MOV    A,M
  3206.     CALL    PUTCHR
  3207.     INX    H
  3208.     DCR    B
  3209.     JNZ    PUTSB
  3210.     RET
  3211. ;.....
  3212. ;
  3213. ; Output null-terminated string to console/printer/file
  3214. ;
  3215. PUTS:    LDAX    D        ; Load character from DE string
  3216.     ANI    7FH        ; Strip off parity
  3217.     ORA    A        ; Is a 0?
  3218.     RZ            ; Yes, Terminate
  3219.     CALL    PUTCHR        ; Display character
  3220.     INX    D        ; Next string position
  3221.     JMP    PUTS        ; Continue
  3222. ;.....
  3223. ;
  3224. ; Fetch character from console (without echo)
  3225. ;
  3226. GETCH:    LHLD    0000H+1        ; Warm Boot Address
  3227.     MVI    L,9        ; Direct Console
  3228.     CALL    GOHL        ; Get Character
  3229.     ANI    7FH        ; Strip off any parity
  3230.     RET
  3231. ;.....
  3232. ;
  3233. ; Check for a CTL-C or CTL-S entered from the keyboard.  Jump to EXIT if
  3234. ; CTL-C, pause on CTL-S.
  3235. ;
  3236. CKABRT:    PUSH    H
  3237.     PUSH    D
  3238.     PUSH    B
  3239.     MVI    C,CONST
  3240.     CALL    BDOS
  3241.     ORA    A
  3242.     JZ    CKAB3        ; No character, exit
  3243.     MVI    C,RDCON
  3244.     CALL    BDOS
  3245.     ANI    5FH
  3246.     CPI    'S'-40H
  3247.     JZ    CKAB0
  3248.     CPI    'S'
  3249.     JNZ    CKAB1
  3250.     CALL    CKAB4
  3251.  
  3252. CKAB0:    MVI    C,RDCON
  3253.     CALL    BDOS
  3254.     ANI    5FH
  3255.  
  3256. CKAB1:    CPI    'C'-40H        ; CTL-C?
  3257.     JZ    CKAB2        ; Yes, quit
  3258.     CPI    'K'-40H
  3259.     JZ    CKAB2
  3260.     CPI    'X'-40H
  3261.     JZ    CKAB2
  3262.     CPI    ' '        ; Any other CTL-character, abort
  3263.     JC    CKAB3
  3264.     CALL    CKAB4        ; Clear the character from screen
  3265.     CPI    'C'
  3266.     JZ    CKAB2
  3267.     CPI    'K'
  3268.     JZ    CKAB2
  3269.     CPI    'X'
  3270.     JNZ    CKAB3
  3271.  
  3272. CKAB2:    LXI    D,CKMS1
  3273.     CALL    PUTS
  3274.     POP    B
  3275.     POP    D
  3276.     POP    H
  3277.     JMP    EX0        ; All done
  3278.  
  3279. CKAB3:    POP    B
  3280.     POP    D
  3281.     POP    H
  3282.     RET
  3283.  
  3284. CKAB4:    PUSH    PSW
  3285.     LXI    D,CKMS2
  3286.     CALL    PUTS
  3287.     POP    PSW
  3288.     RET
  3289. ;.....
  3290. ;
  3291. ; Call here to call address in HL
  3292. ;
  3293. GOHL:    PCHL
  3294. ;
  3295. ; Enter BDOS, save all extended registers
  3296. ;
  3297. CPM:    PUSH    B        ; Save Registers
  3298.     PUSH    D
  3299.     PUSH    H
  3300.  
  3301.      IF    ZRDOS
  3302.     LDA    ZRDFLG        ; ZRDOS running?
  3303.     ORA    A
  3304.     JNZ    ZRD        ; ZRDOS error trap and DOSs call
  3305.      ENDIF            ; ZRDOS
  3306.  
  3307.     CALL    BDOS
  3308.     MOV    B,A        ; Save return code
  3309.     LDA    VERFLG        ; Is this 3.0?
  3310.     CPI    30H
  3311.     MOV    A,B
  3312.     JC    CPM20        ; No, exit normally
  3313.     CPI    0FFH        ; Yes, was return code FF?
  3314.     JNZ    CPM20        ; No, exit normally
  3315.     MOV    A,H        ; Yes, check for error code
  3316.     ORA    A
  3317.     JNZ    DSKERR        ; Exit if physical error
  3318.     MOV    A,B        ; Else, continue normally
  3319.  
  3320. CPM20:    POP    H
  3321.     POP    D
  3322.     POP    B
  3323.     RET
  3324. ;.....
  3325. ;
  3326. ; ZRDOS Error Trap and System Call exits to CPM20
  3327. ;
  3328.      IF    ZRDOS
  3329. ZRD:    CALL    SETTRAP        ; Set the warm boot trap
  3330.     CALL    BDOS        ; Do what we're told
  3331.     CALL    RESTRAP        ; Reset the trap
  3332.     JMP    CPM20        ; Error free exit
  3333. ;.....
  3334. ;
  3335. ; Set Warm Boot Trap in ZRDOS
  3336. ;
  3337. SETTRAP:PUSH    H
  3338.     PUSH    D
  3339.     PUSH    B
  3340.     MVI    C,SETWBT    ; Set warm boot trap to come here
  3341.     LXI    D,WBTRAP
  3342.     CALL    BDOS
  3343.     POP    B
  3344.     POP    D
  3345.     POP    H
  3346.     RET
  3347. ;.....
  3348. ;
  3349. ; WBTRAP is where the ZRDOS returns control on warm boot (error)
  3350. ;
  3351. WBTRAP:    LXI    H,DSKERR    ; Return here after trap reset
  3352.     PUSH    H        ; Save DSKERR on stack
  3353. ;
  3354. ; Reset Warm Boot Trap in ZRDOS
  3355. ;
  3356. RESTRAP:PUSH    H
  3357.     PUSH    D
  3358.     PUSH    B
  3359.     PUSH    PSW
  3360.     MVI    C,RESWBT    ; Reset warm boot trap
  3361.     CALL    BDOS
  3362.     POP    PSW
  3363.     POP    B
  3364.     POP    D
  3365.     POP    H
  3366.     RET
  3367.      ENDIF            ; ZRDOS
  3368. ;.....
  3369. ;
  3370. ; For file output mode, return to old user area and set DMA for the file
  3371. ; output buffer.
  3372. ;
  3373. SETFOP:    CALL    CKVER        ; Clear carry if CP/M 2 or later
  3374.     LDA    OLDUSR        ; Get user number at startup
  3375.     MOV    E,A
  3376.     MVI    C,STUSER
  3377.     CNC    CPM        ; Reset old user number if CP/M 2
  3378.     LXI    D,OUTBUF    ; Move DMA from search buffer into
  3379.     JMP    SET2        ; Output buffer
  3380.     RET
  3381. ;.....
  3382. ;
  3383. ; Move disk buffer DMA to default buffer for directory search operations
  3384. ; and BDOS media change routines (required for pre-CP/M 2 systems while
  3385. ; in file output mode with active buffer).
  3386. ;
  3387. SETSRC:    LXI    D,TBUF        ; Default DMA Address
  3388.  
  3389. SET2:    MVI    C,STDMA        ; Set DMA Address
  3390.     JMP    CPM
  3391. ;.....
  3392. ;
  3393. ; Print amount of free space remaining on selected drive
  3394. ;
  3395. PRTFRE:    LXI    D,TOTMS7    ; Print " Free: '
  3396.     CALL    PUTS
  3397.     LHLD    FREEBY
  3398.     CALL    DECPRT        ; Print k free
  3399.     LXI    D,TOTMS8    ; Print "k "
  3400.     CALL    PUTS
  3401.     LDA    VFLAG        ; Alphabetizing vertically?
  3402.     ORA    A
  3403.     RZ            ; If yes, finished
  3404.     JMP    CRLF        ; Else turn up an extra line
  3405. ;.....
  3406. ;
  3407. ; Show string on the console
  3408. ;
  3409. SHOW:    LDAX    D        ; Get character from DE string
  3410.     ANI    7FH        ; Strip off parity
  3411.     ORA    A        ; Is it a 0?
  3412.     RZ            ; Yes, terminate
  3413.     PUSH    B        ; Save registers
  3414.     PUSH    D
  3415.     PUSH    H
  3416.     CALL    CONOUT        ; Show character on console
  3417.     POP    H        ; Load registers
  3418.     POP    D
  3419.     POP    B
  3420.     INX    D        ; Next string position
  3421.     JMP    SHOW        ; Continue
  3422. ;.....
  3423. ;
  3424. ; Compare routine for last extent of file search
  3425. ;
  3426. COMPR:    PUSH    H        ; Save table address
  3427.     MOV    E,M        ; Load low order
  3428.     INX    H
  3429.     MOV    D,M        ; Load high order
  3430.     INX    H
  3431.     MOV    C,M
  3432.     INX    H
  3433.     MOV    B,M
  3434. ;
  3435. ; BC, DE now point to entries to be compared
  3436. ;
  3437.     XCHG
  3438.     MOV    E,A        ; Get count
  3439.  
  3440. CMPLP:    LDAX    B
  3441.     XRA    M        ; Copy bit 7 of M
  3442.     ANI    7FH        ; Into bit 7 of A
  3443.     XRA    M
  3444.     CMP    M        ; Then compare
  3445.     INX    H
  3446.     INX    B
  3447.     JNZ    NOTEQL        ; Quit on mismatch
  3448.     DCR    E        ; Or end of count
  3449.     JNZ    CMPLP
  3450. ;
  3451. NOTEQL:    POP    H
  3452.     RET            ; Condition code tells all
  3453. ;.....
  3454. ;
  3455. ; Swap entries in the order table
  3456. ;
  3457. SWAP:    LXI    B,ORDER-2    ; Table base
  3458.     DAD    H        ; *2
  3459.     DAD    B        ; + base
  3460.     XCHG
  3461.     DAD    H        ; *2
  3462.     DAD    B        ; + base
  3463.     MOV    C,M
  3464.     LDAX    D
  3465.     XCHG
  3466.     MOV    M,C
  3467.     STAX    D
  3468.     INX    H
  3469.     INX    D
  3470.     MOV    C,M
  3471.     LDAX    D
  3472.     XCHG
  3473.     MOV    M,C
  3474.     STAX    D
  3475.     RET
  3476. ;.....
  3477. ;
  3478. ; New compare routine for sorting
  3479. ;
  3480. ; Changed to perform full 8-bit test of file size words.  7-bit
  3481. ; test failed when one word was 80h larger than the other. <crw>
  3482. ;
  3483. COMPARE:LXI    B,ORDER-2
  3484.     DAD    H
  3485.     DAD    B
  3486.     XCHG
  3487.     DAD    H
  3488.     DAD    B
  3489.     XCHG
  3490.     MOV    C,M
  3491.     INX    H
  3492.     MOV    B,M
  3493.     XCHG
  3494.     MOV    E,C
  3495.     MOV    D,B
  3496.     MOV    C,M
  3497.     INX    H
  3498.     MOV    H,M
  3499.     MOV    L,C
  3500. ;    LD    B,13        ; Count for normal sort
  3501.     MVI    B,11
  3502.     LDA    TOPFLG        ; Check for sort by type
  3503.     ORA    A
  3504. ;    JP    NZ,CMPLPE    ; Jump if normal sort
  3505.     JZ    COMP1        ; Jump if sort by type
  3506.     CALL    CMPLPE
  3507.     RNZ
  3508.     JMP    COMP2        ; Names match, go test extents
  3509. COMP1:
  3510.     PUSH    H        ; Save name pointers for later
  3511.     PUSH    D
  3512.     LXI    B,8        ; Point to file types
  3513.     DAD    B
  3514.     XCHG
  3515.     DAD    B
  3516.     XCHG
  3517.     MVI    B,3        ; Count for type compare
  3518.     CALL    CMPLPE
  3519.     POP    D        ; Retrieve name pointers
  3520.     POP    H        ; 
  3521.     RNZ
  3522.     MVI    B,8        ; Count for name compare
  3523.     CALL    CMPLPE
  3524.     RNZ
  3525.     INX    D        ; Point to extent
  3526.     INX    D
  3527.     INX    D
  3528.     INX    H
  3529.     INX    H
  3530.     INX    H
  3531. COMP2:    MVI    B,2        ; Count for extent compare
  3532.  
  3533. COMPB8:    LDAX    D
  3534.     CMP    M        ; 8-bit compare <crw>
  3535.     INX    D
  3536.     INX    H
  3537.     RNZ
  3538.     DCR    B
  3539.     JNZ    COMPB8
  3540.     RET
  3541.  
  3542. CMPLPE:    LDAX    D        ; 
  3543.     XRA    M        ; Copy bit 7 of M
  3544.     ANI    7FH        ; Into bit 7 of A
  3545.     XRA    M        ; 
  3546.     CMP    M        ; Then compare
  3547.     INX    D
  3548.     INX    H
  3549.     RNZ
  3550.     DCR    B
  3551.     JNZ    CMPLPE
  3552.     RET
  3553.  
  3554. ;.....
  3555. ;
  3556. ; Error exit
  3557. ;
  3558. ERXIT:    MVI    A,0FFH        ; Error Flag
  3559.     STA    FOPFLG        ; Disable file output on error
  3560.     CALL    CRLF        ; Space down
  3561.     POP    D        ; Load message string pointer
  3562.     CALL    PUTS        ; Print message
  3563.     LXI    D,ERRMS1    ; " Error"
  3564.     CALL    PUTS        ; Print message
  3565.     CALL    CRLF        ; Space down
  3566. ;
  3567. ; Exit - all done, restore stack
  3568. ;
  3569. EXIT:    LDA    DOPFLG        ; Multi-disk selected?
  3570.     ORA    A
  3571.     JNZ    EX0        ; No, skip next
  3572.     CALL    CKABRT        ; Check for user abort
  3573.     MVI    A,HIDRV-LODRV    ; Maximum drive code to search
  3574.     LXI    H,FCB        ; Increment directory FCB drive code
  3575.     INR    M
  3576.     CMP    M        ; Does next disk exceed maximum?
  3577.     JC    EX0
  3578.  
  3579. ;     IF    MAXDRV
  3580.  
  3581.      IF    ZCPR3P AND MAXDRV
  3582.     PUSH    H
  3583.     LHLD    Z3DRVL        ; Point to ENV
  3584.     MOV    A,M        ; Get it
  3585.     POP    H
  3586.      ENDIF        ;ZCPR3P AND MAXDRV
  3587.  
  3588.      IF    NOT ZCPR3P AND MAXDRV
  3589.     LDA    MXDRV        ; Look at another value limit
  3590.     INR    A
  3591.      ENDIF        ;NOT ZCPR3P AND MAXDRV
  3592.  
  3593.      IF    MAXDRV AND NOT DRVVEC
  3594.     CMP    M        ; Is it lower?
  3595.     JC    EX0        ; Bail out if too low
  3596.     JMP    NOOPT        ; Search next disk
  3597.      ENDIF            ; MAXDRV AND NOT DRVVEC
  3598.  
  3599.     JNC    NOOPT        ; Search next disk if MAXDR not true
  3600.  
  3601. EX0:    LDA    VFLAG        ; Check display form
  3602.     ORA    A
  3603.     CZ    CRLF        ; Turn up a blank line at end if vertical
  3604.     MVI    C,CONST        ; Check console status
  3605.     CALL    CPM
  3606.     ORA    A        ; Character waiting?
  3607.     MVI    C,RDCON
  3608.     CNZ    CPM        ; Gobble up character
  3609.  
  3610.      IF    ZRDOS
  3611.     LDA    ZRDFLG        ; ZRDOS running?
  3612.     ORA    A
  3613.     JNZ    EXIT2        ; Yes
  3614.      ENDIF            ; ZRDOS
  3615.  
  3616.     LDA    VERFLG        ; Version flag
  3617.     CPI    30H        ; CP/M 3.0?
  3618.     JC    EXIT1        ; No
  3619.     MVI    C,2DH        ; Yes,
  3620.     MVI    E,0        ; Reset error mode to default
  3621.     CALL    CPM
  3622.     JMP    EXIT2        ; Quit
  3623.  
  3624. EXIT1:    LDA    DOPFLG        ; If they were swapped
  3625.     ORA    A
  3626.     CZ    SWAPEM
  3627.  
  3628. EXIT2    EQU    $
  3629.  
  3630.      IF    SHOPUB
  3631.     CALL    RSTPUB
  3632.      ENDIF            ; SHOPUB
  3633.  
  3634.     LDA    AOPFLG        ; Doing all users
  3635.     MOV    C,A
  3636.     LDA    DOPFLG        ; Or disk?
  3637.     ANA    C
  3638.     MOV    C,A
  3639.     LDA    HOPFLG        ; Or higher users?
  3640.     ANA    C
  3641.     JNZ    TOTDONE        ; If no, skip totals
  3642.     MVI    A,1        ; Force no file output
  3643.     STA    LINCNT
  3644.     STA    FOPFLG
  3645.     LXI    D,ALLTOT    ; First part of message
  3646.     CALL    PUTS
  3647.     LHLD    TOTFL1        ; Total files found
  3648.     CALL    DECPRT
  3649.     LXI    D,TOTMS4
  3650.     CALL    PUTS
  3651.     LHLD    TOTSZ1        ; Total 'k' found
  3652.     CALL    DECPRT
  3653.     LXI    D,TOTMS8
  3654.     CALL    PUTS
  3655.     LXI    D,TOTMS7
  3656.     CALL    PUTS
  3657.     LHLD    TOTFRE
  3658.     CALL    DECPRT
  3659.     LXI    D,ALLTO1
  3660.     CALL    PUTS
  3661. TOTDONE:
  3662.      IF    WMBOOT
  3663.     JMP    0000H
  3664.      ENDIF            ; WMBOOT
  3665.  
  3666.     LDA    OLDDSK        ; Restore original drive
  3667.     MOV    E,A
  3668.     MVI    C,14
  3669.     CALL    CPM
  3670.     LDA    OLDUSR        ; Restore original user area
  3671.     MOV    E,A
  3672.     MVI    C,32
  3673.     CALL    CPM
  3674.  
  3675. EXIT3:    LHLD    STACK        ; Get old stack pointer
  3676.     SPHL            ; Move back to old stack
  3677.     RET            ; And return to CCP
  3678. ;.....
  3679. ;
  3680. ; Restore Public areas if they were changed
  3681. ;
  3682.      IF    SHOPUB
  3683. RSTPUB:    LHLD    0109H
  3684.     MVI    D,0
  3685.     MVI    E,07EH
  3686.     DAD    D
  3687.     LDA    PUBDRV
  3688.     MOV    M,A
  3689.     INX    H
  3690.     LDA    PUBUSR
  3691.     MOV    M,A
  3692.     RET
  3693.      ENDIF            ; SHOPUB
  3694. ;.....
  3695. ;
  3696.      IF    NDIRS
  3697. NAMDIR:    MVI    A,0
  3698.     STA    CURDIR        ; Initial check count
  3699.  
  3700. NAMDR1:    LHLD    NAMADR        ; Named directory buffer address
  3701.  
  3702. NAMDR2:    LDA    FCB        ; Get current Drive
  3703.     CMP    M        ; Does NDR entry match current drive?
  3704.     JNZ    NXTDIR        ; No, check next
  3705.     LDA    NEWUSR        ; Get current user
  3706.     INX    H
  3707.     CMP    M        ; Does NDR entry match current user?
  3708.     JNZ    NXTDIR        ; No, check next
  3709.     MVI    A,'['        ; Frame the name in brackets
  3710.     CALL    PUTCHR
  3711.     MVI    C,8        ; Number of Characters in entry
  3712.  
  3713. DIRCHR:    INX    H        ; Match, Point to Directory Name
  3714.     MOV    A,M        ; Get Character
  3715.     CPI    20H        ; End of entry?
  3716.     JNZ    DIRCH1        ; No
  3717.  
  3718. DIRCH0:    PUSH    PSW
  3719.     MVI    A,']'        ; Print closing bracket
  3720.     CALL    PUTCHR
  3721.     POP    PSW
  3722.     JMP    DIRCH2
  3723.  
  3724. DIRCH1:    CALL    PUTCHR
  3725.     DCR    C
  3726.     JNZ    DIRCHR        ; Output Eight characters
  3727.     JMP    DIRCH0
  3728.     RET            ; Done
  3729. DIRCH2:    MOV    A,C
  3730.     ORA    A
  3731.     RZ
  3732.     MVI    A,20H        ; Fill with spaces for neatness sake
  3733.     CALL    PUTCHR
  3734.     DCR    C
  3735.     JNZ    DIRCH2
  3736.     RET
  3737.  
  3738. NXTDIR:    LDA    CURDIR
  3739.     ADI    1        ; Increment Directory pointer
  3740.     STA    CURDIR
  3741.     LXI    H,NUMDIR
  3742.     CMP    M        ; Exceeded Max Entry?
  3743.     JZ    NODIR        ; Yes, there is no entry for this DU
  3744.     LHLD    NAMADR        ; Get base NDR address
  3745.     MVI    D,0
  3746.     MVI    E,18        ; Increment to next entry
  3747.  
  3748. NXTD:    DAD    D
  3749.     DCR    A        ; Decrement count
  3750.     JNZ    NXTD        ; Until current Offset reached
  3751.     JMP    NAMDR2        ; And check the entry for a match
  3752. NODIR:    MVI    C,10        ; No match, output ten spaces
  3753.  
  3754. NODIR1:    MVI    A,20H
  3755.     CALL    PUTCHR
  3756.     DCR    C
  3757.     JNZ    NODIR1
  3758.     RET
  3759.      ENDIF            ; NDIRS
  3760. ;.....
  3761. ;
  3762. ; Trap BDOS select and sector error vectors to our own intercept routine
  3763. ; so we can catch a reference to an illegal drive.
  3764. ;
  3765. SWAPEM:    DS    0
  3766.  
  3767.      IF    ZRDOS
  3768.     LDA    ZRDFLG        ; See if ZRDOS running
  3769.     ORA    A
  3770.     RNZ            ; Yes, quit this
  3771.      ENDIF            ; ZRDOS
  3772.  
  3773.     LDA    VERFLG        ; Version flag
  3774.     CPI    30H        ; Error mode call available?
  3775.     JC    SWAP20        ; No, use BDOS error vectors
  3776.     MVI    C,2DH        ; Yes, use error mode call
  3777.     MVI    E,0FFH        ;
  3778.     CALL    CPM        ; Set "return code only" mode
  3779.     RET
  3780.  
  3781. SWAP20:    LHLD    BDOS+1        ; Load pointer to base of BDOS
  3782.     INX    H        ; Swap new pointer if running a
  3783.     MOV    E,M        ; Program below the CCP
  3784.     INX    H
  3785.     MOV    D,M
  3786.     XCHG            ; HL points to the proper vector
  3787.     MVI    L,9        ; Point to record error vector
  3788.     LXI    D,VECTBL    ; Exchange with our vector table
  3789.     MVI    A,4        ; 4 bytes to swap
  3790.  
  3791. SWAPLP:    MOV    B,M        ; Load byte from HL
  3792.     XCHG
  3793.     MOV    C,M        ; Load byte from DE
  3794.     MOV    M,B        ; Save byte from HL
  3795.     XCHG
  3796.     MOV    M,C        ; Save byte from DE
  3797.     INX    H        ; Increment exchange pointers
  3798.     INX    D
  3799.     DCR    A        ; Counter-1
  3800.     JNZ    SWAPLP        ; Continue swapping
  3801.     RET
  3802. ;.....
  3803. ;
  3804. ; Check CP/M version number. Return carry flag set if pre-CP/M 2.  If
  3805. ; CP/M 2 or later or MP/M (any version), return carry clear.
  3806. ;
  3807. CKVER:    LDA    VERFLG        ; Version Flag
  3808.     CPI    20H        ; CP/M 2.0?
  3809.     RET
  3810. ;.....
  3811. ;
  3812. ; Return point from intercepted BDOS select and bad record errors.
  3813. ;
  3814. DSKERR:    LXI    SP,STACK    ; Get out of BDOS' stack
  3815.     JMP    EXIT        ; And exit back to CCP
  3816. ;.....
  3817. ;
  3818. ;-----------------------------------------------------------------------
  3819. ;             Start of FNAME routine
  3820. ;
  3821. ; Main module
  3822. ;    on entry, DE points to FCB to be filled, HL points to first
  3823. ;        byte of target string, RFCB is 36 bytes long
  3824. ;    on exit, B=disk number (1 for A, etc.) and C=user number
  3825. ;        HL points to terminating character
  3826. ;        A=0 and Z set if error in disk or user numbers
  3827. ;        A=0FFH and NZ if ok
  3828. ;
  3829. MAXDISK    EQU    16        ; Maximum number of disks
  3830. MAXUSER    EQU    31        ; Maximum user number
  3831.  
  3832. FNAME:    PUSH    D        ; Save DE
  3833.     MVI    A,0FFH        ; Set default disk and user
  3834.     STA    DISKNO
  3835.     STA    USERNO
  3836.     MVI    B,36        ; Initialize FCB
  3837.     PUSH    D        ; Save pointer
  3838.     XRA    A        ; A=0
  3839.  
  3840. FNINI:    STAX    D        ; Store zero
  3841.     INX    D        ; Point to next
  3842.     DCR    B        ; Count down
  3843.     JNZ    FNINI
  3844.     POP    D        ; Get pointer back
  3845.     PUSH    H        ; Save pointer
  3846. ;
  3847. ; Scan for colon, comma, or space in string
  3848. ;
  3849. COLON:    MOV    A,M        ; Scan for colon or space
  3850.     INX    H        ; Point to next
  3851.     CPI    ':'        ; Colon found?
  3852.     JZ    COLON1
  3853.     CPI    ','        ; Comma found?
  3854.     JZ    GETF1
  3855.     CPI    ' '+1        ; Delimiter?
  3856.     JC    GETF1
  3857.     JMP    COLON        ; Continue if not EOL
  3858. ;
  3859. COLON1:    POP    H        ; Clear stack
  3860.     MOV    A,M        ; Save possible drive specification
  3861.     CALL    CAPS        ; Capitalize
  3862.     CPI    'A'        ; Digit if less than "A"
  3863.     JC    USERCK        ; Process user number
  3864.     SUI    'A'        ; Change from ASCII to binary
  3865.     CPI    MAXDISK        ; Within bounds?
  3866.     JC    SVDISK
  3867. ;
  3868. ERREXIT:XRA    A        ; Error indicator
  3869.     POP    D        ; Restore DE
  3870.     RET
  3871. ;.....
  3872. ;
  3873. ; Log in specified disk
  3874. ;
  3875. SVDISK:    INR    A        ; Adjust to 1 for "A"
  3876.     STA    DISKNO        ; Save flag
  3877.     INX    H        ; Point to next character
  3878. ;
  3879. ; Check for user
  3880. ;
  3881. USERCK:    MOV    A,M        ; Get possible user #
  3882.     CPI    ':'        ; No user number
  3883.     JZ    GETFILE
  3884.     CPI    '?'        ; All user numbers?
  3885.     JNZ    USERC1
  3886.     STA    USERNO        ; Set value
  3887.     INX    H        ; Point to after
  3888.     MOV    A,M        ; Must be colon
  3889.     CPI    ':'
  3890.     JZ    GETFILE
  3891.     JMP    ERREXIT        ; Fatal error if not colon after ?
  3892.  
  3893. USERC1:    XRA    A        ; Zero user number
  3894.     MOV    B,A        ; B = A for user number
  3895.  
  3896. USRLOOP:MOV    A,M        ; Get digit
  3897.     INX    H        ; Point to next
  3898.     CPI    ':'        ; Done?
  3899.     JZ    USRDN
  3900.     SUI    '0'        ; Convert to binary
  3901.     JC    ERREXIT        ; User number error?
  3902.     CPI    10
  3903.     JNC    ERREXIT
  3904.     MOV    C,A        ; Next digit in C
  3905.     MOV    A,B        ; Old number in A
  3906.     ADD    A        ; *2
  3907.     ADD    A        ; *4
  3908.     ADD    B        ; *5
  3909.     ADD    A        ; *10
  3910.     ADD    C        ; *10+new digit
  3911.     MOV    B,A        ; Result in B
  3912.     JMP    USRLOOP
  3913.  
  3914. USRDN:    MOV    A,B        ; Get newer user number
  3915.     CPI    MAXUSER+1    ; Within range?
  3916.     JNC    ERREXIT
  3917.     STA    USERNO        ; Save in flag
  3918.     JMP    GETFILE
  3919. ;
  3920. ; Extract file name
  3921. ;
  3922. GETF1:    POP    H        ; Get pointer to byte
  3923. ;
  3924. GETFILE:MOV    A,M        ; Pointing to colon?
  3925.     CPI    ':'
  3926.     JNZ    GFILE1
  3927.     INX    H        ; Skip over colon
  3928.  
  3929. GFILE1:    MOV    A,M        ; Get next character
  3930.     CPI    ','        ; Delimiter?
  3931.     JZ    GFQUES
  3932.     CPI    ' '+1        ; Not a delimiter?
  3933.     JNC    GFILE2
  3934.  
  3935. GFQUES:    INX    D        ; Fill with ???
  3936.     MVI    B,11        ; 11 bytes
  3937.     MVI    A,'?'
  3938.  
  3939. GFFILL:    STAX    D        ; Put?
  3940.     INX    D        ; Point to next
  3941.     DCR    B        ; Count down
  3942.     JNZ    GFFILL
  3943.  
  3944. FNDONE:    LDA    DISKNO        ; Get disk number
  3945.     MOV    B,A        ; In 'B'
  3946.     LDA    USERNO        ; Get user number
  3947.     MOV    C,A        ; In 'C'
  3948.     POP    D        ; Restore registers
  3949.     MVI    A,0FFH        ; No error
  3950.     ORA    A        ; Set flags
  3951.     RET
  3952. ;
  3953. ; Get file name fields
  3954. ;
  3955. GFILE2:    MVI    B,8        ; At most, 8 byte filename
  3956.     CALL    SCANF        ; Scan and fill
  3957.     MVI    B,3        ; At most, 3 byte filetype
  3958.     MOV    A,M        ; Get delimiter
  3959.     CPI    '.'        ; Filename ending in "."?
  3960.     JNZ    GFILE3
  3961.     INX    H        ; Point to character after "."
  3962.     CALL    SCANF        ; Scan and fill
  3963.     JMP    FNDONE        ; Done, return to "args"
  3964.  
  3965. GFILE3:    CALL    SCANF4        ; Fill with spaces
  3966.     JMP    FNDONE
  3967. ;
  3968. ; Scanner routine
  3969. ;
  3970. SCANF:    CALL    DELCK        ; Check for delimiter
  3971.     JZ    SCANF4        ; Fill with spaces if found
  3972.     INX    D        ; Next byte in filename
  3973.     CPI    '*'        ; Question mark fill ?
  3974.     JNZ    SCANF1
  3975.     MVI    A,'?'        ; Place "?"
  3976.     STAX    D
  3977.     JMP    SCANF2
  3978.  
  3979. SCANF1:    STAX    D        ; Place character
  3980.     INX    H        ; Next position
  3981.  
  3982. SCANF2:    DCR    B        ; Count down
  3983.     JNZ    SCANF        ; Continue loop
  3984.  
  3985. SCANF3:    CALL    DELCK        ; Skip to delimiter
  3986.     RZ
  3987.     INX    H        ; Point to next
  3988.     JMP    SCANF3
  3989.  
  3990. SCANF4:    INX    D        ; Next filename or filetype
  3991.     MVI    A,' '        ; Fill with spaces
  3992.     STAX    D
  3993.     DCR    B        ; Count down
  3994.     JNZ    SCANF4
  3995.     RET
  3996. ;.....
  3997. ;
  3998. ; Check character pointed to by HL for a delimiter,
  3999. ; return with Zero flag set if the character is a delimiter
  4000. ;
  4001. DELCK:    MOV    A,M        ; Get the character
  4002.     CALL    CAPS        ; Capitalize
  4003.     ORA    A        ; 0=delimiter
  4004.     RZ
  4005.     CPI    ' '+1        ; Space character+1
  4006.     JC    DELCK1        ; Space character or less
  4007.     CPI    '='
  4008.     RZ
  4009.     CPI    5FH        ; Underscore
  4010.     RZ
  4011.     CPI    '.'
  4012.     RZ
  4013.     CPI    ':'
  4014.     RZ
  4015.     CPI    ';'
  4016.     RZ
  4017.     CPI    ','
  4018.     RZ
  4019.     CPI    '<'
  4020.     RZ
  4021.     CPI    '>'
  4022.     RET
  4023. ;
  4024. DELCK1:    CMP    M        ; Compare with self for OK
  4025.     RET
  4026. ;.....
  4027. ;
  4028. CAPS:    CPI    'a'
  4029.     RC
  4030.     CPI    'z'+1
  4031.     RNC
  4032.     SUI    20H
  4033.     RET
  4034. ;.....
  4035. ;              End of FNAME routine
  4036. ;-----------------------------------------------------------------------
  4037. ;
  4038. ; Subroutines to read library file directory
  4039. ;
  4040. PRTLMEM:LXI    H,ORDER        ; Initialize order table pointer
  4041.     SHLD    NEXTL
  4042.     XRA    A
  4043.     STA    LNCNT
  4044.  
  4045. ENTRYL:    LHLD    LCOUNT        ; Get FCB count
  4046.     DCX    H        ; Decrement it
  4047.     SHLD    LCOUNT
  4048.     MOV    A,H        ; Is this the last file?
  4049.     ORA    L
  4050.     JZ    LBRTST        ; Yes, skip compare
  4051.     PUSH    B
  4052.     CALL    CKABRT        ; Keyboard abort?
  4053.     LHLD    NEXTL
  4054.     MVI    A,11
  4055.     CALL    COMPR        ; This entry match next one?
  4056.     POP    B
  4057.     JNZ    LBRTST        ; No, print it
  4058.     INX    H
  4059.     INX    H        ; Skip, highest extent last in list
  4060.     SHLD    NEXTL
  4061.     JMP    ENTRYL        ; Loop back for next lowest extent
  4062. ;.....
  4063. ;
  4064. ; Exit Library member printing
  4065. ;
  4066. LBEXIT:    LHLD    LMTOTL
  4067.     MOV    A,H
  4068.     ORA    L
  4069.     RZ
  4070.     PUSH    H        ; Save member count
  4071.     XRA    A        ; Get a zero to
  4072.     STA    SUPSPC        ; Suppress leading spaces in totals
  4073.  
  4074.      IF    Z80DOS
  4075.     MVI    L,2        ; If last line is full, don't turn
  4076.     LDA    NODFLG
  4077.     ORA    A
  4078.     JNZ    NOD7
  4079.     MVI    L,4
  4080. NOD7:
  4081.      ENDIF        ;Z80DOS
  4082.  
  4083.      IF    NOT Z80DOS
  4084.     MVI    L,4        ; If last line is full, don't turn
  4085.      ENDIF        ;NOT Z80DOS
  4086.  
  4087.     LDA    LNCNT
  4088.     CMP    L        ; Up extra line
  4089.     CNZ    CRLF        ; If partial line, extra line needed
  4090.     LXI    D,CONTM1    ; Print "There are "
  4091.     CALL    PUTS
  4092.     POP    H        ; Get total member count back
  4093.     CALL    DECPRT
  4094.     LXI    D,MFILES    ; Print "Members in "
  4095.     CALL    PUTS
  4096.     LHLD    LBTOTL
  4097.     CALL    DECPRT
  4098.     LXI    D,LIBR
  4099.     JMP    PUTS
  4100. ;
  4101. ; Valid entry obtained - spit it out
  4102. ;
  4103. LBRTST:    MVI    A,1        ; Turn off .ARC/ARK
  4104.     STA    ISARC
  4105.     LHLD    NEXTL        ; Load order table pointer
  4106.     MOV    E,M        ; Low order address
  4107.     INX    H
  4108.     MOV    D,M        ; High order address
  4109.     INX    H
  4110.     SHLD    NEXTL        ; Save updated table pointer
  4111.     LXI    H,8
  4112.     DAD    D
  4113.     CALL    CKLBR
  4114.     JZ    LBRSET
  4115.     CALL    CKARC
  4116.     JNZ    LBRNEX
  4117.     XRA    A
  4118.     STA    ISARC
  4119.  
  4120. LBRSET:    PUSH    D
  4121.  
  4122.      IF    Z80DOS
  4123.     LDA    NODFLG
  4124.     ORA    A
  4125.     JZ    ZARC0
  4126.     LDA    ISARC
  4127.     ORA    A
  4128.     JZ    ZARC0
  4129.     MVI    L,2        ; 2 NAMES PER LINE
  4130.     JMP    ZARC0A
  4131. ZARC0:    MVI    L,4        ; 4 NAMES PER LINE
  4132. ZARC0A:    LDA    LNCNT
  4133.      ENDIF        ;Z80DOS
  4134.  
  4135.      IF    NOT Z80DOS
  4136.     LDA    LNCNT
  4137.     MVI    L,4
  4138.      ENDIF        ;NOT Z80DOS
  4139.  
  4140.     CMP    L
  4141.     CNZ    CRLF
  4142.     PUSH    PSW        ; Just in case
  4143.     LXI    D,LFMSP1    ; Long Library directory message
  4144.     LDA    ISARC
  4145.     ORA    A
  4146.     JNZ    SARCM1
  4147.     LXI    D,AFMSP1
  4148.  
  4149. SARCM1:    CALL    PUTS        ; Print it
  4150.     POP    PSW        ; Put it back
  4151.     LDA    FCB        ; Load current drive
  4152.     ADI    'A'-1        ; Convert to ASCII
  4153.     CALL    PUTCHR        ; Print it
  4154.     CALL    PUTUSR        ; Print user # after it
  4155.     MVI    A,':'        ; And colon
  4156.     CALL    PUTCHR
  4157.     POP    H
  4158.     PUSH    H
  4159.     MVI    B,8        ; Filename length
  4160.     CALL    PUTSB
  4161.     MVI    A,'.'        ; Period after filename
  4162.     CALL    PUTCHR
  4163.     MVI    B,3        ; 3 characters of filetype
  4164.     CALL    PUTSB
  4165.  
  4166.      IF    Z80DOS
  4167.     LDA    NODFLG
  4168.     ORA    A
  4169.     JZ    NOD8
  4170.     CALL    DISDAT
  4171. NOD8:
  4172.      ENDIF        ;Z80DOS
  4173.  
  4174.     CALL    SIZEFL        ; Compute size of library in k
  4175.     XCHG
  4176.     CALL    DECPRT
  4177.     LXI    D,LFMSP3
  4178.     CALL    PUTS
  4179.     POP    H
  4180. ;
  4181. ; Saves the library file name into LBRFCB
  4182. ;
  4183.     LDA    FCB
  4184.     LXI    D,LBRFCB    ; To
  4185.     STAX    D
  4186.     INX    D
  4187.     MVI    B,11        ; Length
  4188.     CALL    MOVE        ; Do the move
  4189.     XCHG
  4190.     MVI    B,25
  4191.  
  4192. CLMFCB:    MVI    M,0
  4193.     INX    H
  4194.     DCR    B
  4195.     JNZ    CLMFCB
  4196.     CALL    SETLDMA
  4197.     LXI    D,LBRFCB    ; Point to file
  4198.     MVI    C,OPEN        ; Get function
  4199.     CALL    CPM        ; Open it
  4200.     MVI    C,READ
  4201.     LXI    D,LBRFCB
  4202.     CALL    CPM
  4203.     CALL    SETFOP
  4204.     LXI    H,LBBUF
  4205.     MOV    A,M
  4206.     ORA    A
  4207.     JZ    CKLDIR        ; Check directory present?
  4208.  
  4209.     LDA    ISARC
  4210.     ORA    A
  4211.     JNZ    BADLBR
  4212.     MOV    A,M
  4213.     CPI    ARCMAR
  4214.     JZ    CKADIR
  4215.  
  4216. BADLBR:    LXI    H,NLBRF
  4217.     LDA    ISARC
  4218.     ORA    A
  4219.     JNZ    NBARC
  4220.     LXI    H,NARCF
  4221.  
  4222. NBARC:    MVI    B,25
  4223.     CALL    PUTSB
  4224. ;
  4225. LMLEXI:    CALL    LBCLOS
  4226. ;
  4227. ; Do next library file
  4228. ;
  4229. LBRNEX:    LHLD    LCOUNT        ; Check count
  4230.     MOV    A,H
  4231.     ORA    L
  4232.     JZ    LBEXIT        ; No more, all done
  4233.     JMP    ENTRYL        ; Else, get next .LBR file
  4234. ;.....
  4235. ;
  4236. ; Close the library file
  4237. ;
  4238. LBCLOS:    LXI    D,LBRFCB
  4239.     MVI    C,CLOSE
  4240.     CALL    CPM
  4241.     RET
  4242. ;.....
  4243. ;
  4244. ; Set the Library file DMA address
  4245. ;
  4246. SETLDMA:CALL    CKVER        ; Set carry if pre-CP/M 2
  4247.     LDA    NEWUSR        ; Get user area for directory
  4248.     MOV    E,A
  4249.     MVI    C,STUSER    ; Get the user function
  4250.     CNC    CPM        ; And set new user number if CP/M 2
  4251.     LXI    D,LBBUF
  4252.     MVI    C,STDMA
  4253.     CALL    CPM
  4254.     RET
  4255. ;.....
  4256. ;
  4257. ; Check to see if there indeed is a LBR file directory
  4258. ;
  4259. CKLDIR:    MVI    B,11        ; Length of file name
  4260.     MVI    A,' '        ; Space
  4261.     INX    H
  4262.  
  4263. CKDLP:    CMP    M
  4264.     JNZ    BADLBR
  4265.     DCR    B
  4266.     INX    H
  4267.     JNZ    CKDLP
  4268. ;
  4269. ; The first entry in the LBR directory is indeed blank.  Now see if the
  4270. ; directory size is > 0
  4271. ;
  4272.     MOV    E,M        ; File starting location low
  4273.     INX    H        ; Must be zero here
  4274.     MOV    A,M        ; File starting location high
  4275.     ORA    E        ; Must be zero here also
  4276.     JNZ    BADLBR
  4277.     INX    H
  4278.     MOV    E,M        ; Get library size low
  4279.     INX    H        ; Point to library size high
  4280.     MOV    D,M        ; Get library size high
  4281.     MOV    A,D
  4282.     ORA    E        ; Library must have some size
  4283.     JZ    BADLBR
  4284.     DCX    D
  4285.     XCHG
  4286.     SHLD    SLFILE
  4287.     LHLD    LBTOTL
  4288.     INX    H
  4289.     SHLD    LBTOTL
  4290.  
  4291.      IF    Z80DOS
  4292.     LDA    ISARC
  4293.     ORA    A
  4294.     JZ    ZARC1
  4295.     LDA    NODFLG
  4296.     ORA    A
  4297.     JZ    ZARC1
  4298.     MVI    A,2
  4299.     JMP    ZARC1A
  4300. ZARC1:    MVI    A,4
  4301. ZARC1A:
  4302.      ENDIF        ;Z80DOS
  4303.  
  4304.      IF    NOT Z80DOS
  4305.     MVI    A,4
  4306.      ENDIF        ;NOT Z80DOS
  4307.  
  4308.     STA    LNCNT        ; Reset names per line counter
  4309.     MVI    B,3
  4310.     LXI    H,17
  4311.     DAD    D
  4312.     JMP    LMTEST
  4313.  
  4314. LFMLOP:    LHLD    SLFILE        ; Get next buffer if more
  4315.     MOV    A,L
  4316.     ORA    H
  4317.     JZ    LMLEXI
  4318.     DCX    H
  4319.     SHLD    SLFILE
  4320.     CALL    SETLDMA
  4321.     MVI    C,READ
  4322.     LXI    D,LBRFCB
  4323.     CALL    CPM
  4324.     CALL    SETFOP
  4325.     MVI    B,4        ; Get file count per record
  4326.     LXI    H,LBBUF        ; Get buffer starting address
  4327.  
  4328. LMTEST:    MOV    A,M        ; Get member open flag
  4329.     ORA    A        ; Test for open
  4330.     JZ    PRMNAM
  4331.  
  4332. LMTESA:    LDA    ISARC
  4333.     ORA    A
  4334.     RZ
  4335.     LXI    D,32        ; Member not open get offset
  4336.     DAD    D        ; To next and add it in
  4337.     DCR    B        ; Is buffer empty ?
  4338.     JNZ    LMTEST        ; No so test next entry
  4339.     JMP    LFMLOP        ; Yes, get next buffer
  4340. ;
  4341. PRMNAM:    PUSH    H        ; Print member name and size
  4342.     PUSH    B
  4343.     CALL    CKABRT        ; Keyboard abort?
  4344.     LXI    H,LNCNT
  4345.  
  4346.      IF    Z80DOS
  4347.     LDA    ISARC
  4348.     ORA    A
  4349.     JZ    ZARC2
  4350.     LDA    NODFLG
  4351.     ORA    A
  4352.     JZ    ZARC2
  4353.     MVI    A,2
  4354.     JMP    ZARC2A
  4355. ZARC2:    MVI    A,4
  4356. ZARC2A:
  4357.      ENDIF        ;Z80DOS
  4358.  
  4359.      IF    NOT Z80DOS
  4360.     MVI    A,4
  4361.      ENDIF        ;NOT Z80DOS
  4362.  
  4363.     CMP    M
  4364.     JNZ    PRMNA1
  4365.  
  4366.      IF    PRBRDR
  4367.     MVI    A,'*'        ; Load "A" with border character
  4368.     CALL    PUTCHR        ; Print it
  4369.     MVI    A,' '        ;
  4370.     CALL    PUTCHR        ; Space between border and text
  4371.      ENDIF            ; PRBRDR
  4372.  
  4373.     JMP    PRMNA2
  4374.  
  4375. PRMNA1:    CALL    SPACE
  4376.     MVI    A,':'
  4377.     CALL    PUTCHR
  4378.     CALL    SPACE
  4379.  
  4380. PRMNA2:    POP    B
  4381.     POP    H
  4382.     PUSH    H
  4383.     PUSH    B
  4384.     INX    H
  4385.     MVI    B,8        ; Filename length
  4386.     CALL    PUTSB
  4387.     MVI    A,'.'        ; Period after filename
  4388.     CALL    PUTCHR
  4389.     MVI    B,3        ; 3 characters of filetype
  4390.     CALL    PUTSB
  4391.     INX    H
  4392.     INX    H
  4393.  
  4394.      IF    Z80DOS
  4395.     PUSH    H        ; Save pointer
  4396.     LDA    ISARC
  4397.     ORA    A
  4398.     JZ    ZARC3
  4399.     LDA    NODFLG
  4400.     ORA    A
  4401.     JZ    ZARC3
  4402.     LXI    D,2
  4403.     DAD    D        ; Skip size field and point to CRC
  4404.                 ; DISDAT will point it to date field
  4405.     CALL    DISDAT        ; Show the date
  4406. ZARC3:    POP    H
  4407.      ENDIF    ;Z80DOS
  4408.  
  4409.     MOV    E,M
  4410.     INX    H
  4411.     MOV    D,M
  4412.     XCHG
  4413. ;
  4414. ; Output the size of the individual file
  4415. ;
  4416.     PUSH    D
  4417.     PUSH    H
  4418.     XCHG
  4419.     LHLD    LLENLOC
  4420.     XCHG
  4421.     DAD    D
  4422.     SHLD    LLENLOC
  4423.     POP    H
  4424. ;
  4425. ; New code added to convert lib members from records to 'k'.  Upon entry
  4426. ; member's size in records is in HL.
  4427. ;
  4428.     LDA    COPFLG        ; File sizes wanted in records?
  4429.     ORA    A
  4430.     JZ    PRMNA3        ; Jump if so
  4431.     LXI    D,7        ; Round up to nearest 1k
  4432.     DAD    D
  4433.     XCHG
  4434.     LXI    H,0
  4435.     MOV    A,E        ; Low byte of record count in A
  4436.     RRC
  4437.     RRC
  4438.     RRC
  4439.     ANI    1FH
  4440.     MOV    E,A        ; And put it back
  4441.     MOV    L,D        ; Get the high byte if any
  4442.     MVI    D,0        ; Clean out the old resting place
  4443.     DAD    H        ; Multiply it by 32 to convert to
  4444.     DAD    H        ; Number of k bytes
  4445.     DAD    H
  4446.     DAD    H
  4447.     DAD    H
  4448.     DAD    D        ; And add in the low byte
  4449.  
  4450. PRMNA3:    POP    D
  4451.     CALL    DECPRT        ; Go print it
  4452.     LDA    FSIZEC        ; Follow with 'k' or 'r'
  4453.     CALL    PUTCHR
  4454. ;
  4455. ; Update library member total and name counter
  4456. ;
  4457.     LHLD    LMTOTL
  4458.     INX    H
  4459.     SHLD    LMTOTL
  4460.     LDA    LNCNT
  4461.     DCR    A
  4462.     STA    LNCNT
  4463.     POP    B
  4464.     POP    H
  4465.     JNZ    LMTESA        ; And go output another file
  4466. ;
  4467. ; Current line full, start a new one
  4468. ;
  4469.      IF    Z80DOS
  4470.     LDA    ISARC
  4471.     ORA    A
  4472.     JZ    ZARC4
  4473.     LDA    NODFLG
  4474.     ORA    A
  4475.     JZ    ZARC4
  4476.     MVI    A,2
  4477.     JMP    ZARC4A
  4478. ZARC4:    MVI    A,4
  4479. ZARC4A:
  4480.      ENDIF        ;Z80DOS
  4481.  
  4482.      IF    NOT Z80DOS
  4483.     MVI    A,4
  4484.      ENDIF        ;NOT Z80DOS
  4485.  
  4486.     STA    LNCNT        ; Reset names per line counter
  4487.     CALL    CRLF        ; Space down to next line
  4488.     JMP    LMTESA
  4489. ;.....
  4490. ;
  4491. ; Move characters from "HL" to "DE" length in "B"
  4492. ;
  4493. MOVE:    MOV    A,M        ; Get a character
  4494.     STAX    D        ; Store it
  4495.     INX    H        ; To next "from"
  4496.     INX    D        ; To next "to"
  4497.     DCR    B        ; More?
  4498.     JNZ    MOVE        ; Yes, loop
  4499.     RET            ; No, return
  4500. ;.....
  4501. ;
  4502. ; Archive file subroutines
  4503. ;
  4504. CKADIR:    XRA    A
  4505.     DCR    A
  4506.     STA    GETABL        ; Say buffer is full (first read by lbr test)
  4507.     LHLD    LBTOTL        ; Bump library count total
  4508.     INX    H
  4509.     SHLD    LBTOTL
  4510.     MVI    A,4        ; LDA     MNPL
  4511.     STA    LNCNT        ; Reset names per line counter
  4512.  
  4513. ARCLP:    CALL    GET        ; Get the next character from buffer
  4514.     CPI    ARCMAR        ; Is it archive header marker?
  4515.     JNZ    BADLBR        ; And abort if not
  4516.     CALL    GET        ; Get header version
  4517.     ORA    A        ; If zero, that's logical end of file,
  4518.     JZ    LMLEXI        ; And we're done
  4519.     LXI    D,ANAME        ; Set to fill header buffer
  4520.     MVI    B,HDRSIZ    ; Setup normal header size less file name
  4521.     CPI    1        ; But test if version 1
  4522.     JNZ    GETHD1        ; Skip if not version 1
  4523.     LXI    B,HDRSIZ-4    ; Else, header is 4 bytes less
  4524.  
  4525. GETHD1:    CALL    GET        ; Get header byte
  4526.     STAX    D        ; Store in buffer
  4527.     INX    D
  4528.     DCR    B
  4529.     JNZ    GETHD1        ; Loop for all bytes
  4530.     LXI    H,ARCFIL    ; Prefill dummy arc FCB name with spaces
  4531.     MVI    B,11
  4532.  
  4533. FIXAN:    MVI    M,' '
  4534.     INX    H
  4535.     DCR    B
  4536.     JNZ    FIXAN
  4537.     MVI    B,5        ; Prefill rest of dummy FCB with zero
  4538.  
  4539. FIXAE:    MVI    M,0
  4540.     INX    H
  4541.     DCR    B
  4542.     JNZ    FIXAE
  4543.     LXI    H,ANAME        ; Get pointer to archive header buffer
  4544.     LXI    D,ARCFIL    ; Point to our dummy FCB
  4545.     MVI    B,8        ; Get name length
  4546.  
  4547. MANAME:    MOV    A,M        ; Get character from header
  4548.     INX    H
  4549.     ORA    A
  4550.     JZ    AEDONE        ; Nothing in buffer so we're done
  4551.     CPI    02EH        ; Is the char a point
  4552.     JZ    DAEXT        ; DO FILE EXTENT
  4553.     STAX    D
  4554.     INX    D
  4555.     DCR    B
  4556.     JNZ    MANAME
  4557.  
  4558. DAEXT:    LXI    D,ARCFIL+8    ; Get dummy file extent address
  4559.     MVI    B,3
  4560.     MOV    A,M
  4561.     CPI    2EH
  4562.     JNZ    AELOP
  4563.     INX    H
  4564.  
  4565. AELOP:    MOV    A,M        ; Fill in the file extent
  4566.     ORA    A
  4567.     JZ    AEDONE
  4568.     STAX    D
  4569.     INX    H
  4570.     INX    D
  4571.     DCR    B
  4572.     JNZ    AELOP
  4573.  
  4574. AEDONE:    LXI    H,ASIZE
  4575.     MOV    E,M        ; Fetch BCDE from (HL)
  4576.     INX    H
  4577.     MOV    D,M
  4578.     INX    H
  4579.     MOV    C,M
  4580.     XRA    A        ; Clear flags
  4581.     MOV    A,E        ; Convert file length count in bytes
  4582.     RAL            ; To length in records for output
  4583.     MOV    A,D
  4584.     RAL
  4585.     MOV    E,A
  4586.     MOV    A,C
  4587.     RAL
  4588.     MOV    D,A
  4589.     XCHG
  4590.     SHLD    ARCFIL+13    ; Save file length
  4591.     LXI    H,ARCFIL-1    ; Point to dummy FCB
  4592.     CALL    PRMNAM        ; List the file info
  4593.     LXI    H,ASIZE        ; Get remaining file size
  4594.     MOV    A,M
  4595.     ANI    7FH
  4596.     LHLD    ARCFIL+13    ; Save file length
  4597.     XCHG            ; Save record offset
  4598.     LXI    H,GETABL    ; Point to offset of last byte read
  4599.     ADD    M        ; Add byte offsets
  4600.     CPI    80H        ; Does it overflow current record?
  4601.     JC    NRAD
  4602.     SUI    80H        ; Adjust pointer
  4603.     INX    D        ; Bump record number
  4604.  
  4605. NRAD:    MOV    M,A        ; Update buffer pointer for new position
  4606.     MOV    A,D        ; Check record offset
  4607.     ORA    E
  4608.     JZ    LEXIT        ; Return if none (still in same record)
  4609.     PUSH    D        ; Save record offset
  4610.     LXI    D,LBRFCB
  4611.     MVI    C,RECORD    ; Compute current "random" record no.
  4612.     CALL    CPM        ; (I.e. next sequential record to read)
  4613.     LHLD    LBRFCB+FRN    ; Get result
  4614.     DCX    H        ; Adjust next record to current record
  4615.     POP    D        ; Restore record offset
  4616.     DAD    D        ; Compute new record no.
  4617.     JC    BADLBR        ; If >64k, it's past largest (8 Mb) file
  4618.     SHLD    LBRFCB+FRN    ; Save new record no.
  4619.     MVI    C,READRN    ; Read the random record
  4620.     CALL    GETREC
  4621.     ORA    A
  4622.     JNZ    BADLBR        ; File read error
  4623.     LXI    H,LBRFCB+FCR    ; Point to current record in extent
  4624.     INR    M        ; Bump for subsequent sequential read
  4625.  
  4626. LEXIT:    JMP    ARCLP        ; Loop for next file
  4627. ;.....
  4628. ;
  4629. ; Get next sequential byte from archive file
  4630. ;
  4631. GET:    PUSH    B        ; Save registers
  4632.     PUSH    D
  4633.     PUSH    H
  4634.     LDA    GETABL        ; Point to last byte read
  4635.     INR    A        ; At end of buffer?
  4636.     CPI    80H
  4637.     CNC    GETNXT        ; Yes, read next record and reset pointer
  4638.     STA    GETABL        ; Save new buffer pointer
  4639.     MOV    L,A
  4640.     MVI    H,0
  4641.     LXI    D,LBBUF
  4642.     DAD    D
  4643.     MOV    A,M        ; Fetch byte from there
  4644.     POP    H        ; Restore registers
  4645.     POP    D
  4646.     POP    B
  4647.     RET            ; Return
  4648. ;
  4649. ; Get next sequential record from archive file
  4650. ;
  4651. GETNXT:    MVI    C,READ        ; Setup read-sequential function code
  4652.     CALL    GETREC
  4653.     ORA    A
  4654.     JNZ    RDERR
  4655.     PUSH    PSW
  4656.     XRA    A
  4657.     DCR    A
  4658.     STA    GETABL
  4659.     POP    PSW
  4660.     RET
  4661. ;
  4662. RDERR:    POP    H        ; Strip GETNXT return
  4663.     POP    H        ; Clean up the get stack
  4664.     POP    D
  4665.     POP    B
  4666.     POP    H        ; Strip get calling address
  4667.     JMP    BADLBR        ; Show error
  4668. ;
  4669. ; Get record (sequential or random) from archive file
  4670. ;
  4671. GETREC:    PUSH    H
  4672.     PUSH    B
  4673.     CALL    SETLDMA        ; Set library DMA address
  4674.     LXI    D,LBRFCB    ; Setup FCB address
  4675.     POP    B        ; Restore read function
  4676.     CALL    CPM        ; Do it
  4677.     PUSH    PSW        ; Save read status
  4678.     CALL    SETFOP        ; Reset Print file DMA address
  4679.     POP    PSW        ; Restore read status
  4680.     POP    H        ; Restore buffer pointer
  4681.     RET
  4682. ;.....
  4683. ;
  4684. ; Test file extent for ARC/ARK
  4685. ;
  4686. CKARC:    PUSH    H
  4687.     PUSH    D
  4688.     PUSH    B
  4689.     XCHG
  4690.     LXI    H,ARCTYP
  4691.     MVI    C,2        ; Number for the loop to test
  4692. ;
  4693. CKARL:    LDAX    D
  4694.     ANI    7FH
  4695.     CMP    M
  4696.     JNZ    CKARX
  4697.     INX    H
  4698.     INX    D
  4699.     DCR    C
  4700.     JNZ    CKARL
  4701. ;
  4702. ; The first 2 match now see if C or K for .ARC or .ARK
  4703. ;
  4704.     LDAX    D
  4705.     ANI    7FH
  4706.     CPI    'C'        ; See if "C"
  4707.     JZ    CKARX
  4708.     CPI    'K'        ; See if "K"
  4709.  
  4710. CKARX:    POP    B
  4711.     POP    D
  4712.     POP    H
  4713.     RET
  4714. ;.....
  4715. ;
  4716. ; Test file extent for LBR
  4717. ;
  4718. CKLBR:    PUSH    H
  4719.     PUSH    D
  4720.     PUSH    B
  4721.     XCHG
  4722.     LXI    H,LBRTYP
  4723.     MVI    C,3
  4724.  
  4725. CKLBL:    LDAX    D
  4726.     ANI    7FH
  4727.     CMP    M
  4728.     JNZ    CKLBX
  4729.     INX    H
  4730.     INX    D
  4731.     DCR    C
  4732.     JNZ    CKLBL
  4733.  
  4734. CKLBX:    POP    B
  4735.     POP    D
  4736.     POP    H
  4737.     RET
  4738. ;
  4739. ; TIMEON routine
  4740. ;
  4741. ; Go through a search to see if BYE is active
  4742. ;
  4743.      IF    TIMEON
  4744. TIME:    LHLD    0001H        ; Point to warm boot again
  4745.     DCX    H        ; If BYE active,
  4746.     MOV    D,M        ; Pick up pointer to BYE variables
  4747.     DCX    H        ; (COVECT) followed by "BYE"
  4748.     MOV    E,M
  4749.     LXI    H,15        ; Calculate address of BYE variable
  4750.     DAD    D        ; Where ptr to orig BIOS vector stored
  4751.     MOV    E,M        ; Load that address into DE
  4752.     INX    H        ; If BIOS active, DE now points to
  4753.     MOV    D,M        ; Original BIOS console output vector
  4754.     INX    H        ; Point to BYE signon message
  4755.     MOV    A,M        ; Get letter
  4756.     ANI    05FH        ; Convert to upper case if needed
  4757.     CPI    'B'        ; Try to match "BYE"
  4758.     RNZ            ; Out if BYE not active
  4759.     INX    H
  4760.     MOV    A,M
  4761.     ANI    05FH        ; Convert to u-case if needed
  4762.     CPI    'Y'
  4763.     RNZ
  4764.     INX    H
  4765.     MOV    A,M
  4766.     ANI    05FH        ; Convert to u-case if needed
  4767.     CPI    'E'
  4768.     RNZ
  4769.  
  4770.     LXI    D,6        ; Bye running, point to RTCBUF
  4771.     DAD    D
  4772.     MOV    E,M        ; Get RTCBUF address
  4773.     INX    H        ; And copy
  4774.     MOV    D,M        ; In DE
  4775.     XCHG            ; Put in HL
  4776.     LXI    D,7        ; Offset to
  4777.     DAD    D        ; Time-on-system byte
  4778.     MOV    A,M        ; Load TOS byte
  4779.     LXI    H,TONMS1    ; Where to store in ASCII
  4780.     CALL    DEC8        ; Convert binary to ASCII
  4781.     LXI    D,TONMSG
  4782.     CALL    PUTS        ; Print the message
  4783.     RET            ; And return
  4784. ;.....
  4785. ;
  4786. ; DEC8 will convert an 8 bit binary number in A to 3 ASCII
  4787. ; bytes. HL points to the MSB location where the ASCII bytes
  4788. ; will be stored. Leading zeros are suppressed, store spaces
  4789. ; in your buffer before calling.
  4790. ;
  4791. DEC8:    PUSH    B
  4792.     PUSH    D
  4793.     MVI    E,0        ; Leading zero flag
  4794.     MVI    D,100
  4795.  
  4796. DEC81:    MVI    C,'0'-1
  4797.  
  4798. DEC82:    INR    C
  4799.     SUB    D        ; 100 or 10
  4800.     JNC    DEC82        ; Still +
  4801.     ADD    D        ; Now add it back
  4802.     MOV    B,A        ; Remainder
  4803.     MOV    A,C        ; Get 100/10
  4804.     CPI    '1'        ; Zero?
  4805.     JNC    DEC83        ; Yes
  4806.     MOV    A,E        ; Check flag
  4807.     ORA    A        ; Reset?
  4808.     MOV    A,C        ; Restore byte
  4809.     JZ    DEC84        ; Leading zeros are skipped
  4810.  
  4811. DEC83:    MOV    M,A        ; Store in buffer
  4812.     INX    H        ; Increment storage location
  4813.     MVI    E,0FFH        ; Set zero flag
  4814.  
  4815. DEC84:    MOV    A,D
  4816.     SUI    90        ; 100 to 10
  4817.     MOV    D,A
  4818.     MOV    A,B        ; Remainder
  4819.     JNC    DEC81        ; Do it again
  4820.     ADI    '0'        ; Make ASCII
  4821.     MOV    M,A        ; And store it
  4822.     POP    D
  4823.     POP    B
  4824.     RET
  4825.  
  4826. TONMSG:    DB    13,10,'Minutes on System: '
  4827. TONMS1:    DB    '    ',0
  4828.      ENDIF            ; TIMEON
  4829. ;
  4830. ;              end of TIMEON routine
  4831. ;-----------------------------------------------------------------------
  4832. ;               help routine
  4833. ;
  4834. ; Help menu if ? is typed, using a fancy ZCMD or ZCPR system
  4835. ;
  4836.      IF    WHEEL
  4837. HELPME:    LXI    D,OPTMSG    ; Point at message
  4838.     CALL    SHOW
  4839.      ENDIF        ;WHEEL
  4840.  
  4841.      IF    ZCPR3P AND WHEEL
  4842.     PUSH    H
  4843.     LHLD    Z3WHLL        ; Point to enviorment
  4844.     MOV    A,M        ; Get it
  4845.     POP    H
  4846.      ENDIF        ;ZCPR3P AND WHEEL
  4847.  
  4848.      IF    NOT ZCPR3P AND WHEEL
  4849.     LDA    WHLOC        ; Get wheel byte
  4850.      ENDIF        ;NOT ZCPR3P AND WHEEL
  4851.  
  4852.      IF    WHEEL
  4853.     ORA    A        ; If set, help out poor SYSOP
  4854.     JZ    EXIT3        ; No - exit
  4855.     LXI    D,SYSOP1    ; Point at message
  4856.     CALL    SHOW
  4857.     JMP    EXIT3        ; And exit
  4858. ;
  4859. ; This menu of options will appear to normal users (WHEEL not set).
  4860. ; Modify the menus to accommodate your system requirements.
  4861. ;
  4862. OPTMSG:    DB    13,10,13,10
  4863.     DB    '  Available Options (start with a  $  or  /  or'
  4864.     DB    '  [ character):',13,10,13,10
  4865.     DB    '  A - all user areas               N - no page pause'
  4866.     DB    ' [more]',13,10
  4867.     DB    '  C - file sizes in records        Q - show non-$ARCHived'
  4868.     DB    ' files',13,10
  4869.     DB    '  D - all drives                   T - order files'
  4870.     DB    ' by EXT type',13,10
  4871.     DB    '  H - Current area to highest      V - show version'
  4872.     DB    ' number',13,10
  4873.     DB    '  L - list LBR/ARC/ARK members     X - aux. format'
  4874.     DB    ' (horiz/vert)'
  4875.      ENDIF
  4876.  
  4877.      IF    Z80DOS AND WHEEL
  4878.     DB    13,10
  4879.     DB    '  Z - Do not show dates',13,10
  4880.     DB    '  = - Exact date match             + - GE date match',13,10
  4881.     DB    '  - - LT date match                ! - Use creation date for'
  4882.     DB    ' match',13,10
  4883.     DB    '  % - Use alteration date match    @ - Use access date for'
  4884.     DB    ' match',13,10
  4885.     DB    '   A date input with no =+-!%@ will use =% default,'
  4886.     DB    ' * as date is current date'
  4887.      ENDIF        ;Z80DOS
  4888.  
  4889.      IF    WHEEL
  4890.     DB    13,10,13,10
  4891.      ENDIF
  4892.  
  4893.      IF    Z80DOS AND WHEEL
  4894.     DB    ' Example - to list all drives/users, no pauses,'
  4895.     DB    ' GE date match on access date:',13,10,13,10
  4896.     DB    '                     B0>SD $AND+@ 7/1/88'
  4897.      ENDIF        ;Z80DOS
  4898.  
  4899.      IF    NOT Z80DOS AND WHEEL
  4900.     DB    '  Example - to list all drives and user areas,'
  4901.     DB    ' no pauses:',13,10,13,10
  4902.     DB    '                     B0>SD $AND <ret>'
  4903.      ENDIF        ;NOT Z80DOS
  4904.  
  4905.      IF    WHEEL
  4906.     DB    13,10,13,10,0
  4907. ;
  4908. ; This menu of options appears only when the WHEEL is set.
  4909. ;
  4910. SYSOP1:    DB    '  * * * Special SYSOP Options (WHEEL SET) * * *'
  4911.      ENDIF
  4912.  
  4913.      IF    NOT FATTRIB AND WHEEL
  4914.     DB    13,10,13,10
  4915.      ENDIF        ;NOT FATTRIB
  4916.  
  4917.      IF    FATTRIB AND WHEEL
  4918.     DB    13,10
  4919.      ENDIF        ;FATTRIB
  4920.  
  4921.      IF    WHEEL
  4922.     DB    '  F - file output (DISK.DIR)       R - reset disk'
  4923.     DB    ' system',13,10
  4924.     DB    '  O - show $SYS files only         S - include'
  4925.     DB    ' $SYS files',13,10
  4926.     DB    '  P - printer output',13,10
  4927.      ENDIF
  4928.  
  4929.      IF    FATTRIB AND WHEEL
  4930.     DB    '  1 - Check attrib 1               2 - Check attrib 2',13,10
  4931.     DB    '  3 - Check attrib 3               4 - Check attrib 4',13,10
  4932.      ENDIF        ;FATTRIB
  4933.  
  4934.      IF    WHEEL
  4935.     DB    0
  4936.      ENDIF            ; WHEEL
  4937. ;
  4938. ; Help menu if ? is typed, NOT using any fancy ZCMD or ZCPR system
  4939. ;
  4940.      IF    NOT WHEEL
  4941. HELPME:    LXI    D,OPTMSG    ; Point at message
  4942.     CALL    SHOW
  4943.     JMP    EXIT3        ; And exit
  4944. ;
  4945. OPTMSG:    DB    13,10,13,10
  4946.     DB    '  Available Options (start with a  $  or  /  or'
  4947.     DB    '  [  character):',13,10
  4948.     DB    13,10
  4949.     DB    '  A - all user areas               P - printer output'
  4950.     DB    13,10
  4951.     DB    '  C - file sizes in records        Q - show non $ARChived'
  4952.     DB    ' files',13,10
  4953.     DB    '  D - all drives                   R - reset disk system'
  4954.     DB    13,10
  4955.     DB    '  F - file output (DISK.DIR)       S - include $SYS'
  4956.     DB    ' files',13,10
  4957.     DB    '  H - Current area to highest      T - order files'
  4958.     DB    ' by EXT type',13,10
  4959.     DB    '  L - list LBR/ARC/ARK members     V - show version'
  4960.     DB    ' number',13,10
  4961.     DB    '  N - no page pause [more]         X - aux. format'
  4962.     DB    ' (horiz/vert)',13,10
  4963.     DB    '  O - show $SYS files only'
  4964.      ENDIF        ;NOT WHEEL
  4965.  
  4966.      IF Z80DOS AND NOT WHEEL
  4967.     DB    '         Z - do not show dates'
  4968.      ENDIF            ; Z80DOS
  4969.  
  4970.      IF    NOT WHEEL
  4971.     DB    13,10
  4972.      ENDIF        ;NOT WHEEL
  4973.  
  4974.      IF    FATTRIB AND NOT WHEEL
  4975.     DB    '  1 - Check attrib 1               2 - Check attrib 2',13,10
  4976.     DB    '  3 - Check attrib 3               4 - Check attrib 4',13,10
  4977.      ENDIF        ;FATTRIB
  4978.  
  4979.      IF    Z80DOS AND NOT WHEEL
  4980.     DB    '  = - Exact date match             + - GE date match',13,10
  4981.     DB    '  - - LT date match                ! - Use creation date for'
  4982.     DB    ' match',13,10
  4983.     DB    '  % - Use alteration date match    @ - Use access date for'
  4984.     DB    ' match',13,10
  4985.     DB    '   A date input with no =+-!%@ will use =% default,'
  4986.     DB    ' * as date is current date'
  4987.     DB    13,10,13,10
  4988.     DB    ' Example - to list all drives/users, no pauses,'
  4989.     DB    ' GE date match on access date:',13,10,13,10
  4990.     DB    '                     B0>SD $AND+@ 7/1/88',13,10,13,10,0
  4991.      ENDIF        ;Z80DOS
  4992.  
  4993.      IF    NOT Z80DOS AND NOT WHEEL
  4994.     DB    13,10,'  Example - to list all drives and user areas,'
  4995.     DB    ' no pauses:',13,10,13,10
  4996.     DB    '                     B0>SD $AND <ret>'
  4997.     DB    13,10,13,10,13,10,13,10,13,10,13,10,13,10
  4998.     DB    0
  4999.      ENDIF        ;NOT Z80ODS
  5000.  
  5001. ;     ENDIF            ; NOT WHEEL
  5002.  
  5003.  
  5004.      IF    Z80DOS
  5005. DISDAT:    PUSH    B
  5006.     PUSH    H        ; Save pointer to size field
  5007.     PUSH    D
  5008.     INX    H        ; and skip over size
  5009.     INX    H        ;
  5010.     MOV    E,M        ; Get JD in DE
  5011.     INX    H        ;
  5012.     MOV    D,M        ;
  5013.     XCHG            ; to HL
  5014.     CALL    DATEHL        ;
  5015.     PUSH    H        ; Month and Year in L,H
  5016.     PUSH    PSW        ; Day in A
  5017.     CALL    SPACE
  5018.     CALL    SPACE
  5019.     POP    PSW
  5020.     JNZ    DAYOK        ; NZ = was a day there
  5021.     POP    H
  5022.     CALL    NODATE
  5023.     JMP    DNOTOK
  5024. DAYOK:    PUSH    PSW
  5025.     MOV    A,L        ; Month out
  5026.     CALL    BCDOUT
  5027.     MVI    A,'/'
  5028.     CALL    PUTCHR
  5029.     POP    PSW
  5030.     CALL    BCDOUT        ; Day out
  5031.     MVI    A,'/'
  5032.     CALL    PUTCHR
  5033.     POP    H
  5034.     MOV    A,H        ; Year out
  5035.     CALL    BCDOUT
  5036. DNOTOK:    CALL    SPACE
  5037.     CALL    SPACE
  5038.     POP    D
  5039.     POP    H
  5040.     POP    B
  5041.     RET
  5042.  
  5043. NODATE:
  5044.     LXI    D,NODATM
  5045.     CALL    PUTS
  5046.     RET
  5047. NODATM:
  5048.     DB    '-- -- --',0
  5049.  
  5050. BCDOUT:
  5051.     PUSH    B        ; Save
  5052.     MOV    B,A        ; A holds BCD digits
  5053.     RAR
  5054.     RAR
  5055.     RAR
  5056.     RAR
  5057.     CALL    BCDOT1        ; Output high order
  5058.     MOV    A,B
  5059.     CALL    BCDOT1        ; And low order
  5060.     POP    B
  5061.     RET
  5062. BCDOT1:    ANI    0FH
  5063.     ADI    '0'
  5064.     CALL    PUTCHR
  5065.     RET
  5066.  
  5067. ;
  5068. ; DATEHL converts the value in HL to BCD year, month, day
  5069. ;     for use with Z80DOS time stamps.
  5070. ;
  5071. ;
  5072. ; Inputs:    HL contains hex days since December 31, 1977
  5073. ;
  5074. ; Outputs:    H contains BCD 20th century year
  5075. ;        L contains BCD month
  5076. ;        A contains BCD day
  5077. ;
  5078. ;        Zero flag set (Z) and A=0 if invalid date (zero) detected,
  5079. ;        Zero flag reset (NZ) and A=0ffh otherwise.
  5080.  
  5081. ; Converted to 8080 from DATEHL by Carson Wilson who Adapted from B5C-CPM3.INS
  5082.  
  5083. DATEHL:
  5084.     MOV    A,H
  5085.     ORA    L        ; Test blank date (zero)
  5086.     RZ            ; Return Z and A=0 if so
  5087.     SHLD    DAYS        ; Save initial value
  5088.     MVI    B,78        ; Set years counter
  5089. LOOP:
  5090.     CALL    CKLEAP
  5091.     LXI    D,-365        ; Set up for subtract
  5092.     JNZ    NOPLY        ; Skip if no leap year
  5093.     DCX    D        ; Set for leap year
  5094. NOPLY:
  5095.     DAD    D        ; Subtract
  5096.     JNC    YDONE        ; Continue if years done
  5097.     MOV    A,H
  5098.     ORA    L
  5099.     JZ    YDONE
  5100.     SHLD    DAYS        ; Else save days count
  5101.     INR    B        ; Increment years count
  5102.     JMP    LOOP        ; And do again
  5103. ;
  5104. ; The years are now finished, the years count is in 'B' (HL is invalid)
  5105. ;
  5106. YDONE:
  5107.     MOV    A,B
  5108.     CALL    BINBCD
  5109.     STA    YEARS        ; save BCD year
  5110. ;
  5111.     CALL    CKLEAP
  5112.     MVI    A,0E4H        ; -28
  5113.     JNZ    FEBNO        ; February not 29 days
  5114.     MVI    A,0E3H        ; Leap year -29
  5115. FEBNO:
  5116.     STA    FEB        ; Set february
  5117.     LHLD    DAYS        ; Get days count
  5118.     LXI    D,MTABLE    ; Point to months table
  5119.     MVI    B,0FFH        ; Set up 'B' for subtract
  5120.     MVI    A,0        ; Set a for # of months
  5121. MLOOP:
  5122.     PUSH    PSW
  5123.     LDAX    D        ; Get month
  5124.     MOV    C,A        ; Put in 'C' for subtract
  5125.     POP    PSW
  5126.     SHLD    DAYS        ; save days count
  5127.     DAD    B        ; Subtract
  5128.     INX    D        ; Increment months counter
  5129.     INR    A
  5130.     JC    MLOOP        ; Loop for next month
  5131.  
  5132. ;
  5133. ; The months are finished, days count is on stack.  First, calculate
  5134. ; month.
  5135. ;
  5136. MDONE:
  5137.     MOV    B,A        ; Save months
  5138.     LHLD    DAYS
  5139.     MOV    A,H
  5140.     ORA    L
  5141.     JNZ    NZD
  5142.     DCX    D
  5143.     DCX    D
  5144.     LDAX    D
  5145.     CMA
  5146.     INR    A
  5147.     MOV    L,A
  5148.     DCR    B
  5149. NZD:
  5150.     MOV    A,L        ; Retrieve binary day of month
  5151.     CALL    BINBCD        ; Convert to BCD
  5152.     PUSH    PSW        ; Save day in A
  5153. ;
  5154.     MOV    A,B        ; Retrieve the binary month
  5155.     CALL    BINBCD        ; Convert binary month to BCD
  5156.     MOV    L,A        ; Return month in L
  5157. ;
  5158.     LDA    YEARS
  5159.     MOV    H,A        ; Return year in H
  5160. ;
  5161.     POP    PSW        ; Restore day
  5162.     ORA    A        ; Set NZ flag
  5163.     RET
  5164.  
  5165. ;
  5166. ; Support Routines:
  5167. ;
  5168.  
  5169. ;
  5170. ; Check for leap years.
  5171. ;
  5172. CKLEAP:
  5173.     MOV    A,B
  5174.     ANI    0FCH
  5175.     CMP    B
  5176.     RET
  5177. ;
  5178. ; Convert A to BCD & store back in A
  5179. ;
  5180. BINBCD:
  5181.     ORA    A
  5182.     RZ
  5183.     PUSH    B
  5184.     MOV    B,A
  5185.     XRA    A
  5186. BINBCD1:
  5187.     ADI    1
  5188.     DAA
  5189.     DCR    B
  5190.     JNZ    BINBCD1
  5191.     POP    B
  5192.     RET
  5193. ;
  5194. ; Buffers:
  5195. ;
  5196.  
  5197. ;
  5198. ; Months table
  5199. ;
  5200. MTABLE:
  5201.     DB    0E1H            ;January -31
  5202. FEB:
  5203.     db    0E4H             ;February -28
  5204.     db    0E1H,0E2H,0E1H,0E2H     ;Mar-Jun -31,-30,-31,-30
  5205.     db    0E1H,0E1H,0E2H        ;Jul-Sep -31,-31,-30
  5206.     db    0E1H,0E2H,0E1H        ;Oct-Dec -31,-30,-31
  5207.  
  5208.      ENDIF    ;Z80DOS
  5209.  
  5210.  
  5211.  
  5212. ;
  5213. ; Messages and Error statements
  5214. ;
  5215. CKMS1:    DB    13,10,'++ ABORTED ++',0
  5216. CKMS2:    DB    8,' ',8,0
  5217. DRUMSG:    DB    'Drive/User',0
  5218. EOSMSG:    DB    '[more] ','$'
  5219.  
  5220.      IF    VSPAGE
  5221. MORERA:    DB    13,'                  ----------------------------------------'
  5222.     DB    13,10,'$'
  5223.      ENDIF            ;VSPAGE
  5224.  
  5225.      IF    NOT VSPAGE
  5226. MORERA:    DB    13,'        ',13,'$'
  5227.      ENDIF
  5228.  
  5229. ERRMS1:    DB    ' '
  5230. ERRMS2:    DB    'Error',0
  5231. ERRTAG:    DB    ' ->',0
  5232. NOFLM:    DB    '>> No detectable file(s) on ',0
  5233. NOFMS1:    DB    13,10,13,10,' ',0
  5234. NOFMS2:    DB    '  ',0
  5235. NOFMS3:    DB    ':  ',0
  5236. SOHFLG:    DB    0
  5237. TOTMS1:    DB    13,10,'         Drive ',0
  5238. TOTMS4:    DB    '/',0
  5239. TOTMS5:    DB    'k  ',0
  5240. TOTMS6:    DB    ' Files: ',0
  5241. TOTMS7:    DB    ' Free: ',0
  5242. TOTMS8:    DB    'k ',0
  5243. ALLTOT:    DB    13,10,'             Total files: ',0
  5244. ALLTO1:    DB    'k',13,10,0
  5245.  
  5246.      IF    PRBRDR
  5247. CONTM1:    DB    13,10,'** There are ',0
  5248. MFILES:    DB    ' member files in ',0
  5249. LIBR:    DB    ' library(s) and/or archive(s) **',0
  5250. AFMSP1:    DB    13,10,'** Archive directory for ',0
  5251. LFMSP1:    DB    13,10,'** Library directory for ',0
  5252. LFMSP3:    DB    'k'
  5253.     DB    ' **'
  5254.     DB    13,10,0
  5255.      ENDIF            ; PRBRDR
  5256.  
  5257.      IF    NOT PRBRDR
  5258. CONTM1:    DB    13,10,'There are ',0
  5259. MFILES:    DB    ' member files in ',0
  5260. LIBR:    DB    ' library(s) and/or archive(s)',0
  5261. AFMSP1:    DB    13,10,'Archive directory for ',0
  5262. LFMSP1:    DB    13,10,'Library directory for ',0
  5263. LFMSP3:    DB    'k'
  5264.     DB    13,10,0
  5265.      ENDIF            ; Not PRBRDR
  5266.  
  5267. NLBRF:    DB    '++ Not a library file ++',13,10
  5268. NARCF:    DB    '++ Not an archive file ++',13,10
  5269. LBRTYP:    DB    'LBR'
  5270. ARCTYP:    DB    'AR'        ; We only test the first 2 in the loop.
  5271.                 ; The C or K are tested separately.
  5272. ;
  5273. ; Permanently initialized data area
  5274. ;
  5275. VECTBL:    DW    DSKERR        ; BDOS record error intercept vector
  5276.     DW    DSKERR        ; BDOS select error intercept vector
  5277. ;
  5278. ; End of code that must be stored on disk in the .COM file
  5279. ;
  5280. ; Data area reinitialized by code when SD is run or rerun
  5281. ;
  5282. DATA0    EQU    $        ; Start of area to initialize
  5283.  
  5284. OTBL    EQU    $        ; Mark start of option table
  5285. VFLAG:    DS    1
  5286. AOPFLG:    DS    1
  5287. COPFLG:    DS    1
  5288. DOPFLG:    DS    1
  5289. FOPFLG:    DS    1
  5290. HOPFLG:    DS    1
  5291. LOPFLG:    DS    1
  5292. NOPFLG:    DS    1
  5293. OOPFLG:    DS    1
  5294. POPFLG:    DS    1
  5295. QOPFLG:    DS    1
  5296. ROPFLG:    DS    1
  5297. SOPFLG:    DS    1
  5298. TOPFLG:    DS    1
  5299. VOPFLG:    DS    1
  5300. XOPFLG:    DS    1
  5301.  
  5302.      IF    Z80DOS        ;
  5303. DEOPFL:    DS    1
  5304. DPOPFL:    DS    1
  5305. DMOPFL:    DS    1
  5306. DNOPFL: DS    1
  5307. DAOPFL: DS    1
  5308. DGOPFL:    DS    1
  5309. NODFLG:    DS    1
  5310.      ENDIF    ;Z80DOS
  5311.  
  5312.      IF    FATTRIB
  5313. ONEFLG:    DS    1
  5314. TWOFLG:    DS    1
  5315. THRFLG:    DS    1
  5316. FORFLG:    DS    1
  5317.      ENDIF
  5318.  
  5319. OEND    EQU    $        ; End of option table
  5320. ;
  5321. ; End of option lookup table
  5322. ;
  5323. BUFPNT:    DS    2        ; Next location in output buffer
  5324. BUFCNT:    DS    1        ; Number of bytes left in output buffer
  5325. OUTFCB:    DS    1+8+3        ; User number, filename, and filetype
  5326. ;
  5327. ; Beginning of area reinitialized to zero each time SD.COM is run
  5328. ;
  5329.     DS    21        ; Rest of DISK.DIR FCB
  5330. DISKNO:    DS    1        ; Disk number
  5331. USERNO:    DS    1        ; User number
  5332. OPNFLG:    DS    1        ; File open flag
  5333. DRVFLG:    DS    1        ; D option check for prior drive specificaton
  5334. FNDFLG:    DS    1        ; Files Matched Flag
  5335. BYEACT:    DS    1        ; BYE Active Flag
  5336.  
  5337. LINCNT:    DS    1        ; # lines printed on screen
  5338. LLENLOC:DS    2        ; Running total of .LBR length
  5339. LMTOTL:    DS    2
  5340. LBTOTL:    DS    2
  5341. LNCNT:    DS    1
  5342. LCOUNT:    DS    2
  5343. NEXTL:    DS    2
  5344. SLFILE:    DS    2
  5345. LINES:    DS    1        ; Number of lines to be printed
  5346. FIRSTT:    DS    1        ; First time flag for version number
  5347. ISARC:    DS    1
  5348. ;
  5349. ; Uninitialized data area
  5350. ;
  5351. BASUSR:    DS    1        ; Copy of original directory user #
  5352. BLKMAX:    DS    2        ; Highest block # on drive
  5353. BLKMSK:    DS    1        ; Records/block - 1
  5354. BLKSHF:    DS    1        ; Number shifts to mult by sec/blk
  5355. COUNT:    DS    2        ; Entry count
  5356. DIRMAX:    DS    2        ; Highest file # in directory
  5357. FILERC:    DS    2        ; File size in records
  5358. FREEBY:    DS    2        ; Number of k left on dir. drive
  5359. FSIZEC:    DS    1        ; File size character ('k' or 'r')
  5360. GAP:    DS    2        ; Sort routine storage
  5361. I:    DS    2        ; Sort routine storage
  5362. J:    DS    2        ; Sort routine storage
  5363. JG:    DS    2        ; Sort routine storage
  5364. LZFLG:    DS    1        ; 0 when printing leading zeros
  5365. MAXUSR:    DS    1        ; Max user # for drive
  5366. NEWUSR:    DS    1        ; User # selected by "$U" option
  5367. NEXTT:    DS    2        ; Next table entry
  5368. OLDDSK:    DS    1        ; Currently logged-in drive
  5369. OLDUSR:    DS    1        ; User number upon invocation
  5370. SCOUNT:    DS    2        ; # to sort
  5371. SUPSPC:    DS    1        ; Leading space flag
  5372. TBLOC:    DS    2        ; Start of name table
  5373. TOTFIL:    DS    2        ; Total number of files
  5374. TOTSIZ:    DS    2        ; Total size of all files
  5375. TOTFL1:    DS    2        ; Total files of all D/U
  5376. TOTSZ1:    DS    2        ; Total size of all D/U
  5377. TOTFRE:    DS    2
  5378. USRNR:    DS    1        ; User number
  5379. VERFLG:    DS    1        ; CP/M version number (0=pre-CP/M 2)
  5380. ZRDFLG:    DS    1        ; ZRDOS version number
  5381.  
  5382.     IF    Z80DOS        ;
  5383. DATPLS:    DS    1        ; Holds +/- flag for date math
  5384. DATCH1:    DS    2        ; Holds first input date
  5385. DATCHK:    DS    2        ; Holds date to look for
  5386. DTMTCH:    DS    1        ; Holds <,>=,>
  5387. DATMOD:    DS    2        ; Holds date found for file
  5388. DAYS:    ds    2        ; temporary buffers
  5389. YEARS:    ds    1        ;
  5390. YEARS1:    DS    1
  5391. MONTHS:    DS    1
  5392. DAYS1:    DS    1
  5393. ASCII:    DS    5        ; holds date from system
  5394.     ENDIF        ;Z80DOS
  5395.  
  5396.  
  5397. DATA1    EQU    $        ; End of area to initialize
  5398.  
  5399.      IF    ZCPR3P
  5400. Z3DRVL:    DS    2        ; Points to Z33 max drv location
  5401. Z3USRL:    DS    2        ; Points to Z33 max user location
  5402. Z3WHLL:    DS    2        ; Points to Z33 wheel location
  5403.      ENDIF        ;ZCPR3P
  5404.  
  5405.      IF    NDIRS
  5406. NAMADR:    DS    2        ; Named Directory Buffer Address
  5407. NUMDIR:    DS    1        ; Number of entries
  5408. CURDIR:    DS    1        ; NDR Check counter
  5409.      ENDIF            ; NDIRS
  5410.  
  5411.      IF    SHOPUB
  5412. PUBDRV:    DS    1        ; Storage for Public Drive byte
  5413. PUBUSR:    DS    1        ; "    "    "      User     "
  5414.      ENDIF            ; SHOPUB
  5415.  
  5416. GETABL:    DS    1
  5417. LBRFCB:    DS    36
  5418. LBBUF:    DS    128
  5419.  
  5420. ANAME:    DS    13
  5421. ASIZE:    DS    14
  5422. ARCFIL:    DS    16
  5423.  
  5424. NEWPTR:    DS    2        ; Start of second table
  5425. XPOINT:    DS    2
  5426. JUMPER:    DS    2        ; Increment for second table to
  5427. WASHERE:
  5428.     DS    1
  5429. VSFRST:    DS    1
  5430. OUTBUF:    DS    128        ; Output file buffer
  5431. ;
  5432. ; BDOS equates
  5433. ;
  5434. BDOS    EQU    0005H        ; Entry Point for BDOS calls
  5435. FCB    EQU    005CH        ; Default FCB Address
  5436. TBUF    EQU    0080H        ; Default DMA Address
  5437.  
  5438. RDCON    EQU    1        ; Console input
  5439. WRCON    EQU    2        ; Console output
  5440. LIST    EQU    5        ; List output
  5441. PRINT    EQU    9        ; Print string
  5442. CONST    EQU    11        ; Get console status
  5443. CPMVER    EQU    12        ; Return CP/M version
  5444. RESET    EQU    13        ; Reset disk system
  5445. SELDSK    EQU    14        ; Select disk
  5446. OPEN    EQU    15        ; Open file
  5447. CLOSE    EQU    16        ; Close file
  5448. SRCHF    EQU    17        ; Search for first
  5449. SRCHN    EQU    18        ; Search for next
  5450. READ    EQU    20        ; Read sequential
  5451. WRITE    EQU    21        ; Write sequential
  5452. MAKE    EQU    22        ; Make file
  5453. CURDSK    EQU    25        ; Return current disk
  5454. STDMA    EQU    26        ; Set DMA Address
  5455. DSKALL    EQU    27        ; Get address of allocation vector
  5456. DSKPAR    EQU    31        ; Get address of disk parameters
  5457. STUSER    EQU    32        ; Set/get user number
  5458.  
  5459.      IF    ZRDOS
  5460. ZRDVER    EQU    48        ; Return version (ZRDOS)
  5461. SETWBT    EQU    50        ; Set warm boot trap (ZRDOS)
  5462. RESWBT    EQU    52        ; Reset warm boot trap (ZRDOS)
  5463.      ENDIF            ; ZRDOS
  5464.  
  5465.     DS    60        ; Stack area
  5466. STACK:    DS    2        ; Old stack pointer
  5467.  
  5468. ORDER    EQU    $        ; Order table starts here
  5469.  
  5470.     END
  5471.