#ifndef ONSTACK_H
#define ONSTACK_H
//========================================================================================
//
//	This source file is a component of the Bedrock Class Library
//
//	File:				OnStack.h
//	Release Version:	$ 1.0d1 $
//
//	Creation Date:		22 December, 1992
//
//	Derived from BRTryBlo.h
//		Creation Date:		June 1, 1992
//
//	COPYRIGHT 1990-93 SYMANTEC CORPORATION. ALL RIGHTS RESERVED. UNPUBLISHED -- RIGHTS
//	RESERVED UNDER THE COPYRIGHT LAWS OF THE UNITED STATES. USE OF COPYRIGHT NOTICE IS
//	PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION OR DISCLOSURE.
//
//	THIS SOFTWARE Contains PROPRIETARY AND CONFIDENTIAL INFORMATION OF SYMANTEC
//	CORPORATION. USE, DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
//	EXPRESS WRITTEN PERMISSION OF SYMANTEC CORPORATION.
//
//	RESTRICTED RIGHTS LEGEND
//	Use, duplication, or disclosure by the Government is subject to restrictions as Set
//	forth in subparagraph (c)(l)(ii) of the Rights in Technical Data and Computer
//	Software clause at DFARS 252.227-7013. Symantec Corporation, 10201 Torre Avenue,
//	Cupertino, CA 95014.
//
//========================================================================================

#if !defined(BRPRIDEB_H) && defined(BR_BUILD_WIN)
#include "BRPriDeb.h"
#endif

#ifdef BR_BUILD_MAC

#if 1
// Slow version for use if (__OnStack()) xxx; works for near and far data
extern "C"
{
	#pragma parameter __OnStack(__A0)
	int __OnStack(void *)
		= {0x7000, 0xBFC8, 0x6408, 0xB1F8, 0x0908, 0x6202, 0x7001, 0x4880, 0x48C0};
}
/*
00000                          	OnStackCheck PROC
00000                          			;movea.l	a4,a0	; 4 compiler generated move
00000   7000                   			moveq	#0,d0
00002   BFC8                   			cmpa.l	a0,a7
00004   6408            0000E  			bcc.s	@1
00006   B1F8 0908              			cmpa.l	$908,a0
0000A   6202            0000E  			bhi.s	@1
0000C   7001                   			moveq	#1,d0
0000E                          		@1:
0000E   4880                   			ext.w	d0
00010   48C0                   			ext.l	d0
00012                          		ENDPROC
*/
#endif

#if 0
// Near data version
extern "C"
{
	#pragma parameter __OnStack(__A0)
	void __OnStack(void *)
		= {0xBFC8, 0x6210, 0xB1F8, 0x0908, 0x620A};
}
/*
00000                          	OnStack	PROC
00000                          			;movea.l	a4,a0	; 4 compiler generated move
00000   BFC8                   			cmpa.l	a0,a7		; 6
00002   6210            00014  			bhi.s	@1			; 10/8
00004   B1F8 0908              			cmpa.l	$908,a0		; 6
00008   620A            00014  			bhi.s	@1			; 10/8
0000A   2F0C                   			move.l	a4,-(a7)
0000C   486D 001E              			pea		30(a5)
00010   4EAD 001E              			jsr		30(a5)		; 18
00014                          		@1:
00014   4E71                   			nop
00016                          		ENDPROC
*/
#endif

#if 0
// Far data version for when the code is compiled with the -m option.
extern "C"
{
	#pragma parameter __OnStack(__A0)
	void __OnStack(void *)
		= {0xBFC8, 0x6218, 0xB1F8, 0x0908, 0x6212};
}
/*
00000                          	OnStackFar	PROC
00000                          			;movea.l	a4,a0	; 4 compiler generated move
00000   BFC8                   			cmpa.l	a0,a7		; 6
00002   6218            0001C  			bhi.s	@1			; 10/8
00004   B1F8 0908              			cmpa.l	$908,a0		; 6
00008   6212            0001C  			bhi.s	@1			; 10/8
0000A   2F0C                   			move.l	a4,-(a7)
0000C   204D                   			movea.l	a5,a0
0000E   D1FC 0001 0000         			adda.l	#-$FFFF0000,a0
00014   4855                   			pea		(a5)
00016   4EAD 001E              			jsr		30(a5)		; 18
0001A   504F                   			addq	#8,a7
0001C                          		@1:
0001C   4E71                   			nop
0001E                          		ENDPROC
*/
#endif

#endif

#ifdef BR_BUILD_WIN
//----------------------------------------------------------------------------------------
//	WinGetStackBottom
//----------------------------------------------------------------------------------------

inline unsigned short *WinGetStackBottom()
{
					asm(0x8C, 0xD2);			// mov DX, SS		2 cycles
#ifndef __BORLANDC__					
	return (void*)	
#endif
	asm(0xB8, 0x0E, 0x00);		// mov AX, 0Eh		2 cycles
}

inline unsigned short *WinGetStackTop()
{
					asm(0x8C, 0xD2);			// mov DX, SS		2 cycles
#ifndef __BORLANDC__					
	return (void*)	
#endif	
	asm(0xB8, 0x0A, 0x00);		// mov AX, 0Ah		2 cycles
}

inline unsigned short __SegmentOf(void* p)
{
	return (unsigned short)((unsigned long)p >> 16);
}

inline unsigned short __OffsetOf(void* p)
{
	return (unsigned short) p;
}

inline int __OnStack(void * p)
{
	int i;
	if (__SegmentOf(p) != __SegmentOf(&i))
		return 0;
	unsigned short top = *WinGetStackTop();
	unsigned short bot = *WinGetStackBottom();
#ifdef BR_DEBUG
	BR_PRIMITIVE_ASSERT(top < bot);
	long size = bot-top;
	BR_PRIMITIVE_ASSERT(size>=5000);
	BR_PRIMITIVE_ASSERT(size<=50000);
#endif
	unsigned short offset = __OffsetOf(p);
	return (offset>top && offset<bot);
}
#endif

#endif