/*
 * $Id: u64macro.h,v 1.1 2003/02/07 18:15:44 wheeler Exp $
 *
 * ６４マクロ
 * 注意
 * 幾つかのマクロでは、グローバル変数に依存しています
 * SegmentBaseAddress:SetSegment*, GetSegment*, SEGMENT_TO_*, *_TO_SEGMENT
 * SegmentRomStart:SEGMENT_TO_ROM
 * IdentityMtx:g*SPPushMatrix,g*SPLoadIdentity
 *
 * $Log: u64macro.h,v $
 * Revision 1.1  2003/02/07 18:15:44  wheeler
 * Fox's version of libultra and friends.
 *
 * Revision 1.21  1997/03/05  05:32:52  hayakawa
 * モードの追加整理
 * ＤＭＡ転送削除
 *
 * Revision 1.20  1997/02/07  10:40:25  hayakawa
 * マクロ追加
 *
 * Revision 1.19  1996/11/26  10:18:37  hayakawa
 * グローバル変数に依存している
 *
 * Revision 1.18  1996/11/21  06:40:41  hayakawa
 * いろいろ変更
 *
 * Revision 1.17  1996/10/29  12:47:18  hayakawa
 * 高速gbiマクロを追加
 *
 * Revision 1.16  1996/10/20  09:18:56  hayakawa
 * DMACOPY変更
 *
 * Revision 1.15  1996/10/14  10:45:23  hayakawa
 * ヘッダ変更
 *
 */

#ifndef __U64MACRO_H_
#define __U64MACRO_H_

#include "ultra64.h"

/*
 * ウルトラ６４に関係のあるマクロなどの定義
 */

/*
 * プロジェクトのヘッダに持っていった方がいいかも
 */
#define	SCREEN_HT	240		/* 画面の縦サイズ（ドット） */
#define	SCREEN_WD	320		/* 画面の横サイズ（ドット）  */

#define TMEM_SIZE_FULL 4096	/* TMEMのサイズ（バイト） */
#define TMEM_SIZE_HALF 2048	/* ＣＩ用TMEMのサイズの半分（バイト） */



/*
 * gbi.h に追加するマクロ
 */
/* 32bitカラー作成 */
#define	GRGBA8888(r, g, b, a)	((r) << 24 | (g) << 16 | (b) << 8 | (a))
/*
 * 新しいコンバインモード
 */
/* テクスチャ表示(アルファ無効) */
#define	G_CC_RGB		0, 0, 0, TEXEL0, 0, 0, 0, 1
#define	G_CC_RGB1		G_CC_RGB
/* テクスチャ表示(アルファ有効) */
#define	G_CC_RGBA		0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0
/* ライト×プリミティブ */
#define	G_CC_SHADE_PRIM		SHADE, 0, PRIMITIVE, 0, SHADE, 0, PRIMITIVE, 0
/* テクスチャ×環境カラー */
#define	G_CC_MODULATEIA_ENV	TEXEL0, 0, ENVIRONMENT, 0, TEXEL0, 0, ENVIRONMENT, 0
#define	G_CC_MODULATERGBA_ENV	G_CC_MODULATEIA_ENV
/* プリミティブカラーと環境カラーの線形補完（係数はテクスチャカラー）  */    
#define	G_CC_BLENDPERGBA	PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT
/* テクスチャカラーとプリミティブカラーの線形補完（係数は環境カラー） */
#define	G_CC_BLENDPRGBA_ENV	PRIMITIVE, TEXEL0, ENVIRONMENT, TEXEL0, PRIMITIVE, TEXEL0, ENVIRONMENT, TEXEL0
/* テクスチャカラーとプリミティブカラーの線形補完（係数はプリミティブＬＯＤ） */
#define	G_CC_BLENDPRGBA		PRIMITIVE, TEXEL0, PRIM_LOD_FRAC, TEXEL0, PRIMITIVE, TEXEL0, PRIM_LOD_FRAC, TEXEL0
/* 色つきアルファテクスチャ */
#define G_CC_PRIMDECALA 	0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0
/* エッジがきれいなカラーテクスチャ（RGBA16とI4を結合するための）モード */
#define G_CC_MULTIBIT_ALPHA 	0, 0, 0, TEXEL0, 0, 0, 0, TEXEL1
/* G_CC_MULTIBIT_ALPHAをポリゴンに貼る */
#define G_CC_MODULATEIA_2TEX 	TEXEL0, 0, SHADE, 0, TEXEL1, 0, SHADE, 0
/* ニンジェン変換用につくった */
#define G_CC_MODULATEIA_SHADEPRIM TEXEL0, 0, SHADE, 0, TEXEL0, 0, PRIMITIVE, 0 /* ライトが当たって、プリミティブアルファを持つテクスチャ */
#define G_CC_MODULATERGBA_SHADEPRIM G_CC_MODULATEIA_SHADEPRIM
#define G_CC_SHADEPRIM_TRANSP	SHADE, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE /* ライトが当たらず、プリミティブアルファを持つポリゴン */
#define G_CC_SHADE_TRANSP	0, 0, 0, SHADE, 0, 0, 0, PRIMITIVE /* 不要？ */

#define G_CC_REFLECT_SHADE	TEXEL0, 0, PRIMITIVE, SHADE, TEXEL0, 0, PRIMITIVE, 0 /* テスト:ノーマルライト＋鏡面光 */
#define G_CC_MORPH_2TEX		TEXEL1, TEXEL0, PRIMITIVE_ALPHA, TEXEL0, TEXEL1, TEXEL0, PRIMITIVE, TEXEL0 /* ２つのテクスチャのモーフィング */
#define G_CC_NOISE2 		NOISE, 0, COMBINED, 0, 0, 0, 0, COMBINED /* １サイクル目につくった色に対して、２サイクル目にノイズをかける */

/*
 * 新しいレンダーモード
 */

/* コンバインアルファを使った加算モード（２サイクルモードの１サイクル目） */
#define	RM_ADD_ALPHA(clk)						\
	IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_OPA |			\
	GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1)
#define G_RM_ADD_ALPHA		RM_ADD_ALPHA(1)
#define G_RM_ADD_ALPHA2      	RM_ADD_ALPHA(2)

/* メモリの色を掛け算する（２サイクルモードの１サイクル目） */
#define	RM_MUL(clk)							\
	IM_RD | CVG_DST_SAVE | FORCE_BL |  ZMODE_OPA | 			\
	GBL_c##clk(G_BL_CLR_MEM, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1)
#define	G_RM_MUL		RM_MUL(1)
#define	G_RM_MUL2		RM_MUL(2)

/* ADDやMULの時の２サイクル目 */
#define	G_RM_FOG_SHADE_A2	GBL_c2(G_BL_CLR_FOG, G_BL_A_SHADE, G_BL_CLR_IN, G_BL_1MA)
#define	G_RM_FOG_PRIM_A2	GBL_c2(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_IN, G_BL_1MA)
#define	G_RM_PASS2		GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1)

/* 不透明RAサーフェイスフォグ付き（未テスト） */
#define	RM_RA_ZB_OPA_SURF_FOG(clk)				\
	AA_EN | Z_CMP | Z_UPD | CVG_DST_CLAMP |			\
	ZMODE_OPA | ALPHA_CVG_SEL |				\
	GBL_c##clk(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_IN, G_BL_1MA)
#define	G_RM_RA_ZB_OPA_SURF_FOG	RM_RA_ZB_OPA_SURF_FOG(1)
#define	G_RM_RA_ZB_OPA_SURF_FOG2	RM_RA_ZB_OPA_SURF_FOG(2)

/* 不透明サーフェイスフォグ付き（未テスト） */
#define	RM_ZB_OPA_SURF_FOG(clk)					\
	Z_CMP | Z_UPD | CVG_DST_FULL | ALPHA_CVG_SEL |		\
	ZMODE_OPA |						\
	GBL_c##clk(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_IN, G_BL_1MA)
#define	G_RM_ZB_OPA_SURF_FOG	RM_OPA_SURF_FOG(1)
#define	G_RM_ZB_OPA_SURF_FOG2	RM_OPA_SURF_FOG(2)

/* RM_AA_ZB_OPA_INTER と RM_AA_ZB_OPA_TERR の中間の性質を持つ？ */
#define	RM_AA_ZB_OPA_INTERR(clk)				\
	AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP |		\
	ZMODE_INTER | ALPHA_CVG_SEL |				\
	GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
#define	G_RM_AA_ZB_OPA_INTERR	RM_AA_ZB_OPA_INTERR(1)
#define	G_RM_AA_ZB_OPA_INTERR2	RM_AA_ZB_OPA_INTERR(2)

/* RM_AA_ZB_TEX_INTER と RM_AA_ZB_TEX_TERR の中間の性質を持つ？ */
#define	RM_AA_ZB_TEX_INTERR(clk)				\
	AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP |		\
	ZMODE_INTER | CVG_X_ALPHA | ALPHA_CVG_SEL |		\
	GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
#define	G_RM_AA_ZB_TEX_INTERR	RM_AA_ZB_TEX_INTERR(1)
#define	G_RM_AA_ZB_TEX_INTERR2	RM_AA_ZB_TEX_INTERR(2)

/* 半透明のデカル */
#define	RM_ZB_CLD_DECAL(clk)					\
	Z_CMP | IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_DEC |	\
	GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
#define	G_RM_ZB_CLD_DECAL	RM_ZB_CLD_DECAL(1)
#define	G_RM_ZB_CLD_DECAL2	RM_ZB_CLD_DECAL(2)

/*
 * 透明部分のカバレッジに影響を与えず、
 * 不透明部分のカバレッジをフルにする。
 * 半透明部分のカバレッジに少し影響を与える。(半透明には向かない)
 */
#define	RM_AA_TEX_CVG(clk)					\
	AA_EN | IM_RD | CVG_DST_CLAMP | 	 		\
	ZMODE_OPA | CVG_X_ALPHA | 				\
	GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
#define G_RM_AA_TEX_CVG    RM_AA_TEX_CVG(1)
#define G_RM_AA_TEX_CVG2   RM_AA_TEX_CVG(2)

#define	RM_AA_ZB_TEX_CVG(clk)					\
	AA_EN | Z_CMP | Z_UPD | IM_RD | CVG_DST_CLAMP | 	\
	ZMODE_OPA | CVG_X_ALPHA | 				\
	GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)
#define G_RM_AA_TEX_CVG    RM_AA_TEX_CVG(1)
#define G_RM_AA_TEX_CVG2   RM_AA_TEX_CVG(2)

/*
 * RAバージョンのG_RM_AA_TEX_EDGE
 */
#define	RM_RA_TEX_EDGE(clk)					\
	AA_EN | CVG_DST_CLAMP |					\
	CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE |	\
	GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_A_MEM)
#define	G_RM_RA_TEX_EDGE	RM_RA_TEX_EDGE(1)
#define	G_RM_RA_TEX_EDGE2	RM_RA_TEX_EDGE(2)
#define	RM_RA_TEX_EDGE_BL(clk)					\
	AA_EN | CVG_DST_CLAMP |					\
	CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE |	\
	GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_BL, G_BL_1MA)
#define	G_RM_RA_TEX_EDGE_BL	RM_RA_TEX_EDGE_BL(1)
#define	G_RM_RA_TEX_EDGE_BL2	RM_RA_TEX_EDGE_BL(2)

/*
 * ヌキの部分を更新しないので少し速い。
 * 内部エッジの処理は正しく行われない。
 * テクスチャレクタングルに向く
 * 
 */
#define RM_CLD_TEX_EDGE(clk) 						\
	IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_OPA |  			\
	AA_EN | CVG_X_ALPHA | TEX_EDGE | 				\
	GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)

#define RM_ZB_CLD_TEX_EDGE(clk) 					\
	Z_CMP | IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_OPA | 		\
	AA_EN | CVG_X_ALPHA | TEX_EDGE |				\
	GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)

#define	G_RM_CLD_TEX_EDGE	RM_CLD_TEX_EDGE(1)
#define	G_RM_CLD_TEX_EDGE2	RM_CLD_TEX_EDGE(2)
#define	G_RM_ZB_CLD_TEX_EDGE	RM_ZB_CLD_TEX_EDGE(1)
#define	G_RM_ZB_CLD_TEX_EDGE2	RM_ZB_CLD_TEX_EDGE(2)

#define RM_XLU_TEX_EDGE(clk) 						\
	IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_OPA |  			\
	AA_EN | CVG_X_ALPHA | TEX_EDGE | 				\
	GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)

#define RM_ZB_XLU_TEX_EDGE(clk) 					\
	Z_CMP | IM_RD | CVG_DST_SAVE | FORCE_BL | ZMODE_OPA | 		\
	AA_EN | CVG_X_ALPHA | TEX_EDGE |				\
	GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)

#define	G_RM_XLU_TEX_EDGE	RM_XLU_TEX_EDGE(1)
#define	G_RM_XLU_TEX_EDGE2	RM_XLU_TEX_EDGE(2)
#define	G_RM_ZB_XLU_TEX_EDGE	RM_ZB_XLU_TEX_EDGE(1)
#define	G_RM_ZB_XLU_TEX_EDGE2	RM_ZB_XLU_TEX_EDGE(2)

/* 半透明の影 */
#define	G_RM_ZB_SHADOW 		G_RM_ZB_CLD_DECAL
#define	G_RM_ZB_SHADOW2 	G_RM_ZB_CLD_DECAL2

/* フェードアウト(検討の結果RM_XLU_SURFと同じになりました) */
#define	G_RM_FADEOUT 		G_RM_XLU_SURF
#define	G_RM_FADEOUT2 		G_RM_XLU_SURF2

/*
 * 非アンチエリアスラインのテスト
 * マニュアルによるとポイントサンプリングにおいては、
 * ラインとサーフェイスに差はない
 */
#define	G_RM_ZB_XLU_LINE	G_RM_ZB_XLU_SURF
#define	G_RM_ZB_XLU_LINE2	G_RM_ZB_XLU_SURF2
#define	G_RM_ZB_DEC_LINE	G_RM_ZB_OPA_DECAL
#define	G_RM_ZB_DEC_LINE2	G_RM_ZB_OPA_DECAL2
#define	G_RM_XLU_LINE		G_RM_XLU_SURF
#define	G_RM_XLU_LINE2		G_RM_XLU_SURF2
#define	G_RM_DEC_LINE		G_RM_OPA_DECAL
#define	G_RM_DEC_LINE2		G_RM_OPA_DECAL2

/*
 * ターボマイクロコード系
 */
#define gtDisplayList(pkt, gst, sta, vtx, tri)				\
{ 									\
	gtGfx *_g = (gtGfx *)(pkt); 					\
									\
	_g->obj.gstatep = (gst);					\
	_g->obj.statep = (sta);						\
	_g->obj.vtxp = (vtx);						\
	_g->obj.trip = (tri);						\
}

/*
 * ＤＰのOtherModeを直接設定する
 */
#define	gDPSetOtherModeLH(pkt, low, high) 				\
    gDma0p(pkt, G_RDPSETOTHERMODE, low, high)

#define	gsDPSetOtherModeLH(low, high) 					\
    gsDma0p(G_RDPSETOTHERMODE, low, high)

#define	gDPSetOtherModeHL(pkt, high, low) 				\
    gDma0p(pkt, G_RDPSETOTHERMODE, low, high)

#define	gsDPSetOtherModeHL(high, low) 					\
    gsDma0p(G_RDPSETOTHERMODE, low, high)

#define	gDPSetOtherMode gDPSetOtherModeLH
#define	gsDPSetOtherMode gsDPSetOtherModeLH

/*
 * ＳＰのOtherModeを直接設定する
 * 同時にＤＰのOtherModeも設定される
 */
#define gsSPSetOtherModeHL(high, low) 					\
									\
	gsSPSetOtherMode(G_SETOTHERMODE_H, 0, 24, high), 		\
	gsSPSetOtherMode(G_SETOTHERMODE_L, 0, 3, low), 			\
	gsSPSetOtherMode(G_SETOTHERMODE_L, 3, 29, low)
    
#define gSPSetOtherModeHL(pkt, high, low) 				\
{									\
	gSPSetOtherMode(pkt, G_SETOTHERMODE_H, 0, 24, high); 		\
	gSPSetOtherMode(pkt, G_SETOTHERMODE_L, 0, 3, low); 		\
	gSPSetOtherMode(pkt, G_SETOTHERMODE_L, 3, 29, low); 		\
}

/*
 * SPが保持しているOtherModeに戻す
 * gDPSetOtherModeで変更した直後に有効
 */
#define gSPResetOtherMode(pkt) 						\
	gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_COLORDITHER, 1, 0)

#define gsSPResetOtherMode() 						\
    	gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_COLORDITHER, 1, 0)
    
/*
 * 行列関連の便をはかる
 */
#define	gSPMultMatrix(pkt, m, n)  					\
    	gSPMatrix(pkt, m, (n)|G_MTX_MUL)

#define	gsSPMultMatrix(m, n) 						\
    	gsSPMatrix(m, (n)|G_MTX_MUL)

#define	gSPLoadMatrix(pkt, m, n)  					\
    	gSPMatrix(pkt, m, (n)|G_MTX_LOAD)

#define	gsSPLoadMatrix(m, n) 						\
    	gsSPMatrix(m, (n)|G_MTX_LOAD)

#define	gSPPushMatrix(pkt, n)     					\
    	gSPMatrix(pkt, (IdentityMtx.m), (n)|G_MTX_MUL|G_MTX_PUSH)

#define	gsSPPushMatrix(n)    						\
    	gsSPMatrix((IdentityMtx.m), (n)|G_MTX_MUL|G_MTX_PUSH)

#define	gSPLoadIdentity(pkt, n)   					\
    	gSPMatrix(pkt, (IdentityMtx.m), (n)|G_MTX_LOAD)

#define	gsSPLoadIdentity(n)  						\
    	gsSPMatrix((IdentityMtx.m), (n)|G_MTX_LOAD)
    
/*
 * 色をパック形式で設定する（高速）
 */
#define	gDPSetEnvColor_rgba8888(pkt, rgba8888)				\
            gDPSetColor(pkt, G_SETENVCOLOR, rgba8888)
#define	gDPSetBlendColor_rgba8888(pkt, rgba8888)			\
            gDPSetColor(pkt, G_SETBLENDCOLOR, rgba8888)
#define	gDPSetFogColor_rgba8888(pkt, rgba8888)				\
            gDPSetColor(pkt, G_SETFOGCOLOR, rgba8888)
#define	gDPSetPrimColor_rgba8888(pkt, m, l, rgba8888)			\
{									\
	Gfx *_g = (Gfx *)(pkt);						\
									\
	_g->words.w0 =	(_SHIFTL(G_SETPRIMCOLOR, 24, 8) | 		\
			 _SHIFTL(m, 8, 8) | _SHIFTL(l, 0, 8));		\
	_g->words.w1 =  (unsigned int)(rgba8888);			\
}

/*
 * Vtx型の頂点データを設定するマクロ
 */
#define makeVtx(vtx, x, y, z, f, s, t, r, g, b, a) \
    ((vtx)->v.ob[0] = (short)(x), \
     (vtx)->v.ob[1] = (short)(y), \
     (vtx)->v.ob[2] = (short)(z), \
     (vtx)->v.flag  = (unsigned short)(f), \
     (vtx)->v.tc[0] = (short)(s), \
     (vtx)->v.tc[1] = (short)(t), \
     (vtx)->v.cn[0] = (unsigned char)(r), \
     (vtx)->v.cn[1] = (unsigned char)(g), \
     (vtx)->v.cn[2] = (unsigned char)(b), \
     (vtx)->v.cn[3] = (unsigned char)(a))
    
    
/*
 * セグメントのサイズを返す
 */
#define SEGMENT_ROM_SIZE(name) \
    (u32)(_##name##SegmentRomEnd - _##name##SegmentRomStart)
#define SEGMENT_SIZE(name) \
    (u32)(_##name##SegmentEnd - _##name##SegmentStart)

/*
 * spec file で定義される外部アドレスの定義
 */
				/* コードセグメント用 */
#define EXTERN_DEFSEG_CODE(name) \
    extern char \
    _##name##SegmentStart[], \
    _##name##SegmentTextStart[], \
    _##name##SegmentTextEnd[], \
    _##name##SegmentDataStart[], \
    _##name##SegmentDataEnd[], \
    _##name##SegmentBssStart[], \
    _##name##SegmentBssEnd[], \
    _##name##SegmentEnd[], \
    _##name##SegmentRomStart[], \
    _##name##SegmentRomEnd[]
				/* データセグメント用 */
#define EXTERN_DEFSEG_DATA(name) \
    extern char \
    _##name##SegmentStart[], \
    _##name##SegmentEnd[], \
    _##name##SegmentRomStart[], \
    _##name##SegmentRomEnd[]
				/* ＲＡＷデータ用 */
#define EXTERN_DEFSEG_RAW(name) \
    extern char \
    _##name##SegmentRomStart[], \
    _##name##SegmentRomEnd[]
    
#define EXTERN_DEFSEG(name) EXTERN_DEFSEG_CODE(name)

/*
 * セグメントテーブルバッファを登録する(gsSegmentと同じ形)
 */
/* 内部テーブルにセグメント先頭アドレスをセット */
#define xSetSegment(segtbl, number, base) ((segtbl)[number] = (u32)(base))
#define SetSegment(number, base) xSetSegment(SegmentBaseAddress, number, base)
/* 内部テーブルにセグメント先頭アドレスをセット(K0アドレス) */
#define xSetSegmentK0(segtbl, number, base) xSetSegment(segtbl, number, OS_K0_TO_PHYSICAL(base))
#define SetSegmentK0(number, base) SetSegment(number, OS_K0_TO_PHYSICAL(base))
/* 内部テーブルからセグメント先頭アドレスをゲット */
#define xGetSegment(segtbl, number) ((segtbl)[number])
#define GetSegment(number) xGetSegment(SegmentBaseAddress, number)
/* 内部テーブルからセグメント先頭アドレスをゲット(K0アドレス) */
#define xGetSegmentK0(segtbl, number) OS_PHYSICAL_TO_K0(xGetSegment(segtbl, number))
#define GetSegmentK0(number) xGetSegmentK0(SegmentBaseAddress, number)
    
/*
 * セグメントアドレスをROMアドレスに変換する
 */
#define xSEGMENT_TO_ROM(segtbl, addr) \
    ((segtbl)[SEGMENT_NUMBER(addr)] + (unsigned long)SEGMENT_OFFSET(addr))
#define SEGMENT_TO_ROM(addr) xSEGMENT_TO_ROM(SegmentRomStart, addr)
    
/*
 * セグメントアドレスを物理アドレスに変換する
 */
#define xSEGMENT_TO_PHYSICAL(segtbl, addr) \
    ((segtbl)[SEGMENT_NUMBER(addr)] + (unsigned long)SEGMENT_OFFSET(addr))
#define SEGMENT_TO_PHYSICAL(addr) \
    xSEGMENT_TO_PHYSICAL(SegmentBaseAddress, addr)
    
/*
 * セグメントアドレスをKSEG0アドレスに変換する
 */
#define xSEGMENT_TO_KSEG0(segtbl, addr) \
     ((void *)OS_PHYSICAL_TO_K0(xSEGMENT_TO_PHYSICAL(segtbl, addr)))
#define SEGMENT_TO_KSEG0(addr) xSEGMENT_TO_KSEG0(SegmentBaseAddress, addr)
    
/*
 * セグメント番号＋物理アドレスをセグメントアドレスに変換する
 */
#define xPHYSICAL_TO_SEGMENT(segtbl, num, addr) \
    ((void *)SEGMENT_ADDR((num), ((addr) - (segtbl)[num])))
#define PHYSICAL_TO_SEGMENT(num, addr) \
    xPHYSICAL_TO_SEGMENT(SegmentBaseAddress, num, addr)
    
/*
 * セグメント番号＋KSEG0アドレスをセグメントアドレスに変換する
 */
#define xKSEG0_TO_SEGMENT(segtbl, num, addr) \
    xPHYSICAL_TO_SEGMENT(segtbl, num, OS_K0_TO_PHYSICAL(addr))
#define KSEG0_TO_SEGMENT(num, addr) \
    xKSEG0_TO_SEGMENT(SegmentBaseAddress, num, addr)

/*
 * 仮想アドレスを物理アドレスに変換する
 */
#define VIRTUAL_TO_PHYSICAL(addr) \
    osVirtualToPhysical(addr)
    
/*
 * 物理アドレスを仮想アドレスに変換する
 */
#define PHYSICAL_TO_VIRTUAL(addr) \
    osPhysicalToVirtual(addr)
    
/*
 * 仮想アドレスをKSEG0アドレスに変換する
 */
#define VIRTUAL_TO_KSEG0(addr) \
    OS_PHYSICAL_TO_K0(OS_K0_TO_PHYSICAL(addr))

/*
 * KSEG0アドレスをKSEG1アドレスに変換する
 */
#define KSEG0_TO_KSEG1(addr) \
    (void *)((unsigned int)(addr) | 0xa0000000)

/*
 * KSEG0   void *
 * Segment void *
 * Virtual void *
 * Physical unsigned int
 * ROM     unsigned long
 */
    
/*
 * セグメントテーブルバッファ
 */
extern unsigned long SegmentBaseAddress[NUM_SEGMENTS];
extern const unsigned long SegmentRomStart[NUM_SEGMENTS]; /* SEGMENT_TO_ROM */

/*
 * gSPPushMatrix,gSPLoadIdentity用
 */
#if 1
#include "mtxuty-long.h"	/* extern Mtx2 IdentityMtx; */
#else
//extern Mtx2 IdentityMtx;
#endif

/*
 * "u64debug.h" 
 */


#endif /* __U64MACRO_H_ */
