home *** CD-ROM | disk | FTP | other *** search
- title DISKDIRL - DISKette DIRectory List Ver 1.0
- page 85,132
- ;
- code segment
- assume cs:code,ds:code
- ;
- org 100h
- begin: jmp starther
- ;
- version db 0 ;DOS Version flag
- defdrv db 0 ;Default drive address at entry
- numdrv db 0 ;Number of drives in the system
- drivemsg db 13,10,'Enter drive to be listed (Esc to end): $'
- errmsg1 db 13,10,'Invalid drive letter$'
- setprt db 27,'0',27,'C',44,15,0 ;Set 1/8" 132 ch 44 ln condensed
- restprt db 27,64,0 ;Restore printer to power up status
- restr db 12,0 ;Printer "restore" forms command
- titlelen equ 44 ;Length of user inputed title line
- titlemsg db 13,10,'Enter 44 char title: $'
- titlebuf db titlelen+1,0 ;Input buffer for user title
- db titlelen+1 dup (?)
- title1 db 6 dup (' ') ;First title line
- titlelne db 49 dup (' ') ;Where user supplied title input goes
- db 'Free: '
- freespc db 10 dup (' ') ;Formatted free space in title line
- month db ' /' ;Date fields in title line
- day db ' /'
- year db ' ',0 ;End of title
- f10000 dw 10000 ;Conversion constants
- f1000 dw 1000,100,10
- extfcb db 0ffh,5 dup (0),16h ;Extended FCB for read all entries
- db 0,11 dup('?'),24 dup (?)
- stacknum dw 0 ;Count of entries in stack
- entryprt db 0 ;Number of entries printed
- lnecnt db 0 ;Line count of current entry
- work db 7 dup (0),' ',0 ;Work buffer for file size
- leftbdr db '| ',0 ;Left border
- rightbdr db ' |' ;* Right border (includes CRLF)
- crlf db 13,10,0 ;* Carriage return + line feed
- page
- starther proc near
- mov dx,offset setprt
- call prtstrng ;Set printer with required options
- mov ah,30h
- int 21h ;Check DOS Version
- or al,al
- jz notver2 ;Version 1.x
- dec al ;Version 2.x
- notver2: mov version,al ;Save DOS version flag
- mov ah,19h
- int 21h ;Get default drive
- mov defdrv,al ;Save it
- mov dl,al
- mov ah,0eh
- int 21h ;Get number of drives
- mov numdrv,al ;Save it
- ;
- ; Start of main loop
- ;
- mainloop: mov dx,offset drivemsg
- mov ah,9
- int 21h ;Prompt for drive for directory read
- mov ah,1
- int 21h ;Get user response
- cmp al,1bh ;Check for exit (Esc char)
- je finished ;We're done, so end program
- or al,' ' ;Force lower case
- sub al,'a'-1 ;Compute drive number (A = 0)
- jnc drvok ;Check for valid drive
- msgerror: mov dx,offset errmsg1 ;Invalid drive message
- mov ah,9
- int 21h ;Put out error message
- jmp mainloop
- finished: mov dl,12
- mov ah,2
- int 21h ;Force page restore
- mov dl,defdrv ;Load default drive at entry
- mov ah,0eh
- int 21h ;Restore default drive
- test entryprt,1 ;Were any entries printed ?
- jz norest ;Skip if not
- mov dx,offset crlf
- call prtstrng ;Restore page
- norest: mov dx,offset restprt
- call prtstrng ;Reset printer
- int 20h ;Exit program
- drvok: cmp al,numdrv ;Check for installed drive
- ja msgerror ;Drive not installed
- dec al
- mov dl,al
- mov ah,0eh
- int 21h ;Make selected drive default
- ;
- ; Get Title routine
- ;
- mov di,offset title1
- mov cx,55 ;Length to clear
- mov al,' '
- rep stosb ;Clear title line
- mov dx,offset titlemsg
- mov ah,9
- int 21h ;Prompt for title
- mov dx,offset titlebuf
- mov ah,0ah
- int 21h ;Get title from user
- mov cl,titlebuf+1 ;Load length
- xor ch,ch
- mov si,offset titlebuf+2
- mov di,offset titlelne
- rep movsb ;Move user title to title line
- mov ah,2ah
- int 21h ;Get today's date
- sub cx,1900 ;Convert to two digit year
- mov di,offset year
- mov al,cl
- call decimal ;Fill in month/day/year on title line
- mov di,offset month
- mov al,dh
- call decimal
- mov di,offset day
- mov al,dl
- call decimal
- ;
- ; Get Free Space routine
- ;
- test version,1 ;DOS version 2.x will supply that
- jz vers1x
- xor dl,dl ;Set for default drive
- mov ah,36h
- int 21h ;Ver 2.x - get free space from DOS
- mul bx
- mul cx ;AX,DX contains bytes free
- jmp vers1x4 ;Enter common code
- vers1x: push ds
- mov ah,1bh
- int 21h ;Ver 1.x - get FAT
- xor ah,ah
- xchg cx,dx ;CX has number of units
- mul dx ;Bytes/allocation unit
- push ax ;Save
- xor ax,ax
- mov si,2 ;First FAT entry
- vers1x1: mov di,si
- shr di,1
- add di,si ;Compute 1 1/2 bytes
- mov di,word ptr [bx+di] ;Load FAT entry
- test si,1 ;See if odd or even
- jz vers1x2
- push cx
- mov cl,4
- shr di,cl ;Adjust for 12 bits
- pop cx
- vers1x2: and di,0fffh ;Three nibbles
- jnz vers1x3 ;In use, so don't count
- inc ax
- vers1x3: inc si ;Step to next entry
- loop vers1x1 ;Loop through FAT
- pop cx ;Restore bytes/allocation unit
- mul cx ;Compute total free bytes
- pop ds ;Restore program seg reg
- vers1x4: mov di,offset freespc ;Point to output area
- call convert ;Convert size to ASCII
- ;
- ; Load Directory Entries routine
- ;
- mov di,offset ptrtbl
- xor ax,ax
- mov cx,121
- rep stosw ;Clear pointer table
- mov bx,offset ptrtbl ;BX points to start of pointer list
- mov di,offset entries ;DI points to start of entry stack
- xor cx,cx
- mov dx,offset extfcb
- mov ah,11h
- nxdirent: int 21h ;Get next entry
- or al,al
- jnz sortdir
- call saventry ;Stack entry
- inc cx ;Count entry
- mov dx,offset extfcb
- mov ah,12h
- jmp nxdirent
- ;
- ; Sort Directory Entries routine
- ;
- sortdir: mov stacknum,cx ;Save entry count
- dec cx
- mov si,offset ptrtbl ;Point to first stack entry ptr
- sortdir1: mov di,si
- add di,2 ;Set to "next" pointer
- mov dx,cx
- push cx
- sortdir2: push si ;This compare forces short strings
- push di ; low since they end with nuls
- mov cx,12 ;Max compare allowed
- mov si,word ptr [si] ;Point to entry
- mov di,word ptr [di] ;Point to other entry
- rep cmpsb ;Compare strings
- pop di
- pop si
- jbe sortdir3 ;Ascending sequence, so no change
- mov ax,word ptr [si]
- xchg ax,word ptr [di]
- mov word ptr [si],ax ;Exchange pointers
- sortdir3: add di,2
- dec dl
- jnz sortdir2 ;Bubble through inner loop
- pop cx
- add si,2
- loop sortdir1 ;Bubble through outer loop
- ;
- ; Have Listing Produced routine
- ;
- inc entryprt ;Count numbers of prints
- mov ax,stacknum ;Load entry count
- add ax,2 ;Round up before divide
- mov dh,3 ;Divide by num of entrys per line
- div dh
- cbw
- push ax ;Entries per column count
- mov cx,33 ;Set body default line count
- cmp ax,cx ;See if number of lines to print
- jl prtent2 ; is greater than the default
- mov cx,ax
- prtent2: mov lnecnt,cl ;Set new body line count
- call prtbordr ;Do upper border
- call blanklne ;Do a blank line
- call prtlbdr ;Do left margin
- mov dx,offset title1
- call prtstrng ;Output the title line
- mov cx,6 ;Add 6 extra blanks after date
- call prtblks
- call prtrbdr ;Do right margin
- call blanklne ;Another blank line
- pop cx
- mov bp,cx
- shl bp,1 ;BP has offset/col in ptr list
- mov si,offset ptrtbl ;Point to start of ptr list
- prtent3: call prtlbdr ;Do a left margin
- mov dl,3 ;Set inner loop count to columns
- xor bx,bx ;Clear column offset reg
- prtent4: call prtentry ;Print stack entry
- add bx,bp ;Step to next column entry
- dec dl
- jnz prtent4 ;End of inner loop
- call prtrbdr ;Do a right margin
- add si,2 ;Step to next ptr
- dec lnecnt ;Decrement body line count
- loop prtent3 ;End of outer loop
- mov cl,lnecnt ;Load remaining body lines
- xor ch,ch
- jcxz prtent6 ;All used
- prtent5: call blanklne ;Fill out body lines
- loop prtent5
- prtent6: call prtbordr ;Do bottom border
- mov dx,offset restr
- call prtstrng ;Restore page
- jmp mainloop
- starther endp
- page
- decimal proc near ;Converts AL to two decimal digits
- aam ;Store it at SI
- or ax,'00'
- xchg al,ah
- stosw ;Save in image
- ret
- decimal endp
- ;
- convert proc near ;Convert 6 digits, zero surpressed
- push di ;Save pointer for later use
- div f10000 ;Result range 0-99
- aam
- or ax,'00' ;Make ASCII
- xchg ah,al
- stosw ;Place in image
- mov cx,3 ;Convert last four digits
- mov si,offset f1000
- divloop: mov ax,dx ;Remainder becomes dividend
- xor dx,dx
- div word ptr [si] ;Power of 10 divide
- or al,'0' ;Result range 0-9
- stosb
- add si,2
- loop divloop
- or dl,'0' ;Last digit in remainder
- mov al,dl
- stosb
- mov cx,5 ;Now zero surpress 5 digits
- pop di
- mov al,' '
- padloop: cmp byte ptr [di],'0'
- jnz cnvtret ;Conversion complete
- stosb ;Replace leading zero with blank
- loop padloop
- cnvtret: ret
- convert endp
- ;
- saventry proc near
- push cx
- mov word ptr [bx],di ;Save pointer to start of entry
- add bx,2 ;Step pointer table reg
- push di ;Save DI for now
- mov di,81h+7+8 ;Point pass end of DTA - file name
- mov cx,8
- savcmpfn: dec di
- cmp byte ptr [di],' ' ;Look for last non-blank in name
- loope savcmpfn
- add cx,1 ;Compensate for LOOPE
- mov si,81h+7 ;Point to beginning DTA - file name
- pop di
- rep movsb ;Copy DTA - file name to 'entries:'
- mov si,89h+7 ;Point to DTA type field
- cmp byte ptr [si],' '
- jz savend ;No file type
- mov byte ptr [di],'.'
- inc di
- mov cx,3
- rep movsb ;Move type field to stack
- savend: mov byte ptr [di],0 ;Mark end of string
- inc di
- mov si,9dh+7 ;Point to size of file
- mov cx,4
- rep movsb ;And save in stack
- mov si,99h+7 ;Point to last update date
- movsw ;Save it in the stack
- pop cx
- ret
- saventry endp
- ;
- prtstrng proc near ;This sub prints the string pointed
- push dx ; to by the DX reg on entry.
- push si ; The string is terminated by
- mov si,dx ; a nul byte.
- mov ah,5
- prtsloop: mov dl,byte ptr [si]
- or dl,dl
- jz prtsend
- int 21h
- inc si
- jmp prtsloop
- prtsend: pop si
- pop dx
- ret
- prtstrng endp
- ;
- prtentry proc near ;Print one stack entry
- push bx
- push cx
- push dx
- mov cx,12
- mov di,word ptr [si+bx] ;DI points to stack entry
- or di,di
- jz prtenty4
- mov ah,5
- prtenty1: mov dl,byte ptr [di] ;Print to the end of the name/type
- or dl,dl ; entry blanking remainder of 12
- jz prtenty5 ; character field
- int 21h
- inc di
- loop prtenty1
- prtenty2: inc di
- mov ax,word ptr[di] ;Load file size
- mov dx,word ptr[di+2]
- mov bx,word ptr[di+4] ;Load file last update date
- push si
- mov di,offset work
- call convert ;Convert size to ASCII decimal
- pop si
- mov dx,offset work
- call prtstrng ;One blank between fields
- mov ax,bx ;Save last update date data
- mov cl,1+8 ;Shift year in bottom part of reg
- shr ax,cl
- add ax,80 ;Format in year-1980, correct for it
- mov di,offset year
- call decimal ;Make year printable
- mov ax,bx ;Now do month
- mov cl,5
- shr ax,cl
- and ax,000fh ;Reg now has month in it
- mov di,offset month
- call decimal
- mov ax,bx ;Finally do day
- and ax,001fh
- mov di,offset day
- call decimal
- mov dx,offset month-1 ;Use date starting with a blank
- call prtstrng ;Go print it
- prtenty3: pop dx
- push dx ;Reload entry value
- dec dl
- jz prteend ;If last column, don't space over
- mov cx,2
- call prtblks ;Two blanks between columns
- prteend: pop dx
- pop cx
- pop bx
- ret
- prtenty4: mov cx,27 ;No entry, so blank entire column
- call prtblks
- jmp prtenty3
- prtenty5: call prtblks ;Blanks remainder of name/type field
- jmp prtenty2
- prtentry endp
- ;
- blanklne proc near
- push cx
- call prtlbdr ;Output a bordered blank line
- mov cx,85
- call prtblks ;Go clear line
- call prtrbdr ;Print right margin
- pop cx
- ret
- blanklne endp
- ;
- prtbordr proc near
- mov cx,89
- mov dl,'-'
- call prtblk1 ;Output a top or bottom border
- mov dx,offset crlf
- call prtstrng
- ret
- prtbordr endp
- ;
- prtlbdr proc near ;Outputs "| "
- push dx
- mov dx,offset leftbdr
- call prtstrng
- pop dx
- ret
- prtlbdr endp
- ;
- prtrbdr proc near ;Outputs " |CRLF"
- push dx
- mov dx,offset rightbdr
- call prtstrng
- pop dx
- ret
- prtrbdr endp
- ;
- prtblks proc near ;Outputs CX blanks to the printer
- mov dl,' '
- prtblk1: mov ah,5 ;Outputs DL char CX times
- prtbloop: int 21h
- loop prtbloop
- ret
- prtblks endp
- ;
- ptrtbl dw 0 ;Pointer list
- entries equ ptrtbl+121*2 ;Start of entry stack
- ;
- code ends
- ;
- end begin