Nugget
Loading...
Searching...
No Matches
gte-nclip.c
Go to the documentation of this file.
1// NCLIP: normal clipping (screen-space triangle winding / area)
2// MAC0 = SX0*(SY1-SY2) + SX1*(SY2-SY0) + SX2*(SY0-SY1)
3
4CESTER_TEST(nclip_ccw, gte_tests,
5 cop2_put(12, 0x00000000); // (0,0)
6 cop2_put(13, 0x00000064); // (100,0)
7 cop2_put(14, 0x00640000); // (0,100)
10 int32_t mac0;
11 cop2_get(24, mac0);
13 cester_assert_uint_eq(0, gte_read_flag());
14)
15
16CESTER_TEST(nclip_cw, gte_tests,
17 cop2_put(12, 0x00000000);
18 cop2_put(13, 0x00640000); // (0,100)
19 cop2_put(14, 0x00000064); // (100,0)
22 int32_t mac0;
23 cop2_get(24, mac0);
25)
26
27CESTER_TEST(nclip_collinear, gte_tests,
28 cop2_put(12, 0x00000000);
29 cop2_put(13, 0x00320032); // (50,50)
30 cop2_put(14, 0x00640064); // (100,100)
33 int32_t mac0;
34 cop2_get(24, mac0);
36)
37
38// NCLIP with large screen coords near saturation limits
39CESTER_TEST(nclip_large_coords, gte_tests,
40 // SXY values near the screen coord limits (-0x400..0x3FF)
41 cop2_put(12, (0xfc00 << 16) | 0x03ff); // (0x3FF, -0x400)
42 cop2_put(13, (0x03ff << 16) | 0xfc00); // (-0x400, 0x3FF)
43 cop2_put(14, 0x00000000); // (0, 0)
46 int32_t mac0;
48 cop2_get(24, mac0);
49 flag = gte_read_flag();
50 // (0x3FF * 0x3FF) + (-0x400 * 0) + (0 * (-0x400))
51 // - (0x3FF * 0) - (-0x400 * (-0x400)) - (0 * 0x3FF)
52 // = 0x3FF*0x3FF - 0x400*0x400 = 1046529 - 1048576 = -2047
53 // Actually: SX0=0x3FF, SY0=-0x400, SX1=-0x400, SY1=0x3FF, SX2=0, SY2=0
54 // MAC0 = SX0*(SY1-SY2) + SX1*(SY2-SY0) + SX2*(SY0-SY1)
55 // = 0x3FF*(0x3FF-0) + (-0x400)*(0-(-0x400)) + 0*((-0x400)-0x3FF)
56 // = 0x3FF*0x3FF + (-0x400)*0x400
57 // = 1046529 - 1048576 = -2047
58 ramsyscall_printf("NCLIP large: MAC0=%d FLAG=0x%08x\n", mac0, flag);
61)
62
63// NCLIP MAC0 overflow: maximum possible cross product
64CESTER_TEST(nclip_overflow, gte_tests,
65 // Use values that produce MAC0 > 0x7FFFFFFF
66 // Max SX/SY after saturation is -0x400..0x3FF (11-bit signed)
67 // Max cross product: 0x3FF*0x3FF*2 + 0x400*0x400*2 ~ 4 million, no overflow
68 // Need unsaturated values: SXY registers are 16-bit signed
69 cop2_put(12, (0x7fff << 16) | 0x7fff); // (32767, 32767)
70 cop2_put(13, (0x8000 << 16) | 0x8000); // (-32768, -32768)
71 cop2_put(14, (0x7fff << 16) | 0x8000); // (-32768, 32767)
74 int32_t mac0;
76 cop2_get(24, mac0);
77 flag = gte_read_flag();
78 ramsyscall_printf("NCLIP overflow: MAC0=%d FLAG=0x%08x\n", mac0, flag);
79 // Check if FLAG.16 or FLAG.15 (MAC0 overflow) is set
80 ramsyscall_printf(" FLAG.16=%u FLAG.15=%u\n", (flag >> 16) & 1, (flag >> 15) & 1);
82 uint32_t f15 = (flag >> 15) & 1;
84)
CESTER_TEST(cpu_cop0_basic_write_bp, cpu_tests, uint32_t expectedEPC;uint32_t t;volatile uint32_t *ptr=(volatile uint32_t *) 0x58; *ptr=1;__asm__ volatile("" " lui %0, 0b1100101010000000\n" " mtc0 %0, $7\n" " li %0, 0x58\n" " mtc0 %0, $5\n" " li %0, 0xfffffff0\n" " mtc0 %0, $9\n" :"=r"(t));cester_assert_uint_eq(1, *ptr);__asm__ volatile("la %0, 1f\n1:\nsw $0, 0x58($0)" :"=r"(expectedEPC));__asm__ volatile("mtc0 $0, $7\n");cester_assert_uint_eq(0, *ptr);cester_assert_uint_eq(1, s_got40);cester_assert_uint_eq(0, s_got80);cester_assert_uint_eq(0x40, s_from);cester_assert_uint_eq(expectedEPC, s_epc);) CESTER_TEST(cpu_cop0_kseg_write_bp
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_NCLIP
Definition cop2.h:133
#define cop2_get(reg, dest)
Definition cop2.h:189
cester_assert_int_eq(0, hi)
gte_tests
Definition gte-depthcue.c:29
gte_clear_flag()
ramsyscall_printf("DCPL: MAC=(%d,%d,%d) RGB2=0x%08x\n", mac1, mac2, mac3, rgb2)
uint32_t flag
Definition gte-edgecase.c:36
int32_t mac0
Definition gte-edgecase.c:149
void uint32_t(classId, spec)