COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

	Copyright (c) GeoWorks 1992 -- All Rights Reserved

PROJECT:	PC GEOS
MODULE:		
FILE:		assert.def

AUTHOR:		John Wedgwood, Mar 16, 1994

	
REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial revision


DESCRIPTION:
	Code to implement assertions.
		
	$Id: assert.def,v 1.1 97/04/04 14:22:12 newdeal Exp $

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@

;
; We need the macros for the dword stuff.
;
include	geos.def
include disk.def

SetDef	__ASSERT

COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Quick-reference list:	(Please keep this up to date as you modify this file)
---------------------
	(Note: for double-word quantities, "expr" can be a register pair)

	Handle assertions:	(Format: Assert <hanType> expr)
	------------------
	Assert handle			expr
	Assert gstate			expr
	Assert window			expr
	Assert lmem			expr
	Assert objblock			expr
	Assert gstring			expr
	Assert fileHandle		expr
	Assert diskHandle		expr
	Assert vmMemHandle		expr
	Assert vmFileHandle		expr
	Assert thread			expr
	Assert socket			expr

	Range assertions:	(Format: Assert <rangeType> expr min max)
	-----------------
	Assert srange			expr, min, max
	Assert urange			expr, min, max

	Pointer/segment assertions:
	---------------------------
	Assert segment			expr
	Assert fptr			expr
	Assert optr			expr
	Assert nptr			expr, seg
	Assert dgroup			expr
	Assert vfptr			expr
	Assert fptrXIP			expr

	Other basic GEOS types:
	-----------------------
	Assert chunk			expr, seg
	Assert chunkPtr			expr, seg
	Assert vmBlock			expr, file
	Assert ChunkArray		expr
	Assert HugeArray		expr, file
	Assert stackFrame		expr

	Esp type verification:
	----------------------
	Assert etype			expr, et
	Assert record			expr, rec

	Object stuff:
	-------------
	Assert objectPtr		expr, oclass
	Assert objectOD			expr, oclass

	String stuff:
	-------------
	Assert asciiChar		expr
	Assert ascii			expr, len
	Assert nullTerminatedAscii	expr
	Assert okForRepMovsb
	Assert okForRepCmpsb
	Assert okForRepScasb
	Assert buffer			expr, size

	Basic comparisons:	(Format: Assert <cmpType> expr value)
	------------------
	Assert l/le/g/ge/a/ae/b/be/e	expr, value

	Assert carrySet
	Assert carryClear

	Assert bitSet			expr, recordField
	Assert bitClear			expr, recordField

	Assert inList			expr, <val1, val2, ...>


Stuff on the list to do:
------------------------
	* Simplify the etype and record assertions to allow:
		Assert etypeName expr
		Assert recName   expr

	* Validate a full optr, not just the handle
	
	* Validate a pointer to an object, not just the segment/chunk

	* Validate a pointer into a chunk-array as being a valid element
		Assert ChunkArrayElement dsdi

	* Validate a huge-array handle element
		Assert HugeArrayElement dsdi

Background:
-----------
Assertions are implemented as a macro. The idea is that you can check
that an expression is of a given type in an easy manner:

	Assert handle ax
	Assert optr dxax
	Assert etype SomeEnumeratedType cx

Or that something is in a range (signed or unsigned):

	Assert srange 0 MAX_EXPECTED_VALUE ax
	Assert urange -MAX_EXPECTED_RANGE MAX_EXPECTED_RANGE ax

The goal is to make the assertion mechanism extensible, so that while this
file may contain macros for common system structures, it should be possible
for individual developers to create their own additions to the types that
can be checked, or to the functions that Assert can handle.

The technique for this is to have macros of the form:
	
	Assert_handle
	Assert_optr
	Assert_etype
	Assert_urange
	Assert_srange
	...

This allows the application developer to add assertions for their own
data-structures by creating macros named in this fashion.

To get a better idea, take a look at the definition for 'Assert' at the
bottom of the file.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		PreserveAndGetIntoReg
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Get a value into a register, preserving the register if needed.

CALLED BY:	Utility
PASS:		reg	- The register to get it into
		expr	- Expression to get into reg
RETURN:		nothing
DESTROYED:	nothing

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
PreserveAndGetIntoReg	macro	reg, expr

  ifdif	<expr>, <reg>
	;
	; Save the register that we'll be nuking.
	;
		push	reg

	;
	; Use 'segmov' if we are moving into a segment register.
	;
    ifidn	<reg>, <ds>
		segmov	reg, expr
    else
        ifidn	<reg>, <es>
		segmov	reg, expr
        else
		mov	reg, expr
	endif
    endif

  endif

endm

RestoreReg		macro	reg, expr
    ifdif	<expr>, <reg>
	;
	; The expression is in the register, we need to restore it.
	;
		pop	reg
    endif
endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		SetDWordRegistersAndCall
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Set up two registers with the contents of a dword and then
		call a function to do EC work.

CALLED BY:	Utility
PASS:		highReg	- Register to get the contents of the high word
		lowReg	- Register to get the contents of the low word
		expr	- Expression to load from
		routine	- Routine to call
		func	- The macro that called this one
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		generated by the routine called.

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/18/94	Initial version
	kho	12/21/96	Use trash reg

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
SetDWordRegistersAndCall	macro	highReg, lowReg, expr, routine, func
	local	drl, drh, regargs

	;
	; First extract the expressions for the low and high words, assuming
	; a register pair.
	;
regargs = 0

_CheckDWordOneArg	<expr>, func
_ParseDWordArg	<expr>, drl, drh, regargs, func

if (regargs eq 0)
	;
	; Pick our trash register. The trash register should never appear in
	; the expr, so that rules out bx, ds, si, es, di, bp. Obviously, it
	; should not be highReg / lowReg.
	;
	if <highReg> ne <ax> and <lowReg> ne <ax>
		trashReg = ax
	elif <highReg> ne <cx> and <lowReg> ne <cx>
		trashReg = cx
	else
		trashReg = dx
	endif

	;
	; Have to make sure we compute lowReg with the original
	; highReg, so use the trashReg to hold the new highReg.
	;
		push	highReg
		PreserveAndGetIntoReg	trashReg,expr.high
		PreserveAndGetIntoReg	lowReg,  expr.low
		mov	highReg, trashReg
		call	routine
		RestoreReg		lowReg,  expr.low
		RestoreReg		trashReg,expr.high
		pop	highReg

else
  ;
  ; Register pair.
  ;
		PreserveAndGetIntoReg	highReg, %drh
		PreserveAndGetIntoReg	lowReg,  %drl
		call	routine
		RestoreReg		lowReg,  %drl
		RestoreReg		highReg, %drh
endif

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		PreserveDWordAndGetIntoRegs
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Set up two registers with the contents of a dword

CALLED BY:	Utility
PASS:		highReg	- Register to get the contents of the high word
		lowReg	- Register to get the contents of the low word
		expr	- Expression to load from
		func	- The macro that called this one
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		generated by the routine called.

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/18/94	Initial version as SetDWordRegistersAndCall
	epw	 5/03/95	created PreserveDWordAndGetIntoRegs

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
PreserveDWordAndGetIntoRegs	macro	highReg, lowReg, expr, func
	local	srl, srh, regargs

	;
	; First extract the expressions for the low and high words, assuming
	; a register pair.
	;
regargs = 0

_CheckDWordOneArg	<expr>, func
_ParseDWordArg	<expr>, srl, srh, regargs, func

if (regargs eq 0)
		PreserveAndGetIntoReg	highReg, expr.high
		PreserveAndGetIntoReg	lowReg,  expr.low
elifidn <highReg>, srl
  ;
  ; Register pair.
  ;
		PreserveAndGetIntoReg	lowReg,  %srl
		PreserveAndGetIntoReg	highReg, %srh
else
		PreserveAndGetIntoReg	highReg, %srh
		PreserveAndGetIntoReg	lowReg,  %srl
endif

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		RestoreDWord
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Restore the registers used to hold a dword

CALLED BY:	Utility
PASS:		highReg	- Register to get the contents of the high word
		lowReg	- Register to get the contents of the low word
		expr	- Expression to load from
		func	- The macro that called this one
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		generated by the routine called.

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/18/94	Initial version as SetDWordRegistersAndCall
	epw	 5/03/95	created RestoreDWord
	

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
RestoreDWord	macro	highReg, lowReg, expr, func
	local	srl, srh, regargs

	;
	; First extract the expressions for the low and high words, assuming
	; a register pair.
	;
regargs = 0

_CheckDWordOneArg	<expr>, func
_ParseDWordArg	<expr>, srl, srh, regargs, func

if (regargs eq 0)
		RestoreReg		lowReg,  expr.low
		RestoreReg		highReg, expr.high
elifidn <highReg>, srl
		RestoreReg		highReg, %srh
		RestoreReg		lowReg,  %srl
else
  ;
  ; Register pair.
  ;
		RestoreReg		lowReg,  %srl
		RestoreReg		highReg, %srh
endif

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_handle
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Asserts that an expression is a valid handle.

CALLED BY:	Assert
PASS:		expr	- The expression to check
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		generated by ECCheckMemHandle

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_handle	macro	expr

		PreserveAndGetIntoReg	bx, expr
		call	ECCheckMemHandle	; preserves flags
		RestoreReg		bx, expr

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_gstate
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is a valid gstate.

CALLED BY:	Assert
PASS:		expr	- The expression to check
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		generated by ECCheckGStateHandle

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_gstate	macro	expr

		PreserveAndGetIntoReg	di, expr
		call	ECCheckGStateHandle	; preserves flags
		RestoreReg		di, expr

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_window
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert than an expression is a valid window.

CALLED BY:	Assert
PASS:		expr	- Expression to check
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		generated by ECCheckWindowHandle

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_window	macro	expr

		PreserveAndGetIntoReg	bx, expr
		call	ECCheckWindowHandle	; preserves flags
		RestoreReg		bx, expr

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_lmem
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is the handle of an lmem block.

CALLED BY:	Assert
PASS:		expr	- Expression to check
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		???

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_lmem	macro	expr

		PreserveAndGetIntoReg	bx, expr
		call	ECCheckLMemHandle	; preserves flags
		RestoreReg		bx, expr
endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_objblock
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is the handle of an object block.

CALLED BY:	Assert
PASS:		expr	- Expression to check
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		???

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_objblock	macro	expr
		Assert	lmem, expr
endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_gstring
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is the handle of a graphics-string

CALLED BY:	Assert
PASS:		expr	- Expression to check
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		???

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_gstring	macro	expr
		Assert	lmem, expr
endm



COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_thread
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is a thread handle.

CALLED BY:	Assert
PASS:		expr	- Expression to check
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		???

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	ardeb	 5/2/94		Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_thread	macro	expr

		PreserveAndGetIntoReg	bx, expr
		call	ECCheckThreadHandle	; preserves flags
		RestoreReg		bx, expr
endm



COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_socket
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is a socket handle

PASS:		expr	- Expression to check

PSEUDO CODE/STRATEGY:

KNOWN BUGS/SIDE EFFECTS/IDEAS:

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	EW	12/ 5/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_socket		macro	expr
		PreserveAndGetIntoReg	bx, expr
		call	ECCheckSocket
		RestoreReg		bx, expr
endm



COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_segment
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is a valid segment.

CALLED BY:	Assert
PASS:		expr	- Expression to check
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		Generated by ECCheckSegment

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_segment	macro	expr

		PreserveAndGetIntoReg	ax, expr
		call	ECCheckSegment	; Preserves flags
		RestoreReg		ax, expr

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_fptr
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is a valid far ptr

CALLED BY:	Assert
PASS:		expr	- Expression to check
				If the expression is a register pair, then
				the first register is the segment, and the
				second is the offset.
				
				Otherwise these values are used:
					expr.segment
					expr.offset
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		generated by ECCheckBounds

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_fptr	macro	expr

    SetDWordRegistersAndCall	ds, si, expr, ECCheckBounds, Assert_fptr

endm



COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_fptrXIP
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is a valid non-virtual far 
		pointer, and is not pointing to a movable XIP code resource

REQUIRES:	heapInt.def on XIP systems

PASS:		expr	- Expression to check
				If the expression is a register pair, then
				the first register is the segment, and the
				second is the offset.
				
				Otherwise these values are used:
					expr.segment
					expr.offset

RETURN:		nothing
DESTROYED:	nothing

ERRORS:		non-XIP: generated by Assert_fptr
		XIP:	 generated by ECCheckValidFarPointerXIP
			 or VIRTUAL_SEGMENT_NOT_PERMITTED

KNOWN BUGS/SIDE EFFECTS/IDEAS:

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	EW	5/ 3/95   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@

VIRTUAL_SEGMENT_NOT_PERMITTED	enum	FatalErrors
; A virtual far pointer was passed to a routine which expects only
; true far pointers.

Assert_fptrXIP		macro	expr
if _FXIP
		PreserveDWordAndGetIntoRegs	bx,si,expr,Assert_fptrXIP
		call	ECAssertValidFarPointerXIP

	;
	;  cmp bx, MAX_SEGMENT, do not want to include 
	;  Include/heapInt.def which defines MAX_SEGMENT.
	;
		cmp	bx, 0xf000	
		ERROR_A VIRTUAL_SEGMENT_NOT_PERMITTED
		RestoreDWord			bx,si,expr,Assert_fptrXIP
else
		Assert_fptr expr
endif		
endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_vfptr
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is a valid virtual far ptr

CALLED BY:	Assert
PASS:		expr	- Expression to check
				If the expression is a register pair, then
				the first register is the vseg, and the
				second is the offset.
				
				Otherwise these values are used:
					expr.segment
					expr.offset
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		generated by ECCheckBounds

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_vfptr	macro	expr

    SetDWordRegistersAndCall	bx, si, expr, ECAssertValidFarPointerXIP, Assert_vfptr

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_nptr
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is a valid offset from a segment.

CALLED BY:	Assert
PASS:		expr	- Expression that is the near pointer
		seg	- Segment to check for
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		generated from ECCheckBounds

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_nptr	macro	expr, seg
		PreserveAndGetIntoReg si, expr
		EC_BOUNDS	seg, si
		RestoreReg	si, expr
endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_optr
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is a valid optr

CALLED BY:	Assert
PASS:		expr	- Expression to check
				If the expression is a register pair, then
				the first register is the handle, and the
				second is a chunk.
				
				Otherwise these values are used:
					expr.handle
					expr.chunk
RETURN:		nothing
DESTROYED:	nothing

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_optr	macro	expr
	local	drl, drh, regargs

	;
	; First extract the expressions for the low and high words, assuming
	; a register pair.
	;
regargs = 0

_CheckDWordOneArg	expr, <Assert_optr>
_ParseDWordArg	expr, drl, drh, regargs, <Assert_optr>

if (regargs eq 0)
		Assert lmem (expr).handle
else
  ;
  ; Register pair.
  ;
		Assert lmem %drh
endif

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_fileHandle
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is a file handle

CALLED BY:	Assert
PASS:		expr	- Expression to check
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		generated by ECCheckFileHandle

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_fileHandle	macro	expr

		PreserveAndGetIntoReg	bx, expr
		call	ECCheckFileHandle
		RestoreReg		bx, expr

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_vmFileHandle
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is a VM file handle (also checks
		integrity of file, of ECF_VMEM set)

CALLED BY:	Assert
PASS:		expr	- Expression to check
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		generated by ECVMCheckVMFile

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_vmFileHandle	macro	expr

		PreserveAndGetIntoReg	bx, expr
		call	ECVMCheckVMFile
		RestoreReg		bx, expr

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_diskHandle
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is a valid disk handle
		or a StandardPath
CALLED BY:	Assert
PASS:		expr	- Expression to check
RETURN:		nothing
DESTROYED:	nothing

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_diskHandle	macro	expr
		local	isHandle, done
	;
	; decide if this is a standard path or a disk handle
	;
		PreserveAndGetIntoReg	bx, expr
		test	bx, DISK_IS_STD_PATH_MASK
		jz	isHandle
	;
	; it's a standard path, so verify it as an etype
	;
		Assert	etype, bx, StandardPath
		jmp	done
	;
	; it's a disk handle, so verify it as a handle
	;
isHandle:
		Assert	handle, bx
done:
		RestoreReg		bx, expr
endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_vmBlock
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is a valid VM block handle.

CALLED BY:	Assert
PASS:		expr	- Expression to check
		file	- File the thing would be in
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		generated by ECVMCheckVMBlockHandle

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_vmBlock	macro	expr, file
		PreserveAndGetIntoReg	ax, expr
		PreserveAndGetIntoReg	bx, file

		call	ECVMCheckVMBlockHandle
		
		RestoreReg	bx, file
		RestoreReg	ax, expr
endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_vmMemHandle
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is the memory handle for a vm block

CALLED BY:	Assert
PASS:		expr	- Expression to check
RETURN:		nothing
DESTROYED:	nothing

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_vmMemHandle	macro	expr

		PreserveAndGetIntoReg	bx, expr
		call	ECVMCheckMemHandle	; preserves flags
		RestoreReg		bx, expr

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_chunk
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is a valid chunk handle in a given
		segment

CALLED BY:	Assert
PASS:		expr	- Expression to check
		seg	- Segment
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		generated by ECLMemValidateHandle

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_chunk	macro	expr, seg
		PreserveAndGetIntoReg si, expr
		PreserveAndGetIntoReg ds, seg
		call	ECLMemValidateHandle
		RestoreReg ds, seg
		RestoreReg si, expr
endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_chunkPtr
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is an offset to the beginning of a
		used chunk in an lmem heap.

CALLED BY:	Assert
PASS:		expr	- Expression to check
		seg	- Segment
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		generated by ECCheckLMemChunk

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_chunkPtr	macro	expr, seg
		PreserveAndGetIntoReg si, expr
		PreserveAndGetIntoReg ds, seg
		call	ECCheckLMemChunk
		RestoreReg ds, seg
		RestoreReg si, expr
endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_ChunkArray
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is a pointer to a valid chunk-array.

CALLED BY:	Assert
PASS:		expr	- Expression to check
				If the expression is a register pair, then
				the first register is the segment, and the
				second is the chunk handle.
				
				Otherwise these values are used:
					expr.segment
					expr.chunk
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		generated by ECCheckChunkArray

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_ChunkArray	macro	expr

  SetDWordRegistersAndCall   ds, si, expr, ECCheckChunkArray, Assert_ChunkArray

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_HugeArray
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is a pointer to a valid huge-array

CALLED BY:	Assert
PASS:		expr	- Expression to check
		file	- File the thing would be in
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		generated by ECCheckHugeArray

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	simon   2/16/97   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_HugeArray	macro	expr, file
		PreserveAndGetIntoReg	di, expr
		PreserveAndGetIntoReg	bx, file

		call	ECCheckHugeArray
		
		RestoreReg	bx, file
		RestoreReg	di, expr
endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_objectPtr
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Verify that an expression is an undereferenced pointer to an
		object and that the object is of a given class.

CALLED BY:	Assert
PASS:		expr	- Expression to check
				If the expression is a register pair, then
				the first register is the segment, and the
				second is the chunk handle.
				
				Otherwise these values are used:
					expr.segment
					expr.chunk
		oclass	- The expected class of the object
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		OBJECT_NOT_OF_PROPER_CLASS

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
OBJECT_NOT_OF_PROPER_CLASS			enum FatalErrors

CheckObjInClass	macro	oclass
	;
	; Assumes that *ds:si already points to the object.
	;
	      	Assert	chunk, si, ds
	      	push	es, di
	if (type segment oclass) eq 3
	      	; library segment, so can/must use just "segment oclass"
		segmov	es, <segment oclass>, di
	else
		push	ax, bx, cx
		call	GEODEGETCODEPROCESSHANDLE
		mov_tr	bx, ax		;BX <- owning geode of code resource
		mov	ax, resid oclass
		call	GeodeGetGeodeResourceHandle
		call	MemDerefES
		pop	ax, bx, cx
	endif
	      	mov	di, offset oclass
	      	call	ObjIsObjectInClass
		ERROR_NC OBJECT_NOT_OF_PROPER_CLASS
	      	pop	es, di

endm

Assert_objectPtr	macro	expr, oclass

	local	drl, drh, regargs

	;
	; First extract the expressions for the low and high words, assuming
	; a register pair.
	;
regargs = 0

_CheckDWordOneArg	<expr>, <Assert_objectPtr>
_ParseDWordArg	<expr>, drl, drh, regargs, <Assert_objectPtr>

if (regargs eq 0)
		PreserveAndGetIntoReg	ds, expr.segment
		PreserveAndGetIntoReg	si, expr.chunk
		CheckObjInClass	oclass
		RestoreReg		si, expr.chunk
		RestoreReg		ds, expr.segment
else
  ;
  ; Register pair.
  ;
		PreserveAndGetIntoReg	ds, %drh
		PreserveAndGetIntoReg	si, %drl
		CheckObjInClass	oclass
		RestoreReg		si, %drl
		RestoreReg		ds, %drh
endif

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_objectOD
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is the OD of an object.

CALLED BY:	Assert
PASS:		expr	- Expression to check
				If the expression is a register pair, then
				the first register is the handle, and the
				second is the chunk handle.
				
				Otherwise these values are used:
					expr.handle
					expr.chunk
		oclass	- The expected class of the object
		fixup	- if non-blank, DS points to an object block and
			  will be fixed up after the ObjMessage to ensure
			  the OD is of the proper class.
			  
			  if blank and DS points to an object block, DS will
			  be *DESTROYED* when ec +segment is active.
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		OBJECT_NOT_OF_PROPER_CLASS

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
CheckObjODInClass	macro	oclass, fixup
	;
	; Assumes ^lbx:si refers to the object.
	;
		call	ECCheckLMemOD
	      	push	ax, cx, dx, bp, es, di
	if (type segment oclass) eq 3
	      	; library segment, so can/must use just "segment oclass"
	      	mov	cx, segment oclass
	else
		push	bx
		call	GEODEGETCODEPROCESSHANDLE
		mov_tr	bx, ax		;BX <- owning geode of code resource
		mov	ax, resid oclass
		call	GeodeGetGeodeResourceHandle
		call	MemDerefES
		pop	bx
	      	mov	cx, es
	endif
	      	mov	dx, offset oclass
	      	mov	ax, MSG_META_IS_OBJECT_IN_CLASS
	ifnb <fixup>
		mov	di, mask MF_CALL or mask MF_FIXUP_DS
	else
	      	mov	di, mask MF_CALL
	endif
	      	call	ObjMessage
		ERROR_NC OBJECT_NOT_OF_PROPER_CLASS
	      	pop	ax, cx, dx, bp, es, di

endm

Assert_objectOD	macro	expr, oclass, fixup

	local	drl, drh, regargs

	;
	; First extract the expressions for the low and high words, assuming
	; a register pair.
	;
regargs = 0

_CheckDWordOneArg	<expr>, <Assert_objectOD>
_ParseDWordArg	<expr>, drl, drh, regargs, <Assert_objectOD>

if (regargs eq 0)
		PreserveAndGetIntoReg	bx, expr.handle
		PreserveAndGetIntoReg	si, expr.chunk
		CheckObjODInClass	oclass, fixup
		RestoreReg		si, expr.chunk
		RestoreReg		bx, expr.handle
else
  ;
  ; Register pair.
  ;
		PreserveAndGetIntoReg	bx, %drh
		PreserveAndGetIntoReg	si, %drl
		CheckObjODInClass	oclass, fixup
		RestoreReg		si, %drl
		RestoreReg		bx, %drh
endif

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_srange
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that a value is within a signed range.

CALLED BY:	Assert
PASS:		expr	- Expression to check
		min	- Minimum valid value
		max	- Maximum valid value
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		NUMBER_NOT_IN_SIGNED_RANGE

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@

NUMBER_NOT_IN_SIGNED_RANGE	enum	FatalErrors
; An assertion that an expression was within the bounds of a signed range failed.

Assert_srange	macro	expr, min, max

		cmp	expr, min
		ERROR_L	NUMBER_NOT_IN_SIGNED_RANGE
		cmp	expr, max
		ERROR_G	NUMBER_NOT_IN_SIGNED_RANGE

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_urange
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is within an unsigned range.

CALLED BY:	Assert
PASS:		expr	- Expression to check
		min	- Minimum valid value
		max	- Maximum valid value
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		NUMBER_NOT_IN_UNSIGNED_RANGE

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@

NUMBER_NOT_IN_UNSIGNED_RANGE	enum	FatalErrors
; An assertion that an expression was within the bounds of a unsigned range
; failed.

Assert_urange	macro	expr, min, max

		cmp	expr, min
		ERROR_B	NUMBER_NOT_IN_UNSIGNED_RANGE
		cmp	expr, max
		ERROR_A	NUMBER_NOT_IN_UNSIGNED_RANGE

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_etype
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is a valid member of an etype.

CALLED BY:	Assert
PASS:		expr	- Expression to check
		etype	- Etype that it is supposed to be in
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		NOT_VALID_MEMBER_OF_ENUMERATED_TYPE

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
NOT_VALID_MEMBER_OF_ENUMERATED_TYPE			enum FatalErrors
; Assertion failed. The expression is not a legal value for the enumerated type.

Assert_etype	macro	expr, et

;
; Check for signed etype.
;
if et gt 0x7fff
  ;
  ; It is a signed etype, check for initial value less than zero.
  ;
 if first et ne 0
	;
	; Initial value is less than zero, check for being less than the first.
	;
		cmp	expr, first et
		ERROR_B	NOT_VALID_MEMBER_OF_ENUMERATED_TYPE
 endif
	;
	; Signed etype. Check for the value being above the last entry
	;
		cmp	expr, et
		ERROR_AE NOT_VALID_MEMBER_OF_ENUMERATED_TYPE

elif first et ne 0
  ;
  ; An unsigned etype with the first value above zero.
  ;
		cmp	expr, first et
		ERROR_L	NOT_VALID_MEMBER_OF_ENUMERATED_TYPE
		cmp	expr, et
		ERROR_GE NOT_VALID_MEMBER_OF_ENUMERATED_TYPE

else
  ;
  ; An unsigned etype with the first value being zero.
  ;
		cmp	expr, et
		ERROR_AE NOT_VALID_MEMBER_OF_ENUMERATED_TYPE
endif

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_record
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is valid for a record.

CALLED BY:	Assert
PASS:		expr	- Expression to check
		rec	- Record to check against
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		NOT_A_VALID_RECORD

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
NOT_A_VALID_RECORD			enum	FatalErrors
; The expression is not a valid record of the given type. That is to say that
; there are bits set in places that are not considered part of the record.

Assert_record	macro	expr, rec

		test	expr, not rec
		ERROR_NZ NOT_A_VALID_RECORD

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_asciiChar
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that a character is an ascii character

CALLED BY:	Assert, CheckAsciiString
PASS:		expr	- Byte to check
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		NOT_VALID_ASCII_CHAR

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
NOT_VALID_ASCII_CHAR			enum	FatalErrors
; An assertion that a character was valid ascii has failed.
; Valid ascii is anything that is Alpha, Punctuation, Space, Symbol, Digit

Assert_asciiChar	macro	expr

	local	quit

	;
	; Get the character into al.  Must clear ah or else check
	; routines will complain about double-byte stuff.
	;
		push	ax
	ifdif	<expr>, <al>
		mov	al, expr
	endif
		clr	ah

		call	LocalIsAlpha
		jnz	quit
		
		call	LocalIsPunctuation
		jnz	quit

		call	LocalIsSpace
		jnz	quit
		
		call	LocalIsSymbol
		jnz	quit
		
		call	LocalIsDigit
		jnz	quit

		ERROR	NOT_VALID_ASCII_CHAR

quit:
		pop	ax
endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_ascii
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that a string of characters is valid ascii

CALLED BY:	Assert
PASS:		expr	- Pointer to the text.
				If the expression is a register pair, then
				the first register is the segment, and the
				second is the offset.
				
				Otherwise these values are used:
					expr.segment
					expr.offset
		len	- Expression which is the length of the string
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		NOT_VALID_ASCII_CHAR

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
CheckAsciiString	macro
	;
	; Assumes ds:si points to the string and cx is the length
	;
	local	charLoop

		push    ax, cx, si              ; #1
charLoop:
		Assert	fptr, dssi
		lodsb		; al <- character
		Assert asciiChar al
		loop	charLoop
	
		pop     ax, cx, si              ; #1
endm

Assert_ascii	macro	expr, len


	local	drl, drh, regargs

	;
	; First extract the expressions for the low and high words, assuming
	; a register pair.
	;
regargs = 0

_CheckDWordOneArg	<expr>, <Assert_ascii>
_ParseDWordArg	<expr>, drl, drh, regargs, <Assert_ascii>

if (regargs eq 0)
		PreserveAndGetIntoReg	ds, expr.segment
		PreserveAndGetIntoReg	si, expr.offset
		PreserveAndGetIntoReg	cx, len
		CheckAsciiString
		RestoreReg		cx, len
		RestoreReg		si, expr.segment
		RestoreReg		ds, expr.offset
else
  ;
  ; Register pair.
  ;
		PreserveAndGetIntoReg	ds, %drh
		PreserveAndGetIntoReg	si, %drl
		PreserveAndGetIntoReg	cx, len
		CheckAsciiString
		RestoreReg		cx, len
		RestoreReg		si, %drl
		RestoreReg		ds, %drh
endif

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_nullTerminatedAscii
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that a null terminated string is valid ascii

CALLED BY:	Assert
PASS:		expr	- Pointer to the text.
				If the expression is a register pair, then
				the first register is the segment, and the
				second is the offset.
				
				Otherwise these values are used:
					expr.segment
					expr.offset
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		NOT_VALID_ASCII_CHAR

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
CheckNullTerminatedAsciiString	macro
	;
	; Assumes that ds:si points to the string.
	;
		
	local	charLoop, quit

		push	ax, si			; #1
charLoop:
		Assert	fptr, dssi

		lodsb		; al <- character

		tst	al	; quit if null
		jz	quit

		Assert asciiChar al
		jmp	charLoop

quit:
		pop	ax, si			; #1
endm

Assert_nullTerminatedAscii	macro	expr

	local	drl, drh, regargs

	;
	; First extract the expressions for the low and high words, assuming
	; a register pair.
	;
regargs = 0

_CheckDWordOneArg	<expr>, <Assert_nullTerminatedAscii>
_ParseDWordArg	<expr>, drl, drh, regargs, <Assert_nullTerminatedAscii>

if (regargs eq 0)
		PreserveAndGetIntoReg	ds, expr.segment
		PreserveAndGetIntoReg	si, expr.offset
		CheckNullTerminatedAsciiString
		RestoreReg		si, expr.segment
		RestoreReg		ds, expr.offset
else
  ;
  ; Register pair.
  ;
		PreserveAndGetIntoReg	ds, %drh
		PreserveAndGetIntoReg	si, %drl
		CheckNullTerminatedAsciiString
		RestoreReg		si, %drl
		RestoreReg		ds, %drh
endif

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_okForRepMovsb_Cmpsb
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that a movsb/cmpsb will be legal by checking the
		pointers involved. This assumes a move upward...

CALLED BY:	Assert
PASS:		ds:si	= Pointer to source
		es:di	= Pointer to dest
		cx	= Length
RETURN:		nothing
DESTROYED:	nothing

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_okForRepMovsb	macro
		local	done
	;
	; Ensure the pointers are valid at the start
	;
		Assert	fptr dssi
		Assert	fptr esdi

	;
	; Ensure that the pointers will be valid when we're done.
	;
 		jcxz	done			; skip checking if no
						; data to mov/cmp
		push	si, di

		add	si, cx
		dec	si
		Assert	fptr dssi
	
		add	di, cx
		dec	di
		Assert	fptr esdi
		
		pop	si, di
done:
		
endm

Assert_okForRepCmpsb	macro
	Assert_okForRepMovsb
endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_okForRepScasb
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that a rep scasb can be successful. Assumes moving up.

CALLED BY:	Assert
PASS:		es:di	= Pointer to the start
		cx	= Number of bytes to search
		al	= Byte to search for
RETURN:		nothing
DESTROYED:	nothing

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_okForRepScasb	macro
		local	done
		
		Assert	fptr esdi

 		jcxz	done			; skip checking if no
						; data to search
		push	di

		add	di, cx
		dec	di
		Assert	fptr esdi
		
		pop	di
done:
endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_buffer
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that a buffer of specified length is within address
		bounds. 

CALLED BY:	Assert
PASS:		expr	- start of buffer
		size	- size of buffer (in bytes)	
RETURN:		nothing
DESTROYED:	nothing

PSEUDO CODE/STRATEGY:

EXAMPLES:
	e.g.	Assert	buffer	dssi, cx
	
REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	simon	9/28/95   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert_buffer		macro	expr, size
		PreserveDWordAndGetIntoRegs	es,di,expr,Assert_buffer
		PreserveAndGetIntoReg		cx, size
	
		Assert_okForRepScasb
	
		RestoreReg			cx, size
		RestoreDWord			es,di,expr,Assert_buffer
endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_lt
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is less than some value.

CALLED BY:	Assert
PASS:		expr	- Expression to check
		bound	- Value to compare against
RETURN:		nothing
DESTROYED:	nothing
ERROR:		ASSERTION_FAILED

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
ASSERTION_FAILED			enum	FatalErrors
; An assertion failed.

;
; This macro defines other macros
;
__defassert	macro	suffix

    ;
    ; Here is the macro that gets defined. It takes two arguments (the expression
    ; and the bound) and the name is constructed from combining "Assert_" with
    ; the appropriate branch.
    ;
    Assert_&suffix macro expr, bound
ifdif <expr>, <sp>
	local 	notError
	cmp	expr, bound
	j&suffix notError		; The branch
	ERROR	ASSERTION_FAILED
else
	PrintMessage <Do NOT use sp with this macro (no code generated)>
endif
notError:
    endm
endm

;
; Repeat, for each sort of comparison.
;
irp	er, <l, le, g, ge, a, ae, b, be, e, ne, z, nz>
	__defassert er
endm



COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_carrySet, Assert_carryClear
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that the carry is set or clear.  Just does an ERROR_C
		or ERROR_NC with an ASSERTION_FAILED fatal error.

CALLED BY:	Assert

PASS:		nothing

RETURN:		nothing

DESTROYED:	nothing

ERROR:		ASSERTION_FAILED

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jdashe	12/28/95	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@

Assert_carrySet	macro
		ERROR_NC ASSERTION_FAILED
endm

Assert_carryClear macro
		ERROR_C ASSERTION_FAILED
endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_stackFrame
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that a pointer is to a stack frame.

CALLED BY:	Assert
PASS:		expr	- Offset into the stack segment.
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		OFFSET_IS_NOT_A_VALID_STACK_FRAME

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/17/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
OFFSET_IS_NOT_A_VALID_STACK_FRAME	enum	FatalErrors
; An offset that was expected to be for a stack frame was not valid. It could
; have been beyond the end of the stack, of below the stack pointer.

Assert_stackFrame	macro	expr

	;
	; First validate the pointer
	;
		EC_BOUNDS	ss, expr

	;
	; Now make sure the offset is in the valid stack area.
	;
		push	ax
		mov	ax, sp
		add	ax, size word		; ax <- old sp

	;
	; Compare to old stack pointer
	;
		cmp	ax, expr
		ERROR_A	OFFSET_IS_NOT_A_VALID_STACK_FRAME
		
		pop	ax

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_dgroup
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression is the same as dgroup

CALLED BY:	Assert
PASS:		expr	- Expression to check
RETURN:		nothing
DESTROYED:	nothing
ERRORS:		SEGMENT_IS_NOT_DGROUP

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/18/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
SEGMENT_IS_NOT_DGROUP			enum	FatalErrors
; The segment is not dgroup, and it is supposed to be.

Assert_dgroup	macro	expr
	;
	; Make sure the segment is valid at all
	;
		Assert segment expr

	;
	; Get the segment into ax and dgroup into bx and compare.
	;
		PreserveAndGetIntoReg	ax, expr
		push	ds, bx

		push	ax, cx
		call	GEODEGETCODEPROCESSHANDLE
		mov_tr	bx, ax		; bx <- owning geode of code resource
		mov	ax, resid dgroup
		call	GeodeGetGeodeResourceHandle
		call	MemDerefDS	; ds <- dgroup
		pop	ax, cx

		mov	bx, ds		; bx <- dgroup

		cmp	ax, bx
		ERROR_NZ SEGMENT_IS_NOT_DGROUP

		pop	ds, bx
		RestoreReg	ax, expr
endm



COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	The basic Assert function

CALLED BY:	by applications wishing to do EC checking.
PASS:		Arguments depend on the type of assertion
RETURN:		nothing
DESTROYED:	nothing, flags are preserved
ERRORS:		Depend on the type of assertion

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jcw	 3/16/94	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
Assert	macro	suffix, val1, val2, val3, val4, val5, val6

if ERROR_CHECK
  ifb <suffix>
	ErrMessage <Invalid Assert>
  else
	pushf
	Assert_&suffix <val1>, <val2>, <val3>, <val4>, <val5>, <val6>
	popf
  endif
endif

endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_bitSet
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Make sure the indicated bit is non-zero

PASS:		expr	= expression to test (non-constant)
		bit	= record field name or numeric equate that specify
			  the bit that must be set ("mask" operator 
			  automatically used if field name is given)

PSEUDO CODE/STRATEGY:

KNOWN BUGS/SIDE EFFECTS/IDEAS:

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	ardeb	9/28/94		Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BIT_MUST_BE_SET			enum FatalErrors

Assert_bitSet	macro	expr, bit
	; if bit 2 and bit 9 are set, it's a record-related constant
	if ((.type (bit)) and 0x204) eq 0x204
		test	expr, mask bit
	else
		test	expr, bit
	endif
		ERROR_Z	BIT_MUST_BE_SET
		endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_bitSet
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Make sure the indicated bit is non-zero

PASS:		expr	= expression to test (non-constant)
		bit	= record field name or numeric equate that specify
			  the bit that must be set ("mask" operator 
			  automatically used if field name is given)

PSEUDO CODE/STRATEGY:

KNOWN BUGS/SIDE EFFECTS/IDEAS:

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	ardeb	9/28/94		Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
BIT_MUST_BE_CLEAR		enum FatalErrors

Assert_bitClear	macro	expr, bit
	; if bit 2 and bit 9 are set, it's a record-related constant
	if ((.type (bit)) and 0x204) eq 0x204
		test	expr, mask bit
	else
		test	expr, bit
	endif
		ERROR_NZ	BIT_MUST_BE_CLEAR
		endm

COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		Assert_inList
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Assert that an expression matches an item in a given list.

SYNTAX:		Assert	inList, ax, <TRUE, FALSE, -17>

CALLED BY:	Assert

PASS:		expr			- Expression to check
		list			- a list of as many values as you like

RETURN:		nothing

DESTROYED:	nothing

ERROR:		VALUE_NOT_IN_LIST

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	jdashe	4/12/95		Initial version
	jdashe	4/18/95		Adam-ized for your protection.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
VALUE_NOT_IN_LIST			enum	FatalErrors

Assert_inList	macro	expr, list
	local	equalsOK
	irp	x, <list>
		cmp	expr, x
		je	equalsOK
	endm
		ERROR	VALUE_NOT_IN_LIST
equalsOK:
	endm


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		_writecheck, _readcheck
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	validate a segment/offset pair

PASS:		seg	- segment of expression
		off	- offset of expression

PSEUDO CODE/STRATEGY:
	These macros are invoked automatically by esp when the
	directives .wcheck (write checking) and .rcheck (read
	checking) are encountered.
	
	The directives are not perfect, and as a result, any
	two-operand instruction assumes that the first operand
	is actually a destination and performs write-checking
	on it (this is not appropriate for stuff like 'cmp', but
	it doesn't hurt much either).
	
	Read/Write checking can be turned off using the .norcheck and
	.nowcheck directives.

KNOWN BUGS/SIDE EFFECTS/IDEAS:

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	JCW	8/11/94   	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
_writecheck	macro	expr, seg, isSI
	;
	; We turn off write checking here so that we don't recurse.
	;
	.nowcheck

  if	ERROR_CHECK

	ifdif <seg>, <ds>
		push	ds
		push	segregof expr
		pop	ds
	endif

	ifb <isSI>
		push	si
		lea	si, expr
	endif

		call	ECCheckBounds

	ifb <isSI>
		pop	si
	endif

	ifdif <seg>, <ds>
		pop	ds
	endif

  endif
	;
	; Now we restore write checking...
	;
	.wcheck
endm

_readcheck	macro	expr, seg, isSI
	;
	; We turn off read-checking here so that we don't recurse.
	;
	.norcheck

	;
	; We use the same code as for write checking... this may
	; change someday
	;
	_writecheck	<expr>, <seg>, <isSI>

	;
	; Now turn read-checking back on.
	;
	.rcheck
endm

ifdef	WRITE_CHECK
	.wcheck
endif

ifdef	READ_CHECK
	.rcheck
endif
