1 #pragma once 2 3 #include "iop/Iop_BiosBase.h" 4 #include "OsStructManager.h" 5 #include "OsVariableWrapper.h" 6 #include "MIPS.h" 7 8 class CPsxBios : public Iop::CBiosBase 9 { 10 public: 11 struct EXEHEADER 12 { 13 uint8 id[8]; 14 uint32 text; 15 uint32 data; 16 uint32 pc0; 17 uint32 gp0; 18 uint32 textAddr; 19 uint32 textSize; 20 uint32 dataAddr; 21 uint32 dataSize; 22 uint32 bssAddr; 23 uint32 bssSize; 24 uint32 stackAddr; 25 uint32 stackSize; 26 uint32 savedSp; 27 uint32 savedFp; 28 uint32 savedGp; 29 uint32 savedRa; 30 uint32 savedS0; 31 }; 32 33 CPsxBios(CMIPS&, uint8*, uint32); 34 virtual ~CPsxBios() = default; 35 36 void Reset(); 37 void HandleInterrupt() override; 38 void HandleException() override; 39 void CountTicks(uint32) override; 40 41 void LoadExe(const uint8*); 42 43 void SaveState(Framework::CZipArchiveWriter&) override; 44 void LoadState(Framework::CZipArchiveReader&) override; 45 46 void NotifyVBlankStart() override; 47 void NotifyVBlankEnd() override; 48 49 bool IsIdle() override; 50 51 #ifdef DEBUGGER_INCLUDED 52 void LoadDebugTags(Framework::Xml::CNode*) override; 53 void SaveDebugTags(Framework::Xml::CNode*) override; 54 55 BiosDebugModuleInfoArray GetModulesDebugInfo() const override; 56 BiosDebugThreadInfoArray GetThreadsDebugInfo() const override; 57 #endif 58 59 private: 60 struct EVENT 61 { 62 uint32 isValid; 63 uint32 enabled; 64 uint32 classId; 65 uint32 spec; 66 uint32 mode; 67 uint32 func; 68 uint32 fired; 69 }; 70 71 struct CB_TABLE 72 { 73 uint32 address; 74 uint32 size; 75 }; 76 77 struct PROCESS 78 { 79 uint32 currentThreadControlBlockAddr; 80 }; 81 82 enum THREAD_STATUS 83 { 84 THREAD_STATUS_FREE = 0x1000, 85 THREAD_STATUS_ALLOCATED = 0x4000, 86 }; 87 88 struct THREAD 89 { 90 uint32 status; 91 uint32 reserved0; 92 uint32 gpr[0x20]; 93 uint32 pc; 94 uint32 hi; 95 uint32 lo; 96 uint32 sr; 97 uint32 cause; 98 uint32 reserved1[9]; 99 }; 100 static_assert(sizeof(THREAD) == 0xC0, "Size of THREAD must be 192 bytes."); 101 102 enum 103 { 104 MAX_EVENT = 32, 105 }; 106 107 enum 108 { 109 EVENT_ID_RCNT2 = 0xF2000002, 110 }; 111 112 typedef void (CPsxBios::*SyscallHandler)(); 113 114 void LongJump(uint32, uint32 = 0); 115 116 PROCESS* GetProcess(); 117 void SaveCpuState(); 118 void LoadCpuState(); 119 uint32 AllocateSysMemory(uint32); 120 121 void DisassembleSyscall(uint32); 122 123 void ProcessSubFunction(SyscallHandler*, unsigned int); 124 void AssembleInterruptHandler(); 125 void AssembleEventChecker(); 126 127 //A0 128 void sc_setjmp(); 129 void sc_longjmp(); 130 void sc_strcpy(); 131 void sc_bzero(); 132 void sc_memcpy(); 133 void sc_memset(); 134 void sc_rand(); 135 void sc_srand(); 136 void sc_InitHeap(); 137 void sc_printf(); 138 void sc_FlushCache(); 139 void sc_bu_init(); 140 void sc_96_remove(); 141 void sc_SetMem(); 142 143 //B0 144 void sc_SysMalloc(); 145 void sc_DeliverEvent(); 146 void sc_OpenEvent(); 147 void sc_CloseEvent(); 148 void sc_WaitEvent(); 149 void sc_TestEvent(); 150 void sc_EnableEvent(); 151 void sc_DisableEvent(); 152 void sc_OpenThread(); 153 void sc_ChangeThread(); 154 void sc_StopPAD(); 155 void sc_PAD_dr(); 156 void sc_ReturnFromException(); 157 void sc_SetDefaultExitFromException(); 158 void sc_SetCustomExitFromException(); 159 void sc_puts(); 160 void sc_InitCARD(); 161 void sc_StartCARD(); 162 void sc_GetC0Table(); 163 void sc_GetB0Table(); 164 void sc_ChangeClearPad(); 165 166 //C0 167 void sc_EnqueueTimerAndVblankIrqs(); 168 void sc_EnqueueSyscallHandler(); 169 void sc_SysDeqIntRP(); 170 void sc_SysInitMemory(); 171 void sc_ChangeClearRCnt(); 172 void sc_InitDefInt(); 173 174 void sc_EnterCriticalSection(); 175 void sc_ExitCriticalSection(); 176 void sc_Illegal(); 177 178 enum 179 { 180 MAX_HANDLER_A0 = 0x100, 181 MAX_HANDLER_B0 = 0x80, 182 MAX_HANDLER_C0 = 0x20, 183 }; 184 185 CMIPS& m_cpu; 186 uint8* m_ram; 187 uint32 m_ramSize; 188 189 OsVariableWrapper<uint32> m_exitFromExceptionStateAddr; 190 OsVariableWrapper<uint32> m_sysHeapPointerAddr; 191 192 COsStructManager<EVENT> m_events; 193 194 static SyscallHandler m_handlerA0[MAX_HANDLER_A0]; 195 static SyscallHandler m_handlerB0[MAX_HANDLER_B0]; 196 static SyscallHandler m_handlerC0[MAX_HANDLER_C0]; 197 }; 198