Subversion Repositories Kolibri OS

Rev

Rev 5565 | Details | Compare with Previous | Last modification | View Log | RSS feed

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