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
221 /* from gte.txt.. not sure if this is any good. */
222 const char gte_cycletab[64] = {
223 /* 1 2 3 4 5 6 7 8 9 a b c d e f */
224 0, 15, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 6, 0, 0, 0,
225 8, 8, 8, 19, 13, 0, 44, 0, 0, 0, 0, 17, 11, 0, 14, 0,
226 30, 0, 0, 0, 0, 0, 0, 0, 5, 8, 17, 0, 0, 5, 6, 0,
227 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 39,
234 #define GCBITS3(b0,b1,b2) \
235 (GCBIT(b0) | GCBIT(b1) | GCBIT(b2))
236 #define GDBITS2(b0,b1) \
237 (GDBIT(b0) | GDBIT(b1))
238 #define GDBITS3(b0,b1,b2) \
239 (GDBITS2(b0,b1) | GDBIT(b2))
240 #define GDBITS4(b0,b1,b2,b3) \
241 (GDBITS3(b0,b1,b2) | GDBIT(b3))
242 #define GDBITS5(b0,b1,b2,b3,b4) \
243 (GDBITS4(b0,b1,b2,b3) | GDBIT(b4))
244 #define GDBITS6(b0,b1,b2,b3,b4,b5) \
245 (GDBITS5(b0,b1,b2,b3,b4) | GDBIT(b5))
246 #define GDBITS7(b0,b1,b2,b3,b4,b5,b6) \
247 (GDBITS6(b0,b1,b2,b3,b4,b5) | GDBIT(b6))
248 #define GDBITS8(b0,b1,b2,b3,b4,b5,b6,b7) \
249 (GDBITS7(b0,b1,b2,b3,b4,b5,b6) | GDBIT(b7))
250 #define GDBITS9(b0,b1,b2,b3,b4,b5,b6,b7,b8) \
251 (GDBITS8(b0,b1,b2,b3,b4,b5,b6,b7) | GDBIT(b8))
252 #define GDBITS10(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9) \
253 (GDBITS9(b0,b1,b2,b3,b4,b5,b6,b7,b8) | GDBIT(b9))
255 const uint64_t gte_reg_reads[64] = {
256 [GTE_RTPS] = 0x1f0000ff00000000ll | GDBITS7(0,1,13,14,17,18,19),
257 [GTE_NCLIP] = GDBITS3(12,13,14),
258 [GTE_OP] = GCBITS3(0,2,4) | GDBITS3(9,10,11),
259 [GTE_DPCS] = GCBITS3(21,22,23) | GDBITS4(6,8,21,22),
260 [GTE_INTPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22),
261 [GTE_MVMVA] = 0x00ffffff00000000ll | GDBITS9(0,1,2,3,4,5,9,10,11), // XXX: maybe decode further?
262 [GTE_NCDS] = 0x00ffff0000000000ll | GDBITS6(0,1,6,8,21,22),
263 [GTE_CDP] = 0x00ffe00000000000ll | GDBITS7(6,8,9,10,11,21,22),
264 [GTE_NCDT] = 0x00ffff0000000000ll | GDBITS8(0,1,2,3,4,5,6,8),
265 [GTE_NCCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22),
266 [GTE_CC] = 0x001fe00000000000ll | GDBITS6(6,9,10,11,21,22),
267 [GTE_NCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22),
268 [GTE_NCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6),
269 [GTE_SQR] = GDBITS3(9,10,11),
270 [GTE_DCPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22),
271 [GTE_DPCT] = GCBITS3(21,22,23) | GDBITS4(8,20,21,22),
272 [GTE_AVSZ3] = GCBIT(29) | GDBITS3(17,18,19),
273 [GTE_AVSZ4] = GCBIT(30) | GDBITS4(16,17,18,19),
274 [GTE_RTPT] = 0x1f0000ff00000000ll | GDBITS7(0,1,2,3,4,5,19),
275 [GTE_GPF] = GDBITS7(6,8,9,10,11,21,22),
276 [GTE_GPL] = GDBITS10(6,8,9,10,11,21,22,25,26,27),
277 [GTE_NCCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6),
280 // note: this excludes gteFLAG that is always written to
281 const uint64_t gte_reg_writes[64] = {
282 [GTE_RTPS] = 0x0f0f7f00ll,
283 [GTE_NCLIP] = GDBIT(24),
284 [GTE_OP] = GDBITS6(9,10,11,25,26,27),
285 [GTE_DPCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
286 [GTE_INTPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
287 [GTE_MVMVA] = GDBITS6(9,10,11,25,26,27),
288 [GTE_NCDS] = GDBITS9(9,10,11,20,21,22,25,26,27),
289 [GTE_CDP] = GDBITS9(9,10,11,20,21,22,25,26,27),
290 [GTE_NCDT] = GDBITS9(9,10,11,20,21,22,25,26,27),
291 [GTE_NCCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
292 [GTE_CC] = GDBITS9(9,10,11,20,21,22,25,26,27),
293 [GTE_NCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
294 [GTE_NCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
295 [GTE_SQR] = GDBITS6(9,10,11,25,26,27),
296 [GTE_DCPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
297 [GTE_DPCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
298 [GTE_AVSZ3] = GDBITS2(7,24),
299 [GTE_AVSZ4] = GDBITS2(7,24),
300 [GTE_RTPT] = 0x0f0f7f00ll,
301 [GTE_GPF] = GDBITS9(9,10,11,20,21,22,25,26,27),
302 [GTE_GPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
303 [GTE_NCCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
306 static int ari64_init()
308 static u32 scratch_buf[8*8*2] __attribute__((aligned(64)));
309 extern void (*psxCP2[64])();
310 extern void psxNULL();
311 extern unsigned char *out;
315 new_dyna_pcsx_mem_init();
317 for (i = 0; i < ARRAY_SIZE(gte_handlers); i++)
318 if (psxCP2[i] != psxNULL)
319 gte_handlers[i] = psxCP2[i];
321 #if defined(__arm__) && !defined(DRC_DBG)
322 gte_handlers[0x06] = gteNCLIP_arm;
324 gte_handlers_nf[0x01] = gteRTPS_nf_arm;
325 gte_handlers_nf[0x30] = gteRTPT_nf_arm;
328 // compiler's _nf version is still a lot slower than neon
329 // _nf_arm RTPS is roughly the same, RTPT slower
330 gte_handlers[0x01] = gte_handlers_nf[0x01] = gteRTPS_neon;
331 gte_handlers[0x30] = gte_handlers_nf[0x30] = gteRTPT_neon;
335 memcpy(gte_handlers_nf, gte_handlers, sizeof(gte_handlers_nf));
338 zeromem_ptr = zero_mem;
339 scratch_buf_ptr = scratch_buf;
341 SysPrintf("Mapped (RAM/scrp/ROM/LUTs/TC):\n");
342 SysPrintf("%p/%p/%p/%p/%p\n",
343 psxM, psxH, psxR, mem_rtab, out);
348 static void ari64_reset()
350 printf("ari64_reset\n");
351 new_dyna_pcsx_mem_reset();
352 invalidate_all_pages();
354 pending_exception = 1;
357 // execute until predefined leave points
358 // (HLE softcall exit and BIOS fastboot end)
359 static void ari64_execute_until()
361 schedule_timeslice();
363 evprintf("ari64_execute %08x, %u->%u (%d)\n", psxRegs.pc,
364 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
366 new_dyna_start(dynarec_local);
368 evprintf("ari64_execute end %08x, %u->%u (%d)\n", psxRegs.pc,
369 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
372 static void ari64_execute()
375 ari64_execute_until();
376 evprintf("drc left @%08x\n", psxRegs.pc);
380 static void ari64_clear(u32 addr, u32 size)
382 u32 start, end, main_ram;
384 size *= 4; /* PCSX uses DMA units (words) */
386 evprintf("ari64_clear %08x %04x\n", addr, size);
388 /* check for RAM mirrors */
389 main_ram = (addr & 0xffe00000) == 0x80000000;
392 end = (addr + size) >> 12;
394 for (; start <= end; start++)
395 if (!main_ram || !invalid_code[start])
396 invalidate_block(start);
399 #ifdef ICACHE_EMULATION
400 static void ari64_notify(int note, void *data) {
402 Should be fixed when ARM dynarec has proper icache emulation.
405 case R3000ACPU_NOTIFY_CACHE_UNISOLATED:
407 case R3000ACPU_NOTIFY_CACHE_ISOLATED:
409 case R3000ACPU_NOTIFY_DMA3_EXE_LOAD:
417 static void ari64_shutdown()
419 new_dynarec_cleanup();
420 new_dyna_pcsx_mem_shutdown();
429 #ifdef ICACHE_EMULATION
435 #else // if DRC_DISABLE
437 unsigned int address;
438 int pending_exception, stop;
439 unsigned int next_interupt;
440 int new_dynarec_did_compile;
441 int cycle_multiplier;
442 int cycle_multiplier_override;
443 int new_dynarec_hacks_pergame;
444 int new_dynarec_hacks;
450 void *scratch_buf_ptr;
451 void new_dynarec_init() {}
452 void new_dyna_start(void *context) {}
453 void new_dynarec_cleanup() {}
454 void new_dynarec_clear_full() {}
455 void invalidate_all_pages() {}
456 void invalidate_block(unsigned int block) {}
457 void new_dyna_pcsx_mem_init(void) {}
458 void new_dyna_pcsx_mem_reset(void) {}
459 void new_dyna_pcsx_mem_load_state(void) {}
460 void new_dyna_pcsx_mem_shutdown(void) {}
461 int new_dynarec_save_blocks(void *save, int size) { return 0; }
462 void new_dynarec_load_blocks(const void *save, int size) {}
469 extern u32 last_io_addr;
471 static void dump_mem(const char *fname, void *mem, size_t size)
473 FILE *f1 = fopen(fname, "wb");
475 f1 = fopen(strrchr(fname, '/') + 1, "wb");
476 fwrite(mem, 1, size, f1);
480 static u32 memcheck_read(u32 a)
482 if ((a >> 16) == 0x1f80)
484 return *(u32 *)(psxH + (a & 0xfffc));
486 if ((a >> 16) == 0x1f00)
488 return *(u32 *)(psxP + (a & 0xfffc));
490 // if ((a & ~0xe0600000) < 0x200000)
492 return *(u32 *)(psxM + (a & 0x1ffffc));
496 void do_insn_trace(void)
498 static psxRegisters oldregs;
499 static u32 old_io_addr = (u32)-1;
500 static u32 old_io_data = 0xbad0c0de;
501 static u32 event_cycles_o[PSXINT_COUNT];
502 u32 *allregs_p = (void *)&psxRegs;
503 u32 *allregs_o = (void *)&oldregs;
508 //last_io_addr = 0x5e2c8;
510 f = fopen("tracelog", "wb");
513 oldregs.code = psxRegs.code; // don't care
514 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
515 if (allregs_p[i] != allregs_o[i]) {
517 fwrite(&allregs_p[i], 1, 4, f);
518 allregs_o[i] = allregs_p[i];
522 for (i = 0; i < PSXINT_COUNT; i++) {
523 if (event_cycles[i] != event_cycles_o[i]) {
525 fwrite(&byte, 1, 1, f);
527 fwrite(&event_cycles[i], 1, 4, f);
528 event_cycles_o[i] = event_cycles[i];
532 if (old_io_addr != last_io_addr) {
534 fwrite(&byte, 1, 1, f);
535 fwrite(&last_io_addr, 1, 4, f);
536 old_io_addr = last_io_addr;
538 io_data = memcheck_read(last_io_addr);
539 if (old_io_data != io_data) {
541 fwrite(&byte, 1, 1, f);
542 fwrite(&io_data, 1, 4, f);
543 old_io_data = io_data;
546 fwrite(&byte, 1, 1, f);
549 if (psxRegs.cycle == 190230) {
550 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
551 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
559 static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
560 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
561 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
562 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
563 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
565 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
566 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
567 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
568 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
570 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
571 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
572 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
573 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
575 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
576 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
577 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
578 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
580 "PC", "code", "cycle", "interrupt",
588 static int miss_log_i;
589 #define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
590 #define miss_log_mask (miss_log_len-1)
592 static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
594 miss_log[miss_log_i].reg = reg;
595 miss_log[miss_log_i].val = val;
596 miss_log[miss_log_i].val_expect = val_expect;
597 miss_log[miss_log_i].pc = pc;
598 miss_log[miss_log_i].cycle = cycle;
599 miss_log_i = (miss_log_i + 1) & miss_log_mask;
604 void do_insn_cmp(void)
606 static psxRegisters rregs;
607 static u32 mem_addr, mem_val;
608 u32 *allregs_p = (void *)&psxRegs;
609 u32 *allregs_e = (void *)&rregs;
610 static u32 ppc, failcount;
611 int i, ret, bad = 0, which_event = -1;
616 f = fopen("tracelog", "rb");
619 if ((ret = fread(&code, 1, 1, f)) <= 0)
628 fread(&which_event, 1, 1, f);
629 fread(&ev_cycles, 1, 4, f);
632 fread(&mem_addr, 1, 4, f);
635 fread(&mem_val, 1, 4, f);
638 fread(&allregs_e[code], 1, 4, f);
646 psxRegs.code = rregs.code; // don't care
647 psxRegs.cycle = rregs.cycle;
648 psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
650 //if (psxRegs.cycle == 166172) breakme();
652 if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
653 mem_val == memcheck_read(mem_addr)
659 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
660 if (allregs_p[i] != allregs_e[i]) {
661 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
668 if (mem_val != memcheck_read(mem_addr)) {
669 printf("bad mem @%08x: %08x %08x\n", mem_addr, memcheck_read(mem_addr), mem_val);
673 if (which_event >= 0 && event_cycles[which_event] != ev_cycles) {
674 printf("bad ev_cycles #%d: %08x %08x\n", which_event, event_cycles[which_event], ev_cycles);
678 if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
679 static int last_mcycle;
680 if (last_mcycle != psxRegs.cycle >> 20) {
681 printf("%u\n", psxRegs.cycle);
682 last_mcycle = psxRegs.cycle >> 20;
689 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
690 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
691 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
692 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
693 printf("-- %d\n", bad);
694 for (i = 0; i < 8; i++)
695 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
696 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+24]);
697 printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
698 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
699 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
702 psxRegs.cycle = rregs.cycle + 2; // sync timing