aboutsummaryrefslogtreecommitdiff
path: root/src/SPI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/SPI.cpp')
-rw-r--r--src/SPI.cpp136
1 files changed, 90 insertions, 46 deletions
diff --git a/src/SPI.cpp b/src/SPI.cpp
index 80ef336..e990b3a 100644
--- a/src/SPI.cpp
+++ b/src/SPI.cpp
@@ -1,5 +1,5 @@
/*
- Copyright 2016-2021 Arisotura
+ Copyright 2016-2022 melonDS team
This file is part of melonDS.
@@ -127,8 +127,8 @@ void LoadDefaultFirmware()
if (NDS::ConsoleType == 1)
{
Firmware[0x1D] = 0x57; // DSi
- Firmware[0x2F] = 0x18;
- Firmware[0x1FD] = 0x02;
+ Firmware[0x2F] = 0x0F;
+ Firmware[0x1FD] = 0x01;
Firmware[0x1FE] = 0x20;
}
else
@@ -215,41 +215,52 @@ void LoadDefaultFirmware()
// wifi access points
// TODO: WFC ID??
- u32 apdata = userdata - 0x400;
- memset(&Firmware[apdata], 0, 0x300);
-
- strcpy((char*)&Firmware[apdata+0x40], "melonAP");
- if (NDS::ConsoleType == 1) *(u16*)&Firmware[apdata+0xEA] = 1400;
- Firmware[apdata+0xEF] = 0x01;
- *(u16*)&Firmware[apdata+0xFE] = CRC16(&Firmware[apdata], 0xFE, 0x0000);
-
- apdata += 0x100;
- Firmware[apdata+0xE7] = 0xFF;
- Firmware[apdata+0xEF] = 0x01;
- *(u16*)&Firmware[apdata+0xFE] = CRC16(&Firmware[apdata], 0xFE, 0x0000);
-
- apdata += 0x100;
- Firmware[apdata+0xE7] = 0xFF;
- Firmware[apdata+0xEF] = 0x01;
- *(u16*)&Firmware[apdata+0xFE] = CRC16(&Firmware[apdata], 0xFE, 0x0000);
-
- if (NDS::ConsoleType == 1)
+ FILE* f = Platform::OpenLocalFile("wfcsettings.bin"+Platform::InstanceFileSuffix(), "rb");
+ if (!f) f = Platform::OpenLocalFile("wfcsettings.bin", "rb");
+ if (f)
{
- apdata = userdata - 0xA00;
- Firmware[apdata+0xE7] = 0xFF;
+ u32 apdata = userdata - 0xA00;
+ fread(&Firmware[apdata], 0x900, 1, f);
+ fclose(f);
+ }
+ else
+ {
+ u32 apdata = userdata - 0x400;
+ memset(&Firmware[apdata], 0, 0x300);
+
+ strcpy((char*)&Firmware[apdata+0x40], "melonAP");
+ if (NDS::ConsoleType == 1) *(u16*)&Firmware[apdata+0xEA] = 1400;
+ Firmware[apdata+0xEF] = 0x01;
*(u16*)&Firmware[apdata+0xFE] = CRC16(&Firmware[apdata], 0xFE, 0x0000);
- apdata += 0x200;
+ apdata += 0x100;
Firmware[apdata+0xE7] = 0xFF;
+ Firmware[apdata+0xEF] = 0x01;
*(u16*)&Firmware[apdata+0xFE] = CRC16(&Firmware[apdata], 0xFE, 0x0000);
- apdata += 0x200;
+ apdata += 0x100;
Firmware[apdata+0xE7] = 0xFF;
+ Firmware[apdata+0xEF] = 0x01;
*(u16*)&Firmware[apdata+0xFE] = CRC16(&Firmware[apdata], 0xFE, 0x0000);
+
+ if (NDS::ConsoleType == 1)
+ {
+ apdata = userdata - 0xA00;
+ Firmware[apdata+0xE7] = 0xFF;
+ *(u16*)&Firmware[apdata+0xFE] = CRC16(&Firmware[apdata], 0xFE, 0x0000);
+
+ apdata += 0x200;
+ Firmware[apdata+0xE7] = 0xFF;
+ *(u16*)&Firmware[apdata+0xFE] = CRC16(&Firmware[apdata], 0xFE, 0x0000);
+
+ apdata += 0x200;
+ Firmware[apdata+0xE7] = 0xFF;
+ *(u16*)&Firmware[apdata+0xFE] = CRC16(&Firmware[apdata], 0xFE, 0x0000);
+ }
}
}
-void LoadFirmwareFromFile(FILE* f)
+void LoadFirmwareFromFile(FILE* f, bool makecopy)
{
fseek(f, 0, SEEK_END);
@@ -261,7 +272,9 @@ void LoadFirmwareFromFile(FILE* f)
fread(Firmware, 1, FirmwareLength, f);
// take a backup
- std::string fwBackupPath = FirmwarePath + ".bak";
+ std::string fwBackupPath;
+ if (!makecopy) fwBackupPath = FirmwarePath + ".bak";
+ else fwBackupPath = FirmwarePath;
FILE* bf = Platform::OpenLocalFile(fwBackupPath, "rb");
if (!bf)
{
@@ -323,15 +336,24 @@ void Reset()
else
FirmwarePath = Platform::GetConfigString(Platform::FirmwarePath);
+ bool makecopy = false;
+ std::string origpath = FirmwarePath;
+ FirmwarePath += Platform::InstanceFileSuffix();
+
FILE* f = Platform::OpenLocalFile(FirmwarePath, "rb");
if (!f)
{
+ f = Platform::OpenLocalFile(origpath, "rb");
+ makecopy = true;
+ }
+ if (!f)
+ {
printf("Firmware not found! Generating default firmware.\n");
FirmwarePath = "";
}
else
{
- LoadFirmwareFromFile(f);
+ LoadFirmwareFromFile(f, makecopy);
fclose(f);
}
}
@@ -375,28 +397,28 @@ void Reset()
*(u16*)&Firmware[userdata+0x72] = CRC16(&Firmware[userdata], 0x70, 0xFFFF);
- if (firmoverride)
+ //if (firmoverride)
{
u8 mac[6];
- bool rep;
+ bool rep = false;
+
+ memcpy(mac, &Firmware[0x36], 6);
+
+ if (firmoverride)
+ rep = Platform::GetConfigArray(Platform::Firm_MAC, mac);
- if (Platform::GetConfigBool(Platform::Firm_RandomizeMAC))
+ int inst = Platform::InstanceID();
+ if (inst > 0)
{
- mac[0] = 0x00;
- mac[1] = 0x09;
- mac[2] = 0xBF;
- mac[3] = rand()&0xFF;
- mac[4] = rand()&0xFF;
- mac[5] = rand()&0xFF;
rep = true;
- }
- else
- {
- rep = Platform::GetConfigArray(Platform::Firm_MAC, mac);
+ mac[3] += inst;
+ mac[4] += inst*0x44;
+ mac[5] += inst*0x10;
}
if (rep)
{
+ mac[0] &= 0xFC; // ensure the MAC isn't a broadcast MAC
memcpy(&Firmware[0x36], mac, 6);
*(u16*)&Firmware[0x2A] = CRC16(&Firmware[0x2C], *(u16*)&Firmware[0x2C], 0x0000);
@@ -463,6 +485,7 @@ void SetupDirectBoot(bool dsi)
}
}
+u32 GetFirmwareLength() { return FirmwareLength; }
u8 GetConsoleType() { return Firmware[0x1D]; }
u8 GetWifiVersion() { return Firmware[0x2F]; }
u8 GetNWifiVersion() { return Firmware[0x1FD]; } // for DSi; will return 0xFF on a DS
@@ -563,6 +586,7 @@ void Write(u8 val, u32 hold)
default:
printf("unknown firmware SPI command %02X\n", CurCmd);
+ Data = 0xFF;
break;
}
@@ -573,12 +597,27 @@ void Write(u8 val, u32 hold)
FILE* f = Platform::OpenLocalFile(FirmwarePath, "r+b");
if (f)
{
- u32 cutoff = 0x7FA00 & FirmwareMask;
+ u32 cutoff = ((NDS::ConsoleType==1) ? 0x7F400 : 0x7FA00) & FirmwareMask;
fseek(f, cutoff, SEEK_SET);
fwrite(&Firmware[cutoff], FirmwareLength-cutoff, 1, f);
fclose(f);
}
}
+ else
+ {
+ char wfcfile[50] = {0};
+ int inst = Platform::InstanceID();
+ if (inst > 0) snprintf(wfcfile, 49, "wfcsettings.bin", Platform::InstanceID());
+ else strncpy(wfcfile, "wfcsettings.bin", 49);
+
+ FILE* f = Platform::OpenLocalFile(wfcfile, "wb");
+ if (f)
+ {
+ u32 cutoff = 0x7F400 & FirmwareMask;
+ fwrite(&Firmware[cutoff], 0x900, 1, f);
+ fclose(f);
+ }
+ }
}
}
@@ -617,12 +656,15 @@ void Reset()
Registers[4] = 0x40;
RegMasks[0] = 0x7F;
- RegMasks[1] = 0x01;
+ RegMasks[1] = 0x00;
RegMasks[2] = 0x01;
RegMasks[3] = 0x03;
RegMasks[4] = 0x0F;
}
+bool GetBatteryLevelOkay() { return !Registers[1]; }
+void SetBatteryLevelOkay(bool okay) { Registers[1] = okay ? 0x00 : 0x01; }
+
void DoSavestate(Savestate* file)
{
file->Section("SPPW");
@@ -659,6 +701,7 @@ void Write(u8 val, u32 hold)
if (DataPos == 1)
{
+ // TODO: DSi-specific registers in DSi mode
u32 regid = Index & 0x07;
if (Index & 0x80)
@@ -891,6 +934,8 @@ void WriteCnt(u16 val)
}
}
+ // TODO: presumably the transfer speed can be changed during a transfer
+ // like with the NDSCart SPI interface
Cnt = (Cnt & 0x0080) | (val & 0xCF03);
if (val & 0x0400) printf("!! CRAPOED 16BIT SPI MODE\n");
if (Cnt & (1<<7)) printf("!! CHANGING SPICNT DURING TRANSFER: %04X\n", val);
@@ -925,8 +970,7 @@ u8 ReadData()
void WriteData(u8 val)
{
if (!(Cnt & (1<<15))) return;
-
- if (Cnt & (1<<7)) printf("!! WRITING AUXSPIDATA DURING PENDING TRANSFER\n");
+ if (Cnt & (1<<7)) return;
Cnt |= (1<<7);
switch (Cnt & 0x0300)