可以通过BIOS把显示模式改为VGA图形模式吗?
当然可以。中断10H,即Video BIOS,负责处理文本模式和图形模式之间的转换。当你所运行的程序要进行文本模式和图形模式之间的相互转换时(即使该程序是Microsoft Windows),就需要通过Video BIOS来实现这种转换。每一种不同的设置都被称作一种显示模式。
要改变显示模式,你必须通过int 10H服务来调用Video BIOS。这就是说,你必须向中断10H的中断处理程序发出中断请求。除中断号不同之外,这与实现DOS调用(int 21H)没有什么区别。下面的一段程序通过调用Video BIOS函数0,先从标准文本模式(模式3)切换到一个由命令行输入的模式号,然后再切换回来:
# include <stdlib. h>
# include <dos. h>
main(int argc, char * * argv)
{
union REGS regs;
int mode;
/ * accept Mode number in hex * /
sscanf (argv[1] , " %x" , &mode) ;
regs. h. ah = 0; /* AH = 0 means "change display mode" */
regs.h.al = (char)mode; /* AL = ??, where ?? is the Mode number *
regs. x. bx = 0; /* Page number, usually zero */
int86(0xl0, ®s, ®s); /* Call the BIOS (intlO) * /
printf("Mode 0x%X now active\n" , mode);
printf ("Press any key to return. . . ") ;
getch();
regs. h. al = 3; / * return to Mode 3 * /
int86(0xl0, ®s, ®s);
}
有一个有趣的特点并没有在这个程序中表现出来,即该程序可以在不清屏的情况下改变显示模式。在某些场合,这一特点极为有用。要想改变显示模式,而又不影响屏幕内容,只需把存放在AI.寄存器中的显示模式值和80H或一下。例如,如果你要切换到模式13H,你只需把93H存入AL中,而程序中其余的代码可以保持不变。
今天,在VESA Video BIOS标准中已经加入了VGA卡对扩充显示模式(见下文中的补充说明)的支持。然而,需要有一个新的“改变显示模式”函数来支持这些扩充模式。按照VESA标准,在切换VESA模式时,应该使用函数4FH,而不是前文例子中的函数O。下面的程序改进了前文中的例子,以切换VESA模式:
# include <stdlib. h>
#include <dos. h>
main(int argc, char * * argv)
{
union REGS regs;
int mode;
/ * accept Mode number in hex * /
sscanf (argv[1], " %x" , &mode);
regs. x. ax = 0x4F02; /* change display mode * /
regs. x. bx = (short )mode; / * three-digit mode number * /
int86(0x10, ®s, ®s); /* Call the BIOS (intlO) * /
if(regs.h.al !=0x4F){
printf("VESA modes NOT supported! \n" );
}
else {
printf("Mode Ox%X now active\n" , mode);
printf ("Press any key to return. . . " ) ;
getch() ;
}
regs. h. al = 3; / * return to Mode 3 * /
int86(0x10,®s, ®s) ;
}
注意,在切换VESA模式时,不能通过把模式号和80H或一下来达到不清屏的目的。但是。只要把原来两位的(十六进制)模式号的最高位往前移一位,就得到了VESA模式号(所有VESA模式号的长度都是三位(十六进制),见下文中的补充说明)。因此,为了切换到VESA模式101H并且保留屏幕上的内容,你只需把VESA模式号换为901H。
关于显示模式的补充说明:
IBM推出了一种显示模式标准,该标准试图定义所有可能会用到的显示模式,其中包括所有可能的像素层次(颜色的数目)。因此,IBM创建了19种显示模式(从OH到13H)。表14.8a给出了这种显示模式标准。
14.8a 标准显示模式
-------------------------------------------------------------------------------
模式(H) 分辨率 图形/文本 颜色
-------------------------------------------------------------------------------
0 40X 25 文本 单色
1 40 X 25 文本 16
2 80X 25 文本 单色
3 80X 25 文本 16
4 320X 200 图形 4
5 320X 200 图形 4级灰度
6 640X 200 图形 单色
7 80 X 25 文本 单色
8 160X 200 图形 16
9 320X 200 图形 16
A 640 x 200 图形 4
B 保留给EC-A BIOS使用
C 保留给EGA BIOS使用
D 320×200 图形 16
E 640×200 图形 16
F 640×350 图形 单色
10 640×350 图形 4
11 640×480 图形 单色
12 640×480 图形 16
13 320×200 图形 256
-------------------------------------------------------------------------------
那么,你见过其中的某些模式吗?模式3是80×25彩色文本模式,也就是PC机上电时你所看到的模式。当你把"VGA"(随Windows提供的一个驱动程序)选为Microsoft Windows3.x的驱动程序时,你所看到的就是模式12(H)。注意,上表中并没有一种颜色多于256色或分辨率高于640×480的模式。多年以来,模式4,9和D一直是DOS游戏开发者喜欢用的模式,它们拥有“高”达320×200的分辨率和足够的颜色(4或16种),足以显示一些“象样”的图形。所有流行的动画游戏几乎都使用模式13,例如DOOM(一代和二代),id软件公司的new Heretic,Apogee公司的Rise of the Triad,Interplay公司的Descent,等等。实际上,许多动画游戏在VGA卡上耍了个小花招,即把模式13的分辨率改为320×240 这种模式被称为模式x,它有更多的内存页。可以提高图形质量和显示速度。
那么,其它一些常见的显示模式又是从哪里来的呢?它们是由VGA卡的制造商提供的。这些你可能已经熟悉的显示模式来自各种各样的渠道,但不管它们来自何处,VGA卡的制造商们都把它们加到了自己的VGA卡中,以增加这些VGA卡的价值。这些模式通常被称为扩充显示模式(extended display mode)。由于竞争和资本积累的原因,VGA卡的制造商们逐步转向了这些更高级的显示模式。有人还试过其它一些显示模式(听说过1152×900吗?),但并不象上述模式那样受欢迎。
那么。什么是VESA呢?它与VGA卡有什么关系呢?尽管VGA卡的制造商们都选择了支持同样的一组显示模式(包括扩充模式),但他们都按自己的专用方式去实现其中的扩充模式,而游戏厂商和其它软件厂商不得不去支持市场上每一种VGA卡的每一种专用方式。因此,一些制造商和其它方面的一些代表一起组成了一个委员会,以尽可能地使这些卡的设置和编程标准化,这个委员会就是VESA(Video Electronic Standards Association)。VESA委员会采用了一种扩充显示模式的标准,从而使软件可以通过普通的BIOS调用来设置和初始化所有符合该标准的VGA卡。基本上可以这样说,在美国出售的所有的VGA卡都支持某种VESA标准。
所有的VESA模式(即VESA标准所包含的那些显示模式)都采用宽度为9位(bit)的模式号,而不是标准模式的8位(hit)模式号。使用了9位(bit)的模式号后,就可以用三位十六进制数来表示VESA模式了,而IBM标准模式只能用两位十六进制数(在表14.8a中,从0到13H)来表示,这样就避免了模式号的冲突。因此,所有的VESA模式号都大于100H。VESA模式是这样起作用的:假设你想让你的VGA卡以1024×768和256色这样的模式显示,而这种模式就是VESA模式105,因此你要用模式号105作一次BIOS调用。Video BIOS(有时叫做VESA BIOS)会把VESA模式号翻译成内部专用号,以完成实际的模式切换工作。VGA卡的制造商们在每一块VGA卡上都提供了一种可以完成上述翻译工作的Video BIOS,因此你只需要搞清楚VESA模式号就行了。表14.8b列出了最新的VESA显示模式(VESA是一个不断发展的标准。)
表14.8b VESA显示模式
----------------------------------------------------------------------------
分辨率 颜色 VESA模式
----------------------------------------------------------------------------
640X400 256 100
640X480 256 101
640X480 32768 110
640X480 65536 111
640X480 16. 7M 112
800X600 16 102
800X600 256 103
800X600 32768 113
800X600 65536 114
800X600 16. 7M 115
1024X768 16 104
1024X768 256 105
1024X768 32768 116
1024X768 65536 117
1024X768 16. 7M 118
1280X1024 16 106
1280X1024 256 107
1280X1024 32768 119
1280X1024 65536 11A
1280X1024 16. 7M 11B
-----------------------------------------------------------------------------
注意,这些都是人们熟悉的显示模式,特别是在使用Microsoft Windows时,这些模式更为常见。
要改变显示模式,你必须通过int 10H服务来调用Video BIOS。这就是说,你必须向中断10H的中断处理程序发出中断请求。除中断号不同之外,这与实现DOS调用(int 21H)没有什么区别。下面的一段程序通过调用Video BIOS函数0,先从标准文本模式(模式3)切换到一个由命令行输入的模式号,然后再切换回来:
# include <stdlib. h>
# include <dos. h>
main(int argc, char * * argv)
{
union REGS regs;
int mode;
/ * accept Mode number in hex * /
sscanf (argv[1] , " %x" , &mode) ;
regs. h. ah = 0; /* AH = 0 means "change display mode" */
regs.h.al = (char)mode; /* AL = ??, where ?? is the Mode number *
regs. x. bx = 0; /* Page number, usually zero */
int86(0xl0, ®s, ®s); /* Call the BIOS (intlO) * /
printf("Mode 0x%X now active\n" , mode);
printf ("Press any key to return. . . ") ;
getch();
regs. h. al = 3; / * return to Mode 3 * /
int86(0xl0, ®s, ®s);
}
有一个有趣的特点并没有在这个程序中表现出来,即该程序可以在不清屏的情况下改变显示模式。在某些场合,这一特点极为有用。要想改变显示模式,而又不影响屏幕内容,只需把存放在AI.寄存器中的显示模式值和80H或一下。例如,如果你要切换到模式13H,你只需把93H存入AL中,而程序中其余的代码可以保持不变。
今天,在VESA Video BIOS标准中已经加入了VGA卡对扩充显示模式(见下文中的补充说明)的支持。然而,需要有一个新的“改变显示模式”函数来支持这些扩充模式。按照VESA标准,在切换VESA模式时,应该使用函数4FH,而不是前文例子中的函数O。下面的程序改进了前文中的例子,以切换VESA模式:
# include <stdlib. h>
#include <dos. h>
main(int argc, char * * argv)
{
union REGS regs;
int mode;
/ * accept Mode number in hex * /
sscanf (argv[1], " %x" , &mode);
regs. x. ax = 0x4F02; /* change display mode * /
regs. x. bx = (short )mode; / * three-digit mode number * /
int86(0x10, ®s, ®s); /* Call the BIOS (intlO) * /
if(regs.h.al !=0x4F){
printf("VESA modes NOT supported! \n" );
}
else {
printf("Mode Ox%X now active\n" , mode);
printf ("Press any key to return. . . " ) ;
getch() ;
}
regs. h. al = 3; / * return to Mode 3 * /
int86(0x10,®s, ®s) ;
}
注意,在切换VESA模式时,不能通过把模式号和80H或一下来达到不清屏的目的。但是。只要把原来两位的(十六进制)模式号的最高位往前移一位,就得到了VESA模式号(所有VESA模式号的长度都是三位(十六进制),见下文中的补充说明)。因此,为了切换到VESA模式101H并且保留屏幕上的内容,你只需把VESA模式号换为901H。
关于显示模式的补充说明:
IBM推出了一种显示模式标准,该标准试图定义所有可能会用到的显示模式,其中包括所有可能的像素层次(颜色的数目)。因此,IBM创建了19种显示模式(从OH到13H)。表14.8a给出了这种显示模式标准。
14.8a 标准显示模式
-------------------------------------------------------------------------------
模式(H) 分辨率 图形/文本 颜色
-------------------------------------------------------------------------------
0 40X 25 文本 单色
1 40 X 25 文本 16
2 80X 25 文本 单色
3 80X 25 文本 16
4 320X 200 图形 4
5 320X 200 图形 4级灰度
6 640X 200 图形 单色
7 80 X 25 文本 单色
8 160X 200 图形 16
9 320X 200 图形 16
A 640 x 200 图形 4
B 保留给EC-A BIOS使用
C 保留给EGA BIOS使用
D 320×200 图形 16
E 640×200 图形 16
F 640×350 图形 单色
10 640×350 图形 4
11 640×480 图形 单色
12 640×480 图形 16
13 320×200 图形 256
-------------------------------------------------------------------------------
那么,你见过其中的某些模式吗?模式3是80×25彩色文本模式,也就是PC机上电时你所看到的模式。当你把"VGA"(随Windows提供的一个驱动程序)选为Microsoft Windows3.x的驱动程序时,你所看到的就是模式12(H)。注意,上表中并没有一种颜色多于256色或分辨率高于640×480的模式。多年以来,模式4,9和D一直是DOS游戏开发者喜欢用的模式,它们拥有“高”达320×200的分辨率和足够的颜色(4或16种),足以显示一些“象样”的图形。所有流行的动画游戏几乎都使用模式13,例如DOOM(一代和二代),id软件公司的new Heretic,Apogee公司的Rise of the Triad,Interplay公司的Descent,等等。实际上,许多动画游戏在VGA卡上耍了个小花招,即把模式13的分辨率改为320×240 这种模式被称为模式x,它有更多的内存页。可以提高图形质量和显示速度。
那么,其它一些常见的显示模式又是从哪里来的呢?它们是由VGA卡的制造商提供的。这些你可能已经熟悉的显示模式来自各种各样的渠道,但不管它们来自何处,VGA卡的制造商们都把它们加到了自己的VGA卡中,以增加这些VGA卡的价值。这些模式通常被称为扩充显示模式(extended display mode)。由于竞争和资本积累的原因,VGA卡的制造商们逐步转向了这些更高级的显示模式。有人还试过其它一些显示模式(听说过1152×900吗?),但并不象上述模式那样受欢迎。
那么。什么是VESA呢?它与VGA卡有什么关系呢?尽管VGA卡的制造商们都选择了支持同样的一组显示模式(包括扩充模式),但他们都按自己的专用方式去实现其中的扩充模式,而游戏厂商和其它软件厂商不得不去支持市场上每一种VGA卡的每一种专用方式。因此,一些制造商和其它方面的一些代表一起组成了一个委员会,以尽可能地使这些卡的设置和编程标准化,这个委员会就是VESA(Video Electronic Standards Association)。VESA委员会采用了一种扩充显示模式的标准,从而使软件可以通过普通的BIOS调用来设置和初始化所有符合该标准的VGA卡。基本上可以这样说,在美国出售的所有的VGA卡都支持某种VESA标准。
所有的VESA模式(即VESA标准所包含的那些显示模式)都采用宽度为9位(bit)的模式号,而不是标准模式的8位(hit)模式号。使用了9位(bit)的模式号后,就可以用三位十六进制数来表示VESA模式了,而IBM标准模式只能用两位十六进制数(在表14.8a中,从0到13H)来表示,这样就避免了模式号的冲突。因此,所有的VESA模式号都大于100H。VESA模式是这样起作用的:假设你想让你的VGA卡以1024×768和256色这样的模式显示,而这种模式就是VESA模式105,因此你要用模式号105作一次BIOS调用。Video BIOS(有时叫做VESA BIOS)会把VESA模式号翻译成内部专用号,以完成实际的模式切换工作。VGA卡的制造商们在每一块VGA卡上都提供了一种可以完成上述翻译工作的Video BIOS,因此你只需要搞清楚VESA模式号就行了。表14.8b列出了最新的VESA显示模式(VESA是一个不断发展的标准。)
表14.8b VESA显示模式
----------------------------------------------------------------------------
分辨率 颜色 VESA模式
----------------------------------------------------------------------------
640X400 256 100
640X480 256 101
640X480 32768 110
640X480 65536 111
640X480 16. 7M 112
800X600 16 102
800X600 256 103
800X600 32768 113
800X600 65536 114
800X600 16. 7M 115
1024X768 16 104
1024X768 256 105
1024X768 32768 116
1024X768 65536 117
1024X768 16. 7M 118
1280X1024 16 106
1280X1024 256 107
1280X1024 32768 119
1280X1024 65536 11A
1280X1024 16. 7M 11B
-----------------------------------------------------------------------------
注意,这些都是人们熟悉的显示模式,特别是在使用Microsoft Windows时,这些模式更为常见。