Subversion Repositories Kolibri OS

Rev

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