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"
16 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
18 //#define evprintf printf
21 char invalid_code[0x100000];
24 static void schedule_timeslice(void)
26 u32 i, c = psxRegs.cycle;
29 min = psxNextsCounter + psxNextCounter - c;
30 for (i = 0; i < ARRAY_SIZE(event_cycles); i++) {
31 dif = event_cycles[i] - c;
32 //evprintf(" ev %d\n", dif);
33 if (0 < dif && dif < min)
36 next_interupt = c + min;
39 static u32 cnt, last_cycle;
43 sum += psxRegs.cycle - last_cycle;
44 if ((cnt & 0xff) == 0)
45 printf("%u\n", (u32)(sum / cnt));
47 last_cycle = psxRegs.cycle;
53 evprintf(" +ge %08x, %u->%u\n", psxRegs.pc, psxRegs.cycle, next_interupt);
62 evprintf(" -ge %08x, %u->%u (%d)\n", psxRegs.pc, psxRegs.cycle,
63 next_interupt, next_interupt - psxRegs.cycle);
65 pending_exception = 1; /* FIXME */
70 extern void psxMTC0();
72 evprintf("ari64 MTC0 %08x %08x %u\n", psxRegs.code, psxRegs.pc, psxRegs.cycle);
74 gen_interupt(); /* FIXME: checking pending irqs should be enough */
79 printf("ari64_check_interupt\n");
82 void *gte_handlers[64];
84 /* from gte.txt.. not sure if this is any good. */
85 const char gte_cycletab[64] = {
86 /* 1 2 3 4 5 6 7 8 9 a b c d e f */
87 0, 15, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 6, 0, 0, 0,
88 8, 8, 8, 19, 13, 0, 44, 0, 0, 0, 0, 17, 11, 0, 14, 0,
89 30, 0, 0, 0, 0, 0, 0, 0, 5, 8, 17, 0, 0, 5, 6, 0,
90 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 39,
93 static int ari64_init()
95 extern void (*psxCP2[64])();
96 extern void psxNULL();
97 extern void *psxH_ptr;
101 new_dyna_pcsx_mem_init();
103 for (i = 0; i < ARRAY_SIZE(gte_handlers); i++)
104 if (psxCP2[i] != psxNULL)
105 gte_handlers[i] = psxCP2[i];
112 static void ari64_reset()
114 printf("ari64_reset\n");
115 new_dyna_pcsx_mem_reset();
116 invalidate_all_pages();
117 pending_exception = 1;
120 static void ari64_execute()
122 schedule_timeslice();
124 evprintf("ari64_execute %08x, %u->%u (%d)\n", psxRegs.pc,
125 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
129 evprintf("ari64_execute end %08x, %u->%u (%d)\n", psxRegs.pc,
130 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
133 static void ari64_clear(u32 addr, u32 size)
137 evprintf("ari64_clear %08x %04x\n", addr, size);
139 /* check for RAM mirrors */
140 if ((addr & ~0xe0600000) < 0x200000) {
146 end = (addr + size) >> 12;
148 for (; start <= end; start++)
149 if (!invalid_code[start])
150 invalidate_block(start);
153 static void ari64_shutdown()
155 new_dynarec_cleanup();
158 extern void intExecute();
159 extern void intExecuteT();
160 extern void intExecuteBlock();
161 extern void intExecuteBlockT();
163 #define intExecuteT intExecute
164 #define intExecuteBlockT intExecuteBlock
183 void do_insn_trace() {}
184 void do_insn_cmp() {}
187 #if defined(__x86_64__) || defined(__i386__)
188 unsigned int address, readmem_word, word;
189 unsigned short hword;
191 int pending_exception, stop;
192 unsigned int next_interupt;
194 void new_dynarec_init() {}
195 void new_dyna_start() {}
196 void new_dynarec_cleanup() {}
197 void invalidate_all_pages() {}
198 void invalidate_block(unsigned int block) {}
199 void new_dyna_pcsx_mem_init(void) {}
200 void new_dyna_pcsx_mem_reset(void) {}
207 extern u32 last_io_addr;
209 static void dump_mem(const char *fname, void *mem, size_t size)
211 FILE *f1 = fopen(fname, "wb");
213 f1 = fopen(strrchr(fname, '/') + 1, "wb");
214 fwrite(mem, 1, size, f1);
218 void do_insn_trace(void)
220 static psxRegisters oldregs;
221 static u32 old_io_addr = (u32)-1;
222 static u32 old_io_data = 0xbad0c0de;
223 u32 *allregs_p = (void *)&psxRegs;
224 u32 *allregs_o = (void *)&oldregs;
229 //last_io_addr = 0x5e2c8;
231 f = fopen("tracelog", "wb");
233 oldregs.code = psxRegs.code; // don't care
234 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
235 if (allregs_p[i] != allregs_o[i]) {
237 fwrite(&allregs_p[i], 1, 4, f);
238 allregs_o[i] = allregs_p[i];
241 if (old_io_addr != last_io_addr) {
243 fwrite(&byte, 1, 1, f);
244 fwrite(&last_io_addr, 1, 4, f);
245 old_io_addr = last_io_addr;
247 io_data = (void *)(psxM + (last_io_addr&0x1ffffc));
248 if (old_io_data != *io_data) {
250 fwrite(&byte, 1, 1, f);
251 fwrite(io_data, 1, 4, f);
252 old_io_data = *io_data;
255 fwrite(&byte, 1, 1, f);
258 if (psxRegs.cycle == 190230) {
259 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
260 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
267 static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
268 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
269 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
270 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
271 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
273 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
274 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
275 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
276 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
278 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
279 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
280 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
281 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
283 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
284 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
285 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
286 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
288 "PC", "code", "cycle", "interrupt",
296 static int miss_log_i;
297 #define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
298 #define miss_log_mask (miss_log_len-1)
300 static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
302 miss_log[miss_log_i].reg = reg;
303 miss_log[miss_log_i].val = val;
304 miss_log[miss_log_i].val_expect = val_expect;
305 miss_log[miss_log_i].pc = pc;
306 miss_log[miss_log_i].cycle = cycle;
307 miss_log_i = (miss_log_i + 1) & miss_log_mask;
312 void do_insn_cmp(void)
314 static psxRegisters rregs;
315 static u32 mem_addr, mem_val;
316 u32 *allregs_p = (void *)&psxRegs;
317 u32 *allregs_e = (void *)&rregs;
318 static u32 ppc, failcount;
323 f = fopen("tracelog", "rb");
326 if ((ret = fread(&code, 1, 1, f)) <= 0)
333 if ((ret = fread(&mem_addr, 1, 4, f)) <= 0)
338 if ((ret = fread(&mem_val, 1, 4, f)) <= 0)
342 if ((ret = fread(&allregs_e[code], 1, 4, f)) <= 0)
351 psxRegs.code = rregs.code; // don't care
352 psxRegs.cycle = rregs.cycle;
353 psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
355 //if (psxRegs.cycle == 166172) breakme();
356 //if (psxRegs.cycle > 11296376) printf("pc=%08x %u %08x\n", psxRegs.pc, psxRegs.cycle, psxRegs.interrupt);
358 mem_addr &= 0x1ffffc;
360 if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
361 mem_val == *(u32 *)(psxM + mem_addr)
367 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
368 if (allregs_p[i] != allregs_e[i]) {
369 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
374 if (mem_val != *(u32 *)(psxM + mem_addr)) {
375 printf("bad mem @%08x: %08x %08x\n", mem_addr, *(u32 *)(psxM + mem_addr), mem_val);
379 if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
380 static int last_mcycle;
381 if (last_mcycle != psxRegs.cycle >> 20) {
382 printf("%u\n", psxRegs.cycle);
383 last_mcycle = psxRegs.cycle >> 20;
390 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
391 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
392 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
393 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
394 printf("-- %d\n", bad);
395 for (i = 0; i < 8; i++)
396 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
397 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+24]);
398 printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
399 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
400 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
403 psxRegs.cycle = rregs.cycle + 2; // sync timing