c4f8c8e404
git-svn-id: svn://kolibrios.org@1909 a494cfbc-eb01-0410-851d-a64ba20cac60
930 lines
28 KiB
PHP
930 lines
28 KiB
PHP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; ;;
|
|
;; Copyright (C) KolibriOS team 2004-2007. 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
|
|
.hdreadcache:
|
|
; cmp dword [esi+4],0 ; empty
|
|
; je .nohdcache
|
|
cmp [esi],eax ; correct sector
|
|
je .yeshdcache
|
|
.nohdcache:
|
|
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
|
|
; mov dword [esi+4],1 ; hd read - mark as same as in hd
|
|
.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
|
|
@@NextRetr:
|
|
; Ïîäàòü êîìàíäó
|
|
;*************************************************
|
|
;* ÏÎËÍÎÅ ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÊÎÌÏÀÊÒ-ÄÈÑÊÀ *
|
|
;* Ñ÷èòûâàþòñÿ äàííûå ïîëüçîâàòåëÿ, èíôîðìàöèÿ *
|
|
;* ñóáêàíàëà è êîíòðîëüíàÿ èíôîðìàöèÿ *
|
|
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
|
|
;* ïåðìåííûå: *
|
|
;* ChannelNumber - íîìåð êàíàëà; *
|
|
;* DiskNumber - íîìåð äèñêà íà êàíàëå; *
|
|
;* CDSectorAddress - àäðåñ ñ÷èòûâàåìîãî ñåêòîðà. *
|
|
;* Äàííûå ñ÷èòûâàåòñÿ â ìàññèâ CDDataBuf. *
|
|
;*************************************************
|
|
;ReadCD:
|
|
push ecx
|
|
; pusha
|
|
; Çàäàòü ðàçìåð ñåêòîðà
|
|
; mov [CDBlockSize],2048 ;2352
|
|
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
|
|
call clear_packet_buffer
|
|
; Ñôîðìèðîâàòü ïàêåòíóþ êîìàíäó äëÿ ñ÷èòûâàíèÿ
|
|
; ñåêòîðà äàííûõ
|
|
; Çàäàòü êîä êîìàíäû Read CD
|
|
mov [PacketCommand],byte 0x28 ;0xBE
|
|
; Çàäàòü àäðåñ ñåêòîðà
|
|
mov AX,word [CDSectorAddress+2]
|
|
xchg AL,AH
|
|
mov word [PacketCommand+2],AX
|
|
mov AX,word [CDSectorAddress]
|
|
xchg AL,AH
|
|
mov word [PacketCommand+4],AX
|
|
; mov eax,[CDSectorAddress]
|
|
; mov [PacketCommand+2],eax
|
|
; Çàäàòü êîëè÷åñòâî ñ÷èòûâàåìûõ ñåêòîðîâ
|
|
mov [PacketCommand+8],byte 1
|
|
; Çàäàòü ñ÷èòûâàíèå äàííûõ â ïîëíîì îáúåìå
|
|
; mov [PacketCommand+9],byte 0xF8
|
|
; Ïîäàòü êîìàíäó
|
|
call SendPacketDatCommand
|
|
pop ecx
|
|
; ret
|
|
|
|
; cmp [DevErrorCode],0
|
|
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
|
|
.wait:
|
|
dec eax
|
|
; test eax,eax
|
|
jz @@NextRetr
|
|
jmp .wait
|
|
@@:
|
|
; Çàäåðæêà íà 2,5 ñåêóíäû
|
|
; mov EAX,[timer_ticks]
|
|
; add EAX,50 ;250
|
|
;@@Wait:
|
|
; call change_task
|
|
; cmp EAX,[timer_ticks]
|
|
; ja @@Wait
|
|
loop @@NextRetr
|
|
@@End_4:
|
|
mov dword [DevErrorCode],eax
|
|
popad
|
|
ret
|
|
|
|
|
|
; Óíèâåðñàëüíûå ïðîöåäóðû, îáåñïå÷èâàþùèå âûïîëíåíèå
|
|
; ïàêåòíûõ êîìàíä â ðåæèìå PIO
|
|
|
|
; Ìàêñèìàëüíî äîïóñòèìîå âðåìÿ îæèäàíèÿ ðåàêöèè
|
|
; óñòðîéñòâà íà ïàêåòíóþ êîìàíäó (â òèêàõ)
|
|
|
|
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 - ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ. *
|
|
; return eax DevErrorCode
|
|
;****************************************************
|
|
SendPacketDatCommand:
|
|
xor eax,eax
|
|
; mov byte [DevErrorCode],al
|
|
; Çàäàòü ðåæèì CHS
|
|
mov byte [ATAAddressMode],al
|
|
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû
|
|
mov byte [ATAFeatures],al
|
|
mov byte [ATASectorCount],al
|
|
mov byte [ATASectorNumber],al
|
|
; Çàãðóçèòü ðàçìåð ïåðåäàâàåìîãî áëîêà
|
|
mov [ATAHead],al
|
|
; mov AX,[CDBlockSize]
|
|
mov [ATACylinder],CDBlockSize
|
|
mov [ATACommand],0A0h
|
|
call SendCommandToHDD_1
|
|
test eax,eax
|
|
; cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
|
|
jnz @@End_8 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
|
|
|
|
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó
|
|
; ïàêåòíîé êîìàíäû
|
|
mov DX,[ATABasePortAddr]
|
|
add DX,7 ;ïîðò 1õ7h
|
|
mov ecx,NoTickWaitTime
|
|
@@WaitDevice0:
|
|
cmp [timer_ticks_enable],0
|
|
jne @f
|
|
dec ecx
|
|
; test ecx,ecx
|
|
jz @@Err1_1
|
|
jmp .test
|
|
@@:
|
|
call change_task
|
|
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
|
|
mov EAX,[timer_ticks]
|
|
sub EAX,[TickCounter_1]
|
|
cmp EAX,BSYWaitTime
|
|
ja @@Err1_1 ;îøèáêà òàéì-àóòà
|
|
; Ïðîâåðèòü ãîòîâíîñòü
|
|
.test:
|
|
in AL,DX
|
|
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
|
|
jnz @@WaitDevice0
|
|
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
|
|
jnz @@Err6
|
|
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ
|
|
jz @@WaitDevice0
|
|
; Ïîñëàòü ïàêåòíóþ êîìàíäó
|
|
cli
|
|
mov DX,[ATABasePortAddr]
|
|
mov AX,[PacketCommand]
|
|
out DX,AX
|
|
mov AX,[PacketCommand+2]
|
|
out DX,AX
|
|
mov AX,[PacketCommand+4]
|
|
out DX,AX
|
|
mov AX,[PacketCommand+6]
|
|
out DX,AX
|
|
mov AX,[PacketCommand+8]
|
|
out DX,AX
|
|
mov AX,[PacketCommand+10]
|
|
out DX,AX
|
|
sti
|
|
; Îæèäàíèå ãîòîâíîñòè äàííûõ
|
|
mov DX,[ATABasePortAddr]
|
|
add DX,7 ;ïîðò 1õ7h
|
|
mov ecx,NoTickWaitTime
|
|
@@WaitDevice1:
|
|
cmp [timer_ticks_enable],0
|
|
jne @f
|
|
dec ecx
|
|
; test ecx,ecx
|
|
jz @@Err1_1
|
|
jmp .test_1
|
|
@@:
|
|
call change_task
|
|
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
|
|
mov EAX,[timer_ticks]
|
|
sub EAX,[TickCounter_1]
|
|
cmp EAX,MaxCDWaitTime
|
|
ja @@Err1_1 ;îøèáêà òàéì-àóòà
|
|
; Ïðîâåðèòü ãîòîâíîñòü
|
|
.test_1:
|
|
in AL,DX
|
|
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
|
|
jnz @@WaitDevice1
|
|
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
|
|
jnz @@Err6_temp
|
|
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ
|
|
jz @@WaitDevice1
|
|
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà
|
|
mov EDI,[CDDataBuf_pointer] ;0x7000 ;CDDataBuf
|
|
; Çàãðóçèòü àäðåñ ðåãèñòðà äàííûõ êîíòðîëëåðà
|
|
mov DX,[ATABasePortAddr] ;ïîðò 1x0h
|
|
; Çàãðóçèòü â ñ÷åò÷èê ðàçìåð áëîêà â áàéòàõ
|
|
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
|
|
; mov [DevErrorCode],1
|
|
; ret
|
|
@@Err6_temp:
|
|
mov eax,7
|
|
ret
|
|
; mov [DevErrorCode],7
|
|
; ret
|
|
@@Err6:
|
|
mov eax,6
|
|
ret
|
|
; mov [DevErrorCode],6
|
|
;@@End_8:
|
|
; ret
|
|
|
|
|
|
|
|
;***********************************************
|
|
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, *
|
|
;* ÍÅ ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×È ÄÀÍÍÛÕ *
|
|
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç *
|
|
;* ãëîáàëüíûå ïåðìåííûå: *
|
|
;* ChannelNumber - íîìåð êàíàëà; *
|
|
;* DiskNumber - íîìåð äèñêà íà êàíàëå; *
|
|
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò. *
|
|
;***********************************************
|
|
SendPacketNoDatCommand:
|
|
pushad
|
|
xor eax,eax
|
|
; mov byte [DevErrorCode],al
|
|
; Çàäàòü ðåæèì 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],0A0h
|
|
call SendCommandToHDD_1
|
|
; cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
|
|
test eax,eax
|
|
jnz @@End_9 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
|
|
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó
|
|
; ïàêåòíîé êîìàíäû
|
|
mov DX,[ATABasePortAddr]
|
|
add DX,7 ;ïîðò 1õ7h
|
|
@@WaitDevice0_1:
|
|
call change_task
|
|
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ
|
|
mov EAX,[timer_ticks]
|
|
sub EAX,[TickCounter_1]
|
|
cmp EAX,BSYWaitTime
|
|
ja @@Err1_3 ;îøèáêà òàéì-àóòà
|
|
; Ïðîâåðèòü ãîòîâíîñòü
|
|
in AL,DX
|
|
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
|
|
jnz @@WaitDevice0_1
|
|
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
|
|
jnz @@Err6_1
|
|
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ
|
|
jz @@WaitDevice0_1
|
|
; Ïîñëàòü ïàêåòíóþ êîìàíäó
|
|
; cli
|
|
mov DX,[ATABasePortAddr]
|
|
mov AX,word [PacketCommand]
|
|
out DX,AX
|
|
mov AX,word [PacketCommand+2]
|
|
out DX,AX
|
|
mov AX,word [PacketCommand+4]
|
|
out DX,AX
|
|
mov AX,word [PacketCommand+6]
|
|
out DX,AX
|
|
mov AX,word [PacketCommand+8]
|
|
out DX,AX
|
|
mov AX,word [PacketCommand+10]
|
|
out DX,AX
|
|
; sti
|
|
cmp [ignore_CD_eject_wait],1
|
|
je @@clear_DEC
|
|
; Îæèäàíèå ïîäòâåðæäåíèÿ ïðèåìà êîìàíäû
|
|
mov DX,[ATABasePortAddr]
|
|
add DX,7 ;ïîðò 1õ7h
|
|
@@WaitDevice1_1:
|
|
call change_task
|
|
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
|
|
mov EAX,[timer_ticks]
|
|
sub EAX,[TickCounter_1]
|
|
cmp EAX,MaxCDWaitTime
|
|
ja @@Err1_3 ;îøèáêà òàéì-àóòà
|
|
; Îæèäàòü îñâîáîæäåíèÿ óñòðîéñòâà
|
|
in AL,DX
|
|
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
|
|
jnz @@WaitDevice1_1
|
|
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
|
|
jnz @@Err6_1
|
|
test AL,40h ;ñîñòîÿíèå ñèãíàëà DRDY
|
|
jz @@WaitDevice1_1
|
|
@@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:
|
|
; 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 ê ïðèåìó êîìàíäû
|
|
; Âûáðàòü íóæíûé äèñê
|
|
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
|
|
@@WaitHDReady_2:
|
|
cmp [timer_ticks_enable],0
|
|
jne @f
|
|
dec ecx
|
|
; test ecx,ecx
|
|
jz @@Err1_4
|
|
jmp .test
|
|
@@:
|
|
call change_task
|
|
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ
|
|
mov eax,[timer_ticks]
|
|
sub eax,[TickCounter_1]
|
|
cmp eax,BSYWaitTime ;300 ;îæèäàòü 3 ñåê.
|
|
ja @@Err1_4 ;îøèáêà òàéì-àóòà
|
|
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíèÿ
|
|
.test:
|
|
in AL,DX
|
|
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY
|
|
test AL,80h
|
|
jnz @@WaitHDReady_2
|
|
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ
|
|
test AL,08h
|
|
jnz @@WaitHDReady_2
|
|
|
|
; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà
|
|
cli
|
|
mov DX,[ATABasePortAddr]
|
|
inc DX ;ðåãèñòð "îñîáåííîñòåé"
|
|
mov AL,[ATAFeatures]
|
|
out DX,AL
|
|
inc DX ;ñ÷åò÷èê ñåêòîðîâ
|
|
mov AL,[ATASectorCount]
|
|
out DX,AL
|
|
inc DX ;ðåãèñòð íîìåðà ñåêòîðà
|
|
mov AL,[ATASectorNumber]
|
|
out DX,AL
|
|
inc DX ;íîìåð öèëèíäðà (ìëàäøèé áàéò)
|
|
mov AX,[ATACylinder]
|
|
out DX,AL
|
|
inc DX ;íîìåð öèëèíäðà (ñòàðøèé áàéò)
|
|
mov AL,AH
|
|
out DX,AL
|
|
inc DX ;íîìåð ãîëîâêè/íîìåð äèñêà
|
|
mov AL,[DiskNumber]
|
|
shl AL,4
|
|
cmp [ATAHead],0Fh ;ïðîâåðèòü íîìåð ãîëîâêè
|
|
ja @@Err5_4
|
|
or AL,[ATAHead]
|
|
or AL,10100000b
|
|
mov AH,[ATAAddressMode]
|
|
shl AH,6
|
|
or AL,AH
|
|
out DX,AL
|
|
; Ïîñëàòü êîìàíäó
|
|
mov AL,[ATACommand]
|
|
inc DX ;ðåãèñòð êîìàíä
|
|
out DX,AL
|
|
sti
|
|
; Ñáðîñèòü ïðèçíàê îøèáêè
|
|
; mov [DevErrorCode],0
|
|
@@End_10:
|
|
xor eax,eax
|
|
ret
|
|
; Çàïèñàòü êîä îøèáêè
|
|
@@Err1_4:
|
|
xor eax,eax
|
|
inc eax
|
|
; mov [DevErrorCode],1
|
|
ret
|
|
@@Err2_4:
|
|
mov eax,2
|
|
; mov [DevErrorCode],2
|
|
ret
|
|
@@Err3_4:
|
|
mov eax,3
|
|
; mov [DevErrorCode],3
|
|
ret
|
|
@@Err4_4:
|
|
mov eax,4
|
|
; mov [DevErrorCode],4
|
|
ret
|
|
@@Err5_4:
|
|
mov eax,5
|
|
; mov [DevErrorCode],5
|
|
; Çàâåðøåíèå ðàáîòû ïðîãðàììû
|
|
ret
|
|
; sti
|
|
; popad
|
|
|
|
;*************************************************
|
|
;* ÎÆÈÄÀÍÈÅ ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ Ê ÐÀÁÎÒÅ *
|
|
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
|
|
;* ïåðìåííûå: *
|
|
;* ChannelNumber - íîìåð êàíàëà; *
|
|
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
|
|
;*************************************************
|
|
WaitUnitReady:
|
|
pusha
|
|
; Çàïîìíèòü âðåìÿ íà÷àëà îïåðàöèè
|
|
mov EAX,[timer_ticks]
|
|
mov [WURStartTime],EAX
|
|
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
|
|
call clear_packet_buffer
|
|
; Ñôîðìèðîâàòü êîìàíäó TEST UNIT READY
|
|
mov [PacketCommand],word 00h
|
|
; ÖÈÊË ÎÆÈÄÀÍÈß ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ
|
|
mov ecx,NoTickWaitTime
|
|
@@SendCommand:
|
|
; Ïîäàòü êîìàíäó ïðîâåðêè ãîòîâíîñòè
|
|
call SendPacketNoDatCommand
|
|
cmp [timer_ticks_enable],0
|
|
jne @f
|
|
cmp [DevErrorCode],0
|
|
je @@End_11
|
|
dec ecx
|
|
; cmp ecx,0
|
|
jz .Error
|
|
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
|
|
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 00b
|
|
; Ïîäàòü êîìàíäó
|
|
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 1Bh
|
|
; Çàäàòü îïåðàöèþ çàãðóçêè íîñèòåëÿ
|
|
mov [PacketCommand+4],word 00000011b
|
|
; Ïîäàòü êîìàíäó
|
|
call SendPacketNoDatCommand
|
|
popa
|
|
ret
|
|
|
|
;*************************************************
|
|
;* ÈÇÂËÅ×Ü ÍÎÑÈÒÅËÜ ÈÇ ÄÈÑÊÎÂÎÄÀ *
|
|
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
|
|
;* ïåðìåííûå: *
|
|
;* ChannelNumber - íîìåð êàíàëà; *
|
|
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
|
|
;*************************************************
|
|
EjectMedium:
|
|
pusha
|
|
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
|
|
call clear_packet_buffer
|
|
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT
|
|
; Çàäàòü êîä êîìàíäû
|
|
mov [PacketCommand],word 1Bh
|
|
; Çàäàòü îïåðàöèþ èçâëå÷åíèÿ íîñèòåëÿ
|
|
mov [PacketCommand+4],word 00000010b
|
|
; Ïîäàòü êîìàíäó
|
|
call SendPacketNoDatCommand
|
|
popa
|
|
ret
|
|
|
|
;*************************************************
|
|
;* Ïðîâåðèòü ñîáûòèå íàæàòèÿ êíîïêè èçâëå÷åíèÿ *
|
|
;* äèñêà *
|
|
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
|
|
;* ïåðåìåííûå: *
|
|
;* ChannelNumber - íîìåð êàíàëà; *
|
|
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
|
|
;*************************************************
|
|
align 4
|
|
check_ATAPI_device_event:
|
|
pusha
|
|
mov eax,[timer_ticks]
|
|
sub eax,[timer_ATAPI_check]
|
|
cmp eax,100
|
|
jb .end_1
|
|
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
|
|
.end:
|
|
|
|
sti
|
|
mov eax,[timer_ticks]
|
|
mov [timer_ATAPI_check],eax
|
|
.end_1:
|
|
popa
|
|
ret
|
|
|
|
.ide3:
|
|
cli
|
|
cmp [ATAPI_IDE3_lock],1
|
|
jne .ide2_1
|
|
cmp [IDE_Channel_2],0
|
|
jne .ide1_1
|
|
cmp [cd_status],0
|
|
jne .end
|
|
mov [IDE_Channel_2],1
|
|
call reserve_ok2
|
|
mov [ChannelNumber],2
|
|
mov [DiskNumber],1
|
|
mov [cdpos],4
|
|
call GetEvent_StatusNotification
|
|
cmp [CDDataBuf+4],byte 1
|
|
je .eject_ide3
|
|
call syscall_cdaudio.free
|
|
jmp .ide2_1
|
|
.eject_ide3:
|
|
call .eject
|
|
call syscall_cdaudio.free
|
|
jmp .ide2_1
|
|
|
|
.ide2:
|
|
cli
|
|
cmp [ATAPI_IDE2_lock],1
|
|
jne .ide1_1
|
|
cmp [IDE_Channel_2],0
|
|
jne .ide1_1
|
|
cmp [cd_status],0
|
|
jne .end
|
|
mov [IDE_Channel_2],1
|
|
call reserve_ok2
|
|
mov [ChannelNumber],2
|
|
mov [DiskNumber],0
|
|
mov [cdpos],3
|
|
call GetEvent_StatusNotification
|
|
cmp [CDDataBuf+4],byte 1
|
|
je .eject_ide2
|
|
call syscall_cdaudio.free
|
|
jmp .ide1_1
|
|
.eject_ide2:
|
|
call .eject
|
|
call syscall_cdaudio.free
|
|
jmp .ide1_1
|
|
|
|
.ide1:
|
|
cli
|
|
cmp [ATAPI_IDE1_lock],1
|
|
jne .ide0_1
|
|
cmp [IDE_Channel_1],0
|
|
jne .end
|
|
cmp [cd_status],0
|
|
jne .end
|
|
mov [IDE_Channel_1],1
|
|
call reserve_ok2
|
|
mov [ChannelNumber],1
|
|
mov [DiskNumber],1
|
|
mov [cdpos],2
|
|
call GetEvent_StatusNotification
|
|
cmp [CDDataBuf+4],byte 1
|
|
je .eject_ide1
|
|
call syscall_cdaudio.free
|
|
jmp .ide0_1
|
|
.eject_ide1:
|
|
call .eject
|
|
call syscall_cdaudio.free
|
|
jmp .ide0_1
|
|
|
|
.ide0:
|
|
cli
|
|
cmp [ATAPI_IDE0_lock],1
|
|
jne .end
|
|
cmp [IDE_Channel_1],0
|
|
jne .end
|
|
cmp [cd_status],0
|
|
jne .end
|
|
mov [IDE_Channel_1],1
|
|
call reserve_ok2
|
|
mov [ChannelNumber],1
|
|
mov [DiskNumber],0
|
|
mov [cdpos],1
|
|
call GetEvent_StatusNotification
|
|
cmp [CDDataBuf+4],byte 1
|
|
je .eject_ide0
|
|
call syscall_cdaudio.free
|
|
jmp .end
|
|
.eject_ide0:
|
|
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
|
|
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
|