Subversion Repositories Kolibri OS

Rev

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

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