Операционная система MS-DOS© Александр Фролов, Григорий ФроловТом 1, книга 3, М.: Диалог-МИФИ, 1992. 1.7. Функция _bios_disk()Стандартная библиотека трансляторов Microsoft QC .01, QC .5, C .0 содержит специальную функцию, облегчающую работу с диском на уровне BIOS - _bios_disk(). Эта функция требует использования файла bios.h и описана следующим образом: unsigned _bios_disk(unsigned funct, struct diskinfo_t *diskinfo); Параметр funct задает выполняемую функцию, параметр diskinfo - это указатель на структуру, описывающую необходимые параметры, такие как номер дорожки, номер головки и т.д.: struct diskinfo_t { unsigned drive; // Номер дисковода unsigned head; // Номер головки unsigned track; // Номер дорожки unsigned sector; // Номер первого сектора unsigned nsectors; // Количество читаемых, // записываемых // или сравниваемых секторов void far *buffer; // Адрес буфера в памяти }; Перед использованием функции _bios_disk() программа должна заполнить поля структуры diskinfo и вызвать _bios_disk() с соответствующим параметром funct. Файл bios.h содержит константы для следующих значений параметра funct:
Приведем пример программы, читающей первый сектор нулевой дорожки (нулевая головка) диска А:. В случае ошибки программа пытается прочесть сектор три раза: #include <stdio.h> #include <conio.h> #include <bios.h> #include <dos.h> #include <stdlib.h> char _far diskbuf[512]; void main(void); void main(void) { unsigned status = 0, i; struct diskinfo_t di; di.drive = 0; di.head = 0; di.track = 0; di.sector = 1; di.nsectors = 1; di.buffer = diskbuf; for(i = 0; i < 3; i++) { status = _bios_disk(_DISK_READ, &di) >> 8; if( !status ) break; } } Последний пример, который мы приведем перед тем, как закончить с работой диска на физическом уровне, это форматирование дорожки. Сейчас мы будем использовать стандартное форматирование. Как отформатировать дорожку нестандартным образом, вы узнаете в разделе, посвященном защите информации от несанкционированного копирования. Там же будет приведен соответствующий пример. Приведенная ниже программа форматирует 20-ю дорожку дискеты, установленной в дисковод А:. #include <stdio.h> #include <conio.h> #include <dos.h> #include <stdlib.h> #include <bios.h> #include "sysp.h" // Номер форматируемой дорожки #define TRK 20 // Код размера сектора - 512 байт #define SEC_SIZE 2 union REGS inregs, outregs; char _far diskbuf[512]; void main(void); void main(void) { struct diskinfo_t di; unsigned status; unsigned char old_sec_size, old_fill_char, old_eot; int i, j; DPT _far *dpt_ptr; // Получаем адрес таблицы параметров дискеты dpt_ptr = get_dpt(); // Сохраняем старые значения из таблицы параметров old_sec_size = dpt_ptr->sec_size; old_fill_char = dpt_ptr->fill_char; old_eot = dpt_ptr->eot; // Устанавливаем в таблице параметров дискеты // код размера сектора, символ заполнения при // форматировании, количество секторов на дорожке dpt_ptr->sec_size = SEC_SIZE; dpt_ptr->fill_char = 0xf8; dpt_ptr->eot = 15; // Устанавливаем тип диска inregs.h.ah = 0x17; inregs.h.al = 3; inregs.h.dl = 0; int86(0x13, &inregs, &outregs); // Устанавливаем среду для форматирования inregs.h.ah = 0x18; inregs.h.ch = TRK; inregs.h.cl = dpt_ptr->eot; inregs.h.dl = 0; int86(0x13, &inregs, &outregs); // Подготавливаем параметры для функции форматирования di.drive = 0; di.head = 0; di.track = TRK; di.sector = 1; di.nsectors = 15; di.buffer = diskbuf; // Подготавливаем буфер формата для 15-ти секторов for(i=0, j=1; j<16; i += 4, j++) { diskbuf[i] = TRK; diskbuf[i+1] = 0; diskbuf[i+2] = j; diskbuf[i+3] = SEC_SIZE; } // Вызываем функцию форматирования дорожки status = _bios_disk(_DISK_FORMAT, &di) >> 8; printf("\nФорматирование завершилось с кодом: %d",status); // Восстанавливаем старые значения в // таблице параметров дискеты dpt_ptr->sec_size = old_sec_size; dpt_ptr->fill_char = old_fill_char; dpt_ptr->eot = old_eot; } |