home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name isinstal -- Install interrupt service routine
- *
- * Synopsis ercode = isinstal(intype,pfunc,pident,pisrblk,pstack,
- * stksize,stknum);
- *
- * int ercode Error return code:
- * 0 if okay;
- * 1 if intype is outside of 0-255 range
- * int intype Interrupt type number
- * void (*pfunc)() Pointer to interrupt service routine
- * char *pident Pointer to 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 ISINSTAL installs an interrupt service routine (ISR) in
- * the interrupt vector of the specified type. This
- * includes (1) completing all the values in the ISR
- * control block; and (2) storing the address of the ISR
- * control block in the interrupt vector.
- *
- * The ISR is in effect (and may be invoked) as soon as
- * operation (2) is complete, i.e., even before ISINSTAL
- * returns to its caller.
- *
- * 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 other programs may
- * examine the interrupt vector and detect the presence of
- * this ISR. (See ISDETECT for an example of this.)
- *
- * Use ISISRSTK and ISSETISR (formerly called PCISRSTK and
- * PCSETISR, respectively) to install an ISR which was
- * built for use with C TOOLS 2. (Such ISRs must be
- * modified before they may be used directly with
- * ISINSTAL.)
- *
- * Example The following code fragment illustrates one way to
- * declare the arguments to ISINSTAL and how to use
- * ISSETVEC to restore the contents of the interrupt vector
- * when the ISR is no longer in use.
- *
- * #include <bisr.h>
- * #if LAT300
- * #include <stdlib.h>
- * #endif
- * #if MSC300
- * #include <malloc.h>
- * #include <process.h>
- * #endif
- *
- * #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.)
- *
- * issetvec(intype,&isrblk.prev_vec);
- * free(pstacks);
- *
- * Returns ercode The return code is 0 if the vector is
- * is successfully set; other values are:
- * 1 - Interrupt type out of range
- *
- * Version 3.0 (C)Copyright Blaise Computing Inc. 1986
- *
- **/
-
- #include <bisr.h>
-
- #if LAT300
- #include <stdlib.h>
- #endif
- #if MSC300
- #include <memory.h>
- #endif
-
- #define NO_ERROR 0
- #define BAD_INTYPE 1
-
- typedef char CHAR16[16]; /* Aid for using utcopy */
-
- int isinstal(intype,pfunc,pident,pisrblk,pstack,stksize,stknum)
- int intype;
- int (*pfunc)();
- char *pident;
- ISRCTRL *pisrblk;
- char *pstack;
- int stksize,stknum;
- {
- int i,ints_were_on;
- ADS isrblk_ads;
- unsigned cs,ss,ds,es;
- extern int isdispat(); /* ISR dispatcher */
-
- if (utrange(intype,0,255))
- return BAD_INTYPE;
-
- pisrblk->fcall_opcode = 0x9a90; /* NOP + far call opcodes */
-
- utcodptr(isdispat,&pisrblk->isrdisp);
- pisrblk->iret_opcode = 0xcbcf; /* IRET + RETF opcodes */
-
- utabsptr(pstack,&pisrblk->isrstk);/* Beginning of stack region */
- pisrblk->isrstksize = stksize; /* Size of stack region */
-
- /* Initial SP at bottom of */
- pisrblk->isrsp = pisrblk->isrstk.r; /* stack region */
-
- utsreg(&cs,&ss,&ds,&es);
- pisrblk->isrds = ds;
- pisrblk->isres = es;
- utcodptr(pfunc,&pisrblk->isr);
- pisrblk->isrpsp = utpspseg;
-
- pisrblk->level = 0;
- pisrblk->limit = stknum;
- pisrblk->sign2 = ~(pisrblk->signature = ICB_SIGNATURE);
- utcopy(pisrblk->ident,pident,CHAR16);
-
- pisrblk->control =
- pisrblk->status = 0;
- for (i = 0; i < sizeof(pisrblk->scratch); i++)
- pisrblk->scratch[i] = 0;
-
- /* Now load the interrupt vector with the segment and offset */
- /* address of the ISR control block. */
-
- utabsptr((char *) pisrblk,&isrblk_ads);
- isrblk_ads.r += ICB_ENTRY_OFFSET; /* Address of instruction which */
- /* will be installed in */
- /* interrupt vector. */
- ints_were_on = utintoff();
- isretvec(intype,&pisrblk->prev_vec);
- issetvec(intype,&isrblk_ads); /* This completes the */
- /* installation. */
- if (ints_were_on)
- utinton();
-
- return NO_ERROR;
- }