gzoutfifo.s 5.83 KB
/*---------------------------------------------------------------------
  $Id: gzoutfifo.s,v 1.1.1.1 2002/05/02 03:29:12 blythe Exp $
  
  File : gzoutfifo.s
  
  Coded     by Yoshitaka Yasumoto.   Jun 18, 1997.
  Copyright by Nintendo, Co., Ltd.           1997.
  ---------------------------------------------------------------------*/
	
	#================================================================
	#  FIFO バッファへの出力処理
	#================================================================ 

	#----------------------------------------------------------------
	#  OutputClose 後に GfxDone へジャンプ
	#----------------------------------------------------------------
#if 0	/* 今回は不要 */
OutputCloseGfxDone:	
	addi	sys0, outp, -RSP_OUTPUT_ENOUGH
	blez	sys0, GfxDone
	_li	(return, GfxDone)
#endif
	#----------------------------------------------------------------
	#  DMEM 上のバッファにデータが貯まったかの判定
	#  3 角形コマンドを書き出すのに充分な空き容量がなければデータを
	#  FIFO へ吐き出す
	#----------------------------------------------------------------
OutputClose:
  AssignForDMAproc
	addi	sys0, outp, -RSP_OUTPUT_ENOUGH
	blez	sys0, ReturnToR31
		
	#----------------------------------------------------------------
	#  FIFO へのデータはき出し処理に関する DMA パラメータ取得
	#----------------------------------------------------------------
OutputCloseFlush:
	lw	dram_adrs, RSP_STATEP_FIFO_OUTP(zero)	# FIFO 空き領域先頭
	lw	sys1,      GTASK_OUTBUFF_SZ(zero)	# FIFO 領域終端
	addi	dma_len, outp, -RSP_OUTPUT_OFFSET	# データサイズ取得
	blez	dma_len, ReturnToR31			# データなしなら終了
	
	#----------------------------------------------------------------
	#  FIFO の空き領域の計算
	#  FIFO の空き領域にデータが収まるなら DMA 転送へ
	#----------------------------------------------------------------	
	sub	sys1, sys1, dram_adrs
	sub	sys0, sys1, dma_len
#ifdef	SUBDLNICE
	bgez	sys0, WaitFifoFree_1
#else
	bgez	sys0, WaitFifoFree
#endif
	sw	return, RSPZS_OUTFIFO_RETURN(zero)	# return の保存
	
	#----------------------------------------------------------------
	#  DMA 転送領域が空くまで待つ
	#  (1) DP の STATUS が START_VALID でなくなるまで待つ
	#  (2) FIFO 領域の先頭から書き込むデータ分だけの領域が空くまで待つ
	#	待つ間に Sub DL を取り出して処理を行なう
	#----------------------------------------------------------------
WaitStartInvalid:
	mfc0	sys0, CMD_STATUS
	andi	sys0, sys0, DPC_STATUS_START_VALID
	bne	sys0, zero, WaitStartInvalid
	lw	dram_adrs, GTASK_OUTBUFF(zero)		# FIFO 先頭
CheckTopBuffer:	
	mfc0	sys1, CMD_CURRENT
	beq	sys1, dram_adrs, CheckTopBuffer
	sw	dram_adrs, RSP_STATEP_FIFO_OUTP(zero)	# dram_adrs 保存
	mtc0	dram_adrs, CMD_START
WaitFifoFree_0:
	lw	dram_adrs, RSP_STATEP_FIFO_OUTP(zero)
WaitFifoFree:
	mfc0	sys1, CMD_CURRENT
	lbu	iswrite, RSPZS_OUTFIFO_RETURN+1(zero)	# SubDL 制御
	addi	dma_len, outp, -RSP_OUTPUT_OFFSET # データサイズ再取得
	sub	sys1, sys1, dram_adrs		# FIFO 空き領域サイズ
	blez	sys1, WaitFifoFree_Done
	sub	sys0, sys1, dma_len
	bgtz	sys0, WaitFifoFree_Done
WaitFifoFree_1:	
#ifdef	SUBDLNICE
	lbu	iswrite, RSPZS_OUTFIFO_RETURN+1(zero)	# SubDL 制御
#else
	nop
#endif
	.symbol	SubGfxDone, (WaitFifoFree_0|0x8000)
	
	#---------------------------------------------------------------------
	#  Main DL のパラメータ保存, Sub DL のパラメータ取得
	#---------------------------------------------------------------------
	bltz	gfxdone, SubGfxLoop_1
	_li	(gfxdone, SubGfxDone)			# 0xffff8xxx	
	sw	inp,  RSP_SUBDL_SAVE_INP(zero)
	lw	inp,  RSP_SUBDL_INP(iswrite)
	sh	dinp, RSP_SUBDL_SAVE_DINP(zero)
	lh	dinp, RSP_SUBDL_DINP(zero)
	
	#---------------------------------------------------------------------
	#  Sub DL の処理ループ
	#---------------------------------------------------------------------
SubGfxLoop_1:	
	beq	inp,  zero, WaitFifoFree		# SubGfx ないなら Loop
        lw	gfx0, (RSP_SUBDLINPUT_BOTTOM+0)(dinp)	# DL 前半を gfx0 へ
	beq	dinp, zero, StartDLload			# DL バッファが空か ?
	sra     sys0, gfx0, 24                          # INDEX 作成	
	sll	sys0, sys0, 1				# INDEX 作成
        lhu     sys0, RSP_JTBL_A_ORG(sys0)		# テーブル参照
        lw      gfx1, (RSP_SUBDLINPUT_BOTTOM+4)(dinp)	# DL 後半を gfx1 へ
        jr      sys0                                    # 各処理へ JUMP
        addiu   dinp, dinp, 8                           # ポインタ加算 
	
	#---------------------------------------------------------------------
	#  Sub DL のパラメータ保存, Main DL のパラメータ取得
	#---------------------------------------------------------------------
WaitFifoFree_Done:
	bgtz	gfxdone, CloseDMA
	_liu	(gfxdone, GfxDone)			# 0x00000xxx
	sh	dinp,      RSP_SUBDL_DINP(zero)
	lh	dinp,      RSP_SUBDL_SAVE_DINP(zero)
	sw	inp,       RSP_SUBDL_INP(iswrite)
	lw	inp,       RSP_SUBDL_SAVE_INP(zero)
CloseDMA:
	#----------------------------------------------------------------
	#  FIFO 空き領域先頭ポインタ更新し, 保存する.
	#----------------------------------------------------------------
	add	sys1, dram_adrs, dma_len
	sw	sys1, RSP_STATEP_FIFO_OUTP(zero)
	#----------------------------------------------------------------
	#  DMA パラメータを設定し, DMA を開始する.
	#----------------------------------------------------------------
	addi	dma_len, dma_len, -1
	lhu	iswrite, RSPZS_OUTFIFO_RETURN+2(zero)	# 正の値となる
	jal	DMAproc
	_li	(dmem_adrs, RSP_OUTPUT_OFFSET)
	#----------------------------------------------------------------
	#  DMA 終了待ち / DMEM バッファポインタを初期化する.
	#  iswrite の値を保持するため + 高速化のため展開する
	#----------------------------------------------------------------
OutputCloseDMAwait:
	mfc0	sys0, DMA_BUSY
	bne	sys0, zero, OutputCloseDMAwait
	_li	(outp, RSP_OUTPUT_OFFSET)
	#----------------------------------------------------------------
	# DP ポインタを更新する
	#----------------------------------------------------------------
	jr	iswrite				# 呼び出し元に戻る
	mtc0	sys1, CMD_END			# DP ポインタ更新
  EndAssignForDMAproc
	
/*======== End of gzoutfifo.s ========*/