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];
19 static void schedule_timeslice(void)
21 u32 i, c = psxRegs.cycle;
24 min = psxNextsCounter + psxNextCounter - c;
25 for (i = 0; i < ARRAY_SIZE(event_cycles); i++) {
26 dif = event_cycles[i] - c;
27 //evprintf(" ev %d\n", dif);
28 if (0 < dif && dif < min)
31 next_interupt = c + min;
34 static u32 cnt, last_cycle;
38 sum += psxRegs.cycle - last_cycle;
39 if ((cnt & 0xff) == 0)
40 printf("%u\n", (u32)(sum / cnt));
42 last_cycle = psxRegs.cycle;
48 evprintf(" +ge %08x, %u->%u\n", psxRegs.pc, psxRegs.cycle, next_interupt);
57 evprintf(" -ge %08x, %u->%u (%d)\n", psxRegs.pc, psxRegs.cycle,
58 next_interupt, next_interupt - psxRegs.cycle);
60 pending_exception = 1; /* FIXME */
65 extern void psxMTC0();
67 evprintf("ari64 MTC0 %08x %08x %u\n", psxRegs.code, psxRegs.pc, psxRegs.cycle);
69 gen_interupt(); /* FIXME: checking pending irqs should be enough */
74 printf("ari64_check_interupt\n");
79 printf("ari64_read_nomem_new\n");
82 static void read_mem8()
84 memprintf("ari64_read_mem8 %08x @%08x %u\n", address, psxRegs.pc, psxRegs.cycle);
85 readmem_word = psxMemRead8(address) & 0xff;
88 static void read_mem16()
90 memprintf("ari64_read_mem16 %08x @%08x %u\n", address, psxRegs.pc, psxRegs.cycle);
91 readmem_word = psxMemRead16(address) & 0xffff;
94 static void read_mem32()
96 memprintf("ari64_read_mem32 %08x @%08x %u\n", address, psxRegs.pc, psxRegs.cycle);
97 readmem_word = psxMemRead32(address);
100 static void write_mem8()
102 memprintf("ari64_write_mem8 %08x, %02x @%08x %u\n", address, byte, psxRegs.pc, psxRegs.cycle);
103 psxMemWrite8(address, byte);
106 static void write_mem16()
108 memprintf("ari64_write_mem16 %08x, %04x @%08x %u\n", address, hword, psxRegs.pc, psxRegs.cycle);
109 psxMemWrite16(address, hword);
112 static void write_mem32()
114 memprintf("ari64_write_mem32 %08x, %08x @%08x %u\n", address, word, psxRegs.pc, psxRegs.cycle);
115 psxMemWrite32(address, word);
118 void (*readmem[0x10000])();
119 void (*readmemb[0x10000])();
120 void (*readmemh[0x10000])();
121 void (*writemem[0x10000])();
122 void (*writememb[0x10000])();
123 void (*writememh[0x10000])();
125 void *gte_handlers[64];
127 /* from gte.txt.. not sure if this is any good. */
128 const char gte_cycletab[64] = {
129 /* 1 2 3 4 5 6 7 8 9 a b c d e f */
130 0, 15, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 6, 0, 0, 0,
131 8, 8, 8, 19, 13, 0, 44, 0, 0, 0, 0, 17, 11, 0, 14, 0,
132 30, 0, 0, 0, 0, 0, 0, 0, 5, 8, 17, 0, 0, 5, 6, 0,
133 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 39,
136 static int ari64_init()
138 extern void (*psxCP2[64])();
139 extern void psxNULL();
144 for (i = 0; i < ARRAY_SIZE(readmem); i++) {
145 readmemb[i] = read_mem8;
146 readmemh[i] = read_mem16;
147 readmem[i] = read_mem32;
148 writememb[i] = write_mem8;
149 writememh[i] = write_mem16;
150 writemem[i] = write_mem32;
153 for (i = 0; i < ARRAY_SIZE(gte_handlers); i++)
154 if (psxCP2[i] != psxNULL)
155 gte_handlers[i] = psxCP2[i];
160 static void ari64_reset()
162 printf("ari64_reset\n");
163 invalidate_all_pages();
164 pending_exception = 1;
167 static void ari64_execute()
169 schedule_timeslice();
171 evprintf("ari64_execute %08x, %u->%u (%d)\n", psxRegs.pc,
172 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
176 evprintf("ari64_execute end %08x, %u->%u (%d)\n", psxRegs.pc,
177 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
180 static void ari64_clear(u32 addr, u32 size)
184 evprintf("ari64_clear %08x %04x\n", addr, size);
186 /* check for RAM mirrors */
187 if ((addr & ~0xe0600000) < 0x200000) {
193 end = (addr + size) >> 12;
195 for (; start <= end; start++)
196 if (!invalid_code[start])
197 invalidate_block(start);
200 static void ari64_shutdown()
202 new_dynarec_cleanup();
205 extern void intExecute();
206 extern void intExecuteT();
207 extern void intExecuteBlock();
208 extern void intExecuteBlockT();
210 #define intExecuteT intExecute
211 #define intExecuteBlockT intExecuteBlock
230 void do_insn_trace() {}
231 void do_insn_cmp() {}
234 #if defined(__x86_64__) || defined(__i386__)
235 unsigned int address, readmem_word, word;
236 unsigned short hword;
238 int pending_exception, stop;
239 unsigned int next_interupt;
240 void new_dynarec_init() {}
241 void new_dyna_start() {}
242 void new_dynarec_cleanup() {}
243 void invalidate_all_pages() {}
244 void invalidate_block(unsigned int block) {}
251 extern u32 last_io_addr;
253 static void dump_mem(const char *fname, void *mem, size_t size)
255 FILE *f1 = fopen(fname, "wb");
257 f1 = fopen(strrchr(fname, '/') + 1, "wb");
258 fwrite(mem, 1, size, f1);
262 void do_insn_trace(void)
264 static psxRegisters oldregs;
265 static u32 old_io_addr = (u32)-1;
266 static u32 old_io_data = 0xbad0c0de;
267 u32 *allregs_p = (void *)&psxRegs;
268 u32 *allregs_o = (void *)&oldregs;
273 //last_io_addr = 0x5e2c8;
275 f = fopen("tracelog", "wb");
277 oldregs.code = psxRegs.code; // don't care
278 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
279 if (allregs_p[i] != allregs_o[i]) {
281 fwrite(&allregs_p[i], 1, 4, f);
282 allregs_o[i] = allregs_p[i];
285 if (old_io_addr != last_io_addr) {
287 fwrite(&byte, 1, 1, f);
288 fwrite(&last_io_addr, 1, 4, f);
289 old_io_addr = last_io_addr;
291 io_data = (void *)(psxM + (last_io_addr&0x1ffffc));
292 if (old_io_data != *io_data) {
294 fwrite(&byte, 1, 1, f);
295 fwrite(io_data, 1, 4, f);
296 old_io_data = *io_data;
299 fwrite(&byte, 1, 1, f);
302 if (psxRegs.cycle == 190230) {
303 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
304 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
311 static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
312 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
313 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
314 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
315 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
317 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
318 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
319 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
320 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
322 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
323 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
324 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
325 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
327 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
328 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
329 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
330 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
332 "PC", "code", "cycle", "interrupt",
340 static int miss_log_i;
341 #define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
342 #define miss_log_mask (miss_log_len-1)
344 static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
346 miss_log[miss_log_i].reg = reg;
347 miss_log[miss_log_i].val = val;
348 miss_log[miss_log_i].val_expect = val_expect;
349 miss_log[miss_log_i].pc = pc;
350 miss_log[miss_log_i].cycle = cycle;
351 miss_log_i = (miss_log_i + 1) & miss_log_mask;
356 void do_insn_cmp(void)
358 static psxRegisters rregs;
359 static u32 mem_addr, mem_val;
360 u32 *allregs_p = (void *)&psxRegs;
361 u32 *allregs_e = (void *)&rregs;
362 static u32 ppc, failcount;
367 f = fopen("tracelog", "rb");
370 if ((ret = fread(&code, 1, 1, f)) <= 0)
377 if ((ret = fread(&mem_addr, 1, 4, f)) <= 0)
382 if ((ret = fread(&mem_val, 1, 4, f)) <= 0)
386 if ((ret = fread(&allregs_e[code], 1, 4, f)) <= 0)
395 psxRegs.code = rregs.code; // don't care
396 psxRegs.cycle = rregs.cycle;
397 psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
399 //if (psxRegs.cycle == 166172) breakme();
400 //if (psxRegs.cycle > 11296376) printf("pc=%08x %u %08x\n", psxRegs.pc, psxRegs.cycle, psxRegs.interrupt);
402 mem_addr &= 0x1ffffc;
404 if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
405 mem_val == *(u32 *)(psxM + mem_addr)
411 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
412 if (allregs_p[i] != allregs_e[i]) {
413 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
418 if (mem_val != *(u32 *)(psxM + mem_addr)) {
419 printf("bad mem @%08x: %08x %08x\n", mem_addr, *(u32 *)(psxM + mem_addr), mem_val);
423 if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
424 static int last_mcycle;
425 if (last_mcycle != psxRegs.cycle >> 20) {
426 printf("%u\n", psxRegs.cycle);
427 last_mcycle = psxRegs.cycle >> 20;
434 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
435 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
436 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
437 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
438 printf("-- %d\n", bad);
439 for (i = 0; i < 8; i++)
440 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
441 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+23]);
442 printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
443 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
444 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
447 psxRegs.cycle = rregs.cycle + 2; // sync timing