Subversion Repositories Kolibri OS

Rev

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

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