home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / dtx9203 / borhot / newisr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-25  |  3.3 KB  |  93 lines

  1. /* ------------------------------------------------------ */
  2. /*                      NEWISR.C                          */
  3. /*      Chaining to and Returning Values in Registers     */
  4. /*              (c) 1991 Borland International            */
  5. /*                   All rights reserved.                 */
  6. /* ------------------------------------------------------ */
  7. /*            veröffentlicht in DOS toolbox 3'92          */
  8. /* ------------------------------------------------------ */
  9.  
  10. #include <dos.h>
  11. #include <stdio.h>
  12.  
  13. #define INT_NUMBER 0x21   // Trap Interrupt 21H (!)
  14.  
  15. // A user-defined type for use with getvect() & setvect()
  16. typedef void interrupt far (*intvect)(...);
  17.  
  18. intvect OldISR;        // For storing address of old vector
  19.  
  20. /* ------------------------------------------------------ */
  21.  
  22. void interrupt NewISR(unsigned bp, unsigned di, unsigned si,
  23.                       unsigned ds, unsigned es, unsigned dx,
  24.                       unsigned cx, unsigned bx, unsigned ax,
  25.                       unsigned ip, unsigned cs,
  26.                       unsigned flags) {
  27.  
  28.              // We know flags, cs, ip, cx... aren't used!
  29. #pragma warn -par
  30.  
  31.   // Insert your ISR Code Here...
  32.   // .
  33.   // .
  34.   // If (I_am_Handling_The_Interrupt)
  35.   // {
  36.   //    Do_Whatever_I_need_to_and();
  37.   //    return;
  38.   // }
  39.  
  40. /* The following Code indirectly chains to the Old Vector
  41.    by:
  42.    1.  Putting the Address of the Old ISR on the Stack
  43.    2.  Restoring the Value of Registers Pushed on the Stack
  44.    3.  Executing a Far Return which translates into a jump
  45.        to the address on the Stack
  46.        (i.e. the Old Vector's Address)
  47. */
  48.  
  49.   _BX  =   bx;           // Restore value of BX register
  50.   _CX  =   ax;           // Save value of AX in CX
  51.    ax  =   FP_SEG((void far *)OldISR);
  52.                          // Place address of OldISR
  53.    bx  =   FP_OFF((void far *)OldISR);  // on the stack
  54.   _AX  =  _CX  ;         // Restore value of AX register
  55.   __emit__(0x5D);        // asm  POP BP -> restore BP
  56.   __emit__(0x5F);        // asm  POP DI -> restore DI
  57.   __emit__(0x5E);        // asm  POP SI -> restore SI
  58.   __emit__(0x1F);        // asm  POP DS -> restore DS
  59.   __emit__(0x07);        // asm  POP ES -> restore ES
  60.   __emit__(0x5A);        // asm  POP DX -> restore DX
  61.   __emit__(0x59);        // asm  POP CX -> restore CX
  62.   __emit__(0xCB);        // asm  RETF   -> indirect far jump
  63.                          // to OldISR
  64.  
  65. /* NOTE: Any code of the ISR beyond this point will not be
  66.          executed. The above does not *CALL* the old ISR
  67.          but rather *JUMPS* to it. When the OldISR executes
  68.          its IRET, control will resume at the original
  69.          location prior to the INTERRUPTion!!
  70. */
  71. #pragma warn .par
  72.               // restore state of 'parms not used' warning
  73. }  // end of newISR()
  74.  
  75. /* ------------------------------------------------------ */
  76.  
  77. int main(void) {
  78.   unsigned CountDown = 999;
  79.  
  80.   OldISR = (intvect) getvect(INT_NUMBER);
  81.   setvect(INT_NUMBER, (intvect)NewISR);
  82.  
  83.   while(CountDown--)
  84.     printf("This is the countdown:  [%03d]\r", CountDown);
  85.   printf("\nThis is the end of the countdown !\n");
  86.  
  87.   setvect(INT_NUMBER, OldISR);
  88.   return 0;
  89. }
  90. /* ------------------------------------------------------ */
  91. /*                Ende von NEWISR.C                       */
  92.  
  93.