From 44a4cc83d13b499fa83df22c3155f1f0c85c3742 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 15 Apr 2021 01:14:50 +0200 Subject: [PATCH] actually make the NAND thing work --- src/NDSCart.cpp | 91 +++++++++++++++++++++++++++++++++++-------------- src/NDSCart.h | 6 +++- 2 files changed, 70 insertions(+), 27 deletions(-) diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index f97ac646..fc1bc31c 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -1177,7 +1177,12 @@ void CartRetailNAND::Reset() { SRAMAddr = 0; SRAMStatus = 0x20; - SRAMReadWindow = 0; + SRAMWindow = 0; + + // ROM header 94/96 = SRAM addr start / 0x20000 + SRAMBase = *(u16*)&ROM[0x96] << 17; + + memset(SRAMWriteBuffer, 0, 0x800); } void CartRetailNAND::DoSavestate(Savestate* file) @@ -1210,16 +1215,52 @@ void CartRetailNAND::LoadSave(const char* path, u32 type) int CartRetailNAND::ROMCommandStart(u8* cmd, u8* data, u32 len) { - // ROM header 94/96 = save addr start / 0x20000 - switch (cmd[0]) { - case 0x85: // write enable? - SRAMStatus |= (1<<4); + case 0x81: // write data + if ((SRAMStatus & (1<<4)) && SRAMWindow >= SRAMBase && SRAMWindow < (SRAMBase+0x800000)) + { + u32 addr = (cmd[1]<<24) | (cmd[2]<<16) | (cmd[3]<<8) | cmd[4]; + + // the command is issued 4 times, each with the same address + // seems they use the one from the first command (CHECKME) + if (!SRAMAddr) + SRAMAddr = addr; + } + else + SRAMAddr = 0; + return 1; + + case 0x82: // commit write + if (SRAMAddr && SRAMWritePos) + { + if (SRAMLength && SRAMAddr < (SRAMBase+SRAMLength-0x20000)) + { + memcpy(&SRAM[SRAMAddr - SRAMBase], SRAMWriteBuffer, 0x800); + SRAMFileDirty = true; + } + + SRAMAddr = 0; + SRAMWritePos = 0; + } + SRAMStatus &= ~(1<<4); + return 0; + + case 0x84: // discard write buffer + SRAMAddr = 0; + SRAMWritePos = 0; + return 0; + + case 0x85: // write enable + if (SRAMWindow) + { + SRAMStatus |= (1<<4); + SRAMWritePos = 0; + } return 0; case 0x8B: // revert to ROM read mode - SRAMReadWindow = 0; + SRAMWindow = 0; return 0; case 0x94: // return ID data @@ -1249,7 +1290,7 @@ int CartRetailNAND::ROMCommandStart(u8* cmd, u8* data, u32 len) // NAND remains stuck 'busy' forever if this is less than the starting SRAM address // TODO. - SRAMReadWindow = addr; + SRAMWindow = addr; } return 0; @@ -1257,8 +1298,9 @@ int CartRetailNAND::ROMCommandStart(u8* cmd, u8* data, u32 len) { u32 addr = (cmd[1]<<24) | (cmd[2]<<16) | (cmd[3]<<8) | cmd[4]; - if (SRAMReadWindow == 0) + if (SRAMWindow == 0) { + // regular ROM mode memset(data, 0, len); if (((addr + len - 1) >> 12) != (addr >> 12)) @@ -1272,21 +1314,13 @@ int CartRetailNAND::ROMCommandStart(u8* cmd, u8* data, u32 len) } else { + // SRAM mode memset(data, 0xFF, len); - u32 sramstart = *(u16*)&ROM[0x96] << 17; - u32 sramend = sramstart + 0x800000; // CHECKME - if (SRAMReadWindow >= sramstart && SRAMReadWindow < sramend && - addr >= SRAMReadWindow && addr < (SRAMReadWindow+0x20000)) + if (SRAMWindow >= SRAMBase && SRAMWindow < (SRAMBase+SRAMLength) && + addr >= SRAMWindow && addr < (SRAMWindow+0x20000)) { - // TODO!! - - if (addr == (sramstart+0x7FF800)) - { - u8 iddata[0x10] = {0xEC, 0x00, 0x9E, 0xA1, 0x51, 0x65, 0x34, 0x35, 0x30, 0x35, 0x30, 0x31, 0x19, 0x19, 0x02, 0x0A}; - memcpy(data, iddata, std::min(len, 0x10u)); - printf("READING ID BLOCK @ %08X\n", addr); - } + memcpy(data, &SRAM[addr - SRAMBase], len); } } } @@ -1297,17 +1331,13 @@ int CartRetailNAND::ROMCommandStart(u8* cmd, u8* data, u32 len) // status bits // bit5: ready // bit4: write enable -printf("NAND STATUS %02X\n", SRAMStatus); + for (u32 i = 0; i < len; i+=4) *(u32*)&data[i] = SRAMStatus * 0x01010101; } return 0; default: - /*if (cmd[0] != 0xB8) - printf("shitty command %02X %02X %02X %02X %02X %02X %02X %02X - %08X\n", - cmd[0], cmd[1], cmd[2], cmd[3], - cmd[4], cmd[5], cmd[6], cmd[7], len);*/ return CartRetail::ROMCommandStart(cmd, data, len); } } @@ -1316,7 +1346,16 @@ void CartRetailNAND::ROMCommandFinish(u8* cmd, u8* data, u32 len) { switch (cmd[0]) { - // TODO! + case 0x81: // write data + if (SRAMAddr) + { + if ((SRAMWritePos + len) > 0x800) + len = 0x800 - SRAMWritePos; + + memcpy(&SRAMWriteBuffer[SRAMWritePos], data, len); + SRAMWritePos += len; + } + return; default: return CartCommon::ROMCommandFinish(cmd, data, len); diff --git a/src/NDSCart.h b/src/NDSCart.h index 2f3bf233..f56a8697 100644 --- a/src/NDSCart.h +++ b/src/NDSCart.h @@ -155,7 +155,11 @@ public: u8 SPIWrite(u8 val, u32 pos, bool last); private: - u32 SRAMReadWindow; + u32 SRAMBase; + u32 SRAMWindow; + + u8 SRAMWriteBuffer[0x800]; + u32 SRAMWritePos; }; // CartRetailIR -- SPI IR device and SRAM