Clear interrupts on double dma requests. Fixes the game Fahrenheit (Indigo Prophecy).

Thanks to "blood" for the discovery :)

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2873 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
ramapcsx2 2010-04-19 13:22:00 +00:00
parent 93e3205a09
commit d857fec233
3 changed files with 29 additions and 2 deletions

View File

@ -406,6 +406,28 @@ static __forceinline const wxChar* ChcrName(u32 addr)
}
}
static __forceinline const int ChannelNumber(u32 addr)
{
switch (addr)
{
case D0_CHCR: return 0;
case D1_CHCR: return 1;
case D2_CHCR: return 2;
case D3_CHCR: return 3;
case D4_CHCR: return 4;
case D5_CHCR: return 5;
case D6_CHCR: return 6;
case D7_CHCR: return 7;
case D8_CHCR: return 8;
case D9_CHCR: return 9;
default:
{
DevCon.Warning("Invalid DMA channel number");
return 51; // some value
}
}
}
union tDMAC_CTRL {
struct {
u32 DMAE : 1; // 0/1 - disables/enables all DMAs

View File

@ -117,12 +117,16 @@ static void DmaExec( void (*func)(), u32 mem, u32 value )
tDMA_CHCR chcr(value);
//It's invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC
if (chcr.STR && reg->chcr.STR && dmacRegs->ctrl.DMAE) {
if (chcr.STR && reg->chcr.STR && dmacRegs->ctrl.DMAE)
{
if((reg->chcr._u32 & 0xff) == (chcr._u32 & 0xff) && psHu8(DMAC_ENABLER+2) == 0) //Tried to start another DMA in the same mode
{
DevCon.Warning(L"DMAExec32 Attempt to run DMA while one is already active in %s(%x)", ChcrName(mem), mem);
cpuClearInt( ChannelNumber(mem) ); // clear any eventual interrupts (Fahrenheit boot, VIF1 active)
}
else //Just trying to change mode without stopping the DMA, so we dont care really :P
{
HW_LOG("Attempted to change modes while DMA active, ignoring");
DevCon.Warning("Attempted to change modes while DMA active, ignoring");
// When DMA is active only STR field is writable, so we just
// call the dma transfer function w/o modifying CHCR contents...
//func();

View File

@ -379,6 +379,7 @@ extern void cpuException(u32 code, u32 bd);
extern void cpuTlbMissR(u32 addr, u32 bd);
extern void cpuTlbMissW(u32 addr, u32 bd);
extern void cpuTestHwInts();
extern void cpuClearInt(uint n);
extern void cpuSetNextBranch( u32 startCycle, s32 delta );
extern void cpuSetNextBranchDelta( s32 delta );