Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
gte-sqr.c
Go to the documentation of this file.
1// SQR: square of IR vector
2
3// clang-format off
4
5CESTER_TEST(sqr_shifted, gte_tests,
6 cop2_put(9, 0x1000); // 1.0
7 cop2_put(10, 0x0800); // 0.5
8 cop2_put(11, 0x2000); // 2.0
10 cop2_cmd(COP2_SQR(1, 0));
11 uint32_t ir1, ir2, ir3;
12 cop2_get(9, ir1);
13 cop2_get(10, ir2);
14 cop2_get(11, ir3);
15 cester_assert_uint_eq(0x1000, ir1); // 1.0^2 = 1.0
16 cester_assert_uint_eq(0x0400, ir2); // 0.5^2 = 0.25
17 cester_assert_uint_eq(0x4000, ir3); // 2.0^2 = 4.0 (no saturation, lm=0)
18)
19
20CESTER_TEST(sqr_unshifted, gte_tests,
21 cop2_put(9, 4);
22 cop2_put(10, 5);
23 cop2_put(11, 6);
26 uint32_t ir1, ir2, ir3;
33)
34
35// SQR sets MAC1-3 as well
36CESTER_TEST(sqr_mac_output, gte_tests,
37 cop2_put(9, 100);
38 cop2_put(10, 200);
39 cop2_put(11, 300);
41 cop2_cmd(COP2_SQR(0, 0));
42 int32_t mac1, mac2, mac3;
43 cop2_get(25, mac1);
44 cop2_get(26, mac2);
45 cop2_get(27, mac3);
49)
50
51// SQR with IR saturation (shifted, result > 0x7fff with lm=0)
52CESTER_TEST(sqr_saturation_shifted, gte_tests,
53 cop2_put(9, 0x4000); // 4.0 in 4.12; 4^2 = 16, >>12 = 0x4000 (fits)
54 cop2_put(10, 0x5a82); // ~5.656 (sqrt(32)); 32 >>12 = 0x8000 = saturates
55 cop2_put(11, 0x7fff); // max positive; 0x7fff^2 >>12 = huge, saturates
58 uint32_t ir1, ir2, ir3;
59 uint32_t flag;
60 cop2_get(9, ir1);
61 cop2_get(10, ir2);
62 cop2_get(11, ir3);
63 flag = gte_read_flag();
64 ramsyscall_printf("SQR sat: IR1=0x%04x IR2=0x%04x IR3=0x%04x FLAG=0x%08x\n",
65 ir1 & 0xffff, ir2 & 0xffff, ir3 & 0xffff, flag);
66 cester_assert_uint_eq(0x7fff, ir1 & 0xffff);
67 cester_assert_uint_eq(0x7fff, ir2 & 0xffff);
68 cester_assert_uint_eq(0x7fff, ir3 & 0xffff);
70)
71
72// SQR with negative input (result should still be positive: square)
73CESTER_TEST(sqr_negative_input, gte_tests,
74 cop2_put(9, 0xfffffff6); // -10 (sign-extended)
75 cop2_put(10, 0xffffffce); // -50
76 cop2_put(11, 0xffffff9c); // -100
78 cop2_cmd(COP2_SQR(0, 0));
79 int32_t mac1, mac2, mac3;
80 cop2_get(25, mac1);
81 cop2_get(26, mac2);
82 cop2_get(27, mac3);
83 // Squares of negative numbers are positive
84 // But GTE multiplies IR*IR where IR is 16-bit signed
85 // -10 * -10 = 100, -50 * -50 = 2500, -100 * -100 = 10000
86 ramsyscall_printf("SQR neg: MAC1=%d MAC2=%d MAC3=%d\n", mac1, mac2, mac3);
90)
#define cop2_cmd(op)
Definition cop2.h:175
#define cop2_put(reg, val)
Definition cop2.h:191
#define COP2_SQR(sf, lm)
Definition cop2.h:161
#define cop2_get(reg, dest)
Definition cop2.h:198
int32_t mac1
Definition gte-depthcue.c:118
int32_t mac2
Definition gte-depthcue.c:118
int32_t mac3
Definition gte-depthcue.c:118
cester_assert_uint_eq(16, ir1)
uint32_t ir1
Definition gte-sqr.c:26
uint32_t ir2
Definition gte-sqr.c:26
gte_tests
Definition gte-sqr.c:20
uint32_t flag
Definition gte-sqr.c:59
ramsyscall_printf("SQR sat: IR1=0x%04x IR2=0x%04x IR3=0x%04x FLAG=0x%08x\n", ir1 &0xffff, ir2 &0xffff, ir3 &0xffff, flag)
gte_clear_flag()
CESTER_TEST(sqr_shifted, gte_tests, cop2_put(9, 0x1000);cop2_put(10, 0x0800);cop2_put(11, 0x2000);gte_clear_flag();cop2_cmd(COP2_SQR(1, 0));uint32_t ir1, ir2, ir3;cop2_get(9, ir1);cop2_get(10, ir2);cop2_get(11, ir3);cester_assert_uint_eq(0x1000, ir1);cester_assert_uint_eq(0x0400, ir2);cester_assert_uint_eq(0x4000, ir3);) CESTER_TEST(sqr_unshifted
uint32_t ir3
Definition gte-sqr.c:26
cester_assert_int_eq(3, xaCommand(CDL_SETMODE, &mode, 1, NULL, NULL))