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