fix x86 build, minor refactoring
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / emu_if.c
CommitLineData
7139f3c8 1// pending_exception?
822b27d1 2// swi 0 in do_unalignedwritestub?
f95a77f7 3#include <stdio.h>
4
5#include "emu_if.h"
7139f3c8 6#include "../psxmem.h"
7#include "../psxhle.h"
8
ae602c19 9#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
10
7139f3c8 11//#define memprintf printf
12#define memprintf(...)
13//#define evprintf printf
14#define evprintf(...)
15
f95a77f7 16char invalid_code[0x100000];
ae602c19 17u32 event_cycles[6];
f95a77f7 18
7139f3c8 19void MTC0_()
f95a77f7 20{
7139f3c8 21 extern void psxMTC0();
22
b9b61529 23 memprintf("ari64 MTC0 %08x\n", psxRegs.code);
7139f3c8 24 psxMTC0();
25 pending_exception = 1; /* FIXME? */
f95a77f7 26}
27
654e8cfb 28static void schedule_timeslice(void)
f95a77f7 29{
654e8cfb 30 u32 i, c = psxRegs.cycle;
31 s32 min, dif;
32
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)
38 min = dif;
39 }
40 next_interupt = c + min;
41
42#if 0
43 static u32 cnt, last_cycle;
44 static u64 sum;
45 if (last_cycle) {
46 cnt++;
47 sum += psxRegs.cycle - last_cycle;
48 if ((cnt & 0xff) == 0)
49 printf("%u\n", (u32)(sum / cnt));
50 }
51 last_cycle = psxRegs.cycle;
52#endif
53}
ae602c19 54
654e8cfb 55void gen_interupt()
56{
57 //evprintf("ari64_gen_interupt\n");
58 evprintf(" +ge %08x, %u->%u\n", psxRegs.pc, psxRegs.cycle, next_interupt);
7139f3c8 59#ifdef DRC_DBG
60 psxRegs.cycle += 2;
7139f3c8 61#endif
62
63 psxBranchTest();
64
654e8cfb 65 schedule_timeslice();
ae602c19 66
654e8cfb 67 evprintf(" -ge %08x, %u->%u (%d)\n", psxRegs.pc, psxRegs.cycle,
68 next_interupt, next_interupt - psxRegs.cycle);
7139f3c8 69
70 pending_exception = 1; /* FIXME */
f95a77f7 71}
72
73void check_interupt()
74{
7139f3c8 75 printf("ari64_check_interupt\n");
f95a77f7 76}
77
78void read_nomem_new()
79{
7139f3c8 80 printf("ari64_read_nomem_new\n");
81}
82
83static void read_mem8()
84{
85 memprintf("ari64_read_mem8 %08x, PC~=%08x\n", address, psxRegs.pc);
86 readmem_word = psxMemRead8(address) & 0xff;
87}
88
89static void read_mem16()
90{
91 memprintf("ari64_read_mem16 %08x, PC~=%08x\n", address, psxRegs.pc);
92 readmem_word = psxMemRead16(address) & 0xffff;
93}
94
95static void read_mem32()
96{
97 memprintf("ari64_read_mem32 %08x, PC~=%08x\n", address, psxRegs.pc);
98 readmem_word = psxMemRead32(address);
99}
100
101static void write_mem8()
102{
103 memprintf("ari64_write_mem8 %08x, %02x, PC~=%08x\n", address, byte, psxRegs.pc);
104 psxMemWrite8(address, byte);
f95a77f7 105}
106
7139f3c8 107static void write_mem16()
f95a77f7 108{
7139f3c8 109 memprintf("ari64_write_mem16 %08x, %04x, PC~=%08x\n", address, hword, psxRegs.pc);
110 psxMemWrite16(address, hword);
f95a77f7 111}
112
7139f3c8 113static void write_mem32()
f95a77f7 114{
7139f3c8 115 memprintf("ari64_write_mem32 %08x, %08x, PC~=%08x\n", address, word, psxRegs.pc);
116 psxMemWrite32(address, word);
f95a77f7 117}
118
119void (*readmem[0x10000])();
120void (*readmemb[0x10000])();
121void (*readmemh[0x10000])();
122void (*writemem[0x10000])();
123void (*writememb[0x10000])();
124void (*writememh[0x10000])();
125
b9b61529 126void *gte_handlers[64];
127
128/* from gte.txt.. not sure if this is any good. */
129const 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,
135};
f95a77f7 136
137static int ari64_init()
138{
b9b61529 139 extern void (*psxCP2[64])();
140 extern void psxNULL();
f95a77f7 141 size_t i;
b9b61529 142
f95a77f7 143 new_dynarec_init();
144
ae602c19 145 for (i = 0; i < ARRAY_SIZE(readmem); i++) {
7139f3c8 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;
f95a77f7 152 }
7139f3c8 153
ae602c19 154 for (i = 0; i < ARRAY_SIZE(gte_handlers); i++)
b9b61529 155 if (psxCP2[i] != psxNULL)
156 gte_handlers[i] = psxCP2[i];
157
b9b61529 158 return 0;
f95a77f7 159}
160
161static void ari64_reset()
162{
f95a77f7 163 printf("ari64_reset\n");
4b421010 164 invalidate_all_pages();
165 pending_exception = 1;
f95a77f7 166}
167
168static void ari64_execute()
169{
654e8cfb 170 schedule_timeslice();
171
172 evprintf("ari64_execute %08x, %u->%u (%d)\n", psxRegs.pc,
173 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
7139f3c8 174
b9b61529 175 new_dyna_start();
654e8cfb 176
177 evprintf("ari64_execute end %08x, %u->%u (%d)\n", psxRegs.pc,
178 psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle);
f95a77f7 179}
180
4b421010 181static void ari64_clear(u32 addr, u32 size)
f95a77f7 182{
4b421010 183 u32 start, end;
184
185 evprintf("ari64_clear %08x %04x\n", addr, size);
186
187 /* check for RAM mirrors */
188 if ((start & ~0xe0000000) < 0x200000) {
189 start &= ~0xe0000000;
190 start |= 0x80000000;
191 }
192
193 start = addr >> 12;
194 end = (addr + size) >> 12;
195
196 for (; start <= end; start++)
197 if (!invalid_code[start])
198 invalidate_block(start);
f95a77f7 199}
200
201static void ari64_shutdown()
202{
203 new_dynarec_cleanup();
204}
205
7139f3c8 206extern void intExecute();
207extern void intExecuteT();
208extern void intExecuteBlock();
209extern void intExecuteBlockT();
210#ifndef DRC_DBG
211#define intExecuteT intExecute
212#define intExecuteBlockT intExecuteBlock
213#endif
214
f95a77f7 215R3000Acpu psxRec = {
216 ari64_init,
217 ari64_reset,
7139f3c8 218#if 1
f95a77f7 219 ari64_execute,
7139f3c8 220 ari64_execute,
221#else
222 intExecuteT,
223 intExecuteBlockT,
224#endif
f95a77f7 225 ari64_clear,
226 ari64_shutdown
227};
7139f3c8 228
229// TODO: rm
230#ifndef DRC_DBG
231void do_insn_trace() {}
232void do_insn_cmp() {}
233#endif
234
235#if defined(__x86_64__) || defined(__i386__)
236unsigned int address, readmem_word, word;
237unsigned short hword;
238unsigned char byte;
ccf51908 239int pending_exception, stop;
7139f3c8 240unsigned int next_interupt;
7139f3c8 241void new_dynarec_init() {}
3eb78778 242void new_dyna_start() {}
7139f3c8 243void new_dynarec_cleanup() {}
ccf51908 244void invalidate_all_pages() {}
245void invalidate_block(unsigned int block) {}
7139f3c8 246#endif
247
248#ifdef DRC_DBG
249
250#include <stddef.h>
251static FILE *f;
252extern u32 last_io_addr;
253
254static void dump_mem(const char *fname, void *mem, size_t size)
255{
256 FILE *f1 = fopen(fname, "wb");
3eb78778 257 if (f1 == NULL)
258 f1 = fopen(strrchr(fname, '/') + 1, "wb");
7139f3c8 259 fwrite(mem, 1, size, f1);
260 fclose(f1);
261}
262
263void do_insn_trace(void)
264{
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;
270 u32 *io_data;
271 int i;
272 u8 byte;
273
274//last_io_addr = 0x5e2c8;
275 if (f == NULL)
276 f = fopen("tracelog", "wb");
277
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]) {
281 fwrite(&i, 1, 1, f);
282 fwrite(&allregs_p[i], 1, 4, f);
283 allregs_o[i] = allregs_p[i];
284 }
285 }
286 if (old_io_addr != last_io_addr) {
287 byte = 0xfd;
288 fwrite(&byte, 1, 1, f);
289 fwrite(&last_io_addr, 1, 4, f);
290 old_io_addr = last_io_addr;
291 }
292 io_data = (void *)(psxM + (last_io_addr&0x1ffffc));
293 if (old_io_data != *io_data) {
294 byte = 0xfe;
295 fwrite(&byte, 1, 1, f);
296 fwrite(io_data, 1, 4, f);
297 old_io_data = *io_data;
298 }
299 byte = 0xff;
300 fwrite(&byte, 1, 1, f);
301
302#if 0
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);
306 printf("dumped\n");
307 exit(1);
308 }
309#endif
310}
311
312static 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",
317 "lo", "hi",
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",
322
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",
327
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",
332
333 "PC", "code", "cycle", "interrupt",
334};
335
3eb78778 336static struct {
337 int reg;
338 u32 val, val_expect;
339 u32 pc, cycle;
340} miss_log[64];
341static 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)
344
345static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
346{
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;
353}
354
7139f3c8 355void breakme() {}
356
357void do_insn_cmp(void)
358{
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;
364 int i, ret, bad = 0;
365 u8 code;
366
367 if (f == NULL)
368 f = fopen("tracelog", "rb");
369
370 while (1) {
371 if ((ret = fread(&code, 1, 1, f)) <= 0)
372 break;
373 if (ret <= 0)
374 break;
375 if (code == 0xff)
376 break;
377 if (code == 0xfd) {
378 if ((ret = fread(&mem_addr, 1, 4, f)) <= 0)
379 break;
380 continue;
381 }
382 if (code == 0xfe) {
383 if ((ret = fread(&mem_val, 1, 4, f)) <= 0)
384 break;
385 continue;
386 }
387 if ((ret = fread(&allregs_e[code], 1, 4, f)) <= 0)
388 break;
389 }
390
391 if (ret <= 0) {
392 printf("EOF?\n");
393 goto end;
394 }
395
396 psxRegs.code = rregs.code; // don't care
397psxRegs.cycle = rregs.cycle;
398psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
399
400//if (psxRegs.cycle == 166172) breakme();
401//if (psxRegs.cycle > 11296376) printf("pc=%08x %u %08x\n", psxRegs.pc, psxRegs.cycle, psxRegs.interrupt);
402
403 mem_addr &= 0x1ffffc;
404
405 if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
406 mem_val == *(u32 *)(psxM + mem_addr)
407 ) {
408 failcount = 0;
409 goto ok;
410 }
411
412 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
413 if (allregs_p[i] != allregs_e[i]) {
3eb78778 414 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
7139f3c8 415 bad++;
416 }
417 }
418
419 if (mem_val != *(u32 *)(psxM + mem_addr)) {
420 printf("bad mem @%08x: %08x %08x\n", mem_addr, *(u32 *)(psxM + mem_addr), mem_val);
421 goto end;
422 }
423
424 if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
3eb78778 425 static int last_mcycle;
426 if (last_mcycle != psxRegs.cycle >> 20) {
427 printf("%u\n", psxRegs.cycle);
428 last_mcycle = psxRegs.cycle >> 20;
429 }
7139f3c8 430 failcount++;
431 goto ok;
432 }
433
434end:
3eb78778 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]);
7139f3c8 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);
446 exit(1);
447ok:
448 psxRegs.cycle = rregs.cycle + 2; // sync timing
449 ppc = psxRegs.pc;
450}
451
452#endif