drc: fix cycle counting, make it use single var
[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
9//#define memprintf printf
10#define memprintf(...)
11//#define evprintf printf
12#define evprintf(...)
13
14//#define DRC_DBG
f95a77f7 15
16char invalid_code[0x100000];
17
7139f3c8 18void MTC0_()
f95a77f7 19{
7139f3c8 20 extern void psxMTC0();
21
22 printf("ari64 MTC0 %08x\n", psxRegs.code);
23 psxMTC0();
24 pending_exception = 1; /* FIXME? */
f95a77f7 25}
26
27void gen_interupt()
28{
7139f3c8 29 evprintf("ari64_gen_interupt\n");
822b27d1 30 evprintf(" +ge %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
7139f3c8 31#ifdef DRC_DBG
32 psxRegs.cycle += 2;
7139f3c8 33#endif
34
35 psxBranchTest();
36
822b27d1 37 next_interupt = psxNextsCounter + psxNextCounter;
38 evprintf(" -ge %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
7139f3c8 39
40 pending_exception = 1; /* FIXME */
f95a77f7 41}
42
43void check_interupt()
44{
7139f3c8 45 printf("ari64_check_interupt\n");
f95a77f7 46}
47
48void read_nomem_new()
49{
7139f3c8 50 printf("ari64_read_nomem_new\n");
51}
52
53static void read_mem8()
54{
55 memprintf("ari64_read_mem8 %08x, PC~=%08x\n", address, psxRegs.pc);
56 readmem_word = psxMemRead8(address) & 0xff;
57}
58
59static void read_mem16()
60{
61 memprintf("ari64_read_mem16 %08x, PC~=%08x\n", address, psxRegs.pc);
62 readmem_word = psxMemRead16(address) & 0xffff;
63}
64
65static void read_mem32()
66{
67 memprintf("ari64_read_mem32 %08x, PC~=%08x\n", address, psxRegs.pc);
68 readmem_word = psxMemRead32(address);
69}
70
71static void write_mem8()
72{
73 memprintf("ari64_write_mem8 %08x, %02x, PC~=%08x\n", address, byte, psxRegs.pc);
74 psxMemWrite8(address, byte);
f95a77f7 75}
76
7139f3c8 77static void write_mem16()
f95a77f7 78{
7139f3c8 79 memprintf("ari64_write_mem16 %08x, %04x, PC~=%08x\n", address, hword, psxRegs.pc);
80 psxMemWrite16(address, hword);
f95a77f7 81}
82
7139f3c8 83static void write_mem32()
f95a77f7 84{
7139f3c8 85 memprintf("ari64_write_mem32 %08x, %08x, PC~=%08x\n", address, word, psxRegs.pc);
86 psxMemWrite32(address, word);
f95a77f7 87}
88
89void (*readmem[0x10000])();
90void (*readmemb[0x10000])();
91void (*readmemh[0x10000])();
92void (*writemem[0x10000])();
93void (*writememb[0x10000])();
94void (*writememh[0x10000])();
95
96
97static int ari64_init()
98{
99 size_t i;
100 new_dynarec_init();
101
102 for (i = 0; i < sizeof(readmem) / sizeof(readmem[0]); i++) {
7139f3c8 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;
f95a77f7 109 }
7139f3c8 110
111 psxHLEt_addr = (void *)psxHLEt;
f95a77f7 112}
113
114static void ari64_reset()
115{
116 /* hmh */
117 printf("ari64_reset\n");
118}
119
120static void ari64_execute()
121{
822b27d1 122 next_interupt = psxNextsCounter + psxNextCounter;
7139f3c8 123
822b27d1 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);
f95a77f7 126 new_dyna_start(psxRegs.pc);
822b27d1 127 evprintf("ari64_execute end %08x, %d->%d\n", psxRegs.pc, psxRegs.cycle, next_interupt);
f95a77f7 128}
129
130static void ari64_clear(u32 Addr, u32 Size)
131{
132}
133
134static void ari64_shutdown()
135{
136 new_dynarec_cleanup();
137}
138
7139f3c8 139extern void intExecute();
140extern void intExecuteT();
141extern void intExecuteBlock();
142extern void intExecuteBlockT();
143#ifndef DRC_DBG
144#define intExecuteT intExecute
145#define intExecuteBlockT intExecuteBlock
146#endif
147
f95a77f7 148R3000Acpu psxRec = {
149 ari64_init,
150 ari64_reset,
7139f3c8 151#if 1
f95a77f7 152 ari64_execute,
7139f3c8 153 ari64_execute,
154#else
155 intExecuteT,
156 intExecuteBlockT,
157#endif
f95a77f7 158 ari64_clear,
159 ari64_shutdown
160};
7139f3c8 161
162// TODO: rm
163#ifndef DRC_DBG
164void do_insn_trace() {}
165void do_insn_cmp() {}
166#endif
167
168#if defined(__x86_64__) || defined(__i386__)
169unsigned int address, readmem_word, word;
170unsigned short hword;
171unsigned char byte;
172int pending_exception;
173unsigned int next_interupt;
174void *psxHLEt_addr;
175void new_dynarec_init() {}
176int new_dyna_start() {}
177void new_dynarec_cleanup() {}
178#endif
179
180#ifdef DRC_DBG
181
182#include <stddef.h>
183static FILE *f;
184extern u32 last_io_addr;
185
186static 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
193void 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
242static 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
266void breakme() {}
267
268void 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
308psxRegs.cycle = rregs.cycle;
309psxRegs.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
342end:
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);
347ok:
348 psxRegs.cycle = rregs.cycle + 2; // sync timing
349 ppc = psxRegs.pc;
350}
351
352#endif