From 669ac71159b57092bab5caaaf1843b2dece9c5d8 Mon Sep 17 00:00:00 2001 From: jpd002 Date: Tue, 15 Jan 2008 20:27:44 +0000 Subject: [PATCH] Even more conversion done for quake.elf (SIF/IOP overhaul) git-svn-id: http://svn.purei.org/purei/trunk@224 b36208d7-6611-0410-8bec-b1987f11c4a2 --- Purei.vcproj | 344 +++++++-------- Source/COP_FPU.cpp | 37 +- Source/CodeGen.cpp | 32 +- Source/CodeGen.h | 11 +- Source/CodeGen_FPU.cpp | 7 +- Source/CodeGen_MD.cpp | 62 ++- Source/DMAC.cpp | 10 +- Source/GIF.cpp | 4 +- Source/GSH_OpenGL.cpp | 2 + Source/IOP_Cdvdfsv.cpp | 374 ---------------- Source/IOP_Cdvdfsv.h | 49 --- Source/IOP_DbcMan.cpp | 223 ---------- Source/IOP_DbcMan.h | 50 --- Source/IOP_Dummy.cpp | 29 -- Source/IOP_Dummy.h | 23 - Source/IOP_FileIO.cpp | 378 ---------------- Source/IOP_FileIO.h | 83 ---- Source/IOP_LibSD.cpp | 32 -- Source/IOP_LibSD.h | 26 -- Source/IOP_LoadFile.cpp | 77 ---- Source/IOP_LoadFile.h | 28 -- Source/IOP_McServ.cpp | 414 ------------------ Source/IOP_McServ.h | 109 ----- Source/IOP_Module.h | 19 - Source/IOP_PadMan.cpp | 224 ---------- Source/IOP_PadMan.h | 172 -------- Source/IOP_SysMem.cpp | 65 --- Source/IOP_SysMem.h | 28 -- Source/IOP_Unknown.cpp | 33 -- Source/IOP_Unknown.h | 22 - Source/MA_EE.cpp | 48 +-- Source/MA_MIPSIV.cpp | 20 +- Source/MA_MIPSIV.h | 2 +- Source/MA_MIPSIV_Templates.cpp | 34 +- Source/MipsCodeGen.cpp | 19 + Source/MipsCodeGen.h | 3 + Source/PS2OS.cpp | 6 +- Source/PS2VM.cpp | 70 +-- Source/PS2VM.h | 30 +- Source/Ps2Const.h | 37 ++ Source/SIF.cpp | 85 ++-- Source/SIF.h | 24 +- Source/SifModule.h | 11 + Source/X86Assembler.cpp | 5 + Source/X86Assembler.h | 2 + Source/X86Assembler_Sse.cpp | 7 + Source/iop/ArgumentIterator.cpp | 26 ++ Source/iop/ArgumentIterator.h | 18 + Source/iop/DirectoryDevice.cpp | 52 +++ Source/iop/DirectoryDevice.h | 18 + Source/iop/Ioman_Device.h | 27 ++ Source/iop/IopBios.cpp | 733 ++++++++++++++++++++++++++++++++ Source/iop/IopBios.h | 142 +++++++ Source/iop/Iop_Dynamic.cpp | 28 ++ Source/iop/Iop_Dynamic.h | 23 + Source/iop/Iop_Intc.cpp | 40 ++ Source/iop/Iop_Intc.h | 26 ++ Source/iop/Iop_Intrman.cpp | 91 ++++ Source/iop/Iop_Intrman.h | 27 ++ Source/iop/Iop_Ioman.cpp | 277 ++++++++++++ Source/iop/Iop_Ioman.h | 63 +++ Source/iop/Iop_Loadcore.cpp | 44 ++ Source/iop/Iop_Loadcore.h | 27 ++ Source/iop/Iop_Modload.cpp | 54 +++ Source/iop/Iop_Modload.h | 26 ++ Source/iop/Iop_Module.h | 21 + Source/iop/Iop_Stdio.cpp | 99 +++++ Source/iop/Iop_Stdio.h | 25 ++ Source/iop/Iop_Sysclib.cpp | 119 ++++++ Source/iop/Iop_Sysclib.h | 31 ++ Source/iop/Iop_Sysmem.cpp | 86 ++++ Source/iop/Iop_Sysmem.h | 33 ++ Source/iop/Iop_Thbase.cpp | 92 ++++ Source/iop/Iop_Thbase.h | 41 ++ Source/iop/Iop_Thevent.cpp | 39 ++ Source/iop/Iop_Thevent.h | 27 ++ Source/iop/Iop_Thsema.cpp | 62 +++ Source/iop/Iop_Thsema.h | 36 ++ Source/iop/Iop_Timrman.cpp | 34 ++ Source/iop/Iop_Timrman.h | 22 + Source/win32ui/Debugger.cpp | Bin 53050 -> 53100 bytes 81 files changed, 2994 insertions(+), 2885 deletions(-) delete mode 100644 Source/IOP_Cdvdfsv.cpp delete mode 100644 Source/IOP_Cdvdfsv.h delete mode 100644 Source/IOP_DbcMan.cpp delete mode 100644 Source/IOP_DbcMan.h delete mode 100644 Source/IOP_Dummy.cpp delete mode 100644 Source/IOP_Dummy.h delete mode 100644 Source/IOP_FileIO.cpp delete mode 100644 Source/IOP_FileIO.h delete mode 100644 Source/IOP_LibSD.cpp delete mode 100644 Source/IOP_LibSD.h delete mode 100644 Source/IOP_LoadFile.cpp delete mode 100644 Source/IOP_LoadFile.h delete mode 100644 Source/IOP_McServ.cpp delete mode 100644 Source/IOP_McServ.h delete mode 100644 Source/IOP_Module.h delete mode 100644 Source/IOP_PadMan.cpp delete mode 100644 Source/IOP_PadMan.h delete mode 100644 Source/IOP_SysMem.cpp delete mode 100644 Source/IOP_SysMem.h delete mode 100644 Source/IOP_Unknown.cpp delete mode 100644 Source/IOP_Unknown.h create mode 100644 Source/Ps2Const.h create mode 100644 Source/SifModule.h create mode 100644 Source/iop/ArgumentIterator.cpp create mode 100644 Source/iop/ArgumentIterator.h create mode 100644 Source/iop/DirectoryDevice.cpp create mode 100644 Source/iop/DirectoryDevice.h create mode 100644 Source/iop/Ioman_Device.h create mode 100644 Source/iop/IopBios.cpp create mode 100644 Source/iop/IopBios.h create mode 100644 Source/iop/Iop_Dynamic.cpp create mode 100644 Source/iop/Iop_Dynamic.h create mode 100644 Source/iop/Iop_Intc.cpp create mode 100644 Source/iop/Iop_Intc.h create mode 100644 Source/iop/Iop_Intrman.cpp create mode 100644 Source/iop/Iop_Intrman.h create mode 100644 Source/iop/Iop_Ioman.cpp create mode 100644 Source/iop/Iop_Ioman.h create mode 100644 Source/iop/Iop_Loadcore.cpp create mode 100644 Source/iop/Iop_Loadcore.h create mode 100644 Source/iop/Iop_Modload.cpp create mode 100644 Source/iop/Iop_Modload.h create mode 100644 Source/iop/Iop_Module.h create mode 100644 Source/iop/Iop_Stdio.cpp create mode 100644 Source/iop/Iop_Stdio.h create mode 100644 Source/iop/Iop_Sysclib.cpp create mode 100644 Source/iop/Iop_Sysclib.h create mode 100644 Source/iop/Iop_Sysmem.cpp create mode 100644 Source/iop/Iop_Sysmem.h create mode 100644 Source/iop/Iop_Thbase.cpp create mode 100644 Source/iop/Iop_Thbase.h create mode 100644 Source/iop/Iop_Thevent.cpp create mode 100644 Source/iop/Iop_Thevent.h create mode 100644 Source/iop/Iop_Thsema.cpp create mode 100644 Source/iop/Iop_Thsema.h create mode 100644 Source/iop/Iop_Timrman.cpp create mode 100644 Source/iop/Iop_Timrman.h diff --git a/Purei.vcproj b/Purei.vcproj index 7fd3f154..f924c42a 100644 --- a/Purei.vcproj +++ b/Purei.vcproj @@ -956,158 +956,6 @@ RelativePath=".\Source\INTC.cpp" > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1526,50 +1374,6 @@ RelativePath=".\Source\Integer64.h" > - - - - - - - - - - - - - - - - - - - - - - @@ -1698,6 +1502,10 @@ RelativePath=".\Source\Profiler.h" > + + @@ -1730,6 +1538,10 @@ RelativePath=".\Source\SIF.h" > + + @@ -1887,6 +1699,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + > 18) & 0x07]); - Branch(true); - } - CCodeGen::End(); + TestCCBit(m_nCCMask[(m_nOpcode >> 18) & 0x07]); + BranchEx(true); } //02 void CCOP_FPU::BC1FL() { - CCodeGen::Begin(m_pB); - { - TestCCBit(m_nCCMask[(m_nOpcode >> 18) & 0x07]); - BranchLikely(false); - } - CCodeGen::End(); + TestCCBit(m_nCCMask[(m_nOpcode >> 18) & 0x07]); + BranchLikelyEx(false); } //03 void CCOP_FPU::BC1TL() { - CCodeGen::Begin(m_pB); - { - TestCCBit(m_nCCMask[(m_nOpcode >> 18) & 0x07]); - BranchLikely(true); - } - CCodeGen::End(); + TestCCBit(m_nCCMask[(m_nOpcode >> 18) & 0x07]); + BranchLikelyEx(true); } ////////////////////////////////////////////////// @@ -383,15 +371,12 @@ void CCOP_FPU::C_LT_S() //36 void CCOP_FPU::C_LE_S() { - CCodeGen::Begin(m_pB); - { - CFPU::PushSingle(&m_pCtx->m_State.nCOP10[m_nFT * 2]); - CFPU::PushSingle(&m_pCtx->m_State.nCOP10[m_nFS * 2]); - CFPU::Cmp(CCodeGen::CONDITION_BE); + m_codeGen->FP_PushSingle(offsetof(CMIPS, m_State.nCOP10[m_nFT * 2])); + m_codeGen->FP_PushSingle(offsetof(CMIPS, m_State.nCOP10[m_nFS * 2])); - SetCCBit(true, m_nCCMask[((m_nOpcode >> 8) & 0x07)]); - } - CCodeGen::End(); + m_codeGen->FP_Cmp(CCodeGen::CONDITION_BE); + + SetCCBit(true, m_nCCMask[((m_nOpcode >> 8) & 0x07)]); } ////////////////////////////////////////////////// diff --git a/Source/CodeGen.cpp b/Source/CodeGen.cpp index a2380316..c447ed2f 100644 --- a/Source/CodeGen.cpp +++ b/Source/CodeGen.cpp @@ -2052,6 +2052,36 @@ void CCodeGen::Shl64(uint8 nAmount) } } +void CCodeGen::Sra() +{ + if(FitsPattern()) + { + RelativeRelative::PatternValue ops = GetPattern(); + unsigned int shiftAmount = AllocateRegister(REGISTER_SHIFTAMOUNT); + unsigned int resultRegister = AllocateRegister(); + LoadRelativeInRegister(resultRegister, ops.first); + LoadRelativeInRegister(shiftAmount, ops.second); + m_Assembler.SarEd(CX86Assembler::MakeRegisterAddress(m_nRegisterLookupEx[resultRegister])); + FreeRegister(shiftAmount); + PushReg(resultRegister); + } + else if(FitsPattern()) + { + ConstantRelative::PatternValue ops = GetPattern(); + unsigned int shiftAmount = AllocateRegister(REGISTER_SHIFTAMOUNT); + unsigned int resultRegister = AllocateRegister(); + LoadConstantInRegister(resultRegister, ops.first); + LoadRelativeInRegister(shiftAmount, ops.second); + m_Assembler.SarEd(CX86Assembler::MakeRegisterAddress(m_nRegisterLookupEx[resultRegister])); + FreeRegister(shiftAmount); + PushReg(resultRegister); + } + else + { + assert(0); + } +} + void CCodeGen::Sra(uint8 nAmount) { if(FitsPattern()) @@ -2062,7 +2092,7 @@ void CCodeGen::Sra(uint8 nAmount) } else if(FitsPattern()) { - UnaryRelativeSelfCallAsRegister(bind(&CCodeGen::Sra, nAmount)); + UnaryRelativeSelfCallAsRegister(bind(&CCodeGen::Sra, this, nAmount)); } else { diff --git a/Source/CodeGen.h b/Source/CodeGen.h index 45e0e012..2acad57e 100644 --- a/Source/CodeGen.h +++ b/Source/CodeGen.h @@ -119,8 +119,9 @@ public: void Shl(uint8); static void Shl64(); void Shl64(uint8); - static void Sra(uint8); - static void Sra64(uint8); + void Sra(); + void Sra(uint8); + void Sra64(uint8); void Srl(); void Srl(uint8); static void Srl64(); @@ -145,14 +146,16 @@ public: void FP_Neg(); //SIMD (128-bits only) - void MD_PushRel(size_t); - void MD_PullRel(size_t); + virtual void MD_PushRel(size_t); + virtual void MD_PullRel(size_t); void MD_PushReg(XMMREGISTER); void MD_And(); void MD_Not(); void MD_Or(); void MD_SubB(); + void MD_SubW(); + void MD_Xor(); void SetStream(Framework::CStream*); static CX86Assembler m_Assembler; diff --git a/Source/CodeGen_FPU.cpp b/Source/CodeGen_FPU.cpp index 8fe8a857..99bd3d05 100644 --- a/Source/CodeGen_FPU.cpp +++ b/Source/CodeGen_FPU.cpp @@ -368,15 +368,18 @@ void CCodeGen::FP_Cmp(CCodeGen::CONDITION condition) case CONDITION_BL: conditionCode = CX86Assembler::SSE_CMP_LT; break; + case CONDITION_BE: + conditionCode = CX86Assembler::SSE_CMP_LE; + break; default: assert(0); break; } XMMREGISTER tempResultRegister = AllocateXmmRegister(); unsigned int resultRegister = AllocateRegister(); - FP_LoadSingleRelativeInRegister(tempResultRegister, ops.first); + FP_LoadSingleRelativeInRegister(tempResultRegister, ops.second); m_Assembler.CmpssEd(tempResultRegister, - CX86Assembler::MakeIndRegOffAddress(g_nBaseRegister, ops.second), + CX86Assembler::MakeIndRegOffAddress(g_nBaseRegister, ops.first), conditionCode); //Can't move directly to register using MOVSS, so we use CVTTSS2SI //0x00000000 -- CVT -> zero diff --git a/Source/CodeGen_MD.cpp b/Source/CodeGen_MD.cpp index 8338f041..e1253053 100644 --- a/Source/CodeGen_MD.cpp +++ b/Source/CodeGen_MD.cpp @@ -2,20 +2,20 @@ #include "CodeGen.h" #include "CodeGen_StackPatterns.h" -bool CCodeGen::Register128HasNextUse(XMMREGISTER registerId) -{ - unsigned int nCount = m_Shadow.GetCount(); - - for(unsigned int i = 0; i < nCount; i += 2) - { - if(m_Shadow.GetAt(i) == REGISTER128) - { - if(m_Shadow.GetAt(i + 1) == registerId) return true; - } - } - - return false; -} +bool CCodeGen::Register128HasNextUse(XMMREGISTER registerId) +{ + unsigned int nCount = m_Shadow.GetCount(); + + for(unsigned int i = 0; i < nCount; i += 2) + { + if(m_Shadow.GetAt(i) == REGISTER128) + { + if(m_Shadow.GetAt(i + 1) == registerId) return true; + } + } + + return false; +} void CCodeGen::LoadRelative128InRegister(XMMREGISTER registerId, uint32 offset) { @@ -119,3 +119,37 @@ void CCodeGen::MD_SubB() assert(0); } } + +void CCodeGen::MD_SubW() +{ + if(FitsPattern()) + { + RelativeRelative128::PatternValue ops(GetPattern()); + XMMREGISTER resultRegister = AllocateXmmRegister(); + LoadRelative128InRegister(resultRegister, ops.first); + m_Assembler.PsubdVo(resultRegister, + CX86Assembler::MakeIndRegOffAddress(g_nBaseRegister, ops.second)); + MD_PushReg(resultRegister); + } + else + { + assert(0); + } +} + +void CCodeGen::MD_Xor() +{ + if(FitsPattern()) + { + RelativeRelative128::PatternValue ops(GetPattern()); + XMMREGISTER resultRegister = AllocateXmmRegister(); + LoadRelative128InRegister(resultRegister, ops.first); + m_Assembler.PxorVo(resultRegister, + CX86Assembler::MakeIndRegOffAddress(g_nBaseRegister, ops.second)); + MD_PushReg(resultRegister); + } + else + { + assert(0); + } +} diff --git a/Source/DMAC.cpp b/Source/DMAC.cpp index f415375f..1b9056a3 100644 --- a/Source/DMAC.cpp +++ b/Source/DMAC.cpp @@ -1,9 +1,9 @@ #include -#include "PS2VM.h" #include "DMAC.h" #include "INTC.h" #include "GIF.h" #include "SIF.h" +#include "Ps2Const.h" #include "Profiler.h" #include "Log.h" #include "RegisterStateFile.h" @@ -143,11 +143,11 @@ uint32 CDMAC::ResumeDMA3(void* pBuffer, uint32 nSize) if(m_D3_MADR & 0x80000000) { - pDst = m_spr + (m_D3_MADR & (CPS2VM::SPRSIZE - 1)); + pDst = m_spr + (m_D3_MADR & (PS2::SPRSIZE - 1)); } else { - pDst = m_ram + (m_D3_MADR & (CPS2VM::RAMSIZE - 1)); + pDst = m_ram + (m_D3_MADR & (PS2::EERAMSIZE - 1)); } memcpy(pDst, pBuffer, nSize * 0x10); @@ -212,8 +212,8 @@ uint32 CDMAC::ReceiveSPRDMA(uint32 nSrcAddress, uint32 nCount, bool nTagIncluded assert(nTagIncluded == false); nDstAddress = m_D9_SADR; - nDstAddress &= (CPS2VM::SPRSIZE - 1); - nSrcAddress &= (CPS2VM::RAMSIZE - 1); + nDstAddress &= (PS2::SPRSIZE - 1); + nSrcAddress &= (PS2::EERAMSIZE - 1); memcpy(m_spr + nDstAddress, m_ram + nSrcAddress, nCount * 0x10); diff --git a/Source/GIF.cpp b/Source/GIF.cpp index b9c2ece6..04ad73c9 100644 --- a/Source/GIF.cpp +++ b/Source/GIF.cpp @@ -2,7 +2,7 @@ #include #include "GIF.h" #include "uint128.h" -#include "PS2VM.h" +#include "Ps2Const.h" #include "Profiler.h" #include "Log.h" @@ -283,7 +283,7 @@ uint32 CGIF::ReceiveDMA(uint32 nAddress, uint32 nQWC, uint32 unused, bool nTagIn if(nAddress & 0x80000000) { pMemory = m_spr; - nAddress &= CPS2VM::SPRSIZE - 1; + nAddress &= PS2::SPRSIZE - 1; } else { diff --git a/Source/GSH_OpenGL.cpp b/Source/GSH_OpenGL.cpp index 083d6caa..48ae0829 100644 --- a/Source/GSH_OpenGL.cpp +++ b/Source/GSH_OpenGL.cpp @@ -1155,6 +1155,8 @@ void CGSH_OpenGL::DisplayTransferedImage(uint32 nAddress) glBindTexture(GL_TEXTURE_2D, NULL); glDeleteTextures(1, &nTexture); + + FlipImpl(); } void CGSH_OpenGL::SetVBlank() diff --git a/Source/IOP_Cdvdfsv.cpp b/Source/IOP_Cdvdfsv.cpp deleted file mode 100644 index 138b242e..00000000 --- a/Source/IOP_Cdvdfsv.cpp +++ /dev/null @@ -1,374 +0,0 @@ -#include -#include -#include "IOP_Cdvdfsv.h" -#include "PS2VM.h" - -using namespace IOP; -using namespace Framework; - -uint32 CCdvdfsv::m_nStreamPos = 0; - -CCdvdfsv::CCdvdfsv(uint32 nID) -{ - m_nID = nID; -} - -CCdvdfsv::~CCdvdfsv() -{ - -} - -void CCdvdfsv::Invoke(uint32 nMethod, void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - switch(m_nID) - { - case MODULE_ID_1: - Invoke592(nMethod, pArgs, nArgsSize, pRet, nRetSize); - break; - case MODULE_ID_2: - Invoke593(nMethod, pArgs, nArgsSize, pRet, nRetSize); - break; - case MODULE_ID_4: - Invoke595(nMethod, pArgs, nArgsSize, pRet, nRetSize); - break; - case MODULE_ID_6: - Invoke597(nMethod, pArgs, nArgsSize, pRet, nRetSize); - break; - case MODULE_ID_7: - Invoke59C(nMethod, pArgs, nArgsSize, pRet, nRetSize); - break; - } -} - -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 nMethod, void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - switch(nMethod) - { - case 0: - //Init - uint32 nMode; - - assert(nArgsSize >= 4); - assert(nRetSize >= 0x10); - - nMode = ((uint32*)pArgs)[0x00]; - - Log("Init(mode = %i);\r\n", nMode); - - ((uint32*)pRet)[0x03] = 0xFF; - - break; - default: - Log("Unknown method invoked (0x%0.8X, 0x%0.8X).\r\n", m_nID, nMethod); - break; - } -} - -void CCdvdfsv::Invoke593(uint32 nMethod, void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - switch(nMethod) - { - case 0x03: - - assert(nRetSize >= 4); - - Log("GetDiskType();\r\n"); - - //Returns PS2DVD for now. - ((uint32*)pRet)[0x00] = 0x14; - - break; - - case 0x04: - assert(nRetSize >= 4); - - Log("GetError();\r\n"); - - ((uint32*)pRet)[0x00] = 0x00; - break; - - case 0x0C: - //Status - //Returns - //0 - Stopped - //1 - Open - //2 - Spin - //3 - Read - //and more... - - assert(nRetSize >= 4); - - Log("Status();\r\n"); - - ((uint32*)pRet)[0x00] = 0; - - break; - case 0x22: - //Set Media Mode (1 - CDROM, 2 - DVDROM) - uint32 nMode; - - assert(nArgsSize >= 4); - assert(nRetSize >= 4); - - nMode = ((uint32*)pArgs)[0x00]; - - Log("SetMediaMode(mode = %i);\r\n", nMode); - - ((uint32*)pRet)[0x00] = 1; - - break; - default: - Log("Unknown method invoked (0x%0.8X, 0x%0.8X).\r\n", m_nID, nMethod); - break; - } -} - -void CCdvdfsv::Invoke595(uint32 nMethod, void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - switch(nMethod) - { - case 1: - Read(pArgs, nArgsSize, pRet, nRetSize); - break; - case 4: - //GetToc - uint32 nBuffer; - - assert(nArgsSize >= 4); - assert(nRetSize >= 4); - - nBuffer = ((uint32*)pArgs)[0x00]; - - Log("GetToc(buffer = 0x%0.8X);\r\n", nBuffer); - - ((uint32*)pRet)[0x00] = 1; - break; - case 9: - StreamCmd(pArgs, nArgsSize, pRet, nRetSize); - break; - case 0x0E: - //DiskReady (returns 2 if ready, 6 if not ready) - - assert(nRetSize >= 4); - - Log("NDiskReady();\r\n"); - - ((uint32*)pRet)[0x00] = 2; - break; - default: - Log("Unknown method invoked (0x%0.8X, 0x%0.8X).\r\n", m_nID, nMethod); - break; - } -} - -void CCdvdfsv::Invoke597(uint32 nMethod, void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - switch(nMethod) - { - case 0: - SearchFile(pArgs, nArgsSize, pRet, nRetSize); - break; - default: - Log("Unknown method invoked (0x%0.8X, 0x%0.8X).\r\n", m_nID, nMethod); - break; - } -} - -void CCdvdfsv::Invoke59C(uint32 nMethod, void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - switch(nMethod) - { - case 0: - //DiskReady (returns 2 if ready, 6 if not ready) - - uint32 nMode; - - assert(nRetSize >= 4); - assert(nArgsSize >= 4); - - nMode = ((uint32*)pArgs)[0x00]; - - Log("DiskReady(mode = %i);\r\n", nMode); - - ((uint32*)pRet)[0x00] = 2; - break; - default: - Log("Unknown method invoked (0x%0.8X, 0x%0.8X).\r\n", m_nID, nMethod); - break; - } -} - -void CCdvdfsv::Read(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - uint32 nSector, nCount, nDstAddr, nMode; - unsigned int i; - - nSector = ((uint32*)pArgs)[0x00]; - nCount = ((uint32*)pArgs)[0x01]; - nDstAddr = ((uint32*)pArgs)[0x02]; - nMode = ((uint32*)pArgs)[0x04]; - - Log("Read(sector = 0x%0.8X, count = 0x%0.8X, addr = 0x%0.8X, mode = 0x%0.8X);\r\n", \ - nSector, - nCount, - nDstAddr, - nMode); - - for(i = 0; i < nCount; i++) - { - CPS2VM::m_pCDROM0->ReadBlock(nSector + i, CPS2VM::m_pRAM + (nDstAddr + (i * 0x800))); - } - - if(nRetSize >= 4) - { - ((uint32*)pRet)[0] = 0; - } -} - -void CCdvdfsv::StreamCmd(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - uint32 nSector, nCount, nDstAddr, nCmd, nMode, i; - - nSector = ((uint32*)pArgs)[0x00]; - nCount = ((uint32*)pArgs)[0x01]; - nDstAddr = ((uint32*)pArgs)[0x02]; - nCmd = ((uint32*)pArgs)[0x03]; - nMode = ((uint32*)pArgs)[0x04]; - - Log("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; - ((uint32*)pRet)[0] = 1; - - Log("StreamStart(pos = 0x%0.8X);\r\n", \ - nSector); - break; - case 2: - //Read - nDstAddr &= (CPS2VM::RAMSIZE - 1); - - for(i = 0; i < nCount; i++) - { - CPS2VM::m_pCDROM0->ReadBlock(m_nStreamPos, CPS2VM::m_pRAM + (nDstAddr + (i * 0x800))); - m_nStreamPos++; - } - - ((uint32*)pRet)[0] = nCount; - - Log("StreamRead(count = 0x%0.8X, dest = 0x%0.8X);\r\n", \ - nCount, \ - nDstAddr); - break; - case 5: - //Init - ((uint32*)pRet)[0] = 1; - - Log("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; - ((uint32*)pRet)[0] = 1; - - Log("StreamSeek(pos = 0x%0.8X);\r\n", \ - nSector); - break; - } -} - -void CCdvdfsv::SearchFile(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - char* sPath; - char* sTemp; - char sFixedPath[256]; - CISO9660* pISO; - ISO9660::CDirectoryRecord Record; - - assert(nArgsSize >= 0x128); - assert(nRetSize == 4); - - pISO = CPS2VM::m_pCDROM0; - if(pISO == NULL) - { - *(uint32*)pRet = 0; - return; - } - - //0x12C structure - //00 - Block Num - //04 - Size - //08 - //0C - //10 - //14 - //18 - //1C - //20 - Unknown - //24 - Path - - sPath = (char*)pArgs + 0x24; - - strcpy(sFixedPath, sPath); - - //Fix all slashes - sTemp = strchr(sFixedPath, '\\'); - while(sTemp != NULL) - { - *sTemp = '/'; - sTemp = strchr(sTemp + 1, '\\'); - } - - Log("SearchFile(path = %s);\r\n", sFixedPath); - - if(!pISO->GetFileRecord(&Record, sFixedPath)) - { - *(uint32*)pRet = 0; - return; - } - - ((uint32*)pArgs)[0x00] = Record.GetPosition(); - ((uint32*)pArgs)[0x01] = Record.GetDataLength(); - - *(uint32*)pRet = 1; -} - -void CCdvdfsv::Log(const char* sFormat, ...) -{ -#ifdef _DEBUG - - if(!CPS2VM::m_Logging.GetIOPLoggingStatus()) return; - - va_list Args; - printf("IOP_Cdvdfsv: "); - va_start(Args, sFormat); - vprintf(sFormat, Args); - va_end(Args); - -#endif -} diff --git a/Source/IOP_Cdvdfsv.h b/Source/IOP_Cdvdfsv.h deleted file mode 100644 index 2a982973..00000000 --- a/Source/IOP_Cdvdfsv.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _IOP_CDVDFSV_H_ -#define _IOP_CDVDFSV_H_ - -#include "IOP_Module.h" - -namespace IOP -{ - - class CCdvdfsv : public CModule - { - public: - CCdvdfsv(uint32); - virtual ~CCdvdfsv(); - virtual void Invoke(uint32, void*, uint32, void*, uint32); - virtual void SaveState(Framework::CStream*); - virtual void LoadState(Framework::CStream*); - - enum MODULE_ID - { - MODULE_ID_1 = 0x80000592, - MODULE_ID_2 = 0x80000593, - MODULE_ID_3 = 0x80000594, - MODULE_ID_4 = 0x80000595, - MODULE_ID_5 = 0x80000596, - MODULE_ID_6 = 0x80000597, - MODULE_ID_7 = 0x8000059C, - }; - - private: - void Invoke592(uint32, void*, uint32, void*, uint32); - void Invoke593(uint32, void*, uint32, void*, uint32); - void Invoke595(uint32, void*, uint32, void*, uint32); - void Invoke597(uint32, void*, uint32, void*, uint32); - void Invoke59C(uint32, void*, uint32, void*, uint32); - - //Methods - void Read(void*, uint32, void*, uint32); - void StreamCmd(void*, uint32, void*, uint32); - void SearchFile(void*, uint32, void*, uint32); - - static void Log(const char*, ...); - - uint32 m_nID; - static uint32 m_nStreamPos; - }; - -} - -#endif diff --git a/Source/IOP_DbcMan.cpp b/Source/IOP_DbcMan.cpp deleted file mode 100644 index b27c2c6a..00000000 --- a/Source/IOP_DbcMan.cpp +++ /dev/null @@ -1,223 +0,0 @@ -#include -#include -#include "IOP_DbcMan.h" -#include "PS2VM.h" - -using namespace IOP; -using namespace Framework; - -CDbcMan::CDbcMan() -{ - -} - -CDbcMan::~CDbcMan() -{ - DeleteAllSockets(); -} - -void CDbcMan::Invoke(uint32 nMethod, void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - switch(nMethod) - { - case 0x80000901: - CreateSocket(pArgs, nArgsSize, pRet, nRetSize); - break; - case 0x80000904: - SetWorkAddr(pArgs, nArgsSize, pRet, nRetSize); - break; - case 0x8000091A: - ReceiveData(pArgs, nArgsSize, pRet, nRetSize); - break; - case 0x80000963: - GetVersionInformation(pArgs, nArgsSize, pRet, nRetSize); - break; - } -} - -void CDbcMan::SaveState(CStream* pStream) -{ - uint32 nCount, nID; - SOCKET* pSocket; - CList::ITERATOR itSocket; - - nCount = m_Socket.Count(); - pStream->Write(&nCount, 4); - - for(itSocket = m_Socket.Begin(); itSocket.HasNext(); itSocket++) - { - nID = itSocket.GetKey(); - pSocket = (*itSocket); - - pStream->Write(&nID, 4); - pStream->Write(pSocket, sizeof(SOCKET)); - } -} - -void CDbcMan::LoadState(CStream* pStream) -{ - uint32 nCount, nID, i; - SOCKET* pSocket; - - DeleteAllSockets(); - - pStream->Read(&nCount, 4); - - for(i = 0; i < nCount; i++) - { - pSocket = new SOCKET; - - pStream->Read(&nID, 4); - pStream->Read(pSocket, sizeof(SOCKET)); - - m_Socket.Insert(pSocket, nID); - } -} - -void CDbcMan::SetButtonState(unsigned int nPadNumber, CPadListener::BUTTON nButton, bool nPressed) -{ - SOCKET* pSocket; - CList::ITERATOR itSocket; - uint16 nStatus; - - for(itSocket = m_Socket.Begin(); itSocket.HasNext(); itSocket++) - { - pSocket = (*itSocket); - if(pSocket->nPort != nPadNumber) continue; - - nStatus = (CPS2VM::m_pRAM[pSocket->nBuf1 + 0x1C] << 8) | (CPS2VM::m_pRAM[pSocket->nBuf1 + 0x1D]); - - nStatus &= (~nButton); - if(!nPressed) - { - nStatus |= nButton; - } - - CPS2VM::m_pRAM[pSocket->nBuf1 + 0x1C] = (uint8)(nStatus >> 8); - CPS2VM::m_pRAM[pSocket->nBuf1 + 0x1D] = (uint8)(nStatus >> 0); - -// *(uint16*)&CPS2VM::m_pRAM[pSocket->nBuf1 + 0x1C] ^= 0x2010; - } -} - -void CDbcMan::CreateSocket(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - uint32 nType1, nType2, nPort, nSlot, nBuf1, nBuf2, nID; - SOCKET* pSocket; - - assert(nArgsSize >= 0x30); - assert(nRetSize >= 0x04); - - nType1 = ((uint32*)pArgs)[0x00]; - nType2 = ((uint32*)pArgs)[0x01]; - nPort = ((uint32*)pArgs)[0x02]; - nSlot = ((uint32*)pArgs)[0x03]; - nBuf1 = ((uint32*)pArgs)[0x0A]; - nBuf2 = ((uint32*)pArgs)[0x0B]; - - pSocket = new SOCKET; - pSocket->nPort = nPort; - pSocket->nSlot = nSlot; - pSocket->nBuf1 = nBuf1; - pSocket->nBuf2 = nBuf2; - - nID = m_Socket.MakeKey(); - m_Socket.Insert(pSocket, nID); - - ((uint32*)pRet)[0x09] = nID; - - Log("CreateSocket(type1 = 0x%0.8X, type2 = 0x%0.8X, port = %i, slot = %i, buf1 = 0x%0.8X, buf2 = 0x%0.8X);\r\n", \ - nType1, \ - nType2, \ - nPort, \ - nSlot, \ - nBuf1, \ - nBuf2); -} - -void CDbcMan::SetWorkAddr(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - uint32 nAddress; - - assert(nArgsSize == 0x400); - assert(nRetSize == 0x400); - - //0 - Some number (0x0200) (size?) - //1 - Address to bind with - - nAddress = ((uint32*)pArgs)[1]; - - //Set Ready (?) status - CPS2VM::m_pRAM[nAddress] = 1; - - ((uint32*)pRet)[0] = 0x00000000; - - Log("SetWorkAddr(addr = 0x%0.8X);\r\n", nAddress); -} - -void CDbcMan::ReceiveData(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - uint32 nParam, nFlags, nSocket; - SOCKET* pSocket; - - //Param Frame - //0 - Socket ID - //1 - Value passed in parameter to the library - //2 - Some parameter (0x01, or some address) - - nSocket = ((uint32*)pArgs)[0]; - nFlags = ((uint32*)pArgs)[1]; - nParam = ((uint32*)pArgs)[2]; - - pSocket = m_Socket.Find(nSocket); - if(pSocket != NULL) - { - CPS2VM::m_pRAM[pSocket->nBuf1 + 0x02] = 0x20; - *(uint32*)&CPS2VM::m_pRAM[pSocket->nBuf1 + 0x04] = 0x01; - } - - //Return frame - //0 - Success Status - //1 - ??? - //2 - Size of returned data - //3+ - Data - - ((uint32*)pRet)[0] = 0; - ((uint32*)pRet)[2] = 0x1; - ((uint32*)pRet)[3] = 0x1; - - Log("ReceiveData(socket = 0x%0.8X, flags = 0x%0.8X, param = 0x%0.8X);\r\n", nSocket, nFlags, nParam); -} - -void CDbcMan::GetVersionInformation(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - assert(nArgsSize == 0x400); - assert(nRetSize == 0x400); - - ((uint32*)pRet)[0] = 0x00000200; - - Log("GetVersionInformation();\r\n"); -} - -void CDbcMan::DeleteAllSockets() -{ - while(m_Socket.Count() != 0) - { - delete m_Socket.Pull(); - } -} - -void CDbcMan::Log(const char* sFormat, ...) -{ -#ifdef _DEBUG - - if(!CPS2VM::m_Logging.GetIOPLoggingStatus()) return; - - va_list Args; - printf("IOP_DbcMan: "); - va_start(Args, sFormat); - vprintf(sFormat, Args); - va_end(Args); - -#endif -} diff --git a/Source/IOP_DbcMan.h b/Source/IOP_DbcMan.h deleted file mode 100644 index e5fe0a5d..00000000 --- a/Source/IOP_DbcMan.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _IOP_DBCMAN_H_ -#define _IOP_DBCMAN_H_ - -#include "IOP_Module.h" -#include "PadListener.h" -#include "List.h" - -namespace IOP -{ - - class CDbcMan : public CModule, public CPadListener - { - public: - CDbcMan(); - virtual ~CDbcMan(); - virtual void Invoke(uint32, void*, uint32, void*, uint32); - virtual void SaveState(Framework::CStream*); - virtual void LoadState(Framework::CStream*); - virtual void SetButtonState(unsigned int, CPadListener::BUTTON, bool); - - enum MODULE_ID - { - MODULE_ID = 0x80000900 - }; - - private: - struct SOCKET - { - uint32 nPort; - uint32 nSlot; - uint32 nBuf1; - uint32 nBuf2; - }; - - void CreateSocket(void*, uint32, void*, uint32); - void SetWorkAddr(void*, uint32, void*, uint32); - void ReceiveData(void*, uint32, void*, uint32); - void GetVersionInformation(void*, uint32, void*, uint32); - - void DeleteAllSockets(); - - void Log(const char*, ...); - - Framework::CList m_Socket; - }; - -} - -#endif - diff --git a/Source/IOP_Dummy.cpp b/Source/IOP_Dummy.cpp deleted file mode 100644 index 69b48106..00000000 --- a/Source/IOP_Dummy.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include "IOP_Dummy.h" - -using namespace IOP; -using namespace Framework; - -void CDummy::Invoke(uint32 nMethod, void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - switch(nMethod) - { - case 1: - case 2: - assert(nRetSize >= 4); - - ((uint32*)pRet)[0] = 1; - - break; - } -} - -void CDummy::LoadState(CStream* pStream) -{ - -} - -void CDummy::SaveState(CStream* pStream) -{ - -} diff --git a/Source/IOP_Dummy.h b/Source/IOP_Dummy.h deleted file mode 100644 index 65d15180..00000000 --- a/Source/IOP_Dummy.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _IOP_DUMMY_H_ -#define _IOP_DUMMY_H_ - -#include "IOP_Module.h" - -namespace IOP -{ - class CDummy : public CModule - { - public: - virtual void Invoke(uint32, void*, uint32, void*, uint32); - virtual void LoadState(Framework::CStream*); - virtual void SaveState(Framework::CStream*); - - enum MODULE_ID - { - MODULE_ID = 0x00000030, - }; - - }; -}; - -#endif diff --git a/Source/IOP_FileIO.cpp b/Source/IOP_FileIO.cpp deleted file mode 100644 index 0b3618e5..00000000 --- a/Source/IOP_FileIO.cpp +++ /dev/null @@ -1,378 +0,0 @@ -#include -#include -#include "IOP_FileIO.h" -#include "PS2VM.h" -#include "Config.h" -#include "StdStream.h" - -using namespace IOP; -using namespace Framework; - -CFileIO::CFileIO() -{ - CConfig::GetInstance()->RegisterPreferenceBoolean("iop.fileio.stdlogging", false); - CConfig::GetInstance()->RegisterPreferenceString("ps2.host.directory", "./vfs/host"); - CConfig::GetInstance()->RegisterPreferenceString("ps2.mc0.directory", "./vfs/mc0"); - CConfig::GetInstance()->RegisterPreferenceString("ps2.mc1.directory", "./vfs/mc1"); - - m_Device.Insert(new CDirectoryDevice("mc0", "ps2.mc0.directory")); - m_Device.Insert(new CDirectoryDevice("host", "ps2.host.directory")); - m_Device.Insert(new CCDROM0Device()); - - //Insert standard files if requested. - if(CConfig::GetInstance()->GetPreferenceBoolean("iop.fileio.stdlogging")) - { - try - { - m_File.Insert(new CStdStream(fopen("ps2_stdout.txt", "ab")), 1); - m_File.Insert(new CStdStream(fopen("ps2_stderr.txt", "ab")), 2); - } - catch(...) - { - //Humm, some error occured when opening these files... - } - } - - m_nFileID = 3; -} - -CFileIO::~CFileIO() -{ - while(m_File.Count() != 0) - { - delete m_File.Pull(); - } - while(m_Device.Count() != 0) - { - delete m_Device.Pull(); - } -} - -void CFileIO::Invoke(uint32 nMethod, void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - switch(nMethod) - { - case 0x00000000: - assert(nRetSize == 4); - *(uint32*)pRet = Open(*(uint32*)pArgs, ((char*)pArgs) + 4); - break; - case 0x00000001: - assert(nRetSize == 4); - *(uint32*)pRet = Close(*(uint32*)pArgs); - break; - case 0x00000002: - assert(nRetSize == 4); - *(uint32*)pRet = Read(((uint32*)pArgs)[0], ((uint32*)pArgs)[2], (void*)(CPS2VM::m_pRAM + ((uint32*)pArgs)[1])); - break; - case 0x00000003: - assert(nRetSize == 4); - *(uint32*)pRet = Write(((uint32*)pArgs)[0], ((uint32*)pArgs)[2], (void*)(CPS2VM::m_pRAM + ((uint32*)pArgs)[1])); - break; - case 0x00000004: - assert(nRetSize == 4); - *(uint32*)pRet = Seek(((uint32*)pArgs)[0], ((uint32*)pArgs)[1], ((uint32*)pArgs)[2]); - break; - default: - assert(0); - break; - } -} - -void CFileIO::SaveState(CStream* pStream) -{ - -} - -void CFileIO::LoadState(CStream* pStream) -{ - -} - -CStream* CFileIO::GetFile(uint32 nMode, const char* sPath) -{ - char sDevice[256]; - char sDevicePath[256]; - CDevice* pDevice; - - if(!SplitPath(sPath, sDevice, sDevicePath)) - { - return NULL; - } - - pDevice = FindDevice(sDevice); - if(pDevice == NULL) - { - return NULL; - } - - return pDevice->OpenFile(nMode, sDevicePath); -} - -bool CFileIO::SplitPath(const char* sPath, char* sDevice, char* sDevicePath) -{ - const char* sSplit; - unsigned int nLenght; - unsigned int nDevLenght; - unsigned int nDevPathLenght; - - nLenght = (unsigned int)strlen(sPath); - sSplit = strchr(sPath, ':'); - if(sSplit == NULL) - { - //Invalid path - return false; - } - - nDevLenght = (unsigned int)(sSplit - sPath); - nDevPathLenght = (unsigned int)(nLenght - (sSplit - sPath) - 1); - - strncpy(sDevice, sPath, nDevLenght); - strncpy(sDevicePath, sSplit + 1, nDevPathLenght); - - sDevice[nDevLenght] = '\0'; - sDevicePath[nDevPathLenght] = '\0'; - - return true; -} - -CFileIO::CDevice* CFileIO::FindDevice(const char* sDeviceName) -{ - CList::ITERATOR itDevice; - CDevice* pDevice; - - for(itDevice = m_Device.Begin(); itDevice.HasNext(); itDevice++) - { - pDevice = (*itDevice); - if(!strcmp(pDevice->GetName(), sDeviceName)) - { - return pDevice; - } - } - - return NULL; -} - -uint32 CFileIO::RegisterFile(CStream* pFile) -{ - uint32 nFD; - nFD = m_nFileID; - m_File.Insert(pFile, nFD); - m_nFileID++; - return nFD; -} - -uint32 CFileIO::Open(uint32 nMode, const char* sPath) -{ -/* - char sDevice[256]; - char sDevicePath[256]; - CDevice* pDevice; -*/ - CStream* pFile; - - Log("Attempting to open file '%s'.\r\n", sPath); - - pFile = GetFile(nMode, sPath); - if(pFile == NULL) - { - return 0xFFFFFFFF; - } - - return RegisterFile(pFile); -/* - if(!SplitPath(sPath, sDevice, sDevicePath)) - { - return 0xFFFFFFFF; - } - - pDevice = FindDevice(sDevice); - if(pDevice == NULL) - { - return 0xFFFFFFFF; - } - - pFile = pDevice->OpenFile(nMode, sDevicePath); - if(pFile == NULL) - { - return 0xFFFFFFFF; - } -*/ -} - -uint32 CFileIO::Close(uint32 nFile) -{ - CStream* pFile; - - pFile = m_File.Remove(nFile); - if(pFile == NULL) - { - return 0xFFFFFFFF; - } - - delete pFile; - - return 0; -} - -uint32 CFileIO::Read(uint32 nFile, uint32 nSize, void* pBuffer) -{ - CStream* pFile; - - pFile = m_File.Find(nFile); - if(pFile == NULL) - { - Log("Reading from an unopened file (fd = %i).\r\n", nFile); - return 0xFFFFFFFF; - } - - if(pFile->IsEOF()) - { - return 0; - } - - return (uint32)pFile->Read(pBuffer, nSize); -} - -uint32 CFileIO::Write(uint32 nFile, uint32 nSize, void* pBuffer) -{ - CStream* pFile; - uint32 nAmount; - - pFile = m_File.Find(nFile); - if(pFile == NULL) - { - if(nFile > 2) - { - Log("Writing to an unopened file (fd = %i).\r\n", nFile); - } - return 0xFFFFFFFF; - } - - nAmount = (uint32)pFile->Write(pBuffer, nSize); - pFile->Flush(); - return nAmount; -} - -uint32 CFileIO::Seek(uint32 nFile, uint32 nOffset, uint32 nWhence) -{ - CStream* pFile; - STREAM_SEEK_DIRECTION nPosition; - - pFile = m_File.Find(nFile); - if(pFile == NULL) - { - Log("Seeking in an unopened file (fd = %i).\r\n", nFile); - return 0xFFFFFFFF; - } - - switch(nWhence) - { - case 0: - nPosition = Framework::STREAM_SEEK_SET; - break; - case 1: - nPosition = Framework::STREAM_SEEK_CUR; - break; - case 2: - nPosition = Framework::STREAM_SEEK_END; - break; - } - - pFile->Seek(nOffset, nPosition); - return (uint32)pFile->Tell(); -} - -void CFileIO::Log(const char* sFormat, ...) -{ -#ifdef _DEBUG - - if(!CPS2VM::m_Logging.GetIOPLoggingStatus()) return; - - va_list Args; - printf("IOP_FileIO: "); - va_start(Args, sFormat); - vprintf(sFormat, Args); - va_end(Args); - -#endif -} - -///////////////////////////////////////////// -//Devices Implementation -///////////////////////////////////////////// - -CFileIO::CDevice::CDevice(const char* sName) -{ - m_sName = sName; -} - -const char* CFileIO::CDevice::GetName() -{ - return m_sName; -} - -CFileIO::CDirectoryDevice::CDirectoryDevice(const char* sName, const char* sBasePathPreference) : -CDevice(sName) -{ - m_sBasePathPreference = sBasePathPreference; -} - -CStream* CFileIO::CDirectoryDevice::OpenFile(uint32 nMode, const char* sDevicePath) -{ - FILE* pStream; - char sPath[256]; - const char* sMode; - const char* sBasePath; - - sBasePath = CConfig::GetInstance()->GetPreferenceString(m_sBasePathPreference); - - strcpy(sPath, sBasePath); - if(sDevicePath[0] != '/') - { - strcat(sPath, "/"); - } - strcat(sPath, sDevicePath); - - switch(nMode) - { - case 0: - case O_RDONLY: - sMode = "rb"; - break; - case (O_RDWR | O_CREAT): - sMode = "w+"; - break; - default: - assert(0); - break; - } - - - pStream = fopen(sPath, sMode); - if(pStream == NULL) return NULL; - - return new CStdStream(pStream); -} - -CFileIO::CCDROM0Device::CCDROM0Device() : -CFileIO::CDevice("cdrom0") -{ - -} - -CFileIO::CCDROM0Device::~CCDROM0Device() -{ - -} - -CStream* CFileIO::CCDROM0Device::OpenFile(uint32 nMode, const char* sDevicePath) -{ - CISO9660* pISO; - - if(nMode != O_RDONLY) return NULL; - - pISO = CPS2VM::m_pCDROM0; - if(pISO == NULL) return NULL; - - return pISO->Open(sDevicePath); -} diff --git a/Source/IOP_FileIO.h b/Source/IOP_FileIO.h deleted file mode 100644 index ba3a16de..00000000 --- a/Source/IOP_FileIO.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef _IOP_FILEIO_H_ -#define _IOP_FILEIO_H_ - -#include -#include "IOP_Module.h" -#include "List.h" -#include "Stream.h" - -namespace IOP -{ - class CFileIO : public CModule - { - public: - CFileIO(); - ~CFileIO(); - virtual void Invoke(uint32, void*, uint32, void*, uint32); - virtual void SaveState(Framework::CStream*); - virtual void LoadState(Framework::CStream*); - Framework::CStream* GetFile(uint32, const char*); - uint32 Read(uint32, uint32, void*); - uint32 Write(uint32, uint32, void*); - - enum MODULE_ID - { - MODULE_ID = 0x80000001 - }; - - enum OPEN_FLAGS - { - O_RDONLY = 0x00000001, - O_WRONLY = 0x00000002, - O_RDWR = 0x00000003, - O_CREAT = 0x00000200, - }; - - private: - class CDevice - { - public: - CDevice(const char*); - virtual ~CDevice() {} - virtual Framework::CStream* OpenFile(uint32, const char*) = 0; - virtual const char* GetName(); - - private: - const char* m_sName; - }; - - class CDirectoryDevice : public CDevice - { - public: - CDirectoryDevice(const char*, const char*); - virtual Framework::CStream* OpenFile(uint32, const char*); - private: - const char* m_sBasePathPreference; - }; - - class CCDROM0Device : public CDevice - { - public: - CCDROM0Device(); - virtual ~CCDROM0Device(); - virtual Framework::CStream* OpenFile(uint32, const char*); - }; - - bool SplitPath(const char*, char*, char*); - CDevice* FindDevice(const char*); - uint32 RegisterFile(Framework::CStream*); - - uint32 Open(uint32, const char*); - uint32 Close(uint32); - uint32 Seek(uint32, uint32, uint32); - - void Log(const char*, ...); - - uint32 m_nFileID; - - Framework::CList m_File; - Framework::CList m_Device; - }; -} - -#endif diff --git a/Source/IOP_LibSD.cpp b/Source/IOP_LibSD.cpp deleted file mode 100644 index ef38c52a..00000000 --- a/Source/IOP_LibSD.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "IOP_LibSD.h" - -using namespace IOP; -using namespace Framework; - -void CLibSD::Invoke(uint32 nMethod, void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - switch(nMethod) - { - case 0x8100: - //Not sure about this one - GetBufferSize(pArgs, nArgsSize, pRet, nRetSize); - break; - } -} - -void CLibSD::SaveState(CStream* pStream) -{ - -} - -void CLibSD::LoadState(CStream* pStream) -{ - -} - -void CLibSD::GetBufferSize(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - static uint32 nTemp = 0; - nTemp += 0x400; - ((uint32*)pRet)[0] = nTemp; -} diff --git a/Source/IOP_LibSD.h b/Source/IOP_LibSD.h deleted file mode 100644 index 321f854f..00000000 --- a/Source/IOP_LibSD.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _IOP_LIBSD_H_ -#define _IOP_LIBSD_H_ - -#include "IOP_Module.h" - -namespace IOP -{ - class CLibSD : public CModule - { - public: - virtual void Invoke(uint32, void*, uint32, void*, uint32); - virtual void SaveState(Framework::CStream*); - virtual void LoadState(Framework::CStream*); - - enum MODULE_ID - { - MODULE_ID = 0x80000701 - }; - - private: - void GetBufferSize(void*, uint32, void*, uint32); - }; - -}; - -#endif diff --git a/Source/IOP_LoadFile.cpp b/Source/IOP_LoadFile.cpp deleted file mode 100644 index 2a7cd50c..00000000 --- a/Source/IOP_LoadFile.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include -#include -#include "IOP_LoadFile.h" -#include "PS2VM.h" - -using namespace IOP; -using namespace Framework; - -void CLoadFile::Invoke(uint32 nMethod, void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - switch(nMethod) - { - case 0x00: - LoadModule(pArgs, nArgsSize, pRet, nRetSize); - break; - case 0xFF: - //This is sometimes called after binding this server with a client - Initialize(pArgs, nArgsSize, pRet, nRetSize); - break; - default: - assert(0); - break; - } -} - -void CLoadFile::SaveState(CStream* pStream) -{ - -} - -void CLoadFile::LoadState(CStream* pStream) -{ - -} - -void CLoadFile::LoadModule(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - char sModuleName[253]; - - assert(nArgsSize == 512); - - //Sometimes called with 4, sometimes 8 - assert(nRetSize >= 4); - - memset(sModuleName, 0, 253); - strncpy(sModuleName, &((const char*)pArgs)[8], 252); - - //Load the module??? - Log("Request to load module '%s' received.\r\n", sModuleName); - - //This function returns something negative upon failure - *(uint32*)pRet = 0x00000000; -} - -void CLoadFile::Initialize(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - assert(nArgsSize == 0); - assert(nRetSize == 4); - - *(uint32*)pRet = 0x2E2E2E2E; -} - -void CLoadFile::Log(const char* sFormat, ...) -{ -#ifdef _DEBUG - - if(!CPS2VM::m_Logging.GetIOPLoggingStatus()) return; - - va_list Args; - printf("IOP_LoadFile: "); - va_start(Args, sFormat); - vprintf(sFormat, Args); - va_end(Args); - -#endif -} diff --git a/Source/IOP_LoadFile.h b/Source/IOP_LoadFile.h deleted file mode 100644 index 3ac71930..00000000 --- a/Source/IOP_LoadFile.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _IOP_LOADFILE_H_ -#define _IOP_LOADFILE_H_ - -#include "IOP_Module.h" - -namespace IOP -{ - class CLoadFile : public CModule - { - public: - virtual void Invoke(uint32, void*, uint32, void*, uint32); - virtual void SaveState(Framework::CStream*); - virtual void LoadState(Framework::CStream*); - - enum MODULE_ID - { - MODULE_ID = 0x80000006 - }; - - private: - void LoadModule(void*, uint32, void*, uint32); - void Initialize(void*, uint32, void*, uint32); - void Log(const char*, ...); - }; - -}; - -#endif diff --git a/Source/IOP_McServ.cpp b/Source/IOP_McServ.cpp deleted file mode 100644 index 77c116e1..00000000 --- a/Source/IOP_McServ.cpp +++ /dev/null @@ -1,414 +0,0 @@ -#include -#include -#include -#include "Config.h" -#include "IOP_McServ.h" -#include "PS2VM.h" - -using namespace IOP; -using namespace Framework; -using namespace boost; -using namespace std; - -const char* CMcServ::m_sMcPathPreference[2] = -{ - "ps2.mc0.directory", - "ps2.mc1.directory", -}; - -CMcServ::CMcServ() -{ - assert(sizeof(CMD) == 0x414); - m_nNextHandle = 1; -} - -CMcServ::~CMcServ() -{ - //Close any handles that might still be in there... - - for(HandleMap::iterator itHandle = m_Handles.begin(); - itHandle != m_Handles.end(); - itHandle++) - { - fclose(itHandle->second); - } -} - -void CMcServ::Invoke(uint32 nMethod, void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - switch(nMethod) - { - case 0x01: - GetInfo(pArgs, nArgsSize, pRet, nRetSize); - break; - case 0x02: - Open(pArgs, nArgsSize, pRet, nRetSize); - break; - case 0x03: - Close(pArgs, nArgsSize, pRet, nRetSize); - break; - case 0x05: - Read(pArgs, nArgsSize, pRet, nRetSize); - break; - case 0x0D: - GetDir(pArgs, nArgsSize, pRet, nRetSize); - break; - case 0xFE: - //Get version? - GetVersionInformation(pArgs, nArgsSize, pRet, nRetSize); - break; - default: - Log("Unknown method invoked (0x%0.8X).\r\n", nMethod); - break; - } -} - -void CMcServ::SaveState(CStream* pStream) -{ - -} - -void CMcServ::LoadState(CStream* pStream) -{ - -} - -void CMcServ::GetInfo(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - assert(nArgsSize >= 0x1C); - - uint32 nPort, nSlot; - uint32* pRetBuffer; - - bool nWantType; - bool nWantFreeSpace; - bool nWantFormatted; - - nPort = ((uint32*)pArgs)[1]; - nSlot = ((uint32*)pArgs)[2]; - nWantType = ((uint32*)pArgs)[3] != 0; - nWantFreeSpace = ((uint32*)pArgs)[4] != 0; - nWantFormatted = ((uint32*)pArgs)[5] != 0; - pRetBuffer = (uint32*)&CPS2VM::m_pRAM[((uint32*)pArgs)[7]]; - - Log("GetInfo(nPort = %i, nSlot = %i, nWantType = %i, nWantFreeSpace = %i, nWantFormatted = %i, nRetBuffer = 0x%0.8X);\r\n", - nPort, nSlot, nWantType, nWantFreeSpace, nWantFormatted, ((uint32*)pArgs)[7]); - - if(nWantType) - { - pRetBuffer[0x00] = 2; - } - if(nWantFreeSpace) - { - pRetBuffer[0x01] = 0x800000; - } - if(nWantFormatted) - { - pRetBuffer[0x24] = 1; - } - - ((uint32*)pRet)[0] = 0; -} - -void CMcServ::Open(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - uint32 nHandle; - CMD* pCmd; - FILE* pFile; - const char* sAccess; - - assert(nArgsSize >= 0x414); - - pCmd = reinterpret_cast(pArgs); - - Log("Open(nPort = %i, nSlot = %i, nFlags = %i, sName = %s);\r\n", - pCmd->nPort, pCmd->nSlot, pCmd->nFlags, pCmd->sName); - - if(pCmd->nPort > 1) - { - assert(0); - ((uint32*)pRet)[0] = -1; - return; - } - - filesystem::path Path; - - try - { - Path = filesystem::path(CConfig::GetInstance()->GetPreferenceString(m_sMcPathPreference[pCmd->nPort]), filesystem::native); - Path /= pCmd->sName; - } - catch(const exception& Exception) - { - Log("Error while executing Open: %s\r\n.", Exception.what()); - reinterpret_cast(pRet)[0] = -1; - return; - } - - sAccess = NULL; - switch(pCmd->nFlags) - { - case 1: - sAccess = "rb"; - break; - } - - if(sAccess == NULL) - { - ((uint32*)pRet)[0] = -1; - assert(0); - return; - } - - pFile = fopen(Path.string().c_str(), sAccess); - if(pFile == NULL) - { - ((uint32*)pRet)[0] = -1; - return; - } - - nHandle = GenerateHandle(); - m_Handles[nHandle] = pFile; - - ((uint32*)pRet)[0] = nHandle; -} - -void CMcServ::Close(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - FILECMD* pCmd; - - pCmd = reinterpret_cast(pArgs); - - Log("Close(nHandle = %i);\r\n", - pCmd->nHandle); - - HandleMap::iterator itHandle; - - itHandle = m_Handles.find(pCmd->nHandle); - if(itHandle == m_Handles.end()) - { - ((uint32*)pRet)[0] = -1; - assert(0); - return; - } - - fclose(itHandle->second); - m_Handles.erase(itHandle); - - ((uint32*)pRet)[0] = 0; -} - -void CMcServ::Read(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - FILECMD* pCmd; - FILE* pFile; - void* pDst; - - pCmd = reinterpret_cast(pArgs); - - Log("Read(nHandle = %i, nSize = 0x%0.8X, nBufferAddress = 0x%0.8X, nParamAddress = 0x%0.8X);\r\n", - pCmd->nHandle, pCmd->nSize, pCmd->nBufferAddress, pCmd->nParamAddress); - - HandleMap::iterator itHandle; - - itHandle = m_Handles.find(pCmd->nHandle); - if(itHandle == m_Handles.end()) - { - ((uint32*)pRet)[0] = -1; - assert(0); - return; - } - - pFile = itHandle->second; - pDst = &CPS2VM::m_pRAM[pCmd->nBufferAddress]; - - //This param buffer is used in the callback after calling this method... No clue what it's for - ((uint32*)&CPS2VM::m_pRAM[pCmd->nParamAddress])[0] = 0; - ((uint32*)&CPS2VM::m_pRAM[pCmd->nParamAddress])[1] = 0; - - ((uint32*)pRet)[0] = static_cast(fread(pDst, 1, pCmd->nSize, pFile)); -} - -void CMcServ::GetDir(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - uint32 nRet; - - nRet = 0; - - assert(nArgsSize >= 0x414); - - CMD* pCmd; - pCmd = reinterpret_cast(pArgs); - - Log("GetDir(nPort = %i, nSlot = %i, nFlags = %i, nMaxEntries = %i, nTableAddress = 0x%0.8X, sName = %s);\r\n", - pCmd->nPort, pCmd->nSlot, pCmd->nFlags, pCmd->nMaxEntries, pCmd->nTableAddress, pCmd->sName); - - if(pCmd->nPort > 1) - { - assert(0); - ((uint32*)pRet)[0] = -1; - return; - } - - try - { - filesystem::path McPath(CConfig::GetInstance()->GetPreferenceString(m_sMcPathPreference[pCmd->nPort]), filesystem::native); - McPath = filesystem::complete(McPath); - - if(filesystem::exists(McPath)) - { - CPathFinder PathFinder(McPath, reinterpret_cast(&CPS2VM::m_pRAM[pCmd->nTableAddress]), pCmd->nMaxEntries, pCmd->sName); - nRet = PathFinder.Search(); - } - } - catch(const exception& Exception) - { - Log("Error while executing GetDir: %s\r\n.", Exception.what()); - } - - ((uint32*)pRet)[0] = nRet; -} - -void CMcServ::GetVersionInformation(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - assert(nArgsSize == 0x30); - assert(nRetSize == 0x0C); - - ((uint32*)pRet)[0] = 0x00000000; - ((uint32*)pRet)[1] = 0x0000020A; //mcserv version - ((uint32*)pRet)[2] = 0x0000020E; //mcman version - - Log("Init();\r\n"); -} - -uint32 CMcServ::GenerateHandle() -{ - return m_nNextHandle++; -} - -void CMcServ::Log(const char* sFormat, ...) -{ -#ifdef _DEBUG - - if(!CPS2VM::m_Logging.GetIOPLoggingStatus()) return; - - va_list Args; - printf("IOP_McServ: "); - va_start(Args, sFormat); - vprintf(sFormat, Args); - va_end(Args); - -#endif -} - -///////////////////////////////////////////// -//CPathFinder Implementation -///////////////////////////////////////////// - -CMcServ::CPathFinder::CPathFinder(const filesystem::path& BasePath, ENTRY* pEntry, unsigned int nMax, const char* sFilter) -{ - m_BasePath = BasePath; - m_pEntry = pEntry; - m_nIndex = 0; - m_nMax = nMax; - m_sFilter = sFilter; -} - -CMcServ::CPathFinder::~CPathFinder() -{ - -} - -unsigned int CMcServ::CPathFinder::Search() -{ - SearchRecurse(m_BasePath); - return m_nIndex; -} - -void CMcServ::CPathFinder::SearchRecurse(const filesystem::path& Path) -{ - filesystem::directory_iterator itEnd; - - for(filesystem::directory_iterator itElement(Path); - itElement != itEnd; - itElement++) - { - string sRelativePath((*itElement).string()); - - //"Extract" a more appropriate relative path from the memory card point of view - sRelativePath.erase(0, m_BasePath.string().size()); - - //Attempt to match this against the filter - if(MatchesFilter(sRelativePath.c_str())) - { - //This fits... fill in the information - - ENTRY* pEntry; - pEntry = &m_pEntry[m_nIndex]; - - //strncpy(reinterpret_cast(pEntry->sName), sRelativePath.c_str(), 0x1F); - strncpy(reinterpret_cast(pEntry->sName), (*itElement).leaf().c_str(), 0x1F); - pEntry->sName[0x1F] = 0; - - if(filesystem::is_directory(*itElement)) - { - pEntry->nSize = 0; - pEntry->nAttributes = 0x8427; - } - else - { - pEntry->nSize = static_cast(filesystem::file_size(*itElement)); - pEntry->nAttributes = 0x8497; - } - - m_nIndex++; - } - - if(filesystem::is_directory(*itElement)) - { - SearchRecurse(*itElement); - } - } -} - -//Based on an algorithm found on http://xoomer.alice.it/acantato/dev/wildcard/wildmatch.html -bool CMcServ::CPathFinder::MatchesFilter(const char* sPath) -{ - const char* sPattern; - const char* s; - const char* p; - bool nStar; - - sPattern = m_sFilter.c_str(); - nStar = false; - -_loopStart: - - for(s = sPath, p = sPattern; *s; s++, p++) - { - switch(*p) - { - case '*': - nStar = true; - sPath = s; - sPattern = p; - if((*++p) == 0) return true; - goto _loopStart; - break; - default: - if(toupper(*s) != toupper(*p)) - { - goto _starCheck; - } - break; - } - } - - if(*p == '*') p++; - return (*p) == 0; - -_starCheck: - if(!nStar) return false; - sPath++; - goto _loopStart; -} diff --git a/Source/IOP_McServ.h b/Source/IOP_McServ.h deleted file mode 100644 index f160f87e..00000000 --- a/Source/IOP_McServ.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef _IOP_MCSERV_H_ -#define _IOP_MCSERV_H_ - -#include "IOP_Module.h" -#include -#include -#include - -namespace IOP -{ - - class CMcServ : public CModule - { - public: - CMcServ(); - virtual ~CMcServ(); - virtual void Invoke(uint32, void*, uint32, void*, uint32); - virtual void SaveState(Framework::CStream*); - virtual void LoadState(Framework::CStream*); - - enum MODULE_ID - { - MODULE_ID = 0x80000400, - }; - - private: - struct CMD - { - uint32 nPort; - uint32 nSlot; - uint32 nFlags; - uint32 nMaxEntries; - uint32 nTableAddress; - char sName[0x400]; - }; - - struct FILECMD - { - uint32 nHandle; - uint32 nPad[2]; - uint32 nSize; - uint32 nOffset; - uint32 nOrigin; - uint32 nBufferAddress; - uint32 nParamAddress; - char nData[16]; - }; - - class CPathFinder - { - public: - struct ENTRY - { - struct TIME - { - uint8 nUnknown; - uint8 nSecond; - uint8 nMinute; - uint8 nHour; - uint8 nDay; - uint8 nMonth; - uint16 nYear; - }; - - TIME CreationTime; - TIME ModificationTime; - uint32 nSize; - uint16 nAttributes; - uint16 nReserved0; - uint32 nReserved1[2]; - uint8 sName[0x20]; - }; - CPathFinder(const boost::filesystem::path&, ENTRY*, unsigned int, const char*); - ~CPathFinder(); - - unsigned int Search(); - - private: - void SearchRecurse(const boost::filesystem::path&); - bool MatchesFilter(const char*); - - ENTRY* m_pEntry; - boost::filesystem::path m_BasePath; - std::string m_sFilter; - unsigned int m_nIndex; - unsigned int m_nMax; - - }; - - void GetInfo(void*, uint32, void*, uint32); - void Open(void*, uint32, void*, uint32); - void Close(void*, uint32, void*, uint32); - void Read(void*, uint32, void*, uint32); - void GetDir(void*, uint32, void*, uint32); - void GetVersionInformation(void*, uint32, void*, uint32); - - uint32 GenerateHandle(); - void Log(const char*, ...); - - typedef std::map HandleMap; - - HandleMap m_Handles; - static const char* m_sMcPathPreference[2]; - uint32 m_nNextHandle; - }; - -} - -#endif diff --git a/Source/IOP_Module.h b/Source/IOP_Module.h deleted file mode 100644 index 394cd28e..00000000 --- a/Source/IOP_Module.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _IOP_MODULE_H_ -#define _IOP_MODULE_H_ - -#include "Types.h" -#include "Stream.h" - -namespace IOP -{ - class CModule - { - public: - virtual ~CModule() {} - virtual void Invoke(uint32, void*, uint32, void*, uint32) = 0; - virtual void SaveState(Framework::CStream*) = 0; - virtual void LoadState(Framework::CStream*) = 0; - }; -}; - -#endif diff --git a/Source/IOP_PadMan.cpp b/Source/IOP_PadMan.cpp deleted file mode 100644 index 7ddd9fc3..00000000 --- a/Source/IOP_PadMan.cpp +++ /dev/null @@ -1,224 +0,0 @@ -#include -#include -#include -#include "IOP_PadMan.h" -#include "PS2VM.h" - -using namespace IOP; -using namespace Framework; -using namespace boost; - -#define PADNUM (1) -#define MODE (0x4) - -CPadMan::CPadMan() -{ - m_nPadDataAddress = 0; - m_nPadDataType = 0; - m_pPad = NULL; -} - -void CPadMan::Invoke(uint32 nMethod, void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - assert(nMethod == 1); - nMethod = ((uint32*)pArgs)[0]; - switch(nMethod) - { - case 0x00000001: - case 0x80000100: - Open(pArgs, nArgsSize, pRet, nRetSize); - break; - case 0x00000008: - SetActuatorAlign(pArgs, nArgsSize, pRet, nRetSize); - break; - case 0x00000010: - Init(pArgs, nArgsSize, pRet, nRetSize); - break; - case 0x00000012: - GetModuleVersion(pArgs, nArgsSize, pRet, nRetSize); - break; - default: - Log("Unknown method invoked (0x%0.8X).\r\n", nMethod); - break; - } -} - -void CPadMan::SaveState(CStream* pStream) -{ - pStream->Write(&m_nPadDataAddress, 4); - pStream->Write(&m_nPadDataType, 4); -} - -void CPadMan::LoadState(CStream* pStream) -{ - pStream->Read(&m_nPadDataAddress, 4); - pStream->Read(&m_nPadDataType, 4); -} - -void CPadMan::SetButtonState(unsigned int nPadNumber, CPadListener::BUTTON nButton, bool nPressed) -{ - if(m_nPadDataAddress == 0) return; - - ExecutePadDataFunction(bind(&CPadMan::PDF_SetButtonState, _1, nButton, nPressed), - CPS2VM::m_pRAM + m_nPadDataAddress, PADNUM); -} - -void CPadMan::Open(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - uint32 nPort, nSlot, nAddress; - - nPort = ((uint32*)pArgs)[1]; - nSlot = ((uint32*)pArgs)[2]; - nAddress = ((uint32*)pArgs)[4]; - - if(nPort == 0) - { - m_nPadDataAddress = nAddress; - m_pPad = (PADDATA*)(CPS2VM::m_pRAM + nAddress); - } - - Log("Opening device on port %i and slot %i.\r\n", nPort, nSlot); - - ExecutePadDataFunction(&CPadMan::PDF_InitializeStruct0, CPS2VM::m_pRAM + m_nPadDataAddress, 0); - ExecutePadDataFunction(&CPadMan::PDF_InitializeStruct1, CPS2VM::m_pRAM + m_nPadDataAddress, 1); - - //Returns 0 on error - ((uint32*)pRet)[3] = 0x00000001; -} - -void CPadMan::SetActuatorAlign(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - assert(nRetSize >= 24); - - ((uint32*)pRet)[5] = 1; -} - -void CPadMan::Init(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - assert(nRetSize >= 0x10); - - m_nPadDataType = 1; - - Log("Init();\r\n"); - - ((uint32*)pRet)[3] = 1; -} - -void CPadMan::GetModuleVersion(void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - assert(nRetSize >= 0x10); - - Log("GetModuleVersion();\r\n"); - - ((uint32*)pRet)[3] = 0x00000400; -} - -void CPadMan::ExecutePadDataFunction(PadDataFunction Function, void* pBase, size_t nOffset) -{ - switch(m_nPadDataType) - { - case 0: - Function(&CPadDataHandler(reinterpret_cast(pBase) + nOffset)); - break; - case 1: - Function(&CPadDataHandler(reinterpret_cast(pBase) + nOffset)); - break; - } -} - -void CPadMan::PDF_InitializeStruct0(CPadDataInterface* pPadData) -{ - pPadData->SetFrame(0); - pPadData->SetState(6); - pPadData->SetReqState(0); - pPadData->SetLength(32); - pPadData->SetOk(1); - -// m_pPad[0].nFrame = 0; -// m_pPad[0].nState = 6; -// m_pPad[0].nReqState = 0; -// m_pPad[0].nLength = 32; -// m_pPad[0].nOk = 1; -} - -void CPadMan::PDF_InitializeStruct1(CPadDataInterface* pPadData) -{ - pPadData->SetFrame(1); - pPadData->SetState(6); - pPadData->SetReqState(0); - pPadData->SetLength(32); - pPadData->SetOk(1); - - //EX struct initialization - pPadData->SetModeCurId(MODE << 4); - pPadData->SetModeCurOffset(0); - pPadData->SetModeTable(0, MODE); -/* - m_pPad[1].nFrame = 1; - m_pPad[1].nState = 6; - m_pPad[1].nReqState = 0; - m_pPad[1].nLength = 32; - m_pPad[1].nOk = 1; -#ifdef USE_EX - m_pPad[1].nModeCurId = MODE << 4; - m_pPad[1].nModeCurOffset = 0; - m_pPad[1].nModeTable[0] = MODE; -#endif -*/ -} - -void CPadMan::PDF_SetButtonState(CPadDataInterface* pPadData, BUTTON nButton, bool nPressed) -{ - uint16 nStatus; - - nStatus = (pPadData->GetData(2) << 8) | (pPadData->GetData(3)); - - nStatus &= ~nButton; - if(!nPressed) - { - nStatus |= nButton; - } - - pPadData->SetReqState(0); - - pPadData->SetData(2, static_cast(nStatus >> 8)); - pPadData->SetData(3, static_cast(nStatus >> 0)); - - pPadData->SetData(0, 0); - pPadData->SetData(1, MODE << 4); - -/* - uint16 nStatus; - if(m_pPad == NULL) return; - nStatus = (m_pPad[PADNUM].nData[2] << 8) | (m_pPad[PADNUM].nData[3]); - - nStatus &= ~nButton; - if(!nPressed) - { - nStatus |= nButton; - } - - m_pPad[PADNUM].nReqState = 0; - - m_pPad[PADNUM].nData[2] = (uint8)(nStatus >> 8); - m_pPad[PADNUM].nData[3] = (uint8)(nStatus >> 0); - - m_pPad[PADNUM].nData[0] = 0; - m_pPad[PADNUM].nData[1] = MODE << 4; -*/ -} - -void CPadMan::Log(const char* sFormat, ...) -{ -#ifdef _DEBUG - - if(!CPS2VM::m_Logging.GetIOPLoggingStatus()) return; - - va_list Args; - printf("IOP_PadMan: "); - va_start(Args, sFormat); - vprintf(sFormat, Args); - va_end(Args); - -#endif -} diff --git a/Source/IOP_PadMan.h b/Source/IOP_PadMan.h deleted file mode 100644 index 9ad8b07a..00000000 --- a/Source/IOP_PadMan.h +++ /dev/null @@ -1,172 +0,0 @@ -#ifndef _IOP_PADMAN_H_ -#define _IOP_PADMAN_H_ - -#include "IOP_Module.h" -#include "PadListener.h" -#include - -//#define USE_EX - -namespace IOP -{ - class CPadMan : public CModule, public CPadListener - { - public: - CPadMan(); - virtual void Invoke(uint32, void*, uint32, void*, uint32); - virtual void SaveState(Framework::CStream*); - virtual void LoadState(Framework::CStream*); - virtual void SetButtonState(unsigned int, CPadListener::BUTTON, bool); - - enum MODULE_ID - { - MODULE_ID_1 = 0x80000100, - MODULE_ID_2 = 0x80000101, - MODULE_ID_3 = 0x8000010F, - MODULE_ID_4 = 0x0000011F, - }; - - private: - struct PADDATAEX - { - uint8 nData[32]; - uint32 nReserved1[4]; - uint8 nActuator[32]; - uint16 nModeTable[4]; - uint32 nFrame; - uint32 nReserved2; - uint32 nLength; - uint8 nModeOk; - uint8 nModeCurId; - uint8 nReserved3[2]; - uint8 nNrOfModes; - uint8 nModeCurOffset; - uint8 nActuatorCount; - uint8 nReserved4[5]; - uint8 nState; - uint8 nReqState; - uint8 nOk; - uint8 nReserved5[13]; - }; - - struct PADDATA - { - uint32 nFrame; - uint8 nState; - uint8 nReqState; - uint8 nOk; - uint8 nReserved0; - uint8 nData[32]; - uint32 nLength; - uint32 nReserved1[5]; - }; - - class CPadDataInterface - { - public: - virtual ~CPadDataInterface() {} - virtual void SetData(unsigned int, uint8) = 0; - virtual uint8 GetData(unsigned int) = 0; - virtual void SetFrame(unsigned int) = 0; - virtual void SetState(unsigned int) = 0; - virtual void SetReqState(unsigned int) = 0; - virtual void SetLength(unsigned int) = 0; - virtual void SetOk(unsigned int) = 0; - virtual void SetModeCurId(unsigned int) = 0; - virtual void SetModeCurOffset(unsigned int) = 0; - virtual void SetModeTable(unsigned int, unsigned int) = 0; - }; - - template class CPadDataHandler : public CPadDataInterface - { - public: - CPadDataHandler(void* pPtr) - { - m_pPadData = reinterpret_cast(pPtr); - } - - virtual ~CPadDataHandler() - { - - } - - virtual uint8 GetData(unsigned int nIndex) - { - return m_pPadData->nData[nIndex]; - } - - virtual void SetData(unsigned int nIndex, uint8 nValue) - { - m_pPadData->nData[nIndex] = nValue; - } - - virtual void SetFrame(unsigned int nValue) - { - m_pPadData->nFrame = nValue; - } - - virtual void SetState(unsigned int nValue) - { - m_pPadData->nState = nValue; - } - - virtual void SetReqState(unsigned int nValue) - { - m_pPadData->nReqState = nValue; - } - - virtual void SetLength(unsigned int nValue) - { - m_pPadData->nLength = nValue; - } - - virtual void SetOk(unsigned int nValue) - { - m_pPadData->nOk = nValue; - } - - virtual void SetModeCurId(unsigned int nValue) - { - m_pPadData->nModeCurId = nValue; - } - - virtual void SetModeCurOffset(unsigned int nValue) - { - m_pPadData->nModeCurOffset = nValue; - } - - virtual void SetModeTable(unsigned int nIndex, unsigned int nValue) - { - m_pPadData->nModeTable[nIndex] = nValue; - } - - private: - T* m_pPadData; - }; - - typedef boost::function< void (CPadDataInterface*) > PadDataFunction; - - PADDATA* m_pPad; - - unsigned int m_nPadDataType; - uint32 m_nPadDataAddress; - - void Open(void*, uint32, void*, uint32); - void SetActuatorAlign(void*, uint32, void*, uint32); - void Init(void*, uint32, void*, uint32); - void GetModuleVersion(void*, uint32, void*, uint32); - void ExecutePadDataFunction(PadDataFunction, void*, size_t); - - static void PDF_InitializeStruct0(CPadDataInterface*); - static void PDF_InitializeStruct1(CPadDataInterface*); - static void PDF_SetButtonState(CPadDataInterface*, BUTTON, bool); - - static void Log(const char*, ...); - }; - - template <> void CPadMan::CPadDataHandler::SetModeCurId(unsigned int); - template <> void CPadMan::CPadDataHandler::SetModeCurOffset(unsigned int); - template <> void CPadMan::CPadDataHandler::SetModeTable(unsigned int, unsigned int); -} - -#endif diff --git a/Source/IOP_SysMem.cpp b/Source/IOP_SysMem.cpp deleted file mode 100644 index a6f7a29e..00000000 --- a/Source/IOP_SysMem.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include -#include "IOP_SysMem.h" -#include "PS2VM.h" - -using namespace IOP; -using namespace Framework; - -void CSysMem::Invoke(uint32 nMethod, void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - switch(nMethod) - { - case 0x01: - assert(nRetSize == 4); - *(uint32*)pRet = Allocate(*(uint32*)pArgs); - break; - case 0x04: - assert(nRetSize == 4); - *(uint32*)pRet = AllocateSystemMemory(((uint32*)pArgs)[0], ((uint32*)pArgs)[1], ((uint32*)pArgs)[2]); - break; - default: - //assert(0); - break; - } -} - -void CSysMem::SaveState(CStream* pStream) -{ - -} - -void CSysMem::LoadState(CStream* pStream) -{ - -} - -uint32 CSysMem::Allocate(uint32 nSize) -{ - Log("Allocate(size = 0x%0.8X);\r\n", nSize); - //return 0x01; - return nSize; -} - -uint32 CSysMem::AllocateSystemMemory(uint32 nFlags, uint32 nSize, uint32 nPtr) -{ - //Ys 1&2 Eternal Story calls this - - Log("AllocateSystemMemory(flags = 0x%0.8X, size = 0x%0.8X, ptr = 0x%0.8X);\r\n", nFlags, nSize, nPtr); - return 0x01; -} - -void CSysMem::Log(const char* sFormat, ...) -{ -#ifdef _DEBUG - - if(!CPS2VM::m_Logging.GetIOPLoggingStatus()) return; - - va_list Args; - printf("IOP_SysMem: "); - va_start(Args, sFormat); - vprintf(sFormat, Args); - va_end(Args); - -#endif -} diff --git a/Source/IOP_SysMem.h b/Source/IOP_SysMem.h deleted file mode 100644 index 80ae1b27..00000000 --- a/Source/IOP_SysMem.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _IOP_SYSMEM_H_ -#define _IOP_SYSMEM_H_ - -#include "IOP_Module.h" - -namespace IOP -{ - class CSysMem : public CModule - { - public: - virtual void Invoke(uint32, void*, uint32, void*, uint32); - virtual void SaveState(Framework::CStream*); - virtual void LoadState(Framework::CStream*); - - enum MODULE_ID - { - MODULE_ID = 0x80000003 - }; - - private: - uint32 Allocate(uint32); - uint32 AllocateSystemMemory(uint32, uint32, uint32); - - void Log(const char*, ...); - }; -}; - -#endif diff --git a/Source/IOP_Unknown.cpp b/Source/IOP_Unknown.cpp deleted file mode 100644 index 5639c37b..00000000 --- a/Source/IOP_Unknown.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "PS2VM.h" -#include "IOP_Unknown.h" - -using namespace IOP; - -void CUnknown::Invoke(uint32 nMethod, void* pArgs, uint32 nArgsSize, void* pRet, uint32 nRetSize) -{ - switch(nMethod) - { - case 0x01000000: - { - if(nRetSize == 0x7C) - { - (reinterpret_cast(pRet))[0x30] |= 0x7; - (reinterpret_cast(pRet))[0x31] |= 0x7; - - (reinterpret_cast(pRet))[0x30] ^= 0x8; - (reinterpret_cast(pRet))[0x31] ^= 0x8; - } - break; - } - } -} - -void CUnknown::LoadState(Framework::CStream* pStream) -{ - -} - -void CUnknown::SaveState(Framework::CStream* pStream) -{ - -} diff --git a/Source/IOP_Unknown.h b/Source/IOP_Unknown.h deleted file mode 100644 index 21549a7f..00000000 --- a/Source/IOP_Unknown.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _IOP_UNKNOWN_H_ -#define _IOP_UNKNOWN_H_ - -#include "IOP_Module.h" - -namespace IOP -{ - class CUnknown : public CModule - { - public: - virtual void Invoke(uint32, void*, uint32, void*, uint32); - virtual void LoadState(Framework::CStream*); - virtual void SaveState(Framework::CStream*); - - enum MODULE_ID - { - MODULE_ID = 0x00012345, - }; - }; -}; - -#endif diff --git a/Source/MA_EE.cpp b/Source/MA_EE.cpp index fd0903d9..ce344813 100644 --- a/Source/MA_EE.cpp +++ b/Source/MA_EE.cpp @@ -272,33 +272,13 @@ void CMA_EE::MULTU1() //1A void CMA_EE::DIV1() { - m_pB->PushAddr(&m_pCtx->m_State.nGPR[m_nRS].nV[0]); - m_pB->PushAddr(&m_pCtx->m_State.nGPR[m_nRT].nV[0]); - m_pB->DivS(); - - m_pB->SeX32(); - m_pB->PullAddr(&m_pCtx->m_State.nLO1[1]); - m_pB->PullAddr(&m_pCtx->m_State.nLO1[0]); - - m_pB->SeX32(); - m_pB->PullAddr(&m_pCtx->m_State.nHI1[1]); - m_pB->PullAddr(&m_pCtx->m_State.nHI1[0]); + Template_Div32()(bind(&CCodeGen::DivS, m_codeGen), 1); } //1B void CMA_EE::DIVU1() { - m_pB->PushAddr(&m_pCtx->m_State.nGPR[m_nRS].nV[0]); - m_pB->PushAddr(&m_pCtx->m_State.nGPR[m_nRT].nV[0]); - m_pB->Div(); - - m_pB->SeX32(); - m_pB->PullAddr(&m_pCtx->m_State.nLO1[1]); - m_pB->PullAddr(&m_pCtx->m_State.nLO1[0]); - - m_pB->SeX32(); - m_pB->PullAddr(&m_pCtx->m_State.nHI1[1]); - m_pB->PullAddr(&m_pCtx->m_State.nHI1[0]); + Template_Div32()(bind(&CCodeGen::Div, m_codeGen), 1); } //28 @@ -356,14 +336,10 @@ void CMA_EE::PSRAH() //01 void CMA_EE::PSUBW() { - CCodeGen::Begin(m_pB); - { - PushVector(m_nRS); - PushVector(m_nRT); - CVUI128::SubW(); - PullVector(m_nRD); - } - CCodeGen::End(); + PushVector(m_nRS); + PushVector(m_nRT); + m_codeGen->MD_SubW(); + PullVector(m_nRD); } //04 @@ -646,14 +622,10 @@ void CMA_EE::PAND() //13 void CMA_EE::PXOR() { - CCodeGen::Begin(m_pB); - { - CVUI128::Push(&m_pCtx->m_State.nGPR[m_nRS]); - CVUI128::Push(&m_pCtx->m_State.nGPR[m_nRT]); - CVUI128::Xor(); - CVUI128::Pull(&m_pCtx->m_State.nGPR[m_nRD]); - } - CCodeGen::End(); + PushVector(m_nRS); + PushVector(m_nRT); + m_codeGen->MD_Xor(); + PullVector(m_nRD); } ////////////////////////////////////////////////// diff --git a/Source/MA_MIPSIV.cpp b/Source/MA_MIPSIV.cpp index 6798dc59..8767cb26 100644 --- a/Source/MA_MIPSIV.cpp +++ b/Source/MA_MIPSIV.cpp @@ -791,7 +791,7 @@ void CMA_MIPSIV::SRL() //03 void CMA_MIPSIV::SRA() { - Template_ShiftCst32()(&CCodeGen::Sra); + Template_ShiftCst32()(bind(&CCodeGen::Sra, m_codeGen, _1)); } //04 @@ -809,11 +809,7 @@ void CMA_MIPSIV::SRLV() //07 void CMA_MIPSIV::SRAV() { - m_pB->PushAddr(&m_pCtx->m_State.nGPR[m_nRT].nV[0]); - m_pB->PushAddr(&m_pCtx->m_State.nGPR[m_nRS].nV[0]); - m_pB->Sra(); - SignExtendTop32(m_nRD); - m_pB->PullAddr(&m_pCtx->m_State.nGPR[m_nRD].nV[0]); + Template_ShiftVar32()(bind(&CCodeGen::Sra, m_codeGen)); } //08 @@ -907,11 +903,11 @@ void CMA_MIPSIV::MFLO() //13 void CMA_MIPSIV::MTLO() { - m_pB->PushAddr(&m_pCtx->m_State.nGPR[m_nRS].nV[0]); - m_pB->PullAddr(&m_pCtx->m_State.nLO[0]); + m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0])); + m_codeGen->PullRel(offsetof(CMIPS, m_State.nLO[0])); - m_pB->PushAddr(&m_pCtx->m_State.nGPR[m_nRS].nV[1]); - m_pB->PullAddr(&m_pCtx->m_State.nLO[1]); + m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[1])); + m_codeGen->PullRel(offsetof(CMIPS, m_State.nLO[1])); } //14 @@ -961,13 +957,13 @@ void CMA_MIPSIV::MULTU() //1A void CMA_MIPSIV::DIV() { - Template_Div32()(bind(&CCodeGen::DivS, m_codeGen)); + Template_Div32()(bind(&CCodeGen::DivS, m_codeGen), 0); } //1B void CMA_MIPSIV::DIVU() { - Template_Div32()(bind(&CCodeGen::Div, m_codeGen)); + Template_Div32()(bind(&CCodeGen::Div, m_codeGen), 0); } //20 diff --git a/Source/MA_MIPSIV.h b/Source/MA_MIPSIV.h index 20e4ec1a..e8eaaa8c 100644 --- a/Source/MA_MIPSIV.h +++ b/Source/MA_MIPSIV.h @@ -89,7 +89,7 @@ protected: struct Template_Div32 { typedef std::tr1::function OperationFunctionType; - void operator()(const OperationFunctionType&) const; + void operator()(const OperationFunctionType&, unsigned int) const; }; struct Template_MovEqual diff --git a/Source/MA_MIPSIV_Templates.cpp b/Source/MA_MIPSIV_Templates.cpp index 16f75bf0..d688f6d5 100644 --- a/Source/MA_MIPSIV_Templates.cpp +++ b/Source/MA_MIPSIV_Templates.cpp @@ -91,19 +91,41 @@ void CMA_MIPSIV::Template_Mult32::operator()(const OperationFunctionType& Functi } } -void CMA_MIPSIV::Template_Div32::operator()(const OperationFunctionType& function) const +void CMA_MIPSIV::Template_Div32::operator()(const OperationFunctionType& function, unsigned int unit) const { - m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0])); + size_t lo[2]; + size_t hi[2]; + + switch(unit) + { + case 0: + lo[0] = offsetof(CMIPS, m_State.nLO[0]); + lo[1] = offsetof(CMIPS, m_State.nLO[1]); + hi[0] = offsetof(CMIPS, m_State.nHI[0]); + hi[1] = offsetof(CMIPS, m_State.nHI[1]); + break; + case 1: + lo[0] = offsetof(CMIPS, m_State.nLO1[0]); + lo[1] = offsetof(CMIPS, m_State.nLO1[1]); + hi[0] = offsetof(CMIPS, m_State.nHI1[0]); + hi[1] = offsetof(CMIPS, m_State.nHI1[1]); + break; + default: + throw runtime_error("Invalid unit number."); + break; + } + + m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRS].nV[0])); m_codeGen->PushRel(offsetof(CMIPS, m_State.nGPR[m_nRT].nV[0])); function(); m_codeGen->SeX(); - m_codeGen->PullRel(offsetof(CMIPS, m_State.nLO[1])); - m_codeGen->PullRel(offsetof(CMIPS, m_State.nLO[0])); + m_codeGen->PullRel(lo[1]); + m_codeGen->PullRel(lo[0]); m_codeGen->SeX(); - m_codeGen->PullRel(offsetof(CMIPS, m_State.nHI[1])); - m_codeGen->PullRel(offsetof(CMIPS, m_State.nHI[0])); + m_codeGen->PullRel(hi[1]); + m_codeGen->PullRel(hi[0]); } void CMA_MIPSIV::Template_MovEqual::operator()(bool isEqual) const diff --git a/Source/MipsCodeGen.cpp b/Source/MipsCodeGen.cpp index 1e554ed9..6893bcd2 100644 --- a/Source/MipsCodeGen.cpp +++ b/Source/MipsCodeGen.cpp @@ -109,6 +109,25 @@ void CMipsCodeGen::FP_PullWordTruncate(size_t offset) CCodeGen::FP_PullWordTruncate(offset); } +void CMipsCodeGen::MD_PushRel(size_t offset) +{ + //Dump all four 32-bits of the variable + for(unsigned int i = 0; i < 4; i++) + { + DumpVariable(offset + (i * 4)); + } + CCodeGen::MD_PushRel(offset); +} + +void CMipsCodeGen::MD_PullRel(size_t offset) +{ + for(unsigned int i = 0; i < 4; i++) + { + assert(GetVariableStatus(offset + (i * 4)) == NULL); + } + CCodeGen::MD_PullRel(offset); +} + void CMipsCodeGen::EndIf() { assert(m_Shadow.GetCount() == 0); diff --git a/Source/MipsCodeGen.h b/Source/MipsCodeGen.h index b4cec48c..799e22e1 100644 --- a/Source/MipsCodeGen.h +++ b/Source/MipsCodeGen.h @@ -19,6 +19,9 @@ public: virtual void FP_PullSingle(size_t); virtual void FP_PullWordTruncate(size_t); + virtual void MD_PushRel(size_t); + virtual void MD_PullRel(size_t); + virtual void EndIf(); virtual void BeginIfElseAlt(); diff --git a/Source/PS2OS.cpp b/Source/PS2OS.cpp index 04436082..f34f6a6d 100644 --- a/Source/PS2OS.cpp +++ b/Source/PS2OS.cpp @@ -4,7 +4,7 @@ #include #include #include "PS2OS.h" -#include "PS2VM.h" +#include "Ps2Const.h" #include "StdStream.h" #include "PtrMacro.h" #include "Utils.h" @@ -2140,7 +2140,7 @@ void CPS2OS::sc_Deci2Call() if(pHandler->nValid != 0) { nParam = *(uint32*)&m_ram[pHandler->nBufferAddr + 0x10]; - nParam &= (CPS2VM::RAMSIZE - 1); + nParam &= (PS2::EERAMSIZE - 1); nLength = m_ram[nParam + 0x00] - 0x0C; sString = &m_ram[nParam + 0x0C]; @@ -2182,7 +2182,7 @@ void CPS2OS::sc_Deci2Call() //7F void CPS2OS::sc_GetMemorySize() { - m_ee.m_State.nGPR[SC_RETURN].nV[0] = CPS2VM::RAMSIZE; + m_ee.m_State.nGPR[SC_RETURN].nV[0] = PS2::EERAMSIZE; m_ee.m_State.nGPR[SC_RETURN].nV[1] = 0; } diff --git a/Source/PS2VM.cpp b/Source/PS2VM.cpp index 6fec92f2..0fcdd473 100644 --- a/Source/PS2VM.cpp +++ b/Source/PS2VM.cpp @@ -1,6 +1,7 @@ #include #include #include "PS2VM.h" +#include "Ps2Const.h" #include "IPU.h" #include "VIF.h" #include "Timer.h" @@ -19,7 +20,8 @@ #include "zip/ZipArchiveWriter.h" #include "Config.h" #include "Profiler.h" -#include "IOP_FileIO.h" +#include "iop/IopBios.h" +#include "iop/DirectoryDevice.h" #define STATE_EE ("ee") #define STATE_VU1 ("vu1") @@ -28,6 +30,13 @@ #define STATE_VUMEM1 ("vumem1") #define STATE_MICROMEM1 ("micromem1") +#define PREF_PS2_HOST_DIRECTORY ("ps2.host.directory") +#define PREF_PS2_MC0_DIRECTORY ("ps2.mc0.directory") +#define PREF_PS2_MC1_DIRECTORY ("ps2.mc1.directory") +#define PREF_PS2_HOST_DIRECTORY_DEFAULT ("./vfs/host") +#define PREF_PS2_MC0_DIRECTORY_DEFAULT ("./vfs/mc0") +#define PREF_PS2_MC1_DIRECTORY_DEFAULT ("./vfs/mc1") + #ifdef _DEBUG //#define SCREENTICKS 10000 @@ -52,9 +61,10 @@ using namespace std; using namespace std::tr1; CPS2VM::CPS2VM() : -m_pRAM(new uint8[RAMSIZE]), -m_pBIOS(new uint8[BIOSSIZE]), -m_pSPR(new uint8[SPRSIZE]), +m_pRAM(new uint8[PS2::EERAMSIZE]), +m_pBIOS(new uint8[PS2::EEBIOSSIZE]), +m_pSPR(new uint8[PS2::SPRSIZE]), +m_iopRam(new uint8[PS2::IOPRAMSIZE]), m_pVUMem0(NULL), m_pMicroMem0(NULL), m_pVUMem1(NULL), @@ -62,6 +72,7 @@ m_pMicroMem1(NULL), m_pThread(NULL), m_EE(MEMORYMAP_ENDIAN_LSBF, 0x00000000, 0x20000000), m_VU1(MEMORYMAP_ENDIAN_LSBF, 0x00000000, 0x00008000), +m_iop(MEMORYMAP_ENDIAN_LSBF, 0x00000000, 0x00400000), m_executor(m_EE), m_nStatus(PAUSED), m_nEnd(false), @@ -76,12 +87,18 @@ m_gif(m_pGS, m_pRAM, m_pSPR), m_sif(m_dmac, m_pRAM), m_intc(m_dmac) { + CConfig::GetInstance()->RegisterPreferenceString(PREF_PS2_HOST_DIRECTORY, PREF_PS2_HOST_DIRECTORY_DEFAULT); + CConfig::GetInstance()->RegisterPreferenceString(PREF_PS2_MC0_DIRECTORY, PREF_PS2_MC0_DIRECTORY_DEFAULT); + CConfig::GetInstance()->RegisterPreferenceString(PREF_PS2_MC1_DIRECTORY, PREF_PS2_MC1_DIRECTORY_DEFAULT); + m_os = new CPS2OS(m_EE, m_VU1, m_pRAM, m_pBIOS, m_pGS, m_sif); + m_iopOs = new CIopBios(0x100, m_iop, m_iopRam, PS2::IOPRAMSIZE, m_sif); } CPS2VM::~CPS2VM() { delete m_os; + delete m_iopOs; } ////////////////////////////////////////////////// @@ -231,13 +248,11 @@ unsigned int CPS2VM::LoadState(const char* sPath) void CPS2VM::CreateVM() { - printf("PS2VM: Virtual Machine Memory Usage: RAM: %i MBs, BIOS: %i MBs, SPR: %i KBs.\r\n", RAMSIZE / 0x100000, BIOSSIZE / 0x100000, SPRSIZE / 0x1000); + printf("PS2VM: Virtual Machine Memory Usage: RAM: %i MBs, BIOS: %i MBs, SPR: %i KBs.\r\n", + PS2::EERAMSIZE / 0x100000, PS2::EEBIOSSIZE / 0x100000, PS2::SPRSIZE / 0x1000); -// m_pRAM = (uint8*)malloc(RAMSIZE); -// m_pBIOS = (uint8*)malloc(BIOSSIZE); -// m_pSPR = (uint8*)malloc(SPRSIZE); - m_pVUMem1 = (uint8*)malloc(VUMEM1SIZE); - m_pMicroMem1 = (uint8*)malloc(MICROMEM1SIZE); + m_pVUMem1 = (uint8*)malloc(PS2::VUMEM1SIZE); + m_pMicroMem1 = (uint8*)malloc(PS2::MICROMEM1SIZE); //EmotionEngine context setup m_EE.m_pMemoryMap->InsertReadMap(0x00000000, 0x01FFFFFF, m_pRAM, 0x00); @@ -296,10 +311,10 @@ void CPS2VM::ResetVM() { m_executor.Clear(); - memset(m_pRAM, 0, RAMSIZE); - memset(m_pSPR, 0, SPRSIZE); - memset(m_pVUMem1, 0, VUMEM1SIZE); - memset(m_pMicroMem1, 0, MICROMEM1SIZE); + memset(m_pRAM, 0, PS2::EERAMSIZE); + memset(m_pSPR, 0, PS2::SPRSIZE); + memset(m_pVUMem1, 0, PS2::VUMEM1SIZE); + memset(m_pMicroMem1, 0, PS2::MICROMEM1SIZE); //LoadBIOS(); @@ -336,8 +351,13 @@ void CPS2VM::ResetVM() // m_pOS = new CPS2OS(m_EE, m_VU1, m_pRAM, m_pBIOS, m_pGS); m_os->Release(); m_os->Initialize(); + m_iopOs->Reset(); - RegisterModulesInPadHandler(); + m_iopOs->GetIoman()->RegisterDevice("host", new CDirectoryDevice(PREF_PS2_HOST_DIRECTORY)); + m_iopOs->GetIoman()->RegisterDevice("mc0", new CDirectoryDevice(PREF_PS2_MC0_DIRECTORY)); + m_iopOs->GetIoman()->RegisterDevice("mc1", new CDirectoryDevice(PREF_PS2_MC1_DIRECTORY)); + + RegisterModulesInPadHandler(); } void CPS2VM::DestroyVM() @@ -364,10 +384,10 @@ void CPS2VM::SaveVMState(const char* sPath, unsigned int& result) archive.InsertFile(new CMemoryStateFile(STATE_EE, &m_EE.m_State, sizeof(MIPSSTATE))); archive.InsertFile(new CMemoryStateFile(STATE_VU1, &m_VU1.m_State, sizeof(MIPSSTATE))); - archive.InsertFile(new CMemoryStateFile(STATE_RAM, m_pRAM, RAMSIZE)); - archive.InsertFile(new CMemoryStateFile(STATE_SPR, m_pSPR, SPRSIZE)); - archive.InsertFile(new CMemoryStateFile(STATE_VUMEM1, m_pVUMem1, VUMEM1SIZE)); - archive.InsertFile(new CMemoryStateFile(STATE_MICROMEM1, m_pMicroMem1, MICROMEM1SIZE)); + archive.InsertFile(new CMemoryStateFile(STATE_RAM, m_pRAM, PS2::EERAMSIZE)); + archive.InsertFile(new CMemoryStateFile(STATE_SPR, m_pSPR, PS2::SPRSIZE)); + archive.InsertFile(new CMemoryStateFile(STATE_VUMEM1, m_pVUMem1, PS2::VUMEM1SIZE)); + archive.InsertFile(new CMemoryStateFile(STATE_MICROMEM1, m_pMicroMem1, PS2::MICROMEM1SIZE)); m_pGS->SaveState(archive); m_dmac.SaveState(archive); @@ -405,10 +425,10 @@ void CPS2VM::LoadVMState(const char* sPath, unsigned int& result) archive.BeginReadFile(STATE_EE )->Read(&m_EE.m_State, sizeof(MIPSSTATE)); archive.BeginReadFile(STATE_VU1 )->Read(&m_VU1.m_State, sizeof(MIPSSTATE)); - archive.BeginReadFile(STATE_RAM )->Read(m_pRAM, RAMSIZE); - archive.BeginReadFile(STATE_SPR )->Read(m_pSPR, SPRSIZE); - archive.BeginReadFile(STATE_VUMEM1 )->Read(m_pVUMem1, VUMEM1SIZE); - archive.BeginReadFile(STATE_MICROMEM1 )->Read(m_pMicroMem1, MICROMEM1SIZE); + archive.BeginReadFile(STATE_RAM )->Read(m_pRAM, PS2::EERAMSIZE); + archive.BeginReadFile(STATE_SPR )->Read(m_pSPR, PS2::SPRSIZE); + archive.BeginReadFile(STATE_VUMEM1 )->Read(m_pVUMem1, PS2::VUMEM1SIZE); + archive.BeginReadFile(STATE_MICROMEM1 )->Read(m_pMicroMem1, PS2::MICROMEM1SIZE); m_pGS->LoadState(archive); m_dmac.LoadState(archive); @@ -516,7 +536,7 @@ void CPS2VM::CDROM0_Destroy() void CPS2VM::LoadBIOS() { CStdStream BiosStream(fopen("./vfs/rom0/scph10000.bin", "rb")); - BiosStream.Read(m_pBIOS, BIOSSIZE); + BiosStream.Read(m_pBIOS, PS2::EEBIOSSIZE); } void CPS2VM::RegisterModulesInPadHandler() @@ -633,7 +653,7 @@ uint32 CPS2VM::IOPortWriteHandler(uint32 nAddress, uint32 nData) void CPS2VM::EEMemWriteHandler(uint32 nAddress) { - if(nAddress < RAMSIZE) + if(nAddress < PS2::EERAMSIZE) { //Check if the block we're about to invalidate is the same //as the one we're executing in diff --git a/Source/PS2VM.h b/Source/PS2VM.h index c8cb7536..37762da9 100644 --- a/Source/PS2VM.h +++ b/Source/PS2VM.h @@ -17,7 +17,7 @@ #include "VirtualMachine.h" #include "MipsExecutor.h" -class CSIF; +class CIopBios; enum PS2VM_MSG { @@ -46,31 +46,6 @@ typedef CPadHandler* (*PADHANDLERFACTORY)(void*); class CPS2VM : public CVirtualMachine { public: - enum PS2VM_RAMSIZE - { - RAMSIZE = 0x02000000, - }; - - enum PS2VM_BIOSSIZE - { - BIOSSIZE = 0x00400000, - }; - - enum PS2VM_SPRSIZE - { - SPRSIZE = 0x00004000, - }; - - enum PS2VM_VUMEM1SIZE - { - VUMEM1SIZE = 0x00004000, - }; - - enum PS2VM_MICROMEM1SIZE - { - MICROMEM1SIZE = 0x00004000, - }; - CPS2VM(); virtual ~CPS2VM(); @@ -109,12 +84,14 @@ public: uint8* m_pRAM; uint8* m_pBIOS; uint8* m_pSPR; + uint8* m_iopRam; CDMAC m_dmac; CGIF m_gif; CSIF m_sif; CINTC m_intc; CPS2OS* m_os; + CIopBios* m_iopOs; uint8* m_pVUMem0; uint8* m_pMicroMem0; @@ -124,6 +101,7 @@ public: CMIPS m_EE; CMIPS m_VU1; + CMIPS m_iop; CMipsExecutor m_executor; unsigned int m_nVBlankTicks; bool m_nInVBlank; diff --git a/Source/Ps2Const.h b/Source/Ps2Const.h new file mode 100644 index 00000000..b2b24b5d --- /dev/null +++ b/Source/Ps2Const.h @@ -0,0 +1,37 @@ +#ifndef _PS2CONST_H_ +#define _PS2CONST_H_ + +namespace PS2 +{ + enum EERAMSIZE + { + EERAMSIZE = 0x02000000, + }; + + enum IOPRAMSIZE + { + IOPRAMSIZE = 0x00400000, + }; + + enum EEBIOSSIZE + { + EEBIOSSIZE = 0x00400000, + }; + + enum SPRSIZE + { + SPRSIZE = 0x00004000, + }; + + enum VUMEM1SIZE + { + VUMEM1SIZE = 0x00004000, + }; + + enum MICROMEM1SIZE + { + MICROMEM1SIZE = 0x00004000, + }; +} + +#endif diff --git a/Source/SIF.cpp b/Source/SIF.cpp index 43242670..26d410c3 100644 --- a/Source/SIF.cpp +++ b/Source/SIF.cpp @@ -1,17 +1,7 @@ #include -#include "PS2VM.h" +#include "Ps2Const.h" #include "SIF.h" #include "PtrMacro.h" -#include "IOP_PadMan.h" -#include "IOP_LoadFile.h" -#include "IOP_FileIO.h" -#include "IOP_SysMem.h" -#include "IOP_McServ.h" -#include "IOP_DbcMan.h" -#include "IOP_LibSD.h" -#include "IOP_Cdvdfsv.h" -#include "IOP_Dummy.h" -#include "IOP_Unknown.h" #include "Profiler.h" #include "Log.h" @@ -25,6 +15,7 @@ #endif using namespace Framework; +using namespace std; CSIF::CSIF(CDMAC& dmac, uint8* eeRam) : m_nMAINADDR(0), @@ -33,9 +24,10 @@ m_nMSFLAG(0), m_nSMFLAG(0), m_nEERecvAddr(0), m_nDataAddr(0), -m_pPadMan(NULL), m_dmac(dmac), -m_eeRam(eeRam) +m_eeRam(eeRam), +m_dmaBuffer(NULL), +m_dmaBufferSize(0) { } @@ -78,23 +70,29 @@ void CSIF::Reset() // m_Module.Insert(new IOP::CDbcMan, IOP::CDbcMan::MODULE_ID); } +void CSIF::SetDmaBuffer(uint8* buffer, uint32 size) +{ + m_dmaBuffer = buffer; + m_dmaBufferSize = size; +} + +void CSIF::RegisterModule(uint32 moduleId, CSifModule* module) +{ + m_modules[moduleId] = module; +} + void CSIF::DeleteModules() { - m_modules.erase(IOP::CPadMan::MODULE_ID_1); - m_modules.erase(IOP::CPadMan::MODULE_ID_3); - - DELETEPTR(m_pPadMan); - - for(ModuleMap::iterator moduleIterator(m_modules.begin()); - m_modules.end() != moduleIterator; moduleIterator++) - { - delete moduleIterator->second; - } + m_modules.clear(); } uint32 CSIF::ReceiveDMA5(uint32 srcAddress, uint32 size, uint32 unused, bool isTagIncluded) { - memcpy(m_eeRam + srcAddress, CSIF::m_pRAM, size); + if(size > m_dmaBufferSize) + { + throw runtime_error("Packet too big."); + } + memcpy(m_eeRam + srcAddress, m_dmaBuffer, size); return size; } @@ -108,7 +106,7 @@ uint32 CSIF::ReceiveDMA6(uint32 nSrcAddr, uint32 nSize, uint32 nDstAddr, bool is PACKETHDR* pHDR; //Humm, this is kinda odd, but it ors the address with 0x20000000 - nSrcAddr &= (CPS2VM::RAMSIZE - 1); + nSrcAddr &= (PS2::EERAMSIZE - 1); if(nDstAddr == RPC_RECVADDR) { @@ -163,10 +161,13 @@ void CSIF::SendDMA(void* pData, uint32 nSize) //Humm, the DMAC doesn't know about our addresses on this side... uint32 nQuads; - memcpy(m_pRAM, pData, nSize); + if(nSize > m_dmaBufferSize) + { + throw runtime_error("Packet too big."); + } - nQuads = nSize / 0x10; - if((nSize & 0x0F) != 0) nQuads++; + memcpy(m_dmaBuffer, pData, nSize); + nQuads = (nSize + 0x0F) / 0x10; m_dmac.SetRegister(CDMAC::D5_MADR, m_nEERecvAddr); m_dmac.SetRegister(CDMAC::D5_QWC, nQuads); @@ -209,23 +210,6 @@ void CSIF::SaveState(CStream* pStream) */ } -IOP::CPadMan* CSIF::GetPadMan() -{ - return m_pPadMan; -} - -IOP::CDbcMan* CSIF::GetDbcMan() -{ - ModuleMap::iterator moduleIterator(m_modules.find(IOP::CDbcMan::MODULE_ID)); - return moduleIterator == m_modules.end() ? NULL : static_cast(moduleIterator->second); -} - -IOP::CFileIO* CSIF::GetFileIO() -{ - ModuleMap::iterator moduleIterator(m_modules.find(IOP::CFileIO::MODULE_ID)); - return moduleIterator == m_modules.end() ? NULL : static_cast(moduleIterator->second); -} - ///////////////////////////////////////////////////////// //SIF Commands ///////////////////////////////////////////////////////// @@ -250,7 +234,7 @@ void CSIF::Cmd_Initialize(PACKETHDR* pHDR) if(pInit->Header.nOptional == 0) { m_nEERecvAddr = pInit->nEEAddress; - m_nEERecvAddr &= (CPS2VM::RAMSIZE - 1); + m_nEERecvAddr &= (PS2::EERAMSIZE - 1); } else if(pInit->Header.nOptional == 1) { @@ -312,13 +296,16 @@ void CSIF::Cmd_Call(PACKETHDR* pHDR) CLog::GetInstance().Print(LOG_NAME, "Calling function 0x%0.8X of module 0x%0.8X.\r\n", pCall->nRPCNumber, pCall->nServerDataAddr); - nRecvAddr = (pCall->nRecv & (CPS2VM::RAMSIZE - 1)); + nRecvAddr = (pCall->nRecv & (PS2::EERAMSIZE - 1)); ModuleMap::iterator moduleIterator(m_modules.find(pCall->nServerDataAddr)); if(moduleIterator != m_modules.end()) { - IOP::CModule* pModule(moduleIterator->second); - pModule->Invoke(pCall->nRPCNumber, m_eeRam + m_nDataAddr, pCall->nSendSize, m_eeRam + nRecvAddr, pCall->nRecvSize); + CSifModule* pModule(moduleIterator->second); + pModule->Invoke(pCall->nRPCNumber, + reinterpret_cast(m_eeRam + m_nDataAddr), pCall->nSendSize, + reinterpret_cast(m_eeRam + nRecvAddr), pCall->nRecvSize, + m_eeRam); } else { diff --git a/Source/SIF.h b/Source/SIF.h index 5f450400..a602ae41 100644 --- a/Source/SIF.h +++ b/Source/SIF.h @@ -3,16 +3,9 @@ #include #include "Stream.h" -#include "IOP_Module.h" +#include "SifModule.h" #include "DMAC.h" -namespace IOP -{ - class CPadMan; - class CDbcMan; - class CFileIO; -}; - class CSIF { public: @@ -21,6 +14,9 @@ public: void Reset(); + void RegisterModule(uint32, CSifModule*); + void SetDmaBuffer(uint8*, uint32); + uint32 ReceiveDMA5(uint32, uint32, uint32, bool); uint32 ReceiveDMA6(uint32, uint32, uint32, bool); void SendDMA(void*, uint32); @@ -31,15 +27,8 @@ public: void LoadState(Framework::CStream*); void SaveState(Framework::CStream*); - IOP::CPadMan* GetPadMan(); - IOP::CDbcMan* GetDbcMan(); - IOP::CFileIO* GetFileIO(); - - //This will eventually be moved in the IOP - uint8 m_pRAM[0x1000]; - private: - typedef std::map ModuleMap; + typedef std::map ModuleMap; enum CONST_MAX_USERREG { @@ -115,6 +104,8 @@ private: void Cmd_Call(PACKETHDR*); uint8* m_eeRam; + uint8* m_dmaBuffer; + uint32 m_dmaBufferSize; CDMAC& m_dmac; uint32 m_nMAINADDR; @@ -127,7 +118,6 @@ private: uint32 m_nUserReg[MAX_USERREG]; - IOP::CPadMan* m_pPadMan; ModuleMap m_modules; }; diff --git a/Source/SifModule.h b/Source/SifModule.h new file mode 100644 index 00000000..6a595d54 --- /dev/null +++ b/Source/SifModule.h @@ -0,0 +1,11 @@ +#ifndef _SIFMODULE_H_ +#define _SIFMODULE_H_ + +class CSifModule +{ +public: + virtual ~CSifModule() {} + virtual void Invoke(uint32, uint32*, uint32, uint32*, uint32, uint8*) = 0; +}; + +#endif diff --git a/Source/X86Assembler.cpp b/Source/X86Assembler.cpp index df90c8c6..a690a5c7 100644 --- a/Source/X86Assembler.cpp +++ b/Source/X86Assembler.cpp @@ -397,6 +397,11 @@ void CX86Assembler::Ret() WriteByte(0xC3); } +void CX86Assembler::SarEd(const CAddress& address) +{ + WriteEvOp(0xD3, 0x07, false, address); +} + void CX86Assembler::SarEd(const CAddress& address, uint8 amount) { WriteEvOp(0xC1, 0x07, false, address); diff --git a/Source/X86Assembler.h b/Source/X86Assembler.h index 08ef02a1..2dce211e 100644 --- a/Source/X86Assembler.h +++ b/Source/X86Assembler.h @@ -146,6 +146,7 @@ public: void PushEd(const CAddress&); void PushId(uint32); void Ret(); + void SarEd(const CAddress&); void SarEd(const CAddress&, uint8); void SbbEd(REGISTER, const CAddress&); void SbbId(const CAddress&, uint32); @@ -204,6 +205,7 @@ public: void PcmpeqdVo(XMMREGISTER, const CAddress&); void PorVo(XMMREGISTER, const CAddress&); void PsubbVo(XMMREGISTER, const CAddress&); + void PsubdVo(XMMREGISTER, const CAddress&); void PxorVo(XMMREGISTER, const CAddress&); void MovssEd(const CAddress&, XMMREGISTER); diff --git a/Source/X86Assembler_Sse.cpp b/Source/X86Assembler_Sse.cpp index 2aa3236d..891c3ea6 100644 --- a/Source/X86Assembler_Sse.cpp +++ b/Source/X86Assembler_Sse.cpp @@ -42,6 +42,13 @@ void CX86Assembler::PsubbVo(XMMREGISTER registerId, const CAddress& address) WriteEdVdOp(0xF8, address, registerId); } +void CX86Assembler::PsubdVo(XMMREGISTER registerId, const CAddress& address) +{ + WriteByte(0x66); + WriteByte(0x0F); + WriteEdVdOp(0xFA, address, registerId); +} + void CX86Assembler::PxorVo(XMMREGISTER registerId, const CAddress& address) { WriteByte(0x66); diff --git a/Source/iop/ArgumentIterator.cpp b/Source/iop/ArgumentIterator.cpp new file mode 100644 index 00000000..9de2d3a8 --- /dev/null +++ b/Source/iop/ArgumentIterator.cpp @@ -0,0 +1,26 @@ +#include "ArgumentIterator.h" + +CArgumentIterator::CArgumentIterator(CMIPS& context) : +m_context(context), +m_current(0) +{ + +} + +CArgumentIterator::~CArgumentIterator() +{ + +} + +uint32 CArgumentIterator::GetNext() +{ + if(m_current > 3) + { + uint32 address = m_context.m_State.nGPR[CMIPS::SP].nV0 + (m_current++ - 4) * 4 + 0x10; + return m_context.m_pMemoryMap->GetWord(address); + } + else + { + return m_context.m_State.nGPR[CMIPS::A0 + m_current++].nV[0]; + } +} diff --git a/Source/iop/ArgumentIterator.h b/Source/iop/ArgumentIterator.h new file mode 100644 index 00000000..6e6bb162 --- /dev/null +++ b/Source/iop/ArgumentIterator.h @@ -0,0 +1,18 @@ +#ifndef _ARGUMENT_ITERATOR_H_ +#define _ARGUMENT_ITERATOR_H_ + +#include "../MIPS.h" + +class CArgumentIterator +{ +public: + CArgumentIterator(CMIPS&); + virtual ~CArgumentIterator(); + uint32 GetNext(); + +private: + unsigned int m_current; + CMIPS& m_context; +}; + +#endif diff --git a/Source/iop/DirectoryDevice.cpp b/Source/iop/DirectoryDevice.cpp new file mode 100644 index 00000000..c4cbf900 --- /dev/null +++ b/Source/iop/DirectoryDevice.cpp @@ -0,0 +1,52 @@ +#include "DirectoryDevice.h" +#include "StdStream.h" +#include "../Config.h" + +using namespace Framework; +using namespace std; + +CDirectoryDevice::CDirectoryDevice(const char* basePathPreferenceName) : +m_basePathPreferenceName(basePathPreferenceName) +{ + +} + +CDirectoryDevice::~CDirectoryDevice() +{ + +} + +CStream* CDirectoryDevice::GetFile(uint32 accessType, const char* devicePath) +{ + const char* mode(NULL); + string path; + + const char* basePath = CConfig::GetInstance()->GetPreferenceString(m_basePathPreferenceName.c_str()); + + path = basePath; + if(devicePath[0] != '/') + { + path += "/"; + } + path += devicePath; + + switch(accessType) + { + case 0: + case O_RDONLY: + mode = "rb"; + break; + case (O_RDWR | O_CREAT): + mode = "w+"; + break; + default: + assert(0); + break; + } + + + FILE* stream = fopen(path.c_str(), mode); + if(stream == NULL) return NULL; + + return new CStdStream(stream); +} diff --git a/Source/iop/DirectoryDevice.h b/Source/iop/DirectoryDevice.h new file mode 100644 index 00000000..29777942 --- /dev/null +++ b/Source/iop/DirectoryDevice.h @@ -0,0 +1,18 @@ +#ifndef _DIRECTORYDEVICE_H_ +#define _DIRECTORYDEVICE_H_ + +#include +#include "Ioman_Device.h" + +class CDirectoryDevice : public Iop::Ioman::CDevice +{ +public: + CDirectoryDevice(const char*); + virtual ~CDirectoryDevice(); + virtual Framework::CStream* GetFile(uint32, const char*); + +private: + std::string m_basePathPreferenceName; +}; + +#endif diff --git a/Source/iop/Ioman_Device.h b/Source/iop/Ioman_Device.h new file mode 100644 index 00000000..57f607e0 --- /dev/null +++ b/Source/iop/Ioman_Device.h @@ -0,0 +1,27 @@ +#ifndef _IOMAN_DEVICE_H_ +#define _IOMAN_DEVICE_H_ + +#include "Stream.h" + +namespace Iop +{ + namespace Ioman + { + class CDevice + { + public: + enum OPEN_FLAGS + { + O_RDONLY = 0x00000001, + O_WRONLY = 0x00000002, + O_RDWR = 0x00000003, + O_CREAT = 0x00000200, + }; + + virtual ~CDevice() {} + virtual Framework::CStream* GetFile(uint32, const char*) = 0; + }; + } +} + +#endif diff --git a/Source/iop/IopBios.cpp b/Source/iop/IopBios.cpp new file mode 100644 index 00000000..c7df7697 --- /dev/null +++ b/Source/iop/IopBios.cpp @@ -0,0 +1,733 @@ +#include "IopBios.h" +#include "../COP_SCU.h" +#include "../Log.h" +#include "Iop_Sysclib.h" +#include "Iop_Loadcore.h" +#include "Iop_Thbase.h" +#include "Iop_Thsema.h" +#include "Iop_Thevent.h" +#include "Iop_Timrman.h" +#include "Iop_Intrman.h" +#include +#include + +#define LOGNAME "iop_bios" + +using namespace std; +using namespace Framework; + +CIopBios::CIopBios(uint32 baseAddress, CMIPS& cpu, uint8* ram, uint32 ramSize, CSIF& sif) : +m_baseAddress(baseAddress), +m_cpu(cpu), +m_ram(ram), +m_ramSize(ramSize), +m_sif(sif), +m_nextThreadId(1), +m_nextSemaphoreId(1), +m_stdio(NULL), +m_sysmem(NULL), +m_ioman(NULL), +m_modload(NULL), +m_rescheduleNeeded(false), +m_currentThreadId(-1) +{ + CMIPSAssembler assembler(reinterpret_cast(&m_ram[m_baseAddress])); + m_threadFinishAddress = AssembleThreadFinish(assembler); +} + +CIopBios::~CIopBios() +{ +#ifdef _DEBUG + SaveAllModulesTags(m_cpu.m_Comments, "comments"); + SaveAllModulesTags(m_cpu.m_Functions, "functions"); +#endif + DeleteModules(); +} + +void CIopBios::Reset() +{ + DeleteModules(); + + //Register built-in modules + { + m_stdio = new Iop::CStdio(m_ram); + RegisterModule(m_stdio); + } + { + m_ioman = new Iop::CIoman(m_ram, m_sif); + RegisterModule(m_ioman); + } + { + m_sysmem = new Iop::CSysmem(0x1000, m_ramSize, *m_stdio); + RegisterModule(m_sysmem); + } + { + m_modload = new Iop::CModload(*this, m_ram); + RegisterModule(m_modload); + } + { + RegisterModule(new Iop::CSysclib(m_ram, *m_stdio)); + } + { + RegisterModule(new Iop::CLoadcore(*this, m_ram)); + } + { + RegisterModule(new Iop::CThbase(*this, m_ram)); + } + { + RegisterModule(new Iop::CThsema(*this, m_ram)); + } + { + RegisterModule(new Iop::CThevent(*this, m_ram)); + } + { + RegisterModule(new Iop::CTimrman()); + } + { + RegisterModule(new Iop::CIntrman(m_ram)); + } + + const int sifDmaBufferSize = 0x1000; + uint32 sifDmaBufferPtr = m_sysmem->AllocateMemory(sifDmaBufferSize, 0); + m_sif.SetDmaBuffer(m_ram + sifDmaBufferPtr, sifDmaBufferSize); +} + +void CIopBios::LoadAndStartModule(const char* path, const char* args, unsigned int argsLength) +{ + ExecutableRange moduleRange; + uint32 entryPoint = LoadExecutable(path, moduleRange); + + LOADEDMODULE loadedModule; + loadedModule.name = GetModuleNameFromPath(path); + loadedModule.begin = moduleRange.first; + loadedModule.end = moduleRange.second; + m_loadedModules.push_back(loadedModule); + + uint32 threadId = CreateThread(entryPoint, DEFAULT_PRIORITY); + THREAD& thread = GetThread(threadId); + + typedef vector ParamListType; + ParamListType paramList; + + paramList.push_back(Push( + thread.context.gpr[CMIPS::SP], + reinterpret_cast(path), + static_cast(strlen(path)) + 1)); + if(argsLength != 0 && args != NULL) + { + paramList.push_back(Push( + thread.context.gpr[CMIPS::SP], + reinterpret_cast(args), + static_cast(strlen(args)) + 1)); + } + thread.context.gpr[CMIPS::A0] = static_cast(paramList.size()); + for(ParamListType::reverse_iterator param(paramList.rbegin()); + paramList.rend() != param; param++) + { + thread.context.gpr[CMIPS::A1] = Push( + thread.context.gpr[CMIPS::SP], + reinterpret_cast(&(*param)), + 4); + } + + StartThread(threadId); + if(m_currentThreadId == -1) + { + Reschedule(); + } + +#ifdef _DEBUG + LoadModuleTags(loadedModule, m_cpu.m_Comments, "comments"); + LoadModuleTags(loadedModule, m_cpu.m_Functions, "functions"); + m_cpu.m_pAnalysis->Analyse(moduleRange.first, moduleRange.second); +#endif + + for(int i = 0; i < 0x00400000 / 4; i++) + { + uint32 nVal = ((uint32*)m_ram)[i]; +// if(nVal == 0x34C00) +// { +// printf("Allo: 0x%0.8X\r\n", i * 4); +// } +/* + if((nVal & 0xFFFF) == 0xB730) + { + char mnemonic[256]; + m_cpu.m_pArch->GetInstructionMnemonic(&m_cpu, i * 4, nVal, mnemonic, 256); + printf("Allo: %s, 0x%0.8X\r\n", mnemonic, i * 4); + } +*/ +/* + if(nVal == 0x2F9B50) + { + printf("Allo: 0x%0.8X\r\n", i * 4); + } +*/ + + if((nVal & 0xFC000000) == 0x0C000000) + { + nVal &= 0x3FFFFFF; + nVal *= 4; + if(nVal == 0x41410) + { + printf("Allo: 0x%0.8X\r\n", i * 4); + } + } + + } + + *reinterpret_cast(&m_ram[0x41674]) = 0; +} + +CIopBios::THREAD& CIopBios::GetThread(uint32 threadId) +{ + return GetThreadPosition(threadId)->second; +} + +CIopBios::ThreadMapType::iterator CIopBios::GetThreadPosition(uint32 threadId) +{ + for(ThreadMapType::iterator thread(m_threads.begin()); + thread != m_threads.end(); thread++) + { + if(thread->second.id == threadId) + { + return thread; + } + } + throw runtime_error("Unexisting thread id."); +} + +uint32 CIopBios::CreateThread(uint32 threadProc, uint32 priority) +{ + THREAD thread; + memset(&thread, 0, sizeof(thread)); + thread.context.delayJump = 1; + uint32 stackBaseAddress = m_sysmem->AllocateMemory(DEFAULT_STACKSIZE, 0); + thread.id = m_nextThreadId++; + thread.priority = priority; + thread.status = THREAD_STATUS_CREATED; + thread.context.epc = threadProc; + thread.nextActivateTime = 0; + thread.context.gpr[CMIPS::RA] = m_threadFinishAddress; + thread.context.gpr[CMIPS::SP] = stackBaseAddress; + m_threads.insert(ThreadMapType::value_type(thread.priority, thread)); + return thread.id; +} + +void CIopBios::StartThread(uint32 threadId, uint32* param) +{ + THREAD& thread = GetThread(threadId); + if(thread.status != THREAD_STATUS_CREATED) + { + throw runtime_error("Invalid thread state."); + } + thread.status = THREAD_STATUS_RUNNING; + if(param != NULL) + { + thread.context.gpr[CMIPS::A0] = *param; + } + m_rescheduleNeeded = true; +} + +void CIopBios::DelayThread(uint32 delay) +{ + //TODO : Need to delay or something... + THREAD& thread = GetThread(m_currentThreadId); + thread.nextActivateTime = GetCurrentTime() + delay; + m_rescheduleNeeded = true; +} + +void CIopBios::SleepThread() +{ + THREAD& thread = GetThread(m_currentThreadId); + if(thread.status != THREAD_STATUS_RUNNING) + { + throw runtime_error("Thread isn't running."); + } + if(thread.wakeupCount == 0) + { + thread.status = THREAD_STATUS_SLEEPING; + m_rescheduleNeeded = true; + } + else + { + thread.wakeupCount--; + } +} + +uint32 CIopBios::WakeupThread(uint32 threadId) +{ + THREAD& thread = GetThread(threadId); + if(thread.status == THREAD_STATUS_SLEEPING) + { + thread.status = THREAD_STATUS_RUNNING; + m_rescheduleNeeded = true; + } + else + { + thread.wakeupCount++; + } + return thread.wakeupCount; +} + +uint32 CIopBios::GetThreadId() +{ + return m_currentThreadId; +} + +void CIopBios::ExitCurrentThread() +{ + ThreadMapType::iterator thread = GetThreadPosition(m_currentThreadId); + m_threads.erase(thread); + m_currentThreadId = -1; + m_rescheduleNeeded = true; +} + +void CIopBios::LoadThreadContext(uint32 threadId) +{ + THREAD& thread = GetThread(threadId); + for(unsigned int i = 0; i < 32; i++) + { + if(i == CMIPS::R0) continue; + if(i == CMIPS::K0) continue; + if(i == CMIPS::K1) continue; + m_cpu.m_State.nGPR[i].nD0 = static_cast(thread.context.gpr[i]); + } + m_cpu.m_State.nPC = thread.context.epc; + m_cpu.m_State.nDelayedJumpAddr = thread.context.delayJump; +} + +void CIopBios::SaveThreadContext(uint32 threadId) +{ + THREAD& thread = GetThread(threadId); + for(unsigned int i = 0; i < 32; i++) + { + if(i == CMIPS::R0) continue; + if(i == CMIPS::K0) continue; + if(i == CMIPS::K1) continue; + thread.context.gpr[i] = m_cpu.m_State.nGPR[i].nV0; + } + thread.context.epc = m_cpu.m_State.nPC; + thread.context.delayJump = m_cpu.m_State.nDelayedJumpAddr; +} + +void CIopBios::Reschedule() +{ + if(m_currentThreadId != -1) + { + SaveThreadContext(m_currentThreadId); + //Reinsert the thread into the map + ThreadMapType::iterator threadPosition = GetThreadPosition(m_currentThreadId); + THREAD thread(threadPosition->second); + m_threads.erase(threadPosition); + m_threads.insert(ThreadMapType::value_type(thread.priority, thread)); + } + + uint32 nextThreadId = GetNextReadyThread(true); + if(nextThreadId == -1) + { + //Try without checking activation time + nextThreadId = GetNextReadyThread(false); + if(nextThreadId == -1) + { + throw runtime_error("No thread available for running."); + } + } + + LoadThreadContext(nextThreadId); + m_currentThreadId = nextThreadId; + m_cpu.m_nQuota = 1; +} + +uint32 CIopBios::GetNextReadyThread(bool checkActivateTime) +{ + if(checkActivateTime) + { + for(ThreadMapType::const_iterator thread(m_threads.begin()); + thread != m_threads.end(); thread++) + { + const THREAD& nextThread = thread->second; + if(GetCurrentTime() <= nextThread.nextActivateTime) continue; + if(nextThread.status == THREAD_STATUS_RUNNING) + { + return nextThread.id; + } + } + return -1; + } + else + { + //Find the thread with the earliest wakeup time + uint64 activateTime = -1; + uint32 nextThreadId = -1; + for(ThreadMapType::const_iterator thread(m_threads.begin()); + thread != m_threads.end(); thread++) + { + const THREAD& nextThread = thread->second; + if(nextThread.status != THREAD_STATUS_RUNNING) continue; + if(nextThread.nextActivateTime < activateTime) + { + nextThreadId = nextThread.id; + } + } + return nextThreadId; + } +} + +uint64 CIopBios::GetCurrentTime() +{ + return (clock() * 1000) / CLOCKS_PER_SEC; +} + +CIopBios::SEMAPHORE& CIopBios::GetSemaphore(uint32 semaphoreId) +{ + SemaphoreMapType::iterator semaphore(m_semaphores.find(semaphoreId)); + if(semaphore == m_semaphores.end()) + { + throw runtime_error("Invalid semaphore id."); + } + return semaphore->second; +} + +uint32 CIopBios::CreateSemaphore(uint32 initialCount, uint32 maxCount) +{ + SEMAPHORE semaphore; + memset(&semaphore, 0, sizeof(SEMAPHORE)); + semaphore.count = initialCount; + semaphore.maxCount = maxCount; + semaphore.id = m_nextSemaphoreId++; + semaphore.waitCount = 0; + m_semaphores[semaphore.id] = semaphore; + return semaphore.id; +} + +uint32 CIopBios::SignalSemaphore(uint32 semaphoreId) +{ + SEMAPHORE& semaphore = GetSemaphore(semaphoreId); + if(semaphore.waitCount != 0) + { + for(ThreadMapType::iterator threadIterator(m_threads.begin()); + m_threads.end() != threadIterator; ++threadIterator) + { + THREAD& thread(threadIterator->second); + if(thread.waitSemaphore == semaphoreId) + { + if(thread.status != THREAD_STATUS_WAITING) + { + throw runtime_error("Thread not waiting (inconsistent state)."); + } + thread.status = THREAD_STATUS_RUNNING; + thread.waitSemaphore = 0; + m_rescheduleNeeded = true; + semaphore.waitCount--; + if(semaphore.waitCount == 0) + { + break; + } + } + } + } + else + { + semaphore.count++; + } + return semaphore.count; +} + +uint32 CIopBios::WaitSemaphore(uint32 semaphoreId) +{ + SEMAPHORE& semaphore = GetSemaphore(semaphoreId); + if(semaphore.count == 0) + { + THREAD& thread = GetThread(m_currentThreadId); + thread.status = THREAD_STATUS_WAITING; + thread.waitSemaphore = semaphoreId; + semaphore.waitCount++; + m_rescheduleNeeded = true; + } + else + { + semaphore.count--; + } + return semaphore.count; +} + +Iop::CIoman* CIopBios::GetIoman() +{ + return m_ioman; +} + +uint32 CIopBios::AssembleThreadFinish(CMIPSAssembler& assembler) +{ + uint32 address = m_baseAddress + assembler.GetProgramSize(); + assembler.ADDIU(CMIPS::V0, CMIPS::R0, 0x0666); + assembler.SYSCALL(); + return address; +} + +void CIopBios::SysCallHandler() +{ + uint32 searchAddress = m_cpu.m_State.nCOP0[CCOP_SCU::EPC]; + uint32 callInstruction = m_cpu.m_pMemoryMap->GetWord(searchAddress); + if(callInstruction == 0x0000000C) + { + if(m_cpu.m_State.nGPR[CMIPS::V0].nV0 == 0x666) + { + ExitCurrentThread(); + } + } + else + { + //Search for the import record + uint32 instruction = callInstruction; + while(instruction != 0x41E00000) + { + searchAddress -= 4; + instruction = m_cpu.m_pMemoryMap->GetWord(searchAddress); + } + uint32 functionId = callInstruction & 0xFFFF; + uint32 version = m_cpu.m_pMemoryMap->GetWord(searchAddress + 8); + string moduleName = ReadModuleName(searchAddress + 0x0C); + + IopModuleMapType::iterator module(m_modules.find(moduleName)); + if(module != m_modules.end()) + { + module->second->Invoke(m_cpu, functionId); + } + else + { +#ifdef _DEBUG + CLog::GetInstance().Print(LOGNAME, "%0.8X: Trying to call a function from non-existing module (%s, %d).\r\n", + m_cpu.m_State.nPC, moduleName.c_str(), functionId); +#endif + } + } + + if(m_rescheduleNeeded) + { + m_rescheduleNeeded = false; + Reschedule(); + } + + m_cpu.m_State.nHasException = 0; +} + +string CIopBios::GetModuleNameFromPath(const std::string& path) +{ + string::size_type slashPosition; + slashPosition = path.rfind('/'); + if(slashPosition != string::npos) + { + return string(path.begin() + slashPosition + 1, path.end()); + } + return path; +} + +const CIopBios::LOADEDMODULE& CIopBios::GetModuleAtAddress(uint32 address) +{ + for(LoadedModuleListType::const_iterator moduleIterator(m_loadedModules.begin()); + m_loadedModules.end() != moduleIterator; moduleIterator++) + { + const LOADEDMODULE& module(*moduleIterator); + if(address >= module.begin && address <= module.end) + { + return module; + } + } + throw runtime_error("No module at specified address."); +} + +void CIopBios::LoadModuleTags(const LOADEDMODULE& module, CMIPSTags& tags, const char* tagCollectionName) +{ + CMIPSTags moduleTags; + moduleTags.Unserialize((module.name + "." + string(tagCollectionName)).c_str()); + for(CMIPSTags::TagIterator tag(moduleTags.GetTagsBegin()); + tag != moduleTags.GetTagsEnd(); tag++) + { + tags.InsertTag(tag->first + module.begin, tag->second.c_str()); + } + tags.m_OnTagListChanged(); +} + +void CIopBios::SaveAllModulesTags(CMIPSTags& tags, const char* tagCollectionName) +{ + for(LoadedModuleListType::const_iterator moduleIterator(m_loadedModules.begin()); + m_loadedModules.end() != moduleIterator; moduleIterator++) + { + const LOADEDMODULE& module(*moduleIterator); + CMIPSTags moduleTags; + for(CMIPSTags::TagIterator tag(tags.GetTagsBegin()); + tag != tags.GetTagsEnd(); tag++) + { + uint32 tagAddress = tag->first; + if(tagAddress >= module.begin && tagAddress <= module.end) + { + moduleTags.InsertTag(tagAddress - module.begin, tag->second.c_str()); + } + } + moduleTags.Serialize((module.name + "." + string(tagCollectionName)).c_str()); + } +} + +void CIopBios::DeleteModules() +{ + while(m_modules.size() != 0) + { + delete m_modules.begin()->second; + m_modules.erase(m_modules.begin()); + } +} + +string CIopBios::ReadModuleName(uint32 address) +{ + string moduleName; + while(1) + { + uint8 character = m_cpu.m_pMemoryMap->GetByte(address++); + if(character == 0) break; + if(character < 0x10) continue; + moduleName += character; + } + return moduleName; +} + +void CIopBios::RegisterModule(Iop::CModule* module) +{ + m_modules[module->GetId()] = module; +} + +uint32 CIopBios::Push(uint32& address, const uint8* data, uint32 size) +{ + uint32 fixedSize = ((size + 0x3) / 0x4) * 0x4; + address -= fixedSize; + memcpy(&m_ram[address], data, size); + return address; +} + +uint32 CIopBios::LoadExecutable(const char* path, ExecutableRange& executableRange) +{ + uint32 handle = m_ioman->Open(Iop::Ioman::CDevice::O_RDONLY, path); + if(handle & 0x80000000) + { + throw runtime_error("Couldn't open executable for reading."); + } + Iop::CIoman::CFile file(handle, *m_ioman); + CStream* stream = m_ioman->GetFileStream(file); + CELF elf(stream); + + unsigned int programHeaderIndex = GetElfProgramToLoad(elf); + if(programHeaderIndex == -1) + { + throw runtime_error("No program to load."); + } + ELFPROGRAMHEADER* programHeader = elf.GetProgram(programHeaderIndex); +// uint32 baseAddress = m_sysmem->AllocateMemory(elf.m_nLenght, 0); + uint32 baseAddress = m_sysmem->AllocateMemory(programHeader->nMemorySize, 0); + RelocateElf(elf, baseAddress); + + memcpy( + m_ram + baseAddress, + elf.m_pData + programHeader->nOffset, + programHeader->nFileSize); + + executableRange.first = baseAddress; + executableRange.second = baseAddress + programHeader->nMemorySize; + return baseAddress + elf.m_Header.nEntryPoint; +} + +unsigned int CIopBios::GetElfProgramToLoad(CELF& elf) +{ + unsigned int program = -1; + for(unsigned int i = 0; i < elf.m_Header.nProgHeaderCount; i++) + { + ELFPROGRAMHEADER* programHeader = elf.GetProgram(i); + if(programHeader != NULL && programHeader->nType == 1) + { + if(program != -1) + { + throw runtime_error("Multiple loadable program headers found."); + } + program = i; + } + } + return program; +} + +void CIopBios::RelocateElf(CELF& elf, uint32 baseAddress) +{ + //Process relocation + for(unsigned int i = 0; i < elf.m_Header.nSectHeaderCount; i++) + { + ELFSECTIONHEADER* sectionHeader = elf.GetSection(i); + if(sectionHeader != NULL && sectionHeader->nType == CELF::SHT_REL) + { + uint32 lastHi16 = -1; + uint32 instructionHi16 = -1; + unsigned int linkedSection = sectionHeader->nInfo; + unsigned int recordCount = sectionHeader->nSize / 8; + ELFSECTIONHEADER* relocatedSection = elf.GetSection(linkedSection); + const uint32* relocationRecord = reinterpret_cast(elf.GetSectionData(i)); + uint8* relocatedSectionData = reinterpret_cast(const_cast(elf.GetSectionData(linkedSection))); + if(relocatedSection == NULL || relocationRecord == NULL || relocatedSection == NULL) continue; + uint32 sectionBase = relocatedSection->nStart; + for(unsigned int record = 0; record < recordCount; record++) + { + uint32 relocationAddress = relocationRecord[0] - sectionBase; + uint32 relocationType = relocationRecord[1]; + if(relocationAddress < relocatedSection->nSize) + { + uint32& instruction = *reinterpret_cast(&relocatedSectionData[relocationAddress]); + switch(relocationType) + { + case CELF::R_MIPS_32: + { + instruction += baseAddress; + } + break; + case CELF::R_MIPS_26: + { + uint32 offset = (instruction & 0x03FFFFFF) + (baseAddress >> 2); + instruction &= ~0x03FFFFFF; + instruction |= offset; + } + break; + case CELF::R_MIPS_HI16: + { + lastHi16 = relocationAddress; + instructionHi16 = instruction; + } + break; + case CELF::R_MIPS_LO16: + { + if(lastHi16 != -1) + { + uint32 offset = static_cast(instruction) + (instructionHi16 << 16); + offset += baseAddress; + instruction &= ~0xFFFF; + instruction |= offset & 0xFFFF; + + uint32& prevInstruction = *reinterpret_cast(&relocatedSectionData[lastHi16]); + prevInstruction &= ~0xFFFF; + if(offset & 0x8000) offset += 0x10000; + prevInstruction |= offset >> 16; + lastHi16 = -1; + } + else + { +#ifdef _DEBUG + CLog::GetInstance().Print(LOGNAME, "%s: No HI16 relocation record found for corresponding LO16.\r\n", + __FUNCTION__); +#endif + } + } + break; + default: + throw runtime_error("Unknown relocation type."); + break; + } + } + relocationRecord += 2; + } + } + } +} diff --git a/Source/iop/IopBios.h b/Source/iop/IopBios.h new file mode 100644 index 00000000..2067e082 --- /dev/null +++ b/Source/iop/IopBios.h @@ -0,0 +1,142 @@ +#ifndef _IOPBIOS_H_ +#define _IOPBIOS_H_ + +#include +#include "../MIPSAssembler.h" +#include "../MIPS.h" +#include "../ELF.h" +#include "../SIF.h" +#include "Iop_Ioman.h" +#include "Iop_Stdio.h" +#include "Iop_Sysmem.h" +#include "Iop_Modload.h" + +class CIopBios +{ +public: + CIopBios(uint32, CMIPS&, uint8*, uint32, CSIF&); + virtual ~CIopBios(); + + void LoadAndStartModule(const char*, const char*, unsigned int); + void SysCallHandler(); + + void Reset(); + + Iop::CIoman* GetIoman(); + void RegisterModule(Iop::CModule*); + + uint32 CreateThread(uint32, uint32); + void StartThread(uint32, uint32* = NULL); + void DelayThread(uint32); + uint32 GetThreadId(); + void SleepThread(); + uint32 WakeupThread(uint32); + + uint32 CreateSemaphore(uint32, uint32); + uint32 SignalSemaphore(uint32); + uint32 WaitSemaphore(uint32); + +private: + enum DEFAULT_STACKSIZE + { + DEFAULT_STACKSIZE = 0x8000, + }; + + enum DEFAULT_PRIORITY + { + DEFAULT_PRIORITY = 7, + }; + + struct THREADCONTEXT + { + uint32 gpr[0x20]; + uint32 epc; + uint32 delayJump; + }; + + struct THREAD + { + uint32 id; + uint32 priority; + THREADCONTEXT context; + uint32 status; + uint32 waitSemaphore; + uint32 wakeupCount; + uint64 nextActivateTime; + }; + + struct SEMAPHORE + { + uint32 id; + uint32 count; + uint32 maxCount; + uint32 waitCount; + }; + + struct LOADEDMODULE + { + std::string name; + uint32 begin; + uint32 end; + }; + + enum THREAD_STATUS + { + THREAD_STATUS_CREATED = 1, + THREAD_STATUS_RUNNING = 2, + THREAD_STATUS_SLEEPING = 3, + THREAD_STATUS_ZOMBIE = 4, + THREAD_STATUS_WAITING = 5, + }; + + typedef std::multimap > ThreadMapType; + typedef std::map IopModuleMapType; + typedef std::map SemaphoreMapType; + typedef std::list LoadedModuleListType; + typedef std::pair ExecutableRange; + + THREAD& GetThread(uint32); + ThreadMapType::iterator GetThreadPosition(uint32); + void ExitCurrentThread(); + void LoadThreadContext(uint32); + void SaveThreadContext(uint32); + void Reschedule(); + uint32 GetNextReadyThread(bool); + uint64 GetCurrentTime(); + + SEMAPHORE& GetSemaphore(uint32); + + uint32 LoadExecutable(const char*, ExecutableRange&); + unsigned int GetElfProgramToLoad(CELF&); + void RelocateElf(CELF&, uint32); + std::string ReadModuleName(uint32); + std::string GetModuleNameFromPath(const std::string&); + const LOADEDMODULE& GetModuleAtAddress(uint32); + void LoadModuleTags(const LOADEDMODULE&, CMIPSTags&, const char*); + void SaveAllModulesTags(CMIPSTags&, const char*); + void DeleteModules(); + uint32 Push(uint32&, const uint8*, uint32); + + uint32 AssembleThreadFinish(CMIPSAssembler&); + + CMIPS& m_cpu; + CSIF& m_sif; + uint8* m_ram; + uint32 m_ramSize; + uint32 m_baseAddress; + uint32 m_threadFinishAddress; + uint32 m_nextThreadId; + uint32 m_nextSemaphoreId; + uint32 m_currentThreadId; + bool m_rescheduleNeeded; + ThreadMapType m_threads; + SemaphoreMapType m_semaphores; + IopModuleMapType m_modules; + LoadedModuleListType m_loadedModules; + Iop::CStdio* m_stdio; + Iop::CIoman* m_ioman; + Iop::CSysmem* m_sysmem; + Iop::CModload* m_modload; +}; + +#endif diff --git a/Source/iop/Iop_Dynamic.cpp b/Source/iop/Iop_Dynamic.cpp new file mode 100644 index 00000000..fdef02d0 --- /dev/null +++ b/Source/iop/Iop_Dynamic.cpp @@ -0,0 +1,28 @@ +#include "Iop_Dynamic.h" + +using namespace std; +using namespace Iop; + +CDynamic::CDynamic(uint32* exportTable) : +m_exportTable(exportTable), +m_name(reinterpret_cast(m_exportTable) + 12) +{ + +} + +CDynamic::~CDynamic() +{ + +} + +string CDynamic::GetId() const +{ + return m_name; +} + +void CDynamic::Invoke(CMIPS& context, unsigned int functionId) +{ + uint32 functionAddress = m_exportTable[5 + functionId]; + context.m_State.nGPR[CMIPS::RA].nD0 = context.m_State.nPC; + context.m_State.nPC = functionAddress; +} diff --git a/Source/iop/Iop_Dynamic.h b/Source/iop/Iop_Dynamic.h new file mode 100644 index 00000000..87ca3153 --- /dev/null +++ b/Source/iop/Iop_Dynamic.h @@ -0,0 +1,23 @@ +#ifndef _IOP_DYNAMIC_H_ +#define _IOP_DYNAMIC_H_ + +#include "Iop_Module.h" + +namespace Iop +{ + class CDynamic : public CModule + { + public: + CDynamic(uint32*); + virtual ~CDynamic(); + + std::string GetId() const; + void Invoke(CMIPS&, unsigned int); + + private: + uint32* m_exportTable; + std::string m_name; + }; +} + +#endif diff --git a/Source/iop/Iop_Intc.cpp b/Source/iop/Iop_Intc.cpp new file mode 100644 index 00000000..a4dead23 --- /dev/null +++ b/Source/iop/Iop_Intc.cpp @@ -0,0 +1,40 @@ +#include "Iop_Intc.h" + +using namespace Iop; + +CIntc::CIntc() : +m_mask(0), +m_status(0) +{ + +} + +CIntc::~CIntc() +{ + +} + +void CIntc::AssertLine(unsigned int line) +{ + m_status |= 1 << line; +} + +void CIntc::ClearLine(unsigned int line) +{ + m_status &= ~(1 << line); +} + +void CIntc::SetMask(uint32 mask) +{ + m_mask = mask; +} + +void CIntc::SetStatus(uint32 status) +{ + m_status = status; +} + +bool CIntc::HasPendingInterrupt() +{ + return (m_mask & m_status) != 0; +} diff --git a/Source/iop/Iop_Intc.h b/Source/iop/Iop_Intc.h new file mode 100644 index 00000000..fc9d8997 --- /dev/null +++ b/Source/iop/Iop_Intc.h @@ -0,0 +1,26 @@ +#ifndef _IOP_INTC_H_ +#define _IOP_INTC_H_ + +#include "Types.h" + +namespace Iop +{ + class CIntc + { + public: + CIntc(); + virtual ~CIntc(); + + void AssertLine(unsigned int); + void ClearLine(unsigned int); + void SetStatus(uint32); + void SetMask(uint32); + bool HasPendingInterrupt(); + + private: + uint32 m_status; + uint32 m_mask; + }; +} + +#endif diff --git a/Source/iop/Iop_Intrman.cpp b/Source/iop/Iop_Intrman.cpp new file mode 100644 index 00000000..48f3d97d --- /dev/null +++ b/Source/iop/Iop_Intrman.cpp @@ -0,0 +1,91 @@ +#include "Iop_Intrman.h" +#include "../Log.h" +#include "../COP_SCU.h" + +#define LOGNAME "iop_intrman" + +using namespace Iop; +using namespace std; + +CIntrman::CIntrman(uint8* ram) : +m_ram(ram) +{ + +} + +CIntrman::~CIntrman() +{ + +} + +string CIntrman::GetId() const +{ + return "intrman"; +} + +void CIntrman::Invoke(CMIPS& context, unsigned int functionId) +{ + switch(functionId) + { + case 9: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(EnableInterrupts( + context + )); + break; + case 17: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(SuspendInterrupts( + context, + reinterpret_cast(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]) + )); + break; + case 18: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(ResumeInterrupts( + context, + context.m_State.nGPR[CMIPS::A0].nV0 + )); + break; + case 23: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(QueryIntrContext( + context + )); + break; + default: + CLog::GetInstance().Print(LOGNAME, "%0.8X: Unknown function (%d) called.\r\n", context.m_State.nPC, functionId); + break; + } +} + +uint32 CIntrman::EnableInterrupts(CMIPS& context) +{ + uint32& statusRegister = context.m_State.nCOP0[CCOP_SCU::STATUS]; + statusRegister |= 1; + return 0; +} + +uint32 CIntrman::SuspendInterrupts(CMIPS& context, uint32* state) +{ + uint32& statusRegister = context.m_State.nCOP0[CCOP_SCU::STATUS]; + (*state) = statusRegister & 1; + statusRegister &= ~1; + return 0; +} + +uint32 CIntrman::ResumeInterrupts(CMIPS& context, uint32 state) +{ + uint32& statusRegister = context.m_State.nCOP0[CCOP_SCU::STATUS]; + if(state) + { + statusRegister |= 1; + } + else + { + statusRegister &= ~1; + } + return 0; +} + +uint32 CIntrman::QueryIntrContext(CMIPS& context) +{ + uint32& statusRegister = context.m_State.nCOP0[CCOP_SCU::STATUS]; + return (statusRegister & 0x02 ? 1 : 0); +} diff --git a/Source/iop/Iop_Intrman.h b/Source/iop/Iop_Intrman.h new file mode 100644 index 00000000..48c588e0 --- /dev/null +++ b/Source/iop/Iop_Intrman.h @@ -0,0 +1,27 @@ +#ifndef _IOP_INTRMAN_H_ +#define _IOP_INTRMAN_H_ + +#include "Iop_Module.h" + +namespace Iop +{ + class CIntrman : public CModule + { + public: + CIntrman(uint8*); + virtual ~CIntrman(); + + std::string GetId() const; + void Invoke(CMIPS&, unsigned int); + + private: + uint32 EnableInterrupts(CMIPS&); + uint32 SuspendInterrupts(CMIPS&, uint32*); + uint32 ResumeInterrupts(CMIPS&, uint32); + uint32 QueryIntrContext(CMIPS&); + uint8* m_ram; + }; +} + +#endif + diff --git a/Source/iop/Iop_Ioman.cpp b/Source/iop/Iop_Ioman.cpp new file mode 100644 index 00000000..c7cf9208 --- /dev/null +++ b/Source/iop/Iop_Ioman.cpp @@ -0,0 +1,277 @@ +#include "../Config.h" +#include "Iop_Ioman.h" +#include "StdStream.h" +#include + +using namespace Iop; +using namespace std; +using namespace Framework; + +#define PREF_IOP_FILEIO_STDLOGGING ("iop.fileio.stdlogging") + +CIoman::CIoman(uint8* ram, CSIF& sif) : +m_ram(ram), +m_nextFileHandle(3) +{ + CConfig::GetInstance()->RegisterPreferenceBoolean(PREF_IOP_FILEIO_STDLOGGING, false); + sif.RegisterModule(SIF_MODULE_ID, this); + + //Insert standard files if requested. + if(CConfig::GetInstance()->GetPreferenceBoolean(PREF_IOP_FILEIO_STDLOGGING)) + { + try + { + m_files[1] = new CStdStream(fopen("ps2_stdout.txt", "ab")); + m_files[2] = new CStdStream(fopen("ps2_stderr.txt", "ab")); + } + catch(...) + { + //Humm, some error occured when opening these files... + } + } +} + +CIoman::~CIoman() +{ + for(FileMapType::iterator fileIterator(m_files.begin()); + m_files.end() != fileIterator; fileIterator++) + { + delete fileIterator->second; + } + for(DeviceMapType::iterator deviceIterator(m_devices.begin()); + m_devices.end() != deviceIterator; deviceIterator++) + { + delete deviceIterator->second; + } +} + +std::string CIoman::GetId() const +{ + return "ioman"; +} + +void CIoman::RegisterDevice(const char* name, Ioman::CDevice* device) +{ + m_devices[name] = device; +} + +uint32 CIoman::Open(uint32 flags, const char* path) +{ + uint32 handle = 0xFFFFFFFF; + try + { + string fullPath(path); + string::size_type position = fullPath.find(":"); + if(position == string::npos) + { + throw runtime_error("Invalid path."); + } + string deviceName(fullPath.begin(), fullPath.begin() + position); + string devicePath(fullPath.begin() + position + 1, fullPath.end()); + DeviceMapType::iterator device(m_devices.find(deviceName)); + if(device == m_devices.end()) + { + throw runtime_error("Device not found."); + } + CStream* stream = device->second->GetFile(flags, devicePath.c_str()); + if(stream == NULL) + { + throw runtime_error("File not found."); + } + handle = m_nextFileHandle++; + m_files[handle] = stream; + } + catch(const exception& except) + { + printf("%s: Error occured while trying to open file : %s\r\n", __FUNCTION__, except.what()); + } + 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 + { + CStream* stream = GetFileStream(handle); + result = static_cast(stream->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::Write(uint32 handle, uint32 size, void* buffer) +{ + uint32 result = 0xFFFFFFFF; + try + { + CStream* stream = GetFileStream(handle); + result = static_cast(stream->Write(buffer, size)); + } + catch(const exception& except) + { + printf("%s: Error occured while trying to write file : %s\r\n", __FUNCTION__, except.what()); + } + return result; +} + +uint32 CIoman::Seek(uint32 handle, uint32 position, uint32 whence) +{ + uint32 result = 0xFFFFFFFF; + try + { + CStream* stream = GetFileStream(handle); + switch(whence) + { + case 0: + whence = STREAM_SEEK_SET; + break; + case 1: + whence = STREAM_SEEK_CUR; + break; + case 2: + whence = STREAM_SEEK_END; + break; + } + + stream->Seek(position, static_cast(whence)); + result = static_cast(stream->Tell()); + } + catch(const exception& except) + { + printf("%s: Error occured while trying to seek file : %s\r\n", __FUNCTION__, except.what()); + } + return result; +} + +uint32 CIoman::DelDrv(const char* deviceName) +{ + return -1; +} + +CStream* CIoman::GetFileStream(uint32 handle) +{ + FileMapType::iterator file(m_files.find(handle)); + if(file == m_files.end()) + { + throw runtime_error("Invalid file handle."); + } + return file->second; +} + +//IOP Invoke +void CIoman::Invoke(CMIPS& context, unsigned int functionId) +{ + switch(functionId) + { + case 4: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(Open( + context.m_State.nGPR[CMIPS::A1].nV[0], + 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], + 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(DelDrv( + reinterpret_cast(&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; + } +} + +//SIF Invoke +void CIoman::Invoke(uint32 method, uint32* args, uint32 argsSize, uint32* ret, uint32 retSize, uint8* ram) +{ + switch(method) + { + case 0: + assert(retSize == 4); + *ret = Open(*args, reinterpret_cast(args) + 4); + break; +/* + case 0x00000001: + assert(nRetSize == 4); + *(uint32*)pRet = Close(*(uint32*)pArgs); + break; +*/ + case 2: + assert(retSize == 4); + *ret = Read(args[0], args[2], reinterpret_cast(ram + args[1])); + break; + case 3: + assert(retSize == 4); + *ret = Write(args[0], args[2], reinterpret_cast(ram + args[1])); + break; + case 4: + assert(retSize == 4); + *ret = Seek(args[0], args[1], args[2]); + break; + default: + printf("%s: Unknown function (%d) called.\r\n", __FUNCTION__, method); + break; + } +} + +//-------------------------------------------------- +//-------------------------------------------------- + +CIoman::CFile::CFile(uint32 handle, CIoman& ioman) : +m_handle(handle), +m_ioman(ioman) +{ + +} + +CIoman::CFile::~CFile() +{ + m_ioman.Close(m_handle); +} + +CIoman::CFile::operator uint32() +{ + return m_handle; +} diff --git a/Source/iop/Iop_Ioman.h b/Source/iop/Iop_Ioman.h new file mode 100644 index 00000000..e85cf2cc --- /dev/null +++ b/Source/iop/Iop_Ioman.h @@ -0,0 +1,63 @@ +#ifndef _IOP_IOMAN_H_ +#define _IOP_IOMAN_H_ + +#include +#include "../Sif.h" +#include "Iop_Module.h" +#include "Ioman_Device.h" +#include "Stream.h" + +namespace Iop +{ + class CIoman : public CModule, public CSifModule + { + public: + class CFile + { + public: + CFile(uint32, CIoman&); + virtual ~CFile(); + + operator uint32(); + private: + uint32 m_handle; + CIoman& m_ioman; + }; + + enum SIF_MODULE_ID + { + SIF_MODULE_ID = 0x80000001 + }; + + CIoman(uint8*, CSIF&); + virtual ~CIoman(); + + virtual std::string GetId() const; + virtual void Invoke(CMIPS&, unsigned int); + virtual void Invoke(uint32, uint32*, uint32, uint32*, uint32, uint8*); + + void RegisterDevice(const char*, Ioman::CDevice*); + + uint32 Open(uint32, const char*); + uint32 Close(uint32); + uint32 Read(uint32, uint32, void*); + uint32 Write(uint32, uint32, void*); + uint32 Seek(uint32, uint32, uint32); + uint32 DelDrv(const char*); + + Framework::CStream* GetFileStream(uint32); + + private: + typedef std::map FileMapType; + typedef std::map DeviceMapType; + + void Open(CMIPS&); + + FileMapType m_files; + DeviceMapType m_devices; + uint8* m_ram; + uint32 m_nextFileHandle; + }; +} + +#endif diff --git a/Source/iop/Iop_Loadcore.cpp b/Source/iop/Iop_Loadcore.cpp new file mode 100644 index 00000000..f7fe1ec7 --- /dev/null +++ b/Source/iop/Iop_Loadcore.cpp @@ -0,0 +1,44 @@ +#include "Iop_Loadcore.h" +#include "Iop_Dynamic.h" +#include "IopBios.h" + +using namespace Iop; +using namespace std; + +CLoadcore::CLoadcore(CIopBios& bios, uint8* ram) : +m_bios(bios), +m_ram(ram) +{ + +} + +CLoadcore::~CLoadcore() +{ + +} + +string CLoadcore::GetId() const +{ + return "loadcore"; +} + +void CLoadcore::Invoke(CMIPS& context, unsigned int functionId) +{ + switch(functionId) + { + case 6: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(RegisterLibraryEntries( + reinterpret_cast(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]) + )); + break; + default: + printf("%s(%0.8X): Unknown function (%d) called.\r\n", __FUNCTION__, context.m_State.nPC, functionId); + break; + } +} + +uint32 CLoadcore::RegisterLibraryEntries(uint32* exportTable) +{ + m_bios.RegisterModule(new CDynamic(exportTable)); + return 1; +} diff --git a/Source/iop/Iop_Loadcore.h b/Source/iop/Iop_Loadcore.h new file mode 100644 index 00000000..de4a6ea3 --- /dev/null +++ b/Source/iop/Iop_Loadcore.h @@ -0,0 +1,27 @@ +#ifndef _IOP_LOADCORE_H_ +#define _IOP_LOADCORE_H_ + +#include "Iop_Module.h" + +class CIopBios; + +namespace Iop +{ + class CLoadcore : public CModule + { + public: + CLoadcore(CIopBios&, uint8*); + virtual ~CLoadcore(); + + std::string GetId() const; + void Invoke(CMIPS&, unsigned int); + + private: + uint32 RegisterLibraryEntries(uint32*); + + CIopBios& m_bios; + uint8* m_ram; + }; +} + +#endif diff --git a/Source/iop/Iop_Modload.cpp b/Source/iop/Iop_Modload.cpp new file mode 100644 index 00000000..c3aee2d8 --- /dev/null +++ b/Source/iop/Iop_Modload.cpp @@ -0,0 +1,54 @@ +#include "Iop_Modload.h" +#include "IopBios.h" + +using namespace Iop; +using namespace std; +using namespace Framework; + +CModload::CModload(CIopBios& bios, uint8* ram) : +m_bios(bios), +m_ram(ram) +{ + +} + +CModload::~CModload() +{ + +} + +string CModload::GetId() const +{ + return "modload"; +} + +void CModload::Invoke(CMIPS& context, unsigned int functionId) +{ + switch(functionId) + { + case 7: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(LoadStartModule( + reinterpret_cast(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]), + context.m_State.nGPR[CMIPS::A1].nV0, + reinterpret_cast(&m_ram[context.m_State.nGPR[CMIPS::A2].nV0]), + reinterpret_cast(&m_ram[context.m_State.nGPR[CMIPS::A3].nV0]) + )); + break; + default: + printf("%s(%0.8X): Unknown function (%d) called.\r\n", __FUNCTION__, context.m_State.nPC, functionId); + break; + } +} + +uint32 CModload::LoadStartModule(const char* path, uint32 argsLength, const char* args, uint32* result) +{ + try + { + m_bios.LoadAndStartModule(path, args, argsLength); + } + catch(const exception& except) + { + printf("%s: Error occured while trying to load module '%s' : %s\r\n", __FUNCTION__, path, except.what()); + } + return 0; +} diff --git a/Source/iop/Iop_Modload.h b/Source/iop/Iop_Modload.h new file mode 100644 index 00000000..be075896 --- /dev/null +++ b/Source/iop/Iop_Modload.h @@ -0,0 +1,26 @@ +#ifndef _IOP_MODLOAD_H_ +#define _IOP_MODLOAD_H_ + +#include "Iop_Module.h" + +class CIopBios; + +namespace Iop +{ + class CModload : public CModule + { + public: + CModload(CIopBios&, uint8*); + virtual ~CModload(); + + std::string GetId() const; + void Invoke(CMIPS&, unsigned int); + + private: + uint32 LoadStartModule(const char*, uint32, const char*, uint32*); + CIopBios& m_bios; + uint8* m_ram; + }; +} + +#endif diff --git a/Source/iop/Iop_Module.h b/Source/iop/Iop_Module.h new file mode 100644 index 00000000..d2a70dfe --- /dev/null +++ b/Source/iop/Iop_Module.h @@ -0,0 +1,21 @@ +#ifndef _IOP_MODULE_H_ +#define _IOP_MODULE_H_ + +#include +#include "../MIPS.h" + +namespace Iop +{ + class CModule + { + public: + virtual ~CModule() {} + virtual std::string GetId() const = 0; + virtual void Invoke(CMIPS&, unsigned int) = 0; + + private: + + }; +}; + +#endif diff --git a/Source/iop/Iop_Stdio.cpp b/Source/iop/Iop_Stdio.cpp new file mode 100644 index 00000000..a713664a --- /dev/null +++ b/Source/iop/Iop_Stdio.cpp @@ -0,0 +1,99 @@ +#include "Iop_Stdio.h" +#include +#include "lexical_cast_ex.h" + +using namespace Iop; +using namespace std; +using namespace boost; + +CStdio::CStdio(uint8* ram) : +m_ram(ram) +{ + +} + +CStdio::~CStdio() +{ + +} + +string CStdio::GetId() const +{ + return "stdio"; +} + +void CStdio::Invoke(CMIPS& context, unsigned int functionId) +{ + switch(functionId) + { + case 4: + __printf(context); + break; + default: + printf("%s(%0.8X): Unknown function (%d) called.", __FUNCTION__, context.m_State.nPC, functionId); + break; + } +} + +string CStdio::PrintFormatted(CArgumentIterator& args) +{ + string output; + const char* format = reinterpret_cast(&m_ram[args.GetNext()]); + while(*format != 0) + { + char character = *(format++); + if(character == '%') + { + bool paramDone = false; + bool inPrecision = false; + string precision; + while(!paramDone && *format != 0) + { + char type = *(format++); + if(type == 's') + { + const char* text = reinterpret_cast(&m_ram[args.GetNext()]); + output += text; + paramDone = true; + } + else if(type == 'd') + { + int number = args.GetNext(); + unsigned int precisionValue = precision.length() ? lexical_cast(precision) : 0; + output += lexical_cast(number); + paramDone = true; + } + else if(type == 'u') + { + unsigned int number = args.GetNext(); + unsigned int precisionValue = precision.length() ? lexical_cast(precision) : 0; + output += lexical_cast_uint(number, precisionValue); + paramDone = true; + } + else if(type == '.') + { + inPrecision = true; + } + else + { + if(inPrecision) + { + precision += type; + } + } + } + } + else + { + output += character; + } + } + return output; +} + +void CStdio::__printf(CMIPS& context) +{ + CArgumentIterator args(context); + string output = PrintFormatted(args); + printf("%s", output.c_str()); +} diff --git a/Source/iop/Iop_Stdio.h b/Source/iop/Iop_Stdio.h new file mode 100644 index 00000000..233d6a7b --- /dev/null +++ b/Source/iop/Iop_Stdio.h @@ -0,0 +1,25 @@ +#ifndef _IOP_STDIO_H_ +#define _IOP_STDIO_H_ + +#include "Iop_Module.h" +#include "ArgumentIterator.h" + +namespace Iop +{ + class CStdio : public CModule + { + public: + CStdio(uint8*); + virtual ~CStdio(); + + std::string GetId() const; + void Invoke(CMIPS&, unsigned int); + void __printf(CMIPS&); + std::string PrintFormatted(CArgumentIterator&); + + private: + uint8* m_ram; + }; +} + +#endif diff --git a/Source/iop/Iop_Sysclib.cpp b/Source/iop/Iop_Sysclib.cpp new file mode 100644 index 00000000..b91ac7c3 --- /dev/null +++ b/Source/iop/Iop_Sysclib.cpp @@ -0,0 +1,119 @@ +#include "Iop_Sysclib.h" + +using namespace Iop; +using namespace std; + +CSysclib::CSysclib(uint8* ram, CStdio& stdio) : +m_ram(ram), +m_stdio(stdio) +{ + +} + +CSysclib::~CSysclib() +{ + +} + +string CSysclib::GetId() const +{ + return "sysclib"; +} + +void CSysclib::Invoke(CMIPS& context, unsigned int functionId) +{ + switch(functionId) + { + case 12: + context.m_State.nGPR[CMIPS::V0].nD0 = context.m_State.nGPR[CMIPS::A0].nD0; + __memcpy( + &m_ram[context.m_State.nGPR[CMIPS::A0].nV0], + &m_ram[context.m_State.nGPR[CMIPS::A1].nV0], + context.m_State.nGPR[CMIPS::A2].nV0); + break; + case 14: + context.m_State.nGPR[CMIPS::V0].nD0 = context.m_State.nGPR[CMIPS::A0].nD0; + __memset( + &m_ram[context.m_State.nGPR[CMIPS::A0].nV0], + context.m_State.nGPR[CMIPS::A1].nV0, + context.m_State.nGPR[CMIPS::A2].nV0); + break; + case 17: + __memset( + &m_ram[context.m_State.nGPR[CMIPS::A0].nV0], + 0, + context.m_State.nGPR[CMIPS::A1].nV0); + break; + case 19: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(__sprintf(context)); + break; + case 23: + context.m_State.nGPR[CMIPS::V0].nD0 = context.m_State.nGPR[CMIPS::A0].nD0; + __strcpy( + reinterpret_cast(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]), + reinterpret_cast(&m_ram[context.m_State.nGPR[CMIPS::A1].nV0]) + ); + break; + case 27: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(__strlen( + reinterpret_cast(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]) + )); + break; + case 30: + context.m_State.nGPR[CMIPS::V0].nD0 = context.m_State.nGPR[CMIPS::A0].nD0; + __strncpy( + reinterpret_cast(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]), + reinterpret_cast(&m_ram[context.m_State.nGPR[CMIPS::A1].nV0]), + context.m_State.nGPR[CMIPS::A2].nV0); + break; + case 36: + assert(context.m_State.nGPR[CMIPS::A1].nV0 == 0); + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(__strtol( + reinterpret_cast(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]), + context.m_State.nGPR[CMIPS::A2].nV0 + )); + break; + default: + printf("%s(%0.8X): Unknown function (%d) called.\r\n", __FUNCTION__, context.m_State.nPC, functionId); + break; + } +} + +void CSysclib::__memcpy(void* dest, const void* src, unsigned int length) +{ + memcpy(dest, src, length); +} + +void CSysclib::__memset(void* dest, int character, unsigned int length) +{ + memset(dest, character, length); +} + +uint32 CSysclib::__sprintf(CMIPS& context) +{ + CArgumentIterator args(context); + char* destination = reinterpret_cast(&m_ram[args.GetNext()]); + string output = m_stdio.PrintFormatted(args); + strcpy(destination, output.c_str()); + return static_cast(output.length()); +} + +uint32 CSysclib::__strlen(const char* string) +{ + return static_cast(strlen(string)); +} + +void CSysclib::__strcpy(char* dst, const char* src) +{ + strcpy(dst, src); +} + +void CSysclib::__strncpy(char* dst, const char* src, unsigned int count) +{ + strncpy(dst, src, count); +} + +uint32 CSysclib::__strtol(const char* string, unsigned int radix) +{ + return strtol(string, NULL, radix); +} diff --git a/Source/iop/Iop_Sysclib.h b/Source/iop/Iop_Sysclib.h new file mode 100644 index 00000000..6881c7b3 --- /dev/null +++ b/Source/iop/Iop_Sysclib.h @@ -0,0 +1,31 @@ +#ifndef _IOP_SYSCLIB_H_ +#define _IOP_SYSCLIB_H_ + +#include "IOP_Module.h" +#include "IOP_Stdio.h" + +namespace Iop +{ + class CSysclib : public CModule + { + public: + CSysclib(uint8*, CStdio&); + virtual ~CSysclib(); + + std::string GetId() const; + void Invoke(CMIPS&, unsigned int); + + private: + void __memcpy(void*, const void*, unsigned int); + void __memset(void*, int, unsigned int); + uint32 __sprintf(CMIPS& context); + uint32 __strlen(const char*); + void __strcpy(char*, const char*); + void __strncpy(char*, const char*, unsigned int); + uint32 __strtol(const char*, unsigned int); + uint8* m_ram; + CStdio& m_stdio; + }; +} + +#endif diff --git a/Source/iop/Iop_Sysmem.cpp b/Source/iop/Iop_Sysmem.cpp new file mode 100644 index 00000000..7be94fdf --- /dev/null +++ b/Source/iop/Iop_Sysmem.cpp @@ -0,0 +1,86 @@ +#include "Iop_Sysmem.h" + +using namespace Iop; +using namespace std; + +CSysmem::CSysmem(uint32 memoryBegin, uint32 memoryEnd, CStdio& stdio) : +m_memoryBegin(memoryBegin), +m_memoryEnd(memoryEnd), +m_stdio(stdio), +m_memorySize(memoryEnd - memoryBegin) +{ + //Initialize block map + m_blockMap[m_memorySize] = 0; +} + +CSysmem::~CSysmem() +{ + +} + +string CSysmem::GetId() const +{ + return "sysmem"; +} + +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; + case 5: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(FreeMemory( + context.m_State.nGPR[CMIPS::A0].nV[0] + )); + break; + case 14: + m_stdio.__printf(context); + 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; +} + +uint32 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); + } + return 0; +} diff --git a/Source/iop/Iop_Sysmem.h b/Source/iop/Iop_Sysmem.h new file mode 100644 index 00000000..d9bae91c --- /dev/null +++ b/Source/iop/Iop_Sysmem.h @@ -0,0 +1,33 @@ +#ifndef _IOP_SYSMEM_H_ +#define _IOP_SYSMEM_H_ + +#include "Iop_Module.h" +#include "Iop_Stdio.h" + +namespace Iop +{ + class CSysmem : public CModule + { + public: + CSysmem(uint32, uint32, Iop::CStdio&); + virtual ~CSysmem(); + + std::string GetId() const; + void Invoke(CMIPS&, unsigned int); + + uint32 AllocateMemory(uint32, uint32); + uint32 FreeMemory(uint32); + + private: + typedef std::map BlockMapType; + + BlockMapType m_blockMap; + uint32 m_memoryBegin; + uint32 m_memoryEnd; + uint32 m_memorySize; + Iop::CStdio& m_stdio; + }; +} + + +#endif diff --git a/Source/iop/Iop_Thbase.cpp b/Source/iop/Iop_Thbase.cpp new file mode 100644 index 00000000..86353eee --- /dev/null +++ b/Source/iop/Iop_Thbase.cpp @@ -0,0 +1,92 @@ +#include "Iop_Thbase.h" +#include "IopBios.h" + +using namespace Iop; +using namespace std; + +CThbase::CThbase(CIopBios& bios, uint8* ram) : +m_ram(ram), +m_bios(bios) +{ + +} + +CThbase::~CThbase() +{ + +} + +string CThbase::GetId() const +{ + return "thbase"; +} + +void CThbase::Invoke(CMIPS& context, unsigned int functionId) +{ + switch(functionId) + { + case 4: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(CreateThread( + reinterpret_cast(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]) + )); + break; + case 6: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(StartThread( + context.m_State.nGPR[CMIPS::A0].nV0, + context.m_State.nGPR[CMIPS::A1].nV0 + )); + break; + case 20: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(GetThreadId()); + break; + case 24: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(SleepThread()); + break; + case 25: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(WakeupThread( + context.m_State.nGPR[CMIPS::A0].nV0 + )); + break; + case 33: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(DelayThread( + context.m_State.nGPR[CMIPS::A0].nV0 + )); + break; + default: + printf("%s(%0.8X): Unknown function (%d) called.\r\n", __FUNCTION__, context.m_State.nPC, functionId); + break; + } +} + +uint32 CThbase::CreateThread(const THREAD* thread) +{ + return m_bios.CreateThread(thread->threadProc, thread->priority); +} + +uint32 CThbase::StartThread(uint32 threadId, uint32 param) +{ + m_bios.StartThread(threadId, ¶m); + return 1; +} + +uint32 CThbase::DelayThread(uint32 delay) +{ + m_bios.DelayThread(delay); + return 1; +} + +uint32 CThbase::GetThreadId() +{ + return m_bios.GetThreadId(); +} + +uint32 CThbase::SleepThread() +{ + m_bios.SleepThread(); + return 1; +} + +uint32 CThbase::WakeupThread(uint32 threadId) +{ + return m_bios.WakeupThread(threadId); +} diff --git a/Source/iop/Iop_Thbase.h b/Source/iop/Iop_Thbase.h new file mode 100644 index 00000000..0d659ab8 --- /dev/null +++ b/Source/iop/Iop_Thbase.h @@ -0,0 +1,41 @@ +#ifndef _IOP_THBASE_H_ +#define _IOP_THBASE_H_ + +#include "Iop_Module.h" + +class CIopBios; + +namespace Iop +{ + class CThbase : public CModule + { + public: + CThbase(CIopBios&, uint8*); + virtual ~CThbase(); + + std::string GetId() const; + void Invoke(CMIPS&, unsigned int); + + private: + struct THREAD + { + uint32 attributes; + uint32 options; + uint32 threadProc; + uint32 stackSize; + uint32 priority; + }; + + uint32 CreateThread(const THREAD*); + uint32 StartThread(uint32, uint32); + uint32 DelayThread(uint32); + uint32 GetThreadId(); + uint32 SleepThread(); + uint32 WakeupThread(uint32); + + uint8* m_ram; + CIopBios& m_bios; + }; +} + +#endif diff --git a/Source/iop/Iop_Thevent.cpp b/Source/iop/Iop_Thevent.cpp new file mode 100644 index 00000000..26b688a4 --- /dev/null +++ b/Source/iop/Iop_Thevent.cpp @@ -0,0 +1,39 @@ +#include "Iop_Thevent.h" + +using namespace Iop; +using namespace std; + +CThevent::CThevent(CIopBios& bios, uint8* ram) : +m_bios(bios), +m_ram(ram) +{ + +} + +CThevent::~CThevent() +{ + +} + +string CThevent::GetId() const +{ + return "thevent"; +} + +void CThevent::Invoke(CMIPS& context, unsigned int functionId) +{ + switch(functionId) + { + case 4: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(CreateEventFlag()); + break; + default: + printf("%s(%0.8X): Unknown function (%d) called.\r\n", __FUNCTION__, context.m_State.nPC, functionId); + break; + } +} + +uint32 CThevent::CreateEventFlag() +{ + return 3; +} diff --git a/Source/iop/Iop_Thevent.h b/Source/iop/Iop_Thevent.h new file mode 100644 index 00000000..ec336ebe --- /dev/null +++ b/Source/iop/Iop_Thevent.h @@ -0,0 +1,27 @@ +#ifndef _IOP_THEVENT_H_ +#define _IOP_THEVENT_H_ + +#include "Iop_Module.h" + +class CIopBios; + +namespace Iop +{ + class CThevent : public CModule + { + public: + CThevent(CIopBios&, uint8*); + virtual ~CThevent(); + + std::string GetId() const; + void Invoke(CMIPS&, unsigned int); + + private: + uint32 CreateEventFlag(); + + uint8* m_ram; + CIopBios& m_bios; + }; +} + +#endif diff --git a/Source/iop/Iop_Thsema.cpp b/Source/iop/Iop_Thsema.cpp new file mode 100644 index 00000000..9cfa6cf8 --- /dev/null +++ b/Source/iop/Iop_Thsema.cpp @@ -0,0 +1,62 @@ +#include "Iop_Thsema.h" +#include "IopBios.h" + +using namespace Iop; +using namespace std; + +CThsema::CThsema(CIopBios& bios, uint8* ram) : +m_bios(bios), +m_ram(ram) +{ + +} + +CThsema::~CThsema() +{ + +} + +string CThsema::GetId() const +{ + return "thsemap"; +} + +void CThsema::Invoke(CMIPS& context, unsigned int functionId) +{ + switch(functionId) + { + case 4: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(CreateSemaphore( + reinterpret_cast(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]) + )); + break; + case 6: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(SignalSemaphore( + context.m_State.nGPR[CMIPS::A0].nV0 + )); + break; + case 8: + context.m_State.nGPR[CMIPS::V0].nD0 = static_cast(WaitSemaphore( + context.m_State.nGPR[CMIPS::A0].nV0 + )); + break; + default: + printf("%s(%0.8X): Unknown function (%d) called.\r\n", __FUNCTION__, context.m_State.nPC, functionId); + break; + } +} + +uint32 CThsema::CreateSemaphore(const SEMAPHORE* semaphore) +{ + return m_bios.CreateSemaphore(semaphore->initialCount, semaphore->maxCount); +} + +uint32 CThsema::SignalSemaphore(uint32 semaphoreId) +{ + return m_bios.SignalSemaphore(semaphoreId); +} + +uint32 CThsema::WaitSemaphore(uint32 semaphoreId) +{ + return m_bios.WaitSemaphore(semaphoreId); +} diff --git a/Source/iop/Iop_Thsema.h b/Source/iop/Iop_Thsema.h new file mode 100644 index 00000000..daf2045a --- /dev/null +++ b/Source/iop/Iop_Thsema.h @@ -0,0 +1,36 @@ +#ifndef _IOP_THSEMA_H_ +#define _IOP_THSEMA_H_ + +#include "Iop_Module.h" +#include "IopBios.h" + +namespace Iop +{ + class CThsema : public CModule + { + public: + CThsema(CIopBios&, uint8*); + virtual ~CThsema(); + + std::string GetId() const; + void Invoke(CMIPS&, unsigned int); + + private: + struct SEMAPHORE + { + uint32 attributes; + uint32 options; + uint32 initialCount; + uint32 maxCount; + }; + + uint32 CreateSemaphore(const SEMAPHORE*); + uint32 WaitSemaphore(uint32); + uint32 SignalSemaphore(uint32); + + uint8* m_ram; + CIopBios& m_bios; + }; +} + +#endif diff --git a/Source/iop/Iop_Timrman.cpp b/Source/iop/Iop_Timrman.cpp new file mode 100644 index 00000000..735b95c6 --- /dev/null +++ b/Source/iop/Iop_Timrman.cpp @@ -0,0 +1,34 @@ +#include "Iop_Timrman.h" + +using namespace Iop; +using namespace std; + +CTimrman::CTimrman() +{ + +} + +CTimrman::~CTimrman() +{ + +} + +string CTimrman::GetId() const +{ + return "timrman"; +} + +void CTimrman::Invoke(CMIPS& context, unsigned int functionId) +{ + switch(functionId) + { + case 20: + context.m_State.nGPR[CMIPS::V0].nD0 = 0; + printf("Timrman: Install handler.\r\n"); + break; + default: + printf("%s(%0.8X): Unknown function (%d) called.\r\n", __FUNCTION__, context.m_State.nPC, functionId); + break; + + } +} diff --git a/Source/iop/Iop_Timrman.h b/Source/iop/Iop_Timrman.h new file mode 100644 index 00000000..3d36807a --- /dev/null +++ b/Source/iop/Iop_Timrman.h @@ -0,0 +1,22 @@ +#ifndef _TIMRMAN_H_ +#define _TIMRMAN_H_ + +#include "Iop_Module.h" + +namespace Iop +{ + class CTimrman : public CModule + { + public: + CTimrman(); + virtual ~CTimrman(); + + std::string GetId() const; + void Invoke(CMIPS&, unsigned int); + + private: + + }; +} + +#endif diff --git a/Source/win32ui/Debugger.cpp b/Source/win32ui/Debugger.cpp index 6ecde7e02a2ae71a4c804e78f5df345972538cbe..48b2367db24deaf662976431ec131c3746830cc3 100644 GIT binary patch delta 59 zcmdlrkNM3!<_%$tqIwK^4EhWK48;sa49*Ps40%9S$>c&t`ORUBRgSy?48cGNDO15tTqceNA~~#(ntyw