ChonkyStation/gte.cpp
2022-09-13 19:13:26 +02:00

859 lines
No EOL
36 KiB
C++

#include "gte.h"
void gte::execute(uint32_t instr, uint32_t* gpr) {
instruction = instr;
//printf("0x%x\n", instr & 0x3f);
switch (instr & 0x3f) {
case MOVE: {
switch ((instr >> 21) & 0x1f) {
case MFC2: moveMFC2(gpr); break;
case CFC2: moveCFC2(gpr); break;
case MTC2: moveMTC2(gpr); break;
case CTC2: moveCTC2(gpr); break;
default:
printf("Unimplemented GTE MOVE instruction: 0x%x\n", (instr >> 21) & 0x1f);
exit(1);
}
break;
}
case RTPS: cop2c.raw[31] = 0; commandRTPS(); break;
case NCLIP: cop2c.raw[31] = 0; commandNCLIP(); break;
case OP: cop2c.raw[31] = 0; commandOP(); break;
case DPCS: cop2c.raw[31] = 0; commandDPCS(); break;
case INTPL: cop2c.raw[31] = 0; commandINTPL(); break;
case MVMVA: cop2c.raw[31] = 0; commandMVMVA(); break;
case NCDS: cop2c.raw[31] = 0; commandNCDS(); break;
case NCDT: cop2c.raw[31] = 0; commandNCDT(); break;
case NCCS: cop2c.raw[31] = 0; commandNCCS(); break;
case NCS: cop2c.raw[31] = 0; commandNCS(); break;
case NCT: cop2c.raw[31] = 0; commandNCT(); break;
case SQR: cop2c.raw[31] = 0; commandSQR(); break;
case DPCT: cop2c.raw[31] = 0; commandDPCT(); break;
case AVSZ3: cop2c.raw[31] = 0; commandAVSZ3(); break;
case AVSZ4: cop2c.raw[31] = 0; commandAVSZ4(); break;
case RTPT: cop2c.raw[31] = 0; commandRTPT(); break;
case GPF: cop2c.raw[31] = 0; commandGPF(); break;
case GPL: cop2c.raw[31] = 0; commandGPL(); break;
case NCCT: cop2c.raw[31] = 0; commandNCCT(); break;
default:
printf("Unimplemented GTE instruction: 0x%x\n", instr);
exit(1);
}
}
int16_t gte::mx(int x, int i) {
switch (x) {
case 0: // Rotation matrix
switch (i) {
case 11: return RT11;
case 12: return RT12;
case 13: return RT13;
case 21: return RT21;
case 22: return RT22;
case 23: return RT23;
case 31: return RT31;
case 32: return RT32;
case 33: return RT33;
default:
printf("Bad matrix index (%d)\n", i); exit(0);
}
case 1: // Light matrix
switch (i) {
case 11: return L11;
case 12: return L12;
case 13: return L13;
case 21: return L21;
case 22: return L22;
case 23: return L23;
case 31: return L31;
case 32: return L32;
case 33: return L33;
default:
printf("Bad matrix index (%d)\n", i); exit(0);
}
case 2: // Colour matrix
switch (i) {
case 11: return LR1;
case 12: return LR2;
case 13: return LR3;
case 21: return LG1;
case 22: return LG2;
case 23: return LG3;
case 31: return LB1;
case 32: return LB2;
case 33: return LB3;
default:
printf("Bad matrix index (%d)\n", i); exit(0);
}
default:
printf("Bad mx value (%d)\n", x);
exit(0);
}
}
int16_t gte::vx(int x, int i) {
switch (x) {
case 0:
switch (i) {
case 0: return VX0;
case 1: return VY0;
case 2: return VZ0;
default:
printf("Bad vector index (%d)\n", i);
exit(0);
}
case 1:
switch (i) {
case 0: return VX1;
case 1: return VY1;
case 2: return VZ1;
default:
printf("Bad vector index (%d)\n", i);
exit(0);
}
case 2:
switch (i) {
case 0: return VX2;
case 1: return VY2;
case 2: return VZ2;
default:
printf("Bad vector index (%d)\n", i);
exit(0);
}
case 3:
switch (i) {
case 0: return IR1;
case 1: return IR2;
case 2: return IR3;
default:
printf("Bad vector index (%d)\n", i);
exit(0);
}
default:
printf("Bad vx value (%d)\n", x);
exit(0);
}
}
int64_t gte::tx(int x, int i) {
switch (x) {
case 0:
switch (i) {
case 0: return TRX;
case 1: return TRY;
case 2: return TRZ;
default:
printf("Bad vector index (%d)\n", i);
exit(0);
}
case 1:
switch (i) {
case 0: return RBK;
case 1: return GBK;
case 2: return BBK;
default:
printf("Bad vector index (%d)\n", i);
exit(0);
}
case 3: return 0;
default:
printf("Bad tx value (%d)\n", x);
exit(0);
}
}
// Helpers
uint32_t gte::readCop2d(uint32_t reg) {
switch (reg) {
case 1:
case 3:
case 5:
case 8:
case 9:
case 10:
case 11:
return (int32_t)cop2d.r[reg].sw.l;
case 7:
case 16:
case 17:
case 18:
case 19:
return (uint32_t)cop2d.r[reg].w.l;
case 15: // SXYP returns SXY2
return cop2d.raw[14];
case 29:
return (saturate(IR1 >> 7, 0, 0x1f) << 0) | (saturate(IR2 >> 7, 0, 0x1f) << 5) | (saturate(IR3 >> 7, 0, 0x1f) << 10);
case 31:
return __lzcnt(((int32_t)LZCS < 0) ? ~LZCS : LZCS);
default:
return cop2d.r[reg].d;
}
}
void gte::writeCop2d(uint32_t reg, uint32_t value) {
switch (reg) {
case 0:
case 2:
case 4:
case 6: {
cop2d.raw[reg] = value;
break;
}
case 1:
case 3:
case 5: {
cop2d.raw[reg] = (value);
break;
}
case 15: {
SXY0 = SXY1;
SXY1 = SXY2;
SXY2 = value;
break;
}
case 28: {
cop2d.r[28].d = value;
IR1 = (value & 0x1f) << 7;
IR2 = (value & 0x3e0) << 2;
IR3 = (value & 0x7c00) >> 3;
break;
}
case 30: {
LZCS = value;
break;
}
default:
cop2d.raw[reg] = value;
break;
}
}
void gte::writeCop2c(uint32_t reg, uint32_t value) {
switch (reg) {
case 4:
case 12:
case 20:
case 26:
case 27:
case 29:
case 30:
cop2c.r[reg].d = (int32_t)(int16_t)value;
break;
case 31: cop2c.r[reg].d = value & 0x7ffff000; break;
default:
cop2c.r[reg].d = value;
break;
}
}
// Push a Z value to the Z-coordinate FIFO
void gte::pushZ(uint16_t value) {
SZ0 = SZ1;
SZ1 = SZ2;
SZ2 = SZ3;
SZ3 = value;
}
void gte::pushColour() {
RGB0 = RGB1;
RGB1 = RGB2;
const uint32_t col = (saturate(((int32_t)MAC1 >> 4), 0, 0xff) << 0) | (saturate(((int32_t)MAC2 >> 4), 0, 0xff) << 8) | (saturate(((int32_t)MAC3 >> 4), 0, 0xff) << 16) | (CD2 << 24);
//RGB2 = 0x00345678 | (CD2 << 24);
RGB2 = col;
}
void gte::setIRFromMAC(bool lm) {
IR1 = (int16_t)saturate(MAC1, -0x8000 * (lm ? 0 : 1), 0x7fff);
IR2 = (int16_t)saturate(MAC2, -0x8000 * (lm ? 0 : 1), 0x7fff);
IR3 = (int16_t)saturate(MAC3, -0x8000 * (lm ? 0 : 1), 0x7fff);
}
// Commands
void gte::moveMFC2(uint32_t* gpr) {
gpr[(instruction >> 16) & 0x1f] = readCop2d((instruction >> 11) & 0x1f);
}
void gte::moveMTC2(uint32_t* gpr) {
writeCop2d((instruction >> 11) & 0x1f, gpr[(instruction >> 16) & 0x1f]);
}
void gte::moveCFC2(uint32_t* gpr) {
gpr[(instruction >> 16) & 0x1f] = cop2c.r[(instruction >> 11) & 0x1f].d;
}
void gte::moveCTC2(uint32_t* gpr) {
//printf("ctc2 (cnt%d <- r%d)\n", (instruction >> 11) & 0x1f, (instruction >> 16) & 0x1f);
writeCop2c((instruction >> 11) & 0x1f, gpr[(instruction >> 16) & 0x1f]);
}
void gte::commandRTPS() {
//printf("rtps\n");
const int lm = 0;
const int shift = sf(instruction) * 12;
MAC1 = int64_t(((int64_t)(int32_t)(TRX) * 0x1000) + ((int16_t)RT11 * (int16_t)VX0) + ((int16_t)RT12 * (int16_t)VY0) + ((int16_t)RT13 * (int16_t)VZ0)) >> shift;
MAC2 = int64_t(((int64_t)(int32_t)(TRY) * 0x1000) + ((int16_t)RT21 * (int16_t)VX0) + ((int16_t)RT22 * (int16_t)VY0) + ((int16_t)RT23 * (int16_t)VZ0)) >> shift;
MAC3 = int64_t(((int64_t)(int32_t)(TRZ) * 0x1000) + ((int16_t)RT31 * (int16_t)VX0) + ((int16_t)RT32 * (int16_t)VY0) + ((int16_t)RT33 * (int16_t)VZ0)) >> shift;
setIRFromMAC(lm);
auto newZ = int32_t(MAC3) >> ((1 - sf(instruction)) * 12);
pushZ(newZ);
SXY0 = SXY1;
SXY1 = SXY2;
//uint32_t _proj_factor = (((((uint32_t)(H) * 0x20000) / (uint32_t)(SZ3)) + 1) / 2);
//int32_t _proj_factor = ((H * 0x20000) / (uint16_t)SZ3);
int64_t proj_factor = gte_divide(H, SZ3);
//int64_t proj_factor = (int64_t)(_proj_factor);
int64_t _x = (int64_t)(int16_t)(IR1);
int64_t _y = (int64_t)(int16_t)(IR2);
int32_t x = ((IR1 * proj_factor) + OFX);
int32_t y = ((IR2 * proj_factor) + OFY);
x = saturate((x >> 16), -0x400, 0x3ff);
y = saturate((y >> 16), -0x400, 0x3ff);
SX2 = x;
SY2 = y;
//MAC0 = ((int64_t)(((((uint16_t)(H) * 0x20000) / (uint16_t)(SZ3)) + 1) / 2) * (int64_t)(int16_t)(IR1)) + OFX; SETSX2(((int32_t)(MAC0)) / 0x10000);
//MAC0 = ((int64_t)(((((uint16_t)(H) * 0x20000) / (uint16_t)(SZ3)) + 1) / 2) * (int64_t)(int16_t)(IR2)) + OFY; SETSY2(((int32_t)(MAC0)) / 0x10000);
//MAC0 = ((((((uint16_t)(H) * 0x20000) / (uint16_t)(SZ3)) + 1) / 2) * DQA) + DQB; IR0 =
int64_t depth = ((int64_t)DQB + ((int64_t)DQA * proj_factor));
MAC0 = depth;
IR0 = saturate((depth >> 12), 0, 0x1000);
}
void gte::commandDPCS() {
//printf("DPCS\n");
const int shift = sf(instruction) * 12;
const int lm = this->lm(instruction);
MAC1 = R << 16;
MAC2 = G << 16;
MAC3 = B << 16;
// Interpolate colour
int32_t _MAC1 = MAC1;
int32_t _MAC2 = MAC2;
int32_t _MAC3 = MAC3;
MAC1 = ((((int64_t)RFC << 12) - MAC1) >> shift);
MAC2 = ((((int64_t)GFC << 12) - MAC2) >> shift);
MAC3 = ((((int64_t)BFC << 12) - MAC3) >> shift);
IR1 = saturate(MAC1, -0x8000, 0x7fff);
IR2 = saturate(MAC2, -0x8000, 0x7fff);
IR3 = saturate(MAC3, -0x8000, 0x7fff);
MAC1 = (((int64_t)IR1 * IR0) + _MAC1) >> shift;
MAC2 = (((int64_t)IR2 * IR0) + _MAC2) >> shift;
MAC3 = (((int64_t)IR3 * IR0) + _MAC3) >> shift;
IR1 = (int16_t)saturate(MAC1, -0x8000 * (lm ? 0 : 1), 0x7fff);
IR2 = (int16_t)saturate(MAC2, -0x8000 * (lm ? 0 : 1), 0x7fff);
IR3 = (int16_t)saturate(MAC3, -0x8000 * (lm ? 0 : 1), 0x7fff);
pushColour();
}
void gte::commandINTPL() {
//printf("INTPL\n");
const int shift = sf(instruction) * 12;
const int lm = this->lm(instruction);
MAC1 = (int64_t)IR1 << 12;
MAC2 = (int64_t)IR2 << 12;
MAC3 = (int64_t)IR3 << 12;
// Interpolate colour
int32_t _MAC1 = MAC1;
int32_t _MAC2 = MAC2;
int32_t _MAC3 = MAC3;
MAC1 = ((((int64_t)RFC << 12) - MAC1) >> shift);
MAC2 = ((((int64_t)GFC << 12) - MAC2) >> shift);
MAC3 = ((((int64_t)BFC << 12) - MAC3) >> shift);
IR1 = saturate(MAC1, -0x8000, 0x7fff);
IR2 = saturate(MAC2, -0x8000, 0x7fff);
IR3 = saturate(MAC3, -0x8000, 0x7fff);
MAC1 = (((int64_t)IR1 * IR0) + _MAC1) >> shift;
MAC2 = (((int64_t)IR2 * IR0) + _MAC2) >> shift;
MAC3 = (((int64_t)IR3 * IR0) + _MAC3) >> shift;
IR1 = (int16_t)saturate(MAC1, -0x8000 * (lm ? 0 : 1), 0x7fff);
IR2 = (int16_t)saturate(MAC2, -0x8000 * (lm ? 0 : 1), 0x7fff);
IR3 = (int16_t)saturate(MAC3, -0x8000 * (lm ? 0 : 1), 0x7fff);
pushColour();
}
void gte::commandMVMVA() {
const int lm = this->lm(instruction);
const int shift = sf(instruction) * 12;
const int m = this->m(instruction);
const int v = this->v(instruction);
const int cv = this->cv(instruction);
MAC1 = int64_t((tx(cv, 0) * 0x1000) + (mx(m, 11) * vx(v, 0)) + (mx(m, 12) * vx(v, 1)) + (mx(m, 13) * vx(v, 2))) >> shift;
MAC2 = int64_t((tx(cv, 1) * 0x1000) + (mx(m, 21) * vx(v, 0)) + (mx(m, 22) * vx(v, 1)) + (mx(m, 23) * vx(v, 2))) >> shift;
MAC3 = int64_t((tx(cv, 2) * 0x1000) + (mx(m, 31) * vx(v, 0)) + (mx(m, 32) * vx(v, 1)) + (mx(m, 33) * vx(v, 2))) >> shift;
setIRFromMAC(lm);
}
void gte::commandNCDS() {
//printf("NCDS\n");
const int shift = sf(instruction) * 12;
const int lm = this->lm(instruction);
MAC1 = int32_t((int64_t)((int16_t)L11 * (int16_t)VX0) + (int64_t)((int16_t)L12 * (int16_t)VY0) + (int64_t)((int16_t)L13 * (int16_t)VZ0)) >> shift;
MAC2 = int32_t((int64_t)((int16_t)L21 * (int16_t)VX0) + (int64_t)((int16_t)L22 * (int16_t)VY0) + (int64_t)((int16_t)L23 * (int16_t)VZ0)) >> shift;
MAC3 = int32_t((int64_t)((int16_t)L31 * (int16_t)VX0) + (int64_t)((int16_t)L32 * (int16_t)VY0) + (int64_t)((int16_t)L33 * (int16_t)VZ0)) >> shift;
setIRFromMAC(lm);
MAC1 = int32_t(((int64_t)RBK * 0x1000) + ((int64_t)((int16_t)LR1 * (int16_t)IR1) + (int64_t)((int16_t)LR2 * (int16_t)IR2) + (int64_t)((int16_t)LR3 * (int16_t)IR3))) >> shift;
MAC2 = int32_t(((int64_t)GBK * 0x1000) + ((int64_t)((int16_t)LG1 * (int16_t)IR1) + (int64_t)((int16_t)LG2 * (int16_t)IR2) + (int64_t)((int16_t)LG3 * (int16_t)IR3))) >> shift;
MAC3 = int32_t(((int64_t)BBK * 0x1000) + ((int64_t)((int16_t)LB1 * (int16_t)IR1) + (int64_t)((int16_t)LB2 * (int16_t)IR2) + (int64_t)((int16_t)LB3 * (int16_t)IR3))) >> shift;
setIRFromMAC(lm);
MAC1 = ((int64_t)R * (int16_t)IR1) << 4;
MAC2 = ((int64_t)G * (int16_t)IR2) << 4;
MAC3 = ((int64_t)B * (int16_t)IR3) << 4;
// Interpolate colour
uint32_t _MAC1 = MAC1;
uint32_t _MAC2 = MAC2;
uint32_t _MAC3 = MAC3;
MAC1 = (int32_t)((((int64_t)RFC << 12) - (int32_t)MAC1) >> shift);
MAC2 = (int32_t)((((int64_t)GFC << 12) - (int32_t)MAC2) >> shift);
MAC3 = (int32_t)((((int64_t)BFC << 12) - (int32_t)MAC3) >> shift);
setIRFromMAC(0);
MAC1 = (int32_t)(((int64_t)IR1 * IR0) + (int32_t)_MAC1) >> shift;
MAC2 = (int32_t)(((int64_t)IR2 * IR0) + (int32_t)_MAC2) >> shift;
MAC3 = (int32_t)(((int64_t)IR3 * IR0) + (int32_t)_MAC3) >> shift;
setIRFromMAC(lm);
pushColour();
}
void gte::commandNCDT() {
//printf("NCDT\n");
const int shift = sf(instruction) * 12;
const int lm = this->lm(instruction);
MAC1 = int32_t((int64_t)((int16_t)L11 * (int16_t)VX0) + (int64_t)((int16_t)L12 * (int16_t)VY0) + (int64_t)((int16_t)L13 * (int16_t)VZ0)) >> shift;
MAC2 = int32_t((int64_t)((int16_t)L21 * (int16_t)VX0) + (int64_t)((int16_t)L22 * (int16_t)VY0) + (int64_t)((int16_t)L23 * (int16_t)VZ0)) >> shift;
MAC3 = int32_t((int64_t)((int16_t)L31 * (int16_t)VX0) + (int64_t)((int16_t)L32 * (int16_t)VY0) + (int64_t)((int16_t)L33 * (int16_t)VZ0)) >> shift;
setIRFromMAC(lm);
MAC1 = int32_t(((int64_t)RBK * 0x1000) + ((int64_t)((int16_t)LR1 * (int16_t)IR1) + (int64_t)((int16_t)LR2 * (int16_t)IR2) + (int64_t)((int16_t)LR3 * (int16_t)IR3))) >> shift;
MAC2 = int32_t(((int64_t)GBK * 0x1000) + ((int64_t)((int16_t)LG1 * (int16_t)IR1) + (int64_t)((int16_t)LG2 * (int16_t)IR2) + (int64_t)((int16_t)LG3 * (int16_t)IR3))) >> shift;
MAC3 = int32_t(((int64_t)BBK * 0x1000) + ((int64_t)((int16_t)LB1 * (int16_t)IR1) + (int64_t)((int16_t)LB2 * (int16_t)IR2) + (int64_t)((int16_t)LB3 * (int16_t)IR3))) >> shift;
setIRFromMAC(lm);
MAC1 = ((int64_t)R * (int16_t)IR1) << 4;
MAC2 = ((int64_t)G * (int16_t)IR2) << 4;
MAC3 = ((int64_t)B * (int16_t)IR3) << 4;
// Interpolate colour
uint32_t _MAC1 = MAC1;
uint32_t _MAC2 = MAC2;
uint32_t _MAC3 = MAC3;
MAC1 = (int32_t)((((int64_t)RFC << 12) - (int32_t)MAC1) >> shift);
MAC2 = (int32_t)((((int64_t)GFC << 12) - (int32_t)MAC2) >> shift);
MAC3 = (int32_t)((((int64_t)BFC << 12) - (int32_t)MAC3) >> shift);
setIRFromMAC(0);
MAC1 = (int32_t)(((int64_t)IR1 * IR0) + (int32_t)_MAC1) >> shift;
MAC2 = (int32_t)(((int64_t)IR2 * IR0) + (int32_t)_MAC2) >> shift;
MAC3 = (int32_t)(((int64_t)IR3 * IR0) + (int32_t)_MAC3) >> shift;
setIRFromMAC(lm);
pushColour();
MAC1 = int32_t((int64_t)((int16_t)L11 * (int16_t)VX1) + (int64_t)((int16_t)L12 * (int16_t)VY1) + (int64_t)((int16_t)L13 * (int16_t)VZ1)) >> shift;
MAC2 = int32_t((int64_t)((int16_t)L21 * (int16_t)VX1) + (int64_t)((int16_t)L22 * (int16_t)VY1) + (int64_t)((int16_t)L23 * (int16_t)VZ1)) >> shift;
MAC3 = int32_t((int64_t)((int16_t)L31 * (int16_t)VX1) + (int64_t)((int16_t)L32 * (int16_t)VY1) + (int64_t)((int16_t)L33 * (int16_t)VZ1)) >> shift;
setIRFromMAC(lm);
MAC1 = int32_t(((int64_t)RBK * 0x1000) + ((int64_t)((int16_t)LR1 * (int16_t)IR1) + (int64_t)((int16_t)LR2 * (int16_t)IR2) + (int64_t)((int16_t)LR3 * (int16_t)IR3))) >> shift;
MAC2 = int32_t(((int64_t)GBK * 0x1000) + ((int64_t)((int16_t)LG1 * (int16_t)IR1) + (int64_t)((int16_t)LG2 * (int16_t)IR2) + (int64_t)((int16_t)LG3 * (int16_t)IR3))) >> shift;
MAC3 = int32_t(((int64_t)BBK * 0x1000) + ((int64_t)((int16_t)LB1 * (int16_t)IR1) + (int64_t)((int16_t)LB2 * (int16_t)IR2) + (int64_t)((int16_t)LB3 * (int16_t)IR3))) >> shift;
setIRFromMAC(lm);
MAC1 = ((int64_t)R * (int16_t)IR1) << 4;
MAC2 = ((int64_t)G * (int16_t)IR2) << 4;
MAC3 = ((int64_t)B * (int16_t)IR3) << 4;
// Interpolate colour
_MAC1 = MAC1;
_MAC2 = MAC2;
_MAC3 = MAC3;
MAC1 = (int32_t)((((int64_t)RFC << 12) - (int32_t)MAC1) >> shift);
MAC2 = (int32_t)((((int64_t)GFC << 12) - (int32_t)MAC2) >> shift);
MAC3 = (int32_t)((((int64_t)BFC << 12) - (int32_t)MAC3) >> shift);
setIRFromMAC(0);
MAC1 = (int32_t)(((int64_t)IR1 * IR0) + (int32_t)_MAC1) >> shift;
MAC2 = (int32_t)(((int64_t)IR2 * IR0) + (int32_t)_MAC2) >> shift;
MAC3 = (int32_t)(((int64_t)IR3 * IR0) + (int32_t)_MAC3) >> shift;
setIRFromMAC(lm);
pushColour();
MAC1 = int32_t((int64_t)((int16_t)L11 * (int16_t)VX2) + (int64_t)((int16_t)L12 * (int16_t)VY2) + (int64_t)((int16_t)L13 * (int16_t)VZ2)) >> shift;
MAC2 = int32_t((int64_t)((int16_t)L21 * (int16_t)VX2) + (int64_t)((int16_t)L22 * (int16_t)VY2) + (int64_t)((int16_t)L23 * (int16_t)VZ2)) >> shift;
MAC3 = int32_t((int64_t)((int16_t)L31 * (int16_t)VX2) + (int64_t)((int16_t)L32 * (int16_t)VY2) + (int64_t)((int16_t)L33 * (int16_t)VZ2)) >> shift;
setIRFromMAC(lm);
MAC1 = int32_t(((int64_t)RBK * 0x1000) + ((int64_t)((int16_t)LR1 * (int16_t)IR1) + (int64_t)((int16_t)LR2 * (int16_t)IR2) + (int64_t)((int16_t)LR3 * (int16_t)IR3))) >> shift;
MAC2 = int32_t(((int64_t)GBK * 0x1000) + ((int64_t)((int16_t)LG1 * (int16_t)IR1) + (int64_t)((int16_t)LG2 * (int16_t)IR2) + (int64_t)((int16_t)LG3 * (int16_t)IR3))) >> shift;
MAC3 = int32_t(((int64_t)BBK * 0x1000) + ((int64_t)((int16_t)LB1 * (int16_t)IR1) + (int64_t)((int16_t)LB2 * (int16_t)IR2) + (int64_t)((int16_t)LB3 * (int16_t)IR3))) >> shift;
setIRFromMAC(lm);
MAC1 = ((int64_t)R * (int16_t)IR1) << 4;
MAC2 = ((int64_t)G * (int16_t)IR2) << 4;
MAC3 = ((int64_t)B * (int16_t)IR3) << 4;
// Interpolate colour
_MAC1 = MAC1;
_MAC2 = MAC2;
_MAC3 = MAC3;
MAC1 = (int32_t)((((int64_t)RFC << 12) - (int32_t)MAC1) >> shift);
MAC2 = (int32_t)((((int64_t)GFC << 12) - (int32_t)MAC2) >> shift);
MAC3 = (int32_t)((((int64_t)BFC << 12) - (int32_t)MAC3) >> shift);
setIRFromMAC(0);
MAC1 = (int32_t)(((int64_t)IR1 * IR0) + (int32_t)_MAC1) >> shift;
MAC2 = (int32_t)(((int64_t)IR2 * IR0) + (int32_t)_MAC2) >> shift;
MAC3 = (int32_t)(((int64_t)IR3 * IR0) + (int32_t)_MAC3) >> shift;
setIRFromMAC(lm);
pushColour();
}
void gte::commandNCCS() {
const int shift = sf(instruction) * 12;
const int lm = this->lm(instruction);
MAC1 = int32_t((int64_t)((int16_t)L11 * (int16_t)VX0) + (int64_t)((int16_t)L12 * (int16_t)VY0) + (int64_t)((int16_t)L13 * (int16_t)VZ0)) >> shift;
MAC2 = int32_t((int64_t)((int16_t)L21 * (int16_t)VX0) + (int64_t)((int16_t)L22 * (int16_t)VY0) + (int64_t)((int16_t)L23 * (int16_t)VZ0)) >> shift;
MAC3 = int32_t((int64_t)((int16_t)L31 * (int16_t)VX0) + (int64_t)((int16_t)L32 * (int16_t)VY0) + (int64_t)((int16_t)L33 * (int16_t)VZ0)) >> shift;
setIRFromMAC(lm);
MAC1 = int32_t(((int64_t)RBK * 0x1000) + ((int64_t)((int16_t)LR1 * (int16_t)IR1) + (int64_t)((int16_t)LR2 * (int16_t)IR2) + (int64_t)((int16_t)LR3 * (int16_t)IR3))) >> shift;
MAC2 = int32_t(((int64_t)GBK * 0x1000) + ((int64_t)((int16_t)LG1 * (int16_t)IR1) + (int64_t)((int16_t)LG2 * (int16_t)IR2) + (int64_t)((int16_t)LG3 * (int16_t)IR3))) >> shift;
MAC3 = int32_t(((int64_t)BBK * 0x1000) + ((int64_t)((int16_t)LB1 * (int16_t)IR1) + (int64_t)((int16_t)LB2 * (int16_t)IR2) + (int64_t)((int16_t)LB3 * (int16_t)IR3))) >> shift;
setIRFromMAC(lm);
MAC1 = ((int64_t)R * (int16_t)IR1) << 4;
MAC2 = ((int64_t)G * (int16_t)IR2) << 4;
MAC3 = ((int64_t)B * (int16_t)IR3) << 4;
MAC1 = (int32_t)MAC1 >> shift;
MAC2 = (int32_t)MAC2 >> shift;
MAC3 = (int32_t)MAC3 >> shift;
setIRFromMAC(lm);
pushColour();
}
void gte::commandNCS() {
//printf("ncs\n");
const int shift = sf(instruction) * 12;
const int lm = this->lm(instruction);
MAC1 = (int64_t)(L11 * VX0 + L12 * VY0 + L13 * VZ0) >> shift;
MAC1 = (int64_t)(L21 * VX0 + L22 * VY0 + L23 * VZ0) >> shift;
MAC1 = (int64_t)(L31 * VX0 + L32 * VY0 + L33 * VZ0) >> shift;
//MAC1 = int32_t((int64_t)((int16_t)L11 * (int16_t)VX0) + (int64_t)((int16_t)L12 * (int16_t)VY0) + (int64_t)((int16_t)L13 * (int16_t)VZ0)) >> shift;
//MAC2 = int32_t((int64_t)((int16_t)L21 * (int16_t)VX0) + (int64_t)((int16_t)L22 * (int16_t)VY0) + (int64_t)((int16_t)L23 * (int16_t)VZ0)) >> shift;
//MAC3 = int32_t((int64_t)((int16_t)L31 * (int16_t)VX0) + (int64_t)((int16_t)L32 * (int16_t)VY0) + (int64_t)((int16_t)L33 * (int16_t)VZ0)) >> shift;
setIRFromMAC(lm);
MAC1 = (int64_t)((((int64_t)(RBK * 0x1000 + LR1 * IR1)) + (int64_t)(LR2 * IR2)) + (int64_t)(LR3 * IR3)) >> shift;
MAC2 = (int64_t)((((int64_t)(GBK * 0x1000 + LG1 * IR1)) + (int64_t)(LG2 * IR2)) + (int64_t)(LG3 * IR3)) >> shift;
MAC3 = (int64_t)((((int64_t)(BBK * 0x1000 + LB1 * IR1)) + (int64_t)(LB2 * IR2)) + (int64_t)(LB3 * IR3)) >> shift;
//MAC1 = int32_t(((int64_t)RBK * 0x1000) + ((int64_t)((int16_t)LR1 * (int16_t)IR1) + (int64_t)((int16_t)LR2 * (int16_t)IR2) + (int64_t)((int16_t)LR3 * (int16_t)IR3))) >> shift;
//MAC2 = int32_t(((int64_t)GBK * 0x1000) + ((int64_t)((int16_t)LG1 * (int16_t)IR1) + (int64_t)((int16_t)LG2 * (int16_t)IR2) + (int64_t)((int16_t)LG3 * (int16_t)IR3))) >> shift;
//MAC3 = int32_t(((int64_t)BBK * 0x1000) + ((int64_t)((int16_t)LB1 * (int16_t)IR1) + (int64_t)((int16_t)LB2 * (int16_t)IR2) + (int64_t)((int16_t)LB3 * (int16_t)IR3))) >> shift;
setIRFromMAC(lm);
pushColour();
}
void gte::commandNCT() {
//printf("nct\n");
const int shift = sf(instruction) * 12;
const int lm = this->lm(instruction);
//MAC1 = (int64_t)(L11 * VX0 + L12 * VY0 + L13 * VZ0) >> shift;
//MAC1 = (int64_t)(L21 * VX0 + L22 * VY0 + L23 * VZ0) >> shift;
//MAC1 = (int64_t)(L31 * VX0 + L32 * VY0 + L33 * VZ0) >> shift;
MAC1 = int32_t((int64_t)((int16_t)L11 * (int16_t)VX0) + (int64_t)((int16_t)L12 * (int16_t)VY0) + (int64_t)((int16_t)L13 * (int16_t)VZ0)) >> shift;
MAC2 = int32_t((int64_t)((int16_t)L21 * (int16_t)VX0) + (int64_t)((int16_t)L22 * (int16_t)VY0) + (int64_t)((int16_t)L23 * (int16_t)VZ0)) >> shift;
MAC3 = int32_t((int64_t)((int16_t)L31 * (int16_t)VX0) + (int64_t)((int16_t)L32 * (int16_t)VY0) + (int64_t)((int16_t)L33 * (int16_t)VZ0)) >> shift;
setIRFromMAC(lm);
//MAC1 = (int64_t)((((int64_t)(RBK * 0x1000 + LR1 * IR1)) + (int64_t)(LR2 * IR2)) + (int64_t)(LR3 * IR3)) >> shift;
//MAC2 = (int64_t)((((int64_t)(GBK * 0x1000 + LG1 * IR1)) + (int64_t)(LG2 * IR2)) + (int64_t)(LG3 * IR3)) >> shift;
//MAC3 = (int64_t)((((int64_t)(BBK * 0x1000 + LB1 * IR1)) + (int64_t)(LB2 * IR2)) + (int64_t)(LB3 * IR3)) >> shift;
MAC1 = int32_t(((int64_t)RBK * 0x1000) + ((int64_t)((int16_t)LR1 * (int16_t)IR1) + (int64_t)((int16_t)LR2 * (int16_t)IR2) + (int64_t)((int16_t)LR3 * (int16_t)IR3))) >> shift;
MAC2 = int32_t(((int64_t)GBK * 0x1000) + ((int64_t)((int16_t)LG1 * (int16_t)IR1) + (int64_t)((int16_t)LG2 * (int16_t)IR2) + (int64_t)((int16_t)LG3 * (int16_t)IR3))) >> shift;
MAC3 = int32_t(((int64_t)BBK * 0x1000) + ((int64_t)((int16_t)LB1 * (int16_t)IR1) + (int64_t)((int16_t)LB2 * (int16_t)IR2) + (int64_t)((int16_t)LB3 * (int16_t)IR3))) >> shift;
setIRFromMAC(lm);
pushColour();
//MAC1 = (int64_t)(L11 * VX0 + L12 * VY0 + L13 * VZ0) >> shift;
//MAC1 = (int64_t)(L21 * VX0 + L22 * VY0 + L23 * VZ0) >> shift;
//MAC1 = (int64_t)(L31 * VX0 + L32 * VY0 + L33 * VZ0) >> shift;
MAC1 = int32_t((int64_t)((int16_t)L11 * (int16_t)VX1) + (int64_t)((int16_t)L12 * (int16_t)VY1) + (int64_t)((int16_t)L13 * (int16_t)VZ1)) >> shift;
MAC2 = int32_t((int64_t)((int16_t)L21 * (int16_t)VX1) + (int64_t)((int16_t)L22 * (int16_t)VY1) + (int64_t)((int16_t)L23 * (int16_t)VZ1)) >> shift;
MAC3 = int32_t((int64_t)((int16_t)L31 * (int16_t)VX1) + (int64_t)((int16_t)L32 * (int16_t)VY1) + (int64_t)((int16_t)L33 * (int16_t)VZ1)) >> shift;
setIRFromMAC(lm);
//MAC1 = (int64_t)((((int64_t)(RBK * 0x1000 + LR1 * IR1)) + (int64_t)(LR2 * IR2)) + (int64_t)(LR3 * IR3)) >> shift;
//MAC2 = (int64_t)((((int64_t)(GBK * 0x1000 + LG1 * IR1)) + (int64_t)(LG2 * IR2)) + (int64_t)(LG3 * IR3)) >> shift;
//MAC3 = (int64_t)((((int64_t)(BBK * 0x1000 + LB1 * IR1)) + (int64_t)(LB2 * IR2)) + (int64_t)(LB3 * IR3)) >> shift;
MAC1 = int32_t(((int64_t)RBK * 0x1000) + ((int64_t)((int16_t)LR1 * (int16_t)IR1) + (int64_t)((int16_t)LR2 * (int16_t)IR2) + (int64_t)((int16_t)LR3 * (int16_t)IR3))) >> shift;
MAC2 = int32_t(((int64_t)GBK * 0x1000) + ((int64_t)((int16_t)LG1 * (int16_t)IR1) + (int64_t)((int16_t)LG2 * (int16_t)IR2) + (int64_t)((int16_t)LG3 * (int16_t)IR3))) >> shift;
MAC3 = int32_t(((int64_t)BBK * 0x1000) + ((int64_t)((int16_t)LB1 * (int16_t)IR1) + (int64_t)((int16_t)LB2 * (int16_t)IR2) + (int64_t)((int16_t)LB3 * (int16_t)IR3))) >> shift;
setIRFromMAC(lm);
pushColour();
//MAC1 = (int64_t)(L11 * VX0 + L12 * VY0 + L13 * VZ0) >> shift;
//MAC1 = (int64_t)(L21 * VX0 + L22 * VY0 + L23 * VZ0) >> shift;
//MAC1 = (int64_t)(L31 * VX0 + L32 * VY0 + L33 * VZ0) >> shift;
MAC1 = int32_t((int64_t)((int16_t)L11 * (int16_t)VX2) + (int64_t)((int16_t)L12 * (int16_t)VY2) + (int64_t)((int16_t)L13 * (int16_t)VZ2)) >> shift;
MAC2 = int32_t((int64_t)((int16_t)L21 * (int16_t)VX2) + (int64_t)((int16_t)L22 * (int16_t)VY2) + (int64_t)((int16_t)L23 * (int16_t)VZ2)) >> shift;
MAC3 = int32_t((int64_t)((int16_t)L31 * (int16_t)VX2) + (int64_t)((int16_t)L32 * (int16_t)VY2) + (int64_t)((int16_t)L33 * (int16_t)VZ2)) >> shift;
setIRFromMAC(lm);
//MAC1 = (int64_t)((((int64_t)(RBK * 0x1000 + LR1 * IR1)) + (int64_t)(LR2 * IR2)) + (int64_t)(LR3 * IR3)) >> shift;
//MAC2 = (int64_t)((((int64_t)(GBK * 0x1000 + LG1 * IR1)) + (int64_t)(LG2 * IR2)) + (int64_t)(LG3 * IR3)) >> shift;
//MAC3 = (int64_t)((((int64_t)(BBK * 0x1000 + LB1 * IR1)) + (int64_t)(LB2 * IR2)) + (int64_t)(LB3 * IR3)) >> shift;
MAC1 = int32_t(((int64_t)RBK * 0x1000) + ((int64_t)((int16_t)LR1 * (int16_t)IR1) + (int64_t)((int16_t)LR2 * (int16_t)IR2) + (int64_t)((int16_t)LR3 * (int16_t)IR3))) >> shift;
MAC2 = int32_t(((int64_t)GBK * 0x1000) + ((int64_t)((int16_t)LG1 * (int16_t)IR1) + (int64_t)((int16_t)LG2 * (int16_t)IR2) + (int64_t)((int16_t)LG3 * (int16_t)IR3))) >> shift;
MAC3 = int32_t(((int64_t)BBK * 0x1000) + ((int64_t)((int16_t)LB1 * (int16_t)IR1) + (int64_t)((int16_t)LB2 * (int16_t)IR2) + (int64_t)((int16_t)LB3 * (int16_t)IR3))) >> shift;
setIRFromMAC(lm);
pushColour();
}
void gte::commandSQR() {
//printf("SQR\n");
const int shift = sf(instruction) * 12;
MAC1 = (IR1 * IR1) >> shift;
MAC2 = (IR2 * IR2) >> shift;
MAC3 = (IR3 * IR3) >> shift;
IR1 = saturate(MAC1, 0, 0x7fff);
IR2 = saturate(MAC2, 0, 0x7fff);
IR3 = saturate(MAC3, 0, 0x7fff);
}
void gte::commandDPCT() {
//printf("DPCT\n");
const int shift = sf(instruction) * 12;
const int lm = this->lm(instruction);
for (int i = 0; i < 3; i++) {
MAC1 = R0 << 16;
MAC2 = G0 << 16;
MAC3 = B0 << 16;
// Interpolate colour
int32_t _MAC1 = MAC1;
int32_t _MAC2 = MAC2;
int32_t _MAC3 = MAC3;
MAC1 = ((((int64_t)RFC << 12) - MAC1) >> shift);
MAC2 = ((((int64_t)GFC << 12) - MAC2) >> shift);
MAC3 = ((((int64_t)BFC << 12) - MAC3) >> shift);
setIRFromMAC(0);
MAC1 = (((int64_t)IR1 * IR0) + _MAC1) >> shift;
MAC2 = (((int64_t)IR2 * IR0) + _MAC2) >> shift;
MAC3 = (((int64_t)IR3 * IR0) + _MAC3) >> shift;
setIRFromMAC(lm);
pushColour();
}
}
void gte::commandNCLIP() {
//printf("nclip\n");
MAC0 = (int64_t)((int32_t)(SX0) * (int32_t)(SY1)) + ((int32_t)(SX1) * (int32_t)(SY2)) + ((int32_t)(SX2) * (int32_t)(SY0)) - ((int32_t)(SX0) * (int32_t)(SY2)) - ((int32_t)(SX1) * (int32_t)(SY0)) - ((int32_t)(SX2) * (int32_t)(SY1));
//MAC0 = ((int64_t)(SX0 * SY1) + (SX1 * SY2) + (SX2 * SY0) - (SX0 * SY2) - (SX1 * SY0) - (SX2 * SY1));
//printf("sx0: %d, sy0: %d sx1: %d, sy1: %d sx2: %d, sy2: %d\n", SX0, SY0, SX1, SY1, SX2, SY2);
//auto a = (int32_t)(SX0) * ((int32_t)(SY1) - (int32_t)(SY2));
//auto b = (int32_t)(SX1) * ((int32_t)(SY2) - (int32_t)(SY0));
//auto c = (int32_t)(SX2) * ((int32_t)(SY0) - (int32_t)(SY1));
//MAC0 = (int32_t)(a + b + c);
//MAC0 = 0x1500000;
//printf("%d\n", MAC0);
}
void gte::commandOP() {
//printf("OP\n");
const int shift = sf(instruction) * 12;
const int lm = this->lm(instruction);
MAC1 = (int64_t)((RT22 * IR3) - (RT33 * IR2));
MAC2 = (int64_t)((RT33 * IR1) - (RT11 * IR3));
MAC3 = (int64_t)((RT11 * IR2) - (RT22 * IR1));
MAC1 = (int64_t)MAC1 >> shift;
MAC2 = (int64_t)MAC2 >> shift;
MAC3 = (int64_t)MAC3 >> shift;
setIRFromMAC(lm);
}
void gte::commandAVSZ3() {
//printf("avsz3\n");
MAC0 = (int64_t)ZSF3 * ((uint16_t)SZ1 + (uint16_t)SZ2 + (uint16_t)SZ3);
//MAC0 = 0x10000;
//MAC0 = ((int64_t)(ZSF3 * SZ1) + (ZSF3 * SZ2) + (ZSF3 * SZ3));
OTZ = saturate((int32_t)MAC0 / 0x1000, 0, 0xffff);
}
void gte::commandAVSZ4() {
//printf("avsz4\n");
MAC0 = (int64_t)ZSF4 * ((uint16_t)SZ0 + (uint16_t)SZ1 + (uint16_t)SZ2 + (uint16_t)SZ3);
OTZ = saturate((int32_t)MAC0 / 0x1000, 0, 0xffff);
}
void gte::commandRTPT() {
//printf("rtpt\n");
const int shift = sf(instruction) * 12;
const int lm = 0;
MAC1 = int64_t(((int64_t)(int32_t)(TRX) * 0x1000) + ((int16_t)RT11 * (int16_t)VX0) + ((int16_t)RT12 * (int16_t)VY0) + ((int16_t)RT13 * (int16_t)VZ0)) >> shift;
MAC2 = int64_t(((int64_t)(int32_t)(TRY) * 0x1000) + ((int16_t)RT21 * (int16_t)VX0) + ((int16_t)RT22 * (int16_t)VY0) + ((int16_t)RT23 * (int16_t)VZ0)) >> shift;
MAC3 = int64_t(((int64_t)(int32_t)(TRZ) * 0x1000) + ((int16_t)RT31 * (int16_t)VX0) + ((int16_t)RT32 * (int16_t)VY0) + ((int16_t)RT33 * (int16_t)VZ0)) >> shift;
setIRFromMAC(lm);
auto newZ = int32_t(MAC3) >> ((1 - sf(instruction)) * 12);
pushZ(newZ);
SXY0 = SXY1;
SXY1 = SXY2;
//uint32_t _proj_factor = (((((uint32_t)(H) * 0x20000) / (uint32_t)(SZ3)) + 1) / 2);
//int32_t _proj_factor = ((H * 0x20000) / (uint16_t)SZ3);
int32_t proj_factor = gte_divide(H, SZ3);
//int64_t proj_factor = (int64_t)(_proj_factor);
int64_t _x = (int64_t)(int16_t)(IR1);
int64_t _y = (int64_t)(int16_t)(IR2);
int32_t x = ((IR1 * proj_factor) + OFX);
int32_t y = ((IR2 * proj_factor) + OFY);
x = saturate((x >> 16), -0x400, 0x3ff);
y = saturate((y >> 16), -0x400, 0x3ff);
SX2 = x;
SY2 = y;
//MAC0 = ((int64_t)(((((uint16_t)(H) * 0x20000) / (uint16_t)(SZ3)) + 1) / 2) * (int64_t)(int16_t)(IR1)) + OFX; SETSX2(((int32_t)(MAC0)) / 0x10000);
//MAC0 = ((int64_t)(((((uint16_t)(H) * 0x20000) / (uint16_t)(SZ3)) + 1) / 2) * (int64_t)(int16_t)(IR2)) + OFY; SETSY2(((int32_t)(MAC0)) / 0x10000);
//MAC0 = ((((((uint16_t)(H) * 0x20000) / (uint16_t)(SZ3)) + 1) / 2) * DQA) + DQB; IR0 =
/*int64_t depth = ((int64_t)DQB + ((int64_t)DQA * proj_factor));
MAC0 = (int32_t)(depth);
depth >>= 12;
IR0 = (int16_t)(depth);*/
MAC1 = int64_t(((int64_t)(int32_t)(TRX) * 0x1000) + ((int16_t)RT11 * (int16_t)VX1) + ((int16_t)RT12 * (int16_t)VY1) + ((int16_t)RT13 * (int16_t)VZ1)) >> shift;
MAC2 = int64_t(((int64_t)(int32_t)(TRY) * 0x1000) + ((int16_t)RT21 * (int16_t)VX1) + ((int16_t)RT22 * (int16_t)VY1) + ((int16_t)RT23 * (int16_t)VZ1)) >> shift;
MAC3 = int64_t(((int64_t)(int32_t)(TRZ) * 0x1000) + ((int16_t)RT31 * (int16_t)VX1) + ((int16_t)RT32 * (int16_t)VY1) + ((int16_t)RT33 * (int16_t)VZ1)) >> shift;
setIRFromMAC(lm);
newZ = int32_t(MAC3) >> ((1 - sf(instruction)) * 12);
pushZ(newZ);
SXY0 = SXY1;
SXY1 = SXY2;
//_proj_factor = (((((uint32_t)(H) * 0x20000) / (uint32_t)(SZ3)) + 1) / 2);
//_proj_factor = ((H * 0x20000) / (uint16_t)SZ3);
proj_factor = gte_divide(H, SZ3);
//proj_factor = (int64_t)(_proj_factor);
_x = (int64_t)(int16_t)(IR1);
_y = (int64_t)(int16_t)(IR2);
x = ((IR1 * proj_factor) + OFX);
y = ((IR2 * proj_factor) + OFY);
x = saturate((x >> 16), -0x400, 0x3ff);
y = saturate((y >> 16), -0x400, 0x3ff);
SX2 = x;
SY2 = y;
//MAC0 = ((int64_t)(((((uint16_t)(H) * 0x20000) / (uint16_t)(SZ3)) + 1) / 2) * (int64_t)(int16_t)(IR1)) + OFX; SETSX2(((int32_t)(MAC0)) / 0x10000);
//MAC0 = ((int64_t)(((((uint16_t)(H) * 0x20000) / (uint16_t)(SZ3)) + 1) / 2) * (int64_t)(int16_t)(IR2)) + OFY; SETSY2(((int32_t)(MAC0)) / 0x10000);
//MAC0 = ((((((uint16_t)(H) * 0x20000) / (uint16_t)(SZ3)) + 1) / 2) * DQA) + DQB; IR0 =
/*depth = ((int64_t)DQB + ((int64_t)DQA * proj_factor));
MAC0 = (int32_t)(depth);
depth >>= 12;
IR0 = (int16_t)(depth);*/
MAC1 = int64_t(((int64_t)(int32_t)(TRX) * 0x1000) + ((int16_t)RT11 * (int16_t)VX2) + ((int16_t)RT12 * (int16_t)VY2) + ((int16_t)RT13 * (int16_t)VZ2)) >> shift;
MAC2 = int64_t(((int64_t)(int32_t)(TRY) * 0x1000) + ((int16_t)RT21 * (int16_t)VX2) + ((int16_t)RT22 * (int16_t)VY2) + ((int16_t)RT23 * (int16_t)VZ2)) >> shift;
MAC3 = int64_t(((int64_t)(int32_t)(TRZ) * 0x1000) + ((int16_t)RT31 * (int16_t)VX2) + ((int16_t)RT32 * (int16_t)VY2) + ((int16_t)RT33 * (int16_t)VZ2)) >> shift;
setIRFromMAC(lm);
newZ = int32_t(MAC3) >> ((1 - sf(instruction)) * 12);
pushZ(newZ);
SXY0 = SXY1;
SXY1 = SXY2;
//_proj_factor = (((((uint32_t)(H) * 0x20000) / (uint32_t)(SZ3)) + 1) / 2);
//_proj_factor = ((H * 0x20000) / (uint16_t)SZ3);
proj_factor = gte_divide(H, SZ3);
//proj_factor = (int64_t)(_proj_factor);
_x = (int64_t)(int16_t)(IR1);
_y = (int64_t)(int16_t)(IR2);
x = ((IR1 * proj_factor) + OFX);
y = ((IR2 * proj_factor) + OFY);
x = saturate((x >> 16), -0x400, 0x3ff);
y = saturate((y >> 16), -0x400, 0x3ff);
SX2 = x;
SY2 = y;
//MAC0 = ((int64_t)(((((uint16_t)(H) * 0x20000) / (uint16_t)(SZ3)) + 1) / 2) * (int64_t)(int16_t)(IR1)) + OFX; SETSX2(((int32_t)(MAC0)) / 0x10000);
//MAC0 = ((int64_t)(((((uint16_t)(H) * 0x20000) / (uint16_t)(SZ3)) + 1) / 2) * (int64_t)(int16_t)(IR2)) + OFY; SETSY2(((int32_t)(MAC0)) / 0x10000);
//MAC0 = ((((((uint16_t)(H) * 0x20000) / (uint16_t)(SZ3)) + 1) / 2) * DQA) + DQB; IR0 =
int64_t depth = ((int64_t)DQB + ((int64_t)DQA * proj_factor));
MAC0 = depth;
IR0 = saturate((depth >> 12), 0, 0x1000);
}
void gte::commandGPF() {
//printf("GPF\n");
const int shift = sf(instruction) * 12;
const int lm = this->lm(instruction);
MAC1 = (int32_t)(IR1 * IR0) >> shift;
MAC2 = (int32_t)(IR2 * IR0) >> shift;
MAC3 = (int32_t)(IR3 * IR0) >> shift;
setIRFromMAC(lm);
pushColour();
}
void gte::commandGPL() {
//printf("GPL\n");
const int shift = sf(instruction) * 12;
const int lm = this->lm(instruction);
MAC1 <<= shift;
MAC2 <<= shift;
MAC3 <<= shift;
MAC1 = (int32_t)((IR1 * IR0) + MAC1) >> shift;
MAC2 = (int32_t)((IR2 * IR0) + MAC2) >> shift;
MAC3 = (int32_t)((IR3 * IR0) + MAC3) >> shift;
setIRFromMAC(lm);
pushColour();
}
void gte::commandNCCT() {
const int shift = sf(instruction) * 12;
const int lm = this->lm(instruction);
MAC1 = int32_t((int64_t)((int16_t)L11 * (int16_t)VX0) + (int64_t)((int16_t)L12 * (int16_t)VY0) + (int64_t)((int16_t)L13 * (int16_t)VZ0)) >> shift;
MAC2 = int32_t((int64_t)((int16_t)L21 * (int16_t)VX0) + (int64_t)((int16_t)L22 * (int16_t)VY0) + (int64_t)((int16_t)L23 * (int16_t)VZ0)) >> shift;
MAC3 = int32_t((int64_t)((int16_t)L31 * (int16_t)VX0) + (int64_t)((int16_t)L32 * (int16_t)VY0) + (int64_t)((int16_t)L33 * (int16_t)VZ0)) >> shift;
setIRFromMAC(lm);
MAC1 = int32_t(((int64_t)RBK * 0x1000) + ((int64_t)((int16_t)LR1 * (int16_t)IR1) + (int64_t)((int16_t)LR2 * (int16_t)IR2) + (int64_t)((int16_t)LR3 * (int16_t)IR3))) >> shift;
MAC2 = int32_t(((int64_t)GBK * 0x1000) + ((int64_t)((int16_t)LG1 * (int16_t)IR1) + (int64_t)((int16_t)LG2 * (int16_t)IR2) + (int64_t)((int16_t)LG3 * (int16_t)IR3))) >> shift;
MAC3 = int32_t(((int64_t)BBK * 0x1000) + ((int64_t)((int16_t)LB1 * (int16_t)IR1) + (int64_t)((int16_t)LB2 * (int16_t)IR2) + (int64_t)((int16_t)LB3 * (int16_t)IR3))) >> shift;
setIRFromMAC(lm);
MAC1 = ((int64_t)R * (int16_t)IR1) << 4;
MAC2 = ((int64_t)G * (int16_t)IR2) << 4;
MAC3 = ((int64_t)B * (int16_t)IR3) << 4;
MAC1 = (int32_t)MAC1 >> shift;
MAC2 = (int32_t)MAC2 >> shift;
MAC3 = (int32_t)MAC3 >> shift;
setIRFromMAC(lm);
pushColour();
MAC1 = int32_t((int64_t)((int16_t)L11 * (int16_t)VX1) + (int64_t)((int16_t)L12 * (int16_t)VY1) + (int64_t)((int16_t)L13 * (int16_t)VZ1)) >> shift;
MAC2 = int32_t((int64_t)((int16_t)L21 * (int16_t)VX1) + (int64_t)((int16_t)L22 * (int16_t)VY1) + (int64_t)((int16_t)L23 * (int16_t)VZ1)) >> shift;
MAC3 = int32_t((int64_t)((int16_t)L31 * (int16_t)VX1) + (int64_t)((int16_t)L32 * (int16_t)VY1) + (int64_t)((int16_t)L33 * (int16_t)VZ1)) >> shift;
setIRFromMAC(lm);
MAC1 = int32_t(((int64_t)RBK * 0x1000) + ((int64_t)((int16_t)LR1 * (int16_t)IR1) + (int64_t)((int16_t)LR2 * (int16_t)IR2) + (int64_t)((int16_t)LR3 * (int16_t)IR3))) >> shift;
MAC2 = int32_t(((int64_t)GBK * 0x1000) + ((int64_t)((int16_t)LG1 * (int16_t)IR1) + (int64_t)((int16_t)LG2 * (int16_t)IR2) + (int64_t)((int16_t)LG3 * (int16_t)IR3))) >> shift;
MAC3 = int32_t(((int64_t)BBK * 0x1000) + ((int64_t)((int16_t)LB1 * (int16_t)IR1) + (int64_t)((int16_t)LB2 * (int16_t)IR2) + (int64_t)((int16_t)LB3 * (int16_t)IR3))) >> shift;
setIRFromMAC(lm);
MAC1 = ((int64_t)R * (int16_t)IR1) << 4;
MAC2 = ((int64_t)G * (int16_t)IR2) << 4;
MAC3 = ((int64_t)B * (int16_t)IR3) << 4;
MAC1 = (int32_t)MAC1 >> shift;
MAC2 = (int32_t)MAC2 >> shift;
MAC3 = (int32_t)MAC3 >> shift;
setIRFromMAC(lm);
pushColour();
MAC1 = int32_t((int64_t)((int16_t)L11 * (int16_t)VX2) + (int64_t)((int16_t)L12 * (int16_t)VY2) + (int64_t)((int16_t)L13 * (int16_t)VZ2)) >> shift;
MAC2 = int32_t((int64_t)((int16_t)L21 * (int16_t)VX2) + (int64_t)((int16_t)L22 * (int16_t)VY2) + (int64_t)((int16_t)L23 * (int16_t)VZ2)) >> shift;
MAC3 = int32_t((int64_t)((int16_t)L31 * (int16_t)VX2) + (int64_t)((int16_t)L32 * (int16_t)VY2) + (int64_t)((int16_t)L33 * (int16_t)VZ2)) >> shift;
setIRFromMAC(lm);
MAC1 = int32_t(((int64_t)RBK * 0x1000) + ((int64_t)((int16_t)LR1 * (int16_t)IR1) + (int64_t)((int16_t)LR2 * (int16_t)IR2) + (int64_t)((int16_t)LR3 * (int16_t)IR3))) >> shift;
MAC2 = int32_t(((int64_t)GBK * 0x1000) + ((int64_t)((int16_t)LG1 * (int16_t)IR1) + (int64_t)((int16_t)LG2 * (int16_t)IR2) + (int64_t)((int16_t)LG3 * (int16_t)IR3))) >> shift;
MAC3 = int32_t(((int64_t)BBK * 0x1000) + ((int64_t)((int16_t)LB1 * (int16_t)IR1) + (int64_t)((int16_t)LB2 * (int16_t)IR2) + (int64_t)((int16_t)LB3 * (int16_t)IR3))) >> shift;
setIRFromMAC(lm);
MAC1 = ((int64_t)R * (int16_t)IR1) << 4;
MAC2 = ((int64_t)G * (int16_t)IR2) << 4;
MAC3 = ((int64_t)B * (int16_t)IR3) << 4;
MAC1 = (int32_t)MAC1 >> shift;
MAC2 = (int32_t)MAC2 >> shift;
MAC3 = (int32_t)MAC3 >> shift;
setIRFromMAC(lm);
pushColour();
}