Metropoli BBS
VIEWER: intmain.c MODE: TEXT (ASCII)
/****************************************************************************
*		INTMAIN.C -- main routine for a C interrupt handler
*
*	This source file demonstrates how to make a routine resident. Notice
*	that it calls int_init(), the interrupt initializtion function. 
*	Another routine, inttime(), is the actual interrupt handler.
*
* ---------------------------------------------------------------------------
*		How to Create an Interrupt-Driven C Routine
*
*	The theory behind interrupt driven  code is easy to understand. The
*	first thing to remember is that when an interrupt occurs, YOU CAN NOT 
*	BE SURE OF WHAT IS IN THE MACHINE REGISTERS. This is critical when
*	hooking into hardware interrupts. Therefore, you must recreate your
*	program environment every time your interrupt routine gets called.
*
*	Lattice C code relies on certain things to always be available.
*	The stack, heap, and static areas must ALWAYS be availble to the C
*	code. For this reason, you cannot just keep a C program resident and
*	expect it work. This source, along with CINT.ASM, show you the hows
*	and whys of setting up a C environment.
*
*	Step 1: Write your actual interrupt handler. It can do almost 
*	anything, depending on what type of interrupt you are hooking into.
*	(Example: A routine that hooks into interrupt 24H MUST NOT call any
*	DOS services except for services 01 - 12H. Doing so will destory the
*	DOS stack.)
*	When you compile this source, do so in the small model. DO NOT use
*	the STD I/O routines (printf, scanf, etc.). Actually, you can try,
*	but then you should disregard Step 2.
*
*	Step 2: Recompile _MAIN.C in the S Model with the option -dTINY.
*	What this does is create a new version of _main that does not open
*	any of the STD I/O ports. (STDIN, STDOUT, STDERR, and in 3.00 STDPRT,
*	and STDAUX.) Doing this will cut the size of the executable by at
*	least 5K.
*
*	Step 3: Modify CINT.ASM to suit your needs. This part is up to you.
*	You may need to do what I did and hook into two interrupts. My other
*	handler was written in assembler, and it just reinstalled my critical
*	error vector. (A nasty trick, but one that was required.)
*
*	Step 4: Link the .OBJ files. You will have to use the C.OBJ in the
*	\LC\C directory. This allows us to EXE2BIN the resulting .EXE file.
*	Include the required libraries (LC.LIB, and whatever), and ignore the
*	"No stack" warning.
*
*	Step 5: EXE2BIN the .EXE file. EXE2BIN seems to have problems with
*	programs over 32K in size. Hopefully, you won't be getting this big.
*	Rename the resulting .BIN file to a .COM file.
*
*	Step 6: Run and/or debug the program, just like any other program.
*	Just remeber to reboot the machine before you install your interrupt
*	handler again.
*
*	That's about it. You should now, with a little work, be able to write
*	your own "SideKick" type program, or anything that requires itself to
*	be patched into an interrupt and resident in memory.
*
*	John Riley, Lattice Techincal Support
*
****************************************************************************/

#include "dos.h"	/* Used for the REGS declaration */

extern unsigned _tsize;	/* This is defined in C.ASM. It contains the size of
			   the entire program in paragraphs */

main()
{
	union REGS out;
	int_init();		/* Hook into the interrupt */
	out.x.dx = _tsize;	/* Setup for the intdos call */
	out.x.ax = 0x3100;	/* Terminate and stay resident call */
	intdos(&out,&out);
}


/****************************************************************************
*
*	INTTIME -- Interrupt handler
*
*	This function can do anything it wants (within reason).
*
****************************************************************************/
inttime()
{
	cprintf("Got here!!!\n");
	return(0);
}


[ RETURN TO DIRECTORY ]