git-svn-id: http://svn.purei.org/purei/trunk@173 b36208d7-6611-0410-8bec-b1987f11c4a2

This commit is contained in:
jpd002 2007-11-09 22:31:30 +00:00
parent 4568411ef0
commit d75bac07a3
7 changed files with 147 additions and 63 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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