home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- *
- * Protected Mode Library
- *
- * Copyright (C) 1994 SciTech Software.
- * All rights reserved.
- *
- * Filename: $RCSfile: pmode.h $
- * Version: $Revision: 1.1 $
- *
- * Language: ANSI C
- * Environment: Real mode and 16/32 bit Protected Mode under MSDOS
- *
- * Description: Header file for DOS extender independant protected mode
- * programming. This module will need to be included in
- * all programs that use SciTech Software's products that
- * are to be compiled in protected mode, and will need to be
- * compile with the correct defines for the DOS extender that
- * you will be using (or with no defines for real mode
- * emulation of these routines).
- *
- * Works with the following:
- *
- * Real Mode DOS (large memory model)
- * Generic DPMI * NOT TESTED *
- *
- * 286 Extenders:
- *
- * Phar Lap 286|DOS Extender * NO INTERRUPT SUPPORT YET *
- * Ergo DPM/16 * NOT TESTED *
- *
- * 386 Extenders:
- *
- * Phar Lap 386|DOS Extender * NOT TESTED *
- * Symantec C++ DOSX
- * Intel Code Builder * NOT TESTED *
- * Ergo OS/386 * NOT TESTED *
- * Rational DOS/4GW
- * DJGPP port of GNU C++ * NOT TESTED *
- * EMX port of GNU C++ * NOT TESTED *
- *
- * Based on ideas and code from the book "Dos and Windows
- * Protected Mode" by Al Williams.
- *
- * $Id: pmode.h 1.1 1994/03/10 09:05:43 kjb release $
- *
- ****************************************************************************/
-
- #ifndef __PMODE_H
- #define __PMODE_H
-
- #ifndef __DOS_H
- #include <dos.h>
- #endif
-
- #ifdef __MSC__
- #define MK_FP(s,o) ( (void far *)( ((unsigned long)(s) << 16) + \
- (unsigned long)(o) ))
- #endif
-
- /*--------------------------- Macros and Typedefs -------------------------*/
-
- /* You will need to define one of the following before you compile this
- * module for it to work correctly with the DOS extender that you are
- * using. If none is specified, it is assumed you are compiling for DOS
- * real mode.
- *
- * REALMODE - Dos real mode
- * DPMI - Generic DPMI
- * PHARLAP286 - Phar Lap 286|DOS Extender
- * ERGODPM - Ergo DPM/16
- * PHARLAP386 - Phar Lap 386|DOS Extender
- * DOSX - Symantec C++ DOSX and X32VM
- * CODEBUILDER - Intel Code Builder
- * ERGO386 - Ergo
- * DOS4GW - Rational DOS/4GW
- * DJGPP - DJGPP port of GNU C++
- * EMX - EMX port of GNU C++
- *
- * One of the following will be defined automatically for you when in
- * protected mode (REALMODE will be defined otherwise):
- *
- * PMODE286 - 286 protected mode
- * PMODE386 - 386 protected mode
- *
- * Note that for efficiency this library will use near pointers whenever
- * possible to avoid potential performance penalties associated with loading
- * the segment registers in protected mode. Hence the conventional memory
- * area must be mapped into the linear memory space for 32 bit protected
- * mode DOS extenders. Naturally in real mode and 286 protected mode all
- * pointers are far.
- */
-
- #if !defined(DOS) && !defined(DPMI) && !defined(PHARLAP286) \
- && !defined(ERGODPM) && !defined(PHARLAP386) && !defined(CODEBUILDER) \
- && !defined(ERGO386) && !defined(DOS4GW) && !defined(DJGPP) \
- && !defined(EMX) && !defined(DOSX)
- #define REALMODE
- #endif
-
- #if defined(DOS4GW) || defined(ERGO386)
- #define __WATCOM32__
- #endif
-
- #ifdef __WATCOM32__
- struct _RMWORDREGS {
- unsigned short ax, bx, cx, dx, si, di, cflag, flags;
- };
-
- struct _RMBYTEREGS {
- unsigned char al, ah, bl, bh, cl, ch, dl, dh;
- };
-
- typedef union {
- struct _RMWORDREGS x;
- struct _RMBYTEREGS h;
- } RMREGS;
-
- typedef struct {
- unsigned short es;
- unsigned short cs;
- unsigned short ss;
- unsigned short ds;
- } RMSREGS;
- #else
- typedef union REGS RMREGS;
- typedef struct SREGS RMSREGS;
- #endif
-
- #if defined(DJGPP) || defined(EMX)
- #define far
- #define cdecl
- #define interrupt
- #endif
-
- #if defined(DPMI) || defined(PHARLAP286) || defined(ERGODPM)
- #define PMODE286
- #else
- #if defined(PHARLAP386) || defined(CODEBUILDER) || defined(ERGO386) \
- || defined(DOS4GW) || defined(DJGPP) || defined(EMX) || defined(DOSX)
- #define PMODE386
- #endif
- #endif
-
- #ifndef __MSDOS__
- #define __MSDOS__
- #endif
-
- /* Define a macro for creating physical style address that can be
- * passed directly to PMODE_mapLinearPointer().
- */
-
- #define MK_PHYS(s,o) (((unsigned long)(s) << 4) + (unsigned long)(o))
-
- /* Macros for obtaining values from specific offsets away from a passed
- * pointer (such as the BIOS data area).
- */
-
- #define PMODE_getByte(p, off) (*( (unsigned char *)((char *)(p) + (off)) ))
- #define PMODE_getWord(p, off) (*( (unsigned short *)((char *)(p) + (off)) ))
- #define PMODE_getLong(p, off) (*( (unsigned long *)((char *)(p) + (off)) ))
- #define PMODE_setByte(p, off, val) (*( (unsigned char *)((char *)(p) + (off)) ) = (val))
- #define PMODE_setWord(p, off, val) (*( (unsigned short *)((char *)(p) + (off)) ) = (val))
- #define PMODE_setLong(p, off, val) (*( (unsigned long *)((char *)(p) + (off)) ) = (val))
-
- /* Define the structure for saving the interrupt vector values. When
- * restoring interrupt vectors, some DOS extenders require the value of
- * both the real and protected mode vectors to be save (DOSX) and others
- * automaticlly restore them all for you on exit. The following structure
- * is used to save the information required by the DOS extender to restore
- * the interrupt vectors correctly.
- */
-
- typedef struct {
- void far *pmode_isr;
- unsigned long real_isr;
- } SAVEINT;
-
- /* Define the different types of modes supported. This is a global variable
- * that can be used to determine the type at runtime which will contain
- * one of these values.
- */
-
- enum {
- PMODE_realMode,
- PMODE_286,
- PMODE_386,
- };
-
- extern int _PMODE_modeType;
-
- /*--------------------------- Function Prototypes -------------------------*/
-
- /* Routine to map a pointer to physical memory address (ensure the
- * pointer is freed after you have finished using it). Will return NULL
- * if the pointer could not be allocated. This routine does not _allocate_
- * the memory, but simply provides the translation between a physical
- * memory address and a protected mode pointer for accessing it.
- *
- * Use the macro MK_PHYS() to create a physical base address from a
- * segment and offset to pass to this routine.
- *
- * This routine will only currently works for memory addresses below 1Mb
- * since most extenders allow this to be mapped into near memory.
- * New routines may need to be created to access physical extended memory
- * addresses above 1Mb but the returned pointers will probably have to be
- * declared as far.
- */
-
- void * PMODE_mapLinearPointer(long base_address, unsigned limit);
- void PMODE_freeLinearPointer(void *ptr);
-
- /* Macro to map a real mode style pointer that is specified as a segment
- * and offset within the first Mb of memory. Simple translates this into
- * a physical address and calls the above routine.
- */
-
- #define PMODE_mapRealPointer(p, limit) \
- PMODE_mapLinearPointer( (((unsigned long)(p) & 0xFFFF0000) >> 12) + \
- ((unsigned long)(p) & 0xFFFF), limit)
- #define PMODE_freeRealPointer(p) PMODE_freeLinearPointer(p)
-
- /* Routine to return a pointer to the BIOS data area starting at 0x40
- * to the calling program. This is a global pointer maintained by the
- * PMODE library and will never be freed.
- */
-
- void * PMODE_getBIOSPointer(void);
-
- /* Routine to allocate a block of conventional memory below the 1Mb
- * limit so that it can be accessed from real mode. Ensure that you free
- * the segment when you are done with it.
- *
- * This routine returns a protected mode pointer to the segment that has
- * been allocated, and also returns the physical segment address which can
- * be passed to real mode routines. Will return NULL if memory could not
- * be allocated.
- *
- * Please note that with some DOS extenders, memory allocated with the
- * following function cannot be freed, hence it will be allocated for the
- * life of your program. Thus if you need to call a bunch of different
- * real-mode routines in your program, allocate a single large buffer
- * that can be re-used throughout the program execution.
- */
-
- void * PMODE_allocRealSeg(unsigned short size, unsigned long *segid,
- unsigned *segment, unsigned *offset);
- void PMODE_freeRealSeg(unsigned long segid);
-
- /* Routine to create a code segment alias for a data pointer so that code
- * can be executed on the heap. This pointer is a near pointer as it is
- * near impossible to create a far code segment pointer with most extenders.
- */
-
- void * PMODE_createCSAlias(void *dataptr);
- void PMODE_freeCSAlias(void *alias);
-
- /* Routine to create a data segment alias for a code segment that can be
- * used to modify code in the code segment. This pointer has to be a far
- * pointer, as the normal near DS segment of most DOS extenders wont allow
- * you to overwrite the code segment (or obvious reasons ;-).
- */
-
- void far * PMODE_createDSAlias(void (*codeptr)());
- void PMODE_freeDSAlias(void far *alias);
-
- /* Routines to generate real mode interrupts using the same interface that
- * is used by int86() and int86x() in realmode. This routine is need to
- * call certain BIOS and DOS functions that are not supported by some
- * DOS extenders. No translation is done on any of the register values,
- * so they must be correctly set up and translated by the calling program.
- *
- * Normally the DOS extenders will allow you to use the normal int86()
- * function directly and will pass on unhandled calls to real mode to be
- * handled by the real mode handler. However calls to int86x() with real
- * mode segment values to be loaded will cause a GPF if used with the
- * standard int86x(), so you should use these routines if you know you
- * want to call a real mode handler.
- */
-
- int PMODE_int86(int intno, RMREGS *in, RMREGS *out);
- int PMODE_int86x(int intno, RMREGS *in, RMREGS *out,
- RMSREGS *sregs);
-
- /* Routine to install a mouse interrupt handling routine. The routine to
- * be called is a native real or protected mode assembly language routine.
- * The real mode equivalent to this is to install the routine with the
- * mouse Int 33h function 12 or 20 system call. Most DOS extenders directly
- * support this interface in protected mode, but for those that do not a
- * real mode routine will need to be installed that will pass up control
- * to the appropriate protected mode routine. A mouse soft (function 33)
- * or hard (function 0) reset will remove this routine. Will return 0 if
- * the routine could not be successfully installed.
- *
- * Note that the mouse handler routine _must_ be a far function and return
- * with a far return. It must also load and restore the value of DS as this
- * register will not contain the correct value for the current data segment
- * when called by the mouse interrupt handler.
- */
-
- int PMODE_installMouseHandler(int mask, void (cdecl far *handler)());
-
- /* Routines to save and restore interrupt handling routines. The routines
- * will install a _protected mode_ interrupt handling routine that will
- * get control in protected mode whenever an interrupt occurs in either real
- * mode or protected mode. Only one handler is installed, and it is up to
- * the DOS extender or the PMODE library to ensure that real mode interrupts
- * are passed up to the protected mode handler. This is effectively
- * analogous to the standard real mode setvect and getvect style routines.
- * If you require special BI-MODAL interrupt handling routines (ie: dual
- * real mode and protected mode routines) you will need to do some DOS
- * extender specific programming.
- */
-
- void far * PMODE_getISR(int intno, SAVEINT *save);
- void PMODE_setISR(int intno, void far *isr);
- void PMODE_restoreISR(int intno, SAVEINT *save);
-
- #endif /* __PMODE_H */
-