Subversion Repositories Kolibri OS

Rev

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