home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / m / msc7.zip / EXCEPTIO.CPP < prev    next >
C/C++ Source or Header  |  1992-02-12  |  2KB  |  80 lines

  1. //
  2. // (c) Copyright 1992, Qualitas, Inc. All Rights Reserved
  3. //
  4. // exceptio.cpp - member functions for ExceptionHandler class
  5. //
  6.  
  7. #include <dos.h>
  8. #include "exceptio.h"
  9.  
  10. extern "C" {
  11.     void initDispatch(void);
  12.     void (far* setXDispatch(uChar, void (*)(dpmiRegs_t, excFrame),
  13.                 void (**)(dpmiRegs_t, excFrame)))();
  14.     void callXHandler(dpmiRegs_t *, excFrame *, void far *);
  15. };
  16.  
  17. extern boolean dispatchInitialized;
  18.  
  19. //
  20. //
  21. // ExceptionHandler class
  22. //
  23. //     Constructor
  24. //
  25. ExceptionHandler::ExceptionHandler(uChar xNum, 
  26.                     void (*handler)(dpmiRegs_t,excFrame))
  27. {
  28.  
  29.     if (!dispatchInitialized)
  30.     {
  31.         initDispatch();
  32.         dispatchInitialized = TRUE;
  33.     }
  34.  
  35.     // get the current vector for the exception from DPMI
  36.  
  37.     DPMIGetExceptionVector(xNum, (void (far**)())&previousVector);
  38.  
  39.  
  40.     // hook the exception vector
  41.  
  42.     ordinal = xNum;
  43.     DPMISetExceptionVector(xNum,setXDispatch(xNum,handler,&prevDispatch));
  44. }
  45.  
  46. //
  47. // destructor
  48. // 
  49. ExceptionHandler::~ExceptionHandler(void)
  50. {
  51.  
  52.     if (FP_SEG(previousVector) == theCodeSel)
  53.         setXDispatch(ordinal, prevDispatch, &prevDispatch);
  54.  
  55.     DPMISetExceptionVector(ordinal, (void (far*)())previousVector);
  56. }
  57.  
  58. //
  59. // Call the previous exception handler
  60. //
  61. // The register state in dRegs is restored, the exception frame is pushed
  62. // on the stack, and the previous handler is called.  Care is taken to
  63. // maintain the internal dispatching tables correctly.
  64. //
  65. // The exception frame may be altered by the previous handler
  66. //
  67. void ExceptionHandler::callPrevious(dpmiRegs_t& dRegs, excFrame& ef)
  68. {
  69.     void (*saveDispatch)(dpmiRegs_t, excFrame);
  70.  
  71.     if (FP_SEG(previousVector) == theCodeSel)
  72.     {
  73.         setXDispatch(ordinal, prevDispatch, &saveDispatch);
  74.         callXHandler(&dRegs, &ef, previousVector);
  75.         setXDispatch(ordinal, saveDispatch, &prevDispatch);
  76.     }
  77.     else
  78.         callXHandler(&dRegs, &ef, previousVector);
  79. }
  80.