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 cycle = psxRegs.cycle;
73 for (irq = 0, irq_bits = psxRegs.interrupt; irq_bits != 0; irq++, irq_bits >>= 1) {
76 if ((s32)(cycle - event_cycles[irq]) >= 0) {
77 // note: irq_funcs() also modify psxRegs.interrupt
78 psxRegs.interrupt &= ~(1u << irq);
83 if ((psxHu32(0x1070) & psxHu32(0x1074)) && (Status & 0x401) == 0x401) {
84 psxException(0x400, 0);
85 pending_exception = 1;
91 evprintf(" +ge %08x, %u->%u\n", psxRegs.pc, psxRegs.cycle, next_interupt);
95 //pending_exception = 1;
99 evprintf(" -ge %08x, %u->%u (%d)\n", psxRegs.pc, psxRegs.cycle,
100 next_interupt, next_interupt - psxRegs.cycle);
104 extern void MTC0(int reg, u32 val);
106 void pcsx_mtc0(u32 reg, u32 val)
108 evprintf("MTC0 %d #%x @%08x %u\n", reg, val, psxRegs.pc, psxRegs.cycle);
111 if (Cause & Status & 0x0300) // possible sw irq
112 pending_exception = 1;
115 void pcsx_mtc0_ds(u32 reg, u32 val)
117 evprintf("MTC0 %d #%x @%08x %u\n", reg, val, psxRegs.pc, psxRegs.cycle);
121 void new_dyna_before_save(void)
123 psxRegs.interrupt &= ~(1 << PSXINT_RCNT); // old savestate compat
125 // psxRegs.intCycle is always maintained, no need to convert
128 void new_dyna_after_save(void)
130 psxRegs.interrupt |= 1 << PSXINT_RCNT;
133 static void new_dyna_restore(void)
136 for (i = 0; i < PSXINT_COUNT; i++)
137 event_cycles[i] = psxRegs.intCycle[i].sCycle + psxRegs.intCycle[i].cycle;
139 event_cycles[PSXINT_RCNT] = psxNextsCounter + psxNextCounter;
140 psxRegs.interrupt |= 1 << PSXINT_RCNT;
141 psxRegs.interrupt &= (1 << PSXINT_COUNT) - 1;
143 new_dyna_pcsx_mem_load_state();
146 void new_dyna_freeze(void *f, int mode)
148 const char header_save[8] = "ariblks";
149 uint32_t addrs[1024 * 4];
154 if (mode != 0) { // save
155 size = new_dynarec_save_blocks(addrs, sizeof(addrs));
159 SaveFuncs.write(f, header_save, sizeof(header_save));
160 SaveFuncs.write(f, &size, sizeof(size));
161 SaveFuncs.write(f, addrs, size);
166 bytes = SaveFuncs.read(f, header, sizeof(header));
167 if (bytes != sizeof(header) || strcmp(header, header_save)) {
169 SaveFuncs.seek(f, -bytes, SEEK_CUR);
172 SaveFuncs.read(f, &size, sizeof(size));
175 if (size > sizeof(addrs)) {
176 bytes = size - sizeof(addrs);
177 SaveFuncs.seek(f, bytes, SEEK_CUR);
178 size = sizeof(addrs);
180 bytes = SaveFuncs.read(f, addrs, size);
184 if (psxCpu != &psxInt)
185 new_dynarec_load_blocks(addrs, size);
188 //printf("drc: %d block info entries %s\n", size/8, mode ? "saved" : "loaded");
191 #if !defined(DRC_DISABLE) && !defined(LIGHTREC)
194 void *gte_handlers[64];
196 void *gte_handlers_nf[64] = {
197 NULL , gteRTPS_nf , NULL , NULL , NULL , NULL , gteNCLIP_nf, NULL , // 00
198 NULL , NULL , NULL , NULL , gteOP_nf , NULL , NULL , NULL , // 08
199 gteDPCS_nf, gteINTPL_nf, gteMVMVA_nf, gteNCDS_nf, gteCDP_nf, NULL , gteNCDT_nf , NULL , // 10
200 NULL , NULL , NULL , gteNCCS_nf, gteCC_nf , NULL , gteNCS_nf , NULL , // 18
201 gteNCT_nf , NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 20
202 gteSQR_nf , gteDCPL_nf , gteDPCT_nf , NULL , NULL , gteAVSZ3_nf, gteAVSZ4_nf, NULL , // 28
203 gteRTPT_nf, NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 30
204 NULL , NULL , NULL , NULL , NULL , gteGPF_nf , gteGPL_nf , gteNCCT_nf, // 38
207 const char *gte_regnames[64] = {
208 NULL , "RTPS" , NULL , NULL , NULL , NULL , "NCLIP", NULL , // 00
209 NULL , NULL , NULL , NULL , "OP" , NULL , NULL , NULL , // 08
210 "DPCS", "INTPL", "MVMVA", "NCDS", "CDP", NULL , "NCDT" , NULL , // 10
211 NULL , NULL , NULL , "NCCS", "CC" , NULL , "NCS" , NULL , // 18
212 "NCT" , NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 20
213 "SQR" , "DCPL" , "DPCT" , NULL , NULL , "AVSZ3", "AVSZ4", NULL , // 28
214 "RTPT", NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 30
215 NULL , NULL , NULL , NULL , NULL , "GPF" , "GPL" , "NCCT", // 38
222 #define GCBITS3(b0,b1,b2) \
223 (GCBIT(b0) | GCBIT(b1) | GCBIT(b2))
224 #define GDBITS2(b0,b1) \
225 (GDBIT(b0) | GDBIT(b1))
226 #define GDBITS3(b0,b1,b2) \
227 (GDBITS2(b0,b1) | GDBIT(b2))
228 #define GDBITS4(b0,b1,b2,b3) \
229 (GDBITS3(b0,b1,b2) | GDBIT(b3))
230 #define GDBITS5(b0,b1,b2,b3,b4) \
231 (GDBITS4(b0,b1,b2,b3) | GDBIT(b4))
232 #define GDBITS6(b0,b1,b2,b3,b4,b5) \
233 (GDBITS5(b0,b1,b2,b3,b4) | GDBIT(b5))
234 #define GDBITS7(b0,b1,b2,b3,b4,b5,b6) \
235 (GDBITS6(b0,b1,b2,b3,b4,b5) | GDBIT(b6))
236 #define GDBITS8(b0,b1,b2,b3,b4,b5,b6,b7) \
237 (GDBITS7(b0,b1,b2,b3,b4,b5,b6) | GDBIT(b7))
238 #define GDBITS9(b0,b1,b2,b3,b4,b5,b6,b7,b8) \
239 (GDBITS8(b0,b1,b2,b3,b4,b5,b6,b7) | GDBIT(b8))
240 #define GDBITS10(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9) \
241 (GDBITS9(b0,b1,b2,b3,b4,b5,b6,b7,b8) | GDBIT(b9))
243 const uint64_t gte_reg_reads[64] = {
244 [GTE_RTPS] = 0x1f0000ff00000000ll | GDBITS7(0,1,13,14,17,18,19),
245 [GTE_NCLIP] = GDBITS3(12,13,14),
246 [GTE_OP] = GCBITS3(0,2,4) | GDBITS3(9,10,11),
247 [GTE_DPCS] = GCBITS3(21,22,23) | GDBITS4(6,8,21,22),
248 [GTE_INTPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22),
249 [GTE_MVMVA] = 0x00ffffff00000000ll | GDBITS9(0,1,2,3,4,5,9,10,11), // XXX: maybe decode further?
250 [GTE_NCDS] = 0x00ffff0000000000ll | GDBITS6(0,1,6,8,21,22),
251 [GTE_CDP] = 0x00ffe00000000000ll | GDBITS7(6,8,9,10,11,21,22),
252 [GTE_NCDT] = 0x00ffff0000000000ll | GDBITS8(0,1,2,3,4,5,6,8),
253 [GTE_NCCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22),
254 [GTE_CC] = 0x001fe00000000000ll | GDBITS6(6,9,10,11,21,22),
255 [GTE_NCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22),
256 [GTE_NCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6),
257 [GTE_SQR] = GDBITS3(9,10,11),
258 [GTE_DCPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22),
259 [GTE_DPCT] = GCBITS3(21,22,23) | GDBITS4(8,20,21,22),
260 [GTE_AVSZ3] = GCBIT(29) | GDBITS3(17,18,19),
261 [GTE_AVSZ4] = GCBIT(30) | GDBITS4(16,17,18,19),
262 [GTE_RTPT] = 0x1f0000ff00000000ll | GDBITS7(0,1,2,3,4,5,19),
263 [GTE_GPF] = GDBITS7(6,8,9,10,11,21,22),
264 [GTE_GPL] = GDBITS10(6,8,9,10,11,21,22,25,26,27),
265 [GTE_NCCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6),
268 // note: this excludes gteFLAG that is always written to
269 const uint64_t gte_reg_writes[64] = {
270 [GTE_RTPS] = 0x0f0f7f00ll,
271 [GTE_NCLIP] = GDBIT(24),
272 [GTE_OP] = GDBITS6(9,10,11,25,26,27),
273 [GTE_DPCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
274 [GTE_INTPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
275 [GTE_MVMVA] = GDBITS6(9,10,11,25,26,27),
276 [GTE_NCDS] = GDBITS9(9,10,11,20,21,22,25,26,27),
277 [GTE_CDP] = GDBITS9(9,10,11,20,21,22,25,26,27),
278 [GTE_NCDT] = GDBITS9(9,10,11,20,21,22,25,26,27),
279 [GTE_NCCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
280 [GTE_CC] = GDBITS9(9,10,11,20,21,22,25,26,27),
281 [GTE_NCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
282 [GTE_NCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
283 [GTE_SQR] = GDBITS6(9,10,11,25,26,27),
284 [GTE_DCPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
285 [GTE_DPCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
286 [GTE_AVSZ3] = GDBITS2(7,24),
287 [GTE_AVSZ4] = GDBITS2(7,24),
288 [GTE_RTPT] = 0x0f0f7f00ll,
289 [GTE_GPF] = GDBITS9(9,10,11,20,21,22,25,26,27),
290 [GTE_GPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
291 [GTE_NCCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
294 static int ari64_init()
296 static u32 scratch_buf[8*8*2] __attribute__((aligned(64)));
297 extern void (*psxCP2[64])();
298 extern void psxNULL();
299 extern unsigned char *out;
303 new_dyna_pcsx_mem_init();
305 for (i = 0; i < ARRAY_SIZE(gte_handlers); i++)
306 if (psxCP2[i] != psxNULL)
307 gte_handlers[i] = psxCP2[i];
309 #if defined(__arm__) && !defined(DRC_DBG)
310 gte_handlers[0x06] = gteNCLIP_arm;
312 gte_handlers_nf[0x01] = gteRTPS_nf_arm;
313 gte_handlers_nf[0x30] = gteRTPT_nf_arm;
316 // compiler's _nf version is still a lot slower than neon
317 // _nf_arm RTPS is roughly the same, RTPT slower
318 gte_handlers[0x01] = gte_handlers_nf[0x01] = gteRTPS_neon;
319 gte_handlers[0x30] = gte_handlers_nf[0x30] = gteRTPT_neon;
323 memcpy(gte_handlers_nf, gte_handlers, sizeof(gte_handlers_nf));
326 zeromem_ptr = zero_mem;
327 scratch_buf_ptr = scratch_buf;
329 SysPrintf("Mapped (RAM/scrp/ROM/LUTs/TC):\n");
330 SysPrintf("%p/%p/%p/%p/%p\n",
331 psxM, psxH, psxR, mem_rtab, out);
336 static void ari64_reset()
338 printf("ari64_reset\n");
339 new_dyna_pcsx_mem_reset();
340 invalidate_all_pages();
342 pending_exception = 1;
345 // execute until predefined leave points
346 // (HLE softcall exit and BIOS fastboot end)
347 static void ari64_execute_until()
349 schedule_timeslice();
351 evprintf("ari64_execute %08x, %u->%u (%d)\n", psxRegs.pc,
352 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
354 new_dyna_start(dynarec_local);
356 evprintf("ari64_execute end %08x, %u->%u (%d)\n", psxRegs.pc,
357 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
360 static void ari64_execute()
363 ari64_execute_until();
364 evprintf("drc left @%08x\n", psxRegs.pc);
368 static void ari64_clear(u32 addr, u32 size)
370 u32 start, end, main_ram;
372 size *= 4; /* PCSX uses DMA units (words) */
374 evprintf("ari64_clear %08x %04x\n", addr, size);
376 /* check for RAM mirrors */
377 main_ram = (addr & 0xffe00000) == 0x80000000;
380 end = (addr + size) >> 12;
382 for (; start <= end; start++)
383 if (!main_ram || !invalid_code[start])
384 invalidate_block(start);
387 static void ari64_notify(int note, void *data) {
389 Should be fixed when ARM dynarec has proper icache emulation.
392 case R3000ACPU_NOTIFY_CACHE_UNISOLATED:
394 case R3000ACPU_NOTIFY_CACHE_ISOLATED:
396 case R3000ACPU_NOTIFY_DMA3_EXE_LOAD:
403 static void ari64_apply_config()
407 if (Config.DisableStalls)
408 new_dynarec_hacks |= NDHACK_NO_STALLS;
410 new_dynarec_hacks &= ~NDHACK_NO_STALLS;
412 if (cycle_multiplier != cycle_multiplier_old
413 || new_dynarec_hacks != new_dynarec_hacks_old)
415 new_dynarec_clear_full();
419 static void ari64_shutdown()
421 new_dynarec_cleanup();
422 new_dyna_pcsx_mem_shutdown();
436 #else // if DRC_DISABLE
438 unsigned int address;
439 int pending_exception, stop;
440 unsigned int next_interupt;
441 int new_dynarec_did_compile;
442 int cycle_multiplier;
443 int cycle_multiplier_override;
444 int cycle_multiplier_old;
445 int new_dynarec_hacks_pergame;
446 int new_dynarec_hacks_old;
447 int new_dynarec_hacks;
453 void *scratch_buf_ptr;
454 void new_dynarec_init() {}
455 void new_dyna_start(void *context) {}
456 void new_dynarec_cleanup() {}
457 void new_dynarec_clear_full() {}
458 void invalidate_all_pages() {}
459 void invalidate_block(unsigned int block) {}
460 void new_dyna_pcsx_mem_init(void) {}
461 void new_dyna_pcsx_mem_reset(void) {}
462 void new_dyna_pcsx_mem_load_state(void) {}
463 void new_dyna_pcsx_mem_shutdown(void) {}
464 int new_dynarec_save_blocks(void *save, int size) { return 0; }
465 void new_dynarec_load_blocks(const void *save, int size) {}
476 void dump_mem(const char *fname, void *mem, size_t size)
478 FILE *f1 = fopen(fname, "wb");
480 f1 = fopen(strrchr(fname, '/') + 1, "wb");
481 fwrite(mem, 1, size, f1);
485 static u32 memcheck_read(u32 a)
487 if ((a >> 16) == 0x1f80)
489 return *(u32 *)(psxH + (a & 0xfffc));
491 if ((a >> 16) == 0x1f00)
493 return *(u32 *)(psxP + (a & 0xfffc));
495 // if ((a & ~0xe0600000) < 0x200000)
497 return *(u32 *)(psxM + (a & 0x1ffffc));
501 void do_insn_trace(void)
503 static psxRegisters oldregs;
504 static u32 event_cycles_o[PSXINT_COUNT];
505 u32 *allregs_p = (void *)&psxRegs;
506 u32 *allregs_o = (void *)&oldregs;
511 //last_io_addr = 0x5e2c8;
513 f = fopen("tracelog", "wb");
516 oldregs.code = psxRegs.code; // don't care
517 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
518 if (allregs_p[i] != allregs_o[i]) {
520 fwrite(&allregs_p[i], 1, 4, f);
521 allregs_o[i] = allregs_p[i];
525 for (i = 0; i < PSXINT_COUNT; i++) {
526 if (event_cycles[i] != event_cycles_o[i]) {
528 fwrite(&byte, 1, 1, f);
530 fwrite(&event_cycles[i], 1, 4, f);
531 event_cycles_o[i] = event_cycles[i];
534 #define SAVE_IF_CHANGED(code_, name_) { \
535 static u32 old_##name_ = 0xbad0c0de; \
536 if (old_##name_ != name_) { \
538 fwrite(&byte, 1, 1, f); \
539 fwrite(&name_, 1, 4, f); \
540 old_##name_ = name_; \
543 SAVE_IF_CHANGED(0xfb, irq_test_cycle);
544 SAVE_IF_CHANGED(0xfc, handler_cycle);
545 SAVE_IF_CHANGED(0xfd, last_io_addr);
546 io_data = memcheck_read(last_io_addr);
547 SAVE_IF_CHANGED(0xfe, io_data);
549 fwrite(&byte, 1, 1, f);
552 if (psxRegs.cycle == 190230) {
553 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
554 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
562 static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
563 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
564 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
565 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
566 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
568 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
569 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
570 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
571 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
573 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
574 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
575 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
576 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
578 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
579 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
580 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
581 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
583 "PC", "code", "cycle", "interrupt",
591 static int miss_log_i;
592 #define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
593 #define miss_log_mask (miss_log_len-1)
595 static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
597 miss_log[miss_log_i].reg = reg;
598 miss_log[miss_log_i].val = val;
599 miss_log[miss_log_i].val_expect = val_expect;
600 miss_log[miss_log_i].pc = pc;
601 miss_log[miss_log_i].cycle = cycle;
602 miss_log_i = (miss_log_i + 1) & miss_log_mask;
607 void do_insn_cmp(void)
609 extern int last_count;
610 static psxRegisters rregs;
611 static u32 mem_addr, mem_val;
612 static u32 irq_test_cycle_intr;
613 static u32 handler_cycle_intr;
614 u32 *allregs_p = (void *)&psxRegs;
615 u32 *allregs_e = (void *)&rregs;
616 static u32 ppc, failcount;
617 int i, ret, bad = 0, fatal = 0, which_event = -1;
622 f = fopen("tracelog", "rb");
625 if ((ret = fread(&code, 1, 1, f)) <= 0)
634 fread(&which_event, 1, 1, f);
635 fread(&ev_cycles, 1, 4, f);
638 fread(&irq_test_cycle_intr, 1, 4, f);
641 fread(&handler_cycle_intr, 1, 4, f);
644 fread(&mem_addr, 1, 4, f);
647 fread(&mem_val, 1, 4, f);
650 assert(code < offsetof(psxRegisters, intCycle) / 4);
651 fread(&allregs_e[code], 1, 4, f);
659 psxRegs.code = rregs.code; // don't care
660 psxRegs.cycle += last_count;
661 //psxRegs.cycle = rregs.cycle; // needs reload in _cmp
662 psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
664 //if (psxRegs.cycle == 166172) breakme();
666 if (which_event >= 0 && event_cycles[which_event] != ev_cycles) {
667 printf("bad ev_cycles #%d: %08x %08x\n", which_event, event_cycles[which_event], ev_cycles);
671 if (irq_test_cycle > irq_test_cycle_intr) {
672 printf("bad irq_test_cycle: %u %u\n", irq_test_cycle, irq_test_cycle_intr);
676 if (handler_cycle != handler_cycle_intr) {
677 printf("bad handler_cycle: %u %u\n", handler_cycle, handler_cycle_intr);
681 if (mem_val != memcheck_read(mem_addr)) {
682 printf("bad mem @%08x: %08x %08x\n", mem_addr, memcheck_read(mem_addr), mem_val);
686 if (!fatal && !memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle))) {
691 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
692 if (allregs_p[i] != allregs_e[i]) {
693 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
700 if (!fatal && psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
701 static int last_mcycle;
702 if (last_mcycle != psxRegs.cycle >> 20) {
703 printf("%u\n", psxRegs.cycle);
704 last_mcycle = psxRegs.cycle >> 20;
710 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
711 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
712 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
713 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
714 printf("-- %d\n", bad);
715 for (i = 0; i < 8; i++)
716 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
717 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+24]);
718 printf("PC: %08x/%08x, cycle %u, next %u\n", psxRegs.pc, ppc, psxRegs.cycle, next_interupt);
719 //dump_mem("/tmp/psxram.dump", psxM, 0x200000);
720 //dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
723 //psxRegs.cycle = rregs.cycle + 2; // sync timing