Subversion Repositories Kolibri OS

Rev

Rev 837 | Details | Compare with Previous | Last modification | View Log | RSS feed

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