Merge branch 'justice_league_heroes'

This commit is contained in:
Jean-Philip Desjardins 2015-01-01 15:37:44 -05:00
commit d3bf023d28
30 changed files with 680 additions and 103 deletions

View File

@ -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);

View File

@ -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);
};

View File

@ -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

View File

@ -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);

View File

@ -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 },

View File

@ -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);

View File

@ -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];

View File

@ -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

View File

@ -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*);

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -27,6 +27,11 @@ void CSifManNull::SetDmaBuffer(uint32, uint32)
}
void CSifManNull::SetCmdBuffer(uint32, uint32)
{
}
void CSifManNull::SendCallReply(uint32, const void*)
{

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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
{

View File

@ -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;

View File

@ -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;

View File

@ -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" />

View File

@ -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" />

View 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);
}

View File

@ -0,0 +1,9 @@
#pragma once
#include "Test.h"
class CExtendTest : public CTest
{
public:
void Execute(CTestVm&);
};

View File

@ -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)

View File

@ -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);

View 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);
}

View File

@ -0,0 +1,9 @@
#pragma once
#include "Test.h"
class CPackedMultiplyTest : public CTest
{
public:
void Execute(CTestVm&);
};