Subversion Repositories Kolibri OS

Rev

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