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