home *** CD-ROM | disk | FTP | other *** search
- /* ------------------------------------------------------ */
- /* NEWISR.C */
- /* Chaining to and Returning Values in Registers */
- /* (c) 1991 Borland International */
- /* All rights reserved. */
- /* ------------------------------------------------------ */
- /* veröffentlicht in DOS toolbox 3'92 */
- /* ------------------------------------------------------ */
-
- #include <dos.h>
- #include <stdio.h>
-
- #define INT_NUMBER 0x21 // Trap Interrupt 21H (!)
-
- // A user-defined type for use with getvect() & setvect()
- typedef void interrupt far (*intvect)(...);
-
- intvect OldISR; // For storing address of old vector
-
- /* ------------------------------------------------------ */
-
- void interrupt NewISR(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs,
- unsigned flags) {
-
- // We know flags, cs, ip, cx... aren't used!
- #pragma warn -par
-
- // Insert your ISR Code Here...
- // .
- // .
- // If (I_am_Handling_The_Interrupt)
- // {
- // Do_Whatever_I_need_to_and();
- // return;
- // }
-
- /* The following Code indirectly chains to the Old Vector
- by:
- 1. Putting the Address of the Old ISR on the Stack
- 2. Restoring the Value of Registers Pushed on the Stack
- 3. Executing a Far Return which translates into a jump
- to the address on the Stack
- (i.e. the Old Vector's Address)
- */
-
- _BX = bx; // Restore value of BX register
- _CX = ax; // Save value of AX in CX
- ax = FP_SEG((void far *)OldISR);
- // Place address of OldISR
- bx = FP_OFF((void far *)OldISR); // on the stack
- _AX = _CX ; // Restore value of AX register
- __emit__(0x5D); // asm POP BP -> restore BP
- __emit__(0x5F); // asm POP DI -> restore DI
- __emit__(0x5E); // asm POP SI -> restore SI
- __emit__(0x1F); // asm POP DS -> restore DS
- __emit__(0x07); // asm POP ES -> restore ES
- __emit__(0x5A); // asm POP DX -> restore DX
- __emit__(0x59); // asm POP CX -> restore CX
- __emit__(0xCB); // asm RETF -> indirect far jump
- // to OldISR
-
- /* NOTE: Any code of the ISR beyond this point will not be
- executed. The above does not *CALL* the old ISR
- but rather *JUMPS* to it. When the OldISR executes
- its IRET, control will resume at the original
- location prior to the INTERRUPTion!!
- */
- #pragma warn .par
- // restore state of 'parms not used' warning
- } // end of newISR()
-
- /* ------------------------------------------------------ */
-
- int main(void) {
- unsigned CountDown = 999;
-
- OldISR = (intvect) getvect(INT_NUMBER);
- setvect(INT_NUMBER, (intvect)NewISR);
-
- while(CountDown--)
- printf("This is the countdown: [%03d]\r", CountDown);
- printf("\nThis is the end of the countdown !\n");
-
- setvect(INT_NUMBER, OldISR);
- return 0;
- }
- /* ------------------------------------------------------ */
- /* Ende von NEWISR.C */
-
-