🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.os.msdos.programmer
Article #5945

Re: Chaining interrupt handlers in Turbo C

#5945
From: Frank Whaley
Date: Wed, 24 Apr 1991 20:47
125 lines
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!few
References: <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