mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-23 14:19:55 -06:00
* some fixes to SD controller support, make it clear that there is no SD inserted, makes Flipnote work somewhat better
* immediately clear AES busy flag when the block count is zero (occurs when loading DSi cart games) * implement NDMA start modes that have an old-DMA equivalent (except for GXFIFO mode) now it boots DSi carts!
This commit is contained in:
16
src/DSi.cpp
16
src/DSi.cpp
@ -411,6 +411,16 @@ void StallNDMAs()
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NDMAsInMode(u32 cpu, u32 mode)
|
||||||
|
{
|
||||||
|
cpu <<= 2;
|
||||||
|
if (NDMAs[cpu+0]->IsInMode(mode)) return true;
|
||||||
|
if (NDMAs[cpu+1]->IsInMode(mode)) return true;
|
||||||
|
if (NDMAs[cpu+2]->IsInMode(mode)) return true;
|
||||||
|
if (NDMAs[cpu+3]->IsInMode(mode)) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool NDMAsRunning(u32 cpu)
|
bool NDMAsRunning(u32 cpu)
|
||||||
{
|
{
|
||||||
cpu <<= 2;
|
cpu <<= 2;
|
||||||
@ -1156,7 +1166,7 @@ u8 ARM9IORead8(u32 addr)
|
|||||||
|
|
||||||
return NDS::ARM9IORead8(addr);
|
return NDS::ARM9IORead8(addr);
|
||||||
}
|
}
|
||||||
|
//u16 dicks = 0;
|
||||||
u16 ARM9IORead16(u32 addr)
|
u16 ARM9IORead16(u32 addr)
|
||||||
{
|
{
|
||||||
switch (addr)
|
switch (addr)
|
||||||
@ -1174,6 +1184,8 @@ u16 ARM9IORead16(u32 addr)
|
|||||||
CASE_READ16_32BIT(0x04004058, MBK[0][6])
|
CASE_READ16_32BIT(0x04004058, MBK[0][6])
|
||||||
CASE_READ16_32BIT(0x0400405C, MBK[0][7])
|
CASE_READ16_32BIT(0x0400405C, MBK[0][7])
|
||||||
CASE_READ16_32BIT(0x04004060, MBK[0][8])
|
CASE_READ16_32BIT(0x04004060, MBK[0][8])
|
||||||
|
|
||||||
|
//case 0x04004202: return dicks & 0xEF1F;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NDS::ARM9IORead16(addr);
|
return NDS::ARM9IORead16(addr);
|
||||||
@ -1318,6 +1330,8 @@ void ARM9IOWrite16(u32 addr, u16 val)
|
|||||||
MapNWRAM_C(6, val & 0xFF);
|
MapNWRAM_C(6, val & 0xFF);
|
||||||
MapNWRAM_C(7, val >> 8);
|
MapNWRAM_C(7, val >> 8);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
//case 0x04004202: dicks = val & 0xEF3F; return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NDS::ARM9IOWrite16(addr, val);
|
return NDS::ARM9IOWrite16(addr, val);
|
||||||
|
@ -47,6 +47,7 @@ bool LoadNAND();
|
|||||||
|
|
||||||
void RunNDMAs(u32 cpu);
|
void RunNDMAs(u32 cpu);
|
||||||
void StallNDMAs();
|
void StallNDMAs();
|
||||||
|
bool NDMAsInMode(u32 cpu, u32 mode);
|
||||||
bool NDMAsRunning(u32 cpu);
|
bool NDMAsRunning(u32 cpu);
|
||||||
void CheckNDMAs(u32 cpu, u32 mode);
|
void CheckNDMAs(u32 cpu, u32 mode);
|
||||||
void StopNDMAs(u32 cpu, u32 mode);
|
void StopNDMAs(u32 cpu, u32 mode);
|
||||||
|
@ -129,28 +129,8 @@ void Reset()
|
|||||||
memset(CurKey, 0, sizeof(CurKey));
|
memset(CurKey, 0, sizeof(CurKey));
|
||||||
memset(CurMAC, 0, sizeof(CurMAC));
|
memset(CurMAC, 0, sizeof(CurMAC));
|
||||||
|
|
||||||
// initialize keys, as per GBAtek
|
// initialize keys
|
||||||
|
|
||||||
#if 0
|
|
||||||
// slot 0: modcrypt
|
|
||||||
*(u32*)&KeyX[0][0] = 0x746E694E;
|
|
||||||
*(u32*)&KeyX[0][4] = 0x6F646E65;
|
|
||||||
|
|
||||||
// slot 1: 'Tad'/dev.kp
|
|
||||||
*(u32*)&KeyX[1][0] = 0x4E00004A;
|
|
||||||
*(u32*)&KeyX[1][4] = 0x4A00004E;
|
|
||||||
*(u32*)&KeyX[1][8] = (u32)(DSi::ConsoleID >> 32) ^ 0xC80C4B72;
|
|
||||||
*(u32*)&KeyX[1][12] = (u32)DSi::ConsoleID;
|
|
||||||
|
|
||||||
// slot 3: console-unique eMMC crypto
|
|
||||||
*(u32*)&KeyX[3][0] = (u32)DSi::ConsoleID;
|
|
||||||
*(u32*)&KeyX[3][4] = (u32)DSi::ConsoleID ^ 0x24EE6906;
|
|
||||||
*(u32*)&KeyX[3][8] = (u32)(DSi::ConsoleID >> 32) ^ 0xE65B601D;
|
|
||||||
*(u32*)&KeyX[3][12] = (u32)(DSi::ConsoleID >> 32);
|
|
||||||
*(u32*)&KeyY[3][0] = 0x0AB9DC76;
|
|
||||||
*(u32*)&KeyY[3][4] = 0xBD4DC4D3;
|
|
||||||
*(u32*)&KeyY[3][8] = 0x202DDD1D;
|
|
||||||
#endif
|
|
||||||
FILE* f = Platform::OpenLocalFile("aeskeys.bin", "rb");
|
FILE* f = Platform::OpenLocalFile("aeskeys.bin", "rb");
|
||||||
if (f)
|
if (f)
|
||||||
{
|
{
|
||||||
@ -233,12 +213,12 @@ u32 ReadCnt()
|
|||||||
|
|
||||||
ret |= InputFIFO->Level();
|
ret |= InputFIFO->Level();
|
||||||
ret |= (OutputFIFO->Level() << 5);
|
ret |= (OutputFIFO->Level() << 5);
|
||||||
|
//printf("READ AES CNT: %08X, LEVELS: IN=%d OUT=%d\n", ret, InputFIFO->Level(), OutputFIFO->Level());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteCnt(u32 val)
|
void WriteCnt(u32 val)
|
||||||
{
|
{printf("AES CNT = %08X\n", val);
|
||||||
u32 oldcnt = Cnt;
|
u32 oldcnt = Cnt;
|
||||||
Cnt = val & 0xFC1FF000;
|
Cnt = val & 0xFC1FF000;
|
||||||
|
|
||||||
@ -267,41 +247,51 @@ void WriteCnt(u32 val)
|
|||||||
// transfer start (checkme)
|
// transfer start (checkme)
|
||||||
RemBlocks = BlkCnt >> 16;
|
RemBlocks = BlkCnt >> 16;
|
||||||
|
|
||||||
u8 key[16];
|
if (RemBlocks > 0)
|
||||||
u8 iv[16];
|
|
||||||
|
|
||||||
Swap16(key, CurKey);
|
|
||||||
Swap16(iv, IV);
|
|
||||||
|
|
||||||
if (AESMode < 2)
|
|
||||||
{
|
{
|
||||||
if (BlkCnt & 0xFFFF) printf("AES: CCM EXTRA LEN TODO\n");
|
u8 key[16];
|
||||||
|
u8 iv[16];
|
||||||
|
|
||||||
u32 maclen = (val >> 16) & 0x7;
|
Swap16(key, CurKey);
|
||||||
if (maclen < 1) maclen = 1;
|
Swap16(iv, IV);
|
||||||
|
|
||||||
iv[0] = 0x02;
|
if (AESMode < 2)
|
||||||
for (int i = 0; i < 12; i++) iv[1+i] = iv[4+i];
|
{
|
||||||
iv[13] = 0x00;
|
if (BlkCnt & 0xFFFF) printf("AES: CCM EXTRA LEN TODO\n");
|
||||||
iv[14] = 0x00;
|
|
||||||
iv[15] = 0x01;
|
|
||||||
|
|
||||||
AES_init_ctx_iv(&Ctx, key, iv);
|
u32 maclen = (val >> 16) & 0x7;
|
||||||
|
if (maclen < 1) maclen = 1;
|
||||||
|
|
||||||
iv[0] |= (maclen << 3) | ((BlkCnt & 0xFFFF) ? (1<<6) : 0);
|
iv[0] = 0x02;
|
||||||
iv[13] = RemBlocks >> 12;
|
for (int i = 0; i < 12; i++) iv[1+i] = iv[4+i];
|
||||||
iv[14] = RemBlocks >> 4;
|
iv[13] = 0x00;
|
||||||
iv[15] = RemBlocks << 4;
|
iv[14] = 0x00;
|
||||||
|
iv[15] = 0x01;
|
||||||
|
|
||||||
memcpy(CurMAC, iv, 16);
|
AES_init_ctx_iv(&Ctx, key, iv);
|
||||||
AES_ECB_encrypt(&Ctx, CurMAC);
|
|
||||||
|
iv[0] |= (maclen << 3) | ((BlkCnt & 0xFFFF) ? (1<<6) : 0);
|
||||||
|
iv[13] = RemBlocks >> 12;
|
||||||
|
iv[14] = RemBlocks >> 4;
|
||||||
|
iv[15] = RemBlocks << 4;
|
||||||
|
|
||||||
|
memcpy(CurMAC, iv, 16);
|
||||||
|
AES_ECB_encrypt(&Ctx, CurMAC);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AES_init_ctx_iv(&Ctx, key, iv);
|
||||||
|
}
|
||||||
|
|
||||||
|
DSi::CheckNDMAs(1, 0x2A);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AES_init_ctx_iv(&Ctx, key, iv);
|
// no blocks to process? oh well. mark it finished
|
||||||
}
|
// CHECKME: does this trigger any IRQ or shit?
|
||||||
|
|
||||||
DSi::CheckNDMAs(1, 0x2A);
|
Cnt &= ~(1<<31);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("AES CNT: %08X / mode=%d key=%d inDMA=%d outDMA=%d blocks=%d\n",
|
printf("AES CNT: %08X / mode=%d key=%d inDMA=%d outDMA=%d blocks=%d\n",
|
||||||
@ -309,7 +299,7 @@ void WriteCnt(u32 val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WriteBlkCnt(u32 val)
|
void WriteBlkCnt(u32 val)
|
||||||
{
|
{printf("AES BLOCK CNT %08X / %d\n", val, val>>16);
|
||||||
BlkCnt = val;
|
BlkCnt = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,7 +405,7 @@ void Update()
|
|||||||
// CHECKME
|
// CHECKME
|
||||||
Cnt &= ~(1<<21);
|
Cnt &= ~(1<<21);
|
||||||
}
|
}
|
||||||
|
printf("AES: FINISHED\n");
|
||||||
Cnt &= ~(1<<31);
|
Cnt &= ~(1<<31);
|
||||||
if (Cnt & (1<<30)) NDS::SetIRQ2(NDS::IRQ2_DSi_AES);
|
if (Cnt & (1<<30)) NDS::SetIRQ2(NDS::IRQ2_DSi_AES);
|
||||||
DSi::StopNDMAs(1, 0x2A);
|
DSi::StopNDMAs(1, 0x2A);
|
||||||
|
@ -101,8 +101,10 @@ void DSi_NDMA::WriteCnt(u32 val)
|
|||||||
Start();
|
Start();
|
||||||
|
|
||||||
if (StartMode != 0x10 && StartMode != 0x30 &&
|
if (StartMode != 0x10 && StartMode != 0x30 &&
|
||||||
StartMode != 0x2A && StartMode != 0x2B)
|
StartMode != 0x04 && StartMode != 0x06 && StartMode != 0x07 && StartMode != 0x08 && StartMode != 0x09 &&
|
||||||
printf("UNIMPLEMENTED ARM%d NDMA%d START MODE %02X, %08X->%08X\n", CPU?7:9, Num, StartMode, SrcAddr, DstAddr);
|
StartMode != 0x24 && StartMode != 0x26 && StartMode != 0x28 && StartMode != 0x29 && StartMode != 0x2A && StartMode != 0x2B)
|
||||||
|
printf("UNIMPLEMENTED ARM%d NDMA%d START MODE %02X, %08X->%08X LEN=%d BLK=%d CNT=%08X\n",
|
||||||
|
CPU?7:9, Num, StartMode, SrcAddr, DstAddr, TotalLength, BlockLength, Cnt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,10 +91,16 @@ void DSi_SDHost::Reset()
|
|||||||
|
|
||||||
if (Num == 0)
|
if (Num == 0)
|
||||||
{
|
{
|
||||||
|
// TODO: eventually pull from host filesystem
|
||||||
|
/*DSi_MMCStorage* sd = new DSi_MMCStorage(this, false, "sd.bin");
|
||||||
|
u8 sd_cid[16] = {0xBD, 0x12, 0x34, 0x56, 0x78, 0x03, 0x4D, 0x30, 0x30, 0x46, 0x50, 0x41, 0x00, 0x00, 0x15, 0x00};
|
||||||
|
sd->SetCID(sd_cid);*/
|
||||||
|
DSi_MMCStorage* sd = NULL;
|
||||||
|
|
||||||
DSi_MMCStorage* mmc = new DSi_MMCStorage(this, true, "nand.bin");
|
DSi_MMCStorage* mmc = new DSi_MMCStorage(this, true, "nand.bin");
|
||||||
mmc->SetCID(DSi::eMMC_CID);
|
mmc->SetCID(DSi::eMMC_CID);
|
||||||
|
|
||||||
// TODO: port 0 (SD)
|
Ports[0] = sd;
|
||||||
Ports[1] = mmc;
|
Ports[1] = mmc;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -196,6 +202,14 @@ void DSi_SDHost::FinishSend(u32 param)
|
|||||||
host->ClearIRQ(25);
|
host->ClearIRQ(25);
|
||||||
host->SetIRQ(24);
|
host->SetIRQ(24);
|
||||||
//if (param & 0x2) host->SetIRQ(2);
|
//if (param & 0x2) host->SetIRQ(2);
|
||||||
|
|
||||||
|
// TODO: this is an assumption and should eventually be confirmed
|
||||||
|
// Flipnote sets DMA blocklen to 128 words and totallen to 1024 words
|
||||||
|
// so, presumably, DMA should trigger when the FIFO is full
|
||||||
|
// 'full' being when it reaches whatever BlockLen16 is set to, or the
|
||||||
|
// other blocklen register, or when it is actually full (but that makes
|
||||||
|
// less sense)
|
||||||
|
DSi::CheckNDMAs(1, host->Num ? 0x29 : 0x28);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 DSi_SDHost::SendData(u8* data, u32 len)
|
u32 DSi_SDHost::SendData(u8* data, u32 len)
|
||||||
@ -286,7 +300,7 @@ u32 DSi_SDHost::GetTransferrableLen(u32 len)
|
|||||||
|
|
||||||
u16 DSi_SDHost::Read(u32 addr)
|
u16 DSi_SDHost::Read(u32 addr)
|
||||||
{
|
{
|
||||||
//if(Num)printf("SDIO READ %08X %08X\n", addr, NDS::GetPC(1));
|
if(!Num)printf("SDMMC READ %08X %08X\n", addr, NDS::GetPC(1));
|
||||||
|
|
||||||
switch (addr & 0x1FF)
|
switch (addr & 0x1FF)
|
||||||
{
|
{
|
||||||
@ -307,7 +321,24 @@ u16 DSi_SDHost::Read(u32 addr)
|
|||||||
case 0x018: return ResponseBuffer[6];
|
case 0x018: return ResponseBuffer[6];
|
||||||
case 0x01A: return ResponseBuffer[7];
|
case 0x01A: return ResponseBuffer[7];
|
||||||
|
|
||||||
case 0x01C: return (IRQStatus & 0x031D) | 0x0030; // TODO: adjust insert flags for SD card
|
case 0x01C:
|
||||||
|
{
|
||||||
|
u16 ret = (IRQStatus & 0x031D);
|
||||||
|
|
||||||
|
if (!Num)
|
||||||
|
{
|
||||||
|
if (Ports[0]) // basic check of whether the SD card is inserted
|
||||||
|
ret |= 0x0030;
|
||||||
|
else
|
||||||
|
ret |= 0x0008;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// SDIO wifi is always inserted, I guess
|
||||||
|
ret |= 0x0030;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
case 0x01E: return ((IRQStatus >> 16) & 0x8B7F);
|
case 0x01E: return ((IRQStatus >> 16) & 0x8B7F);
|
||||||
case 0x020: return IRQMask & 0x031D;
|
case 0x020: return IRQMask & 0x031D;
|
||||||
case 0x022: return (IRQMask >> 16) & 0x8B7F;
|
case 0x022: return (IRQMask >> 16) & 0x8B7F;
|
||||||
@ -436,7 +467,7 @@ u32 DSi_SDHost::ReadFIFO32()
|
|||||||
|
|
||||||
void DSi_SDHost::Write(u32 addr, u16 val)
|
void DSi_SDHost::Write(u32 addr, u16 val)
|
||||||
{
|
{
|
||||||
//if(Num)printf("SDIO WRITE %08X %04X %08X\n", addr, val, NDS::GetPC(1));
|
if(!Num)printf("SDMMC WRITE %08X %04X %08X\n", addr, val, NDS::GetPC(1));
|
||||||
|
|
||||||
switch (addr & 0x1FF)
|
switch (addr & 0x1FF)
|
||||||
{
|
{
|
||||||
@ -464,7 +495,7 @@ void DSi_SDHost::Write(u32 addr, u16 val)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x002: PortSelect = val; printf("%s: PORT SELECT %04X\n", SD_DESC, val); return;
|
case 0x002: PortSelect = (val & 0x040F) | (PortSelect & 0x0300); printf("%s: PORT SELECT %04X (%04X)\n", SD_DESC, val, PortSelect); return;
|
||||||
case 0x004: Param = (Param & 0xFFFF0000) | val; return;
|
case 0x004: Param = (Param & 0xFFFF0000) | val; return;
|
||||||
case 0x006: Param = (Param & 0x0000FFFF) | (val << 16); return;
|
case 0x006: Param = (Param & 0x0000FFFF) | (val << 16); return;
|
||||||
|
|
||||||
@ -504,7 +535,7 @@ void DSi_SDHost::Write(u32 addr, u16 val)
|
|||||||
if (DataFIFO[f]->IsFull())
|
if (DataFIFO[f]->IsFull())
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
printf("!!!! %s FIFO FULL\n", SD_DESC);
|
printf("!!!! %s FIFO (16) FULL\n", SD_DESC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,12 +613,14 @@ void DSi_SDHost::WriteFIFO32(u32 val)
|
|||||||
{
|
{
|
||||||
if (DataMode != 1) return;
|
if (DataMode != 1) return;
|
||||||
|
|
||||||
|
printf("%s: WRITE FIFO32: LEVEL=%d/%d\n", SD_DESC, DataFIFO[CurFIFO]->Level(), (BlockLen16>>1));
|
||||||
|
|
||||||
DSi_SDDevice* dev = Ports[PortSelect & 0x1];
|
DSi_SDDevice* dev = Ports[PortSelect & 0x1];
|
||||||
u32 f = CurFIFO;
|
u32 f = CurFIFO;
|
||||||
if (DataFIFO[f]->IsFull())
|
if (DataFIFO[f]->IsFull())
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
printf("!!!! %s FIFO FULL\n", SD_DESC);
|
printf("!!!! %s FIFO (32) FULL\n", SD_DESC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,12 +641,26 @@ void DSi_SDHost::WriteFIFO32(u32 val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define MMC_DESC (Internal?"NAND":"SDcard")
|
||||||
|
|
||||||
DSi_MMCStorage::DSi_MMCStorage(DSi_SDHost* host, bool internal, const char* path) : DSi_SDDevice(host)
|
DSi_MMCStorage::DSi_MMCStorage(DSi_SDHost* host, bool internal, const char* path) : DSi_SDDevice(host)
|
||||||
{
|
{
|
||||||
Internal = internal;
|
Internal = internal;
|
||||||
strncpy(FilePath, path, 1023); FilePath[1023] = '\0';
|
strncpy(FilePath, path, 1023); FilePath[1023] = '\0';
|
||||||
|
|
||||||
File = Platform::OpenLocalFile(path, "r+b");
|
File = Platform::OpenLocalFile(path, "r+b");
|
||||||
|
if (!File)
|
||||||
|
{
|
||||||
|
if (internal)
|
||||||
|
{
|
||||||
|
// TODO: proper failure
|
||||||
|
printf("!! MMC file %s does not exist\n", path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
File = Platform::OpenLocalFile(path, "w+b");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CSR = 0x00000100; // checkme
|
CSR = 0x00000100; // checkme
|
||||||
|
|
||||||
@ -674,6 +721,7 @@ void DSi_MMCStorage::SendCMD(u8 cmd, u32 param)
|
|||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
printf("CMD3 on SD card: TODO\n");
|
printf("CMD3 on SD card: TODO\n");
|
||||||
|
Host->SendResponse((CSR & 0x1FFF) | ((CSR >> 6) & 0x2000) | ((CSR >> 8) & 0xC000) | (1 << 16), true);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
42
src/NDS.cpp
42
src/NDS.cpp
@ -1371,6 +1371,29 @@ void RunTimers(u32 cpu)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// matching NDMA modes for DSi
|
||||||
|
const u32 NDMAModes[] =
|
||||||
|
{
|
||||||
|
// ARM9
|
||||||
|
|
||||||
|
0x10, // immediate
|
||||||
|
0x06, // VBlank
|
||||||
|
0x07, // HBlank
|
||||||
|
0x08, // scanline start
|
||||||
|
0x09, // mainmem FIFO
|
||||||
|
0x04, // DS cart slot
|
||||||
|
0xFF, // GBA cart slot
|
||||||
|
0x0A, // GX FIFO
|
||||||
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||||
|
|
||||||
|
// ARM7
|
||||||
|
|
||||||
|
0x30, // immediate
|
||||||
|
0x26, // VBlank
|
||||||
|
0x24, // DS cart slot
|
||||||
|
0xFF, // wifi / GBA cart slot (TODO)
|
||||||
|
};
|
||||||
|
|
||||||
bool DMAsInMode(u32 cpu, u32 mode)
|
bool DMAsInMode(u32 cpu, u32 mode)
|
||||||
{
|
{
|
||||||
cpu <<= 2;
|
cpu <<= 2;
|
||||||
@ -1378,6 +1401,13 @@ bool DMAsInMode(u32 cpu, u32 mode)
|
|||||||
if (DMAs[cpu+1]->IsInMode(mode)) return true;
|
if (DMAs[cpu+1]->IsInMode(mode)) return true;
|
||||||
if (DMAs[cpu+2]->IsInMode(mode)) return true;
|
if (DMAs[cpu+2]->IsInMode(mode)) return true;
|
||||||
if (DMAs[cpu+3]->IsInMode(mode)) return true;
|
if (DMAs[cpu+3]->IsInMode(mode)) return true;
|
||||||
|
|
||||||
|
if (true)
|
||||||
|
{
|
||||||
|
cpu >>= 2;
|
||||||
|
return DSi::NDMAsInMode(cpu, NDMAModes[mode]);
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1399,6 +1429,12 @@ void CheckDMAs(u32 cpu, u32 mode)
|
|||||||
DMAs[cpu+1]->StartIfNeeded(mode);
|
DMAs[cpu+1]->StartIfNeeded(mode);
|
||||||
DMAs[cpu+2]->StartIfNeeded(mode);
|
DMAs[cpu+2]->StartIfNeeded(mode);
|
||||||
DMAs[cpu+3]->StartIfNeeded(mode);
|
DMAs[cpu+3]->StartIfNeeded(mode);
|
||||||
|
|
||||||
|
if (true)
|
||||||
|
{
|
||||||
|
cpu >>= 2;
|
||||||
|
DSi::CheckNDMAs(cpu, NDMAModes[mode]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopDMAs(u32 cpu, u32 mode)
|
void StopDMAs(u32 cpu, u32 mode)
|
||||||
@ -1408,6 +1444,12 @@ void StopDMAs(u32 cpu, u32 mode)
|
|||||||
DMAs[cpu+1]->StopIfNeeded(mode);
|
DMAs[cpu+1]->StopIfNeeded(mode);
|
||||||
DMAs[cpu+2]->StopIfNeeded(mode);
|
DMAs[cpu+2]->StopIfNeeded(mode);
|
||||||
DMAs[cpu+3]->StopIfNeeded(mode);
|
DMAs[cpu+3]->StopIfNeeded(mode);
|
||||||
|
|
||||||
|
if (true)
|
||||||
|
{
|
||||||
|
cpu >>= 2;
|
||||||
|
DSi::StopNDMAs(cpu, NDMAModes[mode]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1227,11 +1227,11 @@ void WriteROMCnt(u32 val)
|
|||||||
*(u32*)&cmd[4] = *(u32*)&ROMCommand[4];
|
*(u32*)&cmd[4] = *(u32*)&ROMCommand[4];
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("ROM COMMAND %04X %08X %02X%02X%02X%02X%02X%02X%02X%02X SIZE %04X\n",
|
/*printf("ROM COMMAND %04X %08X %02X%02X%02X%02X%02X%02X%02X%02X SIZE %04X\n",
|
||||||
SPICnt, ROMCnt,
|
SPICnt, ROMCnt,
|
||||||
cmd[0], cmd[1], cmd[2], cmd[3],
|
cmd[0], cmd[1], cmd[2], cmd[3],
|
||||||
cmd[4], cmd[5], cmd[6], cmd[7],
|
cmd[4], cmd[5], cmd[6], cmd[7],
|
||||||
datasize);
|
datasize);*/
|
||||||
|
|
||||||
switch (cmd[0])
|
switch (cmd[0])
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user