From b1db5d20809991c343849b9e2ecdbc1f8f6a3aca Mon Sep 17 00:00:00 2001 From: mtabachenko Date: Sun, 4 Jul 2010 15:19:16 +0000 Subject: [PATCH] core: - fix IRQ handler for ARM7 when use external SWI (big speedup); --- desmume/src/MMU.cpp | 9 +-- desmume/src/armcpu.cpp | 139 +++++++++++++++++++++++++---------------- desmume/src/armcpu.h | 1 + 3 files changed, 91 insertions(+), 58 deletions(-) diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 9b135ef74..29c2b3645 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -1074,7 +1074,7 @@ static void execdiv() { } // TODO: -// NAND flash support (used in Made in Ore/WariWare D.I.Y.) +// NAND flash support (used in Made in Ore/WarioWare D.I.Y.) template void FASTCALL MMU_writeToGCControl(u32 val) { @@ -1146,7 +1146,9 @@ void FASTCALL MMU_writeToGCControl(u32 val) case 0x85: { card.address = 0; - card.transfer_count = 0x80; + //card.transfer_count = 0x80; + // needs for WarioWare D.I.Y - ingame saves don't work but game don't freeze in main menu + card.transfer_count = 0; } break; @@ -3657,8 +3659,7 @@ void FASTCALL _MMU_ARM7_write08(u32 adr, u8 val) switch(val) { case 0xC0: NDS_Sleep(); break; - // TODO: its break firmware booting? but BIG speedup with ext. SWI - //case 0x80: NDS_ARM7.waitIRQ = 1; break; + case 0x80: armcpu_Wait4IRQ(&NDS_ARM7); break; default: break; } break; diff --git a/desmume/src/armcpu.cpp b/desmume/src/armcpu.cpp index 14771ba99..9b17389fb 100644 --- a/desmume/src/armcpu.cpp +++ b/desmume/src/armcpu.cpp @@ -371,6 +371,35 @@ u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode) return oldmode; } +u32 armcpu_Wait4IRQ(armcpu_t *cpu) +{ + u32 instructAddr = cpu->instruct_adr; + // on the first call, wirq is not set + if(cpu->wirq) + { + // check wether an irq was issued + if(!cpu->waitIRQ) + { + cpu->waitIRQ = 0; + cpu->wirq = 0; + return 1; // return execution + } + // otherwise, repeat this instruction + cpu->R[15] = instructAddr; + cpu->next_instruction = instructAddr; + return 1; + } + + // first run, set us into waiting state + cpu->waitIRQ = 1; + cpu->wirq = 1; + // and set next instruction to repeat this + cpu->R[15] = instructAddr; + cpu->next_instruction = instructAddr; + // only SWI set IME to 1 + return 1; +} + template FORCEINLINE static u32 armcpu_prefetch() { @@ -554,7 +583,8 @@ BOOL armcpu_irqException(armcpu_t *armcpu) u32 TRAPUNDEF(armcpu_t* cpu) { - LOG("Undefined instruction: %#08X PC = %#08X \n", cpu->instruction, cpu->instruct_adr); + INFO("ARM%c: Undefined instruction: 0x%08X (%s) PC=0x%08X\n", cpu->proc_ID?'7':'9', cpu->instruction, decodeIntruction(false, cpu->instruction), cpu->instruct_adr); + if (((cpu->intVector != 0) ^ (cpu->proc_ID == ARMCPU_ARM9))) { armcpu_exception(&NDS_ARM9,0x04); @@ -592,59 +622,60 @@ u32 armcpu_exec() //this assert is annoying. but sometimes it is handy. //assert(ARMPROC.instruct_adr!=0x00000000); //#ifdef DEVELOPER -// if ((((ARMPROC.instruct_adr & 0x0F000000) == 0x0F000000) && (PROCNUM == 0)) || -// (((ARMPROC.instruct_adr & 0x0F000000) == 0x00000000) && (PROCNUM == 1))) -// { -// switch (ARMPROC.instruct_adr & 0xFFFF) -// { -// case 0x00000000: -// printf("BIOS%c: Reset!!!\n", PROCNUM?'7':'9'); -// emu_halt(); -// break; -// case 0x00000004: -// printf("BIOS%c: Undefined instruction\n", PROCNUM?'7':'9'); -// //emu_halt(); -// break; -// case 0x00000008: -// //printf("BIOS%c: SWI\n", PROCNUM?'7':'9'); -// break; -// case 0x0000000C: -// printf("BIOS%c: Prefetch Abort!!!\n", PROCNUM?'7':'9'); -// //emu_halt(); -// break; -// case 0x00000010: -// //printf("BIOS%c: Data Abort!!!\n", PROCNUM?'7':'9'); -// //emu_halt(); -// break; -// case 0x00000014: -// printf("BIOS%c: Reserved!!!\n", PROCNUM?'7':'9'); -// break; -// case 0x00000018: -// //printf("BIOS%c: IRQ\n", PROCNUM?'7':'9'); -// break; -// case 0x0000001C: -// printf("BIOS%c: Fast IRQ\n", PROCNUM?'7':'9'); -// break; -// } -// } -//#endif -// -//#ifdef GDB_STUB -// if (ARMPROC.stalled) { -// return STALLED_CYCLE_COUNT; -// } -// -// /* check for interrupts */ -// if (ARMPROC.irq_flag) { -// armcpu_irqException(&ARMPROC); -// } -// -// cFetch = armcpu_prefetch(&ARMPROC); -// -// if (ARMPROC.stalled) { -// return MMU_fetchExecuteCycles(cExecute, cFetch); -// } -//#endif +#if 0 + if ((((ARMPROC.instruct_adr & 0x0F000000) == 0x0F000000) && (PROCNUM == 0)) || + (((ARMPROC.instruct_adr & 0x0F000000) == 0x00000000) && (PROCNUM == 1))) + { + switch (ARMPROC.instruct_adr & 0xFFFF) + { + case 0x00000000: + printf("BIOS%c: Reset!!!\n", PROCNUM?'7':'9'); + emu_halt(); + break; + case 0x00000004: + printf("BIOS%c: Undefined instruction\n", PROCNUM?'7':'9'); + //emu_halt(); + break; + case 0x00000008: + //printf("BIOS%c: SWI\n", PROCNUM?'7':'9'); + break; + case 0x0000000C: + printf("BIOS%c: Prefetch Abort!!!\n", PROCNUM?'7':'9'); + //emu_halt(); + break; + case 0x00000010: + //printf("BIOS%c: Data Abort!!!\n", PROCNUM?'7':'9'); + //emu_halt(); + break; + case 0x00000014: + printf("BIOS%c: Reserved!!!\n", PROCNUM?'7':'9'); + break; + case 0x00000018: + //printf("BIOS%c: IRQ\n", PROCNUM?'7':'9'); + break; + case 0x0000001C: + printf("BIOS%c: Fast IRQ\n", PROCNUM?'7':'9'); + break; + } + } +#endif + +#ifdef GDB_STUB + if (ARMPROC.stalled) { + return STALLED_CYCLE_COUNT; + } + + /* check for interrupts */ + if (ARMPROC.irq_flag) { + armcpu_irqException(&ARMPROC); + } + + cFetch = armcpu_prefetch(&ARMPROC); + + if (ARMPROC.stalled) { + return MMU_fetchExecuteCycles(cExecute, cFetch); + } +#endif //cFetch = armcpu_prefetch(&ARMPROC); diff --git a/desmume/src/armcpu.h b/desmume/src/armcpu.h index 5fc87e59d..2a7d3df6a 100644 --- a/desmume/src/armcpu.h +++ b/desmume/src/armcpu.h @@ -253,6 +253,7 @@ BOOL armcpu_irqException(armcpu_t *armcpu); BOOL armcpu_flagIrq( armcpu_t *armcpu); void armcpu_exception(armcpu_t *cpu, u32 number); u32 TRAPUNDEF(armcpu_t* cpu); +u32 armcpu_Wait4IRQ(armcpu_t *cpu); extern armcpu_t NDS_ARM7; extern armcpu_t NDS_ARM9;