diff --git a/common/src/Utilities/ThreadTools.cpp b/common/src/Utilities/ThreadTools.cpp index 3854300fc3..8236a50db9 100644 --- a/common/src/Utilities/ThreadTools.cpp +++ b/common/src/Utilities/ThreadTools.cpp @@ -118,12 +118,12 @@ Threading::PersistentThread::~PersistentThread() throw() bool Threading::PersistentThread::AffinityAssert_AllowFromSelf() const { - return pxAssertMsg( IsSelf(), wxsFormat( L"Thread affinity violation: Call allowed from '%s' thread only.", m_name ) ); + return pxAssertMsg( IsSelf(), wxsFormat( L"Thread affinity violation: Call allowed from '%s' thread only.", m_name.c_str() ) ); } bool Threading::PersistentThread::AffinityAssert_DisallowFromSelf() const { - return pxAssertMsg( !IsSelf(), wxsFormat( L"Thread affinity violation: Call is *not* allowed from '%s' thread.", m_name ) ); + return pxAssertMsg( !IsSelf(), wxsFormat( L"Thread affinity violation: Call is *not* allowed from '%s' thread.", m_name.c_str() ) ); } void Threading::PersistentThread::FrankenMutex( Mutex& mutex ) diff --git a/pcsx2/Dmac.h b/pcsx2/Dmac.h index aaa57634b1..0bd2e27f39 100644 --- a/pcsx2/Dmac.h +++ b/pcsx2/Dmac.h @@ -121,6 +121,7 @@ union tDMA_CHCR { tDMA_CHCR( u32 val) { _u32 = val; } bool test(u32 flags) { return !!(_u32 & flags); } + void set(u32 value) { _u32 = value; } void set_flags(u32 flags) { _u32 |= flags; } void clear_flags(u32 flags) { _u32 &= ~flags; } void reset() { _u32 = 0; } @@ -335,6 +336,24 @@ union tDMAC_QUEUE bool empty() { return (_u16 == 0); } }; +static __forceinline const wxChar* ChcrName(u32 addr) +{ + switch (addr) + { + case D0_CHCR: return L"Vif 0"; + case D1_CHCR: return L"Vif 1"; + case D2_CHCR: return L"GS"; + case D3_CHCR: return L"Ipu 0"; + case D4_CHCR: return L"Ipu 1"; + case D5_CHCR: return L"Sif 0"; + case D6_CHCR: return L"Sif 1"; + case D7_CHCR: return L"Sif 2"; + case D8_CHCR: return L"SPR 0"; + case SPR1_CHCR: return L"SPR 1"; + default: return L"???"; + } +} + union tDMAC_CTRL { struct { u32 DMAE : 1; // 0/1 - disables/enables all DMAs diff --git a/pcsx2/GS.h b/pcsx2/GS.h index 3e96ea0f80..8443d2ecdc 100644 --- a/pcsx2/GS.h +++ b/pcsx2/GS.h @@ -28,6 +28,29 @@ enum CSRfifoState CSR_FIFO_RESERVED }; +union tGS_CSRw +{ + struct + { + u32 SIGNAL : 1; // SIGNAL event + u32 FINISH : 1; // FINISH event + u32 HSINT : 1; // HSYNC Interrupt + u32 VSINT : 1; // VSYNC Interrupt + u32 EDWINT : 1; // Rect Area Write Termination Interrupt + }; + u32 _u32; + + void reset() { _u32 = 0; } + void fill() + { + SIGNAL = true; + FINISH = true; + HSINT = true; + VSINT = true; + EDWINT = true; + } +}; + // I'm initializing this as 64 bit because GSCSRr is 64 bit. There only appeared to be 32 bits worth of fields, // and CSRw is 32 bit, though, so I'm not sure if that's correct. union tGS_CSR @@ -35,7 +58,6 @@ union tGS_CSR struct { // Start Interrupts. - // If writing, 1 clears the old event, and enables a new one. 0 does nothing. // If reading, 1 means a signal has been generated. u64 SIGNAL : 1; // SIGNAL event u64 FINISH : 1; // FINISH event @@ -71,19 +93,6 @@ union tGS_CSR _u64 = value; } - // This only sets the interrupts. - void setIntBits(const u64 value) - { - _u64 = (_u64 & ~0x1f) | (value & 0x1f); - } - - // This inverts value, ands it with the current bits, and then sends the result to - // setIntBits to be set as the current interrupts. Which appears to be what gsCSRwrite does. - void flipIntBits(tGS_CSR value) - { - setIntBits(_u64 & ~value._u64); - } - bool interrupts() { return (SIGNAL || FINISH || HSINT || VSINT || EDWINT); } void setAllInterrupts(bool value) diff --git a/pcsx2/HwWrite.cpp b/pcsx2/HwWrite.cpp index ded0f207d1..e4286b8d26 100644 --- a/pcsx2/HwWrite.cpp +++ b/pcsx2/HwWrite.cpp @@ -32,7 +32,7 @@ static __forceinline void DmaExec8( void (*func)(), u32 mem, u8 value ) //It's invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC if ((value & 0x1) && ((psHu8(mem) & 0x1) == 0x1) && dmacRegs->ctrl.DMAE) { - DevCon.Warning( "DMAExec8 Attempt to run DMA while one is already active mem = %x", mem ); + DevCon.Warning( L"DMAExec8 Attempt to run DMA while one is already active in %s(%x)", ChcrName(mem), mem ); } // Upper 16bits of QWC should not be written since QWC is 16bits in size. @@ -52,24 +52,26 @@ static __forceinline void DmaExec8( void (*func)(), u32 mem, u8 value ) static __forceinline void DmaExec16( void (*func)(), u32 mem, u16 value ) { - u32 qwcRegister = mem | 0x20; + DMACh *reg = &psH_DMACh(mem); + 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(value).STR) && (psH_Chcr(mem).STR) && dmacRegs->ctrl.DMAE) + if (chcr.STR && reg->chcr.STR && dmacRegs->ctrl.DMAE) { - DevCon.Warning( "DMAExec16 Attempt to run DMA while one is already active mem = %x", mem); + DevCon.Warning( L"DMAExec16 Attempt to run DMA while one is already active in %s(%x)", ChcrName(mem), mem ); } - // Upper 16bits of QWC should not be written since QWC is 16bits in size. - if ((psHu32(qwcRegister) >> 16) != 0) + // Note: pad is the padding right above qwc, so we're testing whether qwc + // has overflowed into pad. + if (reg->pad != 0) { - DMA_LOG("DMA QWC (%x) upper 16bits set to %x\n", - qwcRegister, psHu32(qwcRegister) >> 16); - psHu32(qwcRegister) = 0; + DevCon.Warning(L"DMA QWC (%s) upper 16 bits set to %x\n", + ChcrName(mem), reg->pad); + reg->qwc = reg->pad = 0; } - psHu16(mem) = CHCR(value).lower(); - if ((psHu16(mem) & 0x100) && dmacRegs->ctrl.DMAE) + psHu16(mem) = chcr.lower(); + if (reg->chcr.STR && dmacRegs->ctrl.DMAE) { //Console.WriteLn("16bit DMA Start"); func(); @@ -78,34 +80,36 @@ static __forceinline void DmaExec16( void (*func)(), u32 mem, u16 value ) static void DmaExec( void (*func)(), u32 mem, u32 value ) { - u32 qwcRegister = mem | 0x20; - + DMACh *reg = &psH_DMACh(mem); + 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(value).STR) && (psH_Chcr(mem).STR) && dmacRegs->ctrl.DMAE) + if (chcr.STR && reg->chcr.STR && dmacRegs->ctrl.DMAE) { - DevCon.Warning( "DMAExec32 Attempt to run DMA while one is already active mem = %x", mem ); - + DevCon.Warning( L"DMAExec32 Attempt to run DMA while one is already active in %s(%x)", ChcrName(mem), mem ); + //DevCon.Warning( L"DMAExec32: chcr value = 0x%x", value); // Returning here breaks every single Gust game written. :( // Not returning here breaks Fatal Frame. Gamefix time. if (CHECK_DMAEXECHACK) return; } - // Upper 16bits of QWC should not be written since QWC is 16bits in size. - if ((psHu32(qwcRegister) >> 16) != 0) + // Note: pad is the padding right above qwc, so we're testing whether qwc + // has overflowed into pad. + if (reg->pad != 0) { - DevCon.Warning("DMA QWC (%x) upper 16bits set to %x\n", - qwcRegister, psHu32(qwcRegister) >> 16); - psHu32(qwcRegister) = 0; + DevCon.Warning(L"DMA QWC (%s) upper 16 bits set to %x\n", + ChcrName(mem), reg->pad); + reg->qwc = reg->pad = 0; + //return; } /* Keep the old tag if in chain mode and hw doesn't set it*/ - if ((CHCR(value).MOD == CHAIN_MODE) && (CHCR(value).TAG == 0)) - psHu32(mem) = (psH_Chcr(mem).TAG << 16) | CHCR(value).lower(); + if ((chcr.MOD == CHAIN_MODE) && (chcr.TAG == 0)) + reg->chcr.set((reg->chcr.TAG << 16) | chcr.lower()); else /* Else (including Normal mode etc) write whatever the hardware sends*/ - psHu32(mem) = value; + reg->chcr.set(value); - if (psH_Chcr(mem).STR && dmacRegs->ctrl.DMAE) - func(); + if (reg->chcr.STR && dmacRegs->ctrl.DMAE) func(); } ///////////////////////////////////////////////////////////////////////// @@ -360,7 +364,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) case D0_CHCR: // dma0 - vif0 DMA_LOG("VIF0dma %lx", value); - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit VIF0 DMA Start while DMAC Disabled\n"); QueuedDMA.VIF0 = true; @@ -370,13 +374,13 @@ __forceinline void hwWrite16(u32 mem, u16 value) case D1_CHCR: // dma1 - vif1 - chcr DMA_LOG("VIF1dma CHCR %lx", value); - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit VIF1 DMA Start while DMAC Disabled\n"); QueuedDMA.VIF1 = true; } - if (value & 0x100) vif1.done = false; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO + if (CHCR(value).STR) vif1.done = false; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO DmaExec16(dmaVIF1, mem, value); break; @@ -415,7 +419,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) case D2_CHCR: // dma2 - gif DMA_LOG("0x%8.8x hwWrite32: GSdma %lx", cpuRegs.cycle, value); - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit GIF DMA Start while DMAC Disabled\n"); QueuedDMA.GIF = true; @@ -457,7 +461,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) case D3_CHCR: // dma3 - fromIPU DMA_LOG("IPU0dma %lx", value); - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit IPU0 DMA Start while DMAC Disabled\n"); QueuedDMA.IPU0 = true; @@ -489,7 +493,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) case D4_CHCR: // dma4 - toIPU DMA_LOG("IPU1dma %lx", value); - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit IPU1 DMA Start while DMAC Disabled\n"); QueuedDMA.IPU1 = true; @@ -521,7 +525,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) case D5_CHCR: // dma5 - sif0 DMA_LOG("SIF0dma %lx", value); // if (value == 0) psxSu32(0x30) = 0x40000; - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit SIF0 DMA Start while DMAC Disabled\n"); QueuedDMA.SIF0 = true; @@ -535,7 +539,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) case D6_CHCR: // dma6 - sif1 DMA_LOG("SIF1dma %lx", value); - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit SIF1 DMA Start while DMAC Disabled\n"); QueuedDMA.SIF1 = true; @@ -567,7 +571,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) case D7_CHCR: // dma7 - sif2 DMA_LOG("SIF2dma %lx", value); - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit SIF2 DMA Start while DMAC Disabled\n"); QueuedDMA.SIF2 = true; @@ -581,7 +585,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) case D8_CHCR: // dma8 - fromSPR DMA_LOG("fromSPRdma %lx", value); - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit SPR0 DMA Start while DMAC Disabled\n"); QueuedDMA.SPR0 = true; @@ -591,7 +595,7 @@ __forceinline void hwWrite16(u32 mem, u16 value) case SPR1_CHCR: // dma9 - toSPR DMA_LOG("toSPRdma %lx", value); - if ((value & 0x100) && !dmacRegs->ctrl.DMAE) + if (CHCR(value).STR && !dmacRegs->ctrl.DMAE) { DevCon.Warning("16 bit SPR1 DMA Start while DMAC Disabled\n"); QueuedDMA.SPR1 = true; diff --git a/pcsx2/Memory.h b/pcsx2/Memory.h index 7a7b1e4426..33c55cd5d3 100644 --- a/pcsx2/Memory.h +++ b/pcsx2/Memory.h @@ -119,7 +119,7 @@ extern u8 *psS; //0.015 mb, scratch pad #define psSu32(mem) (*(u32*)&PS2MEM_SCRATCH[(mem) & 0x3fff]) #define psSu64(mem) (*(u64*)&PS2MEM_SCRATCH[(mem) & 0x3fff]) -#define psH_Chcr(mem) (*(tDMA_CHCR*)&PS2MEM_HW[(mem) & 0xffff]) +#define psH_DMACh(mem) (*(DMACh*)&PS2MEM_HW[(mem) & 0xffff]) extern void memAlloc(); extern void memReset(); // clears PS2 ram and loads the bios. Throws Exception::FileNotFound on error. extern void memShutdown();