start work on NAND shito.

This commit is contained in:
StapleButter 2018-12-12 20:59:08 +01:00
parent 548432c364
commit 4d71da04ec
1 changed files with 134 additions and 74 deletions

View File

@ -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,81 +1218,34 @@ 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:
switch (cmd[0] & 0xF0) if (CmdEncMode == 1)
{ {
case 0x40: switch (cmd[0] & 0xF0)
DataEncMode = 2;
break;
case 0x10:
for (u32 pos = 0; pos < DataOutLen; pos += 4)
*(u32*)&DataOut[pos] = CartID;
break;
case 0x20:
{ {
u32 addr = (cmd[2] & 0xF0) << 8; case 0x40:
ReadROM(addr, 0x1000, 0); DataEncMode = 2;
} break;
break;
case 0xA0: case 0x10:
CmdEncMode = 2; for (u32 pos = 0; pos < DataOutLen; pos += 4)
break; *(u32*)&DataOut[pos] = CartID;
break;
case 0x20:
{
u32 addr = (cmd[2] & 0xF0) << 8;
ReadROM(addr, 0x1000, 0);
}
break;
case 0xA0:
CmdEncMode = 2;
break;
}
} }
else if (ROMCommandHandler)
ROMCommandHandler(cmd);
break; break;
} }