diff options
author | StapleButter <thetotalworm@gmail.com> | 2017-01-31 17:34:17 +0100 |
---|---|---|
committer | StapleButter <thetotalworm@gmail.com> | 2017-01-31 17:34:17 +0100 |
commit | 516bc30ee38ccf4f8039bc25c10e0c1c70605ded (patch) | |
tree | 5ce9af8cd4ad0d54d3ee4d46ccfba636e6764033 | |
parent | c3e2f7ad9b6bc7683518c2f26a89cec89253fac5 (diff) |
* very shitty implementation of save RAM. requires an existing save file for now.
* refine some SPI code, too. mostly removing a useless function.
* support 16bit accesses to DMAxCNT registers.
-rw-r--r-- | NDS.cpp | 91 | ||||
-rw-r--r-- | NDSCart.cpp | 167 | ||||
-rw-r--r-- | NDSCart.h | 8 | ||||
-rw-r--r-- | SPI.cpp | 27 | ||||
-rw-r--r-- | SPI.h | 2 | ||||
-rw-r--r-- | melonDS.depend | 10 |
6 files changed, 257 insertions, 48 deletions
@@ -1317,6 +1317,8 @@ u8 ARM9IORead8(u32 addr) { switch (addr) { + case 0x040001A2: return NDSCart::ReadSPIData(); + case 0x04000208: return IME[0]; case 0x04000240: return GPU::VRAMCNT[0]; @@ -1353,6 +1355,15 @@ u16 ARM9IORead16(u32 addr) case 0x04000004: return GPU::DispStat[0]; case 0x04000006: return GPU::VCount; + case 0x040000B8: return DMAs[0]->Cnt & 0xFFFF; + case 0x040000BA: return DMAs[0]->Cnt >> 16; + case 0x040000C4: return DMAs[1]->Cnt & 0xFFFF; + case 0x040000C6: return DMAs[1]->Cnt >> 16; + case 0x040000D0: return DMAs[2]->Cnt & 0xFFFF; + case 0x040000D2: return DMAs[2]->Cnt >> 16; + case 0x040000DC: return DMAs[3]->Cnt & 0xFFFF; + case 0x040000DE: return DMAs[3]->Cnt >> 16; + case 0x040000E0: return ((u16*)DMA9Fill)[0]; case 0x040000E2: return ((u16*)DMA9Fill)[1]; case 0x040000E4: return ((u16*)DMA9Fill)[2]; @@ -1385,6 +1396,7 @@ u16 ARM9IORead16(u32 addr) } case 0x040001A0: return NDSCart::SPICnt; + case 0x040001A2: return NDSCart::ReadSPIData(); case 0x04000204: return ExMemCnt[0]; case 0x04000208: return IME[0]; @@ -1437,6 +1449,7 @@ u32 ARM9IORead32(u32 addr) case 0x04000108: return TimerGetCounter(2) | (Timers[2].Cnt << 16); case 0x0400010C: return TimerGetCounter(3) | (Timers[3].Cnt << 16); + case 0x040001A0: return NDSCart::SPICnt | (NDSCart::ReadSPIData() << 16); case 0x040001A4: return NDSCart::ROMCnt; case 0x04000208: return IME[0]; @@ -1476,7 +1489,7 @@ u32 ARM9IORead32(u32 addr) return IPCFIFO7->Peek(); case 0x04100010: - if (!(ExMemCnt[0] & (1<<11))) return NDSCart::ReadData(); + if (!(ExMemCnt[0] & (1<<11))) return NDSCart::ReadROMData(); return 0; } @@ -1500,17 +1513,18 @@ void ARM9IOWrite8(u32 addr, u8 val) case 0x040001A0: if (!(ExMemCnt[0] & (1<<11))) { - NDSCart::SPICnt &= 0xFF00; - NDSCart::SPICnt |= val; + NDSCart::WriteSPICnt((NDSCart::SPICnt & 0xFF00) | val); } return; case 0x040001A1: if (!(ExMemCnt[0] & (1<<11))) { - NDSCart::SPICnt &= 0x00FF; - NDSCart::SPICnt |= (val << 8); + NDSCart::WriteSPICnt((NDSCart::SPICnt & 0x00FF) | (val << 8)); } return; + case 0x040001A2: + NDSCart::WriteSPIData(val); + return; case 0x040001A8: NDSCart::ROMCommand[0] = val; return; case 0x040001A9: NDSCart::ROMCommand[1] = val; return; @@ -1560,6 +1574,15 @@ void ARM9IOWrite16(u32 addr, u16 val) { case 0x04000004: GPU::SetDispStat(0, val); return; + case 0x040000B8: DMAs[0]->WriteCnt((DMAs[0]->Cnt & 0xFFFF0000) | val); return; + case 0x040000BA: DMAs[0]->WriteCnt((DMAs[0]->Cnt & 0x0000FFFF) | (val << 16)); return; + case 0x040000C4: DMAs[1]->WriteCnt((DMAs[1]->Cnt & 0xFFFF0000) | val); return; + case 0x040000C6: DMAs[1]->WriteCnt((DMAs[1]->Cnt & 0x0000FFFF) | (val << 16)); return; + case 0x040000D0: DMAs[2]->WriteCnt((DMAs[2]->Cnt & 0xFFFF0000) | val); return; + case 0x040000D2: DMAs[2]->WriteCnt((DMAs[2]->Cnt & 0x0000FFFF) | (val << 16)); return; + case 0x040000DC: DMAs[3]->WriteCnt((DMAs[3]->Cnt & 0xFFFF0000) | val); return; + case 0x040000DE: DMAs[3]->WriteCnt((DMAs[3]->Cnt & 0x0000FFFF) | (val << 16)); return; + case 0x04000100: Timers[0].Reload = val; return; case 0x04000102: TimerStart(0, val); return; case 0x04000104: Timers[1].Reload = val; return; @@ -1594,7 +1617,10 @@ void ARM9IOWrite16(u32 addr, u16 val) return; case 0x040001A0: - if (!(ExMemCnt[0] & (1<<11))) NDSCart::SPICnt = val; + if (!(ExMemCnt[0] & (1<<11))) NDSCart::WriteSPICnt(val); + return; + case 0x040001A2: + NDSCart::WriteSPIData(val & 0xFF); return; case 0x040001B8: ROMSeed0[4] = val & 0x7F; return; @@ -1709,12 +1735,12 @@ void ARM9IOWrite32(u32 addr, u32 val) case 0x040001A0: if (!(ExMemCnt[0] & (1<<11))) { - NDSCart::SPICnt = val & 0xFFFF; - // TODO: SPI shit + NDSCart::WriteSPICnt(val & 0xFFFF); + NDSCart::WriteSPIData((val >> 16) & 0xFF); } return; case 0x040001A4: - if (!(ExMemCnt[0] & (1<<11))) NDSCart::WriteCnt(val); + if (!(ExMemCnt[0] & (1<<11))) NDSCart::WriteROMCnt(val); return; case 0x040001B0: *(u32*)&ROMSeed0[0] = val; return; @@ -1768,6 +1794,8 @@ u8 ARM7IORead8(u32 addr) { case 0x04000138: return RTC::Read() & 0xFF; + case 0x040001A2: return NDSCart::ReadSPIData(); + case 0x040001C2: return SPI::ReadData(); case 0x04000208: return IME[1]; @@ -1795,6 +1823,15 @@ u16 ARM7IORead16(u32 addr) case 0x04000004: return GPU::DispStat[1]; case 0x04000006: return GPU::VCount; + case 0x040000B8: return DMAs[4]->Cnt & 0xFFFF; + case 0x040000BA: return DMAs[4]->Cnt >> 16; + case 0x040000C4: return DMAs[5]->Cnt & 0xFFFF; + case 0x040000C6: return DMAs[5]->Cnt >> 16; + case 0x040000D0: return DMAs[6]->Cnt & 0xFFFF; + case 0x040000D2: return DMAs[6]->Cnt >> 16; + case 0x040000DC: return DMAs[7]->Cnt & 0xFFFF; + case 0x040000DE: return DMAs[7]->Cnt >> 16; + case 0x04000100: return TimerGetCounter(4); case 0x04000102: return Timers[4].Cnt; case 0x04000104: return TimerGetCounter(5); @@ -1822,8 +1859,9 @@ u16 ARM7IORead16(u32 addr) } case 0x040001A0: return NDSCart::SPICnt; + case 0x040001A2: return NDSCart::ReadSPIData(); - case 0x040001C0: return SPI::ReadCnt(); + case 0x040001C0: return SPI::Cnt; case 0x040001C2: return SPI::ReadData(); case 0x04000204: return ExMemCnt[1]; @@ -1869,10 +1907,11 @@ u32 ARM7IORead32(u32 addr) case 0x04000108: return TimerGetCounter(6) | (Timers[6].Cnt << 16); case 0x0400010C: return TimerGetCounter(7) | (Timers[7].Cnt << 16); + case 0x040001A0: return NDSCart::SPICnt | (NDSCart::ReadSPIData() << 16); case 0x040001A4: return NDSCart::ROMCnt; case 0x040001C0: - return SPI::ReadCnt() | (SPI::ReadData() << 16); + return SPI::Cnt | (SPI::ReadData() << 16); case 0x04000208: return IME[1]; case 0x04000210: return IE[1]; @@ -1900,7 +1939,7 @@ u32 ARM7IORead32(u32 addr) return IPCFIFO9->Peek(); case 0x04100010: - if (ExMemCnt[0] & (1<<11)) return NDSCart::ReadData(); + if (ExMemCnt[0] & (1<<11)) return NDSCart::ReadROMData(); return 0; } @@ -1923,19 +1962,17 @@ void ARM7IOWrite8(u32 addr, u8 val) case 0x040001A0: if (ExMemCnt[0] & (1<<11)) { - NDSCart::SPICnt &= 0xFF00; - NDSCart::SPICnt |= val; + NDSCart::WriteSPICnt((NDSCart::SPICnt & 0xFF00) | val); } return; case 0x040001A1: if (ExMemCnt[0] & (1<<11)) { - NDSCart::SPICnt &= 0x00FF; - NDSCart::SPICnt |= (val << 8); + NDSCart::WriteSPICnt((NDSCart::SPICnt & 0x00FF) | (val << 8)); } return; case 0x040001A2: - printf("CART SPI %02X\n", val); + NDSCart::WriteSPIData(val); return; case 0x040001A8: NDSCart::ROMCommand[0] = val; return; @@ -1980,6 +2017,15 @@ void ARM7IOWrite16(u32 addr, u16 val) { case 0x04000004: GPU::SetDispStat(1, val); return; + case 0x040000B8: DMAs[4]->WriteCnt((DMAs[4]->Cnt & 0xFFFF0000) | val); return; + case 0x040000BA: DMAs[4]->WriteCnt((DMAs[4]->Cnt & 0x0000FFFF) | (val << 16)); return; + case 0x040000C4: DMAs[5]->WriteCnt((DMAs[5]->Cnt & 0xFFFF0000) | val); return; + case 0x040000C6: DMAs[5]->WriteCnt((DMAs[5]->Cnt & 0x0000FFFF) | (val << 16)); return; + case 0x040000D0: DMAs[6]->WriteCnt((DMAs[6]->Cnt & 0xFFFF0000) | val); return; + case 0x040000D2: DMAs[6]->WriteCnt((DMAs[6]->Cnt & 0x0000FFFF) | (val << 16)); return; + case 0x040000DC: DMAs[7]->WriteCnt((DMAs[7]->Cnt & 0xFFFF0000) | val); return; + case 0x040000DE: DMAs[7]->WriteCnt((DMAs[7]->Cnt & 0x0000FFFF) | (val << 16)); return; + case 0x04000100: Timers[4].Reload = val; return; case 0x04000102: TimerStart(4, val); return; case 0x04000104: Timers[5].Reload = val; return; @@ -2018,10 +2064,10 @@ void ARM7IOWrite16(u32 addr, u16 val) case 0x040001A0: if (ExMemCnt[0] & (1<<11)) - NDSCart::SPICnt = val; + NDSCart::WriteSPICnt(val); return; case 0x040001A2: - printf("CART SPI %04X\n", val); + NDSCart::WriteSPIData(val & 0xFF); return; case 0x040001B8: ROMSeed0[12] = val & 0x7F; return; @@ -2030,7 +2076,6 @@ void ARM7IOWrite16(u32 addr, u16 val) case 0x040001C0: SPI::WriteCnt(val); return; - case 0x040001C2: SPI::WriteData(val & 0xFF); return; @@ -2116,12 +2161,12 @@ void ARM7IOWrite32(u32 addr, u32 val) case 0x040001A0: if (ExMemCnt[0] & (1<<11)) { - NDSCart::SPICnt = val & 0xFFFF; - // TODO: SPI shit + NDSCart::WriteSPICnt(val & 0xFFFF); + NDSCart::WriteSPIData((val >> 16) & 0xFF); } return; case 0x040001A4: - if (ExMemCnt[0] & (1<<11)) NDSCart::WriteCnt(val); + if (ExMemCnt[0] & (1<<11)) NDSCart::WriteROMCnt(val); return; case 0x040001B0: *(u32*)&ROMSeed0[8] = val; return; diff --git a/NDSCart.cpp b/NDSCart.cpp index 0ef3faf..d4f657d 100644 --- a/NDSCart.cpp +++ b/NDSCart.cpp @@ -21,6 +21,142 @@ #include "NDS.h" #include "NDSCart.h" + +namespace NDSCart_SRAM +{ + +u8* SRAM; +u32 SRAMLength; + +u32 AddrLength; + +u32 Hold; +u8 CurCmd; +u32 DataPos; +u8 Data; + +u8 StatusReg; +u32 Addr; + + +void Init() +{ + SRAM = NULL; +} + +void Reset() +{ + if (SRAM) delete[] SRAM; + + FILE* f = fopen("rom/nsmb.sav", "rb"); // TODO: NOT HARDCODE THE FILENAME!!! + if (f) + { + fseek(f, 0, SEEK_END); + SRAMLength = (u32)ftell(f); + SRAM = new u8[SRAMLength]; + + fseek(f, 0, SEEK_SET); + fread(SRAM, SRAMLength, 1, f); + + fclose(f); + + switch (SRAMLength) + { + case 8192: AddrLength = 2; break; + default: + printf("!! BAD SAVE LENGTH %d\n", SRAMLength); + AddrLength = 2; + break; + } + } + else + { + // TODO: autodetect save type + SRAMLength = 0; + } + + Hold = 0; + CurCmd = 0; + Data = 0; + StatusReg = 0x00; +} + +u8 Read() +{ + return Data; +} + +void Write(u8 val, u32 hold) +{ + if (!hold) + { + Hold = 0; + } + + if (hold && (!Hold)) + { + CurCmd = val; + Hold = 1; + Data = 0; + DataPos = 1; + Addr = 0; + //printf("save SPI command %02X\n", CurCmd); + return; + } + + switch (CurCmd) + { + case 0x03: // read + { + if (DataPos < AddrLength+1) + { + Addr <<= 8; + Addr |= val; + Data = 0; + + //if (DataPos == AddrLength) printf("save SPI read %08X\n", Addr); + } + else + { + if (Addr >= SRAMLength) + Data = 0; + else + Data = SRAM[Addr]; + + Addr++; + } + + DataPos++; + } + break; + + case 0x04: // write disable + StatusReg &= ~(1<<1); + Data = 0; + break; + + case 0x05: // read status reg + Data = StatusReg; + break; + + case 0x06: // write enable + StatusReg |= (1<<1); + Data = 0; + break; + + case 0x9F: // read JEDEC ID + Data = 0xFF; + break; + + default: + printf("unknown save SPI command %02X\n", CurCmd); + break; + } +} + +} + + namespace NDSCart { @@ -154,6 +290,7 @@ void Key2_Encrypt(u8* data, u32 len) void Init() { + NDSCart_SRAM::Init(); } void Reset() @@ -179,6 +316,8 @@ void Reset() CmdEncMode = 0; DataEncMode = 0; + + NDSCart_SRAM::Reset(); } @@ -293,7 +432,7 @@ void ROMPrepareData(u32 param) // NDS::ScheduleEvent((ROMCnt & (1<<27)) ? 8:5, ROMPrepareData, 0); } -void WriteCnt(u32 val) +void WriteROMCnt(u32 val) { ROMCnt = val & 0xFF7F7FFF; @@ -437,7 +576,7 @@ void WriteCnt(u32 val) //NDS::ScheduleEvent((ROMCnt & (1<<27)) ? 8:5, ROMPrepareData, 0); } -u32 ReadData() +u32 ReadROMData() { /*if (ROMCnt & (1<<23)) { @@ -472,4 +611,28 @@ void DMA(u32 addr) EndTransfer(); } + +void WriteSPICnt(u16 val) +{ + SPICnt = (SPICnt & 0x0080) | (val & 0xE043); +} + +u8 ReadSPIData() +{ + if (!(SPICnt & (1<<15))) return 0; + if (!(SPICnt & (1<<13))) return 0; + + return NDSCart_SRAM::Read(); +} + +void WriteSPIData(u8 val) +{ + if (!(SPICnt & (1<<15))) return; + if (!(SPICnt & (1<<13))) return; + + // TODO: take delays into account + + NDSCart_SRAM::Write(val, SPICnt&(1<<6)); +} + } @@ -38,10 +38,14 @@ void Reset(); void LoadROM(char* path); -void WriteCnt(u32 val); -u32 ReadData(); +void WriteROMCnt(u32 val); +u32 ReadROMData(); void DMA(u32 addr); +void WriteSPICnt(u16 val); +u8 ReadSPIData(); +void WriteSPIData(u8 val); + } #endif @@ -270,7 +270,7 @@ void Write(u8 val, u32 hold) namespace SPI { -u16 CNT; +u16 Cnt; u32 CurDevice; @@ -283,29 +283,24 @@ void Init() void Reset() { - CNT = 0; + Cnt = 0; SPI_Firmware::Reset(); SPI_Powerman::Reset(); } -u16 ReadCnt() -{ - return CNT; -} - void WriteCnt(u16 val) { - CNT = val & 0xCF03; + Cnt = (Cnt & 0x0080) | (val & 0xCF03); if (val & 0x0400) printf("!! CRAPOED 16BIT SPI MODE\n"); } u8 ReadData() { - if (!(CNT & (1<<15))) return 0; + if (!(Cnt & (1<<15))) return 0; - switch (CNT & 0x0300) + switch (Cnt & 0x0300) { case 0x0000: return SPI_Powerman::Read(); case 0x0100: return SPI_Firmware::Read(); @@ -315,18 +310,18 @@ u8 ReadData() void WriteData(u8 val) { - if (!(CNT & (1<<15))) return; + if (!(Cnt & (1<<15))) return; // TODO: take delays into account - switch (CNT & 0x0300) + switch (Cnt & 0x0300) { - case 0x0000: SPI_Powerman::Write(val, CNT&(1<<11)); break; - case 0x0100: SPI_Firmware::Write(val, CNT&(1<<11)); break; - default: printf("SPI to unknown device %04X %02X\n", CNT, val); break; + case 0x0000: SPI_Powerman::Write(val, Cnt&(1<<11)); break; + case 0x0100: SPI_Firmware::Write(val, Cnt&(1<<11)); break; + default: printf("SPI to unknown device %04X %02X\n", Cnt, val); break; } - if (CNT & (1<<14)) + if (Cnt & (1<<14)) NDS::TriggerIRQ(1, NDS::IRQ_SPI); } @@ -22,6 +22,8 @@ namespace SPI { +extern u16 Cnt; + void Init(); void Reset(); diff --git a/melonDS.depend b/melonDS.depend index 79b1c51..e32d002 100644 --- a/melonDS.depend +++ b/melonDS.depend @@ -10,7 +10,7 @@ 1481161027 c:\documents\sources\melonds\types.h -1485868426 source:c:\documents\sources\melonds\nds.cpp +1485879135 source:c:\documents\sources\melonds\nds.cpp <stdio.h> <string.h> "NDS.h" @@ -24,7 +24,7 @@ "RTC.h" "Wifi.h" -1485871611 source:c:\documents\sources\melonds\arm.cpp +1485873712 source:c:\documents\sources\melonds\arm.cpp <stdio.h> "NDS.h" "ARM.h" @@ -78,9 +78,9 @@ "ARM.h" "CP15.h" -1480957111 c:\documents\sources\melonds\spi.h +1485878592 c:\documents\sources\melonds\spi.h -1485820057 source:c:\documents\sources\melonds\spi.cpp +1485878652 source:c:\documents\sources\melonds\spi.cpp <stdio.h> <string.h> "NDS.h" @@ -134,7 +134,7 @@ <string.h> "RTC.h" -1485112531 c:\documents\sources\melonds\ndscart.h +1485878561 c:\documents\sources\melonds\ndscart.h "types.h" 1485813068 source:c:\documents\sources\melonds\ndscart.cpp |