1 #pragma once 2 3 #include "Iop_Module.h" 4 #include "Iop_SifMan.h" 5 #include "Iop_SifDynamic.h" 6 #include "Iop_Sysmem.h" 7 #include "zip/ZipArchiveWriter.h" 8 #include "zip/ZipArchiveReader.h" 9 10 class CIopBios; 11 12 namespace Iop 13 { 14 class CSifCmd : public CModule 15 { 16 public: 17 CSifCmd(CIopBios&, CSifMan&, CSysmem&, uint8*); 18 virtual ~CSifCmd(); 19 20 std::string GetId() const override; 21 std::string GetFunctionName(unsigned int) const override; 22 void Invoke(CMIPS&, unsigned int) override; 23 24 void ProcessInvocation(uint32, uint32, uint32*, uint32); 25 26 void LoadState(Framework::CZipArchiveReader&) override; 27 void SaveState(Framework::CZipArchiveWriter&) const override; 28 29 void SifBindRpc(CMIPS&); 30 void SifCallRpc(CMIPS&); 31 32 private: 33 typedef std::list<CSifDynamic*> DynamicModuleList; 34 35 struct SIFRPCQUEUEDATA 36 { 37 uint32 threadId; 38 uint32 active; 39 uint32 serverDataLink; //Set when there's a pending request 40 uint32 serverDataStart; //Set when a RPC server has been registered on the queue 41 uint32 serverDataEnd; 42 uint32 queueNext; 43 }; 44 45 struct SIFRPCSERVERDATA 46 { 47 uint32 serverId; 48 49 uint32 function; 50 uint32 buffer; 51 uint32 size; 52 53 uint32 cfunction; 54 uint32 cbuffer; 55 uint32 csize; 56 57 uint32 rsize; 58 uint32 rid; 59 60 uint32 queueAddr; 61 62 //This field is not a part of the real structure, added for bookkeeping reasons. 63 uint32 active; 64 }; 65 static_assert(sizeof(SIFRPCSERVERDATA) <= 0x44, "Size of SIFRPCSERVERDATA must be less or equal to 68 bytes."); 66 67 struct SIFCMDDATA 68 { 69 //There might be an additional GP member in here, but some games such as 70 //Shadow Hearts 2 rely on the fact that this structure is 8 bytes long 71 uint32 sifCmdHandler; 72 uint32 data; 73 }; 74 75 enum 76 { 77 MAX_SYSTEM_COMMAND = 0x20, 78 MAX_SREG = 0x20, 79 PENDING_CMD_BUFFER_SIZE = 0x400, 80 }; 81 82 struct MODULEDATA 83 { 84 uint8 trampoline[0x800]; 85 uint8 sendCmdExtraStruct[0x10]; 86 uint32 sreg[MAX_SREG]; 87 SIFCMDDATA sysCmdBuffer[MAX_SYSTEM_COMMAND]; 88 uint32 usrCmdBufferAddr; 89 uint32 usrCmdBufferLen; 90 uint32 executingCmd; 91 uint8 pendingCmdBuffer[PENDING_CMD_BUFFER_SIZE]; 92 uint32 pendingCmdBufferSize; 93 }; 94 95 void ClearServers(); 96 void BuildExportTable(); 97 98 void ProcessCustomCommand(uint32); 99 void ProcessSetSreg(uint32); 100 void ProcessRpcRequestEnd(uint32); 101 void ProcessDynamicCommand(uint32); 102 void ProcessNextDynamicCommand(); 103 104 int32 SifGetSreg(uint32); 105 uint32 SifSetCmdBuffer(uint32, uint32); 106 void SifAddCmdHandler(uint32, uint32, uint32); 107 uint32 SifSendCmd(uint32, uint32, uint32, uint32, uint32, uint32); 108 void SifRegisterRpc(CMIPS&); 109 uint32 SifCheckStatRpc(uint32); 110 void SifSetRpcQueue(uint32, uint32); 111 uint32 SifGetNextRequest(uint32); 112 void SifExecRequest(CMIPS&); 113 void SifRpcLoop(CMIPS&); 114 uint32 SifGetOtherData(uint32, uint32, uint32, uint32, uint32); 115 uint32 SifRemoveRpc(uint32, uint32); 116 uint32 SifRemoveRpcQueue(uint32); 117 uint32 SifSendCmdIntr(uint32, uint32, uint32, uint32, uint32, uint32, uint32, uint32); 118 void FinishExecRequest(uint32, uint32); 119 void FinishExecCmd(); 120 void FinishBindRpc(uint32, uint32); 121 void SleepThread(); 122 void DelayThread(uint32); 123 124 CIopBios& m_bios; 125 CSifMan& m_sifMan; 126 CSysmem& m_sysMem; 127 uint8* m_ram = nullptr; 128 uint32 m_moduleDataAddr = 0; 129 uint32 m_trampolineAddr = 0; 130 uint32 m_sendCmdExtraStructAddr = 0; 131 uint32 m_sysCmdBufferAddr = 0; 132 uint32 m_sifRpcLoopAddr = 0; 133 uint32 m_sifExecRequestAddr = 0; 134 uint32 m_sifExecCmdHandlerAddr = 0; 135 uint32 m_sifBindRpcAddr = 0; 136 DynamicModuleList m_servers; 137 }; 138 139 typedef std::shared_ptr<CSifCmd> SifCmdPtr; 140 } 141