home *** CD-ROM | disk | FTP | other *** search
- ; tree.asm g.r.green
- ; program to draw directory tree of the default drive
- ; running msdos.
- ;
- ; changes made to accomodate for the IBM line drawing set
- ; Hans ZURFCC::Zangger Aug 86 {Baum == german for 'tree'
- ;
- ; TREE.ASM Copyright (C) by Gordon R. Green
- ; 9-May-1985 All Rights Reserved. Released For Any
- ; use without cost exceeding the cost of handling
- ; and reproduction, as long this heading is
- ; included with all or any part used of this
- ; program and credit given to Gordon R. Green.
- ;
- ; Gordon R. Green
- ; 7 Juniper St.
- ; Hudson, N.H. 03051
- ;
- ;
- ; Installation Instructions:
- ; masm tree
- ; link tree ; ignore lack of stack err msg!!!
- ; exe2bin tree.exe tree.com
- ; del tree.exe
- ;
- ; Invocation:
- ; TREE ; takes no arguments
-
-
- ;**************************************************************
- ; Macro definitions
-
- ; DISPLAY STRING
- display macro string
- mov dx,offset string
- mov ah,9
- int doscall
- endm
-
- ; SET_DTA
- set_dta macro buffer
- mov dx,offset buffer
- mov ah,1AH
- int doscall
- endm
-
- ; SEARCH_FIRST
- search_first macro fcb
- mov dx,offset fcb
- mov ah,11H
- int doscall
- endm
- ;
- FSCROLL EQU 6 ;BIOS function = scroll
- FLOCATE EQU 2 ;BIOS function = locate
- COLOR EQU 7 ;attribute, white on black background
- ALL EQU 0 ;indicates entire screen on scroll
- HOR EQU 196
- VER EQU 179
- COR EQU 192
- LFIN EQU 195
- TFIN EQU 194
- BFIN EQU 192
- FACE EQU 1
- ;
- BIOSCAL MACRO FUNCTION
- MOV AH,FUNCTION ;specify function desired
- INT 10H ;call BIOS for desired function
- ENDM
- ;
-
- SCROLL MACRO POS1,POS2,ATTRIBUTE,ROWS
- ;;coordinates to be presented in row,col format as a single number, as:
- ;;row * 256 + col
- ;;
- ;;POS1 =upper left coordinate
- ;;POS2 =lower right coordinate
- ;;ATTRIBUTE =color descriptor of fill character
- ;;ROWS =how many rows to be scrolled (0=do entire screen)
-
- MOV CX,POS1 ;upper left corner
- MOV DX,POS2 ;botton right corner
- MOV BH,ATTRIBUTE ;pass how to color fill
- MOV AL,ROWS ;do entire window
- BIOSCAL FSCROLL ;request scroll function from bios
- ENDM
- ;
- LOCATE MACRO ROW,COL
- MOV DH,ROW ;move cursor to this row
- MOV DL,COL ;and to this col in this screen number
- MOV BH,0
- BIOSCAL FLOCATE ;move cursor
- ENDM
- ;
- ; End of macros
- ;**************************************************************
-
-
- ;**************************
- ;*** ***
- ;*** EQU Statements ***
- ;*** ***
- ;**************************
-
- max_level equ 14
- doscall equ 21H
-
- ; dos calls
- type_chr equ 2
- find_file equ 4EH
- find_nxt_file equ 4FH
-
- ; ASCII characters
- CR equ 0DH
- LF equ 0AH
- H_TAB equ 9
-
-
- ;**************************
- ;*** ***
- ;*** Main Program ***
- ;*** ***
- ;**************************
-
- ;***********************************************************
- prognam segment ;define code segment
-
- org 100H
-
- assume cs:prognam, ds:prognam, ss:prognam
-
- start:
- push ds ; set up return to DOS
- call crlf
- xor ax,ax ; clear ax
- push ax
- call init ; init tables, save current directory,
- ; switch to root
- ; read disk name and display it
-
- set_dta buffer
- search_first fcb ; look for disk name
- cmp al,0FFH ; found?
- jne name_fnd ; if yes
- ; mov al," " ; else fill in blank name
- ;display hig_vid
- display no_label ; else say No Label
- jmp nolabel
- mov di,offset buffer+8
- mov cx,11
- repz stosb
- name_fnd:
- mov al,"$" ; insert string terminator
- mov buffer[19],al
- ;display hig_vid
- ;display spaces1
- display buffer[8] ; display name in reverse video
- nolabel:
- ;display reg_vid
- display link ; draw lines down to main tree
- mov unused,3 ; force proper positioning later
-
- ; read root directory into memory and sort it
- mov di,offset buf ; pntr to filename storage
- mov begin_dir,di
- call get_file_names ; get filenames for this level
- mov bx,level
- mov begin_dir[bx+2],di ; mark start of next level
- mov num_dir[bx],ax ; save # of directories at this level
- cmp ax,0 ; any sub-diretories?
- je no_sub_dirs ; if none in root, then no tree
-
- main_loop:
- mov bx,level ; all dirs done at this level?
- mov ax,cur_dir[bx]
- cmp ax,num_dir[bx]
- jne more_dirs ; if not
- cmp bx,0 ; are we at top level?
- jne up ; if no
- abort: jmp quit ; if yes
- more_dirs:
- call dn_level ; go down one level
- mov bx,level ; init di with where to store filenames
- mov di,begin_dir[bx]
- call get_file_names
- mov bx,level ; save pntr for next level
- mov begin_dir[bx+2],di
- mov num_dir[bx],ax ; save # dirs at this level
- mov cur_dir[bx],0 ; set cur_dir=0 for this level
- cmp ax,0 ; any dirs?
- jne more_dirs ; if yes, go dn another level
- call crlf
- mov unused,-1
- up:
- call up_level ; else go up a level
- mov bx,level ; bump cnt of cur_dir
- inc cur_dir[bx]
- jmp main_loop ; and loop back
- quit:
- call crlf
- mov ah,3BH ; restore original directory
- mov dx,offset old_dir
- int doscall
- ret ; exit to dos
-
- no_sub_dirs:
- display no_subdirs
- jmp quit
-
- ;**********************************
- ;*** ***
- ;*** Support Routines ***
- ;*** ***
- ;**********************************
-
- ;**************************************************************
- ; initialize a bunch of things
- ; on entry ax = 0
- init:
- ; init tables (begin_dir, num_dir, cur_dir)
- mov di,offset begin_dir ; (ax = 0)
- mov cx,max_level * 3
- repz stosw
- mov level,ax ; (ax = 0)
-
- ; init default file spec at 5CH
- mov al,"?" ; fill with wildcards
- mov di,byte ptr 5DH ; default fcb+1
- mov cx,11
- repz stosb
-
- ; save current directory name
- mov ah,47H ; get current directory name
- mov si,offset old_dir+1 ; and put here
- mov dl,0 ; from present drive
- int doscall
-
- ; change to root_directory
- mov ah,3BH ; change current directory
- mov dx,offset root_dir ; to root-directory
- int doscall
- scroll 0,24*256+79,color,all ; scroll row=24, col=79 (zero relative)
- locate 0,0 ;Cursor to top left at (0,0)
- locate 0,65
- display sign_on
- locate 0,0
- ret ; escape sequence
-
-
- ;**************************************************************
- ; move down a directory level
-
- dn_level:
- ; move to new directory
- mov bx,level
- mov si,begin_dir[bx] ; where names start for this level
- mov ax,cur_dir[bx] ; cur_dir
- mov cx,11
- mul cl ; times size = offset
- add ax,si ; ax points to next name
- mov si,ax ; move to si
- mov di,offset dn_dir + 2
- mov cx,8 ; ready to move 8 chars
- repz movsb
- call show_name ; display the directory name
- mov ah,3BH ; change current directory
- mov dx,offset dn_dir
- cmp level,0
- jne dn_lv
- inc dx
- dn_lv:
- int doscall ;### error chk?
- inc level ; adjust level count
- inc level ; by 2
- ret
-
-
- ;**************************************************************
- ; show directory name
-
- show_name:
- cmp unused,-1 ; new line?
- jne shnm0 ; if not
- call do_indents
- mov unused,0
- shnm0: mov cx,unused ; any unused?
- cmp cx,0 ; if not
- je shnm2
- shnm1: mov dl, HOR ; else pad with hor lines
- mov ah,2
- int doscall
- loop shnm1
- shnm2: mov bx,level
- mov end_pad, LFIN ; init end_pad to left "T"
- cmp cur_dir [bx],0 ; determine end_pad value
- jne shnm3
- mov end_pad, TFIN ; if 1st, top "T"
- shnm3: mov ax,cur_dir [bx]
- inc ax
- cmp ax,num_dir [bx]
- jne shnm4
- mov end_pad, BFIN ; if last, lower left corner
- shnm4: dec ax
- cmp ax,0
- jne shnm5
- cmp num_dir[bx],1
- jg shnm5
- mov end_pad, HOR ; if 1st & last, horizontal line
- shnm5: mov dl,end_pad ; output end_pad
- mov ah,2
- int doscall
- ;display spaces1
- ;display hig_vid ; switch to reverse video
- mov bx,offset dn_dir + 2 ; output name
- mov dl,[bx] ; first character
- mov ah,2
- int doscall
- inc bx
- mov cx,7 ; 7 more characters in filename
- shnm6: mov dl,[bx] ; all but first char in lower case
- cmp dl,0
- je shnm8 ; if nul
- cmp dl,"A"
- jl shnm7
- cmp dl,"Z"
- ; jg shnm7
- ; or dl," "
- shnm7: mov ah,2 ; finally output char
- int doscall
- inc bx
- loop shnm6 ; loop for all chars
- shnm8: mov unused,cx
- ;display spaces1
- ;display reg_vid ; back to normal video
- ret
-
-
- ;**************************************************************
- ; handle the indents at beginning of line
-
- do_indents:
- mov bx,0 ; "level" for this routine
- do_ind1:
- display spaces8 ; output leading spaces8
- cmp bx,level ; done if present level
- je do_ind3
- mov dl," " ; else output space
- mov ax,cur_dir [bx]
- inc ax
- cmp ax,num_dir [bx]
- je do_ind2
- ;display spaces1
- mov dl, VER ; or vertical bar
- do_ind2:
- mov ah,2
- int doscall
- do_ind3:
- inc bx ; bump local index
- inc bx
- cmp bx,level ; see if we are done
- jle do_ind1 ; if not
- ret
-
- ;**************************************************************
- ; move up a directory level
-
- up_level:
- mov ah,3BH ; change current directory
- mov dx,offset up_dir ; up a level
- int doscall ;### error chk?
- dec level ; adjust level count
- dec level ; by 2
- ret
-
-
- ;**************************************************************
- ; get list of files that match
- ; entry - di = addr of place to put data
- ; return - di = addr of next data loc
- ; ax = # files found (stored in tmp_cnt during routine)
-
- get_file_names:
- mov tmp_loc,di
- mov tmp_cnt,0 ; init file cntr for this routine
- push di
- set_dta fb_reserve ; set data transfer area
- mov al,0 ; clear fb_pname area
- mov di,offset fb_pname
- mov cx,11
- repz stosb
- pop di
- mov ah,find_file ; find match file
- mov dx,5DH ; point at default fcb+1
- mov cx,010H ; attributes to look for
- int doscall
- jnc sav_nam ; if we found something
- mov ax,0 ; else
- ret ; return with cnt=0
-
- sav_nam:
- cmp fb_attr,10H ; directory?
- jne no_save ; if not
- cmp fb_pname, '.' ; named "."?
- je no_save ; if yes
- mov si,offset fb_pname ; else save filename
- mov cx,11
- repz movsb
- inc tmp_cnt ; bump file cnt
- no_save:
- push di
- mov al,0 ; clear fb_pname area
- mov di,offset fb_pname
- mov cx,13
- repz stosb
- pop di
- mov ah,find_nxt_file ; find nxt file match
- int doscall
- cmp al,18 ; any file?
- jnz sav_nam ; yes
- call sort
- mov ax,tmp_cnt ; no, return ax = tmp_cnt
- ret
-
-
- ;**************************************************************
- ; sort list of files
- ; entry - di = nxt data loc
- ; tmp_loc = start of data to sort
- ; tmp_cnt = how many to sort
- ; return - di = nxt data loc
- ; data area is sorted
-
- sort: push di
- cmp tmp_cnt,1 ; more than one?
- jnz sort_start ; yes
- jmp sort_done ; no - only one
- sort_start:
- mov bx,tmp_loc
- mov dl,0
- mov dh,1
- sort1: mov si,bx
- mov di,si
- add di,11
- mov cx,8
- repz cmpsb
- jle sort3
- mov cx,11
- mov dl,1
- mov si,bx
- mov di,si
- add di,11
- sort2: mov al,[si]
- xchg [di],al
- mov [si],al
- inc si
- inc di
- loop sort2
- sort3: add bx,11
- inc dh
- mov al,dh ;### expand to 16 bit cnt
- xor ah,ah
- cmp ax,tmp_cnt
- jl sort1
- cmp dl,1
- jz sort_start
- sort_done:
- pop di
- ret
-
- ;**************************************************************
- ; type cr, lf
- crlf:
- display crlf_msg
- ret
-
- ;**********************************
- ;*** ***
- ;*** Storage Allocation ***
- ;*** ***
- ;**********************************
-
- ;**************************************************************
- crlf_msg db CR, LF, "$"
- root_dir db "\",0
- up_dir db "..",0 ; go up a directory level
- dn_dir db ".\", 16 dup (?)
- old_dir db "\", 64 dup (?) ; saves original directory
- no_label db "No DiskLabel$"
- no_subdirs db " No SubDirs$"
- sign_on db "Baum V1.2 ", FACE, "$"
- end_pad db (?) ; graphic joining character
- link db CR, LF, " ", COR, "$"; link from disk name
- spaces8 db " $" ; 8 spaces
- spaces1 db " $" ; 1 space
- tmp_cnt dw (?) ; temporary counter
- tmp_loc dw (?) ; tmp location storage
- unused dw -1 ; # chars not used in field
-
- ; 'level' is current directory level (0 = root), and is used as index into
- ; begin_dir, num_dir, and cur_dir arrays. begin_dir array stores addresses
- ; in buf where the data for each level begins. num_dir array stores the
- ; number of directories at each level. cur_dir array stores the number
- ; of the directory being processed at each level. Whenever we move up
- ; one level, the data for all lower levels is obsolete and the pointers
- ; are now invalid and the corresponding area in 'buf' may be re-used.
-
- level dw (?) ; current level ( 0 - ((n-1)*2) )
- begin_dir dw max_level dup (?) ; index within BUF where data starts
- num_dir dw max_level dup (?) ; # dirs at this level
- cur_dir dw max_level dup (?) ; # of dir being proc. at this level
-
- ; CAUTION!!! be careful when making modifications.
- ; The buffers from here on are used at different times and are overlapping.
- ; 'fcb' overlaps 'buffer', and 'buffer' overlaps 'fb_*' and 'buf'.
-
- fcb db 0FFH, 0,0,0,0,0,8, 0, "???????????"
- buffer db (?)
-
- fb_reserve db 21 dup (?) ; data returned about file
- fb_attr db ?
- fb_time dw ?
- fb_date dw ?
- fb_size_lo dw ?
- fb_size_hi dw ?
- fb_pname db 13 dup (?)
-
- buf: db (?) ; buffer area from here to stack
- ; stores sorted directories for
- ; all levels
-
- prognam ends ;end of code segment
- end start ;end assembly
-
-