2008-08-24 21:28:42 +00:00
|
|
|
#include "../AppConfig.h"
|
2008-01-15 20:27:44 +00:00
|
|
|
#include "Iop_Ioman.h"
|
|
|
|
#include "StdStream.h"
|
|
|
|
#include <stdexcept>
|
|
|
|
|
|
|
|
using namespace Iop;
|
|
|
|
|
|
|
|
#define PREF_IOP_FILEIO_STDLOGGING ("iop.fileio.stdlogging")
|
|
|
|
|
2012-05-26 18:37:09 +00:00
|
|
|
CIoman::CIoman(uint8* ram)
|
|
|
|
: m_ram(ram)
|
|
|
|
, m_nextFileHandle(3)
|
2008-01-15 20:27:44 +00:00
|
|
|
{
|
2008-08-24 21:28:42 +00:00
|
|
|
CAppConfig::GetInstance().RegisterPreferenceBoolean(PREF_IOP_FILEIO_STDLOGGING, false);
|
2008-01-15 20:27:44 +00:00
|
|
|
|
|
|
|
//Insert standard files if requested.
|
2008-08-24 21:28:42 +00:00
|
|
|
if(CAppConfig::GetInstance().GetPreferenceBoolean(PREF_IOP_FILEIO_STDLOGGING))
|
2008-01-15 20:27:44 +00:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2012-05-26 18:37:09 +00:00
|
|
|
m_files[1] = new Framework::CStdStream(fopen("ps2_stdout.txt", "ab"));
|
|
|
|
m_files[2] = new Framework::CStdStream(fopen("ps2_stderr.txt", "ab"));
|
2008-01-15 20:27:44 +00:00
|
|
|
}
|
|
|
|
catch(...)
|
|
|
|
{
|
|
|
|
//Humm, some error occured when opening these files...
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CIoman::~CIoman()
|
|
|
|
{
|
2012-05-26 18:37:09 +00:00
|
|
|
for(auto fileIterator(std::begin(m_files));
|
|
|
|
std::end(m_files) != fileIterator; fileIterator++)
|
|
|
|
{
|
|
|
|
delete fileIterator->second;
|
|
|
|
}
|
2008-11-04 03:47:36 +00:00
|
|
|
m_devices.clear();
|
2008-01-15 20:27:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string CIoman::GetId() const
|
|
|
|
{
|
2012-05-26 18:37:09 +00:00
|
|
|
return "ioman";
|
2008-01-15 20:27:44 +00:00
|
|
|
}
|
|
|
|
|
2012-05-26 18:37:09 +00:00
|
|
|
std::string CIoman::GetFunctionName(unsigned int functionId) const
|
2008-11-28 23:46:52 +00:00
|
|
|
{
|
|
|
|
return "unknown";
|
|
|
|
}
|
|
|
|
|
2008-11-04 03:47:36 +00:00
|
|
|
void CIoman::RegisterDevice(const char* name, const DevicePtr& device)
|
2008-01-15 20:27:44 +00:00
|
|
|
{
|
2012-05-26 18:37:09 +00:00
|
|
|
m_devices[name] = device;
|
2008-01-15 20:27:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32 CIoman::Open(uint32 flags, const char* path)
|
|
|
|
{
|
2012-05-26 18:37:09 +00:00
|
|
|
uint32 handle = 0xFFFFFFFF;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::string fullPath(path);
|
|
|
|
std::string::size_type position = fullPath.find(":");
|
|
|
|
if(position == std::string::npos)
|
|
|
|
{
|
|
|
|
throw std::runtime_error("Invalid path.");
|
|
|
|
}
|
|
|
|
std::string deviceName(fullPath.begin(), fullPath.begin() + position);
|
|
|
|
std::string devicePath(fullPath.begin() + position + 1, fullPath.end());
|
|
|
|
DeviceMapType::iterator device(m_devices.find(deviceName));
|
|
|
|
if(device == m_devices.end())
|
|
|
|
{
|
|
|
|
throw std::runtime_error("Device not found.");
|
|
|
|
}
|
|
|
|
Framework::CStream* stream = device->second->GetFile(flags, devicePath.c_str());
|
|
|
|
if(stream == NULL)
|
|
|
|
{
|
|
|
|
throw std::runtime_error("File not found.");
|
|
|
|
}
|
|
|
|
handle = m_nextFileHandle++;
|
|
|
|
m_files[handle] = stream;
|
|
|
|
}
|
|
|
|
catch(const std::exception& except)
|
|
|
|
{
|
|
|
|
printf("%s: Error occured while trying to open file : %s\r\n", __FUNCTION__, except.what());
|
|
|
|
}
|
|
|
|
return handle;
|
2008-01-15 20:27:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32 CIoman::Close(uint32 handle)
|
|
|
|
{
|
2012-05-26 18:37:09 +00:00
|
|
|
uint32 result = 0xFFFFFFFF;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
auto file(m_files.find(handle));
|
|
|
|
if(file == std::end(m_files))
|
|
|
|
{
|
|
|
|
throw std::runtime_error("Invalid file handle.");
|
|
|
|
}
|
|
|
|
delete file->second;
|
|
|
|
m_files.erase(file);
|
|
|
|
result = 0;
|
|
|
|
}
|
|
|
|
catch(const std::exception& except)
|
|
|
|
{
|
|
|
|
printf("%s: Error occured while trying to close file : %s\r\n", __FUNCTION__, except.what());
|
|
|
|
}
|
|
|
|
return result;
|
2008-01-15 20:27:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32 CIoman::Read(uint32 handle, uint32 size, void* buffer)
|
|
|
|
{
|
2012-05-26 18:37:09 +00:00
|
|
|
uint32 result = 0xFFFFFFFF;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Framework::CStream* stream = GetFileStream(handle);
|
|
|
|
result = static_cast<uint32>(stream->Read(buffer, size));
|
|
|
|
}
|
|
|
|
catch(const std::exception& except)
|
|
|
|
{
|
|
|
|
printf("%s: Error occured while trying to read file : %s\r\n", __FUNCTION__, except.what());
|
|
|
|
}
|
|
|
|
return result;
|
2008-01-15 20:27:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32 CIoman::Write(uint32 handle, uint32 size, void* buffer)
|
|
|
|
{
|
2012-05-26 18:37:09 +00:00
|
|
|
uint32 result = 0xFFFFFFFF;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Framework::CStream* stream = GetFileStream(handle);
|
|
|
|
result = static_cast<uint32>(stream->Write(buffer, size));
|
|
|
|
}
|
|
|
|
catch(const std::exception& except)
|
|
|
|
{
|
|
|
|
printf("%s: Error occured while trying to write file : %s\r\n", __FUNCTION__, except.what());
|
|
|
|
}
|
|
|
|
return result;
|
2008-01-15 20:27:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32 CIoman::Seek(uint32 handle, uint32 position, uint32 whence)
|
|
|
|
{
|
2012-05-26 18:37:09 +00:00
|
|
|
uint32 result = 0xFFFFFFFF;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Framework::CStream* stream = GetFileStream(handle);
|
|
|
|
switch(whence)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
whence = Framework::STREAM_SEEK_SET;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
whence = Framework::STREAM_SEEK_CUR;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
whence = Framework::STREAM_SEEK_END;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
stream->Seek(position, static_cast<Framework::STREAM_SEEK_DIRECTION>(whence));
|
|
|
|
result = static_cast<uint32>(stream->Tell());
|
|
|
|
}
|
|
|
|
catch(const std::exception& except)
|
|
|
|
{
|
|
|
|
printf("%s: Error occured while trying to seek file : %s\r\n", __FUNCTION__, except.what());
|
|
|
|
}
|
|
|
|
return result;
|
2008-01-15 20:27:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32 CIoman::DelDrv(const char* deviceName)
|
|
|
|
{
|
2012-05-26 18:37:09 +00:00
|
|
|
return -1;
|
2008-01-15 20:27:44 +00:00
|
|
|
}
|
|
|
|
|
2012-05-26 18:37:09 +00:00
|
|
|
Framework::CStream* CIoman::GetFileStream(uint32 handle)
|
2008-01-15 20:27:44 +00:00
|
|
|
{
|
2012-05-26 18:37:09 +00:00
|
|
|
auto file(m_files.find(handle));
|
|
|
|
if(file == std::end(m_files))
|
|
|
|
{
|
|
|
|
throw std::runtime_error("Invalid file handle.");
|
|
|
|
}
|
|
|
|
return file->second;
|
2008-01-15 20:27:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//IOP Invoke
|
|
|
|
void CIoman::Invoke(CMIPS& context, unsigned int functionId)
|
|
|
|
{
|
2012-05-26 18:37:09 +00:00
|
|
|
switch(functionId)
|
|
|
|
{
|
|
|
|
case 4:
|
|
|
|
context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(Open(
|
|
|
|
context.m_State.nGPR[CMIPS::A1].nV[0],
|
|
|
|
reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV[0]])
|
|
|
|
));
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(Close(
|
|
|
|
context.m_State.nGPR[CMIPS::A0].nV[0]
|
|
|
|
));
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(Read(
|
|
|
|
context.m_State.nGPR[CMIPS::A0].nV[0],
|
|
|
|
context.m_State.nGPR[CMIPS::A2].nV[0],
|
|
|
|
&m_ram[context.m_State.nGPR[CMIPS::A1].nV[0]]
|
|
|
|
));
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(Seek(
|
|
|
|
context.m_State.nGPR[CMIPS::A0].nV[0],
|
|
|
|
context.m_State.nGPR[CMIPS::A1].nV[0],
|
|
|
|
context.m_State.nGPR[CMIPS::A2].nV[0]));
|
|
|
|
break;
|
|
|
|
case 21:
|
|
|
|
context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(DelDrv(
|
|
|
|
reinterpret_cast<char*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nD0])
|
|
|
|
));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printf("%s(%0.8X): Unknown function (%d) called.\r\n", __FUNCTION__, context.m_State.nPC, functionId);
|
|
|
|
break;
|
|
|
|
}
|
2008-01-15 20:27:44 +00:00
|
|
|
}
|
|
|
|
|
2008-10-20 04:14:13 +00:00
|
|
|
//--------------------------------------------------
|
|
|
|
// CFile
|
|
|
|
//--------------------------------------------------
|
|
|
|
|
2012-05-26 18:37:09 +00:00
|
|
|
CIoman::CFile::CFile(uint32 handle, CIoman& ioman)
|
|
|
|
: m_handle(handle)
|
|
|
|
, m_ioman(ioman)
|
2008-10-20 04:14:13 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
CIoman::CFile::~CFile()
|
|
|
|
{
|
2012-05-26 18:37:09 +00:00
|
|
|
m_ioman.Close(m_handle);
|
2008-10-20 04:14:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CIoman::CFile::operator uint32()
|
|
|
|
{
|
2012-05-26 18:37:09 +00:00
|
|
|
return m_handle;
|
2008-10-20 04:14:13 +00:00
|
|
|
}
|