forked from KolibriOS/kolibrios
Add sort.obj library sources to SVN.
git-svn-id: svn://kolibrios.org@4341 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
9ba170ff16
commit
059f79f86f
677
programs/develop/libraries/sorter/sort.asm
Normal file
677
programs/develop/libraries/sorter/sort.asm
Normal file
@ -0,0 +1,677 @@
|
||||
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
|
16
programs/develop/libraries/sorter/sort.txt
Normal file
16
programs/develop/libraries/sorter/sort.txt
Normal file
@ -0,0 +1,16 @@
|
||||
При загрузке библиотеки нужно вызывать функцию START с параметром DLL_ENTRY = 1.
|
||||
Рабочая процедура для сортировки папки экспортируется как SortDir и принимает
|
||||
три параметра, указатель на массив блоков с информацией для файла
|
||||
(стандартные элементы по 304 байта в формате функции 70), число таких блоков
|
||||
и тип сортировки: 0=имя,2=расширение,4=время последней модификации,6=размер,
|
||||
10=время создания,12=время последнего доступа,1,3,5,7,11,13 - сортировка
|
||||
по соответствующему параметру в обратном порядке.
|
||||
Например, для сортировки по расширению данных папки, только что прочитанных
|
||||
функцией 70 в буфер dirdata, можно сделать так:
|
||||
push 2 ; режим сортировки
|
||||
push dword [dirdata+4] ; число файлов
|
||||
; можно писать push ebx, если
|
||||
; дело происходит непосредственно после int 0x40
|
||||
push dirdata+32 ; данные файлов
|
||||
call [SortDir]
|
||||
; теперь данные в dirdata отсортированы
|
Loading…
Reference in New Issue
Block a user