better save support. not hardcoded filename, support for non-tiny EEPROM and Flash, attempt at autodetecting the right memory type.

This commit is contained in:
StapleButter
2017-02-03 16:57:31 +01:00
parent 7e9972e037
commit f4335b9292
6 changed files with 342 additions and 56 deletions

View File

@ -135,7 +135,8 @@ void Write(u32 id, u32 val)
return; 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) u32 Read(u32 id)

View File

@ -89,6 +89,8 @@ void DMA::WriteCnt(u32 val)
Start(); Start();
//else //else
// printf("SPECIAL ARM%d DMA%d START MODE %02X\n", CPU?7:9, Num, StartMode); // 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. // special path for cart DMA. this is a gross hack.
// emulating it properly requires emulating cart transfer delays, so uh... TODO // emulating it properly requires emulating cart transfer delays, so uh... TODO
if (CurSrcAddr==0x04100010 && RemCount==1 && (Cnt & 0x07E00000)==0x07000000 && 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); NDSCart::DMA(CurDstAddr);
Cnt &= ~0x80000000; Cnt &= ~0x80000000;

View File

@ -411,7 +411,6 @@ void ReleaseKey(u32 key)
void TouchScreen(u16 x, u16 y) void TouchScreen(u16 x, u16 y)
{ {
SPI_TSC::SetTouchCoords(x, y); SPI_TSC::SetTouchCoords(x, y);
printf("touching %d,%d\n", x, y);
} }
void ReleaseScreen() void ReleaseScreen()
@ -703,8 +702,8 @@ void StartSqrt()
void debug(u32 param) void debug(u32 param)
{ {
printf("ARM9 PC=%08X %08X\n", ARM9->R[15], ARM9->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 %08X\n", ARM7->R[15], ARM7->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; 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; return 0;
} }

View File

@ -28,7 +28,14 @@ namespace NDSCart_SRAM
u8* SRAM; u8* SRAM;
u32 SRAMLength; 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; u32 Hold;
u8 CurCmd; u8 CurCmd;
@ -39,16 +46,31 @@ u8 StatusReg;
u32 Addr; 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() void Init()
{ {
SRAM = NULL; SRAM = NULL;
} }
void Reset() void Reset()
{
//
}
void LoadSave(char* path)
{ {
if (SRAM) delete[] SRAM; 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) if (f)
{ {
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
@ -62,17 +84,29 @@ void Reset()
switch (SRAMLength) 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: default:
printf("!! BAD SAVE LENGTH %d\n", SRAMLength); printf("!! BAD SAVE LENGTH %d\n", SRAMLength);
AddrLength = 2; WriteFunc = Write_Null;
break; break;
} }
} }
else else
{ {
// TODO: autodetect save type
SRAMLength = 0; 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; Hold = 0;
@ -86,10 +120,250 @@ u8 Read()
return Data; 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) void Write(u8 val, u32 hold)
{ {
bool islast = false;
if (!hold) if (!hold)
{ {
if (Hold) islast = true;
Hold = 0; Hold = 0;
} }
@ -98,7 +372,7 @@ void Write(u8 val, u32 hold)
CurCmd = val; CurCmd = val;
Hold = 1; Hold = 1;
Data = 0; Data = 0;
DataPos = 1; DataPos = 0;
Addr = 0; Addr = 0;
//printf("save SPI command %02X\n", CurCmd); //printf("save SPI command %02X\n", CurCmd);
return; return;
@ -106,28 +380,13 @@ void Write(u8 val, u32 hold)
switch (CurCmd) switch (CurCmd)
{ {
case 0x03: // read case 0x02:
{ case 0x03:
if (DataPos < AddrLength+1) case 0x0A:
{ case 0x0B:
Addr <<= 8; case 0x9F:
Addr |= val; WriteFunc(val, islast);
Data = 0; DataPos++;
//if (DataPos == AddrLength) printf("save SPI read %08X\n", Addr);
}
else
{
if (Addr >= SRAMLength)
Data = 0;
else
Data = SRAM[Addr];
Addr++;
}
DataPos++;
}
break; break;
case 0x04: // write disable case 0x04: // write disable
@ -144,14 +403,21 @@ void Write(u8 val, u32 hold)
Data = 0; Data = 0;
break; break;
case 0x9F: // read JEDEC ID
Data = 0xFF;
break;
default: default:
printf("unknown save SPI command %02X\n", CurCmd); if (DataPos==0)
printf("unknown save SPI command %02X\n", CurCmd);
break; 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); fclose(f);
//CartROM = 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(); NDS::SetupDirectBoot();
CartInserted = true; CartInserted = true;
@ -382,6 +651,15 @@ void LoadROM(char* path)
// encryption // encryption
Key1_InitKeycode(gamecode, 2, 2); 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) void ReadROM(u32 addr, u32 len, u32 offset)

View File

@ -41,20 +41,26 @@ LRESULT CALLBACK derpo(HWND window, UINT msg, WPARAM wparam, LPARAM lparam)
printf("close\n"); printf("close\n");
{ {
// 6006800 6008000 // 6006800 6008000
FILE* f = fopen("wram.bin", "wb"); FILE* f = fopen("debug/wram.bin", "wb");
for (u32 i = 0x37F8000; i < 0x3808000; i+=4) if (f)
{ {
u32 blarg = NDS::ARM7Read32(i); for (u32 i = 0x37F8000; i < 0x3808000; i+=4)
fwrite(&blarg, 4, 1, f); {
u32 blarg = NDS::ARM7Read32(i);
fwrite(&blarg, 4, 1, f);
}
fclose(f);
} }
fclose(f); f = fopen("debug/mainram.bin", "wb");
f = fopen("mainram.bin", "wb"); if (f)
for (u32 i = 0x2000000; i < 0x2400000; i+=4)
{ {
u32 blarg = NDS::ARM9Read32(i); for (u32 i = 0x2000000; i < 0x2400000; i+=4)
fwrite(&blarg, 4, 1, f); {
u32 blarg = NDS::ARM9Read32(i);
fwrite(&blarg, 4, 1, f);
}
fclose(f);
} }
fclose(f);
} }
PostQuitMessage(0); PostQuitMessage(0);
return 0; return 0;

View File

@ -1,5 +1,5 @@
# depslib dependency file v1.0 # depslib dependency file v1.0
1485974193 source:c:\documents\sources\melonds\main.cpp 1486086940 source:c:\documents\sources\melonds\main.cpp
<stdio.h> <stdio.h>
<windows.h> <windows.h>
"NDS.h" "NDS.h"
@ -10,7 +10,7 @@
1481161027 c:\documents\sources\melonds\types.h 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> <stdio.h>
<string.h> <string.h>
"NDS.h" "NDS.h"
@ -24,7 +24,7 @@
"RTC.h" "RTC.h"
"Wifi.h" "Wifi.h"
1485981252 source:c:\documents\sources\melonds\arm.cpp 1486085968 source:c:\documents\sources\melonds\arm.cpp
<stdio.h> <stdio.h>
"NDS.h" "NDS.h"
"ARM.h" "ARM.h"
@ -71,7 +71,7 @@
1485799621 c:\documents\sources\melonds\cp15.h 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> <stdio.h>
<string.h> <string.h>
"NDS.h" "NDS.h"
@ -86,7 +86,7 @@
"NDS.h" "NDS.h"
"SPI.h" "SPI.h"
1485993754 source:c:\documents\sources\melonds\gpu2d.cpp 1485994573 source:c:\documents\sources\melonds\gpu2d.cpp
<stdio.h> <stdio.h>
<string.h> <string.h>
"NDS.h" "NDS.h"
@ -108,7 +108,7 @@
1484612398 c:\documents\sources\melonds\fifo.h 1484612398 c:\documents\sources\melonds\fifo.h
"types.h" "types.h"
1485901572 source:c:\documents\sources\melonds\dma.cpp 1486093630 source:c:\documents\sources\melonds\dma.cpp
<stdio.h> <stdio.h>
"NDS.h" "NDS.h"
"DMA.h" "DMA.h"
@ -137,7 +137,7 @@
1485980863 c:\documents\sources\melonds\ndscart.h 1485980863 c:\documents\sources\melonds\ndscart.h
"types.h" "types.h"
1485981191 source:c:\documents\sources\melonds\ndscart.cpp 1486137256 source:c:\documents\sources\melonds\ndscart.cpp
<stdio.h> <stdio.h>
<string.h> <string.h>
"NDS.h" "NDS.h"