Subversion Repositories Kolibri OS

Rev

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

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