From d21d10e087ac0d2396edd33fed8089b7ed9ede30 Mon Sep 17 00:00:00 2001 From: Tim Seidel Date: Tue, 6 Jul 2021 09:28:15 +0200 Subject: [PATCH 1/2] Added DSi NWRAM support Guarded by define DSI_NEWWRAM, which is currently only set for the VS Studio Project --- desmume/src/MMU.cpp | 791 +++++++++++++++++++ desmume/src/MMU.h | 19 + desmume/src/frontend/windows/DeSmuME.vcxproj | 5 + desmume/src/frontend/windows/IORegView.cpp | 237 +++++- desmume/src/registers.h | 28 + 5 files changed, 1077 insertions(+), 3 deletions(-) diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index ebbaafeb9..3a7ee9f23 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -54,6 +54,10 @@ #define ASSERT_UNALIGNED(x) #endif +#ifdef DSI_NEWWRAM +void FASTCALL MMU_UpdateNWRAM(); +#endif + //TODO - do we need these here? static _KEY2 key2; @@ -2709,6 +2713,19 @@ bool validateIORegsWrite(u32 addr, u8 size, u32 val) // ...GBA case REG_DISPB_MASTERBRIGHT: + // NWRAM +#ifdef DSI_NEWWRAM: + case REG_NWRAM_CTRL_SET0BANK0: + case REG_NWRAM_CTRL_SET1BANK0: + case REG_NWRAM_CTRL_SET1BANK4: + case REG_NWRAM_CTRL_SET2BANK0: + case REG_NWRAM_CTRL_SET2BANK4: + case REG_NWRAM_WINDOW_SET0: + case REG_NWRAM_WINDOW_SET1: + case REG_NWRAM_WINDOW_SET2: + case REG_NWRAM_PROTECT: +#endif + // 0x04100000 case REG_IPCFIFORECV: case REG_GCDATAIN: @@ -2810,6 +2827,19 @@ bool validateIORegsWrite(u32 addr, u8 size, u32 val) // Sound + // NWRAM +#ifdef DSI_NEWWRAM: + case REG_NWRAM_CTRL_SET0BANK0: + case REG_NWRAM_CTRL_SET1BANK0: + case REG_NWRAM_CTRL_SET1BANK4: + case REG_NWRAM_CTRL_SET2BANK0: + case REG_NWRAM_CTRL_SET2BANK4: + case REG_NWRAM_WINDOW_SET0: + case REG_NWRAM_WINDOW_SET1: + case REG_NWRAM_WINDOW_SET2: + case REG_NWRAM_PROTECT: +#endif + // 0x04100000 - IPC case REG_IPCFIFORECV: case REG_GCDATAIN: @@ -3674,6 +3704,61 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val) case 0x040001AF : LOG("%08X : %02X\r\n", adr, val); #endif +#ifdef DSI_NEWWRAM + case REG_NWRAM_CTRL_SET0BANK0: + case REG_NWRAM_CTRL_SET0BANK1: + case REG_NWRAM_CTRL_SET0BANK2: + case REG_NWRAM_CTRL_SET0BANK3: + case REG_NWRAM_CTRL_SET1BANK0: + case REG_NWRAM_CTRL_SET1BANK1: + case REG_NWRAM_CTRL_SET1BANK2: + case REG_NWRAM_CTRL_SET1BANK3: + case REG_NWRAM_CTRL_SET1BANK4: + case REG_NWRAM_CTRL_SET1BANK5: + case REG_NWRAM_CTRL_SET1BANK6: + case REG_NWRAM_CTRL_SET1BANK7: + case REG_NWRAM_CTRL_SET2BANK0: + case REG_NWRAM_CTRL_SET2BANK1: + case REG_NWRAM_CTRL_SET2BANK2: + case REG_NWRAM_CTRL_SET2BANK3: + case REG_NWRAM_CTRL_SET2BANK4: + case REG_NWRAM_CTRL_SET2BANK5: + case REG_NWRAM_CTRL_SET2BANK6: + case REG_NWRAM_CTRL_SET2BANK7: + { + // check if this bank is currently writeable + uint8_t bit = (adr >= REG_NWRAM_CTRL_SET1BANK0) ? ((adr - REG_NWRAM_CTRL_SET1BANK0) + 8) : (adr - REG_NWRAM_CTRL_SET0BANK0); + if (MMU.regNWRAM_Protect & (1 << bit)) + return; + // otherwise update! + MMU.regNRWAM_BankControl[adr - REG_NWRAM_CTRL_SET0BANK0] = val; + MMU_UpdateNWRAM(); + return; + } + case REG_NWRAM_WINDOW_SET0: + case REG_NWRAM_WINDOW_SET0 + 1: + case REG_NWRAM_WINDOW_SET0 + 2: + case REG_NWRAM_WINDOW_SET0 + 3: + case REG_NWRAM_WINDOW_SET1: + case REG_NWRAM_WINDOW_SET1 + 1: + case REG_NWRAM_WINDOW_SET1 + 2: + case REG_NWRAM_WINDOW_SET1 + 3: + case REG_NWRAM_WINDOW_SET2: + case REG_NWRAM_WINDOW_SET2 + 1: + case REG_NWRAM_WINDOW_SET2 + 2: + case REG_NWRAM_WINDOW_SET2 + 3: + MMU.regNWRAM_Windows[1][(adr - REG_NWRAM_WINDOW_SET0) >> 2] &= ~(0xff << ((adr & 3) * 8)); + MMU.regNWRAM_Windows[1][(adr - REG_NWRAM_WINDOW_SET0) >> 2] |= (val << ((adr & 3) * 8)); + MMU_UpdateNWRAM(); + return; + case REG_NWRAM_PROTECT: + case REG_NWRAM_PROTECT + 1: + case REG_NWRAM_PROTECT + 2: + case REG_NWRAM_PROTECT + 3: + // not writeable on arm9 + return; +#endif + } MMU.MMU_MEM[ARMCPU_ARM9][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]]=val; @@ -3685,6 +3770,18 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val) return; } +#ifdef DSI_NEWWRAM + if ((adr >> 24) == 0x03) + { + if (MMU.NWRAMBLOCKPTRS[0][(adr - 0x03000000) / 0x8000]) + { + MMU.NWRAMBLOCKPTRS[0][(adr - 0x03000000) / 0x8000][adr & 0x7fff] = val; + return; + } + } +#endif + + bool unmapped, restricted; adr = MMU_LCDmap(adr, unmapped, restricted); if(unmapped) return; @@ -4251,6 +4348,64 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) case REG_GCROMCTRL+2 : MMU_writeToGCControl( (T1ReadLong(MMU.MMU_MEM[0][0x40], 0x1A4) & 0xFFFF) | ((u32) val << 16)); return; +#ifdef DSI_NEWWRAM + case REG_NWRAM_CTRL_SET0BANK0: + case REG_NWRAM_CTRL_SET0BANK1: + case REG_NWRAM_CTRL_SET0BANK2: + case REG_NWRAM_CTRL_SET0BANK3: + case REG_NWRAM_CTRL_SET1BANK0: + case REG_NWRAM_CTRL_SET1BANK1: + case REG_NWRAM_CTRL_SET1BANK2: + case REG_NWRAM_CTRL_SET1BANK3: + case REG_NWRAM_CTRL_SET1BANK4: + case REG_NWRAM_CTRL_SET1BANK5: + case REG_NWRAM_CTRL_SET1BANK6: + case REG_NWRAM_CTRL_SET1BANK7: + case REG_NWRAM_CTRL_SET2BANK0: + case REG_NWRAM_CTRL_SET2BANK1: + case REG_NWRAM_CTRL_SET2BANK2: + case REG_NWRAM_CTRL_SET2BANK3: + case REG_NWRAM_CTRL_SET2BANK4: + case REG_NWRAM_CTRL_SET2BANK5: + case REG_NWRAM_CTRL_SET2BANK6: + case REG_NWRAM_CTRL_SET2BANK7: + { + // check if this bank is currently writeable + for (int i = 0; i < 2; i++) + { + uint8_t bit = ((adr + i) >= REG_NWRAM_CTRL_SET1BANK0) ? (((adr+i) - REG_NWRAM_CTRL_SET1BANK0) + 8) : ((adr + i) - REG_NWRAM_CTRL_SET0BANK0); + if (MMU.regNWRAM_Protect & (1 << bit)) + return; + // otherwise update! + MMU.regNRWAM_BankControl[adr - REG_NWRAM_CTRL_SET0BANK0] = val >> (i *8); + + } + MMU_UpdateNWRAM(); + return; + } + case REG_NWRAM_WINDOW_SET0: + case REG_NWRAM_WINDOW_SET0 + 1: + case REG_NWRAM_WINDOW_SET0 + 2: + case REG_NWRAM_WINDOW_SET0 + 3: + case REG_NWRAM_WINDOW_SET1: + case REG_NWRAM_WINDOW_SET1 + 1: + case REG_NWRAM_WINDOW_SET1 + 2: + case REG_NWRAM_WINDOW_SET1 + 3: + case REG_NWRAM_WINDOW_SET2: + case REG_NWRAM_WINDOW_SET2 + 1: + case REG_NWRAM_WINDOW_SET2 + 2: + case REG_NWRAM_WINDOW_SET2 + 3: + MMU.regNWRAM_Windows[1][(adr - REG_NWRAM_WINDOW_SET0) >> 2] &= ~(0xffff << ((adr & 2) * 8)); + MMU.regNWRAM_Windows[1][(adr - REG_NWRAM_WINDOW_SET0) >> 2] |= (val << ((adr & 2) * 8)); + MMU_UpdateNWRAM(); + return; + case REG_NWRAM_PROTECT: + case REG_NWRAM_PROTECT + 1: + case REG_NWRAM_PROTECT + 2: + case REG_NWRAM_PROTECT + 3: + // not writeable on arm9 + return; +#endif } T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr&MMU.MMU_MASK[ARMCPU_ARM9][adr>>20], val); @@ -4262,6 +4417,17 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) return; } +#ifdef DSI_NEWWRAM + if ((adr >> 24) == 0x03) + { + if (MMU.NWRAMBLOCKPTRS[1][(adr - 0x03000000) / 0x8000]) + { + T1WriteWord(MMU.NWRAMBLOCKPTRS[1][(adr - 0x03000000) / 0x8000], adr & 0x7fff, val); + return; + } + } +#endif + bool unmapped, restricted; adr = MMU_LCDmap(adr, unmapped, restricted); if(unmapped) return; @@ -4760,6 +4926,63 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) case REG_GCDATAIN: MMU_writeToGC(val); return; +#ifdef DSI_NEWWRAM + case REG_NWRAM_CTRL_SET0BANK0: + case REG_NWRAM_CTRL_SET0BANK1: + case REG_NWRAM_CTRL_SET0BANK2: + case REG_NWRAM_CTRL_SET0BANK3: + case REG_NWRAM_CTRL_SET1BANK0: + case REG_NWRAM_CTRL_SET1BANK1: + case REG_NWRAM_CTRL_SET1BANK2: + case REG_NWRAM_CTRL_SET1BANK3: + case REG_NWRAM_CTRL_SET1BANK4: + case REG_NWRAM_CTRL_SET1BANK5: + case REG_NWRAM_CTRL_SET1BANK6: + case REG_NWRAM_CTRL_SET1BANK7: + case REG_NWRAM_CTRL_SET2BANK0: + case REG_NWRAM_CTRL_SET2BANK1: + case REG_NWRAM_CTRL_SET2BANK2: + case REG_NWRAM_CTRL_SET2BANK3: + case REG_NWRAM_CTRL_SET2BANK4: + case REG_NWRAM_CTRL_SET2BANK5: + case REG_NWRAM_CTRL_SET2BANK6: + case REG_NWRAM_CTRL_SET2BANK7: + { + // check if this bank is currently writeable + for (int i = 0; i < 4; i++) + { + uint8_t bit = ((adr + i) >= REG_NWRAM_CTRL_SET1BANK0) ? (((adr + i) - REG_NWRAM_CTRL_SET1BANK0) + 8) : ((adr + i) - REG_NWRAM_CTRL_SET0BANK0); + if (MMU.regNWRAM_Protect & (1 << bit)) + return; + // otherwise update! + MMU.regNRWAM_BankControl[adr - REG_NWRAM_CTRL_SET0BANK0] = val >> (i * 8); + + } + MMU_UpdateNWRAM(); + return; + } + case REG_NWRAM_WINDOW_SET0: + case REG_NWRAM_WINDOW_SET0 + 1: + case REG_NWRAM_WINDOW_SET0 + 2: + case REG_NWRAM_WINDOW_SET0 + 3: + case REG_NWRAM_WINDOW_SET1: + case REG_NWRAM_WINDOW_SET1 + 1: + case REG_NWRAM_WINDOW_SET1 + 2: + case REG_NWRAM_WINDOW_SET1 + 3: + case REG_NWRAM_WINDOW_SET2: + case REG_NWRAM_WINDOW_SET2 + 1: + case REG_NWRAM_WINDOW_SET2 + 2: + case REG_NWRAM_WINDOW_SET2 + 3: + MMU.regNWRAM_Windows[1][(adr - REG_NWRAM_WINDOW_SET0) >> 2] = val; + MMU_UpdateNWRAM(); + return; + case REG_NWRAM_PROTECT: + case REG_NWRAM_PROTECT + 1: + case REG_NWRAM_PROTECT + 2: + case REG_NWRAM_PROTECT + 3: + // not writeable on arm9 + return; +#endif } T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20], val); @@ -4771,6 +4994,17 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) return; } +#ifdef DSI_NEWWRAM + if ((adr >> 24) == 0x03) + { + if (MMU.NWRAMBLOCKPTRS[1][(adr - 0x03000000) / 0x8000]) + { + T1WriteLong(MMU.NWRAMBLOCKPTRS[1][(adr - 0x03000000) / 0x8000], adr & 0x7fff, val); + return; + } + } +#endif + bool unmapped, restricted; adr = MMU_LCDmap(adr, unmapped, restricted); if(unmapped) return; @@ -4900,9 +5134,59 @@ u8 FASTCALL _MMU_ARM9_read08(u32 adr) case REG_KEYINPUT: LagFrameFlag=0; break; +#ifdef DSI_NEWWRAM + case REG_NWRAM_CTRL_SET0BANK0: + case REG_NWRAM_CTRL_SET0BANK1: + case REG_NWRAM_CTRL_SET0BANK2: + case REG_NWRAM_CTRL_SET0BANK3: + case REG_NWRAM_CTRL_SET1BANK0: + case REG_NWRAM_CTRL_SET1BANK1: + case REG_NWRAM_CTRL_SET1BANK2: + case REG_NWRAM_CTRL_SET1BANK3: + case REG_NWRAM_CTRL_SET1BANK4: + case REG_NWRAM_CTRL_SET1BANK5: + case REG_NWRAM_CTRL_SET1BANK6: + case REG_NWRAM_CTRL_SET1BANK7: + case REG_NWRAM_CTRL_SET2BANK0: + case REG_NWRAM_CTRL_SET2BANK1: + case REG_NWRAM_CTRL_SET2BANK2: + case REG_NWRAM_CTRL_SET2BANK3: + case REG_NWRAM_CTRL_SET2BANK4: + case REG_NWRAM_CTRL_SET2BANK5: + case REG_NWRAM_CTRL_SET2BANK6: + case REG_NWRAM_CTRL_SET2BANK7: + return MMU.regNRWAM_BankControl[adr - REG_NWRAM_CTRL_SET0BANK0]; + case REG_NWRAM_WINDOW_SET0: + case REG_NWRAM_WINDOW_SET0 + 1: + case REG_NWRAM_WINDOW_SET0 + 2: + case REG_NWRAM_WINDOW_SET0 + 3: + case REG_NWRAM_WINDOW_SET1: + case REG_NWRAM_WINDOW_SET1 + 1: + case REG_NWRAM_WINDOW_SET1 + 2: + case REG_NWRAM_WINDOW_SET1 + 3: + case REG_NWRAM_WINDOW_SET2: + case REG_NWRAM_WINDOW_SET2 + 1: + case REG_NWRAM_WINDOW_SET2 + 2: + case REG_NWRAM_WINDOW_SET2 + 3: + return (MMU.regNWRAM_Windows[1][(adr - REG_NWRAM_WINDOW_SET0) >> 2] >> ((adr & 3) * 8)) & 0xff; + case REG_NWRAM_PROTECT: + case REG_NWRAM_PROTECT + 1: + case REG_NWRAM_PROTECT + 2: + case REG_NWRAM_PROTECT + 3: + return (MMU.regNWRAM_Protect >> ((adr & 3) * 8)) & 0xff; +#endif } } +#ifdef DSI_NEWWRAM + if ((adr >> 24) == 0x03) + { + if (MMU.NWRAMBLOCKPTRS[1][(adr - 0x03000000) / 0x8000]) + return MMU.NWRAMBLOCKPTRS[1][(adr - 0x03000000) / 0x8000][adr & 0x7fff]; + } +#endif + + bool unmapped, restricted; adr = MMU_LCDmap(adr, unmapped, restricted); if(unmapped) return 0; @@ -5007,11 +5291,59 @@ u16 FASTCALL _MMU_ARM9_read16(u32 adr) case eng_3D_FOG_TABLE+0x10: case eng_3D_FOG_TABLE+0x12: case eng_3D_FOG_TABLE+0x14: case eng_3D_FOG_TABLE+0x16: case eng_3D_FOG_TABLE+0x18: case eng_3D_FOG_TABLE+0x1A: case eng_3D_FOG_TABLE+0x1C: case eng_3D_FOG_TABLE+0x1E: return 0; +#ifdef DSI_NEWWRAM + case REG_NWRAM_CTRL_SET0BANK0: + case REG_NWRAM_CTRL_SET0BANK1: + case REG_NWRAM_CTRL_SET0BANK2: + case REG_NWRAM_CTRL_SET0BANK3: + case REG_NWRAM_CTRL_SET1BANK0: + case REG_NWRAM_CTRL_SET1BANK1: + case REG_NWRAM_CTRL_SET1BANK2: + case REG_NWRAM_CTRL_SET1BANK3: + case REG_NWRAM_CTRL_SET1BANK4: + case REG_NWRAM_CTRL_SET1BANK5: + case REG_NWRAM_CTRL_SET1BANK6: + case REG_NWRAM_CTRL_SET1BANK7: + case REG_NWRAM_CTRL_SET2BANK0: + case REG_NWRAM_CTRL_SET2BANK1: + case REG_NWRAM_CTRL_SET2BANK2: + case REG_NWRAM_CTRL_SET2BANK3: + case REG_NWRAM_CTRL_SET2BANK4: + case REG_NWRAM_CTRL_SET2BANK5: + case REG_NWRAM_CTRL_SET2BANK6: + return MMU.regNRWAM_BankControl[adr - REG_NWRAM_CTRL_SET0BANK0] | (MMU.regNRWAM_BankControl[adr + 1 - REG_NWRAM_CTRL_SET0BANK0] << 8); + case REG_NWRAM_WINDOW_SET0: + case REG_NWRAM_WINDOW_SET0 + 1: + case REG_NWRAM_WINDOW_SET0 + 2: + case REG_NWRAM_WINDOW_SET0 + 3: + case REG_NWRAM_WINDOW_SET1: + case REG_NWRAM_WINDOW_SET1 + 1: + case REG_NWRAM_WINDOW_SET1 + 2: + case REG_NWRAM_WINDOW_SET1 + 3: + case REG_NWRAM_WINDOW_SET2: + case REG_NWRAM_WINDOW_SET2 + 1: + case REG_NWRAM_WINDOW_SET2 + 2: + case REG_NWRAM_WINDOW_SET2 + 3: + return (MMU.regNWRAM_Windows[1][(adr - REG_NWRAM_WINDOW_SET0) >> 2] >> ((adr & 2) * 8)) & 0xffff; + case REG_NWRAM_PROTECT: + case REG_NWRAM_PROTECT + 1: + case REG_NWRAM_PROTECT + 2: + case REG_NWRAM_PROTECT + 3: + return (MMU.regNWRAM_Protect >> ((adr & 2) * 8)) & 0xffff; +#endif } return T1ReadWord_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]); } +#ifdef DSI_NEWWRAM + if ((adr >> 24) == 0x03) + { + if (MMU.NWRAMBLOCKPTRS[1][(adr - 0x03000000) / 0x8000]) + return T1ReadWord_guaranteedAligned(MMU.NWRAMBLOCKPTRS[1][(adr - 0x03000000) / 0x8000], adr & 0x7fff); + } +#endif + bool unmapped, restricted; adr = MMU_LCDmap(adr,unmapped, restricted); if(unmapped) return 0; @@ -5152,10 +5484,58 @@ u32 FASTCALL _MMU_ARM9_read32(u32 adr) case REG_KEYINPUT: LagFrameFlag=0; break; +#ifdef DSI_NEWWRAM + case REG_NWRAM_CTRL_SET0BANK0: + case REG_NWRAM_CTRL_SET0BANK1: + case REG_NWRAM_CTRL_SET0BANK2: + case REG_NWRAM_CTRL_SET0BANK3: + case REG_NWRAM_CTRL_SET1BANK0: + case REG_NWRAM_CTRL_SET1BANK1: + case REG_NWRAM_CTRL_SET1BANK2: + case REG_NWRAM_CTRL_SET1BANK3: + case REG_NWRAM_CTRL_SET1BANK4: + case REG_NWRAM_CTRL_SET1BANK5: + case REG_NWRAM_CTRL_SET1BANK6: + case REG_NWRAM_CTRL_SET1BANK7: + case REG_NWRAM_CTRL_SET2BANK0: + case REG_NWRAM_CTRL_SET2BANK1: + case REG_NWRAM_CTRL_SET2BANK2: + case REG_NWRAM_CTRL_SET2BANK3: + case REG_NWRAM_CTRL_SET2BANK4: + return MMU.regNRWAM_BankControl[adr - REG_NWRAM_CTRL_SET0BANK0] | (MMU.regNRWAM_BankControl[adr + 1 - REG_NWRAM_CTRL_SET0BANK0] << 8) + | (MMU.regNRWAM_BankControl[adr + 2 - REG_NWRAM_CTRL_SET0BANK0] << 16) | (MMU.regNRWAM_BankControl[adr + 3 - REG_NWRAM_CTRL_SET0BANK0] << 24); + case REG_NWRAM_WINDOW_SET0: + case REG_NWRAM_WINDOW_SET0 + 1: + case REG_NWRAM_WINDOW_SET0 + 2: + case REG_NWRAM_WINDOW_SET0 + 3: + case REG_NWRAM_WINDOW_SET1: + case REG_NWRAM_WINDOW_SET1 + 1: + case REG_NWRAM_WINDOW_SET1 + 2: + case REG_NWRAM_WINDOW_SET1 + 3: + case REG_NWRAM_WINDOW_SET2: + case REG_NWRAM_WINDOW_SET2 + 1: + case REG_NWRAM_WINDOW_SET2 + 2: + case REG_NWRAM_WINDOW_SET2 + 3: + return MMU.regNWRAM_Windows[1][(adr - REG_NWRAM_WINDOW_SET0) >> 2]; + case REG_NWRAM_PROTECT: + case REG_NWRAM_PROTECT + 1: + case REG_NWRAM_PROTECT + 2: + case REG_NWRAM_PROTECT + 3: + return MMU.regNWRAM_Protect; +#endif } return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]); } + +#ifdef DSI_NEWWRAM + if ((adr >> 24) == 0x03) + { + if (MMU.NWRAMBLOCKPTRS[1][(adr - 0x03000000) / 0x8000]) + return T1ReadLong_guaranteedAligned(MMU.NWRAMBLOCKPTRS[1][(adr - 0x03000000) / 0x8000], adr & 0x7fff); + } +#endif + bool unmapped, restricted; adr = MMU_LCDmap(adr,unmapped, restricted); if(unmapped) return 0; @@ -5261,11 +5641,71 @@ void FASTCALL _MMU_ARM7_write08(u32 adr, u8 val) // into RAM at 0x027FF830 MMU_writeToSPIData(val); return; +#ifdef DSI_NEWWRAM + case REG_NWRAM_CTRL_SET0BANK0: + case REG_NWRAM_CTRL_SET0BANK1: + case REG_NWRAM_CTRL_SET0BANK2: + case REG_NWRAM_CTRL_SET0BANK3: + case REG_NWRAM_CTRL_SET1BANK0: + case REG_NWRAM_CTRL_SET1BANK1: + case REG_NWRAM_CTRL_SET1BANK2: + case REG_NWRAM_CTRL_SET1BANK3: + case REG_NWRAM_CTRL_SET1BANK4: + case REG_NWRAM_CTRL_SET1BANK5: + case REG_NWRAM_CTRL_SET1BANK6: + case REG_NWRAM_CTRL_SET1BANK7: + case REG_NWRAM_CTRL_SET2BANK0: + case REG_NWRAM_CTRL_SET2BANK1: + case REG_NWRAM_CTRL_SET2BANK2: + case REG_NWRAM_CTRL_SET2BANK3: + case REG_NWRAM_CTRL_SET2BANK4: + case REG_NWRAM_CTRL_SET2BANK5: + case REG_NWRAM_CTRL_SET2BANK6: + case REG_NWRAM_CTRL_SET2BANK7: + /* These registers can not be changed by the arm7, as of a fuse bit in SCFG + TODO: If that SFCG is implemented this might get writeable */ + return; + case REG_NWRAM_WINDOW_SET0: + case REG_NWRAM_WINDOW_SET0 + 1: + case REG_NWRAM_WINDOW_SET0 + 2: + case REG_NWRAM_WINDOW_SET0 + 3: + case REG_NWRAM_WINDOW_SET1: + case REG_NWRAM_WINDOW_SET1 + 1: + case REG_NWRAM_WINDOW_SET1 + 2: + case REG_NWRAM_WINDOW_SET1 + 3: + case REG_NWRAM_WINDOW_SET2: + case REG_NWRAM_WINDOW_SET2 + 1: + case REG_NWRAM_WINDOW_SET2 + 2: + case REG_NWRAM_WINDOW_SET2 + 3: + MMU.regNWRAM_Windows[0][(adr - REG_NWRAM_WINDOW_SET0) >> 2] &= ~(0xff << ((adr & 3) * 8)); + MMU.regNWRAM_Windows[0][(adr - REG_NWRAM_WINDOW_SET0) >> 2] |= (val << ((adr & 3) * 8)); + MMU_UpdateNWRAM(); + return; + case REG_NWRAM_PROTECT: + case REG_NWRAM_PROTECT + 1: + case REG_NWRAM_PROTECT + 2: + case REG_NWRAM_PROTECT + 3: + MMU.regNWRAM_Protect &= ~(0xff << ((adr & 3) * 8)); + MMU.regNWRAM_Protect |= (val << ((adr & 3) * 8)); + return; +#endif } MMU.MMU_MEM[ARMCPU_ARM7][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]]=val; return; } + +#ifdef DSI_NEWWRAM + if ((adr >> 24) == 0x03) + { + if (MMU.NWRAMBLOCKPTRS[0][(adr - 0x03000000) / 0x8000]) + { + MMU.NWRAMBLOCKPTRS[0][(adr - 0x03000000) / 0x8000][adr & 0x7fff] = val; + return; + } + } +#endif + bool unmapped, restricted; adr = MMU_LCDmap(adr,unmapped, restricted); if(unmapped) return; @@ -5446,12 +5886,72 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val) case REG_GCROMCTRL+2 : MMU_writeToGCControl( (T1ReadLong(MMU.MMU_MEM[1][0x40], 0x1A4) & 0xFFFF) | ((u32) val << 16)); return; +#ifdef DSI_NEWWRAM + case REG_NWRAM_CTRL_SET0BANK0: + case REG_NWRAM_CTRL_SET0BANK1: + case REG_NWRAM_CTRL_SET0BANK2: + case REG_NWRAM_CTRL_SET0BANK3: + case REG_NWRAM_CTRL_SET1BANK0: + case REG_NWRAM_CTRL_SET1BANK1: + case REG_NWRAM_CTRL_SET1BANK2: + case REG_NWRAM_CTRL_SET1BANK3: + case REG_NWRAM_CTRL_SET1BANK4: + case REG_NWRAM_CTRL_SET1BANK5: + case REG_NWRAM_CTRL_SET1BANK6: + case REG_NWRAM_CTRL_SET1BANK7: + case REG_NWRAM_CTRL_SET2BANK0: + case REG_NWRAM_CTRL_SET2BANK1: + case REG_NWRAM_CTRL_SET2BANK2: + case REG_NWRAM_CTRL_SET2BANK3: + case REG_NWRAM_CTRL_SET2BANK4: + case REG_NWRAM_CTRL_SET2BANK5: + case REG_NWRAM_CTRL_SET2BANK6: + case REG_NWRAM_CTRL_SET2BANK7: + /* These registers can not be changed by the arm7, as of a fuse bit in SCFG + TODO: If that SFCG is implemented this might get writeable */ + return; + case REG_NWRAM_WINDOW_SET0: + case REG_NWRAM_WINDOW_SET0 + 1: + case REG_NWRAM_WINDOW_SET0 + 2: + case REG_NWRAM_WINDOW_SET0 + 3: + case REG_NWRAM_WINDOW_SET1: + case REG_NWRAM_WINDOW_SET1 + 1: + case REG_NWRAM_WINDOW_SET1 + 2: + case REG_NWRAM_WINDOW_SET1 + 3: + case REG_NWRAM_WINDOW_SET2: + case REG_NWRAM_WINDOW_SET2 + 1: + case REG_NWRAM_WINDOW_SET2 + 2: + case REG_NWRAM_WINDOW_SET2 + 3: + MMU.regNWRAM_Windows[0][(adr - REG_NWRAM_WINDOW_SET0) >> 2] &= ~(0xffff << ((adr & 2) * 8)); + MMU.regNWRAM_Windows[0][(adr - REG_NWRAM_WINDOW_SET0) >> 2] |= (val << ((adr & 2) * 8)); + MMU_UpdateNWRAM(); + return; + case REG_NWRAM_PROTECT: + case REG_NWRAM_PROTECT + 1: + case REG_NWRAM_PROTECT + 2: + case REG_NWRAM_PROTECT + 3: + MMU.regNWRAM_Protect &= ~(0xffff << ((adr & 2) * 8)); + MMU.regNWRAM_Protect |= (val << ((adr & 2) * 8)); + return; +#endif } T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][adr>>20], adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20], val); return; } + +#ifdef DSI_NEWWRAM + if ((adr >> 24) == 0x03) + { + if (MMU.NWRAMBLOCKPTRS[0][(adr - 0x03000000) / 0x8000]) + { + T1WriteWord(MMU.NWRAMBLOCKPTRS[0][(adr - 0x03000000) / 0x8000], adr & 0x7fff, val); + return; + } + } +#endif + bool unmapped, restricted; adr = MMU_LCDmap(adr,unmapped, restricted); if(unmapped) return; @@ -5546,11 +6046,68 @@ void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val) case REG_GCDATAIN: MMU_writeToGC(val); return; +#ifdef DSI_NEWWRAM + case REG_NWRAM_CTRL_SET0BANK0: + case REG_NWRAM_CTRL_SET0BANK1: + case REG_NWRAM_CTRL_SET0BANK2: + case REG_NWRAM_CTRL_SET0BANK3: + case REG_NWRAM_CTRL_SET1BANK0: + case REG_NWRAM_CTRL_SET1BANK1: + case REG_NWRAM_CTRL_SET1BANK2: + case REG_NWRAM_CTRL_SET1BANK3: + case REG_NWRAM_CTRL_SET1BANK4: + case REG_NWRAM_CTRL_SET1BANK5: + case REG_NWRAM_CTRL_SET1BANK6: + case REG_NWRAM_CTRL_SET1BANK7: + case REG_NWRAM_CTRL_SET2BANK0: + case REG_NWRAM_CTRL_SET2BANK1: + case REG_NWRAM_CTRL_SET2BANK2: + case REG_NWRAM_CTRL_SET2BANK3: + case REG_NWRAM_CTRL_SET2BANK4: + case REG_NWRAM_CTRL_SET2BANK5: + case REG_NWRAM_CTRL_SET2BANK6: + case REG_NWRAM_CTRL_SET2BANK7: + /* These registers can not be changed by the arm7, as of a fuse bit in SCFG + TODO: If that SFCG is implemented this might get writeable */ + return; + case REG_NWRAM_WINDOW_SET0: + case REG_NWRAM_WINDOW_SET0 + 1: + case REG_NWRAM_WINDOW_SET0 + 2: + case REG_NWRAM_WINDOW_SET0 + 3: + case REG_NWRAM_WINDOW_SET1: + case REG_NWRAM_WINDOW_SET1 + 1: + case REG_NWRAM_WINDOW_SET1 + 2: + case REG_NWRAM_WINDOW_SET1 + 3: + case REG_NWRAM_WINDOW_SET2: + case REG_NWRAM_WINDOW_SET2 + 1: + case REG_NWRAM_WINDOW_SET2 + 2: + case REG_NWRAM_WINDOW_SET2 + 3: + MMU.regNWRAM_Windows[0][(adr - REG_NWRAM_WINDOW_SET0) >> 2] = val; + MMU_UpdateNWRAM(); + return; + case REG_NWRAM_PROTECT: + case REG_NWRAM_PROTECT + 1: + case REG_NWRAM_PROTECT + 2: + case REG_NWRAM_PROTECT + 3: + MMU.regNWRAM_Protect = val; + return; +#endif } T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr>>20], val); return; } +#ifdef DSI_NEWWRAM + if ((adr >> 24) == 0x03) + { + if (MMU.NWRAMBLOCKPTRS[0][(adr - 0x03000000) / 0x8000]) + { + T1WriteLong(MMU.NWRAMBLOCKPTRS[0][(adr - 0x03000000) / 0x8000], adr & 0x7fff, val); + return; + } + } +#endif + bool unmapped, restricted; adr = MMU_LCDmap(adr,unmapped, restricted); if(unmapped) return; @@ -5638,11 +6195,60 @@ u8 FASTCALL _MMU_ARM7_read08(u32 adr) case REG_TM3CNTL+1: return _MMU_ARM7_read16(adr-1)>>8; case REG_TM3CNTL+2: return _MMU_ARM7_read16(adr); case REG_TM3CNTL+3: return _MMU_ARM7_read16(adr-1)>>8; +#ifdef DSI_NEWWRAM + case REG_NWRAM_CTRL_SET0BANK0: + case REG_NWRAM_CTRL_SET0BANK1: + case REG_NWRAM_CTRL_SET0BANK2: + case REG_NWRAM_CTRL_SET0BANK3: + case REG_NWRAM_CTRL_SET1BANK0: + case REG_NWRAM_CTRL_SET1BANK1: + case REG_NWRAM_CTRL_SET1BANK2: + case REG_NWRAM_CTRL_SET1BANK3: + case REG_NWRAM_CTRL_SET1BANK4: + case REG_NWRAM_CTRL_SET1BANK5: + case REG_NWRAM_CTRL_SET1BANK6: + case REG_NWRAM_CTRL_SET1BANK7: + case REG_NWRAM_CTRL_SET2BANK0: + case REG_NWRAM_CTRL_SET2BANK1: + case REG_NWRAM_CTRL_SET2BANK2: + case REG_NWRAM_CTRL_SET2BANK3: + case REG_NWRAM_CTRL_SET2BANK4: + case REG_NWRAM_CTRL_SET2BANK5: + case REG_NWRAM_CTRL_SET2BANK6: + case REG_NWRAM_CTRL_SET2BANK7: + return MMU.regNRWAM_BankControl[adr - REG_NWRAM_CTRL_SET0BANK0]; + case REG_NWRAM_WINDOW_SET0: + case REG_NWRAM_WINDOW_SET0 + 1: + case REG_NWRAM_WINDOW_SET0 + 2: + case REG_NWRAM_WINDOW_SET0 + 3: + case REG_NWRAM_WINDOW_SET1: + case REG_NWRAM_WINDOW_SET1 + 1: + case REG_NWRAM_WINDOW_SET1 + 2: + case REG_NWRAM_WINDOW_SET1 + 3: + case REG_NWRAM_WINDOW_SET2: + case REG_NWRAM_WINDOW_SET2 + 1: + case REG_NWRAM_WINDOW_SET2 + 2: + case REG_NWRAM_WINDOW_SET2 + 3: + return (MMU.regNWRAM_Windows[0][(adr - REG_NWRAM_WINDOW_SET0) >> 2] >> ((adr & 3) * 8)) & 0xff; + case REG_NWRAM_PROTECT: + case REG_NWRAM_PROTECT + 1: + case REG_NWRAM_PROTECT + 2: + case REG_NWRAM_PROTECT + 3: + return (MMU.regNWRAM_Protect >> ((adr & 3) * 8)) & 0xff; +#endif } return MMU.MMU_MEM[ARMCPU_ARM7][adr>>20][adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]]; } +#ifdef DSI_NEWWRAM + if ((adr >> 24) == 0x03) + { + if (MMU.NWRAMBLOCKPTRS[0][(adr - 0x03000000) / 0x8000]) + return MMU.NWRAMBLOCKPTRS[0][(adr - 0x03000000) / 0x8000][adr & 0x7fff]; + } +#endif + bool unmapped, restricted; adr = MMU_LCDmap(adr,unmapped, restricted); if(unmapped) return 0; @@ -5723,10 +6329,58 @@ u16 FASTCALL _MMU_ARM7_read16(u32 adr) //since the arm7 polls this (and EXTKEYIN) every frame, we shouldnt count this as an input check //LagFrameFlag=0; break; +#ifdef DSI_NEWWRAM + case REG_NWRAM_CTRL_SET0BANK0: + case REG_NWRAM_CTRL_SET0BANK1: + case REG_NWRAM_CTRL_SET0BANK2: + case REG_NWRAM_CTRL_SET0BANK3: + case REG_NWRAM_CTRL_SET1BANK0: + case REG_NWRAM_CTRL_SET1BANK1: + case REG_NWRAM_CTRL_SET1BANK2: + case REG_NWRAM_CTRL_SET1BANK3: + case REG_NWRAM_CTRL_SET1BANK4: + case REG_NWRAM_CTRL_SET1BANK5: + case REG_NWRAM_CTRL_SET1BANK6: + case REG_NWRAM_CTRL_SET1BANK7: + case REG_NWRAM_CTRL_SET2BANK0: + case REG_NWRAM_CTRL_SET2BANK1: + case REG_NWRAM_CTRL_SET2BANK2: + case REG_NWRAM_CTRL_SET2BANK3: + case REG_NWRAM_CTRL_SET2BANK4: + case REG_NWRAM_CTRL_SET2BANK5: + case REG_NWRAM_CTRL_SET2BANK6: + return MMU.regNRWAM_BankControl[adr - REG_NWRAM_CTRL_SET0BANK0] | (MMU.regNRWAM_BankControl[adr + 1 - REG_NWRAM_CTRL_SET0BANK0] << 8); + case REG_NWRAM_WINDOW_SET0: + case REG_NWRAM_WINDOW_SET0 + 1: + case REG_NWRAM_WINDOW_SET0 + 2: + case REG_NWRAM_WINDOW_SET0 + 3: + case REG_NWRAM_WINDOW_SET1: + case REG_NWRAM_WINDOW_SET1 + 1: + case REG_NWRAM_WINDOW_SET1 + 2: + case REG_NWRAM_WINDOW_SET1 + 3: + case REG_NWRAM_WINDOW_SET2: + case REG_NWRAM_WINDOW_SET2 + 1: + case REG_NWRAM_WINDOW_SET2 + 2: + case REG_NWRAM_WINDOW_SET2 + 3: + return (MMU.regNWRAM_Windows[0][(adr - REG_NWRAM_WINDOW_SET0) >> 2] >> ((adr & 2) * 8)) & 0xffff; + case REG_NWRAM_PROTECT: + case REG_NWRAM_PROTECT + 1: + case REG_NWRAM_PROTECT + 2: + case REG_NWRAM_PROTECT + 3: + return (MMU.regNWRAM_Protect >> ((adr & 2) * 8)) & 0xffff; +#endif } return T1ReadWord_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]); } +#ifdef DSI_NEWWRAM + if ((adr >> 24) == 0x03) + { + if (MMU.NWRAMBLOCKPTRS[0][(adr - 0x03000000) / 0x8000]) + return T1ReadWord_guaranteedAligned(MMU.NWRAMBLOCKPTRS[0][(adr - 0x03000000) / 0x8000], adr & 0x7fff); + } +#endif + bool unmapped, restricted; adr = MMU_LCDmap(adr,unmapped, restricted); if(unmapped) return 0; @@ -5804,11 +6458,58 @@ u32 FASTCALL _MMU_ARM7_read32(u32 adr) //make sure WRAMSTAT is stashed and then fallthrough return the value from memory. i know, gross. T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x241, MMU.WRAMCNT); break; +#ifdef DSI_NEWWRAM + case REG_NWRAM_CTRL_SET0BANK0: + case REG_NWRAM_CTRL_SET0BANK1: + case REG_NWRAM_CTRL_SET0BANK2: + case REG_NWRAM_CTRL_SET0BANK3: + case REG_NWRAM_CTRL_SET1BANK0: + case REG_NWRAM_CTRL_SET1BANK1: + case REG_NWRAM_CTRL_SET1BANK2: + case REG_NWRAM_CTRL_SET1BANK3: + case REG_NWRAM_CTRL_SET1BANK4: + case REG_NWRAM_CTRL_SET1BANK5: + case REG_NWRAM_CTRL_SET1BANK6: + case REG_NWRAM_CTRL_SET1BANK7: + case REG_NWRAM_CTRL_SET2BANK0: + case REG_NWRAM_CTRL_SET2BANK1: + case REG_NWRAM_CTRL_SET2BANK2: + case REG_NWRAM_CTRL_SET2BANK3: + case REG_NWRAM_CTRL_SET2BANK4: + return MMU.regNRWAM_BankControl[adr - REG_NWRAM_CTRL_SET0BANK0] | (MMU.regNRWAM_BankControl[adr + 1 - REG_NWRAM_CTRL_SET0BANK0] << 8) + | (MMU.regNRWAM_BankControl[adr + 2 - REG_NWRAM_CTRL_SET0BANK0] << 16) | (MMU.regNRWAM_BankControl[adr + 3 - REG_NWRAM_CTRL_SET0BANK0] << 24); + case REG_NWRAM_WINDOW_SET0: + case REG_NWRAM_WINDOW_SET0 + 1: + case REG_NWRAM_WINDOW_SET0 + 2: + case REG_NWRAM_WINDOW_SET0 + 3: + case REG_NWRAM_WINDOW_SET1: + case REG_NWRAM_WINDOW_SET1 + 1: + case REG_NWRAM_WINDOW_SET1 + 2: + case REG_NWRAM_WINDOW_SET1 + 3: + case REG_NWRAM_WINDOW_SET2: + case REG_NWRAM_WINDOW_SET2 + 1: + case REG_NWRAM_WINDOW_SET2 + 2: + case REG_NWRAM_WINDOW_SET2 + 3: + return MMU.regNWRAM_Windows[1][(adr - REG_NWRAM_WINDOW_SET0) >> 2]; + case REG_NWRAM_PROTECT: + case REG_NWRAM_PROTECT + 1: + case REG_NWRAM_PROTECT + 2: + case REG_NWRAM_PROTECT + 3: + return MMU.regNWRAM_Protect; +#endif } return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr>>20]); } +#ifdef DSI_NEWWRAM + if ((adr >> 24) == 0x03) + { + if (MMU.NWRAMBLOCKPTRS[0][(adr - 0x03000000) / 0x8000]) + return T1ReadLong_guaranteedAligned(MMU.NWRAMBLOCKPTRS[0][(adr - 0x03000000) / 0x8000], adr & 0x7fff); + } +#endif + bool unmapped, restricted; adr = MMU_LCDmap(adr,unmapped, restricted); if(unmapped) return 0; @@ -5818,6 +6519,96 @@ u32 FASTCALL _MMU_ARM7_read32(u32 adr) return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][adr >> 20], adr & MMU.MMU_MASK[ARMCPU_ARM7][adr >> 20]); } +#ifdef DSI_NEWWRAM + + +#pragma optimize( "g", off) +//================================================= MMU Update new WRAM Mapping +void FASTCALL MMU_UpdateNWRAM() +{ + // move through all 32k Blocks in the 0x03000000 to 0x03FFFFFF range. The range consists of 512 blocks + // and check where the data for the arm7/arm9 shall point to + // TODO: This does not work when blending NWRAM into the HW Register range + uint32_t blockLimits[12]; + uint32_t arm9BlockLimits[6]; + + // pre calculate the window limits in 32k Blocks for each core and window + for (int i = 0; i < 2; i++) + { + blockLimits[i * 6 + 0] = (MMU.regNWRAM_Windows[i][0] & 0x0FF0) >> 3; + blockLimits[i * 6 + 2] = (MMU.regNWRAM_Windows[i][1] & 0x0FF8) >> 3; + blockLimits[i * 6 + 4] = (MMU.regNWRAM_Windows[i][2] & 0x0FF8) >> 3; + blockLimits[i * 6 + 1] = (MMU.regNWRAM_Windows[i][0] & 0x0FF00000) >> 19; + blockLimits[i * 6 + 3] = (MMU.regNWRAM_Windows[i][1] & 0x0FF80000) >> 19; + blockLimits[i * 6 + 5] = (MMU.regNWRAM_Windows[i][2] & 0x0FF80000) >> 19; + } + + // now check every block in the 0x03... range to which nwram page it belongs + for (int block = 0; block < 512; block++) + { + for (int core = 0; core < 2; core++) + { + u8* data = 0; + for (int set = 0; (set < 3) && (data == 0); set++) + { + // for each of the 3 sets + if ((block >= blockLimits[core * 6 + set * 2]) && (block < blockLimits[core * 6 + set * 2 + 1])) + { + // This set is blended in at this region + uint8_t sectorLength = (MMU.regNWRAM_Windows[core][set] >> 12) & 0x03; + // the first set does not know an image size of 32kB (0) and will default to 64kB (1) + if ((sectorLength == 0) && (set == 0)) + sectorLength = 1; + uint8_t sectorBlocks = 1 << sectorLength; + uint8_t sectorPart = block & (sectorBlocks - 1); + // now iterate through all banks in the set and check if it is + // enabled & assigned to the core + if (set == 0) + { + // the set A is special as it combines two 32kB blocks into a single 64kB Block + // therefor we have only 4 bank controls which are matching for 2 blocks each + for (int bank = 0; bank < 4; bank++) + { + if (!(MMU.regNRWAM_BankControl[bank] & 0x80)) // not enabled + continue; + if ((MMU.regNRWAM_BankControl[bank] & 0x03) != (1 - core)) // assigned to dsp or different core + continue; + if (((MMU.regNRWAM_BankControl[bank] >> 2) & 6) != (sectorPart & ~1)) + continue; + // when this is reached, the current block is found in this set for this core + // So remember the data it shall point to + // for the first set the parts are of 2 blocks + data = &MMU.NWRAM[set][bank | (sectorPart & 1)][0]; + } + } + else + { + // otherwise it is a regular set with each 32kB block having its own bank control register + for (int bank = 0; bank < 8; bank++) + { + if (!(MMU.regNRWAM_BankControl[bank + set * 8 - 4] & 0x80)) // not enabled + continue; + if ((MMU.regNRWAM_BankControl[bank + set * 8 - 4] & 0x03) != (1 - core)) // assigned to dsp or different core + continue; + if (((MMU.regNRWAM_BankControl[bank + set * 8 - 4] >> 2) & 7) != sectorPart) + continue; + // when this is reached, the current block is found in this set for this core + // So remember the data it shall point to + // for the first set the parts are of 2 blocks + data = &MMU.NWRAM[set][bank][0]; + } + } + } + } + MMU.NWRAMBLOCKPTRS[core][block] = data; + } + } + // TODO +} +#pragma optimize( "g", on) + +#endif + //========================================================================================================= u32 FASTCALL MMU_read32(u32 proc, u32 adr) diff --git a/desmume/src/MMU.h b/desmume/src/MMU.h index 6091a2723..ebeb1b54e 100644 --- a/desmume/src/MMU.h +++ b/desmume/src/MMU.h @@ -402,6 +402,25 @@ struct MMU_struct //32KB of shared WRAM - can be switched between ARM7 & ARM9 in two blocks u8 SWIRAM[0x8000]; +#ifdef DSI_NEWWRAM + // new shared WRAM, 3 banks, each of 256k + // smallest chunk to blend in is 32k + u8 NWRAM[3][8][32 * 1024]; + + // Control register for each bank (named MBK?.? in gbatek) + u8 regNRWAM_BankControl[20]; + // Window control registers. One set of 3 for each core + u32 regNWRAM_Windows[2][3]; + // Bank control write protection register + u32 regNWRAM_Protect; + + // Pointer for each block of the region from 0x03000000 to 0x03ffffff + // for each core. This way the memory lookup must not calculate the effective + // WRAM address on each access but prepares these pointers only when the + // window or bank registers changed. + u8* NWRAMBLOCKPTRS[2][512] ; +#endif + //Unused ram u8 UNUSED_RAM[4]; diff --git a/desmume/src/frontend/windows/DeSmuME.vcxproj b/desmume/src/frontend/windows/DeSmuME.vcxproj index f6aadc49c..6a9db20f9 100644 --- a/desmume/src/frontend/windows/DeSmuME.vcxproj +++ b/desmume/src/frontend/windows/DeSmuME.vcxproj @@ -51,6 +51,11 @@ + + + HAVE_LIBAGG=1;HAVE_JIT=1;HAVE_LUA=1;%(PreprocessorDefinitions);DSI_NEWWRAM + + diff --git a/desmume/src/frontend/windows/IORegView.cpp b/desmume/src/frontend/windows/IORegView.cpp index 02495891e..a870e2589 100644 --- a/desmume/src/frontend/windows/IORegView.cpp +++ b/desmume/src/frontend/windows/IORegView.cpp @@ -229,7 +229,122 @@ IOReg IORegs9[] = { {"DMA 1",9,1},{"DMA 2",10,1},{"DMA 3",11,1},{"Keypad",12,1}, {"Game Pak",13,1},{"IPC sync",16,1},{"IPC send FIFO empty",17,1},{"IPC recv FIFO not empty",18,1}, {"Gamecard transfer",19,1},{"Gamecard IREQ_MC",20,1},{"GX FIFO",21,1}}}, - +#ifdef DSI_NEWWRAM + { CatBegin, "NWRAM registers", 0, 4, 0, {{0}} }, + { MMIOReg, "NWRAMCTRL_S0B0", REG_NWRAM_CTRL_SET0BANK0, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S0B1", REG_NWRAM_CTRL_SET0BANK1, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S0B2", REG_NWRAM_CTRL_SET0BANK2, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S0B3", REG_NWRAM_CTRL_SET0BANK3, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S1B0", REG_NWRAM_CTRL_SET0BANK0, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S1B1", REG_NWRAM_CTRL_SET1BANK1, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S1B2", REG_NWRAM_CTRL_SET1BANK2, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S1B3", REG_NWRAM_CTRL_SET1BANK3, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S1B4", REG_NWRAM_CTRL_SET1BANK4, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S1B5", REG_NWRAM_CTRL_SET1BANK5, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S1B6", REG_NWRAM_CTRL_SET1BANK6, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S1B7", REG_NWRAM_CTRL_SET1BANK7, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S2B0", REG_NWRAM_CTRL_SET1BANK0, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S2B1", REG_NWRAM_CTRL_SET1BANK1, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S2B2", REG_NWRAM_CTRL_SET1BANK2, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S2B3", REG_NWRAM_CTRL_SET1BANK3, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S2B4", REG_NWRAM_CTRL_SET1BANK4, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S2B5", REG_NWRAM_CTRL_SET1BANK5, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S2B6", REG_NWRAM_CTRL_SET1BANK6, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_S2B7", REG_NWRAM_CTRL_SET1BANK7, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}} }, + { MMIOReg, "NWRAMCTRL_WINDOW_0", REG_NWRAM_WINDOW_SET0, 4, 3, { + {"Start block", 3, 8}, + {"End Block", 19, 10}, + {"Image Size", 12, 2}} }, + { MMIOReg, "NWRAMCTRL_WINDOW_1", REG_NWRAM_WINDOW_SET1, 4, 3, { + {"Start block", 3, 8}, + {"End Block", 19, 10}, + {"Image Size", 12, 2}} }, + { MMIOReg, "NWRAMCTRL_WINDOW_2", REG_NWRAM_WINDOW_SET2, 4, 3, { + {"Start block", 3, 8}, + {"End Block", 19, 10}, + {"Image Size", 12, 2}} }, + { MMIOReg, "NWRAMCTRL_PROTECT", REG_NWRAM_PROTECT, 4, 20, { + {"Set 0 Part 0 Protected", 0, 1}, + {"Set 0 Part 1 Protected", 1, 1}, + {"Set 0 Part 2 Protected", 2, 1}, + {"Set 0 Part 3 Protected", 3, 1}, + {"Set 1 Part 0 Protected", 8, 1}, + {"Set 1 Part 1 Protected", 9, 1}, + {"Set 1 Part 2 Protected", 10, 1}, + {"Set 1 Part 3 Protected", 11, 1}, + {"Set 1 Part 4 Protected", 12, 1}, + {"Set 1 Part 5 Protected", 13, 1}, + {"Set 1 Part 6 Protected", 14, 1}, + {"Set 1 Part 7 Protected", 15, 1}, + {"Set 2 Part 0 Protected", 16, 1}, + {"Set 2 Part 1 Protected", 17, 1}, + {"Set 2 Part 2 Protected", 18, 1}, + {"Set 2 Part 3 Protected", 19, 1}, + {"Set 2 Part 4 Protected", 20, 1}, + {"Set 2 Part 5 Protected", 21, 1}, + {"Set 2 Part 6 Protected", 22, 1}, + {"Set 2 Part 7 Protected", 23, 1}} }, +#endif {ListEnd, "", 0, 0, 0, {{0}}} }; @@ -271,8 +386,124 @@ IOReg IORegs7[] = { {MMIOReg, "DMA3SAD", REG_DMA3SAD, 4, 1, {{"Value",0,27}}}, {MMIOReg, "DMA3DAD", REG_DMA3DAD, 4, 1, {{"Value",0,27}}}, {MMIOReg, "DMA3CNT", REG_DMA3CNTL, 4, 8, {{"Word Count",0,21}, {"Dest update method",21,2}, {"Src update method",23,2}, {"Repeat Flag",25,1}, {"32bit Width Enable",26,1},{"Start Mode",28,2}, {"IRQ Enable",30,1}, {"Enabled",31,1}}}, - - +#ifdef DSI_NEWWRAM + {CatBegin, "NWRAM registers", 0, 4, 0, {{0}}}, + {MMIOReg, "NWRAMCTRL_S0B0", REG_NWRAM_CTRL_SET0BANK0, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S0B1", REG_NWRAM_CTRL_SET0BANK1, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S0B2", REG_NWRAM_CTRL_SET0BANK2, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S0B3", REG_NWRAM_CTRL_SET0BANK3, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S1B0", REG_NWRAM_CTRL_SET0BANK0, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S1B1", REG_NWRAM_CTRL_SET1BANK1, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S1B2", REG_NWRAM_CTRL_SET1BANK2, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S1B3", REG_NWRAM_CTRL_SET1BANK3, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S1B4", REG_NWRAM_CTRL_SET1BANK4, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S1B5", REG_NWRAM_CTRL_SET1BANK5, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S1B6", REG_NWRAM_CTRL_SET1BANK6, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S1B7", REG_NWRAM_CTRL_SET1BANK7, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S2B0", REG_NWRAM_CTRL_SET1BANK0, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S2B1", REG_NWRAM_CTRL_SET1BANK1, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S2B2", REG_NWRAM_CTRL_SET1BANK2, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S2B3", REG_NWRAM_CTRL_SET1BANK3, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S2B4", REG_NWRAM_CTRL_SET1BANK4, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S2B5", REG_NWRAM_CTRL_SET1BANK5, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S2B6", REG_NWRAM_CTRL_SET1BANK6, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + {MMIOReg, "NWRAMCTRL_S2B7", REG_NWRAM_CTRL_SET1BANK7, 1, 3, { + {"Enable", 7, 1}, + {"Block", 2, 2}, + {"Owner", 0, 2}}}, + { MMIOReg, "NWRAMCTRL_WINDOW_0", REG_NWRAM_WINDOW_SET0, 4, 3, { + {"Start block", 3, 8}, + {"End Block", 19, 10}, + {"Image Size", 12, 2}} }, + { MMIOReg, "NWRAMCTRL_WINDOW_1", REG_NWRAM_WINDOW_SET1, 4, 3, { + {"Start block", 3, 8}, + {"End Block", 19, 10}, + {"Image Size", 12, 2}} }, + { MMIOReg, "NWRAMCTRL_WINDOW_2", REG_NWRAM_WINDOW_SET2, 4, 3, { + {"Start block", 3, 8}, + {"End Block", 19, 10}, + {"Image Size", 12, 2}} }, + { MMIOReg, "NWRAMCTRL_PROTECT", REG_NWRAM_PROTECT, 4, 20, { + {"Set 0 Part 0 Protected", 0, 1}, + {"Set 0 Part 1 Protected", 1, 1}, + {"Set 0 Part 2 Protected", 2, 1}, + {"Set 0 Part 3 Protected", 3, 1}, + {"Set 1 Part 0 Protected", 8, 1}, + {"Set 1 Part 1 Protected", 9, 1}, + {"Set 1 Part 2 Protected", 10, 1}, + {"Set 1 Part 3 Protected", 11, 1}, + {"Set 1 Part 4 Protected", 12, 1}, + {"Set 1 Part 5 Protected", 13, 1}, + {"Set 1 Part 6 Protected", 14, 1}, + {"Set 1 Part 7 Protected", 15, 1}, + {"Set 2 Part 0 Protected", 16, 1}, + {"Set 2 Part 1 Protected", 17, 1}, + {"Set 2 Part 2 Protected", 18, 1}, + {"Set 2 Part 3 Protected", 19, 1}, + {"Set 2 Part 4 Protected", 20, 1}, + {"Set 2 Part 5 Protected", 21, 1}, + {"Set 2 Part 6 Protected", 22, 1}, + {"Set 2 Part 7 Protected", 23, 1}} }, +#endif + + {ListEnd, "", 0, 0, 0, {{0}}} }; diff --git a/desmume/src/registers.h b/desmume/src/registers.h index 30d16a463..8a910937f 100644 --- a/desmume/src/registers.h +++ b/desmume/src/registers.h @@ -227,6 +227,34 @@ #define REG_DISPB_BLDY 0x04001054 #define REG_DISPB_MASTERBRIGHT 0x0400106C +// NWRAM Ports +#ifdef DSI_NEWWRAM +#define REG_NWRAM_CTRL_SET0BANK0 0x04004040 +#define REG_NWRAM_CTRL_SET0BANK1 0x04004041 +#define REG_NWRAM_CTRL_SET0BANK2 0x04004042 +#define REG_NWRAM_CTRL_SET0BANK3 0x04004043 +#define REG_NWRAM_CTRL_SET1BANK0 0x04004044 +#define REG_NWRAM_CTRL_SET1BANK1 0x04004045 +#define REG_NWRAM_CTRL_SET1BANK2 0x04004046 +#define REG_NWRAM_CTRL_SET1BANK3 0x04004047 +#define REG_NWRAM_CTRL_SET1BANK4 0x04004048 +#define REG_NWRAM_CTRL_SET1BANK5 0x04004049 +#define REG_NWRAM_CTRL_SET1BANK6 0x0400404a +#define REG_NWRAM_CTRL_SET1BANK7 0x0400404b +#define REG_NWRAM_CTRL_SET2BANK0 0x0400404c +#define REG_NWRAM_CTRL_SET2BANK1 0x0400404d +#define REG_NWRAM_CTRL_SET2BANK2 0x0400404e +#define REG_NWRAM_CTRL_SET2BANK3 0x0400404f +#define REG_NWRAM_CTRL_SET2BANK4 0x04004050 +#define REG_NWRAM_CTRL_SET2BANK5 0x04004051 +#define REG_NWRAM_CTRL_SET2BANK6 0x04004052 +#define REG_NWRAM_CTRL_SET2BANK7 0x04004053 +#define REG_NWRAM_WINDOW_SET0 0x04004054 +#define REG_NWRAM_WINDOW_SET1 0x04004058 +#define REG_NWRAM_WINDOW_SET2 0x0400405c +#define REG_NWRAM_PROTECT 0x04004060 +#endif + // Receive ports #define REG_IPCFIFORECV 0x04100000 #define REG_GCDATAIN 0x04100010 From a44d7ff4061bb9ba31697d048d2e2f72420c927b Mon Sep 17 00:00:00 2001 From: Tim Seidel Date: Tue, 6 Jul 2021 11:10:53 +0200 Subject: [PATCH 2/2] NWRAM Initialization for a consistent startup setting. (Was handled by the default initialization, which might not be valid in all compiler settings) --- desmume/src/MMU.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 3a7ee9f23..2e8b04faa 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -911,7 +911,7 @@ void MMU_Init(void) LOG("MMU init\n"); memset(&MMU, 0, sizeof(MMU_struct)); - + MMU.blank_memory = &MMU.ARM9_LCD[0xA4000]; //MMU.DTCMRegion = 0x027C0000; @@ -930,14 +930,29 @@ void MMU_Init(void) MMU.fw.isFirmware = true; rtcInit(); - + slot1_Init(); slot2_Init(); - - if(Mic_Init() == FALSE) + + if (Mic_Init() == FALSE) INFO("Microphone init failed.\n"); else INFO("Microphone successfully inited.\n"); + +#ifdef DSI_NEWWRAM + // Disable all NWRAM Banks on Init + for (int i = 0; i < 20; i++) + MMU.regNRWAM_BankControl[i] = 0; + // Disable all Windows + for (int i = 0; i < 2; i++) + for (int q = 0; q < 3; q++) + MMU.regNWRAM_Windows[i][q] = 0; + // No Write Protection + MMU.regNWRAM_Protect = 0 ; + // update internal data from these init settings + MMU_UpdateNWRAM(); +#endif + } void MMU_DeInit(void) {