diff --git a/pcsx2/HwWrite.cpp b/pcsx2/HwWrite.cpp index 5f5dd0cfdc..74a92020a2 100644 --- a/pcsx2/HwWrite.cpp +++ b/pcsx2/HwWrite.cpp @@ -218,8 +218,6 @@ void __fastcall hwWrite32( u32 mem, u32 value ) template< uint page > void __fastcall _hwWrite8(u32 mem, u8 value) { - pxAssert( (mem & 0x03) == 0 ); - iswitch (mem) icase(SIO_TXFIFO) { @@ -247,7 +245,7 @@ void __fastcall _hwWrite8(u32 mem, u8 value) return; } - u32 merged = _hwRead32(mem); + u32 merged = _hwRead32(mem & ~0x03); ((u8*)&merged)[mem & 0x3] = value; _hwWrite32(mem & ~0x03, merged); @@ -265,7 +263,7 @@ void __fastcall _hwWrite16(u32 mem, u16 value) { pxAssume( (mem & 0x01) == 0 ); - u32 merged = _hwRead32(mem); + u32 merged = _hwRead32(mem & ~0x03); ((u16*)&merged)[(mem>>1) & 0x1] = value; hwWrite32(mem & ~0x03, merged); diff --git a/pcsx2/IPU/IPU.cpp b/pcsx2/IPU/IPU.cpp index 9a7b41d746..165e2a0b40 100644 --- a/pcsx2/IPU/IPU.cpp +++ b/pcsx2/IPU/IPU.cpp @@ -17,6 +17,7 @@ #include "Common.h" #include "IPU.h" +#include "IPUdma.h" #include "yuv2rgb.h" #include "mpeg2lib/Mpeg.h" @@ -27,8 +28,7 @@ static __fi void IPU_INT0_FROM() { - extern void ipu0Interrupt(); // defined in IPUdma.cpp - if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) ipu0Interrupt(); + if (ipu0dma.qwc > 0 && ipu0dma.chcr.STR) ipu0Interrupt(); } tIPU_cmd ipu_cmd; @@ -60,14 +60,14 @@ u8* readbits = _readbits; // always can decrement by one 1qw __fi void IPUProcessInterrupt() { - if (ipuRegs->ctrl.BUSY && g_BP.IFC) IPUWorker(); + if (ipuRegs.ctrl.BUSY && g_BP.IFC) IPUWorker(); } ///////////////////////////////////////////////////////// // Register accesses (run on EE thread) int ipuInit() { - memzero(*ipuRegs); + memzero(ipuRegs); memzero(g_BP); memzero(decoder); @@ -213,27 +213,27 @@ __fi u32 ipuRead32(u32 mem) switch (mem) { ipucase(IPU_CTRL): // IPU_CTRL - ipuRegs->ctrl.IFC = g_BP.IFC; - ipuRegs->ctrl.CBP = coded_block_pattern; + ipuRegs.ctrl.IFC = g_BP.IFC; + ipuRegs.ctrl.CBP = coded_block_pattern; - if (!ipuRegs->ctrl.BUSY) - IPU_LOG("read32: IPU_CTRL=0x%08X %x", ipuRegs->ctrl._u32, cpuRegs.pc); + if (!ipuRegs.ctrl.BUSY) + IPU_LOG("read32: IPU_CTRL=0x%08X", ipuRegs.ctrl._u32); - return ipuRegs->ctrl._u32; + return ipuRegs.ctrl._u32; ipucase(IPU_BP): // IPU_BP - ipuRegs->ipubp = g_BP.BP & 0x7f; - ipuRegs->ipubp |= g_BP.IFC << 8; - ipuRegs->ipubp |= (g_BP.FP /*+ g_BP.bufferhasnew*/) << 16; + ipuRegs.ipubp = g_BP.BP & 0x7f; + ipuRegs.ipubp |= g_BP.IFC << 8; + ipuRegs.ipubp |= (g_BP.FP /*+ g_BP.bufferhasnew*/) << 16; - IPU_LOG("read32: IPU_BP=0x%08X", ipuRegs->ipubp); - return ipuRegs->ipubp; + IPU_LOG("read32: IPU_BP=0x%08X", ipuRegs.ipubp); + return ipuRegs.ipubp; default: - IPU_LOG("read32: Addr=0x%x Value = 0x%08X", mem, *(u32*)(((u8*)ipuRegs) + mem)); + IPU_LOG("read32: Addr=0x%08X Value = 0x%08X", mem, psHu32(IPU_CMD + mem)); } - return *(u32*)(((u8*)ipuRegs) + mem); + return psHu32(IPU_CMD + mem); } __fi u64 ipuRead64(u32 mem) @@ -249,8 +249,8 @@ __fi u64 ipuRead64(u32 mem) switch (mem) { ipucase(IPU_CMD): // IPU_CMD - if (ipuRegs->cmd.DATA & 0xffffff) - IPU_LOG("read64: IPU_CMD=BUSY=%x, DATA=%08X", ipuRegs->cmd.BUSY ? 1 : 0, ipuRegs->cmd.DATA); + if (ipuRegs.cmd.DATA & 0xffffff) + IPU_LOG("read64: IPU_CMD=BUSY=%x, DATA=%08X", ipuRegs.cmd.BUSY ? 1 : 0, ipuRegs.cmd.DATA); break; ipucase(IPU_CTRL): @@ -262,14 +262,14 @@ __fi u64 ipuRead64(u32 mem) break; ipucase(IPU_TOP): // IPU_TOP - IPU_LOG("read64: IPU_TOP=%x, bp = %d", ipuRegs->top, g_BP.BP); + IPU_LOG("read64: IPU_TOP=%x, bp = %d", ipuRegs.top, g_BP.BP); break; default: IPU_LOG("read64: Unknown=%x", mem); break; } - return *(u64*)(((u8*)ipuRegs) + mem); + return psHu64(IPU_CMD + mem); } void ipuSoftReset() @@ -278,10 +278,10 @@ void ipuSoftReset() coded_block_pattern = 0; - ipuRegs->ctrl.reset(); - ipuRegs->top = 0; + ipuRegs.ctrl.reset(); + ipuRegs.top = 0; ipu_cmd.clear(); - ipuRegs->cmd.BUSY = 0; + ipuRegs.cmd.BUSY = 0; g_BP.BP = 0; g_BP.FP = 0; @@ -308,14 +308,14 @@ __fi bool ipuWrite32(u32 mem, u32 value) ipucase(IPU_CTRL): // IPU_CTRL // CTRL = the first 16 bits of ctrl [0x8000ffff], + value for the next 16 bits, // minus the reserved bits. (18-19; 27-29) [0x47f30000] - ipuRegs->ctrl.write(value); - if (ipuRegs->ctrl.IDP == 3) + ipuRegs.ctrl.write(value); + if (ipuRegs.ctrl.IDP == 3) { Console.WriteLn("IPU Invalid Intra DC Precision, switching to 9 bits"); - ipuRegs->ctrl.IDP = 1; + ipuRegs.ctrl.IDP = 1; } - if (ipuRegs->ctrl.RST) ipuSoftReset(); // RESET + if (ipuRegs.ctrl.RST) ipuSoftReset(); // RESET IPU_LOG("write32: IPU_CTRL=0x%08X", value); return false; @@ -357,8 +357,8 @@ static void ipuBCLR(u32 val) g_BP.BP = val & 0x7F; g_BP.FP = 0; //g_BP.bufferhasnew = 0; - ipuRegs->ctrl.BUSY = 0; - ipuRegs->cmd.BUSY = 0; + ipuRegs.ctrl.BUSY = 0; + ipuRegs.cmd.BUSY = 0; memzero(_readbits); IPU_LOG("Clear IPU input FIFO. Set Bit offset=0x%X", g_BP.BP); } @@ -373,14 +373,14 @@ static bool ipuIDEC(u32 val, bool resume) g_BP.BP += idec.FB;//skip FB bits //from IPU_CTRL - ipuRegs->ctrl.PCT = I_TYPE; //Intra DECoding;) + ipuRegs.ctrl.PCT = I_TYPE; //Intra DECoding;) - decoder.coding_type = ipuRegs->ctrl.PCT; - decoder.mpeg1 = ipuRegs->ctrl.MP1; - decoder.q_scale_type = ipuRegs->ctrl.QST; - decoder.intra_vlc_format = ipuRegs->ctrl.IVF; - decoder.scantype = ipuRegs->ctrl.AS; - decoder.intra_dc_precision = ipuRegs->ctrl.IDP; + decoder.coding_type = ipuRegs.ctrl.PCT; + decoder.mpeg1 = ipuRegs.ctrl.MP1; + decoder.q_scale_type = ipuRegs.ctrl.QST; + decoder.intra_vlc_format = ipuRegs.ctrl.IVF; + decoder.scantype = ipuRegs.ctrl.AS; + decoder.intra_dc_precision = ipuRegs.ctrl.IDP; //from IDEC value decoder.quantizer_scale = idec.QSC; @@ -409,11 +409,11 @@ static __fi bool ipuBDEC(u32 val, bool resume) g_BP.BP += bdec.FB;//skip FB bits decoder.coding_type = I_TYPE; - decoder.mpeg1 = ipuRegs->ctrl.MP1; - decoder.q_scale_type = ipuRegs->ctrl.QST; - decoder.intra_vlc_format = ipuRegs->ctrl.IVF; - decoder.scantype = ipuRegs->ctrl.AS; - decoder.intra_dc_precision = ipuRegs->ctrl.IDP; + decoder.mpeg1 = ipuRegs.ctrl.MP1; + decoder.q_scale_type = ipuRegs.ctrl.QST; + decoder.intra_vlc_format = ipuRegs.ctrl.IVF; + decoder.scantype = ipuRegs.ctrl.AS; + decoder.intra_dc_precision = ipuRegs.ctrl.IDP; //from BDEC value decoder.quantizer_scale = decoder.q_scale_type ? non_linear_quantizer_scale [bdec.QSC] : bdec.QSC << 1; @@ -433,7 +433,7 @@ static bool __fastcall ipuVDEC(u32 val) switch (ipu_cmd.pos[0]) { case 0: - ipuRegs->cmd.DATA = 0; + ipuRegs.cmd.DATA = 0; if (!getBits32((u8*)&decoder.bitstream_buf, 0)) return false; decoder.bitstream_bits = -16; @@ -442,22 +442,22 @@ static bool __fastcall ipuVDEC(u32 val) switch ((val >> 26) & 3) { case 0://Macroblock Address Increment - decoder.mpeg1 = ipuRegs->ctrl.MP1; - ipuRegs->cmd.DATA = get_macroblock_address_increment(); + decoder.mpeg1 = ipuRegs.ctrl.MP1; + ipuRegs.cmd.DATA = get_macroblock_address_increment(); break; case 1://Macroblock Type decoder.frame_pred_frame_dct = 1; - decoder.coding_type = ipuRegs->ctrl.PCT; - ipuRegs->cmd.DATA = get_macroblock_modes(); + decoder.coding_type = ipuRegs.ctrl.PCT; + ipuRegs.cmd.DATA = get_macroblock_modes(); break; case 2://Motion Code - ipuRegs->cmd.DATA = get_motion_delta(0); + ipuRegs.cmd.DATA = get_motion_delta(0); break; case 3://DMVector - ipuRegs->cmd.DATA = get_dmv(); + ipuRegs.cmd.DATA = get_dmv(); break; } @@ -469,21 +469,21 @@ static bool __fastcall ipuVDEC(u32 val) ReorderBitstream(); } - ipuRegs->cmd.DATA = (ipuRegs->cmd.DATA & 0xFFFF) | ((decoder.bitstream_bits + 16) << 16); - ipuRegs->ctrl.ECD = (ipuRegs->cmd.DATA == 0); + ipuRegs.cmd.DATA = (ipuRegs.cmd.DATA & 0xFFFF) | ((decoder.bitstream_bits + 16) << 16); + ipuRegs.ctrl.ECD = (ipuRegs.cmd.DATA == 0); case 1: - if (!getBits32((u8*)&ipuRegs->top, 0)) + if (!getBits32((u8*)&ipuRegs.top, 0)) { ipu_cmd.pos[0] = 1; return false; } - BigEndian(ipuRegs->top, ipuRegs->top); + BigEndian(ipuRegs.top, ipuRegs.top); IPU_LOG("VDEC command data 0x%x(0x%x). Skip 0x%X bits/Table=%d (%s), pct %d", - ipuRegs->cmd.DATA, ipuRegs->cmd.DATA >> 16, val & 0x3f, (val >> 26) & 3, (val >> 26) & 1 ? - ((val >> 26) & 2 ? "DMV" : "MBT") : (((val >> 26) & 2 ? "MC" : "MBAI")), ipuRegs->ctrl.PCT); + ipuRegs.cmd.DATA, ipuRegs.cmd.DATA >> 16, val & 0x3f, (val >> 26) & 3, (val >> 26) & 1 ? + ((val >> 26) & 2 ? "DMV" : "MBT") : (((val >> 26) & 2 ? "MC" : "MBAI")), ipuRegs.ctrl.PCT); return true; jNO_DEFAULT @@ -494,12 +494,12 @@ static bool __fastcall ipuVDEC(u32 val) static __fi bool ipuFDEC(u32 val) { - if (!getBits32((u8*)&ipuRegs->cmd.DATA, 0)) return false; + if (!getBits32((u8*)&ipuRegs.cmd.DATA, 0)) return false; - BigEndian(ipuRegs->cmd.DATA, ipuRegs->cmd.DATA); - ipuRegs->top = ipuRegs->cmd.DATA; + BigEndian(ipuRegs.cmd.DATA, ipuRegs.cmd.DATA); + ipuRegs.top = ipuRegs.cmd.DATA; - IPU_LOG("FDEC read: 0x%08x", ipuRegs->top); + IPU_LOG("FDEC read: 0x%08x", ipuRegs.top); return true; } @@ -967,10 +967,10 @@ u8 __fastcall getBits8(u8 *address, u32 advance) void IPUCMD_WRITE(u32 val) { // don't process anything if currently busy - if (ipuRegs->ctrl.BUSY) Console.WriteLn("IPU BUSY!"); // wait for thread + if (ipuRegs.ctrl.BUSY) Console.WriteLn("IPU BUSY!"); // wait for thread - ipuRegs->ctrl.ECD = 0; - ipuRegs->ctrl.SCD = 0; //clear ECD/SCD + ipuRegs.ctrl.ECD = 0; + ipuRegs.ctrl.SCD = 0; //clear ECD/SCD ipu_cmd.clear(); ipu_cmd.current = val; @@ -988,17 +988,17 @@ void IPUCMD_WRITE(u32 val) // check if enough data in queue if (ipuVDEC(val)) return; - ipuRegs->cmd.BUSY = 0x80000000; - ipuRegs->topbusy = 0x80000000; + ipuRegs.cmd.BUSY = 0x80000000; + ipuRegs.topbusy = 0x80000000; break; case SCE_IPU_FDEC: - IPU_LOG("FDEC command. Skip 0x%X bits, FIFO 0x%X qwords, BP 0x%X, FP %d, CHCR 0x%x, %x", - val & 0x3f, g_BP.IFC, (int)g_BP.BP, g_BP.FP, ipu1dma->chcr._u32, cpuRegs.pc); + IPU_LOG("FDEC command. Skip 0x%X bits, FIFO 0x%X qwords, BP 0x%X, FP %d, CHCR 0x%x", + val & 0x3f, g_BP.IFC, (int)g_BP.BP, g_BP.FP, ipu1dma.chcr._u32); g_BP.BP += val & 0x3F; if (ipuFDEC(val)) return; - ipuRegs->cmd.BUSY = 0x80000000; - ipuRegs->topbusy = 0x80000000; + ipuRegs.cmd.BUSY = 0x80000000; + ipuRegs.topbusy = 0x80000000; break; case SCE_IPU_SETTH: @@ -1042,58 +1042,58 @@ void IPUCMD_WRITE(u32 val) return; } - ipuRegs->topbusy = 0x80000000; + ipuRegs.topbusy = 0x80000000; break; case SCE_IPU_BDEC: if (ipuBDEC(val, false)) { IPU_INT0_FROM(); - if (ipuRegs->ctrl.SCD || ipuRegs->ctrl.ECD) hwIntcIrq(INTC_IPU); + if (ipuRegs.ctrl.SCD || ipuRegs.ctrl.ECD) hwIntcIrq(INTC_IPU); return; } else { - ipuRegs->topbusy = 0x80000000; + ipuRegs.topbusy = 0x80000000; } break; } // have to resort to the thread - ipuRegs->ctrl.BUSY = 1; - if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU); + ipuRegs.ctrl.BUSY = 1; + if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU); } void IPUWorker() { - pxAssert(ipuRegs->ctrl.BUSY); + pxAssert(ipuRegs.ctrl.BUSY); switch (ipu_cmd.CMD) { case SCE_IPU_VDEC: if (!ipuVDEC(ipu_cmd.current)) { - if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU); + if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU); return; } - ipuRegs->cmd.BUSY = 0; - ipuRegs->topbusy = 0; + ipuRegs.cmd.BUSY = 0; + ipuRegs.topbusy = 0; break; case SCE_IPU_FDEC: if (!ipuFDEC(ipu_cmd.current)) { - if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU); + if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU); return; } - ipuRegs->cmd.BUSY = 0; - ipuRegs->topbusy = 0; + ipuRegs.cmd.BUSY = 0; + ipuRegs.topbusy = 0; break; case SCE_IPU_SETIQ: if (!ipuSETIQ(ipu_cmd.current)) { - if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU); + if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU); return; } break; @@ -1101,7 +1101,7 @@ void IPUWorker() case SCE_IPU_SETVQ: if (!ipuSETVQ(ipu_cmd.current)) { - if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU); + if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU); return; } break; @@ -1109,7 +1109,7 @@ void IPUWorker() case SCE_IPU_CSC: if (!ipuCSC(ipu_cmd.current)) { - if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU); + if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU); return; } IPU_INT0_FROM(); @@ -1118,7 +1118,7 @@ void IPUWorker() case SCE_IPU_PACK: if (!ipuPACK(ipu_cmd.current)) { - if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU); + if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU); return; } break; @@ -1126,14 +1126,14 @@ void IPUWorker() case SCE_IPU_IDEC: if (!ipuIDEC(ipu_cmd.current, true)) { - if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU); + if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU); return; } - ipuRegs->ctrl.OFC = 0; - ipuRegs->ctrl.BUSY = 0; - ipuRegs->topbusy = 0; - ipuRegs->cmd.BUSY = 0; + ipuRegs.ctrl.OFC = 0; + ipuRegs.ctrl.BUSY = 0; + ipuRegs.topbusy = 0; + ipuRegs.cmd.BUSY = 0; ipu_cmd.current = 0xffffffff; // CHECK!: IPU0dma remains when IDEC is done, so we need to clear it @@ -1143,17 +1143,17 @@ void IPUWorker() case SCE_IPU_BDEC: if (!ipuBDEC(ipu_cmd.current, true)) { - if(ipu1dma->chcr.STR == false) hwIntcIrq(INTC_IPU); + if(ipu1dma.chcr.STR == false) hwIntcIrq(INTC_IPU); return; } - ipuRegs->ctrl.BUSY = 0; - ipuRegs->topbusy = 0; - ipuRegs->cmd.BUSY = 0; + ipuRegs.ctrl.BUSY = 0; + ipuRegs.topbusy = 0; + ipuRegs.cmd.BUSY = 0; ipu_cmd.current = 0xffffffff; IPU_INT0_FROM(); - if (ipuRegs->ctrl.SCD || ipuRegs->ctrl.ECD) hwIntcIrq(INTC_IPU); + if (ipuRegs.ctrl.SCD || ipuRegs.ctrl.ECD) hwIntcIrq(INTC_IPU); return; default: @@ -1162,6 +1162,6 @@ void IPUWorker() } // success - ipuRegs->ctrl.BUSY = 0; + ipuRegs.ctrl.BUSY = 0; ipu_cmd.current = 0xffffffff; } diff --git a/pcsx2/IPU/IPU.h b/pcsx2/IPU/IPU.h index 1afb8beb6d..e33c211b3e 100644 --- a/pcsx2/IPU/IPU.h +++ b/pcsx2/IPU/IPU.h @@ -176,8 +176,6 @@ struct IPUregisters { u32 dummy3[2]; }; -#define ipuRegs ((IPUregisters*)(&eeHw[0x2000])) - struct tIPU_cmd { int index; @@ -202,6 +200,8 @@ struct tIPU_cmd } }; +static IPUregisters& ipuRegs = (IPUregisters&)eeHw[0x2000]; + extern tIPU_cmd ipu_cmd; extern int coded_block_pattern; diff --git a/pcsx2/IPU/IPU_Fifo.cpp b/pcsx2/IPU/IPU_Fifo.cpp index 85a8776f03..2c2902cf6f 100644 --- a/pcsx2/IPU/IPU_Fifo.cpp +++ b/pcsx2/IPU/IPU_Fifo.cpp @@ -36,7 +36,7 @@ void IPU_Fifo_Input::clear() { memzero(data); g_BP.IFC = 0; - ipuRegs->ctrl.IFC = 0; + ipuRegs.ctrl.IFC = 0; readpos = 0; writepos = 0; } @@ -44,7 +44,7 @@ void IPU_Fifo_Input::clear() void IPU_Fifo_Output::clear() { memzero(data); - ipuRegs->ctrl.OFC = 0; + ipuRegs.ctrl.OFC = 0; readpos = 0; writepos = 0; } @@ -90,9 +90,9 @@ int IPU_Fifo_Output::write(const u32 *value, int size) { int transsize, firsttrans; - if ((int)ipuRegs->ctrl.OFC >= 8) IPU0dma(); + if ((int)ipuRegs.ctrl.OFC >= 8) IPU0dma(); - transsize = min(size, 8 - (int)ipuRegs->ctrl.OFC); + transsize = min(size, 8 - (int)ipuRegs.ctrl.OFC); firsttrans = transsize; while (transsize-- > 0) @@ -105,7 +105,7 @@ int IPU_Fifo_Output::write(const u32 *value, int size) value += 4; } - ipuRegs->ctrl.OFC += firsttrans; + ipuRegs.ctrl.OFC += firsttrans; IPU0dma(); return firsttrans; @@ -151,7 +151,7 @@ void IPU_Fifo_Output::_readsingle(void *value) void IPU_Fifo_Output::read(void *value, int size) { - ipuRegs->ctrl.OFC -= size; + ipuRegs.ctrl.OFC -= size; while (size > 0) { _readsingle(value); @@ -162,9 +162,9 @@ void IPU_Fifo_Output::read(void *value, int size) void IPU_Fifo_Output::readsingle(void *value) { - if (ipuRegs->ctrl.OFC > 0) + if (ipuRegs.ctrl.OFC > 0) { - ipuRegs->ctrl.OFC--; + ipuRegs.ctrl.OFC--; _readsingle(value); } } diff --git a/pcsx2/IPU/IPUdma.cpp b/pcsx2/IPU/IPUdma.cpp index 9870934add..f44b1b09b8 100644 --- a/pcsx2/IPU/IPUdma.cpp +++ b/pcsx2/IPU/IPUdma.cpp @@ -1,509 +1,509 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2002-2010 PCSX2 Dev Team - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 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 PCSX2. - * If not, see . - */ - -#include "PrecompiledHeader.h" -#include "Common.h" -#include "IPU.h" -#include "IPU/IPUdma.h" -#include "mpeg2lib/Mpeg.h" - -#include "Vif.h" -#include "Gif.h" -#include "Vif_Dma.h" - -static IPUStatus IPU1Status; -static tIPU_DMA g_nDMATransfer; - -void ipuDmaReset() -{ - IPU1Status.InProgress = false; - IPU1Status.DMAMode = DMA_MODE_NORMAL; - IPU1Status.DMAFinished = true; - - g_nDMATransfer.reset(); -} - -void SaveStateBase::ipuDmaFreeze() -{ - FreezeTag( "IPUdma" ); - Freeze(g_nDMATransfer); - Freeze(IPU1Status); -} - -static __fi bool ipuDmacPartialChain(tDMA_TAG tag) -{ - switch (tag.ID) - { - case TAG_REFE: // refe - ipu1dma->tadr += 16; - return true; - - case TAG_END: // end - ipu1dma->tadr = ipu1dma->madr; - return true; - } - return false; -} - -static __fi void ipuDmacSrcChain() -{ - switch (IPU1Status.ChainMode) - { - case TAG_REFE: // refe - //if(IPU1Status.InProgress == false) ipu1dma->tadr += 16; - IPU1Status.DMAFinished = true; - break; - case TAG_CNT: // cnt - // Set the taddr to the next tag - ipu1dma->tadr = ipu1dma->madr; - //if(IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = false; - break; - - case TAG_NEXT: // next - ipu1dma->tadr = IPU1Status.NextMem; - //if(IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = false; - break; - - case TAG_REF: // ref - //if(IPU1Status.InProgress == false)ipu1dma->tadr += 16; - //if(IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = false; - break; - - case TAG_END: // end - ipu1dma->tadr = ipu1dma->madr; - IPU1Status.DMAFinished = true; - break; - } -} - -static __fi bool WaitGSPaths() -{ - if(CHECK_IPUWAITHACK) - { - if(GSTransferStatus.PTH3 < STOPPED_MODE && GSTransferStatus.PTH3 != IDLE_MODE) - { - //GIF_LOG("Flushing gif chcr %x tadr %x madr %x qwc %x", gif->chcr._u32, gif->tadr, gif->madr, gif->qwc); - //DevCon.WriteLn("Waiting for GIF"); - return false; - } - - if(GSTransferStatus.PTH2 != STOPPED_MODE) - { - //DevCon.WriteLn("Waiting for VIF"); - return false; - } - if(GSTransferStatus.PTH1 != STOPPED_MODE) - { - //DevCon.WriteLn("Waiting for VU"); - return false; - } - } - return true; -} - -static __fi int IPU1chain() { - - int totalqwc = 0; - - if (ipu1dma->qwc > 0 && IPU1Status.InProgress == true) - { - int qwc = ipu1dma->qwc; - u32 *pMem; - - pMem = (u32*)dmaGetAddr(ipu1dma->madr, false); - - if (pMem == NULL) - { - Console.Error("ipu1dma NULL!"); - return totalqwc; - } - - //Write our data to the fifo - qwc = ipu_fifo.in.write(pMem, qwc); - ipu1dma->madr += qwc << 4; - ipu1dma->qwc -= qwc; - totalqwc += qwc; - } - if( ipu1dma->qwc == 0) - { - //Update TADR etc - if(IPU1Status.DMAMode == DMA_MODE_CHAIN) ipuDmacSrcChain(); - //If the transfer has finished or we have room in the FIFO, schedule to the interrupt code. - - //No data left - IPU1Status.InProgress = false; - } //If we still have data the commands should pull this across when need be. - - return totalqwc; -} - -//static __fi bool WaitGSPaths() -//{ -// //Wait for all GS paths to be clear -// if (GSTransferStatus._u32 != 0x2a) -// { -// if(GSTransferStatus.PTH3 != STOPPED_MODE && vif1Regs.mskpath3) return true; -// IPU_LOG("Waiting for GS transfers to finish %x", GSTransferStatus._u32); -// IPU_INT_TO(4); -// return false; -// } -// return true; -//} - - - -int IPU1dma() -{ - int ipu1cycles = 0; - int totalqwc = 0; - - //We need to make sure GIF has flushed before sending IPU data, it seems to REALLY screw FFX videos - //if(!WaitGSPaths()) return totalqwc; - - if(ipu1dma->chcr.STR == false || IPU1Status.DMAMode == 2) - { - //We MUST stop the IPU from trying to fill the FIFO with more data if the DMA has been suspended - //if we don't, we risk causing the data to go out of sync with the fifo and we end up losing some! - //This is true for Dragons Quest 8 and probably others which suspend the DMA. - DevCon.Warning("IPU1 running when IPU1 DMA disabled! CHCR %x QWC %x", ipu1dma->chcr._u32, ipu1dma->qwc); - return 0; - } - - IPU_LOG("IPU1 DMA Called QWC %x Finished %d In Progress %d tadr %x", ipu1dma->qwc, IPU1Status.DMAFinished, IPU1Status.InProgress, ipu1dma->tadr); - - switch(IPU1Status.DMAMode) - { - case DMA_MODE_NORMAL: - { - if(!WaitGSPaths()) - { // legacy WaitGSPaths() for now - IPU_INT_TO(4); //Give it a short wait. - return totalqwc; - } - IPU_LOG("Processing Normal QWC left %x Finished %d In Progress %d", ipu1dma->qwc, IPU1Status.DMAFinished, IPU1Status.InProgress); - if(IPU1Status.InProgress == true) totalqwc += IPU1chain(); - } - break; - - case DMA_MODE_CHAIN: - { - if(IPU1Status.InProgress == true) //No transfer is ready to go so we need to set one up - { - if(!WaitGSPaths()) - { // legacy WaitGSPaths() for now - IPU_INT_TO(4); //Give it a short wait. - return totalqwc; - } - IPU_LOG("Processing Chain QWC left %x Finished %d In Progress %d", ipu1dma->qwc, IPU1Status.DMAFinished, IPU1Status.InProgress); - totalqwc += IPU1chain(); - //Set the TADR forward - } - - - if(IPU1Status.InProgress == false && IPU1Status.DMAFinished == false) //No transfer is ready to go so we need to set one up - { - tDMA_TAG* ptag = dmaGetAddr(ipu1dma->tadr, false); //Set memory pointer to TADR - - if (!ipu1dma->transfer("IPU1", ptag)) - { - return totalqwc; - } - - ipu1cycles += 1; // Add 1 cycles from the QW read for the tag - IPU1Status.ChainMode = ptag->ID; - - if(ipu1dma->chcr.TTE) DevCon.Warning("TTE?"); - - switch (IPU1Status.ChainMode) - { - case TAG_REFE: // refe - // do not change tadr - //ipu1dma->tadr += 16; - ipu1dma->tadr += 16; - ipu1dma->madr = ptag[1]._u32; - IPU_LOG("Tag should end on %x", ipu1dma->tadr); - - break; - - case TAG_CNT: // cnt - ipu1dma->madr = ipu1dma->tadr + 16; - IPU_LOG("Tag should end on %x", ipu1dma->madr + ipu1dma->qwc * 16); - //ipu1dma->tadr = ipu1dma->madr + (ipu1dma->qwc * 16); - // Set the taddr to the next tag - //IPU1Status.DMAFinished = false; - break; - - case TAG_NEXT: // next - ipu1dma->madr = ipu1dma->tadr + 16; - IPU1Status.NextMem = ptag[1]._u32; - IPU_LOG("Tag should end on %x", IPU1Status.NextMem); - //IPU1Status.DMAFinished = false; - break; - - case TAG_REF: // ref - ipu1dma->madr = ptag[1]._u32; - ipu1dma->tadr += 16; - IPU_LOG("Tag should end on %x", ipu1dma->tadr); - //IPU1Status.DMAFinished = false; - break; - - case TAG_END: // end - // do not change tadr - ipu1dma->madr = ipu1dma->tadr + 16; - ipu1dma->tadr += 16; - IPU_LOG("Tag should end on %x", ipu1dma->madr + ipu1dma->qwc * 16); - - break; - - default: - Console.Error("IPU ERROR: different transfer mode!, Please report to PCSX2 Team"); - break; - } - - //if(ipu1dma->qwc == 0) Console.Warning("Blank QWC!"); - if(ipu1dma->qwc > 0) IPU1Status.InProgress = true; - IPU_LOG("dmaIPU1 dmaChain %8.8x_%8.8x size=%d, addr=%lx, fifosize=%x", - ptag[1]._u32, ptag[0]._u32, ipu1dma->qwc, ipu1dma->madr, 8 - g_BP.IFC); - - if (ipu1dma->chcr.TIE && ptag->IRQ) //Tag Interrupt is set, so schedule the end/interrupt - IPU1Status.DMAFinished = true; - - - if(!WaitGSPaths() && ipu1dma->qwc > 0) - { // legacy WaitGSPaths() for now - IPU_INT_TO(4); //Give it a short wait. - return totalqwc; - } - IPU_LOG("Processing Start Chain QWC left %x Finished %d In Progress %d", ipu1dma->qwc, IPU1Status.DMAFinished, IPU1Status.InProgress); - totalqwc += IPU1chain(); - //Set the TADR forward - } - - } - break; - } - - //Do this here to prevent double settings on Chain DMA's - if(totalqwc > 0 || ipu1dma->qwc == 0) - { - IPU_INT_TO(totalqwc * BIAS); - IPUProcessInterrupt(); - } - else - { - cpuRegs.eCycle[4] = 0x9999;//IPU_INT_TO(2048); - } - - IPU_LOG("Completed Call IPU1 DMA QWC Remaining %x Finished %d In Progress %d tadr %x", ipu1dma->qwc, IPU1Status.DMAFinished, IPU1Status.InProgress, ipu1dma->tadr); - return totalqwc; -} - -int IPU0dma() -{ - int readsize; - static int totalsize = 0; - tDMA_TAG* pMem; - - if ((!(ipu0dma->chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_FROM_IPU))) || (ipu0dma->qwc == 0)) - return 0; - - pxAssert(!(ipu0dma->chcr.TTE)); - - IPU_LOG("dmaIPU0 chcr = %lx, madr = %lx, qwc = %lx", - ipu0dma->chcr._u32, ipu0dma->madr, ipu0dma->qwc); - - pxAssert(ipu0dma->chcr.MOD == NORMAL_MODE); - - pMem = dmaGetAddr(ipu0dma->madr, true); - - readsize = min(ipu0dma->qwc, (u16)ipuRegs->ctrl.OFC); - totalsize+=readsize; - ipu_fifo.out.read(pMem, readsize); - - ipu0dma->madr += readsize << 4; - ipu0dma->qwc -= readsize; // note: qwc is u16 - - if (ipu0dma->qwc == 0) - { - if (dmacRegs.ctrl.STS == STS_fromIPU) // STS == fromIPU - { - dmacRegs.stadr.ADDR = ipu0dma->madr; - switch (dmacRegs.ctrl.STD) - { - case NO_STD: - break; - case STD_GIF: // GIF - Console.Warning("GIFSTALL"); - g_nDMATransfer.GIFSTALL = true; - break; - case STD_VIF1: // VIF - Console.Warning("VIFSTALL"); - g_nDMATransfer.VIFSTALL = true; - break; - case STD_SIF1: - Console.Warning("SIFSTALL"); - g_nDMATransfer.SIFSTALL = true; - break; - } - } - //Fixme ( voodoocycles ): - //This was IPU_INT_FROM(readsize*BIAS ); - //This broke vids in Digital Devil Saga - //Note that interrupting based on totalsize is just guessing.. - IPU_INT_FROM( readsize * BIAS ); - totalsize = 0; - } - - return readsize; -} - -__fi void dmaIPU0() // fromIPU -{ - if (ipu0dma->pad != 0) - { - // Note: pad is the padding right above qwc, so we're testing whether qwc - // has overflowed into pad. - DevCon.Warning(L"IPU0dma's upper 16 bits set to %x", ipu0dma->pad); - ipu0dma->qwc = ipu0dma->pad = 0; - //If we are going to clear down IPU0, we should end it too. Going to test this scenario on the PS2 mind - Refraction - ipu0dma->chcr.STR = false; - hwDmacIrq(DMAC_FROM_IPU); - } - IPUProcessInterrupt(); -} - -__fi void dmaIPU1() // toIPU -{ - IPU_LOG("IPU1DMAStart QWC %x, MADR %x, CHCR %x, TADR %x", ipu1dma->qwc, ipu1dma->madr, ipu1dma->chcr._u32, ipu1dma->tadr); - - if (ipu1dma->pad != 0) - { - // Note: pad is the padding right above qwc, so we're testing whether qwc - // has overflowed into pad. - DevCon.Warning(L"IPU1dma's upper 16 bits set to %x\n", ipu1dma->pad); - ipu1dma->qwc = ipu1dma->pad = 0; - // If we are going to clear down IPU1, we should end it too. - // Going to test this scenario on the PS2 mind - Refraction - ipu1dma->chcr.STR = false; - hwDmacIrq(DMAC_TO_IPU); - } - - if (ipu1dma->chcr.MOD == CHAIN_MODE) //Chain Mode - { - IPU_LOG("Setting up IPU1 Chain mode"); - if(ipu1dma->qwc == 0) - { - IPU1Status.InProgress = false; - IPU1Status.DMAFinished = false; - } - else - { //Attempting to continue a previous chain - IPU_LOG("Resuming DMA TAG %x", (ipu1dma->chcr.TAG >> 12)); - //We MUST check the CHCR for the tag it last knew, it can be manipulated! - IPU1Status.ChainMode = (ipu1dma->chcr.TAG >> 12) & 0x7; - IPU1Status.InProgress = true; - IPU1Status.DMAFinished = ((ipu1dma->chcr.TAG >> 15) && ipu1dma->chcr.TIE) ? true : false; - } - - IPU1Status.DMAMode = DMA_MODE_CHAIN; - IPU1dma(); - } - else //Normal Mode - { - if(ipu1dma->qwc == 0) - { - ipu1dma->chcr.STR = false; - // Hack to force stop IPU - ipuRegs->cmd.BUSY = 0; - ipuRegs->ctrl.BUSY = 0; - ipuRegs->topbusy = 0; - // - hwDmacIrq(DMAC_TO_IPU); - Console.Warning("IPU1 Normal error!"); - } - else - { - IPU_LOG("Setting up IPU1 Normal mode"); - IPU1Status.InProgress = true; - IPU1Status.DMAFinished = true; - IPU1Status.DMAMode = DMA_MODE_NORMAL; - IPU1dma(); - } - } -} - -extern void GIFdma(); - -void ipu0Interrupt() -{ - IPU_LOG("ipu0Interrupt: %x", cpuRegs.cycle); - - if (g_nDMATransfer.FIREINT0) - { - g_nDMATransfer.FIREINT0 = false; - hwIntcIrq(INTC_IPU); - } - - if (g_nDMATransfer.GIFSTALL) - { - // gif - Console.Warning("IPU GIF Stall"); - g_nDMATransfer.GIFSTALL = false; - //if (gif->chcr.STR) GIFdma(); - } - - if (g_nDMATransfer.VIFSTALL) - { - // vif - Console.Warning("IPU VIF Stall"); - g_nDMATransfer.VIFSTALL = false; - //if (vif1ch.chcr.STR) dmaVIF1(); - } - - if (g_nDMATransfer.SIFSTALL) - { - // sif - Console.Warning("IPU SIF Stall"); - g_nDMATransfer.SIFSTALL = false; - - // Not totally sure whether this needs to be done or not, so I'm - // leaving it commented out for the moment. - //if (sif1dma->chcr.STR) SIF1Dma(); - } - - if (g_nDMATransfer.TIE0) - { - g_nDMATransfer.TIE0 = false; - } - - ipu0dma->chcr.STR = false; - hwDmacIrq(DMAC_FROM_IPU); -} - -IPU_FORCEINLINE void ipu1Interrupt() -{ - IPU_LOG("ipu1Interrupt %x:", cpuRegs.cycle); - - if(IPU1Status.DMAFinished == false || IPU1Status.InProgress == true) //Sanity Check - { - IPU1dma(); - return; - } - - IPU_LOG("ipu1 finish %x:", cpuRegs.cycle); - ipu1dma->chcr.STR = false; - IPU1Status.DMAMode = 2; - hwDmacIrq(DMAC_TO_IPU); -} +/* PCSX2 - PS2 Emulator for PCs + * Copyright (C) 2002-2010 PCSX2 Dev Team + * + * PCSX2 is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * PCSX2 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 PCSX2. + * If not, see . + */ + +#include "PrecompiledHeader.h" +#include "Common.h" +#include "IPU.h" +#include "IPU/IPUdma.h" +#include "mpeg2lib/Mpeg.h" + +#include "Vif.h" +#include "Gif.h" +#include "Vif_Dma.h" + +static IPUStatus IPU1Status; +static tIPU_DMA g_nDMATransfer; + +void ipuDmaReset() +{ + IPU1Status.InProgress = false; + IPU1Status.DMAMode = DMA_MODE_NORMAL; + IPU1Status.DMAFinished = true; + + g_nDMATransfer.reset(); +} + +void SaveStateBase::ipuDmaFreeze() +{ + FreezeTag( "IPUdma" ); + Freeze(g_nDMATransfer); + Freeze(IPU1Status); +} + +static __fi bool ipuDmacPartialChain(tDMA_TAG tag) +{ + switch (tag.ID) + { + case TAG_REFE: // refe + ipu1dma.tadr += 16; + return true; + + case TAG_END: // end + ipu1dma.tadr = ipu1dma.madr; + return true; + } + return false; +} + +static __fi void ipuDmacSrcChain() +{ + switch (IPU1Status.ChainMode) + { + case TAG_REFE: // refe + //if(IPU1Status.InProgress == false) ipu1dma.tadr += 16; + IPU1Status.DMAFinished = true; + break; + case TAG_CNT: // cnt + // Set the taddr to the next tag + ipu1dma.tadr = ipu1dma.madr; + //if(IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = false; + break; + + case TAG_NEXT: // next + ipu1dma.tadr = IPU1Status.NextMem; + //if(IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = false; + break; + + case TAG_REF: // ref + //if(IPU1Status.InProgress == false)ipu1dma.tadr += 16; + //if(IPU1Status.DMAFinished == false) IPU1Status.DMAFinished = false; + break; + + case TAG_END: // end + ipu1dma.tadr = ipu1dma.madr; + IPU1Status.DMAFinished = true; + break; + } +} + +static __fi bool WaitGSPaths() +{ + if(CHECK_IPUWAITHACK) + { + if(GSTransferStatus.PTH3 < STOPPED_MODE && GSTransferStatus.PTH3 != IDLE_MODE) + { + //GIF_LOG("Flushing gif chcr %x tadr %x madr %x qwc %x", gif->chcr._u32, gif->tadr, gif->madr, gif->qwc); + //DevCon.WriteLn("Waiting for GIF"); + return false; + } + + if(GSTransferStatus.PTH2 != STOPPED_MODE) + { + //DevCon.WriteLn("Waiting for VIF"); + return false; + } + if(GSTransferStatus.PTH1 != STOPPED_MODE) + { + //DevCon.WriteLn("Waiting for VU"); + return false; + } + } + return true; +} + +static __fi int IPU1chain() { + + int totalqwc = 0; + + if (ipu1dma.qwc > 0 && IPU1Status.InProgress == true) + { + int qwc = ipu1dma.qwc; + u32 *pMem; + + pMem = (u32*)dmaGetAddr(ipu1dma.madr, false); + + if (pMem == NULL) + { + Console.Error("ipu1dma NULL!"); + return totalqwc; + } + + //Write our data to the fifo + qwc = ipu_fifo.in.write(pMem, qwc); + ipu1dma.madr += qwc << 4; + ipu1dma.qwc -= qwc; + totalqwc += qwc; + } + if( ipu1dma.qwc == 0) + { + //Update TADR etc + if(IPU1Status.DMAMode == DMA_MODE_CHAIN) ipuDmacSrcChain(); + //If the transfer has finished or we have room in the FIFO, schedule to the interrupt code. + + //No data left + IPU1Status.InProgress = false; + } //If we still have data the commands should pull this across when need be. + + return totalqwc; +} + +//static __fi bool WaitGSPaths() +//{ +// //Wait for all GS paths to be clear +// if (GSTransferStatus._u32 != 0x2a) +// { +// if(GSTransferStatus.PTH3 != STOPPED_MODE && vif1Regs.mskpath3) return true; +// IPU_LOG("Waiting for GS transfers to finish %x", GSTransferStatus._u32); +// IPU_INT_TO(4); +// return false; +// } +// return true; +//} + + + +int IPU1dma() +{ + int ipu1cycles = 0; + int totalqwc = 0; + + //We need to make sure GIF has flushed before sending IPU data, it seems to REALLY screw FFX videos + //if(!WaitGSPaths()) return totalqwc; + + if(ipu1dma.chcr.STR == false || IPU1Status.DMAMode == 2) + { + //We MUST stop the IPU from trying to fill the FIFO with more data if the DMA has been suspended + //if we don't, we risk causing the data to go out of sync with the fifo and we end up losing some! + //This is true for Dragons Quest 8 and probably others which suspend the DMA. + DevCon.Warning("IPU1 running when IPU1 DMA disabled! CHCR %x QWC %x", ipu1dma.chcr._u32, ipu1dma.qwc); + return 0; + } + + IPU_LOG("IPU1 DMA Called QWC %x Finished %d In Progress %d tadr %x", ipu1dma.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress, ipu1dma.tadr); + + switch(IPU1Status.DMAMode) + { + case DMA_MODE_NORMAL: + { + if(!WaitGSPaths()) + { // legacy WaitGSPaths() for now + IPU_INT_TO(4); //Give it a short wait. + return totalqwc; + } + IPU_LOG("Processing Normal QWC left %x Finished %d In Progress %d", ipu1dma.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress); + if(IPU1Status.InProgress == true) totalqwc += IPU1chain(); + } + break; + + case DMA_MODE_CHAIN: + { + if(IPU1Status.InProgress == true) //No transfer is ready to go so we need to set one up + { + if(!WaitGSPaths()) + { // legacy WaitGSPaths() for now + IPU_INT_TO(4); //Give it a short wait. + return totalqwc; + } + IPU_LOG("Processing Chain QWC left %x Finished %d In Progress %d", ipu1dma.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress); + totalqwc += IPU1chain(); + //Set the TADR forward + } + + + if(IPU1Status.InProgress == false && IPU1Status.DMAFinished == false) //No transfer is ready to go so we need to set one up + { + tDMA_TAG* ptag = dmaGetAddr(ipu1dma.tadr, false); //Set memory pointer to TADR + + if (!ipu1dma.transfer("IPU1", ptag)) + { + return totalqwc; + } + + ipu1cycles += 1; // Add 1 cycles from the QW read for the tag + IPU1Status.ChainMode = ptag->ID; + + if(ipu1dma.chcr.TTE) DevCon.Warning("TTE?"); + + switch (IPU1Status.ChainMode) + { + case TAG_REFE: // refe + // do not change tadr + //ipu1dma.tadr += 16; + ipu1dma.tadr += 16; + ipu1dma.madr = ptag[1]._u32; + IPU_LOG("Tag should end on %x", ipu1dma.tadr); + + break; + + case TAG_CNT: // cnt + ipu1dma.madr = ipu1dma.tadr + 16; + IPU_LOG("Tag should end on %x", ipu1dma.madr + ipu1dma.qwc * 16); + //ipu1dma.tadr = ipu1dma.madr + (ipu1dma.qwc * 16); + // Set the taddr to the next tag + //IPU1Status.DMAFinished = false; + break; + + case TAG_NEXT: // next + ipu1dma.madr = ipu1dma.tadr + 16; + IPU1Status.NextMem = ptag[1]._u32; + IPU_LOG("Tag should end on %x", IPU1Status.NextMem); + //IPU1Status.DMAFinished = false; + break; + + case TAG_REF: // ref + ipu1dma.madr = ptag[1]._u32; + ipu1dma.tadr += 16; + IPU_LOG("Tag should end on %x", ipu1dma.tadr); + //IPU1Status.DMAFinished = false; + break; + + case TAG_END: // end + // do not change tadr + ipu1dma.madr = ipu1dma.tadr + 16; + ipu1dma.tadr += 16; + IPU_LOG("Tag should end on %x", ipu1dma.madr + ipu1dma.qwc * 16); + + break; + + default: + Console.Error("IPU ERROR: different transfer mode!, Please report to PCSX2 Team"); + break; + } + + //if(ipu1dma.qwc == 0) Console.Warning("Blank QWC!"); + if(ipu1dma.qwc > 0) IPU1Status.InProgress = true; + IPU_LOG("dmaIPU1 dmaChain %8.8x_%8.8x size=%d, addr=%lx, fifosize=%x", + ptag[1]._u32, ptag[0]._u32, ipu1dma.qwc, ipu1dma.madr, 8 - g_BP.IFC); + + if (ipu1dma.chcr.TIE && ptag->IRQ) //Tag Interrupt is set, so schedule the end/interrupt + IPU1Status.DMAFinished = true; + + + if(!WaitGSPaths() && ipu1dma.qwc > 0) + { // legacy WaitGSPaths() for now + IPU_INT_TO(4); //Give it a short wait. + return totalqwc; + } + IPU_LOG("Processing Start Chain QWC left %x Finished %d In Progress %d", ipu1dma.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress); + totalqwc += IPU1chain(); + //Set the TADR forward + } + + } + break; + } + + //Do this here to prevent double settings on Chain DMA's + if(totalqwc > 0 || ipu1dma.qwc == 0) + { + IPU_INT_TO(totalqwc * BIAS); + IPUProcessInterrupt(); + } + else + { + cpuRegs.eCycle[4] = 0x9999;//IPU_INT_TO(2048); + } + + IPU_LOG("Completed Call IPU1 DMA QWC Remaining %x Finished %d In Progress %d tadr %x", ipu1dma.qwc, IPU1Status.DMAFinished, IPU1Status.InProgress, ipu1dma.tadr); + return totalqwc; +} + +int IPU0dma() +{ + int readsize; + static int totalsize = 0; + tDMA_TAG* pMem; + + if ((!(ipu0dma.chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_FROM_IPU))) || (ipu0dma.qwc == 0)) + return 0; + + pxAssert(!(ipu0dma.chcr.TTE)); + + IPU_LOG("dmaIPU0 chcr = %lx, madr = %lx, qwc = %lx", + ipu0dma.chcr._u32, ipu0dma.madr, ipu0dma.qwc); + + pxAssert(ipu0dma.chcr.MOD == NORMAL_MODE); + + pMem = dmaGetAddr(ipu0dma.madr, true); + + readsize = min(ipu0dma.qwc, (u16)ipuRegs.ctrl.OFC); + totalsize+=readsize; + ipu_fifo.out.read(pMem, readsize); + + ipu0dma.madr += readsize << 4; + ipu0dma.qwc -= readsize; // note: qwc is u16 + + if (ipu0dma.qwc == 0) + { + if (dmacRegs.ctrl.STS == STS_fromIPU) // STS == fromIPU + { + dmacRegs.stadr.ADDR = ipu0dma.madr; + switch (dmacRegs.ctrl.STD) + { + case NO_STD: + break; + case STD_GIF: // GIF + Console.Warning("GIFSTALL"); + g_nDMATransfer.GIFSTALL = true; + break; + case STD_VIF1: // VIF + Console.Warning("VIFSTALL"); + g_nDMATransfer.VIFSTALL = true; + break; + case STD_SIF1: + Console.Warning("SIFSTALL"); + g_nDMATransfer.SIFSTALL = true; + break; + } + } + //Fixme ( voodoocycles ): + //This was IPU_INT_FROM(readsize*BIAS ); + //This broke vids in Digital Devil Saga + //Note that interrupting based on totalsize is just guessing.. + IPU_INT_FROM( readsize * BIAS ); + totalsize = 0; + } + + return readsize; +} + +__fi void dmaIPU0() // fromIPU +{ + if (ipu0dma.pad != 0) + { + // Note: pad is the padding right above qwc, so we're testing whether qwc + // has overflowed into pad. + DevCon.Warning(L"IPU0dma's upper 16 bits set to %x", ipu0dma.pad); + ipu0dma.qwc = ipu0dma.pad = 0; + //If we are going to clear down IPU0, we should end it too. Going to test this scenario on the PS2 mind - Refraction + ipu0dma.chcr.STR = false; + hwDmacIrq(DMAC_FROM_IPU); + } + IPUProcessInterrupt(); +} + +__fi void dmaIPU1() // toIPU +{ + IPU_LOG("IPU1DMAStart QWC %x, MADR %x, CHCR %x, TADR %x", ipu1dma.qwc, ipu1dma.madr, ipu1dma.chcr._u32, ipu1dma.tadr); + + if (ipu1dma.pad != 0) + { + // Note: pad is the padding right above qwc, so we're testing whether qwc + // has overflowed into pad. + DevCon.Warning(L"IPU1dma's upper 16 bits set to %x\n", ipu1dma.pad); + ipu1dma.qwc = ipu1dma.pad = 0; + // If we are going to clear down IPU1, we should end it too. + // Going to test this scenario on the PS2 mind - Refraction + ipu1dma.chcr.STR = false; + hwDmacIrq(DMAC_TO_IPU); + } + + if (ipu1dma.chcr.MOD == CHAIN_MODE) //Chain Mode + { + IPU_LOG("Setting up IPU1 Chain mode"); + if(ipu1dma.qwc == 0) + { + IPU1Status.InProgress = false; + IPU1Status.DMAFinished = false; + } + else + { //Attempting to continue a previous chain + IPU_LOG("Resuming DMA TAG %x", (ipu1dma.chcr.TAG >> 12)); + //We MUST check the CHCR for the tag it last knew, it can be manipulated! + IPU1Status.ChainMode = (ipu1dma.chcr.TAG >> 12) & 0x7; + IPU1Status.InProgress = true; + IPU1Status.DMAFinished = ((ipu1dma.chcr.TAG >> 15) && ipu1dma.chcr.TIE) ? true : false; + } + + IPU1Status.DMAMode = DMA_MODE_CHAIN; + IPU1dma(); + } + else //Normal Mode + { + if(ipu1dma.qwc == 0) + { + ipu1dma.chcr.STR = false; + // Hack to force stop IPU + ipuRegs.cmd.BUSY = 0; + ipuRegs.ctrl.BUSY = 0; + ipuRegs.topbusy = 0; + // + hwDmacIrq(DMAC_TO_IPU); + Console.Warning("IPU1 Normal error!"); + } + else + { + IPU_LOG("Setting up IPU1 Normal mode"); + IPU1Status.InProgress = true; + IPU1Status.DMAFinished = true; + IPU1Status.DMAMode = DMA_MODE_NORMAL; + IPU1dma(); + } + } +} + +extern void GIFdma(); + +void ipu0Interrupt() +{ + IPU_LOG("ipu0Interrupt: %x", cpuRegs.cycle); + + if (g_nDMATransfer.FIREINT0) + { + g_nDMATransfer.FIREINT0 = false; + hwIntcIrq(INTC_IPU); + } + + if (g_nDMATransfer.GIFSTALL) + { + // gif + Console.Warning("IPU GIF Stall"); + g_nDMATransfer.GIFSTALL = false; + //if (gif->chcr.STR) GIFdma(); + } + + if (g_nDMATransfer.VIFSTALL) + { + // vif + Console.Warning("IPU VIF Stall"); + g_nDMATransfer.VIFSTALL = false; + //if (vif1ch.chcr.STR) dmaVIF1(); + } + + if (g_nDMATransfer.SIFSTALL) + { + // sif + Console.Warning("IPU SIF Stall"); + g_nDMATransfer.SIFSTALL = false; + + // Not totally sure whether this needs to be done or not, so I'm + // leaving it commented out for the moment. + //if (sif1dma.chcr.STR) SIF1Dma(); + } + + if (g_nDMATransfer.TIE0) + { + g_nDMATransfer.TIE0 = false; + } + + ipu0dma.chcr.STR = false; + hwDmacIrq(DMAC_FROM_IPU); +} + +IPU_FORCEINLINE void ipu1Interrupt() +{ + IPU_LOG("ipu1Interrupt %x:", cpuRegs.cycle); + + if(IPU1Status.DMAFinished == false || IPU1Status.InProgress == true) //Sanity Check + { + IPU1dma(); + return; + } + + IPU_LOG("ipu1 finish %x:", cpuRegs.cycle); + ipu1dma.chcr.STR = false; + IPU1Status.DMAMode = 2; + hwDmacIrq(DMAC_TO_IPU); +} diff --git a/pcsx2/IPU/IPUdma.h b/pcsx2/IPU/IPUdma.h index 4e95a878a9..9c62820d13 100644 --- a/pcsx2/IPU/IPUdma.h +++ b/pcsx2/IPU/IPUdma.h @@ -1,71 +1,93 @@ -struct IPUStatus { - bool InProgress; - u8 DMAMode; - bool DMAFinished; - bool IRQTriggered; - u8 TagFollow; - u32 TagAddr; - bool stalled; - u8 ChainMode; - u32 NextMem; -}; - -#define DMA_MODE_NORMAL 0 -#define DMA_MODE_CHAIN 1 - -#define IPU1_TAG_FOLLOW 0 -#define IPU1_TAG_QWC 1 -#define IPU1_TAG_ADDR 2 -#define IPU1_TAG_NONE 3 - -union tIPU_DMA -{ - struct - { - bool GIFSTALL : 1; - bool TIE0 :1; - bool TIE1 : 1; - bool ACTV1 : 1; - bool DOTIE1 : 1; - bool FIREINT0 : 1; - bool FIREINT1 : 1; - bool VIFSTALL : 1; - bool SIFSTALL : 1; - }; - u32 _u32; - - tIPU_DMA( u32 val ){ _u32 = val; } - tIPU_DMA() { } - - bool test(u32 flags) const { return !!(_u32 & flags); } - void set_flags(u32 flags) { _u32 |= flags; } - void clear_flags(u32 flags) { _u32 &= ~flags; } - void reset() { _u32 = 0; } - wxString desc() const - { - wxString temp(L"g_nDMATransfer["); - - if (GIFSTALL) temp += L" GIFSTALL "; - if (TIE0) temp += L" TIE0 "; - if (TIE1) temp += L" TIE1 "; - if (ACTV1) temp += L" ACTV1 "; - if (DOTIE1) temp += L" DOTIE1 "; - if (FIREINT0) temp += L" FIREINT0 "; - if (FIREINT1) temp += L" FIREINT1 "; - if (VIFSTALL) temp += L" VIFSTALL "; - if (SIFSTALL) temp += L" SIFSTALL "; - - temp += L"]"; - return temp; - } -}; - -extern void ipu0Interrupt(); -extern void ipu1Interrupt(); - -extern void dmaIPU0(); -extern void dmaIPU1(); -extern int IPU0dma(); -extern int IPU1dma(); - -extern void ipuDmaReset(); +/* PCSX2 - PS2 Emulator for PCs + * Copyright (C) 2002-2010 PCSX2 Dev Team + * + * PCSX2 is free software: you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * PCSX2 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 PCSX2. + * If not, see . + */ + +#pragma once + +#include "IPU.h" + +static DMACh& ipu0dma = (DMACh&)eeHw[0xb000]; +static DMACh& ipu1dma = (DMACh&)eeHw[0xb400]; + +struct IPUStatus { + bool InProgress; + u8 DMAMode; + bool DMAFinished; + bool IRQTriggered; + u8 TagFollow; + u32 TagAddr; + bool stalled; + u8 ChainMode; + u32 NextMem; +}; + +#define DMA_MODE_NORMAL 0 +#define DMA_MODE_CHAIN 1 + +#define IPU1_TAG_FOLLOW 0 +#define IPU1_TAG_QWC 1 +#define IPU1_TAG_ADDR 2 +#define IPU1_TAG_NONE 3 + +union tIPU_DMA +{ + struct + { + bool GIFSTALL : 1; + bool TIE0 :1; + bool TIE1 : 1; + bool ACTV1 : 1; + bool DOTIE1 : 1; + bool FIREINT0 : 1; + bool FIREINT1 : 1; + bool VIFSTALL : 1; + bool SIFSTALL : 1; + }; + u32 _u32; + + tIPU_DMA( u32 val ){ _u32 = val; } + tIPU_DMA() { } + + bool test(u32 flags) const { return !!(_u32 & flags); } + void set_flags(u32 flags) { _u32 |= flags; } + void clear_flags(u32 flags) { _u32 &= ~flags; } + void reset() { _u32 = 0; } + wxString desc() const + { + wxString temp(L"g_nDMATransfer["); + + if (GIFSTALL) temp += L" GIFSTALL "; + if (TIE0) temp += L" TIE0 "; + if (TIE1) temp += L" TIE1 "; + if (ACTV1) temp += L" ACTV1 "; + if (DOTIE1) temp += L" DOTIE1 "; + if (FIREINT0) temp += L" FIREINT0 "; + if (FIREINT1) temp += L" FIREINT1 "; + if (VIFSTALL) temp += L" VIFSTALL "; + if (SIFSTALL) temp += L" SIFSTALL "; + + temp += L"]"; + return temp; + } +}; + +extern void ipu0Interrupt(); +extern void ipu1Interrupt(); + +extern void dmaIPU0(); +extern void dmaIPU1(); +extern int IPU0dma(); +extern int IPU1dma(); + +extern void ipuDmaReset(); diff --git a/pcsx2/IPU/mpeg2lib/Mpeg.cpp b/pcsx2/IPU/mpeg2lib/Mpeg.cpp index dddb64cfad..27edd38f89 100644 --- a/pcsx2/IPU/mpeg2lib/Mpeg.cpp +++ b/pcsx2/IPU/mpeg2lib/Mpeg.cpp @@ -680,7 +680,7 @@ static __fi bool slice_non_intra_DCT(s16 * const dest, const int stride, const b void __fi finishmpeg2sliceIDEC() { - ipuRegs->ctrl.SCD = 0; + ipuRegs.ctrl.SCD = 0; coded_block_pattern = decoder.coded_block_pattern; g_BP.BP += decoder.bitstream_bits - 16; @@ -710,8 +710,8 @@ bool mpeg2sliceIDEC() decoder.dc_dct_pred[2] = 128 << decoder.intra_dc_precision; decoder.mbc = 0; - ipuRegs->top = 0; - ipuRegs->ctrl.ECD = 0; + ipuRegs.top = 0; + ipuRegs.ctrl.ECD = 0; case 1: ipu_cmd.pos[0] = 1; @@ -907,17 +907,17 @@ finish_idec: { if (g_BP.BP & 7) g_BP.BP += 8 - (g_BP.BP & 7); - ipuRegs->ctrl.SCD = 1; + ipuRegs.ctrl.SCD = 1; } case 4: - if (!getBits32((u8*)&ipuRegs->top, 0)) + if (!getBits32((u8*)&ipuRegs.top, 0)) { ipu_cmd.pos[0] = 4; return false; } - BigEndian(ipuRegs->top, ipuRegs->top); + BigEndian(ipuRegs.top, ipuRegs.top); break; } @@ -942,8 +942,8 @@ bool mpeg2_slice() decoder.dc_dct_pred[2] = 128 << decoder.intra_dc_precision; } - ipuRegs->ctrl.ECD = 0; - ipuRegs->top = 0; + ipuRegs.ctrl.ECD = 0; + ipuRegs.top = 0; memzero_sse_a(mb8); memzero_sse_a(mb16); case 1: @@ -1082,7 +1082,7 @@ bool mpeg2_slice() } // Send The MacroBlock via DmaIpuFrom - ipuRegs->ctrl.SCD = 0; + ipuRegs.ctrl.SCD = 0; coded_block_pattern = decoder.coded_block_pattern; g_BP.BP += (int)decoder.bitstream_bits - 16; @@ -1128,17 +1128,17 @@ bool mpeg2_slice() { if (g_BP.BP & 7) g_BP.BP += 8 - (g_BP.BP & 7); - ipuRegs->ctrl.SCD = 1; + ipuRegs.ctrl.SCD = 1; } case 5: - if (!getBits32((u8*)&ipuRegs->top, 0)) + if (!getBits32((u8*)&ipuRegs.top, 0)) { ipu_cmd.pos[0] = 5; return false; } - BigEndian(ipuRegs->top, ipuRegs->top); + BigEndian(ipuRegs.top, ipuRegs.top); decoder.bitstream_bits = 0; break; } diff --git a/pcsx2/Memory.h b/pcsx2/Memory.h index d98c4000e0..7a325e1aec 100644 --- a/pcsx2/Memory.h +++ b/pcsx2/Memory.h @@ -39,14 +39,6 @@ static __fi void ZeroQWC( u128& dest ) _mm_store_ps( (float*)&dest, _mm_setzero_ps() ); } -// Various useful locations -#define sif0dma ((DMACh*)&eeHw[0xc000]) -#define sif1dma ((DMACh*)&eeHw[0xc400]) -#define sif2dma ((DMACh*)&eeHw[0xc800]) - -#define ipu0dma ((DMACh *)&eeHw[0xb000]) -#define ipu1dma ((DMACh *)&eeHw[0xb400]) - #define PSM(mem) (vtlb_GetPhyPtr((mem)&0x1fffffff)) //pcsx2 is a competition.The one with most hacks wins :D #define psHs8(mem) (*(s8 *)&eeHw[(mem) & 0xffff]) diff --git a/pcsx2/Sif.cpp b/pcsx2/Sif.cpp index a8c580e242..196298d18a 100644 --- a/pcsx2/Sif.cpp +++ b/pcsx2/Sif.cpp @@ -28,9 +28,9 @@ void sifInit() __fi void dmaSIF2() { - SIF_LOG(wxString(L"dmaSIF2" + sif2dma->cmq_to_str()).To8BitData()); + SIF_LOG(wxString(L"dmaSIF2" + sif2dma.cmq_to_str()).To8BitData()); - sif2dma->chcr.STR = false; + sif2dma.chcr.STR = false; hwDmacIrq(DMAC_SIF2); Console.WriteLn("*PCSX2*: dmaSIF2"); } diff --git a/pcsx2/Sif.h b/pcsx2/Sif.h index 5744dee6cc..9d276a4a78 100644 --- a/pcsx2/Sif.h +++ b/pcsx2/Sif.h @@ -16,7 +16,12 @@ #ifndef __SIF_H__ #define __SIF_H__ -#define FIFO_SIF_W 128 +static const int FIFO_SIF_W = 128; + +static DMACh& sif0dma = (DMACh&)eeHw[0xc000]; +static DMACh& sif1dma = (DMACh&)eeHw[0xc400]; +static DMACh& sif2dma = (DMACh&)eeHw[0xc800]; + struct sifData { diff --git a/pcsx2/Sif0.cpp b/pcsx2/Sif0.cpp index 7a12cb04bf..29ecc0ea90 100644 --- a/pcsx2/Sif0.cpp +++ b/pcsx2/Sif0.cpp @@ -35,14 +35,14 @@ static __fi void Sif0Init() // Write from Fifo to EE. static __fi bool WriteFifoToEE() { - const int readSize = min((s32)sif0dma->qwc, sif0.fifo.size >> 2); + const int readSize = min((s32)sif0dma.qwc, sif0.fifo.size >> 2); tDMA_TAG *ptag; - //SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma->madr); - SIF_LOG("Write Fifo to EE: ----------- %lX of %lX", readSize << 2, sif0dma->qwc << 2); + //SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma.madr); + SIF_LOG("Write Fifo to EE: ----------- %lX of %lX", readSize << 2, sif0dma.qwc << 2); - ptag = sif0dma->getAddr(sif0dma->madr, DMAC_SIF0, true); + ptag = sif0dma.getAddr(sif0dma.madr, DMAC_SIF0, true); if (ptag == NULL) { DevCon.Warning("Write Fifo to EE: ptag == NULL"); @@ -52,11 +52,11 @@ static __fi bool WriteFifoToEE() sif0.fifo.read((u32*)ptag, readSize << 2); // Clearing handled by vtlb memory protection and manual blocks. - //Cpu->Clear(sif0dma->madr, readSize*4); + //Cpu->Clear(sif0dma.madr, readSize*4); - sif0dma->madr += readSize << 4; + sif0dma.madr += readSize << 4; sif0.ee.cycles += readSize; // fixme : BIAS is factored in above - sif0dma->qwc -= readSize; + sif0dma.qwc -= readSize; return true; } @@ -87,14 +87,14 @@ static __fi bool ProcessEETag() sif0.fifo.read((u32*)&tag[0], 4); // Tag SIF_LOG("SIF0 EE read tag: %x %x %x %x", tag[0], tag[1], tag[2], tag[3]); - sif0dma->unsafeTransfer(((tDMA_TAG*)(tag))); - sif0dma->madr = tag[1]; + sif0dma.unsafeTransfer(((tDMA_TAG*)(tag))); + sif0dma.madr = tag[1]; tDMA_TAG ptag(tag[0]); SIF_LOG("SIF0 EE dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)", - sif0dma->madr, sif0dma->qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]); + sif0dma.madr, sif0dma.qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]); - if (sif0dma->chcr.TIE && ptag.IRQ) + if (sif0dma.chcr.TIE && ptag.IRQ) { //Console.WriteLn("SIF0 TIE"); sif0.ee.end = true; @@ -105,12 +105,12 @@ static __fi bool ProcessEETag() case TAG_REFE: sif0.ee.end = true; if (dmacRegs.ctrl.STS != NO_STS) - dmacRegs.stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16); + dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16); break; case TAG_REFS: if (dmacRegs.ctrl.STS != NO_STS) - dmacRegs.stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16); + dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16); break; case TAG_END: @@ -177,7 +177,7 @@ static __fi void EndIOP() // Handle the EE transfer. static __fi void HandleEETransfer() { - if(sif0dma->chcr.STR == false) + if(sif0dma.chcr.STR == false) { DevCon.Warning("Replacement for irq prevention hack EE SIF0"); sif0.ee.end = false; @@ -190,17 +190,17 @@ static __fi void HandleEETransfer() DevCon.Warning("SIF0 stall control"); } - /*if (sif0dma->qwc == 0) - if (sif0dma->chcr.MOD == NORMAL_MODE) + /*if (sif0dma.qwc == 0) + if (sif0dma.chcr.MOD == NORMAL_MODE) if (!sif0.ee.end){ DevCon.Warning("sif0 irq prevented"); done = true; return; }*/ - if (sif0dma->qwc <= 0) + if (sif0dma.qwc <= 0) { - if ((sif0dma->chcr.MOD == NORMAL_MODE) || sif0.ee.end) + if ((sif0dma.chcr.MOD == NORMAL_MODE) || sif0.ee.end) { // Stop transferring ee, and signal an interrupt. done = true; @@ -214,7 +214,7 @@ static __fi void HandleEETransfer() } } - if (sif0dma->qwc > 0) // If we're writing something, continue to do so. + if (sif0dma.qwc > 0) // If we're writing something, continue to do so. { // Write from Fifo to EE. if (sif0.fifo.size > 0) @@ -306,7 +306,7 @@ __fi void SIF0Dma() } if (sif0.ee.busy) { - if(sif0.fifo.size >= 4 || (sif0.ee.end == true && sif0dma->qwc == 0)) + if(sif0.fifo.size >= 4 || (sif0.ee.end == true && sif0dma.qwc == 0)) { BusyCheck++; HandleEETransfer(); @@ -326,19 +326,19 @@ __fi void sif0Interrupt() __fi void EEsif0Interrupt() { hwDmacIrq(DMAC_SIF0); - sif0dma->chcr.STR = false; + sif0dma.chcr.STR = false; } __fi void dmaSIF0() { - SIF_LOG(wxString(L"dmaSIF0" + sif0dma->cmqt_to_str()).To8BitData()); + SIF_LOG(wxString(L"dmaSIF0" + sif0dma.cmqt_to_str()).To8BitData()); if (sif0.fifo.readPos != sif0.fifo.writePos) { SIF_LOG("warning, sif0.fifoReadPos != sif0.fifoWritePos"); } - //if(sif0dma->chcr.MOD == CHAIN_MODE && sif0dma->qwc > 0) DevCon.Warning(L"SIF0 QWC on Chain CHCR " + sif0dma->chcr.desc()); + //if(sif0dma.chcr.MOD == CHAIN_MODE && sif0dma.qwc > 0) DevCon.Warning(L"SIF0 QWC on Chain CHCR " + sif0dma.chcr.desc()); psHu32(SBUS_F240) |= 0x2000; sif0.ee.busy = true; diff --git a/pcsx2/Sif1.cpp b/pcsx2/Sif1.cpp index e3f6fa0ff1..58bb072af0 100644 --- a/pcsx2/Sif1.cpp +++ b/pcsx2/Sif1.cpp @@ -38,11 +38,11 @@ static __fi bool WriteEEtoFifo() // There's some data ready to transfer into the fifo.. SIF_LOG("Sif 1: Write EE to Fifo"); - const int writeSize = min((s32)sif1dma->qwc, sif1.fifo.free() >> 2); + const int writeSize = min((s32)sif1dma.qwc, sif1.fifo.free() >> 2); tDMA_TAG *ptag; - ptag = sif1dma->getAddr(sif1dma->madr, DMAC_SIF1, false); + ptag = sif1dma.getAddr(sif1dma.madr, DMAC_SIF1, false); if (ptag == NULL) { DevCon.Warning("Write EE to Fifo: ptag == NULL"); @@ -51,9 +51,9 @@ static __fi bool WriteEEtoFifo() sif1.fifo.write((u32*)ptag, writeSize << 2); - sif1dma->madr += writeSize << 4; + sif1dma.madr += writeSize << 4; sif1.ee.cycles += writeSize; // fixme : BIAS is factored in above - sif1dma->qwc -= writeSize; + sif1dma.qwc -= writeSize; return true; } @@ -84,21 +84,21 @@ static __fi bool ProcessEETag() tDMA_TAG *ptag; SIF_LOG("Sif1: ProcessEETag"); - // Process DMA tag at sif1dma->tadr - ptag = sif1dma->DMAtransfer(sif1dma->tadr, DMAC_SIF1); + // Process DMA tag at sif1dma.tadr + ptag = sif1dma.DMAtransfer(sif1dma.tadr, DMAC_SIF1); if (ptag == NULL) { Console.WriteLn("Sif1 ProcessEETag: ptag = NULL"); return false; } - if (sif1dma->chcr.TTE) + if (sif1dma.chcr.TTE) { Console.WriteLn("SIF1 TTE"); sif1.fifo.write((u32*)ptag + 2, 2); } - if (sif1dma->chcr.TIE && ptag->IRQ) + if (sif1dma.chcr.TIE && ptag->IRQ) { Console.WriteLn("SIF1 TIE"); sif1.ee.end = true; @@ -109,30 +109,30 @@ static __fi bool ProcessEETag() { case TAG_REFE: sif1.ee.end = true; - sif1dma->madr = ptag[1]._u32; - sif1dma->tadr += 16; + sif1dma.madr = ptag[1]._u32; + sif1dma.tadr += 16; break; case TAG_CNT: - sif1dma->madr = sif1dma->tadr + 16; - sif1dma->tadr = sif1dma->madr + (sif1dma->qwc << 4); + sif1dma.madr = sif1dma.tadr + 16; + sif1dma.tadr = sif1dma.madr + (sif1dma.qwc << 4); break; case TAG_NEXT: - sif1dma->madr = sif1dma->tadr + 16; - sif1dma->tadr = ptag[1]._u32; + sif1dma.madr = sif1dma.tadr + 16; + sif1dma.tadr = ptag[1]._u32; break; case TAG_REF: case TAG_REFS: - sif1dma->madr = ptag[1]._u32; - sif1dma->tadr += 16; + sif1dma.madr = ptag[1]._u32; + sif1dma.tadr += 16; break; case TAG_END: sif1.ee.end = true; - sif1dma->madr = sif1dma->tadr + 16; - sif1dma->tadr = sif1dma->madr + (sif1dma->qwc << 4); + sif1dma.madr = sif1dma.tadr + 16; + sif1dma.tadr = sif1dma.madr + (sif1dma.qwc << 4); break; default: @@ -203,7 +203,7 @@ static __fi void EndIOP() // Handle the EE transfer. static __fi void HandleEETransfer() { - if(sif1dma->chcr.STR == false) + if(sif1dma.chcr.STR == false) { DevCon.Warning("Replacement for irq prevention hack EE SIF1"); sif1.ee.end = false; @@ -215,19 +215,19 @@ static __fi void HandleEETransfer() DevCon.Warning("SIF1 stall control"); // STD == fromSIF1 } - /*if (sif1dma->qwc == 0) - if (sif1dma->chcr.MOD == NORMAL_MODE) + /*if (sif1dma.qwc == 0) + if (sif1dma.chcr.MOD == NORMAL_MODE) if (!sif1.ee.end){ - DevCon.Warning("sif1 irq prevented CHCR %x QWC %x", sif1dma->chcr, sif1dma->qwc); + DevCon.Warning("sif1 irq prevented CHCR %x QWC %x", sif1dma.chcr, sif1dma.qwc); done = true; return; }*/ // If there's no more to transfer. - if (sif1dma->qwc <= 0) + if (sif1dma.qwc <= 0) { // If NORMAL mode or end of CHAIN then stop DMA. - if ((sif1dma->chcr.MOD == NORMAL_MODE) || sif1.ee.end) + if ((sif1dma.chcr.MOD == NORMAL_MODE) || sif1.ee.end) { done = true; EndEE(); @@ -292,7 +292,7 @@ __fi void SIF1Dma() if (sif1.ee.busy) { - if(sif1.fifo.free() > 0 || (sif1.ee.end == true && sif1dma->qwc == 0)) + if(sif1.fifo.free() > 0 || (sif1.ee.end == true && sif1dma.qwc == 0)) { BusyCheck++; HandleEETransfer(); @@ -322,21 +322,21 @@ __fi void sif1Interrupt() __fi void EEsif1Interrupt() { hwDmacIrq(DMAC_SIF1); - sif1dma->chcr.STR = false; + sif1dma.chcr.STR = false; } // Do almost exactly the same thing as psxDma10 in IopDma.cpp. // Main difference is this checks for iop, where psxDma10 checks for ee. __fi void dmaSIF1() { - SIF_LOG(wxString(L"dmaSIF1" + sif1dma->cmqt_to_str()).To8BitData()); + SIF_LOG(wxString(L"dmaSIF1" + sif1dma.cmqt_to_str()).To8BitData()); if (sif1.fifo.readPos != sif1.fifo.writePos) { SIF_LOG("warning, sif1.fifoReadPos != sif1.fifoWritePos"); } - //if(sif1dma->chcr.MOD == CHAIN_MODE && sif1dma->qwc > 0) DevCon.Warning(L"SIF1 QWC on Chain CHCR " + sif1dma->chcr.desc()); + //if(sif1dma.chcr.MOD == CHAIN_MODE && sif1dma.qwc > 0) DevCon.Warning(L"SIF1 QWC on Chain CHCR " + sif1dma.chcr.desc()); psHu32(SBUS_F240) |= 0x4000; sif1.ee.busy = true; diff --git a/pcsx2/windows/VCprojects/IopSif.cpp b/pcsx2/windows/VCprojects/IopSif.cpp index d5b9b12a0f..5085bd4cbe 100644 --- a/pcsx2/windows/VCprojects/IopSif.cpp +++ b/pcsx2/windows/VCprojects/IopSif.cpp @@ -33,14 +33,14 @@ s32 PrepareEERead() "\n\tread tag: %x %x %x %x", hw_dma(9).madr, hw_dma(9).tadr, sif0.iop.counter, sif0words, sif0data, tag[0], tag[1], tag[2], tag[3]); - sif0dma->unsafeTransfer(((tDMA_TAG*)(tag))); - sif0dma->madr = tag[1]; + sif0dma.unsafeTransfer(((tDMA_TAG*)(tag))); + sif0dma.madr = tag[1]; tDMA_TAG ptag(tag[0]); SIF_LOG("SIF0 EE dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)", - sif0dma->madr, sif0dma->qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]); + sif0dma.madr, sif0dma.qwc, ptag.ID, ptag.IRQ, tag[1], tag[0]); - if (sif0dma->chcr.TIE && ptag.IRQ) + if (sif0dma.chcr.TIE && ptag.IRQ) { //Console.WriteLn("SIF0 TIE"); sif0.ee.end = true; @@ -51,12 +51,12 @@ s32 PrepareEERead() case TAG_REFE: sif0.ee.end = true; if (dmacRegs.ctrl.STS != NO_STS) - dmacRegs.stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16); + dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16); break; case TAG_REFS: if (dmacRegs.ctrl.STS != NO_STS) - dmacRegs.stadr.ADDR = sif0dma->madr + (sif0dma->qwc * 16); + dmacRegs.stadr.ADDR = sif0dma.madr + (sif0dma.qwc * 16); break; case TAG_END: @@ -91,7 +91,7 @@ s32 DoSifRead(u32 iopAvailable) SIF_LOG("Write IOP to EE: +++++++++++ %lX of %lX", transferSizeWords, sif0.iop.counter); - tDMA_TAG *ptag = sif0dma->getAddr(sif0dma->madr, DMAC_SIF0, true); + tDMA_TAG *ptag = sif0dma.getAddr(sif0dma.madr, DMAC_SIF0, true); if (ptag == NULL) { DevCon.Warning("Write IOP to EE: ptag == NULL"); @@ -101,11 +101,11 @@ s32 DoSifRead(u32 iopAvailable) memcpy((u32*)ptag, (u32*)iopPhysMem(hw_dma(9).madr), transferSizeBytes); // Clearing handled by vtlb memory protection and manual blocks. - //Cpu->Clear(sif0dma->madr, readSize*4); + //Cpu->Clear(sif0dma.madr, readSize*4); - sif0dma->madr += transferSizeBytes; + sif0dma.madr += transferSizeBytes; sif0.ee.cycles += transferSizeQWords * 2; - sif0dma->qwc -= transferSizeQWords; + sif0dma.qwc -= transferSizeQWords; return transferSizeBytes; }