summaryrefslogblamecommitdiffstats
path: root/private/os2/ldr/basemac.h
blob: c3dbd0e57f850944c090662c6f2897e08cdf8b0f (plain) (tree)
































































































































                                                                                    
/*static char *SCCSID = "@(#)basemac.h	6.1 90/11/15";*/
/***	BASEMAC.H
 *
 *	SCCSID = @(#)basemac.h	13.20 90/09/06
 *
 *	Macros required for other include files
 *	Copyright (c) 1988,1989 Microsoft Corporation
 *
 *
 *	MODIFICATION HISTORY
 *	    10/14/88  JTP    Created.
 *	    12/04/88  JTP    Added OS/2-specific macros.
 */


/*** Generic macros
 */

#define NElements(array) ((sizeof array)/(sizeof array[0]))

#define SWAP(a,b,tmp)	(tmp=b, b=a, a=tmp)


// Assorted macros from STDLIB.H...
#define min(a, b)	(((a) < (b))? (a) : (b))
#define max(a, b)	(((a) > (b))? (a) : (b))


// To extract offset or selector from a FAR32 (16:32) pointer
#define OFFSETOF32(p)	(((PDWORD)&(p))[0])
#define SEGMENTOF32(p)	(((PWORD)&(p))[2])

// To extract offset or selector from any FAR (16:16) pointer
#define OFFSETOF16(p)	(((PWORD)&(p))[0])
#define SEGMENTOF16(p)	(((PWORD)&(p))[1])

// For now, the default operators assume they're working on 16:16 pointers
#define OFFSETOF	OFFSETOF16
#define SEGMENTOF	SEGMENTOF16

// To convert a tiled 16:16 address to a 0:32 address
#define MAKEFLATP(fp)	((PVOID)((SEGMENTOF(fp)&~7)<<13 | OFFSETOF(fp)))

// To extract any byte, word, dword, pfn, etc. from the given item
#define BYTEOF(p,i)	(((PBYTE)&(p))[i])
#define WORDOF(p,i)	(((PWORD)&(p))[i])
#define DWORDOF(p,i)	(((PDWORD)&(p))[i])
#define PFNOF(p,i)	(((PPFN)&(p))[i])

// To test/set bits
#define TESTBIT(i,b)	(((i)&(b)) != 0)
#define SETBIT(i,b,f)	(i = ((i)&~(b)) | (b)*(!!(f)))
#define SETBITB(i,b,f)	(i = (BYTE)(((i)&~(b)) | (b)*(!!(f))))

// ZEROBITS returns the number of low zero bits in a 32-bit constant
#define _Z2(l)		((l)&1?0:(l)&2?1:2)
#define _Z4(l)		((l)&3?_Z2(l):_Z2((l)>>2)+2)
#define _Z8(l)		((l)&15?_Z4(l):_Z4((l)>>4)+4)
#define _Z16(l) 	((l)&255?_Z8(l):_Z8((l)>>8)+8)
#define _Z32(l) 	((l)&65535?_Z16(l):_Z16((l)>>16)+16)
#define ZEROBITS(l)	_Z32(l)

// LOG2 returns the nearest base-2 log of a 32-bit constant, rounded up
#define _L2(l)		((l)&~1?2:(l)&1)
#define _L4(l)		((l)&~3?_L2((l)>>2)+2:_L2(l))
#define _L8(l)		((l)&~15?_L4((l)>>4)+4:_L4(l))
#define _L16(l) 	((l)&~255?_L8((l)>>8)+8:_L8(l))
#define _L32(l) 	((l)&~65535?_L16((l)>>16)+16:_L16(l))
#define LOG2(l) 	_L32((l)-1)

// EXP2 returns 2 raised to the given power
#define EXP2(l) 	(1 << (l))

// Unit conversion macros
#define KBFROMBYTES(nb) 	(((nb)+KSIZE-1)/KSIZE)
#define BYTESFROMKB(nkb)	((nkb)*KSIZE)
#define PAGESFROMBYTES(nb)	(((nb)+PAGESIZE-1)/PAGESIZE)

// To obtain a pointer to the page containing the given linear address
#define PPAGEFROMP(p)		((PVOID)((ULONG)(p) & ~(PAGESIZE-1)))
#define PPAGEFROMPGNO(p)	((PVOID)((ULONG)(p) * PAGESIZE))
#define PGNOFROMP(p)		((ULONG)(p) / PAGESIZE)


// To create a usable FAR pointer from an unusable FAR16 pointer
#define FPFROMF16P(fp,f16p)	OFFSETOF32(fp) = OFFSETOF16(f16p),\
				SEGMENTOF32(fp) = SEGMENTOF16(f16p)

// To create pointers from V86-mode segments+offsets
// Note the validity of these pointers depends on the context they're used in
#define PFROMVP(vp)		((PVOID)((WORDOF(vp,1)<<4)+WORDOF(vp,0)))
#define PFROMVADDR(seg,off)	((PVOID)(((WORD)(seg)<<4)+(WORD)(off)))
#define VPFROMVADDR(seg,off)	((VPVOID)(((WORD)(seg)<<16)|(WORD)(off)))

// To create V86 pointers from normal (flat) pointers
#define HISEG(p)		((USHORT)((ULONG)(p)>>4))
#define LOOFF(p)		((USHORT)((ULONG)(p)&0xf))
#define VPFROMP(p)		((VPVOID)((((ULONG)(p)&~0xf)<<12)|((ULONG)(p)&0xf)))

#define LOSEG(p)		(((ULONG)(p)-HIOFF(p))>>4)
#define HIOFF(p)		(min(0xfff0,(ULONG)(p)&0xffff0)|((ULONG)(p)&0xf))
#define LOSEGVPFROMP(p) 	((VPVOID)((LOSEG(p)<<16)|HIOFF(p)))


// To calculate the byte offset of a field in a structure of type "type"
#define FIELDOFFSET(type,field)	((ULONG)&(((type *)0)->field))


/*** Older stuff (discouraged -JTP)
 */

// To extract high and low order parts of a 32-bit quantity
#define LOUSHORT(l)		(((PUSHORT)&(l))[0])
#define HIUSHORT(l)		(((PUSHORT)&(l))[1])

// To create pointer from V86-mode segment+offset
#define SEGOFF2P(seg,off)	((PVOID)((seg<<4)+(USHORT)off))


/*** OS/2-specific macros
 */

#ifdef	INCL_SSTODS

#define SSToDS(p)	((void *) (TKSSBase + (unsigned) (p)))

extern char *TKSSBase;

#endif