drc: update according to interpreter (2)
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / emu_if.c
... / ...
CommitLineData
1/*
2 * (C) GraÅžvydas "notaz" Ignotas, 2010-2011
3 *
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.
6 */
7
8#include <stdio.h>
9
10#include "emu_if.h"
11#include "pcsxmem.h"
12#include "events.h"
13#include "../psxhle.h"
14#include "../psxinterpreter.h"
15#include "../r3000a.h"
16#include "../gte_arm.h"
17#include "../gte_neon.h"
18#define FLAGLESS
19#include "../gte.h"
20
21#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
22
23//#define evprintf printf
24#define evprintf(...)
25
26void pcsx_mtc0(u32 reg, u32 val)
27{
28 evprintf("MTC0 %d #%x @%08x %u\n", reg, val, psxRegs.pc, psxRegs.cycle);
29 MTC0(&psxRegs, reg, val);
30 gen_interupt(&psxRegs.CP0);
31 if (psxRegs.CP0.n.Cause & psxRegs.CP0.n.SR & 0x0300) // possible sw irq
32 pending_exception = 1;
33}
34
35void pcsx_mtc0_ds(u32 reg, u32 val)
36{
37 evprintf("MTC0 %d #%x @%08x %u\n", reg, val, psxRegs.pc, psxRegs.cycle);
38 MTC0(&psxRegs, reg, val);
39}
40
41static void new_dyna_restore(void)
42{
43 int i;
44 for (i = 0; i < PSXINT_COUNT; i++)
45 event_cycles[i] = psxRegs.intCycle[i].sCycle + psxRegs.intCycle[i].cycle;
46
47 event_cycles[PSXINT_RCNT] = psxNextsCounter + psxNextCounter;
48 psxRegs.interrupt |= 1 << PSXINT_RCNT;
49 psxRegs.interrupt &= (1 << PSXINT_COUNT) - 1;
50
51 new_dyna_pcsx_mem_load_state();
52}
53
54void new_dyna_freeze(void *f, int mode)
55{
56 const char header_save[8] = "ariblks";
57 uint32_t addrs[1024 * 4];
58 int32_t size = 0;
59 int bytes;
60 char header[8];
61
62 if (mode != 0) { // save
63 size = new_dynarec_save_blocks(addrs, sizeof(addrs));
64 if (size == 0)
65 return;
66
67 SaveFuncs.write(f, header_save, sizeof(header_save));
68 SaveFuncs.write(f, &size, sizeof(size));
69 SaveFuncs.write(f, addrs, size);
70 }
71 else {
72 new_dyna_restore();
73
74 bytes = SaveFuncs.read(f, header, sizeof(header));
75 if (bytes != sizeof(header) || strcmp(header, header_save)) {
76 if (bytes > 0)
77 SaveFuncs.seek(f, -bytes, SEEK_CUR);
78 return;
79 }
80 SaveFuncs.read(f, &size, sizeof(size));
81 if (size <= 0)
82 return;
83 if (size > sizeof(addrs)) {
84 bytes = size - sizeof(addrs);
85 SaveFuncs.seek(f, bytes, SEEK_CUR);
86 size = sizeof(addrs);
87 }
88 bytes = SaveFuncs.read(f, addrs, size);
89 if (bytes != size)
90 return;
91
92 if (psxCpu != &psxInt)
93 new_dynarec_load_blocks(addrs, size);
94 }
95
96 //printf("drc: %d block info entries %s\n", size/8, mode ? "saved" : "loaded");
97}
98
99#if !defined(DRC_DISABLE) && !defined(LIGHTREC)
100
101/* GTE stuff */
102void *gte_handlers[64];
103
104void *gte_handlers_nf[64] = {
105 NULL , gteRTPS_nf , NULL , NULL , NULL , NULL , gteNCLIP_nf, NULL , // 00
106 NULL , NULL , NULL , NULL , gteOP_nf , NULL , NULL , NULL , // 08
107 gteDPCS_nf, gteINTPL_nf, gteMVMVA_nf, gteNCDS_nf, gteCDP_nf, NULL , gteNCDT_nf , NULL , // 10
108 NULL , NULL , NULL , gteNCCS_nf, gteCC_nf , NULL , gteNCS_nf , NULL , // 18
109 gteNCT_nf , NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 20
110 gteSQR_nf , gteDCPL_nf , gteDPCT_nf , NULL , NULL , gteAVSZ3_nf, gteAVSZ4_nf, NULL , // 28
111 gteRTPT_nf, NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 30
112 NULL , NULL , NULL , NULL , NULL , gteGPF_nf , gteGPL_nf , gteNCCT_nf, // 38
113};
114
115const char *gte_regnames[64] = {
116 NULL , "RTPS" , NULL , NULL , NULL , NULL , "NCLIP", NULL , // 00
117 NULL , NULL , NULL , NULL , "OP" , NULL , NULL , NULL , // 08
118 "DPCS", "INTPL", "MVMVA", "NCDS", "CDP", NULL , "NCDT" , NULL , // 10
119 NULL , NULL , NULL , "NCCS", "CC" , NULL , "NCS" , NULL , // 18
120 "NCT" , NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 20
121 "SQR" , "DCPL" , "DPCT" , NULL , NULL , "AVSZ3", "AVSZ4", NULL , // 28
122 "RTPT", NULL , NULL , NULL , NULL , NULL , NULL , NULL , // 30
123 NULL , NULL , NULL , NULL , NULL , "GPF" , "GPL" , "NCCT", // 38
124};
125
126#define GCBIT(x) \
127 (1ll << (32+x))
128#define GDBIT(x) \
129 (1ll << (x))
130#define GCBITS3(b0,b1,b2) \
131 (GCBIT(b0) | GCBIT(b1) | GCBIT(b2))
132#define GDBITS2(b0,b1) \
133 (GDBIT(b0) | GDBIT(b1))
134#define GDBITS3(b0,b1,b2) \
135 (GDBITS2(b0,b1) | GDBIT(b2))
136#define GDBITS4(b0,b1,b2,b3) \
137 (GDBITS3(b0,b1,b2) | GDBIT(b3))
138#define GDBITS5(b0,b1,b2,b3,b4) \
139 (GDBITS4(b0,b1,b2,b3) | GDBIT(b4))
140#define GDBITS6(b0,b1,b2,b3,b4,b5) \
141 (GDBITS5(b0,b1,b2,b3,b4) | GDBIT(b5))
142#define GDBITS7(b0,b1,b2,b3,b4,b5,b6) \
143 (GDBITS6(b0,b1,b2,b3,b4,b5) | GDBIT(b6))
144#define GDBITS8(b0,b1,b2,b3,b4,b5,b6,b7) \
145 (GDBITS7(b0,b1,b2,b3,b4,b5,b6) | GDBIT(b7))
146#define GDBITS9(b0,b1,b2,b3,b4,b5,b6,b7,b8) \
147 (GDBITS8(b0,b1,b2,b3,b4,b5,b6,b7) | GDBIT(b8))
148#define GDBITS10(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9) \
149 (GDBITS9(b0,b1,b2,b3,b4,b5,b6,b7,b8) | GDBIT(b9))
150
151const uint64_t gte_reg_reads[64] = {
152 [GTE_RTPS] = 0x1f0000ff00000000ll | GDBITS7(0,1,13,14,17,18,19),
153 [GTE_NCLIP] = GDBITS3(12,13,14),
154 [GTE_OP] = GCBITS3(0,2,4) | GDBITS3(9,10,11),
155 [GTE_DPCS] = GCBITS3(21,22,23) | GDBITS4(6,8,21,22),
156 [GTE_INTPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22),
157 [GTE_MVMVA] = 0x00ffffff00000000ll | GDBITS9(0,1,2,3,4,5,9,10,11), // XXX: maybe decode further?
158 [GTE_NCDS] = 0x00ffff0000000000ll | GDBITS6(0,1,6,8,21,22),
159 [GTE_CDP] = 0x00ffe00000000000ll | GDBITS7(6,8,9,10,11,21,22),
160 [GTE_NCDT] = 0x00ffff0000000000ll | GDBITS8(0,1,2,3,4,5,6,8),
161 [GTE_NCCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22),
162 [GTE_CC] = 0x001fe00000000000ll | GDBITS6(6,9,10,11,21,22),
163 [GTE_NCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22),
164 [GTE_NCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6),
165 [GTE_SQR] = GDBITS3(9,10,11),
166 [GTE_DCPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22),
167 [GTE_DPCT] = GCBITS3(21,22,23) | GDBITS4(8,20,21,22),
168 [GTE_AVSZ3] = GCBIT(29) | GDBITS3(17,18,19),
169 [GTE_AVSZ4] = GCBIT(30) | GDBITS4(16,17,18,19),
170 [GTE_RTPT] = 0x1f0000ff00000000ll | GDBITS7(0,1,2,3,4,5,19),
171 [GTE_GPF] = GDBITS7(6,8,9,10,11,21,22),
172 [GTE_GPL] = GDBITS10(6,8,9,10,11,21,22,25,26,27),
173 [GTE_NCCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6),
174};
175
176// note: this excludes gteFLAG that is always written to
177const uint64_t gte_reg_writes[64] = {
178 [GTE_RTPS] = 0x0f0f7f00ll,
179 [GTE_NCLIP] = GDBIT(24),
180 [GTE_OP] = GDBITS6(9,10,11,25,26,27),
181 [GTE_DPCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
182 [GTE_INTPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
183 [GTE_MVMVA] = GDBITS6(9,10,11,25,26,27),
184 [GTE_NCDS] = GDBITS9(9,10,11,20,21,22,25,26,27),
185 [GTE_CDP] = GDBITS9(9,10,11,20,21,22,25,26,27),
186 [GTE_NCDT] = GDBITS9(9,10,11,20,21,22,25,26,27),
187 [GTE_NCCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
188 [GTE_CC] = GDBITS9(9,10,11,20,21,22,25,26,27),
189 [GTE_NCS] = GDBITS9(9,10,11,20,21,22,25,26,27),
190 [GTE_NCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
191 [GTE_SQR] = GDBITS6(9,10,11,25,26,27),
192 [GTE_DCPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
193 [GTE_DPCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
194 [GTE_AVSZ3] = GDBITS2(7,24),
195 [GTE_AVSZ4] = GDBITS2(7,24),
196 [GTE_RTPT] = 0x0f0f7f00ll,
197 [GTE_GPF] = GDBITS9(9,10,11,20,21,22,25,26,27),
198 [GTE_GPL] = GDBITS9(9,10,11,20,21,22,25,26,27),
199 [GTE_NCCT] = GDBITS9(9,10,11,20,21,22,25,26,27),
200};
201
202static int ari64_init()
203{
204 static u32 scratch_buf[8*8*2] __attribute__((aligned(64)));
205 size_t i;
206
207 new_dynarec_init();
208 new_dyna_pcsx_mem_init();
209
210 for (i = 0; i < ARRAY_SIZE(gte_handlers); i++)
211 if (psxCP2[i] != gteNULL)
212 gte_handlers[i] = psxCP2[i];
213
214#if defined(__arm__) && !defined(DRC_DBG)
215 gte_handlers[0x06] = gteNCLIP_arm;
216#ifdef HAVE_ARMV5
217 gte_handlers_nf[0x01] = gteRTPS_nf_arm;
218 gte_handlers_nf[0x30] = gteRTPT_nf_arm;
219#endif
220#ifdef __ARM_NEON__
221 // compiler's _nf version is still a lot slower than neon
222 // _nf_arm RTPS is roughly the same, RTPT slower
223 gte_handlers[0x01] = gte_handlers_nf[0x01] = gteRTPS_neon;
224 gte_handlers[0x30] = gte_handlers_nf[0x30] = gteRTPT_neon;
225#endif
226#endif
227#ifdef DRC_DBG
228 memcpy(gte_handlers_nf, gte_handlers, sizeof(gte_handlers_nf));
229#endif
230 psxH_ptr = psxH;
231 zeromem_ptr = zero_mem;
232 scratch_buf_ptr = scratch_buf;
233
234 return 0;
235}
236
237static void ari64_reset()
238{
239 new_dyna_pcsx_mem_reset();
240 new_dynarec_invalidate_all_pages();
241 new_dyna_restore();
242 pending_exception = 1;
243}
244
245// execute until predefined leave points
246// (HLE softcall exit and BIOS fastboot end)
247static void ari64_execute_until()
248{
249 schedule_timeslice();
250
251 evprintf("ari64_execute %08x, %u->%u (%d)\n", psxRegs.pc,
252 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
253
254 new_dyna_start(dynarec_local);
255
256 evprintf("ari64_execute end %08x, %u->%u (%d)\n", psxRegs.pc,
257 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
258}
259
260static void ari64_execute()
261{
262 while (!stop) {
263 ari64_execute_until();
264 evprintf("drc left @%08x\n", psxRegs.pc);
265 }
266}
267
268static void ari64_execute_block(enum blockExecCaller caller)
269{
270 if (caller == EXEC_CALLER_BOOT)
271 stop++;
272
273 ari64_execute_until();
274
275 if (caller == EXEC_CALLER_BOOT)
276 stop--;
277}
278
279static void ari64_clear(u32 addr, u32 size)
280{
281 size *= 4; /* PCSX uses DMA units (words) */
282
283 evprintf("ari64_clear %08x %04x\n", addr, size);
284
285 new_dynarec_invalidate_range(addr, addr + size);
286}
287
288static void ari64_notify(enum R3000Anote note, void *data) {
289 switch (note)
290 {
291 case R3000ACPU_NOTIFY_CACHE_UNISOLATED:
292 case R3000ACPU_NOTIFY_CACHE_ISOLATED:
293 new_dyna_pcsx_mem_isolate(note == R3000ACPU_NOTIFY_CACHE_ISOLATED);
294 break;
295 case R3000ACPU_NOTIFY_BEFORE_SAVE:
296 break;
297 case R3000ACPU_NOTIFY_AFTER_LOAD:
298 ari64_reset();
299 break;
300 }
301}
302
303static void ari64_apply_config()
304{
305 intApplyConfig();
306
307 if (Config.DisableStalls)
308 new_dynarec_hacks |= NDHACK_NO_STALLS;
309 else
310 new_dynarec_hacks &= ~NDHACK_NO_STALLS;
311
312 if (Config.cycle_multiplier != cycle_multiplier_old
313 || new_dynarec_hacks != new_dynarec_hacks_old)
314 {
315 new_dynarec_clear_full();
316 }
317}
318
319static void ari64_shutdown()
320{
321 new_dynarec_cleanup();
322 new_dyna_pcsx_mem_shutdown();
323}
324
325R3000Acpu psxRec = {
326 ari64_init,
327 ari64_reset,
328 ari64_execute,
329 ari64_execute_block,
330 ari64_clear,
331 ari64_notify,
332 ari64_apply_config,
333 ari64_shutdown
334};
335
336#else // if DRC_DISABLE
337
338unsigned int address;
339int pending_exception, stop;
340u32 next_interupt;
341int new_dynarec_did_compile;
342int cycle_multiplier_old;
343int new_dynarec_hacks_pergame;
344int new_dynarec_hacks_old;
345int new_dynarec_hacks;
346void *psxH_ptr;
347void *zeromem_ptr;
348u32 zero_mem[0x1000/4];
349void *mem_rtab;
350void *scratch_buf_ptr;
351void new_dynarec_init() {}
352void new_dyna_start(void *context) {}
353void new_dynarec_cleanup() {}
354void new_dynarec_clear_full() {}
355void new_dynarec_invalidate_all_pages() {}
356void new_dynarec_invalidate_range(unsigned int start, unsigned int end) {}
357void new_dyna_pcsx_mem_init(void) {}
358void new_dyna_pcsx_mem_reset(void) {}
359void new_dyna_pcsx_mem_load_state(void) {}
360void new_dyna_pcsx_mem_isolate(int enable) {}
361void new_dyna_pcsx_mem_shutdown(void) {}
362int new_dynarec_save_blocks(void *save, int size) { return 0; }
363void new_dynarec_load_blocks(const void *save, int size) {}
364#endif
365
366#ifdef DRC_DBG
367
368#include <stddef.h>
369static FILE *f;
370u32 irq_test_cycle;
371u32 handler_cycle;
372u32 last_io_addr;
373
374void dump_mem(const char *fname, void *mem, size_t size)
375{
376 FILE *f1 = fopen(fname, "wb");
377 if (f1 == NULL)
378 f1 = fopen(strrchr(fname, '/') + 1, "wb");
379 fwrite(mem, 1, size, f1);
380 fclose(f1);
381}
382
383static u32 memcheck_read(u32 a)
384{
385 if ((a >> 16) == 0x1f80)
386 // scratchpad/IO
387 return *(u32 *)(psxH + (a & 0xfffc));
388
389 if ((a >> 16) == 0x1f00)
390 // parallel
391 return *(u32 *)(psxP + (a & 0xfffc));
392
393// if ((a & ~0xe0600000) < 0x200000)
394 // RAM
395 return *(u32 *)(psxM + (a & 0x1ffffc));
396}
397
398#if 0
399void do_insn_trace(void)
400{
401 static psxRegisters oldregs;
402 static u32 event_cycles_o[PSXINT_COUNT];
403 u32 *allregs_p = (void *)&psxRegs;
404 u32 *allregs_o = (void *)&oldregs;
405 u32 io_data;
406 int i;
407 u8 byte;
408
409 //last_io_addr = 0x5e2c8;
410 if (f == NULL)
411 f = fopen("tracelog", "wb");
412
413 // log reg changes
414 oldregs.code = psxRegs.code; // don't care
415 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
416 if (allregs_p[i] != allregs_o[i]) {
417 fwrite(&i, 1, 1, f);
418 fwrite(&allregs_p[i], 1, 4, f);
419 allregs_o[i] = allregs_p[i];
420 }
421 }
422 // log event changes
423 for (i = 0; i < PSXINT_COUNT; i++) {
424 if (event_cycles[i] != event_cycles_o[i]) {
425 byte = 0xf8;
426 fwrite(&byte, 1, 1, f);
427 fwrite(&i, 1, 1, f);
428 fwrite(&event_cycles[i], 1, 4, f);
429 event_cycles_o[i] = event_cycles[i];
430 }
431 }
432 #define SAVE_IF_CHANGED(code_, name_) { \
433 static u32 old_##name_ = 0xbad0c0de; \
434 if (old_##name_ != name_) { \
435 byte = code_; \
436 fwrite(&byte, 1, 1, f); \
437 fwrite(&name_, 1, 4, f); \
438 old_##name_ = name_; \
439 } \
440 }
441 SAVE_IF_CHANGED(0xfb, irq_test_cycle);
442 SAVE_IF_CHANGED(0xfc, handler_cycle);
443 SAVE_IF_CHANGED(0xfd, last_io_addr);
444 io_data = memcheck_read(last_io_addr);
445 SAVE_IF_CHANGED(0xfe, io_data);
446 byte = 0xff;
447 fwrite(&byte, 1, 1, f);
448
449#if 0
450 if (psxRegs.cycle == 190230) {
451 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
452 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
453 printf("dumped\n");
454 exit(1);
455 }
456#endif
457}
458#endif
459
460static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
461 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
462 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
463 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
464 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
465 "lo", "hi",
466 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
467 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
468 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
469 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
470
471 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
472 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
473 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
474 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
475
476 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
477 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
478 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
479 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
480
481 "PC", "code", "cycle", "interrupt",
482};
483
484static struct {
485 int reg;
486 u32 val, val_expect;
487 u32 pc, cycle;
488} miss_log[64];
489static int miss_log_i;
490#define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
491#define miss_log_mask (miss_log_len-1)
492
493static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
494{
495 miss_log[miss_log_i].reg = reg;
496 miss_log[miss_log_i].val = val;
497 miss_log[miss_log_i].val_expect = val_expect;
498 miss_log[miss_log_i].pc = pc;
499 miss_log[miss_log_i].cycle = cycle;
500 miss_log_i = (miss_log_i + 1) & miss_log_mask;
501}
502
503void breakme() {}
504
505void do_insn_cmp(void)
506{
507 extern int last_count;
508 static psxRegisters rregs;
509 static u32 mem_addr, mem_val;
510 static u32 irq_test_cycle_intr;
511 static u32 handler_cycle_intr;
512 u32 *allregs_p = (void *)&psxRegs;
513 u32 *allregs_e = (void *)&rregs;
514 u32 badregs_mask = 0;
515 static u32 ppc, failcount;
516 static u32 badregs_mask_prev;
517 int i, ret, bad = 0, fatal = 0, which_event = -1;
518 u32 ev_cycles = 0;
519 u8 code;
520
521 if (f == NULL)
522 f = fopen("tracelog", "rb");
523
524 while (1) {
525 if ((ret = fread(&code, 1, 1, f)) <= 0)
526 break;
527 if (ret <= 0)
528 break;
529 if (code == 0xff)
530 break;
531 switch (code) {
532 case 0xf8:
533 which_event = 0;
534 fread(&which_event, 1, 1, f);
535 fread(&ev_cycles, 1, 4, f);
536 continue;
537 case 0xfb:
538 fread(&irq_test_cycle_intr, 1, 4, f);
539 continue;
540 case 0xfc:
541 fread(&handler_cycle_intr, 1, 4, f);
542 continue;
543 case 0xfd:
544 fread(&mem_addr, 1, 4, f);
545 continue;
546 case 0xfe:
547 fread(&mem_val, 1, 4, f);
548 continue;
549 }
550 assert(code < offsetof(psxRegisters, intCycle) / 4);
551 fread(&allregs_e[code], 1, 4, f);
552 }
553
554 if (ret <= 0) {
555 printf("EOF?\n");
556 exit(1);
557 }
558
559 psxRegs.code = rregs.code; // don't care
560 psxRegs.cycle += last_count;
561 //psxRegs.cycle = rregs.cycle; // needs reload in _cmp
562 psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
563
564 //if (psxRegs.cycle == 166172) breakme();
565
566 if (which_event >= 0 && event_cycles[which_event] != ev_cycles) {
567 printf("bad ev_cycles #%d: %u %u / %u\n", which_event,
568 event_cycles[which_event], ev_cycles, psxRegs.cycle);
569 fatal = 1;
570 }
571
572 if (irq_test_cycle > irq_test_cycle_intr) {
573 printf("bad irq_test_cycle: %u %u\n", irq_test_cycle, irq_test_cycle_intr);
574 fatal = 1;
575 }
576
577 if (handler_cycle != handler_cycle_intr) {
578 printf("bad handler_cycle: %u %u\n", handler_cycle, handler_cycle_intr);
579 fatal = 1;
580 }
581
582 if (mem_val != memcheck_read(mem_addr)) {
583 printf("bad mem @%08x: %08x %08x\n", mem_addr, memcheck_read(mem_addr), mem_val);
584 fatal = 1;
585 }
586
587 if (!fatal && !memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle))) {
588 failcount = 0;
589 goto ok;
590 }
591
592 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
593 if (allregs_p[i] != allregs_e[i]) {
594 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
595 bad++;
596 if (i >= 32)
597 fatal = 1;
598 else
599 badregs_mask |= 1u << i;
600 }
601 }
602
603 if (badregs_mask_prev & badregs_mask)
604 failcount++;
605 else
606 failcount = 0;
607
608 if (!fatal && psxRegs.pc == rregs.pc && bad < 6 && failcount < 24) {
609 static int last_mcycle;
610 if (last_mcycle != psxRegs.cycle >> 20) {
611 printf("%u\n", psxRegs.cycle);
612 last_mcycle = psxRegs.cycle >> 20;
613 }
614 goto ok;
615 }
616
617 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
618 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
619 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
620 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
621 printf("-- %d\n", bad);
622 for (i = 0; i < 8; i++)
623 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
624 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+24]);
625 printf("PC: %08x/%08x, cycle %u, next %u\n", psxRegs.pc, ppc, psxRegs.cycle, next_interupt);
626 //dump_mem("/tmp/psxram.dump", psxM, 0x200000);
627 //dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
628 exit(1);
629ok:
630 //psxRegs.cycle = rregs.cycle + 2; // sync timing
631 ppc = psxRegs.pc;
632 badregs_mask_prev = badregs_mask;
633}
634
635#endif