home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 5 / ctrom5b.zip / ctrom5b / PROGRAM / ASM / ALIB30B / SORT02.ASM < prev    next >
Assembly Source File  |  1994-11-04  |  9KB  |  423 lines

  1. ;***************************** SORT02.ASM ***********************************
  2.  
  3. LIBSEG           segment byte public "LIB"
  4.         assume cs:LIBSEG , ds:nothing
  5.  
  6. ;----------------------------------------------------------------------------
  7. .xlist
  8.     include  mac.inc
  9.     include  common.inc
  10.  
  11.     extrn    dos_mem_allocate:far
  12.     extrn    dos_mem_release:far
  13.     
  14.     extrn    order_buffer:near
  15.     extrn    make_index:near
  16.     extrn    DiskWrite_open:far
  17.     extrn    DiskWrite_buffer:far
  18.     extrn    DiskWrite_close:far
  19.     
  20.     extrn    sort_engine:word
  21.     extrn    sort_field_len:word
  22.     extrn    sort_column:word
  23.     extrn    last_sort_column:word
  24.     extrn    buffer_off:word
  25.     extrn    fixed_record_len:word
  26.     extrn    rec_term_char:byte
  27.     extrn    prime_asciiz_off:word
  28.     extrn    prime_asciiz_seg:word
  29. .list
  30. comment 
  31. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -(  SORT   )
  32. ; file sort, read file into buffers and sort them.
  33. ;            use merge sort to combine files.
  34. ;
  35. ;  inputs:  es:di = pointer to buffer, or asciiz if file
  36. ;              cx = buffer length, or zero if file
  37. ;              bx = record length if fixed length, else zero if variable len.
  38. ;              al = record terminator for variable lenght records. else zero
  39. ;
  40. ;   output:   carry set if insufficient memory, or disk error
  41. ;
  42. ;* * * * * * * * * * * * * *
  43. 
  44.  
  45. buffer_size    equ    4000h        
  46.  
  47. prime_handle    dw    0
  48. prime_seg    dw    0
  49. last_prime_read    dw    0        ;size of last prime read
  50. prime_index_seg    dw    0
  51.  
  52. temp1_asciiz    db    'temp1.$$$',0
  53. temp1_handle    dw    0
  54. temp1_seg    dw    0
  55. last_temp1_read    dw    0
  56. temp1_index_seg    dw    0
  57.  
  58. temp2_asciiz    db    'temp2.$$$',0
  59.  temp2_handle    dw    0
  60.  
  61.     public    file_sort
  62. file_sort    proc    near
  63.     mov    cs:prime_Asciiz_seg,es
  64.     mov    cs:prime_Asciiz_off,di    
  65. ;
  66. ; compute last_sort_column
  67. ;
  68.     mov    dx,cs:sort_column
  69.     mov    cs:last_sort_column,dx
  70.     mov    dx,cs:sort_field_len
  71.     add    cs:last_sort_column,dx
  72.     
  73.     mov    dx,di            ;get asciiz ptr
  74.     push    es
  75.     pop    ds            ;get asciiz seg
  76.     mov    ax,3d00h        ;open file for read-only
  77.     int    21h            ;ax = handle if no carry
  78.     mov    cs:prime_handle,ax
  79. ;
  80. ; allocate memory for prime buffer
  81. ;
  82.     mov    dx,0
  83.     mov    ax,buffer_size        ;allocate 32k
  84.     call    dos_mem_allocate
  85.     jc    fs_err            ;jmp if insifficient memory
  86.     mov    cs:prime_seg,es        ;save buffer
  87. ;
  88. ; allocate memory to form new prime index
  89. ;
  90.     mov    dx,0
  91.     mov    ax,buffer_size        ;allocate 32k
  92.     call    dos_mem_allocate
  93.     jc    fs_err            ;jmp if insifficient memory
  94.     mov    cs:prime_index_seg,es    ;save prime index buf
  95. ;
  96. ; allocate memory for temp1 buffer
  97. ;
  98.     mov    dx,0
  99.     mov    ax,buffer_size        ;allocate 32k
  100.     call    dos_mem_allocate
  101.     jc    fs_err            ;jmp if insifficient memory
  102.     mov    cs:temp1_seg,es        ;save buffer
  103. ;
  104. ; allocate memory for temp1 index
  105. ;
  106.     mov    dx,0
  107.     mov    ax,buffer_size        ;allocate 32k
  108.     call    dos_mem_allocate
  109.     jc    fs_err            ;jmp if insifficient memory
  110.     mov    cs:temp1_index_seg,es    ;save buffer
  111. ;
  112. ; read and sort prime
  113. ;
  114.     mov    di,cs:prime_index_seg    ;get index seg
  115.     mov    ds,cs:prime_seg
  116.     mov    bx,cs:prime_handle
  117.     call    read_and_sort
  118.     mov    cs:last_prime_read,bx
  119. ;
  120. ; order data in buffer
  121. ;
  122.     mov    ds,cs:prime_seg
  123.     mov    si,0
  124.     mov    dx,cs:prime_index_seg
  125.     call    order_buffer
  126. ;
  127. ; write prime data to temp1
  128. ;
  129.     mov    ah,3ch            ;file create
  130.     push    cs
  131.     pop    ds
  132.     mov    dx,offset temp1_asciiz
  133.     mov    cx,0            ;normal read/write file
  134.     int    21h
  135.     jc    bad_file
  136.     mov    cs:temp1_handle,ax
  137.  
  138.     mov    bx,cs:temp1_handle
  139.     mov    ah,40h
  140.     mov    cx,cs:last_prime_read
  141.     mov    dx,0            ;offset buffer
  142.     mov    ds,cs:prime_seg    
  143.     int    21h
  144.     jc    bad_file
  145. ;
  146. ; read and sort next prime block 
  147. ;
  148. rf_loop:
  149. ;
  150. ; read and sort prime
  151. ;
  152.     mov    di,cs:prime_index_seg        ;get index seg
  153.     mov    ds,cs:prime_seg
  154.     mov    bx,cs:prime_handle
  155.     call    read_and_sort
  156.     mov    cs:last_prime_read,bx
  157.     cmp    bx,0
  158.     je    fs_tail                ;jmp if prime exhausted
  159. ;
  160. ; merge sorted buffer & temp1 -> temp2
  161. ;
  162. ; rewind temp1 file
  163. ;
  164.     mov    bx,cs:temp1_handle    ;rewind
  165.     mov    cx,0            ;  temp1
  166.     mov    dx,0
  167.     mov    ax,4200h        ;file seek relative to start
  168.     int    21h
  169. ;
  170. ; create temp2 file
  171. ;
  172.     push    cs
  173.     pop    ds
  174.     mov    dx,offset temp2_asciiz
  175.     call    DiskWrite_open
  176.     jc    bad_file
  177. ;
  178. ; merge prime + temp1 -> temp2
  179. ;
  180.     mov    bp,0            ;prime index ptr setup
  181. ;
  182. ; read and sort temp1
  183. ;
  184. read_temp1:
  185.     mov    di,cs:temp1_index_seg        ;get index seg
  186.     mov    ds,cs:temp1_seg
  187.     mov    bx,cs:temp1_handle
  188.     call    read_and_sort
  189.     mov    cs:last_temp1_read,bx
  190.     
  191.     mov    bx,0            ;temp1 index ptr setup
  192.     
  193. merge_lp:    
  194.     mov    ds,cs:prime_index_seg
  195.     mov    si,word ptr ds:[bp]    ;get prime buffer ptr
  196.     mov    cx,word ptr ds:[bp+2]    ;get record length
  197.     mov    ds,cs:prime_seg
  198.  
  199.     mov    es,cs:temp1_index_seg
  200.     mov    di,word ptr es:[bx]    ;get temp1 buffer ptr
  201.     mov    ax,word ptr es:[bx+2]    ;get record length
  202.     mov    es,cs:temp1_seg
  203.  
  204.     cmp    cs:last_temp1_read,0
  205.     jne    fs_2            ;jmp if temp1 not = eof
  206.     cmp    si,-1
  207.     jne    write_prime        ;jmp if prime has data
  208.     jmp    merge_done
  209. ;
  210. ; temp1 = eof  prime has data    
  211. ;
  212. ;fs_1:    cmp    di,-1
  213. ;    jne    write_temp1        ;jmp if temp1 has data
  214. ;    jmp    merge_done
  215. ;
  216. ; temp1 not at eof
  217. ;
  218. fs_2:    cmp    di,-1
  219.     je    read_temp1        ;jmp if at end of temp1 index
  220. ;
  221. ; temp1 has data
  222. ;
  223.     cmp    si,-1
  224.     je    write_temp1        ;jmp if prime index at end
  225. ;
  226. ; both prime & temp1 index's have data
  227. ;
  228.          cmp    cx,cs:last_sort_column    ;check if truncated prime
  229.     jb    write_prime        ;jmp if prime record truncated
  230.  
  231.     cmp    ax,cs:last_sort_column
  232.     jb    write_temp1        ;jmp if temp1 record truncated
  233.     
  234.     add    si,cs:sort_column
  235.     add    di,cs:sort_column
  236.  
  237.     apush    cx,si,di
  238.     mov    cx,cs:sort_field_len
  239.     rep    cmpsb            ;compare prime & temp1
  240.     apop    di,si,cx
  241.     jae    write_temp1
  242. ;
  243. ; cx=record len, ds=buffer seg   si=buffer offset
  244. ;
  245. write_prime:
  246.     mov    dx,si
  247.     add    bp,4            ;move index fwd
  248.     jmp    do_write
  249. ;
  250. ; ax=record len  es=buffer seg  di=buffer offset
  251. ;    
  252. write_temp1:
  253.     mov    dx,di
  254.     mov    cx,ax
  255.     push    es
  256.     pop    ds
  257.     add    bx,4            ;move index fwd
  258. ;
  259. do_write:
  260.     call    DiskWrite_buffer    ;write temp2
  261.     jmp    merge_lp        
  262.         
  263. merge_done:    
  264. ;
  265. ; delete temp1 and rename temp2 -> temp1
  266. ;
  267.     mov    bx,cs:temp1_handle
  268.     mov    ah,3eh            ;close file
  269.     int    21h
  270.     
  271.     mov    dx,offset temp1_asciiz
  272.     push    cs
  273.     pop    ds
  274.     mov    ah,41h
  275.     int    21h            ;delete temp1
  276.  
  277.     call    DiskWrite_close        ;close temp2
  278. ;
  279. ; rename temp2 -> temp1
  280. ;
  281.     mov    dx,offset temp2_asciiz
  282.     mov    di,offset temp1_asciiz
  283.     push    ds
  284.     pop    es
  285.     mov    ah,56h
  286.     int    21h
  287. ;
  288. ; re-open temp1
  289. ;
  290.     mov    ah,3dh            ;file create
  291.     push    cs
  292.     pop    ds
  293.     mov    dx,offset temp1_asciiz
  294.     mov    al,2            ;normal read/write file
  295.     int    21h
  296.     jc    bad_file
  297.     mov    cs:temp1_handle,ax
  298.     
  299.     jmp    rf_loop
  300. ;
  301. ; no more prime data.  delete prime.  rename temp1 -> prime
  302. ;
  303. fs_tail:
  304.     mov    bx,cs:prime_handle
  305.     mov    ah,3eh
  306.     int    21h            ;close prime
  307.     
  308.     lds    dx,dword ptr cs:prime_Asciiz_off
  309.     mov    ah,41h
  310.     int    21h            ;delete prime
  311.  
  312.     mov    bx,cs:temp1_handle
  313.     mov    ah,3eh
  314.     int    21h            ;close temp1.$$$
  315.     
  316.     mov    dx,offset temp1_asciiz
  317.     push    cs
  318.     pop    ds
  319.     les    di,dword ptr cs:prime_Asciiz_off
  320.     mov    ah,56h
  321.     int    21h
  322.     clc
  323.     jmp    fs_exit
  324.  
  325. bad_file:
  326. fs_err:
  327. fs_exit:pushf
  328.     cmp    cs:prime_seg,0
  329.     je    fs_exit2        ;jmp if not allocated
  330.     mov    es,cs:prime_seg
  331.     call    dos_mem_release
  332.     mov    cs:prime_seg,0
  333. fs_exit2:
  334.     cmp    cs:prime_index_seg,0
  335.     je    fs_exit3
  336.     mov    es,cs:prime_index_seg
  337.     call    dos_mem_release
  338.     mov    cs:prime_index_seg,0
  339. fs_exit3:
  340.     cmp    cs:temp1_seg,0
  341.     je    fs_exit4
  342.     mov    es,cs:temp1_seg
  343.     call    dos_mem_release
  344.     mov    cs:temp1_seg,0
  345. fs_exit4:
  346.     cmp    cs:temp1_index_seg,0
  347.     je    fs_exit5
  348.     mov    es,cs:temp1_index_seg
  349.     call    dos_mem_release
  350.     mov    cs:temp1_index_seg,0
  351. fs_exit5:
  352.     popf            
  353.     ret
  354. file_sort    endp     
  355. ;----------------------------------------------------------------------
  356. ; read_and_index - read file and index data
  357. ;  inputs:  ds:0 = buffer seg
  358. ;             bx = file handle
  359. ;             di = index seg
  360. ;  output: bx = amount of data read
  361. ;
  362. last_read    dw    0
  363. handle        dw    0
  364. buffer_segment    dw    0
  365.  
  366. read_and_sort:
  367.     apush    ax,cx,dx,si,bp,es
  368.     mov    cs:handle,bx
  369.     mov    cs:buffer_segment,ds
  370.     
  371.     mov    cx,buffer_size
  372.     mov    dx,0
  373.     mov    ah,3fh
  374.     int    21h            ;read data
  375.     mov    cs:last_read,ax        ;save amount of data read
  376.     test    ax,ax
  377.     jz    ras_exit        ;exit if at eof
  378. ;
  379. ; build index
  380. ;
  381.     mov    ds,di            ;get index_seg
  382.     mov    di,0                   ;index buf offset
  383.     mov    cx,ax                    ;get size of last read
  384.     mov    bx,cs:fixed_record_len
  385.     mov    al,cs:rec_term_char
  386.     mov    es,cs:buffer_segment
  387.     call    make_index        ;make index
  388. ;
  389. ; if partial record at end, seek back in file
  390. ;
  391.     cmp    cs:last_read,buffer_size
  392.     jne    skip_adjust1        ;jmp if at eof
  393.     jcxz    skip_adjust1        ;jmp if no partial record at end
  394.  
  395.     sub    cs:last_read,cx    
  396.     mov    bx,cs:handle        ;seek back
  397.     mov    dx,0
  398.     xchg    dx,cx            ;cx,dx = seek rel
  399. ;
  400. ; convert move to (negative) move back in file
  401. ;
  402.            not    cx
  403.     neg    dx
  404.     sbb    cx,-1
  405.     
  406.     mov    ax,4201h        ;file seek relative to current loc
  407.     int    21h
  408. skip_adjust1:
  409. ;
  410. ; sort the index
  411. ;
  412.     mov    cx,cs:sort_field_len
  413.     mov    dx,cs:sort_column
  414.     mov    si,0            ;buffer offset
  415.     call    sort_engine
  416. ras_exit:    
  417.     mov    bx,cs:last_read
  418.     apop    es,bp,si,dx,cx,ax
  419.     ret
  420.  
  421. LIBSEG    ENDS
  422.     end
  423.