2 * (C) GraÅžvydas "notaz" Ignotas, 2010-2011
4 * This work is licensed under the terms of GNU GPL version 2 or later.
5 * See the COPYING file in the top-level directory.
12 #include "../psxhle.h"
13 #include "../r3000a.h"
15 #include "../psxdma.h"
17 #include "../gte_arm.h"
18 #include "../gte_neon.h"
22 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
24 //#define evprintf printf
27 char invalid_code[0x100000];
28 u32 event_cycles[PSXINT_COUNT];
30 static void schedule_timeslice(void)
32 u32 i, c = psxRegs.cycle;
33 u32 irqs = psxRegs.interrupt;
37 for (i = 0; irqs != 0; i++, irqs >>= 1) {
40 dif = event_cycles[i] - c;
41 //evprintf(" ev %d\n", dif);
42 if (0 < dif && dif < min)
45 next_interupt = c + min;
48 typedef void (irq_func)();
50 static irq_func * const irq_funcs[] = {
51 [PSXINT_SIO] = sioInterrupt,
52 [PSXINT_CDR] = cdrInterrupt,
53 [PSXINT_CDREAD] = cdrReadInterrupt,
54 [PSXINT_GPUDMA] = gpuInterrupt,
55 [PSXINT_MDECOUTDMA] = mdec1Interrupt,
56 [PSXINT_SPUDMA] = spuInterrupt,
57 [PSXINT_MDECINDMA] = mdec0Interrupt,
58 [PSXINT_GPUOTCDMA] = gpuotcInterrupt,
59 [PSXINT_CDRDMA] = cdrDmaInterrupt,
60 [PSXINT_CDRLID] = cdrLidSeekInterrupt,
61 [PSXINT_CDRPLAY] = cdrPlayInterrupt,
62 [PSXINT_SPU_UPDATE] = spuUpdate,
63 [PSXINT_RCNT] = psxRcntUpdate,
66 /* local dupe of psxBranchTest, using event_cycles */
67 static void irq_test(void)
69 u32 irqs = psxRegs.interrupt;
70 u32 cycle = psxRegs.cycle;
73 // irq_funcs() may queue more irqs
74 psxRegs.interrupt = 0;
76 for (irq = 0, irq_bits = irqs; irq_bits != 0; irq++, irq_bits >>= 1) {
79 if ((s32)(cycle - event_cycles[irq]) >= 0) {
84 psxRegs.interrupt |= irqs;
86 if ((psxHu32(0x1070) & psxHu32(0x1074)) && (Status & 0x401) == 0x401) {
87 psxException(0x400, 0);
88 pending_exception = 1;
94 evprintf(" +ge %08x, %u->%u\n", psxRegs.pc, psxRegs.cycle, next_interupt);
98 //pending_exception = 1;
100 schedule_timeslice();
102 evprintf(" -ge %08x, %u->%u (%d)\n", psxRegs.pc, psxRegs.cycle,
103 next_interupt, next_interupt - psxRegs.cycle);
107 extern void MTC0(int reg, u32 val);
109 void pcsx_mtc0(u32 reg, u32 val)
111 evprintf("MTC0 %d #%x @%08x %u\n", reg, val, psxRegs.pc, psxRegs.cycle);
114 if (Cause & Status & 0x0300) // possible sw irq
115 pending_exception = 1;
118 void pcsx_mtc0_ds(u32 reg, u32 val)
120 evprintf("MTC0 %d #%x @%08x %u\n", reg, val, psxRegs.pc, psxRegs.cycle);
124 void new_dyna_before_save(void)
126 psxRegs.interrupt &= ~(1 << PSXINT_RCNT); // old savestate compat
128 // psxRegs.intCycle is always maintained, no need to convert
131 void new_dyna_after_save(void)
133 psxRegs.interrupt |= 1 << PSXINT_RCNT;
136 static void new_dyna_restore(void)
139 for (i = 0; i < PSXINT_COUNT; i++)
140 event_cycles[i] = psxRegs.intCycle[i].sCycle + psxRegs.intCycle[i].cycle;
142 event_cycles[PSXINT_RCNT] = psxNextsCounter + psxNextCounter;
143 psxRegs.interrupt |= 1 << PSXINT_RCNT;
144 psxRegs.interrupt &= (1 << PSXINT_COUNT) - 1;
146 new_dyna_pcsx_mem_load_state();
149 void new_dyna_freeze(void *f, int mode)
151 const char header_save[8] = "ariblks";
152 uint32_t addrs[1024 * 4];
157 if (mode != 0) { // save
158 size = new_dynarec_save_blocks(addrs, sizeof(addrs));
162 SaveFuncs.write(f, header_save, sizeof(header_save));
163 SaveFuncs.write(f, &size, sizeof(size));
164 SaveFuncs.write(f, addrs, size);
169 bytes = SaveFuncs.read(f, header, sizeof(header));
170 if (bytes != sizeof(header) || strcmp(header, header_save)) {
172 SaveFuncs.seek(f, -bytes, SEEK_CUR);
175 SaveFuncs.read(f, &size, sizeof(size));
178 if (size > sizeof(addrs)) {
179 bytes = size - sizeof(addrs);
180 SaveFuncs.seek(f, bytes, SEEK_CUR);
181 size = sizeof(addrs);
183 bytes = SaveFuncs.read(f, addrs, size);
187 if (psxCpu != &psxInt)
188 new_dynarec_load_blocks(addrs, size);
191 //printf("drc: %d block info entries %s\n", size/8, mode ? "saved" : "loaded");
197 void *gte_handlers[64];
199 void *gte_handlers_nf[64] = {
200 NULL , gteRTPS_nf , NULL , NULL , NULL , NULL , gteNCLIP_nf, NULL , // 00
201 NULL , NULL , NULL , NULL , gteOP_nf , NULL , NULL , NULL , // 08
202 gteDPCS_nf, gteINTPL_nf, gteMVMVA_nf, gteNCDS_nf, gteCDP_nf, NULL , gteNCDT_nf , NULL , // 10
203 NULL , NULL , NULL , gteNCCS_nf, gteCC_nf , NULL , gteNCS_nf , NULL , // 18
204 gteNCT_nf , NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 20
205 gteSQR_nf , gteDCPL_nf , gteDPCT_nf , NULL , NULL , gteAVSZ3_nf, gteAVSZ4_nf, NULL , // 28
206 gteRTPT_nf, NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 30
207 NULL , NULL , NULL , NULL , NULL , gteGPF_nf , gteGPL_nf , gteNCCT_nf, // 38
210 const char *gte_regnames[64] = {
211 NULL , "RTPS" , NULL , NULL , NULL , NULL , "NCLIP", NULL , // 00
212 NULL , NULL , NULL , NULL , "OP" , NULL , NULL , NULL , // 08
213 "DPCS", "INTPL", "MVMVA", "NCDS", "CDP", NULL , "NCDT" , NULL , // 10
214 NULL , NULL , NULL , "NCCS", "CC" , NULL , "NCS" , NULL , // 18
215 "NCT" , NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 20
216 "SQR" , "DCPL" , "DPCT" , NULL , NULL , "AVSZ3", "AVSZ4", NULL , // 28
217 "RTPT", NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 30
218 NULL , NULL , NULL , NULL , NULL , "GPF" , "GPL" , "NCCT", // 38
225 #define GCBITS3(b0,b1,b2) \
226 (GCBIT(b0) | GCBIT(b1) | GCBIT(b2))
227 #define GDBITS2(b0,b1) \
228 (GDBIT(b0) | GDBIT(b1))
229 #define GDBITS3(b0,b1,b2) \
230 (GDBITS2(b0,b1) | GDBIT(b2))
231 #define GDBITS4(b0,b1,b2,b3) \
232 (GDBITS3(b0,b1,b2) | GDBIT(b3))
233 #define GDBITS5(b0,b1,b2,b3,b4) \
234 (GDBITS4(b0,b1,b2,b3) | GDBIT(b4))
235 #define GDBITS6(b0,b1,b2,b3,b4,b5) \
236 (GDBITS5(b0,b1,b2,b3,b4) | GDBIT(b5))
237 #define GDBITS7(b0,b1,b2,b3,b4,b5,b6) \
238 (GDBITS6(b0,b1,b2,b3,b4,b5) | GDBIT(b6))
239 #define GDBITS8(b0,b1,b2,b3,b4,b5,b6,b7) \
240 (GDBITS7(b0,b1,b2,b3,b4,b5,b6) | GDBIT(b7))
241 #define GDBITS9(b0,b1,b2,b3,b4,b5,b6,b7,b8) \
242 (GDBITS8(b0,b1,b2,b3,b4,b5,b6,b7) | GDBIT(b8))
243 #define GDBITS10(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9) \
244 (GDBITS9(b0,b1,b2,b3,b4,b5,b6,b7,b8) | GDBIT(b9))
246 const uint64_t gte_reg_reads[64] = {
247 [GTE_RTPS] = 0x1f0000ff00000000ll | GDBITS7(0,1,13,14,17,18,19),
248 [GTE_NCLIP] = GDBITS3(12,13,14),
249 [GTE_OP] = GCBITS3(0,2,4) | GDBITS3(9,10,11),
250 [GTE_DPCS] = GCBITS3(21,22,23) | GDBITS4(6,8,21,22),
251 [GTE_INTPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22),
252 [GTE_MVMVA] = 0x00ffffff00000000ll | GDBITS9(0,1,2,3,4,5,9,10,11), // XXX: maybe decode further?
253 [GTE_NCDS] = 0x00ffff0000000000ll | GDBITS6(0,1,6,8,21,22),
254 [GTE_CDP] = 0x00ffe00000000000ll | GDBITS7(6,8,9,10,11,21,22),
255 [GTE_NCDT] = 0x00ffff0000000000ll | GDBITS8(0,1,2,3,4,5,6,8),
256 [GTE_NCCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22),
257 [GTE_CC] = 0x001fe00000000000ll | GDBITS6(6,9,10,11,21,22),
258 [GTE_NCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22),
259 [GTE_NCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6),
260 [GTE_SQR] = GDBITS3(9,10,11),
261 [GTE_DCPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22),
262 [GTE_DPCT] = GCBITS3(21,22,23) | GDBITS4(8,20,21,22),
263 [GTE_AVSZ3] = GCBIT(29) | GDBITS3(17,18,19),
264 [GTE_AVSZ4] = GCBIT(30) | GDBITS4(16,17,18,19),
265 [GTE_RTPT] = 0x1f0000ff00000000ll | GDBITS7(0,1,2,3,4,5,19),
266 [GTE_GPF] = GDBITS7(6,8,9,10,11,21,22),
267 [GTE_GPL] = GDBITS10(6,8,9,10,11,21,22,25,26,27),
268 [GTE_NCCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6),
271 // note: this excludes gteFLAG that is always written to
272 const uint64_t gte_reg_writes[64] = {
273 [GTE_RTPS] = 0x0f0f7f00ll,
274 [GTE_NCLIP] = GDBIT(24),
275 [GTE_OP] = GDBITS6(9,10,11,25,26,27),
276 [GTE_DPCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
277 [GTE_INTPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
278 [GTE_MVMVA] = GDBITS6(9,10,11,25,26,27),
279 [GTE_NCDS] = GDBITS9(9,10,11,20,21,22,25,26,27),
280 [GTE_CDP] = GDBITS9(9,10,11,20,21,22,25,26,27),
281 [GTE_NCDT] = GDBITS9(9,10,11,20,21,22,25,26,27),
282 [GTE_NCCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
283 [GTE_CC] = GDBITS9(9,10,11,20,21,22,25,26,27),
284 [GTE_NCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
285 [GTE_NCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
286 [GTE_SQR] = GDBITS6(9,10,11,25,26,27),
287 [GTE_DCPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
288 [GTE_DPCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
289 [GTE_AVSZ3] = GDBITS2(7,24),
290 [GTE_AVSZ4] = GDBITS2(7,24),
291 [GTE_RTPT] = 0x0f0f7f00ll,
292 [GTE_GPF] = GDBITS9(9,10,11,20,21,22,25,26,27),
293 [GTE_GPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
294 [GTE_NCCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
297 static int ari64_init()
299 static u32 scratch_buf[8*8*2] __attribute__((aligned(64)));
300 extern void (*psxCP2[64])();
301 extern void psxNULL();
302 extern unsigned char *out;
306 new_dyna_pcsx_mem_init();
308 for (i = 0; i < ARRAY_SIZE(gte_handlers); i++)
309 if (psxCP2[i] != psxNULL)
310 gte_handlers[i] = psxCP2[i];
312 #if defined(__arm__) && !defined(DRC_DBG)
313 gte_handlers[0x06] = gteNCLIP_arm;
315 gte_handlers_nf[0x01] = gteRTPS_nf_arm;
316 gte_handlers_nf[0x30] = gteRTPT_nf_arm;
319 // compiler's _nf version is still a lot slower than neon
320 // _nf_arm RTPS is roughly the same, RTPT slower
321 gte_handlers[0x01] = gte_handlers_nf[0x01] = gteRTPS_neon;
322 gte_handlers[0x30] = gte_handlers_nf[0x30] = gteRTPT_neon;
326 memcpy(gte_handlers_nf, gte_handlers, sizeof(gte_handlers_nf));
329 zeromem_ptr = zero_mem;
330 scratch_buf_ptr = scratch_buf;
332 SysPrintf("Mapped (RAM/scrp/ROM/LUTs/TC):\n");
333 SysPrintf("%p/%p/%p/%p/%p\n",
334 psxM, psxH, psxR, mem_rtab, out);
339 static void ari64_reset()
341 printf("ari64_reset\n");
342 new_dyna_pcsx_mem_reset();
343 invalidate_all_pages();
345 pending_exception = 1;
348 // execute until predefined leave points
349 // (HLE softcall exit and BIOS fastboot end)
350 static void ari64_execute_until()
352 schedule_timeslice();
354 evprintf("ari64_execute %08x, %u->%u (%d)\n", psxRegs.pc,
355 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
357 new_dyna_start(dynarec_local);
359 evprintf("ari64_execute end %08x, %u->%u (%d)\n", psxRegs.pc,
360 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
363 static void ari64_execute()
366 ari64_execute_until();
367 evprintf("drc left @%08x\n", psxRegs.pc);
371 static void ari64_clear(u32 addr, u32 size)
373 u32 start, end, main_ram;
375 size *= 4; /* PCSX uses DMA units (words) */
377 evprintf("ari64_clear %08x %04x\n", addr, size);
379 /* check for RAM mirrors */
380 main_ram = (addr & 0xffe00000) == 0x80000000;
383 end = (addr + size) >> 12;
385 for (; start <= end; start++)
386 if (!main_ram || !invalid_code[start])
387 invalidate_block(start);
390 #ifdef ICACHE_EMULATION
391 static void ari64_notify(int note, void *data) {
393 Should be fixed when ARM dynarec has proper icache emulation.
396 case R3000ACPU_NOTIFY_CACHE_UNISOLATED:
398 case R3000ACPU_NOTIFY_CACHE_ISOLATED:
400 case R3000ACPU_NOTIFY_DMA3_EXE_LOAD:
408 static void ari64_apply_config()
410 if (Config.DisableStalls)
411 new_dynarec_hacks |= NDHACK_NO_STALLS;
413 new_dynarec_hacks &= ~NDHACK_NO_STALLS;
415 if (cycle_multiplier != cycle_multiplier_old
416 || new_dynarec_hacks != new_dynarec_hacks_old)
418 new_dynarec_clear_full();
422 static void ari64_shutdown()
424 new_dynarec_cleanup();
425 new_dyna_pcsx_mem_shutdown();
434 #ifdef ICACHE_EMULATION
441 #else // if DRC_DISABLE
443 unsigned int address;
444 int pending_exception, stop;
445 unsigned int next_interupt;
446 int new_dynarec_did_compile;
447 int cycle_multiplier;
448 int cycle_multiplier_override;
449 int cycle_multiplier_old;
450 int new_dynarec_hacks_pergame;
451 int new_dynarec_hacks_old;
452 int new_dynarec_hacks;
458 void *scratch_buf_ptr;
459 void new_dynarec_init() {}
460 void new_dyna_start(void *context) {}
461 void new_dynarec_cleanup() {}
462 void new_dynarec_clear_full() {}
463 void invalidate_all_pages() {}
464 void invalidate_block(unsigned int block) {}
465 void new_dyna_pcsx_mem_init(void) {}
466 void new_dyna_pcsx_mem_reset(void) {}
467 void new_dyna_pcsx_mem_load_state(void) {}
468 void new_dyna_pcsx_mem_shutdown(void) {}
469 int new_dynarec_save_blocks(void *save, int size) { return 0; }
470 void new_dynarec_load_blocks(const void *save, int size) {}
477 extern u32 last_io_addr;
479 static void dump_mem(const char *fname, void *mem, size_t size)
481 FILE *f1 = fopen(fname, "wb");
483 f1 = fopen(strrchr(fname, '/') + 1, "wb");
484 fwrite(mem, 1, size, f1);
488 static u32 memcheck_read(u32 a)
490 if ((a >> 16) == 0x1f80)
492 return *(u32 *)(psxH + (a & 0xfffc));
494 if ((a >> 16) == 0x1f00)
496 return *(u32 *)(psxP + (a & 0xfffc));
498 // if ((a & ~0xe0600000) < 0x200000)
500 return *(u32 *)(psxM + (a & 0x1ffffc));
504 void do_insn_trace(void)
506 static psxRegisters oldregs;
507 static u32 old_io_addr = (u32)-1;
508 static u32 old_io_data = 0xbad0c0de;
509 static u32 event_cycles_o[PSXINT_COUNT];
510 u32 *allregs_p = (void *)&psxRegs;
511 u32 *allregs_o = (void *)&oldregs;
516 //last_io_addr = 0x5e2c8;
518 f = fopen("tracelog", "wb");
521 oldregs.code = psxRegs.code; // don't care
522 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
523 if (allregs_p[i] != allregs_o[i]) {
525 fwrite(&allregs_p[i], 1, 4, f);
526 allregs_o[i] = allregs_p[i];
530 for (i = 0; i < PSXINT_COUNT; i++) {
531 if (event_cycles[i] != event_cycles_o[i]) {
533 fwrite(&byte, 1, 1, f);
535 fwrite(&event_cycles[i], 1, 4, f);
536 event_cycles_o[i] = event_cycles[i];
540 if (old_io_addr != last_io_addr) {
542 fwrite(&byte, 1, 1, f);
543 fwrite(&last_io_addr, 1, 4, f);
544 old_io_addr = last_io_addr;
546 io_data = memcheck_read(last_io_addr);
547 if (old_io_data != io_data) {
549 fwrite(&byte, 1, 1, f);
550 fwrite(&io_data, 1, 4, f);
551 old_io_data = io_data;
554 fwrite(&byte, 1, 1, f);
557 if (psxRegs.cycle == 190230) {
558 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
559 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
567 static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
568 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
569 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
570 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
571 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
573 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
574 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
575 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
576 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
578 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
579 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
580 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
581 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
583 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
584 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
585 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
586 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
588 "PC", "code", "cycle", "interrupt",
596 static int miss_log_i;
597 #define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
598 #define miss_log_mask (miss_log_len-1)
600 static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
602 miss_log[miss_log_i].reg = reg;
603 miss_log[miss_log_i].val = val;
604 miss_log[miss_log_i].val_expect = val_expect;
605 miss_log[miss_log_i].pc = pc;
606 miss_log[miss_log_i].cycle = cycle;
607 miss_log_i = (miss_log_i + 1) & miss_log_mask;
612 void do_insn_cmp(void)
614 static psxRegisters rregs;
615 static u32 mem_addr, mem_val;
616 u32 *allregs_p = (void *)&psxRegs;
617 u32 *allregs_e = (void *)&rregs;
618 static u32 ppc, failcount;
619 int i, ret, bad = 0, which_event = -1;
624 f = fopen("tracelog", "rb");
627 if ((ret = fread(&code, 1, 1, f)) <= 0)
636 fread(&which_event, 1, 1, f);
637 fread(&ev_cycles, 1, 4, f);
640 fread(&mem_addr, 1, 4, f);
643 fread(&mem_val, 1, 4, f);
646 fread(&allregs_e[code], 1, 4, f);
654 psxRegs.code = rregs.code; // don't care
655 psxRegs.cycle = rregs.cycle;
656 psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
658 //if (psxRegs.cycle == 166172) breakme();
660 if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
661 mem_val == memcheck_read(mem_addr)
667 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
668 if (allregs_p[i] != allregs_e[i]) {
669 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
676 if (mem_val != memcheck_read(mem_addr)) {
677 printf("bad mem @%08x: %08x %08x\n", mem_addr, memcheck_read(mem_addr), mem_val);
681 if (which_event >= 0 && event_cycles[which_event] != ev_cycles) {
682 printf("bad ev_cycles #%d: %08x %08x\n", which_event, event_cycles[which_event], ev_cycles);
686 if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
687 static int last_mcycle;
688 if (last_mcycle != psxRegs.cycle >> 20) {
689 printf("%u\n", psxRegs.cycle);
690 last_mcycle = psxRegs.cycle >> 20;
697 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
698 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
699 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
700 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
701 printf("-- %d\n", bad);
702 for (i = 0; i < 8; i++)
703 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
704 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+24]);
705 printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
706 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
707 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
710 psxRegs.cycle = rregs.cycle + 2; // sync timing