没办法了,这两天生病,周一交东西,200分求助!
houzy 2003-08-20 11:18:00 dos6.22下,
tc2.0,
标准c,tsr程序
原本运行的是一个图形菜单界面的程序,现在的tsr程序要在该程序中热键弹出,而该tsr程序是文本菜单(基本内存只有640k,节约起见,现在也是刚好够用而已)。
问题就在于,我只知道怎么保护原本是文本菜单的程序。而现在 需要做两步,一是保护原来的显存和状态,二是切换到文本状态 。
现在切换状态我已经搞定,而保护图形菜单程序的显存始终没有成功。
我参照的是如下程序(是c++的,只是参考,我需要标准c的):
/**************************下面是本程序的一些数据定义************************/
const unsigned long VGA_VRAMG=0xa0000000L; //图形模式显存地址首址
const unsigned long VGA_VRAMT=0xb8000000L; //文本模式显存地址首址
static char vga_buf1[2048]; //保存VGA状态数据
static char vga_buf2[0x3000]; //保存显存数据2K+2K+8K
/************************下面是几个有关VGA操作的辅助函数*********************/
inline void vga_set_mode(unsigned modenum) //把VGA显示模式设置为modenum
{
_AX=modenum;
_AH=0x0;
geninterrupt(0x10); //AH=0,AL=modenum,调用BIOS INT 10H
}
inline void vga_rplane_sel(char planenum) //选中VGA页面planenum读取
{
_AH=planenum; //AH=planenum将被送到I/O地址0x3cf
_AL=0x4; //AL=4送0x3ce,选中"读页面选择寄存器"
outport(0x3ce,_AX); //AL先送0x3ce,AH后送0x3cf
}
inline void vga_wplane_sel(char planenum) //选中VGA页面planenum写入
{
_AX=0x0102; //AL=2送0x3c4,选中"彩色页面写允许寄存器"
_AH<<=planenum; //AH=(0x01< outport(0x3c4,_AX); //AL先送0x3c4,AH后送0x3c5
}
/***********************上面是几个有关VGA操作的辅助函数**********************/
/************************下面是几个保存和恢复屏幕的函数**********************/
/* 由于使用了VESA调用,对Super VGA的模式也可以成功地保存和恢复.
但相应地,显示卡也必须支持有关VESA调用 */
void vga_save(char far* buffer1,char far* buffer2)
//保存VGA状态到buffer1,保存被文本模式03H破坏的显存到buffer2,并切换到模式03H
{
_ES=FP_SEG(buffer1);
_BX=FP_OFF(buffer1); //ES:BX=buffer1,缓冲区的首址
_AX=0x4f04; //BIOS INT 10H的4F04号VESA功能调用
_CX=0xffff; //表示要保存所有的状态数据
_DL=0x1; //子功能1,保存VGA状态到ES:BX
geninterrupt(0x10);
vga_set_mode(0x92); //切换到模式12H,0x92的最高位是1表示保留显存数据
vga_rplane_sel(0x2); //选择页面2读取
_fmemcpy(buffer2,(void far*)VGA_VRAMG,0x2000);
//页面2的开头8K将被模式03H的字模覆盖,故保存到buffer2
vga_set_mode(0x83); //切换到模式03H,0x82的最高位是1表示保留显存数据
_fmemcpy(buffer2+0x2000,(void far*)VGA_VRAMT,0x1000);
//显存头上的4K(页面0的2K是字符,页面1的2K是属性,CPU地址交替)
//将被模式03H的屏幕数据覆盖,故保存到buffer2+0x2000
}
void vga_restore(char far* buffer1,char far* buffer2)
//用buffer2的数据恢复显存,用buffer1的数据恢复VGA状态
{
_fmemcpy((void far*)VGA_VRAMT,buffer2+0x2000,0x1000);
//恢复显存头上的4K(页面0开头的2K,页面1开头的2K)
vga_set_mode(0x92);
vga_wplane_sel(0x2);
_fmemcpy((void far*)VGA_VRAMG,buffer2,0x2000);
//恢复显存页面2的开头8K
_ES=FP_SEG(buffer1);
_BX=FP_OFF(buffer1);
_AX=0x4f04;
_CX=0xffff;
_DL=0x2; //子功能2,用ES:BX的数据恢复VGA状态
geninterrupt(0x10);
}
/************************上面是几个保存和恢复屏幕的函数**********************/
有用的主要就是就是 vga_save 和 vga_restore两个函数,分别在tsr执行前和执行后调用。里面的 vga_set_mode 证实可用,而保存显存的总是失败,请大家看看,谢谢了!