Better BIOS IRQ wait routines, supporting old IRQ flags discarding.

This seems to fix all the SPP problems!
This commit is contained in:
luigi__ 2009-01-31 19:37:06 +00:00
parent 61a36046d4
commit 9cd1ad785e
5 changed files with 74 additions and 40 deletions

View File

@ -1,34 +1,34 @@
/* Copyright (C) 2006 yopyop
yopyop156@ifrance.com
yopyop156.ifrance.com
Copyright 2007 shash
Copyright 2007-2009 DeSmuME team
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "FIFO.h"
/* Copyright (C) 2006 yopyop
yopyop156@ifrance.com
yopyop156.ifrance.com
Copyright 2007 shash
Copyright 2007-2009 DeSmuME team
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "FIFO.h"
#include <string.h>
#include "armcpu.h"
#include "debug.h"
#include "mem.h"
#include "MMU.h"
#include "MMU.h"
// ========================================================= IPC FIFO
IPC_FIFO ipc_fifo[2]; // 0 - ARM9
// 1 - ARM7
@ -70,7 +70,8 @@ void IPC_FIFOsend(u8 proc, u32 val)
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l);
T1WriteWord(MMU.MMU_MEM[proc_remote][0x40], 0x184, cnt_r);
MMU.reg_IF[proc_remote] |= ( (cnt_l & 0x0400) << 8 );
// MMU.reg_IF[proc_remote] |= ( (cnt_l & 0x0400) << 8 );
setIF(proc_remote, ((cnt_l & 0x0400)<<8));
}
u32 IPC_FIFOrecv(u8 proc)
@ -111,7 +112,8 @@ u32 IPC_FIFOrecv(u8 proc)
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l);
T1WriteWord(MMU.MMU_MEM[proc_remote][0x40], 0x184, cnt_r);
MMU.reg_IF[proc_remote] |= ( (cnt_l & 0x0004) << 15);
//MMU.reg_IF[proc_remote] |= ( (cnt_l & 0x0004) << 15);
setIF(proc_remote, ((cnt_l & 0x0004)<<15));
return (val);
}
@ -127,13 +129,14 @@ void IPC_FIFOcnt(u8 proc, u16 val)
ipc_fifo[proc].tail = 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);
//MMU.reg_IF[proc^1] |= ((val & 0x0004) << 15);
setIF(proc^1, ((val & 0x0004)<<15));
return;
}
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, val);
}
// ========================================================= GFX FIFO
GFX_FIFO gxFIFO;
@ -232,7 +235,8 @@ void GFX_FIFOcnt(u32 val)
if (gxstat & 0xC0000000)
{
//NDS_makeARM9Int(21);
MMU.reg_IF[0] = (1<<21);
//MMU.reg_IF[0] = (1<<21);
setIF(0, (1<<21));
}
}

View File

@ -224,7 +224,8 @@ inline u32 NDS_exec(s32 nb) { return NDS_exec<false>(nb); }
{
if(T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0x10)
{
MMU.reg_IF[0] |= 2;// & (MMU.reg_IME[0] << 1);// (MMU.reg_IE[0] & (1<<1));
//MMU.reg_IF[0] |= 2;// & (MMU.reg_IME[0] << 1);// (MMU.reg_IE[0] & (1<<1));
setIF(0, 2);
NDS_ARM9.wIRQ = TRUE;
}
}
@ -233,7 +234,8 @@ inline u32 NDS_exec(s32 nb) { return NDS_exec<false>(nb); }
{
if(T1ReadWord(MMU.ARM7_REG, 4) & 0x10)
{
MMU.reg_IF[1] |= 2;// & (MMU.reg_IME[1] << 1);// (MMU.reg_IE[1] & (1<<1));
// MMU.reg_IF[1] |= 2;// & (MMU.reg_IME[1] << 1);// (MMU.reg_IE[1] & (1<<1));
setIF(1, 2);
NDS_ARM7.wIRQ = TRUE;
}
}
@ -242,7 +244,8 @@ inline u32 NDS_exec(s32 nb) { return NDS_exec<false>(nb); }
{
if(T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0x8)
{
MMU.reg_IF[0] |= 1;// & (MMU.reg_IME[0]);// (MMU.reg_IE[0] & 1);
// MMU.reg_IF[0] |= 1;// & (MMU.reg_IME[0]);// (MMU.reg_IE[0] & 1);
setIF(0, 1);
NDS_ARM9.wIRQ = TRUE;
//emu_halt();
/*logcount++;*/
@ -252,7 +255,8 @@ inline u32 NDS_exec(s32 nb) { return NDS_exec<false>(nb); }
static INLINE void NDS_ARM7VBlankInt(void)
{
if(T1ReadWord(MMU.ARM7_REG, 4) & 0x8)
MMU.reg_IF[1] |= 1;// & (MMU.reg_IME[1]);// (MMU.reg_IE[1] & 1);
// MMU.reg_IF[1] |= 1;// & (MMU.reg_IME[1]);// (MMU.reg_IE[1] & 1);
setIF(1, 1);
NDS_ARM7.wIRQ = TRUE;
//emu_halt();
}

View File

@ -213,6 +213,8 @@ void armcpu_init(armcpu_t *armcpu, u32 adr)
armcpu->waitIRQ = FALSE;
armcpu->wirq = FALSE;
armcpu->newIrqFlags = 0;
#ifdef GDB_STUB
armcpu->irq_flag = 0;
#endif

View File

@ -182,6 +182,8 @@ typedef struct armcpu_t
BOOL wIRQ;
BOOL wirq;
u32 newIrqFlags;
u32 (* *swi_tab)();
#ifdef GDB_STUB
@ -224,10 +226,20 @@ BOOL armcpu_flagIrq( armcpu_t *armcpu);
extern armcpu_t NDS_ARM7;
extern armcpu_t NDS_ARM9;
static INLINE void setIF(int PROCNUM, u32 flag)
{
MMU.reg_IF[PROCNUM] |= flag;
if(ARMPROC.waitIRQ)
ARMPROC.newIrqFlags |= flag;
}
static INLINE void NDS_makeARM9Int(u32 num)
{
/* flag the interrupt request source */
MMU.reg_IF[0] |= (1<<num);
// MMU.reg_IF[0] |= (1<<num);
setIF(0, (1<<num));
/* generate the interrupt if enabled */
if ((MMU.reg_IE[0] & (1 << num)) && MMU.reg_IME[0])
@ -240,7 +252,8 @@ static INLINE void NDS_makeARM9Int(u32 num)
static INLINE void NDS_makeARM7Int(u32 num)
{
/* flag the interrupt request source */
MMU.reg_IF[1] |= (1<<num);
//MMU.reg_IF[1] |= (1<<num);
setIF(1, (1<<num));
/* generate the interrupt if enabled */
if ((MMU.reg_IE[1] & (1 << num)) && MMU.reg_IME[1])

View File

@ -214,6 +214,8 @@ TEMPLATE u32 intrWaitARM()
u32 intrFlagAdr;// = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8;
u32 intr;
u32 intrFlag = 0;
BOOL noDiscard = ((cpu->R[0] == 0) && (PROCNUM == 1));
//emu_halt();
if(cpu->proc_ID)
@ -223,13 +225,17 @@ TEMPLATE u32 intrWaitARM()
intrFlagAdr = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8;
}
intr = _MMU_read32(cpu->proc_ID,intrFlagAdr);
intrFlag = cpu->R[1] & intr;
intrFlag = (cpu->R[1] & intr);
if(!noDiscard)
intrFlag &= ARMPROC.newIrqFlags;
if(intrFlag)
{
// si une(ou plusieurs) des interruptions que l'on attend s'est(se sont) produite(s)
// on efface son(les) occurence(s).
intr ^= intrFlag;
cpu->newIrqFlags ^= intrFlag;
_MMU_write32(cpu->proc_ID, intrFlagAdr, intr);
//cpu->switchMode(oldmode[cpu->proc_ID]);
return 1;
@ -245,6 +251,10 @@ TEMPLATE u32 intrWaitARM()
TEMPLATE static u32 waitVBlankARM()
{
cpu->R[0] = 1;
cpu->R[1] = 1;
return intrWaitARM<PROCNUM>();
#if 0
u32 intrFlagAdr;// = (((armcp15_t *)(cpu->coproc[15]))->DTCMRegion&0xFFFFF000)+0x3FF8;
u32 intr;
u32 intrFlag = 0;
@ -259,7 +269,7 @@ TEMPLATE static u32 waitVBlankARM()
intr = _MMU_read32(cpu->proc_ID,intrFlagAdr);
intrFlag = 1 & intr;
if(intrFlag)
// if(intrFlag)
{
// si une(ou plusieurs) des interruptions que l'on attend s'est(se sont) produite(s)
// on efface son(les) occurence(s).
@ -275,6 +285,7 @@ TEMPLATE static u32 waitVBlankARM()
//oldmode[cpu->proc_ID] = cpu->switchMode(SVC);
return 1;
#endif
}
TEMPLATE static u32 wait4IRQ()