Subversion Repositories Kolibri OS

Rev

Rev 4641 | Rev 4772 | 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: 4700 $
9
 
10
 
11
;******************************************************
3539 clevermous 12
; поиск приводов HDD и CD
13
; автор исходного текста Кулаков Владимир Геннадьевич.
14
; адаптация и доработка Mario79
2288 clevermous 15
;******************************************************
16
 
17
;****************************************************
3539 clevermous 18
;*                 ПОИСК HDD и CD                   *
2288 clevermous 19
;****************************************************
4700 mario79 20
        cmp     [ecx+IDE_DATA.ProgrammingInterface], 0
3785 mario79 21
        je      EndFindHDD
22
 
2288 clevermous 23
FindHDD:
4700 mario79 24
        push    ecx
25
 
26
        xor     ebx, ebx
27
        inc     ebx
28
 
29
        cmp     ecx, IDE_controller_2
30
        jne     @f
31
 
32
        add     bl, 5
33
        jmp     .find
34
@@:
35
        cmp     ecx, IDE_controller_3
36
        jne     .find
37
 
38
        add     bl, 10
39
;--------------------------------------
40
.find:
41
 
2288 clevermous 42
        mov     [ChannelNumber], 1
43
        mov     [DiskNumber], 0
4700 mario79 44
        call    FindHDD_2
45
 
2288 clevermous 46
        mov     [DiskNumber], 1
4700 mario79 47
        call    FindHDD_2
48
 
2288 clevermous 49
        inc     [ChannelNumber]
4700 mario79 50
 
2288 clevermous 51
        mov     [DiskNumber], 0
4700 mario79 52
        call    FindHDD_2
53
 
2288 clevermous 54
        mov     [DiskNumber], 1
55
        call    FindHDD_1
4700 mario79 56
 
57
        pop     ecx
2288 clevermous 58
        jmp     EndFindHDD
4700 mario79 59
;-----------------------------------------------------------------------------
60
FindHDD_2:
61
        call    FindHDD_1
62
        shl     byte [ebx+DRIVE_DATA], 2
63
        ret
64
;-----------------------------------------------------------------------------
2288 clevermous 65
FindHDD_1:
3706 mario79 66
        DEBUGF  1, "K : Channel %d ",[ChannelNumber]:2
67
        DEBUGF  1, "Disk %d\n",[DiskNumber]:1
4700 mario79 68
        push    ebx
2288 clevermous 69
        call    ReadHDD_ID
4700 mario79 70
        pop     ebx
2288 clevermous 71
        cmp     [DevErrorCode], 0
4700 mario79 72
        jne     .FindCD
73
 
2288 clevermous 74
        cmp     [Sector512+6], word 16
4700 mario79 75
        ja      .FindCD
76
 
2288 clevermous 77
        cmp     [Sector512+12], word 255
4700 mario79 78
        ja      .FindCD
79
 
80
        inc     byte [ebx+DRIVE_DATA]
81
        jmp     .Print_Device_Name
82
;--------------------------------------
83
.FindCD:
84
        push    ebx
2288 clevermous 85
        call    DeviceReset
4700 mario79 86
        pop     ebx
2288 clevermous 87
        cmp     [DevErrorCode], 0
4700 mario79 88
        jne     .end
89
 
90
        push    ebx
2288 clevermous 91
        call    ReadCD_ID
4700 mario79 92
        pop     ebx
2288 clevermous 93
        cmp     [DevErrorCode], 0
4700 mario79 94
        jne     .end
95
 
96
        add     [ebx+DRIVE_DATA], byte 2
97
;--------------------------------------
98
.Print_Device_Name:
3711 clevermous 99
        pushad
100
        pushfd
101
        mov     esi, Sector512+27*2
102
        mov     edi, dev_name
103
        mov     ecx, 20
104
        cld
3702 mario79 105
@@:
3711 clevermous 106
        lodsw
107
        xchg    ah, al
108
        stosw
109
        loop    @b
4700 mario79 110
 
3702 mario79 111
        DEBUGF 1, "K : Dev: %s \n", dev_name
3881 mario79 112
 
113
        xor     eax, eax
114
        mov     ax, [Sector512+64*2]
4624 mario79 115
        DEBUGF  1, "K : PIO mode possible modes %x\n", al
4700 mario79 116
 
4624 mario79 117
        mov     ax, [Sector512+51*2]
118
        mov     al, ah
119
        call    convert_Sector512_value
120
        DEBUGF  1, "K : PIO mode set mode %x\n", ah
4700 mario79 121
 
3881 mario79 122
        mov     ax, [Sector512+63*2]
4624 mario79 123
        DEBUGF  1, "K : Multiword DMA possible modes %x\n", al
4700 mario79 124
 
4624 mario79 125
        mov     al, ah
126
        call    convert_Sector512_value
127
        DEBUGF  1, "K : Multiword DMA set mode %x\n", ah
4700 mario79 128
 
3881 mario79 129
        mov     ax, [Sector512+88*2]
4624 mario79 130
        DEBUGF  1, "K : Ultra DMA possible modes %x\n", al
4700 mario79 131
 
4624 mario79 132
        mov     al, ah
133
        call    convert_Sector512_value
134
        DEBUGF  1, "K : Ultra DMA set mode %x\n", ah
4700 mario79 135
 
136
        popfd
137
        popad
2288 clevermous 138
        ret
4700 mario79 139
;--------------------------------------
140
.end:
141
        DEBUGF  1, "K : Device not found\n"
2288 clevermous 142
        ret
4624 mario79 143
;-----------------------------------------------------------------------------
144
convert_Sector512_value:
145
        mov     ecx, 8
146
        xor     ah, ah
147
@@:
148
        test    al, 1b
149
        jnz     .end
2288 clevermous 150
 
4624 mario79 151
        shr     al, 1
152
        inc     ah
153
        loop    @b
154
 
155
        xor     ah, ah
156
.end:
157
        ret
158
;-----------------------------------------------------------------------------
3539 clevermous 159
; Адрес считываемого сектора в режиме LBA
2288 clevermous 160
uglobal
4700 mario79 161
SectorAddress   dd ?
3702 mario79 162
dev_name:
3711 clevermous 163
        rb 41
2288 clevermous 164
endg
4700 mario79 165
;-----------------------------------------------------------------------------
2288 clevermous 166
;*************************************************
3539 clevermous 167
;*     ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА      *
168
;* Входные параметры передаются через глобальные *
169
;* переменные:                                   *
170
;* ChannelNumber - номер канала (1 или 2);       *
171
;* DiskNumber - номер диска на канале (0 или 1). *
172
;* Идентификационный блок данных считывается     *
173
;* в массив Sector512.                           *
2288 clevermous 174
;*************************************************
175
ReadHDD_ID:
3539 clevermous 176
; Задать режим CHS
2288 clevermous 177
        mov     [ATAAddressMode], 0
3539 clevermous 178
; Послать команду идентификации устройства
2288 clevermous 179
        mov     [ATAFeatures], 0
180
        mov     [ATAHead], 0
4700 mario79 181
        mov     [ATACommand], 0xEC
2288 clevermous 182
        call    SendCommandToHDD
4700 mario79 183
        cmp     [DevErrorCode], 0 ;проверить код ошибки
3539 clevermous 184
        jne     @@End  ;закончить, сохранив код ошибки
4700 mario79 185
 
186
        mov     dx, [ATABasePortAddr]
187
        add     dx, 7    ;адрес регистра состояни
2288 clevermous 188
        mov     ecx, 0xffff
189
@@WaitCompleet:
3539 clevermous 190
        ; Проверить время выполнения команды
2288 clevermous 191
        dec     ecx
3539 clevermous 192
        jz      @@Error1  ;ошибка тайм-аута
193
        ; Проверить готовность
4700 mario79 194
        in      al, dx
195
        test    al, 80h  ;состояние сигнала BSY
2288 clevermous 196
        jnz     @@WaitCompleet
4700 mario79 197
 
198
        test    al, 1    ;состояние сигнала ERR
2288 clevermous 199
        jnz     @@Error6
4700 mario79 200
 
201
        test    al, 08h  ;состояние сигнала DRQ
2288 clevermous 202
        jz      @@WaitCompleet
3539 clevermous 203
; Принять блок данных от контроллера
4700 mario79 204
        mov     edi, Sector512
205
        mov     dx, [ATABasePortAddr];регистр данных
206
        mov     cx, 256  ;число считываемых слов
3539 clevermous 207
        rep insw         ;принять блок данных
2288 clevermous 208
        ret
3539 clevermous 209
; Записать код ошибки
2288 clevermous 210
@@Error1:
211
        mov     [DevErrorCode], 1
212
        ret
213
@@Error6:
214
        mov     [DevErrorCode], 6
215
@@End:
216
        ret
4700 mario79 217
;-----------------------------------------------------------------------------
218
uglobal
3539 clevermous 219
; Стандартные базовые адреса каналов 1 и 2
4700 mario79 220
StandardATABases dw ?, ? ; 1F0h, 170h
3539 clevermous 221
; Номер канала
4700 mario79 222
ChannelNumber   dw ?
3539 clevermous 223
; Номер диска
4700 mario79 224
DiskNumber      db ?
3539 clevermous 225
; Базовый адрес группы портов контроллера ATA
4700 mario79 226
ATABasePortAddr dw ?
3539 clevermous 227
; Параметры ATA-команды
4700 mario79 228
ATAFeatures     db ? ;особенности
229
ATASectorCount  db ? ;количество обрабатываемых секторов
230
ATASectorNumber db ? ;номер начального сектора
231
ATACylinder     dw ? ;номер начального цилиндра
232
ATAHead         db ? ;номер начальной головки
233
ATAAddressMode  db ? ;режим адресации (0 - CHS, 1 - LBA)
234
ATACommand      db ? ;код команды, подлежащей выполнению
3539 clevermous 235
; Код ошибки (0 - нет ошибок, 1 - превышен допустимый
236
; интервал ожидания, 2 - неверный код режима адресации,
237
; 3 - неверный номер канала, 4 - неверный номер диска,
238
; 5 - неверный номер головки, 6 - ошибка при выполнении
239
; команды)
2288 clevermous 240
DevErrorCode dd ?
241
endg
4700 mario79 242
;-----------------------------------------------------------------------------
2288 clevermous 243
;****************************************************
3539 clevermous 244
;*          ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ         *
245
;* Входные параметры передаются через глобальные    *
246
;* переменные:                                      *
247
;* ChannelNumber - номер канала (1 или 2);          *
248
;* DiskNumber - номер диска (0 или 1);              *
249
;* ATAFeatures - "особенности";                     *
250
;* ATASectorCount - количество секторов;            *
251
;* ATASectorNumber - номер начального сектора;      *
252
;* ATACylinder - номер начального цилиндра;         *
253
;* ATAHead - номер начальной головки;               *
254
;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); *
255
;* ATACommand - код команды.                        *
256
;* После успешного выполнения функции:              *
257
;* в ATABasePortAddr - базовый адрес HDD;           *
258
;* в DevErrorCode - ноль.                           *
259
;* При возникновении ошибки в DevErrorCode будет    *
260
;* возвращен код ошибки.                            *
2288 clevermous 261
;****************************************************
262
SendCommandToHDD:
3539 clevermous 263
; Проверить значение кода режима
2288 clevermous 264
        cmp     [ATAAddressMode], 1
265
        ja      @@Err2
3539 clevermous 266
; Проверить корректность номера канала
4700 mario79 267
        mov     bx, [ChannelNumber]
268
        cmp     bx, 1
2288 clevermous 269
        jb      @@Err3
4700 mario79 270
 
271
        cmp     bx, 2
2288 clevermous 272
        ja      @@Err3
3539 clevermous 273
; Установить базовый адрес
4700 mario79 274
        dec     bx
275
        shl     bx, 1
2288 clevermous 276
        movzx   ebx, bx
4700 mario79 277
        mov     ax, [ebx+StandardATABases]
278
        mov     [ATABasePortAddr], ax
3539 clevermous 279
; Ожидание готовности HDD к приему команды
280
        ; Выбрать нужный диск
4700 mario79 281
        mov     dx, [ATABasePortAddr]
282
        add     dx, 6   ;адрес регистра головок
283
        mov     al, [DiskNumber]
284
        cmp     al, 1   ;проверить номера диска
2288 clevermous 285
        ja      @@Err4
4700 mario79 286
 
287
        shl     al, 4
288
        or      al, 10100000b
289
        out     dx, al
3539 clevermous 290
        ; Ожидать, пока диск не будет готов
4700 mario79 291
        inc     dx
2288 clevermous 292
        mov     ecx, 0xfff
293
@@WaitHDReady:
3539 clevermous 294
        ; Проверить время ожидани
2288 clevermous 295
        dec     ecx
296
        jz      @@Err1
3539 clevermous 297
        ; Прочитать регистр состояни
4700 mario79 298
        in      al, dx
3539 clevermous 299
        ; Проверить состояние сигнала BSY
4700 mario79 300
        test    al, 80h
2288 clevermous 301
        jnz     @@WaitHDReady
3539 clevermous 302
        ; Проверить состояние сигнала DRQ
4700 mario79 303
        test    al, 08h
2288 clevermous 304
        jnz     @@WaitHDReady
3539 clevermous 305
; Загрузить команду в регистры контроллера
2288 clevermous 306
        cli
4700 mario79 307
        mov     dx, [ATABasePortAddr]
308
        inc     dx      ;регистр "особенностей"
309
        mov     al, [ATAFeatures]
310
        out     dx, AL
311
        inc     dx      ;счетчик секторов
312
        mov     al, [ATASectorCount]
313
        out     dx, AL
314
        inc     dx      ;регистр номера сектора
315
        mov     al, [ATASectorNumber]
316
        out     dx, AL
317
        inc     dx      ;номер цилиндра (младший байт)
318
        mov     ax, [ATACylinder]
319
        out     dx, AL
320
        inc     dx      ;номер цилиндра (старший байт)
321
        mov     al, AH
322
        out     dx, AL
323
        inc     dx      ;номер головки/номер диска
324
        mov     al, [DiskNumber]
325
        shl     al, 4
326
        cmp     [ATAHead], 0xF ;проверить номер головки
2288 clevermous 327
        ja      @@Err5
4700 mario79 328
 
329
        or      al, [ATAHead]
330
        or      al, 10100000b
331
        mov     ah, [ATAAddressMode]
332
        shl     ah, 6
333
        or      al, ah
334
        out     dx, al
3539 clevermous 335
; Послать команду
4700 mario79 336
        mov     al, [ATACommand]
337
        inc     dx      ;регистр команд
338
        out     dx, al
2288 clevermous 339
        sti
3539 clevermous 340
; Сбросить признак ошибки
2288 clevermous 341
        mov     [DevErrorCode], 0
342
        ret
3539 clevermous 343
; Записать код ошибки
2288 clevermous 344
@@Err1:
345
        mov     [DevErrorCode], 1
346
        ret
347
@@Err2:
348
        mov     [DevErrorCode], 2
349
        ret
350
@@Err3:
351
        mov     [DevErrorCode], 3
352
        ret
353
@@Err4:
354
        mov     [DevErrorCode], 4
355
        ret
356
@@Err5:
357
        mov     [DevErrorCode], 5
3539 clevermous 358
; Завершение работы программы
2288 clevermous 359
        ret
4700 mario79 360
;-----------------------------------------------------------------------------
2288 clevermous 361
;*************************************************
3539 clevermous 362
;*     ЧТЕНИЕ ИДЕНТИФИКАТОРА УСТРОЙСТВА ATAPI    *
363
;* Входные параметры передаются через глобальные *
364
;* перменные:                                    *
365
;* ChannelNumber - номер канала;                 *
366
;* DiskNumber - номер диска на канале.           *
367
;* Идентификационный блок данных считывается     *
368
;* в массив Sector512.                           *
2288 clevermous 369
;*************************************************
370
ReadCD_ID:
3539 clevermous 371
; Задать режим CHS
2288 clevermous 372
        mov     [ATAAddressMode], 0
3539 clevermous 373
; Послать команду идентификации устройства
2288 clevermous 374
        mov     [ATAFeatures], 0
375
        mov     [ATASectorCount], 0
376
        mov     [ATASectorNumber], 0
377
        mov     [ATACylinder], 0
378
        mov     [ATAHead], 0
4700 mario79 379
        mov     [ATACommand], 0xA1
2288 clevermous 380
        call    SendCommandToHDD
3539 clevermous 381
        cmp     [DevErrorCode], 0;проверить код ошибки
382
        jne     @@End_1  ;закончить, сохранив код ошибки
383
; Ожидать готовность данных HDD
4700 mario79 384
        mov     dx, [ATABasePortAddr]
385
        add     dx, 7  ;порт 1х7h
2288 clevermous 386
        mov     ecx, 0xffff
387
@@WaitCompleet_1:
3539 clevermous 388
        ; Проверить врем
2288 clevermous 389
        dec     ecx
3539 clevermous 390
        jz      @@Error1_1 ;ошибка тайм-аута
391
        ; Проверить готовность
4700 mario79 392
        in      al, dx
393
        test    al, 80h  ;состояние сигнала BSY
2288 clevermous 394
        jnz     @@WaitCompleet_1
4700 mario79 395
 
396
        test    al, 1    ;состояние сигнала ERR
2288 clevermous 397
        jnz     @@Error6_1
4700 mario79 398
 
399
        test    al, 08h  ;состояние сигнала DRQ
2288 clevermous 400
        jz      @@WaitCompleet_1
3539 clevermous 401
; Принять блок данных от контроллера
4700 mario79 402
        mov     edi, Sector512 ;offset Sector512
403
        mov     dx, [ATABasePortAddr];порт 1x0h
404
        mov     cx, 256;число считываемых слов
2288 clevermous 405
        rep insw
406
        ret
3539 clevermous 407
; Записать код ошибки
2288 clevermous 408
@@Error1_1:
409
        mov     [DevErrorCode], 1
410
        ret
411
@@Error6_1:
412
        mov     [DevErrorCode], 6
413
@@End_1:
414
        ret
4700 mario79 415
;-----------------------------------------------------------------------------
2288 clevermous 416
;*************************************************
3539 clevermous 417
;*                СБРОС УСТРОЙСТВА               *
418
;* Входные параметры передаются через глобальные *
419
;* переменные:                                   *
420
;* ChannelNumber - номер канала (1 или 2);       *
421
;* DiskNumber - номер диска (0 или 1).           *
2288 clevermous 422
;*************************************************
423
DeviceReset:
3539 clevermous 424
; Проверить корректность номера канала
4700 mario79 425
        mov     bx, [ChannelNumber]
426
        cmp     bx, 1
2288 clevermous 427
        jb      @@Err3_2
4700 mario79 428
 
429
        cmp     bx, 2
2288 clevermous 430
        ja      @@Err3_2
3539 clevermous 431
; Установить базовый адрес
4700 mario79 432
        dec     bx
433
        shl     bx, 1
2288 clevermous 434
        movzx   ebx, bx
4700 mario79 435
        mov     dx, [ebx+StandardATABases]
436
        mov     [ATABasePortAddr], dx
3539 clevermous 437
; Выбрать нужный диск
4700 mario79 438
        add     dx, 6   ;адрес регистра головок
439
        mov     al, [DiskNumber]
440
        cmp     al, 1   ;проверить номера диска
2288 clevermous 441
        ja      @@Err4_2
4700 mario79 442
 
443
        shl     al, 4
444
        or      al, 10100000b
445
        out     dx, al
3539 clevermous 446
; Послать команду "Сброс"
4700 mario79 447
        mov     al, 0x8
448
        inc     dx      ;регистр команд
449
        out     dx, al
2288 clevermous 450
        mov     ecx, 0x80000
451
@@WaitHDReady_1:
3539 clevermous 452
        ; Проверить время ожидани
2288 clevermous 453
        dec     ecx
3539 clevermous 454
        je      @@Err1_2 ;ошибка тайм-аута
455
        ; Прочитать регистр состояни
4700 mario79 456
        in      al, dx
3539 clevermous 457
        ; Проверить состояние сигнала BSY
4700 mario79 458
        test    al, 80h
2288 clevermous 459
        jnz     @@WaitHDReady_1
3539 clevermous 460
; Сбросить признак ошибки
2288 clevermous 461
        mov     [DevErrorCode], 0
462
        ret
3539 clevermous 463
; Обработка ошибок
2288 clevermous 464
@@Err1_2:
465
        mov     [DevErrorCode], 1
466
        ret
467
@@Err3_2:
468
        mov     [DevErrorCode], 3
469
        ret
470
@@Err4_2:
471
        mov     [DevErrorCode], 4
3539 clevermous 472
; Записать код ошибки
2288 clevermous 473
        ret
4700 mario79 474
;-----------------------------------------------------------------------------
2288 clevermous 475
EndFindHDD: