2560eb3aca60bacfeb018eaca93bbb8b4989fa44
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / emu_if.c
1 // pending_exception?
2 // swi 0 in do_unalignedwritestub?
3 #include <stdio.h>
4
5 #include "emu_if.h"
6 #include "../psxmem.h"
7 #include "../psxhle.h"
8
9 //#define memprintf printf
10 #define memprintf(...)
11 //#define evprintf printf
12 #define evprintf(...)
13
14 char invalid_code[0x100000];
15
16 void MTC0_()
17 {
18         extern void psxMTC0();
19
20         memprintf("ari64 MTC0 %08x\n", psxRegs.code);
21         psxMTC0();
22         pending_exception = 1; /* FIXME? */
23 }
24
25 void gen_interupt()
26 {
27         evprintf("ari64_gen_interupt\n");
28         evprintf("  +ge %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
29 #ifdef DRC_DBG
30         psxRegs.cycle += 2;
31 #endif
32
33         psxBranchTest();
34
35         next_interupt = psxNextsCounter + psxNextCounter;
36         evprintf("  -ge %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
37
38         pending_exception = 1; /* FIXME */
39 }
40
41 void check_interupt()
42 {
43         printf("ari64_check_interupt\n");
44 }
45
46 void read_nomem_new()
47 {
48         printf("ari64_read_nomem_new\n");
49 }
50
51 static void read_mem8()
52 {
53         memprintf("ari64_read_mem8  %08x, PC~=%08x\n", address, psxRegs.pc);
54         readmem_word = psxMemRead8(address) & 0xff;
55 }
56
57 static void read_mem16()
58 {
59         memprintf("ari64_read_mem16 %08x, PC~=%08x\n", address, psxRegs.pc);
60         readmem_word = psxMemRead16(address) & 0xffff;
61 }
62
63 static void read_mem32()
64 {
65         memprintf("ari64_read_mem32 %08x, PC~=%08x\n", address, psxRegs.pc);
66         readmem_word = psxMemRead32(address);
67 }
68
69 static void write_mem8()
70 {
71         memprintf("ari64_write_mem8  %08x,       %02x, PC~=%08x\n", address, byte, psxRegs.pc);
72         psxMemWrite8(address, byte);
73 }
74
75 static void write_mem16()
76 {
77         memprintf("ari64_write_mem16 %08x,     %04x, PC~=%08x\n", address, hword, psxRegs.pc);
78         psxMemWrite16(address, hword);
79 }
80
81 static void write_mem32()
82 {
83         memprintf("ari64_write_mem32 %08x, %08x, PC~=%08x\n", address, word, psxRegs.pc);
84         psxMemWrite32(address, word);
85 }
86
87 void (*readmem[0x10000])();
88 void (*readmemb[0x10000])();
89 void (*readmemh[0x10000])();
90 void (*writemem[0x10000])();
91 void (*writememb[0x10000])();
92 void (*writememh[0x10000])();
93
94 void *gte_handlers[64];
95
96 /* from gte.txt.. not sure if this is any good. */
97 const char gte_cycletab[64] = {
98         /*   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f */
99          0, 15,  0,  0,  0,  0,  8,  0,  0,  0,  0,  0,  6,  0,  0,  0,
100          8,  8,  8, 19, 13,  0, 44,  0,  0,  0,  0, 17, 11,  0, 14,  0,
101         30,  0,  0,  0,  0,  0,  0,  0,  5,  8, 17,  0,  0,  5,  6,  0,
102         23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  5, 39,
103 };
104
105 static int ari64_init()
106 {
107         extern void (*psxCP2[64])();
108         extern void psxNULL();
109         size_t i;
110
111         new_dynarec_init();
112
113         for (i = 0; i < sizeof(readmem) / sizeof(readmem[0]); i++) {
114                 readmemb[i] = read_mem8;
115                 readmemh[i] = read_mem16;
116                 readmem[i] = read_mem32;
117                 writememb[i] = write_mem8;
118                 writememh[i] = write_mem16;
119                 writemem[i] = write_mem32;
120         }
121
122         for (i = 0; i < sizeof(gte_handlers) / sizeof(gte_handlers[0]); i++)
123                 if (psxCP2[i] != psxNULL)
124                         gte_handlers[i] = psxCP2[i];
125
126         return 0;
127 }
128
129 static void ari64_reset()
130 {
131         /* hmh */
132         printf("ari64_reset\n");
133 }
134
135 static void ari64_execute()
136 {
137         next_interupt = psxNextsCounter + psxNextCounter;
138
139         evprintf("psxNextsCounter %d, psxNextCounter %d\n", psxNextsCounter, psxNextCounter);
140         evprintf("ari64_execute %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
141         new_dyna_start();
142         evprintf("ari64_execute end %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
143 }
144
145 static void ari64_clear(u32 Addr, u32 Size)
146 {
147 }
148
149 static void ari64_shutdown()
150 {
151         new_dynarec_cleanup();
152 }
153
154 extern void intExecute();
155 extern void intExecuteT();
156 extern void intExecuteBlock();
157 extern void intExecuteBlockT();
158 #ifndef DRC_DBG
159 #define intExecuteT intExecute
160 #define intExecuteBlockT intExecuteBlock
161 #endif
162
163 R3000Acpu psxRec = {
164         ari64_init,
165         ari64_reset,
166 #if 1
167         ari64_execute,
168         ari64_execute,
169 #else
170         intExecuteT,
171         intExecuteBlockT,
172 #endif
173         ari64_clear,
174         ari64_shutdown
175 };
176
177 // TODO: rm
178 #ifndef DRC_DBG
179 void do_insn_trace() {}
180 void do_insn_cmp() {}
181 #endif
182
183 #if defined(__x86_64__) || defined(__i386__)
184 unsigned int address, readmem_word, word;
185 unsigned short hword;
186 unsigned char byte;
187 int pending_exception;
188 unsigned int next_interupt;
189 void new_dynarec_init() {}
190 void new_dyna_start() {}
191 void new_dynarec_cleanup() {}
192 #endif
193
194 #ifdef DRC_DBG
195
196 #include <stddef.h>
197 static FILE *f;
198 extern u32 last_io_addr;
199
200 static void dump_mem(const char *fname, void *mem, size_t size)
201 {
202         FILE *f1 = fopen(fname, "wb");
203         if (f1 == NULL)
204                 f1 = fopen(strrchr(fname, '/') + 1, "wb");
205         fwrite(mem, 1, size, f1);
206         fclose(f1);
207 }
208
209 void do_insn_trace(void)
210 {
211         static psxRegisters oldregs;
212         static u32 old_io_addr = (u32)-1;
213         static u32 old_io_data = 0xbad0c0de;
214         u32 *allregs_p = (void *)&psxRegs;
215         u32 *allregs_o = (void *)&oldregs;
216         u32 *io_data;
217         int i;
218         u8 byte;
219
220 //last_io_addr = 0x5e2c8;
221         if (f == NULL)
222                 f = fopen("tracelog", "wb");
223
224         oldregs.code = psxRegs.code; // don't care
225         for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
226                 if (allregs_p[i] != allregs_o[i]) {
227                         fwrite(&i, 1, 1, f);
228                         fwrite(&allregs_p[i], 1, 4, f);
229                         allregs_o[i] = allregs_p[i];
230                 }
231         }
232         if (old_io_addr != last_io_addr) {
233                 byte = 0xfd;
234                 fwrite(&byte, 1, 1, f);
235                 fwrite(&last_io_addr, 1, 4, f);
236                 old_io_addr = last_io_addr;
237         }
238         io_data = (void *)(psxM + (last_io_addr&0x1ffffc));
239         if (old_io_data != *io_data) {
240                 byte = 0xfe;
241                 fwrite(&byte, 1, 1, f);
242                 fwrite(io_data, 1, 4, f);
243                 old_io_data = *io_data;
244         }
245         byte = 0xff;
246         fwrite(&byte, 1, 1, f);
247
248 #if 0
249         if (psxRegs.cycle == 190230) {
250                 dump_mem("/mnt/ntz/dev/pnd/tmp/psxram_i.dump", psxM, 0x200000);
251                 dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs_i.dump", psxH, 0x10000);
252                 printf("dumped\n");
253                 exit(1);
254         }
255 #endif
256 }
257
258 static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
259         "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
260         "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
261         "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
262         "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
263         "lo",  "hi",
264         "C0_0",  "C0_1",  "C0_2",  "C0_3",  "C0_4",  "C0_5",  "C0_6",  "C0_7",
265         "C0_8",  "C0_9",  "C0_10", "C0_11", "C0_12", "C0_13", "C0_14", "C0_15",
266         "C0_16", "C0_17", "C0_18", "C0_19", "C0_20", "C0_21", "C0_22", "C0_23",
267         "C0_24", "C0_25", "C0_26", "C0_27", "C0_28", "C0_29", "C0_30", "C0_31",
268
269         "C2D0",  "C2D1",  "C2D2",  "C2D3",  "C2D4",  "C2D5",  "C2D6",  "C2D7",
270         "C2D8",  "C2D9",  "C2D10", "C2D11", "C2D12", "C2D13", "C2D14", "C2D15",
271         "C2D16", "C2D17", "C2D18", "C2D19", "C2D20", "C2D21", "C2D22", "C2D23",
272         "C2D24", "C2D25", "C2D26", "C2D27", "C2D28", "C2D29", "C2D30", "C2D31",
273
274         "C2C0",  "C2C1",  "C2C2",  "C2C3",  "C2C4",  "C2C5",  "C2C6",  "C2C7",
275         "C2C8",  "C2C9",  "C2C10", "C2C11", "C2C12", "C2C13", "C2C14", "C2C15",
276         "C2C16", "C2C17", "C2C18", "C2C19", "C2C20", "C2C21", "C2C22", "C2C23",
277         "C2C24", "C2C25", "C2C26", "C2C27", "C2C28", "C2C29", "C2C30", "C2C31",
278
279         "PC", "code", "cycle", "interrupt",
280 };
281
282 static struct {
283         int reg;
284         u32 val, val_expect;
285         u32 pc, cycle;
286 } miss_log[64];
287 static int miss_log_i;
288 #define miss_log_len (sizeof(miss_log)/sizeof(miss_log[0]))
289 #define miss_log_mask (miss_log_len-1)
290
291 static void miss_log_add(int reg, u32 val, u32 val_expect, u32 pc, u32 cycle)
292 {
293         miss_log[miss_log_i].reg = reg;
294         miss_log[miss_log_i].val = val;
295         miss_log[miss_log_i].val_expect = val_expect;
296         miss_log[miss_log_i].pc = pc;
297         miss_log[miss_log_i].cycle = cycle;
298         miss_log_i = (miss_log_i + 1) & miss_log_mask;
299 }
300
301 void breakme() {}
302
303 void do_insn_cmp(void)
304 {
305         static psxRegisters rregs;
306         static u32 mem_addr, mem_val;
307         u32 *allregs_p = (void *)&psxRegs;
308         u32 *allregs_e = (void *)&rregs;
309         static u32 ppc, failcount;
310         int i, ret, bad = 0;
311         u8 code;
312
313         if (f == NULL)
314                 f = fopen("tracelog", "rb");
315
316         while (1) {
317                 if ((ret = fread(&code, 1, 1, f)) <= 0)
318                         break;
319                 if (ret <= 0)
320                         break;
321                 if (code == 0xff)
322                         break;
323                 if (code == 0xfd) {
324                         if ((ret = fread(&mem_addr, 1, 4, f)) <= 0)
325                                 break;
326                         continue;
327                 }
328                 if (code == 0xfe) {
329                         if ((ret = fread(&mem_val, 1, 4, f)) <= 0)
330                                 break;
331                         continue;
332                 }
333                 if ((ret = fread(&allregs_e[code], 1, 4, f)) <= 0)
334                         break;
335         }
336
337         if (ret <= 0) {
338                 printf("EOF?\n");
339                 goto end;
340         }
341
342         psxRegs.code = rregs.code; // don't care
343 psxRegs.cycle = rregs.cycle;
344 psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count
345
346 //if (psxRegs.cycle == 166172) breakme();
347 //if (psxRegs.cycle > 11296376) printf("pc=%08x %u  %08x\n", psxRegs.pc, psxRegs.cycle, psxRegs.interrupt);
348
349         mem_addr &= 0x1ffffc;
350
351         if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 &&
352                         mem_val == *(u32 *)(psxM + mem_addr)
353            ) {
354                 failcount = 0;
355                 goto ok;
356         }
357
358         for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) {
359                 if (allregs_p[i] != allregs_e[i]) {
360                         miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle);
361                         bad++;
362                 }
363         }
364
365         if (mem_val != *(u32 *)(psxM + mem_addr)) {
366                 printf("bad mem @%08x: %08x %08x\n", mem_addr, *(u32 *)(psxM + mem_addr), mem_val);
367                 goto end;
368         }
369
370         if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) {
371                 static int last_mcycle;
372                 if (last_mcycle != psxRegs.cycle >> 20) {
373                         printf("%u\n", psxRegs.cycle);
374                         last_mcycle = psxRegs.cycle >> 20;
375                 }
376                 failcount++;
377                 goto ok;
378         }
379
380 end:
381         for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask)
382                 printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n",
383                         regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val,
384                         miss_log[miss_log_i].val_expect, miss_log[miss_log_i].pc, miss_log[miss_log_i].cycle);
385         printf("-- %d\n", bad);
386         for (i = 0; i < 8; i++)
387                 printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i],
388                         i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+23]);
389         printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle);
390         dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000);
391         dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000);
392         exit(1);
393 ok:
394         psxRegs.cycle = rregs.cycle + 2; // sync timing
395         ppc = psxRegs.pc;
396 }
397
398 #endif