gxdone.s 8.21 KB
/*---------------------------------------------------------------------*
	Copyright (C) 1997, Nintendo.
	
	File		gxdone.s
	Coded    by	Yoshitaka Yasumoto.	Oct 20, 1997.
	
	$Id: gxdone.s,v 1.1.1.1 2002/05/02 03:29:11 blythe Exp $
 *---------------------------------------------------------------------*/

 #============================================================================
 #	オーバーレイコード TASKDONE
 #============================================================================
	#---------------------------------------------------------------------
	#  TASK の終了処理
	#
	#	$1 の値に応じて処理が振り分けられる.
	#		$1 ==   0  なら case_G_LOAD_UCODE
	#		$1 ==  -4  なら TaskDone
	#		$1 == 0x80 なら TaskYield
	#---------------------------------------------------------------------
  AssignForDMAproc
  FixedAssign(flag, 1)
overlay_TaskDone:
#if	defined(UCODE_L3DEX2)
	#---------------------------------------------------------------------
	#   シザリングパラメータの設定
	#	シザリングパラメータを設定値に戻す.
	#	xbus の場合, 自分で転送を行なう.
	#	fifo の場合, この後のコードで Flush される.
	#---------------------------------------------------------------------
		ldv	vtmp[0], RSP_GSTAT_SCISSOR(zero)
		addi	outp, outp, 8
		sdv	vtmp[0], -8(outp)
#endif
#if	defined(OUT_fifo)
	#---------------------------------------------------------------------
	#  DRAM FIFO 転送バッファの Flush
	#	DRAM FIFO バッファへ RDP command データをはき出す.
	#	DRAM FIFO への出力バッファをダブルバッファにしているため
	#	この処理が必要になる.
	#
	#	(データサイズ-1) を計算し, 結果が 0 以上ならデータをはき出す.
	#	DMA 転送終了を待つ.
	#---------------------------------------------------------------------
		sub	sys0, outp, outpThd	# OutputClose へ値を持ち越す
		addiu	sys1, sys0, RSP_WORK_OUTPUT_TSZ-1
		bgezal	sys1, OutputClose0
		nop				# なにかに使う.
		jal	DMAwait

	#---------------------------------------------------------------------
	#  CMD_END の更新.
	#	$1 < 0 なら TaskDone 処理へ.
	#---------------------------------------------------------------------
		lw	dram_adrs, RSP_GSTAT_FIFO_OUTP(zero)	
		bltz	flag, ov_TaskDone
		mtc0	dram_adrs, CMD_END

#elif	defined(OUT_xbus)
	#---------------------------------------------------------------------
	#  $1 < 0 なら TaskDone 処理へ.
	#---------------------------------------------------------------------
		bltz	flag, ov_TaskDone
#if	defined(UCODE_L3DEX2)
		mtc0	outp, CMD_END
#else
		nop
#endif
#endif
	#---------------------------------------------------------------------
	#  DL の DRAM ポインタを計算.
	#	$1 != 0 なら Yield 処理へ.
	#---------------------------------------------------------------------
		bne	flag, zero, ov_TaskYield
		add	inp,  inp, dinp		# DL ポインタの計算

	#---------------------------------------------------------------------
	#  G_LOAD_UCODE 処理
	#	この処理は 0x1080 までで終了する必要がある
	#---------------------------------------------------------------------
ov_G_LOAD_UCODE:
	#---------------------------------------------------------------------
	#  レジスタの保存
	#	次のマイクロコードと処理してきた DL へのポインタを保存する.
	#---------------------------------------------------------------------
		lw	dram_adrs, (RSP_DLINPUT_BOTTOM-4)(dinp)
		sw	inp,       GTASK_DATA(zero)	# DL ポインタの保存
		sw	dram_adrs, GTASK_UCODE(zero)	# 次の ucode の保存
	
	#---------------------------------------------------------------------
	#  IMEM へのロード
	#---------------------------------------------------------------------
		_liu	(dmem_adrs, CODE_TOP_BOOT)	# DMA 先頭
		jal	DMAread				# DMA 開始
		_li	(dma_len, CODE_TOP_COMMON-CODE_TOP_BOOT-1)
							# DMA サイズ
	#---------------------------------------------------------------------
	#  XBUS マイクロコードからの G_LOAD_UCODE は RDP の処理が終了するま
	#  で待つ
	#---------------------------------------------------------------------
#if	defined(OUT_xbus)
ov_G_LOAD_UCODE_0:
		mfc0	sys0, CMD_STATUS
		andi	sys0, sys0, DPC_STATUS_DMA_BUSY
		bne	sys0, zero, ov_G_LOAD_UCODE_0
#endif
	#---------------------------------------------------------------------
	# DMEM へのロード
	#	GSTAT 領域へはロードしないため, その分のパラメータを調節する.
	#	この調整を GBI 側でするか UCODE でするかによって処理が変わる.
	#---------------------------------------------------------------------
		lw	dram_adrs, RSP_GSTAT_RDPHALF_1L(zero)	# Data Sec.
		_liu	(dmem_adrs, RSP_LSTAT_OFFSET)		# DMA 先頭
#ifdef FIXED_GBI
		jal	DMAread					# DMA 開始
		andi	dma_len, gfx0, 0x0fff			# DMA サイズ
#else
		andi	dma_len,   gfx0, 0x0fff			# DMA サイズ
		add	dram_adrs, dram_adrs, dmem_adrs		# GSTAT のSKIP
		jal	DMAread					# DMA 開始
		sub	dma_len,   dma_len,   dmem_adrs		# GSTAT 分減算
#endif		
	#---------------------------------------------------------------------
	# 以降 DMA 待ちルーチンへ, DMA 終了後 0x1080+4 番地へ Jump する
	#---------------------------------------------------------------------
		j	DMAwait
		_li	(return, RSP_LOADUCODE_Return) # = UCODE_START+4
	
	#---------------------------------------------------------------------
	#  Yield 処理
	#---------------------------------------------------------------------
ov_TaskYield:
#if	defined(OUT_fifo)
	#---------------------------------------------------------------------
	#  レジスタの保存
	#	現在の UCODE のアドレスを Yield Buffer へ保存. UCODE のアド
	#	レスは OS によって読み出され, Yield 復帰時に OSTask 構造体
	#	内へ再設定される. これによって途中で UCODE を切り替えたとき
	#	でも yield 処理を行なうことが可能.
	#	また inp の値も Yield Buffer へ保存する.
	#---------------------------------------------------------------------
		lw      sys0, GTASK_UCODE(zero)
	        sw      inp,  RSP_SAVE_YIELD_INP(zero)
	        sw      sys0, RSP_SAVE_YIELD_UCODE(zero)	
	#---------------------------------------------------------------------
        #  DMEM の内容の DMA 転送
	#	Yield Buffer のアドレスを dram_adrs へ設定
	#	sys1 は CPU への割り込みフラグとして共用
	#---------------------------------------------------------------------
	        _li	(sys1, SP_SET_YIELDED|SP_SET_TASKDONE)
	        lw	dram_adrs, GTASK_YIELD(zero)
	        _li	(dmem_adrs, 0x8000)
	        _li	(dma_len, RSP_SAVE_YIELD_LEN-1)
	        j	DMAwrite	
	        _li	(return, ov_TaskDone2)	# 終了後 ov_TaskDone2 へ飛ぶ
	
#elif	defined(OUT_xbus)
	#---------------------------------------------------------------------
	#  レジスタの保存
	#	Fifo の場合と同様に処理したいところであるが, 保存エリアが
	#	RDP のバッファと重なるため, 直接 DMEM へ書き込むことがで
	#	きない. そのため違うところに書き込み DMA を調整して
	#	別処理で Yield Buffer へ書き込む.
	#---------------------------------------------------------------------
		lw	sys0, GTASK_UCODE(zero)
		sw	inp,  RSP_SAVETMP_YIELD_INP(zero)
		sw	sys0, RSP_SAVETMP_YIELD_UCODE(zero)
	#---------------------------------------------------------------------
        #  DMEM の内容の DMA 転送
	#	Yield Buffer のアドレスを dram_adrs へ設定
	#	sys1 は CPU への割り込みフラグとして共用
	#	レジスタの保存は別処理で行なわれるので, SAVE が必要な
	#	領域分しか転送する必要はない.
	#---------------------------------------------------------------------
		# 先頭から SAVE 領域までの転送
	        lw	dram_adrs, GTASK_YIELD(zero)
	        _li	(dmem_adrs, 0x8000)
	        jal	DMAwrite	
	        _li	(dma_len, RSP_WORK_OFFSET-1)
		# レジスタ保存領域の転送
	        _li	(sys1, SP_SET_YIELDED|SP_SET_TASKDONE)
		addiu	dram_adrs, dram_adrs, RSP_SAVE_YIELD_LEN-8
		_li	(dmem_adrs, 0x8000+RSP_SAVETMP_YIELD_INP)
		_li	(dma_len, 7)
		j	DMAwrite
	        _li	(return, ov_TaskDone2)	# 終了後 ov_TaskDone2 へ飛ぶ
#endif
	#---------------------------------------------------------------------
	#  TaskDone 処理
	#---------------------------------------------------------------------
	#  CPU への割り込み通知
	#---------------------------------------------------------------------
ov_TaskDone:	_li	(sys1, SP_SET_TASKDONE)
ov_TaskDone2:	
#if	defined(OUT_xbus)
	#---------------------------------------------------------------------
	#  XBUS マイクロコードの終了時には RDP の処理が終了するまで待つ
	#  FIFO マイクロコードとの混在のため.
	#---------------------------------------------------------------------
		mfc0	sys0, CMD_STATUS
		andi	sys0, sys0, DPC_STATUS_DMA_BUSY
		bne	sys0, zero, ov_TaskDone2
		nop
#endif
		mtc0	sys1, SP_STATUS
		break
		nop
  EndAssign(flag, 1)
  EndAssignForDMAproc
	
/*======== End of gxdone.s ========*/