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_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 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();
151 void *gte_handlers[64];
153 void *gte_handlers_nf[64] = {
154 NULL , gteRTPS_nf , NULL , NULL , NULL , NULL , gteNCLIP_nf, NULL , // 00
155 NULL , NULL , NULL , NULL , gteOP_nf , NULL , NULL , NULL , // 08
156 gteDPCS_nf, gteINTPL_nf, gteMVMVA_nf, gteNCDS_nf, gteCDP_nf, NULL , gteNCDT_nf , NULL , // 10
157 NULL , NULL , NULL , gteNCCS_nf, gteCC_nf , NULL , gteNCS_nf , NULL , // 18
158 gteNCT_nf , NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 20
159 gteSQR_nf , gteDCPL_nf , gteDPCT_nf , NULL , NULL , gteAVSZ3_nf, gteAVSZ4_nf, NULL , // 28
160 gteRTPT_nf, NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 30
161 NULL , NULL , NULL , NULL , NULL , gteGPF_nf , gteGPL_nf , gteNCCT_nf, // 38
164 const char *gte_regnames[64] = {
165 NULL , "RTPS" , NULL , NULL , NULL , NULL , "NCLIP", NULL , // 00
166 NULL , NULL , NULL , NULL , "OP" , NULL , NULL , NULL , // 08
167 "DPCS", "INTPL", "MVMVA", "NCDS", "CDP", NULL , "NCDT" , NULL , // 10
168 NULL , NULL , NULL , "NCCS", "CC" , NULL , "NCS" , NULL , // 18
169 "NCT" , NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 20
170 "SQR" , "DCPL" , "DPCT" , NULL , NULL , "AVSZ3", "AVSZ4", NULL , // 28
171 "RTPT", NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 30
172 NULL , NULL , NULL , NULL , NULL , "GPF" , "GPL" , "NCCT", // 38
175 /* from gte.txt.. not sure if this is any good. */
176 const char gte_cycletab[64] = {
177 /* 1 2 3 4 5 6 7 8 9 a b c d e f */
178 0, 15, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 6, 0, 0, 0,
179 8, 8, 8, 19, 13, 0, 44, 0, 0, 0, 0, 17, 11, 0, 14, 0,
180 30, 0, 0, 0, 0, 0, 0, 0, 5, 8, 17, 0, 0, 5, 6, 0,
181 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 39,
188 #define GCBITS3(b0,b1,b2) \
189 (GCBIT(b0) | GCBIT(b1) | GCBIT(b2))
190 #define GDBITS2(b0,b1) \
191 (GDBIT(b0) | GDBIT(b1))
192 #define GDBITS3(b0,b1,b2) \
193 (GDBITS2(b0,b1) | GDBIT(b2))
194 #define GDBITS4(b0,b1,b2,b3) \
195 (GDBITS3(b0,b1,b2) | GDBIT(b3))
196 #define GDBITS5(b0,b1,b2,b3,b4) \
197 (GDBITS4(b0,b1,b2,b3) | GDBIT(b4))
198 #define GDBITS6(b0,b1,b2,b3,b4,b5) \
199 (GDBITS5(b0,b1,b2,b3,b4) | GDBIT(b5))
200 #define GDBITS7(b0,b1,b2,b3,b4,b5,b6) \
201 (GDBITS6(b0,b1,b2,b3,b4,b5) | GDBIT(b6))
202 #define GDBITS8(b0,b1,b2,b3,b4,b5,b6,b7) \
203 (GDBITS7(b0,b1,b2,b3,b4,b5,b6) | GDBIT(b7))
204 #define GDBITS9(b0,b1,b2,b3,b4,b5,b6,b7,b8) \
205 (GDBITS8(b0,b1,b2,b3,b4,b5,b6,b7) | GDBIT(b8))
206 #define GDBITS10(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9) \
207 (GDBITS9(b0,b1,b2,b3,b4,b5,b6,b7,b8) | GDBIT(b9))
209 const uint64_t gte_reg_reads[64] = {
210 [GTE_RTPS] = 0x1f0000ff00000000ll | GDBITS7(0,1,13,14,17,18,19),
211 [GTE_NCLIP] = GDBITS3(12,13,14),
212 [GTE_OP] = GCBITS3(0,2,4) | GDBITS3(9,10,11),
213 [GTE_DPCS] = GCBITS3(21,22,23) | GDBITS4(6,8,21,22),
214 [GTE_INTPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22),
215 [GTE_MVMVA] = 0x00ffffff00000000ll | GDBITS9(0,1,2,3,4,5,9,10,11), // XXX: maybe decode further?
216 [GTE_NCDS] = 0x00ffff0000000000ll | GDBITS6(0,1,6,8,21,22),
217 [GTE_CDP] = 0x00ffe00000000000ll | GDBITS7(6,8,9,10,11,21,22),
218 [GTE_NCDT] = 0x00ffff0000000000ll | GDBITS8(0,1,2,3,4,5,6,8),
219 [GTE_NCCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22),
220 [GTE_CC] = 0x001fe00000000000ll | GDBITS6(6,9,10,11,21,22),
221 [GTE_NCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22),
222 [GTE_NCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6),
223 [GTE_SQR] = GDBITS3(9,10,11),
224 [GTE_DCPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22),
225 [GTE_DPCT] = GCBITS3(21,22,23) | GDBITS4(8,20,21,22),
226 [GTE_AVSZ3] = GCBIT(29) | GDBITS3(17,18,19),
227 [GTE_AVSZ4] = GCBIT(30) | GDBITS4(16,17,18,19),
228 [GTE_RTPT] = 0x1f0000ff00000000ll | GDBITS7(0,1,2,3,4,5,19),
229 [GTE_GPF] = GDBITS7(6,8,9,10,11,21,22),
230 [GTE_GPL] = GDBITS10(6,8,9,10,11,21,22,25,26,27),
231 [GTE_NCCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6),
234 // note: this excludes gteFLAG that is always written to
235 const uint64_t gte_reg_writes[64] = {
236 [GTE_RTPS] = 0x0f0f7f00ll,
237 [GTE_NCLIP] = GDBIT(24),
238 [GTE_OP] = GDBITS6(9,10,11,25,26,27),
239 [GTE_DPCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
240 [GTE_INTPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
241 [GTE_MVMVA] = GDBITS6(9,10,11,25,26,27),
242 [GTE_NCDS] = GDBITS9(9,10,11,20,21,22,25,26,27),
243 [GTE_CDP] = GDBITS9(9,10,11,20,21,22,25,26,27),
244 [GTE_NCDT] = GDBITS9(9,10,11,20,21,22,25,26,27),
245 [GTE_NCCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
246 [GTE_CC] = GDBITS9(9,10,11,20,21,22,25,26,27),
247 [GTE_NCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
248 [GTE_NCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
249 [GTE_SQR] = GDBITS6(9,10,11,25,26,27),
250 [GTE_DCPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
251 [GTE_DPCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
252 [GTE_AVSZ3] = GDBITS2(7,24),
253 [GTE_AVSZ4] = GDBITS2(7,24),
254 [GTE_RTPT] = 0x0f0f7f00ll,
255 [GTE_GPF] = GDBITS9(9,10,11,20,21,22,25,26,27),
256 [GTE_GPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
257 [GTE_NCCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
260 static int ari64_init()
262 extern void (*psxCP2[64])();
263 extern void psxNULL();
268 new_dyna_pcsx_mem_init();
270 for (i = 0; i < ARRAY_SIZE(gte_handlers); i++)
271 if (psxCP2[i] != psxNULL)
272 gte_handlers[i] = psxCP2[i];
274 #if defined(__arm__) && !defined(DRC_DBG)
275 gte_handlers[0x06] = gteNCLIP_arm;
277 gte_handlers_nf[0x01] = gteRTPS_nf_arm;
278 gte_handlers_nf[0x30] = gteRTPT_nf_arm;
281 // compiler's _nf version is still a lot slower than neon
282 // _nf_arm RTPS is roughly the same, RTPT slower
283 gte_handlers[0x01] = gte_handlers_nf[0x01] = gteRTPS_neon;
284 gte_handlers[0x30] = gte_handlers_nf[0x30] = gteRTPT_neon;
288 memcpy(gte_handlers_nf, gte_handlers, sizeof(gte_handlers_nf));
291 zeromem_ptr = zero_mem;
292 scratch_buf_ptr = scratch_buf;
294 SysPrintf("Mapped (RAM/scrp/ROM/LUTs/TC):\n");
295 SysPrintf("%08x/%08x/%08x/%08x/%08x\n",
296 psxM, psxH, psxR, mem_rtab, out);
301 static void ari64_reset()
303 printf("ari64_reset\n");
304 new_dyna_pcsx_mem_reset();
305 invalidate_all_pages();
307 pending_exception = 1;
310 // execute until predefined leave points
311 // (HLE softcall exit and BIOS fastboot end)
312 static void ari64_execute_until()
314 schedule_timeslice();
316 evprintf("ari64_execute %08x, %u->%u (%d)\n", psxRegs.pc,
317 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
321 evprintf("ari64_execute end %08x, %u->%u (%d)\n", psxRegs.pc,
322 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
325 static void ari64_execute()
328 ari64_execute_until();
329 evprintf("drc left @%08x\n", psxRegs.pc);
333 static void ari64_clear(u32 addr, u32 size)
335 u32 start, end, main_ram;
337 size *= 4; /* PCSX uses DMA units */
339 evprintf("ari64_clear %08x %04x\n", addr, size);
341 /* check for RAM mirrors */
342 main_ram = (addr & 0xffe00000) == 0x80000000;
345 end = (addr + size) >> 12;
347 for (; start <= end; start++)
348 if (!main_ram || !invalid_code[start])
349 invalidate_block(start);
352 static void ari64_shutdown()
354 new_dynarec_cleanup();
355 new_dyna_pcsx_mem_shutdown();
358 extern void intExecute();
359 extern void intExecuteT();
360 extern void intExecuteBlock();
361 extern void intExecuteBlockT();
363 #define intExecuteT intExecute
364 #define intExecuteBlockT intExecuteBlock
383 void do_insn_trace() {}
384 void do_insn_cmp() {}
388 unsigned int address;
389 int pending_exception, stop;
390 unsigned int next_interupt;
391 int new_dynarec_did_compile;
392 int cycle_multiplier;
393 int new_dynarec_hacks;
399 void *scratch_buf_ptr;
400 void new_dynarec_init() { (void)ari64_execute; }
401 void new_dyna_start() {}
402 void new_dynarec_cleanup() {}
403 void new_dynarec_clear_full() {}
404 void invalidate_all_pages() {}
405 void invalidate_block(unsigned int block) {}
406 void new_dyna_pcsx_mem_init(void) {}
407 void new_dyna_pcsx_mem_reset(void) {}
408 void new_dyna_pcsx_mem_load_state(void) {}
409 void new_dyna_pcsx_mem_shutdown(void) {}
416 extern u32 last_io_addr;
418 static void dump_mem(const char *fname, void *mem, size_t size)
420 FILE *f1 = fopen(fname, "wb");
422 f1 = fopen(strrchr(fname, '/') + 1, "wb");
423 fwrite(mem, 1, size, f1);
427 static u32 memcheck_read(u32 a)
429 if ((a >> 16) == 0x1f80)
431 return *(u32 *)(psxH + (a & 0xfffc));
433 if ((a >> 16) == 0x1f00)
435 return *(u32 *)(psxP + (a & 0xfffc));
437 // if ((a & ~0xe0600000) < 0x200000)
439 return *(u32 *)(psxM + (a & 0x1ffffc));
442 void do_insn_trace(void)
444 static psxRegisters oldregs;
445 static u32 old_io_addr = (u32)-1;
446 static u32 old_io_data = 0xbad0c0de;
447 static u32 event_cycles_o[PSXINT_COUNT];
448 u32 *allregs_p = (void *)&psxRegs;
449 u32 *allregs_o = (void *)&oldregs;
454 //last_io_addr = 0x5e2c8;
456 f = fopen("tracelog", "wb");
459 oldregs.code = psxRegs.code; // don't care
460 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
461 if (allregs_p[i] != allregs_o[i]) {
463 fwrite(&allregs_p[i], 1, 4, f);
464 allregs_o[i] = allregs_p[i];
468 for (i = 0; i < PSXINT_COUNT; i++) {
469 if (event_cycles[i] != event_cycles_o[i]) {
471 fwrite(&byte, 1, 1, f);
473 fwrite(&event_cycles[i], 1, 4, f);
474 event_cycles_o[i] = event_cycles[i];
478 if (old_io_addr != last_io_addr) {
480 fwrite(&byte, 1, 1, f);
481 fwrite(&last_io_addr, 1, 4, f);
482 old_io_addr = last_io_addr;
484 io_data = memcheck_read(last_io_addr);
485 if (old_io_data != io_data) {
487 fwrite(&byte, 1, 1, f);
488 fwrite(&io_data, 1, 4, f);
489 old_io_data = io_data;
492 fwrite(&byte, 1, 1, f);
495 if (psxRegs.cycle == 190230) {
496 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
497 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
504 static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
505 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
506 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
507 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
508 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
510 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
511 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
512 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
513 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
515 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
516 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
517 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
518 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
520 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
521 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
522 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
523 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
525 "PC", "code", "cycle", "interrupt",
533 static int miss_log_i;
534 #define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
535 #define miss_log_mask (miss_log_len-1)
537 static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
539 miss_log[miss_log_i].reg = reg;
540 miss_log[miss_log_i].val = val;
541 miss_log[miss_log_i].val_expect = val_expect;
542 miss_log[miss_log_i].pc = pc;
543 miss_log[miss_log_i].cycle = cycle;
544 miss_log_i = (miss_log_i + 1) & miss_log_mask;
549 void do_insn_cmp(void)
551 static psxRegisters rregs;
552 static u32 mem_addr, mem_val;
553 u32 *allregs_p = (void *)&psxRegs;
554 u32 *allregs_e = (void *)&rregs;
555 static u32 ppc, failcount;
556 int i, ret, bad = 0, which_event = -1;
561 f = fopen("tracelog", "rb");
564 if ((ret = fread(&code, 1, 1, f)) <= 0)
573 fread(&which_event, 1, 1, f);
574 fread(&ev_cycles, 1, 4, f);
577 fread(&mem_addr, 1, 4, f);
580 fread(&mem_val, 1, 4, f);
583 fread(&allregs_e[code], 1, 4, f);
591 psxRegs.code = rregs.code; // don't care
592 psxRegs.cycle = rregs.cycle;
593 psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
595 //if (psxRegs.cycle == 166172) breakme();
597 if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
598 mem_val == memcheck_read(mem_addr)
604 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
605 if (allregs_p[i] != allregs_e[i]) {
606 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
611 if (mem_val != memcheck_read(mem_addr)) {
612 printf("bad mem @%08x: %08x %08x\n", mem_addr, memcheck_read(mem_addr), mem_val);
616 if (which_event >= 0 && event_cycles[which_event] != ev_cycles) {
617 printf("bad ev_cycles #%d: %08x %08x\n", which_event, event_cycles[which_event], ev_cycles);
621 if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
622 static int last_mcycle;
623 if (last_mcycle != psxRegs.cycle >> 20) {
624 printf("%u\n", psxRegs.cycle);
625 last_mcycle = psxRegs.cycle >> 20;
632 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
633 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
634 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
635 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
636 printf("-- %d\n", bad);
637 for (i = 0; i < 8; i++)
638 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
639 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+24]);
640 printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
641 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
642 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
645 psxRegs.cycle = rregs.cycle + 2; // sync timing