
    TITLE   SDIR - SORTED DIRECTORY COMMAND, Version 2.1
    PAGE    64,132                            ; JAN 1983
COMMENT |
    SDIR [d:][filename[.ext]] [options]
     [filespec] same as for DIR command
 
     [options] * /A - List hidden files.
               * /E - Without screen erase.
               * /P - Pause when screen full.
                 /X - Sort by extension.
                 /S - Sort by size.
                 /D - Sort by date/time.
                 /N - Do not sort, original order.
 
       Default = *.* sorted by name.ext with screen erase.
       * - Option may be combined with other options.
 
   This source file was created from an object file obtained
 from Gene Plantz's BBS in Chicago. The original file name
 was SD.HEX.  I then used DEBUG and CAPTURE to get the first
 dis-assembly which  was then edited with WORDSTAR to create
 a source that when assembled using MASM would duplicate the
 original object file.
   Comments have been added and I do hope they are helpful.
 I have made several modifications to the first version and
 am continuing to add comments.  This source file is an
 excellent example for anyone wishing to learn 8086/8088
 assembly language.  Use at your own risk and feel free to
 share this file with your friends.
   I certainly wish that John Chapman would publish his
 source file.  His comments are sure to be more meaningful
 than mine could ever be.  Some of the conversion routines
 are very elegant, but difficult to understand.  As far as
 I'm concerned, PRINTDD is magic.
   Several modifications have been made.  They are:
 
	1. Filespecs are processed like DIR does.
	2. No sort option was added. /N
	3. Pause when screen full option added. /P
    4. Number of files found is printed.
 
                                    Ted Reuss
                                    Houston, TX
 
    SDIR Version 2.2  The GETFREE Subroutine was updated for DOS 2.0
    April 1, 1983   by   Jack Y. Fong
    Changes are denoted by "JYF" at the end of changed lines.
|
 
    SUBTTL  EQUATES & STRUCTURES
    PAGE
IF1
DOSCALL MACRO       FUNC,PARM1
.xcref
F_C =       FUNC
IFNB <PARM1>
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
    MOV     DL,PARM1
ELSE
    MOV     DX,OFFSET PARM1
ENDIF
ENDIF
	MOV	AH,FUNC
	INT	21H
.cref
	ENDM
ENDIF
.SALL	;supress all macro expansions
;	PC-DOS INTERRUPT 21H FUNCTION CODES
;
@CHROUT EQU	2	;display char in DL
@KEYIN	EQU	8	;kybd input w/o echo
@STROUT EQU	9	;print string terminated with $
@CKEYIN EQU	12	;clr kybd bufr & do inp.func in AL
@SRCH1	EQU	17	;search for first dir entry
@SRCH2	EQU	18	;search for next dir entry
@GETDSK EQU	25	;get default disk drive
@SETDTA EQU	26	;set disk transfer addr
@FATAD2 EQU	28	;get FAT of drive # in DL
@PARSEF EQU 41      ;parse filename
@GETDTE EQU 42      ;get system date
@GETTME EQU 44      ;get system time
@DSKFSP EQU 36H     ;get disk free space                            JYF
@GETVER EQU 30H     ;get version number                             JYF
 
CR  EQU     0DH     ;carriage return
LF  EQU     0AH     ;line feed
FCB_1       EQU     5CH     ;fcb for parameter 1
PARAM_L EQU 80H     ;# characters in PARAM_B
PARAM_B EQU 81H     ;DOS cmd parameter buffer.
 
; PC-DOS packed date   <yyyyyyym mmmddddd>
P_DTE       RECORD  P_YR:7,P_MO:4,P_DY:5
; PC-DOS packed time   <hhhhhmmm mmmsssss>
P_TME       RECORD  P_HR:5,P_MI:6,P_2S:5
 
DIRNTRY STRUC               ;directory entry structure
LNK DW      0       ;ptr to next entry
NAM DB      8 DUP(0),'.' ;filename
EXT DB      3 DUP(0) ;extension
TME DW      0       ;time
DTE	DW	0	;date
SZL	DW	0	;low word of size
SZH	DW	0	;high word of size
DIRNTRY ENDS
 
	SUBTTL	DATA AREA & INITIALIZATION
	PAGE
SDIR	SEGMENT PUBLIC 'CODE'
	ASSUME	CS:SDIR,DS:SDIR,ES:SDIR
	ORG	100H
MAIN	PROC	FAR
	JMP	STARTS
 
DIRLNK	DW	DIRBUF	;ptr to next opening in DIRBUF
C1LNK	DW	0	;ptr to row 1, column 1
C2LNK	DW	0	;ptr to row 1, column 2
NBRFILS DW	0	;# of files or detail lines
SRTFLG	DB	0	;if = 0 then sort else no sort
CLSFLG      DB      0       ;if = 0 then clear screen
EXTFLG      DB      0       ;if <> 0 then sort by ext
SIZFLG      DB      0       ;if <> 0 then sort by size
DTEFLG      DB      0       ;if <> 0 then sort by date/time
PSEFLG      DB      0       ;if <> 0 then pause if screen full
LPERSCR EQU 25      ;Lines per screen
LINCNT      DB      LPERSCR-4 ;Number of lines left
PSEMSG      DB      'Strike a key when ready . . . $'
 
HDNG1       DB      'Capital PC Software Exchange /AEPXSDN/ 2.2' ;   JYF
    DB      'DRIVE '
HDRVE       DB      '@:    Date '
D_MM        DW      '00'            ;Month
    DB      '/'
D_DD        DW      '00'            ;Day
    DB      '/'
D_YY        DW      '00'            ;Year
    DB      '  Time '
T_HH        DW      '00'            ;Hours
    DB      ':'
T_MM        DW      '00'            ;Minutes
    DB      CR,LF
CRLF	DB	CR,LF,'$'
HDNG2	DB	'FILESPEC.EXT  BYTES-  --LAST CHANGE--$'
	DB	8 DUP(' ')
SPACES	DB	'$'
HDNG3	DB	' File(s)',CR,LF,'$'
 
	SUBTTL	DISK TRANSFER AREA & FREE SPACE ENTRY DEFS
	PAGE
 
XFCB	DB	-1,7 DUP(0),11 DUP('?'),25 DUP(0)
ATTRIB	EQU	XFCB+6		;file attribute
DRVNBR	EQU	ATTRIB+1	;drive # (1=A, 2=B, etc.)
 
DTA	DB	40 DUP(0)	;Disk Transfer Area used
FILNAME EQU	DTA+8		;by SRCHDIR for the
FILTIME EQU	DTA+30		;directory search.
FILSIZE EQU	DTA+36
 
FREESPC DW	0		;Free space entry.
	DB	'*FREE SPACE*',4 DUP(0)
LOSIZE	DW	0		;of free space
HISIZE	DW	0		;of free space
 
	SUBTTL	MAIN PROGRAM SECTION
	PAGE
STARTS:
	PUSH	DS		;Set up the
	XOR	AX,AX		; stack for a
	PUSH	AX		; return to DOS.
	CALL	GETARGS 	;Process arguments
	CALL	SRCHDIR 	;Search directory
	CMP	SRTFLG,0	;Check if any sort
	JZ	A1		; option selected.
	CALL	LNKDIRB 	;Leave in original
	JMP	SHORT A2	; directory order.
A1:	CALL	SRTDIRB 	;Sort by major key
A2:	CALL	GETFREE 	;Get free space
	CALL	SPLTLST 	;Set up for 2 columns
	CALL	PRTHDNG 	;Print headings
	CALL	PRTDRVR 	;Print detail lines
	CALL	PRTNFLS 	;Print # of files
	RET			;Return to DOS
MAIN	ENDP
 
	SUBTTL	GETARGS - PROCESS ARGUMENTS
	PAGE
GETARGS PROC	NEAR
	MOV	SI,PARAM_B	;point to cmd buffer
	MOV	DI,OFFSET DRVNBR ;point to FCB
	MOV	AL, 1111B	;Select parse options
	DOSCALL @PARSEF 	;Parse filename
	CMP	BYTE PTR [DI],0 ;If <> 0 then
	JNZ	B1		; not default drive
	DOSCALL @GETDSK 	;AL <- default disk
	INC	AL		;Increment drive #
	STOSB			;Save drive #
B1:	MOV	SI,PARAM_L	;SI <- ptr cmd length
	MOV	CH,0
	MOV	CL,[SI] 	;CL <- # chars in cmd
	JCXZ	B10
B2:	INC	SI		;Point to next char
	CMP	BYTE PTR [SI],'/'
	JNZ	B8		;If not a slash
	MOV	AL,[SI+1]	;AL <- option letter
	AND	AL,0DFH 	;Force to upper-case
	CMP	AL,'A'          ;Hidden & system files?
	JNZ	B3		;Nope, try next one.
	MOV	BYTE PTR ATTRIB,2+6  ;Hidden & system
B3:	CMP	AL,'E'          ;Without screen erase?
	JNZ	B4		;Nope, try next one.
	MOV	CLSFLG,AL
B4:	CMP	AL,'S'          ;Sort by size?
	JNZ	B5		;Nope, try next one.
	MOV	SIZFLG,AL
B5:	CMP	AL,'D'          ;Sort by date/time?
	JNZ	B6		;Nope, try next one.
	MOV	DTEFLG,AL
B6:	CMP	AL,'X'          ;Sort by extension?
	JNZ	B7		;Nope, try next one.
	MOV	EXTFLG,AL
B7:	CMP	AL,'N'          ;Original order?
	JNZ	B8		;Nope, try next one.
	MOV	SRTFLG,AL
B8:	CMP	AL,'P'          ;Pause when screen full?
	JNZ	B9		;Nope, try next one.
	MOV	PSEFLG,AL
B9:	LOOP	B2		;Test for another param.
B10:	RET
GETARGS ENDP
 
	SUBTTL	SRCHDIR - SEARCH DIRECTORY
	PAGE
SRCHDIR PROC	NEAR
	DOSCALL @SETDTA,DTA	;Set DTA for dir. search
	DOSCALL @SRCH1,XFCB	;First call to search dir.
C1:	OR	AL,AL
	JNZ	C2		;Not found, quit looking.
	MOV	BX,DIRLNK	;BX <- base of DIRBUF
	LEA	DI,[BX].NAM
	MOV	SI,OFFSET FILNAME
	MOV	CX,SIZE NAM
	CLD
	REPZ	MOVSB		;Move filename to DIRBUF
	MOV	BYTE PTR [DI],'.' ; Store a period
	INC	DI
	MOV	CX,SIZE EXT
	REPZ	MOVSB		;Move ext to DIRBUF
	MOV	SI,OFFSET FILTIME
	MOVSW			;Move time to DIRBUF
	MOVSW			;Move date to DIRBUF
	MOV	SI,OFFSET FILSIZE
	MOVSW			;Move size to DIRBUF
	MOVSW
	ADD	BX,SIZE DIRNTRY ;Point to next entry
	MOV	DIRLNK,BX	;Save ptr
	INC	NBRFILS 	;Increment file count
	DOSCALL @SRCH2,XFCB	;Search for next file
	JMP	C1		;Loop for next one
C2:	RET
SRCHDIR ENDP
 
	SUBTTL	SRTDIRB - SORTS ENTRIES IN DIRBUF
	PAGE
SRTDIRB PROC	NEAR	;Sorts directory entries in DIRBUF
	MOV	DI,OFFSET DIRBUF ;Point to DIRBUF
D1:	CMP	DI,DIRLNK	;Are there anymore?
	JNC	D8		;NO, exit
	MOV	SI,OFFSET C1LNK ;Start with column 1 ptr
D2:	MOV	BX,SI
	MOV	SI,[BX] 	;SI<-ptr to next entry
	OR	SI,SI
	JZ	D7		;if link=0
	MOV	AX,SI
	MOV	DX,DI
	XOR	CL,CL		;CL <- 0
	CMP	CL,SIZFLG
	JNZ	D5		;If sort by size
	CMP	CL,DTEFLG
	JNZ	D4		;If sort by date/time
	CMP	CL,EXTFLG
	JNZ	D3		;If sort by ext
	LEA	SI,[SI].NAM
	LEA	DI,[DI].NAM
	MOV	CX,1+SIZE NAM+SIZE EXT	;# of bytes
	JMP	SHORT D6
D3:	LEA	SI,[SI].EXT	;Sort by extension
	LEA	DI,[DI].EXT
	MOV	CX,SIZE EXT	;# of bytes
	JMP	SHORT D6
D4:	LEA	SI,[SI].DTE	;Sort by date/time
	LEA	DI,[DI].DTE
	MOV	CX,2		;# of words
	STD
	REPZ	CMPSW
	MOV	DI,DX
	MOV	SI,AX
	JBE	D2
	JMP	SHORT D7
D5:	LEA	SI,[SI].SZH	;Sort by size
	LEA	DI,[DI].SZH
	MOV	CX,2		;# of words
	STD
	REPZ	CMPSW
	MOV	DI,DX
	MOV	SI,AX
	JBE	D2
	JMP	SHORT D7
D6:	CLD			;Sort by name.ext
	REPZ	CMPSB
	MOV	DI,DX
	MOV	SI,AX
	JBE	D2
D7:	MOV	[DI],SI
	MOV	[BX],DI
	ADD	DI,SIZE DIRNTRY ;Point to next entry
	JMP	D1
D8:	RET
SRTDIRB ENDP
 
	SUBTTL
	PAGE
; LNKDIRB - LINKS ENTRIES IN DIRBUF
 
LNKDIRB PROC	NEAR		;LINK ENTRIES IN DIRBUF
	MOV	DI,OFFSET DIRBUF
	MOV	C1LNK,DI       ;Point to 1st entry
	MOV	CX,NBRFILS	;Set loop counter
	DEC	CX
LNK1:	MOV	BX,DI
	ADD	DI,SIZE DIRNTRY ;Offset to next entry
	MOV	[BX],DI 	;Store ptr
	LOOP	LNK1		;Link next entry
	MOV	[DI],CX 	;Last ptr <- null
	RET
LNKDIRB ENDP
 
; SPLTLST - SPLITS LINKED LIST IN HALF
 
SPLTLST PROC	NEAR
	MOV	CX,NBRFILS	;Get # of entries
	SAR	CX,1		; and divide by 2
	JZ	F2		;if NBRFILS < 2
	ADC	CL,0		;Account for odd #
	MOV	BX,OFFSET C1LNK
F1:	MOV	BX,[BX] 	;Chain thru list to
	LOOP	F1		; last row of column 1.
	MOV	AX,[BX] 	;Get ptr to 1st row of col 2
	MOV	C2LNK,AX	; C2LNK <- R1,C2 ptr
	MOV	[BX],CX 	;Last row of col 1 <- null
F2:	RET
SPLTLST ENDP
 
	SUBTTL	GETFREE - GET DISK FREE SPACE
    PAGE
GETFREE PROC        NEAR            ;cluster = allocation unit
    MOV     DL,DRVNBR       ;Get drive #
    PUSH    DS              ;Save DS
    DOSCALL @GETVER         ;get DOS version number                    JYF
    CMP     AL,2            ;is this version 2.0 or higher?            JYF
    JGE     E4              ;yes                                       JYF
                            ;no                                        JYF
    DOSCALL @FATAD2         ;Get FAT info from DOS
    MOV     AH,0            ;AL = sector size
    XCHG    CX,DX           ;Sector size times the
    MUL     DX              ; # sectors/cluster
    PUSH    AX              ;Save cluster size
    XOR     AX,AX           ;Unused clusters = 0
    MOV     SI,2            ;Skip first 3 clusters
E1: MOV     DI,SI           ;DI <- cluster #
    SHR     DI,1            ;Divide cluster number
    ADD     DI,SI           ; by 1.5
    MOV     DI,[BX+DI]      ;Fetch from FAT
    TEST    SI,1            ;Test if even or odd
    JZ      E2              ;If even then skip
    SHR     DI,1            ; else if odd
    SHR     DI,1            ;  right justify the
    SHR     DI,1            ;  cluster number.
    SHR     DI,1
E2: AND     DI,0FFFH        ;Mask the low 12 bits
    JNZ     E3              ;If not 0 then skip, else
    INC     AX              ; increment counter.
E3: INC     SI              ;Point to next cluster
    LOOP    E1              ; and go check it.
    POP     CX              ;Get cluster size, times
    MUL     CX              ;  # of free clusters
    JMP     E5              ;skip processing for DOS 2.0                JYF
E4:                         ;processing for DOS 2.00                    JYF
    DOSCALL @DSKFSP         ;get disk free space                        JYF
    MUL     BX              ;AX (sectors/clustor) * BX (free clustors)  JYF
    MOV     DX,AX           ;                                           JYF
    MUL     CX              ;AX * CX (bytes/clustor)                    JYF
E5:                         ;                                           JYF
    POP     DS              ;Restore DS
    MOV     LOSIZE,AX       ;Save the 32 bit
    MOV     HISIZE,DX       ; binary free space
    MOV     BX,C1LNK        ;Insert FREESPC in
    MOV     DI,OFFSET FREESPC ;first position
    MOV     [DI],BX         ; of linked list of
    MOV     C1LNK,DI        ; directory entries.
    INC     NBRFILS         ;Bump # of entries
    RET
GETFREE ENDP
 
    SUBTTL  PRTHDNG - PRINT HEADINGS
    PAGE
PRTHDNG PROC        NEAR
	MOV	AL,CLSFLG
	OR	AL,AL
	JNZ	G1		;If not erase screen
	SUB	CX,CX
	MOV	DX,24*256+79	;row=24 col=79
	MOV	BH,7		;Video mode
	MOV	AX,0600H
	INT	10H		;BIOS video call
	SUB	DX,DX
	MOV	AH,2		;Clear screen
	MOV	BH,0
	INT	10H		;BIOS video call
G1:	MOV	AL,DRVNBR	;Get drive #
	ADD	HDRVE,AL	;Convert to ascii
	DOSCALL @GETDTE ; CX<-year, DH<-month, DL<-day
	MOV	AL,DH
	AAM
	XCHG	AL,AH
	OR	D_MM,AX 	;Fold into month
	MOV	AL,DL
	AAM
	XCHG	AL,AH
	OR	D_DD,AX 	;Fold into day
	MOV	AX,CX
	SUB	AX,1900
	AAM
	XCHG	AL,AH
	OR	D_YY,AX 	;Fold into year
	DOSCALL @GETTME ; CH<-hours, CL<-minutes
	MOV	AL,CH		;AL<-binary hours
	AAM			;Convert AL to two
	XCHG	AL,AH		; BCD digits in AX.
	OR	T_HH,AX 	;Fold into hours
	MOV	AL,CL		;AL<-binary minutes
	AAM			;Convert AL to two
	XCHG	AL,AH		; BCD digits in AX.
	OR	T_MM,AX 	;Fold into minutes
	DOSCALL @STROUT,HDNG1	;Print main heading
	DOSCALL @STROUT,HDNG2	;Print column 1 heading
	CMP	WORD PTR C2LNK,0
	JZ	G2		;If not 2 columns
	DOSCALL @STROUT,SPACES-5 ;Print 5 spaces
	DOSCALL @STROUT,HDNG2	;Print column 2 heading
G2:	DOSCALL @STROUT,CRLF	;Start a new line
	RET
PRTHDNG ENDP
 
	SUBTTL	PRINT DETAIL LINES
	PAGE
PRTDRVR PROC	NEAR		;Driver routine
	MOV	BX,C1LNK
	OR	BX,BX		;more to print?
	JZ	H2		; no, return
	MOV	AX,[BX]
	MOV	C1LNK,AX
	CALL	PRTDTL		;print column one
	MOV	BX,C2LNK
	OR	BX,BX
	JZ	H1		;If no column 2 entry
	DOSCALL @STROUT,SPACES-5 ;print 5 spaces
	MOV	AX,[BX]
	MOV	C2LNK,AX
	CALL	PRTDTL		;print column two
H1:	DOSCALL @STROUT,CRLF
	CMP	PSEFLG,0	;Check for pause option
	JZ	PRTDRVR 	;Nope, continue
	DEC	LINCNT		;Decrement line counter
	JNZ	PRTDRVR 	;If page not full?
	MOV	LINCNT,LPERSCR-2 ;Reset to # lines/screen
	DOSCALL @STROUT,PSEMSG	;Display pause message.
	MOV	AL,@KEYIN	;Specify input function
	DOSCALL @CKEYIN 	;Wait for key press
	DOSCALL @STROUT,CRLF	;Set to new line
	JMP	PRTDRVR 	;Go do the next line
H2:	RET
PRTDRVR ENDP
 
PRTDTL	PROC	NEAR	;Prints file.ext, size, date & time
	MOV	CX,1+SIZE NAM+SIZE EXT
	SUB	DI,DI		;DI <- 0
I1:	DOSCALL @CHROUT,[BX+DI].NAM
	INC	DI		;point to next char.
	LOOP	I1		;go do next char.
	PUSH	BX		;save entry base
	MOV	SI,[BX].SZL	;SI <- low size
	MOV	DI,[BX].SZH	;DI <- high size
	CALL	PRINTDD 	;Print size
	POP	BX		;restore entry base
	DOSCALL @STROUT,SPACES-2 ;print 2 spaces
	MOV	AX,[BX].DTE	;AX <- packed date
	CALL	PRTDTE
	DOSCALL @STROUT,SPACES-2 ;print 2 spaces
	MOV	AX,[BX].TME	;AX <- packed time
	CALL	PRTTME
	RET
PRTDTL	ENDP
 
	SUBTTL	PRINTDD - PRINT A DOUBLE WORD IN DI:SI
	PAGE
PRINTDD PROC	NEAR	;Prints a 32 bit integer in DI:SI
	XOR	AX,AX		;Zero out the
	MOV	BX,AX		; working
	MOV	BP,AX		; registers.
	MOV	CX,32		;# bits of precision
J1:	SHL	SI,1
	RCL	DI,1
	XCHG	BP,AX
	CALL	J6
	XCHG	BP,AX
	XCHG	BX,AX
	CALL	J6
	XCHG	BX,AX
	ADC	AL,0
	LOOP	J1
	MOV	CX,1710H	;5904 ?
	MOV	AX,BX
	CALL	J2
	MOV	AX,BP
J2:	PUSH	AX
	MOV	DL,AH
	CALL	J3
	POP	DX
J3:	MOV	DH,DL
	SHR	DL,1		;Move high
	SHR	DL,1		; nibble to
	SHR	DL,1		; the low
	SHR	DL,1		; position.
	CALL	J4
	MOV	DL,DH
J4:	AND	DL,0FH		;Mask low nibble
	JZ	J5		;If not zero
	MOV	CL,0
J5:	DEC	CH
	AND	CL,CH
	OR	DL,'0'          ;Fold in ASCII zero
	SUB	DL,CL
	DOSCALL @CHROUT 	;Print next digit
	RET			;Exit to caller
PRINTDD ENDP
 
J6	PROC	NEAR
	ADC	AL,AL
	DAA
	XCHG	AL,AH
	ADC	AL,AL
	DAA
	XCHG	AL,AH
	RET
J6	ENDP
 
	SUBTTL	PRINT DATE, TIME & # FILES ROUTINES
	PAGE
PRTDTE	PROC	NEAR	;Print packed date in AX as MM/DD/YY
	OR	AX,AX
	JNZ	K1		;If date <> 0
	DOSCALL @STROUT,SPACES-8 ;Print 8 spaces
	RET
K1:	PUSH	AX
	AND	AX,MASK P_MO	;Mask the month,
	MOV	CL,P_MO 	; set shift count,
	SHR	AX,CL		; right justify, &
	CALL	PRTBCD		; print it.
	DOSCALL @CHROUT,'/'
	POP	AX
	PUSH	AX
	AND	AX,MASK P_DY	;Mask the day &
	CALL	PRTBCD		; print it.
	DOSCALL @CHROUT,'/'
	POP	AX
	AND	AX,MASK P_YR	;Mask the year,
	MOV	CL,P_YR 	; set shift count,
	SHR	AX,CL		; right justify,
	ADD	AX,80		; add in year bias, &
				; print it.
PRTBCD: AAM			;Convert AL to BCD
	OR	AX,'00'         ;Convert to ASCII
	PUSH	AX
	DOSCALL @CHROUT,AH	;High order digit
	POP	AX
	DOSCALL @CHROUT,AL	;Low order digit
	RET
PRTDTE	ENDP
 
PRTTME	PROC	NEAR	;Print packed time in AX as HH:MM
	OR	AX,AX
	JNZ	L1
	DOSCALL @STROUT,SPACES-5 ;Print 5 spaces
	RET
L1:	PUSH	AX
	AND	AX,MASK P_HR	;Mask the hours,
	MOV	CL,P_HR 	; set shift count,
	SHR	AX,CL		; right justify, &
	CALL	PRTBCD		; print it.
	DOSCALL @CHROUT,':'
	POP	AX
	AND	AX,MASK P_MI	;Mask the minutes,
	MOV	CL,P_MI 	; set shift count,
	SHR	AX,CL		; right justify, &
	CALL	PRTBCD		; print it.
	RET
PRTTME	ENDP
 
PRTNFLS PROC	NEAR	;print number of files
	MOV	SI,NBRFILS	;get # of files
	DEC	SI		;-1 for free space
	XOR	DI,DI		;zero high order
	CALL	PRINTDD 	;Print # of files
	DOSCALL @STROUT,HDNG3
	RET
PRTNFLS ENDP
	EVEN
DIRBUF	DIRNTRY <>	;Buffer for directory entries
SDIR	ENDS
	END	MAIN
