Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
4429 Serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
4923 Serge 8
$Revision: 4734 $
4429 Serge 9
 
4923 Serge 10
;-----------------------------------------------------------------------------
4429 Serge 11
;**********************************************************
12
;  Непосредственная работа с устройством СD (ATAPI)
13
;**********************************************************
14
; Автор части исходного текста Кулаков Владимир Геннадьевич
15
; Адаптация, доработка и разработка Mario79,
16
 
17
; Максимальное количество повторений операции чтения
18
MaxRetr equ 10
19
; Предельное время ожидания готовности к приему команды
20
; (в тиках)
21
BSYWaitTime equ 1000  ;2
22
NoTickWaitTime equ 0xfffff
23
CDBlockSize equ 2048
24
;********************************************
25
;*        ЧТЕНИЕ СЕКТОРА С ПОВТОРАМИ        *
26
;* Многократное повторение чтения при сбоях *
27
;********************************************
28
ReadCDWRetr:
29
;-----------------------------------------------------------
30
; input  : eax = block to read
31
;          ebx = destination
32
;-----------------------------------------------------------
33
        pushad
34
        mov     eax, [CDSectorAddress]
35
        mov     ebx, [CDDataBuf_pointer]
36
        call    cd_calculate_cache
37
        xor     edi, edi
38
        add     esi, 8
39
        inc     edi
4923 Serge 40
;--------------------------------------
41
align 4
4429 Serge 42
.hdreadcache:
43
        cmp     [esi], eax      ; correct sector
44
        je      .yeshdcache
4923 Serge 45
 
4429 Serge 46
        add     esi, 8
47
        inc     edi
48
        dec     ecx
49
        jnz     .hdreadcache
4923 Serge 50
 
4429 Serge 51
        call    find_empty_slot_CD_cache ; ret in edi
52
 
53
        push    edi
54
        push    eax
55
        call    cd_calculate_cache_2
56
        shl     edi, 11
57
        add     edi, eax
58
        mov     [CDDataBuf_pointer], edi
59
        pop     eax
60
        pop     edi
61
 
62
        call    ReadCDWRetr_1
63
        cmp     [DevErrorCode], 0
64
        jne     .exit
65
 
66
        mov     [CDDataBuf_pointer], ebx
67
        call    cd_calculate_cache_1
68
        lea     esi, [edi*8+esi]
69
        mov     [esi], eax      ; sector number
4923 Serge 70
;--------------------------------------
4429 Serge 71
.yeshdcache:
72
        mov     esi, edi
4923 Serge 73
        shl     esi, 11 ;9
4429 Serge 74
        push    eax
75
        call    cd_calculate_cache_2
76
        add     esi, eax
77
        pop     eax
4923 Serge 78
        mov     edi, ebx ;[CDDataBuf_pointer]
79
        mov     ecx, 512 ;/4
4429 Serge 80
        cld
81
        rep movsd               ; move data
4923 Serge 82
;--------------------------------------
4429 Serge 83
.exit:
84
        popad
85
        ret
4923 Serge 86
;-----------------------------------------------------------------------------
4429 Serge 87
ReadCDWRetr_1:
88
        pushad
89
; Цикл, пока команда не выполнена успешно или не
90
; исчерпано количество попыток
4923 Serge 91
        mov     ecx, MaxRetr
92
;--------------------------------------
93
align 4
4429 Serge 94
@@NextRetr:
95
; Подать команду
96
;*************************************************
97
;*      ПОЛНОЕ ЧТЕНИЕ СЕКТОРА КОМПАКТ-ДИСКА      *
98
;* Считываются данные пользователя, информация   *
99
;* субканала и контрольная информация            *
100
;* Входные параметры передаются через глобальные *
101
;* перменные:                                    *
102
;* ChannelNumber - номер канала;                 *
103
;* DiskNumber - номер диска на канале;           *
104
;* CDSectorAddress - адрес считываемого сектора. *
105
;* Данные считывается в массив CDDataBuf.        *
106
;*************************************************
107
;ReadCD:
108
        push    ecx
109
; Очистить буфер пакетной команды
110
        call    clear_packet_buffer
111
; Сформировать пакетную команду для считывания
112
; сектора данных
113
; Задать код команды Read CD
4923 Serge 114
        mov     [PacketCommand], byte 0x28 ;0xBE
4429 Serge 115
; Задать адрес сектора
4923 Serge 116
        mov     ax, word [CDSectorAddress+2]
117
        xchg    al, ah
118
        mov     word [PacketCommand+2], ax
119
        mov     ax, word [CDSectorAddress]
120
        xchg    al, ah
121
        mov     word [PacketCommand+4], ax
4429 Serge 122
; Задать количество считываемых секторов
123
        mov     [PacketCommand+8], byte 1
124
; Подать команду
125
        call    SendPacketDatCommand
126
        pop     ecx
127
 
128
        test    eax, eax
129
        jz      @@End_4
130
 
131
        or      ecx, ecx        ;{SPraid.simba} (for cd load)
132
        jz      @@End_4
4923 Serge 133
 
4429 Serge 134
        dec     ecx
135
 
136
        cmp     [timer_ticks_enable], 0
137
        jne     @f
4923 Serge 138
 
4429 Serge 139
        mov     eax, NoTickWaitTime
4923 Serge 140
;--------------------------------------
141
align 4
4429 Serge 142
.wait:
143
        dec     eax
144
        jz      @@NextRetr
4923 Serge 145
 
4429 Serge 146
        jmp     .wait
4923 Serge 147
;--------------------------------------
148
align 4
4429 Serge 149
@@:
150
        loop    @@NextRetr
4923 Serge 151
;--------------------------------------
4429 Serge 152
@@End_4:
153
        mov     dword [DevErrorCode], eax
154
        popad
155
        ret
4923 Serge 156
;-----------------------------------------------------------------------------
4429 Serge 157
; Универсальные процедуры, обеспечивающие выполнение
158
;             пакетных команд в режиме PIO
159
; Максимально допустимое время ожидания реакции
160
; устройства на пакетную команду (в тиках)
4923 Serge 161
;-----------------------------------------------------------------------------
4429 Serge 162
MaxCDWaitTime equ 1000 ;200 ;10 секунд
163
uglobal
164
; Область памяти для формирования пакетной команды
165
PacketCommand:
166
                 rb 12  ;DB 12 DUP (?)
167
; Адрес считываемого сектора данных
4923 Serge 168
CDSectorAddress:   dd ?
4429 Serge 169
; Время начала очередной операции с диском
4923 Serge 170
TickCounter_1     dd 0
4429 Serge 171
; Время начала ожидания готовности устройства
4923 Serge 172
WURStartTime      dd 0
4429 Serge 173
; указатель буфера для считывания
174
CDDataBuf_pointer dd 0
175
endg
4923 Serge 176
;-----------------------------------------------------------------------------
4429 Serge 177
;****************************************************
178
;*    ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ,    *
179
;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ *
180
;*     РАЗМЕРОМ 2048 БАЙТ ОТ УСТРОЙСТВА К ХОСТУ     *
181
;* Входные параметры передаются через глобальные    *
182
;* перменные:                                       *
183
;* ChannelNumber - номер канала;                    *
184
;* DiskNumber - номер диска на канале;              *
185
;* PacketCommand - 12-байтный командный пакет;      *
186
;* CDBlockSize - размер принимаемого блока данных.  *
187
; return eax DevErrorCode
188
;****************************************************
189
SendPacketDatCommand:
190
        xor     eax, eax
191
; Задать режим CHS
192
        mov     byte [ATAAddressMode], al
193
; Послать ATA-команду передачи пакетной команды
194
        mov     byte [ATAFeatures], al
195
        mov     byte [ATASectorCount], al
196
        mov     byte [ATASectorNumber], al
197
        ; Загрузить размер передаваемого блока
198
        mov     [ATAHead], al
199
        mov     [ATACylinder], CDBlockSize
4923 Serge 200
        mov     [ATACommand], 0xA0
4429 Serge 201
        call    SendCommandToHDD_1
202
        test    eax, eax
203
        jnz     @@End_8    ;закончить, сохранив код ошибки
204
; Ожидание готовности дисковода к приему
205
; пакетной команды
4923 Serge 206
        mov     dx, [ATABasePortAddr]
207
        add     dx, 7    ;порт 1х7h
4429 Serge 208
        mov     ecx, NoTickWaitTime
4923 Serge 209
;--------------------------------------
210
align 4
4429 Serge 211
@@WaitDevice0:
212
        cmp     [timer_ticks_enable], 0
213
        jne     @f
4923 Serge 214
 
4429 Serge 215
        dec     ecx
216
        jz      @@Err1_1
4923 Serge 217
 
4429 Serge 218
        jmp     .test
4923 Serge 219
;--------------------------------------
220
align 4
4429 Serge 221
@@:
222
        call    change_task
223
        ; Проверить время выполнения команды
4923 Serge 224
        mov     eax, [timer_ticks]
225
        sub     eax, [TickCounter_1]
226
        cmp     eax, BSYWaitTime
4429 Serge 227
        ja      @@Err1_1   ;ошибка тайм-аута
228
        ; Проверить готовность
4923 Serge 229
;--------------------------------------
230
align 4
4429 Serge 231
.test:
4923 Serge 232
        in      al, dx
233
        test    al, 0x80  ;состояние сигнала BSY
4429 Serge 234
        jnz     @@WaitDevice0
4923 Serge 235
 
236
        test    al, 1    ;состояние сигнала ERR
4429 Serge 237
        jnz     @@Err6
4923 Serge 238
 
239
        test    al, 0x8  ;состояние сигнала DRQ
4429 Serge 240
        jz      @@WaitDevice0
241
; Послать пакетную команду
242
        cli
4923 Serge 243
        mov     dx, [ATABasePortAddr]
244
        mov     ax, [PacketCommand]
245
        out     dx, ax
246
        mov     ax, [PacketCommand+2]
247
        out     dx, ax
248
        mov     ax, [PacketCommand+4]
249
        out     dx, ax
250
        mov     ax, [PacketCommand+6]
251
        out     dx, ax
252
        mov     ax, [PacketCommand+8]
253
        out     dx, ax
254
        mov     ax, [PacketCommand+10]
255
        out     dx, ax
4429 Serge 256
        sti
257
; Ожидание готовности данных
4923 Serge 258
        mov     dx, [ATABasePortAddr]
259
        add     dx, 7  ;порт 1х7h
4429 Serge 260
        mov     ecx, NoTickWaitTime
4923 Serge 261
;--------------------------------------
262
align 4
4429 Serge 263
@@WaitDevice1:
264
        cmp     [timer_ticks_enable], 0
265
        jne     @f
4923 Serge 266
 
4429 Serge 267
        dec     ecx
268
        jz      @@Err1_1
4923 Serge 269
 
4429 Serge 270
        jmp     .test_1
4923 Serge 271
;--------------------------------------
272
align 4
4429 Serge 273
@@:
274
        call    change_task
275
        ; Проверить время выполнения команды
4923 Serge 276
        mov     eax, [timer_ticks]
277
        sub     eax, [TickCounter_1]
278
        cmp     eax, MaxCDWaitTime
4429 Serge 279
        ja      @@Err1_1   ;ошибка тайм-аута
280
        ; Проверить готовность
4923 Serge 281
;--------------------------------------
282
align 4
4429 Serge 283
.test_1:
4923 Serge 284
        in      al, dx
285
        test    al, 0x80  ;состояние сигнала BSY
4429 Serge 286
        jnz     @@WaitDevice1
4923 Serge 287
 
288
        test    al, 1    ;состояние сигнала ERR
4429 Serge 289
        jnz     @@Err6_temp
4923 Serge 290
 
291
        test    al, 0x8  ;состояние сигнала DRQ
4429 Serge 292
        jz      @@WaitDevice1
293
; Принять блок данных от контроллера
4923 Serge 294
        mov     edi, [CDDataBuf_pointer]
4429 Serge 295
        ; Загрузить адрес регистра данных контроллера
4923 Serge 296
        mov     dx, [ATABasePortAddr]
4429 Serge 297
        ; Загрузить в счетчик размер блока в байтах
298
        xor     ecx, ecx
4923 Serge 299
        mov     cx, CDBlockSize
4429 Serge 300
        ; Вычислить размер блока в 16-разрядных словах
4923 Serge 301
        shr     cx, 1 ;разделить размер блока на 2
4429 Serge 302
        ; Принять блок данных
303
        cli
304
        cld
305
        rep insw
306
        sti
4923 Serge 307
;--------------------------------------
4429 Serge 308
; Успешное завершение приема данных
309
@@End_8:
310
        xor     eax, eax
311
        ret
4923 Serge 312
;--------------------------------------
4429 Serge 313
; Записать код ошибки
314
@@Err1_1:
315
        xor     eax, eax
316
        inc     eax
317
        ret
4923 Serge 318
;--------------------------------------
4429 Serge 319
@@Err6_temp:
320
        mov     eax, 7
321
        ret
4923 Serge 322
;--------------------------------------
4429 Serge 323
@@Err6:
324
        mov     eax, 6
325
        ret
4923 Serge 326
;-----------------------------------------------------------------------------
4429 Serge 327
;***********************************************
328
;*  ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
329
;*     НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ    *
330
;* Входные параметры передаются через          *
331
;* глобальные перменные:                       *
332
;* ChannelNumber - номер канала;               *
333
;* DiskNumber - номер диска на канале;         *
334
;* PacketCommand - 12-байтный командный пакет. *
335
;***********************************************
336
SendPacketNoDatCommand:
337
        pushad
338
        xor     eax, eax
339
; Задать режим CHS
340
        mov     byte [ATAAddressMode], al
341
; Послать ATA-команду передачи пакетной команды
342
        mov     byte [ATAFeatures], al
343
        mov     byte [ATASectorCount], al
344
        mov     byte [ATASectorNumber], al
345
        mov     word [ATACylinder], ax
346
        mov     byte [ATAHead], al
4923 Serge 347
        mov     [ATACommand], 0xA0
4429 Serge 348
        call    SendCommandToHDD_1
349
        test    eax, eax
350
        jnz     @@End_9  ;закончить, сохранив код ошибки
351
; Ожидание готовности дисковода к приему
352
; пакетной команды
4923 Serge 353
        mov     dx, [ATABasePortAddr]
354
        add     dx, 7  ;порт 1х7h
355
;--------------------------------------
356
align 4
4429 Serge 357
@@WaitDevice0_1:
358
        call    change_task
359
        ; Проверить время ожидания
4923 Serge 360
        mov     eax, [timer_ticks]
361
        sub     eax, [TickCounter_1]
362
        cmp     eax, BSYWaitTime
4429 Serge 363
        ja      @@Err1_3   ;ошибка тайм-аута
364
        ; Проверить готовность
4923 Serge 365
        in      al, dx
366
        test    al, 0x80  ;состояние сигнала BSY
4429 Serge 367
        jnz     @@WaitDevice0_1
4923 Serge 368
 
369
        test    al, 1    ;состояние сигнала ERR
4429 Serge 370
        jnz     @@Err6_1
4923 Serge 371
 
372
        test    al, 0x8  ;состояние сигнала DRQ
4429 Serge 373
        jz      @@WaitDevice0_1
374
; Послать пакетную команду
375
;        cli
4923 Serge 376
        mov     dx, [ATABasePortAddr]
377
        mov     ax, word [PacketCommand]
378
        out     dx, ax
379
        mov     ax, word [PacketCommand+2]
380
        out     dx, ax
381
        mov     ax, word [PacketCommand+4]
382
        out     dx, ax
383
        mov     ax, word [PacketCommand+6]
384
        out     dx, ax
385
        mov     ax, word [PacketCommand+8]
386
        out     dx, ax
387
        mov     ax, word [PacketCommand+10]
388
        out     dx, ax
4429 Serge 389
;        sti
390
        cmp     [ignore_CD_eject_wait], 1
391
        je      @@clear_DEC
392
; Ожидание подтверждения приема команды
4923 Serge 393
        mov     dx, [ATABasePortAddr]
394
        add     dx, 7  ;порт 1х7h
395
;--------------------------------------
396
align 4
4429 Serge 397
@@WaitDevice1_1:
398
        call    change_task
399
        ; Проверить время выполнения команды
4923 Serge 400
        mov     eax, [timer_ticks]
401
        sub     eax, [TickCounter_1]
402
        cmp     eax, MaxCDWaitTime
4429 Serge 403
        ja      @@Err1_3   ;ошибка тайм-аута
404
        ; Ожидать освобождения устройства
4923 Serge 405
        in      al, dx
406
        test    al, 0x80  ;состояние сигнала BSY
4429 Serge 407
        jnz     @@WaitDevice1_1
4923 Serge 408
 
409
        test    al, 1    ;состояние сигнала ERR
4429 Serge 410
        jnz     @@Err6_1
4923 Serge 411
 
412
        test    al, 0x40  ;состояние сигнала DRDY
4429 Serge 413
        jz      @@WaitDevice1_1
4923 Serge 414
;--------------------------------------
4429 Serge 415
@@clear_DEC:
416
        and     [DevErrorCode], 0
417
        popad
418
        ret
4923 Serge 419
;--------------------------------------
4429 Serge 420
; Записать код ошибки
421
@@Err1_3:
422
        xor     eax, eax
423
        inc     eax
424
        jmp     @@End_9
4923 Serge 425
;--------------------------------------
4429 Serge 426
@@Err6_1:
427
        mov     eax, 6
4923 Serge 428
;--------------------------------------
4429 Serge 429
@@End_9:
430
        mov     [DevErrorCode], eax
431
        popad
432
        ret
4923 Serge 433
;-----------------------------------------------------------------------------
4429 Serge 434
;****************************************************
435
;*          ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ         *
436
;* Входные параметры передаются через глобальные    *
437
;* переменные:                                      *
438
;* ChannelNumber - номер канала (1 или 2);          *
439
;* DiskNumber - номер диска (0 или 1);              *
440
;* ATAFeatures - "особенности";                     *
441
;* ATASectorCount - количество секторов;            *
442
;* ATASectorNumber - номер начального сектора;      *
443
;* ATACylinder - номер начального цилиндра;         *
444
;* ATAHead - номер начальной головки;               *
445
;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); *
446
;* ATACommand - код команды.                        *
447
;* После успешного выполнения функции:              *
448
;* в ATABasePortAddr - базовый адрес HDD;           *
449
;* в DevErrorCode - ноль.                           *
450
;* При возникновении ошибки в DevErrorCode будет    *
451
;* возвращен код ошибки в eax                       *
452
;****************************************************
453
SendCommandToHDD_1:
454
; Проверить значение кода режима
455
        cmp     [ATAAddressMode], 1
456
        ja      @@Err2_4
457
; Проверить корректность номера канала
4923 Serge 458
        mov     bx, [ChannelNumber]
459
        cmp     bx, 1
4429 Serge 460
        jb      @@Err3_4
4923 Serge 461
 
462
        cmp     bx, 2
4429 Serge 463
        ja      @@Err3_4
464
; Установить базовый адрес
4923 Serge 465
        dec     bx
466
        shl     ebx, 2
4429 Serge 467
        movzx   ebx, bx
4923 Serge 468
        mov     eax, [cdpos]
469
        dec     eax
470
        shr     eax, 2
471
        imul    eax, sizeof.IDE_DATA
472
        add     eax, IDE_controller_1
473
        add     eax, ebx
474
        mov     ax, [eax+IDE_DATA.BAR0_val]
475
        mov     [ATABasePortAddr], ax
4429 Serge 476
; Ожидание готовности HDD к приему команды
477
        ; Выбрать нужный диск
4923 Serge 478
        mov     dx, [ATABasePortAddr]
479
        add     dx, 6   ;адрес регистра головок
480
        mov     al, [DiskNumber]
481
        cmp     al, 1   ;проверить номера диска
4429 Serge 482
        ja      @@Err4_4
4923 Serge 483
 
484
        shl     al, 4
485
        or      al, 10100000b
486
        out     dx, al
4429 Serge 487
        ; Ожидать, пока диск не будет готов
4923 Serge 488
        inc     dx
4429 Serge 489
        mov     eax, [timer_ticks]
490
        mov     [TickCounter_1], eax
491
        mov     ecx, NoTickWaitTime
4923 Serge 492
;--------------------------------------
493
align 4
4429 Serge 494
@@WaitHDReady_2:
495
        cmp     [timer_ticks_enable], 0
496
        jne     @f
4923 Serge 497
 
4429 Serge 498
        dec     ecx
499
        jz      @@Err1_4
4923 Serge 500
 
4429 Serge 501
        jmp     .test
4923 Serge 502
;--------------------------------------
503
align 4
4429 Serge 504
@@:
505
        call    change_task
506
        ; Проверить время ожидания
507
        mov     eax, [timer_ticks]
508
        sub     eax, [TickCounter_1]
4923 Serge 509
        cmp     eax, BSYWaitTime ;300    ;ожидать 3 сек.
4429 Serge 510
        ja      @@Err1_4   ;ошибка тайм-аута
4923 Serge 511
;--------------------------------------
512
align 4
4429 Serge 513
.test:
4923 Serge 514
        in      al, dx ; Прочитать регистр состояния
4429 Serge 515
        ; Проверить состояние сигнала BSY
4923 Serge 516
        test    al, 0x80
4429 Serge 517
        jnz     @@WaitHDReady_2
518
        ; Проверить состояние сигнала DRQ
4923 Serge 519
        test    al, 0x8
4429 Serge 520
        jnz     @@WaitHDReady_2
521
; Загрузить команду в регистры контроллера
522
        cli
4923 Serge 523
        mov     dx, [ATABasePortAddr]
524
        inc     dx      ;регистр "особенностей"
525
        mov     al, [ATAFeatures]
526
        out     dx, al
527
        inc     dx      ;счетчик секторов
528
        mov     al, [ATASectorCount]
529
        out     dx, al
530
        inc     dx      ;регистр номера сектора
531
        mov     al, [ATASectorNumber]
532
        out     dx, al
533
        inc     dx      ;номер цилиндра (младший байт)
534
        mov     ax, [ATACylinder]
535
        out     dx, al
536
        inc     dx      ;номер цилиндра (старший байт)
537
        mov     al, ah
538
        out     dx, al
539
        inc     dx      ;номер головки/номер диска
540
        mov     al, [DiskNumber]
541
        shl     al, 4
542
        cmp     [ATAHead], 0xF ;проверить номер головки
4429 Serge 543
        ja      @@Err5_4
4923 Serge 544
 
545
        or      al, [ATAHead]
546
        or      al, 10100000b
547
        mov     ah, [ATAAddressMode]
548
        shl     ah, 6
549
        or      al, ah
550
        out     dx, al
4429 Serge 551
; Послать команду
4923 Serge 552
        mov     al, [ATACommand]
553
        inc     dx      ;регистр команд
554
        out     dx, al
4429 Serge 555
        sti
4923 Serge 556
;--------------------------------------
4429 Serge 557
@@End_10:
558
        xor     eax, eax
559
        ret
4923 Serge 560
;--------------------------------------
4429 Serge 561
; Записать код ошибки
562
@@Err1_4:
563
        xor     eax, eax
564
        inc     eax
565
        ret
4923 Serge 566
;--------------------------------------
4429 Serge 567
@@Err2_4:
568
        mov     eax, 2
569
        ret
4923 Serge 570
;--------------------------------------
4429 Serge 571
@@Err3_4:
572
        mov     eax, 3
573
        ret
4923 Serge 574
;--------------------------------------
4429 Serge 575
@@Err4_4:
576
        mov     eax, 4
577
        ret
4923 Serge 578
;--------------------------------------
4429 Serge 579
@@Err5_4:
580
        mov     eax, 5
581
        ret
4923 Serge 582
;-----------------------------------------------------------------------------
4429 Serge 583
;*************************************************
584
;*    ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ    *
585
;* Входные параметры передаются через глобальные *
586
;* перменные:                                    *
587
;* ChannelNumber - номер канала;                 *
588
;* DiskNumber - номер диска на канале.           *
589
;*************************************************
590
WaitUnitReady:
591
        pusha
592
; Запомнить время начала операции
4923 Serge 593
        mov     eax, [timer_ticks]
594
        mov     [WURStartTime], eax
4429 Serge 595
; Очистить буфер пакетной команды
596
        call    clear_packet_buffer
597
; Сформировать команду TEST UNIT READY
4923 Serge 598
        mov     [PacketCommand], word 0
4429 Serge 599
; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА
600
        mov     ecx, NoTickWaitTime
4923 Serge 601
;--------------------------------------
602
align 4
4429 Serge 603
@@SendCommand:
604
        ; Подать команду проверки готовности
605
        call    SendPacketNoDatCommand
606
        cmp     [timer_ticks_enable], 0
607
        jne     @f
4923 Serge 608
 
4429 Serge 609
        cmp     [DevErrorCode], 0
610
        je      @@End_11
4923 Serge 611
 
4429 Serge 612
        dec     ecx
613
        jz      .Error
4923 Serge 614
 
4429 Serge 615
        jmp     @@SendCommand
4923 Serge 616
;--------------------------------------
617
align 4
4429 Serge 618
@@:
619
        call    change_task
620
        ; Проверить код ошибки
621
        cmp     [DevErrorCode], 0
622
        je      @@End_11
623
        ; Проверить время ожидания готовности
4923 Serge 624
        mov     eax, [timer_ticks]
625
        sub     eax, [WURStartTime]
626
        cmp     eax, MaxCDWaitTime
4429 Serge 627
        jb      @@SendCommand
4923 Serge 628
;--------------------------------------
4429 Serge 629
.Error:
630
        ; Ошибка тайм-аута
631
        mov     [DevErrorCode], 1
4923 Serge 632
;--------------------------------------
4429 Serge 633
@@End_11:
634
        popa
635
        ret
4923 Serge 636
;-----------------------------------------------------------------------------
4429 Serge 637
;*************************************************
638
;*            ЗАПРЕТИТЬ СМЕНУ ДИСКА              *
639
;* Входные параметры передаются через глобальные *
640
;* перменные:                                    *
641
;* ChannelNumber - номер канала;                 *
642
;* DiskNumber - номер диска на канале.           *
643
;*************************************************
644
prevent_medium_removal:
645
        pusha
646
; Очистить буфер пакетной команды
647
        call    clear_packet_buffer
648
; Задать код команды
649
        mov     [PacketCommand], byte 0x1E
650
; Задать код запрета
651
        mov     [PacketCommand+4], byte 11b
652
; Подать команду
653
        call    SendPacketNoDatCommand
654
        mov     eax, ATAPI_IDE0_lock
655
        add     eax, [cdpos]
656
        dec     eax
657
        mov     [eax], byte 1
658
        popa
659
        ret
4923 Serge 660
;-----------------------------------------------------------------------------
4429 Serge 661
;*************************************************
662
;*            РАЗРЕШИТЬ СМЕНУ ДИСКА              *
663
;* Входные параметры передаются через глобальные *
664
;* перменные:                                    *
665
;* ChannelNumber - номер канала;                 *
666
;* DiskNumber - номер диска на канале.           *
667
;*************************************************
668
allow_medium_removal:
669
        pusha
670
; Очистить буфер пакетной команды
671
        call    clear_packet_buffer
672
; Задать код команды
673
        mov     [PacketCommand], byte 0x1E
674
; Задать код запрета
4923 Serge 675
        mov     [PacketCommand+4], byte 0
4429 Serge 676
; Подать команду
677
        call    SendPacketNoDatCommand
678
        mov     eax, ATAPI_IDE0_lock
679
        add     eax, [cdpos]
680
        dec     eax
681
        mov     [eax], byte 0
682
        popa
683
        ret
4923 Serge 684
;-----------------------------------------------------------------------------
4429 Serge 685
;*************************************************
686
;*         ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД         *
687
;* Входные параметры передаются через глобальные *
688
;* перменные:                                    *
689
;* ChannelNumber - номер канала;                 *
690
;* DiskNumber - номер диска на канале.           *
691
;*************************************************
692
LoadMedium:
693
        pusha
694
; Очистить буфер пакетной команды
695
        call    clear_packet_buffer
696
; Сформировать команду START/STOP UNIT
697
        ; Задать код команды
4923 Serge 698
        mov     [PacketCommand], word 0x1B
4429 Serge 699
        ; Задать операцию загрузки носителя
700
        mov     [PacketCommand+4], word 00000011b
701
; Подать команду
702
        call    SendPacketNoDatCommand
703
        popa
704
        ret
4923 Serge 705
;-----------------------------------------------------------------------------
4429 Serge 706
;*************************************************
707
;*         ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА         *
708
;* Входные параметры передаются через глобальные *
709
;* перменные:                                    *
710
;* ChannelNumber - номер канала;                 *
711
;* DiskNumber - номер диска на канале.           *
712
;*************************************************
713
EjectMedium:
714
        pusha
715
; Очистить буфер пакетной команды
716
        call    clear_packet_buffer
717
; Сформировать команду START/STOP UNIT
718
        ; Задать код команды
4923 Serge 719
        mov     [PacketCommand], word 0x1B
4429 Serge 720
        ; Задать операцию извлечения носителя
721
        mov     [PacketCommand+4], word 00000010b
722
; Подать команду
723
        call    SendPacketNoDatCommand
724
        popa
725
        ret
4923 Serge 726
;-----------------------------------------------------------------------------
4429 Serge 727
;*************************************************
728
;* Проверить событие нажатия кнопки извлечения   *
729
;*                     диска                     *
730
;* Входные параметры передаются через глобальные *
731
;* переменные:                                   *
732
;* ChannelNumber - номер канала;                 *
733
;* DiskNumber - номер диска на канале.           *
734
;*************************************************
735
proc check_ATAPI_device_event_has_work?
736
        mov     eax, [timer_ticks]
737
        sub     eax, [timer_ATAPI_check]
738
        cmp     eax, 100
739
        jb      .no
4923 Serge 740
 
4429 Serge 741
        xor     eax, eax
742
        inc     eax
743
        ret
4923 Serge 744
;--------------------------------------
4429 Serge 745
.no:
746
        xor     eax, eax
747
        ret
748
endp
4923 Serge 749
;-----------------------------------------------------------------------------
4429 Serge 750
align 4
751
check_ATAPI_device_event:
752
        pusha
753
        mov     eax, [timer_ticks]
754
        sub     eax, [timer_ATAPI_check]
755
        cmp     eax, 100
756
        jb      .end_1
4923 Serge 757
 
758
        pushfd
4429 Serge 759
        mov     al, [DRIVE_DATA+1]
760
        and     al, 11b
761
        cmp     al, 10b
762
        jz      .ide3
4923 Serge 763
;--------------------------------------
4429 Serge 764
.ide2_1:
765
        mov     al, [DRIVE_DATA+1]
766
        and     al, 1100b
767
        cmp     al, 1000b
768
        jz      .ide2
4923 Serge 769
;--------------------------------------
4429 Serge 770
.ide1_1:
771
        mov     al, [DRIVE_DATA+1]
772
        and     al, 110000b
773
        cmp     al, 100000b
774
        jz      .ide1
4923 Serge 775
;--------------------------------------
4429 Serge 776
.ide0_1:
777
        mov     al, [DRIVE_DATA+1]
778
        and     al, 11000000b
779
        cmp     al, 10000000b
780
        jz      .ide0
4923 Serge 781
;--------------------------------------
782
.ide7_1:
783
        mov     al, [DRIVE_DATA+6]
784
        and     al, 11b
785
        cmp     al, 10b
786
        jz      .ide7
787
;--------------------------------------
788
.ide6_1:
789
        mov     al, [DRIVE_DATA+6]
790
        and     al, 1100b
791
        cmp     al, 1000b
792
        jz      .ide6
793
;--------------------------------------
794
.ide5_1:
795
        mov     al, [DRIVE_DATA+6]
796
        and     al, 110000b
797
        cmp     al, 100000b
798
        jz      .ide5
799
;--------------------------------------
800
.ide4_1:
801
        mov     al, [DRIVE_DATA+6]
802
        and     al, 11000000b
803
        cmp     al, 10000000b
804
        jz      .ide4
805
;--------------------------------------
806
.ide11_1:
807
        mov     al, [DRIVE_DATA+11]
808
        and     al, 11b
809
        cmp     al, 10b
810
        jz      .ide11
811
;--------------------------------------
812
.ide10_1:
813
        mov     al, [DRIVE_DATA+11]
814
        and     al, 1100b
815
        cmp     al, 1000b
816
        jz      .ide10
817
;--------------------------------------
818
.ide9_1:
819
        mov     al, [DRIVE_DATA+11]
820
        and     al, 110000b
821
        cmp     al, 100000b
822
        jz      .ide9
823
;--------------------------------------
824
.ide8_1:
825
        mov     al, [DRIVE_DATA+11]
826
        and     al, 11000000b
827
        cmp     al, 10000000b
828
        jz      .ide8
829
;--------------------------------------
4429 Serge 830
.end:
4923 Serge 831
        popfd
4429 Serge 832
        mov     eax, [timer_ticks]
833
        mov     [timer_ATAPI_check], eax
4923 Serge 834
;--------------------------------------
4429 Serge 835
.end_1:
836
        popa
837
        ret
4923 Serge 838
;-----------------------------------------------------------------------------
4429 Serge 839
.ide3:
840
        cli
841
        cmp     [ATAPI_IDE3_lock], 1
842
        jne     .ide2_1
4923 Serge 843
 
4429 Serge 844
        cmp     [cd_status], 0
845
        jne     .end
4923 Serge 846
 
4429 Serge 847
        mov     ecx, ide_channel2_mutex
848
        call    mutex_lock
849
        call    reserve_ok2
850
        mov     [ChannelNumber], 2
851
        mov     [DiskNumber], 1
852
        mov     [cdpos], 4
853
        call    GetEvent_StatusNotification
854
        cmp     [CDDataBuf+4], byte 1
4923 Serge 855
        jne     @f
856
 
4429 Serge 857
        call    .eject
4923 Serge 858
;--------------------------------------
859
@@:
4429 Serge 860
        call    syscall_cdaudio.free
861
        jmp     .ide2_1
4923 Serge 862
;-----------------------------------------------------------------------------
4429 Serge 863
.ide2:
864
        cli
865
        cmp     [ATAPI_IDE2_lock], 1
866
        jne     .ide1_1
4923 Serge 867
 
4429 Serge 868
        cmp     [cd_status], 0
869
        jne     .end
4923 Serge 870
 
4429 Serge 871
        mov     ecx, ide_channel2_mutex
872
        call    mutex_lock
873
        call    reserve_ok2
874
        mov     [ChannelNumber], 2
875
        mov     [DiskNumber], 0
876
        mov     [cdpos], 3
877
        call    GetEvent_StatusNotification
878
        cmp     [CDDataBuf+4], byte 1
4923 Serge 879
        jne     @f
880
 
4429 Serge 881
        call    .eject
4923 Serge 882
;--------------------------------------
883
@@:
4429 Serge 884
        call    syscall_cdaudio.free
885
        jmp     .ide1_1
4923 Serge 886
;-----------------------------------------------------------------------------
4429 Serge 887
.ide1:
888
        cli
889
        cmp     [ATAPI_IDE1_lock], 1
890
        jne     .ide0_1
4923 Serge 891
 
4429 Serge 892
        cmp     [cd_status], 0
893
        jne     .end
4923 Serge 894
 
4429 Serge 895
        mov     ecx, ide_channel1_mutex
896
        call    mutex_lock
897
        call    reserve_ok2
898
        mov     [ChannelNumber], 1
899
        mov     [DiskNumber], 1
900
        mov     [cdpos], 2
901
        call    GetEvent_StatusNotification
902
        cmp     [CDDataBuf+4], byte 1
4923 Serge 903
        jne     @f
904
 
4429 Serge 905
        call    .eject
4923 Serge 906
;--------------------------------------
907
@@:
4429 Serge 908
        call    syscall_cdaudio.free
909
        jmp     .ide0_1
4923 Serge 910
;-----------------------------------------------------------------------------
4429 Serge 911
.ide0:
912
        cli
913
        cmp     [ATAPI_IDE0_lock], 1
4923 Serge 914
        jne     .ide7_1
915
 
4429 Serge 916
        cmp     [cd_status], 0
917
        jne     .end
4923 Serge 918
 
4429 Serge 919
        mov     ecx, ide_channel1_mutex
920
        call    mutex_lock
921
        call    reserve_ok2
922
        mov     [ChannelNumber], 1
923
        mov     [DiskNumber], 0
924
        mov     [cdpos], 1
925
        call    GetEvent_StatusNotification
926
        cmp     [CDDataBuf+4], byte 1
4923 Serge 927
        jne     @f
928
 
929
        call    .eject
930
;--------------------------------------
931
@@:
4429 Serge 932
        call    syscall_cdaudio.free
4923 Serge 933
        jmp     .ide7_1
934
;-----------------------------------------------------------------------------
935
.ide7:
936
        cli
937
        cmp     [ATAPI_IDE7_lock], 1
938
        jne     .ide6_1
939
 
940
        cmp     [cd_status], 0
941
        jne     .end
942
 
943
        mov     ecx, ide_channel4_mutex
944
        call    mutex_lock
945
        call    reserve_ok2
946
        mov     [ChannelNumber], 2
947
        mov     [DiskNumber], 1
948
        mov     [cdpos], 8
949
        call    GetEvent_StatusNotification
950
        cmp     [CDDataBuf+4], byte 1
951
        jne     @f
952
 
4429 Serge 953
        call    .eject
4923 Serge 954
;--------------------------------------
955
@@:
4429 Serge 956
        call    syscall_cdaudio.free
4923 Serge 957
        jmp     .ide6_1
958
;-----------------------------------------------------------------------------
959
.ide6:
960
        cli
961
        cmp     [ATAPI_IDE6_lock], 1
962
        jne     .ide5_1
963
 
964
        cmp     [cd_status], 0
965
        jne     .end
966
 
967
        mov     ecx, ide_channel4_mutex
968
        call    mutex_lock
969
        call    reserve_ok2
970
        mov     [ChannelNumber], 2
971
        mov     [DiskNumber], 0
972
        mov     [cdpos], 7
973
        call    GetEvent_StatusNotification
974
        cmp     [CDDataBuf+4], byte 1
975
        jne     @f
976
 
977
        call    .eject
978
;--------------------------------------
979
@@:
980
        call    syscall_cdaudio.free
981
        jmp     .ide5_1
982
;-----------------------------------------------------------------------------
983
.ide5:
984
        cli
985
        cmp     [ATAPI_IDE5_lock], 1
986
        jne     .ide4_1
987
 
988
        cmp     [cd_status], 0
989
        jne     .end
990
 
991
        mov     ecx, ide_channel3_mutex
992
        call    mutex_lock
993
        call    reserve_ok2
994
        mov     [ChannelNumber], 1
995
        mov     [DiskNumber], 1
996
        mov     [cdpos], 6
997
        call    GetEvent_StatusNotification
998
        cmp     [CDDataBuf+4], byte 1
999
        jne     @f
1000
 
1001
        call    .eject
1002
;--------------------------------------
1003
@@:
1004
        call    syscall_cdaudio.free
1005
        jmp     .ide4_1
1006
;-----------------------------------------------------------------------------
1007
.ide4:
1008
        cli
1009
        cmp     [ATAPI_IDE4_lock], 1
1010
        jne     .ide11_1
1011
 
1012
        cmp     [cd_status], 0
1013
        jne     .end
1014
 
1015
        mov     ecx, ide_channel3_mutex
1016
        call    mutex_lock
1017
        call    reserve_ok2
1018
        mov     [ChannelNumber], 1
1019
        mov     [DiskNumber], 0
1020
        mov     [cdpos], 5
1021
        call    GetEvent_StatusNotification
1022
        cmp     [CDDataBuf+4], byte 1
1023
        jne     @f
1024
 
1025
        call    .eject
1026
;--------------------------------------
1027
@@:
1028
        call    syscall_cdaudio.free
1029
        jmp     .ide11_1
1030
;-----------------------------------------------------------------------------
1031
.ide11:
1032
        cli
1033
        cmp     [ATAPI_IDE11_lock], 1
1034
        jne     .ide10_1
1035
 
1036
        cmp     [cd_status], 0
1037
        jne     .end
1038
 
1039
        mov     ecx, ide_channel6_mutex
1040
        call    mutex_lock
1041
        call    reserve_ok2
1042
        mov     [ChannelNumber], 2
1043
        mov     [DiskNumber], 1
1044
        mov     [cdpos], 12
1045
        call    GetEvent_StatusNotification
1046
        cmp     [CDDataBuf+4], byte 1
1047
        jne     @f
1048
 
1049
        call    .eject
1050
;--------------------------------------
1051
@@:
1052
        call    syscall_cdaudio.free
1053
        jmp     .ide10_1
1054
;-----------------------------------------------------------------------------
1055
.ide10:
1056
        cli
1057
        cmp     [ATAPI_IDE10_lock], 1
1058
        jne     .ide9_1
1059
 
1060
        cmp     [cd_status], 0
1061
        jne     .end
1062
 
1063
        mov     ecx, ide_channel6_mutex
1064
        call    mutex_lock
1065
        call    reserve_ok2
1066
        mov     [ChannelNumber], 2
1067
        mov     [DiskNumber], 0
1068
        mov     [cdpos], 11
1069
        call    GetEvent_StatusNotification
1070
        cmp     [CDDataBuf+4], byte 1
1071
        jne     @f
1072
 
1073
        call    .eject
1074
;--------------------------------------
1075
@@:
1076
        call    syscall_cdaudio.free
1077
        jmp     .ide9_1
1078
;-----------------------------------------------------------------------------
1079
.ide9:
1080
        cli
1081
        cmp     [ATAPI_IDE9_lock], 1
1082
        jne     .ide8_1
1083
 
1084
        cmp     [cd_status], 0
1085
        jne     .end
1086
 
1087
        mov     ecx, ide_channel5_mutex
1088
        call    mutex_lock
1089
        call    reserve_ok2
1090
        mov     [ChannelNumber], 1
1091
        mov     [DiskNumber], 1
1092
        mov     [cdpos], 10
1093
        call    GetEvent_StatusNotification
1094
        cmp     [CDDataBuf+4], byte 1
1095
        jne     @f
1096
 
1097
        call    .eject
1098
;--------------------------------------
1099
@@:
1100
        call    syscall_cdaudio.free
1101
        jmp     .ide8_1
1102
;-----------------------------------------------------------------------------
1103
.ide8:
1104
        cli
1105
        cmp     [ATAPI_IDE8_lock], 1
1106
        jne     .end
1107
 
1108
        cmp     [cd_status], 0
1109
        jne     .end
1110
 
1111
        mov     ecx, ide_channel5_mutex
1112
        call    mutex_lock
1113
        call    reserve_ok2
1114
        mov     [ChannelNumber], 1
1115
        mov     [DiskNumber], 0
1116
        mov     [cdpos], 9
1117
        call    GetEvent_StatusNotification
1118
        cmp     [CDDataBuf+4], byte 1
1119
        jne     @f
1120
 
1121
        call    .eject
1122
;--------------------------------------
1123
@@:
1124
        call    syscall_cdaudio.free
4429 Serge 1125
        jmp     .end
4923 Serge 1126
;-----------------------------------------------------------------------------
4429 Serge 1127
.eject:
1128
        call    clear_CD_cache
1129
        call    allow_medium_removal
1130
        mov     [ignore_CD_eject_wait], 1
1131
        call    EjectMedium
1132
        mov     [ignore_CD_eject_wait], 0
1133
        ret
4923 Serge 1134
;-----------------------------------------------------------------------------
4429 Serge 1135
iglobal
1136
timer_ATAPI_check dd 0
1137
ATAPI_IDE0_lock db 0
1138
ATAPI_IDE1_lock db 0
1139
ATAPI_IDE2_lock db 0
1140
ATAPI_IDE3_lock db 0
4923 Serge 1141
ATAPI_IDE4_lock db 0
1142
ATAPI_IDE5_lock db 0
1143
ATAPI_IDE6_lock db 0
1144
ATAPI_IDE7_lock db 0
1145
ATAPI_IDE8_lock db 0
1146
ATAPI_IDE9_lock db 0
1147
ATAPI_IDE10_lock db 0
1148
ATAPI_IDE11_lock db 0
4429 Serge 1149
ignore_CD_eject_wait db 0
1150
endg
4923 Serge 1151
;-----------------------------------------------------------------------------
4429 Serge 1152
;*************************************************
1153
;* Получить сообщение о событии или состоянии    *
1154
;*                  устройства                   *
1155
;* Входные параметры передаются через глобальные *
1156
;* переменные:                                   *
1157
;* ChannelNumber - номер канала;                 *
1158
;* DiskNumber - номер диска на канале.           *
1159
;*************************************************
1160
GetEvent_StatusNotification:
1161
        pusha
1162
        mov     [CDDataBuf_pointer], CDDataBuf
1163
; Очистить буфер пакетной команды
1164
        call    clear_packet_buffer
1165
; Задать код команды
1166
        mov     [PacketCommand], byte 4Ah
1167
        mov     [PacketCommand+1], byte 00000001b
1168
; Задать запрос класса сообщений
1169
        mov     [PacketCommand+4], byte 00010000b
1170
; Размер выделенной области
1171
        mov     [PacketCommand+7], byte 8h
1172
        mov     [PacketCommand+8], byte 0h
1173
; Подать команду
1174
        call    SendPacketDatCommand
1175
        popa
1176
        ret
4923 Serge 1177
;-----------------------------------------------------------------------------
4429 Serge 1178
;*************************************************
1179
; прочитать информацию из TOC
1180
;* Входные параметры передаются через глобальные *
1181
;* переменные:                                   *
1182
;* ChannelNumber - номер канала;                 *
1183
;* DiskNumber - номер диска на канале.           *
1184
;*************************************************
1185
Read_TOC:
1186
        pusha
1187
        mov     [CDDataBuf_pointer], CDDataBuf
1188
; Очистить буфер пакетной команды
1189
        call    clear_packet_buffer
1190
; Сформировать пакетную команду для считывания
1191
; сектора данных
1192
        mov     [PacketCommand], byte 0x43
1193
        ; Задать формат
1194
        mov     [PacketCommand+2], byte 1
1195
; Размер выделенной области
1196
        mov     [PacketCommand+7], byte 0xFF
1197
        mov     [PacketCommand+8], byte 0h
1198
; Подать команду
1199
        call    SendPacketDatCommand
1200
        popa
1201
        ret
4923 Serge 1202
;-----------------------------------------------------------------------------
4429 Serge 1203
;*************************************************
1204
;* ОПРЕДЕЛИТЬ ОБЩЕЕ КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ *
1205
;* Входные параметры передаются через глобальные *
1206
;* переменные:                                   *
1207
;* ChannelNumber - номер канала;                 *
1208
;* DiskNumber - номер диска на канале.           *
1209
;*************************************************
1210
;ReadCapacity:
1211
;       pusha
1212
;; Очистить буфер пакетной команды
1213
;       call  clear_packet_buffer
1214
;; Задать размер буфера в байтах
1215
;       mov     [CDBlockSize],8
1216
;; Сформировать команду READ CAPACITY
1217
;       mov     [PacketCommand],word 25h
1218
;; Подать команду
1219
;       call    SendPacketDatCommand
1220
;       popa
1221
;       ret
4923 Serge 1222
;-----------------------------------------------------------------------------
4429 Serge 1223
clear_packet_buffer:
1224
; Очистить буфер пакетной команды
1225
        and     [PacketCommand], dword 0
1226
        and     [PacketCommand+4], dword 0
1227
        and     [PacketCommand+8], dword 0
1228
        ret
4923 Serge 1229
;-----------------------------------------------------------------------------