;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                                                              ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License    ;;
;;                                                              ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

$Revision$


;******************************************************
; ïîèñê ïðèâîäîâ HDD è CD
; àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷.
; àäàïòàöèÿ è äîðàáîòêà Mario79
;******************************************************

;****************************************************
;*                 ÏÎÈÑÊ HDD è CD                   *
;****************************************************
FindHDD:
        mov     [ChannelNumber], 1
        mov     [DiskNumber], 0
        call    FindHDD_3
;        mov     ax,[Sector512+176]
;        mov     [DRIVE_DATA+6],ax
;        mov     ax,[Sector512+126]
;        mov     [DRIVE_DATA+8],ax
;        mov     ax,[Sector512+128]
;        mov     [DRIVE_DATA+8],ax
        mov     [DiskNumber], 1
        call    FindHDD_3
;        mov     al,[Sector512+176]
;        mov     [DRIVE_DATA+7],al
        inc     [ChannelNumber]
        mov     [DiskNumber], 0
        call    FindHDD_3
;        mov     al,[Sector512+176]
;        mov     [DRIVE_DATA+8],al
        mov     [DiskNumber], 1
        call    FindHDD_1
;        mov     al,[Sector512+176]
;        mov     [DRIVE_DATA+9],al

        jmp     EndFindHDD

FindHDD_1:
        call    ReadHDD_ID
        cmp     [DevErrorCode], 0
        jne     FindHDD_2
        cmp     [Sector512+6], word 16
        ja      FindHDD_2
        cmp     [Sector512+12], word 255
        ja      FindHDD_2
        inc     byte [DRIVE_DATA+1]
        jmp     FindHDD_2_2
   FindHDD_2:
        call    DeviceReset
        cmp     [DevErrorCode], 0
        jne     FindHDD_2_2
        call    ReadCD_ID
        cmp     [DevErrorCode], 0
        jne     FindHDD_2_2
        inc     byte [DRIVE_DATA+1]
        inc     byte [DRIVE_DATA+1]
   FindHDD_2_2:
        ret

FindHDD_3:
        call    FindHDD_1
        shl     byte [DRIVE_DATA+1], 2
        ret


; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà â ðåæèìå LBA
uglobal
SectorAddress   DD ?
endg
;*************************************************
;*     ×ÒÅÍÈÅ ÈÄÅÍÒÈÔÈÊÀÒÎÐÀ ÆÅÑÒÊÎÃÎ ÄÈÑÊÀ      *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå:                                   *
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2);       *
;* DiskNumber - íîìåð äèñêà íà êàíàëå (0 èëè 1). *
;* Èäåíòèôèêàöèîííûé áëîê äàííûõ ñ÷èòûâàåòñÿ     *
;* â ìàññèâ Sector512.                           *
;*************************************************
ReadHDD_ID:
; Çàäàòü ðåæèì CHS
        mov     [ATAAddressMode], 0
; Ïîñëàòü êîìàíäó èäåíòèôèêàöèè óñòðîéñòâà
        mov     [ATAFeatures], 0
        mov     [ATAHead], 0
        mov     [ATACommand], 0ECh
        call    SendCommandToHDD
        cmp     [DevErrorCode], 0;ïðîâåðèòü êîä îøèáêè
        jne     @@End  ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
        mov     DX, [ATABasePortAddr]
        add     DX, 7    ;àäðåñ ðåãèñòðà ñîñòîÿíè
        mov     ecx, 0xffff
@@WaitCompleet:
        ; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
        dec     ecx
;        cmp  ecx,0
        jz      @@Error1  ;îøèáêà òàéì-àóòà
        ; Ïðîâåðèòü ãîòîâíîñòü
        in      AL, DX
        test    AL, 80h  ;ñîñòîÿíèå ñèãíàëà BSY
        jnz     @@WaitCompleet
        test    AL, 1    ;ñîñòîÿíèå ñèãíàëà ERR
        jnz     @@Error6
        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         ;ïðèíÿòü áëîê äàííûõ
        ret
; Çàïèñàòü êîä îøèáêè
@@Error1:
        mov     [DevErrorCode], 1
        ret
@@Error6:
        mov     [DevErrorCode], 6
@@End:
        ret


iglobal
; Ñòàíäàðòíûå áàçîâûå àäðåñà êàíàëîâ 1 è 2
StandardATABases DW 1F0h, 170h
endg
uglobal
; Íîìåð êàíàëà
ChannelNumber   DW ?
; Íîìåð äèñêà
DiskNumber      DB ?
; Áàçîâûé àäðåñ ãðóïïû ïîðòîâ êîíòðîëëåðà 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 - îøèáêà ïðè âûïîëíåíèè
; êîìàíäû)
DevErrorCode dd ?
endg
;****************************************************
;*          ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ         *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå    *
;* ïåðåìåííûå:                                      *
;* 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 ê ïðèåìó êîìàíäû
        ; Âûáðàòü íóæíûé äèñê
        mov     DX, [ATABasePortAddr]
        add     DX, 6   ;àäðåñ ðåãèñòðà ãîëîâîê
        mov     AL, [DiskNumber]
        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   ;îøèáêà òàéì-àóòà
        ; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíè
        in      AL, DX
        ; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY
        test    AL, 80h
        jnz     @@WaitHDReady
        ; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ
        test    AL, 08h
        jnz     @@WaitHDReady
; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà
        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
        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
        ret
; Çàïèñàòü êîä îøèáêè
@@Err1:
        mov     [DevErrorCode], 1
        ret
@@Err2:
        mov     [DevErrorCode], 2
        ret
@@Err3:
        mov     [DevErrorCode], 3
        ret
@@Err4:
        mov     [DevErrorCode], 4
        ret
@@Err5:
        mov     [DevErrorCode], 5
; Çàâåðøåíèå ðàáîòû ïðîãðàììû
        ret

;*************************************************
;*     ×ÒÅÍÈÅ ÈÄÅÍÒÈÔÈÊÀÒÎÐÀ ÓÑÒÐÎÉÑÒÂÀ ATAPI    *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå:                                    *
;* ChannelNumber - íîìåð êàíàëà;                 *
;* DiskNumber - íîìåð äèñêà íà êàíàëå.           *
;* Èäåíòèôèêàöèîííûé áëîê äàííûõ ñ÷èòûâàåòñÿ     *
;* â ìàññèâ Sector512.                           *
;*************************************************
ReadCD_ID:
; Çàäàòü ðåæèì CHS
        mov     [ATAAddressMode], 0
; Ïîñëàòü êîìàíäó èäåíòèôèêàöèè óñòðîéñòâà
        mov     [ATAFeatures], 0
        mov     [ATASectorCount], 0
        mov     [ATASectorNumber], 0
        mov     [ATACylinder], 0
        mov     [ATAHead], 0
        mov     [ATACommand], 0A1h
        call    SendCommandToHDD
        cmp     [DevErrorCode], 0;ïðîâåðèòü êîä îøèáêè
        jne     @@End_1  ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
; Îæèäàòü ãîòîâíîñòü äàííûõ HDD
        mov     DX, [ATABasePortAddr]
        add     DX, 7  ;ïîðò 1õ7h
        mov     ecx, 0xffff
@@WaitCompleet_1:
        ; Ïðîâåðèòü âðåì
        dec     ecx
;        cmp    ecx,0
        jz      @@Error1_1 ;îøèáêà òàéì-àóòà
        ; Ïðîâåðèòü ãîòîâíîñòü
        in      AL, DX
        test    AL, 80h  ;ñîñòîÿíèå ñèãíàëà BSY
        jnz     @@WaitCompleet_1
        test    AL, 1    ;ñîñòîÿíèå ñèãíàëà ERR
        jnz     @@Error6_1
        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;÷èñëî ñ÷èòûâàåìûõ ñëîâ
        rep insw
        ret
; Çàïèñàòü êîä îøèáêè
@@Error1_1:
        mov     [DevErrorCode], 1
        ret
@@Error6_1:
        mov     [DevErrorCode], 6
@@End_1:
        ret

;*************************************************
;*                ÑÁÐÎÑ ÓÑÒÐÎÉÑÒÂÀ               *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå:                                   *
;* 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   ;àäðåñ ðåãèñòðà ãîëîâîê
        mov     AL, [DiskNumber]
        cmp     AL, 1   ;ïðîâåðèòü íîìåðà äèñêà
        ja      @@Err4_2
        shl     AL, 4
        or      AL, 10100000b
        out     DX, AL
; Ïîñëàòü êîìàíäó "Ñáðîñ"
        mov     AL, 08h
        inc     DX      ;ðåãèñòð êîìàíä
        out     DX, AL
        mov     ecx, 0x80000
@@WaitHDReady_1:
        ; Ïðîâåðèòü âðåìÿ îæèäàíè
        dec     ecx
;        cmp     ecx,0
        je      @@Err1_2 ;îøèáêà òàéì-àóòà
        ; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíè
        in      AL, DX
        ; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY
        test    AL, 80h
        jnz     @@WaitHDReady_1
; Ñáðîñèòü ïðèçíàê îøèáêè
        mov     [DevErrorCode], 0
        ret
; Îáðàáîòêà îøèáîê
@@Err1_2:
        mov     [DevErrorCode], 1
        ret
@@Err3_2:
        mov     [DevErrorCode], 3
        ret
@@Err4_2:
        mov     [DevErrorCode], 4
; Çàïèñàòü êîä îøèáêè
        ret

EndFindHDD: