Subversion Repositories Kolibri OS

Rev

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