2 * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
4 * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and
5 * Jerremy Koot (jkoot@snes9x.com)
7 * Super FX C emulator code
8 * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and
10 * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
12 * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson.
13 * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_.
14 * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com).
16 * DOS port code contains the works of other authors. See headers in
19 * Snes9x homepage: http://www.snes9x.com
21 * Permission to use, copy, modify and distribute Snes9x in both binary and
22 * source form, for non-commercial purposes, is hereby granted without fee,
23 * providing that this license information and copyright notice appear with
24 * all copies and any derived work.
26 * This software is provided 'as-is', without any express or implied
27 * warranty. In no event shall the authors be held liable for any damages
28 * arising from the use of this software.
30 * Snes9x is freeware for PERSONAL USE only. Commercial users should
31 * seek permission of the copyright holders first. Commercial use includes
32 * charging money for Snes9x or software derived from Snes9x.
34 * The copyright holders request that bug fixes and improvements to the code
35 * should be forwarded to them so everyone can benefit from the modifications
38 * Super NES and Super Nintendo Entertainment System are trademarks of
39 * Nintendo Co., Limited and its subsidiary companies.
48 static bool8 S9xAllHex (const char *code, int len)
50 for (int i = 0; i < len; i++)
51 if ((code [i] < '0' || code [i] > '9') &&
52 (code [i] < 'a' || code [i] > 'f') &&
53 (code [i] < 'A' || code [i] > 'F'))
59 const char *S9xProActionReplayToRaw (const char *code, uint32 &address, uint8 &byte)
62 if (strlen (code) != 8 || !S9xAllHex (code, 8) ||
63 sscanf (code, "%x", &data) != 1)
64 return ("Invalid Pro Action Replay code - should be 8 hex digits in length.");
71 const char *S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram,
72 uint8 &num_bytes, uint8 bytes[3])
75 if (strlen (code) != 14)
76 return ("Invalid Gold Finger code should be 14 hex digits in length.");
78 strncpy (tmp, code, 5);
80 if (sscanf (tmp, "%x", &address) != 1)
81 return ("Invalid Gold Finger code.");
84 for (i = 0; i < 3; i++)
86 strncpy (tmp, code + 5 + i * 2, 2);
89 if (sscanf (tmp, "%x", &byte) != 1)
91 bytes [i] = (uint8) byte;
94 sram = code [13] == '1';
98 const char *S9xGameGenieToRaw (const char *code, uint32 &address, uint8 &byte)
102 if (strlen (code) != 9 || *(code + 4) != '-' || !S9xAllHex (code, 4) ||
103 !S9xAllHex (code + 5, 4))
104 return ("Invalid Game Genie(tm) code - should be 'xxxx-xxxx'.");
106 strcpy (new_code, "0x");
107 strncpy (new_code + 2, code, 4);
108 strcpy (new_code + 6, code + 5);
110 static const char *real_hex = "0123456789ABCDEF";
111 static const char *genie_hex = "DF4709156BC8A23E";
113 for (int i = 2; i < 10; i++)
115 if (islower (new_code [i]))
116 new_code [i] = toupper (new_code [i]);
118 for (j = 0; j < 16; j++)
120 if (new_code [i] == genie_hex [j])
122 new_code [i] = real_hex [j];
127 return ("Invalid hex-character in Game Genie(tm) code");
130 sscanf (new_code, "%x", &data);
131 byte = (uint8)(data >> 24);
132 address = data & 0xffffff;
133 address = ((address & 0x003c00) << 10) +
134 ((address & 0x00003c) << 14) +
135 ((address & 0xf00000) >> 8) +
136 ((address & 0x000003) << 10) +
137 ((address & 0x00c000) >> 6) +
138 ((address & 0x0f0000) >> 12) +
139 ((address & 0x0003c0) >> 6);
144 void S9xStartCheatSearch (SCheatData *d)
146 memmove (d->CWRAM, d->RAM, 0x20000);
147 memmove (d->CSRAM, d->SRAM, 0x10000);
148 memmove (d->CIRAM, &d->FillRAM [0x3000], 0x2000);
149 memset ((char *) d->WRAM_BITS, 0xff, 0x20000 >> 3);
150 memset ((char *) d->SRAM_BITS, 0xff, 0x10000 >> 3);
151 memset ((char *) d->IRAM_BITS, 0xff, 0x2000 >> 3);
154 #define BIT_CLEAR(a,v) \
155 (a)[(v) >> 5] &= ~(1 << ((v) & 31))
157 #define BIT_SET(a,v) \
158 (a)[(v) >> 5] |= 1 << ((v) & 31)
160 #define TEST_BIT(a,v) \
161 ((a)[(v) >> 5] & (1 << ((v) & 31)))
164 ((c) == S9X_LESS_THAN ? (a) < (b) : \
165 (c) == S9X_GREATER_THAN ? (a) > (b) : \
166 (c) == S9X_LESS_THAN_OR_EQUAL ? (a) <= (b) : \
167 (c) == S9X_GREATER_THAN_OR_EQUAL ? (a) >= (b) : \
168 (c) == S9X_EQUAL ? (a) == (b) : \
172 ((s) == S9X_8_BITS ? (uint8) (*((m) + (o))) : \
173 (s) == S9X_16_BITS ? ((uint16) (*((m) + (o)) + (*((m) + (o) + 1) << 8))) : \
174 (s) == S9X_24_BITS ? ((uint32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16))) : \
175 ((uint32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16) + (*((m) + (o) + 3) << 24))))
178 ((s) == S9X_8_BITS ? ((int8) *((m) + (o))) : \
179 (s) == S9X_16_BITS ? ((int16) (*((m) + (o)) + (*((m) + (o) + 1) << 8))) : \
180 (s) == S9X_24_BITS ? (((int32) ((*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16)) << 8)) >> 8): \
181 ((int32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16) + (*((m) + (o) + 3) << 24))))
183 void S9xSearchForChange (SCheatData *d, S9xCheatComparisonType cmp,
184 S9xCheatDataSize size, bool8 is_signed, bool8 update)
190 case S9X_8_BITS: l = 0; break;
191 case S9X_16_BITS: l = 1; break;
192 case S9X_24_BITS: l = 2; break;
194 case S9X_32_BITS: l = 3; break;
200 for (i = 0; i < 0x20000 - l; i++)
202 if (TEST_BIT (d->WRAM_BITS, i) &&
203 _C(cmp, _DS(size, d->RAM, i), _DS(size, d->CWRAM, i)))
206 d->CWRAM [i] = d->RAM [i];
209 BIT_CLEAR (d->WRAM_BITS, i);
212 for (i = 0; i < 0x10000 - l; i++)
214 if (TEST_BIT (d->SRAM_BITS, i) &&
215 _C(cmp, _DS(size, d->SRAM, i), _DS(size, d->CSRAM, i)))
218 d->CSRAM [i] = d->SRAM [i];
221 BIT_CLEAR (d->SRAM_BITS, i);
224 for (i = 0; i < 0x2000 - l; i++)
226 if (TEST_BIT (d->IRAM_BITS, i) &&
227 _C(cmp, _DS(size, d->FillRAM + 0x3000, i), _DS(size, d->CIRAM, i)))
230 d->CIRAM [i] = d->FillRAM [i + 0x3000];
233 BIT_CLEAR (d->IRAM_BITS, i);
238 for (i = 0; i < 0x20000 - l; i++)
240 if (TEST_BIT (d->WRAM_BITS, i) &&
241 _C(cmp, _D(size, d->RAM, i), _D(size, d->CWRAM, i)))
244 d->CWRAM [i] = d->RAM [i];
247 BIT_CLEAR (d->WRAM_BITS, i);
250 for (i = 0; i < 0x10000 - l; i++)
252 if (TEST_BIT (d->SRAM_BITS, i) &&
253 _C(cmp, _D(size, d->SRAM, i), _D(size, d->CSRAM, i)))
256 d->CSRAM [i] = d->SRAM [i];
259 BIT_CLEAR (d->SRAM_BITS, i);
262 for (i = 0; i < 0x2000 - l; i++)
264 if (TEST_BIT (d->IRAM_BITS, i) &&
265 _C(cmp, _D(size, d->FillRAM + 0x3000, i), _D(size, d->CIRAM, i)))
268 d->CIRAM [i] = d->FillRAM [i + 0x3000];
271 BIT_CLEAR (d->IRAM_BITS, i);
276 void S9xSearchForValue (SCheatData *d, S9xCheatComparisonType cmp,
277 S9xCheatDataSize size, uint32 value,
278 bool8 is_signed, bool8 update)
284 case S9X_8_BITS: l = 0; break;
285 case S9X_16_BITS: l = 1; break;
286 case S9X_24_BITS: l = 2; break;
288 case S9X_32_BITS: l = 3; break;
295 for (i = 0; i < 0x20000 - l; i++)
297 if (TEST_BIT (d->WRAM_BITS, i) &&
298 _C(cmp, _DS(size, d->RAM, i), (int32) value))
301 d->CWRAM [i] = d->RAM [i];
304 BIT_CLEAR (d->WRAM_BITS, i);
307 for (i = 0; i < 0x10000 - l; i++)
309 if (TEST_BIT (d->SRAM_BITS, i) &&
310 _C(cmp, _DS(size, d->SRAM, i), (int32) value))
313 d->CSRAM [i] = d->SRAM [i];
316 BIT_CLEAR (d->SRAM_BITS, i);
319 for (i = 0; i < 0x2000 - l; i++)
321 if (TEST_BIT (d->IRAM_BITS, i) &&
322 _C(cmp, _DS(size, d->FillRAM + 0x3000, i), (int32) value))
325 d->CIRAM [i] = d->FillRAM [i + 0x3000];
328 BIT_CLEAR (d->IRAM_BITS, i);
333 for (i = 0; i < 0x20000 - l; i++)
335 if (TEST_BIT (d->WRAM_BITS, i) &&
336 _C(cmp, _D(size, d->RAM, i), value))
339 d->CWRAM [i] = d->RAM [i];
342 BIT_CLEAR (d->WRAM_BITS, i);
345 for (i = 0; i < 0x10000 - l; i++)
347 if (TEST_BIT (d->SRAM_BITS, i) &&
348 _C(cmp, _D(size, d->SRAM, i), value))
351 d->CSRAM [i] = d->SRAM [i];
354 BIT_CLEAR (d->SRAM_BITS, i);
357 for (i = 0; i < 0x2000 - l; i++)
359 if (TEST_BIT (d->IRAM_BITS, i) &&
360 _C(cmp, _D(size, d->FillRAM + 0x3000, i), value))
363 d->CIRAM [i] = d->FillRAM [i + 0x3000];
366 BIT_CLEAR (d->IRAM_BITS, i);
371 void S9xOutputCheatSearchResults (SCheatData *d)
374 for (i = 0; i < 0x20000; i++)
376 if (TEST_BIT (d->WRAM_BITS, i))
377 printf ("WRAM: %05x: %02x\n", i, d->RAM [i]);
380 for (i = 0; i < 0x10000; i++)
382 if (TEST_BIT (d->SRAM_BITS, i))
383 printf ("SRAM: %04x: %02x\n", i, d->SRAM [i]);
386 for (i = 0; i < 0x2000; i++)
388 if (TEST_BIT (d->IRAM_BITS, i))
389 printf ("IRAM: %05x: %02x\n", i, d->FillRAM [i + 0x3000]);