CPU: Simplify GTE register addressing
This commit is contained in:
parent
4e7d420a06
commit
a6dab97928
|
@ -642,6 +642,14 @@ void Core::ExecuteInstruction()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (m_current_instruction_pc == 0x8002bf50)
|
||||||
|
{
|
||||||
|
TRACE_EXECUTION = true;
|
||||||
|
__debugbreak();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if (TRACE_EXECUTION)
|
if (TRACE_EXECUTION)
|
||||||
PrintInstruction(inst.bits, m_current_instruction_pc, this);
|
PrintInstruction(inst.bits, m_current_instruction_pc, this);
|
||||||
|
@ -1219,7 +1227,7 @@ void Core::ExecuteInstruction()
|
||||||
if (!ReadMemoryWord(addr, &value))
|
if (!ReadMemoryWord(addr, &value))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_cop2.WriteDataRegister(ZeroExtend32(static_cast<u8>(inst.i.rt.GetValue())), value);
|
m_cop2.WriteRegister(ZeroExtend32(static_cast<u8>(inst.i.rt.GetValue())), value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1233,7 +1241,7 @@ void Core::ExecuteInstruction()
|
||||||
}
|
}
|
||||||
|
|
||||||
const VirtualMemoryAddress addr = ReadReg(inst.i.rs) + inst.i.imm_sext32();
|
const VirtualMemoryAddress addr = ReadReg(inst.i.rs) + inst.i.imm_sext32();
|
||||||
const u32 value = m_cop2.ReadDataRegister(ZeroExtend32(static_cast<u8>(inst.i.rt.GetValue())));
|
const u32 value = m_cop2.ReadRegister(ZeroExtend32(static_cast<u8>(inst.i.rt.GetValue())));
|
||||||
WriteMemoryWord(addr, value);
|
WriteMemoryWord(addr, value);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1317,19 +1325,19 @@ void Core::ExecuteCop2Instruction()
|
||||||
switch (inst.cop.CommonOp())
|
switch (inst.cop.CommonOp())
|
||||||
{
|
{
|
||||||
case CopCommonInstruction::cfcn:
|
case CopCommonInstruction::cfcn:
|
||||||
WriteRegDelayed(inst.r.rt, m_cop2.ReadControlRegister(static_cast<u32>(inst.r.rd.GetValue())));
|
WriteRegDelayed(inst.r.rt, m_cop2.ReadRegister(static_cast<u32>(inst.r.rd.GetValue()) + 32));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CopCommonInstruction::ctcn:
|
case CopCommonInstruction::ctcn:
|
||||||
m_cop2.WriteControlRegister(static_cast<u32>(inst.r.rd.GetValue()), ReadReg(inst.r.rt));
|
m_cop2.WriteRegister(static_cast<u32>(inst.r.rd.GetValue()) + 32, ReadReg(inst.r.rt));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CopCommonInstruction::mfcn:
|
case CopCommonInstruction::mfcn:
|
||||||
WriteRegDelayed(inst.r.rt, m_cop2.ReadDataRegister(static_cast<u32>(inst.r.rd.GetValue())));
|
WriteRegDelayed(inst.r.rt, m_cop2.ReadRegister(static_cast<u32>(inst.r.rd.GetValue())));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CopCommonInstruction::mtcn:
|
case CopCommonInstruction::mtcn:
|
||||||
m_cop2.WriteDataRegister(static_cast<u32>(inst.r.rd.GetValue()), ReadReg(inst.r.rt));
|
m_cop2.WriteRegister(static_cast<u32>(inst.r.rd.GetValue()), ReadReg(inst.r.rt));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CopCommonInstruction::bcnc:
|
case CopCommonInstruction::bcnc:
|
||||||
|
|
160
src/core/gte.cpp
160
src/core/gte.cpp
|
@ -55,19 +55,20 @@ void Core::Reset()
|
||||||
|
|
||||||
bool Core::DoState(StateWrapper& sw)
|
bool Core::DoState(StateWrapper& sw)
|
||||||
{
|
{
|
||||||
sw.DoArray(m_regs.dr32, NUM_DATA_REGS);
|
sw.DoArray(m_regs.r32, NUM_DATA_REGS + NUM_CONTROL_REGS);
|
||||||
sw.DoArray(m_regs.cr32, NUM_CONTROL_REGS);
|
|
||||||
return !sw.HasError();
|
return !sw.HasError();
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Core::ReadDataRegister(u32 index) const
|
u32 Core::ReadRegister(u32 index) const
|
||||||
{
|
{
|
||||||
|
DebugAssert(index < countof(m_regs.r32));
|
||||||
|
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
case 15: // SXY3
|
case 15: // SXY3
|
||||||
{
|
{
|
||||||
// mirror of SXY2
|
// mirror of SXY2
|
||||||
return m_regs.dr32[14];
|
return m_regs.r32[14];
|
||||||
}
|
}
|
||||||
|
|
||||||
case 28: // IRGB
|
case 28: // IRGB
|
||||||
|
@ -80,46 +81,23 @@ u32 Core::ReadDataRegister(u32 index) const
|
||||||
return ZeroExtend32(r) | (ZeroExtend32(g) << 5) | (ZeroExtend32(b) << 10);
|
return ZeroExtend32(r) | (ZeroExtend32(g) << 5) | (ZeroExtend32(b) << 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0: // V0-1 [x,y]
|
|
||||||
case 1: // V0[z]
|
|
||||||
case 2: // V1-2 [x,y]
|
|
||||||
case 3: // V1[z]
|
|
||||||
case 4: // V2-3 [x,y]
|
|
||||||
case 5: // V2[z]
|
|
||||||
case 6: // RGBC
|
|
||||||
case 7: // OTZ
|
|
||||||
case 8: // IR0
|
|
||||||
case 9: // IR1
|
|
||||||
case 10: // IR2
|
|
||||||
case 11: // IR3
|
|
||||||
case 12: // SXY0
|
|
||||||
case 13: // SXY1
|
|
||||||
case 14: // SXY2
|
|
||||||
case 16: // SZ0
|
|
||||||
case 17: // SZ1
|
|
||||||
case 18: // SZ2
|
|
||||||
case 19: // SZ3
|
|
||||||
case 20: // RGB0
|
|
||||||
case 21: // RGB1
|
|
||||||
case 22: // RGB2
|
|
||||||
case 23: // RES1
|
|
||||||
case 24: // MAC0
|
|
||||||
case 25: // MAC1
|
|
||||||
case 26: // MAC2
|
|
||||||
case 27: // MAC3
|
|
||||||
case 30: // LZCS
|
|
||||||
case 31: // LZCR
|
|
||||||
return m_regs.dr32[index];
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Panic("Unknown register");
|
return m_regs.r32[index];
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::WriteDataRegister(u32 index, u32 value)
|
void Core::WriteRegister(u32 index, u32 value)
|
||||||
{
|
{
|
||||||
// Log_DebugPrintf("DataReg(%u) <- 0x%08X", index, value);
|
#if 0
|
||||||
|
if (index < 32)
|
||||||
|
{
|
||||||
|
Log_DebugPrintf("DataReg(%u) <- 0x%08X", index, value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log_DebugPrintf("ControlReg(%u) <- 0x%08X", index, value);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (index)
|
switch (index)
|
||||||
{
|
{
|
||||||
|
@ -130,9 +108,16 @@ void Core::WriteDataRegister(u32 index, u32 value)
|
||||||
case 9: // IR1
|
case 9: // IR1
|
||||||
case 10: // IR2
|
case 10: // IR2
|
||||||
case 11: // IR3
|
case 11: // IR3
|
||||||
|
case 36: // RT33
|
||||||
|
case 44: // L33
|
||||||
|
case 52: // LR33
|
||||||
|
case 58: // H - sign-extended on read but zext on use
|
||||||
|
case 59: // DQA
|
||||||
|
case 61: // ZSF3
|
||||||
|
case 62: // ZSF4
|
||||||
{
|
{
|
||||||
// sign-extend z component of vector registers
|
// sign-extend z component of vector registers
|
||||||
m_regs.dr32[index] = SignExtend32(Truncate16(value));
|
m_regs.r32[index] = SignExtend32(Truncate16(value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -143,16 +128,16 @@ void Core::WriteDataRegister(u32 index, u32 value)
|
||||||
case 19: // SZ3
|
case 19: // SZ3
|
||||||
{
|
{
|
||||||
// zero-extend unsigned values
|
// zero-extend unsigned values
|
||||||
m_regs.dr32[index] = ZeroExtend32(Truncate16(value));
|
m_regs.r32[index] = ZeroExtend32(Truncate16(value));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 15: // SXY3
|
case 15: // SXY3
|
||||||
{
|
{
|
||||||
// writing to SXYP pushes to the FIFO
|
// writing to SXYP pushes to the FIFO
|
||||||
m_regs.dr32[12] = m_regs.dr32[13]; // SXY0 <- SXY1
|
m_regs.r32[12] = m_regs.r32[13]; // SXY0 <- SXY1
|
||||||
m_regs.dr32[13] = m_regs.dr32[14]; // SXY1 <- SXY2
|
m_regs.r32[13] = m_regs.r32[14]; // SXY1 <- SXY2
|
||||||
m_regs.dr32[14] = value; // SXY2 <- SXYP
|
m_regs.r32[14] = value; // SXY2 <- SXYP
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -160,9 +145,9 @@ void Core::WriteDataRegister(u32 index, u32 value)
|
||||||
{
|
{
|
||||||
// IRGB register, convert 555 to 16-bit
|
// IRGB register, convert 555 to 16-bit
|
||||||
m_regs.IRGB = value & UINT32_C(0x7FFF);
|
m_regs.IRGB = value & UINT32_C(0x7FFF);
|
||||||
m_regs.dr32[9] = SignExtend32(static_cast<u16>(Truncate16((value & UINT32_C(0x1F)) * UINT32_C(0x80))));
|
m_regs.r32[9] = SignExtend32(static_cast<u16>(Truncate16((value & UINT32_C(0x1F)) * UINT32_C(0x80))));
|
||||||
m_regs.dr32[10] = SignExtend32(static_cast<u16>(Truncate16(((value >> 5) & UINT32_C(0x1F)) * UINT32_C(0x80))));
|
m_regs.r32[10] = SignExtend32(static_cast<u16>(Truncate16(((value >> 5) & UINT32_C(0x1F)) * UINT32_C(0x80))));
|
||||||
m_regs.dr32[11] = SignExtend32(static_cast<u16>(Truncate16(((value >> 10) & UINT32_C(0x1F)) * UINT32_C(0x80))));
|
m_regs.r32[11] = SignExtend32(static_cast<u16>(Truncate16(((value >> 10) & UINT32_C(0x1F)) * UINT32_C(0x80))));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -180,94 +165,19 @@ void Core::WriteDataRegister(u32 index, u32 value)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0: // V0-1 [x,y]
|
case 63: // FLAG
|
||||||
case 2: // V1-2 [x,y]
|
|
||||||
case 4: // V2-3 [x,y]
|
|
||||||
case 6: // RGBC
|
|
||||||
case 12: // SXY0
|
|
||||||
case 13: // SXY1
|
|
||||||
case 14: // SXY2
|
|
||||||
case 20: // RGB0
|
|
||||||
case 21: // RGB1
|
|
||||||
case 22: // RGB2
|
|
||||||
case 23: // RES1
|
|
||||||
case 24: // MAC0
|
|
||||||
case 25: // MAC1
|
|
||||||
case 26: // MAC2
|
|
||||||
case 27: // MAC3
|
|
||||||
m_regs.dr32[index] = value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
Panic("Unknown register");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 Core::ReadControlRegister(u32 index) const
|
|
||||||
{
|
|
||||||
return m_regs.cr32[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
void Core::WriteControlRegister(u32 index, u32 value)
|
|
||||||
{
|
|
||||||
// Log_DebugPrintf("ControlReg(%u,%u) <- 0x%08X", index, index + 32, value);
|
|
||||||
|
|
||||||
switch (index)
|
|
||||||
{
|
|
||||||
case 36 - 32: // RT33
|
|
||||||
case 44 - 32: // L33
|
|
||||||
case 52 - 32: // LR33
|
|
||||||
case 58 - 32: // H - sign-extended on read but zext on use
|
|
||||||
case 59 - 32: // DQA
|
|
||||||
case 61 - 32: // ZSF3
|
|
||||||
case 62 - 32: // ZSF4
|
|
||||||
{
|
|
||||||
// MSB of the last matrix element is the last element sign-extended
|
|
||||||
m_regs.cr32[index] = SignExtend32(Truncate16(value));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 63 - 32: // FLAG
|
|
||||||
{
|
{
|
||||||
m_regs.FLAG.bits = value & UINT32_C(0x7FFFF000);
|
m_regs.FLAG.bits = value & UINT32_C(0x7FFFF000);
|
||||||
m_regs.FLAG.UpdateError();
|
m_regs.FLAG.UpdateError();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 32 - 32: // RT11,RT12
|
default:
|
||||||
case 33 - 32: // RT13,RT21
|
|
||||||
case 34 - 32: // RT22,RT23
|
|
||||||
case 35 - 32: // RT31,RT32
|
|
||||||
case 37 - 32: // TRX
|
|
||||||
case 38 - 32: // TRY
|
|
||||||
case 39 - 32: // TRZ
|
|
||||||
case 40 - 32: // L11,L12
|
|
||||||
case 41 - 32: // L13,L21
|
|
||||||
case 42 - 32: // L22,L23
|
|
||||||
case 43 - 32: // L31,L32
|
|
||||||
case 45 - 32: // RBK
|
|
||||||
case 46 - 32: // GBK
|
|
||||||
case 47 - 32: // BBK
|
|
||||||
case 48 - 32: // LR11,LR12
|
|
||||||
case 49 - 32: // LR13,LR21
|
|
||||||
case 50 - 32: // LR22,LR23
|
|
||||||
case 51 - 32: // LR31,LR32
|
|
||||||
case 53 - 32: // RFC
|
|
||||||
case 54 - 32: // GFC
|
|
||||||
case 55 - 32: // BFC
|
|
||||||
case 56 - 32: // OFX
|
|
||||||
case 57 - 32: // OFY
|
|
||||||
case 60 - 32: // DQB
|
|
||||||
{
|
{
|
||||||
// written as-is, 2x16 or 1x32 bits
|
// written as-is, 2x16 or 1x32 bits
|
||||||
m_regs.cr32[index] = value;
|
m_regs.r32[index] = value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
|
||||||
Panic("Unknown register");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,14 +14,9 @@ public:
|
||||||
void Reset();
|
void Reset();
|
||||||
bool DoState(StateWrapper& sw);
|
bool DoState(StateWrapper& sw);
|
||||||
|
|
||||||
u32 ReadRegister(u32 index) const { return m_regs.dr32[index]; }
|
// control registers are offset by +32
|
||||||
void WriteRegister(u32 index, u32 value) { m_regs.dr32[index] = value; }
|
u32 ReadRegister(u32 index) const;
|
||||||
|
void WriteRegister(u32 index, u32 value);
|
||||||
u32 ReadDataRegister(u32 index) const;
|
|
||||||
void WriteDataRegister(u32 index, u32 value);
|
|
||||||
|
|
||||||
u32 ReadControlRegister(u32 index) const;
|
|
||||||
void WriteControlRegister(u32 index, u32 value);
|
|
||||||
|
|
||||||
void ExecuteInstruction(Instruction inst);
|
void ExecuteInstruction(Instruction inst);
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,8 @@ union Regs
|
||||||
u32 cr32[NUM_CONTROL_REGS];
|
u32 cr32[NUM_CONTROL_REGS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
u32 r32[NUM_DATA_REGS + NUM_CONTROL_REGS];
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue