Article View: comp.os.msdos.programmer
Article #5945Re: Chaining interrupt handlers in Turbo C
From: Frank Whaley
Date: Wed, 24 Apr 1991 20:47
Date: Wed, 24 Apr 1991 20:47
125 lines
3449 bytes
3449 bytes
In article <1991Apr17.214023.22334@bilver.uucp> dandrews@bilver.uucp (Dave Andrews) writes:
> * A week or so ago, someone asked:
> * "how can I chain to the next interrupt handler in Turbo C?"
And Dave responded with a very interesting version of chain_intr(). I
never would have thought of his method. Unfortunately there are a
couple of problems.
Interrupts are improperly chained if the interrupt handler function
has local variables. Turbo C (2.0, I can't speak for TC++ or BC++)
only sets the BP register when the interrupt function uses local
variables, so it cannot be used in all cases to unroll the stack.
The best way to write handlers with local data:
void interrupt handler()
{
if ( somethingWeDo )
doIt();
else
chain_intr(original);
}
Dave's macro can only be used before a return, either stated or
implied. So:
if ( notForMe )
{
chain_intr(original);
return; /* required */
}
...
I've attached a new version of what I use. It still suffers from not
working in handlers with local variables, but it can be called anywhere
and is implemented as a function.
PAGE 60, 132
TITLE chain 24-Apr-91 Chain interrupt |
;-----------------------------------------------------------------------|
; |
; Turbo C Library -- ChainIntr |
; Chain interrupt |
; |
;-----------------------------------------------------------------------|
; sizes
LCODE = 0
IFDEF __MEDIUM__
LCODE = 1
ENDIF
IFDEF __LARGE__
LCODE = 1
ENDIF
IFDEF __HUGE__
LCODE = 1
ENDIF
; Code Segment
IF LCODE
CHAIN_TEXT Segment Byte Public 'CODE'
Assume CS:CHAIN_TEXT
ELSE
_TEXT Segment Byte Public 'CODE'
Assume CS:_TEXT
ENDIF
PAGE
;-----------------------------------------------------------------------|
; Chain interrupt |
; |
; SYNOPSIS |
; void ChainIntr(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 _ChainIntr
IF LCODE
_ChainIntr Proc Far
ELSE
_ChainIntr Proc Near
ENDIF
POP AX ; clear return addr
IF LCODE
POP AX
ENDIF
POP BX ; get target addr
POP AX
MOV BP,SP ; store target addr
XCHG AX,[BP + 16]
XCHG BX,[BP + 14]
POP BP ; restore saved registers
POP DI
POP SI
POP DS
POP ES
POP DX
POP CX
RETF ; return to target
_ChainIntr EndP
IF LCODE
CHAIN_TEXT EndS
ELSE
_TEXT EndS
ENDIF
END ; of chain.asm
--
Frank Whaley
Software Engineer
Gupta Technologies
few@gupta.com
Technical Details
Message-ID:
<1991Apr24.204727.27737@gupta.portal.com>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rpi!dali.cs.montana.edu!caen!sdd.hp.com!mips!apple!portal!gupta!fewReferences:
<1991Apr17.214023.22334@bilver.uucp>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!rpi!dali.cs.montana.edu!caen!sdd.hp.com!mips!apple!portal!gupta!few From: few@gupta.portal.com (Frank Whaley) Newsgroups: comp.os.msdos.programmer Subject: Re: Chaining interrupt handlers in Turbo C Keywords: TC TURBOC interrupt _chain_intr Message-ID: <1991Apr24.204727.27737@gupta.portal.com> Date: 24 Apr 91 20:47:27 GMT References: <1991Apr17.214023.22334@bilver.uucp> Organization: Gupta Technologies Inc Lines: 125