home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 15 / CDACTUAL15.iso / cdactual / program / asm / MISC_ASM.ZIP / LDIR.ASM < prev    next >
Encoding:
Assembly Source File  |  1991-03-25  |  32.3 KB  |  1,445 lines

  1.     page    74,132
  2.     title    --- ldir - list directory -
  3.  
  4. ;    LDIR (c) Copyright Vernon D. Buerg 1985-1991
  5. ;    ALL RIGHTS RESERVED.
  6.  
  7. dtantry struc                ; DTA entry returned by DOS
  8. dtarsvd db    21 dup (0)        ;  reserved
  9. dtaattr db    0            ;  attribute
  10. dtatime dw    0            ;  update time
  11. dtadate dw    0            ;  update date
  12. dtasize dw    0,0            ;  size bytes (lo,hi)
  13. dtaname db    12 dup (' ')            ;  name and ext
  14.     db    0,13,10,255        ;  stopper and print
  15. dtantry ends
  16.  
  17. argntry struc                ; Search arguments
  18. argdriv db    0,':'                   ;  drive
  19. argpath db    '\'                     ;  path delimiter
  20. argname db    64 dup (0),255        ;  path,file,ext
  21. argntry ends
  22.  
  23. tblntry struc                ; Table Entries
  24. tblattr db    0            ;  attribute
  25. tblpath db    21 dup (0)        ;  path name(s)
  26. tblname db    8 dup (' ')             ;  file name
  27. tbldot    db    ' '                     ;  delimiter
  28. tblext    db    3 dup (' ')             ;  extension
  29. tblsize db    ' 0000000 '             ; File size
  30. tbldate db    '80-01/01 '             ; Date
  31. tbltime db    ' 0:00 '                ; Time
  32. tblfatr db    3 dup (' ')             ; File attributes
  33. tblctl    db    13,10,255        ; print control chars
  34. tblntry ends
  35.  
  36. filntry struc                ; List of files in table
  37. filsub    db    0            ; -index to subdirectory name
  38. filattr db    0            ; -file attributes
  39. filtime dw    0            ; -time stamp
  40. fildate dw    0            ; -date stamp
  41. filsize dw    0,0            ; -file size
  42. filname db    12 dup ('?')            ; -asciiz file name
  43. filstop db    ?            ; -asciiz stopper
  44. filntry ends
  45.  
  46.  
  47. bios    segment at 40h        ; dos data area
  48.     org    84h        ;
  49. ega_row label    byte        ; rows on screen
  50. bios    ends
  51.  
  52. save    macro    reglist
  53.     irp    reg, <reglist>
  54.     push    reg        ; save register
  55.     endm
  56.     endm
  57.  
  58. return    macro    reglist
  59.     irp    reg, <reglist>
  60.     pop    reg        ; restore register
  61.     endm
  62.     ret            ; return to caller
  63.     endm
  64.  
  65.  
  66. cseg    segment public para 'CODE'
  67.     assume    cs:cseg, ds:cseg, es:nothing
  68.     org    100h
  69.  
  70. ldir    proc    far
  71.     jmp    start
  72.  
  73.     page
  74. ;
  75. ;    Usage information, display panel
  76.  
  77.     db    bs,bs,bs,'   ',cr,lf    ; in case TYPEd
  78.  
  79. help    db    cr,lf,tab,tab,' -- LDIR Version 4.4 --- 25 Mar 91 --'
  80.     db    cr,lf,tab,tab,'  (c) Copyright Vernon D. Buerg 1985-91'
  81.     db    cr,lf
  82.     db    cr,lf,tab,tab,tab,' Command syntax:'
  83.     db    cr,lf
  84.     db    cr,lf,tab,tab,'LDIR [d:][\path[fname[.ext]]] /?.../?'
  85.     db    cr,lf,tab,tab
  86.     db    cr,lf,tab,tab,'    /A   include Attributes'
  87.     db    cr,lf,tab,tab,'    /B   Brief headings'
  88.     db    cr,lf,tab,tab,'    /C   Clear screen first'
  89.     db    cr,lf,tab,tab,'    /D   sort by Date'
  90.     db    cr,lf,tab,tab,'    /F   sort by Filename (default)'
  91.     db    cr,lf,tab,tab,'    /H   include Hidden files'
  92.     db    cr,lf,tab,tab,'    /M   only Modified files'
  93.     db    cr,lf,tab,tab,'    /N   No sorting'
  94.     db    cr,lf,tab,tab,'    /P   include all Paths'
  95.     db    cr,lf,tab,tab,'    /S   sort by Size'
  96.     db    cr,lf,tab,tab,'    /V   Verbose headings'
  97.     db    cr,lf,tab,tab,'    /W   Wait after screen full'
  98.     db    cr,lf,tab,tab,'    /X   sort by eXtension'
  99.     db    cr,lf,tab,tab,'    /?   display usage syntax',Stopper
  100.     db    stopper,26
  101.  
  102.     page
  103. ;
  104. ;    Data Areas, Constants, Etc.
  105.  
  106. dta_len equ    size dtantry        ; DTA length
  107. arg_len equ    size argntry        ; Argument length
  108. tbl_len equ    size tblntry        ; Disk record entry
  109. fil_len equ    size filntry        ; File description entry
  110.  
  111. tblpara equ    tbl_len/16        ; paragraphs in each table entry
  112.  
  113. depth    equ    3            ; Maximum sub-DIR nest level
  114. tab    equ    9            ; A tabbie
  115. lf    equ    10            ; Line feed
  116. cr    equ    13            ; Carriage return
  117. stopper equ    255            ; Ends print strings
  118. bs    equ    8            ; Backspace
  119.  
  120. curdsk    equ    19h            ;Get current disk
  121. setdta    equ    1ah            ;Set data transfer area
  122. dskspc    equ    36h            ;Get disk free space
  123. chdir    equ    3bh            ;Change directory
  124. write    equ    40h            ;Write to a file handle
  125. getpath equ    47h            ;Get current directory
  126.  
  127. stackx    dw    0            ; Entry stack pointer
  128. dirmask db    0            ; Directory flags mask
  129. errlvl    db    0            ; DOS return code
  130. _attr    db    7            ; Clear attribute
  131. _page    db    0            ; Video page
  132. _rows    db    0            ; Rows on screen
  133.  
  134. flags    db    byname            ; Command switches
  135.  byattr  equ    1            ; -attributes included
  136.  byhide  equ    2            ; -want hidden files
  137.  byclear equ    4            ; -clear screen
  138.  bydate  equ    8            ; -sort by date/time
  139.  byext     equ    10h            ; -sort by extension
  140.  byname  equ    40h            ; -sort by name
  141.  bysize  equ    80h            ; -sort by size
  142.  
  143. flags2    db    0            ; More switches
  144.  bymod     equ    01h            ; -modified files only
  145.  bywait  equ    02h            ; -wait when screen full
  146.  bybrief equ    4            ; -four up
  147.  bypath  equ    20h            ; -all paths
  148.  byv     equ    40h            ; -verbose headings
  149.  
  150. date    record    yr:7,mo:4,dy:5        ; Packed date
  151. time    record    hour:5,min:6,sec:5    ; Packed time
  152.  
  153. anyname db    '\????????.???',0,stopper ;Global filename.ext
  154. subdir    db    '-Dir'
  155.  
  156. count    dw    0            ; Number of files
  157. numdir    dw    0            ; Number of table entries
  158. maxdir    dw    0            ; Maximum table entries
  159. nxtdir    dw    0            ; Offset to next entry
  160. segdir    dw    0            ; Segment addr of of gotten table
  161. numbyte dw    0,0            ;Total bytes used
  162. linecnt db    0            ;Line counter for /W
  163.  
  164. ddptr    dw    0
  165.  
  166.     page
  167. ;
  168. ;    Headings and titles
  169.  
  170. titlea    db    'List DIRectory            Volume: '
  171. volname db    11 dup (' '),11 dup (' ')
  172. month    db    'mm/'
  173. day    db    'dd/'
  174. year    db    'yy '
  175. hours    db    'hh:'
  176. mins    db    'mm:'
  177. secs    db    'ss',cr,lf,stopper
  178.  
  179. more    db    '... more',stopper
  180. backsp    db    8 dup (8),stopper    ; backspace over 'more'
  181.  
  182. titleb    db    tab,tab,tab,tab,'  '    ; Command parameters
  183. titles    db    64 dup (0),stopper    ; Current directory
  184.  
  185. titlec    db    cr,lf,'Filename Ext   Bytes  -Last Change-     '
  186. titled    db    'Filename Ext   Bytes  -Last Change-'
  187. newline db    lf,cr,stopper
  188.  
  189. nrmsg    db    cr,cr,'        '        ; Ending message
  190. nrbytes db    '         bytes in'
  191. nrfiles db    '         File(s); '
  192.     db    '         '
  193. nrsize    db    '         bytes free.',stopper
  194.  
  195.  
  196. extfcb    db    255,0,0,0,0,0        ; Extended FCB to get label
  197.     db    8            ; Attribute
  198. drivenr db    0,11 dup('?')           ; Drive number
  199.     db    2 dup(0)        ; Current block number
  200.     db    3 dup(0)        ; Logical record size
  201.     db    20 dup(0)        ; File size
  202.  
  203. temp    db    0            ; Sort exchange area
  204. origdr    db    'x:'                    ; Original drive
  205. origdir db    '\',63 dup (0)          ; and path
  206. origptr dw    origdir         ; End of orig path name
  207.  
  208. rootdir db    'x:\',0                 ; To get vol label
  209. olddate db    8 dup (0)        ;
  210. drptr    dw    offset parmdr        ;
  211.  
  212. model    tblntry <>            ; Model print line
  213.     page
  214. ;
  215. ;    Set default drive and path
  216.  
  217. start:
  218.     mov    sp,offset local_stack_end ; Use local stack
  219.     mov    word ptr stackx,sp      ; Save stack ptr for exiting
  220.     mov    ah,8            ; Get monitor stuff
  221.     int    10h            ;
  222.     mov    _page,0         ; -video page
  223.     mov    _attr,ah        ; -current attribute
  224.  
  225.     push    es            ; set dos data area
  226.     mov    ax,bios         ; segment address
  227.     mov    es,ax            ;
  228.     mov    al,byte ptr es:ega_row    ; dos rows on screen
  229.     mov    ah,24            ; default max rows
  230.     or    al,al            ; is row value ok?
  231.     jz    start1            ; no, use default
  232.     mov    ah,al            ; yes,
  233. start1:
  234.     mov    byte ptr _rows,ah    ; set max rows on screen
  235.     pop    es            ;
  236.  
  237.     call    switchs         ; Get program options
  238.  
  239.     mov    ah,13            ; Reset diskettes
  240.     int    21h            ;
  241.  
  242.     mov    ah,curdsk        ; Get current disk
  243.     int    21h            ;
  244.     add    al,'A'                  ;
  245.     mov    origdr,al        ; Save original drive letter
  246.     mov    rootdir,al        ;  for reading vol label
  247.     mov    parmdr,al        ;
  248.  
  249.     mov    dx,offset dta        ; Set Data Transfer Area
  250.     mov    ah,setdta        ;
  251.     int    21h            ;
  252.  
  253.     call    getparm         ; Get desired dr:path in 'parmdir'
  254.  
  255.     call    getvol            ; Get vol name, current dir in 'origdir'
  256.  
  257.     call    setarg            ; Set search argument
  258.  
  259.     call    alloc            ; Allocate table for directory
  260.  
  261.     call    clock            ; Date/time to heading
  262.  
  263.     call    getdir            ; Read the directory
  264.  
  265.     test    flags,bydate+byext+byname+bysize ; Any sort options?       ;4.4
  266.     jz    nosort            ; no, display fifo dir
  267.     call    sort            ; Sort directory table
  268.  
  269. nosort:
  270.     call    print            ; Display the entries
  271.  
  272.     mov    ax,count        ; Number of files
  273.     sub    dx,dx            ;
  274.     mov    si,offset nrfiles    ;
  275.     call    format            ;
  276.  
  277.     mov    dx,numbyte        ; Total bytes used
  278.     mov    ax,numbyte+2        ;
  279.     mov    si,offset nrbytes    ; target field
  280.     call    formatc         ; Make pretty
  281.     mov    dx,offset nrmsg     ; Display summary stats
  282.  
  283. exit:    mov    sp,cs:stackx        ; Insure exiting stack
  284.     call    prints            ; Display final message
  285.  
  286. done:    mov    sp,cs:stackx        ; Insure exiting stack
  287.     mov    al,errlvl        ; Return to system
  288.     mov    ah,4ch            ; via EXIT with error level
  289.     int    21h            ;
  290.  
  291. ldir    endp
  292.  
  293.     page
  294. ;
  295. ;    Set options from command line
  296.  
  297. switchs proc    near
  298.     mov    si,82h            ; Command tail
  299.     mov    dh,flags        ; Default switches
  300.     mov    dl,flags2
  301.     sub    cx,cx
  302.     or    cl,byte ptr -2[si]    ; test parm length
  303.     jz    switch_exit        ; none, return as-is
  304.  
  305. sw1:    lodsb                ; Scan for switch
  306.     cmp    al,'/'
  307.     loopne    sw1
  308.     or    cx,cx            ; found one?
  309.     jz    switch_exit
  310.     mov    byte ptr -1[si],cr    ; Stop string here
  311.     jmp    short sw2a
  312.  
  313. switch_exit:
  314.     mov    flags,dh        ; Store new switches
  315.     mov    flags2,dl
  316.     test    dh,byclear        ; Want clear screen?
  317.     jz    swx0            ;  no, skip next
  318.     call    cls            ;  yes
  319.  
  320. swx0:    mov    al,dirmask        ; Current directory attribute mask
  321.     test    flags,byhide        ;  include hidden files
  322.     jz    swx1
  323.     or    al,2
  324. swx1:    test    flags,byattr        ;  include display of attributes?
  325.     jz    swx2
  326.     or    al,7
  327. swx2:    test    flags2,bypath        ;  include sub-directories?
  328.     jz    swx3
  329.     or    al,16
  330. swx3:    mov    byte ptr dirmask,al    ; Update dir search criteria
  331.     ret
  332.  
  333. sw2:    lodsb
  334.     cmp    al,'/'                  ; Another switch?
  335.     loopne    sw2
  336.     jcxz    switch_exit
  337.  
  338. sw2a:    lodsb                ; yes, get letter following
  339.     dec    cx
  340.     jle    sw3            ; missing switch
  341.  
  342. sw3:    cmp    al,'?'                  ; Help?
  343.     jne    sw4
  344.     mov    dx,offset help
  345.     jmp    exit
  346.  
  347. sw4:    and    al,0dfh         ; Make option uppercase
  348.     cmp    al,'A'                  ; Attributes?
  349.     jne    sw5
  350.     or    dh,byattr
  351. sw5:    cmp    al,'B'                  ; Brief?
  352.     jne    sw6
  353.     or    dl,bybrief
  354. sw6:    cmp    al,'C'                  ; Clear?
  355.     jne    sw7
  356.     or    dh,byclear
  357. sw7:    cmp    al,'D'                  ; Date?
  358.     jne    sw8
  359.     or    dh,bydate
  360. sw8:    cmp    al,'X'                  ; Ext?
  361.     jne    sw9
  362.     or    dh,byext
  363. sw9:    cmp    al,'P'                  ; Paths?
  364.     jne    sw10
  365.     or    dl,bypath
  366. sw10:    cmp    al,'S'                  ; Size?
  367.     jne    sw11
  368.     or    dh,bysize
  369. sw11:    cmp    al,'H'                  ; Hidden?
  370.     jne    sw12
  371.     or    dh,byhide
  372. sw12:    cmp    al,'M'                  ; Modified only
  373.     jne    sw12b
  374.     or    dl,bymod
  375. sw12b:    cmp    al,'W'                  ; Wait when screen fills?
  376.     jne    sw12c
  377.     or    dl,bywait
  378. sw12c:    cmp    al,'F'                  ; Sort by filename?
  379.     jne    sw12d
  380.     or    dh,byname
  381. sw12d:    cmp    al,'N'                  ; No sorting?
  382.     jne    sw13
  383.     and    dh,0ffh-byname-byext-bysize-bydate
  384.  
  385. sw13:    cmp    al,'B'                  ; Brief headings?
  386.     jne    sw14            ;
  387.     or    flags2,byv        ;
  388. sw14:
  389.     jmp    sw2            ; Try for another option
  390.  
  391. switchs endp
  392.     page
  393. ;
  394. ;    Copy command parameters
  395.  
  396. getparm proc    near
  397.     mov    si,82h            ; Command tail
  398.     mov    di,offset parmdir    ; goes after d:\
  399.     sub    cx,cx            ;
  400.     or    cl,byte ptr -2[si]    ; any parmeters?
  401.     jz    parm9            ; no, use defaults
  402.  
  403. parm0:    cmp    byte ptr 1[si],':'      ; Drive specified?
  404.     jne    parm1            ;  no
  405.     mov    di,offset parmdr    ;  yes, replace drive letter
  406.  
  407. parm1:    lodsb                ; Skip leading blanks
  408.     cmp    al,' '                  ;
  409.     jne    parm3            ;
  410.     loope    parm1            ;
  411.     jcxz    parm9            ;
  412.  
  413. parm2:    lodsb                ; Copy d:\path\fname.ext
  414. parm3:    cmp    al,cr            ; end of string?
  415.     je    parm9            ;
  416.     cmp    al,' '                  ; end of operand?
  417.     jbe    parm9            ;
  418.     cmp    al,','                  ;
  419.     je    parm9            ;
  420.     stosb                ;
  421.     loop    parm2            ;
  422.  
  423. parm9:    and    byte ptr parmdr,0dfh    ; Upper case drive parm
  424.     mov    drptr,di        ; Save ptr to parm end
  425.     mov    al,0            ; Insure asciiz
  426.     stosb                ;
  427.     mov    al,parmdr        ;
  428.     mov    origdr,al        ;
  429.     mov    rootdir,al        ;
  430.     ret                ;
  431. getparm endp
  432.     page
  433. ;
  434. ;    Get volume label and disk free space
  435.  
  436. getvol    proc    near
  437.     mov    dl,parmdr        ; Get drive letter
  438.     sub    dl,64            ; and make it a number
  439.     mov    drivenr,dl        ;
  440.     mov    si,offset origdir+1    ; Save current path name
  441.     mov    ah,getpath        ;
  442.     int    21h            ;
  443.  
  444.     mov    al,0            ; Get end of path name
  445.     mov    di,offset origdir    ;
  446.     mov    cx,67            ;
  447.     repne    scasb            ;
  448.     sub    di,2            ;
  449.     mov    origptr,di        ;
  450.  
  451.     cmp    origdir+1,0        ; Already in root?
  452.     je    getvl3            ; yes, no chdir needed
  453.     inc    origptr         ;
  454.     mov    dx,offset rootdir    ; no, point to root directory
  455.     mov    ah,chdir        ;
  456.     int    21h            ;
  457.     jc    getvl9            ;
  458.  
  459. getvl3: mov    dx,offset extfcb    ; Search for volume entry
  460.     mov    ah,11h            ;
  461.     int    21h            ;
  462.  
  463.     or    al,al            ; Any found?
  464.     jnz    getvl4            ; no, tough
  465.     mov    cx,11            ; yes, copy it to heading
  466.     mov    si,offset dta+8     ;
  467.     mov    di,offset volname    ;
  468.     repz    movsb            ;
  469.  
  470. getvl4: cmp    origdir+1,0        ; Need to restore curdir?
  471.     je    getvl9            ;
  472.     mov    dx,offset origdr    ; Back to current dir
  473.     mov    ah,chdir        ;
  474.     int    21h            ;
  475.  
  476. getvl9:                 ; Get disk free space
  477.     mov    dl,parmdr        ; Current drive letter
  478.     sub    dl,64            ;  as a number
  479.     mov    ah,dskspc        ; Get free space
  480.     int    21h            ;
  481.     cmp    ax,0ffffh        ; Valid?
  482.     je    getvl10         ; no, skip it
  483.     mul    cx            ;  Bytes per cluster
  484.     mul    bx            ;  Total free
  485.     mov    si,offset nrsize    ; Format size
  486.     call    formatc         ;  with commas
  487.  
  488. getvl10:
  489.     ret                ;
  490. getvol    endp                ;
  491.     page
  492. ;
  493. ;    Set search criteria
  494.  
  495. setarg    proc    near
  496. set1:    mov    bp,offset dta        ; First DTA
  497.     mov    bx,offset search    ; Search arument entries
  498.  
  499.     mov    ax,word ptr parmdr    ; Set search drive
  500.     lea    di,[bx].argdriv     ;
  501.     stosw                ;
  502.  
  503. ;    parameter is possibly a filespec
  504.  
  505. set2:    cmp    byte ptr parmdir,'\'    ; path requested?
  506.     je    set8            ; yes, more than a filespec
  507.     mov    cx,origptr        ; no, set search path
  508.     mov    si,offset origdr+2    ;  from original path
  509.     sub    cx,si            ;
  510.     jcxz    set2a            ; In a subdir?
  511.     rep    movsb            ;
  512.     mov    al,'\'                  ; Add filespec delimiter
  513.     stosb                ;
  514.  
  515. set2a:    mov    si,offset parmdir    ; Copy filespec
  516.     mov    cx,drptr        ;  to search criteria
  517.     sub    cx,si            ;
  518.     jcxz    set5            ; None, append global filespec
  519.     rep    movsb            ;
  520.     jmp    set7            ; Done
  521.  
  522. ;    parameter is possibly a path\filespec
  523.  
  524. set8:    mov    dx,offset parmdr    ; Requested d:\path\filespec
  525.     mov    ah,chdir        ;
  526.     int    21h            ; Is parm a valid path name?
  527.     jc    set4            ;  no, have d:\path\filespec
  528.  
  529. set8a:    mov    dx,offset origdr    ; Restore path
  530.     mov    ah,chdir        ;
  531.     int    21h            ;
  532.  
  533.     mov    si,offset parmdir    ; Set search d:\path
  534.     mov    cx,drptr        ;  from command parameter
  535.     sub    cx,si            ;
  536.     jcxz    set5            ;
  537.     rep    movsb            ;
  538.     jmp    set5            ; Append global filespec
  539.  
  540. set4:    mov    si,offset parmdir    ; Set search d:\path
  541.     mov    cx,drptr        ;  from command parameter
  542.     sub    cx,si            ;
  543. set4a:    jcxz    set5            ;
  544.     rep    movsb            ;
  545.     jmp    set7            ; Done
  546.  
  547. ;    append global filespec to search criteria
  548.  
  549. set5:    mov    si,offset anyname    ; Add global search arg
  550.     cmp    byte ptr -1[di],'\'     ; Already have delimiter?
  551.     jne    set6            ;
  552.     dec    di            ; yes, overlay it
  553.  
  554. set6:    mov    cx,15            ; Length of global filespec
  555.     push    di            ; Save current end pointer
  556.     rep    movsb            ;
  557.     pop    di            ; Restore work reg
  558.     jmp    set9            ;
  559.  
  560. set7:    mov    al,0            ; Append ASCIIZ stopper
  561.     stosb                ;
  562.  
  563. set9:    lea    si,[bx].argdriv     ; Copy d:\path\filespec
  564.     mov    cx,di            ;
  565.     sub    cx,si            ;
  566.     mov    di,offset titles    ;  to titles
  567.     rep    movsb            ;
  568.     mov    byte ptr [di],stopper    ; Add print stopper
  569.  
  570. set10:    ret                ; Back to caller
  571.  
  572. setarg    endp
  573.     page
  574. ;
  575. ;    Obtain directory table
  576.  
  577. alloc    proc    near
  578.     push    bx            ; save registers
  579.     mov    bx,pgmsize        ; size of program module
  580.     mov    ah,4ah            ; modify memory
  581.     int    21h            ;
  582.     mov    bx,-1            ; ask for all remaining memory
  583. alloc1:
  584.     mov    ah,48h            ; allocate memory
  585.     int    21h            ;
  586.     jc    alloc1            ; get what there is
  587.  
  588.     mov    segdir,ax        ; segment addr of table
  589.     mov    nxtdir,0        ; offset to first entry
  590.  
  591.     shr    bx,1            ; change number of paragraphs
  592.     shr    bx,1            ;  to 64-byte entries
  593.     mov    maxdir,bx        ; maximum table count
  594.     pop    bx            ; restore registers
  595.     ret                ;
  596. alloc    endp
  597.  
  598.     page
  599. ;
  600. ;    Build table of directory entries
  601.  
  602. getdir    proc    near
  603.     push    bp            ; Ptr to DTA
  604.     push    bx            ; Ptr to search are
  605.  
  606. ; Set DTA for current nesting level
  607.     mov    dx,bp            ; Data transfer area
  608.     mov    ah,setdta        ; Set local DTA
  609.     int    21h
  610.  
  611. ; Set search criteria for this level
  612.     mov    dx,bx            ; Search criteria
  613.     sub    cx,cx            ; Directory options
  614.     mov    cl,dirmask
  615.     mov    ah,4eh            ; Find first matching entry
  616.     int    21h
  617.  
  618. ; Examine directory entry just returned
  619. get1:    or    al,al
  620.     jnz    gotdir            ; Not found, quit looking.
  621.     cmp    byte ptr [bp].dtaattr,10h
  622.     jne    get3            ; Is it a sub-dir?
  623.     cmp    byte ptr [bp].dtaname,'.'
  624.     je    get4            ; May be <DIR> entry
  625.  
  626.     call    addfile         ; Add directory entry to table
  627.  
  628. ; Build parms for sub-dir search
  629.     lea    dx,[bp].dtaname     ; Save ptr to found name
  630.     lea    si,[bx].argdriv     ; Point to current arg
  631.     add    bp,dta_len        ; Next DTA
  632.     add    bx,arg_len        ; Next search arg
  633.  
  634. ; Copy previous arg as next search arg
  635.     mov    cx,64            ; Maximum length
  636.     lea    di,[bx].argdriv     ; Point to new search arg
  637. get6:    lodsb                ;
  638.     cmp    al,'?'                  ; Used global name?
  639.     je    get9            ;  yes, single nest
  640.     cmp    al,0            ; End of dir name?
  641.     je    get5            ;  yes, append wild cards
  642.     stosb                ;
  643.     loop    get6            ; Continue copying
  644.  
  645. ; Add sub-dir name to search arg
  646. get9:    mov    si,dx            ; Saved ptr to found name
  647. get8:    lodsb                ;
  648.     cmp    al,0            ; End of DIR name?
  649.     je    get5            ;  yes, append wild cards
  650.     stosb                ;  no, add to arg
  651.     loop    get8            ; Continue copying fname
  652.  
  653. get5:    mov    si,offset anyname    ; Append wild cards
  654.     rep    movsb            ;
  655.  
  656.     call    getdir            ; Search the sub-dir
  657.     sub    bx,arg_len        ; restore arg
  658.     sub    bp,dta_len        ; and DTA
  659.  
  660. ; Restore DTA to find next matching entry
  661.     mov    dx,bp            ; Data transfer area
  662.     mov    ah,setdta        ; Set DTA
  663.     int    21h            ;
  664.     jmp    short get4        ;
  665.  
  666. get3:    call    addfile         ; Add the entry
  667.  
  668. get4:    mov    cx,12            ; Clear found name
  669.     mov    al,' '                  ;
  670.     lea    di,[bp].dtaname     ; Point to file name area
  671.     rep    stosb            ;
  672.  
  673.     mov    ah,4fh            ; Search for next file
  674.     mov    dx,bp            ;
  675.     int    21h            ;
  676.     jmp    get1            ; Loop for next one
  677.  
  678. gotdir: pop    bx            ; Restore arg
  679.     pop    bp            ;  and DTA
  680.     ret                ; Return to caller
  681. getdir    endp                ;
  682.     page
  683. ;
  684. ;    Add a directory entry to table
  685.  
  686. addfile proc    near
  687.     save    <cx,bp,di,si>        ; Save registers
  688.  
  689.     mov    cx,tbl_len        ; Initialize table entry
  690.     mov    si,offset model     ;
  691.     mov    di,offset pline     ;
  692.     rep    movsb            ;
  693.  
  694.     mov    al,[bp].dtaattr     ; Copy file attributes
  695.     mov    pline.tblattr,al    ;
  696.     test    flags2,bymod        ; Just modified files?
  697.     jz    addfile1        ;  no, add all
  698.     test    al,10h            ;  yes, pass subdirs
  699.     jnz    addfile1        ;
  700.     test    al,20h            ; is it modified tho?
  701.     jnz    addfile1        ; yes, add the entry
  702.     jmp    addfile11        ; no, exit
  703.  
  704. addfile1:
  705.     call    getdate         ; Format date
  706.     call    gettime         ;  time
  707.     call    getsize         ;  bytes
  708.  
  709.     lea    si,[bp].dtaname     ; Copy file name
  710.     lea    di,pline.tblname    ;
  711.     mov    cx,12            ;
  712. addfile2:
  713.     lodsb                ;
  714.     cmp    al,0            ;
  715.     je    addfile5        ;
  716.     cmp    al,'.'                  ; separate extension
  717.     je    addfile3        ;
  718.     stosb                ;
  719.     loop    addfile2        ;
  720. addfile3:
  721.     jcxz    addfile5        ;
  722.     lea    di,pline.tblname+8    ;
  723. addfile4:
  724.     stosb                ;
  725.     lodsb                ;
  726.     cmp    al,0            ;
  727.     je    addfile5        ;
  728.     loop    addfile4        ;
  729.  
  730. addfile5:
  731.     lea    di,pline.tblpath    ; Copy path name
  732.     lea    si,[bx].argname     ;
  733.     mov    cx,size tblpath     ;
  734. addfile6:
  735.     cmp    byte ptr 1[si],'?'      ; Wildcard part?
  736.     je    addfile7        ; yes, have name
  737.     lodsb                ;
  738.     stosb                ;
  739.     loop    addfile6        ;
  740.  
  741. addfile7:
  742.     lea    si,pline.tblname    ;
  743.     test    pline.tblattr,10h    ; Subdirectory?
  744.     jnz    addfile8        ;  yes, copy path name
  745.     jcxz    addfile10        ;  no, pad with blanks
  746.     mov    al,' '                  ;
  747.     rep    stosb            ;
  748.     jmp    addfile10        ;
  749.  
  750. addfile8:
  751.     cmp    cl,12            ; Max subdir name length
  752.     jbe    addfile9        ; to be copied
  753.     mov    cl,12            ;
  754. addfile9:
  755.     rep    movsb            ;
  756.  
  757. addfile10:
  758.     mov    cx,numdir        ; Number of table entries
  759.     cmp    cx,maxdir        ; is table full?
  760.     jae    addfile11        ;  yes, skip it
  761.     push    es            ;  no, add to table
  762.     mov    ax,word ptr segdir    ; Segment addr of table
  763.     add    ax,nxtdir        ; plus next entry offset
  764.     sub    di,di            ;
  765.     mov    si,offset pline     ; copy table stuff
  766.     mov    cx,tbl_len        ;
  767.     mov    es,ax            ; Set target segment
  768.     rep    movsb            ;
  769.     pop    es            ;
  770.  
  771.     inc    numdir            ; Incr entry count
  772.     add    nxtdir,tblpara        ; Bump offset for next table entry
  773.  
  774. addfile11:
  775.     return    <si,di,bp,cx>        ; restore registers
  776. addfile endp
  777.     page
  778. ;
  779. ;    Print file information
  780.  
  781. print    proc    near
  782.     cmp    numdir,1        ; Just one file?
  783.     ja    printt            ;  no, two up heading
  784.     mov    word ptr titled,0a0dh    ;
  785.     mov    titled+2,stopper    ;
  786.  
  787. printt:
  788.     test    flags2,byv        ; Want headings?
  789.     jnz    printv            ;  no
  790.     add    linecnt,3        ;  yes
  791.     mov    dx,offset titlea    ; Top titles
  792.     call    prints            ;
  793.     mov    dx,offset titleb    ; Subdir name
  794.     call    prints            ;
  795.     mov    dx,offset titlec    ; Headings
  796.     call    prints            ;
  797. printv:
  798.     mov    ax,cs            ; Set extra seg
  799.     mov    es,ax            ;  locally
  800.  
  801.     sub    ax,ax            ; Offset to first table entry
  802.     mov    nxtdir,ax        ;  as current entry
  803.     mov    ax,numdir        ; Compute offset
  804.     inc    ax            ;  to second half
  805.     shr    ax,1            ;
  806.     mov    cl,2            ; Times 64 (4 paras each)
  807.     shl    ax,cl            ;
  808.     mov    cx,numdir        ; Number of entries
  809.     or    cx,cx            ; Even number of entries?
  810.     jz    print7            ; yes, all set
  811.     inc    cx            ; no, just one
  812.     shr    cx,1            ; Set half of count
  813.  
  814. print_next:
  815.     call    print0            ; Left side
  816.     push    [nxtdir]        ;
  817.     add    nxtdir,ax        ;
  818.     call    print0            ; Right side
  819.     pop    [nxtdir]        ;
  820.  
  821.     add    nxtdir,tblpara        ; Point to next entry
  822.  
  823.     test    flags2,bywait        ; Wait for screen full?
  824.     jz    printw1         ;  no, continue
  825.     inc    linecnt         ;  yes, bump line count
  826.     mov    dl,_rows        ; rows available on screen
  827.     cmp    linecnt,dl        ; Full now?
  828.     jb    printw1         ;  no, continue
  829.     call    waitkey         ;  yes, get a key
  830.  
  831. printw1:
  832.     loop    print_next        ; continue for all entries
  833. print7:
  834.     ret                ; done, return
  835. print    endp                ;
  836.  
  837.  
  838. print0    proc    near
  839.     save    <ax,cx,di>        ; Save registers
  840.  
  841.     push    ds            ; copy table entry to print line
  842.     mov    cx,tbl_len        ; length of table entry
  843.     sub    si,si            ; offset to next entry
  844.     mov    di,offset pline     ; offset to print line
  845.     mov    ax,word ptr segdir    ; Segment addr for table
  846.     add    ax,nxtdir        ;  plus paras offset
  847.     mov    ds,ax            ;   as source segment
  848.     rep    movsb            ;    for copy
  849.     pop    ds            ;
  850.  
  851.     inc    count            ; Number of files
  852.     mov    ax,count        ;
  853.     cmp    ax,numdir        ; Done em all?
  854.     jbe    print1            ; no, display this one
  855.     dec    count            ; yes,
  856.     jmp    print9            ;  done, return
  857.  
  858. print1:
  859.     mov    cl,byte ptr pline.tblattr
  860.     lea    di,byte ptr pline.tblfatr
  861.  
  862.     test    cl,32            ; Archived?
  863.     jnz    print2            ;
  864.     mov    al,'A'                  ;
  865.     stosb                ;
  866.  
  867. print2: test    cl,4            ; System?
  868.     jz    print3            ;
  869.     mov    al,'S'                  ;
  870.     stosb                ;
  871.  
  872. print3: test    cl,2            ; Hidden?
  873.     jz    print4            ;
  874.     mov    al,'H'                  ;
  875.     stosb                ;
  876.  
  877. print4: test    cl,1            ; Read only?
  878.     jz    print5            ;
  879.     mov    al,'R'                  ;
  880.     stosb                ;
  881.  
  882. print5: test    cl,10h            ; Sub directory?
  883.     jz    print5a         ; no
  884.     lea    di,pline.tblfatr-1    ; yes, special display
  885.     mov    si,offset subdir    ;
  886.     mov    cx,4            ;
  887.     rep    movsb            ;   for copying
  888.  
  889. print5a:
  890.     test    flags2,bypath        ; Doing all paths?
  891.     jz    print6            ;
  892.     cmp    pline.tblpath+1,'?'     ; Nested entry?
  893.     je    print6            ;  no, as-is
  894.     mov    pline.tblfatr-1,'-'     ;  yes, flag it in display
  895.  
  896. print6: lea    si,pline.tbldate    ; Reformat date
  897.     mov    di,offset olddate    ;   for copying
  898.     mov    cx,8            ;
  899.     rep    movsb            ;
  900.  
  901.     lea    di,pline.tbldate    ; Format date
  902.     mov    ax,word ptr olddate+3    ;
  903.     stosw                ;
  904.     mov    al,"/"                  ;
  905.     stosb                ;
  906.     mov    ax,word ptr olddate+6    ;
  907.     stosw                ;
  908.     mov    al,"/"                  ;
  909.     stosb                ;
  910.     mov    ax,word ptr olddate    ;
  911.     stosw                ;
  912.  
  913.     cmp    pline.tblext,' '        ; Any extension?
  914.     jne    print8            ;  yes, leave the dot
  915.     mov    pline.tblext-1,' '      ;  no, rid it
  916.  
  917. print8: lea    dx,pline.tblname    ;
  918.     mov    byte ptr pline.tblctl,' '
  919.     mov    byte ptr pline.tblctl+1,stopper
  920.     mov    byte ptr nrmsg+1,lf    ;
  921.     test    count,1         ; Right side?
  922.     jnz    print8a         ;
  923.     mov    byte ptr nrmsg+1,cr    ;
  924.     mov    word ptr pline.tblctl,0a0dh
  925. print8a:
  926.     call    prints            ; Display an entry
  927.  
  928. print9:
  929.     return    <di,cx,ax>        ; Restore registers
  930. print0    endp
  931.  
  932.     page
  933. ;
  934. ;    Pause at end of screen for any key
  935.  
  936. waitkey proc    near
  937.     save    <ax,bx,cx,dx>        ; save work regs
  938.  
  939.     mov    linecnt,0        ; reset counter
  940.     mov    ah,2            ; Set cursor position
  941.     mov    dl,0            ;  col 72
  942.     mov    dh,_rows        ;  last row
  943. ;;    add    dh,2            ;  adjust for heading
  944.     sub    bx,bx            ;
  945.     int    10h            ;
  946.  
  947.     mov    dx,offset more        ; ask for more
  948.     call    prints            ;
  949.  
  950.     mov    ah,0            ; wait for a key
  951.     int    16h            ;
  952.  
  953.     mov    dx,offset backsp    ; backspace over 'more...'
  954.     call    prints            ;
  955.  
  956.     test    flags,byclear        ; Clear screen each time?
  957.     jz    waitkeyc        ;  no
  958.     call    cls            ; Clear screen
  959. waitkeyc:
  960.     test    flags2,byv        ; need headings again?
  961.     jnz    waitkeyx        ;  no
  962.     add    linecnt,3        ;  yes
  963.     mov    dx,offset titlea    ; Top titles
  964.     call    prints            ;
  965.     mov    dx,offset titleb    ; Subdir name
  966.     call    prints            ;
  967.     mov    dx,offset titlec    ; Headings
  968.     call    prints            ;
  969.  
  970. waitkeyx:
  971.     return    <dx,cx,bx,ax>        ; restore registers
  972. waitkey endp
  973.     page
  974. ;
  975. ;    Format the date
  976.  
  977. getdate proc    near            ;Format the date
  978.     mov    ax,word ptr [bp].dtadate
  979.     mov    di,offset pline.tbldate
  980.     or    ax,ax            ;Is it zero?
  981.     jz    gotdate
  982.     push    ax            ;Save date
  983.     and    ax,mask yr        ;Get year part
  984.     mov    cl,yr            ;Bits to shift
  985.     call    cnvrt
  986.     or    al,'8'                  ;Adjust for base year
  987.     stosw
  988.     mov    al,'-'
  989.     stosb
  990.  
  991.     pop    ax            ;Get the date back
  992.     push    ax            ;Save it
  993.     and    ax,mask mo        ;Get month part
  994.     mov    cl,mo            ;Bits to shift
  995.     call    cnvrt2
  996.     stosw
  997.     mov    al,'/'
  998.     stosb
  999.  
  1000.     pop    ax            ;Get the date back
  1001.     and    ax,mask dy        ;Get day part
  1002.     mov    cl,dy            ;Bits to shift
  1003.     call    cnvrt
  1004.     stosw
  1005. gotdate:ret
  1006. getdate endp
  1007.  
  1008.     page
  1009. ;
  1010. ;    Format the time
  1011.  
  1012. gettime proc    near            ; Format the date
  1013.     mov    ax,word ptr [bp].dtatime;
  1014.     lea    di,pline.tbltime    ;
  1015.     or    ax,ax            ; It is zero?
  1016.     jz    gottime         ;
  1017.     push    ax            ; Save date
  1018.     and    ax,mask hour        ; Get hour part
  1019.     mov    cl,hour         ; Bits to shift
  1020.     shr    ax,cl            ;
  1021.     call    cnvrt1            ;
  1022.     stosw                ;
  1023.     mov    al,':'                  ;
  1024.     stosb                ;
  1025.  
  1026. gt3:    pop    ax            ; Get the time back
  1027.     and    ax,mask min        ; Get min part
  1028.     mov    cl,min            ; Bits to shift
  1029.     call    cnvrt            ;
  1030.     stosw                ;
  1031. gottime:
  1032.     ret                ;
  1033. gettime endp
  1034.  
  1035. cnvrt2    proc    near            ; Convert to ASCII
  1036.     call    cnvrt            ;
  1037.     cmp    al,'0'                  ; Suppress leading zero
  1038.     jne    cnvrtd            ;
  1039.     mov    al,' '                  ;
  1040.     ret                ;
  1041.  
  1042. cnvrt:    shr    ax,cl            ;
  1043. cnvrt1: aam                ; Make AL into BCD
  1044.     or    ax,'00'                 ; and to ASCII
  1045.     xchg    al,ah            ;
  1046. cnvrtd: ret                ;
  1047. cnvrt2    endp                ;
  1048.     page
  1049. ;
  1050. ;    Format the size
  1051.  
  1052. getsize proc    near
  1053.     save    <bp,bx>         ; Ptr to Dta entry
  1054.     mov    ax,word ptr [bp].dtasize;
  1055.     add    numbyte+2,ax        ;
  1056.     mov    dx,word ptr [bp].dtasize+2
  1057.     adc    numbyte,dx        ;
  1058.     lea    si,pline.tblsize    ; Target offset
  1059.     call    format            ; Format double word
  1060.     return    <bx,bp>         ;
  1061. getsize endp
  1062.  
  1063.     page
  1064. ;
  1065. ;    Format ASCII numbers from binary
  1066.  
  1067. format    proc    near            ; Formats a 32 bit integer in DX:AX
  1068.     save    <bp,bx,di,si>        ; to DS:SI
  1069.     mov    ddptr,si        ; addr of target field
  1070.     mov    di,dx            ; subroutine uses di:si
  1071.     mov    si,ax
  1072.     call    printdd
  1073.     return    <si,di,bx,bp>
  1074.  
  1075. printdd:
  1076.     xor    ax,ax        ;zero out the
  1077.     mov    bx,ax        ; working
  1078.     mov    bp,ax        ; registers.
  1079.     mov    cx,32        ;# bits of precision
  1080. j1:    shl    si,1
  1081.     rcl    di,1
  1082.     xchg    bp,ax
  1083.     call    j6
  1084.     xchg    bp,ax
  1085.     xchg    bx,ax
  1086.     call    j6
  1087.     xchg    bx,ax
  1088.     adc    al,0
  1089.     loop    j1
  1090.     mov    cx,1710h
  1091.     mov    ax,bx
  1092.     call    j2
  1093.     mov    ax,bp
  1094. j2:    push    ax
  1095.     mov    dl,ah
  1096.     call    j3
  1097.     pop    dx
  1098. j3:    mov    dh,dl
  1099.     shr    dl,1        ;move high
  1100.     shr    dl,1        ; nibble to
  1101.     shr    dl,1        ; the low
  1102.     shr    dl,1        ; position.
  1103.     call    j4
  1104.     mov    dl,dh
  1105. j4:    and    dl,0fh        ;mask low nibble
  1106.     jz    j5        ;if not zero
  1107.     sub    cl,cl
  1108. j5:    dec    ch
  1109.     and    cl,ch
  1110.     or    dl,'0'          ;fold in ascii zero
  1111.     sub    dl,cl
  1112.     mov    bx,ddptr
  1113.     mov    [bx],dl     ;ptr to next target field
  1114.     inc    ddptr
  1115.     ret
  1116.  
  1117. j6:    adc    al,al
  1118.     daa
  1119.     xchg    al,ah
  1120.     adc    al,al
  1121.     daa
  1122.     xchg    al,ah
  1123.     ret
  1124. format    endp
  1125.  
  1126.     page
  1127. ;
  1128. ;    Binary to ASCII numbers with commas
  1129. ;
  1130. ;    DX:AX has value to convert
  1131. ;    SI points to target area, 11-bytes
  1132.  
  1133. formatc proc    near            ;
  1134.     push    si            ; Save parameters
  1135.     mov    bx,si            ;
  1136. fs1:    mov    cx,10000        ; Get 10K
  1137.     div    cx            ;
  1138.     push    ax            ;
  1139.     mov    ax,dx            ;
  1140.     sub    dx,dx            ;
  1141.     mov    si,bx            ; Point to msg
  1142.     call    format            ; Rightmost 4 digits
  1143.  
  1144. fs1a:    pop    ax            ; get 10k
  1145.     sub    dx,dx            ;
  1146.     or    ax,ax            ;
  1147.     jz    fs1x            ; none left
  1148.     or    word ptr 3[bx],'00'     ;
  1149. fs1b:    mov    cx,word ptr 3[bx]    ; insert a comma
  1150.     mov    byte ptr 4[bx],','      ;
  1151.     mov    word ptr 2[bx],cx    ;
  1152.     mov    cx,1000         ; compute 10m
  1153.     div    cx            ;
  1154. fs1c:    push    ax            ; save 10m
  1155.     mov    ax,dx            ; copy 10k
  1156.     sub    dx,dx            ;
  1157.     lea    si,-5[bx]        ;
  1158.     call    format            ; middle 3 digits
  1159.     cmp    byte ptr [bx],' '       ; millions?
  1160.     je    fs1d            ;
  1161.     mov    cx,word ptr -1[bx]    ; insert a comma
  1162.     mov    byte ptr [bx],','       ;
  1163.     mov    word ptr -2[bx],cx    ;
  1164.     or    word ptr 1[bx],'00'     ;
  1165.  
  1166. fs1d:    pop    ax            ; get 10m
  1167.     sub    dx,dx            ;
  1168.     or    ax,ax            ;
  1169.     jz    fs1x            ; none left
  1170.     lea    si,-9[bx]        ;
  1171.     call    format            ;
  1172.  
  1173. fs1f:    cmp    ax,9            ; need a zero?
  1174.     jbe    fs1x            ; no
  1175.     or    word ptr -3[bx],'00'    ;
  1176.  
  1177. fs1x:    pop    si            ; Target
  1178.  
  1179.     sub    si,9            ; Point to first digit
  1180.     mov    cx,16            ; Maximum length
  1181. fs1y:    lodsb                ; Have non-zero?
  1182.     cmp    al,'0'                  ;
  1183.     ja    fs1z            ;  yes, insure readable
  1184.     loop    fs1y            ;
  1185. fs1z:
  1186.     jcxz    fs1exit         ;
  1187.     cmp    byte ptr [si],','       ;
  1188.     je    fs1w            ;
  1189.     or    byte ptr [si],'0'       ;
  1190. fs1w:
  1191.     inc    si            ;
  1192.     loop    fs1z            ;
  1193. fs1exit:
  1194.     ret                ;
  1195. formatc endp
  1196.  
  1197.     page
  1198. ;
  1199. ;    Print String like INT 21H function 9
  1200.  
  1201. prints    proc    near            ; DX has offset to string
  1202.     save    <si,bx,cx>        ;  ending in char x'FF'
  1203.     mov    si,dx            ; Ptr to string text
  1204.     sub    cx,cx            ; Overall text length
  1205. ps1:    lodsb
  1206.     cmp    al,stopper        ; Ending hex FF?
  1207.     je    ps9
  1208.     inc    cx
  1209.     jmp    short ps1
  1210.  
  1211. ps9:
  1212.     mov    bx,1            ; Standard output device
  1213.     mov    ah,40h            ;  to write to
  1214.     int    21h
  1215.  
  1216.     return    <cx,bx,si>        ; Recover registers
  1217. prints    endp
  1218.  
  1219.  
  1220. cls    proc    near            ; Clear screen
  1221.     save    <ax,bx,cx,dx,si>
  1222.  
  1223.     mov    ax,600h         ; Scroll all lines
  1224.     sub    cx,cx            ;  upper left
  1225.     mov    dx,184fh        ;  lower right
  1226.     mov    bl,_page        ;  video page
  1227.     mov    bh,_attr        ;  attribute
  1228.     int    10h            ; Video I/O
  1229.  
  1230.     mov    bl,_attr        ; Set cursor position
  1231.     mov    bh,_page
  1232.     sub    dx,dx            ;  to 1,1
  1233.     mov    ah,2
  1234.     int    10h
  1235.  
  1236.     return    <si,dx,cx,bx,ax>    ; return to caller
  1237. cls    endp
  1238.  
  1239.     page
  1240. ;
  1241. ;    Format current date and time
  1242.  
  1243. clock    proc    near
  1244.     save    <ax,bx,cx,dx>        ; save work regs
  1245.  
  1246.     mov    ah,2ah            ;Get date
  1247.     int    21h
  1248.     sub    cx,1900         ; last two digits
  1249.     mov    ax,cx            ;Make readable
  1250.     call    cnvrt1            ;Convert to ASCII
  1251.     mov    word ptr year,ax
  1252.     xchg    al,dh            ;Get month
  1253.     call    cnvrt1            ;Convert to ASCII
  1254.     mov    word ptr month,ax
  1255.     xchg    al,dl            ;Get day
  1256.     call    cnvrt1            ;Convert to ASCII
  1257.     mov    word ptr day,ax
  1258.  
  1259.     mov    ah,2ch            ;Get time
  1260.     int    21h
  1261.     xchg    al,ch            ;Get hours
  1262.     call    cnvrt1            ;Convert to ASCII
  1263.     mov    word ptr hours,ax
  1264.     xchg    al,cl            ;Get minutes
  1265.     call    cnvrt1            ;Convert to ASCII
  1266.     mov    word ptr mins,ax
  1267.     xchg    al,dh            ;Get seconds
  1268.     call    cnvrt1            ;Convert to ASCII
  1269.     mov    word ptr secs,ax
  1270.  
  1271.     return    <dx,cx,bx,ax>        ; return to caller
  1272. clock    endp
  1273.  
  1274.     page
  1275. ;
  1276. ;    Shell-Metzger Sort of 64-byte table records
  1277.  
  1278. ;    Variables used for sort subroutine
  1279.  
  1280. numrec    dw    0            ; Number of entries
  1281. loc    dw    0
  1282. index1    dw    0
  1283. incr    dw    0
  1284. limit    dw    0
  1285. index2    dw    0
  1286. ptr1    dw    0            ;Offset to record Index1
  1287. ptr2    dw    0            ;Offset to record Index2
  1288.  
  1289. keyptr    dw    0            ;Offset to key
  1290. keylen    dw    0            ;Length of key
  1291. base    dw    0            ;Seg addr of array
  1292.  
  1293. sort    proc    near
  1294.     push    ds            ; Save seg regs
  1295.     push    es
  1296.  
  1297. ;    Set sort options
  1298.  
  1299.     sub    bx,bx            ; Offset to key
  1300.     mov    bl,offset tblpath
  1301.     test    flags,bysize
  1302.     jz    sort1
  1303.     mov    bl,offset tblsize    ; Sort by size
  1304. sort1:    test    flags,bydate
  1305.     jz    sort2
  1306.     mov    bl,offset tbldate    ; Sort by date/time
  1307. sort2:    test    flags,byext
  1308.     jz    sort3
  1309.     mov    bl,offset tblext
  1310.  
  1311. ;    Initialize sort parameters
  1312.  
  1313. sort3:    mov    cx,numdir        ; Number of entries
  1314.     mov    numrec,cx
  1315.     mov    keyptr,bx
  1316.  
  1317.     mov    dx,64            ; Length of key
  1318.     sub    dx,bx
  1319.     mov    keylen,dx
  1320.     mov    es,segdir        ; Seg addr of table
  1321.     mov    ax,es            ; Save array addr
  1322.     sub    ax,4            ;  adjust for indexing
  1323.     mov    base,ax
  1324.  
  1325. ;    Sort 64-byte entries
  1326.  
  1327.     mov    loc,cx            ; Loc=NumRecs
  1328.  
  1329. check:    cmp    loc,1            ; IF Loc<=1 THEN
  1330.     jg    check1            ; GOTO SORTED
  1331.     jmp    sorted
  1332.  
  1333. check1: mov    ax,loc
  1334.     sar    ax,1            ; Loc=2*(Loc/4)+1
  1335.     or    ax,1
  1336.     mov    loc,ax
  1337.  
  1338.     mov    ax,numrec        ; Limit=NumRec-Loc
  1339.     sub    ax,loc
  1340.     mov    limit,ax
  1341.  
  1342.     mov    incr,0            ; Incr=0
  1343.  
  1344. again:    inc    incr            ; Incr=Incr+1
  1345.  
  1346.     mov    ax,incr         ; IF Incr>Limit THEN GOTO CHECK
  1347.     cmp    ax,limit
  1348.     jg    check
  1349.  
  1350.     shl    ax,1
  1351.     shl    ax,1
  1352.     mov    index1,ax        ; Index1=Incr
  1353.  
  1354.     mov    index2,ax        ; Index2=Index1+Loc
  1355.     mov    ax,loc
  1356.     shl    ax,1            ; times 2
  1357.     shl    ax,1            ; times 4
  1358.     add    index2,ax
  1359.  
  1360. comp:    mov    ax,index1        ; IF array(Index1)<=array(Index2)
  1361.     add    ax,base
  1362.     mov    es,ax
  1363.     mov    ptr1,ax
  1364.     mov    di,keyptr
  1365.  
  1366.     mov    ax,index2        ; THEN GOTO AGAIN
  1367.     add    ax,base
  1368.     mov    ptr2,ax
  1369.     mov    si,keyptr
  1370.     mov    cx,cs:keylen
  1371.  
  1372.     push    ds
  1373.     mov    ds,ax
  1374.     repe    cmpsb
  1375.     pop    ds
  1376.     jae    again
  1377.  
  1378. swap:    mov    bx,ptr1         ; ELSE
  1379.     mov    dx,ptr2         ; TEMP=array(Index1)
  1380.  
  1381.     mov    ax,cs
  1382.     mov    es,ax
  1383.     mov    di,offset temp
  1384.     mov    cx,tbl_len
  1385.  
  1386.     mov    ds,bx
  1387.     sub    si,si
  1388.     rep    movsb
  1389.  
  1390.     mov    es,bx            ; array(Index1)=array(Index2)
  1391.     mov    ds,dx
  1392.     sub    di,di
  1393.     sub    si,si
  1394.     mov    cx,tbl_len
  1395.     rep    movsb
  1396.  
  1397.     mov    ax,cs            ; array(Index2)=TEMP
  1398.     mov    ds,ax
  1399.     mov    si,offset temp
  1400.     mov    es,dx
  1401.     sub    di,di
  1402.     mov    cx,tbl_len
  1403.     rep    movsb
  1404.  
  1405.     mov    ax,index1        ; Index2=Index1
  1406.     mov    index2,ax
  1407.  
  1408.     mov    ax,loc            ; Index1=Index1-Loc
  1409.     shl    ax,1
  1410.     shl    ax,1
  1411.     sub    index1,ax
  1412.  
  1413.     jg    comp            ; IF Index1>0 then GOTO COMP
  1414.     jmp    again            ; ELSE GOTO AGAIN
  1415.  
  1416. sorted: pop    es            ;Recover register
  1417.     pop    ds
  1418.     ret
  1419. sort    endp
  1420.  
  1421.     page
  1422.  
  1423. ;
  1424. ;    Data structures and work areas
  1425.  
  1426.  
  1427. parmdr        db    ' :'                            ; Drive letter
  1428. parmdir     equ    $                ; for specific path
  1429.  
  1430. pline        equ    parmdir+64            ; Print line
  1431.  
  1432. dta        equ    pline+tbl_len            ; Disk transfer areas
  1433.  
  1434. search        equ    dta + (depth+1)*dta_len     ; Search arguments
  1435.  
  1436. local_stack    equ    search + (depth+1)*arg_len    ; Local stack
  1437. local_stack_end equ    local_stack+512
  1438.  
  1439. workend     equ    local_stack_end + 2        ; End of work areas
  1440.  
  1441. pgmsize     equ    (workend - cseg + 512) /16    ; Size of program
  1442.  
  1443. cseg        ends
  1444.         end    ldir
  1445.