gxs2imm.s
10.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
/*---------------------------------------------------------------------*
Copyright (C) 1997, Nintendo.
File gxs2imm.s
Coded by Yoshitaka Yasumoto. Oct 20, 1997.
$Id: gxs2imm.s,v 1.1.1.1 2002/05/02 03:29:11 blythe Exp $
*---------------------------------------------------------------------*/
#============================================================================
# IMM 系処理
#============================================================================
#ifndef OVERLAY
#else /* OVERLAY */
.symbol case_G_SPECIAL_1, GfxDone
.symbol case_G_SPECIAL_2, GfxDone
.symbol case_G_SPECIAL_3, GfxDone
#---------------------------------------------------------------------
# case_G_DMA_IO (DEBUG 用)
# IMEM/DMEM 内のデータを DMA で DRAM へ読み出したり書き出し
# たりする.
#
# +------------+-+----------+---+-+------+--------+---+
# | DMA_IO |F| dmem_adrs/8 |0| dma_len/8 |000|
# +------------+-+----------+---+-+------+--------+---+
# | dram adrs |
# +------------+------------+------------+------------+
#---------------------------------------------------------------------
AssignForDMAproc
case_G_DMA_IO:
jal AdrsFixup
lh dmem_adrs, RSP_DLINPUT_BOTTOM-7(dinp) # F が符号拡張される
andi dma_len, gfx0, 0xff8
sra dmem_adrs, dmem_adrs, 2
j DMAproc
_li (return, DMAwaitGfxDone)
EndAssignForDMAproc
#---------------------------------------------------------------------
# case_G_RDPHALF_0
# GBI を内部バッファに保存する.
# TextureRectangle 系のコマンド Part 1 を処理する
#---------------------------------------------------------------------
# case_G_RDPHALF_1
# GBI を内部バッファに保存する.
# TextureRectangle 系のコマンド Part 2 を処理する
# パラメータが足りない GBI の補助用にも使用
#---------------------------------------------------------------------
# RSP_STATEP_RDPHALF_0L と RSP_STATEP_RDPHALF_1L のアドレス差
# が 4Bytes であることを利用して共通化する.
#---------------------------------------------------------------------
.symbol adrs_G_RDPHALF_0, case_G_RDPHALF_0 & 0x1fff
.symbol RSP_RDPHALF_DIFF, RSP_GSTAT_RDPHALF_0H - adrs_G_RDPHALF_0
case_G_RDPHALF_0:
sw gfx0, RSP_RDPHALF_DIFF+0(sys0)
case_G_RDPHALF_1:
j GfxDone
sw gfx1, RSP_RDPHALF_DIFF+4(sys0)
#---------------------------------------------------------------------
# case_G_SELECT_DL
# 条件に一致した場合において DL を呼び出す.
# +------------------------------------------+
# |G_RDPHALF_0| sid:8 | DL_L:16 |
# +------------------------------------------+
# | flag:32 |
# +------------------------------------------+
# |G_SELECT_DL| param:8 | DL_H:16 |
# +------------------------------------------+
# | mask:32 |
# +------------------------------------------+
#
# (STATUS[sid] & mask) == flag の場合には, 呼び出さない.
# その他の場合, 呼び出しを行ない STATUS を以下のように変更.
# STATUS[sid] = (STATUS[sid] & ~mask) | (flag & mask);
#
# gfx1 に DL の値を代入し G_DL へ処理を移す.
# param は G_DL_PUSH, G_DL_NOPUSH のいづれかである.
#---------------------------------------------------------------------
case_G_SELECT_DL:
Assign(sid, 1)
Assign(status, 2)
Assign(flag, 3)
Assign(flag2, 4)
# define mask gfx1
Assign(maskR, 5)
Assign(tmp, 6)
lbu sid, RSP_STATEP_RDPHALF_0H+1(zero)
lw flag, RSP_STATEP_RDPHALF_0L(zero)
nor maskR, mask, zero
lw status, RSPOBJ_GENSTAT_TABLE(sid)
sh gfx0, RSP_STATEP_RDPHALF_0H(zero)
and flag2, flag, mask
and tmp, status, mask
beq tmp, flag, GfxDone # status & mask == flag なら終
and tmp, status, maskR
or tmp, tmp, flag2 # 新 status の作成
sw tmp, RSPOBJ_GENSTAT_TABLE(sid) # 新 stat 保存
lw gfx1, RSP_STATEP_RDPHALF_0H(zero) # DL の取得
# gfx1 に DL のポインタを代入して G_DL へ抜ける
EndAssign(sid, 1)
EndAssign(status, 2)
EndAssign(flag, 3)
EndAssign(flag2, 4)
# undef mask
EndAssign(maskR, 5)
EndAssign(tmp, 6)
#---------------------------------------------------------------------
# case_G_DL
# 指定された DL へ処理を移す.
# gfx0 の bit15 が 1 なら gSPBranchDL, 0 なら gSPDisplayList
# となる. DL スタックのオーバーフローのチェックはしていない.
#---------------------------------------------------------------------
case_G_DL:
FixedAssign(stackp, 1)
FixedAssign(param, 2)
Assign(save_inp, 3)
lbu stackp, RSP_GSTAT_DL_N(zero)
sll param, gfx0, 15
case_G_DL_0: jal AdrsFixup # gximm_ex.s から Jump in する
add save_inp, inp, dinp
bltz param, StartDLload
_mov (inp, dram_adrs)
sw save_inp, RSP_GSTAT_DLSTACK_OFFSET(stackp)
addi stackp, stackp, 4
case_G_DL_1: j StartDLload # G_ENDDL から Jump in する
sb stackp, RSP_GSTAT_DL_N(zero)
EndAssign(param, 2)
EndAssign(save_inp, 3)
#---------------------------------------------------------------------
# case_G_ENDDL
# DL スタックを POP して 呼び出し側の DL へ処理を移す
#
# JUMP 先の TaskDone は stackp($1) で DL スタックの計算を行な
# うことに依存したコードとなっているので変更するときは注意する.
#---------------------------------------------------------------------
case_G_ENDDL: lbu stackp, RSP_GSTAT_DL_N(zero) # Load Delay 2clk
beq stackp, zero, TaskDone # stackp == -4 で Jump
addi stackp, stackp, -4
j case_G_DL_1
lw inp, RSP_GSTAT_DLSTACK_OFFSET(stackp)
EndAssign(stackp, 1)
#---------------------------------------------------------------------
# case_G_MOVEWORD
# 32bit データを DMEM に書き込む
#
# Level 2 から GBI が変更になったので注意すること.
# +------------+------------+------------+------------+
# | MOVEWORD | index | offset |
# +------------+------------+------------+------------+
# | data |
# +------------+------------+------------+------------+
#
# DMEM のレンジは下位 12 Bit しかないので上位の値をあえて
# マスクする必要はない.
#---------------------------------------------------------------------
case_G_MOVEWORD:
Assign(index, 1)
FixedAssign(adrs, 2)
srl index, gfx0, 16
lhu adrs, RSP_LSTAT_MOVEWORD_OFFSET-(G_MOVEWORD<<8)(index)
case_G_MOVEWORD_0:
# gximm_ex.s からここへ Jump する
add adrs, adrs, gfx0
j GfxDone
sw gfx1, 0(adrs)
EndAssign(index, 1)
EndAssign(adrs, 2)
#---------------------------------------------------------------------
# case_G_OBJ_MOVEMEM
# RDRAM から DMEM へデータの転送を行なう
# +-----------------------+
# |CMD:8|Len:8| ID:16 |
# +-----------------------+
# | Source Adrs:32 |
# +-----------------------+
#
# Matrix スプライトの回転のためのマトリクスをロードする.
# SubMatrix スプライトの移動, スケーリング値をロードする.
#---------------------------------------------------------------------
case_G_OBJ_MOVEMEM:
AssignForDMAproc
jal AdrsFixup # Matrix データのアドレスの変換
lhu dmem_adrs, RSP_MOVEMEM_TBL(gfx0) # 転送先アドレス
lbu dma_len, (RSP_DLINPUT_BOTTOM-7)(dinp)
j DMAread
case_G_SETOTHERMODE_H:
_li (return, DMAwaitGfxDone)
EndAssignForDMAproc
#===== この間に命令をいれてはならん. =====
#---------------------------------------------------------------------
# case_G_SETOTHERMODE_[LH]
# Other mode フラグを ON/OFF し RDP へ送る
# case_G_SETOTHERMODE_H と case_G_SETOTHERMODE_L のアドレス差
# が 4 Bytes であることを利用して処理を行なっているのでこれを
# 変更する場合はここを修正すること. case_G_SETOTHERMODE_H は
# この前のルーチン case_G_DMA_General 内にそのエントリがある.
# 本命令は RDP 系の命令ではあるが, 他の RDP 系の命令の中で都
# 合の良い命令で終るもの(case_G_SETOTHERMODE_H のエントリとし
# て使えそうな命令)が gxrdp.s 内に無かったため, 止む終えず
# gximm.s に置いてある.
#
# Level 2 から GBI が変更になったので注意すること.
# +------------+------------+------------+------------+
# |OTHERMODE_LH| |32-shift-len| len-1 |
# +------------+------------+------------+------------+
# | data |
# +------------+------------+------------+------------+
#
# DL のデコード時にジャンプ先を代入した sys0 を用いて
# RSP_OTHERMODE の _H/_L の違いを吸収する.
# srlv/srav 命令のシフト数は下位 5 bit のみが有効なので
# わざわざ and を掛ける必要はない.
#---------------------------------------------------------------------
case_G_SETOTHERMODE_L:
Assign(shft, 1)
Assign(mask, 2)
Assign(mode, 3)
.symbol adrs_G_SETOTHERMODE_L, (case_G_SETOTHERMODE_L & 0x1fff)
.symbol RSP_OTHERMODE_DIFF, (RSP_GSTAT_OTHER_L-adrs_G_SETOTHERMODE_L)
lw mode, RSP_OTHERMODE_DIFF(sys0)
lui mask, 0x8000 # mask = 0x80000000
srav mask, mask, gfx0 # mask = 11..100..0b (1 が len 個)
srl shft, gfx0, 8 # shift 値の取得
srlv mask, mask, shft # mask = 00..011..100..0
nor mask, mask, zero # Bit 反転 mask = 11..100..011..1
and mode, mode, mask # 変更するフラグをクリアする
or mode, mode, gfx1 # フラグ変更
sw mode, RSP_OTHERMODE_DIFF(sys0) # DMEM に変更を保存
lw gfx0, RSP_GSTAT_OTHER_H(zero)
j case_G_RDP_General
lw gfx1, RSP_GSTAT_OTHER_L(zero)
EndAssign(shft, 1)
EndAssign(mask, 2)
EndAssign(mode, 3)
#---------------------------------------------------------------------
# case_G_OBJ_RENDERMODE
# OBJ の描画モードを RSP に知らせる.
#
# G_OBJRM_NOTXCLAMP 0x01
# G_OBJRM_XLU 0x02 # Ignored
# G_OBJRM_ANTIALIAS 0x04 # Ignored
# G_OBJRM_BILERP 0x08
# G_OBJRM_SHRINKSIZE_1 0x10
# G_OBJRM_SHRINKSIZE_2 0x20
# G_OBJRM_SHRINKSIZE_3 0x30
# G_OBJRM_WIDEN 0x40
#
# gfx0 = [Cmd | ]
# gfx1 = [ |Mode]
#---------------------------------------------------------------------
case_G_OBJ_RENDERMODE:
Assign(ptr, 1)
Assign(shiftA, 2)
Assign(shiftB, 3)
sb gfx1, RSPOBJ_RENDERMODE(zero)
#
# Transparent/AntiAlias/Bilerp の設定
#
andi ptr, gfx1, 0x08 # 8 倍
addiu ptr, ptr, RSPOBJ_RENDERTBL_SMODE
sh ptr, RSPOBJ_RENDERP_SMODE(zero)
#
# Texture Window
#
andi ptr, gfx0, 0x08
addiu ptr, ptr, RSPOBJ_RENDERTBL_TWINDOW
sh ptr, RSPOBJ_RENDERP_TWINDOW(zero)
#
# Shrink Param [2|3]
#
andi ptr, gfx1, 0x18 # Bilerp|Shrink1
srl ptr, ptr, 1
lw shiftB, RSPOBJ_SHRINKOBJ_TBL(ptr)
#
# Shrink Param [0|1]
#
andi ptr, gfx1, 0x70 # Shrink1|Shrink2|Widen
srl ptr, ptr, 2
lw shiftA, RSPOBJ_SHRINKIMG_TBL(ptr)
sw shiftB, RSPOBJ_SHRINKPARAM+4(zero)
j GfxDone
sw shiftA, RSPOBJ_SHRINKPARAM+0(zero)
EndAssign(ptr, 1)
EndAssign(shiftA, 2)
EndAssign(shiftB, 3)
#endif /* OVERLAY */
/*======== End of gximm.s ========*/