/************************************************************* * File: pmirq.c * Author: Phil Bunce (pjb@carmel.com) * Purpose: * This function makes it very easy to install interrupt handlers * that are written in C. See examples/pmon/irq.c for an example * of its use. * Revision History: * 961208 Created * 981016 Renamed. Was irq.c */ #include #include #include #ifndef SR_ISHIFT /* just in case you don't have this yet */ #define SR_ISHIFT 8 #endif int IRQTrap(); static Func *hwexctbl[] = {0,IRQTrap}; /*********************************************************************** * Func *pmIRQInstall(int IRQNum, Func *ISRFun) * * Install and enable a new Interrupt Service Routine. * * int IRQNum - interrupt request number (0..7) * 0 = sw0 lo priority * 1 = sw1 * 2 = int0 * 3 = int1 * 4 = int2 * 5 = int3 * 6 = int4 * 7 = int5 hi priority * * Func *ISRFun - new interrupt handler * If ISRFun is zero, the specified vector will be uninstalled * * Return: * The old interrupt service routine address. */ Func *pmIRQInstall(IRQNum, ISRFun) int IRQNum; Func *ISRFun; { Func * OldISR; /* Sanity check */ if (IRQNum < 0 || IRQNum >= MAXINTHNDLRS) return((Func *)0); /* only does this the first time */ if (hwexctbl[0]==0) onintr(0,hwexctbl); if (pri_table[1]==0) buildPriTable(pri_table); /* Get old ISR function */ OldISR = IRQVector[IRQNum]; if (!ISRFun) { /* uninstall */ mtc0(C0_SR,mfc0(C0_SR)&~(1<<(SR_ISHIFT+IRQNum))); IRQVector[IRQNum] = 0; return(OldISR); } /* Replace with new ISR function */ IRQVector[IRQNum] = ISRFun; /* Enable the interrupt */ mtc0(C0_SR,mfc0(C0_SR)|(1<<(SR_ISHIFT+IRQNum))|SR_IEC); return(OldISR); }