aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStapleButter <thetotalworm@gmail.com>2017-02-03 16:57:31 +0100
committerStapleButter <thetotalworm@gmail.com>2017-02-03 16:57:31 +0100
commitf4335b92927ec3ba0eb3675eb1c4a5c80bb0a05d (patch)
treec38d271abf37386fcf872f11c81b9d254e247804
parent7e9972e0378ca7a5499d16511f3a3b169d6a62e1 (diff)
better save support. not hardcoded filename, support for non-tiny EEPROM and Flash, attempt at autodetecting the right memory type.
-rw-r--r--CP15.cpp3
-rw-r--r--DMA.cpp4
-rw-r--r--NDS.cpp7
-rw-r--r--NDSCart.cpp344
-rw-r--r--main.cpp26
-rw-r--r--melonDS.depend14
6 files changed, 342 insertions, 56 deletions
diff --git a/CP15.cpp b/CP15.cpp
index ded58aa..4d1fee6 100644
--- a/CP15.cpp
+++ b/CP15.cpp
@@ -135,7 +135,8 @@ void Write(u32 id, u32 val)
return;
}
- //printf("unknown CP15 write op %03X %08X\n", id, val);
+ if ((id&0xF00)!=0x700)
+ printf("unknown CP15 write op %03X %08X\n", id, val);
}
u32 Read(u32 id)
diff --git a/DMA.cpp b/DMA.cpp
index e5a3833..6c47f5c 100644
--- a/DMA.cpp
+++ b/DMA.cpp
@@ -89,6 +89,8 @@ void DMA::WriteCnt(u32 val)
Start();
//else
// printf("SPECIAL ARM%d DMA%d START MODE %02X\n", CPU?7:9, Num, StartMode);
+ if (StartMode!=0x00 && StartMode!=0x10 && StartMode!=0x05 && StartMode!=0x12)
+ printf("UNIMPLEMENTED ARM%d DMA%d START MODE %02X\n", CPU?7:9, Num, StartMode);
}
}
@@ -110,7 +112,7 @@ void DMA::Start()
// special path for cart DMA. this is a gross hack.
// emulating it properly requires emulating cart transfer delays, so uh... TODO
if (CurSrcAddr==0x04100010 && RemCount==1 && (Cnt & 0x07E00000)==0x07000000 &&
- ((CPU==0 && StartMode==0x06) || (CPU==1 && StartMode==0x12)))
+ ((CPU==0 && StartMode==0x05) || (CPU==1 && StartMode==0x12)))
{
NDSCart::DMA(CurDstAddr);
Cnt &= ~0x80000000;
diff --git a/NDS.cpp b/NDS.cpp
index 413409a..cd6fd8c 100644
--- a/NDS.cpp
+++ b/NDS.cpp
@@ -411,7 +411,6 @@ void ReleaseKey(u32 key)
void TouchScreen(u16 x, u16 y)
{
SPI_TSC::SetTouchCoords(x, y);
- printf("touching %d,%d\n", x, y);
}
void ReleaseScreen()
@@ -703,8 +702,8 @@ void StartSqrt()
void debug(u32 param)
{
- printf("ARM9 PC=%08X %08X\n", ARM9->R[15], ARM9->R_IRQ[1]);
- printf("ARM7 PC=%08X %08X\n", ARM7->R[15], ARM7->R_IRQ[1]);
+ printf("ARM9 PC=%08X LR=%08X %08X\n", ARM9->R[15], ARM9->R[14], ARM9->R_IRQ[1]);
+ printf("ARM7 PC=%08X LR=%08X %08X\n", ARM7->R[15], ARM7->R[14], ARM7->R_IRQ[1]);
}
@@ -807,7 +806,7 @@ u16 ARM9Read16(u32 addr)
return 0xFFFF;
}
- printf("unknown arm9 read16 %08X\n", addr);
+ printf("unknown arm9 read16 %08X %08X %08X %08X\n", addr, ARM9->R[15], ARM9->R[1], ARM9->R[2]);
return 0;
}
diff --git a/NDSCart.cpp b/NDSCart.cpp
index 145f627..9a2e094 100644
--- a/NDSCart.cpp
+++ b/NDSCart.cpp
@@ -28,7 +28,14 @@ namespace NDSCart_SRAM
u8* SRAM;
u32 SRAMLength;
-u32 AddrLength;
+char SRAMPath[256];
+
+void (*WriteFunc)(u8 val, bool islast);
+
+u32 Discover_MemoryType;
+u32 Discover_Likeliness;
+u8* Discover_Buffer;
+u32 Discover_DataPos;
u32 Hold;
u8 CurCmd;
@@ -39,6 +46,13 @@ u8 StatusReg;
u32 Addr;
+void Write_Null(u8 val, bool islast);
+void Write_EEPROMTiny(u8 val, bool islast);
+void Write_EEPROM(u8 val, bool islast);
+void Write_Flash(u8 val, bool islast);
+void Write_Discover(u8 val, bool islast);
+
+
void Init()
{
SRAM = NULL;
@@ -46,9 +60,17 @@ void Init()
void Reset()
{
+ //
+}
+
+void LoadSave(char* path)
+{
if (SRAM) delete[] SRAM;
- FILE* f = fopen("rom/nsmb.sav", "rb"); // TODO: NOT HARDCODE THE FILENAME!!!
+ strncpy(SRAMPath, path, 255);
+ SRAMPath[255] = '\0';
+
+ FILE* f = fopen(path, "rb");
if (f)
{
fseek(f, 0, SEEK_END);
@@ -62,17 +84,29 @@ void Reset()
switch (SRAMLength)
{
- case 8192: AddrLength = 2; break;
+ case 512: WriteFunc = Write_EEPROMTiny; break;
+ case 8192:
+ case 65536: WriteFunc = Write_EEPROM; break;
+ case 256*1024:
+ case 512*1024:
+ case 1024*1024:
+ case 8192*1024: WriteFunc = Write_Flash; break;
default:
printf("!! BAD SAVE LENGTH %d\n", SRAMLength);
- AddrLength = 2;
+ WriteFunc = Write_Null;
break;
}
}
else
{
- // TODO: autodetect save type
SRAMLength = 0;
+ WriteFunc = Write_Discover;
+ Discover_MemoryType = 2;
+ Discover_Likeliness = 0;
+
+ Discover_DataPos = 0;
+ Discover_Buffer = new u8[256*1024];
+ memset(Discover_Buffer, 0, 256*1024);
}
Hold = 0;
@@ -86,10 +120,250 @@ u8 Read()
return Data;
}
+void SetMemoryType()
+{
+ switch (Discover_MemoryType)
+ {
+ case 1:
+ printf("Save memory type: EEPROM 4k\n");
+ WriteFunc = Write_EEPROMTiny;
+ SRAMLength = 512;
+ break;
+
+ case 2:
+ printf("Save memory type: EEPROM 64k\n");
+ WriteFunc = Write_EEPROM;
+ SRAMLength = 8192;
+ break;
+
+ case 3:
+ printf("Save memory type: EEPROM 512k\n");
+ WriteFunc = Write_EEPROM;
+ SRAMLength = 65536;
+ break;
+
+ case 4:
+ printf("Save memory type: Flash. Hope the size is 256K.\n");
+ WriteFunc = Write_Flash;
+ SRAMLength = 256*1024;
+ break;
+
+ case 5:
+ printf("Save memory type: ...something else\n");
+ WriteFunc = Write_Null;
+ SRAMLength = 0;
+ break;
+ }
+
+ if (!SRAMLength)
+ return;
+
+ SRAM = new u8[SRAMLength];
+
+ // replay writes that occured during discovery
+ u8 prev_cmd = CurCmd;
+ u32 pos = 0;
+ while (pos < 256*1024)
+ {
+ u32 len = *(u32*)&Discover_Buffer[pos];
+ pos += 4;
+ if (len == 0) break;
+
+ CurCmd = Discover_Buffer[pos++];
+ DataPos = 0;
+ Addr = 0;
+ Data = 0;
+ for (u32 i = 1; i < len; i++)
+ {
+ WriteFunc(Discover_Buffer[pos++], (i==(len-1)));
+ DataPos++;
+ }
+ }
+
+ CurCmd = prev_cmd;
+}
+
+void Write_Discover(u8 val, bool islast)
+{
+ // attempt at autodetecting the type of save memory.
+ // we basically hope the game will be nice and clear whole pages of memory.
+
+ if (CurCmd == 0x03 || CurCmd == 0x0B)
+ {
+ if (Discover_Likeliness)
+ {
+ // apply. and pray.
+ SetMemoryType();
+
+ DataPos = 0;
+ Addr = 0;
+ Data = 0;
+ return WriteFunc(val, islast);
+ }
+ else
+ {
+ Data = 0;
+ return;
+ }
+ }
+
+ if (CurCmd == 0x02 || CurCmd == 0x0A)
+ {
+ if (DataPos == 0)
+ Discover_Buffer[Discover_DataPos + 4] = CurCmd;
+
+ Discover_Buffer[Discover_DataPos + 5 + DataPos] = val;
+
+ if (islast)
+ {
+ u32 len = DataPos+1;
+
+ *(u32*)&Discover_Buffer[Discover_DataPos] = len+1;
+ Discover_DataPos += 5+len;
+
+ if (Discover_Likeliness <= len)
+ {
+ Discover_Likeliness = len;
+
+ if (len > 3+256) // bigger Flash, FRAM, whatever
+ {
+ Discover_MemoryType = 5;
+ }
+ else if (len > 2+128) // Flash
+ {
+ Discover_MemoryType = 4;
+ }
+ else if (len > 2+32) // EEPROM 512k
+ {
+ Discover_MemoryType = 3;
+ }
+ else if (len > 1+16 || (len != 1+16 && CurCmd != 0x0A)) // EEPROM 64k
+ {
+ Discover_MemoryType = 2;
+ }
+ else // EEPROM 4k
+ {
+ Discover_MemoryType = 1;
+ }
+ }
+
+ printf("discover: type=%d likeliness=%d\n", Discover_MemoryType, Discover_Likeliness);
+ }
+ }
+}
+
+void Write_Null(u8 val, bool islast) {}
+
+void Write_EEPROMTiny(u8 val, bool islast)
+{
+ // TODO
+}
+
+void Write_EEPROM(u8 val, bool islast)
+{
+ switch (CurCmd)
+ {
+ case 0x02:
+ if (DataPos < 2)
+ {
+ Addr <<= 8;
+ Addr |= val;
+ Data = 0;
+ }
+ else
+ {
+ if (Addr < SRAMLength)
+ SRAM[Addr] = val;
+
+ Addr++;
+ }
+ break;
+
+ case 0x03:
+ if (DataPos < 2)
+ {
+ Addr <<= 8;
+ Addr |= val;
+ Data = 0;
+ }
+ else
+ {
+ if (Addr >= SRAMLength)
+ Data = 0;
+ else
+ Data = SRAM[Addr];
+
+ Addr++;
+ }
+ break;
+
+ case 0x9F:
+ Data = 0xFF;
+ break;
+
+ default:
+ if (DataPos==0)
+ printf("unknown EEPROM save command %02X\n", CurCmd);
+ break;
+ }
+}
+
+void Write_Flash(u8 val, bool islast)
+{
+ switch (CurCmd)
+ {
+ case 0x03:
+ if (DataPos < 3)
+ {
+ Addr <<= 8;
+ Addr |= val;
+ Data = 0;
+ }
+ else
+ {
+ if (Addr >= SRAMLength)
+ Data = 0;
+ else
+ Data = SRAM[Addr];
+
+ Addr++;
+ }
+ break;
+
+ case 0x0A:
+ if (DataPos < 3)
+ {
+ Addr <<= 8;
+ Addr |= val;
+ Data = 0;
+ }
+ else
+ {
+ if (Addr < SRAMLength)
+ SRAM[Addr] = val;
+
+ Addr++;
+ }
+ break;
+
+ case 0x9F:
+ Data = 0xFF;
+ break;
+
+ default:
+ if (DataPos==0)
+ printf("unknown Flash save command %02X\n", CurCmd);
+ break;
+ }
+}
+
void Write(u8 val, u32 hold)
{
+ bool islast = false;
+
if (!hold)
{
+ if (Hold) islast = true;
Hold = 0;
}
@@ -98,7 +372,7 @@ void Write(u8 val, u32 hold)
CurCmd = val;
Hold = 1;
Data = 0;
- DataPos = 1;
+ DataPos = 0;
Addr = 0;
//printf("save SPI command %02X\n", CurCmd);
return;
@@ -106,28 +380,13 @@ void Write(u8 val, u32 hold)
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++;
- }
+ case 0x02:
+ case 0x03:
+ case 0x0A:
+ case 0x0B:
+ case 0x9F:
+ WriteFunc(val, islast);
+ DataPos++;
break;
case 0x04: // write disable
@@ -144,14 +403,21 @@ void Write(u8 val, u32 hold)
Data = 0;
break;
- case 0x9F: // read JEDEC ID
- Data = 0xFF;
- break;
-
default:
- printf("unknown save SPI command %02X\n", CurCmd);
+ if (DataPos==0)
+ printf("unknown save SPI command %02X\n", CurCmd);
break;
}
+
+ if (islast && (CurCmd == 0x02 || CurCmd == 0x0A))
+ {
+ FILE* f = fopen(SRAMPath, "wb");
+ if (f)
+ {
+ fwrite(SRAM, SRAMLength, 1, f);
+ fclose(f);
+ }
+ }
}
}
@@ -347,6 +613,9 @@ void LoadROM(char* path)
fclose(f);
//CartROM = f;
+ // temp. TODO: later make this user selectable
+ // calling this sets up shit for booting from the cart directly.
+ // normal behavior is booting from the BIOS.
NDS::SetupDirectBoot();
CartInserted = true;
@@ -382,6 +651,15 @@ void LoadROM(char* path)
// encryption
Key1_InitKeycode(gamecode, 2, 2);
+
+
+ // save
+ char savepath[256];
+ strncpy(savepath, path, 255);
+ savepath[255] = '\0';
+ strncpy(savepath + strlen(path) - 3, "sav", 3);
+ printf("Save file: %s\n", savepath);
+ NDSCart_SRAM::LoadSave(savepath);
}
void ReadROM(u32 addr, u32 len, u32 offset)
diff --git a/main.cpp b/main.cpp
index 3e0a6a8..8b29972 100644
--- a/main.cpp
+++ b/main.cpp
@@ -41,20 +41,26 @@ LRESULT CALLBACK derpo(HWND window, UINT msg, WPARAM wparam, LPARAM lparam)
printf("close\n");
{
// 6006800 6008000
- FILE* f = fopen("wram.bin", "wb");
- for (u32 i = 0x37F8000; i < 0x3808000; i+=4)
+ FILE* f = fopen("debug/wram.bin", "wb");
+ if (f)
{
- u32 blarg = NDS::ARM7Read32(i);
- fwrite(&blarg, 4, 1, f);
+ for (u32 i = 0x37F8000; i < 0x3808000; i+=4)
+ {
+ u32 blarg = NDS::ARM7Read32(i);
+ fwrite(&blarg, 4, 1, f);
+ }
+ fclose(f);
}
- fclose(f);
- f = fopen("mainram.bin", "wb");
- for (u32 i = 0x2000000; i < 0x2400000; i+=4)
+ f = fopen("debug/mainram.bin", "wb");
+ if (f)
{
- u32 blarg = NDS::ARM9Read32(i);
- fwrite(&blarg, 4, 1, f);
+ for (u32 i = 0x2000000; i < 0x2400000; i+=4)
+ {
+ u32 blarg = NDS::ARM9Read32(i);
+ fwrite(&blarg, 4, 1, f);
+ }
+ fclose(f);
}
- fclose(f);
}
PostQuitMessage(0);
return 0;
diff --git a/melonDS.depend b/melonDS.depend
index 61e4016..18630d9 100644
--- a/melonDS.depend
+++ b/melonDS.depend
@@ -1,5 +1,5 @@
# depslib dependency file v1.0
-1485974193 source:c:\documents\sources\melonds\main.cpp
+1486086940 source:c:\documents\sources\melonds\main.cpp
<stdio.h>
<windows.h>
"NDS.h"
@@ -10,7 +10,7 @@
1481161027 c:\documents\sources\melonds\types.h
-1485988923 source:c:\documents\sources\melonds\nds.cpp
+1486135026 source:c:\documents\sources\melonds\nds.cpp
<stdio.h>
<string.h>
"NDS.h"
@@ -24,7 +24,7 @@
"RTC.h"
"Wifi.h"
-1485981252 source:c:\documents\sources\melonds\arm.cpp
+1486085968 source:c:\documents\sources\melonds\arm.cpp
<stdio.h>
"NDS.h"
"ARM.h"
@@ -71,7 +71,7 @@
1485799621 c:\documents\sources\melonds\cp15.h
-1485901523 source:c:\documents\sources\melonds\cp15.cpp
+1486086235 source:c:\documents\sources\melonds\cp15.cpp
<stdio.h>
<string.h>
"NDS.h"
@@ -86,7 +86,7 @@
"NDS.h"
"SPI.h"
-1485993754 source:c:\documents\sources\melonds\gpu2d.cpp
+1485994573 source:c:\documents\sources\melonds\gpu2d.cpp
<stdio.h>
<string.h>
"NDS.h"
@@ -108,7 +108,7 @@
1484612398 c:\documents\sources\melonds\fifo.h
"types.h"
-1485901572 source:c:\documents\sources\melonds\dma.cpp
+1486093630 source:c:\documents\sources\melonds\dma.cpp
<stdio.h>
"NDS.h"
"DMA.h"
@@ -137,7 +137,7 @@
1485980863 c:\documents\sources\melonds\ndscart.h
"types.h"
-1485981191 source:c:\documents\sources\melonds\ndscart.cpp
+1486137256 source:c:\documents\sources\melonds\ndscart.cpp
<stdio.h>
<string.h>
"NDS.h"