home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 3 / FREEWARE.BIN / ms_dos / dsort / dstqsrt.asm < prev    next >
Assembly Source File  |  1980-01-02  |  6KB  |  211 lines

  1.     page    96,132
  2. ;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
  3. ;§                                                                          §
  4. ;§              ディレクトリエントリ  ソート  ユーティリティ                §
  5. ;§                                                                          §
  6. ;§                                     DSORT.EXE  Ver1.11    §
  7. ;§                                                                          §
  8. ;§                   Copyright (C) by 福地 邦雄 1991. All rights reserved.  §
  9. ;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
  10.     .MODEL  SMALL,C
  11. ;
  12. REVERSE     equ 1
  13. FALSE       equ 0
  14. direntrysize    equ 20h
  15. ;
  16.     public  dirqsort,dirswap,sortfuncall
  17. ;
  18.     .code
  19. ;
  20. ;------------------------------------------------------------------------------
  21. ;
  22. ;   dirqsort
  23. ;       ディレクトリエントリのクイックソート
  24. ;
  25. ;   TYPE    near call
  26. ;   IN      DS = ソートバッファセグメント
  27. ;           [SP+2] = ソートバッファオフセット
  28. ;           [SP+4] = 要素数
  29. ;           ES:[SP+6] = 比較関数リストアドレス
  30. ;   OUT     なし
  31. ;   保存レジスタ    bp,ds
  32. ;
  33. ;------------------------------------------------------------------------------
  34. ;
  35. dirqsort    proc    sortobj,elmcount,funclist
  36.     local cmpobj,chgedobj,cmpcount,chgcount
  37. ;
  38. ;   @if (elmcount,gt,1),L           ; 要素数2以上ならソート実行
  39.       cmp   elmcount,1
  40.       jg    @i0001
  41.       jmp   @i0002
  42. @i0001:
  43.         mov     si,sortobj
  44.         mov     di,direntrysize
  45.         add     di,si
  46.         cmp     elmcount,02
  47.         mov     cmpobj,di
  48. ;       @if (zf,on)                 ; 要素数2なら直接比較
  49.           jnz   @i0003
  50.             mov     bx,funclist
  51.             call    sortfuncall
  52.             test    ax,ax
  53. ;           @if (zf,off),and,(sf,off)   ; エントリ1が大きい時は入れ換え
  54.               jz    @i0004
  55.               js    @i0004
  56.                 mov     di,cmpobj
  57.                 mov     si,sortobj
  58.                 call    dirswap
  59. ;           @ifend
  60. @i0004:
  61. ;       @else                       ; 要素数3以上
  62.           jmp   @i0005
  63. @i0003:
  64.             mov ax,elmcount         ; 比較の基準を配列の真ん中から取り出す
  65.             mov     bx,2
  66.             cwd
  67.             idiv        bx
  68.             mov     bx,direntrysize
  69.             imul    bx
  70.             mov     si,sortobj
  71.             mov     di,si
  72.             add     di,ax
  73.             call    dirswap
  74.             mov     ax,sortobj      ; 準備
  75.             mov     chgcount,0
  76.             mov     cmpcount,1
  77.             mov     chgedobj,ax
  78. ;           @do repeat
  79. @d0001:
  80.                 mov     ax,cmpcount ; 比較終了か?
  81. ;               @if (ax,ge,elmcount)
  82.                   cmp   ax,elmcount
  83.                   jl    @i0006
  84. ;                   @doexit
  85.                       jmp   @d0002
  86. ;               @ifend
  87. @i0006:
  88.                 mov     di,sortobj  ; 比較関数呼び出し
  89.                 mov     si,cmpobj
  90.                 mov     bx,funclist
  91.                 call    sortfuncall
  92.                 test    ax,ax
  93. ;               @if (sf,on)         ; 比較対象エントリが小さい時
  94.                   jns   @i0007
  95.                     inc     chgcount
  96.                     add     chgedobj,direntrysize
  97.                     mov     si,cmpobj
  98.                     mov     di,chgedobj
  99. ;                   @if (si,/=,di)
  100.                       cmp   si,di
  101.                       je    @i0008
  102.                         call      dirswap
  103. ;                   @ifend
  104. @i0008:
  105. ;               @ifend
  106. @i0007:
  107.                 add     cmpobj,direntrysize ; 次の比較対象へ
  108.                 inc     cmpcount
  109. ;           @doend
  110.               jmp   @d0001
  111. @d0002:
  112.             mov     si,sortobj      ;
  113.             mov     di,chgedobj
  114. ;           @if (si,/=,di)
  115.               cmp   si,di
  116.               je    @i0009
  117.                 call      dirswap
  118. ;           @ifend
  119. @i0009:
  120.             push    funclist        ; 再帰呼び出し 1
  121.             push    chgcount
  122.             push    sortobj
  123.             call    dirqsort
  124.             mov     bx,chgedobj     ; 再帰呼び出し 2
  125.             add     bx,direntrysize
  126.             mov     cx,elmcount
  127.             sub     cx,chgcount
  128.             dec     cx
  129.             push    funclist
  130.             push    cx
  131.             push    bx
  132.             call    dirqsort
  133. ;       @ifend
  134. @i0005:
  135. ;   @ifend
  136. @i0002:
  137.     ret     6
  138. ;
  139. dirqsort    endp
  140. ;
  141. ;------------------------------------------------------------------------------
  142. ;
  143. ;   dirswap
  144. ;       ディレクトリエントリの交換
  145. ;
  146. ;   TYPE    near call
  147. ;   IN      DS:SI = エントリ1アドレス
  148. ;              DI = エントリ2アドレス
  149. ;   OUT     なし
  150. ;   保存レジスタ    bx,dx,si,di,bp,ds,es
  151. ;
  152. ;------------------------------------------------------------------------------
  153. ;
  154. dirswap proc
  155. ;
  156.     cld
  157.     mov     cx,direntrysize/2
  158. swaploop:
  159.     mov     ax,[si]
  160.     xchg    [di],ax
  161.     mov     [si],ax
  162.     lea     si,[si+2]
  163.     lea     di,[di+2]
  164.     loop    swaploop
  165. ;
  166.     ret
  167. ;
  168. dirswap endp
  169. ;
  170. ;------------------------------------------------------------------------------
  171. ;
  172. ;   sortfuncall
  173. ;       ソート用比較関数列の呼び出し
  174. ;
  175. ;   TYPE    near call
  176. ;   IN      ES:BX = 比較関数列のアドレス
  177. ;           DS:SI = エントリ1アドレス
  178. ;              DI = エントリ2アドレス
  179. ;   OUT     AX = 比較結果
  180. ;   保存レジスタ    si,di,bp,ds,es
  181. ;
  182. ;------------------------------------------------------------------------------
  183. ;
  184. sortfuncall proc
  185. ;
  186. ;   @do until
  187. @d0003:
  188.         call    word ptr es:[bx]    ; 比較関数呼び出し
  189. ;       @if (word ptr es:[bx+2],=,REVERSE)  ; 逆順指定の時は結果を反転
  190.           cmp   word ptr es:[bx+2],REVERSE
  191.           jne   @i0010
  192.             neg     ax
  193. ;       @ifend
  194. @i0010:
  195. ;       @if (ax,/=,0)               ; 比較して違いがあれば終了
  196.           or    ax,ax
  197.           je    @i0011
  198.             jmp     compareend
  199. ;       @ifend
  200. @i0011:
  201.         lea     bx,[bx+4]           ; 次の比較関数へ
  202. ;   @doend (word ptr es:[bx],=,0)   ; 関数列の終了まで
  203.       cmp   word ptr es:[bx],0
  204.       jne   @d0003
  205. compareend:
  206.     ret
  207. ;
  208. sortfuncall endp
  209. ;
  210.     end
  211.