home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / ASMUTL / CHEAPASM.ZIP / SDIR.ASM < prev    next >
Encoding:
Assembly Source File  |  1987-01-11  |  17.6 KB  |  623 lines

  1.  
  2.  
  3.     TITLE   SDIR - SORTED DIRECTORY COMMAND, Version 2.1
  4.     PAGE    64,132                            ; JAN 1983
  5. COMMENT |
  6.     SDIR [d:][filename[.ext]] [options]
  7.      [filespec] same as for DIR command
  8.  
  9.      [options] * /A - List hidden files.
  10.                * /E - Without screen erase.
  11.                * /P - Pause when screen full.
  12.                  /X - Sort by extension.
  13.                  /S - Sort by size.
  14.                  /D - Sort by date/time.
  15.                  /N - Do not sort, original order.
  16.  
  17.        Default = *.* sorted by name.ext with screen erase.
  18.        * - Option may be combined with other options.
  19.  
  20.    This source file was created from an object file obtained
  21.  from Gene Plantz's BBS in Chicago. The original file name
  22.  was SD.HEX.  I then used DEBUG and CAPTURE to get the first
  23.  dis-assembly which  was then edited with WORDSTAR to create
  24.  a source that when assembled using MASM would duplicate the
  25.  original object file.
  26.    Comments have been added and I do hope they are helpful.
  27.  I have made several modifications to the first version and
  28.  am continuing to add comments.  This source file is an
  29.  excellent example for anyone wishing to learn 8086/8088
  30.  assembly language.  Use at your own risk and feel free to
  31.  share this file with your friends.
  32.    I certainly wish that John Chapman would publish his
  33.  source file.  His comments are sure to be more meaningful
  34.  than mine could ever be.  Some of the conversion routines
  35.  are very elegant, but difficult to understand.  As far as
  36.  I'm concerned, PRINTDD is magic.
  37.    Several modifications have been made.  They are:
  38.  
  39.     1. Filespecs are processed like DIR does.
  40.     2. No sort option was added. /N
  41.     3. Pause when screen full option added. /P
  42.     4. Number of files found is printed.
  43.  
  44.                                     Ted Reuss
  45.                                     Houston, TX
  46.  
  47.     SDIR Version 2.2  The GETFREE Subroutine was updated for DOS 2.0
  48.     April 1, 1983   by   Jack Y. Fong
  49.     Changes are denoted by "JYF" at the end of changed lines.
  50. |
  51.  
  52.     SUBTTL  EQUATES & STRUCTURES
  53.     PAGE
  54. IF1
  55. DOSCALL MACRO       FUNC,PARM1
  56. .xcref
  57. F_C =       FUNC
  58. IFNB <PARM1>
  59. IF F_C EQ 2 OR (F_C GE 4 AND F_C LE 6) OR F_C EQ 14 OR F_C EQ 46
  60.     MOV     DL,PARM1
  61. ELSE
  62.     MOV     DX,OFFSET PARM1
  63. ENDIF
  64. ENDIF
  65.     MOV    AH,FUNC
  66.     INT    21H
  67. .cref
  68.     ENDM
  69. ENDIF
  70. .SALL    ;supress all macro expansions
  71. ;    PC-DOS INTERRUPT 21H FUNCTION CODES
  72. ;
  73. @CHROUT EQU    2    ;display char in DL
  74. @KEYIN    EQU    8    ;kybd input w/o echo
  75. @STROUT EQU    9    ;print string terminated with $
  76. @CKEYIN EQU    12    ;clr kybd bufr & do inp.func in AL
  77. @SRCH1    EQU    17    ;search for first dir entry
  78. @SRCH2    EQU    18    ;search for next dir entry
  79. @GETDSK EQU    25    ;get default disk drive
  80. @SETDTA EQU    26    ;set disk transfer addr
  81. @FATAD2 EQU    28    ;get FAT of drive # in DL
  82. @PARSEF EQU 41      ;parse filename
  83. @GETDTE EQU 42      ;get system date
  84. @GETTME EQU 44      ;get system time
  85. @DSKFSP EQU 36H     ;get disk free space                            JYF
  86. @GETVER EQU 30H     ;get version number                             JYF
  87.  
  88. CR  EQU     0DH     ;carriage return
  89. LF  EQU     0AH     ;line feed
  90. FCB_1       EQU     5CH     ;fcb for parameter 1
  91. PARAM_L EQU 80H     ;# characters in PARAM_B
  92. PARAM_B EQU 81H     ;DOS cmd parameter buffer.
  93.  
  94. ; PC-DOS packed date   <yyyyyyym mmmddddd>
  95. P_DTE       RECORD  P_YR:7,P_MO:4,P_DY:5
  96. ; PC-DOS packed time   <hhhhhmmm mmmsssss>
  97. P_TME       RECORD  P_HR:5,P_MI:6,P_2S:5
  98.  
  99. DIRNTRY STRUC               ;directory entry structure
  100. LNK DW      0       ;ptr to next entry
  101. NAM DB      8 DUP(0),'.' ;filename
  102. EXT DB      3 DUP(0) ;extension
  103. TME DW      0       ;time
  104. DTE    DW    0    ;date
  105. SZL    DW    0    ;low word of size
  106. SZH    DW    0    ;high word of size
  107. DIRNTRY ENDS
  108.  
  109.     SUBTTL    DATA AREA & INITIALIZATION
  110.     PAGE
  111. SDIR    SEGMENT PUBLIC 'CODE'
  112.     ASSUME    CS:SDIR,DS:SDIR,ES:SDIR
  113.     ORG    100H
  114. MAIN    PROC    FAR
  115.     JMP    STARTS
  116.  
  117. DIRLNK    DW    DIRBUF    ;ptr to next opening in DIRBUF
  118. C1LNK    DW    0    ;ptr to row 1, column 1
  119. C2LNK    DW    0    ;ptr to row 1, column 2
  120. NBRFILS DW    0    ;# of files or detail lines
  121. SRTFLG    DB    0    ;if = 0 then sort else no sort
  122. CLSFLG      DB      0       ;if = 0 then clear screen
  123. EXTFLG      DB      0       ;if <> 0 then sort by ext
  124. SIZFLG      DB      0       ;if <> 0 then sort by size
  125. DTEFLG      DB      0       ;if <> 0 then sort by date/time
  126. PSEFLG      DB      0       ;if <> 0 then pause if screen full
  127. LPERSCR EQU 25      ;Lines per screen
  128. LINCNT      DB      LPERSCR-4 ;Number of lines left
  129. PSEMSG      DB      'Strike a key when ready . . . $'
  130.  
  131. HDNG1       DB      'Capital PC Software Exchange /AEPXSDN/ 2.2' ;   JYF
  132.     DB      'DRIVE '
  133. HDRVE       DB      '@:    Date '
  134. D_MM        DW      '00'            ;Month
  135.     DB      '/'
  136. D_DD        DW      '00'            ;Day
  137.     DB      '/'
  138. D_YY        DW      '00'            ;Year
  139.     DB      '  Time '
  140. T_HH        DW      '00'            ;Hours
  141.     DB      ':'
  142. T_MM        DW      '00'            ;Minutes
  143.     DB      CR,LF
  144. CRLF    DB    CR,LF,'$'
  145. HDNG2    DB    'FILESPEC.EXT  BYTES-  --LAST CHANGE--$'
  146.     DB    8 DUP(' ')
  147. SPACES    DB    '$'
  148. HDNG3    DB    ' File(s)',CR,LF,'$'
  149.  
  150.     SUBTTL    DISK TRANSFER AREA & FREE SPACE ENTRY DEFS
  151.     PAGE
  152.  
  153. XFCB    DB    -1,7 DUP(0),11 DUP('?'),25 DUP(0)
  154. ATTRIB    EQU    XFCB+6        ;file attribute
  155. DRVNBR    EQU    ATTRIB+1    ;drive # (1=A, 2=B, etc.)
  156.  
  157. DTA    DB    40 DUP(0)    ;Disk Transfer Area used
  158. FILNAME EQU    DTA+8        ;by SRCHDIR for the
  159. FILTIME EQU    DTA+30        ;directory search.
  160. FILSIZE EQU    DTA+36
  161.  
  162. FREESPC DW    0        ;Free space entry.
  163.     DB    '*FREE SPACE*',4 DUP(0)
  164. LOSIZE    DW    0        ;of free space
  165. HISIZE    DW    0        ;of free space
  166.  
  167.     SUBTTL    MAIN PROGRAM SECTION
  168.     PAGE
  169. STARTS:
  170.     PUSH    DS        ;Set up the
  171.     XOR    AX,AX        ; stack for a
  172.     PUSH    AX        ; return to DOS.
  173.     CALL    GETARGS     ;Process arguments
  174.     CALL    SRCHDIR     ;Search directory
  175.     CMP    SRTFLG,0    ;Check if any sort
  176.     JZ    A1        ; option selected.
  177.     CALL    LNKDIRB     ;Leave in original
  178.     JMP    SHORT A2    ; directory order.
  179. A1:    CALL    SRTDIRB     ;Sort by major key
  180. A2:    CALL    GETFREE     ;Get free space
  181.     CALL    SPLTLST     ;Set up for 2 columns
  182.     CALL    PRTHDNG     ;Print headings
  183.     CALL    PRTDRVR     ;Print detail lines
  184.     CALL    PRTNFLS     ;Print # of files
  185.     RET            ;Return to DOS
  186. MAIN    ENDP
  187.  
  188.     SUBTTL    GETARGS - PROCESS ARGUMENTS
  189.     PAGE
  190. GETARGS PROC    NEAR
  191.     MOV    SI,PARAM_B    ;point to cmd buffer
  192.     MOV    DI,OFFSET DRVNBR ;point to FCB
  193.     MOV    AL, 1111B    ;Select parse options
  194.     DOSCALL @PARSEF     ;Parse filename
  195.     CMP    BYTE PTR [DI],0 ;If <> 0 then
  196.     JNZ    B1        ; not default drive
  197.     DOSCALL @GETDSK     ;AL <- default disk
  198.     INC    AL        ;Increment drive #
  199.     STOSB            ;Save drive #
  200. B1:    MOV    SI,PARAM_L    ;SI <- ptr cmd length
  201.     MOV    CH,0
  202.     MOV    CL,[SI]     ;CL <- # chars in cmd
  203.     JCXZ    B10
  204. B2:    INC    SI        ;Point to next char
  205.     CMP    BYTE PTR [SI],'/'
  206.     JNZ    B8        ;If not a slash
  207.     MOV    AL,[SI+1]    ;AL <- option letter
  208.     AND    AL,0DFH     ;Force to upper-case
  209.     CMP    AL,'A'          ;Hidden & system files?
  210.     JNZ    B3        ;Nope, try next one.
  211.     MOV    BYTE PTR ATTRIB,2+6  ;Hidden & system
  212. B3:    CMP    AL,'E'          ;Without screen erase?
  213.     JNZ    B4        ;Nope, try next one.
  214.     MOV    CLSFLG,AL
  215. B4:    CMP    AL,'S'          ;Sort by size?
  216.     JNZ    B5        ;Nope, try next one.
  217.     MOV    SIZFLG,AL
  218. B5:    CMP    AL,'D'          ;Sort by date/time?
  219.     JNZ    B6        ;Nope, try next one.
  220.     MOV    DTEFLG,AL
  221. B6:    CMP    AL,'X'          ;Sort by extension?
  222.     JNZ    B7        ;Nope, try next one.
  223.     MOV    EXTFLG,AL
  224. B7:    CMP    AL,'N'          ;Original order?
  225.     JNZ    B8        ;Nope, try next one.
  226.     MOV    SRTFLG,AL
  227. B8:    CMP    AL,'P'          ;Pause when screen full?
  228.     JNZ    B9        ;Nope, try next one.
  229.     MOV    PSEFLG,AL
  230. B9:    LOOP    B2        ;Test for another param.
  231. B10:    RET
  232. GETARGS ENDP
  233.  
  234.     SUBTTL    SRCHDIR - SEARCH DIRECTORY
  235.     PAGE
  236. SRCHDIR PROC    NEAR
  237.     DOSCALL @SETDTA,DTA    ;Set DTA for dir. search
  238.     DOSCALL @SRCH1,XFCB    ;First call to search dir.
  239. C1:    OR    AL,AL
  240.     JNZ    C2        ;Not found, quit looking.
  241.     MOV    BX,DIRLNK    ;BX <- base of DIRBUF
  242.     LEA    DI,[BX].NAM
  243.     MOV    SI,OFFSET FILNAME
  244.     MOV    CX,SIZE NAM
  245.     CLD
  246.     REPZ    MOVSB        ;Move filename to DIRBUF
  247.     MOV    BYTE PTR [DI],'.' ; Store a period
  248.     INC    DI
  249.     MOV    CX,SIZE EXT
  250.     REPZ    MOVSB        ;Move ext to DIRBUF
  251.     MOV    SI,OFFSET FILTIME
  252.     MOVSW            ;Move time to DIRBUF
  253.     MOVSW            ;Move date to DIRBUF
  254.     MOV    SI,OFFSET FILSIZE
  255.     MOVSW            ;Move size to DIRBUF
  256.     MOVSW
  257.     ADD    BX,SIZE DIRNTRY ;Point to next entry
  258.     MOV    DIRLNK,BX    ;Save ptr
  259.     INC    NBRFILS     ;Increment file count
  260.     DOSCALL @SRCH2,XFCB    ;Search for next file
  261.     JMP    C1        ;Loop for next one
  262. C2:    RET
  263. SRCHDIR ENDP
  264.  
  265.     SUBTTL    SRTDIRB - SORTS ENTRIES IN DIRBUF
  266.     PAGE
  267. SRTDIRB PROC    NEAR    ;Sorts directory entries in DIRBUF
  268.     MOV    DI,OFFSET DIRBUF ;Point to DIRBUF
  269. D1:    CMP    DI,DIRLNK    ;Are there anymore?
  270.     JNC    D8        ;NO, exit
  271.     MOV    SI,OFFSET C1LNK ;Start with column 1 ptr
  272. D2:    MOV    BX,SI
  273.     MOV    SI,[BX]     ;SI<-ptr to next entry
  274.     OR    SI,SI
  275.     JZ    D7        ;if link=0
  276.     MOV    AX,SI
  277.     MOV    DX,DI
  278.     XOR    CL,CL        ;CL <- 0
  279.     CMP    CL,SIZFLG
  280.     JNZ    D5        ;If sort by size
  281.     CMP    CL,DTEFLG
  282.     JNZ    D4        ;If sort by date/time
  283.     CMP    CL,EXTFLG
  284.     JNZ    D3        ;If sort by ext
  285.     LEA    SI,[SI].NAM
  286.     LEA    DI,[DI].NAM
  287.     MOV    CX,1+SIZE NAM+SIZE EXT    ;# of bytes
  288.     JMP    SHORT D6
  289. D3:    LEA    SI,[SI].EXT    ;Sort by extension
  290.     LEA    DI,[DI].EXT
  291.     MOV    CX,SIZE EXT    ;# of bytes
  292.     JMP    SHORT D6
  293. D4:    LEA    SI,[SI].DTE    ;Sort by date/time
  294.     LEA    DI,[DI].DTE
  295.     MOV    CX,2        ;# of words
  296.     STD
  297.     REPZ    CMPSW
  298.     MOV    DI,DX
  299.     MOV    SI,AX
  300.     JBE    D2
  301.     JMP    SHORT D7
  302. D5:    LEA    SI,[SI].SZH    ;Sort by size
  303.     LEA    DI,[DI].SZH
  304.     MOV    CX,2        ;# of words
  305.     STD
  306.     REPZ    CMPSW
  307.     MOV    DI,DX
  308.     MOV    SI,AX
  309.     JBE    D2
  310.     JMP    SHORT D7
  311. D6:    CLD            ;Sort by name.ext
  312.     REPZ    CMPSB
  313.     MOV    DI,DX
  314.     MOV    SI,AX
  315.     JBE    D2
  316. D7:    MOV    [DI],SI
  317.     MOV    [BX],DI
  318.     ADD    DI,SIZE DIRNTRY ;Point to next entry
  319.     JMP    D1
  320. D8:    RET
  321. SRTDIRB ENDP
  322.  
  323.     SUBTTL
  324.     PAGE
  325. ; LNKDIRB - LINKS ENTRIES IN DIRBUF
  326.  
  327. LNKDIRB PROC    NEAR        ;LINK ENTRIES IN DIRBUF
  328.     MOV    DI,OFFSET DIRBUF
  329.     MOV    C1LNK,DI       ;Point to 1st entry
  330.     MOV    CX,NBRFILS    ;Set loop counter
  331.     DEC    CX
  332. LNK1:    MOV    BX,DI
  333.     ADD    DI,SIZE DIRNTRY ;Offset to next entry
  334.     MOV    [BX],DI     ;Store ptr
  335.     LOOP    LNK1        ;Link next entry
  336.     MOV    [DI],CX     ;Last ptr <- null
  337.     RET
  338. LNKDIRB ENDP
  339.  
  340. ; SPLTLST - SPLITS LINKED LIST IN HALF
  341.  
  342. SPLTLST PROC    NEAR
  343.     MOV    CX,NBRFILS    ;Get # of entries
  344.     SAR    CX,1        ; and divide by 2
  345.     JZ    F2        ;if NBRFILS < 2
  346.     ADC    CL,0        ;Account for odd #
  347.     MOV    BX,OFFSET C1LNK
  348. F1:    MOV    BX,[BX]     ;Chain thru list to
  349.     LOOP    F1        ; last row of column 1.
  350.     MOV    AX,[BX]     ;Get ptr to 1st row of col 2
  351.     MOV    C2LNK,AX    ; C2LNK <- R1,C2 ptr
  352.     MOV    [BX],CX     ;Last row of col 1 <- null
  353. F2:    RET
  354. SPLTLST ENDP
  355.  
  356.     SUBTTL    GETFREE - GET DISK FREE SPACE
  357.     PAGE
  358. GETFREE PROC        NEAR            ;cluster = allocation unit
  359.     MOV     DL,DRVNBR       ;Get drive #
  360.     PUSH    DS              ;Save DS
  361.     DOSCALL @GETVER         ;get DOS version number                    JYF
  362.     CMP     AL,2            ;is this version 2.0 or higher?            JYF
  363.     JGE     E4              ;yes                                       JYF
  364.                             ;no                                        JYF
  365.     DOSCALL @FATAD2         ;Get FAT info from DOS
  366.     MOV     AH,0            ;AL = sector size
  367.     XCHG    CX,DX           ;Sector size times the
  368.     MUL     DX              ; # sectors/cluster
  369.     PUSH    AX              ;Save cluster size
  370.     XOR     AX,AX           ;Unused clusters = 0
  371.     MOV     SI,2            ;Skip first 3 clusters
  372. E1: MOV     DI,SI           ;DI <- cluster #
  373.     SHR     DI,1            ;Divide cluster number
  374.     ADD     DI,SI           ; by 1.5
  375.     MOV     DI,[BX+DI]      ;Fetch from FAT
  376.     TEST    SI,1            ;Test if even or odd
  377.     JZ      E2              ;If even then skip
  378.     SHR     DI,1            ; else if odd
  379.     SHR     DI,1            ;  right justify the
  380.     SHR     DI,1            ;  cluster number.
  381.     SHR     DI,1
  382. E2: AND     DI,0FFFH        ;Mask the low 12 bits
  383.     JNZ     E3              ;If not 0 then skip, else
  384.     INC     AX              ; increment counter.
  385. E3: INC     SI              ;Point to next cluster
  386.     LOOP    E1              ; and go check it.
  387.     POP     CX              ;Get cluster size, times
  388.     MUL     CX              ;  # of free clusters
  389.     JMP     E5              ;skip processing for DOS 2.0                JYF
  390. E4:                         ;processing for DOS 2.00                    JYF
  391.     DOSCALL @DSKFSP         ;get disk free space                        JYF
  392.     MUL     BX              ;AX (sectors/clustor) * BX (free clustors)  JYF
  393.     MOV     DX,AX           ;                                           JYF
  394.     MUL     CX              ;AX * CX (bytes/clustor)                    JYF
  395. E5:                         ;                                           JYF
  396.     POP     DS              ;Restore DS
  397.     MOV     LOSIZE,AX       ;Save the 32 bit
  398.     MOV     HISIZE,DX       ; binary free space
  399.     MOV     BX,C1LNK        ;Insert FREESPC in
  400.     MOV     DI,OFFSET FREESPC ;first position
  401.     MOV     [DI],BX         ; of linked list of
  402.     MOV     C1LNK,DI        ; directory entries.
  403.     INC     NBRFILS         ;Bump # of entries
  404.     RET
  405. GETFREE ENDP
  406.  
  407.     SUBTTL  PRTHDNG - PRINT HEADINGS
  408.     PAGE
  409. PRTHDNG PROC        NEAR
  410.     MOV    AL,CLSFLG
  411.     OR    AL,AL
  412.     JNZ    G1        ;If not erase screen
  413.     SUB    CX,CX
  414.     MOV    DX,24*256+79    ;row=24 col=79
  415.     MOV    BH,7        ;Video mode
  416.     MOV    AX,0600H
  417.     INT    10H        ;BIOS video call
  418.     SUB    DX,DX
  419.     MOV    AH,2        ;Clear screen
  420.     MOV    BH,0
  421.     INT    10H        ;BIOS video call
  422. G1:    MOV    AL,DRVNBR    ;Get drive #
  423.     ADD    HDRVE,AL    ;Convert to ascii
  424.     DOSCALL @GETDTE ; CX<-year, DH<-month, DL<-day
  425.     MOV    AL,DH
  426.     AAM
  427.     XCHG    AL,AH
  428.     OR    D_MM,AX     ;Fold into month
  429.     MOV    AL,DL
  430.     AAM
  431.     XCHG    AL,AH
  432.     OR    D_DD,AX     ;Fold into day
  433.     MOV    AX,CX
  434.     SUB    AX,1900
  435.     AAM
  436.     XCHG    AL,AH
  437.     OR    D_YY,AX     ;Fold into year
  438.     DOSCALL @GETTME ; CH<-hours, CL<-minutes
  439.     MOV    AL,CH        ;AL<-binary hours
  440.     AAM            ;Convert AL to two
  441.     XCHG    AL,AH        ; BCD digits in AX.
  442.     OR    T_HH,AX     ;Fold into hours
  443.     MOV    AL,CL        ;AL<-binary minutes
  444.     AAM            ;Convert AL to two
  445.     XCHG    AL,AH        ; BCD digits in AX.
  446.     OR    T_MM,AX     ;Fold into minutes
  447.     DOSCALL @STROUT,HDNG1    ;Print main heading
  448.     DOSCALL @STROUT,HDNG2    ;Print column 1 heading
  449.     CMP    WORD PTR C2LNK,0
  450.     JZ    G2        ;If not 2 columns
  451.     DOSCALL @STROUT,SPACES-5 ;Print 5 spaces
  452.     DOSCALL @STROUT,HDNG2    ;Print column 2 heading
  453. G2:    DOSCALL @STROUT,CRLF    ;Start a new line
  454.     RET
  455. PRTHDNG ENDP
  456.  
  457.     SUBTTL    PRINT DETAIL LINES
  458.     PAGE
  459. PRTDRVR PROC    NEAR        ;Driver routine
  460.     MOV    BX,C1LNK
  461.     OR    BX,BX        ;more to print?
  462.     JZ    H2        ; no, return
  463.     MOV    AX,[BX]
  464.     MOV    C1LNK,AX
  465.     CALL    PRTDTL        ;print column one
  466.     MOV    BX,C2LNK
  467.     OR    BX,BX
  468.     JZ    H1        ;If no column 2 entry
  469.     DOSCALL @STROUT,SPACES-5 ;print 5 spaces
  470.     MOV    AX,[BX]
  471.     MOV    C2LNK,AX
  472.     CALL    PRTDTL        ;print column two
  473. H1:    DOSCALL @STROUT,CRLF
  474.     CMP    PSEFLG,0    ;Check for pause option
  475.     JZ    PRTDRVR     ;Nope, continue
  476.     DEC    LINCNT        ;Decrement line counter
  477.     JNZ    PRTDRVR     ;If page not full?
  478.     MOV    LINCNT,LPERSCR-2 ;Reset to # lines/screen
  479.     DOSCALL @STROUT,PSEMSG    ;Display pause message.
  480.     MOV    AL,@KEYIN    ;Specify input function
  481.     DOSCALL @CKEYIN     ;Wait for key press
  482.     DOSCALL @STROUT,CRLF    ;Set to new line
  483.     JMP    PRTDRVR     ;Go do the next line
  484. H2:    RET
  485. PRTDRVR ENDP
  486.  
  487. PRTDTL    PROC    NEAR    ;Prints file.ext, size, date & time
  488.     MOV    CX,1+SIZE NAM+SIZE EXT
  489.     SUB    DI,DI        ;DI <- 0
  490. I1:    DOSCALL @CHROUT,[BX+DI].NAM
  491.     INC    DI        ;point to next char.
  492.     LOOP    I1        ;go do next char.
  493.     PUSH    BX        ;save entry base
  494.     MOV    SI,[BX].SZL    ;SI <- low size
  495.     MOV    DI,[BX].SZH    ;DI <- high size
  496.     CALL    PRINTDD     ;Print size
  497.     POP    BX        ;restore entry base
  498.     DOSCALL @STROUT,SPACES-2 ;print 2 spaces
  499.     MOV    AX,[BX].DTE    ;AX <- packed date
  500.     CALL    PRTDTE
  501.     DOSCALL @STROUT,SPACES-2 ;print 2 spaces
  502.     MOV    AX,[BX].TME    ;AX <- packed time
  503.     CALL    PRTTME
  504.     RET
  505. PRTDTL    ENDP
  506.  
  507.     SUBTTL    PRINTDD - PRINT A DOUBLE WORD IN DI:SI
  508.     PAGE
  509. PRINTDD PROC    NEAR    ;Prints a 32 bit integer in DI:SI
  510.     XOR    AX,AX        ;Zero out the
  511.     MOV    BX,AX        ; working
  512.     MOV    BP,AX        ; registers.
  513.     MOV    CX,32        ;# bits of precision
  514. J1:    SHL    SI,1
  515.     RCL    DI,1
  516.     XCHG    BP,AX
  517.     CALL    J6
  518.     XCHG    BP,AX
  519.     XCHG    BX,AX
  520.     CALL    J6
  521.     XCHG    BX,AX
  522.     ADC    AL,0
  523.     LOOP    J1
  524.     MOV    CX,1710H    ;5904 ?
  525.     MOV    AX,BX
  526.     CALL    J2
  527.     MOV    AX,BP
  528. J2:    PUSH    AX
  529.     MOV    DL,AH
  530.     CALL    J3
  531.     POP    DX
  532. J3:    MOV    DH,DL
  533.     SHR    DL,1        ;Move high
  534.     SHR    DL,1        ; nibble to
  535.     SHR    DL,1        ; the low
  536.     SHR    DL,1        ; position.
  537.     CALL    J4
  538.     MOV    DL,DH
  539. J4:    AND    DL,0FH        ;Mask low nibble
  540.     JZ    J5        ;If not zero
  541.     MOV    CL,0
  542. J5:    DEC    CH
  543.     AND    CL,CH
  544.     OR    DL,'0'          ;Fold in ASCII zero
  545.     SUB    DL,CL
  546.     DOSCALL @CHROUT     ;Print next digit
  547.     RET            ;Exit to caller
  548. PRINTDD ENDP
  549.  
  550. J6    PROC    NEAR
  551.     ADC    AL,AL
  552.     DAA
  553.     XCHG    AL,AH
  554.     ADC    AL,AL
  555.     DAA
  556.     XCHG    AL,AH
  557.     RET
  558. J6    ENDP
  559.  
  560.     SUBTTL    PRINT DATE, TIME & # FILES ROUTINES
  561.     PAGE
  562. PRTDTE    PROC    NEAR    ;Print packed date in AX as MM/DD/YY
  563.     OR    AX,AX
  564.     JNZ    K1        ;If date <> 0
  565.     DOSCALL @STROUT,SPACES-8 ;Print 8 spaces
  566.     RET
  567. K1:    PUSH    AX
  568.     AND    AX,MASK P_MO    ;Mask the month,
  569.     MOV    CL,P_MO     ; set shift count,
  570.     SHR    AX,CL        ; right justify, &
  571.     CALL    PRTBCD        ; print it.
  572.     DOSCALL @CHROUT,'/'
  573.     POP    AX
  574.     PUSH    AX
  575.     AND    AX,MASK P_DY    ;Mask the day &
  576.     CALL    PRTBCD        ; print it.
  577.     DOSCALL @CHROUT,'/'
  578.     POP    AX
  579.     AND    AX,MASK P_YR    ;Mask the year,
  580.     MOV    CL,P_YR     ; set shift count,
  581.     SHR    AX,CL        ; right justify,
  582.     ADD    AX,80        ; add in year bias, &
  583.                 ; print it.
  584. PRTBCD: AAM            ;Convert AL to BCD
  585.     OR    AX,'00'         ;Convert to ASCII
  586.     PUSH    AX
  587.     DOSCALL @CHROUT,AH    ;High order digit
  588.     POP    AX
  589.     DOSCALL @CHROUT,AL    ;Low order digit
  590.     RET
  591. PRTDTE    ENDP
  592.  
  593. PRTTME    PROC    NEAR    ;Print packed time in AX as HH:MM
  594.     OR    AX,AX
  595.     JNZ    L1
  596.     DOSCALL @STROUT,SPACES-5 ;Print 5 spaces
  597.     RET
  598. L1:    PUSH    AX
  599.     AND    AX,MASK P_HR    ;Mask the hours,
  600.     MOV    CL,P_HR     ; set shift count,
  601.     SHR    AX,CL        ; right justify, &
  602.     CALL    PRTBCD        ; print it.
  603.     DOSCALL @CHROUT,':'
  604.     POP    AX
  605.     AND    AX,MASK P_MI    ;Mask the minutes,
  606.     MOV    CL,P_MI     ; set shift count,
  607.     SHR    AX,CL        ; right justify, &
  608.     CALL    PRTBCD        ; print it.
  609.     RET
  610. PRTTME    ENDP
  611.  
  612. PRTNFLS PROC    NEAR    ;print number of files
  613.     MOV    SI,NBRFILS    ;get # of files
  614.     DEC    SI        ;-1 for free space
  615.     XOR    DI,DI        ;zero high order
  616.     CALL    PRINTDD     ;Print # of files
  617.     DOSCALL @STROUT,HDNG3
  618.     RET
  619. PRTNFLS ENDP
  620.     EVEN
  621. DIRBUF    DIRNTRY <>    ;Buffer for directory entries
  622. SDIR    ENDS
  623.     END    MAIN
  624.