CodeNet / Приложения / Графика / VGA, VESA и другие стандарты / Графический адаптер 8514/a фирмы IBM
Графический адаптер 8514/a фирмы IBM
Листинг программы 8514DEMO.C
/* Демонстрация работы дисплейного адаптера 8514/A */ /* Необходимы:ibmafi.h, calafi.obj, hdiload.exe, stan1220.fnt */ #include <dos.h> /*заголовок для функций обращения к DOS */ #include <io.h> /*заголовок для функций работы с файлами*/ #include <fcntl.h> #include <malloc.h> /*заголовок для функ-й управлен. памятью*/ #include <string.h> /*заголовок для функций обработки строк */ #include <ibmafi.h> /*интерфейс дисплейного адаптера */ #define FONTFILE_NAME "STAN1220.FNT" #define COLOR_WHITE 3 #define MESSAGE "Hello, Display Adapter 8514/A!" #define MAX_STR 40 HOPEN_DATA open_data ={ 3,0,0 } HCLOSE_DATA close_data ={ 2,0 } HSCS_DATA font ={ 4,0 } /* Описание локальных функций */ struct CharSetDef *LoadFont(char *); int main(void); /* Локальные функции */ struct CharSetDef *LoadFont(fileName); char *fileName; /* имя файла, содержащего шрифт */ { word fontlen; struct FontFileDefn *ioaddr; int f_id; struct CharSetDef *a_csd; /* Попытка открытия файла, содержащего шрифт. Если файл не может быть открыт, возвращается признак ошибки */ if ((f_id = open (fileName,O_RDONLY | O_BINARY)) == -1) return NULL; /* Определение размера файла шрифта, выделение буфера и чтение в него файла. Если буфер не может быть выделен, возвращается признак ошибки */ fontlen = (int)lseek(f_id,0L,2); if (!(ioaddr = (struct FontFileDefn *)malloc(fontlen))) return NULL; lseek(f_id,0L,0); /* переход на начало файла */ read(f_id,(char *)ioaddr,fontlen); /* Помещение в таблицу определения шрифта адреса начала загруженного шрифта */ a_csd = (struct CharSetDef *)(((char *)ioaddr) + ioaddr->page_array[ioaddr->def_page].csd_offset); a_csd->chardef1=((char far *)ioaddr+((long)a_csd->chardef1); a_csd->chardef2=((char far *)ioaddr+((long)a_csd->chardef2); a_csd->chardef3=((char far *)ioaddr+((long)a_csd->chardef3); a_csd->indextbl = (int far *) (((byte far *)ioaddr)+((long)a_csd->indextbl)); a_csd->enveltbl=(char far *)ioaddr)+(long)a_csd->enveltbl)); /* Закрытие файла и возврат адреса */ close(f_id); return a_csd; } int main() { HINIT_DATA taskState; HQDPS_DATA stateBufferInfo; HQMODE_DATA modeData; HSCOL_DATA textcolor; HCHST_DATA(MAX_STR) drawString; int retVal; int messageHeight, messageWidth; union REGS inregs, outregs; struct SREGS segregs; /* Проверка наличия программного интерфейса адаптера */ if (getafi() == NULL) { printf ("Please run HDILOAD to install the interface.\n"); return 1; } /* Программы интерфейса загружены, производится обращение к адаптеру и проверяется результат обращения к нему */ HOPEN(&open_data); /* Открытие интерфейса */ if (open_data.iflags) /* в случае ошибки */ { printf("Adapter Open error:%X\n",open_data.iflags; return 1; } /* Выделение буфера состояния задачи. Данные в этот буфер записываются при вызове HINIT и должны быть помещены туда независимо от того будет или не будет производиться переключение режимов адаптера */ stateBufferInfo.length = 6; /* Размер буфера */ HQDPS(stateBufferInfo); /* Информационный блок буфера состояния теперь содержит размер буфера состояния задачи для функции HINIT. Т.к. программе HINIT в качестве указателя передается только сегментный адрес, она предполагает, что смещение буфера в этом сегменте равно 0 */ inregs.h.ah = 0x48; /* Выделение сегмента */ inregs.x.bx = stateBufferInfo.size; intdos(&inregs,&outregs); taskState.segment = outregs.x.ax; taskState.length = 2; /* Длина сегментного указателя */ HINIT(&taskState); /* Инициализация адаптера */ modeData.length = 18; /* Режим по умолчанию */ HQMODE(&modeData); /* Все установки сделаны. Все это стандартные действия, которые должны быть выполнены в любой прикладной программе, взаимодействующей с 8514/A. Теперь будет загружен шрифт и выведено сообщение на экран. Используется стандартный шрифт 12 x 20, поставляемый с программами интерфейса */ if (!(font.address = LoadFont(FONTFILE_NAME))) { printf("Font file %s could not be loaded!\n", FONTFILE_NAME); retVal = 1; } else { textColor.length = 4; textColor.index = COLOR_WHITE; HSCOL(&textColor); /* Символы выводятся белым цветом*/ font.length = 4; HCSC(&font); /* Установка шрифта */ /* Далее выполняются необходимые вычисления для того, чтобы вывести сообщение в центре экрана с учетом размера символов */ messagHeights = font.address->cellheight; messagWidth = font.address->cellwidth*strlen(MESSAGE); /* Вывод строки */ drawString.coord.x_coord = (modeData.width - messageWidth) / 2; drawString.coord.y_coord = (modeData.heights - messageHeight) / 2; drawString.length = sizeof(coord_pr) + strlen(MESSAGE); strcpy(drawString.string,MESSAGE); HCHST (&drawString); retVal = 0; } getch(); /* Освобождение буфера и закрытие адаптера */ inregs.h.ah = 0x49; segregs.es = taskState.segment; int86x(0x21,&inregs,&outregs,&segregs); HCLOSE(&close_data); /* эакрыть интерфейс адаптера */ return(0); }