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