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