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"
14 #include "../../../cdrom.h"
15 #include "../../../psxdma.h"
16 #include "../../../mdec.h"
17 #include "../../../gte_arm.h"
18 #include "../../../gte_neon.h"
20 #include "../../../gte.h"
23 #include "../../../gte.h"
26 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
28 //#define evprintf printf
31 char invalid_code[0x100000];
32 static u32 scratch_buf[8*8*2] __attribute__((aligned(64)));
33 u32 event_cycles[PSXINT_COUNT];
35 static void schedule_timeslice(void)
37 u32 i, c = psxRegs.cycle;
38 u32 irqs = psxRegs.interrupt;
42 for (i = 0; irqs != 0; i++, irqs >>= 1) {
45 dif = event_cycles[i] - c;
46 //evprintf(" ev %d\n", dif);
47 if (0 < dif && dif < min)
50 next_interupt = c + min;
53 typedef void (irq_func)();
55 static irq_func * const irq_funcs[] = {
56 [PSXINT_SIO] = sioInterrupt,
57 [PSXINT_CDR] = cdrInterrupt,
58 [PSXINT_CDREAD] = cdrReadInterrupt,
59 [PSXINT_GPUDMA] = gpuInterrupt,
60 [PSXINT_MDECOUTDMA] = mdec1Interrupt,
61 [PSXINT_SPUDMA] = spuInterrupt,
62 [PSXINT_MDECINDMA] = mdec0Interrupt,
63 [PSXINT_GPUOTCDMA] = gpuotcInterrupt,
64 [PSXINT_CDRDMA] = cdrDmaInterrupt,
65 [PSXINT_CDRLID] = cdrLidSeekInterrupt,
66 [PSXINT_CDRPLAY] = cdrPlayInterrupt,
67 [PSXINT_SPU_UPDATE] = spuUpdate,
68 [PSXINT_RCNT] = psxRcntUpdate,
71 /* local dupe of psxBranchTest, using event_cycles */
72 static void irq_test(void)
74 u32 irqs = psxRegs.interrupt;
75 u32 cycle = psxRegs.cycle;
78 // irq_funcs() may queue more irqs
79 psxRegs.interrupt = 0;
81 for (irq = 0, irq_bits = irqs; irq_bits != 0; irq++, irq_bits >>= 1) {
84 if ((s32)(cycle - event_cycles[irq]) >= 0) {
89 psxRegs.interrupt |= irqs;
91 if ((psxHu32(0x1070) & psxHu32(0x1074)) && (Status & 0x401) == 0x401) {
92 psxException(0x400, 0);
93 pending_exception = 1;
99 evprintf(" +ge %08x, %u->%u\n", psxRegs.pc, psxRegs.cycle, next_interupt);
103 //pending_exception = 1;
105 schedule_timeslice();
107 evprintf(" -ge %08x, %u->%u (%d)\n", psxRegs.pc, psxRegs.cycle,
108 next_interupt, next_interupt - psxRegs.cycle);
112 extern void MTC0(int reg, u32 val);
114 void pcsx_mtc0(u32 reg, u32 val)
116 evprintf("MTC0 %d #%x @%08x %u\n", reg, val, psxRegs.pc, psxRegs.cycle);
119 if (Cause & Status & 0x0300) // possible sw irq
120 pending_exception = 1;
123 void pcsx_mtc0_ds(u32 reg, u32 val)
125 evprintf("MTC0 %d #%x @%08x %u\n", reg, val, psxRegs.pc, psxRegs.cycle);
129 void new_dyna_before_save(void)
131 psxRegs.interrupt &= ~(1 << PSXINT_RCNT); // old savestate compat
133 // psxRegs.intCycle is always maintained, no need to convert
136 void new_dyna_after_save(void)
138 psxRegs.interrupt |= 1 << PSXINT_RCNT;
141 static void new_dyna_restore(void)
144 for (i = 0; i < PSXINT_COUNT; i++)
145 event_cycles[i] = psxRegs.intCycle[i].sCycle + psxRegs.intCycle[i].cycle;
147 event_cycles[PSXINT_RCNT] = psxNextsCounter + psxNextCounter;
148 psxRegs.interrupt |= 1 << PSXINT_RCNT;
149 psxRegs.interrupt &= (1 << PSXINT_COUNT) - 1;
151 new_dyna_pcsx_mem_load_state();
154 void new_dyna_freeze(void *f, int mode)
156 const char header_save[8] = "ariblks";
157 uint32_t addrs[1024 * 4];
162 if (mode != 0) { // save
163 size = new_dynarec_save_blocks(addrs, sizeof(addrs));
167 SaveFuncs.write(f, header_save, sizeof(header_save));
168 SaveFuncs.write(f, &size, sizeof(size));
169 SaveFuncs.write(f, addrs, size);
174 bytes = SaveFuncs.read(f, header, sizeof(header));
175 if (bytes != sizeof(header) || strcmp(header, header_save)) {
177 SaveFuncs.seek(f, -bytes, SEEK_CUR);
180 SaveFuncs.read(f, &size, sizeof(size));
183 if (size > sizeof(addrs)) {
184 bytes = size - sizeof(addrs);
185 SaveFuncs.seek(f, bytes, SEEK_CUR);
186 size = sizeof(addrs);
188 bytes = SaveFuncs.read(f, addrs, size);
192 new_dynarec_load_blocks(addrs, size);
195 //printf("drc: %d block info entries %s\n", size/8, mode ? "saved" : "loaded");
199 void *gte_handlers[64];
201 void *gte_handlers_nf[64] = {
202 NULL , gteRTPS_nf , NULL , NULL , NULL , NULL , gteNCLIP_nf, NULL , // 00
203 NULL , NULL , NULL , NULL , gteOP_nf , NULL , NULL , NULL , // 08
204 gteDPCS_nf, gteINTPL_nf, gteMVMVA_nf, gteNCDS_nf, gteCDP_nf, NULL , gteNCDT_nf , NULL , // 10
205 NULL , NULL , NULL , gteNCCS_nf, gteCC_nf , NULL , gteNCS_nf , NULL , // 18
206 gteNCT_nf , NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 20
207 gteSQR_nf , gteDCPL_nf , gteDPCT_nf , NULL , NULL , gteAVSZ3_nf, gteAVSZ4_nf, NULL , // 28
208 gteRTPT_nf, NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 30
209 NULL , NULL , NULL , NULL , NULL , gteGPF_nf , gteGPL_nf , gteNCCT_nf, // 38
212 const char *gte_regnames[64] = {
213 NULL , "RTPS" , NULL , NULL , NULL , NULL , "NCLIP", NULL , // 00
214 NULL , NULL , NULL , NULL , "OP" , NULL , NULL , NULL , // 08
215 "DPCS", "INTPL", "MVMVA", "NCDS", "CDP", NULL , "NCDT" , NULL , // 10
216 NULL , NULL , NULL , "NCCS", "CC" , NULL , "NCS" , NULL , // 18
217 "NCT" , NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 20
218 "SQR" , "DCPL" , "DPCT" , NULL , NULL , "AVSZ3", "AVSZ4", NULL , // 28
219 "RTPT", NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 30
220 NULL , NULL , NULL , NULL , NULL , "GPF" , "GPL" , "NCCT", // 38
223 /* from gte.txt.. not sure if this is any good. */
224 const char gte_cycletab[64] = {
225 /* 1 2 3 4 5 6 7 8 9 a b c d e f */
226 0, 15, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 6, 0, 0, 0,
227 8, 8, 8, 19, 13, 0, 44, 0, 0, 0, 0, 17, 11, 0, 14, 0,
228 30, 0, 0, 0, 0, 0, 0, 0, 5, 8, 17, 0, 0, 5, 6, 0,
229 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 39,
236 #define GCBITS3(b0,b1,b2) \
237 (GCBIT(b0) | GCBIT(b1) | GCBIT(b2))
238 #define GDBITS2(b0,b1) \
239 (GDBIT(b0) | GDBIT(b1))
240 #define GDBITS3(b0,b1,b2) \
241 (GDBITS2(b0,b1) | GDBIT(b2))
242 #define GDBITS4(b0,b1,b2,b3) \
243 (GDBITS3(b0,b1,b2) | GDBIT(b3))
244 #define GDBITS5(b0,b1,b2,b3,b4) \
245 (GDBITS4(b0,b1,b2,b3) | GDBIT(b4))
246 #define GDBITS6(b0,b1,b2,b3,b4,b5) \
247 (GDBITS5(b0,b1,b2,b3,b4) | GDBIT(b5))
248 #define GDBITS7(b0,b1,b2,b3,b4,b5,b6) \
249 (GDBITS6(b0,b1,b2,b3,b4,b5) | GDBIT(b6))
250 #define GDBITS8(b0,b1,b2,b3,b4,b5,b6,b7) \
251 (GDBITS7(b0,b1,b2,b3,b4,b5,b6) | GDBIT(b7))
252 #define GDBITS9(b0,b1,b2,b3,b4,b5,b6,b7,b8) \
253 (GDBITS8(b0,b1,b2,b3,b4,b5,b6,b7) | GDBIT(b8))
254 #define GDBITS10(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9) \
255 (GDBITS9(b0,b1,b2,b3,b4,b5,b6,b7,b8) | GDBIT(b9))
257 const uint64_t gte_reg_reads[64] = {
258 [GTE_RTPS] = 0x1f0000ff00000000ll | GDBITS7(0,1,13,14,17,18,19),
259 [GTE_NCLIP] = GDBITS3(12,13,14),
260 [GTE_OP] = GCBITS3(0,2,4) | GDBITS3(9,10,11),
261 [GTE_DPCS] = GCBITS3(21,22,23) | GDBITS4(6,8,21,22),
262 [GTE_INTPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22),
263 [GTE_MVMVA] = 0x00ffffff00000000ll | GDBITS9(0,1,2,3,4,5,9,10,11), // XXX: maybe decode further?
264 [GTE_NCDS] = 0x00ffff0000000000ll | GDBITS6(0,1,6,8,21,22),
265 [GTE_CDP] = 0x00ffe00000000000ll | GDBITS7(6,8,9,10,11,21,22),
266 [GTE_NCDT] = 0x00ffff0000000000ll | GDBITS8(0,1,2,3,4,5,6,8),
267 [GTE_NCCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22),
268 [GTE_CC] = 0x001fe00000000000ll | GDBITS6(6,9,10,11,21,22),
269 [GTE_NCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22),
270 [GTE_NCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6),
271 [GTE_SQR] = GDBITS3(9,10,11),
272 [GTE_DCPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22),
273 [GTE_DPCT] = GCBITS3(21,22,23) | GDBITS4(8,20,21,22),
274 [GTE_AVSZ3] = GCBIT(29) | GDBITS3(17,18,19),
275 [GTE_AVSZ4] = GCBIT(30) | GDBITS4(16,17,18,19),
276 [GTE_RTPT] = 0x1f0000ff00000000ll | GDBITS7(0,1,2,3,4,5,19),
277 [GTE_GPF] = GDBITS7(6,8,9,10,11,21,22),
278 [GTE_GPL] = GDBITS10(6,8,9,10,11,21,22,25,26,27),
279 [GTE_NCCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6),
282 // note: this excludes gteFLAG that is always written to
283 const uint64_t gte_reg_writes[64] = {
284 [GTE_RTPS] = 0x0f0f7f00ll,
285 [GTE_NCLIP] = GDBIT(24),
286 [GTE_OP] = GDBITS6(9,10,11,25,26,27),
287 [GTE_DPCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
288 [GTE_INTPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
289 [GTE_MVMVA] = GDBITS6(9,10,11,25,26,27),
290 [GTE_NCDS] = GDBITS9(9,10,11,20,21,22,25,26,27),
291 [GTE_CDP] = GDBITS9(9,10,11,20,21,22,25,26,27),
292 [GTE_NCDT] = GDBITS9(9,10,11,20,21,22,25,26,27),
293 [GTE_NCCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
294 [GTE_CC] = GDBITS9(9,10,11,20,21,22,25,26,27),
295 [GTE_NCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
296 [GTE_NCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
297 [GTE_SQR] = GDBITS6(9,10,11,25,26,27),
298 [GTE_DCPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
299 [GTE_DPCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
300 [GTE_AVSZ3] = GDBITS2(7,24),
301 [GTE_AVSZ4] = GDBITS2(7,24),
302 [GTE_RTPT] = 0x0f0f7f00ll,
303 [GTE_GPF] = GDBITS9(9,10,11,20,21,22,25,26,27),
304 [GTE_GPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
305 [GTE_NCCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
308 static int ari64_init()
310 extern void (*psxCP2[64])();
311 extern void psxNULL();
312 extern unsigned char *out;
316 new_dyna_pcsx_mem_init();
318 for (i = 0; i < ARRAY_SIZE(gte_handlers); i++)
319 if (psxCP2[i] != psxNULL)
320 gte_handlers[i] = psxCP2[i];
322 #if defined(__arm__) && !defined(DRC_DBG)
323 gte_handlers[0x06] = gteNCLIP_arm;
325 gte_handlers_nf[0x01] = gteRTPS_nf_arm;
326 gte_handlers_nf[0x30] = gteRTPT_nf_arm;
329 // compiler's _nf version is still a lot slower than neon
330 // _nf_arm RTPS is roughly the same, RTPT slower
331 gte_handlers[0x01] = gte_handlers_nf[0x01] = gteRTPS_neon;
332 gte_handlers[0x30] = gte_handlers_nf[0x30] = gteRTPT_neon;
336 memcpy(gte_handlers_nf, gte_handlers, sizeof(gte_handlers_nf));
340 zeromem_ptr = zero_mem;
341 scratch_buf_ptr = scratch_buf;
343 SysPrintf("Mapped (RAM/scrp/ROM/LUTs/TC):\n");
344 SysPrintf("%08x/%08x/%08x/%08x/%08x\n",
345 psxM, psxH, psxR, mem_rtab, out);
350 static void ari64_reset()
352 printf("ari64_reset\n");
353 new_dyna_pcsx_mem_reset();
354 invalidate_all_pages();
356 pending_exception = 1;
359 // execute until predefined leave points
360 // (HLE softcall exit and BIOS fastboot end)
361 static void ari64_execute_until()
363 schedule_timeslice();
365 evprintf("ari64_execute %08x, %u->%u (%d)\n", psxRegs.pc,
366 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
370 evprintf("ari64_execute end %08x, %u->%u (%d)\n", psxRegs.pc,
371 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
374 static void ari64_execute()
377 ari64_execute_until();
378 evprintf("drc left @%08x\n", psxRegs.pc);
382 static void ari64_clear(u32 addr, u32 size)
384 u32 start, end, main_ram;
386 size *= 4; /* PCSX uses DMA units (words) */
388 evprintf("ari64_clear %08x %04x\n", addr, size);
390 /* check for RAM mirrors */
391 main_ram = (addr & 0xffe00000) == 0x80000000;
394 end = (addr + size) >> 12;
396 for (; start <= end; start++)
397 if (!main_ram || !invalid_code[start])
398 invalidate_block(start);
401 static void ari64_shutdown()
403 new_dynarec_cleanup();
404 new_dyna_pcsx_mem_shutdown();
407 extern void intExecute();
408 extern void intExecuteT();
409 extern void intExecuteBlock();
410 extern void intExecuteBlockT();
412 #define intExecuteT intExecute
413 #define intExecuteBlockT intExecuteBlock
432 void do_insn_trace() {}
433 void do_insn_cmp() {}
437 unsigned int address;
438 int pending_exception, stop;
440 int new_dynarec_did_compile;
441 int cycle_multiplier;
442 int new_dynarec_hacks;
448 void *scratch_buf_ptr;
449 void new_dynarec_init() { (void)ari64_execute; }
450 void new_dyna_start() {}
451 void new_dynarec_cleanup() {}
452 void new_dynarec_clear_full() {}
453 void invalidate_all_pages() {}
454 void invalidate_block(unsigned int block) {}
455 void new_dyna_pcsx_mem_init(void) {}
456 void new_dyna_pcsx_mem_reset(void) {}
457 void new_dyna_pcsx_mem_load_state(void) {}
458 void new_dyna_pcsx_mem_shutdown(void) {}
459 int new_dynarec_save_blocks(void *save, int size) { return 0; }
460 void new_dynarec_load_blocks(const void *save, int size) {}
467 extern u32 last_io_addr;
469 static void dump_mem(const char *fname, void *mem, size_t size)
471 FILE *f1 = fopen(fname, "wb");
473 f1 = fopen(strrchr(fname, '/') + 1, "wb");
474 fwrite(mem, 1, size, f1);
478 static u32 memcheck_read(u32 a)
480 if ((a >> 16) == 0x1f80)
482 return *(u32 *)(psxH + (a & 0xfffc));
484 if ((a >> 16) == 0x1f00)
486 return *(u32 *)(psxP + (a & 0xfffc));
488 // if ((a & ~0xe0600000) < 0x200000)
490 return *(u32 *)(psxM + (a & 0x1ffffc));
493 void do_insn_trace(void)
495 static psxRegisters oldregs;
496 static u32 old_io_addr = (u32)-1;
497 static u32 old_io_data = 0xbad0c0de;
498 static u32 event_cycles_o[PSXINT_COUNT];
499 u32 *allregs_p = (void *)&psxRegs;
500 u32 *allregs_o = (void *)&oldregs;
505 //last_io_addr = 0x5e2c8;
507 f = fopen("tracelog", "wb");
510 oldregs.code = psxRegs.code; // don't care
511 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
512 if (allregs_p[i] != allregs_o[i]) {
514 fwrite(&allregs_p[i], 1, 4, f);
515 allregs_o[i] = allregs_p[i];
519 for (i = 0; i < PSXINT_COUNT; i++) {
520 if (event_cycles[i] != event_cycles_o[i]) {
522 fwrite(&byte, 1, 1, f);
524 fwrite(&event_cycles[i], 1, 4, f);
525 event_cycles_o[i] = event_cycles[i];
529 if (old_io_addr != last_io_addr) {
531 fwrite(&byte, 1, 1, f);
532 fwrite(&last_io_addr, 1, 4, f);
533 old_io_addr = last_io_addr;
535 io_data = memcheck_read(last_io_addr);
536 if (old_io_data != io_data) {
538 fwrite(&byte, 1, 1, f);
539 fwrite(&io_data, 1, 4, f);
540 old_io_data = io_data;
543 fwrite(&byte, 1, 1, f);
546 if (psxRegs.cycle == 190230) {
547 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
548 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
555 static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
556 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
557 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
558 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
559 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
561 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
562 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
563 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
564 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
566 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
567 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
568 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
569 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
571 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
572 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
573 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
574 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
576 "PC", "code", "cycle", "interrupt",
584 static int miss_log_i;
585 #define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
586 #define miss_log_mask (miss_log_len-1)
588 static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
590 miss_log[miss_log_i].reg = reg;
591 miss_log[miss_log_i].val = val;
592 miss_log[miss_log_i].val_expect = val_expect;
593 miss_log[miss_log_i].pc = pc;
594 miss_log[miss_log_i].cycle = cycle;
595 miss_log_i = (miss_log_i + 1) & miss_log_mask;
600 void do_insn_cmp(void)
602 static psxRegisters rregs;
603 static u32 mem_addr, mem_val;
604 u32 *allregs_p = (void *)&psxRegs;
605 u32 *allregs_e = (void *)&rregs;
606 static u32 ppc, failcount;
607 int i, ret, bad = 0, which_event = -1;
612 f = fopen("tracelog", "rb");
615 if ((ret = fread(&code, 1, 1, f)) <= 0)
624 fread(&which_event, 1, 1, f);
625 fread(&ev_cycles, 1, 4, f);
628 fread(&mem_addr, 1, 4, f);
631 fread(&mem_val, 1, 4, f);
634 fread(&allregs_e[code], 1, 4, f);
642 psxRegs.code = rregs.code; // don't care
643 psxRegs.cycle = rregs.cycle;
644 psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
646 //if (psxRegs.cycle == 166172) breakme();
648 if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
649 mem_val == memcheck_read(mem_addr)
655 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
656 if (allregs_p[i] != allregs_e[i]) {
657 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
662 if (mem_val != memcheck_read(mem_addr)) {
663 printf("bad mem @%08x: %08x %08x\n", mem_addr, memcheck_read(mem_addr), mem_val);
667 if (which_event >= 0 && event_cycles[which_event] != ev_cycles) {
668 printf("bad ev_cycles #%d: %08x %08x\n", which_event, event_cycles[which_event], ev_cycles);
672 if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
673 static int last_mcycle;
674 if (last_mcycle != psxRegs.cycle >> 20) {
675 printf("%u\n", psxRegs.cycle);
676 last_mcycle = psxRegs.cycle >> 20;
683 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
684 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
685 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
686 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
687 printf("-- %d\n", bad);
688 for (i = 0; i < 8; i++)
689 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
690 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+24]);
691 printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
692 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
693 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
696 psxRegs.cycle = rregs.cycle + 2; // sync timing