2011-10-14 23:38:50 +02:00
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;; ;;
|
2012-03-13 17:51:57 +01:00
|
|
|
|
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;; Distributed under terms of the GNU General Public License ;;
|
|
|
|
|
;; ;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
|
|
$Revision$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;**********************************************************
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Непосредственная работа с контроллером гибкого диска
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;**********************************************************
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Автор исходного текста Кулаков Владимир Геннадьевич.
|
|
|
|
|
; Адаптация и доработка Mario79
|
2011-10-14 23:38:50 +02:00
|
|
|
|
|
2013-05-28 00:16:00 +02:00
|
|
|
|
;give_back_application_data: ; переслать приложению
|
2011-10-14 23:38:50 +02:00
|
|
|
|
; mov edi,[TASK_BASE]
|
|
|
|
|
; mov edi,[edi+TASKDATA.mem_start]
|
|
|
|
|
; add edi,ecx
|
|
|
|
|
give_back_application_data_1:
|
|
|
|
|
mov esi, FDD_BUFF;FDD_DataBuffer ;0x40000
|
|
|
|
|
xor ecx, ecx
|
|
|
|
|
mov cx, 128
|
|
|
|
|
cld
|
|
|
|
|
rep movsd
|
|
|
|
|
ret
|
|
|
|
|
|
2013-05-28 00:16:00 +02:00
|
|
|
|
;take_data_from_application: ; взять из приложени
|
2011-10-14 23:38:50 +02:00
|
|
|
|
; mov esi,[TASK_BASE]
|
|
|
|
|
; mov esi,[esi+TASKDATA.mem_start]
|
|
|
|
|
; add esi,ecx
|
|
|
|
|
take_data_from_application_1:
|
|
|
|
|
mov edi, FDD_BUFF;FDD_DataBuffer ;0x40000
|
|
|
|
|
xor ecx, ecx
|
|
|
|
|
mov cx, 128
|
|
|
|
|
cld
|
|
|
|
|
rep movsd
|
|
|
|
|
ret
|
|
|
|
|
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Коды завершения операции с контроллером (FDC_Status)
|
|
|
|
|
FDC_Normal equ 0 ;нормальное завершение
|
|
|
|
|
FDC_TimeOut equ 1 ;ошибка тайм-аута
|
|
|
|
|
FDC_DiskNotFound equ 2 ;в дисководе нет диска
|
|
|
|
|
FDC_TrackNotFound equ 3 ;дорожка не найдена
|
|
|
|
|
FDC_SectorNotFound equ 4 ;сектор не найден
|
2011-10-14 23:38:50 +02:00
|
|
|
|
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Максимальные значения координат сектора (заданные
|
|
|
|
|
; значения соответствуют параметрам стандартного
|
|
|
|
|
; трехдюймового гибкого диска объемом 1,44 Мб)
|
2011-10-14 23:38:50 +02:00
|
|
|
|
MAX_Track equ 79
|
|
|
|
|
MAX_Head equ 1
|
|
|
|
|
MAX_Sector equ 18
|
|
|
|
|
|
|
|
|
|
uglobal
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Счетчик тиков таймера
|
2011-10-14 23:38:50 +02:00
|
|
|
|
TickCounter dd ?
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Код завершения операции с контроллером НГМД
|
2011-10-14 23:38:50 +02:00
|
|
|
|
FDC_Status DB ?
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Флаг прерывания от НГМД
|
2011-10-14 23:38:50 +02:00
|
|
|
|
FDD_IntFlag DB ?
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Момент начала последней операции с НГМД
|
2011-10-14 23:38:50 +02:00
|
|
|
|
FDD_Time DD ?
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Номер дисковода
|
2011-10-14 23:38:50 +02:00
|
|
|
|
FDD_Type db 0
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Координаты сектора
|
2011-10-14 23:38:50 +02:00
|
|
|
|
FDD_Track DB ?
|
|
|
|
|
FDD_Head DB ?
|
|
|
|
|
FDD_Sector DB ?
|
|
|
|
|
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Блок результата операции
|
2011-10-14 23:38:50 +02:00
|
|
|
|
FDC_ST0 DB ?
|
|
|
|
|
FDC_ST1 DB ?
|
|
|
|
|
FDC_ST2 DB ?
|
|
|
|
|
FDC_C DB ?
|
|
|
|
|
FDC_H DB ?
|
|
|
|
|
FDC_R DB ?
|
|
|
|
|
FDC_N DB ?
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Счетчик повторения операции чтени
|
2011-10-14 23:38:50 +02:00
|
|
|
|
ReadRepCounter DB ?
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Счетчик повторения операции рекалибровки
|
2011-10-14 23:38:50 +02:00
|
|
|
|
RecalRepCounter DB ?
|
|
|
|
|
endg
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Область памяти для хранения прочитанного сектора
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;FDD_DataBuffer: times 512 db 0 ;DB 512 DUP (?)
|
|
|
|
|
fdd_motor_status db 0
|
|
|
|
|
timer_fdd_motor dd 0
|
|
|
|
|
|
|
|
|
|
;*************************************
|
2013-05-28 00:16:00 +02:00
|
|
|
|
;* ИНИЦИАЛИЗАЦИЯ РЕЖИМА ПДП ДЛЯ НГМД *
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;*************************************
|
|
|
|
|
Init_FDC_DMA:
|
|
|
|
|
pushad
|
|
|
|
|
mov al, 0
|
|
|
|
|
out 0x0c, al; reset the flip-flop to a known state.
|
|
|
|
|
mov al, 6 ; mask channel 2 so we can reprogram it.
|
|
|
|
|
out 0x0a, al
|
|
|
|
|
mov al, [dmamode]; 0x46 -> Read from floppy - 0x4A Write to floppy
|
|
|
|
|
out 0x0b, al
|
|
|
|
|
mov al, 0
|
|
|
|
|
out 0x0c, al; reset the flip-flop to a known state.
|
|
|
|
|
mov eax, 0xD000
|
|
|
|
|
out 0x04, al; set the channel 2 starting address to 0
|
|
|
|
|
shr eax, 8
|
|
|
|
|
out 0x04, al
|
|
|
|
|
shr eax, 8
|
|
|
|
|
out 0x81, al
|
|
|
|
|
mov al, 0
|
|
|
|
|
out 0x0c, al; reset flip-flop
|
|
|
|
|
mov al, 0xff;set count (actual size -1)
|
|
|
|
|
out 0x5, al
|
|
|
|
|
mov al, 0x1;[dmasize] ;(0x1ff = 511 / 0x23ff =9215)
|
|
|
|
|
out 0x5, al
|
|
|
|
|
mov al, 2
|
|
|
|
|
out 0xa, al
|
|
|
|
|
popad
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;***********************************
|
2013-05-28 00:16:00 +02:00
|
|
|
|
;* ЗАПИСАТЬ БАЙТ В ПОРТ ДАННЫХ FDC *
|
|
|
|
|
;* Параметры: *
|
|
|
|
|
;* AL - выводимый байт. *
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;***********************************
|
|
|
|
|
FDCDataOutput:
|
|
|
|
|
; pusha
|
|
|
|
|
push eax ecx edx
|
2013-05-28 00:16:00 +02:00
|
|
|
|
mov AH, AL ;запомнить байт в AH
|
|
|
|
|
; Сбросить переменную состояния контроллера
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov [FDC_Status], FDC_Normal
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Проверить готовность контроллера к приему данных
|
|
|
|
|
mov DX, 3F4h ;(порт состояния FDC)
|
|
|
|
|
mov ecx, 0x10000 ;установить счетчик тайм-аута
|
2011-10-14 23:38:50 +02:00
|
|
|
|
@@TestRS:
|
2013-05-28 00:16:00 +02:00
|
|
|
|
in AL, DX ;прочитать регистр RS
|
|
|
|
|
and AL, 0C0h ;выделить разряды 6 и 7
|
|
|
|
|
cmp AL, 80h ;проверить разряды 6 и 7
|
2011-10-14 23:38:50 +02:00
|
|
|
|
je @@OutByteToFDC
|
|
|
|
|
loop @@TestRS
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Ошибка тайм-аута
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov [FDC_Status], FDC_TimeOut
|
|
|
|
|
jmp @@End_5
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Вывести байт в порт данных
|
2011-10-14 23:38:50 +02:00
|
|
|
|
@@OutByteToFDC:
|
|
|
|
|
inc DX
|
|
|
|
|
mov AL, AH
|
|
|
|
|
out DX, AL
|
|
|
|
|
@@End_5:
|
|
|
|
|
; popa
|
|
|
|
|
pop edx ecx eax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;******************************************
|
2013-05-28 00:16:00 +02:00
|
|
|
|
;* ПРОЧИТАТЬ БАЙТ ИЗ ПОРТА ДАННЫХ FDC *
|
|
|
|
|
;* Процедура не имеет входных параметров. *
|
|
|
|
|
;* Выходные данные: *
|
|
|
|
|
;* AL - считанный байт. *
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;******************************************
|
|
|
|
|
FDCDataInput:
|
|
|
|
|
push ECX
|
|
|
|
|
push DX
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Сбросить переменную состояния контроллера
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov [FDC_Status], FDC_Normal
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Проверить готовность контроллера к передаче данных
|
|
|
|
|
mov DX, 3F4h ;(порт состояния FDC)
|
|
|
|
|
xor CX, CX ;установить счетчик тайм-аута
|
2011-10-14 23:38:50 +02:00
|
|
|
|
@@TestRS_1:
|
2013-05-28 00:16:00 +02:00
|
|
|
|
in AL, DX ;прочитать регистр RS
|
|
|
|
|
and AL, 0C0h ;выдлить разряды 6 и 7
|
|
|
|
|
cmp AL, 0C0h ;проверить разряды 6 и 7
|
2011-10-14 23:38:50 +02:00
|
|
|
|
je @@GetByteFromFDC
|
|
|
|
|
loop @@TestRS_1
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Ошибка тайм-аута
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov [FDC_Status], FDC_TimeOut
|
|
|
|
|
jmp @@End_6
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Ввести байт из порта данных
|
2011-10-14 23:38:50 +02:00
|
|
|
|
@@GetByteFromFDC:
|
|
|
|
|
inc DX
|
|
|
|
|
in AL, DX
|
|
|
|
|
@@End_6:
|
|
|
|
|
pop DX
|
|
|
|
|
pop ECX
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*********************************************
|
2013-05-28 00:16:00 +02:00
|
|
|
|
;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД *
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;*********************************************
|
|
|
|
|
FDCInterrupt:
|
2013-07-06 13:33:30 +02:00
|
|
|
|
; Установить флаг прерывания
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov [FDD_IntFlag], 1
|
2013-07-06 13:33:30 +02:00
|
|
|
|
mov al, 1
|
2011-10-14 23:38:50 +02:00
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*******************************************
|
2013-05-28 00:16:00 +02:00
|
|
|
|
;* ОЖИДАНИЕ ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД *
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;*******************************************
|
|
|
|
|
WaitFDCInterrupt:
|
|
|
|
|
pusha
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Сбросить байт состояния операции
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov [FDC_Status], FDC_Normal
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Сбросить флаг прерывани
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov [FDD_IntFlag], 0
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Обнулить счетчик тиков
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov eax, [timer_ticks]
|
|
|
|
|
mov [TickCounter], eax
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Ожидать установки флага прерывания НГМД
|
2011-10-14 23:38:50 +02:00
|
|
|
|
@@TestRS_2:
|
2013-07-06 13:33:30 +02:00
|
|
|
|
call change_task
|
2011-10-14 23:38:50 +02:00
|
|
|
|
cmp [FDD_IntFlag], 0
|
2013-05-28 00:16:00 +02:00
|
|
|
|
jnz @@End_7 ;прерывание произошло
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov eax, [timer_ticks]
|
|
|
|
|
sub eax, [TickCounter]
|
2013-05-28 00:16:00 +02:00
|
|
|
|
cmp eax, 50 ;25 ;5 ;ожидать 5 тиков
|
2011-10-14 23:38:50 +02:00
|
|
|
|
jb @@TestRS_2
|
|
|
|
|
; jl @@TestRS_2
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Ошибка тайм-аута
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov [FDC_Status], FDC_TimeOut
|
|
|
|
|
; mov [flp_status],0
|
|
|
|
|
@@End_7:
|
|
|
|
|
popa
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*********************************
|
2013-05-28 00:16:00 +02:00
|
|
|
|
;* ВКЛЮЧИТЬ МОТОР ДИСКОВОДА "A:" *
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;*********************************
|
|
|
|
|
FDDMotorON:
|
|
|
|
|
pusha
|
|
|
|
|
; cmp [fdd_motor_status],1
|
|
|
|
|
; je fdd_motor_on
|
|
|
|
|
mov al, [flp_number]
|
|
|
|
|
cmp [fdd_motor_status], al
|
|
|
|
|
je fdd_motor_on
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Произвести сброс контроллера НГМД
|
|
|
|
|
mov DX, 3F2h;порт управления двигателями
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov AL, 0
|
|
|
|
|
out DX, AL
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Выбрать и включить мотор дисковода
|
2011-10-14 23:38:50 +02:00
|
|
|
|
cmp [flp_number], 1
|
|
|
|
|
jne FDDMotorON_B
|
|
|
|
|
; call FDDMotorOFF_B
|
|
|
|
|
mov AL, 1Ch ; Floppy A
|
|
|
|
|
jmp FDDMotorON_1
|
|
|
|
|
FDDMotorON_B:
|
|
|
|
|
; call FDDMotorOFF_A
|
|
|
|
|
mov AL, 2Dh ; Floppy B
|
|
|
|
|
FDDMotorON_1:
|
|
|
|
|
out DX, AL
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Обнулить счетчик тиков
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov eax, [timer_ticks]
|
|
|
|
|
mov [TickCounter], eax
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Ожидать 0,5 с
|
2011-10-14 23:38:50 +02:00
|
|
|
|
@@dT:
|
|
|
|
|
call change_task
|
|
|
|
|
mov eax, [timer_ticks]
|
|
|
|
|
sub eax, [TickCounter]
|
|
|
|
|
cmp eax, 50 ;10
|
|
|
|
|
jb @@dT
|
|
|
|
|
cmp [flp_number], 1
|
|
|
|
|
jne fdd_motor_on_B
|
|
|
|
|
mov [fdd_motor_status], 1
|
|
|
|
|
jmp fdd_motor_on
|
|
|
|
|
fdd_motor_on_B:
|
|
|
|
|
mov [fdd_motor_status], 2
|
|
|
|
|
fdd_motor_on:
|
|
|
|
|
call save_timer_fdd_motor
|
|
|
|
|
popa
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*****************************************
|
2013-05-28 00:16:00 +02:00
|
|
|
|
;* СОХРАНЕНИЕ УКАЗАТЕЛЯ ВРЕМЕНИ *
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;*****************************************
|
|
|
|
|
save_timer_fdd_motor:
|
|
|
|
|
mov eax, [timer_ticks]
|
|
|
|
|
mov [timer_fdd_motor], eax
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*****************************************
|
2013-05-28 00:16:00 +02:00
|
|
|
|
;* ПРОВЕРКА ЗАДЕРЖКИ ВЫКЛЮЧЕНИЯ МОТОРА *
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;*****************************************
|
2013-05-27 11:02:35 +02:00
|
|
|
|
proc check_fdd_motor_status_has_work?
|
|
|
|
|
cmp [flp_status], 0
|
|
|
|
|
jnz .yes
|
|
|
|
|
cmp [fdd_motor_status], 0
|
|
|
|
|
jz .no
|
|
|
|
|
mov eax, [timer_ticks]
|
|
|
|
|
sub eax, [timer_fdd_motor]
|
|
|
|
|
cmp eax, 500
|
|
|
|
|
jb .no
|
|
|
|
|
.yes:
|
|
|
|
|
xor eax, eax
|
|
|
|
|
inc eax
|
|
|
|
|
ret
|
|
|
|
|
.no:
|
|
|
|
|
xor eax, eax
|
|
|
|
|
ret
|
|
|
|
|
endp
|
|
|
|
|
|
2011-10-14 23:38:50 +02:00
|
|
|
|
align 4
|
|
|
|
|
check_fdd_motor_status:
|
|
|
|
|
cmp [fdd_motor_status], 0
|
|
|
|
|
je end_check_fdd_motor_status_1
|
|
|
|
|
mov eax, [timer_ticks]
|
|
|
|
|
sub eax, [timer_fdd_motor]
|
|
|
|
|
cmp eax, 500
|
|
|
|
|
jb end_check_fdd_motor_status
|
|
|
|
|
call FDDMotorOFF
|
|
|
|
|
mov [fdd_motor_status], 0
|
|
|
|
|
end_check_fdd_motor_status_1:
|
|
|
|
|
mov [flp_status], 0
|
|
|
|
|
end_check_fdd_motor_status:
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;**********************************
|
2013-05-28 00:16:00 +02:00
|
|
|
|
;* ВЫКЛЮЧИТЬ МОТОР ДИСКОВОДА *
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;**********************************
|
|
|
|
|
FDDMotorOFF:
|
|
|
|
|
push AX
|
|
|
|
|
push DX
|
|
|
|
|
cmp [flp_number], 1
|
|
|
|
|
jne FDDMotorOFF_1
|
|
|
|
|
call FDDMotorOFF_A
|
|
|
|
|
jmp FDDMotorOFF_2
|
|
|
|
|
FDDMotorOFF_1:
|
|
|
|
|
call FDDMotorOFF_B
|
|
|
|
|
FDDMotorOFF_2:
|
|
|
|
|
pop DX
|
|
|
|
|
pop AX
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; сброс флагов кеширования в связи с устареванием информации
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov [root_read], 0
|
|
|
|
|
mov [flp_fat], 0
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
FDDMotorOFF_A:
|
2013-05-28 00:16:00 +02:00
|
|
|
|
mov DX, 3F2h;порт управления двигателями
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov AL, 0Ch ; Floppy A
|
|
|
|
|
out DX, AL
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
FDDMotorOFF_B:
|
2013-05-28 00:16:00 +02:00
|
|
|
|
mov DX, 3F2h;порт управления двигателями
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov AL, 5h ; Floppy B
|
|
|
|
|
out DX, AL
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*******************************
|
2013-05-28 00:16:00 +02:00
|
|
|
|
;* РЕКАЛИБРОВКА ДИСКОВОДА "A:" *
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;*******************************
|
|
|
|
|
RecalibrateFDD:
|
|
|
|
|
pusha
|
|
|
|
|
call save_timer_fdd_motor
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Подать команду "Рекалибровка"
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov AL, 07h
|
|
|
|
|
call FDCDataOutput
|
|
|
|
|
mov AL, 00h
|
|
|
|
|
call FDCDataOutput
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Ожидать завершения операции
|
2011-10-14 23:38:50 +02:00
|
|
|
|
call WaitFDCInterrupt
|
|
|
|
|
; cmp [FDC_Status],0
|
|
|
|
|
; je no_fdc_status_error
|
|
|
|
|
; mov [flp_status],0
|
|
|
|
|
;no_fdc_status_error:
|
|
|
|
|
call save_timer_fdd_motor
|
|
|
|
|
popa
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*****************************************************
|
2013-05-28 00:16:00 +02:00
|
|
|
|
;* ПОИСК ДОРОЖКИ *
|
|
|
|
|
;* Параметры передаются через глобальные переменные: *
|
|
|
|
|
;* FDD_Track - номер дорожки (0-79); *
|
|
|
|
|
;* FDD_Head - номер головки (0-1). *
|
|
|
|
|
;* Результат операции заносится в FDC_Status. *
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;*****************************************************
|
|
|
|
|
SeekTrack:
|
|
|
|
|
pusha
|
|
|
|
|
call save_timer_fdd_motor
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Подать команду "Поиск"
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov AL, 0Fh
|
|
|
|
|
call FDCDataOutput
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Передать байт номера головки/накопител
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov AL, [FDD_Head]
|
|
|
|
|
shl AL, 2
|
|
|
|
|
call FDCDataOutput
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Передать байт номера дорожки
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov AL, [FDD_Track]
|
|
|
|
|
call FDCDataOutput
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Ожидать завершения операции
|
2011-10-14 23:38:50 +02:00
|
|
|
|
call WaitFDCInterrupt
|
|
|
|
|
cmp [FDC_Status], FDC_Normal
|
|
|
|
|
jne @@Exit
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Сохранить результат поиска
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov AL, 08h
|
|
|
|
|
call FDCDataOutput
|
|
|
|
|
call FDCDataInput
|
|
|
|
|
mov [FDC_ST0], AL
|
|
|
|
|
call FDCDataInput
|
|
|
|
|
mov [FDC_C], AL
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Проверить результат поиска
|
|
|
|
|
; Поиск завершен?
|
2011-10-14 23:38:50 +02:00
|
|
|
|
test [FDC_ST0], 100000b
|
|
|
|
|
je @@Err
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Заданный трек найден?
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov AL, [FDC_C]
|
|
|
|
|
cmp AL, [FDD_Track]
|
|
|
|
|
jne @@Err
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Номер головки совпадает с заданным?
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov AL, [FDC_ST0]
|
|
|
|
|
and AL, 100b
|
|
|
|
|
shr AL, 2
|
|
|
|
|
cmp AL, [FDD_Head]
|
|
|
|
|
jne @@Err
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Операция завершена успешно
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov [FDC_Status], FDC_Normal
|
|
|
|
|
jmp @@Exit
|
2013-05-28 00:16:00 +02:00
|
|
|
|
@@Err: ; Трек не найден
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov [FDC_Status], FDC_TrackNotFound
|
|
|
|
|
; mov [flp_status],0
|
|
|
|
|
@@Exit:
|
|
|
|
|
call save_timer_fdd_motor
|
|
|
|
|
popa
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*******************************************************
|
2013-05-28 00:16:00 +02:00
|
|
|
|
;* ЧТЕНИЕ СЕКТОРА ДАННЫХ *
|
|
|
|
|
;* Параметры передаются через глобальные переменные: *
|
|
|
|
|
;* FDD_Track - номер дорожки (0-79); *
|
|
|
|
|
;* FDD_Head - номер головки (0-1); *
|
|
|
|
|
;* FDD_Sector - номер сектора (1-18). *
|
|
|
|
|
;* Результат операции заносится в FDC_Status. *
|
|
|
|
|
;* В случае успешного выполнения операции чтения *
|
|
|
|
|
;* содержимое сектора будет занесено в FDD_DataBuffer. *
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;*******************************************************
|
|
|
|
|
ReadSector:
|
|
|
|
|
pushad
|
|
|
|
|
call save_timer_fdd_motor
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Установить скорость передачи 500 Кбайт/с
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov AX, 0
|
|
|
|
|
mov DX, 03F7h
|
|
|
|
|
out DX, AL
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Инициализировать канал прямого доступа к памяти
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov [dmamode], 0x46
|
|
|
|
|
call Init_FDC_DMA
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Подать команду "Чтение данных"
|
|
|
|
|
mov AL, 0E6h ;чтение в мультитрековом режиме
|
2011-10-14 23:38:50 +02:00
|
|
|
|
call FDCDataOutput
|
|
|
|
|
mov AL, [FDD_Head]
|
|
|
|
|
shl AL, 2
|
|
|
|
|
call FDCDataOutput
|
|
|
|
|
mov AL, [FDD_Track]
|
|
|
|
|
call FDCDataOutput
|
|
|
|
|
mov AL, [FDD_Head]
|
|
|
|
|
call FDCDataOutput
|
|
|
|
|
mov AL, [FDD_Sector]
|
|
|
|
|
call FDCDataOutput
|
2013-05-28 00:16:00 +02:00
|
|
|
|
mov AL, 2 ;код размера сектора (512 байт)
|
2011-10-14 23:38:50 +02:00
|
|
|
|
call FDCDataOutput
|
2013-05-28 00:16:00 +02:00
|
|
|
|
mov AL, 18 ;+1; 3Fh ;число секторов на дорожке
|
2011-10-14 23:38:50 +02:00
|
|
|
|
call FDCDataOutput
|
2013-05-28 00:16:00 +02:00
|
|
|
|
mov AL, 1Bh ;значение GPL
|
2011-10-14 23:38:50 +02:00
|
|
|
|
call FDCDataOutput
|
2013-05-28 00:16:00 +02:00
|
|
|
|
mov AL, 0FFh;значение DTL
|
2011-10-14 23:38:50 +02:00
|
|
|
|
call FDCDataOutput
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Ожидаем прерывание по завершении операции
|
2011-10-14 23:38:50 +02:00
|
|
|
|
call WaitFDCInterrupt
|
|
|
|
|
cmp [FDC_Status], FDC_Normal
|
|
|
|
|
jne @@Exit_1
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Считываем статус завершения операции
|
2011-10-14 23:38:50 +02:00
|
|
|
|
call GetStatusInfo
|
|
|
|
|
test [FDC_ST0], 11011000b
|
|
|
|
|
jnz @@Err_1
|
|
|
|
|
mov [FDC_Status], FDC_Normal
|
|
|
|
|
jmp @@Exit_1
|
|
|
|
|
@@Err_1:
|
|
|
|
|
mov [FDC_Status], FDC_SectorNotFound
|
|
|
|
|
; mov [flp_status],0
|
|
|
|
|
@@Exit_1:
|
|
|
|
|
call save_timer_fdd_motor
|
|
|
|
|
popad
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*******************************************************
|
2013-05-28 00:16:00 +02:00
|
|
|
|
;* ЧТЕНИЕ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ) *
|
|
|
|
|
;* Параметры передаются через глобальные переменные: *
|
|
|
|
|
;* FDD_Track - номер дорожки (0-79); *
|
|
|
|
|
;* FDD_Head - номер головки (0-1); *
|
|
|
|
|
;* FDD_Sector - номер сектора (1-18). *
|
|
|
|
|
;* Результат операции заносится в FDC_Status. *
|
|
|
|
|
;* В случае успешного выполнения операции чтения *
|
|
|
|
|
;* содержимое сектора будет занесено в FDD_DataBuffer. *
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;*******************************************************
|
|
|
|
|
ReadSectWithRetr:
|
|
|
|
|
pusha
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Обнулить счетчик повторения операции рекалибровки
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov [RecalRepCounter], 0
|
|
|
|
|
@@TryAgain:
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Обнулить счетчик повторения операции чтени
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov [ReadRepCounter], 0
|
|
|
|
|
@@ReadSector_1:
|
|
|
|
|
call ReadSector
|
|
|
|
|
cmp [FDC_Status], 0
|
|
|
|
|
je @@Exit_2
|
|
|
|
|
cmp [FDC_Status], 1
|
|
|
|
|
je @@Err_3
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Троекратное повторение чтени
|
2011-10-14 23:38:50 +02:00
|
|
|
|
inc [ReadRepCounter]
|
|
|
|
|
cmp [ReadRepCounter], 3
|
|
|
|
|
jb @@ReadSector_1
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Троекратное повторение рекалибровки
|
2011-10-14 23:38:50 +02:00
|
|
|
|
call RecalibrateFDD
|
|
|
|
|
call SeekTrack
|
|
|
|
|
inc [RecalRepCounter]
|
|
|
|
|
cmp [RecalRepCounter], 3
|
|
|
|
|
jb @@TryAgain
|
|
|
|
|
; mov [flp_status],0
|
|
|
|
|
@@Exit_2:
|
|
|
|
|
popa
|
|
|
|
|
ret
|
|
|
|
|
@@Err_3:
|
|
|
|
|
mov [flp_status], 0
|
|
|
|
|
popa
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*******************************************************
|
2013-05-28 00:16:00 +02:00
|
|
|
|
;* ЗАПИСЬ СЕКТОРА ДАННЫХ *
|
|
|
|
|
;* Параметры передаются через глобальные переменные: *
|
|
|
|
|
;* FDD_Track - номер дорожки (0-79); *
|
|
|
|
|
;* FDD_Head - номер головки (0-1); *
|
|
|
|
|
;* FDD_Sector - номер сектора (1-18). *
|
|
|
|
|
;* Результат операции заносится в FDC_Status. *
|
|
|
|
|
;* В случае успешного выполнения операции записи *
|
|
|
|
|
;* содержимое FDD_DataBuffer будет занесено в сектор. *
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;*******************************************************
|
|
|
|
|
WriteSector:
|
|
|
|
|
pushad
|
|
|
|
|
call save_timer_fdd_motor
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Установить скорость передачи 500 Кбайт/с
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov AX, 0
|
|
|
|
|
mov DX, 03F7h
|
|
|
|
|
out DX, AL
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Инициализировать канал прямого доступа к памяти
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov [dmamode], 0x4A
|
|
|
|
|
call Init_FDC_DMA
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Подать команду "Запись данных"
|
|
|
|
|
mov AL, 0xC5 ;0x45 ;запись в мультитрековом режиме
|
2011-10-14 23:38:50 +02:00
|
|
|
|
call FDCDataOutput
|
|
|
|
|
mov AL, [FDD_Head]
|
|
|
|
|
shl AL, 2
|
|
|
|
|
call FDCDataOutput
|
|
|
|
|
mov AL, [FDD_Track]
|
|
|
|
|
call FDCDataOutput
|
|
|
|
|
mov AL, [FDD_Head]
|
|
|
|
|
call FDCDataOutput
|
|
|
|
|
mov AL, [FDD_Sector]
|
|
|
|
|
call FDCDataOutput
|
2013-05-28 00:16:00 +02:00
|
|
|
|
mov AL, 2 ;код размера сектора (512 байт)
|
2011-10-14 23:38:50 +02:00
|
|
|
|
call FDCDataOutput
|
2013-05-28 00:16:00 +02:00
|
|
|
|
mov AL, 18; 3Fh ;число секторов на дорожке
|
2011-10-14 23:38:50 +02:00
|
|
|
|
call FDCDataOutput
|
2013-05-28 00:16:00 +02:00
|
|
|
|
mov AL, 1Bh ;значение GPL
|
2011-10-14 23:38:50 +02:00
|
|
|
|
call FDCDataOutput
|
2013-05-28 00:16:00 +02:00
|
|
|
|
mov AL, 0FFh;значение DTL
|
2011-10-14 23:38:50 +02:00
|
|
|
|
call FDCDataOutput
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Ожидаем прерывание по завершении операции
|
2011-10-14 23:38:50 +02:00
|
|
|
|
call WaitFDCInterrupt
|
|
|
|
|
cmp [FDC_Status], FDC_Normal
|
|
|
|
|
jne @@Exit_3
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Считываем статус завершения операции
|
2011-10-14 23:38:50 +02:00
|
|
|
|
call GetStatusInfo
|
|
|
|
|
test [FDC_ST0], 11000000b ;11011000b
|
|
|
|
|
jnz @@Err_2
|
|
|
|
|
mov [FDC_Status], FDC_Normal
|
|
|
|
|
jmp @@Exit_3
|
|
|
|
|
@@Err_2:
|
|
|
|
|
mov [FDC_Status], FDC_SectorNotFound
|
|
|
|
|
@@Exit_3:
|
|
|
|
|
call save_timer_fdd_motor
|
|
|
|
|
popad
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*******************************************************
|
2013-05-28 00:16:00 +02:00
|
|
|
|
;* ЗАПИСЬ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ) *
|
|
|
|
|
;* Параметры передаются через глобальные переменные: *
|
|
|
|
|
;* FDD_Track - номер дорожки (0-79); *
|
|
|
|
|
;* FDD_Head - номер головки (0-1); *
|
|
|
|
|
;* FDD_Sector - номер сектора (1-18). *
|
|
|
|
|
;* Результат операции заносится в FDC_Status. *
|
|
|
|
|
;* В случае успешного выполнения операции записи *
|
|
|
|
|
;* содержимое FDD_DataBuffer будет занесено в сектор. *
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;*******************************************************
|
|
|
|
|
WriteSectWithRetr:
|
|
|
|
|
pusha
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Обнулить счетчик повторения операции рекалибровки
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov [RecalRepCounter], 0
|
|
|
|
|
@@TryAgain_1:
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Обнулить счетчик повторения операции чтени
|
2011-10-14 23:38:50 +02:00
|
|
|
|
mov [ReadRepCounter], 0
|
|
|
|
|
@@WriteSector_1:
|
|
|
|
|
call WriteSector
|
|
|
|
|
cmp [FDC_Status], 0
|
|
|
|
|
je @@Exit_4
|
|
|
|
|
cmp [FDC_Status], 1
|
|
|
|
|
je @@Err_4
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Троекратное повторение чтени
|
2011-10-14 23:38:50 +02:00
|
|
|
|
inc [ReadRepCounter]
|
|
|
|
|
cmp [ReadRepCounter], 3
|
|
|
|
|
jb @@WriteSector_1
|
2013-05-28 00:16:00 +02:00
|
|
|
|
; Троекратное повторение рекалибровки
|
2011-10-14 23:38:50 +02:00
|
|
|
|
call RecalibrateFDD
|
|
|
|
|
call SeekTrack
|
|
|
|
|
inc [RecalRepCounter]
|
|
|
|
|
cmp [RecalRepCounter], 3
|
|
|
|
|
jb @@TryAgain_1
|
|
|
|
|
@@Exit_4:
|
|
|
|
|
popa
|
|
|
|
|
ret
|
|
|
|
|
@@Err_4:
|
|
|
|
|
mov [flp_status], 0
|
|
|
|
|
popa
|
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
;*********************************************
|
2013-05-28 00:16:00 +02:00
|
|
|
|
;* ПОЛУЧИТЬ ИНФОРМАЦИЮ О РЕЗУЛЬТАТЕ ОПЕРАЦИИ *
|
2011-10-14 23:38:50 +02:00
|
|
|
|
;*********************************************
|
|
|
|
|
GetStatusInfo:
|
|
|
|
|
push AX
|
|
|
|
|
call FDCDataInput
|
|
|
|
|
mov [FDC_ST0], AL
|
|
|
|
|
call FDCDataInput
|
|
|
|
|
mov [FDC_ST1], AL
|
|
|
|
|
call FDCDataInput
|
|
|
|
|
mov [FDC_ST2], AL
|
|
|
|
|
call FDCDataInput
|
|
|
|
|
mov [FDC_C], AL
|
|
|
|
|
call FDCDataInput
|
|
|
|
|
mov [FDC_H], AL
|
|
|
|
|
call FDCDataInput
|
|
|
|
|
mov [FDC_R], AL
|
|
|
|
|
call FDCDataInput
|
|
|
|
|
mov [FDC_N], AL
|
|
|
|
|
pop AX
|
|
|
|
|
ret
|
|
|
|
|
|