home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / programming / misc_programming / INCLUDE / PMODE.H < prev    next >
C/C++ Source or Header  |  1994-08-22  |  14KB  |  383 lines

  1. /****************************************************************************
  2. *
  3. *                         PM/Lite and PM/Pro Library
  4. *
  5. *                    Copyright (C) 1994 SciTech Software.
  6. *                            All rights reserved.
  7. *
  8. * Filename:        $RCSfile: pmode.h $
  9. * Version:        $Revision: 1.1 $
  10. *
  11. * Language:        ANSI C
  12. * Environment:    Real mode and 16/32 bit Protected Mode under MSDOS
  13. *
  14. * Description:    Header file for the DOS extender independant protected
  15. *                mode programming library. This library will need to be
  16. *                included in all programs that use SciTech Software's
  17. *                products that are to be compiled in protected mode.
  18. *
  19. *                This library provides pre-built selectors for the BIOS
  20. *                data area and VGA frame buffer, and methods for allocating
  21. *                your own selectors for physical memory. It also returns
  22. *                appropriate selectors for accessing memory allocated in
  23. *                the low DOS 1Mb memory area, and routines for accessing
  24. *                memory through a selector and offset. By using selectors
  25. *                for accessing memory outside of the applications linear
  26. *                address space, your code will be fully DPMI compliant and
  27. *                will run under Windows 3.1 and OS/2 2.x DOS boxes.
  28. *
  29. *                This Professional version of this library also provides
  30. *                simplified interrupt handling, allowing all common interrupt
  31. *                handlers to be hooked and handled directly with normal C
  32. *                functions, both in 16 bit and 32 bit modes. Note however that
  33. *                simplified handling does not mean slow performance! All low
  34. *                level interrupt handling is done efficiently in assembler
  35. *                for speed (well actually necessary to insulate the
  36. *                application from the lack of far pointers in 32 bit PM). The
  37. *                interrupt handlers currently supported are:
  38. *
  39. *                    Mouse (0x33 callback)
  40. *                   Timer Tick (0x8)
  41. *                    Keyboard (0x9)
  42. *                    Control C/Break (0x23/0x1B)
  43. *                    Critical Error (0x24)
  44. *
  45. *                Note that all interrupt handlers are correctly hooked to
  46. *                ensure that control is always recieved in protected mode.
  47. *
  48. *                Works with the following:
  49. *
  50. *                    Real Mode DOS (large memory model)
  51. *
  52. *                286 Extenders:
  53. *
  54. *                    Windows 3.1 DPMI
  55. *                    Borland DPMI16
  56. *
  57. *                386 Extenders:
  58. *
  59. *                    Windows 3.1 DPMI (Win32s)
  60. *                    Phar Lap TNT DOS Extender
  61. *                    FlashTek DOSX/X32-VM
  62. *                    Borland DPMI32
  63. *                    Rational DOS/4GW
  64. *                    DJGPP go32 for GNU C++            * NO SELECTORS YET!! *
  65. *
  66. *                Currently supports the following compilers:
  67. *
  68. *                    Borland C++ 3.1
  69. *                    Borland C++ 4.0, 16 bit
  70. *                    Borland C++ 4.0, 32 bit
  71. *                    Microsoft Visual C++ 1.5, 16 bit * NOT TESTED YET    *
  72. *                    Microsoft Visual C++ 1.5, 32 bit * NOT TESTED YET    *
  73. *                    Symantec C++ 6.1, 16 bit
  74. *                    Symantec C++ 6.1, 32 bit
  75. *                    Watcom C++ 10.0, 16 bit
  76. *                    Watcom C++ 10.0, 32 bit
  77. *                    Metaware High C++ 3.21, 32 bit
  78. *                    DJGPP port of GNU C++, 32 bit    * NO SELECTORS YET!! *
  79. *
  80. * $Id: pmode.h 1.1 1994/08/22 07:46:56 kjb release $
  81. *
  82. ****************************************************************************/
  83.  
  84. #ifndef    __PMODE_H
  85. #define    __PMODE_H
  86.  
  87. #ifndef    __DOS_H
  88. #include <dos.h>
  89. #endif
  90.  
  91. /*--------------------------- Macros and Typedefs -------------------------*/
  92.  
  93. /* You will need to define one of the following before you compile this
  94.  * library for it to work correctly with the DOS extender that you are
  95.  * using. If none is specified, it is assumed you are compiling for DOS
  96.  * real mode.
  97.  *
  98.  *        REALMODE    - Dos real mode
  99.  *        WINDPMI16    - Windows 3.1 16 bit DPMI
  100.  *        DPMI16        - Borland's DPMI16 DOS Power Pack Extender
  101.  *        WINDPMI32    - Windows 3.1 32 bit DPMI
  102.  *        TNT            - Phar Lap TNT DOS Extender
  103.  *        DOSX        - Symantec C++ DOSX and Flashtek X32VM
  104.  *        DPMI32        - Borland's DPMI32 DOS Power Pack Extender
  105.  *        DOS4GW        - Rational DOS/4GW and DOS/4GW Professional
  106.  *        DJGPP        - DJGPP port of GNU C++
  107.  *
  108.  * One of the following will be defined automatically for you when in
  109.  * protected mode (REALMODE will be defined otherwise):
  110.  *
  111.  *        PM286    - 286 protected mode
  112.  *        PM386    - 386 protected mode
  113.  */
  114.  
  115. #if    defined(TNT) || defined(DOSX) || defined(DPMI32) || defined(DOS4GW)    \
  116.     || defined(DJGPP) || defined(WINDPMI32)
  117. #define    PM386
  118. #elif defined(DPMI16) || defined(WINDPMI16)
  119. #define    PM286
  120. #else
  121. #define    REALMODE
  122. #endif
  123.  
  124. /* Provide definitions for the real mode register structures passed to
  125.  * the PM_int86() and PM_int86x() routines.
  126.  */
  127.  
  128. #if defined(REALMODE) || defined(PM286) || defined(__SC__)
  129. typedef union REGS RMREGS;
  130. typedef struct SREGS RMSREGS;
  131. #else
  132. struct _RMWORDREGS {
  133.     unsigned short ax, bx, cx, dx, si, di, cflag, flags;
  134.     };
  135.  
  136. struct _RMBYTEREGS {
  137.     unsigned char   al, ah, bl, bh, cl, ch, dl, dh;
  138.     };
  139.  
  140. typedef union {
  141.     struct  _RMWORDREGS x;
  142.     struct  _RMBYTEREGS h;
  143.     } RMREGS;
  144.  
  145. typedef struct {
  146.     unsigned short  es;
  147.     unsigned short  cs;
  148.     unsigned short  ss;
  149.     unsigned short    ds;
  150.     } RMSREGS;
  151. #endif
  152.  
  153. #ifdef DJGPP
  154. #define    _cdecl        /* GCC doesn't know about _cdecl modifiers            */
  155. #endif
  156.  
  157. /* For the Metaware High C/C++ compiler, there is no _cdecl calling
  158.  * convention. The conventions can be changed, but it is a complicated
  159.  * process involving #pragmas, and all externally referenced functions
  160.  * will use stack based calling conventions. We also need to change the
  161.  * global aliasing conventions to use underscores for external function
  162.  * and variables names, so that our assembler routines will link
  163.  * correctly (except of course the main function - man what a PAIN!).
  164.  */
  165.  
  166. #ifdef    __HIGHC__
  167. #define    _cdecl
  168. #pragma Global_aliasing_convention("_%r")
  169. extern main();
  170. #pragma Alias(main,"main")
  171. #endif
  172.  
  173. #ifndef    __MSDOS__
  174. #define    __MSDOS__
  175. #endif
  176.  
  177. /* Define a macro for creating physical base addresses from segment:offset */
  178.  
  179. #define MK_PHYS(s,o)  (((unsigned long)(s) << 4) + (unsigned long)(o))
  180.  
  181. /* Define the different types of modes supported. This is a global variable
  182.  * that can be used to determine the type at runtime which will contain
  183.  * one of these values.
  184.  */
  185.  
  186. typedef enum {
  187.     PM_realMode,
  188.     PM_286,
  189.     PM_386,
  190.     } PM_mode_enum;
  191.  
  192. /* Define the different types of interrupt handlers that we support        */
  193.  
  194. typedef void (* _cdecl PM_intHandler)(void);
  195. typedef void (* _cdecl PM_breakHandler)(int ctrlBreakHit);
  196. typedef void (* _cdecl PM_criticalHandler)(int *ax,int *di);
  197. typedef void (* _cdecl PM_mouseHandler)(unsigned mask, unsigned butstate,
  198.     unsigned x,unsigned y);
  199.  
  200. extern int _PM_modeType;
  201.  
  202. /*--------------------------- Function Prototypes -------------------------*/
  203.  
  204. #ifdef    __cplusplus
  205. extern "C" {            /* Use "C" linkage when in C++ mode    */
  206. #endif
  207.  
  208. /* Routines to access data through a selector and offset. For real mode
  209.  * and 16 bit protected mode, the offset can only be a maximum of 64k.
  210.  */
  211.  
  212. unsigned char _cdecl PM_getByte(unsigned s, unsigned o);
  213. unsigned short _cdecl PM_getWord(unsigned s, unsigned o);
  214. unsigned long _cdecl PM_getLong(unsigned s, unsigned o);
  215. void _cdecl PM_setByte(unsigned s, unsigned o, unsigned char v);
  216. void _cdecl PM_setWord(unsigned s, unsigned o, unsigned short v);
  217. void _cdecl PM_setLong(unsigned s, unsigned o, unsigned long v);
  218.  
  219. /* Routines for copying data between the applications data space and
  220.  * memory accessible through a selector and offset.
  221.  */
  222.  
  223. void _cdecl PM_memcpynf(void *dst,unsigned src_s,unsigned src_o,unsigned n);
  224. void _cdecl PM_memcpyfn(unsigned dst_s,unsigned dst_o,void *src,unsigned n);
  225.  
  226. /* Routine to return a selector to the BIOS data area at segment 0x40 */
  227.  
  228. unsigned PM_getBIOSSelector(void);
  229.  
  230. /* Routine to return a selector to the VGA frame buffer. The selector
  231.  * will map to the correct portion of video memory depending on the
  232.  * current video mode (0x3, 0x7 or graphics).
  233.  */
  234.  
  235. unsigned PM_getVGASelector(void);
  236.  
  237. /* Routine to get a selector:offset for accessing a low 1Mb memory block.
  238.  * You dont need to free this pointer, but in 16 bit protected mode
  239.  * the selector allocated will be re-used the next time this routine is
  240.  * called. If you need a permanent selector, allocate it with
  241.  * PM_createSelector instead.
  242.  */
  243.  
  244. void PM_mapRealPointer(unsigned *sel,unsigned *off,unsigned r_seg,
  245.     unsigned r_off);
  246.  
  247. /* Routine to create an arbritray selector to physical memory */
  248.  
  249. unsigned PM_createSelector(unsigned long base,unsigned limit);
  250. void PM_freeSelector(unsigned sel);
  251.  
  252. /* Routine to allocate a block of conventional memory below the 1Mb
  253.  * limit so that it can be accessed from real mode. Ensure that you free
  254.  * the segment when you are done with it.
  255.  *
  256.  * This routine returns a selector and offset to the segment that has been
  257.  * allocated, and also returns the real mode segment and offset which can
  258.  * be passed to real mode routines. Will return 0 if memory could not be
  259.  * allocated.
  260.  *
  261.  * Please note that with some DOS extenders, memory allocated with the
  262.  * following function cannot be freed, hence it will be allocated for the
  263.  * life of your program. Thus if you need to call a bunch of different
  264.  * real-mode routines in your program, allocate a single large buffer at
  265.  * program startup that can be re-used throughout the program execution.
  266.  */
  267.  
  268. int PM_allocRealSeg(unsigned size,unsigned *sel,unsigned *off,
  269.     unsigned *r_seg,unsigned *r_off);
  270. void PM_freeRealSeg(unsigned sel,unsigned off);
  271.  
  272. /* Routine to call a real mode assembly language procedure. Register
  273.  * values are passed in and out in the 'regs' and 'sregs' structures. We
  274.  * do not provide any method of copying data from the protected mode stack
  275.  * to the real mode stack, so if you need to pass data to real mode, you will
  276.  * need to write a real mode assembly language hook to recieve the values
  277.  * in registers, and to pass the data through a real mode block allocated
  278.  * with the PM_allocRealSeg() routine.
  279.  */
  280.  
  281. void _cdecl PM_callRealMode(unsigned seg,unsigned off, RMREGS *regs,
  282.     RMSREGS *sregs);
  283.  
  284. /* Routines to generate real mode interrupts using the same interface that
  285.  * is used by int86() and int86x() in realmode. This routine is need to
  286.  * call certain BIOS and DOS functions that are not supported by some
  287.  * DOS extenders. No translation is done on any of the register values,
  288.  * so they must be correctly set up and translated by the calling program.
  289.  *
  290.  * Normally the DOS extenders will allow you to use the normal int86()
  291.  * function directly and will pass on unhandled calls to real mode to be
  292.  * handled by the real mode handler. However calls to int86x() with real
  293.  * mode segment values to be loaded will cause a GPF if used with the
  294.  * standard int86x(), so you should use these routines if you know you
  295.  * want to call a real mode handler.
  296.  */
  297.  
  298. int PM_int86(int intno, RMREGS *in, RMREGS *out);
  299. int PM_int86x(int intno, RMREGS *in, RMREGS *out,
  300.     RMSREGS *sregs);
  301.  
  302. /*------------- Functions in Professional version only --------------------*/
  303.  
  304. /* Routine to install a mouse interrupt handling routine. The
  305.  * mouse handler routine is a normal C function, and the PM library
  306.  * will take care of passing the correct parameters to the function,
  307.  * and switching to a local stack.
  308.  *
  309.  * Note that you _must_ lock the memory containing the mouse interrupt
  310.  * handler with the PM_lockPages() function otherwise you may encounter
  311.  * problems in virtual memory environments.
  312.  */
  313.  
  314. int PM_setMouseHandler(int mask,PM_mouseHandler mh);
  315. void PM_restoreMouseHandler(void);
  316.  
  317. /* Routine to reset the mouse driver, and re-install the current
  318.  * mouse interrupt handler if one was currently installed (since the
  319.  * mouse reset will automatically remove this handler.
  320.  */
  321.  
  322. void PM_resetMouseDriver(int hardReset);
  323.  
  324. /* Routines to install and remove timer and keyboard interrupt handlers.
  325.  * The handler routines are normal C functions. If the return value from
  326.  * the function is PM_chainInt, the previous handler will be chained
  327.  * to, otherwise the interrupt will simply return.
  328.  *
  329.  * Note that you _must_ lock the memory containing the interrupt
  330.  * handlers with the PM_lockPages() function otherwise you may encounter
  331.  * problems in virtual memory environments.
  332.  */
  333.  
  334. void PM_setTimerHandler(PM_intHandler ih);
  335. void _cdecl PM_chainPrevTimer(void);
  336. void PM_restoreTimerHandler(void);
  337. void PM_setKeyHandler(PM_intHandler ih);
  338. void _cdecl PM_chainPrevKey(void);
  339. void PM_restoreKeyHandler(void);
  340.  
  341. /* Routines to install and remove the control c/break interrupt handler.
  342.  * The handler is a normal C functions, that takes a boolean flag as a
  343.  * parameter. This flag will be 1 if the control break key caused the
  344.  * interrupt, or 0 if Ctrl-C caused the interrupt.
  345.  */
  346.  
  347. void PM_setBreakHandler(PM_breakHandler bh);
  348. void PM_restoreBreakHandler(void);
  349.  
  350. /* Routines to install and remove the critical error handler. The handler
  351.  * is a normal C function that takes a pointer to the value in register
  352.  * AX a pointer to the value in DI that was passed up from DOS. These
  353.  * values are used to determine the cause of the critical error, and to
  354.  * handle it appropriately.
  355.  */
  356.  
  357. void PM_setCriticalHandler(PM_criticalHandler ch);
  358. void PM_restoreCriticalHandler(void);
  359.  
  360. /* Routine to lock and unlock regions of memory under a virtual memory
  361.  * environment. These routines _must_ be used to lock all hardware
  362.  * and mouse interrupt handlers installed, _AND_ any global data that
  363.  * these handler manipulate, so that they will always be present in memory
  364.  * to handle the incoming interrupts.
  365.  *
  366.  * Note that it is important to call the correct routine depending on
  367.  * whether the area being locked is code or data, so that under 32 bit
  368.  * PM we will get the selector value correct.
  369.  */
  370.  
  371. typedef void (*__codePtr)();
  372.  
  373. int PM_lockDataPages(void *p,unsigned len);
  374. int PM_unlockDataPages(void *p,unsigned len);
  375. int PM_lockCodePages(__codePtr p,unsigned len);
  376. int PM_unlockCodePages(__codePtr p,unsigned len);
  377.  
  378. #ifdef    __cplusplus
  379. }                        /* End of "C" linkage for C++    */
  380. #endif
  381.  
  382. #endif /* __PMODE_H */
  383.