mirror of
https://github.com/libretro/Play-.git
synced 2025-02-12 20:29:11 +00:00
Merge branch 'justice_league_heroes'
This commit is contained in:
commit
d3bf023d28
@ -48,12 +48,66 @@ void CEEAssembler::PEXCH(unsigned int rd, unsigned int rt)
|
||||
m_ptr++;
|
||||
}
|
||||
|
||||
void CEEAssembler::PEXTLB(unsigned int rd, unsigned int rs, unsigned int rt)
|
||||
{
|
||||
(*m_ptr) = ((0x1C) << 26) | (rs << 21) | (rt << 16) | (rd << 11) | ((0x1A) << 6) | (0x08);
|
||||
m_ptr++;
|
||||
}
|
||||
|
||||
void CEEAssembler::PEXTUB(unsigned int rd, unsigned int rs, unsigned int rt)
|
||||
{
|
||||
(*m_ptr) = ((0x1C) << 26) | (rs << 21) | (rt << 16) | (rd << 11) | ((0x1A) << 6) | (0x28);
|
||||
m_ptr++;
|
||||
}
|
||||
|
||||
void CEEAssembler::PEXTLH(unsigned int rd, unsigned int rs, unsigned int rt)
|
||||
{
|
||||
(*m_ptr) = ((0x1C) << 26) | (rs << 21) | (rt << 16) | (rd << 11) | ((0x16) << 6) | (0x08);
|
||||
m_ptr++;
|
||||
}
|
||||
|
||||
void CEEAssembler::PEXTUH(unsigned int rd, unsigned int rs, unsigned int rt)
|
||||
{
|
||||
(*m_ptr) = ((0x1C) << 26) | (rs << 21) | (rt << 16) | (rd << 11) | ((0x16) << 6) | (0x28);
|
||||
m_ptr++;
|
||||
}
|
||||
|
||||
void CEEAssembler::PEXCW(unsigned int rd, unsigned int rt)
|
||||
{
|
||||
(*m_ptr) = ((0x1C) << 26) | (rt << 16) | (rd << 11) | ((0x1E) << 6) | (0x29);
|
||||
m_ptr++;
|
||||
}
|
||||
|
||||
void CEEAssembler::PMFLO(unsigned int rd)
|
||||
{
|
||||
(*m_ptr) = ((0x1C) << 26) | (rd << 11) | ((0x09) << 6) | (0x09);
|
||||
m_ptr++;
|
||||
}
|
||||
|
||||
void CEEAssembler::PMFHI(unsigned int rd)
|
||||
{
|
||||
(*m_ptr) = ((0x1C) << 26) | (rd << 11) | ((0x08) << 6) | (0x09);
|
||||
m_ptr++;
|
||||
}
|
||||
|
||||
void CEEAssembler::PMFHL_UW(unsigned int rd)
|
||||
{
|
||||
(*m_ptr) = ((0x1C) << 26) | (rd << 11) | ((0x01) << 6) | (0x30);
|
||||
m_ptr++;
|
||||
}
|
||||
|
||||
void CEEAssembler::PMULTH(unsigned int rd, unsigned int rs, unsigned int rt)
|
||||
{
|
||||
(*m_ptr) = ((0x1C) << 26) | (rs << 21) | (rt << 16) | (rd << 11) | ((0x1C) << 6) | (0x09);
|
||||
m_ptr++;
|
||||
}
|
||||
|
||||
void CEEAssembler::PPACH(unsigned int rd, unsigned int rs, unsigned int rt)
|
||||
{
|
||||
(*m_ptr) = ((0x1C) << 26) | (rs << 21) | (rt << 16) | (rd << 11) | ((0x17) << 6) | (0x08);
|
||||
m_ptr++;
|
||||
}
|
||||
|
||||
void CEEAssembler::PPACW(unsigned int rd, unsigned int rs, unsigned int rt)
|
||||
{
|
||||
(*m_ptr) = ((0x1C) << 26) | (rs << 21) | (rt << 16) | (rd << 11) | ((0x13) << 6) | (0x08);
|
||||
|
@ -14,7 +14,16 @@ public:
|
||||
void MTLO1(unsigned int);
|
||||
void PADDW(unsigned int, unsigned int, unsigned int);
|
||||
void PEXCH(unsigned int, unsigned int);
|
||||
void PEXTLB(unsigned int, unsigned int, unsigned int);
|
||||
void PEXTUB(unsigned int, unsigned int, unsigned int);
|
||||
void PEXTLH(unsigned int, unsigned int, unsigned int);
|
||||
void PEXTUH(unsigned int, unsigned int, unsigned int);
|
||||
void PEXCW(unsigned int, unsigned int);
|
||||
void PMFLO(unsigned int);
|
||||
void PMFHI(unsigned int);
|
||||
void PMFHL_UW(unsigned int);
|
||||
void PMULTH(unsigned int, unsigned int, unsigned int);
|
||||
void PPACH(unsigned int, unsigned int, unsigned int);
|
||||
void PPACW(unsigned int, unsigned int, unsigned int);
|
||||
void SQ(unsigned int, uint16, unsigned int);
|
||||
};
|
||||
|
@ -382,6 +382,15 @@ void CMA_EE::PADDH()
|
||||
PullVector(m_nRD);
|
||||
}
|
||||
|
||||
//05
|
||||
void CMA_EE::PSUBH()
|
||||
{
|
||||
PushVector(m_nRS);
|
||||
PushVector(m_nRT);
|
||||
m_codeGen->MD_SubH();
|
||||
PullVector(m_nRD);
|
||||
}
|
||||
|
||||
//06
|
||||
void CMA_EE::PCGTH()
|
||||
{
|
||||
@ -618,6 +627,24 @@ void CMA_EE::PEXTUW()
|
||||
PullVector(m_nRD);
|
||||
}
|
||||
|
||||
//15
|
||||
void CMA_EE::PSUBUH()
|
||||
{
|
||||
PushVector(m_nRS);
|
||||
PushVector(m_nRT);
|
||||
m_codeGen->MD_SubHUS();
|
||||
PullVector(m_nRD);
|
||||
}
|
||||
|
||||
//16
|
||||
void CMA_EE::PEXTUH()
|
||||
{
|
||||
PushVector(m_nRS);
|
||||
PushVector(m_nRT);
|
||||
m_codeGen->MD_UnpackUpperHW();
|
||||
PullVector(m_nRD);
|
||||
}
|
||||
|
||||
//18
|
||||
void CMA_EE::PADDUB()
|
||||
{
|
||||
@ -627,6 +654,15 @@ void CMA_EE::PADDUB()
|
||||
PullVector(m_nRD);
|
||||
}
|
||||
|
||||
//19
|
||||
void CMA_EE::PSUBUB()
|
||||
{
|
||||
PushVector(m_nRS);
|
||||
PushVector(m_nRT);
|
||||
m_codeGen->MD_SubBUS();
|
||||
PullVector(m_nRD);
|
||||
}
|
||||
|
||||
//1A
|
||||
void CMA_EE::PEXTUB()
|
||||
{
|
||||
@ -936,6 +972,25 @@ void CMA_EE::PMTHI()
|
||||
}
|
||||
}
|
||||
|
||||
//0A
|
||||
void CMA_EE::PINTEH()
|
||||
{
|
||||
for(unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[i]));
|
||||
m_codeGen->Shl(16);
|
||||
m_codeGen->PushCst(0xFFFF0000);
|
||||
m_codeGen->And();
|
||||
|
||||
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[i]));
|
||||
m_codeGen->PushCst(0xFFFF);
|
||||
m_codeGen->And();
|
||||
|
||||
m_codeGen->Or();
|
||||
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[i]));
|
||||
}
|
||||
}
|
||||
|
||||
//0E
|
||||
void CMA_EE::PCPYUD()
|
||||
{
|
||||
@ -951,7 +1006,7 @@ void CMA_EE::PCPYUD()
|
||||
m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[3]));
|
||||
|
||||
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[3]));
|
||||
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[2]));
|
||||
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[2]));
|
||||
}
|
||||
|
||||
//12
|
||||
@ -1057,6 +1112,7 @@ void CMA_EE::PEXCW()
|
||||
//PMFHL
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
//00
|
||||
void CMA_EE::PMFHL_LW()
|
||||
{
|
||||
m_codeGen->PushRel(offsetof(CMIPS, m_State.nLO[0]));
|
||||
@ -1072,6 +1128,22 @@ void CMA_EE::PMFHL_LW()
|
||||
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[3]));
|
||||
}
|
||||
|
||||
//01
|
||||
void CMA_EE::PMFHL_UW()
|
||||
{
|
||||
m_codeGen->PushRel(offsetof(CMIPS, m_State.nLO[1]));
|
||||
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[0]));
|
||||
|
||||
m_codeGen->PushRel(offsetof(CMIPS, m_State.nHI[1]));
|
||||
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[1]));
|
||||
|
||||
m_codeGen->PushRel(offsetof(CMIPS, m_State.nLO1[1]));
|
||||
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[2]));
|
||||
|
||||
m_codeGen->PushRel(offsetof(CMIPS, m_State.nHI1[1]));
|
||||
m_codeGen->PullRel(offsetof(CMIPS, m_State.nGPR[m_nRD].nV[3]));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
//Generic Stuff
|
||||
//////////////////////////////////////////////////
|
||||
@ -1152,7 +1224,7 @@ void CMA_EE::Generic_MADD(unsigned int unit, bool isSigned)
|
||||
CMA_EE::InstructionFuncConstant CMA_EE::m_pOpMmi0[0x20] =
|
||||
{
|
||||
//0x00
|
||||
&CMA_EE::PADDW, &CMA_EE::PSUBW, &CMA_EE::PCGTW, &CMA_EE::PMAXW, &CMA_EE::PADDH, &CMA_EE::Illegal, &CMA_EE::PCGTH, &CMA_EE::PMAXH,
|
||||
&CMA_EE::PADDW, &CMA_EE::PSUBW, &CMA_EE::PCGTW, &CMA_EE::PMAXW, &CMA_EE::PADDH, &CMA_EE::PSUBH, &CMA_EE::PCGTH, &CMA_EE::PMAXH,
|
||||
//0x08
|
||||
&CMA_EE::PADDB, &CMA_EE::PSUBB, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal,
|
||||
//0x10
|
||||
@ -1168,9 +1240,9 @@ CMA_EE::InstructionFuncConstant CMA_EE::m_pOpMmi1[0x20] =
|
||||
//0x08
|
||||
&CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::PCEQB, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal,
|
||||
//0x10
|
||||
&CMA_EE::PADDUW, &CMA_EE::Illegal, &CMA_EE::PEXTUW, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal,
|
||||
&CMA_EE::PADDUW, &CMA_EE::Illegal, &CMA_EE::PEXTUW, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::PSUBUH, &CMA_EE::PEXTUH, &CMA_EE::Illegal,
|
||||
//0x18
|
||||
&CMA_EE::PADDUB, &CMA_EE::Illegal, &CMA_EE::PEXTUB, &CMA_EE::QFSRV, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal,
|
||||
&CMA_EE::PADDUB, &CMA_EE::PSUBUB, &CMA_EE::PEXTUB, &CMA_EE::QFSRV, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal,
|
||||
};
|
||||
|
||||
CMA_EE::InstructionFuncConstant CMA_EE::m_pOpMmi2[0x20] =
|
||||
@ -1190,7 +1262,7 @@ CMA_EE::InstructionFuncConstant CMA_EE::m_pOpMmi3[0x20] =
|
||||
//0x00
|
||||
&CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal,
|
||||
//0x08
|
||||
&CMA_EE::PMTHI, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::PCPYUD, &CMA_EE::Illegal,
|
||||
&CMA_EE::PMTHI, &CMA_EE::Illegal, &CMA_EE::PINTEH, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::PCPYUD, &CMA_EE::Illegal,
|
||||
//0x10
|
||||
&CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::POR, &CMA_EE::PNOR, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal,
|
||||
//0x18
|
||||
@ -1200,7 +1272,7 @@ CMA_EE::InstructionFuncConstant CMA_EE::m_pOpMmi3[0x20] =
|
||||
CMA_EE::InstructionFuncConstant CMA_EE::m_pOpPmfhl[0x20] =
|
||||
{
|
||||
//0x00
|
||||
&CMA_EE::PMFHL_LW, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal,
|
||||
&CMA_EE::PMFHL_LW, &CMA_EE::PMFHL_UW, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal,
|
||||
//0x08
|
||||
&CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal, &CMA_EE::Illegal,
|
||||
//0x10
|
||||
|
@ -82,6 +82,7 @@ private:
|
||||
void PCGTW();
|
||||
void PMAXW();
|
||||
void PADDH();
|
||||
void PSUBH();
|
||||
void PCGTH();
|
||||
void PMAXH();
|
||||
void PADDB();
|
||||
@ -105,7 +106,10 @@ private:
|
||||
void PCEQB();
|
||||
void PADDUW();
|
||||
void PEXTUW();
|
||||
void PSUBUH();
|
||||
void PEXTUH();
|
||||
void PADDUB();
|
||||
void PSUBUB();
|
||||
void PEXTUB();
|
||||
void QFSRV();
|
||||
|
||||
@ -123,6 +127,7 @@ private:
|
||||
|
||||
//Mmi3
|
||||
void PMTHI();
|
||||
void PINTEH();
|
||||
void PCPYUD();
|
||||
void POR();
|
||||
void PNOR();
|
||||
@ -132,6 +137,7 @@ private:
|
||||
|
||||
//Pmfhl
|
||||
void PMFHL_LW();
|
||||
void PMFHL_UW();
|
||||
|
||||
void Generic_MADD(unsigned int unit, bool isSigned);
|
||||
|
||||
|
@ -104,7 +104,7 @@ INSTRUCTION CMA_EE::m_cReflMmi0[32] =
|
||||
{ "PCGTW", NULL, CopyMnemonic, ReflOpRdRsRt, NULL, NULL },
|
||||
{ "PMAXW", NULL, CopyMnemonic, ReflOpRdRsRt, NULL, NULL },
|
||||
{ "PADDH", NULL, CopyMnemonic, ReflOpRdRsRt, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ "PSUBH", NULL, CopyMnemonic, ReflOpRdRsRt, NULL, NULL },
|
||||
{ "PCGTH", NULL, CopyMnemonic, ReflOpRdRsRt, NULL, NULL },
|
||||
{ "PMAXH", NULL, CopyMnemonic, ReflOpRdRsRt, NULL, NULL },
|
||||
//0x08
|
||||
@ -162,12 +162,12 @@ INSTRUCTION CMA_EE::m_cReflMmi1[32] =
|
||||
{ "PEXTUW", NULL, CopyMnemonic, ReflOpRdRsRt, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ "PSUBUH", NULL, CopyMnemonic, ReflOpRdRsRt, NULL, NULL },
|
||||
{ "PEXTUH", NULL, CopyMnemonic, ReflOpRdRsRt, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
//0x18
|
||||
{ "PADDUB", NULL, CopyMnemonic, ReflOpRdRsRt, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ "PSUBUB", NULL, CopyMnemonic, ReflOpRdRsRt, NULL, NULL },
|
||||
{ "PEXTUB", NULL, CopyMnemonic, ReflOpRdRsRt, NULL, NULL },
|
||||
{ "QFSRV", NULL, CopyMnemonic, ReflOpRdRsRt, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
@ -230,7 +230,7 @@ INSTRUCTION CMA_EE::m_cReflMmi3[32] =
|
||||
//0x08
|
||||
{ "PMTHI", NULL, CopyMnemonic, ReflOpRs, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ "PINTEH", NULL, CopyMnemonic, ReflOpRdRsRt, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
@ -260,7 +260,7 @@ INSTRUCTION CMA_EE::m_cReflPmfhl[32] =
|
||||
{
|
||||
//0x00
|
||||
{ "PMFHL.LW", NULL, CopyMnemonic, ReflOpRd, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ "PMFHL.UW", NULL, CopyMnemonic, ReflOpRd, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL },
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "StructCollectionStateFile.h"
|
||||
#include "lexical_cast_ex.h"
|
||||
|
||||
#define CMD_RECVADDR (CIopBios::CONTROL_BLOCK_END)
|
||||
#define RPC_RECVADDR 0xDEADBEEF
|
||||
|
||||
#define LOG_NAME ("sif")
|
||||
@ -41,17 +40,9 @@
|
||||
#define STATE_PACKET_REQUEST_END_CLIENTBUFFER ("Packet_Request_End_ClientBuffer")
|
||||
|
||||
CSIF::CSIF(CDMAC& dmac, uint8* eeRam, uint8* iopRam)
|
||||
: m_nMAINADDR(0)
|
||||
, m_nSUBADDR(0)
|
||||
, m_nMSFLAG(0)
|
||||
, m_nSMFLAG(0)
|
||||
, m_nEERecvAddr(0)
|
||||
, m_nDataAddr(0)
|
||||
, m_dmac(dmac)
|
||||
: m_dmac(dmac)
|
||||
, m_eeRam(eeRam)
|
||||
, m_iopRam(iopRam)
|
||||
, m_dmaBuffer(NULL)
|
||||
, m_dmaBufferSize(0)
|
||||
{
|
||||
|
||||
}
|
||||
@ -64,8 +55,7 @@ CSIF::~CSIF()
|
||||
void CSIF::Reset()
|
||||
{
|
||||
m_nMAINADDR = 0;
|
||||
//This should be the address to which the IOP receives its requests from the EE
|
||||
m_nSUBADDR = CMD_RECVADDR;
|
||||
m_nSUBADDR = 0;
|
||||
m_nMSFLAG = 0;
|
||||
// m_nSMFLAG = 0x20000;
|
||||
m_nSMFLAG = 0x60000;
|
||||
@ -83,10 +73,17 @@ void CSIF::Reset()
|
||||
|
||||
void CSIF::SetDmaBuffer(uint32 bufferAddress, uint32 size)
|
||||
{
|
||||
m_dmaBuffer = m_iopRam + bufferAddress;
|
||||
m_dmaBufferAddress = bufferAddress;
|
||||
m_dmaBufferSize = size;
|
||||
}
|
||||
|
||||
void CSIF::SetCmdBuffer(uint32 bufferAddress, uint32 size)
|
||||
{
|
||||
m_cmdBufferAddress = bufferAddress;
|
||||
m_cmdBufferSize = size;
|
||||
m_nSUBADDR = bufferAddress;
|
||||
}
|
||||
|
||||
void CSIF::RegisterModule(uint32 moduleId, CSifModule* module)
|
||||
{
|
||||
m_modules[moduleId] = module;
|
||||
@ -120,7 +117,7 @@ uint32 CSIF::ReceiveDMA5(uint32 srcAddress, uint32 size, uint32 unused, bool isT
|
||||
{
|
||||
throw std::runtime_error("Packet too big.");
|
||||
}
|
||||
memcpy(m_eeRam + srcAddress, m_dmaBuffer, size);
|
||||
memcpy(m_eeRam + srcAddress, m_iopRam + m_dmaBufferAddress, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
@ -138,7 +135,7 @@ uint32 CSIF::ReceiveDMA6(uint32 nSrcAddr, uint32 nSize, uint32 nDstAddr, bool is
|
||||
m_nDataAddr = nSrcAddr;
|
||||
return nSize;
|
||||
}
|
||||
else if(nDstAddr == CMD_RECVADDR)
|
||||
else if(nDstAddr == m_nSUBADDR)
|
||||
{
|
||||
auto hdr = reinterpret_cast<SIFCMDHEADER*>(m_eeRam + nSrcAddr);
|
||||
|
||||
@ -173,7 +170,8 @@ uint32 CSIF::ReceiveDMA6(uint32 nSrcAddr, uint32 nSize, uint32 nDstAddr, bool is
|
||||
default:
|
||||
if(m_customCommandHandler)
|
||||
{
|
||||
m_customCommandHandler(hdr);
|
||||
memcpy(m_iopRam + nDstAddr, m_eeRam + nSrcAddr, nSize);
|
||||
m_customCommandHandler(nDstAddr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -185,7 +183,7 @@ uint32 CSIF::ReceiveDMA6(uint32 nSrcAddr, uint32 nSize, uint32 nDstAddr, bool is
|
||||
assert(nDstAddr < PS2::IOP_RAM_SIZE);
|
||||
CLog::GetInstance().Print(LOG_NAME, "WriteToIop(dstAddr = 0x%0.8X, srcAddr = 0x%0.8X, size = 0x%0.8X);\r\n",
|
||||
nDstAddr, nSrcAddr, nSize);
|
||||
if(nDstAddr >= 0 && nDstAddr <= CMD_RECVADDR)
|
||||
if(nDstAddr >= 0 && nDstAddr <= CIopBios::CONTROL_BLOCK_END)
|
||||
{
|
||||
CLog::GetInstance().Print(LOG_NAME, "Warning: Trying to DMA in Bios Control Area.\r\n");
|
||||
}
|
||||
@ -234,7 +232,7 @@ void CSIF::SendDMA(void* pData, uint32 nSize)
|
||||
throw std::runtime_error("Packet too big.");
|
||||
}
|
||||
|
||||
memcpy(m_dmaBuffer, pData, nSize);
|
||||
memcpy(m_iopRam + m_dmaBufferAddress, pData, nSize);
|
||||
uint32 nQuads = (nSize + 0x0F) / 0x10;
|
||||
|
||||
m_dmac.SetRegister(CDMAC::D5_MADR, m_nEERecvAddr);
|
||||
|
21
Source/SIF.h
21
Source/SIF.h
@ -13,7 +13,7 @@
|
||||
class CSIF
|
||||
{
|
||||
public:
|
||||
typedef std::function<void (const SIFCMDHEADER*)> CustomCommandHandler;
|
||||
typedef std::function<void (uint32)> CustomCommandHandler;
|
||||
|
||||
CSIF(CDMAC&, uint8*, uint8*);
|
||||
virtual ~CSIF();
|
||||
@ -27,6 +27,7 @@ public:
|
||||
bool IsModuleRegistered(uint32) const;
|
||||
void UnregisterModule(uint32);
|
||||
void SetDmaBuffer(uint32, uint32);
|
||||
void SetCmdBuffer(uint32, uint32);
|
||||
void SendCallReply(uint32, const void*);
|
||||
void SetCustomCommandHandler(const CustomCommandHandler&);
|
||||
|
||||
@ -85,17 +86,19 @@ private:
|
||||
|
||||
uint8* m_eeRam;
|
||||
uint8* m_iopRam;
|
||||
uint8* m_dmaBuffer;
|
||||
uint32 m_dmaBufferSize;
|
||||
uint32 m_dmaBufferAddress = 0;
|
||||
uint32 m_dmaBufferSize = 0;
|
||||
uint32 m_cmdBufferAddress = 0;
|
||||
uint32 m_cmdBufferSize = 0;
|
||||
CDMAC& m_dmac;
|
||||
|
||||
uint32 m_nMAINADDR;
|
||||
uint32 m_nSUBADDR;
|
||||
uint32 m_nMSFLAG;
|
||||
uint32 m_nSMFLAG;
|
||||
uint32 m_nMAINADDR = 0;
|
||||
uint32 m_nSUBADDR = 0;
|
||||
uint32 m_nMSFLAG = 0;
|
||||
uint32 m_nSMFLAG = 0;
|
||||
|
||||
uint32 m_nEERecvAddr;
|
||||
uint32 m_nDataAddr;
|
||||
uint32 m_nEERecvAddr = 0;
|
||||
uint32 m_nDataAddr = 0;
|
||||
|
||||
uint32 m_nUserReg[MAX_USERREG];
|
||||
|
||||
|
@ -216,11 +216,18 @@ void CIopBios::Reset(Iop::CSifMan* sifMan)
|
||||
}
|
||||
#endif
|
||||
|
||||
const int sifDmaBufferSize = 0x1000;
|
||||
uint32 sifDmaBufferPtr = m_sysmem->AllocateMemory(sifDmaBufferSize, 0, 0);
|
||||
#ifndef _NULL_SIFMAN
|
||||
m_sifMan->SetDmaBuffer(sifDmaBufferPtr, sifDmaBufferSize);
|
||||
#endif
|
||||
{
|
||||
const int sifDmaBufferSize = 0x1000;
|
||||
uint32 sifDmaBufferPtr = m_sysmem->AllocateMemory(sifDmaBufferSize, 0, 0);
|
||||
m_sifMan->SetDmaBuffer(sifDmaBufferPtr, sifDmaBufferSize);
|
||||
}
|
||||
|
||||
{
|
||||
const int sifCmdBufferSize = 0x100;
|
||||
uint32 sifCmdBufferPtr = m_sysmem->AllocateMemory(sifCmdBufferSize, 0, 0);
|
||||
m_sifMan->SetCmdBuffer(sifCmdBufferPtr, sifCmdBufferSize);
|
||||
}
|
||||
|
||||
m_sifMan->GenerateHandlers(m_ram, *m_sysmem);
|
||||
|
||||
InitializeModuleLoader();
|
||||
@ -1995,6 +2002,39 @@ void CIopBios::RelocateElf(CELF& elf, uint32 baseAddress)
|
||||
}
|
||||
}
|
||||
|
||||
void CIopBios::TriggerCallback(uint32 address, uint32 arg0, uint32 arg1)
|
||||
{
|
||||
// Call the addres on a callback thread with A0 set to arg0
|
||||
uint32 callbackThreadId = -1;
|
||||
|
||||
//Find a thread we could recycle for a new callback
|
||||
for (auto threadIterator = m_threads.Begin();
|
||||
threadIterator != m_threads.End(); threadIterator++)
|
||||
{
|
||||
const auto& thread(m_threads[threadIterator]);
|
||||
if(thread == nullptr) continue;
|
||||
if(thread->threadProc != address) continue;
|
||||
if(thread->status == THREAD_STATUS_DORMANT)
|
||||
{
|
||||
callbackThreadId = thread->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//If no threads are available, create a new one
|
||||
if(callbackThreadId == -1)
|
||||
{
|
||||
callbackThreadId = CreateThread(address, DEFAULT_PRIORITY, DEFAULT_STACKSIZE, 0);
|
||||
}
|
||||
|
||||
ChangeThreadPriority(callbackThreadId, 1);
|
||||
StartThread(callbackThreadId);
|
||||
|
||||
auto thread = GetThread(callbackThreadId);
|
||||
thread->context.gpr[CMIPS::A0] = arg0;
|
||||
thread->context.gpr[CMIPS::A1] = arg1;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Debug Stuff
|
||||
|
||||
|
@ -161,6 +161,8 @@ public:
|
||||
bool RegisterIntrHandler(uint32, uint32, uint32, uint32);
|
||||
bool ReleaseIntrHandler(uint32);
|
||||
|
||||
void TriggerCallback(uint32 address, uint32 arg0, uint32 arg1);
|
||||
|
||||
#ifdef DEBUGGER_INCLUDED
|
||||
void LoadDebugTags(Framework::Xml::CNode*);
|
||||
void SaveDebugTags(Framework::Xml::CNode*);
|
||||
|
@ -7,9 +7,10 @@ using namespace Iop;
|
||||
|
||||
#define LOG_NAME "iop_loadcore"
|
||||
|
||||
#define FUNCTION_FLUSHDCACHE "FlushDcache"
|
||||
#define FUNCTION_REGISTERLIBRARYENTRIES "RegisterLibraryEntries"
|
||||
#define FUNCTION_QUERYBOOTMODE "QueryBootMode"
|
||||
#define FUNCTION_FLUSHDCACHE "FlushDcache"
|
||||
#define FUNCTION_REGISTERLIBRARYENTRIES "RegisterLibraryEntries"
|
||||
#define FUNCTION_QUERYBOOTMODE "QueryBootMode"
|
||||
#define FUNCTION_SETREBOOTTIMELIBHANDLINGMODE "SetRebootTimeLibraryHandlingMode"
|
||||
|
||||
#define PATH_MAX_SIZE 252
|
||||
#define ARGS_MAX_SIZE 252
|
||||
@ -44,6 +45,9 @@ std::string CLoadcore::GetFunctionName(unsigned int functionId) const
|
||||
case 12:
|
||||
return FUNCTION_QUERYBOOTMODE;
|
||||
break;
|
||||
case 27:
|
||||
return FUNCTION_SETREBOOTTIMELIBHANDLINGMODE;
|
||||
break;
|
||||
default:
|
||||
return "unknown";
|
||||
break;
|
||||
@ -67,6 +71,12 @@ void CLoadcore::Invoke(CMIPS& context, unsigned int functionId)
|
||||
context.m_State.nGPR[CMIPS::A0].nV0
|
||||
));
|
||||
break;
|
||||
case 27:
|
||||
context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(SetRebootTimeLibraryHandlingMode(
|
||||
context.m_State.nGPR[CMIPS::A0].nV0,
|
||||
context.m_State.nGPR[CMIPS::A1].nV0
|
||||
));
|
||||
break;
|
||||
default:
|
||||
CLog::GetInstance().Print(LOG_NAME, "Unknown function (%d) called (PC: 0x%0.8X).\r\n",
|
||||
functionId, context.m_State.nPC);
|
||||
@ -121,6 +131,13 @@ uint32 CLoadcore::QueryBootMode(uint32 param)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 CLoadcore::SetRebootTimeLibraryHandlingMode(uint32 libAddr, uint32 mode)
|
||||
{
|
||||
CLog::GetInstance().Print(LOG_NAME, FUNCTION_SETREBOOTTIMELIBHANDLINGMODE "(libAddr = 0x%0.8X, mode = 0x%0.8X);\r\n",
|
||||
libAddr, mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool CLoadcore::LoadModule(uint32* args, uint32 argsSize, uint32* ret, uint32 retSize)
|
||||
{
|
||||
char moduleName[PATH_MAX_SIZE];
|
||||
@ -184,8 +201,10 @@ void CLoadcore::LoadExecutable(uint32* args, uint32 argsSize, uint32* ret, uint3
|
||||
|
||||
void CLoadcore::LoadModuleFromMemory(uint32* args, uint32 argsSize, uint32* ret, uint32 retSize)
|
||||
{
|
||||
CLog::GetInstance().Print(LOG_NAME, "Request to load module at 0x%0.8X received with %d bytes arguments payload.\r\n", args[0], 0);
|
||||
m_bios.LoadAndStartModule(args[0], NULL, 0);
|
||||
const char* moduleArgs = reinterpret_cast<const char*>(args) + 8 + PATH_MAX_SIZE;
|
||||
uint32 moduleArgsSize = args[1];
|
||||
CLog::GetInstance().Print(LOG_NAME, "Request to load module at 0x%0.8X received with %d bytes arguments payload.\r\n", args[0], moduleArgsSize);
|
||||
m_bios.LoadAndStartModule(args[0], moduleArgs, moduleArgsSize);
|
||||
ret[0] = 0x00000000;
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ namespace Iop
|
||||
private:
|
||||
uint32 RegisterLibraryEntries(uint32);
|
||||
uint32 QueryBootMode(uint32);
|
||||
uint32 SetRebootTimeLibraryHandlingMode(uint32, uint32);
|
||||
|
||||
bool LoadModule(uint32*, uint32, uint32*, uint32);
|
||||
void LoadExecutable(uint32*, uint32, uint32*, uint32);
|
||||
|
@ -17,7 +17,10 @@ using namespace Iop;
|
||||
#define MODULE_NAME "sifcmd"
|
||||
#define MODULE_VERSION 0x101
|
||||
|
||||
#define FUNCTION_SIFSETCMDBUFFER "SifSetCmdBuffer"
|
||||
#define FUNCTION_SIFADDCMDHANDLER "SifAddCmdHandler"
|
||||
#define FUNCTION_SIFSENDCMD "SifSendCmd"
|
||||
#define FUNCTION_ISIFSENDCMD "iSifSendCmd"
|
||||
#define FUNCTION_SIFINITRPC "SifInitRpc"
|
||||
#define FUNCTION_SIFBINDRPC "SifBindRpc"
|
||||
#define FUNCTION_SIFCALLRPC "SifCallRpc"
|
||||
@ -40,7 +43,7 @@ CSifCmd::CSifCmd(CIopBios& bios, CSifMan& sifMan, CSysmem& sysMem, uint8* ram)
|
||||
m_memoryBufferAddr = m_sysMem.AllocateMemory(TRAMPOLINE_SIZE + SENDCMD_EXTRASTRUCT_SIZE, 0, 0);
|
||||
m_trampolineAddr = m_memoryBufferAddr;
|
||||
m_sendCmdExtraStructAddr = m_memoryBufferAddr + TRAMPOLINE_SIZE;
|
||||
sifMan.SetCustomCommandHandler([&] (const SIFCMDHEADER* commandHeader) { ProcessCustomCommand(commandHeader); });
|
||||
sifMan.SetCustomCommandHandler([&] (uint32 commandHeaderAddr) { ProcessCustomCommand(commandHeaderAddr); });
|
||||
BuildExportTable();
|
||||
}
|
||||
|
||||
@ -98,9 +101,18 @@ std::string CSifCmd::GetFunctionName(unsigned int functionId) const
|
||||
{
|
||||
switch(functionId)
|
||||
{
|
||||
case 8:
|
||||
return FUNCTION_SIFSETCMDBUFFER;
|
||||
break;
|
||||
case 10:
|
||||
return FUNCTION_SIFADDCMDHANDLER;
|
||||
break;
|
||||
case 12:
|
||||
return FUNCTION_SIFSENDCMD;
|
||||
break;
|
||||
case 13:
|
||||
return FUNCTION_ISIFSENDCMD;
|
||||
break;
|
||||
case 14:
|
||||
return FUNCTION_SIFINITRPC;
|
||||
break;
|
||||
@ -138,7 +150,19 @@ void CSifCmd::Invoke(CMIPS& context, unsigned int functionId)
|
||||
{
|
||||
switch(functionId)
|
||||
{
|
||||
case 8:
|
||||
context.m_State.nGPR[CMIPS::V0].nV0 = SifSetCmdBuffer(
|
||||
context.m_State.nGPR[CMIPS::A0].nV0,
|
||||
context.m_State.nGPR[CMIPS::A1].nV0);
|
||||
break;
|
||||
case 10:
|
||||
SifAddCmdHandler(
|
||||
context.m_State.nGPR[CMIPS::A0].nV0,
|
||||
context.m_State.nGPR[CMIPS::A1].nV0,
|
||||
context.m_State.nGPR[CMIPS::A2].nV0);
|
||||
break;
|
||||
case 12:
|
||||
case 13:
|
||||
context.m_State.nGPR[CMIPS::V0].nV0 = SifSendCmd(
|
||||
context.m_State.nGPR[CMIPS::A0].nV0,
|
||||
context.m_State.nGPR[CMIPS::A1].nV0,
|
||||
@ -147,6 +171,9 @@ void CSifCmd::Invoke(CMIPS& context, unsigned int functionId)
|
||||
context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x10),
|
||||
context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x14));
|
||||
break;
|
||||
case 14:
|
||||
CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFINITRPC "();\r\n");
|
||||
break;
|
||||
case 15:
|
||||
context.m_State.nGPR[CMIPS::V0].nV0 = SifBindRpc(
|
||||
context.m_State.nGPR[CMIPS::A0].nV0,
|
||||
@ -247,41 +274,82 @@ void CSifCmd::ReturnFromRpcInvoke(CMIPS& context)
|
||||
m_sifMan.SendCallReply(serverData->serverId, returnData);
|
||||
}
|
||||
|
||||
void CSifCmd::ProcessCustomCommand(const SIFCMDHEADER* commandHeader)
|
||||
void CSifCmd::ProcessCustomCommand(uint32 commandHeaderAddr)
|
||||
{
|
||||
switch(commandHeader->commandId)
|
||||
auto commandHeader = reinterpret_cast<const SIFCMDHEADER*>(m_ram + commandHeaderAddr);
|
||||
if(commandHeader->commandId == SIF_CMD_REND)
|
||||
{
|
||||
case SIF_CMD_REND:
|
||||
auto requestEnd = reinterpret_cast<const SIFRPCREQUESTEND*>(commandHeader);
|
||||
assert(requestEnd->clientDataAddr != 0);
|
||||
auto clientData = reinterpret_cast<SIFRPCCLIENTDATA*>(m_ram + requestEnd->clientDataAddr);
|
||||
if(requestEnd->commandId == SIF_CMD_BIND)
|
||||
{
|
||||
auto requestEnd = reinterpret_cast<const SIFRPCREQUESTEND*>(commandHeader);
|
||||
assert(requestEnd->clientDataAddr != 0);
|
||||
auto clientData = reinterpret_cast<SIFRPCCLIENTDATA*>(m_ram + requestEnd->clientDataAddr);
|
||||
if(requestEnd->commandId == SIF_CMD_BIND)
|
||||
{
|
||||
clientData->serverDataAddr = requestEnd->serverDataAddr;
|
||||
clientData->buffPtr = requestEnd->buffer;
|
||||
clientData->cbuffPtr = requestEnd->cbuffer;
|
||||
}
|
||||
else if(requestEnd->commandId == SIF_CMD_CALL)
|
||||
{
|
||||
assert(clientData->endFctPtr == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
assert(clientData->header.semaId != 0);
|
||||
m_bios.SignalSemaphore(clientData->header.semaId, true);
|
||||
m_bios.DeleteSemaphore(clientData->header.semaId);
|
||||
clientData->header.semaId = 0;
|
||||
clientData->serverDataAddr = requestEnd->serverDataAddr;
|
||||
clientData->buffPtr = requestEnd->buffer;
|
||||
clientData->cbuffPtr = requestEnd->cbuffer;
|
||||
}
|
||||
break;
|
||||
else if(requestEnd->commandId == SIF_CMD_CALL)
|
||||
{
|
||||
assert(clientData->endFctPtr == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
assert(clientData->header.semaId != 0);
|
||||
m_bios.SignalSemaphore(clientData->header.semaId, true);
|
||||
m_bios.DeleteSemaphore(clientData->header.semaId);
|
||||
clientData->header.semaId = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((m_cmdBuffer != 0) && (commandHeader->commandId < m_cmdBufferLen))
|
||||
{
|
||||
const auto& cmdDataEntry = (reinterpret_cast<SIFCMDDATA*>(m_ram + m_cmdBuffer))[commandHeader->commandId];
|
||||
|
||||
CLog::GetInstance().Print(LOG_NAME, "Calling SIF command handler for command 0x%0.8X at 0x%0.8X with data 0x%0.8X.\r\n",
|
||||
commandHeader->commandId, cmdDataEntry.sifCmdHandler, cmdDataEntry.data);
|
||||
|
||||
//This expects to be in an interrupt and the handler is called in the interrupt.
|
||||
//That's not the case here though, so we try for the same effect by calling the handler outside of an interrupt.
|
||||
//TODO: Set GP
|
||||
m_bios.TriggerCallback(cmdDataEntry.sifCmdHandler, commandHeaderAddr, cmdDataEntry.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 CSifCmd::SifSetCmdBuffer(uint32 data, uint32 length)
|
||||
{
|
||||
CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFSETCMDBUFFER "(data = 0x%0.8X, length = %d);\r\n",
|
||||
data, length);
|
||||
|
||||
uint32 originalBuffer = m_cmdBuffer;
|
||||
m_cmdBuffer = data;
|
||||
m_cmdBufferLen = length;
|
||||
|
||||
return originalBuffer;
|
||||
}
|
||||
|
||||
void CSifCmd::SifAddCmdHandler(uint32 pos, uint32 handler, uint32 data)
|
||||
{
|
||||
CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFADDCMDHANDLER "(pos = 0x%0.8X, handler = 0x%0.8X, data = 0x%0.8X);\r\n",
|
||||
pos, handler, data);
|
||||
if((m_cmdBuffer != 0) && (pos < m_cmdBufferLen))
|
||||
{
|
||||
auto& cmdDataEntry = (reinterpret_cast<SIFCMDDATA*>(m_ram + m_cmdBuffer))[pos];
|
||||
//TODO: Set GP
|
||||
cmdDataEntry.sifCmdHandler = handler;
|
||||
cmdDataEntry.data = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
CLog::GetInstance().Print(LOG_NAME, "SifAddCmdHandler - error command buffer too small or not set.\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
uint32 CSifCmd::SifSendCmd(uint32 commandId, uint32 packetPtr, uint32 packetSize, uint32 srcExtraPtr, uint32 dstExtraPtr, uint32 sizeExtra)
|
||||
{
|
||||
CLog::GetInstance().Print(LOG_NAME, "SifSendCmd(commandId = 0x%0.8X, packetPtr = 0x%0.8X, packetSize = 0x%0.8X, srcExtraPtr = 0x%0.8X, dstExtraPtr = 0x%0.8X, sizeExtra = 0x%0.8X);\r\n",
|
||||
CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFSENDCMD "(commandId = 0x%0.8X, packetPtr = 0x%0.8X, packetSize = 0x%0.8X, srcExtraPtr = 0x%0.8X, dstExtraPtr = 0x%0.8X, sizeExtra = 0x%0.8X);\r\n",
|
||||
commandId, packetPtr, packetSize, srcExtraPtr, dstExtraPtr, sizeExtra);
|
||||
|
||||
assert(packetSize >= 0x10);
|
||||
@ -293,11 +361,8 @@ uint32 CSifCmd::SifSendCmd(uint32 commandId, uint32 packetPtr, uint32 packetSize
|
||||
header->dest = 0;
|
||||
m_sifMan.SendPacket(packetData, packetSize);
|
||||
|
||||
if(sizeExtra != 0)
|
||||
if(sizeExtra != 0 && srcExtraPtr != 0 && dstExtraPtr != 0)
|
||||
{
|
||||
assert(srcExtraPtr != 0);
|
||||
assert(dstExtraPtr != 0);
|
||||
|
||||
auto dmaReg = reinterpret_cast<SIFDMAREG*>(m_ram + m_sendCmdExtraStructAddr);
|
||||
dmaReg->srcAddr = srcExtraPtr;
|
||||
dmaReg->dstAddr = dstExtraPtr;
|
||||
@ -396,7 +461,7 @@ void CSifCmd::SifRegisterRpc(CMIPS& context)
|
||||
uint32 cbuffer = context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x14);
|
||||
uint32 queueAddr = context.m_pMemoryMap->GetWord(context.m_State.nGPR[CMIPS::SP].nV0 + 0x18);
|
||||
|
||||
CLog::GetInstance().Print(LOG_NAME, "SifRegisterRpc(serverData = 0x%0.8X, serverId = 0x%0.8X, function = 0x%0.8X, buffer = 0x%0.8X, cfunction = 0x%0.8X, cbuffer = 0x%0.8X, queue = 0x%0.8X);\r\n",
|
||||
CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFREGISTERRPC "(serverData = 0x%0.8X, serverId = 0x%0.8X, function = 0x%0.8X, buffer = 0x%0.8X, cfunction = 0x%0.8X, cbuffer = 0x%0.8X, queue = 0x%0.8X);\r\n",
|
||||
serverDataAddr, serverId, function, buffer, cfunction, cbuffer, queueAddr);
|
||||
|
||||
bool moduleRegistered = m_sifMan.IsModuleRegistered(serverId);
|
||||
|
@ -54,10 +54,18 @@ namespace Iop
|
||||
uint32 queueAddr;
|
||||
};
|
||||
|
||||
// m_cmdBuffer is an array of these structures.
|
||||
struct SIFCMDDATA
|
||||
{
|
||||
uint32 sifCmdHandler;
|
||||
uint32 data;
|
||||
uint32 gp;
|
||||
};
|
||||
|
||||
void ClearServers();
|
||||
void BuildExportTable();
|
||||
|
||||
void ProcessCustomCommand(const SIFCMDHEADER*);
|
||||
void ProcessCustomCommand(uint32);
|
||||
|
||||
uint32 SifSendCmd(uint32, uint32, uint32, uint32, uint32, uint32);
|
||||
uint32 SifBindRpc(uint32, uint32, uint32);
|
||||
@ -68,6 +76,11 @@ namespace Iop
|
||||
void SifRpcLoop(uint32);
|
||||
uint32 SifGetOtherData(uint32, uint32, uint32, uint32, uint32);
|
||||
void ReturnFromRpcInvoke(CMIPS&);
|
||||
uint32 SifSetCmdBuffer(uint32 pData, uint32 len);
|
||||
void SifAddCmdHandler(uint32 pos, uint32 handler, uint32 data);
|
||||
|
||||
uint32 m_cmdBuffer = 0;
|
||||
uint32 m_cmdBufferLen = 0;
|
||||
|
||||
CIopBios& m_bios;
|
||||
CSifMan& m_sifMan;
|
||||
|
@ -11,7 +11,7 @@ namespace Iop
|
||||
class CSifMan : public CModule
|
||||
{
|
||||
public:
|
||||
typedef std::function<void (const SIFCMDHEADER*)> CustomCommandHandler;
|
||||
typedef std::function<void (uint32)> CustomCommandHandler;
|
||||
|
||||
CSifMan();
|
||||
virtual ~CSifMan();
|
||||
@ -27,6 +27,7 @@ namespace Iop
|
||||
virtual void UnregisterModule(uint32) = 0;
|
||||
virtual void SendPacket(void*, uint32) = 0;
|
||||
virtual void SetDmaBuffer(uint32, uint32) = 0;
|
||||
virtual void SetCmdBuffer(uint32, uint32) = 0;
|
||||
virtual void SendCallReply(uint32, const void*) = 0;
|
||||
virtual void GetOtherData(uint32, uint32, uint32) = 0;
|
||||
virtual void SetCustomCommandHandler(const CustomCommandHandler&) = 0;
|
||||
|
@ -27,6 +27,11 @@ void CSifManNull::SetDmaBuffer(uint32, uint32)
|
||||
|
||||
}
|
||||
|
||||
void CSifManNull::SetCmdBuffer(uint32, uint32)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CSifManNull::SendCallReply(uint32, const void*)
|
||||
{
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
#ifndef _IOP_SIFMANNULL_H_
|
||||
#define _IOP_SIFMANNULL_H_
|
||||
#pragma once
|
||||
|
||||
#include "Iop_SifMan.h"
|
||||
|
||||
@ -13,10 +12,9 @@ namespace Iop
|
||||
void UnregisterModule(uint32) override;
|
||||
void SendPacket(void*, uint32) override;
|
||||
void SetDmaBuffer(uint32, uint32) override;
|
||||
void SetCmdBuffer(uint32, uint32) override;
|
||||
void SendCallReply(uint32, const void*) override;
|
||||
void GetOtherData(uint32, uint32, uint32) override;
|
||||
void SetCustomCommandHandler(const CustomCommandHandler&) override;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -40,6 +40,11 @@ void CSifManPs2::SetDmaBuffer(uint32 bufferAddress, uint32 size)
|
||||
m_sif.SetDmaBuffer(bufferAddress, size);
|
||||
}
|
||||
|
||||
void CSifManPs2::SetCmdBuffer(uint32 bufferAddress, uint32 size)
|
||||
{
|
||||
m_sif.SetCmdBuffer(bufferAddress, size);
|
||||
}
|
||||
|
||||
void CSifManPs2::SendCallReply(uint32 serverId, const void* returnData)
|
||||
{
|
||||
m_sif.SendCallReply(serverId, returnData);
|
||||
|
@ -16,6 +16,7 @@ namespace Iop
|
||||
void UnregisterModule(uint32) override;
|
||||
void SendPacket(void*, uint32) override;
|
||||
void SetDmaBuffer(uint32, uint32) override;
|
||||
void SetCmdBuffer(uint32, uint32) override;
|
||||
void SendCallReply(uint32, const void*) override;
|
||||
void GetOtherData(uint32, uint32, uint32) override;
|
||||
void SetCustomCommandHandler(const CustomCommandHandler&) override;
|
||||
|
@ -68,6 +68,9 @@ std::string CSysclib::GetFunctionName(unsigned int functionId) const
|
||||
case 36:
|
||||
return "strtol";
|
||||
break;
|
||||
case 41:
|
||||
return "wmemset";
|
||||
break;
|
||||
default:
|
||||
return "unknown";
|
||||
break;
|
||||
@ -179,6 +182,20 @@ void CSysclib::Invoke(CMIPS& context, unsigned int functionId)
|
||||
context.m_State.nGPR[CMIPS::A2].nV0
|
||||
));
|
||||
break;
|
||||
case 41:
|
||||
//wmemset
|
||||
{
|
||||
uint32* dest = reinterpret_cast<uint32*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]);
|
||||
uint32 value = context.m_State.nGPR[CMIPS::A1].nV0;
|
||||
uint32 numChars = context.m_State.nGPR[CMIPS::A2].nV0;
|
||||
uint32* end = dest + numChars;
|
||||
while(dest < end)
|
||||
{
|
||||
*dest++ = value;
|
||||
}
|
||||
context.m_State.nGPR[CMIPS::V0].nD0 = context.m_State.nGPR[CMIPS::A0].nV0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("%s(%0.8X): Unknown function (%d) called.\r\n", __FUNCTION__, context.m_State.nPC, functionId);
|
||||
assert(0);
|
||||
|
@ -505,7 +505,18 @@ void CGSH_Direct3D9::Prim_Triangle()
|
||||
//Textured triangle
|
||||
if(m_primitiveMode.nUseUV)
|
||||
{
|
||||
//TODO
|
||||
UV uv[3];
|
||||
uv[0] <<= m_vtxBuffer[2].nUV;
|
||||
uv[1] <<= m_vtxBuffer[1].nUV;
|
||||
uv[2] <<= m_vtxBuffer[0].nUV;
|
||||
|
||||
nU1 = uv[0].GetU() / static_cast<float>(m_currentTextureWidth);
|
||||
nU2 = uv[1].GetU() / static_cast<float>(m_currentTextureWidth);
|
||||
nU3 = uv[2].GetU() / static_cast<float>(m_currentTextureWidth);
|
||||
|
||||
nV1 = uv[0].GetV() / static_cast<float>(m_currentTextureHeight);
|
||||
nV2 = uv[1].GetV() / static_cast<float>(m_currentTextureHeight);
|
||||
nV3 = uv[2].GetV() / static_cast<float>(m_currentTextureHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -68,7 +68,7 @@ private:
|
||||
|
||||
enum CVTBUFFERSIZE
|
||||
{
|
||||
CVTBUFFERSIZE = 0x400000,
|
||||
CVTBUFFERSIZE = 2048 * 2048 * 4,
|
||||
};
|
||||
|
||||
struct RENDERSTATE
|
||||
@ -94,7 +94,6 @@ private:
|
||||
|
||||
uint32 m_nStart;
|
||||
uint32 m_nSize;
|
||||
unsigned int m_nPSM;
|
||||
uint32 m_nCLUTAddress;
|
||||
uint64 m_nTex0;
|
||||
uint64 m_nTexClut;
|
||||
|
@ -227,14 +227,23 @@ uint32 CGSH_Direct3D9::ConvertTexturePsm8(const TEX0& tex0, const TEXA& texA)
|
||||
uint32 clut[256];
|
||||
FlattenClut(tex0, clut);
|
||||
|
||||
CGsPixelFormats::CPixelIndexorPSMT8 Indexor(m_pRAM, tex0.GetBufPtr(), tex0.nBufWidth);
|
||||
CGsPixelFormats::CPixelIndexorPSMT8 indexor(m_pRAM, tex0.GetBufPtr(), tex0.nBufWidth);
|
||||
|
||||
uint32 bufWidthBytes = tex0.nBufWidth * 64;
|
||||
|
||||
for(unsigned int j = 0; j < height; j++)
|
||||
{
|
||||
for(unsigned int i = 0; i < width; i++)
|
||||
{
|
||||
uint8 pixel = Indexor.GetPixel(i, j);
|
||||
dst[i] = clut[pixel];
|
||||
if(i <= bufWidthBytes)
|
||||
{
|
||||
uint32 pixel = indexor.GetPixel(i, j);
|
||||
dst[i] = clut[pixel];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
checksum = crc32(checksum, reinterpret_cast<Bytef*>(dst), sizeof(uint32) * width);
|
||||
@ -257,13 +266,22 @@ uint32 CGSH_Direct3D9::ConvertTexturePsm8H(const TEX0& tex0, const TEXA& texA)
|
||||
|
||||
CGsPixelFormats::CPixelIndexorPSMCT32 indexor(m_pRAM, tex0.GetBufPtr(), tex0.nBufWidth);
|
||||
|
||||
uint32 bufWidthBytes = tex0.nBufWidth * 64;
|
||||
|
||||
for(unsigned int j = 0; j < height; j++)
|
||||
{
|
||||
for(unsigned int i = 0; i < width; i++)
|
||||
{
|
||||
uint32 pixel = indexor.GetPixel(i, j);
|
||||
pixel >>= 24;
|
||||
dst[i] = clut[pixel];
|
||||
if(i <= bufWidthBytes)
|
||||
{
|
||||
uint32 pixel = indexor.GetPixel(i, j);
|
||||
pixel >>= 24;
|
||||
dst[i] = clut[pixel];
|
||||
}
|
||||
else
|
||||
{
|
||||
dst[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
checksum = crc32(checksum, reinterpret_cast<Bytef*>(dst), sizeof(uint32) * width);
|
||||
@ -412,7 +430,6 @@ void CGSH_Direct3D9::UploadConversionBuffer(const TEX0& tex0, const TEXA& texA,
|
||||
CGSH_Direct3D9::CCachedTexture::CCachedTexture()
|
||||
: m_nStart(0)
|
||||
, m_nSize(0)
|
||||
, m_nPSM(0)
|
||||
, m_nCLUTAddress(0)
|
||||
, m_nTex0(0)
|
||||
, m_nTexClut(0)
|
||||
@ -472,7 +489,6 @@ CGSH_Direct3D9::TexturePtr CGSH_Direct3D9::TexCache_SearchLive(const TEX0& tex0)
|
||||
if(!texture->m_live) continue;
|
||||
//if(!texture.IsValid()) continue;
|
||||
//if(m_TexCache[i].m_nStart != pTex0->GetBufPtr()) continue;
|
||||
//if(m_TexCache[i].m_nPSM != pTex0->nPsm) continue;
|
||||
//if(m_TexCache[i].m_nCLUTAddress != pTex0->GetCLUTPtr()) continue;
|
||||
if(static_cast<uint64>(tex0) != texture->m_nTex0) continue;
|
||||
// if(texture->m_nIsCSM2)
|
||||
@ -512,9 +528,8 @@ void CGSH_Direct3D9::TexCache_Insert(const TEX0& tex0, const TexturePtr& texture
|
||||
|
||||
cachedTexture->m_nStart = tex0.GetBufPtr();
|
||||
cachedTexture->m_nSize = tex0.GetBufWidth() * tex0.GetHeight() * CGsPixelFormats::GetPsmPixelSize(tex0.nPsm) / 8;
|
||||
// cachedTexture->m_nPSM = pTex0->nPsm;
|
||||
// cachedTexture->m_nCLUTAddress = pTex0->GetCLUTPtr();
|
||||
cachedTexture->m_nTex0 = *reinterpret_cast<const uint64*>(&tex0);
|
||||
cachedTexture->m_nTex0 = static_cast<const uint64>(tex0);
|
||||
// cachedTexture->m_nTexClut = (*(uint64*)GetTexClut()) & 0x3FFFFF;
|
||||
cachedTexture->m_nTexClut = 0;
|
||||
cachedTexture->m_nIsCSM2 = tex0.nCSM == 1;
|
||||
|
@ -168,7 +168,9 @@
|
||||
<ClCompile Include="..\Source\MIPSTags.cpp" />
|
||||
<ClCompile Include="..\tools\MipsTest\Add64Test.cpp" />
|
||||
<ClCompile Include="..\tools\MipsTest\ExchangeTest.cpp" />
|
||||
<ClCompile Include="..\tools\MipsTest\ExtendTest.cpp" />
|
||||
<ClCompile Include="..\tools\MipsTest\Main.cpp" />
|
||||
<ClCompile Include="..\tools\MipsTest\PackedMultiplyTest.cpp" />
|
||||
<ClCompile Include="..\tools\MipsTest\PackTest.cpp" />
|
||||
<ClCompile Include="..\tools\MipsTest\SetLessThanTest.cpp" />
|
||||
<ClCompile Include="..\tools\MipsTest\Shift32Test.cpp" />
|
||||
@ -202,6 +204,8 @@
|
||||
<ClInclude Include="..\Source\MIPSTags.h" />
|
||||
<ClInclude Include="..\tools\MipsTest\Add64Test.h" />
|
||||
<ClInclude Include="..\tools\MipsTest\ExchangeTest.h" />
|
||||
<ClInclude Include="..\tools\MipsTest\ExtendTest.h" />
|
||||
<ClInclude Include="..\tools\MipsTest\PackedMultiplyTest.h" />
|
||||
<ClInclude Include="..\tools\MipsTest\PackTest.h" />
|
||||
<ClInclude Include="..\tools\MipsTest\SetLessThanTest.h" />
|
||||
<ClInclude Include="..\tools\MipsTest\Shift32Test.h" />
|
||||
|
@ -103,6 +103,12 @@
|
||||
<ClCompile Include="..\tools\MipsTest\PackTest.cpp">
|
||||
<Filter>Source Files\Tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tools\MipsTest\ExtendTest.cpp">
|
||||
<Filter>Source Files\Tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tools\MipsTest\PackedMultiplyTest.cpp">
|
||||
<Filter>Source Files\Tests</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\tools\MipsTest\TestVm.h">
|
||||
@ -186,6 +192,12 @@
|
||||
<ClInclude Include="..\tools\MipsTest\PackTest.h">
|
||||
<Filter>Source Files\Tests</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\tools\MipsTest\ExtendTest.h">
|
||||
<Filter>Source Files\Tests</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\tools\MipsTest\PackedMultiplyTest.h">
|
||||
<Filter>Source Files\Tests</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
85
tools/MipsTest/ExtendTest.cpp
Normal file
85
tools/MipsTest/ExtendTest.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
#include "ExtendTest.h"
|
||||
#include "EEAssembler.h"
|
||||
|
||||
void CExtendTest::Execute(CTestVm& virtualMachine)
|
||||
{
|
||||
auto& cpu = virtualMachine.m_cpu;
|
||||
|
||||
const uint32 baseAddress = 0x100;
|
||||
const uint32 constantValue0 = 0x11110000;
|
||||
const uint32 constantValue1 = 0x33332222;
|
||||
const uint32 constantValue2 = 0x55554444;
|
||||
const uint32 constantValue3 = 0x77776666;
|
||||
const uint32 constantValue4 = 0x99998888;
|
||||
const uint32 constantValue5 = 0xBBBBAAAA;
|
||||
const uint32 constantValue6 = 0xDDDDCCCC;
|
||||
const uint32 constantValue7 = 0xFFFFEEEE;
|
||||
const uint64 extlbResultLow = 0x1199119900880088ULL;
|
||||
const uint64 extlbResultHigh = 0x33BB33BB22AA22AAULL;
|
||||
const uint64 extubResultLow = 0x55DD55DD44CC44CCULL;
|
||||
const uint64 extubResultHigh = 0x77FF77FF66EE66EEULL;
|
||||
const uint64 extuhResultLow = 0x5555DDDD4444CCCCULL;
|
||||
const uint64 extuhResultHigh = 0x7777FFFF6666EEEEULL;
|
||||
const uint64 extlhResultLow = 0x1111999900008888ULL;
|
||||
const uint64 extlhResultHigh = 0x3333BBBB2222AAAAULL;
|
||||
|
||||
auto valueRegister0 = CMIPS::A0;
|
||||
auto valueRegister1 = CMIPS::A1;
|
||||
auto extlbResult = CMIPS::T0;
|
||||
auto extubResult = CMIPS::T1;
|
||||
auto extlhResult = CMIPS::T2;
|
||||
auto extuhResult = CMIPS::T3;
|
||||
|
||||
virtualMachine.Reset();
|
||||
|
||||
{
|
||||
CEEAssembler assembler(reinterpret_cast<uint32*>(virtualMachine.m_ram + baseAddress));
|
||||
|
||||
//PEXTLB
|
||||
assembler.PEXTLB(extlbResult, valueRegister0, valueRegister1);
|
||||
|
||||
//PEXTUB
|
||||
assembler.PEXTUB(extubResult, valueRegister0, valueRegister1);
|
||||
|
||||
//PEXTLH
|
||||
assembler.PEXTLH(extlhResult, valueRegister0, valueRegister1);
|
||||
|
||||
//PEXTUH
|
||||
assembler.PEXTUH(extuhResult, valueRegister0, valueRegister1);
|
||||
|
||||
assembler.SYSCALL();
|
||||
}
|
||||
|
||||
//Setup initial state
|
||||
cpu.m_State.nGPR[valueRegister0].nV[0] = constantValue0;
|
||||
cpu.m_State.nGPR[valueRegister0].nV[1] = constantValue1;
|
||||
cpu.m_State.nGPR[valueRegister0].nV[2] = constantValue2;
|
||||
cpu.m_State.nGPR[valueRegister0].nV[3] = constantValue3;
|
||||
cpu.m_State.nGPR[valueRegister1].nV[0] = constantValue4;
|
||||
cpu.m_State.nGPR[valueRegister1].nV[1] = constantValue5;
|
||||
cpu.m_State.nGPR[valueRegister1].nV[2] = constantValue6;
|
||||
cpu.m_State.nGPR[valueRegister1].nV[3] = constantValue7;
|
||||
|
||||
//Execute
|
||||
virtualMachine.ExecuteTest(baseAddress);
|
||||
|
||||
//Check final state
|
||||
TEST_VERIFY(cpu.m_State.nGPR[valueRegister0].nV[0] == constantValue0);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[valueRegister0].nV[1] == constantValue1);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[valueRegister0].nV[2] == constantValue2);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[valueRegister0].nV[3] == constantValue3);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[valueRegister1].nV[0] == constantValue4);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[valueRegister1].nV[1] == constantValue5);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[valueRegister1].nV[2] == constantValue6);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[valueRegister1].nV[3] == constantValue7);
|
||||
|
||||
TEST_VERIFY(cpu.m_State.nGPR[extlbResult].nD0 == extlbResultLow);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[extlbResult].nD1 == extlbResultHigh);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[extubResult].nD0 == extubResultLow);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[extubResult].nD1 == extubResultHigh);
|
||||
|
||||
TEST_VERIFY(cpu.m_State.nGPR[extlhResult].nD0 == extlhResultLow);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[extlhResult].nD1 == extlhResultHigh);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[extuhResult].nD0 == extuhResultLow);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[extuhResult].nD1 == extuhResultHigh);
|
||||
}
|
9
tools/MipsTest/ExtendTest.h
Normal file
9
tools/MipsTest/ExtendTest.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "Test.h"
|
||||
|
||||
class CExtendTest : public CTest
|
||||
{
|
||||
public:
|
||||
void Execute(CTestVm&);
|
||||
};
|
@ -7,7 +7,9 @@
|
||||
#include "Shift32Test.h"
|
||||
#include "Shift64Test.h"
|
||||
#include "ExchangeTest.h"
|
||||
#include "ExtendTest.h"
|
||||
#include "PackTest.h"
|
||||
#include "PackedMultiplyTest.h"
|
||||
|
||||
typedef std::function<CTest* ()> TestFactoryFunction;
|
||||
|
||||
@ -19,7 +21,9 @@ static const TestFactoryFunction s_factories[] =
|
||||
[] () -> CTest* { return new CShift32Test(); },
|
||||
[] () -> CTest* { return new CShift64Test(); },
|
||||
[] () -> CTest* { return new CExchangeTest(); },
|
||||
[] () -> CTest* { return new CPackTest(); }
|
||||
[] () -> CTest* { return new CExtendTest(); },
|
||||
[] () -> CTest* { return new CPackTest(); },
|
||||
[] () -> CTest* { return new CPackedMultiplyTest(); }
|
||||
};
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
|
@ -14,19 +14,30 @@ void CPackTest::Execute(CTestVm& virtualMachine)
|
||||
const uint32 constantValue5 = 0x55555555;
|
||||
const uint32 constantValue6 = 0x66666666;
|
||||
const uint32 constantValue7 = 0x77777777;
|
||||
const uint64 pachResultLow = 0x7777666655554444ULL;
|
||||
const uint64 pachResultHigh = 0x3333222211110000ULL;
|
||||
const uint64 pacwResultLow = 0x6666666644444444ULL;
|
||||
const uint64 pacwResultHigh = 0x2222222200000000ULL;
|
||||
|
||||
auto valueRegister0 = CMIPS::A0;
|
||||
auto valueRegister1 = CMIPS::A1;
|
||||
auto pacwResult = CMIPS::T0;
|
||||
auto pacwSelfResult = CMIPS::T1;
|
||||
auto pachResult = CMIPS::T0;
|
||||
auto pachSelfResult = CMIPS::T1;
|
||||
auto pacwResult = CMIPS::T2;
|
||||
auto pacwSelfResult = CMIPS::T3;
|
||||
|
||||
virtualMachine.Reset();
|
||||
|
||||
{
|
||||
CEEAssembler assembler(reinterpret_cast<uint32*>(virtualMachine.m_ram + baseAddress));
|
||||
|
||||
//PPACH
|
||||
assembler.PPACH(pachResult, valueRegister0, valueRegister1);
|
||||
|
||||
//PPACH (self)
|
||||
assembler.PADDW(pachSelfResult, valueRegister0, CMIPS::R0);
|
||||
assembler.PPACH(pachSelfResult, pachSelfResult, valueRegister1);
|
||||
|
||||
//PPACW
|
||||
assembler.PPACW(pacwResult, valueRegister0, valueRegister1);
|
||||
|
||||
@ -62,6 +73,12 @@ void CPackTest::Execute(CTestVm& virtualMachine)
|
||||
TEST_VERIFY(cpu.m_State.nGPR[valueRegister1].nV[2] == constantValue6);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[valueRegister1].nV[3] == constantValue7);
|
||||
|
||||
TEST_VERIFY(cpu.m_State.nGPR[pachResult].nD0 == pachResultLow);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[pachResult].nD1 == pachResultHigh);
|
||||
|
||||
TEST_VERIFY(cpu.m_State.nGPR[pachSelfResult].nD0 == pachResultLow);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[pachSelfResult].nD1 == pachResultHigh);
|
||||
|
||||
TEST_VERIFY(cpu.m_State.nGPR[pacwResult].nD0 == pacwResultLow);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[pacwResult].nD1 == pacwResultHigh);
|
||||
|
||||
|
103
tools/MipsTest/PackedMultiplyTest.cpp
Normal file
103
tools/MipsTest/PackedMultiplyTest.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
#include "PackedMultiplyTest.h"
|
||||
#include "EEAssembler.h"
|
||||
|
||||
void CPackedMultiplyTest::Execute(CTestVm& virtualMachine)
|
||||
{
|
||||
auto& cpu = virtualMachine.m_cpu;
|
||||
|
||||
const uint32 baseAddress = 0x100;
|
||||
const uint32 constantValue0 = 0x11110000;
|
||||
const uint32 constantValue1 = 0x33332222;
|
||||
const uint32 constantValue2 = 0x55554444;
|
||||
const uint32 constantValue3 = 0x77776666;
|
||||
const uint32 constantValue4 = 0x99998888;
|
||||
const uint32 constantValue5 = 0xBBBBAAAA;
|
||||
const uint32 constantValue6 = 0xDDDDCCCC;
|
||||
const uint32 constantValue7 = 0xFFFFEEEE;
|
||||
const uint64 multhResultLow = 0xF49F3E9400000000ULL;
|
||||
const uint64 multhResultHigh = 0xF92C06D4F2589630ULL;
|
||||
const uint64 multhLoLow = 0xF92C5C2900000000ULL;
|
||||
const uint64 multhLoHigh = 0xF49F0B61F2589630ULL;
|
||||
const uint64 multhHiLow = 0xF258A741F49F3E94ULL;
|
||||
const uint64 multhHiHigh = 0xFFFF8889F92C06D4ULL;
|
||||
const uint64 mfhlUwResultLow = 0xF258A741F92C5C29ULL;
|
||||
const uint64 mfhlUwResultHigh = 0xFFFF8889F49F0B61ULL;
|
||||
|
||||
auto valueRegister0 = CMIPS::A0;
|
||||
auto valueRegister1 = CMIPS::A1;
|
||||
auto multhResult = CMIPS::T0;
|
||||
auto multhLo = CMIPS::T1;
|
||||
auto multhHi = CMIPS::T2;
|
||||
auto multhSelfResult = CMIPS::T3;
|
||||
auto multhSelfLo = CMIPS::T4;
|
||||
auto multhSelfHi = CMIPS::T5;
|
||||
auto mfhlUwResult = CMIPS::T6;
|
||||
|
||||
virtualMachine.Reset();
|
||||
|
||||
{
|
||||
CEEAssembler assembler(reinterpret_cast<uint32*>(virtualMachine.m_ram + baseAddress));
|
||||
|
||||
//PMULTH
|
||||
assembler.PMULTH(multhResult, valueRegister0, valueRegister1);
|
||||
assembler.PMFLO(multhLo);
|
||||
assembler.PMFHI(multhHi);
|
||||
|
||||
//PMULTH (self)
|
||||
assembler.PADDW(multhSelfResult, valueRegister0, CMIPS::R0);
|
||||
assembler.PMULTH(multhSelfResult, multhSelfResult, valueRegister1);
|
||||
assembler.PMFLO(multhSelfLo);
|
||||
assembler.PMFHI(multhSelfHi);
|
||||
|
||||
//PMFHL.UW
|
||||
assembler.PMFHL_UW(mfhlUwResult);
|
||||
|
||||
assembler.SYSCALL();
|
||||
}
|
||||
|
||||
//Setup initial state
|
||||
cpu.m_State.nGPR[valueRegister0].nV[0] = constantValue0;
|
||||
cpu.m_State.nGPR[valueRegister0].nV[1] = constantValue1;
|
||||
cpu.m_State.nGPR[valueRegister0].nV[2] = constantValue2;
|
||||
cpu.m_State.nGPR[valueRegister0].nV[3] = constantValue3;
|
||||
|
||||
cpu.m_State.nGPR[valueRegister1].nV[0] = constantValue4;
|
||||
cpu.m_State.nGPR[valueRegister1].nV[1] = constantValue5;
|
||||
cpu.m_State.nGPR[valueRegister1].nV[2] = constantValue6;
|
||||
cpu.m_State.nGPR[valueRegister1].nV[3] = constantValue7;
|
||||
|
||||
//Execute
|
||||
virtualMachine.ExecuteTest(baseAddress);
|
||||
|
||||
//Check final state
|
||||
TEST_VERIFY(cpu.m_State.nGPR[valueRegister0].nV[0] == constantValue0);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[valueRegister0].nV[1] == constantValue1);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[valueRegister0].nV[2] == constantValue2);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[valueRegister0].nV[3] == constantValue3);
|
||||
|
||||
TEST_VERIFY(cpu.m_State.nGPR[valueRegister1].nV[0] == constantValue4);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[valueRegister1].nV[1] == constantValue5);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[valueRegister1].nV[2] == constantValue6);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[valueRegister1].nV[3] == constantValue7);
|
||||
|
||||
TEST_VERIFY(cpu.m_State.nGPR[multhResult].nD0 == multhResultLow);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[multhResult].nD1 == multhResultHigh);
|
||||
|
||||
TEST_VERIFY(cpu.m_State.nGPR[multhLo].nD0 == multhLoLow);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[multhLo].nD1 == multhLoHigh);
|
||||
|
||||
TEST_VERIFY(cpu.m_State.nGPR[multhHi].nD0 == multhHiLow);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[multhHi].nD1 == multhHiHigh);
|
||||
|
||||
TEST_VERIFY(cpu.m_State.nGPR[multhSelfResult].nD0 == multhResultLow);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[multhSelfResult].nD1 == multhResultHigh);
|
||||
|
||||
TEST_VERIFY(cpu.m_State.nGPR[multhSelfLo].nD0 == multhLoLow);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[multhSelfLo].nD1 == multhLoHigh);
|
||||
|
||||
TEST_VERIFY(cpu.m_State.nGPR[multhSelfHi].nD0 == multhHiLow);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[multhSelfHi].nD1 == multhHiHigh);
|
||||
|
||||
TEST_VERIFY(cpu.m_State.nGPR[mfhlUwResult].nD0 == mfhlUwResultLow);
|
||||
TEST_VERIFY(cpu.m_State.nGPR[mfhlUwResult].nD1 == mfhlUwResultHigh);
|
||||
}
|
9
tools/MipsTest/PackedMultiplyTest.h
Normal file
9
tools/MipsTest/PackedMultiplyTest.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "Test.h"
|
||||
|
||||
class CPackedMultiplyTest : public CTest
|
||||
{
|
||||
public:
|
||||
void Execute(CTestVm&);
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user