Subversion Repositories Kolibri OS

Rev

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