gxinit.s
11.3 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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
/*---------------------------------------------------------------------*
Copyright (C) 1997, Nintendo.
File gxinit.s
Coded by Yoshitaka Yasumoto. Oct 20, 1997.
$Id: gxinit.s,v 1.1.1.1 2002/05/02 03:29:11 blythe Exp $
*---------------------------------------------------------------------*/
#---------------------------------------------------------------------
# 初期化を行なう.
# この領域は初期化処理後にオーバーレイされるのであまり命令数に
# 気をはらう必要はないので, 先に計算できるものは成るべくここで
# しておく.
#---------------------------------------------------------------------
#---------------------------------------------------------------------
# 定数の初期化
# outp DMEM 内のコマンドバッファのポインタ
# outpThd DMEM 内のコマンドバッファの FULL 判定ポインタ
# vzero 全ての要素が 0 の Vec. Reg.
# vone 全ての要素が 1 の Vec. Reg.
# vconst* VU 計算時に使用する定数値を保持する
#---------------------------------------------------------------------
# Vzero is initialized once in a task.
#if (defined(USE_RSPBOOT0) && !defined(SAFE_MODE))
vor vzero, $v16, $v16 # $v16->vzero へ
#else
vxor vzero, vzero, vzero
#endif
RSP_LOADUCODE_Return:
lqv vconst0[0], RSP_LSTAT_VCONST0(zero)
lqv vconst1[0], RSP_LSTAT_VCONST1(zero)
#ifdef UCODE_S2DEX2
lqv vconst2[0], RSP_LSTAT_VCONST2(zero)
lqv vconst3[0], RSP_LSTAT_VCONST3(zero)
_li (vecptr, RSPOBJ_VPTR)
#endif
_li (outp, RSP_WORK_OUTPUT_0)
vadd vone, vzero, vzero # Clear VCO DEBUG v2.08
_li (outpThd, RSP_WORK_OUTPUT_THD_0)
vsub vone, vzero, _0xffff
#if defined(OUT_fifo)
#---------------------------------------------------------------------
# STATUS フラグのクリア
# SP_STATUS YIELDED/TASKDONE フラグのクリア
#
# 初期状態/LoadUcode後状態/Yield 復帰 かの判定
# RSP_GSTAT_FIFO_OUTP が 0 なら初期状態であるとみなし, FIFO の
# 設定処理を行なう.
# GTASK_FLAGS を参照して OS_TASK_YIELDED フラグを調べ Yield
# 復帰でないなら LoadUcode 後の処理へ JUMP する.
# また Yield 復帰後に LoadUcode を処理する場合に対応するため,
# GTASK_FLAGS をクリアしておく.
#---------------------------------------------------------------------
Assign(sys2, 1)
lw sys0, RSP_GSTAT_FIFO_OUTP(zero)
lw sys1, GTASK_FLAGS(zero)
_li (sys2, SP_CLR_YIELDED|SP_CLR_TASKDONE)
beq sys0, zero, doInit_InitFifo # Fifo 設定へ
mtc0 sys2, SP_STATUS
andi sys1, sys1, OS_TASK_YIELDED
beq sys1, zero, doInit_SetOverlay
sw zero, GTASK_FLAGS(zero) # FLAGS のクリア
EndAssign(sys2, 1)
#---------------------------------------------------------------------
# Yield からの復帰処理
# DL の処理継続位置を取得する.
# SubSet モジュールがロードされているならロードする.
#---------------------------------------------------------------------
j doInit_Overlay
lw inp, RSP_SAVE_YIELD_INP(zero)
#---------------------------------------------------------------------
# RDP が XBUS を参照しているなら FIFO をリセットする.
#---------------------------------------------------------------------
doInit_InitFifo:
mfc0 sys0, CMD_STATUS
andi sys0, sys0, DPC_STATUS_XBUS_DMEM_DMA
bne sys0, zero, doInit_RestartFifo
#---------------------------------------------------------------------
# DRAM-FIFO バッファの設定
# DP が現在 fifo のどこを処理しているかを判定することで,
# Fifo への書き込み開始位置を取得する. これによって, 複数の
# マイクロコードを使用しているときにも Fifo バッファを共用す
# ることができる.
#---------------------------------------------------------------------
Assign(rdpcur, 1)
Assign(rdpend, 2)
Assign(buftop, 3)
Assign(bufend, 4)
#---------------------------------------------------------------------
# RDP が現在処理中である RDP コマンド領域の最終位置が fifo
# バッファ先頭よりも前にあるなら FIFO エリアとは重ならない
# ので FIFO 先頭から使用できる.
#
# if (buftop > rdpend) goto restart_fifo;
#---------------------------------------------------------------------
mfc0 rdpend, CMD_END
lw buftop, GTASK_OUTBUFF(zero)
sub sys0, buftop, rdpend
bgtz sys0, doInit_RestartFifo
#---------------------------------------------------------------------
# CMD_CURRENT が 0 なら FIFO が初期状態であるとみなしリセッ
# トする. また同様に, RDP コマンドの領域の現在参照領域が,
# FIFO バッファの最終位置より後ろにあるなら FIFO エリアと
# 重ならないので FIFO 先頭から使用できる.
#
# if ( NULL == rdpcur) goto restart_fifo;
# if (bufend <= rdpcur) goto restart_fifo;
#---------------------------------------------------------------------
mfc0 rdpcur, CMD_CURRENT
lw bufend, GTASK_OUTBUFF_SZ(zero)
beq rdpcur, zero, doInit_RestartFifo
sub sys0, rdpcur, bufend
bgez sys0, doInit_RestartFifo
nop
#---------------------------------------------------------------------
# CMD_CURRENT != CMD_END なら, すなわち RDP の処理が終了していな
# いなら FIFO の続きから出力する.
#---------------------------------------------------------------------
bne rdpcur, rdpend, doInit_SetFifo
#---------------------------------------------------------------------
# Fifo 書き込み位置のリセット
# Fifo の先頭から書き込むように指定する.
#---------------------------------------------------------------------
doInit_RestartFifo:
# DP ステータスが DPC_STATUS_START_VALID になるまで待機
mfc0 sys0, CMD_STATUS
andi sys0, sys0, DPC_STATUS_START_VALID
bne sys0, zero, doInit_RestartFifo
# DP コマンドバッファとして DRAM を参照するように変更
_li (sys0, DPC_CLR_XBUS_DMEM_DMA)
mtc0 sys0, CMD_STATUS
# 次に書き込む位置をリセット/ DP コマンドポインタを設定
lw rdpend, GTASK_OUTBUFF_SZ(zero)
mtc0 rdpend, CMD_START
mtc0 rdpend, CMD_END
#---------------------------------------------------------------------
# Fifo への DP コマンドの送信位置を DMEM へ保存する
#---------------------------------------------------------------------
doInit_SetFifo:
sw rdpend, RSP_GSTAT_FIFO_OUTP(zero)
doInit_SetFifo_End:
EndAssign(rdpcur, 1)
EndAssign(rdpend, 2)
EndAssign(buftop, 3)
EndAssign(bufend, 4)
#elif defined(OUT_xbus)
#---------------------------------------------------------------------
# DMEM-FIFO バッファの設定
# DP のコマンドバッファを DMEM 上にとるように設定する.
# XBUS マイクロコードの次に起動するマイクロコードには
# DP_WAIT フラグを設定して DP の終了を待つ必要がある
# XBUS->AUDIO 必要
# XBUS->XBUS 必要/不要?
# XBUS->FIFO 必要
# FIFO->AUDIO 不要
# FIFO->XBUS 必要? 描画中に XBUS_DRAM の切替は可能?
# FIFO->FIFO 不要
# RSPBOOT で判定する?
#---------------------------------------------------------------------
doInit_InitXbus:
# RDP の処理が終了するまで待つ
# DP ステータスが DPC_STATUS_START_VALID になるまで待機
mfc0 sys0, CMD_STATUS
andi sys0, sys0, DPC_STATUS_DMA_BUSY|DPC_STATUS_START_VALID
bne sys0, zero, doInit_InitXbus
# RSP_GSTAT_FIFO_OUTP をリセットする
sw zero, RSP_GSTAT_FIFO_OUTP(zero)
# DP コマンドバッファとして DMEM を参照するように変更
_li (sys0, DPC_SET_XBUS_DMEM_DMA)
mtc0 sys0, CMD_STATUS
# 次に書き込む位置をリセット/ DP コマンドポインタを設定
_li (outp, RSP_WORK_OUTPUT_0)
mtc0 outp, CMD_START
mtc0 outp, CMD_END
#---------------------------------------------------------------------
# STATUS フラグのクリア
# SP_STATUS YIELDED/TASKDONE フラグのクリア
#
# 初期状態/LoadUcode後状態/Yield 復帰 かの判定
# GTASK_FLAGS を参照して OS_TASK_YIELDED フラグを調べ Yield
# 復帰でないなら LoadUcode 後の処理へ JUMP する.
# また Yield 復帰後に LoadUcode を処理する場合に対応するため,
# GTASK_FLAGS をクリアしておく.
#---------------------------------------------------------------------
Assign(sys2, 1)
lw sys1, GTASK_FLAGS(zero)
_li (sys2, SP_CLR_YIELDED|SP_CLR_TASKDONE)
mtc0 sys2, SP_STATUS
andi sys1, sys1, OS_TASK_YIELDED
beq sys1, zero, doInit_SetGstat # Gstat 設定へ
sw zero, GTASK_FLAGS(zero) # FLAGS のクリア
EndAssign(sys2, 1)
#---------------------------------------------------------------------
# Yield からの復帰処理
# DL の処理継続位置を取得する.
#---------------------------------------------------------------------
j doInit_Overlay
lw inp, RSP_SAVE_YIELD_INP(zero)
#endif
#---------------------------------------------------------------------
# 全ての UCode のコード量の差を埋めるために nop を追加し
# 調整する
# F3DEX_fifo が最大長になるのでそれにあわせる
#---------------------------------------------------------------------
#ifdef OUT_xbus
nop nop nop nop nop nop nop nop
nop nop nop nop nop nop nop nop
#endif
#if defined(UCODE_F3DEX2_Rej)||defined(UCODE_F3DLX2_Rej)
nop nop nop nop nop nop
#endif
#if defined(UCODE_L3DEX2)
nop nop nop
#endif
#---------------------------------------------------------------------
# その他の GSTAT エリアの初期化
#---------------------------------------------------------------------
doInit_SetGstat:
lw sys0, RSP_GSTAT_DRAM_STACK(zero)
bne sys0, zero, doInit_SetOverlay
lw sys0, GTASK_STACK(zero)
sw sys0, RSP_GSTAT_DRAM_STACK(zero)
#---------------------------------------------------------------------
# Overlay コードのアドレス値の変換
# DRAM 上に保持されている Overlay / SubModule のアドレスを
# 取得する. DMEM 上の OFFSET 値に UCODE のアドレス値を加算
# することで各モジュールへのアドレスが計算できる.
#
# ここから LoadUcode の処理が合流する
#---------------------------------------------------------------------
doInit_SetOverlay:
Assign(base, 1)
Assign(adr0, 2)
Assign(adr1, 3)
Assign(adr2, 4)
Assign(adr3, 5)
#if (defined(UCODE_F3DEX2)||defined(UCODE_F3DEX2_NoN))
# define OVERLAY2 RSP_SUBMOD_OVERLAY_LIGHTING
# define OVERLAY3 RSP_SUBMOD_OVERLAY_CLIPPING
#elif (defined(UCODE_S2DEX2))
# define OVERLAY2 RSP_LSTAT_OVERLAY_SPRITE
# define OVERLAY3 RSP_LSTAT_OVERLAY_BG1CYC
#endif
lw base, GTASK_UCODE(zero)
lw adr0, RSP_LSTAT_OVERLAY_TASKDONE(zero)
lw adr1, RSP_LSTAT_OVERLAY_RSPBOOT(zero)
#ifdef OVERLAY2
lw adr2, OVERLAY2(zero)
lw adr3, OVERLAY3(zero)
#endif
add adr0, adr0, base
add adr1, adr1, base
sw adr0, RSP_LSTAT_OVERLAY_TASKDONE(zero)
sw adr1, RSP_LSTAT_OVERLAY_RSPBOOT(zero)
#ifdef OVERLAY2
add adr2, adr2, base
add adr3, adr3, base
sw adr2, OVERLAY2(zero)
sw adr3, OVERLAY3(zero)
#endif
EndAssign(base, 1)
EndAssign(adr0, 2)
EndAssign(adr1, 3)
EndAssign(adr2, 4)
EndAssign(adr3, 5)
#---------------------------------------------------------------------
# Scissor Box のデコード (必要な場合のみ)
#---------------------------------------------------------------------
#if (defined(UCODE_L3DEX2)||defined(UCODE_S2DEX2))
lw gfx0, RSP_GSTAT_SCISSOR+0(zero)
jal case_G_SETSCISSOR_Decode
lw gfx1, RSP_GSTAT_SCISSOR+4(zero)
#endif
#---------------------------------------------------------------------
# DL の処理先頭番地の取得
#---------------------------------------------------------------------
lw inp, GTASK_DATA(zero)
#---------------------------------------------------------------------
# RSPBOOT Overlay 開始
# Overlay のため初期化部分を 8 バイト整列させる必要があるので
# .align を挿入する.
#---------------------------------------------------------------------
doInit_Overlay: _li (sys0, RSP_LSTAT_OVERLAY_RSPBOOT)
.align 8
jal LoadOverlay
_mov (sys1, return)
#=====================================================================
# ここまでのコードはマイクロコード始動後, 使用しないので Overlay を
# かけて他のコードをロードする.
#=====================================================================
/*======== End of gxinit.s ========*/