Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1159 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
1206 hidnplayr 8
$Revision: 1206 $
1159 hidnplayr 9
 
10
 
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
 
24
;*************************************************
25
;*      ПОЛНОЕ ЧТЕНИЕ СЕКТОРА КОМПАКТ-ДИСКА      *
26
;* Считываются данные пользователя, информация   *
27
;* субканала и контрольная информация            *
28
;* Входные параметры передаются через глобальные *
29
;* перменные:                                    *
30
;* ChannelNumber - номер канала;                 *
31
;* DiskNumber - номер диска на канале;           *
32
;* CDSectorAddress - адрес считываемого сектора. *
33
;* Данные считывается в массив CDDataBuf.        *
34
;*************************************************
35
ReadCD:
1198 clevermous 36
        pusha
1159 hidnplayr 37
; Задать размер сектора
1198 clevermous 38
        mov       [CDBlockSize],2048 ;2352
1159 hidnplayr 39
; Очистить буфер пакетной команды
1198 clevermous 40
        call  clear_packet_buffer
1159 hidnplayr 41
; Сформировать пакетную команду для считывания
42
; сектора данных
1198 clevermous 43
        ; Задать код команды Read CD
44
        mov       [PacketCommand],byte 0x28  ;0xBE
45
        ; Задать адрес сектора
46
        mov   AX,word [CDSectorAddress+2]
47
        xchg  AL,AH
48
        mov   word [PacketCommand+2],AX
49
        mov   AX,word [CDSectorAddress]
50
        xchg  AL,AH
51
        mov   word [PacketCommand+4],AX
1159 hidnplayr 52
;        mov   eax,[CDSectorAddress]
53
;        mov   [PacketCommand+2],eax
1198 clevermous 54
        ; Задать количество считываемых секторов
55
        mov       [PacketCommand+8],byte 1
56
        ; Задать считывание данных в полном объеме
1159 hidnplayr 57
;        mov     [PacketCommand+9],byte 0xF8
58
; Подать команду
1198 clevermous 59
        call  SendPacketDatCommand
60
        popa
61
        ret
1159 hidnplayr 62
 
63
;********************************************
64
;*        ЧТЕНИЕ СЕКТОРА С ПОВТОРАМИ        *
65
;* Многократное повторение чтения при сбоях *
66
;********************************************
67
ReadCDWRetr:
68
;-----------------------------------------------------------
69
; input  : eax = block to read
70
;          ebx = destination
71
;-----------------------------------------------------------
72
    pushad
73
    mov   eax,[CDSectorAddress]
74
    mov   ebx,[CDDataBuf_pointer]
75
    call  cd_calculate_cache
76
    add   esi,8
77
    mov   edi,1
78
.hdreadcache:
79
;    cmp   dword [esi+4],0       ; empty
80
;    je    .nohdcache
1198 clevermous 81
    cmp   [esi],eax             ; correct sector
82
    je    .yeshdcache
1159 hidnplayr 83
.nohdcache:
84
    add   esi,8
85
    inc   edi
86
    dec   ecx
87
    jnz   .hdreadcache
1198 clevermous 88
    call  find_empty_slot_CD_cache       ; ret in edi
1159 hidnplayr 89
 
90
    push  edi
91
    push  eax
92
    call  cd_calculate_cache_2
93
    shl   edi,11
94
    add   edi,eax
95
    mov   [CDDataBuf_pointer],edi
96
    pop   eax
97
    pop   edi
98
 
99
    call  ReadCDWRetr_1
100
    cmp   [DevErrorCode],0
101
    jne   .exit
102
 
103
    mov   [CDDataBuf_pointer],ebx
104
    call  cd_calculate_cache_1
105
    lea   esi,[edi*8+esi]
1198 clevermous 106
    mov   [esi],eax             ; sector number
1159 hidnplayr 107
;    mov   dword [esi+4],1       ; hd read - mark as same as in hd
108
.yeshdcache:
109
    mov   esi,edi
110
    shl   esi,11    ;9
111
    push  eax
112
    call  cd_calculate_cache_2
113
    add   esi,eax
114
    pop   eax
115
    mov   edi,ebx   ;[CDDataBuf_pointer]
116
    mov   ecx,512   ;/4
117
    cld
1198 clevermous 118
    rep   movsd                 ; move data
1159 hidnplayr 119
.exit:
120
    popad
121
    ret
122
 
123
ReadCDWRetr_1:
1198 clevermous 124
        pushad
1159 hidnplayr 125
 
126
; Цикл, пока команда не выполнена успешно или не
127
; исчерпано количество попыток
1198 clevermous 128
        mov       ECX,MaxRetr
1159 hidnplayr 129
@@NextRetr:
130
; Подать команду
1198 clevermous 131
        call  ReadCD
132
        cmp       [DevErrorCode],0
133
        je        @@End_4
1159 hidnplayr 134
 
1198 clevermous 135
        or    ecx,ecx           ;{SPraid.simba} (for cd load)
136
        jz    @@End_4
137
        dec   ecx
1159 hidnplayr 138
 
1198 clevermous 139
        cmp   [timer_ticks_enable],0
140
        jne   @f
141
        mov   eax,NoTickWaitTime
1159 hidnplayr 142
.wait:
1198 clevermous 143
        dec   eax
144
        cmp   eax,0
145
        je    @@NextRetr
146
        jmp       .wait
1159 hidnplayr 147
@@:
148
; Задержка на 2,5 секунды
149
;       mov     EAX,[timer_ticks]
150
;       add     EAX,50  ;250
151
;@@Wait:
152
;       call    change_task
153
;       cmp     EAX,[timer_ticks]
154
;       ja      @@Wait
1198 clevermous 155
        loop  @@NextRetr
1159 hidnplayr 156
@@End_4:
1198 clevermous 157
        popad
158
        ret
1159 hidnplayr 159
 
160
 
161
;   Универсальные процедуры, обеспечивающие выполнение
162
;             пакетных команд в режиме PIO
163
 
164
; Максимально допустимое время ожидания реакции
165
; устройства на пакетную команду (в тиках)
166
MaxCDWaitTime equ 1000 ;200 ;10 секунд
167
 
168
; Область памяти для формирования пакетной команды
1198 clevermous 169
PacketCommand:   rb 12  ;DB 12 DUP (?)
1159 hidnplayr 170
; Область памяти для приема данных от дисковода
171
;CDDataBuf       DB 4096 DUP (0)
172
; Размер принимаемого блока данных в байтах
1198 clevermous 173
CDBlockSize     DW ?
1159 hidnplayr 174
; Адрес считываемого сектора данных
175
CDSectorAddress: DD ?
176
; Время начала очередной операции с диском
177
TickCounter_1 DD 0
178
; Время начала ожидания готовности устройства
179
WURStartTime DD 0
180
; указатель буфера для считывания
181
CDDataBuf_pointer dd 0
182
 
183
;****************************************************
184
;*    ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ,    *
185
;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ *
186
;*     РАЗМЕРОМ 2048 БАЙТ ОТ УСТРОЙСТВА К ХОСТУ     *
187
;* Входные параметры передаются через глобальные    *
188
;* перменные:                                       *
189
;* ChannelNumber - номер канала;                    *
190
;* DiskNumber - номер диска на канале;              *
191
;* PacketCommand - 12-байтный командный пакет;      *
192
;* CDBlockSize - размер принимаемого блока данных.  *
193
;****************************************************
194
SendPacketDatCommand:
1198 clevermous 195
        pushad
196
        mov   [DevErrorCode],0
1159 hidnplayr 197
; Задать режим CHS
1198 clevermous 198
        mov     [ATAAddressMode],0
1159 hidnplayr 199
; Послать ATA-команду передачи пакетной команды
1198 clevermous 200
        mov     [ATAFeatures],0
201
        mov     [ATASectorCount],0
202
        mov     [ATASectorNumber],0
203
        ; Загрузить размер передаваемого блока
204
        mov     AX,[CDBlockSize]
205
        mov     [ATACylinder],AX
206
        mov     [ATAHead],0
207
        mov     [ATACommand],0A0h
208
        call    SendCommandToHDD_1
209
        cmp     [DevErrorCode],0 ;проверить код ошибки
210
        jne     @@End_8    ;закончить, сохранив код ошибки
1159 hidnplayr 211
 
212
; Ожидание готовности дисковода к приему
213
; пакетной команды
1198 clevermous 214
        mov     DX,[ATABasePortAddr]
215
        add     DX,7     ;порт 1х7h
216
        mov     ecx,NoTickWaitTime
1159 hidnplayr 217
@@WaitDevice0:
1198 clevermous 218
        cmp     [timer_ticks_enable],0
219
        jne     @f
220
        dec     ecx
221
        cmp     ecx,0
222
        je      @@Err1_1
223
        jmp     .test
1159 hidnplayr 224
@@:
1198 clevermous 225
        call    change_task
226
        ; Проверить время выполнения команды
227
        mov     EAX,[timer_ticks]
228
        sub     EAX,[TickCounter_1]
229
        cmp     EAX,BSYWaitTime
230
        ja      @@Err1_1   ;ошибка тайм-аута
231
        ; Проверить готовность
1159 hidnplayr 232
.test:
1198 clevermous 233
        in      AL,DX
234
        test    AL,80h   ;состояние сигнала BSY
235
        jnz     @@WaitDevice0
236
        test    AL,08h   ;состояние сигнала DRQ
237
        jz      @@WaitDevice0
238
        test    AL,1     ;состояние сигнала ERR
239
        jnz     @@Err6
1159 hidnplayr 240
; Послать пакетную команду
1198 clevermous 241
        cli
242
        mov     DX,[ATABasePortAddr]
243
        mov     AX,[PacketCommand]
244
        out     DX,AX
245
        mov     AX,[PacketCommand+2]
246
        out     DX,AX
247
        mov     AX,[PacketCommand+4]
248
        out     DX,AX
249
        mov     AX,[PacketCommand+6]
250
        out     DX,AX
251
        mov     AX,[PacketCommand+8]
252
        out     DX,AX
253
        mov     AX,[PacketCommand+10]
254
        out     DX,AX
255
        sti
1159 hidnplayr 256
; Ожидание готовности данных
1198 clevermous 257
        mov     DX,[ATABasePortAddr]
258
        add     DX,7   ;порт 1х7h
259
        mov     ecx,NoTickWaitTime
1159 hidnplayr 260
@@WaitDevice1:
1198 clevermous 261
        cmp     [timer_ticks_enable],0
262
        jne     @f
263
        dec     ecx
264
        cmp     ecx,0
265
        je      @@Err1_1
266
        jmp     .test_1
1159 hidnplayr 267
@@:
1198 clevermous 268
        call    change_task
269
        ; Проверить время выполнения команды
270
        mov     EAX,[timer_ticks]
271
        sub     EAX,[TickCounter_1]
272
        cmp     EAX,MaxCDWaitTime
273
        ja      @@Err1_1   ;ошибка тайм-аута
274
        ; Проверить готовность
1159 hidnplayr 275
.test_1:
1198 clevermous 276
        in      AL,DX
277
        test    AL,80h   ;состояние сигнала BSY
278
        jnz     @@WaitDevice1
279
        test    AL,08h   ;состояние сигнала DRQ
280
        jz      @@WaitDevice1
281
        test    AL,1     ;состояние сигнала ERR
282
        jnz     @@Err6_temp
1159 hidnplayr 283
; Принять блок данных от контроллера
1198 clevermous 284
        mov     EDI,[CDDataBuf_pointer] ;0x7000  ;CDDataBuf
285
        ; Загрузить адрес регистра данных контроллера
286
        mov     DX,[ATABasePortAddr] ;порт 1x0h
287
        ; Загрузить в счетчик размер блока в байтах
288
        xor     ecx,ecx
289
        mov     CX,[CDBlockSize]
290
        ; Вычислить размер блока в 16-разрядных словах
291
        shr     CX,1 ;разделить размер блока на 2
292
        ; Принять блок данных
293
        cli
294
        cld
295
        rep     insw
296
        sti
297
        ; Успешное завершение приема данных
298
        jmp @@End_8
1159 hidnplayr 299
 
300
; Записать код ошибки
301
@@Err1_1:
1198 clevermous 302
        mov     [DevErrorCode],1
303
        jmp @@End_8
1159 hidnplayr 304
@@Err6_temp:
1198 clevermous 305
        mov     [DevErrorCode],7
306
        jmp @@End_8
1159 hidnplayr 307
@@Err6:
1198 clevermous 308
        mov     [DevErrorCode],6
1159 hidnplayr 309
@@End_8:
1198 clevermous 310
        popad
311
        ret
1159 hidnplayr 312
 
313
 
314
 
315
;***********************************************
316
;*  ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
317
;*     НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ    *
318
;* Входные параметры передаются через          *
319
;* глобальные перменные:                       *
320
;* ChannelNumber - номер канала;               *
321
;* DiskNumber - номер диска на канале;         *
322
;* PacketCommand - 12-байтный командный пакет. *
323
;***********************************************
324
SendPacketNoDatCommand:
1198 clevermous 325
        pushad
1159 hidnplayr 326
    mov   [DevErrorCode],0
327
; Задать режим CHS
1198 clevermous 328
        mov     [ATAAddressMode],0
1159 hidnplayr 329
; Послать ATA-команду передачи пакетной команды
1198 clevermous 330
        mov     [ATAFeatures],0
331
        mov     [ATASectorCount],0
332
        mov     [ATASectorNumber],0
333
        mov     [ATACylinder],0
334
        mov     [ATAHead],0
335
        mov     [ATACommand],0A0h
336
        call    SendCommandToHDD_1
337
        cmp     [DevErrorCode],0 ;проверить код ошибки
338
        jne     @@End_9  ;закончить, сохранив код ошибки
1159 hidnplayr 339
; Ожидание готовности дисковода к приему
340
; пакетной команды
1198 clevermous 341
        mov     DX,[ATABasePortAddr]
342
        add     DX,7   ;порт 1х7h
1159 hidnplayr 343
@@WaitDevice0_1:
1198 clevermous 344
        call    change_task
345
        ; Проверить время ожидания
346
        mov     EAX,[timer_ticks]
347
        sub     EAX,[TickCounter_1]
348
        cmp     EAX,BSYWaitTime
349
        ja      @@Err1_3   ;ошибка тайм-аута
350
        ; Проверить готовность
351
        in      AL,DX
352
        test    AL,80h   ;состояние сигнала BSY
353
        jnz     @@WaitDevice0_1
354
        test    AL,1     ;состояние сигнала ERR
355
        jnz     @@Err6_1
356
        test    AL,08h   ;состояние сигнала DRQ
357
        jz      @@WaitDevice0_1
1159 hidnplayr 358
; Послать пакетную команду
359
;        cli
1198 clevermous 360
        mov     DX,[ATABasePortAddr]
361
        mov     AX,word [PacketCommand]
362
        out     DX,AX
363
        mov     AX,word [PacketCommand+2]
364
        out     DX,AX
365
        mov     AX,word [PacketCommand+4]
366
        out     DX,AX
367
        mov     AX,word [PacketCommand+6]
368
        out     DX,AX
369
        mov     AX,word [PacketCommand+8]
370
        out     DX,AX
371
        mov     AX,word [PacketCommand+10]
372
        out     DX,AX
1159 hidnplayr 373
;        sti
374
    cmp [ignore_CD_eject_wait],1
1198 clevermous 375
    je  @@End_9
1159 hidnplayr 376
; Ожидание подтверждения приема команды
1198 clevermous 377
        mov     DX,[ATABasePortAddr]
378
        add     DX,7   ;порт 1х7h
1159 hidnplayr 379
@@WaitDevice1_1:
1198 clevermous 380
        call    change_task
381
        ; Проверить время выполнения команды
382
        mov     EAX,[timer_ticks]
383
        sub     EAX,[TickCounter_1]
384
        cmp     EAX,MaxCDWaitTime
385
        ja      @@Err1_3   ;ошибка тайм-аута
386
        ; Ожидать освобождения устройства
387
        in      AL,DX
388
        test    AL,80h   ;состояние сигнала BSY
389
        jnz     @@WaitDevice1_1
390
        test    AL,1     ;состояние сигнала ERR
391
        jnz     @@Err6_1
392
        test    AL,40h   ;состояние сигнала DRDY
393
        jz      @@WaitDevice1_1
394
        jmp @@End_9
1159 hidnplayr 395
 
396
; Записать код ошибки
397
@@Err1_3:
1198 clevermous 398
        mov     [DevErrorCode],1
399
        jmp @@End_9
1159 hidnplayr 400
@@Err6_1:
1198 clevermous 401
        mov     [DevErrorCode],6
1159 hidnplayr 402
@@End_9:
1198 clevermous 403
        popad
404
        ret
1159 hidnplayr 405
 
406
;****************************************************
407
;*          ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ         *
408
;* Входные параметры передаются через глобальные    *
409
;* переменные:                                      *
410
;* ChannelNumber - номер канала (1 или 2);          *
411
;* DiskNumber - номер диска (0 или 1);              *
412
;* ATAFeatures - "особенности";                     *
413
;* ATASectorCount - количество секторов;            *
414
;* ATASectorNumber - номер начального сектора;      *
415
;* ATACylinder - номер начального цилиндра;         *
416
;* ATAHead - номер начальной головки;               *
417
;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); *
418
;* ATACommand - код команды.                        *
419
;* После успешного выполнения функции:              *
420
;* в ATABasePortAddr - базовый адрес HDD;           *
421
;* в DevErrorCode - ноль.                           *
422
;* При возникновении ошибки в DevErrorCode будет    *
423
;* возвращен код ошибки.                            *
424
;****************************************************
425
SendCommandToHDD_1:
1198 clevermous 426
        pushad
1159 hidnplayr 427
    mov   [DevErrorCode],0
428
; Проверить значение кода режима
1198 clevermous 429
        cmp     [ATAAddressMode],1
430
        ja      @@Err2_4
1159 hidnplayr 431
; Проверить корректность номера канала
1198 clevermous 432
        mov     BX,[ChannelNumber]
433
        cmp     BX,1
434
        jb      @@Err3_4
435
        cmp     BX,2
436
        ja      @@Err3_4
1159 hidnplayr 437
; Установить базовый адрес
1198 clevermous 438
        dec     BX
439
        shl     BX,1
440
        movzx   ebx,bx
441
        mov     AX,[ebx+StandardATABases]
442
        mov     [ATABasePortAddr],AX
1159 hidnplayr 443
; Ожидание готовности HDD к приему команды
1198 clevermous 444
        ; Выбрать нужный диск
445
        mov     DX,[ATABasePortAddr]
446
        add     DX,6    ;адрес регистра головок
447
        mov     AL,[DiskNumber]
448
        cmp     AL,1    ;проверить номера диска
449
        ja      @@Err4_4
450
        shl     AL,4
451
        or      AL,10100000b
452
        out     DX,AL
453
        ; Ожидать, пока диск не будет готов
454
        inc     DX
455
        mov     eax,[timer_ticks]
456
        mov     [TickCounter_1],eax
457
        mov     ecx,NoTickWaitTime
1159 hidnplayr 458
@@WaitHDReady_2:
1198 clevermous 459
        cmp    [timer_ticks_enable],0
460
        jne    @f
461
        dec    ecx
462
        cmp    ecx,0
463
        je     @@Err1_4
464
        jmp    .test
1159 hidnplayr 465
@@:
1198 clevermous 466
        call    change_task
467
        ; Проверить время ожидания
468
        mov     eax,[timer_ticks]
469
        sub     eax,[TickCounter_1]
470
        cmp     eax,BSYWaitTime ;300    ;ожидать 3 сек.
471
        ja      @@Err1_4   ;ошибка тайм-аута
472
        ; Прочитать регистр состояния
1159 hidnplayr 473
.test:
1198 clevermous 474
        in      AL,DX
475
        ; Проверить состояние сигнала BSY
476
        test    AL,80h
477
        jnz     @@WaitHDReady_2
478
        ; Проверить состояние сигнала DRQ
479
        test    AL,08h
480
        jnz     @@WaitHDReady_2
1159 hidnplayr 481
 
482
; Загрузить команду в регистры контроллера
1198 clevermous 483
        cli
484
        mov     DX,[ATABasePortAddr]
485
        inc     DX      ;регистр "особенностей"
486
        mov     AL,[ATAFeatures]
487
        out     DX,AL
488
        inc     DX      ;счетчик секторов
489
        mov     AL,[ATASectorCount]
490
        out     DX,AL
491
        inc     DX      ;регистр номера сектора
492
        mov     AL,[ATASectorNumber]
493
        out     DX,AL
494
        inc     DX      ;номер цилиндра (младший байт)
495
        mov     AX,[ATACylinder]
496
        out     DX,AL
497
        inc     DX      ;номер цилиндра (старший байт)
498
        mov     AL,AH
499
        out     DX,AL
500
        inc     DX      ;номер головки/номер диска
501
        mov     AL,[DiskNumber]
502
        shl     AL,4
503
        cmp     [ATAHead],0Fh ;проверить номер головки
504
        ja      @@Err5_4
505
        or      AL,[ATAHead]
506
        or      AL,10100000b
507
        mov     AH,[ATAAddressMode]
508
        shl     AH,6
509
        or      AL,AH
510
        out     DX,AL
1159 hidnplayr 511
; Послать команду
1198 clevermous 512
        mov     AL,[ATACommand]
513
        inc     DX      ;регистр команд
514
        out     DX,AL
515
        sti
1159 hidnplayr 516
; Сбросить признак ошибки
1198 clevermous 517
        mov     [DevErrorCode],0
518
        jmp @@End_10
1159 hidnplayr 519
; Записать код ошибки
520
@@Err1_4:
1198 clevermous 521
        mov     [DevErrorCode],1
522
        jmp @@End_10
1159 hidnplayr 523
@@Err2_4:
1198 clevermous 524
        mov     [DevErrorCode],2
525
        jmp @@End_10
1159 hidnplayr 526
@@Err3_4:
1198 clevermous 527
        mov     [DevErrorCode],3
528
        jmp @@End_10
1159 hidnplayr 529
@@Err4_4:
1198 clevermous 530
        mov     [DevErrorCode],4
531
        jmp @@End_10
1159 hidnplayr 532
@@Err5_4:
1198 clevermous 533
        mov     [DevErrorCode],5
1159 hidnplayr 534
; Завершение работы программы
535
@@End_10:
536
;        sti
1198 clevermous 537
        popad
538
        ret
1159 hidnplayr 539
 
540
;*************************************************
541
;*    ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ    *
542
;* Входные параметры передаются через глобальные *
543
;* перменные:                                    *
544
;* ChannelNumber - номер канала;                 *
545
;* DiskNumber - номер диска на канале.           *
546
;*************************************************
547
WaitUnitReady:
1198 clevermous 548
        pusha
1159 hidnplayr 549
; Запомнить время начала операции
1198 clevermous 550
        mov     EAX,[timer_ticks]
551
        mov     [WURStartTime],EAX
1159 hidnplayr 552
; Очистить буфер пакетной команды
1198 clevermous 553
        call  clear_packet_buffer
1159 hidnplayr 554
; Сформировать команду TEST UNIT READY
1198 clevermous 555
        mov     [PacketCommand],word 00h
1159 hidnplayr 556
; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА
1198 clevermous 557
        mov     ecx,NoTickWaitTime
1159 hidnplayr 558
@@SendCommand:
1198 clevermous 559
        ; Подать команду проверки готовности
560
        call    SendPacketNoDatCommand
561
        cmp     [timer_ticks_enable],0
562
        jne     @f
563
        cmp     [DevErrorCode],0
564
        je      @@End_11
565
        dec     ecx
566
        cmp     ecx,0
567
        je      .Error
568
        jmp     @@SendCommand
1159 hidnplayr 569
@@:
1198 clevermous 570
        call    change_task
571
        ; Проверить код ошибки
572
        cmp     [DevErrorCode],0
573
        je      @@End_11
574
        ; Проверить время ожидания готовности
575
        mov     EAX,[timer_ticks]
576
        sub     EAX,[WURStartTime]
577
        cmp     EAX,MaxCDWaitTime
578
        jb      @@SendCommand
1159 hidnplayr 579
.Error:
1198 clevermous 580
        ; Ошибка тайм-аута
581
        mov     [DevErrorCode],1
1159 hidnplayr 582
@@End_11:
1198 clevermous 583
        popa
584
        ret
1159 hidnplayr 585
 
586
;*************************************************
587
;*            ЗАПРЕТИТЬ СМЕНУ ДИСКА              *
588
;* Входные параметры передаются через глобальные *
589
;* перменные:                                    *
590
;* ChannelNumber - номер канала;                 *
591
;* DiskNumber - номер диска на канале.           *
592
;*************************************************
593
prevent_medium_removal:
1198 clevermous 594
        pusha
1159 hidnplayr 595
; Очистить буфер пакетной команды
1198 clevermous 596
        call  clear_packet_buffer
1159 hidnplayr 597
; Задать код команды
1198 clevermous 598
        mov  [PacketCommand],byte 0x1E
1159 hidnplayr 599
; Задать код запрета
600
    mov  [PacketCommand+4],byte 11b
601
; Подать команду
1198 clevermous 602
        call SendPacketNoDatCommand
603
        mov  eax,ATAPI_IDE0_lock
604
        add  eax,[cdpos]
605
        dec  eax
606
        mov  [eax],byte 1
607
        popa
608
        ret
1159 hidnplayr 609
 
610
;*************************************************
611
;*            РАЗРЕШИТЬ СМЕНУ ДИСКА              *
612
;* Входные параметры передаются через глобальные *
613
;* перменные:                                    *
614
;* ChannelNumber - номер канала;                 *
615
;* DiskNumber - номер диска на канале.           *
616
;*************************************************
617
allow_medium_removal:
1198 clevermous 618
        pusha
1159 hidnplayr 619
; Очистить буфер пакетной команды
1198 clevermous 620
        call  clear_packet_buffer
1159 hidnplayr 621
; Задать код команды
1198 clevermous 622
        mov  [PacketCommand],byte 0x1E
1159 hidnplayr 623
; Задать код запрета
624
    mov  [PacketCommand+4],byte 00b
625
; Подать команду
1198 clevermous 626
        call SendPacketNoDatCommand
627
        mov  eax,ATAPI_IDE0_lock
628
        add  eax,[cdpos]
629
        dec  eax
630
        mov  [eax],byte 0
631
        popa
632
        ret
1159 hidnplayr 633
 
634
;*************************************************
635
;*         ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД         *
636
;* Входные параметры передаются через глобальные *
637
;* перменные:                                    *
638
;* ChannelNumber - номер канала;                 *
639
;* DiskNumber - номер диска на канале.           *
640
;*************************************************
641
LoadMedium:
1198 clevermous 642
        pusha
1159 hidnplayr 643
; Очистить буфер пакетной команды
1198 clevermous 644
        call  clear_packet_buffer
1159 hidnplayr 645
; Сформировать команду START/STOP UNIT
1198 clevermous 646
        ; Задать код команды
647
        mov     [PacketCommand],word 1Bh
648
        ; Задать операцию загрузки носителя
649
        mov     [PacketCommand+4],word 00000011b
1159 hidnplayr 650
; Подать команду
1198 clevermous 651
        call    SendPacketNoDatCommand
652
        popa
653
        ret
1159 hidnplayr 654
 
655
;*************************************************
656
;*         ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА         *
657
;* Входные параметры передаются через глобальные *
658
;* перменные:                                    *
659
;* ChannelNumber - номер канала;                 *
660
;* DiskNumber - номер диска на канале.           *
661
;*************************************************
662
EjectMedium:
1198 clevermous 663
        pusha
1159 hidnplayr 664
; Очистить буфер пакетной команды
1198 clevermous 665
        call  clear_packet_buffer
1159 hidnplayr 666
; Сформировать команду START/STOP UNIT
1198 clevermous 667
        ; Задать код команды
668
        mov     [PacketCommand],word 1Bh
669
        ; Задать операцию извлечения носителя
670
        mov     [PacketCommand+4],word 00000010b
1159 hidnplayr 671
; Подать команду
1198 clevermous 672
        call    SendPacketNoDatCommand
673
        popa
674
        ret
1159 hidnplayr 675
 
676
;*************************************************
677
;* Проверить событие нажатия кнопки извлечения   *
678
;*                     диска                     *
679
;* Входные параметры передаются через глобальные *
680
;* переменные:                                   *
681
;* ChannelNumber - номер канала;                 *
682
;* DiskNumber - номер диска на канале.           *
683
;*************************************************
1198 clevermous 684
align 4
1159 hidnplayr 685
check_ATAPI_device_event:
1198 clevermous 686
        pusha
1159 hidnplayr 687
    mov  eax,[timer_ticks]
688
    sub  eax,[timer_ATAPI_check]
689
    cmp  eax,100
1198 clevermous 690
    jb   .end_1
1159 hidnplayr 691
    mov  al,[DRIVE_DATA+1]
692
    and al,11b
693
    cmp al,10b
1198 clevermous 694
    jz  .ide3
1159 hidnplayr 695
.ide2_1:
696
    mov  al,[DRIVE_DATA+1]
697
    and al,1100b
698
    cmp al,1000b
1198 clevermous 699
    jz  .ide2
1159 hidnplayr 700
.ide1_1:
701
    mov  al,[DRIVE_DATA+1]
702
    and al,110000b
703
    cmp al,100000b
1198 clevermous 704
    jz  .ide1
1159 hidnplayr 705
.ide0_1:
706
    mov  al,[DRIVE_DATA+1]
707
    and al,11000000b
708
    cmp al,10000000b
1198 clevermous 709
    jz  .ide0
1159 hidnplayr 710
.end:
711
 
712
    sti
713
    mov  eax,[timer_ticks]
714
    mov  [timer_ATAPI_check],eax
715
.end_1:
1198 clevermous 716
        popa
717
        ret
1159 hidnplayr 718
 
719
.ide3:
720
    cli
721
    cmp  [ATAPI_IDE3_lock],1
722
    jne  .ide2_1
723
    cmp  [IDE_Channel_2],0
724
    jne  .ide1_1
725
    cmp  [cd_status],0
726
    jne  .end
1198 clevermous 727
        mov  [IDE_Channel_2],1
1159 hidnplayr 728
    call reserve_ok2
1198 clevermous 729
        mov  [ChannelNumber],2
730
        mov  [DiskNumber],1
731
        mov      [cdpos],4
732
        call GetEvent_StatusNotification
733
        cmp  [CDDataBuf+4],byte 1
734
        je   .eject_ide3
735
        call syscall_cdaudio.free
1159 hidnplayr 736
    jmp  .ide2_1
737
.eject_ide3:
738
    call .eject
1198 clevermous 739
        call syscall_cdaudio.free
1159 hidnplayr 740
    jmp  .ide2_1
741
 
742
.ide2:
743
    cli
744
    cmp  [ATAPI_IDE2_lock],1
745
    jne  .ide1_1
746
    cmp  [IDE_Channel_2],0
747
    jne  .ide1_1
748
    cmp  [cd_status],0
749
    jne  .end
1198 clevermous 750
        mov  [IDE_Channel_2],1
1159 hidnplayr 751
    call  reserve_ok2
1198 clevermous 752
        mov  [ChannelNumber],2
753
        mov  [DiskNumber],0
754
        mov     [cdpos],3
755
        call GetEvent_StatusNotification
756
        cmp  [CDDataBuf+4],byte 1
757
        je   .eject_ide2
758
        call syscall_cdaudio.free
1159 hidnplayr 759
    jmp  .ide1_1
760
.eject_ide2:
761
    call .eject
1198 clevermous 762
        call syscall_cdaudio.free
1159 hidnplayr 763
    jmp  .ide1_1
764
 
765
.ide1:
766
    cli
767
    cmp  [ATAPI_IDE1_lock],1
768
    jne  .ide0_1
769
    cmp  [IDE_Channel_1],0
770
    jne  .end
771
    cmp  [cd_status],0
772
    jne  .end
1198 clevermous 773
        mov  [IDE_Channel_1],1
1159 hidnplayr 774
    call reserve_ok2
1198 clevermous 775
        mov  [ChannelNumber],1
776
        mov  [DiskNumber],1
777
        mov     [cdpos],2
778
        call GetEvent_StatusNotification
779
        cmp  [CDDataBuf+4],byte 1
780
        je   .eject_ide1
781
        call syscall_cdaudio.free
1159 hidnplayr 782
    jmp  .ide0_1
783
.eject_ide1:
784
    call .eject
1198 clevermous 785
        call syscall_cdaudio.free
1159 hidnplayr 786
    jmp  .ide0_1
787
 
788
.ide0:
789
    cli
790
    cmp  [ATAPI_IDE0_lock],1
791
    jne  .end
792
    cmp  [IDE_Channel_1],0
793
    jne  .end
794
    cmp  [cd_status],0
795
    jne  .end
1198 clevermous 796
        mov  [IDE_Channel_1],1
1159 hidnplayr 797
    call reserve_ok2
1198 clevermous 798
        mov  [ChannelNumber],1
799
        mov  [DiskNumber],0
800
        mov     [cdpos],1
801
        call GetEvent_StatusNotification
802
        cmp  [CDDataBuf+4],byte 1
803
        je   .eject_ide0
804
        call syscall_cdaudio.free
1159 hidnplayr 805
    jmp  .end
806
.eject_ide0:
807
    call .eject
1198 clevermous 808
        call syscall_cdaudio.free
1159 hidnplayr 809
    jmp  .end
810
 
811
.eject:
1198 clevermous 812
        call clear_CD_cache
813
        call allow_medium_removal
814
        mov  [ignore_CD_eject_wait],1
815
        call EjectMedium
816
        mov  [ignore_CD_eject_wait],0
817
        ret
1159 hidnplayr 818
 
819
timer_ATAPI_check dd 0
820
ATAPI_IDE0_lock db 0
821
ATAPI_IDE1_lock db 0
822
ATAPI_IDE2_lock db 0
823
ATAPI_IDE3_lock db 0
824
ignore_CD_eject_wait db 0
825
 
826
;*************************************************
827
;* Получить сообщение о событии или состоянии    *
828
;*                  устройства                   *
829
;* Входные параметры передаются через глобальные *
830
;* переменные:                                   *
831
;* ChannelNumber - номер канала;                 *
832
;* DiskNumber - номер диска на канале.           *
833
;*************************************************
834
GetEvent_StatusNotification:
1198 clevermous 835
        pusha
836
        mov     [CDDataBuf_pointer],CDDataBuf
1159 hidnplayr 837
; Очистить буфер пакетной команды
1198 clevermous 838
        call  clear_packet_buffer
1159 hidnplayr 839
; Задать код команды
1198 clevermous 840
        mov     [PacketCommand],byte 4Ah
841
        mov     [PacketCommand+1],byte 00000001b
1159 hidnplayr 842
; Задать запрос класса сообщений
1198 clevermous 843
        mov     [PacketCommand+4],byte 00010000b
1159 hidnplayr 844
; Размер выделенной области
1198 clevermous 845
        mov     [PacketCommand+7],byte 8h
846
        mov     [PacketCommand+8],byte 0h
1159 hidnplayr 847
; Подать команду
1198 clevermous 848
        call    SendPacketDatCommand
849
        popa
850
        ret
1159 hidnplayr 851
 
852
;*************************************************
853
; прочитать информацию из TOC
854
;* Входные параметры передаются через глобальные *
855
;* переменные:                                   *
856
;* ChannelNumber - номер канала;                 *
857
;* DiskNumber - номер диска на канале.           *
858
;*************************************************
859
Read_TOC:
1198 clevermous 860
        pusha
861
        mov     [CDDataBuf_pointer],CDDataBuf
1159 hidnplayr 862
; Очистить буфер пакетной команды
1198 clevermous 863
        call  clear_packet_buffer
1159 hidnplayr 864
; Сформировать пакетную команду для считывания
865
; сектора данных
1198 clevermous 866
        mov       [PacketCommand],byte 0x43
867
        ; Задать формат
868
        mov       [PacketCommand+2],byte 1
1159 hidnplayr 869
; Размер выделенной области
1198 clevermous 870
        mov     [PacketCommand+7],byte 0xFF
871
        mov     [PacketCommand+8],byte 0h
1159 hidnplayr 872
; Подать команду
1198 clevermous 873
        call  SendPacketDatCommand
874
        popa
875
        ret
1159 hidnplayr 876
 
877
;*************************************************
878
;* ОПРЕДЕЛИТЬ ОБЩЕЕ КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ *
879
;* Входные параметры передаются через глобальные *
880
;* переменные:                                   *
881
;* ChannelNumber - номер канала;                 *
882
;* DiskNumber - номер диска на канале.           *
883
;*************************************************
884
;ReadCapacity:
885
;       pusha
886
;; Очистить буфер пакетной команды
887
;       call  clear_packet_buffer
888
;; Задать размер буфера в байтах
889
;       mov     [CDBlockSize],8
890
;; Сформировать команду READ CAPACITY
891
;       mov     [PacketCommand],word 25h
892
;; Подать команду
893
;       call    SendPacketDatCommand
894
;       popa
895
;       ret
896
 
897
clear_packet_buffer:
898
; Очистить буфер пакетной команды
1198 clevermous 899
        mov     [PacketCommand],dword 0
900
        mov     [PacketCommand+4],dword 0
901
        mov     [PacketCommand+8],dword 0
902
        ret