improve event handling again
[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{
163 /* hmh */
164 printf("ari64_reset\n");
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
180static void ari64_clear(u32 Addr, u32 Size)
181{
182}
183
184static void ari64_shutdown()
185{
186 new_dynarec_cleanup();
187}
188
7139f3c8 189extern void intExecute();
190extern void intExecuteT();
191extern void intExecuteBlock();
192extern void intExecuteBlockT();
193#ifndef DRC_DBG
194#define intExecuteT intExecute
195#define intExecuteBlockT intExecuteBlock
196#endif
197
f95a77f7 198R3000Acpu psxRec = {
199 ari64_init,
200 ari64_reset,
7139f3c8 201#if 1
f95a77f7 202 ari64_execute,
7139f3c8 203 ari64_execute,
204#else
205 intExecuteT,
206 intExecuteBlockT,
207#endif
f95a77f7 208 ari64_clear,
209 ari64_shutdown
210};
7139f3c8 211
212// TODO: rm
213#ifndef DRC_DBG
214void do_insn_trace() {}
215void do_insn_cmp() {}
216#endif
217
218#if defined(__x86_64__) || defined(__i386__)
219unsigned int address, readmem_word, word;
220unsigned short hword;
221unsigned char byte;
222int pending_exception;
223unsigned int next_interupt;
7139f3c8 224void new_dynarec_init() {}
3eb78778 225void new_dyna_start() {}
7139f3c8 226void new_dynarec_cleanup() {}
227#endif
228
229#ifdef DRC_DBG
230
231#include <stddef.h>
232static FILE *f;
233extern u32 last_io_addr;
234
235static void dump_mem(const char *fname, void *mem, size_t size)
236{
237 FILE *f1 = fopen(fname, "wb");
3eb78778 238 if (f1 == NULL)
239 f1 = fopen(strrchr(fname, '/') + 1, "wb");
7139f3c8 240 fwrite(mem, 1, size, f1);
241 fclose(f1);
242}
243
244void do_insn_trace(void)
245{
246 static psxRegisters oldregs;
247 static u32 old_io_addr = (u32)-1;
248 static u32 old_io_data = 0xbad0c0de;
249 u32 *allregs_p = (void *)&psxRegs;
250 u32 *allregs_o = (void *)&oldregs;
251 u32 *io_data;
252 int i;
253 u8 byte;
254
255//last_io_addr = 0x5e2c8;
256 if (f == NULL)
257 f = fopen("tracelog", "wb");
258
259 oldregs.code = psxRegs.code; // don't care
260 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
261 if (allregs_p[i] != allregs_o[i]) {
262 fwrite(&i, 1, 1, f);
263 fwrite(&allregs_p[i], 1, 4, f);
264 allregs_o[i] = allregs_p[i];
265 }
266 }
267 if (old_io_addr != last_io_addr) {
268 byte = 0xfd;
269 fwrite(&byte, 1, 1, f);
270 fwrite(&last_io_addr, 1, 4, f);
271 old_io_addr = last_io_addr;
272 }
273 io_data = (void *)(psxM + (last_io_addr&0x1ffffc));
274 if (old_io_data != *io_data) {
275 byte = 0xfe;
276 fwrite(&byte, 1, 1, f);
277 fwrite(io_data, 1, 4, f);
278 old_io_data = *io_data;
279 }
280 byte = 0xff;
281 fwrite(&byte, 1, 1, f);
282
283#if 0
284 if (psxRegs.cycle == 190230) {
285 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
286 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
287 printf("dumped\n");
288 exit(1);
289 }
290#endif
291}
292
293static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
294 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
295 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
296 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
297 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
298 "lo", "hi",
299 "C0_0", "C0_1", "C0_2", "C0_3", "C0_4", "C0_5", "C0_6", "C0_7",
300 "C0_8", "C0_9", "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
301 "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
302 "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
303
304 "C2D0", "C2D1", "C2D2", "C2D3", "C2D4", "C2D5", "C2D6", "C2D7",
305 "C2D8", "C2D9", "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
306 "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
307 "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
308
309 "C2C0", "C2C1", "C2C2", "C2C3", "C2C4", "C2C5", "C2C6", "C2C7",
310 "C2C8", "C2C9", "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
311 "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
312 "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
313
314 "PC", "code", "cycle", "interrupt",
315};
316
3eb78778 317static struct {
318 int reg;
319 u32 val, val_expect;
320 u32 pc, cycle;
321} miss_log[64];
322static int miss_log_i;
323#define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
324#define miss_log_mask (miss_log_len-1)
325
326static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
327{
328 miss_log[miss_log_i].reg = reg;
329 miss_log[miss_log_i].val = val;
330 miss_log[miss_log_i].val_expect = val_expect;
331 miss_log[miss_log_i].pc = pc;
332 miss_log[miss_log_i].cycle = cycle;
333 miss_log_i = (miss_log_i + 1) & miss_log_mask;
334}
335
7139f3c8 336void breakme() {}
337
338void do_insn_cmp(void)
339{
340 static psxRegisters rregs;
341 static u32 mem_addr, mem_val;
342 u32 *allregs_p = (void *)&psxRegs;
343 u32 *allregs_e = (void *)&rregs;
344 static u32 ppc, failcount;
345 int i, ret, bad = 0;
346 u8 code;
347
348 if (f == NULL)
349 f = fopen("tracelog", "rb");
350
351 while (1) {
352 if ((ret = fread(&code, 1, 1, f)) <= 0)
353 break;
354 if (ret <= 0)
355 break;
356 if (code == 0xff)
357 break;
358 if (code == 0xfd) {
359 if ((ret = fread(&mem_addr, 1, 4, f)) <= 0)
360 break;
361 continue;
362 }
363 if (code == 0xfe) {
364 if ((ret = fread(&mem_val, 1, 4, f)) <= 0)
365 break;
366 continue;
367 }
368 if ((ret = fread(&allregs_e[code], 1, 4, f)) <= 0)
369 break;
370 }
371
372 if (ret <= 0) {
373 printf("EOF?\n");
374 goto end;
375 }
376
377 psxRegs.code = rregs.code; // don't care
378psxRegs.cycle = rregs.cycle;
379psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
380
381//if (psxRegs.cycle == 166172) breakme();
382//if (psxRegs.cycle > 11296376) printf("pc=%08x %u %08x\n", psxRegs.pc, psxRegs.cycle, psxRegs.interrupt);
383
384 mem_addr &= 0x1ffffc;
385
386 if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
387 mem_val == *(u32 *)(psxM + mem_addr)
388 ) {
389 failcount = 0;
390 goto ok;
391 }
392
393 for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
394 if (allregs_p[i] != allregs_e[i]) {
3eb78778 395 miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
7139f3c8 396 bad++;
397 }
398 }
399
400 if (mem_val != *(u32 *)(psxM + mem_addr)) {
401 printf("bad mem @%08x: %08x %08x\n", mem_addr, *(u32 *)(psxM + mem_addr), mem_val);
402 goto end;
403 }
404
405 if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
3eb78778 406 static int last_mcycle;
407 if (last_mcycle != psxRegs.cycle >> 20) {
408 printf("%u\n", psxRegs.cycle);
409 last_mcycle = psxRegs.cycle >> 20;
410 }
7139f3c8 411 failcount++;
412 goto ok;
413 }
414
415end:
3eb78778 416 for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
417 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
418 regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
419 miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
420 printf("-- %d\n", bad);
421 for (i = 0; i < 8; i++)
422 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
423 i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+23]);
7139f3c8 424 printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
425 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
426 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
427 exit(1);
428ok:
429 psxRegs.cycle = rregs.cycle + 2; // sync timing
430 ppc = psxRegs.pc;
431}
432
433#endif