Subversion Repositories Kolibri OS

Rev

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