Subversion Repositories Kolibri OS

Rev

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