荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Pazu (不可一世的眼睛), 信区: Program
标  题: [转载] TRS程序的保存和恢复
发信站: BBS 荔园晨风站 (Tue Feb 29 17:35:24 2000), 转信

【 以下文字转载自 sysop 讨论区 】
【 原文由 lwx 所发表 】

                      TSR程序中"保存","恢复"技术的应用

    TSR编程常常要遇到DOS重入,屏幕保护等许多烦人的事情.但只要采用适当的
  方法,这些事情可以变得很轻松.
    我的经验就是:保存!--尽情破坏--恢复!!
    只要把一切可能被TSR破坏的东西(数据,硬件状态等)保存好,TSR内部就不必
  再顾虑重重了.到TSR退出激活态时,把所有东西一一复原,被中断的程序就可以
  安全地运行下去.
    保存CPU的寄存器就不必说了,因为用interrupt关键字说明的函数会自动保存
  所有寄存器.下面主要给出保存屏幕,鼠标,DOS数据等的例子.

    以下的一些程序片断,仅供分析借鉴,如有不妥或需要补充的,敬请提出. :)


>>-=============================程序实例:BEGIN=============================-<<

/*  程序在Borland C++ 3.1下编译通过,由于涉及行内汇编,其他编译器产
    生的结果可能有所不同,还望注意检查.                             */

/*  由于程序涉及较多未公开的DOS调用和内部数据结构,以及较多VGA寄存
    器操作,对运行环境可能有一定的要求.                             */


#include <dos.h>
#include <bios.h>
#include <stdio.h>
#include <string.h>

/**************************下面是本程序的一些数据定义************************/

const unsigned PSP_ENV=0x2c;  //PSP中保存环境段段址的偏移
const unsigned PSP_DTA=0x80;  //PSP中用于磁盘传输区DTA的内存区首址
const unsigned long VGA_VRAMG=0xa0000000L;  //图形模式显存地址首址
const unsigned lo4];  //保存鼠标驱动程序状态数据
static char sda_buf[2048];     //保存DOS的SDA数据
  //以上预先分配了一些缓冲区,其大小是经验值

static void far* sda_addr;     //DOS的SDA数据区首址
static unsigned sda_size;      //DOS的SDA数据区大小
static void far* indos_addr;   //DOS的INDOS标志地址
  //以上是DOS的一些参数,必须由main()在驻留前取得

/**************************上面是本程序的一些数据定义************************/



/************************下面是几个有关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<<planenum)将被送到I/O地址0x3c5
outport(0x3c4,_AX);     //AL先送0x3c4,AH后送0x3c5
}

/***********************上面是几个有关VGA操作的辅助函数**********************/




/************************下面是几个保存和?**************/

void mouse_save(char far* buffer)  //保存鼠标驱动程序状态到buffer
{                       //Warning:Inline keyword will cause an error
_ES=FP_SEG(buffer);
_DX=FP_OFF(buffer);
_AX=0x0016;             //子功能0x16,保存保存鼠标驱动程序状态到ES:DX
geninterrupt(0x33);     //鼠标驱动程序INT 33H服务
}
void mouse_restore(char far* buffer) //用buffer数据恢复鼠标驱动程序状态
{
_AX=0x0000;
geninterrupt(0x33);     //先调子功能0x00,RESET鼠标驱动程序
_ES=FP_SEG(buffer);
_DX=FP_OFF(buffer);
_AX=0x0017;             //子功能0x17,用ES:DX数据恢复鼠标驱动程序状态
geninterrupt(0x33);     //鼠标驱动程序INT 33H服务
}

/************************上面是几个保存和恢复鼠标的函数**********************/




/**************************下面是有关设置DOS数据的函数***********************/

inline void set_psp(unsigned newpsp) //把DOS当前进程的PSP强行设置为newpsp
{
_BX=newpsp;                //未公开的DOS调用0x50
_AH=0x50;
geninterrupt(0x21);
}

void set_dta(void far* newdta)       //用newdta作为DOS磁盘传输区(DTA)
{
asm{
  push ds;
  lds dx,newdta;           //DS:DX=newdta
  mov ah,0x1a;             //INT 21H的1A号功能,把DTA指向DS:DX
  int 0x21;
  pop ds;
  }
}

/**************************上面是有关设置DOS数据的函数***********************/



/*****************下面是一个TSR激活蔳ned far*)MK_FP(_psp,PSP_ENV);
asm mov ah,0x49;
asm int 0x21;        //释放环境段所占的内存

//这里省略了一些重要事务...
}

/*****************上面是一个TSR激活时保存和恢复各种数据的实例****************/



>>-==============================程序实例:END==============================-<<



                                               Wei Min Luo

                                                   整理于1997.9




--
※ 来源:·BBS 荔园晨风站 bbs.szu.edu.cn·[FROM: 202.116.191.135]
--
※ 转载:·BBS 荔园晨风站 bbs.szu.edu.cn·[FROM: 192.168.0.189]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店