start work on NAND shito.
This commit is contained in:
parent
548432c364
commit
4d71da04ec
172
src/NDSCart.cpp
172
src/NDSCart.cpp
|
@ -153,8 +153,8 @@ void LoadSave(const char* path, u32 type)
|
||||||
case 256*1024:
|
case 256*1024:
|
||||||
case 512*1024:
|
case 512*1024:
|
||||||
case 1024*1024:
|
case 1024*1024:
|
||||||
case 8192*1024:
|
case 8192*1024: WriteFunc = Write_Flash; break;
|
||||||
case 32768*1024: WriteFunc = Write_Flash; break;
|
case 32768*1024: WriteFunc = Write_Null; break; // NAND FLASH, handled differently
|
||||||
default:
|
default:
|
||||||
printf("!! BAD SAVE LENGTH %d\n", SRAMLength);
|
printf("!! BAD SAVE LENGTH %d\n", SRAMLength);
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -484,6 +484,12 @@ u64 Key2_X;
|
||||||
u64 Key2_Y;
|
u64 Key2_Y;
|
||||||
|
|
||||||
|
|
||||||
|
void ROMCommand_Retail(u8* cmd);
|
||||||
|
void ROMCommand_RetailNAND(u8* cmd);
|
||||||
|
|
||||||
|
void (*ROMCommandHandler)(u8* cmd);
|
||||||
|
|
||||||
|
|
||||||
u32 ByteSwap(u32 val)
|
u32 ByteSwap(u32 val)
|
||||||
{
|
{
|
||||||
return (val >> 24) | ((val >> 8) & 0xFF00) | ((val << 8) & 0xFF0000) | (val << 24);
|
return (val >> 24) | ((val >> 8) & 0xFF00) | ((val << 8) & 0xFF0000) | (val << 24);
|
||||||
|
@ -625,6 +631,8 @@ void Reset()
|
||||||
CartID = 0;
|
CartID = 0;
|
||||||
CartIsHomebrew = false;
|
CartIsHomebrew = false;
|
||||||
|
|
||||||
|
ROMCommandHandler = NULL;
|
||||||
|
|
||||||
CmdEncMode = 0;
|
CmdEncMode = 0;
|
||||||
DataEncMode = 0;
|
DataEncMode = 0;
|
||||||
|
|
||||||
|
@ -908,10 +916,22 @@ bool LoadROM(const char* path, const char* sram, bool direct)
|
||||||
else
|
else
|
||||||
printf("ROM entry: %08X %08X %08X\n", romparams[0], romparams[1], romparams[2]);
|
printf("ROM entry: %08X %08X %08X\n", romparams[0], romparams[1], romparams[2]);
|
||||||
|
|
||||||
|
if (romparams[0] != len) printf("!! bad ROM size %d (expected %d) rounded to %d\n", len, romparams[0], CartROMSize);
|
||||||
|
|
||||||
// generate a ROM ID
|
// generate a ROM ID
|
||||||
// note: most games don't check the actual value
|
// note: most games don't check the actual value
|
||||||
// it just has to stay the same throughout gameplay
|
// it just has to stay the same throughout gameplay
|
||||||
CartID = 0x00001FC2;
|
CartID = 0x000000C2;
|
||||||
|
|
||||||
|
if (CartROMSize <= 128*1024*1024)
|
||||||
|
CartID |= ((CartROMSize >> 20) - 1) << 8;
|
||||||
|
else
|
||||||
|
CartID |= (0x100 - (CartROMSize >> 28)) << 8;
|
||||||
|
|
||||||
|
if (romparams[1] == 8)
|
||||||
|
CartID |= 0x08000000; // NAND flag
|
||||||
|
|
||||||
|
printf("Cart ID: %08X\n", CartID);
|
||||||
|
|
||||||
if (*(u32*)&CartROM[0x20] < 0x4000)
|
if (*(u32*)&CartROM[0x20] < 0x4000)
|
||||||
{
|
{
|
||||||
|
@ -928,6 +948,12 @@ bool LoadROM(const char* path, const char* sram, bool direct)
|
||||||
|
|
||||||
CartInserted = true;
|
CartInserted = true;
|
||||||
|
|
||||||
|
// TODO: support more fancy cart types (homebrew?, flashcarts, etc)
|
||||||
|
if (CartID & 0x08000000)
|
||||||
|
ROMCommandHandler = ROMCommand_RetailNAND;
|
||||||
|
else
|
||||||
|
ROMCommandHandler = ROMCommand_Retail;
|
||||||
|
|
||||||
u32 arm9base = *(u32*)&CartROM[0x20];
|
u32 arm9base = *(u32*)&CartROM[0x20];
|
||||||
if (arm9base < 0x8000)
|
if (arm9base < 0x8000)
|
||||||
{
|
{
|
||||||
|
@ -1020,7 +1046,88 @@ void ROMPrepareData(u32 param)
|
||||||
NDS::CheckDMAs(0, 0x05);
|
NDS::CheckDMAs(0, 0x05);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 sc_addr = 0;
|
|
||||||
|
void ROMCommand_Retail(u8* cmd)
|
||||||
|
{
|
||||||
|
switch (cmd[0])
|
||||||
|
{
|
||||||
|
case 0xB7:
|
||||||
|
{
|
||||||
|
u32 addr = (cmd[1]<<24) | (cmd[2]<<16) | (cmd[3]<<8) | cmd[4];
|
||||||
|
memset(DataOut, 0, DataOutLen);
|
||||||
|
|
||||||
|
if (((addr + DataOutLen - 1) >> 12) != (addr >> 12))
|
||||||
|
{
|
||||||
|
u32 len1 = 0x1000 - (addr & 0xFFF);
|
||||||
|
ReadROM_B7(addr, len1, 0);
|
||||||
|
ReadROM_B7(addr+len1, DataOutLen-len1, len1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ReadROM_B7(addr, DataOutLen, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("unknown retail cart command %02X\n", cmd[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ROMCommand_RetailNAND(u8* cmd)
|
||||||
|
{
|
||||||
|
switch (cmd[0])
|
||||||
|
{
|
||||||
|
case 0x94: // NAND init
|
||||||
|
{
|
||||||
|
// initial value: should have bit7 clear
|
||||||
|
NDSCart_SRAM::StatusReg = 0;
|
||||||
|
|
||||||
|
// Jam with the Band stores words 6-9 of this at 0x02131BB0
|
||||||
|
// it doesn't seem to use those anywhere later
|
||||||
|
for (u32 pos = 0; pos < DataOutLen; pos += 4)
|
||||||
|
*(u32*)&DataOut[pos] = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xB2: // set savemem addr
|
||||||
|
{
|
||||||
|
NDSCart_SRAM::StatusReg |= 0x20;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xB7:
|
||||||
|
{
|
||||||
|
u32 addr = (cmd[1]<<24) | (cmd[2]<<16) | (cmd[3]<<8) | cmd[4];
|
||||||
|
memset(DataOut, 0, DataOutLen);
|
||||||
|
|
||||||
|
if (((addr + DataOutLen - 1) >> 12) != (addr >> 12))
|
||||||
|
{
|
||||||
|
u32 len1 = 0x1000 - (addr & 0xFFF);
|
||||||
|
ReadROM_B7(addr, len1, 0);
|
||||||
|
ReadROM_B7(addr+len1, DataOutLen-len1, len1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ReadROM_B7(addr, DataOutLen, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xD6: // NAND status
|
||||||
|
{
|
||||||
|
// status reg bits:
|
||||||
|
// * bit7: busy? error?
|
||||||
|
// * bit5: accessing savemem
|
||||||
|
|
||||||
|
for (u32 pos = 0; pos < DataOutLen; pos += 4)
|
||||||
|
*(u32*)&DataOut[pos] = NDSCart_SRAM::StatusReg * 0x01010101;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("unknown NAND command %02X %04Xn", cmd[0], DataOutLen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void WriteROMCnt(u32 val)
|
void WriteROMCnt(u32 val)
|
||||||
{
|
{
|
||||||
|
@ -1111,59 +1218,9 @@ void WriteROMCnt(u32 val)
|
||||||
if (CartInserted) CmdEncMode = 1;
|
if (CartInserted) CmdEncMode = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xB7:
|
|
||||||
{
|
|
||||||
u32 addr = (cmd[1]<<24) | (cmd[2]<<16) | (cmd[3]<<8) | cmd[4];
|
|
||||||
memset(DataOut, 0, DataOutLen);
|
|
||||||
|
|
||||||
if (((addr + DataOutLen - 1) >> 12) != (addr >> 12))
|
|
||||||
{
|
|
||||||
u32 len1 = 0x1000 - (addr & 0xFFF);
|
|
||||||
ReadROM_B7(addr, len1, 0);
|
|
||||||
ReadROM_B7(addr+len1, DataOutLen-len1, len1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ReadROM_B7(addr, DataOutLen, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
// SUPERCARD EMULATION TEST
|
|
||||||
// TODO: INTEGRATE BETTER!!!!
|
|
||||||
|
|
||||||
case 0x70: // init??? returns whether SDHC addressing should be used
|
|
||||||
for (u32 pos = 0; pos < DataOutLen; pos += 4)
|
|
||||||
*(u32*)&DataOut[pos] = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x53: // set address for read
|
|
||||||
sc_addr = (cmd[1]<<24) | (cmd[2]<<16) | (cmd[3]<<8) | cmd[4];
|
|
||||||
printf("SUPERCARD: read %08X\n", sc_addr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x80: // read operation busy, I guess
|
|
||||||
// TODO: make it take some time
|
|
||||||
for (u32 pos = 0; pos < DataOutLen; pos += 4)
|
|
||||||
*(u32*)&DataOut[pos] = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x81: // read data
|
|
||||||
{
|
|
||||||
if (DataOutLen != 0x200)
|
|
||||||
printf("SUPERCARD: BOGUS READ %d\n", DataOutLen);
|
|
||||||
|
|
||||||
// TODO: this is really inefficient. just testing
|
|
||||||
FILE* f = fopen("scsd.bin", "rb");
|
|
||||||
fseek(f, sc_addr, SEEK_SET);
|
|
||||||
fread(DataOut, 1, 0x200, f);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// SUPERCARD EMULATION TEST END
|
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (CmdEncMode == 1)
|
||||||
|
{
|
||||||
switch (cmd[0] & 0xF0)
|
switch (cmd[0] & 0xF0)
|
||||||
{
|
{
|
||||||
case 0x40:
|
case 0x40:
|
||||||
|
@ -1186,6 +1243,9 @@ void WriteROMCnt(u32 val)
|
||||||
CmdEncMode = 2;
|
CmdEncMode = 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (ROMCommandHandler)
|
||||||
|
ROMCommandHandler(cmd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue