aboutsummaryrefslogtreecommitdiff
path: root/src/NDSCart.cpp
diff options
context:
space:
mode:
authorArisotura <thetotalworm@gmail.com>2021-07-22 21:37:34 +0200
committerArisotura <thetotalworm@gmail.com>2021-07-22 21:37:34 +0200
commitcd4ef575ee6e85e607e9a26a38af9d69d1cc69f3 (patch)
treed13da5b03d04e28efb31030eaccca256f645e8d9 /src/NDSCart.cpp
parentab48461dc58dd10fe9a7983f8d6ba03c6c3e7c01 (diff)
NDSCart: correctly restrict reading the DSi region on DSi carts
Diffstat (limited to 'src/NDSCart.cpp')
-rw-r--r--src/NDSCart.cpp27
1 files changed, 19 insertions, 8 deletions
diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp
index 65bed2b..b87139a 100644
--- a/src/NDSCart.cpp
+++ b/src/NDSCart.cpp
@@ -193,6 +193,7 @@ CartCommon::CartCommon(u8* rom, u32 len, u32 chipid)
u8 unitcode = ROM[0x12];
IsDSi = (unitcode & 0x02) != 0;
+ DSiBase = *(u16*)&ROM[0x92] << 19;
}
CartCommon::~CartCommon()
@@ -203,12 +204,14 @@ void CartCommon::Reset()
{
CmdEncMode = 0;
DataEncMode = 0;
+ DSiMode = false;
}
void CartCommon::SetupDirectBoot()
{
CmdEncMode = 2;
DataEncMode = 2;
+ DSiMode = false; // TODO!!
}
void CartCommon::DoSavestate(Savestate* file)
@@ -217,6 +220,7 @@ void CartCommon::DoSavestate(Savestate* file)
file->Var32(&CmdEncMode);
file->Var32(&DataEncMode);
+ file->Bool32(&DSiMode);
}
void CartCommon::LoadSave(const char* path, u32 type)
@@ -266,13 +270,15 @@ int CartCommon::ROMCommandStart(u8* cmd, u8* data, u32 len)
case 0x3C:
CmdEncMode = 1;
Key1_InitKeycode(false, *(u32*)&ROM[0xC], 2, 2);
+ DSiMode = false;
return 0;
case 0x3D:
if (IsDSi)
{
- CmdEncMode = 11;
+ CmdEncMode = 1;
Key1_InitKeycode(true, *(u32*)&ROM[0xC], 1, 2);
+ DSiMode = true;
}
return 0;
@@ -280,7 +286,7 @@ int CartCommon::ROMCommandStart(u8* cmd, u8* data, u32 len)
return 0;
}
}
- else if (CmdEncMode == 1 || CmdEncMode == 11)
+ else if (CmdEncMode == 1)
{
// decrypt the KEY1 command as needed
// (KEY2 commands do not need decrypted because KEY2 is handled entirely by hardware,
@@ -309,14 +315,13 @@ int CartCommon::ROMCommandStart(u8* cmd, u8* data, u32 len)
case 0x20:
{
u32 addr = (cmddec[2] & 0xF0) << 8;
- if (CmdEncMode == 11)
+ if (DSiMode)
{
// the DSi region starts with 0x3000 unreadable bytes
// similarly to how the DS region starts at 0x1000 with 0x3000 unreadable bytes
// these contain data for KEY1 crypto
- u32 dsiregion = *(u16*)&ROM[0x92] << 19;
addr -= 0x1000;
- addr += dsiregion;
+ addr += DSiBase;
}
ReadROM(addr, 0x1000, data, 0);
}
@@ -597,9 +602,15 @@ void CartRetail::ReadROM_B7(u32 addr, u32 len, u8* data, u32 offset)
if (addr < 0x8000)
addr = 0x8000 + (addr & 0x1FF);
- // TODO: protect DSi secure area
- // also protect DSi region if not unlocked
- // and other security shenanigans
+ if (IsDSi && (addr >= DSiBase))
+ {
+ // for DSi carts:
+ // * in DSi mode: block the first 0x3000 bytes of the DSi area
+ // * in DS mode: block the entire DSi area
+
+ if ((!DSiMode) || (addr < (DSiBase+0x3000)))
+ addr = 0x8000 + (addr & 0x1FF);
+ }
memcpy(data+offset, ROM+addr, len);
}