gs2imm.s 7.59 KB
/*---------------------------------------------------------------------
	Copyright (C) 1997, Nintendo.
	
	File		gs2imm.s
	Coded    by	Yoshitaka Yasumoto.	Jan 23, 1997.
	Modified by	
	Comments	
	
	$Id: gs2imm.s,v 1.1.1.1 2002/05/02 03:29:12 blythe Exp $
  ---------------------------------------------------------------------*/
	
	# ================================================================
	# IMM 系処理
	# ================================================================

	# ----------------------------------------------------------------
	# case_G_RDPHALF_0
	#	TextureRectangle 系のコマンド Part 1 を処理する
	#	noYield を無くすためにまとめて処理を行なう
	# ----------------------------------------------------------------
case_G_RDPHALF_0:
	sw	gfx0, RSP_STATEP_RDPHALF_0H(zero)
	j	GfxDone
	sw	gfx1, RSP_STATEP_RDPHALF_0L(zero)

	# ----------------------------------------------------------------
	# case_G_RDPHALF_1
	#	TextureRectangle 系のコマンド Part 2 を処理する
	#	パラメータが足りない GBI の補助用にも使用
	# ----------------------------------------------------------------
case_G_RDPHALF_1:
	j	GfxDone
	sw	gfx1, RSP_STATEP_RDPHALF_1L(zero)
	
	# ----------------------------------------------------------------
	# case_G_TEXRECT_DONE
	#	TextureRectangle 系のコマンド Part 3 を処理する
	# ----------------------------------------------------------------
case_G_TEXRECT_DONE:
   Assign(cmd0, 1)
   Assign(cmd1, 2)
	lw	gfx0, RSP_STATEP_RDPHALF_1L(zero)
	sw	gfx1, 12(outp)
	lw	cmd1, RSP_STATEP_RDPHALF_0L(zero)
	sw	gfx0,  8(outp)
	lw	cmd0, RSP_STATEP_RDPHALF_0H(zero)
	sw	cmd1,  4(outp)
	addi	outp, outp, 16
	j	OutputCloseGfxDone
	sw	cmd0,  0-16(outp)
   EndAssign(cmd0, 1)
   EndAssign(cmd1, 2)

	# ----------------------------------------------------------------
	# case_G_ENDDL
	#	DL スタックを POP して 呼び出し側の DL へ処理を移す
	# ----------------------------------------------------------------
case_G_ENDDL:
  Assign(stackp, 2)
	lbu	stackp, RSP_STATEP_DL_N(zero)	# Load Delay 2clk
	beq	stackp, zero, TaskDone
	addi	stackp, stackp, -4
	sb	stackp, RSP_STATEP_DL_N(zero)
	j	StartDLload
	lw	inp, RSP_DLSTACK_OFFSET(stackp)
  EndAssign(stackp, 2)

	# ----------------------------------------------------------------
	# case_G_SETOTHERMODE_[LH]
	#	Other mode フラグを ON/OFF し RDP へ送る
	# ----------------------------------------------------------------
case_G_SETOTHERMODE_H:
	nop
case_G_SETOTHERMODE_L:
  Assign(mode,  1)
  Assign(shift, 2)
  Assign(maskA, 3)
  Assign(maskB, 4)
   .symbol adrs_G_SETOTHERMODE_L, (case_G_SETOTHERMODE_L & 0x1fff)
   .symbol RSP_OTHERMODE_DIFF,    (RSP_STATEP_OTHER_L-adrs_G_SETOTHERMODE_L)
	#
	# DL のデコード時にジャンプ先を代入した sys0 を用いて RSP_OTHERMODE 
	# の _H/_L の違いを吸収する
	#
	lw	mode,  RSP_OTHERMODE_DIFF(sys0)
	srl	shift, gfx0, 8
	nor	maskA, zero,  zero	# maskA = 0xffffffff
	#
	# sllv 命令のシフト数は下位 5 bit のみが有効なので
	# わざわざ and を掛ける必要はない
	#
	sllv	maskB, maskA, shift	# maskB = 0xffffffff << (shift)
	addi	gfx0,  gfx0,  -1	# len = 32 の場合のための対策 (len>0)
	sllv	maskA, maskB, gfx0	# maskA = 0xffffffff << (shift+len-1)
	sll	maskA, maskA, 1		# maskA = maskA << 1
	xor	maskA, maskA, maskB	# マスク値を得る
	nor	maskA, maskA, zero	# 反転させる
		#
		# 次の DL を調べ, もし case_G_OTHERMODE_* なら RDP へ送らず
		# に終了する
		#
		lb	gfx0, RSP_DLINPUT_BOTTOM(dinp)	# 次の DL を取得
	and	maskA, maskA, mode		# 変更するフラグをクリアする
		beq	dinp, zero, sendToRDP	# もし DL バッファが空なら送信
	or	mode,  maskA,  gfx1			# フラグの設定
		addi	sys1, gfx0, -G_SETOTHERMODE_L	# 次の DL の調査
		andi	sys1, sys1, 0xfe
		beq	sys1, zero, GfxDone1	# 次も SETOTHERMODE なら終了
  sendToRDP:
	sw	mode, RSP_OTHERMODE_DIFF(sys0)	# DMEM に変更を保存
	
	#
	# RDP コマンドを発行する
	#
#if	0			/* IMEM 節約にはこちらのコード */
	lw	gfx1, RSP_STATEP_OTHER_L(zero)	# この順序なのは意味あり
	j	case_G_RDP_General
	lw	gfx0, RSP_STATEP_OTHER_H(zero)
#else				/* 速度優先にはこちらのコード */
	# gfx0 を保存したまま GfxDone1 へ飛ぶことで高速化をしている
	lw	sys1, RSP_STATEP_OTHER_H(zero)
	addi	outp, outp, 8
	lw	gfx1, RSP_STATEP_OTHER_L(zero)
	sw	sys1, 0-8(outp)
	j	OutputCloseGfxDone
	sw	gfx1, 4-8(outp)
#endif
  EndAssign(mode,  1)
  EndAssign(shift, 2)
  EndAssign(maskA, 3)
  EndAssign(maskB, 4)

	# ----------------------------------------------------------------
	# case_G_MOVEWORD
	#	DMEM 内の指定位置に WORD データを書き込む
	#	現状では SEGMENT および General Status の設定にしか使用
	#	していない.
	# ----------------------------------------------------------------
case_G_MOVEWORD:
  Assign(target, 1)
  Assign(outptr, 2)
  Assign(offset, 3)
	andi	target, gfx0, 0xff

	# SEGMENT/GENSTAT の設定以外のコマンドなら停止
	Assert_geI(target, MOVEWORD_TBL_END+1)
	Assert_ltI(target, MOVEWORD_TBL_BEGIN)
	
	lhu	outptr, (RSP_MOVEWORD_TBL-MOVEWORD_TBL_BEGIN)(target)
	srl	offset, gfx0, 8
	add	outptr, outptr, offset
	j	GfxDone
	sw	gfx1, 0(outptr)
  EndAssign(target, 1)
  EndAssign(outptr, 2)
  EndAssign(offset, 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)

#if 1
 #========================================================================
 #  以下の 7 命令は gs2rdp.s から移動させたものである.
 #  これにより gs2imm.s の命令数がオーバーレイ領域と一致する.
 #========================================================================
	# ----------------------------------------------------------------
	# case_G_RDPSETOTHERMODE
	#	現在の OtherMode の設定を保存しておく.
	#	(G_SETOTHERMODE_[LH] のために必要)
	# ----------------------------------------------------------------
case_G_RDPSETOTHERMODE:
	sw	gfx0, RSP_STATEP_OTHER_H(zero)
	j	case_G_RDP_General
	sw	gfx1, RSP_STATEP_OTHER_L(zero)
	
	# ----------------------------------------------------------------
	# case_G_RDP_AdrsFixup
	#	コマンド内のセグメントアドレスを物理アドレスに変換してから
	#	RDP コマンドとして送る
	# ----------------------------------------------------------------
case_G_RDP_AdrsFixup:
  Assign(dram_adrs, 19)
	jal	AdrsFixup		
	addi	outp, outp, 8
	j	case_G_RDP_General2
	sw	dram_adrs, 4-8(outp)
  EndAssign(dram_adrs, 19)
#endif
	
 #----------------------------------------------------------------------------
 #	アドレス合せのための詰め物
 #	Overlay 領域 0 とのサイズを合わせるために nop を付加する
 #----------------------------------------------------------------------------
IMM_PAD_START:		.symbol	dummy_IMM_PAD_START, 0
			.space	(StartDLload & 0xfffffff8)+0x1000
IMM_PAD_END:		.symbol	dummy_IMM_PAD_END, 0
	
/*======== End of gs2imm.s ========*/