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