Some work done to make Half-Life work.

git-svn-id: http://svn.purei.org/purei/trunk@509 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
jpd002 2009-04-28 01:20:03 +00:00
parent 4e64a4c612
commit bced4b20e2
16 changed files with 381 additions and 26 deletions

View File

@ -607,6 +607,14 @@
RelativePath=".\Source\iop\Iop_Cdvdfsv.h"
>
</File>
<File
RelativePath=".\Source\iop\Iop_Cdvdman.cpp"
>
</File>
<File
RelativePath=".\Source\iop\Iop_Cdvdman.h"
>
</File>
<File
RelativePath=".\Source\iop\Iop_DbcMan.cpp"
>

View File

@ -80,10 +80,32 @@ void CCOP_SCU::MTC0()
m_codeGen->PullRel(offsetof(CMIPS, m_State.nCOP0[m_nRD]));
}
//10
void CCOP_SCU::CO()
//08
void CCOP_SCU::BC0()
{
((this)->*(m_pOpCO[(m_nOpcode & 0x3F)]))();
((this)->*(m_pOpBC0[m_nRT]))();
}
//10
void CCOP_SCU::C0()
{
((this)->*(m_pOpC0[(m_nOpcode & 0x3F)]))();
}
//////////////////////////////////////////////////
//Branches
//////////////////////////////////////////////////
//00
void CCOP_SCU::BC0F()
{
}
//01
void CCOP_SCU::BC0T()
{
}
//////////////////////////////////////////////////
@ -157,14 +179,26 @@ CCOP_SCU::InstructionFuncConstant CCOP_SCU::m_pOpGeneral[0x20] =
//0x00
&MFC0, &Illegal, &Illegal, &Illegal, &MTC0, &Illegal, &Illegal, &Illegal,
//0x08
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
&BC0, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x10
&CO, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
&C0, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
};
CCOP_SCU::InstructionFuncConstant CCOP_SCU::m_pOpCO[0x40] =
CCOP_SCU::InstructionFuncConstant CCOP_SCU::m_pOpBC0[0x20] =
{
//0x00
&BC0F, &BC0T, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x08
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x10
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
//0x18
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
};
CCOP_SCU::InstructionFuncConstant CCOP_SCU::m_pOpC0[0x40] =
{
//0x00
&Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal, &Illegal,
@ -194,6 +228,20 @@ void CCOP_SCU::GetInstruction(uint32 nOpcode, char* sText)
case 0x04:
strcpy(sText, "MTC0");
break;
case 0x08:
switch((nOpcode >> 16) & 0x1F)
{
case 0x00:
strcpy(sText, "BC0F");
break;
case 0x01:
strcpy(sText, "BC0T");
break;
default:
strcpy(sText, "???");
break;
}
break;
case 0x10:
switch(nOpcode & 0x3F)
{
@ -222,27 +270,65 @@ void CCOP_SCU::GetInstruction(uint32 nOpcode, char* sText)
void CCOP_SCU::GetArguments(uint32 nAddress, uint32 nOpcode, char* sText)
{
unsigned char nRD, nRT;
nRT = (unsigned char)((nOpcode >> 16) & 0x1F);
nRD = (unsigned char)((nOpcode >> 11) & 0x1F);
uint8 nRT = static_cast<uint8>((nOpcode >> 16) & 0x1F);
uint8 nRD = static_cast<uint8>((nOpcode >> 11) & 0x1F);
uint16 nImm = static_cast<uint16>(nOpcode);
switch((nOpcode >> 21) & 0x1F)
{
case 0x00:
case 0x04:
sprintf(sText, "%s, %s", CMIPS::m_sGPRName[nRT], m_sRegName[nRD]);
break;
case 0x08:
switch((nOpcode >> 16) & 0x1F)
{
case 0x00:
case 0x01:
sprintf(sText, "0x%0.8X", nAddress + CMIPS::GetBranch(nImm) + 4);
break;
default:
strcpy(sText, "");
break;
}
break;
default:
strcpy(sText, "");
break;
}
}
uint32 CCOP_SCU::GetEffectiveAddress(uint32 nAddress, uint32 nData)
uint32 CCOP_SCU::GetEffectiveAddress(uint32 nAddress, uint32 nOpcode)
{
return false;
if(((nOpcode >> 21) & 0x1F) == 0x08)
{
switch((nOpcode >> 16) & 0x1F)
{
case 0x00:
case 0x01:
return (nAddress + CMIPS::GetBranch(static_cast<uint16>(nOpcode)) + 4);
break;
default:
return 0;
break;
}
}
return 0;
}
bool CCOP_SCU::IsBranch(uint32 nData)
bool CCOP_SCU::IsBranch(uint32 nOpcode)
{
return 0;
if(((nOpcode >> 21) & 0x1F) == 0x08)
{
switch((nOpcode >> 16) & 0x1F)
{
case 0x00:
case 0x01:
return true;
break;
default:
return false;
break;
}
}
return false;
}

View File

@ -26,7 +26,8 @@ private:
typedef void (CCOP_SCU::*InstructionFuncConstant)();
static InstructionFuncConstant m_pOpGeneral[0x20];
static InstructionFuncConstant m_pOpCO[0x40];
static InstructionFuncConstant m_pOpBC0[0x20];
static InstructionFuncConstant m_pOpC0[0x40];
uint8 m_nRT;
uint8 m_nRD;
@ -34,9 +35,14 @@ private:
//General
void MFC0();
void MTC0();
void CO();
void BC0();
void C0();
//CO
//BC0
void BC0F();
void BC0T();
//C0
void ERET();
void EI();
void DI();

View File

@ -504,7 +504,7 @@ void CPS2VM::ResetVM()
}
m_os->Initialize();
m_iopOs->Reset(new Iop::CSifManPs2(m_sif));
m_iopOs->Reset(new Iop::CSifManPs2(m_sif, m_pRAM, m_iop.m_ram));
CDROM0_Reset();
@ -764,7 +764,7 @@ void CPS2VM::CDROM0_Mount(const char* sPath)
}
m_pCDROM0 = new CISO9660(pStream);
m_iopOs->GetCdvdfsv()->SetIsoImage(m_pCDROM0);
SetIopCdImage(m_pCDROM0);
}
catch(const exception& Exception)
{
@ -777,10 +777,16 @@ void CPS2VM::CDROM0_Mount(const char* sPath)
void CPS2VM::CDROM0_Destroy()
{
m_iopOs->GetCdvdfsv()->SetIsoImage(NULL);
SetIopCdImage(NULL);
DELETEPTR(m_pCDROM0);
}
void CPS2VM::SetIopCdImage(CISO9660* image)
{
m_iopOs->GetCdvdfsv()->SetIsoImage(image);
m_iopOs->GetCdvdman()->SetIsoImage(image);
}
void CPS2VM::LoadBIOS()
{
CStdStream BiosStream(fopen("./vfs/rom0/scph10000.bin", "rb"));

View File

@ -168,6 +168,7 @@ private:
void CDROM0_Mount(const char*);
void CDROM0_Reset();
void CDROM0_Destroy();
void SetIopCdImage(CISO9660*);
void LoadBIOS();
void RegisterModulesInPadHandler();

View File

@ -511,7 +511,7 @@ void CSIF::SendCallReply(uint32 serverId, void* returnData)
if(replyIterator == m_callReplies.end()) return;
CALLREQUESTINFO& requestInfo(replyIterator->second);
assert(requestInfo.call.nRecv != 0);
//assert(requestInfo.call.nRecv != 0);
if(requestInfo.call.nRecv != 0)
{
memcpy(m_eeRam + requestInfo.call.nRecv, returnData, requestInfo.call.nRecvSize);

View File

@ -156,6 +156,10 @@ void CIopBios::Reset(Iop::CSifMan* sifMan)
}
{
RegisterModule(new Iop::CVblank(*this));
}
{
m_cdvdman = new Iop::CCdvdman(m_ram);
RegisterModule(m_cdvdman);
}
{
RegisterModule(m_sifMan);
@ -857,6 +861,11 @@ Iop::CIoman* CIopBios::GetIoman()
return m_ioman;
}
Iop::CCdvdman* CIopBios::GetCdvdman()
{
return m_cdvdman;
}
#ifdef _IOP_EMULATE_MODULES
Iop::CDbcMan* CIopBios::GetDbcman()

View File

@ -11,6 +11,7 @@
#include "Iop_SifMan.h"
#include "Iop_SifCmd.h"
#include "Iop_Ioman.h"
#include "Iop_Cdvdman.h"
#include "Iop_Stdio.h"
#include "Iop_Sysmem.h"
#include "Iop_Modload.h"
@ -82,6 +83,7 @@ public:
#endif
Iop::CIoman* GetIoman();
Iop::CCdvdman* GetCdvdman();
#ifdef _IOP_EMULATE_MODULES
Iop::CDbcMan* GetDbcman();
Iop::CPadMan* GetPadman();
@ -235,6 +237,7 @@ private:
Iop::CSifCmd* m_sifCmd;
Iop::CStdio* m_stdio;
Iop::CIoman* m_ioman;
Iop::CCdvdman* m_cdvdman;
Iop::CSysmem* m_sysmem;
Iop::CModload* m_modload;
#ifdef _IOP_EMULATE_MODULES

View File

@ -0,0 +1,98 @@
#include "../Log.h"
#include "Iop_Cdvdman.h"
#define LOG_NAME "iop_cdvdman"
#define FUNCTION_CDREAD "CdRead"
#define FUNCTION_CDSYNC "CdSync"
using namespace Iop;
using namespace std;
CCdvdman::CCdvdman(uint8* ram) :
m_ram(ram),
m_image(NULL)
{
}
CCdvdman::~CCdvdman()
{
}
string CCdvdman::GetId() const
{
return "cdvdman";
}
string CCdvdman::GetFunctionName(unsigned int functionId) const
{
switch(functionId)
{
case 6:
return FUNCTION_CDREAD;
break;
case 11:
return FUNCTION_CDSYNC;
break;
default:
return "unknown";
break;
}
}
void CCdvdman::Invoke(CMIPS& ctx, unsigned int functionId)
{
switch(functionId)
{
case 6:
ctx.m_State.nGPR[CMIPS::V0].nV0 = CdRead(
ctx.m_State.nGPR[CMIPS::A0].nV0,
ctx.m_State.nGPR[CMIPS::A1].nV0,
ctx.m_State.nGPR[CMIPS::A2].nV0,
ctx.m_State.nGPR[CMIPS::A3].nV0);
break;
case 11:
ctx.m_State.nGPR[CMIPS::V0].nV0 = CdSync();
break;
default:
CLog::GetInstance().Print(LOG_NAME, "Unknown function called (%d).\r\n",
functionId);
break;
}
}
void CCdvdman::SetIsoImage(CISO9660* image)
{
m_image = image;
}
uint32 CCdvdman::CdRead(uint32 startSector, uint32 sectorCount, uint32 bufferPtr, uint32 modePtr)
{
CLog::GetInstance().Print(LOG_NAME, FUNCTION_CDREAD "(startSector = 0x%X, sectorCount = 0x%X, bufferPtr = 0x%0.8X, modePtr = 0x%0.8X);\r\n",
startSector, sectorCount, bufferPtr, modePtr);
if(modePtr != 0)
{
uint8* mode = &m_ram[modePtr];
//Does that make sure it's 2048 byte mode?
assert(mode[2] == 0);
}
if(m_image != NULL && bufferPtr != 0)
{
uint8* buffer = &m_ram[bufferPtr];
uint32 sectorSize = 2048;
for(unsigned int i = 0; i < sectorCount; i++)
{
m_image->ReadBlock(startSector + i, buffer);
buffer += sectorSize;
}
}
return 1;
}
uint32 CCdvdman::CdSync()
{
CLog::GetInstance().Print(LOG_NAME, FUNCTION_CDSYNC "();\r\n");
return 1;
}

30
Source/iop/Iop_Cdvdman.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef _IOP_CDVDMAN_H_
#define _IOP_CDVDMAN_H_
#include "Iop_Module.h"
#include "../ISO9660/ISO9660.h"
namespace Iop
{
class CCdvdman : public CModule
{
public:
CCdvdman(uint8*);
virtual ~CCdvdman();
virtual std::string GetId() const;
virtual std::string GetFunctionName(unsigned int) const;
virtual void Invoke(CMIPS&, unsigned int);
void SetIsoImage(CISO9660*);
private:
uint32 CdRead(uint32, uint32, uint32, uint32);
uint32 CdSync();
CISO9660* m_image;
uint8* m_ram;
};
};
#endif

View File

@ -1,5 +1,6 @@
#include "Iop_SifCmd.h"
#include "IopBios.h"
#include "../SIF.h"
#include "../Log.h"
#include "../StructCollectionStateFile.h"
#include <boost/lexical_cast.hpp>
@ -17,7 +18,9 @@ using namespace std;
#define MODULE_NAME "sifcmd"
#define MODULE_VERSION 0x101
#define FUNCTION_SIFSENDCMD "SifSendCmd"
#define FUNCTION_SIFINITRPC "SifInitRpc"
#define FUNCTION_SIFBINDRPC "SifBindRpc"
#define FUNCTION_SIFREGISTERRPC "SifRegisterRpc"
#define FUNCTION_SIFSETRPCQUEUE "SifSetRpcQueue"
#define FUNCTION_SIFRPCLOOP "SifRpcLoop"
@ -93,9 +96,15 @@ string CSifCmd::GetFunctionName(unsigned int functionId) const
{
switch(functionId)
{
case 12:
return FUNCTION_SIFSENDCMD;
break;
case 14:
return FUNCTION_SIFINITRPC;
break;
case 15:
return FUNCTION_SIFBINDRPC;
break;
case 17:
return FUNCTION_SIFREGISTERRPC;
break;
@ -118,6 +127,21 @@ void CSifCmd::Invoke(CMIPS& context, unsigned int functionId)
{
switch(functionId)
{
case 12:
context.m_State.nGPR[CMIPS::V0].nV0 = SifSendCmd(
context.m_State.nGPR[CMIPS::A0].nV0,
context.m_State.nGPR[CMIPS::A1].nV0,
context.m_State.nGPR[CMIPS::A2].nV0,
context.m_State.nGPR[CMIPS::A3].nV0,
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 15:
context.m_State.nGPR[CMIPS::V0].nV0 = SifBindRpc(
context.m_State.nGPR[CMIPS::A0].nV0,
context.m_State.nGPR[CMIPS::A1].nV0,
context.m_State.nGPR[CMIPS::A2].nV0);
break;
case 17:
SifRegisterRpc(context);
break;
@ -195,6 +219,38 @@ void CSifCmd::ReturnFromRpcInvoke(CMIPS& context)
m_sifMan.SendCallReply(serverData->serverId, returnData);
}
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",
commandId, packetPtr, packetSize, srcExtraPtr, dstExtraPtr, sizeExtra);
assert(srcExtraPtr == 0);
assert(dstExtraPtr == 0);
assert(sizeExtra == 0);
uint8* packetData = m_ram + packetPtr;
size_t sentPacketSize = sizeof(CSIF::PACKETHDR) + packetSize;
uint8* sentPacket = reinterpret_cast<uint8*>(alloca(sentPacketSize));
CSIF::PACKETHDR* header = reinterpret_cast<CSIF::PACKETHDR*>(sentPacket);
header->nCID = commandId;
header->nSize = packetSize;
header->nDest = 0;
header->nOptional = 0;
memcpy(sentPacket + sizeof(CSIF::PACKETHDR), packetData, packetSize);
m_sifMan.SendPacket(sentPacket, sentPacketSize);
return 0;
}
uint32 CSifCmd::SifBindRpc(uint32 clientDataAddress, uint32 rpcNumber, uint32 mode)
{
CLog::GetInstance().Print(LOG_NAME, "SifBindRpc(clientData = 0x%0.8X, rpcNumber = 0x%0.8X, mode = 0x%0.8X);\r\n",
clientDataAddress, rpcNumber, mode);
//Set struct t_SifRpcServerData *server to 0
*reinterpret_cast<uint32*>(&m_ram[clientDataAddress + 0x24]) = rpcNumber;
return 0;
}
void CSifCmd::SifRegisterRpc(CMIPS& context)
{
uint32 serverDataAddr = context.m_State.nGPR[CMIPS::A0].nV0;

View File

@ -58,6 +58,8 @@ namespace Iop
void ClearServers();
void BuildExportTable();
uint32 SifSendCmd(uint32, uint32, uint32, uint32, uint32, uint32);
uint32 SifBindRpc(uint32, uint32, uint32);
void SifRegisterRpc(CMIPS&);
void SifSetRpcQueue(uint32, uint32);
void SifRpcLoop(uint32);

View File

@ -5,6 +5,7 @@
#define FUNCTION_SIFINIT "SifInit"
#define FUNCTION_SIFSETDMA "SifSetDma"
#define FUNCTION_SIFDMASTAT "SifDmaStat"
#define FUNCTION_SIFCHECKINIT "SifCheckInit"
using namespace Iop;
@ -35,6 +36,9 @@ string CSifMan::GetFunctionName(unsigned int functionId) const
case 7:
return FUNCTION_SIFSETDMA;
break;
case 8:
return FUNCTION_SIFDMASTAT;
break;
case 29:
return FUNCTION_SIFCHECKINIT;
break;
@ -52,6 +56,9 @@ void CSifMan::Invoke(CMIPS& context, unsigned int functionId)
context.m_State.nGPR[CMIPS::A1].nV0
));
break;
case 8:
context.m_State.nGPR[CMIPS::V0].nV0 = SifDmaStat(context.m_State.nGPR[CMIPS::A0].nV0);
break;
default:
CLog::GetInstance().Print(LOG_NAME, "%0.8X: Unknown function (%d) called.\r\n", context.m_State.nPC, functionId);
break;
@ -62,5 +69,12 @@ uint32 CSifMan::SifSetDma(uint32 structAddr, uint32 length)
{
CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFSETDMA "(structAddr = 0x%0.8X, length = %X);\r\n",
structAddr, length);
return 1;
return length;
}
uint32 CSifMan::SifDmaStat(uint32 transferId)
{
CLog::GetInstance().Print(LOG_NAME, FUNCTION_SIFDMASTAT "(transferId = %X);\r\n",
transferId);
return -1;
}

View File

@ -2,8 +2,10 @@
using namespace Iop;
CSifManPs2::CSifManPs2(CSIF& sif) :
m_sif(sif)
CSifManPs2::CSifManPs2(CSIF& sif, uint8* eeRam, uint8* iopRam) :
m_sif(sif),
m_eeRam(eeRam),
m_iopRam(iopRam)
{
}
@ -37,3 +39,31 @@ void CSifManPs2::SendCallReply(uint32 serverId, void* returnData)
{
m_sif.SendCallReply(serverId, returnData);
}
uint32 CSifManPs2::SifSetDma(uint32 structAddr, uint32 count)
{
CSifMan::SifSetDma(structAddr, count);
struct DMAREG
{
uint32 nSrcAddr;
uint32 nDstAddr;
uint32 nSize;
uint32 nFlags;
};
if(structAddr == 0)
{
return 0;
}
DMAREG* pXfer = reinterpret_cast<DMAREG*>(m_iopRam + structAddr);
for(unsigned int i = 0; i < count; i++)
{
uint8* src = m_iopRam + pXfer[i].nSrcAddr;
uint8* dst = m_eeRam + pXfer[i].nDstAddr;
memcpy(dst, src, pXfer[i].nSize);
}
return count;
}

View File

@ -9,7 +9,7 @@ namespace Iop
class CSifManPs2 : public CSifMan
{
public:
CSifManPs2(CSIF&);
CSifManPs2(CSIF&, uint8*, uint8*);
virtual ~CSifManPs2();
virtual void RegisterModule(uint32, CSifModule*);
@ -18,8 +18,13 @@ namespace Iop
virtual void SetDmaBuffer(uint32, uint32);
virtual void SendCallReply(uint32, void*);
protected:
virtual uint32 SifSetDma(uint32, uint32);
private:
CSIF& m_sif;
uint8* m_eeRam;
uint8* m_iopRam;
};
}

View File

@ -22,8 +22,9 @@ namespace Iop
virtual void SetDmaBuffer(uint32, uint32) = 0;
virtual void SendCallReply(uint32, void*) = 0;
private:
uint32 SifSetDma(uint32, uint32);
protected:
virtual uint32 SifSetDma(uint32, uint32);
virtual uint32 SifDmaStat(uint32);
};
}