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

  1. //
  2. // (C) Copyright 1992 Qualitas, Inc.  All rights reserved.
  3. //
  4. // xreal.cpp  -  example usage of RealProcedure, RealInterrupt, and
  5. //          CallBack classes in DPMI class library
  6. //
  7.  
  8. #include <iostream.h>
  9. #include <iomanip.h>
  10. #include <dos.h>
  11. #include "dpmihost.h"
  12. #include "dpmiint.h"
  13. #include "realproc.h"
  14. #include "callback.h"
  15. #include "realint.h"
  16.  
  17. //
  18. // This function can run in either real or protected mode. The
  19. // example program invokes it in both ways to illustrate RealProcedure usage.
  20. //
  21. void far whatMode(void)
  22. {
  23.     if (DPMIGetCPUMode() == 0)
  24.         cout << "Currently running in protected mode\n";
  25.     else
  26.         cout << "Currently running in real/V86 mode\n";
  27. }
  28.  
  29. //
  30. //  This function must run only in real mode.  It uses the INT 67h vector
  31. //  in the real mode interrupt vector table to locate the system EMS 
  32. //  driver, if any.  Attempting to run this in protected mode would 
  33. //  result in a general protection exception.
  34. //
  35. uShort far findEMS(const char* deviceName)
  36. {
  37.     int i;
  38.  
  39.     // get EMS vector
  40.     void far* far* pVector = (void far* far*)MK_FP(0, 0x67*4);
  41.  
  42.     // device name should be at offset 0xA in that para
  43.     char far *pDevice = (char far *)MK_FP(FP_SEG(*pVector), 0xA);
  44.  
  45.     // compare 8 character strings
  46.     for (i=0; i < 8; i++)
  47.         if (deviceName[i] != pDevice[i])
  48.             break;
  49.     if (i == 8)
  50.         return FP_SEG(*pVector);    // matched string
  51.     else                    //   so return paragraph
  52.         return 0;            // didn't find device
  53. }
  54.  
  55. void TestRealProcs(void)
  56. {
  57.     RealProcedure rWhatMode((void far *)whatMode, 0);
  58.  
  59.     whatMode();
  60.     rWhatMode();
  61.  
  62.     RealProcedure rFindEMS((void far *)findEMS, sizeof(char*));
  63.  
  64.     uShort EMSpara = (int)rFindEMS("EMMXXXX0");
  65.     if (EMSpara != 0)
  66.     {
  67.         cout << "Found EMS at real paragraph " << hex << EMSpara;
  68.         cout << "\n";
  69.     }
  70.     else
  71.         cout << "EMS device not found\n";
  72. }
  73.  
  74. ////////////////  Real Mode CallBack Example //////////////////////////
  75. //
  76. // The example presented here illustrates the mechanics of real mode
  77. // call backs. The protected mode caller invokes real mode software interrupt
  78. // 99h, for which a handler has been installed.  The real mode
  79. // int 99h handler makes a call back to a protected mode call back handler,
  80. // which outputs a message and changes the value of the SI register.  The
  81. // example illustrates that a register changed in the call back handler
  82. // can be passed back through the real mode interrupt handler to the
  83. // original caller.
  84.  
  85. RealInterruptHandler* p99Handler;    // pointer to RealInterruptHandler obj
  86. CallBack *pCB99;            // pointer to CallBack object
  87. void (far *cb99addr)();            // real mode callback address
  88.  
  89. //
  90. // The call back handler - runs in protected mode - called back by real
  91. // mode int 99h handler.  This handler negates the value of the SI register.
  92. //
  93. void CallBack99Handler(dpmiRegs_t iFrame)
  94. {
  95.     cout << "Handling callback from real mode int 99h handler"
  96.          << "  si=" << dec << iFrame.drESI.s << "\n";
  97.  
  98.     iFrame.drESI.s = -iFrame.drESI.s;
  99. }
  100.  
  101. //
  102. // The real mode int 99h handler - installed by the original protected mode
  103. // caller.  The protected mode caller generates an real mode int 99h using
  104. // the DPMI library call.
  105. //
  106. void HandleRealInt99(dpmiRegs_t iFrame)
  107. {
  108.     uShort regSI;
  109.  
  110.     cout << "In real int 99h handler\n";
  111.  
  112.     regSI = iFrame.drESI.s;
  113.  
  114.     _asm mov si, regSI
  115.  
  116.     (*cb99addr)();        // call back to protected mode handler
  117.  
  118.     _asm mov regSI, si
  119.  
  120.     iFrame.drESI.s = regSI;
  121. }
  122.  
  123. //
  124. // The call back test driver - installs a real mode software int 99h 
  125. // handler - generates a real int 99h - real mode int 99h handler calls 
  126. // back to the call back handler.  This example also shows how to use
  127. // the RealInterrupt class.
  128. //
  129. void TestCallBack(void)     
  130. {
  131.     dpmiRegs_t rRegs;
  132.  
  133.  
  134.     // install real mode int 99h handler
  135.     p99Handler = new RealInterruptHandler(0x99, HandleRealInt99);
  136.  
  137.     // install call back handler
  138.     pCB99 = new CallBack(CallBack99Handler);
  139.  
  140.     // get real mode paragraph:offset to call back to
  141.     cb99addr = (void (far*)())pCB99->getCallBackAddress();
  142.  
  143.     // create a RealInterrupt for real interrupt 0x99
  144.  
  145.     RealInterrupt real99(0x99);
  146.  
  147.     // set up a register structure to invoke the real int 0x99
  148.     rRegs.drESI.s = 99; rRegs.drSP=rRegs.drSS=0; rRegs.drFlags=0x3202;
  149.  
  150.     // Issue int 0x99 in real mode
  151.     real99(rRegs);
  152.  
  153.     cout << "On return from int 99, si=" << dec 
  154.          << (int)rRegs.drESI.s << "\n";
  155.  
  156.     delete p99Handler;    // unhook real int 99h
  157.     delete pCB99;        // release call back to DPMI host
  158. }
  159.  
  160. void main(void)
  161. {
  162.     DPMIhost dpmi;
  163.  
  164.     if (dpmi.getStatus() == DPMIok)
  165.     {
  166.         dpmi.enterProtectedMode();
  167.         TestRealProcs();
  168.         TestCallBack();
  169.     }
  170.     else
  171.         cout << "DPMI host not present\n";
  172. }