drc: use direct hle calls
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / emu_if.c
... / ...
CommitLineData
1// pending_exception?
2// swi 0 in do_unalignedwritestub?
3#include <stdio.h>
4
5#include "emu_if.h"
6#include "../psxmem.h"
7#include "../psxhle.h"
8
9//#define memprintf printf
10#define memprintf(...)
11//#define evprintf printf
12#define evprintf(...)
13
14char invalid_code[0x100000];
15
16void MTC0_()
17{
18 extern void psxMTC0();
19
20 memprintf("ari64 MTC0 %08x\n", psxRegs.code);
21 psxMTC0();
22 pending_exception = 1; /* FIXME? */
23}
24
25void gen_interupt()
26{
27 evprintf("ari64_gen_interupt\n");
28 evprintf(" +ge %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
29#ifdef DRC_DBG
30 psxRegs.cycle += 2;
31#endif
32
33 psxBranchTest();
34
35 next_interupt = psxNextsCounter + psxNextCounter;
36 evprintf(" -ge %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
37
38 pending_exception = 1; /* FIXME */
39}
40
41void check_interupt()
42{
43 printf("ari64_check_interupt\n");
44}
45
46void read_nomem_new()
47{
48 printf("ari64_read_nomem_new\n");
49}
50
51static void read_mem8()
52{
53 memprintf("ari64_read_mem8 %08x, PC~=%08x\n", address, psxRegs.pc);
54 readmem_word = psxMemRead8(address) & 0xff;
55}
56
57static void read_mem16()
58{
59 memprintf("ari64_read_mem16 %08x, PC~=%08x\n", address, psxRegs.pc);
60 readmem_word = psxMemRead16(address) & 0xffff;
61}
62
63static void read_mem32()
64{
65 memprintf("ari64_read_mem32 %08x, PC~=%08x\n", address, psxRegs.pc);
66 readmem_word = psxMemRead32(address);
67}
68
69static void write_mem8()
70{
71 memprintf("ari64_write_mem8 %08x, %02x, PC~=%08x\n", address, byte, psxRegs.pc);
72 psxMemWrite8(address, byte);
73}
74
75static void write_mem16()
76{
77 memprintf("ari64_write_mem16 %08x, %04x, PC~=%08x\n", address, hword, psxRegs.pc);
78 psxMemWrite16(address, hword);
79}
80
81static void write_mem32()
82{
83 memprintf("ari64_write_mem32 %08x, %08x, PC~=%08x\n", address, word, psxRegs.pc);
84 psxMemWrite32(address, word);
85}
86
87void (*readmem[0x10000])();
88void (*readmemb[0x10000])();
89void (*readmemh[0x10000])();
90void (*writemem[0x10000])();
91void (*writememb[0x10000])();
92void (*writememh[0x10000])();
93
94void *gte_handlers[64];
95
96/* from gte.txt.. not sure if this is any good. */
97const char gte_cycletab[64] = {
98 /* 1 2 3 4 5 6 7 8 9 a b c d e f */
99 0, 15, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 6, 0, 0, 0,
100 8, 8, 8, 19, 13, 0, 44, 0, 0, 0, 0, 17, 11, 0, 14, 0,
101 30, 0, 0, 0, 0, 0, 0, 0, 5, 8, 17, 0, 0, 5, 6, 0,
102 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 39,
103};
104
105static int ari64_init()
106{
107 extern void (*psxCP2[64])();
108 extern void psxNULL();
109 size_t i;
110
111 new_dynarec_init();
112
113 for (i = 0; i < sizeof(readmem) / sizeof(readmem[0]); i++) {
114 readmemb[i] = read_mem8;
115 readmemh[i] = read_mem16;
116 readmem[i] = read_mem32;
117 writememb[i] = write_mem8;
118 writememh[i] = write_mem16;
119 writemem[i] = write_mem32;
120 }
121
122 for (i = 0; i < sizeof(gte_handlers) / sizeof(gte_handlers[0]); i++)
123 if (psxCP2[i] != psxNULL)
124 gte_handlers[i] = psxCP2[i];
125
126 return 0;
127}
128
129static void ari64_reset()
130{
131 /* hmh */
132 printf("ari64_reset\n");
133}
134
135static void ari64_execute()
136{
137 next_interupt = psxNextsCounter + psxNextCounter;
138
139 evprintf("psxNextsCounter %d, psxNextCounter %d\n", psxNextsCounter, psxNextCounter);
140 evprintf("ari64_execute %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
141 new_dyna_start();
142 evprintf("ari64_execute end %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
143}
144
145static void ari64_clear(u32 Addr, u32 Size)
146{
147}
148
149static void ari64_shutdown()
150{
151 new_dynarec_cleanup();
152}
153
154extern void intExecute();
155extern void intExecuteT();
156extern void intExecuteBlock();
157extern void intExecuteBlockT();
158#ifndef DRC_DBG
159#define intExecuteT intExecute
160#define intExecuteBlockT intExecuteBlock
161#endif
162
163R3000Acpu psxRec = {
164 ari64_init,
165 ari64_reset,
166#if 1
167 ari64_execute,
168 ari64_execute,
169#else
170 intExecuteT,
171 intExecuteBlockT,
172#endif
173 ari64_clear,
174 ari64_shutdown
175};
176
177// TODO: rm
178#ifndef DRC_DBG
179void do_insn_trace() {}
180void do_insn_cmp() {}
181#endif
182
183#if defined(__x86_64__) || defined(__i386__)
184unsigned int address, readmem_word, word;
185unsigned short hword;
186unsigned char byte;
187int pending_exception;
188unsigned int next_interupt;
189void new_dynarec_init() {}
190int new_dyna_start() {}
191void new_dynarec_cleanup() {}
192#endif
193
194#ifdef DRC_DBG
195
196#include <stddef.h>
197static FILE *f;
198extern u32 last_io_addr;
199
200static void dump_mem(const char *fname, void *mem, size_t size)
201{
202 FILE *f1 = fopen(fname, "wb");
203 fwrite(mem, 1, size, f1);
204 fclose(f1);
205}
206
207void do_insn_trace(void)
208{
209 static psxRegisters oldregs;
210 static u32 old_io_addr = (u32)-1;
211 static u32 old_io_data = 0xbad0c0de;
212 u32 *allregs_p = (void *)&psxRegs;
213 u32 *allregs_o = (void *)&oldregs;
214 u32 *io_data;
215 int i;
216 u8 byte;
217
218//last_io_addr = 0x5e2c8;
219 if (f == NULL)
220 f = fopen("tracelog", "wb");
221
222 oldregs.code = psxRegs.code; // don't care
223 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
224 if (allregs_p[i] != allregs_o[i]) {
225 fwrite(&i, 1, 1, f);
226 fwrite(&allregs_p[i], 1, 4, f);
227 allregs_o[i] = allregs_p[i];
228 }
229 }
230 if (old_io_addr != last_io_addr) {
231 byte = 0xfd;
232 fwrite(&byte, 1, 1, f);
233 fwrite(&last_io_addr, 1, 4, f);
234 old_io_addr = last_io_addr;
235 }
236 io_data = (void *)(psxM + (last_io_addr&0x1ffffc));
237 if (old_io_data != *io_data) {
238 byte = 0xfe;
239 fwrite(&byte, 1, 1, f);
240 fwrite(io_data, 1, 4, f);
241 old_io_data = *io_data;
242 }
243 byte = 0xff;
244 fwrite(&byte, 1, 1, f);
245
246#if 0
247 if (psxRegs.cycle == 190230) {
248 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
249 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
250 printf("dumped\n");
251 exit(1);
252 }
253#endif
254}
255
256static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
257 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
258 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
259 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
260 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
261 "lo", "hi",
262 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
263 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
264 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
265 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
266
267 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
268 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
269 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
270 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
271
272 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
273 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
274 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
275 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
276
277 "PC", "code", "cycle", "interrupt",
278};
279
280void breakme() {}
281
282void do_insn_cmp(void)
283{
284 static psxRegisters rregs;
285 static u32 mem_addr, mem_val;
286 u32 *allregs_p = (void *)&psxRegs;
287 u32 *allregs_e = (void *)&rregs;
288 static u32 ppc, failcount;
289 int i, ret, bad = 0;
290 u8 code;
291
292 if (f == NULL)
293 f = fopen("tracelog", "rb");
294
295 while (1) {
296 if ((ret = fread(&code, 1, 1, f)) <= 0)
297 break;
298 if (ret <= 0)
299 break;
300 if (code == 0xff)
301 break;
302 if (code == 0xfd) {
303 if ((ret = fread(&mem_addr, 1, 4, f)) <= 0)
304 break;
305 continue;
306 }
307 if (code == 0xfe) {
308 if ((ret = fread(&mem_val, 1, 4, f)) <= 0)
309 break;
310 continue;
311 }
312 if ((ret = fread(&allregs_e[code], 1, 4, f)) <= 0)
313 break;
314 }
315
316 if (ret <= 0) {
317 printf("EOF?\n");
318 goto end;
319 }
320
321 psxRegs.code = rregs.code; // don't care
322psxRegs.cycle = rregs.cycle;
323psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
324
325//if (psxRegs.cycle == 166172) breakme();
326//if (psxRegs.cycle > 11296376) printf("pc=%08x %u %08x\n", psxRegs.pc, psxRegs.cycle, psxRegs.interrupt);
327
328 mem_addr &= 0x1ffffc;
329
330 if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
331 mem_val == *(u32 *)(psxM + mem_addr)
332 ) {
333 failcount = 0;
334 goto ok;
335 }
336
337 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
338 if (allregs_p[i] != allregs_e[i]) {
339 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
340 regnames[i], allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
341 bad++;
342 }
343 }
344
345 if (mem_val != *(u32 *)(psxM + mem_addr)) {
346 printf("bad mem @%08x: %08x %08x\n", mem_addr, *(u32 *)(psxM + mem_addr), mem_val);
347 goto end;
348 }
349
350 if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
351 printf("-- %d\n", bad);
352 failcount++;
353 goto ok;
354 }
355
356end:
357 printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
358 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
359 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
360 exit(1);
361ok:
362 psxRegs.cycle = rregs.cycle + 2; // sync timing
363 ppc = psxRegs.pc;
364}
365
366#endif