diff options
Diffstat (limited to 'src/SPI.cpp')
-rw-r--r-- | src/SPI.cpp | 479 |
1 files changed, 104 insertions, 375 deletions
diff --git a/src/SPI.cpp b/src/SPI.cpp index 3c44964..a755c44 100644 --- a/src/SPI.cpp +++ b/src/SPI.cpp @@ -19,10 +19,8 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> -#include <string> -#include <algorithm> -#include <codecvt> -#include <locale> +#include <memory> +#include <utility> #include "NDS.h" #include "DSi.h" #include "SPI.h" @@ -34,12 +32,7 @@ using namespace Platform; namespace SPI_Firmware { -std::string FirmwarePath; -u8* Firmware; -u32 FirmwareLength; -u32 FirmwareMask; - -u32 UserSettings; +std::unique_ptr<Firmware> Firmware; u32 Hold; u8 CurCmd; @@ -49,10 +42,9 @@ u8 Data; u8 StatusReg; u32 Addr; - -u16 CRC16(u8* data, u32 len, u32 start) +u16 CRC16(const u8* data, u32 len, u32 start) { - u16 blarg[8] = {0xC0C1, 0xC181, 0xC301, 0xC601, 0xCC01, 0xD801, 0xF001, 0xA001}; + constexpr u16 blarg[8] = {0xC0C1, 0xC181, 0xC301, 0xC601, 0xCC01, 0xD801, 0xF001, 0xA001}; for (u32 i = 0; i < len; i++) { @@ -75,23 +67,20 @@ u16 CRC16(u8* data, u32 len, u32 start) bool VerifyCRC16(u32 start, u32 offset, u32 len, u32 crcoffset) { - u16 crc_stored = *(u16*)&Firmware[crcoffset]; - u16 crc_calced = CRC16(&Firmware[offset], len, start); + u16 crc_stored = *(u16*)&Firmware->Buffer()[crcoffset]; + u16 crc_calced = CRC16(&Firmware->Buffer()[offset], len, start); return (crc_stored == crc_calced); } bool Init() { - FirmwarePath = ""; - Firmware = nullptr; return true; } void DeInit() { - if (Firmware) delete[] Firmware; - Firmware = nullptr; + RemoveFirmware(); } u32 FixFirmwareLength(u32 originalLength) @@ -117,335 +106,43 @@ u32 FixFirmwareLength(u32 originalLength) return originalLength; } -void LoadDefaultFirmware() -{ - Log(LogLevel::Debug, "Using default firmware image...\n"); - - FirmwareLength = 0x20000; - Firmware = new u8[FirmwareLength]; - memset(Firmware, 0xFF, FirmwareLength); - FirmwareMask = FirmwareLength - 1; - - memset(Firmware, 0, 0x1D); - - if (NDS::ConsoleType == 1) - { - Firmware[0x1D] = 0x57; // DSi - Firmware[0x2F] = 0x0F; - Firmware[0x1FD] = 0x01; - Firmware[0x1FE] = 0x20; - Firmware[0x2FF] = 0x80; // boot0: use NAND as stage2 medium - - // these need to be zero (part of the stage2 firmware signature!) - memset(&Firmware[0x22], 0, 8); - } - else - { - Firmware[0x1D] = 0x20; // DS Lite (TODO: make configurable?) - Firmware[0x2F] = 0x06; - } - - // wifi calibration - - const u8 defaultmac[6] = {0x00, 0x09, 0xBF, 0x11, 0x22, 0x33}; - const u8 bbinit[0x69] = - { - 0x03, 0x17, 0x40, 0x00, 0x1B, 0x6C, 0x48, 0x80, 0x38, 0x00, 0x35, 0x07, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0xBB, 0x01, 0x24, 0x7F, - 0x5A, 0x01, 0x3F, 0x01, 0x3F, 0x36, 0x1D, 0x00, 0x78, 0x35, 0x55, 0x12, 0x34, 0x1C, 0x00, 0x01, - 0x0E, 0x38, 0x03, 0x70, 0xC5, 0x2A, 0x0A, 0x08, 0x04, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFE, - 0xFE, 0xFE, 0xFE, 0xFC, 0xFC, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xF8, 0xF8, 0xF6, 0x00, 0x12, 0x14, - 0x12, 0x41, 0x23, 0x03, 0x04, 0x70, 0x35, 0x0E, 0x2C, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x12, 0x28, 0x1C - }; - const u8 rfinit[0x29] = - { - 0x31, 0x4C, 0x4F, 0x21, 0x00, 0x10, 0xB0, 0x08, 0xFA, 0x15, 0x26, 0xE6, 0xC1, 0x01, 0x0E, 0x50, - 0x05, 0x00, 0x6D, 0x12, 0x00, 0x00, 0x01, 0xFF, 0x0E, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x06, - 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x00, 0x00 - }; - const u8 chandata[0x3C] = - { - 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x16, - 0x26, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1E, 0x1F, 0x18, - 0x01, 0x4B, 0x4B, 0x4B, 0x4B, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, 0x4D, 0x4D, 0x4D, - 0x02, 0x6C, 0x71, 0x76, 0x5B, 0x40, 0x45, 0x4A, 0x2F, 0x34, 0x39, 0x3E, 0x03, 0x08, 0x14 - }; - - *(u16*)&Firmware[0x2C] = 0x138; - Firmware[0x2E] = 0; - *(u32*)&Firmware[0x30] = 0xFFFFFFFF; - *(u16*)&Firmware[0x34] = 0x00FF; - memcpy(&Firmware[0x36], defaultmac, 6); - *(u16*)&Firmware[0x3C] = 0x3FFE; - *(u16*)&Firmware[0x3E] = 0xFFFF; - Firmware[0x40] = 0x03; - Firmware[0x41] = 0x94; - Firmware[0x42] = 0x29; - Firmware[0x43] = 0x02; - *(u16*)&Firmware[0x44] = 0x0002; - *(u16*)&Firmware[0x46] = 0x0017; - *(u16*)&Firmware[0x48] = 0x0026; - *(u16*)&Firmware[0x4A] = 0x1818; - *(u16*)&Firmware[0x4C] = 0x0048; - *(u16*)&Firmware[0x4E] = 0x4840; - *(u16*)&Firmware[0x50] = 0x0058; - *(u16*)&Firmware[0x52] = 0x0042; - *(u16*)&Firmware[0x54] = 0x0146; - *(u16*)&Firmware[0x56] = 0x8064; - *(u16*)&Firmware[0x58] = 0xE6E6; - *(u16*)&Firmware[0x5A] = 0x2443; - *(u16*)&Firmware[0x5C] = 0x000E; - *(u16*)&Firmware[0x5E] = 0x0001; - *(u16*)&Firmware[0x60] = 0x0001; - *(u16*)&Firmware[0x62] = 0x0402; - memcpy(&Firmware[0x64], bbinit, 0x69); - Firmware[0xCD] = 0; - memcpy(&Firmware[0xCE], rfinit, 0x29); - Firmware[0xF7] = 0x02; - memcpy(&Firmware[0xF8], chandata, 0x3C); - - *(u16*)&Firmware[0x2A] = CRC16(&Firmware[0x2C], *(u16*)&Firmware[0x2C], 0x0000); - - // user data - - u32 userdata = 0x7FE00 & FirmwareMask; - *(u16*)&Firmware[0x20] = userdata >> 3; - - memset(Firmware + userdata, 0, 0x74); - Firmware[userdata+0x00] = 5; // version - Firmware[userdata+0x03] = 1; - Firmware[userdata+0x04] = 1; - *(u16*)&Firmware[userdata+0x64] = 0x0031; - - *(u16*)&Firmware[userdata+0x72] = CRC16(&Firmware[userdata], 0x70, 0xFFFF); - - // wifi access points - // TODO: WFC ID?? - - std::string wfcsettings = Platform::GetConfigString(ConfigEntry::WifiSettingsPath); - - FileHandle* f = Platform::OpenLocalFile(wfcsettings + Platform::InstanceFileSuffix(), FileMode::Read); - if (!f) f = Platform::OpenLocalFile(wfcsettings, FileMode::Read); - if (f) - { - u32 apdata = userdata - 0xA00; - FileRead(&Firmware[apdata], 0x900, 1, f); - CloseFile(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 += 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) - { - 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(FileHandle* f, bool makecopy) -{ - FirmwareLength = FixFirmwareLength(FileLength(f)); - - Firmware = new u8[FirmwareLength]; - - FileRewind(f); - FileRead(Firmware, 1, FirmwareLength, f); - - // take a backup - std::string fwBackupPath; - if (!makecopy) fwBackupPath = FirmwarePath + ".bak"; - else fwBackupPath = FirmwarePath; - FileHandle* bf = Platform::OpenLocalFile(fwBackupPath, FileMode::Read); - if (!bf) - { - bf = Platform::OpenLocalFile(fwBackupPath, FileMode::Write); - if (bf) - { - FileWrite(Firmware, 1, FirmwareLength, bf); - CloseFile(bf); - } - else - { - Log(LogLevel::Error, "Could not write firmware backup!\n"); - } - } - else - { - CloseFile(bf); - } -} - -void LoadUserSettingsFromConfig() -{ - // setting up username - std::string orig_username = Platform::GetConfigString(Platform::Firm_Username); - std::u16string username = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes(orig_username); - size_t usernameLength = std::min(username.length(), (size_t) 10); - memcpy(Firmware + UserSettings + 0x06, username.data(), usernameLength * sizeof(char16_t)); - Firmware[UserSettings+0x1A] = usernameLength; - - // setting language - Firmware[UserSettings+0x64] = Platform::GetConfigInt(Platform::Firm_Language); - - // setting up color - Firmware[UserSettings+0x02] = Platform::GetConfigInt(Platform::Firm_Color); - - // setting up birthday - Firmware[UserSettings+0x03] = Platform::GetConfigInt(Platform::Firm_BirthdayMonth); - Firmware[UserSettings+0x04] = Platform::GetConfigInt(Platform::Firm_BirthdayDay); - - // setup message - std::string orig_message = Platform::GetConfigString(Platform::Firm_Message); - std::u16string message = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes(orig_message); - size_t messageLength = std::min(message.length(), (size_t) 26); - memcpy(Firmware + UserSettings + 0x1C, message.data(), messageLength * sizeof(char16_t)); - Firmware[UserSettings+0x50] = messageLength; -} - void Reset() { - if (Firmware) delete[] Firmware; - Firmware = nullptr; - FirmwarePath = ""; - bool firmoverride = false; - - if (Platform::GetConfigBool(Platform::ExternalBIOSEnable)) + if (!Firmware) { - if (NDS::ConsoleType == 1) - FirmwarePath = Platform::GetConfigString(Platform::DSi_FirmwarePath); - else - FirmwarePath = Platform::GetConfigString(Platform::FirmwarePath); - - Log(LogLevel::Debug, "SPI firmware: loading from file %s\n", FirmwarePath.c_str()); - - bool makecopy = false; - std::string origpath = FirmwarePath; - FirmwarePath += Platform::InstanceFileSuffix(); - - FileHandle* f = Platform::OpenLocalFile(FirmwarePath, FileMode::Read); - if (!f) - { - f = Platform::OpenLocalFile(origpath, FileMode::Read); - makecopy = true; - } - if (!f) - { - Log(LogLevel::Warn,"Firmware not found! Generating default firmware.\n"); - FirmwarePath = ""; - } - else - { - LoadFirmwareFromFile(f, makecopy); - CloseFile(f); - } + Log(LogLevel::Warn, "SPI firmware: no firmware loaded! Using default\n"); + Firmware = std::make_unique<class Firmware>(NDS::ConsoleType); } - if (FirmwarePath.empty()) - { - LoadDefaultFirmware(); - firmoverride = true; - } - else - { - firmoverride = Platform::GetConfigBool(Platform::Firm_OverrideSettings); - } - - FirmwareMask = FirmwareLength - 1; - - u32 userdata = 0x7FE00 & FirmwareMask; - if (*(u16*)&Firmware[userdata+0x170] == ((*(u16*)&Firmware[userdata+0x70] + 1) & 0x7F)) + // fix touchscreen coords + for (UserData& u : Firmware->UserData()) { - if (VerifyCRC16(0xFFFF, userdata+0x100, 0x70, userdata+0x172)) - userdata += 0x100; + u.TouchCalibrationADC1[0] = 0; + u.TouchCalibrationADC1[1] = 0; + u.TouchCalibrationPixel1[0] = 0; + u.TouchCalibrationPixel1[1] = 0; + u.TouchCalibrationADC2[0] = 255<<4; + u.TouchCalibrationADC2[1] = 191<<4; + u.TouchCalibrationPixel2[0] = 255; + u.TouchCalibrationPixel2[1] = 191; } - UserSettings = userdata; - - if (firmoverride) - LoadUserSettingsFromConfig(); - - // fix touchscreen coords - *(u16*)&Firmware[userdata+0x58] = 0; - *(u16*)&Firmware[userdata+0x5A] = 0; - Firmware[userdata+0x5C] = 0; - Firmware[userdata+0x5D] = 0; - *(u16*)&Firmware[userdata+0x5E] = 255<<4; - *(u16*)&Firmware[userdata+0x60] = 191<<4; - Firmware[userdata+0x62] = 255; - Firmware[userdata+0x63] = 191; + Firmware->UpdateChecksums(); // disable autoboot //Firmware[userdata+0x64] &= 0xBF; - *(u16*)&Firmware[userdata+0x72] = CRC16(&Firmware[userdata], 0x70, 0xFFFF); - - //if (firmoverride) - { - u8 mac[6]; - bool rep = false; - - memcpy(mac, &Firmware[0x36], 6); - - if (firmoverride) - rep = Platform::GetConfigArray(Platform::Firm_MAC, mac); - - int inst = Platform::InstanceID(); - if (inst > 0) - { - rep = true; - 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); - } - } - - Log(LogLevel::Info, "MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", - Firmware[0x36], Firmware[0x37], Firmware[0x38], - Firmware[0x39], Firmware[0x3A], Firmware[0x3B]); + MacAddress mac = Firmware->Header().MacAddress; + Log(LogLevel::Info, "MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); // verify shit - Log(LogLevel::Debug, "FW: WIFI CRC16 = %s\n", VerifyCRC16(0x0000, 0x2C, *(u16*)&Firmware[0x2C], 0x2A)?"GOOD":"BAD"); - Log(LogLevel::Debug, "FW: AP1 CRC16 = %s\n", VerifyCRC16(0x0000, 0x7FA00&FirmwareMask, 0xFE, 0x7FAFE&FirmwareMask)?"GOOD":"BAD"); - Log(LogLevel::Debug, "FW: AP2 CRC16 = %s\n", VerifyCRC16(0x0000, 0x7FB00&FirmwareMask, 0xFE, 0x7FBFE&FirmwareMask)?"GOOD":"BAD"); - Log(LogLevel::Debug, "FW: AP3 CRC16 = %s\n", VerifyCRC16(0x0000, 0x7FC00&FirmwareMask, 0xFE, 0x7FCFE&FirmwareMask)?"GOOD":"BAD"); - Log(LogLevel::Debug, "FW: USER0 CRC16 = %s\n", VerifyCRC16(0xFFFF, 0x7FE00&FirmwareMask, 0x70, 0x7FE72&FirmwareMask)?"GOOD":"BAD"); - Log(LogLevel::Debug, "FW: USER1 CRC16 = %s\n", VerifyCRC16(0xFFFF, 0x7FF00&FirmwareMask, 0x70, 0x7FF72&FirmwareMask)?"GOOD":"BAD"); + u32 mask = Firmware->Mask(); + Log(LogLevel::Debug, "FW: WIFI CRC16 = %s\n", VerifyCRC16(0x0000, 0x2C, *(u16*)&Firmware->Buffer()[0x2C], 0x2A)?"GOOD":"BAD"); + Log(LogLevel::Debug, "FW: AP1 CRC16 = %s\n", VerifyCRC16(0x0000, 0x7FA00&mask, 0xFE, 0x7FAFE&mask)?"GOOD":"BAD"); + Log(LogLevel::Debug, "FW: AP2 CRC16 = %s\n", VerifyCRC16(0x0000, 0x7FB00&mask, 0xFE, 0x7FBFE&mask)?"GOOD":"BAD"); + Log(LogLevel::Debug, "FW: AP3 CRC16 = %s\n", VerifyCRC16(0x0000, 0x7FC00&mask, 0xFE, 0x7FCFE&mask)?"GOOD":"BAD"); + Log(LogLevel::Debug, "FW: USER0 CRC16 = %s\n", VerifyCRC16(0xFFFF, 0x7FE00&mask, 0x70, 0x7FE72&mask)?"GOOD":"BAD"); + Log(LogLevel::Debug, "FW: USER1 CRC16 = %s\n", VerifyCRC16(0xFFFF, 0x7FF00&mask, 0x70, 0x7FF72&mask)?"GOOD":"BAD"); Hold = 0; CurCmd = 0; @@ -471,36 +168,85 @@ void DoSavestate(Savestate* file) void SetupDirectBoot(bool dsi) { + const FirmwareHeader& header = Firmware->Header(); + const UserData& userdata = Firmware->EffectiveUserData(); if (dsi) { for (u32 i = 0; i < 6; i += 2) - DSi::ARM9Write16(0x02FFFCF4, *(u16*)&Firmware[0x36+i]); // MAC address + DSi::ARM9Write16(0x02FFFCF4, *(u16*)&header.MacAddress[i]); // MAC address // checkme - DSi::ARM9Write16(0x02FFFCFA, *(u16*)&Firmware[0x3C]); // enabled channels + DSi::ARM9Write16(0x02FFFCFA, header.EnabledChannels); // enabled channels for (u32 i = 0; i < 0x70; i += 4) - DSi::ARM9Write32(0x02FFFC80+i, *(u32*)&Firmware[UserSettings+i]); + DSi::ARM9Write32(0x02FFFC80+i, *(u32*)&userdata.Bytes[i]); } else { NDS::ARM9Write32(0x027FF864, 0); - NDS::ARM9Write32(0x027FF868, *(u16*)&Firmware[0x20] << 3); // user settings offset + NDS::ARM9Write32(0x027FF868, header.UserSettingsOffset << 3); // user settings offset - NDS::ARM9Write16(0x027FF874, *(u16*)&Firmware[0x26]); // CRC16 for data/gfx - NDS::ARM9Write16(0x027FF876, *(u16*)&Firmware[0x04]); // CRC16 for GUI/wifi code + NDS::ARM9Write16(0x027FF874, header.DataGfxChecksum); // CRC16 for data/gfx + NDS::ARM9Write16(0x027FF876, header.GUIWifiCodeChecksum); // CRC16 for GUI/wifi code for (u32 i = 0; i < 0x70; i += 4) - NDS::ARM9Write32(0x027FFC80+i, *(u32*)&Firmware[UserSettings+i]); + NDS::ARM9Write32(0x027FFC80+i, *(u32*)&userdata.Bytes[i]); + } +} + +const class Firmware* GetFirmware() +{ + return Firmware.get(); +} + +bool IsLoadedFirmwareBuiltIn() +{ + return Firmware->Header().Identifier == GENERATED_FIRMWARE_IDENTIFIER; +} + +bool InstallFirmware(class Firmware&& firmware) +{ + if (!firmware.Buffer()) + { + Log(LogLevel::Error, "SPI firmware: firmware buffer is null!\n"); + return false; } + + Firmware = std::make_unique<class Firmware>(std::move(firmware)); + + FirmwareIdentifier id = Firmware->Header().Identifier; + Log(LogLevel::Debug, "Installed firmware (Identifier: %c%c%c%c)\n", id[0], id[1], id[2], id[3]); + + return true; } -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 -u8 GetRFVersion() { return Firmware[0x40]; } -u8* GetWifiMAC() { return &Firmware[0x36]; } +bool InstallFirmware(std::unique_ptr<class Firmware>&& firmware) +{ + if (!firmware) + { + Log(LogLevel::Error, "SPI firmware: firmware is null!\n"); + return false; + } + + if (!firmware->Buffer()) + { + Log(LogLevel::Error, "SPI firmware: firmware buffer is null!\n"); + return false; + } + + Firmware = std::move(firmware); + + FirmwareIdentifier id = Firmware->Header().Identifier; + Log(LogLevel::Debug, "Installed firmware (Identifier: %c%c%c%c)\n", id[0], id[1], id[2], id[3]); + + return true; +} + +void RemoveFirmware() +{ + Firmware.reset(); + Log(LogLevel::Debug, "Removed installed firmware (if any)\n"); +} u8 Read() { @@ -539,7 +285,7 @@ void Write(u8 val, u32 hold) } else { - Data = Firmware[Addr & FirmwareMask]; + Data = Firmware->Buffer()[Addr & Firmware->Mask()]; Addr++; } @@ -565,14 +311,14 @@ void Write(u8 val, u32 hold) { // TODO: what happens if you write too many bytes? (max 256, they say) if (DataPos < 4) - { + { // If we're in the middle of writing the address... Addr <<= 8; Addr |= val; Data = 0; } else { - Firmware[Addr & FirmwareMask] = val; + Firmware->Buffer()[Addr & Firmware->Mask()] = val; Data = val; Addr++; } @@ -601,31 +347,14 @@ void Write(u8 val, u32 hold) } if (!hold && (CurCmd == 0x02 || CurCmd == 0x0A)) - { - if (!FirmwarePath.empty()) - { - FileHandle* f = Platform::OpenLocalFile(FirmwarePath, FileMode::ReadWriteExisting); - if (f) - { - u32 cutoff = ((NDS::ConsoleType==1) ? 0x7F400 : 0x7FA00) & FirmwareMask; - FileSeek(f, cutoff, FileSeekOrigin::Start); - FileWrite(&Firmware[cutoff], FirmwareLength-cutoff, 1, f); - CloseFile(f); - } - } - else - { - std::string wfcfile = Platform::GetConfigString(ConfigEntry::WifiSettingsPath); - if (Platform::InstanceID() > 0) wfcfile += Platform::InstanceFileSuffix(); - - FileHandle* f = Platform::OpenLocalFile(wfcfile, FileMode::Write); - if (f) - { - u32 cutoff = 0x7F400 & FirmwareMask; - FileWrite(&Firmware[cutoff], 0x900, 1, f); - CloseFile(f); - } - } + { // If the SPI firmware chip just finished a write... + // We only notify the frontend of changes to the Wi-fi/userdata settings region + // (although it might still decide to flush the whole thing) + u32 wifioffset = Firmware->WifiAccessPointOffset(); + + // Request that the start of the Wi-fi/userdata settings region + // through the end of the firmware blob be flushed to disk + Platform::WriteFirmware(*Firmware, wifioffset, Firmware->Length() - wifioffset); } } |