Subversion Repositories Kolibri OS

Rev

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