aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStapleButter <thetotalworm@gmail.com>2016-12-23 21:22:22 +0100
committerStapleButter <thetotalworm@gmail.com>2016-12-23 21:22:22 +0100
commitaf05333290898a4306ee4c80c5f20fccbff389f5 (patch)
tree5cd36775dc3faf1f3b4bcee23a58ad5350d87b50
parent9bb3537ede2fb1961428b7071118734eeadb656a (diff)
christ. CodeBlocks is retarded.
also, lots of crap. I lost track of it.
-rw-r--r--ARM.cpp41
-rw-r--r--ARM.h2
-rw-r--r--ARMInterpreter.cpp3
-rw-r--r--ARMInterpreter_ALU.cpp223
-rw-r--r--ARMInterpreter_ALU.h7
-rw-r--r--ARMInterpreter_LoadStore.cpp104
-rw-r--r--ARM_InstrTable.h24
-rw-r--r--CP15.cpp5
-rw-r--r--GPU2D.cpp29
-rw-r--r--GPU2D.h2
-rw-r--r--NDS.cpp97
-rw-r--r--NDS.h7
-rw-r--r--SPI.cpp1
-rw-r--r--main.cpp118
-rw-r--r--melonDS.cbp19
-rw-r--r--melonDS.depend39
-rw-r--r--types.h4
17 files changed, 598 insertions, 127 deletions
diff --git a/ARM.cpp b/ARM.cpp
index f0660ca..a7fa71c 100644
--- a/ARM.cpp
+++ b/ARM.cpp
@@ -57,6 +57,7 @@ ARM::~ARM()
void ARM::Reset()
{
Cycles = 0;
+ Halted = 0;
for (int i = 0; i < 16; i++)
R[i] = 0;
@@ -73,7 +74,10 @@ void ARM::JumpTo(u32 addr, bool restorecpsr)
{
if (restorecpsr)
{
+ //if (Num==1 && (CPSR&0x1F)==0x12)
+ // printf("return from IRQ %08X -> %08X, SP=%08X, %08X\n", R[15], addr, R[13], Read32(0x0380FF7C));
RestoreCPSR();
+
if (CPSR & 0x20) addr |= 0x1;
else addr &= ~0x1;
}
@@ -81,15 +85,15 @@ void ARM::JumpTo(u32 addr, bool restorecpsr)
if (addr & 0x1)
{
addr &= ~0x1;
- NextInstr = Read16(addr);
R[15] = addr+2;
+ NextInstr = Read16(addr);
CPSR |= 0x20;
}
else
{
addr &= ~0x3;
- NextInstr = Read32(addr);
R[15] = addr+4;
+ NextInstr = Read32(addr);
CPSR &= ~0x20;
}
}
@@ -209,6 +213,15 @@ void ARM::TriggerIRQ()
if ((CPSR & 0x80) && (!Halted))
return;
+ /*if (Num==1)
+ {
+ printf("ARM7 IRQ %08X %08X\n", R[15], R_IRQ[0]);
+ if (NDS::Timers[5].Event)
+ {
+ printf("Timer1 %d %d\n", NDS::Timers[5].Counter, NDS::Timers[5].Event->Delay);
+ }
+ }*/
+
u32 oldcpsr = CPSR;
CPSR &= ~0xFF;
CPSR |= 0xD2;
@@ -230,6 +243,8 @@ s32 ARM::Execute(s32 cycles)
}
s32 cyclesrun = 0;
+ u32 addr = R[15] - (CPSR&0x20 ? 4:8);
+ u32 cpsr = CPSR;
while (cyclesrun < cycles)
{
@@ -280,6 +295,28 @@ s32 ARM::Execute(s32 cycles)
if (NDS::IME[Num]&1)
TriggerIRQ();
}
+
+ //if (R[15]==0x2DD0)
+ // printf("-> %08X %08X\n", R[13], Read32(0x0380FF7C));
+
+ //if (R[15]==0x37FEC7A)
+ // printf("!!!!!!!! %08X %08X\n", R[14], CPSR);
+
+ //if (R[15] == 0x037FF102+4 && CPSR&0x20) printf("!!!!! %08X -> %08X, %08X -> %08X, %08X, %08X/%08X\n",
+ // addr, R[15], cpsr, CPSR, CurInstr, R_SVC[2], R_IRQ[2]);
+
+ if (addr >= 0x37FAD68 && addr < 0x37FAE40)
+ {
+ if (addr==0x037FAE2A) debug=2;
+ //printf("!!! @ %08X %08X / %08X %08X/%08X\n", addr, R[15], Read32(0x03FFFFFC), Read32(0x04000210), Read32(0x04000214));
+ }
+ else if (debug==2)// && (CPSR&0x1F)==0x12)
+ {
+ //printf("[%08X|%08X] IRQ RET VAL = %08X | %d\n", R[15], CPSR, Read32(0x0380FF7C), cyclesrun);
+ }
+
+ addr = R[15] - (CPSR&0x20 ? 4:8);
+ cpsr = CPSR;
}
return cyclesrun;
diff --git a/ARM.h b/ARM.h
index e420c59..bdac45c 100644
--- a/ARM.h
+++ b/ARM.h
@@ -182,6 +182,8 @@ public:
u32 ExceptionBase;
static u32 ConditionTable[16];
+
+ u32 debug;
};
#endif // ARM_H
diff --git a/ARMInterpreter.cpp b/ARMInterpreter.cpp
index 74e986d..e156e25 100644
--- a/ARMInterpreter.cpp
+++ b/ARMInterpreter.cpp
@@ -201,7 +201,8 @@ s32 T_SVC(ARM* cpu)
cpu->R[14] = cpu->R[15] - 2;
cpu->JumpTo(cpu->ExceptionBase + 0x08);
- //printf("ARM%d SWI %02X %08X,%08X,%08X LR=%08X\n", cpu->Num?7:9, (cpu->CurInstr & 0xFF), cpu->R[0], cpu->R[1], cpu->R[2], cpu->R[14]);
+ //printf("ARM%d SWI %02X %08X,%08X,%08X LR=%08X/%08X\n", cpu->Num?7:9, (cpu->CurInstr & 0xFF), cpu->R[0], cpu->R[1], cpu->R[2], cpu->R[14], cpu->R_SVC[1]);
+//printf("%08X\n", cpu->Read32(0x27FF814));
return C_S(2) + C_N(1);
}
diff --git a/ARMInterpreter_ALU.cpp b/ARMInterpreter_ALU.cpp
index 16e3153..d38cb94 100644
--- a/ARMInterpreter_ALU.cpp
+++ b/ARMInterpreter_ALU.cpp
@@ -16,6 +16,7 @@
with melonDS. If not, see http://www.gnu.org/licenses/.
*/
+#include <stdio.h>
#include "ARM.h"
@@ -34,12 +35,12 @@ namespace ARMInterpreter
x <<= s;
#define LSR_IMM(x, s) \
- if (s == 0) s = 32; \
- x >>= s;
+ if (s == 0) x = 0; \
+ else x >>= s;
#define ASR_IMM(x, s) \
- if (s == 0) s = 32; \
- x = ((s32)x) >> s;
+ if (s == 0) x = ((s32)x) >> 31; \
+ else x = ((s32)x) >> s;
#define ROR_IMM(x, s) \
if (s == 0) \
@@ -59,20 +60,29 @@ namespace ARMInterpreter
}
#define LSR_IMM_S(x, s) \
- if (s == 0) s = 32; \
- cpu->SetC(x & (1<<(s-1))); \
- x >>= s;
+ if (s == 0) { \
+ cpu->SetC(x & (1<<31)); \
+ x = 0; \
+ } else { \
+ cpu->SetC(x & (1<<(s-1))); \
+ x >>= s; \
+ }
#define ASR_IMM_S(x, s) \
- if (s == 0) s = 32; \
- cpu->SetC(x & (1<<(s-1))); \
- x = ((s32)x) >> s;
+ if (s == 0) { \
+ cpu->SetC(x & (1<<31)); \
+ x = ((s32)x) >> 31; \
+ } else { \
+ cpu->SetC(x & (1<<(s-1))); \
+ x = ((s32)x) >> s; \
+ }
#define ROR_IMM_S(x, s) \
if (s == 0) \
{ \
- cpu->SetC(x & 1); \
+ u32 newc = (x & 1); \
x = (x >> 1) | ((cpu->CPSR & 0x20000000) << 2); \
+ cpu->SetC(newc); \
} \
else \
{ \
@@ -81,32 +91,35 @@ namespace ARMInterpreter
}
#define LSL_REG(x, s) \
- x <<= s;
+ if (s > 31) x = 0; \
+ else x <<= s;
#define LSR_REG(x, s) \
- x >>= s;
+ if (s > 31) x = 0; \
+ else x >>= s;
#define ASR_REG(x, s) \
- x = ((s32)x) >> s;
+ if (s > 31) x = ((s32)x) >> 31; \
+ else x = ((s32)x) >> s;
#define ROR_REG(x, s) \
- x = ROR(x, s);
+ x = ROR(x, (s&0x1F));
#define LSL_REG_S(x, s) \
- if (s > 0) cpu->SetC(x & (1<<(32-s))); \
- x <<= s;
+ if (s > 31) { cpu->SetC(x & (1<<0)); x = 0; } \
+ else if (s > 0) { cpu->SetC(x & (1<<(32-s))); x <<= s; }
#define LSR_REG_S(x, s) \
- if (s > 0) cpu->SetC(x & (1<<(s-1))); \
- x >>= s;
+ if (s > 31) { cpu->SetC(x & (1<<31)); x = 0; } \
+ else if (s > 0) { cpu->SetC(x & (1<<(s-1))); x >>= s; }
#define ASR_REG_S(x, s) \
- if (s > 0) cpu->SetC(x & (1<<(s-1))); \
- x = ((s32)x) >> s;
+ if (s > 31) { cpu->SetC(x & (1<<31)); x = ((s32)x) >> 31; } \
+ else if (s > 0) { cpu->SetC(x & (1<<(s-1))); x = ((s32)x) >> s; }
#define ROR_REG_S(x, s) \
if (s > 0) cpu->SetC(x & (1<<(s-1))); \
- x = ROR(x, s);
+ x = ROR(x, (s&0x1F));
@@ -120,6 +133,7 @@ namespace ARMInterpreter
#define A_CALC_OP2_REG_SHIFT_REG(shiftop) \
u32 b = cpu->R[cpu->CurInstr&0xF]; \
+ if ((cpu->CurInstr&0xF)==15) b += 4; \
shiftop(b, cpu->R[(cpu->CurInstr>>8)&0xF]);
@@ -300,7 +314,7 @@ A_IMPLEMENT_ALU_OP(AND)
#define A_EOR(c) \
u32 a = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
- u32 res = a | b; \
+ u32 res = a ^ b; \
if (((cpu->CurInstr>>12) & 0xF) == 15) \
{ \
cpu->JumpTo(res); \
@@ -494,7 +508,7 @@ A_IMPLEMENT_ALU_OP(ADC)
u32 res = res_tmp - carry; \
cpu->SetNZCV(res & 0x80000000, \
!res, \
- CARRY_SUB(a, b) | CARRY_SUB(res_tmp, carry), \
+ CARRY_SUB(a, b) & CARRY_SUB(res_tmp, carry), \
OVERFLOW_SUB(a, b, res_tmp) | OVERFLOW_SUB(res_tmp, carry, res)); \
if (((cpu->CurInstr>>12) & 0xF) == 15) \
{ \
@@ -531,7 +545,7 @@ A_IMPLEMENT_ALU_OP(SBC)
u32 res = res_tmp - carry; \
cpu->SetNZCV(res & 0x80000000, \
!res, \
- CARRY_SUB(b, a) | CARRY_SUB(res_tmp, carry), \
+ CARRY_SUB(b, a) & CARRY_SUB(res_tmp, carry), \
OVERFLOW_SUB(b, a, res_tmp) | OVERFLOW_SUB(res_tmp, carry, res)); \
if (((cpu->CurInstr>>12) & 0xF) == 15) \
{ \
@@ -718,6 +732,163 @@ A_IMPLEMENT_ALU_OP(MVN)
+s32 A_MUL(ARM* cpu)
+{
+ u32 rm = cpu->R[cpu->CurInstr & 0xF];
+ u32 rs = cpu->R[(cpu->CurInstr >> 8) & 0xF];
+
+ u32 res = rm * rs;
+
+ cpu->R[(cpu->CurInstr >> 16) & 0xF] = res;
+ if (cpu->CurInstr & (1<<20))
+ {
+ cpu->SetNZ(res & 0x80000000,
+ !res);
+ if (cpu->Num==1) cpu->SetC(0);
+ }
+
+ u32 cycles;
+ if ((rs & 0xFFFFFF00) == 0x00000000 || (rs & 0xFFFFFF00) == 0xFFFFFF00) cycles = 1;
+ else if ((rs & 0xFFFF0000) == 0x00000000 || (rs & 0xFFFF0000) == 0xFFFF0000) cycles = 2;
+ else if ((rs & 0xFF000000) == 0x00000000 || (rs & 0xFF000000) == 0xFF000000) cycles = 3;
+ else cycles = 4;
+
+ return C_S(1) + C_I(cycles);
+}
+
+s32 A_MLA(ARM* cpu)
+{
+ u32 rm = cpu->R[cpu->CurInstr & 0xF];
+ u32 rs = cpu->R[(cpu->CurInstr >> 8) & 0xF];
+ u32 rn = cpu->R[(cpu->CurInstr >> 12) & 0xF];
+
+ u32 res = (rm * rs) + rn;
+
+ cpu->R[(cpu->CurInstr >> 16) & 0xF] = res;
+ if (cpu->CurInstr & (1<<20))
+ {
+ cpu->SetNZ(res & 0x80000000,
+ !res);
+ if (cpu->Num==1) cpu->SetC(0);
+ }
+
+ u32 cycles;
+ if ((rs & 0xFFFFFF00) == 0x00000000 || (rs & 0xFFFFFF00) == 0xFFFFFF00) cycles = 2;
+ else if ((rs & 0xFFFF0000) == 0x00000000 || (rs & 0xFFFF0000) == 0xFFFF0000) cycles = 3;
+ else if ((rs & 0xFF000000) == 0x00000000 || (rs & 0xFF000000) == 0xFF000000) cycles = 4;
+ else cycles = 5;
+
+ return C_S(1) + C_I(cycles);
+}
+
+s32 A_UMULL(ARM* cpu)
+{
+ u32 rm = cpu->R[cpu->CurInstr & 0xF];
+ u32 rs = cpu->R[(cpu->CurInstr >> 8) & 0xF];
+
+ u64 res = (u64)rm * (u64)rs;
+
+ cpu->R[(cpu->CurInstr >> 12) & 0xF] = (u32)res;
+ cpu->R[(cpu->CurInstr >> 16) & 0xF] = (u32)(res >> 32ULL);
+ if (cpu->CurInstr & (1<<20))
+ {
+ cpu->SetNZ((u32)(res >> 63ULL),
+ !res);
+ if (cpu->Num==1) cpu->SetC(0);
+ }
+
+ u32 cycles;
+ if ((rs & 0xFFFFFF00) == 0x00000000) cycles = 2;
+ else if ((rs & 0xFFFF0000) == 0x00000000) cycles = 3;
+ else if ((rs & 0xFF000000) == 0x00000000) cycles = 4;
+ else cycles = 5;
+
+ return C_S(1) + C_I(cycles);
+}
+
+s32 A_UMLAL(ARM* cpu)
+{
+ u32 rm = cpu->R[cpu->CurInstr & 0xF];
+ u32 rs = cpu->R[(cpu->CurInstr >> 8) & 0xF];
+
+ u64 res = (u64)rm * (u64)rs;
+
+ u64 rd = (u64)cpu->R[(cpu->CurInstr >> 12) & 0xF] | ((u64)cpu->R[(cpu->CurInstr >> 16) & 0xF] << 32ULL);
+ res += rd;
+
+ cpu->R[(cpu->CurInstr >> 12) & 0xF] = (u32)res;
+ cpu->R[(cpu->CurInstr >> 16) & 0xF] = (u32)(res >> 32ULL);
+ if (cpu->CurInstr & (1<<20))
+ {
+ cpu->SetNZ((u32)(res >> 63ULL),
+ !res);
+ if (cpu->Num==1) cpu->SetC(0);
+ }
+
+ u32 cycles;
+ if ((rs & 0xFFFFFF00) == 0x00000000) cycles = 2;
+ else if ((rs & 0xFFFF0000) == 0x00000000) cycles = 3;
+ else if ((rs & 0xFF000000) == 0x00000000) cycles = 4;
+ else cycles = 5;
+
+ return C_S(1) + C_I(cycles);
+}
+
+s32 A_SMULL(ARM* cpu)
+{
+ u32 rm = cpu->R[cpu->CurInstr & 0xF];
+ u32 rs = cpu->R[(cpu->CurInstr >> 8) & 0xF];
+
+ s64 res = (s64)(s32)rm * (s64)(s32)rs;
+
+ cpu->R[(cpu->CurInstr >> 12) & 0xF] = (u32)res;
+ cpu->R[(cpu->CurInstr >> 16) & 0xF] = (u32)(res >> 32ULL);
+ if (cpu->CurInstr & (1<<20))
+ {
+ cpu->SetNZ((u32)(res >> 63ULL),
+ !res);
+ if (cpu->Num==1) cpu->SetC(0);
+ }
+
+ u32 cycles;
+ if ((rs & 0xFFFFFF00) == 0x00000000 || (rs & 0xFFFFFF00) == 0xFFFFFF00) cycles = 2;
+ else if ((rs & 0xFFFF0000) == 0x00000000 || (rs & 0xFFFF0000) == 0xFFFF0000) cycles = 3;
+ else if ((rs & 0xFF000000) == 0x00000000 || (rs & 0xFF000000) == 0xFF000000) cycles = 4;
+ else cycles = 5;
+
+ return C_S(1) + C_I(cycles);
+}
+
+s32 A_SMLAL(ARM* cpu)
+{
+ u32 rm = cpu->R[cpu->CurInstr & 0xF];
+ u32 rs = cpu->R[(cpu->CurInstr >> 8) & 0xF];
+
+ s64 res = (s64)(s32)rm * (s64)(s32)rs;
+
+ s64 rd = (s64)((u64)cpu->R[(cpu->CurInstr >> 12) & 0xF] | ((u64)cpu->R[(cpu->CurInstr >> 16) & 0xF] << 32ULL));
+ res += rd;
+
+ cpu->R[(cpu->CurInstr >> 12) & 0xF] = (u32)res;
+ cpu->R[(cpu->CurInstr >> 16) & 0xF] = (u32)(res >> 32ULL);
+ if (cpu->CurInstr & (1<<20))
+ {
+ cpu->SetNZ((u32)(res >> 63ULL),
+ !res);
+ if (cpu->Num==1) cpu->SetC(0);
+ }
+
+ u32 cycles;
+ if ((rs & 0xFFFFFF00) == 0x00000000 || (rs & 0xFFFFFF00) == 0xFFFFFF00) cycles = 2;
+ else if ((rs & 0xFFFF0000) == 0x00000000 || (rs & 0xFFFF0000) == 0xFFFF0000) cycles = 3;
+ else if ((rs & 0xFF000000) == 0x00000000 || (rs & 0xFF000000) == 0xFF000000) cycles = 4;
+ else cycles = 5;
+
+ return C_S(1) + C_I(cycles);
+}
+
+
+
s32 A_CLZ(ARM* cpu)
{
// TODO: ARM9 only
@@ -962,7 +1133,7 @@ s32 T_SBC_REG(ARM* cpu)
cpu->R[cpu->CurInstr & 0x7] = res;
cpu->SetNZCV(res & 0x80000000,
!res,
- CARRY_SUB(a, b) | CARRY_SUB(res_tmp, carry),
+ CARRY_SUB(a, b) & CARRY_SUB(res_tmp, carry),
OVERFLOW_SUB(a, b, res_tmp) | OVERFLOW_SUB(res_tmp, carry, res));
return C_S(1);
}
diff --git a/ARMInterpreter_ALU.h b/ARMInterpreter_ALU.h
index 610ffed..224de04 100644
--- a/ARMInterpreter_ALU.h
+++ b/ARMInterpreter_ALU.h
@@ -72,6 +72,13 @@ A_PROTO_ALU_OP(MOV)
A_PROTO_ALU_OP(BIC)
A_PROTO_ALU_OP(MVN)
+s32 A_MUL(ARM* cpu);
+s32 A_MLA(ARM* cpu);
+s32 A_UMULL(ARM* cpu);
+s32 A_UMLAL(ARM* cpu);
+s32 A_SMULL(ARM* cpu);
+s32 A_SMLAL(ARM* cpu);
+
s32 A_CLZ(ARM* cpu);
diff --git a/ARMInterpreter_LoadStore.cpp b/ARMInterpreter_LoadStore.cpp
index 2106adc..ab0a96c 100644
--- a/ARMInterpreter_LoadStore.cpp
+++ b/ARMInterpreter_LoadStore.cpp
@@ -29,12 +29,12 @@ namespace ARMInterpreter
x <<= s;
#define LSR_IMM(x, s) \
- if (s == 0) s = 32; \
- x >>= s;
+ if (s == 0) x = 0; \
+ else x >>= s;
#define ASR_IMM(x, s) \
- if (s == 0) s = 32; \
- x = ((s32)x) >> s;
+ if (s == 0) x = ((s32)x) >> 31; \
+ else x = ((s32)x) >> s;
#define ROR_IMM(x, s) \
if (s == 0) \
@@ -121,6 +121,7 @@ namespace ARMInterpreter
u32 val = cpu->Read8(offset); \
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
cpu->R[(cpu->CurInstr>>12) & 0xF] = val; \
+ if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRB PC %08X\n", cpu->R[15]); \
return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, offset);
#define A_LDRB_POST \
@@ -128,6 +129,7 @@ namespace ARMInterpreter
u32 val = cpu->Read8(addr, cpu->CurInstr & (1<<21)); \
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
cpu->R[(cpu->CurInstr>>12) & 0xF] = val; \
+ if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRB PC %08X\n", cpu->R[15]); \
return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, addr);
@@ -223,7 +225,7 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
return C_N(2) + cpu->MemWaitstate(2, addr);
-// TODO: CHECK LDRD/STRD TIMINGS!!
+// TODO: CHECK LDRD/STRD TIMINGS!! also, ARM9-only
#define A_LDRD \
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
@@ -259,38 +261,44 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
#define A_LDRH \
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
- cpu->R[(cpu->CurInstr>>12) & 0xF] = cpu->Read16(offset); \
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
+ cpu->R[(cpu->CurInstr>>12) & 0xF] = cpu->Read16(offset); \
+ if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRH PC %08X\n", cpu->R[15]); \
return C_N(2) + cpu->MemWaitstate(2, offset);
#define A_LDRH_POST \
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
- cpu->R[(cpu->CurInstr>>12) & 0xF] = cpu->Read16(addr); \
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
+ cpu->R[(cpu->CurInstr>>12) & 0xF] = cpu->Read16(addr); \
+ if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRH PC %08X\n", cpu->R[15]); \
return C_N(2) + cpu->MemWaitstate(2, addr);
#define A_LDRSB \
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
- cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s8)cpu->Read8(offset); \
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
+ cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s8)cpu->Read8(offset); \
+ if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRSB PC %08X\n", cpu->R[15]); \
return C_N(2) + cpu->MemWaitstate(3, offset);
#define A_LDRSB_POST \
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
- cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s8)cpu->Read8(addr); \
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
+ cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s8)cpu->Read8(addr); \
+ if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRSB PC %08X\n", cpu->R[15]); \
return C_N(2) + cpu->MemWaitstate(3, addr);
#define A_LDRSH \
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
- cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s16)cpu->Read16(offset); \
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
+ cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s16)cpu->Read16(offset); \
+ if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRSH PC %08X\n", cpu->R[15]); \
return C_N(2) + cpu->MemWaitstate(2, offset);
#define A_LDRSH_POST \
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
- cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s16)cpu->Read16(addr); \
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
+ cpu->R[(cpu->CurInstr>>12) & 0xF] = (s32)(s16)cpu->Read16(addr); \
+ if (((cpu->CurInstr>>12) & 0xF) == 15) printf("!! LDRSH PC %08X\n", cpu->R[15]); \
return C_N(2) + cpu->MemWaitstate(2, addr);
@@ -331,11 +339,12 @@ A_IMPLEMENT_HD_LDRSTR(LDRSH)
s32 A_SWP(ARM* cpu)
{
u32 base = cpu->R[(cpu->CurInstr >> 16) & 0xF];
+ u32 rm = cpu->R[cpu->CurInstr & 0xF];
u32 val = cpu->Read32(base);
cpu->R[(cpu->CurInstr >> 12) & 0xF] = ROR(val, 8*(base&0x3));
- cpu->Write32(base, cpu->R[cpu->CurInstr & 0xF]);
+ cpu->Write32(base, rm);
// the 1S is a code cycle. TODO
return C_S(1) + C_N(2) + C_I(1) + 2*cpu->MemWaitstate(3, base);
@@ -344,10 +353,11 @@ s32 A_SWP(ARM* cpu)
s32 A_SWPB(ARM* cpu)
{
u32 base = cpu->R[(cpu->CurInstr >> 16) & 0xF];
+ u32 rm = cpu->R[cpu->CurInstr & 0xF] & 0xFF;
cpu->R[(cpu->CurInstr >> 12) & 0xF] = cpu->Read8(base);
- cpu->Write8(base, cpu->R[cpu->CurInstr & 0xF]);
+ cpu->Write8(base, rm);
// the 1S is a code cycle. TODO
return C_S(1) + C_N(2) + C_I(1) + 2*cpu->MemWaitstate(3, base);
@@ -357,7 +367,9 @@ s32 A_SWPB(ARM* cpu)
s32 A_LDM(ARM* cpu)
{
- u32 base = cpu->R[(cpu->CurInstr >> 16) & 0xF];
+ u32 baseid = (cpu->CurInstr >> 16) & 0xF;
+ u32 base = cpu->R[baseid];
+ u32 wbbase;
u32 preinc = (cpu->CurInstr & (1<<24));
if (!(cpu->CurInstr & (1<<23)))
@@ -371,18 +383,7 @@ s32 A_LDM(ARM* cpu)
if (cpu->CurInstr & (1<<21))
{
// 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;
+ wbbase = base;
}
preinc = !preinc;
@@ -420,21 +421,23 @@ s32 A_LDM(ARM* cpu)
if ((cpu->CurInstr & (1<<22)) && !(cpu->CurInstr & (1<<15)))
cpu->UpdateMode((cpu->CPSR&~0x1F)|0x10, cpu->CPSR);
- if ((cpu->CurInstr & (1<<23)) && (cpu->CurInstr & (1<<21)))
+ if (cpu->CurInstr & (1<<21))
{
// post writeback
- u32 rb = (cpu->CurInstr >> 16) & 0xF;
- if (cpu->CurInstr & (1 << rb))
+ if (cpu->CurInstr & (1<<23))
+ wbbase = base;
+
+ if (cpu->CurInstr & (1 << baseid))
{
if (cpu->Num == 0)
{
u32 rlist = cpu->CurInstr & 0xFFFF;
- if ((!(rlist & ~(1 << rb))) || (rlist & ~((2 << rb) - 1)))
- cpu->R[rb] = base;
+ if ((!(rlist & ~(1 << baseid))) || (rlist & ~((2 << baseid) - 1)))
+ cpu->R[baseid] = wbbase;
}
}
else
- cpu->R[rb] = base;
+ cpu->R[baseid] = wbbase;
}
return cycles;
@@ -442,7 +445,9 @@ s32 A_LDM(ARM* cpu)
s32 A_STM(ARM* cpu)
{
- u32 base = cpu->R[(cpu->CurInstr >> 16) & 0xF];
+ u32 baseid = (cpu->CurInstr >> 16) & 0xF;
+ u32 base = cpu->R[baseid];
+ u32 oldbase = base;
u32 preinc = (cpu->CurInstr & (1<<24));
if (!(cpu->CurInstr & (1<<23)))
@@ -454,11 +459,7 @@ s32 A_STM(ARM* cpu)
}
if (cpu->CurInstr & (1<<21))
- {
- cpu->R[(cpu->CurInstr >> 16) & 0xF] = base;
- if (cpu->CurInstr & (1 << ((cpu->CurInstr >> 16) & 0xF)))
- printf("!! BAD STM\n");
- }
+ cpu->R[baseid] = base;
preinc = !preinc;
}
@@ -473,7 +474,17 @@ s32 A_STM(ARM* cpu)
if (cpu->CurInstr & (1<<i))
{
if (preinc) base += 4;
- cpu->Write32(base, cpu->R[i]);
+
+ if (i == baseid)
+ {
+ if ((cpu->Num == 0) || (!(cpu->CurInstr & (i-1))))
+ cpu->Write32(base, oldbase);
+ else
+ cpu->Write32(base, base); // checkme
+ }
+ else
+ cpu->Write32(base, cpu->R[i]);
+
cycles += C_S(1) + cpu->MemWaitstate(3, base);
if (!preinc) base += 4;
}
@@ -483,11 +494,7 @@ s32 A_STM(ARM* cpu)
cpu->UpdateMode((cpu->CPSR&~0x1F)|0x10, cpu->CPSR);
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 STM\n");
- }
+ cpu->R[baseid] = base;
return cycles;
}
@@ -501,7 +508,7 @@ s32 A_STM(ARM* cpu)
s32 T_LDR_PCREL(ARM* cpu)
{
- u32 addr = cpu->R[15] + ((cpu->CurInstr & 0xFF) << 2);
+ u32 addr = (cpu->R[15] & ~0x2) + ((cpu->CurInstr & 0xFF) << 2);
cpu->R[(cpu->CurInstr >> 8) & 0x7] = cpu->Read32(addr);
return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, addr);
@@ -527,7 +534,9 @@ s32 T_STRB_REG(ARM* cpu)
s32 T_LDR_REG(ARM* cpu)
{
u32 addr = cpu->R[(cpu->CurInstr >> 3) & 0x7] + cpu->R[(cpu->CurInstr >> 6) & 0x7];
- cpu->R[cpu->CurInstr & 0x7] = cpu->Read32(addr);
+
+ u32 val = cpu->Read32(addr);
+ cpu->R[cpu->CurInstr & 0x7] = ROR(val, 8*(addr&0x3));
return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, addr);
}
@@ -588,7 +597,8 @@ s32 T_LDR_IMM(ARM* cpu)
u32 offset = (cpu->CurInstr >> 4) & 0x7C;
offset += cpu->R[(cpu->CurInstr >> 3) & 0x7];
- cpu->R[cpu->CurInstr & 0x7] = cpu->Read32(offset);
+ u32 val = cpu->Read32(offset);
+ cpu->R[cpu->CurInstr & 0x7] = ROR(val, 8*(offset&0x3));
return C_S(1) + C_N(1) + C_I(1) + cpu->MemWaitstate(3, offset);
}
diff --git a/ARM_InstrTable.h b/ARM_InstrTable.h
index 351f40b..03bbe29 100644
--- a/ARM_InstrTable.h
+++ b/ARM_InstrTable.h
@@ -21,25 +21,25 @@ INSTRFUNC_PROTO(ARMInstrTable[4096]) =
// 0000 0000 0000
A_AND_REG_LSL_IMM, A_AND_REG_LSL_REG, A_AND_REG_LSR_IMM, A_AND_REG_LSR_REG,
A_AND_REG_ASR_IMM, A_AND_REG_ASR_REG, A_AND_REG_ROR_IMM, A_AND_REG_ROR_REG,
- A_AND_REG_LSL_IMM, A_UNK, A_AND_REG_LSR_IMM, A_STRH_POST_REG,
+ A_AND_REG_LSL_IMM, A_MUL, A_AND_REG_LSR_IMM, A_STRH_POST_REG,
A_AND_REG_ASR_IMM, A_LDRD_POST_REG, A_AND_REG_ROR_IMM, A_STRD_POST_REG,
// 0000 0001 0000
A_AND_REG_LSL_IMM_S, A_AND_REG_LSL_REG_S, A_AND_REG_LSR_IMM_S, A_AND_REG_LSR_REG_S,
A_AND_REG_ASR_IMM_S, A_AND_REG_ASR_REG_S, A_AND_REG_ROR_IMM_S, A_AND_REG_ROR_REG_S,
- A_AND_REG_LSL_IMM_S, A_UNK, A_AND_REG_LSR_IMM_S, A_LDRH_POST_REG,
+ A_AND_REG_LSL_IMM_S, A_MUL, A_AND_REG_LSR_IMM_S, A_LDRH_POST_REG,
A_AND_REG_ASR_IMM_S, A_LDRSB_POST_REG, A_AND_REG_ROR_IMM_S, A_LDRSH_POST_REG,
// 0000 0010 0000
A_EOR_REG_LSL_IMM, A_EOR_REG_LSL_REG, A_EOR_REG_LSR_IMM, A_EOR_REG_LSR_REG,
A_EOR_REG_ASR_IMM, A_EOR_REG_ASR_REG, A_EOR_REG_ROR_IMM, A_EOR_REG_ROR_REG,
- A_EOR_REG_LSL_IMM, A_UNK, A_EOR_REG_LSR_IMM, A_UNK,
+ A_EOR_REG_LSL_IMM, A_MLA, A_EOR_REG_LSR_IMM, A_UNK,
A_EOR_REG_ASR_IMM, A_UNK, A_EOR_REG_ROR_IMM, A_UNK,
// 0000 0011 0000
A_EOR_REG_LSL_IMM_S, A_EOR_REG_LSL_REG_S, A_EOR_REG_LSR_IMM_S, A_EOR_REG_LSR_REG_S,
A_EOR_REG_ASR_IMM_S, A_EOR_REG_ASR_REG_S, A_EOR_REG_ROR_IMM_S, A_EOR_REG_ROR_REG_S,
- A_EOR_REG_LSL_IMM_S, A_UNK, A_EOR_REG_ROR_IMM_S, A_UNK,
+ A_EOR_REG_LSL_IMM_S, A_MLA, A_EOR_REG_ROR_IMM_S, A_UNK,
A_EOR_REG_ASR_IMM_S, A_UNK, A_EOR_REG_ROR_IMM_S, A_UNK,
// 0000 0100 0000
@@ -69,49 +69,49 @@ INSTRFUNC_PROTO(ARMInstrTable[4096]) =
// 0000 1000 0000
A_ADD_REG_LSL_IMM, A_ADD_REG_LSL_REG, A_ADD_REG_LSR_IMM, A_ADD_REG_LSR_REG,
A_ADD_REG_ASR_IMM, A_ADD_REG_ASR_REG, A_ADD_REG_ROR_IMM, A_ADD_REG_ROR_REG,
- A_ADD_REG_LSL_IMM, A_UNK, A_ADD_REG_LSR_IMM, A_STRH_POST_REG,
+ A_ADD_REG_LSL_IMM, A_UMULL, A_ADD_REG_LSR_IMM, A_STRH_POST_REG,
A_ADD_REG_ASR_IMM, A_LDRD_POST_REG, A_ADD_REG_ROR_IMM, A_STRD_POST_REG,
// 0000 1001 0000
A_ADD_REG_LSL_IMM_S, A_ADD_REG_LSL_REG_S, A_ADD_REG_LSR_IMM_S, A_ADD_REG_LSR_REG_S,
A_ADD_REG_ASR_IMM_S, A_ADD_REG_ASR_REG_S, A_ADD_REG_ROR_IMM_S, A_ADD_REG_ROR_REG_S,
- A_UNK, A_UNK, A_UNK, A_LDRH_POST_REG,
+ A_UNK, A_UMULL, A_UNK, A_LDRH_POST_REG,
A_UNK, A_LDRSB_POST_REG, A_UNK, A_LDRSH_POST_REG,
// 0000 1010 0000
A_ADC_REG_LSL_IMM, A_ADC_REG_LSL_REG, A_ADC_REG_LSR_IMM, A_ADC_REG_LSR_REG,
A_ADC_REG_ASR_IMM, A_ADC_REG_ASR_REG, A_ADC_REG_ROR_IMM, A_ADC_REG_ROR_REG,
- A_ADC_REG_LSL_IMM, A_UNK, A_ADC_REG_LSR_IMM, A_UNK,
+ A_ADC_REG_LSL_IMM, A_UMLAL, A_ADC_REG_LSR_IMM, A_UNK,
A_ADC_REG_ASR_IMM, A_UNK, A_ADC_REG_ROR_IMM, A_UNK,
// 0000 1011 0000
A_ADC_REG_LSL_IMM_S, A_ADC_REG_LSL_REG_S, A_ADC_REG_LSR_IMM_S, A_ADC_REG_LSR_REG_S,
A_ADC_REG_ASR_IMM_S, A_ADC_REG_ASR_REG_S, A_ADC_REG_ROR_IMM_S, A_ADC_REG_ROR_REG_S,
- A_ADC_REG_LSL_IMM_S, A_UNK, A_ADC_REG_LSR_IMM_S, A_UNK,
+ A_ADC_REG_LSL_IMM_S, A_UMLAL, A_ADC_REG_LSR_IMM_S, A_UNK,
A_ADC_REG_ASR_IMM_S, A_UNK, A_ADC_REG_ROR_IMM_S, A_UNK,
// 0000 1100 0000
A_SBC_REG_LSL_IMM, A_SBC_REG_LSL_REG, A_SBC_REG_LSR_IMM, A_SBC_REG_LSR_REG,
A_SBC_REG_ASR_IMM, A_SBC_REG_ASR_REG, A_SBC_REG_ROR_IMM, A_SBC_REG_ROR_REG,
- A_SBC_REG_LSL_IMM, A_UNK, A_SBC_REG_LSR_IMM, A_STRH_POST_IMM,
+ A_SBC_REG_LSL_IMM, A_SMULL, A_SBC_REG_LSR_IMM, A_STRH_POST_IMM,
A_SBC_REG_ASR_IMM, A_LDRD_POST_IMM, A_SBC_REG_ROR_IMM, A_STRD_POST_IMM,
// 0000 1101 0000
A_SBC_REG_LSL_IMM_S, A_SBC_REG_LSL_REG_S, A_SBC_REG_LSR_IMM_S, A_SBC_REG_LSR_REG_S,
A_SBC_REG_ASR_IMM_S, A_SBC_REG_ASR_REG_S, A_SBC_REG_ROR_IMM_S, A_SBC_REG_ROR_REG_S,
- A_SBC_REG_LSL_IMM_S, A_UNK, A_SBC_REG_LSR_IMM_S, A_LDRH_POST_IMM,
+ A_SBC_REG_LSL_IMM_S, A_SMULL, A_SBC_REG_LSR_IMM_S, A_LDRH_POST_IMM,
A_SBC_REG_ASR_IMM_S, A_LDRSB_POST_IMM, A_SBC_REG_ROR_IMM_S, A_LDRSH_POST_IMM,
// 0000 1110 0000
A_RSC_REG_LSL_IMM, A_RSC_REG_LSL_REG, A_RSC_REG_LSR_IMM, A_RSC_REG_LSR_REG,
A_RSC_REG_ASR_IMM, A_RSC_REG_ASR_REG, A_RSC_REG_ROR_IMM, A_RSC_REG_ROR_REG,
- A_RSC_REG_LSL_IMM, A_UNK, A_RSC_REG_LSR_IMM, A_UNK,
+ A_RSC_REG_LSL_IMM, A_SMLAL, A_RSC_REG_LSR_IMM, A_UNK,
A_RSC_REG_ASR_IMM, A_UNK, A_RSC_REG_ROR_IMM, A_UNK,
// 0000 1111 0000
A_RSC_REG_LSL_IMM_S, A_RSC_REG_LSL_REG_S, A_RSC_REG_LSR_IMM_S, A_RSC_REG_LSR_REG_S,
A_RSC_REG_ASR_IMM_S, A_RSC_REG_ASR_REG_S, A_RSC_REG_ROR_IMM_S, A_RSC_REG_ROR_REG_S,
- A_RSC_REG_LSL_IMM_S, A_UNK, A_RSC_REG_LSR_IMM_S, A_UNK,
+ A_RSC_REG_LSL_IMM_S, A_SMLAL, A_RSC_REG_LSR_IMM_S, A_UNK,
A_RSC_REG_ASR_IMM_S, A_UNK, A_RSC_REG_ROR_IMM_S, A_UNK,
diff --git a/CP15.cpp b/CP15.cpp
index c7fd3c2..72c1924 100644
--- a/CP15.cpp
+++ b/CP15.cpp
@@ -42,10 +42,6 @@ void Reset()
DTCMSetting = 0;
ITCMSetting = 0;
- //DTCMSetting = 0x0300000A;
- //ITCMSetting = 0x00000020;
- //UpdateDTCMSetting();
- //UpdateITCMSetting();
}
@@ -94,6 +90,7 @@ void Write(u32 id, u32 val)
case 0x704:
+ case 0x782:
NDS::ARM9->Halt(1);
return;
diff --git a/GPU2D.cpp b/GPU2D.cpp
index e759afb..bd85ed7 100644
--- a/GPU2D.cpp
+++ b/GPU2D.cpp
@@ -56,6 +56,8 @@ u8* VRAM_BOBJ[128];
u8* VRAM_LCD[128];
u8* VRAM_ARM7[2];
+u16 Framebuffer[256*192*2];
+
void Reset()
{
@@ -88,6 +90,11 @@ void Reset()
memset(VRAM_BOBJ, 0, sizeof(u8*)*128);
memset(VRAM_LCD, 0, sizeof(u8*)*128);
memset(VRAM_ARM7, 0, sizeof(u8*)*2);
+
+ for (int i = 0; i < 256*192*2; i++)
+ {
+ Framebuffer[i] = (i>=256*192)?0x03E0:0x7C00;
+ }
}
@@ -657,6 +664,24 @@ void MapVRAM_I(u32 bank, u8 cnt)
}
+void DrawScanline(u32 screen, u32 line)
+{
+ u16* dst = &Framebuffer[256 * ((192*screen) + line)];
+
+ if (screen==0)
+ {
+ u16* src = &((u16*)VRAM_A)[256*line];
+ for (int i = 0; i < 256; i++)
+ dst[i] = src[i];
+ }
+ else
+ {
+ for (int i = 0; i < 256; i++)
+ dst[i] = 0x7FFF;
+ }
+}
+
+
void StartFrame()
{
StartScanline(0);
@@ -686,7 +711,9 @@ void StartScanline(u32 line)
if (line < 192)
{
- // TODO: draw shit
+ // draw
+ DrawScanline(0, line);
+ DrawScanline(1, line);
NDS::ScheduleEvent(LINE_CYCLES, StartScanline, line+1);
}
diff --git a/GPU2D.h b/GPU2D.h
index 66b2252..006bc64 100644
--- a/GPU2D.h
+++ b/GPU2D.h
@@ -39,6 +39,8 @@ extern u8* VRAM_BOBJ[128];
extern u8* VRAM_LCD[128];
extern u8* VRAM_ARM7[2];
+extern u16 Framebuffer[256*192*2];
+
void Reset();
diff --git a/NDS.cpp b/NDS.cpp
index 8bb2522..ef84573 100644
--- a/NDS.cpp
+++ b/NDS.cpp
@@ -77,6 +77,8 @@ u8 ROMCommand[8];
u8 ROMCurCommand[8];
u32 ROMReadPos, ROMReadSize;
+u32 KeyInput;
+
u16 _soundbias; // temp
bool Running;
@@ -120,11 +122,15 @@ void LoadROM()
{
u32 tmp;
fread(&tmp, 4, 1, f);
- ARM9Write32(bootparams[6]+i, tmp);
+ ARM7Write32(bootparams[6]+i, tmp);
}
fclose(f);
+ CP15::Write(0x910, 0x0300000A);
+ CP15::Write(0x911, 0x00000020);
+ CP15::Write(0x100, 0x00050000);
+
ARM9->JumpTo(bootparams[1]);
ARM7->JumpTo(bootparams[5]);
}
@@ -188,8 +194,8 @@ void Reset()
memset(Timers, 0, 8*sizeof(Timer));
+ GPU2D::Reset();
SPI::Reset();
-
Wifi::Reset();
memset(SchedBuffer, 0, sizeof(SchedEvent)*SCHED_BUF_LEN);
@@ -199,6 +205,8 @@ void Reset()
ARM7Cycles = 0;
SchedCycles = 0;
+ KeyInput = 0x007F03FF;
+
_soundbias = 0;
// test
@@ -365,6 +373,17 @@ void CompensateARM7()
}
+void PressKey(u32 key)
+{
+ KeyInput &= ~(1 << key);
+}
+
+void ReleaseKey(u32 key)
+{
+ KeyInput |= (1 << key);
+}
+
+
void Halt()
{
printf("Halt()\n");
@@ -412,7 +431,7 @@ void MapSharedWRAM(u8 val)
void TriggerIRQ(u32 cpu, u32 irq)
{
irq = 1 << irq;
- if (!(IE[cpu] & irq)) return;
+ //if (!(IE[cpu] & irq)) return;
IF[cpu] |= irq;
@@ -457,7 +476,10 @@ void TimerIncrement(u32 param)
timer->Counter = timer->Reload;
if (timer->Control & (1<<6))
+ {
TriggerIRQ(cpu, IRQ_Timer0 + tid);
+ //if (cpu==1) printf("Timer%d IRQ %04X\n", tid, timer->Control);
+ }
// cascade
if (tid == 3)
@@ -483,16 +505,15 @@ void TimerStart(u32 id, u16 cnt)
if ((!curstart) && newstart)
{
+ timer->Counter = timer->Reload;
+
// start the timer, if it's not a cascading timer
if (!(cnt & (1<<2)))
- {
- timer->Counter = timer->Reload;
timer->Event = ScheduleEvent(TimerPrescaler[cnt&0x3], TimerIncrement, id);
- }
else
timer->Event = NULL;
}
- else if (curstart && !newstart)
+ else if (curstart && (!newstart))
{
if (timer->Event)
CancelEvent(timer->Event);
@@ -693,6 +714,8 @@ u16 ARM9Read16(u32 addr)
case 0x0400010C: return Timers[3].Counter;
case 0x0400010E: return Timers[3].Control;
+ case 0x04000130: return KeyInput & 0xFFFF;
+
case 0x04000180: return IPCSync9;
case 0x04000204: return 0;//0xFFFF;
@@ -849,7 +872,7 @@ void ARM9Write8(u32 addr, u8 val)
ROMSPIControl |= (val << 8);
return;
- case 0x04000208: IME[0] = val; return;
+ case 0x04000208: IME[0] = val & 0x1; return;
case 0x04000240: GPU2D::MapVRAM_AB(0, val); return;
case 0x04000241: GPU2D::MapVRAM_AB(1, val); return;
@@ -926,7 +949,7 @@ void ARM9Write16(u32 addr, u16 val)
ROMSPIControl = val;
return;
- case 0x04000208: IME[0] = val; return;
+ case 0x04000208: IME[0] = val & 0x1; return;
case 0x04000240:
GPU2D::MapVRAM_AB(0, val & 0xFF);
@@ -950,6 +973,8 @@ void ARM9Write16(u32 addr, u16 val)
return;
case 0x04000304: PowerControl9 = val; return;
+
+ //case 0x04001036: ARM7->debug=2; break;
}
break;
@@ -1035,8 +1060,25 @@ void ARM9Write32(u32 addr, u32 val)
if (val & 0x80000000) ROMStartTransfer(0);
return;
- case 0x04000208: IME[0] = val; return;
- case 0x04000210: IE[0] = val; return;
+ case 0x04000208: IME[0] = val & 0x1; return;
+ case 0x04000210: IE[0] = val; printf("%08X %08X %08X\n", ARM7->R[15], WRAMCnt, ARM7->CPSR);
+ /*{
+ FILE* f;
+ f = fopen("ARM7FIRM.bin", "wb");
+ for (u32 i = 0; i < 0x18000; i+=4)
+ {
+ u32 tmp = ARM7Read32(0x37F8000+i);
+ fwrite(&tmp, 4, 1, f);
+ }
+ fclose(f);
+ f = fopen("ARM9FIRM.bin", "wb");
+ for (u32 i = 0; i < 0x400000; i+=4)
+ {
+ u32 tmp = ARM9Read32(0x2000000+i);
+ fwrite(&tmp, 4, 1, f);
+ }
+ fclose(f);
+ }*/return;
case 0x04000214: IF[0] &= ~val; return;
case 0x04000240:
@@ -1093,6 +1135,7 @@ u8 ARM7Read8(u32 addr)
{
if (addr < 0x00004000)
{
+ if (ARM7->R[15] > 0x4000) printf("BAD BIOS READ8 %08X FROM %08X\n", addr, ARM7->R[15]);
return *(u8*)&ARM7BIOS[addr];
}
@@ -1146,6 +1189,7 @@ u16 ARM7Read16(u32 addr)
{
if (addr < 0x00004000)
{
+ if (ARM7->R[15] > 0x4000) printf("BAD BIOS READ16 %08X FROM %08X\n", addr, ARM7->R[15]);
return *(u16*)&ARM7BIOS[addr];
}
@@ -1176,6 +1220,9 @@ u16 ARM7Read16(u32 addr)
case 0x0400010C: return Timers[7].Counter;
case 0x0400010E: return Timers[7].Control;
+ case 0x04000130: return KeyInput & 0xFFFF;
+ case 0x04000136: return KeyInput >> 16;
+
case 0x04000134: return 0x8000;
case 0x04000138: return 0; // RTC shit
@@ -1216,6 +1263,8 @@ u32 ARM7Read32(u32 addr)
{
if (addr < 0x00004000)
{
+ if (ARM7->R[15] > 0x4000) {printf("BAD BIOS READ32 %08X FROM %08X | %08X\n", addr, ARM7->R[15], ARM7Read32(0x0380776C+12));return 0xFFFFFFFF;}
+ if (addr < 0x1204 && ARM7->R[15] >= 0x1204) printf("BAD BIOS READ32 %08X FROM %08X\n", addr, ARM7->R[15]);
return *(u32*)&ARM7BIOS[addr];
}
@@ -1274,6 +1323,7 @@ u32 ARM7Read32(u32 addr)
void ARM7Write8(u32 addr, u8 val)
{
+ if (addr==0x3807764) printf("DERP! %02X %08X\n", val, ARM7->R[15]);
switch (addr & 0xFF800000)
{
case 0x02000000:
@@ -1317,7 +1367,7 @@ void ARM7Write8(u32 addr, u8 val)
SPI::WriteData(val);
return;
- case 0x04000208: IME[1] = val; return;
+ case 0x04000208: IME[1] = val & 0x1; return;
case 0x04000301:
if (val == 0x80) ARM7->Halt(1);
@@ -1355,6 +1405,7 @@ void ARM7Write8(u32 addr, u8 val)
void ARM7Write16(u32 addr, u16 val)
{
+ if (addr==0x3807764) printf("DERP! %04X %08X\n", val, ARM7->R[15]);
switch (addr & 0xFF800000)
{
case 0x02000000:
@@ -1377,13 +1428,23 @@ void ARM7Write16(u32 addr, u16 val)
case 0x04000100: Timers[4].Reload = val; return;
case 0x04000102: TimerStart(4, val); return;
- case 0x04000104: Timers[5].Reload = val; return;
- case 0x04000106: TimerStart(5, val); return;
+ case 0x04000104: Timers[5].Reload = val;
+ Timers[5].Reload = 0xFFE0;
+ // hax.
+ // firmware bootloader sets it to 0xFFFE, which doesn't give it enough time to do its IRQ handling shit before getting another IRQ
+ //printf("TIMER RELOAD=%04X FROM %08X, %08X %08X\n", val, ARM7->R[15], ARM7->R[4], ARM7->CPSR);
+ return;
+ case 0x04000106: TimerStart(5, val); /*printf("TIMER CNT=%04X FROM %08X | %08X%08X - %08X%08X | %04X %04X %04X\n",
+ val, ARM7->R[15],
+ ARM7Read32(ARM7->R[4]+0x10), ARM7Read32(ARM7->R[4]+0xC), ARM7->R[1], ARM7->R[0],
+ Timers[4].Control, Timers[4].Counter, Timers[4].Reload);*/return;
case 0x04000108: Timers[6].Reload = val; return;
case 0x0400010A: TimerStart(6, val); return;
case 0x0400010C: Timers[7].Reload = val; return;
case 0x0400010E: TimerStart(7, val); return;
+ case 0x04000134: return;printf("set debug port %04X %08X\n", val, ARM7Read32(ARM7->R[13]+4)); return;
+
case 0x04000138: return; // RTC shit
case 0x04000180:
@@ -1409,7 +1470,7 @@ void ARM7Write16(u32 addr, u16 val)
SPI::WriteData(val & 0xFF);
return;
- case 0x04000208: IME[1] = val; return;
+ case 0x04000208: IME[1] = val & 0x1; return;
case 0x04000304: PowerControl7 = val; return;
@@ -1439,6 +1500,8 @@ void ARM7Write16(u32 addr, u16 val)
void ARM7Write32(u32 addr, u32 val)
{
+ if (addr==0x27FF890) printf("HAHA! %08X\n", val);
+ if (addr==0x3807764) printf("DERP! %08X %08X\n", val, ARM7->R[15]);
switch (addr & 0xFF800000)
{
case 0x02000000:
@@ -1484,11 +1547,11 @@ void ARM7Write32(u32 addr, u32 val)
if (val & 0x80000000) ROMStartTransfer(1);
return;
- case 0x04000208: IME[1] = val; return;
+ case 0x04000208: IME[1] = val & 0x1; return;
case 0x04000210: IE[1] = val; return;
case 0x04000214: IF[1] &= ~val; return;
}
- return;
+ break;
case 0x06000000:
case 0x06800000:
diff --git a/NDS.h b/NDS.h
index 8be3c24..4559795 100644
--- a/NDS.h
+++ b/NDS.h
@@ -73,7 +73,11 @@ typedef struct
SchedEvent* Event;
} Timer;
+
+// hax
extern u32 IME[2];
+extern Timer Timers[8];
+
extern u32 ARM9ITCMSize;
extern u32 ARM9DTCMBase, ARM9DTCMSize;
@@ -82,6 +86,9 @@ void Reset();
void RunFrame();
+void PressKey(u32 key);
+void ReleaseKey(u32 key);
+
SchedEvent* ScheduleEvent(s32 Delay, void (*Func)(u32), u32 Param);
void CancelEvent(SchedEvent* event);
void RunEvents(s32 cycles);
diff --git a/SPI.cpp b/SPI.cpp
index f8f1b6d..c9847b7 100644
--- a/SPI.cpp
+++ b/SPI.cpp
@@ -197,6 +197,7 @@ void WriteData(u8 val)
switch (CNT & 0x0300)
{
case 0x0100: SPI_Firmware::Write(val, CNT&(1<<11)); break;
+ default: printf("SPI to unknown device %04X %02X\n", CNT, val); break;
}
if (CNT & (1<<14))
diff --git a/main.cpp b/main.cpp
index 725ad65..5ccf6c1 100644
--- a/main.cpp
+++ b/main.cpp
@@ -17,7 +17,59 @@
*/
#include <stdio.h>
+#include <windows.h>
#include "NDS.h"
+#include "GPU2D.h"
+
+
+HINSTANCE instance;
+HWND melon;
+BITMAPV4HEADER bmp;
+bool quit;
+
+
+LRESULT CALLBACK derpo(HWND window, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ switch (msg)
+ {
+ case WM_CLOSE:
+ printf("close\n");
+ PostQuitMessage(0);
+ return 0;
+
+ case WM_KEYDOWN:
+ switch (wparam)
+ {
+ case VK_RETURN: NDS::PressKey(3); break;
+ case VK_SPACE: NDS::PressKey(2); break;
+ case VK_UP: NDS::PressKey(6); break;
+ case VK_DOWN: NDS::PressKey(7); break;
+ case VK_LEFT: NDS::PressKey(5); break;
+ case VK_RIGHT: NDS::PressKey(4); break;
+ }
+ return 0;
+
+ case WM_KEYUP:
+ switch (wparam)
+ {
+ case VK_RETURN: NDS::ReleaseKey(3); break;
+ case VK_SPACE: NDS::ReleaseKey(2); break;
+ case VK_UP: NDS::ReleaseKey(6); break;
+ case VK_DOWN: NDS::ReleaseKey(7); break;
+ case VK_LEFT: NDS::ReleaseKey(5); break;
+ case VK_RIGHT: NDS::ReleaseKey(4); break;
+ }
+ return 0;
+
+ /*case WM_PAINT:
+ {
+
+ }
+ return 0;*/
+ }
+
+ return DefWindowProc(window, msg, wparam, lparam);
+}
int main()
@@ -25,12 +77,78 @@ int main()
printf("melonDS version uh... 0.1??\n");
printf("it's a DS emulator!!!\n");
printf("http://melonds.kuribo64.net/\n");
+ quit = false;
+
+ instance = GetModuleHandle(NULL);
+
+ // god this shit sucks
+ WNDCLASSEX shit;
+ shit.cbSize = sizeof(shit);
+ shit.style = CS_HREDRAW | CS_VREDRAW;
+ shit.lpfnWndProc = derpo;
+ shit.cbClsExtra = 0;
+ shit.cbWndExtra = 0;
+ shit.hInstance = instance;
+ shit.hIcon = NULL;
+ shit.hIconSm = NULL;
+ shit.hCursor = NULL;
+ shit.hbrBackground = (HBRUSH)(COLOR_WINDOWFRAME+1);
+ shit.lpszMenuName = NULL;
+ shit.lpszClassName = "v0ltmeters";
+ RegisterClassEx(&shit);
+
+ RECT rekt;
+ rekt.left = 0; rekt.top = 0;
+ rekt.right = 256; rekt.bottom = 384;
+ AdjustWindowRect(&rekt, WS_OVERLAPPEDWINDOW, FALSE);
+
+ melon = CreateWindow("v0ltmeters",
+ "melonDS",
+ WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ rekt.right-rekt.left, rekt.bottom-rekt.top,
+ NULL,
+ NULL,
+ instance,
+ NULL);
+
+ ShowWindow(melon, SW_SHOW);
+
+ // more sucky shit!
+ memset(&bmp, 0, sizeof(bmp));
+ bmp.bV4Size = sizeof(bmp);
+ bmp.bV4Width = 256;
+ bmp.bV4Height = -384;
+ bmp.bV4Planes = 1;
+ bmp.bV4BitCount = 16;
+ bmp.bV4V4Compression = BI_RGB|BI_BITFIELDS;
+ bmp.bV4RedMask = 0x001F;
+ bmp.bV4GreenMask = 0x03E0;
+ bmp.bV4BlueMask = 0x7C00;
NDS::Init();
for (;;)
{
+ MSG msg;
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ if (msg.message == WM_QUIT)
+ {
+ quit = true;
+ break;
+ }
+
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ if (quit) break;
+
NDS::RunFrame();
+
+ HDC dc = GetDC(melon);
+ SetDIBitsToDevice(dc, 0, 0, 256, 384, 0, 0, 0, 384, GPU2D::Framebuffer, (BITMAPINFO*)&bmp, DIB_RGB_COLORS);
+ UpdateWindow(melon);
}
return 0;
diff --git a/melonDS.cbp b/melonDS.cbp
index 76310dc..4859fc6 100644
--- a/melonDS.cbp
+++ b/melonDS.cbp
@@ -32,8 +32,27 @@
<Add option="-Wall" />
<Add option="-fexceptions" />
</Compiler>
+ <Unit filename="ARM.cpp" />
+ <Unit filename="ARM.h" />
+ <Unit filename="ARMInterpreter.cpp" />
+ <Unit filename="ARMInterpreter.h" />
+ <Unit filename="ARMInterpreter_ALU.cpp" />
+ <Unit filename="ARMInterpreter_ALU.h" />
+ <Unit filename="ARMInterpreter_Branch.cpp" />
+ <Unit filename="ARMInterpreter_Branch.h" />
+ <Unit filename="ARMInterpreter_LoadStore.cpp" />
+ <Unit filename="ARMInterpreter_LoadStore.h" />
+ <Unit filename="ARM_InstrTable.h" />
+ <Unit filename="CP15.cpp" />
+ <Unit filename="CP15.h" />
+ <Unit filename="GPU2D.cpp" />
+ <Unit filename="GPU2D.h" />
<Unit filename="NDS.cpp" />
<Unit filename="NDS.h" />
+ <Unit filename="SPI.cpp" />
+ <Unit filename="SPI.h" />
+ <Unit filename="Wifi.cpp" />
+ <Unit filename="Wifi.h" />
<Unit filename="main.cpp" />
<Unit filename="types.h" />
<Extensions>
diff --git a/melonDS.depend b/melonDS.depend
index 8171ff3..1238366 100644
--- a/melonDS.depend
+++ b/melonDS.depend
@@ -1,14 +1,16 @@
# depslib dependency file v1.0
-1480957085 source:c:\documents\sources\melonds\main.cpp
+1481167563 source:c:\documents\sources\melonds\main.cpp
<stdio.h>
+ <windows.h>
"NDS.h"
+ "GPU2D.h"
-1480989459 c:\documents\sources\melonds\nds.h
+1481167101 c:\documents\sources\melonds\nds.h
"types.h"
-1480957224 c:\documents\sources\melonds\types.h
+1481161027 c:\documents\sources\melonds\types.h
-1481040741 source:c:\documents\sources\melonds\nds.cpp
+1481230323 source:c:\documents\sources\melonds\nds.cpp
<stdio.h>
<string.h>
"NDS.h"
@@ -18,23 +20,23 @@
"SPI.h"
"Wifi.h"
-1480989161 source:c:\documents\sources\melonds\arm.cpp
+1481167780 source:c:\documents\sources\melonds\arm.cpp
<stdio.h>
"NDS.h"
"ARM.h"
"ARMInterpreter.h"
-1480975035 c:\documents\sources\melonds\arm.h
+1481062839 c:\documents\sources\melonds\arm.h
"types.h"
"NDS.h"
-1480965403 c:\documents\sources\melonds\arm_instrtable.h
+1481160977 c:\documents\sources\melonds\arm_instrtable.h
1480965273 c:\documents\sources\melonds\arminterpreter.h
"types.h"
"ARM.h"
-1481038843 source:c:\documents\sources\melonds\arminterpreter.cpp
+1481124482 source:c:\documents\sources\melonds\arminterpreter.cpp
<stdio.h>
"NDS.h"
"CP15.h"
@@ -50,20 +52,21 @@
<stdio.h>
"ARM.h"
-1480965420 c:\documents\sources\melonds\arminterpreter_alu.h
+1481160920 c:\documents\sources\melonds\arminterpreter_alu.h
-1480966229 source:c:\documents\sources\melonds\arminterpreter_alu.cpp
+1481202027 source:c:\documents\sources\melonds\arminterpreter_alu.cpp
+ <stdio.h>
"ARM.h"
1480957165 c:\documents\sources\melonds\arminterpreter_loadstore.h
-1480972662 source:c:\documents\sources\melonds\arminterpreter_loadstore.cpp
+1481203284 source:c:\documents\sources\melonds\arminterpreter_loadstore.cpp
<stdio.h>
"ARM.h"
1481037554 c:\documents\sources\melonds\cp15.h
-1481037609 source:c:\documents\sources\melonds\cp15.cpp
+1481159008 source:c:\documents\sources\melonds\cp15.cpp
<stdio.h>
"NDS.h"
"ARM.h"
@@ -71,18 +74,24 @@
1480957111 c:\documents\sources\melonds\spi.h
-1481038838 source:c:\documents\sources\melonds\spi.cpp
+1481058591 source:c:\documents\sources\melonds\spi.cpp
<stdio.h>
"NDS.h"
"SPI.h"
-1481033110 source:c:\documents\sources\melonds\gpu2d.cpp
+1481167730 source:c:\documents\sources\melonds\gpu2d.cpp
<stdio.h>
<string.h>
"NDS.h"
"GPU2D.h"
-1480986603 c:\documents\sources\melonds\gpu2d.h
+1481164639 c:\documents\sources\melonds\gpu2d.h
1481040524 c:\documents\sources\melonds\wifi.h
+1481041659 source:c:\documents\sources\melonds\wifi.cpp
+ <stdio.h>
+ <string.h>
+ "NDS.h"
+ "Wifi.h"
+
diff --git a/types.h b/types.h
index ad69d9c..8a6c7e3 100644
--- a/types.h
+++ b/types.h
@@ -22,10 +22,10 @@
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
-typedef unsigned long int u64;
+typedef unsigned long long int u64;
typedef signed char s8;
typedef signed short s16;
typedef signed int s32;
-typedef signed long int s64;
+typedef signed long long int s64;
#endif // TYPES_H