Subversion Repositories Kolibri OS

Rev

Rev 8053 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 8054 $
  9.  
  10. ;-----------------------------------------------------------------------------
  11. ;**********************************************************
  12. ;  Direct work with CD (ATAPI) device
  13. ;**********************************************************
  14. ; Author of a part of the source code -  Kulakov Vladimir Gennadievich
  15. ; Adaptation, revision and development -  Mario79, <Lrz>
  16.  
  17. ; Maximum number of repeats of a read operation
  18. MaxRetr = 10
  19. ; Maximum waiting time for ready to receive a command
  20. ; (in ticks)
  21. BSYWaitTime = 1000  ;2
  22. NoTickWaitTime = 0xfffff
  23. CDBlockSize = 2048
  24. ;********************************************
  25. ;*        READING SECTOR WITH REPEATS       *
  26. ;*      Repeated reads on failures          *
  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. ;--------------------------------------
  41. align 4
  42. .hdreadcache:
  43.         cmp     [esi], eax      ; correct sector
  44.         je      .yeshdcache
  45.  
  46.         add     esi, 8
  47.         inc     edi
  48.         dec     ecx
  49.         jnz     .hdreadcache
  50.  
  51.         call    find_empty_slot_CD_cache ; ret in edi
  52.  
  53.         push    edi
  54.         push    eax
  55.         call    cd_calculate_cache_2
  56.         shl     edi, 11
  57.         add     edi, eax
  58.         mov     [CDDataBuf_pointer], edi
  59.         pop     eax
  60.         pop     edi
  61.  
  62.         call    ReadCDWRetr_1
  63.         cmp     [DevErrorCode], 0
  64.         jne     .exit
  65.  
  66.         mov     [CDDataBuf_pointer], ebx
  67.         call    cd_calculate_cache_1
  68.         lea     esi, [edi*8+esi]
  69.         mov     [esi], eax      ; sector number
  70. ;--------------------------------------
  71. .yeshdcache:
  72.         mov     esi, edi
  73.         shl     esi, 11 ;9
  74.         push    eax
  75.         call    cd_calculate_cache_2
  76.         add     esi, eax
  77.         pop     eax
  78.         mov     edi, ebx ;[CDDataBuf_pointer]
  79.         mov     ecx, 512 ;/4
  80.         cld
  81.         rep movsd               ; move data
  82. ;--------------------------------------
  83. .exit:
  84.         popad
  85.         ret
  86. ;-----------------------------------------------------------------------------
  87. ReadCDWRetr_1:
  88.         pushad
  89. ; Loop until the command is successful or the number of attempts is over
  90.         mov     ecx, MaxRetr
  91. ;--------------------------------------
  92. align 4
  93. @@NextRetr:
  94. ; Send a command
  95. ;*************************************************
  96. ;*      FULL READ OF COMPACT DISK SECTOR         *
  97. ;* User data, subchannel                         *
  98. ;* information and control information are read  *
  99. ;* Input parameters are passed through global    *
  100. ;* variables:                                    *
  101. ;* ChannelNumber - channel number;               *
  102. ;* DiskNumber - disc number on channel;          *
  103. ;* CDSectorAddress - address of reading sector.  *
  104. ;* The data is read into the CDDataBuf array.    *
  105. ;*************************************************
  106. ;ReadCD:
  107.         push    ecx
  108. ; Flush the packet command buffer
  109.         call    clear_packet_buffer
  110. ; Generate a packet command to read a data sector
  111. ; Set the command code Read CD
  112.         mov     [PacketCommand], byte 0x28 ;0xBE
  113. ; Set the sector address
  114.         mov     ax, word [CDSectorAddress+2]
  115.         xchg    al, ah
  116.         mov     word [PacketCommand+2], ax
  117.         mov     ax, word [CDSectorAddress]
  118.         xchg    al, ah
  119.         mov     word [PacketCommand+4], ax
  120. ; Set the number of sectors to read
  121.         mov     [PacketCommand+8], byte 1
  122. ; Send a command
  123.         call    SendPacketDatCommand
  124.         pop     ecx
  125.  
  126.         test    eax, eax
  127.         jz      @@End_4
  128.  
  129.         or      ecx, ecx        ;{SPraid.simba} (for cd load)
  130.         jz      @@End_4
  131.  
  132.         dec     ecx
  133.  
  134.         cmp     [timer_ticks_enable], 0
  135.         jne     @f
  136.  
  137.         mov     eax, NoTickWaitTime
  138. ;--------------------------------------
  139. align 4
  140. .wait:
  141.         dec     eax
  142.         jz      @@NextRetr
  143.  
  144.         jmp     .wait
  145. ;--------------------------------------
  146. align 4
  147. @@:
  148.         loop    @@NextRetr
  149. ;--------------------------------------
  150. @@End_4:
  151.         mov     dword [DevErrorCode], eax
  152.         popad
  153.         ret
  154. ;-----------------------------------------------------------------------------
  155. ; General purpose procedures to execute packet commands in PIO Mode
  156. ; Maximum allowable waiting time for the device to respond to a packet command (in ticks)
  157. ;-----------------------------------------------------------------------------
  158. MaxCDWaitTime = 1000 ;200 ;10 seconds
  159. uglobal
  160. ; Memory area for generating a packet command
  161. PacketCommand:
  162.                  rb 12  ;DB 12 DUP (?)
  163. ; address of reading data sector
  164. CDSectorAddress:   dd ?
  165. ; Start time of the next disk operation
  166. TickCounter_1     dd 0
  167. ; Time to start waiting for device readiness
  168. WURStartTime      dd 0
  169. ; pointer to buffer to read data into
  170. CDDataBuf_pointer dd 0
  171. endg
  172. ;-----------------------------------------------------------------------------
  173. ;****************************************************
  174. ;*    SEND TO ATAPI DEVICE PACKET COMMAND,          *
  175. ;* THAT MEANS TRASMIT ONE DATA SECTOR OF SIZE       *
  176. ;*     2048 BYTE FROM DEVICE TO HOST                *
  177. ;* Input parameters are passed through global       *
  178. ;* variables:                                       *
  179. ;* ChannelNumber - channel number;                  *
  180. ;* DiskNumber - disk number on channel.             *
  181. ;* PacketCommand - 12-byte command packet;          *
  182. ;* CDBlockSize - size of receiving data block.      *
  183. ; return eax DevErrorCode
  184. ;****************************************************
  185. SendPacketDatCommand:
  186.         xor     eax, eax
  187. ; Set CHS mode
  188.         mov     byte [ATAAddressMode], al
  189. ; Send ATA command to send packet command
  190.         mov     byte [ATAFeatures], al
  191.         mov     byte [ATASectorCount], al
  192.         mov     byte [ATASectorNumber], al
  193. ; Load the size of the sending block
  194.         mov     [ATAHead], al
  195.         mov     [ATACylinder], CDBlockSize
  196.         mov     [ATACommand], 0xA0
  197.         call    SendCommandToHDD_1
  198.         test    eax, eax
  199.         jnz     @@End_8    ; finish, saving the error code
  200. ; Waiting for the drive to be ready to receive a packet command
  201.         mov     dx, [ATABasePortAddr]
  202.         add     dx, 7    ; port 1x7h
  203.         mov     ecx, NoTickWaitTime
  204. ;--------------------------------------
  205. align 4
  206. @@WaitDevice0:
  207.         cmp     [timer_ticks_enable], 0
  208.         jne     @f
  209.  
  210.         dec     ecx
  211.         jz      @@Err1_1
  212.  
  213.         jmp     .test
  214. ;--------------------------------------
  215. align 4
  216. @@:
  217.         call    change_task
  218.         ; Check command execution time
  219.         mov     eax, [timer_ticks]
  220.         sub     eax, [TickCounter_1]
  221.         cmp     eax, BSYWaitTime
  222.         ja      @@Err1_1   ; time out error
  223.         ; Check readiness
  224. ;--------------------------------------
  225. align 4
  226. .test:
  227.         in      al, dx
  228.         test    al, 0x80  ; BSY signal state
  229.         jnz     @@WaitDevice0
  230.  
  231.         test    al, 1     ; ERR signal state
  232.         jnz     @@Err6
  233.  
  234.         test    al, 0x8   ; DRQ signal state
  235.         jz      @@WaitDevice0
  236. ; Send a packet command
  237.         cli
  238.         mov     dx, [ATABasePortAddr]
  239.         mov     ax, [PacketCommand]
  240.         out     dx, ax
  241.         mov     ax, [PacketCommand+2]
  242.         out     dx, ax
  243.         mov     ax, [PacketCommand+4]
  244.         out     dx, ax
  245.         mov     ax, [PacketCommand+6]
  246.         out     dx, ax
  247.         mov     ax, [PacketCommand+8]
  248.         out     dx, ax
  249.         mov     ax, [PacketCommand+10]
  250.         out     dx, ax
  251.         sti
  252. ; Waiting for data to be ready
  253.         mov     dx, [ATABasePortAddr]
  254.         add     dx, 7  ; port 1x7h
  255.         mov     ecx, NoTickWaitTime
  256. ;--------------------------------------
  257. align 4
  258. @@WaitDevice1:
  259.         cmp     [timer_ticks_enable], 0
  260.         jne     @f
  261.  
  262.         dec     ecx
  263.         jz      @@Err1_1
  264.  
  265.         jmp     .test_1
  266. ;--------------------------------------
  267. align 4
  268. @@:
  269.         call    change_task
  270.         ; Check command execution time
  271.         mov     eax, [timer_ticks]
  272.         sub     eax, [TickCounter_1]
  273.         cmp     eax, MaxCDWaitTime
  274.         ja      @@Err1_1   ; time out error
  275.         ; Check readiness
  276. ;--------------------------------------
  277. align 4
  278. .test_1:
  279.         in      al, dx
  280.         test    al, 0x80  ; BSY signal state
  281.         jnz     @@WaitDevice1
  282.  
  283.         test    al, 1    ; ERR signal state
  284.         jnz     @@Err6_temp
  285.  
  286.         test    al, 0x8  ; DRQ signal state
  287.         jz      @@WaitDevice1
  288. ; Receive data block from controller
  289.         mov     edi, [CDDataBuf_pointer]
  290.         ; Load controller's data register address
  291.         mov     dx, [ATABasePortAddr]
  292.         ; Load the block size in bytes into the counter
  293.         xor     ecx, ecx
  294.         mov     cx, CDBlockSize
  295.         ; Calculate block size in 16-bit words
  296.         shr     cx, 1 ; divide block size by 2
  297.         ; Receive data block
  298.         cli
  299.         cld
  300.         rep insw
  301.         sti
  302. ;--------------------------------------
  303. ; Successful completion of data receive
  304. @@End_8:
  305.         xor     eax, eax
  306.         ret
  307. ;--------------------------------------
  308. ; Write error code
  309. @@Err1_1:
  310.         xor     eax, eax
  311.         inc     eax
  312.         ret
  313. ;--------------------------------------
  314. @@Err6_temp:
  315.         mov     eax, 7
  316.         ret
  317. ;--------------------------------------
  318. @@Err6:
  319.         mov     eax, 6
  320.         ret
  321. ;-----------------------------------------------------------------------------
  322. ;***********************************************
  323. ;*  SEND TO ATAPI DEVICE PACKET COMMAND,       *
  324. ;*     THAT DOESNT MEAN TRANSMIT DATA          *
  325. ;* Input parameters are passed through global  *
  326. ;* variables:                                  *
  327. ;* ChannelNumber - channel number;             *
  328. ;* DiskNumber - disk number on channel.        *
  329. ;* PacketCommand - 12-byte command packet.     *
  330. ;***********************************************
  331. SendPacketNoDatCommand:
  332.         pushad
  333.         xor     eax, eax
  334. ; Set CHS mode
  335.         mov     byte [ATAAddressMode], al
  336. ; Send ATA command to send packet command
  337.         mov     byte [ATAFeatures], al
  338.         mov     byte [ATASectorCount], al
  339.         mov     byte [ATASectorNumber], al
  340.         mov     word [ATACylinder], ax
  341.         mov     byte [ATAHead], al
  342.         mov     [ATACommand], 0xA0
  343.         call    SendCommandToHDD_1
  344.         test    eax, eax
  345.         jnz     @@End_9  ; finish, saving the error code
  346. ; Waiting for the drive to be ready to receive a packet command
  347.         mov     dx, [ATABasePortAddr]
  348.         add     dx, 7  ; port 1x7h
  349. ;--------------------------------------
  350. align 4
  351. @@WaitDevice0_1:
  352.         call    change_task
  353.         ; Check waiting time
  354.         mov     eax, [timer_ticks]
  355.         sub     eax, [TickCounter_1]
  356.         cmp     eax, BSYWaitTime
  357.         ja      @@Err1_3  ; time out error
  358.         ; Check readiness
  359.         in      al, dx
  360.         test    al, 0x80  ; BSY signal state
  361.         jnz     @@WaitDevice0_1
  362.  
  363.         test    al, 1     ; ERR signal state
  364.         jnz     @@Err6_1
  365.  
  366.         test    al, 0x8   ; DRQ signal state
  367.         jz      @@WaitDevice0_1
  368. ; Send packet command
  369. ;        cli
  370.         mov     dx, [ATABasePortAddr]
  371.         mov     ax, word [PacketCommand]
  372.         out     dx, ax
  373.         mov     ax, word [PacketCommand+2]
  374.         out     dx, ax
  375.         mov     ax, word [PacketCommand+4]
  376.         out     dx, ax
  377.         mov     ax, word [PacketCommand+6]
  378.         out     dx, ax
  379.         mov     ax, word [PacketCommand+8]
  380.         out     dx, ax
  381.         mov     ax, word [PacketCommand+10]
  382.         out     dx, ax
  383. ;        sti
  384.         cmp     [ignore_CD_eject_wait], 1
  385.         je      @@clear_DEC
  386. ; Waiting for confirmation of command receive
  387.         mov     dx, [ATABasePortAddr]
  388.         add     dx, 7  ; port 1x7h
  389. ;--------------------------------------
  390. align 4
  391. @@WaitDevice1_1:
  392.         call    change_task
  393.         ; Check command execution time
  394.         mov     eax, [timer_ticks]
  395.         sub     eax, [TickCounter_1]
  396.         cmp     eax, MaxCDWaitTime
  397.         ja      @@Err1_3   ; time out error
  398.         ; Wait for device release
  399.         in      al, dx
  400.         test    al, 0x80   ; BSY signal state
  401.         jnz     @@WaitDevice1_1
  402.  
  403.         test    al, 1      ; ERR signal state
  404.         jnz     @@Err6_1
  405.  
  406.         test    al, 0x40   ; DRDY signal state
  407.         jz      @@WaitDevice1_1
  408. ;--------------------------------------
  409. @@clear_DEC:
  410.         and     [DevErrorCode], 0
  411.         popad
  412.         ret
  413. ;--------------------------------------
  414. ; Write error code
  415. @@Err1_3:
  416.         xor     eax, eax
  417.         inc     eax
  418.         jmp     @@End_9
  419. ;--------------------------------------
  420. @@Err6_1:
  421.         mov     eax, 6
  422. ;--------------------------------------
  423. @@End_9:
  424.         mov     [DevErrorCode], eax
  425.         popad
  426.         ret
  427. ;-----------------------------------------------------------------------------
  428. ;****************************************************
  429. ;*          SEND COMMAND TO GIVEN DISK              *
  430. ;* Input parameters are passed through the global   *
  431. ;* variables:                                       *
  432. ;* ChannelNumber - channel number (1 or 2);         *
  433. ;* DiskNumber - disk number (0 or 1);               *
  434. ;* ATAFeatures - "features";                        *
  435. ;* ATASectorCount - sector count;                   *
  436. ;* ATASectorNumber - initial sector number;         *
  437. ;* ATACylinder - initial cylinder number;           *
  438. ;* ATAHead - initial head number;                   *
  439. ;* ATAAddressMode - addressing mode (0-CHS, 1-LBA); *
  440. ;* ATACommand - command code.                       *
  441. ;* If the function finished successfully:           *
  442. ;* in ATABasePortAddr - base address of HDD;        *
  443. ;* in DevErrorCode - zero.                          *
  444. ;* If error has occured then in DevErrorCode will   *
  445. ;* be the error code.                               *
  446. ;****************************************************
  447. SendCommandToHDD_1:
  448. ; Check the addressing mode code
  449.         cmp     [ATAAddressMode], 1
  450.         ja      @@Err2_4
  451. ; Check the channel number correctness
  452.         movzx   ebx, [ChannelNumber]
  453.         dec     ebx
  454.         cmp     ebx, 1
  455.         ja      @@Err3_4
  456. ; Set the base address
  457.         shl     ebx, 2
  458.         mov     eax, [cdpos]
  459.         dec     eax
  460.         shr     eax, 2
  461.         imul    eax, sizeof.IDE_DATA
  462.         add     eax, IDE_controller_1
  463.         add     eax, ebx
  464.         mov     ax, [eax+IDE_DATA.BAR0_val]
  465.         mov     [ATABasePortAddr], ax
  466. ; Waiting for HDD ready to receive a command
  467.         ; Choose desired disk
  468.         mov     dx, [ATABasePortAddr]
  469.         add     dx, 6   ; address of the heads register
  470.         mov     al, [DiskNumber]
  471.         cmp     al, 1   ; check the disk number
  472.         ja      @@Err4_4
  473.  
  474.         shl     al, 4
  475.         or      al, 10100000b
  476.         out     dx, al
  477.         ; Waiting for disk ready
  478.         inc     dx
  479.         mov     eax, [timer_ticks]
  480.         mov     [TickCounter_1], eax
  481.         mov     ecx, NoTickWaitTime
  482. ;--------------------------------------
  483. align 4
  484. @@WaitHDReady_2:
  485.         cmp     [timer_ticks_enable], 0
  486.         jne     @f
  487.  
  488.         dec     ecx
  489.         jz      @@Err1_4
  490.  
  491.         jmp     .test
  492. ;--------------------------------------
  493. align 4
  494. @@:
  495.         call    change_task
  496.         ; Check waiting time
  497.         mov     eax, [timer_ticks]
  498.         sub     eax, [TickCounter_1]
  499.         cmp     eax, BSYWaitTime ;300    ; wait for 3 seconds
  500.         ja      @@Err1_4   ; time out error
  501. ;--------------------------------------
  502. align 4
  503. .test:
  504.         in      al, dx ; Read the state register
  505.         ; Check the state of BSY signal
  506.         test    al, 0x80
  507.         jnz     @@WaitHDReady_2
  508.         ; Check the state of DRQ signal
  509.         test    al, 0x8
  510.         jnz     @@WaitHDReady_2
  511. ; load command to controller's registers
  512.         cli
  513.         mov     dx, [ATABasePortAddr]
  514.         inc     dx      ; "features" register
  515.         mov     al, [ATAFeatures]
  516.         out     dx, al
  517.         inc     dx      ; sector counter
  518.         mov     al, [ATASectorCount]
  519.         out     dx, al
  520.         inc     dx      ; sector number register
  521.         mov     al, [ATASectorNumber]
  522.         out     dx, al
  523.         inc     dx      ; cylinder number (low byte)
  524.         mov     ax, [ATACylinder]
  525.         out     dx, al
  526.         inc     dx      ; cylinder number (high byte)
  527.         mov     al, ah
  528.         out     dx, al
  529.         inc     dx      ; head number / disk number
  530.         mov     al, [DiskNumber]
  531.         shl     al, 4
  532.         cmp     [ATAHead], 0xF ; check head number
  533.         ja      @@Err5_4
  534.  
  535.         or      al, [ATAHead]
  536.         or      al, 10100000b
  537.         mov     ah, [ATAAddressMode]
  538.         shl     ah, 6
  539.         or      al, ah
  540.         out     dx, al
  541. ; Send command
  542.         mov     al, [ATACommand]
  543.         inc     dx      ; command register
  544.         out     dx, al
  545.         sti
  546. ;--------------------------------------
  547. @@End_10:
  548.         xor     eax, eax
  549.         ret
  550. ;--------------------------------------
  551. ; Write error code
  552. @@Err1_4:
  553.         xor     eax, eax
  554.         inc     eax
  555.         ret
  556. ;--------------------------------------
  557. @@Err2_4:
  558.         mov     eax, 2
  559.         ret
  560. ;--------------------------------------
  561. @@Err3_4:
  562.         mov     eax, 3
  563.         ret
  564. ;--------------------------------------
  565. @@Err4_4:
  566.         mov     eax, 4
  567.         ret
  568. ;--------------------------------------
  569. @@Err5_4:
  570.         mov     eax, 5
  571.         ret
  572. ;-----------------------------------------------------------------------------
  573. ;*************************************************
  574. ;*    WAIT FOR THE DEVICE IS READY FOR WORK      *
  575. ;* Input parameters are passed through global    *
  576. ;* variables:                                    *
  577. ;* ChannelNumber - channel number;               *
  578. ;* DiskNumber - disk number on channel.          *
  579. ;*************************************************
  580. WaitUnitReady:
  581.         pusha
  582. ; Remember the peration start time
  583.         mov     eax, [timer_ticks]
  584.         mov     [WURStartTime], eax
  585. ; Clear the packet command buffer
  586.         call    clear_packet_buffer
  587. ; Generate TEST UNIT READY command
  588.         mov     [PacketCommand], word 0
  589. ; waiting loop for device readiness
  590.         mov     ecx, NoTickWaitTime
  591. ;--------------------------------------
  592. align 4
  593. @@SendCommand:
  594.         ; Send readiness check command
  595.         call    SendPacketNoDatCommand
  596.         cmp     [timer_ticks_enable], 0
  597.         jne     @f
  598.  
  599.         cmp     [DevErrorCode], 0
  600.         je      @@End_11
  601.  
  602.         dec     ecx
  603.         jz      .Error
  604.  
  605.         jmp     @@SendCommand
  606. ;--------------------------------------
  607. align 4
  608. @@:
  609.         call    change_task
  610.         ; Check the error code
  611.         cmp     [DevErrorCode], 0
  612.         je      @@End_11
  613.         ; Check waiting time
  614.         mov     eax, [timer_ticks]
  615.         sub     eax, [WURStartTime]
  616.         cmp     eax, MaxCDWaitTime
  617.         jb      @@SendCommand
  618. ;--------------------------------------
  619. .Error:
  620.         ; time out error
  621.         mov     [DevErrorCode], 1
  622. ;--------------------------------------
  623. @@End_11:
  624.         popa
  625.         ret
  626. ;-----------------------------------------------------------------------------
  627. ;*************************************************
  628. ;*            FORBID DISK CHANGE                 *
  629. ;* Input parameters are passed through global    *
  630. ;* variables:                                    *
  631. ;* ChannelNumber - channel number;               *
  632. ;* DiskNumber - disk number on channel.          *
  633. ;*************************************************
  634. prevent_medium_removal:
  635.         pusha
  636. ; Clear the packet command buffer
  637.         call    clear_packet_buffer
  638. ; Set command code
  639.         mov     [PacketCommand], byte 0x1E
  640. ; Set "Forbid" code
  641.         mov     [PacketCommand+4], byte 11b
  642. ; Send command
  643.         call    SendPacketNoDatCommand
  644.         mov     eax, ATAPI_IDE0_lock
  645.         add     eax, [cdpos]
  646.         dec     eax
  647.         mov     [eax], byte 1
  648.         popa
  649.         ret
  650. ;-----------------------------------------------------------------------------
  651. ;*************************************************
  652. ;*            ALLOW DISK CHANGE                  *
  653. ;* Input parameters are passed through global    *
  654. ;* variables:                                    *
  655. ;* ChannelNumber - channel number;               *
  656. ;* DiskNumber - disk number on channel.          *
  657. ;*************************************************
  658. allow_medium_removal:
  659.         pusha
  660. ; Clear the packet command buffer
  661.         call    clear_packet_buffer
  662. ; Set command code
  663.         mov     [PacketCommand], byte 0x1E
  664. ; unset "Forbid" code
  665.         mov     [PacketCommand+4], byte 0
  666. ; Send command
  667.         call    SendPacketNoDatCommand
  668.         mov     eax, ATAPI_IDE0_lock
  669.         add     eax, [cdpos]
  670.         dec     eax
  671.         mov     [eax], byte 0
  672.         popa
  673.         ret
  674. ;-----------------------------------------------------------------------------
  675. ;*************************************************
  676. ;*         LOAD DISK TO THE DRIVE                *
  677. ;* Input parameters are passed through global    *
  678. ;* variables:                                    *
  679. ;* ChannelNumber - channel number;               *
  680. ;* DiskNumber - disk number on channel.          *
  681. ;*************************************************
  682. LoadMedium:
  683.         pusha
  684. ; Clear the packet command buffer
  685.         call    clear_packet_buffer
  686. ; Generate START/STOP UNIT command
  687.         ; Set command code
  688.         mov     [PacketCommand], word 0x1B
  689.         ; Set disk loading operation
  690.         mov     [PacketCommand+4], word 00000011b
  691. ; Send command
  692.         call    SendPacketNoDatCommand
  693.         popa
  694.         ret
  695. ;-----------------------------------------------------------------------------
  696. ;*************************************************
  697. ;*         REMOVE THE DISK FROM THE DRIVE        *
  698. ;* Input parameters are passed through global    *
  699. ;* variables:                                    *
  700. ;* ChannelNumber - channel number;               *
  701. ;* DiskNumber - disk number on channel.          *
  702. ;*************************************************
  703. EjectMedium:
  704.         pusha
  705. ; Clear the packet command buffer
  706.         call    clear_packet_buffer
  707. ; Generate START/STOP UNIT command
  708.         ; Set command code
  709.         mov     [PacketCommand], word 0x1B
  710.         ; Set the operation to eject disk
  711.         mov     [PacketCommand+4], word 00000010b
  712. ; Send command
  713.         call    SendPacketNoDatCommand
  714.         popa
  715.         ret
  716. ;-----------------------------------------------------------------------------
  717. ;*************************************************
  718. ;* Check the event of pressing the eject button  *
  719. ;*                                               *
  720. ;* Input parameters are passed through global    *
  721. ;* variables:                                    *
  722. ;* ChannelNumber - channel number;               *
  723. ;* DiskNumber - disk number on channel.          *
  724. ;*************************************************
  725. proc check_ATAPI_device_event_has_work?
  726.         mov     eax, [timer_ticks]
  727.         sub     eax, [timer_ATAPI_check]
  728.         cmp     eax, 100
  729.         jb      .no
  730.  
  731.         xor     eax, eax
  732.         inc     eax
  733.         ret
  734. ;--------------------------------------
  735. .no:
  736.         xor     eax, eax
  737.         ret
  738. endp
  739. ;-----------------------------------------------------------------------------
  740. align 4
  741. check_ATAPI_device_event:
  742.         pusha
  743.         mov     eax, [timer_ticks]
  744.         sub     eax, [timer_ATAPI_check]
  745.         cmp     eax, 100
  746.         jb      .end_1
  747.  
  748.         pushfd
  749.         mov     al, [DRIVE_DATA+1]
  750.         and     al, 11b
  751.         cmp     al, 10b
  752.         jz      .ide3
  753. ;--------------------------------------
  754. .ide2_1:
  755.         mov     al, [DRIVE_DATA+1]
  756.         and     al, 1100b
  757.         cmp     al, 1000b
  758.         jz      .ide2
  759. ;--------------------------------------
  760. .ide1_1:
  761.         mov     al, [DRIVE_DATA+1]
  762.         and     al, 110000b
  763.         cmp     al, 100000b
  764.         jz      .ide1
  765. ;--------------------------------------
  766. .ide0_1:
  767.         mov     al, [DRIVE_DATA+1]
  768.         and     al, 11000000b
  769.         cmp     al, 10000000b
  770.         jz      .ide0
  771. ;--------------------------------------
  772. .ide7_1:
  773.         mov     al, [DRIVE_DATA+6]
  774.         and     al, 11b
  775.         cmp     al, 10b
  776.         jz      .ide7
  777. ;--------------------------------------
  778. .ide6_1:
  779.         mov     al, [DRIVE_DATA+6]
  780.         and     al, 1100b
  781.         cmp     al, 1000b
  782.         jz      .ide6
  783. ;--------------------------------------
  784. .ide5_1:
  785.         mov     al, [DRIVE_DATA+6]
  786.         and     al, 110000b
  787.         cmp     al, 100000b
  788.         jz      .ide5
  789. ;--------------------------------------
  790. .ide4_1:
  791.         mov     al, [DRIVE_DATA+6]
  792.         and     al, 11000000b
  793.         cmp     al, 10000000b
  794.         jz      .ide4
  795. ;--------------------------------------
  796. .ide11_1:
  797.         mov     al, [DRIVE_DATA+11]
  798.         and     al, 11b
  799.         cmp     al, 10b
  800.         jz      .ide11
  801. ;--------------------------------------
  802. .ide10_1:
  803.         mov     al, [DRIVE_DATA+11]
  804.         and     al, 1100b
  805.         cmp     al, 1000b
  806.         jz      .ide10
  807. ;--------------------------------------
  808. .ide9_1:
  809.         mov     al, [DRIVE_DATA+11]
  810.         and     al, 110000b
  811.         cmp     al, 100000b
  812.         jz      .ide9
  813. ;--------------------------------------
  814. .ide8_1:
  815.         mov     al, [DRIVE_DATA+11]
  816.         and     al, 11000000b
  817.         cmp     al, 10000000b
  818.         jz      .ide8
  819. ;--------------------------------------
  820. .end:
  821.         popfd
  822.         mov     eax, [timer_ticks]
  823.         mov     [timer_ATAPI_check], eax
  824. ;--------------------------------------
  825. .end_1:
  826.         popa
  827.         ret
  828. ;-----------------------------------------------------------------------------
  829. .ide3:
  830.         cli
  831.         cmp     [ATAPI_IDE3_lock], 1
  832.         jne     .ide2_1
  833.  
  834.         cmp     [cd_status], 0
  835.         jne     .end
  836.  
  837.         mov     ecx, ide_channel2_mutex
  838.         call    mutex_lock
  839.         call    reserve_ok2
  840.         mov     [ChannelNumber], 2
  841.         mov     [DiskNumber], 1
  842.         mov     [cdpos], 4
  843.         call    GetEvent_StatusNotification
  844.         cmp     [CDDataBuf+4], byte 1
  845.         jne     @f
  846.  
  847.         call    .eject
  848. ;--------------------------------------
  849. @@:
  850.         call    syscall_cdaudio.free
  851.         jmp     .ide2_1
  852. ;-----------------------------------------------------------------------------
  853. .ide2:
  854.         cli
  855.         cmp     [ATAPI_IDE2_lock], 1
  856.         jne     .ide1_1
  857.  
  858.         cmp     [cd_status], 0
  859.         jne     .end
  860.  
  861.         mov     ecx, ide_channel2_mutex
  862.         call    mutex_lock
  863.         call    reserve_ok2
  864.         mov     [ChannelNumber], 2
  865.         mov     [DiskNumber], 0
  866.         mov     [cdpos], 3
  867.         call    GetEvent_StatusNotification
  868.         cmp     [CDDataBuf+4], byte 1
  869.         jne     @f
  870.  
  871.         call    .eject
  872. ;--------------------------------------
  873. @@:
  874.         call    syscall_cdaudio.free
  875.         jmp     .ide1_1
  876. ;-----------------------------------------------------------------------------
  877. .ide1:
  878.         cli
  879.         cmp     [ATAPI_IDE1_lock], 1
  880.         jne     .ide0_1
  881.  
  882.         cmp     [cd_status], 0
  883.         jne     .end
  884.  
  885.         mov     ecx, ide_channel1_mutex
  886.         call    mutex_lock
  887.         call    reserve_ok2
  888.         mov     [ChannelNumber], 1
  889.         mov     [DiskNumber], 1
  890.         mov     [cdpos], 2
  891.         call    GetEvent_StatusNotification
  892.         cmp     [CDDataBuf+4], byte 1
  893.         jne     @f
  894.  
  895.         call    .eject
  896. ;--------------------------------------
  897. @@:
  898.         call    syscall_cdaudio.free
  899.         jmp     .ide0_1
  900. ;-----------------------------------------------------------------------------
  901. .ide0:
  902.         cli
  903.         cmp     [ATAPI_IDE0_lock], 1
  904.         jne     .ide7_1
  905.  
  906.         cmp     [cd_status], 0
  907.         jne     .end
  908.  
  909.         mov     ecx, ide_channel1_mutex
  910.         call    mutex_lock
  911.         call    reserve_ok2
  912.         mov     [ChannelNumber], 1
  913.         mov     [DiskNumber], 0
  914.         mov     [cdpos], 1
  915.         call    GetEvent_StatusNotification
  916.         cmp     [CDDataBuf+4], byte 1
  917.         jne     @f
  918.  
  919.         call    .eject
  920. ;--------------------------------------
  921. @@:
  922.         call    syscall_cdaudio.free
  923.         jmp     .ide7_1
  924. ;-----------------------------------------------------------------------------
  925. .ide7:
  926.         cli
  927.         cmp     [ATAPI_IDE7_lock], 1
  928.         jne     .ide6_1
  929.  
  930.         cmp     [cd_status], 0
  931.         jne     .end
  932.  
  933.         mov     ecx, ide_channel4_mutex
  934.         call    mutex_lock
  935.         call    reserve_ok2
  936.         mov     [ChannelNumber], 2
  937.         mov     [DiskNumber], 1
  938.         mov     [cdpos], 8
  939.         call    GetEvent_StatusNotification
  940.         cmp     [CDDataBuf+4], byte 1
  941.         jne     @f
  942.  
  943.         call    .eject
  944. ;--------------------------------------
  945. @@:
  946.         call    syscall_cdaudio.free
  947.         jmp     .ide6_1
  948. ;-----------------------------------------------------------------------------
  949. .ide6:
  950.         cli
  951.         cmp     [ATAPI_IDE6_lock], 1
  952.         jne     .ide5_1
  953.  
  954.         cmp     [cd_status], 0
  955.         jne     .end
  956.  
  957.         mov     ecx, ide_channel4_mutex
  958.         call    mutex_lock
  959.         call    reserve_ok2
  960.         mov     [ChannelNumber], 2
  961.         mov     [DiskNumber], 0
  962.         mov     [cdpos], 7
  963.         call    GetEvent_StatusNotification
  964.         cmp     [CDDataBuf+4], byte 1
  965.         jne     @f
  966.  
  967.         call    .eject
  968. ;--------------------------------------
  969. @@:
  970.         call    syscall_cdaudio.free
  971.         jmp     .ide5_1
  972. ;-----------------------------------------------------------------------------
  973. .ide5:
  974.         cli
  975.         cmp     [ATAPI_IDE5_lock], 1
  976.         jne     .ide4_1
  977.  
  978.         cmp     [cd_status], 0
  979.         jne     .end
  980.  
  981.         mov     ecx, ide_channel3_mutex
  982.         call    mutex_lock
  983.         call    reserve_ok2
  984.         mov     [ChannelNumber], 1
  985.         mov     [DiskNumber], 1
  986.         mov     [cdpos], 6
  987.         call    GetEvent_StatusNotification
  988.         cmp     [CDDataBuf+4], byte 1
  989.         jne     @f
  990.  
  991.         call    .eject
  992. ;--------------------------------------
  993. @@:
  994.         call    syscall_cdaudio.free
  995.         jmp     .ide4_1
  996. ;-----------------------------------------------------------------------------
  997. .ide4:
  998.         cli
  999.         cmp     [ATAPI_IDE4_lock], 1
  1000.         jne     .ide11_1
  1001.  
  1002.         cmp     [cd_status], 0
  1003.         jne     .end
  1004.  
  1005.         mov     ecx, ide_channel3_mutex
  1006.         call    mutex_lock
  1007.         call    reserve_ok2
  1008.         mov     [ChannelNumber], 1
  1009.         mov     [DiskNumber], 0
  1010.         mov     [cdpos], 5
  1011.         call    GetEvent_StatusNotification
  1012.         cmp     [CDDataBuf+4], byte 1
  1013.         jne     @f
  1014.  
  1015.         call    .eject
  1016. ;--------------------------------------
  1017. @@:
  1018.         call    syscall_cdaudio.free
  1019.         jmp     .ide11_1
  1020. ;-----------------------------------------------------------------------------
  1021. .ide11:
  1022.         cli
  1023.         cmp     [ATAPI_IDE11_lock], 1
  1024.         jne     .ide10_1
  1025.  
  1026.         cmp     [cd_status], 0
  1027.         jne     .end
  1028.  
  1029.         mov     ecx, ide_channel6_mutex
  1030.         call    mutex_lock
  1031.         call    reserve_ok2
  1032.         mov     [ChannelNumber], 2
  1033.         mov     [DiskNumber], 1
  1034.         mov     [cdpos], 12
  1035.         call    GetEvent_StatusNotification
  1036.         cmp     [CDDataBuf+4], byte 1
  1037.         jne     @f
  1038.  
  1039.         call    .eject
  1040. ;--------------------------------------
  1041. @@:
  1042.         call    syscall_cdaudio.free
  1043.         jmp     .ide10_1
  1044. ;-----------------------------------------------------------------------------
  1045. .ide10:
  1046.         cli
  1047.         cmp     [ATAPI_IDE10_lock], 1
  1048.         jne     .ide9_1
  1049.  
  1050.         cmp     [cd_status], 0
  1051.         jne     .end
  1052.  
  1053.         mov     ecx, ide_channel6_mutex
  1054.         call    mutex_lock
  1055.         call    reserve_ok2
  1056.         mov     [ChannelNumber], 2
  1057.         mov     [DiskNumber], 0
  1058.         mov     [cdpos], 11
  1059.         call    GetEvent_StatusNotification
  1060.         cmp     [CDDataBuf+4], byte 1
  1061.         jne     @f
  1062.  
  1063.         call    .eject
  1064. ;--------------------------------------
  1065. @@:
  1066.         call    syscall_cdaudio.free
  1067.         jmp     .ide9_1
  1068. ;-----------------------------------------------------------------------------
  1069. .ide9:
  1070.         cli
  1071.         cmp     [ATAPI_IDE9_lock], 1
  1072.         jne     .ide8_1
  1073.  
  1074.         cmp     [cd_status], 0
  1075.         jne     .end
  1076.  
  1077.         mov     ecx, ide_channel5_mutex
  1078.         call    mutex_lock
  1079.         call    reserve_ok2
  1080.         mov     [ChannelNumber], 1
  1081.         mov     [DiskNumber], 1
  1082.         mov     [cdpos], 10
  1083.         call    GetEvent_StatusNotification
  1084.         cmp     [CDDataBuf+4], byte 1
  1085.         jne     @f
  1086.  
  1087.         call    .eject
  1088. ;--------------------------------------
  1089. @@:
  1090.         call    syscall_cdaudio.free
  1091.         jmp     .ide8_1
  1092. ;-----------------------------------------------------------------------------
  1093. .ide8:
  1094.         cli
  1095.         cmp     [ATAPI_IDE8_lock], 1
  1096.         jne     .end
  1097.  
  1098.         cmp     [cd_status], 0
  1099.         jne     .end
  1100.  
  1101.         mov     ecx, ide_channel5_mutex
  1102.         call    mutex_lock
  1103.         call    reserve_ok2
  1104.         mov     [ChannelNumber], 1
  1105.         mov     [DiskNumber], 0
  1106.         mov     [cdpos], 9
  1107.         call    GetEvent_StatusNotification
  1108.         cmp     [CDDataBuf+4], byte 1
  1109.         jne     @f
  1110.  
  1111.         call    .eject
  1112. ;--------------------------------------
  1113. @@:
  1114.         call    syscall_cdaudio.free
  1115.         jmp     .end
  1116. ;-----------------------------------------------------------------------------
  1117. .eject:
  1118.         call    clear_CD_cache
  1119.         call    allow_medium_removal
  1120.         mov     [ignore_CD_eject_wait], 1
  1121.         call    EjectMedium
  1122.         mov     [ignore_CD_eject_wait], 0
  1123.         ret
  1124. ;-----------------------------------------------------------------------------
  1125. iglobal
  1126. timer_ATAPI_check dd 0
  1127. ATAPI_IDE0_lock db 0
  1128. ATAPI_IDE1_lock db 0
  1129. ATAPI_IDE2_lock db 0
  1130. ATAPI_IDE3_lock db 0
  1131. ATAPI_IDE4_lock db 0
  1132. ATAPI_IDE5_lock db 0
  1133. ATAPI_IDE6_lock db 0
  1134. ATAPI_IDE7_lock db 0
  1135. ATAPI_IDE8_lock db 0
  1136. ATAPI_IDE9_lock db 0
  1137. ATAPI_IDE10_lock db 0
  1138. ATAPI_IDE11_lock db 0
  1139. ignore_CD_eject_wait db 0
  1140. endg
  1141. ;-----------------------------------------------------------------------------
  1142. ;*************************************************
  1143. ;* Get an event or device status message         *
  1144. ;*                                               *
  1145. ;* Input parameters are passed through global    *
  1146. ;* variables:                                    *
  1147. ;* ChannelNumber - channel number;               *
  1148. ;* DiskNumber - disk number on channel           *
  1149. ;*************************************************
  1150. GetEvent_StatusNotification:
  1151.         pusha
  1152.         mov     [CDDataBuf_pointer], CDDataBuf
  1153. ; Clear the packet command buffer
  1154.         call    clear_packet_buffer
  1155. ; Set command code
  1156.         mov     [PacketCommand], byte 4Ah
  1157.         mov     [PacketCommand+1], byte 00000001b
  1158. ; Set message class request
  1159.         mov     [PacketCommand+4], byte 00010000b
  1160. ; Size of allocated area
  1161.         mov     [PacketCommand+7], byte 8h
  1162.         mov     [PacketCommand+8], byte 0h
  1163. ; Send command
  1164.         call    SendPacketDatCommand
  1165.         popa
  1166.         ret
  1167. ;-----------------------------------------------------------------------------
  1168. ;*************************************************
  1169. ; Read information from TOC (Table of contents)  *
  1170. ;* Input parameters are passed through global    *
  1171. ;* variables:                                    *
  1172. ;* ChannelNumber - channel number;               *
  1173. ;* DiskNumber - disk number on channel           *
  1174. ;*************************************************
  1175. Read_TOC:
  1176.         pusha
  1177.         mov     [CDDataBuf_pointer], CDDataBuf
  1178. ; Clear the packet command buffer
  1179.         call    clear_packet_buffer
  1180. ; Generate a packet command to read a data sector
  1181.         mov     [PacketCommand], byte 0x43
  1182.         ; Set format
  1183.         mov     [PacketCommand+2], byte 1
  1184. ; Size of allocated area
  1185.         mov     [PacketCommand+7], byte 0xFF
  1186.         mov     [PacketCommand+8], byte 0h
  1187. ; Send a command
  1188.         call    SendPacketDatCommand
  1189.         popa
  1190.         ret
  1191. ;-----------------------------------------------------------------------------
  1192. ;*****************************************************
  1193. ;* DETERMINE THE TOTAL NUMBER OF SECTORS ON THE DISK *
  1194. ;* Input parameters are passed through global        *
  1195. ;* variables:                                        *
  1196. ;* ChannelNumber - channel number;                   *
  1197. ;* DiskNumber - disk number on channel               *
  1198. ;*****************************************************
  1199. ;ReadCapacity:
  1200. ;       pusha
  1201. ;; Clear the packet command buffer
  1202. ;       call  clear_packet_buffer
  1203. ;; Set the buffer size in bytes
  1204. ;       mov     [CDBlockSize],8
  1205. ;; Generate READ CAPACITY command
  1206. ;       mov     [PacketCommand],word 25h
  1207. ;; Send command
  1208. ;       call    SendPacketDatCommand
  1209. ;       popa
  1210. ;       ret
  1211. ;-----------------------------------------------------------------------------
  1212. clear_packet_buffer:
  1213. ; Clear the packet command buffer
  1214.         and     [PacketCommand], dword 0
  1215.         and     [PacketCommand+4], dword 0
  1216.         and     [PacketCommand+8], dword 0
  1217.         ret
  1218. ;-----------------------------------------------------------------------------
  1219.