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"