Subversion Repositories Kolibri OS

Rev

Rev 637 | Rev 1168 | 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: 758 $
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
758 mario79 23
 
87 mario79 24
;*************************************************
25
;*      ПОЛНОЕ ЧТЕНИЕ СЕКТОРА КОМПАКТ-ДИСКА      *
26
;* Считываются данные пользователя, информация   *
27
;* субканала и контрольная информация            *
28
;* Входные параметры передаются через глобальные *
29
;* перменные:                                    *
30
;* ChannelNumber - номер канала;                 *
31
;* DiskNumber - номер диска на канале;           *
32
;* CDSectorAddress - адрес считываемого сектора. *
33
;* Данные считывается в массив CDDataBuf.        *
34
;*************************************************
35
ReadCD:
585 mario79 36
	pusha
87 mario79 37
; Задать размер сектора
628 mario79 38
	mov	  [CDBlockSize],2048 ;2352
87 mario79 39
; Очистить буфер пакетной команды
585 mario79 40
	call  clear_packet_buffer
87 mario79 41
; Сформировать пакетную команду для считывания
42
; сектора данных
585 mario79 43
	; Задать код команды Read CD
628 mario79 44
	mov	  [PacketCommand],byte 0x28  ;0xBE
585 mario79 45
	; Задать адрес сектора
628 mario79 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
87 mario79 52
;        mov   eax,[CDSectorAddress]
53
;        mov   [PacketCommand+2],eax
585 mario79 54
	; Задать количество считываемых секторов
628 mario79 55
	mov	  [PacketCommand+8],byte 1
585 mario79 56
	; Задать считывание данных в полном объеме
87 mario79 57
;        mov     [PacketCommand+9],byte 0xF8
58
; Подать команду
628 mario79 59
	call  SendPacketDatCommand
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
628 mario79 100
    cmp   [DevErrorCode],0
101
    jne   .exit
102
 
585 mario79 103
    mov   [CDDataBuf_pointer],ebx
104
    call  cd_calculate_cache_1
105
    lea   esi,[edi*8+esi]
106
    mov   [esi],eax		; sector number
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
118
    rep   movsd 		; move data
628 mario79 119
.exit:
585 mario79 120
    popad
121
    ret
122
 
123
ReadCDWRetr_1:
124
	pushad
125
 
87 mario79 126
; Цикл, пока команда не выполнена успешно или не
127
; исчерпано количество попыток
628 mario79 128
	mov	  ECX,MaxRetr
87 mario79 129
@@NextRetr:
130
; Подать команду
628 mario79 131
	call  ReadCD
132
	cmp	  [DevErrorCode],0
133
	je	  @@End_4
585 mario79 134
 
758 mario79 135
	or    ecx,ecx		;{SPraid.simba} (for cd load)
628 mario79 136
	jz    @@End_4
137
	dec   ecx
585 mario79 138
 
628 mario79 139
	cmp   [timer_ticks_enable],0
140
	jne   @f
141
	mov   eax,NoTickWaitTime
538 spraid 142
.wait:
628 mario79 143
	dec   eax
144
	cmp   eax,0
145
	je    @@NextRetr
146
	jmp	  .wait
538 spraid 147
@@:
87 mario79 148
; Задержка на 2,5 секунды
758 mario79 149
;       mov     EAX,[timer_ticks]
150
;       add     EAX,50  ;250
628 mario79 151
;@@Wait:
758 mario79 152
;       call    change_task
153
;       cmp     EAX,[timer_ticks]
154
;       ja      @@Wait
628 mario79 155
	loop  @@NextRetr
87 mario79 156
@@End_4:
585 mario79 157
	popad
158
	ret
87 mario79 159
 
160
 
161
;   Универсальные процедуры, обеспечивающие выполнение
162
;             пакетных команд в режиме PIO
163
 
164
; Максимально допустимое время ожидания реакции
165
; устройства на пакетную команду (в тиках)
166
MaxCDWaitTime equ 1000 ;200 ;10 секунд
167
 
168
; Область памяти для формирования пакетной команды
585 mario79 169
PacketCommand:	 rb 12	;DB 12 DUP (?)
87 mario79 170
; Область памяти для приема данных от дисковода
171
;CDDataBuf       DB 4096 DUP (0)
172
; Размер принимаемого блока данных в байтах
585 mario79 173
CDBlockSize	DW ?
87 mario79 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:
585 mario79 195
	pushad
628 mario79 196
	mov   [DevErrorCode],0
87 mario79 197
; Задать режим CHS
585 mario79 198
	mov	[ATAAddressMode],0
87 mario79 199
; Послать ATA-команду передачи пакетной команды
585 mario79 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    ;закончить, сохранив код ошибки
87 mario79 211
 
212
; Ожидание готовности дисковода к приему
213
; пакетной команды
585 mario79 214
	mov	DX,[ATABasePortAddr]
215
	add	DX,7	 ;порт 1х7h
216
	mov	ecx,NoTickWaitTime
87 mario79 217
@@WaitDevice0:
585 mario79 218
	cmp	[timer_ticks_enable],0
219
	jne	@f
220
	dec	ecx
221
	cmp	ecx,0
222
	je	@@Err1_1
223
	jmp	.test
538 spraid 224
@@:
585 mario79 225
	call	change_task
226
	; Проверить время выполнения команды
227
	mov	EAX,[timer_ticks]
228
	sub	EAX,[TickCounter_1]
229
	cmp	EAX,BSYWaitTime
230
	ja	@@Err1_1   ;ошибка тайм-аута
231
	; Проверить готовность
538 spraid 232
.test:
585 mario79 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
87 mario79 240
; Послать пакетную команду
585 mario79 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
87 mario79 256
; Ожидание готовности данных
585 mario79 257
	mov	DX,[ATABasePortAddr]
258
	add	DX,7   ;порт 1х7h
259
	mov	ecx,NoTickWaitTime
87 mario79 260
@@WaitDevice1:
585 mario79 261
	cmp	[timer_ticks_enable],0
262
	jne	@f
263
	dec	ecx
264
	cmp	ecx,0
265
	je	@@Err1_1
266
	jmp	.test_1
538 spraid 267
@@:
585 mario79 268
	call	change_task
269
	; Проверить время выполнения команды
270
	mov	EAX,[timer_ticks]
271
	sub	EAX,[TickCounter_1]
272
	cmp	EAX,MaxCDWaitTime
273
	ja	@@Err1_1   ;ошибка тайм-аута
274
	; Проверить готовность
538 spraid 275
.test_1:
585 mario79 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
87 mario79 283
; Принять блок данных от контроллера
585 mario79 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
87 mario79 299
 
300
; Записать код ошибки
301
@@Err1_1:
585 mario79 302
	mov	[DevErrorCode],1
303
	jmp @@End_8
87 mario79 304
@@Err6_temp:
585 mario79 305
	mov	[DevErrorCode],7
306
	jmp @@End_8
87 mario79 307
@@Err6:
585 mario79 308
	mov	[DevErrorCode],6
87 mario79 309
@@End_8:
585 mario79 310
	popad
311
	ret
87 mario79 312
 
313
 
314
 
315
;***********************************************
316
;*  ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
317
;*     НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ    *
318
;* Входные параметры передаются через          *
319
;* глобальные перменные:                       *
320
;* ChannelNumber - номер канала;               *
321
;* DiskNumber - номер диска на канале;         *
322
;* PacketCommand - 12-байтный командный пакет. *
323
;***********************************************
324
SendPacketNoDatCommand:
585 mario79 325
	pushad
628 mario79 326
    mov   [DevErrorCode],0
87 mario79 327
; Задать режим CHS
585 mario79 328
	mov	[ATAAddressMode],0
87 mario79 329
; Послать ATA-команду передачи пакетной команды
585 mario79 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  ;закончить, сохранив код ошибки
87 mario79 339
; Ожидание готовности дисковода к приему
340
; пакетной команды
585 mario79 341
	mov	DX,[ATABasePortAddr]
342
	add	DX,7   ;порт 1х7h
87 mario79 343
@@WaitDevice0_1:
585 mario79 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
87 mario79 358
; Послать пакетную команду
359
;        cli
585 mario79 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
87 mario79 373
;        sti
618 mario79 374
    cmp [ignore_CD_eject_wait],1
628 mario79 375
    je	@@End_9
87 mario79 376
; Ожидание подтверждения приема команды
585 mario79 377
	mov	DX,[ATABasePortAddr]
378
	add	DX,7   ;порт 1х7h
87 mario79 379
@@WaitDevice1_1:
585 mario79 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
87 mario79 395
 
396
; Записать код ошибки
397
@@Err1_3:
585 mario79 398
	mov	[DevErrorCode],1
399
	jmp @@End_9
87 mario79 400
@@Err6_1:
585 mario79 401
	mov	[DevErrorCode],6
87 mario79 402
@@End_9:
585 mario79 403
	popad
404
	ret
87 mario79 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:
585 mario79 426
	pushad
628 mario79 427
    mov   [DevErrorCode],0
87 mario79 428
; Проверить значение кода режима
585 mario79 429
	cmp	[ATAAddressMode],1
430
	ja	@@Err2_4
87 mario79 431
; Проверить корректность номера канала
585 mario79 432
	mov	BX,[ChannelNumber]
433
	cmp	BX,1
434
	jb	@@Err3_4
435
	cmp	BX,2
436
	ja	@@Err3_4
87 mario79 437
; Установить базовый адрес
585 mario79 438
	dec	BX
439
	shl	BX,1
440
	movzx	ebx,bx
441
	mov	AX,[ebx+StandardATABases]
442
	mov	[ATABasePortAddr],AX
87 mario79 443
; Ожидание готовности HDD к приему команды
585 mario79 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
87 mario79 458
@@WaitHDReady_2:
585 mario79 459
	cmp    [timer_ticks_enable],0
460
	jne    @f
461
	dec    ecx
462
	cmp    ecx,0
463
	je     @@Err1_4
464
	jmp    .test
538 spraid 465
@@:
585 mario79 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
	; Прочитать регистр состояния
538 spraid 473
.test:
585 mario79 474
	in	AL,DX
475
	; Проверить состояние сигнала BSY
476
	test	AL,80h
477
	jnz	@@WaitHDReady_2
478
	; Проверить состояние сигнала DRQ
479
	test	AL,08h
480
	jnz	@@WaitHDReady_2
538 spraid 481
 
87 mario79 482
; Загрузить команду в регистры контроллера
585 mario79 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
87 mario79 511
; Послать команду
585 mario79 512
	mov	AL,[ATACommand]
513
	inc	DX	;регистр команд
514
	out	DX,AL
515
	sti
87 mario79 516
; Сбросить признак ошибки
585 mario79 517
	mov	[DevErrorCode],0
518
	jmp @@End_10
87 mario79 519
; Записать код ошибки
520
@@Err1_4:
585 mario79 521
	mov	[DevErrorCode],1
522
	jmp @@End_10
87 mario79 523
@@Err2_4:
585 mario79 524
	mov	[DevErrorCode],2
525
	jmp @@End_10
87 mario79 526
@@Err3_4:
585 mario79 527
	mov	[DevErrorCode],3
528
	jmp @@End_10
87 mario79 529
@@Err4_4:
585 mario79 530
	mov	[DevErrorCode],4
531
	jmp @@End_10
87 mario79 532
@@Err5_4:
585 mario79 533
	mov	[DevErrorCode],5
87 mario79 534
; Завершение работы программы
535
@@End_10:
538 spraid 536
;        sti
585 mario79 537
	popad
538
	ret
539
 
87 mario79 540
;*************************************************
541
;*    ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ    *
542
;* Входные параметры передаются через глобальные *
543
;* перменные:                                    *
544
;* ChannelNumber - номер канала;                 *
545
;* DiskNumber - номер диска на канале.           *
546
;*************************************************
547
WaitUnitReady:
585 mario79 548
	pusha
87 mario79 549
; Запомнить время начала операции
585 mario79 550
	mov	EAX,[timer_ticks]
551
	mov	[WURStartTime],EAX
87 mario79 552
; Очистить буфер пакетной команды
585 mario79 553
	call  clear_packet_buffer
87 mario79 554
; Сформировать команду TEST UNIT READY
585 mario79 555
	mov	[PacketCommand],word 00h
87 mario79 556
; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА
637 mario79 557
	mov	ecx,NoTickWaitTime
87 mario79 558
@@SendCommand:
585 mario79 559
	; Подать команду проверки готовности
560
	call	SendPacketNoDatCommand
637 mario79 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
569
@@:
585 mario79 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
637 mario79 579
.Error:
585 mario79 580
	; Ошибка тайм-аута
581
	mov	[DevErrorCode],1
87 mario79 582
@@End_11:
585 mario79 583
	popa
584
	ret
87 mario79 585
 
586
;*************************************************
585 mario79 587
;*            ЗАПРЕТИТЬ СМЕНУ ДИСКА              *
588
;* Входные параметры передаются через глобальные *
589
;* перменные:                                    *
590
;* ChannelNumber - номер канала;                 *
591
;* DiskNumber - номер диска на канале.           *
592
;*************************************************
593
prevent_medium_removal:
594
	pusha
595
; Очистить буфер пакетной команды
596
	call  clear_packet_buffer
597
; Задать код команды
598
	mov  [PacketCommand],byte 0x1E
599
; Задать код запрета
600
    mov  [PacketCommand+4],byte 11b
601
; Подать команду
602
	call SendPacketNoDatCommand
618 mario79 603
	mov  eax,ATAPI_IDE0_lock
604
	add  eax,[cdpos]
605
	dec  eax
606
	mov  [eax],byte 1
585 mario79 607
	popa
608
	ret
609
 
610
;*************************************************
611
;*            РАЗРЕШИТЬ СМЕНУ ДИСКА              *
612
;* Входные параметры передаются через глобальные *
613
;* перменные:                                    *
614
;* ChannelNumber - номер канала;                 *
615
;* DiskNumber - номер диска на канале.           *
618 mario79 616
;*************************************************
585 mario79 617
allow_medium_removal:
618
	pusha
619
; Очистить буфер пакетной команды
620
	call  clear_packet_buffer
621
; Задать код команды
622
	mov  [PacketCommand],byte 0x1E
623
; Задать код запрета
624
    mov  [PacketCommand+4],byte 00b
625
; Подать команду
626
	call SendPacketNoDatCommand
618 mario79 627
	mov  eax,ATAPI_IDE0_lock
628
	add  eax,[cdpos]
629
	dec  eax
630
	mov  [eax],byte 0
585 mario79 631
	popa
632
	ret
633
 
634
;*************************************************
87 mario79 635
;*         ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД         *
636
;* Входные параметры передаются через глобальные *
637
;* перменные:                                    *
638
;* ChannelNumber - номер канала;                 *
639
;* DiskNumber - номер диска на канале.           *
640
;*************************************************
641
LoadMedium:
585 mario79 642
	pusha
87 mario79 643
; Очистить буфер пакетной команды
585 mario79 644
	call  clear_packet_buffer
87 mario79 645
; Сформировать команду START/STOP UNIT
585 mario79 646
	; Задать код команды
647
	mov	[PacketCommand],word 1Bh
648
	; Задать операцию загрузки носителя
649
	mov	[PacketCommand+4],word 00000011b
87 mario79 650
; Подать команду
585 mario79 651
	call	SendPacketNoDatCommand
652
	popa
653
	ret
87 mario79 654
 
655
;*************************************************
656
;*         ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА         *
657
;* Входные параметры передаются через глобальные *
658
;* перменные:                                    *
659
;* ChannelNumber - номер канала;                 *
660
;* DiskNumber - номер диска на канале.           *
661
;*************************************************
585 mario79 662
EjectMedium:
663
	pusha
87 mario79 664
; Очистить буфер пакетной команды
585 mario79 665
	call  clear_packet_buffer
87 mario79 666
; Сформировать команду START/STOP UNIT
585 mario79 667
	; Задать код команды
668
	mov	[PacketCommand],word 1Bh
669
	; Задать операцию извлечения носителя
670
	mov	[PacketCommand+4],word 00000010b
87 mario79 671
; Подать команду
585 mario79 672
	call	SendPacketNoDatCommand
673
	popa
674
	ret
87 mario79 675
 
676
;*************************************************
618 mario79 677
;* Проверить событие нажатия кнопки извлечения   *
678
;*                     диска                     *
87 mario79 679
;* Входные параметры передаются через глобальные *
680
;* переменные:                                   *
681
;* ChannelNumber - номер канала;                 *
682
;* DiskNumber - номер диска на канале.           *
683
;*************************************************
618 mario79 684
check_ATAPI_device_event:
585 mario79 685
	pusha
618 mario79 686
    mov  eax,[timer_ticks]
687
    sub  eax,[timer_ATAPI_check]
688
    cmp  eax,100
689
    jb	 .end_1
690
    mov  al,[DRIVE_DATA+1]
691
    and al,11b
692
    cmp al,10b
693
    jz	.ide3
694
.ide2_1:
695
    mov  al,[DRIVE_DATA+1]
696
    and al,1100b
697
    cmp al,1000b
698
    jz	.ide2
699
.ide1_1:
700
    mov  al,[DRIVE_DATA+1]
701
    and al,110000b
702
    cmp al,100000b
703
    jz	.ide1
704
.ide0_1:
705
    mov  al,[DRIVE_DATA+1]
706
    and al,11000000b
707
    cmp al,10000000b
708
    jz	.ide0
709
.end:
710
 
711
    sti
712
    mov  eax,[timer_ticks]
713
    mov  [timer_ATAPI_check],eax
714
.end_1:
715
	popa
716
	ret
717
 
718
.ide3:
719
    cli
720
    cmp  [ATAPI_IDE3_lock],1
721
    jne  .ide2_1
722
    cmp  [IDE_Channel_2],0
723
    jne  .ide1_1
724
    cmp  [cd_status],0
725
    jne  .end
726
	mov  [IDE_Channel_2],1
727
    call reserve_ok2
728
	mov  [ChannelNumber],2
729
	mov  [DiskNumber],1
730
	mov	 [cdpos],4
731
	call GetEvent_StatusNotification
732
	cmp  [CDDataBuf+4],byte 1
733
	je   .eject_ide3
734
	call syscall_cdaudio.free
735
    jmp  .ide2_1
736
.eject_ide3:
737
    call .eject
738
	call syscall_cdaudio.free
739
    jmp  .ide2_1
740
 
741
.ide2:
742
    cli
743
    cmp  [ATAPI_IDE2_lock],1
744
    jne  .ide1_1
745
    cmp  [IDE_Channel_2],0
746
    jne  .ide1_1
747
    cmp  [cd_status],0
748
    jne  .end
749
	mov  [IDE_Channel_2],1
750
    call  reserve_ok2
751
	mov  [ChannelNumber],2
752
	mov  [DiskNumber],0
753
	mov	[cdpos],3
754
	call GetEvent_StatusNotification
755
	cmp  [CDDataBuf+4],byte 1
756
	je   .eject_ide2
757
	call syscall_cdaudio.free
758
    jmp  .ide1_1
759
.eject_ide2:
760
    call .eject
761
	call syscall_cdaudio.free
762
    jmp  .ide1_1
763
 
764
.ide1:
765
    cli
766
    cmp  [ATAPI_IDE1_lock],1
767
    jne  .ide0_1
768
    cmp  [IDE_Channel_1],0
769
    jne  .end
770
    cmp  [cd_status],0
771
    jne  .end
772
	mov  [IDE_Channel_1],1
773
    call reserve_ok2
774
	mov  [ChannelNumber],1
775
	mov  [DiskNumber],1
776
	mov	[cdpos],2
777
	call GetEvent_StatusNotification
778
	cmp  [CDDataBuf+4],byte 1
779
	je   .eject_ide1
780
	call syscall_cdaudio.free
781
    jmp  .ide0_1
782
.eject_ide1:
783
    call .eject
784
	call syscall_cdaudio.free
785
    jmp  .ide0_1
786
 
787
.ide0:
788
    cli
789
    cmp  [ATAPI_IDE0_lock],1
790
    jne  .end
791
    cmp  [IDE_Channel_1],0
792
    jne  .end
793
    cmp  [cd_status],0
794
    jne  .end
795
	mov  [IDE_Channel_1],1
796
    call reserve_ok2
797
	mov  [ChannelNumber],1
798
	mov  [DiskNumber],0
799
	mov	[cdpos],1
800
	call GetEvent_StatusNotification
801
	cmp  [CDDataBuf+4],byte 1
802
	je   .eject_ide0
803
	call syscall_cdaudio.free
804
    jmp  .end
805
.eject_ide0:
806
    call .eject
807
	call syscall_cdaudio.free
808
    jmp  .end
809
 
810
.eject:
811
	call clear_CD_cache
812
	call allow_medium_removal
813
	mov  [ignore_CD_eject_wait],1
814
	call EjectMedium
815
	mov  [ignore_CD_eject_wait],0
816
	ret
817
 
818
timer_ATAPI_check dd 0
819
ATAPI_IDE0_lock db 0
820
ATAPI_IDE1_lock db 0
821
ATAPI_IDE2_lock db 0
822
ATAPI_IDE3_lock db 0
823
ignore_CD_eject_wait db 0
824
 
825
;*************************************************
826
;* Получить сообщение о событии или состоянии    *
827
;*                  устройства                   *
828
;* Входные параметры передаются через глобальные *
829
;* переменные:                                   *
830
;* ChannelNumber - номер канала;                 *
831
;* DiskNumber - номер диска на канале.           *
832
;*************************************************
833
GetEvent_StatusNotification:
834
	pusha
628 mario79 835
	mov	[CDDataBuf_pointer],CDDataBuf
87 mario79 836
; Очистить буфер пакетной команды
585 mario79 837
	call  clear_packet_buffer
618 mario79 838
; Задать код команды
628 mario79 839
	mov	[PacketCommand],byte 4Ah
618 mario79 840
	mov	[PacketCommand+1],byte 00000001b
841
; Задать запрос класса сообщений
842
	mov	[PacketCommand+4],byte 00010000b
628 mario79 843
; Размер выделенной области
844
	mov	[PacketCommand+7],byte 8h
845
	mov	[PacketCommand+8],byte 0h
87 mario79 846
; Подать команду
585 mario79 847
	call	SendPacketDatCommand
848
	popa
849
	ret
87 mario79 850
 
618 mario79 851
;*************************************************
758 mario79 852
; прочитать информацию из TOC
853
;* Входные параметры передаются через глобальные *
854
;* переменные:                                   *
855
;* ChannelNumber - номер канала;                 *
856
;* DiskNumber - номер диска на канале.           *
857
;*************************************************
858
Read_TOC:
859
	pusha
860
	mov	[CDDataBuf_pointer],CDDataBuf
861
; Очистить буфер пакетной команды
862
	call  clear_packet_buffer
863
; Сформировать пакетную команду для считывания
864
; сектора данных
865
	mov	  [PacketCommand],byte 0x43
866
	; Задать формат
867
	mov	  [PacketCommand+2],byte 1
868
; Размер выделенной области
869
	mov	[PacketCommand+7],byte 0xFF
870
	mov	[PacketCommand+8],byte 0h
871
; Подать команду
872
	call  SendPacketDatCommand
873
	popa
874
	ret
875
 
876
;*************************************************
618 mario79 877
;* ОПРЕДЕЛИТЬ ОБЩЕЕ КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ *
878
;* Входные параметры передаются через глобальные *
879
;* переменные:                                   *
880
;* ChannelNumber - номер канала;                 *
881
;* DiskNumber - номер диска на канале.           *
882
;*************************************************
883
;ReadCapacity:
628 mario79 884
;       pusha
618 mario79 885
;; Очистить буфер пакетной команды
628 mario79 886
;       call  clear_packet_buffer
618 mario79 887
;; Задать размер буфера в байтах
628 mario79 888
;       mov     [CDBlockSize],8
618 mario79 889
;; Сформировать команду READ CAPACITY
628 mario79 890
;       mov     [PacketCommand],word 25h
618 mario79 891
;; Подать команду
628 mario79 892
;       call    SendPacketDatCommand
893
;       popa
894
;       ret
618 mario79 895
 
585 mario79 896
clear_packet_buffer:
87 mario79 897
; Очистить буфер пакетной команды
585 mario79 898
	mov	[PacketCommand],dword 0
899
	mov	[PacketCommand+4],dword 0
900
	mov	[PacketCommand+8],dword 0
901
	ret