forked from KolibriOS/kolibrios
Added:
1) Low level procedures for СD device: read sector, load tray, out tray; 2) Function 70/0 for ISO9660 - read file 2) Function 70/0 for ISO9660 - read directory in format of standard 1. git-svn-id: svn://kolibrios.org@87 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
b3a457d97d
commit
4a1560020b
546
kernel/trunk/blkdev/cd_drv.inc
Normal file
546
kernel/trunk/blkdev/cd_drv.inc
Normal file
@ -0,0 +1,546 @@
|
||||
;**********************************************************
|
||||
; Непосредственная работа с устройством СD (ATAPI)
|
||||
;**********************************************************
|
||||
; Автор исходного текста Кулаков Владимир Геннадьевич.
|
||||
; Адаптация и доработка Mario79
|
||||
|
||||
; Процедура для полного считывания всех
|
||||
; данных из сектора компакт-диска
|
||||
; Автор текста программы Кулаков Владимир Геннадьевич.
|
||||
|
||||
|
||||
; Максимальное количество повторений операции чтения
|
||||
MaxRetr equ 3
|
||||
; Предельное время ожидания готовности к приему команды
|
||||
; (в тиках)
|
||||
BSYWaitTime equ 1000 ;2
|
||||
|
||||
;*************************************************
|
||||
;* ПОЛНОЕ ЧТЕНИЕ СЕКТОРА КОМПАКТ-ДИСКА *
|
||||
;* Считываются данные пользователя, информация *
|
||||
;* субканала и контрольная информация *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* перменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале; *
|
||||
;* CDSectorAddress - адрес считываемого сектора. *
|
||||
;* Данные считывается в массив CDDataBuf. *
|
||||
;*************************************************
|
||||
ReadCD:
|
||||
pusha
|
||||
; Задать размер сектора
|
||||
mov [CDBlockSize],2048 ;2352
|
||||
; Очистить буфер пакетной команды
|
||||
call clear_packet_buffer
|
||||
; Сформировать пакетную команду для считывания
|
||||
; сектора данных
|
||||
; Задать код команды Read CD
|
||||
mov [PacketCommand],byte 0x28 ;0xBE
|
||||
; Задать адрес сектора
|
||||
mov AX,word [CDSectorAddress+2]
|
||||
xchg AL,AH
|
||||
mov word [PacketCommand+2],AX
|
||||
mov AX,word [CDSectorAddress]
|
||||
xchg AL,AH
|
||||
mov word [PacketCommand+4],AX
|
||||
; mov eax,[CDSectorAddress]
|
||||
; mov [PacketCommand+2],eax
|
||||
; Задать количество считываемых секторов
|
||||
mov [PacketCommand+8],byte 1
|
||||
; Задать считывание данных в полном объеме
|
||||
; mov [PacketCommand+9],byte 0xF8
|
||||
; Подать команду
|
||||
call SendPacketDatCommand
|
||||
; call test_mario79
|
||||
popa
|
||||
ret
|
||||
|
||||
;********************************************
|
||||
;* ЧТЕНИЕ СЕКТОРА С ПОВТОРАМИ *
|
||||
;* Многократное повторение чтения при сбоях *
|
||||
;********************************************
|
||||
ReadCDWRetr:
|
||||
pusha
|
||||
; Цикл, пока команда не выполнена успешно или не
|
||||
; исчерпано количество попыток
|
||||
mov ECX,MaxRetr
|
||||
@@NextRetr:
|
||||
; Подать команду
|
||||
call ReadCD
|
||||
cmp [DevErrorCode],0
|
||||
je @@End_4
|
||||
; Задержка на 2,5 секунды
|
||||
mov EAX,[timer_ticks]
|
||||
add EAX,250 ;50
|
||||
@@Wait:
|
||||
call change_task
|
||||
cmp EAX,[timer_ticks]
|
||||
ja @@Wait
|
||||
loop @@NextRetr
|
||||
; call test_mario79
|
||||
; Сообщение об ошибке
|
||||
; mov SI,offset ErrS
|
||||
; call FatalError
|
||||
@@End_4:
|
||||
popa
|
||||
ret
|
||||
|
||||
|
||||
; Универсальные процедуры, обеспечивающие выполнение
|
||||
; пакетных команд в режиме PIO
|
||||
;
|
||||
; Автор текста программы Кулаков Владимир Геннадьевич.
|
||||
|
||||
; Максимально допустимое время ожидания реакции
|
||||
; устройства на пакетную команду (в тиках)
|
||||
MaxCDWaitTime equ 1000 ;200 ;10 секунд
|
||||
|
||||
; Область памяти для формирования пакетной команды
|
||||
PacketCommand: rb 12 ;DB 12 DUP (?)
|
||||
; Область памяти для приема данных от дисковода
|
||||
;CDDataBuf DB 4096 DUP (0)
|
||||
; Размер принимаемого блока данных в байтах
|
||||
CDBlockSize DW ?
|
||||
; Адрес считываемого сектора данных
|
||||
CDSectorAddress: DD ?
|
||||
; Время начала очередной операции с диском
|
||||
TickCounter_1 DD 0
|
||||
; Время начала ожидания готовности устройства
|
||||
WURStartTime DD 0
|
||||
; указатель буфера для считывания
|
||||
CDDataBuf_pointer dd 0
|
||||
|
||||
;****************************************************
|
||||
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
|
||||
;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ *
|
||||
;* РАЗМЕРОМ 2048 БАЙТ ОТ УСТРОЙСТВА К ХОСТУ *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* перменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале; *
|
||||
;* PacketCommand - 12-байтный командный пакет; *
|
||||
;* CDBlockSize - размер принимаемого блока данных. *
|
||||
;****************************************************
|
||||
SendPacketDatCommand:
|
||||
pushad
|
||||
; Задать режим CHS
|
||||
mov [ATAAddressMode],0
|
||||
; Послать ATA-команду передачи пакетной команды
|
||||
mov [ATAFeatures],0
|
||||
mov [ATASectorCount],0
|
||||
mov [ATASectorNumber],0
|
||||
; Загрузить размер передаваемого блока
|
||||
mov AX,[CDBlockSize]
|
||||
mov [ATACylinder],AX
|
||||
mov [ATAHead],0
|
||||
mov [ATACommand],0A0h
|
||||
call SendCommandToHDD_1
|
||||
; call test_mario79
|
||||
cmp [DevErrorCode],0 ;проверить код ошибки
|
||||
jne @@End_8 ;закончить, сохранив код ошибки
|
||||
|
||||
; Ожидание готовности дисковода к приему
|
||||
; пакетной команды
|
||||
mov DX,[ATABasePortAddr]
|
||||
add DX,7 ;порт 1х7h
|
||||
@@WaitDevice0:
|
||||
call change_task
|
||||
; Проверить время выполнения команды
|
||||
mov EAX,[timer_ticks]
|
||||
sub EAX,[TickCounter_1]
|
||||
cmp EAX,BSYWaitTime
|
||||
ja @@Err1_1 ;ошибка тайм-аута
|
||||
; Проверить готовность
|
||||
in AL,DX
|
||||
test AL,80h ;состояние сигнала BSY
|
||||
jnz @@WaitDevice0
|
||||
test AL,1 ;состояние сигнала ERR
|
||||
jnz @@Err6
|
||||
test AL,08h ;состояние сигнала DRQ
|
||||
jz @@WaitDevice0
|
||||
; Послать пакетную команду
|
||||
cli
|
||||
mov DX,[ATABasePortAddr]
|
||||
mov AX,[PacketCommand]
|
||||
out DX,AX
|
||||
mov AX,[PacketCommand+2]
|
||||
out DX,AX
|
||||
mov AX,[PacketCommand+4]
|
||||
out DX,AX
|
||||
mov AX,[PacketCommand+6]
|
||||
out DX,AX
|
||||
mov AX,[PacketCommand+8]
|
||||
out DX,AX
|
||||
mov AX,[PacketCommand+10]
|
||||
out DX,AX
|
||||
sti
|
||||
; Ожидание готовности данных
|
||||
mov DX,[ATABasePortAddr]
|
||||
add DX,7 ;порт 1х7h
|
||||
@@WaitDevice1:
|
||||
call change_task
|
||||
; Проверить время выполнения команды
|
||||
mov EAX,[timer_ticks]
|
||||
sub EAX,[TickCounter_1]
|
||||
cmp EAX,MaxCDWaitTime
|
||||
ja @@Err1_1 ;ошибка тайм-аута
|
||||
; Проверить готовность
|
||||
in AL,DX
|
||||
test AL,80h ;состояние сигнала BSY
|
||||
jnz @@WaitDevice1
|
||||
test AL,1 ;состояние сигнала ERR
|
||||
jnz @@Err6_temp
|
||||
test AL,08h ;состояние сигнала DRQ
|
||||
jz @@WaitDevice1
|
||||
cli
|
||||
; Принять блок данных от контроллера
|
||||
mov EDI,[CDDataBuf_pointer] ;0x7000 ;CDDataBuf
|
||||
; Загрузить адрес регистра данных контроллера
|
||||
mov DX,[ATABasePortAddr] ;порт 1x0h
|
||||
; Загрузить в счетчик размер блока в байтах
|
||||
mov CX,[CDBlockSize]
|
||||
; Вычислить размер блока в 16-разрядных словах
|
||||
shr CX,1 ;разделить размер блока на 2
|
||||
; Принять блок данных
|
||||
cld
|
||||
rep insw
|
||||
sti
|
||||
; Успешное завершение приема данных
|
||||
jmp @@End_8
|
||||
|
||||
; Записать код ошибки
|
||||
@@Err1_1:
|
||||
mov [DevErrorCode],1
|
||||
jmp @@End_8
|
||||
@@Err6_temp:
|
||||
mov [DevErrorCode],7
|
||||
jmp @@End_8
|
||||
@@Err6:
|
||||
mov [DevErrorCode],6
|
||||
|
||||
@@End_8:
|
||||
popad
|
||||
ret
|
||||
|
||||
|
||||
|
||||
;***********************************************
|
||||
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
|
||||
;* НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ *
|
||||
;* Входные параметры передаются через *
|
||||
;* глобальные перменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале; *
|
||||
;* PacketCommand - 12-байтный командный пакет. *
|
||||
;***********************************************
|
||||
SendPacketNoDatCommand:
|
||||
pushad
|
||||
; Задать режим CHS
|
||||
mov [ATAAddressMode],0
|
||||
; Послать ATA-команду передачи пакетной команды
|
||||
mov [ATAFeatures],0
|
||||
mov [ATASectorCount],0
|
||||
mov [ATASectorNumber],0
|
||||
mov [ATACylinder],0
|
||||
mov [ATAHead],0
|
||||
mov [ATACommand],0A0h
|
||||
call SendCommandToHDD_1
|
||||
cmp [DevErrorCode],0 ;проверить код ошибки
|
||||
jne @@End_9 ;закончить, сохранив код ошибки
|
||||
; Ожидание готовности дисковода к приему
|
||||
; пакетной команды
|
||||
mov DX,[ATABasePortAddr]
|
||||
add DX,7 ;порт 1х7h
|
||||
@@WaitDevice0_1:
|
||||
call change_task
|
||||
; Проверить время ожидания
|
||||
mov EAX,[timer_ticks]
|
||||
sub EAX,[TickCounter_1]
|
||||
cmp EAX,BSYWaitTime
|
||||
ja @@Err1_3 ;ошибка тайм-аута
|
||||
; Проверить готовность
|
||||
in AL,DX
|
||||
test AL,80h ;состояние сигнала BSY
|
||||
jnz @@WaitDevice0_1
|
||||
test AL,1 ;состояние сигнала ERR
|
||||
jnz @@Err6_1
|
||||
test AL,08h ;состояние сигнала DRQ
|
||||
jz @@WaitDevice0_1
|
||||
; Послать пакетную команду
|
||||
; cli
|
||||
mov DX,[ATABasePortAddr]
|
||||
mov AX,word [PacketCommand]
|
||||
out DX,AX
|
||||
mov AX,word [PacketCommand+2]
|
||||
out DX,AX
|
||||
mov AX,word [PacketCommand+4]
|
||||
out DX,AX
|
||||
mov AX,word [PacketCommand+6]
|
||||
out DX,AX
|
||||
mov AX,word [PacketCommand+8]
|
||||
out DX,AX
|
||||
mov AX,word [PacketCommand+10]
|
||||
out DX,AX
|
||||
; sti
|
||||
; Ожидание подтверждения приема команды
|
||||
mov DX,[ATABasePortAddr]
|
||||
add DX,7 ;порт 1х7h
|
||||
@@WaitDevice1_1:
|
||||
call change_task
|
||||
; Проверить время выполнения команды
|
||||
mov EAX,[timer_ticks]
|
||||
sub EAX,[TickCounter_1]
|
||||
cmp EAX,MaxCDWaitTime
|
||||
ja @@Err1_3 ;ошибка тайм-аута
|
||||
; Ожидать освобождения устройства
|
||||
in AL,DX
|
||||
test AL,80h ;состояние сигнала BSY
|
||||
jnz @@WaitDevice1_1
|
||||
test AL,1 ;состояние сигнала ERR
|
||||
jnz @@Err6_1
|
||||
test AL,40h ;состояние сигнала DRDY
|
||||
jz @@WaitDevice1_1
|
||||
jmp @@End_9
|
||||
|
||||
; Записать код ошибки
|
||||
@@Err1_3:
|
||||
mov [DevErrorCode],1
|
||||
jmp @@End_9
|
||||
@@Err6_1:
|
||||
mov [DevErrorCode],6
|
||||
@@End_9:
|
||||
popad
|
||||
ret
|
||||
|
||||
;****************************************************
|
||||
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* переменные: *
|
||||
;* ChannelNumber - номер канала (1 или 2); *
|
||||
;* DiskNumber - номер диска (0 или 1); *
|
||||
;* ATAFeatures - "особенности"; *
|
||||
;* ATASectorCount - количество секторов; *
|
||||
;* ATASectorNumber - номер начального сектора; *
|
||||
;* ATACylinder - номер начального цилиндра; *
|
||||
;* ATAHead - номер начальной головки; *
|
||||
;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); *
|
||||
;* ATACommand - код команды. *
|
||||
;* После успешного выполнения функции: *
|
||||
;* в ATABasePortAddr - базовый адрес HDD; *
|
||||
;* в DevErrorCode - ноль. *
|
||||
;* При возникновении ошибки в DevErrorCode будет *
|
||||
;* возвращен код ошибки. *
|
||||
;****************************************************
|
||||
SendCommandToHDD_1:
|
||||
pushad
|
||||
; Проверить значение кода режима
|
||||
cmp [ATAAddressMode],1
|
||||
ja @@Err2_4
|
||||
; Проверить корректность номера канала
|
||||
mov BX,[ChannelNumber]
|
||||
cmp BX,1
|
||||
jb @@Err3_4
|
||||
cmp BX,2
|
||||
ja @@Err3_4
|
||||
; Установить базовый адрес
|
||||
dec BX
|
||||
shl BX,1
|
||||
movzx ebx,bx
|
||||
mov AX,[ebx+StandardATABases]
|
||||
mov [ATABasePortAddr],AX
|
||||
; Ожидание готовности HDD к приему команды
|
||||
; Выбрать нужный диск
|
||||
mov DX,[ATABasePortAddr]
|
||||
add DX,6 ;адрес регистра головок
|
||||
mov AL,[DiskNumber]
|
||||
cmp AL,1 ;проверить номера диска
|
||||
ja @@Err4_4
|
||||
shl AL,4
|
||||
or AL,10100000b
|
||||
out DX,AL
|
||||
; Ожидать, пока диск не будет готов
|
||||
inc DX
|
||||
; mov ecx,0xfff
|
||||
mov eax,[timer_ticks]
|
||||
mov [TickCounter_1],eax
|
||||
@@WaitHDReady_2:
|
||||
call change_task
|
||||
; Проверить время ожидания
|
||||
; dec ecx
|
||||
; cmp ecx,0
|
||||
; je @@Err1
|
||||
mov eax,[timer_ticks]
|
||||
sub eax,[TickCounter_1]
|
||||
cmp eax,BSYWaitTime ;300 ;ожидать 3 сек.
|
||||
ja @@Err1_4 ;ошибка тайм-аута
|
||||
; Прочитать регистр состояния
|
||||
in AL,DX
|
||||
; Проверить состояние сигнала BSY
|
||||
test AL,80h
|
||||
jnz @@WaitHDReady_2
|
||||
; Проверить состояние сигнала DRQ
|
||||
test AL,08h
|
||||
jnz @@WaitHDReady_2
|
||||
; Загрузить команду в регистры контроллера
|
||||
cli
|
||||
mov DX,[ATABasePortAddr]
|
||||
inc DX ;регистр "особенностей"
|
||||
mov AL,[ATAFeatures]
|
||||
out DX,AL
|
||||
inc DX ;счетчик секторов
|
||||
mov AL,[ATASectorCount]
|
||||
out DX,AL
|
||||
inc DX ;регистр номера сектора
|
||||
mov AL,[ATASectorNumber]
|
||||
out DX,AL
|
||||
inc DX ;номер цилиндра (младший байт)
|
||||
mov AX,[ATACylinder]
|
||||
out DX,AL
|
||||
inc DX ;номер цилиндра (старший байт)
|
||||
mov AL,AH
|
||||
out DX,AL
|
||||
inc DX ;номер головки/номер диска
|
||||
mov AL,[DiskNumber]
|
||||
shl AL,4
|
||||
cmp [ATAHead],0Fh ;проверить номер головки
|
||||
ja @@Err5_4
|
||||
or AL,[ATAHead]
|
||||
or AL,10100000b
|
||||
mov AH,[ATAAddressMode]
|
||||
shl AH,6
|
||||
or AL,AH
|
||||
out DX,AL
|
||||
; Послать команду
|
||||
mov AL,[ATACommand]
|
||||
inc DX ;регистр команд
|
||||
out DX,AL
|
||||
sti
|
||||
; Сбросить признак ошибки
|
||||
mov [DevErrorCode],0
|
||||
jmp @@End_10
|
||||
; Записать код ошибки
|
||||
@@Err1_4:
|
||||
mov [DevErrorCode],1
|
||||
jmp @@End_10
|
||||
@@Err2_4:
|
||||
mov [DevErrorCode],2
|
||||
jmp @@End_10
|
||||
@@Err3_4:
|
||||
mov [DevErrorCode],3
|
||||
jmp @@End_10
|
||||
@@Err4_4:
|
||||
mov [DevErrorCode],4
|
||||
jmp @@End_10
|
||||
@@Err5_4:
|
||||
mov [DevErrorCode],5
|
||||
; Завершение работы программы
|
||||
@@End_10:
|
||||
sti
|
||||
popad
|
||||
ret
|
||||
|
||||
;*************************************************
|
||||
;* ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* перменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале. *
|
||||
;*************************************************
|
||||
WaitUnitReady:
|
||||
pusha
|
||||
; Запомнить время начала операции
|
||||
mov EAX,[timer_ticks]
|
||||
mov [WURStartTime],EAX
|
||||
; Очистить буфер пакетной команды
|
||||
call clear_packet_buffer
|
||||
; Сформировать команду TEST UNIT READY
|
||||
mov [PacketCommand],word 00h
|
||||
; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА
|
||||
@@SendCommand:
|
||||
; Подать команду проверки готовности
|
||||
call SendPacketNoDatCommand
|
||||
call change_task
|
||||
; Проверить код ошибки
|
||||
cmp [DevErrorCode],0
|
||||
je @@End_11
|
||||
; Проверить время ожидания готовности
|
||||
mov EAX,[timer_ticks]
|
||||
sub EAX,[WURStartTime]
|
||||
cmp EAX,MaxCDWaitTime
|
||||
jb @@SendCommand
|
||||
; Ошибка тайм-аута
|
||||
mov [DevErrorCode],1
|
||||
@@End_11:
|
||||
popa
|
||||
ret
|
||||
|
||||
|
||||
;*************************************************
|
||||
;* ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* перменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале. *
|
||||
;*************************************************
|
||||
LoadMedium:
|
||||
pusha
|
||||
; Очистить буфер пакетной команды
|
||||
call clear_packet_buffer
|
||||
; Сформировать команду START/STOP UNIT
|
||||
; Задать код команды
|
||||
mov [PacketCommand],word 1Bh
|
||||
; Задать операцию загрузки носителя
|
||||
mov [PacketCommand+4],word 00000011b
|
||||
; Подать команду
|
||||
call SendPacketNoDatCommand
|
||||
popa
|
||||
ret
|
||||
|
||||
;*************************************************
|
||||
;* ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* перменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале. *
|
||||
;*************************************************
|
||||
UnloadMedium:
|
||||
pusha
|
||||
; Очистить буфер пакетной команды
|
||||
call clear_packet_buffer
|
||||
; Сформировать команду START/STOP UNIT
|
||||
; Задать код команды
|
||||
mov [PacketCommand],word 1Bh
|
||||
; Задать операцию извлечения носителя
|
||||
mov [PacketCommand+4],word 00000010b
|
||||
; Подать команду
|
||||
call SendPacketNoDatCommand
|
||||
popa
|
||||
ret
|
||||
|
||||
;*************************************************
|
||||
;* ОПРЕДЕЛИТЬ ОБЩЕЕ КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ *
|
||||
;* Входные параметры передаются через глобальные *
|
||||
;* переменные: *
|
||||
;* ChannelNumber - номер канала; *
|
||||
;* DiskNumber - номер диска на канале. *
|
||||
;*************************************************
|
||||
ReadCapacity:
|
||||
pusha
|
||||
; Очистить буфер пакетной команды
|
||||
call clear_packet_buffer
|
||||
; Задать размер буфера в байтах
|
||||
mov [CDBlockSize],8
|
||||
; Сформировать команду READ CAPACITY
|
||||
mov [PacketCommand],word 25h
|
||||
; Подать команду
|
||||
call SendPacketDatCommand
|
||||
popa
|
||||
ret
|
||||
|
||||
clear_packet_buffer:
|
||||
; Очистить буфер пакетной команды
|
||||
mov [PacketCommand],dword 0
|
||||
mov [PacketCommand+4],dword 0
|
||||
mov [PacketCommand+8],dword 0
|
||||
ret
|
||||
|
@ -28,8 +28,23 @@ rootdirs:
|
||||
db 3,'hd3'
|
||||
dd fs_OnHd3
|
||||
dd fs_NextHd3
|
||||
;**********************************************
|
||||
db 3,'cd0'
|
||||
dd fs_OnCd0
|
||||
dd fs_NextCd
|
||||
db 3,'cd1'
|
||||
dd fs_OnCd1
|
||||
dd fs_NextCd
|
||||
db 3,'cd2'
|
||||
dd fs_OnCd2
|
||||
dd fs_NextCd
|
||||
db 3,'cd3'
|
||||
dd fs_OnCd3
|
||||
dd fs_NextCd
|
||||
;***********************************************
|
||||
db 0
|
||||
|
||||
|
||||
virtual_root_query:
|
||||
dd fs_HasRamdisk
|
||||
db 'rd',0
|
||||
@ -43,6 +58,16 @@ virtual_root_query:
|
||||
db 'hd2',0
|
||||
dd fs_HasHd3
|
||||
db 'hd3',0
|
||||
;**********************************************
|
||||
dd fs_HasCd0
|
||||
db 'cd0',0
|
||||
dd fs_HasCd1
|
||||
db 'cd1',0
|
||||
dd fs_HasCd2
|
||||
db 'cd2',0
|
||||
dd fs_HasCd3
|
||||
db 'cd3',0
|
||||
;**********************************************
|
||||
dd 0
|
||||
endg
|
||||
|
||||
@ -420,6 +445,71 @@ fs_HdServices:
|
||||
dd fs_HdSetFileInfo
|
||||
fs_NumHdServices = ($ - fs_HdServices)/4
|
||||
|
||||
;*******************************************************
|
||||
fs_OnCd0:
|
||||
call reserve_cd
|
||||
mov [ChannelNumber],1
|
||||
mov [DiskNumber],0
|
||||
push 6
|
||||
jmp fs_OnCd
|
||||
fs_OnCd1:
|
||||
call reserve_cd
|
||||
mov [ChannelNumber],1
|
||||
mov [DiskNumber],1
|
||||
push 4
|
||||
jmp fs_OnCd
|
||||
fs_OnCd2:
|
||||
call reserve_cd
|
||||
mov [ChannelNumber],2
|
||||
mov [DiskNumber],0
|
||||
push 2
|
||||
jmp fs_OnCd
|
||||
fs_OnCd3:
|
||||
call reserve_cd
|
||||
mov [ChannelNumber],2
|
||||
mov [DiskNumber],1
|
||||
push 0
|
||||
fs_OnCd:
|
||||
|
||||
pop eax
|
||||
mov [hdpos], eax
|
||||
cmp ecx, 0x100
|
||||
jae .nf
|
||||
push cx bx
|
||||
mov cl,al
|
||||
mov bl,[0x40001]
|
||||
shr bl,cl
|
||||
test bl,2
|
||||
pop bx cx
|
||||
|
||||
jnz @f
|
||||
.nf:
|
||||
and [cd_status], 0
|
||||
mov dword [esp+36], 5 ; not found
|
||||
ret
|
||||
@@:
|
||||
mov ecx, [ebx+12]
|
||||
mov edx, [ebx+16]
|
||||
add edx, std_application_base_address
|
||||
mov eax, [ebx]
|
||||
cmp eax, 1
|
||||
ja .not_impl
|
||||
add ebx, 4
|
||||
call dword [fs_CdServices + eax*4]
|
||||
and [cd_status], 0
|
||||
mov [esp+36], eax
|
||||
mov [esp+24], ebx
|
||||
ret
|
||||
.not_impl:
|
||||
and [hd1_status], 0
|
||||
mov dword [esp+36], 2 ; not implemented
|
||||
ret
|
||||
|
||||
fs_CdServices:
|
||||
dd fs_CdRead
|
||||
dd fs_CdReadFolder
|
||||
;*******************************************************
|
||||
|
||||
fs_HasRamdisk:
|
||||
mov al, 1 ; we always have ramdisk
|
||||
ret
|
||||
@ -454,6 +544,33 @@ fs_HasHd3:
|
||||
setz al
|
||||
ret
|
||||
|
||||
;*******************************************************
|
||||
fs_HasCd0:
|
||||
mov al, [0x40001]
|
||||
and al, 11000000b
|
||||
cmp al, 10000000b
|
||||
setz al
|
||||
ret
|
||||
fs_HasCd1:
|
||||
mov al, [0x40001]
|
||||
and al, 00110000b
|
||||
cmp al, 00100000b
|
||||
setz al
|
||||
ret
|
||||
fs_HasCd2:
|
||||
mov al, [0x40001]
|
||||
and al, 00001100b
|
||||
cmp al, 00001000b
|
||||
setz al
|
||||
ret
|
||||
fs_HasCd3:
|
||||
mov al, [0x40001]
|
||||
and al, 00000011b
|
||||
cmp al, 00000010b
|
||||
setz al
|
||||
ret
|
||||
;*******************************************************
|
||||
|
||||
; fs_NextXXX functions:
|
||||
; in: eax = partition number, from which start to scan
|
||||
; out: CF=1 => no more partitions
|
||||
@ -509,3 +626,16 @@ fs_NextHd:
|
||||
inc eax
|
||||
clc
|
||||
ret
|
||||
|
||||
;*******************************************************
|
||||
fs_NextCd:
|
||||
; we always have /cdX/1
|
||||
test eax, eax
|
||||
stc
|
||||
jnz @f
|
||||
mov al, 1
|
||||
clc
|
||||
@@:
|
||||
ret
|
||||
;*******************************************************
|
||||
|
||||
|
631
kernel/trunk/fs/iso9660.inc
Normal file
631
kernel/trunk/fs/iso9660.inc
Normal file
@ -0,0 +1,631 @@
|
||||
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
|
||||
endg
|
||||
|
||||
CDDataBuf equ 0x7000
|
||||
|
||||
reserve_cd:
|
||||
|
||||
cli
|
||||
cmp [cd_status],0
|
||||
je reserve_ok2
|
||||
|
||||
sti
|
||||
call change_task
|
||||
jmp reserve_hd1
|
||||
|
||||
reserve_ok2:
|
||||
|
||||
push eax
|
||||
mov eax,[0x3000]
|
||||
shl eax,5
|
||||
mov eax,[eax+0x3000+4]
|
||||
mov [cd_status],eax
|
||||
pop eax
|
||||
sti
|
||||
ret
|
||||
|
||||
cd_status dd 0
|
||||
|
||||
;----------------------------------------------------------------
|
||||
;
|
||||
; fs_CdRead - LFN variant for reading CD disk
|
||||
;
|
||||
; esi points to filename /dir1/dir2/.../dirn/file,0
|
||||
; ebx pointer to 64-bit number = first wanted byte, 0+
|
||||
; may be ebx=0 - start from first byte
|
||||
; ecx number of bytes to read, 0+
|
||||
; edx mem location to return data
|
||||
;
|
||||
; 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] ; ðåàëüíûé ðàçìåð ôàéëîâîé ñåêöèè
|
||||
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 .new_sector
|
||||
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 ; ÷èòàåì ñåêòîð ôàéëà
|
||||
cmp [DevErrorCode],0
|
||||
jne .noaccess_3
|
||||
inc dword [CDSectorAddress]
|
||||
add edx, 2048
|
||||
sub ecx, 2048
|
||||
jmp .new_sector
|
||||
.incomplete_sector:
|
||||
; we must read and memmove incomplete sector
|
||||
mov [CDDataBuf_pointer],CDDataBuf
|
||||
call ReadCDWRetr ; ÷èòàåì ñåêòîð ôàéëà
|
||||
cmp [DevErrorCode],0
|
||||
jne .noaccess_3
|
||||
inc dword [CDSectorAddress]
|
||||
mov eax,CDDataBuf
|
||||
add eax, ebx
|
||||
push ecx
|
||||
add ecx, ebx
|
||||
cmp ecx, 2048
|
||||
jbe @f
|
||||
mov ecx, 2048
|
||||
@@:
|
||||
sub ecx, ebx
|
||||
push edi esi ecx
|
||||
mov edi,edx
|
||||
mov esi,eax ;0x7000 ; CD data buffer
|
||||
cld
|
||||
rep movsb
|
||||
pop ecx esi edi
|
||||
add edx, ecx
|
||||
sub [esp], ecx
|
||||
pop ecx
|
||||
xor ebx, ebx
|
||||
jmp .new_sector
|
||||
|
||||
.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
|
||||
;
|
||||
; esi points to filename /dir1/dir2/.../dirn/file,0
|
||||
; ebx pointer to structure 32-bit number = first wanted block, 0+
|
||||
; & flags (bitfields)
|
||||
; flags: bit 0: 0=ANSI names, 1=UNICODE names
|
||||
; ecx number of blocks to read, 0+
|
||||
; edx mem location to return data
|
||||
;
|
||||
; 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] ; ðàçìåð äèðåêòðîðèè
|
||||
.doit:
|
||||
; init header
|
||||
push eax ecx
|
||||
mov edi, edx
|
||||
mov ecx, 32/4
|
||||
xor eax, eax
|
||||
rep stosd
|
||||
pop ecx eax
|
||||
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 ; ÷èòàåì ñåêòîð äèðåêòîðèè
|
||||
cmp [DevErrorCode],0
|
||||
jne .noaccess_1
|
||||
call .get_names_from_buffer
|
||||
sub eax,2048
|
||||
; äèðåêòîðèÿ çàêîí÷èëàñü?
|
||||
cmp eax,0
|
||||
jg .read_to_buffer
|
||||
mov edi,[cd_counter_block]
|
||||
mov [edx+8],edi
|
||||
mov edi,[ebx]
|
||||
sub [edx+4],edi
|
||||
pop ecx edi
|
||||
xor ebx,ebx
|
||||
mov eax,ERROR_SUCCESS
|
||||
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
|
||||
mov esi,ebp
|
||||
mov edi,[cd_mem_location]
|
||||
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
|
||||
call uni2ansi_char
|
||||
cld
|
||||
stosb
|
||||
; ïðîâåðêà êîíöà ôàéëà
|
||||
mov al,[esi+1]
|
||||
cmp al,byte 3Bh ; ñåïàðàòîð êîíöà ôàéëà ';'
|
||||
je .cd_get_parameters_of_file_1
|
||||
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
|
||||
movzx eax,byte [ebp-33]
|
||||
add eax,ebp
|
||||
sub eax,34
|
||||
cmp esi,eax
|
||||
je .cd_get_parameters_of_file_1
|
||||
; ïðîâåðêà êîíöà ïàïêè
|
||||
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
|
||||
; ïðîâåðêà êîíöà ôàéëà
|
||||
mov ax,[esi]
|
||||
cmp ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
|
||||
je .cd_get_parameters_of_file_2
|
||||
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
|
||||
movzx eax,byte [ebp-33]
|
||||
add eax,ebp
|
||||
sub eax,34
|
||||
cmp esi,eax
|
||||
je .cd_get_parameters_of_file_2
|
||||
; ïðîâåðêà êîíöà ïàïêè
|
||||
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
|
||||
|
||||
.cd_get_parameters_of_file:
|
||||
mov edi,[cd_mem_location]
|
||||
; ïîëó÷àåì àòðèáóòû ôàéëà
|
||||
xor eax,eax
|
||||
; ôàéë íå àðõèâèðîâàëñÿ
|
||||
inc al
|
||||
shl eax,1
|
||||
; ýòî êàòàëîã?
|
||||
test [ebp-8],byte 2
|
||||
jz .file
|
||||
inc al
|
||||
.file:
|
||||
; ìåòêà òîìà íå êàê â FAT, â ýòîì âèäå îòñóòñâóåò
|
||||
; ôàéë íå ÿâëÿåòñÿ ñèñòåìíûì
|
||||
shl eax,3
|
||||
; ôàéë ÿâëÿåòñÿ ñêðûòûì? (àòðèáóò ñóùåñòâîâàíèå)
|
||||
test [ebp-8],byte 1
|
||||
jz .hidden
|
||||
inc al
|
||||
.hidden:
|
||||
shl eax,1
|
||||
; ôàéë âñåãäà òîëüêî äëÿ ÷òåíèÿ, òàê êàê ýòî CD
|
||||
inc al
|
||||
mov [edi],eax
|
||||
; ïîëó÷àåì âðåìÿ äëÿ ôàéëà
|
||||
;÷àñ
|
||||
movzx eax,byte [ebp-12]
|
||||
shl eax,8
|
||||
;ìèíóòà
|
||||
mov al,[ebp-11]
|
||||
shl eax,8
|
||||
;ñåêóíäà
|
||||
mov al,[ebp-10]
|
||||
;âðåìÿ ñîçäàíèÿ ôàéëà
|
||||
mov [edi+8],eax
|
||||
;âðåìÿ ïîñëåäíåãî äîñòóïà
|
||||
mov [edi+16],eax
|
||||
;âðåìÿ ïîñëåäíåé çàïèñè
|
||||
mov [edi+24],eax
|
||||
; ïîëó÷àåì äàòó äëÿ ôàéëà
|
||||
;ãîä
|
||||
movzx eax,byte [ebp-15]
|
||||
add eax,1900
|
||||
shl eax,8
|
||||
;ìåñÿö
|
||||
mov al,[ebp-14]
|
||||
shl eax,8
|
||||
;äåíü
|
||||
mov al,[ebp-13]
|
||||
;äàòà ñîçäàíèÿ ôàéëà
|
||||
mov [edi+12],eax
|
||||
;âðåìÿ ïîñëåäíåãî äîñòóïà
|
||||
mov [edi+20],eax
|
||||
;âðåìÿ ïîñëåäíåé çàïèñè
|
||||
mov [edi+28],eax
|
||||
; ïîëó÷àåì òèï äàííûõ èìåíè
|
||||
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
|
||||
@@:
|
||||
; ïîëó÷àåì ðàçìåð ôàéëà â áàéòàõ
|
||||
xor eax,eax
|
||||
mov [edi+32+4],eax
|
||||
mov eax,[ebp-23]
|
||||
mov [edi+32],eax
|
||||
ret
|
||||
|
||||
.end_buffer:
|
||||
pop edx edi esi eax
|
||||
ret
|
||||
|
||||
cd_find_lfn:
|
||||
; in: esi->name
|
||||
; out: CF=1 - file not found
|
||||
; else CF=0 and [cd_current_pointer_of_input] direntry
|
||||
push eax esi
|
||||
; 16 ñåêòîð íà÷àëî íàáîðà äåñêðèïòîðîâ òîìîâ
|
||||
mov [CDSectorAddress],dword 15
|
||||
.start:
|
||||
inc dword [CDSectorAddress]
|
||||
mov [CDDataBuf_pointer],CDDataBuf
|
||||
call ReadCDWRetr
|
||||
cmp [DevErrorCode],0
|
||||
jne .access_denied
|
||||
; ïðîâåðêà íà âøèâîñòü
|
||||
cmp [CDDataBuf+1],dword 'CD00'
|
||||
jne .access_denied
|
||||
cmp [CDDataBuf+5],byte '1'
|
||||
jne .access_denied
|
||||
; ñåêòîð ÿâëÿåòñÿ òåðìèíàòîðîì íàáîð äåñêðèïòîðîâ òîìîâ?
|
||||
cmp [CDDataBuf],byte 0xff
|
||||
je .access_denied
|
||||
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì è óëó÷øåííûì äåñêðèïòîðîì òîìà?
|
||||
cmp [CDDataBuf],byte 0x2
|
||||
jne .start
|
||||
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì äåñêðèïòîðîì òîìà?
|
||||
cmp [CDDataBuf+6],byte 0x1
|
||||
jne .start
|
||||
; ïàðàìåòðû root äèðåêòðîðèè
|
||||
mov eax,[CDDataBuf+0x9c+2] ; íà÷àëî root äèðåêòðîðèè
|
||||
mov [CDSectorAddress],eax
|
||||
mov eax,[CDDataBuf+0x9c+10] ; ðàçìåð root äèðåêòðîðèè
|
||||
cmp byte [esi], 0
|
||||
jnz @f
|
||||
mov [cd_current_pointer_of_input],CDDataBuf+0x9c
|
||||
jmp .done
|
||||
@@:
|
||||
; íà÷èíàåì ïîèñê
|
||||
.mainloop:
|
||||
dec dword [CDSectorAddress]
|
||||
.read_to_buffer:
|
||||
inc dword [CDSectorAddress]
|
||||
mov [CDDataBuf_pointer],CDDataBuf
|
||||
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè
|
||||
cmp [DevErrorCode],0
|
||||
jne .access_denied
|
||||
call cd_find_name_in_buffer
|
||||
jnc .found
|
||||
sub eax,2048
|
||||
; äèðåêòîðèÿ çàêîí÷èëàñü?
|
||||
cmp eax,0
|
||||
jg .read_to_buffer
|
||||
; íåò èñêîìîãî ýëåìåíòà öåïî÷êè
|
||||
.access_denied:
|
||||
pop esi eax
|
||||
stc
|
||||
ret
|
||||
; èñêîìûé ýëåìåíò öåïî÷êè íàéäåí
|
||||
.found:
|
||||
; êîíåö ïóòè ôàéëà
|
||||
cmp byte [esi], 0
|
||||
jz .done
|
||||
mov eax,[cd_current_pointer_of_input]
|
||||
add eax,2
|
||||
mov eax,[eax]
|
||||
mov [CDSectorAddress],eax ; íà÷àëî äèðåêòîðèè
|
||||
add eax,8
|
||||
mov eax,[eax] ; ðàçìåð äèðåêòîðèè
|
||||
jmp .mainloop
|
||||
; óêàçàòåëü ôàéëà íàéäåí
|
||||
.done:
|
||||
pop esi eax
|
||||
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]
|
||||
cmp eax,0 ; âõîäû çàêîí÷èëèñü?
|
||||
je .next_sector
|
||||
cmp ebp,CDDataBuf+2048 ; áóôåð çàêîí÷èëñÿ?
|
||||
jae .next_sector
|
||||
movzx eax, byte [ebp]
|
||||
add [cd_current_pointer_of_input_2],eax ; ñëåäóþùèé âõîä êàòàëîãà
|
||||
add ebp,33 ; óêàçàòåëü óñòàíîâëåí íà íà÷àëî èìåíè
|
||||
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
|
||||
; out: if names match: ZF=1 and esi->next component of name
|
||||
; else: ZF=0, esi is not changed
|
||||
; destroys eax
|
||||
push esi eax edi
|
||||
mov edi,ebp
|
||||
.loop:
|
||||
cld
|
||||
lodsb
|
||||
push ax
|
||||
call char_toupper
|
||||
call ansi2uni_char
|
||||
xchg ah,al
|
||||
cld
|
||||
scasw
|
||||
pop ax
|
||||
je .coincides
|
||||
call char_todown
|
||||
call ansi2uni_char
|
||||
xchg ah,al
|
||||
cld
|
||||
sub edi,2
|
||||
scasw
|
||||
jne .name_not_coincide
|
||||
.coincides:
|
||||
cmp [esi],byte '/' ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
|
||||
je .done
|
||||
cmp [esi],byte 0 ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
|
||||
je .done
|
||||
jmp .loop
|
||||
.name_not_coincide:
|
||||
pop edi eax esi
|
||||
stc
|
||||
ret
|
||||
.done:
|
||||
; ïðîâåðêà êîíöà ôàéëà
|
||||
cmp [edi],word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
|
||||
je .done_1
|
||||
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
|
||||
movzx eax,byte [ebp-33]
|
||||
add eax,ebp
|
||||
sub eax,34
|
||||
cmp edi,eax
|
||||
je .done_1
|
||||
; ïðîâåðêà êîíöà ïàïêè
|
||||
movzx eax,byte [ebp-1]
|
||||
add eax,ebp
|
||||
cmp edi,eax
|
||||
jne .name_not_coincide
|
||||
.done_1:
|
||||
pop edi eax
|
||||
add esp,4
|
||||
inc esi
|
||||
clc
|
||||
ret
|
||||
|
||||
char_todown:
|
||||
; convert character to uppercase, using cp866 encoding
|
||||
; in: al=symbol
|
||||
; out: al=converted symbol
|
||||
cmp al, 'A'
|
||||
jb .ret
|
||||
cmp al, 'Z'
|
||||
jbe .az
|
||||
cmp al, '€'
|
||||
jb .ret
|
||||
cmp al, '<27>'
|
||||
jb .rus1
|
||||
cmp al, 'Ÿ'
|
||||
ja .ret
|
||||
; 0x90-0x9F -> 0xE0-0xEF
|
||||
add al, 'à'-'<27>'
|
||||
.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
|
||||
; 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, 'ð'
|
||||
jmp .doit
|
||||
.yo2:
|
||||
mov al, 'ñ'
|
||||
jmp .doit
|
||||
.rus1:
|
||||
; 0x410-0x43F -> 0x80-0xAF
|
||||
add al, 0x70
|
||||
jmp .doit
|
||||
.rus2:
|
||||
; 0x440-0x44F -> 0xE0-0xEF
|
||||
add al, 0xA0
|
||||
.ascii:
|
||||
.doit:
|
||||
ret
|
@ -150,6 +150,7 @@ include "fs/fat32.inc" ; read / write for fat32 filesystem
|
||||
include "fs/fat12.inc" ; read / write for fat12 filesystem
|
||||
include "blkdev/rd.inc" ; ramdisk read /write
|
||||
include "fs/fs_lfn.inc" ; syscall, version 2
|
||||
include "fs/iso9660.inc" ; read for iso9660 filesystem CD
|
||||
|
||||
; sound
|
||||
|
||||
@ -186,6 +187,7 @@ include "blkdev/flp_drv.inc"
|
||||
; CD drive controller
|
||||
|
||||
include "blkdev/cdrom.inc"
|
||||
include "blkdev/cd_drv.inc"
|
||||
|
||||
; Character devices
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user