TSR's with TC

Frank Whaley few at quad1.quad.com
Wed Aug 30 09:56:25 AEST 1989


In article <1098 at koko.CSUStan.EDU> jb at koko.UUCP (John Birchfield) writes:
>In article <3723 at ncsuvx.ncsu.edu>, sherman at csclea.ncsu.edu (Chris Sherman) writes:
>> _chain_intr, which is usually used in an interrupt handler, accepts the
>> address of another interrupt handler, and jumps (not calls) over to it.
>> It is as if the first handler was never called.
>> 
>Turbo C allows writing interrupt handlers directly in C using
>pretty much the same mechanism as Microsoft.  The following C
>program is provided as a very succinct example.

<< succinct example deleted >>

While Turbo C does provide excellent interrupt handling support, the
_chain_intr() function provides one capability not available from the
normal Turbo C facilities:  The ability to preserve original register
contents when passing control to a subsequent (or original, depending
on your point of view) interrupt handler.

Note that the correct synopsis of an interrupt handling function is:
	void interrupt handler(bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,fl)
		int bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,fl;
as the register contents are pushed upon entry, and popped upon exit.
While within the handler, DS contains the current DGROUP value and
other registers change as necessary.  If the original interrupt handler
is called from within our handler, it is unlikely that the correct
register values will be passed.

For many interrupt service routines this is inconsequential, as they
do not care what the previous state of the machine was -- for example,
serial port interrupt handlers are responding to a hardware interrupt and
must preserve and restore the machine state at the time of the interrupt.
However, when software interrupts are used for communication between
processes (I use the term loosely :-), the contents of the registers is
very important.  The DOS Services interrupt (0x21) and the Multiplex
interrupt (0x2f) are two examples that expect parameters to be provided
in registers which are modified by the Turbo C interrupt service code.

Fortunately (this is the part you were waiting for) the _chain_intr()
function is not dificult to implement.  Attached is a "dirty" version
(values are popped into code-segment variables) which is missing the
necessary segment/group descriptions, but which demonstrates the
principles of chaining interrupts.

I should note that, if desired, interrupt handlers can examine or modify
the input register values.  For example, to count all "open file" calls
within a program:
	Assuming:
		...
		long opencount = 0;
		void interrupt (*old21)();
		...
		old21 = getvect(0x21);
		setvect(0x21, my21);
		...

	void interrupt my21(bp,di,si,ds,es,dx,cx,bx,ax)
		int bp,di,si,ds,es,dx,cx,bx,ax;
	{
		if ( (ax & 0xff00) == 0x3d00 )
			opencount++;

		_chain_intr(old21);
	}
-----
;-----------------------------------------------------------------------|
;	_chain_intr -- chain interrupt					|
;									|
;	SYNOPSIS							|
;		void _chain_intr(target)				|
;			void interrupt (*target)();			|
;									|
;	DESCRIPTION							|
;		Chain to another interrupt handler, passing original	|
;		 (or possibly modified) register values.		|
;									|
;	RETURNS								|
;		This function returns to the original source of the	|
;		 interrupt.						|
;									|
;-----------------------------------------------------------------------|

	Public	__chain_intr
__chain_intr	Proc	Near

	POP	AX			;  clear return addr
;;;;;;;	POP	AX			;  another for large code models

	POP	Word Ptr CS:target	;  get target addr into jump
	POP	Word Ptr CS:target + 2

	POP	BP			;  restore saved registers
	POP	DI
	POP	SI
	POP	DS
	POP	ES
	POP	DX
	POP	CX
	POP	BX
	POP	AX

	;  we leave original IP, CS and flags on stack

	DB	0EAH			;  JMPF
target	DD	0			;  target address

__chain_intr	EndP
-----
-- 
Frank Whaley
Senior Development Engineer
Quadratron Systems Incorporated
few at quad1.quad.com
uunet!ccicpg!quad1!few

Water separates the people of the world;
Wine unites them.



More information about the Comp.lang.c mailing list