Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 3785 $
  9.  
  10.  
  11. ;******************************************************
  12. ; поиск приводов HDD и CD
  13. ; автор исходного текста Кулаков Владимир Геннадьевич.
  14. ; адаптация и доработка Mario79
  15. ;******************************************************
  16.  
  17. ;****************************************************
  18. ;*                 ПОИСК HDD и CD                   *
  19. ;****************************************************
  20.         cmp     [IDEContrProgrammingInterface], 0
  21.         je      EndFindHDD
  22.  
  23. FindHDD:
  24.         mov     [ChannelNumber], 1
  25.         mov     [DiskNumber], 0
  26.         call    FindHDD_3
  27. ;        mov     ax,[Sector512+176]
  28. ;        mov     [DRIVE_DATA+6],ax
  29. ;        mov     ax,[Sector512+126]
  30. ;        mov     [DRIVE_DATA+8],ax
  31. ;        mov     ax,[Sector512+128]
  32. ;        mov     [DRIVE_DATA+8],ax
  33.         mov     [DiskNumber], 1
  34.         call    FindHDD_3
  35. ;        mov     al,[Sector512+176]
  36. ;        mov     [DRIVE_DATA+7],al
  37.         inc     [ChannelNumber]
  38.         mov     [DiskNumber], 0
  39.         call    FindHDD_3
  40. ;        mov     al,[Sector512+176]
  41. ;        mov     [DRIVE_DATA+8],al
  42.         mov     [DiskNumber], 1
  43.         call    FindHDD_1
  44. ;        mov     al,[Sector512+176]
  45. ;        mov     [DRIVE_DATA+9],al
  46.  
  47.         jmp     EndFindHDD
  48.  
  49. FindHDD_1:
  50.         DEBUGF  1, "K : Channel %d ",[ChannelNumber]:2
  51.         DEBUGF  1, "Disk %d\n",[DiskNumber]:1
  52.         call    ReadHDD_ID
  53.         cmp     [DevErrorCode], 0
  54.         jne     FindHDD_2
  55.         cmp     [Sector512+6], word 16
  56.         ja      FindHDD_2
  57.         cmp     [Sector512+12], word 255
  58.         ja      FindHDD_2
  59.         inc     byte [DRIVE_DATA+1]
  60.         jmp     Print_Device_Name
  61.    FindHDD_2:
  62.         call    DeviceReset
  63.         cmp     [DevErrorCode], 0
  64.         jne     FindHDD_2_2
  65.         call    ReadCD_ID
  66.         cmp     [DevErrorCode], 0
  67.         jne     FindHDD_2_2
  68.         inc     byte [DRIVE_DATA+1]
  69.         inc     byte [DRIVE_DATA+1]
  70. Print_Device_Name:      
  71.         pushad
  72.         pushfd
  73.         mov     esi, Sector512+27*2
  74.         mov     edi, dev_name
  75.         mov     ecx, 20
  76.         cld
  77. @@:
  78.         lodsw
  79.         xchg    ah, al
  80.         stosw
  81.         loop    @b
  82.         popfd
  83.         popad
  84.         DEBUGF 1, "K : Dev: %s \n", dev_name
  85.    FindHDD_2_2:
  86.         ret
  87.  
  88. FindHDD_3:
  89.         call    FindHDD_1
  90.         shl     byte [DRIVE_DATA+1], 2
  91.         ret
  92.  
  93. ; Адрес считываемого сектора в режиме LBA
  94. uglobal
  95. SectorAddress   DD ?
  96. dev_name:
  97.         rb 41
  98. endg
  99. ;*************************************************
  100. ;*     ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА      *
  101. ;* Входные параметры передаются через глобальные *
  102. ;* переменные:                                   *
  103. ;* ChannelNumber - номер канала (1 или 2);       *
  104. ;* DiskNumber - номер диска на канале (0 или 1). *
  105. ;* Идентификационный блок данных считывается     *
  106. ;* в массив Sector512.                           *
  107. ;*************************************************
  108. ReadHDD_ID:
  109. ; Задать режим CHS
  110.         mov     [ATAAddressMode], 0
  111. ; Послать команду идентификации устройства
  112.         mov     [ATAFeatures], 0
  113.         mov     [ATAHead], 0
  114.         mov     [ATACommand], 0ECh
  115.         call    SendCommandToHDD
  116.         cmp     [DevErrorCode], 0;проверить код ошибки
  117.         jne     @@End  ;закончить, сохранив код ошибки
  118.         mov     DX, [ATABasePortAddr]
  119.         add     DX, 7    ;адрес регистра состояни
  120.         mov     ecx, 0xffff
  121. @@WaitCompleet:
  122.         ; Проверить время выполнения команды
  123.         dec     ecx
  124. ;        cmp  ecx,0
  125.         jz      @@Error1  ;ошибка тайм-аута
  126.         ; Проверить готовность
  127.         in      AL, DX
  128.         test    AL, 80h  ;состояние сигнала BSY
  129.         jnz     @@WaitCompleet
  130.         test    AL, 1    ;состояние сигнала ERR
  131.         jnz     @@Error6
  132.         test    AL, 08h  ;состояние сигнала DRQ
  133.         jz      @@WaitCompleet
  134. ; Принять блок данных от контроллера
  135. ;        mov     AX,DS
  136. ;        mov     ES,AX
  137.         mov     EDI, Sector512 ;offset Sector512
  138.         mov     DX, [ATABasePortAddr];регистр данных
  139.         mov     CX, 256  ;число считываемых слов
  140.         rep insw         ;принять блок данных
  141.         ret
  142. ; Записать код ошибки
  143. @@Error1:
  144.         mov     [DevErrorCode], 1
  145.         ret
  146. @@Error6:
  147.         mov     [DevErrorCode], 6
  148. @@End:
  149.         ret
  150.  
  151.  
  152. iglobal
  153. ; Стандартные базовые адреса каналов 1 и 2
  154. StandardATABases DW 1F0h, 170h
  155. endg
  156. uglobal
  157. ; Номер канала
  158. ChannelNumber   DW ?
  159. ; Номер диска
  160. DiskNumber      DB ?
  161. ; Базовый адрес группы портов контроллера ATA
  162. ATABasePortAddr DW ?
  163. ; Параметры ATA-команды
  164. ATAFeatures     DB ? ;особенности
  165. ATASectorCount  DB ? ;количество обрабатываемых секторов
  166. ATASectorNumber DB ? ;номер начального сектора
  167. ATACylinder     DW ? ;номер начального цилиндра
  168. ATAHead         DB ? ;номер начальной головки
  169. ATAAddressMode  DB ? ;режим адресации (0 - CHS, 1 - LBA)
  170. ATACommand      DB ? ;код команды, подлежащей выполнению
  171. ; Код ошибки (0 - нет ошибок, 1 - превышен допустимый
  172. ; интервал ожидания, 2 - неверный код режима адресации,
  173. ; 3 - неверный номер канала, 4 - неверный номер диска,
  174. ; 5 - неверный номер головки, 6 - ошибка при выполнении
  175. ; команды)
  176. DevErrorCode dd ?
  177. endg
  178. ;****************************************************
  179. ;*          ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ         *
  180. ;* Входные параметры передаются через глобальные    *
  181. ;* переменные:                                      *
  182. ;* ChannelNumber - номер канала (1 или 2);          *
  183. ;* DiskNumber - номер диска (0 или 1);              *
  184. ;* ATAFeatures - "особенности";                     *
  185. ;* ATASectorCount - количество секторов;            *
  186. ;* ATASectorNumber - номер начального сектора;      *
  187. ;* ATACylinder - номер начального цилиндра;         *
  188. ;* ATAHead - номер начальной головки;               *
  189. ;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); *
  190. ;* ATACommand - код команды.                        *
  191. ;* После успешного выполнения функции:              *
  192. ;* в ATABasePortAddr - базовый адрес HDD;           *
  193. ;* в DevErrorCode - ноль.                           *
  194. ;* При возникновении ошибки в DevErrorCode будет    *
  195. ;* возвращен код ошибки.                            *
  196. ;****************************************************
  197. SendCommandToHDD:
  198. ; Проверить значение кода режима
  199.         cmp     [ATAAddressMode], 1
  200.         ja      @@Err2
  201. ; Проверить корректность номера канала
  202.         mov     BX, [ChannelNumber]
  203.         cmp     BX, 1
  204.         jb      @@Err3
  205.         cmp     BX, 2
  206.         ja      @@Err3
  207. ; Установить базовый адрес
  208.         dec     BX
  209.         shl     BX, 1
  210.         movzx   ebx, bx
  211.         mov     AX, [ebx+StandardATABases]
  212.         mov     [ATABasePortAddr], AX
  213. ; Ожидание готовности HDD к приему команды
  214.         ; Выбрать нужный диск
  215.         mov     DX, [ATABasePortAddr]
  216.         add     DX, 6   ;адрес регистра головок
  217.         mov     AL, [DiskNumber]
  218.         cmp     AL, 1   ;проверить номера диска
  219.         ja      @@Err4
  220.         shl     AL, 4
  221.         or      AL, 10100000b
  222.         out     DX, AL
  223.         ; Ожидать, пока диск не будет готов
  224.         inc     DX
  225.         mov     ecx, 0xfff
  226. ;        mov     eax,[timer_ticks]
  227. ;        mov     [TickCounter_1],eax
  228. @@WaitHDReady:
  229.         ; Проверить время ожидани
  230.         dec     ecx
  231. ;        cmp  ecx,0
  232.         jz      @@Err1
  233. ;        mov     eax,[timer_ticks]
  234. ;        sub     eax,[TickCounter_1]
  235. ;        cmp     eax,300    ;ожидать 300 тиков
  236. ;        ja      @@Err1   ;ошибка тайм-аута
  237.         ; Прочитать регистр состояни
  238.         in      AL, DX
  239.         ; Проверить состояние сигнала BSY
  240.         test    AL, 80h
  241.         jnz     @@WaitHDReady
  242.         ; Проверить состояние сигнала DRQ
  243.         test    AL, 08h
  244.         jnz     @@WaitHDReady
  245. ; Загрузить команду в регистры контроллера
  246.         cli
  247.         mov     DX, [ATABasePortAddr]
  248.         inc     DX      ;регистр "особенностей"
  249.         mov     AL, [ATAFeatures]
  250.         out     DX, AL
  251.         inc     DX      ;счетчик секторов
  252.         mov     AL, [ATASectorCount]
  253.         out     DX, AL
  254.         inc     DX      ;регистр номера сектора
  255.         mov     AL, [ATASectorNumber]
  256.         out     DX, AL
  257.         inc     DX      ;номер цилиндра (младший байт)
  258.         mov     AX, [ATACylinder]
  259.         out     DX, AL
  260.         inc     DX      ;номер цилиндра (старший байт)
  261.         mov     AL, AH
  262.         out     DX, AL
  263.         inc     DX      ;номер головки/номер диска
  264.         mov     AL, [DiskNumber]
  265.         shl     AL, 4
  266.         cmp     [ATAHead], 0Fh;проверить номер головки
  267.         ja      @@Err5
  268.         or      AL, [ATAHead]
  269.         or      AL, 10100000b
  270.         mov     AH, [ATAAddressMode]
  271.         shl     AH, 6
  272.         or      AL, AH
  273.         out     DX, AL
  274. ; Послать команду
  275.         mov     AL, [ATACommand]
  276.         inc     DX      ;регистр команд
  277.         out     DX, AL
  278.         sti
  279. ; Сбросить признак ошибки
  280.         mov     [DevErrorCode], 0
  281.         ret
  282. ; Записать код ошибки
  283. @@Err1:
  284.         mov     [DevErrorCode], 1
  285.         ret
  286. @@Err2:
  287.         mov     [DevErrorCode], 2
  288.         ret
  289. @@Err3:
  290.         mov     [DevErrorCode], 3
  291.         ret
  292. @@Err4:
  293.         mov     [DevErrorCode], 4
  294.         ret
  295. @@Err5:
  296.         mov     [DevErrorCode], 5
  297. ; Завершение работы программы
  298.         ret
  299.  
  300. ;*************************************************
  301. ;*     ЧТЕНИЕ ИДЕНТИФИКАТОРА УСТРОЙСТВА ATAPI    *
  302. ;* Входные параметры передаются через глобальные *
  303. ;* перменные:                                    *
  304. ;* ChannelNumber - номер канала;                 *
  305. ;* DiskNumber - номер диска на канале.           *
  306. ;* Идентификационный блок данных считывается     *
  307. ;* в массив Sector512.                           *
  308. ;*************************************************
  309. ReadCD_ID:
  310. ; Задать режим CHS
  311.         mov     [ATAAddressMode], 0
  312. ; Послать команду идентификации устройства
  313.         mov     [ATAFeatures], 0
  314.         mov     [ATASectorCount], 0
  315.         mov     [ATASectorNumber], 0
  316.         mov     [ATACylinder], 0
  317.         mov     [ATAHead], 0
  318.         mov     [ATACommand], 0A1h
  319.         call    SendCommandToHDD
  320.         cmp     [DevErrorCode], 0;проверить код ошибки
  321.         jne     @@End_1  ;закончить, сохранив код ошибки
  322. ; Ожидать готовность данных HDD
  323.         mov     DX, [ATABasePortAddr]
  324.         add     DX, 7  ;порт 1х7h
  325.         mov     ecx, 0xffff
  326. @@WaitCompleet_1:
  327.         ; Проверить врем
  328.         dec     ecx
  329. ;        cmp    ecx,0
  330.         jz      @@Error1_1 ;ошибка тайм-аута
  331.         ; Проверить готовность
  332.         in      AL, DX
  333.         test    AL, 80h  ;состояние сигнала BSY
  334.         jnz     @@WaitCompleet_1
  335.         test    AL, 1    ;состояние сигнала ERR
  336.         jnz     @@Error6_1
  337.         test    AL, 08h  ;состояние сигнала DRQ
  338.         jz      @@WaitCompleet_1
  339. ; Принять блок данных от контроллера
  340. ;        mov     AX,DS
  341. ;        mov     ES,AX
  342.         mov     EDI, Sector512 ;offset Sector512
  343.         mov     DX, [ATABasePortAddr];порт 1x0h
  344.         mov     CX, 256;число считываемых слов
  345.         rep insw
  346.         ret
  347. ; Записать код ошибки
  348. @@Error1_1:
  349.         mov     [DevErrorCode], 1
  350.         ret
  351. @@Error6_1:
  352.         mov     [DevErrorCode], 6
  353. @@End_1:
  354.         ret
  355.  
  356. ;*************************************************
  357. ;*                СБРОС УСТРОЙСТВА               *
  358. ;* Входные параметры передаются через глобальные *
  359. ;* переменные:                                   *
  360. ;* ChannelNumber - номер канала (1 или 2);       *
  361. ;* DiskNumber - номер диска (0 или 1).           *
  362. ;*************************************************
  363. DeviceReset:
  364. ; Проверить корректность номера канала
  365.         mov     BX, [ChannelNumber]
  366.         cmp     BX, 1
  367.         jb      @@Err3_2
  368.         cmp     BX, 2
  369.         ja      @@Err3_2
  370. ; Установить базовый адрес
  371.         dec     BX
  372.         shl     BX, 1
  373.         movzx   ebx, bx
  374.         mov     DX, [ebx+StandardATABases]
  375.         mov     [ATABasePortAddr], DX
  376. ; Выбрать нужный диск
  377.         add     DX, 6   ;адрес регистра головок
  378.         mov     AL, [DiskNumber]
  379.         cmp     AL, 1   ;проверить номера диска
  380.         ja      @@Err4_2
  381.         shl     AL, 4
  382.         or      AL, 10100000b
  383.         out     DX, AL
  384. ; Послать команду "Сброс"
  385.         mov     AL, 08h
  386.         inc     DX      ;регистр команд
  387.         out     DX, AL
  388.         mov     ecx, 0x80000
  389. @@WaitHDReady_1:
  390.         ; Проверить время ожидани
  391.         dec     ecx
  392. ;        cmp     ecx,0
  393.         je      @@Err1_2 ;ошибка тайм-аута
  394.         ; Прочитать регистр состояни
  395.         in      AL, DX
  396.         ; Проверить состояние сигнала BSY
  397.         test    AL, 80h
  398.         jnz     @@WaitHDReady_1
  399. ; Сбросить признак ошибки
  400.         mov     [DevErrorCode], 0
  401.         ret
  402. ; Обработка ошибок
  403. @@Err1_2:
  404.         mov     [DevErrorCode], 1
  405.         ret
  406. @@Err3_2:
  407.         mov     [DevErrorCode], 3
  408.         ret
  409. @@Err4_2:
  410.         mov     [DevErrorCode], 4
  411. ; Записать код ошибки
  412.         ret
  413.  
  414. EndFindHDD:
  415.  
  416.