home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name isprep -- Prepare interrupt service routine control block
- *
- * Synopsis isprep(pfunc,pident,pisrblk,pstack,stksize,stknum);
- *
- * void cdecl (*pfunc)(ALLREG *,ISRCTRL *,ISRMSG *)
- * Pointer to interrupt service routine
- * const char *pident
- * Address of array of 16 bytes of
- * identifying information
- * ISRCTRL *pisrblk Pointer to ISR control block
- * (already allocated)
- * char *pstack Address of beginning of memory block
- * to be used for the stack(s) for this ISR
- * (already allocated)
- * int stksize Size (in bytes) of one ISR stack
- * (must be at least 64 bytes).
- * int stknum Maximum depth of nested invocations of
- * this ISR (must be at least 1)
- *
- * Description This function prepares an interrupt service routine
- * (ISR) control block for installation. This includes
- * everything necessary to execute the ISR via the ISR
- * dispatcher (ISDISPAT).
- *
- * The calling function must allocate space for the ISR
- * control block and pass its address as pisrblk. This
- * space must be static during the time that the ISR is in
- * use.
- *
- * The calling function must also allocate space to be used
- * for the ISR's stack(s). The address of this space must
- * be passed as pstack. The space must be at least
- * (stksize*stknum) bytes long. This space must be static
- * during the time that the ISR is in use.
- *
- * The sixteen bytes of identifying information are stored
- * in the ISR control block so that (when the ISR is
- * installed in an interrupt vector) other programs may
- * examine the interrupt vector and detect the presence of
- * this ISR. (See ISSENSE for an example of this.)
- *
- * Example The following code fragment illustrates one way to
- * declare the arguments to ISINSTAL and how to use
- * ISPUTVEC to restore the contents of the interrupt vector
- * when the ISR is no longer in use.
- *
- * #include <stdlib.h>
- * #include <bintrupt.h>
- *
- * #define MY_INTYPE 0x60
- * #define MY_STK_SIZE 2000
- * #define MY_NUM_STKS 5
- *
- * void my_isr(ALLREG *,ISRCTRL *,ISRMSG *);
- * static ISRCTRL isrblk;
- * char *pstacks;
- *
- * if (NIL == (pstacks = malloc(MY_STK_SIZE*MY_NUM_STKS)))
- * exit(3);
- * isinstal(MY_INTYPE,my_isr,"THIS IS MY ISR.",
- * &isrblk,pstacks,MY_STK_SIZE,MY_NUM_STKS);
- *
- * ....... (Use the ISR.)
- *
- * isputvec(intype,isrblk.prev_vec);
- * free(pstacks);
- *
- * Returns (None -- function return type is void.)
- *
- * Version 6.00 (C)Copyright Blaise Computing Inc. 1986,1987,1989
- *
- **/
-
- #include <dos.h>
- #include <stdlib.h>
- #include <string.h> /* For memcpy(), strcmp(). */
-
- #include <bintrupt.h>
-
- typedef char CHAR16[16]; /* Aid for using utcopy */
-
- static unsigned stack_limit_unsafe(void);
-
- void isprep(pfunc,pident,pisrblk,pstack,stksize,stknum)
- void (*pfunc)(ALLREG *,ISRCTRL *,ISRMSG *);
- const char *pident;
- ISRCTRL *pisrblk;
- char *pstack;
- int stksize,stknum;
- {
- int i;
- extern void isdispat(void); /* ISR dispatcher */
-
- struct SREGS segregs;
-
- pisrblk->fcall_opcode = 0x9a90; /* NOP + far call opcodes */
-
- pisrblk->isrdisp = (void (far *) ()) isdispat;
- pisrblk->iret_opcode = 0xcbcf; /* IRET + RETF opcodes */
-
- pisrblk->isrstk = pstack; /* Beginning of stack region */
- pisrblk->isrstksize = stksize; /* Size of stack region */
-
- /* Initial SP at bottom of */
- pisrblk->isrsp = utoff(pisrblk->isrstk); /* stack region */
-
- segread(&segregs);
- pisrblk->isrds = segregs.ds;
- pisrblk->isres = segregs.es;
- pisrblk->isr = (void (far *)(ALLREG *,
- ISRCTRL *,
- ISRMSG *)) pfunc;
- pisrblk->isrpsp = utpspseg;
-
- pisrblk->level = 0;
- pisrblk->limit = stknum;
- pisrblk->sign2 = ~(pisrblk->signature = ICB_SIGNATURE);
- utcopy(pisrblk->ident,pident,CHAR16);
-
- pisrblk->control = stack_limit_unsafe();
- pisrblk->status = 0;
- for (i = 0; i < sizeof(pisrblk->scratch); i++)
- pisrblk->scratch[i] = 0;
-
- pisrblk->prev_vec = FARNIL; /* Clear pointer to previous */
- /* interrupt handler to prevent */
- /* calling it before the ISR is */
- /* really installed. */
-
- return;
- }
-
- static unsigned stack_limit_unsafe()
- {
- unsigned result;
-
- #if defined(__TURBOC__) \
- && (defined(__SMALL__) || defined(__MEDIUM__) || defined(__TINY__))
-
- char buffer[5]; /* Check Turbo C copyright year.*/
- utpeekn(uttofaru(utseg(&_psp),27),buffer,4);
- buffer[4] = '\0';
-
- if (0 == strcmp(buffer,"1987"))
- result = 0; /* Safe to adjust stack limit. */
- else
- result = ICB_NOCHECK; /* Don't adjust stack limit. */
-
- #else
- result = 0; /* Safe to adjust stack limit. */
- #endif
-
- return result;
- }