home *** CD-ROM | disk | FTP | other *** search
- /******************************************
- * INTATT.C *
- * Copyright TimeSlice, Inc. 1985, 86, 87. *
- ******************************************/
-
-
- #include <ts.h>
- #include <stdio.h>
-
-
-
- extern int *_istop ;
- char _opiret = IRET; /*used for null intrpt vectors*/
- long _iid = 1 ; /* master intr id number */
- int intmgr(), rlsmem(), _ts_free() ;
- char *getmem();
- void intrest();
-
- /***
- * INTATT( INTNO , STKSIZ , FUNC , RBAFLAG , ARG )
- * This function will attach function FUNC to interrupt # intno, and if
- * RBAFLAG == 0 --> replace original ISR with FUNC
- * == 1 --> execute FUNC and then original ISR
- * Before control is passed to FUNC a temporary stack of STKSIZ words is
- * prepared for it in the C DataSegment. A value can be passed to the
- * function through the parameter ARG . A unique id is returned in long
- * format.
- ***/
- long intatt( intno, stksiz, func , ctlflag, arg )
- int intno, stksiz ;
- void (*func)();
- int ctlflag;
- char *arg;
- {
- INTLST *p;
- int cpuflags, ivect;
- FARPTR vector;
- static char initialized;
-
- #if ( defined(LATTICE) && ( defined(MD) || defined(ML) ))
- /*make sure that _istop is on paragraph boundary (for Lattice large data)*/
- if( !initialized ) {
- cpuflags = cli();
- *((int*)&_istop) &= ~0xF;
- putf( cpuflags );
- }
-
- /*make sure stksiz is a multiple of 16 (paragraph size)*/
- stksiz = (stksiz+0xF) & ~0xF;
- #endif
-
- /**allocate an INTLST structure p**/
- #if defined(TURBOC)
- if( NULL == ( p = (INTLST *)cpcrit( DOS_CRCLASS, _ts_malloc , sizeof( INTLST ) )))
- #else
- if( NULL == ( p = (INTLST *)cpcrit( DOS_CRCLASS, getmem , sizeof( INTLST ) )))
- #endif
- return( NULL );
- intexit = intrest; /*make sure exitmp() calls it*/
- p->stksiz = stksiz * sizeof( int ); /*initialize p*/
- p->arg = arg;
- p->iid = _iid;
- p->intno = intno;
- p->func = func;
- p->opcall = CALLFAR;
- p->imoff = f_off( intmgr );
- p->imseg = f_seg( intmgr );
- p->dummy2 = NOP;
- /**if ctlflag continue with old interrupt service routine, else iret**/
- p->opjmp = (ctlflag == 1 ) ? JUMPFAR : IRET;
- /**save old interrupt vector & update with new value**/
- cpuflags = cli(); /*hold interrupts*/
- peek( 0 , ivect = (intno << 2) , &p->jmpaddr.l , sizeof( long ) );
- if( ! p->jmpaddr.l ) { /*redirect null vectors to _opiret*/
- p->jmpaddr.i.off = d_off( &_opiret );
- p->jmpaddr.i.seg = d_seg( &_opiret );
- }
- vector.i.off = d_off( &p->opcall );
- vector.i.seg = d_seg( &p->opcall );
- poke( 0 , ivect , &vector , sizeof( vector ) );
- p->nxt = ilhead; /*insert p into ilhead's list*/
- ilhead = p;
- do { /*find next intrpt with same intno*/
- p = p->nxt ;
- } while ( p && p->intno != intno );
- ilhead->inxt = p; /*insert in that intno list*/
- putf( cpuflags ); /*reset flags to original value*/
- return _iid++ ;
- }
-
- /***
- * INTDET( IID )
- * Detach from the interrupt list, the INTLIST having id IID.
- * Return NULL if no interrupt associated with IID.
- ***/
- INTLST *intdet( iid )
- long iid;
- {
- INTLST *q, /*intlst of iid*/
- *p, /*predecessor of q (nxt ptr)*/
- *r; /*predecessor of q (inxt ptr)*/
- int cpuflags;
-
- cpuflags = cli();
- /**find p & q**/
- for( p = (INTLST*)&ilhead ; p->nxt && p->nxt->iid != iid ; p = p->nxt );
- if( q = p->nxt ) { /*if it exists...*/
- /**find r, first int with same intno**/
- for( r = ilhead ; r->intno != q->intno ; r = r->nxt );
- p->nxt = q->nxt; /*remove iid from nxt list*/
- /**restore original interrupt vector**/
- if( r == q ) { /*iid is first int of intno*/
- /*if pointint to _opiret reset to NULL vector*/
- if( (q->jmpaddr.i.off == d_off(&_opiret)) &&
- (q->jmpaddr.i.seg == d_seg(&_opiret)) )
- q->jmpaddr.l = 0;
- poke( 0 , q->intno << 2 , (char*)&q->jmpaddr.l , sizeof( long ));
- } else {
- while( r->inxt != q ) /*set r to predecessor (inxt list)*/
- r = r->inxt;
- r->jmpaddr.l = q->jmpaddr.l;
- r->inxt = q->inxt; /*remove iid from inxt list*/
- }
- putf( cpuflags );
- #if defined(TURBOC)
- crit( DOS_CRCLASS, _ts_free , q , sizeof( INTLST ) ); /*free INTLST*/
- #else
- crit( DOS_CRCLASS, rlsmem , q , sizeof( INTLST ) ); /*free INTLST*/
- #endif
- } else
- putf( cpuflags );
- return( q );
- }
-
- /***
- * INTREST()
- * this function detaches all functions attached to all interrupts.
- ***/
- void intrest() {
-
- while( ilhead )
- intdet( ilhead->iid );
- }
-