home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / diverses / cexpress / files / filltree.asm < prev    next >
Encoding:
Assembly Source File  |  1989-05-03  |  8.2 KB  |  230 lines

  1. ;void  fill_tree_array(tree_array,work_area,max_entry,drive_num);
  2. ;  char  *tree_array,*work_area;
  3. ;  unsigned short  max_entry,drive_num;
  4.  
  5.     EXTRN  _memory_model:byte
  6.     EXTRN  _error_code:byte
  7.         EXTRN  _tree_array_size:word
  8.  
  9. _TEXT    SEGMENT BYTE PUBLIC 'CODE'
  10.     ASSUME CS:_TEXT
  11.     PUBLIC _fill_tree_array
  12. _fill_tree_array proc near
  13.     push bp
  14.         mov  bp,sp
  15.     push di            
  16.     push si            
  17.     cmp  _memory_model,0    ;near or far?
  18.     jle  begin        ;jump if near
  19.     inc  bp            ;else add 2 to BP
  20.     inc  bp            ;
  21. begin:    push ds
  22.     jmp  G1
  23. current_element     dw 1    ;values are initialized below so that can call
  24. current_search_dir  dw 0 ;   the routine more than once
  25. parent_element     dw 0
  26. parent_offset     dw 0
  27. prior_element     dw 0
  28. errorcode     db 0
  29. treearray     dd 0
  30. workarea     dd 0
  31. copy_name PROC
  32.     les  di,cs:dword ptr treearray    ;point ES:DI to start of TreeArray
  33.     mov  ax,cs:current_element ;get current (free) element
  34.     mov bx,cs:parent_offset    ;see if parent subdirectory is root dir
  35.     or  bx,bx        ;will be 0 if so
  36.     jz  B1            ;won't set child field in its parent record
  37.     test  es:[bx+15],0ffffh    ;will set child field only for first subdir
  38.     jnz  A1            ;if child field not still zero, already set
  39.     mov es:[bx+15],ax    ;set child pointer
  40. A1:    mov  cs:parent_offset,0  ;zero value flags that parent dir is root
  41. B1:    dec  ax            ;count from zero to set offset
  42.     mov  bl,21        ;bytes per record
  43.     mul  bl            ;calculate offset to current element
  44.     add  di,ax        ;adjust offset pointer
  45.     lds  si,cs:dword ptr workarea ;point DS:SI to subdir name field
  46.     add  si,30        ;name offset
  47.     push di            ;save TreeArray ptr
  48. C1:    mov  al,[si]        ;get character
  49.     mov  es:[di],al        ;copy the character
  50.     inc  di            ;inc TreeArray pointer
  51.     inc  si            ;forward WorkArea pointer
  52.     or   al,al        ;final zero?
  53.     jnz  C1            ;loop
  54.     pop  di            ;pt back to start of TreeArray element
  55. D1:    add  di,13        ;forward to Parent field
  56.     mov  ax,cs:parent_element ;get ptr to parent
  57.     mov  es:[di],ax        ;place in linked list
  58.     add  di,4        ;forward pointer to Prior field
  59.     mov  ax,cs:prior_element ;get number of prior element (0=none)
  60.     or   ax,ax        ;test
  61.     jz   E1            ;jump ahead if first record for the subdir
  62.     mov  es:[di],ax        ;set Prior field
  63.     mov  ax,cs:current_element ;
  64.     mov  es:[di-19],ax    ;set Next field of prior record
  65. E1:     mov  ax,cs:current_element ;
  66.     mov  cs:prior_element,ax ;set prior_element for next time through
  67.     ret
  68. copy_name endp
  69.  
  70. add_drive_descriptor PROC
  71.     mov  ax,[bp+10]        ;get drive specifier
  72.     or   ax,ax        ;0 = default
  73.     jz   F1            ;don't write drive specifier if default
  74.     dec  si            ;pull back pointer
  75.     mov  byte ptr [si],':'    ;write colon
  76.     add  ax,64        ;drive number + 64 = ascii char
  77.     dec  si            ;pull back pointer
  78.     mov  [si],al        ;write drive character
  79. F1:    ret
  80. add_drive_descriptor endp
  81.  
  82. G1:    sub  ax,ax           ;initialize variables
  83.     mov  cs:current_search_dir,ax 
  84.     mov  cs:prior_element,ax   ;
  85.     mov  cs:parent_element,ax  ;
  86.     mov  cs:parent_offset,ax   ;
  87.     mov  cs:errorcode,al       ;
  88.     inc  ax               ;
  89.     mov  cs:current_element,ax ;
  90.     cmp  _memory_model,2    ;data near or far?
  91.     jb   G2            ;jump if near
  92.     les  di,dword ptr[bp+4]    ;store TreeArray address
  93.     add  di,21        ;start from array element 1
  94.     mov  word ptr cs:treearray,di  
  95.     mov  word ptr cs:treearray+2,es  
  96.     les  di,dword ptr[bp+8]    ;store WorkArea address
  97.     mov  word ptr cs:workarea,di
  98.     mov  word ptr cs:workarea+2,es
  99.     add  bp,4        ;add 4 to BP since 2 dword pointers
  100.     jmp  short G3        ;
  101. G2:    mov  ax,ds        ;ES = DS
  102.     mov  es,ax        ;
  103.     mov  word ptr cs:treearray+2,ax
  104.     mov  word ptr cs:workarea+2,ax
  105.     mov  ax,[bp+4]        ;get TreeArray offset
  106.     add  ax,21        ;start from array element 1
  107.     mov  word ptr cs:treearray,ax
  108.     mov  ax,[bp+6]        ;get WorkArea offset
  109.     mov  word ptr cs:workarea,ax
  110. G3:    mov  ah,2fh        ;get current DTA address
  111.     int  21h        ;DTA in ES:BX
  112.         lds  dx,cs:dword ptr workarea ;get WorkArea pointer
  113.     push bx            ;save offset of old DTA
  114.     push es            ;save segment of old DTA
  115.     mov  ah,1ah        ;function to set DTA
  116.     int  21h        ;set DTA to WorkArea
  117.     lds  si,cs:dword ptr workarea ;now DS:SI pts to WorkArea
  118.     les  di,cs:dword ptr treearray ;ES:DI pts to TreeArray
  119.     add  di,13        ;offset to first linked list pointer
  120.     mov  cx,[bp+8]        ;get max elements
  121.     or   cx,cx        ;test for zero
  122.     jnz  H1            ;jump ahead if nonzero
  123.     mov  cs:errorcode,2    ;else set error code
  124.     jmp  S1            ;quit routine
  125. H1:    sub  dx,dx        ;will zero out all linked list pointers
  126. I1:    mov  es:[di],dx        ;zero parent
  127.     mov  es:[di+2],dx    ;zero child
  128.     mov  es:[di+4],dx    ;zero prior
  129.     mov  es:[di+6],dx    ;zero next
  130.     add  di,21        ;forward to next element
  131. ;ASSEMBLE INITIAL ASCIIZ STRING:
  132.     loop I1            ;do whole array
  133.     add  si,169        ;string is at high end of work area    
  134.     mov  ax,002Ah        ;asterisk plus null (will write *.*0)
  135.     mov  [si],ax        ;write it
  136.     mov  ax,2E2Ah        ;asterisk plus period
  137.     dec  si            ;pull back pointer
  138.     dec  si            ;
  139.     mov  [si],ax        ;write it
  140.     mov  al,'\'        ;initial search is root directory
  141.     dec  si            ;pull back ASCIIZ ptr
  142.     mov  [si],al        ;ready to search root dir
  143.     call add_drive_descriptor ;(to start of ASCIIZ string)
  144.     mov  dx,si        ;DS:DX must point to ASCIIZ string
  145. ;SEARCH A SUBDIRECTORY:
  146. J1:    mov  word ptr cs:prior_element,0 ;clear Prior element counter
  147.     mov  ah,4eh        ;function to find FIRST
  148. K1:    mov  cx,16        ;file attribute for subdirectory    
  149.     int  21h        ;get first subdir listed
  150.     jc   N1            ;jump if none
  151.     lds  si,cs:dword ptr workarea;pt to start of DOS work area
  152.     cmp  byte ptr[si+21],16 ;is it a subdirectory?
  153.     jne  M1            ;jump ahead if not   
  154.     cmp  byte ptr[si+30],'.';is it a subdir reference entry?
  155.     je   M1            ;skip it if so
  156.     mov  ax,[bp+8]        ;get MaxElements
  157.     cmp  cs:current_element,ax ;filled up?
  158.     jna  L1            ;jump if not
  159.     mov  cs:errorcode,2    ;else set internal error code
  160.     jmp  S1            ;go quit
  161. L1:    call copy_name        ;copy subdir name to TreeArray
  162.     inc  cs:current_element ;inc ptr to next free element
  163. M1:    mov  ah,4fh        ;function to find NEXT subdir
  164.     jmp  short K1        ;go seek next subdir
  165. N1:    mov  ax,cs:current_search_dir
  166.     inc  ax            ;...to current element. When 1 less...
  167.     cmp  cs:current_element,ax ;...the scan is finished
  168.     je   S1            ;finished
  169.     mov  cs:parent_offset,0 ;keeps offset of parent of current element
  170. ;ASSEMBLE ASCIIZ STRING FOR NEXT SUBDIR:
  171.     lds  si,cs:dword ptr workarea ;point to work area
  172.     add  si,165        ;offset to byte before \*.*0
  173.     inc  cs:current_search_dir
  174.     les  di,cs:dword ptr treearray ;ES:DI to TreeArray
  175.     mov  ax,cs:current_search_dir ;get subdir element number
  176.     mov  cs:parent_element,ax  ;use as value for Parent field
  177.     jmp  P1            ;jump over entry point for loop
  178. O1:     dec  si            ;pull back DOS path pointer
  179. P1:     les  di,cs:dword ptr treearray ;ES:DI to TreeArray 
  180.     dec  ax            ;count from 0 to figure offset
  181.     mov  dl,21        ;bytes per record
  182.     mul  dl            ;calculate offset
  183.     add  di,ax        ;add to pointer
  184.     test  cs:parent_offset,0ffffh ;see if parent_offset is zero
  185.     jnz  Q1            ;if so, parent dir is root dir
  186.     mov  cs:parent_offset,di ;save for marking Parent field
  187. Q1:    sub  cx,cx        ;counts string length
  188. Q2:    cmp  byte ptr es:[di],0 ;need to know string length
  189.     je   Q3            ;end of string?
  190.     inc  di            ;forward ptr    
  191.     inc  cx            ;inc string length counter
  192.     jmp  short Q2        ;loop till end
  193. Q3:    dec  di            ;point DI back to last char
  194. R1:    mov  al,es:[di]        ;get char from the string
  195.     mov  [si],al        ;move it
  196.     dec  di            ;moving in reverse
  197.     dec  si            ;
  198.     loop R1            ;go do next char
  199.     mov  byte ptr[si],'\'   ;add initial slash
  200.     add  di,14        ;point to Parent field
  201.     mov  ax,es:[di]        ;get Parent element number
  202.     or   ax,ax        ;test for no Parent
  203.     jnz  O1            ;loop till whole path assembled
  204.     call add_drive_descriptor ;(to start of ASCIIZ string)
  205.     mov  dx,si        ;DS:DX must point to ASCIIZ string
  206.     jmp  J1            ;go search next subdir
  207. S1:    pop  ds            ;get old DTA
  208.     pop  dx            ;
  209.     mov  ah,1ah        ;function to set DTA
  210.     int  21h        ;restore former DTA    
  211.     pop  ds            ;restore changed registers
  212.     mov  ax,cs:current_element
  213.     dec  ax            ;
  214.     mov  _tree_array_size,ax ;set return value for _tree_array_size
  215.     mov  bl,1        ;1 = no tree elements
  216.     or   ax,ax        ;test for zero elements
  217.     jz   T1            ;jump if nonzero
  218.     mov  bl,cs:errorcode    ;get internal errorcode variable
  219. T1:    mov  _error_code,bl    ;set Turbo's global _error_code
  220.     pop  si            
  221.     pop  di            
  222.         pop  bp            
  223.     cmp  _memory_model,0    ;quit
  224.     jle  quit        ;
  225.     db   0CBh        ;RET far
  226. quit:    ret            ;RET near
  227. _fill_tree_array endp
  228. _TEXT    ENDS
  229.     END
  230.