(5)当前显示方式所使用的最大页号:vga-pages
这个表格由图形初始化例程来填写。图形初始化例程接收的显示模式是统一的模式号,这样可以撇开具体的设备,如InitVGA(TVGA800×600)。该例程调用显示设备检测程序DetectVGA来判断显示器的类型,从而填写表格中的各栏目,并初始化图形系统为所需的图形方式。所有图形算法都要查此表。
除了用上述方法来实现兼容外,视频电子学标准协会(VESA)为我们提供了另一种方法。
VESA
提供了一组附加的BIOS功能,这组功能以标准的方式访问SuperVGA扩充的模式。VESA的附加功能都是通过BIOS中断10H的4FH功能来实现的。VESA的子功能01能返回非常有用的SuperVGA模式信息,包括分页例程的地址。
因此,程序员可以按照VESA的标准来编写图形系统,这样的程序可以在所有支持VESA的显示器上运行。由于VESA包括了世界上的主要VGA供应商,写出来的程序可移植性是很好的。但是,其效率却可能是最低的。所以最好采用一种折衷的办法,对于熟悉的产品,可以不用VESA的功能,对于不熟悉(资料不全)或检测不出来的显示器尝试用VESA提供的手段来编程,当然要检测显示设备是否支持VESA。
有时出于某种考虑,不希望支持所有显示设备的代码集中在一个程序中,可以为每个显示设备分别提供驱动模块,主程序根据检测的结果选择一个合适的模块加载。Borland的C++就是这样,它有一套BGI驱动程序,各驱动程序提供统一的图形函数接口。笔者在实际工作中,为每一种显示设备编写了一个256色的BGI格式的驱动程序,这样,在编写图形系统时,再也没有必要考虑用户的实际显示设备了。
三、范例
本文附有两个图形显示的例子。ShowGif能显示16/256色GIF格式图像,能以任何256色模式启动,支持多种显示器。图像可以漫游,并可随时通过按键切换显示方式。Main则是一个BGI驱动的鼠标/键盘控制的256色汉字图形菜单。它自己会挑选一个合适的BGI,也可以从命令行指定一个BGI(比如指定VESA256给TVGA显示器)。
限于篇幅,这里仅给出有关的数据结构和部分函数的说明(程序2)。然后给出一个初始化显
示系统的C语言片断(程序3)。
程序2(TVGA256。H):
/*统一的模式集*/
enumTVGA-MODE
TVGA320x200=0,
TVGA640x400=1,
TVGA640x480=2,
TVGA800x600=3,
TVGA1024x768=4,
;
voidTVGA256-driver(void);
voidPVGA256-driver(void);
voidAVGA256-driver(void);
。。。
voidVESA256-driver(void);
externintfar-CdeclTVGA256-driver-far[];
externintfar-CdeclPVGA256-driver-far[];
externintfar-CdeclAVGA256-driver-far[];
。。。
externintfar-CdeclVESA256-driver-far[];
/*支持的VGA集合*/
enumVGAs{
UnKnownVGA,
TridentVGA,
ParadiseVGA,
AheadVGA,
。。。
VesaVGA
};
/*对应的BGI驱动程序名*/
unsignedchar*Drivers[]={
"TVGA256",
"TVGA256",
"AVGA256",
。。。
"VESA256",
};
externintDetectVGA(void);
/*功能:检测显示卡的型号
返回值:0-Unknowm1-TridentVGA2-ParadiseVGA
。。。
x-不能检测出的VGA,但支持VESA
返回值同时写入全局变量vga-type*/
externintVesaFound(void);
/*功能:检测VESABIOS的存在性
返回:0-不支持VESA;
其它-VESA版本号(0x0102即1。02版);
返回值同时写入全程变量vesa-found。*/
externvoidInitVesa(void);
/*功能:初始化VESA。根据-vga-mode模式号换算成VESA的标准模式号填写页粒度(WinGranularity),页大小(WinSize),
和分页例程的入口地址(WinFuncPtr)
VESA的标准模式解释如下:
100h-640x400256
101h-640x480256
102h-800x60016
103h-800x600256
104h-1024x76816
105h-1024x768256etc。
InitVesa供给InitVGA调用*/
externvoidInitVGA(intmode);
/*功能:初始化显示系统(自动调用DetectVGA检测显示卡)
参数:mode=TVGA320x200(0)
TVGA640x400(1)
TVGA640x480(2)
TVGA800x600(3)
TVGA1024x768(4)
返回:InitVGA没有显式的返回值,但它初始化下列全程变量:
vga-mode,vga-width,vga-depth,vga-pages,PageSelect
必要时自动调用InitVesa
*/
externintvga-type;
externintvga-mode;
externintvga-width;
externintvga-depth;
externintvga-pages;
externintvga-pages;
externcharpage-number;
externintvesa-found;
。。。
程序3(初始化显示系统的程序片断):
。。。
intGraphDriver,GraphMode;
unsignedchar*bgiDriver="PVGA256";
bgiDriver=Drivers[DetectVGA()];
GraphDriver=installuserdriver(bgiDriver,NULL);
GraphMode=TVGA800x600;
initgraph(&GraphDriver,&GraphMode,"");。。。
参考文献
1来文占等编译。SuperVGA高级编程指南。北京:北京科海培训中心,1991。5。
2张一波编译。SuperVGA与VESA编程指南。北京:海洋出版社,1992
(责任编辑:一枝笔写作)