Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 8053 → Rev 8054

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