Subversion Repositories Kolibri OS

Rev

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