2010-10-01 11:21:55 +02:00
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;; ;;
|
2012-03-15 13:41:29 +01:00
|
|
|
|
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
|
2010-10-01 11:21:55 +02:00
|
|
|
|
;; Distributed under terms of the GNU General Public License ;;
|
|
|
|
|
;; ;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
|
|
$Revision$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;**********************************************************
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Непосредственная работа с устройством СD (ATAPI)
|
2010-10-01 11:21:55 +02:00
|
|
|
|
;**********************************************************
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Автор части исходного текста Кулаков Владимир Геннадьевич
|
|
|
|
|
; Адаптация, доработка и разработка Mario79,<Lrz>
|
2010-10-01 11:21:55 +02:00
|
|
|
|
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Максимальное количество повторений операции чтения
|
2010-10-01 11:21:55 +02:00
|
|
|
|
MaxRetr equ 10
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Предельное время ожидания готовности к приему команды
|
|
|
|
|
; (в тиках)
|
2010-10-01 11:21:55 +02:00
|
|
|
|
BSYWaitTime equ 1000 ;2
|
|
|
|
|
NoTickWaitTime equ 0xfffff
|
|
|
|
|
CDBlockSize equ 2048
|
|
|
|
|
;********************************************
|
2013-05-28 21:09:31 +02:00
|
|
|
|
;* ЧТЕНИЕ СЕКТОРА С ПОВТОРАМИ *
|
|
|
|
|
;* Многократное повторение чтения при сбоях *
|
2010-10-01 11:21:55 +02:00
|
|
|
|
;********************************************
|
|
|
|
|
ReadCDWRetr:
|
|
|
|
|
;-----------------------------------------------------------
|
|
|
|
|
; input : eax = block to read
|
|
|
|
|
; ebx = destination
|
|
|
|
|
;-----------------------------------------------------------
|
2013-05-28 21:09:31 +02:00
|
|
|
|
pushad
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov eax, [CDSectorAddress]
|
|
|
|
|
mov ebx, [CDDataBuf_pointer]
|
2013-05-28 21:09:31 +02:00
|
|
|
|
call cd_calculate_cache
|
2012-03-08 09:33:38 +01:00
|
|
|
|
xor edi, edi
|
|
|
|
|
add esi, 8
|
2013-05-28 21:09:31 +02:00
|
|
|
|
inc edi
|
2010-10-01 11:21:55 +02:00
|
|
|
|
.hdreadcache:
|
|
|
|
|
; cmp dword [esi+4],0 ; empty
|
|
|
|
|
; je .nohdcache
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [esi], eax ; correct sector
|
2013-05-28 21:09:31 +02:00
|
|
|
|
je .yeshdcache
|
2010-10-01 11:21:55 +02:00
|
|
|
|
.nohdcache:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
add esi, 8
|
2013-05-28 21:09:31 +02:00
|
|
|
|
inc edi
|
|
|
|
|
dec ecx
|
|
|
|
|
jnz .hdreadcache
|
|
|
|
|
call find_empty_slot_CD_cache ; ret in edi
|
|
|
|
|
|
|
|
|
|
push edi
|
|
|
|
|
push eax
|
|
|
|
|
call cd_calculate_cache_2
|
2012-03-08 09:33:38 +01:00
|
|
|
|
shl edi, 11
|
|
|
|
|
add edi, eax
|
|
|
|
|
mov [CDDataBuf_pointer], edi
|
2013-05-28 21:09:31 +02:00
|
|
|
|
pop eax
|
|
|
|
|
pop edi
|
2010-10-01 11:21:55 +02:00
|
|
|
|
|
2013-05-28 21:09:31 +02:00
|
|
|
|
call ReadCDWRetr_1
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [DevErrorCode], 0
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jne .exit
|
2010-10-01 11:21:55 +02:00
|
|
|
|
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [CDDataBuf_pointer], ebx
|
2013-05-28 21:09:31 +02:00
|
|
|
|
call cd_calculate_cache_1
|
2012-03-08 09:33:38 +01:00
|
|
|
|
lea esi, [edi*8+esi]
|
|
|
|
|
mov [esi], eax ; sector number
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; mov dword [esi+4],1 ; hd read - mark as same as in hd
|
|
|
|
|
.yeshdcache:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov esi, edi
|
|
|
|
|
shl esi, 11;9
|
2013-05-28 21:09:31 +02:00
|
|
|
|
push eax
|
|
|
|
|
call cd_calculate_cache_2
|
2012-03-08 09:33:38 +01:00
|
|
|
|
add esi, eax
|
2013-05-28 21:09:31 +02:00
|
|
|
|
pop eax
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov edi, ebx;[CDDataBuf_pointer]
|
|
|
|
|
mov ecx, 512;/4
|
2013-05-28 21:09:31 +02:00
|
|
|
|
cld
|
|
|
|
|
rep movsd ; move data
|
2010-10-01 11:21:55 +02:00
|
|
|
|
.exit:
|
2013-05-28 21:09:31 +02:00
|
|
|
|
popad
|
|
|
|
|
ret
|
2010-10-01 11:21:55 +02:00
|
|
|
|
|
|
|
|
|
ReadCDWRetr_1:
|
|
|
|
|
pushad
|
|
|
|
|
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Цикл, пока команда не выполнена успешно или не
|
|
|
|
|
; исчерпано количество попыток
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov ECX, MaxRetr
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@NextRetr:
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Подать команду
|
2010-10-01 11:21:55 +02:00
|
|
|
|
;*************************************************
|
2013-05-28 21:09:31 +02:00
|
|
|
|
;* ПОЛНОЕ ЧТЕНИЕ СЕКТОРА КОМПАКТ-ДИСКА *
|
|
|
|
|
;* Считываются данные пользователя, информация *
|
|
|
|
|
;* субканала и контрольная информация *
|
|
|
|
|
;* Входные параметры передаются через глобальные *
|
|
|
|
|
;* перменные: *
|
|
|
|
|
;* ChannelNumber - номер канала; *
|
|
|
|
|
;* DiskNumber - номер диска на канале; *
|
|
|
|
|
;* CDSectorAddress - адрес считываемого сектора. *
|
|
|
|
|
;* Данные считывается в массив CDDataBuf. *
|
2010-10-01 11:21:55 +02:00
|
|
|
|
;*************************************************
|
|
|
|
|
;ReadCD:
|
2013-05-28 21:09:31 +02:00
|
|
|
|
push ecx
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; pusha
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Задать размер сектора
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; mov [CDBlockSize],2048 ;2352
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Очистить буфер пакетной команды
|
|
|
|
|
call clear_packet_buffer
|
|
|
|
|
; Сформировать пакетную команду для считывания
|
|
|
|
|
; сектора данных
|
|
|
|
|
; Задать код команды Read CD
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [PacketCommand], byte 0x28;0xBE
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Задать адрес сектора
|
2012-03-08 09:33:38 +01:00
|
|
|
|
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
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; mov eax,[CDSectorAddress]
|
|
|
|
|
; mov [PacketCommand+2],eax
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Задать количество считываемых секторов
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [PacketCommand+8], byte 1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Задать считывание данных в полном объеме
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; mov [PacketCommand+9],byte 0xF8
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Подать команду
|
|
|
|
|
call SendPacketDatCommand
|
|
|
|
|
pop ecx
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; ret
|
|
|
|
|
|
|
|
|
|
; cmp [DevErrorCode],0
|
2012-03-08 09:33:38 +01:00
|
|
|
|
test eax, eax
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jz @@End_4
|
2010-10-01 11:21:55 +02:00
|
|
|
|
|
2012-03-08 09:33:38 +01:00
|
|
|
|
or ecx, ecx ;{SPraid.simba} (for cd load)
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jz @@End_4
|
|
|
|
|
dec ecx
|
2010-10-01 11:21:55 +02:00
|
|
|
|
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [timer_ticks_enable], 0
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jne @f
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov eax, NoTickWaitTime
|
2010-10-01 11:21:55 +02:00
|
|
|
|
.wait:
|
2013-05-28 21:09:31 +02:00
|
|
|
|
dec eax
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; test eax,eax
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jz @@NextRetr
|
|
|
|
|
jmp .wait
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@:
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Задержка на 2,5 секунды
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; mov EAX,[timer_ticks]
|
|
|
|
|
; add EAX,50 ;250
|
|
|
|
|
;@@Wait:
|
|
|
|
|
; call change_task
|
|
|
|
|
; cmp EAX,[timer_ticks]
|
|
|
|
|
; ja @@Wait
|
2013-05-28 21:09:31 +02:00
|
|
|
|
loop @@NextRetr
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@End_4:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov dword [DevErrorCode], eax
|
2010-10-01 11:21:55 +02:00
|
|
|
|
popad
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Универсальные процедуры, обеспечивающие выполнение
|
|
|
|
|
; пакетных команд в режиме PIO
|
2010-10-01 11:21:55 +02:00
|
|
|
|
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Максимально допустимое время ожидания реакции
|
|
|
|
|
; устройства на пакетную команду (в тиках)
|
2010-10-01 11:21:55 +02:00
|
|
|
|
|
2013-05-28 21:09:31 +02:00
|
|
|
|
MaxCDWaitTime equ 1000 ;200 ;10 секунд
|
2010-10-01 11:21:55 +02:00
|
|
|
|
uglobal
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Область памяти для формирования пакетной команды
|
2012-03-08 09:33:38 +01:00
|
|
|
|
PacketCommand:
|
|
|
|
|
rb 12 ;DB 12 DUP (?)
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Область памяти для приема данных от дисковода
|
2010-10-01 11:21:55 +02:00
|
|
|
|
;CDDataBuf DB 4096 DUP (0)
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Размер принимаемого блока данных в байтах
|
2010-10-01 11:21:55 +02:00
|
|
|
|
;CDBlockSize DW ?
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Адрес считываемого сектора данных
|
2012-03-08 09:33:38 +01:00
|
|
|
|
CDSectorAddress:
|
|
|
|
|
DD ?
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Время начала очередной операции с диском
|
2010-10-01 11:21:55 +02:00
|
|
|
|
TickCounter_1 DD 0
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Время начала ожидания готовности устройства
|
2010-10-01 11:21:55 +02:00
|
|
|
|
WURStartTime DD 0
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; указатель буфера для считывания
|
2010-10-01 11:21:55 +02:00
|
|
|
|
CDDataBuf_pointer dd 0
|
|
|
|
|
endg
|
|
|
|
|
;****************************************************
|
2013-05-28 21:09:31 +02:00
|
|
|
|
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
|
|
|
|
|
;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ *
|
|
|
|
|
;* РАЗМЕРОМ 2048 БАЙТ ОТ УСТРОЙСТВА К ХОСТУ *
|
|
|
|
|
;* Входные параметры передаются через глобальные *
|
|
|
|
|
;* перменные: *
|
|
|
|
|
;* ChannelNumber - номер канала; *
|
|
|
|
|
;* DiskNumber - номер диска на канале; *
|
|
|
|
|
;* PacketCommand - 12-байтный командный пакет; *
|
|
|
|
|
;* CDBlockSize - размер принимаемого блока данных. *
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; return eax DevErrorCode
|
|
|
|
|
;****************************************************
|
|
|
|
|
SendPacketDatCommand:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
xor eax, eax
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; mov byte [DevErrorCode],al
|
|
|
|
|
; Задать режим CHS
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov byte [ATAAddressMode], al
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Послать ATA-команду передачи пакетной команды
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov byte [ATAFeatures], al
|
|
|
|
|
mov byte [ATASectorCount], al
|
|
|
|
|
mov byte [ATASectorNumber], al
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Загрузить размер передаваемого блока
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [ATAHead], al
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; mov AX,[CDBlockSize]
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [ATACylinder], CDBlockSize
|
|
|
|
|
mov [ATACommand], 0A0h
|
2010-10-01 11:21:55 +02:00
|
|
|
|
call SendCommandToHDD_1
|
2012-03-08 09:33:38 +01:00
|
|
|
|
test eax, eax
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; cmp [DevErrorCode],0 ;проверить код ошибки
|
|
|
|
|
jnz @@End_8 ;закончить, сохранив код ошибки
|
2010-10-01 11:21:55 +02:00
|
|
|
|
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Ожидание готовности дисковода к приему
|
|
|
|
|
; пакетной команды
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov DX, [ATABasePortAddr]
|
2013-05-28 21:09:31 +02:00
|
|
|
|
add DX, 7 ;порт 1х7h
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov ecx, NoTickWaitTime
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@WaitDevice0:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [timer_ticks_enable], 0
|
2010-10-01 11:21:55 +02:00
|
|
|
|
jne @f
|
|
|
|
|
dec ecx
|
|
|
|
|
; test ecx,ecx
|
|
|
|
|
jz @@Err1_1
|
|
|
|
|
jmp .test
|
|
|
|
|
@@:
|
|
|
|
|
call change_task
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Проверить время выполнения команды
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov EAX, [timer_ticks]
|
|
|
|
|
sub EAX, [TickCounter_1]
|
|
|
|
|
cmp EAX, BSYWaitTime
|
2013-05-28 21:09:31 +02:00
|
|
|
|
ja @@Err1_1 ;ошибка тайм-аута
|
|
|
|
|
; Проверить готовность
|
2010-10-01 11:21:55 +02:00
|
|
|
|
.test:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
in AL, DX
|
2013-05-28 21:09:31 +02:00
|
|
|
|
test AL, 80h ;состояние сигнала BSY
|
2010-10-01 11:21:55 +02:00
|
|
|
|
jnz @@WaitDevice0
|
2013-05-28 21:09:31 +02:00
|
|
|
|
test AL, 1 ;состояние сигнала ERR
|
2010-10-01 11:21:55 +02:00
|
|
|
|
jnz @@Err6
|
2013-05-28 21:09:31 +02:00
|
|
|
|
test AL, 08h ;состояние сигнала DRQ
|
2011-07-22 20:08:47 +02:00
|
|
|
|
jz @@WaitDevice0
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Послать пакетную команду
|
2010-10-01 11:21:55 +02:00
|
|
|
|
cli
|
2012-03-08 09:33:38 +01:00
|
|
|
|
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
|
2010-10-01 11:21:55 +02:00
|
|
|
|
sti
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Ожидание готовности данных
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov DX, [ATABasePortAddr]
|
2013-05-28 21:09:31 +02:00
|
|
|
|
add DX, 7 ;порт 1х7h
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov ecx, NoTickWaitTime
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@WaitDevice1:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [timer_ticks_enable], 0
|
2010-10-01 11:21:55 +02:00
|
|
|
|
jne @f
|
|
|
|
|
dec ecx
|
|
|
|
|
; test ecx,ecx
|
|
|
|
|
jz @@Err1_1
|
|
|
|
|
jmp .test_1
|
|
|
|
|
@@:
|
|
|
|
|
call change_task
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Проверить время выполнения команды
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov EAX, [timer_ticks]
|
|
|
|
|
sub EAX, [TickCounter_1]
|
|
|
|
|
cmp EAX, MaxCDWaitTime
|
2013-05-28 21:09:31 +02:00
|
|
|
|
ja @@Err1_1 ;ошибка тайм-аута
|
|
|
|
|
; Проверить готовность
|
2010-10-01 11:21:55 +02:00
|
|
|
|
.test_1:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
in AL, DX
|
2013-05-28 21:09:31 +02:00
|
|
|
|
test AL, 80h ;состояние сигнала BSY
|
2010-10-01 11:21:55 +02:00
|
|
|
|
jnz @@WaitDevice1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
test AL, 1 ;состояние сигнала ERR
|
2010-10-01 11:21:55 +02:00
|
|
|
|
jnz @@Err6_temp
|
2013-05-28 21:09:31 +02:00
|
|
|
|
test AL, 08h ;состояние сигнала DRQ
|
2011-07-22 20:08:47 +02:00
|
|
|
|
jz @@WaitDevice1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Принять блок данных от контроллера
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov EDI, [CDDataBuf_pointer];0x7000 ;CDDataBuf
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Загрузить адрес регистра данных контроллера
|
|
|
|
|
mov DX, [ATABasePortAddr];порт 1x0h
|
|
|
|
|
; Загрузить в счетчик размер блока в байтах
|
2012-03-08 09:33:38 +01:00
|
|
|
|
xor ecx, ecx
|
|
|
|
|
mov CX, CDBlockSize
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Вычислить размер блока в 16-разрядных словах
|
|
|
|
|
shr CX, 1;разделить размер блока на 2
|
|
|
|
|
; Принять блок данных
|
2010-10-01 11:21:55 +02:00
|
|
|
|
cli
|
|
|
|
|
cld
|
2013-05-28 21:09:31 +02:00
|
|
|
|
rep insw
|
2010-10-01 11:21:55 +02:00
|
|
|
|
sti
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Успешное завершение приема данных
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@End_8:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
xor eax, eax
|
2010-10-01 11:21:55 +02:00
|
|
|
|
ret
|
|
|
|
|
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Записать код ошибки
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@Err1_1:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
xor eax, eax
|
2013-05-28 21:09:31 +02:00
|
|
|
|
inc eax
|
|
|
|
|
ret
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; mov [DevErrorCode],1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; ret
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@Err6_temp:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov eax, 7
|
2013-05-28 21:09:31 +02:00
|
|
|
|
ret
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; mov [DevErrorCode],7
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; ret
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@Err6:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov eax, 6
|
2013-05-28 21:09:31 +02:00
|
|
|
|
ret
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; mov [DevErrorCode],6
|
|
|
|
|
;@@End_8:
|
|
|
|
|
; ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;***********************************************
|
2013-05-28 21:09:31 +02:00
|
|
|
|
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
|
|
|
|
|
;* НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ *
|
|
|
|
|
;* Входные параметры передаются через *
|
|
|
|
|
;* глобальные перменные: *
|
|
|
|
|
;* ChannelNumber - номер канала; *
|
|
|
|
|
;* DiskNumber - номер диска на канале; *
|
|
|
|
|
;* PacketCommand - 12-байтный командный пакет. *
|
2010-10-01 11:21:55 +02:00
|
|
|
|
;***********************************************
|
|
|
|
|
SendPacketNoDatCommand:
|
|
|
|
|
pushad
|
2012-03-08 09:33:38 +01:00
|
|
|
|
xor eax, eax
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; mov byte [DevErrorCode],al
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Задать режим CHS
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov byte [ATAAddressMode], al
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Послать ATA-команду передачи пакетной команды
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov byte [ATAFeatures], al
|
|
|
|
|
mov byte [ATASectorCount], al
|
|
|
|
|
mov byte [ATASectorNumber], al
|
|
|
|
|
mov word [ATACylinder], ax
|
|
|
|
|
mov byte [ATAHead], al
|
|
|
|
|
mov [ATACommand], 0A0h
|
2010-10-01 11:21:55 +02:00
|
|
|
|
call SendCommandToHDD_1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; cmp [DevErrorCode],0 ;проверить код ошибки
|
2012-03-08 09:33:38 +01:00
|
|
|
|
test eax, eax
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jnz @@End_9 ;закончить, сохранив код ошибки
|
|
|
|
|
; Ожидание готовности дисковода к приему
|
|
|
|
|
; пакетной команды
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov DX, [ATABasePortAddr]
|
2013-05-28 21:09:31 +02:00
|
|
|
|
add DX, 7 ;порт 1х7h
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@WaitDevice0_1:
|
|
|
|
|
call change_task
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Проверить время ожидания
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov EAX, [timer_ticks]
|
|
|
|
|
sub EAX, [TickCounter_1]
|
|
|
|
|
cmp EAX, BSYWaitTime
|
2013-05-28 21:09:31 +02:00
|
|
|
|
ja @@Err1_3 ;ошибка тайм-аута
|
|
|
|
|
; Проверить готовность
|
2012-03-08 09:33:38 +01:00
|
|
|
|
in AL, DX
|
2013-05-28 21:09:31 +02:00
|
|
|
|
test AL, 80h ;состояние сигнала BSY
|
2010-10-01 11:21:55 +02:00
|
|
|
|
jnz @@WaitDevice0_1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
test AL, 1 ;состояние сигнала ERR
|
2010-10-01 11:21:55 +02:00
|
|
|
|
jnz @@Err6_1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
test AL, 08h ;состояние сигнала DRQ
|
2010-10-01 11:21:55 +02:00
|
|
|
|
jz @@WaitDevice0_1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Послать пакетную команду
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; cli
|
2012-03-08 09:33:38 +01:00
|
|
|
|
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
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; sti
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [ignore_CD_eject_wait], 1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
je @@clear_DEC
|
|
|
|
|
; Ожидание подтверждения приема команды
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov DX, [ATABasePortAddr]
|
2013-05-28 21:09:31 +02:00
|
|
|
|
add DX, 7 ;порт 1х7h
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@WaitDevice1_1:
|
|
|
|
|
call change_task
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Проверить время выполнения команды
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov EAX, [timer_ticks]
|
|
|
|
|
sub EAX, [TickCounter_1]
|
|
|
|
|
cmp EAX, MaxCDWaitTime
|
2013-05-28 21:09:31 +02:00
|
|
|
|
ja @@Err1_3 ;ошибка тайм-аута
|
|
|
|
|
; Ожидать освобождения устройства
|
2012-03-08 09:33:38 +01:00
|
|
|
|
in AL, DX
|
2013-05-28 21:09:31 +02:00
|
|
|
|
test AL, 80h ;состояние сигнала BSY
|
2010-10-01 11:21:55 +02:00
|
|
|
|
jnz @@WaitDevice1_1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
test AL, 1 ;состояние сигнала ERR
|
2010-10-01 11:21:55 +02:00
|
|
|
|
jnz @@Err6_1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
test AL, 40h ;состояние сигнала DRDY
|
2010-10-01 11:21:55 +02:00
|
|
|
|
jz @@WaitDevice1_1
|
|
|
|
|
@@clear_DEC:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
and [DevErrorCode], 0
|
2010-10-01 11:21:55 +02:00
|
|
|
|
popad
|
|
|
|
|
ret
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Записать код ошибки
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@Err1_3:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
xor eax, eax
|
2013-05-28 21:09:31 +02:00
|
|
|
|
inc eax
|
|
|
|
|
jmp @@End_9
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@Err6_1:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov eax, 6
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@End_9:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [DevErrorCode], eax
|
2010-10-01 11:21:55 +02:00
|
|
|
|
popad
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;****************************************************
|
2013-05-28 21:09:31 +02:00
|
|
|
|
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ *
|
|
|
|
|
;* Входные параметры передаются через глобальные *
|
|
|
|
|
;* переменные: *
|
|
|
|
|
;* ChannelNumber - номер канала (1 или 2); *
|
|
|
|
|
;* DiskNumber - номер диска (0 или 1); *
|
|
|
|
|
;* ATAFeatures - "особенности"; *
|
|
|
|
|
;* ATASectorCount - количество секторов; *
|
|
|
|
|
;* ATASectorNumber - номер начального сектора; *
|
|
|
|
|
;* ATACylinder - номер начального цилиндра; *
|
|
|
|
|
;* ATAHead - номер начальной головки; *
|
|
|
|
|
;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); *
|
|
|
|
|
;* ATACommand - код команды. *
|
|
|
|
|
;* После успешного выполнения функции: *
|
|
|
|
|
;* в ATABasePortAddr - базовый адрес HDD; *
|
|
|
|
|
;* в DevErrorCode - ноль. *
|
|
|
|
|
;* При возникновении ошибки в DevErrorCode будет *
|
|
|
|
|
;* возвращен код ошибки в eax *
|
2010-10-01 11:21:55 +02:00
|
|
|
|
;****************************************************
|
|
|
|
|
SendCommandToHDD_1:
|
|
|
|
|
; pushad
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; mov [DevErrorCode],0 not need
|
|
|
|
|
; Проверить значение кода режима
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [ATAAddressMode], 1
|
2010-10-01 11:21:55 +02:00
|
|
|
|
ja @@Err2_4
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Проверить корректность номера канала
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov BX, [ChannelNumber]
|
|
|
|
|
cmp BX, 1
|
2010-10-01 11:21:55 +02:00
|
|
|
|
jb @@Err3_4
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp BX, 2
|
2010-10-01 11:21:55 +02:00
|
|
|
|
ja @@Err3_4
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Установить базовый адрес
|
2010-10-01 11:21:55 +02:00
|
|
|
|
dec BX
|
2012-03-08 09:33:38 +01:00
|
|
|
|
shl BX, 1
|
|
|
|
|
movzx ebx, bx
|
|
|
|
|
mov AX, [ebx+StandardATABases]
|
|
|
|
|
mov [ATABasePortAddr], AX
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Ожидание готовности HDD к приему команды
|
|
|
|
|
; Выбрать нужный диск
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov DX, [ATABasePortAddr]
|
2013-05-28 21:09:31 +02:00
|
|
|
|
add DX, 6 ;адрес регистра головок
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov AL, [DiskNumber]
|
2013-05-28 21:09:31 +02:00
|
|
|
|
cmp AL, 1 ;проверить номера диска
|
2010-10-01 11:21:55 +02:00
|
|
|
|
ja @@Err4_4
|
2012-03-08 09:33:38 +01:00
|
|
|
|
shl AL, 4
|
|
|
|
|
or AL, 10100000b
|
|
|
|
|
out DX, AL
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Ожидать, пока диск не будет готов
|
2010-10-01 11:21:55 +02:00
|
|
|
|
inc DX
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov eax, [timer_ticks]
|
|
|
|
|
mov [TickCounter_1], eax
|
|
|
|
|
mov ecx, NoTickWaitTime
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@WaitHDReady_2:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [timer_ticks_enable], 0
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jne @f
|
|
|
|
|
dec ecx
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; test ecx,ecx
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jz @@Err1_4
|
|
|
|
|
jmp .test
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@:
|
|
|
|
|
call change_task
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Проверить время ожидания
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov eax, [timer_ticks]
|
|
|
|
|
sub eax, [TickCounter_1]
|
2013-05-28 21:09:31 +02:00
|
|
|
|
cmp eax, BSYWaitTime;300 ;ожидать 3 сек.
|
|
|
|
|
ja @@Err1_4 ;ошибка тайм-аута
|
|
|
|
|
; Прочитать регистр состояния
|
2010-10-01 11:21:55 +02:00
|
|
|
|
.test:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
in AL, DX
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Проверить состояние сигнала BSY
|
2012-03-08 09:33:38 +01:00
|
|
|
|
test AL, 80h
|
2010-10-01 11:21:55 +02:00
|
|
|
|
jnz @@WaitHDReady_2
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Проверить состояние сигнала DRQ
|
2012-03-08 09:33:38 +01:00
|
|
|
|
test AL, 08h
|
2010-10-01 11:21:55 +02:00
|
|
|
|
jnz @@WaitHDReady_2
|
|
|
|
|
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Загрузить команду в регистры контроллера
|
2010-10-01 11:21:55 +02:00
|
|
|
|
cli
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov DX, [ATABasePortAddr]
|
2013-05-28 21:09:31 +02:00
|
|
|
|
inc DX ;регистр "особенностей"
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov AL, [ATAFeatures]
|
|
|
|
|
out DX, AL
|
2013-05-28 21:09:31 +02:00
|
|
|
|
inc DX ;счетчик секторов
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov AL, [ATASectorCount]
|
|
|
|
|
out DX, AL
|
2013-05-28 21:09:31 +02:00
|
|
|
|
inc DX ;регистр номера сектора
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov AL, [ATASectorNumber]
|
|
|
|
|
out DX, AL
|
2013-05-28 21:09:31 +02:00
|
|
|
|
inc DX ;номер цилиндра (младший байт)
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov AX, [ATACylinder]
|
|
|
|
|
out DX, AL
|
2013-05-28 21:09:31 +02:00
|
|
|
|
inc DX ;номер цилиндра (старший байт)
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov AL, AH
|
|
|
|
|
out DX, AL
|
2013-05-28 21:09:31 +02:00
|
|
|
|
inc DX ;номер головки/номер диска
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov AL, [DiskNumber]
|
|
|
|
|
shl AL, 4
|
2013-05-28 21:09:31 +02:00
|
|
|
|
cmp [ATAHead], 0Fh;проверить номер головки
|
2010-10-01 11:21:55 +02:00
|
|
|
|
ja @@Err5_4
|
2012-03-08 09:33:38 +01:00
|
|
|
|
or AL, [ATAHead]
|
|
|
|
|
or AL, 10100000b
|
|
|
|
|
mov AH, [ATAAddressMode]
|
|
|
|
|
shl AH, 6
|
|
|
|
|
or AL, AH
|
|
|
|
|
out DX, AL
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Послать команду
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov AL, [ATACommand]
|
2013-05-28 21:09:31 +02:00
|
|
|
|
inc DX ;регистр команд
|
2012-03-08 09:33:38 +01:00
|
|
|
|
out DX, AL
|
2010-10-01 11:21:55 +02:00
|
|
|
|
sti
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Сбросить признак ошибки
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; mov [DevErrorCode],0
|
|
|
|
|
@@End_10:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
xor eax, eax
|
2013-05-28 21:09:31 +02:00
|
|
|
|
ret
|
|
|
|
|
; Записать код ошибки
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@Err1_4:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
xor eax, eax
|
2013-05-28 21:09:31 +02:00
|
|
|
|
inc eax
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; mov [DevErrorCode],1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
ret
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@Err2_4:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov eax, 2
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; mov [DevErrorCode],2
|
2013-05-28 21:09:31 +02:00
|
|
|
|
ret
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@Err3_4:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov eax, 3
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; mov [DevErrorCode],3
|
2013-05-28 21:09:31 +02:00
|
|
|
|
ret
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@Err4_4:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov eax, 4
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; mov [DevErrorCode],4
|
2013-05-28 21:09:31 +02:00
|
|
|
|
ret
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@Err5_4:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov eax, 5
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; mov [DevErrorCode],5
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Завершение работы программы
|
|
|
|
|
ret
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; sti
|
|
|
|
|
; popad
|
|
|
|
|
|
|
|
|
|
;*************************************************
|
2013-05-28 21:09:31 +02:00
|
|
|
|
;* ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ *
|
|
|
|
|
;* Входные параметры передаются через глобальные *
|
|
|
|
|
;* перменные: *
|
|
|
|
|
;* ChannelNumber - номер канала; *
|
|
|
|
|
;* DiskNumber - номер диска на канале. *
|
2010-10-01 11:21:55 +02:00
|
|
|
|
;*************************************************
|
|
|
|
|
WaitUnitReady:
|
|
|
|
|
pusha
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Запомнить время начала операции
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov EAX, [timer_ticks]
|
|
|
|
|
mov [WURStartTime], EAX
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Очистить буфер пакетной команды
|
|
|
|
|
call clear_packet_buffer
|
|
|
|
|
; Сформировать команду TEST UNIT READY
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [PacketCommand], word 00h
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov ecx, NoTickWaitTime
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@SendCommand:
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Подать команду проверки готовности
|
2010-10-01 11:21:55 +02:00
|
|
|
|
call SendPacketNoDatCommand
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [timer_ticks_enable], 0
|
2010-10-01 11:21:55 +02:00
|
|
|
|
jne @f
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [DevErrorCode], 0
|
2010-10-01 11:21:55 +02:00
|
|
|
|
je @@End_11
|
|
|
|
|
dec ecx
|
|
|
|
|
; cmp ecx,0
|
|
|
|
|
jz .Error
|
|
|
|
|
jmp @@SendCommand
|
|
|
|
|
@@:
|
|
|
|
|
call change_task
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Проверить код ошибки
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [DevErrorCode], 0
|
2010-10-01 11:21:55 +02:00
|
|
|
|
je @@End_11
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Проверить время ожидания готовности
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov EAX, [timer_ticks]
|
|
|
|
|
sub EAX, [WURStartTime]
|
|
|
|
|
cmp EAX, MaxCDWaitTime
|
2010-10-01 11:21:55 +02:00
|
|
|
|
jb @@SendCommand
|
|
|
|
|
.Error:
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Ошибка тайм-аута
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [DevErrorCode], 1
|
2010-10-01 11:21:55 +02:00
|
|
|
|
@@End_11:
|
|
|
|
|
popa
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*************************************************
|
2013-05-28 21:09:31 +02:00
|
|
|
|
;* ЗАПРЕТИТЬ СМЕНУ ДИСКА *
|
|
|
|
|
;* Входные параметры передаются через глобальные *
|
|
|
|
|
;* перменные: *
|
|
|
|
|
;* ChannelNumber - номер канала; *
|
|
|
|
|
;* DiskNumber - номер диска на канале. *
|
2010-10-01 11:21:55 +02:00
|
|
|
|
;*************************************************
|
|
|
|
|
prevent_medium_removal:
|
|
|
|
|
pusha
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Очистить буфер пакетной команды
|
|
|
|
|
call clear_packet_buffer
|
|
|
|
|
; Задать код команды
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [PacketCommand], byte 0x1E
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Задать код запрета
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [PacketCommand+4], byte 11b
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Подать команду
|
|
|
|
|
call SendPacketNoDatCommand
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov eax, ATAPI_IDE0_lock
|
|
|
|
|
add eax, [cdpos]
|
2013-05-28 21:09:31 +02:00
|
|
|
|
dec eax
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [eax], byte 1
|
2010-10-01 11:21:55 +02:00
|
|
|
|
popa
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*************************************************
|
2013-05-28 21:09:31 +02:00
|
|
|
|
;* РАЗРЕШИТЬ СМЕНУ ДИСКА *
|
|
|
|
|
;* Входные параметры передаются через глобальные *
|
|
|
|
|
;* перменные: *
|
|
|
|
|
;* ChannelNumber - номер канала; *
|
|
|
|
|
;* DiskNumber - номер диска на канале. *
|
2010-10-01 11:21:55 +02:00
|
|
|
|
;*************************************************
|
|
|
|
|
allow_medium_removal:
|
|
|
|
|
pusha
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Очистить буфер пакетной команды
|
|
|
|
|
call clear_packet_buffer
|
|
|
|
|
; Задать код команды
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [PacketCommand], byte 0x1E
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Задать код запрета
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [PacketCommand+4], byte 00b
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Подать команду
|
|
|
|
|
call SendPacketNoDatCommand
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov eax, ATAPI_IDE0_lock
|
|
|
|
|
add eax, [cdpos]
|
2013-05-28 21:09:31 +02:00
|
|
|
|
dec eax
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [eax], byte 0
|
2010-10-01 11:21:55 +02:00
|
|
|
|
popa
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*************************************************
|
2013-05-28 21:09:31 +02:00
|
|
|
|
;* ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД *
|
|
|
|
|
;* Входные параметры передаются через глобальные *
|
|
|
|
|
;* перменные: *
|
|
|
|
|
;* ChannelNumber - номер канала; *
|
|
|
|
|
;* DiskNumber - номер диска на канале. *
|
2010-10-01 11:21:55 +02:00
|
|
|
|
;*************************************************
|
|
|
|
|
LoadMedium:
|
|
|
|
|
pusha
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Очистить буфер пакетной команды
|
|
|
|
|
call clear_packet_buffer
|
|
|
|
|
; Сформировать команду START/STOP UNIT
|
|
|
|
|
; Задать код команды
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [PacketCommand], word 1Bh
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Задать операцию загрузки носителя
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [PacketCommand+4], word 00000011b
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Подать команду
|
2010-10-01 11:21:55 +02:00
|
|
|
|
call SendPacketNoDatCommand
|
|
|
|
|
popa
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*************************************************
|
2013-05-28 21:09:31 +02:00
|
|
|
|
;* ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА *
|
|
|
|
|
;* Входные параметры передаются через глобальные *
|
|
|
|
|
;* перменные: *
|
|
|
|
|
;* ChannelNumber - номер канала; *
|
|
|
|
|
;* DiskNumber - номер диска на канале. *
|
2010-10-01 11:21:55 +02:00
|
|
|
|
;*************************************************
|
|
|
|
|
EjectMedium:
|
|
|
|
|
pusha
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Очистить буфер пакетной команды
|
|
|
|
|
call clear_packet_buffer
|
|
|
|
|
; Сформировать команду START/STOP UNIT
|
|
|
|
|
; Задать код команды
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [PacketCommand], word 1Bh
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Задать операцию извлечения носителя
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [PacketCommand+4], word 00000010b
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Подать команду
|
2010-10-01 11:21:55 +02:00
|
|
|
|
call SendPacketNoDatCommand
|
|
|
|
|
popa
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*************************************************
|
2013-05-28 21:09:31 +02:00
|
|
|
|
;* Проверить событие нажатия кнопки извлечения *
|
|
|
|
|
;* диска *
|
|
|
|
|
;* Входные параметры передаются через глобальные *
|
|
|
|
|
;* переменные: *
|
|
|
|
|
;* ChannelNumber - номер канала; *
|
|
|
|
|
;* DiskNumber - номер диска на канале. *
|
2010-10-01 11:21:55 +02:00
|
|
|
|
;*************************************************
|
2013-05-28 21:09:31 +02:00
|
|
|
|
proc check_ATAPI_device_event_has_work?
|
|
|
|
|
mov eax, [timer_ticks]
|
|
|
|
|
sub eax, [timer_ATAPI_check]
|
|
|
|
|
cmp eax, 100
|
|
|
|
|
jb .no
|
|
|
|
|
.yes:
|
|
|
|
|
xor eax, eax
|
|
|
|
|
inc eax
|
|
|
|
|
ret
|
|
|
|
|
.no:
|
|
|
|
|
xor eax, eax
|
|
|
|
|
ret
|
|
|
|
|
endp
|
|
|
|
|
|
2010-10-01 11:21:55 +02:00
|
|
|
|
align 4
|
|
|
|
|
check_ATAPI_device_event:
|
|
|
|
|
pusha
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov eax, [timer_ticks]
|
|
|
|
|
sub eax, [timer_ATAPI_check]
|
|
|
|
|
cmp eax, 100
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jb .end_1
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov al, [DRIVE_DATA+1]
|
|
|
|
|
and al, 11b
|
|
|
|
|
cmp al, 10b
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jz .ide3
|
2010-10-01 11:21:55 +02:00
|
|
|
|
.ide2_1:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov al, [DRIVE_DATA+1]
|
|
|
|
|
and al, 1100b
|
|
|
|
|
cmp al, 1000b
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jz .ide2
|
2010-10-01 11:21:55 +02:00
|
|
|
|
.ide1_1:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov al, [DRIVE_DATA+1]
|
|
|
|
|
and al, 110000b
|
|
|
|
|
cmp al, 100000b
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jz .ide1
|
2010-10-01 11:21:55 +02:00
|
|
|
|
.ide0_1:
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov al, [DRIVE_DATA+1]
|
|
|
|
|
and al, 11000000b
|
|
|
|
|
cmp al, 10000000b
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jz .ide0
|
2010-10-01 11:21:55 +02:00
|
|
|
|
.end:
|
|
|
|
|
|
2013-05-28 21:09:31 +02:00
|
|
|
|
sti
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov eax, [timer_ticks]
|
|
|
|
|
mov [timer_ATAPI_check], eax
|
2010-10-01 11:21:55 +02:00
|
|
|
|
.end_1:
|
|
|
|
|
popa
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
.ide3:
|
2013-05-28 21:09:31 +02:00
|
|
|
|
cli
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [ATAPI_IDE3_lock], 1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jne .ide2_1
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [IDE_Channel_2], 0
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jne .ide1_1
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [cd_status], 0
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jne .end
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [IDE_Channel_2], 1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
call reserve_ok2
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [ChannelNumber], 2
|
|
|
|
|
mov [DiskNumber], 1
|
|
|
|
|
mov [cdpos], 4
|
2013-05-28 21:09:31 +02:00
|
|
|
|
call GetEvent_StatusNotification
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [CDDataBuf+4], byte 1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
je .eject_ide3
|
|
|
|
|
call syscall_cdaudio.free
|
|
|
|
|
jmp .ide2_1
|
2010-10-01 11:21:55 +02:00
|
|
|
|
.eject_ide3:
|
2013-05-28 21:09:31 +02:00
|
|
|
|
call .eject
|
|
|
|
|
call syscall_cdaudio.free
|
|
|
|
|
jmp .ide2_1
|
2010-10-01 11:21:55 +02:00
|
|
|
|
|
|
|
|
|
.ide2:
|
2013-05-28 21:09:31 +02:00
|
|
|
|
cli
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [ATAPI_IDE2_lock], 1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jne .ide1_1
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [IDE_Channel_2], 0
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jne .ide1_1
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [cd_status], 0
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jne .end
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [IDE_Channel_2], 1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
call reserve_ok2
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [ChannelNumber], 2
|
|
|
|
|
mov [DiskNumber], 0
|
|
|
|
|
mov [cdpos], 3
|
2013-05-28 21:09:31 +02:00
|
|
|
|
call GetEvent_StatusNotification
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [CDDataBuf+4], byte 1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
je .eject_ide2
|
|
|
|
|
call syscall_cdaudio.free
|
|
|
|
|
jmp .ide1_1
|
2010-10-01 11:21:55 +02:00
|
|
|
|
.eject_ide2:
|
2013-05-28 21:09:31 +02:00
|
|
|
|
call .eject
|
|
|
|
|
call syscall_cdaudio.free
|
|
|
|
|
jmp .ide1_1
|
2010-10-01 11:21:55 +02:00
|
|
|
|
|
|
|
|
|
.ide1:
|
2013-05-28 21:09:31 +02:00
|
|
|
|
cli
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [ATAPI_IDE1_lock], 1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jne .ide0_1
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [IDE_Channel_1], 0
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jne .end
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [cd_status], 0
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jne .end
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [IDE_Channel_1], 1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
call reserve_ok2
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [ChannelNumber], 1
|
|
|
|
|
mov [DiskNumber], 1
|
|
|
|
|
mov [cdpos], 2
|
2013-05-28 21:09:31 +02:00
|
|
|
|
call GetEvent_StatusNotification
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [CDDataBuf+4], byte 1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
je .eject_ide1
|
|
|
|
|
call syscall_cdaudio.free
|
|
|
|
|
jmp .ide0_1
|
2010-10-01 11:21:55 +02:00
|
|
|
|
.eject_ide1:
|
2013-05-28 21:09:31 +02:00
|
|
|
|
call .eject
|
|
|
|
|
call syscall_cdaudio.free
|
|
|
|
|
jmp .ide0_1
|
2010-10-01 11:21:55 +02:00
|
|
|
|
|
|
|
|
|
.ide0:
|
2013-05-28 21:09:31 +02:00
|
|
|
|
cli
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [ATAPI_IDE0_lock], 1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jne .end
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [IDE_Channel_1], 0
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jne .end
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [cd_status], 0
|
2013-05-28 21:09:31 +02:00
|
|
|
|
jne .end
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [IDE_Channel_1], 1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
call reserve_ok2
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [ChannelNumber], 1
|
|
|
|
|
mov [DiskNumber], 0
|
|
|
|
|
mov [cdpos], 1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
call GetEvent_StatusNotification
|
2012-03-08 09:33:38 +01:00
|
|
|
|
cmp [CDDataBuf+4], byte 1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
je .eject_ide0
|
|
|
|
|
call syscall_cdaudio.free
|
|
|
|
|
jmp .end
|
2010-10-01 11:21:55 +02:00
|
|
|
|
.eject_ide0:
|
2013-05-28 21:09:31 +02:00
|
|
|
|
call .eject
|
|
|
|
|
call syscall_cdaudio.free
|
|
|
|
|
jmp .end
|
2010-10-01 11:21:55 +02:00
|
|
|
|
|
|
|
|
|
.eject:
|
2013-05-28 21:09:31 +02:00
|
|
|
|
call clear_CD_cache
|
|
|
|
|
call allow_medium_removal
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [ignore_CD_eject_wait], 1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
call EjectMedium
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [ignore_CD_eject_wait], 0
|
2010-10-01 11:21:55 +02:00
|
|
|
|
ret
|
|
|
|
|
iglobal
|
|
|
|
|
timer_ATAPI_check dd 0
|
|
|
|
|
ATAPI_IDE0_lock db 0
|
|
|
|
|
ATAPI_IDE1_lock db 0
|
|
|
|
|
ATAPI_IDE2_lock db 0
|
|
|
|
|
ATAPI_IDE3_lock db 0
|
|
|
|
|
ignore_CD_eject_wait db 0
|
|
|
|
|
endg
|
|
|
|
|
;*************************************************
|
2013-05-28 21:09:31 +02:00
|
|
|
|
;* Получить сообщение о событии или состоянии *
|
|
|
|
|
;* устройства *
|
|
|
|
|
;* Входные параметры передаются через глобальные *
|
|
|
|
|
;* переменные: *
|
|
|
|
|
;* ChannelNumber - номер канала; *
|
|
|
|
|
;* DiskNumber - номер диска на канале. *
|
2010-10-01 11:21:55 +02:00
|
|
|
|
;*************************************************
|
|
|
|
|
GetEvent_StatusNotification:
|
|
|
|
|
pusha
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [CDDataBuf_pointer], CDDataBuf
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Очистить буфер пакетной команды
|
|
|
|
|
call clear_packet_buffer
|
|
|
|
|
; Задать код команды
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [PacketCommand], byte 4Ah
|
|
|
|
|
mov [PacketCommand+1], byte 00000001b
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Задать запрос класса сообщений
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [PacketCommand+4], byte 00010000b
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Размер выделенной области
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [PacketCommand+7], byte 8h
|
|
|
|
|
mov [PacketCommand+8], byte 0h
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Подать команду
|
2010-10-01 11:21:55 +02:00
|
|
|
|
call SendPacketDatCommand
|
|
|
|
|
popa
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*************************************************
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; прочитать информацию из TOC
|
|
|
|
|
;* Входные параметры передаются через глобальные *
|
|
|
|
|
;* переменные: *
|
|
|
|
|
;* ChannelNumber - номер канала; *
|
|
|
|
|
;* DiskNumber - номер диска на канале. *
|
2010-10-01 11:21:55 +02:00
|
|
|
|
;*************************************************
|
|
|
|
|
Read_TOC:
|
|
|
|
|
pusha
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [CDDataBuf_pointer], CDDataBuf
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Очистить буфер пакетной команды
|
|
|
|
|
call clear_packet_buffer
|
|
|
|
|
; Сформировать пакетную команду для считывания
|
|
|
|
|
; сектора данных
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [PacketCommand], byte 0x43
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Задать формат
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [PacketCommand+2], byte 1
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Размер выделенной области
|
2012-03-08 09:33:38 +01:00
|
|
|
|
mov [PacketCommand+7], byte 0xFF
|
|
|
|
|
mov [PacketCommand+8], byte 0h
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Подать команду
|
|
|
|
|
call SendPacketDatCommand
|
2010-10-01 11:21:55 +02:00
|
|
|
|
popa
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*************************************************
|
2013-05-28 21:09:31 +02:00
|
|
|
|
;* ОПРЕДЕЛИТЬ ОБЩЕЕ КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ *
|
|
|
|
|
;* Входные параметры передаются через глобальные *
|
|
|
|
|
;* переменные: *
|
|
|
|
|
;* ChannelNumber - номер канала; *
|
|
|
|
|
;* DiskNumber - номер диска на канале. *
|
2010-10-01 11:21:55 +02:00
|
|
|
|
;*************************************************
|
|
|
|
|
;ReadCapacity:
|
|
|
|
|
; pusha
|
2013-05-28 21:09:31 +02:00
|
|
|
|
;; Очистить буфер пакетной команды
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; call clear_packet_buffer
|
2013-05-28 21:09:31 +02:00
|
|
|
|
;; Задать размер буфера в байтах
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; mov [CDBlockSize],8
|
2013-05-28 21:09:31 +02:00
|
|
|
|
;; Сформировать команду READ CAPACITY
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; mov [PacketCommand],word 25h
|
2013-05-28 21:09:31 +02:00
|
|
|
|
;; Подать команду
|
2010-10-01 11:21:55 +02:00
|
|
|
|
; call SendPacketDatCommand
|
|
|
|
|
; popa
|
|
|
|
|
; ret
|
|
|
|
|
|
|
|
|
|
clear_packet_buffer:
|
2013-05-28 21:09:31 +02:00
|
|
|
|
; Очистить буфер пакетной команды
|
2012-03-08 09:33:38 +01:00
|
|
|
|
and [PacketCommand], dword 0
|
|
|
|
|
and [PacketCommand+4], dword 0
|
|
|
|
|
and [PacketCommand+8], dword 0
|
2010-10-01 11:21:55 +02:00
|
|
|
|
ret
|