kolibrios-gitea/programs/develop/libraries/sorter/sort.asm

678 lines
15 KiB
NASM
Raw Normal View History

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, '<27>'-'Z'-1
@@:
stosb
inc eax
loop @b
add al, 0x20
mov cl, '<27>'-'<27>'
@@:
stosb
inc eax
loop @b
add al, 0x30
mov cl, '<27>'-'<27>'+1
@@:
stosb
inc eax
loop @b
sub al, 0x50
mov cl, 256-'<27>'-1
@@:
stosb
inc eax
loop @b
mov byte [edi-256+'<27>'], '<27>'
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
; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E0AEA2> qword'<27><> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⢥ ecx <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> edx, <20><EFBFBD><E3ADAA><EFBFBD> <20><EFBFBD><E0A0A2><EFBFBD><EFBFBD><EFBFBD> <20> ebx
; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 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