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,55 → 661,69 |
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] |
sub eax, [timer_ATAPI_check] |
cmp eax, 100 |
jb .no |
.yes: |
xor eax, eax |
inc eax |
ret |
.no: |
xor eax, eax |
ret |
endp |
|
align 4 |
check_ATAPI_device_event: |
pusha |
853,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 |