Subversion Repositories Kolibri OS

Rev

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

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