drc: small debug improvement
[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() {}
3eb78778 190void new_dyna_start() {}
7139f3c8 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");
3eb78778 203 if (f1 == NULL)
204 f1 = fopen(strrchr(fname, '/') + 1, "wb");
7139f3c8 205 fwrite(mem, 1, size, f1);
206 fclose(f1);
207}
208
209void do_insn_trace(void)
210{
211 static psxRegisters oldregs;
212 static u32 old_io_addr = (u32)-1;
213 static u32 old_io_data = 0xbad0c0de;
214 u32 *allregs_p = (void *)&psxRegs;
215 u32 *allregs_o = (void *)&oldregs;
216 u32 *io_data;
217 int i;
218 u8 byte;
219
220//last_io_addr = 0x5e2c8;
221 if (f == NULL)
222 f = fopen("tracelog", "wb");
223
224 oldregs.code = psxRegs.code; // don't care
225 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
226 if (allregs_p[i] != allregs_o[i]) {
227 fwrite(&i, 1, 1, f);
228 fwrite(&allregs_p[i], 1, 4, f);
229 allregs_o[i] = allregs_p[i];
230 }
231 }
232 if (old_io_addr != last_io_addr) {
233 byte = 0xfd;
234 fwrite(&byte, 1, 1, f);
235 fwrite(&last_io_addr, 1, 4, f);
236 old_io_addr = last_io_addr;
237 }
238 io_data = (void *)(psxM + (last_io_addr&0x1ffffc));
239 if (old_io_data != *io_data) {
240 byte = 0xfe;
241 fwrite(&byte, 1, 1, f);
242 fwrite(io_data, 1, 4, f);
243 old_io_data = *io_data;
244 }
245 byte = 0xff;
246 fwrite(&byte, 1, 1, f);
247
248#if 0
249 if (psxRegs.cycle == 190230) {
250 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
251 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
252 printf("dumped\n");
253 exit(1);
254 }
255#endif
256}
257
258static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
259 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
260 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
261 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
262 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
263 "lo", "hi",
264 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
265 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
266 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
267 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
268
269 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
270 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
271 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
272 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
273
274 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
275 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
276 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
277 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
278
279 "PC", "code", "cycle", "interrupt",
280};
281
3eb78778 282static struct {
283 int reg;
284 u32 val, val_expect;
285 u32 pc, cycle;
286} miss_log[64];
287static int miss_log_i;
288#define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
289#define miss_log_mask (miss_log_len-1)
290
291static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
292{
293 miss_log[miss_log_i].reg = reg;
294 miss_log[miss_log_i].val = val;
295 miss_log[miss_log_i].val_expect = val_expect;
296 miss_log[miss_log_i].pc = pc;
297 miss_log[miss_log_i].cycle = cycle;
298 miss_log_i = (miss_log_i + 1) & miss_log_mask;
299}
300
7139f3c8 301void breakme() {}
302
303void do_insn_cmp(void)
304{
305 static psxRegisters rregs;
306 static u32 mem_addr, mem_val;
307 u32 *allregs_p = (void *)&psxRegs;
308 u32 *allregs_e = (void *)&rregs;
309 static u32 ppc, failcount;
310 int i, ret, bad = 0;
311 u8 code;
312
313 if (f == NULL)
314 f = fopen("tracelog", "rb");
315
316 while (1) {
317 if ((ret = fread(&code, 1, 1, f)) <= 0)
318 break;
319 if (ret <= 0)
320 break;
321 if (code == 0xff)
322 break;
323 if (code == 0xfd) {
324 if ((ret = fread(&mem_addr, 1, 4, f)) <= 0)
325 break;
326 continue;
327 }
328 if (code == 0xfe) {
329 if ((ret = fread(&mem_val, 1, 4, f)) <= 0)
330 break;
331 continue;
332 }
333 if ((ret = fread(&allregs_e[code], 1, 4, f)) <= 0)
334 break;
335 }
336
337 if (ret <= 0) {
338 printf("EOF?\n");
339 goto end;
340 }
341
342 psxRegs.code = rregs.code; // don't care
343psxRegs.cycle = rregs.cycle;
344psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
345
346//if (psxRegs.cycle == 166172) breakme();
347//if (psxRegs.cycle > 11296376) printf("pc=%08x %u %08x\n", psxRegs.pc, psxRegs.cycle, psxRegs.interrupt);
348
349 mem_addr &= 0x1ffffc;
350
351 if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
352 mem_val == *(u32 *)(psxM + mem_addr)
353 ) {
354 failcount = 0;
355 goto ok;
356 }
357
358 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
359 if (allregs_p[i] != allregs_e[i]) {
3eb78778 360 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
7139f3c8 361 bad++;
362 }
363 }
364
365 if (mem_val != *(u32 *)(psxM + mem_addr)) {
366 printf("bad mem @%08x: %08x %08x\n", mem_addr, *(u32 *)(psxM + mem_addr), mem_val);
367 goto end;
368 }
369
370 if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
3eb78778 371 static int last_mcycle;
372 if (last_mcycle != psxRegs.cycle >> 20) {
373 printf("%u\n", psxRegs.cycle);
374 last_mcycle = psxRegs.cycle >> 20;
375 }
7139f3c8 376 failcount++;
377 goto ok;
378 }
379
380end:
3eb78778 381 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
382 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
383 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
384 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
385 printf("-- %d\n", bad);
386 for (i = 0; i < 8; i++)
387 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
388 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+23]);
7139f3c8 389 printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
390 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
391 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
392 exit(1);
393ok:
394 psxRegs.cycle = rregs.cycle + 2; // sync timing
395 ppc = psxRegs.pc;
396}
397
398#endif