home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_02_02 / 2n02025a < prev    next >
Text File  |  1990-12-17  |  5KB  |  156 lines

  1. #include <stdio.h>
  2. #include <dos.h>
  3. #include "defs.h"
  4.  
  5. extern int DOS_Extender;
  6.  
  7. #ifdef __HIGHC__
  8. typedef _far void (*ISRH)(void);
  9. #else
  10. typedef void (_far *ISRH)(void);
  11. #endif
  12.  
  13. typedef struct isr_struct
  14. {
  15.    ULONG realvector;
  16.    ISRH  handler;
  17. } ISR;
  18.  
  19. ISR OldTimer, NewTimer, OldInt90, NewInt90;
  20.  
  21. void HookTimer(void);
  22. void UnHookTimer(void);
  23. void GetISR(USHORT intnum, ISR *OldISR);
  24. void SetISR(USHORT intnum, ISR *NewISR, UINT PharlapStrategy);
  25. #if defined(_I386) || defined(_I486) || defined(__386__)
  26.    extern void NewTimerISR(void);
  27. #else
  28.    extern void _far NewTimerISR(void);
  29. #endif
  30.  
  31. #define SET_ISR           0x2500
  32. #define GET_ISR           0x3500
  33. #define GET_PROT_ISRH     0x2502
  34. #define GET_REAL_VECTOR   0x2503
  35. #define SET_PROT_ISRH     0x2504
  36. #define SET_REAL_VECTOR   0x2505
  37. #define SET_PROT_ALLWAYS  0x2506
  38. #define SET_BOTH          0x2507
  39. #define GET_HARD_IRQ_BASE 0x250C
  40.  
  41. void HookTimer(void)
  42. {
  43.    GetISR(0x90, &OldInt90);
  44.    GetISR(0x08, &OldTimer);
  45.    if (DOS_Extender == PHARLAP_386)
  46.       NewInt90.realvector = OldTimer.realvector;
  47.    else
  48.       NewInt90.handler    = OldTimer.handler;
  49.    NewTimer.handler = (ISRH)NewTimerISR;
  50.    SetISR(0x90, &NewInt90, SET_REAL_VECTOR);
  51.    SetISR(0x08, &NewTimer, SET_PROT_ALLWAYS);
  52. }
  53.  
  54. void UnHookTimer(void)
  55. {
  56.    SetISR(0x08, &OldTimer, SET_BOTH);
  57.    SetISR(0x90, &OldInt90, SET_REAL_VECTOR);
  58. }
  59.  
  60. void GetISR(USHORT intnum, ISR *OldISR)
  61. {
  62.    union REGS regs;
  63.    struct SREGS segregs;
  64.  
  65.    if (DOS_Extender == PHARLAP_386)
  66.       {
  67.       if ( intnum > 0x07 && intnum < 0x10 ) /* Hardware IRQs are remapped */
  68.          {
  69.          /*-------------------------------------------------------------*/
  70.          /*  Get the interrupt vector base for IRQ0 through IRQ7        */
  71.          /*  DOS maps these to interrupts 0x08 through 0x0F            */
  72.          /*-------------------------------------------------------------*/
  73.          regs.x.AX = GET_HARD_IRQ_BASE;
  74.          int86(0x21, ®s, ®s);  /*  get IRQ0-IRQ7 base vector      */
  75.          intnum += regs.h.al - 0x08; /*  adjust the target intnum       */
  76.          }
  77.       regs.x.CX = intnum;              /*specify get interrupt vector   */
  78.       regs.x.AX = GET_PROT_ISRH;       /*specify protected mode handler */
  79.       segread(&segregs);
  80.       int86x(0x21, ®s, ®s, &segregs); /*get the prot handler      */
  81.       FP_MAK(OldISR->handler, regs.x.BX, segregs.es);
  82.       regs.x.AX = GET_REAL_VECTOR;          /*specify real mode vector  */
  83.       segread(&segregs);
  84.       int86x(0x21, ®s, ®s, &segregs); /*get the real vector       */
  85.       OldISR->realvector = (ULONG) regs.x.BX;
  86.       }
  87.    else  /* REAL MODE or an ERGO extender */
  88.       {
  89.       regs.x.AX = GET_ISR | intnum;
  90.       segread(&segregs);
  91.       int86x(0x21, ®s, ®s, &segregs);
  92.       FP_MAK(OldISR->handler, regs.x.BX, segregs.es);
  93.       }
  94. }
  95.  
  96. void SetISR(USHORT intnum, ISR *NewISR, UINT PharlapStrategy)
  97. {
  98.    union REGS regs;
  99.    struct SREGS segregs;
  100.  
  101.    segread(&segregs);
  102. #if defined(_I386) || defined(_I486) || defined(__386__)
  103.    if (DOS_Extender == PHARLAP_386)
  104.       {
  105.       if ( intnum < 0x10 && intnum > 0x07 ) /* Hardware IRQs are remapped */
  106.          {
  107.          /*-------------------------------------------------------------*/
  108.          /*  Get the interrupt vector base for IRQ0 through IRQ7        */
  109.          /*-------------------------------------------------------------*/
  110.          regs.x.AX = GET_HARD_IRQ_BASE;
  111.          int86(0x21, ®s, ®s);  /*  get the base interrupt vector  */
  112.          intnum += regs.h.al - 0x08; /*  adjust the target intnum       */
  113.          }
  114.       regs.x.CX  = intnum;
  115.       switch (PharlapStrategy)
  116.          {
  117.          case SET_PROT_ALLWAYS:
  118.               regs.x.AX  = SET_PROT_ALLWAYS;
  119.               regs.x.DX  = FP_OFF(NewISR->handler);/*extract ISRH offset */
  120.               segregs.ds = FP_SEG(NewISR->handler);/*extract ISRH segment*/
  121.               break;
  122.          case SET_PROT_ISRH:
  123.               regs.x.AX  = SET_PROT_ISRH;
  124.               regs.x.DX  = FP_OFF(NewISR->handler);/*extract ISRH offset */
  125.               segregs.ds = FP_SEG(NewISR->handler);/*extract ISRH segment*/
  126.               break;
  127.          case SET_REAL_VECTOR:
  128.               regs.x.AX = SET_REAL_VECTOR; /*specify interrupt vector replacement*/
  129.               regs.x.BX = NewISR->realvector;
  130.               break;
  131.          case SET_BOTH:
  132.               regs.x.AX  = SET_BOTH;
  133.               regs.x.BX  = NewISR->realvector;
  134.               regs.x.DX  = FP_OFF(NewISR->handler);/*extract ISRH offset */
  135.               segregs.ds = FP_SEG(NewISR->handler);/*extract ISRH segment*/
  136.               break;
  137.          }
  138.       }
  139.    else    
  140. #endif
  141.       {    /* Real Mode or ERGO Extenders */
  142.       regs.x.AX  = SET_ISR | intnum; /*specify interrupt handler*/
  143.       regs.x.DX  = FP_OFF(NewISR->handler);/*extract isr offset */
  144.       segregs.ds = FP_SEG(NewISR->handler);/*extract isr segment*/
  145.       }
  146.    int86x(0x21, ®s, ®s, &segregs);
  147. }
  148.  
  149. #ifdef __HIGHC__
  150. #pragma Alias(NewTimerISR, "_NewTimerISR");
  151. #endif
  152. #ifdef __WATCOMC__
  153. #pragma aux (OUR_C) NewTimerISR;
  154. #endif
  155.  
  156.