diff --git a/pcsx2/Dmac.h b/pcsx2/Dmac.h index b62ef8a271..b68737b79d 100644 --- a/pcsx2/Dmac.h +++ b/pcsx2/Dmac.h @@ -171,10 +171,6 @@ union tDMA_QWC { tDMA_TAG tag() const { return (tDMA_TAG)_u32; } }; -static void setDmacStat(u32 num); -static tDMA_TAG *dmaGetAddr(u32 addr, bool write); -static void throwBusError(const char *s); - struct DMACh { tDMA_CHCR chcr; u32 _null0[3]; @@ -200,63 +196,14 @@ struct DMACh { qwc = ptag[0].QWC; } - bool transfer(const char *s, tDMA_TAG* ptag) - { - if (ptag == NULL) // Is ptag empty? - { - throwBusError(s); - return false; - } - chcrTransfer(ptag); + bool transfer(const char *s, tDMA_TAG* ptag); + void unsafeTransfer(tDMA_TAG* ptag); + tDMA_TAG *getAddr(u32 addr, u32 num, bool write); + tDMA_TAG *DMAtransfer(u32 addr, u32 num); + tDMA_TAG dma_tag(); - qwcTransfer(ptag); - return true; - } - - void unsafeTransfer(tDMA_TAG* ptag) - { - chcrTransfer(ptag); - qwcTransfer(ptag); - } - - tDMA_TAG *getAddr(u32 addr, u32 num, bool write) - { - tDMA_TAG *ptr = dmaGetAddr(addr, write); - if (ptr == NULL) - { - throwBusError("dmaGetAddr"); - setDmacStat(num); - chcr.STR = false; - } - - return ptr; - } - - tDMA_TAG *DMAtransfer(u32 addr, u32 num) - { - tDMA_TAG *tag = getAddr(addr, num, false); - - if (tag == NULL) return NULL; - - chcrTransfer(tag); - qwcTransfer(tag); - return tag; - } - - tDMA_TAG dma_tag() - { - return chcr.tag(); - } - - wxString cmq_to_str() const - { - return wxsFormat(L"chcr = %lx, madr = %lx, qwc = %lx", chcr._u32, madr, qwc); - } - - wxString cmqt_to_str() const - { - return wxsFormat(L"chcr = %lx, madr = %lx, qwc = %lx, tadr = %1x", chcr._u32, madr, qwc, tadr); - } + wxString cmq_to_str() const; + wxString cmqt_to_str() const; }; enum INTCIrqs @@ -599,80 +546,10 @@ static DMACh& gifch = (DMACh&)eeHw[0xA000]; static DMACh& spr0ch = (DMACh&)eeHw[0xD000]; static DMACh& spr1ch = (DMACh&)eeHw[0xD400]; -static __fi void throwBusError(const char *s) -{ - Console.Error("%s BUSERR", s); - dmacRegs.stat.BEIS = true; -} - -static __fi void setDmacStat(u32 num) -{ - dmacRegs.stat.set_flags(1 << num); -} - -// Note: Dma addresses are guaranteed to be aligned to 16 bytes (128 bits) -static __fi tDMA_TAG *SPRdmaGetAddr(u32 addr, bool write) -{ - // if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); } - - //For some reason Getaway references SPR Memory from itself using SPR0, oh well, let it i guess... - if((addr & 0x70000000) == 0x70000000) - { - return (tDMA_TAG*)&eeMem->Scratch[addr & 0x3ff0]; - } - - // FIXME: Why??? DMA uses physical addresses - addr &= 0x1ffffff0; - - if (addr < Ps2MemSize::Base) - { - return (tDMA_TAG*)&eeMem->Main[addr]; - } - else if (addr < 0x10000000) - { - return (tDMA_TAG*)(write ? eeMem->ZeroWrite : eeMem->ZeroRead); - } - else if ((addr >= 0x11004000) && (addr < 0x11010000)) - { - //Access for VU Memory - return (tDMA_TAG*)vtlb_GetPhyPtr(addr & 0x1FFFFFF0); - } - else - { - Console.Error( "*PCSX2*: DMA error: %8.8x", addr); - return NULL; - } -} - -// Note: Dma addresses are guaranteed to be aligned to 16 bytes (128 bits) -static __ri tDMA_TAG *dmaGetAddr(u32 addr, bool write) -{ - // if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); } - if (DMA_TAG(addr).SPR) return (tDMA_TAG*)&eeMem->Scratch[addr & 0x3ff0]; - - // FIXME: Why??? DMA uses physical addresses - addr &= 0x1ffffff0; - - if (addr < Ps2MemSize::Base) - { - return (tDMA_TAG*)&eeMem->Main[addr]; - } - else if (addr < 0x10000000) - { - return (tDMA_TAG*)(write ? eeMem->ZeroWrite : eeMem->ZeroRead); - } - else if (addr < 0x10004000) - { - // Secret scratchpad address for DMA = end of maximum main memory? - //Console.Warning("Writing to the scratchpad without the SPR flag set!"); - return (tDMA_TAG*)&eeMem->Scratch[addr & 0x3ff0]; - } - else - { - Console.Error( "*PCSX2*: DMA error: %8.8x", addr); - return NULL; - } -} +extern void throwBusError(const char *s); +extern void setDmacStat(u32 num); +extern tDMA_TAG *SPRdmaGetAddr(u32 addr, bool write); +extern tDMA_TAG *dmaGetAddr(u32 addr, bool write); extern void hwIntcIrq(int n); extern void hwDmacIrq(int n); @@ -681,5 +558,5 @@ extern bool hwMFIFOWrite(u32 addr, const u128* data, uint size_qwc); extern bool hwDmacSrcChainWithStack(DMACh& dma, int id); extern bool hwDmacSrcChain(DMACh& dma, int id); -template< uint page > -extern bool dmacWrite32( u32 mem, mem32_t& value ); +template< uint page > u32 dmacRead32( u32 mem ); +template< uint page > extern bool dmacWrite32( u32 mem, mem32_t& value ); diff --git a/pcsx2/HwRead.cpp b/pcsx2/HwRead.cpp index 3b1813da29..f031af06e2 100644 --- a/pcsx2/HwRead.cpp +++ b/pcsx2/HwRead.cpp @@ -48,12 +48,7 @@ mem32_t __fastcall _hwRead32(u32 mem) case 0x02: return ipuRead32( mem ); - case 0x03: - if ((mem == GIF_STAT) && CHECK_OPHFLAGHACK) - { - gifRegs.stat.OPH = !gifRegs.stat.OPH; - } - break; + case 0x03: return dmacRead32<0x03>( mem ); case 0x04: case 0x05: diff --git a/pcsx2/ps2/LegacyDmac.cpp b/pcsx2/ps2/LegacyDmac.cpp index f236fe7f5c..0b2f9c6dbe 100644 --- a/pcsx2/ps2/LegacyDmac.cpp +++ b/pcsx2/ps2/LegacyDmac.cpp @@ -20,6 +20,140 @@ #include "ps2/HwInternal.h" +bool DMACh::transfer(const char *s, tDMA_TAG* ptag) +{ + if (ptag == NULL) // Is ptag empty? + { + throwBusError(s); + return false; + } + chcrTransfer(ptag); + + qwcTransfer(ptag); + return true; +} + +void DMACh::unsafeTransfer(tDMA_TAG* ptag) +{ + chcrTransfer(ptag); + qwcTransfer(ptag); +} + +tDMA_TAG *DMACh::getAddr(u32 addr, u32 num, bool write) +{ + tDMA_TAG *ptr = dmaGetAddr(addr, write); + if (ptr == NULL) + { + throwBusError("dmaGetAddr"); + setDmacStat(num); + chcr.STR = false; + } + + return ptr; +} + +tDMA_TAG *DMACh::DMAtransfer(u32 addr, u32 num) +{ + tDMA_TAG *tag = getAddr(addr, num, false); + + if (tag == NULL) return NULL; + + chcrTransfer(tag); + qwcTransfer(tag); + return tag; +} + +tDMA_TAG DMACh::dma_tag() +{ + return chcr.tag(); +} + +wxString DMACh::cmq_to_str() const +{ + return wxsFormat(L"chcr = %lx, madr = %lx, qwc = %lx", chcr._u32, madr, qwc); +} + +wxString DMACh::cmqt_to_str() const +{ + return wxsFormat(L"chcr = %lx, madr = %lx, qwc = %lx, tadr = %1x", chcr._u32, madr, qwc, tadr); +} + +__fi void throwBusError(const char *s) +{ + Console.Error("%s BUSERR", s); + dmacRegs.stat.BEIS = true; +} + +__fi void setDmacStat(u32 num) +{ + dmacRegs.stat.set_flags(1 << num); +} + +// Note: Dma addresses are guaranteed to be aligned to 16 bytes (128 bits) +__fi tDMA_TAG *SPRdmaGetAddr(u32 addr, bool write) +{ + // if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); } + + //For some reason Getaway references SPR Memory from itself using SPR0, oh well, let it i guess... + if((addr & 0x70000000) == 0x70000000) + { + return (tDMA_TAG*)&eeMem->Scratch[addr & 0x3ff0]; + } + + // FIXME: Why??? DMA uses physical addresses + addr &= 0x1ffffff0; + + if (addr < Ps2MemSize::Base) + { + return (tDMA_TAG*)&eeMem->Main[addr]; + } + else if (addr < 0x10000000) + { + return (tDMA_TAG*)(write ? eeMem->ZeroWrite : eeMem->ZeroRead); + } + else if ((addr >= 0x11004000) && (addr < 0x11010000)) + { + //Access for VU Memory + return (tDMA_TAG*)vtlb_GetPhyPtr(addr & 0x1FFFFFF0); + } + else + { + Console.Error( "*PCSX2*: DMA error: %8.8x", addr); + return NULL; + } +} + +// Note: Dma addresses are guaranteed to be aligned to 16 bytes (128 bits) +__ri tDMA_TAG *dmaGetAddr(u32 addr, bool write) +{ + // if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); } + if (DMA_TAG(addr).SPR) return (tDMA_TAG*)&eeMem->Scratch[addr & 0x3ff0]; + + // FIXME: Why??? DMA uses physical addresses + addr &= 0x1ffffff0; + + if (addr < Ps2MemSize::Base) + { + return (tDMA_TAG*)&eeMem->Main[addr]; + } + else if (addr < 0x10000000) + { + return (tDMA_TAG*)(write ? eeMem->ZeroWrite : eeMem->ZeroRead); + } + else if (addr < 0x10004000) + { + // Secret scratchpad address for DMA = end of maximum main memory? + //Console.Warning("Writing to the scratchpad without the SPR flag set!"); + return (tDMA_TAG*)&eeMem->Scratch[addr & 0x3ff0]; + } + else + { + Console.Error( "*PCSX2*: DMA error: %8.8x", addr); + return NULL; + } +} + + // Returns true if the DMA is enabled and executed successfully. Returns false if execution // was blocked (DMAE or master DMA enabler). static bool QuickDmaExec( void (*func)(), u32 mem) @@ -139,25 +273,16 @@ static __ri void DmaExec( void (*func)(), u32 mem, u32 value ) } //else QueuedDMA._u16 &~= (1 << ChannelNumber(mem)); // } -// DmaExec8 should only be called for the second byte of CHCR. -// Testing Note: dark cloud 2 uses 8 bit DMAs register writes. -static __fi void DmaExec8( void (*func)(), u32 mem, u8 value ) -{ - pxAssumeMsg( (mem & 0xf) == 1, "DmaExec8 should only be called for the second byte of CHCR" ); - - // The calling function calls this when the second byte (bits 8->15) is written. Only bit 8 - // is effective, and it is the STR (start) bit. :) - DmaExec( func, mem & ~0xf, (u32)value<<8 ); -} - -static __fi void DmaExec16( void (*func)(), u32 mem, u16 value ) -{ - DmaExec( func, mem, (u32)value ); -} - +template< uint page > __fi u32 dmacRead32( u32 mem ) { // Fixme: OPH hack. Toggle the flag on each GIF_STAT access. (rama) + if (IsPageFor(mem) && (mem == GIF_STAT) && CHECK_OPHFLAGHACK) + { + gifRegs.stat.OPH = !gifRegs.stat.OPH; + } + + return psHu32(mem); } // Returns TRUE if the caller should do writeback of the register to eeHw; false if the @@ -326,17 +451,16 @@ __fi bool dmacWrite32( u32 mem, mem32_t& value ) return true; } +template u32 dmacRead32<0x03>( u32 mem ); + template bool dmacWrite32<0x00>( u32 mem, mem32_t& value ); template bool dmacWrite32<0x01>( u32 mem, mem32_t& value ); template bool dmacWrite32<0x02>( u32 mem, mem32_t& value ); - template bool dmacWrite32<0x03>( u32 mem, mem32_t& value ); - template bool dmacWrite32<0x04>( u32 mem, mem32_t& value ); template bool dmacWrite32<0x05>( u32 mem, mem32_t& value ); template bool dmacWrite32<0x06>( u32 mem, mem32_t& value ); template bool dmacWrite32<0x07>( u32 mem, mem32_t& value ); - template bool dmacWrite32<0x08>( u32 mem, mem32_t& value ); template bool dmacWrite32<0x09>( u32 mem, mem32_t& value ); template bool dmacWrite32<0x0a>( u32 mem, mem32_t& value ); @@ -344,5 +468,4 @@ template bool dmacWrite32<0x0b>( u32 mem, mem32_t& value ); template bool dmacWrite32<0x0c>( u32 mem, mem32_t& value ); template bool dmacWrite32<0x0d>( u32 mem, mem32_t& value ); template bool dmacWrite32<0x0e>( u32 mem, mem32_t& value ); - template bool dmacWrite32<0x0f>( u32 mem, mem32_t& value );