Play-/Source/iop/Iop_Cdvdfsv.cpp
2012-04-14 21:18:59 +00:00

434 lines
10 KiB
C++

#include <assert.h>
#include "../Log.h"
#include "../Ps2Const.h"
#include "IOP_Cdvdfsv.h"
#include "placeholder_def.h"
using namespace Iop;
#define LOG_NAME "iop_cdvdfsv"
CCdvdfsv::CCdvdfsv(CSifMan& sif, uint8* iopRam) :
m_nStreamPos(0),
m_iso(NULL),
m_iopRam(iopRam)
{
m_module592 = CSifModuleAdapter(bind(&CCdvdfsv::Invoke592, this,
PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3, PLACEHOLDER_4, PLACEHOLDER_5, PLACEHOLDER_6));
m_module593 = CSifModuleAdapter(bind(&CCdvdfsv::Invoke593, this,
PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3, PLACEHOLDER_4, PLACEHOLDER_5, PLACEHOLDER_6));
m_module595 = CSifModuleAdapter(bind(&CCdvdfsv::Invoke595, this,
PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3, PLACEHOLDER_4, PLACEHOLDER_5, PLACEHOLDER_6));
m_module597 = CSifModuleAdapter(bind(&CCdvdfsv::Invoke597, this,
PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3, PLACEHOLDER_4, PLACEHOLDER_5, PLACEHOLDER_6));
m_module59A = CSifModuleAdapter(bind(&CCdvdfsv::Invoke59A, this,
PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3, PLACEHOLDER_4, PLACEHOLDER_5, PLACEHOLDER_6));
m_module59C = CSifModuleAdapter(bind(&CCdvdfsv::Invoke59C, this,
PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3, PLACEHOLDER_4, PLACEHOLDER_5, PLACEHOLDER_6));
sif.RegisterModule(MODULE_ID_1, &m_module592);
sif.RegisterModule(MODULE_ID_2, &m_module593);
sif.RegisterModule(MODULE_ID_4, &m_module595);
sif.RegisterModule(MODULE_ID_6, &m_module597);
sif.RegisterModule(MODULE_ID_7, &m_module59A);
sif.RegisterModule(MODULE_ID_8, &m_module59C);
}
CCdvdfsv::~CCdvdfsv()
{
}
std::string CCdvdfsv::GetId() const
{
return "cdvdfsv";
}
std::string CCdvdfsv::GetFunctionName(unsigned int) const
{
return "unknown";
}
void CCdvdfsv::SetIsoImage(CISO9660* iso)
{
m_iso = iso;
}
void CCdvdfsv::Invoke(CMIPS& context, unsigned int functionId)
{
throw std::runtime_error("Not implemented.");
}
/*
void CCdvdfsv::SaveState(CStream* pStream)
{
if(m_nID != MODULE_ID_1) return;
pStream->Write(&m_nStreamPos, 4);
}
void CCdvdfsv::LoadState(CStream* pStream)
{
if(m_nID != MODULE_ID_1) return;
pStream->Read(&m_nStreamPos, 4);
}
*/
void CCdvdfsv::Invoke592(uint32 method, uint32* args, uint32 argsSize, uint32* ret, uint32 retSize, uint8* ram)
{
switch(method)
{
case 0:
{
//Init
assert(argsSize >= 4);
uint32 nMode = args[0x00];
if(retSize != 0)
{
assert(retSize >= 0x10);
ret[0x03] = 0xFF;
}
CLog::GetInstance().Print(LOG_NAME, "Init(mode = %d);\r\n", nMode);
}
break;
default:
CLog::GetInstance().Print(LOG_NAME, "Unknown method invoked (0x%0.8X, 0x%0.8X).\r\n", 0x592, method);
break;
}
}
void CCdvdfsv::Invoke593(uint32 method, uint32* args, uint32 argsSize, uint32* ret, uint32 retSize, uint8* ram)
{
switch(method)
{
case 0x01:
{
assert(retSize >= 0xC);
CLog::GetInstance().Print(LOG_NAME, "ReadClock();\r\n");
time_t currentTime = time(0);
tm* localTime = localtime(&currentTime);
uint8* clockResult = reinterpret_cast<uint8*>(ret + 1);
clockResult[0] = 0x01; //Status ?
clockResult[1] = static_cast<uint8>(localTime->tm_sec); //Seconds
clockResult[2] = static_cast<uint8>(localTime->tm_min); //Minutes
clockResult[3] = static_cast<uint8>(localTime->tm_hour); //Hour
clockResult[4] = 0; //Padding
clockResult[5] = static_cast<uint8>(localTime->tm_mday); //Day
clockResult[6] = static_cast<uint8>(localTime->tm_mon); //Month
clockResult[7] = static_cast<uint8>(localTime->tm_year % 100); //Year
ret[0x00] = 0x00;
}
break;
case 0x03:
assert(retSize >= 4);
CLog::GetInstance().Print(LOG_NAME, "GetDiskType();\r\n");
//Returns PS2DVD for now.
ret[0x00] = 0x14;
break;
case 0x04:
assert(retSize >= 4);
CLog::GetInstance().Print(LOG_NAME, "GetError();\r\n");
ret[0x00] = 0x00;
break;
case 0x0C:
//Status
//Returns
//0 - Stopped
//1 - Open
//2 - Spin
//3 - Read
//and more...
assert(retSize >= 4);
CLog::GetInstance().Print(LOG_NAME, "Status();\r\n");
ret[0x00] = 0;
break;
case 0x22:
{
//Set Media Mode (1 - CDROM, 2 - DVDROM)
assert(argsSize >= 4);
assert(retSize >= 4);
uint32 nMode = args[0x00];
CLog::GetInstance().Print(LOG_NAME, "SetMediaMode(mode = %i);\r\n", nMode);
ret[0x00] = 1;
}
break;
default:
CLog::GetInstance().Print(LOG_NAME, "Unknown method invoked (0x%0.8X, 0x%0.8X).\r\n", 0x593, method);
break;
}
}
void CCdvdfsv::Invoke595(uint32 method, uint32* args, uint32 argsSize, uint32* ret, uint32 retSize, uint8* ram)
{
switch(method)
{
case 1:
Read(args, argsSize, ret, retSize, ram);
break;
case 4:
{
//GetToc
assert(argsSize >= 4);
assert(retSize >= 4);
uint32 nBuffer = args[0x00];
CLog::GetInstance().Print(LOG_NAME, "GetToc(buffer = 0x%0.8X);\r\n", nBuffer);
ret[0x00] = 1;
}
break;
case 9:
StreamCmd(args, argsSize, ret, retSize, ram);
break;
case 0x0D:
//ReadIopMem
ReadIopMem(args, argsSize, ret, retSize, ram);
break;
case 0x0E:
//DiskReady (returns 2 if ready, 6 if not ready)
assert(retSize >= 4);
CLog::GetInstance().Print(LOG_NAME, "NDiskReady();\r\n");
ret[0x00] = 2;
break;
default:
CLog::GetInstance().Print(LOG_NAME, "Unknown method invoked (0x%0.8X, 0x%0.8X).\r\n", 0x595, method);
break;
}
}
void CCdvdfsv::Invoke597(uint32 method, uint32* args, uint32 argsSize, uint32* ret, uint32 retSize, uint8* ram)
{
switch(method)
{
case 0:
SearchFile(args, argsSize, ret, retSize, ram);
break;
default:
CLog::GetInstance().Print(LOG_NAME, "Unknown method invoked (0x%0.8X, 0x%0.8X).\r\n", 0x597, method);
break;
}
}
void CCdvdfsv::Invoke59A(uint32 method, uint32* args, uint32 argsSize, uint32* ret, uint32 retSize, uint8* ram)
{
Invoke59C(method, args, argsSize, ret, retSize, ram);
}
void CCdvdfsv::Invoke59C(uint32 method, uint32* args, uint32 argsSize, uint32* ret, uint32 retSize, uint8* ram)
{
switch(method)
{
case 0:
{
//DiskReady (returns 2 if ready, 6 if not ready)
assert(retSize >= 4);
assert(argsSize >= 4);
uint32 nMode = args[0x00];
CLog::GetInstance().Print(LOG_NAME, "DiskReady(mode = %i);\r\n", nMode);
ret[0x00] = 2;
}
break;
default:
CLog::GetInstance().Print(LOG_NAME, "Unknown method invoked (0x%0.8X, 0x%0.8X).\r\n", 0x59C, method);
break;
}
}
void CCdvdfsv::Read(uint32* args, uint32 argsSize, uint32* ret, uint32 retSize, uint8* ram)
{
uint32 nSector = args[0x00];
uint32 nCount = args[0x01];
uint32 nDstAddr = args[0x02];
uint32 nMode = args[0x03];
CLog::GetInstance().Print(LOG_NAME, "Read(sector = 0x%0.8X, count = 0x%0.8X, addr = 0x%0.8X, mode = 0x%0.8X);\r\n", \
nSector,
nCount,
nDstAddr,
nMode);
if(m_iso != NULL)
{
for(unsigned int i = 0; i < nCount; i++)
{
m_iso->ReadBlock(nSector + i, ram + (nDstAddr + (i * 0x800)));
}
}
if(retSize >= 4)
{
ret[0] = 0;
}
}
void CCdvdfsv::ReadIopMem(uint32* args, uint32 argsSize, uint32* ret, uint32 retSize, uint8* ram)
{
uint32 nSector = args[0x00];
uint32 nCount = args[0x01];
uint32 nDstAddr = args[0x02];
uint32 nMode = args[0x03];
CLog::GetInstance().Print(LOG_NAME, "ReadIopMem(sector = 0x%0.8X, count = 0x%0.8X, addr = 0x%0.8X, mode = 0x%0.8X);\r\n", \
nSector,
nCount,
nDstAddr,
nMode);
if(m_iso != NULL)
{
for(unsigned int i = 0; i < nCount; i++)
{
m_iso->ReadBlock(nSector + i, m_iopRam + nDstAddr);
nDstAddr += 0x800;
}
}
if(retSize >= 4)
{
ret[0] = 0;
}
}
void CCdvdfsv::StreamCmd(uint32* args, uint32 argsSize, uint32* ret, uint32 retSize, uint8* ram)
{
uint32 nSector, nCount, nDstAddr, nCmd, nMode;
nSector = args[0x00];
nCount = args[0x01];
nDstAddr = args[0x02];
nCmd = args[0x03];
nMode = args[0x04];
CLog::GetInstance().Print(LOG_NAME, "StreamCmd(sector = 0x%0.8X, count = 0x%0.8X, addr = 0x%0.8X, cmd = 0x%0.8X);\r\n", \
nSector,
nCount,
nDstAddr,
nMode);
switch(nCmd)
{
case 1:
//Start
m_nStreamPos = nSector;
ret[0] = 1;
CLog::GetInstance().Print(LOG_NAME, "StreamStart(pos = 0x%0.8X);\r\n", \
nSector);
break;
case 2:
//Read
nDstAddr &= (PS2::EERAMSIZE - 1);
if(m_iso != NULL)
{
for(unsigned int i = 0; i < nCount; i++)
{
m_iso->ReadBlock(m_nStreamPos, ram + (nDstAddr + (i * 0x800)));
m_nStreamPos++;
}
}
ret[0] = nCount;
CLog::GetInstance().Print(LOG_NAME, "StreamRead(count = 0x%0.8X, dest = 0x%0.8X);\r\n", \
nCount, \
nDstAddr);
break;
case 5:
//Init
ret[0] = 1;
CLog::GetInstance().Print(LOG_NAME, "StreamInit(bufsize = 0x%0.8X, numbuf = 0x%0.8X, buf = 0x%0.8X);\r\n", \
nSector, \
nCount, \
nDstAddr);
break;
case 4:
case 9:
//Seek
m_nStreamPos = nSector;
ret[0] = 1;
CLog::GetInstance().Print(LOG_NAME, "StreamSeek(pos = 0x%0.8X);\r\n", \
nSector);
break;
default:
CLog::GetInstance().Print(LOG_NAME, "Unknown stream command used.\r\n");
break;
}
}
void CCdvdfsv::SearchFile(uint32* args, uint32 argsSize, uint32* ret, uint32 retSize, uint8* ram)
{
uint32 pathOffset = 0x24;
if(argsSize == 0x128)
{
pathOffset = 0x24;
}
else if(argsSize == 0x124)
{
pathOffset = 0x20;
}
else
{
assert(0);
}
assert(retSize == 4);
if(m_iso == NULL)
{
ret[0] = 0;
return;
}
//0x12C structure
//00 - Block Num
//04 - Size
//08
//0C
//10
//14
//18
//1C
//20 - Unknown
//24 - Path
char* sPath = reinterpret_cast<char*>(args) + pathOffset;
//Fix all slashes
std::string fixedPath(sPath);
{
std::string::size_type slashPos = fixedPath.find('\\');
while(slashPos != std::string::npos)
{
fixedPath[slashPos] = '/';
slashPos = fixedPath.find('\\', slashPos + 1);
}
}
CLog::GetInstance().Print(LOG_NAME, "SearchFile(path = %s);\r\n", fixedPath.c_str());
ISO9660::CDirectoryRecord Record;
if(!m_iso->GetFileRecord(&Record, fixedPath.c_str()))
{
ret[0] = 0;
return;
}
args[0x00] = Record.GetPosition();
args[0x01] = Record.GetDataLength();
ret[0] = 1;
}