summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLagoLunatic <LagoLunatic@users.noreply.github.com>2026-08-27 13:12:01 -0400
committerLagoLunatic <LagoLunatic@users.noreply.github.com>2026-08-27 13:12:01 -0400
commit1d3e6a84f24decbc48eff8ca3b68cbae9050bd77 (patch)
treebbcc848ee1dea5946abac581d5b45dca74e03c9b /src
parentf25285624595171cf61008d16ff3d9ccf4edeab8 (diff)
Add debug-only vi TUs from TP to fix debug build
Diffstat (limited to 'src')
-rw-r--r--src/dolphin/vi/gpioexi.c142
-rw-r--r--src/dolphin/vi/i2c.c227
-rw-r--r--src/dolphin/vi/initphilips.c71
3 files changed, 440 insertions, 0 deletions
diff --git a/src/dolphin/vi/gpioexi.c b/src/dolphin/vi/gpioexi.c
new file mode 100644
index 00000000..a93de197
--- /dev/null
+++ b/src/dolphin/vi/gpioexi.c
@@ -0,0 +1,142 @@
+#include "dolphin/os/OS.h"
+
+static u8 shadowGPIOOE;
+static u8 shadowGPIOData;
+
+// prototypes
+static void initGpioExi(void);
+static void setVideoReset(int value);
+static void setI2CEnable(int value);
+static int gpioOutput(u8 value);
+static int gpioOE(u8 value);
+static int gpioOut(u32 addr, u8 value);
+static int gpioInput(u8* p);
+
+void __VIInitI2C(void) {
+ OSTime time;
+
+ initGpioExi();
+ setVideoReset(0);
+ time = OSGetTime();
+ while (OSGetTime() - time < OSMicrosecondsToTicks(100)) {}
+ setVideoReset(1);
+ setI2CEnable(1);
+}
+
+static void initGpioExi(void) {
+ shadowGPIOOE = 0;
+ shadowGPIOData = 0;
+ gpioOutput(shadowGPIOData);
+ gpioOE(shadowGPIOOE);
+}
+
+void __VISetSCL(int value) {
+ shadowGPIOOE &= ~2;
+ if (value == 0) {
+ shadowGPIOOE |= 2;
+ }
+ gpioOE(shadowGPIOOE);
+}
+
+int __VIGetSCL(void) {
+ u8 value;
+
+ gpioInput(&value);
+ if (value & 2) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+void __VISetSDA(int value) {
+ shadowGPIOOE &= ~1;
+ if (value == 0) {
+ shadowGPIOOE |= 1;
+ }
+ gpioOE(shadowGPIOOE);
+}
+
+int __VIGetSDA(void) {
+ u8 value;
+
+ gpioInput(&value);
+ if (value & 1) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static void setVideoReset(int value) {
+ if (value != 0) {
+ shadowGPIOData |= 4;
+ } else {
+ shadowGPIOData &= ~4;
+ }
+ shadowGPIOOE |= 4;
+ gpioOutput(shadowGPIOData);
+ gpioOE(shadowGPIOOE);
+}
+
+static void setI2CEnable(int value) {
+ if (value != 0) {
+ shadowGPIOData &= ~0x10;
+ } else {
+ shadowGPIOData |= 0x10;
+ }
+ shadowGPIOOE |= 0x10;
+ gpioOutput(shadowGPIOData);
+ gpioOE(shadowGPIOOE);
+}
+
+static int gpioOutput(u8 value) {
+ return gpioOut(0x800404U, value);
+}
+
+static int gpioOE(u8 value) {
+ return gpioOut(0x800408U, value);
+}
+
+static int gpioOut(u32 addr, u8 value) {
+ u32 cmd;
+
+ cmd = (addr | 0x02000000) << 6;
+ if (EXILock(0, 1, 0) == 0) {
+ return 0;
+ }
+ if (EXISelect(0, 1, 4) == 0) {
+ EXIUnlock(0);
+ return 0;
+ }
+
+ EXIImm(0, &cmd, 4, EXI_WRITE, 0);
+ EXISync(0);
+ cmd = value << 24;
+ EXIImm(0, &cmd, 1, EXI_WRITE, 0);
+ EXISync(0);
+ EXIDeselect(0);
+ EXIUnlock(0);
+ return 1;
+}
+
+static int gpioInput(u8* p) {
+ u32 cmd;
+
+ if (EXILock(0, 1, 0) == 0) {
+ return 0;
+ }
+ if (EXISelect(0, 1, 4) == 0) {
+ EXIUnlock(0);
+ return 0;
+ }
+ cmd = 0x20010100;
+ EXIImm(0, &cmd, 4, EXI_WRITE, 0);
+ EXISync(0);
+ EXIImm(0, &cmd, 1, EXI_READ, 0);
+ EXISync(0);
+ EXIDeselect(0);
+ EXIUnlock(0);
+ *p = cmd >> 24;
+ return 1;
+}
diff --git a/src/dolphin/vi/i2c.c b/src/dolphin/vi/i2c.c
new file mode 100644
index 00000000..2c028b9b
--- /dev/null
+++ b/src/dolphin/vi/i2c.c
@@ -0,0 +1,227 @@
+#include "dolphin/os/OS.h"
+
+static volatile u32 __i2c_ident_flag = 1;
+static volatile u32 __i2c_ident_first = 0;
+
+#define busRd32(addr) (*(volatile u32 *)(addr))
+#define busWrt32(addr, val) (*(volatile u32 *)(addr)) = (val)
+
+void WaitMicroTime(s32 usec) {
+ OSTime t = __OSGetSystemTime();
+
+ while (((__OSGetSystemTime() - t) * 8) / 486 < usec);
+}
+
+static void VICheckI2C(void) {
+ __i2c_ident_flag = 1;
+}
+
+static BOOL __VISetSCL(u32 value) {
+ u32 reg;
+ value &= 1;
+
+ reg = busRd32(0xCD8000C0);
+ reg &= ~(1 << 14);
+ reg = (u32)(reg | (value << 14));
+ busWrt32(0xCD8000C0, reg);
+ return TRUE;
+}
+
+static BOOL __VISetSDA(u32 value) {
+ u32 reg;
+ value &= 1;
+ reg = busRd32(0xCD8000C0);
+ reg &= ~(1 << 15);
+ reg = (u32)(reg | (value << 15));
+ busWrt32(0xCD8000C0, reg);
+ return TRUE;
+}
+
+static u32 __VIGetSDA(void) {
+ u32 reg = busRd32(0xCD8000C8);
+ return (u32)((reg >> 15) & 1);
+}
+
+static void __VIOpenI2C(u32 dir) {
+ u32 reg = busRd32(0xCD8000C4);
+ reg = (u32)(reg & ~(1 << 15));
+ reg = (u32)(reg | (1 << 14) | (dir << 15));
+ busWrt32(0xCD8000C4, reg);
+}
+
+static int wait4ClkHigh(void) {
+ WaitMicroTime(2);
+ return 1;
+}
+
+static int sendSlaveAddr(u8 slaveAddr) {
+ int i;
+
+ if (0 == __i2c_ident_flag) {
+ __VISetSDA(1);
+ } else {
+ __VISetSDA(0);
+ }
+
+ WaitMicroTime(2);
+ __VISetSCL(0);
+
+ for (i = 0; i < 8; i++) {
+ if (slaveAddr & 0x80) {
+ if (0 == __i2c_ident_flag) {
+ __VISetSDA(0);
+ } else {
+ __VISetSDA(1);
+ }
+ } else {
+ if (0 == __i2c_ident_flag) {
+ __VISetSDA(1);
+ } else {
+ __VISetSDA(0);
+ }
+ }
+
+ WaitMicroTime(2);
+ __VISetSCL(1);
+
+ if (wait4ClkHigh() == 0) {
+ return 0;
+ }
+
+ __VISetSCL(0);
+ slaveAddr <<= 1;
+ }
+
+ __VIOpenI2C(0);
+ WaitMicroTime(2);
+ __VISetSCL(1);
+
+ if (wait4ClkHigh() == 0) {
+ return 0;
+ }
+
+ if (1 == __i2c_ident_flag) {
+ if (__VIGetSDA() != 0) {
+ return 0;
+ }
+ }
+
+ if (0 == __i2c_ident_flag) {
+ __VISetSDA(1);
+ } else {
+ __VISetSDA(0);
+ }
+
+ __VIOpenI2C(1);
+ __VISetSCL(0);
+ return 1;
+}
+
+int __VISendI2CData(u8 slaveAddr, u8* pData, int nBytes) {
+ s32 i;
+ u8 data;
+ BOOL enabled;
+
+ if (__i2c_ident_first == 0) {
+ VICheckI2C();
+ __i2c_ident_first = 1;
+ }
+
+ enabled = OSDisableInterrupts();
+
+ __VIOpenI2C(1);
+ __VISetSCL(1);
+
+ if (0 == __i2c_ident_flag) {
+ __VISetSDA(0);
+ } else {
+ __VISetSDA(1);
+ }
+
+ WaitMicroTime(2);
+ WaitMicroTime(2);
+
+ if (sendSlaveAddr(slaveAddr) == 0) {
+ OSRestoreInterrupts(enabled);
+ return 0;
+ }
+
+ __VIOpenI2C(1);
+
+ while (nBytes != 0) {
+ data = *pData++;
+ for (i = 0; i < 8; i++) {
+ if (data & 0x80) {
+ if (0 == __i2c_ident_flag) {
+ __VISetSDA(0);
+ } else {
+ __VISetSDA(1);
+ }
+ } else {
+ if (0 == __i2c_ident_flag) {
+ __VISetSDA(1);
+ } else {
+ __VISetSDA(0);
+ }
+ }
+
+ WaitMicroTime(2);
+ __VISetSCL(1);
+
+ if (wait4ClkHigh() == 0) {
+ OSRestoreInterrupts(enabled);
+ return 0;
+ }
+
+ __VISetSCL(0);
+ data <<= 1;
+ }
+
+ __VIOpenI2C(0);
+ WaitMicroTime(2);
+ __VISetSCL(1);
+
+ if (wait4ClkHigh() == 0) {
+ OSRestoreInterrupts(enabled);
+ return 0;
+ }
+
+ if (1 == __i2c_ident_flag) {
+ if (__VIGetSDA() != 0) {
+ OSRestoreInterrupts(enabled);
+ return 0;
+ }
+ }
+
+ if (0 == __i2c_ident_flag) {
+ __VISetSDA(1);
+ } else {
+ __VISetSDA(0);
+ }
+
+ __VIOpenI2C(1);
+ __VISetSCL(0);
+ nBytes--;
+ }
+
+ __VIOpenI2C(1);
+
+ if (0 == __i2c_ident_flag) {
+ __VISetSDA(1);
+ } else {
+ __VISetSDA(0);
+ }
+
+ WaitMicroTime(2);
+ __VISetSCL(1);
+ WaitMicroTime(2);
+
+ if (0 == __i2c_ident_flag) {
+ __VISetSDA(0);
+ } else {
+ __VISetSDA(1);
+ }
+
+ OSRestoreInterrupts(enabled);
+ return 1;
+}
diff --git a/src/dolphin/vi/initphilips.c b/src/dolphin/vi/initphilips.c
new file mode 100644
index 00000000..9b1cda44
--- /dev/null
+++ b/src/dolphin/vi/initphilips.c
@@ -0,0 +1,71 @@
+#include "dolphin/vi/vi.h"
+
+static u8 ntscRange0[4] = { 0x00, 0x00, 0x19, 0x1D };
+
+static u8 ntscRange1[38] = {
+ 0x2D, 0x76, 0xA5, 0x2A,
+ 0x2E, 0x2E, 0x00, 0x15,
+ 0x3F, 0x1F, 0x7C, 0xF0,
+ 0x21, 0x55, 0x56, 0x67,
+ 0x58, 0x20, 0xF9, 0x00,
+ 0xB0, 0x14, 0x80, 0xE8,
+ 0x10, 0x42, 0x03, 0x03,
+ 0x05, 0x16, 0x04, 0x16,
+ 0x18, 0x38, 0x40, 0x00,
+ 0x00, 0x00
+};
+
+static u8 palRange0[4] = { 0x00, 0x00, 0x21, 0x1D };
+
+static u8 palRange1[38] = {
+ 0x0C, 0x7D, 0xAF, 0x23,
+ 0x35, 0x35, 0x00, 0x06,
+ 0x2F, 0xCB, 0x8A, 0x09,
+ 0x2A, 0x55, 0x56, 0x67,
+ 0x58, 0x20, 0x05, 0x20,
+ 0xA0, 0x14, 0x80, 0xE8,
+ 0x10, 0x42, 0x03, 0x03,
+ 0x05, 0x16, 0x04, 0x16,
+ 0x18, 0x38, 0x40, 0x00,
+ 0x00, 0x00
+};
+
+static u8 value3a = 19;
+
+static void send7120Data(u8 *range0, u8 *range1) {
+ u8 i;
+ u8 buffer[2];
+
+ for (i = 0; i < 38; i++) {
+ buffer[0] = i;
+ buffer[1] = 0;
+ __VISendI2CData(0x88, buffer, 2);
+ }
+
+ for (i = 38; i < 42; i++) {
+ buffer[0] = i;
+ buffer[1] = range0[i - 38];
+ __VISendI2CData(0x88, buffer, 2);
+ }
+
+ for (i = 42; i < 58; i++) {
+ buffer[0] = i;
+ buffer[1] = 0;
+ __VISendI2CData(0x88, buffer, 2);
+ }
+
+ buffer[0] = 0x3A;
+ buffer[1] = value3a;
+ __VISendI2CData(0x88, buffer, 2);
+
+ for (i = 90; i < 128; i++) {
+ buffer[0] = i;
+ buffer[1] = range1[i - 90];
+ __VISendI2CData(0x88, buffer, 2);
+ }
+}
+
+void __VIInitPhilips(void) {
+ __VIInitI2C();
+ send7120Data(ntscRange0, ntscRange1);
+}