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

unsigned int segm, unsigned int



Пример 10

void far *MK_FP( unsigned int segm, unsigned int offs);
Следует учитывать, что внутреннее представление указателей зависит от модели памяти, в которой транслируется программа или от явного описания. Указатель может быть либо ближним (явное описание: near) и представляться двухбайтным смещением в текущем сегменте, либо дальним (явное описание: far) и иметь четырехбайтное представление - сегментная часть адреса и смещение. Указанные макросы работают только с дальними указателями.
Программные примеры данного пособия компилируются в модели памяти large (если в тексте программы не указана другая модель). По умолчанию в этой модели все указатели являются far. При компиляции в той модели памяти, где указатель по умолчанию near необходимо включить в описания всех указателей явные описатели far.



Пример 10

/*== ПРИМЕР 7.10 ==*/ /*= Использование Esc-последовательностей драйвера ANSI =*/ main() { char string[81]; /* 1). Клавише с ASCII-кодом 97 ( буква a) назначается целая строка "клавиша a" */ printf("\33[97;\"клавиша a\"p"); /* 2). Клавише с ASCII-кодом 98 (буква b) назначается код 66 (буква B) */ printf("\33[98;66p"); /* 3). Клавише с ASCII-кодом 99 (буква c) назначается последовательность кодов 65,66,67 (буквы ABC) */ printf("\33[99;65;66;67p"); /* 4). Клавише с ASCII-кодом 100 (буква c) назначается строка "перевод строки" и еще символ с кодом 10 */ printf("\33[100;\"перевод строки\";10p"); /* 5). Клавише с расширенным ASCII-кодом 0,59 (F1) назначается строка "клавиша F1" 6). Клавише с расширенным ASCII-кодом 0,60 (F2) назначается код 98 (буква b) - при обработке этого назначения не будет учитываться ранее сделанное нзначение для кода 98 */ printf("\33[0;59;\"клавиша F1\"p\33[0;60;98p"); /* При вводе этой строки убедимс, что назначение сработало */ gets(string); /* Восстановление кодов */ printf("\33[97;97p\33[98;98p\33[99;99p"); printf("\33[100;100p\33[0;59;0;59p\33[0;60;0;60p"); /* При вводе этой строки убедимся, что восстановление произошло */ gets(string); }



Пример 10

/*== ПРИМЕР 9.8 ==*/ /*======= Формирование пользовательского шрифта ======*/ #include <dos.h>
unsigned char font[56] = { /* пользовательский шрифт 8x14 */ /* буква T */ 0x00,0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x5a, 0x7e,0x7e,0x00,0x00,0x00, /* буква U */ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6, 0xc6,0xc6,0x00,0x00,0x00, /* буква V */ 0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xc6,0xc6, 0xc6,0xc6,0x00,0x00,0x00, /* буква W */ 0x00,0x00,0x6c,0x7c,0xd6,0xd6,0xc6,0xc6,0xc6, 0xc6,0xc6,0x00,0x00,0x00 }; unsigned save_es, save_bp; /* для сохр.адреса */ unsigned reg[5]; /* для сохранения регистров */ main() { int i; clrscr(); for ( i = 'A'; i
Подфункции 1 и 2 могут использоваться для восстановления исходных обpазов в знакогенеpатоpе, пpи их выполнении из ПЗУ адаптеpа загpужаются таблицы символов 8 x 14 (подфункция 1) или 8 x 8 (подфункция 2). В нашей пpогpамме пpи нажатии клавиши загpуженный нами шpифт заменяется шpифтом из ПЗУ. Однако, может оказаться, что пpи этом будет испоpчена втоpая стpока вывода - символы киpиллицы. Действительно, обpазы букв киpиллицы необязательно пpисутствуют в ПЗУ адаптеpа заpубежного пpоизводства. Дpайвеp-pусификатоp создает свою таблицу обpазов, котоpую он загpужает в знакогенеpатоp, используя те же сpедства, что и мы (подфункцию 0). Для того, чтобы коppектно восстановить знакогенеpатоp, пpогpамма должна пpежде чем загpужать свой шpифт узнать и запомнить адpес той таблицы, котоpая загpужена в знакогенеpатоp в настоящий момент, что наша пpогpамма и делает пpи помощи подфункции 0x30. Пpи окончании pаботы с оpигинальным шpифтом пpогpамма загpужает в знакогенеpатоp таблицу, адpес котоpой она запомнила pанее.



Пример 10

struct FCB { byte drive; /* Логич. номер диска: 0-текущий, 1 - A, 2 - B и т.д. */ char fname[8]; /* Имя файла (дополн.пробелами) */ char fext[3]; /* Расширение файла (доп.пробелами) */ word curblk; /* Текущий номер блока (в блоке 128 записей) */ word recsize; /* Размер записи (байт) */ dword fsize; /* Размер файла (байт) */ word date; /* Дата создания (в формате элемента каталога) */ word time; /* Время создания (в формате элемента каталога) */ char reserved1[8]; byte currec; /* Текущий номер записи в блоке */ dword randrec; /* Относительный номер записи */ };
Во всех операциях с файлом идентификатором файла служит адрес FCB.

Программист перед открытием файла должен заполнить поля drive, fname и fext, остальные поля заполняются при открытии файла системой и поддерживаются DOS при работе с файлом. Если при создании файла необходимо задать его атрибуты в каталоге, FCB должен иметь расширенный формат, а именно:



Пример 10

/*== ПРИМЕР 13.3 ==*/ /*======= Распечатка массива текущих каталогов ==========*/ #include <dos.h> #include <stdlib.h> #define byte unsigned char # define word unsigned int struct CDS { /* структура текущего каталога */ char path[67]; word flags; union VAR { struct { /* для DOS 3.x, 4.x */ void *ddcb; word dir_clust; byte reserved[11]; } dos4; struct { /* для DOS 5.x и выше */ byte drive reserved1; word par_clust, par_entry,dir_clust; byte reserved2[4]; } dos5; } dosx; } *cds; word a_seg, a_off; /* нач.адрес массива */ byte lastdrive; /* LASTDRIVE из CONFIG */ byte ndrive; /* счетчик */ word units; /* число блочных устр-в */ byte dos; /* версия DOS */ int cds_size; /* размер CDS */ union REGS rr; struct SREGS sr; main() { /* номер версии DOS */ rr.h.ah=0x30; intdos(&rr,&rr); dos=rr.h.al; if (dos!=4) cds_size=81; else cds_size=88; /* адрес CVT */ rr.h.ah=0x52; intdosx(&rr,&rr,&sr); printf("\nМассив текущих каталогов\n"); /* выборка информации из CVT */ a_off=peek(sr.es,rr.x.bx+22); a_seg=peek(sr.es,rr.x.bx+24); cds=(struct CDS *)MK_FP(a_seg,a_off); lastdrive=peekb(sr.es,rr.x.bx+33); printf("LASTDRIVE - %u\n",lastdrive); for(ndrive=0; ndrive<lastdrive; ndrive++) { printf("Адрес CDS - %Fp\n",cds); printf(" path - %s\n",cds->path); if (dos<5) { printf(" адр.DPB - "); if (cds->dosx.dos4.ddcb==NULL) printf("пусто\n"); else { printf(" %Fp\n",cds->dosx.dos4.ddcb); printf(" флаги - %04X\n",cds->flags); printf(" 1-й кластер тек.каталога - %04X\n", cds->dosx.dos4.dir_clust); } } else { printf(" флаги - %04X\n",cds->flags); printf(" 1-й кластер тек.каталога - %04X\n",cds->dosx.dos5.dir_clust); printf(" лог.диск #%d\n",cds->dosx.dos5.drive); printf(" верхний каталог - кластер %04X,",cds->dosx.dos5.par_clust); printf(" вход - %d\n",cds->dosx.dos5.par_entry); } cds=(struct CDS *)((byte *)cds+cds_size); if (getch()==27) exit(0); } }

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