aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/DSi.cpp202
-rw-r--r--src/DSi.h5
2 files changed, 206 insertions, 1 deletions
diff --git a/src/DSi.cpp b/src/DSi.cpp
index 8026e49..920981d 100644
--- a/src/DSi.cpp
+++ b/src/DSi.cpp
@@ -16,6 +16,8 @@
with melonDS. If not, see http://www.gnu.org/licenses/.
*/
+#include <stdio.h>
+#include <string.h>
#include "NDS.h"
#include "DSi.h"
#include "tiny-AES-c/aes.hpp"
@@ -26,7 +28,19 @@
namespace DSi
{
-//
+u32 MBK[2][9];
+
+u8 NWRAM_A[0x40000];
+u8 NWRAM_B[0x40000];
+u8 NWRAM_C[0x40000];
+
+u8* NWRAMMap_A[2][4];
+u8* NWRAMMap_B[3][4];
+u8* NWRAMMap_C[3][4];
+
+u32 NWRAMStart[2][3];
+u32 NWRAMEnd[2][3];
+u32 NWRAMMask[2][3];
bool LoadBIOS()
@@ -81,6 +95,18 @@ bool LoadNAND()
{
printf("Loading DSi NAND\n");
+ memset(NWRAM_A, 0, 0x40000);
+ memset(NWRAM_B, 0, 0x40000);
+ memset(NWRAM_C, 0, 0x40000);
+
+ memset(MBK, 0, sizeof(MBK));
+ memset(NWRAMMap_A, 0, sizeof(NWRAMMap_A));
+ memset(NWRAMMap_B, 0, sizeof(NWRAMMap_B));
+ memset(NWRAMMap_C, 0, sizeof(NWRAMMap_C));
+ memset(NWRAMStart, 0, sizeof(NWRAMStart));
+ memset(NWRAMEnd, 0, sizeof(NWRAMEnd));
+ memset(NWRAMMask, 0, sizeof(NWRAMMask));
+
FILE* f = Platform::OpenLocalFile("nand.bin", "rb");
if (f)
{
@@ -93,6 +119,45 @@ bool LoadNAND()
printf("ARM7: offset=%08X size=%08X RAM=%08X size_aligned=%08X\n",
bootparams[4], bootparams[5], bootparams[6], bootparams[7]);
+ // read and apply new-WRAM settings
+
+ u32 mbk[12];
+ fseek(f, 0x380, SEEK_SET);
+ fread(mbk, 4, 12, f);
+
+ MapNWRAM_A(0, mbk[0] & 0xFF);
+ MapNWRAM_A(1, (mbk[0] >> 8) & 0xFF);
+ MapNWRAM_A(2, (mbk[0] >> 16) & 0xFF);
+ MapNWRAM_A(3, mbk[0] >> 24);
+
+ MapNWRAM_B(0, mbk[1] & 0xFF);
+ MapNWRAM_B(1, (mbk[1] >> 8) & 0xFF);
+ MapNWRAM_B(2, (mbk[1] >> 16) & 0xFF);
+ MapNWRAM_B(3, mbk[1] >> 24);
+ MapNWRAM_B(4, mbk[2] & 0xFF);
+ MapNWRAM_B(5, (mbk[2] >> 8) & 0xFF);
+ MapNWRAM_B(6, (mbk[2] >> 16) & 0xFF);
+ MapNWRAM_B(7, mbk[2] >> 24);
+
+ MapNWRAM_C(0, mbk[3] & 0xFF);
+ MapNWRAM_C(1, (mbk[3] >> 8) & 0xFF);
+ MapNWRAM_C(2, (mbk[3] >> 16) & 0xFF);
+ MapNWRAM_C(3, mbk[3] >> 24);
+ MapNWRAM_C(4, mbk[4] & 0xFF);
+ MapNWRAM_C(5, (mbk[4] >> 8) & 0xFF);
+ MapNWRAM_C(6, (mbk[4] >> 16) & 0xFF);
+ MapNWRAM_C(7, mbk[4] >> 24);
+
+ MapNWRAMRange(0, 0, mbk[5]);
+ MapNWRAMRange(0, 1, mbk[6]);
+ MapNWRAMRange(0, 2, mbk[7]);
+
+ MapNWRAMRange(1, 0, mbk[8]);
+ MapNWRAMRange(1, 1, mbk[9]);
+ MapNWRAMRange(1, 2, mbk[10]);
+
+ // TODO: MBK9 protect thing
+
#define printhex(str, size) { for (int z = 0; z < (size); z++) printf("%02X", (str)[z]); printf("\n"); }
#define printhex_rev(str, size) { for (int z = (size)-1; z >= 0; z--) printf("%02X", (str)[z]); printf("\n"); }
@@ -112,6 +177,141 @@ bool LoadNAND()
}
+// new WRAM mapping
+// TODO: find out what happens upon overlapping slots!!
+
+void MapNWRAM_A(u32 num, u8 val)
+{
+ int mbkn = 0, mbks = 8*num;
+
+ u8 oldval = (MBK[0][mbkn] >> mbks) & 0xFF;
+ if (oldval == val) return;
+
+ MBK[0][mbkn] &= ~(0xFF << mbks);
+ MBK[0][mbkn] |= (val << mbks);
+ MBK[1][mbkn] = MBK[0][mbkn];
+
+ u8* ptr = &NWRAM_A[num << 16];
+
+ if (oldval & 0x80)
+ {
+ if (NWRAMMap_A[oldval & 0x01][(oldval >> 2) & 0x3] == ptr)
+ NWRAMMap_A[oldval & 0x01][(oldval >> 2) & 0x3] = NULL;
+ }
+
+ if (val & 0x80)
+ {
+ NWRAMMap_A[val & 0x01][(val >> 2) & 0x3] = ptr;
+ }
+}
+
+void MapNWRAM_B(u32 num, u8 val)
+{
+ int mbkn = 1+(num>>2), mbks = 8*(num&3);
+
+ u8 oldval = (MBK[0][mbkn] >> mbks) & 0xFF;
+ if (oldval == val) return;
+
+ MBK[0][mbkn] &= ~(0xFF << mbks);
+ MBK[0][mbkn] |= (val << mbks);
+ MBK[1][mbkn] = MBK[0][mbkn];
+
+ u8* ptr = &NWRAM_B[num << 15];
+
+ if (oldval & 0x80)
+ {
+ if (oldval & 0x02) oldval &= 0xFE;
+
+ if (NWRAMMap_B[oldval & 0x03][(oldval >> 2) & 0x7] == ptr)
+ NWRAMMap_B[oldval & 0x03][(oldval >> 2) & 0x7] = NULL;
+ }
+
+ if (val & 0x80)
+ {
+ if (val & 0x02) val &= 0xFE;
+
+ NWRAMMap_B[val & 0x03][(val >> 2) & 0x7] = ptr;
+ }
+}
+
+void MapNWRAM_C(u32 num, u8 val)
+{
+ int mbkn = 3+(num>>2), mbks = 8*(num&3);
+
+ u8 oldval = (MBK[0][mbkn] >> mbks) & 0xFF;
+ if (oldval == val) return;
+
+ MBK[0][mbkn] &= ~(0xFF << mbks);
+ MBK[0][mbkn] |= (val << mbks);
+ MBK[1][mbkn] = MBK[0][mbkn];
+
+ u8* ptr = &NWRAM_C[num << 15];
+
+ if (oldval & 0x80)
+ {
+ if (oldval & 0x02) oldval &= 0xFE;
+
+ if (NWRAMMap_C[oldval & 0x03][(oldval >> 2) & 0x7] == ptr)
+ NWRAMMap_C[oldval & 0x03][(oldval >> 2) & 0x7] = NULL;
+ }
+
+ if (val & 0x80)
+ {
+ if (val & 0x02) val &= 0xFE;
+
+ NWRAMMap_C[val & 0x03][(val >> 2) & 0x7] = ptr;
+ }
+}
+
+void MapNWRAMRange(u32 cpu, u32 num, u32 val)
+{
+ u32 oldval = MBK[cpu][5+num];
+ if (oldval == val) return;
+
+ MBK[cpu][5+num] = val;
+
+ // TODO: what happens when the ranges are 'out of range'????
+ if (num == 0)
+ {
+ u32 start = 0x03000000 + (((val >> 4) & 0xFF) << 16);
+ u32 end = 0x03000000 + (((val >> 20) & 0x1FF) << 16);
+ u32 size = (val >> 12) & 0x3;
+
+ printf("NWRAM-A: ARM%d range %08X-%08X, size %d\n", cpu?7:9, start, end, size);
+
+ NWRAMStart[cpu][num] = start;
+ NWRAMEnd[cpu][num] = end;
+
+ switch (size)
+ {
+ case 0:
+ case 1: NWRAMMask[cpu][num] = 0x0; break;
+ case 2: NWRAMMask[cpu][num] = 0x1; break; // CHECKME
+ case 3: NWRAMMask[cpu][num] = 0x3; break;
+ }
+ }
+ else
+ {
+ u32 start = 0x03000000 + (((val >> 3) & 0x1FF) << 15);
+ u32 end = 0x03000000 + (((val >> 19) & 0x3FF) << 15);
+ u32 size = (val >> 12) & 0x3;
+
+ printf("NWRAM-%c: ARM%d range %08X-%08X, size %d\n", 'A'+num, cpu?7:9, start, end, size);
+
+ NWRAMStart[cpu][num] = start;
+ NWRAMEnd[cpu][num] = end;
+
+ switch (size)
+ {
+ case 0: NWRAMMask[cpu][num] = 0x0; break;
+ case 1: NWRAMMask[cpu][num] = 0x1; break;
+ case 2: NWRAMMask[cpu][num] = 0x3; break;
+ case 3: NWRAMMask[cpu][num] = 0x7; break;
+ }
+ }
+}
+
+
u8 ARM9Read8(u32 addr)
{
switch (addr & 0xFF000000)
diff --git a/src/DSi.h b/src/DSi.h
index 2a3ee21..040c39b 100644
--- a/src/DSi.h
+++ b/src/DSi.h
@@ -27,6 +27,11 @@ namespace DSi
bool LoadBIOS();
bool LoadNAND();
+void MapNWRAM_A(u32 num, u8 val);
+void MapNWRAM_B(u32 num, u8 val);
+void MapNWRAM_C(u32 num, u8 val);
+void MapNWRAMRange(u32 cpu, u32 num, u32 val);
+
u8 ARM9Read8(u32 addr);
u16 ARM9Read16(u32 addr);
u32 ARM9Read32(u32 addr);