aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ARM.cpp7
-rw-r--r--ARM.h6
-rw-r--r--ARMInterpreter.h4
-rw-r--r--ARMInterpreter_ALU.cpp27
-rw-r--r--ARMInterpreter_ALU.h2
-rw-r--r--ARMInterpreter_LoadStore.cpp32
-rw-r--r--ARM_InstrTable.h2
-rw-r--r--CP15.cpp12
-rw-r--r--GPU2D.cpp696
-rw-r--r--GPU2D.h29
-rw-r--r--NDS.cpp282
-rw-r--r--SPI.cpp4
-rw-r--r--melonDS.depend48
13 files changed, 1092 insertions, 59 deletions
diff --git a/ARM.cpp b/ARM.cpp
index fab4698..6c6949d 100644
--- a/ARM.cpp
+++ b/ARM.cpp
@@ -206,7 +206,10 @@ void ARM::UpdateMode(u32 oldmode, u32 newmode)
void ARM::TriggerIRQ()
{
- if (CPSR & 0x80) return;
+ if ((CPSR & 0x80) && (!Halted))
+ return;
+
+ Halted = 0;
u32 oldcpsr = CPSR;
CPSR &= ~0xFF;
@@ -220,6 +223,8 @@ void ARM::TriggerIRQ()
s32 ARM::Execute(s32 cycles)
{
+ if (Halted) return cycles;
+
s32 cyclesrun = 0;
while (cyclesrun < cycles)
diff --git a/ARM.h b/ARM.h
index 72ba088..e420c59 100644
--- a/ARM.h
+++ b/ARM.h
@@ -40,6 +40,11 @@ public:
void JumpTo(u32 addr, bool restorecpsr = false);
void RestoreCPSR();
+ void Halt(u32 halt)
+ {
+ Halted = halt;
+ }
+
s32 Execute(s32 cycles);
bool CheckCondition(u32 code)
@@ -162,6 +167,7 @@ public:
u32 Num;
s32 Cycles;
+ u32 Halted;
u32 R[16]; // heh
u32 CPSR;
diff --git a/ARMInterpreter.h b/ARMInterpreter.h
index 12005f3..e6fed79 100644
--- a/ARMInterpreter.h
+++ b/ARMInterpreter.h
@@ -25,10 +25,6 @@
namespace ARMInterpreter
{
-s32 A_MSR_IMM(ARM* cpu);
-s32 A_MSR_REG(ARM* cpu);
-s32 A_MRS(ARM* cpu);
-
extern s32 (*ARMInstrTable[4096])(ARM* cpu);
extern s32 (*THUMBInstrTable[1024])(ARM* cpu);
diff --git a/ARMInterpreter_ALU.cpp b/ARMInterpreter_ALU.cpp
index 676ff5f..16e3153 100644
--- a/ARMInterpreter_ALU.cpp
+++ b/ARMInterpreter_ALU.cpp
@@ -718,6 +718,33 @@ A_IMPLEMENT_ALU_OP(MVN)
+s32 A_CLZ(ARM* cpu)
+{
+ // TODO: ARM9 only
+
+ u32 val = cpu->R[cpu->CurInstr & 0xF];
+
+ u32 res = 0;
+ while ((val & 0xFF000000) == 0)
+ {
+ res += 8;
+ val <<= 8;
+ val |= 0xFF;
+ }
+ while ((val & 0x80000000) == 0)
+ {
+ res++;
+ val <<= 1;
+ val |= 0x1;
+ }
+
+ cpu->R[(cpu->CurInstr >> 12) & 0xF] = res;
+
+ return C_S(1);
+}
+
+
+
// ---- THUMB ----------------------------------
diff --git a/ARMInterpreter_ALU.h b/ARMInterpreter_ALU.h
index 1c6fe44..610ffed 100644
--- a/ARMInterpreter_ALU.h
+++ b/ARMInterpreter_ALU.h
@@ -72,6 +72,8 @@ A_PROTO_ALU_OP(MOV)
A_PROTO_ALU_OP(BIC)
A_PROTO_ALU_OP(MVN)
+s32 A_CLZ(ARM* cpu);
+
s32 T_LSL_IMM(ARM* cpu);
s32 T_LSR_IMM(ARM* cpu);
diff --git a/ARMInterpreter_LoadStore.cpp b/ARMInterpreter_LoadStore.cpp
index 165a2fe..2106adc 100644
--- a/ARMInterpreter_LoadStore.cpp
+++ b/ARMInterpreter_LoadStore.cpp
@@ -370,9 +370,19 @@ s32 A_LDM(ARM* cpu)
if (cpu->CurInstr & (1<<21))
{
- cpu->R[(cpu->CurInstr >> 16) & 0xF] = base;
- if (cpu->CurInstr & (1 << ((cpu->CurInstr >> 16) & 0xF)))
- printf("!! BAD LDM\n");
+ // pre writeback
+ u32 rb = (cpu->CurInstr >> 16) & 0xF;
+ if (cpu->CurInstr & (1 << rb))
+ {
+ if (cpu->Num == 0)
+ {
+ u32 rlist = cpu->CurInstr & 0xFFFF;
+ if ((!(rlist & ~(1 << rb))) || (rlist & ~((2 << rb) - 1)))
+ cpu->R[rb] = base;
+ }
+ }
+ else
+ cpu->R[rb] = base;
}
preinc = !preinc;
@@ -412,9 +422,19 @@ s32 A_LDM(ARM* cpu)
if ((cpu->CurInstr & (1<<23)) && (cpu->CurInstr & (1<<21)))
{
- cpu->R[(cpu->CurInstr >> 16) & 0xF] = base;
- if (cpu->CurInstr & (1 << ((cpu->CurInstr >> 16) & 0xF)))
- printf("!! BAD LDM\n");
+ // post writeback
+ u32 rb = (cpu->CurInstr >> 16) & 0xF;
+ if (cpu->CurInstr & (1 << rb))
+ {
+ if (cpu->Num == 0)
+ {
+ u32 rlist = cpu->CurInstr & 0xFFFF;
+ if ((!(rlist & ~(1 << rb))) || (rlist & ~((2 << rb) - 1)))
+ cpu->R[rb] = base;
+ }
+ }
+ else
+ cpu->R[rb] = base;
}
return cycles;
diff --git a/ARM_InstrTable.h b/ARM_InstrTable.h
index e39703c..351f40b 100644
--- a/ARM_InstrTable.h
+++ b/ARM_InstrTable.h
@@ -153,7 +153,7 @@ INSTRFUNC_PROTO(ARMInstrTable[4096]) =
A_CMP_REG_ASR_IMM, A_LDRSB_IMM, A_CMP_REG_ROR_IMM, A_LDRSH_IMM,
// 0001 0110 0000
- A_MSR_REG, A_UNK, A_UNK, A_UNK,
+ A_MSR_REG, A_CLZ, A_UNK, A_UNK,
A_UNK, A_UNK, A_UNK, A_UNK,
A_UNK, A_UNK, A_UNK, A_STRH_IMM,
A_UNK, A_LDRD_IMM, A_UNK, A_STRD_IMM,
diff --git a/CP15.cpp b/CP15.cpp
index 528f62e..1213d28 100644
--- a/CP15.cpp
+++ b/CP15.cpp
@@ -18,8 +18,15 @@
#include <stdio.h>
#include "NDS.h"
+#include "ARM.h"
+// derp
+namespace NDS
+{
+extern ARM* ARM9;
+}
+
namespace CP15
{
@@ -81,6 +88,11 @@ void Write(u32 id, u32 val)
return;
+ case 0x704:
+ NDS::ARM9->Halt(1);
+ return;
+
+
case 0x910:
DTCMSetting = val;
UpdateDTCMSetting();
diff --git a/GPU2D.cpp b/GPU2D.cpp
index 8145101..a879576 100644
--- a/GPU2D.cpp
+++ b/GPU2D.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 "GPU2D.h"
@@ -23,6 +25,698 @@
namespace GPU2D
{
-//
+#define LINE_CYCLES (355*6 * 2)
+#define FRAME_CYCLES (LINE_CYCLES * 263)
+
+u16 VCount;
+
+u16 DispStat[2], VMatch[2];
+
+u8 VRAM_A[128*1024];
+u8 VRAM_B[128*1024];
+u8 VRAM_C[128*1024];
+u8 VRAM_D[128*1024];
+u8 VRAM_E[ 64*1024];
+u8 VRAM_F[ 16*1024];
+u8 VRAM_G[ 16*1024];
+u8 VRAM_H[ 32*1024];
+u8 VRAM_I[ 16*1024];
+u8* VRAM[9] = {VRAM_A, VRAM_B, VRAM_C, VRAM_D, VRAM_E, VRAM_F, VRAM_G, VRAM_H, VRAM_I};
+
+u8 VRAMCNT[9];
+u8 VRAMSTAT;
+
+u8* VRAM_ABG[128];
+u8* VRAM_AOBJ[128];
+u8* VRAM_BBG[128];
+u8* VRAM_BOBJ[128];
+u8* VRAM_LCD[128];
+u8* VRAM_ARM7[2];
+
+
+void Reset()
+{
+ VCount = 0;
+
+ DispStat[0] = 0;
+ DispStat[1] = 0;
+ VMatch[0] = 0;
+ VMatch[1] = 0;
+
+ memset(VRAM_A, 0, 128*1024);
+ memset(VRAM_B, 0, 128*1024);
+ memset(VRAM_C, 0, 128*1024);
+ memset(VRAM_D, 0, 128*1024);
+ memset(VRAM_E, 0, 64*1024);
+ memset(VRAM_F, 0, 16*1024);
+ memset(VRAM_G, 0, 16*1024);
+ memset(VRAM_H, 0, 32*1024);
+ memset(VRAM_I, 0, 16*1024);
+
+ memset(VRAMCNT, 0, 9);
+ VRAMSTAT = 0;
+
+ memset(VRAM_ABG, 0, sizeof(u8*)*128);
+ memset(VRAM_AOBJ, 0, sizeof(u8*)*128);
+ memset(VRAM_BBG, 0, sizeof(u8*)*128);
+ memset(VRAM_BOBJ, 0, sizeof(u8*)*128);
+ memset(VRAM_LCD, 0, sizeof(u8*)*128);
+ memset(VRAM_ARM7, 0, sizeof(u8*)*2);
+}
+
+
+void MapVRAM_AB(u32 bank, u8 cnt)
+{
+ u8 oldcnt = VRAMCNT[bank];
+ VRAMCNT[bank] = cnt;
+
+ if (oldcnt == cnt) return;
+
+ u8 oldofs = (oldcnt >> 3) & 0x3;
+ u8 ofs = (cnt >> 3) & 0x3;
+
+ u8* vram = VRAM[bank];
+
+ if (oldcnt & (1<<7))
+ {
+ u8** vrammap = NULL;
+
+ switch (oldcnt & 0x3)
+ {
+ case 0:
+ vrammap = &VRAM_LCD[bank<<3];
+ break;
+
+ case 1:
+ vrammap = &VRAM_ABG[oldofs<<3];
+ break;
+
+ case 2:
+ oldofs &= 0x1;
+ vrammap = &VRAM_AOBJ[oldofs<<3];
+ break;
+
+ case 3:
+ // not mapped to memory
+ break;
+ }
+
+ if (vrammap)
+ {
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap = NULL;
+ }
+ }
+
+ if (cnt & (1<<7))
+ {
+ u8** vrammap = NULL;
+
+ switch (cnt & 0x3)
+ {
+ case 0:
+ vrammap = &VRAM_LCD[bank<<3];
+ break;
+
+ case 1:
+ vrammap = &VRAM_ABG[ofs<<3];
+ break;
+
+ case 2:
+ ofs &= 0x1;
+ vrammap = &VRAM_AOBJ[ofs<<3];
+ break;
+
+ case 3:
+ // not mapped to memory
+ break;
+ }
+
+ if (vrammap)
+ {
+ *vrammap++ = vram; vram += 0x4000;
+ *vrammap++ = vram; vram += 0x4000;
+ *vrammap++ = vram; vram += 0x4000;
+ *vrammap++ = vram; vram += 0x4000;
+ *vrammap++ = vram; vram += 0x4000;
+ *vrammap++ = vram; vram += 0x4000;
+ *vrammap++ = vram; vram += 0x4000;
+ *vrammap = vram;
+ }
+ }
+}
+
+void MapVRAM_CD(u32 bank, u8 cnt)
+{
+ u8 oldcnt = VRAMCNT[bank];
+ VRAMCNT[bank] = cnt;
+
+ VRAMSTAT &= ~(1 << (bank-2));
+
+ if (oldcnt == cnt) return;
+
+ u8 oldofs = (oldcnt >> 3) & 0x7;
+ u8 ofs = (cnt >> 3) & 0x7;
+
+ u8* vram = VRAM[bank];
+
+ if (oldcnt & (1<<7))
+ {
+ u8** vrammap = NULL;
+
+ switch (oldcnt & 0x7)
+ {
+ case 0:
+ vrammap = &VRAM_LCD[bank<<3];
+ break;
+
+ case 1:
+ vrammap = &VRAM_ABG[oldofs<<3];
+ break;
+
+ case 2:
+ oldofs &= 0x1;
+ VRAM_ARM7[oldofs] = NULL;
+ break;
+
+ case 3:
+ // not mapped to memory
+ break;
+
+ case 4:
+ if (bank == 2)
+ vrammap = &VRAM_BBG[0];
+ else
+ vrammap = &VRAM_BOBJ[0];
+ break;
+ }
+
+ if (vrammap)
+ {
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap = NULL;
+ }
+ }
+
+ if (cnt & (1<<7))
+ {
+ u8** vrammap = NULL;
+
+ switch (cnt & 0x7)
+ {
+ case 0:
+ vrammap = &VRAM_LCD[bank<<3];
+ break;
+
+ case 1:
+ vrammap = &VRAM_ABG[ofs<<3];
+ break;
+
+ case 2:
+ ofs &= 0x1;
+ VRAM_ARM7[ofs] = vram;
+ VRAMSTAT |= (1 << (bank-2));
+ break;
+
+ case 3:
+ // not mapped to memory
+ break;
+
+ case 4:
+ if (bank == 2)
+ vrammap = &VRAM_BBG[0];
+ else
+ vrammap = &VRAM_BOBJ[0];
+ break;
+ }
+
+ if (vrammap)
+ {
+ *vrammap++ = vram; vram += 0x4000;
+ *vrammap++ = vram; vram += 0x4000;
+ *vrammap++ = vram; vram += 0x4000;
+ *vrammap++ = vram; vram += 0x4000;
+ *vrammap++ = vram; vram += 0x4000;
+ *vrammap++ = vram; vram += 0x4000;
+ *vrammap++ = vram; vram += 0x4000;
+ *vrammap = vram;
+ }
+ }
+}
+
+void MapVRAM_E(u32 bank, u8 cnt)
+{
+ u8 oldcnt = VRAMCNT[bank];
+ VRAMCNT[bank] = cnt;
+
+ if (oldcnt == cnt) return;
+
+ u8 oldofs = (oldcnt >> 3) & 0x7;
+ u8 ofs = (cnt >> 3) & 0x7;
+
+ u8* vram = VRAM[bank];
+
+ if (oldcnt & (1<<7))
+ {
+ u8** vrammap = NULL;
+
+ switch (oldcnt & 0x7)
+ {
+ case 0:
+ VRAM_LCD[0x20] = NULL;
+ VRAM_LCD[0x21] = NULL;
+ VRAM_LCD[0x22] = NULL;
+ VRAM_LCD[0x23] = NULL;
+ break;
+
+ case 1:
+ vrammap = &VRAM_ABG[0];
+ break;
+
+ case 2:
+ vrammap = &VRAM_AOBJ[0];
+ break;
+
+ case 3:
+ // not mapped to memory
+ break;
+
+ case 4:
+ // BG EXTPAL -- TODO
+ break;
+
+ case 5:
+ // OBJ EXTPAL -- TODO
+ break;
+ }
+
+ if (vrammap)
+ {
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap = NULL;
+ }
+ }
+
+ if (cnt & (1<<7))
+ {
+ u8** vrammap = NULL;
+
+ switch (cnt & 0x7)
+ {
+ case 0:
+ VRAM_LCD[0x20] = &vram[0x0000];
+ VRAM_LCD[0x21] = &vram[0x4000];
+ VRAM_LCD[0x22] = &vram[0x8000];
+ VRAM_LCD[0x23] = &vram[0xC000];
+ break;
+
+ case 1:
+ vrammap = &VRAM_ABG[0];
+ break;
+
+ case 2:
+ vrammap = &VRAM_AOBJ[0];
+ break;
+
+ case 3:
+ // not mapped to memory
+ break;
+
+ case 4:
+ // BG EXTPAL -- TODO
+ break;
+
+ case 5:
+ // OBJ EXTPAL -- TODO
+ break;
+ }
+
+ if (vrammap)
+ {
+ *vrammap++ = &vram[0x0000];
+ *vrammap++ = &vram[0x4000];
+ *vrammap++ = &vram[0x8000];
+ *vrammap++ = &vram[0xC000];
+ *vrammap++ = &vram[0x0000];
+ *vrammap++ = &vram[0x4000];
+ *vrammap++ = &vram[0x8000];
+ *vrammap = &vram[0xC000];
+ }
+ }
+}
+
+void MapVRAM_FG(u32 bank, u8 cnt)
+{
+ u8 oldcnt = VRAMCNT[bank];
+ VRAMCNT[bank] = cnt;
+
+ if (oldcnt == cnt) return;
+
+ u8 oldofs = (oldcnt >> 3) & 0x7;
+ u8 ofs = (cnt >> 3) & 0x7;
+
+ u8* vram = VRAM[bank];
+ bank -= 5;
+
+ if (oldcnt & (1<<7))
+ {
+ u8** vrammap = NULL;
+
+ switch (oldcnt & 0x7)
+ {
+ case 0:
+ VRAM_LCD[0x24 + bank] = NULL;
+ break;
+
+ case 1:
+ vrammap = &VRAM_ABG[(oldofs & 0x1) | ((oldofs & 0x2) << 1)];
+ break;
+
+ case 2:
+ vrammap = &VRAM_AOBJ[(oldofs & 0x1) | ((oldofs & 0x2) << 1)];
+ break;
+
+ case 3:
+ // not mapped to memory
+ break;
+
+ case 4:
+ // BG EXTPAL TODO
+ break;
+
+ case 5:
+ // OBJ EXTPAL TODO
+ break;
+ }
+
+ if (vrammap)
+ {
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap = NULL;
+ }
+ }
+
+ if (cnt & (1<<7))
+ {
+ u8** vrammap = NULL;
+
+ switch (cnt & 0x7)
+ {
+ case 0:
+ VRAM_LCD[0x24 + bank] = vram;
+ break;
+
+ case 1:
+ vrammap = &VRAM_ABG[(ofs & 0x1) | ((ofs & 0x2) << 1)];
+ break;
+
+ case 2:
+ vrammap = &VRAM_AOBJ[(ofs & 0x1) | ((ofs & 0x2) << 1)];
+ break;
+
+ case 3:
+ // not mapped to memory
+ break;
+
+ case 4:
+ // BG EXTPAL TODO
+ break;
+
+ case 5:
+ // OBJ EXTPAL TODO
+ break;
+ }
+
+ if (vrammap)
+ {
+ *vrammap++ = vram;
+ *vrammap++ = vram;
+ *vrammap++ = vram;
+ *vrammap++ = vram;
+ *vrammap++ = vram;
+ *vrammap++ = vram;
+ *vrammap++ = vram;
+ *vrammap = vram;
+ }
+ }
+}
+
+void MapVRAM_H(u32 bank, u8 cnt)
+{
+ u8 oldcnt = VRAMCNT[bank];
+ VRAMCNT[bank] = cnt;
+
+ if (oldcnt == cnt) return;
+
+ u8 oldofs = (oldcnt >> 3) & 0x7;
+ u8 ofs = (cnt >> 3) & 0x7;
+
+ u8* vram = VRAM[bank];
+
+ if (oldcnt & (1<<7))
+ {
+ u8** vrammap = NULL;
+
+ switch (oldcnt & 0x3)
+ {
+ case 0:
+ VRAM_LCD[0x26] = NULL;
+ VRAM_LCD[0x27] = NULL;
+ break;
+
+ case 1:
+ vrammap = &VRAM_BBG[0x00];
+ break;
+
+ case 2:
+ // BG EXTPAL TODO
+ break;
+ }
+
+ if (vrammap)
+ {
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap = NULL;
+ }
+ }
+
+ if (cnt & (1<<7))
+ {
+ u8** vrammap = NULL;
+
+ switch (cnt & 0x3)
+ {
+ case 0:
+ VRAM_LCD[0x26] = &vram[0x0000];
+ VRAM_LCD[0x27] = &vram[0x4000];
+ break;
+
+ case 1:
+ vrammap = &VRAM_BBG[0x00];
+ break;
+
+ case 2:
+ // BG EXTPAL TODO
+ break;
+ }
+
+ if (vrammap)
+ {
+ *vrammap++ = &vram[0x0000];
+ *vrammap++ = &vram[0x4000];
+ *vrammap++ = &vram[0x0000];
+ *vrammap++ = &vram[0x4000];
+ *vrammap++ = &vram[0x0000];
+ *vrammap++ = &vram[0x4000];
+ *vrammap++ = &vram[0x0000];
+ *vrammap = &vram[0x4000];
+ }
+ }
+}
+
+void MapVRAM_I(u32 bank, u8 cnt)
+{
+ u8 oldcnt = VRAMCNT[bank];
+ VRAMCNT[bank] = cnt;
+
+ if (oldcnt == cnt) return;
+
+ u8 oldofs = (oldcnt >> 3) & 0x7;
+ u8 ofs = (cnt >> 3) & 0x7;
+
+ u8* vram = VRAM[bank];
+ bank -= 5;
+
+ if (oldcnt & (1<<7))
+ {
+ u8** vrammap = NULL;
+
+ switch (oldcnt & 0x3)
+ {
+ case 0:
+ VRAM_LCD[0x28] = NULL;
+ break;
+
+ case 1:
+ vrammap = &VRAM_BBG[0x02];
+ break;
+
+ case 2:
+ vrammap = &VRAM_BOBJ[0x00];
+ break;
+
+ case 3:
+ // not mapped to memory
+ break;
+ }
+
+ if (vrammap)
+ {
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap++ = NULL;
+ *vrammap = NULL;
+ }
+ }
+
+ if (cnt & (1<<7))
+ {
+ u8** vrammap = NULL;
+
+ switch (cnt & 0x3)
+ {
+ case 0:
+ VRAM_LCD[0x28] = vram;
+ break;
+
+ case 1:
+ vrammap = &VRAM_BBG[0x02];
+ break;
+
+ case 2:
+ vrammap = &VRAM_BOBJ[0x00];
+ break;
+
+ case 3:
+ // not mapped to memory
+ break;
+ }
+
+ if (vrammap)
+ {
+ *vrammap++ = vram;
+ *vrammap++ = vram;
+ *vrammap++ = vram;
+ *vrammap++ = vram;
+ *vrammap++ = vram;
+ *vrammap++ = vram;
+ *vrammap++ = vram;
+ *vrammap = vram;
+ }
+ }
+}
+
+
+void StartFrame()
+{
+ StartScanline(0);
+}
+
+void StartScanline(u32 line)
+{
+ VCount = line;
+
+ if (line == VMatch[0])
+ {
+ DispStat[0] |= (1<<2);
+
+ if (DispStat[0] & (1<<5)) NDS::TriggerIRQ(0, NDS::IRQ_VCount);
+ }
+ else
+ DispStat[0] &= ~(1<<2);
+
+ if (line == VMatch[1])
+ {
+ DispStat[1] |= (1<<2);
+
+ if (DispStat[1] & (1<<5)) NDS::TriggerIRQ(1, NDS::IRQ_VCount);
+ }
+ else
+ DispStat[1] &= ~(1<<2);
+
+ if (line < 192)
+ {
+ // TODO: draw shit
+
+ NDS::ScheduleEvent(LINE_CYCLES, StartScanline, line+1);
+ }
+ else if (line == 262)
+ {
+ // frame end
+
+ DispStat[0] &= ~(1<<0);
+ DispStat[1] &= ~(1<<0);
+ }
+ else
+ {
+ if (line == 192)
+ {
+ // VBlank
+ DispStat[0] |= (1<<0);
+ DispStat[1] |= (1<<0);
+
+ if (DispStat[0] & (1<<3)) NDS::TriggerIRQ(0, NDS::IRQ_VBlank);
+ if (DispStat[1] & (1<<3)) NDS::TriggerIRQ(1, NDS::IRQ_VBlank);
+ }
+
+ NDS::ScheduleEvent(LINE_CYCLES, StartScanline, line+1);
+ }
+}
+
+
+void SetDispStat(u32 cpu, u16 val)
+{
+ val &= 0xFFB8;
+ DispStat[cpu] &= 0x0047;
+ DispStat[cpu] |= val;
+
+ VMatch[cpu] = (val >> 8) | ((val & 0x80) << 1);
+
+ if (val & 0x10) printf("!! HBLANK ENABLED\n");
+}
}
diff --git a/GPU2D.h b/GPU2D.h
index 4ff09e5..1b6c178 100644
--- a/GPU2D.h
+++ b/GPU2D.h
@@ -22,7 +22,34 @@
namespace GPU2D
{
-// shit here
+extern u16 VCount;
+
+extern u16 DispStat[2];
+
+extern u8 VRAMCNT[9];
+extern u8 VRAMSTAT;
+
+extern u8* VRAM_ABG[128];
+extern u8* VRAM_AOBJ[128];
+extern u8* VRAM_BBG[128];
+extern u8* VRAM_BOBJ[128];
+extern u8* VRAM_LCD[128];
+extern u8* VRAM_ARM7[2];
+
+
+void Reset();
+
+void MapVRAM_AB(u32 bank, u8 cnt);
+void MapVRAM_CD(u32 bank, u8 cnt);
+void MapVRAM_E(u32 bank, u8 cnt);
+void MapVRAM_FG(u32 bank, u8 cnt);
+void MapVRAM_H(u32 bank, u8 cnt);
+void MapVRAM_I(u32 bank, u8 cnt);
+
+void StartFrame();
+void StartScanline(u32 line);
+
+void SetDispStat(u32 cpu, u16 val);
}
diff --git a/NDS.cpp b/NDS.cpp
index 97fa850..dfb6194 100644
--- a/NDS.cpp
+++ b/NDS.cpp
@@ -21,6 +21,7 @@
#include "NDS.h"
#include "ARM.h"
#include "CP15.h"
+#include "GPU2D.h"
#include "SPI.h"
@@ -152,25 +153,30 @@ void Reset()
void RunFrame()
{
s32 framecycles = 560190<<1;
-
const s32 maxcycles = 16;
+ if (!Running) return; // dorp
+
+ GPU2D::StartFrame();
+
while (Running && framecycles>0)
{
- //ARM9Cycles = ARM9->Execute(32 + ARM9Cycles);
- //ARM7Cycles = ARM7->Execute(16 + ARM7Cycles);
-
- //framecycles -= 32;
s32 cyclestorun = maxcycles;
- // TODO: scheduler integration here
+ if (SchedQueue)
+ {
+ if (SchedQueue->Delay < cyclestorun)
+ cyclestorun = SchedQueue->Delay;
+ }
- CompensatedCycles = ARM9Cycles;
- s32 c9 = ARM9->Execute(cyclestorun - ARM9Cycles);
- ARM9Cycles = c9 - cyclestorun;
- c9 -= CompensatedCycles;
+ //CompensatedCycles = ARM9Cycles;
+ s32 torun9 = cyclestorun - ARM9Cycles;
+ s32 c9 = ARM9->Execute(torun9);
+ ARM9Cycles = c9 - torun9;
+ //c9 -= CompensatedCycles;
- s32 c7 = ARM7->Execute((c9 - ARM7Cycles) >> 1) << 1;
- ARM7Cycles = c7 - c9;
+ s32 torun7 = (c9 - ARM7Cycles) & ~1;
+ s32 c7 = ARM7->Execute(torun7 >> 1) << 1;
+ ARM7Cycles = c7 - torun7;
RunEvents(c9);
framecycles -= cyclestorun;
@@ -190,9 +196,24 @@ SchedEvent* ScheduleEvent(s32 Delay, void (*Func)(u32), u32 Param)
}
}
+ //if (Func == GPU2D::StartScanline)
+ // printf("add scanline event %d delay %d\n", Param, Delay);
+
if (entry == -1)
{
printf("!! SCHEDULER BUFFER FULL\n");
+ /*void TimerIncrement(u32 param);
+ for (int i = 0; i < SCHED_BUF_LEN; i++)
+ {
+ printf("%d. %s (%08X), delay %d, prev=%d, next=%d\n",
+ i,
+ SchedBuffer[i].Func ? ((SchedBuffer[i].Func==TimerIncrement)?"Timer":"Scanline") : "NULL",
+ SchedBuffer[i].Param,
+ SchedBuffer[i].Delay,
+ SchedBuffer[i].PrevEvent ? (SchedBuffer[i].PrevEvent-SchedBuffer) : -1,
+ SchedBuffer[i].NextEvent ? (SchedBuffer[i].NextEvent-SchedBuffer) : -1);
+ }*/
+ //printf("%p %p %08X %p\n", SchedQueue, SchedQueue->Func, SchedQueue->Param, TimerIncrement);
return NULL;
}
@@ -200,6 +221,8 @@ SchedEvent* ScheduleEvent(s32 Delay, void (*Func)(u32), u32 Param)
evt->Func = Func;
evt->Param = Param;
+ Delay += SchedCycles;
+
SchedEvent* cur = SchedQueue;
SchedEvent* prev = NULL;
for (;;)
@@ -239,6 +262,8 @@ SchedEvent* ScheduleEvent(s32 Delay, void (*Func)(u32), u32 Param)
if (evt->PrevEvent)
evt->PrevEvent->NextEvent = evt;
+ else
+ SchedQueue = evt;
cur->PrevEvent = evt;
cur->Delay -= evt->Delay;
@@ -264,6 +289,7 @@ void CancelEvent(SchedEvent* event)
void RunEvents(s32 cycles)
{
+ //printf("runevents %d\n", cycles);
SchedCycles += cycles;
SchedEvent* evt = SchedQueue;
@@ -281,7 +307,7 @@ void RunEvents(s32 cycles)
}
void CompensateARM7()
-{
+{return;
s32 c9 = ARM9->Cycles - CompensatedCycles;
CompensatedCycles = ARM9->Cycles;
@@ -358,7 +384,7 @@ void TimerIncrement(u32 param)
for (;;)
{
timer->Counter++;
- if (param==7)printf("timer%d increment %04X %04X %04X\n", param, timer->Control, timer->Counter, timer->Reload);
+
if (tid == (param&0x3))
timer->Event = ScheduleEvent(TimerPrescaler[timer->Control&0x3], TimerIncrement, param);
@@ -389,8 +415,6 @@ void TimerStart(u32 id, u16 cnt)
u16 curstart = timer->Control & (1<<7);
u16 newstart = cnt & (1<<7);
- printf("timer%d start: %04X %04X\n", id, timer->Control, cnt);
-
timer->Control = cnt;
if ((!curstart) && newstart)
@@ -442,9 +466,36 @@ u8 ARM9Read8(u32 addr)
{
case 0x04000208: return IME[0];
- case 0x04000247:
- return WRAMCnt;
+ case 0x04000240: return GPU2D::VRAMCNT[0];
+ case 0x04000241: return GPU2D::VRAMCNT[1];
+ case 0x04000242: return GPU2D::VRAMCNT[2];
+ case 0x04000243: return GPU2D::VRAMCNT[3];
+ case 0x04000244: return GPU2D::VRAMCNT[4];
+ case 0x04000245: return GPU2D::VRAMCNT[5];
+ case 0x04000246: return GPU2D::VRAMCNT[6];
+ case 0x04000247: return WRAMCnt;
+ case 0x04000248: return GPU2D::VRAMCNT[7];
+ case 0x04000249: return GPU2D::VRAMCNT[8];
}
+ printf("unknown arm9 IO read8 %08X\n", addr);
+ return 0;
+
+ case 0x06000000:
+ {
+ u32 chunk = (addr >> 14) & 0x7F;
+ u8* vram = NULL;
+ switch (addr & 0x00E00000)
+ {
+ case 0x00000000: vram = GPU2D::VRAM_ABG[chunk]; break;
+ case 0x00200000: vram = GPU2D::VRAM_AOBJ[chunk]; break;
+ case 0x00400000: vram = GPU2D::VRAM_BBG[chunk]; break;
+ case 0x00600000: vram = GPU2D::VRAM_BOBJ[chunk]; break;
+ case 0x00800000: vram = GPU2D::VRAM_LCD[chunk]; break;
+ }
+ if (vram)
+ return *(u8*)&vram[addr & 0x3FFF];
+ }
+ return 0;
}
printf("unknown arm9 read8 %08X\n", addr);
@@ -478,6 +529,9 @@ u16 ARM9Read16(u32 addr)
case 0x04000000:
switch (addr)
{
+ case 0x04000004: return GPU2D::DispStat[0];
+ case 0x04000006: return GPU2D::VCount;
+
case 0x04000100: return Timers[0].Counter;
case 0x04000102: return Timers[0].Control;
case 0x04000104: return Timers[1].Counter;
@@ -491,6 +545,26 @@ u16 ARM9Read16(u32 addr)
case 0x04000208: return IME[0];
}
+
+ printf("unknown arm9 IO read16 %08X\n", addr);
+ return 0;
+
+ case 0x06000000:
+ {
+ u32 chunk = (addr >> 14) & 0x7F;
+ u8* vram = NULL;
+ switch (addr & 0x00E00000)
+ {
+ case 0x00000000: vram = GPU2D::VRAM_ABG[chunk]; break;
+ case 0x00200000: vram = GPU2D::VRAM_AOBJ[chunk]; break;
+ case 0x00400000: vram = GPU2D::VRAM_BBG[chunk]; break;
+ case 0x00600000: vram = GPU2D::VRAM_BOBJ[chunk]; break;
+ case 0x00800000: vram = GPU2D::VRAM_LCD[chunk]; break;
+ }
+ if (vram)
+ return *(u16*)&vram[addr & 0x3FFF];
+ }
+ return 0;
}
printf("unknown arm9 read16 %08X\n", addr);
@@ -538,6 +612,8 @@ u32 ARM9Read32(u32 addr)
case 0x04000000:
switch (addr)
{
+ case 0x04000004: return GPU2D::DispStat[0] | (GPU2D::VCount << 16);
+
case 0x04000100: return Timers[0].Counter | (Timers[0].Control << 16);
case 0x04000104: return Timers[1].Counter | (Timers[1].Control << 16);
case 0x04000108: return Timers[2].Counter | (Timers[2].Control << 16);
@@ -547,6 +623,26 @@ u32 ARM9Read32(u32 addr)
case 0x04000210: return IE[0];
case 0x04000214: return IF[0];
}
+
+ printf("unknown arm9 IO read32 %08X | %08X %08X %08X\n", addr, ARM9->R[15], ARM9->R[12], ARM9Read32(0x027FF820));
+ return 0;
+
+ case 0x06000000:
+ {
+ u32 chunk = (addr >> 14) & 0x7F;
+ u8* vram = NULL;
+ switch (addr & 0x00E00000)
+ {
+ case 0x00000000: vram = GPU2D::VRAM_ABG[chunk]; break;
+ case 0x00200000: vram = GPU2D::VRAM_AOBJ[chunk]; break;
+ case 0x00400000: vram = GPU2D::VRAM_BBG[chunk]; break;
+ case 0x00600000: vram = GPU2D::VRAM_BOBJ[chunk]; break;
+ case 0x00800000: vram = GPU2D::VRAM_LCD[chunk]; break;
+ }
+ if (vram)
+ return *(u32*)&vram[addr & 0x3FFF];
+ }
+ return 0;
}
printf("unknown arm9 read32 %08X | %08X %08X %08X\n", addr, ARM9->R[15], ARM9->R[12], ARM9Read32(0x027FF820));
@@ -581,11 +677,21 @@ void ARM9Write8(u32 addr, u8 val)
{
case 0x04000208: IME[0] = val; return;
+ case 0x04000240: GPU2D::MapVRAM_AB(0, val); return;
+ case 0x04000241: GPU2D::MapVRAM_AB(1, val); return;
+ case 0x04000242: GPU2D::MapVRAM_CD(2, val); return;
+ case 0x04000243: GPU2D::MapVRAM_CD(3, val); return;
+ case 0x04000244: GPU2D::MapVRAM_E(4, val); return;
+ case 0x04000245: GPU2D::MapVRAM_FG(5, val); return;
+ case 0x04000246: GPU2D::MapVRAM_FG(6, val); return;
case 0x04000247:
WRAMCnt = val;
MapSharedWRAM();
return;
+ case 0x04000248: GPU2D::MapVRAM_H(7, val); return;
+ case 0x04000249: GPU2D::MapVRAM_I(8, val); return;
}
+ break;
}
printf("unknown arm9 write8 %08X %02X\n", addr, val);
@@ -617,6 +723,8 @@ void ARM9Write16(u32 addr, u16 val)
case 0x04000000:
switch (addr)
{
+ case 0x04000004: GPU2D::SetDispStat(0, val); return;
+
case 0x04000100: Timers[0].Reload = val; return;
case 0x04000102: TimerStart(0, val); return;
case 0x04000104: Timers[1].Reload = val; return;
@@ -640,6 +748,24 @@ void ARM9Write16(u32 addr, u16 val)
case 0x04000208: IME[0] = val; return;
}
+ break;
+
+ case 0x06000000:
+ {
+ u32 chunk = (addr >> 14) & 0x7F;
+ u8* vram = NULL;
+ switch (addr & 0x00E00000)
+ {
+ case 0x00000000: vram = GPU2D::VRAM_ABG[chunk]; break;
+ case 0x00200000: vram = GPU2D::VRAM_AOBJ[chunk]; break;
+ case 0x00400000: vram = GPU2D::VRAM_BBG[chunk]; break;
+ case 0x00600000: vram = GPU2D::VRAM_BOBJ[chunk]; break;
+ case 0x00800000: vram = GPU2D::VRAM_LCD[chunk]; break;
+ }
+ if (vram)
+ *(u16*)&vram[addr & 0x3FFF] = val;
+ }
+ return;
}
printf("unknown arm9 write16 %08X %04X\n", addr, val);
@@ -689,9 +815,27 @@ void ARM9Write32(u32 addr, u32 val)
return;
case 0x04000208: IME[0] = val; return;
- case 0x04000210: IE[0] = val; return;
+ case 0x04000210: IE[0] = val; printf("ARM9 IE == %08X\n", val); return;
case 0x04000214: IF[0] &= ~val; return;
}
+ break;
+
+ case 0x06000000:
+ {
+ u32 chunk = (addr >> 14) & 0x7F;
+ u8* vram = NULL;
+ switch (addr & 0x00E00000)
+ {
+ case 0x00000000: vram = GPU2D::VRAM_ABG[chunk]; break;
+ case 0x00200000: vram = GPU2D::VRAM_AOBJ[chunk]; break;
+ case 0x00400000: vram = GPU2D::VRAM_BBG[chunk]; break;
+ case 0x00600000: vram = GPU2D::VRAM_BOBJ[chunk]; break;
+ case 0x00800000: vram = GPU2D::VRAM_LCD[chunk]; break;
+ }
+ if (vram)
+ *(u32*)&vram[addr & 0x3FFF] = val;
+ }
+ return;
}
printf("unknown arm9 write32 %08X %08X | %08X\n", addr, val, ARM9->R[15]);
@@ -727,9 +871,21 @@ u8 ARM7Read8(u32 addr)
case 0x04000208: return IME[1];
- case 0x04000241:
- return WRAMCnt;
+ case 0x04000240: return GPU2D::VRAMSTAT;
+ case 0x04000241: return WRAMCnt;
}
+ printf("unknown arm7 IO read8 %08X\n", addr);
+ return 0;
+
+ case 0x06000000:
+ case 0x06800000:
+ {
+ u32 chunk = (addr >> 17) & 0x1;
+ u8* vram = GPU2D::VRAM_ARM7[chunk];
+ if (vram)
+ return *(u8*)&vram[addr & 0x3FFF];
+ }
+ return 0;
}
printf("unknown arm7 read8 %08X\n", addr);
@@ -758,6 +914,9 @@ u16 ARM7Read16(u32 addr)
case 0x04000000:
switch (addr)
{
+ case 0x04000004: return GPU2D::DispStat[1];
+ case 0x04000006: return GPU2D::VCount;
+
case 0x04000100: return Timers[4].Counter;
case 0x04000102: return Timers[4].Control;
case 0x04000104: return Timers[5].Counter;
@@ -778,6 +937,23 @@ u16 ARM7Read16(u32 addr)
case 0x04000504: return _soundbias;
}
+
+ printf("unknown arm7 IO read16 %08X %08X\n", addr, ARM7->R[15]);
+ return 0;
+
+ case 0x04800000:
+ // wifi shit
+ return 0;
+
+ case 0x06000000:
+ case 0x06800000:
+ {
+ u32 chunk = (addr >> 17) & 0x1;
+ u8* vram = GPU2D::VRAM_ARM7[chunk];
+ if (vram)
+ return *(u16*)&vram[addr & 0x3FFF];
+ }
+ return 0;
}
printf("unknown arm7 read16 %08X %08X\n", addr, ARM7->R[15]);
@@ -806,6 +982,8 @@ u32 ARM7Read32(u32 addr)
case 0x04000000:
switch (addr)
{
+ case 0x04000004: return GPU2D::DispStat[1] | (GPU2D::VCount << 16);
+
case 0x04000100: return Timers[4].Counter | (Timers[4].Control << 16);
case 0x04000104: return Timers[5].Counter | (Timers[5].Control << 16);
case 0x04000108: return Timers[6].Counter | (Timers[6].Control << 16);
@@ -821,6 +999,19 @@ u32 ARM7Read32(u32 addr)
case 0x04000210: return IE[1];
case 0x04000214: return IF[1];
}
+
+ printf("unknown arm7 IO read32 %08X | %08X\n", addr, ARM7->R[15]);
+ return 0;
+
+ case 0x06000000:
+ case 0x06800000:
+ {
+ u32 chunk = (addr >> 17) & 0x1;
+ u8* vram = GPU2D::VRAM_ARM7[chunk];
+ if (vram)
+ return *(u32*)&vram[addr & 0x3FFF];
+ }
+ return 0;
}
if ((addr&0xFF000000) == 0xEA000000) Halt();
@@ -852,8 +1043,7 @@ void ARM7Write8(u32 addr, u8 val)
return;
case 0x04000301:
- if (val != 0x80) return;
- TriggerIRQ(1, IRQ_CartSendDone); // HAAAAXX!!
+ if (val == 0x80) ARM7->Halt(1);
return;
case 0x040001C2:
@@ -862,10 +1052,22 @@ void ARM7Write8(u32 addr, u8 val)
case 0x04000208: IME[1] = val; return;
}
+ break;
+
+ case 0x06000000:
+ case 0x06800000:
+ {
+ u32 chunk = (addr >> 17) & 0x1;
+ u8* vram = GPU2D::VRAM_ARM7[chunk];
+ if (vram)
+ *(u8*)&vram[addr & 0x3FFF] = val;
+ }
+ return;
}
if (addr==0xA20)
{
+ //TriggerIRQ(1, IRQ_CartSendDone);
/*FILE* f = fopen("ram.bin", "wb");
fwrite(MainRAM, 0x400000, 1, f);
fclose(f);
@@ -900,6 +1102,8 @@ void ARM7Write16(u32 addr, u16 val)
case 0x04000000:
switch (addr)
{
+ case 0x04000004: GPU2D::SetDispStat(1, val); return;
+
case 0x04000100: Timers[4].Reload = val; return;
case 0x04000102: TimerStart(4, val); return;
case 0x04000104: Timers[5].Reload = val; return;
@@ -936,6 +1140,21 @@ void ARM7Write16(u32 addr, u16 val)
_soundbias = val & 0x3FF;
return;
}
+ break;
+
+ case 0x04800000:
+ // wifi shit
+ return;
+
+ case 0x06000000:
+ case 0x06800000:
+ {
+ u32 chunk = (addr >> 17) & 0x1;
+ u8* vram = GPU2D::VRAM_ARM7[chunk];
+ if (vram)
+ *(u16*)&vram[addr & 0x3FFF] = val;
+ }
+ return;
}
printf("unknown arm7 write16 %08X %04X | %08X\n", addr, val, ARM7->R[15]);
@@ -978,10 +1197,25 @@ void ARM7Write32(u32 addr, u32 val)
TimerStart(7, val>>16);
return;
+ case 0x040001A4:
+ if (val & 0x80000000) TriggerIRQ(1, IRQ_CartSendDone); // HAX!!!!
+ return;
+
case 0x04000208: IME[1] = val; return;
case 0x04000210: IE[1] = val; return;
- case 0x04000214: IF[1] &= ~val; printf("IRQ ack %08X\n", val);return;
+ case 0x04000214: IF[1] &= ~val; return;
}
+ return;
+
+ case 0x06000000:
+ case 0x06800000:
+ {
+ u32 chunk = (addr >> 17) & 0x1;
+ u8* vram = GPU2D::VRAM_ARM7[chunk];
+ if (vram)
+ *(u32*)&vram[addr & 0x3FFF] = val;
+ }
+ return;
}
printf("unknown arm7 write32 %08X %08X | %08X %08X\n", addr, val, ARM7->R[15], ARM7->CurInstr);
diff --git a/SPI.cpp b/SPI.cpp
index 562cf09..f8f1b6d 100644
--- a/SPI.cpp
+++ b/SPI.cpp
@@ -79,7 +79,7 @@ void Write(u8 val, u32 hold)
Data = 0;
DataPos = 1;
Addr = 0;
- printf("firmware SPI command %02X\n", CurCmd);
+ //printf("firmware SPI command %02X\n", CurCmd);
return;
}
@@ -93,7 +93,7 @@ void Write(u8 val, u32 hold)
Addr |= val;
Data = 0;
- if (DataPos == 3) printf("firmware SPI read %08X\n", Addr);
+ //if (DataPos == 3) printf("firmware SPI read %08X\n", Addr);
}
else
{
diff --git a/melonDS.depend b/melonDS.depend
index a8a280b..b317bfe 100644
--- a/melonDS.depend
+++ b/melonDS.depend
@@ -1,38 +1,39 @@
# depslib dependency file v1.0
-1480007651 source:c:\documents\sources\melonds\main.cpp
+1480957085 source:c:\documents\sources\melonds\main.cpp
<stdio.h>
"NDS.h"
-1480942921 c:\documents\sources\melonds\nds.h
+1480975422 c:\documents\sources\melonds\nds.h
"types.h"
-1463409689 c:\documents\sources\melonds\types.h
+1480957224 c:\documents\sources\melonds\types.h
-1480953322 source:c:\documents\sources\melonds\nds.cpp
+1480975347 source:c:\documents\sources\melonds\nds.cpp
<stdio.h>
<string.h>
"NDS.h"
"ARM.h"
"CP15.h"
+ "GPU2D.h"
"SPI.h"
-1480953451 source:c:\documents\sources\melonds\arm.cpp
+1480975148 source:c:\documents\sources\melonds\arm.cpp
<stdio.h>
"NDS.h"
"ARM.h"
"ARMInterpreter.h"
-1480951045 c:\documents\sources\melonds\arm.h
+1480975035 c:\documents\sources\melonds\arm.h
"types.h"
"NDS.h"
-1480954012 c:\documents\sources\melonds\arm_instrtable.h
+1480965403 c:\documents\sources\melonds\arm_instrtable.h
-1480725698 c:\documents\sources\melonds\arminterpreter.h
+1480965273 c:\documents\sources\melonds\arminterpreter.h
"types.h"
"ARM.h"
-1480952246 source:c:\documents\sources\melonds\arminterpreter.cpp
+1480975549 source:c:\documents\sources\melonds\arminterpreter.cpp
<stdio.h>
"NDS.h"
"CP15.h"
@@ -42,33 +43,42 @@
"ARMInterpreter_LoadStore.h"
"ARM_InstrTable.h"
-1480783605 c:\documents\sources\melonds\arminterpreter_branch.h
+1480957205 c:\documents\sources\melonds\arminterpreter_branch.h
-1480783825 source:c:\documents\sources\melonds\arminterpreter_branch.cpp
+1480957179 source:c:\documents\sources\melonds\arminterpreter_branch.cpp
<stdio.h>
"ARM.h"
-1480784137 c:\documents\sources\melonds\arminterpreter_alu.h
+1480965420 c:\documents\sources\melonds\arminterpreter_alu.h
-1480952092 source:c:\documents\sources\melonds\arminterpreter_alu.cpp
+1480966229 source:c:\documents\sources\melonds\arminterpreter_alu.cpp
"ARM.h"
-1480953933 c:\documents\sources\melonds\arminterpreter_loadstore.h
+1480957165 c:\documents\sources\melonds\arminterpreter_loadstore.h
-1480953916 source:c:\documents\sources\melonds\arminterpreter_loadstore.cpp
+1480972662 source:c:\documents\sources\melonds\arminterpreter_loadstore.cpp
<stdio.h>
"ARM.h"
-1480776964 c:\documents\sources\melonds\cp15.h
+1480957212 c:\documents\sources\melonds\cp15.h
-1480950166 source:c:\documents\sources\melonds\cp15.cpp
+1480975492 source:c:\documents\sources\melonds\cp15.cpp
<stdio.h>
"NDS.h"
+ "ARM.h"
-1480814622 c:\documents\sources\melonds\spi.h
+1480957111 c:\documents\sources\melonds\spi.h
-1480954747 source:c:\documents\sources\melonds\spi.cpp
+1480973443 source:c:\documents\sources\melonds\spi.cpp
<stdio.h>
"NDS.h"
"SPI.h"
+1480971901 source:c:\documents\sources\melonds\gpu2d.cpp
+ <stdio.h>
+ <string.h>
+ "NDS.h"
+ "GPU2D.h"
+
+1480970908 c:\documents\sources\melonds\gpu2d.h
+