Subversion Repositories Kolibri OS

Rev

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

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