Alternative way of handling FLUSH.

This commit is contained in:
Jean-Philip Desjardins 2024-03-05 18:00:17 -05:00
parent 8fd1061149
commit 02743d5aba
3 changed files with 17 additions and 32 deletions

View file

@ -86,8 +86,7 @@ void CVif::Reset()
m_pendingMicroProgram = -1; m_pendingMicroProgram = -1;
m_incomingFifoDelay = 0; m_incomingFifoDelay = 0;
m_interruptDelayTicks = 0; m_interruptDelayTicks = 0;
m_stallDma = false; m_mpgExecuting = false;
m_stallDmaCount = 0;
} }
uint32 CVif::GetRegister(uint32 address) uint32 CVif::GetRegister(uint32 address)
@ -254,6 +253,7 @@ void CVif::SetRegister(uint32 address, uint32 value)
void CVif::CountTicks(uint32 ticks) void CVif::CountTicks(uint32 ticks)
{ {
m_mpgExecuting = false;
if(m_interruptDelayTicks != 0) if(m_interruptDelayTicks != 0)
{ {
m_interruptDelayTicks -= ticks; m_interruptDelayTicks -= ticks;
@ -355,16 +355,12 @@ uint32 CVif::GetITOP() const
uint32 CVif::ReceiveDMA(uint32 address, uint32 qwc, uint32 unused, bool tagIncluded) uint32 CVif::ReceiveDMA(uint32 address, uint32 qwc, uint32 unused, bool tagIncluded)
{ {
if(m_STAT.nVEW && m_vpu.IsVuRunning()) if(m_STAT.nVEW && (m_vpu.IsVuRunning() || m_mpgExecuting))
{ {
//Is waiting for program end, don't bother //Is waiting for program end, don't bother
m_mpgExecuting = false;
return 0; return 0;
} }
if(m_stallDma)
{
m_stallDma = false;
return m_stallDmaCount;
}
#ifdef PROFILE #ifdef PROFILE
CProfilerZone profilerZone(m_vifProfilerZone); CProfilerZone profilerZone(m_vifProfilerZone);
@ -383,21 +379,7 @@ uint32 CVif::ReceiveDMA(uint32 address, uint32 qwc, uint32 unused, bool tagInclu
assert((remainingSize & 0x0F) == 0); assert((remainingSize & 0x0F) == 0);
remainingSize /= 0x10; remainingSize /= 0x10;
uint32 result = qwc - remainingSize; return qwc - remainingSize;
if(result == 0)
{
m_stallDma = false;
}
if(m_stallDma)
{
m_stallDmaCount = result;
return 0;
}
else
{
return result;
}
} }
bool CVif::IsWaitingForProgramEnd() const bool CVif::IsWaitingForProgramEnd() const
@ -447,7 +429,7 @@ void CVif::ProcessPacket(StreamType& stream)
} }
if(m_STAT.nVEW == 1) if(m_STAT.nVEW == 1)
{ {
if(m_vpu.IsVuRunning()) break; if(m_vpu.IsVuRunning() || m_mpgExecuting) break;
m_STAT.nVEW = 0; m_STAT.nVEW = 0;
//Command is waiting for micro-program to end. //Command is waiting for micro-program to end.
ExecuteCommand(stream, m_CODE); ExecuteCommand(stream, m_CODE);
@ -531,7 +513,7 @@ void CVif::ExecuteCommand(StreamType& stream, CODE nCommand)
m_STAT.nMRK = 1; m_STAT.nMRK = 1;
break; break;
case CODE_CMD_FLUSHE: case CODE_CMD_FLUSHE:
if(m_vpu.IsVuRunning()) if(m_vpu.IsVuRunning() || m_mpgExecuting)
{ {
m_STAT.nVEW = 1; m_STAT.nVEW = 1;
} }
@ -591,6 +573,8 @@ void CVif::ExecuteCommand(StreamType& stream, CODE nCommand)
void CVif::Cmd_MPG(StreamType& stream, CODE nCommand) void CVif::Cmd_MPG(StreamType& stream, CODE nCommand)
{ {
m_mpgExecuting = false;
uint32 nSize = stream.GetAvailableReadBytes(); uint32 nSize = stream.GetAvailableReadBytes();
uint32 nNum = (m_NUM == 0) ? (256) : (m_NUM); uint32 nNum = (m_NUM == 0) ? (256) : (m_NUM);
@ -717,6 +701,8 @@ void CVif::Cmd_STMASK(StreamType& stream, CODE command)
void CVif::Cmd_UNPACK(StreamType& stream, CODE nCommand, uint32 nDstAddr) void CVif::Cmd_UNPACK(StreamType& stream, CODE nCommand, uint32 nDstAddr)
{ {
m_mpgExecuting = false;
uint32 cl = m_CYCLE.nCL; uint32 cl = m_CYCLE.nCL;
uint32 wl = m_CYCLE.nWL; uint32 wl = m_CYCLE.nWL;
if(wl == 0) if(wl == 0)
@ -756,6 +742,7 @@ void CVif::StartMicroProgram(uint32 address)
assert(!m_STAT.nVEW); assert(!m_STAT.nVEW);
PrepareMicroProgram(); PrepareMicroProgram();
m_vpu.ExecuteMicroProgram(address); m_vpu.ExecuteMicroProgram(address);
m_mpgExecuting = true;
} }
void CVif::StartDelayedMicroProgram(uint32 address) void CVif::StartDelayedMicroProgram(uint32 address)
@ -782,6 +769,7 @@ bool CVif::ResumeDelayedMicroProgram()
assert(!m_vpu.IsVuRunning()); assert(!m_vpu.IsVuRunning());
m_vpu.ExecuteMicroProgram(m_pendingMicroProgram); m_vpu.ExecuteMicroProgram(m_pendingMicroProgram);
m_pendingMicroProgram = -1; m_pendingMicroProgram = -1;
m_mpgExecuting = true;
return true; return true;
} }
else else

View file

@ -669,9 +669,6 @@ protected:
uint8 m_fifoBuffer[FIFO_SIZE]; uint8 m_fifoBuffer[FIFO_SIZE];
uint32 m_fifoIndex = 0; uint32 m_fifoIndex = 0;
bool m_stallDma = false;
uint32 m_stallDmaCount = 0;
STAT m_STAT; STAT m_STAT;
ERR m_ERR; ERR m_ERR;
CYCLE m_CYCLE; CYCLE m_CYCLE;
@ -689,6 +686,7 @@ protected:
uint32 m_pendingMicroProgram; uint32 m_pendingMicroProgram;
uint32 m_incomingFifoDelay; uint32 m_incomingFifoDelay;
int32 m_interruptDelayTicks; int32 m_interruptDelayTicks;
bool m_mpgExecuting = false;
CProfiler::ZoneHandle m_vifProfilerZone = 0; CProfiler::ZoneHandle m_vifProfilerZone = 0;
}; };

View file

@ -114,7 +114,7 @@ void CVif1::ExecuteCommand(StreamType& stream, CODE nCommand)
m_gif.SetPath3Masked((nCommand.nIMM & 0x8000) != 0); m_gif.SetPath3Masked((nCommand.nIMM & 0x8000) != 0);
break; break;
case CODE_CMD_FLUSH: case CODE_CMD_FLUSH:
if(m_vpu.IsVuRunning()) if(m_vpu.IsVuRunning() || m_mpgExecuting)
{ {
m_STAT.nVEW = 1; m_STAT.nVEW = 1;
} }
@ -129,7 +129,7 @@ void CVif1::ExecuteCommand(StreamType& stream, CODE nCommand)
} }
break; break;
case CODE_CMD_FLUSHA: case CODE_CMD_FLUSHA:
if(m_vpu.IsVuRunning()) if(m_vpu.IsVuRunning() || m_mpgExecuting)
{ {
m_STAT.nVEW = 1; m_STAT.nVEW = 1;
} }
@ -155,8 +155,7 @@ void CVif1::ExecuteCommand(StreamType& stream, CODE nCommand)
void CVif1::Cmd_DIRECT(StreamType& stream, CODE nCommand) void CVif1::Cmd_DIRECT(StreamType& stream, CODE nCommand)
{ {
m_stallDma = true; m_mpgExecuting = false;
m_stallDmaCount = 0;
uint32 nSize = stream.GetAvailableReadBytes(); uint32 nSize = stream.GetAvailableReadBytes();
assert((nSize & 0x03) == 0); assert((nSize & 0x03) == 0);