diff --git a/desmume/src/FIFO.cpp b/desmume/src/FIFO.cpp index 7bff14f99..4419f0a1b 100644 --- a/desmume/src/FIFO.cpp +++ b/desmume/src/FIFO.cpp @@ -34,13 +34,6 @@ IPC_FIFO ipc_fifo[2]; // 0 - ARM9 // 1 - ARM7 -u8 FORCEINLINE IPC_FIFOgetSize(u8 proc) -{ - if (ipc_fifo[proc].head < ipc_fifo[proc].tail) return (ipc_fifo[proc].tail - ipc_fifo[proc].head); - if (ipc_fifo[proc].head > ipc_fifo[proc].tail) return (16 - (ipc_fifo[proc].head - ipc_fifo[proc].tail)); - return 0; -} - void IPC_FIFOinit(u8 proc) { memset(&ipc_fifo[proc], 0, sizeof(IPC_FIFO)); @@ -62,14 +55,14 @@ void IPC_FIFOsend(u8 proc, u32 val) u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc_remote][0x40], 0x184); - //LOG("IPC%s send FIFO 0x%08X (l 0x%X, tail %02i) (r 0x%X, tail %02i)\n", - // proc?"7":"9", val, cnt_l, ipc_fifo[proc].tail, cnt_r, ipc_fifo[proc^1].tail); + //LOG("IPC%s send FIFO 0x%08X size %03i (l 0x%X, tail %02i) (r 0x%X, tail %02i)\n", + // proc?"7":"9", val, ipc_fifo[proc].size, cnt_l, ipc_fifo[proc].tail, cnt_r, ipc_fifo[proc^1].tail); cnt_l &= 0xBFFC; // clear send empty bit & full cnt_r &= 0xBCFF; // set recv empty bit & full ipc_fifo[proc].buf[ipc_fifo[proc].tail] = val; ipc_fifo[proc].tail++; - ipc_fifo[proc].size = IPC_FIFOgetSize(proc); + ipc_fifo[proc].size++; if (ipc_fifo[proc].tail > 15) ipc_fifo[proc].tail = 0; if (ipc_fifo[proc].size > 15) @@ -106,11 +99,12 @@ u32 IPC_FIFOrecv(u8 proc) val = ipc_fifo[proc_remote].buf[ipc_fifo[proc_remote].head]; ipc_fifo[proc_remote].head++; - ipc_fifo[proc_remote].size = IPC_FIFOgetSize(proc_remote); + ipc_fifo[proc_remote].size--; if (ipc_fifo[proc_remote].head > 15) ipc_fifo[proc_remote].head = 0; - //LOG("IPC%s recv FIFO 0x%08X (l 0x%X, tail %02i) (r 0x%X, tail %02i)\n", - // proc?"7":"9", val, cnt_l, ipc_fifo[proc].tail, cnt_r, ipc_fifo[proc^1].tail); + //LOG("IPC%s recv FIFO 0x%08X size %03i (l 0x%X, tail %02i) (r 0x%X, tail %02i)\n", + // proc?"7":"9", val, ipc_fifo[proc].size, cnt_l, ipc_fifo[proc].tail, cnt_r, ipc_fifo[proc^1].tail); + if ( ipc_fifo[proc_remote].size == 0 ) // FIFO empty { @@ -134,7 +128,7 @@ void IPC_FIFOcnt(u8 proc, u16 val) //LOG("IPC%s FIFO context 0x%X (local 0x%04X, remote 0x%04X)\n", proc?"7":"9", val, cnt_l, cnt_r); if (val & 0x4008) { - ipc_fifo[proc].tail = 0; + ipc_fifo[proc].head = 0; ipc_fifo[proc].tail = 0; ipc_fifo[proc].size = 0; T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, (cnt_l & 0x0301) | (val & 0x8404) | 1); T1WriteWord(MMU.MMU_MEM[proc^1][0x40], 0x184, (cnt_r & 0x8407) | 0x100); //MMU.reg_IF[proc^1] |= ((val & 0x0004) << 15); diff --git a/desmume/src/bios.cpp b/desmume/src/bios.cpp index 226c830f5..a136821de 100644 --- a/desmume/src/bios.cpp +++ b/desmume/src/bios.cpp @@ -211,26 +211,32 @@ TEMPLATE static u32 delayLoop() TEMPLATE u32 intrWaitARM() { - u32 intrFlagAdr;// = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8; - u32 intr; + u32 intrFlagAdr = 0; + u32 intr = 0; u32 intrFlag = 0; - BOOL noDiscard = ((cpu->R[0] == 0) && (PROCNUM == 1)); + BOOL noDiscard = ((cpu->R[0] == 0) && (PROCNUM == ARMCPU_ARM7)); //emu_halt(); - if(cpu->proc_ID) + if(PROCNUM == ARMCPU_ARM7) { intrFlagAdr = 0x380FFF8; } else { intrFlagAdr = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8; } - intr = _MMU_read32(intrFlagAdr); + intr = _MMU_read32(intrFlagAdr); + intrFlag = (cpu->R[1] & intr); - + //INFO("ARM%c: wait for IRQ r0=0x%02X, r1=0x%08X - 0x%08X (flag 0x%08X)\n", PROCNUM?'7':'9', cpu->R[0], cpu->R[1], intr, intrFlag); if(!noDiscard) - intrFlag &= ARMPROC.newIrqFlags; - - if(intrFlag) + intrFlag &= cpu->newIrqFlags; + + // http://nocash.emubase.de/gbatek.htm#bioshaltfunctions + // SWI 04h (GBA/NDS7/NDS9) - IntrWait + // ... The function forcefully sets IME=1. ... + _MMU_write32(0x04000208, 1); + + if(intrFlag) { // si une(ou plusieurs) des interruptions que l'on attend s'est(se sont) produite(s) // on efface son(les) occurence(s). @@ -240,7 +246,7 @@ TEMPLATE u32 intrWaitARM() //cpu->switchMode(oldmode[cpu->proc_ID]); return 1; } - + cpu->R[15] = cpu->instruct_adr; cpu->next_instruction = cpu->R[15]; cpu->waitIRQ = 1;