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