Skip to content

Commit

Permalink
Only trigger T/D bit interrupts when they are enabled.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpd002 committed Aug 16, 2024
1 parent b59696f commit cdb0fa8
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 24 deletions.
5 changes: 4 additions & 1 deletion Source/MIPS.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@ enum
MIPS_EXCEPTION_CHECKPENDINGINT,
MIPS_EXCEPTION_IDLE,
MIPS_EXCEPTION_RETURNFROMEXCEPTION,
MIPS_EXCEPTION_CALLMS,
MIPS_EXCEPTION_BREAKPOINT,
MIPS_EXCEPTION_TLB,
MIPS_EXCEPTION_VU_CALLMS,
MIPS_EXCEPTION_VU_DBIT,
MIPS_EXCEPTION_VU_TBIT,
MIPS_EXCEPTION_VU_EBIT,
};

struct TLBENTRY
Expand Down
22 changes: 13 additions & 9 deletions Source/ee/COP_VU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,24 +283,28 @@ void CCOP_VU::CTC2()
m_codeGen->PullRel(offsetof(CMIPS, m_State.cmsar0));
break;
case CTRL_REG_FBRST:
//Don't care
{
uint32 valueCursor = m_codeGen->GetTopCursor();

m_codeGen->PushCtx();
m_codeGen->PushCursor(valueCursor);
m_codeGen->PushCst(CVpu::EE_ADDR_VU_FBRST);
m_codeGen->Call(reinterpret_cast<void*>(&MemoryUtils_SetWordProxy), 3, Jitter::CJitter::RETURN_VALUE_NONE);

m_codeGen->PullTop();
break;
}
break;
case CTRL_REG_CMSAR1:
{
m_codeGen->PushCst(0xFFFF);
m_codeGen->And();
uint32 valueCursor = m_codeGen->GetTopCursor();

//Push context
m_codeGen->PushCtx();
//Push value
m_codeGen->PushCursor(valueCursor);
//Compute Address
m_codeGen->PushCst(CVpu::EE_ADDR_VU_CMSAR1);
m_codeGen->Call(reinterpret_cast<void*>(&MemoryUtils_SetWordProxy), 3, Jitter::CJitter::RETURN_VALUE_NONE);
//Clear stack
assert(m_codeGen->GetTopCursor() == valueCursor);

m_codeGen->PullTop();
}
break;
Expand Down Expand Up @@ -573,7 +577,7 @@ void CCOP_VU::VCALLMS()
m_codeGen->PushCst(static_cast<uint32>(m_nImm15) * 8);
m_codeGen->PullRel(offsetof(CMIPS, m_State.callMsAddr));

m_codeGen->PushCst(MIPS_EXCEPTION_CALLMS);
m_codeGen->PushCst(MIPS_EXCEPTION_VU_CALLMS);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nHasException));
}

Expand All @@ -587,7 +591,7 @@ void CCOP_VU::VCALLMSR()
m_codeGen->Shl(3);
m_codeGen->PullRel(offsetof(CMIPS, m_State.callMsAddr));

m_codeGen->PushCst(MIPS_EXCEPTION_CALLMS);
m_codeGen->PushCst(MIPS_EXCEPTION_VU_CALLMS);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nHasException));
}

Expand Down
6 changes: 5 additions & 1 deletion Source/ee/Ee_SubSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ int CSubSystem::ExecuteCpu(int quota)
case MIPS_EXCEPTION_TLB:
m_os->HandleTLBException();
break;
case MIPS_EXCEPTION_CALLMS:
case MIPS_EXCEPTION_VU_CALLMS:
assert(m_EE.m_State.callMsEnabled);
if(m_EE.m_State.callMsEnabled)
{
Expand Down Expand Up @@ -569,6 +569,10 @@ uint32 CSubSystem::IOPortWriteHandler(uint32 nAddress, uint32 nData)
uint32 offset = nAddress - CVpu::EE_ADDR_VU1AREA_START;
HandleVu1AreaWrite(offset, nData);
}
else if(nAddress == CVpu::EE_ADDR_VU_FBRST)
{
m_vpu1->SetFbrst((nData >> 8) & 0xF);
}
else if(nAddress == CVpu::EE_ADDR_VU_CMSAR1)
{
bool validAddress = (nData & 0x7) == 0;
Expand Down
14 changes: 9 additions & 5 deletions Source/ee/MA_VU_Upper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,27 @@ void CMA_VU::CUpper::CompileInstruction(uint32 nAddress, CMipsJitter* codeGen, C

((this)->*(m_pOpVector[m_nOpcode & 0x3F]))();

if((m_nOpcode & (VUShared::VU_UPPEROP_BIT_D | VUShared::VU_UPPEROP_BIT_T)) != 0)
if(m_nOpcode & VUShared::VU_UPPEROP_BIT_D)
{
m_codeGen->PushCst(2);
m_codeGen->PushCst(MIPS_EXCEPTION_VU_DBIT);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nHasException));
}

if(m_nOpcode & VUShared::VU_UPPEROP_BIT_T)
{
m_codeGen->PushCst(MIPS_EXCEPTION_VU_TBIT);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nHasException));
}

//Check I bit
if(m_nOpcode & VUShared::VU_UPPEROP_BIT_I)
{
LOI(pCtx->m_pMemoryMap->GetInstruction(nAddress - 4));
}

//Check E bit
if(m_nOpcode & VUShared::VU_UPPEROP_BIT_E)
{
//Force exception checking if microprogram is done
m_codeGen->PushCst(1);
m_codeGen->PushCst(MIPS_EXCEPTION_VU_EBIT);
m_codeGen->PullRel(offsetof(CMIPS, m_State.nHasException));
}
}
Expand Down
34 changes: 28 additions & 6 deletions Source/ee/Vpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define STATE_PATH_REGS_FORMAT ("vpu/vpu_%d.xml")

#define STATE_REGS_VUSTATE ("vuState")
#define STATE_REGS_FBRST ("fbrst")

CVpu::CVpu(unsigned int number, const VPUINIT& vpuInit, CGIF& gif, CINTC& intc, uint8* ram, uint8* spr)
: m_number(number)
Expand Down Expand Up @@ -53,16 +54,29 @@ void CVpu::Execute(int32 quota)
m_ctx->m_executor->Execute(quota);
switch(m_ctx->m_State.nHasException)
{
case 1:
case MIPS_EXCEPTION_VU_EBIT:
//E bit encountered
m_vuState = VU_STATE_READY;
VuStateChanged(m_vuState);
break;
case 2:
//T bit encountered
m_vuState = VU_STATE_STOPPED;
VuStateChanged(m_vuState);
VuInterruptTriggered();
case MIPS_EXCEPTION_VU_TBIT:
case MIPS_EXCEPTION_VU_DBIT:
//T/D bit encountered
{
bool mustBreak = false;
mustBreak |= (m_ctx->m_State.nHasException == MIPS_EXCEPTION_VU_TBIT) && (m_fbrst & FBRST_TE);
mustBreak |= (m_ctx->m_State.nHasException == MIPS_EXCEPTION_VU_DBIT) && (m_fbrst & FBRST_DE);
if(mustBreak)
{
m_vuState = VU_STATE_STOPPED;
VuStateChanged(m_vuState);
VuInterruptTriggered();
}
else
{
m_ctx->m_State.nHasException = 0;
}
}
break;
default:
break;
Expand Down Expand Up @@ -120,6 +134,7 @@ void CVpu::SaveState(Framework::CZipArchiveWriter& archive)
auto path = string_format(STATE_PATH_REGS_FORMAT, m_number);
auto registerFile = std::make_unique<CRegisterStateFile>(path.c_str());
registerFile->SetRegister32(STATE_REGS_VUSTATE, m_vuState);
registerFile->SetRegister32(STATE_REGS_FBRST, m_fbrst);
archive.InsertFile(std::move(registerFile));
}

Expand All @@ -132,6 +147,7 @@ void CVpu::LoadState(Framework::CZipArchiveReader& archive)
auto path = string_format(STATE_PATH_REGS_FORMAT, m_number);
CRegisterStateFile registerFile(*archive.BeginReadFile(path.c_str()));
m_vuState = static_cast<VU_STATE>(registerFile.GetRegister32(STATE_REGS_VUSTATE));
m_fbrst = registerFile.GetRegister32(STATE_REGS_FBRST);
}

m_vif->LoadState(archive);
Expand Down Expand Up @@ -167,6 +183,12 @@ CVif& CVpu::GetVif()
return *m_vif.get();
}

void CVpu::SetFbrst(uint32 fbrst)
{
//Only keep DE and TE bits
m_fbrst = (fbrst & (FBRST_DE | FBRST_TE));
}

void CVpu::ExecuteMicroProgram(uint32 nAddress)
{
CLog::GetInstance().Print(LOG_NAME, "Starting microprogram execution at 0x%08X.\r\n", nAddress);
Expand Down
16 changes: 14 additions & 2 deletions Source/ee/Vpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ class CVpu

EE_ADDR_VU1AREA_START = 0x1000FB00,
EE_ADDR_VU1AREA_END = 0x1000FEFF,
EE_ADDR_VU_CMSAR1 = 0x1000FFC0, //This is meant to be used by the EE through CTC2
EE_ADDR_VU_FBRST = 0x1000FFC0, //This is meant to be used by the EE through CTC2
EE_ADDR_VU_CMSAR1 = 0x1000FFC4, //This is meant to be used by the EE through CTC2
};

enum VU_STATE
Expand Down Expand Up @@ -63,7 +64,7 @@ class CVpu
uint32 GetMicroMemorySize() const;
uint8* GetVuMemory() const;
uint32 GetVuMemorySize() const;

inline VU_STATE GetVuState() const
{
return m_vuState;
Expand All @@ -81,6 +82,8 @@ class CVpu

CVif& GetVif();

void SetFbrst(uint32);

void ExecuteMicroProgram(uint32);
void InvalidateMicroProgram();
void InvalidateMicroProgram(uint32, uint32);
Expand All @@ -100,6 +103,14 @@ class CVpu
VuInterruptTriggeredEvent VuInterruptTriggered;

protected:
enum
{
FBRST_FB = (1 << 0),
FBRST_RS = (1 << 1),
FBRST_DE = (1 << 2),
FBRST_TE = (1 << 3),
};

typedef std::unique_ptr<CVif> VifPtr;

unsigned int m_number = 0;
Expand All @@ -120,6 +131,7 @@ class CVpu
#endif

VU_STATE m_vuState = VU_STATE_READY;
uint32 m_fbrst = 0;

CProfiler::ZoneHandle m_vuProfilerZone = 0;
};

0 comments on commit cdb0fa8

Please sign in to comment.