Nugget
Loading...
Searching...
No Matches
gte-regio.c
Go to the documentation of this file.
1// GTE register I/O tests: data/control register read/write, sign extension,
2// SXY FIFO, IRGB/ORGB, LZCS/LZCR, FLAG register, CTC2 sign extension.
3
4// ==========================================================================
5// Data register roundtrip and sign/zero extension
6// ==========================================================================
7
8CESTER_TEST(regio_mac0_roundtrip, gte_tests,
9 cop2_put(24, 0x12345678);
11 cop2_get(24, out);
12 cester_assert_uint_eq(0x12345678, out);
13)
14
15CESTER_TEST(regio_mac1_roundtrip, gte_tests,
16 cop2_put(25, 0xdeadbeef);
18 cop2_get(25, out);
19 cester_assert_uint_eq(0xdeadbeef, out);
20)
21
22CESTER_TEST(regio_ir0_sign_extend, gte_tests,
23 cop2_put(8, 0x0000ffff);
25 cop2_get(8, out);
26 cester_assert_uint_eq(0xffffffff, out);
27)
28
29CESTER_TEST(regio_ir1_sign_extend, gte_tests,
30 cop2_put(9, 0x00008000);
32 cop2_get(9, out);
33 cester_assert_uint_eq(0xffff8000, out);
34)
35
36CESTER_TEST(regio_ir2_positive, gte_tests,
37 cop2_put(10, 0x00001234);
39 cop2_get(10, out);
40 cester_assert_uint_eq(0x00001234, out);
41)
42
43CESTER_TEST(regio_ir3_positive, gte_tests,
44 cop2_put(11, 0x00007fff);
46 cop2_get(11, out);
47 cester_assert_uint_eq(0x00007fff, out);
48)
49
50CESTER_TEST(regio_vz0_sign_extend, gte_tests,
51 cop2_put(1, 0x0000ff00);
53 cop2_get(1, out);
54 cester_assert_uint_eq(0xffffff00, out);
55)
56
57CESTER_TEST(regio_vxy0_packed, gte_tests,
58 cop2_put(0, 0x00640032);
60 cop2_get(0, out);
61 cester_assert_uint_eq(0x00640032, out);
62)
63
64CESTER_TEST(regio_otz_zero_extend, gte_tests,
65 cop2_put(7, 0xffffffff);
67 cop2_get(7, out);
68 cester_assert_uint_eq(0x0000ffff, out);
69)
70
71CESTER_TEST(regio_sz_zero_extend, gte_tests,
72 cop2_put(16, 0xdeadbeef);
74 cop2_get(16, out);
75 cester_assert_uint_eq(0x0000beef, out);
76)
77
78CESTER_TEST(regio_rgbc_roundtrip, gte_tests,
79 cop2_put(6, 0xaa554080);
81 cop2_get(6, out);
82 cester_assert_uint_eq(0xaa554080, out);
83)
84
85CESTER_TEST(regio_res1_readwrite, gte_tests,
86 cop2_put(23, 0xdeadbeef);
88 cop2_get(23, out);
89 cester_assert_uint_eq(0xdeadbeef, out);
90)
91
92// ==========================================================================
93// SXY FIFO
94// ==========================================================================
95
96CESTER_TEST(regio_sxy_fifo_push, gte_tests,
97 cop2_put(12, 0x00010002);
98 cop2_put(13, 0x00030004);
99 cop2_put(14, 0x00050006);
100 cop2_put(15, 0x00070008);
102 cop2_get(12, sxy0);
103 cop2_get(13, sxy1);
104 cop2_get(14, sxy2);
105 cester_assert_uint_eq(0x00030004, sxy0);
106 cester_assert_uint_eq(0x00050006, sxy1);
107 cester_assert_uint_eq(0x00070008, sxy2);
108)
109
110CESTER_TEST(regio_sxyp_read_returns_sxy2, gte_tests,
111 cop2_put(14, 0xaabbccdd);
112 uint32_t sxyp;
113 cop2_get(15, sxyp);
114 cester_assert_uint_eq(0xaabbccdd, sxyp);
115)
116
117CESTER_TEST(regio_sxy_fifo_triple_push, gte_tests,
118 cop2_put(15, 0x11111111);
119 cop2_put(15, 0x22222222);
120 cop2_put(15, 0x33333333);
122 cop2_get(12, sxy0);
123 cop2_get(13, sxy1);
124 cop2_get(14, sxy2);
125 cester_assert_uint_eq(0x11111111, sxy0);
126 cester_assert_uint_eq(0x22222222, sxy1);
127 cester_assert_uint_eq(0x33333333, sxy2);
128)
129
130// ==========================================================================
131// IRGB / ORGB
132// ==========================================================================
133
134CESTER_TEST(regio_irgb_expand, gte_tests,
135 cop2_put(28, 0x7fff);
136 __asm__ volatile("nop; nop; nop; nop");
138 cop2_get(9, ir1);
139 cop2_get(10, ir2);
140 cop2_get(11, ir3);
141 cester_assert_uint_eq(0x00000f80, ir1);
142 cester_assert_uint_eq(0x00000f80, ir2);
143 cester_assert_uint_eq(0x00000f80, ir3);
144)
145
146CESTER_TEST(regio_irgb_individual, gte_tests,
147 cop2_put(28, 0x000a); // R=10, G=0, B=0
148 __asm__ volatile("nop; nop; nop; nop");
150 cop2_get(9, ir1);
151 cop2_get(10, ir2);
152 cop2_get(11, ir3);
153 cester_assert_uint_eq(0x00000500, ir1); // 10 << 7
154 cester_assert_uint_eq(0x00000000, ir2);
155 cester_assert_uint_eq(0x00000000, ir3);
156)
157
158CESTER_TEST(regio_orgb_pack, gte_tests,
159 cop2_put(9, 0x0f80);
160 cop2_put(10, 0x0f80);
161 cop2_put(11, 0x0f80);
162 uint32_t orgb;
163 cop2_get(29, orgb);
164 cester_assert_uint_eq(0x7fff, orgb);
165)
166
167// ORGB saturates, not truncates (psx-spx correct, Sony SDK wrong)
168CESTER_TEST(regio_orgb_saturate_negative, gte_tests,
169 cop2_put(9, 0xffff8000); // IR1 = -32768 (negative)
170 cop2_put(10, 0x00002000); // IR2 = 8192 (large positive)
171 cop2_put(11, 0x00000380); // IR3 = 896 (normal)
172 uint32_t orgb;
173 cop2_get(29, orgb);
174 uint32_t r = orgb & 0x1f;
175 uint32_t g = (orgb >> 5) & 0x1f;
176 uint32_t b = (orgb >> 10) & 0x1f;
177 cester_assert_uint_eq(0, r); // negative saturated to 0
178 cester_assert_uint_eq(31, g); // large saturated to 0x1f
179 cester_assert_uint_eq(7, b); // 896 >> 7 = 7
180)
181
182CESTER_TEST(regio_orgb_saturate_large, gte_tests,
183 cop2_put(9, 0x1000);
184 cop2_put(10, 0x1000);
185 cop2_put(11, 0x1000);
186 uint32_t orgb;
187 cop2_get(29, orgb);
188 // 0x1000>>7 = 0x20 = 32, saturated to 31
189 cester_assert_uint_eq(0x7fff, orgb);
190)
191
192// ==========================================================================
193// LZCS / LZCR
194// ==========================================================================
195
196CESTER_TEST(regio_lzcr_zero, gte_tests,
197 cop2_put(30, 0x00000000);
198 uint32_t lzcr;
199 cop2_get(31, lzcr);
200 cester_assert_uint_eq(32, lzcr);
201)
202
203CESTER_TEST(regio_lzcr_all_ones, gte_tests,
204 cop2_put(30, 0xffffffff);
205 uint32_t lzcr;
206 cop2_get(31, lzcr);
207 cester_assert_uint_eq(32, lzcr);
208)
209
210CESTER_TEST(regio_lzcr_one, gte_tests,
211 cop2_put(30, 0x00000001);
212 uint32_t lzcr;
213 cop2_get(31, lzcr);
214 cester_assert_uint_eq(31, lzcr);
215)
216
217CESTER_TEST(regio_lzcr_msb_set, gte_tests,
218 cop2_put(30, 0x80000000);
219 uint32_t lzcr;
220 cop2_get(31, lzcr);
221 cester_assert_uint_eq(1, lzcr);
222)
223
224CESTER_TEST(regio_lzcr_positive_mid, gte_tests,
225 cop2_put(30, 0x00010000);
226 uint32_t lzcr;
227 cop2_get(31, lzcr);
228 cester_assert_uint_eq(15, lzcr);
229)
230
231CESTER_TEST(regio_lzcr_negative_mid, gte_tests,
232 cop2_put(30, 0xfffe0000);
233 uint32_t lzcr;
234 cop2_get(31, lzcr);
235 cester_assert_uint_eq(15, lzcr);
236)
237
238// ==========================================================================
239// FLAG register
240// ==========================================================================
241
242CESTER_TEST(regio_flag_write_mask, gte_tests,
243 cop2_putc(31, 0xffffffff);
244 uint32_t flag = gte_read_flag();
245 cester_assert_uint_eq(0xfffff000, flag);
246)
247
248CESTER_TEST(regio_flag_low_bits_masked, gte_tests,
249 cop2_putc(31, 0x00000fff);
250 uint32_t flag = gte_read_flag();
252)
253
254CESTER_TEST(regio_flag_bit12_no_summary, gte_tests,
255 cop2_putc(31, (1 << 12));
256 uint32_t flag = gte_read_flag();
257 cester_assert_uint_eq((1 << 12), flag);
258)
259
260CESTER_TEST(regio_flag_bits19_22_no_summary, gte_tests,
262 int ok = 1;
263 int i;
264 for (i = 19; i <= 22; i++) {
265 cop2_putc(31, (1u << i));
266 flag = gte_read_flag();
267 if (flag != (1u << i)) ok = 0;
268 }
270)
271
272CESTER_TEST(regio_flag_bits13_18_set_summary, gte_tests,
274 int ok = 1;
275 int i;
276 for (i = 13; i <= 18; i++) {
277 cop2_putc(31, (1u << i));
278 flag = gte_read_flag();
279 if (flag != ((1u << i) | (1u << 31))) ok = 0;
280 }
282)
283
284CESTER_TEST(regio_flag_bits23_30_set_summary, gte_tests,
286 int ok = 1;
287 int i;
288 for (i = 23; i <= 30; i++) {
289 cop2_putc(31, (1u << i));
290 flag = gte_read_flag();
291 if (flag != ((1u << i) | (1u << 31))) ok = 0;
292 }
294)
295
296// ==========================================================================
297// Control register sign extension
298// ==========================================================================
299
300CESTER_TEST(regio_ctrl_r33_sign_extend, gte_tests,
301 cop2_putc(4, 0x00008000);
303 cop2_getc(4, out);
304 cester_assert_uint_eq(0xffff8000, out);
305)
306
307CESTER_TEST(regio_ctrl_zsf3_sign_extend, gte_tests,
308 cop2_putc(29, 0x0000ffff);
310 cop2_getc(29, out);
311 cester_assert_uint_eq(0xffffffff, out);
312)
313
314// H register sign-extension bug (psx-spx documented, Sony omitted)
315CESTER_TEST(regio_h_sign_extension_bug, gte_tests,
316 cop2_putc(26, 0x8000);
317 uint32_t h;
318 cop2_getc(26, h);
319 cester_assert_uint_eq(0xffff8000, h);
320)
321
322CESTER_TEST(regio_h_positive, gte_tests,
323 cop2_putc(26, 0x7fff);
324 uint32_t h;
325 cop2_getc(26, h);
326 cester_assert_uint_eq(0x00007fff, h);
327)
328
329// All single-16bit control regs sign-extend
330CESTER_TEST(regio_ctc2_sign_extend_all, gte_tests,
332 int ok = 1;
333 // R33(4), L33(12), LB3(20), H(26), DQA(27), ZSF3(29), ZSF4(30)
334 cop2_putc(4, 0x8000); cop2_getc(4, out); if (out != 0xffff8000) ok = 0;
335 cop2_putc(12, 0x8000); cop2_getc(12, out); if (out != 0xffff8000) ok = 0;
336 cop2_putc(20, 0x8000); cop2_getc(20, out); if (out != 0xffff8000) ok = 0;
337 cop2_putc(26, 0x8000); cop2_getc(26, out); if (out != 0xffff8000) ok = 0;
338 cop2_putc(27, 0x8000); cop2_getc(27, out); if (out != 0xffff8000) ok = 0;
339 cop2_putc(29, 0x8000); cop2_getc(29, out); if (out != 0xffff8000) ok = 0;
340 cop2_putc(30, 0x8000); cop2_getc(30, out); if (out != 0xffff8000) ok = 0;
342)
343
344// lm flag clamp behavior
345CESTER_TEST(regio_lm_clamp, gte_tests,
346 // GPF sf=1 lm=0: IR clamp -0x8000..0x7fff
347 cop2_put(8, 0x1000);
348 cop2_put(9, 0xffff8000);
349 cop2_put(10, 0x100);
350 cop2_put(11, 0x7fff);
351 cop2_put(6, 0x00808080);
353 cop2_cmd(COP2_GPF(1, 0));
354 int32_t mac1_lm0;
355 uint32_t ir1_lm0;
356 cop2_get(25, mac1_lm0);
357 cop2_get(9, ir1_lm0);
358 // GPF sf=1 lm=1
359 cop2_put(8, 0x1000);
360 cop2_put(9, 0xffff8000);
361 cop2_put(10, 0x100);
362 cop2_put(11, 0x7fff);
363 cop2_put(6, 0x00808080);
365 cop2_cmd(COP2_GPF(1, 1));
366 int32_t mac1_lm1;
367 uint32_t ir1_lm1;
368 cop2_get(25, mac1_lm1);
369 cop2_get(9, ir1_lm1);
370 cester_assert_int_eq(-32768, mac1_lm0);
371 cester_assert_int_eq(-32768, mac1_lm1);
372 cester_assert_uint_eq(0xffff8000, ir1_lm0); // lm=0: stays -32768
373 cester_assert_uint_eq(0x00000000, ir1_lm1); // lm=1: clamped to 0
374)
cester_assert_uint_eq(1, *ptr)
#define cop2_cmd(op)
Definition cop2.h:175
#define cop2_put(reg, val)
Definition cop2.h:182
#define cop2_getc(reg, dest)
Definition cop2.h:203
#define COP2_GPF(sf, lm)
Definition cop2.h:168
#define cop2_putc(reg, val)
Definition cop2.h:196
#define cop2_get(reg, dest)
Definition cop2.h:189
uint32_t r
Definition cpu.c:222
uint32_t out
Definition cpu.c:62
uint8_t g
Definition gte-depthcue.c:38
uint8_t b
Definition gte-depthcue.c:39
gte_clear_flag()
uint32_t ir1
Definition gte-edgecase.c:108
uint32_t sxy2
Definition gte-edgecase.c:36
uint32_t ir3
Definition gte-precision.c:320
int ok
Definition gte-regio.c:286
CESTER_TEST(regio_mac0_roundtrip, CESTER_TEST(gte_tests, cop2_put(24, 0x12345678);uint32_t out;cop2_get(24, out);cester_assert_uint_eq(0x12345678, out);)
Definition gte-regio.c:8
gte_tests
Definition gte-regio.c:284
cester_assert_int_eq(1, ok)
uint32_t flag
Definition gte-regio.c:285
int i
Definition gte-regio.c:287
uint32_t sxy0
Definition gte-rtps.c:164
uint32_t sxy1
Definition gte-rtps.c:164
uint32_t ir2
Definition gte-sqr.c:24
void uint32_t(classId, spec)