однобайтный порт) эквивалентен двум операторам:
Пример 13
outport(0x20,0x11);
(а 0x20 - однобайтный порт) эквивалентен двум операторам: outportb(0x20,0x11); outportb(0x21,0);
Пример 13
/*== ПРИМЕР 10.7 == файл 10_7.H ==*/ /*================= Работа с библиотекой ================ */ /* элемент оглавления библиотеки */ struct lib_dir { char memb_name[8]; /* имя раздела */ unsigned long memb_addr; /* адрес раздела (смещение в байтах от начала файла) */ unsigned memb_size; /* размер (число строк) */ }; /* параметры файла */ struct file_info { unsigned char attr; /* атрибуты */ unsigned date; /* дата */ unsigned time; /* время */ unsigned long size; /* размер */ }; /*== ПРИМЕР 10.7 == файл 10_7.C ==*/ /*================= Работа с библиотекой ================ */ /* Главная программа и сервисные функции */ #include <stdio.h> #include <10_7.h> int memb_max; /* max число разделов */ char libname[80]; /* имя выбранной библиотеки */ char fmemb[9]; /* имя раздела */ int SIZE; /* размер эл-та оглавления */ /*==== main ====*/ main() { char opt; int flag;
init_l(); /* нач.установки */ for(flag=0; flag==0; ) { opt=getopt(); /* меню и выбор опции */ switch (opt) { /* выполнение опций */ case '0': getlib(); break; case '1': if (checkname()) creat_lib(); break; case '2': list_lib(); break; case '3': query_lib(); break; case '4': ren_lib(); break; case '5': del_lib(); break; case 'A': add_memb(); break; case 'B': repl_memb(); break; case 'C': find_out_memb(); break; case 'D': del_memb(); break; case 'E': ren_memb(); break; case 'F': look_membs(); break; case 27: flag++; break; default: printf("\7"); } } } /*==== начальные установки ====*/ init_l() { libname[0]=0; /* имя не выбрано */ SIZE=sizeof(struct lib_dir); /* размер эл-та оглавления */ } /*==== ввод имени библиотеки ====*/ getlib() { printf("\nИмя файла-библиотеки >"); scanf("%s",libname); strupr(libname); strcat(libname,".LBR"); } /*==== ввод имени раздела ====*/ getmemb() { char member[9]; int i; printf("\nИмя раздела >"); scanf("%s",member); for(i=0;i<8;fmemb[i++]=' '); for(i=0;(i<8)&&member[i];i++) fmemb[i]=member[i]; } /*==== проверка имени библиотеки ====*/ checkname() { if (libname[0]) return (1); prt("Не выбрано имя библиотеки"); return(0); } /*==== вывод на экран меню и ввод кода операции ====*/ int getopt() { char f; clrscr(); printf("===== Операции с библиотекой =====\n"); printf("0 - выбор имени библиотеки\n"); printf("1 - создание библиотеки\n"); printf("2 - список .LBX-файлов\n"); printf("3 - информация о выбранном файле\n"); printf("4 - переименование библиотеки\n"); printf("5 - уничтожение библиотеки\n"); printf("====== Операции с разделами ======\n"); printf("A - добавление раздела\n"); printf("B - замена раздела\n"); printf("C - поиск раздела\n"); printf("D - удаление раздела\n"); printf("E - переименование раздела\n"); printf("F - оглавление библиотеки\n"); printf("\nEsc - конец работы\n"); if (libname[0]) { gotoxy(45,1); printf("%s",libname); } gotoxy(1,18); f=getche(); printf("\n"); f=toupper(f); return(f); } /*==== пауза ====*/ pressany() { printf("\nНажмите любую клавишу...\n"); getch(); } /*==== печать элемента оглавления ====*/ print_head(struct lib_dir *a) { int i; printf("Раздел "); for(i=0;i<8;printf("%c",a->memb_name[i++])); printf(" размер - %d ",a->memb_size); printf("адрес - %lxH\n",a->memb_addr); } /*==== печать сообщения с паузой ====*/ prt(char *s) { printf("%s",s); pressany(); } /*==== вывод информации о файле ====*/ prt_info(struct file_info *a) { if (a->attr!=0xff) printf("Атрибут - %02Xh\n",a->attr); printf("Дата - %04d/%02d/%02d\n", ((a->date>>9)&0x007f)+1980,(a->date>>5)&0x000f, a->date&0x001f); printf("Время - %02d/%02d/%02d\n", (a->time>>11)&0x001f,(a->time>>5)&0x003f, (a->time&0x001f)*2); printf("Размер - %ld\n",a->size); printf("Мест в оглавлении - %d\n",memb_max); pressany(); } /*== ПРИМЕР 10.7 == файл 10_7_A.C ==*/ /*================= Работа с библиотекой =================*/ /* Организация операций над библиотекой */ #include <stdlib.h> #include <10_7.h> unsigned long fptr; /* текущая позиция в файле */ extern char fmemb[9]; /* имя раздела */ extern char libname[80]; /* имя файла-библиотеки */ extern int memb_max; /* число мест в оглавлении */ static int memb_num; /* номер эл-та оглавления */ static char strbuf[200]; /* буфер строки */ static struct lib_dir a; /* буфер эл-та оглавления */
Пример 13
struct DFCB { word n_handles; /* число дескрипторов */ byte open_mode; /* режим открытия */ byte reserved; byte attr; /* атрибуты файла */ word info; /* состояние устройства */ char *drv_ptr; /* адрес драйвера/DPB */ word First_clust; /* номер начального кластера */ word F_time, F_date; /* время и дата */ dword F_size; /* размер файла */ dword F_seek; /* текущее смещение в файле */ word lst_cl_n; /* относит.номер текущ.кластера */ word dir_sect; /* номер сектора каталога */ byte reserved2[2]; byte dir_num; /* номер элемента в секторе */ char fname[11]; /* имя и расширение */ byte reserved3[6]; word owner; /* PID хозяина */ word lst_clust; /* абс.номер текущего кластера */ byte reserved4[6]; };
Рассмотрение полей DFCB упорядочим по их назначению, а не по порядку их расположения в памяти.
В поле fname содержится имя файла формата FCB, то есть имя дополняется до восьми, а расширение - до трех символов пробелами. Поле n_handles содержит число дескрипторов, связанных с этим файлом. Для закрытого файла (неиспользуемого DFCB) это число - 0. Поле info содержит информационное слово для файла, формируемое драйвером устройства. Интерес в этом слове для нас представляет разряд 7, являющийся индикатором того, дисковый это файл (0) или устройство (1), и разряды 0-5, которые для дисковых файлов содержат номер дисковода (0 - A, 1 - B и т.д.). Поле drv_ptr содержит адрес. Для дисковых файлов это - адрес DPB, а для файлов-устройств - адрес заголовка драйвера. Поле owner содержит PID (сегментный адрес PSP) программы, открывшей этот файл. Поле open_mode содержит режим доступа, заданный при открытии файла (1 в старшем разряде этого байта означает, что файл открыт методом FCB).
Следующая группа полей имеет смысл только для дисковых файлов и содержит данные из элемента оглавления, описывающего этот файл в каталоге. First_clust - первый кластер файла по FAT, F_time и F_date - время и дата последней модификации файла в формате каталога, F_size - размер файла в байтах, attr - байт атрибутов файла по каталогу.
Следующие поля определяют текущее состояние чтения/записи для дискового файла. F_seek - текущее смещение от начала файла в байтах, lst_cl_n - текущее смещение от начала файла в кластерах (относительный номер последнего считанного/записанного кластера), lst_clust - абсолютный номер на диске последнего считанного/записанного кластера (смещение этого поля различно для разных версий DOS).
Наконец, еще два поля используются для внесения изменений в элемент оглавления, описывающий этот файл: dir_sect - номер сектора, содержащего часть каталога, в котором файл описан, dir_num - номер элемента в этом секторе.
Программа следующего примера позволяет просмотреть таблицы DFCB. Поскольку длины блоков разные для разных версий DOS, в описании DFCB - struct DFCB - имеется первая часть, инвариантная для всех версий DOS, и вторая - union VAR - описывающая варианты структуры DFCB для DOS 3.x и 4.x.