aboutsummaryrefslogtreecommitdiff
path: root/src/DSi_NAND.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/DSi_NAND.h')
-rw-r--r--src/DSi_NAND.h112
1 files changed, 110 insertions, 2 deletions
diff --git a/src/DSi_NAND.h b/src/DSi_NAND.h
index 14599b2..9bff8f2 100644
--- a/src/DSi_NAND.h
+++ b/src/DSi_NAND.h
@@ -22,6 +22,8 @@
#include "types.h"
#include "NDS_Header.h"
#include "DSi_TMD.h"
+#include "SPI_Firmware.h"
+#include <array>
#include <vector>
#include <string>
@@ -35,6 +37,10 @@ enum
TitleData_BannerSav,
};
+union DSiFirmwareSystemSettings;
+union DSiSerialData;
+using DSiHardwareInfoN = std::array<u8, 0x9C>;
+
bool Init(u8* es_keyY);
void DeInit();
@@ -42,9 +48,9 @@ Platform::FileHandle* GetFile();
void GetIDs(u8* emmc_cid, u64& consoleid);
-void ReadHardwareInfo(u8* dataS, u8* dataN);
+void ReadHardwareInfo(DSiSerialData& dataS, DSiHardwareInfoN& dataN);
-void ReadUserData(u8* data);
+void ReadUserData(DSiFirmwareSystemSettings& data);
void PatchUserData();
void ListTitles(u32 category, std::vector<u32>& titlelist);
@@ -58,6 +64,108 @@ u32 GetTitleDataMask(u32 category, u32 titleid);
bool ImportTitleData(u32 category, u32 titleid, int type, const char* file);
bool ExportTitleData(u32 category, u32 titleid, int type, const char* file);
+typedef std::array<u8, 20> SHA1Hash;
+typedef std::array<u8, 8> TitleID;
+
+/// Firmware settings for the DSi, saved to the NAND as TWLCFG0.dat or TWLCFG1.dat.
+/// The DSi mirrors this information to its own firmware for compatibility with NDS games.
+/// @note The file is normally 16KiB, but only the first 432 bytes are used;
+/// the rest is FF-padded.
+/// This struct excludes the padding.
+/// @see https://problemkaputt.de/gbatek.htm#dsisdmmcfirmwaresystemsettingsdatafiles
+union DSiFirmwareSystemSettings
+{
+ struct
+ {
+ SHA1Hash Hash;
+ u8 Zero00[108];
+ u8 Version;
+ u8 UpdateCounter;
+ u8 Zero01[2];
+ u32 BelowRAMAreaSize;
+ u32 ConfigFlags;
+ u8 Zero02;
+ u8 CountryCode;
+ SPI_Firmware::Language Language;
+ u8 RTCYear;
+ u32 RTCOffset;
+ u8 Zero3[4];
+ u8 EULAVersion;
+ u8 Zero04[9];
+ u8 AlarmHour;
+ u8 AlarmMinute;
+ u8 Zero05[2];
+ bool AlarmEnable;
+ u8 Zero06[2];
+ u8 SystemMenuUsedTitleSlots;
+ u8 SystemMenuFreeTitleSlots;
+ u8 Unknown0;
+ u8 Unknown1;
+ u8 Zero07[3];
+ TitleID SystemMenuMostRecentTitleID;
+ std::array<u16, 2> TouchCalibrationADC1;
+ std::array<u8, 2> TouchCalibrationPixel1;
+ std::array<u16, 2> TouchCalibrationADC2;
+ std::array<u8, 2> TouchCalibrationPixel2;
+ u8 Unknown2[4];
+ u8 Zero08[4];
+ u8 FavoriteColor;
+ u8 Zero09;
+ u8 BirthdayMonth;
+ u8 BirthdayDay;
+ char16_t Nickname[11];
+ char16_t Message[27];
+ u8 ParentalControlsFlags;
+ u8 Zero10[6];
+ u8 ParentalControlsRegion;
+ u8 ParentalControlsYearsOfAgeRating;
+ u8 ParentalControlsSecretQuestion;
+ u8 Unknown3;
+ u8 Zero11[2];
+ char ParentalControlsPIN[5];
+ char16_t ParentalControlsSecretAnswer[65];
+ };
+ u8 Bytes[432];
+
+ void UpdateHash();
+};
+
+static_assert(sizeof(DSiFirmwareSystemSettings) == 432, "DSiFirmwareSystemSettings must be exactly 432 bytes");
+
+enum class ConsoleRegion : u8
+{
+ Japan,
+ USA,
+ Europe,
+ Australia,
+ China,
+ Korea,
+};
+
+/// Data file saved to 0:/sys/HWINFO_S.dat.
+/// @note The file is normally 16KiB, but only the first 164 bytes are used;
+/// the rest is FF-padded.
+/// This struct excludes the padding.
+/// @see https://problemkaputt.de/gbatek.htm#dsisdmmcfirmwaremiscfiles
+union DSiSerialData
+{
+ struct
+ {
+ u8 RsaSha1HMAC[0x80];
+ u32 Version;
+ u32 EntrySize;
+ u32 SupportedLanguages;
+ u8 Unknown0[4];
+ ConsoleRegion Region;
+ char Serial[12];
+ u8 Unknown1[3];
+ u8 TitleIDLSBs[4];
+ };
+ u8 Bytes[164];
+};
+
+static_assert(sizeof(DSiSerialData) == 164, "DSiSerialData must be exactly 164 bytes");
+
}
#endif // DSI_NAND_H