Added missing launcher
[mupen64plus-pandora.git] / source / front-end / src / compare_core.c
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
34 static FILE *fPipe = NULL;
35 static int comp_reg_32[32];
36 static long long comp_reg_64[32];
37 static unsigned int old_op = 0;
38 static int l_CoreCompareMode = CORE_COMPARE_DISABLE;
39
40 static long long *ptr_reg = NULL;  /* pointer to the 64-bit general purpose registers in the core */
41 static int       *ptr_cop0 = NULL; /* pointer to the 32-bit Co-processor 0 registers in the core */
42 static long long *ptr_fgr = NULL;  /* pointer to the 64-bit floating-point registers in the core */ 
43 static int       *ptr_PC = NULL;   /* pointer to 32-bit R4300 Program Counter */
44
45 /* local functions */
46 static 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
61 static 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
106 static 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
120 static 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 */
197 void 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