Subversion Repositories Kolibri OS

Rev

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