kolibrios/programs/develop/libraries/sorter/sort.asm
Yogev Ezra 059f79f86f Add sort.obj library sources to SVN.
git-svn-id: svn://kolibrios.org@4341 a494cfbc-eb01-0410-851d-a64ba20cac60
2013-12-10 21:48:04 +00:00

678 lines
15 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

format MS COFF
public EXPORTS
section '.flat' code readable align 16
; void __stdcall START(dword state);
DLL_ENTRY equ 1
DLL_EXIT equ -1
START:
cmp dword [esp+4], DLL_ENTRY
jnz .ret
push edi
mov edi, tolower_table
push 'A'
pop ecx
xor eax, eax
@@:
stosb
inc eax
loop @b
add al, 0x20
mov cl, 'Z'-'A'+1
@@:
stosb
inc eax
loop @b
sub al, 0x20
mov cl, '€'-'Z'-1
@@:
stosb
inc eax
loop @b
add al, 0x20
mov cl, '<27>'-'€'
@@:
stosb
inc eax
loop @b
add al, 0x30
mov cl, 'Ÿ'-'<27>'+1
@@:
stosb
inc eax
loop @b
sub al, 0x50
mov cl, 256-'Ÿ'-1
@@:
stosb
inc eax
loop @b
mov byte [edi-256+'ð'], 'ñ'
pop edi
.ret:
ret 4
; enum sort_mode
; { SORT_BY_NAME = 0, SORT_BY_NAME_REV = 1,
; SORT_BY_EXT = 2, SORT_BY_EXT_REV = 3,
; SORT_BY_MODIFIED = 4, SORT_BY_MODIFIED_REV = 5,
; SORT_BY_SIZE = 6, SORT_BY_SIZE_REV = 7,
; SORT_BY_CREATED = 10, SORT_BY_CREATED_REV = 11,
; SORT_BY_ACCESSED = 12, SORT_BY_ACCESSED_REV = 13 };
; int __stdcall sort_dir(BDFE* folder_data, unsigned num_folder_entries, sort_mode mode);
; return: 0 = ok, 1 = error
sort_dir:
cmp dword [esp+12], num_compare_fns
jae .error
push ebx
mov eax, ptr_table + 0x1FFF
mov edx, ptr_table
and eax, not 0xFFF
mov ecx, [esp+4+8] ; num_folder_entries
sub eax, edx
shl ecx, 3
jz .done
cmp eax, ecx
jae .memok
push 68
pop eax
push 12
pop ebx
int 0x40
test eax, eax
jz .error2
mov edx, eax
.memok:
shr ecx, 3
mov eax, edx
mov ebx, [esp+4+4] ; folder_data
push ecx
.init_ptr:
mov [eax], ebx
mov [eax+4], eax
add eax, 8
add ebx, 304
sub ecx, 1
jnz .init_ptr
pop ecx
mov ebx, [esp+4+12] ; mode
mov ebx, [compare_fns+ebx*4]
test ebx, ebx
jz .done_free
push esi edi ecx
call sort
pop ecx
mov ebx, edx
sub esp, 304
.moveloop:
mov esi, [ebx]
test esi, esi
jz .movenext
cmp [ebx+4], ebx
jz .movenext
mov esi, [ebx]
mov edi, esp
push ecx
mov ecx, 304/4
rep movsd
mov edi, [ebx]
mov eax, [ebx+4]
.z:
mov esi, [eax]
mov dword [eax], 0
push esi
mov ecx, 304/4
rep movsd
pop edi
mov eax, [eax+4]
cmp eax, ebx
jnz .z
lea esi, [esp+4]
mov ecx, 304/4
rep movsd
pop ecx
.movenext:
add ebx, 8
sub ecx, 1
jnz .moveloop
add esp, 304
pop edi esi
.done_free:
cmp edx, ptr_table
jz .done
push 68
pop eax
push 13
pop ebx
mov ecx, edx
int 0x40
.done:
pop ebx
xor eax, eax
ret 12
.error2:
pop ebx
.error:
push 1
pop eax
ret 12
; ‘®àâ¨à®¢ª  qword'®¢ ¢ ª®«¨ç¥á⢥ ecx ¯®  ¤à¥áã edx, äã­ªæ¨ï áà ¢­¥­¨ï ¢ ebx
; <20> §àãè ¥â eax, ecx, esi, edi
sort:
; jecxz .done ; checked by caller
mov eax, ecx
@@:
push eax
call .restore
pop eax
sub eax, 1
jnz @b
@@:
cmp ecx, 1
jz .done
mov esi, 1
mov edi, ecx
call .exchange
dec ecx
mov eax, 1
call .restore
jmp @b
.done:
ret
.exchange:
push eax ecx
mov eax, [edx+esi*8-8]
mov ecx, [edx+edi*8-8]
mov [edx+esi*8-8], ecx
mov [edx+edi*8-8], eax
mov eax, [edx+esi*8-4]
mov ecx, [edx+edi*8-4]
mov [edx+esi*8-4], ecx
mov [edx+edi*8-4], eax
pop ecx eax
ret
.restore:
lea esi, [eax+eax]
cmp esi, ecx
ja .doner
push esi
mov esi, [edx+esi*8-8]
mov edi, [edx+eax*8-8]
call ebx
pop esi
ja .need_xchg
cmp esi, ecx
jae .doner
push esi
mov esi, [edx+esi*8]
mov edi, [edx+eax*8-8]
call ebx
pop esi
jbe .doner
.need_xchg:
cmp esi, ecx
jz .do_xchg
push esi
mov edi, [edx+esi*8-8]
mov esi, [edx+esi*8]
call ebx
pop esi
sbb esi, -1
.do_xchg:
mov edi, eax
call .exchange
mov eax, esi
jmp .restore
.doner:
ret
compare_name:
test byte [esi], 10h
jnz .1dir
test byte [edi], 10h
jnz .greater
.eq1:
add esi, 40
add edi, 40
jmp strcmpi
.greater:
test esi, esi
ret
.1dir:
test byte [edi], 10h
jnz .eq1
.less:
xor edi, edi
stc
ret
compare_name_rev:
test byte [esi], 10h
jnz .1dir
test byte [edi], 10h
jnz .greater
.eq1:
add esi, 40
add edi, 40
xchg esi, edi
jmp strcmpi
.greater:
test esi, esi
ret
.1dir:
test byte [edi], 10h
jnz .eq1
.less:
xor edi, edi
stc
ret
strcmpi:
push eax
@@:
lodsb
call match_symbol
jnz .ret
inc edi
test al, al
jnz @b
.ret:
pop eax
ret
compare_ext:
test byte [esi], 10h
jnz .1dir
test byte [edi], 10h
jnz .greater
.eq1:
add esi, 40
add edi, 40
push esi edi
call seek_ext
xchg esi, edi
call seek_ext
xchg esi, edi
call strcmpi
jnz .ret
pop edi esi
jmp strcmpi
.ret:
pop edi esi
ret
.greater:
test esi, esi
ret
.1dir:
test byte [edi], 10h
jnz .eq1
.less:
xor edi, edi
stc
ret
compare_ext_rev:
test byte [esi], 10h
jnz .1dir
test byte [edi], 10h
jnz .greater
.eq1:
add esi, 40
add edi, 40
push esi edi
call seek_ext
xchg esi, edi
call seek_ext
call strcmpi
jnz .ret
pop edi esi
xchg esi, edi
jmp strcmpi
.ret:
pop edi esi
ret
.greater:
test esi, esi
ret
.1dir:
test byte [edi], 10h
jnz .eq1
.less:
xor edi, edi
stc
ret
seek_ext:
push eax
xor eax, eax
.l:
inc esi
cmp byte [esi-1], '.'
jnz @f
mov eax, esi
@@:
cmp byte [esi-1], 0
jnz .l
test eax, eax
jnz @f
lea eax, [esi-1]
@@:
mov esi, eax
pop eax
ret
compare_modified:
test byte [esi], 10h
jnz .1dir
test byte [edi], 10h
jnz .greater
.eq1:
push edi
mov edi, [edi+28]
cmp edi, [esi+28]
pop edi
jnz @f
push edi
mov edi, [edi+24]
cmp edi, [esi+24]
pop edi
jnz @f
add esi, 40
add edi, 40
jmp strcmpi
@@:
ret
.greater:
test esi, esi
ret
.1dir:
test byte [edi], 10h
jnz .eq1
.less:
xor edi, edi
stc
ret
compare_modified_rev:
test byte [esi], 10h
jnz .1dir
test byte [edi], 10h
jnz .greater
.eq1:
push esi
mov esi, [esi+28]
cmp esi, [edi+28]
pop esi
jnz @f
push esi
mov esi, [esi+24]
cmp esi, [edi+24]
pop esi
jnz @f
add esi, 40
add edi, 40
xchg esi, edi
jmp strcmpi
@@:
ret
.greater:
test esi, esi
ret
.1dir:
test byte [edi], 10h
jnz .eq1
.less:
xor edi, edi
stc
ret
compare_size:
test byte [esi], 10h
jnz .1dir
test byte [edi], 10h
jnz .greater
.eq1:
push edi
mov edi, [edi+36]
cmp edi, [esi+36]
pop edi
jnz @f
push edi
mov edi, [edi+32]
cmp edi, [esi+32]
pop edi
jnz @f
add esi, 40
add edi, 40
jmp strcmpi
@@:
ret
.greater:
test esi, esi
ret
.1dir:
test byte [edi], 10h
jnz .eq1
.less:
xor edi, edi
stc
ret
compare_size_rev:
test byte [esi], 10h
jnz .1dir
test byte [edi], 10h
jnz .greater
.eq1:
push esi
mov esi, [esi+36]
cmp esi, [edi+36]
pop esi
jnz @f
push esi
mov esi, [esi+32]
cmp esi, [edi+32]
pop esi
jnz @f
add esi, 40
add edi, 40
xchg esi, edi
jmp strcmpi
@@:
ret
.greater:
test esi, esi
ret
.1dir:
test byte [edi], 10h
jnz .eq1
.less:
xor edi, edi
stc
ret
compare_unordered:
cmp esi, edi
ret
compare_unordered_rev:
cmp edi, esi
ret
compare_created:
test byte [esi], 10h
jnz .1dir
test byte [edi], 10h
jnz .greater
.eq1:
push edi
mov edi, [edi+12]
cmp edi, [esi+12]
pop edi
jnz @f
push edi
mov edi, [edi+8]
cmp edi, [esi+8]
pop edi
jnz @f
add esi, 40
add edi, 40
jmp strcmpi
@@:
ret
.greater:
test esi, esi
ret
.1dir:
test byte [edi], 10h
jnz .eq1
.less:
xor edi, edi
stc
ret
compare_created_rev:
test byte [esi], 10h
jnz .1dir
test byte [edi], 10h
jnz .greater
.eq1:
push esi
mov esi, [esi+12]
cmp esi, [edi+12]
pop esi
jnz @f
push esi
mov esi, [esi+8]
cmp esi, [edi+8]
pop esi
jnz @f
add esi, 40
add edi, 40
xchg esi, edi
jmp strcmpi
@@:
ret
.greater:
test esi, esi
ret
.1dir:
test byte [edi], 10h
jnz .eq1
.less:
xor edi, edi
stc
ret
compare_accessed:
test byte [esi], 10h
jnz .1dir
test byte [edi], 10h
jnz .greater
.eq1:
push edi
mov edi, [edi+20]
cmp edi, [esi+20]
pop edi
jnz @f
push edi
mov edi, [edi+16]
cmp edi, [esi+16]
pop edi
jnz @f
add esi, 40
add edi, 40
jmp strcmpi
@@:
ret
.greater:
test esi, esi
ret
.1dir:
test byte [edi], 10h
jnz .eq1
.less:
xor edi, edi
stc
ret
compare_accessed_rev:
test byte [esi], 10h
jnz .1dir
test byte [edi], 10h
jnz .greater
.eq1:
push esi
mov esi, [esi+20]
cmp esi, [edi+20]
pop esi
jnz @f
push esi
mov esi, [esi+16]
cmp esi, [edi+16]
pop esi
jnz @f
add esi, 40
add edi, 40
xchg esi, edi
jmp strcmpi
@@:
ret
.greater:
test esi, esi
ret
.1dir:
test byte [edi], 10h
jnz .eq1
.less:
xor edi, edi
stc
ret
match_symbol:
; in: al,[edi]=symbols
; out: flags as 'cmp al,[edi]'
push eax ecx
movzx ecx, al
mov al, [tolower_table+ecx]
movzx ecx, byte [edi]
cmp al, [tolower_table+ecx]
pop ecx eax
ret
align 4
compare_fns dd compare_name
dd compare_name_rev
dd compare_ext
dd compare_ext_rev
dd compare_modified
dd compare_modified_rev
dd compare_size
dd compare_size_rev
; dd compare_unordered
; dd compare_unordered_rev
dd 0
dd 0
dd compare_created
dd compare_created_rev
dd compare_accessed
dd compare_accessed_rev
num_compare_fns = ($ - compare_fns) / 4
EXPORTS:
dd szStart, START
dd szVersion, 0x00010001
dd szSortDir, sort_dir
dd szStrcmpi, strcmpi
dd 0
szStart db 'START',0
szVersion db 'version',0
szSortDir db 'SortDir',0
szStrcmpi db 'strcmpi',0
section '.data' data readable writable align 16
tolower_table rb 256
; ptr_table must be last variable
ptr_table rb 0x1000