temp. stashing NAND work

This commit is contained in:
StapleButter 2018-12-13 02:12:47 +01:00
parent 4d71da04ec
commit 369e5381e2
4 changed files with 187 additions and 21 deletions

View File

@ -176,6 +176,22 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr)
//if (addr == 0x0201764C) printf("capture test %d: R1=%08X\n", R[6], R[1]); //if (addr == 0x0201764C) printf("capture test %d: R1=%08X\n", R[6], R[1]);
//if (addr == 0x020175D8) printf("capture test %d: res=%08X\n", R[6], R[0]); //if (addr == 0x020175D8) printf("capture test %d: res=%08X\n", R[6], R[0]);
// R0=DMA# R1=src R2=size // R0=DMA# R1=src R2=size
//if (addr==0x020612B8) printf("read NAND status, %08X\n", R[15]);
//if(addr==0x020614A4) printf("isnandgood_75, %08X\n", R[15]);
if (addr==0x0206176C) printf("NAND SHIT %08X %08X %08X %08X\n", R[0], R[1], R[2], R[3]);
if (addr==0x206185C) printf("BORK!! %08X\n", R[0]);
if (addr==0x02061144) printf("NAND WRITE SHIT %08X %08X %08X %08X\n", R[0], R[1], R[2], R[3]);
if (addr==0x0205D6F0)
{
printf("VERIFY %08X, %08X %08X %08X %08X\n", R[15], R[0], R[1], R[2], R[3]);
/*FILE* f = fopen("kaka.bin", "wb");
fwrite(&NDS::MainRAM[0x031371C], 0x800, 1, f);
fclose(f);*/
}
if (R[15]==0x0205D75C) printf("returned %d\n", R[0]);
if (R[15]==0x02061298) printf("RETURN FROM NAND WRITE %d\n", R[0]);
//if ((addr>=0x02061144 && addr<0x02061290) ||
// (R[15]>=0x0206114C && R[15]<0x02061298)) printf("!! %08X->%08X %d\n", R[15]-8, addr, R[0]);
u32 oldregion = R[15] >> 24; u32 oldregion = R[15] >> 24;
u32 newregion = addr >> 24; u32 newregion = addr >> 24;

View File

@ -2931,6 +2931,10 @@ void ARM9IOWrite32(u32 addr, u32 val)
PowerControl9 = val & 0xFFFF; PowerControl9 = val & 0xFFFF;
GPU::DisplaySwap(PowerControl9>>15); GPU::DisplaySwap(PowerControl9>>15);
return; return;
case 0x04100010:
if (!(ExMemCnt[0] & (1<<11))) NDSCart::WriteROMData(val);
return;
} }
if (addr >= 0x04000000 && addr < 0x04000060) if (addr >= 0x04000000 && addr < 0x04000060)
@ -3450,6 +3454,10 @@ void ARM7IOWrite32(u32 addr, u32 val)
if (ARM7BIOSProt == 0) if (ARM7BIOSProt == 0)
ARM7BIOSProt = val & 0xFFFE; ARM7BIOSProt = val & 0xFFFE;
return; return;
case 0x04100010:
if (ExMemCnt[0] & (1<<11)) NDSCart::WriteROMData(val);
return;
} }
if (addr >= 0x04000400 && addr < 0x04000520) if (addr >= 0x04000400 && addr < 0x04000520)

View File

@ -190,6 +190,16 @@ void RelocateSave(const char* path, bool write)
fclose(f); fclose(f);
} }
void Flush()
{
FILE* f = melon_fopen(SRAMPath, "wb");
if (f)
{
fwrite(SRAM, SRAMLength, 1, f);
fclose(f);
}
}
u8 Read() u8 Read()
{ {
return Data; return Data;
@ -443,12 +453,7 @@ void Write(u8 val, u32 hold)
if (islast && (CurCmd == 0x02 || CurCmd == 0x0A) && (SRAMLength > 0)) if (islast && (CurCmd == 0x02 || CurCmd == 0x0A) && (SRAMLength > 0))
{ {
FILE* f = melon_fopen(SRAMPath, "wb"); Flush();
if (f)
{
fwrite(SRAM, SRAMLength, 1, f);
fclose(f);
}
} }
} }
@ -986,6 +991,12 @@ bool LoadROM(const char* path, const char* sram, bool direct)
printf("Save file: %s\n", sram); printf("Save file: %s\n", sram);
NDSCart_SRAM::LoadSave(sram, romparams[1]); NDSCart_SRAM::LoadSave(sram, romparams[1]);
// extra NAND init
if (CartID & 0x08000000)
{
NDSCart_SRAM::StatusReg = 0x60;
}
return true; return true;
} }
@ -1027,16 +1038,40 @@ void ROMEndTransfer(u32 param)
if (SPICnt & (1<<14)) if (SPICnt & (1<<14))
NDS::SetIRQ((NDS::ExMemCnt[0]>>11)&0x1, NDS::IRQ_CartSendDone); NDS::SetIRQ((NDS::ExMemCnt[0]>>11)&0x1, NDS::IRQ_CartSendDone);
// NAND write end
if (CartID & 0x08000000)
{
if (NDSCart_SRAM::CurCmd == 0x81)
{
u32 addr = NDSCart_SRAM::Addr & (NDSCart_SRAM::SRAMLength-1);
u32 len = DataOutLen;
if ((addr+len) > NDSCart_SRAM::SRAMLength)
{
u32 len1 = NDSCart_SRAM::SRAMLength - addr;
memcpy(&NDSCart_SRAM::SRAM[addr], &DataOut[0], len1);
memcpy(&NDSCart_SRAM::SRAM[0], &DataOut[len1], len-len1);
}
else
memcpy(&NDSCart_SRAM::SRAM[addr], DataOut, len);
NDSCart_SRAM::Flush();
NDSCart_SRAM::Addr += len;
}
}
} }
void ROMPrepareData(u32 param) void ROMPrepareData(u32 param)
{ {
if (DataOutPos >= DataOutLen) if (!(ROMCnt & (1<<30)))
ROMDataOut = 0; {
else if (DataOutPos >= DataOutLen)
ROMDataOut = *(u32*)&DataOut[DataOutPos]; ROMDataOut = 0;
else
ROMDataOut = *(u32*)&DataOut[DataOutPos];
DataOutPos += 4; DataOutPos += 4;
}
ROMCnt |= (1<<23); ROMCnt |= (1<<23);
@ -1075,12 +1110,60 @@ void ROMCommand_Retail(u8* cmd)
void ROMCommand_RetailNAND(u8* cmd) void ROMCommand_RetailNAND(u8* cmd)
{ {
//if (cmd[0]!=0xB7) printf("NAND cmd %02X %08X %08X %04X\n", cmd[0], ((u32*)cmd)[0], ((u32*)cmd)[1], DataOutLen);
u8 prevcmd = NDSCart_SRAM::CurCmd;
NDSCart_SRAM::CurCmd = cmd[0];
switch (cmd[0]) switch (cmd[0])
{ {
case 0x81: // write
{
NDSCart_SRAM::StatusReg &= ~0x40;
u32 addr = (cmd[1]<<24) | (cmd[2]<<16) | (cmd[3]<<8) | cmd[4];
addr -= 0x07200000;
if (prevcmd != 0x81) NDSCart_SRAM::Addr = addr;
printf("write %08X (%08X)\n", NDSCart_SRAM::Addr, addr);
}
break;
case 0x82: // erase sector
{
NDSCart_SRAM::StatusReg &= ~0x40;
u32 addr = (cmd[1]<<24) | (cmd[2]<<16) | (cmd[3]<<8) | cmd[4];
addr -= 0x07200000;
printf("erase???? %08X\n", addr);
/*for (int i = 0; i < 0x200; i++)
{
NDSCart_SRAM::SRAM[addr & (NDSCart_SRAM::SRAMLength-1)] = 0;
addr++;
}
NDSCart_SRAM::Flush();*/
}
break;
case 0x84: // write disable
{
NDSCart_SRAM::StatusReg &= ~0x10;
}
break;
case 0x85: // write enable
{
NDSCart_SRAM::StatusReg |= 0x10;
}
break;
case 0x8B: // ??? set ROM mode??
{
NDSCart_SRAM::StatusReg |= 0x40;
}
break;
case 0x94: // NAND init case 0x94: // NAND init
{ {
// initial value: should have bit7 clear // initial value: should have bit7 clear
NDSCart_SRAM::StatusReg = 0; NDSCart_SRAM::StatusReg = 0x60;
// Jam with the Band stores words 6-9 of this at 0x02131BB0 // Jam with the Band stores words 6-9 of this at 0x02131BB0
// it doesn't seem to use those anywhere later // it doesn't seem to use those anywhere later
@ -1091,23 +1174,38 @@ void ROMCommand_RetailNAND(u8* cmd)
case 0xB2: // set savemem addr case 0xB2: // set savemem addr
{ {
NDSCart_SRAM::StatusReg |= 0x20; u32 addr = (cmd[1]<<24) | (cmd[2]<<16) | (cmd[3]<<8) | cmd[4];
addr -= 0x07200000;
NDSCart_SRAM::Addr = addr;
printf("seek %08X\n", addr);
NDSCart_SRAM::StatusReg &= ~0x40;
} }
break; break;
case 0xB7: case 0xB7:
{ {
u32 addr = (cmd[1]<<24) | (cmd[2]<<16) | (cmd[3]<<8) | cmd[4]; u32 addr = (cmd[1]<<24) | (cmd[2]<<16) | (cmd[3]<<8) | cmd[4];
memset(DataOut, 0, DataOutLen);
if (((addr + DataOutLen - 1) >> 12) != (addr >> 12)) if (!(NDSCart_SRAM::StatusReg & 0x40))
{ {
u32 len1 = 0x1000 - (addr & 0xFFF); addr -= 0x07200000;
ReadROM_B7(addr, len1, 0); printf("read %08X\n", addr);
ReadROM_B7(addr+len1, DataOutLen-len1, len1); addr &= (NDSCart_SRAM::SRAMLength-1);
memcpy(DataOut, &NDSCart_SRAM::SRAM[addr], DataOutLen);
} }
else else
ReadROM_B7(addr, DataOutLen, 0); {
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; break;
@ -1115,7 +1213,9 @@ void ROMCommand_RetailNAND(u8* cmd)
{ {
// status reg bits: // status reg bits:
// * bit7: busy? error? // * bit7: busy? error?
// * bit5: accessing savemem // * bit6: accessing ROM?
// * bit5: ??
// * bit4: write enable
for (u32 pos = 0; pos < DataOutLen; pos += 4) for (u32 pos = 0; pos < DataOutLen; pos += 4)
*(u32*)&DataOut[pos] = NDSCart_SRAM::StatusReg * 0x01010101; *(u32*)&DataOut[pos] = NDSCart_SRAM::StatusReg * 0x01010101;
@ -1123,7 +1223,7 @@ void ROMCommand_RetailNAND(u8* cmd)
break; break;
default: default:
printf("unknown NAND command %02X %04Xn", cmd[0], DataOutLen); printf("unknown NAND command %02X %04X\n", cmd[0], DataOutLen);
break; break;
} }
} }
@ -1269,6 +1369,12 @@ void WriteROMCnt(u32 val)
u32 ReadROMData() u32 ReadROMData()
{ {
if (ROMCnt & (1<<30))
{
printf("!! TRYING TO READ ROM DATA WHILE IN WRITE MODE\n");
return 0;
}
if (ROMCnt & (1<<23)) if (ROMCnt & (1<<23))
{ {
ROMCnt &= ~(1<<23); ROMCnt &= ~(1<<23);
@ -1288,6 +1394,41 @@ u32 ReadROMData()
return ROMDataOut; return ROMDataOut;
} }
void WriteROMData(u32 val)
{
if (!(ROMCnt & (1<<30)))
{
printf("!! TRYING TO WRITE ROM DATA WHILE IN READ MODE\n");
return;
}
// TODO: check all the ROM write logic against hardware
// write process, according to game code:
// * send command, set ROMCnt
// * wait for DRQ
// * write data
// * wait for DRQ, repeat
if (ROMCnt & (1<<23))
{
ROMCnt &= ~(1<<23);
*(u32*)&DataOut[DataOutPos] = val;
DataOutPos += 4;
if (DataOutPos < DataOutLen)
{
u32 xfercycle = (ROMCnt & (1<<27)) ? 8 : 5;
u32 delay = 4;
if (!(DataOutPos & 0x1FF)) delay += ((ROMCnt >> 16) & 0x3F);
NDS::ScheduleEvent(NDS::Event_ROMTransfer, true, xfercycle*delay, ROMPrepareData, 0);
}
else
ROMEndTransfer(0);
}
}
void WriteSPICnt(u16 val) void WriteSPICnt(u16 val)
{ {

View File

@ -49,6 +49,7 @@ void RelocateSave(const char* path, bool write);
void WriteROMCnt(u32 val); void WriteROMCnt(u32 val);
u32 ReadROMData(); u32 ReadROMData();
void WriteROMData(u32 val);
void WriteSPICnt(u16 val); void WriteSPICnt(u16 val);
u8 ReadSPIData(); u8 ReadSPIData();