home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-386-Vol-2of3.iso / b / bc3.zip / DPMIINT.CPP < prev    next >
C/C++ Source or Header  |  1992-02-17  |  3KB  |  138 lines

  1. //
  2. // (c) Copyright 1992, Qualitas, Inc.  All Rights Reserved
  3. //
  4. // dpmiint.cpp - member functions for InterruptHandler and 
  5. //         RealInterruptHandler classes
  6. //
  7. #include <dos.h>
  8. #include "dpmiint.h"
  9.  
  10. boolean dispatchInitialized=FALSE;
  11.  
  12. extern "C" {
  13.     void initDispatch(void);
  14.     void (_interrupt *setDispatch(int ord, void (*)(dpmiRegs_t), 
  15.                     int, void (**)(dpmiRegs_t)))();
  16.     void callHandler(dpmiRegs_t *, void far *);
  17. };
  18.  
  19.  
  20. //
  21. // InterruptHandler class
  22. //
  23. //     Constructor
  24. //
  25. InterruptHandler::InterruptHandler(uChar ord, void (*isrAddress)(dpmiRegs_t))
  26. {
  27.     selector_t codeAlias;
  28.     uShort far *pFixup;
  29.  
  30.     if (!dispatchInitialized)
  31.     {
  32.         initDispatch();
  33.         dispatchInitialized = TRUE;
  34.     }
  35.     ordinal = ord;
  36.     mode = 1;
  37.  
  38.     // get the current vector for the interrupt from DPMI;
  39.  
  40.     DPMIGetProtInterruptVector(ord,
  41.             (void (_interrupt **)())&previousVector);
  42.  
  43.     // assume (since this is a small model implementation) that
  44.     // the vector being set up is in the same code segment
  45.  
  46.     DPMISetProtInterruptVector(ord, 
  47.         (void (_interrupt (*)()))
  48.             setDispatch(ord, isrAddress, 1, &prevDispatch));
  49. }
  50.  
  51. //
  52. //  This constructor is provided only as a base constructor for the
  53. //  RealInterruptHandler class.  
  54. //
  55. InterruptHandler::InterruptHandler(uChar ord)
  56. {
  57.     ordinal = ord;
  58. }
  59.  
  60. //
  61. // Destructor
  62. //
  63. InterruptHandler::~InterruptHandler(void)
  64. {
  65.     if (FP_SEG(previousVector) == theCodeSel)
  66.       setDispatch(ordinal, prevDispatch, 1, &prevDispatch);
  67.  
  68.     if (previousVector)
  69.         DPMISetProtInterruptVector(ordinal, 
  70.                     (void (_interrupt*)())previousVector);
  71. }
  72.  
  73.  
  74. //
  75. //
  76. // Call to previous handler
  77. // 
  78. // The previous handler is called after setting up the register as in
  79. // the passed structure.  Care is taken to maintain the internal
  80. // dispatch tables.
  81. //
  82. // This method is inherited and used by the RealInterruptHandler class.
  83. //
  84. void InterruptHandler::callPrevious(dpmiRegs_t& dRegs)
  85. {
  86.     void (*saveDispatch)(dpmiRegs_t);
  87.  
  88.     if (FP_SEG(previousVector) == theCodeSel)
  89.     {
  90.         setDispatch(ordinal, prevDispatch, mode, &saveDispatch);
  91.         callHandler(&dRegs, previousVector);
  92.         setDispatch(ordinal, saveDispatch, mode, &prevDispatch);
  93.     }
  94.     else
  95.         callHandler(&dRegs, previousVector);
  96. }
  97.  
  98.  
  99. //
  100. //
  101. //  Constructor for real mode interrupt handler
  102. //
  103. RealInterruptHandler::RealInterruptHandler(uChar ord,void (*isr)(dpmiRegs_t)):
  104.         InterruptHandler(ord)
  105. {
  106.     if (!dispatchInitialized)
  107.     {
  108.         initDispatch();
  109.         dispatchInitialized = TRUE;
  110.     }
  111.  
  112.     DPMIGetRealInterruptVector(ord, (void (far* *)())&previousVector);
  113.     DPMISetRealInterruptVector(ord,
  114.             (void (far *)())setDispatch(ord, isr, 0, &prevDispatch));
  115.     mode = 0;
  116. }
  117.  
  118. //
  119. //  Destructor for real mode interrupt handler
  120. //
  121. RealInterruptHandler::~RealInterruptHandler(void)
  122. {
  123.     uLong codeBase;
  124.     uShort codePara;
  125.  
  126.     DPMIGetSegmentBase(theCodeSel, &codeBase);
  127.     codePara = codeBase >> 4;
  128.  
  129.     DPMITestDisableInts();
  130.  
  131.     if (FP_SEG(previousVector) == codePara)
  132.       setDispatch(ordinal, prevDispatch, 0, &prevDispatch);
  133.  
  134.     DPMISetRealInterruptVector(ordinal,(void (far*)())previousVector);
  135.  
  136.     previousVector=0;
  137. }
  138.