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