project64/Source/Project64-rsp-core/cpu/RSPRegister.cpp

109 lines
2.2 KiB
C++

#include "RspTypes.h"
#include <Project64-rsp-core/cpu/RSPRegisters.h>
#include <string.h>
const char * GPR_Strings[32] = {
"R0",
"AT",
"V0",
"V1",
"A0",
"A1",
"A2",
"A3",
"T0",
"T1",
"T2",
"T3",
"T4",
"T5",
"T6",
"T7",
"S0",
"S1",
"S2",
"S3",
"S4",
"S5",
"S6",
"S7",
"T8",
"T9",
"K0",
"K1",
"GP",
"SP",
"S8",
"RA",
};
CRSPRegisters::CRSPRegisters() :
VCOL(m_Flags[0].UB[0]),
VCOH(m_Flags[0].UB[1]),
VCCL(m_Flags[1].UB[0]),
VCCH(m_Flags[1].UB[1]),
VCE(m_Flags[2].UB[0])
{
Reset();
}
void CRSPRegisters::Reset(void)
{
memset(m_GPR, 0, sizeof(m_GPR));
for (size_t i = 0, n = sizeof(m_Vect) / sizeof(m_Vect[0]); i < n; i++)
{
m_Vect[i] = RSPVector();
}
m_Reciprocals[0] = 0xFFFF;
for (uint16_t i = 1; i < 512; i++)
{
m_Reciprocals[i] = uint16_t((((1ull << 34) / (uint64_t)(i + 512)) + 1) >> 8);
}
for (uint16_t i = 0; i < 512; i++)
{
uint64_t a = (i + 512) >> ((i % 2 == 1) ? 1 : 0);
uint64_t b = 1 << 17;
while (a * (b + 1) * (b + 1) < (uint64_t(1) << 44))
{
b++;
}
m_InverseSquareRoots[i] = uint16_t(b >> 1);
}
m_Result = 0;
m_In = 0;
m_High = false;
}
int64_t CRSPRegisters::AccumulatorGet(uint8_t el)
{
return (((int64_t)m_ACCUM[el].HW[3]) << 32) | (((int64_t)m_ACCUM[el].UHW[2]) << 16) | m_ACCUM[el].UHW[1];
}
void CRSPRegisters::AccumulatorSet(uint8_t el, int64_t Accumulator)
{
m_ACCUM[el].HW[3] = (int16_t)(Accumulator >> 32);
m_ACCUM[el].HW[2] = (int16_t)(Accumulator >> 16);
m_ACCUM[el].HW[1] = (int16_t)(Accumulator);
}
uint16_t CRSPRegisters::AccumulatorSaturate(uint8_t el, bool High)
{
if (m_ACCUM[el].HW[3] < 0)
{
if (m_ACCUM[el].UHW[3] != 0xFFFF || m_ACCUM[el].HW[2] >= 0)
{
return High ? 0x8000 : 0x0000;
}
else
{
return m_ACCUM[el].UHW[High ? 2 : 1];
}
}
if (m_ACCUM[el].UHW[3] != 0 || m_ACCUM[el].HW[2] < 0)
{
return High ? 0x7fff : 0xffff;
}
return m_ACCUM[el].UHW[High ? 2 : 1];
}