home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / pmod01 / source / pmode.h < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-10  |  11.7 KB  |  320 lines

  1. /****************************************************************************
  2. *
  3. *                          Protected Mode 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 DOS extender independant protected mode
  15. *                programming. This module will need to be included in
  16. *                all programs that use SciTech Software's products that
  17. *                are to be compiled in protected mode, and will need to be
  18. *                compile with the correct defines for the DOS extender that
  19. *                you will be using (or with no defines for real mode
  20. *                emulation of these routines).
  21. *
  22. *                Works with the following:
  23. *
  24. *                    Real Mode DOS (large memory model)
  25. *                    Generic DPMI                * NOT TESTED *
  26. *
  27. *                286 Extenders:
  28. *
  29. *                    Phar Lap 286|DOS Extender    * NO INTERRUPT SUPPORT YET *
  30. *                    Ergo DPM/16                    * NOT TESTED *
  31. *
  32. *                386 Extenders:
  33. *
  34. *                    Phar Lap 386|DOS Extender    * NOT TESTED *
  35. *                    Symantec C++ DOSX
  36. *                    Intel Code Builder            * NOT TESTED *
  37. *                    Ergo OS/386                    * NOT TESTED *
  38. *                    Rational DOS/4GW
  39. *                    DJGPP port of GNU C++        * NOT TESTED *
  40. *                    EMX port of GNU C++            * NOT TESTED *
  41. *
  42. *                Based on ideas and code from the book "Dos and Windows
  43. *                Protected Mode" by Al Williams.
  44. *
  45. * $Id: pmode.h 1.1 1994/03/10 09:05:43 kjb release $
  46. *
  47. ****************************************************************************/
  48.  
  49. #ifndef    __PMODE_H
  50. #define    __PMODE_H
  51.  
  52. #ifndef    __DOS_H
  53. #include <dos.h>
  54. #endif
  55.  
  56. #ifdef  __MSC__
  57. #define MK_FP(s,o)  ( (void far *)( ((unsigned long)(s) << 16) + \
  58.                     (unsigned long)(o) ))
  59. #endif
  60.  
  61. /*--------------------------- Macros and Typedefs -------------------------*/
  62.  
  63. /* You will need to define one of the following before you compile this
  64.  * module for it to work correctly with the DOS extender that you are
  65.  * using. If none is specified, it is assumed you are compiling for DOS
  66.  * real mode.
  67.  *
  68.  *        REALMODE    - Dos real mode
  69.  *        DPMI        - Generic DPMI
  70.  *        PHARLAP286    - Phar Lap 286|DOS Extender
  71.  *        ERGODPM        - Ergo DPM/16
  72.  *        PHARLAP386    - Phar Lap 386|DOS Extender
  73.  *        DOSX        - Symantec C++ DOSX and X32VM
  74.  *        CODEBUILDER    - Intel Code Builder
  75.  *        ERGO386        - Ergo
  76.  *        DOS4GW        - Rational DOS/4GW
  77.  *        DJGPP        - DJGPP port of GNU C++
  78.  *        EMX            - EMX port of GNU C++
  79.  *
  80.  * One of the following will be defined automatically for you when in
  81.  * protected mode (REALMODE will be defined otherwise):
  82.  *
  83.  *        PMODE286    - 286 protected mode
  84.  *        PMODE386    - 386 protected mode
  85.  *
  86.  * Note that for efficiency this library will use near pointers whenever
  87.  * possible to avoid potential performance penalties associated with loading
  88.  * the segment registers in protected mode. Hence the conventional memory
  89.  * area must be mapped into the linear memory space for 32 bit protected
  90.  * mode DOS extenders. Naturally in real mode and 286 protected mode all
  91.  * pointers are far.
  92.  */
  93.  
  94. #if !defined(DOS) && !defined(DPMI) && !defined(PHARLAP286) \
  95.     && !defined(ERGODPM) && !defined(PHARLAP386) && !defined(CODEBUILDER) \
  96.     && !defined(ERGO386) && !defined(DOS4GW) && !defined(DJGPP) \
  97.     && !defined(EMX) && !defined(DOSX)
  98. #define    REALMODE
  99. #endif
  100.  
  101. #if defined(DOS4GW) || defined(ERGO386)
  102. #define    __WATCOM32__
  103. #endif
  104.  
  105. #ifdef    __WATCOM32__
  106. struct _RMWORDREGS {
  107.     unsigned short ax, bx, cx, dx, si, di, cflag, flags;
  108.     };
  109.  
  110. struct _RMBYTEREGS {
  111.     unsigned char   al, ah, bl, bh, cl, ch, dl, dh;
  112.     };
  113.  
  114. typedef union {
  115.     struct  _RMWORDREGS x;
  116.     struct  _RMBYTEREGS h;
  117.     } RMREGS;
  118.  
  119. typedef struct {
  120.     unsigned short  es;
  121.     unsigned short  cs;
  122.     unsigned short  ss;
  123.     unsigned short    ds;
  124.     } RMSREGS;
  125. #else
  126. typedef union REGS RMREGS;
  127. typedef struct SREGS RMSREGS;
  128. #endif
  129.  
  130. #if defined(DJGPP) || defined(EMX)
  131. #define far
  132. #define    cdecl
  133. #define    interrupt
  134. #endif
  135.  
  136. #if defined(DPMI) || defined(PHARLAP286) || defined(ERGODPM)
  137. #define    PMODE286
  138. #else
  139. #if defined(PHARLAP386) || defined(CODEBUILDER) || defined(ERGO386)    \
  140.     || defined(DOS4GW) || defined(DJGPP) || defined(EMX) || defined(DOSX)
  141. #define    PMODE386
  142. #endif
  143. #endif
  144.  
  145. #ifndef    __MSDOS__
  146. #define    __MSDOS__
  147. #endif
  148.  
  149. /* Define a macro for creating physical style address that can be
  150.  * passed directly to PMODE_mapLinearPointer().
  151.  */
  152.  
  153. #define MK_PHYS(s,o)  (((unsigned long)(s) << 4) + (unsigned long)(o))
  154.  
  155. /* Macros for obtaining values from specific offsets away from a passed
  156.  * pointer (such as the BIOS data area).
  157.  */
  158.  
  159. #define    PMODE_getByte(p, off)    (*( (unsigned char *)((char *)(p) + (off)) ))
  160. #define    PMODE_getWord(p, off)    (*( (unsigned short *)((char *)(p) + (off)) ))
  161. #define    PMODE_getLong(p, off)    (*( (unsigned long *)((char *)(p) + (off)) ))
  162. #define    PMODE_setByte(p, off, val) (*( (unsigned char *)((char *)(p) + (off)) ) = (val))
  163. #define    PMODE_setWord(p, off, val) (*( (unsigned short *)((char *)(p) + (off)) ) = (val))
  164. #define    PMODE_setLong(p, off, val) (*( (unsigned long *)((char *)(p) + (off)) ) = (val))
  165.  
  166. /* Define the structure for saving the interrupt vector values. When
  167.  * restoring interrupt vectors, some DOS extenders require the value of
  168.  * both the real and protected mode vectors to be save (DOSX) and others
  169.  * automaticlly restore them all for you on exit. The following structure
  170.  * is used to save the information required by the DOS extender to restore
  171.  * the interrupt vectors correctly.
  172.  */
  173.  
  174. typedef struct {
  175.     void far         *pmode_isr;
  176.     unsigned long    real_isr;
  177.     } SAVEINT;
  178.  
  179. /* Define the different types of modes supported. This is a global variable
  180.  * that can be used to determine the type at runtime which will contain
  181.  * one of these values.
  182.  */
  183.  
  184. enum {
  185.     PMODE_realMode,
  186.     PMODE_286,
  187.     PMODE_386,
  188.     };
  189.  
  190. extern int _PMODE_modeType;
  191.  
  192. /*--------------------------- Function Prototypes -------------------------*/
  193.  
  194. /* Routine to map a pointer to physical memory address (ensure the
  195.  * pointer is freed after you have finished using it). Will return NULL
  196.  * if the pointer could not be allocated. This routine does not _allocate_
  197.  * the memory, but simply provides the translation between a physical
  198.  * memory address and a protected mode pointer for accessing it.
  199.  *
  200.  * Use the macro MK_PHYS() to create a physical base address from a
  201.  * segment and offset to pass to this routine.
  202.  *
  203.  * This routine will only currently works for memory addresses below 1Mb
  204.  * since most extenders allow this to be mapped into near memory.
  205.  * New routines may need to be created to access physical extended memory
  206.  * addresses above 1Mb but the returned pointers will probably have to be
  207.  * declared as far.
  208.  */
  209.  
  210. void * PMODE_mapLinearPointer(long base_address, unsigned limit);
  211. void PMODE_freeLinearPointer(void *ptr);
  212.  
  213. /* Macro to map a real mode style pointer that is specified as a segment
  214.  * and offset within the first Mb of memory. Simple translates this into
  215.  * a physical address and calls the above routine.
  216.  */
  217.  
  218. #define    PMODE_mapRealPointer(p, limit)    \
  219.     PMODE_mapLinearPointer( (((unsigned long)(p) & 0xFFFF0000) >> 12) + \
  220.         ((unsigned long)(p) & 0xFFFF), limit)
  221. #define    PMODE_freeRealPointer(p)    PMODE_freeLinearPointer(p)
  222.  
  223. /* Routine to return a pointer to the BIOS data area starting at 0x40
  224.  * to the calling program. This is a global pointer maintained by the
  225.  * PMODE library and will never be freed.
  226.  */
  227.  
  228. void * PMODE_getBIOSPointer(void);
  229.  
  230. /* Routine to allocate a block of conventional memory below the 1Mb
  231.  * limit so that it can be accessed from real mode. Ensure that you free
  232.  * the segment when you are done with it.
  233.  *
  234.  * This routine returns a protected mode pointer to the segment that has
  235.  * been allocated, and also returns the physical segment address which can
  236.  * be passed to real mode routines. Will return NULL if memory could not
  237.  * be allocated.
  238.  *
  239.  * Please note that with some DOS extenders, memory allocated with the
  240.  * following function cannot be freed, hence it will be allocated for the
  241.  * life of your program. Thus if you need to call a bunch of different
  242.  * real-mode routines in your program, allocate a single large buffer
  243.  * that can be re-used throughout the program execution.
  244.  */
  245.  
  246. void * PMODE_allocRealSeg(unsigned short size, unsigned long *segid,
  247.     unsigned *segment, unsigned *offset);
  248. void PMODE_freeRealSeg(unsigned long segid);
  249.  
  250. /* Routine to create a code segment alias for a data pointer so that code
  251.  * can be executed on the heap. This pointer is a near pointer as it is
  252.  * near impossible to create a far code segment pointer with most extenders.
  253.  */
  254.  
  255. void * PMODE_createCSAlias(void *dataptr);
  256. void PMODE_freeCSAlias(void *alias);
  257.  
  258. /* Routine to create a data segment alias for a code segment that can be
  259.  * used to modify code in the code segment. This pointer has to be a far
  260.  * pointer, as the normal near DS segment of most DOS extenders wont allow
  261.  * you to overwrite the code segment (or obvious reasons ;-).
  262.  */
  263.  
  264. void far * PMODE_createDSAlias(void (*codeptr)());
  265. void PMODE_freeDSAlias(void far *alias);
  266.  
  267. /* Routines to generate real mode interrupts using the same interface that
  268.  * is used by int86() and int86x() in realmode. This routine is need to
  269.  * call certain BIOS and DOS functions that are not supported by some
  270.  * DOS extenders. No translation is done on any of the register values,
  271.  * so they must be correctly set up and translated by the calling program.
  272.  *
  273.  * Normally the DOS extenders will allow you to use the normal int86()
  274.  * function directly and will pass on unhandled calls to real mode to be
  275.  * handled by the real mode handler. However calls to int86x() with real
  276.  * mode segment values to be loaded will cause a GPF if used with the
  277.  * standard int86x(), so you should use these routines if you know you
  278.  * want to call a real mode handler.
  279.  */
  280.  
  281. int PMODE_int86(int intno, RMREGS *in, RMREGS *out);
  282. int PMODE_int86x(int intno, RMREGS *in, RMREGS *out,
  283.     RMSREGS *sregs);
  284.  
  285. /* Routine to install a mouse interrupt handling routine. The routine to
  286.  * be called is a native real or protected mode assembly language routine.
  287.  * The real mode equivalent to this is to install the routine with the
  288.  * mouse Int 33h function 12 or 20 system call. Most DOS extenders directly
  289.  * support this interface in protected mode, but for those that do not a
  290.  * real mode routine will need to be installed that will pass up control
  291.  * to the appropriate protected mode routine. A mouse soft (function 33)
  292.  * or hard (function 0) reset will remove this routine. Will return 0 if
  293.  * the routine could not be successfully installed.
  294.  *
  295.  * Note that the mouse handler routine _must_ be a far function and return
  296.  * with a far return. It must also load and restore the value of DS as this
  297.  * register will not contain the correct value for the current data segment
  298.  * when called by the mouse interrupt handler.
  299.  */
  300.  
  301. int PMODE_installMouseHandler(int mask, void (cdecl far *handler)());
  302.  
  303. /* Routines to save and restore interrupt handling routines. The routines
  304.  * will install a _protected mode_ interrupt handling routine that will
  305.  * get control in protected mode whenever an interrupt occurs in either real
  306.  * mode or protected mode. Only one handler is installed, and it is up to
  307.  * the DOS extender or the PMODE library to ensure that real mode interrupts
  308.  * are passed up to the protected mode handler. This is effectively
  309.  * analogous to the standard real mode setvect and getvect style routines.
  310.  * If you require special BI-MODAL interrupt handling routines (ie: dual
  311.  * real mode and protected mode routines) you will need to do some DOS
  312.  * extender specific programming.
  313.  */
  314.  
  315. void far * PMODE_getISR(int intno, SAVEINT *save);
  316. void PMODE_setISR(int intno, void far *isr);
  317. void PMODE_restoreISR(int intno, SAVEINT *save);
  318.  
  319. #endif /* __PMODE_H */
  320.