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 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 #ifdef ICACHE_EMULATION
397 static void ari64_notify(int note, void *data) {
399 Should be fixed when ARM dynarec has proper icache emulation.
402 case R3000ACPU_NOTIFY_CACHE_UNISOLATED:
404 case R3000ACPU_NOTIFY_CACHE_ISOLATED:
406 case R3000ACPU_NOTIFY_DMA3_EXE_LOAD:
414 static void ari64_shutdown()
416 new_dynarec_cleanup();
417 new_dyna_pcsx_mem_shutdown();
420 extern void intExecute();
421 extern void intExecuteT();
422 extern void intExecuteBlock();
423 extern void intExecuteBlockT();
425 #define intExecuteT intExecute
426 #define intExecuteBlockT intExecuteBlock
440 #ifdef ICACHE_EMULATION
448 void do_insn_trace() {}
449 void do_insn_cmp() {}
453 unsigned int address;
454 int pending_exception, stop;
455 unsigned int next_interupt;
456 int new_dynarec_did_compile;
457 int cycle_multiplier;
458 int new_dynarec_hacks;
464 void *scratch_buf_ptr;
465 void new_dynarec_init() { (void)ari64_execute; }
466 void new_dyna_start() {}
467 void new_dynarec_cleanup() {}
468 void new_dynarec_clear_full() {}
469 void invalidate_all_pages() {}
470 void invalidate_block(unsigned int block) {}
471 void new_dyna_pcsx_mem_init(void) {}
472 void new_dyna_pcsx_mem_reset(void) {}
473 void new_dyna_pcsx_mem_load_state(void) {}
474 void new_dyna_pcsx_mem_shutdown(void) {}
475 int new_dynarec_save_blocks(void *save, int size) { return 0; }
476 void new_dynarec_load_blocks(const void *save, int size) {}
483 extern u32 last_io_addr;
485 static void dump_mem(const char *fname, void *mem, size_t size)
487 FILE *f1 = fopen(fname, "wb");
489 f1 = fopen(strrchr(fname, '/') + 1, "wb");
490 fwrite(mem, 1, size, f1);
494 static u32 memcheck_read(u32 a)
496 if ((a >> 16) == 0x1f80)
498 return *(u32 *)(psxH + (a & 0xfffc));
500 if ((a >> 16) == 0x1f00)
502 return *(u32 *)(psxP + (a & 0xfffc));
504 // if ((a & ~0xe0600000) < 0x200000)
506 return *(u32 *)(psxM + (a & 0x1ffffc));
509 void do_insn_trace(void)
511 static psxRegisters oldregs;
512 static u32 old_io_addr = (u32)-1;
513 static u32 old_io_data = 0xbad0c0de;
514 static u32 event_cycles_o[PSXINT_COUNT];
515 u32 *allregs_p = (void *)&psxRegs;
516 u32 *allregs_o = (void *)&oldregs;
521 //last_io_addr = 0x5e2c8;
523 f = fopen("tracelog", "wb");
526 oldregs.code = psxRegs.code; // don't care
527 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
528 if (allregs_p[i] != allregs_o[i]) {
530 fwrite(&allregs_p[i], 1, 4, f);
531 allregs_o[i] = allregs_p[i];
535 for (i = 0; i < PSXINT_COUNT; i++) {
536 if (event_cycles[i] != event_cycles_o[i]) {
538 fwrite(&byte, 1, 1, f);
540 fwrite(&event_cycles[i], 1, 4, f);
541 event_cycles_o[i] = event_cycles[i];
545 if (old_io_addr != last_io_addr) {
547 fwrite(&byte, 1, 1, f);
548 fwrite(&last_io_addr, 1, 4, f);
549 old_io_addr = last_io_addr;
551 io_data = memcheck_read(last_io_addr);
552 if (old_io_data != io_data) {
554 fwrite(&byte, 1, 1, f);
555 fwrite(&io_data, 1, 4, f);
556 old_io_data = io_data;
559 fwrite(&byte, 1, 1, f);
562 if (psxRegs.cycle == 190230) {
563 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
564 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
571 static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
572 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
573 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
574 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
575 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
577 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
578 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
579 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
580 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
582 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
583 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
584 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
585 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
587 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
588 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
589 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
590 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
592 "PC", "code", "cycle", "interrupt",
600 static int miss_log_i;
601 #define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
602 #define miss_log_mask (miss_log_len-1)
604 static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
606 miss_log[miss_log_i].reg = reg;
607 miss_log[miss_log_i].val = val;
608 miss_log[miss_log_i].val_expect = val_expect;
609 miss_log[miss_log_i].pc = pc;
610 miss_log[miss_log_i].cycle = cycle;
611 miss_log_i = (miss_log_i + 1) & miss_log_mask;
616 void do_insn_cmp(void)
618 static psxRegisters rregs;
619 static u32 mem_addr, mem_val;
620 u32 *allregs_p = (void *)&psxRegs;
621 u32 *allregs_e = (void *)&rregs;
622 static u32 ppc, failcount;
623 int i, ret, bad = 0, which_event = -1;
628 f = fopen("tracelog", "rb");
631 if ((ret = fread(&code, 1, 1, f)) <= 0)
640 fread(&which_event, 1, 1, f);
641 fread(&ev_cycles, 1, 4, f);
644 fread(&mem_addr, 1, 4, f);
647 fread(&mem_val, 1, 4, f);
650 fread(&allregs_e[code], 1, 4, f);
658 psxRegs.code = rregs.code; // don't care
659 psxRegs.cycle = rregs.cycle;
660 psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
662 //if (psxRegs.cycle == 166172) breakme();
664 if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
665 mem_val == memcheck_read(mem_addr)
671 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
672 if (allregs_p[i] != allregs_e[i]) {
673 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
678 if (mem_val != memcheck_read(mem_addr)) {
679 printf("bad mem @%08x: %08x %08x\n", mem_addr, memcheck_read(mem_addr), mem_val);
683 if (which_event >= 0 && event_cycles[which_event] != ev_cycles) {
684 printf("bad ev_cycles #%d: %08x %08x\n", which_event, event_cycles[which_event], ev_cycles);
688 if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
689 static int last_mcycle;
690 if (last_mcycle != psxRegs.cycle >> 20) {
691 printf("%u\n", psxRegs.cycle);
692 last_mcycle = psxRegs.cycle >> 20;
699 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
700 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
701 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
702 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
703 printf("-- %d\n", bad);
704 for (i = 0; i < 8; i++)
705 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
706 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+24]);
707 printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
708 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
709 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
712 psxRegs.cycle = rregs.cycle + 2; // sync timing