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);
}
