home *** CD-ROM | disk | FTP | other *** search
/ ftp.update.uu.se / ftp.update.uu.se.2014.03.zip / ftp.update.uu.se / pub / rainbow / msdos / misc / tree.lzh / TREE.ASM next >
Assembly Source File  |  1985-05-23  |  12KB  |  486 lines

  1. ; tree.asm    g.r.green
  2. ; program to draw directory tree of the default drive on CRT of Rainbow 
  3. ; running msdos.  Will probably run on any msdos machine with VT1xx
  4. ; compatible CRT.
  5. ;
  6. ;        TREE.ASM Copyright (C) by Gordon R. Green
  7. ;               9-May-1985 All Rights Reserved. Released For Any
  8. ;               use without cost exceeding the cost of handling
  9. ;               and reproduction, as long this heading is
  10. ;               included with all or any part used of this
  11. ;               program and credit given to Gordon R. Green.
  12. ;
  13. ;                Gordon R. Green
  14. ;            7 Juniper St.
  15. ;            Hudson, N.H. 03051
  16. ;
  17. ;
  18. ; Installation Instructions:
  19. ;    masm tree
  20. ;    link tree        ; ignore lack of stack err msg!!!
  21. ;    exe2bin tree.exe tree.com
  22. ;    del tree.exe
  23. ;
  24. ; Invocation:
  25. ;    TREE            ; takes no arguments
  26.  
  27.  
  28. ;**************************************************************
  29. ; Macro definitions
  30.  
  31. ;    DISPLAY STRING
  32. display    macro    string
  33.     mov    dx,offset string
  34.     mov    ah,9
  35.     int    doscall
  36.     endm
  37.  
  38. ;    SET_DTA
  39. set_dta    macro    buffer
  40.     mov    dx,offset buffer
  41.     mov    ah,1AH
  42.     int    doscall
  43.     endm
  44.  
  45. ;    SEARCH_FIRST
  46. search_first    macro    fcb
  47.     mov    dx,offset fcb
  48.     mov    ah,11H
  49.     int    doscall
  50.     endm
  51.  
  52. ; End of macros
  53. ;**************************************************************
  54.  
  55.  
  56. ;**************************
  57. ;***            ***
  58. ;***    EQU Statements    ***
  59. ;***            ***
  60. ;**************************
  61.  
  62. max_level    equ    14
  63. doscall        equ    21H
  64.  
  65. ; dos calls
  66. type_chr    equ    2
  67. find_file    equ    4EH
  68. find_nxt_file    equ    4FH
  69.  
  70. ; ASCII characters
  71. CR        equ    0DH
  72. LF        equ    0AH
  73. H_TAB        equ    9
  74.  
  75.  
  76. ;**************************
  77. ;***            ***
  78. ;***    Main Program    ***
  79. ;***            ***
  80. ;**************************
  81.  
  82. ;***********************************************************
  83. prognam    segment    ;define code segment
  84.  
  85.     org    100H
  86.  
  87.     assume cs:prognam, ds:prognam, ss:prognam
  88.  
  89. start:
  90.     push    ds            ; set up return to DOS
  91.     call    crlf
  92.     xor    ax,ax            ; clear ax
  93.     push    ax
  94.     call    init            ; init tables, save current directory,
  95.                     ;   switch to root
  96. ; read disk name and display it
  97.  
  98.     set_dta    buffer
  99.     search_first    fcb        ; look for disk name
  100.     cmp    al,0FFH            ; found?
  101.     jne    name_fnd        ; if yes
  102.     mov    al," "            ; else fill in blank name
  103.     mov    di,offset buffer+8
  104.     mov    cx,11
  105.     repz    stosb
  106. name_fnd:
  107.     mov    al,"$"            ; insert string terminator
  108.     mov    buffer[19],al
  109.     display    rev_vid
  110.     display buffer[8]        ; display name in reverse video
  111.     display    reg_vid
  112.     display    link            ; draw lines down to main tree
  113.     mov    unused,3        ; force proper positioning later
  114.  
  115. ; read root directory into memory and sort it
  116.     mov    di,offset buf        ; pntr to filename storage
  117.     mov    begin_dir,di
  118.     call    get_file_names        ; get filenames for this level
  119.     mov    bx,level
  120.     mov    begin_dir[bx+2],di    ; mark start of next level
  121.     mov    num_dir[bx],ax        ; save # of directories at this level
  122.     cmp    ax,0            ; any sub-diretories?
  123.     je    abort            ;   if none in root, then no tree
  124.  
  125. main_loop:
  126.     mov    bx,level        ; all dirs done at this level?
  127.     mov    ax,cur_dir[bx]
  128.     cmp    ax,num_dir[bx]
  129.     jne    more_dirs        ; if not
  130.     cmp    bx,0            ; are we at top level?
  131.     jne    up            ; if no
  132. abort:    jmp    quit            ; if yes
  133. more_dirs:
  134.     call    dn_level        ; go down one level
  135.     mov    bx,level        ; init di with where to store filenames
  136.     mov    di,begin_dir[bx]
  137.     call    get_file_names
  138.     mov    bx,level        ; save pntr for next level
  139.     mov    begin_dir[bx+2],di
  140.     mov    num_dir[bx],ax        ; save # dirs at this level
  141.     mov    cur_dir[bx],0        ; set cur_dir=0 for this level
  142.     cmp    ax,0            ; any dirs?
  143.     jne    more_dirs        ; if yes, go dn another level
  144.     call    crlf
  145.     mov    unused,-1
  146. up:
  147.     call    up_level        ; else go up a level
  148.     mov    bx,level        ;   bump cnt of cur_dir
  149.     inc    cur_dir[bx]
  150.     jmp    main_loop        ;   and loop back
  151. quit:
  152.     call    crlf
  153.     display    end_graphic        ; exit graphics
  154.     mov    ah,3BH            ; restore original directory
  155.     mov    dx,offset old_dir
  156.     int    doscall
  157.     ret                ; exit to dos
  158.  
  159. ;**********************************
  160. ;***                ***
  161. ;***    Support Routines    ***
  162. ;***                ***
  163. ;**********************************
  164.  
  165. ;**************************************************************
  166. ; initialize a bunch of things
  167. ;    on entry ax = 0
  168. init:
  169. ; init tables (begin_dir, num_dir, cur_dir)
  170.     mov    di,offset begin_dir    ; (ax = 0)
  171.     mov    cx,max_level * 3
  172.     repz    stosw
  173.     mov    level,ax        ; (ax = 0)
  174.  
  175. ; init default file spec at 5CH
  176.     mov    al,"?"            ; fill with wildcards
  177.     mov    di,byte ptr 5DH        ;    default fcb+1
  178.     mov    cx,11
  179.     repz    stosb
  180.  
  181. ; save current directory name
  182.     mov    ah,47H            ; get current directory name
  183.     mov    si,offset old_dir+1    ;    and put here
  184.     mov    dl,0            ;    from present drive
  185.     int    doscall
  186.  
  187. ; change to root_directory
  188.     mov    ah,3BH            ; change current directory
  189.     mov    dx,offset root_dir    ;    to root-directory
  190.     int    doscall
  191.  
  192. ; enter graphics mode
  193.     display    sign_on            ; falls thru to enter graphics
  194.     ret                ;   escape sequence
  195.  
  196.  
  197. ;**************************************************************
  198. ; move down a directory level
  199.  
  200. dn_level:
  201. ; move to new directory
  202.     mov    bx,level
  203.     mov    si,begin_dir[bx]    ; where names start for this level
  204.     mov    ax,cur_dir[bx]        ; cur_dir
  205.     mov    cx,11
  206.     mul    cl            ; times size = offset
  207.     add    ax,si            ; ax points to next name
  208.     mov    si,ax            ; move to si
  209.     mov    di,offset dn_dir + 2
  210.     mov    cx,8            ; ready to move 8 chars
  211.     repz    movsb
  212.     call    show_name        ; display the directory name
  213.     mov    ah,3BH            ; change current directory
  214.     mov    dx,offset dn_dir
  215.     cmp    level,0
  216.     jne    dn_lv
  217.     inc    dx
  218. dn_lv:
  219.     int    doscall            ;### error chk?
  220.     inc    level            ; adjust level count
  221.     inc    level            ;    by 2
  222.     ret
  223.  
  224.  
  225. ;**************************************************************
  226. ; show directory name
  227.  
  228. show_name:
  229.     cmp    unused,-1        ; new line?
  230.     jne    shnm0            ;   if not
  231.     call    do_indents
  232.     mov    unused,0
  233. shnm0:    mov    cx,unused        ; any unused?
  234.     cmp    cx,0            ;   if not
  235.     je    shnm2
  236. shnm1:    mov    dl,"q"            ;   else pad with dashes
  237.     mov    ah,2
  238.     int    doscall
  239.     loop    shnm1
  240. shnm2:    mov    bx,level
  241.     mov    end_pad,"t"        ; init end_pad to rt Tee
  242.     cmp    cur_dir[bx],0        ; determine end_pad value
  243.     jne    shnm3
  244.     mov    end_pad,"w"        ; if 1st, top Tee
  245. shnm3:    mov    ax,cur_dir[bx]
  246.     inc    ax
  247.     cmp    ax,num_dir[bx]
  248.     jne    shnm4
  249.     mov    end_pad,"m"        ; if last, ell
  250. shnm4:    dec    ax
  251.     cmp    ax,0
  252.     jne    shnm5
  253.     cmp    num_dir[bx],1
  254.     jg    shnm5
  255.     mov    end_pad,"q"        ; if 1st & last, dash
  256. shnm5:    mov    dl,end_pad        ; output end_pad
  257.     mov    ah,2
  258.     int    doscall
  259.     display    rev_vid            ; switch to reverse video
  260.     mov    bx,offset dn_dir + 2    ; output name
  261.     mov    dl,[bx]            ;   first character
  262.     mov    ah,2
  263.     int    doscall
  264.     inc    bx
  265.     mov    cx,7            ; 7 more characters in filename
  266. shnm6:    mov    dl,[bx]            ; all but first char in lower case
  267.     cmp    dl,0
  268.     je    shnm8            ; if nul
  269.     cmp    dl,"A"
  270.     jl    shnm7
  271.     cmp    dl,"Z"
  272.     jg    shnm7
  273.     or    dl," "
  274. shnm7:    mov    ah,2            ; finally output char
  275.     int    doscall
  276.     inc    bx
  277.     loop    shnm6            ; loop for all chars
  278. shnm8:    mov    unused,cx
  279.     display    reg_vid            ; back to normal video
  280.     ret
  281.  
  282.  
  283. ;**************************************************************
  284. ; handle the indents at beginning of line
  285.  
  286. do_indents:
  287.     mov    bx,0            ; "level" for this routine
  288. do_ind1:
  289.     display    spaces            ; output leading spaces
  290.     cmp    bx,level        ; done if present level
  291.     je    do_ind3
  292.     mov    dl," "            ;   else output space
  293.     mov    ax,cur_dir[bx]
  294.     inc    ax
  295.     cmp    ax,num_dir[bx]
  296.     je    do_ind2
  297.     mov    dl,"x"            ;   or vertical bar
  298. do_ind2:
  299.     mov    ah,2
  300.     int    doscall
  301. do_ind3:
  302.     inc    bx            ; bump local index
  303.     inc    bx
  304.     cmp    bx,level        ; see if we are done
  305.     jle    do_ind1            ;    if not
  306.     ret
  307.  
  308.  
  309. ;**************************************************************
  310. ; move up a directory level
  311.  
  312. up_level:
  313.     mov    ah,3BH            ; change current directory
  314.     mov    dx,offset up_dir    ;   up a level
  315.     int    doscall            ;### error chk?
  316.     dec    level            ; adjust level count
  317.     dec    level            ;   by 2
  318.     ret
  319.  
  320.  
  321. ;**************************************************************
  322. ; get list of files that match
  323. ;    entry -        di = addr of place to put data
  324. ;    return -    di = addr of next data loc
  325. ;            ax = # files found (stored in tmp_cnt during routine)
  326.  
  327. get_file_names:
  328.     mov    tmp_loc,di
  329.     mov    tmp_cnt,0        ; init file cntr for this routine
  330.     push    di
  331.     set_dta fb_reserve        ; set data transfer area
  332.     mov    al,0            ; clear fb_pname area
  333.     mov    di,offset fb_pname
  334.     mov    cx,11
  335.     repz    stosb
  336.     pop    di
  337.     mov    ah,find_file        ; find match file
  338.     mov    dx,5DH            ; point at default fcb+1
  339.     mov    cx,010H            ; attributes to look for
  340.     int    doscall
  341.     jnc    sav_nam            ; if we found something
  342.     mov    ax,0            ; else
  343.     ret                ;    return with cnt=0
  344.  
  345. sav_nam:
  346.     cmp    fb_attr,10H        ; directory?
  347.     jne    no_save            ;   if not
  348.     cmp    fb_pname, '.'        ; named "."?
  349.     je    no_save            ;   if yes
  350.     mov    si,offset fb_pname    ; else save filename
  351.     mov    cx,11
  352.     repz    movsb
  353.     inc    tmp_cnt            ; bump file cnt
  354. no_save:
  355.     push    di
  356.     mov    al,0            ; clear fb_pname area
  357.     mov    di,offset fb_pname
  358.     mov    cx,13
  359.     repz    stosb
  360.     pop    di
  361.     mov    ah,find_nxt_file    ; find nxt file match
  362.     int    doscall
  363.     cmp    al,18            ; any file?
  364.     jnz    sav_nam            ;    yes
  365.     call    sort
  366.     mov    ax,tmp_cnt        ;    no, return  ax = tmp_cnt
  367.     ret
  368.  
  369.  
  370. ;**************************************************************
  371. ; sort list of files
  372. ;    entry -        di = nxt data loc
  373. ;            tmp_loc = start of data to sort
  374. ;            tmp_cnt = how many to sort
  375. ;    return -    di = nxt data loc
  376. ;            data area is sorted
  377.  
  378. sort:    push    di
  379.     cmp    tmp_cnt,1        ; more than one?
  380.     jnz    sort_start        ;    yes
  381.     jmp    sort_done        ;    no - only one
  382. sort_start:
  383.     mov    bx,tmp_loc
  384.     mov    dl,0
  385.     mov    dh,1
  386. sort1:    mov    si,bx
  387.     mov    di,si
  388.     add    di,11
  389.     mov    cx,8
  390.     repz    cmpsb
  391.     jle    sort3
  392.     mov    cx,11
  393.     mov    dl,1
  394.     mov    si,bx
  395.     mov    di,si
  396.     add    di,11
  397. sort2:    mov    al,[si]
  398.     xchg    [di],al
  399.     mov    [si],al
  400.     inc    si
  401.     inc    di
  402.     loop    sort2
  403. sort3:    add    bx,11
  404.     inc    dh
  405.     mov    al,dh            ;### expand to 16 bit cnt
  406.     xor    ah,ah
  407.     cmp    ax,tmp_cnt
  408.     jl    sort1
  409.     cmp    dl,1
  410.     jz    sort_start
  411. sort_done:
  412.     pop    di
  413.     ret
  414.  
  415. ;**************************************************************
  416. ; type cr, lf
  417. crlf:
  418.     display    crlf_msg
  419.     ret
  420.  
  421. ;**********************************
  422. ;***                ***
  423. ;***    Storage Allocation    ***
  424. ;***                ***
  425. ;**********************************
  426.  
  427. ;**************************************************************
  428. crlf_msg    db    CR, LF, "$"
  429. root_dir    db    "\",0
  430. up_dir        db    "..",0        ; go up a directory level
  431. dn_dir        db    ".\", 16 dup (?)
  432. old_dir        db    "\", 64 dup (?)    ; saves original directory
  433. sign_on        db    "Tree V1.1", CR, LF, LF
  434. go_graphic    db    1BH,")0",0EH,"$"  ; esc sequence for graphics
  435. end_graphic    db    1BH,"[m",0FH,"$"  ; esc seq to end graphics
  436. end_pad        db    (?)        ; graphic joining character
  437. rev_vid        db    0FH,1BH,"[1;4;7m$" ; switch to reverse video
  438. reg_vid        db    1BH,"[m",1BH,"[1m",0EH,"$" ; switch back to normal & graphics
  439. link        db    CR, LF, "    x", CR, LF, "    m$" ; link from disk name
  440. spaces        db    "        $"    ; 8 spaces
  441. vertical    db    "x$"        ; graphic vertical line
  442.  
  443. tmp_cnt        dw    (?)        ; temporary counter
  444. tmp_loc        dw    (?)        ; tmp location storage
  445. unused        dw    -1        ; # chars not used in field
  446.  
  447. ; 'level' is current directory level (0 = root), and is used as index into
  448. ; begin_dir, num_dir, and cur_dir arrays.  begin_dir array stores addresses
  449. ; in buf where the data for each level begins.  num_dir array stores the
  450. ; number of directories at each level.  cur_dir array stores the number
  451. ; of the directory being processed at each level.  Whenever we move up
  452. ; one level, the data for all lower levels is obsolete and the pointers
  453. ; are now invalid and the corresponding area in 'buf' may be re-used.
  454.  
  455. level        dw    (?)        ; current level ( 0 - ((n-1)*2) )
  456. begin_dir    dw    max_level dup (?) ; index within BUF where data starts
  457. num_dir        dw    max_level dup (?) ; # dirs at this level
  458. cur_dir        dw    max_level dup (?) ; # of dir being proc. at this level
  459.  
  460. ; CAUTION!!!  be careful when making modifications.
  461. ; The buffers from here on are used at different times and are overlapping.
  462. ; 'fcb' overlaps 'buffer', and 'buffer' overlaps 'fb_*' and 'buf'.
  463.  
  464. fcb    db    0FFH, 0,0,0,0,0,8, 0, "???????????"
  465. buffer        db    (?)
  466.  
  467. fb_reserve    db    21 dup (?)    ; data returned about file
  468. fb_attr        db    ?
  469. fb_time        dw    ?
  470. fb_date        dw    ?
  471. fb_size_lo    dw    ?
  472. fb_size_hi    dw    ?
  473. fb_pname    db    13 dup (?)
  474.  
  475. buf:        db    (?)        ; buffer area from here to stack
  476.                     ; stores sorted directories for
  477.                     ; all levels
  478.  
  479. ;----------------------------------------------------------
  480.  
  481. prognam    ends        ;end of code segment
  482.  
  483. ;***********************************************************
  484.  
  485.     end  start    ;end assembly
  486.