9,12 → 9,12 |
|
|
;********************************************************** |
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ êîíòðîëëåðîì ãèáêîãî äèñêà |
; Непосредственная работа с контроллером гибкого диска |
;********************************************************** |
; Àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; Àäàïòàöèÿ è äîðàáîòêà Mario79 |
; Автор исходного текста Кулаков Владимир Геннадьевич. |
; Адаптация и доработка Mario79 |
|
;give_back_application_data: ; ïåðåñëàòü ïðèëîæåíèþ |
;give_back_application_data: ; переслать приложению |
; mov edi,[TASK_BASE] |
; mov edi,[edi+TASKDATA.mem_start] |
; add edi,ecx |
26,7 → 26,7 |
rep movsd |
ret |
|
;take_data_from_application: ; âçÿòü èç ïðèëîæåíè |
;take_data_from_application: ; взять из приложени |
; mov esi,[TASK_BASE] |
; mov esi,[esi+TASKDATA.mem_start] |
; add esi,ecx |
38,37 → 38,37 |
rep movsd |
ret |
|
; Êîäû çàâåðøåíèÿ îïåðàöèè ñ êîíòðîëëåðîì (FDC_Status) |
FDC_Normal equ 0 ;íîðìàëüíîå çàâåðøåíèå |
FDC_TimeOut equ 1 ;îøèáêà òàéì-àóòà |
FDC_DiskNotFound equ 2 ;â äèñêîâîäå íåò äèñêà |
FDC_TrackNotFound equ 3 ;äîðîæêà íå íàéäåíà |
FDC_SectorNotFound equ 4 ;ñåêòîð íå íàéäåí |
; Коды завершения операции с контроллером (FDC_Status) |
FDC_Normal equ 0 ;нормальное завершение |
FDC_TimeOut equ 1 ;ошибка тайм-аута |
FDC_DiskNotFound equ 2 ;в дисководе нет диска |
FDC_TrackNotFound equ 3 ;дорожка не найдена |
FDC_SectorNotFound equ 4 ;сектор не найден |
|
; Ìàêñèìàëüíûå çíà÷åíèÿ êîîðäèíàò ñåêòîðà (çàäàííûå |
; çíà÷åíèÿ ñîîòâåòñòâóþò ïàðàìåòðàì ñòàíäàðòíîãî |
; òðåõäþéìîâîãî ãèáêîãî äèñêà îáúåìîì 1,44 Ìá) |
; Максимальные значения координат сектора (заданные |
; значения соответствуют параметрам стандартного |
; трехдюймового гибкого диска объемом 1,44 Мб) |
MAX_Track equ 79 |
MAX_Head equ 1 |
MAX_Sector equ 18 |
|
uglobal |
; Ñ÷åò÷èê òèêîâ òàéìåðà |
; Счетчик тиков таймера |
TickCounter dd ? |
; Êîä çàâåðøåíèÿ îïåðàöèè ñ êîíòðîëëåðîì ÍÃÌÄ |
; Код завершения операции с контроллером НГМД |
FDC_Status DB ? |
; Ôëàã ïðåðûâàíèÿ îò ÍÃÌÄ |
; Флаг прерывания от НГМД |
FDD_IntFlag DB ? |
; Ìîìåíò íà÷àëà ïîñëåäíåé îïåðàöèè ñ ÍÃÌÄ |
; Момент начала последней операции с НГМД |
FDD_Time DD ? |
; Íîìåð äèñêîâîäà |
; Номер дисковода |
FDD_Type db 0 |
; Êîîðäèíàòû ñåêòîðà |
; Координаты сектора |
FDD_Track DB ? |
FDD_Head DB ? |
FDD_Sector DB ? |
|
; Áëîê ðåçóëüòàòà îïåðàöèè |
; Блок результата операции |
FDC_ST0 DB ? |
FDC_ST1 DB ? |
FDC_ST2 DB ? |
76,18 → 76,18 |
FDC_H DB ? |
FDC_R DB ? |
FDC_N DB ? |
; Ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè |
; Счетчик повторения операции чтени |
ReadRepCounter DB ? |
; Ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
; Счетчик повторения операции рекалибровки |
RecalRepCounter DB ? |
endg |
; Îáëàñòü ïàìÿòè äëÿ õðàíåíèÿ ïðî÷èòàííîãî ñåêòîðà |
; Область памяти для хранения прочитанного сектора |
;FDD_DataBuffer: times 512 db 0 ;DB 512 DUP (?) |
fdd_motor_status db 0 |
timer_fdd_motor dd 0 |
|
;************************************* |
;* ÈÍÈÖÈÀËÈÇÀÖÈß ÐÅÆÈÌÀ ÏÄÏ ÄËß ÍÃÌÄ * |
;* ИНИЦИАЛИЗАЦИЯ РЕЖИМА ПДП ДЛЯ НГМД * |
;************************************* |
Init_FDC_DMA: |
pushad |
117,29 → 117,29 |
ret |
|
;*********************************** |
;* ÇÀÏÈÑÀÒÜ ÁÀÉÒ Â ÏÎÐÒ ÄÀÍÍÛÕ FDC * |
;* Ïàðàìåòðû: * |
;* AL - âûâîäèìûé áàéò. * |
;* ЗАПИСАТЬ БАЙТ В ПОРТ ДАННЫХ FDC * |
;* Параметры: * |
;* AL - выводимый байт. * |
;*********************************** |
FDCDataOutput: |
; pusha |
push eax ecx edx |
mov AH, AL ;çàïîìíèòü áàéò â AH |
; Ñáðîñèòü ïåðåìåííóþ ñîñòîÿíèÿ êîíòðîëëåðà |
mov AH, AL ;запомнить байт в AH |
; Сбросить переменную состояния контроллера |
mov [FDC_Status], FDC_Normal |
; Ïðîâåðèòü ãîòîâíîñòü êîíòðîëëåðà ê ïðèåìó äàííûõ |
mov DX, 3F4h ;(ïîðò ñîñòîÿíèÿ FDC) |
mov ecx, 0x10000 ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà |
; Проверить готовность контроллера к приему данных |
mov DX, 3F4h ;(порт состояния FDC) |
mov ecx, 0x10000 ;установить счетчик тайм-аута |
@@TestRS: |
in AL, DX ;ïðî÷èòàòü ðåãèñòð RS |
and AL, 0C0h ;âûäåëèòü ðàçðÿäû 6 è 7 |
cmp AL, 80h ;ïðîâåðèòü ðàçðÿäû 6 è 7 |
in AL, DX ;прочитать регистр RS |
and AL, 0C0h ;выделить разряды 6 и 7 |
cmp AL, 80h ;проверить разряды 6 и 7 |
je @@OutByteToFDC |
loop @@TestRS |
; Îøèáêà òàéì-àóòà |
; Ошибка тайм-аута |
mov [FDC_Status], FDC_TimeOut |
jmp @@End_5 |
; Âûâåñòè áàéò â ïîðò äàííûõ |
; Вывести байт в порт данных |
@@OutByteToFDC: |
inc DX |
mov AL, AH |
150,29 → 150,29 |
ret |
|
;****************************************** |
;* ÏÐÎ×ÈÒÀÒÜ ÁÀÉÒ ÈÇ ÏÎÐÒÀ ÄÀÍÍÛÕ FDC * |
;* Ïðîöåäóðà íå èìååò âõîäíûõ ïàðàìåòðîâ. * |
;* Âûõîäíûå äàííûå: * |
;* AL - ñ÷èòàííûé áàéò. * |
;* ПРОЧИТАТЬ БАЙТ ИЗ ПОРТА ДАННЫХ FDC * |
;* Процедура не имеет входных параметров. * |
;* Выходные данные: * |
;* AL - считанный байт. * |
;****************************************** |
FDCDataInput: |
push ECX |
push DX |
; Ñáðîñèòü ïåðåìåííóþ ñîñòîÿíèÿ êîíòðîëëåðà |
; Сбросить переменную состояния контроллера |
mov [FDC_Status], FDC_Normal |
; Ïðîâåðèòü ãîòîâíîñòü êîíòðîëëåðà ê ïåðåäà÷å äàííûõ |
mov DX, 3F4h ;(ïîðò ñîñòîÿíèÿ FDC) |
xor CX, CX ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà |
; Проверить готовность контроллера к передаче данных |
mov DX, 3F4h ;(порт состояния FDC) |
xor CX, CX ;установить счетчик тайм-аута |
@@TestRS_1: |
in AL, DX ;ïðî÷èòàòü ðåãèñòð RS |
and AL, 0C0h ;âûäëèòü ðàçðÿäû 6 è 7 |
cmp AL, 0C0h ;ïðîâåðèòü ðàçðÿäû 6 è 7 |
in AL, DX ;прочитать регистр RS |
and AL, 0C0h ;выдлить разряды 6 и 7 |
cmp AL, 0C0h ;проверить разряды 6 и 7 |
je @@GetByteFromFDC |
loop @@TestRS_1 |
; Îøèáêà òàéì-àóòà |
; Ошибка тайм-аута |
mov [FDC_Status], FDC_TimeOut |
jmp @@End_6 |
; Ââåñòè áàéò èç ïîðòà äàííûõ |
; Ввести байт из порта данных |
@@GetByteFromFDC: |
inc DX |
in AL, DX |
182,17 → 182,17 |
ret |
|
;********************************************* |
;* ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈß ÎÒ ÊÎÍÒÐÎËËÅÐÀ ÍÃÌÄ * |
;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД * |
;********************************************* |
FDCInterrupt: |
; Óñòàíîâèòü ôëàã ïðåðûâàíè |
; Установить флаг прерывани |
mov [FDD_IntFlag], 1 |
ret |
|
|
;****************************************** |
;* ÓÑÒÀÍÎÂÈÒÜ ÍÎÂÛÉ ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈÉ * |
;* ÍÃÌÄ * |
;* УСТАНОВИТЬ НОВЫЙ ОБРАБОТЧИК ПРЕРЫВАНИЙ * |
;* НГМД * |
;****************************************** |
SetUserInterrupts: |
mov [fdc_irq_func], FDCInterrupt |
199,28 → 199,28 |
ret |
|
;******************************************* |
;* ÎÆÈÄÀÍÈÅ ÏÐÅÐÛÂÀÍÈß ÎÒ ÊÎÍÒÐÎËËÅÐÀ ÍÃÌÄ * |
;* ОЖИДАНИЕ ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД * |
;******************************************* |
WaitFDCInterrupt: |
pusha |
; Ñáðîñèòü áàéò ñîñòîÿíèÿ îïåðàöèè |
; Сбросить байт состояния операции |
mov [FDC_Status], FDC_Normal |
; Ñáðîñèòü ôëàã ïðåðûâàíè |
; Сбросить флаг прерывани |
mov [FDD_IntFlag], 0 |
; Îáíóëèòü ñ÷åò÷èê òèêîâ |
; Обнулить счетчик тиков |
mov eax, [timer_ticks] |
mov [TickCounter], eax |
; Îæèäàòü óñòàíîâêè ôëàãà ïðåðûâàíèÿ ÍÃÌÄ |
; Ожидать установки флага прерывания НГМД |
@@TestRS_2: |
cmp [FDD_IntFlag], 0 |
jnz @@End_7 ;ïðåðûâàíèå ïðîèçîøëî |
jnz @@End_7 ;прерывание произошло |
call change_task |
mov eax, [timer_ticks] |
sub eax, [TickCounter] |
cmp eax, 50 ;25 ;5 ;îæèäàòü 5 òèêîâ |
cmp eax, 50 ;25 ;5 ;ожидать 5 тиков |
jb @@TestRS_2 |
; jl @@TestRS_2 |
; Îøèáêà òàéì-àóòà |
; Ошибка тайм-аута |
mov [FDC_Status], FDC_TimeOut |
; mov [flp_status],0 |
@@End_7: |
228,7 → 228,7 |
ret |
|
;********************************* |
;* ÂÊËÞ×ÈÒÜ ÌÎÒÎÐ ÄÈÑÊÎÂÎÄÀ "A:" * |
;* ВКЛЮЧИТЬ МОТОР ДИСКОВОДА "A:" * |
;********************************* |
FDDMotorON: |
pusha |
237,11 → 237,11 |
mov al, [flp_number] |
cmp [fdd_motor_status], al |
je fdd_motor_on |
; Ïðîèçâåñòè ñáðîñ êîíòðîëëåðà ÍÃÌÄ |
mov DX, 3F2h;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
; Произвести сброс контроллера НГМД |
mov DX, 3F2h;порт управления двигателями |
mov AL, 0 |
out DX, AL |
; Âûáðàòü è âêëþ÷èòü ìîòîð äèñêîâîäà |
; Выбрать и включить мотор дисковода |
cmp [flp_number], 1 |
jne FDDMotorON_B |
; call FDDMotorOFF_B |
252,10 → 252,10 |
mov AL, 2Dh ; Floppy B |
FDDMotorON_1: |
out DX, AL |
; Îáíóëèòü ñ÷åò÷èê òèêîâ |
; Обнулить счетчик тиков |
mov eax, [timer_ticks] |
mov [TickCounter], eax |
; Îæèäàòü 0,5 ñ |
; Ожидать 0,5 с |
@@dT: |
call change_task |
mov eax, [timer_ticks] |
274,7 → 274,7 |
ret |
|
;***************************************** |
;* ÑÎÕÐÀÍÅÍÈÅ ÓÊÀÇÀÒÅËß ÂÐÅÌÅÍÈ * |
;* СОХРАНЕНИЕ УКАЗАТЕЛЯ ВРЕМЕНИ * |
;***************************************** |
save_timer_fdd_motor: |
mov eax, [timer_ticks] |
282,8 → 282,26 |
ret |
|
;***************************************** |
;* ÏÐÎÂÅÐÊÀ ÇÀÄÅÐÆÊÈ ÂÛÊËÞ×ÅÍÈß ÌÎÒÎÐÀ * |
;* ПРОВЕРКА ЗАДЕРЖКИ ВЫКЛЮЧЕНИЯ МОТОРА * |
;***************************************** |
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 |
|
align 4 |
check_fdd_motor_status: |
cmp [fdd_motor_status], 0 |
300,7 → 318,7 |
ret |
|
;********************************** |
;* ÂÛÊËÞ×ÈÒÜ ÌÎÒÎÐ ÄÈÑÊÎÂÎÄÀ * |
;* ВЫКЛЮЧИТЬ МОТОР ДИСКОВОДА * |
;********************************** |
FDDMotorOFF: |
push AX |
314,35 → 332,35 |
FDDMotorOFF_2: |
pop DX |
pop AX |
; ñáðîñ ôëàãîâ êåøèðîâàíèÿ â ñâÿçè ñ óñòàðåâàíèåì èíôîðìàöèè |
; сброс флагов кеширования в связи с устареванием информации |
mov [root_read], 0 |
mov [flp_fat], 0 |
ret |
|
FDDMotorOFF_A: |
mov DX, 3F2h;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov DX, 3F2h;порт управления двигателями |
mov AL, 0Ch ; Floppy A |
out DX, AL |
ret |
|
FDDMotorOFF_B: |
mov DX, 3F2h;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov DX, 3F2h;порт управления двигателями |
mov AL, 5h ; Floppy B |
out DX, AL |
ret |
|
;******************************* |
;* ÐÅÊÀËÈÁÐÎÂÊÀ ÄÈÑÊÎÂÎÄÀ "A:" * |
;* РЕКАЛИБРОВКА ДИСКОВОДА "A:" * |
;******************************* |
RecalibrateFDD: |
pusha |
call save_timer_fdd_motor |
; Ïîäàòü êîìàíäó "Ðåêàëèáðîâêà" |
; Подать команду "Рекалибровка" |
mov AL, 07h |
call FDCDataOutput |
mov AL, 00h |
call FDCDataOutput |
; Îæèäàòü çàâåðøåíèÿ îïåðàöèè |
; Ожидать завершения операции |
call WaitFDCInterrupt |
; cmp [FDC_Status],0 |
; je no_fdc_status_error |
353,30 → 371,30 |
ret |
|
;***************************************************** |
;* ÏÎÈÑÊ ÄÎÐÎÆÊÈ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;* ПОИСК ДОРОЖКИ * |
;* Параметры передаются через глобальные переменные: * |
;* FDD_Track - номер дорожки (0-79); * |
;* FDD_Head - номер головки (0-1). * |
;* Результат операции заносится в FDC_Status. * |
;***************************************************** |
SeekTrack: |
pusha |
call save_timer_fdd_motor |
; Ïîäàòü êîìàíäó "Ïîèñê" |
; Подать команду "Поиск" |
mov AL, 0Fh |
call FDCDataOutput |
; Ïåðåäàòü áàéò íîìåðà ãîëîâêè/íàêîïèòåë |
; Передать байт номера головки/накопител |
mov AL, [FDD_Head] |
shl AL, 2 |
call FDCDataOutput |
; Ïåðåäàòü áàéò íîìåðà äîðîæêè |
; Передать байт номера дорожки |
mov AL, [FDD_Track] |
call FDCDataOutput |
; Îæèäàòü çàâåðøåíèÿ îïåðàöèè |
; Ожидать завершения операции |
call WaitFDCInterrupt |
cmp [FDC_Status], FDC_Normal |
jne @@Exit |
; Ñîõðàíèòü ðåçóëüòàò ïîèñêà |
; Сохранить результат поиска |
mov AL, 08h |
call FDCDataOutput |
call FDCDataInput |
383,24 → 401,24 |
mov [FDC_ST0], AL |
call FDCDataInput |
mov [FDC_C], AL |
; Ïðîâåðèòü ðåçóëüòàò ïîèñêà |
; Ïîèñê çàâåðøåí? |
; Проверить результат поиска |
; Поиск завершен? |
test [FDC_ST0], 100000b |
je @@Err |
; Çàäàííûé òðåê íàéäåí? |
; Заданный трек найден? |
mov AL, [FDC_C] |
cmp AL, [FDD_Track] |
jne @@Err |
; Íîìåð ãîëîâêè ñîâïàäàåò ñ çàäàííûì? |
; Номер головки совпадает с заданным? |
mov AL, [FDC_ST0] |
and AL, 100b |
shr AL, 2 |
cmp AL, [FDD_Head] |
jne @@Err |
; Îïåðàöèÿ çàâåðøåíà óñïåøíî |
; Операция завершена успешно |
mov [FDC_Status], FDC_Normal |
jmp @@Exit |
@@Err: ; Òðåê íå íàéäåí |
@@Err: ; Трек не найден |
mov [FDC_Status], FDC_TrackNotFound |
; mov [flp_status],0 |
@@Exit: |
409,27 → 427,27 |
ret |
|
;******************************************************* |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè ÷òåíèÿ * |
;* ñîäåðæèìîå ñåêòîðà áóäåò çàíåñåíî â FDD_DataBuffer. * |
;* ЧТЕНИЕ СЕКТОРА ДАННЫХ * |
;* Параметры передаются через глобальные переменные: * |
;* FDD_Track - номер дорожки (0-79); * |
;* FDD_Head - номер головки (0-1); * |
;* FDD_Sector - номер сектора (1-18). * |
;* Результат операции заносится в FDC_Status. * |
;* В случае успешного выполнения операции чтения * |
;* содержимое сектора будет занесено в FDD_DataBuffer. * |
;******************************************************* |
ReadSector: |
pushad |
call save_timer_fdd_motor |
; Óñòàíîâèòü ñêîðîñòü ïåðåäà÷è 500 Êáàéò/ñ |
; Установить скорость передачи 500 Кбайт/с |
mov AX, 0 |
mov DX, 03F7h |
out DX, AL |
; Èíèöèàëèçèðîâàòü êàíàë ïðÿìîãî äîñòóïà ê ïàìÿòè |
; Инициализировать канал прямого доступа к памяти |
mov [dmamode], 0x46 |
call Init_FDC_DMA |
; Ïîäàòü êîìàíäó "×òåíèå äàííûõ" |
mov AL, 0E6h ;÷òåíèå â ìóëüòèòðåêîâîì ðåæèìå |
; Подать команду "Чтение данных" |
mov AL, 0E6h ;чтение в мультитрековом режиме |
call FDCDataOutput |
mov AL, [FDD_Head] |
shl AL, 2 |
440,19 → 458,19 |
call FDCDataOutput |
mov AL, [FDD_Sector] |
call FDCDataOutput |
mov AL, 2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò) |
mov AL, 2 ;код размера сектора (512 байт) |
call FDCDataOutput |
mov AL, 18 ;+1; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå |
mov AL, 18 ;+1; 3Fh ;число секторов на дорожке |
call FDCDataOutput |
mov AL, 1Bh ;çíà÷åíèå GPL |
mov AL, 1Bh ;значение GPL |
call FDCDataOutput |
mov AL, 0FFh;çíà÷åíèå DTL |
mov AL, 0FFh;значение DTL |
call FDCDataOutput |
; Îæèäàåì ïðåðûâàíèå ïî çàâåðøåíèè îïåðàöèè |
; Ожидаем прерывание по завершении операции |
call WaitFDCInterrupt |
cmp [FDC_Status], FDC_Normal |
jne @@Exit_1 |
; Ñ÷èòûâàåì ñòàòóñ çàâåðøåíèÿ îïåðàöèè |
; Считываем статус завершения операции |
call GetStatusInfo |
test [FDC_ST0], 11011000b |
jnz @@Err_1 |
467,21 → 485,21 |
ret |
|
;******************************************************* |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ (Ñ ÏÎÂÒÎÐÅÍÈÅÌ ÎÏÅÐÀÖÈÈ ÏÐÈ ÑÁÎÅ) * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè ÷òåíèÿ * |
;* ñîäåðæèìîå ñåêòîðà áóäåò çàíåñåíî â FDD_DataBuffer. * |
;* ЧТЕНИЕ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ) * |
;* Параметры передаются через глобальные переменные: * |
;* FDD_Track - номер дорожки (0-79); * |
;* FDD_Head - номер головки (0-1); * |
;* FDD_Sector - номер сектора (1-18). * |
;* Результат операции заносится в FDC_Status. * |
;* В случае успешного выполнения операции чтения * |
;* содержимое сектора будет занесено в FDD_DataBuffer. * |
;******************************************************* |
ReadSectWithRetr: |
pusha |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
; Обнулить счетчик повторения операции рекалибровки |
mov [RecalRepCounter], 0 |
@@TryAgain: |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè |
; Обнулить счетчик повторения операции чтени |
mov [ReadRepCounter], 0 |
@@ReadSector_1: |
call ReadSector |
489,11 → 507,11 |
je @@Exit_2 |
cmp [FDC_Status], 1 |
je @@Err_3 |
; Òðîåêðàòíîå ïîâòîðåíèå ÷òåíè |
; Троекратное повторение чтени |
inc [ReadRepCounter] |
cmp [ReadRepCounter], 3 |
jb @@ReadSector_1 |
; Òðîåêðàòíîå ïîâòîðåíèå ðåêàëèáðîâêè |
; Троекратное повторение рекалибровки |
call RecalibrateFDD |
call SeekTrack |
inc [RecalRepCounter] |
509,27 → 527,27 |
ret |
|
;******************************************************* |
;* ÇÀÏÈÑÜ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè çàïèñè * |
;* ñîäåðæèìîå FDD_DataBuffer áóäåò çàíåñåíî â ñåêòîð. * |
;* ЗАПИСЬ СЕКТОРА ДАННЫХ * |
;* Параметры передаются через глобальные переменные: * |
;* FDD_Track - номер дорожки (0-79); * |
;* FDD_Head - номер головки (0-1); * |
;* FDD_Sector - номер сектора (1-18). * |
;* Результат операции заносится в FDC_Status. * |
;* В случае успешного выполнения операции записи * |
;* содержимое FDD_DataBuffer будет занесено в сектор. * |
;******************************************************* |
WriteSector: |
pushad |
call save_timer_fdd_motor |
; Óñòàíîâèòü ñêîðîñòü ïåðåäà÷è 500 Êáàéò/ñ |
; Установить скорость передачи 500 Кбайт/с |
mov AX, 0 |
mov DX, 03F7h |
out DX, AL |
; Èíèöèàëèçèðîâàòü êàíàë ïðÿìîãî äîñòóïà ê ïàìÿòè |
; Инициализировать канал прямого доступа к памяти |
mov [dmamode], 0x4A |
call Init_FDC_DMA |
; Ïîäàòü êîìàíäó "Çàïèñü äàííûõ" |
mov AL, 0xC5 ;0x45 ;çàïèñü â ìóëüòèòðåêîâîì ðåæèìå |
; Подать команду "Запись данных" |
mov AL, 0xC5 ;0x45 ;запись в мультитрековом режиме |
call FDCDataOutput |
mov AL, [FDD_Head] |
shl AL, 2 |
540,19 → 558,19 |
call FDCDataOutput |
mov AL, [FDD_Sector] |
call FDCDataOutput |
mov AL, 2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò) |
mov AL, 2 ;код размера сектора (512 байт) |
call FDCDataOutput |
mov AL, 18; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå |
mov AL, 18; 3Fh ;число секторов на дорожке |
call FDCDataOutput |
mov AL, 1Bh ;çíà÷åíèå GPL |
mov AL, 1Bh ;значение GPL |
call FDCDataOutput |
mov AL, 0FFh;çíà÷åíèå DTL |
mov AL, 0FFh;значение DTL |
call FDCDataOutput |
; Îæèäàåì ïðåðûâàíèå ïî çàâåðøåíèè îïåðàöèè |
; Ожидаем прерывание по завершении операции |
call WaitFDCInterrupt |
cmp [FDC_Status], FDC_Normal |
jne @@Exit_3 |
; Ñ÷èòûâàåì ñòàòóñ çàâåðøåíèÿ îïåðàöèè |
; Считываем статус завершения операции |
call GetStatusInfo |
test [FDC_ST0], 11000000b ;11011000b |
jnz @@Err_2 |
566,21 → 584,21 |
ret |
|
;******************************************************* |
;* ÇÀÏÈÑÜ ÑÅÊÒÎÐÀ (Ñ ÏÎÂÒÎÐÅÍÈÅÌ ÎÏÅÐÀÖÈÈ ÏÐÈ ÑÁÎÅ) * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè çàïèñè * |
;* ñîäåðæèìîå FDD_DataBuffer áóäåò çàíåñåíî â ñåêòîð. * |
;* ЗАПИСЬ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ) * |
;* Параметры передаются через глобальные переменные: * |
;* FDD_Track - номер дорожки (0-79); * |
;* FDD_Head - номер головки (0-1); * |
;* FDD_Sector - номер сектора (1-18). * |
;* Результат операции заносится в FDC_Status. * |
;* В случае успешного выполнения операции записи * |
;* содержимое FDD_DataBuffer будет занесено в сектор. * |
;******************************************************* |
WriteSectWithRetr: |
pusha |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
; Обнулить счетчик повторения операции рекалибровки |
mov [RecalRepCounter], 0 |
@@TryAgain_1: |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè |
; Обнулить счетчик повторения операции чтени |
mov [ReadRepCounter], 0 |
@@WriteSector_1: |
call WriteSector |
588,11 → 606,11 |
je @@Exit_4 |
cmp [FDC_Status], 1 |
je @@Err_4 |
; Òðîåêðàòíîå ïîâòîðåíèå ÷òåíè |
; Троекратное повторение чтени |
inc [ReadRepCounter] |
cmp [ReadRepCounter], 3 |
jb @@WriteSector_1 |
; Òðîåêðàòíîå ïîâòîðåíèå ðåêàëèáðîâêè |
; Троекратное повторение рекалибровки |
call RecalibrateFDD |
call SeekTrack |
inc [RecalRepCounter] |
607,7 → 625,7 |
ret |
|
;********************************************* |
;* ÏÎËÓ×ÈÒÜ ÈÍÔÎÐÌÀÖÈÞ Î ÐÅÇÓËÜÒÀÒÅ ÎÏÅÐÀÖÈÈ * |
;* ПОЛУЧИТЬ ИНФОРМАЦИЮ О РЕЗУЛЬТАТЕ ОПЕРАЦИИ * |
;********************************************* |
GetStatusInfo: |
push AX |