Subversion Repositories Kolibri OS

Rev

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