home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol101 / xdir3.mac < prev    next >
Encoding:
Text File  |  1984-04-29  |  37.0 KB  |  1,755 lines

  1. ;
  2. ;  PROGRAM:  XDIR III
  3. ;  AUTHOR:  RICHARD CONN
  4. ;  VERSION:  1.5
  5. ;  DATE:  8 JAN 83
  6. ;  PREVIOUS VERSIONS:  1.4 (6 JAN 83), 1.3 (7 DEC 82)
  7. ;  PREVIOUS VERSIONS:  1.2 (2 NOV 82), 1.1 (30 OCT 82), 1.0 (20 OCT 82)
  8. ;
  9. vers    equ    15
  10.  
  11. ;
  12. ;    This program is Copyright (c) 1982, 1983 by Richard Conn
  13. ;    All Rights Reserved
  14. ;
  15. ;    ZCPR2 and its utilities, including this one, are released
  16. ; to the public domain.  Anyone who wishes to USE them may do so with
  17. ; no strings attached.  The author assumes no responsibility or
  18. ; liability for the use of ZCPR2 and its utilities.
  19. ;
  20. ;    The author, Richard Conn, has sole rights to this program.
  21. ; ZCPR2 and its utilities may not be sold without the express,
  22. ; written permission of the author.
  23. ;
  24.  
  25.  
  26. ;
  27. ;  XDIR III -- Extended Disk Directory Program
  28. ;        CP/M 2.2 Version
  29. ;
  30. ;    XDIR III produces a formatted, alphabetized listing of the contents
  31. ; of the disk directory of the implied (current logged-in) or specified disk.
  32. ;
  33. ;    XDIR III is invoked by a command line of the following form --
  34. ;
  35. ;        XDIR dir:filename.typ ooo...
  36. ; or
  37. ;
  38. ;        XDIR /oooo...
  39. ;
  40. ; where:
  41. ;    dir is an optional directory name or a disk/user specification (du)
  42. ;    if dir is omitted, XDIR III defaults to the current disk/user
  43. ;    filename.typ is an ambiguous file name and type (* and ? may be used)
  44. ;    o are option letters as follows:
  45. ;        Aa - Set the attributes of the files to be displayed;
  46. ;            a=S for System Files, a=N for Non-System Files
  47. ;            a=A for All Files (System and Non-System)
  48. ;        D  - Send Output to Disk as well as screen
  49. ;        Ff - Engage File Name Buffer Facility
  50. ;            f=L to Log File Names to Disk
  51. ;            f=P to Print Names Logged to Disk
  52. ;            f=S to Scan Disk for File Names and Compare to Logged
  53. ;        G  - Toggle Grouping (group files by file name and type or
  54. ;            type and name)
  55. ;        H  - Toggle Horizontal or Vertical format of display
  56. ;        I  - Inspect files selected by FL option for inclusion
  57. ;        N  - Negate selection; select those files which do NOT
  58. ;            match the ambiguous file name
  59. ;        P  - Print display as well as show it on the screen
  60. ; Options may be combined as desired; note that AA is the same as AS and AN,
  61. ; but AS by itself negates AN and vice-versa, with AN taking precident
  62. ;
  63.  
  64.  
  65. ;
  66. ;  CP/M Equates
  67. ;
  68. base    equ    0
  69. wboot    equ    base
  70. bdose    equ    base+5
  71. fcb    equ    base+5ch
  72. buff    equ    base+80h
  73. cr    equ    0dh
  74. lf    equ    0ah
  75. esize    equ    16    ; size of directory entries
  76. optch    equ    '/'    ; option char
  77. maxent    equ    51    ; maximum number of entries/screen
  78.  
  79. ;
  80. ;  External Routines
  81. ;
  82.     ext    bdos    ; BDOS
  83.     ext    zfname    ; file name parser with named directories
  84.     ext    zgpins    ; init buffers
  85.     ext    dbuffer    ; disk routines
  86.     ext    dfree
  87.     ext    diralpha
  88.     ext    dirsload
  89.     ext    dirpack
  90.     ext    dirnpack
  91.     ext    dirsel
  92.     ext    dparam
  93.     ext    fsize
  94.     ext    fo0$open    ; byte-oriented file output
  95.     ext    fo0$close
  96.     ext    f0$put
  97.     ext    fo1$open
  98.     ext    fo1$close
  99.     ext    f1$put
  100.     ext    fi1$open
  101.     ext    fi1$close
  102.     ext    f1$get
  103.     ext    bbline    ; input line editor
  104.     ext    retud    ; get current user and disk
  105.     ext    print    ; print routines
  106.     ext    pstr
  107.     ext    lpstr
  108.     ext    lcrlf
  109.     ext    caps    ; capitalize char
  110.     ext    cin    ; console in char
  111.     ext    lout    ; print char
  112.     ext    cout    ; console out char
  113.     ext    crlf    ; new line
  114.     ext    madc    ; a as dec chars in memory
  115.     ext    mhldc    ; hl as dec chars in memory
  116.     ext    fillb    ; memory fill
  117.     ext    moveb    ; memory move
  118.     ext    codend    ; beginning of buffer area
  119.  
  120. ;
  121. ;  Branch to Start of Program
  122. ;
  123.     jmp    start
  124.  
  125. ;
  126. ;******************************************************************
  127. ;
  128. ;  SINSFORM -- ZCPR2 Utility Standard General Purpose Initialization Format
  129. ;
  130. ;    This data block precisely defines the data format for
  131. ; initial features of a ZCPR2 system which are required for proper
  132. ; initialization of the ZCPR2-Specific Routines in SYSLIB.
  133. ;
  134.  
  135. ;
  136. ;  EXTERNAL PATH DATA
  137. ;
  138. EPAVAIL:
  139.     DB    0FFH    ; IS EXTERNAL PATH AVAILABLE? (0=NO, 0FFH=YES)
  140. EPADR:
  141.     DW    40H    ; ADDRESS OF EXTERNAL PATH IF AVAILABLE
  142.  
  143. ;
  144. ;  INTERNAL PATH DATA
  145. ;
  146. INTPATH:
  147.     DB    0,0    ; DISK, USER FOR FIRST PATH ELEMENT
  148.             ; DISK = 1 FOR A, '$' FOR CURRENT
  149.             ; USER = NUMBER, '$' FOR CURRENT
  150.     DB    0,0
  151.     DB    0,0
  152.     DB    0,0
  153.     DB    0,0
  154.     DB    0,0
  155.     DB    0,0
  156.     DB    0,0    ; DISK, USER FOR 8TH PATH ELEMENT
  157.     DB    0    ; END OF PATH
  158.  
  159. ;
  160. ;  MULTIPLE COMMAND LINE BUFFER DATA
  161. ;
  162. MCAVAIL:
  163.     DB    0FFH    ; IS MULTIPLE COMMAND LINE BUFFER AVAILABLE?
  164. MCADR:
  165.     DW    0FF00H    ; ADDRESS OF MULTIPLE COMMAND LINE BUFFER IF AVAILABLE
  166.  
  167. ;
  168. ;  DISK/USER LIMITS
  169. ;
  170. MDISK:
  171.     DB    4    ; MAXIMUM NUMBER OF DISKS
  172. MUSER:
  173.     DB    31    ; MAXIMUM USER NUMBER
  174.  
  175. ;
  176. ;  FLAGS TO PERMIT LOG IN FOR DIFFERENT USER AREA OR DISK
  177. ;
  178. DOK:
  179.     DB    0FFH    ; ALLOW DISK CHANGE? (0=NO, 0FFH=YES)
  180. UOK:
  181.     DB    0FFH    ; ALLOW USER CHANGE? (0=NO, 0FFH=YES)
  182.  
  183. ;
  184. ;  PRIVILEGED USER DATA
  185. ;
  186. PUSER:
  187.     DB    10    ; BEGINNING OF PRIVILEGED USER AREAS
  188. PPASS:
  189.     DB    'chdir',0    ; PASSWORD FOR MOVING INTO PRIV USER AREAS
  190.     DS    41-($-PPASS)    ; 40 CHARS MAX IN BUFFER + 1 for ending NULL
  191.  
  192. ;
  193. ;  CURRENT USER/DISK INDICATOR
  194. ;
  195. CINDIC:
  196.     DB    '$'    ; USUAL VALUE (FOR PATH EXPRESSIONS)
  197.  
  198. ;
  199. ;  DMA ADDRESS FOR DISK TRANSFERS
  200. ;
  201. DMADR:
  202.     DW    80H    ; TBUFF AREA
  203.  
  204. ;
  205. ;  NAMED DIRECTORY INFORMATION
  206. ;
  207. NDRADR:
  208.     DW    00000H    ; ADDRESS OF MEMORY-RESIDENT NAMED DIRECTORY
  209. NDNAMES:
  210.     DB    64    ; MAX NUMBER OF DIRECTORY NAMES
  211. DNFILE:
  212.     DB    'NAMES   '    ; NAME OF DISK NAME FILE
  213.     DB    'DIR'        ; TYPE OF DISK NAME FILE
  214.  
  215. ;
  216. ;  REQUIREMENTS FLAGS
  217. ;
  218. EPREQD:
  219.     DB    0FFH    ; EXTERNAL PATH?
  220. MCREQD:
  221.     DB    0FFH    ; MULTIPLE COMMAND LINE?
  222. MXREQD:
  223.     DB    0FFH    ; MAX USER/DISK?
  224. UDREQD:
  225.     DB    0FFH    ; ALLOW USER/DISK CHANGE?
  226. PUREQD:
  227.     DB    0FFH    ; PRIVILEGED USER?
  228. CDREQD:
  229.     DB    0FFH    ; CURRENT INDIC AND DMA?
  230. NDREQD:
  231.     DB    0FFH    ; NAMED DIRECTORIES?
  232. Z2CLASS:
  233.     DB    3    ; CLASS 3
  234.     DB    'ZCPR2'
  235.     DS    10    ; RESERVED
  236.  
  237. ;
  238. ;  END OF SINSFORM -- STANDARD DEFAULT PARAMETER DATA
  239. ;
  240. ;******************************************************************
  241. ;
  242.  
  243. ;
  244. ;  Other Buffers
  245. ;
  246. igrp:    db    0ffh    ; Group by file type and name
  247. ifmt:    db    0    ; vertical format
  248. iatt:    db    10000000b    ; Non-System files only
  249. iscn:    db    0    ; 0=dir display, 0ffh=scan for files by default
  250. fenab:    db    0ffh    ; enable F options (0=no)
  251. lenab:    db    0ffh    ; enable FL option (0=no)
  252. asenab:    db    0ffh    ; enable AS option (0=no)
  253.  
  254. ;
  255. ;  Buffers
  256. ;
  257. aflg:    ds    1    ; attibute flag
  258. dflg:    ds    1    ; disk output on flag
  259. fflg:    ds    1    ; 0=no file name buffer function
  260. gflg:    ds    1    ; 0=group by name/type
  261. hflg:    ds    1    ; 0=vertical list
  262. iflg:    ds    1    ; 0=no inspect
  263. nflg:    ds    1    ; 0=no negate
  264. pflg:    ds    1    ; printer output on flag
  265. fopt:    ds    1    ; file name buffer option
  266. crcnt:    ds    1    ; entry counter
  267. fmark:    ds    1    ; first file marker
  268. dflgt:    ds    1    ; temp flags
  269. pflgt:    ds    1
  270. dflgs:    ds    1
  271. pflgs:    ds    1
  272. disk:    ds    1    ; selected disk
  273. curdisk:
  274.     ds    1    ; current disk
  275. rem:    ds    1    ; remainder buffer
  276. firstf:    ds    2    ; ptr to first file of group to print
  277. totfil:    ds    2    ; total number of files on disk
  278. fcount:    ds    2    ; count of files
  279. countf:    ds    2    ; down count of files
  280. freesiz:
  281.     ds    2    ; amount of free space on disk
  282. totsiz:
  283.     ds    2    ; total size of all files
  284. ptr1:    ds    2    ; col output ptrs
  285. ptr2:    ds    2
  286. ptr3:    ds    2
  287. entptr:    ds    2    ; current entry ptr
  288. numbuf:    ds    6    ; number buffer
  289. dfnbuf:
  290.     ds    12    ; disk file name buffer
  291. dskfcb:
  292.     db    0
  293.     db    'XDIR    DIR'
  294.     db    0,0,0,0
  295.     ds    16
  296.     ds    4
  297. fnfcb:
  298.     db    0
  299.     db    'FNAMES  DIR'
  300.     db    0,0,0,0
  301.     ds    16
  302.     ds    4
  303. cmdlne:
  304.     ds    210    ; 210 bytes for command line
  305.     ds    100    ; 100 bytes for stack
  306. stack:    ds    2    ; stack ptr
  307.     db    0
  308.  
  309. ;
  310. ;  Command Line Option Table
  311. ;
  312. optab:
  313.     db    'A'
  314.     dw    opta
  315.     db    'D'
  316.     dw    optd
  317.     db    'F'
  318.     dw    optf
  319.     db    'G'
  320.     dw    optg
  321.     db    'H'
  322.     dw    opth
  323.     db    'I'
  324.     dw    opti
  325.     db    'N'
  326.     dw    optn
  327.     db    'P'
  328.     dw    optp
  329.     db    0
  330.  
  331. ;
  332. ;  Start of XDIR III
  333. ;
  334. start:
  335.  
  336. ;  Save stack ptr for return later
  337.     lxi    h,0    ; get stack
  338.     dad    sp
  339.     shld    stack    ; save stack ptr for return
  340.     lxi    sp,stack
  341.  
  342. ;  Mark end of command line
  343.     lxi    h,buff    ; place ending zero in command line buffer
  344.     mov    a,m    ; get char count
  345.     inx    h    ; pt to first char
  346.     add    l    ; pt to after last char
  347.     mov    l,a
  348.     mov    a,h
  349.     aci    0
  350.     mov    h,a
  351.     mvi    m,0    ; store ending zero
  352.  
  353. ;  Save command line in CMDLNE buffer
  354.     lxi    h,buff+1    ; copy input line into command line buffer
  355.     lxi    d,cmdlne
  356. start1:
  357.     mov    a,m    ; get byte
  358.     stax    d    ; put byte
  359.     inx    h    ; pt to next
  360.     inx    d
  361.     ora    a    ; end of line?
  362.     jnz    start1
  363.  
  364. ;  Initialize ZCPR2 buffers in SYSLIB
  365.     call    zgpins    ; do init
  366.  
  367. ;  Get and save current user number
  368. noext:
  369.     call    retud    ; get current user and disk
  370.     mov    a,c    ; get user into A
  371.     sta    aflg    ; current user number
  372.     mov    a,b    ; get disk into A
  373.     sta    curdisk    ; current disk number
  374.     mvi    a,0ffh    ; set default user flag
  375.     sta    disk    ; default disk selected
  376.  
  377. ;  Set flag values
  378.     lda    igrp    ; set grouping (file name/type or type/name)
  379.     sta    gflg
  380.     lda    ifmt    ; set listing format (vertical or horizontal, 0=vert)
  381.     sta    hflg
  382.     lda    iatt    ; set file attributes
  383.     mov    c,a    ; save in c
  384.     lda    aflg    ; get current user number
  385.     ora    c    ; mask in file attributes
  386.     sta    aflg    ; save flag
  387.     lda    iscn    ; set initial function (Scan or Dir)
  388.     sta    fflg
  389.     xra    a    ; A=0
  390.     sta    nflg    ; set no negation
  391.     sta    dflg    ; set no disk output
  392.     sta    pflg    ; set no printer output
  393.     sta    iflg    ; set no file name inspection (for /FP)
  394.  
  395. ;  Assume wild file name
  396.     lxi    h,fcb+1    ; store '?' chars
  397.     mvi    a,'?'
  398.     mvi    b,11    ; 11 chars
  399.     call    fillb
  400.  
  401. ;  Scan command line for options
  402.     lxi    h,cmdlne    ; pt to first char
  403.     call    sblank    ; skip over blanks
  404.     ora    a    ; end of line?
  405.     jz    xdir    ; begin main processing
  406.     inx    h    ; prep for invalid option
  407.     cpi    optch    ; option?
  408.     jz    opt    ; process options
  409.     dcx    h    ; ok to process for dir:filename.typ form
  410. ;  Process for DIR:FILENAME.TYP form
  411.     push    h    ; save ptr to first char of file name
  412.     call    codend    ; get scratch area ptr
  413.     mov    b,h    ; bc pts to scratch area
  414.     mov    c,l
  415.     pop    h    ; get ptr to first char of file name
  416.     lxi    d,fcb    ; extract file name into fcb, and get user and disk
  417. ;  named directory scan
  418.     call    zfname    ; hl pts to first char of file name, de pts to fcb,
  419.             ;   bc pts to scratch area
  420. ;  scan complete -- check for valid user and disk
  421.     jnz    udok    ; no user or disk number error
  422.     call    print
  423.     db    cr,lf,'Error -- Invalid Directory or Disk/User Specified'
  424.     db    cr,lf,0
  425.     jmp    return
  426. ;  scan complete -- look for possible following option char
  427. udok:
  428.     call    sblank    ; skip over blanks
  429.     mov    a,m    ; option char follows?
  430.     cpi    optch
  431.     jnz    skipo
  432.     inx    h    ; skip over option char
  433. ;  HL now pts to possible set of options
  434. skipo:
  435.     lda    udreqd    ; enable user and disk selection?
  436.     ora    a    ; 0=no
  437.     jnz    skipo1
  438.     lxi    b,0ffffh    ; select defaults for disk and user
  439. ;  check for disk select and select if so
  440. skipo1:
  441.     mov    a,b    ; disk number in a
  442.     sta    disk
  443.     cpi    0ffh    ; default?
  444.     jz    skipd    ; skip disk selection if so
  445.     push    b    ; save bc
  446.     push    h    ; save hl ptr
  447.     mov    e,b    ; disk number in e
  448.     dcr    e    ; adjust to 0-15
  449.     mvi    c,14    ; select disk
  450.     lda    dok    ; ok to select a disk?
  451.     ora    a    ; 0=no
  452.     cnz    bdos
  453.     pop    h    ; get hl ptr
  454.     pop    b    ; get bc
  455. ;  check for user select and select if so
  456. skipd:
  457.     mov    a,c    ; user number in a
  458.     cpi    0ffh    ; default?
  459.     jz    selcu    ; select current user if so
  460.     cpi    '?'    ; all users?
  461.     jz    selau    ; select all users if so
  462.     ani    1fh    ; mask for user number
  463. setusr:
  464.     mov    c,a    ; result in c
  465.     lda    aflg    ; get attribute flag
  466.     ani    0c0h    ; get rid of old user
  467.     ora    c    ; mask in user number
  468.     sta    aflg    ; set attribute flag
  469.     jmp    opt    ; now process options
  470. ;  select current user
  471. selcu:
  472.     lda    aflg    ; get current user
  473.     ani    1fh    ; select user number only
  474.     jmp    setusr
  475. ;  select all users
  476. selau:
  477.     lda    aflg    ; get attribute flag
  478.     ori    20h    ; select all users
  479.     sta    aflg
  480.  
  481. ;  Look for options -- main loop; HL pts to next char
  482. opt:
  483.     mov    a,m    ; get option char
  484.     inx    h    ; pt to next
  485.     ora    a    ; end of line?
  486.     jz    xdir    ; begin main processing
  487.     cpi    ' '    ; skip over spaces
  488.     jz    opt
  489.     cpi    optch    ; option char?
  490.     jz    opterr    ; loop back if so
  491.     lxi    d,optab    ; pt to option table
  492.     mov    b,a    ; option char in b
  493. ;  Scan option table
  494. opt1:
  495.     ldax    d    ; get option table char
  496.     ora    a    ; end of table?
  497.     jz    opterr    ; invalid option error
  498.     cmp    b    ; compare to passed option
  499.     jz    opt2    ; process if match
  500.     inx    d    ; skip address
  501.     inx    d
  502.     inx    d    ; pt to next opt char
  503.     jmp    opt1
  504. ;  Process option found
  505. opt2:
  506.     inx    d    ; pt to low-order address
  507.     ldax    d    ; get it
  508.     mov    c,a    ; low in C
  509.     inx    d    ; pt to high-order address
  510.     ldax    d    ; get it
  511.     mov    b,a    ; high in B
  512.     push    b    ; BC on stack
  513.     ret        ; Process option routine
  514. ;  Option A -- File Attributes
  515. opta:
  516.     mov    a,m    ; get next option letter
  517.     cpi    'N'    ; Non-System files?
  518.     jz    optan
  519.     cpi    'S'    ; System files?
  520.     jz    optas
  521.     cpi    'A'    ; All files?
  522.     jnz    opterr    ; error if not
  523. ;  Option AA -- All Files
  524. optaa:
  525.     lda    asenab    ; enable system files?
  526.     ora    a    ; 0=no
  527.     jz    optan
  528.     mvi    c,11000000b    ; System and Non-system
  529. optaret:
  530.     lda    aflg    ; get flag
  531.     ani    3fh    ; leave in user selection
  532.     ora    c    ; mask in sys/non-sys
  533.     sta    aflg    ; restore flag
  534.     inx    h    ; pt to next
  535.     jmp    opt
  536. ;  Option AS -- System Files
  537. optas:
  538.     lda    asenab    ; enable system files?
  539.     ora    a    ; 0=no
  540.     jz    optan
  541.     mvi    c,01000000b    ; System Only
  542.     jmp    optaret
  543. ;  Option AN -- Non-System Files
  544. optan:
  545.     mvi    c,10000000b    ; Non-system Only
  546.     jmp    optaret
  547.  
  548. ;  Option F - select file name buffer functions
  549. optf:
  550.     mvi    a,0ffh    ; set flag
  551.     sta    fflg
  552.     mov    a,m    ; get option char
  553.     sta    fopt
  554.     cpi    'L'    ; log file names to disk
  555.     jz    optfok
  556.     cpi    'P'    ; print names of files
  557.     jz    optfok
  558.     cpi    'S'    ; scan disk for files
  559.     jz    optfok
  560.     jmp    opterr    ; error otherwise
  561. optfok:
  562.     inx    h    ; pt to next option letter
  563.     jmp    opt
  564.  
  565. ;  Option G - toggle it; grouping (0=file name and type)
  566. optg:
  567.     lda    gflg    ; get flag
  568.     cma        ; toggle it
  569.     sta    gflg
  570.     jmp    opt    ; continue option processing
  571.  
  572. ;  Option H -- toggle it; horizontal/vertical listing (0=vertical)
  573. opth:
  574.     lda    hflg    ; get flag
  575.     cma        ; toggle it
  576.     sta    hflg
  577.     jmp    opt    ; continue option processing
  578.  
  579. ;  Option I -- enable it; inspect for FL option only
  580. opti:
  581.     mvi    a,0ffh    ; ON
  582.     sta    iflg
  583.     jmp    opt
  584.  
  585. ;  Option D -- enable it; Disk output
  586. optd:
  587.     mvi    a,0ffh    ; ON
  588.     sta    dflg
  589.     jmp    opt
  590.  
  591. ;  Option P -- enable it; Printer output
  592. optp:
  593.     mvi    a,0ffh    ; ON
  594.     sta    pflg
  595.     jmp    opt
  596.  
  597. ;  Option N -- enable it; Negate Selection
  598. optn:
  599.     mvi    a,0ffh    ; ON
  600.     sta    nflg
  601.     jmp    opt
  602.  
  603. ;  Option error message
  604. opterr:
  605.     xra    a    ; set no disk or printer output
  606.     sta    dflg
  607.     sta    pflg
  608.     call    banner    ; print banner
  609.     call    print
  610.     db    '     Invalid Option --> ',0
  611.     dcx    h    ; pt to first char
  612.     call    pstr    ; print string pted to by hl
  613.     call    print
  614.     db    cr,lf,'XDIR III command lines are:'
  615.     db    cr,lf,'        XDIR dir:filename.typ ooo...'
  616.     db    cr,lf,'or'
  617.     db    cr,lf,'        XDIR /oooo...'
  618.     db    cr,lf,'where:    dir: is optional and indicates selected '
  619.     db    'directory (DIR or DU form)'
  620.     db    cr,lf,'    filename.typ is an ambiguous file name and type '
  621.     db    '(also optional)'
  622.     db    cr,lf,'    o are option letters as follows:'
  623.     db    cr,lf,'        Aa - Set the file attributes'
  624.     db    cr,lf,'          a=S for System, a=N for Non-System'
  625.     db    cr,lf,'          a=A for All Files (System and Non-System)'
  626.     db    cr,lf,'        D  - Send Output to Disk File XDIR.DIR'
  627.     db    cr,lf,'        Ff - Enable a File Buffer Function'
  628.     db    cr,lf,'          f=L for Log Names to FNAMES.DIR'
  629.     db    cr,lf,'          f=P to Print Names stored in FNAMES.DIR'
  630.     db    cr,lf,'          f=S to Scan Disk and Compare to FNAMES.DIR'
  631.     db    cr,lf,'        G  - Toggle Grouping (name/type or type/name)'
  632.     db    cr,lf,'        H  - Toggle Horizontal or Vertical format'
  633.     db    cr,lf,'        I  - Inspect Logged Files (for FL Option Only)'
  634.     db    cr,lf,'        N  - Negate selection'
  635.     db    cr,lf,'        P  - Send display to printer'
  636.     db    cr,lf,' Options may be combined as desired',0
  637.  
  638. ;  Return to CP/M
  639. return:
  640.     lda    dflg    ; disk output?
  641.     ora    a    ; 0=no
  642.     cnz    fo0$close    ; close file if so
  643.     lhld    stack    ; get old stack ptr
  644.     sphl
  645.     ret        ; return to CP/M
  646.  
  647. ;  Memory Overflow Error
  648. memerr:
  649.     call    printx
  650.     db    cr,lf,'Not Enough Room in TPA -- Aborting',cr,lf,0
  651.     jmp    return
  652.  
  653. ;  Print banner of XDIR III
  654. banner:
  655.     call    printx
  656.     db    'XDIR III, Version '
  657.     db    vers/10+'0','.',(vers mod 10)+'0',0
  658.     ret
  659.  
  660. ;
  661. ;  Begin XDIR III processing
  662. ;
  663. xdir:
  664.  
  665. ;  This section disables the /Ff option and /FL option if default set
  666.     lda    fenab    ; enable FFLG? (/Ff option)
  667.     ora    a    ; 0=no
  668.     jnz    xdst1
  669.     xra    a    ; turn off FFLG
  670.     sta    fflg
  671. xdst1:
  672.     lda    lenab    ; enable FL option?
  673.     ora    a    ; 0=no
  674.     jnz    xdst2
  675.     lda    fflg    ; FFLG on?
  676.     ora    a    ; 0=no
  677.     jz    xdst2
  678.     lda    fopt    ; check for L
  679.     cpi    'L'
  680.     jnz    xdst2
  681.     mvi    a,'P'    ; switch L to P
  682.     sta    fopt
  683. xdst2:
  684.     lda    fflg    ; file name buffer option?
  685.     ora    a    ; 0=no
  686.     jz    xdirst
  687.     xra    a    ; A=0
  688.     sta    gflg    ; group by file name and type
  689.     lda    fopt    ; print immediately if P option
  690.     cpi    'P'    ; print?
  691.     jnz    xdirst
  692.     call    banner    ; print banner
  693.     jmp    xdirfp    ; print file names
  694.  
  695. ;  Get files from disk
  696. xdirst:
  697.     lda    pflg    ; printer output?
  698.     ora    a    ; 0=no
  699.     jz    xdirgo
  700.     call    print    ; message to user
  701.     db    cr,lf,'XDIR III Print -- Please Input Header: ',0
  702.     xra    a    ; no caps
  703.     call    bbline    ; input line from user
  704.     ora    a    ; no chars?
  705.     jz    xdirgo
  706.     call    lpstr    ; print header line
  707.     call    lcrlf    ; new line
  708. xdirgo:
  709.     call    crlf    ; new line on console
  710.     call    codend    ; end of code
  711.     call    dbuffer    ; set buffers
  712.     jz    memerr    ; memory overflow error?
  713.     push    h    ; save regs
  714.     push    d
  715.     call    dfree    ; compute amount of free space on disk
  716.     xchg        ; amount in hl
  717.     shld    freesiz    ; save free space count
  718.     pop    d    ; get regs
  719.     pop    h
  720.     call    dirsload    ; load with sizing information
  721.     jz    memerr    ; memory overflow error?
  722.     push    h    ; save hl
  723.     mov    h,b    ; HL=number of files loaded
  724.     mov    l,c
  725.     shld    totfil    ; save total count
  726.     push    b    ; save bc
  727.     lda    curdisk    ; prepare to relog in disk
  728.     mov    e,a
  729.     mvi    c,14    ; select disk
  730.     lda    disk    ; was disk changed?
  731.     cpi    0ffh    ; 0ffh if not
  732.     cnz    bdos
  733.  
  734. ;  Open disk file if necessary for disk output
  735.     lda    dflg    ; disk output?
  736.     ora    a    ; 0=no
  737.     jz    xdir0
  738.     lxi    d,dskfcb    ; open disk file for char output
  739.     call    fo0$open    ; open file for output
  740. xdir0:
  741.     pop    b    ; get count
  742.     pop    h    ; get ptr
  743.  
  744. ;  Continue processing; select desired files
  745.     lda    aflg    ; get file attributes
  746.     lxi    d,fcb    ; get ptr to fcb
  747.     call    dirsel    ; select files
  748.  
  749. ;  Now, pack and alphabetize directory
  750.     lda    nflg    ; negate selection?
  751.     ora    a    ; 0=no
  752.     cz    dirpack    ; select marked entries
  753.     cnz    dirnpack    ; select unmarked entries
  754.     lda    gflg    ; get grouping flag
  755.     call    diralpha    ; alphabetize directory
  756.     shld    firstf    ; save ptr to first file
  757.     mov    h,b    ; HL=file count
  758.     mov    l,c
  759.     shld    fcount    ; save file count
  760.     shld    countf    ; save file down count
  761.     lxi    h,0    ; set file size counter
  762.     shld    totsiz    ; save counter
  763.     lda    dflg    ; set temp flags
  764.     sta    dflgt
  765.     lda    pflg
  766.     sta    pflgt
  767.  
  768. ;
  769. ;  Major feature selection --
  770. ;    Two major features of XDIR are selected at this time:
  771. ;        1.  Directory Display Functions
  772. ;        2.  File Name Buffer Functions
  773. ;    At this point, the following key values are know:
  774. ;        FIRSTF - Pointer to First File
  775. ;        FCOUNT, COUNTF - Number of Files
  776. ;
  777.     lda    fflg    ; get flag
  778.     ora    a    ; Z=Directory Display, NZ=File Name Buffer Fcts
  779.     jnz    xdirf    ; Do File Name Buffer Fcts
  780.  
  781. ;
  782. ;  Main Directory Print Routine -- This routine displays the directory to
  783. ;  the console, printer, or disk as desired
  784. ;
  785. ;  Print header lines and one screen of entries
  786. xdir2:
  787.     lda    dflg    ; save disk and print output flags
  788.     sta    dflgs
  789.     lda    pflg
  790.     sta    pflgs
  791.     lda    dflgt    ; use temp flags
  792.     sta    dflg
  793.     lda    pflgt
  794.     sta    pflg
  795.     xra    a    ; A=0
  796.     sta    dflgt    ; clear temp flags so no banner 2nd time around
  797.     sta    pflgt
  798. ;  Print: Main Banner
  799.     call    banner    ; print banner
  800. ;  Print: Horizontal/Vertical Listing Message
  801.     call    printx
  802.     db    '    ',0
  803.     lda    hflg    ; get horizontal/vertical flag
  804.     ora    a    ; 0=vertical
  805.     jnz    xdir2a
  806.     call    printx
  807.     db    'Vertical',0
  808.     jmp    xdir3
  809. xdir2a:
  810.     call    printx
  811.     db    'Horizontal',0
  812. ;  Print: Listing by File Name and Type or Type and Name Message
  813. xdir3:
  814.     call    printx
  815.     db    ' Listing by File ',0
  816.     lda    gflg    ; grouping flag
  817.     ora    a    ; 0=name and type
  818.     jnz    xdir3a
  819.     call    printx
  820.     db    'Name and Type',0
  821.     jmp    xdir4
  822. xdir3a:
  823.     call    printx
  824.     db    'Type and Name',0
  825. ;  Print:  Disk and User
  826. xdir4:
  827.     call    printx    ; print everywhere
  828.     db    cr,lf,' Disk: ',0
  829.     lda    curdisk    ; get current disk
  830.     mov    c,a    ; ... in C
  831.     lda    disk    ; default disk?
  832.     cpi    0ffh
  833.     jz    xdir4a
  834.     dcr    a    ; adjust disk number for following conversion
  835.     mov    c,a    ; get selected disk
  836. xdir4a:
  837.     mov    a,c    ; print disk in C
  838.     adi    'A'    ; convert to ASCII
  839.     call    coutx    ; print everywhere
  840.     call    printx    ; print everywhere
  841.     db    '  User: ',0
  842.     lda    aflg    ; get user number
  843.     ani    20h    ; all?
  844.     jz    xdir4b
  845.     call    printx
  846.     db    'All',0
  847.     jmp    xdir5
  848. xdir4b:
  849.     lda    aflg    ; get selected user
  850.     ani    1fh    ; select user number
  851.     lxi    d,numbuf    ; store number in buffer
  852.     call    madc    ; get number
  853.     mvi    b,3    ; 3 digits
  854.     call    prnumx    ; print number everywhere
  855. ;  Print: Selected File Attributes
  856. xdir5:
  857.     call    printx
  858.     db    ', File Attributes: ',0
  859.     lda    aflg    ; get flag
  860.     push    psw    ; save A
  861.     ani    80h    ; Non-system?
  862.     jz    xdir5a
  863.     call    printx
  864.     db    ' Non-System',0
  865. xdir5a:
  866.     pop    psw    ; get A
  867.     ani    40h    ; System?
  868.     jz    xdir5b
  869.     call    printx
  870.     db    ' System',0
  871.  
  872. ;  See if any files selected
  873. xdir5b:
  874.     lhld    countf    ; get file down count
  875.     mov    a,h    ; any files?
  876.     ora    l
  877.     jnz    xdir6
  878.     call    printx    ; print everywhere
  879.     db    cr,lf,'No files selected',cr,lf,0
  880.     jmp    return
  881. xdir6:
  882.     lda    aflg    ; all users selected?
  883.     ani    20h
  884.     jnz    xdir6a
  885. ;
  886. ;  This is the header which is printed if the files in only one user area are
  887. ;    displayed
  888. ;
  889.     call    printx    ; specific user selected
  890.     db    cr,lf,cr,lf
  891.     db    'Filename.Typ Size K RS   '
  892.     db    'Filename.Typ Size K RS   '
  893.     db    'Filename.Typ Size K RS'
  894.     db    cr,lf
  895.     db    '-------- --- ------ --   '
  896.     db    '-------- --- ------ --   '
  897.     db    '-------- --- ------ --',0
  898.     jmp    xdir6b
  899. xdir6a:
  900. ;
  901. ;  This is the header which is printed if the files in all user areas are
  902. ;    displayed
  903. ;
  904.     call    printx    ; all users selected
  905.     db    cr,lf,cr,lf
  906.     db    ' U Filename.Typ Size K RS '
  907.     db    ' U Filename.Typ Size K RS '
  908.     db    ' U Filename.Typ Size K RS'
  909.     db    cr,lf
  910.     db    ' - -------- --- ------ -- '
  911.     db    ' - -------- --- ------ -- '
  912.     db    ' - -------- --- ------ --',0
  913.  
  914. ;  Prepare Columnar Output
  915. xdir6b:
  916.     lda    dflgs    ; restore disk and print flags
  917.     sta    dflg
  918.     lda    pflgs
  919.     sta    pflg
  920.     lhld    countf    ; get file count down
  921.     lxi    d,maxent    ; assume maxent entries to print
  922.     mov    a,h    ; within range?
  923.     ora    a    ; outside of range if not
  924.     jnz    xdir7    ; subtract entries to print from total entries
  925.     mov    a,l    ; within range?
  926.     cpi    maxent    ; less than maxent entries left?
  927.     jnc    xdir7    ; subtract entries to print from total entries
  928.     mov    d,h    ; DE=HL=number of entries to print
  929.     mov    e,l
  930. xdir7:
  931.     mov    a,l    ; subtract entries to print (DE) from total (HL)
  932.     sub    e
  933.     mov    l,a
  934.     mov    a,h
  935.     sbb    d
  936.     mov    h,a    ; HL=result
  937.     shld    countf    ; save new down count
  938.     mov    b,h    ; BC=count
  939.     mov    c,l
  940.     lhld    firstf    ; pt to first file
  941. ;
  942. ;  At this point, BC=number of remaining entries, DE=number of entries to
  943. ;    print, and HL pts to first entry to print
  944. ;
  945.     shld    ptr1    ; save ptr to 1st entry
  946.     lda    hflg    ; horizontal listing?
  947.     ora    a    ; 0ffh = yes
  948.     jnz    xdir7c    ; don't worry about columns if horizontal
  949.     push    d    ; save count
  950.     call    divde3    ; divide DE by 3, result*esize in BC, remainder in A
  951.     lxi    d,esize    ; DE=ESIZE (size of entry)
  952.     dad    b    ; add BC as a minimum
  953.     ora    a    ; any remainder?
  954.     jz    xdir7a    ; skip if none
  955.     dad    d    ; add in ESIZE for additional length of 1st col
  956. xdir7a:
  957.     shld    ptr2    ; save ptr to col 2
  958.     dad    b    ; add BC as a minimum
  959.     cpi    2    ; if remainder 2, add ESIZE for additional
  960.     jc    xdir7b
  961.     dad    d    ; add in ESIZE
  962. xdir7b:
  963.     shld    ptr3    ; save ptr to col 3
  964.     pop    d    ; get count in de
  965. ;
  966. ;  Main entry print routine
  967. ;
  968. xdir7c:
  969.     mvi    d,1    ; set 3's counter
  970. xdir8:
  971.     lhld    ptr1    ; pt to first entry
  972.     call    prentry    ; print entry
  973.     shld    ptr1    ; put ptr
  974.     lda    hflg    ; horizontal?
  975.     ora    a    ; 0ffh = yes
  976.     jnz    xdir9
  977.     dcr    e    ; count down
  978.     jz    xdir10
  979.     lhld    ptr2    ; get ptr
  980.     call    prentry    ; print entry
  981.     shld    ptr2    ; put ptr
  982.     dcr    e    ; count down
  983.     jz    xdir10
  984.     lhld    ptr3    ; get ptr
  985.     call    prentry    ; print entry
  986.     shld    ptr3    ; put ptr
  987. xdir9:
  988.     dcr    e    ; count down
  989.     jnz    xdir8    ; continue if not zero
  990.     shld    firstf    ; save ptr to first of next set of entries to print
  991.     lhld    countf    ; get count of remaining entries
  992. ;
  993. ;  At this point, HL=number of entries left
  994. ;
  995.     mov    a,h    ; anything left?
  996.     ora    l
  997.     jz    xdir10
  998.     call    print    ; screen break
  999.     db    cr,lf,'Screen Break -- Type any character to continue ',0
  1000.     call    cin    ; get response
  1001.     call    crlfx    ; new line
  1002.     call    crlfx    ; new line
  1003.     cpi    3    ; abort?
  1004.     jz    return
  1005.     jmp    xdir2    ; new screen display
  1006. ;
  1007. ;  Print end statistics and exit
  1008. ;
  1009. xdir10:
  1010.     call    crlfx    ; new line
  1011.     lhld    fcount    ; print file count
  1012.     call    prhlx    ; print it everywhere
  1013.     call    printx
  1014.     db    ' Files Occupying ',0
  1015.     lhld    totsiz    ; get total of file sizes
  1016.     call    prhlx    ; print it everywhere
  1017.     call    printx
  1018.     db    'K, ',0
  1019.     lhld    totfil    ; print total file count
  1020.     call    prhlx    ; print it everywhere
  1021.     call    printx
  1022.     db    ' Files on Disk and ',0
  1023.     lhld    freesiz    ; get amount of free space
  1024.     call    prhlx    ; print it everywhere
  1025.     call    printx
  1026.     db    'K Free',0
  1027.     lda    dflg    ; disk on?
  1028.     ora    a    ; 0=no
  1029.     jz    return
  1030.     mvi    a,cr    ; new line on disk
  1031.     call    f0$put
  1032.     mvi    a,lf
  1033.     call    f0$put
  1034.     jmp    return
  1035.  
  1036. ;
  1037. ;  File Name Buffer Functions
  1038. ;
  1039. xdirf:
  1040.     call    banner    ; print banner
  1041.     lda    iscn    ; just scan?
  1042.     ora    a    ; 0=no
  1043.     jnz    xdirfs
  1044.     lda    fopt    ; get option of F command
  1045.     cpi    'L'    ; log names to disk?
  1046.     jz    xdirfl
  1047.     cpi    'S'    ; scan names on disk?
  1048.     jz    xdirfs
  1049. ;
  1050. ;  File Name Print Option; /FP option
  1051. ;
  1052. xdirfp:
  1053.     call    openin    ; open FNAMES.DIR for input
  1054. xdfp0:
  1055.     call    printx
  1056.     db    cr,lf,cr,lf
  1057.     db    'Printout of Recorded File Names --',cr,lf,'     ',0
  1058. ;  Extract File Name Count
  1059.     call    f1$get    ; get low count
  1060.     jnz    geterr
  1061.     mov    l,a    ; save in L
  1062.     call    f1$get    ; get high count
  1063.     jnz    geterr
  1064.     mov    h,a    ; save in H
  1065.     push    h    ; save HL
  1066.     call    prhlx    ; print HL everywhere
  1067.     call    printx
  1068.     db    ' File Names Recorded',cr,lf,0
  1069.     call    prfhdr    ; print file name header
  1070.     pop    h    ; get HL
  1071.     mvi    c,0    ; set entry counter
  1072. ;  Loop for extracting names from FNAMES.DIR and printing them
  1073. xdfp1:
  1074.     mov    a,h    ; no more entries?
  1075.     ora    l
  1076.     jz    xdfp2
  1077.     dcx    h    ; count down
  1078.     call    getdfn    ; get next disk file name from FNAMES.DIR
  1079.     call    prfnfx    ; print file name entry
  1080.     inr    c    ; increment count
  1081.     mov    a,c    ; new line time?
  1082.     ani    3
  1083.     cz    crlfx
  1084.     jmp    xdfp1
  1085. xdfp2:
  1086.     call    fi1$close
  1087.     call    crlfx    ; new line
  1088.     jmp    return
  1089. ;
  1090. ;  Log File Names to Disk; /FL option
  1091. ;    Structure of FNAMES.DIR file is:
  1092. ;        File Name Count, Low-Order Byte
  1093. ;        File Name Count, High-Order Byte
  1094. ;        File Names, stored as 12 bytes -- User Number, FN, and FT
  1095. ;
  1096. xdirfl:
  1097.     lxi    d,fnfcb    ; open file for output
  1098.     call    fo1$open
  1099.     jz    xdfl1
  1100.     call    printx
  1101.     db    cr,lf,'Cannot Open FNAMES.DIR for Output -- Aborting',cr,lf,0
  1102.     jmp    return
  1103. ;  Log Files to Disk with possible initial inspect and select by user
  1104. xdfl1:
  1105.     lda    iflg    ; inspect?
  1106.     ora    a    ; 0=no
  1107.     cnz    flinsp    ; inspect if selected
  1108. ;  Print file count
  1109.     call    printx
  1110.     db    cr,lf,cr,lf
  1111.     db    'Logging File Names to Disk --',cr,lf,'     ',0
  1112.     lhld    fcount    ; get count
  1113.     call    prhlx    ; print it
  1114.     call    printx
  1115.     db    ' File Names to be Logged to Disk',cr,lf,0
  1116. ;  Check file count and print appropriate header
  1117.     lhld    fcount    ; get number of files
  1118.     mov    a,h    ; any files?
  1119.     ora    l
  1120.     jz    xdfl1a
  1121.     call    prfhdr    ; print file name header
  1122.     jmp    xdfl1b
  1123. xdfl1a:
  1124.     call    printx    ; no files
  1125.     db    '     No Files to be Logged',0
  1126. ;  Store file count to disk
  1127. xdfl1b:
  1128.     mov    a,l    ; store low count
  1129.     call    f1$put
  1130.     jnz    puterr
  1131.     mov    a,h    ; store high count
  1132.     call    f1$put
  1133.     jnz    puterr
  1134.     xchg        ; ... in DE
  1135.     lhld    firstf    ; pt to first file
  1136.     mvi    c,0    ; set display counter
  1137. ;  Loop to store files names
  1138. xdfl2:
  1139.     mov    a,d    ; done?
  1140.     ora    e
  1141.     jz    xdfl3
  1142.     dcx    d    ; count down
  1143. ;  Write entry to disk
  1144.     push    d    ; save count
  1145.     push    h    ; save ptr to file
  1146.     mov    a,m    ; get user number
  1147.     call    f1$put    ; save it
  1148.     jnz    puterr
  1149.     lxi    d,numbuf    ; print user number
  1150.     push    d    ; save ptr
  1151.     call    madc
  1152.     pop    d    ; get ptr
  1153.     inx    d    ; pt to 1st digit
  1154.     ldax    d    ; get it
  1155.     call    coutx
  1156.     inx    d    ; pt to last digit
  1157.     ldax    d    ; get it
  1158.     call    coutx
  1159.     mvi    a,' '    ; <SP>
  1160.     call    coutx
  1161.     inx    h    ; pt to FN
  1162.     mvi    b,8    ; 8 chars
  1163.     call    xdput
  1164.     mvi    a,'.'
  1165.     call    coutx
  1166.     mvi    b,3    ; 3 chars
  1167.     call    xdput
  1168.     mvi    a,' '    ; print <SP>
  1169.     call    coutx
  1170.     call    coutx
  1171.     inr    c    ; increment count
  1172.     mov    a,c    ; get count
  1173.     ani    3
  1174.     cz    crlfx
  1175.     pop    h    ; get ptr to first file
  1176.     pop    d    ; get count
  1177.     push    b
  1178.     lxi    b,esize    ; pt to next file
  1179.     dad    b
  1180.     pop    b
  1181.     jmp    xdfl2
  1182. ;  Done with creation of FNAMES.DIR
  1183. xdfl3:
  1184.     call    fo1$close    ; close file
  1185.     call    crlfx
  1186.     jmp    return
  1187. ;  Write B chars pted to by HL to FNAMES.DIR and user
  1188. xdput:
  1189.     mov    a,m    ; get char
  1190.     call    coutx    ; print it everywhere
  1191.     call    f1$put    ; put it on disk
  1192.     jnz    puterr
  1193.     inx    h    ; pt to next
  1194.     dcr    b    ; count down
  1195.     jnz    xdput
  1196.     ret
  1197.  
  1198. ;
  1199. ;  Inspect Files for Logging to Disk
  1200. ;
  1201. flinsp:
  1202.     lhld    fcount    ; get count of files
  1203.     xchg        ; ... in DE
  1204.     mov    a,d    ; any files selected?
  1205.     ora    e
  1206.     rz        ; abort if none
  1207. ;  Inspection banner
  1208.     call    printx
  1209.     db    cr,lf,'Inspection of Files for Logging to Disk',0
  1210.     lhld    firstf    ; pt to first file
  1211. ;  Main inspection loop
  1212. flil1:
  1213.     mov    a,d    ; any files selected?
  1214.     ora    e
  1215.     jz    flil3    ; done if not
  1216.     dcx    d    ; count down
  1217.     push    d    ; save count
  1218.     lxi    d,dfnbuf    ; copy file name to buffer
  1219.     mvi    b,12    ; 12 bytes
  1220.     call    moveb
  1221.     call    printx
  1222.     db    cr,lf,'Log ',0
  1223.     call    prfnfx    ; print file name for prompt
  1224.     call    printx
  1225.     db    ' to Disk (Y/N/<CR>=Y)? ',0
  1226.     call    cin    ; get response
  1227.     call    caps    ; capitalize
  1228.     call    coutx
  1229.     cpi    'N'    ; No?
  1230.     jz    flil2
  1231.     mov    a,m    ; mark user number
  1232.     ori    80h
  1233.     mov    m,a
  1234. flil2:
  1235.     lxi    d,esize    ; skip to next entry
  1236.     dad    d
  1237.     pop    d    ; get count
  1238.     jmp    flil1
  1239. flil3:
  1240.     lhld    fcount    ; get number of files
  1241.     mov    b,h    ; count in BC
  1242.     mov    c,l
  1243.     lhld    firstf    ; pt to first file
  1244.     call    dirpack    ; pack directory
  1245.     mov    h,b    ; new count in HL
  1246.     mov    l,c
  1247.     shld    fcount    ; set counts
  1248.     shld    countf
  1249.     ret
  1250.  
  1251. ;
  1252. ;  Error Message for Output
  1253. ;
  1254. puterr:
  1255.     call    printx
  1256.     db    cr,lf,'Error in Writing to Disk -- Aborting',cr,lf,0
  1257.     jmp    return
  1258.  
  1259. ;
  1260. ;  Scan Disk for File Names; /FS option
  1261. ;
  1262. xdirfs:
  1263.     call    printx
  1264.     db    cr,lf,'File Name Scanner',0
  1265.     call    openin    ; open FNAMES.DIR for input
  1266. xdfs1:
  1267.     call    printx
  1268.     db    cr,lf,'Files Named in FNAMES.DIR missing from Disk --',cr,lf,0
  1269. ;  Get file name count
  1270.     call    f1$get    ; get file name count from disk
  1271.     jnz    geterr
  1272.     mov    c,a    ; store low
  1273.     call    f1$get
  1274.     jnz    geterr
  1275.     mov    b,a    ; store high
  1276.     lhld    fcount    ; get count of number of files
  1277.     xchg        ; ... in DE
  1278.     lhld    firstf    ; pt to first file
  1279.     xra    a    ; A=0
  1280.     sta    crcnt    ; set counter for CRLF
  1281.     sta    fmark    ; mark no first file yet
  1282.  
  1283. ;
  1284. ;  At this point, HL pts to first file in buffer, DE is number of files in
  1285. ;    buffer, and BC is number of files in FNAMES.DIR
  1286. ;
  1287.     mov    a,b    ; any names in FNAMES.DIR?
  1288.     ora    c
  1289.     jz    xdfs5    ; mark all names in buffer if not
  1290.     call    getdfn    ; get first disk name
  1291. xdfs2:
  1292.     mov    a,b    ; see if any more files in FNAMES.DIR
  1293.     ora    c
  1294.     jz    xdfs5    ; mark rest of files in buffer and continue
  1295.     mov    a,d    ; see if any more files in buffer
  1296.     ora    e
  1297.     jz    xdfs6    ; name rest of files in FNAMES.DIR as missing and cont
  1298.     call    compfn    ; compare to file name pted to by HL
  1299.     jz    xdfs3a    ; advance to next file if they match
  1300.     jc    xdfs3    ; mark file name pted to by HL as additional
  1301.     lda    fmark    ; first file?
  1302.     ora    a    ; 0=yes
  1303.     jnz    xdfs2a
  1304.     mvi    a,0ffh    ; set mark
  1305.     sta    fmark
  1306.     call    prfhdr    ; print header
  1307. xdfs2a:
  1308.     call    prfnfx    ; print file name in FNAMES.DIR
  1309.     dcx    b    ; count down
  1310.     mov    a,b    ; done?
  1311.     ora    c
  1312.     jz    xdfs2
  1313.     call    getdfn    ; get next name
  1314.     lda    crcnt    ; get entry counter
  1315.     inr    a    ; increment
  1316.     sta    crcnt
  1317.     ani    3    ; mask
  1318.     cz    crlfx    ; new line every 4
  1319.     jmp    xdfs2
  1320. xdfs3:
  1321.     mov    a,m    ; get user number
  1322.     ori    80h    ; mark it
  1323.     mov    m,a    ; put it back
  1324.     jmp    xdfs4
  1325. xdfs3a:
  1326.     call    getdfn    ; get next name
  1327.     dcx    b    ; count down on names
  1328. xdfs4:
  1329.     push    d    ; save count
  1330.     lxi    d,esize    ; pt to next entry
  1331.     dad    d
  1332.     pop    d    ; get count
  1333.     dcx    d    ; count down
  1334.     jmp    xdfs2    ; continue
  1335. ;  Mark rest of files in buffer
  1336. xdfs5:
  1337.     mov    a,d    ; check count
  1338.     ora    e
  1339.     jz    xdfs7
  1340.     dcx    d    ; count down
  1341.     mov    a,m    ; get user number
  1342.     ori    80h    ; mark it
  1343.     mov    m,a    ; put user number
  1344.     lxi    b,esize    ; skip to next file
  1345.     dad    b
  1346.     jmp    xdfs5    ; continue
  1347. ;  Name rest of files in FNAMES.DIR as missing
  1348. xdfs6:
  1349.     call    prfnfx    ; print file name in FNAMES.DIR
  1350.     dcx    b    ; count down
  1351.     mov    a,b    ; done?
  1352.     ora    c
  1353.     jz    xdfs7    ; next phase
  1354.     lda    crcnt    ; get entry counter
  1355.     inr    a    ; increment
  1356.     sta    crcnt
  1357.     ani    3    ; mask
  1358.     cz    crlfx    ; new line every 4
  1359.     call    getdfn    ; get next name
  1360.     jmp    xdfs6
  1361. ;  Part 2 of Scan - Name Additional Files
  1362. xdfs7:
  1363.     lda    fmark    ; no files printed?
  1364.     ora    a    ; 0=none
  1365.     jnz    xdfs7a
  1366.     call    printx
  1367.     db    '   No Files Missing',0
  1368. xdfs7a:
  1369.     xra    a    ; A=0
  1370.     sta    fmark    ; set mark for 2nd part
  1371.     call    printx
  1372.     db    cr,lf,'Additional Files on Disk NOT in FNAMES.DIR --',cr,lf,0
  1373.     lhld    fcount    ; get count of files
  1374.     xchg        ; ... in DE
  1375.     lhld    firstf    ; pt to first file
  1376.     xra    a    ; A=0
  1377.     sta    crcnt    ; set counter
  1378. xdfs8:
  1379.     mov    a,d    ; check count
  1380.     ora    e
  1381.     jz    xdfs9    ; done if zero
  1382.     dcx    d    ; count down
  1383.     mov    a,m    ; get user number
  1384.     ani    80h    ; marked?
  1385.     jz    xdfs8b    ; skip if not
  1386.     mov    a,m    ; get user number
  1387.     ani    7fh    ; mask
  1388.     mov    m,a    ; replace
  1389.     lda    fmark    ; first time?
  1390.     ora    a    ; 0=yes
  1391.     jnz    xdfs8a
  1392.     mvi    a,0ffh    ; set mark
  1393.     sta    fmark
  1394.     call    prfhdr    ; print header
  1395. xdfs8a:
  1396.     push    d    ; save count
  1397.     lxi    d,dfnbuf    ; copy to buffer for print
  1398.     mvi    b,12    ; 12 bytes
  1399.     call    moveb    ; copy
  1400.     pop    d
  1401.     call    prfnfx    ; print file name
  1402.     lda    crcnt    ; count down
  1403.     inr    a
  1404.     sta    crcnt
  1405.     ani    3    ; new line?
  1406.     cz    crlfx
  1407. xdfs8b:
  1408.     lxi    b,esize    ; pt to next entry
  1409.     dad    b
  1410.     jmp    xdfs8    ; continue
  1411. ;  Done with Scan
  1412. xdfs9:
  1413.     lda    fmark    ; no files printed?
  1414.     ora    a    ; 0=none
  1415.     jnz    xdfs9a
  1416.     call    printx
  1417.     db    '   No Additional Files',0
  1418. xdfs9a:
  1419.     call    printx
  1420.     db    cr,lf,'File Scan Complete',cr,lf,0
  1421.     jmp    return
  1422.  
  1423. ;
  1424. ;  Compare file name pted to by HL with that in DFNBUF; return with Z if same,
  1425. ;    C if (HL)<(DFNBUF)
  1426. ;
  1427. compfn:
  1428.     push    h    ; save regs
  1429.     push    d
  1430.     push    b
  1431.     lxi    d,dfnbuf    ; pt to buffer
  1432.     xchg        ; DE pts to file name, HL pts to DFNBUF
  1433.     push    h    ; save ptrs
  1434.     push    d
  1435.     mvi    b,11    ; compare FN and FT
  1436. cfn1:
  1437.     inx    h    ; pt to next
  1438.     inx    d
  1439.     mov    a,m    ; get char from DFNBUF
  1440.     ani    7fh    ; mask MSB
  1441.     mov    c,a    ; save in C
  1442.     ldax    d    ; get name in memory buffer
  1443.     ani    7fh    ; mask MSB
  1444.     cmp    c    ; compare to name in DFNBUF
  1445.     jnz    cfn2    ; not same, so exit with flag set
  1446.     dcr    b    ; count down
  1447.     jnz    cfn1
  1448.     pop    d    ; same so far, so compare user numbers
  1449.     pop    h
  1450.     mov    a,m    ; get user number
  1451.     ani    7fh    ; mask MSB
  1452.     mov    c,a    ; save in C
  1453.     ldax    d    ; get user number
  1454.     ani    7fh    ; mask MSB
  1455.     cmp    c    ; compare
  1456.     push    h    ; fill stack for ext
  1457.     push    h
  1458. cfn2:
  1459.     pop    h    ; clear stack
  1460.     pop    h
  1461.     pop    b    ; get regs and exit
  1462.     pop    d
  1463.     pop    h
  1464.     ret
  1465.  
  1466. ;
  1467. ;  General Utility Routines
  1468. ;
  1469.  
  1470. ;
  1471. ;  Print user and file name stored in DFNBUF for /Ff functions
  1472. ;
  1473. prfnfx:
  1474.     push    h    ; save regs
  1475.     push    d
  1476.     push    b
  1477.     lxi    h,dfnbuf    ; pt to first byte of buffer
  1478.     mov    a,m        ; get first byte (user number)
  1479.     lxi    d,numbuf    ; convert to chars in memory
  1480.     call    madc
  1481.     lxi    d,numbuf+1    ; pt to first char
  1482.     ldax    d    ; get it
  1483.     call    coutx
  1484.     inx    d    ; pt to 2nd char
  1485.     ldax    d    ; get it
  1486.     call    coutx
  1487.     mvi    a,' '    ; <SP>
  1488.     call    coutx
  1489.     inx    h    ; pt to FN
  1490.     mvi    b,8    ; 8 chars for FN
  1491.     call    prch
  1492.     mvi    a,'.'
  1493.     call    coutx
  1494.     mvi    b,3    ; 3 chars for FT
  1495.     call    prch
  1496.     mvi    a,' '    ; 2 <SP>
  1497.     call    coutx
  1498.     call    coutx
  1499.     pop    b    ; get regs
  1500.     pop    d
  1501.     pop    h
  1502.     ret
  1503. ;
  1504. ;  Get next User Number, FN, and FT from disk and save it in buffer
  1505. ;
  1506. getdfn:
  1507.     push    h    ; save regs
  1508.     push    d
  1509.     push    b
  1510.     lxi    h,dfnbuf    ; pt to buffer
  1511.     mvi    b,12    ; 12 bytes
  1512. getdf1:
  1513.     call    f1$get    ; get user
  1514.     jnz    geterr
  1515.     mov    m,a    ; store user
  1516.     inx    h    ; pt to next
  1517.     dcr    b    ; count down
  1518.     jnz    getdf1
  1519.     pop    b    ; restore regs
  1520.     pop    d
  1521.     pop    h
  1522.     ret
  1523. ;
  1524. ;  Print File Buffer Names Header Everywhere
  1525. ;
  1526. prfhdr:
  1527.     call    printx
  1528.     db    '     Horizontal Listing by File Name and Type',cr,lf
  1529.     db    ' U Filename.Typ  '
  1530.     db    ' U Filename.Typ  '
  1531.     db    ' U Filename.Typ  '
  1532.     db    ' U Filename.Typ',cr,lf
  1533.     db    ' - -------- ---  '
  1534.     db    ' - -------- ---  '
  1535.     db    ' - -------- ---  '
  1536.     db    ' - -------- ---',cr,lf,0
  1537.     ret
  1538. ;
  1539. ;  Get Error Message and Abort
  1540. ;
  1541. geterr:
  1542.     call    printx
  1543.     db    cr,lf,'Premature EOF -- Aborting',cr,lf,0
  1544.     jmp    return
  1545. ;
  1546. ;  Open FNAMES.DIR for byte-oriented input
  1547. ;
  1548. openin:
  1549.     lxi    d,fnfcb    ; open file
  1550.     call    fi1$open    ; open for input
  1551.     rz
  1552.     call    printx
  1553.     db    cr,lf,'FNAMES.DIR Not Found -- Aborting',cr,lf,0
  1554.     jmp    return
  1555. ;
  1556. ;  Print disk entry for normal directory display functions
  1557. ;
  1558. prentry:
  1559.     dcr    d    ; count <CRLF> counter
  1560.     jnz    prent1
  1561.     mvi    d,3    ; reset count
  1562.     call    crlfx
  1563. prent1:
  1564.     shld    entptr    ; save entry ptr
  1565.     lda    aflg    ; all users selected?
  1566.     ani    20h
  1567.     jz    prent2
  1568. ;
  1569. ;  The following prints the user number if all user numbers are selected
  1570. ;
  1571.     push    h    ; save regs
  1572.     push    d
  1573.     push    b
  1574.     mov    a,m    ; get user number
  1575.     ani    1fh    ; mask it
  1576.     lxi    d,numbuf
  1577.     call    madc    ; convert to chars in memory
  1578.     lxi    h,numbuf+1    ; pt to first char
  1579.     mov    a,m    ; get it
  1580.     call    coutx
  1581.     inx    h    ; get 2nd char
  1582.     mov    a,m
  1583.     call    coutx
  1584.     mvi    a,' '    ; print <SP>
  1585.     call    coutx
  1586.     pop    b    ; get regs
  1587.     pop    d
  1588.     pop    h
  1589. prent2:
  1590.     inx    h    ; pt to first char of file name
  1591.     mvi    b,8    ; print 8 chars
  1592.     call    prch
  1593.     mvi    a,'.'    ; print dot
  1594.     call    coutx
  1595.     push    h    ; save RS ptr
  1596.     mvi    b,3    ; print 3 chars
  1597.     call    prch
  1598.     push    d    ; save de
  1599.     lhld    entptr    ; pt to entry
  1600.     mvi    a,' '    ; skip 2 spaces
  1601.     call    coutx
  1602.     call    coutx
  1603.     call    fsize    ; compute file size
  1604.     lhld    totsiz    ; get total file size counter
  1605.     dad    d    ; add in new file
  1606.     shld    totsiz    ; save new total file size counter
  1607.     xchg        ; get file size into HL
  1608.     call    prhlx    ; print HL value
  1609.     pop    d    ; get de
  1610.     pop    h    ; pt to RS
  1611.     mvi    a,' '    ; print 1 space
  1612.     call    coutx
  1613.     mvi    b,'R'    ; letter
  1614.     call    prletx    ; print R if bit set
  1615.     inx    h
  1616.     mvi    b,'S'    ; letter
  1617.     call    prletx    ; print S if bit set
  1618.     mvi    a,' '    ; 1 space
  1619.     call    coutx
  1620.     lda    aflg    ; all users?
  1621.     ani    20h
  1622.     jnz    prent3
  1623. ;
  1624. ;  The following prints 2 additional spaces if only one user area is selected
  1625. ;
  1626.     mvi    a,' '    ; 2 more spaces for not all users
  1627.     call    coutx
  1628.     call    coutx
  1629. prent3:
  1630.     lxi    b,6    ; pt to next entry
  1631.     dad    b
  1632.     ret
  1633. ;
  1634. ;  Print B chars pted to by HL
  1635. ;
  1636. prch:
  1637.     mov    a,m    ; get char
  1638.     inx    h    ; pt to next
  1639.     ani    7fh    ; mask out msb
  1640.     cpi    ' '    ; within range?
  1641.     jnc    prch1    ; print special char if not valid char
  1642.     mvi    a,'?'    ; print ? if not valid char
  1643. prch1:
  1644.     call    coutx    ; print it
  1645.     dcr    b    ; count down
  1646.     jnz    prch
  1647.     ret
  1648. ;
  1649. ;  Extended Print Routines
  1650. ;
  1651. prletx:
  1652.     mov    a,m    ; get byte
  1653.     ani    80h    ; look at msb
  1654.     jz    prlets
  1655.     mov    a,b    ; get letter
  1656.     call    coutx
  1657.     ret
  1658. prlets:
  1659.     mvi    a,' '    ; print <sp>
  1660.     call    coutx
  1661.     ret
  1662. prhlx:
  1663.     lxi    d,numbuf    ; store in number buffer
  1664.     call    mhldc    ; hl into memory as decimal
  1665.     mvi    b,5    ; 5 digits
  1666. prnumx:
  1667.     lxi    h,numbuf    ; pt to buffer
  1668. prnum:
  1669.     mov    a,m    ; get digit
  1670.     inx    h    ; pt to next
  1671.     call    coutx    ; print everywhere
  1672.     dcr    b    ; count down
  1673.     jnz    prnum
  1674.     ret
  1675. printx:
  1676.     xthl        ; pt to string
  1677. prxl:
  1678.     mov    a,m    ; get byte
  1679.     inx    h    ; pt to next
  1680.     ora    a    ; done?
  1681.     jz    prxld
  1682.     call    coutx    ; print everywhere
  1683.     jmp    prxl
  1684. prxld:
  1685.     xthl        ; set ret adr
  1686.     ret
  1687. coutx:
  1688.     push    b    ; save bc
  1689.     mov    b,a    ; char in B
  1690.     call    cout    ; print to screen
  1691.     lda    pflg    ; printer on?
  1692.     ora    a    ; 0=no
  1693.     mov    a,b    ; get char
  1694.     cnz    lout    ; printer output if on
  1695.     lda    dflg    ; disk on?
  1696.     ora    a    ; 0=no
  1697.     mov    a,b    ; get char
  1698.     cnz    f0$put    ; output to file
  1699.     pop    b
  1700.     ret
  1701. crlfx:
  1702.     push    psw    ; save A
  1703.     call    printx
  1704.     db    cr,lf,0
  1705.     pop    psw    ; get A
  1706.     ret
  1707. ;
  1708. ;  Divide DE by 3; return with BC=result*esize, a=remainder
  1709. ;
  1710. divde3:
  1711.     push    d    ; save de, hl
  1712.     push    h
  1713.     mvi    d,0    ; make sure D=0
  1714.     mov    a,e    ; value in A
  1715. divd31:
  1716.     sui    3    ; subtract 3
  1717.     jc    divd32
  1718.     jz    divd33
  1719.     inr    d    ; add 1 to result
  1720.     jmp    divd31
  1721. divd32:
  1722.     adi    3    ; add back in
  1723.     jmp    divd34
  1724. divd33:
  1725.     inr    d    ; add 1 for even division
  1726. divd34:
  1727.     sta    rem    ; save remainder
  1728.     lxi    b,esize
  1729.     lxi    h,0
  1730. divd35:
  1731.     mov    a,d    ; done?
  1732.     ora    a    ; 0=yes
  1733.     jz    divd36
  1734.     dcr    d
  1735.     dad    b    ; add in another ESIZE
  1736.     jmp    divd35
  1737. divd36:
  1738.     mov    b,h    ; BC is result
  1739.     mov    c,l
  1740.     lda    rem    ; A is remainder
  1741.     pop    h    ; restore regs
  1742.     pop    d
  1743.     ret
  1744. ;
  1745. ;  Skip blanks
  1746. ;
  1747. sblank:
  1748.     mov    a,m    ; pt to char
  1749.     cpi    ' '    ; blank?
  1750.     rnz
  1751.     inx    h    ; pt to next
  1752.     jmp    sblank
  1753.  
  1754.     end
  1755.