gxloop.s 3.69 KB
/*---------------------------------------------------------------------*
	Copyright (C) 1998, Nintendo.
	
	File		gxloop.s
	Coded    by	Yoshitaka Yasumoto.	Apr  6, 1998.
	
	$Id: gxloop.s,v 1.1.1.1 2002/05/02 03:29:11 blythe Exp $
 *---------------------------------------------------------------------*/

        #---------------------------------------------------------------------
	#  DisplayList 処理ループ
        #---------------------------------------------------------------------
StartDLload:
	#---------------------------------------------------------------------
	#	Display List を DRAM アドレス inp から DMEM の
	#	RSP_DLINPUT_OFFSET へ GX_MAX_DL 個読み込む. 
	#---------------------------------------------------------------------
  AssignForDMAproc
		#------- DMA 開始 -------
		_li	(dma_len, GX_MAX_DL*8-1)
		_mov	(dram_adrs, inp)
		jal	DMAread
		_liu	(dmem_adrs, RSP_DLINPUT_OFFSET)
	
		#------- DL ポインタ加算 & ロードカウンタ初期化 -------
		addiu	inp, inp, GX_MAX_DL*8
		_li	(dinp, -GX_MAX_DL*8)
		
		#------- DMA 終了待ち -------
DMAwaitGfxDone:
		jal	DMAwait		# ロード遅延内で gfx0 を取得する.
  EndAssignForDMAproc

	#====== この間にコードをはさんではならん
        #---------------------------------------------------------------------
	#	DL を読み込んだあとは dinp をカウンタ兼 DL ポインタとし,
	#	dinp = -GX_MAX_DL*8 から順に加算していき, dinp==0 となるまで
	#	DL の処理を続ける. dinp==0 でバッファが空なので再度 DL のロー
	#	ドを行なう.
	#	
	#	現在処理中の DL は
	#		DRAM アドレス:	dinp+inp
	#		DMEM アドレス:	dinp+RSP_DLINPUT_BOTTOM
	#	で求められる.
        #---------------------------------------------------------------------
	#	dinp をポインタとして Display List を gfx0, gfx1 へと代入する
	#	gfx0 の最上位 8 byte をデコードして各命令のアドレスをテーブル
	#	引きし Jump する.
        #---------------------------------------------------------------------
	#	SP の STATUS Reg を調べて, CPU からの Yield 要求があるかどう
	#	かをチェックする. もし要求フラグ (SP_STATUS_YIELD) が立って
	#	いたら Yield 処理を行なう.
        #---------------------------------------------------------------------
	#	最終的に sys0 に JUMP 先アドレスを設定して JUMP する.
	#	以下は sys0 を使用することに依存したコードとなっているため
	#	sys0 から他のレジスタに切り替えた場合は同時に修正する必要が
	#	ある.
	#		case_G_LOAD_UCODE
	#		case_G_SETOTHERMODEH
	#		case_G_SETOTHERMODEL
	#		case_G_RDPHALF_0
	#		case_G_RDPHALF_1
	#
	#	また case_G_DMA_General では sys1 に符号付きでコマンドの
	#	ID が入っていることを利用しており,
	#	また yield($1) で Yield の判定を行なっている.
	#	TaskYield は $1 に SP_STATUS_YIELD=0x80 が代入されていること
	#	を, また case_G_SUBMODULE は $1 に 0 が代入されていることを
	#	前提としてコードになっているので同様に注意する
        #---------------------------------------------------------------------
  FixedAssign(yield, 1)
GfxDone:
		mfc0    yield, SP_STATUS		###! YIELD 要求チェック
	lw	gfx0, (RSP_DLINPUT_BOTTOM+0)(dinp)	# DL 前半を gfx0 へ
	beq	dinp, zero, StartDLload			# DL 終了なら新規ロード
		andi    yield, yield, SP_STATUS_YIELD   ###! YIELD フラグ判定
	sra	sys1, gfx0, 24                          # INDEX 作成(符号付)
	sll	sys0, sys1, 1                           # INDEX 作成
	lhu	sys0, RSP_LSTAT_JUMPTBL(sys0)		# テーブル参照
		bne	yield, zero, TaskYield		###! YIELD なら Jump
        lw	gfx1, (RSP_DLINPUT_BOTTOM+4)(dinp)	# DL 後半を gfx1 へ
#ifdef	SAFE_MODE
  FixedAssign(dadrs, 2)
		add	dadrs, inp, dinp		# 現在処理中の DL 取得
        addiu	dinp, dinp, 8				# ポインタ加算
        jr	sys0					# 各処理へ JUMP
		sw	dadrs, 0xfc0(zero)		# アドレス記録
  EndAssign(dadrs, 2)
#else
        jr	sys0					# 各処理へ JUMP
        addiu	dinp, dinp, 8				# ポインタ加算
#endif
  EndAssign(yield, 1)
	
/*======== End of gxloop.s ========*/