kolibrios-fun/kernel/trunk/blkdev/cd_drv.inc
pathoswithin ee14b53b33 sysfunction 70 cleaning
git-svn-id: svn://kolibrios.org@6464 a494cfbc-eb01-0410-851d-a64ba20cac60
2016-07-29 11:12:13 +00:00

1226 lines
42 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
;-----------------------------------------------------------------------------
;**********************************************************
; Непосредственная работа с устройством СD (ATAPI)
;**********************************************************
; Автор части исходного текста Кулаков Владимир Геннадьевич
; Адаптация, доработка и разработка Mario79,<Lrz>
; Максимальное количество повторений операции чтения
MaxRetr equ 10
; Предельное время ожидания готовности к приему команды
; (в тиках)
BSYWaitTime equ 1000 ;2
NoTickWaitTime equ 0xfffff
CDBlockSize equ 2048
;********************************************
;* ЧТЕНИЕ СЕКТОРА С ПОВТОРАМИ *
;* Многократное повторение чтения при сбоях *
;********************************************
ReadCDWRetr:
;-----------------------------------------------------------
; input : eax = block to read
; ebx = destination
;-----------------------------------------------------------
pushad
mov eax, [CDSectorAddress]
mov ebx, [CDDataBuf_pointer]
call cd_calculate_cache
xor edi, edi
add esi, 8
inc edi
;--------------------------------------
align 4
.hdreadcache:
cmp [esi], eax ; correct sector
je .yeshdcache
add esi, 8
inc edi
dec ecx
jnz .hdreadcache
call find_empty_slot_CD_cache ; ret in edi
push edi
push eax
call cd_calculate_cache_2
shl edi, 11
add edi, eax
mov [CDDataBuf_pointer], edi
pop eax
pop edi
call ReadCDWRetr_1
cmp [DevErrorCode], 0
jne .exit
mov [CDDataBuf_pointer], ebx
call cd_calculate_cache_1
lea esi, [edi*8+esi]
mov [esi], eax ; sector number
;--------------------------------------
.yeshdcache:
mov esi, edi
shl esi, 11 ;9
push eax
call cd_calculate_cache_2
add esi, eax
pop eax
mov edi, ebx ;[CDDataBuf_pointer]
mov ecx, 512 ;/4
cld
rep movsd ; move data
;--------------------------------------
.exit:
popad
ret
;-----------------------------------------------------------------------------
ReadCDWRetr_1:
pushad
; Цикл, пока команда не выполнена успешно или не
; исчерпано количество попыток
mov ecx, MaxRetr
;--------------------------------------
align 4
@@NextRetr:
; Подать команду
;*************************************************
;* ПОЛНОЕ ЧТЕНИЕ СЕКТОРА КОМПАКТ-ДИСКА *
;* Считываются данные пользователя, информация *
;* субканала и контрольная информация *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале; *
;* CDSectorAddress - адрес считываемого сектора. *
;* Данные считывается в массив CDDataBuf. *
;*************************************************
;ReadCD:
push ecx
; Очистить буфер пакетной команды
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 [PacketCommand+8], byte 1
; Подать команду
call SendPacketDatCommand
pop ecx
test eax, eax
jz @@End_4
or ecx, ecx ;{SPraid.simba} (for cd load)
jz @@End_4
dec ecx
cmp [timer_ticks_enable], 0
jne @f
mov eax, NoTickWaitTime
;--------------------------------------
align 4
.wait:
dec eax
jz @@NextRetr
jmp .wait
;--------------------------------------
align 4
@@:
loop @@NextRetr
;--------------------------------------
@@End_4:
mov dword [DevErrorCode], eax
popad
ret
;-----------------------------------------------------------------------------
; Универсальные процедуры, обеспечивающие выполнение
; пакетных команд в режиме PIO
; Максимально допустимое время ожидания реакции
; устройства на пакетную команду (в тиках)
;-----------------------------------------------------------------------------
MaxCDWaitTime equ 1000 ;200 ;10 секунд
uglobal
; Область памяти для формирования пакетной команды
PacketCommand:
rb 12 ;DB 12 DUP (?)
; Адрес считываемого сектора данных
CDSectorAddress: dd ?
; Время начала очередной операции с диском
TickCounter_1 dd 0
; Время начала ожидания готовности устройства
WURStartTime dd 0
; указатель буфера для считывания
CDDataBuf_pointer dd 0
endg
;-----------------------------------------------------------------------------
;****************************************************
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ *
;* РАЗМЕРОМ 2048 БАЙТ ОТ УСТРОЙСТВА К ХОСТУ *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале; *
;* PacketCommand - 12-байтный командный пакет; *
;* CDBlockSize - размер принимаемого блока данных. *
; return eax DevErrorCode
;****************************************************
SendPacketDatCommand:
xor eax, eax
; Задать режим CHS
mov byte [ATAAddressMode], al
; Послать ATA-команду передачи пакетной команды
mov byte [ATAFeatures], al
mov byte [ATASectorCount], al
mov byte [ATASectorNumber], al
; Загрузить размер передаваемого блока
mov [ATAHead], al
mov [ATACylinder], CDBlockSize
mov [ATACommand], 0xA0
call SendCommandToHDD_1
test eax, eax
jnz @@End_8 ;закончить, сохранив код ошибки
; Ожидание готовности дисковода к приему
; пакетной команды
mov dx, [ATABasePortAddr]
add dx, 7 ;порт 1х7h
mov ecx, NoTickWaitTime
;--------------------------------------
align 4
@@WaitDevice0:
cmp [timer_ticks_enable], 0
jne @f
dec ecx
jz @@Err1_1
jmp .test
;--------------------------------------
align 4
@@:
call change_task
; Проверить время выполнения команды
mov eax, [timer_ticks]
sub eax, [TickCounter_1]
cmp eax, BSYWaitTime
ja @@Err1_1 ;ошибка тайм-аута
; Проверить готовность
;--------------------------------------
align 4
.test:
in al, dx
test al, 0x80 ;состояние сигнала BSY
jnz @@WaitDevice0
test al, 1 ;состояние сигнала ERR
jnz @@Err6
test al, 0x8 ;состояние сигнала 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
mov ecx, NoTickWaitTime
;--------------------------------------
align 4
@@WaitDevice1:
cmp [timer_ticks_enable], 0
jne @f
dec ecx
jz @@Err1_1
jmp .test_1
;--------------------------------------
align 4
@@:
call change_task
; Проверить время выполнения команды
mov eax, [timer_ticks]
sub eax, [TickCounter_1]
cmp eax, MaxCDWaitTime
ja @@Err1_1 ;ошибка тайм-аута
; Проверить готовность
;--------------------------------------
align 4
.test_1:
in al, dx
test al, 0x80 ;состояние сигнала BSY
jnz @@WaitDevice1
test al, 1 ;состояние сигнала ERR
jnz @@Err6_temp
test al, 0x8 ;состояние сигнала DRQ
jz @@WaitDevice1
; Принять блок данных от контроллера
mov edi, [CDDataBuf_pointer]
; Загрузить адрес регистра данных контроллера
mov dx, [ATABasePortAddr]
; Загрузить в счетчик размер блока в байтах
xor ecx, ecx
mov cx, CDBlockSize
; Вычислить размер блока в 16-разрядных словах
shr cx, 1 ;разделить размер блока на 2
; Принять блок данных
cli
cld
rep insw
sti
;--------------------------------------
; Успешное завершение приема данных
@@End_8:
xor eax, eax
ret
;--------------------------------------
; Записать код ошибки
@@Err1_1:
xor eax, eax
inc eax
ret
;--------------------------------------
@@Err6_temp:
mov eax, 7
ret
;--------------------------------------
@@Err6:
mov eax, 6
ret
;-----------------------------------------------------------------------------
;***********************************************
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
;* НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ *
;* Входные параметры передаются через *
;* глобальные перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале; *
;* PacketCommand - 12-байтный командный пакет. *
;***********************************************
SendPacketNoDatCommand:
pushad
xor eax, eax
; Задать режим CHS
mov byte [ATAAddressMode], al
; Послать ATA-команду передачи пакетной команды
mov byte [ATAFeatures], al
mov byte [ATASectorCount], al
mov byte [ATASectorNumber], al
mov word [ATACylinder], ax
mov byte [ATAHead], al
mov [ATACommand], 0xA0
call SendCommandToHDD_1
test eax, eax
jnz @@End_9 ;закончить, сохранив код ошибки
; Ожидание готовности дисковода к приему
; пакетной команды
mov dx, [ATABasePortAddr]
add dx, 7 ;порт 1х7h
;--------------------------------------
align 4
@@WaitDevice0_1:
call change_task
; Проверить время ожидания
mov eax, [timer_ticks]
sub eax, [TickCounter_1]
cmp eax, BSYWaitTime
ja @@Err1_3 ;ошибка тайм-аута
; Проверить готовность
in al, dx
test al, 0x80 ;состояние сигнала BSY
jnz @@WaitDevice0_1
test al, 1 ;состояние сигнала ERR
jnz @@Err6_1
test al, 0x8 ;состояние сигнала 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
cmp [ignore_CD_eject_wait], 1
je @@clear_DEC
; Ожидание подтверждения приема команды
mov dx, [ATABasePortAddr]
add dx, 7 ;порт 1х7h
;--------------------------------------
align 4
@@WaitDevice1_1:
call change_task
; Проверить время выполнения команды
mov eax, [timer_ticks]
sub eax, [TickCounter_1]
cmp eax, MaxCDWaitTime
ja @@Err1_3 ;ошибка тайм-аута
; Ожидать освобождения устройства
in al, dx
test al, 0x80 ;состояние сигнала BSY
jnz @@WaitDevice1_1
test al, 1 ;состояние сигнала ERR
jnz @@Err6_1
test al, 0x40 ;состояние сигнала DRDY
jz @@WaitDevice1_1
;--------------------------------------
@@clear_DEC:
and [DevErrorCode], 0
popad
ret
;--------------------------------------
; Записать код ошибки
@@Err1_3:
xor eax, eax
inc eax
jmp @@End_9
;--------------------------------------
@@Err6_1:
mov eax, 6
;--------------------------------------
@@End_9:
mov [DevErrorCode], eax
popad
ret
;-----------------------------------------------------------------------------
;****************************************************
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ *
;* Входные параметры передаются через глобальные *
;* переменные: *
;* ChannelNumber - номер канала (1 или 2); *
;* DiskNumber - номер диска (0 или 1); *
;* ATAFeatures - "особенности"; *
;* ATASectorCount - количество секторов; *
;* ATASectorNumber - номер начального сектора; *
;* ATACylinder - номер начального цилиндра; *
;* ATAHead - номер начальной головки; *
;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); *
;* ATACommand - код команды. *
;* После успешного выполнения функции: *
;* в ATABasePortAddr - базовый адрес HDD; *
;* в DevErrorCode - ноль. *
;* При возникновении ошибки в DevErrorCode будет *
;* возвращен код ошибки в eax *
;****************************************************
SendCommandToHDD_1:
; Проверить значение кода режима
cmp [ATAAddressMode], 1
ja @@Err2_4
; Проверить корректность номера канала
movzx ebx, [ChannelNumber]
dec ebx
cmp ebx, 1
ja @@Err3_4
; Установить базовый адрес
shl ebx, 2
mov eax, [cdpos]
dec eax
shr eax, 2
imul eax, sizeof.IDE_DATA
add eax, IDE_controller_1
add eax, ebx
mov ax, [eax+IDE_DATA.BAR0_val]
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 eax, [timer_ticks]
mov [TickCounter_1], eax
mov ecx, NoTickWaitTime
;--------------------------------------
align 4
@@WaitHDReady_2:
cmp [timer_ticks_enable], 0
jne @f
dec ecx
jz @@Err1_4
jmp .test
;--------------------------------------
align 4
@@:
call change_task
; Проверить время ожидания
mov eax, [timer_ticks]
sub eax, [TickCounter_1]
cmp eax, BSYWaitTime ;300 ;ожидать 3 сек.
ja @@Err1_4 ;ошибка тайм-аута
;--------------------------------------
align 4
.test:
in al, dx ; Прочитать регистр состояния
; Проверить состояние сигнала BSY
test al, 0x80
jnz @@WaitHDReady_2
; Проверить состояние сигнала DRQ
test al, 0x8
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], 0xF ;проверить номер головки
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
;--------------------------------------
@@End_10:
xor eax, eax
ret
;--------------------------------------
; Записать код ошибки
@@Err1_4:
xor eax, eax
inc eax
ret
;--------------------------------------
@@Err2_4:
mov eax, 2
ret
;--------------------------------------
@@Err3_4:
mov eax, 3
ret
;--------------------------------------
@@Err4_4:
mov eax, 4
ret
;--------------------------------------
@@Err5_4:
mov eax, 5
ret
;-----------------------------------------------------------------------------
;*************************************************
;* ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;*************************************************
WaitUnitReady:
pusha
; Запомнить время начала операции
mov eax, [timer_ticks]
mov [WURStartTime], eax
; Очистить буфер пакетной команды
call clear_packet_buffer
; Сформировать команду TEST UNIT READY
mov [PacketCommand], word 0
; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА
mov ecx, NoTickWaitTime
;--------------------------------------
align 4
@@SendCommand:
; Подать команду проверки готовности
call SendPacketNoDatCommand
cmp [timer_ticks_enable], 0
jne @f
cmp [DevErrorCode], 0
je @@End_11
dec ecx
jz .Error
jmp @@SendCommand
;--------------------------------------
align 4
@@:
call change_task
; Проверить код ошибки
cmp [DevErrorCode], 0
je @@End_11
; Проверить время ожидания готовности
mov eax, [timer_ticks]
sub eax, [WURStartTime]
cmp eax, MaxCDWaitTime
jb @@SendCommand
;--------------------------------------
.Error:
; Ошибка тайм-аута
mov [DevErrorCode], 1
;--------------------------------------
@@End_11:
popa
ret
;-----------------------------------------------------------------------------
;*************************************************
;* ЗАПРЕТИТЬ СМЕНУ ДИСКА *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;*************************************************
prevent_medium_removal:
pusha
; Очистить буфер пакетной команды
call clear_packet_buffer
; Задать код команды
mov [PacketCommand], byte 0x1E
; Задать код запрета
mov [PacketCommand+4], byte 11b
; Подать команду
call SendPacketNoDatCommand
mov eax, ATAPI_IDE0_lock
add eax, [cdpos]
dec eax
mov [eax], byte 1
popa
ret
;-----------------------------------------------------------------------------
;*************************************************
;* РАЗРЕШИТЬ СМЕНУ ДИСКА *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;*************************************************
allow_medium_removal:
pusha
; Очистить буфер пакетной команды
call clear_packet_buffer
; Задать код команды
mov [PacketCommand], byte 0x1E
; Задать код запрета
mov [PacketCommand+4], byte 0
; Подать команду
call SendPacketNoDatCommand
mov eax, ATAPI_IDE0_lock
add eax, [cdpos]
dec eax
mov [eax], byte 0
popa
ret
;-----------------------------------------------------------------------------
;*************************************************
;* ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;*************************************************
LoadMedium:
pusha
; Очистить буфер пакетной команды
call clear_packet_buffer
; Сформировать команду START/STOP UNIT
; Задать код команды
mov [PacketCommand], word 0x1B
; Задать операцию загрузки носителя
mov [PacketCommand+4], word 00000011b
; Подать команду
call SendPacketNoDatCommand
popa
ret
;-----------------------------------------------------------------------------
;*************************************************
;* ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;*************************************************
EjectMedium:
pusha
; Очистить буфер пакетной команды
call clear_packet_buffer
; Сформировать команду START/STOP UNIT
; Задать код команды
mov [PacketCommand], word 0x1B
; Задать операцию извлечения носителя
mov [PacketCommand+4], word 00000010b
; Подать команду
call SendPacketNoDatCommand
popa
ret
;-----------------------------------------------------------------------------
;*************************************************
;* Проверить событие нажатия кнопки извлечения *
;* диска *
;* Входные параметры передаются через глобальные *
;* переменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;*************************************************
proc check_ATAPI_device_event_has_work?
mov eax, [timer_ticks]
sub eax, [timer_ATAPI_check]
cmp eax, 100
jb .no
xor eax, eax
inc eax
ret
;--------------------------------------
.no:
xor eax, eax
ret
endp
;-----------------------------------------------------------------------------
align 4
check_ATAPI_device_event:
pusha
mov eax, [timer_ticks]
sub eax, [timer_ATAPI_check]
cmp eax, 100
jb .end_1
pushfd
mov al, [DRIVE_DATA+1]
and al, 11b
cmp al, 10b
jz .ide3
;--------------------------------------
.ide2_1:
mov al, [DRIVE_DATA+1]
and al, 1100b
cmp al, 1000b
jz .ide2
;--------------------------------------
.ide1_1:
mov al, [DRIVE_DATA+1]
and al, 110000b
cmp al, 100000b
jz .ide1
;--------------------------------------
.ide0_1:
mov al, [DRIVE_DATA+1]
and al, 11000000b
cmp al, 10000000b
jz .ide0
;--------------------------------------
.ide7_1:
mov al, [DRIVE_DATA+6]
and al, 11b
cmp al, 10b
jz .ide7
;--------------------------------------
.ide6_1:
mov al, [DRIVE_DATA+6]
and al, 1100b
cmp al, 1000b
jz .ide6
;--------------------------------------
.ide5_1:
mov al, [DRIVE_DATA+6]
and al, 110000b
cmp al, 100000b
jz .ide5
;--------------------------------------
.ide4_1:
mov al, [DRIVE_DATA+6]
and al, 11000000b
cmp al, 10000000b
jz .ide4
;--------------------------------------
.ide11_1:
mov al, [DRIVE_DATA+11]
and al, 11b
cmp al, 10b
jz .ide11
;--------------------------------------
.ide10_1:
mov al, [DRIVE_DATA+11]
and al, 1100b
cmp al, 1000b
jz .ide10
;--------------------------------------
.ide9_1:
mov al, [DRIVE_DATA+11]
and al, 110000b
cmp al, 100000b
jz .ide9
;--------------------------------------
.ide8_1:
mov al, [DRIVE_DATA+11]
and al, 11000000b
cmp al, 10000000b
jz .ide8
;--------------------------------------
.end:
popfd
mov eax, [timer_ticks]
mov [timer_ATAPI_check], eax
;--------------------------------------
.end_1:
popa
ret
;-----------------------------------------------------------------------------
.ide3:
cli
cmp [ATAPI_IDE3_lock], 1
jne .ide2_1
cmp [cd_status], 0
jne .end
mov ecx, ide_channel2_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 2
mov [DiskNumber], 1
mov [cdpos], 4
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide2_1
;-----------------------------------------------------------------------------
.ide2:
cli
cmp [ATAPI_IDE2_lock], 1
jne .ide1_1
cmp [cd_status], 0
jne .end
mov ecx, ide_channel2_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 2
mov [DiskNumber], 0
mov [cdpos], 3
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide1_1
;-----------------------------------------------------------------------------
.ide1:
cli
cmp [ATAPI_IDE1_lock], 1
jne .ide0_1
cmp [cd_status], 0
jne .end
mov ecx, ide_channel1_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 1
mov [DiskNumber], 1
mov [cdpos], 2
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide0_1
;-----------------------------------------------------------------------------
.ide0:
cli
cmp [ATAPI_IDE0_lock], 1
jne .ide7_1
cmp [cd_status], 0
jne .end
mov ecx, ide_channel1_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 1
mov [DiskNumber], 0
mov [cdpos], 1
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide7_1
;-----------------------------------------------------------------------------
.ide7:
cli
cmp [ATAPI_IDE7_lock], 1
jne .ide6_1
cmp [cd_status], 0
jne .end
mov ecx, ide_channel4_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 2
mov [DiskNumber], 1
mov [cdpos], 8
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide6_1
;-----------------------------------------------------------------------------
.ide6:
cli
cmp [ATAPI_IDE6_lock], 1
jne .ide5_1
cmp [cd_status], 0
jne .end
mov ecx, ide_channel4_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 2
mov [DiskNumber], 0
mov [cdpos], 7
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide5_1
;-----------------------------------------------------------------------------
.ide5:
cli
cmp [ATAPI_IDE5_lock], 1
jne .ide4_1
cmp [cd_status], 0
jne .end
mov ecx, ide_channel3_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 1
mov [DiskNumber], 1
mov [cdpos], 6
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide4_1
;-----------------------------------------------------------------------------
.ide4:
cli
cmp [ATAPI_IDE4_lock], 1
jne .ide11_1
cmp [cd_status], 0
jne .end
mov ecx, ide_channel3_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 1
mov [DiskNumber], 0
mov [cdpos], 5
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide11_1
;-----------------------------------------------------------------------------
.ide11:
cli
cmp [ATAPI_IDE11_lock], 1
jne .ide10_1
cmp [cd_status], 0
jne .end
mov ecx, ide_channel6_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 2
mov [DiskNumber], 1
mov [cdpos], 12
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide10_1
;-----------------------------------------------------------------------------
.ide10:
cli
cmp [ATAPI_IDE10_lock], 1
jne .ide9_1
cmp [cd_status], 0
jne .end
mov ecx, ide_channel6_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 2
mov [DiskNumber], 0
mov [cdpos], 11
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide9_1
;-----------------------------------------------------------------------------
.ide9:
cli
cmp [ATAPI_IDE9_lock], 1
jne .ide8_1
cmp [cd_status], 0
jne .end
mov ecx, ide_channel5_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 1
mov [DiskNumber], 1
mov [cdpos], 10
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .ide8_1
;-----------------------------------------------------------------------------
.ide8:
cli
cmp [ATAPI_IDE8_lock], 1
jne .end
cmp [cd_status], 0
jne .end
mov ecx, ide_channel5_mutex
call mutex_lock
call reserve_ok2
mov [ChannelNumber], 1
mov [DiskNumber], 0
mov [cdpos], 9
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
jne @f
call .eject
;--------------------------------------
@@:
call syscall_cdaudio.free
jmp .end
;-----------------------------------------------------------------------------
.eject:
call clear_CD_cache
call allow_medium_removal
mov [ignore_CD_eject_wait], 1
call EjectMedium
mov [ignore_CD_eject_wait], 0
ret
;-----------------------------------------------------------------------------
iglobal
timer_ATAPI_check dd 0
ATAPI_IDE0_lock db 0
ATAPI_IDE1_lock db 0
ATAPI_IDE2_lock db 0
ATAPI_IDE3_lock db 0
ATAPI_IDE4_lock db 0
ATAPI_IDE5_lock db 0
ATAPI_IDE6_lock db 0
ATAPI_IDE7_lock db 0
ATAPI_IDE8_lock db 0
ATAPI_IDE9_lock db 0
ATAPI_IDE10_lock db 0
ATAPI_IDE11_lock db 0
ignore_CD_eject_wait db 0
endg
;-----------------------------------------------------------------------------
;*************************************************
;* Получить сообщение о событии или состоянии *
;* устройства *
;* Входные параметры передаются через глобальные *
;* переменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;*************************************************
GetEvent_StatusNotification:
pusha
mov [CDDataBuf_pointer], CDDataBuf
; Очистить буфер пакетной команды
call clear_packet_buffer
; Задать код команды
mov [PacketCommand], byte 4Ah
mov [PacketCommand+1], byte 00000001b
; Задать запрос класса сообщений
mov [PacketCommand+4], byte 00010000b
; Размер выделенной области
mov [PacketCommand+7], byte 8h
mov [PacketCommand+8], byte 0h
; Подать команду
call SendPacketDatCommand
popa
ret
;-----------------------------------------------------------------------------
;*************************************************
; прочитать информацию из TOC
;* Входные параметры передаются через глобальные *
;* переменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;*************************************************
Read_TOC:
pusha
mov [CDDataBuf_pointer], CDDataBuf
; Очистить буфер пакетной команды
call clear_packet_buffer
; Сформировать пакетную команду для считывания
; сектора данных
mov [PacketCommand], byte 0x43
; Задать формат
mov [PacketCommand+2], byte 1
; Размер выделенной области
mov [PacketCommand+7], byte 0xFF
mov [PacketCommand+8], byte 0h
; Подать команду
call SendPacketDatCommand
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:
; Очистить буфер пакетной команды
and [PacketCommand], dword 0
and [PacketCommand+4], dword 0
and [PacketCommand+8], dword 0
ret
;-----------------------------------------------------------------------------