drc: use direct hle calls
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / emu_if.c
CommitLineData
7139f3c8 1// pending_exception?
822b27d1 2// swi 0 in do_unalignedwritestub?
f95a77f7 3#include <stdio.h>
4
5#include "emu_if.h"
7139f3c8 6#include "../psxmem.h"
7#include "../psxhle.h"
8
9//#define memprintf printf
10#define memprintf(...)
11//#define evprintf printf
12#define evprintf(...)
13
f95a77f7 14char invalid_code[0x100000];
15
7139f3c8 16void MTC0_()
f95a77f7 17{
7139f3c8 18 extern void psxMTC0();
19
b9b61529 20 memprintf("ari64 MTC0 %08x\n", psxRegs.code);
7139f3c8 21 psxMTC0();
22 pending_exception = 1; /* FIXME? */
f95a77f7 23}
24
25void gen_interupt()
26{
7139f3c8 27 evprintf("ari64_gen_interupt\n");
822b27d1 28 evprintf(" +ge %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
7139f3c8 29#ifdef DRC_DBG
30 psxRegs.cycle += 2;
7139f3c8 31#endif
32
33 psxBranchTest();
34
822b27d1 35 next_interupt = psxNextsCounter + psxNextCounter;
36 evprintf(" -ge %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
7139f3c8 37
38 pending_exception = 1; /* FIXME */
f95a77f7 39}
40
41void check_interupt()
42{
7139f3c8 43 printf("ari64_check_interupt\n");
f95a77f7 44}
45
46void read_nomem_new()
47{
7139f3c8 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);
f95a77f7 73}
74
7139f3c8 75static void write_mem16()
f95a77f7 76{
7139f3c8 77 memprintf("ari64_write_mem16 %08x, %04x, PC~=%08x\n", address, hword, psxRegs.pc);
78 psxMemWrite16(address, hword);
f95a77f7 79}
80
7139f3c8 81static void write_mem32()
f95a77f7 82{
7139f3c8 83 memprintf("ari64_write_mem32 %08x, %08x, PC~=%08x\n", address, word, psxRegs.pc);
84 psxMemWrite32(address, word);
f95a77f7 85}
86
87void (*readmem[0x10000])();
88void (*readmemb[0x10000])();
89void (*readmemh[0x10000])();
90void (*writemem[0x10000])();
91void (*writememb[0x10000])();
92void (*writememh[0x10000])();
93
b9b61529 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};
f95a77f7 104
105static int ari64_init()
106{
b9b61529 107 extern void (*psxCP2[64])();
108 extern void psxNULL();
f95a77f7 109 size_t i;
b9b61529 110
f95a77f7 111 new_dynarec_init();
112
113 for (i = 0; i < sizeof(readmem) / sizeof(readmem[0]); i++) {
7139f3c8 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;
f95a77f7 120 }
7139f3c8 121
b9b61529 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
b9b61529 126 return 0;
f95a77f7 127}
128
129static void ari64_reset()
130{
131 /* hmh */
132 printf("ari64_reset\n");
133}
134
135static void ari64_execute()
136{
822b27d1 137 next_interupt = psxNextsCounter + psxNextCounter;
7139f3c8 138
b9b61529 139 evprintf("psxNextsCounter %d, psxNextCounter %d\n", psxNextsCounter, psxNextCounter);
822b27d1 140 evprintf("ari64_execute %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
b9b61529 141 new_dyna_start();
822b27d1 142 evprintf("ari64_execute end %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
f95a77f7 143}
144
145static void ari64_clear(u32 Addr, u32 Size)
146{
147}
148
149static void ari64_shutdown()
150{
151 new_dynarec_cleanup();
152}
153
7139f3c8 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
f95a77f7 163R3000Acpu psxRec = {
164 ari64_init,
165 ari64_reset,
7139f3c8 166#if 1
f95a77f7 167 ari64_execute,
7139f3c8 168 ari64_execute,
169#else
170 intExecuteT,
171 intExecuteBlockT,
172#endif
f95a77f7 173 ari64_clear,
174 ari64_shutdown
175};
7139f3c8 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;
7139f3c8 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