mirror of
https://github.com/libretro/Play-.git
synced 2025-01-27 03:35:13 +00:00
git-svn-id: http://svn.purei.org/purei/trunk@173 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
parent
4568411ef0
commit
d75bac07a3
@ -60,6 +60,46 @@ uint32 CIoman::Open(uint32 flags, const char* path)
|
||||
return handle;
|
||||
}
|
||||
|
||||
uint32 CIoman::Close(uint32 handle)
|
||||
{
|
||||
uint32 result = 0xFFFFFFFF;
|
||||
try
|
||||
{
|
||||
FileMapType::iterator file(m_files.find(handle));
|
||||
if(file == m_files.end())
|
||||
{
|
||||
throw runtime_error("Invalid file handle.");
|
||||
}
|
||||
delete file->second;
|
||||
m_files.erase(file);
|
||||
result = 0;
|
||||
}
|
||||
catch(const exception& except)
|
||||
{
|
||||
printf("%s: Error occured while trying to close file : %s\r\n", __FUNCTION__, except.what());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32 CIoman::Read(uint32 handle, uint32 size, void* buffer)
|
||||
{
|
||||
uint32 result = 0xFFFFFFFF;
|
||||
try
|
||||
{
|
||||
FileMapType::iterator file(m_files.find(handle));
|
||||
if(file == m_files.end())
|
||||
{
|
||||
throw runtime_error("Invalid file handle.");
|
||||
}
|
||||
result = static_cast<uint32>(file->second->Read(buffer, size));
|
||||
}
|
||||
catch(const exception& except)
|
||||
{
|
||||
printf("%s: Error occured while trying to read file : %s\r\n", __FUNCTION__, except.what());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32 CIoman::Seek(uint32 handle, uint32 position, uint32 whence)
|
||||
{
|
||||
uint32 result = 0xFFFFFFFF;
|
||||
@ -103,6 +143,18 @@ void CIoman::Invoke(CMIPS& context, unsigned int functionId)
|
||||
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],
|
||||
@ -110,7 +162,7 @@ void CIoman::Invoke(CMIPS& context, unsigned int functionId)
|
||||
context.m_State.nGPR[CMIPS::A2].nV[0]));
|
||||
break;
|
||||
default:
|
||||
printf("%s(%0.8X): Unknown function (%d) called.", __FUNCTION__, context.m_State.nPC, functionId);
|
||||
printf("%s(%0.8X): Unknown function (%d) called.\r\n", __FUNCTION__, context.m_State.nPC, functionId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ namespace Iop
|
||||
void RegisterDevice(const char*, Ioman::CDevice*);
|
||||
|
||||
uint32 Open(uint32, const char*);
|
||||
uint32 Close(uint32);
|
||||
uint32 Read(uint32, uint32, void*);
|
||||
uint32 Seek(uint32, uint32, uint32);
|
||||
|
||||
private:
|
||||
|
@ -3,9 +3,13 @@
|
||||
using namespace Iop;
|
||||
using namespace std;
|
||||
|
||||
CSysmem::CSysmem()
|
||||
CSysmem::CSysmem(uint32 memoryBegin, uint32 memoryEnd) :
|
||||
m_memoryBegin(memoryBegin),
|
||||
m_memoryEnd(memoryEnd),
|
||||
m_memorySize(memoryEnd - memoryBegin)
|
||||
{
|
||||
|
||||
//Initialize block map
|
||||
m_blockMap[m_memorySize] = 0;
|
||||
}
|
||||
|
||||
CSysmem::~CSysmem()
|
||||
@ -18,7 +22,55 @@ string CSysmem::GetId() const
|
||||
return "sysmem";
|
||||
}
|
||||
|
||||
void CSysmem::Invoke(CMIPS& context, unsigned int commandId)
|
||||
void CSysmem::Invoke(CMIPS& context, unsigned int functionId)
|
||||
{
|
||||
|
||||
switch(functionId)
|
||||
{
|
||||
case 4:
|
||||
context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(AllocateMemory(
|
||||
context.m_State.nGPR[CMIPS::A1].nV[0],
|
||||
context.m_State.nGPR[CMIPS::A0].nV[0]
|
||||
));
|
||||
break;
|
||||
default:
|
||||
printf("%s(%0.8X): Unknown function (%d) called.\r\n", __FUNCTION__, context.m_State.nPC, functionId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 CSysmem::AllocateMemory(uint32 size, uint32 flags)
|
||||
{
|
||||
uint32 begin = 0;
|
||||
const uint32 blockSize = 0x400;
|
||||
size = ((size + (blockSize - 1)) / blockSize) * blockSize;
|
||||
for(BlockMapType::iterator blockIterator(m_blockMap.begin());
|
||||
blockIterator != m_blockMap.end(); blockIterator++)
|
||||
{
|
||||
uint32 end = blockIterator->first;
|
||||
if((end - begin) >= size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
begin = blockIterator->first + blockIterator->second;
|
||||
}
|
||||
if(begin != m_memorySize)
|
||||
{
|
||||
m_blockMap[begin] = size;
|
||||
return begin + m_memoryBegin;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CSysmem::FreeMemory(uint32 address)
|
||||
{
|
||||
address -= m_memoryBegin;
|
||||
BlockMapType::iterator block(m_blockMap.find(address));
|
||||
if(block != m_blockMap.end())
|
||||
{
|
||||
m_blockMap.erase(block);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s: Trying to unallocate an unexisting memory block (0x%0.8X).\r\n", __FUNCTION__, address);
|
||||
}
|
||||
}
|
||||
|
@ -8,14 +8,21 @@ namespace Iop
|
||||
class CSysmem : public CModule
|
||||
{
|
||||
public:
|
||||
CSysmem();
|
||||
virtual ~CSysmem();
|
||||
CSysmem(uint32, uint32);
|
||||
virtual ~CSysmem();
|
||||
|
||||
std::string GetId() const;
|
||||
void Invoke(CMIPS&, unsigned int);
|
||||
std::string GetId() const;
|
||||
void Invoke(CMIPS&, unsigned int);
|
||||
|
||||
uint32 AllocateMemory(uint32, uint32);
|
||||
void FreeMemory(uint32);
|
||||
private:
|
||||
typedef std::map<uint32, uint32> BlockMapType;
|
||||
|
||||
BlockMapType m_blockMap;
|
||||
uint32 m_memoryBegin;
|
||||
uint32 m_memoryEnd;
|
||||
uint32 m_memorySize;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -17,9 +17,6 @@ m_pauseAck(false),
|
||||
m_emuThread(NULL),
|
||||
m_iopStdio(NULL)
|
||||
{
|
||||
//Initialize block map
|
||||
m_blockMap[RAMSIZE] = 0;
|
||||
|
||||
memset(&m_cpu.m_State, 0, sizeof(m_cpu.m_State));
|
||||
m_ram = new uint8[RAMSIZE];
|
||||
m_cpu.m_pMemoryMap->InsertReadMap(0x00000000, RAMSIZE - 1, m_ram, MEMORYMAP_TYPE_MEMORY, 0x00);
|
||||
@ -36,7 +33,22 @@ m_iopStdio(NULL)
|
||||
m_cpu.m_Comments.Unserialize("comments.bin");
|
||||
#endif
|
||||
|
||||
uint32 stackBegin = AllocateMemory(DEFAULT_STACKSIZE);
|
||||
//Register built-in modules
|
||||
{
|
||||
m_iopStdio = new Iop::CStdio(m_ram);
|
||||
RegisterModule(m_iopStdio);
|
||||
}
|
||||
{
|
||||
m_iopIoman = new Iop::CIoman(m_ram);
|
||||
RegisterModule(m_iopIoman);
|
||||
m_iopIoman->RegisterDevice("host", new Iop::Ioman::CPsf(m_fileSystem));
|
||||
}
|
||||
{
|
||||
m_iopSysmem = new Iop::CSysmem(0x1000, RAMSIZE);
|
||||
RegisterModule(m_iopSysmem);
|
||||
}
|
||||
|
||||
uint32 stackBegin = m_iopSysmem->AllocateMemory(DEFAULT_STACKSIZE, 0);
|
||||
uint32 entryPoint = LoadIopModule("psf2.irx", 0x000100000);
|
||||
string execPath = "host:/psf2.irx";
|
||||
m_cpu.m_State.nGPR[CMIPS::SP].nV0 = stackBegin + DEFAULT_STACKSIZE;
|
||||
@ -51,15 +63,6 @@ m_iopStdio(NULL)
|
||||
4);
|
||||
m_cpu.m_State.nPC = entryPoint;
|
||||
|
||||
{
|
||||
m_iopStdio = new Iop::CStdio(m_ram);
|
||||
m_iopModules[m_iopStdio->GetId()] = m_iopStdio;
|
||||
}
|
||||
{
|
||||
m_iopIoman = new Iop::CIoman(m_ram);
|
||||
m_iopModules[m_iopIoman->GetId()] = m_iopIoman;
|
||||
m_iopIoman->RegisterDevice("host", new Iop::Ioman::CPsf(m_fileSystem));
|
||||
}
|
||||
|
||||
m_emuThread = new thread(bind(&CPsfVm::EmulationProc, this));
|
||||
}
|
||||
@ -116,7 +119,7 @@ uint32 CPsfVm::LoadIopModule(const char* modulePath, uint32 baseAddress)
|
||||
CPtrStream stream(file->data, file->size);
|
||||
CELF elf(&stream);
|
||||
|
||||
baseAddress = AllocateMemory(elf.m_nLenght);
|
||||
baseAddress = m_iopSysmem->AllocateMemory(elf.m_nLenght, 0);
|
||||
|
||||
//Process relocation
|
||||
for(unsigned int i = 0; i < elf.m_Header.nSectHeaderCount; i++)
|
||||
@ -227,6 +230,11 @@ string CPsfVm::ReadModuleName(uint32 address)
|
||||
return moduleName;
|
||||
}
|
||||
|
||||
void CPsfVm::RegisterModule(Iop::CModule* module)
|
||||
{
|
||||
m_iopModules[module->GetId()] = module;
|
||||
}
|
||||
|
||||
void CPsfVm::SysCallHandlerStub(CMIPS* state)
|
||||
{
|
||||
reinterpret_cast<CPsfVm*>(state->m_handlerParam)->SysCallHandler();
|
||||
@ -259,42 +267,6 @@ void CPsfVm::SysCallHandler()
|
||||
}
|
||||
}
|
||||
|
||||
uint32 CPsfVm::AllocateMemory(uint32 size)
|
||||
{
|
||||
uint32 begin = 0x1000;
|
||||
const uint32 blockSize = 0x400;
|
||||
size = ((size + (blockSize - 1)) / blockSize) * blockSize;
|
||||
for(BlockMapType::iterator blockIterator(m_blockMap.begin());
|
||||
blockIterator != m_blockMap.end(); blockIterator++)
|
||||
{
|
||||
uint32 end = blockIterator->first;
|
||||
if((end - begin) >= size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
begin = blockIterator->first + blockIterator->second;
|
||||
}
|
||||
if(begin != RAMSIZE)
|
||||
{
|
||||
m_blockMap[begin] = size;
|
||||
return begin;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CPsfVm::FreeMemory(uint32 address)
|
||||
{
|
||||
BlockMapType::iterator block(m_blockMap.find(address));
|
||||
if(block != m_blockMap.end())
|
||||
{
|
||||
m_blockMap.erase(block);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s: Trying to unallocate an unexisting memory block (0x%0.8X).\r\n", __FUNCTION__, address);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 CPsfVm::Push(uint32& address, const uint8* data, uint32 size)
|
||||
{
|
||||
uint32 fixedSize = ((size + 0xF) / 0x10) * 0x10;
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <boost/thread.hpp>
|
||||
#include "Iop_Stdio.h"
|
||||
#include "Iop_Ioman.h"
|
||||
#include "Iop_Sysmem.h"
|
||||
#include "Ioman_Psf.h"
|
||||
|
||||
class CPsfVm : public CVirtualMachine
|
||||
@ -23,7 +24,6 @@ public:
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, Iop::CModule*> IopModuleMapType;
|
||||
typedef std::map<uint32, uint32> BlockMapType;
|
||||
|
||||
enum RAMSIZE
|
||||
{
|
||||
@ -36,8 +36,6 @@ private:
|
||||
};
|
||||
|
||||
uint32 LoadIopModule(const char*, uint32);
|
||||
uint32 AllocateMemory(uint32);
|
||||
void FreeMemory(uint32);
|
||||
uint32 Push(uint32&, const uint8*, uint32);
|
||||
static unsigned int TickFunctionStub(unsigned int, CMIPS*);
|
||||
static void SysCallHandlerStub(CMIPS*);
|
||||
@ -45,13 +43,13 @@ private:
|
||||
void SysCallHandler();
|
||||
|
||||
std::string ReadModuleName(uint32);
|
||||
void RegisterModule(Iop::CModule*);
|
||||
|
||||
void EmulationProc();
|
||||
|
||||
CMIPS m_cpu;
|
||||
CPsfFs m_fileSystem;
|
||||
uint8* m_ram;
|
||||
BlockMapType m_blockMap;
|
||||
STATUS m_status;
|
||||
bool m_pauseAck;
|
||||
boost::thread* m_emuThread;
|
||||
@ -59,6 +57,7 @@ private:
|
||||
IopModuleMapType m_iopModules;
|
||||
Iop::CStdio* m_iopStdio;
|
||||
Iop::CIoman* m_iopIoman;
|
||||
Iop::CSysmem* m_iopSysmem;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user