forked from KolibriOS/kolibrios
translate russian comments to english #5, no code changes
git-svn-id: svn://kolibrios.org@8054 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
cdf87e6a72
commit
d1e7997956
@ -9,7 +9,7 @@ $Revision$
|
|||||||
|
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
;**********************************************************
|
;**********************************************************
|
||||||
; Direct work with СD (ATAPI) device
|
; Direct work with CD (ATAPI) device
|
||||||
;**********************************************************
|
;**********************************************************
|
||||||
; Author of a part of the source code - Kulakov Vladimir Gennadievich
|
; Author of a part of the source code - Kulakov Vladimir Gennadievich
|
||||||
; Adaptation, revision and development - Mario79, <Lrz>
|
; Adaptation, revision and development - Mario79, <Lrz>
|
||||||
@ -22,8 +22,8 @@ BSYWaitTime = 1000 ;2
|
|||||||
NoTickWaitTime = 0xfffff
|
NoTickWaitTime = 0xfffff
|
||||||
CDBlockSize = 2048
|
CDBlockSize = 2048
|
||||||
;********************************************
|
;********************************************
|
||||||
;* ЧТЕНИЕ СЕКТОРА С ПОВТОРАМИ *
|
;* READING SECTOR WITH REPEATS *
|
||||||
;* Многократное повторение чтения при сбоях *
|
;* Repeated reads on failures *
|
||||||
;********************************************
|
;********************************************
|
||||||
ReadCDWRetr:
|
ReadCDWRetr:
|
||||||
;-----------------------------------------------------------
|
;-----------------------------------------------------------
|
||||||
@ -86,42 +86,40 @@ align 4
|
|||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
ReadCDWRetr_1:
|
ReadCDWRetr_1:
|
||||||
pushad
|
pushad
|
||||||
; Цикл, пока команда не выполнена успешно или не
|
; Loop until the command is successful or the number of attempts is over
|
||||||
; исчерпано количество попыток
|
|
||||||
mov ecx, MaxRetr
|
mov ecx, MaxRetr
|
||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
align 4
|
align 4
|
||||||
@@NextRetr:
|
@@NextRetr:
|
||||||
; Подать команду
|
; Send a command
|
||||||
;*************************************************
|
;*************************************************
|
||||||
;* ПОЛНОЕ ЧТЕНИЕ СЕКТОРА КОМПАКТ-ДИСКА *
|
;* FULL READ OF COMPACT DISK SECTOR *
|
||||||
;* Считываются данные пользователя, информация *
|
;* User data, subchannel *
|
||||||
;* субканала и контрольная информация *
|
;* information and control information are read *
|
||||||
;* Входные параметры передаются через глобальные *
|
;* Input parameters are passed through global *
|
||||||
;* перменные: *
|
;* variables: *
|
||||||
;* ChannelNumber - номер канала; *
|
;* ChannelNumber - channel number; *
|
||||||
;* DiskNumber - номер диска на канале; *
|
;* DiskNumber - disc number on channel; *
|
||||||
;* CDSectorAddress - адрес считываемого сектора. *
|
;* CDSectorAddress - address of reading sector. *
|
||||||
;* Данные считывается в массив CDDataBuf. *
|
;* The data is read into the CDDataBuf array. *
|
||||||
;*************************************************
|
;*************************************************
|
||||||
;ReadCD:
|
;ReadCD:
|
||||||
push ecx
|
push ecx
|
||||||
; Очистить буфер пакетной команды
|
; Flush the packet command buffer
|
||||||
call clear_packet_buffer
|
call clear_packet_buffer
|
||||||
; Сформировать пакетную команду для считывания
|
; Generate a packet command to read a data sector
|
||||||
; сектора данных
|
; Set the command code Read CD
|
||||||
; Задать код команды Read CD
|
|
||||||
mov [PacketCommand], byte 0x28 ;0xBE
|
mov [PacketCommand], byte 0x28 ;0xBE
|
||||||
; Задать адрес сектора
|
; Set the sector address
|
||||||
mov ax, word [CDSectorAddress+2]
|
mov ax, word [CDSectorAddress+2]
|
||||||
xchg al, ah
|
xchg al, ah
|
||||||
mov word [PacketCommand+2], ax
|
mov word [PacketCommand+2], ax
|
||||||
mov ax, word [CDSectorAddress]
|
mov ax, word [CDSectorAddress]
|
||||||
xchg al, ah
|
xchg al, ah
|
||||||
mov word [PacketCommand+4], ax
|
mov word [PacketCommand+4], ax
|
||||||
; Задать количество считываемых секторов
|
; Set the number of sectors to read
|
||||||
mov [PacketCommand+8], byte 1
|
mov [PacketCommand+8], byte 1
|
||||||
; Подать команду
|
; Send a command
|
||||||
call SendPacketDatCommand
|
call SendPacketDatCommand
|
||||||
pop ecx
|
pop ecx
|
||||||
|
|
||||||
@ -154,57 +152,54 @@ align 4
|
|||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
; Универсальные процедуры, обеспечивающие выполнение
|
; General purpose procedures to execute packet commands in PIO Mode
|
||||||
; пакетных команд в режиме PIO
|
; Maximum allowable waiting time for the device to respond to a packet command (in ticks)
|
||||||
; Максимально допустимое время ожидания реакции
|
|
||||||
; устройства на пакетную команду (в тиках)
|
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
MaxCDWaitTime = 1000 ;200 ;10 секунд
|
MaxCDWaitTime = 1000 ;200 ;10 seconds
|
||||||
uglobal
|
uglobal
|
||||||
; Область памяти для формирования пакетной команды
|
; Memory area for generating a packet command
|
||||||
PacketCommand:
|
PacketCommand:
|
||||||
rb 12 ;DB 12 DUP (?)
|
rb 12 ;DB 12 DUP (?)
|
||||||
; Адрес считываемого сектора данных
|
; address of reading data sector
|
||||||
CDSectorAddress: dd ?
|
CDSectorAddress: dd ?
|
||||||
; Время начала очередной операции с диском
|
; Start time of the next disk operation
|
||||||
TickCounter_1 dd 0
|
TickCounter_1 dd 0
|
||||||
; Время начала ожидания готовности устройства
|
; Time to start waiting for device readiness
|
||||||
WURStartTime dd 0
|
WURStartTime dd 0
|
||||||
; указатель буфера для считывания
|
; pointer to buffer to read data into
|
||||||
CDDataBuf_pointer dd 0
|
CDDataBuf_pointer dd 0
|
||||||
endg
|
endg
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
;****************************************************
|
;****************************************************
|
||||||
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
|
;* SEND TO ATAPI DEVICE PACKET COMMAND, *
|
||||||
;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ *
|
;* THAT MEANS TRASMIT ONE DATA SECTOR OF SIZE *
|
||||||
;* РАЗМЕРОМ 2048 БАЙТ ОТ УСТРОЙСТВА К ХОСТУ *
|
;* 2048 BYTE FROM DEVICE TO HOST *
|
||||||
;* Входные параметры передаются через глобальные *
|
;* Input parameters are passed through global *
|
||||||
;* перменные: *
|
;* variables: *
|
||||||
;* ChannelNumber - номер канала; *
|
;* ChannelNumber - channel number; *
|
||||||
;* DiskNumber - номер диска на канале; *
|
;* DiskNumber - disk number on channel. *
|
||||||
;* PacketCommand - 12-байтный командный пакет; *
|
;* PacketCommand - 12-byte command packet; *
|
||||||
;* CDBlockSize - размер принимаемого блока данных. *
|
;* CDBlockSize - size of receiving data block. *
|
||||||
; return eax DevErrorCode
|
; return eax DevErrorCode
|
||||||
;****************************************************
|
;****************************************************
|
||||||
SendPacketDatCommand:
|
SendPacketDatCommand:
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
; Задать режим CHS
|
; Set CHS mode
|
||||||
mov byte [ATAAddressMode], al
|
mov byte [ATAAddressMode], al
|
||||||
; Послать ATA-команду передачи пакетной команды
|
; Send ATA command to send packet command
|
||||||
mov byte [ATAFeatures], al
|
mov byte [ATAFeatures], al
|
||||||
mov byte [ATASectorCount], al
|
mov byte [ATASectorCount], al
|
||||||
mov byte [ATASectorNumber], al
|
mov byte [ATASectorNumber], al
|
||||||
; Загрузить размер передаваемого блока
|
; Load the size of the sending block
|
||||||
mov [ATAHead], al
|
mov [ATAHead], al
|
||||||
mov [ATACylinder], CDBlockSize
|
mov [ATACylinder], CDBlockSize
|
||||||
mov [ATACommand], 0xA0
|
mov [ATACommand], 0xA0
|
||||||
call SendCommandToHDD_1
|
call SendCommandToHDD_1
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jnz @@End_8 ;закончить, сохранив код ошибки
|
jnz @@End_8 ; finish, saving the error code
|
||||||
; Ожидание готовности дисковода к приему
|
; Waiting for the drive to be ready to receive a packet command
|
||||||
; пакетной команды
|
|
||||||
mov dx, [ATABasePortAddr]
|
mov dx, [ATABasePortAddr]
|
||||||
add dx, 7 ;порт 1х7h
|
add dx, 7 ; port 1x7h
|
||||||
mov ecx, NoTickWaitTime
|
mov ecx, NoTickWaitTime
|
||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
align 4
|
align 4
|
||||||
@ -220,25 +215,25 @@ align 4
|
|||||||
align 4
|
align 4
|
||||||
@@:
|
@@:
|
||||||
call change_task
|
call change_task
|
||||||
; Проверить время выполнения команды
|
; Check command execution time
|
||||||
mov eax, [timer_ticks]
|
mov eax, [timer_ticks]
|
||||||
sub eax, [TickCounter_1]
|
sub eax, [TickCounter_1]
|
||||||
cmp eax, BSYWaitTime
|
cmp eax, BSYWaitTime
|
||||||
ja @@Err1_1 ;ошибка тайм-аута
|
ja @@Err1_1 ; time out error
|
||||||
; Проверить готовность
|
; Check readiness
|
||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
align 4
|
align 4
|
||||||
.test:
|
.test:
|
||||||
in al, dx
|
in al, dx
|
||||||
test al, 0x80 ;состояние сигнала BSY
|
test al, 0x80 ; BSY signal state
|
||||||
jnz @@WaitDevice0
|
jnz @@WaitDevice0
|
||||||
|
|
||||||
test al, 1 ;состояние сигнала ERR
|
test al, 1 ; ERR signal state
|
||||||
jnz @@Err6
|
jnz @@Err6
|
||||||
|
|
||||||
test al, 0x8 ;состояние сигнала DRQ
|
test al, 0x8 ; DRQ signal state
|
||||||
jz @@WaitDevice0
|
jz @@WaitDevice0
|
||||||
; Послать пакетную команду
|
; Send a packet command
|
||||||
cli
|
cli
|
||||||
mov dx, [ATABasePortAddr]
|
mov dx, [ATABasePortAddr]
|
||||||
mov ax, [PacketCommand]
|
mov ax, [PacketCommand]
|
||||||
@ -254,9 +249,9 @@ align 4
|
|||||||
mov ax, [PacketCommand+10]
|
mov ax, [PacketCommand+10]
|
||||||
out dx, ax
|
out dx, ax
|
||||||
sti
|
sti
|
||||||
; Ожидание готовности данных
|
; Waiting for data to be ready
|
||||||
mov dx, [ATABasePortAddr]
|
mov dx, [ATABasePortAddr]
|
||||||
add dx, 7 ;порт 1х7h
|
add dx, 7 ; port 1x7h
|
||||||
mov ecx, NoTickWaitTime
|
mov ecx, NoTickWaitTime
|
||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
align 4
|
align 4
|
||||||
@ -272,45 +267,45 @@ align 4
|
|||||||
align 4
|
align 4
|
||||||
@@:
|
@@:
|
||||||
call change_task
|
call change_task
|
||||||
; Проверить время выполнения команды
|
; Check command execution time
|
||||||
mov eax, [timer_ticks]
|
mov eax, [timer_ticks]
|
||||||
sub eax, [TickCounter_1]
|
sub eax, [TickCounter_1]
|
||||||
cmp eax, MaxCDWaitTime
|
cmp eax, MaxCDWaitTime
|
||||||
ja @@Err1_1 ;ошибка тайм-аута
|
ja @@Err1_1 ; time out error
|
||||||
; Проверить готовность
|
; Check readiness
|
||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
align 4
|
align 4
|
||||||
.test_1:
|
.test_1:
|
||||||
in al, dx
|
in al, dx
|
||||||
test al, 0x80 ;состояние сигнала BSY
|
test al, 0x80 ; BSY signal state
|
||||||
jnz @@WaitDevice1
|
jnz @@WaitDevice1
|
||||||
|
|
||||||
test al, 1 ;состояние сигнала ERR
|
test al, 1 ; ERR signal state
|
||||||
jnz @@Err6_temp
|
jnz @@Err6_temp
|
||||||
|
|
||||||
test al, 0x8 ;состояние сигнала DRQ
|
test al, 0x8 ; DRQ signal state
|
||||||
jz @@WaitDevice1
|
jz @@WaitDevice1
|
||||||
; Принять блок данных от контроллера
|
; Receive data block from controller
|
||||||
mov edi, [CDDataBuf_pointer]
|
mov edi, [CDDataBuf_pointer]
|
||||||
; Загрузить адрес регистра данных контроллера
|
; Load controller's data register address
|
||||||
mov dx, [ATABasePortAddr]
|
mov dx, [ATABasePortAddr]
|
||||||
; Загрузить в счетчик размер блока в байтах
|
; Load the block size in bytes into the counter
|
||||||
xor ecx, ecx
|
xor ecx, ecx
|
||||||
mov cx, CDBlockSize
|
mov cx, CDBlockSize
|
||||||
; Вычислить размер блока в 16-разрядных словах
|
; Calculate block size in 16-bit words
|
||||||
shr cx, 1 ;разделить размер блока на 2
|
shr cx, 1 ; divide block size by 2
|
||||||
; Принять блок данных
|
; Receive data block
|
||||||
cli
|
cli
|
||||||
cld
|
cld
|
||||||
rep insw
|
rep insw
|
||||||
sti
|
sti
|
||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
; Успешное завершение приема данных
|
; Successful completion of data receive
|
||||||
@@End_8:
|
@@End_8:
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
; Записать код ошибки
|
; Write error code
|
||||||
@@Err1_1:
|
@@Err1_1:
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
inc eax
|
inc eax
|
||||||
@ -325,20 +320,20 @@ align 4
|
|||||||
ret
|
ret
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
;***********************************************
|
;***********************************************
|
||||||
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, *
|
;* SEND TO ATAPI DEVICE PACKET COMMAND, *
|
||||||
;* НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ *
|
;* THAT DOESNT MEAN TRANSMIT DATA *
|
||||||
;* Входные параметры передаются через *
|
;* Input parameters are passed through global *
|
||||||
;* глобальные перменные: *
|
;* variables: *
|
||||||
;* ChannelNumber - номер канала; *
|
;* ChannelNumber - channel number; *
|
||||||
;* DiskNumber - номер диска на канале; *
|
;* DiskNumber - disk number on channel. *
|
||||||
;* PacketCommand - 12-байтный командный пакет. *
|
;* PacketCommand - 12-byte command packet. *
|
||||||
;***********************************************
|
;***********************************************
|
||||||
SendPacketNoDatCommand:
|
SendPacketNoDatCommand:
|
||||||
pushad
|
pushad
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
; Задать режим CHS
|
; Set CHS mode
|
||||||
mov byte [ATAAddressMode], al
|
mov byte [ATAAddressMode], al
|
||||||
; Послать ATA-команду передачи пакетной команды
|
; Send ATA command to send packet command
|
||||||
mov byte [ATAFeatures], al
|
mov byte [ATAFeatures], al
|
||||||
mov byte [ATASectorCount], al
|
mov byte [ATASectorCount], al
|
||||||
mov byte [ATASectorNumber], al
|
mov byte [ATASectorNumber], al
|
||||||
@ -347,31 +342,30 @@ SendPacketNoDatCommand:
|
|||||||
mov [ATACommand], 0xA0
|
mov [ATACommand], 0xA0
|
||||||
call SendCommandToHDD_1
|
call SendCommandToHDD_1
|
||||||
test eax, eax
|
test eax, eax
|
||||||
jnz @@End_9 ;закончить, сохранив код ошибки
|
jnz @@End_9 ; finish, saving the error code
|
||||||
; Ожидание готовности дисковода к приему
|
; Waiting for the drive to be ready to receive a packet command
|
||||||
; пакетной команды
|
|
||||||
mov dx, [ATABasePortAddr]
|
mov dx, [ATABasePortAddr]
|
||||||
add dx, 7 ;порт 1х7h
|
add dx, 7 ; port 1x7h
|
||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
align 4
|
align 4
|
||||||
@@WaitDevice0_1:
|
@@WaitDevice0_1:
|
||||||
call change_task
|
call change_task
|
||||||
; Проверить время ожидания
|
; Check waiting time
|
||||||
mov eax, [timer_ticks]
|
mov eax, [timer_ticks]
|
||||||
sub eax, [TickCounter_1]
|
sub eax, [TickCounter_1]
|
||||||
cmp eax, BSYWaitTime
|
cmp eax, BSYWaitTime
|
||||||
ja @@Err1_3 ;ошибка тайм-аута
|
ja @@Err1_3 ; time out error
|
||||||
; Проверить готовность
|
; Check readiness
|
||||||
in al, dx
|
in al, dx
|
||||||
test al, 0x80 ;состояние сигнала BSY
|
test al, 0x80 ; BSY signal state
|
||||||
jnz @@WaitDevice0_1
|
jnz @@WaitDevice0_1
|
||||||
|
|
||||||
test al, 1 ;состояние сигнала ERR
|
test al, 1 ; ERR signal state
|
||||||
jnz @@Err6_1
|
jnz @@Err6_1
|
||||||
|
|
||||||
test al, 0x8 ;состояние сигнала DRQ
|
test al, 0x8 ; DRQ signal state
|
||||||
jz @@WaitDevice0_1
|
jz @@WaitDevice0_1
|
||||||
; Послать пакетную команду
|
; Send packet command
|
||||||
; cli
|
; cli
|
||||||
mov dx, [ATABasePortAddr]
|
mov dx, [ATABasePortAddr]
|
||||||
mov ax, word [PacketCommand]
|
mov ax, word [PacketCommand]
|
||||||
@ -389,27 +383,27 @@ align 4
|
|||||||
; sti
|
; sti
|
||||||
cmp [ignore_CD_eject_wait], 1
|
cmp [ignore_CD_eject_wait], 1
|
||||||
je @@clear_DEC
|
je @@clear_DEC
|
||||||
; Ожидание подтверждения приема команды
|
; Waiting for confirmation of command receive
|
||||||
mov dx, [ATABasePortAddr]
|
mov dx, [ATABasePortAddr]
|
||||||
add dx, 7 ;порт 1х7h
|
add dx, 7 ; port 1x7h
|
||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
align 4
|
align 4
|
||||||
@@WaitDevice1_1:
|
@@WaitDevice1_1:
|
||||||
call change_task
|
call change_task
|
||||||
; Проверить время выполнения команды
|
; Check command execution time
|
||||||
mov eax, [timer_ticks]
|
mov eax, [timer_ticks]
|
||||||
sub eax, [TickCounter_1]
|
sub eax, [TickCounter_1]
|
||||||
cmp eax, MaxCDWaitTime
|
cmp eax, MaxCDWaitTime
|
||||||
ja @@Err1_3 ;ошибка тайм-аута
|
ja @@Err1_3 ; time out error
|
||||||
; Ожидать освобождения устройства
|
; Wait for device release
|
||||||
in al, dx
|
in al, dx
|
||||||
test al, 0x80 ;состояние сигнала BSY
|
test al, 0x80 ; BSY signal state
|
||||||
jnz @@WaitDevice1_1
|
jnz @@WaitDevice1_1
|
||||||
|
|
||||||
test al, 1 ;состояние сигнала ERR
|
test al, 1 ; ERR signal state
|
||||||
jnz @@Err6_1
|
jnz @@Err6_1
|
||||||
|
|
||||||
test al, 0x40 ;состояние сигнала DRDY
|
test al, 0x40 ; DRDY signal state
|
||||||
jz @@WaitDevice1_1
|
jz @@WaitDevice1_1
|
||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
@@clear_DEC:
|
@@clear_DEC:
|
||||||
@ -417,7 +411,7 @@ align 4
|
|||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
; Записать код ошибки
|
; Write error code
|
||||||
@@Err1_3:
|
@@Err1_3:
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
inc eax
|
inc eax
|
||||||
@ -432,34 +426,34 @@ align 4
|
|||||||
ret
|
ret
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
;****************************************************
|
;****************************************************
|
||||||
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ *
|
;* SEND COMMAND TO GIVEN DISK *
|
||||||
;* Входные параметры передаются через глобальные *
|
;* Input parameters are passed through the global *
|
||||||
;* переменные: *
|
;* variables: *
|
||||||
;* ChannelNumber - номер канала (1 или 2); *
|
;* ChannelNumber - channel number (1 or 2); *
|
||||||
;* DiskNumber - номер диска (0 или 1); *
|
;* DiskNumber - disk number (0 or 1); *
|
||||||
;* ATAFeatures - "особенности"; *
|
;* ATAFeatures - "features"; *
|
||||||
;* ATASectorCount - количество секторов; *
|
;* ATASectorCount - sector count; *
|
||||||
;* ATASectorNumber - номер начального сектора; *
|
;* ATASectorNumber - initial sector number; *
|
||||||
;* ATACylinder - номер начального цилиндра; *
|
;* ATACylinder - initial cylinder number; *
|
||||||
;* ATAHead - номер начальной головки; *
|
;* ATAHead - initial head number; *
|
||||||
;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); *
|
;* ATAAddressMode - addressing mode (0-CHS, 1-LBA); *
|
||||||
;* ATACommand - код команды. *
|
;* ATACommand - command code. *
|
||||||
;* После успешного выполнения функции: *
|
;* If the function finished successfully: *
|
||||||
;* в ATABasePortAddr - базовый адрес HDD; *
|
;* in ATABasePortAddr - base address of HDD; *
|
||||||
;* в DevErrorCode - ноль. *
|
;* in DevErrorCode - zero. *
|
||||||
;* При возникновении ошибки в DevErrorCode будет *
|
;* If error has occured then in DevErrorCode will *
|
||||||
;* возвращен код ошибки в eax *
|
;* be the error code. *
|
||||||
;****************************************************
|
;****************************************************
|
||||||
SendCommandToHDD_1:
|
SendCommandToHDD_1:
|
||||||
; Проверить значение кода режима
|
; Check the addressing mode code
|
||||||
cmp [ATAAddressMode], 1
|
cmp [ATAAddressMode], 1
|
||||||
ja @@Err2_4
|
ja @@Err2_4
|
||||||
; Проверить корректность номера канала
|
; Check the channel number correctness
|
||||||
movzx ebx, [ChannelNumber]
|
movzx ebx, [ChannelNumber]
|
||||||
dec ebx
|
dec ebx
|
||||||
cmp ebx, 1
|
cmp ebx, 1
|
||||||
ja @@Err3_4
|
ja @@Err3_4
|
||||||
; Установить базовый адрес
|
; Set the base address
|
||||||
shl ebx, 2
|
shl ebx, 2
|
||||||
mov eax, [cdpos]
|
mov eax, [cdpos]
|
||||||
dec eax
|
dec eax
|
||||||
@ -469,18 +463,18 @@ SendCommandToHDD_1:
|
|||||||
add eax, ebx
|
add eax, ebx
|
||||||
mov ax, [eax+IDE_DATA.BAR0_val]
|
mov ax, [eax+IDE_DATA.BAR0_val]
|
||||||
mov [ATABasePortAddr], ax
|
mov [ATABasePortAddr], ax
|
||||||
; Ожидание готовности HDD к приему команды
|
; Waiting for HDD ready to receive a command
|
||||||
; Выбрать нужный диск
|
; Choose desired disk
|
||||||
mov dx, [ATABasePortAddr]
|
mov dx, [ATABasePortAddr]
|
||||||
add dx, 6 ;адрес регистра головок
|
add dx, 6 ; address of the heads register
|
||||||
mov al, [DiskNumber]
|
mov al, [DiskNumber]
|
||||||
cmp al, 1 ;проверить номера диска
|
cmp al, 1 ; check the disk number
|
||||||
ja @@Err4_4
|
ja @@Err4_4
|
||||||
|
|
||||||
shl al, 4
|
shl al, 4
|
||||||
or al, 10100000b
|
or al, 10100000b
|
||||||
out dx, al
|
out dx, al
|
||||||
; Ожидать, пока диск не будет готов
|
; Waiting for disk ready
|
||||||
inc dx
|
inc dx
|
||||||
mov eax, [timer_ticks]
|
mov eax, [timer_ticks]
|
||||||
mov [TickCounter_1], eax
|
mov [TickCounter_1], eax
|
||||||
@ -499,43 +493,43 @@ align 4
|
|||||||
align 4
|
align 4
|
||||||
@@:
|
@@:
|
||||||
call change_task
|
call change_task
|
||||||
; Проверить время ожидания
|
; Check waiting time
|
||||||
mov eax, [timer_ticks]
|
mov eax, [timer_ticks]
|
||||||
sub eax, [TickCounter_1]
|
sub eax, [TickCounter_1]
|
||||||
cmp eax, BSYWaitTime ;300 ;ожидать 3 сек.
|
cmp eax, BSYWaitTime ;300 ; wait for 3 seconds
|
||||||
ja @@Err1_4 ;ошибка тайм-аута
|
ja @@Err1_4 ; time out error
|
||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
align 4
|
align 4
|
||||||
.test:
|
.test:
|
||||||
in al, dx ; Прочитать регистр состояния
|
in al, dx ; Read the state register
|
||||||
; Проверить состояние сигнала BSY
|
; Check the state of BSY signal
|
||||||
test al, 0x80
|
test al, 0x80
|
||||||
jnz @@WaitHDReady_2
|
jnz @@WaitHDReady_2
|
||||||
; Проверить состояние сигнала DRQ
|
; Check the state of DRQ signal
|
||||||
test al, 0x8
|
test al, 0x8
|
||||||
jnz @@WaitHDReady_2
|
jnz @@WaitHDReady_2
|
||||||
; Загрузить команду в регистры контроллера
|
; load command to controller's registers
|
||||||
cli
|
cli
|
||||||
mov dx, [ATABasePortAddr]
|
mov dx, [ATABasePortAddr]
|
||||||
inc dx ;регистр "особенностей"
|
inc dx ; "features" register
|
||||||
mov al, [ATAFeatures]
|
mov al, [ATAFeatures]
|
||||||
out dx, al
|
out dx, al
|
||||||
inc dx ;счетчик секторов
|
inc dx ; sector counter
|
||||||
mov al, [ATASectorCount]
|
mov al, [ATASectorCount]
|
||||||
out dx, al
|
out dx, al
|
||||||
inc dx ;регистр номера сектора
|
inc dx ; sector number register
|
||||||
mov al, [ATASectorNumber]
|
mov al, [ATASectorNumber]
|
||||||
out dx, al
|
out dx, al
|
||||||
inc dx ;номер цилиндра (младший байт)
|
inc dx ; cylinder number (low byte)
|
||||||
mov ax, [ATACylinder]
|
mov ax, [ATACylinder]
|
||||||
out dx, al
|
out dx, al
|
||||||
inc dx ;номер цилиндра (старший байт)
|
inc dx ; cylinder number (high byte)
|
||||||
mov al, ah
|
mov al, ah
|
||||||
out dx, al
|
out dx, al
|
||||||
inc dx ;номер головки/номер диска
|
inc dx ; head number / disk number
|
||||||
mov al, [DiskNumber]
|
mov al, [DiskNumber]
|
||||||
shl al, 4
|
shl al, 4
|
||||||
cmp [ATAHead], 0xF ;проверить номер головки
|
cmp [ATAHead], 0xF ; check head number
|
||||||
ja @@Err5_4
|
ja @@Err5_4
|
||||||
|
|
||||||
or al, [ATAHead]
|
or al, [ATAHead]
|
||||||
@ -544,9 +538,9 @@ align 4
|
|||||||
shl ah, 6
|
shl ah, 6
|
||||||
or al, ah
|
or al, ah
|
||||||
out dx, al
|
out dx, al
|
||||||
; Послать команду
|
; Send command
|
||||||
mov al, [ATACommand]
|
mov al, [ATACommand]
|
||||||
inc dx ;регистр команд
|
inc dx ; command register
|
||||||
out dx, al
|
out dx, al
|
||||||
sti
|
sti
|
||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
@ -554,7 +548,7 @@ align 4
|
|||||||
xor eax, eax
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
; Записать код ошибки
|
; Write error code
|
||||||
@@Err1_4:
|
@@Err1_4:
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
inc eax
|
inc eax
|
||||||
@ -577,27 +571,27 @@ align 4
|
|||||||
ret
|
ret
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
;*************************************************
|
;*************************************************
|
||||||
;* ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ *
|
;* WAIT FOR THE DEVICE IS READY FOR WORK *
|
||||||
;* Входные параметры передаются через глобальные *
|
;* Input parameters are passed through global *
|
||||||
;* перменные: *
|
;* variables: *
|
||||||
;* ChannelNumber - номер канала; *
|
;* ChannelNumber - channel number; *
|
||||||
;* DiskNumber - номер диска на канале. *
|
;* DiskNumber - disk number on channel. *
|
||||||
;*************************************************
|
;*************************************************
|
||||||
WaitUnitReady:
|
WaitUnitReady:
|
||||||
pusha
|
pusha
|
||||||
; Запомнить время начала операции
|
; Remember the peration start time
|
||||||
mov eax, [timer_ticks]
|
mov eax, [timer_ticks]
|
||||||
mov [WURStartTime], eax
|
mov [WURStartTime], eax
|
||||||
; Очистить буфер пакетной команды
|
; Clear the packet command buffer
|
||||||
call clear_packet_buffer
|
call clear_packet_buffer
|
||||||
; Сформировать команду TEST UNIT READY
|
; Generate TEST UNIT READY command
|
||||||
mov [PacketCommand], word 0
|
mov [PacketCommand], word 0
|
||||||
; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА
|
; waiting loop for device readiness
|
||||||
mov ecx, NoTickWaitTime
|
mov ecx, NoTickWaitTime
|
||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
align 4
|
align 4
|
||||||
@@SendCommand:
|
@@SendCommand:
|
||||||
; Подать команду проверки готовности
|
; Send readiness check command
|
||||||
call SendPacketNoDatCommand
|
call SendPacketNoDatCommand
|
||||||
cmp [timer_ticks_enable], 0
|
cmp [timer_ticks_enable], 0
|
||||||
jne @f
|
jne @f
|
||||||
@ -613,17 +607,17 @@ align 4
|
|||||||
align 4
|
align 4
|
||||||
@@:
|
@@:
|
||||||
call change_task
|
call change_task
|
||||||
; Проверить код ошибки
|
; Check the error code
|
||||||
cmp [DevErrorCode], 0
|
cmp [DevErrorCode], 0
|
||||||
je @@End_11
|
je @@End_11
|
||||||
; Проверить время ожидания готовности
|
; Check waiting time
|
||||||
mov eax, [timer_ticks]
|
mov eax, [timer_ticks]
|
||||||
sub eax, [WURStartTime]
|
sub eax, [WURStartTime]
|
||||||
cmp eax, MaxCDWaitTime
|
cmp eax, MaxCDWaitTime
|
||||||
jb @@SendCommand
|
jb @@SendCommand
|
||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
.Error:
|
.Error:
|
||||||
; Ошибка тайм-аута
|
; time out error
|
||||||
mov [DevErrorCode], 1
|
mov [DevErrorCode], 1
|
||||||
;--------------------------------------
|
;--------------------------------------
|
||||||
@@End_11:
|
@@End_11:
|
||||||
@ -631,21 +625,21 @@ align 4
|
|||||||
ret
|
ret
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
;*************************************************
|
;*************************************************
|
||||||
;* ЗАПРЕТИТЬ СМЕНУ ДИСКА *
|
;* FORBID DISK CHANGE *
|
||||||
;* Входные параметры передаются через глобальные *
|
;* Input parameters are passed through global *
|
||||||
;* перменные: *
|
;* variables: *
|
||||||
;* ChannelNumber - номер канала; *
|
;* ChannelNumber - channel number; *
|
||||||
;* DiskNumber - номер диска на канале. *
|
;* DiskNumber - disk number on channel. *
|
||||||
;*************************************************
|
;*************************************************
|
||||||
prevent_medium_removal:
|
prevent_medium_removal:
|
||||||
pusha
|
pusha
|
||||||
; Очистить буфер пакетной команды
|
; Clear the packet command buffer
|
||||||
call clear_packet_buffer
|
call clear_packet_buffer
|
||||||
; Задать код команды
|
; Set command code
|
||||||
mov [PacketCommand], byte 0x1E
|
mov [PacketCommand], byte 0x1E
|
||||||
; Задать код запрета
|
; Set "Forbid" code
|
||||||
mov [PacketCommand+4], byte 11b
|
mov [PacketCommand+4], byte 11b
|
||||||
; Подать команду
|
; Send command
|
||||||
call SendPacketNoDatCommand
|
call SendPacketNoDatCommand
|
||||||
mov eax, ATAPI_IDE0_lock
|
mov eax, ATAPI_IDE0_lock
|
||||||
add eax, [cdpos]
|
add eax, [cdpos]
|
||||||
@ -655,21 +649,21 @@ prevent_medium_removal:
|
|||||||
ret
|
ret
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
;*************************************************
|
;*************************************************
|
||||||
;* РАЗРЕШИТЬ СМЕНУ ДИСКА *
|
;* ALLOW DISK CHANGE *
|
||||||
;* Входные параметры передаются через глобальные *
|
;* Input parameters are passed through global *
|
||||||
;* перменные: *
|
;* variables: *
|
||||||
;* ChannelNumber - номер канала; *
|
;* ChannelNumber - channel number; *
|
||||||
;* DiskNumber - номер диска на канале. *
|
;* DiskNumber - disk number on channel. *
|
||||||
;*************************************************
|
;*************************************************
|
||||||
allow_medium_removal:
|
allow_medium_removal:
|
||||||
pusha
|
pusha
|
||||||
; Очистить буфер пакетной команды
|
; Clear the packet command buffer
|
||||||
call clear_packet_buffer
|
call clear_packet_buffer
|
||||||
; Задать код команды
|
; Set command code
|
||||||
mov [PacketCommand], byte 0x1E
|
mov [PacketCommand], byte 0x1E
|
||||||
; Задать код запрета
|
; unset "Forbid" code
|
||||||
mov [PacketCommand+4], byte 0
|
mov [PacketCommand+4], byte 0
|
||||||
; Подать команду
|
; Send command
|
||||||
call SendPacketNoDatCommand
|
call SendPacketNoDatCommand
|
||||||
mov eax, ATAPI_IDE0_lock
|
mov eax, ATAPI_IDE0_lock
|
||||||
add eax, [cdpos]
|
add eax, [cdpos]
|
||||||
@ -679,54 +673,54 @@ allow_medium_removal:
|
|||||||
ret
|
ret
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
;*************************************************
|
;*************************************************
|
||||||
;* ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД *
|
;* LOAD DISK TO THE DRIVE *
|
||||||
;* Входные параметры передаются через глобальные *
|
;* Input parameters are passed through global *
|
||||||
;* перменные: *
|
;* variables: *
|
||||||
;* ChannelNumber - номер канала; *
|
;* ChannelNumber - channel number; *
|
||||||
;* DiskNumber - номер диска на канале. *
|
;* DiskNumber - disk number on channel. *
|
||||||
;*************************************************
|
;*************************************************
|
||||||
LoadMedium:
|
LoadMedium:
|
||||||
pusha
|
pusha
|
||||||
; Очистить буфер пакетной команды
|
; Clear the packet command buffer
|
||||||
call clear_packet_buffer
|
call clear_packet_buffer
|
||||||
; Сформировать команду START/STOP UNIT
|
; Generate START/STOP UNIT command
|
||||||
; Задать код команды
|
; Set command code
|
||||||
mov [PacketCommand], word 0x1B
|
mov [PacketCommand], word 0x1B
|
||||||
; Задать операцию загрузки носителя
|
; Set disk loading operation
|
||||||
mov [PacketCommand+4], word 00000011b
|
mov [PacketCommand+4], word 00000011b
|
||||||
; Подать команду
|
; Send command
|
||||||
call SendPacketNoDatCommand
|
call SendPacketNoDatCommand
|
||||||
popa
|
popa
|
||||||
ret
|
ret
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
;*************************************************
|
;*************************************************
|
||||||
;* ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА *
|
;* REMOVE THE DISK FROM THE DRIVE *
|
||||||
;* Входные параметры передаются через глобальные *
|
;* Input parameters are passed through global *
|
||||||
;* перменные: *
|
;* variables: *
|
||||||
;* ChannelNumber - номер канала; *
|
;* ChannelNumber - channel number; *
|
||||||
;* DiskNumber - номер диска на канале. *
|
;* DiskNumber - disk number on channel. *
|
||||||
;*************************************************
|
;*************************************************
|
||||||
EjectMedium:
|
EjectMedium:
|
||||||
pusha
|
pusha
|
||||||
; Очистить буфер пакетной команды
|
; Clear the packet command buffer
|
||||||
call clear_packet_buffer
|
call clear_packet_buffer
|
||||||
; Сформировать команду START/STOP UNIT
|
; Generate START/STOP UNIT command
|
||||||
; Задать код команды
|
; Set command code
|
||||||
mov [PacketCommand], word 0x1B
|
mov [PacketCommand], word 0x1B
|
||||||
; Задать операцию извлечения носителя
|
; Set the operation to eject disk
|
||||||
mov [PacketCommand+4], word 00000010b
|
mov [PacketCommand+4], word 00000010b
|
||||||
; Подать команду
|
; Send command
|
||||||
call SendPacketNoDatCommand
|
call SendPacketNoDatCommand
|
||||||
popa
|
popa
|
||||||
ret
|
ret
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
;*************************************************
|
;*************************************************
|
||||||
;* Проверить событие нажатия кнопки извлечения *
|
;* Check the event of pressing the eject button *
|
||||||
;* диска *
|
;* *
|
||||||
;* Входные параметры передаются через глобальные *
|
;* Input parameters are passed through global *
|
||||||
;* переменные: *
|
;* variables: *
|
||||||
;* ChannelNumber - номер канала; *
|
;* ChannelNumber - channel number; *
|
||||||
;* DiskNumber - номер диска на канале. *
|
;* DiskNumber - disk number on channel. *
|
||||||
;*************************************************
|
;*************************************************
|
||||||
proc check_ATAPI_device_event_has_work?
|
proc check_ATAPI_device_event_has_work?
|
||||||
mov eax, [timer_ticks]
|
mov eax, [timer_ticks]
|
||||||
@ -1146,78 +1140,77 @@ ignore_CD_eject_wait db 0
|
|||||||
endg
|
endg
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
;*************************************************
|
;*************************************************
|
||||||
;* Получить сообщение о событии или состоянии *
|
;* Get an event or device status message *
|
||||||
;* устройства *
|
;* *
|
||||||
;* Входные параметры передаются через глобальные *
|
;* Input parameters are passed through global *
|
||||||
;* переменные: *
|
;* variables: *
|
||||||
;* ChannelNumber - номер канала; *
|
;* ChannelNumber - channel number; *
|
||||||
;* DiskNumber - номер диска на канале. *
|
;* DiskNumber - disk number on channel *
|
||||||
;*************************************************
|
;*************************************************
|
||||||
GetEvent_StatusNotification:
|
GetEvent_StatusNotification:
|
||||||
pusha
|
pusha
|
||||||
mov [CDDataBuf_pointer], CDDataBuf
|
mov [CDDataBuf_pointer], CDDataBuf
|
||||||
; Очистить буфер пакетной команды
|
; Clear the packet command buffer
|
||||||
call clear_packet_buffer
|
call clear_packet_buffer
|
||||||
; Задать код команды
|
; Set command code
|
||||||
mov [PacketCommand], byte 4Ah
|
mov [PacketCommand], byte 4Ah
|
||||||
mov [PacketCommand+1], byte 00000001b
|
mov [PacketCommand+1], byte 00000001b
|
||||||
; Задать запрос класса сообщений
|
; Set message class request
|
||||||
mov [PacketCommand+4], byte 00010000b
|
mov [PacketCommand+4], byte 00010000b
|
||||||
; Размер выделенной области
|
; Size of allocated area
|
||||||
mov [PacketCommand+7], byte 8h
|
mov [PacketCommand+7], byte 8h
|
||||||
mov [PacketCommand+8], byte 0h
|
mov [PacketCommand+8], byte 0h
|
||||||
; Подать команду
|
; Send command
|
||||||
call SendPacketDatCommand
|
call SendPacketDatCommand
|
||||||
popa
|
popa
|
||||||
ret
|
ret
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
;*************************************************
|
;*************************************************
|
||||||
; прочитать информацию из TOC
|
; Read information from TOC (Table of contents) *
|
||||||
;* Входные параметры передаются через глобальные *
|
;* Input parameters are passed through global *
|
||||||
;* переменные: *
|
;* variables: *
|
||||||
;* ChannelNumber - номер канала; *
|
;* ChannelNumber - channel number; *
|
||||||
;* DiskNumber - номер диска на канале. *
|
;* DiskNumber - disk number on channel *
|
||||||
;*************************************************
|
;*************************************************
|
||||||
Read_TOC:
|
Read_TOC:
|
||||||
pusha
|
pusha
|
||||||
mov [CDDataBuf_pointer], CDDataBuf
|
mov [CDDataBuf_pointer], CDDataBuf
|
||||||
; Очистить буфер пакетной команды
|
; Clear the packet command buffer
|
||||||
call clear_packet_buffer
|
call clear_packet_buffer
|
||||||
; Сформировать пакетную команду для считывания
|
; Generate a packet command to read a data sector
|
||||||
; сектора данных
|
|
||||||
mov [PacketCommand], byte 0x43
|
mov [PacketCommand], byte 0x43
|
||||||
; Задать формат
|
; Set format
|
||||||
mov [PacketCommand+2], byte 1
|
mov [PacketCommand+2], byte 1
|
||||||
; Размер выделенной области
|
; Size of allocated area
|
||||||
mov [PacketCommand+7], byte 0xFF
|
mov [PacketCommand+7], byte 0xFF
|
||||||
mov [PacketCommand+8], byte 0h
|
mov [PacketCommand+8], byte 0h
|
||||||
; Подать команду
|
; Send a command
|
||||||
call SendPacketDatCommand
|
call SendPacketDatCommand
|
||||||
popa
|
popa
|
||||||
ret
|
ret
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
;*************************************************
|
;*****************************************************
|
||||||
;* ОПРЕДЕЛИТЬ ОБЩЕЕ КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ *
|
;* DETERMINE THE TOTAL NUMBER OF SECTORS ON THE DISK *
|
||||||
;* Входные параметры передаются через глобальные *
|
;* Input parameters are passed through global *
|
||||||
;* переменные: *
|
;* variables: *
|
||||||
;* ChannelNumber - номер канала; *
|
;* ChannelNumber - channel number; *
|
||||||
;* DiskNumber - номер диска на канале. *
|
;* DiskNumber - disk number on channel *
|
||||||
;*************************************************
|
;*****************************************************
|
||||||
;ReadCapacity:
|
;ReadCapacity:
|
||||||
; pusha
|
; pusha
|
||||||
;; Очистить буфер пакетной команды
|
;; Clear the packet command buffer
|
||||||
; call clear_packet_buffer
|
; call clear_packet_buffer
|
||||||
;; Задать размер буфера в байтах
|
;; Set the buffer size in bytes
|
||||||
; mov [CDBlockSize],8
|
; mov [CDBlockSize],8
|
||||||
;; Сформировать команду READ CAPACITY
|
;; Generate READ CAPACITY command
|
||||||
; mov [PacketCommand],word 25h
|
; mov [PacketCommand],word 25h
|
||||||
;; Подать команду
|
;; Send command
|
||||||
; call SendPacketDatCommand
|
; call SendPacketDatCommand
|
||||||
; popa
|
; popa
|
||||||
; ret
|
; ret
|
||||||
;-----------------------------------------------------------------------------
|
;-----------------------------------------------------------------------------
|
||||||
clear_packet_buffer:
|
clear_packet_buffer:
|
||||||
; Очистить буфер пакетной команды
|
; Clear the packet command buffer
|
||||||
and [PacketCommand], dword 0
|
and [PacketCommand], dword 0
|
||||||
and [PacketCommand+4], dword 0
|
and [PacketCommand+4], dword 0
|
||||||
and [PacketCommand+8], dword 0
|
and [PacketCommand+8], dword 0
|
||||||
|
@ -9,12 +9,12 @@ $Revision$
|
|||||||
|
|
||||||
|
|
||||||
;**********************************************************
|
;**********************************************************
|
||||||
; Непосредственная работа с контроллером гибкого диска
|
; Direct work with floppy disk drive
|
||||||
;**********************************************************
|
;**********************************************************
|
||||||
; Автор исходного текста Кулаков Владимир Геннадьевич.
|
; Source code author Kulakov Vladimir Gennadievich.
|
||||||
; Адаптация и доработка Mario79
|
; Adaptation and improvement Mario79
|
||||||
|
|
||||||
;give_back_application_data: ; переслать приложению
|
;give_back_application_data: ; give back to application
|
||||||
; mov edi,[TASK_BASE]
|
; mov edi,[TASK_BASE]
|
||||||
; mov edi,[edi+TASKDATA.mem_start]
|
; mov edi,[edi+TASKDATA.mem_start]
|
||||||
; add edi,ecx
|
; add edi,ecx
|
||||||
@ -25,7 +25,7 @@ give_back_application_data_1:
|
|||||||
rep movsd
|
rep movsd
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;take_data_from_application: ; взять из приложени
|
;take_data_from_application: ; take from application
|
||||||
; mov esi,[TASK_BASE]
|
; mov esi,[TASK_BASE]
|
||||||
; mov esi,[esi+TASKDATA.mem_start]
|
; mov esi,[esi+TASKDATA.mem_start]
|
||||||
; add esi,ecx
|
; add esi,ecx
|
||||||
@ -36,37 +36,37 @@ take_data_from_application_1:
|
|||||||
rep movsd
|
rep movsd
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; Коды завершения операции с контроллером (FDC_Status)
|
; Controller operations result codes (FDC_Status)
|
||||||
FDC_Normal = 0 ;нормальное завершение
|
FDC_Normal = 0 ; normal finish
|
||||||
FDC_TimeOut = 1 ;ошибка тайм-аута
|
FDC_TimeOut = 1 ; time out error
|
||||||
FDC_DiskNotFound = 2 ;в дисководе нет диска
|
FDC_DiskNotFound = 2 ; no disk in drive
|
||||||
FDC_TrackNotFound = 3 ;дорожка не найдена
|
FDC_TrackNotFound = 3 ; track not found
|
||||||
FDC_SectorNotFound = 4 ;сектор не найден
|
FDC_SectorNotFound = 4 ; sector not found
|
||||||
|
|
||||||
; Максимальные значения координат сектора (заданные
|
; Maximum values of the sector coordinates (specified
|
||||||
; значения соответствуют параметрам стандартного
|
; values correspond to the parameters of the standard
|
||||||
; трехдюймового гибкого диска объемом 1,44 Мб)
|
; 3-inch 1.44 MB floppy disk)
|
||||||
MAX_Track = 79
|
MAX_Track = 79
|
||||||
MAX_Head = 1
|
MAX_Head = 1
|
||||||
MAX_Sector = 18
|
MAX_Sector = 18
|
||||||
|
|
||||||
uglobal
|
uglobal
|
||||||
; Счетчик тиков таймера
|
; Timer tick counter
|
||||||
TickCounter dd ?
|
TickCounter dd ?
|
||||||
; Код завершения операции с контроллером НГМД
|
; Operation completion code with the floppy disk drive controller
|
||||||
FDC_Status DB ?
|
FDC_Status DB ?
|
||||||
; Флаг прерывания от НГМД
|
; Interrupt flag from floppy disk drive
|
||||||
FDD_IntFlag DB ?
|
FDD_IntFlag DB ?
|
||||||
; Момент начала последней операции с НГМД
|
; The moment of the beginning of the last operation with FDD
|
||||||
FDD_Time DD ?
|
FDD_Time DD ?
|
||||||
; Номер дисковода
|
; Drive number
|
||||||
FDD_Type db 0
|
FDD_Type db 0
|
||||||
; Координаты сектора
|
; Sector coordinates
|
||||||
FDD_Track DB ?
|
FDD_Track DB ?
|
||||||
FDD_Head DB ?
|
FDD_Head DB ?
|
||||||
FDD_Sector DB ?
|
FDD_Sector DB ?
|
||||||
|
|
||||||
; Блок результата операции
|
; Operation result block
|
||||||
FDC_ST0 DB ?
|
FDC_ST0 DB ?
|
||||||
FDC_ST1 DB ?
|
FDC_ST1 DB ?
|
||||||
FDC_ST2 DB ?
|
FDC_ST2 DB ?
|
||||||
@ -74,19 +74,19 @@ FDC_C DB ?
|
|||||||
FDC_H DB ?
|
FDC_H DB ?
|
||||||
FDC_R DB ?
|
FDC_R DB ?
|
||||||
FDC_N DB ?
|
FDC_N DB ?
|
||||||
; Счетчик повторения операции чтени
|
; Read operation repetition counter
|
||||||
ReadRepCounter DB ?
|
ReadRepCounter DB ?
|
||||||
; Счетчик повторения операции рекалибровки
|
; Recalibration operation repetition counter
|
||||||
RecalRepCounter DB ?
|
RecalRepCounter DB ?
|
||||||
endg
|
endg
|
||||||
; Область памяти для хранения прочитанного сектора
|
; Memory area for storing the readed sector
|
||||||
;FDD_DataBuffer: times 512 db 0 ;DB 512 DUP (?)
|
;FDD_DataBuffer: times 512 db 0 ;DB 512 DUP (?)
|
||||||
fdd_motor_status db 0
|
fdd_motor_status db 0
|
||||||
timer_fdd_motor dd 0
|
timer_fdd_motor dd 0
|
||||||
|
|
||||||
;*************************************
|
;**************************************
|
||||||
;* ИНИЦИАЛИЗАЦИЯ РЕЖИМА ПДП ДЛЯ НГМД *
|
;* INITIALIZATION OF DMA MODE FOR FDD *
|
||||||
;*************************************
|
;**************************************
|
||||||
Init_FDC_DMA:
|
Init_FDC_DMA:
|
||||||
pushad
|
pushad
|
||||||
mov al, 0
|
mov al, 0
|
||||||
@ -115,31 +115,31 @@ Init_FDC_DMA:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
;***********************************
|
;***********************************
|
||||||
;* ЗАПИСАТЬ БАЙТ В ПОРТ ДАННЫХ FDC *
|
;* WRITE BYTE TO FDC DATA PORT *
|
||||||
;* Параметры: *
|
;* Parameters: *
|
||||||
;* AL - выводимый байт. *
|
;* AL - byte to write. *
|
||||||
;***********************************
|
;***********************************
|
||||||
FDCDataOutput:
|
FDCDataOutput:
|
||||||
; DEBUGF 1,'K : FDCDataOutput(%x)',al
|
; DEBUGF 1,'K : FDCDataOutput(%x)',al
|
||||||
; pusha
|
; pusha
|
||||||
push eax ecx edx
|
push eax ecx edx
|
||||||
mov AH, AL ;запомнить байт в AH
|
mov AH, AL ; remember byte to AH
|
||||||
; Сбросить переменную состояния контроллера
|
; Reset controller state variable
|
||||||
mov [FDC_Status], FDC_Normal
|
mov [FDC_Status], FDC_Normal
|
||||||
; Проверить готовность контроллера к приему данных
|
; Check the readiness of the controller to receive data
|
||||||
mov DX, 3F4h ;(порт состояния FDC)
|
mov DX, 3F4h ; (FDC state port)
|
||||||
mov ecx, 0x10000 ;установить счетчик тайм-аута
|
mov ecx, 0x10000 ; set timeout counter
|
||||||
@@TestRS:
|
@@TestRS:
|
||||||
in AL, DX ;прочитать регистр RS
|
in AL, DX ; read the RS register
|
||||||
and AL, 0C0h ;выделить разряды 6 и 7
|
and AL, 0C0h ; get digits 6 and 7
|
||||||
cmp AL, 80h ;проверить разряды 6 и 7
|
cmp AL, 80h ; check digits 6 and 7
|
||||||
je @@OutByteToFDC
|
je @@OutByteToFDC
|
||||||
loop @@TestRS
|
loop @@TestRS
|
||||||
; Ошибка тайм-аута
|
; Time out error
|
||||||
; DEBUGF 1,' timeout\n'
|
; DEBUGF 1,' timeout\n'
|
||||||
mov [FDC_Status], FDC_TimeOut
|
mov [FDC_Status], FDC_TimeOut
|
||||||
jmp @@End_5
|
jmp @@End_5
|
||||||
; Вывести байт в порт данных
|
; Write byte to data port
|
||||||
@@OutByteToFDC:
|
@@OutByteToFDC:
|
||||||
inc DX
|
inc DX
|
||||||
mov AL, AH
|
mov AL, AH
|
||||||
@ -151,30 +151,30 @@ FDCDataOutput:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
;******************************************
|
;******************************************
|
||||||
;* ПРОЧИТАТЬ БАЙТ ИЗ ПОРТА ДАННЫХ FDC *
|
;* READ BYTE FROM FDC DATA PORT *
|
||||||
;* Процедура не имеет входных параметров. *
|
;* Procedure doesnt have input params. *
|
||||||
;* Выходные данные: *
|
;* Output : *
|
||||||
;* AL - считанный байт. *
|
;* AL - byte read. *
|
||||||
;******************************************
|
;******************************************
|
||||||
FDCDataInput:
|
FDCDataInput:
|
||||||
push ECX
|
push ECX
|
||||||
push DX
|
push DX
|
||||||
; Сбросить переменную состояния контроллера
|
; Reset controller state variable
|
||||||
mov [FDC_Status], FDC_Normal
|
mov [FDC_Status], FDC_Normal
|
||||||
; Проверить готовность контроллера к передаче данных
|
; Check the readiness of the controller to receive data
|
||||||
mov DX, 3F4h ;(порт состояния FDC)
|
mov DX, 3F4h ;(FDC state port)
|
||||||
mov ecx, 0x10000 ;установить счетчик тайм-аута
|
mov ecx, 0x10000 ; set timeout counter
|
||||||
@@TestRS_1:
|
@@TestRS_1:
|
||||||
in AL, DX ;прочитать регистр RS
|
in AL, DX ; read the RS register
|
||||||
and AL, 0C0h ;выдлить разряды 6 и 7
|
and AL, 0C0h ; get digits 6 and 7
|
||||||
cmp AL, 0C0h ;проверить разряды 6 и 7
|
cmp AL, 0C0h ; check digits 6 and 7
|
||||||
je @@GetByteFromFDC
|
je @@GetByteFromFDC
|
||||||
loop @@TestRS_1
|
loop @@TestRS_1
|
||||||
; Ошибка тайм-аута
|
; Time out error
|
||||||
; DEBUGF 1,'K : FDCDataInput: timeout\n'
|
; DEBUGF 1,'K : FDCDataInput: timeout\n'
|
||||||
mov [FDC_Status], FDC_TimeOut
|
mov [FDC_Status], FDC_TimeOut
|
||||||
jmp @@End_6
|
jmp @@End_6
|
||||||
; Ввести байт из порта данных
|
; Get byte from data port
|
||||||
@@GetByteFromFDC:
|
@@GetByteFromFDC:
|
||||||
inc DX
|
inc DX
|
||||||
in AL, DX
|
in AL, DX
|
||||||
@ -185,45 +185,45 @@ FDCDataInput:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
;*********************************************
|
;*********************************************
|
||||||
;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД *
|
;* FDC INTERRUPT HANDLER *
|
||||||
;*********************************************
|
;*********************************************
|
||||||
FDCInterrupt:
|
FDCInterrupt:
|
||||||
; dbgstr 'FDCInterrupt'
|
; dbgstr 'FDCInterrupt'
|
||||||
; Установить флаг прерывания
|
; Set the interrupt flag
|
||||||
mov [FDD_IntFlag], 1
|
mov [FDD_IntFlag], 1
|
||||||
mov al, 1
|
mov al, 1
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;*******************************************
|
;*******************************************
|
||||||
;* ОЖИДАНИЕ ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД *
|
;* WAIT FOR INTERRUPT FROM FDC *
|
||||||
;*******************************************
|
;*******************************************
|
||||||
WaitFDCInterrupt:
|
WaitFDCInterrupt:
|
||||||
pusha
|
pusha
|
||||||
; Сбросить байт состояния операции
|
; Reset operation status byte
|
||||||
mov [FDC_Status], FDC_Normal
|
mov [FDC_Status], FDC_Normal
|
||||||
; Обнулить счетчик тиков
|
; Zero out the tick counter
|
||||||
mov eax, [timer_ticks]
|
mov eax, [timer_ticks]
|
||||||
mov [TickCounter], eax
|
mov [TickCounter], eax
|
||||||
; Ожидать установки флага прерывания НГМД
|
; Wait for the floppy disk interrupt flag to be set
|
||||||
@@TestRS_2:
|
@@TestRS_2:
|
||||||
call change_task
|
call change_task
|
||||||
cmp [FDD_IntFlag], 0
|
cmp [FDD_IntFlag], 0
|
||||||
jnz @@End_7 ;прерывание произошло
|
jnz @@End_7 ; interrupt occured
|
||||||
mov eax, [timer_ticks]
|
mov eax, [timer_ticks]
|
||||||
sub eax, [TickCounter]
|
sub eax, [TickCounter]
|
||||||
cmp eax, 200;50 ;25 ;5 ;ожидать 5 тиков
|
cmp eax, 200;50 ;25 ;5 ; wait 5 ticks
|
||||||
jb @@TestRS_2
|
jb @@TestRS_2
|
||||||
; jl @@TestRS_2
|
; jl @@TestRS_2
|
||||||
; Ошибка тайм-аута
|
; Time out error
|
||||||
; dbgstr 'WaitFDCInterrupt: timeout'
|
; dbgstr 'WaitFDCInterrupt: timeout'
|
||||||
mov [FDC_Status], FDC_TimeOut
|
mov [FDC_Status], FDC_TimeOut
|
||||||
@@End_7:
|
@@End_7:
|
||||||
popa
|
popa
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;*********************************
|
;***********************************
|
||||||
;* ВКЛЮЧИТЬ МОТОР ДИСКОВОДА "A:" *
|
;* Turn on the motor of drive "A:" *
|
||||||
;*********************************
|
;***********************************
|
||||||
FDDMotorON:
|
FDDMotorON:
|
||||||
; dbgstr 'FDDMotorON'
|
; dbgstr 'FDDMotorON'
|
||||||
pusha
|
pusha
|
||||||
@ -232,11 +232,11 @@ FDDMotorON:
|
|||||||
mov al, [flp_number]
|
mov al, [flp_number]
|
||||||
cmp [fdd_motor_status], al
|
cmp [fdd_motor_status], al
|
||||||
je fdd_motor_on
|
je fdd_motor_on
|
||||||
; Произвести сброс контроллера НГМД
|
; Reset the FDD controller
|
||||||
mov DX, 3F2h;порт управления двигателями
|
mov DX, 3F2h ; motor control port
|
||||||
mov AL, 0
|
mov AL, 0
|
||||||
out DX, AL
|
out DX, AL
|
||||||
; Выбрать и включить мотор дисковода
|
; Select and turn on the drive motor
|
||||||
cmp [flp_number], 1
|
cmp [flp_number], 1
|
||||||
jne FDDMotorON_B
|
jne FDDMotorON_B
|
||||||
; call FDDMotorOFF_B
|
; call FDDMotorOFF_B
|
||||||
@ -247,10 +247,10 @@ FDDMotorON_B:
|
|||||||
mov AL, 2Dh ; Floppy B
|
mov AL, 2Dh ; Floppy B
|
||||||
FDDMotorON_1:
|
FDDMotorON_1:
|
||||||
out DX, AL
|
out DX, AL
|
||||||
; Обнулить счетчик тиков
|
; Zero out the tick counter
|
||||||
mov eax, [timer_ticks]
|
mov eax, [timer_ticks]
|
||||||
mov [TickCounter], eax
|
mov [TickCounter], eax
|
||||||
; Ожидать 0,5 с
|
; wait 0.5 s
|
||||||
@@dT:
|
@@dT:
|
||||||
call change_task
|
call change_task
|
||||||
mov eax, [timer_ticks]
|
mov eax, [timer_ticks]
|
||||||
@ -283,7 +283,7 @@ fdd_motor_on:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
;*****************************************
|
;*****************************************
|
||||||
;* СОХРАНЕНИЕ УКАЗАТЕЛЯ ВРЕМЕНИ *
|
;* SAVING TIME STAMP *
|
||||||
;*****************************************
|
;*****************************************
|
||||||
save_timer_fdd_motor:
|
save_timer_fdd_motor:
|
||||||
mov eax, [timer_ticks]
|
mov eax, [timer_ticks]
|
||||||
@ -291,7 +291,7 @@ save_timer_fdd_motor:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
;*****************************************
|
;*****************************************
|
||||||
;* ПРОВЕРКА ЗАДЕРЖКИ ВЫКЛЮЧЕНИЯ МОТОРА *
|
;* CHECK THE MOTOR SHUTDOWN DELAY *
|
||||||
;*****************************************
|
;*****************************************
|
||||||
proc check_fdd_motor_status_has_work?
|
proc check_fdd_motor_status_has_work?
|
||||||
cmp [fdd_motor_status], 0
|
cmp [fdd_motor_status], 0
|
||||||
@ -324,7 +324,7 @@ end_check_fdd_motor_status:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
;**********************************
|
;**********************************
|
||||||
;* ВЫКЛЮЧИТЬ МОТОР ДИСКОВОДА *
|
;* TURN OFF MOTOR OF DRIVE *
|
||||||
;**********************************
|
;**********************************
|
||||||
FDDMotorOFF:
|
FDDMotorOFF:
|
||||||
; dbgstr 'FDDMotorOFF'
|
; dbgstr 'FDDMotorOFF'
|
||||||
@ -339,39 +339,39 @@ FDDMotorOFF_1:
|
|||||||
FDDMotorOFF_2:
|
FDDMotorOFF_2:
|
||||||
pop DX
|
pop DX
|
||||||
pop AX
|
pop AX
|
||||||
; сброс флагов кеширования в связи с устареванием информации
|
; clearing caching flags due to information obsolescence
|
||||||
or [floppy_media_flags+0], FLOPPY_MEDIA_NEED_RESCAN
|
or [floppy_media_flags+0], FLOPPY_MEDIA_NEED_RESCAN
|
||||||
or [floppy_media_flags+1], FLOPPY_MEDIA_NEED_RESCAN
|
or [floppy_media_flags+1], FLOPPY_MEDIA_NEED_RESCAN
|
||||||
ret
|
ret
|
||||||
|
|
||||||
FDDMotorOFF_A:
|
FDDMotorOFF_A:
|
||||||
mov DX, 3F2h;порт управления двигателями
|
mov DX, 3F2h ; motor control port
|
||||||
mov AL, 0Ch ; Floppy A
|
mov AL, 0Ch ; Floppy A
|
||||||
out DX, AL
|
out DX, AL
|
||||||
ret
|
ret
|
||||||
|
|
||||||
FDDMotorOFF_B:
|
FDDMotorOFF_B:
|
||||||
mov DX, 3F2h;порт управления двигателями
|
mov DX, 3F2h ; motor control port
|
||||||
mov AL, 5h ; Floppy B
|
mov AL, 5h ; Floppy B
|
||||||
out DX, AL
|
out DX, AL
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;*******************************
|
;*******************************
|
||||||
;* РЕКАЛИБРОВКА ДИСКОВОДА "A:" *
|
;* RECALIBRATE DRIVE "A:" *
|
||||||
;*******************************
|
;*******************************
|
||||||
RecalibrateFDD:
|
RecalibrateFDD:
|
||||||
; dbgstr 'RecalibrateFDD'
|
; dbgstr 'RecalibrateFDD'
|
||||||
pusha
|
pusha
|
||||||
call save_timer_fdd_motor
|
call save_timer_fdd_motor
|
||||||
; Сбросить флаг прерывания
|
; Clear the interrupt flag
|
||||||
mov [FDD_IntFlag], 0
|
mov [FDD_IntFlag], 0
|
||||||
; Подать команду "Рекалибровка"
|
; Send the "Recalibration" command
|
||||||
mov AL, 07h
|
mov AL, 07h
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
mov AL, [flp_number]
|
mov AL, [flp_number]
|
||||||
dec AL
|
dec AL
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
; Ожидать завершения операции
|
; Wait for the operation to complete
|
||||||
call WaitFDCInterrupt
|
call WaitFDCInterrupt
|
||||||
cmp [FDC_Status], 0
|
cmp [FDC_Status], 0
|
||||||
jne .fail
|
jne .fail
|
||||||
@ -396,48 +396,48 @@ RecalibrateFDD:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
;*****************************************************
|
;*****************************************************
|
||||||
;* ПОИСК ДОРОЖКИ *
|
;* TRACK SEARCH *
|
||||||
;* Параметры передаются через глобальные переменные: *
|
;* Parameters are passed through global variables: *
|
||||||
;* FDD_Track - номер дорожки (0-79); *
|
;* FDD_Track - track number (0-79); *
|
||||||
;* FDD_Head - номер головки (0-1). *
|
;* FDD_Head - head number (0-1). *
|
||||||
;* Результат операции заносится в FDC_Status. *
|
;* Result of operation is written to FDC_Status. *
|
||||||
;*****************************************************
|
;*****************************************************
|
||||||
SeekTrack:
|
SeekTrack:
|
||||||
; dbgstr 'SeekTrack'
|
; dbgstr 'SeekTrack'
|
||||||
pusha
|
pusha
|
||||||
call save_timer_fdd_motor
|
call save_timer_fdd_motor
|
||||||
; Сбросить флаг прерывания
|
; Clear the interrupt flag
|
||||||
mov [FDD_IntFlag], 0
|
mov [FDD_IntFlag], 0
|
||||||
; Подать команду "Поиск"
|
; Send "Search" command
|
||||||
mov AL, 0Fh
|
mov AL, 0Fh
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
; Передать байт номера головки/накопител
|
; Send head / drive number byte
|
||||||
mov AL, [FDD_Head]
|
mov AL, [FDD_Head]
|
||||||
shl AL, 2
|
shl AL, 2
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
; Передать байт номера дорожки
|
; Send track number byte
|
||||||
mov AL, [FDD_Track]
|
mov AL, [FDD_Track]
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
; Ожидать завершения операции
|
; Wait for the operation to complete
|
||||||
call WaitFDCInterrupt
|
call WaitFDCInterrupt
|
||||||
cmp [FDC_Status], FDC_Normal
|
cmp [FDC_Status], FDC_Normal
|
||||||
jne @@Exit
|
jne @@Exit
|
||||||
; Сохранить результат поиска
|
; Save search result
|
||||||
mov AL, 08h
|
mov AL, 08h
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
call FDCDataInput
|
call FDCDataInput
|
||||||
mov [FDC_ST0], AL
|
mov [FDC_ST0], AL
|
||||||
call FDCDataInput
|
call FDCDataInput
|
||||||
mov [FDC_C], AL
|
mov [FDC_C], AL
|
||||||
; Проверить результат поиска
|
; Check search result
|
||||||
; Поиск завершен?
|
; Is search finished?
|
||||||
test [FDC_ST0], 100000b
|
test [FDC_ST0], 100000b
|
||||||
je @@Err
|
je @@Err
|
||||||
; Заданный трек найден?
|
; Is the specified track found?
|
||||||
mov AL, [FDC_C]
|
mov AL, [FDC_C]
|
||||||
cmp AL, [FDD_Track]
|
cmp AL, [FDD_Track]
|
||||||
jne @@Err
|
jne @@Err
|
||||||
; Номер головки совпадает с заданным?
|
; Does the head number match the specified one?
|
||||||
; The H bit (Head Address) in ST0 will always return a "0" (c) 82077AA datasheet,
|
; The H bit (Head Address) in ST0 will always return a "0" (c) 82077AA datasheet,
|
||||||
; description of SEEK command. So we can not verify the proper head.
|
; description of SEEK command. So we can not verify the proper head.
|
||||||
; mov AL, [FDC_ST0]
|
; mov AL, [FDC_ST0]
|
||||||
@ -445,11 +445,11 @@ SeekTrack:
|
|||||||
; shr AL, 2
|
; shr AL, 2
|
||||||
; cmp AL, [FDD_Head]
|
; cmp AL, [FDD_Head]
|
||||||
; jne @@Err
|
; jne @@Err
|
||||||
; Операция завершена успешно
|
; Operation completed successfully
|
||||||
; dbgstr 'SeekTrack: FDC_Normal'
|
; dbgstr 'SeekTrack: FDC_Normal'
|
||||||
mov [FDC_Status], FDC_Normal
|
mov [FDC_Status], FDC_Normal
|
||||||
jmp @@Exit
|
jmp @@Exit
|
||||||
@@Err: ; Трек не найден
|
@@Err: ; Track not found
|
||||||
; dbgstr 'SeekTrack: FDC_TrackNotFound'
|
; dbgstr 'SeekTrack: FDC_TrackNotFound'
|
||||||
mov [FDC_Status], FDC_TrackNotFound
|
mov [FDC_Status], FDC_TrackNotFound
|
||||||
@@Exit:
|
@@Exit:
|
||||||
@ -458,30 +458,30 @@ SeekTrack:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
;*******************************************************
|
;*******************************************************
|
||||||
;* ЧТЕНИЕ СЕКТОРА ДАННЫХ *
|
;* READING A DATA SECTOR *
|
||||||
;* Параметры передаются через глобальные переменные: *
|
;* Parameters are passed through global variables: *
|
||||||
;* FDD_Track - номер дорожки (0-79); *
|
;* FDD_Track - track number (0-79); *
|
||||||
;* FDD_Head - номер головки (0-1); *
|
;* FDD_Head - head number (0-1); *
|
||||||
;* FDD_Sector - номер сектора (1-18). *
|
;* FDD_Sector - sector number (1-18). *
|
||||||
;* Результат операции заносится в FDC_Status. *
|
;* Result of operation is written to FDC_Status. *
|
||||||
;* В случае успешного выполнения операции чтения *
|
;* If the read operation is successful, the contents *
|
||||||
;* содержимое сектора будет занесено в FDD_DataBuffer. *
|
;* of the sector will be written to FDD_DataBuffer. *
|
||||||
;*******************************************************
|
;*******************************************************
|
||||||
ReadSector:
|
ReadSector:
|
||||||
; dbgstr 'ReadSector'
|
; dbgstr 'ReadSector'
|
||||||
pushad
|
pushad
|
||||||
call save_timer_fdd_motor
|
call save_timer_fdd_motor
|
||||||
; Сбросить флаг прерывания
|
; Clear the interrupt flag
|
||||||
mov [FDD_IntFlag], 0
|
mov [FDD_IntFlag], 0
|
||||||
; Установить скорость передачи 500 Кбайт/с
|
; Set transmit speed to 500 Kb / s
|
||||||
mov AX, 0
|
mov AX, 0
|
||||||
mov DX, 03F7h
|
mov DX, 03F7h
|
||||||
out DX, AL
|
out DX, AL
|
||||||
; Инициализировать канал прямого доступа к памяти
|
; Initialize the DMA channel
|
||||||
mov [dmamode], 0x46
|
mov [dmamode], 0x46
|
||||||
call Init_FDC_DMA
|
call Init_FDC_DMA
|
||||||
; Подать команду "Чтение данных"
|
; Send "Data read" command
|
||||||
mov AL, 0E6h ;чтение в мультитрековом режиме
|
mov AL, 0E6h ; reading in multi-track mode
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
mov AL, [FDD_Head]
|
mov AL, [FDD_Head]
|
||||||
shl AL, 2
|
shl AL, 2
|
||||||
@ -494,19 +494,19 @@ ReadSector:
|
|||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
mov AL, [FDD_Sector]
|
mov AL, [FDD_Sector]
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
mov AL, 2 ;код размера сектора (512 байт)
|
mov AL, 2 ; sector size code (512 byte)
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
mov AL, 18 ;+1; 3Fh ;число секторов на дорожке
|
mov AL, 18 ;+1; 3Fh ;number of sectors per track
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
mov AL, 1Bh ;значение GPL
|
mov AL, 1Bh ; GPL value
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
mov AL, 0FFh;значение DTL
|
mov AL, 0FFh; DTL value
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
; Ожидаем прерывание по завершении операции
|
; Waiting for an interrupt at the end of the operation
|
||||||
call WaitFDCInterrupt
|
call WaitFDCInterrupt
|
||||||
cmp [FDC_Status], FDC_Normal
|
cmp [FDC_Status], FDC_Normal
|
||||||
jne @@Exit_1
|
jne @@Exit_1
|
||||||
; Считываем статус завершения операции
|
; Read the operation completion status
|
||||||
call GetStatusInfo
|
call GetStatusInfo
|
||||||
test [FDC_ST0], 11011000b
|
test [FDC_ST0], 11011000b
|
||||||
jnz @@Err_1
|
jnz @@Err_1
|
||||||
@ -522,21 +522,21 @@ ReadSector:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
;*******************************************************
|
;*******************************************************
|
||||||
;* ЧТЕНИЕ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ) *
|
;* READ SECTOR (WITH RETRY OF OPERATION ON FAILURE) *
|
||||||
;* Параметры передаются через глобальные переменные: *
|
;* Parameters are passed through global variables: *
|
||||||
;* FDD_Track - номер дорожки (0-79); *
|
;* FDD_Track - track number (0-79); *
|
||||||
;* FDD_Head - номер головки (0-1); *
|
;* FDD_Head - head number (0-1); *
|
||||||
;* FDD_Sector - номер сектора (1-18). *
|
;* FDD_Sector - sector number (1-18). *
|
||||||
;* Результат операции заносится в FDC_Status. *
|
;* Result of operation is written to FDC_Status. *
|
||||||
;* В случае успешного выполнения операции чтения *
|
;* If the read operation is successful, the contents *
|
||||||
;* содержимое сектора будет занесено в FDD_DataBuffer. *
|
;* of the sector will be written to FDD_DataBuffer. *
|
||||||
;*******************************************************
|
;*******************************************************
|
||||||
ReadSectWithRetr:
|
ReadSectWithRetr:
|
||||||
pusha
|
pusha
|
||||||
; Обнулить счетчик повторения операции рекалибровки
|
; Reset the recalibration repetition counter
|
||||||
mov [RecalRepCounter], 0
|
mov [RecalRepCounter], 0
|
||||||
@@TryAgain:
|
@@TryAgain:
|
||||||
; Обнулить счетчик повторения операции чтени
|
; Reset the read operation retry counter
|
||||||
mov [ReadRepCounter], 0
|
mov [ReadRepCounter], 0
|
||||||
@@ReadSector_1:
|
@@ReadSector_1:
|
||||||
call ReadSector
|
call ReadSector
|
||||||
@ -544,11 +544,11 @@ ReadSectWithRetr:
|
|||||||
je @@Exit_2
|
je @@Exit_2
|
||||||
cmp [FDC_Status], 1
|
cmp [FDC_Status], 1
|
||||||
je @@Err_3
|
je @@Err_3
|
||||||
; Троекратное повторение чтени
|
; Three times repeat reading
|
||||||
inc [ReadRepCounter]
|
inc [ReadRepCounter]
|
||||||
cmp [ReadRepCounter], 3
|
cmp [ReadRepCounter], 3
|
||||||
jb @@ReadSector_1
|
jb @@ReadSector_1
|
||||||
; Троекратное повторение рекалибровки
|
; Three times repeat recalibration
|
||||||
call RecalibrateFDD
|
call RecalibrateFDD
|
||||||
call SeekTrack
|
call SeekTrack
|
||||||
inc [RecalRepCounter]
|
inc [RecalRepCounter]
|
||||||
@ -562,30 +562,30 @@ ReadSectWithRetr:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
;*******************************************************
|
;*******************************************************
|
||||||
;* ЗАПИСЬ СЕКТОРА ДАННЫХ *
|
;* WRITE DATA SECTOR *
|
||||||
;* Параметры передаются через глобальные переменные: *
|
;* Parameters are passed through global variables: *
|
||||||
;* FDD_Track - номер дорожки (0-79); *
|
;* FDD_Track - track number (0-79); *
|
||||||
;* FDD_Head - номер головки (0-1); *
|
;* FDD_Head - head number (0-1); *
|
||||||
;* FDD_Sector - номер сектора (1-18). *
|
;* FDD_Sector - sector number (1-18). *
|
||||||
;* Результат операции заносится в FDC_Status. *
|
;* Result of operation is written to FDC_Status. *
|
||||||
;* В случае успешного выполнения операции записи *
|
;* If the write operation is successful, the contents *
|
||||||
;* содержимое FDD_DataBuffer будет занесено в сектор. *
|
;* of FDD_DataBuffer will be written to the sector *
|
||||||
;*******************************************************
|
;*******************************************************
|
||||||
WriteSector:
|
WriteSector:
|
||||||
; dbgstr 'WriteSector'
|
; dbgstr 'WriteSector'
|
||||||
pushad
|
pushad
|
||||||
call save_timer_fdd_motor
|
call save_timer_fdd_motor
|
||||||
; Сбросить флаг прерывания
|
; Clear the interrupt flag
|
||||||
mov [FDD_IntFlag], 0
|
mov [FDD_IntFlag], 0
|
||||||
; Установить скорость передачи 500 Кбайт/с
|
; Set transmit speed to 500 Kb / s
|
||||||
mov AX, 0
|
mov AX, 0
|
||||||
mov DX, 03F7h
|
mov DX, 03F7h
|
||||||
out DX, AL
|
out DX, AL
|
||||||
; Инициализировать канал прямого доступа к памяти
|
; Initialize the DMA channel
|
||||||
mov [dmamode], 0x4A
|
mov [dmamode], 0x4A
|
||||||
call Init_FDC_DMA
|
call Init_FDC_DMA
|
||||||
; Подать команду "Запись данных"
|
; Send "Write data" command
|
||||||
mov AL, 0xC5 ;0x45 ;запись в мультитрековом режиме
|
mov AL, 0xC5 ;0x45 ; write in multi-track mode
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
mov AL, [FDD_Head]
|
mov AL, [FDD_Head]
|
||||||
shl AL, 2
|
shl AL, 2
|
||||||
@ -598,19 +598,19 @@ WriteSector:
|
|||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
mov AL, [FDD_Sector]
|
mov AL, [FDD_Sector]
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
mov AL, 2 ;код размера сектора (512 байт)
|
mov AL, 2 ; sector size code (512 bytes)
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
mov AL, 18; 3Fh ;число секторов на дорожке
|
mov AL, 18; 3Fh ; sectors per track
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
mov AL, 1Bh ;значение GPL
|
mov AL, 1Bh ; GPL value
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
mov AL, 0FFh;значение DTL
|
mov AL, 0FFh; DTL value
|
||||||
call FDCDataOutput
|
call FDCDataOutput
|
||||||
; Ожидаем прерывание по завершении операции
|
; Waiting for an interrupt at the end of the operation
|
||||||
call WaitFDCInterrupt
|
call WaitFDCInterrupt
|
||||||
cmp [FDC_Status], FDC_Normal
|
cmp [FDC_Status], FDC_Normal
|
||||||
jne @@Exit_3
|
jne @@Exit_3
|
||||||
; Считываем статус завершения операции
|
; Reading the completion status of the operation
|
||||||
call GetStatusInfo
|
call GetStatusInfo
|
||||||
test [FDC_ST0], 11000000b ;11011000b
|
test [FDC_ST0], 11000000b ;11011000b
|
||||||
jnz @@Err_2
|
jnz @@Err_2
|
||||||
@ -624,21 +624,21 @@ WriteSector:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
;*******************************************************
|
;*******************************************************
|
||||||
;* ЗАПИСЬ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ) *
|
;* WRITE SECTOR (WITH REPEAT ON FAILURE) *
|
||||||
;* Параметры передаются через глобальные переменные: *
|
;* Parameters are passed through global variables: *
|
||||||
;* FDD_Track - номер дорожки (0-79); *
|
;* FDD_Track - track number (0-79); *
|
||||||
;* FDD_Head - номер головки (0-1); *
|
;* FDD_Head - head number (0-1); *
|
||||||
;* FDD_Sector - номер сектора (1-18). *
|
;* FDD_Sector - sector number (1-18). *
|
||||||
;* Результат операции заносится в FDC_Status. *
|
;* Result of operation is written to FDC_Status. *
|
||||||
;* В случае успешного выполнения операции записи *
|
;* If the write operation is successful, the contents *
|
||||||
;* содержимое FDD_DataBuffer будет занесено в сектор. *
|
;* of FDD_DataBuffer will be written to the sector *
|
||||||
;*******************************************************
|
;*******************************************************
|
||||||
WriteSectWithRetr:
|
WriteSectWithRetr:
|
||||||
pusha
|
pusha
|
||||||
; Обнулить счетчик повторения операции рекалибровки
|
; Reset the recalibration repetition counter
|
||||||
mov [RecalRepCounter], 0
|
mov [RecalRepCounter], 0
|
||||||
@@TryAgain_1:
|
@@TryAgain_1:
|
||||||
; Обнулить счетчик повторения операции чтени
|
; Reset the read operation retry counter
|
||||||
mov [ReadRepCounter], 0
|
mov [ReadRepCounter], 0
|
||||||
@@WriteSector_1:
|
@@WriteSector_1:
|
||||||
call WriteSector
|
call WriteSector
|
||||||
@ -646,11 +646,11 @@ WriteSectWithRetr:
|
|||||||
je @@Exit_4
|
je @@Exit_4
|
||||||
cmp [FDC_Status], 1
|
cmp [FDC_Status], 1
|
||||||
je @@Err_4
|
je @@Err_4
|
||||||
; Троекратное повторение чтени
|
; Three times repeat writing
|
||||||
inc [ReadRepCounter]
|
inc [ReadRepCounter]
|
||||||
cmp [ReadRepCounter], 3
|
cmp [ReadRepCounter], 3
|
||||||
jb @@WriteSector_1
|
jb @@WriteSector_1
|
||||||
; Троекратное повторение рекалибровки
|
; Three times repeat recalibration
|
||||||
call RecalibrateFDD
|
call RecalibrateFDD
|
||||||
call SeekTrack
|
call SeekTrack
|
||||||
inc [RecalRepCounter]
|
inc [RecalRepCounter]
|
||||||
@ -664,7 +664,7 @@ WriteSectWithRetr:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
;*********************************************
|
;*********************************************
|
||||||
;* ПОЛУЧИТЬ ИНФОРМАЦИЮ О РЕЗУЛЬТАТЕ ОПЕРАЦИИ *
|
;* GET INFORMATION ABOUT THE RESULT OF THE OPERATION
|
||||||
;*********************************************
|
;*********************************************
|
||||||
GetStatusInfo:
|
GetStatusInfo:
|
||||||
push AX
|
push AX
|
||||||
@ -831,9 +831,9 @@ endp
|
|||||||
|
|
||||||
proc floppy_read_bootsector
|
proc floppy_read_bootsector
|
||||||
pushad
|
pushad
|
||||||
mov [FDD_Track], 0; Цилиндр
|
mov [FDD_Track], 0 ; Cylinder
|
||||||
mov [FDD_Head], 0; Сторона
|
mov [FDD_Head], 0 ; Head
|
||||||
mov [FDD_Sector], 1; Сектор
|
mov [FDD_Sector], 1 ; Sector
|
||||||
call FDDMotorON
|
call FDDMotorON
|
||||||
call RecalibrateFDD
|
call RecalibrateFDD
|
||||||
cmp [FDC_Status], 0
|
cmp [FDC_Status], 0
|
||||||
|
Loading…
Reference in New Issue
Block a user