9,13 → 9,13 |
|
|
;****************************************************** |
; ïîèñê ïðèâîäîâ HDD è CD |
; àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; àäàïòàöèÿ è äîðàáîòêà Mario79 |
; поиск приводов HDD и CD |
; автор исходного текста Кулаков Владимир Геннадьевич. |
; адаптация и доработка Mario79 |
;****************************************************** |
|
;**************************************************** |
;* ÏÎÈÑÊ HDD è CD * |
;* ПОИСК HDD и CD * |
;**************************************************** |
FindHDD: |
mov [ChannelNumber], 1 |
71,54 → 71,54 |
ret |
|
|
; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà â ðåæèìå LBA |
; Адрес считываемого сектора в режиме LBA |
uglobal |
SectorAddress DD ? |
endg |
;************************************************* |
;* ×ÒÅÍÈÅ ÈÄÅÍÒÈÔÈÊÀÒÎÐÀ ÆÅÑÒÊÎÃÎ ÄÈÑÊÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå (0 èëè 1). * |
;* Èäåíòèôèêàöèîííûé áëîê äàííûõ ñ÷èòûâàåòñÿ * |
;* â ìàññèâ Sector512. * |
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА * |
;* Входные параметры передаются через глобальные * |
;* переменные: * |
;* ChannelNumber - номер канала (1 или 2); * |
;* DiskNumber - номер диска на канале (0 или 1). * |
;* Идентификационный блок данных считывается * |
;* в массив Sector512. * |
;************************************************* |
ReadHDD_ID: |
; Çàäàòü ðåæèì CHS |
; Задать режим CHS |
mov [ATAAddressMode], 0 |
; Ïîñëàòü êîìàíäó èäåíòèôèêàöèè óñòðîéñòâà |
; Послать команду идентификации устройства |
mov [ATAFeatures], 0 |
mov [ATAHead], 0 |
mov [ATACommand], 0ECh |
call SendCommandToHDD |
cmp [DevErrorCode], 0;ïðîâåðèòü êîä îøèáêè |
jne @@End ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
cmp [DevErrorCode], 0;проверить код ошибки |
jne @@End ;закончить, сохранив код ошибки |
mov DX, [ATABasePortAddr] |
add DX, 7 ;àäðåñ ðåãèñòðà ñîñòîÿíè |
add DX, 7 ;адрес регистра состояни |
mov ecx, 0xffff |
@@WaitCompleet: |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
; Проверить время выполнения команды |
dec ecx |
; cmp ecx,0 |
jz @@Error1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
jz @@Error1 ;ошибка тайм-аута |
; Проверить готовность |
in AL, DX |
test AL, 80h ;ñîñòîÿíèå ñèãíàëà BSY |
test AL, 80h ;состояние сигнала BSY |
jnz @@WaitCompleet |
test AL, 1 ;ñîñòîÿíèå ñèãíàëà ERR |
test AL, 1 ;состояние сигнала ERR |
jnz @@Error6 |
test AL, 08h ;ñîñòîÿíèå ñèãíàëà DRQ |
test AL, 08h ;состояние сигнала DRQ |
jz @@WaitCompleet |
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà |
; Принять блок данных от контроллера |
; mov AX,DS |
; mov ES,AX |
mov EDI, Sector512 ;offset Sector512 |
mov DX, [ATABasePortAddr];ðåãèñòð äàííûõ |
mov CX, 256 ;÷èñëî ñ÷èòûâàåìûõ ñëîâ |
rep insw ;ïðèíÿòü áëîê äàííûõ |
mov DX, [ATABasePortAddr];регистр данных |
mov CX, 256 ;число считываемых слов |
rep insw ;принять блок данных |
ret |
; Çàïèñàòü êîä îøèáêè |
; Записать код ошибки |
@@Error1: |
mov [DevErrorCode], 1 |
ret |
129,120 → 129,120 |
|
|
iglobal |
; Ñòàíäàðòíûå áàçîâûå àäðåñà êàíàëîâ 1 è 2 |
; Стандартные базовые адреса каналов 1 и 2 |
StandardATABases DW 1F0h, 170h |
endg |
uglobal |
; Íîìåð êàíàëà |
; Номер канала |
ChannelNumber DW ? |
; Íîìåð äèñêà |
; Номер диска |
DiskNumber DB ? |
; Áàçîâûé àäðåñ ãðóïïû ïîðòîâ êîíòðîëëåðà ATA |
; Базовый адрес группы портов контроллера ATA |
ATABasePortAddr DW ? |
; Ïàðàìåòðû ATA-êîìàíäû |
ATAFeatures DB ? ;îñîáåííîñòè |
ATASectorCount DB ? ;êîëè÷åñòâî îáðàáàòûâàåìûõ ñåêòîðîâ |
ATASectorNumber DB ? ;íîìåð íà÷àëüíîãî ñåêòîðà |
ATACylinder DW ? ;íîìåð íà÷àëüíîãî öèëèíäðà |
ATAHead DB ? ;íîìåð íà÷àëüíîé ãîëîâêè |
ATAAddressMode DB ? ;ðåæèì àäðåñàöèè (0 - CHS, 1 - LBA) |
ATACommand DB ? ;êîä êîìàíäû, ïîäëåæàùåé âûïîëíåíèþ |
; Êîä îøèáêè (0 - íåò îøèáîê, 1 - ïðåâûøåí äîïóñòèìûé |
; èíòåðâàë îæèäàíèÿ, 2 - íåâåðíûé êîä ðåæèìà àäðåñàöèè, |
; 3 - íåâåðíûé íîìåð êàíàëà, 4 - íåâåðíûé íîìåð äèñêà, |
; 5 - íåâåðíûé íîìåð ãîëîâêè, 6 - îøèáêà ïðè âûïîëíåíèè |
; êîìàíäû) |
; Параметры ATA-команды |
ATAFeatures DB ? ;особенности |
ATASectorCount DB ? ;количество обрабатываемых секторов |
ATASectorNumber DB ? ;номер начального сектора |
ATACylinder DW ? ;номер начального цилиндра |
ATAHead DB ? ;номер начальной головки |
ATAAddressMode DB ? ;режим адресации (0 - CHS, 1 - LBA) |
ATACommand DB ? ;код команды, подлежащей выполнению |
; Код ошибки (0 - нет ошибок, 1 - превышен допустимый |
; интервал ожидания, 2 - неверный код режима адресации, |
; 3 - неверный номер канала, 4 - неверный номер диска, |
; 5 - неверный номер головки, 6 - ошибка при выполнении |
; команды) |
DevErrorCode dd ? |
endg |
;**************************************************** |
;* ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà (0 èëè 1); * |
;* ATAFeatures - "îñîáåííîñòè"; * |
;* ATASectorCount - êîëè÷åñòâî ñåêòîðîâ; * |
;* ATASectorNumber - íîìåð íà÷àëüíîãî ñåêòîðà; * |
;* ATACylinder - íîìåð íà÷àëüíîãî öèëèíäðà; * |
;* ATAHead - íîìåð íà÷àëüíîé ãîëîâêè; * |
;* ATAAddressMode - ðåæèì àäðåñàöèè (0-CHS, 1-LBA); * |
;* ATACommand - êîä êîìàíäû. * |
;* Ïîñëå óñïåøíîãî âûïîëíåíèÿ ôóíêöèè: * |
;* â ATABasePortAddr - áàçîâûé àäðåñ HDD; * |
;* â DevErrorCode - íîëü. * |
;* Ïðè âîçíèêíîâåíèè îøèáêè â DevErrorCode áóäåò * |
;* âîçâðàùåí êîä îøèáêè. * |
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ * |
;* Входные параметры передаются через глобальные * |
;* переменные: * |
;* ChannelNumber - номер канала (1 или 2); * |
;* DiskNumber - номер диска (0 или 1); * |
;* ATAFeatures - "особенности"; * |
;* ATASectorCount - количество секторов; * |
;* ATASectorNumber - номер начального сектора; * |
;* ATACylinder - номер начального цилиндра; * |
;* ATAHead - номер начальной головки; * |
;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); * |
;* ATACommand - код команды. * |
;* После успешного выполнения функции: * |
;* в ATABasePortAddr - базовый адрес HDD; * |
;* в DevErrorCode - ноль. * |
;* При возникновении ошибки в DevErrorCode будет * |
;* возвращен код ошибки. * |
;**************************************************** |
SendCommandToHDD: |
; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà |
; Проверить значение кода режима |
cmp [ATAAddressMode], 1 |
ja @@Err2 |
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà |
; Проверить корректность номера канала |
mov BX, [ChannelNumber] |
cmp BX, 1 |
jb @@Err3 |
cmp BX, 2 |
ja @@Err3 |
; Óñòàíîâèòü áàçîâûé àäðåñ |
; Установить базовый адрес |
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 |
shl AL, 4 |
or AL, 10100000b |
out DX, AL |
; Îæèäàòü, ïîêà äèñê íå áóäåò ãîòîâ |
; Ожидать, пока диск не будет готов |
inc DX |
mov ecx, 0xfff |
; mov eax,[timer_ticks] |
; mov [TickCounter_1],eax |
@@WaitHDReady: |
; Ïðîâåðèòü âðåìÿ îæèäàíè |
; Проверить время ожидани |
dec ecx |
; cmp ecx,0 |
jz @@Err1 |
; mov eax,[timer_ticks] |
; sub eax,[TickCounter_1] |
; cmp eax,300 ;îæèäàòü 300 òèêîâ |
; ja @@Err1 ;îøèáêà òàéì-àóòà |
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíè |
; cmp eax,300 ;ожидать 300 тиков |
; ja @@Err1 ;ошибка тайм-аута |
; Прочитать регистр состояни |
in AL, DX |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY |
; Проверить состояние сигнала BSY |
test AL, 80h |
jnz @@WaitHDReady |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ |
; Проверить состояние сигнала DRQ |
test AL, 08h |
jnz @@WaitHDReady |
; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà |
; Загрузить команду в регистры контроллера |
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 |
or AL, [ATAHead] |
or AL, 10100000b |
250,15 → 250,15 |
shl AH, 6 |
or AL, AH |
out DX, AL |
; Ïîñëàòü êîìàíäó |
; Послать команду |
mov AL, [ATACommand] |
inc DX ;ðåãèñòð êîìàíä |
inc DX ;регистр команд |
out DX, AL |
sti |
; Ñáðîñèòü ïðèçíàê îøèáêè |
; Сбросить признак ошибки |
mov [DevErrorCode], 0 |
ret |
; Çàïèñàòü êîä îøèáêè |
; Записать код ошибки |
@@Err1: |
mov [DevErrorCode], 1 |
ret |
273,22 → 273,22 |
ret |
@@Err5: |
mov [DevErrorCode], 5 |
; Çàâåðøåíèå ðàáîòû ïðîãðàììû |
; Завершение работы программы |
ret |
|
;************************************************* |
;* ×ÒÅÍÈÅ ÈÄÅÍÒÈÔÈÊÀÒÎÐÀ ÓÑÒÐÎÉÑÒÂÀ ATAPI * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;* Èäåíòèôèêàöèîííûé áëîê äàííûõ ñ÷èòûâàåòñÿ * |
;* â ìàññèâ Sector512. * |
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА УСТРОЙСТВА ATAPI * |
;* Входные параметры передаются через глобальные * |
;* перменные: * |
;* ChannelNumber - номер канала; * |
;* DiskNumber - номер диска на канале. * |
;* Идентификационный блок данных считывается * |
;* в массив Sector512. * |
;************************************************* |
ReadCD_ID: |
; Çàäàòü ðåæèì CHS |
; Задать режим CHS |
mov [ATAAddressMode], 0 |
; Ïîñëàòü êîìàíäó èäåíòèôèêàöèè óñòðîéñòâà |
; Послать команду идентификации устройства |
mov [ATAFeatures], 0 |
mov [ATASectorCount], 0 |
mov [ATASectorNumber], 0 |
296,34 → 296,34 |
mov [ATAHead], 0 |
mov [ATACommand], 0A1h |
call SendCommandToHDD |
cmp [DevErrorCode], 0;ïðîâåðèòü êîä îøèáêè |
jne @@End_1 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
; Îæèäàòü ãîòîâíîñòü äàííûõ HDD |
cmp [DevErrorCode], 0;проверить код ошибки |
jne @@End_1 ;закончить, сохранив код ошибки |
; Ожидать готовность данных HDD |
mov DX, [ATABasePortAddr] |
add DX, 7 ;ïîðò 1õ7h |
add DX, 7 ;порт 1х7h |
mov ecx, 0xffff |
@@WaitCompleet_1: |
; Ïðîâåðèòü âðåì |
; Проверить врем |
dec ecx |
; cmp ecx,0 |
jz @@Error1_1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
jz @@Error1_1 ;ошибка тайм-аута |
; Проверить готовность |
in AL, DX |
test AL, 80h ;ñîñòîÿíèå ñèãíàëà BSY |
test AL, 80h ;состояние сигнала BSY |
jnz @@WaitCompleet_1 |
test AL, 1 ;ñîñòîÿíèå ñèãíàëà ERR |
test AL, 1 ;состояние сигнала ERR |
jnz @@Error6_1 |
test AL, 08h ;ñîñòîÿíèå ñèãíàëà DRQ |
test AL, 08h ;состояние сигнала DRQ |
jz @@WaitCompleet_1 |
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà |
; Принять блок данных от контроллера |
; mov AX,DS |
; mov ES,AX |
mov EDI, Sector512 ;offset Sector512 |
mov DX, [ATABasePortAddr];ïîðò 1x0h |
mov CX, 256;÷èñëî ñ÷èòûâàåìûõ ñëîâ |
mov DX, [ATABasePortAddr];порт 1x0h |
mov CX, 256;число считываемых слов |
rep insw |
ret |
; Çàïèñàòü êîä îøèáêè |
; Записать код ошибки |
@@Error1_1: |
mov [DevErrorCode], 1 |
ret |
333,52 → 333,52 |
ret |
|
;************************************************* |
;* ÑÁÐÎÑ ÓÑÒÐÎÉÑÒÂÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà (0 èëè 1). * |
;* СБРОС УСТРОЙСТВА * |
;* Входные параметры передаются через глобальные * |
;* переменные: * |
;* ChannelNumber - номер канала (1 или 2); * |
;* DiskNumber - номер диска (0 или 1). * |
;************************************************* |
DeviceReset: |
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà |
; Проверить корректность номера канала |
mov BX, [ChannelNumber] |
cmp BX, 1 |
jb @@Err3_2 |
cmp BX, 2 |
ja @@Err3_2 |
; Óñòàíîâèòü áàçîâûé àäðåñ |
; Установить базовый адрес |
dec BX |
shl BX, 1 |
movzx ebx, bx |
mov DX, [ebx+StandardATABases] |
mov [ATABasePortAddr], DX |
; Âûáðàòü íóæíûé äèñê |
add DX, 6 ;àäðåñ ðåãèñòðà ãîëîâîê |
; Выбрать нужный диск |
add DX, 6 ;адрес регистра головок |
mov AL, [DiskNumber] |
cmp AL, 1 ;ïðîâåðèòü íîìåðà äèñêà |
cmp AL, 1 ;проверить номера диска |
ja @@Err4_2 |
shl AL, 4 |
or AL, 10100000b |
out DX, AL |
; Ïîñëàòü êîìàíäó "Ñáðîñ" |
; Послать команду "Сброс" |
mov AL, 08h |
inc DX ;ðåãèñòð êîìàíä |
inc DX ;регистр команд |
out DX, AL |
mov ecx, 0x80000 |
@@WaitHDReady_1: |
; Ïðîâåðèòü âðåìÿ îæèäàíè |
; Проверить время ожидани |
dec ecx |
; cmp ecx,0 |
je @@Err1_2 ;îøèáêà òàéì-àóòà |
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíè |
je @@Err1_2 ;ошибка тайм-аута |
; Прочитать регистр состояни |
in AL, DX |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY |
; Проверить состояние сигнала BSY |
test AL, 80h |
jnz @@WaitHDReady_1 |
; Ñáðîñèòü ïðèçíàê îøèáêè |
; Сбросить признак ошибки |
mov [DevErrorCode], 0 |
ret |
; Îáðàáîòêà îøèáîê |
; Обработка ошибок |
@@Err1_2: |
mov [DevErrorCode], 1 |
ret |
387,7 → 387,7 |
ret |
@@Err4_2: |
mov [DevErrorCode], 4 |
; Çàïèñàòü êîä îøèáêè |
; Записать код ошибки |
ret |
|
EndFindHDD: |