well, GX FIFO base. noting that for now, it doesn't do much beyond getting full real quick.

also make ROM loading fail gracefully if it shits itself, instead of entering an endless loop.
This commit is contained in:
StapleButter
2017-02-07 23:31:21 +01:00
parent 2b7fac05c7
commit 971e7b7e89
7 changed files with 218 additions and 20 deletions

174
GPU3D.cpp
View File

@ -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;
}
}
}