aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDesperateProgrammer <Tim.seidel@rwth-Aachen.de>2021-07-23 12:21:54 +0200
committerGitHub <noreply@github.com>2021-07-23 12:21:54 +0200
commitb1c2665c398c06a69f4a70736b1e6e34d3b5f741 (patch)
tree88455cf07331bf088289ee268f2daaee813de183 /src
parenta09ce44c486c809343b4e8565e0040f7570ada9e (diff)
NWRAM & Direct Boot (#1149)
* SCFG_BIOS now selects between NDS and DSi BIOS Allowing experimental direct boot. * - making NWRAM Priorities work as in the HW - fixed loading DSi stage2 Bootloader when in direct boot (should not be loaded) and might interfere with the image loaded into the (N)WRAM previously * NWRAM and SCFG Registers are now write-guarded by the corresponding SCFG_EXT7/9 Bits * removed debugging remainder * Moved NDSHeader dependent SCFG initialization into the new DSi::SetupDirectBoot function called from NDS::SetupDirectBoot when ConsoleType is DSi * removed redundant SCFG_BIOS bit checks * Set of changes from RSDuck's review * removed a forgotten comment * - removed the guarded debug outputs for NWRAM - NWRAM writes to bank and window registers now apply their write masks. - added comment on an existing TODO within the code describing, why this is OK - fixed initial NWRAM bank reset just accessing set A * NWRAM not mapped to 03... range if bit25 in SCFG_EXT is cleared * removed NWRAM write block on cleared bit25 in SCFG_EXT * changed type of iterator for MapNWRAM_x functions from s8 to int * - reduced calculations/comparisons on NWRAM write operations - changed u8 to unsigned int for an iterator MapNWRAM_x Co-authored-by: Tim Seidel <t.seidel@kts-systeme.de>
Diffstat (limited to 'src')
-rw-r--r--src/DSi.cpp1005
-rw-r--r--src/DSi.h1
-rw-r--r--src/NDS.cpp10
3 files changed, 698 insertions, 318 deletions
diff --git a/src/DSi.cpp b/src/DSi.cpp
index b55992c..b22dc8f 100644
--- a/src/DSi.cpp
+++ b/src/DSi.cpp
@@ -162,6 +162,7 @@ void Reset()
SCFG_EXT[1] = 0x93FFFB06;
SCFG_MC = 0x0010;//0x0011;
SCFG_RST = 0;
+
DSi_DSP::SetRstLine(false);
// LCD init flag
@@ -185,6 +186,39 @@ void Reset()
ARM7Write16(eaddr+0x42, 0x0001);
}
+void SetupDirectBoot()
+{
+ // If loading a NDS directly, this value should be set
+ // depending on the console type in the header at offset 12h
+ switch (NDSCart::Header.UnitCode)
+ {
+ case 0x00: /* NDS Image */
+ // on a pure NDS Image, we disable all extended features
+ // TODO: For now keep the features enabled, as you can run pure NDS in NDS Emulation anyway
+ SCFG_BIOS = 0x0303;
+ break;
+ case 0x02: /* DSi Enhanced Image */
+ SCFG_BIOS = 0x0303;
+ break;
+ default:
+ SCFG_BIOS = 0x0101; // TODO: should be zero when booting from BIOS
+ break;
+ }
+ // no NWRAM Mapping
+ for (int i = 0; i < 4; i++)
+ MapNWRAM_A(i, 0);
+ for (int i = 0; i < 8; i++)
+ MapNWRAM_B(i, 0);
+ for (int i = 0; i < 8; i++)
+ MapNWRAM_C(i, 0);
+ // No NWRAM Window
+ for (int i = 0; i < 3; i++)
+ {
+ MapNWRAMRange(0, i, 0);
+ MapNWRAMRange(1, i, 0);
+ }
+}
+
void SoftReset()
{
// TODO: check exactly what is reset
@@ -572,6 +606,10 @@ void StopNDMAs(u32 cpu, u32 mode)
void MapNWRAM_A(u32 num, u8 val)
{
+ // NWRAM Bank A does not allow all bits to be set
+ // possible non working combinations are caught by later code, but these are not set-able at all
+ val &= ~0x72;
+
if (MBK[0][8] & (1 << num))
{
printf("trying to map NWRAM_A %d to %02X, but it is write-protected (%08X)\n", num, val, MBK[0][8]);
@@ -591,22 +629,35 @@ void MapNWRAM_A(u32 num, u8 val)
MBK[0][mbkn] |= (val << mbks);
MBK[1][mbkn] = MBK[0][mbkn];
- u8* ptr = &NWRAM_A[num << 16];
-
- if (oldval & 0x80)
+ // When we only update the mapping on the written MBK, we will
+ // have priority of the last witten MBK over the others
+ // However the hardware has a fixed order. Therefor
+ // we need to iterate through them all in a fixed order and update
+ // the mapping, so the result is independend on the MBK write order
+ for (unsigned int part = 0; part < 4; part++)
{
- if (NWRAMMap_A[oldval & 0x01][(oldval >> 2) & 0x3] == ptr)
- NWRAMMap_A[oldval & 0x01][(oldval >> 2) & 0x3] = NULL;
+ NWRAMMap_A[0][part] = NULL;
+ NWRAMMap_A[1][part] = NULL;
}
-
- if (val & 0x80)
+ for (int part = 3; part >= 0; part--)
{
- NWRAMMap_A[val & 0x01][(val >> 2) & 0x3] = ptr;
+ u8* ptr = &NWRAM_A[part << 16];
+
+ if ((MBK[0][0 + (part / 4)] >> ((part % 4) * 8)) & 0x80)
+ {
+ u8 mVal = (MBK[0][0 + (part / 4)] >> ((part % 4) * 8)) & 0xfd;
+
+ NWRAMMap_A[mVal & 0x03][(mVal >> 2) & 0x3] = ptr;
+ }
}
}
void MapNWRAM_B(u32 num, u8 val)
{
+ // NWRAM Bank B does not allow all bits to be set
+ // possible non working combinations are caught by later code, but these are not set-able at all
+ val &= ~0x60;
+
if (MBK[0][8] & (1 << (8+num)))
{
printf("trying to map NWRAM_B %d to %02X, but it is write-protected (%08X)\n", num, val, MBK[0][8]);
@@ -626,28 +677,42 @@ void MapNWRAM_B(u32 num, u8 val)
MBK[0][mbkn] |= (val << mbks);
MBK[1][mbkn] = MBK[0][mbkn];
- u8* ptr = &NWRAM_B[num << 15];
-
- DSi_DSP::OnMBKCfg('B', num, oldval, val, ptr);
-
- if (oldval & 0x80)
+ // When we only update the mapping on the written MBK, we will
+ // have priority of the last witten MBK over the others
+ // However the hardware has a fixed order. Therefor
+ // we need to iterate through them all in a fixed order and update
+ // the mapping, so the result is independend on the MBK write order
+ for (unsigned int part = 0; part < 8; part++)
{
- if (oldval & 0x02) oldval &= 0xFE;
-
- if (NWRAMMap_B[oldval & 0x03][(oldval >> 2) & 0x7] == ptr)
- NWRAMMap_B[oldval & 0x03][(oldval >> 2) & 0x7] = NULL;
+ NWRAMMap_B[0][part] = NULL;
+ NWRAMMap_B[1][part] = NULL;
+ NWRAMMap_B[2][part] = NULL;
}
-
- if (val & 0x80)
+ for (int part = 7; part >= 0; part--)
{
- if (val & 0x02) val &= 0xFE;
+ u8* ptr = &NWRAM_B[part << 15];
+
+ if (part == num)
+ {
+ DSi_DSP::OnMBKCfg('B', num, oldval, val, ptr);
+ }
- NWRAMMap_B[val & 0x03][(val >> 2) & 0x7] = ptr;
+ if ((MBK[0][1 + (part / 4)] >> ((part % 4) * 8)) & 0x80)
+ {
+ u8 mVal = (MBK[0][1 + (part / 4)] >> ((part % 4) * 8)) & 0xff;
+ if (mVal & 0x02) mVal &= 0xFE;
+
+ NWRAMMap_B[mVal & 0x03][(mVal >> 2) & 0x7] = ptr;
+ }
}
}
void MapNWRAM_C(u32 num, u8 val)
{
+ // NWRAM Bank C does not allow all bits to be set
+ // possible non working combinations are caught by later code, but these are not set-able at all
+ val &= ~0x60;
+
if (MBK[0][8] & (1 << (16+num)))
{
printf("trying to map NWRAM_C %d to %02X, but it is write-protected (%08X)\n", num, val, MBK[0][8]);
@@ -667,28 +732,51 @@ void MapNWRAM_C(u32 num, u8 val)
MBK[0][mbkn] |= (val << mbks);
MBK[1][mbkn] = MBK[0][mbkn];
- u8* ptr = &NWRAM_C[num << 15];
-
- DSi_DSP::OnMBKCfg('C', num, oldval, val, ptr);
-
- if (oldval & 0x80)
+ // When we only update the mapping on the written MBK, we will
+ // have priority of the last witten MBK over the others
+ // However the hardware has a fixed order. Therefor
+ // we need to iterate through them all in a fixed order and update
+ // the mapping, so the result is independend on the MBK write order
+ for (unsigned int part = 0; part < 8; part++)
{
- if (oldval & 0x02) oldval &= 0xFE;
-
- if (NWRAMMap_C[oldval & 0x03][(oldval >> 2) & 0x7] == ptr)
- NWRAMMap_C[oldval & 0x03][(oldval >> 2) & 0x7] = NULL;
+ NWRAMMap_C[0][part] = NULL;
+ NWRAMMap_C[1][part] = NULL;
+ NWRAMMap_C[2][part] = NULL;
}
-
- if (val & 0x80)
+ for (int part = 7; part >= 0; part--)
{
- if (val & 0x02) val &= 0xFE;
+ u8* ptr = &NWRAM_C[part << 15];
+
+ if (part == num)
+ {
+ DSi_DSP::OnMBKCfg('C', num, oldval, val, ptr);
+ }
- NWRAMMap_C[val & 0x03][(val >> 2) & 0x7] = ptr;
+ if ((MBK[0][3 + (part / 4)] >> ((part % 4) * 8)) & 0x80)
+ {
+ u8 mVal = MBK[0][3 + (part / 4)] >> ((part % 4) *8) & 0xff;
+ if (mVal & 0x02) mVal &= 0xFE;
+ NWRAMMap_C[mVal & 0x03][(mVal >> 2) & 0x7] = ptr;
+ }
}
}
void MapNWRAMRange(u32 cpu, u32 num, u32 val)
{
+ // The windowing registers are not writeable in all bits
+ // We need to do this before the change test, so we do not
+ // get false "was changed" fall throughs
+ switch (num)
+ {
+ case 0:
+ val &= ~0xE00FC00F;
+ break;
+ case 1:
+ case 2:
+ val &= ~0xE007C007;
+ break;
+ }
+
u32 oldval = MBK[cpu][5+num];
if (oldval == val) return;
@@ -698,7 +786,14 @@ void MapNWRAMRange(u32 cpu, u32 num, u32 val)
MBK[cpu][5+num] = val;
- // TODO: what happens when the ranges are 'out of range'????
+ // Was TODO: What happens when the ranges are 'out of range'????
+ // Answer: The actual range is limited to 0x03000000 to 0x03ffffff
+ // The NWRAM can not map into the HW Register ranges and is never
+ // mapped there. However the end indizes are allowed to have a value
+ // exceeding that range, in which the accessed area is just cut
+ // at the end of the region
+ // since melonDS does this cut by the case switch in the read/write
+ // functions, we do not need to care here.
if (num == 0)
{
u32 start = 0x03000000 + (((val >> 4) & 0xFF) << 16);
@@ -802,20 +897,24 @@ u8 ARM9Read8(u32 addr)
switch (addr & 0xFF000000)
{
case 0x03000000:
- if (addr >= NWRAMStart[0][0] && addr < NWRAMEnd[0][0])
+ case 0x03800000:
+ if (SCFG_EXT[0] & (1 << 25))
{
- u8* ptr = NWRAMMap_A[0][(addr >> 16) & NWRAMMask[0][0]];
- return ptr ? *(u8*)&ptr[addr & 0xFFFF] : 0;
- }
- if (addr >= NWRAMStart[0][1] && addr < NWRAMEnd[0][1])
- {
- u8* ptr = NWRAMMap_B[0][(addr >> 15) & NWRAMMask[0][1]];
- return ptr ? *(u8*)&ptr[addr & 0x7FFF] : 0;
- }
- if (addr >= NWRAMStart[0][2] && addr < NWRAMEnd[0][2])
- {
- u8* ptr = NWRAMMap_C[0][(addr >> 15) & NWRAMMask[0][2]];
- return ptr ? *(u8*)&ptr[addr & 0x7FFF] : 0;
+ if (addr >= NWRAMStart[0][0] && addr < NWRAMEnd[0][0])
+ {
+ u8* ptr = NWRAMMap_A[0][(addr >> 16) & NWRAMMask[0][0]];
+ return ptr ? *(u8*)&ptr[addr & 0xFFFF] : 0;
+ }
+ if (addr >= NWRAMStart[0][1] && addr < NWRAMEnd[0][1])
+ {
+ u8* ptr = NWRAMMap_B[0][(addr >> 15) & NWRAMMask[0][1]];
+ return ptr ? *(u8*)&ptr[addr & 0x7FFF] : 0;
+ }
+ if (addr >= NWRAMStart[0][2] && addr < NWRAMEnd[0][2])
+ {
+ u8* ptr = NWRAMMap_C[0][(addr >> 15) & NWRAMMask[0][2]];
+ return ptr ? *(u8*)&ptr[addr & 0x7FFF] : 0;
+ }
}
return NDS::ARM9Read8(addr);
@@ -844,20 +943,24 @@ u16 ARM9Read16(u32 addr)
switch (addr & 0xFF000000)
{
case 0x03000000:
- if (addr >= NWRAMStart[0][0] && addr < NWRAMEnd[0][0])
- {
- u8* ptr = NWRAMMap_A[0][(addr >> 16) & NWRAMMask[0][0]];
- return ptr ? *(u16*)&ptr[addr & 0xFFFF] : 0;
- }
- if (addr >= NWRAMStart[0][1] && addr < NWRAMEnd[0][1])
- {
- u8* ptr = NWRAMMap_B[0][(addr >> 15) & NWRAMMask[0][1]];
- return ptr ? *(u16*)&ptr[addr & 0x7FFF] : 0;
- }
- if (addr >= NWRAMStart[0][2] && addr < NWRAMEnd[0][2])
+ case 0x03800000:
+ if (SCFG_EXT[0] & (1 << 25))
{
- u8* ptr = NWRAMMap_C[0][(addr >> 15) & NWRAMMask[0][2]];
- return ptr ? *(u16*)&ptr[addr & 0x7FFF] : 0;
+ if (addr >= NWRAMStart[0][0] && addr < NWRAMEnd[0][0])
+ {
+ u8* ptr = NWRAMMap_A[0][(addr >> 16) & NWRAMMask[0][0]];
+ return ptr ? *(u16*)&ptr[addr & 0xFFFF] : 0;
+ }
+ if (addr >= NWRAMStart[0][1] && addr < NWRAMEnd[0][1])
+ {
+ u8* ptr = NWRAMMap_B[0][(addr >> 15) & NWRAMMask[0][1]];
+ return ptr ? *(u16*)&ptr[addr & 0x7FFF] : 0;
+ }
+ if (addr >= NWRAMStart[0][2] && addr < NWRAMEnd[0][2])
+ {
+ u8* ptr = NWRAMMap_C[0][(addr >> 15) & NWRAMMask[0][2]];
+ return ptr ? *(u16*)&ptr[addr & 0x7FFF] : 0;
+ }
}
return NDS::ARM9Read16(addr);
@@ -879,7 +982,6 @@ u32 ARM9Read32(u32 addr)
{
if ((addr >= 0xFFFF8000) && (SCFG_BIOS & (1<<0)))
return 0xFFFFFFFF;
-
return *(u32*)&ARM9iBIOS[addr & 0xFFFF];
}
@@ -892,20 +994,24 @@ u32 ARM9Read32(u32 addr)
break;
case 0x03000000:
- if (addr >= NWRAMStart[0][0] && addr < NWRAMEnd[0][0])
+ case 0x03800000:
+ if (SCFG_EXT[0] & (1 << 25))
{
- u8* ptr = NWRAMMap_A[0][(addr >> 16) & NWRAMMask[0][0]];
- return ptr ? *(u32*)&ptr[addr & 0xFFFF] : 0;
- }
- if (addr >= NWRAMStart[0][1] && addr < NWRAMEnd[0][1])
- {
- u8* ptr = NWRAMMap_B[0][(addr >> 15) & NWRAMMask[0][1]];
- return ptr ? *(u32*)&ptr[addr & 0x7FFF] : 0;
- }
- if (addr >= NWRAMStart[0][2] && addr < NWRAMEnd[0][2])
- {
- u8* ptr = NWRAMMap_C[0][(addr >> 15) & NWRAMMask[0][2]];
- return ptr ? *(u32*)&ptr[addr & 0x7FFF] : 0;
+ if (addr >= NWRAMStart[0][0] && addr < NWRAMEnd[0][0])
+ {
+ u8* ptr = NWRAMMap_A[0][(addr >> 16) & NWRAMMask[0][0]];
+ return ptr ? *(u32*)&ptr[addr & 0xFFFF] : 0;
+ }
+ if (addr >= NWRAMStart[0][1] && addr < NWRAMEnd[0][1])
+ {
+ u8* ptr = NWRAMMap_B[0][(addr >> 15) & NWRAMMask[0][1]];
+ return ptr ? *(u32*)&ptr[addr & 0x7FFF] : 0;
+ }
+ if (addr >= NWRAMStart[0][2] && addr < NWRAMEnd[0][2])
+ {
+ u8* ptr = NWRAMMap_C[0][(addr >> 15) & NWRAMMask[0][2]];
+ return ptr ? *(u32*)&ptr[addr & 0x7FFF] : 0;
+ }
}
return NDS::ARM9Read32(addr);
@@ -926,41 +1032,69 @@ void ARM9Write8(u32 addr, u8 val)
switch (addr & 0xFF000000)
{
case 0x03000000:
- if (addr >= NWRAMStart[0][0] && addr < NWRAMEnd[0][0])
+ case 0x03800000:
+ if (SCFG_EXT[0] & (1 << 25))
{
- u8* ptr = NWRAMMap_A[0][(addr >> 16) & NWRAMMask[0][0]];
- if (ptr)
+ if (addr >= NWRAMStart[0][0] && addr < NWRAMEnd[0][0])
{
- *(u8*)&ptr[addr & 0xFFFF] = val;
+ // Write to a bank is special, as it writes to all
+ // parts that are mapped and not just the highest priority
+ // See http://melonds.kuribo64.net/board/thread.php?pid=3974#3974
+ // so we need to iterate through all parts and write to all mapped here
+ unsigned int destPartSetting = ((addr >> 13) & (NWRAMMask[0][0] << 3)) | 0x80;
+ for (int page = 0; page < 4; page++)
+ {
+ unsigned int bankInfo = (MBK[0][0 + (page / 4)] >> ((page % 4) * 8)) & 0xff;
+ if (bankInfo != destPartSetting)
+ continue;
+ u8* ptr = &NWRAM_A[page * 0x8000];
+ *(u8*)&ptr[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED
- ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr);
+ ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr);
#endif
+ }
+ return;
}
- return;
- }
- if (addr >= NWRAMStart[0][1] && addr < NWRAMEnd[0][1])
- {
- u8* ptr = NWRAMMap_B[0][(addr >> 15) & NWRAMMask[0][1]];
- if (ptr)
+ if (addr >= NWRAMStart[0][1] && addr < NWRAMEnd[0][1])
{
- *(u8*)&ptr[addr & 0x7FFF] = val;
+ // Write to a bank is special, as it writes to all
+ // parts that are mapped and not just the highest priority
+ // See http://melonds.kuribo64.net/board/thread.php?pid=3974#3974
+ // so we need to iterate through all parts and write to all mapped here
+ unsigned int destPartSetting = ((addr >> 13) & (NWRAMMask[0][1] << 2)) | 0x80;
+ for (int page = 0; page < 8; page++)
+ {
+ unsigned int bankInfo = (MBK[0][1 + (page / 4)] >> ((page % 4) * 8)) & 0xff;
+ if (bankInfo != destPartSetting)
+ continue;
+ u8* ptr = &NWRAM_B[page * 0x8000];
+ *(u8*)&ptr[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED
- ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr);
+ ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr);
#endif
+ }
+ return;
}
- return;
- }
- if (addr >= NWRAMStart[0][2] && addr < NWRAMEnd[0][2])
- {
- u8* ptr = NWRAMMap_C[0][(addr >> 15) & NWRAMMask[0][2]];
- if (ptr)
+ if (addr >= NWRAMStart[0][2] && addr < NWRAMEnd[0][2])
{
- *(u8*)&ptr[addr & 0x7FFF] = val;
+ // Write to a bank is special, as it writes to all
+ // parts that are mapped and not just the highest priority
+ // See http://melonds.kuribo64.net/board/thread.php?pid=3974#3974
+ // so we need to iterate through all parts and write to all mapped here
+ unsigned int destPartSetting = ((addr >> 13) & (NWRAMMask[0][2] << 2)) | 0x80;
+ for (int page = 0; page < 8; page++)
+ {
+ unsigned int bankInfo = (MBK[0][3 + (page / 4)] >> ((page % 4) * 8)) & 0xff;
+ if (bankInfo != destPartSetting)
+ continue;
+ u8* ptr = &NWRAM_C[page * 0x8000];
+ *(u8*)&ptr[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED
- ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr);
+ ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr);
#endif
+ }
+ return;
}
- return;
}
return NDS::ARM9Write8(addr, val);
@@ -996,41 +1130,69 @@ void ARM9Write16(u32 addr, u16 val)
switch (addr & 0xFF000000)
{
case 0x03000000:
- if (addr >= NWRAMStart[0][0] && addr < NWRAMEnd[0][0])
+ case 0x03800000:
+ if (SCFG_EXT[0] & (1 << 25))
{
- u8* ptr = NWRAMMap_A[0][(addr >> 16) & NWRAMMask[0][0]];
- if (ptr)
+ if (addr >= NWRAMStart[0][0] && addr < NWRAMEnd[0][0])
{
- *(u16*)&ptr[addr & 0xFFFF] = val;
+ // Write to a bank is special, as it writes to all
+ // parts that are mapped and not just the highest priority
+ // See http://melonds.kuribo64.net/board/thread.php?pid=3974#3974
+ // so we need to iterate through all parts and write to all mapped here
+ unsigned int destPartSetting = ((addr >> 13) & (NWRAMMask[0][0] << 3)) | 0x80;
+ for (int page = 0; page < 4; page++)
+ {
+ unsigned int bankInfo = (MBK[0][0 + (page / 4)] >> ((page % 4) * 8)) & 0xff;
+ if (bankInfo != destPartSetting)
+ continue;
+ u8* ptr = &NWRAM_A[page * 0x8000];
+ *(u16*)&ptr[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED
- ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr);
+ ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr);
#endif
+ }
+ return;
}
- return;
- }
- if (addr >= NWRAMStart[0][1] && addr < NWRAMEnd[0][1])
- {
- u8* ptr = NWRAMMap_B[0][(addr >> 15) & NWRAMMask[0][1]];
- if (ptr)
+ if (addr >= NWRAMStart[0][1] && addr < NWRAMEnd[0][1])
{
- *(u16*)&ptr[addr & 0x7FFF] = val;
+ // Write to a bank is special, as it writes to all
+ // parts that are mapped and not just the highest priority
+ // See http://melonds.kuribo64.net/board/thread.php?pid=3974#3974
+ // so we need to iterate through all parts and write to all mapped here
+ unsigned int destPartSetting = ((addr >> 13) & (NWRAMMask[0][1] << 2)) | 0x80;
+ for (int page = 0; page < 8; page++)
+ {
+ unsigned int bankInfo = (MBK[0][1 + (page / 4)] >> ((page % 4) * 8)) & 0xff;
+ if (bankInfo != destPartSetting)
+ continue;
+ u8* ptr = &NWRAM_B[page * 0x8000];
+ *(u16*)&ptr[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED
- ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr);
+ ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr);
#endif
+ }
+ return;
}
- return;
- }
- if (addr >= NWRAMStart[0][2] && addr < NWRAMEnd[0][2])
- {
- u8* ptr = NWRAMMap_C[0][(addr >> 15) & NWRAMMask[0][2]];
- if (ptr)
+ if (addr >= NWRAMStart[0][2] && addr < NWRAMEnd[0][2])
{
- *(u16*)&ptr[addr & 0x7FFF] = val;
+ // Write to a bank is special, as it writes to all
+ // parts that are mapped and not just the highest priority
+ // See http://melonds.kuribo64.net/board/thread.php?pid=3974#3974
+ // so we need to iterate through all parts and write to all mapped here
+ unsigned int destPartSetting = ((addr >> 13) & (NWRAMMask[0][2] << 2)) | 0x80;
+ for (int page = 0; page < 8; page++)
+ {
+ unsigned int bankInfo = (MBK[0][3 + (page / 4)] >> ((page % 4) * 8)) & 0xff;
+ if (bankInfo != destPartSetting)
+ continue;
+ u8* ptr = &NWRAM_C[page * 0x8000];
+ *(u16*)&ptr[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED
- ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr);
+ ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr);
#endif
+ }
+ return;
}
- return;
}
return NDS::ARM9Write16(addr, val);
@@ -1052,41 +1214,69 @@ void ARM9Write32(u32 addr, u32 val)
switch (addr & 0xFF000000)
{
case 0x03000000:
- if (addr >= NWRAMStart[0][0] && addr < NWRAMEnd[0][0])
+ case 0x03800000:
+ if (SCFG_EXT[0] & (1 << 25))
{
- u8* ptr = NWRAMMap_A[0][(addr >> 16) & NWRAMMask[0][0]];
- if (ptr)
+ if (addr >= NWRAMStart[0][0] && addr < NWRAMEnd[0][0])
{
- *(u32*)&ptr[addr & 0xFFFF] = val;
+ // Write to a bank is special, as it writes to all
+ // parts that are mapped and not just the highest priority
+ // See http://melonds.kuribo64.net/board/thread.php?pid=3974#3974
+ // so we need to iterate through all parts and write to all mapped here
+ unsigned int destPartSetting = ((addr >> 13) & (NWRAMMask[0][0] << 3)) | 0x80;
+ for (int page = 0; page < 4; page++)
+ {
+ unsigned int bankInfo = (MBK[0][0 + (page / 4)] >> ((page % 4) * 8)) & 0xff;
+ if (bankInfo != destPartSetting)
+ continue;
+ u8* ptr = &NWRAM_A[page * 0x8000];
+ *(u32*)&ptr[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED
- ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr);
+ ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr);
#endif
+ }
+ return;
}
- return;
- }
- if (addr >= NWRAMStart[0][1] && addr < NWRAMEnd[0][1])
- {
- u8* ptr = NWRAMMap_B[0][(addr >> 15) & NWRAMMask[0][1]];
- if (ptr)
+ if (addr >= NWRAMStart[0][1] && addr < NWRAMEnd[0][1])
{
- *(u32*)&ptr[addr & 0x7FFF] = val;
+ // Write to a bank is special, as it writes to all
+ // parts that are mapped and not just the highest priority
+ // See http://melonds.kuribo64.net/board/thread.php?pid=3974#3974
+ // so we need to iterate through all parts and write to all mapped here
+ unsigned int destPartSetting = ((addr >> 13) & (NWRAMMask[0][1] << 2)) | 0x80;
+ for (int page = 0; page < 8; page++)
+ {
+ unsigned int bankInfo = (MBK[0][1 + (page / 4)] >> ((page % 4) * 8)) & 0xff;
+ if (bankInfo != destPartSetting)
+ continue;
+ u8* ptr = &NWRAM_B[page * 0x8000];
+ *(u32*)&ptr[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED
- ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr);
+ ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr);
#endif
+ }
+ return;
}
- return;
- }
- if (addr >= NWRAMStart[0][2] && addr < NWRAMEnd[0][2])
- {
- u8* ptr = NWRAMMap_C[0][(addr >> 15) & NWRAMMask[0][2]];
- if (ptr)
+ if (addr >= NWRAMStart[0][2] && addr < NWRAMEnd[0][2])
{
- *(u32*)&ptr[addr & 0x7FFF] = val;
+ // Write to a bank is special, as it writes to all
+ // parts that are mapped and not just the highest priority
+ // See http://melonds.kuribo64.net/board/thread.php?pid=3974#3974
+ // so we need to iterate through all parts and write to all mapped here
+ unsigned int destPartSetting = ((addr >> 13) & (NWRAMMask[0][2] << 2)) | 0x80;
+ for (int page = 0; page < 8; page++)
+ {
+ unsigned int bankInfo = (MBK[0][3 + (page / 4)] >> ((page % 4) * 8)) & 0xff;
+ if (bankInfo != destPartSetting)
+ continue;
+ u8* ptr = &NWRAM_C[page * 0x8000];
+ *(u32*)&ptr[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED
- ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr);
+ ARMJIT::CheckAndInvalidate<0, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr);
#endif
+ }
+ return;
}
- return;
}
return NDS::ARM9Write32(addr, val);
@@ -1151,26 +1341,30 @@ u8 ARM7Read8(u32 addr)
if (addr < NDS::ARM7BIOSProt && NDS::ARM7->R[15] >= NDS::ARM7BIOSProt)
return 0xFF;
- return *(u8*)&ARM7iBIOS[addr];
+ return *(u8*)&ARM7iBIOS[addr & 0xFFFF];
}
switch (addr & 0xFF800000)
{
case 0x03000000:
- if (addr >= NWRAMStart[1][0] && addr < NWRAMEnd[1][0])
- {
- u8* ptr = NWRAMMap_A[1][(addr >> 16) & NWRAMMask[1][0]];
- return ptr ? *(u8*)&ptr[addr & 0xFFFF] : 0;
- }
- if (addr >= NWRAMStart[1][1] && addr < NWRAMEnd[1][1])
- {
- u8* ptr = NWRAMMap_B[1][(addr >> 15) & NWRAMMask[1][1]];
- return ptr ? *(u8*)&ptr[addr & 0x7FFF] : 0;
- }
- if (addr >= NWRAMStart[1][2] && addr < NWRAMEnd[1][2])
+ case 0x03800000:
+ if (SCFG_EXT[1] & (1 << 25))
{
- u8* ptr = NWRAMMap_C[1][(addr >> 15) & NWRAMMask[1][2]];
- return ptr ? *(u8*)&ptr[addr & 0x7FFF] : 0;
+ if (addr >= NWRAMStart[1][0] && addr < NWRAMEnd[1][0])
+ {
+ u8* ptr = NWRAMMap_A[1][(addr >> 16) & NWRAMMask[1][0]];
+ return ptr ? *(u8*)&ptr[addr & 0xFFFF] : 0;
+ }
+ if (addr >= NWRAMStart[1][1] && addr < NWRAMEnd[1][1])
+ {
+ u8* ptr = NWRAMMap_B[1][(addr >> 15) & NWRAMMask[1][1]];
+ return ptr ? *(u8*)&ptr[addr & 0x7FFF] : 0;
+ }
+ if (addr >= NWRAMStart[1][2] && addr < NWRAMEnd[1][2])
+ {
+ u8* ptr = NWRAMMap_C[1][(addr >> 15) & NWRAMMask[1][2]];
+ return ptr ? *(u8*)&ptr[addr & 0x7FFF] : 0;
+ }
}
return NDS::ARM7Read8(addr);
@@ -1200,26 +1394,30 @@ u16 ARM7Read16(u32 addr)
if (addr < NDS::ARM7BIOSProt && NDS::ARM7->R[15] >= NDS::ARM7BIOSProt)
return 0xFFFF;
- return *(u16*)&ARM7iBIOS[addr];
+ return *(u16*)&ARM7iBIOS[addr & 0xFFFF];
}
switch (addr & 0xFF800000)
{
case 0x03000000:
- if (addr >= NWRAMStart[1][0] && addr < NWRAMEnd[1][0])
- {
- u8* ptr = NWRAMMap_A[1][(addr >> 16) & NWRAMMask[1][0]];
- return ptr ? *(u16*)&ptr[addr & 0xFFFF] : 0;
- }
- if (addr >= NWRAMStart[1][1] && addr < NWRAMEnd[1][1])
- {
- u8* ptr = NWRAMMap_B[1][(addr >> 15) & NWRAMMask[1][1]];
- return ptr ? *(u16*)&ptr[addr & 0x7FFF] : 0;
- }
- if (addr >= NWRAMStart[1][2] && addr < NWRAMEnd[1][2])
+ case 0x03800000:
+ if (SCFG_EXT[1] & (1 << 25))
{
- u8* ptr = NWRAMMap_C[1][(addr >> 15) & NWRAMMask[1][2]];
- return ptr ? *(u16*)&ptr[addr & 0x7FFF] : 0;
+ if (addr >= NWRAMStart[1][0] && addr < NWRAMEnd[1][0])
+ {
+ u8* ptr = NWRAMMap_A[1][(addr >> 16) & NWRAMMask[1][0]];
+ return ptr ? *(u16*)&ptr[addr & 0xFFFF] : 0;
+ }
+ if (addr >= NWRAMStart[1][1] && addr < NWRAMEnd[1][1])
+ {
+ u8* ptr = NWRAMMap_B[1][(addr >> 15) & NWRAMMask[1][1]];
+ return ptr ? *(u16*)&ptr[addr & 0x7FFF] : 0;
+ }
+ if (addr >= NWRAMStart[1][2] && addr < NWRAMEnd[1][2])
+ {
+ u8* ptr = NWRAMMap_C[1][(addr >> 15) & NWRAMMask[1][2]];
+ return ptr ? *(u16*)&ptr[addr & 0x7FFF] : 0;
+ }
}
return NDS::ARM7Read16(addr);
@@ -1249,26 +1447,30 @@ u32 ARM7Read32(u32 addr)
if (addr < NDS::ARM7BIOSProt && NDS::ARM7->R[15] >= NDS::ARM7BIOSProt)
return 0xFFFFFFFF;
- return *(u32*)&ARM7iBIOS[addr];
+ return *(u32*)&ARM7iBIOS[addr & 0xFFFF];
}
switch (addr & 0xFF800000)
{
case 0x03000000:
- if (addr >= NWRAMStart[1][0] && addr < NWRAMEnd[1][0])
- {
- u8* ptr = NWRAMMap_A[1][(addr >> 16) & NWRAMMask[1][0]];
- return ptr ? *(u32*)&ptr[addr & 0xFFFF] : 0;
- }
- if (addr >= NWRAMStart[1][1] && addr < NWRAMEnd[1][1])
+ case 0x03800000:
+ if (SCFG_EXT[1] & (1 << 25))
{
- u8* ptr = NWRAMMap_B[1][(addr >> 15) & NWRAMMask[1][1]];
- return ptr ? *(u32*)&ptr[addr & 0x7FFF] : 0;
- }
- if (addr >= NWRAMStart[1][2] && addr < NWRAMEnd[1][2])
- {
- u8* ptr = NWRAMMap_C[1][(addr >> 15) & NWRAMMask[1][2]];
- return ptr ? *(u32*)&ptr[addr & 0x7FFF] : 0;
+ if (addr >= NWRAMStart[1][0] && addr < NWRAMEnd[1][0])
+ {
+ u8* ptr = NWRAMMap_A[1][(addr >> 16) & NWRAMMask[1][0]];
+ return ptr ? *(u32*)&ptr[addr & 0xFFFF] : 0;
+ }
+ if (addr >= NWRAMStart[1][1] && addr < NWRAMEnd[1][1])
+ {
+ u8* ptr = NWRAMMap_B[1][(addr >> 15) & NWRAMMask[1][1]];
+ return ptr ? *(u32*)&ptr[addr & 0x7FFF] : 0;
+ }
+ if (addr >= NWRAMStart[1][2] && addr < NWRAMEnd[1][2])
+ {
+ u8* ptr = NWRAMMap_C[1][(addr >> 15) & NWRAMMask[1][2]];
+ return ptr ? *(u32*)&ptr[addr & 0x7FFF] : 0;
+ }
}
return NDS::ARM7Read32(addr);
@@ -1292,41 +1494,69 @@ void ARM7Write8(u32 addr, u8 val)
switch (addr & 0xFF800000)
{
case 0x03000000:
- if (addr >= NWRAMStart[1][0] && addr < NWRAMEnd[1][0])
+ case 0x03800000:
+ if (SCFG_EXT[1] & (1 << 25))
{
- u8* ptr = NWRAMMap_A[1][(addr >> 16) & NWRAMMask[1][0]];
- if (ptr)
+ if (addr >= NWRAMStart[1][0] && addr < NWRAMEnd[1][0])
{
- *(u8*)&ptr[addr & 0xFFFF] = val;
+ // Write to a bank is special, as it writes to all
+ // parts that are mapped and not just the highest priority
+ // See http://melonds.kuribo64.net/board/thread.php?pid=3974#3974
+ // so we need to iterate through all parts and write to all mapped here
+ unsigned int destPartSetting = ((addr >> 13) & (NWRAMMask[1][0] << 3)) | 0x81;
+ for (int page = 0; page < 4; page++)
+ {
+ unsigned int bankInfo = (MBK[1][0 + (page / 4)] >> ((page % 4) * 8)) & 0xff;
+ if (bankInfo != destPartSetting)
+ continue;
+ u8* ptr = &NWRAM_A[page * 0x8000];
+ *(u8*)&ptr[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED
- ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr);
+ ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr);
#endif
+ }
+ return;
}
- return;
- }
- if (addr >= NWRAMStart[1][1] && addr < NWRAMEnd[1][1])
- {
- u8* ptr = NWRAMMap_B[1][(addr >> 15) & NWRAMMask[1][1]];
- if (ptr)
+ if (addr >= NWRAMStart[1][1] && addr < NWRAMEnd[1][1])
{
- *(u8*)&ptr[addr & 0x7FFF] = val;
+ // Write to a bank is special, as it writes to all
+ // parts that are mapped and not just the highest priority
+ // See http://melonds.kuribo64.net/board/thread.php?pid=3974#3974
+ // so we need to iterate through all parts and write to all mapped here
+ unsigned int destPartSetting = ((addr >> 13) & (NWRAMMask[1][1] << 2)) | 0x81;
+ for (int page = 0; page < 8; page++)
+ {
+ unsigned int bankInfo = (MBK[1][1 + (page / 4)] >> ((page % 4) * 8)) & 0xff;
+ if (bankInfo != destPartSetting)
+ continue;
+ u8* ptr = &NWRAM_B[page * 0x8000];
+ *(u8*)&ptr[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED
- ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr);
+ ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr);
#endif
+ }
+ return;
}
- return;
- }
- if (addr >= NWRAMStart[1][2] && addr < NWRAMEnd[1][2])
- {
- u8* ptr = NWRAMMap_C[1][(addr >> 15) & NWRAMMask[1][2]];
- if (ptr)
+ if (addr >= NWRAMStart[1][2] && addr < NWRAMEnd[1][2])
{
- *(u8*)&ptr[addr & 0x7FFF] = val;
+ // Write to a bank is special, as it writes to all
+ // parts that are mapped and not just the highest priority
+ // See http://melonds.kuribo64.net/board/thread.php?pid=3974#3974
+ // so we need to iterate through all parts and write to all mapped here
+ unsigned int destPartSetting = ((addr >> 13) & (NWRAMMask[1][2] << 2)) | 0x81;
+ for (int page = 0; page < 8; page++)
+ {
+ unsigned int bankInfo = (MBK[1][3 + (page / 4)] >> ((page % 4) * 8)) & 0xff;
+ if (bankInfo != destPartSetting)
+ continue;
+ u8* ptr = &NWRAM_C[page * 0x8000];
+ *(u8*)&ptr[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED
- ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr);
+ ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr);
#endif
+ }
+ return;
}
- return;
}
return NDS::ARM7Write8(addr, val);
@@ -1351,41 +1581,69 @@ void ARM7Write16(u32 addr, u16 val)
switch (addr & 0xFF800000)
{
case 0x03000000:
- if (addr >= NWRAMStart[1][0] && addr < NWRAMEnd[1][0])
+ case 0x03800000:
+ if (SCFG_EXT[1] & (1 << 25))
{
- u8* ptr = NWRAMMap_A[1][(addr >> 16) & NWRAMMask[1][0]];
- if (ptr)
+ if (addr >= NWRAMStart[1][0] && addr < NWRAMEnd[1][0])
{
- *(u16*)&ptr[addr & 0xFFFF] = val;
+ // Write to a bank is special, as it writes to all
+ // parts that are mapped and not just the highest priority
+ // See http://melonds.kuribo64.net/board/thread.php?pid=3974#3974
+ // so we need to iterate through all parts and write to all mapped here
+ unsigned int destPartSetting = ((addr >> 13) & (NWRAMMask[1][0] << 3)) | 0x81;
+ for (int page = 0; page < 4; page++)
+ {
+ unsigned int bankInfo = (MBK[1][0 + (page / 4)] >> ((page % 4) * 8)) & 0xff;
+ if (bankInfo != destPartSetting)
+ continue;
+ u8* ptr = &NWRAM_A[page * 0x8000];
+ *(u16*)&ptr[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED
- ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr);
+ ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr);
#endif
+ }
+ return;
}
- return;
- }
- if (addr >= NWRAMStart[1][1] && addr < NWRAMEnd[1][1])
- {
- u8* ptr = NWRAMMap_B[1][(addr >> 15) & NWRAMMask[1][1]];
- if (ptr)
+ if (addr >= NWRAMStart[1][1] && addr < NWRAMEnd[1][1])
{
- *(u16*)&ptr[addr & 0x7FFF] = val;
+ // Write to a bank is special, as it writes to all
+ // parts that are mapped and not just the highest priority
+ // See http://melonds.kuribo64.net/board/thread.php?pid=3974#3974
+ // so we need to iterate through all parts and write to all mapped here
+ unsigned int destPartSetting = ((addr >> 13) & (NWRAMMask[1][1] << 2)) | 0x81;
+ for (int page = 0; page < 8; page++)
+ {
+ unsigned int bankInfo = (MBK[1][1 + (page / 4)] >> ((page % 4) * 8)) & 0xff;
+ if (bankInfo != destPartSetting)
+ continue;
+ u8* ptr = &NWRAM_B[page * 0x8000];
+ *(u16*)&ptr[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED
- ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr);
+ ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr);
#endif
+ }
+ return;
}
- return;
- }
- if (addr >= NWRAMStart[1][2] && addr < NWRAMEnd[1][2])
- {
- u8* ptr = NWRAMMap_C[1][(addr >> 15) & NWRAMMask[1][2]];
- if (ptr)
+ if (addr >= NWRAMStart[1][2] && addr < NWRAMEnd[1][2])
{
- *(u16*)&ptr[addr & 0x7FFF] = val;
+ // Write to a bank is special, as it writes to all
+ // parts that are mapped and not just the highest priority
+ // See http://melonds.kuribo64.net/board/thread.php?pid=3974#3974
+ // so we need to iterate through all parts and write to all mapped here
+ unsigned int destPartSetting = ((addr >> 13) & (NWRAMMask[1][2] << 2)) | 0x81;
+ for (int page = 0; page < 8; page++)
+ {
+ unsigned int bankInfo = (MBK[1][3 + (page / 4)] >> ((page % 4) * 8)) & 0xff;
+ if (bankInfo != destPartSetting)
+ continue;
+ u8* ptr = &NWRAM_C[page * 0x8000];
+ *(u16*)&ptr[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED
- ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr);
+ ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr);
#endif
+ }
+ return;
}
- return;
}
return NDS::ARM7Write16(addr, val);
@@ -1410,41 +1668,69 @@ void ARM7Write32(u32 addr, u32 val)
switch (addr & 0xFF800000)
{
case 0x03000000:
- if (addr >= NWRAMStart[1][0] && addr < NWRAMEnd[1][0])
+ case 0x03800000:
+ if (SCFG_EXT[1] & (1 << 25))
{
- u8* ptr = NWRAMMap_A[1][(addr >> 16) & NWRAMMask[1][0]];
- if (ptr)
+ if (addr >= NWRAMStart[1][0] && addr < NWRAMEnd[1][0])
{
- *(u32*)&ptr[addr & 0xFFFF] = val;
+ // Write to a bank is special, as it writes to all
+ // parts that are mapped and not just the highest priority
+ // See http://melonds.kuribo64.net/board/thread.php?pid=3974#3974
+ // so we need to iterate through all parts and write to all mapped here
+ unsigned int destPartSetting = ((addr >> 13) & (NWRAMMask[1][0] << 3)) | 0x81;
+ for (int page = 0; page < 4; page++)
+ {
+ unsigned int bankInfo = (MBK[1][0 + (page / 4)] >> ((page % 4) * 8)) & 0xff;
+ if (bankInfo != destPartSetting)
+ continue;
+ u8* ptr = &NWRAM_A[page * 0x8000];
+ *(u32*)&ptr[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED
- ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr);
+ ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_A>(addr);
#endif
+ }
+ return;
}
- return;
- }
- if (addr >= NWRAMStart[1][1] && addr < NWRAMEnd[1][1])
- {
- u8* ptr = NWRAMMap_B[1][(addr >> 15) & NWRAMMask[1][1]];
- if (ptr)
+ if (addr >= NWRAMStart[1][1] && addr < NWRAMEnd[1][1])
{
- *(u32*)&ptr[addr & 0x7FFF] = val;
+ // Write to a bank is special, as it writes to all
+ // parts that are mapped and not just the highest priority
+ // See http://melonds.kuribo64.net/board/thread.php?pid=3974#3974
+ // so we need to iterate through all parts and write to all mapped here
+ unsigned int destPartSetting = ((addr >> 13) & (NWRAMMask[1][1] << 2)) | 0x81;
+ for (int page = 0; page < 8; page++)
+ {
+ unsigned int bankInfo = (MBK[1][1 + (page / 4)] >> ((page % 4) * 8)) & 0xff;
+ if (bankInfo != destPartSetting)
+ continue;
+ u8* ptr = &NWRAM_B[page * 0x8000];
+ *(u32*)&ptr[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED
- ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr);
+ ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_B>(addr);
#endif
+ }
+ return;
}
- return;
- }
- if (addr >= NWRAMStart[1][2] && addr < NWRAMEnd[1][2])
- {
- u8* ptr = NWRAMMap_C[1][(addr >> 15) & NWRAMMask[1][2]];
- if (ptr)
+ if (addr >= NWRAMStart[1][2] && addr < NWRAMEnd[1][2])
{
- *(u32*)&ptr[addr & 0x7FFF] = val;
+ // Write to a bank is special, as it writes to all
+ // parts that are mapped and not just the highest priority
+ // See http://melonds.kuribo64.net/board/thread.php?pid=3974#3974
+ // so we need to iterate through all parts and write to all mapped here
+ unsigned int destPartSetting = ((addr >> 13) & (NWRAMMask[1][2] << 2)) | 0x81;
+ for (int page = 0; page < 8; page++)
+ {
+ unsigned int bankInfo = (MBK[1][3 + (page / 4)] >> ((page % 4) * 8)) & 0xff;
+ if (bankInfo != destPartSetting)
+ continue;
+ u8* ptr = &NWRAM_C[page * 0x8000];
+ *(u32*)&ptr[addr & 0x7FFF] = val;
#ifdef JIT_ENABLED
- ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr);
+ ARMJIT::CheckAndInvalidate<1, ARMJIT_Memory::memregion_NewSharedWRAM_C>(addr);
#endif
+ }
+ return;
}
- return;
}
return NDS::ARM7Write32(addr, val);
@@ -1643,30 +1929,44 @@ void ARM9IOWrite8(u32 addr, u8 val)
return;
case 0x04004006:
+ if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
SCFG_RST = (SCFG_RST & 0xFF00) | val;
DSi_DSP::SetRstLine(val & 1);
return;
- case 0x04004040: MapNWRAM_A(0, val); return;
- case 0x04004041: MapNWRAM_A(1, val); return;
- case 0x04004042: MapNWRAM_A(2, val); return;
- case 0x04004043: MapNWRAM_A(3, val); return;
- case 0x04004044: MapNWRAM_B(0, val); return;
- case 0x04004045: MapNWRAM_B(1, val); return;
- case 0x04004046: MapNWRAM_B(2, val); return;
- case 0x04004047: MapNWRAM_B(3, val); return;
- case 0x04004048: MapNWRAM_B(4, val); return;
- case 0x04004049: MapNWRAM_B(5, val); return;
- case 0x0400404A: MapNWRAM_B(6, val); return;
- case 0x0400404B: MapNWRAM_B(7, val); return;
- case 0x0400404C: MapNWRAM_C(0, val); return;
- case 0x0400404D: MapNWRAM_C(1, val); return;
- case 0x0400404E: MapNWRAM_C(2, val); return;
- case 0x0400404F: MapNWRAM_C(3, val); return;
- case 0x04004050: MapNWRAM_C(4, val); return;
- case 0x04004051: MapNWRAM_C(5, val); return;
- case 0x04004052: MapNWRAM_C(6, val); return;
- case 0x04004053: MapNWRAM_C(7, val); return;
+ case 0x04004040:
+ case 0x04004041:
+ case 0x04004042:
+ case 0x04004043:
+ if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
+ MapNWRAM_A(addr & 3, val);
+ return;
+ case 0x04004044:
+ case 0x04004045:
+ case 0x04004046:
+ case 0x04004047:
+ case 0x04004048:
+ case 0x04004049:
+ case 0x0400404A:
+ case 0x0400404B:
+ if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
+ MapNWRAM_B((addr - 0x04) & 7, val);
+ return;
+ case 0x0400404C:
+ case 0x0400404D:
+ case 0x0400404E:
+ case 0x0400404F:
+ case 0x04004050:
+ case 0x04004051:
+ case 0x04004052:
+ case 0x04004053:
+ if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
+ MapNWRAM_C((addr-0x0C) & 7, val);
+ return;
}
if ((addr & 0xFFFFFF00) == 0x04004200)
@@ -1689,53 +1989,43 @@ void ARM9IOWrite16(u32 addr, u16 val)
switch (addr)
{
case 0x04004004:
+ if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
Set_SCFG_Clock9(val);
return;
case 0x04004006:
+ if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
SCFG_RST = val;
DSi_DSP::SetRstLine(val & 1);
return;
case 0x04004040:
- MapNWRAM_A(0, val & 0xFF);
- MapNWRAM_A(1, val >> 8);
- return;
case 0x04004042:
- MapNWRAM_A(2, val & 0xFF);
- MapNWRAM_A(3, val >> 8);
+ if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
+ MapNWRAM_A((addr & 2), val & 0xFF);
+ MapNWRAM_A((addr & 2) + 1, val >> 8);
return;
+
case 0x04004044:
- MapNWRAM_B(0, val & 0xFF);
- MapNWRAM_B(1, val >> 8);
- return;
case 0x04004046:
- MapNWRAM_B(2, val & 0xFF);
- MapNWRAM_B(3, val >> 8);
- return;
case 0x04004048:
- MapNWRAM_B(4, val & 0xFF);
- MapNWRAM_B(5, val >> 8);
- return;
case 0x0400404A:
- MapNWRAM_B(6, val & 0xFF);
- MapNWRAM_B(7, val >> 8);
+ if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
+ MapNWRAM_B(((addr - 0x04) & 6), val & 0xFF);
+ MapNWRAM_B(((addr - 0x04) & 6) + 1, val >> 8);
return;
case 0x0400404C:
- MapNWRAM_C(0, val & 0xFF);
- MapNWRAM_C(1, val >> 8);
- return;
case 0x0400404E:
- MapNWRAM_C(2, val & 0xFF);
- MapNWRAM_C(3, val >> 8);
- return;
case 0x04004050:
- MapNWRAM_C(4, val & 0xFF);
- MapNWRAM_C(5, val >> 8);
- return;
case 0x04004052:
- MapNWRAM_C(6, val & 0xFF);
- MapNWRAM_C(7, val >> 8);
+ if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
+ MapNWRAM_C(((addr - 0x0C) & 6), val & 0xFF);
+ MapNWRAM_C(((addr - 0x0C) & 6) + 1, val >> 8);
return;
}
@@ -1759,6 +2049,8 @@ void ARM9IOWrite32(u32 addr, u32 val)
switch (addr)
{
case 0x04004004:
+ if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
Set_SCFG_Clock9(val & 0xFFFF);
SCFG_RST = val >> 16;
DSi_DSP::SetRstLine((val >> 16) & 1);
@@ -1766,6 +2058,8 @@ void ARM9IOWrite32(u32 addr, u32 val)
case 0x04004008:
{
+ if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
u32 oldram = (SCFG_EXT[0] >> 14) & 0x3;
u32 newram = (val >> 14) & 0x3;
@@ -1799,38 +2093,60 @@ void ARM9IOWrite32(u32 addr, u32 val)
return;
case 0x04004040:
+ if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
MapNWRAM_A(0, val & 0xFF);
MapNWRAM_A(1, (val >> 8) & 0xFF);
MapNWRAM_A(2, (val >> 16) & 0xFF);
MapNWRAM_A(3, val >> 24);
return;
case 0x04004044:
+ if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
MapNWRAM_B(0, val & 0xFF);
MapNWRAM_B(1, (val >> 8) & 0xFF);
MapNWRAM_B(2, (val >> 16) & 0xFF);
MapNWRAM_B(3, val >> 24);
return;
case 0x04004048:
+ if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
MapNWRAM_B(4, val & 0xFF);
MapNWRAM_B(5, (val >> 8) & 0xFF);
MapNWRAM_B(6, (val >> 16) & 0xFF);
MapNWRAM_B(7, val >> 24);
return;
case 0x0400404C:
+ if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
MapNWRAM_C(0, val & 0xFF);
MapNWRAM_C(1, (val >> 8) & 0xFF);
MapNWRAM_C(2, (val >> 16) & 0xFF);
MapNWRAM_C(3, val >> 24);
return;
case 0x04004050:
+ if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
MapNWRAM_C(4, val & 0xFF);
MapNWRAM_C(5, (val >> 8) & 0xFF);
MapNWRAM_C(6, (val >> 16) & 0xFF);
MapNWRAM_C(7, val >> 24);
return;
- case 0x04004054: MapNWRAMRange(0, 0, val); return;
- case 0x04004058: MapNWRAMRange(0, 1, val); return;
- case 0x0400405C: MapNWRAMRange(0, 2, val); return;
+ case 0x04004054:
+ if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
+ MapNWRAMRange(0, 0, val);
+ return;
+ case 0x04004058:
+ if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
+ MapNWRAMRange(0, 1, val);
+ return;
+ case 0x0400405C:
+ if (!(SCFG_EXT[0] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
+ MapNWRAMRange(0, 2, val);
+ return;
case 0x04004100: NDMACnt[0] = val & 0x800F0000; return;
case 0x04004104: NDMAs[0]->SrcAddr = val & 0xFFFFFFFC; return;
@@ -1877,7 +2193,8 @@ u8 ARM7IORead8(u32 addr)
{
switch (addr)
{
- case 0x04004000: return SCFG_BIOS & 0xFF;
+ case 0x04004000:
+ return SCFG_BIOS & 0xFF;
case 0x04004001: return SCFG_BIOS >> 8;
CASE_READ8_32BIT(0x04004040, MBK[1][0])
@@ -2026,11 +2343,29 @@ void ARM7IOWrite8(u32 addr, u8 val)
switch (addr)
{
case 0x04004000:
+ if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
SCFG_BIOS |= (val & 0x03);
return;
case 0x04004001:
+ if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
SCFG_BIOS |= ((val & 0x07) << 8);
return;
+ case 0x04004060:
+ case 0x04004061:
+ case 0x04004062:
+ case 0x04004063:
+ {
+ if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
+ u32 tmp = MBK[0][8];
+ tmp &= ~(0xff << ((addr % 4) * 8));
+ tmp |= (val << ((addr % 4) * 8));
+ MBK[0][8] = tmp & 0x00FFFF0F;
+ MBK[1][8] = MBK[0][8];
+ return;
+ }
case 0x04004500: DSi_I2C::WriteData(val); return;
case 0x04004501: DSi_I2C::WriteCnt(val); return;
@@ -2043,18 +2378,34 @@ void ARM7IOWrite16(u32 addr, u16 val)
{
switch (addr)
{
- case 0x04000218: NDS::IE2 = (val & 0x7FF7); NDS::UpdateIRQ(1); return;
- case 0x0400021C: NDS::IF2 &= ~(val & 0x7FF7); NDS::UpdateIRQ(1); return;
+ case 0x04000218: NDS::IE2 = (val & 0x7FF7); NDS::UpdateIRQ(1); return;
+ case 0x0400021C: NDS::IF2 &= ~(val & 0x7FF7); NDS::UpdateIRQ(1); return;
- case 0x04004000:
- SCFG_BIOS |= (val & 0x0703);
- return;
- case 0x04004004:
- SCFG_Clock7 = val & 0x0187;
- return;
- case 0x04004010:
- Set_SCFG_MC((SCFG_MC & 0xFFFF0000) | val);
- return;
+ case 0x04004000:
+ if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
+ SCFG_BIOS |= (val & 0x0703);
+ return;
+ case 0x04004004:
+ if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
+ SCFG_Clock7 = val & 0x0187;
+ return;
+ case 0x04004010:
+ if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
+ Set_SCFG_MC((SCFG_MC & 0xFFFF0000) | val);
+ return;
+ case 0x04004060:
+ case 0x04004062:
+ if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
+ u32 tmp = MBK[0][8];
+ tmp &= ~(0xffff << ((addr % 4) * 8));
+ tmp |= (val << ((addr % 4) * 8));
+ MBK[0][8] = tmp & 0x00FFFF0F;
+ MBK[1][8] = MBK[0][8];
+ return;
}
if (addr >= 0x04004800 && addr < 0x04004A00)
@@ -2079,9 +2430,13 @@ void ARM7IOWrite32(u32 addr, u32 val)
case 0x0400021C: NDS::IF2 &= ~(val & 0x7FF7); NDS::UpdateIRQ(1); return;
case 0x04004000:
+ if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
SCFG_BIOS |= (val & 0x0703);
return;
case 0x04004008:
+ if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
SCFG_EXT[0] &= ~0x03000000;
SCFG_EXT[0] |= (val & 0x03000000);
SCFG_EXT[1] &= ~0x93FF0F07;
@@ -2089,13 +2444,33 @@ void ARM7IOWrite32(u32 addr, u32 val)
printf("SCFG_EXT = %08X / %08X (val7 %08X)\n", SCFG_EXT[0], SCFG_EXT[1], val);
return;
case 0x04004010:
+ if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
Set_SCFG_MC(val);
return;
- case 0x04004054: MapNWRAMRange(1, 0, val); return;
- case 0x04004058: MapNWRAMRange(1, 1, val); return;
- case 0x0400405C: MapNWRAMRange(1, 2, val); return;
- case 0x04004060: val &= 0x00FFFF0F; MBK[0][8] = val; MBK[1][8] = val; return;
+ case 0x04004054:
+ if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
+ MapNWRAMRange(1, 0, val);
+ return;
+ case 0x04004058:
+ if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
+ MapNWRAMRange(1, 1, val);
+ return;
+ case 0x0400405C:
+ if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
+ MapNWRAMRange(1, 2, val);
+ return;
+ case 0x04004060:
+ if (!(SCFG_EXT[1] & (1 << 31))) /* no access to SCFG Registers if disabled*/
+ return;
+ val &= 0x00FFFF0F;
+ MBK[0][8] = val;
+ MBK[1][8] = val;
+ return;
case 0x04004100: NDMACnt[1] = val & 0x800F0000; return;
case 0x04004104: NDMAs[4]->SrcAddr = val & 0xFFFFFFFC; return;
diff --git a/src/DSi.h b/src/DSi.h
index a56df66..187dc52 100644
--- a/src/DSi.h
+++ b/src/DSi.h
@@ -60,6 +60,7 @@ bool Init();
void DeInit();
void Reset();
+void SetupDirectBoot();
void SoftReset();
bool LoadBIOS();
diff --git a/src/NDS.cpp b/src/NDS.cpp
index 699b3a6..cd0cb92 100644
--- a/src/NDS.cpp
+++ b/src/NDS.cpp
@@ -164,7 +164,6 @@ bool Running;
bool RunningGame;
-
void DivDone(u32 param);
void SqrtDone(u32 param);
void RunTimer(u32 tid, s32 cycles);
@@ -342,8 +341,13 @@ void SetupDirectBoot()
{
if (ConsoleType == 1)
{
- printf("!! DIRECT BOOT NOT SUPPORTED IN DSI MODE\n");
- return;
+ // With the BIOS select in SCFG_BIOS and the initialization od
+ // SCFG_BIOS depending on the Header->UnitType, we can now boot
+ // directly in the roms.
+ // There are some more SCFG Settings that change depending on
+ // the unit type, so this is experimental
+ printf("!! DIRECT BOOT NOT STABLE IN DSI MODE\n");
+ DSi::SetupDirectBoot();
}
u32 bootparams[8];