2 * (C) GraÅžvydas "notaz" Ignotas, 2010
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"
18 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
20 //#define evprintf printf
23 char invalid_code[0x100000];
24 u32 event_cycles[PSXINT_COUNT];
26 static void schedule_timeslice(void)
28 u32 i, c = psxRegs.cycle;
31 min = psxNextsCounter + psxNextCounter - c;
32 for (i = 0; i < ARRAY_SIZE(event_cycles); i++) {
33 dif = event_cycles[i] - c;
34 //evprintf(" ev %d\n", dif);
35 if (0 < dif && dif < min)
38 next_interupt = c + min;
41 static u32 cnt, last_cycle;
45 sum += psxRegs.cycle - last_cycle;
46 if ((cnt & 0xff) == 0)
47 printf("%u\n", (u32)(sum / cnt));
49 last_cycle = psxRegs.cycle;
53 typedef void (irq_func)();
55 static irq_func * const irq_funcs[] = {
56 [PSXINT_SIO] = sioInterrupt,
57 [PSXINT_CDR] = cdrInterrupt,
58 [PSXINT_CDREAD] = cdrReadInterrupt,
59 [PSXINT_GPUDMA] = gpuInterrupt,
60 [PSXINT_MDECOUTDMA] = mdec1Interrupt,
61 [PSXINT_SPUDMA] = spuInterrupt,
62 [PSXINT_MDECINDMA] = mdec0Interrupt,
63 [PSXINT_GPUOTCDMA] = gpuotcInterrupt,
66 /* local dupe of psxBranchTest, using event_cycles */
67 static void irq_test(void)
69 u32 irqs = psxRegs.interrupt;
70 u32 cycle = psxRegs.cycle;
73 if ((psxRegs.cycle - psxNextsCounter) >= psxNextCounter)
76 // irq_funcs() may queue more irqs
77 psxRegs.interrupt = 0;
79 for (irq = 0, irq_bits = irqs; irq_bits != 0; irq++, irq_bits >>= 1) {
82 if ((s32)(cycle - event_cycles[irq]) >= 0) {
87 psxRegs.interrupt |= irqs;
89 if ((psxHu32(0x1070) & psxHu32(0x1074)) && (Status & 0x401) == 0x401) {
90 psxException(0x400, 0);
91 pending_exception = 1;
97 evprintf(" +ge %08x, %u->%u\n", psxRegs.pc, psxRegs.cycle, next_interupt);
104 //pending_exception = 1;
106 schedule_timeslice();
108 evprintf(" -ge %08x, %u->%u (%d)\n", psxRegs.pc, psxRegs.cycle,
109 next_interupt, next_interupt - psxRegs.cycle);
114 extern void psxMTC0();
116 evprintf("ari64 MTC0 %08x %08x %u\n", psxRegs.code, psxRegs.pc, psxRegs.cycle);
118 gen_interupt(); /* FIXME: checking pending irqs should be enough */
121 void check_interupt()
123 /* FIXME (also asm) */
124 printf("ari64_check_interupt\n");
127 void new_dyna_save(void)
129 // psxRegs.intCycle is always maintained, no need to convert
132 void new_dyna_restore(void)
135 for (i = 0; i < PSXINT_NEWDRC_CHECK; i++)
136 event_cycles[i] = psxRegs.intCycle[i].sCycle + psxRegs.intCycle[i].cycle;
139 void *gte_handlers[64];
141 /* from gte.txt.. not sure if this is any good. */
142 const char gte_cycletab[64] = {
143 /* 1 2 3 4 5 6 7 8 9 a b c d e f */
144 0, 15, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 6, 0, 0, 0,
145 8, 8, 8, 19, 13, 0, 44, 0, 0, 0, 0, 17, 11, 0, 14, 0,
146 30, 0, 0, 0, 0, 0, 0, 0, 5, 8, 17, 0, 0, 5, 6, 0,
147 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 39,
150 static int ari64_init()
152 extern void (*psxCP2[64])();
153 extern void psxNULL();
154 extern void *psxH_ptr;
158 new_dyna_pcsx_mem_init();
160 for (i = 0; i < ARRAY_SIZE(gte_handlers); i++)
161 if (psxCP2[i] != psxNULL)
162 gte_handlers[i] = psxCP2[i];
169 static void ari64_reset()
171 printf("ari64_reset\n");
172 new_dyna_pcsx_mem_reset();
173 invalidate_all_pages();
174 pending_exception = 1;
177 static void ari64_execute()
179 schedule_timeslice();
181 evprintf("ari64_execute %08x, %u->%u (%d)\n", psxRegs.pc,
182 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
186 evprintf("ari64_execute end %08x, %u->%u (%d)\n", psxRegs.pc,
187 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
190 static void ari64_clear(u32 addr, u32 size)
194 evprintf("ari64_clear %08x %04x\n", addr, size);
196 /* check for RAM mirrors */
197 if ((addr & ~0xe0600000) < 0x200000) {
203 end = (addr + size) >> 12;
205 for (; start <= end; start++)
206 if (!invalid_code[start])
207 invalidate_block(start);
210 static void ari64_shutdown()
212 new_dynarec_cleanup();
215 extern void intExecute();
216 extern void intExecuteT();
217 extern void intExecuteBlock();
218 extern void intExecuteBlockT();
220 #define intExecuteT intExecute
221 #define intExecuteBlockT intExecuteBlock
240 void do_insn_trace() {}
241 void do_insn_cmp() {}
244 #if defined(__x86_64__) || defined(__i386__)
245 unsigned int address, readmem_word, word;
246 unsigned short hword;
248 int pending_exception, stop;
249 unsigned int next_interupt;
251 void new_dynarec_init() {}
252 void new_dyna_start() {}
253 void new_dynarec_cleanup() {}
254 void invalidate_all_pages() {}
255 void invalidate_block(unsigned int block) {}
256 void new_dyna_pcsx_mem_init(void) {}
257 void new_dyna_pcsx_mem_reset(void) {}
264 extern u32 last_io_addr;
266 static void dump_mem(const char *fname, void *mem, size_t size)
268 FILE *f1 = fopen(fname, "wb");
270 f1 = fopen(strrchr(fname, '/') + 1, "wb");
271 fwrite(mem, 1, size, f1);
275 void do_insn_trace(void)
277 static psxRegisters oldregs;
278 static u32 old_io_addr = (u32)-1;
279 static u32 old_io_data = 0xbad0c0de;
280 u32 *allregs_p = (void *)&psxRegs;
281 u32 *allregs_o = (void *)&oldregs;
286 //last_io_addr = 0x5e2c8;
288 f = fopen("tracelog", "wb");
290 oldregs.code = psxRegs.code; // don't care
291 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
292 if (allregs_p[i] != allregs_o[i]) {
294 fwrite(&allregs_p[i], 1, 4, f);
295 allregs_o[i] = allregs_p[i];
298 if (old_io_addr != last_io_addr) {
300 fwrite(&byte, 1, 1, f);
301 fwrite(&last_io_addr, 1, 4, f);
302 old_io_addr = last_io_addr;
304 io_data = (void *)(psxM + (last_io_addr&0x1ffffc));
305 if (old_io_data != *io_data) {
307 fwrite(&byte, 1, 1, f);
308 fwrite(io_data, 1, 4, f);
309 old_io_data = *io_data;
312 fwrite(&byte, 1, 1, f);
315 if (psxRegs.cycle == 190230) {
316 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
317 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
324 static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
325 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
326 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
327 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
328 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
330 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
331 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
332 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
333 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
335 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
336 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
337 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
338 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
340 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
341 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
342 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
343 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
345 "PC", "code", "cycle", "interrupt",
353 static int miss_log_i;
354 #define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
355 #define miss_log_mask (miss_log_len-1)
357 static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
359 miss_log[miss_log_i].reg = reg;
360 miss_log[miss_log_i].val = val;
361 miss_log[miss_log_i].val_expect = val_expect;
362 miss_log[miss_log_i].pc = pc;
363 miss_log[miss_log_i].cycle = cycle;
364 miss_log_i = (miss_log_i + 1) & miss_log_mask;
369 void do_insn_cmp(void)
371 static psxRegisters rregs;
372 static u32 mem_addr, mem_val;
373 u32 *allregs_p = (void *)&psxRegs;
374 u32 *allregs_e = (void *)&rregs;
375 static u32 ppc, failcount;
380 f = fopen("tracelog", "rb");
383 if ((ret = fread(&code, 1, 1, f)) <= 0)
390 if ((ret = fread(&mem_addr, 1, 4, f)) <= 0)
395 if ((ret = fread(&mem_val, 1, 4, f)) <= 0)
399 if ((ret = fread(&allregs_e[code], 1, 4, f)) <= 0)
408 psxRegs.code = rregs.code; // don't care
409 psxRegs.cycle = rregs.cycle;
410 psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
412 //if (psxRegs.cycle == 166172) breakme();
413 //if (psxRegs.cycle > 11296376) printf("pc=%08x %u %08x\n", psxRegs.pc, psxRegs.cycle, psxRegs.interrupt);
415 mem_addr &= 0x1ffffc;
417 if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
418 mem_val == *(u32 *)(psxM + mem_addr)
424 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
425 if (allregs_p[i] != allregs_e[i]) {
426 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
431 if (mem_val != *(u32 *)(psxM + mem_addr)) {
432 printf("bad mem @%08x: %08x %08x\n", mem_addr, *(u32 *)(psxM + mem_addr), mem_val);
436 if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
437 static int last_mcycle;
438 if (last_mcycle != psxRegs.cycle >> 20) {
439 printf("%u\n", psxRegs.cycle);
440 last_mcycle = psxRegs.cycle >> 20;
447 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
448 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
449 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
450 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
451 printf("-- %d\n", bad);
452 for (i = 0; i < 8; i++)
453 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
454 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+24]);
455 printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
456 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
457 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
460 psxRegs.cycle = rregs.cycle + 2; // sync timing