From b1c2665c398c06a69f4a70736b1e6e34d3b5f741 Mon Sep 17 00:00:00 2001 From: DesperateProgrammer Date: Fri, 23 Jul 2021 12:21:54 +0200 Subject: 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 --- src/DSi.cpp | 1005 ++++++++++++++++++++++++++++++++++++++++------------------- src/DSi.h | 1 + src/NDS.cpp | 10 +- 3 files changed, 698 insertions(+), 318 deletions(-) (limited to 'src') 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]; -- cgit v1.2.3