home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 13 / 13.iso / s / s001 / 1.ddi / TS / SRC / INTATT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1987-12-19  |  4.4 KB  |  144 lines

  1.                 /******************************************
  2.            *           INTATT.C             *
  3.                * Copyright TimeSlice, Inc. 1985, 86, 87. *
  4.                ******************************************/
  5.  
  6.  
  7. #include <ts.h>
  8. #include <stdio.h>
  9.  
  10.  
  11.  
  12. extern int *_istop ;
  13. char _opiret = IRET;            /*used for null intrpt vectors*/
  14. long _iid = 1 ;            /* master intr id number */
  15. int  intmgr(), rlsmem(), _ts_free() ;
  16. char *getmem();
  17. void intrest();
  18.  
  19. /***
  20. * INTATT( INTNO , STKSIZ , FUNC , RBAFLAG , ARG )
  21. * This function will attach function FUNC to interrupt # intno, and if
  22. *    RBAFLAG == 0    -->    replace original ISR with FUNC
  23. *        == 1    -->    execute FUNC and then original ISR
  24. * Before control is passed to FUNC a temporary stack of STKSIZ words is 
  25. * prepared for it in the C DataSegment. A value can be passed to the 
  26. * function through the parameter ARG . A unique id is returned in long 
  27. * format. 
  28. ***/
  29. long intatt( intno, stksiz, func , ctlflag, arg )
  30. int intno, stksiz ;
  31. void (*func)();
  32. int ctlflag;
  33. char *arg;
  34. {
  35.   INTLST *p;
  36.   int cpuflags, ivect;
  37.   FARPTR vector;
  38.   static char initialized;
  39.  
  40. #if ( defined(LATTICE) && ( defined(MD) || defined(ML)  ))
  41.   /*make sure that _istop is on paragraph boundary (for Lattice large data)*/
  42.   if( !initialized ) {
  43.     cpuflags = cli();
  44.     *((int*)&_istop) &= ~0xF;
  45.     putf( cpuflags );
  46.   }
  47.  
  48.   /*make sure stksiz is a multiple of 16 (paragraph size)*/
  49.   stksiz = (stksiz+0xF) & ~0xF;
  50. #endif
  51.  
  52.   /**allocate an INTLST structure p**/
  53. #if defined(TURBOC)
  54.   if( NULL == ( p = (INTLST *)cpcrit( DOS_CRCLASS, _ts_malloc , sizeof( INTLST ) )))
  55. #else
  56.   if( NULL == ( p = (INTLST *)cpcrit( DOS_CRCLASS, getmem , sizeof( INTLST ) )))
  57. #endif
  58.     return( NULL );
  59.   intexit = intrest;                /*make sure exitmp() calls it*/
  60.   p->stksiz = stksiz * sizeof( int );        /*initialize p*/
  61.   p->arg = arg;
  62.   p->iid = _iid;
  63.   p->intno = intno;
  64.   p->func = func;
  65.   p->opcall = CALLFAR;
  66.   p->imoff = f_off( intmgr );
  67.   p->imseg = f_seg( intmgr );
  68.   p->dummy2 = NOP;
  69.   /**if ctlflag continue with old interrupt service routine, else iret**/
  70.   p->opjmp = (ctlflag == 1 ) ? JUMPFAR : IRET;
  71.   /**save old interrupt vector & update with new value**/
  72.   cpuflags = cli();        /*hold interrupts*/
  73.   peek( 0 , ivect = (intno << 2) , &p->jmpaddr.l , sizeof( long ) );
  74.   if( ! p->jmpaddr.l ) {    /*redirect null vectors to _opiret*/
  75.     p->jmpaddr.i.off = d_off( &_opiret );
  76.     p->jmpaddr.i.seg = d_seg( &_opiret );
  77.   }
  78.   vector.i.off = d_off( &p->opcall );
  79.   vector.i.seg = d_seg( &p->opcall );
  80.   poke( 0 , ivect , &vector , sizeof( vector ) );
  81.   p->nxt = ilhead;        /*insert p into ilhead's list*/
  82.   ilhead = p;
  83.  do {                /*find next intrpt with same intno*/
  84.     p = p->nxt ;
  85.   } while ( p && p->intno != intno );
  86.   ilhead->inxt = p;        /*insert in that intno list*/
  87.   putf( cpuflags );        /*reset flags to original value*/
  88.   return _iid++ ;
  89. }
  90.  
  91. /***
  92. * INTDET( IID )
  93. * Detach from the interrupt list, the INTLIST having id IID.
  94. * Return NULL if no interrupt associated with IID.
  95. ***/
  96. INTLST *intdet( iid )
  97. long iid;
  98. {
  99.   INTLST *q,            /*intlst of iid*/
  100.      *p,            /*predecessor of q (nxt ptr)*/
  101.      *r;            /*predecessor of q (inxt ptr)*/
  102.   int cpuflags;
  103.   
  104.   cpuflags = cli();
  105.   /**find p & q**/
  106.   for( p = (INTLST*)&ilhead ; p->nxt && p->nxt->iid != iid ; p = p->nxt );
  107.   if( q = p->nxt ) {            /*if it exists...*/
  108.     /**find r, first int with same intno**/
  109.     for( r = ilhead ; r->intno != q->intno ; r = r->nxt );
  110.     p->nxt = q->nxt;            /*remove iid from nxt list*/
  111.     /**restore original interrupt vector**/
  112.     if( r == q ) {            /*iid is first int of intno*/
  113.       /*if pointint to _opiret reset to NULL vector*/
  114.       if( (q->jmpaddr.i.off == d_off(&_opiret)) &&
  115.             (q->jmpaddr.i.seg == d_seg(&_opiret)) )
  116.         q->jmpaddr.l = 0;
  117.       poke( 0 , q->intno << 2 , (char*)&q->jmpaddr.l , sizeof( long ));
  118.     } else {
  119.       while( r->inxt != q )        /*set r to predecessor (inxt list)*/
  120.         r = r->inxt;
  121.       r->jmpaddr.l = q->jmpaddr.l;
  122.       r->inxt = q->inxt;        /*remove iid from inxt list*/
  123.     }
  124.     putf( cpuflags );
  125. #if defined(TURBOC)
  126.     crit( DOS_CRCLASS, _ts_free , q , sizeof( INTLST ) );    /*free INTLST*/
  127. #else
  128.     crit( DOS_CRCLASS, rlsmem , q , sizeof( INTLST ) );    /*free INTLST*/
  129. #endif
  130.   } else
  131.     putf( cpuflags );
  132.   return( q );
  133. }
  134.  
  135. /***
  136. * INTREST()
  137. * this function detaches all functions attached to all interrupts.
  138. ***/
  139. void intrest() {
  140.  
  141.   while( ilhead )
  142.     intdet( ilhead->iid );
  143. }
  144.