home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 3
/
FREEWARE.BIN
/
ms_dos
/
dsort
/
dstqsrt.pre
< prev
Wrap
Text File
|
1980-01-02
|
5KB
|
175 lines
page 96,132
;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
;§ §
;§ ディレクトリエントリ ソート ユーティリティ §
;§ §
;§ DSORT.EXE Ver1.11 §
;§ §
;§ Copyright (C) by 福地 邦雄 1991. All rights reserved. §
;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
.MODEL SMALL,C
;
REVERSE equ 1
FALSE equ 0
direntrysize equ 20h
;
public dirqsort,dirswap,sortfuncall
;
.code
;
;------------------------------------------------------------------------------
;
; dirqsort
; ディレクトリエントリのクイックソート
;
; TYPE near call
; IN DS = ソートバッファセグメント
; [SP+2] = ソートバッファオフセット
; [SP+4] = 要素数
; ES:[SP+6] = 比較関数リストアドレス
; OUT なし
; 保存レジスタ bp,ds
;
;------------------------------------------------------------------------------
;
dirqsort proc sortobj,elmcount,funclist
local cmpobj,chgedobj,cmpcount,chgcount
;
@if (elmcount,gt,1),L ; 要素数2以上ならソート実行
mov si,sortobj
mov di,direntrysize
add di,si
cmp elmcount,02
mov cmpobj,di
@if (zf,on) ; 要素数2なら直接比較
mov bx,funclist
call sortfuncall
test ax,ax
@if (zf,off),and,(sf,off) ; エントリ1が大きい時は入れ換え
mov di,cmpobj
mov si,sortobj
call dirswap
@ifend
@else ; 要素数3以上
mov ax,elmcount ; 比較の基準を配列の真ん中から取り出す
mov bx,2
cwd
idiv bx
mov bx,direntrysize
imul bx
mov si,sortobj
mov di,si
add di,ax
call dirswap
mov ax,sortobj ; 準備
mov chgcount,0
mov cmpcount,1
mov chgedobj,ax
@do repeat
mov ax,cmpcount ; 比較終了か?
@if (ax,ge,elmcount)
@doexit
@ifend
mov di,sortobj ; 比較関数呼び出し
mov si,cmpobj
mov bx,funclist
call sortfuncall
test ax,ax
@if (sf,on) ; 比較対象エントリが小さい時
inc chgcount
add chgedobj,direntrysize
mov si,cmpobj
mov di,chgedobj
@if (si,/=,di)
call dirswap
@ifend
@ifend
add cmpobj,direntrysize ; 次の比較対象へ
inc cmpcount
@doend
mov si,sortobj ;
mov di,chgedobj
@if (si,/=,di)
call dirswap
@ifend
push funclist ; 再帰呼び出し 1
push chgcount
push sortobj
call dirqsort
mov bx,chgedobj ; 再帰呼び出し 2
add bx,direntrysize
mov cx,elmcount
sub cx,chgcount
dec cx
push funclist
push cx
push bx
call dirqsort
@ifend
@ifend
ret 6
;
dirqsort endp
;
;------------------------------------------------------------------------------
;
; dirswap
; ディレクトリエントリの交換
;
; TYPE near call
; IN DS:SI = エントリ1アドレス
; DI = エントリ2アドレス
; OUT なし
; 保存レジスタ bx,dx,si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
dirswap proc
;
cld
mov cx,direntrysize/2
swaploop:
mov ax,[si]
xchg [di],ax
mov [si],ax
lea si,[si+2]
lea di,[di+2]
loop swaploop
;
ret
;
dirswap endp
;
;------------------------------------------------------------------------------
;
; sortfuncall
; ソート用比較関数列の呼び出し
;
; TYPE near call
; IN ES:BX = 比較関数列のアドレス
; DS:SI = エントリ1アドレス
; DI = エントリ2アドレス
; OUT AX = 比較結果
; 保存レジスタ si,di,bp,ds,es
;
;------------------------------------------------------------------------------
;
sortfuncall proc
;
@do until
call word ptr es:[bx] ; 比較関数呼び出し
@if (word ptr es:[bx+2],=,REVERSE) ; 逆順指定の時は結果を反転
neg ax
@ifend
@if (ax,/=,0) ; 比較して違いがあれば終了
jmp compareend
@ifend
lea bx,[bx+4] ; 次の比較関数へ
@doend (word ptr es:[bx],=,0) ; 関数列の終了まで
compareend:
ret
;
sortfuncall endp
;
end