Subversion Repositories Kolibri OS

Rev

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

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