/* PLTYPES.H - Definitions for Phar Lap standard data types 		*/
/* $Id: pltypes.h 2.1 93/01/13 13:09:42 rwm Exp $ */
/************************************************************************/
/*	Copyright (C) 1986-1993 Phar Lap Software, Inc.			*/
/*	Unpublished - rights reserved under the Copyright Laws of the	*/
/*	United States.  Use, duplication, or disclosure by the 		*/
/*	Government is subject to restrictions as set forth in 		*/
/*	subparagraph (c)(1)(ii) of the Rights in Technical Data and 	*/
/*	Computer Software clause at 252.227-7013.			*/
/*	Phar Lap Software, Inc., 60 Aberdeen Ave., Cambridge, MA 02138	*/
/************************************************************************/

#ifndef PLTYPES
#define PLTYPES

/*
 * Define the symbol __MSC32__ if we are compiling with a Microsoft C 32-bit
 * compiler
 */
#if defined(_MSC_VER) && (_M_IX86 >= 300)
/* It's a Microsoft compiler, with a target of an 80386 or later */
#define __MSC32__
#endif

/*
 * Compiler features, used to control data type and function prototype
 * setup here, and in PHARLAP.H and PLDOS32.H
 *
 * We set up features for Microsoft 32-bit C/C++, MetaWare High C/C++,
 * and Watcom C/386 here.  For other compilers, we assume all features
 * are supported;  if this is not the case for your compiler, set up
 * __CMPLR_FEATURES__ appropriately here.
 */
#define __FEATURE_FARPTR__	0x00000001	// FAR pointers supported
#define __FEATURE_DOSCALL__	0x00000002	// _dos_, _bios_, _intdosx, 
						// _int86x calls supported in
						// C run-time library

#ifdef __MSC32__
// Microsoft 32-bit C/C++
#define __CMPLR_FEATURES__	0
#endif

#if defined(__HIGHC__) || defined(__WATCOMC__)
// MetaWare High C/C++ and Watcom C/386
#define __CMPLR_FEATURES__	(__FEATURE_FARPTR__ | __FEATURE_DOSCALL__)
#endif

#ifndef __CMPLR_FEATURES__
// Assume other compilers support all features
#define __CMPLR_FEATURES__	(__FEATURE_FARPTR__ | __FEATURE_DOSCALL__)
#endif

/*
 * Keyword used to force stack-based calling conventions in function prototypes
 * for Phar Lap library routines in PHARLAP.H and PLDOS32.H, even if 
 * compiling with register-based calling conventions.
 */
#define __STKCALL		/* define to nothing by default */
#ifdef __HIGHC__
#undef __STKCALL
//#define __STKCALL _CC(_CALLING_CONVENTION & ~_ARGS_IN_REGS)
// High C won't let you turn off reg-based arg passing on an individual
// basis when it's turned on globally.  However, (at least in version 3.03)
// it's always disabled anyway as long as the function isn't declared static.
#define __STKCALL
#endif
#if defined(__WATCOMC__) || defined(__MSC32__)
#undef __STKCALL
#define __STKCALL __cdecl	/* This works for Microsoft and Watcom */
#endif

/*
 * Basic data types and constants.  Some of these are conditionally defined
 * to prevent conflicts with include files for various compilers or
 * operating systems
 */
#ifndef STDPL		/* defined if internal Phar Lap header file included */
#ifndef OS2_INCLUDED	/* defined if OS2.H is included before this file */

typedef unsigned char UCHAR;	/* unsigned 8-bit value */
typedef short SHORT;		/* signed 16-bit value */
typedef unsigned short USHORT;	/* unsigned 16-bit value */
typedef unsigned int UINT;	/* unsigned integer */
#ifndef LONG	/* some folks like to #define LONG */
typedef long LONG;		/* signed 32-bit value */
#endif	/* LONG */
typedef unsigned long ULONG;	/* unsigned 32-bit value */
/* NOTE - BOOL is a conflicting data type between OS2 and DOSX */
typedef int BOOL;		/* Boolean value */

#define TRUE	1		/* Boolean true */
#define FALSE	0		/* Boolean false */

#endif /* OS2_INCLUDED */

typedef void *PTR;		/* generic pointer */
#define EOS  '\0'		/* end-of-string character */

#endif /* STDPL */

/*

Real mode pointer data type (segment:offset16)

The REALPTR data type is used in protected mode to hold
real mode pointers.  The data type is an unsigned long value.
The upper 16 bits of the long are a segment number and the lower
16 bits of the long are an offset.  The format of REALPTR is
identical to a standard pointer as used in real mode.  The 
REALPTR data type is used when mixing real and protected mode
code in the same program.  A REALPTR cannot be dereferenced
in protected mode since the format of pointers in real and
protected mode are different.

As well as the data definition for the REALPTR type, the following
macros are available to set and extract the segment and
offset fields of a REALPR.  The RP_OFF macro returns the offset
portion of a REALPTR.  The RP_SEG macro returns the segment portion
of a REALPTR.  The macro RP_SET is used to combine a segment and an
offset into a REALPTR.  It takes three arguments: the name of the 
REALPTR to be set, an offset, and a segment number.
The RP_INCR macro incrments the offset portion of a REALPTR.

*/

typedef ULONG REALPTR;

#define RP_OFF(rp) ((USHORT)(((ULONG)(rp)) & 0xFFFF))
#define RP_SEG(rp) ((USHORT)(((ULONG)(rp)) >> 16))
#define RP_SET(rp, off, seg) (rp = ((ULONG)(seg) << 16) + (off))
#define RP_INCR(rp, incr) (rp += ((ULONG) (incr)) & 0xFFFF)


/*

Far pointer data type (selector:offset32)

The Microsoft C 32-bit compiler does not support far pointers.  For this
compiler, a FARPTR is defined as a structure which has the same organization
in memory as a standard 48-bit far pointer.

The MetaWare High C/C++ and Watcom C/386 compilers support far pointers in
The MetaWare 80386 High C compiler supports far pointers as well as
addition to 32-bit near pointers.  

The following macros are used to get and set the selector and offset fields
of far pointers, and work both for compilers that directly support far 
pointers and compilers that don't have far pointer support.  
The FP_SEL macro returns the 16-bit selector number field
of a far pointer.  The FP_OFF macro returns the 32-bit offset
field of a far pointer.  The FP_SET macro is used to construct a far
pointer from a selector number and offset.  It takes three arguments:
the name of the far pointer to be set, an offset, and a selector number.
The FP_INCR macro increments the offset field of a far pointer.

*/

#if __CMPLR_FEATURES__ & __FEATURE_FARPTR__
/*
 * Compilers that support far pointers
 */
typedef UCHAR _far *FARPTR;

#ifndef FP_SEL
#define FP_SEL(fp) ((USHORT)(*(((USHORT *)&(fp))+sizeof(UINT)/sizeof(USHORT))))
#endif

#ifndef FP_OFF
#define FP_OFF(fp) ((UINT)(*(UCHAR **)&(fp)))
#endif

#ifndef FP_SET
#define FP_SET(fp, off, sel) ((*(UINT *)&(fp)=(UINT)(off)),\
(*(((USHORT *)&(fp)) + sizeof(UINT)/sizeof(USHORT))=sel))
#endif

#ifndef FP_INCR
#define FP_INCR(fp, incr) (*(UINT *)&(fp) += (UINT) (incr))
#endif

#else
/*
 * Compilers that don't support far pointers;  use a struct instead.
 */
typedef struct {
	ULONG	Off;
	USHORT	Sel;
} FARPTR;

#ifndef FP_SEL
#define FP_SEL(fp) ((fp).Sel)
#endif

#ifndef FP_OFF
#define FP_OFF(fp) ((fp).Off)
#endif

#ifndef FP_SET
#define FP_SET(fp, off, sel) \
	{\
		(fp).Sel = (USHORT) (sel);\
		(fp).Off = (ULONG) (off);\
	}
#endif

#ifndef FP_INCR
#define FP_INCR(fp, incr) ((fp).Off += (ULONG) (incr))
#endif

#endif		/* FARPTR setup */

#endif		/* PLTYPES */
