diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index ac21d5540..759a51d58 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2006 yopyop - Copyright (C) 2008-2016 DeSmuME team + Copyright (C) 2008-2017 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1492,13 +1492,20 @@ static void execHardware_hstart() } else if (nds.VCount == 262) { - if (!(NDS_ARM9.waitIRQ) && nds.overclock < 200 && CommonSettings.pokehax) + if (!NDS_ARM9.freeze && nds.overclock < 2 && CommonSettings.pokehax) { + //suspend arm7 during overclocking so much doesn't run out of control + //actually, this isn't needed yet. + //NDS_ARM7.freeze |= CPU_FREEZE_OVERCLOCK_HACK; + nds.overclock++; nds.VCount = 261; } else { + //overclock arm7 lock is always released here; if it wasn't actiev, this benign + NDS_ARM7.freeze &= ~CPU_FREEZE_OVERCLOCK_HACK; + //when the vcount hits 262, vblank ends (oam pre-renders by one scanline) execHardware_hstart_vblankEnd(); } @@ -1829,7 +1836,7 @@ static /*donotinline*/ std::pair armInnerLoop( { if(doarm9 && (!doarm7 || arm9 <= timer)) { - if(!NDS_ARM9.waitIRQ&&!nds.freezeBus) + if(!(NDS_ARM9.freeze & CPU_FREEZE_WAIT_IRQ) && !nds.freezeBus) { arm9log(); debug(); @@ -1852,7 +1859,8 @@ static /*donotinline*/ std::pair armInnerLoop( } if(doarm7 && (!doarm9 || arm7 <= timer)) { - if(!NDS_ARM7.waitIRQ&&!nds.freezeBus) + bool cpufreeze = !!(NDS_ARM7.freeze & (CPU_FREEZE_WAIT_IRQ|CPU_FREEZE_OVERCLOCK_HACK)); + if(!cpufreeze && !nds.freezeBus) { arm7log(); #ifdef HAVE_JIT @@ -2022,12 +2030,12 @@ void NDS_exec(s32 nb) //if we were waiting for an irq, don't wait too long: //let's re-analyze it after this hardware event (this rolls back a big burst of irq waiting which may have been interrupted by a resynch) - if(NDS_ARM9.waitIRQ) + if(NDS_ARM9.freeze & CPU_FREEZE_WAIT_IRQ) { nds.idleCycles[0] -= (s32)(nds_arm9_timer-nds_timer); nds_arm9_timer = nds_timer; } - if(NDS_ARM7.waitIRQ) + if(NDS_ARM7.freeze & CPU_FREEZE_WAIT_IRQ) { nds.idleCycles[1] -= (s32)(nds_arm7_timer-nds_timer); nds_arm7_timer = nds_timer; @@ -2063,10 +2071,9 @@ template static void execHardware_interrupts_core() u32 IF = MMU.gen_IF(); u32 IE = MMU.reg_IE[PROCNUM]; u32 masked = IF & IE; - if(ARMPROC.halt_IE_and_IF && masked) + if((ARMPROC.freeze & CPU_FREEZE_IRQ_IE_IF) && masked) { - ARMPROC.halt_IE_and_IF = FALSE; - ARMPROC.waitIRQ = FALSE; + ARMPROC.freeze &= ~CPU_FREEZE_IRQ_IE_IF; } if(masked && MMU.reg_IME[PROCNUM] && !ARMPROC.CPSR.bits.I) diff --git a/desmume/src/arm_jit.cpp b/desmume/src/arm_jit.cpp index 9797a813f..a9418e690 100644 --- a/desmume/src/arm_jit.cpp +++ b/desmume/src/arm_jit.cpp @@ -1,6 +1,7 @@ -/* Copyright (C) 2006 yopyop +/* + Copyright (C) 2006 yopyop Copyright (C) 2011 Loren Merritt - Copyright (C) 2012-2016 DeSmuME team + Copyright (C) 2012-2017 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2658,8 +2659,7 @@ static int OP_MCR(const u32 i) if((CRm==0)&&(opcode1==0)&&((opcode2==4))) { //CP15wait4IRQ; - c.mov(cpu_ptr(waitIRQ), true); - c.mov(cpu_ptr(halt_IE_and_IF), true); + c.mov(cpu_ptr(freeze), CPU_FREEZE_IRQ_IE_IF); //IME set deliberately omitted: only SWI sets IME to 1 break; } diff --git a/desmume/src/armcpu.cpp b/desmume/src/armcpu.cpp index 6b793330b..38d93b502 100644 --- a/desmume/src/armcpu.cpp +++ b/desmume/src/armcpu.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2006 yopyop - Copyright (C) 2009-2016 DeSmuME team + Copyright (C) 2009-2017 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -234,8 +234,7 @@ void armcpu_init(armcpu_t *armcpu, u32 adr) armcpu->LDTBit = (armcpu->proc_ID==0); //set ARMv5 style bit--different for each processor armcpu->intVector = 0xFFFF0000 * (armcpu->proc_ID==0); - armcpu->waitIRQ = FALSE; - armcpu->halt_IE_and_IF = FALSE; + armcpu->freeze = CPU_FREEZE_NONE; armcpu->intrWaitARM_state = 0; //#ifdef GDB_STUB @@ -383,8 +382,7 @@ u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode) u32 armcpu_Wait4IRQ(armcpu_t *cpu) { - cpu->waitIRQ = TRUE; - cpu->halt_IE_and_IF = TRUE; + cpu->freeze = (CPU_FREEZE_WAIT_IRQ | CPU_FREEZE_IE_IF); return 1; } @@ -544,7 +542,7 @@ BOOL armcpu_irqException(armcpu_t *armcpu) armcpu->CPSR.bits.T = 0; armcpu->CPSR.bits.I = 1; armcpu->next_instruction = armcpu->intVector + 0x18; - armcpu->waitIRQ = 0; + armcpu->freeze &= ~CPU_FREEZE_IRQ_IE_IF; //must retain invariant of having next instruction to be executed prefetched //(yucky) diff --git a/desmume/src/armcpu.h b/desmume/src/armcpu.h index 8c9ee0989..597b0840a 100644 --- a/desmume/src/armcpu.h +++ b/desmume/src/armcpu.h @@ -1,6 +1,6 @@ /* Copyright (C) 2006 yopyop - Copyright (C) 2006-2016 DeSmuME team + Copyright (C) 2006-2017 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -41,6 +41,13 @@ #define EXCEPTION_IRQ 0x18 #define EXCEPTION_FAST_IRQ 0x1C + +#define CPU_FREEZE_NONE 0x00 +#define CPU_FREEZE_WAIT_IRQ 0x01 //waiting for some IRQ to happen, any IRQ +#define CPU_FREEZE_IE_IF 0x02 //waiting for IE&IF to signal something (probably edge triggered on IRQ too) +#define CPU_FREEZE_IRQ_IE_IF (CPU_FREEZE_WAIT_IRQ|CPU_FREEZE_IE_IF) +#define CPU_FREEZE_OVERCLOCK_HACK 0x04 + #define INSTRUCTION_INDEX(i) ((((i)>>16)&0xFF0)|(((i)>>4)&0xF)) inline u32 ROR(u32 i, u32 j) { return ((((u32)(i))>>(j)) | (((u32)(i))<<(32-(j)))); } @@ -287,8 +294,11 @@ struct armcpu_t u32 intVector; u8 LDTBit; //1 : ARMv5 style 0 : non ARMv5 (earlier) - BOOL waitIRQ; - BOOL halt_IE_and_IF; //the cpu is halted, waiting for IE&IF to signal something + + u32 freeze; + //BOOL waitIRQ; + //BOOL halt_IE_and_IF; + u8 intrWaitARM_state; BOOL BIOS_loaded; diff --git a/desmume/src/bios.cpp b/desmume/src/bios.cpp index e52186e28..c64629c81 100644 --- a/desmume/src/bios.cpp +++ b/desmume/src/bios.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2006 yopyop - Copyright (C) 2008-2016 DeSmuME team + Copyright (C) 2008-2017 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -230,8 +230,7 @@ TEMPLATE static u32 WaitByLoop() TEMPLATE static u32 wait4IRQ() { - cpu->waitIRQ = TRUE; - cpu->halt_IE_and_IF = TRUE; + cpu->freeze = CPU_FREEZE_IRQ_IE_IF; return 1; } @@ -278,8 +277,7 @@ TEMPLATE static u32 intrWaitARM() //the condition wasn't satisfied. this means that we need to halt, wait for some enabled interrupt, //and then ensure that we return to this opcode again to check the condition again - cpu->waitIRQ = TRUE; - cpu->halt_IE_and_IF = TRUE; + cpu->freeze = CPU_FREEZE_IRQ_IE_IF; //(rewire PC to jump back to this opcode) u32 instructAddr = cpu->instruct_adr; diff --git a/desmume/src/cp15.cpp b/desmume/src/cp15.cpp index d77de27ad..55ffaaaf8 100644 --- a/desmume/src/cp15.cpp +++ b/desmume/src/cp15.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2006 yopyop - Copyright (C) 2006-2016 DeSmuME team + Copyright (C) 2006-2017 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -410,8 +410,7 @@ BOOL armcp15_t::moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) if((CRm==0)&&(opcode1==0)&&((opcode2==4))) { //CP15wait4IRQ; - NDS_ARM9.waitIRQ = TRUE; - NDS_ARM9.halt_IE_and_IF = TRUE; + NDS_ARM9.freeze = CPU_FREEZE_IRQ_IE_IF; //IME set deliberately omitted: only SWI sets IME to 1 return TRUE; } diff --git a/desmume/src/frontend/windows/main.cpp b/desmume/src/frontend/windows/main.cpp index 88350fd5d..985609f3d 100644 --- a/desmume/src/frontend/windows/main.cpp +++ b/desmume/src/frontend/windows/main.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2006 Theo Berkau - Copyright (C) 2006-2016 DeSmuME team + Copyright (C) 2006-2017 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/desmume/src/saves.cpp b/desmume/src/saves.cpp index ddb08be76..4333b002f 100644 --- a/desmume/src/saves.cpp +++ b/desmume/src/saves.cpp @@ -2,7 +2,7 @@ Copyright (C) 2006 Normmatt Copyright (C) 2006 Theo Berkau Copyright (C) 2007 Pascal Giard - Copyright (C) 2008-2016 DeSmuME team + Copyright (C) 2008-2017 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -121,8 +121,7 @@ SFORMAT SF_ARM7[]={ { "7FIQ", 4, 1, &NDS_ARM7.SPSR_fiq }, { "7int", 4, 1, &NDS_ARM7.intVector }, { "7LDT", 1, 1, &NDS_ARM7.LDTBit }, - { "7Wai", 4, 1, &NDS_ARM7.waitIRQ }, - { "7hef", 4, 1, &NDS_ARM7.halt_IE_and_IF }, + { "7FRZ", 4, 1, &NDS_ARM7.freeze }, { "7iws", 1, 1, &NDS_ARM7.intrWaitARM_state }, { 0 } }; @@ -158,8 +157,7 @@ SFORMAT SF_ARM9[]={ { "9FIQ", 4, 1, &NDS_ARM9.SPSR_fiq}, { "9int", 4, 1, &NDS_ARM9.intVector}, { "9LDT", 1, 1, &NDS_ARM9.LDTBit}, - { "9Wai", 4, 1, &NDS_ARM9.waitIRQ}, - { "9hef", 4, 1, &NDS_ARM9.halt_IE_and_IF }, + { "9FRZ", 4, 1, &NDS_ARM9.freeze}, { "9iws", 1, 1, &NDS_ARM9.intrWaitARM_state }, { 0 } };