aboutsummaryrefslogtreecommitdiff
path: root/src/NDSCart.h
diff options
context:
space:
mode:
authorAdrian Siekierka <kontakt@asie.pl>2023-12-15 08:19:53 +0100
committerGitHub <noreply@github.com>2023-12-15 08:19:53 +0100
commit6f47c9ed4c0e5b1035089805f272c6965343f113 (patch)
treefadad3548cea8de7fe5ae380d4ff857909c9cb27 /src/NDSCart.h
parent9bfc9c08ffe88de4b54734d6fd03182c0a51e181 (diff)
Support emulating R4 Revolution/M3DS Simply cartridges. (#1854)
* Support emulating R4 Revolution/M3DS Simply cartridges. * NDSCartR4: Write state information to savestate file. * NDSCart: Use strncmp instead of strcmp for R4 detection. * NDSCartR4: stylistic improvements * NDSCartR4: rudimentary Ace3DS support * NDSCartR4: fix boot when firmware enabled * NDSCartR4: Fix for namespace changes --------- Co-authored-by: RSDuck <RSDuck@users.noreply.github.com>
Diffstat (limited to 'src/NDSCart.h')
-rw-r--r--src/NDSCart.h87
1 files changed, 75 insertions, 12 deletions
diff --git a/src/NDSCart.h b/src/NDSCart.h
index dcbc1eb..7d482ab 100644
--- a/src/NDSCart.h
+++ b/src/NDSCart.h
@@ -45,6 +45,7 @@ enum CartType
RetailIR = 0x103,
RetailBT = 0x104,
Homebrew = 0x201,
+ UnlicensedR4 = 0x301
};
class NDSCartSlot;
@@ -236,19 +237,13 @@ public:
u8 SPIWrite(u8 val, u32 pos, bool last) override;
};
-// CartHomebrew -- homebrew 'cart' (no SRAM, DLDI)
-class CartHomebrew : public CartCommon
+// CartSD -- any 'cart' with an SD card slot
+class CartSD : public CartCommon
{
public:
- CartHomebrew(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, std::optional<FATStorage>&& sdcard = std::nullopt);
- CartHomebrew(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, std::optional<FATStorage>&& sdcard = std::nullopt);
- ~CartHomebrew() override;
-
- void Reset() override;
- void SetupDirectBoot(const std::string& romname, NDS& nds) override;
-
- int ROMCommandStart(NDS& nds, NDSCart::NDSCartSlot& cartslot, const u8* cmd, u8* data, u32 len) override;
- void ROMCommandFinish(const u8* cmd, u8* data, u32 len) override;
+ CartSD(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, std::optional<FATStorage>&& sdcard = std::nullopt);
+ CartSD(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, std::optional<FATStorage>&& sdcard = std::nullopt);
+ ~CartSD() override;
[[nodiscard]] const std::optional<FATStorage>& GetSDCard() const noexcept { return SD; }
void SetSDCard(FATStorage&& sdcard) noexcept { SD = std::move(sdcard); }
@@ -260,7 +255,7 @@ public:
// it just leaves behind an optional with a moved-from value
}
-private:
+protected:
void ApplyDLDIPatchAt(u8* binary, u32 dldioffset, const u8* patch, u32 patchlen, bool readonly) const;
void ApplyDLDIPatch(const u8* patch, u32 patchlen, bool readonly);
void ReadROM_B7(u32 addr, u32 len, u8* data, u32 offset) const;
@@ -268,6 +263,74 @@ private:
std::optional<FATStorage> SD {};
};
+// CartHomebrew -- homebrew 'cart' (no SRAM, DLDI)
+class CartHomebrew : public CartSD
+{
+public:
+ CartHomebrew(const u8* rom, u32 len, u32 chipid, ROMListEntry romparams, std::optional<FATStorage>&& sdcard = std::nullopt);
+ CartHomebrew(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, std::optional<FATStorage>&& sdcard = std::nullopt);
+ ~CartHomebrew() override;
+
+ void Reset() override;
+ void SetupDirectBoot(const std::string& romname, NDS& nds) override;
+
+ int ROMCommandStart(NDS& nds, NDSCart::NDSCartSlot& cartslot, const u8* cmd, u8* data, u32 len) override;
+ void ROMCommandFinish(const u8* cmd, u8* data, u32 len) override;
+};
+
+// CartR4 -- unlicensed R4 'cart' (NDSCartR4.cpp)
+enum CartR4Type
+{
+ /* non-SDHC carts */
+ CartR4TypeM3Simply = 0,
+ CartR4TypeR4 = 1,
+ /* SDHC carts */
+ CartR4TypeAce3DS = 2
+};
+
+enum CartR4Language
+{
+ CartR4LanguageJapanese = (7 << 3) | 1,
+ CartR4LanguageEnglish = (7 << 3) | 2,
+ CartR4LanguageFrench = (2 << 3) | 2,
+ CartR4LanguageKorean = (4 << 3) | 2,
+ CartR4LanguageSimplifiedChinese = (6 << 3) | 3,
+ CartR4LanguageTraditionalChinese = (7 << 3) | 3
+};
+
+class CartR4 : public CartSD
+{
+public:
+ CartR4(std::unique_ptr<u8[]>&& rom, u32 len, u32 chipid, ROMListEntry romparams, CartR4Type ctype, CartR4Language clanguage,
+ std::optional<FATStorage>&& sdcard = std::nullopt);
+ ~CartR4() override;
+
+ void Reset() override;
+
+ void DoSavestate(Savestate* file) override;
+
+ int ROMCommandStart(NDS& nds, NDSCart::NDSCartSlot& cartslot, const u8* cmd, u8* data, u32 len) override;
+ void ROMCommandFinish(const u8* cmd, u8* data, u32 len) override;
+
+private:
+ inline u32 GetAdjustedSector(u32 sector) const
+ {
+ return R4CartType >= CartR4TypeAce3DS ? sector : sector >> 9;
+ }
+
+ u16 GetEncryptionKey(u16 sector);
+ void ReadSDToBuffer(u32 sector, bool rom);
+ u64 SDFATEntrySectorGet(u32 entry, u32 addr);
+
+ s32 EncryptionKey;
+ u32 FATEntryOffset[2];
+ u8 Buffer[512];
+ u8 InitStatus;
+ CartR4Type R4CartType;
+ CartR4Language CartLanguage;
+ bool BufferInitialized;
+};
+
class NDSCartSlot
{
public: