Subversion Repositories Kolibri OS

Rev

Rev 3881 | Rev 4700 | 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: 4624 $
  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.  
  86.         xor     eax, eax
  87.         mov     ax, [Sector512+64*2]
  88.         DEBUGF  1, "K : PIO mode possible modes %x\n", al
  89.         mov     ax, [Sector512+51*2]
  90.         mov     al, ah
  91.         call    convert_Sector512_value
  92.         DEBUGF  1, "K : PIO mode set mode %x\n", ah
  93.         mov     ax, [Sector512+63*2]
  94.         DEBUGF  1, "K : Multiword DMA possible modes %x\n", al
  95.         mov     al, ah
  96.         call    convert_Sector512_value
  97.         DEBUGF  1, "K : Multiword DMA set mode %x\n", ah
  98.         mov     ax, [Sector512+88*2]
  99.         DEBUGF  1, "K : Ultra DMA possible modes %x\n", al
  100.         mov     al, ah
  101.         call    convert_Sector512_value
  102.         DEBUGF  1, "K : Ultra DMA set mode %x\n", ah
  103.    FindHDD_2_2:
  104.         ret
  105. ;-----------------------------------------------------------------------------
  106. FindHDD_3:
  107.         call    FindHDD_1
  108.         shl     byte [DRIVE_DATA+1], 2
  109.         ret
  110. ;-----------------------------------------------------------------------------
  111. convert_Sector512_value:
  112.         mov     ecx, 8
  113.         xor     ah, ah
  114. @@:
  115.         test    al, 1b
  116.         jnz     .end
  117.  
  118.         shr     al, 1
  119.         inc     ah
  120.         loop    @b
  121.  
  122.         xor     ah, ah
  123. .end:
  124.         ret
  125. ;-----------------------------------------------------------------------------
  126. ; Адрес считываемого сектора в режиме LBA
  127. uglobal
  128. SectorAddress   DD ?
  129. dev_name:
  130.         rb 41
  131. endg
  132. ;*************************************************
  133. ;*     ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА      *
  134. ;* Входные параметры передаются через глобальные *
  135. ;* переменные:                                   *
  136. ;* ChannelNumber - номер канала (1 или 2);       *
  137. ;* DiskNumber - номер диска на канале (0 или 1). *
  138. ;* Идентификационный блок данных считывается     *
  139. ;* в массив Sector512.                           *
  140. ;*************************************************
  141. ReadHDD_ID:
  142. ; Задать режим CHS
  143.         mov     [ATAAddressMode], 0
  144. ; Послать команду идентификации устройства
  145.         mov     [ATAFeatures], 0
  146.         mov     [ATAHead], 0
  147.         mov     [ATACommand], 0ECh
  148.         call    SendCommandToHDD
  149.         cmp     [DevErrorCode], 0;проверить код ошибки
  150.         jne     @@End  ;закончить, сохранив код ошибки
  151.         mov     DX, [ATABasePortAddr]
  152.         add     DX, 7    ;адрес регистра состояни
  153.         mov     ecx, 0xffff
  154. @@WaitCompleet:
  155.         ; Проверить время выполнения команды
  156.         dec     ecx
  157. ;        cmp  ecx,0
  158.         jz      @@Error1  ;ошибка тайм-аута
  159.         ; Проверить готовность
  160.         in      AL, DX
  161.         test    AL, 80h  ;состояние сигнала BSY
  162.         jnz     @@WaitCompleet
  163.         test    AL, 1    ;состояние сигнала ERR
  164.         jnz     @@Error6
  165.         test    AL, 08h  ;состояние сигнала DRQ
  166.         jz      @@WaitCompleet
  167. ; Принять блок данных от контроллера
  168. ;        mov     AX,DS
  169. ;        mov     ES,AX
  170.         mov     EDI, Sector512 ;offset Sector512
  171.         mov     DX, [ATABasePortAddr];регистр данных
  172.         mov     CX, 256  ;число считываемых слов
  173.         rep insw         ;принять блок данных
  174.         ret
  175. ; Записать код ошибки
  176. @@Error1:
  177.         mov     [DevErrorCode], 1
  178.         ret
  179. @@Error6:
  180.         mov     [DevErrorCode], 6
  181. @@End:
  182.         ret
  183.  
  184.  
  185. iglobal
  186. ; Стандартные базовые адреса каналов 1 и 2
  187. StandardATABases DW 1F0h, 170h
  188. endg
  189. uglobal
  190. ; Номер канала
  191. ChannelNumber   DW ?
  192. ; Номер диска
  193. DiskNumber      DB ?
  194. ; Базовый адрес группы портов контроллера ATA
  195. ATABasePortAddr DW ?
  196. ; Параметры ATA-команды
  197. ATAFeatures     DB ? ;особенности
  198. ATASectorCount  DB ? ;количество обрабатываемых секторов
  199. ATASectorNumber DB ? ;номер начального сектора
  200. ATACylinder     DW ? ;номер начального цилиндра
  201. ATAHead         DB ? ;номер начальной головки
  202. ATAAddressMode  DB ? ;режим адресации (0 - CHS, 1 - LBA)
  203. ATACommand      DB ? ;код команды, подлежащей выполнению
  204. ; Код ошибки (0 - нет ошибок, 1 - превышен допустимый
  205. ; интервал ожидания, 2 - неверный код режима адресации,
  206. ; 3 - неверный номер канала, 4 - неверный номер диска,
  207. ; 5 - неверный номер головки, 6 - ошибка при выполнении
  208. ; команды)
  209. DevErrorCode dd ?
  210. endg
  211. ;****************************************************
  212. ;*          ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ         *
  213. ;* Входные параметры передаются через глобальные    *
  214. ;* переменные:                                      *
  215. ;* ChannelNumber - номер канала (1 или 2);          *
  216. ;* DiskNumber - номер диска (0 или 1);              *
  217. ;* ATAFeatures - "особенности";                     *
  218. ;* ATASectorCount - количество секторов;            *
  219. ;* ATASectorNumber - номер начального сектора;      *
  220. ;* ATACylinder - номер начального цилиндра;         *
  221. ;* ATAHead - номер начальной головки;               *
  222. ;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); *
  223. ;* ATACommand - код команды.                        *
  224. ;* После успешного выполнения функции:              *
  225. ;* в ATABasePortAddr - базовый адрес HDD;           *
  226. ;* в DevErrorCode - ноль.                           *
  227. ;* При возникновении ошибки в DevErrorCode будет    *
  228. ;* возвращен код ошибки.                            *
  229. ;****************************************************
  230. SendCommandToHDD:
  231. ; Проверить значение кода режима
  232.         cmp     [ATAAddressMode], 1
  233.         ja      @@Err2
  234. ; Проверить корректность номера канала
  235.         mov     BX, [ChannelNumber]
  236.         cmp     BX, 1
  237.         jb      @@Err3
  238.         cmp     BX, 2
  239.         ja      @@Err3
  240. ; Установить базовый адрес
  241.         dec     BX
  242.         shl     BX, 1
  243.         movzx   ebx, bx
  244.         mov     AX, [ebx+StandardATABases]
  245.         mov     [ATABasePortAddr], AX
  246. ; Ожидание готовности HDD к приему команды
  247.         ; Выбрать нужный диск
  248.         mov     DX, [ATABasePortAddr]
  249.         add     DX, 6   ;адрес регистра головок
  250.         mov     AL, [DiskNumber]
  251.         cmp     AL, 1   ;проверить номера диска
  252.         ja      @@Err4
  253.         shl     AL, 4
  254.         or      AL, 10100000b
  255.         out     DX, AL
  256.         ; Ожидать, пока диск не будет готов
  257.         inc     DX
  258.         mov     ecx, 0xfff
  259. ;        mov     eax,[timer_ticks]
  260. ;        mov     [TickCounter_1],eax
  261. @@WaitHDReady:
  262.         ; Проверить время ожидани
  263.         dec     ecx
  264. ;        cmp  ecx,0
  265.         jz      @@Err1
  266. ;        mov     eax,[timer_ticks]
  267. ;        sub     eax,[TickCounter_1]
  268. ;        cmp     eax,300    ;ожидать 300 тиков
  269. ;        ja      @@Err1   ;ошибка тайм-аута
  270.         ; Прочитать регистр состояни
  271.         in      AL, DX
  272.         ; Проверить состояние сигнала BSY
  273.         test    AL, 80h
  274.         jnz     @@WaitHDReady
  275.         ; Проверить состояние сигнала DRQ
  276.         test    AL, 08h
  277.         jnz     @@WaitHDReady
  278. ; Загрузить команду в регистры контроллера
  279.         cli
  280.         mov     DX, [ATABasePortAddr]
  281.         inc     DX      ;регистр "особенностей"
  282.         mov     AL, [ATAFeatures]
  283.         out     DX, AL
  284.         inc     DX      ;счетчик секторов
  285.         mov     AL, [ATASectorCount]
  286.         out     DX, AL
  287.         inc     DX      ;регистр номера сектора
  288.         mov     AL, [ATASectorNumber]
  289.         out     DX, AL
  290.         inc     DX      ;номер цилиндра (младший байт)
  291.         mov     AX, [ATACylinder]
  292.         out     DX, AL
  293.         inc     DX      ;номер цилиндра (старший байт)
  294.         mov     AL, AH
  295.         out     DX, AL
  296.         inc     DX      ;номер головки/номер диска
  297.         mov     AL, [DiskNumber]
  298.         shl     AL, 4
  299.         cmp     [ATAHead], 0Fh;проверить номер головки
  300.         ja      @@Err5
  301.         or      AL, [ATAHead]
  302.         or      AL, 10100000b
  303.         mov     AH, [ATAAddressMode]
  304.         shl     AH, 6
  305.         or      AL, AH
  306.         out     DX, AL
  307. ; Послать команду
  308.         mov     AL, [ATACommand]
  309.         inc     DX      ;регистр команд
  310.         out     DX, AL
  311.         sti
  312. ; Сбросить признак ошибки
  313.         mov     [DevErrorCode], 0
  314.         ret
  315. ; Записать код ошибки
  316. @@Err1:
  317.         mov     [DevErrorCode], 1
  318.         ret
  319. @@Err2:
  320.         mov     [DevErrorCode], 2
  321.         ret
  322. @@Err3:
  323.         mov     [DevErrorCode], 3
  324.         ret
  325. @@Err4:
  326.         mov     [DevErrorCode], 4
  327.         ret
  328. @@Err5:
  329.         mov     [DevErrorCode], 5
  330. ; Завершение работы программы
  331.         ret
  332.  
  333. ;*************************************************
  334. ;*     ЧТЕНИЕ ИДЕНТИФИКАТОРА УСТРОЙСТВА ATAPI    *
  335. ;* Входные параметры передаются через глобальные *
  336. ;* перменные:                                    *
  337. ;* ChannelNumber - номер канала;                 *
  338. ;* DiskNumber - номер диска на канале.           *
  339. ;* Идентификационный блок данных считывается     *
  340. ;* в массив Sector512.                           *
  341. ;*************************************************
  342. ReadCD_ID:
  343. ; Задать режим CHS
  344.         mov     [ATAAddressMode], 0
  345. ; Послать команду идентификации устройства
  346.         mov     [ATAFeatures], 0
  347.         mov     [ATASectorCount], 0
  348.         mov     [ATASectorNumber], 0
  349.         mov     [ATACylinder], 0
  350.         mov     [ATAHead], 0
  351.         mov     [ATACommand], 0A1h
  352.         call    SendCommandToHDD
  353.         cmp     [DevErrorCode], 0;проверить код ошибки
  354.         jne     @@End_1  ;закончить, сохранив код ошибки
  355. ; Ожидать готовность данных HDD
  356.         mov     DX, [ATABasePortAddr]
  357.         add     DX, 7  ;порт 1х7h
  358.         mov     ecx, 0xffff
  359. @@WaitCompleet_1:
  360.         ; Проверить врем
  361.         dec     ecx
  362. ;        cmp    ecx,0
  363.         jz      @@Error1_1 ;ошибка тайм-аута
  364.         ; Проверить готовность
  365.         in      AL, DX
  366.         test    AL, 80h  ;состояние сигнала BSY
  367.         jnz     @@WaitCompleet_1
  368.         test    AL, 1    ;состояние сигнала ERR
  369.         jnz     @@Error6_1
  370.         test    AL, 08h  ;состояние сигнала DRQ
  371.         jz      @@WaitCompleet_1
  372. ; Принять блок данных от контроллера
  373. ;        mov     AX,DS
  374. ;        mov     ES,AX
  375.         mov     EDI, Sector512 ;offset Sector512
  376.         mov     DX, [ATABasePortAddr];порт 1x0h
  377.         mov     CX, 256;число считываемых слов
  378.         rep insw
  379.         ret
  380. ; Записать код ошибки
  381. @@Error1_1:
  382.         mov     [DevErrorCode], 1
  383.         ret
  384. @@Error6_1:
  385.         mov     [DevErrorCode], 6
  386. @@End_1:
  387.         ret
  388.  
  389. ;*************************************************
  390. ;*                СБРОС УСТРОЙСТВА               *
  391. ;* Входные параметры передаются через глобальные *
  392. ;* переменные:                                   *
  393. ;* ChannelNumber - номер канала (1 или 2);       *
  394. ;* DiskNumber - номер диска (0 или 1).           *
  395. ;*************************************************
  396. DeviceReset:
  397. ; Проверить корректность номера канала
  398.         mov     BX, [ChannelNumber]
  399.         cmp     BX, 1
  400.         jb      @@Err3_2
  401.         cmp     BX, 2
  402.         ja      @@Err3_2
  403. ; Установить базовый адрес
  404.         dec     BX
  405.         shl     BX, 1
  406.         movzx   ebx, bx
  407.         mov     DX, [ebx+StandardATABases]
  408.         mov     [ATABasePortAddr], DX
  409. ; Выбрать нужный диск
  410.         add     DX, 6   ;адрес регистра головок
  411.         mov     AL, [DiskNumber]
  412.         cmp     AL, 1   ;проверить номера диска
  413.         ja      @@Err4_2
  414.         shl     AL, 4
  415.         or      AL, 10100000b
  416.         out     DX, AL
  417. ; Послать команду "Сброс"
  418.         mov     AL, 08h
  419.         inc     DX      ;регистр команд
  420.         out     DX, AL
  421.         mov     ecx, 0x80000
  422. @@WaitHDReady_1:
  423.         ; Проверить время ожидани
  424.         dec     ecx
  425. ;        cmp     ecx,0
  426.         je      @@Err1_2 ;ошибка тайм-аута
  427.         ; Прочитать регистр состояни
  428.         in      AL, DX
  429.         ; Проверить состояние сигнала BSY
  430.         test    AL, 80h
  431.         jnz     @@WaitHDReady_1
  432. ; Сбросить признак ошибки
  433.         mov     [DevErrorCode], 0
  434.         ret
  435. ; Обработка ошибок
  436. @@Err1_2:
  437.         mov     [DevErrorCode], 1
  438.         ret
  439. @@Err3_2:
  440.         mov     [DevErrorCode], 3
  441.         ret
  442. @@Err4_2:
  443.         mov     [DevErrorCode], 4
  444. ; Записать код ошибки
  445.         ret
  446.  
  447. EndFindHDD:
  448.  
  449.