Subversion Repositories Kolibri OS

Compare Revisions

Ignore whitespace Rev 86 → Rev 87

/kernel/trunk/blkdev/cd_drv.inc
0,0 → 1,546
;**********************************************************
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ óñòðîéñòâîì ÑD (ATAPI)
;**********************************************************
; Àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷.
; Àäàïòàöèÿ è äîðàáîòêà Mario79
 
; Ïðîöåäóðà äëÿ ïîëíîãî ñ÷èòûâàíèÿ âñåõ
; äàííûõ èç ñåêòîðà êîìïàêò-äèñêà
; Àâòîð òåêñòà ïðîãðàììû Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷.
 
 
; Ìàêñèìàëüíîå êîëè÷åñòâî ïîâòîðåíèé îïåðàöèè ÷òåíèÿ
MaxRetr equ 3
; Ïðåäåëüíîå âðåìÿ îæèäàíèÿ ãîòîâíîñòè ê ïðèåìó êîìàíäû
; (â òèêàõ)
BSYWaitTime equ 1000 ;2
 
;*************************************************
;* ÏÎËÍÎÅ ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÊÎÌÏÀÊÒ-ÄÈÑÊÀ *
;* Ñ÷èòûâàþòñÿ äàííûå ïîëüçîâàòåëÿ, èíôîðìàöèÿ *
;* ñóáêàíàëà è êîíòðîëüíàÿ èíôîðìàöèÿ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå; *
;* CDSectorAddress - àäðåñ ñ÷èòûâàåìîãî ñåêòîðà. *
;* Äàííûå ñ÷èòûâàåòñÿ â ìàññèâ CDDataBuf. *
;*************************************************
ReadCD:
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
; call test_mario79
popa
ret
 
;********************************************
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ Ñ ÏÎÂÒÎÐÀÌÈ *
;* Ìíîãîêðàòíîå ïîâòîðåíèå ÷òåíèÿ ïðè ñáîÿõ *
;********************************************
ReadCDWRetr:
pusha
; Öèêë, ïîêà êîìàíäà íå âûïîëíåíà óñïåøíî èëè íå
; èñ÷åðïàíî êîëè÷åñòâî ïîïûòîê
mov ECX,MaxRetr
@@NextRetr:
; Ïîäàòü êîìàíäó
call ReadCD
cmp [DevErrorCode],0
je @@End_4
; Çàäåðæêà íà 2,5 ñåêóíäû
mov EAX,[timer_ticks]
add EAX,250 ;50
@@Wait:
call change_task
cmp EAX,[timer_ticks]
ja @@Wait
loop @@NextRetr
; call test_mario79
; Ñîîáùåíèå îá îøèáêå
; mov SI,offset ErrS
; call FatalError
@@End_4:
popa
ret
 
 
; Óíèâåðñàëüíûå ïðîöåäóðû, îáåñïå÷èâàþùèå âûïîëíåíèå
; ïàêåòíûõ êîìàíä â ðåæèìå PIO
;
; Àâòîð òåêñòà ïðîãðàììû Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷.
 
; Ìàêñèìàëüíî äîïóñòèìîå âðåìÿ îæèäàíèÿ ðåàêöèè
; óñòðîéñòâà íà ïàêåòíóþ êîìàíäó (â òèêàõ)
MaxCDWaitTime equ 1000 ;200 ;10 ñåêóíä
 
; Îáëàñòü ïàìÿòè äëÿ ôîðìèðîâàíèÿ ïàêåòíîé êîìàíäû
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
 
;****************************************************
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, *
;* ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×Ó ÎÄÍÎÃÎ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ *
;* ÐÀÇÌÅÐÎÌ 2048 ÁÀÉÒ ÎÒ ÓÑÒÐÎÉÑÒÂÀ Ê ÕÎÑÒÓ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå; *
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò; *
;* CDBlockSize - ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ. *
;****************************************************
SendPacketDatCommand:
pushad
; Çàäàòü ðåæèì CHS
mov [ATAAddressMode],0
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû
mov [ATAFeatures],0
mov [ATASectorCount],0
mov [ATASectorNumber],0
; Çàãðóçèòü ðàçìåð ïåðåäàâàåìîãî áëîêà
mov AX,[CDBlockSize]
mov [ATACylinder],AX
mov [ATAHead],0
mov [ATACommand],0A0h
call SendCommandToHDD_1
; call test_mario79
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
jne @@End_8 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
 
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó
; ïàêåòíîé êîìàíäû
mov DX,[ATABasePortAddr]
add DX,7 ;ïîðò 1õ7h
@@WaitDevice0:
call change_task
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
mov EAX,[timer_ticks]
sub EAX,[TickCounter_1]
cmp EAX,BSYWaitTime
ja @@Err1_1 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
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
@@WaitDevice1:
call change_task
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
mov EAX,[timer_ticks]
sub EAX,[TickCounter_1]
cmp EAX,MaxCDWaitTime
ja @@Err1_1 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
in AL,DX
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
jnz @@WaitDevice1
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
jnz @@Err6_temp
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ
jz @@WaitDevice1
cli
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà
mov EDI,[CDDataBuf_pointer] ;0x7000 ;CDDataBuf
; Çàãðóçèòü àäðåñ ðåãèñòðà äàííûõ êîíòðîëëåðà
mov DX,[ATABasePortAddr] ;ïîðò 1x0h
; Çàãðóçèòü â ñ÷åò÷èê ðàçìåð áëîêà â áàéòàõ
mov CX,[CDBlockSize]
; Âû÷èñëèòü ðàçìåð áëîêà â 16-ðàçðÿäíûõ ñëîâàõ
shr CX,1 ;ðàçäåëèòü ðàçìåð áëîêà íà 2
; Ïðèíÿòü áëîê äàííûõ
cld
rep insw
sti
; Óñïåøíîå çàâåðøåíèå ïðèåìà äàííûõ
jmp @@End_8
 
; Çàïèñàòü êîä îøèáêè
@@Err1_1:
mov [DevErrorCode],1
jmp @@End_8
@@Err6_temp:
mov [DevErrorCode],7
jmp @@End_8
@@Err6:
mov [DevErrorCode],6
 
@@End_8:
popad
ret
 
 
 
;***********************************************
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, *
;* ÍÅ ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×È ÄÀÍÍÛÕ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç *
;* ãëîáàëüíûå ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå; *
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò. *
;***********************************************
SendPacketNoDatCommand:
pushad
; Çàäàòü ðåæèì CHS
mov [ATAAddressMode],0
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû
mov [ATAFeatures],0
mov [ATASectorCount],0
mov [ATASectorNumber],0
mov [ATACylinder],0
mov [ATAHead],0
mov [ATACommand],0A0h
call SendCommandToHDD_1
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
jne @@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
; Îæèäàíèå ïîäòâåðæäåíèÿ ïðèåìà êîìàíäû
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
jmp @@End_9
 
; Çàïèñàòü êîä îøèáêè
@@Err1_3:
mov [DevErrorCode],1
jmp @@End_9
@@Err6_1:
mov [DevErrorCode],6
@@End_9:
popad
ret
 
;****************************************************
;* ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå: *
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); *
;* DiskNumber - íîìåð äèñêà (0 èëè 1); *
;* ATAFeatures - "îñîáåííîñòè"; *
;* ATASectorCount - êîëè÷åñòâî ñåêòîðîâ; *
;* ATASectorNumber - íîìåð íà÷àëüíîãî ñåêòîðà; *
;* ATACylinder - íîìåð íà÷àëüíîãî öèëèíäðà; *
;* ATAHead - íîìåð íà÷àëüíîé ãîëîâêè; *
;* ATAAddressMode - ðåæèì àäðåñàöèè (0-CHS, 1-LBA); *
;* ATACommand - êîä êîìàíäû. *
;* Ïîñëå óñïåøíîãî âûïîëíåíèÿ ôóíêöèè: *
;* â ATABasePortAddr - áàçîâûé àäðåñ HDD; *
;* â DevErrorCode - íîëü. *
;* Ïðè âîçíèêíîâåíèè îøèáêè â DevErrorCode áóäåò *
;* âîçâðàùåí êîä îøèáêè. *
;****************************************************
SendCommandToHDD_1:
pushad
; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà
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 ecx,0xfff
mov eax,[timer_ticks]
mov [TickCounter_1],eax
@@WaitHDReady_2:
call change_task
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ
; dec ecx
; cmp ecx,0
; je @@Err1
mov eax,[timer_ticks]
sub eax,[TickCounter_1]
cmp eax,BSYWaitTime ;300 ;îæèäàòü 3 ñåê.
ja @@Err1_4 ;îøèáêà òàéì-àóòà
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíèÿ
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
jmp @@End_10
; Çàïèñàòü êîä îøèáêè
@@Err1_4:
mov [DevErrorCode],1
jmp @@End_10
@@Err2_4:
mov [DevErrorCode],2
jmp @@End_10
@@Err3_4:
mov [DevErrorCode],3
jmp @@End_10
@@Err4_4:
mov [DevErrorCode],4
jmp @@End_10
@@Err5_4:
mov [DevErrorCode],5
; Çàâåðøåíèå ðàáîòû ïðîãðàììû
@@End_10:
sti
popad
ret
;*************************************************
;* ÎÆÈÄÀÍÈÅ ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ Ê ÐÀÁÎÒÅ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;*************************************************
WaitUnitReady:
pusha
; Çàïîìíèòü âðåìÿ íà÷àëà îïåðàöèè
mov EAX,[timer_ticks]
mov [WURStartTime],EAX
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
; Ñôîðìèðîâàòü êîìàíäó TEST UNIT READY
mov [PacketCommand],word 00h
; ÖÈÊË ÎÆÈÄÀÍÈß ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ
@@SendCommand:
; Ïîäàòü êîìàíäó ïðîâåðêè ãîòîâíîñòè
call SendPacketNoDatCommand
call change_task
; Ïðîâåðèòü êîä îøèáêè
cmp [DevErrorCode],0
je @@End_11
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ ãîòîâíîñòè
mov EAX,[timer_ticks]
sub EAX,[WURStartTime]
cmp EAX,MaxCDWaitTime
jb @@SendCommand
; Îøèáêà òàéì-àóòà
mov [DevErrorCode],1
@@End_11:
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 - íîìåð äèñêà íà êàíàëå. *
;*************************************************
UnloadMedium:
pusha
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT
; Çàäàòü êîä êîìàíäû
mov [PacketCommand],word 1Bh
; Çàäàòü îïåðàöèþ èçâëå÷åíèÿ íîñèòåëÿ
mov [PacketCommand+4],word 00000010b
; Ïîäàòü êîìàíäó
call SendPacketNoDatCommand
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:
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
mov [PacketCommand],dword 0
mov [PacketCommand+4],dword 0
mov [PacketCommand+8],dword 0
ret
 
/kernel/trunk/fs/fs_lfn.inc
28,8 → 28,23
db 3,'hd3'
dd fs_OnHd3
dd fs_NextHd3
;**********************************************
db 3,'cd0'
dd fs_OnCd0
dd fs_NextCd
db 3,'cd1'
dd fs_OnCd1
dd fs_NextCd
db 3,'cd2'
dd fs_OnCd2
dd fs_NextCd
db 3,'cd3'
dd fs_OnCd3
dd fs_NextCd
;***********************************************
db 0
 
 
virtual_root_query:
dd fs_HasRamdisk
db 'rd',0
43,6 → 58,16
db 'hd2',0
dd fs_HasHd3
db 'hd3',0
;**********************************************
dd fs_HasCd0
db 'cd0',0
dd fs_HasCd1
db 'cd1',0
dd fs_HasCd2
db 'cd2',0
dd fs_HasCd3
db 'cd3',0
;**********************************************
dd 0
endg
 
420,6 → 445,71
dd fs_HdSetFileInfo
fs_NumHdServices = ($ - fs_HdServices)/4
 
;*******************************************************
fs_OnCd0:
call reserve_cd
mov [ChannelNumber],1
mov [DiskNumber],0
push 6
jmp fs_OnCd
fs_OnCd1:
call reserve_cd
mov [ChannelNumber],1
mov [DiskNumber],1
push 4
jmp fs_OnCd
fs_OnCd2:
call reserve_cd
mov [ChannelNumber],2
mov [DiskNumber],0
push 2
jmp fs_OnCd
fs_OnCd3:
call reserve_cd
mov [ChannelNumber],2
mov [DiskNumber],1
push 0
fs_OnCd:
 
pop eax
mov [hdpos], eax
cmp ecx, 0x100
jae .nf
push cx bx
mov cl,al
mov bl,[0x40001]
shr bl,cl
test bl,2
pop bx cx
 
jnz @f
.nf:
and [cd_status], 0
mov dword [esp+36], 5 ; not found
ret
@@:
mov ecx, [ebx+12]
mov edx, [ebx+16]
add edx, std_application_base_address
mov eax, [ebx]
cmp eax, 1
ja .not_impl
add ebx, 4
call dword [fs_CdServices + eax*4]
and [cd_status], 0
mov [esp+36], eax
mov [esp+24], ebx
ret
.not_impl:
and [hd1_status], 0
mov dword [esp+36], 2 ; not implemented
ret
 
fs_CdServices:
dd fs_CdRead
dd fs_CdReadFolder
;*******************************************************
 
fs_HasRamdisk:
mov al, 1 ; we always have ramdisk
ret
454,6 → 544,33
setz al
ret
 
;*******************************************************
fs_HasCd0:
mov al, [0x40001]
and al, 11000000b
cmp al, 10000000b
setz al
ret
fs_HasCd1:
mov al, [0x40001]
and al, 00110000b
cmp al, 00100000b
setz al
ret
fs_HasCd2:
mov al, [0x40001]
and al, 00001100b
cmp al, 00001000b
setz al
ret
fs_HasCd3:
mov al, [0x40001]
and al, 00000011b
cmp al, 00000010b
setz al
ret
;*******************************************************
 
; fs_NextXXX functions:
; in: eax = partition number, from which start to scan
; out: CF=1 => no more partitions
509,3 → 626,16
inc eax
clc
ret
;*******************************************************
fs_NextCd:
; we always have /cdX/1
test eax, eax
stc
jnz @f
mov al, 1
clc
@@:
ret
;*******************************************************
 
/kernel/trunk/fs/iso9660.inc
0,0 → 1,631
uglobal
cd_current_pointer_of_input dd 0
cd_current_pointer_of_input_2 dd 0
cd_mem_location dd 0
cd_counter_block dd 0
endg
 
CDDataBuf equ 0x7000
 
reserve_cd:
 
cli
cmp [cd_status],0
je reserve_ok2
 
sti
call change_task
jmp reserve_hd1
 
reserve_ok2:
 
push eax
mov eax,[0x3000]
shl eax,5
mov eax,[eax+0x3000+4]
mov [cd_status],eax
pop eax
sti
ret
cd_status dd 0
 
;----------------------------------------------------------------
;
; fs_CdRead - LFN variant for reading CD disk
;
; esi points to filename /dir1/dir2/.../dirn/file,0
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to read, 0+
; edx mem location to return data
;
; ret ebx = bytes read or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
fs_CdRead:
push edi
cmp byte [esi], 0
jnz @f
.noaccess:
pop edi
.noaccess_2:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
.noaccess_3:
pop eax edx ecx edi
jmp .noaccess_2
 
@@:
call cd_find_lfn
jnc .found
pop edi
cmp [DevErrorCode],0
jne .noaccess_2
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.found:
mov edi,[cd_current_pointer_of_input]
test byte [edi+25],10b ; do not allow read directories
jnz .noaccess
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
xor ebx, ebx
.reteof:
mov eax, 6 ; end of file
pop edi
ret
@@:
mov ebx, [ebx]
.l1:
push ecx edx
push 0
mov eax, [edi+10] ; ðåàëüíûé ðàçìåð ôàéëîâîé ñåêöèè
sub eax, ebx
jb .eof
cmp eax, ecx
jae @f
mov ecx, eax
mov byte [esp], 6
@@:
mov eax,[edi+2]
mov [CDSectorAddress],eax
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
.new_sector:
test ecx, ecx
jz .done
sub ebx, 2048
jae .new_sector
add ebx, 2048
jnz .incomplete_sector
cmp ecx, 2048
jb .incomplete_sector
; we may read and memmove complete sector
mov [CDDataBuf_pointer],edx
call ReadCDWRetr ; ÷èòàåì ñåêòîð ôàéëà
cmp [DevErrorCode],0
jne .noaccess_3
inc dword [CDSectorAddress]
add edx, 2048
sub ecx, 2048
jmp .new_sector
.incomplete_sector:
; we must read and memmove incomplete sector
mov [CDDataBuf_pointer],CDDataBuf
call ReadCDWRetr ; ÷èòàåì ñåêòîð ôàéëà
cmp [DevErrorCode],0
jne .noaccess_3
inc dword [CDSectorAddress]
mov eax,CDDataBuf
add eax, ebx
push ecx
add ecx, ebx
cmp ecx, 2048
jbe @f
mov ecx, 2048
@@:
sub ecx, ebx
push edi esi ecx
mov edi,edx
mov esi,eax ;0x7000 ; CD data buffer
cld
rep movsb
pop ecx esi edi
add edx, ecx
sub [esp], ecx
pop ecx
xor ebx, ebx
jmp .new_sector
.done:
mov ebx, edx
pop eax edx ecx edi
sub ebx, edx
ret
.eof:
mov ebx, edx
pop eax edx ecx
sub ebx, edx
jmp .reteof
 
;----------------------------------------------------------------
;
; fs_CdReadFolder - LFN variant for reading CD disk folder
;
; esi points to filename /dir1/dir2/.../dirn/file,0
; ebx pointer to structure 32-bit number = first wanted block, 0+
; & flags (bitfields)
; flags: bit 0: 0=ANSI names, 1=UNICODE names
; ecx number of blocks to read, 0+
; edx mem location to return data
;
; ret ebx = blocks read or 0xffffffff folder not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
fs_CdReadFolder:
push edi
call cd_find_lfn
jnc .found
pop edi
cmp [DevErrorCode],0
jne .noaccess_1
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
.found:
mov edi,[cd_current_pointer_of_input]
test byte [edi+25],10b ; do not allow read directories
jnz .found_dir
pop edi
.noaccess_1:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
.found_dir:
mov eax,[edi+2] ; eax=cluster
mov [CDSectorAddress],eax
mov eax,[edi+10] ; ðàçìåð äèðåêòðîðèè
.doit:
; init header
push eax ecx
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
pop ecx eax
mov byte [edx], 1 ; version
mov [cd_mem_location],edx
add [cd_mem_location],32
; íà÷èíàåì ïåðåáðîñêó ÁÄÂÊ â ÓÑÂÊ
;.mainloop:
mov [cd_counter_block],dword 0
dec dword [CDSectorAddress]
push ecx
.read_to_buffer:
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer],CDDataBuf
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè
cmp [DevErrorCode],0
jne .noaccess_1
call .get_names_from_buffer
sub eax,2048
; äèðåêòîðèÿ çàêîí÷èëàñü?
cmp eax,0
jg .read_to_buffer
mov edi,[cd_counter_block]
mov [edx+8],edi
mov edi,[ebx]
sub [edx+4],edi
pop ecx edi
xor ebx,ebx
mov eax,ERROR_SUCCESS
ret
.get_names_from_buffer:
mov [cd_current_pointer_of_input_2],CDDataBuf
push eax esi edi edx
.get_names_from_buffer_1:
call cd_get_name
jc .end_buffer
inc dword [cd_counter_block]
mov eax,[cd_counter_block]
cmp [ebx],eax
jae .get_names_from_buffer_1
test ecx, ecx
jz .get_names_from_buffer_1
mov edi,[cd_counter_block]
mov [edx+4],edi
dec ecx
mov esi,ebp
mov edi,[cd_mem_location]
add edi,40
test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE
jnz .unicode
; jmp .unicode
.ansi:
cmp [cd_counter_block],2
jbe .ansi_parent_directory
cld
lodsw
xchg ah,al
call uni2ansi_char
cld
stosb
; ïðîâåðêà êîíöà ôàéëà
mov al,[esi+1]
cmp al,byte 3Bh ; ñåïàðàòîð êîíöà ôàéëà ';'
je .cd_get_parameters_of_file_1
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
movzx eax,byte [ebp-33]
add eax,ebp
sub eax,34
cmp esi,eax
je .cd_get_parameters_of_file_1
; ïðîâåðêà êîíöà ïàïêè
movzx eax,byte [ebp-1]
add eax,ebp
cmp esi,eax
jb .ansi
.cd_get_parameters_of_file_1:
mov [edi],byte 0
call .cd_get_parameters_of_file
add [cd_mem_location],304
jmp .get_names_from_buffer_1
 
.ansi_parent_directory:
cmp [cd_counter_block],2
je @f
mov [edi],byte '.'
inc edi
jmp .cd_get_parameters_of_file_1
@@:
mov [edi],word '..'
add edi,2
jmp .cd_get_parameters_of_file_1
 
.unicode:
cmp [cd_counter_block],2
jbe .unicode_parent_directory
cld
movsw
; ïðîâåðêà êîíöà ôàéëà
mov ax,[esi]
cmp ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
je .cd_get_parameters_of_file_2
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
movzx eax,byte [ebp-33]
add eax,ebp
sub eax,34
cmp esi,eax
je .cd_get_parameters_of_file_2
; ïðîâåðêà êîíöà ïàïêè
movzx eax,byte [ebp-1]
add eax,ebp
cmp esi,eax
jb .unicode
.cd_get_parameters_of_file_2:
mov [edi],word 0
call .cd_get_parameters_of_file
add [cd_mem_location],560
jmp .get_names_from_buffer_1
 
.unicode_parent_directory:
cmp [cd_counter_block],2
je @f
mov [edi],word 2E00h ; '.'
add edi,2
jmp .cd_get_parameters_of_file_2
@@:
mov [edi],dword 2E002E00h ; '..'
add edi,4
jmp .cd_get_parameters_of_file_2
 
.cd_get_parameters_of_file:
mov edi,[cd_mem_location]
; ïîëó÷àåì àòðèáóòû ôàéëà
xor eax,eax
; ôàéë íå àðõèâèðîâàëñÿ
inc al
shl eax,1
; ýòî êàòàëîã?
test [ebp-8],byte 2
jz .file
inc al
.file:
; ìåòêà òîìà íå êàê â FAT, â ýòîì âèäå îòñóòñâóåò
; ôàéë íå ÿâëÿåòñÿ ñèñòåìíûì
shl eax,3
; ôàéë ÿâëÿåòñÿ ñêðûòûì? (àòðèáóò ñóùåñòâîâàíèå)
test [ebp-8],byte 1
jz .hidden
inc al
.hidden:
shl eax,1
; ôàéë âñåãäà òîëüêî äëÿ ÷òåíèÿ, òàê êàê ýòî CD
inc al
mov [edi],eax
; ïîëó÷àåì âðåìÿ äëÿ ôàéëà
;÷àñ
movzx eax,byte [ebp-12]
shl eax,8
;ìèíóòà
mov al,[ebp-11]
shl eax,8
;ñåêóíäà
mov al,[ebp-10]
;âðåìÿ ñîçäàíèÿ ôàéëà
mov [edi+8],eax
;âðåìÿ ïîñëåäíåãî äîñòóïà
mov [edi+16],eax
;âðåìÿ ïîñëåäíåé çàïèñè
mov [edi+24],eax
; ïîëó÷àåì äàòó äëÿ ôàéëà
;ãîä
movzx eax,byte [ebp-15]
add eax,1900
shl eax,8
;ìåñÿö
mov al,[ebp-14]
shl eax,8
;äåíü
mov al,[ebp-13]
;äàòà ñîçäàíèÿ ôàéëà
mov [edi+12],eax
;âðåìÿ ïîñëåäíåãî äîñòóïà
mov [edi+20],eax
;âðåìÿ ïîñëåäíåé çàïèñè
mov [edi+28],eax
; ïîëó÷àåì òèï äàííûõ èìåíè
xor eax,eax
test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE
jnz .unicode_1
mov [edi+4],eax
jmp @f
.unicode_1:
inc eax
mov [edi+4],eax
@@:
; ïîëó÷àåì ðàçìåð ôàéëà â áàéòàõ
xor eax,eax
mov [edi+32+4],eax
mov eax,[ebp-23]
mov [edi+32],eax
ret
 
.end_buffer:
pop edx edi esi eax
ret
cd_find_lfn:
; in: esi->name
; out: CF=1 - file not found
; else CF=0 and [cd_current_pointer_of_input] direntry
push eax esi
; 16 ñåêòîð íà÷àëî íàáîðà äåñêðèïòîðîâ òîìîâ
mov [CDSectorAddress],dword 15
.start:
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer],CDDataBuf
call ReadCDWRetr
cmp [DevErrorCode],0
jne .access_denied
; ïðîâåðêà íà âøèâîñòü
cmp [CDDataBuf+1],dword 'CD00'
jne .access_denied
cmp [CDDataBuf+5],byte '1'
jne .access_denied
; ñåêòîð ÿâëÿåòñÿ òåðìèíàòîðîì íàáîð äåñêðèïòîðîâ òîìîâ?
cmp [CDDataBuf],byte 0xff
je .access_denied
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì è óëó÷øåííûì äåñêðèïòîðîì òîìà?
cmp [CDDataBuf],byte 0x2
jne .start
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì äåñêðèïòîðîì òîìà?
cmp [CDDataBuf+6],byte 0x1
jne .start
; ïàðàìåòðû root äèðåêòðîðèè
mov eax,[CDDataBuf+0x9c+2] ; íà÷àëî root äèðåêòðîðèè
mov [CDSectorAddress],eax
mov eax,[CDDataBuf+0x9c+10] ; ðàçìåð root äèðåêòðîðèè
cmp byte [esi], 0
jnz @f
mov [cd_current_pointer_of_input],CDDataBuf+0x9c
jmp .done
@@:
; íà÷èíàåì ïîèñê
.mainloop:
dec dword [CDSectorAddress]
.read_to_buffer:
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer],CDDataBuf
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè
cmp [DevErrorCode],0
jne .access_denied
call cd_find_name_in_buffer
jnc .found
sub eax,2048
; äèðåêòîðèÿ çàêîí÷èëàñü?
cmp eax,0
jg .read_to_buffer
; íåò èñêîìîãî ýëåìåíòà öåïî÷êè
.access_denied:
pop esi eax
stc
ret
; èñêîìûé ýëåìåíò öåïî÷êè íàéäåí
.found:
; êîíåö ïóòè ôàéëà
cmp byte [esi], 0
jz .done
mov eax,[cd_current_pointer_of_input]
add eax,2
mov eax,[eax]
mov [CDSectorAddress],eax ; íà÷àëî äèðåêòîðèè
add eax,8
mov eax,[eax] ; ðàçìåð äèðåêòîðèè
jmp .mainloop
; óêàçàòåëü ôàéëà íàéäåí
.done:
pop esi eax
clc
ret
cd_find_name_in_buffer:
mov [cd_current_pointer_of_input_2],CDDataBuf
.start:
call cd_get_name
jc .not_found
call cd_compare_name
jc .start
.found:
clc
ret
.not_found:
stc
ret
 
cd_get_name:
push eax
mov ebp,[cd_current_pointer_of_input_2]
mov [cd_current_pointer_of_input],ebp
mov eax,[ebp]
cmp eax,0 ; âõîäû çàêîí÷èëèñü?
je .next_sector
cmp ebp,CDDataBuf+2048 ; áóôåð çàêîí÷èëñÿ?
jae .next_sector
movzx eax, byte [ebp]
add [cd_current_pointer_of_input_2],eax ; ñëåäóþùèé âõîä êàòàëîãà
add ebp,33 ; óêàçàòåëü óñòàíîâëåí íà íà÷àëî èìåíè
pop eax
clc
ret
.next_sector:
pop eax
stc
ret
 
cd_compare_name:
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
; in: esi->name, ebp->name
; out: if names match: ZF=1 and esi->next component of name
; else: ZF=0, esi is not changed
; destroys eax
push esi eax edi
mov edi,ebp
.loop:
cld
lodsb
push ax
call char_toupper
call ansi2uni_char
xchg ah,al
cld
scasw
pop ax
je .coincides
call char_todown
call ansi2uni_char
xchg ah,al
cld
sub edi,2
scasw
jne .name_not_coincide
.coincides:
cmp [esi],byte '/' ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
je .done
cmp [esi],byte 0 ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
je .done
jmp .loop
.name_not_coincide:
pop edi eax esi
stc
ret
.done:
; ïðîâåðêà êîíöà ôàéëà
cmp [edi],word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
je .done_1
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
movzx eax,byte [ebp-33]
add eax,ebp
sub eax,34
cmp edi,eax
je .done_1
; ïðîâåðêà êîíöà ïàïêè
movzx eax,byte [ebp-1]
add eax,ebp
cmp edi,eax
jne .name_not_coincide
.done_1:
pop edi eax
add esp,4
inc esi
clc
ret
char_todown:
; convert character to uppercase, using cp866 encoding
; in: al=symbol
; out: al=converted symbol
cmp al, 'A'
jb .ret
cmp al, 'Z'
jbe .az
cmp al, '€'
jb .ret
cmp al, ''
jb .rus1
cmp al, 'Ÿ'
ja .ret
; 0x90-0x9F -> 0xE0-0xEF
add al, 'à'-''
.ret:
ret
.rus1:
; 0x80-0x8F -> 0xA0-0xAF
.az:
add al, 0x20
ret
uni2ansi_char:
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
; in: ax=UNICODE character
; out: al=converted ANSI character
cmp ax, 0x80
jb .ascii
cmp ax, 0x401
jz .yo1
cmp ax, 0x451
jz .yo2
cmp ax, 0x410
jb .unk
cmp ax, 0x440
jb .rus1
cmp ax, 0x450
jb .rus2
.unk:
mov al, '_'
jmp .doit
.yo1:
mov al, 'ð'
jmp .doit
.yo2:
mov al, 'ñ'
jmp .doit
.rus1:
; 0x410-0x43F -> 0x80-0xAF
add al, 0x70
jmp .doit
.rus2:
; 0x440-0x44F -> 0xE0-0xEF
add al, 0xA0
.ascii:
.doit:
ret
/kernel/trunk/kernel32.inc
150,6 → 150,7
include "fs/fat12.inc" ; read / write for fat12 filesystem
include "blkdev/rd.inc" ; ramdisk read /write
include "fs/fs_lfn.inc" ; syscall, version 2
include "fs/iso9660.inc" ; read for iso9660 filesystem CD
 
; sound
 
186,6 → 187,7
; CD drive controller
 
include "blkdev/cdrom.inc"
include "blkdev/cd_drv.inc"
 
; Character devices