Subversion Repositories Kolibri OS

Rev

Rev 388 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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