gxloop.s
3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*---------------------------------------------------------------------*
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 ========*/