gzoutfifo.s
5.83 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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*---------------------------------------------------------------------
$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 ========*/