Subversion Repositories Kolibri OS

Rev

Rev 5565 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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