Системное программное обеспечение персональных ЭВМ

которые возвращают сегментную часть адреса



Пример 9

unsigned int FP_SEG(void far *ptr); unsigned int FP_OFF(void far *ptr);
которые возвращают сегментную часть адреса и смещение соответственно.

Обратное преобразование производится макросом:



Пример 9

/*= ПРИМЕР 3.3 =*/ /*======== Маскирование аппаратных прерываний ============*/ #include <dos.h> #include <time.h> main() { unsigned char mask; /* Исходная маска прерываний */ int i; /* Индикация исходного состояния */ for (i=0; i
Из текста программы видно, что порт 0x21 доступен и для записи, и для чтения. Таким образом, для корректного запрета выбранного прерывания необходимо прочитать текущее состояние маски прерываний, и занести в него запрещающую единицу при помощи операции "логическое ИЛИ".
Для AT разряд 2 используется для каскадирования второго контроллера прерываний. Доступ к маске второго контроллера - через порт 0xA1. Назначения разрядов второй маски следующие:


0 - прерывание часов реального времени;
1 - прерывание контроллера EGA;
5 - прерывание математического сопроцессора;
6 - прерывание контроллера жестких дисков;
2,3,4,7 - зарезервированы.


Пример 9

/*== ПРИМЕР 7.9 ==*/ /*========= Пользовательская обработка Ctrl+Break =======*/ /* ВНИМАНИЕ! Для проверки реакции на Ctrl+ Break программу следует запускать вне Турбо-среды */ #include <dos.h>
void interrupt (*old23)(); /* Адрес старого обработчика */ void interrupt new23(); /* Описание нового обработчика */ unsigned char col; /* Цвет вывода */ union REGS rr; struct SREGS sr; void *readvect(int in); void writevect(int in, void *h); void main() { union REGS rr; int i,k,o,m; col=0x21; /* Исходный цвет */ /* Включение Ctrl+Break */ rr.h.ah=0x33; rr.h.al=1; /* Подфункция установка Ctrl+Break */ rr.h.dl=1; /* ON */ intdos(&rr,&rr); /* Перехват вектора */ old23=readvect(0x23); writevect(0x23,new23); for (o=0,i=0,k=0; i
Восстановление вектора 0x23, произведенное нами в конце программы - действие необязательное, так как при завершении программы система сама восстанавливает тот вектор этого прерывания, который был установлен до ее запуска.



Пример 9

/*== ПРИМЕР 9.7 ==*/ /*===== Управление выводом средствами драйвера ANSI ======*/ #include <dos.h>
#define byte unsigned char #define Esc 27 #define Up 'A' #define Down 'B' #define Left 'D' #define Right 'C' byte xc, yc, y0; /* координаты курсора */ byte dx,dy; /* приращения координат */ byte mode; /* видеорежим */ byte attr[2]; /* цвета текста [0] и фона [1] */ int i,j; main() { y0=1; message("Очистка экрана"); getch(); attr[0]=37; attr[1]=40; set_colors(); clear_scr(); attr[0]=30; attr[1]=42; set_colors(); message("Установка цвета"); message("Запоминание позиции курсора"); message("Позиционирование курсора"); getch(); xc=40; yc=12; dx=dy=1; set_cur_pos(xc,yc); save_cur(); for(i=0; i



Пример 9

/*== ПРИМЕР 10.6 ==*/ /*======== Поиск и чтение файла средствами BIOS ========*/ #include <dos.h> #include <string.h> #include <stdlib.h> #include <ctype.h> /*== типы и структуры данных ==*/ #define byte unsigned char #define word unsigned int #define dword unsigned long #define daddr struct DADDR struct DADDR { /* физический дисковый адрес */ byte h; /* головка */ word s, /* сектор */ t, /* дорожка */ ts; /* сектор, дорожка упакованные */ }; struct PART { /* структура элемента раздела */ byte Boot, Begin_Hd; word Begin_SecTrk; byte SysCode, End_Hd; word End_SecTrk; dword RelSec, Size; }; struct MBR { /* стpуктуpа главной загpузочной записи */ char LoadCode[0x1be]; struct PART rt[4]; word EndFlag; }; struct BootRec { /* структура корневой записи */ byte jmp[3], ident[8]; word SectSize; byte ClustSize; word ResSect; byte FatCnt; word RootSize ,TotSecs; byte Media; word FatSize, TrkSecs, HeadCnt; word HidnSecL, HidnSecH; dword LongTotSecs; byte Drive, reserved1, DOS4_flag; dword VolNum; char VolLabel[11], FatForm[8]; }; struct Dir_Item { /* структура элемента оглавления */ char fname[11]; byte attr; char reserved[10]; word time, date, cl; dword size; }; /*== описания функций ==*/ void Read_Mbr(void); void Read_Boot(void); void Get_First(void); void Read_Fat(void); void Read_13(void *mem); void Sect_to_Daddr(dword sect); dword Clust_to_Sect(word clust); word Next_Clust(word clust); char *Get_Name(char *s, char *d); int Find_Name(); void End_of_Job(int n); /*== переменные ==*/ struct PART part; /* текущий элемент раздела */ byte buff1[512]; /* буфер MBR и boot */ struct MBR *mbr; /* указатель на таблицу разделов */ struct BootRec *boot; /* указатель на корневую запись */ byte buff2[512]; /* буфер каталога и текста */ struct Dir_Item *dir; /* указатель на часть каталога */ char *text; /* указатель на текстовый буфер */ byte *fat; /* указатель на FAT */ char job[81]; /* строка-задание */ char *jobptr; /* текущий указатель в job */ char cname[12]; /* текущее имя для поиска */ byte Fdisk; /* физический номер диска */ daddr caddr; /* текуший дисковый адрес */ dword sect; /* текуший номер сектора */ word clust; /* текуший номер кластера */ byte fat16; /* признак формата FAT */ dword fsize; /* размер файла */ int dirnum; /* номер элемента в оглавлении */ dword FirstSect; /* абс.сектор начала */ byte rootdir=1; /* признак корневого каталога или подкаталога (1/0) */ word lastsect; /* последний сектор при чтении */ byte fatalloc=0; /* признак выделения памяти */ /*-------------------------------------------------*/ main() { int n; /* ввод имени файла */ printf("Укажите имя файла >"); scanf("%s",job); /* перевод в верхний регистр */ strupr(job); /* проверка правильности идентификатора диска */ if ((!isalpha(job[0]))(job[1]!=':')(job[2]!='\\')) { printf("%c%c%c -",job[0],job[1],job[2]); End_of_Job(0); } jobptr=job+3; if (job[0]>'A') { /* для жесткого диска - физический номер и чтение MBR */ Fdisk=0x80; Read_Mbr(); } else /* для гибкого диска - физический номер */ Fdisk=job[0]-'A'; Read_Boot(); /* чтение boot-сектора */ Read_Fat(); /* чтение FAT */ dir=(struct Dir_Item *)buff2; do { /* движение по каталогам */ if (!rootdir) clust=dir[dirnum].cl; /* начальный кластер */ /* выделение следующего элемента из строки-задания */ jobptr=Get_Name(jobptr,cname); do { /* пока не дойдем до последнего кластера */ if (rootdir) { /* корневой каталог */ /* нач.сектор корневого огл.



Пример 9

struct CDS { char path[67]; /* см.выше */ word flags; /* см.выше */ byte drive; /* номер DPB, для этого диска */ byte reserved1; word par_clust; /* номер 1-го кластера родительского каталога */ word par_entry; /* номер элемента в родительском каталоге */ word dir_clust; /* см.выше */ byte reserved2[4]; };
Массив Текущих Каталогов представляет собой именно массив, а не список - его элементы располагаются в смежных областях памяти один за другим.

В программе следующего примера, выводящей на экран содержимое Массива Текущих Каталогов, для независимости от версии DOS в описание структуры CDS включено объединение VAR, описывающее различие между версиями.

Содержание раздела