MS-DOS для программиста© Александр Фролов, Григорий ФроловТом 19, М.: Диалог-МИФИ, 1995, 253 стр. 1.6. Примеры использования функций BIOSТолько что мы привели функции BIOS, предназначенные для работы с диском на физическом уровне. Когда и как ими пользоваться? Доступ к диску на физическом уровне может потребоваться для чтения отдельных секторов диска, расположенных в фиксированных (или известных) местах диска - таблицы разделов диска, каталогов и т. п. С помощью функций BIOS можно выполнить низкоуровневое форматирование диска, как стандартное, так и использующее нестандартный формат дорожки. Последняя операция часто применяется для создания установочных (инсталляционных) дискет, защищенных от несанкционированного копирования. В любом случае при записи информации в секторы следует внимательно анализировать работу программы - ошибки могут привести к разрушению логической структуры диска. В результате этого могут появиться потерянные каталоги и файлы. Все опасные эксперименты лучше проводить на дискетах, и только когда вы уверены в безошибочной работе программы, можно "допустить" ее к жесткому диску. Если в компьютере установлен НГМД с высокой плотностью записи, перед началом работы с дискетами двойной плотности записи (360 и 720 Кбайт) вам надо правильно установить скорость передачи данных через контроллер НГМД. Лучше всего это сделать функцией 17h прерывания INT 13h , указав правильный тип дискеты. Не следует забывать о задержке, необходимой для разгона двигателя НГМД до рабочей скорости. Некоторые функции BIOS могут вернуть признак ошибки, если к моменту их вызова двигатель не набрал нужной скорости. Если вы получили признак ошибки, вначале следует три раза повторить вызов функции, сбрасывая каждый раз перед этим контроллер НГМД функцией 0 прерывания INT 13h . Если и после этого ошибка не исчезла, следует провести ее углубленный анализ. Приведем примеры использования функций прерывания INT 13h для работы с НГМД. Программа FD13Первый пример - программа FD13 (листинг 1.3), составленная на языке ассемблера. Она читает самый первый сектор диска, расположенный на нулевой дорожке, нулевой стороне (нулевая головка). Этот сектор имеет номер 1. Листинг 1.3. Файл fd13\fd13.asm .MODEL tiny .DATA ; Буфер, в который будет прочитан сектор диска buf db 512 dup (?) .CODE .STARTUP mov ch, 00h ; номер дорожки mov cl, 01h ; номер сектора mov dh, 00h ; номер головки (стороны диска) mov dl, 00h ; номер НГМД, соответсвует ; устройству А: ; Готовим адрес буфера в ES:BX mov ax, cs mov es, ax mov bx, OFFSET buf ; Готовим код функции mov ah, 02h ; код функции - чтение сектора mov al, 01h ; читаем 1 сектор ; Вызываем прерывание int 13h .EXIT 0 END Для подготовки загрузочного модуля этой программы мы использовали пакетный файл, приведенный в листинге 1.4. Листинг 1.4. Файл fd13\mk.bat tasm fd13 tlink fd13 /t Программа FDCHANGEСледующая программа, которая называется FDCHANGE - пример использования аппаратуры проверки замены дискеты. Текст программы приведен в листинге 1.5. Сначала программа устанавливает тип дискеты. Это нужно для правильного выбора скорости передачи данных контроллером НГМД. При установке типа дискеты сбрасывается флаг замены дискеты. Далее после чтения состояния НГМД программа делает паузу, во время которой вы можете заменить дискету или просто открыть и закрыть дверцу дисковода. Выполнив (или не выполнив) действия по замене дискеты, нажмите на любую клавишу. Программа выведет на экран новое состояние флага замены дискеты. Попробуйте запустить эту программу без дискеты, обратите внимание на состояние порта 0x3F7. Главное, что вы можете взять из приведенной ниже программы - это техника работы с флагом замены дискеты. Используя аппаратуру проверки замены дискеты, ваша программа сможет более полно контролировать действия пользователя при установке и замене дискет. Листинг 1.5. Файл fdchange\ fdchange.cpp #include <stdio.h> #include <conio.h> #include <dos.h> #include <stdlib.h> union REGS inregs, outregs; void main(void) { // Устанавливаем тип диска и сбрасываем // флаг замены дискеты inregs.h.ah = 0x17; inregs.h.al = 3; inregs.h.dl = 0; int86(0x13, &inregs, &outregs); // Определяем тип диска и наличие аппаратной // поддержки проверки замены дискеты inregs.h.ah = 0x15; inregs.h.dl = 0; int86(0x13, &inregs, &outregs); printf("\nТип диска А: %d", outregs.h.ah); // Определяем состояние флага замены дискеты inregs.h.ah = 0x16; inregs.h.dl = 0; int86(0x13, &inregs, &outregs); printf("\nСостояние флага замены дискеты:" " %d",outregs.h.ah); // Выводим состояние порта 0x3F7. // Бит 7 этого порта отображает состояние // флага замены дискеты printf("\nПорт 0x3F7: %02.2x",inp(0x3f7)); // Сбрасываем контроллер НГМД inregs.h.ah = 0; inregs.h.dl = 0; int86(0x13, &inregs, &outregs); // Делаем паузу, во время которой можно // заменить дискету. // Попробуйте во время ожидания нажатия на клавишу // открыть и затем закрыть дверцу дисковода - это // приведет к установке флага замена дискеты printf("\nЗамените дискету и нажмите на любую клавишу"); getch(); // Определяем состояние флага замены дискеты inregs.h.ah = 0x16; inregs.h.dl = 0; int86(0x13, &inregs, &outregs); printf("\nСостояние флага замены дискеты: %d", outregs.h.ah); // Выводим состояние порта 0x3F7. printf("\nПорт 0x3F7: %02.2x", inp(0x3f7)); } Еще один пример использования прерывания INT 13h (нестандартное форматирование дорожки дискеты) мы приведем в следующем разделе. |