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 "../psxinterpreter.h"
14 #include "../r3000a.h"
16 #include "../psxdma.h"
18 #include "../gte_arm.h"
19 #include "../gte_neon.h"
23 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
25 //#define evprintf printf
28 char invalid_code[0x100000];
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 if (psxCpu != &psxInt)
189 new_dynarec_load_blocks(addrs, size);
192 //printf("drc: %d block info entries %s\n", size/8, mode ? "saved" : "loaded");
198 void *gte_handlers[64];
200 void *gte_handlers_nf[64] = {
201 NULL , gteRTPS_nf , NULL , NULL , NULL , NULL , gteNCLIP_nf, NULL , // 00
202 NULL , NULL , NULL , NULL , gteOP_nf , NULL , NULL , NULL , // 08
203 gteDPCS_nf, gteINTPL_nf, gteMVMVA_nf, gteNCDS_nf, gteCDP_nf, NULL , gteNCDT_nf , NULL , // 10
204 NULL , NULL , NULL , gteNCCS_nf, gteCC_nf , NULL , gteNCS_nf , NULL , // 18
205 gteNCT_nf , NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 20
206 gteSQR_nf , gteDCPL_nf , gteDPCT_nf , NULL , NULL , gteAVSZ3_nf, gteAVSZ4_nf, NULL , // 28
207 gteRTPT_nf, NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 30
208 NULL , NULL , NULL , NULL , NULL , gteGPF_nf , gteGPL_nf , gteNCCT_nf, // 38
211 const char *gte_regnames[64] = {
212 NULL , "RTPS" , NULL , NULL , NULL , NULL , "NCLIP", NULL , // 00
213 NULL , NULL , NULL , NULL , "OP" , NULL , NULL , NULL , // 08
214 "DPCS", "INTPL", "MVMVA", "NCDS", "CDP", NULL , "NCDT" , NULL , // 10
215 NULL , NULL , NULL , "NCCS", "CC" , NULL , "NCS" , NULL , // 18
216 "NCT" , NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 20
217 "SQR" , "DCPL" , "DPCT" , NULL , NULL , "AVSZ3", "AVSZ4", NULL , // 28
218 "RTPT", NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 30
219 NULL , NULL , NULL , NULL , NULL , "GPF" , "GPL" , "NCCT", // 38
226 #define GCBITS3(b0,b1,b2) \
227 (GCBIT(b0) | GCBIT(b1) | GCBIT(b2))
228 #define GDBITS2(b0,b1) \
229 (GDBIT(b0) | GDBIT(b1))
230 #define GDBITS3(b0,b1,b2) \
231 (GDBITS2(b0,b1) | GDBIT(b2))
232 #define GDBITS4(b0,b1,b2,b3) \
233 (GDBITS3(b0,b1,b2) | GDBIT(b3))
234 #define GDBITS5(b0,b1,b2,b3,b4) \
235 (GDBITS4(b0,b1,b2,b3) | GDBIT(b4))
236 #define GDBITS6(b0,b1,b2,b3,b4,b5) \
237 (GDBITS5(b0,b1,b2,b3,b4) | GDBIT(b5))
238 #define GDBITS7(b0,b1,b2,b3,b4,b5,b6) \
239 (GDBITS6(b0,b1,b2,b3,b4,b5) | GDBIT(b6))
240 #define GDBITS8(b0,b1,b2,b3,b4,b5,b6,b7) \
241 (GDBITS7(b0,b1,b2,b3,b4,b5,b6) | GDBIT(b7))
242 #define GDBITS9(b0,b1,b2,b3,b4,b5,b6,b7,b8) \
243 (GDBITS8(b0,b1,b2,b3,b4,b5,b6,b7) | GDBIT(b8))
244 #define GDBITS10(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9) \
245 (GDBITS9(b0,b1,b2,b3,b4,b5,b6,b7,b8) | GDBIT(b9))
247 const uint64_t gte_reg_reads[64] = {
248 [GTE_RTPS] = 0x1f0000ff00000000ll | GDBITS7(0,1,13,14,17,18,19),
249 [GTE_NCLIP] = GDBITS3(12,13,14),
250 [GTE_OP] = GCBITS3(0,2,4) | GDBITS3(9,10,11),
251 [GTE_DPCS] = GCBITS3(21,22,23) | GDBITS4(6,8,21,22),
252 [GTE_INTPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22),
253 [GTE_MVMVA] = 0x00ffffff00000000ll | GDBITS9(0,1,2,3,4,5,9,10,11), // XXX: maybe decode further?
254 [GTE_NCDS] = 0x00ffff0000000000ll | GDBITS6(0,1,6,8,21,22),
255 [GTE_CDP] = 0x00ffe00000000000ll | GDBITS7(6,8,9,10,11,21,22),
256 [GTE_NCDT] = 0x00ffff0000000000ll | GDBITS8(0,1,2,3,4,5,6,8),
257 [GTE_NCCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22),
258 [GTE_CC] = 0x001fe00000000000ll | GDBITS6(6,9,10,11,21,22),
259 [GTE_NCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22),
260 [GTE_NCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6),
261 [GTE_SQR] = GDBITS3(9,10,11),
262 [GTE_DCPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22),
263 [GTE_DPCT] = GCBITS3(21,22,23) | GDBITS4(8,20,21,22),
264 [GTE_AVSZ3] = GCBIT(29) | GDBITS3(17,18,19),
265 [GTE_AVSZ4] = GCBIT(30) | GDBITS4(16,17,18,19),
266 [GTE_RTPT] = 0x1f0000ff00000000ll | GDBITS7(0,1,2,3,4,5,19),
267 [GTE_GPF] = GDBITS7(6,8,9,10,11,21,22),
268 [GTE_GPL] = GDBITS10(6,8,9,10,11,21,22,25,26,27),
269 [GTE_NCCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6),
272 // note: this excludes gteFLAG that is always written to
273 const uint64_t gte_reg_writes[64] = {
274 [GTE_RTPS] = 0x0f0f7f00ll,
275 [GTE_NCLIP] = GDBIT(24),
276 [GTE_OP] = GDBITS6(9,10,11,25,26,27),
277 [GTE_DPCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
278 [GTE_INTPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
279 [GTE_MVMVA] = GDBITS6(9,10,11,25,26,27),
280 [GTE_NCDS] = GDBITS9(9,10,11,20,21,22,25,26,27),
281 [GTE_CDP] = GDBITS9(9,10,11,20,21,22,25,26,27),
282 [GTE_NCDT] = GDBITS9(9,10,11,20,21,22,25,26,27),
283 [GTE_NCCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
284 [GTE_CC] = GDBITS9(9,10,11,20,21,22,25,26,27),
285 [GTE_NCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
286 [GTE_NCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
287 [GTE_SQR] = GDBITS6(9,10,11,25,26,27),
288 [GTE_DCPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
289 [GTE_DPCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
290 [GTE_AVSZ3] = GDBITS2(7,24),
291 [GTE_AVSZ4] = GDBITS2(7,24),
292 [GTE_RTPT] = 0x0f0f7f00ll,
293 [GTE_GPF] = GDBITS9(9,10,11,20,21,22,25,26,27),
294 [GTE_GPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
295 [GTE_NCCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
298 static int ari64_init()
300 static u32 scratch_buf[8*8*2] __attribute__((aligned(64)));
301 extern void (*psxCP2[64])();
302 extern void psxNULL();
303 extern unsigned char *out;
307 new_dyna_pcsx_mem_init();
309 for (i = 0; i < ARRAY_SIZE(gte_handlers); i++)
310 if (psxCP2[i] != psxNULL)
311 gte_handlers[i] = psxCP2[i];
313 #if defined(__arm__) && !defined(DRC_DBG)
314 gte_handlers[0x06] = gteNCLIP_arm;
316 gte_handlers_nf[0x01] = gteRTPS_nf_arm;
317 gte_handlers_nf[0x30] = gteRTPT_nf_arm;
320 // compiler's _nf version is still a lot slower than neon
321 // _nf_arm RTPS is roughly the same, RTPT slower
322 gte_handlers[0x01] = gte_handlers_nf[0x01] = gteRTPS_neon;
323 gte_handlers[0x30] = gte_handlers_nf[0x30] = gteRTPT_neon;
327 memcpy(gte_handlers_nf, gte_handlers, sizeof(gte_handlers_nf));
330 zeromem_ptr = zero_mem;
331 scratch_buf_ptr = scratch_buf;
333 SysPrintf("Mapped (RAM/scrp/ROM/LUTs/TC):\n");
334 SysPrintf("%p/%p/%p/%p/%p\n",
335 psxM, psxH, psxR, mem_rtab, out);
340 static void ari64_reset()
342 printf("ari64_reset\n");
343 new_dyna_pcsx_mem_reset();
344 invalidate_all_pages();
346 pending_exception = 1;
349 // execute until predefined leave points
350 // (HLE softcall exit and BIOS fastboot end)
351 static void ari64_execute_until()
353 schedule_timeslice();
355 evprintf("ari64_execute %08x, %u->%u (%d)\n", psxRegs.pc,
356 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
358 new_dyna_start(dynarec_local);
360 evprintf("ari64_execute end %08x, %u->%u (%d)\n", psxRegs.pc,
361 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
364 static void ari64_execute()
367 ari64_execute_until();
368 evprintf("drc left @%08x\n", psxRegs.pc);
372 static void ari64_clear(u32 addr, u32 size)
374 u32 start, end, main_ram;
376 size *= 4; /* PCSX uses DMA units (words) */
378 evprintf("ari64_clear %08x %04x\n", addr, size);
380 /* check for RAM mirrors */
381 main_ram = (addr & 0xffe00000) == 0x80000000;
384 end = (addr + size) >> 12;
386 for (; start <= end; start++)
387 if (!main_ram || !invalid_code[start])
388 invalidate_block(start);
391 static void ari64_notify(int note, void *data) {
393 Should be fixed when ARM dynarec has proper icache emulation.
396 case R3000ACPU_NOTIFY_CACHE_UNISOLATED:
398 case R3000ACPU_NOTIFY_CACHE_ISOLATED:
400 case R3000ACPU_NOTIFY_DMA3_EXE_LOAD:
407 static void ari64_apply_config()
411 if (Config.DisableStalls)
412 new_dynarec_hacks |= NDHACK_NO_STALLS;
414 new_dynarec_hacks &= ~NDHACK_NO_STALLS;
416 if (cycle_multiplier != cycle_multiplier_old
417 || new_dynarec_hacks != new_dynarec_hacks_old)
419 new_dynarec_clear_full();
423 static void ari64_shutdown()
425 new_dynarec_cleanup();
426 new_dyna_pcsx_mem_shutdown();
440 #else // if DRC_DISABLE
442 unsigned int address;
443 int pending_exception, stop;
444 unsigned int next_interupt;
445 int new_dynarec_did_compile;
446 int cycle_multiplier;
447 int cycle_multiplier_override;
448 int cycle_multiplier_old;
449 int new_dynarec_hacks_pergame;
450 int new_dynarec_hacks_old;
451 int new_dynarec_hacks;
457 void *scratch_buf_ptr;
458 void new_dynarec_init() {}
459 void new_dyna_start(void *context) {}
460 void new_dynarec_cleanup() {}
461 void new_dynarec_clear_full() {}
462 void invalidate_all_pages() {}
463 void invalidate_block(unsigned int block) {}
464 void new_dyna_pcsx_mem_init(void) {}
465 void new_dyna_pcsx_mem_reset(void) {}
466 void new_dyna_pcsx_mem_load_state(void) {}
467 void new_dyna_pcsx_mem_shutdown(void) {}
468 int new_dynarec_save_blocks(void *save, int size) { return 0; }
469 void new_dynarec_load_blocks(const void *save, int size) {}
480 static void dump_mem(const char *fname, void *mem, size_t size)
482 FILE *f1 = fopen(fname, "wb");
484 f1 = fopen(strrchr(fname, '/') + 1, "wb");
485 fwrite(mem, 1, size, f1);
489 static u32 memcheck_read(u32 a)
491 if ((a >> 16) == 0x1f80)
493 return *(u32 *)(psxH + (a & 0xfffc));
495 if ((a >> 16) == 0x1f00)
497 return *(u32 *)(psxP + (a & 0xfffc));
499 // if ((a & ~0xe0600000) < 0x200000)
501 return *(u32 *)(psxM + (a & 0x1ffffc));
505 void do_insn_trace(void)
507 static psxRegisters oldregs;
508 static u32 event_cycles_o[PSXINT_COUNT];
509 u32 *allregs_p = (void *)&psxRegs;
510 u32 *allregs_o = (void *)&oldregs;
515 //last_io_addr = 0x5e2c8;
517 f = fopen("tracelog", "wb");
520 oldregs.code = psxRegs.code; // don't care
521 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
522 if (allregs_p[i] != allregs_o[i]) {
524 fwrite(&allregs_p[i], 1, 4, f);
525 allregs_o[i] = allregs_p[i];
529 for (i = 0; i < PSXINT_COUNT; i++) {
530 if (event_cycles[i] != event_cycles_o[i]) {
532 fwrite(&byte, 1, 1, f);
534 fwrite(&event_cycles[i], 1, 4, f);
535 event_cycles_o[i] = event_cycles[i];
538 #define SAVE_IF_CHANGED(code_, name_) { \
539 static u32 old_##name_ = 0xbad0c0de; \
540 if (old_##name_ != name_) { \
542 fwrite(&byte, 1, 1, f); \
543 fwrite(&name_, 1, 4, f); \
544 old_##name_ = name_; \
547 SAVE_IF_CHANGED(0xfb, irq_test_cycle);
548 SAVE_IF_CHANGED(0xfc, handler_cycle);
549 SAVE_IF_CHANGED(0xfd, last_io_addr);
550 io_data = memcheck_read(last_io_addr);
551 SAVE_IF_CHANGED(0xfe, io_data);
553 fwrite(&byte, 1, 1, f);
556 if (psxRegs.cycle == 190230) {
557 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
558 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
566 static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
567 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
568 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
569 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
570 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
572 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
573 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
574 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
575 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
577 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
578 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
579 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
580 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
582 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
583 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
584 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
585 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
587 "PC", "code", "cycle", "interrupt",
595 static int miss_log_i;
596 #define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
597 #define miss_log_mask (miss_log_len-1)
599 static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
601 miss_log[miss_log_i].reg = reg;
602 miss_log[miss_log_i].val = val;
603 miss_log[miss_log_i].val_expect = val_expect;
604 miss_log[miss_log_i].pc = pc;
605 miss_log[miss_log_i].cycle = cycle;
606 miss_log_i = (miss_log_i + 1) & miss_log_mask;
611 void do_insn_cmp(void)
613 extern int last_count;
614 static psxRegisters rregs;
615 static u32 mem_addr, mem_val;
616 static u32 irq_test_cycle_intr;
617 static u32 handler_cycle_intr;
618 u32 *allregs_p = (void *)&psxRegs;
619 u32 *allregs_e = (void *)&rregs;
620 static u32 ppc, failcount;
621 int i, ret, bad = 0, fatal = 0, which_event = -1;
626 f = fopen("tracelog", "rb");
629 if ((ret = fread(&code, 1, 1, f)) <= 0)
638 fread(&which_event, 1, 1, f);
639 fread(&ev_cycles, 1, 4, f);
642 fread(&irq_test_cycle_intr, 1, 4, f);
645 fread(&handler_cycle_intr, 1, 4, f);
648 fread(&mem_addr, 1, 4, f);
651 fread(&mem_val, 1, 4, f);
654 assert(code < offsetof(psxRegisters, intCycle) / 4);
655 fread(&allregs_e[code], 1, 4, f);
663 psxRegs.code = rregs.code; // don't care
664 psxRegs.cycle += last_count;
665 //psxRegs.cycle = rregs.cycle;
666 psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
668 //if (psxRegs.cycle == 166172) breakme();
670 if (which_event >= 0 && event_cycles[which_event] != ev_cycles) {
671 printf("bad ev_cycles #%d: %08x %08x\n", which_event, event_cycles[which_event], ev_cycles);
675 if (irq_test_cycle > irq_test_cycle_intr) {
676 printf("bad irq_test_cycle: %u %u\n", irq_test_cycle, irq_test_cycle_intr);
680 if (handler_cycle != handler_cycle_intr) {
681 printf("bad handler_cycle: %u %u\n", handler_cycle, handler_cycle_intr);
685 if (mem_val != memcheck_read(mem_addr)) {
686 printf("bad mem @%08x: %08x %08x\n", mem_addr, memcheck_read(mem_addr), mem_val);
690 if (!fatal && !memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle))) {
695 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
696 if (allregs_p[i] != allregs_e[i]) {
697 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
704 if (!fatal && psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
705 static int last_mcycle;
706 if (last_mcycle != psxRegs.cycle >> 20) {
707 printf("%u\n", psxRegs.cycle);
708 last_mcycle = psxRegs.cycle >> 20;
714 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
715 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
716 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
717 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
718 printf("-- %d\n", bad);
719 for (i = 0; i < 8; i++)
720 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
721 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+24]);
722 printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
723 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
724 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
727 //psxRegs.cycle = rregs.cycle + 2; // sync timing