Added missing launcher
[mupen64plus-pandora.git] / source / front-end / src / compare_core.c
CommitLineData
5288f542 1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - compare_core.h *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2009 Richard Goedeken *
5 * Copyright (C) 2002 Hacktarux *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
21 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
22
23#include <stdio.h>
24#include <string.h>
25#include <sys/stat.h>
26
27#include "m64p_types.h"
28#include "main.h"
29#include "compare_core.h"
30#include "core_interface.h"
31
32/* local variables */
33
34static FILE *fPipe = NULL;
35static int comp_reg_32[32];
36static long long comp_reg_64[32];
37static unsigned int old_op = 0;
38static int l_CoreCompareMode = CORE_COMPARE_DISABLE;
39
40static long long *ptr_reg = NULL; /* pointer to the 64-bit general purpose registers in the core */
41static int *ptr_cop0 = NULL; /* pointer to the 32-bit Co-processor 0 registers in the core */
42static long long *ptr_fgr = NULL; /* pointer to the 64-bit floating-point registers in the core */
43static int *ptr_PC = NULL; /* pointer to 32-bit R4300 Program Counter */
44
45/* local functions */
46static void stop_it(void)
47{
48 static int errors = 0;
49
50 (*CoreDoCommand)(M64CMD_STOP, 0, NULL);
51
52 errors++;
53#if !defined(WIN32)
54 #if defined(__i386__) || defined(__x86_64__)
55 if (errors > 7)
56 asm("int $3;");
57 #endif
58#endif
59}
60
61static void display_error(char *txt)
62{
63 int i;
64
65 printf("err: %6s addr:%x\t ", txt, *ptr_PC);
66
67 if (!strcmp(txt, "PC"))
68 {
69 printf("My PC: %x Ref PC: %x\t ", *ptr_PC, *comp_reg_32);
70 }
71 else if (!strcmp(txt, "gpr"))
72 {
73 for (i=0; i<32; i++)
74 {
75 if (ptr_reg[i] != comp_reg_64[i])
76 printf("My: reg[%d]=%llx\t Ref: reg[%d]=%llx\t ", i, ptr_reg[i], i, comp_reg_64[i]);
77 }
78 }
79 else if (!strcmp(txt, "cop0"))
80 {
81 for (i=0; i<32; i++)
82 {
83 if (ptr_cop0[i] != comp_reg_32[i])
84 printf("My: reg_cop0[%d]=%x\t Ref: reg_cop0[%d]=%x\t ", i, (unsigned int)ptr_cop0[i], i, (unsigned int)comp_reg_32[i]);
85 }
86 }
87 else if (!strcmp(txt, "cop1"))
88 {
89 for (i=0; i<32; i++)
90 {
91 if (ptr_fgr[i] != comp_reg_64[i])
92 printf("My: reg[%d]=%llx\t Ref: reg[%d]=%llx\t ", i, ptr_fgr[i], i, comp_reg_64[i]);
93 }
94 }
95 printf("\n");
96 /*for (i=0; i<32; i++)
97 {
98 if (reg_cop0[i] != comp_reg[i])
99 printf("reg_cop0[%d]=%llx != reg[%d]=%llx\n",
100 i, reg_cop0[i], i, comp_reg[i]);
101 }*/
102
103 stop_it();
104}
105
106static void compare_core_sync_data(int length, void *value)
107{
108 if (l_CoreCompareMode == CORE_COMPARE_RECV)
109 {
110 if (fread(value, 1, length, fPipe) != length)
111 stop_it();
112 }
113 else if (l_CoreCompareMode == CORE_COMPARE_SEND)
114 {
115 if (fwrite(value, 1, length, fPipe) != length)
116 stop_it();
117 }
118}
119
120static void compare_core_check(unsigned int cur_opcode)
121{
122 static int comparecnt = 0;
123 int iFirst = 1;
124 char errHead[128];
125 sprintf(errHead, "Compare #%i old_op: %x op: %x\n", comparecnt++, old_op, cur_opcode);
126
127 /* get pointer to current R4300 Program Counter address */
128 ptr_PC = (int *) DebugGetCPUDataPtr(M64P_CPU_PC); /* this changes for every instruction */
129
130 if (l_CoreCompareMode == CORE_COMPARE_RECV)
131 {
132 if (fread(comp_reg_32, sizeof(int), 4, fPipe) != 4)
133 printf("compare_core_check: fread() failed");
134 if (*ptr_PC != *comp_reg_32)
135 {
136 if (iFirst)
137 {
138 printf("%s", errHead);
139 iFirst = 0;
140 }
141 display_error("PC");
142 }
143 if (fread (comp_reg_64, sizeof(long long int), 32, fPipe) != 32)
144 printf("compare_core_check: fread() failed");
145 if (memcmp(ptr_reg, comp_reg_64, 32*sizeof(long long int)) != 0)
146 {
147 if (iFirst)
148 {
149 printf("%s", errHead);
150 iFirst = 0;
151 }
152 display_error("gpr");
153 }
154 if (fread(comp_reg_32, sizeof(int), 32, fPipe) != 32)
155 printf("compare_core_check: fread() failed");
156 if (memcmp(ptr_cop0, comp_reg_32, 32*sizeof(int)) != 0)
157 {
158 if (iFirst)
159 {
160 printf("%s", errHead);
161 iFirst = 0;
162 }
163 display_error("cop0");
164 }
165 if (fread(comp_reg_64, sizeof(long long int), 32, fPipe) != 32)
166 printf("compare_core_check: fread() failed");
167 if (memcmp(ptr_fgr, comp_reg_64, 32*sizeof(long long int)))
168 {
169 if (iFirst)
170 {
171 printf("%s", errHead);
172 iFirst = 0;
173 }
174 display_error("cop1");
175 }
176 /*fread(comp_reg, 1, sizeof(int), f);
177 if (memcmp(&rdram[0x31280/4], comp_reg, sizeof(int)))
178 display_error("mem");*/
179 /*fread (comp_reg, 4, 1, f);
180 if (memcmp(&FCR31, comp_reg, 4))
181 display_error();*/
182 old_op = cur_opcode;
183 }
184 else if (l_CoreCompareMode == CORE_COMPARE_SEND)
185 {
186 if (fwrite(ptr_PC, sizeof(int), 4, fPipe) != 4 ||
187 fwrite(ptr_reg, sizeof(long long int), 32, fPipe) != 32 ||
188 fwrite(ptr_cop0, sizeof(int), 32, fPipe) != 32 ||
189 fwrite(ptr_fgr, sizeof(long long int), 32, fPipe) != 32)
190 printf("compare_core_check: fwrite() failed");
191 /*fwrite(&rdram[0x31280/4], 1, sizeof(int), f);
192 fwrite(&FCR31, 4, 1, f);*/
193 }
194}
195
196/* global functions */
197void compare_core_init(int mode)
198{
199#if defined(WIN32)
200 DebugMessage(M64MSG_VERBOSE, "core comparison feature not supported on Windows platform.");
201 return;
202#else
203 /* set mode */
204 l_CoreCompareMode = mode;
205 /* set callback functions in core */
206 if (DebugSetCoreCompare(compare_core_check, compare_core_sync_data) != M64ERR_SUCCESS)
207 {
208 l_CoreCompareMode = CORE_COMPARE_DISABLE;
209 DebugMessage(M64MSG_WARNING, "DebugSetCoreCompare() failed, core comparison disabled.");
210 return;
211 }
212 /* get pointers to emulated R4300 CPU registers */
213 ptr_reg = (long long *) DebugGetCPUDataPtr(M64P_CPU_REG_REG);
214 ptr_cop0 = (int *) DebugGetCPUDataPtr(M64P_CPU_REG_COP0);
215 ptr_fgr = (long long *) DebugGetCPUDataPtr(M64P_CPU_REG_COP1_FGR_64);
216 /* open file handle to FIFO pipe */
217 if (l_CoreCompareMode == CORE_COMPARE_RECV)
218 {
219 mkfifo("compare_pipe", 0600);
220 DebugMessage(M64MSG_INFO, "Core Comparison Waiting to read pipe.");
221 fPipe = fopen("compare_pipe", "r");
222 }
223 else if (l_CoreCompareMode == CORE_COMPARE_SEND)
224 {
225 DebugMessage(M64MSG_INFO, "Core Comparison Waiting to write pipe.");
226 fPipe = fopen("compare_pipe", "w");
227 }
228#endif
229}
230