home *** CD-ROM | disk | FTP | other *** search
- /* ----- resident.c ----- */
-
- #include <dos.h>
- #include <conio.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <malloc.h>
- #include "tsr.h"
-
- static union REGS rg;
- static struct SREGS seg;
-
- /* --- vectors --- */
- #define KEYBD 9
- #define TIMER 0x1c
- #define DISK 0x13
- #define VIDEO 0x10
- #define ZERODIV 0
- #define INT28 0x28
- #define CRIT 0x24
- #define CTRLC 0x23
- #define CTRLBRK 0x1b
-
- /* --- interrupt vector chains --- */
- static void interrupt (far *tmpvect)(void);
- static void interrupt (far *oldbreak)(void);
- static void interrupt (far *oldctrlc)(void);
- void interrupt (far *oldtimer)(void);
- void interrupt (far *old28)(void);
- void interrupt (far *oldkb)(void);
- void interrupt (far *olddisk)(void);
- void interrupt (far *oldvideo)(void);
- static void interrupt (far *oldcrit)(void);
- /* --- ISRs for the TSR --- */
- extern void interrupt newtimer(void);
- extern void interrupt new28(void);
- extern void interrupt newkb(void);
- extern void interrupt newdisk(void);
- extern void interrupt newvideo(void);
- extern void interrupt newcrit();
- extern void interrupt newbreak();
- /* --- global variables --- */
- static unsigned sizeprogram;
- static unsigned dosseg;
- char far *dosbusy;
- static char far *mydta;
- unsigned myss;
- unsigned stack;
- static unsigned intpsp;
- static unsigned far *psps[5];
- static int pspctr;
- static int resoff;
- extern unsigned running;
- int popflg;
- int suspending=0;
- int terminating=0;
- int diskflag=0;
- int videoflag=0;
-
- /* --- local prototypes --- */
- static void resterm(void);
- static void pspaddr(void);
- void dores(void);
- void popup_tsr(void);
- /* --- establish and declare residency --- */
- void resinit()
- { int pp,xtmp;
- suspending=0;terminating=0;running=0;
- segread(&seg);
- myss = seg.ss;
- stack = getsp();
- /* --- get address of DOS busy flag --- */
- rg.h.ah = 0x34;
- intdosx(&rg,&rg,&seg);
- dosseg = seg.es;
- FP_SEG(dosbusy)=seg.es;
- FP_OFF(dosbusy)=rg.x.bx;
- /* --- get address of resident program's dta --- */
- mydta = getdta();
- pspaddr();
- /* --- get original interrupt vectors --- */
- oldtimer = getvect(TIMER);
- old28 = getvect(INT28);
- oldkb = getvect(KEYBD);
- olddisk = getvect(DISK);
- oldvideo = getvect(VIDEO);
-
- /* --- attach vectors to resident program --- */
- tmpvect=newtimer; setvect(TIMER,tmpvect);
- tmpvect=new28; setvect(INT28,tmpvect);
- tmpvect=newkb; setvect(KEYBD,tmpvect);
- tmpvect=newdisk; setvect(DISK, tmpvect);
- tmpvect=newvideo; setvect(VIDEO,tmpvect);
-
- /* --- compute program size --- */
- sizeprogram = farsetsize(0)+50;
- /* --- terminate and stay resident --- */
- keep(0,sizeprogram);
- }
-
- void resident_psp()
- {
- int pp;
- intpsp = *psps[0];
- for (pp=0; pp<pspctr; pp++)
- *psps[pp]=_psp;
- }
-
- void interrupted_psp()
- {
- int pp;
- for (pp=0; pp<pspctr; pp++)
- *psps[pp]=intpsp;
- }
-
- void popup_tsr()
- {
- static char far *intdta;
- static unsigned intsp;
- static unsigned intss;
- static unsigned ctrl_break;
-
- disable();
- oldcrit=getvect(CRIT);
- oldbreak=getvect(CTRLBRK);
- oldctrlc=getvect(CTRLC);
- tmpvect=newcrit; setvect(CRIT,tmpvect);
- tmpvect=newbreak; setvect(CTRLBRK,tmpvect);
- setvect(CTRLC,tmpvect);
- ctrl_break=getcbrk();
- setcbrk(0);
- intdta=getdta();
- setdta(mydta);
- resident_psp();
- enable();
- popup();
- disable();
- interrupted_psp();
- setdta(intdta);
- setvect(CRIT,oldcrit);
- setvect(CTRLBRK,oldbreak);
- setvect(CTRLC,oldctrlc);
- setcbrk(ctrl_break);
- enable();
-
- if (terminating) terminate();
- }
-
- unsigned resident(char *signature)
- {
- char *sg;
- unsigned df,mcbseg,blkseg;
-
- segread(&seg);
- df=seg.ds-_psp;
- rg.h.ah = 0x52;
- intdosx(&rg,&rg,&seg);
- mcbseg=peek(seg.es,rg.x.bx-2);
- while (peekb(mcbseg,0)==0x4d) {
- blkseg=peek(mcbseg,1);
- if (peek(blkseg,0)==0x20cd) {
- if (blkseg==_psp)
- break;
- for (sg=signature;*sg;sg++)
- if (*sg!=peekb(blkseg+df,(unsigned)sg))
- break;
- if (!*sg) {
- if (peek(blkseg+df,(unsigned)&suspending)) {
- poke(blkseg+df,(unsigned)&suspending,0);
- return 2;
- }
- return 1;
- }
- }
- mcbseg+=peek(mcbseg,3)+1;
- }
- return 0;
- }
-
- static void pspaddr()
- {
- unsigned adr=0;
- unsigned enddos;
- static unsigned far *ed, far *ps;
- adr=0;
- rg.h.ah=0x52;
- intdosx(&rg,&rg,&seg);
- FP_SEG(ed)=seg.es;
- FP_OFF(ed)=rg.x.bx-2;
-
- enddos=*ed;
- while(pspctr<5 &&
- (unsigned)((dosseg<<4)+adr)<(enddos<<4)){
- FP_SEG(ps)=dosseg;
- FP_OFF(ps)=adr;
- if (*ps==_psp){
- rg.h.ah = 0x50;
- rg.x.bx = _psp+1;
- intdos(&rg,&rg);
- if (*ps==_psp+1)
- psps[pspctr++]=ps;
- rg.h.ah = 0x50;
- rg.x.bx = _psp;
- intdos(&rg,&rg);
- }
- adr++;
- }
- }
-
- static void resterm()
- {
- static unsigned far *env;
- closefiles();
- setvect(TIMER,oldtimer);
- setvect(INT28,old28);
- setvect(KEYBD,oldkb);
- setvect(DISK,olddisk);
- setvect(VIDEO,oldvideo);
- FP_SEG(env)=_psp;
- FP_OFF(env)=0x2c;
- freemem(*env);
- freemem(_psp);
- }
-
- void terminate()
- {
- tmpvect=newvideo;
- if (getvect(VIDEO)==tmpvect) {
- tmpvect=newdisk;
- if (getvect(DISK)==tmpvect) {
- tmpvect=newkb;
- if (getvect(KEYBD)==tmpvect) {
- tmpvect=new28;
- if (getvect(INT28)==tmpvect) {
- tmpvect=newtimer;
- if (getvect(TIMER)==newtimer){
- resterm();
- return;
- }
- }
- }
- }
- }
- terminating=0;
- suspending=1;
- }
-
-