drc: fix cycle counting, make it use single var
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / emu_if.c
... / ...
CommitLineData
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
16char invalid_code[0x100000];
17
18void MTC0_()
19{
20 extern void psxMTC0();
21
22 printf("ari64 MTC0 %08x\n", psxRegs.code);
23 psxMTC0();
24 pending_exception = 1; /* FIXME? */
25}
26
27void 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
43void check_interupt()
44{
45 printf("ari64_check_interupt\n");
46}
47
48void read_nomem_new()
49{
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);
75}
76
77static void write_mem16()
78{
79 memprintf("ari64_write_mem16 %08x, %04x, PC~=%08x\n", address, hword, psxRegs.pc);
80 psxMemWrite16(address, hword);
81}
82
83static void write_mem32()
84{
85 memprintf("ari64_write_mem32 %08x, %08x, PC~=%08x\n", address, word, psxRegs.pc);
86 psxMemWrite32(address, word);
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++) {
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
114static void ari64_reset()
115{
116 /* hmh */
117 printf("ari64_reset\n");
118}
119
120static 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
130static void ari64_clear(u32 Addr, u32 Size)
131{
132}
133
134static void ari64_shutdown()
135{
136 new_dynarec_cleanup();
137}
138
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
148R3000Acpu 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
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