gs2imm.s
7.59 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
/*---------------------------------------------------------------------
Copyright (C) 1997, Nintendo.
File gs2imm.s
Coded by Yoshitaka Yasumoto. Jan 23, 1997.
Modified by
Comments
$Id: gs2imm.s,v 1.1.1.1 2002/05/02 03:29:12 blythe Exp $
---------------------------------------------------------------------*/
# ================================================================
# IMM 系処理
# ================================================================
# ----------------------------------------------------------------
# case_G_RDPHALF_0
# TextureRectangle 系のコマンド Part 1 を処理する
# noYield を無くすためにまとめて処理を行なう
# ----------------------------------------------------------------
case_G_RDPHALF_0:
sw gfx0, RSP_STATEP_RDPHALF_0H(zero)
j GfxDone
sw gfx1, RSP_STATEP_RDPHALF_0L(zero)
# ----------------------------------------------------------------
# case_G_RDPHALF_1
# TextureRectangle 系のコマンド Part 2 を処理する
# パラメータが足りない GBI の補助用にも使用
# ----------------------------------------------------------------
case_G_RDPHALF_1:
j GfxDone
sw gfx1, RSP_STATEP_RDPHALF_1L(zero)
# ----------------------------------------------------------------
# case_G_TEXRECT_DONE
# TextureRectangle 系のコマンド Part 3 を処理する
# ----------------------------------------------------------------
case_G_TEXRECT_DONE:
Assign(cmd0, 1)
Assign(cmd1, 2)
lw gfx0, RSP_STATEP_RDPHALF_1L(zero)
sw gfx1, 12(outp)
lw cmd1, RSP_STATEP_RDPHALF_0L(zero)
sw gfx0, 8(outp)
lw cmd0, RSP_STATEP_RDPHALF_0H(zero)
sw cmd1, 4(outp)
addi outp, outp, 16
j OutputCloseGfxDone
sw cmd0, 0-16(outp)
EndAssign(cmd0, 1)
EndAssign(cmd1, 2)
# ----------------------------------------------------------------
# case_G_ENDDL
# DL スタックを POP して 呼び出し側の DL へ処理を移す
# ----------------------------------------------------------------
case_G_ENDDL:
Assign(stackp, 2)
lbu stackp, RSP_STATEP_DL_N(zero) # Load Delay 2clk
beq stackp, zero, TaskDone
addi stackp, stackp, -4
sb stackp, RSP_STATEP_DL_N(zero)
j StartDLload
lw inp, RSP_DLSTACK_OFFSET(stackp)
EndAssign(stackp, 2)
# ----------------------------------------------------------------
# case_G_SETOTHERMODE_[LH]
# Other mode フラグを ON/OFF し RDP へ送る
# ----------------------------------------------------------------
case_G_SETOTHERMODE_H:
nop
case_G_SETOTHERMODE_L:
Assign(mode, 1)
Assign(shift, 2)
Assign(maskA, 3)
Assign(maskB, 4)
.symbol adrs_G_SETOTHERMODE_L, (case_G_SETOTHERMODE_L & 0x1fff)
.symbol RSP_OTHERMODE_DIFF, (RSP_STATEP_OTHER_L-adrs_G_SETOTHERMODE_L)
#
# DL のデコード時にジャンプ先を代入した sys0 を用いて RSP_OTHERMODE
# の _H/_L の違いを吸収する
#
lw mode, RSP_OTHERMODE_DIFF(sys0)
srl shift, gfx0, 8
nor maskA, zero, zero # maskA = 0xffffffff
#
# sllv 命令のシフト数は下位 5 bit のみが有効なので
# わざわざ and を掛ける必要はない
#
sllv maskB, maskA, shift # maskB = 0xffffffff << (shift)
addi gfx0, gfx0, -1 # len = 32 の場合のための対策 (len>0)
sllv maskA, maskB, gfx0 # maskA = 0xffffffff << (shift+len-1)
sll maskA, maskA, 1 # maskA = maskA << 1
xor maskA, maskA, maskB # マスク値を得る
nor maskA, maskA, zero # 反転させる
#
# 次の DL を調べ, もし case_G_OTHERMODE_* なら RDP へ送らず
# に終了する
#
lb gfx0, RSP_DLINPUT_BOTTOM(dinp) # 次の DL を取得
and maskA, maskA, mode # 変更するフラグをクリアする
beq dinp, zero, sendToRDP # もし DL バッファが空なら送信
or mode, maskA, gfx1 # フラグの設定
addi sys1, gfx0, -G_SETOTHERMODE_L # 次の DL の調査
andi sys1, sys1, 0xfe
beq sys1, zero, GfxDone1 # 次も SETOTHERMODE なら終了
sendToRDP:
sw mode, RSP_OTHERMODE_DIFF(sys0) # DMEM に変更を保存
#
# RDP コマンドを発行する
#
#if 0 /* IMEM 節約にはこちらのコード */
lw gfx1, RSP_STATEP_OTHER_L(zero) # この順序なのは意味あり
j case_G_RDP_General
lw gfx0, RSP_STATEP_OTHER_H(zero)
#else /* 速度優先にはこちらのコード */
# gfx0 を保存したまま GfxDone1 へ飛ぶことで高速化をしている
lw sys1, RSP_STATEP_OTHER_H(zero)
addi outp, outp, 8
lw gfx1, RSP_STATEP_OTHER_L(zero)
sw sys1, 0-8(outp)
j OutputCloseGfxDone
sw gfx1, 4-8(outp)
#endif
EndAssign(mode, 1)
EndAssign(shift, 2)
EndAssign(maskA, 3)
EndAssign(maskB, 4)
# ----------------------------------------------------------------
# case_G_MOVEWORD
# DMEM 内の指定位置に WORD データを書き込む
# 現状では SEGMENT および General Status の設定にしか使用
# していない.
# ----------------------------------------------------------------
case_G_MOVEWORD:
Assign(target, 1)
Assign(outptr, 2)
Assign(offset, 3)
andi target, gfx0, 0xff
# SEGMENT/GENSTAT の設定以外のコマンドなら停止
Assert_geI(target, MOVEWORD_TBL_END+1)
Assert_ltI(target, MOVEWORD_TBL_BEGIN)
lhu outptr, (RSP_MOVEWORD_TBL-MOVEWORD_TBL_BEGIN)(target)
srl offset, gfx0, 8
add outptr, outptr, offset
j GfxDone
sw gfx1, 0(outptr)
EndAssign(target, 1)
EndAssign(outptr, 2)
EndAssign(offset, 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)
#if 1
#========================================================================
# 以下の 7 命令は gs2rdp.s から移動させたものである.
# これにより gs2imm.s の命令数がオーバーレイ領域と一致する.
#========================================================================
# ----------------------------------------------------------------
# case_G_RDPSETOTHERMODE
# 現在の OtherMode の設定を保存しておく.
# (G_SETOTHERMODE_[LH] のために必要)
# ----------------------------------------------------------------
case_G_RDPSETOTHERMODE:
sw gfx0, RSP_STATEP_OTHER_H(zero)
j case_G_RDP_General
sw gfx1, RSP_STATEP_OTHER_L(zero)
# ----------------------------------------------------------------
# case_G_RDP_AdrsFixup
# コマンド内のセグメントアドレスを物理アドレスに変換してから
# RDP コマンドとして送る
# ----------------------------------------------------------------
case_G_RDP_AdrsFixup:
Assign(dram_adrs, 19)
jal AdrsFixup
addi outp, outp, 8
j case_G_RDP_General2
sw dram_adrs, 4-8(outp)
EndAssign(dram_adrs, 19)
#endif
#----------------------------------------------------------------------------
# アドレス合せのための詰め物
# Overlay 領域 0 とのサイズを合わせるために nop を付加する
#----------------------------------------------------------------------------
IMM_PAD_START: .symbol dummy_IMM_PAD_START, 0
.space (StartDLload & 0xfffffff8)+0x1000
IMM_PAD_END: .symbol dummy_IMM_PAD_END, 0
/*======== End of gs2imm.s ========*/