5,20 → 5,17 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
$Revision: 3742 $ |
$Revision: 4700 $ |
|
|
;----------------------------------------------------------------------------- |
uglobal |
cd_current_pointer_of_input dd 0 |
cd_current_pointer_of_input_2 dd 0 |
cd_mem_location dd 0 |
cd_counter_block dd 0 |
IDE_Channel_1 db 0 |
IDE_Channel_2 db 0 |
endg |
|
;----------------------------------------------------------------------------- |
reserve_cd: |
|
cli |
cmp [cd_status], 0 |
je reserve_ok2 |
26,9 → 23,8 |
sti |
call change_task |
jmp reserve_cd |
|
;----------------------------------------------------------------------------- |
reserve_ok2: |
|
push eax |
mov eax, [CURRENT_TASK] |
shl eax, 5 |
37,48 → 33,105 |
pop eax |
sti |
ret |
;----------------------------------------------------------------------------- |
reserve_cd_channel: |
pushad |
mov eax, [cdpos] |
dec eax |
shr eax, 2 |
|
reserve_cd_channel: |
test eax, eax |
jnz .1 |
|
cmp [ChannelNumber], 1 |
jne .IDE_Channel_2 |
.IDE_Channel_1: |
pushad |
jne @f |
|
mov ecx, ide_channel1_mutex |
jmp .mutex_lock |
;-------------------------------------- |
@@: |
mov ecx, ide_channel2_mutex |
jmp .mutex_lock |
;-------------------------------------- |
.1: |
dec eax |
jnz .2 |
|
cmp [ChannelNumber], 1 |
jne @f |
|
mov ecx, ide_channel3_mutex |
jmp .mutex_lock |
;-------------------------------------- |
@@: |
mov ecx, ide_channel4_mutex |
jmp .mutex_lock |
;-------------------------------------- |
.2: |
cmp [ChannelNumber], 1 |
jne @f |
|
mov ecx, ide_channel5_mutex |
jmp .mutex_lock |
;-------------------------------------- |
@@: |
mov ecx, ide_channel6_mutex |
.mutex_lock: |
call mutex_lock |
mov [IDE_Channel_1], 1 |
popad |
ret |
.IDE_Channel_2: |
;----------------------------------------------------------------------------- |
free_cd_channel: |
pushad |
mov ecx, ide_channel2_mutex |
call mutex_lock |
mov [IDE_Channel_2], 1 |
popad |
ret |
mov eax, [cdpos] |
dec eax |
shr eax, 2 |
|
free_cd_channel: |
test eax, eax |
jnz .1 |
|
cmp [ChannelNumber], 1 |
jne .IDE_Channel_2 |
.IDE_Channel_1: |
mov [IDE_Channel_1], 0 |
pushad |
jne @f |
|
mov ecx, ide_channel1_mutex |
call mutex_unlock |
popad |
ret |
.IDE_Channel_2: |
mov [IDE_Channel_2], 0 |
pushad |
jmp .mutex_unlock |
;-------------------------------------- |
@@: |
mov ecx, ide_channel2_mutex |
jmp .mutex_unlock |
;-------------------------------------- |
.1: |
dec eax |
jnz .2 |
|
cmp [ChannelNumber], 1 |
jne @f |
|
mov ecx, ide_channel3_mutex |
jmp .mutex_unlock |
;-------------------------------------- |
@@: |
mov ecx, ide_channel4_mutex |
jmp .mutex_unlock |
;-------------------------------------- |
.2: |
cmp [ChannelNumber], 1 |
jne @f |
|
mov ecx, ide_channel5_mutex |
jmp .mutex_unlock |
;-------------------------------------- |
@@: |
mov ecx, ide_channel6_mutex |
.mutex_unlock: |
call mutex_unlock |
popad |
ret |
|
;----------------------------------------------------------------------------- |
uglobal |
cd_status dd 0 |
endg |
|
;---------------------------------------------------------------- |
;----------------------------------------------------------------------------- |
; |
; fs_CdRead - LFN variant for reading CD disk |
; |
91,91 → 144,114 |
; ret ebx = bytes read or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
;----------------------------------------------------------------------------- |
fs_CdRead: |
push edi |
cmp byte [esi], 0 |
jnz @f |
;-------------------------------------- |
.noaccess: |
pop edi |
;-------------------------------------- |
.noaccess_2: |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
|
;-------------------------------------- |
.noaccess_3: |
pop eax edx ecx edi |
jmp .noaccess_2 |
|
;-------------------------------------- |
@@: |
call cd_find_lfn |
jnc .found |
|
pop edi |
cmp [DevErrorCode], 0 |
jne .noaccess_2 |
|
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
|
;-------------------------------------- |
.found: |
mov edi, [cd_current_pointer_of_input] |
test byte [edi+25], 10b; do not allow read directories |
jnz .noaccess |
|
test ebx, ebx |
jz .l1 |
|
cmp dword [ebx+4], 0 |
jz @f |
|
xor ebx, ebx |
;-------------------------------------- |
.reteof: |
mov eax, 6; end of file |
pop edi |
ret |
;-------------------------------------- |
@@: |
mov ebx, [ebx] |
;-------------------------------------- |
.l1: |
push ecx edx |
push 0 |
mov eax, [edi+10] ; реальный размер файловой секции |
mov eax, [edi+10] ; real size of the file section |
sub eax, ebx |
jb .eof |
|
cmp eax, ecx |
jae @f |
|
mov ecx, eax |
mov byte [esp], 6 |
;-------------------------------------- |
@@: |
mov eax, [edi+2] |
mov [CDSectorAddress], eax |
;-------------------------------------- |
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data |
.new_sector: |
test ecx, ecx |
jz .done |
|
sub ebx, 2048 |
jae .next |
|
add ebx, 2048 |
jnz .incomplete_sector |
|
cmp ecx, 2048 |
jb .incomplete_sector |
; we may read and memmove complete sector |
mov [CDDataBuf_pointer], edx |
call ReadCDWRetr; читаем сектор файла |
call ReadCDWRetr ; read sector of file |
cmp [DevErrorCode], 0 |
jne .noaccess_3 |
|
add edx, 2048 |
sub ecx, 2048 |
;-------------------------------------- |
.next: |
inc dword [CDSectorAddress] |
jmp .new_sector |
;-------------------------------------- |
.incomplete_sector: |
; we must read and memmove incomplete sector |
mov [CDDataBuf_pointer], CDDataBuf |
call ReadCDWRetr; читаем сектор файла |
call ReadCDWRetr ; read sector of file |
cmp [DevErrorCode], 0 |
jne .noaccess_3 |
|
push ecx |
add ecx, ebx |
cmp ecx, 2048 |
jbe @f |
|
mov ecx, 2048 |
;-------------------------------------- |
@@: |
sub ecx, ebx |
push edi esi ecx |
189,19 → 265,19 |
pop ecx |
xor ebx, ebx |
jmp .next |
|
;-------------------------------------- |
.done: |
mov ebx, edx |
pop eax edx ecx edi |
sub ebx, edx |
ret |
;-------------------------------------- |
.eof: |
mov ebx, edx |
pop eax edx ecx |
sub ebx, edx |
jmp .reteof |
|
;---------------------------------------------------------------- |
;----------------------------------------------------------------------------- |
; |
; fs_CdReadFolder - LFN variant for reading CD disk folder |
; |
215,30 → 291,37 |
; ret ebx = blocks read or 0xffffffff folder not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
;----------------------------------------------------------------------------- |
fs_CdReadFolder: |
push edi |
call cd_find_lfn |
jnc .found |
|
pop edi |
cmp [DevErrorCode], 0 |
jne .noaccess_1 |
|
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
;-------------------------------------- |
.found: |
mov edi, [cd_current_pointer_of_input] |
test byte [edi+25], 10b ; do not allow read directories |
jnz .found_dir |
|
pop edi |
;-------------------------------------- |
.noaccess_1: |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
;-------------------------------------- |
.found_dir: |
mov eax, [edi+2] ; eax=cluster |
mov [CDSectorAddress], eax |
mov eax, [edi+10] ; размер директрории |
mov eax, [edi+10] ; directory size |
;-------------------------------------- |
.doit: |
; init header |
push eax ecx |
250,21 → 333,23 |
mov byte [edx], 1 ; version |
mov [cd_mem_location], edx |
add [cd_mem_location], 32 |
; начинаем переброску БДВК в УСВК |
;.mainloop: |
mov [cd_counter_block], dword 0 |
dec dword [CDSectorAddress] |
push ecx |
;-------------------------------------- |
.read_to_buffer: |
inc dword [CDSectorAddress] |
mov [CDDataBuf_pointer], CDDataBuf |
call ReadCDWRetr ; читаем сектор директории |
call ReadCDWRetr ; read sector of directory |
cmp [DevErrorCode], 0 |
jne .noaccess_1 |
|
call .get_names_from_buffer |
sub eax, 2048 |
; директория закончилась? |
; directory is over? |
ja .read_to_buffer |
|
mov edi, [cd_counter_block] |
mov [edx+8], edi |
mov edi, [ebx] |
272,24 → 357,30 |
xor eax, eax |
dec ecx |
js @f |
|
mov al, ERROR_END_OF_FILE |
;-------------------------------------- |
@@: |
pop ecx edi |
mov ebx, [edx+4] |
ret |
|
;-------------------------------------- |
.get_names_from_buffer: |
mov [cd_current_pointer_of_input_2], CDDataBuf |
push eax esi edi edx |
;-------------------------------------- |
.get_names_from_buffer_1: |
call cd_get_name |
jc .end_buffer |
|
inc dword [cd_counter_block] |
mov eax, [cd_counter_block] |
cmp [ebx], eax |
jae .get_names_from_buffer_1 |
|
test ecx, ecx |
jz .get_names_from_buffer_1 |
|
mov edi, [cd_counter_block] |
mov [edx+4], edi |
dec ecx |
298,10 → 389,11 |
add edi, 40 |
test dword [ebx+4], 1; 0=ANSI, 1=UNICODE |
jnz .unicode |
; jmp .unicode |
;-------------------------------------- |
.ansi: |
cmp [cd_counter_block], 2 |
jbe .ansi_parent_directory |
|
cld |
lodsw |
xchg ah, al |
308,163 → 400,178 |
call uni2ansi_char |
cld |
stosb |
; проверка конца файла |
; check end of file |
mov ax, [esi] |
cmp ax, word 3B00h; сепаратор конца файла ';' |
cmp ax, word 3B00h ; separator end of file ';' |
je .cd_get_parameters_of_file_1 |
; проверка для файлов не заканчивающихся сепаратором |
; check for files not ending with separator |
movzx eax, byte [ebp-33] |
add eax, ebp |
sub eax, 34 |
cmp esi, eax |
je .cd_get_parameters_of_file_1 |
; проверка конца папки |
; check the end of the directory |
movzx eax, byte [ebp-1] |
add eax, ebp |
cmp esi, eax |
jb .ansi |
;-------------------------------------- |
.cd_get_parameters_of_file_1: |
mov [edi], byte 0 |
call cd_get_parameters_of_file |
add [cd_mem_location], 304 |
jmp .get_names_from_buffer_1 |
|
;-------------------------------------- |
.ansi_parent_directory: |
cmp [cd_counter_block], 2 |
je @f |
|
mov [edi], byte '.' |
inc edi |
jmp .cd_get_parameters_of_file_1 |
;-------------------------------------- |
@@: |
mov [edi], word '..' |
add edi, 2 |
jmp .cd_get_parameters_of_file_1 |
|
;-------------------------------------- |
.unicode: |
cmp [cd_counter_block], 2 |
jbe .unicode_parent_directory |
|
cld |
movsw |
; проверка конца файла |
; check end of file |
mov ax, [esi] |
cmp ax, word 3B00h; сепаратор конца файла ';' |
cmp ax, word 3B00h; separator end of file ';' |
je .cd_get_parameters_of_file_2 |
; проверка для файлов не заканчивающихся сепаратором |
; check for files not ending with separator |
movzx eax, byte [ebp-33] |
add eax, ebp |
sub eax, 34 |
cmp esi, eax |
je .cd_get_parameters_of_file_2 |
; проверка конца папки |
; check the end of the directory |
movzx eax, byte [ebp-1] |
add eax, ebp |
cmp esi, eax |
jb .unicode |
;-------------------------------------- |
.cd_get_parameters_of_file_2: |
mov [edi], word 0 |
call cd_get_parameters_of_file |
add [cd_mem_location], 560 |
jmp .get_names_from_buffer_1 |
|
;-------------------------------------- |
.unicode_parent_directory: |
cmp [cd_counter_block], 2 |
je @f |
|
mov [edi], word 2E00h; '.' |
add edi, 2 |
jmp .cd_get_parameters_of_file_2 |
;-------------------------------------- |
@@: |
mov [edi], dword 2E002E00h; '..' |
add edi, 4 |
jmp .cd_get_parameters_of_file_2 |
|
;-------------------------------------- |
.end_buffer: |
pop edx edi esi eax |
ret |
|
;----------------------------------------------------------------------------- |
cd_get_parameters_of_file: |
mov edi, [cd_mem_location] |
cd_get_parameters_of_file_1: |
; получаем атрибуты файла |
; get file attributes |
xor eax, eax |
; файл не архивировался |
; file is not archived |
inc eax |
shl eax, 1 |
; это каталог? |
; is a directory? |
test [ebp-8], byte 2 |
jz .file |
|
inc eax |
;-------------------------------------- |
.file: |
; метка тома не как в FAT, в этом виде отсутсвует |
; файл не является системным |
; not as a volume label in the FAT, in this form not available |
; file is not a system |
shl eax, 3 |
; файл является скрытым? (атрибут существование) |
; file is hidden? (attribute of existence) |
test [ebp-8], byte 1 |
jz .hidden |
|
inc eax |
;-------------------------------------- |
.hidden: |
shl eax, 1 |
; файл всегда только для чтения, так как это CD |
; file is always read-only, as this CD |
inc eax |
mov [edi], eax |
; получаем время для файла |
;час |
; get the time to file |
; hour |
movzx eax, byte [ebp-12] |
shl eax, 8 |
;минута |
; minute |
mov al, [ebp-11] |
shl eax, 8 |
;секунда |
; second |
mov al, [ebp-10] |
;время создания файла |
; file creation time |
mov [edi+8], eax |
;время последнего доступа |
; last access time |
mov [edi+16], eax |
;время последней записи |
; last write time |
mov [edi+24], eax |
; получаем дату для файла |
;год |
; get date for file |
; year |
movzx eax, byte [ebp-15] |
add eax, 1900 |
shl eax, 8 |
;месяц |
; month |
mov al, [ebp-14] |
shl eax, 8 |
;день |
; day |
mov al, [ebp-13] |
;дата создания файла |
; file creation date |
mov [edi+12], eax |
;время последнего доступа |
; last access date |
mov [edi+20], eax |
;время последней записи |
; last write date |
mov [edi+28], eax |
; получаем тип данных имени |
; get the data type of name |
xor eax, eax |
test dword [ebx+4], 1; 0=ANSI, 1=UNICODE |
jnz .unicode_1 |
|
mov [edi+4], eax |
jmp @f |
;-------------------------------------- |
.unicode_1: |
inc eax |
mov [edi+4], eax |
;-------------------------------------- |
@@: |
; получаем размер файла в байтах |
; get the file size in bytes |
xor eax, eax |
mov [edi+32+4], eax |
mov eax, [ebp-23] |
mov [edi+32], eax |
ret |
|
;---------------------------------------------------------------- |
;----------------------------------------------------------------------------- |
; |
; fs_CdGetFileInfo - LFN variant for CD |
; get file/directory attributes structure |
; |
;---------------------------------------------------------------- |
;----------------------------------------------------------------------------- |
fs_CdGetFileInfo: |
cmp byte [esi], 0 |
jnz @f |
|
mov eax, 2 |
ret |
;-------------------------------------- |
@@: |
push edi |
call cd_find_lfn |
471,16 → 578,20 |
pushfd |
cmp [DevErrorCode], 0 |
jz @f |
|
popfd |
pop edi |
mov eax, 11 |
ret |
;-------------------------------------- |
@@: |
popfd |
jnc @f |
|
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
;-------------------------------------- |
@@: |
|
mov edi, edx |
493,8 → 604,7 |
pop edi |
xor eax, eax |
ret |
|
;---------------------------------------------------------------- |
;----------------------------------------------------------------------------- |
cd_find_lfn: |
mov [cd_appl_data], 0 |
; in: esi+ebp -> name |
501,14 → 611,13 |
; out: CF=1 - file not found |
; else CF=0 and [cd_current_pointer_of_input] direntry |
push eax esi |
; 16 сектор начало набора дескрипторов томов |
|
; Sector 16 - start set of volume descriptors |
call WaitUnitReady |
cmp [DevErrorCode], 0 |
jne .access_denied |
|
call prevent_medium_removal |
; тестовое чтение |
; testing of reading |
mov [CDSectorAddress], dword 16 |
mov [CDDataBuf_pointer], CDDataBuf |
call ReadCDWRetr;_1 |
515,10 → 624,11 |
cmp [DevErrorCode], 0 |
jne .access_denied |
|
; вычисление последней сессии |
; calculation of the last session |
call WaitUnitReady |
cmp [DevErrorCode], 0 |
jne .access_denied |
|
call Read_TOC |
mov ah, [CDDataBuf+4+4] |
mov al, [CDDataBuf+4+5] |
529,7 → 639,7 |
mov [CDSectorAddress], eax |
; mov [CDSectorAddress],dword 15 |
mov [CDDataBuf_pointer], CDDataBuf |
|
;-------------------------------------- |
.start: |
inc dword [CDSectorAddress] |
call ReadCDWRetr;_1 |
537,111 → 647,128 |
jne .access_denied |
|
.start_check: |
; проверка на вшивость |
; checking for "lice" |
cmp [CDDataBuf+1], dword 'CD00' |
jne .access_denied |
|
cmp [CDDataBuf+5], byte '1' |
jne .access_denied |
; сектор является терминатором набор дескрипторов томов? |
; sector is the terminator of set of descriptors volumes? |
cmp [CDDataBuf], byte 0xff |
je .access_denied |
; сектор является дополнительным и улучшенным дескриптором тома? |
; sector is an additional and improved descriptor of volume? |
cmp [CDDataBuf], byte 0x2 |
jne .start |
; сектор является дополнительным дескриптором тома? |
; sector is an additional descriptor of volume? |
cmp [CDDataBuf+6], byte 0x1 |
jne .start |
|
; параметры root директрории |
mov eax, [CDDataBuf+0x9c+2]; начало root директрории |
; parameters of root directory |
mov eax, [CDDataBuf+0x9c+2]; start of root directory |
mov [CDSectorAddress], eax |
mov eax, [CDDataBuf+0x9c+10]; размер root директрории |
mov eax, [CDDataBuf+0x9c+10]; size of root directory |
cmp byte [esi], 0 |
jnz @f |
|
mov [cd_current_pointer_of_input], CDDataBuf+0x9c |
jmp .done |
;-------------------------------------- |
@@: |
; начинаем поиск |
; start the search |
.mainloop: |
dec dword [CDSectorAddress] |
;-------------------------------------- |
.read_to_buffer: |
inc dword [CDSectorAddress] |
mov [CDDataBuf_pointer], CDDataBuf |
call ReadCDWRetr ; читаем сектор директории |
call ReadCDWRetr ; read sector of directory |
cmp [DevErrorCode], 0 |
jne .access_denied |
|
push ebp |
call cd_find_name_in_buffer |
pop ebp |
jnc .found |
|
sub eax, 2048 |
; директория закончилась? |
; directory is over? |
cmp eax, 0 |
ja .read_to_buffer |
; нет искомого элемента цепочки |
; desired element of chain is not found |
.access_denied: |
pop esi eax |
mov [cd_appl_data], 1 |
stc |
ret |
; искомый элемент цепочки найден |
;-------------------------------------- |
; desired element of chain found |
.found: |
; конец пути файла |
; the end of the file path |
cmp byte [esi-1], 0 |
jz .done |
.nested: |
mov eax, [cd_current_pointer_of_input] |
push dword [eax+2] |
pop dword [CDSectorAddress] ; начало директории |
mov eax, [eax+2+8]; размер директории |
pop dword [CDSectorAddress] ; beginning of the directory |
mov eax, [eax+2+8] ; size of directory |
jmp .mainloop |
; указатель файла найден |
;-------------------------------------- |
; file pointer found |
.done: |
test ebp, ebp |
jz @f |
|
mov esi, ebp |
xor ebp, ebp |
jmp .nested |
;-------------------------------------- |
@@: |
pop esi eax |
mov [cd_appl_data], 1 |
clc |
ret |
|
;----------------------------------------------------------------------------- |
cd_find_name_in_buffer: |
mov [cd_current_pointer_of_input_2], CDDataBuf |
;-------------------------------------- |
.start: |
call cd_get_name |
jc .not_found |
|
call cd_compare_name |
jc .start |
;-------------------------------------- |
.found: |
clc |
ret |
;-------------------------------------- |
.not_found: |
stc |
ret |
|
;----------------------------------------------------------------------------- |
cd_get_name: |
push eax |
mov ebp, [cd_current_pointer_of_input_2] |
mov [cd_current_pointer_of_input], ebp |
mov eax, [ebp] |
test eax, eax ; входы закончились? |
test eax, eax ; entry's is over? |
jz .next_sector |
cmp ebp, CDDataBuf+2048 ; буфер закончился? |
|
cmp ebp, CDDataBuf+2048 ; buffer is over? |
jae .next_sector |
|
movzx eax, byte [ebp] |
add [cd_current_pointer_of_input_2], eax; следующий вход каталога |
add ebp, 33; указатель установлен на начало имени |
add [cd_current_pointer_of_input_2], eax ; next entry of directory |
add ebp, 33; pointer is set to the beginning of the name |
pop eax |
clc |
ret |
;-------------------------------------- |
.next_sector: |
pop eax |
stc |
ret |
|
;----------------------------------------------------------------------------- |
cd_compare_name: |
; compares ASCIIZ-names, case-insensitive (cp866 encoding) |
; in: esi->name, ebp->name |
650,6 → 777,7 |
; destroys eax |
push esi eax edi |
mov edi, ebp |
;-------------------------------------- |
.loop: |
cld |
lodsb |
666,31 → 794,37 |
sub edi, 2 |
scasw |
jne .name_not_coincide |
;-------------------------------------- |
.coincides: |
cmp [esi], byte '/'; разделитель пути, конец имени текущего элемента |
cmp [esi], byte '/' ; path separator is end of current element |
je .done |
cmp [esi], byte 0; разделитель пути, конец имени текущего элемента |
|
cmp [esi], byte 0 ; path separator end of name |
je .done |
|
jmp .loop |
;-------------------------------------- |
.name_not_coincide: |
pop edi eax esi |
stc |
ret |
;-------------------------------------- |
.done: |
; проверка конца файла |
cmp [edi], word 3B00h; сепаратор конца файла ';' |
; check end of file |
cmp [edi], word 3B00h; separator end of file ';' |
je .done_1 |
; проверка для файлов не заканчивающихся сепаратором |
; check for files not ending with separator |
movzx eax, byte [ebp-33] |
add eax, ebp |
sub eax, 34 |
cmp edi, eax |
je .done_1 |
; проверка конца папки |
; check the end of directory |
movzx eax, byte [ebp-1] |
add eax, ebp |
cmp edi, eax |
jne .name_not_coincide |
;-------------------------------------- |
.done_1: |
pop edi eax |
add esp, 4 |
697,7 → 831,7 |
inc esi |
clc |
ret |
|
;----------------------------------------------------------------------------- |
char_todown: |
; convert character to uppercase, using cp866 encoding |
; in: al=symbol |
704,24 → 838,30 |
; out: al=converted symbol |
cmp al, 'A' |
jb .ret |
|
cmp al, 'Z' |
jbe .az |
|
cmp al, 0x80 ; 'А' |
jb .ret |
|
cmp al, 0x90 ; 'Р' |
jb .rus1 |
|
cmp al, 0x9F ; 'Я' |
ja .ret |
; 0x90-0x9F -> 0xE0-0xEF |
add al, 0xE0-0x90 |
;-------------------------------------- |
.ret: |
ret |
;-------------------------------------- |
.rus1: |
; 0x80-0x8F -> 0xA0-0xAF |
.az: |
add al, 0x20 |
ret |
|
;----------------------------------------------------------------------------- |
uni2ansi_char: |
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding |
; in: ax=UNICODE character |
728,32 → 868,44 |
; out: al=converted ANSI character |
cmp ax, 0x80 |
jb .ascii |
|
cmp ax, 0x401 |
jz .yo1 |
|
cmp ax, 0x451 |
jz .yo2 |
|
cmp ax, 0x410 |
jb .unk |
|
cmp ax, 0x440 |
jb .rus1 |
|
cmp ax, 0x450 |
jb .rus2 |
;-------------------------------------- |
.unk: |
mov al, '_' |
jmp .doit |
;-------------------------------------- |
.yo1: |
mov al, 0xF0 ; 'Ё' in cp866 |
jmp .doit |
;-------------------------------------- |
.yo2: |
mov al, 0xF1 ; 'ё' in cp866 |
jmp .doit |
;-------------------------------------- |
.rus1: |
; 0x410-0x43F -> 0x80-0xAF |
add al, 0x70 |
jmp .doit |
;-------------------------------------- |
.rus2: |
; 0x440-0x44F -> 0xE0-0xEF |
add al, 0xA0 |
;-------------------------------------- |
.ascii: |
.doit: |
ret |
;----------------------------------------------------------------------------- |