home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
asm_kit
/
diskdirl.asm
< prev
next >
Wrap
Assembly Source File
|
1984-07-31
|
18KB
|
455 lines
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