gxs2imm.s 10.3 KB
/*---------------------------------------------------------------------*
	Copyright (C) 1997, Nintendo.
	
	File		gxs2imm.s
	Coded    by	Yoshitaka Yasumoto.	Oct 20, 1997.
	
	$Id: gxs2imm.s,v 1.1.1.1 2002/05/02 03:29:11 blythe Exp $
 *---------------------------------------------------------------------*/
	
 #============================================================================
 #  IMM 系処理
 #============================================================================
#ifndef	OVERLAY
#else	/* OVERLAY */
		.symbol	case_G_SPECIAL_1, GfxDone
		.symbol	case_G_SPECIAL_2, GfxDone
		.symbol	case_G_SPECIAL_3, GfxDone
	
	#---------------------------------------------------------------------
	#  case_G_DMA_IO (DEBUG 用)
	#	IMEM/DMEM 内のデータを DMA で DRAM へ読み出したり書き出し
	#	たりする.
	#
	#	+------------+-+----------+---+-+------+--------+---+
	#	|   DMA_IO   |F|  dmem_adrs/8 |0|   dma_len/8   |000|
	#	+------------+-+----------+---+-+------+--------+---+
	#	|                    dram adrs                      |
	#	+------------+------------+------------+------------+
	#---------------------------------------------------------------------
  AssignForDMAproc
case_G_DMA_IO:	
	jal	AdrsFixup
	lh	dmem_adrs, RSP_DLINPUT_BOTTOM-7(dinp)	# F が符号拡張される
	andi	dma_len,   gfx0, 0xff8
	sra	dmem_adrs, dmem_adrs, 2
	j	DMAproc
	_li	(return, DMAwaitGfxDone)
  EndAssignForDMAproc	
	
	#---------------------------------------------------------------------
	#  case_G_RDPHALF_0
	#	GBI を内部バッファに保存する.
	#	TextureRectangle 系のコマンド Part 1 を処理する
	#---------------------------------------------------------------------
	#  case_G_RDPHALF_1
	#	GBI を内部バッファに保存する.
	#	TextureRectangle 系のコマンド Part 2 を処理する
	#	パラメータが足りない GBI の補助用にも使用
	#---------------------------------------------------------------------
	#	RSP_STATEP_RDPHALF_0L と RSP_STATEP_RDPHALF_1L のアドレス差
	#	が 4Bytes であることを利用して共通化する.
	#---------------------------------------------------------------------
	.symbol adrs_G_RDPHALF_0, case_G_RDPHALF_0 & 0x1fff
	.symbol RSP_RDPHALF_DIFF, RSP_GSTAT_RDPHALF_0H - adrs_G_RDPHALF_0
case_G_RDPHALF_0:
	sw	gfx0, RSP_RDPHALF_DIFF+0(sys0)
case_G_RDPHALF_1:
	j	GfxDone
	sw	gfx1, RSP_RDPHALF_DIFF+4(sys0)
	
	#---------------------------------------------------------------------
	#  case_G_SELECT_DL
	#	条件に一致した場合において DL を呼び出す.
	#	+------------------------------------------+
	#	|G_RDPHALF_0|  sid:8   |      DL_L:16      |
	#	+------------------------------------------+
	#	|                  flag:32                 |
	#	+------------------------------------------+
	#	|G_SELECT_DL|  param:8 |      DL_H:16      |
	#	+------------------------------------------+
	#	|                  mask:32                 |
	#	+------------------------------------------+
	#
	#	(STATUS[sid] & mask) == flag の場合には, 呼び出さない.
	#	その他の場合, 呼び出しを行ない STATUS を以下のように変更.
	#	STATUS[sid] = (STATUS[sid] & ~mask) | (flag & mask); 
	#
	#	gfx1 に DL の値を代入し G_DL へ処理を移す.
	#	param は G_DL_PUSH, G_DL_NOPUSH のいづれかである.
	#---------------------------------------------------------------------
case_G_SELECT_DL:
  Assign(sid,    1)
  Assign(status, 2)
  Assign(flag,   3)
  Assign(flag2,  4)
# define mask    gfx1
  Assign(maskR,  5)
  Assign(tmp,    6)
		lbu	sid,    RSP_STATEP_RDPHALF_0H+1(zero)
		lw	flag,   RSP_STATEP_RDPHALF_0L(zero)
		nor	maskR,  mask,   zero
		lw	status, RSPOBJ_GENSTAT_TABLE(sid)
		sh	gfx0,   RSP_STATEP_RDPHALF_0H(zero)
		and	flag2,  flag,   mask
		and	tmp,    status, mask
		beq	tmp,    flag,   GfxDone	# status & mask == flag なら終
		and	tmp,    status, maskR
		or	tmp,    tmp,    flag2		    # 新 status の作成
		sw	tmp,    RSPOBJ_GENSTAT_TABLE(sid)	# 新 stat 保存
		lw	gfx1,   RSP_STATEP_RDPHALF_0H(zero)	# DL の取得
		# gfx1 に DL のポインタを代入して G_DL へ抜ける
  EndAssign(sid,    1)
  EndAssign(status, 2)
  EndAssign(flag,   3)
  EndAssign(flag2,  4)
# undef     mask
  EndAssign(maskR,  5)
  EndAssign(tmp,    6)

	#---------------------------------------------------------------------
	#  case_G_DL
	#	指定された DL へ処理を移す.
	#	gfx0 の bit15 が 1 なら gSPBranchDL, 0 なら gSPDisplayList 
	#	となる. DL スタックのオーバーフローのチェックはしていない.
	#---------------------------------------------------------------------
case_G_DL:
  FixedAssign(stackp,   1)
  FixedAssign(param,    2)
       Assign(save_inp, 3)
		lbu	stackp, RSP_GSTAT_DL_N(zero)
		sll	param, gfx0, 15
case_G_DL_0:	jal	AdrsFixup	# gximm_ex.s から Jump in する
		add	save_inp, inp, dinp
		bltz	param, StartDLload
		_mov	(inp, dram_adrs)
		sw	save_inp, RSP_GSTAT_DLSTACK_OFFSET(stackp)
		addi	stackp, stackp, 4
case_G_DL_1:	j	StartDLload	# G_ENDDL から Jump in する
		sb	stackp, RSP_GSTAT_DL_N(zero)
  EndAssign(param,    2)
  EndAssign(save_inp, 3)
	
	#---------------------------------------------------------------------
	#  case_G_ENDDL
	#	DL スタックを POP して 呼び出し側の DL へ処理を移す
	#
	#	JUMP 先の TaskDone は stackp($1) で DL スタックの計算を行な
	#	うことに依存したコードとなっているので変更するときは注意する.
	#---------------------------------------------------------------------
case_G_ENDDL:	lbu	stackp, RSP_GSTAT_DL_N(zero)	# Load Delay 2clk
		beq	stackp, zero, TaskDone		# stackp == -4 で Jump
		addi	stackp, stackp, -4
		j	case_G_DL_1
		lw	inp, RSP_GSTAT_DLSTACK_OFFSET(stackp)
  EndAssign(stackp, 1)

	#---------------------------------------------------------------------
	#  case_G_MOVEWORD
	#	32bit データを DMEM に書き込む
	#
	#	Level 2 から GBI が変更になったので注意すること.
	#	+------------+------------+------------+------------+
	#	|  MOVEWORD  |   index    |         offset          |
	#	+------------+------------+------------+------------+
	#	|                       data                        |
	#	+------------+------------+------------+------------+
	#
	#	DMEM のレンジは下位 12 Bit しかないので上位の値をあえて
	#	マスクする必要はない.
	#---------------------------------------------------------------------
case_G_MOVEWORD:
  Assign(index, 1)
  FixedAssign(adrs,  2)
		srl	index, gfx0, 16
		lhu	adrs, RSP_LSTAT_MOVEWORD_OFFSET-(G_MOVEWORD<<8)(index)
case_G_MOVEWORD_0:
		#  gximm_ex.s からここへ Jump する
		add	adrs, adrs, gfx0
		j	GfxDone
		sw	gfx1, 0(adrs)
  EndAssign(index, 1)
  EndAssign(adrs,  2)
	
	#---------------------------------------------------------------------
	#  case_G_OBJ_MOVEMEM
	#	RDRAM から DMEM へデータの転送を行なう
	#	+-----------------------+
	#	|CMD:8|Len:8|   ID:16   |
	#	+-----------------------+
	#	|    Source Adrs:32     |
	#	+-----------------------+
	#
	#	Matrix     スプライトの回転のためのマトリクスをロードする.
	#	SubMatrix  スプライトの移動, スケーリング値をロードする.
	#---------------------------------------------------------------------
case_G_OBJ_MOVEMEM:
  AssignForDMAproc
	jal	AdrsFixup		# Matrix データのアドレスの変換
	lhu	dmem_adrs, RSP_MOVEMEM_TBL(gfx0)	# 転送先アドレス
	lbu	dma_len, (RSP_DLINPUT_BOTTOM-7)(dinp)
	j	DMAread
case_G_SETOTHERMODE_H:
	_li	(return, DMAwaitGfxDone)
  EndAssignForDMAproc
	
	#===== この間に命令をいれてはならん. =====
	#---------------------------------------------------------------------
	# case_G_SETOTHERMODE_[LH]
	#	Other mode フラグを ON/OFF し RDP へ送る
	#	case_G_SETOTHERMODE_H と case_G_SETOTHERMODE_L のアドレス差
	#	が 4 Bytes であることを利用して処理を行なっているのでこれを
	#	変更する場合はここを修正すること. case_G_SETOTHERMODE_H は
	#	この前のルーチン case_G_DMA_General 内にそのエントリがある.
	#	本命令は RDP 系の命令ではあるが, 他の RDP 系の命令の中で都
	#	合の良い命令で終るもの(case_G_SETOTHERMODE_H のエントリとし
	#	て使えそうな命令)が gxrdp.s 内に無かったため, 止む終えず
	#	gximm.s	に置いてある.
	#
	#	Level 2 から GBI が変更になったので注意すること.
	#	+------------+------------+------------+------------+
	#	|OTHERMODE_LH|            |32-shift-len|    len-1   |
	#	+------------+------------+------------+------------+
	#	|                       data                        |
	#	+------------+------------+------------+------------+
	#
	#	DL のデコード時にジャンプ先を代入した sys0 を用いて
	#	RSP_OTHERMODE の _H/_L の違いを吸収する.
	#	srlv/srav 命令のシフト数は下位 5 bit のみが有効なので
	#	わざわざ and を掛ける必要はない.
	#---------------------------------------------------------------------
case_G_SETOTHERMODE_L:
  Assign(shft, 1)
  Assign(mask, 2)
  Assign(mode, 3)
   .symbol adrs_G_SETOTHERMODE_L, (case_G_SETOTHERMODE_L & 0x1fff)
   .symbol RSP_OTHERMODE_DIFF,    (RSP_GSTAT_OTHER_L-adrs_G_SETOTHERMODE_L)
	lw	mode, RSP_OTHERMODE_DIFF(sys0)
	lui	mask, 0x8000		# mask = 0x80000000
	srav	mask, mask, gfx0	# mask = 11..100..0b (1 が len 個)
	srl	shft, gfx0, 8		# shift 値の取得
	srlv	mask, mask, shft	#           mask = 00..011..100..0
	nor	mask, mask, zero	# Bit 反転  mask = 11..100..011..1
	and	mode, mode, mask		# 変更するフラグをクリアする
	or	mode, mode, gfx1		# フラグ変更
	sw	mode, RSP_OTHERMODE_DIFF(sys0)	# DMEM に変更を保存
	lw	gfx0, RSP_GSTAT_OTHER_H(zero)
	j	case_G_RDP_General
	lw	gfx1, RSP_GSTAT_OTHER_L(zero)
  EndAssign(shft, 1)
  EndAssign(mask, 2)
  EndAssign(mode, 3)
	
	#---------------------------------------------------------------------
	# case_G_OBJ_RENDERMODE
	#	OBJ の描画モードを RSP に知らせる.
	#
	#	G_OBJRM_NOTXCLAMP	0x01
	#	G_OBJRM_XLU		0x02   # Ignored
	#	G_OBJRM_ANTIALIAS	0x04   # Ignored
	#	G_OBJRM_BILERP		0x08
	#	G_OBJRM_SHRINKSIZE_1	0x10
	#	G_OBJRM_SHRINKSIZE_2	0x20
	#	G_OBJRM_SHRINKSIZE_3	0x30
	#	G_OBJRM_WIDEN		0x40
	#
	#	gfx0 = [Cmd |            ]
	#	gfx1 = [            |Mode]
	#---------------------------------------------------------------------
case_G_OBJ_RENDERMODE:
  Assign(ptr, 1)
  Assign(shiftA, 2)
  Assign(shiftB, 3)
	sb	gfx1, RSPOBJ_RENDERMODE(zero)
	#
	# Transparent/AntiAlias/Bilerp の設定
	#
	andi	ptr, gfx1, 0x08		# 8 倍
	addiu	ptr, ptr,  RSPOBJ_RENDERTBL_SMODE
	sh	ptr, RSPOBJ_RENDERP_SMODE(zero)
	#
	# Texture Window
	#	
	andi	ptr, gfx0, 0x08
	addiu	ptr, ptr,  RSPOBJ_RENDERTBL_TWINDOW
	sh	ptr, RSPOBJ_RENDERP_TWINDOW(zero)
	#
	# Shrink Param [2|3]
	#
	andi	ptr, gfx1, 0x18		# Bilerp|Shrink1
	srl	ptr, ptr,  1
	lw	shiftB, RSPOBJ_SHRINKOBJ_TBL(ptr)
	#
	# Shrink Param [0|1]
	#
	andi	ptr, gfx1, 0x70		# Shrink1|Shrink2|Widen
	srl	ptr, ptr,  2
	lw	shiftA, RSPOBJ_SHRINKIMG_TBL(ptr)
	sw	shiftB, RSPOBJ_SHRINKPARAM+4(zero)
	j	GfxDone
	sw	shiftA, RSPOBJ_SHRINKPARAM+0(zero)
  EndAssign(ptr, 1)
  EndAssign(shiftA, 2)
  EndAssign(shiftB, 3)
	
#endif	/* OVERLAY */

/*======== End of gximm.s ========*/