Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 3538 → Rev 3539

/kernel/trunk/blkdev/cd_drv.inc
9,21 → 9,21
 
 
;**********************************************************
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ óñòðîéñòâîì ÑD (ATAPI)
; Непосредственная работа с устройством СD (ATAPI)
;**********************************************************
; Àâòîð ÷àñòè èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷
; Àäàïòàöèÿ, äîðàáîòêà è ðàçðàáîòêà Mario79,<Lrz>
; Автор части исходного текста Кулаков Владимир Геннадьевич
; Адаптация, доработка и разработка Mario79,<Lrz>
 
; Ìàêñèìàëüíîå êîëè÷åñòâî ïîâòîðåíèé îïåðàöèè ÷òåíèÿ
; Максимальное количество повторений операции чтения
MaxRetr equ 10
; Ïðåäåëüíîå âðåìÿ îæèäàíèÿ ãîòîâíîñòè ê ïðèåìó êîìàíäû
; (â òèêàõ)
; Предельное время ожидания готовности к приему команды
; (в тиках)
BSYWaitTime equ 1000 ;2
NoTickWaitTime equ 0xfffff
CDBlockSize equ 2048
;********************************************
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ Ñ ÏÎÂÒÎÐÀÌÈ *
;* Ìíîãîêðàòíîå ïîâòîðåíèå ÷òåíèÿ ïðè ñáîÿõ *
;* ЧТЕНИЕ СЕКТОРА С ПОВТОРАМИ *
;* Многократное повторение чтения при сбоях *
;********************************************
ReadCDWRetr:
;-----------------------------------------------------------
85,34 → 85,34
ReadCDWRetr_1:
pushad
 
; Öèêë, ïîêà êîìàíäà íå âûïîëíåíà óñïåøíî èëè íå
; èñ÷åðïàíî êîëè÷åñòâî ïîïûòîê
; Цикл, пока команда не выполнена успешно или не
; исчерпано количество попыток
mov ECX, MaxRetr
@@NextRetr:
; Ïîäàòü êîìàíäó
; Подать команду
;*************************************************
;* ÏÎËÍÎÅ ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÊÎÌÏÀÊÒ-ÄÈÑÊÀ *
;* Ñ÷èòûâàþòñÿ äàííûå ïîëüçîâàòåëÿ, èíôîðìàöèÿ *
;* ñóáêàíàëà è êîíòðîëüíàÿ èíôîðìàöèÿ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå; *
;* CDSectorAddress - àäðåñ ñ÷èòûâàåìîãî ñåêòîðà. *
;* Äàííûå ñ÷èòûâàåòñÿ â ìàññèâ CDDataBuf. *
;* ПОЛНОЕ ЧТЕНИЕ СЕКТОРА КОМПАКТ-ДИСКА *
;* Считываются данные пользователя, информация *
;* субканала и контрольная информация *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале; *
;* CDSectorAddress - адрес считываемого сектора. *
;* Данные считывается в массив CDDataBuf. *
;*************************************************
;ReadCD:
push ecx
; pusha
; Çàäàòü ðàçìåð ñåêòîðà
; Задать размер сектора
; mov [CDBlockSize],2048 ;2352
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
; Очистить буфер пакетной команды
call clear_packet_buffer
; Ñôîðìèðîâàòü ïàêåòíóþ êîìàíäó äëÿ ñ÷èòûâàíèÿ
; ñåêòîðà äàííûõ
; Çàäàòü êîä êîìàíäû Read CD
; Сформировать пакетную команду для считывания
; сектора данных
; Задать код команды Read CD
mov [PacketCommand], byte 0x28;0xBE
; Çàäàòü àäðåñ ñåêòîðà
; Задать адрес сектора
mov AX, word [CDSectorAddress+2]
xchg AL, AH
mov word [PacketCommand+2], AX
121,11 → 121,11
mov word [PacketCommand+4], AX
; mov eax,[CDSectorAddress]
; mov [PacketCommand+2],eax
; Çàäàòü êîëè÷åñòâî ñ÷èòûâàåìûõ ñåêòîðîâ
; Задать количество считываемых секторов
mov [PacketCommand+8], byte 1
; Çàäàòü ñ÷èòûâàíèå äàííûõ â ïîëíîì îáúåìå
; Задать считывание данных в полном объеме
; mov [PacketCommand+9],byte 0xF8
; Ïîäàòü êîìàíäó
; Подать команду
call SendPacketDatCommand
pop ecx
; ret
147,7 → 147,7
jz @@NextRetr
jmp .wait
@@:
; Çàäåðæêà íà 2,5 ñåêóíäû
; Задержка на 2,5 секунды
; mov EAX,[timer_ticks]
; add EAX,50 ;250
;@@Wait:
161,53 → 161,53
ret
 
 
; Óíèâåðñàëüíûå ïðîöåäóðû, îáåñïå÷èâàþùèå âûïîëíåíèå
; ïàêåòíûõ êîìàíä â ðåæèìå PIO
; Универсальные процедуры, обеспечивающие выполнение
; пакетных команд в режиме PIO
 
; Ìàêñèìàëüíî äîïóñòèìîå âðåìÿ îæèäàíèÿ ðåàêöèè
; óñòðîéñòâà íà ïàêåòíóþ êîìàíäó (â òèêàõ)
; Максимально допустимое время ожидания реакции
; устройства на пакетную команду (в тиках)
 
MaxCDWaitTime equ 1000 ;200 ;10 ñåêóíä
MaxCDWaitTime equ 1000 ;200 ;10 секунд
uglobal
; Îáëàñòü ïàìÿòè äëÿ ôîðìèðîâàíèÿ ïàêåòíîé êîìàíäû
; Область памяти для формирования пакетной команды
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
endg
;****************************************************
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, *
;* ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×Ó ÎÄÍÎÃÎ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ *
;* ÐÀÇÌÅÐÎÌ 2048 ÁÀÉÒ ÎÒ ÓÑÒÐÎÉÑÒÂÀ Ê ÕÎÑÒÓ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå; *
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò; *
;* CDBlockSize - ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ. *
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ *
;* РАЗМЕРОМ 2048 БАЙТ ОТ УСТРОЙСТВА К ХОСТУ *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале; *
;* PacketCommand - 12-байтный командный пакет; *
;* CDBlockSize - размер принимаемого блока данных. *
; return eax DevErrorCode
;****************************************************
SendPacketDatCommand:
xor eax, eax
; mov byte [DevErrorCode],al
; Çàäàòü ðåæèì CHS
; Задать режим CHS
mov byte [ATAAddressMode], al
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû
; Послать ATA-команду передачи пакетной команды
mov byte [ATAFeatures], al
mov byte [ATASectorCount], al
mov byte [ATASectorNumber], al
; Çàãðóçèòü ðàçìåð ïåðåäàâàåìîãî áëîêà
; Загрузить размер передаваемого блока
mov [ATAHead], al
; mov AX,[CDBlockSize]
mov [ATACylinder], CDBlockSize
214,13 → 214,13
mov [ATACommand], 0A0h
call SendCommandToHDD_1
test eax, eax
; cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
jnz @@End_8 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
; cmp [DevErrorCode],0 ;проверить код ошибки
jnz @@End_8 ;закончить, сохранив код ошибки
 
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó
; ïàêåòíîé êîìàíäû
; Ожидание готовности дисковода к приему
; пакетной команды
mov DX, [ATABasePortAddr]
add DX, 7 ;ïîðò 1õ7h
add DX, 7 ;порт 1х7h
mov ecx, NoTickWaitTime
@@WaitDevice0:
cmp [timer_ticks_enable], 0
231,21 → 231,21
jmp .test
@@:
call change_task
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
; Проверить время выполнения команды
mov EAX, [timer_ticks]
sub EAX, [TickCounter_1]
cmp EAX, BSYWaitTime
ja @@Err1_1 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
ja @@Err1_1 ;ошибка тайм-аута
; Проверить готовность
.test:
in AL, DX
test AL, 80h ;ñîñòîÿíèå ñèãíàëà BSY
test AL, 80h ;состояние сигнала BSY
jnz @@WaitDevice0
test AL, 1 ;ñîñòîÿíèå ñèãíàëà ERR
test AL, 1 ;состояние сигнала ERR
jnz @@Err6
test AL, 08h ;ñîñòîÿíèå ñèãíàëà DRQ
test AL, 08h ;состояние сигнала DRQ
jz @@WaitDevice0
; Ïîñëàòü ïàêåòíóþ êîìàíäó
; Послать пакетную команду
cli
mov DX, [ATABasePortAddr]
mov AX, [PacketCommand]
261,9 → 261,9
mov AX, [PacketCommand+10]
out DX, AX
sti
; Îæèäàíèå ãîòîâíîñòè äàííûõ
; Ожидание готовности данных
mov DX, [ATABasePortAddr]
add DX, 7 ;ïîðò 1õ7h
add DX, 7 ;порт 1х7h
mov ecx, NoTickWaitTime
@@WaitDevice1:
cmp [timer_ticks_enable], 0
274,40 → 274,40
jmp .test_1
@@:
call change_task
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
; Проверить время выполнения команды
mov EAX, [timer_ticks]
sub EAX, [TickCounter_1]
cmp EAX, MaxCDWaitTime
ja @@Err1_1 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
ja @@Err1_1 ;ошибка тайм-аута
; Проверить готовность
.test_1:
in AL, DX
test AL, 80h ;ñîñòîÿíèå ñèãíàëà BSY
test AL, 80h ;состояние сигнала BSY
jnz @@WaitDevice1
test AL, 1 ;ñîñòîÿíèå ñèãíàëà ERR
test AL, 1 ;состояние сигнала ERR
jnz @@Err6_temp
test AL, 08h ;ñîñòîÿíèå ñèãíàëà DRQ
test AL, 08h ;состояние сигнала DRQ
jz @@WaitDevice1
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà
; Принять блок данных от контроллера
mov EDI, [CDDataBuf_pointer];0x7000 ;CDDataBuf
; Çàãðóçèòü àäðåñ ðåãèñòðà äàííûõ êîíòðîëëåðà
mov DX, [ATABasePortAddr];ïîðò 1x0h
; Çàãðóçèòü â ñ÷åò÷èê ðàçìåð áëîêà â áàéòàõ
; Загрузить адрес регистра данных контроллера
mov DX, [ATABasePortAddr];порт 1x0h
; Загрузить в счетчик размер блока в байтах
xor ecx, ecx
mov CX, CDBlockSize
; Âû÷èñëèòü ðàçìåð áëîêà â 16-ðàçðÿäíûõ ñëîâàõ
shr CX, 1;ðàçäåëèòü ðàçìåð áëîêà íà 2
; Ïðèíÿòü áëîê äàííûõ
; Вычислить размер блока в 16-разрядных словах
shr CX, 1;разделить размер блока на 2
; Принять блок данных
cli
cld
rep insw
sti
; Óñïåøíîå çàâåðøåíèå ïðèåìà äàííûõ
; Успешное завершение приема данных
@@End_8:
xor eax, eax
ret
 
; Çàïèñàòü êîä îøèáêè
; Записать код ошибки
@@Err1_1:
xor eax, eax
inc eax
329,21 → 329,21
 
 
;***********************************************
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, *
;* ÍÅ ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×È ÄÀÍÍÛÕ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç *
;* ãëîáàëüíûå ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå; *
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò. *
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
;* НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ *
;* Входные параметры передаются через *
;* глобальные перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале; *
;* PacketCommand - 12-байтный командный пакет. *
;***********************************************
SendPacketNoDatCommand:
pushad
xor eax, eax
; mov byte [DevErrorCode],al
; Çàäàòü ðåæèì CHS
; Задать режим CHS
mov byte [ATAAddressMode], al
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû
; Послать ATA-команду передачи пакетной команды
mov byte [ATAFeatures], al
mov byte [ATASectorCount], al
mov byte [ATASectorNumber], al
351,29 → 351,29
mov byte [ATAHead], al
mov [ATACommand], 0A0h
call SendCommandToHDD_1
; cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
; cmp [DevErrorCode],0 ;проверить код ошибки
test eax, eax
jnz @@End_9 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó
; ïàêåòíîé êîìàíäû
jnz @@End_9 ;закончить, сохранив код ошибки
; Ожидание готовности дисковода к приему
; пакетной команды
mov DX, [ATABasePortAddr]
add DX, 7 ;ïîðò 1õ7h
add DX, 7 ;порт 1х7h
@@WaitDevice0_1:
call change_task
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ
; Проверить время ожидания
mov EAX, [timer_ticks]
sub EAX, [TickCounter_1]
cmp EAX, BSYWaitTime
ja @@Err1_3 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
ja @@Err1_3 ;ошибка тайм-аута
; Проверить готовность
in AL, DX
test AL, 80h ;ñîñòîÿíèå ñèãíàëà BSY
test AL, 80h ;состояние сигнала BSY
jnz @@WaitDevice0_1
test AL, 1 ;ñîñòîÿíèå ñèãíàëà ERR
test AL, 1 ;состояние сигнала ERR
jnz @@Err6_1
test AL, 08h ;ñîñòîÿíèå ñèãíàëà DRQ
test AL, 08h ;состояние сигнала DRQ
jz @@WaitDevice0_1
; Ïîñëàòü ïàêåòíóþ êîìàíäó
; Послать пакетную команду
; cli
mov DX, [ATABasePortAddr]
mov AX, word [PacketCommand]
391,29 → 391,29
; sti
cmp [ignore_CD_eject_wait], 1
je @@clear_DEC
; Îæèäàíèå ïîäòâåðæäåíèÿ ïðèåìà êîìàíäû
; Ожидание подтверждения приема команды
mov DX, [ATABasePortAddr]
add DX, 7 ;ïîðò 1õ7h
add DX, 7 ;порт 1х7h
@@WaitDevice1_1:
call change_task
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
; Проверить время выполнения команды
mov EAX, [timer_ticks]
sub EAX, [TickCounter_1]
cmp EAX, MaxCDWaitTime
ja @@Err1_3 ;îøèáêà òàéì-àóòà
; Îæèäàòü îñâîáîæäåíèÿ óñòðîéñòâà
ja @@Err1_3 ;ошибка тайм-аута
; Ожидать освобождения устройства
in AL, DX
test AL, 80h ;ñîñòîÿíèå ñèãíàëà BSY
test AL, 80h ;состояние сигнала BSY
jnz @@WaitDevice1_1
test AL, 1 ;ñîñòîÿíèå ñèãíàëà ERR
test AL, 1 ;состояние сигнала ERR
jnz @@Err6_1
test AL, 40h ;ñîñòîÿíèå ñèãíàëà DRDY
test AL, 40h ;состояние сигнала DRDY
jz @@WaitDevice1_1
@@clear_DEC:
and [DevErrorCode], 0
popad
ret
; Çàïèñàòü êîä îøèáêè
; Записать код ошибки
@@Err1_3:
xor eax, eax
inc eax
426,53 → 426,53
ret
 
;****************************************************
;* ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå: *
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); *
;* DiskNumber - íîìåð äèñêà (0 èëè 1); *
;* ATAFeatures - "îñîáåííîñòè"; *
;* ATASectorCount - êîëè÷åñòâî ñåêòîðîâ; *
;* ATASectorNumber - íîìåð íà÷àëüíîãî ñåêòîðà; *
;* ATACylinder - íîìåð íà÷àëüíîãî öèëèíäðà; *
;* ATAHead - íîìåð íà÷àëüíîé ãîëîâêè; *
;* ATAAddressMode - ðåæèì àäðåñàöèè (0-CHS, 1-LBA); *
;* ATACommand - êîä êîìàíäû. *
;* Ïîñëå óñïåøíîãî âûïîëíåíèÿ ôóíêöèè: *
;* â ATABasePortAddr - áàçîâûé àäðåñ HDD; *
;* â DevErrorCode - íîëü. *
;* Ïðè âîçíèêíîâåíèè îøèáêè â DevErrorCode áóäåò *
;* âîçâðàùåí êîä îøèáêè â eax *
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ *
;* Входные параметры передаются через глобальные *
;* переменные: *
;* ChannelNumber - номер канала (1 или 2); *
;* DiskNumber - номер диска (0 или 1); *
;* ATAFeatures - "особенности"; *
;* ATASectorCount - количество секторов; *
;* ATASectorNumber - номер начального сектора; *
;* ATACylinder - номер начального цилиндра; *
;* ATAHead - номер начальной головки; *
;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); *
;* ATACommand - код команды. *
;* После успешного выполнения функции: *
;* в ATABasePortAddr - базовый адрес HDD; *
;* в DevErrorCode - ноль. *
;* При возникновении ошибки в DevErrorCode будет *
;* возвращен код ошибки в eax *
;****************************************************
SendCommandToHDD_1:
; pushad
; mov [DevErrorCode],0 not need
; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà
; Проверить значение кода режима
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 ê ïðèåìó êîìàíäû
; Âûáðàòü íóæíûé äèñê
; Ожидание готовности HDD к приему команды
; Выбрать нужный диск
mov DX, [ATABasePortAddr]
add DX, 6 ;àäðåñ ðåãèñòðà ãîëîâîê
add DX, 6 ;адрес регистра головок
mov AL, [DiskNumber]
cmp AL, 1 ;ïðîâåðèòü íîìåðà äèñêà
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
486,43 → 486,43
jmp .test
@@:
call change_task
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ
; Проверить время ожидания
mov eax, [timer_ticks]
sub eax, [TickCounter_1]
cmp eax, BSYWaitTime;300 ;îæèäàòü 3 ñåê.
ja @@Err1_4 ;îøèáêà òàéì-àóòà
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíèÿ
cmp eax, BSYWaitTime;300 ;ожидать 3 сек.
ja @@Err1_4 ;ошибка тайм-аута
; Прочитать регистр состояния
.test:
in AL, DX
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY
; Проверить состояние сигнала BSY
test AL, 80h
jnz @@WaitHDReady_2
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ
; Проверить состояние сигнала DRQ
test AL, 08h
jnz @@WaitHDReady_2
 
; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà
; Загрузить команду в регистры контроллера
cli
mov DX, [ATABasePortAddr]
inc DX ;ðåãèñòð "îñîáåííîñòåé"
inc DX ;регистр "особенностей"
mov AL, [ATAFeatures]
out DX, AL
inc DX ;ñ÷åò÷èê ñåêòîðîâ
inc DX ;счетчик секторов
mov AL, [ATASectorCount]
out DX, AL
inc DX ;ðåãèñòð íîìåðà ñåêòîðà
inc DX ;регистр номера сектора
mov AL, [ATASectorNumber]
out DX, AL
inc DX ;íîìåð öèëèíäðà (ìëàäøèé áàéò)
inc DX ;номер цилиндра (младший байт)
mov AX, [ATACylinder]
out DX, AL
inc DX ;íîìåð öèëèíäðà (ñòàðøèé áàéò)
inc DX ;номер цилиндра (старший байт)
mov AL, AH
out DX, AL
inc DX ;íîìåð ãîëîâêè/íîìåð äèñêà
inc DX ;номер головки/номер диска
mov AL, [DiskNumber]
shl AL, 4
cmp [ATAHead], 0Fh;ïðîâåðèòü íîìåð ãîëîâêè
cmp [ATAHead], 0Fh;проверить номер головки
ja @@Err5_4
or AL, [ATAHead]
or AL, 10100000b
530,17 → 530,17
shl AH, 6
or AL, AH
out DX, AL
; Ïîñëàòü êîìàíäó
; Послать команду
mov AL, [ATACommand]
inc DX ;ðåãèñòð êîìàíä
inc DX ;регистр команд
out DX, AL
sti
; Ñáðîñèòü ïðèçíàê îøèáêè
; Сбросить признак ошибки
; mov [DevErrorCode],0
@@End_10:
xor eax, eax
ret
; Çàïèñàòü êîä îøèáêè
; Записать код ошибки
@@Err1_4:
xor eax, eax
inc eax
561,31 → 561,31
@@Err5_4:
mov eax, 5
; mov [DevErrorCode],5
; Çàâåðøåíèå ðàáîòû ïðîãðàììû
; Завершение работы программы
ret
; sti
; popad
 
;*************************************************
;* ÎÆÈÄÀÍÈÅ ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ Ê ÐÀÁÎÒÅ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;* ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;*************************************************
WaitUnitReady:
pusha
; Çàïîìíèòü âðåìÿ íà÷àëà îïåðàöèè
; Запомнить время начала операции
mov EAX, [timer_ticks]
mov [WURStartTime], EAX
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
; Очистить буфер пакетной команды
call clear_packet_buffer
; Ñôîðìèðîâàòü êîìàíäó TEST UNIT READY
; Сформировать команду TEST UNIT READY
mov [PacketCommand], word 00h
; ÖÈÊË ÎÆÈÄÀÍÈß ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ
; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА
mov ecx, NoTickWaitTime
@@SendCommand:
; Ïîäàòü êîìàíäó ïðîâåðêè ãîòîâíîñòè
; Подать команду проверки готовности
call SendPacketNoDatCommand
cmp [timer_ticks_enable], 0
jne @f
597,16 → 597,16
jmp @@SendCommand
@@:
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
613,21 → 613,21
ret
 
;*************************************************
;* ÇÀÏÐÅÒÈÒÜ ÑÌÅÍÓ ÄÈÑÊÀ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;* ЗАПРЕТИТЬ СМЕНУ ДИСКА *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* 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]
637,21 → 637,21
ret
 
;*************************************************
;* ÐÀÇÐÅØÈÒÜ ÑÌÅÍÓ ÄÈÑÊÀ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;* РАЗРЕШИТЬ СМЕНУ ДИСКА *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;*************************************************
allow_medium_removal:
pusha
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
; Очистить буфер пакетной команды
call clear_packet_buffer
; Çàäàòü êîä êîìàíäû
; Задать код команды
mov [PacketCommand], byte 0x1E
; Çàäàòü êîä çàïðåòà
; Задать код запрета
mov [PacketCommand+4], byte 00b
; Ïîäàòü êîìàíäó
; Подать команду
call SendPacketNoDatCommand
mov eax, ATAPI_IDE0_lock
add eax, [cdpos]
661,54 → 661,54
ret
 
;*************************************************
;* ÇÀÃÐÓÇÈÒÜ ÍÎÑÈÒÅËÜ Â ÄÈÑÊÎÂÎÄ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;* ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;*************************************************
LoadMedium:
pusha
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
; Очистить буфер пакетной команды
call clear_packet_buffer
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT
; Çàäàòü êîä êîìàíäû
; Сформировать команду START/STOP UNIT
; Задать код команды
mov [PacketCommand], word 1Bh
; Çàäàòü îïåðàöèþ çàãðóçêè íîñèòåëÿ
; Задать операцию загрузки носителя
mov [PacketCommand+4], word 00000011b
; Ïîäàòü êîìàíäó
; Подать команду
call SendPacketNoDatCommand
popa
ret
 
;*************************************************
;* ÈÇÂËÅ×Ü ÍÎÑÈÒÅËÜ ÈÇ ÄÈÑÊÎÂÎÄÀ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;* ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА *
;* Входные параметры передаются через глобальные *
;* перменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;*************************************************
EjectMedium:
pusha
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
; Очистить буфер пакетной команды
call clear_packet_buffer
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT
; Çàäàòü êîä êîìàíäû
; Сформировать команду START/STOP UNIT
; Задать код команды
mov [PacketCommand], word 1Bh
; Çàäàòü îïåðàöèþ èçâëå÷åíèÿ íîñèòåëÿ
; Задать операцию извлечения носителя
mov [PacketCommand+4], word 00000010b
; Ïîäàòü êîìàíäó
; Подать команду
call SendPacketNoDatCommand
popa
ret
 
;*************************************************
;* Ïðîâåðèòü ñîáûòèå íàæàòèÿ êíîïêè èçâëå÷åíèÿ *
;* äèñêà *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;* Проверить событие нажатия кнопки извлечения *
;* диска *
;* Входные параметры передаются через глобальные *
;* переменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;*************************************************
proc check_ATAPI_device_event_has_work?
mov eax, [timer_ticks]
867,78 → 867,78
ignore_CD_eject_wait db 0
endg
;*************************************************
;* Ïîëó÷èòü ñîîáùåíèå î ñîáûòèè èëè ñîñòîÿíèè *
;* óñòðîéñòâà *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;* Получить сообщение о событии или состоянии *
;* устройства *
;* Входные параметры передаются через глобальные *
;* переменные: *
;* 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 - íîìåð äèñêà íà êàíàëå. *
; прочитать информацию из 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 - íîìåð äèñêà íà êàíàëå. *
;* ОПРЕДЕЛИТЬ ОБЩЕЕ КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ *
;* Входные параметры передаются через глобальные *
;* переменные: *
;* ChannelNumber - номер канала; *
;* DiskNumber - номер диска на канале. *
;*************************************************
;ReadCapacity:
; pusha
;; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
;; Очистить буфер пакетной команды
; call clear_packet_buffer
;; Çàäàòü ðàçìåð áóôåðà â áàéòàõ
;; Задать размер буфера в байтах
; mov [CDBlockSize],8
;; Ñôîðìèðîâàòü êîìàíäó READ CAPACITY
;; Сформировать команду 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