aboutsummaryrefslogtreecommitdiff
path: root/GPU3D.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'GPU3D.cpp')
-rw-r--r--GPU3D.cpp174
1 files changed, 174 insertions, 0 deletions
diff --git a/GPU3D.cpp b/GPU3D.cpp
index 81b2705..7d2d2c2 100644
--- a/GPU3D.cpp
+++ b/GPU3D.cpp
@@ -26,6 +26,43 @@
namespace GPU3D
{
+const u32 CmdNumParams[256] =
+{
+ // 0x00
+ 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // 0x10
+ 1, 0, 1, 1, 1, 0, 16, 12, 16, 12, 9, 3, 3,
+ 0, 0, 0,
+ // 0x20
+ 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0,
+ // 0x30
+ 1, 1, 1, 1, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // 0x40
+ 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // 0x50
+ 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // 0x60
+ 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // 0x70
+ 3, 2, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // 0x80+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
typedef struct
{
u8 Command;
@@ -36,6 +73,10 @@ typedef struct
FIFO<CmdFIFOEntry>* CmdFIFO;
FIFO<CmdFIFOEntry>* CmdPIPE;
+u32 NumCommands, CurCommand, ParamCount, TotalParams;
+
+u32 GXStat;
+
bool Init()
{
@@ -55,6 +96,139 @@ void Reset()
{
CmdFIFO->Clear();
CmdPIPE->Clear();
+
+ NumCommands = 0;
+ CurCommand = 0;
+ ParamCount = 0;
+ TotalParams = 0;
+
+ GXStat = 0;
+}
+
+
+void CmdFIFOWrite(CmdFIFOEntry entry)
+{
+ printf("GX FIFO: %02X %08X\n", entry.Command, entry.Param);
+
+ if (CmdFIFO->IsEmpty() && !CmdPIPE->IsFull())
+ {
+ CmdPIPE->Write(entry);
+ }
+ else
+ {
+ if (CmdFIFO->IsFull())
+ {
+ printf("!!! GX FIFO FULL\n");
+ return;
+ }
+
+ CmdFIFO->Write(entry);
+ }
+}
+
+CmdFIFOEntry CmdFIFORead()
+{
+ CmdFIFOEntry ret = CmdPIPE->Read();
+
+ if (CmdPIPE->Level() <= 2)
+ {
+ if (!CmdFIFO->IsEmpty())
+ CmdPIPE->Write(CmdFIFO->Read());
+ if (!CmdFIFO->IsEmpty())
+ CmdPIPE->Write(CmdFIFO->Read());
+ }
+}
+
+
+u8 Read8(u32 addr)
+{
+ return 0;
+}
+
+u16 Read16(u32 addr)
+{
+ return 0;
+}
+
+u32 Read32(u32 addr)
+{
+ switch (addr)
+ {
+ case 0x04000320:
+ return 46; // TODO, eventually
+
+ case 0x04000600:
+ {
+ u32 fifolevel = CmdFIFO->Level();
+
+ return GXStat |
+ // matrix stack levels, TODO
+ (fifolevel << 16) |
+ (fifolevel < 128 ? (1<<25) : 0) |
+ (fifolevel == 0 ? (1<<26) : 0);
+ }
+ }
+ return 0;
+}
+
+void Write8(u32 addr, u8 val)
+{
+ //
+}
+
+void Write16(u32 addr, u16 val)
+{
+ //
+}
+
+void Write32(u32 addr, u32 val)
+{
+ switch (addr)
+ {
+ case 0x04000600:
+ if (val & 0x8000) GXStat &= ~0x8000;
+ val &= 0xC0000000;
+ GXStat &= 0x3FFFFFFF;
+ GXStat |= val;
+ return;
+ }
+
+ if (addr >= 0x04000400 && addr < 0x04000440)
+ {
+ if (NumCommands == 0)
+ {
+ NumCommands = 4;
+ CurCommand = val;
+ ParamCount = 0;
+ TotalParams = CmdNumParams[CurCommand & 0xFF];
+ }
+ else
+ ParamCount++;
+
+ while (ParamCount == TotalParams)
+ {
+ CmdFIFOEntry entry;
+ entry.Command = CurCommand & 0xFF;
+ entry.Param = val;
+ CmdFIFOWrite(entry);
+
+ CurCommand >>= 8;
+ NumCommands--;
+ if (NumCommands == 0) break;
+
+ ParamCount = 0;
+ TotalParams = CmdNumParams[CurCommand & 0xFF];
+ }
+ }
+
+ if (addr >= 0x04000440 && addr < 0x040005CC)
+ {
+ CmdFIFOEntry entry;
+ entry.Command = (addr & 0x1FC) >> 2;
+ entry.Param = val;
+ CmdFIFOWrite(entry);
+ return;
+ }
}
}