home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c070 / 4.ddi / TOOLS.4 / TCTSRC1.EXE / ISPREP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-31  |  4.9 KB  |  157 lines

  1. /**
  2. *
  3. * Name        isprep -- Prepare interrupt service routine control block
  4. *
  5. * Synopsis    isprep(pfunc,pident,pisrblk,pstack,stksize,stknum);
  6. *
  7. *        void cdecl (*pfunc)(ALLREG *,ISRCTRL *,ISRMSG *)
  8. *                  Pointer to interrupt service routine
  9. *        const char *pident
  10. *                  Address of array of 16 bytes of
  11. *                  identifying information
  12. *        ISRCTRL *pisrblk  Pointer to ISR control block
  13. *                  (already allocated)
  14. *        char *pstack      Address of beginning of memory block
  15. *                  to be used for the stack(s) for this ISR
  16. *                  (already allocated)
  17. *        int stksize      Size (in bytes) of one ISR stack
  18. *                  (must be at least 64 bytes).
  19. *        int stknum      Maximum depth of nested invocations of
  20. *                  this ISR (must be at least 1)
  21. *
  22. * Description    This function prepares an interrupt service routine
  23. *        (ISR) control block for installation.  This includes
  24. *        everything necessary to execute the ISR via the ISR
  25. *        dispatcher (ISDISPAT).
  26. *
  27. *        The calling function must allocate space for the ISR
  28. *        control block and pass its address as pisrblk.    This
  29. *        space must be static during the time that the ISR is in
  30. *        use.
  31. *
  32. *        The calling function must also allocate space to be used
  33. *        for the ISR's stack(s).  The address of this space must
  34. *        be passed as pstack.  The space must be at least
  35. *        (stksize*stknum) bytes long.  This space must be static
  36. *        during the time that the ISR is in use.
  37. *
  38. *        The sixteen bytes of identifying information are stored
  39. *        in the ISR control block so that (when the ISR is
  40. *        installed in an interrupt vector) other programs may
  41. *        examine the interrupt vector and detect the presence of
  42. *        this ISR.  (See ISSENSE for an example of this.)
  43. *
  44. * Example    The following code fragment illustrates one way to
  45. *        declare the arguments to ISINSTAL and how to use
  46. *        ISPUTVEC to restore the contents of the interrupt vector
  47. *        when the ISR is no longer in use.
  48. *
  49. *            #include <stdlib.h>
  50. *            #include <bintrupt.h>
  51. *
  52. *            #define MY_INTYPE        0x60
  53. *            #define MY_STK_SIZE     2000
  54. *            #define MY_NUM_STKS        5
  55. *
  56. *            void       my_isr(ALLREG *,ISRCTRL *,ISRMSG *);
  57. *            static ISRCTRL isrblk;
  58. *            char       *pstacks;
  59. *
  60. *            if (NIL == (pstacks = malloc(MY_STK_SIZE*MY_NUM_STKS)))
  61. *            exit(3);
  62. *            isinstal(MY_INTYPE,my_isr,"THIS IS MY ISR.",
  63. *                 &isrblk,pstacks,MY_STK_SIZE,MY_NUM_STKS);
  64. *
  65. *             .......    (Use the ISR.)
  66. *
  67. *            isputvec(intype,isrblk.prev_vec);
  68. *            free(pstacks);
  69. *
  70. * Returns    (None -- function return type is void.)
  71. *
  72. * Version    6.00 (C)Copyright Blaise Computing Inc. 1986,1987,1989
  73. *
  74. **/
  75.  
  76. #include <dos.h>
  77. #include <stdlib.h>
  78. #include <string.h>              /* For memcpy(), strcmp().      */
  79.  
  80. #include <bintrupt.h>
  81.  
  82. typedef char CHAR16[16];          /* Aid for using utcopy          */
  83.  
  84. static unsigned stack_limit_unsafe(void);
  85.  
  86. void isprep(pfunc,pident,pisrblk,pstack,stksize,stknum)
  87. void    (*pfunc)(ALLREG *,ISRCTRL *,ISRMSG *);
  88. const char *pident;
  89. ISRCTRL *pisrblk;
  90. char    *pstack;
  91. int    stksize,stknum;
  92. {
  93.     int     i;
  94.     extern void isdispat(void);       /* ISR dispatcher           */
  95.  
  96.     struct SREGS segregs;
  97.  
  98.     pisrblk->fcall_opcode = 0x9a90;   /* NOP + far call opcodes       */
  99.  
  100.     pisrblk->isrdisp     = (void (far *) ()) isdispat;
  101.     pisrblk->iret_opcode = 0xcbcf;    /* IRET + RETF opcodes          */
  102.  
  103.     pisrblk->isrstk    = pstack;     /* Beginning of stack region    */
  104.     pisrblk->isrstksize = stksize;    /* Size of stack region          */
  105.  
  106.                       /* Initial SP at bottom of      */
  107.     pisrblk->isrsp  = utoff(pisrblk->isrstk);    /* stack region       */
  108.  
  109.     segread(&segregs);
  110.     pisrblk->isrds  = segregs.ds;
  111.     pisrblk->isres  = segregs.es;
  112.     pisrblk->isr    = (void (far *)(ALLREG *,
  113.                     ISRCTRL *,
  114.                     ISRMSG *)) pfunc;
  115.     pisrblk->isrpsp = utpspseg;
  116.  
  117.     pisrblk->level  = 0;
  118.     pisrblk->limit  = stknum;
  119.     pisrblk->sign2  = ~(pisrblk->signature = ICB_SIGNATURE);
  120.     utcopy(pisrblk->ident,pident,CHAR16);
  121.  
  122.     pisrblk->control = stack_limit_unsafe();
  123.     pisrblk->status  = 0;
  124.     for (i = 0; i < sizeof(pisrblk->scratch); i++)
  125.     pisrblk->scratch[i] = 0;
  126.  
  127.     pisrblk->prev_vec = FARNIL;       /* Clear pointer to previous    */
  128.                       /* interrupt handler to prevent */
  129.                       /* calling it before the ISR is */
  130.                       /* really installed.          */
  131.  
  132.     return;
  133. }
  134.  
  135. static unsigned stack_limit_unsafe()
  136. {
  137.     unsigned result;
  138.  
  139. #if    defined(__TURBOC__)                           \
  140.     && (defined(__SMALL__) || defined(__MEDIUM__) || defined(__TINY__))
  141.  
  142.     char buffer[5];              /* Check Turbo C copyright year.*/
  143.     utpeekn(uttofaru(utseg(&_psp),27),buffer,4);
  144.     buffer[4] = '\0';
  145.  
  146.     if (0 == strcmp(buffer,"1987"))
  147.     result = 0;              /* Safe to adjust stack limit.  */
  148.     else
  149.     result = ICB_NOCHECK;          /* Don't adjust stack limit.    */
  150.  
  151. #else
  152.     result = 0;               /* Safe to adjust stack limit.  */
  153. #endif
  154.  
  155.     return result;
  156. }
  157.