From 971e7b7e89426f7284b52c272b1104617af3c370 Mon Sep 17 00:00:00 2001 From: StapleButter Date: Tue, 7 Feb 2017 23:31:21 +0100 Subject: [PATCH] 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. --- FIFO.h | 6 +- GPU3D.cpp | 174 +++++++++++++++++++++++++++++++++++++++++++++++++ GPU3D.h | 7 ++ NDS.cpp | 27 +++++--- NDSCart.cpp | 9 ++- NDSCart.h | 2 +- melonDS.depend | 13 ++-- 7 files changed, 218 insertions(+), 20 deletions(-) diff --git a/FIFO.h b/FIFO.h index b0f4182c..727cc23d 100644 --- a/FIFO.h +++ b/FIFO.h @@ -47,7 +47,7 @@ public: } - void Write(u32 val) + void Write(T& val) { if (IsFull()) return; @@ -60,9 +60,9 @@ public: NumOccupied++; } - T Read() + T& Read() { - T ret = Entries[ReadPos]; + T& ret = Entries[ReadPos]; if (IsEmpty()) return ret; diff --git a/GPU3D.cpp b/GPU3D.cpp index 81b27058..7d2d2c2a 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* CmdFIFO; FIFO* 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; + } } } diff --git a/GPU3D.h b/GPU3D.h index 175b0ff6..7946ffd6 100644 --- a/GPU3D.h +++ b/GPU3D.h @@ -26,6 +26,13 @@ bool Init(); void DeInit(); void Reset(); +u8 Read8(u32 addr); +u16 Read16(u32 addr); +u32 Read32(u32 addr); +void Write8(u32 addr, u8 val); +void Write16(u32 addr, u16 val); +void Write32(u32 addr, u32 val); + } #endif diff --git a/NDS.cpp b/NDS.cpp index 6761e047..c27036aa 100644 --- a/NDS.cpp +++ b/NDS.cpp @@ -307,9 +307,8 @@ void Reset() // test //LoadROM(); //LoadFirmware(); - NDSCart::LoadROM("rom/mkds.nds"); - - Running = true; // hax + if (NDSCart::LoadROM("rom/Simple_Tri.nds")) + Running = true; // hax } @@ -1288,6 +1287,10 @@ u8 ARM9IORead8(u32 addr) { return GPU::GPU2D_B->Read8(addr); } + if (addr >= 0x04000320 && addr < 0x040006A4) + { + return GPU3D::Read8(addr); + } printf("unknown ARM9 IO read8 %08X\n", addr); return 0; @@ -1364,6 +1367,10 @@ u16 ARM9IORead16(u32 addr) { return GPU::GPU2D_B->Read16(addr); } + if (addr >= 0x04000320 && addr < 0x040006A4) + { + return GPU3D::Read16(addr); + } printf("unknown ARM9 IO read16 %08X %08X\n", addr, ARM9->R[15]); return 0; @@ -1418,8 +1425,6 @@ u32 ARM9IORead32(u32 addr) case 0x040002B8: return SqrtVal[0]; case 0x040002BC: return SqrtVal[1]; - case 0x04000600: return 0x06000000; // hax - case 0x04100000: if (IPCFIFOCnt9 & 0x8000) { @@ -1456,8 +1461,7 @@ u32 ARM9IORead32(u32 addr) } if (addr >= 0x04000320 && addr < 0x040006A4) { - // 3D GPU - return 0; + return GPU3D::Read32(addr); } printf("unknown ARM9 IO read32 %08X\n", addr); @@ -1522,6 +1526,11 @@ void ARM9IOWrite8(u32 addr, u8 val) GPU::GPU2D_B->Write8(addr, val); return; } + if (addr >= 0x04000320 && addr < 0x040006A4) + { + GPU3D::Write8(addr, val); + return; + } printf("unknown ARM9 IO write8 %08X %02X\n", addr, val); } @@ -1641,7 +1650,7 @@ void ARM9IOWrite16(u32 addr, u16 val) } if (addr >= 0x04000320 && addr < 0x040006A4) { - // 3D GPU + GPU3D::Write16(addr, val); return; } @@ -1760,7 +1769,7 @@ void ARM9IOWrite32(u32 addr, u32 val) } if (addr >= 0x04000320 && addr < 0x040006A4) { - // 3D GPU + GPU3D::Write32(addr, val); return; } diff --git a/NDSCart.cpp b/NDSCart.cpp index 8553991d..308e5e57 100644 --- a/NDSCart.cpp +++ b/NDSCart.cpp @@ -601,12 +601,17 @@ void Reset() } -void LoadROM(char* path) +bool LoadROM(char* path) { // TODO: streaming mode? for really big ROMs or systems with limited RAM // for now we're lazy FILE* f = fopen(path, "rb"); + if (!f) + { + printf("Failed to open ROM file %s\n", path); + return false; + } fseek(f, 0, SEEK_END); u32 len = (u32)ftell(f); @@ -674,6 +679,8 @@ void LoadROM(char* path) strncpy(savepath + strlen(path) - 3, "sav", 3); printf("Save file: %s\n", savepath); NDSCart_SRAM::LoadSave(savepath); + + return true; } void ReadROM(u32 addr, u32 len, u32 offset) diff --git a/NDSCart.h b/NDSCart.h index ccde9233..61dd11a9 100644 --- a/NDSCart.h +++ b/NDSCart.h @@ -40,7 +40,7 @@ bool Init(); void DeInit(); void Reset(); -void LoadROM(char* path); +bool LoadROM(char* path); void WriteROMCnt(u32 val); u32 ReadROMData(); diff --git a/melonDS.depend b/melonDS.depend index 9c8795b3..72d046f8 100644 --- a/melonDS.depend +++ b/melonDS.depend @@ -10,7 +10,7 @@ 1481161027 c:\documents\sources\melonds\types.h -1486503537 source:c:\documents\sources\melonds\nds.cpp +1486506461 source:c:\documents\sources\melonds\nds.cpp "NDS.h" @@ -105,7 +105,7 @@ 1486501225 source:c:\documents\sources\melonds\fifo.cpp "FIFO.h" -1486503492 c:\documents\sources\melonds\fifo.h +1486506620 c:\documents\sources\melonds\fifo.h "types.h" 1486309616 source:c:\documents\sources\melonds\dma.cpp @@ -135,20 +135,21 @@ "RTC.h" -1486502165 c:\documents\sources\melonds\ndscart.h +1486506409 c:\documents\sources\melonds\ndscart.h "types.h" -1486502488 source:c:\documents\sources\melonds\ndscart.cpp +1486506451 source:c:\documents\sources\melonds\ndscart.cpp "NDS.h" "NDSCart.h" -1486501964 c:\documents\sources\melonds\gpu3d.h +1486503811 c:\documents\sources\melonds\gpu3d.h -1486502427 source:c:\documents\sources\melonds\gpu3d.cpp +1486506240 source:c:\documents\sources\melonds\gpu3d.cpp "NDS.h" "GPU.h" + "FIFO.h"