home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c005 / 4.ddi / C / ISINSTAL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1986-08-05  |  5.3 KB  |  170 lines

  1. /**
  2. *
  3. * Name        isinstal -- Install interrupt service routine
  4. *
  5. * Synopsis    ercode = isinstal(intype,pfunc,pident,pisrblk,pstack,
  6. *                  stksize,stknum);
  7. *
  8. *        int ercode      Error return code:
  9. *                  0 if okay;
  10. *                  1 if intype is outside of 0-255 range
  11. *        int intype      Interrupt type number
  12. *        void (*pfunc)()   Pointer to interrupt service routine
  13. *        char *pident      Pointer to array of 16 bytes of
  14. *                  identifying information
  15. *        ISRCTRL *pisrblk  Pointer to ISR control block
  16. *                  (already allocated)
  17. *        char *pstack      Address of beginning of memory block
  18. *                  to be used for the stack(s) for this ISR
  19. *                  (already allocated)
  20. *        int stksize      Size (in bytes) of one ISR stack
  21. *                  (must be at least 64 bytes).
  22. *        int stknum      Maximum depth of nested invocations of
  23. *                  this ISR (must be at least 1)
  24. *
  25. * Description    ISINSTAL installs an interrupt service routine (ISR) in
  26. *        the interrupt vector of the specified type.  This
  27. *        includes (1) completing all the values in the ISR
  28. *        control block; and (2) storing the address of the ISR
  29. *        control block in the interrupt vector.
  30. *
  31. *        The ISR is in effect (and may be invoked) as soon as
  32. *        operation (2) is complete, i.e., even before ISINSTAL
  33. *        returns to its caller.
  34. *
  35. *        The calling function must allocate space for the ISR
  36. *        control block and pass its address as pisrblk.    This
  37. *        space must be static during the time that the ISR is in
  38. *        use.
  39. *
  40. *        The calling function must also allocate space to be used
  41. *        for the ISR's stack(s).  The address of this space must
  42. *        be passed as pstack.  The space must be at least
  43. *        (stksize*stknum) bytes long.  This space must be static
  44. *        during the time that the ISR is in use.
  45. *
  46. *        The sixteen bytes of identifying information are stored
  47. *        in the ISR control block so that other programs may
  48. *        examine the interrupt vector and detect the presence of
  49. *        this ISR.  (See ISDETECT for an example of this.)
  50. *
  51. *        Use ISISRSTK and ISSETISR (formerly called PCISRSTK and
  52. *        PCSETISR, respectively) to install an ISR which was
  53. *        built for use with C TOOLS 2.  (Such ISRs must be
  54. *        modified before they may be used directly with
  55. *        ISINSTAL.)
  56. *
  57. * Example    The following code fragment illustrates one way to
  58. *        declare the arguments to ISINSTAL and how to use
  59. *        ISSETVEC to restore the contents of the interrupt vector
  60. *        when the ISR is no longer in use.
  61. *
  62. *            #include <bisr.h>
  63. *            #if LAT300
  64. *            #include <stdlib.h>
  65. *            #endif
  66. *            #if MSC300
  67. *            #include <malloc.h>
  68. *            #include <process.h>
  69. *            #endif
  70. *
  71. *            #define MY_INTYPE        0x60
  72. *            #define MY_STK_SIZE     2000
  73. *            #define MY_NUM_STKS        5
  74. *
  75. *            void       my_isr(ALLREG *,ISRCTRL *,ISRMSG *);
  76. *            static ISRCTRL isrblk;
  77. *            char       *pstacks;
  78. *
  79. *            if (NIL == (pstacks = malloc(MY_STK_SIZE*MY_NUM_STKS)))
  80. *            exit(3);
  81. *            isinstal(MY_INTYPE,my_isr,"THIS IS MY ISR.",
  82. *                 &isrblk,pstacks,MY_STK_SIZE,MY_NUM_STKS);
  83. *
  84. *             .......    (Use the ISR.)
  85. *
  86. *            issetvec(intype,&isrblk.prev_vec);
  87. *            free(pstacks);
  88. *
  89. * Returns    ercode          The return code is 0 if the vector is
  90. *                  is successfully set; other values are:
  91. *                  1 - Interrupt type out of range
  92. *
  93. * Version    3.0  (C)Copyright Blaise Computing Inc.  1986
  94. *
  95. **/
  96.  
  97. #include <bisr.h>
  98.  
  99. #if LAT300
  100. #include <stdlib.h>
  101. #endif
  102. #if MSC300
  103. #include <memory.h>
  104. #endif
  105.  
  106. #define  NO_ERROR    0
  107. #define  BAD_INTYPE    1
  108.  
  109. typedef char CHAR16[16];          /* Aid for using utcopy          */
  110.  
  111. int isinstal(intype,pfunc,pident,pisrblk,pstack,stksize,stknum)
  112. int    intype;
  113. int    (*pfunc)();
  114. char    *pident;
  115. ISRCTRL *pisrblk;
  116. char    *pstack;
  117. int    stksize,stknum;
  118. {
  119.     int     i,ints_were_on;
  120.     ADS     isrblk_ads;
  121.     unsigned    cs,ss,ds,es;
  122.     extern int    isdispat();          /* ISR dispatcher           */
  123.  
  124.     if (utrange(intype,0,255))
  125.     return BAD_INTYPE;
  126.  
  127.     pisrblk->fcall_opcode = 0x9a90;   /* NOP + far call opcodes       */
  128.  
  129.     utcodptr(isdispat,&pisrblk->isrdisp);
  130.     pisrblk->iret_opcode = 0xcbcf;    /* IRET + RETF opcodes          */
  131.  
  132.     utabsptr(pstack,&pisrblk->isrstk);/* Beginning of stack region    */
  133.     pisrblk->isrstksize = stksize;    /* Size of stack region          */
  134.  
  135.                       /* Initial SP at bottom of      */
  136.     pisrblk->isrsp  = pisrblk->isrstk.r;    /* stack region       */
  137.  
  138.     utsreg(&cs,&ss,&ds,&es);
  139.     pisrblk->isrds  = ds;
  140.     pisrblk->isres  = es;
  141.     utcodptr(pfunc,&pisrblk->isr);
  142.     pisrblk->isrpsp = utpspseg;
  143.  
  144.     pisrblk->level  = 0;
  145.     pisrblk->limit  = stknum;
  146.     pisrblk->sign2  = ~(pisrblk->signature = ICB_SIGNATURE);
  147.     utcopy(pisrblk->ident,pident,CHAR16);
  148.  
  149.     pisrblk->control =
  150.     pisrblk->status  = 0;
  151.     for (i = 0; i < sizeof(pisrblk->scratch); i++)
  152.     pisrblk->scratch[i] = 0;
  153.  
  154.     /* Now load the interrupt vector with the segment and offset      */
  155.     /* address of the ISR control block.                  */
  156.  
  157.     utabsptr((char *) pisrblk,&isrblk_ads);
  158.     isrblk_ads.r += ICB_ENTRY_OFFSET; /* Address of instruction which */
  159.                       /* will be installed in          */
  160.                       /* interrupt vector.          */
  161.     ints_were_on = utintoff();
  162.     isretvec(intype,&pisrblk->prev_vec);
  163.     issetvec(intype,&isrblk_ads);     /* This completes the          */
  164.                       /* installation.              */
  165.     if (ints_were_on)
  166.     utinton();
  167.  
  168.     return NO_ERROR;
  169. }
  170.