Subversion Repositories Kolibri OS

Rev

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