toutxbus.s 2.63 KB
	
#include <rsp.h>
#include "mbi.h"
#include "tdmem_label.h"	
#include "tst_regs.h"


.name	dmemp, 		$20
.name	dramp, 		$19
.name	outsz, 		$18	# set by caller to max size to write	
	
 ############################################################################
 #
 # Output coordination routines:
 #
 # We support two cases:
 #
 #	1.) output directly to RDP using DMEM as buffer. Requires
 #	    producer/consumer synchronization.
 #
 #	2.) output routed to DRAM. In this case, we use DMEM as
 #	    a temporary buffer, then DMA out to DRAM.
 #
 # Goals:
 #
 #	- small code size.
 #	- efficient and non-obtrusive
 #	- flexible, can easily route to DRAM or RDP.
 #
 # In order to do this, and make it transparent to the parts of the
 # code which do the writing, we implement an open/close interface.
 #
 # FUNCTION:	    OUTPUT TO RDP:		    OUTPUT TO DRAM:
 #-------------------------------------------------------------------------
 # open(size)	- wait for size avail in	- does nothing
 #		  ring buffer.
 #		- possibly handle wrap
 #		- wait for 'current' to get
 #		  out of the way
 #
 # close()	- advance CP0 pointer		- do DMA of cmd to DRAM
 #						- increment pointers
 #						- reset DMEM buffer
 #
 # In between the open() and close(), the ucode writes the data to DMEM.
 # (to either the RDP ring buffer or a temp buffer to be DMA'd)
 #
 ############################################################################

		.ent	OutputOpen

OutputOpen:
 # check if the packet will fit in the buffer
 		addi	dramp, zero, (RSP_OUTPUT_OFFSET + RSP_OUTPUT_SIZE8)
		add	dmemp, outp, outsz
		sub	dramp, dramp, dmemp
		bgez	dramp, CurrentFit
		nop
	
WrapBuffer:
 # packet will not fit, wait for current to wrap
   		mfc0	dramp, CMD_STATUS
		andi	dramp, dramp, 0x0400
   		bne	dramp, zero, WrapBuffer
		# note delay slot

 # wait for current to advance
AdvanceCurrent:	
		mfc0	dramp, CMD_CURRENT
		addi	outp, zero, RSP_OUTPUT_OFFSET
		beq	dramp, outp, AdvanceCurrent
		nop
		mtc0	outp, CMD_START		# reset START
CurrentFit:
		# done if current_address <= outp
		mfc0	dramp, CMD_CURRENT
		sub	dmemp, outp, dramp
		bgez	dmemp, OpenDone
		# note delay slot

		# loop if current_address <= (outp + outsz)
		add	dmemp, outp, outsz
		sub	dramp, dmemp, dramp
		bgez	dramp, CurrentFit
		nop
OpenDone:	
		jr	return
		nop

		.end	OutputOpen
	
 ##################################################################
 ##  OutputClose                                                 ##
 ##################################################################
		.ent	OutputClose
	
OutputClose:
	#
	# XBUS RDP output
	#
		jr	return
		mtc0	outp, CMD_END
	
		.end	OutputClose
	
.unname	outsz
.unname	dramp
.unname	dmemp