gxinit.s 11.3 KB
/*---------------------------------------------------------------------*
	Copyright (C) 1997, Nintendo.
	
	File		gxinit.s
	Coded    by	Yoshitaka Yasumoto.	Oct 20, 1997.
	
	$Id: gxinit.s,v 1.1.1.1 2002/05/02 03:29:11 blythe Exp $
 *---------------------------------------------------------------------*/
	#---------------------------------------------------------------------
	#  初期化を行なう.
	#	この領域は初期化処理後にオーバーレイされるのであまり命令数に
	#	気をはらう必要はないので, 先に計算できるものは成るべくここで
	#	しておく.
	#---------------------------------------------------------------------

	#---------------------------------------------------------------------
	#  定数の初期化
	#	outp		DMEM 内のコマンドバッファのポインタ
	#	outpThd		DMEM 内のコマンドバッファの FULL 判定ポインタ
	#	vzero		全ての要素が 0 の Vec. Reg.
	#	vone		全ての要素が 1 の Vec. Reg.
	#	vconst*		VU 計算時に使用する定数値を保持する
	#---------------------------------------------------------------------
		# Vzero is initialized once in a task.
#if	(defined(USE_RSPBOOT0) && !defined(SAFE_MODE))
		vor	vzero, $v16, $v16	# $v16->vzero へ
#else
		vxor	vzero, vzero, vzero
#endif
	
RSP_LOADUCODE_Return:
		lqv     vconst0[0], RSP_LSTAT_VCONST0(zero)
	        lqv     vconst1[0], RSP_LSTAT_VCONST1(zero)
#ifdef	UCODE_S2DEX2
		lqv     vconst2[0], RSP_LSTAT_VCONST2(zero)
	        lqv     vconst3[0], RSP_LSTAT_VCONST3(zero)
		_li	(vecptr, RSPOBJ_VPTR)
#endif
		_li     (outp,    RSP_WORK_OUTPUT_0)
		vadd	vone, vzero, vzero		# Clear VCO DEBUG v2.08
		_li	(outpThd, RSP_WORK_OUTPUT_THD_0)
		vsub	vone, vzero, _0xffff

#if	defined(OUT_fifo)
	#---------------------------------------------------------------------
	#  STATUS フラグのクリア
	#	SP_STATUS	YIELDED/TASKDONE フラグのクリア
	#
	#  初期状態/LoadUcode後状態/Yield 復帰 かの判定
	#	RSP_GSTAT_FIFO_OUTP が 0 なら初期状態であるとみなし, FIFO の
	#	設定処理を行なう.
	#	GTASK_FLAGS を参照して OS_TASK_YIELDED フラグを調べ Yield 
	#	復帰でないなら LoadUcode 後の処理へ JUMP する.
	#	また Yield 復帰後に LoadUcode を処理する場合に対応するため,
	#	GTASK_FLAGS をクリアしておく.
	#---------------------------------------------------------------------
  Assign(sys2, 1)
		lw	 sys0, RSP_GSTAT_FIFO_OUTP(zero)
		lw       sys1, GTASK_FLAGS(zero)
		_li	(sys2, SP_CLR_YIELDED|SP_CLR_TASKDONE)
		beq	 sys0, zero, doInit_InitFifo	# Fifo 設定へ
		mtc0	 sys2, SP_STATUS
	        andi     sys1, sys1, OS_TASK_YIELDED
	        beq      sys1, zero, doInit_SetOverlay
	        sw       zero, GTASK_FLAGS(zero)	# FLAGS のクリア
  EndAssign(sys2, 1)

	#---------------------------------------------------------------------
	#  Yield からの復帰処理
	#	DL の処理継続位置を取得する.
	#	SubSet モジュールがロードされているならロードする.
	#---------------------------------------------------------------------
		j	doInit_Overlay
		lw	inp,  RSP_SAVE_YIELD_INP(zero)
	
	#---------------------------------------------------------------------
	#	RDP が XBUS を参照しているなら FIFO をリセットする.
	#---------------------------------------------------------------------
doInit_InitFifo:
		mfc0	sys0, CMD_STATUS
		andi	sys0, sys0, DPC_STATUS_XBUS_DMEM_DMA
		bne	sys0, zero, doInit_RestartFifo
		
	#---------------------------------------------------------------------
	#  DRAM-FIFO バッファの設定
	#	DP が現在 fifo のどこを処理しているかを判定することで,
	#	Fifo への書き込み開始位置を取得する. これによって, 複数の
	#	マイクロコードを使用しているときにも Fifo バッファを共用す
	#	ることができる.
	#---------------------------------------------------------------------
  Assign(rdpcur, 1)
  Assign(rdpend, 2)
  Assign(buftop, 3)
  Assign(bufend, 4)
	#---------------------------------------------------------------------
	#	RDP が現在処理中である RDP コマンド領域の最終位置が fifo
	#	バッファ先頭よりも前にあるなら FIFO エリアとは重ならない
	#	ので FIFO 先頭から使用できる.
	#
	#	if (buftop > rdpend) goto restart_fifo; 
	#---------------------------------------------------------------------
		mfc0	rdpend, CMD_END
		lw	buftop, GTASK_OUTBUFF(zero)
		sub	sys0, buftop, rdpend
		bgtz	sys0, doInit_RestartFifo

	#---------------------------------------------------------------------
	#	CMD_CURRENT が 0 なら FIFO が初期状態であるとみなしリセッ
	#	トする. また同様に, RDP コマンドの領域の現在参照領域が,
	#	FIFO バッファの最終位置より後ろにあるなら FIFO エリアと
	#	重ならないので FIFO 先頭から使用できる.
	#
	#	if ( NULL  == rdpcur) goto restart_fifo; 
	#	if (bufend <= rdpcur) goto restart_fifo; 
	#---------------------------------------------------------------------
		mfc0	rdpcur, CMD_CURRENT
		lw	bufend, GTASK_OUTBUFF_SZ(zero)
		beq	rdpcur, zero, doInit_RestartFifo
		sub	sys0,   rdpcur, bufend
		bgez	sys0,   doInit_RestartFifo
		nop
	
	#---------------------------------------------------------------------
	#  CMD_CURRENT != CMD_END なら, すなわち RDP の処理が終了していな
	#  いなら FIFO の続きから出力する.
	#---------------------------------------------------------------------
		bne	rdpcur, rdpend, doInit_SetFifo
	
	#---------------------------------------------------------------------
	#  Fifo 書き込み位置のリセット
	#	Fifo の先頭から書き込むように指定する.
	#---------------------------------------------------------------------
doInit_RestartFifo:
		# DP ステータスが DPC_STATUS_START_VALID になるまで待機
		mfc0	sys0, CMD_STATUS
		andi	sys0, sys0, DPC_STATUS_START_VALID
		bne	sys0, zero, doInit_RestartFifo

		# DP コマンドバッファとして DRAM を参照するように変更
		_li	(sys0, DPC_CLR_XBUS_DMEM_DMA)
		mtc0	sys0, CMD_STATUS
		
		# 次に書き込む位置をリセット/ DP コマンドポインタを設定
		lw	rdpend, GTASK_OUTBUFF_SZ(zero)
		mtc0	rdpend, CMD_START
		mtc0	rdpend, CMD_END
	
	#---------------------------------------------------------------------
	#  Fifo への DP コマンドの送信位置を DMEM へ保存する
	#---------------------------------------------------------------------
doInit_SetFifo:
		sw	rdpend, RSP_GSTAT_FIFO_OUTP(zero)
doInit_SetFifo_End:
  EndAssign(rdpcur, 1)
  EndAssign(rdpend, 2)
  EndAssign(buftop, 3)
  EndAssign(bufend, 4)
  
#elif	defined(OUT_xbus)
	#---------------------------------------------------------------------
	#  DMEM-FIFO バッファの設定
	#	DP のコマンドバッファを DMEM 上にとるように設定する.
	#	XBUS マイクロコードの次に起動するマイクロコードには
	#	DP_WAIT フラグを設定して DP の終了を待つ必要がある
	#		XBUS->AUDIO   必要
	#		XBUS->XBUS    必要/不要?
	#		XBUS->FIFO    必要
	#		FIFO->AUDIO   不要
	#		FIFO->XBUS    必要? 描画中に XBUS_DRAM の切替は可能?
	#		FIFO->FIFO    不要
	#	RSPBOOT で判定する?
	#---------------------------------------------------------------------
doInit_InitXbus:
		#  RDP の処理が終了するまで待つ
		#  DP ステータスが DPC_STATUS_START_VALID になるまで待機
		mfc0	sys0, CMD_STATUS
		andi	sys0, sys0, DPC_STATUS_DMA_BUSY|DPC_STATUS_START_VALID
		bne	sys0, zero, doInit_InitXbus
	
		#  RSP_GSTAT_FIFO_OUTP をリセットする
		sw	zero, RSP_GSTAT_FIFO_OUTP(zero)
	
		# DP コマンドバッファとして DMEM を参照するように変更
		_li	(sys0, DPC_SET_XBUS_DMEM_DMA)
		mtc0	sys0, CMD_STATUS
	
		# 次に書き込む位置をリセット/ DP コマンドポインタを設定
		_li	(outp, RSP_WORK_OUTPUT_0)
		mtc0	outp, CMD_START
		mtc0	outp, CMD_END
	
	#---------------------------------------------------------------------
	#  STATUS フラグのクリア
	#	SP_STATUS	YIELDED/TASKDONE フラグのクリア
	#
	#  初期状態/LoadUcode後状態/Yield 復帰 かの判定
	#	GTASK_FLAGS を参照して OS_TASK_YIELDED フラグを調べ Yield 
	#	復帰でないなら LoadUcode 後の処理へ JUMP する.
	#	また Yield 復帰後に LoadUcode を処理する場合に対応するため,
	#	GTASK_FLAGS をクリアしておく.
	#---------------------------------------------------------------------
  Assign(sys2, 1)
		lw       sys1, GTASK_FLAGS(zero)
		_li	(sys2, SP_CLR_YIELDED|SP_CLR_TASKDONE)
		mtc0	 sys2, SP_STATUS
	        andi     sys1, sys1, OS_TASK_YIELDED
	        beq      sys1, zero, doInit_SetGstat	# Gstat 設定へ
	        sw       zero, GTASK_FLAGS(zero)	# FLAGS のクリア
  EndAssign(sys2, 1)

	#---------------------------------------------------------------------
	#  Yield からの復帰処理
	#	DL の処理継続位置を取得する.
	#---------------------------------------------------------------------
		j	doInit_Overlay
		lw	inp,  RSP_SAVE_YIELD_INP(zero)
#endif
	#---------------------------------------------------------------------
	#	全ての UCode のコード量の差を埋めるために nop を追加し
	#	調整する
	#	F3DEX_fifo が最大長になるのでそれにあわせる
	#---------------------------------------------------------------------
#ifdef	OUT_xbus
		nop	nop	nop	nop	nop	nop	nop	nop
		nop	nop	nop	nop	nop	nop	nop	nop
#endif
#if	defined(UCODE_F3DEX2_Rej)||defined(UCODE_F3DLX2_Rej)
		nop	nop	nop	nop	nop	nop
#endif
#if	defined(UCODE_L3DEX2)
		nop	nop	nop
#endif
	
	#---------------------------------------------------------------------
	#  その他の GSTAT エリアの初期化
	#---------------------------------------------------------------------
doInit_SetGstat:
		lw	sys0, RSP_GSTAT_DRAM_STACK(zero)
		bne	sys0, zero, doInit_SetOverlay
		lw	sys0, GTASK_STACK(zero)
		sw	sys0, RSP_GSTAT_DRAM_STACK(zero)

	#---------------------------------------------------------------------
	#  Overlay コードのアドレス値の変換
	#	DRAM 上に保持されている Overlay / SubModule のアドレスを
	#	取得する. DMEM 上の OFFSET 値に UCODE のアドレス値を加算
	#	することで各モジュールへのアドレスが計算できる.
	#
	#	ここから LoadUcode の処理が合流する
	#---------------------------------------------------------------------
doInit_SetOverlay:
  Assign(base, 1)
  Assign(adr0, 2)
  Assign(adr1, 3)
  Assign(adr2, 4)
  Assign(adr3, 5)
#if	(defined(UCODE_F3DEX2)||defined(UCODE_F3DEX2_NoN))
# define	OVERLAY2	RSP_SUBMOD_OVERLAY_LIGHTING
# define	OVERLAY3	RSP_SUBMOD_OVERLAY_CLIPPING
#elif	(defined(UCODE_S2DEX2))
# define	OVERLAY2	RSP_LSTAT_OVERLAY_SPRITE
# define	OVERLAY3	RSP_LSTAT_OVERLAY_BG1CYC
#endif
		lw	base, GTASK_UCODE(zero)
		lw	adr0, RSP_LSTAT_OVERLAY_TASKDONE(zero)
		lw	adr1, RSP_LSTAT_OVERLAY_RSPBOOT(zero)
#ifdef	OVERLAY2
		lw	adr2, OVERLAY2(zero)
		lw	adr3, OVERLAY3(zero)
#endif
		add	adr0, adr0, base
		add	adr1, adr1, base
		sw	adr0, RSP_LSTAT_OVERLAY_TASKDONE(zero)
		sw	adr1, RSP_LSTAT_OVERLAY_RSPBOOT(zero)
#ifdef	OVERLAY2
		add	adr2, adr2, base
		add	adr3, adr3, base
		sw	adr2, OVERLAY2(zero)
		sw	adr3, OVERLAY3(zero)
#endif
  EndAssign(base, 1)
  EndAssign(adr0, 2)
  EndAssign(adr1, 3)
  EndAssign(adr2, 4)
  EndAssign(adr3, 5)
	#---------------------------------------------------------------------
	#  Scissor Box のデコード (必要な場合のみ)
	#---------------------------------------------------------------------
#if	(defined(UCODE_L3DEX2)||defined(UCODE_S2DEX2))
		lw	gfx0, RSP_GSTAT_SCISSOR+0(zero)
		jal	case_G_SETSCISSOR_Decode
		lw	gfx1, RSP_GSTAT_SCISSOR+4(zero)		
#endif
	#---------------------------------------------------------------------
	#  DL の処理先頭番地の取得
	#---------------------------------------------------------------------
		lw	inp, GTASK_DATA(zero)

	#---------------------------------------------------------------------
	#  RSPBOOT Overlay 開始
	#	Overlay のため初期化部分を 8 バイト整列させる必要があるので
	#	.align を挿入する.
	#---------------------------------------------------------------------
doInit_Overlay:	_li	(sys0, RSP_LSTAT_OVERLAY_RSPBOOT)
		.align	8
		jal	LoadOverlay
		_mov	(sys1, return)

	#=====================================================================
	#  ここまでのコードはマイクロコード始動後, 使用しないので Overlay を
	#  かけて他のコードをロードする.
	#=====================================================================
			
/*======== End of gxinit.s ========*/