diff options
author | StapleButter <thetotalworm@gmail.com> | 2016-12-23 21:22:22 +0100 |
---|---|---|
committer | StapleButter <thetotalworm@gmail.com> | 2016-12-23 21:22:22 +0100 |
commit | af05333290898a4306ee4c80c5f20fccbff389f5 (patch) | |
tree | 5cd36775dc3faf1f3b4bcee23a58ad5350d87b50 | |
parent | 9bb3537ede2fb1961428b7071118734eeadb656a (diff) |
christ. CodeBlocks is retarded.
also, lots of crap. I lost track of it.
-rw-r--r-- | ARM.cpp | 41 | ||||
-rw-r--r-- | ARM.h | 2 | ||||
-rw-r--r-- | ARMInterpreter.cpp | 3 | ||||
-rw-r--r-- | ARMInterpreter_ALU.cpp | 223 | ||||
-rw-r--r-- | ARMInterpreter_ALU.h | 7 | ||||
-rw-r--r-- | ARMInterpreter_LoadStore.cpp | 104 | ||||
-rw-r--r-- | ARM_InstrTable.h | 24 | ||||
-rw-r--r-- | CP15.cpp | 5 | ||||
-rw-r--r-- | GPU2D.cpp | 29 | ||||
-rw-r--r-- | GPU2D.h | 2 | ||||
-rw-r--r-- | NDS.cpp | 97 | ||||
-rw-r--r-- | NDS.h | 7 | ||||
-rw-r--r-- | SPI.cpp | 1 | ||||
-rw-r--r-- | main.cpp | 118 | ||||
-rw-r--r-- | melonDS.cbp | 19 | ||||
-rw-r--r-- | melonDS.depend | 39 | ||||
-rw-r--r-- | types.h | 4 |
17 files changed, 598 insertions, 127 deletions
@@ -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; @@ -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, @@ -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; @@ -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); } @@ -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(); @@ -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: @@ -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); @@ -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)) @@ -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" + @@ -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 |