Subversion Repositories Kolibri OS

Rev

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

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