Subversion Repositories Kolibri OS

Rev

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

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