Скачиваний:
28
Добавлен:
15.09.2014
Размер:
14.24 Кб
Скачать

FDD Примеры программ Полный листинг программы просмотра секторов гибкого диска на дисководе "A:" при помощи функций BIOS. ; Автор текста программы Кулаков Владимир Геннадьевич. IDEAL P386 LOCALS MODEL MEDIUM ; Подключить файл мнемонических обозначений ; кодов управляющих клавиш include "lst_1_03.inc" ; Подключить файл мнемонических обозначений цветов include "lst_1_05.inc" DATASEG ; Текстовые сообщения Txt0 DB LIGHTCYAN,0,7,"ПРИМЕР ИСПОЛЬЗОВАНИЯ ФУНКЦИЙ " DB "BIOS ДЛЯ ЧТЕНИЯ ИНФОРМАЦИИ С ДИСКЕТЫ",0 DB LIGHTGREEN,12,24 DB "Установите дискету в дисковод A:",0 DB YELLOW,24,29,"Нажмите любую клавишу",0 Txt1 DB LIGHTCYAN,0,10,"Просмотр секторов " DB "гибкого диска, находящегося в дисководе A:",0 DB LIGHTGREEN,2,14,"Диск имеет поверхность(и)," DB " секторов на дорожке",0 DB LIGHTCYAN,17,8,"Управляющие клавиши:",0 DB YELLOW,24,27,"Нажмите управляющую клавишу",0 Txt2 DB 19,8,"Стрелка вниз - следующий сектор;",0 DB 20,8,"Стрелка вверх - предыдущий сектор;",0 DB 21,8,"Esc - выход.",0 Txt3 DB LIGHTGREEN,5,8 DB "Дорожка N Головка N Сектор N ",0 TErr DB LIGHTRED,12,20 DB "Ошибка считывания сектора с дисковода A:",0 DB YELLOW,24,29,"Нажмите любую клавишу",0 ; Адрес считываемого сектора в режиме CHS Cylinder DB ? ;номер цилиндра Head DB ? ;номер головки Sector DB ? ;номер сектора ; Предельные значения координат MaxCylinder DB 79 ;? ;максимальный номер цилиндра MaxHead DB 1 ;? ;максимальный номер головки MaxSector DB 18 ;? ;максимальный номер сектора ; Область памяти для хранения прочитанного сектора SectorDataBuffer DB 512 DUP (?) ENDS SEGMENT sseg para stack 'STACK' DB 400h DUP(?) ENDS CODESEG ;***************************** ;* Основной модуль программы * ;***************************** PROC ShowFDDSector mov AX,DGROUP mov DS,AX ; Установить текстовый режим и очистить экран mov AX,3 int 10h ; Скрыть курсор - убрать за нижнюю границу экрана mov [ScreenString],25 mov [ScreenColumn],0 call SetCursorPosition ; Вывести на экран сообщение "Вставьте дискету" mov SI,offset Txt0 call ShowColorString call ShowColorString call ShowColorString ; Ожидать нажатия клавиши call GetChar ; Прочитать BOOT-сектор дискеты mov [Cylinder],0 mov [Head],0 mov [Sector],1 call ReadFDDSector ; Определить и запомнить параметры дискеты mov AL,[SectorDataBuffer+18h] mov [MaxSector],AL mov AL,[SectorDataBuffer+1Ah] dec AL mov [MaxHead],AL ; Очистить экран call ClearScreen ; Вывести текстовые сообщения mov SI,offset Txt1 call ShowColorString call ShowColorString call ShowColorString call ShowColorString ; Установить зеленый цвет и черный фон mov [TextColorAndBackground],LIGHTGREEN ; Отобразить параметры установленной дискеты mov [ScreenString],2 mov [ScreenColumn],25 mov AL,[MaxHead] inc AL call ShowDecByte mov [ScreenColumn],43 mov AL,[MaxSector] call ShowDecByte ; Вывести описание управляющих клавиш mov SI,offset Txt2 call ShowString call ShowString call ShowString ; ЦИКЛ ПО СЕКТОРАМ mov AX,0B800h mov ES,AX @@ReadSector: mov SI,offset Txt3 call ShowColorString mov [ScreenString],5 mov [ScreenColumn],18 mov AL,[Cylinder] call ShowDecByte mov [ScreenColumn],31 mov AL,[Head] call ShowDecByte mov [ScreenColumn],44 mov AL,[Sector] call ShowDecByte ; Прочитать сектор call ReadFDDSector ; Отобразить на экран содержимое считанного сектора ; в ASCII-кодах @@ShowSector: ; Установить начало окна отображения сектора mov DI,7*160+8*2 mov SI,offset SectorDataBuffer ; Задать для символов светло-голубой ; цвет и синий фон mov AH,LIGHTCYAN+BLUE*16 mov DX,8 ;счетчик строк @@OutNextString: mov CX,64 ;счетчик символов в строке @@OutNextChar: lodsb stosw loop @@OutNextChar add DI,16*2 dec DX jnz @@OutNextString @@GetCommand: ; Ожидаем ввода следующей команды call GetChar cmp AL,0 je @@TestCommandByte call Beep jmp short @@GetCommand @@TestCommandByte: cmp AH,B_Esc ;команда "Выход"? ; Выполнить команду "Выход" je @@End @@TestDn: cmp AH,B_DN jne @@TestUp ; Выполнить команду "Стрелка вниз" mov AL,[Sector] cmp AL,[MaxSector] jae @@IncHead ; Увеличить на 1 номер сектора inc [Sector] jmp @@ReadSector @@IncHead: mov AL,[Head] cmp AL,[MaxHead] jae @@IncCylinder ; Увеличить на 1 номер головки, ; установить сектор 1 inc [Head] mov [Sector],1 jmp @@ReadSector @@IncCylinder: mov AL,[Cylinder] cmp AL,[MaxCylinder] jae @@CommandError ; Увеличить на 1 номер цилиндра, установить ; головку 0, сектор 1 inc [Cylinder] mov [Head],0 mov [Sector],1 jmp @@ReadSector @@TestUp: cmp AH,B_UP jne @@CommandError ; Выполнить команду "Стрелка вверх" cmp [Sector],1 jbe @@DecHead ; Уменьшить на 1 номер сектора dec [Sector] jmp @@ReadSector @@DecHead: mov AL,[Head] cmp AL,0 je @@DecCylinder ; Уменьшить на 1 номер головки, установить ; максимальный номер сектора dec [Head] mov AL,[MaxSector] mov [Sector],AL jmp @@ReadSector @@DecCylinder: mov AL,[Cylinder] cmp AL,0 je @@CommandError ; Уменьшить на 1 номер цилиндра, установить ; максимальные номера головки и сектора dec [Cylinder] mov AL,[MaxHead] mov [Head],AL mov AL,[MaxSector] mov [Sector],AL jmp @@ReadSector @@CommandError: call Beep jmp @@GetCommand @@End: ; Переустановить текстовый режим mov ax,3 int 10h ; Выход в DOS mov AH,4Ch int 21h ENDP ShowFDDSector ;********************************************** ;* ПРОЧИТАТЬ СЕКТОР ГИБКОГО ДИСКА * ;* Параметры передаются через глобальные * ;* переменные: * ;* Cylinder - номер цилиндра (от 0 до 79); * ;* Head - номер головки (0 или 1); * ;* Sector - номер сектора (от 1 до 18). * ;* Считанный сектор записывается в основной * ;* сегмент данных по адресу SectorDataBuffer. * ;********************************************** PROC ReadFDDSector NEAR pusha push ES mov AX,DS mov ES,AX mov CX,3 ;счетчик повторений @@Repeat: mov BX,offset SectorDataBuffer mov AH,2 ;подфункция "Прочесть сектор" mov AL,1 ;прочесть 1 сектор mov CH,[Cylinder] mov CL,[Sector] mov DH,[Head] mov DL,0 ;читать диск "A:" int 13h jnc @@End ; Ошибка считывания, инициализировать систему mov AH,0 ;подфункция "Инициализировать" mov DL,0 ;диск "A:" int 13h loop @@Repeat ; Фатальная ошибка jmp @@Err ; Нормальное завершение процедуры @@End: pop ES popa ret ; Аварийный выход - ошибка при чтении файла @@Err: ; Очистить экран call ClearScreen ; Выдать сообщение об ошибке mov SI,offset TErr call ShowColorString call ShowColorString call GetChar ; Выход в DOS mov AH,4Ch int 21h ENDP ReadFDDSector ENDS ; Подключить процедуры вывода данных на экран include "lst_1_02.inc" ; Подключить процедуры перевода чисел в десятичный код include "lst_2_05.inc" END Данная программа подключает несколько внешних файлов: Файл lst_1_02.inc. Файл, содержащий процедуры ввода/вывода общего назначения для работы в цветном текстовом режиме. Файл lst_1_03.inc. Файл мнемонических обозначений кодов управляющих клавиш. Файл lst_1_05.inc. Файл мнемонических обозначений цветов. Файл lst_2_05.inc. Файл, содержащий набор подпрограмм, предназначенных для перевода целых и вещественных чисел из двоичной системы счисления в десятичную и наоборот.

Программирование контроллера накопителя на гибких магнитных дисках. Программа записывает один сектор размером 512 байт на дисковод A:.

STACKSG SEGMENT PARA STACK 'STACK' DW 64 DUP(?) STACKSG ENDS DATASG SEGMENT PARA 'DATA' ;--- BUF_SEC DB 512 DUP(1EH) ; буфер данных сектора STATUS DB 7 DUP(?) ; буфер статуса НГМД DATASG ENDS ; CODESG SEGMENT PARA 'CODE' BEGIN PROC FAR ASSUME CS:CODESG,DS:DATASG,SS:STACKSG PUSH DS SUB AX,AX PUSH AX MOV AX,DATASG MOV DS,AX CALL SEC_W RET BEGIN ENDP ; SEC_W PROC ; начало процедуры записи одного сектора STI ; разрешение прерываний MOV DX,3F2H ; адрес DOR MOV AL,28 ; установка DOR OUT DX,AL MOV CX,3500 ; разгон двигателя НГМД (0,5 с) MOTOR: LOOP MOTOR MOV AH,15 ; выполнение команды "Установить" CALL NGMD_O MOV AH,0 ; номер НГМД CALL NGMD_O MOV AH,10 ; номер дорожки CALL NGMD_O CALL NGMD_INT ; ожидание прерывания от НГМД MOV CX,1750 ; пауза до полной остановки головок (25 мс) WAIT_G:LOOP WAIT_G MOV AL,4AH ; инициализация DMA OUT 12,AL ; код записи данных OUT 11,AL MOV AX,OFFSET BUF_SEC ; вычисление адреса буфера данных MOV BX,DS MOV CL,4 ROL BX,CL MOV DL,BL AND DL,0FH AND BL,0F0H ADD AX,BX JNC PER INC DL PER: OUT 4,AL MOV AL,AH OUT 4,AL MOV AL,DL OUT 81H,AL MOV AX,511 ; установка регистра счетчика DMA OUT 5,AL ; (размер данных, уменьшенный на 1) MOV AL,AH OUT 5,AL MOV AL,2 ; разрешение 2-го канала DMA OUT 10,AL ; выполнение команды "Запись сектора" MOV AH,45H ; код команды CALL NGMD_O MOV AH,0 ; номер НГМД и головки CALL NGMD_O MOV AH,10 ; номер цилиндра CALL NGMD_O MOV AH,0 ; номер головки CALL NGMD_O MOV AH,1 ; номер сектора CALL NGMD_O MOV AH,2 ; код длины сектора CALL NGMD_O MOV AH,9 ; номер последнего сектора на дорожке CALL NGMD_O MOV AH,2AH ; длина межсекторного промежутка CALL NGMD_O MOV AH,0FFH ; длина передаваемых данных CALL NGMD_O CALL NGMD_INT ; ожидание прерывания от НГМД MOV CX,7 ; проверка состояния НГМД LEA BX,STATUS NEXT: CALL NGMD_I MOV [BX],AL INC BX LOOP NEXT MOV DX,3F2H MOV AL,12 OUT DX,AL RET SEC_W ENDP ; процедура обработки прерывания НГМД NGMD_INT PROC MOV AX,40H MOV ES,AX MOV BX,3EH AGAIN: MOV DL,ES:[BX] TEST DL,80H JZ AGAIN AND DL,01111111B MOV ES:[BX],DL RET NGMD_INT ENDP ;процедура пересылки байта НГМД NGMD_O PROC MOV DX,3F4H ;адрес MSR O_NEXT: IN AL,DX TEST AL,128 ;проверка 7-го бита JZ O_NEXT INC DX MOV AL,AH OUT DX,AL RET NGMD_O ENDP ;процедура получения байта от НГМД NGMD_I PROC MOV DX,3F4H I_NEXT: IN AL,DX TEST AL,128 JZ I_NEXT INC DX IN AL,DX RET NGMD_I ENDP END CODESG ENDS

Соседние файлы в папке Учебник