2026-01-12 05:18:12 -05:00
|
|
|
// SPDX-FileCopyrightText: 2002-2026 PCSX2 Dev Team
|
2024-07-30 13:42:36 +02:00
|
|
|
// SPDX-License-Identifier: GPL-3.0+
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
|
#include "Common.h"
|
|
|
|
|
|
2016-04-30 16:17:40 +01:00
|
|
|
#include "Gif.h"
|
2011-08-12 02:31:49 +00:00
|
|
|
#include "Gif_Unit.h"
|
2023-06-24 17:46:36 +10:00
|
|
|
#include "MTGS.h"
|
2009-02-09 21:15:56 +00:00
|
|
|
#include "Vif.h"
|
2010-05-09 19:02:06 +00:00
|
|
|
#include "Vif_Dma.h"
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/////////////////////////// Quick & dirty FIFO :D ////////////////////////
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// Notes on FIFO implementation
|
|
|
|
|
//
|
|
|
|
|
// The FIFO consists of four separate pages of HW register memory, each mapped to a
|
|
|
|
|
// PS2 device. They are listed as follows:
|
|
|
|
|
//
|
|
|
|
|
// 0x4000 - 0x5000 : VIF0 (all registers map to 0x4000)
|
|
|
|
|
// 0x5000 - 0x6000 : VIF1 (all registers map to 0x5000)
|
|
|
|
|
// 0x6000 - 0x7000 : GS (all registers map to 0x6000)
|
|
|
|
|
// 0x7000 - 0x8000 : IPU (registers map to 0x7000 and 0x7010, respectively)
|
|
|
|
|
|
2022-05-12 22:34:42 +10:00
|
|
|
void ReadFIFO_VIF1(mem128_t* out)
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2021-07-29 20:33:52 +01:00
|
|
|
if (vif1Regs.stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
|
|
|
|
|
DevCon.Warning("Reading from vif1 fifo when stalled");
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2011-08-01 03:16:42 +00:00
|
|
|
ZeroQWC(out); // Clear first in case no data gets written...
|
2010-08-31 05:22:26 +00:00
|
|
|
pxAssertRel(vif1Regs.stat.FQC != 0, "FQC = 0 on VIF FIFO READ!");
|
2021-07-29 20:33:52 +01:00
|
|
|
if (vif1Regs.stat.FDR)
|
|
|
|
|
{
|
|
|
|
|
if (vif1Regs.stat.FQC > vif1.GSLastDownloadSize)
|
|
|
|
|
{
|
2010-05-09 19:30:30 +00:00
|
|
|
DevCon.Warning("Warning! GS Download size < FIFO count!");
|
|
|
|
|
}
|
2021-07-29 20:33:52 +01:00
|
|
|
if (vif1Regs.stat.FQC > 0)
|
|
|
|
|
{
|
2023-06-24 17:46:36 +10:00
|
|
|
MTGS::InitAndReadFIFO(reinterpret_cast<u8*>(out), 1);
|
2010-05-09 19:30:30 +00:00
|
|
|
vif1.GSLastDownloadSize--;
|
2011-07-24 13:02:50 +00:00
|
|
|
GUNIT_LOG("ReadFIFO_VIF1");
|
2010-05-09 19:30:30 +00:00
|
|
|
if (vif1.GSLastDownloadSize <= 16)
|
2010-08-31 05:22:26 +00:00
|
|
|
gifRegs.stat.OPH = false;
|
2014-08-13 23:47:03 -07:00
|
|
|
vif1Regs.stat.FQC = std::min((u32)16, vif1.GSLastDownloadSize);
|
2010-05-09 19:30:30 +00:00
|
|
|
}
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
|
2022-05-18 23:27:23 +10:00
|
|
|
VIF_LOG("ReadFIFO/VIF1 -> 0x%08X.%08X.%08X.%08X", out->_u32[0], out->_u32[1], out->_u32[2], out->_u32[3]);
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// WriteFIFO Pages
|
2010-08-31 05:22:26 +00:00
|
|
|
//
|
2022-05-12 22:34:42 +10:00
|
|
|
void WriteFIFO_VIF0(const mem128_t* value)
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2022-05-18 23:27:23 +10:00
|
|
|
VIF_LOG("WriteFIFO/VIF0 <- 0x%08X.%08X.%08X.%08X", value->_u32[0], value->_u32[1], value->_u32[2], value->_u32[3]);
|
2009-09-17 23:04:02 +00:00
|
|
|
|
2010-08-31 05:22:26 +00:00
|
|
|
vif0ch.qwc += 1;
|
2021-07-29 20:33:52 +01:00
|
|
|
if (vif0.irqoffset.value != 0 && vif0.vifstalled.enabled)
|
|
|
|
|
DevCon.Warning("Offset on VIF0 FIFO start!");
|
2023-12-22 20:30:31 +10:00
|
|
|
[[maybe_unused]] bool ret = VIF0transfer((u32*)value, 4);
|
2010-06-22 23:10:40 +00:00
|
|
|
|
2021-07-29 20:33:52 +01:00
|
|
|
if (vif0.cmd)
|
2010-06-22 23:10:40 +00:00
|
|
|
{
|
2021-07-29 20:33:52 +01:00
|
|
|
if (vif0.done && vif0ch.qwc == 0)
|
|
|
|
|
vif0Regs.stat.VPS = VPS_WAITING;
|
2010-06-22 23:10:40 +00:00
|
|
|
}
|
2021-07-29 20:33:52 +01:00
|
|
|
else
|
2010-06-22 23:10:40 +00:00
|
|
|
{
|
2010-08-31 05:22:26 +00:00
|
|
|
vif0Regs.stat.VPS = VPS_IDLE;
|
2010-06-22 23:10:40 +00:00
|
|
|
}
|
|
|
|
|
|
2023-12-22 20:30:31 +10:00
|
|
|
pxAssertMsg(ret, "vif stall code not implemented");
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
2009-09-17 23:04:02 +00:00
|
|
|
|
2022-05-12 22:34:42 +10:00
|
|
|
void WriteFIFO_VIF1(const mem128_t* value)
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2022-05-18 23:27:23 +10:00
|
|
|
VIF_LOG("WriteFIFO/VIF1 <- 0x%08X.%08X.%08X.%08X", value->_u32[0], value->_u32[1], value->_u32[2], value->_u32[3]);
|
2009-09-17 23:04:02 +00:00
|
|
|
|
2021-07-29 20:33:52 +01:00
|
|
|
if (vif1Regs.stat.FDR)
|
|
|
|
|
{
|
2009-10-29 13:32:40 +00:00
|
|
|
DevCon.Warning("writing to fifo when fdr is set!");
|
2011-07-24 22:24:10 +00:00
|
|
|
}
|
2021-07-29 20:33:52 +01:00
|
|
|
if (vif1Regs.stat.test(VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
|
|
|
|
|
{
|
2009-10-29 13:32:40 +00:00
|
|
|
DevCon.Warning("writing to vif1 fifo when stalled");
|
2011-07-24 22:24:10 +00:00
|
|
|
}
|
2021-07-29 20:33:52 +01:00
|
|
|
if (vif1.irqoffset.value != 0 && vif1.vifstalled.enabled)
|
|
|
|
|
{
|
2011-07-24 22:24:10 +00:00
|
|
|
DevCon.Warning("Offset on VIF1 FIFO start!");
|
|
|
|
|
}
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2023-12-22 20:30:31 +10:00
|
|
|
[[maybe_unused]] bool ret = VIF1transfer((u32*)value, 4);
|
2010-06-22 23:10:40 +00:00
|
|
|
|
2021-07-29 20:33:52 +01:00
|
|
|
if (vif1.cmd)
|
|
|
|
|
{
|
|
|
|
|
if (vif1.done && !vif1ch.qwc)
|
|
|
|
|
vif1Regs.stat.VPS = VPS_WAITING;
|
2010-06-22 23:10:40 +00:00
|
|
|
}
|
2021-07-29 20:33:52 +01:00
|
|
|
else
|
|
|
|
|
vif1Regs.stat.VPS = VPS_IDLE;
|
2010-06-22 23:10:40 +00:00
|
|
|
|
2021-07-29 20:33:52 +01:00
|
|
|
if (gifRegs.stat.APATH == 2 && gifUnit.gifPath[1].isDone())
|
2013-02-10 15:06:10 +00:00
|
|
|
{
|
|
|
|
|
gifRegs.stat.APATH = 0;
|
|
|
|
|
gifRegs.stat.OPH = 0;
|
|
|
|
|
vif1Regs.stat.VGW = false; //Let vif continue if it's stuck on a flush
|
|
|
|
|
|
2021-07-29 20:33:52 +01:00
|
|
|
if (gifUnit.checkPaths(1, 0, 1))
|
|
|
|
|
gifUnit.Execute(false, true);
|
2013-02-10 15:06:10 +00:00
|
|
|
}
|
|
|
|
|
|
2023-12-22 20:30:31 +10:00
|
|
|
pxAssertMsg(ret, "vif stall code not implemented");
|
2009-02-09 21:15:56 +00:00
|
|
|
}
|
|
|
|
|
|
2022-05-12 22:34:42 +10:00
|
|
|
void WriteFIFO_GIF(const mem128_t* value)
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2011-07-24 13:02:50 +00:00
|
|
|
GUNIT_LOG("WriteFIFO_GIF()");
|
2021-07-29 20:33:52 +01:00
|
|
|
if ((!gifUnit.CanDoPath3() || gif_fifo.fifoSize > 0))
|
|
|
|
|
{
|
2021-07-24 23:17:57 +01:00
|
|
|
//DevCon.Warning("GIF FIFO HW Write");
|
|
|
|
|
gif_fifo.write_fifo((u32*)value, 1);
|
|
|
|
|
gif_fifo.read_fifo();
|
2016-04-30 16:17:40 +01:00
|
|
|
}
|
2021-07-29 20:33:52 +01:00
|
|
|
else
|
|
|
|
|
{
|
2016-04-30 16:17:40 +01:00
|
|
|
gifUnit.TransferGSPacketData(GIF_TRANS_FIFO, (u8*)value, 16);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT)
|
2012-05-24 18:57:23 +00:00
|
|
|
gifUnit.gifPath[GIF_PATH_3].state = GIF_PATH_IDLE;
|
2013-02-10 15:06:10 +00:00
|
|
|
|
2016-04-30 16:17:40 +01:00
|
|
|
if (gifRegs.stat.APATH == 3)
|
2013-02-10 15:06:10 +00:00
|
|
|
{
|
|
|
|
|
gifRegs.stat.APATH = 0;
|
|
|
|
|
gifRegs.stat.OPH = 0;
|
|
|
|
|
|
2016-04-30 16:17:40 +01:00
|
|
|
if (gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE || gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT)
|
2013-02-10 15:06:10 +00:00
|
|
|
{
|
2021-07-29 20:33:52 +01:00
|
|
|
if (gifUnit.checkPaths(1, 1, 0))
|
|
|
|
|
gifUnit.Execute(false, true);
|
2013-02-10 15:06:10 +00:00
|
|
|
}
|
|
|
|
|
}
|
2010-04-15 00:32:58 +00:00
|
|
|
}
|