2 // swi 0 in do_unalignedwritestub?
9 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
11 //#define memprintf printf
12 #define memprintf(...)
13 //#define evprintf printf
16 char invalid_code[0x100000];
21 extern void psxMTC0();
23 memprintf("ari64 MTC0 %08x\n", psxRegs.code);
25 pending_exception = 1; /* FIXME? */
28 static void schedule_timeslice(void)
30 u32 i, c = psxRegs.cycle;
33 min = psxNextsCounter + psxNextCounter - c;
34 for (i = 0; i < ARRAY_SIZE(event_cycles); i++) {
35 dif = event_cycles[i] - c;
36 //evprintf(" ev %d\n", dif);
37 if (0 < dif && dif < min)
40 next_interupt = c + min;
43 static u32 cnt, last_cycle;
47 sum += psxRegs.cycle - last_cycle;
48 if ((cnt & 0xff) == 0)
49 printf("%u\n", (u32)(sum / cnt));
51 last_cycle = psxRegs.cycle;
57 //evprintf("ari64_gen_interupt\n");
58 evprintf(" +ge %08x, %u->%u\n", psxRegs.pc, psxRegs.cycle, next_interupt);
67 evprintf(" -ge %08x, %u->%u (%d)\n", psxRegs.pc, psxRegs.cycle,
68 next_interupt, next_interupt - psxRegs.cycle);
70 pending_exception = 1; /* FIXME */
75 printf("ari64_check_interupt\n");
80 printf("ari64_read_nomem_new\n");
83 static void read_mem8()
85 memprintf("ari64_read_mem8 %08x, PC~=%08x\n", address, psxRegs.pc);
86 readmem_word = psxMemRead8(address) & 0xff;
89 static void read_mem16()
91 memprintf("ari64_read_mem16 %08x, PC~=%08x\n", address, psxRegs.pc);
92 readmem_word = psxMemRead16(address) & 0xffff;
95 static void read_mem32()
97 memprintf("ari64_read_mem32 %08x, PC~=%08x\n", address, psxRegs.pc);
98 readmem_word = psxMemRead32(address);
101 static void write_mem8()
103 memprintf("ari64_write_mem8 %08x, %02x, PC~=%08x\n", address, byte, psxRegs.pc);
104 psxMemWrite8(address, byte);
107 static void write_mem16()
109 memprintf("ari64_write_mem16 %08x, %04x, PC~=%08x\n", address, hword, psxRegs.pc);
110 psxMemWrite16(address, hword);
113 static void write_mem32()
115 memprintf("ari64_write_mem32 %08x, %08x, PC~=%08x\n", address, word, psxRegs.pc);
116 psxMemWrite32(address, word);
119 void (*readmem[0x10000])();
120 void (*readmemb[0x10000])();
121 void (*readmemh[0x10000])();
122 void (*writemem[0x10000])();
123 void (*writememb[0x10000])();
124 void (*writememh[0x10000])();
126 void *gte_handlers[64];
128 /* from gte.txt.. not sure if this is any good. */
129 const char gte_cycletab[64] = {
130 /* 1 2 3 4 5 6 7 8 9 a b c d e f */
131 0, 15, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 6, 0, 0, 0,
132 8, 8, 8, 19, 13, 0, 44, 0, 0, 0, 0, 17, 11, 0, 14, 0,
133 30, 0, 0, 0, 0, 0, 0, 0, 5, 8, 17, 0, 0, 5, 6, 0,
134 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 39,
137 static int ari64_init()
139 extern void (*psxCP2[64])();
140 extern void psxNULL();
145 for (i = 0; i < ARRAY_SIZE(readmem); i++) {
146 readmemb[i] = read_mem8;
147 readmemh[i] = read_mem16;
148 readmem[i] = read_mem32;
149 writememb[i] = write_mem8;
150 writememh[i] = write_mem16;
151 writemem[i] = write_mem32;
154 for (i = 0; i < ARRAY_SIZE(gte_handlers); i++)
155 if (psxCP2[i] != psxNULL)
156 gte_handlers[i] = psxCP2[i];
161 static void ari64_reset()
163 printf("ari64_reset\n");
164 invalidate_all_pages();
165 pending_exception = 1;
168 static void ari64_execute()
170 schedule_timeslice();
172 evprintf("ari64_execute %08x, %u->%u (%d)\n", psxRegs.pc,
173 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
177 evprintf("ari64_execute end %08x, %u->%u (%d)\n", psxRegs.pc,
178 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
181 static void ari64_clear(u32 addr, u32 size)
185 evprintf("ari64_clear %08x %04x\n", addr, size);
187 /* check for RAM mirrors */
188 if ((start & ~0xe0000000) < 0x200000) {
189 start &= ~0xe0000000;
194 end = (addr + size) >> 12;
196 for (; start <= end; start++)
197 if (!invalid_code[start])
198 invalidate_block(start);
201 static void ari64_shutdown()
203 new_dynarec_cleanup();
206 extern void intExecute();
207 extern void intExecuteT();
208 extern void intExecuteBlock();
209 extern void intExecuteBlockT();
211 #define intExecuteT intExecute
212 #define intExecuteBlockT intExecuteBlock
231 void do_insn_trace() {}
232 void do_insn_cmp() {}
235 #if defined(__x86_64__) || defined(__i386__)
236 unsigned int address, readmem_word, word;
237 unsigned short hword;
239 int pending_exception;
240 unsigned int next_interupt;
241 void new_dynarec_init() {}
242 void new_dyna_start() {}
243 void new_dynarec_cleanup() {}
250 extern u32 last_io_addr;
252 static void dump_mem(const char *fname, void *mem, size_t size)
254 FILE *f1 = fopen(fname, "wb");
256 f1 = fopen(strrchr(fname, '/') + 1, "wb");
257 fwrite(mem, 1, size, f1);
261 void do_insn_trace(void)
263 static psxRegisters oldregs;
264 static u32 old_io_addr = (u32)-1;
265 static u32 old_io_data = 0xbad0c0de;
266 u32 *allregs_p = (void *)&psxRegs;
267 u32 *allregs_o = (void *)&oldregs;
272 //last_io_addr = 0x5e2c8;
274 f = fopen("tracelog", "wb");
276 oldregs.code = psxRegs.code; // don't care
277 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
278 if (allregs_p[i] != allregs_o[i]) {
280 fwrite(&allregs_p[i], 1, 4, f);
281 allregs_o[i] = allregs_p[i];
284 if (old_io_addr != last_io_addr) {
286 fwrite(&byte, 1, 1, f);
287 fwrite(&last_io_addr, 1, 4, f);
288 old_io_addr = last_io_addr;
290 io_data = (void *)(psxM + (last_io_addr&0x1ffffc));
291 if (old_io_data != *io_data) {
293 fwrite(&byte, 1, 1, f);
294 fwrite(io_data, 1, 4, f);
295 old_io_data = *io_data;
298 fwrite(&byte, 1, 1, f);
301 if (psxRegs.cycle == 190230) {
302 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
303 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
310 static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
311 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
312 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
313 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
314 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
316 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
317 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
318 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
319 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
321 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
322 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
323 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
324 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
326 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
327 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
328 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
329 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
331 "PC", "code", "cycle", "interrupt",
339 static int miss_log_i;
340 #define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
341 #define miss_log_mask (miss_log_len-1)
343 static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
345 miss_log[miss_log_i].reg = reg;
346 miss_log[miss_log_i].val = val;
347 miss_log[miss_log_i].val_expect = val_expect;
348 miss_log[miss_log_i].pc = pc;
349 miss_log[miss_log_i].cycle = cycle;
350 miss_log_i = (miss_log_i + 1) & miss_log_mask;
355 void do_insn_cmp(void)
357 static psxRegisters rregs;
358 static u32 mem_addr, mem_val;
359 u32 *allregs_p = (void *)&psxRegs;
360 u32 *allregs_e = (void *)&rregs;
361 static u32 ppc, failcount;
366 f = fopen("tracelog", "rb");
369 if ((ret = fread(&code, 1, 1, f)) <= 0)
376 if ((ret = fread(&mem_addr, 1, 4, f)) <= 0)
381 if ((ret = fread(&mem_val, 1, 4, f)) <= 0)
385 if ((ret = fread(&allregs_e[code], 1, 4, f)) <= 0)
394 psxRegs.code = rregs.code; // don't care
395 psxRegs.cycle = rregs.cycle;
396 psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
398 //if (psxRegs.cycle == 166172) breakme();
399 //if (psxRegs.cycle > 11296376) printf("pc=%08x %u %08x\n", psxRegs.pc, psxRegs.cycle, psxRegs.interrupt);
401 mem_addr &= 0x1ffffc;
403 if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
404 mem_val == *(u32 *)(psxM + mem_addr)
410 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
411 if (allregs_p[i] != allregs_e[i]) {
412 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
417 if (mem_val != *(u32 *)(psxM + mem_addr)) {
418 printf("bad mem @%08x: %08x %08x\n", mem_addr, *(u32 *)(psxM + mem_addr), mem_val);
422 if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
423 static int last_mcycle;
424 if (last_mcycle != psxRegs.cycle >> 20) {
425 printf("%u\n", psxRegs.cycle);
426 last_mcycle = psxRegs.cycle >> 20;
433 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
434 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
435 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
436 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
437 printf("-- %d\n", bad);
438 for (i = 0; i < 8; i++)
439 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
440 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+23]);
441 printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
442 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
443 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
446 psxRegs.cycle = rregs.cycle + 2; // sync timing