From d75bac07a3fd6c9d0d3cce85de287c047c4fc9fd Mon Sep 17 00:00:00 2001 From: jpd002 Date: Fri, 9 Nov 2007 22:31:30 +0000 Subject: [PATCH] git-svn-id: http://svn.purei.org/purei/trunk@173 b36208d7-6611-0410-8bec-b1987f11c4a2 --- tools/PsfPlayer/Source/Iop_Ioman.cpp | 54 ++++++++++++++++++- tools/PsfPlayer/Source/Iop_Ioman.h | 2 + tools/PsfPlayer/Source/Iop_Sysmem.cpp | 60 +++++++++++++++++++-- tools/PsfPlayer/Source/Iop_Sysmem.h | 15 ++++-- tools/PsfPlayer/Source/PsfVm.cpp | 72 ++++++++------------------ tools/PsfPlayer/Source/PsfVm.h | 7 ++- tools/PsfPlayer/functions.bin | Bin 90 -> 125 bytes 7 files changed, 147 insertions(+), 63 deletions(-) diff --git a/tools/PsfPlayer/Source/Iop_Ioman.cpp b/tools/PsfPlayer/Source/Iop_Ioman.cpp index 6fb0b4c5..2d2ee88e 100644 --- a/tools/PsfPlayer/Source/Iop_Ioman.cpp +++ b/tools/PsfPlayer/Source/Iop_Ioman.cpp @@ -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(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(&m_ram[context.m_State.nGPR[CMIPS::A0].nV[0]]) )); break; + case 5: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(Close( + context.m_State.nGPR[CMIPS::A0].nV[0] + )); + break; + case 6: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(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(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; } } diff --git a/tools/PsfPlayer/Source/Iop_Ioman.h b/tools/PsfPlayer/Source/Iop_Ioman.h index 7431c8f3..55cdbddf 100644 --- a/tools/PsfPlayer/Source/Iop_Ioman.h +++ b/tools/PsfPlayer/Source/Iop_Ioman.h @@ -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: diff --git a/tools/PsfPlayer/Source/Iop_Sysmem.cpp b/tools/PsfPlayer/Source/Iop_Sysmem.cpp index 60fecbd6..c1e52de5 100644 --- a/tools/PsfPlayer/Source/Iop_Sysmem.cpp +++ b/tools/PsfPlayer/Source/Iop_Sysmem.cpp @@ -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(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); + } } diff --git a/tools/PsfPlayer/Source/Iop_Sysmem.h b/tools/PsfPlayer/Source/Iop_Sysmem.h index 7ffc60d0..71c56543 100644 --- a/tools/PsfPlayer/Source/Iop_Sysmem.h +++ b/tools/PsfPlayer/Source/Iop_Sysmem.h @@ -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 BlockMapType; + BlockMapType m_blockMap; + uint32 m_memoryBegin; + uint32 m_memoryEnd; + uint32 m_memorySize; }; } diff --git a/tools/PsfPlayer/Source/PsfVm.cpp b/tools/PsfPlayer/Source/PsfVm.cpp index 44b207e6..99415f8a 100644 --- a/tools/PsfPlayer/Source/PsfVm.cpp +++ b/tools/PsfPlayer/Source/PsfVm.cpp @@ -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(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; diff --git a/tools/PsfPlayer/Source/PsfVm.h b/tools/PsfPlayer/Source/PsfVm.h index 2aed55b1..213e0b0d 100644 --- a/tools/PsfPlayer/Source/PsfVm.h +++ b/tools/PsfPlayer/Source/PsfVm.h @@ -8,6 +8,7 @@ #include #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 IopModuleMapType; - typedef std::map 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 diff --git a/tools/PsfPlayer/functions.bin b/tools/PsfPlayer/functions.bin index 88ca2f3f49625d40f3a7d06618fcf9f37fc6eb8f..dbc5e5aa86f7655da3384e83b976d12f84beb4ba 100644 GIT binary patch delta 65 zcma#5Wn`bos3ur3oq>TTJ~KZzF)uzjC%-s#qPn8W8lWI=d~SY9PJUuaJczge7AY=C O$;^*0D9X$$Ndo|(nHC=a delta 29 kcmb=8Vq~4js5a3;QRu>S1_s{v;*yli{P=>R%)F8`0Di6sdH?_b