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

/*---------------------------------------------------------------------------*
 *  DRAM FIFO への出力処理
 *	ある程度の RDP コマンドが貯まってから出力する.
 *	outpThd は出力バッファの先頭位置+RSP_WORK_OUTPUT_THDSZ となっている
 *
 *	gfx1 は破壊されます.
 *---------------------------------------------------------------------------*/
	#---------------------------------------------------------------------
	#  RDP コマンドが充分に貯まったかどうかの判定
	#	次に 2TRI の処理をしたとして充分な空き容量があれば何もせずに
	#	終了する.
	#---------------------------------------------------------------------
  AssignForDMAproc
OutputCloseGfxDone:	_li	(return, GfxDone)
OutputClose:
#if	defined(SAFE_MODE)
			_li	(sys0, G_RDPPIPESYNC)
			sb	sys0, 0(outp)
			addi	outp, outp, 8
#endif	
			sub	sys0, outp, outpThd
			blez	sys0, ReturnToR31

	#---------------------------------------------------------------------
	#  DPC_END の更新
	#	前回の DMA 処理の終了を待ち, DPC_END を更新する
	#  DRAM FIFO のパラメータ取得
	#	dram_adrs: DRAM FIFO の空き領域の先頭アドレス
	#	sys1:      DRAM FIFO の最終アドレス
	#  書き出すデータサイズの計算
	#	dma_len:   転送するデータのサイズ
	#---------------------------------------------------------------------
OutputClose0:
	mfc0	sys1, DMA_BUSY
			lw	dram_adrs, RSP_GSTAT_FIFO_OUTP(zero)
			addiu	dma_len,   sys0, RSP_WORK_OUTPUT_TSZ
	bne	sys1, zero, OutputClose0
			lw	sys1, GTASK_OUTBUFF_SZ(zero)
	mtc0	dram_adrs, CMD_END
		
	#---------------------------------------------------------------------
	#  書き出すデータが DRAM FIFO の空き領域に収まるなら DMA 転送へ
	#	DRAM FIFO の空き領域に DMA 転送を行なったときの終了アドレス
	#	(dram_adrs+dma_len) が DRAM_FIFO の最終アドレスを超えるかど
	#	うかを調べる. 超えなければそのまま DMA 転送へ.
	#---------------------------------------------------------------------
			add	sys0, dram_adrs, dma_len
			sub	sys1, sys1, sys0		# 比較
			bgez	sys1, oc_WaitFree
	
	#---------------------------------------------------------------------
	#  書き出すデータが DRAM FIFO の空き領域に収まらないなら FIFO を
	#  リセットする.
	#	(1) DP STATUS が START_VALID で無くなるまで待つ.
	#	(2) FIFO 先頭アドレスを取得する
	#	(3) DP の CURRENT 位置が先頭でなくなるまで待つ.
	#	(4) DP の読み出し開始位置を FIFO 先頭にセットする.
	#---------------------------------------------------------------------
oc_WaitStart:		mfc0	sys0, CMD_STATUS
			andi	sys0, sys0, DPC_STATUS_START_VALID
			bne	sys0, zero, oc_WaitStart
			
			lw	dram_adrs, GTASK_OUTBUFF(zero)
oc_CheckTop:		mfc0	sys0, CMD_CURRENT
			beq	sys0, dram_adrs, oc_CheckTop
			nop
			mtc0	dram_adrs, CMD_START
			
	#---------------------------------------------------------------------
	#  データを書き出す分だけの FIFO 領域が空くまで待つ
	#	CMD_CURRNET <= dram_adrs または, 
	#	CMD_CURRENT >  dram_adrs+dma_len になるまで待つ
	#---------------------------------------------------------------------
oc_WaitFree:		mfc0	sys0, CMD_CURRENT
			sub	sys0, sys0, dram_adrs
			blez	sys0, oc_CloseDMA
			sub	sys0, sys0, dma_len
			blez	sys0, oc_WaitFree

	#---------------------------------------------------------------------
	#  FIFO 領域ポインタ更新
	#---------------------------------------------------------------------
oc_CloseDMA:		add	sys0, dram_adrs, dma_len
			sw	sys0, RSP_GSTAT_FIFO_OUTP(zero)

	#---------------------------------------------------------------------
	#  DMA パラメータ設定
	#	dma_len には転送サイズが入っている
	#	WRITE DMA のために dmem_adrs を負の値にする必要があるため
	#	0x2000 を減ずる.
	#---------------------------------------------------------------------
			addi	dma_len, dma_len, -1
			addi	dmem_adrs, outpThd, \
				-RSP_WORK_OUTPUT_TSZ-0x2000
			
	#---------------------------------------------------------------------
	#  FIFO バッファの切り替え / DMA 開始
	#	outpThd を切り替え, outp を初期化する.
	#	DMA 開始後, そのまま return する
	#---------------------------------------------------------------------
			xori	outpThd, outpThd, \
				RSP_WORK_OUTPUT_THD_0^RSP_WORK_OUTPUT_THD_1
			j	DMAwrite
			addi	outp, outpThd, -RSP_WORK_OUTPUT_TSZ
  EndAssignForDMAproc

/*======== End of gxoutfifo.s ========*/