7,7 → 7,7 |
|
$Revision$ |
|
|
;----------------------------------------------------------------------------- |
;********************************************************** |
; Непосредственная работа с устройством СD (ATAPI) |
;********************************************************** |
37,16 → 37,17 |
xor edi, edi |
add esi, 8 |
inc edi |
;-------------------------------------- |
align 4 |
.hdreadcache: |
; cmp dword [esi+4],0 ; empty |
; je .nohdcache |
cmp [esi], eax ; correct sector |
je .yeshdcache |
.nohdcache: |
|
add esi, 8 |
inc edi |
dec ecx |
jnz .hdreadcache |
|
call find_empty_slot_CD_cache ; ret in edi |
|
push edi |
66,7 → 67,7 |
call cd_calculate_cache_1 |
lea esi, [edi*8+esi] |
mov [esi], eax ; sector number |
; mov dword [esi+4],1 ; hd read - mark as same as in hd |
;-------------------------------------- |
.yeshdcache: |
mov esi, edi |
shl esi, 11;9 |
78,16 → 79,18 |
mov ecx, 512;/4 |
cld |
rep movsd ; move data |
;-------------------------------------- |
.exit: |
popad |
ret |
|
;----------------------------------------------------------------------------- |
ReadCDWRetr_1: |
pushad |
|
; Цикл, пока команда не выполнена успешно или не |
; исчерпано количество попыток |
mov ECX, MaxRetr |
mov ecx, MaxRetr |
;-------------------------------------- |
align 4 |
@@NextRetr: |
; Подать команду |
;************************************************* |
103,9 → 106,6 |
;************************************************* |
;ReadCD: |
push ecx |
; pusha |
; Задать размер сектора |
; mov [CDBlockSize],2048 ;2352 |
; Очистить буфер пакетной команды |
call clear_packet_buffer |
; Сформировать пакетную команду для считывания |
113,79 → 113,67 |
; Задать код команды Read CD |
mov [PacketCommand], byte 0x28;0xBE |
; Задать адрес сектора |
mov AX, word [CDSectorAddress+2] |
xchg AL, AH |
mov word [PacketCommand+2], AX |
mov AX, word [CDSectorAddress] |
xchg AL, AH |
mov word [PacketCommand+4], AX |
; mov eax,[CDSectorAddress] |
; mov [PacketCommand+2],eax |
mov ax, word [CDSectorAddress+2] |
xchg al, ah |
mov word [PacketCommand+2], ax |
mov ax, word [CDSectorAddress] |
xchg al, ah |
mov word [PacketCommand+4], ax |
; Задать количество считываемых секторов |
mov [PacketCommand+8], byte 1 |
; Задать считывание данных в полном объеме |
; mov [PacketCommand+9],byte 0xF8 |
; Подать команду |
call SendPacketDatCommand |
pop ecx |
; ret |
|
; cmp [DevErrorCode],0 |
test eax, eax |
jz @@End_4 |
|
or ecx, ecx ;{SPraid.simba} (for cd load) |
jz @@End_4 |
|
dec ecx |
|
cmp [timer_ticks_enable], 0 |
jne @f |
|
mov eax, NoTickWaitTime |
;-------------------------------------- |
align 4 |
.wait: |
dec eax |
; test eax,eax |
jz @@NextRetr |
|
jmp .wait |
;-------------------------------------- |
align 4 |
@@: |
; Задержка на 2,5 секунды |
; mov EAX,[timer_ticks] |
; add EAX,50 ;250 |
;@@Wait: |
; call change_task |
; cmp EAX,[timer_ticks] |
; ja @@Wait |
loop @@NextRetr |
;-------------------------------------- |
@@End_4: |
mov dword [DevErrorCode], eax |
popad |
ret |
|
|
;----------------------------------------------------------------------------- |
; Универсальные процедуры, обеспечивающие выполнение |
; пакетных команд в режиме PIO |
|
; Максимально допустимое время ожидания реакции |
; устройства на пакетную команду (в тиках) |
|
;----------------------------------------------------------------------------- |
MaxCDWaitTime equ 1000 ;200 ;10 секунд |
uglobal |
; Область памяти для формирования пакетной команды |
PacketCommand: |
rb 12 ;DB 12 DUP (?) |
; Область памяти для приема данных от дисковода |
;CDDataBuf DB 4096 DUP (0) |
; Размер принимаемого блока данных в байтах |
;CDBlockSize DW ? |
; Адрес считываемого сектора данных |
CDSectorAddress: |
DD ? |
CDSectorAddress: dd ? |
; Время начала очередной операции с диском |
TickCounter_1 DD 0 |
TickCounter_1 dd 0 |
; Время начала ожидания готовности устройства |
WURStartTime DD 0 |
WURStartTime dd 0 |
; указатель буфера для считывания |
CDDataBuf_pointer dd 0 |
endg |
;----------------------------------------------------------------------------- |
;**************************************************** |
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, * |
;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ * |
200,7 → 188,6 |
;**************************************************** |
SendPacketDatCommand: |
xor eax, eax |
; mov byte [DevErrorCode],al |
; Задать режим CHS |
mov byte [ATAAddressMode], al |
; Послать ATA-команду передачи пакетной команды |
209,125 → 196,134 |
mov byte [ATASectorNumber], al |
; Загрузить размер передаваемого блока |
mov [ATAHead], al |
; mov AX,[CDBlockSize] |
mov [ATACylinder], CDBlockSize |
mov [ATACommand], 0A0h |
mov [ATACommand], 0xA0 |
call SendCommandToHDD_1 |
test eax, eax |
; cmp [DevErrorCode],0 ;проверить код ошибки |
jnz @@End_8 ;закончить, сохранив код ошибки |
|
; Ожидание готовности дисковода к приему |
; пакетной команды |
mov DX, [ATABasePortAddr] |
add DX, 7 ;порт 1х7h |
mov dx, [ATABasePortAddr] |
add dx, 7 ;порт 1х7h |
mov ecx, NoTickWaitTime |
;-------------------------------------- |
align 4 |
@@WaitDevice0: |
cmp [timer_ticks_enable], 0 |
jne @f |
|
dec ecx |
; test ecx,ecx |
jz @@Err1_1 |
|
jmp .test |
;-------------------------------------- |
align 4 |
@@: |
call change_task |
; Проверить время выполнения команды |
mov EAX, [timer_ticks] |
sub EAX, [TickCounter_1] |
cmp EAX, BSYWaitTime |
mov eax, [timer_ticks] |
sub eax, [TickCounter_1] |
cmp eax, BSYWaitTime |
ja @@Err1_1 ;ошибка тайм-аута |
; Проверить готовность |
;-------------------------------------- |
align 4 |
.test: |
in AL, DX |
test AL, 80h ;состояние сигнала BSY |
in al, dx |
test al, 0x80 ;состояние сигнала BSY |
jnz @@WaitDevice0 |
test AL, 1 ;состояние сигнала ERR |
|
test al, 1 ;состояние сигнала ERR |
jnz @@Err6 |
test AL, 08h ;состояние сигнала DRQ |
|
test al, 0x8 ;состояние сигнала DRQ |
jz @@WaitDevice0 |
; Послать пакетную команду |
cli |
mov DX, [ATABasePortAddr] |
mov AX, [PacketCommand] |
out DX, AX |
mov AX, [PacketCommand+2] |
out DX, AX |
mov AX, [PacketCommand+4] |
out DX, AX |
mov AX, [PacketCommand+6] |
out DX, AX |
mov AX, [PacketCommand+8] |
out DX, AX |
mov AX, [PacketCommand+10] |
out DX, AX |
mov dx, [ATABasePortAddr] |
mov ax, [PacketCommand] |
out dx, ax |
mov ax, [PacketCommand+2] |
out dx, ax |
mov ax, [PacketCommand+4] |
out dx, ax |
mov ax, [PacketCommand+6] |
out dx, ax |
mov ax, [PacketCommand+8] |
out dx, ax |
mov ax, [PacketCommand+10] |
out dx, ax |
sti |
; Ожидание готовности данных |
mov DX, [ATABasePortAddr] |
add DX, 7 ;порт 1х7h |
mov dx, [ATABasePortAddr] |
add dx, 7 ;порт 1х7h |
mov ecx, NoTickWaitTime |
;-------------------------------------- |
align 4 |
@@WaitDevice1: |
cmp [timer_ticks_enable], 0 |
jne @f |
|
dec ecx |
; test ecx,ecx |
jz @@Err1_1 |
|
jmp .test_1 |
;-------------------------------------- |
align 4 |
@@: |
call change_task |
; Проверить время выполнения команды |
mov EAX, [timer_ticks] |
sub EAX, [TickCounter_1] |
cmp EAX, MaxCDWaitTime |
mov eax, [timer_ticks] |
sub eax, [TickCounter_1] |
cmp eax, MaxCDWaitTime |
ja @@Err1_1 ;ошибка тайм-аута |
; Проверить готовность |
;-------------------------------------- |
align 4 |
.test_1: |
in AL, DX |
test AL, 80h ;состояние сигнала BSY |
in al, dx |
test al, 0x80 ;состояние сигнала BSY |
jnz @@WaitDevice1 |
test AL, 1 ;состояние сигнала ERR |
|
test al, 1 ;состояние сигнала ERR |
jnz @@Err6_temp |
test AL, 08h ;состояние сигнала DRQ |
|
test al, 0x8 ;состояние сигнала DRQ |
jz @@WaitDevice1 |
; Принять блок данных от контроллера |
mov EDI, [CDDataBuf_pointer];0x7000 ;CDDataBuf |
mov edi, [CDDataBuf_pointer] |
; Загрузить адрес регистра данных контроллера |
mov DX, [ATABasePortAddr];порт 1x0h |
mov dx, [ATABasePortAddr] |
; Загрузить в счетчик размер блока в байтах |
xor ecx, ecx |
mov CX, CDBlockSize |
mov cx, CDBlockSize |
; Вычислить размер блока в 16-разрядных словах |
shr CX, 1;разделить размер блока на 2 |
shr cx, 1 ;разделить размер блока на 2 |
; Принять блок данных |
cli |
cld |
rep insw |
sti |
;-------------------------------------- |
; Успешное завершение приема данных |
@@End_8: |
xor eax, eax |
ret |
|
;-------------------------------------- |
; Записать код ошибки |
@@Err1_1: |
xor eax, eax |
inc eax |
ret |
; mov [DevErrorCode],1 |
; ret |
;-------------------------------------- |
@@Err6_temp: |
mov eax, 7 |
ret |
; mov [DevErrorCode],7 |
; ret |
;-------------------------------------- |
@@Err6: |
mov eax, 6 |
ret |
; mov [DevErrorCode],6 |
;@@End_8: |
; ret |
|
|
|
;----------------------------------------------------------------------------- |
;*********************************************** |
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, * |
;* НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ * |
340,7 → 336,6 |
SendPacketNoDatCommand: |
pushad |
xor eax, eax |
; mov byte [DevErrorCode],al |
; Задать режим CHS |
mov byte [ATAAddressMode], al |
; Послать ATA-команду передачи пакетной команды |
349,82 → 344,93 |
mov byte [ATASectorNumber], al |
mov word [ATACylinder], ax |
mov byte [ATAHead], al |
mov [ATACommand], 0A0h |
mov [ATACommand], 0xA0 |
call SendCommandToHDD_1 |
; cmp [DevErrorCode],0 ;проверить код ошибки |
test eax, eax |
jnz @@End_9 ;закончить, сохранив код ошибки |
; Ожидание готовности дисковода к приему |
; пакетной команды |
mov DX, [ATABasePortAddr] |
add DX, 7 ;порт 1х7h |
mov dx, [ATABasePortAddr] |
add dx, 7 ;порт 1х7h |
;-------------------------------------- |
align 4 |
@@WaitDevice0_1: |
call change_task |
; Проверить время ожидания |
mov EAX, [timer_ticks] |
sub EAX, [TickCounter_1] |
cmp EAX, BSYWaitTime |
mov eax, [timer_ticks] |
sub eax, [TickCounter_1] |
cmp eax, BSYWaitTime |
ja @@Err1_3 ;ошибка тайм-аута |
; Проверить готовность |
in AL, DX |
test AL, 80h ;состояние сигнала BSY |
in al, dx |
test al, 0x80 ;состояние сигнала BSY |
jnz @@WaitDevice0_1 |
test AL, 1 ;состояние сигнала ERR |
|
test al, 1 ;состояние сигнала ERR |
jnz @@Err6_1 |
test AL, 08h ;состояние сигнала DRQ |
|
test al, 0x8 ;состояние сигнала DRQ |
jz @@WaitDevice0_1 |
; Послать пакетную команду |
; cli |
mov DX, [ATABasePortAddr] |
mov AX, word [PacketCommand] |
out DX, AX |
mov AX, word [PacketCommand+2] |
out DX, AX |
mov AX, word [PacketCommand+4] |
out DX, AX |
mov AX, word [PacketCommand+6] |
out DX, AX |
mov AX, word [PacketCommand+8] |
out DX, AX |
mov AX, word [PacketCommand+10] |
out DX, AX |
mov dx, [ATABasePortAddr] |
mov ax, word [PacketCommand] |
out dx, ax |
mov ax, word [PacketCommand+2] |
out dx, ax |
mov ax, word [PacketCommand+4] |
out dx, ax |
mov ax, word [PacketCommand+6] |
out dx, ax |
mov ax, word [PacketCommand+8] |
out dx, ax |
mov ax, word [PacketCommand+10] |
out dx, ax |
; sti |
cmp [ignore_CD_eject_wait], 1 |
je @@clear_DEC |
; Ожидание подтверждения приема команды |
mov DX, [ATABasePortAddr] |
add DX, 7 ;порт 1х7h |
mov dx, [ATABasePortAddr] |
add dx, 7 ;порт 1х7h |
;-------------------------------------- |
align 4 |
@@WaitDevice1_1: |
call change_task |
; Проверить время выполнения команды |
mov EAX, [timer_ticks] |
sub EAX, [TickCounter_1] |
cmp EAX, MaxCDWaitTime |
mov eax, [timer_ticks] |
sub eax, [TickCounter_1] |
cmp eax, MaxCDWaitTime |
ja @@Err1_3 ;ошибка тайм-аута |
; Ожидать освобождения устройства |
in AL, DX |
test AL, 80h ;состояние сигнала BSY |
in al, dx |
test al, 0x80 ;состояние сигнала BSY |
jnz @@WaitDevice1_1 |
test AL, 1 ;состояние сигнала ERR |
|
test al, 1 ;состояние сигнала ERR |
jnz @@Err6_1 |
test AL, 40h ;состояние сигнала DRDY |
|
test al, 0x40 ;состояние сигнала DRDY |
jz @@WaitDevice1_1 |
;-------------------------------------- |
@@clear_DEC: |
and [DevErrorCode], 0 |
popad |
ret |
;-------------------------------------- |
; Записать код ошибки |
@@Err1_3: |
xor eax, eax |
inc eax |
jmp @@End_9 |
;-------------------------------------- |
@@Err6_1: |
mov eax, 6 |
;-------------------------------------- |
@@End_9: |
mov [DevErrorCode], eax |
popad |
ret |
|
;----------------------------------------------------------------------------- |
;**************************************************** |
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ * |
;* Входные параметры передаются через глобальные * |
445,45 → 451,56 |
;* возвращен код ошибки в eax * |
;**************************************************** |
SendCommandToHDD_1: |
; pushad |
; mov [DevErrorCode],0 not need |
; Проверить значение кода режима |
cmp [ATAAddressMode], 1 |
ja @@Err2_4 |
; Проверить корректность номера канала |
mov BX, [ChannelNumber] |
cmp BX, 1 |
mov bx, [ChannelNumber] |
cmp bx, 1 |
jb @@Err3_4 |
cmp BX, 2 |
|
cmp bx, 2 |
ja @@Err3_4 |
; Установить базовый адрес |
dec BX |
shl BX, 1 |
dec bx |
shl ebx, 2 |
movzx ebx, bx |
mov AX, [ebx+StandardATABases] |
mov [ATABasePortAddr], AX |
mov eax, [cdpos] |
dec eax |
shr eax, 2 |
imul eax, sizeof.IDE_DATA |
add eax, IDE_controller_1 |
add eax, ebx |
mov ax, [eax+IDE_DATA.BAR0_val] |
mov [ATABasePortAddr], ax |
; Ожидание готовности HDD к приему команды |
; Выбрать нужный диск |
mov DX, [ATABasePortAddr] |
add DX, 6 ;адрес регистра головок |
mov AL, [DiskNumber] |
cmp AL, 1 ;проверить номера диска |
mov dx, [ATABasePortAddr] |
add dx, 6 ;адрес регистра головок |
mov al, [DiskNumber] |
cmp al, 1 ;проверить номера диска |
ja @@Err4_4 |
shl AL, 4 |
or AL, 10100000b |
out DX, AL |
|
shl al, 4 |
or al, 10100000b |
out dx, al |
; Ожидать, пока диск не будет готов |
inc DX |
inc dx |
mov eax, [timer_ticks] |
mov [TickCounter_1], eax |
mov ecx, NoTickWaitTime |
;-------------------------------------- |
align 4 |
@@WaitHDReady_2: |
cmp [timer_ticks_enable], 0 |
jne @f |
|
dec ecx |
; test ecx,ecx |
jz @@Err1_4 |
|
jmp .test |
;-------------------------------------- |
align 4 |
@@: |
call change_task |
; Проверить время ожидания |
491,81 → 508,78 |
sub eax, [TickCounter_1] |
cmp eax, BSYWaitTime;300 ;ожидать 3 сек. |
ja @@Err1_4 ;ошибка тайм-аута |
; Прочитать регистр состояния |
;-------------------------------------- |
align 4 |
.test: |
in AL, DX |
in al, dx ; Прочитать регистр состояния |
; Проверить состояние сигнала BSY |
test AL, 80h |
test al, 0x80 |
jnz @@WaitHDReady_2 |
; Проверить состояние сигнала DRQ |
test AL, 08h |
test al, 0x8 |
jnz @@WaitHDReady_2 |
|
; Загрузить команду в регистры контроллера |
cli |
mov DX, [ATABasePortAddr] |
inc DX ;регистр "особенностей" |
mov AL, [ATAFeatures] |
out DX, AL |
inc DX ;счетчик секторов |
mov AL, [ATASectorCount] |
out DX, AL |
inc DX ;регистр номера сектора |
mov AL, [ATASectorNumber] |
out DX, AL |
inc DX ;номер цилиндра (младший байт) |
mov AX, [ATACylinder] |
out DX, AL |
inc DX ;номер цилиндра (старший байт) |
mov AL, AH |
out DX, AL |
inc DX ;номер головки/номер диска |
mov AL, [DiskNumber] |
shl AL, 4 |
cmp [ATAHead], 0Fh;проверить номер головки |
mov dx, [ATABasePortAddr] |
inc dx ;регистр "особенностей" |
mov al, [ATAFeatures] |
out dx, al |
inc dx ;счетчик секторов |
mov al, [ATASectorCount] |
out dx, al |
inc dx ;регистр номера сектора |
mov al, [ATASectorNumber] |
out dx, al |
inc dx ;номер цилиндра (младший байт) |
mov ax, [ATACylinder] |
out dx, al |
inc dx ;номер цилиндра (старший байт) |
mov al, ah |
out dx, al |
inc dx ;номер головки/номер диска |
mov al, [DiskNumber] |
shl al, 4 |
cmp [ATAHead], 0xF ;проверить номер головки |
ja @@Err5_4 |
or AL, [ATAHead] |
or AL, 10100000b |
mov AH, [ATAAddressMode] |
shl AH, 6 |
or AL, AH |
out DX, AL |
|
or al, [ATAHead] |
or al, 10100000b |
mov ah, [ATAAddressMode] |
shl ah, 6 |
or al, ah |
out dx, al |
; Послать команду |
mov AL, [ATACommand] |
inc DX ;регистр команд |
out DX, AL |
mov al, [ATACommand] |
inc dx ;регистр команд |
out dx, al |
sti |
; Сбросить признак ошибки |
; mov [DevErrorCode],0 |
;-------------------------------------- |
@@End_10: |
xor eax, eax |
ret |
;-------------------------------------- |
; Записать код ошибки |
@@Err1_4: |
xor eax, eax |
inc eax |
; mov [DevErrorCode],1 |
ret |
;-------------------------------------- |
@@Err2_4: |
mov eax, 2 |
; mov [DevErrorCode],2 |
ret |
;-------------------------------------- |
@@Err3_4: |
mov eax, 3 |
; mov [DevErrorCode],3 |
ret |
;-------------------------------------- |
@@Err4_4: |
mov eax, 4 |
; mov [DevErrorCode],4 |
ret |
;-------------------------------------- |
@@Err5_4: |
mov eax, 5 |
; mov [DevErrorCode],5 |
; Завершение работы программы |
ret |
; sti |
; popad |
|
;----------------------------------------------------------------------------- |
;************************************************* |
;* ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ * |
;* Входные параметры передаются через глобальные * |
576,25 → 590,31 |
WaitUnitReady: |
pusha |
; Запомнить время начала операции |
mov EAX, [timer_ticks] |
mov [WURStartTime], EAX |
mov eax, [timer_ticks] |
mov [WURStartTime], eax |
; Очистить буфер пакетной команды |
call clear_packet_buffer |
; Сформировать команду TEST UNIT READY |
mov [PacketCommand], word 00h |
mov [PacketCommand], word 0 |
; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА |
mov ecx, NoTickWaitTime |
;-------------------------------------- |
align 4 |
@@SendCommand: |
; Подать команду проверки готовности |
call SendPacketNoDatCommand |
cmp [timer_ticks_enable], 0 |
jne @f |
|
cmp [DevErrorCode], 0 |
je @@End_11 |
|
dec ecx |
; cmp ecx,0 |
jz .Error |
|
jmp @@SendCommand |
;-------------------------------------- |
align 4 |
@@: |
call change_task |
; Проверить код ошибки |
601,17 → 621,19 |
cmp [DevErrorCode], 0 |
je @@End_11 |
; Проверить время ожидания готовности |
mov EAX, [timer_ticks] |
sub EAX, [WURStartTime] |
cmp EAX, MaxCDWaitTime |
mov eax, [timer_ticks] |
sub eax, [WURStartTime] |
cmp eax, MaxCDWaitTime |
jb @@SendCommand |
;-------------------------------------- |
.Error: |
; Ошибка тайм-аута |
mov [DevErrorCode], 1 |
;-------------------------------------- |
@@End_11: |
popa |
ret |
|
;----------------------------------------------------------------------------- |
;************************************************* |
;* ЗАПРЕТИТЬ СМЕНУ ДИСКА * |
;* Входные параметры передаются через глобальные * |
635,7 → 657,7 |
mov [eax], byte 1 |
popa |
ret |
|
;----------------------------------------------------------------------------- |
;************************************************* |
;* РАЗРЕШИТЬ СМЕНУ ДИСКА * |
;* Входные параметры передаются через глобальные * |
650,7 → 672,7 |
; Задать код команды |
mov [PacketCommand], byte 0x1E |
; Задать код запрета |
mov [PacketCommand+4], byte 00b |
mov [PacketCommand+4], byte 0 |
; Подать команду |
call SendPacketNoDatCommand |
mov eax, ATAPI_IDE0_lock |
659,7 → 681,7 |
mov [eax], byte 0 |
popa |
ret |
|
;----------------------------------------------------------------------------- |
;************************************************* |
;* ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД * |
;* Входные параметры передаются через глобальные * |
673,7 → 695,7 |
call clear_packet_buffer |
; Сформировать команду START/STOP UNIT |
; Задать код команды |
mov [PacketCommand], word 1Bh |
mov [PacketCommand], word 0x1B |
; Задать операцию загрузки носителя |
mov [PacketCommand+4], word 00000011b |
; Подать команду |
680,7 → 702,7 |
call SendPacketNoDatCommand |
popa |
ret |
|
;----------------------------------------------------------------------------- |
;************************************************* |
;* ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА * |
;* Входные параметры передаются через глобальные * |
694,7 → 716,7 |
call clear_packet_buffer |
; Сформировать команду START/STOP UNIT |
; Задать код команды |
mov [PacketCommand], word 1Bh |
mov [PacketCommand], word 0x1B |
; Задать операцию извлечения носителя |
mov [PacketCommand+4], word 00000010b |
; Подать команду |
701,7 → 723,7 |
call SendPacketNoDatCommand |
popa |
ret |
|
;----------------------------------------------------------------------------- |
;************************************************* |
;* Проверить событие нажатия кнопки извлечения * |
;* диска * |
715,15 → 737,16 |
sub eax, [timer_ATAPI_check] |
cmp eax, 100 |
jb .no |
.yes: |
|
xor eax, eax |
inc eax |
ret |
;-------------------------------------- |
.no: |
xor eax, eax |
ret |
endp |
|
;----------------------------------------------------------------------------- |
align 4 |
check_ATAPI_device_event: |
pusha |
731,43 → 754,96 |
sub eax, [timer_ATAPI_check] |
cmp eax, 100 |
jb .end_1 |
|
pushfd |
mov al, [DRIVE_DATA+1] |
and al, 11b |
cmp al, 10b |
jz .ide3 |
;-------------------------------------- |
.ide2_1: |
mov al, [DRIVE_DATA+1] |
and al, 1100b |
cmp al, 1000b |
jz .ide2 |
;-------------------------------------- |
.ide1_1: |
mov al, [DRIVE_DATA+1] |
and al, 110000b |
cmp al, 100000b |
jz .ide1 |
;-------------------------------------- |
.ide0_1: |
mov al, [DRIVE_DATA+1] |
and al, 11000000b |
cmp al, 10000000b |
jz .ide0 |
;-------------------------------------- |
.ide7_1: |
mov al, [DRIVE_DATA+6] |
and al, 11b |
cmp al, 10b |
jz .ide7 |
;-------------------------------------- |
.ide6_1: |
mov al, [DRIVE_DATA+6] |
and al, 1100b |
cmp al, 1000b |
jz .ide6 |
;-------------------------------------- |
.ide5_1: |
mov al, [DRIVE_DATA+6] |
and al, 110000b |
cmp al, 100000b |
jz .ide5 |
;-------------------------------------- |
.ide4_1: |
mov al, [DRIVE_DATA+6] |
and al, 11000000b |
cmp al, 10000000b |
jz .ide4 |
;-------------------------------------- |
.ide11_1: |
mov al, [DRIVE_DATA+11] |
and al, 11b |
cmp al, 10b |
jz .ide11 |
;-------------------------------------- |
.ide10_1: |
mov al, [DRIVE_DATA+11] |
and al, 1100b |
cmp al, 1000b |
jz .ide10 |
;-------------------------------------- |
.ide9_1: |
mov al, [DRIVE_DATA+11] |
and al, 110000b |
cmp al, 100000b |
jz .ide9 |
;-------------------------------------- |
.ide8_1: |
mov al, [DRIVE_DATA+11] |
and al, 11000000b |
cmp al, 10000000b |
jz .ide8 |
;-------------------------------------- |
.end: |
|
sti |
popfd |
mov eax, [timer_ticks] |
mov [timer_ATAPI_check], eax |
;-------------------------------------- |
.end_1: |
popa |
ret |
|
;----------------------------------------------------------------------------- |
.ide3: |
cli |
cmp [ATAPI_IDE3_lock], 1 |
jne .ide2_1 |
cmp [IDE_Channel_2], 0 |
jne .ide1_1 |
|
cmp [cd_status], 0 |
jne .end |
mov [IDE_Channel_2], 1 |
|
mov ecx, ide_channel2_mutex |
call mutex_lock |
call reserve_ok2 |
776,23 → 852,22 |
mov [cdpos], 4 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4], byte 1 |
je .eject_ide3 |
call syscall_cdaudio.free |
jmp .ide2_1 |
.eject_ide3: |
jne @f |
|
call .eject |
;-------------------------------------- |
@@: |
call syscall_cdaudio.free |
jmp .ide2_1 |
|
;----------------------------------------------------------------------------- |
.ide2: |
cli |
cmp [ATAPI_IDE2_lock], 1 |
jne .ide1_1 |
cmp [IDE_Channel_2], 0 |
jne .ide1_1 |
|
cmp [cd_status], 0 |
jne .end |
mov [IDE_Channel_2], 1 |
|
mov ecx, ide_channel2_mutex |
call mutex_lock |
call reserve_ok2 |
801,23 → 876,22 |
mov [cdpos], 3 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4], byte 1 |
je .eject_ide2 |
call syscall_cdaudio.free |
jmp .ide1_1 |
.eject_ide2: |
jne @f |
|
call .eject |
;-------------------------------------- |
@@: |
call syscall_cdaudio.free |
jmp .ide1_1 |
|
;----------------------------------------------------------------------------- |
.ide1: |
cli |
cmp [ATAPI_IDE1_lock], 1 |
jne .ide0_1 |
cmp [IDE_Channel_1], 0 |
jne .end |
|
cmp [cd_status], 0 |
jne .end |
mov [IDE_Channel_1], 1 |
|
mov ecx, ide_channel1_mutex |
call mutex_lock |
call reserve_ok2 |
826,23 → 900,22 |
mov [cdpos], 2 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4], byte 1 |
je .eject_ide1 |
call syscall_cdaudio.free |
jmp .ide0_1 |
.eject_ide1: |
jne @f |
|
call .eject |
;-------------------------------------- |
@@: |
call syscall_cdaudio.free |
jmp .ide0_1 |
|
;----------------------------------------------------------------------------- |
.ide0: |
cli |
cmp [ATAPI_IDE0_lock], 1 |
jne .end |
cmp [IDE_Channel_1], 0 |
jne .end |
jne .ide7_1 |
|
cmp [cd_status], 0 |
jne .end |
mov [IDE_Channel_1], 1 |
|
mov ecx, ide_channel1_mutex |
call mutex_lock |
call reserve_ok2 |
851,14 → 924,206 |
mov [cdpos], 1 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4], byte 1 |
je .eject_ide0 |
jne @f |
|
call .eject |
;-------------------------------------- |
@@: |
call syscall_cdaudio.free |
jmp .end |
.eject_ide0: |
jmp .ide7_1 |
;----------------------------------------------------------------------------- |
.ide7: |
cli |
cmp [ATAPI_IDE7_lock], 1 |
jne .ide6_1 |
|
cmp [cd_status], 0 |
jne .end |
|
mov ecx, ide_channel4_mutex |
call mutex_lock |
call reserve_ok2 |
mov [ChannelNumber], 2 |
mov [DiskNumber], 1 |
mov [cdpos], 8 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4], byte 1 |
jne @f |
|
call .eject |
;-------------------------------------- |
@@: |
call syscall_cdaudio.free |
jmp .ide6_1 |
;----------------------------------------------------------------------------- |
.ide6: |
cli |
cmp [ATAPI_IDE6_lock], 1 |
jne .ide5_1 |
|
cmp [cd_status], 0 |
jne .end |
|
mov ecx, ide_channel4_mutex |
call mutex_lock |
call reserve_ok2 |
mov [ChannelNumber], 2 |
mov [DiskNumber], 0 |
mov [cdpos], 7 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4], byte 1 |
jne @f |
|
call .eject |
;-------------------------------------- |
@@: |
call syscall_cdaudio.free |
jmp .ide5_1 |
;----------------------------------------------------------------------------- |
.ide5: |
cli |
cmp [ATAPI_IDE5_lock], 1 |
jne .ide4_1 |
|
cmp [cd_status], 0 |
jne .end |
|
mov ecx, ide_channel3_mutex |
call mutex_lock |
call reserve_ok2 |
mov [ChannelNumber], 1 |
mov [DiskNumber], 1 |
mov [cdpos], 6 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4], byte 1 |
jne @f |
|
call .eject |
;-------------------------------------- |
@@: |
call syscall_cdaudio.free |
jmp .ide4_1 |
;----------------------------------------------------------------------------- |
.ide4: |
cli |
cmp [ATAPI_IDE4_lock], 1 |
jne .ide11_1 |
|
cmp [cd_status], 0 |
jne .end |
|
mov ecx, ide_channel3_mutex |
call mutex_lock |
call reserve_ok2 |
mov [ChannelNumber], 1 |
mov [DiskNumber], 0 |
mov [cdpos], 5 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4], byte 1 |
jne @f |
|
call .eject |
;-------------------------------------- |
@@: |
call syscall_cdaudio.free |
jmp .ide11_1 |
;----------------------------------------------------------------------------- |
.ide11: |
cli |
cmp [ATAPI_IDE11_lock], 1 |
jne .ide10_1 |
|
cmp [cd_status], 0 |
jne .end |
|
mov ecx, ide_channel6_mutex |
call mutex_lock |
call reserve_ok2 |
mov [ChannelNumber], 2 |
mov [DiskNumber], 1 |
mov [cdpos], 12 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4], byte 1 |
jne @f |
|
call .eject |
;-------------------------------------- |
@@: |
call syscall_cdaudio.free |
jmp .ide10_1 |
;----------------------------------------------------------------------------- |
.ide10: |
cli |
cmp [ATAPI_IDE10_lock], 1 |
jne .ide9_1 |
|
cmp [cd_status], 0 |
jne .end |
|
mov ecx, ide_channel6_mutex |
call mutex_lock |
call reserve_ok2 |
mov [ChannelNumber], 2 |
mov [DiskNumber], 0 |
mov [cdpos], 11 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4], byte 1 |
jne @f |
|
call .eject |
;-------------------------------------- |
@@: |
call syscall_cdaudio.free |
jmp .ide9_1 |
;----------------------------------------------------------------------------- |
.ide9: |
cli |
cmp [ATAPI_IDE9_lock], 1 |
jne .ide8_1 |
|
cmp [cd_status], 0 |
jne .end |
|
mov ecx, ide_channel5_mutex |
call mutex_lock |
call reserve_ok2 |
mov [ChannelNumber], 1 |
mov [DiskNumber], 1 |
mov [cdpos], 10 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4], byte 1 |
jne @f |
|
call .eject |
;-------------------------------------- |
@@: |
call syscall_cdaudio.free |
jmp .ide8_1 |
;----------------------------------------------------------------------------- |
.ide8: |
cli |
cmp [ATAPI_IDE8_lock], 1 |
jne .end |
|
cmp [cd_status], 0 |
jne .end |
|
mov ecx, ide_channel5_mutex |
call mutex_lock |
call reserve_ok2 |
mov [ChannelNumber], 1 |
mov [DiskNumber], 0 |
mov [cdpos], 9 |
call GetEvent_StatusNotification |
cmp [CDDataBuf+4], byte 1 |
jne @f |
|
call .eject |
;-------------------------------------- |
@@: |
call syscall_cdaudio.free |
jmp .end |
|
;----------------------------------------------------------------------------- |
.eject: |
call clear_CD_cache |
call allow_medium_removal |
866,6 → 1131,7 |
call EjectMedium |
mov [ignore_CD_eject_wait], 0 |
ret |
;----------------------------------------------------------------------------- |
iglobal |
timer_ATAPI_check dd 0 |
ATAPI_IDE0_lock db 0 |
872,8 → 1138,17 |
ATAPI_IDE1_lock db 0 |
ATAPI_IDE2_lock db 0 |
ATAPI_IDE3_lock db 0 |
ATAPI_IDE4_lock db 0 |
ATAPI_IDE5_lock db 0 |
ATAPI_IDE6_lock db 0 |
ATAPI_IDE7_lock db 0 |
ATAPI_IDE8_lock db 0 |
ATAPI_IDE9_lock db 0 |
ATAPI_IDE10_lock db 0 |
ATAPI_IDE11_lock db 0 |
ignore_CD_eject_wait db 0 |
endg |
;----------------------------------------------------------------------------- |
;************************************************* |
;* Получить сообщение о событии или состоянии * |
;* устройства * |
899,7 → 1174,7 |
call SendPacketDatCommand |
popa |
ret |
|
;----------------------------------------------------------------------------- |
;************************************************* |
; прочитать информацию из TOC |
;* Входные параметры передаются через глобальные * |
924,7 → 1199,7 |
call SendPacketDatCommand |
popa |
ret |
|
;----------------------------------------------------------------------------- |
;************************************************* |
;* ОПРЕДЕЛИТЬ ОБЩЕЕ КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ * |
;* Входные параметры передаются через глобальные * |
944,7 → 1219,7 |
; call SendPacketDatCommand |
; popa |
; ret |
|
;----------------------------------------------------------------------------- |
clear_packet_buffer: |
; Очистить буфер пакетной команды |
and [PacketCommand], dword 0 |
951,3 → 1226,4 |
and [PacketCommand+4], dword 0 |
and [PacketCommand+8], dword 0 |
ret |
;----------------------------------------------------------------------------- |