Metropoli BBS
VIEWER: size.asm MODE: TEXT (ASCII)
	  title  SIZE.ASM by Art Merrill
	  page,132
cseg      segment para 'code'
	  assume cs:cseg
main	  proc	 far
	  org	 100h
start:	  jmp	 begin

banner    db     lf,'SIZE Vers 1.0 - ',cr,lf,'$'
          db     'Copyright (C) 1985',cr,lf,'$'
          db     'Ziff-Davis Publishing Company',cr,lf,'$'
lf	  equ	 0ah
cr	  equ	 0dh
dta	  equ	 80h
drive     db     0,':'
root      db     '\'
global    db     '*.*'
buffer	  db	 65 dup(0)
count	  dw	 0
tot_bytes dw	 0,0
disk_bloks dw	 0
fix_bloks dw	 0

asc_bytes db     lf,8 dup(0),' bytes in '
asc_files db     4 dup(0),' file(s)',cr,lf
asc_disk  db     8 dup(0),' bytes required on diskette(s)',cr,lf
asc_fix   db     8 dup(0),' bytes required on fixed disk',cr,lf,lf,'$'

errmsg    db     lf,'Invalid parameter(s)',cr,lf
          db     'or file(s) not found',cr,lf,lf,'$'
begin:
	  push	 ds		       ;set up stack for return
	  sub	 ax,ax
	  push	 ax

	  mov	 dx,offset banner      ;print banner
	  mov	 ah,9
	  int	 21h

;get current drive

	  mov	 di,offset drive       ;storage area for drive
	  mov	 dx,offset global      ;we may need this address later
	  mov	 ah,19h 	       ;current disk function
	  int	 21h
	  add	 al,41h 	       ;convert to ascii
	  stosb 		       ;store it

;check for parameters

	  cld			       ;clear direction flag
	  mov	 di,offset buffer      ;set up register for storage
	  mov	 si,dta 	       ;start of data transfer area (dta)
	  lodsb 		       ;get first byte
	  cmp	 al,0		       ;zero indicates no parms entered
	  jnz	 aaa		       ;parms were entered
	  call	 add_global	       ;add global chars
	  jmp	 find_first	       ;proceed with search
aaa:
          cmp    al,2                  ;did user enter just '\'?
	  jnz	 aac		       ;no
	  inc	 si
	  lodsb
          cmp    al,'\'                ;check for backslash
	  jz	 aab		       ;found
	  jmp	 error		       ;not found-error exit
aab:
	  mov	 si,offset drive       ;move drive,backslash and
	  mov	 cx,6		       ;   global chars into buffer
rep	  movsb
	  jmp	 find_first	       ;proceed with search
aac:
	  cmp	 al,3		       ;did user enter just a drive?
	  jnz	 aag		       ;no
	  inc	 si
	  lodsb
	  or	 al,20h 	       ;make lower case if not already
          cmp    al,'a'                ;is it A or greater?
	  jge	 aad		       ;yes
	  jmp	 error		       ;no-error exit
aad:
          cmp    al,'d'                ;is it D or less?
	  jle	 aae		       ;yes
	  jmp	 error		       ;no-error exit
aae:
	  stosb 		       ;store drive letter
	  lodsb 		       ;get next byte
          cmp    al,':'                ;is it a colon?
	  jz	 aaf		       ;yes
	  jmp	 error		       ;no-error exit
aaf:
	  stosb 		       ;store it
	  call	 add_global	       ;add global chars to buffer
	  jmp	 find_first	       ;proceed with search
aag:
	  cmp	 al,4		       ;did user enter drive and \
	  jnz	 aah		       ;no
	  inc	 si		       ;yes-get next byte
	  mov	 cx,3		       ;get all 3 chars
rep	  movsb
	  call	 add_global	       ;add global chars to drive and \
	  jmp	 find_first	       ;proceed with search
aah:
	  inc	 si		       ;user must have entered a path
aai:
	  lodsb 		       ;load first char
	  cmp	 al,0dh 	       ;is it end of entry?
	  jz	 find_first	       ;yes-proceed with search
	  stosb 		       ;no-store char
	  jmp	 aai		       ;get another byte
find_first:
	  mov	 dx,offset buffer      ;start of pathname in memory
	  mov	 cx,20h 	       ;attribute to search for
	  mov	 ah,4eh 	       ;find first function
	  int	 21h
	  jnc	 found_first	       ;file found-proceed to find next
	  jmp	 error		       ;no file found or invalid path
found_first:
	  call	 tally		       ;add to running total
find_next:
	  mov	 ah,4fh 	       ;find next function
	  int	 21h
	  jc	 count_up	       ;no more files found
	  call	 tally		       ;add to running total
	  jmp	 find_next	       ;look for another
count_up:
	  mov	 ax,tot_bytes	       ;low word of total bytes
	  mov	 dx,tot_bytes+2        ;high word of total bytes
	  mov	 di,offset asc_bytes+8 ;end of output string
	  call	 ascii		       ;convert to ascii

	  mov	 ax,count	       ;get total number of files
	  sub	 dx,dx		       ;clear high word
	  mov	 di,offset asc_files+3 ;end of output string
	  call	 ascii		       ;convert to ascii

	  mov	 ax,disk_bloks	       ;total blocks for diskette
	  mov	 bx,400h	       ;1024 decimal=2 clusters
	  mul	 bx
	  mov	 di,offset asc_disk+7  ;end of output string
	  call	 ascii		       ;convert to ascii

	  mov	 ax,fix_bloks	       ;total blocks for fixed disk
	  mov	 bx,1000h	       ;4096 decimal=4 clusters
	  mul	 bx
	  mov	 di,offset asc_fix+7   ;end of output string
	  call	 ascii		       ;convert to ascii

	  mov	 dx,offset asc_bytes   ;start of printout
	  jmp	 exit
error:
	  mov	 dx,offset errmsg
exit:
	  mov	 ah,9		       ;DOS function - print string
	  int	 21h

	  ret

main	  endp

add_global proc  near
	  xchg	 si,dx		       ;location of global chars
	  mov	 cx,3		       ;number of chars
rep	  movsb
	  ret
add_global endp

ascii	  proc	 near
	  xchg	 bp,dx		       ;save high word
	  mov	 bx,0ah 	       ;divisor
	  mov	 cl,30h 	       ;conversion for ascii
aaj:
	  xchg	 ax,bp		       ;get high word
	  sub	 dx,dx		       ;clear register
	  div	 bx
	  xchg	 bp,ax		       ;this will be the new high word
	  div	 bx		       ;divide low word + remainder
	  or	 dl,cl		       ;convert new remainder to ascii
	  mov	 [di],dl	       ;quotient into storage
	  dec	 di		       ;step back one byte
	  cmp	 ax,0		       ;are we done?
	  jnz	 aaj		       ;no
	  ret			       ;yes-exit
ascii	  endp

tally	  proc	 near
	  sub	 dx,dx		       ;clear register
	  inc	 count		       ;add 1 more file to count
	  mov	 bp,9ah 	       ;location of files size in psp
	  mov	 ax,[bp]	       ;get low word
	  mov	 dx,[bp+2]	       ;get high word
	  push	 dx		       ;save for next step
	  push	 ax		       ;save for next step
	  mov	 bx,400h	       ;1024 decimal=2 clusters
	  div	 bx
	  cmp	 dx,0		       ;is there a remainder?
	  jz	 aak		       ;no
	  inc	 disk_bloks	       ;yes-add another block to running total
aak:
	  add	 disk_bloks,ax	       ;add number of blocks to running total
	  pop	 ax		       ;get back low word
	  pop	 dx		       ;get back high word
	  push	 dx		       ;save for next step
	  push	 ax		       ;save for next step
	  mov	 bx,1000h	       ;4096 decimal=4 clusters
	  div	 bx
	  cmp	 dx,0		       ;is there a remainder?
	  jz	 aal		       ;no
	  inc	 fix_bloks	       ;yes-add another block to running total
aal:
	  add	 fix_bloks,ax	       ;add number of blocks to running total
	  pop	 ax		       ;get back low word
	  add	 tot_bytes,ax	       ;add low word to running total
	  jnc	 no_carry
	  inc	 tot_bytes+2	       ;bump up high word
no_carry:
	  pop	 ax		       ;get back high word
	  add	 tot_bytes+2,ax        ;add high word to running total
	  ret			       ;exit
tally	  endp

cseg	  ends
	  end	 start

[ RETURN TO DIRECTORY ]