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.
9 // swi 0 in do_unalignedwritestub?
14 #include "../psxhle.h"
15 #include "../r3000a.h"
17 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
19 //#define evprintf printf
22 char invalid_code[0x100000];
23 u32 event_cycles[PSXINT_COUNT];
25 static void schedule_timeslice(void)
27 u32 i, c = psxRegs.cycle;
30 min = psxNextsCounter + psxNextCounter - c;
31 for (i = 0; i < ARRAY_SIZE(event_cycles); i++) {
32 dif = event_cycles[i] - c;
33 //evprintf(" ev %d\n", dif);
34 if (0 < dif && dif < min)
37 next_interupt = c + min;
40 static u32 cnt, last_cycle;
44 sum += psxRegs.cycle - last_cycle;
45 if ((cnt & 0xff) == 0)
46 printf("%u\n", (u32)(sum / cnt));
48 last_cycle = psxRegs.cycle;
54 evprintf(" +ge %08x, %u->%u\n", psxRegs.pc, psxRegs.cycle, next_interupt);
63 evprintf(" -ge %08x, %u->%u (%d)\n", psxRegs.pc, psxRegs.cycle,
64 next_interupt, next_interupt - psxRegs.cycle);
66 pending_exception = 1; /* FIXME */
71 extern void psxMTC0();
73 evprintf("ari64 MTC0 %08x %08x %u\n", psxRegs.code, psxRegs.pc, psxRegs.cycle);
75 gen_interupt(); /* FIXME: checking pending irqs should be enough */
80 printf("ari64_check_interupt\n");
83 void *gte_handlers[64];
85 /* from gte.txt.. not sure if this is any good. */
86 const char gte_cycletab[64] = {
87 /* 1 2 3 4 5 6 7 8 9 a b c d e f */
88 0, 15, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 6, 0, 0, 0,
89 8, 8, 8, 19, 13, 0, 44, 0, 0, 0, 0, 17, 11, 0, 14, 0,
90 30, 0, 0, 0, 0, 0, 0, 0, 5, 8, 17, 0, 0, 5, 6, 0,
91 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 39,
94 static int ari64_init()
96 extern void (*psxCP2[64])();
97 extern void psxNULL();
98 extern void *psxH_ptr;
102 new_dyna_pcsx_mem_init();
104 for (i = 0; i < ARRAY_SIZE(gte_handlers); i++)
105 if (psxCP2[i] != psxNULL)
106 gte_handlers[i] = psxCP2[i];
113 static void ari64_reset()
115 printf("ari64_reset\n");
116 new_dyna_pcsx_mem_reset();
117 invalidate_all_pages();
118 pending_exception = 1;
121 static void ari64_execute()
123 schedule_timeslice();
125 evprintf("ari64_execute %08x, %u->%u (%d)\n", psxRegs.pc,
126 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
130 evprintf("ari64_execute end %08x, %u->%u (%d)\n", psxRegs.pc,
131 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
134 static void ari64_clear(u32 addr, u32 size)
138 evprintf("ari64_clear %08x %04x\n", addr, size);
140 /* check for RAM mirrors */
141 if ((addr & ~0xe0600000) < 0x200000) {
147 end = (addr + size) >> 12;
149 for (; start <= end; start++)
150 if (!invalid_code[start])
151 invalidate_block(start);
154 static void ari64_shutdown()
156 new_dynarec_cleanup();
159 extern void intExecute();
160 extern void intExecuteT();
161 extern void intExecuteBlock();
162 extern void intExecuteBlockT();
164 #define intExecuteT intExecute
165 #define intExecuteBlockT intExecuteBlock
184 void do_insn_trace() {}
185 void do_insn_cmp() {}
188 #if defined(__x86_64__) || defined(__i386__)
189 unsigned int address, readmem_word, word;
190 unsigned short hword;
192 int pending_exception, stop;
193 unsigned int next_interupt;
195 void new_dynarec_init() {}
196 void new_dyna_start() {}
197 void new_dynarec_cleanup() {}
198 void invalidate_all_pages() {}
199 void invalidate_block(unsigned int block) {}
200 void new_dyna_pcsx_mem_init(void) {}
201 void new_dyna_pcsx_mem_reset(void) {}
208 extern u32 last_io_addr;
210 static void dump_mem(const char *fname, void *mem, size_t size)
212 FILE *f1 = fopen(fname, "wb");
214 f1 = fopen(strrchr(fname, '/') + 1, "wb");
215 fwrite(mem, 1, size, f1);
219 void do_insn_trace(void)
221 static psxRegisters oldregs;
222 static u32 old_io_addr = (u32)-1;
223 static u32 old_io_data = 0xbad0c0de;
224 u32 *allregs_p = (void *)&psxRegs;
225 u32 *allregs_o = (void *)&oldregs;
230 //last_io_addr = 0x5e2c8;
232 f = fopen("tracelog", "wb");
234 oldregs.code = psxRegs.code; // don't care
235 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
236 if (allregs_p[i] != allregs_o[i]) {
238 fwrite(&allregs_p[i], 1, 4, f);
239 allregs_o[i] = allregs_p[i];
242 if (old_io_addr != last_io_addr) {
244 fwrite(&byte, 1, 1, f);
245 fwrite(&last_io_addr, 1, 4, f);
246 old_io_addr = last_io_addr;
248 io_data = (void *)(psxM + (last_io_addr&0x1ffffc));
249 if (old_io_data != *io_data) {
251 fwrite(&byte, 1, 1, f);
252 fwrite(io_data, 1, 4, f);
253 old_io_data = *io_data;
256 fwrite(&byte, 1, 1, f);
259 if (psxRegs.cycle == 190230) {
260 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
261 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
268 static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
269 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
270 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
271 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
272 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
274 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
275 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
276 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
277 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
279 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
280 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
281 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
282 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
284 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
285 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
286 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
287 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
289 "PC", "code", "cycle", "interrupt",
297 static int miss_log_i;
298 #define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
299 #define miss_log_mask (miss_log_len-1)
301 static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
303 miss_log[miss_log_i].reg = reg;
304 miss_log[miss_log_i].val = val;
305 miss_log[miss_log_i].val_expect = val_expect;
306 miss_log[miss_log_i].pc = pc;
307 miss_log[miss_log_i].cycle = cycle;
308 miss_log_i = (miss_log_i + 1) & miss_log_mask;
313 void do_insn_cmp(void)
315 static psxRegisters rregs;
316 static u32 mem_addr, mem_val;
317 u32 *allregs_p = (void *)&psxRegs;
318 u32 *allregs_e = (void *)&rregs;
319 static u32 ppc, failcount;
324 f = fopen("tracelog", "rb");
327 if ((ret = fread(&code, 1, 1, f)) <= 0)
334 if ((ret = fread(&mem_addr, 1, 4, f)) <= 0)
339 if ((ret = fread(&mem_val, 1, 4, f)) <= 0)
343 if ((ret = fread(&allregs_e[code], 1, 4, f)) <= 0)
352 psxRegs.code = rregs.code; // don't care
353 psxRegs.cycle = rregs.cycle;
354 psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
356 //if (psxRegs.cycle == 166172) breakme();
357 //if (psxRegs.cycle > 11296376) printf("pc=%08x %u %08x\n", psxRegs.pc, psxRegs.cycle, psxRegs.interrupt);
359 mem_addr &= 0x1ffffc;
361 if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
362 mem_val == *(u32 *)(psxM + mem_addr)
368 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
369 if (allregs_p[i] != allregs_e[i]) {
370 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
375 if (mem_val != *(u32 *)(psxM + mem_addr)) {
376 printf("bad mem @%08x: %08x %08x\n", mem_addr, *(u32 *)(psxM + mem_addr), mem_val);
380 if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
381 static int last_mcycle;
382 if (last_mcycle != psxRegs.cycle >> 20) {
383 printf("%u\n", psxRegs.cycle);
384 last_mcycle = psxRegs.cycle >> 20;
391 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
392 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
393 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
394 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
395 printf("-- %d\n", bad);
396 for (i = 0; i < 8; i++)
397 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
398 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+24]);
399 printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
400 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
401 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
404 psxRegs.cycle = rregs.cycle + 2; // sync timing