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"
22 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
24 //#define evprintf printf
27 char invalid_code[0x100000];
28 static u32 scratch_buf[8*8*2] __attribute__((aligned(64)));
29 u32 event_cycles[PSXINT_COUNT];
31 static void schedule_timeslice(void)
33 u32 i, c = psxRegs.cycle;
34 u32 irqs = psxRegs.interrupt;
38 for (i = 0; irqs != 0; i++, irqs >>= 1) {
41 dif = event_cycles[i] - c;
42 //evprintf(" ev %d\n", dif);
43 if (0 < dif && dif < min)
46 next_interupt = c + min;
49 typedef void (irq_func)();
51 static irq_func * const irq_funcs[] = {
52 [PSXINT_SIO] = sioInterrupt,
53 [PSXINT_CDR] = cdrInterrupt,
54 [PSXINT_CDREAD] = cdrReadInterrupt,
55 [PSXINT_GPUDMA] = gpuInterrupt,
56 [PSXINT_MDECOUTDMA] = mdec1Interrupt,
57 [PSXINT_SPUDMA] = spuInterrupt,
58 [PSXINT_MDECINDMA] = mdec0Interrupt,
59 [PSXINT_GPUOTCDMA] = gpuotcInterrupt,
60 [PSXINT_CDRDMA] = cdrDmaInterrupt,
61 [PSXINT_CDRLID] = cdrLidSeekInterrupt,
62 [PSXINT_CDRPLAY] = cdrPlayInterrupt,
63 [PSXINT_SPU_UPDATE] = spuUpdate,
64 [PSXINT_RCNT] = psxRcntUpdate,
67 /* local dupe of psxBranchTest, using event_cycles */
68 static void irq_test(void)
70 u32 irqs = psxRegs.interrupt;
71 u32 cycle = psxRegs.cycle;
74 // irq_funcs() may queue more irqs
75 psxRegs.interrupt = 0;
77 for (irq = 0, irq_bits = irqs; irq_bits != 0; irq++, irq_bits >>= 1) {
80 if ((s32)(cycle - event_cycles[irq]) >= 0) {
85 psxRegs.interrupt |= irqs;
87 if ((psxHu32(0x1070) & psxHu32(0x1074)) && (Status & 0x401) == 0x401) {
88 psxException(0x400, 0);
89 pending_exception = 1;
95 evprintf(" +ge %08x, %u->%u\n", psxRegs.pc, psxRegs.cycle, next_interupt);
99 //pending_exception = 1;
101 schedule_timeslice();
103 evprintf(" -ge %08x, %u->%u (%d)\n", psxRegs.pc, psxRegs.cycle,
104 next_interupt, next_interupt - psxRegs.cycle);
108 extern void MTC0(int reg, u32 val);
110 void pcsx_mtc0(u32 reg, u32 val)
112 evprintf("MTC0 %d #%x @%08x %u\n", reg, val, psxRegs.pc, psxRegs.cycle);
115 if (Cause & Status & 0x0300) // possible sw irq
116 pending_exception = 1;
119 void pcsx_mtc0_ds(u32 reg, u32 val)
121 evprintf("MTC0 %d #%x @%08x %u\n", reg, val, psxRegs.pc, psxRegs.cycle);
125 void new_dyna_before_save(void)
127 psxRegs.interrupt &= ~(1 << PSXINT_RCNT); // old savestate compat
129 // psxRegs.intCycle is always maintained, no need to convert
132 void new_dyna_after_save(void)
134 psxRegs.interrupt |= 1 << PSXINT_RCNT;
137 static void new_dyna_restore(void)
140 for (i = 0; i < PSXINT_COUNT; i++)
141 event_cycles[i] = psxRegs.intCycle[i].sCycle + psxRegs.intCycle[i].cycle;
143 event_cycles[PSXINT_RCNT] = psxNextsCounter + psxNextCounter;
144 psxRegs.interrupt |= 1 << PSXINT_RCNT;
145 psxRegs.interrupt &= (1 << PSXINT_COUNT) - 1;
147 new_dyna_pcsx_mem_load_state();
150 void new_dyna_freeze(void *f, int mode)
152 const char header_save[8] = "ariblks";
153 uint32_t addrs[1024 * 4];
158 if (mode != 0) { // save
159 size = new_dynarec_save_blocks(addrs, sizeof(addrs));
163 SaveFuncs.write(f, header_save, sizeof(header_save));
164 SaveFuncs.write(f, &size, sizeof(size));
165 SaveFuncs.write(f, addrs, size);
170 bytes = SaveFuncs.read(f, header, sizeof(header));
171 if (bytes != sizeof(header) || strcmp(header, header_save)) {
173 SaveFuncs.seek(f, -bytes, SEEK_CUR);
176 SaveFuncs.read(f, &size, sizeof(size));
179 if (size > sizeof(addrs)) {
180 bytes = size - sizeof(addrs);
181 SaveFuncs.seek(f, bytes, SEEK_CUR);
182 size = sizeof(addrs);
184 bytes = SaveFuncs.read(f, addrs, size);
188 new_dynarec_load_blocks(addrs, size);
191 //printf("drc: %d block info entries %s\n", size/8, mode ? "saved" : "loaded");
195 void *gte_handlers[64];
197 void *gte_handlers_nf[64] = {
198 NULL , gteRTPS_nf , NULL , NULL , NULL , NULL , gteNCLIP_nf, NULL , // 00
199 NULL , NULL , NULL , NULL , gteOP_nf , NULL , NULL , NULL , // 08
200 gteDPCS_nf, gteINTPL_nf, gteMVMVA_nf, gteNCDS_nf, gteCDP_nf, NULL , gteNCDT_nf , NULL , // 10
201 NULL , NULL , NULL , gteNCCS_nf, gteCC_nf , NULL , gteNCS_nf , NULL , // 18
202 gteNCT_nf , NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 20
203 gteSQR_nf , gteDCPL_nf , gteDPCT_nf , NULL , NULL , gteAVSZ3_nf, gteAVSZ4_nf, NULL , // 28
204 gteRTPT_nf, NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 30
205 NULL , NULL , NULL , NULL , NULL , gteGPF_nf , gteGPL_nf , gteNCCT_nf, // 38
208 const char *gte_regnames[64] = {
209 NULL , "RTPS" , NULL , NULL , NULL , NULL , "NCLIP", NULL , // 00
210 NULL , NULL , NULL , NULL , "OP" , NULL , NULL , NULL , // 08
211 "DPCS", "INTPL", "MVMVA", "NCDS", "CDP", NULL , "NCDT" , NULL , // 10
212 NULL , NULL , NULL , "NCCS", "CC" , NULL , "NCS" , NULL , // 18
213 "NCT" , NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 20
214 "SQR" , "DCPL" , "DPCT" , NULL , NULL , "AVSZ3", "AVSZ4", NULL , // 28
215 "RTPT", NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 30
216 NULL , NULL , NULL , NULL , NULL , "GPF" , "GPL" , "NCCT", // 38
219 /* from gte.txt.. not sure if this is any good. */
220 const char gte_cycletab[64] = {
221 /* 1 2 3 4 5 6 7 8 9 a b c d e f */
222 0, 15, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 6, 0, 0, 0,
223 8, 8, 8, 19, 13, 0, 44, 0, 0, 0, 0, 17, 11, 0, 14, 0,
224 30, 0, 0, 0, 0, 0, 0, 0, 5, 8, 17, 0, 0, 5, 6, 0,
225 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 39,
232 #define GCBITS3(b0,b1,b2) \
233 (GCBIT(b0) | GCBIT(b1) | GCBIT(b2))
234 #define GDBITS2(b0,b1) \
235 (GDBIT(b0) | GDBIT(b1))
236 #define GDBITS3(b0,b1,b2) \
237 (GDBITS2(b0,b1) | GDBIT(b2))
238 #define GDBITS4(b0,b1,b2,b3) \
239 (GDBITS3(b0,b1,b2) | GDBIT(b3))
240 #define GDBITS5(b0,b1,b2,b3,b4) \
241 (GDBITS4(b0,b1,b2,b3) | GDBIT(b4))
242 #define GDBITS6(b0,b1,b2,b3,b4,b5) \
243 (GDBITS5(b0,b1,b2,b3,b4) | GDBIT(b5))
244 #define GDBITS7(b0,b1,b2,b3,b4,b5,b6) \
245 (GDBITS6(b0,b1,b2,b3,b4,b5) | GDBIT(b6))
246 #define GDBITS8(b0,b1,b2,b3,b4,b5,b6,b7) \
247 (GDBITS7(b0,b1,b2,b3,b4,b5,b6) | GDBIT(b7))
248 #define GDBITS9(b0,b1,b2,b3,b4,b5,b6,b7,b8) \
249 (GDBITS8(b0,b1,b2,b3,b4,b5,b6,b7) | GDBIT(b8))
250 #define GDBITS10(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9) \
251 (GDBITS9(b0,b1,b2,b3,b4,b5,b6,b7,b8) | GDBIT(b9))
253 const uint64_t gte_reg_reads[64] = {
254 [GTE_RTPS] = 0x1f0000ff00000000ll | GDBITS7(0,1,13,14,17,18,19),
255 [GTE_NCLIP] = GDBITS3(12,13,14),
256 [GTE_OP] = GCBITS3(0,2,4) | GDBITS3(9,10,11),
257 [GTE_DPCS] = GCBITS3(21,22,23) | GDBITS4(6,8,21,22),
258 [GTE_INTPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22),
259 [GTE_MVMVA] = 0x00ffffff00000000ll | GDBITS9(0,1,2,3,4,5,9,10,11), // XXX: maybe decode further?
260 [GTE_NCDS] = 0x00ffff0000000000ll | GDBITS6(0,1,6,8,21,22),
261 [GTE_CDP] = 0x00ffe00000000000ll | GDBITS7(6,8,9,10,11,21,22),
262 [GTE_NCDT] = 0x00ffff0000000000ll | GDBITS8(0,1,2,3,4,5,6,8),
263 [GTE_NCCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22),
264 [GTE_CC] = 0x001fe00000000000ll | GDBITS6(6,9,10,11,21,22),
265 [GTE_NCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22),
266 [GTE_NCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6),
267 [GTE_SQR] = GDBITS3(9,10,11),
268 [GTE_DCPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22),
269 [GTE_DPCT] = GCBITS3(21,22,23) | GDBITS4(8,20,21,22),
270 [GTE_AVSZ3] = GCBIT(29) | GDBITS3(17,18,19),
271 [GTE_AVSZ4] = GCBIT(30) | GDBITS4(16,17,18,19),
272 [GTE_RTPT] = 0x1f0000ff00000000ll | GDBITS7(0,1,2,3,4,5,19),
273 [GTE_GPF] = GDBITS7(6,8,9,10,11,21,22),
274 [GTE_GPL] = GDBITS10(6,8,9,10,11,21,22,25,26,27),
275 [GTE_NCCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6),
278 // note: this excludes gteFLAG that is always written to
279 const uint64_t gte_reg_writes[64] = {
280 [GTE_RTPS] = 0x0f0f7f00ll,
281 [GTE_NCLIP] = GDBIT(24),
282 [GTE_OP] = GDBITS6(9,10,11,25,26,27),
283 [GTE_DPCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
284 [GTE_INTPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
285 [GTE_MVMVA] = GDBITS6(9,10,11,25,26,27),
286 [GTE_NCDS] = GDBITS9(9,10,11,20,21,22,25,26,27),
287 [GTE_CDP] = GDBITS9(9,10,11,20,21,22,25,26,27),
288 [GTE_NCDT] = GDBITS9(9,10,11,20,21,22,25,26,27),
289 [GTE_NCCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
290 [GTE_CC] = GDBITS9(9,10,11,20,21,22,25,26,27),
291 [GTE_NCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
292 [GTE_NCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
293 [GTE_SQR] = GDBITS6(9,10,11,25,26,27),
294 [GTE_DCPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
295 [GTE_DPCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
296 [GTE_AVSZ3] = GDBITS2(7,24),
297 [GTE_AVSZ4] = GDBITS2(7,24),
298 [GTE_RTPT] = 0x0f0f7f00ll,
299 [GTE_GPF] = GDBITS9(9,10,11,20,21,22,25,26,27),
300 [GTE_GPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
301 [GTE_NCCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
304 static int ari64_init()
306 extern void (*psxCP2[64])();
307 extern void psxNULL();
308 extern unsigned char *out;
312 new_dyna_pcsx_mem_init();
314 for (i = 0; i < ARRAY_SIZE(gte_handlers); i++)
315 if (psxCP2[i] != psxNULL)
316 gte_handlers[i] = psxCP2[i];
318 #if defined(__arm__) && !defined(DRC_DBG)
319 gte_handlers[0x06] = gteNCLIP_arm;
321 gte_handlers_nf[0x01] = gteRTPS_nf_arm;
322 gte_handlers_nf[0x30] = gteRTPT_nf_arm;
325 // compiler's _nf version is still a lot slower than neon
326 // _nf_arm RTPS is roughly the same, RTPT slower
327 gte_handlers[0x01] = gte_handlers_nf[0x01] = gteRTPS_neon;
328 gte_handlers[0x30] = gte_handlers_nf[0x30] = gteRTPT_neon;
332 memcpy(gte_handlers_nf, gte_handlers, sizeof(gte_handlers_nf));
335 zeromem_ptr = zero_mem;
336 scratch_buf_ptr = scratch_buf;
338 SysPrintf("Mapped (RAM/scrp/ROM/LUTs/TC):\n");
339 SysPrintf("%08x/%08x/%08x/%08x/%08x\n",
340 psxM, psxH, psxR, mem_rtab, out);
345 static void ari64_reset()
347 printf("ari64_reset\n");
348 new_dyna_pcsx_mem_reset();
349 invalidate_all_pages();
351 pending_exception = 1;
354 // execute until predefined leave points
355 // (HLE softcall exit and BIOS fastboot end)
356 static void ari64_execute_until()
358 schedule_timeslice();
360 evprintf("ari64_execute %08x, %u->%u (%d)\n", psxRegs.pc,
361 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
365 evprintf("ari64_execute end %08x, %u->%u (%d)\n", psxRegs.pc,
366 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
369 static void ari64_execute()
372 ari64_execute_until();
373 evprintf("drc left @%08x\n", psxRegs.pc);
377 static void ari64_clear(u32 addr, u32 size)
379 u32 start, end, main_ram;
381 size *= 4; /* PCSX uses DMA units (words) */
383 evprintf("ari64_clear %08x %04x\n", addr, size);
385 /* check for RAM mirrors */
386 main_ram = (addr & 0xffe00000) == 0x80000000;
389 end = (addr + size) >> 12;
391 for (; start <= end; start++)
392 if (!main_ram || !invalid_code[start])
393 invalidate_block(start);
396 static void ari64_shutdown()
398 new_dynarec_cleanup();
399 new_dyna_pcsx_mem_shutdown();
402 extern void intExecute();
403 extern void intExecuteT();
404 extern void intExecuteBlock();
405 extern void intExecuteBlockT();
407 #define intExecuteT intExecute
408 #define intExecuteBlockT intExecuteBlock
427 void do_insn_trace() {}
428 void do_insn_cmp() {}
432 unsigned int address;
433 int pending_exception, stop;
435 int new_dynarec_did_compile;
436 int cycle_multiplier;
437 int new_dynarec_hacks;
443 void *scratch_buf_ptr;
444 void new_dynarec_init() { (void)ari64_execute; }
445 void new_dyna_start() {}
446 void new_dynarec_cleanup() {}
447 void new_dynarec_clear_full() {}
448 void invalidate_all_pages() {}
449 void invalidate_block(unsigned int block) {}
450 void new_dyna_pcsx_mem_init(void) {}
451 void new_dyna_pcsx_mem_reset(void) {}
452 void new_dyna_pcsx_mem_load_state(void) {}
453 void new_dyna_pcsx_mem_shutdown(void) {}
454 int new_dynarec_save_blocks(void *save, int size) { return 0; }
455 void new_dynarec_load_blocks(const void *save, int size) {}
462 extern u32 last_io_addr;
464 static void dump_mem(const char *fname, void *mem, size_t size)
466 FILE *f1 = fopen(fname, "wb");
468 f1 = fopen(strrchr(fname, '/') + 1, "wb");
469 fwrite(mem, 1, size, f1);
473 static u32 memcheck_read(u32 a)
475 if ((a >> 16) == 0x1f80)
477 return *(u32 *)(psxH + (a & 0xfffc));
479 if ((a >> 16) == 0x1f00)
481 return *(u32 *)(psxP + (a & 0xfffc));
483 // if ((a & ~0xe0600000) < 0x200000)
485 return *(u32 *)(psxM + (a & 0x1ffffc));
488 void do_insn_trace(void)
490 static psxRegisters oldregs;
491 static u32 old_io_addr = (u32)-1;
492 static u32 old_io_data = 0xbad0c0de;
493 static u32 event_cycles_o[PSXINT_COUNT];
494 u32 *allregs_p = (void *)&psxRegs;
495 u32 *allregs_o = (void *)&oldregs;
500 //last_io_addr = 0x5e2c8;
502 f = fopen("tracelog", "wb");
505 oldregs.code = psxRegs.code; // don't care
506 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
507 if (allregs_p[i] != allregs_o[i]) {
509 fwrite(&allregs_p[i], 1, 4, f);
510 allregs_o[i] = allregs_p[i];
514 for (i = 0; i < PSXINT_COUNT; i++) {
515 if (event_cycles[i] != event_cycles_o[i]) {
517 fwrite(&byte, 1, 1, f);
519 fwrite(&event_cycles[i], 1, 4, f);
520 event_cycles_o[i] = event_cycles[i];
524 if (old_io_addr != last_io_addr) {
526 fwrite(&byte, 1, 1, f);
527 fwrite(&last_io_addr, 1, 4, f);
528 old_io_addr = last_io_addr;
530 io_data = memcheck_read(last_io_addr);
531 if (old_io_data != io_data) {
533 fwrite(&byte, 1, 1, f);
534 fwrite(&io_data, 1, 4, f);
535 old_io_data = io_data;
538 fwrite(&byte, 1, 1, f);
541 if (psxRegs.cycle == 190230) {
542 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
543 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
550 static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
551 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
552 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
553 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
554 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
556 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
557 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
558 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
559 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
561 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
562 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
563 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
564 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
566 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
567 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
568 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
569 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
571 "PC", "code", "cycle", "interrupt",
579 static int miss_log_i;
580 #define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
581 #define miss_log_mask (miss_log_len-1)
583 static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
585 miss_log[miss_log_i].reg = reg;
586 miss_log[miss_log_i].val = val;
587 miss_log[miss_log_i].val_expect = val_expect;
588 miss_log[miss_log_i].pc = pc;
589 miss_log[miss_log_i].cycle = cycle;
590 miss_log_i = (miss_log_i + 1) & miss_log_mask;
595 void do_insn_cmp(void)
597 static psxRegisters rregs;
598 static u32 mem_addr, mem_val;
599 u32 *allregs_p = (void *)&psxRegs;
600 u32 *allregs_e = (void *)&rregs;
601 static u32 ppc, failcount;
602 int i, ret, bad = 0, which_event = -1;
607 f = fopen("tracelog", "rb");
610 if ((ret = fread(&code, 1, 1, f)) <= 0)
619 fread(&which_event, 1, 1, f);
620 fread(&ev_cycles, 1, 4, f);
623 fread(&mem_addr, 1, 4, f);
626 fread(&mem_val, 1, 4, f);
629 fread(&allregs_e[code], 1, 4, f);
637 psxRegs.code = rregs.code; // don't care
638 psxRegs.cycle = rregs.cycle;
639 psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
641 //if (psxRegs.cycle == 166172) breakme();
643 if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
644 mem_val == memcheck_read(mem_addr)
650 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
651 if (allregs_p[i] != allregs_e[i]) {
652 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
657 if (mem_val != memcheck_read(mem_addr)) {
658 printf("bad mem @%08x: %08x %08x\n", mem_addr, memcheck_read(mem_addr), mem_val);
662 if (which_event >= 0 && event_cycles[which_event] != ev_cycles) {
663 printf("bad ev_cycles #%d: %08x %08x\n", which_event, event_cycles[which_event], ev_cycles);
667 if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
668 static int last_mcycle;
669 if (last_mcycle != psxRegs.cycle >> 20) {
670 printf("%u\n", psxRegs.cycle);
671 last_mcycle = psxRegs.cycle >> 20;
678 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
679 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
680 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
681 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
682 printf("-- %d\n", bad);
683 for (i = 0; i < 8; i++)
684 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
685 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+24]);
686 printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
687 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
688 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
691 psxRegs.cycle = rregs.cycle + 2; // sync timing