Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
gte-op.c
Go to the documentation of this file.
1// OP: outer product / cross product
2// Uses rotation matrix diagonal (R11, R22, R33) as D vector
3// Result = D x IR
4
5// clang-format off
6
7CESTER_TEST(op_identity_diagonal, gte_tests,
9 cop2_put(9, 1000);
10 cop2_put(10, 2000);
11 cop2_put(11, 3000);
13 cop2_cmd(COP2_OP_CP(1, 0));
14 int32_t ir1, ir2, ir3;
15 cop2_get(9, ir1);
16 cop2_get(10, ir2);
17 cop2_get(11, ir3);
18 // D=(1,1,1), IR=(1000,2000,3000)
19 // cross = (1*3000-1*2000, 1*1000-1*3000, 1*2000-1*1000) = (1000,-2000,1000)
23)
24
25CESTER_TEST(op_unshifted, gte_tests,
27 cop2_put(9, 10);
28 cop2_put(10, 20);
29 cop2_put(11, 30);
31 cop2_cmd(COP2_OP_CP(0, 0)); // sf=0
32 int32_t mac1, mac2, mac3;
36 // sf=0: no shift. D=(0x1000,0x1000,0x1000), IR=(10,20,30)
37 // MAC1 = R22*IR3 - R33*IR2 = 0x1000*30 - 0x1000*20 = 4096*(30-20) = 40960
41)
42
43// OP with asymmetric diagonal
44CESTER_TEST(op_asymmetric, gte_tests,
45 cop2_putc(0, 0x00000800); // R11=0x800 (0.5)
46 cop2_putc(1, 0x00000000);
47 cop2_putc(2, 0x00001000); // R22=0x1000 (1.0)
48 cop2_putc(3, 0x00000000);
49 cop2_putc(4, 0x2000); // R33=0x2000 (2.0)
50 cop2_put(9, 100);
51 cop2_put(10, 200);
52 cop2_put(11, 300);
54 cop2_cmd(COP2_OP_CP(1, 0));
55 int32_t ir1, ir2, ir3;
56 cop2_get(9, ir1);
57 cop2_get(10, ir2);
58 cop2_get(11, ir3);
59 // D=(0.5, 1.0, 2.0), IR=(100,200,300)
60 // cross.x = D.y*IR.z - D.z*IR.y = 1.0*300 - 2.0*200 = 300 - 400 = -100
61 // cross.y = D.z*IR.x - D.x*IR.z = 2.0*100 - 0.5*300 = 200 - 150 = 50
62 // cross.z = D.x*IR.y - D.y*IR.x = 0.5*200 - 1.0*100 = 100 - 100 = 0
66)
67
68// OP with overflow - large values that exceed 44-bit accumulator
69CESTER_TEST(op_overflow_flag, gte_tests,
70 cop2_putc(0, 0x00007fff); // R11=0x7fff
71 cop2_putc(2, 0x00007fff); // R22=0x7fff
72 cop2_putc(4, 0x7fff); // R33=0x7fff
73 cop2_put(9, 0x7fff);
74 cop2_put(10, 0x7fff);
75 cop2_put(11, 0x7fff);
77 cop2_cmd(COP2_OP_CP(0, 0)); // sf=0, no shift -> large products
78 uint32_t flag;
79 flag = gte_read_flag();
80 ramsyscall_printf("OP overflow: FLAG=0x%08x\n", flag);
81 // With sf=0: MAC = 0x7fff*0x7fff - 0x7fff*0x7fff = 0 for all
82 // Actually this produces zero cross product since all components are equal
84)
#define COP2_OP_CP(sf, lm)
Definition cop2.h:136
#define cop2_cmd(op)
Definition cop2.h:175
#define cop2_put(reg, val)
Definition cop2.h:191
#define cop2_putc(reg, val)
Definition cop2.h:205
#define cop2_get(reg, dest)
Definition cop2.h:198
uint32_t ir1
Definition gte-edgecase.c:110
ramsyscall_printf("OP overflow: FLAG=0x%08x\n", flag)
int32_t mac1
Definition gte-op.c:32
gte_set_identity_rotation()
gte_tests
Definition gte-op.c:25
uint32_t flag
Definition gte-op.c:78
cester_assert_uint_eq(0x00000000, flag)
int32_t mac2
Definition gte-op.c:32
cester_assert_int_eq(40960, mac1)
gte_clear_flag()
int32_t mac3
Definition gte-op.c:32
CESTER_TEST(op_identity_diagonal, gte_tests, gte_set_identity_rotation();cop2_put(9, 1000);cop2_put(10, 2000);cop2_put(11, 3000);gte_clear_flag();cop2_cmd(COP2_OP_CP(1, 0));int32_t ir1, ir2, ir3;cop2_get(9, ir1);cop2_get(10, ir2);cop2_get(11, ir3);cester_assert_int_eq(1000, ir1);cester_assert_int_eq(-2000, ir2);cester_assert_int_eq(1000, ir3);) CESTER_TEST(op_unshifted
uint32_t ir3
Definition gte-precision.c:322
uint32_t ir2
Definition gte-sqr.c:26