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 new_dynarec_load_blocks(addrs, size);
190 //printf("drc: %d block info entries %s\n", size/8, mode ? "saved" : "loaded");
196 void *gte_handlers[64];
198 void *gte_handlers_nf[64] = {
199 NULL , gteRTPS_nf , NULL , NULL , NULL , NULL , gteNCLIP_nf, NULL , // 00
200 NULL , NULL , NULL , NULL , gteOP_nf , NULL , NULL , NULL , // 08
201 gteDPCS_nf, gteINTPL_nf, gteMVMVA_nf, gteNCDS_nf, gteCDP_nf, NULL , gteNCDT_nf , NULL , // 10
202 NULL , NULL , NULL , gteNCCS_nf, gteCC_nf , NULL , gteNCS_nf , NULL , // 18
203 gteNCT_nf , NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 20
204 gteSQR_nf , gteDCPL_nf , gteDPCT_nf , NULL , NULL , gteAVSZ3_nf, gteAVSZ4_nf, NULL , // 28
205 gteRTPT_nf, NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 30
206 NULL , NULL , NULL , NULL , NULL , gteGPF_nf , gteGPL_nf , gteNCCT_nf, // 38
209 const char *gte_regnames[64] = {
210 NULL , "RTPS" , NULL , NULL , NULL , NULL , "NCLIP", NULL , // 00
211 NULL , NULL , NULL , NULL , "OP" , NULL , NULL , NULL , // 08
212 "DPCS", "INTPL", "MVMVA", "NCDS", "CDP", NULL , "NCDT" , NULL , // 10
213 NULL , NULL , NULL , "NCCS", "CC" , NULL , "NCS" , NULL , // 18
214 "NCT" , NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 20
215 "SQR" , "DCPL" , "DPCT" , NULL , NULL , "AVSZ3", "AVSZ4", NULL , // 28
216 "RTPT", NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 30
217 NULL , NULL , NULL , NULL , NULL , "GPF" , "GPL" , "NCCT", // 38
220 /* from gte.txt.. not sure if this is any good. */
221 const char gte_cycletab[64] = {
222 /* 1 2 3 4 5 6 7 8 9 a b c d e f */
223 0, 15, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 6, 0, 0, 0,
224 8, 8, 8, 19, 13, 0, 44, 0, 0, 0, 0, 17, 11, 0, 14, 0,
225 30, 0, 0, 0, 0, 0, 0, 0, 5, 8, 17, 0, 0, 5, 6, 0,
226 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 39,
233 #define GCBITS3(b0,b1,b2) \
234 (GCBIT(b0) | GCBIT(b1) | GCBIT(b2))
235 #define GDBITS2(b0,b1) \
236 (GDBIT(b0) | GDBIT(b1))
237 #define GDBITS3(b0,b1,b2) \
238 (GDBITS2(b0,b1) | GDBIT(b2))
239 #define GDBITS4(b0,b1,b2,b3) \
240 (GDBITS3(b0,b1,b2) | GDBIT(b3))
241 #define GDBITS5(b0,b1,b2,b3,b4) \
242 (GDBITS4(b0,b1,b2,b3) | GDBIT(b4))
243 #define GDBITS6(b0,b1,b2,b3,b4,b5) \
244 (GDBITS5(b0,b1,b2,b3,b4) | GDBIT(b5))
245 #define GDBITS7(b0,b1,b2,b3,b4,b5,b6) \
246 (GDBITS6(b0,b1,b2,b3,b4,b5) | GDBIT(b6))
247 #define GDBITS8(b0,b1,b2,b3,b4,b5,b6,b7) \
248 (GDBITS7(b0,b1,b2,b3,b4,b5,b6) | GDBIT(b7))
249 #define GDBITS9(b0,b1,b2,b3,b4,b5,b6,b7,b8) \
250 (GDBITS8(b0,b1,b2,b3,b4,b5,b6,b7) | GDBIT(b8))
251 #define GDBITS10(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9) \
252 (GDBITS9(b0,b1,b2,b3,b4,b5,b6,b7,b8) | GDBIT(b9))
254 const uint64_t gte_reg_reads[64] = {
255 [GTE_RTPS] = 0x1f0000ff00000000ll | GDBITS7(0,1,13,14,17,18,19),
256 [GTE_NCLIP] = GDBITS3(12,13,14),
257 [GTE_OP] = GCBITS3(0,2,4) | GDBITS3(9,10,11),
258 [GTE_DPCS] = GCBITS3(21,22,23) | GDBITS4(6,8,21,22),
259 [GTE_INTPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22),
260 [GTE_MVMVA] = 0x00ffffff00000000ll | GDBITS9(0,1,2,3,4,5,9,10,11), // XXX: maybe decode further?
261 [GTE_NCDS] = 0x00ffff0000000000ll | GDBITS6(0,1,6,8,21,22),
262 [GTE_CDP] = 0x00ffe00000000000ll | GDBITS7(6,8,9,10,11,21,22),
263 [GTE_NCDT] = 0x00ffff0000000000ll | GDBITS8(0,1,2,3,4,5,6,8),
264 [GTE_NCCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22),
265 [GTE_CC] = 0x001fe00000000000ll | GDBITS6(6,9,10,11,21,22),
266 [GTE_NCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22),
267 [GTE_NCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6),
268 [GTE_SQR] = GDBITS3(9,10,11),
269 [GTE_DCPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22),
270 [GTE_DPCT] = GCBITS3(21,22,23) | GDBITS4(8,20,21,22),
271 [GTE_AVSZ3] = GCBIT(29) | GDBITS3(17,18,19),
272 [GTE_AVSZ4] = GCBIT(30) | GDBITS4(16,17,18,19),
273 [GTE_RTPT] = 0x1f0000ff00000000ll | GDBITS7(0,1,2,3,4,5,19),
274 [GTE_GPF] = GDBITS7(6,8,9,10,11,21,22),
275 [GTE_GPL] = GDBITS10(6,8,9,10,11,21,22,25,26,27),
276 [GTE_NCCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6),
279 // note: this excludes gteFLAG that is always written to
280 const uint64_t gte_reg_writes[64] = {
281 [GTE_RTPS] = 0x0f0f7f00ll,
282 [GTE_NCLIP] = GDBIT(24),
283 [GTE_OP] = GDBITS6(9,10,11,25,26,27),
284 [GTE_DPCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
285 [GTE_INTPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
286 [GTE_MVMVA] = GDBITS6(9,10,11,25,26,27),
287 [GTE_NCDS] = GDBITS9(9,10,11,20,21,22,25,26,27),
288 [GTE_CDP] = GDBITS9(9,10,11,20,21,22,25,26,27),
289 [GTE_NCDT] = GDBITS9(9,10,11,20,21,22,25,26,27),
290 [GTE_NCCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
291 [GTE_CC] = GDBITS9(9,10,11,20,21,22,25,26,27),
292 [GTE_NCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
293 [GTE_NCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
294 [GTE_SQR] = GDBITS6(9,10,11,25,26,27),
295 [GTE_DCPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
296 [GTE_DPCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
297 [GTE_AVSZ3] = GDBITS2(7,24),
298 [GTE_AVSZ4] = GDBITS2(7,24),
299 [GTE_RTPT] = 0x0f0f7f00ll,
300 [GTE_GPF] = GDBITS9(9,10,11,20,21,22,25,26,27),
301 [GTE_GPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
302 [GTE_NCCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
305 static int ari64_init()
307 static u32 scratch_buf[8*8*2] __attribute__((aligned(64)));
308 extern void (*psxCP2[64])();
309 extern void psxNULL();
310 extern unsigned char *out;
314 new_dyna_pcsx_mem_init();
316 for (i = 0; i < ARRAY_SIZE(gte_handlers); i++)
317 if (psxCP2[i] != psxNULL)
318 gte_handlers[i] = psxCP2[i];
320 #if defined(__arm__) && !defined(DRC_DBG)
321 gte_handlers[0x06] = gteNCLIP_arm;
323 gte_handlers_nf[0x01] = gteRTPS_nf_arm;
324 gte_handlers_nf[0x30] = gteRTPT_nf_arm;
327 // compiler's _nf version is still a lot slower than neon
328 // _nf_arm RTPS is roughly the same, RTPT slower
329 gte_handlers[0x01] = gte_handlers_nf[0x01] = gteRTPS_neon;
330 gte_handlers[0x30] = gte_handlers_nf[0x30] = gteRTPT_neon;
334 memcpy(gte_handlers_nf, gte_handlers, sizeof(gte_handlers_nf));
337 zeromem_ptr = zero_mem;
338 scratch_buf_ptr = scratch_buf;
340 SysPrintf("Mapped (RAM/scrp/ROM/LUTs/TC):\n");
341 SysPrintf("%p/%p/%p/%p/%p\n",
342 psxM, psxH, psxR, mem_rtab, out);
347 static void ari64_reset()
349 printf("ari64_reset\n");
350 new_dyna_pcsx_mem_reset();
351 invalidate_all_pages();
353 pending_exception = 1;
356 // execute until predefined leave points
357 // (HLE softcall exit and BIOS fastboot end)
358 static void ari64_execute_until()
360 schedule_timeslice();
362 evprintf("ari64_execute %08x, %u->%u (%d)\n", psxRegs.pc,
363 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
365 new_dyna_start(dynarec_local);
367 evprintf("ari64_execute end %08x, %u->%u (%d)\n", psxRegs.pc,
368 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
371 static void ari64_execute()
374 ari64_execute_until();
375 evprintf("drc left @%08x\n", psxRegs.pc);
379 static void ari64_clear(u32 addr, u32 size)
381 u32 start, end, main_ram;
383 size *= 4; /* PCSX uses DMA units (words) */
385 evprintf("ari64_clear %08x %04x\n", addr, size);
387 /* check for RAM mirrors */
388 main_ram = (addr & 0xffe00000) == 0x80000000;
391 end = (addr + size) >> 12;
393 for (; start <= end; start++)
394 if (!main_ram || !invalid_code[start])
395 invalidate_block(start);
398 #ifdef ICACHE_EMULATION
399 static void ari64_notify(int note, void *data) {
401 Should be fixed when ARM dynarec has proper icache emulation.
404 case R3000ACPU_NOTIFY_CACHE_UNISOLATED:
406 case R3000ACPU_NOTIFY_CACHE_ISOLATED:
408 case R3000ACPU_NOTIFY_DMA3_EXE_LOAD:
416 static void ari64_shutdown()
418 new_dynarec_cleanup();
419 new_dyna_pcsx_mem_shutdown();
428 #ifdef ICACHE_EMULATION
434 #else // if DRC_DISABLE
436 unsigned int address;
437 int pending_exception, stop;
438 unsigned int next_interupt;
439 int new_dynarec_did_compile;
440 int cycle_multiplier;
441 int cycle_multiplier_override;
442 int new_dynarec_hacks_pergame;
443 int new_dynarec_hacks;
449 void *scratch_buf_ptr;
450 void new_dynarec_init() {}
451 void new_dyna_start(void *context) {}
452 void new_dynarec_cleanup() {}
453 void new_dynarec_clear_full() {}
454 void invalidate_all_pages() {}
455 void invalidate_block(unsigned int block) {}
456 void new_dyna_pcsx_mem_init(void) {}
457 void new_dyna_pcsx_mem_reset(void) {}
458 void new_dyna_pcsx_mem_load_state(void) {}
459 void new_dyna_pcsx_mem_shutdown(void) {}
460 int new_dynarec_save_blocks(void *save, int size) { return 0; }
461 void new_dynarec_load_blocks(const void *save, int size) {}
468 extern u32 last_io_addr;
470 static void dump_mem(const char *fname, void *mem, size_t size)
472 FILE *f1 = fopen(fname, "wb");
474 f1 = fopen(strrchr(fname, '/') + 1, "wb");
475 fwrite(mem, 1, size, f1);
479 static u32 memcheck_read(u32 a)
481 if ((a >> 16) == 0x1f80)
483 return *(u32 *)(psxH + (a & 0xfffc));
485 if ((a >> 16) == 0x1f00)
487 return *(u32 *)(psxP + (a & 0xfffc));
489 // if ((a & ~0xe0600000) < 0x200000)
491 return *(u32 *)(psxM + (a & 0x1ffffc));
495 void do_insn_trace(void)
497 static psxRegisters oldregs;
498 static u32 old_io_addr = (u32)-1;
499 static u32 old_io_data = 0xbad0c0de;
500 static u32 event_cycles_o[PSXINT_COUNT];
501 u32 *allregs_p = (void *)&psxRegs;
502 u32 *allregs_o = (void *)&oldregs;
507 //last_io_addr = 0x5e2c8;
509 f = fopen("tracelog", "wb");
512 oldregs.code = psxRegs.code; // don't care
513 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
514 if (allregs_p[i] != allregs_o[i]) {
516 fwrite(&allregs_p[i], 1, 4, f);
517 allregs_o[i] = allregs_p[i];
521 for (i = 0; i < PSXINT_COUNT; i++) {
522 if (event_cycles[i] != event_cycles_o[i]) {
524 fwrite(&byte, 1, 1, f);
526 fwrite(&event_cycles[i], 1, 4, f);
527 event_cycles_o[i] = event_cycles[i];
531 if (old_io_addr != last_io_addr) {
533 fwrite(&byte, 1, 1, f);
534 fwrite(&last_io_addr, 1, 4, f);
535 old_io_addr = last_io_addr;
537 io_data = memcheck_read(last_io_addr);
538 if (old_io_data != io_data) {
540 fwrite(&byte, 1, 1, f);
541 fwrite(&io_data, 1, 4, f);
542 old_io_data = io_data;
545 fwrite(&byte, 1, 1, f);
548 if (psxRegs.cycle == 190230) {
549 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
550 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
558 static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
559 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
560 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
561 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
562 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
564 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
565 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
566 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
567 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
569 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
570 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
571 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
572 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
574 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
575 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
576 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
577 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
579 "PC", "code", "cycle", "interrupt",
587 static int miss_log_i;
588 #define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
589 #define miss_log_mask (miss_log_len-1)
591 static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
593 miss_log[miss_log_i].reg = reg;
594 miss_log[miss_log_i].val = val;
595 miss_log[miss_log_i].val_expect = val_expect;
596 miss_log[miss_log_i].pc = pc;
597 miss_log[miss_log_i].cycle = cycle;
598 miss_log_i = (miss_log_i + 1) & miss_log_mask;
603 void do_insn_cmp(void)
605 static psxRegisters rregs;
606 static u32 mem_addr, mem_val;
607 u32 *allregs_p = (void *)&psxRegs;
608 u32 *allregs_e = (void *)&rregs;
609 static u32 ppc, failcount;
610 int i, ret, bad = 0, which_event = -1;
615 f = fopen("tracelog", "rb");
618 if ((ret = fread(&code, 1, 1, f)) <= 0)
627 fread(&which_event, 1, 1, f);
628 fread(&ev_cycles, 1, 4, f);
631 fread(&mem_addr, 1, 4, f);
634 fread(&mem_val, 1, 4, f);
637 fread(&allregs_e[code], 1, 4, f);
645 psxRegs.code = rregs.code; // don't care
646 psxRegs.cycle = rregs.cycle;
647 psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
649 //if (psxRegs.cycle == 166172) breakme();
651 if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
652 mem_val == memcheck_read(mem_addr)
658 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
659 if (allregs_p[i] != allregs_e[i]) {
660 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
667 if (mem_val != memcheck_read(mem_addr)) {
668 printf("bad mem @%08x: %08x %08x\n", mem_addr, memcheck_read(mem_addr), mem_val);
672 if (which_event >= 0 && event_cycles[which_event] != ev_cycles) {
673 printf("bad ev_cycles #%d: %08x %08x\n", which_event, event_cycles[which_event], ev_cycles);
677 if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
678 static int last_mcycle;
679 if (last_mcycle != psxRegs.cycle >> 20) {
680 printf("%u\n", psxRegs.cycle);
681 last_mcycle = psxRegs.cycle >> 20;
688 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
689 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
690 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
691 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
692 printf("-- %d\n", bad);
693 for (i = 0; i < 8; i++)
694 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
695 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+24]);
696 printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
697 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
698 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
701 psxRegs.cycle = rregs.cycle + 2; // sync timing