diff options
Diffstat (limited to 'GPU3D.cpp')
-rw-r--r-- | GPU3D.cpp | 174 |
1 files changed, 174 insertions, 0 deletions
@@ -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; + } } } |