Subversion Repositories Kolibri OS

Rev

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