[comp.lang.c] Need expertise with Interrupt handlers + TSR coding

dipto@umbc3.UMD.EDU (Dipto Chakravarty) (04/04/88)

From dipto Thu Mar 31 21:23:10 EST 1988

In article <5132@sigi.Colorado.EDU> murillo@boulder.Colorado (Rodrigo) writes:
>
>Does anybody have experience in writing TSRs for DOS in C.  I would like
>to get a hold of some C source that would show the basic principles of
>writing a TSR ...

	Recently, a couple of books have been published on this topic.
	If I remember them right, then they are the following :-

	(1)  MEMORY RESIDENT PROGRAMMING ON THE IBM PC
	     Author: Wadlow; Publisher: Addison Wesley

	(2)  WRITING MEMORY RESIDENT PROGRAMS IN TURBO `C'    {Check thru the}
	     Author: (don't remember ... sorry)               {title citation}
                                                              {in bookstores.}

	The first book is a superb introduction to RAM resident programming
	techniques. The second text talks about the Interrupt Vector Table 
	manipulation, and provides some in-built utilities (pre-written in 
	Assembly, I think) with the help of which one can alter the IVT of
	the PC's memory. 

		The most fundamental principle of writing these fabulous 
	RAM resident programs is to understand how to alter the Interrupt
	Vector Table. 

>   ... how to trap the keyboard interrupt to watch for hot keys.

	The software keyboard interrupt (I think it is 14H) works at the 
	DOS level. One should be able to play with this and hack this 
	code to work by trapping the 14H signal with the int86() function.
	Here is a code fragment to trap an interrupt:
	-----                                        { I used the Microsoft }
	#include <signal.h>                          { `C' functions here   }
	#include <dos.h>                             { The calls in Turbo C }
	#include <stdio.h>                           { differ slightly.     }
	#include <process.h>                         { Refer Turbo C manual.}
	#define CNTL_C 0x23
					/* the e.g. here traps interrupt  */
	int int_handler(int);		/* number 0x23; the values in the */
					/* regs struct may/may not matter */
	union REGS regs;
	.
	.
	signal(SIGINT, int_handler);
	.
	.
	int86(CNTL_C, &regs, &regs);

	Now, you may want to think twice before messing with hardware
	keyboard interrupt. The value is interrupt number 09H, I think. 
	This means that you will begin hacking around at the ROMBIOS
	level. This, definitely is a cool way to trap the keyboard signal
	but be aware of the facts before this technique is attempted. I
	once crippled my keyboard real good! :-) 

	INCORRECT interrupt trapping techniques at the ROMBIOS level 
	(specially for the keyboard) is really as messy as getting into
	a Lisp interpreter, doing a ``(defun exit (.....))'' incorrectly,
	.... and, then attempting to exit out of Lisp in normal ``(EXIT)''
	way! :-)

	I strongly recommend that program testing should be done using an
	innocent interrupt like the "timer tick". 
							Good Luck!


	P.S: I encountered some problems (bugs?) with Turbo `C' at the 
	     time of program development. Microsoft, in my view is safe
	     to use. At the interrupt driver level, when one is screwing 
	     around with the hardware interrupts and ROMBIOS the compiler
	     + the linker + the library ought to be absolutely bug-free.

	     Enjoy!


	-- 
BITNET : dipto@umbc.BITNET    ------\
ARPANET: dipto@umbc3.UMD.EDU  -------> In-real-life: Dipto Chakravarty
USMAIL : CMSC, UMBC,Md 21228  ------/


-- 
BITNET : dipto@umbc.BITNET    ------\
ARPANET: dipto@umbc3.UMD.EDU  -------> In-real-life: Dipto Chakravarty
USMAIL : CMSC, UMBC,Md 21228  ------/

chris@mimsy.UUCP (Chris Torek) (04/04/88)

[I deleted soc.culture.indian from the Newsgroups line.]

In article <926@umbc3.UMD.EDU> dipto@umbc3.UMD.EDU (Dipto Chakravarty) writes:
>WRITING MEMORY RESIDENT PROGRAMS IN TURBO `C' ... talks about the
>Interrupt Vector Table manipulation, and provides some in-built
>utilities (pre-written in Assembly, I think) with the help of which
>one can alter the IVT of the PC's memory. 

Actually, you can do it directly in C (as long as you have large
model or are willing to do segment/offset goo by hand).  You will
need an assembly language stub (or a special compiler keyword) to
call the C code from the interrupt handler, and you will need to
be able to disable and reenable interrupts, but the basic idea is
this:

	/* should be (void (**)()) but many IBM PC C compilers break */
	#define VECTOR(x) (((int (**)())0)[x])

	int (*oldkeyintr)();
	int mykeyintr();
	...
		disable_interrupts();
		oldkeyintr = VECTOR(9);
		VECTOR(9) = mykeyintr;
		enable_interrupts();

If you are not compiling with large model, you will need `far's
sprinkled in liberally.  The `mykeyintr' routine has to begin by saving
ALL the registers that your runtime system uses.  The usual scheme is a
two-level one, with mykeyintr being an assembly stub that calls
dokeyintr().

A cleaner way to define the vector table might be something
like this:

	typedef int (far *vector_t)();	/* should be (void (*)()) */
		/* not sure if the `far' is properly placed */
	struct vector_table {
		vector_t	?;		/* 0: whatever vec 0 is for */
		...	/* 1 through 8 */
		vector_t	keyboard;	/* 9: keyboard interrupt */
		...	/* 10 through 128 or 256 or whatever */
	};
	#define IBM_PC_VECTORS ((struct vector_table far *)0)

		...
		oldkeyintr = IBM_PC_VECTORS->keyboard;
		IBM_PC_VECTORS->keyboard = mykeyintr;

(I have not done any of this myself, but I know it can work, because
I looked at some of the assignments given to CMSC412 (the O/S class)
students here and saw some of the most horrible code given as examples
to get the students started.  After one student had typed in all the
cruft and made it work, I gave him this to simplify everything, and
it still worked.  Great grief, we spend three years making CS undergrads
write clear code, and then we put them in 412 and hand out examples
that are the antithesis of everything we have said so far.  Now if
412 were a software engineering course, I could understand....)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris