Subversion Repositories Kolibri OS

Rev

Rev 2434 | Rev 3555 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 2465 $
  9.  
  10.  
  11. ;**********************************************************
  12. ;  Íåïîñðåäñòâåííàÿ ðàáîòà ñ óñòðîéñòâîì ÑD (ATAPI)
  13. ;**********************************************************
  14. ; Àâòîð ÷àñòè èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷
  15. ; Àäàïòàöèÿ, äîðàáîòêà è ðàçðàáîòêà Mario79,<Lrz>
  16.  
  17. ; Ìàêñèìàëüíîå êîëè÷åñòâî ïîâòîðåíèé îïåðàöèè ÷òåíèÿ
  18. MaxRetr equ 10
  19. ; Ïðåäåëüíîå âðåìÿ îæèäàíèÿ ãîòîâíîñòè ê ïðèåìó êîìàíäû
  20. ; (â òèêàõ)
  21. BSYWaitTime equ 1000  ;2
  22. NoTickWaitTime equ 0xfffff
  23. CDBlockSize equ 2048
  24. ;********************************************
  25. ;*        ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ Ñ ÏÎÂÒÎÐÀÌÈ        *
  26. ;* Ìíîãîêðàòíîå ïîâòîðåíèå ÷òåíèÿ ïðè ñáîÿõ *
  27. ;********************************************
  28. ReadCDWRetr:
  29. ;-----------------------------------------------------------
  30. ; input  : eax = block to read
  31. ;          ebx = destination
  32. ;-----------------------------------------------------------
  33.     pushad
  34.         mov     eax, [CDSectorAddress]
  35.         mov     ebx, [CDDataBuf_pointer]
  36.     call  cd_calculate_cache
  37.         xor     edi, edi
  38.         add     esi, 8
  39.     inc   edi
  40. .hdreadcache:
  41. ;    cmp   dword [esi+4],0       ; empty
  42. ;    je    .nohdcache
  43.         cmp     [esi], eax      ; correct sector
  44.     je    .yeshdcache
  45. .nohdcache:
  46.         add     esi, 8
  47.     inc   edi
  48.     dec   ecx
  49.     jnz   .hdreadcache
  50.     call  find_empty_slot_CD_cache       ; ret in edi
  51.  
  52.     push  edi
  53.     push  eax
  54.     call  cd_calculate_cache_2
  55.         shl     edi, 11
  56.         add     edi, eax
  57.         mov     [CDDataBuf_pointer], edi
  58.     pop   eax
  59.     pop   edi
  60.  
  61.     call  ReadCDWRetr_1
  62.         cmp     [DevErrorCode], 0
  63.     jne   .exit
  64.  
  65.         mov     [CDDataBuf_pointer], ebx
  66.     call  cd_calculate_cache_1
  67.         lea     esi, [edi*8+esi]
  68.         mov     [esi], eax      ; sector number
  69. ;    mov   dword [esi+4],1       ; hd read - mark as same as in hd
  70. .yeshdcache:
  71.         mov     esi, edi
  72.         shl     esi, 11;9
  73.     push  eax
  74.     call  cd_calculate_cache_2
  75.         add     esi, eax
  76.     pop   eax
  77.         mov     edi, ebx;[CDDataBuf_pointer]
  78.         mov     ecx, 512;/4
  79.     cld
  80.     rep   movsd                 ; move data
  81. .exit:
  82.     popad
  83.     ret
  84.  
  85. ReadCDWRetr_1:
  86.         pushad
  87.  
  88. ; Öèêë, ïîêà êîìàíäà íå âûïîëíåíà óñïåøíî èëè íå
  89. ; èñ÷åðïàíî êîëè÷åñòâî ïîïûòîê
  90.         mov     ECX, MaxRetr
  91. @@NextRetr:
  92. ; Ïîäàòü êîìàíäó
  93. ;*************************************************
  94. ;*      ÏÎËÍÎÅ ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÊÎÌÏÀÊÒ-ÄÈÑÊÀ      *
  95. ;* Ñ÷èòûâàþòñÿ äàííûå ïîëüçîâàòåëÿ, èíôîðìàöèÿ   *
  96. ;* ñóáêàíàëà è êîíòðîëüíàÿ èíôîðìàöèÿ            *
  97. ;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
  98. ;* ïåðìåííûå:                                    *
  99. ;* ChannelNumber - íîìåð êàíàëà;                 *
  100. ;* DiskNumber - íîìåð äèñêà íà êàíàëå;           *
  101. ;* CDSectorAddress - àäðåñ ñ÷èòûâàåìîãî ñåêòîðà. *
  102. ;* Äàííûå ñ÷èòûâàåòñÿ â ìàññèâ CDDataBuf.        *
  103. ;*************************************************
  104. ;ReadCD:
  105.         push    ecx
  106. ;        pusha
  107. ; Çàäàòü ðàçìåð ñåêòîðà
  108. ;        mov       [CDBlockSize],2048 ;2352
  109. ; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
  110.         call  clear_packet_buffer
  111. ; Ñôîðìèðîâàòü ïàêåòíóþ êîìàíäó äëÿ ñ÷èòûâàíèÿ
  112. ; ñåêòîðà äàííûõ
  113. ; Çàäàòü êîä êîìàíäû Read CD
  114.         mov     [PacketCommand], byte 0x28;0xBE
  115. ; Çàäàòü àäðåñ ñåêòîðà
  116.         mov     AX, word [CDSectorAddress+2]
  117.         xchg    AL, AH
  118.         mov     word [PacketCommand+2], AX
  119.         mov     AX, word [CDSectorAddress]
  120.         xchg    AL, AH
  121.         mov     word [PacketCommand+4], AX
  122. ;        mov   eax,[CDSectorAddress]
  123. ;        mov   [PacketCommand+2],eax
  124. ; Çàäàòü êîëè÷åñòâî ñ÷èòûâàåìûõ ñåêòîðîâ
  125.         mov     [PacketCommand+8], byte 1
  126. ; Çàäàòü ñ÷èòûâàíèå äàííûõ â ïîëíîì îáúåìå
  127. ;        mov     [PacketCommand+9],byte 0xF8
  128. ; Ïîäàòü êîìàíäó
  129.         call  SendPacketDatCommand
  130.         pop   ecx
  131. ;        ret
  132.  
  133. ;        cmp       [DevErrorCode],0
  134.         test    eax, eax
  135.         jz    @@End_4
  136.  
  137.         or      ecx, ecx        ;{SPraid.simba} (for cd load)
  138.         jz    @@End_4
  139.         dec   ecx
  140.  
  141.         cmp     [timer_ticks_enable], 0
  142.         jne   @f
  143.         mov     eax, NoTickWaitTime
  144. .wait:
  145.         dec   eax
  146. ;        test  eax,eax
  147.         jz    @@NextRetr
  148.         jmp       .wait
  149. @@:
  150. ; Çàäåðæêà íà 2,5 ñåêóíäû
  151. ;       mov     EAX,[timer_ticks]
  152. ;       add     EAX,50  ;250
  153. ;@@Wait:
  154. ;       call    change_task
  155. ;       cmp     EAX,[timer_ticks]
  156. ;       ja      @@Wait
  157.         loop  @@NextRetr
  158. @@End_4:
  159.         mov     dword [DevErrorCode], eax
  160.         popad
  161.         ret
  162.  
  163.  
  164. ; Óíèâåðñàëüíûå ïðîöåäóðû, îáåñïå÷èâàþùèå âûïîëíåíèå
  165. ;             ïàêåòíûõ êîìàíä â ðåæèìå PIO
  166.  
  167. ; Ìàêñèìàëüíî äîïóñòèìîå âðåìÿ îæèäàíèÿ ðåàêöèè
  168. ; óñòðîéñòâà íà ïàêåòíóþ êîìàíäó (â òèêàõ)
  169.  
  170. MaxCDWaitTime equ 1000 ;200 ;10 ñåêóíä
  171. uglobal
  172. ; Îáëàñòü ïàìÿòè äëÿ ôîðìèðîâàíèÿ ïàêåòíîé êîìàíäû
  173. PacketCommand:
  174.                  rb 12  ;DB 12 DUP (?)
  175. ; Îáëàñòü ïàìÿòè äëÿ ïðèåìà äàííûõ îò äèñêîâîäà
  176. ;CDDataBuf       DB 4096 DUP (0)
  177. ; Ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ â áàéòàõ
  178. ;CDBlockSize     DW ?
  179. ; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà äàííûõ
  180. CDSectorAddress:
  181.                  DD ?
  182. ; Âðåìÿ íà÷àëà î÷åðåäíîé îïåðàöèè ñ äèñêîì
  183. TickCounter_1 DD 0
  184. ; Âðåìÿ íà÷àëà îæèäàíèÿ ãîòîâíîñòè óñòðîéñòâà
  185. WURStartTime DD 0
  186. ; óêàçàòåëü áóôåðà äëÿ ñ÷èòûâàíèÿ
  187. CDDataBuf_pointer dd 0
  188. endg
  189. ;****************************************************
  190. ;*    ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ,    *
  191. ;* ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×Ó ÎÄÍÎÃÎ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ *
  192. ;*     ÐÀÇÌÅÐÎÌ 2048 ÁÀÉÒ ÎÒ ÓÑÒÐÎÉÑÒÂÀ Ê ÕÎÑÒÓ     *
  193. ;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå    *
  194. ;* ïåðìåííûå:                                       *
  195. ;* ChannelNumber - íîìåð êàíàëà;                    *
  196. ;* DiskNumber - íîìåð äèñêà íà êàíàëå;              *
  197. ;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò;      *
  198. ;* CDBlockSize - ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ.  *
  199. ; return eax DevErrorCode
  200. ;****************************************************
  201. SendPacketDatCommand:
  202.         xor     eax, eax
  203. ;        mov    byte [DevErrorCode],al
  204. ; Çàäàòü ðåæèì CHS
  205.         mov     byte [ATAAddressMode], al
  206. ; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû
  207.         mov     byte [ATAFeatures], al
  208.         mov     byte [ATASectorCount], al
  209.         mov     byte [ATASectorNumber], al
  210.         ; Çàãðóçèòü ðàçìåð ïåðåäàâàåìîãî áëîêà
  211.         mov     [ATAHead], al
  212. ;        mov     AX,[CDBlockSize]
  213.         mov     [ATACylinder], CDBlockSize
  214.         mov     [ATACommand], 0A0h
  215.         call    SendCommandToHDD_1
  216.         test    eax, eax
  217. ;        cmp     [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
  218.         jnz     @@End_8    ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
  219.  
  220. ; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó
  221. ; ïàêåòíîé êîìàíäû
  222.         mov     DX, [ATABasePortAddr]
  223.         add     DX, 7    ;ïîðò 1õ7h
  224.         mov     ecx, NoTickWaitTime
  225. @@WaitDevice0:
  226.         cmp     [timer_ticks_enable], 0
  227.         jne     @f
  228.         dec     ecx
  229. ;        test    ecx,ecx
  230.         jz      @@Err1_1
  231.         jmp     .test
  232. @@:
  233.         call    change_task
  234.         ; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
  235.         mov     EAX, [timer_ticks]
  236.         sub     EAX, [TickCounter_1]
  237.         cmp     EAX, BSYWaitTime
  238.         ja      @@Err1_1   ;îøèáêà òàéì-àóòà
  239.         ; Ïðîâåðèòü ãîòîâíîñòü
  240. .test:
  241.         in      AL, DX
  242.         test    AL, 80h  ;ñîñòîÿíèå ñèãíàëà BSY
  243.         jnz     @@WaitDevice0
  244.         test    AL, 1    ;ñîñòîÿíèå ñèãíàëà ERR
  245.         jnz     @@Err6
  246.         test    AL, 08h  ;ñîñòîÿíèå ñèãíàëà DRQ
  247.         jz      @@WaitDevice0
  248. ; Ïîñëàòü ïàêåòíóþ êîìàíäó
  249.         cli
  250.         mov     DX, [ATABasePortAddr]
  251.         mov     AX, [PacketCommand]
  252.         out     DX, AX
  253.         mov     AX, [PacketCommand+2]
  254.         out     DX, AX
  255.         mov     AX, [PacketCommand+4]
  256.         out     DX, AX
  257.         mov     AX, [PacketCommand+6]
  258.         out     DX, AX
  259.         mov     AX, [PacketCommand+8]
  260.         out     DX, AX
  261.         mov     AX, [PacketCommand+10]
  262.         out     DX, AX
  263.         sti
  264. ; Îæèäàíèå ãîòîâíîñòè äàííûõ
  265.         mov     DX, [ATABasePortAddr]
  266.         add     DX, 7  ;ïîðò 1õ7h
  267.         mov     ecx, NoTickWaitTime
  268. @@WaitDevice1:
  269.         cmp     [timer_ticks_enable], 0
  270.         jne     @f
  271.         dec     ecx
  272. ;        test    ecx,ecx
  273.         jz      @@Err1_1
  274.         jmp     .test_1
  275. @@:
  276.         call    change_task
  277.         ; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
  278.         mov     EAX, [timer_ticks]
  279.         sub     EAX, [TickCounter_1]
  280.         cmp     EAX, MaxCDWaitTime
  281.         ja      @@Err1_1   ;îøèáêà òàéì-àóòà
  282.         ; Ïðîâåðèòü ãîòîâíîñòü
  283. .test_1:
  284.         in      AL, DX
  285.         test    AL, 80h  ;ñîñòîÿíèå ñèãíàëà BSY
  286.         jnz     @@WaitDevice1
  287.         test    AL, 1    ;ñîñòîÿíèå ñèãíàëà ERR
  288.         jnz     @@Err6_temp
  289.         test    AL, 08h  ;ñîñòîÿíèå ñèãíàëà DRQ
  290.         jz      @@WaitDevice1
  291. ; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà
  292.         mov     EDI, [CDDataBuf_pointer];0x7000  ;CDDataBuf
  293.         ; Çàãðóçèòü àäðåñ ðåãèñòðà äàííûõ êîíòðîëëåðà
  294.         mov     DX, [ATABasePortAddr];ïîðò 1x0h
  295.         ; Çàãðóçèòü â ñ÷åò÷èê ðàçìåð áëîêà â áàéòàõ
  296.         xor     ecx, ecx
  297.         mov     CX, CDBlockSize
  298.         ; Âû÷èñëèòü ðàçìåð áëîêà â 16-ðàçðÿäíûõ ñëîâàõ
  299.         shr     CX, 1;ðàçäåëèòü ðàçìåð áëîêà íà 2
  300.         ; Ïðèíÿòü áëîê äàííûõ
  301.         cli
  302.         cld
  303.         rep     insw
  304.         sti
  305. ; Óñïåøíîå çàâåðøåíèå ïðèåìà äàííûõ
  306. @@End_8:
  307.         xor     eax, eax
  308.         ret
  309.  
  310. ; Çàïèñàòü êîä îøèáêè
  311. @@Err1_1:
  312.         xor     eax, eax
  313.         inc     eax
  314.         ret
  315. ;        mov     [DevErrorCode],1
  316. ;       ret
  317. @@Err6_temp:
  318.         mov     eax, 7
  319.         ret
  320. ;        mov     [DevErrorCode],7
  321. ;       ret
  322. @@Err6:
  323.         mov     eax, 6
  324.         ret
  325. ;        mov     [DevErrorCode],6
  326. ;@@End_8:
  327. ;        ret
  328.  
  329.  
  330.  
  331. ;***********************************************
  332. ;*  ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, *
  333. ;*     ÍÅ ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×È ÄÀÍÍÛÕ    *
  334. ;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç          *
  335. ;* ãëîáàëüíûå ïåðìåííûå:                       *
  336. ;* ChannelNumber - íîìåð êàíàëà;               *
  337. ;* DiskNumber - íîìåð äèñêà íà êàíàëå;         *
  338. ;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò. *
  339. ;***********************************************
  340. SendPacketNoDatCommand:
  341.         pushad
  342.         xor     eax, eax
  343. ;        mov     byte [DevErrorCode],al
  344. ; Çàäàòü ðåæèì CHS
  345.         mov     byte [ATAAddressMode], al
  346. ; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû
  347.         mov     byte [ATAFeatures], al
  348.         mov     byte [ATASectorCount], al
  349.         mov     byte [ATASectorNumber], al
  350.         mov     word [ATACylinder], ax
  351.         mov     byte [ATAHead], al
  352.         mov     [ATACommand], 0A0h
  353.         call    SendCommandToHDD_1
  354. ;        cmp     [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
  355.         test    eax, eax
  356.         jnz     @@End_9  ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
  357. ; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó
  358. ; ïàêåòíîé êîìàíäû
  359.         mov     DX, [ATABasePortAddr]
  360.         add     DX, 7  ;ïîðò 1õ7h
  361. @@WaitDevice0_1:
  362.         call    change_task
  363.         ; Ïðîâåðèòü âðåìÿ îæèäàíèÿ
  364.         mov     EAX, [timer_ticks]
  365.         sub     EAX, [TickCounter_1]
  366.         cmp     EAX, BSYWaitTime
  367.         ja      @@Err1_3   ;îøèáêà òàéì-àóòà
  368.         ; Ïðîâåðèòü ãîòîâíîñòü
  369.         in      AL, DX
  370.         test    AL, 80h  ;ñîñòîÿíèå ñèãíàëà BSY
  371.         jnz     @@WaitDevice0_1
  372.         test    AL, 1    ;ñîñòîÿíèå ñèãíàëà ERR
  373.         jnz     @@Err6_1
  374.         test    AL, 08h  ;ñîñòîÿíèå ñèãíàëà DRQ
  375.         jz      @@WaitDevice0_1
  376. ; Ïîñëàòü ïàêåòíóþ êîìàíäó
  377. ;        cli
  378.         mov     DX, [ATABasePortAddr]
  379.         mov     AX, word [PacketCommand]
  380.         out     DX, AX
  381.         mov     AX, word [PacketCommand+2]
  382.         out     DX, AX
  383.         mov     AX, word [PacketCommand+4]
  384.         out     DX, AX
  385.         mov     AX, word [PacketCommand+6]
  386.         out     DX, AX
  387.         mov     AX, word [PacketCommand+8]
  388.         out     DX, AX
  389.         mov     AX, word [PacketCommand+10]
  390.         out     DX, AX
  391. ;        sti
  392.         cmp     [ignore_CD_eject_wait], 1
  393.         je  @@clear_DEC
  394. ; Îæèäàíèå ïîäòâåðæäåíèÿ ïðèåìà êîìàíäû
  395.         mov     DX, [ATABasePortAddr]
  396.         add     DX, 7  ;ïîðò 1õ7h
  397. @@WaitDevice1_1:
  398.         call    change_task
  399.         ; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
  400.         mov     EAX, [timer_ticks]
  401.         sub     EAX, [TickCounter_1]
  402.         cmp     EAX, MaxCDWaitTime
  403.         ja      @@Err1_3   ;îøèáêà òàéì-àóòà
  404.         ; Îæèäàòü îñâîáîæäåíèÿ óñòðîéñòâà
  405.         in      AL, DX
  406.         test    AL, 80h  ;ñîñòîÿíèå ñèãíàëà BSY
  407.         jnz     @@WaitDevice1_1
  408.         test    AL, 1    ;ñîñòîÿíèå ñèãíàëà ERR
  409.         jnz     @@Err6_1
  410.         test    AL, 40h  ;ñîñòîÿíèå ñèãíàëà DRDY
  411.         jz      @@WaitDevice1_1
  412. @@clear_DEC:
  413.         and     [DevErrorCode], 0
  414.         popad
  415.         ret
  416. ; Çàïèñàòü êîä îøèáêè
  417. @@Err1_3:
  418.         xor     eax, eax
  419.         inc     eax
  420.         jmp @@End_9
  421. @@Err6_1:
  422.         mov     eax, 6
  423. @@End_9:
  424.         mov     [DevErrorCode], eax
  425.         popad
  426.         ret
  427.  
  428. ;****************************************************
  429. ;*          ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ         *
  430. ;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå    *
  431. ;* ïåðåìåííûå:                                      *
  432. ;* ChannelNumber - íîìåð êàíàëà (1 èëè 2);          *
  433. ;* DiskNumber - íîìåð äèñêà (0 èëè 1);              *
  434. ;* ATAFeatures - "îñîáåííîñòè";                     *
  435. ;* ATASectorCount - êîëè÷åñòâî ñåêòîðîâ;            *
  436. ;* ATASectorNumber - íîìåð íà÷àëüíîãî ñåêòîðà;      *
  437. ;* ATACylinder - íîìåð íà÷àëüíîãî öèëèíäðà;         *
  438. ;* ATAHead - íîìåð íà÷àëüíîé ãîëîâêè;               *
  439. ;* ATAAddressMode - ðåæèì àäðåñàöèè (0-CHS, 1-LBA); *
  440. ;* ATACommand - êîä êîìàíäû.                        *
  441. ;* Ïîñëå óñïåøíîãî âûïîëíåíèÿ ôóíêöèè:              *
  442. ;* â ATABasePortAddr - áàçîâûé àäðåñ HDD;           *
  443. ;* â DevErrorCode - íîëü.                           *
  444. ;* Ïðè âîçíèêíîâåíèè îøèáêè â DevErrorCode áóäåò    *
  445. ;* âîçâðàùåí êîä îøèáêè â eax                       *
  446. ;****************************************************
  447. SendCommandToHDD_1:
  448. ;        pushad
  449. ;        mov    [DevErrorCode],0        not need
  450. ; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà
  451.         cmp     [ATAAddressMode], 1
  452.         ja      @@Err2_4
  453. ; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà
  454.         mov     BX, [ChannelNumber]
  455.         cmp     BX, 1
  456.         jb      @@Err3_4
  457.         cmp     BX, 2
  458.         ja      @@Err3_4
  459. ; Óñòàíîâèòü áàçîâûé àäðåñ
  460.         dec     BX
  461.         shl     BX, 1
  462.         movzx   ebx, bx
  463.         mov     AX, [ebx+StandardATABases]
  464.         mov     [ATABasePortAddr], AX
  465. ; Îæèäàíèå ãîòîâíîñòè HDD ê ïðèåìó êîìàíäû
  466.         ; Âûáðàòü íóæíûé äèñê
  467.         mov     DX, [ATABasePortAddr]
  468.         add     DX, 6   ;àäðåñ ðåãèñòðà ãîëîâîê
  469.         mov     AL, [DiskNumber]
  470.         cmp     AL, 1   ;ïðîâåðèòü íîìåðà äèñêà
  471.         ja      @@Err4_4
  472.         shl     AL, 4
  473.         or      AL, 10100000b
  474.         out     DX, AL
  475.         ; Îæèäàòü, ïîêà äèñê íå áóäåò ãîòîâ
  476.         inc     DX
  477.         mov     eax, [timer_ticks]
  478.         mov     [TickCounter_1], eax
  479.         mov     ecx, NoTickWaitTime
  480. @@WaitHDReady_2:
  481.         cmp     [timer_ticks_enable], 0
  482.         jne    @f
  483.         dec    ecx
  484. ;        test   ecx,ecx
  485.         jz     @@Err1_4
  486.         jmp    .test
  487. @@:
  488.         call    change_task
  489.         ; Ïðîâåðèòü âðåìÿ îæèäàíèÿ
  490.         mov     eax, [timer_ticks]
  491.         sub     eax, [TickCounter_1]
  492.         cmp     eax, BSYWaitTime;300    ;îæèäàòü 3 ñåê.
  493.         ja      @@Err1_4   ;îøèáêà òàéì-àóòà
  494.         ; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíèÿ
  495. .test:
  496.         in      AL, DX
  497.         ; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY
  498.         test    AL, 80h
  499.         jnz     @@WaitHDReady_2
  500.         ; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ
  501.         test    AL, 08h
  502.         jnz     @@WaitHDReady_2
  503.  
  504. ; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà
  505.         cli
  506.         mov     DX, [ATABasePortAddr]
  507.         inc     DX      ;ðåãèñòð "îñîáåííîñòåé"
  508.         mov     AL, [ATAFeatures]
  509.         out     DX, AL
  510.         inc     DX      ;ñ÷åò÷èê ñåêòîðîâ
  511.         mov     AL, [ATASectorCount]
  512.         out     DX, AL
  513.         inc     DX      ;ðåãèñòð íîìåðà ñåêòîðà
  514.         mov     AL, [ATASectorNumber]
  515.         out     DX, AL
  516.         inc     DX      ;íîìåð öèëèíäðà (ìëàäøèé áàéò)
  517.         mov     AX, [ATACylinder]
  518.         out     DX, AL
  519.         inc     DX      ;íîìåð öèëèíäðà (ñòàðøèé áàéò)
  520.         mov     AL, AH
  521.         out     DX, AL
  522.         inc     DX      ;íîìåð ãîëîâêè/íîìåð äèñêà
  523.         mov     AL, [DiskNumber]
  524.         shl     AL, 4
  525.         cmp     [ATAHead], 0Fh;ïðîâåðèòü íîìåð ãîëîâêè
  526.         ja      @@Err5_4
  527.         or      AL, [ATAHead]
  528.         or      AL, 10100000b
  529.         mov     AH, [ATAAddressMode]
  530.         shl     AH, 6
  531.         or      AL, AH
  532.         out     DX, AL
  533. ; Ïîñëàòü êîìàíäó
  534.         mov     AL, [ATACommand]
  535.         inc     DX      ;ðåãèñòð êîìàíä
  536.         out     DX, AL
  537.         sti
  538. ; Ñáðîñèòü ïðèçíàê îøèáêè
  539. ;        mov     [DevErrorCode],0
  540. @@End_10:
  541.         xor     eax, eax
  542.         ret
  543. ; Çàïèñàòü êîä îøèáêè
  544. @@Err1_4:
  545.         xor     eax, eax
  546.         inc     eax
  547. ;        mov     [DevErrorCode],1
  548.         ret
  549. @@Err2_4:
  550.         mov     eax, 2
  551. ;        mov     [DevErrorCode],2
  552.         ret
  553. @@Err3_4:
  554.         mov     eax, 3
  555. ;        mov     [DevErrorCode],3
  556.         ret
  557. @@Err4_4:
  558.         mov     eax, 4
  559. ;        mov     [DevErrorCode],4
  560.         ret
  561. @@Err5_4:
  562.         mov     eax, 5
  563. ;        mov     [DevErrorCode],5
  564. ; Çàâåðøåíèå ðàáîòû ïðîãðàììû
  565.         ret
  566. ;        sti
  567. ;        popad
  568.  
  569. ;*************************************************
  570. ;*    ÎÆÈÄÀÍÈÅ ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ Ê ÐÀÁÎÒÅ    *
  571. ;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
  572. ;* ïåðìåííûå:                                    *
  573. ;* ChannelNumber - íîìåð êàíàëà;                 *
  574. ;* DiskNumber - íîìåð äèñêà íà êàíàëå.           *
  575. ;*************************************************
  576. WaitUnitReady:
  577.         pusha
  578. ; Çàïîìíèòü âðåìÿ íà÷àëà îïåðàöèè
  579.         mov     EAX, [timer_ticks]
  580.         mov     [WURStartTime], EAX
  581. ; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
  582.         call  clear_packet_buffer
  583. ; Ñôîðìèðîâàòü êîìàíäó TEST UNIT READY
  584.         mov     [PacketCommand], word 00h
  585. ; ÖÈÊË ÎÆÈÄÀÍÈß ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ
  586.         mov     ecx, NoTickWaitTime
  587. @@SendCommand:
  588.         ; Ïîäàòü êîìàíäó ïðîâåðêè ãîòîâíîñòè
  589.         call    SendPacketNoDatCommand
  590.         cmp     [timer_ticks_enable], 0
  591.         jne     @f
  592.         cmp     [DevErrorCode], 0
  593.         je      @@End_11
  594.         dec     ecx
  595. ;        cmp     ecx,0
  596.         jz      .Error
  597.         jmp     @@SendCommand
  598. @@:
  599.         call    change_task
  600.         ; Ïðîâåðèòü êîä îøèáêè
  601.         cmp     [DevErrorCode], 0
  602.         je      @@End_11
  603.         ; Ïðîâåðèòü âðåìÿ îæèäàíèÿ ãîòîâíîñòè
  604.         mov     EAX, [timer_ticks]
  605.         sub     EAX, [WURStartTime]
  606.         cmp     EAX, MaxCDWaitTime
  607.         jb      @@SendCommand
  608. .Error:
  609.         ; Îøèáêà òàéì-àóòà
  610.         mov     [DevErrorCode], 1
  611. @@End_11:
  612.         popa
  613.         ret
  614.  
  615. ;*************************************************
  616. ;*            ÇÀÏÐÅÒÈÒÜ ÑÌÅÍÓ ÄÈÑÊÀ              *
  617. ;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
  618. ;* ïåðìåííûå:                                    *
  619. ;* ChannelNumber - íîìåð êàíàëà;                 *
  620. ;* DiskNumber - íîìåð äèñêà íà êàíàëå.           *
  621. ;*************************************************
  622. prevent_medium_removal:
  623.         pusha
  624. ; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
  625.         call  clear_packet_buffer
  626. ; Çàäàòü êîä êîìàíäû
  627.         mov     [PacketCommand], byte 0x1E
  628. ; Çàäàòü êîä çàïðåòà
  629.         mov     [PacketCommand+4], byte 11b
  630. ; Ïîäàòü êîìàíäó
  631.         call SendPacketNoDatCommand
  632.         mov     eax, ATAPI_IDE0_lock
  633.         add     eax, [cdpos]
  634.         dec  eax
  635.         mov     [eax], byte 1
  636.         popa
  637.         ret
  638.  
  639. ;*************************************************
  640. ;*            ÐÀÇÐÅØÈÒÜ ÑÌÅÍÓ ÄÈÑÊÀ              *
  641. ;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
  642. ;* ïåðìåííûå:                                    *
  643. ;* ChannelNumber - íîìåð êàíàëà;                 *
  644. ;* DiskNumber - íîìåð äèñêà íà êàíàëå.           *
  645. ;*************************************************
  646. allow_medium_removal:
  647.         pusha
  648. ; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
  649.         call  clear_packet_buffer
  650. ; Çàäàòü êîä êîìàíäû
  651.         mov     [PacketCommand], byte 0x1E
  652. ; Çàäàòü êîä çàïðåòà
  653.         mov     [PacketCommand+4], byte 00b
  654. ; Ïîäàòü êîìàíäó
  655.         call SendPacketNoDatCommand
  656.         mov     eax, ATAPI_IDE0_lock
  657.         add     eax, [cdpos]
  658.         dec  eax
  659.         mov     [eax], byte 0
  660.         popa
  661.         ret
  662.  
  663. ;*************************************************
  664. ;*         ÇÀÃÐÓÇÈÒÜ ÍÎÑÈÒÅËÜ Â ÄÈÑÊÎÂÎÄ         *
  665. ;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
  666. ;* ïåðìåííûå:                                    *
  667. ;* ChannelNumber - íîìåð êàíàëà;                 *
  668. ;* DiskNumber - íîìåð äèñêà íà êàíàëå.           *
  669. ;*************************************************
  670. LoadMedium:
  671.         pusha
  672. ; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
  673.         call  clear_packet_buffer
  674. ; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT
  675.         ; Çàäàòü êîä êîìàíäû
  676.         mov     [PacketCommand], word 1Bh
  677.         ; Çàäàòü îïåðàöèþ çàãðóçêè íîñèòåëÿ
  678.         mov     [PacketCommand+4], word 00000011b
  679. ; Ïîäàòü êîìàíäó
  680.         call    SendPacketNoDatCommand
  681.         popa
  682.         ret
  683.  
  684. ;*************************************************
  685. ;*         ÈÇÂËÅ×Ü ÍÎÑÈÒÅËÜ ÈÇ ÄÈÑÊÎÂÎÄÀ         *
  686. ;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
  687. ;* ïåðìåííûå:                                    *
  688. ;* ChannelNumber - íîìåð êàíàëà;                 *
  689. ;* DiskNumber - íîìåð äèñêà íà êàíàëå.           *
  690. ;*************************************************
  691. EjectMedium:
  692.         pusha
  693. ; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
  694.         call  clear_packet_buffer
  695. ; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT
  696.         ; Çàäàòü êîä êîìàíäû
  697.         mov     [PacketCommand], word 1Bh
  698.         ; Çàäàòü îïåðàöèþ èçâëå÷åíèÿ íîñèòåëÿ
  699.         mov     [PacketCommand+4], word 00000010b
  700. ; Ïîäàòü êîìàíäó
  701.         call    SendPacketNoDatCommand
  702.         popa
  703.         ret
  704.  
  705. ;*************************************************
  706. ;* Ïðîâåðèòü ñîáûòèå íàæàòèÿ êíîïêè èçâëå÷åíèÿ   *
  707. ;*                     äèñêà                     *
  708. ;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
  709. ;* ïåðåìåííûå:                                   *
  710. ;* ChannelNumber - íîìåð êàíàëà;                 *
  711. ;* DiskNumber - íîìåð äèñêà íà êàíàëå.           *
  712. ;*************************************************
  713. align 4
  714. check_ATAPI_device_event:
  715.         pusha
  716.         mov     eax, [timer_ticks]
  717.         sub     eax, [timer_ATAPI_check]
  718.         cmp     eax, 100
  719.     jb   .end_1
  720.         mov     al, [DRIVE_DATA+1]
  721.         and     al, 11b
  722.         cmp     al, 10b
  723.     jz  .ide3
  724. .ide2_1:
  725.         mov     al, [DRIVE_DATA+1]
  726.         and     al, 1100b
  727.         cmp     al, 1000b
  728.     jz  .ide2
  729. .ide1_1:
  730.         mov     al, [DRIVE_DATA+1]
  731.         and     al, 110000b
  732.         cmp     al, 100000b
  733.     jz  .ide1
  734. .ide0_1:
  735.         mov     al, [DRIVE_DATA+1]
  736.         and     al, 11000000b
  737.         cmp     al, 10000000b
  738.     jz  .ide0
  739. .end:
  740.  
  741.     sti
  742.         mov     eax, [timer_ticks]
  743.         mov     [timer_ATAPI_check], eax
  744. .end_1:
  745.         popa
  746.         ret
  747.  
  748. .ide3:
  749.     cli
  750.         cmp     [ATAPI_IDE3_lock], 1
  751.     jne  .ide2_1
  752.         cmp     [IDE_Channel_2], 0
  753.     jne  .ide1_1
  754.         cmp     [cd_status], 0
  755.     jne  .end
  756.         mov     [IDE_Channel_2], 1
  757.     call reserve_ok2
  758.         mov     [ChannelNumber], 2
  759.         mov     [DiskNumber], 1
  760.         mov     [cdpos], 4
  761.         call GetEvent_StatusNotification
  762.         cmp     [CDDataBuf+4], byte 1
  763.         je   .eject_ide3
  764.         call syscall_cdaudio.free
  765.     jmp  .ide2_1
  766. .eject_ide3:
  767.     call .eject
  768.         call syscall_cdaudio.free
  769.     jmp  .ide2_1
  770.  
  771. .ide2:
  772.     cli
  773.         cmp     [ATAPI_IDE2_lock], 1
  774.     jne  .ide1_1
  775.         cmp     [IDE_Channel_2], 0
  776.     jne  .ide1_1
  777.         cmp     [cd_status], 0
  778.     jne  .end
  779.         mov     [IDE_Channel_2], 1
  780.     call  reserve_ok2
  781.         mov     [ChannelNumber], 2
  782.         mov     [DiskNumber], 0
  783.         mov     [cdpos], 3
  784.         call GetEvent_StatusNotification
  785.         cmp     [CDDataBuf+4], byte 1
  786.         je   .eject_ide2
  787.         call syscall_cdaudio.free
  788.     jmp  .ide1_1
  789. .eject_ide2:
  790.     call .eject
  791.         call syscall_cdaudio.free
  792.     jmp  .ide1_1
  793.  
  794. .ide1:
  795.     cli
  796.         cmp     [ATAPI_IDE1_lock], 1
  797.     jne  .ide0_1
  798.         cmp     [IDE_Channel_1], 0
  799.     jne  .end
  800.         cmp     [cd_status], 0
  801.     jne  .end
  802.         mov     [IDE_Channel_1], 1
  803.     call reserve_ok2
  804.         mov     [ChannelNumber], 1
  805.         mov     [DiskNumber], 1
  806.         mov     [cdpos], 2
  807.         call GetEvent_StatusNotification
  808.         cmp     [CDDataBuf+4], byte 1
  809.         je   .eject_ide1
  810.         call syscall_cdaudio.free
  811.     jmp  .ide0_1
  812. .eject_ide1:
  813.     call .eject
  814.         call syscall_cdaudio.free
  815.     jmp  .ide0_1
  816.  
  817. .ide0:
  818.     cli
  819.         cmp     [ATAPI_IDE0_lock], 1
  820.     jne  .end
  821.         cmp     [IDE_Channel_1], 0
  822.     jne  .end
  823.         cmp     [cd_status], 0
  824.     jne  .end
  825.         mov     [IDE_Channel_1], 1
  826.     call reserve_ok2
  827.         mov     [ChannelNumber], 1
  828.         mov     [DiskNumber], 0
  829.         mov     [cdpos], 1
  830.         call GetEvent_StatusNotification
  831.         cmp     [CDDataBuf+4], byte 1
  832.         je   .eject_ide0
  833.         call syscall_cdaudio.free
  834.     jmp  .end
  835. .eject_ide0:
  836.     call .eject
  837.         call syscall_cdaudio.free
  838.     jmp  .end
  839.  
  840. .eject:
  841.         call clear_CD_cache
  842.         call allow_medium_removal
  843.         mov     [ignore_CD_eject_wait], 1
  844.         call EjectMedium
  845.         mov     [ignore_CD_eject_wait], 0
  846.         ret
  847. iglobal
  848. timer_ATAPI_check dd 0
  849. ATAPI_IDE0_lock db 0
  850. ATAPI_IDE1_lock db 0
  851. ATAPI_IDE2_lock db 0
  852. ATAPI_IDE3_lock db 0
  853. ignore_CD_eject_wait db 0
  854. endg
  855. ;*************************************************
  856. ;* Ïîëó÷èòü ñîîáùåíèå î ñîáûòèè èëè ñîñòîÿíèè    *
  857. ;*                  óñòðîéñòâà                   *
  858. ;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
  859. ;* ïåðåìåííûå:                                   *
  860. ;* ChannelNumber - íîìåð êàíàëà;                 *
  861. ;* DiskNumber - íîìåð äèñêà íà êàíàëå.           *
  862. ;*************************************************
  863. GetEvent_StatusNotification:
  864.         pusha
  865.         mov     [CDDataBuf_pointer], CDDataBuf
  866. ; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
  867.         call  clear_packet_buffer
  868. ; Çàäàòü êîä êîìàíäû
  869.         mov     [PacketCommand], byte 4Ah
  870.         mov     [PacketCommand+1], byte 00000001b
  871. ; Çàäàòü çàïðîñ êëàññà ñîîáùåíèé
  872.         mov     [PacketCommand+4], byte 00010000b
  873. ; Ðàçìåð âûäåëåííîé îáëàñòè
  874.         mov     [PacketCommand+7], byte 8h
  875.         mov     [PacketCommand+8], byte 0h
  876. ; Ïîäàòü êîìàíäó
  877.         call    SendPacketDatCommand
  878.         popa
  879.         ret
  880.  
  881. ;*************************************************
  882. ; ïðî÷èòàòü èíôîðìàöèþ èç TOC
  883. ;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
  884. ;* ïåðåìåííûå:                                   *
  885. ;* ChannelNumber - íîìåð êàíàëà;                 *
  886. ;* DiskNumber - íîìåð äèñêà íà êàíàëå.           *
  887. ;*************************************************
  888. Read_TOC:
  889.         pusha
  890.         mov     [CDDataBuf_pointer], CDDataBuf
  891. ; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
  892.         call  clear_packet_buffer
  893. ; Ñôîðìèðîâàòü ïàêåòíóþ êîìàíäó äëÿ ñ÷èòûâàíèÿ
  894. ; ñåêòîðà äàííûõ
  895.         mov     [PacketCommand], byte 0x43
  896.         ; Çàäàòü ôîðìàò
  897.         mov     [PacketCommand+2], byte 1
  898. ; Ðàçìåð âûäåëåííîé îáëàñòè
  899.         mov     [PacketCommand+7], byte 0xFF
  900.         mov     [PacketCommand+8], byte 0h
  901. ; Ïîäàòü êîìàíäó
  902.         call  SendPacketDatCommand
  903.         popa
  904.         ret
  905.  
  906. ;*************************************************
  907. ;* ÎÏÐÅÄÅËÈÒÜ ÎÁÙÅÅ ÊÎËÈ×ÅÑÒÂÎ ÑÅÊÒÎÐΠÍÀ ÄÈÑÊÅ *
  908. ;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
  909. ;* ïåðåìåííûå:                                   *
  910. ;* ChannelNumber - íîìåð êàíàëà;                 *
  911. ;* DiskNumber - íîìåð äèñêà íà êàíàëå.           *
  912. ;*************************************************
  913. ;ReadCapacity:
  914. ;       pusha
  915. ;; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
  916. ;       call  clear_packet_buffer
  917. ;; Çàäàòü ðàçìåð áóôåðà â áàéòàõ
  918. ;       mov     [CDBlockSize],8
  919. ;; Ñôîðìèðîâàòü êîìàíäó READ CAPACITY
  920. ;       mov     [PacketCommand],word 25h
  921. ;; Ïîäàòü êîìàíäó
  922. ;       call    SendPacketDatCommand
  923. ;       popa
  924. ;       ret
  925.  
  926. clear_packet_buffer:
  927. ; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
  928.         and     [PacketCommand], dword 0
  929.         and     [PacketCommand+4], dword 0
  930.         and     [PacketCommand+8], dword 0
  931.         ret
  932.