home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 3
/
FREEWARE.BIN
/
ms_dos
/
dsort
/
dstqsrt.asm
< prev
next >
Wrap
Assembly Source File
|
1980-01-02
|
6KB
|
211 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以上ならソート実行
cmp elmcount,1
jg @i0001
jmp @i0002
@i0001:
mov si,sortobj
mov di,direntrysize
add di,si
cmp elmcount,02
mov cmpobj,di
; @if (zf,on) ; 要素数2なら直接比較
jnz @i0003
mov bx,funclist
call sortfuncall
test ax,ax
; @if (zf,off),and,(sf,off) ; エントリ1が大きい時は入れ換え
jz @i0004
js @i0004
mov di,cmpobj
mov si,sortobj
call dirswap
; @ifend
@i0004:
; @else ; 要素数3以上
jmp @i0005
@i0003:
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
@d0001:
mov ax,cmpcount ; 比較終了か?
; @if (ax,ge,elmcount)
cmp ax,elmcount
jl @i0006
; @doexit
jmp @d0002
; @ifend
@i0006:
mov di,sortobj ; 比較関数呼び出し
mov si,cmpobj
mov bx,funclist
call sortfuncall
test ax,ax
; @if (sf,on) ; 比較対象エントリが小さい時
jns @i0007
inc chgcount
add chgedobj,direntrysize
mov si,cmpobj
mov di,chgedobj
; @if (si,/=,di)
cmp si,di
je @i0008
call dirswap
; @ifend
@i0008:
; @ifend
@i0007:
add cmpobj,direntrysize ; 次の比較対象へ
inc cmpcount
; @doend
jmp @d0001
@d0002:
mov si,sortobj ;
mov di,chgedobj
; @if (si,/=,di)
cmp si,di
je @i0009
call dirswap
; @ifend
@i0009:
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
@i0005:
; @ifend
@i0002:
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
@d0003:
call word ptr es:[bx] ; 比較関数呼び出し
; @if (word ptr es:[bx+2],=,REVERSE) ; 逆順指定の時は結果を反転
cmp word ptr es:[bx+2],REVERSE
jne @i0010
neg ax
; @ifend
@i0010:
; @if (ax,/=,0) ; 比較して違いがあれば終了
or ax,ax
je @i0011
jmp compareend
; @ifend
@i0011:
lea bx,[bx+4] ; 次の比較関数へ
; @doend (word ptr es:[bx],=,0) ; 関数列の終了まで
cmp word ptr es:[bx],0
jne @d0003
compareend:
ret
;
sortfuncall endp
;
end