//--------------------------------------------------------------------------------------
//
// X-BASIC'
// 	一般定義
//
//--------------------------------------------------------------------------------------

#ifndef	__XB_DEFINES__
#define __XB_DEFINES__	1

//--------------------------------------------------------------------------------------

#include "XBversions.h"

//--------------------------------------------------------------------------------------

// bit番号の値を得る
#define	bit(no)		(1<<(no))

//-------------------------------------------------------------------

#define	BASIC_YES	(-1)		// basicでのYESはCと異なる
#if !defined(YES)
#define	YES			(1==1)
#endif
#if !defined(NO)
#define	NO			(!YES)
#endif
#define	BASIC_NO	NO

//-------------------------------------------------------------------
// 共用体

// sizeof(ULong)>=sizeof(UWord)*2じゃなかったらプログラムの書き換えが必要
typedef union {
	ULong	l;									// 32bitならsizeof(ULong)=sizeof(ULong *)
	UWord	w[sizeof(ULong)/sizeof(UWord)];		// 0,1
	UByte	b[sizeof(ULong)/sizeof(UByte)];		// 0,1,2,3
} LONG_WORD;
enum { // wのどちらがH/Lか;全ての共用体で同じになる
	LW=0,	// low  word
	HW		// high word
};
// ARMの順はL→H , X68では逆に定義する必要がある

#define	MAX_DL	(sizeof(double)/sizeof(ULong))		// doubleのサイズにULongが幾つ入るか
#define	MAX_DP	(sizeof(double)/sizeof(void *))		// doubleのサイズにvoid *が幾つ入るか
typedef union {
	double 	d;				// 常に符号あり;double=8バイト64bit
	//
	long long	sll;		// 符号あり64bit long long
	unsigned long long	ll;	// 符号なし64bit long long
	//
	ULong	 l[MAX_DL];		// 符号なし
	SLong	sl[MAX_DL];		// 符号あり;(double)への型キャストをするときはこちらを使わなければならない
	//
	UByte	*bp[MAX_DP];	// 符号なしcharポインタ
	char	*cp[MAX_DP];	// (符号あり)charポインタ
	int		*ip[MAX_DP];	// 符号ありintポインタ
	double	*dp[MAX_DP];	// doubleポインタ
} DOUBLE_LONG;
#define	SZ_DOUBLE_LONG	sizeof(DOUBLE_LONG)
enum { // wのどちらがH/Lか;全ての共用体で同じになる
	LL=0,	// .pは64bitではこちらだけ		low  longword
	HL		//							high longword
};
// ARMの順はL→H , X68では逆に定義する必要がある


// ポインターの格納できる型
// 本当はsize_tで定義すれば一発なのだが、なぜかsize_tが未定義と言われるので仕方なくpsize_tで定義
#ifdef ARM64
typedef	unsigned long	psize_t;
#else
typedef	ULong 			psize_t;
#endif

// アドレスレジスタ相当
typedef union {
	psize_t		l;
	psize_t		*pp;
	void		**vp;		// *〜.vp=void *		sizeof(void *)=size_t
	//
	ULong		*lp;		// *〜.lp=ULong
	UWord		*wp;		// *〜.wp=UWord
	UByte		*bp;		// *〜.bp=UByte
	//
	DOUBLE_LONG	*dp;		// *〜.dp=DOUBLE_LONG
} REGISTER;

//-------------------------------------------------------------------
// 基本関数

#define	b32(w)		(((w)&0xff000000)>>24)
#define	b24(w)		(((w)&0x00ff0000)>>16)
#define	b16(w)		(((w)&0x0000ff00)>> 8)
#define	b8(w)		( (w)&0x000000ff)

#define	w16(h,l)			(((h)<<8)|(l))
#define	w24(hl,lh,ll)		(      ((hl)<<16)|w16(lh,ll))
#define	w32(hh,hl,lh,ll)	((w16(hh,hl)<<16)|w16(lh,ll))

//-------------------------------------------------------------------
// NaNを表す文字列(V2.1)

#define STR_NaN	"NaN"
#define LEN_NaN	(sizeof(STR_NaN)-1)	// STR_NaNのEOS位置

//-------------------------------------------------------------------

#endif
