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'
|
db 3,'hd3'
|
||||||
dd fs_OnHd3
|
dd fs_OnHd3
|
||||||
dd fs_NextHd3
|
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
|
db 0
|
||||||
|
|
||||||
|
|
||||||
virtual_root_query:
|
virtual_root_query:
|
||||||
dd fs_HasRamdisk
|
dd fs_HasRamdisk
|
||||||
db 'rd',0
|
db 'rd',0
|
||||||
@ -43,6 +58,16 @@ virtual_root_query:
|
|||||||
db 'hd2',0
|
db 'hd2',0
|
||||||
dd fs_HasHd3
|
dd fs_HasHd3
|
||||||
db 'hd3',0
|
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
|
dd 0
|
||||||
endg
|
endg
|
||||||
|
|
||||||
@ -420,6 +445,71 @@ fs_HdServices:
|
|||||||
dd fs_HdSetFileInfo
|
dd fs_HdSetFileInfo
|
||||||
fs_NumHdServices = ($ - fs_HdServices)/4
|
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:
|
fs_HasRamdisk:
|
||||||
mov al, 1 ; we always have ramdisk
|
mov al, 1 ; we always have ramdisk
|
||||||
ret
|
ret
|
||||||
@ -454,6 +544,33 @@ fs_HasHd3:
|
|||||||
setz al
|
setz al
|
||||||
ret
|
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:
|
; fs_NextXXX functions:
|
||||||
; in: eax = partition number, from which start to scan
|
; in: eax = partition number, from which start to scan
|
||||||
; out: CF=1 => no more partitions
|
; out: CF=1 => no more partitions
|
||||||
@ -509,3 +626,16 @@ fs_NextHd:
|
|||||||
inc eax
|
inc eax
|
||||||
clc
|
clc
|
||||||
ret
|
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 "fs/fat12.inc" ; read / write for fat12 filesystem
|
||||||
include "blkdev/rd.inc" ; ramdisk read /write
|
include "blkdev/rd.inc" ; ramdisk read /write
|
||||||
include "fs/fs_lfn.inc" ; syscall, version 2
|
include "fs/fs_lfn.inc" ; syscall, version 2
|
||||||
|
include "fs/iso9660.inc" ; read for iso9660 filesystem CD
|
||||||
|
|
||||||
; sound
|
; sound
|
||||||
|
|
||||||
@ -186,6 +187,7 @@ include "blkdev/flp_drv.inc"
|
|||||||
; CD drive controller
|
; CD drive controller
|
||||||
|
|
||||||
include "blkdev/cdrom.inc"
|
include "blkdev/cdrom.inc"
|
||||||
|
include "blkdev/cd_drv.inc"
|
||||||
|
|
||||||
; Character devices
|
; Character devices
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user