diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 094f2f6a4..5b3625f04 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -3683,6 +3683,9 @@ void FASTCALL _MMU_ARM7_write08(u32 adr, u8 val) case REG_IF+3: REG_IF_WriteByte(3,val); break; case REG_POSTFLG: + //The NDS7 register can be written to only from code executed in BIOS. + if (NDS_ARM7.instruct_adr > 0x3FFF) return; + // hack for patched firmwares if (val == 1) { @@ -4298,7 +4301,7 @@ u8 FASTCALL _MMU_ARM7_read08(u32 adr) //How accurate is this? our R[15] may not be exactly what the hardware uses (may use something less by up to 0x08) //This may be inaccurate at the very edge cases. - if (NDS_ARM7.R[15] > 0x3FFF) + if (NDS_ARM7.instruct_adr > 0x3FFF) return 0xFF; } @@ -4363,7 +4366,7 @@ u16 FASTCALL _MMU_ARM7_read16(u32 adr) { //u32 prot = T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x04000308 & MMU.MMU_MASK[ARMCPU_ARM7][0x40]); //if (prot) INFO("MMU7 read 16 at 0x%08X (PC 0x%08X) BIOSPROT address 0x%08X\n", adr, NDS_ARM7.R[15], prot); - if (NDS_ARM7.R[15] > 0x3FFF) + if (NDS_ARM7.instruct_adr > 0x3FFF) return 0xFFFF; } @@ -4458,7 +4461,7 @@ u32 FASTCALL _MMU_ARM7_read32(u32 adr) { //u32 prot = T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x04000308 & MMU.MMU_MASK[ARMCPU_ARM7][0x40]); //if (prot) INFO("MMU7 read 32 at 0x%08X (PC 0x%08X) BIOSPROT address 0x%08X\n", adr, NDS_ARM7.R[15], prot); - if (NDS_ARM7.R[15] > 0x3FFF) + if (NDS_ARM7.instruct_adr > 0x3FFF) return 0xFFFFFFFF; } diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index 724ddd13d..33014ce74 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -2460,8 +2460,9 @@ void NDS_Reset() armcpu_init(&NDS_ARM9, firmware->ARM9bootAddr); } - _MMU_write08(0x04000300, 0); - _MMU_write08(0x04000300, 0); + // REG_POSTFLG + MMU.ARM9_REG[0x300] = 0; + MMU.ARM7_REG[0x300] = 0; } else { @@ -2488,8 +2489,9 @@ void NDS_Reset() armcpu_init(&NDS_ARM7, header->ARM7exe); armcpu_init(&NDS_ARM9, header->ARM9exe); - _MMU_write08(REG_POSTFLG, 1); - _MMU_write08(REG_POSTFLG, 1); + // REG_POSTFLG + MMU.ARM9_REG[0x300] = 1; + MMU.ARM7_REG[0x300] = 1; } // only ARM9 have co-processor reconstruct(&cp15); diff --git a/desmume/src/arm_jit.cpp b/desmume/src/arm_jit.cpp index 7d48da03d..20fce8446 100644 --- a/desmume/src/arm_jit.cpp +++ b/desmume/src/arm_jit.cpp @@ -233,29 +233,32 @@ static GPVar total_cycles; static void *op_cmp[2][2]; #define cpu (&ARMPROC) -#define bb_next_instruction (bb_adr+bb_opcodesize) -#define bb_r15 (bb_adr+2*bb_opcodesize) +#define bb_next_instruction (bb_adr+bb_opcodesize) +#define bb_r15 (bb_adr+2*bb_opcodesize) -#define cpu_ptr(x) dword_ptr(bb_cpu, offsetof(armcpu_t,x)) -#define cpu_ptr_byte(x, y) byte_ptr(bb_cpu, offsetof(armcpu_t,x)+y) -#define flags_ptr cpu_ptr_byte(CPSR.val, 3) -#define reg_ptr(x) dword_ptr(bb_cpu, offsetof(armcpu_t,R)+(4*(x))) -#define reg_pos_ptr(x) dword_ptr(bb_cpu, offsetof(armcpu_t,R)+(4*REG_POS(i,(x)))) -#define reg_pos_ptrL(x) word_ptr( bb_cpu, offsetof(armcpu_t,R)+(4*REG_POS(i,(x)))) -#define reg_pos_ptrH(x) word_ptr( bb_cpu, offsetof(armcpu_t,R)+(4*REG_POS(i,(x)))+2) -#define reg_pos_ptrB(x) byte_ptr( bb_cpu, offsetof(armcpu_t,R)+(4*REG_POS(i,(x)))) -#define reg_pos_thumb(x)dword_ptr(bb_cpu, offsetof(armcpu_t,R)+(4*((i>>x)&0x7))) -#define cp15_ptr(x) dword_ptr(bb_cp15, offsetof(armcp15_t,x)) -#define mmu_ptr(x) dword_ptr(bb_mmu, offsetof(MMU_struct,x)) -#define mmu_ptr_byte(x) byte_ptr(bb_mmu, offsetof(MMU_struct,x)) -#define _REG_NUM(i, n) ((i>>n)&0x7) +#define cpu_ptr(x) dword_ptr(bb_cpu, offsetof(armcpu_t,x)) +#define cpu_ptr_byte(x, y) byte_ptr(bb_cpu, offsetof(armcpu_t,x)+y) +#define flags_ptr cpu_ptr_byte(CPSR.val, 3) +#define reg_ptr(x) dword_ptr(bb_cpu, offsetof(armcpu_t,R)+(4*(x))) +#define reg_pos_ptr(x) dword_ptr(bb_cpu, offsetof(armcpu_t,R)+(4*REG_POS(i,(x)))) +#define reg_pos_ptrL(x) word_ptr( bb_cpu, offsetof(armcpu_t,R)+(4*REG_POS(i,(x)))) +#define reg_pos_ptrH(x) word_ptr( bb_cpu, offsetof(armcpu_t,R)+(4*REG_POS(i,(x)))+2) +#define reg_pos_ptrB(x) byte_ptr( bb_cpu, offsetof(armcpu_t,R)+(4*REG_POS(i,(x)))) +#define reg_pos_thumb(x) dword_ptr(bb_cpu, offsetof(armcpu_t,R)+(4*((i>>x)&0x7))) +#define cp15_ptr(x) dword_ptr(bb_cp15, offsetof(armcp15_t,x)) +#define mmu_ptr(x) dword_ptr(bb_mmu, offsetof(MMU_struct,x)) +#define mmu_ptr_byte(x) byte_ptr(bb_mmu, offsetof(MMU_struct,x)) +#define _REG_NUM(i, n) ((i>>n)&0x7) #ifndef ASMJIT_X64 #define r64 r32 #endif -// TODO -#define changeCPSR NDS_Reschedule +// sequencer.reschedule = true; +#define changeCPSR { \ + ECall* ctxCPSR = c.call((void*)NDS_Reschedule); \ + ctxCPSR->setPrototype(ASMJIT_CALL_CONV, FunctionBuilder0()); \ +} //----------------------------------------------------------------------------- // Shifting macros @@ -654,8 +657,6 @@ static void emit_MMU_aluMemCycles(int alu_cycles, GPVar mem_cycles, int populati return 1; #define OP_ARITHMETIC_R(arg, x86inst, symmetric, flags) \ - if(REG_POS(i,12)==15) \ - return 0; \ arg; \ if(symmetric && !rhs_is_imm) \ { \ @@ -670,7 +671,25 @@ static void emit_MMU_aluMemCycles(int alu_cycles, GPVar mem_cycles, int populati c.mov(reg_pos_ptr(12), lhs); \ } \ if(flags) \ + { \ + if(REG_POS(i,12)==15) \ + { \ + S_DST_R15; \ + c.add(total_cycles, 2); \ + return 1; \ + } \ c.call(op_cmp[PROCNUM][!symmetric])->setPrototype(ASMJIT_CALL_CONV, FunctionBuilder0()); \ + } \ + else \ + { \ + if(REG_POS(i,12)==15) \ + { \ + GPVar tmp = c.newGP(VARIABLE_TYPE_GPD); \ + c.mov(tmp, reg_ptr(15)); \ + c.mov(cpu_ptr(next_instruction), tmp); \ + c.add(total_cycles, 2); \ + } \ + } \ return 1; #define OP_ARITHMETIC_S(arg, x86inst, symmetric) \ @@ -1325,8 +1344,7 @@ static int OP_MRS_SPSR(const u32 i) c.and_(xPSR, 0xFFFFFF00); \ c.or_(xPSR, operand); \ c.mov(xPSR_mem, xPSR); \ - ECall* ctxCPSR = c.call((void*)changeCPSR); \ - ctxCPSR->setPrototype(ASMJIT_CALL_CONV, FunctionBuilder0()); \ + changeCPSR; \ c.bind(__skip); \ } \ return 1; \ @@ -1344,8 +1362,7 @@ static int OP_MRS_SPSR(const u32 i) c.and_(xPSR, 0xFFFF00FF); \ c.or_(xPSR, operand); \ c.mov(xPSR_mem, xPSR); \ - ECall* ctxCPSR = c.call((void*)changeCPSR); \ - ctxCPSR->setPrototype(ASMJIT_CALL_CONV, FunctionBuilder0()); \ + changeCPSR; \ c.bind(__skip); \ } \ return 1; \ @@ -1363,8 +1380,7 @@ static int OP_MRS_SPSR(const u32 i) c.and_(xPSR, 0xFF00FFFF); \ c.or_(xPSR, operand); \ c.mov(xPSR_mem, xPSR); \ - ECall* ctxCPSR = c.call((void*)changeCPSR); \ - ctxCPSR->setPrototype(ASMJIT_CALL_CONV, FunctionBuilder0()); \ + changeCPSR; \ c.bind(__skip); \ } \ return 1; \ @@ -1376,8 +1392,7 @@ static int OP_MRS_SPSR(const u32 i) c.and_(xPSR, 0x00FFFFFF); \ c.or_(xPSR, operand); \ c.mov(xPSR_mem, xPSR); \ - ECall* ctxCPSR = c.call((void*)changeCPSR); \ - ctxCPSR->setPrototype(ASMJIT_CALL_CONV, FunctionBuilder0()); \ + changeCPSR; \ } \ return 1; \ default: \ @@ -1425,8 +1440,7 @@ static int OP_MRS_SPSR(const u32 i) c.or_(xPSR, operand); \ c.mov(xPSR_mem, xPSR); \ c.bind(__done); \ - ECall* ctxCPSR = c.call((void*)changeCPSR); \ - ctxCPSR->setPrototype(ASMJIT_CALL_CONV, FunctionBuilder0()); \ + changeCPSR; \ return 1; static int OP_MSR_CPSR(const u32 i) { OP_MSR_(CPSR, REG_OFF, 1); } @@ -2194,7 +2208,7 @@ static int op_ldm_stm(u32 i, bool store, int dir, bool before, bool writeback) if(BIT15(i) && !store) { - op_bx(cpu_ptr(R[15]), 0, PROCNUM == ARMCPU_ARM9); + op_bx(reg_ptr(15), 0, PROCNUM == ARMCPU_ARM9); } if(writeback) @@ -3674,7 +3688,7 @@ static int OP_BLX(const u32 i) c.add(dst, (i&0x7FF) << 1); c.and_(dst, 0xFFFFFFFC); c.mov(cpu_ptr(instruct_adr), dst); - c.mov(cpu_ptr(R[14]), bb_next_instruction | 1); + c.mov(reg_ptr(14), bb_next_instruction | 1); // reset T bit c.and_(cpu_ptr_byte(CPSR, 0), ~(1<<5)); return 1; @@ -3683,16 +3697,16 @@ static int OP_BLX(const u32 i) static int OP_BL_10(const u32 i) { u32 dst = bb_r15 + (SIGNEXTEND_11(i)<<12); - c.mov(cpu_ptr(R[14]), dst); + c.mov(reg_ptr(14), dst); return 1; } static int OP_BL_11(const u32 i) { GPVar dst = c.newGP(VARIABLE_TYPE_GPD); - c.mov(dst, cpu_ptr(R[14])); + c.mov(dst, reg_ptr(14)); c.add(dst, (i&0x7FF) << 1); c.mov(cpu_ptr(instruct_adr), dst); - c.mov(cpu_ptr(R[14]), bb_next_instruction | 1); + c.mov(reg_ptr(14), bb_next_instruction | 1); return 1; } @@ -3782,7 +3796,7 @@ static u32 FASTCALL OP_DECODE() cpu->next_instruction = adr + 2; cpu->R[15] = adr + 4; u32 opcode = _MMU_read16(adr); - _armlog(adr, opcode); + _armlog(PROCNUM, adr, opcode); cycles = thumb_instructions_set[PROCNUM][opcode>>6](opcode); } else @@ -3790,7 +3804,7 @@ static u32 FASTCALL OP_DECODE() cpu->next_instruction = adr + 4; cpu->R[15] = adr + 8; u32 opcode = _MMU_read32(adr); - _armlog(adr, opcode); + _armlog(PROCNUM, adr, opcode); if(CONDITION(opcode) == 0xE || TEST_COND(CONDITION(opcode), CODE(opcode), cpu->CPSR)) cycles = arm_instructions_set[PROCNUM][INSTRUCTION_INDEX(opcode)](opcode); else @@ -3973,7 +3987,7 @@ static void emit_armop_call(u32 opcode) ctx->setReturn(bb_cycles); } -static void _armlog(u32 addr, u32 opcode) +static void _armlog(u8 proc, u32 addr, u32 opcode) { #if 0 #if 0 @@ -3989,7 +4003,7 @@ static void _armlog(u32 addr, u32 opcode) else des_arm_instructions_set[INDEX22(opcode)](addr, opcode, dasmbuf); #undef INDEX22 - fprintf(stderr, "%s %08X\t%08X \t%s\n", cpu->CPSR.bits.T?"THUMB":"ARM", addr, opcode, dasmbuf); + fprintf(stderr, "%s%c %08X\t%08X \t%s\n", cpu->CPSR.bits.T?"THUMB":"ARM", proc?'7':'9', addr, opcode, dasmbuf); #else return; #endif @@ -4021,7 +4035,7 @@ static u32 compile_basicblock() opcode = _MMU_read16(start_adr + n*2); else opcode = _MMU_read32(start_adr + n*4); - + opcodes[n++] = opcode; has_variable_cycles |= (instr_is_conditional(opcode) && instr_cycles(opcode) > 1) || instr_cycles(opcode) == 0; diff --git a/desmume/src/windows/resource.h b/desmume/src/windows/resource.h index 76c790a85..b42702fda 100644 --- a/desmume/src/windows/resource.h +++ b/desmume/src/windows/resource.h @@ -815,6 +815,7 @@ #define IDC_USENOISE 5010 #define IDC_REGION 6000 #define IDC_IOREG 6001 +#define IDC_CPU 6002 #define ID_LABEL_ZELDA_SHADOW_DEPTH_HACK 9000 #define IDC_ZELDA_SHADOW_DEPTH_HACK 9001 #define ID_LABEL_ZELDA_SHADOW_DEPTH_HACK2 9003