drc: fix unsaved register
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / emu_if.c
CommitLineData
7139f3c8 1// cycles after syscall/hle?
2// pending_exception?
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");
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 */
f95a77f7 48}
49
50void check_interupt()
51{
7139f3c8 52 printf("ari64_check_interupt\n");
f95a77f7 53}
54
55void read_nomem_new()
56{
7139f3c8 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);
f95a77f7 82}
83
7139f3c8 84static void write_mem16()
f95a77f7 85{
7139f3c8 86 memprintf("ari64_write_mem16 %08x, %04x, PC~=%08x\n", address, hword, psxRegs.pc);
87 psxMemWrite16(address, hword);
f95a77f7 88}
89
7139f3c8 90static void write_mem32()
f95a77f7 91{
7139f3c8 92 memprintf("ari64_write_mem32 %08x, %08x, PC~=%08x\n", address, word, psxRegs.pc);
93 psxMemWrite32(address, word);
f95a77f7 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++) {
7139f3c8 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;
f95a77f7 116 }
7139f3c8 117
118 psxHLEt_addr = (void *)psxHLEt;
f95a77f7 119}
120
121static void ari64_reset()
122{
123 /* hmh */
124 printf("ari64_reset\n");
125}
126
127static void ari64_execute()
128{
7139f3c8 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);
f95a77f7 135 new_dyna_start(psxRegs.pc);
7139f3c8 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
f95a77f7 141}
142
143static void ari64_clear(u32 Addr, u32 Size)
144{
145}
146
147static void ari64_shutdown()
148{
149 new_dynarec_cleanup();
150}
151
7139f3c8 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
f95a77f7 161R3000Acpu psxRec = {
162 ari64_init,
163 ari64_reset,
7139f3c8 164#if 1
f95a77f7 165 ari64_execute,
7139f3c8 166 ari64_execute,
167#else
168 intExecuteT,
169 intExecuteBlockT,
170#endif
f95a77f7 171 ari64_clear,
172 ari64_shutdown
173};
7139f3c8 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