Subversion Repositories Kolibri OS

Rev

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