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, stop;
240 unsigned int next_interupt;
241 void new_dynarec_init() {}
242 void new_dyna_start() {}
243 void new_dynarec_cleanup() {}
244 void invalidate_all_pages() {}
245 void invalidate_block(unsigned int block) {}
252 extern u32 last_io_addr;
254 static void dump_mem(const char *fname, void *mem, size_t size)
256 FILE *f1 = fopen(fname, "wb");
258 f1 = fopen(strrchr(fname, '/') + 1, "wb");
259 fwrite(mem, 1, size, f1);
263 void do_insn_trace(void)
265 static psxRegisters oldregs;
266 static u32 old_io_addr = (u32)-1;
267 static u32 old_io_data = 0xbad0c0de;
268 u32 *allregs_p = (void *)&psxRegs;
269 u32 *allregs_o = (void *)&oldregs;
274 //last_io_addr = 0x5e2c8;
276 f = fopen("tracelog", "wb");
278 oldregs.code = psxRegs.code; // don't care
279 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
280 if (allregs_p[i] != allregs_o[i]) {
282 fwrite(&allregs_p[i], 1, 4, f);
283 allregs_o[i] = allregs_p[i];
286 if (old_io_addr != last_io_addr) {
288 fwrite(&byte, 1, 1, f);
289 fwrite(&last_io_addr, 1, 4, f);
290 old_io_addr = last_io_addr;
292 io_data = (void *)(psxM + (last_io_addr&0x1ffffc));
293 if (old_io_data != *io_data) {
295 fwrite(&byte, 1, 1, f);
296 fwrite(io_data, 1, 4, f);
297 old_io_data = *io_data;
300 fwrite(&byte, 1, 1, f);
303 if (psxRegs.cycle == 190230) {
304 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
305 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
312 static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
313 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
314 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
315 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
316 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
318 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
319 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
320 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
321 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
323 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
324 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
325 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
326 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
328 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
329 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
330 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
331 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
333 "PC", "code", "cycle", "interrupt",
341 static int miss_log_i;
342 #define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
343 #define miss_log_mask (miss_log_len-1)
345 static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
347 miss_log[miss_log_i].reg = reg;
348 miss_log[miss_log_i].val = val;
349 miss_log[miss_log_i].val_expect = val_expect;
350 miss_log[miss_log_i].pc = pc;
351 miss_log[miss_log_i].cycle = cycle;
352 miss_log_i = (miss_log_i + 1) & miss_log_mask;
357 void do_insn_cmp(void)
359 static psxRegisters rregs;
360 static u32 mem_addr, mem_val;
361 u32 *allregs_p = (void *)&psxRegs;
362 u32 *allregs_e = (void *)&rregs;
363 static u32 ppc, failcount;
368 f = fopen("tracelog", "rb");
371 if ((ret = fread(&code, 1, 1, f)) <= 0)
378 if ((ret = fread(&mem_addr, 1, 4, f)) <= 0)
383 if ((ret = fread(&mem_val, 1, 4, f)) <= 0)
387 if ((ret = fread(&allregs_e[code], 1, 4, f)) <= 0)
396 psxRegs.code = rregs.code; // don't care
397 psxRegs.cycle = rregs.cycle;
398 psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
400 //if (psxRegs.cycle == 166172) breakme();
401 //if (psxRegs.cycle > 11296376) printf("pc=%08x %u %08x\n", psxRegs.pc, psxRegs.cycle, psxRegs.interrupt);
403 mem_addr &= 0x1ffffc;
405 if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
406 mem_val == *(u32 *)(psxM + mem_addr)
412 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
413 if (allregs_p[i] != allregs_e[i]) {
414 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
419 if (mem_val != *(u32 *)(psxM + mem_addr)) {
420 printf("bad mem @%08x: %08x %08x\n", mem_addr, *(u32 *)(psxM + mem_addr), mem_val);
424 if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
425 static int last_mcycle;
426 if (last_mcycle != psxRegs.cycle >> 20) {
427 printf("%u\n", psxRegs.cycle);
428 last_mcycle = psxRegs.cycle >> 20;
435 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
436 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
437 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
438 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
439 printf("-- %d\n", bad);
440 for (i = 0; i < 8; i++)
441 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
442 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+23]);
443 printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
444 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
445 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
448 psxRegs.cycle = rregs.cycle + 2; // sync timing