support DSi-mode carts
except they need to have the DSi-mode shit encrypted
This commit is contained in:
parent
a9f36929e0
commit
36c741241a
27
src/DSi.cpp
27
src/DSi.cpp
|
@ -22,6 +22,7 @@
|
||||||
#include "DSi.h"
|
#include "DSi.h"
|
||||||
#include "ARM.h"
|
#include "ARM.h"
|
||||||
#include "GPU.h"
|
#include "GPU.h"
|
||||||
|
#include "NDSCart.h"
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
|
|
||||||
#include "DSi_NDMA.h"
|
#include "DSi_NDMA.h"
|
||||||
|
@ -581,6 +582,22 @@ void MapNWRAMRange(u32 cpu, u32 num, u32 val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Set_SCFG_MC(u32 val)
|
||||||
|
{
|
||||||
|
u32 oldslotstatus = SCFG_MC & 0xC;
|
||||||
|
|
||||||
|
val &= 0xFFFF800C;
|
||||||
|
if ((val & 0xC) == 0xC) val &= ~0xC; // hax
|
||||||
|
if (val & 0x8000) printf("SCFG_MC: weird NDS slot swap\n");
|
||||||
|
SCFG_MC = (SCFG_MC & ~0xFFFF800C) | val;
|
||||||
|
|
||||||
|
if ((oldslotstatus == 0x0) && ((SCFG_MC & 0xC) == 0x4))
|
||||||
|
{
|
||||||
|
NDSCart::ResetCart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
u8 ARM9Read8(u32 addr)
|
u8 ARM9Read8(u32 addr)
|
||||||
{
|
{
|
||||||
switch (addr & 0xFF000000)
|
switch (addr & 0xFF000000)
|
||||||
|
@ -1455,10 +1472,7 @@ void ARM7IOWrite16(u32 addr, u16 val)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x04004010:
|
case 0x04004010:
|
||||||
val &= 0x800C;
|
Set_SCFG_MC((SCFG_MC & 0xFFFF0000) | val);
|
||||||
if ((val & 0xC) == 0xC) val &= ~0xC; // hax
|
|
||||||
if (val & 0x8000) printf("SCFG_MC: weird NDS slot swap\n");
|
|
||||||
SCFG_MC = (SCFG_MC & ~0x800C) | val;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1491,10 +1505,7 @@ void ARM7IOWrite32(u32 addr, u32 val)
|
||||||
printf("SCFG_EXT = %08X / %08X (val7 %08X)\n", SCFG_EXT[0], SCFG_EXT[1], val);
|
printf("SCFG_EXT = %08X / %08X (val7 %08X)\n", SCFG_EXT[0], SCFG_EXT[1], val);
|
||||||
return;
|
return;
|
||||||
case 0x04004010:
|
case 0x04004010:
|
||||||
val &= 0xFFFF800C;
|
Set_SCFG_MC(val);
|
||||||
if ((val & 0xC) == 0xC) val &= ~0xC; // hax
|
|
||||||
if (val & 0x8000) printf("SCFG_MC: weird NDS slot swap\n");
|
|
||||||
SCFG_MC = (SCFG_MC & ~0xFFFF800C) | val;
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x04004054: MapNWRAMRange(1, 0, val); return;
|
case 0x04004054: MapNWRAMRange(1, 0, val); return;
|
||||||
|
|
|
@ -32,6 +32,7 @@ extern DSi_SDHost* SDMMC;
|
||||||
extern DSi_SDHost* SDIO;
|
extern DSi_SDHost* SDIO;
|
||||||
|
|
||||||
extern u8 ITCMInit[0x8000];
|
extern u8 ITCMInit[0x8000];
|
||||||
|
extern u8 ARM7Init[0x3C00];
|
||||||
|
|
||||||
|
|
||||||
bool Init();
|
bool Init();
|
||||||
|
|
|
@ -191,7 +191,7 @@ void DSi_SDHost::FinishSend(u32 param)
|
||||||
|
|
||||||
u32 DSi_SDHost::SendData(u8* data, u32 len)
|
u32 DSi_SDHost::SendData(u8* data, u32 len)
|
||||||
{
|
{
|
||||||
printf("%s: data RX, len=%d, blkcnt=%d (%d) blklen=%d, irq=%08X\n", SD_DESC, len, BlockCount16, BlockCountInternal, BlockLen16, IRQMask);
|
//printf("%s: data RX, len=%d, blkcnt=%d (%d) blklen=%d, irq=%08X\n", SD_DESC, len, BlockCount16, BlockCountInternal, BlockLen16, IRQMask);
|
||||||
if (len != BlockLen16) { printf("!! BAD BLOCKLEN\n"); len = BlockLen16; }
|
if (len != BlockLen16) { printf("!! BAD BLOCKLEN\n"); len = BlockLen16; }
|
||||||
|
|
||||||
bool last = (BlockCountInternal == 0);
|
bool last = (BlockCountInternal == 0);
|
||||||
|
@ -796,7 +796,7 @@ void DSi_MMCStorage::ContinueTransfer()
|
||||||
|
|
||||||
u32 DSi_MMCStorage::ReadBlock(u64 addr)
|
u32 DSi_MMCStorage::ReadBlock(u64 addr)
|
||||||
{
|
{
|
||||||
printf("SD/MMC: reading block @ %08X, len=%08X\n", addr, BlockSize);
|
//printf("SD/MMC: reading block @ %08X, len=%08X\n", addr, BlockSize);
|
||||||
|
|
||||||
u32 len = BlockSize;
|
u32 len = BlockSize;
|
||||||
len = Host->GetTransferrableLen(len);
|
len = Host->GetTransferrableLen(len);
|
||||||
|
|
|
@ -475,6 +475,7 @@ u32 CartROMSize;
|
||||||
u32 CartCRC;
|
u32 CartCRC;
|
||||||
u32 CartID;
|
u32 CartID;
|
||||||
bool CartIsHomebrew;
|
bool CartIsHomebrew;
|
||||||
|
bool CartIsDSi;
|
||||||
|
|
||||||
u32 CmdEncMode;
|
u32 CmdEncMode;
|
||||||
u32 DataEncMode;
|
u32 DataEncMode;
|
||||||
|
@ -557,10 +558,13 @@ void Key1_ApplyKeycode(u32* keycode, u32 mod)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Key1_InitKeycode(u32 idcode, u32 level, u32 mod)
|
void Key1_InitKeycode(bool dsi, u32 idcode, u32 level, u32 mod)
|
||||||
{
|
{
|
||||||
//memcpy(Key1_KeyBuf, &NDS::ARM7BIOS[0x30], 0x1048); // hax
|
//memcpy(Key1_KeyBuf, &NDS::ARM7BIOS[0x30], 0x1048); // hax
|
||||||
memcpy(Key1_KeyBuf, &DSi::ITCMInit[0x4894], 0x1048); // hax
|
if (dsi)
|
||||||
|
memcpy(Key1_KeyBuf, &DSi::ARM7Init[0x254], 0x1048); // hax
|
||||||
|
else
|
||||||
|
memcpy(Key1_KeyBuf, &DSi::ITCMInit[0x4894], 0x1048); // hax
|
||||||
|
|
||||||
u32 keycode[3] = {idcode, idcode>>1, idcode<<1};
|
u32 keycode[3] = {idcode, idcode>>1, idcode<<1};
|
||||||
if (level >= 1) Key1_ApplyKeycode(keycode, mod);
|
if (level >= 1) Key1_ApplyKeycode(keycode, mod);
|
||||||
|
@ -613,32 +617,19 @@ void DeInit()
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
SPICnt = 0;
|
|
||||||
ROMCnt = 0;
|
|
||||||
|
|
||||||
memset(ROMCommand, 0, 8);
|
|
||||||
ROMDataOut = 0;
|
|
||||||
|
|
||||||
Key2_X = 0;
|
|
||||||
Key2_Y = 0;
|
|
||||||
|
|
||||||
memset(DataOut, 0, 0x4000);
|
|
||||||
DataOutPos = 0;
|
|
||||||
DataOutLen = 0;
|
|
||||||
|
|
||||||
CartInserted = false;
|
CartInserted = false;
|
||||||
if (CartROM) delete[] CartROM;
|
if (CartROM) delete[] CartROM;
|
||||||
CartROM = NULL;
|
CartROM = NULL;
|
||||||
CartROMSize = 0;
|
CartROMSize = 0;
|
||||||
CartID = 0;
|
CartID = 0;
|
||||||
CartIsHomebrew = false;
|
CartIsHomebrew = false;
|
||||||
|
CartIsDSi = false;
|
||||||
|
|
||||||
ROMCommandHandler = NULL;
|
ROMCommandHandler = NULL;
|
||||||
|
|
||||||
CmdEncMode = 0;
|
|
||||||
DataEncMode = 0;
|
|
||||||
|
|
||||||
NDSCart_SRAM::Reset();
|
NDSCart_SRAM::Reset();
|
||||||
|
|
||||||
|
ResetCart();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoSavestate(Savestate* file)
|
void DoSavestate(Savestate* file)
|
||||||
|
@ -893,6 +884,11 @@ bool LoadROM(const char* path, const char* sram, bool direct)
|
||||||
fread(&gamecode, 4, 1, f);
|
fread(&gamecode, 4, 1, f);
|
||||||
printf("Game code: %c%c%c%c\n", gamecode&0xFF, (gamecode>>8)&0xFF, (gamecode>>16)&0xFF, gamecode>>24);
|
printf("Game code: %c%c%c%c\n", gamecode&0xFF, (gamecode>>8)&0xFF, (gamecode>>16)&0xFF, gamecode>>24);
|
||||||
|
|
||||||
|
u8 unitcode;
|
||||||
|
fseek(f, 0x12, SEEK_SET);
|
||||||
|
fread(&unitcode, 1, 1, f);
|
||||||
|
CartIsDSi = (unitcode & 0x02) != 0;
|
||||||
|
|
||||||
CartROM = new u8[CartROMSize];
|
CartROM = new u8[CartROMSize];
|
||||||
memset(CartROM, 0, CartROMSize);
|
memset(CartROM, 0, CartROMSize);
|
||||||
fseek(f, 0, SEEK_SET);
|
fseek(f, 0, SEEK_SET);
|
||||||
|
@ -934,6 +930,9 @@ bool LoadROM(const char* path, const char* sram, bool direct)
|
||||||
if (romparams[1] == 8)
|
if (romparams[1] == 8)
|
||||||
CartID |= 0x08000000; // NAND flag
|
CartID |= 0x08000000; // NAND flag
|
||||||
|
|
||||||
|
if (CartIsDSi)
|
||||||
|
CartID |= 0x40000000;
|
||||||
|
|
||||||
printf("Cart ID: %08X\n", CartID);
|
printf("Cart ID: %08X\n", CartID);
|
||||||
|
|
||||||
if (*(u32*)&CartROM[0x20] < 0x4000)
|
if (*(u32*)&CartROM[0x20] < 0x4000)
|
||||||
|
@ -969,11 +968,11 @@ bool LoadROM(const char* path, const char* sram, bool direct)
|
||||||
|
|
||||||
strncpy((char*)&CartROM[arm9base], "encryObj", 8);
|
strncpy((char*)&CartROM[arm9base], "encryObj", 8);
|
||||||
|
|
||||||
Key1_InitKeycode(gamecode, 3, 2);
|
Key1_InitKeycode(false, gamecode, 3, 2);
|
||||||
for (u32 i = 0; i < 0x800; i += 8)
|
for (u32 i = 0; i < 0x800; i += 8)
|
||||||
Key1_Encrypt((u32*)&CartROM[arm9base + i]);
|
Key1_Encrypt((u32*)&CartROM[arm9base + i]);
|
||||||
|
|
||||||
Key1_InitKeycode(gamecode, 2, 2);
|
Key1_InitKeycode(false, gamecode, 2, 2);
|
||||||
Key1_Encrypt((u32*)&CartROM[arm9base]);
|
Key1_Encrypt((u32*)&CartROM[arm9base]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -981,9 +980,6 @@ bool LoadROM(const char* path, const char* sram, bool direct)
|
||||||
CartIsHomebrew = true;
|
CartIsHomebrew = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// encryption
|
|
||||||
Key1_InitKeycode(gamecode, 2, 2);
|
|
||||||
|
|
||||||
|
|
||||||
// save
|
// save
|
||||||
printf("Save file: %s\n", sram);
|
printf("Save file: %s\n", sram);
|
||||||
|
@ -998,6 +994,27 @@ void RelocateSave(const char* path, bool write)
|
||||||
NDSCart_SRAM::RelocateSave(path, write);
|
NDSCart_SRAM::RelocateSave(path, write);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResetCart()
|
||||||
|
{
|
||||||
|
// CHECKME: what if there is a transfer in progress?
|
||||||
|
|
||||||
|
SPICnt = 0;
|
||||||
|
ROMCnt = 0;
|
||||||
|
|
||||||
|
memset(ROMCommand, 0, 8);
|
||||||
|
ROMDataOut = 0;
|
||||||
|
|
||||||
|
Key2_X = 0;
|
||||||
|
Key2_Y = 0;
|
||||||
|
|
||||||
|
memset(DataOut, 0, 0x4000);
|
||||||
|
DataOutPos = 0;
|
||||||
|
DataOutLen = 0;
|
||||||
|
|
||||||
|
CmdEncMode = 0;
|
||||||
|
DataEncMode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void ReadROM(u32 addr, u32 len, u32 offset)
|
void ReadROM(u32 addr, u32 len, u32 offset)
|
||||||
{
|
{
|
||||||
if (!CartInserted) return;
|
if (!CartInserted) return;
|
||||||
|
@ -1172,7 +1189,7 @@ void WriteROMCnt(u32 val)
|
||||||
// handle KEY1 encryption as needed.
|
// handle KEY1 encryption as needed.
|
||||||
// KEY2 encryption is implemented in hardware and doesn't need to be handled.
|
// KEY2 encryption is implemented in hardware and doesn't need to be handled.
|
||||||
u8 cmd[8];
|
u8 cmd[8];
|
||||||
if (CmdEncMode == 1)
|
if (CmdEncMode == 1 || CmdEncMode == 11)
|
||||||
{
|
{
|
||||||
*(u32*)&cmd[0] = ByteSwap(*(u32*)&ROMCommand[4]);
|
*(u32*)&cmd[0] = ByteSwap(*(u32*)&ROMCommand[4]);
|
||||||
*(u32*)&cmd[4] = ByteSwap(*(u32*)&ROMCommand[0]);
|
*(u32*)&cmd[4] = ByteSwap(*(u32*)&ROMCommand[0]);
|
||||||
|
@ -1218,11 +1235,23 @@ void WriteROMCnt(u32 val)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x3C:
|
case 0x3C:
|
||||||
if (CartInserted) CmdEncMode = 1;
|
if (CartInserted)
|
||||||
|
{
|
||||||
|
CmdEncMode = 1;
|
||||||
|
Key1_InitKeycode(false, *(u32*)&CartROM[0xC], 2, 2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x3D:
|
||||||
|
if (CartInserted && CartIsDSi)
|
||||||
|
{
|
||||||
|
CmdEncMode = 11;
|
||||||
|
Key1_InitKeycode(true, *(u32*)&CartROM[0xC], 1, 2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (CmdEncMode == 1)
|
if (CmdEncMode == 1 || CmdEncMode == 11)
|
||||||
{
|
{
|
||||||
switch (cmd[0] & 0xF0)
|
switch (cmd[0] & 0xF0)
|
||||||
{
|
{
|
||||||
|
@ -1238,6 +1267,12 @@ void WriteROMCnt(u32 val)
|
||||||
case 0x20:
|
case 0x20:
|
||||||
{
|
{
|
||||||
u32 addr = (cmd[2] & 0xF0) << 8;
|
u32 addr = (cmd[2] & 0xF0) << 8;
|
||||||
|
if (CmdEncMode == 11)
|
||||||
|
{
|
||||||
|
u32 arm9i_base = *(u32*)&CartROM[0x1C0];
|
||||||
|
addr -= 0x4000;
|
||||||
|
addr += arm9i_base;
|
||||||
|
}
|
||||||
ReadROM(addr, 0x1000, 0);
|
ReadROM(addr, 0x1000, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -47,6 +47,8 @@ void DoSavestate(Savestate* file);
|
||||||
bool LoadROM(const char* path, const char* sram, bool direct);
|
bool LoadROM(const char* path, const char* sram, bool direct);
|
||||||
void RelocateSave(const char* path, bool write);
|
void RelocateSave(const char* path, bool write);
|
||||||
|
|
||||||
|
void ResetCart();
|
||||||
|
|
||||||
void WriteROMCnt(u32 val);
|
void WriteROMCnt(u32 val);
|
||||||
u32 ReadROMData();
|
u32 ReadROMData();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue