goutdump.s 1.9 KB
/*
	goutdump.s

	SETA のマクロコードを参考に実装した. fifo のバッファリング処理
 */
.name	return_adrs,	$21
.name   dma_top,	$19
#define	dma_end		outp
.name   fifo_end,       $20
#define	tmp2		fifo_end
#define	outp_top	fifo_end
.name   out_size,       $18	# 呼び出し側で必要なサイズを代入しておく.
.name	tmp,		$6	# ただし outsz から RSP_OUTPUT_END を引いた値

	.ent	OutputOpen

OutputOpen_End:
	jr	return	
OutputOpen:
	add	tmp, outp, out_size	# 空き容量チェック
	blez	tmp, OutputOpen_End	# 空きがあるなら終了

	add	return_adrs, zero, return
	lw	dma_top,  RSP_STATE_FIFO_OUTP(rsp_state)
	lw	fifo_end, RSP_STATE_FIFO_BUF_END(rsp_state)	# fifo end
	addi	out_size, outp, -RSP_OUTPUT_OFFSET
	add	dma_end, dma_top, out_size
	sub	tmp2, fifo_end, dma_end		# tmp = 残りのバッファサイズ
	mfc0	tmp,  CMD_CURRENT		# CurrentFit 用に先読みする
	bgez	tmp2, CurrentFit		# tmp >=0 なら追加で出力可能
	    WrapBuffer:	
		mfc0	tmp, CMD_STATUS
		lw	dma_top, RSP_STATE_FIFO_BUF_TOP(rsp_state)
		/* Delay */
		andi	tmp, tmp, 0x0400 # DPC_STATUS_START_VALID
		bne	tmp, zero, WrapBuffer
	    AdvanceCurrent:	
		mfc0	tmp, CMD_CURRENT
		/* Delay */
		/* Delay */
		beq	tmp, dma_top, AdvanceCurrent
		add	dma_end, dma_top, out_size	# データの最後
		mtc0	dma_top, CMD_START		# スタートの再設定
	# これから DMA 転送する領域に CMD_CURRENT がないかどうかの判定
    CurrentFit0:
	mfc0	tmp, CMD_CURRENT
    CurrentFit:
	sub	tmp2, dma_top, tmp
	bgez	tmp2, OpenDMA		# CURRENT が dma_top より前なら JUMP
	sub	tmp2, dma_end, tmp
	bgez	tmp2, CurrentFit0	# CURRENT が dma_end より前なら LOOP

    OpenDMA:
	addi	outp_top, zero, RSP_OUTPUT_OFFSET
	addi	$17, zero, 1
	jal	DMAproc
	addi	out_size, out_size, -1
	
	jal	DMAwait
	sw	dma_end, RSP_STATE_FIFO_OUTP(rsp_state)
	mtc0	dma_end, CMD_END	
	jr	return_adrs
	addi	outp, zero, RSP_OUTPUT_OFFSET

	.end	OutputOpen
.unname	return_adrs
.unname	dma_top
.unname	fifo_end
.unname	out_size
.unname	tmp
#undef	dma_end
#undef	tmp2
#undef	outp_top