home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / tsr / mixtsr / resident.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-06-16  |  6.8 KB  |  249 lines

  1. /* ----- resident.c ----- */
  2.  
  3. #include <dos.h>
  4. #include <conio.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <malloc.h>
  8. #include "tsr.h"
  9.  
  10. static union REGS rg;
  11. static struct SREGS seg;
  12.  
  13. /* --- vectors --- */
  14. #define KEYBD           9
  15. #define TIMER           0x1c
  16. #define DISK            0x13
  17. #define VIDEO           0x10
  18. #define ZERODIV         0
  19. #define INT28           0x28
  20. #define CRIT            0x24
  21. #define CTRLC           0x23
  22. #define CTRLBRK         0x1b
  23.  
  24. /* --- interrupt vector chains --- */
  25. static void interrupt (far *tmpvect)(void);
  26. static void interrupt (far *oldbreak)(void);
  27. static void interrupt (far *oldctrlc)(void);
  28.  void interrupt (far *oldtimer)(void);
  29.  void interrupt (far *old28)(void);
  30.  void interrupt (far *oldkb)(void);
  31.  void interrupt (far *olddisk)(void);
  32.  void interrupt (far *oldvideo)(void);
  33. static void interrupt (far *oldcrit)(void);
  34. /* --- ISRs for the TSR --- */
  35. extern void interrupt newtimer(void);
  36. extern void interrupt new28(void);
  37. extern void interrupt newkb(void);
  38. extern void interrupt newdisk(void);
  39. extern void interrupt newvideo(void);
  40. extern void interrupt newcrit();
  41. extern void interrupt newbreak();
  42. /* --- global variables --- */
  43. static unsigned sizeprogram;
  44. static unsigned dosseg;
  45. char far *dosbusy;
  46. static char far *mydta;
  47. unsigned myss;
  48. unsigned stack;
  49. static unsigned intpsp;
  50. static unsigned far *psps[5];
  51. static int pspctr;
  52. static int resoff;
  53. extern unsigned running;
  54. int popflg;
  55. int suspending=0;
  56. int terminating=0;
  57. int diskflag=0;
  58. int videoflag=0;
  59.  
  60. /* --- local prototypes --- */
  61. static void resterm(void);
  62. static void pspaddr(void);
  63. void dores(void);
  64. void popup_tsr(void);
  65. /* --- establish and declare residency --- */
  66. void resinit()
  67. {       int pp,xtmp;
  68.         suspending=0;terminating=0;running=0;
  69.         segread(&seg);
  70.         myss = seg.ss;
  71.         stack = getsp();
  72.         /* --- get address of DOS busy flag --- */
  73.         rg.h.ah = 0x34;
  74.         intdosx(&rg,&rg,&seg);
  75.         dosseg = seg.es;
  76.         FP_SEG(dosbusy)=seg.es;
  77.         FP_OFF(dosbusy)=rg.x.bx;
  78.         /* --- get address of resident program's dta --- */
  79.         mydta = getdta();
  80.         pspaddr();
  81.         /* --- get original interrupt vectors --- */
  82.         oldtimer = getvect(TIMER);
  83.         old28 = getvect(INT28);
  84.         oldkb = getvect(KEYBD);
  85.         olddisk = getvect(DISK);
  86.         oldvideo = getvect(VIDEO);
  87.  
  88.         /* --- attach vectors to resident program --- */
  89.         tmpvect=newtimer;    setvect(TIMER,tmpvect);
  90.         tmpvect=new28;       setvect(INT28,tmpvect);
  91.         tmpvect=newkb;       setvect(KEYBD,tmpvect);
  92.         tmpvect=newdisk;     setvect(DISK, tmpvect);
  93.         tmpvect=newvideo;    setvect(VIDEO,tmpvect);
  94.  
  95.         /* --- compute program size --- */
  96.         sizeprogram = farsetsize(0)+50;
  97.         /* --- terminate and stay resident --- */
  98.         keep(0,sizeprogram);
  99. }
  100.  
  101. void resident_psp()
  102. {
  103.         int pp;
  104.         intpsp = *psps[0];
  105.         for (pp=0; pp<pspctr; pp++)
  106.                 *psps[pp]=_psp;
  107. }
  108.  
  109. void interrupted_psp()
  110. {
  111.         int pp;
  112.         for (pp=0; pp<pspctr; pp++)
  113.                 *psps[pp]=intpsp;
  114. }
  115.  
  116. void popup_tsr()
  117. {
  118.         static char far *intdta;
  119.         static unsigned intsp;
  120.         static unsigned intss;
  121.         static unsigned ctrl_break;
  122.  
  123.         disable();
  124.         oldcrit=getvect(CRIT);
  125.         oldbreak=getvect(CTRLBRK);
  126.         oldctrlc=getvect(CTRLC);
  127.         tmpvect=newcrit; setvect(CRIT,tmpvect);
  128.         tmpvect=newbreak; setvect(CTRLBRK,tmpvect);
  129.         setvect(CTRLC,tmpvect);
  130.         ctrl_break=getcbrk();
  131.         setcbrk(0);
  132.         intdta=getdta();
  133.         setdta(mydta);
  134.         resident_psp();
  135.         enable();
  136.         popup();
  137.         disable();
  138.         interrupted_psp();
  139.         setdta(intdta);
  140.         setvect(CRIT,oldcrit);
  141.         setvect(CTRLBRK,oldbreak);
  142.         setvect(CTRLC,oldctrlc);
  143.         setcbrk(ctrl_break);
  144.         enable();
  145.  
  146.         if (terminating) terminate();
  147. }
  148.  
  149. unsigned resident(char *signature)
  150. {
  151.         char *sg;
  152.         unsigned df,mcbseg,blkseg;
  153.  
  154.         segread(&seg);
  155.         df=seg.ds-_psp;
  156.         rg.h.ah = 0x52;
  157.         intdosx(&rg,&rg,&seg);
  158.         mcbseg=peek(seg.es,rg.x.bx-2);
  159.         while (peekb(mcbseg,0)==0x4d) {
  160.            blkseg=peek(mcbseg,1);
  161.            if (peek(blkseg,0)==0x20cd) {
  162.               if (blkseg==_psp)
  163.                  break;
  164.               for (sg=signature;*sg;sg++)
  165.                  if (*sg!=peekb(blkseg+df,(unsigned)sg))
  166.                     break;
  167.               if (!*sg) {
  168.                  if (peek(blkseg+df,(unsigned)&suspending)) {
  169.                     poke(blkseg+df,(unsigned)&suspending,0);
  170.                     return 2;
  171.                  }
  172.                  return 1;
  173.               }
  174.            }
  175.            mcbseg+=peek(mcbseg,3)+1;
  176.         }
  177.         return 0;
  178. }
  179.  
  180. static void pspaddr()
  181. {
  182.         unsigned adr=0;
  183.         unsigned enddos;
  184.         static unsigned far *ed, far *ps;
  185.         adr=0;
  186.         rg.h.ah=0x52;
  187.         intdosx(&rg,&rg,&seg);
  188.         FP_SEG(ed)=seg.es;
  189.         FP_OFF(ed)=rg.x.bx-2;
  190.  
  191.         enddos=*ed;
  192.         while(pspctr<5 &&
  193.                     (unsigned)((dosseg<<4)+adr)<(enddos<<4)){
  194.                 FP_SEG(ps)=dosseg;
  195.                 FP_OFF(ps)=adr;
  196.                 if (*ps==_psp){
  197.                         rg.h.ah = 0x50;
  198.                         rg.x.bx = _psp+1;
  199.                         intdos(&rg,&rg);
  200.                         if (*ps==_psp+1)
  201.                                 psps[pspctr++]=ps;
  202.                         rg.h.ah = 0x50;
  203.                         rg.x.bx = _psp;
  204.                         intdos(&rg,&rg);
  205.                 }
  206.                 adr++;
  207.         }
  208. }
  209.  
  210. static void resterm()
  211. {
  212.         static unsigned far *env;
  213.         closefiles();
  214.         setvect(TIMER,oldtimer);
  215.         setvect(INT28,old28);
  216.         setvect(KEYBD,oldkb);
  217.         setvect(DISK,olddisk);
  218.         setvect(VIDEO,oldvideo);
  219.         FP_SEG(env)=_psp;
  220.         FP_OFF(env)=0x2c;
  221.         freemem(*env);
  222.         freemem(_psp);
  223. }
  224.  
  225. void terminate()
  226. {
  227.         tmpvect=newvideo;
  228.         if (getvect(VIDEO)==tmpvect) {
  229.                 tmpvect=newdisk;
  230.                 if (getvect(DISK)==tmpvect) {
  231.                         tmpvect=newkb;
  232.                         if (getvect(KEYBD)==tmpvect) {
  233.                                 tmpvect=new28;
  234.                                 if (getvect(INT28)==tmpvect) {
  235.                                         tmpvect=newtimer;
  236.                                         if (getvect(TIMER)==newtimer){
  237.                                                 resterm();
  238.                                                 return;
  239.                                         }
  240.                                 }
  241.                         }
  242.                 }
  243.         }
  244.         terminating=0;
  245.         suspending=1;
  246. }
  247.  
  248.  
  249.