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

         

define word unsigned int union



Пример 16

/*== ПРИМЕР 10.9 ==*/ /*=========== Получение информации о диске ==========*/ #include <dos.h> #include <ctype.h> #define byte unsigned char # define word unsigned int union REGS rr; struct SREGS sr; /* полученная информация о диске */ struct di { byte error; /* признак ошибки */ byte media; /* тип носителя */ word tot_clust; /* общее число кластеров */ word free_clust; /* число свободных кластеров */ word clust_size; /* секторов в кластере */ word sect_size; /* байт в секторе */ } info[3]; byte cdrive; /* текущий диск */ byte drive; /* анализируемый диск */ int n; main() { do { printf("\nУкажите идентификатор диска >"); drive=getche(); } while (!isalpha(drive)); drive=toupper(drive)-'A'; /*== 1-й способ ==*/ n=0; /* получить номер текущего диска */ rr.h.ah=0x19; intdos(&rr,&rr); cdrive=rr.h.al; /* задать номер текущего диска */ rr.h.ah=0x0e; rr.h.dl=drive; intdos(&rr,&rr); /* проверить результат */ rr.h.ah=0x19; intdos(&rr,&rr); if (rr.h.al!=drive) { printf("\nНеправильный идентификатор диска\n"); exit(); } /* получение информации о FAT текущего диска */ rr.h.ah=0x1b; intdosx(&rr,&rr,&sr); info[n].media=peekb(sr.ds,rr.x.bx); info[n].tot_clust=rr.x.dx; info[n].clust_size=rr.h.al; info[n].sect_size=rr.x.cx; info[n].free_clust=0xffff; /* восстановить номер текущего диска */ rr.h.ah=0x0e; rr.h.dl=cdrive; intdos(&rr,&rr); /*== 2-й способ ==*/ n++; /* получение информации о FAT заданного диска */ rr.h.ah=0x1c; rr.h.dl=drive+1; intdosx(&rr,&rr,&sr); info[n].media=peekb(sr.ds,rr.x.bx); info[n].tot_clust=rr.x.dx; info[n].clust_size=rr.h.al; info[n].sect_size=rr.x.cx; info[n].free_clust=0xffff; /*== 3-й способ ==*/ n=0; n++; /* получить информацию о дисковом пространстве */ rr.h.ah=0x36; rr.h.dl=drive+1; intdosx(&rr,&rr,&sr); info[n].media=0; info[n].tot_clust=rr.x.dx; info[n].clust_size=rr.x.ax; info[n].sect_size=rr.x.cx; info[n].free_clust=rr.x.bx; /* вывод результатов */ clrscr(); printf("Информация о диске %c",drive+'A'); printf(" | INT 1B | INT 1C | INT 36 |\n"); printf("Тип носителя | "); for(n=0;n<3;n++) if (info[n].media) printf("%02x | ", info[n].media); else printf("-- |"); printf("\nВсего кластеров |"); for(n=0;n<3;printf(" %-6d |",info[n++].tot_clust)); printf("\nСвободных кластеров |"); for(n=0;n<3;n++) if (info[n].free_clust!=0xffff) printf(" %-6d |",info[n].free_clust); else printf(" -- |"); printf("\nСекторов в кластере |"); for(n=0;n<3;printf(" %-6d |",info[n++].clust_size)); printf("\nБайт в секторе |"); for(n=0;n<3;printf(" %-6d |",info[n++].sect_size)); getch(); }

Пример 16

struct BCB { /* BCB DOS 4.0 и далее */ word next; /* смещение следующего */ word prev; /* смещение предыдущего */ byte drive; byte flag; dword sect; byte copies; word sect_off; void *dpb; word count; /* счетчик обращений */ byte reserved[1]; };
Поля drive и sect включают логический номер диска и номер сектора этого диска, содержимое которого скопировано в данный буфер (в ни разу не использованных буферах drive=0xff), поле dpb - ссылку на DPB этого устройства. Поле состояния буфера - flag - будет нами рассмотрено ниже. Поле copies содержит число копий данного сектора на диске (оно отлично от 1 только для секторов, входящих в состав FAT), а поле sect_off - смещение на диске второй копии относительно первой (в секторах).

Все BCB связаны в список, но организация списка различна для разных версий DOS. В DOS 3 начальный адрес этого списка находится в CVT со смещением 0x12 от адреса, возвращаемого функцией 0x52. Каждый элемент списка в поле next содержит адрес (сегмент и смещение) следующего элемента. Признаком конца списка является значение 0xFFFF в смещении адреса следующего элемента.

В DOS 5 все буфера расположены в одном сегменте памяти. Поля next и prev в BCB связывают их в двухсвязный список. Эти поля содержат только смещения, так как сегментный адрес у всех буферов один и тот же. Для этой версии поле CVT со смещением 0x12 включает адрес области памяти, в которой хранится адрес начала списка, для выхода на первый элемент списка необходима двойная адресация. Список - кольцевой, то есть поле next его последнего элемента указывает на первый элемент, а поле prev первого - на последний.
Теперь об интерпретации разрядов байта состояния буфера. Наши эксперименты подтверждают следующие назначения его битов:

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