Subversion Repositories Kolibri OS

Rev

Rev 7136 | Go to most recent revision | 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: 8053 $
  9.  
  10. ;-----------------------------------------------------------------------------
  11. ;**********************************************************
  12. ;  Direct work with СD (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. ;*        ЧТЕНИЕ СЕКТОРА С ПОВТОРАМИ        *
  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. ;--------------------------------------
  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. ; Цикл, пока команда не выполнена успешно или не
  90. ; исчерпано количество попыток
  91.         mov     ecx, MaxRetr
  92. ;--------------------------------------
  93. align 4
  94. @@NextRetr:
  95. ; Подать команду
  96. ;*************************************************
  97. ;*      ПОЛНОЕ ЧТЕНИЕ СЕКТОРА КОМПАКТ-ДИСКА      *
  98. ;* Считываются данные пользователя, информация   *
  99. ;* субканала и контрольная информация            *
  100. ;* Входные параметры передаются через глобальные *
  101. ;* перменные:                                    *
  102. ;* ChannelNumber - номер канала;                 *
  103. ;* DiskNumber - номер диска на канале;           *
  104. ;* CDSectorAddress - адрес считываемого сектора. *
  105. ;* Данные считывается в массив CDDataBuf.        *
  106. ;*************************************************
  107. ;ReadCD:
  108.         push    ecx
  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. ; Задать количество считываемых секторов
  123.         mov     [PacketCommand+8], byte 1
  124. ; Подать команду
  125.         call    SendPacketDatCommand
  126.         pop     ecx
  127.  
  128.         test    eax, eax
  129.         jz      @@End_4
  130.  
  131.         or      ecx, ecx        ;{SPraid.simba} (for cd load)
  132.         jz      @@End_4
  133.  
  134.         dec     ecx
  135.  
  136.         cmp     [timer_ticks_enable], 0
  137.         jne     @f
  138.  
  139.         mov     eax, NoTickWaitTime
  140. ;--------------------------------------
  141. align 4
  142. .wait:
  143.         dec     eax
  144.         jz      @@NextRetr
  145.  
  146.         jmp     .wait
  147. ;--------------------------------------
  148. align 4
  149. @@:
  150.         loop    @@NextRetr
  151. ;--------------------------------------
  152. @@End_4:
  153.         mov     dword [DevErrorCode], eax
  154.         popad
  155.         ret
  156. ;-----------------------------------------------------------------------------
  157. ; Универсальные процедуры, обеспечивающие выполнение
  158. ;             пакетных команд в режиме PIO
  159. ; Максимально допустимое время ожидания реакции
  160. ; устройства на пакетную команду (в тиках)
  161. ;-----------------------------------------------------------------------------
  162. MaxCDWaitTime = 1000 ;200 ;10 секунд
  163. uglobal
  164. ; Область памяти для формирования пакетной команды
  165. PacketCommand:
  166.                  rb 12  ;DB 12 DUP (?)
  167. ; Адрес считываемого сектора данных
  168. CDSectorAddress:   dd ?
  169. ; Время начала очередной операции с диском
  170. TickCounter_1     dd 0
  171. ; Время начала ожидания готовности устройства
  172. WURStartTime      dd 0
  173. ; указатель буфера для считывания
  174. CDDataBuf_pointer dd 0
  175. endg
  176. ;-----------------------------------------------------------------------------
  177. ;****************************************************
  178. ;*    ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ,    *
  179. ;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ *
  180. ;*     РАЗМЕРОМ 2048 БАЙТ ОТ УСТРОЙСТВА К ХОСТУ     *
  181. ;* Входные параметры передаются через глобальные    *
  182. ;* перменные:                                       *
  183. ;* ChannelNumber - номер канала;                    *
  184. ;* DiskNumber - номер диска на канале;              *
  185. ;* PacketCommand - 12-байтный командный пакет;      *
  186. ;* CDBlockSize - размер принимаемого блока данных.  *
  187. ; return eax DevErrorCode
  188. ;****************************************************
  189. SendPacketDatCommand:
  190.         xor     eax, eax
  191. ; Задать режим CHS
  192.         mov     byte [ATAAddressMode], al
  193. ; Послать ATA-команду передачи пакетной команды
  194.         mov     byte [ATAFeatures], al
  195.         mov     byte [ATASectorCount], al
  196.         mov     byte [ATASectorNumber], al
  197.         ; Загрузить размер передаваемого блока
  198.         mov     [ATAHead], al
  199.         mov     [ATACylinder], CDBlockSize
  200.         mov     [ATACommand], 0xA0
  201.         call    SendCommandToHDD_1
  202.         test    eax, eax
  203.         jnz     @@End_8    ;закончить, сохранив код ошибки
  204. ; Ожидание готовности дисковода к приему
  205. ; пакетной команды
  206.         mov     dx, [ATABasePortAddr]
  207.         add     dx, 7    ;порт 1х7h
  208.         mov     ecx, NoTickWaitTime
  209. ;--------------------------------------
  210. align 4
  211. @@WaitDevice0:
  212.         cmp     [timer_ticks_enable], 0
  213.         jne     @f
  214.  
  215.         dec     ecx
  216.         jz      @@Err1_1
  217.  
  218.         jmp     .test
  219. ;--------------------------------------
  220. align 4
  221. @@:
  222.         call    change_task
  223.         ; Проверить время выполнения команды
  224.         mov     eax, [timer_ticks]
  225.         sub     eax, [TickCounter_1]
  226.         cmp     eax, BSYWaitTime
  227.         ja      @@Err1_1   ;ошибка тайм-аута
  228.         ; Проверить готовность
  229. ;--------------------------------------
  230. align 4
  231. .test:
  232.         in      al, dx
  233.         test    al, 0x80  ;состояние сигнала BSY
  234.         jnz     @@WaitDevice0
  235.  
  236.         test    al, 1    ;состояние сигнала ERR
  237.         jnz     @@Err6
  238.  
  239.         test    al, 0x8  ;состояние сигнала DRQ
  240.         jz      @@WaitDevice0
  241. ; Послать пакетную команду
  242.         cli
  243.         mov     dx, [ATABasePortAddr]
  244.         mov     ax, [PacketCommand]
  245.         out     dx, ax
  246.         mov     ax, [PacketCommand+2]
  247.         out     dx, ax
  248.         mov     ax, [PacketCommand+4]
  249.         out     dx, ax
  250.         mov     ax, [PacketCommand+6]
  251.         out     dx, ax
  252.         mov     ax, [PacketCommand+8]
  253.         out     dx, ax
  254.         mov     ax, [PacketCommand+10]
  255.         out     dx, ax
  256.         sti
  257. ; Ожидание готовности данных
  258.         mov     dx, [ATABasePortAddr]
  259.         add     dx, 7  ;порт 1х7h
  260.         mov     ecx, NoTickWaitTime
  261. ;--------------------------------------
  262. align 4
  263. @@WaitDevice1:
  264.         cmp     [timer_ticks_enable], 0
  265.         jne     @f
  266.  
  267.         dec     ecx
  268.         jz      @@Err1_1
  269.  
  270.         jmp     .test_1
  271. ;--------------------------------------
  272. align 4
  273. @@:
  274.         call    change_task
  275.         ; Проверить время выполнения команды
  276.         mov     eax, [timer_ticks]
  277.         sub     eax, [TickCounter_1]
  278.         cmp     eax, MaxCDWaitTime
  279.         ja      @@Err1_1   ;ошибка тайм-аута
  280.         ; Проверить готовность
  281. ;--------------------------------------
  282. align 4
  283. .test_1:
  284.         in      al, dx
  285.         test    al, 0x80  ;состояние сигнала BSY
  286.         jnz     @@WaitDevice1
  287.  
  288.         test    al, 1    ;состояние сигнала ERR
  289.         jnz     @@Err6_temp
  290.  
  291.         test    al, 0x8  ;состояние сигнала DRQ
  292.         jz      @@WaitDevice1
  293. ; Принять блок данных от контроллера
  294.         mov     edi, [CDDataBuf_pointer]
  295.         ; Загрузить адрес регистра данных контроллера
  296.         mov     dx, [ATABasePortAddr]
  297.         ; Загрузить в счетчик размер блока в байтах
  298.         xor     ecx, ecx
  299.         mov     cx, CDBlockSize
  300.         ; Вычислить размер блока в 16-разрядных словах
  301.         shr     cx, 1 ;разделить размер блока на 2
  302.         ; Принять блок данных
  303.         cli
  304.         cld
  305.         rep insw
  306.         sti
  307. ;--------------------------------------
  308. ; Успешное завершение приема данных
  309. @@End_8:
  310.         xor     eax, eax
  311.         ret
  312. ;--------------------------------------
  313. ; Записать код ошибки
  314. @@Err1_1:
  315.         xor     eax, eax
  316.         inc     eax
  317.         ret
  318. ;--------------------------------------
  319. @@Err6_temp:
  320.         mov     eax, 7
  321.         ret
  322. ;--------------------------------------
  323. @@Err6:
  324.         mov     eax, 6
  325.         ret
  326. ;-----------------------------------------------------------------------------
  327. ;***********************************************
  328. ;*  ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
  329. ;*     НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ    *
  330. ;* Входные параметры передаются через          *
  331. ;* глобальные перменные:                       *
  332. ;* ChannelNumber - номер канала;               *
  333. ;* DiskNumber - номер диска на канале;         *
  334. ;* PacketCommand - 12-байтный командный пакет. *
  335. ;***********************************************
  336. SendPacketNoDatCommand:
  337.         pushad
  338.         xor     eax, eax
  339. ; Задать режим CHS
  340.         mov     byte [ATAAddressMode], al
  341. ; Послать ATA-команду передачи пакетной команды
  342.         mov     byte [ATAFeatures], al
  343.         mov     byte [ATASectorCount], al
  344.         mov     byte [ATASectorNumber], al
  345.         mov     word [ATACylinder], ax
  346.         mov     byte [ATAHead], al
  347.         mov     [ATACommand], 0xA0
  348.         call    SendCommandToHDD_1
  349.         test    eax, eax
  350.         jnz     @@End_9  ;закончить, сохранив код ошибки
  351. ; Ожидание готовности дисковода к приему
  352. ; пакетной команды
  353.         mov     dx, [ATABasePortAddr]
  354.         add     dx, 7  ;порт 1х7h
  355. ;--------------------------------------
  356. align 4
  357. @@WaitDevice0_1:
  358.         call    change_task
  359.         ; Проверить время ожидания
  360.         mov     eax, [timer_ticks]
  361.         sub     eax, [TickCounter_1]
  362.         cmp     eax, BSYWaitTime
  363.         ja      @@Err1_3   ;ошибка тайм-аута
  364.         ; Проверить готовность
  365.         in      al, dx
  366.         test    al, 0x80  ;состояние сигнала BSY
  367.         jnz     @@WaitDevice0_1
  368.  
  369.         test    al, 1    ;состояние сигнала ERR
  370.         jnz     @@Err6_1
  371.  
  372.         test    al, 0x8  ;состояние сигнала DRQ
  373.         jz      @@WaitDevice0_1
  374. ; Послать пакетную команду
  375. ;        cli
  376.         mov     dx, [ATABasePortAddr]
  377.         mov     ax, word [PacketCommand]
  378.         out     dx, ax
  379.         mov     ax, word [PacketCommand+2]
  380.         out     dx, ax
  381.         mov     ax, word [PacketCommand+4]
  382.         out     dx, ax
  383.         mov     ax, word [PacketCommand+6]
  384.         out     dx, ax
  385.         mov     ax, word [PacketCommand+8]
  386.         out     dx, ax
  387.         mov     ax, word [PacketCommand+10]
  388.         out     dx, ax
  389. ;        sti
  390.         cmp     [ignore_CD_eject_wait], 1
  391.         je      @@clear_DEC
  392. ; Ожидание подтверждения приема команды
  393.         mov     dx, [ATABasePortAddr]
  394.         add     dx, 7  ;порт 1х7h
  395. ;--------------------------------------
  396. align 4
  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, 0x80  ;состояние сигнала BSY
  407.         jnz     @@WaitDevice1_1
  408.  
  409.         test    al, 1    ;состояние сигнала ERR
  410.         jnz     @@Err6_1
  411.  
  412.         test    al, 0x40  ;состояние сигнала DRDY
  413.         jz      @@WaitDevice1_1
  414. ;--------------------------------------
  415. @@clear_DEC:
  416.         and     [DevErrorCode], 0
  417.         popad
  418.         ret
  419. ;--------------------------------------
  420. ; Записать код ошибки
  421. @@Err1_3:
  422.         xor     eax, eax
  423.         inc     eax
  424.         jmp     @@End_9
  425. ;--------------------------------------
  426. @@Err6_1:
  427.         mov     eax, 6
  428. ;--------------------------------------
  429. @@End_9:
  430.         mov     [DevErrorCode], eax
  431.         popad
  432.         ret
  433. ;-----------------------------------------------------------------------------
  434. ;****************************************************
  435. ;*          ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ         *
  436. ;* Входные параметры передаются через глобальные    *
  437. ;* переменные:                                      *
  438. ;* ChannelNumber - номер канала (1 или 2);          *
  439. ;* DiskNumber - номер диска (0 или 1);              *
  440. ;* ATAFeatures - "особенности";                     *
  441. ;* ATASectorCount - количество секторов;            *
  442. ;* ATASectorNumber - номер начального сектора;      *
  443. ;* ATACylinder - номер начального цилиндра;         *
  444. ;* ATAHead - номер начальной головки;               *
  445. ;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); *
  446. ;* ATACommand - код команды.                        *
  447. ;* После успешного выполнения функции:              *
  448. ;* в ATABasePortAddr - базовый адрес HDD;           *
  449. ;* в DevErrorCode - ноль.                           *
  450. ;* При возникновении ошибки в DevErrorCode будет    *
  451. ;* возвращен код ошибки в eax                       *
  452. ;****************************************************
  453. SendCommandToHDD_1:
  454. ; Проверить значение кода режима
  455.         cmp     [ATAAddressMode], 1
  456.         ja      @@Err2_4
  457. ; Проверить корректность номера канала
  458.         movzx   ebx, [ChannelNumber]
  459.         dec     ebx
  460.         cmp     ebx, 1
  461.         ja      @@Err3_4
  462. ; Установить базовый адрес
  463.         shl     ebx, 2
  464.         mov     eax, [cdpos]
  465.         dec     eax
  466.         shr     eax, 2
  467.         imul    eax, sizeof.IDE_DATA
  468.         add     eax, IDE_controller_1
  469.         add     eax, ebx
  470.         mov     ax, [eax+IDE_DATA.BAR0_val]
  471.         mov     [ATABasePortAddr], ax
  472. ; Ожидание готовности HDD к приему команды
  473.         ; Выбрать нужный диск
  474.         mov     dx, [ATABasePortAddr]
  475.         add     dx, 6   ;адрес регистра головок
  476.         mov     al, [DiskNumber]
  477.         cmp     al, 1   ;проверить номера диска
  478.         ja      @@Err4_4
  479.  
  480.         shl     al, 4
  481.         or      al, 10100000b
  482.         out     dx, al
  483.         ; Ожидать, пока диск не будет готов
  484.         inc     dx
  485.         mov     eax, [timer_ticks]
  486.         mov     [TickCounter_1], eax
  487.         mov     ecx, NoTickWaitTime
  488. ;--------------------------------------
  489. align 4
  490. @@WaitHDReady_2:
  491.         cmp     [timer_ticks_enable], 0
  492.         jne     @f
  493.  
  494.         dec     ecx
  495.         jz      @@Err1_4
  496.  
  497.         jmp     .test
  498. ;--------------------------------------
  499. align 4
  500. @@:
  501.         call    change_task
  502.         ; Проверить время ожидания
  503.         mov     eax, [timer_ticks]
  504.         sub     eax, [TickCounter_1]
  505.         cmp     eax, BSYWaitTime ;300    ;ожидать 3 сек.
  506.         ja      @@Err1_4   ;ошибка тайм-аута
  507. ;--------------------------------------
  508. align 4
  509. .test:
  510.         in      al, dx ; Прочитать регистр состояния
  511.         ; Проверить состояние сигнала BSY
  512.         test    al, 0x80
  513.         jnz     @@WaitHDReady_2
  514.         ; Проверить состояние сигнала DRQ
  515.         test    al, 0x8
  516.         jnz     @@WaitHDReady_2
  517. ; Загрузить команду в регистры контроллера
  518.         cli
  519.         mov     dx, [ATABasePortAddr]
  520.         inc     dx      ;регистр "особенностей"
  521.         mov     al, [ATAFeatures]
  522.         out     dx, al
  523.         inc     dx      ;счетчик секторов
  524.         mov     al, [ATASectorCount]
  525.         out     dx, al
  526.         inc     dx      ;регистр номера сектора
  527.         mov     al, [ATASectorNumber]
  528.         out     dx, al
  529.         inc     dx      ;номер цилиндра (младший байт)
  530.         mov     ax, [ATACylinder]
  531.         out     dx, al
  532.         inc     dx      ;номер цилиндра (старший байт)
  533.         mov     al, ah
  534.         out     dx, al
  535.         inc     dx      ;номер головки/номер диска
  536.         mov     al, [DiskNumber]
  537.         shl     al, 4
  538.         cmp     [ATAHead], 0xF ;проверить номер головки
  539.         ja      @@Err5_4
  540.  
  541.         or      al, [ATAHead]
  542.         or      al, 10100000b
  543.         mov     ah, [ATAAddressMode]
  544.         shl     ah, 6
  545.         or      al, ah
  546.         out     dx, al
  547. ; Послать команду
  548.         mov     al, [ATACommand]
  549.         inc     dx      ;регистр команд
  550.         out     dx, al
  551.         sti
  552. ;--------------------------------------
  553. @@End_10:
  554.         xor     eax, eax
  555.         ret
  556. ;--------------------------------------
  557. ; Записать код ошибки
  558. @@Err1_4:
  559.         xor     eax, eax
  560.         inc     eax
  561.         ret
  562. ;--------------------------------------
  563. @@Err2_4:
  564.         mov     eax, 2
  565.         ret
  566. ;--------------------------------------
  567. @@Err3_4:
  568.         mov     eax, 3
  569.         ret
  570. ;--------------------------------------
  571. @@Err4_4:
  572.         mov     eax, 4
  573.         ret
  574. ;--------------------------------------
  575. @@Err5_4:
  576.         mov     eax, 5
  577.         ret
  578. ;-----------------------------------------------------------------------------
  579. ;*************************************************
  580. ;*    ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ    *
  581. ;* Входные параметры передаются через глобальные *
  582. ;* перменные:                                    *
  583. ;* ChannelNumber - номер канала;                 *
  584. ;* DiskNumber - номер диска на канале.           *
  585. ;*************************************************
  586. WaitUnitReady:
  587.         pusha
  588. ; Запомнить время начала операции
  589.         mov     eax, [timer_ticks]
  590.         mov     [WURStartTime], eax
  591. ; Очистить буфер пакетной команды
  592.         call    clear_packet_buffer
  593. ; Сформировать команду TEST UNIT READY
  594.         mov     [PacketCommand], word 0
  595. ; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА
  596.         mov     ecx, NoTickWaitTime
  597. ;--------------------------------------
  598. align 4
  599. @@SendCommand:
  600.         ; Подать команду проверки готовности
  601.         call    SendPacketNoDatCommand
  602.         cmp     [timer_ticks_enable], 0
  603.         jne     @f
  604.  
  605.         cmp     [DevErrorCode], 0
  606.         je      @@End_11
  607.  
  608.         dec     ecx
  609.         jz      .Error
  610.  
  611.         jmp     @@SendCommand
  612. ;--------------------------------------
  613. align 4
  614. @@:
  615.         call    change_task
  616.         ; Проверить код ошибки
  617.         cmp     [DevErrorCode], 0
  618.         je      @@End_11
  619.         ; Проверить время ожидания готовности
  620.         mov     eax, [timer_ticks]
  621.         sub     eax, [WURStartTime]
  622.         cmp     eax, MaxCDWaitTime
  623.         jb      @@SendCommand
  624. ;--------------------------------------
  625. .Error:
  626.         ; Ошибка тайм-аута
  627.         mov     [DevErrorCode], 1
  628. ;--------------------------------------
  629. @@End_11:
  630.         popa
  631.         ret
  632. ;-----------------------------------------------------------------------------
  633. ;*************************************************
  634. ;*            ЗАПРЕТИТЬ СМЕНУ ДИСКА              *
  635. ;* Входные параметры передаются через глобальные *
  636. ;* перменные:                                    *
  637. ;* ChannelNumber - номер канала;                 *
  638. ;* DiskNumber - номер диска на канале.           *
  639. ;*************************************************
  640. prevent_medium_removal:
  641.         pusha
  642. ; Очистить буфер пакетной команды
  643.         call    clear_packet_buffer
  644. ; Задать код команды
  645.         mov     [PacketCommand], byte 0x1E
  646. ; Задать код запрета
  647.         mov     [PacketCommand+4], byte 11b
  648. ; Подать команду
  649.         call    SendPacketNoDatCommand
  650.         mov     eax, ATAPI_IDE0_lock
  651.         add     eax, [cdpos]
  652.         dec     eax
  653.         mov     [eax], byte 1
  654.         popa
  655.         ret
  656. ;-----------------------------------------------------------------------------
  657. ;*************************************************
  658. ;*            РАЗРЕШИТЬ СМЕНУ ДИСКА              *
  659. ;* Входные параметры передаются через глобальные *
  660. ;* перменные:                                    *
  661. ;* ChannelNumber - номер канала;                 *
  662. ;* DiskNumber - номер диска на канале.           *
  663. ;*************************************************
  664. allow_medium_removal:
  665.         pusha
  666. ; Очистить буфер пакетной команды
  667.         call    clear_packet_buffer
  668. ; Задать код команды
  669.         mov     [PacketCommand], byte 0x1E
  670. ; Задать код запрета
  671.         mov     [PacketCommand+4], byte 0
  672. ; Подать команду
  673.         call    SendPacketNoDatCommand
  674.         mov     eax, ATAPI_IDE0_lock
  675.         add     eax, [cdpos]
  676.         dec     eax
  677.         mov     [eax], byte 0
  678.         popa
  679.         ret
  680. ;-----------------------------------------------------------------------------
  681. ;*************************************************
  682. ;*         ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД         *
  683. ;* Входные параметры передаются через глобальные *
  684. ;* перменные:                                    *
  685. ;* ChannelNumber - номер канала;                 *
  686. ;* DiskNumber - номер диска на канале.           *
  687. ;*************************************************
  688. LoadMedium:
  689.         pusha
  690. ; Очистить буфер пакетной команды
  691.         call    clear_packet_buffer
  692. ; Сформировать команду START/STOP UNIT
  693.         ; Задать код команды
  694.         mov     [PacketCommand], word 0x1B
  695.         ; Задать операцию загрузки носителя
  696.         mov     [PacketCommand+4], word 00000011b
  697. ; Подать команду
  698.         call    SendPacketNoDatCommand
  699.         popa
  700.         ret
  701. ;-----------------------------------------------------------------------------
  702. ;*************************************************
  703. ;*         ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА         *
  704. ;* Входные параметры передаются через глобальные *
  705. ;* перменные:                                    *
  706. ;* ChannelNumber - номер канала;                 *
  707. ;* DiskNumber - номер диска на канале.           *
  708. ;*************************************************
  709. EjectMedium:
  710.         pusha
  711. ; Очистить буфер пакетной команды
  712.         call    clear_packet_buffer
  713. ; Сформировать команду START/STOP UNIT
  714.         ; Задать код команды
  715.         mov     [PacketCommand], word 0x1B
  716.         ; Задать операцию извлечения носителя
  717.         mov     [PacketCommand+4], word 00000010b
  718. ; Подать команду
  719.         call    SendPacketNoDatCommand
  720.         popa
  721.         ret
  722. ;-----------------------------------------------------------------------------
  723. ;*************************************************
  724. ;* Проверить событие нажатия кнопки извлечения   *
  725. ;*                     диска                     *
  726. ;* Входные параметры передаются через глобальные *
  727. ;* переменные:                                   *
  728. ;* ChannelNumber - номер канала;                 *
  729. ;* DiskNumber - номер диска на канале.           *
  730. ;*************************************************
  731. proc check_ATAPI_device_event_has_work?
  732.         mov     eax, [timer_ticks]
  733.         sub     eax, [timer_ATAPI_check]
  734.         cmp     eax, 100
  735.         jb      .no
  736.  
  737.         xor     eax, eax
  738.         inc     eax
  739.         ret
  740. ;--------------------------------------
  741. .no:
  742.         xor     eax, eax
  743.         ret
  744. endp
  745. ;-----------------------------------------------------------------------------
  746. align 4
  747. check_ATAPI_device_event:
  748.         pusha
  749.         mov     eax, [timer_ticks]
  750.         sub     eax, [timer_ATAPI_check]
  751.         cmp     eax, 100
  752.         jb      .end_1
  753.  
  754.         pushfd
  755.         mov     al, [DRIVE_DATA+1]
  756.         and     al, 11b
  757.         cmp     al, 10b
  758.         jz      .ide3
  759. ;--------------------------------------
  760. .ide2_1:
  761.         mov     al, [DRIVE_DATA+1]
  762.         and     al, 1100b
  763.         cmp     al, 1000b
  764.         jz      .ide2
  765. ;--------------------------------------
  766. .ide1_1:
  767.         mov     al, [DRIVE_DATA+1]
  768.         and     al, 110000b
  769.         cmp     al, 100000b
  770.         jz      .ide1
  771. ;--------------------------------------
  772. .ide0_1:
  773.         mov     al, [DRIVE_DATA+1]
  774.         and     al, 11000000b
  775.         cmp     al, 10000000b
  776.         jz      .ide0
  777. ;--------------------------------------
  778. .ide7_1:
  779.         mov     al, [DRIVE_DATA+6]
  780.         and     al, 11b
  781.         cmp     al, 10b
  782.         jz      .ide7
  783. ;--------------------------------------
  784. .ide6_1:
  785.         mov     al, [DRIVE_DATA+6]
  786.         and     al, 1100b
  787.         cmp     al, 1000b
  788.         jz      .ide6
  789. ;--------------------------------------
  790. .ide5_1:
  791.         mov     al, [DRIVE_DATA+6]
  792.         and     al, 110000b
  793.         cmp     al, 100000b
  794.         jz      .ide5
  795. ;--------------------------------------
  796. .ide4_1:
  797.         mov     al, [DRIVE_DATA+6]
  798.         and     al, 11000000b
  799.         cmp     al, 10000000b
  800.         jz      .ide4
  801. ;--------------------------------------
  802. .ide11_1:
  803.         mov     al, [DRIVE_DATA+11]
  804.         and     al, 11b
  805.         cmp     al, 10b
  806.         jz      .ide11
  807. ;--------------------------------------
  808. .ide10_1:
  809.         mov     al, [DRIVE_DATA+11]
  810.         and     al, 1100b
  811.         cmp     al, 1000b
  812.         jz      .ide10
  813. ;--------------------------------------
  814. .ide9_1:
  815.         mov     al, [DRIVE_DATA+11]
  816.         and     al, 110000b
  817.         cmp     al, 100000b
  818.         jz      .ide9
  819. ;--------------------------------------
  820. .ide8_1:
  821.         mov     al, [DRIVE_DATA+11]
  822.         and     al, 11000000b
  823.         cmp     al, 10000000b
  824.         jz      .ide8
  825. ;--------------------------------------
  826. .end:
  827.         popfd
  828.         mov     eax, [timer_ticks]
  829.         mov     [timer_ATAPI_check], eax
  830. ;--------------------------------------
  831. .end_1:
  832.         popa
  833.         ret
  834. ;-----------------------------------------------------------------------------
  835. .ide3:
  836.         cli
  837.         cmp     [ATAPI_IDE3_lock], 1
  838.         jne     .ide2_1
  839.  
  840.         cmp     [cd_status], 0
  841.         jne     .end
  842.  
  843.         mov     ecx, ide_channel2_mutex
  844.         call    mutex_lock
  845.         call    reserve_ok2
  846.         mov     [ChannelNumber], 2
  847.         mov     [DiskNumber], 1
  848.         mov     [cdpos], 4
  849.         call    GetEvent_StatusNotification
  850.         cmp     [CDDataBuf+4], byte 1
  851.         jne     @f
  852.  
  853.         call    .eject
  854. ;--------------------------------------
  855. @@:
  856.         call    syscall_cdaudio.free
  857.         jmp     .ide2_1
  858. ;-----------------------------------------------------------------------------
  859. .ide2:
  860.         cli
  861.         cmp     [ATAPI_IDE2_lock], 1
  862.         jne     .ide1_1
  863.  
  864.         cmp     [cd_status], 0
  865.         jne     .end
  866.  
  867.         mov     ecx, ide_channel2_mutex
  868.         call    mutex_lock
  869.         call    reserve_ok2
  870.         mov     [ChannelNumber], 2
  871.         mov     [DiskNumber], 0
  872.         mov     [cdpos], 3
  873.         call    GetEvent_StatusNotification
  874.         cmp     [CDDataBuf+4], byte 1
  875.         jne     @f
  876.  
  877.         call    .eject
  878. ;--------------------------------------
  879. @@:
  880.         call    syscall_cdaudio.free
  881.         jmp     .ide1_1
  882. ;-----------------------------------------------------------------------------
  883. .ide1:
  884.         cli
  885.         cmp     [ATAPI_IDE1_lock], 1
  886.         jne     .ide0_1
  887.  
  888.         cmp     [cd_status], 0
  889.         jne     .end
  890.  
  891.         mov     ecx, ide_channel1_mutex
  892.         call    mutex_lock
  893.         call    reserve_ok2
  894.         mov     [ChannelNumber], 1
  895.         mov     [DiskNumber], 1
  896.         mov     [cdpos], 2
  897.         call    GetEvent_StatusNotification
  898.         cmp     [CDDataBuf+4], byte 1
  899.         jne     @f
  900.  
  901.         call    .eject
  902. ;--------------------------------------
  903. @@:
  904.         call    syscall_cdaudio.free
  905.         jmp     .ide0_1
  906. ;-----------------------------------------------------------------------------
  907. .ide0:
  908.         cli
  909.         cmp     [ATAPI_IDE0_lock], 1
  910.         jne     .ide7_1
  911.  
  912.         cmp     [cd_status], 0
  913.         jne     .end
  914.  
  915.         mov     ecx, ide_channel1_mutex
  916.         call    mutex_lock
  917.         call    reserve_ok2
  918.         mov     [ChannelNumber], 1
  919.         mov     [DiskNumber], 0
  920.         mov     [cdpos], 1
  921.         call    GetEvent_StatusNotification
  922.         cmp     [CDDataBuf+4], byte 1
  923.         jne     @f
  924.  
  925.         call    .eject
  926. ;--------------------------------------
  927. @@:
  928.         call    syscall_cdaudio.free
  929.         jmp     .ide7_1
  930. ;-----------------------------------------------------------------------------
  931. .ide7:
  932.         cli
  933.         cmp     [ATAPI_IDE7_lock], 1
  934.         jne     .ide6_1
  935.  
  936.         cmp     [cd_status], 0
  937.         jne     .end
  938.  
  939.         mov     ecx, ide_channel4_mutex
  940.         call    mutex_lock
  941.         call    reserve_ok2
  942.         mov     [ChannelNumber], 2
  943.         mov     [DiskNumber], 1
  944.         mov     [cdpos], 8
  945.         call    GetEvent_StatusNotification
  946.         cmp     [CDDataBuf+4], byte 1
  947.         jne     @f
  948.  
  949.         call    .eject
  950. ;--------------------------------------
  951. @@:
  952.         call    syscall_cdaudio.free
  953.         jmp     .ide6_1
  954. ;-----------------------------------------------------------------------------
  955. .ide6:
  956.         cli
  957.         cmp     [ATAPI_IDE6_lock], 1
  958.         jne     .ide5_1
  959.  
  960.         cmp     [cd_status], 0
  961.         jne     .end
  962.  
  963.         mov     ecx, ide_channel4_mutex
  964.         call    mutex_lock
  965.         call    reserve_ok2
  966.         mov     [ChannelNumber], 2
  967.         mov     [DiskNumber], 0
  968.         mov     [cdpos], 7
  969.         call    GetEvent_StatusNotification
  970.         cmp     [CDDataBuf+4], byte 1
  971.         jne     @f
  972.  
  973.         call    .eject
  974. ;--------------------------------------
  975. @@:
  976.         call    syscall_cdaudio.free
  977.         jmp     .ide5_1
  978. ;-----------------------------------------------------------------------------
  979. .ide5:
  980.         cli
  981.         cmp     [ATAPI_IDE5_lock], 1
  982.         jne     .ide4_1
  983.  
  984.         cmp     [cd_status], 0
  985.         jne     .end
  986.  
  987.         mov     ecx, ide_channel3_mutex
  988.         call    mutex_lock
  989.         call    reserve_ok2
  990.         mov     [ChannelNumber], 1
  991.         mov     [DiskNumber], 1
  992.         mov     [cdpos], 6
  993.         call    GetEvent_StatusNotification
  994.         cmp     [CDDataBuf+4], byte 1
  995.         jne     @f
  996.  
  997.         call    .eject
  998. ;--------------------------------------
  999. @@:
  1000.         call    syscall_cdaudio.free
  1001.         jmp     .ide4_1
  1002. ;-----------------------------------------------------------------------------
  1003. .ide4:
  1004.         cli
  1005.         cmp     [ATAPI_IDE4_lock], 1
  1006.         jne     .ide11_1
  1007.  
  1008.         cmp     [cd_status], 0
  1009.         jne     .end
  1010.  
  1011.         mov     ecx, ide_channel3_mutex
  1012.         call    mutex_lock
  1013.         call    reserve_ok2
  1014.         mov     [ChannelNumber], 1
  1015.         mov     [DiskNumber], 0
  1016.         mov     [cdpos], 5
  1017.         call    GetEvent_StatusNotification
  1018.         cmp     [CDDataBuf+4], byte 1
  1019.         jne     @f
  1020.  
  1021.         call    .eject
  1022. ;--------------------------------------
  1023. @@:
  1024.         call    syscall_cdaudio.free
  1025.         jmp     .ide11_1
  1026. ;-----------------------------------------------------------------------------
  1027. .ide11:
  1028.         cli
  1029.         cmp     [ATAPI_IDE11_lock], 1
  1030.         jne     .ide10_1
  1031.  
  1032.         cmp     [cd_status], 0
  1033.         jne     .end
  1034.  
  1035.         mov     ecx, ide_channel6_mutex
  1036.         call    mutex_lock
  1037.         call    reserve_ok2
  1038.         mov     [ChannelNumber], 2
  1039.         mov     [DiskNumber], 1
  1040.         mov     [cdpos], 12
  1041.         call    GetEvent_StatusNotification
  1042.         cmp     [CDDataBuf+4], byte 1
  1043.         jne     @f
  1044.  
  1045.         call    .eject
  1046. ;--------------------------------------
  1047. @@:
  1048.         call    syscall_cdaudio.free
  1049.         jmp     .ide10_1
  1050. ;-----------------------------------------------------------------------------
  1051. .ide10:
  1052.         cli
  1053.         cmp     [ATAPI_IDE10_lock], 1
  1054.         jne     .ide9_1
  1055.  
  1056.         cmp     [cd_status], 0
  1057.         jne     .end
  1058.  
  1059.         mov     ecx, ide_channel6_mutex
  1060.         call    mutex_lock
  1061.         call    reserve_ok2
  1062.         mov     [ChannelNumber], 2
  1063.         mov     [DiskNumber], 0
  1064.         mov     [cdpos], 11
  1065.         call    GetEvent_StatusNotification
  1066.         cmp     [CDDataBuf+4], byte 1
  1067.         jne     @f
  1068.  
  1069.         call    .eject
  1070. ;--------------------------------------
  1071. @@:
  1072.         call    syscall_cdaudio.free
  1073.         jmp     .ide9_1
  1074. ;-----------------------------------------------------------------------------
  1075. .ide9:
  1076.         cli
  1077.         cmp     [ATAPI_IDE9_lock], 1
  1078.         jne     .ide8_1
  1079.  
  1080.         cmp     [cd_status], 0
  1081.         jne     .end
  1082.  
  1083.         mov     ecx, ide_channel5_mutex
  1084.         call    mutex_lock
  1085.         call    reserve_ok2
  1086.         mov     [ChannelNumber], 1
  1087.         mov     [DiskNumber], 1
  1088.         mov     [cdpos], 10
  1089.         call    GetEvent_StatusNotification
  1090.         cmp     [CDDataBuf+4], byte 1
  1091.         jne     @f
  1092.  
  1093.         call    .eject
  1094. ;--------------------------------------
  1095. @@:
  1096.         call    syscall_cdaudio.free
  1097.         jmp     .ide8_1
  1098. ;-----------------------------------------------------------------------------
  1099. .ide8:
  1100.         cli
  1101.         cmp     [ATAPI_IDE8_lock], 1
  1102.         jne     .end
  1103.  
  1104.         cmp     [cd_status], 0
  1105.         jne     .end
  1106.  
  1107.         mov     ecx, ide_channel5_mutex
  1108.         call    mutex_lock
  1109.         call    reserve_ok2
  1110.         mov     [ChannelNumber], 1
  1111.         mov     [DiskNumber], 0
  1112.         mov     [cdpos], 9
  1113.         call    GetEvent_StatusNotification
  1114.         cmp     [CDDataBuf+4], byte 1
  1115.         jne     @f
  1116.  
  1117.         call    .eject
  1118. ;--------------------------------------
  1119. @@:
  1120.         call    syscall_cdaudio.free
  1121.         jmp     .end
  1122. ;-----------------------------------------------------------------------------
  1123. .eject:
  1124.         call    clear_CD_cache
  1125.         call    allow_medium_removal
  1126.         mov     [ignore_CD_eject_wait], 1
  1127.         call    EjectMedium
  1128.         mov     [ignore_CD_eject_wait], 0
  1129.         ret
  1130. ;-----------------------------------------------------------------------------
  1131. iglobal
  1132. timer_ATAPI_check dd 0
  1133. ATAPI_IDE0_lock db 0
  1134. ATAPI_IDE1_lock db 0
  1135. ATAPI_IDE2_lock db 0
  1136. ATAPI_IDE3_lock db 0
  1137. ATAPI_IDE4_lock db 0
  1138. ATAPI_IDE5_lock db 0
  1139. ATAPI_IDE6_lock db 0
  1140. ATAPI_IDE7_lock db 0
  1141. ATAPI_IDE8_lock db 0
  1142. ATAPI_IDE9_lock db 0
  1143. ATAPI_IDE10_lock db 0
  1144. ATAPI_IDE11_lock db 0
  1145. ignore_CD_eject_wait db 0
  1146. endg
  1147. ;-----------------------------------------------------------------------------
  1148. ;*************************************************
  1149. ;* Получить сообщение о событии или состоянии    *
  1150. ;*                  устройства                   *
  1151. ;* Входные параметры передаются через глобальные *
  1152. ;* переменные:                                   *
  1153. ;* ChannelNumber - номер канала;                 *
  1154. ;* DiskNumber - номер диска на канале.           *
  1155. ;*************************************************
  1156. GetEvent_StatusNotification:
  1157.         pusha
  1158.         mov     [CDDataBuf_pointer], CDDataBuf
  1159. ; Очистить буфер пакетной команды
  1160.         call    clear_packet_buffer
  1161. ; Задать код команды
  1162.         mov     [PacketCommand], byte 4Ah
  1163.         mov     [PacketCommand+1], byte 00000001b
  1164. ; Задать запрос класса сообщений
  1165.         mov     [PacketCommand+4], byte 00010000b
  1166. ; Размер выделенной области
  1167.         mov     [PacketCommand+7], byte 8h
  1168.         mov     [PacketCommand+8], byte 0h
  1169. ; Подать команду
  1170.         call    SendPacketDatCommand
  1171.         popa
  1172.         ret
  1173. ;-----------------------------------------------------------------------------
  1174. ;*************************************************
  1175. ; прочитать информацию из TOC
  1176. ;* Входные параметры передаются через глобальные *
  1177. ;* переменные:                                   *
  1178. ;* ChannelNumber - номер канала;                 *
  1179. ;* DiskNumber - номер диска на канале.           *
  1180. ;*************************************************
  1181. Read_TOC:
  1182.         pusha
  1183.         mov     [CDDataBuf_pointer], CDDataBuf
  1184. ; Очистить буфер пакетной команды
  1185.         call    clear_packet_buffer
  1186. ; Сформировать пакетную команду для считывания
  1187. ; сектора данных
  1188.         mov     [PacketCommand], byte 0x43
  1189.         ; Задать формат
  1190.         mov     [PacketCommand+2], byte 1
  1191. ; Размер выделенной области
  1192.         mov     [PacketCommand+7], byte 0xFF
  1193.         mov     [PacketCommand+8], byte 0h
  1194. ; Подать команду
  1195.         call    SendPacketDatCommand
  1196.         popa
  1197.         ret
  1198. ;-----------------------------------------------------------------------------
  1199. ;*************************************************
  1200. ;* ОПРЕДЕЛИТЬ ОБЩЕЕ КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ *
  1201. ;* Входные параметры передаются через глобальные *
  1202. ;* переменные:                                   *
  1203. ;* ChannelNumber - номер канала;                 *
  1204. ;* DiskNumber - номер диска на канале.           *
  1205. ;*************************************************
  1206. ;ReadCapacity:
  1207. ;       pusha
  1208. ;; Очистить буфер пакетной команды
  1209. ;       call  clear_packet_buffer
  1210. ;; Задать размер буфера в байтах
  1211. ;       mov     [CDBlockSize],8
  1212. ;; Сформировать команду READ CAPACITY
  1213. ;       mov     [PacketCommand],word 25h
  1214. ;; Подать команду
  1215. ;       call    SendPacketDatCommand
  1216. ;       popa
  1217. ;       ret
  1218. ;-----------------------------------------------------------------------------
  1219. clear_packet_buffer:
  1220. ; Очистить буфер пакетной команды
  1221.         and     [PacketCommand], dword 0
  1222.         and     [PacketCommand+4], dword 0
  1223.         and     [PacketCommand+8], dword 0
  1224.         ret
  1225. ;-----------------------------------------------------------------------------
  1226.