1 #include "mips3_intf.h"
2 #include "mips3/mips3.h"
3 #include "burnint.h"
4 #include <stdint.h>
5
6 #ifdef MIPS3_X64_DRC
7 #include "mips3/x64/mips3_x64.h"
8 #endif
9
10 #define ADDR_BITS 32
11 #define PAGE_SIZE 0x1000
12 #define PAGE_SHIFT 12
13 #define PAGE_MASK 0xFFF
14 #define PAGE_COUNT (1 << (ADDR_BITS - PAGE_SHIFT))
15 #define PAGE_WADD (PAGE_COUNT)
16 #define MIPS_MAXHANDLER 10
17 #define PFN(x) ((x >> PAGE_SHIFT) & 0xFFFFF)
18
19 struct Mips3MemoryMap
20 {
21 UINT8 *MemMap[PAGE_COUNT * 2];
22
23 pMips3ReadByteHandler ReadByte[MIPS_MAXHANDLER];
24 pMips3WriteByteHandler WriteByte[MIPS_MAXHANDLER];
25 pMips3ReadHalfHandler ReadHalf[MIPS_MAXHANDLER];
26 pMips3WriteHalfHandler WriteHalf[MIPS_MAXHANDLER];
27 pMips3ReadWordHandler ReadWord[MIPS_MAXHANDLER];
28 pMips3WriteWordHandler WriteWord[MIPS_MAXHANDLER];
29 pMips3ReadDoubleHandler ReadDouble[MIPS_MAXHANDLER];
30 pMips3WriteDoubleHandler WriteDouble[MIPS_MAXHANDLER];
31 };
32
33
34 static mips::mips3 *g_mips = NULL;
35 static Mips3MemoryMap *g_mmap = NULL;
36 static bool g_useRecompiler = false;
37
38 #ifdef MIPS3_X64_DRC
39 static mips::mips3_x64 *g_mips_x64 = nullptr;
40 #endif
41
DefReadByte(UINT32 a)42 static UINT8 DefReadByte(UINT32 a) { return 0; }
DefReadHalf(UINT32 a)43 static UINT16 DefReadHalf(UINT32 a) { return 0; }
DefReadWord(UINT32 a)44 static UINT32 DefReadWord(UINT32 a) { return 0; }
DefReadDouble(UINT32 a)45 static UINT64 DefReadDouble(UINT32 a) { return 0; }
DefWriteByte(UINT32 a,UINT8 value)46 static void DefWriteByte(UINT32 a, UINT8 value) { }
DefWriteHalf(UINT32 a,UINT16 value)47 static void DefWriteHalf(UINT32 a, UINT16 value) { }
DefWriteWord(UINT32 a,UINT32 value)48 static void DefWriteWord(UINT32 a, UINT32 value) { }
DefWriteDouble(UINT32 a,UINT64 value)49 static void DefWriteDouble(UINT32 a, UINT64 value) { }
50
ResetMemoryMap()51 static void ResetMemoryMap()
52 {
53 for (int page = 0; page < PAGE_COUNT; page++) {
54 g_mmap->MemMap[page] = (unsigned char*) 0;
55 g_mmap->MemMap[PAGE_WADD + page] = (unsigned char*) 0;
56
57 }
58
59 for (int i = 0; i < MIPS_MAXHANDLER; i++) {
60 g_mmap->ReadByte[i] = DefReadByte;
61 g_mmap->ReadHalf[i] = DefReadHalf;
62 g_mmap->ReadWord[i] = DefReadWord;
63 g_mmap->ReadDouble[i] = DefReadDouble;
64 g_mmap->WriteByte[i] = DefWriteByte;
65 g_mmap->WriteHalf[i] = DefWriteHalf;
66 g_mmap->WriteWord[i] = DefWriteWord;
67 g_mmap->WriteDouble[i] = DefWriteDouble;
68 }
69 }
70
Mips3Init()71 int Mips3Init()
72 {
73 g_mips = new mips::mips3();
74 g_mmap = new Mips3MemoryMap();
75
76 #ifdef MIPS3_X64_DRC
77 g_mips_x64 = new mips::mips3_x64(g_mips);
78 #endif
79
80 ResetMemoryMap();
81
82 return 0;
83 }
84
Mips3UseRecompiler(bool use)85 int Mips3UseRecompiler(bool use)
86 {
87 g_useRecompiler = use;
88
89 return 0;
90 }
91
Mips3Exit()92 int Mips3Exit()
93 {
94 #ifdef MIPS3_X64_DRC
95 delete g_mips_x64;
96 #endif
97 delete g_mips;
98 delete g_mmap;
99 g_mips = NULL;
100 g_mmap = NULL;
101
102 return 0;
103 }
104
105
Mips3Reset()106 void Mips3Reset()
107 {
108 if (g_mips)
109 g_mips->reset();
110 }
111
Mips3Run(int cycles)112 int Mips3Run(int cycles)
113 {
114 #ifdef MIPS3_X64_DRC
115 if (g_mips) {
116 if (g_useRecompiler && g_mips_x64) {
117 g_mips_x64->run(cycles);
118 } else {
119 g_mips->run(cycles);
120 }
121 }
122 #else
123 if (g_mips)
124 g_mips->run(cycles);
125 #endif
126 return 0;
127 }
128
Mips3MapMemory(unsigned char * pMemory,unsigned int nStart,unsigned int nEnd,int nType)129 int Mips3MapMemory(unsigned char* pMemory, unsigned int nStart, unsigned int nEnd, int nType)
130 {
131 const int maxPages = (PFN(nEnd) - PFN(nStart)) + 1;
132
133 int page = PFN(nStart);
134 for (int i = 0; i < maxPages; i++, page++) {
135
136 if (nType & MAP_READ)
137 g_mmap->MemMap[page] = pMemory + (PAGE_SIZE * i);
138
139 if (nType & MAP_WRITE)
140 g_mmap->MemMap[PAGE_WADD + page] = pMemory + (PAGE_SIZE * i);
141 }
142 return 0;
143 }
144
Mips3MapHandler(uintptr_t nHandler,unsigned int nStart,unsigned int nEnd,int nType)145 int Mips3MapHandler(uintptr_t nHandler, unsigned int nStart, unsigned int nEnd, int nType)
146 {
147 const int maxPages = (PFN(nEnd) - PFN(nStart)) + 1;
148
149 int page = PFN(nStart);
150 for (int i = 0; i < maxPages; i++, page++) {
151
152 if (nType & MAP_READ)
153 g_mmap->MemMap[page] = (UINT8*) nHandler;
154
155 if (nType & MAP_WRITE)
156 g_mmap->MemMap[PAGE_WADD + page] = (UINT8*) nHandler;
157 }
158 return 0;
159 }
160
Mips3SetReadByteHandler(int i,pMips3ReadByteHandler pHandler)161 int Mips3SetReadByteHandler(int i, pMips3ReadByteHandler pHandler)
162 {
163 if (i >= MIPS_MAXHANDLER)
164 return 1;
165 g_mmap->ReadByte[i] = pHandler;
166 return 0;
167 }
168
Mips3SetWriteByteHandler(int i,pMips3WriteByteHandler pHandler)169 int Mips3SetWriteByteHandler(int i, pMips3WriteByteHandler pHandler)
170 {
171 if (i >= MIPS_MAXHANDLER)
172 return 1;
173 g_mmap->WriteByte[i] = pHandler;
174 return 0;
175 }
176
Mips3SetReadHalfHandler(int i,pMips3ReadHalfHandler pHandler)177 int Mips3SetReadHalfHandler(int i, pMips3ReadHalfHandler pHandler)
178 {
179 if (i >= MIPS_MAXHANDLER)
180 return 1;
181 g_mmap->ReadHalf[i] = pHandler;
182 return 0;
183 }
184
Mips3SetWriteHalfHandler(int i,pMips3WriteHalfHandler pHandler)185 int Mips3SetWriteHalfHandler(int i, pMips3WriteHalfHandler pHandler)
186 {
187 if (i >= MIPS_MAXHANDLER)
188 return 1;
189 g_mmap->WriteHalf[i] = pHandler;
190 return 0;
191 }
192
Mips3SetReadWordHandler(int i,pMips3ReadWordHandler pHandler)193 int Mips3SetReadWordHandler(int i, pMips3ReadWordHandler pHandler)
194 {
195 if (i >= MIPS_MAXHANDLER)
196 return 1;
197 g_mmap->ReadWord[i] = pHandler;
198 return 0;
199 }
200
Mips3SetWriteWordHandler(int i,pMips3WriteWordHandler pHandler)201 int Mips3SetWriteWordHandler(int i, pMips3WriteWordHandler pHandler)
202 {
203 if (i >= MIPS_MAXHANDLER)
204 return 1;
205 g_mmap->WriteWord[i] = pHandler;
206 return 0;
207 }
208
Mips3SetReadDoubleHandler(int i,pMips3ReadDoubleHandler pHandler)209 int Mips3SetReadDoubleHandler(int i, pMips3ReadDoubleHandler pHandler)
210 {
211 if (i >= MIPS_MAXHANDLER)
212 return 1;
213 g_mmap->ReadDouble[i] = pHandler;
214 return 0;
215 }
216
Mips3SetWriteDoubleHandler(int i,pMips3WriteDoubleHandler pHandler)217 int Mips3SetWriteDoubleHandler(int i, pMips3WriteDoubleHandler pHandler)
218 {
219 if (i >= MIPS_MAXHANDLER)
220 return 1;
221 g_mmap->WriteDouble[i] = pHandler;
222 return 0;
223 }
224
Mips3SetIRQLine(const int line,const int state)225 void Mips3SetIRQLine(const int line, const int state)
226 {
227 if (g_mips) {
228 if (state) {
229 g_mips->m_state.cpr[0][13] |= (0x400 << line);
230 } else {
231 g_mips->m_state.cpr[0][13] &= ~(0x400 << line);
232 }
233 }
234 }
235
236 namespace mips
237 {
238 namespace mem
239 {
240
241
242 template<typename T>
mips_fast_read(uint8_t * ptr,unsigned adr)243 inline T mips_fast_read(uint8_t *ptr, unsigned adr) {
244 return *((T*) ((uint8_t*) ptr + (adr & PAGE_MASK)));
245 }
246
247 template<typename T>
mips_fast_write(uint8_t * xptr,unsigned adr,T value)248 inline void mips_fast_write(uint8_t *xptr, unsigned adr, T value) {
249 T *ptr = ((T*) ((uint8_t*) xptr + (adr & PAGE_MASK)));
250 *ptr = value;
251 }
252
253
read_byte(addr_t address)254 uint8_t read_byte(addr_t address)
255 {
256 address &= 0xFFFFFFFF;
257
258 UINT8 *pr = g_mmap->MemMap[PFN(address)];
259 if ((uintptr_t)pr >= MIPS_MAXHANDLER) {
260 return pr[address & PAGE_MASK];
261 }
262 return g_mmap->ReadByte[(uintptr_t)pr](address);
263 }
264
read_half(addr_t address)265 uint16_t read_half(addr_t address)
266 {
267 address &= 0xFFFFFFFF;
268
269 UINT8 *pr = g_mmap->MemMap[PFN(address)];
270 if ((uintptr_t)pr >= MIPS_MAXHANDLER) {
271 return BURN_ENDIAN_SWAP_INT16(mips_fast_read<uint16_t>(pr, address));
272 }
273 return g_mmap->ReadHalf[(uintptr_t)pr](address);
274 }
275
read_word(addr_t address)276 uint32_t read_word(addr_t address)
277 {
278 address &= 0xFFFFFFFF;
279
280 UINT8 *pr = g_mmap->MemMap[PFN(address)];
281 if ((uintptr_t)pr >= MIPS_MAXHANDLER) {
282 return BURN_ENDIAN_SWAP_INT32(mips_fast_read<uint32_t>(pr, address));
283 }
284 return g_mmap->ReadWord[(uintptr_t)pr](address);
285 }
286
read_dword(addr_t address)287 uint64_t read_dword(addr_t address)
288 {
289 address &= 0xFFFFFFFF;
290
291 UINT8 *pr = g_mmap->MemMap[PFN(address)];
292 if ((uintptr_t)pr >= MIPS_MAXHANDLER) {
293 return BURN_ENDIAN_SWAP_INT64(mips_fast_read<uint64_t>(pr, address));
294 }
295 return g_mmap->ReadDouble[(uintptr_t)pr](address);
296 }
297
298
write_byte(addr_t address,uint8_t value)299 void write_byte(addr_t address, uint8_t value)
300 {
301 address &= 0xFFFFFFFF;
302
303 UINT8 *pr = g_mmap->MemMap[PAGE_WADD + PFN(address)];
304 if ((uintptr_t)pr >= MIPS_MAXHANDLER) {
305 pr[address & PAGE_MASK] = value;
306 return;
307 }
308 g_mmap->WriteByte[(uintptr_t)pr](address, value);
309 }
310
write_half(addr_t address,uint16_t value)311 void write_half(addr_t address, uint16_t value)
312 {
313 address &= 0xFFFFFFFF;
314
315 UINT8 *pr = g_mmap->MemMap[PAGE_WADD + PFN(address)];
316 if ((uintptr_t)pr >= MIPS_MAXHANDLER) {
317 mips_fast_write<uint16_t>(pr, address, BURN_ENDIAN_SWAP_INT16(value));
318 return;
319 }
320 g_mmap->WriteHalf[(uintptr_t)pr](address, value);
321 }
322
write_word(addr_t address,uint32_t value)323 void write_word(addr_t address, uint32_t value)
324 {
325 address &= 0xFFFFFFFF;
326
327 UINT8 *pr = g_mmap->MemMap[PAGE_WADD + PFN(address)];
328 if ((uintptr_t)pr >= MIPS_MAXHANDLER) {
329 mips_fast_write<uint32_t>(pr, address, BURN_ENDIAN_SWAP_INT32(value));
330 return;
331 }
332 g_mmap->WriteWord[(uintptr_t)pr](address, value);
333 }
334
write_dword(addr_t address,uint64_t value)335 void write_dword(addr_t address, uint64_t value)
336 {
337 address &= 0xFFFFFFFF;
338
339 UINT8 *pr = g_mmap->MemMap[PAGE_WADD + PFN(address)];
340 if ((uintptr_t)pr >= MIPS_MAXHANDLER) {
341 mips_fast_write<uint64_t>(pr, address, BURN_ENDIAN_SWAP_INT64(value));
342 return;
343 }
344 g_mmap->WriteDouble[(uintptr_t)pr](address, value);
345 }
346
347 }
348 }
349
350
Mips3GetPC()351 unsigned int Mips3GetPC()
352 {
353 return g_mips->m_prev_pc;
354 }
355