christ. CodeBlocks is retarded.

also, lots of crap. I lost track of it.
This commit is contained in:
StapleButter 2016-12-23 21:22:22 +01:00
parent 9bb3537ede
commit af05333290
17 changed files with 598 additions and 127 deletions

41
ARM.cpp
View File

@ -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;

2
ARM.h
View File

@ -182,6 +182,8 @@ public:
u32 ExceptionBase;
static u32 ConditionTable[16];
u32 debug;
};
#endif // ARM_H

View File

@ -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);
}

View File

@ -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; \
if (s == 0) { \
cpu->SetC(x & (1<<31)); \
x = 0; \
} else { \
cpu->SetC(x & (1<<(s-1))); \
x >>= s;
x >>= s; \
}
#define ASR_IMM_S(x, s) \
if (s == 0) s = 32; \
if (s == 0) { \
cpu->SetC(x & (1<<31)); \
x = ((s32)x) >> 31; \
} else { \
cpu->SetC(x & (1<<(s-1))); \
x = ((s32)x) >> s;
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);
}

View File

@ -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);

View File

@ -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;
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);
}

View File

@ -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,

View File

@ -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;

View File

@ -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);
}

View File

@ -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();

97
NDS.cpp
View File

@ -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:

7
NDS.h
View File

@ -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);

View File

@ -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))

118
main.cpp
View File

@ -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;

View File

@ -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>

View File

@ -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"

View File

@ -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