1 /***********************************************************************************
2 Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3
4 (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
5 Jerremy Koot (jkoot@snes9x.com)
6
7 (c) Copyright 2002 - 2004 Matthew Kendora
8
9 (c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
10
11 (c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
12
13 (c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
14
15 (c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
16 Kris Bleakley (codeviolation@hotmail.com)
17
18 (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
19 Nach (n-a-c-h@users.sourceforge.net),
20 zones (kasumitokoduck@yahoo.com)
21
22 (c) Copyright 2006 - 2007 nitsuja
23
24 (c) Copyright 2009 - 2010 BearOso,
25 OV2
26
27
28 BS-X C emulator code
29 (c) Copyright 2005 - 2006 Dreamer Nom,
30 zones
31
32 C4 x86 assembler and some C emulation code
33 (c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
34 Nach,
35 zsKnight (zsknight@zsnes.com)
36
37 C4 C++ code
38 (c) Copyright 2003 - 2006 Brad Jorsch,
39 Nach
40
41 DSP-1 emulator code
42 (c) Copyright 1998 - 2006 _Demo_,
43 Andreas Naive (andreasnaive@gmail.com),
44 Gary Henderson,
45 Ivar (ivar@snes9x.com),
46 John Weidman,
47 Kris Bleakley,
48 Matthew Kendora,
49 Nach,
50 neviksti (neviksti@hotmail.com)
51
52 DSP-2 emulator code
53 (c) Copyright 2003 John Weidman,
54 Kris Bleakley,
55 Lord Nightmare (lord_nightmare@users.sourceforge.net),
56 Matthew Kendora,
57 neviksti
58
59 DSP-3 emulator code
60 (c) Copyright 2003 - 2006 John Weidman,
61 Kris Bleakley,
62 Lancer,
63 z80 gaiden
64
65 DSP-4 emulator code
66 (c) Copyright 2004 - 2006 Dreamer Nom,
67 John Weidman,
68 Kris Bleakley,
69 Nach,
70 z80 gaiden
71
72 OBC1 emulator code
73 (c) Copyright 2001 - 2004 zsKnight,
74 pagefault (pagefault@zsnes.com),
75 Kris Bleakley
76 Ported from x86 assembler to C by sanmaiwashi
77
78 SPC7110 and RTC C++ emulator code used in 1.39-1.51
79 (c) Copyright 2002 Matthew Kendora with research by
80 zsKnight,
81 John Weidman,
82 Dark Force
83
84 SPC7110 and RTC C++ emulator code used in 1.52+
85 (c) Copyright 2009 byuu,
86 neviksti
87
88 S-DD1 C emulator code
89 (c) Copyright 2003 Brad Jorsch with research by
90 Andreas Naive,
91 John Weidman
92
93 S-RTC C emulator code
94 (c) Copyright 2001 - 2006 byuu,
95 John Weidman
96
97 ST010 C++ emulator code
98 (c) Copyright 2003 Feather,
99 John Weidman,
100 Kris Bleakley,
101 Matthew Kendora
102
103 Super FX x86 assembler emulator code
104 (c) Copyright 1998 - 2003 _Demo_,
105 pagefault,
106 zsKnight
107
108 Super FX C emulator code
109 (c) Copyright 1997 - 1999 Ivar,
110 Gary Henderson,
111 John Weidman
112
113 Sound emulator code used in 1.5-1.51
114 (c) Copyright 1998 - 2003 Brad Martin
115 (c) Copyright 1998 - 2006 Charles Bilyue'
116
117 Sound emulator code used in 1.52+
118 (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
119
120 SH assembler code partly based on x86 assembler code
121 (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
122
123 2xSaI filter
124 (c) Copyright 1999 - 2001 Derek Liauw Kie Fa
125
126 HQ2x, HQ3x, HQ4x filters
127 (c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
128
129 NTSC filter
130 (c) Copyright 2006 - 2007 Shay Green
131
132 GTK+ GUI code
133 (c) Copyright 2004 - 2010 BearOso
134
135 Win32 GUI code
136 (c) Copyright 2003 - 2006 blip,
137 funkyass,
138 Matthew Kendora,
139 Nach,
140 nitsuja
141 (c) Copyright 2009 - 2010 OV2
142
143 Mac OS GUI code
144 (c) Copyright 1998 - 2001 John Stiles
145 (c) Copyright 2001 - 2010 zones
146
147 (c) Copyright 2010 - 2016 Daniel De Matteis. (UNDER NO CIRCUMSTANCE
148 WILL COMMERCIAL RIGHTS EVER BE APPROPRIATED TO ANY PARTY)
149
150 Specific ports contains the works of other authors. See headers in
151 individual files.
152
153
154 Snes9x homepage: http://www.snes9x.com/
155
156 Permission to use, copy, modify and/or distribute Snes9x in both binary
157 and source form, for non-commercial purposes, is hereby granted without
158 fee, providing that this license information and copyright notice appear
159 with all copies and any derived work.
160
161 This software is provided 'as-is', without any express or implied
162 warranty. In no event shall the authors be held liable for any damages
163 arising from the use of this software or it's derivatives.
164
165 Snes9x is freeware for PERSONAL USE only. Commercial users should
166 seek permission of the copyright holders first. Commercial use includes,
167 but is not limited to, charging money for Snes9x or software derived from
168 Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
169 using Snes9x as a promotion for your commercial product.
170
171 The copyright holders request that bug fixes and improvements to the code
172 should be forwarded to them so everyone can benefit from the modifications
173 in future versions.
174
175 Super NES and Super Nintendo Entertainment System are trademarks of
176 Nintendo Co., Limited and its subsidiary companies.
177 ***********************************************************************************/
178 #include <ctype.h>
179 #include <stdlib.h>
180 #include <string.h>
181
182 #include "snes9x.h"
183 #include "memmap.h"
184 #include "getset.h"
185 #include "apu.h"
186 #include "fxinst.h"
187 #include "fxemu.h"
188 #include "sdd1.h"
189 #include "srtc.h"
190 #include "controls.h"
191 #include "cheats.h"
192 #include "display.h"
193 #include "spc7110dec.h"
194
195 #include <streams/file_stream.h>
196 #include <libretro.h>
197
198 void S9xAppendMapping(struct retro_memory_descriptor *desc);
199
200 /* Forward declarations. */
201 static bool8 InitROM (void);
202
203 #define MAP_LIBRETRO_RAW(flags, ptr, offset, start, select, disconnect, len) \
204 do { \
205 struct retro_memory_descriptor desc={flags, ptr, offset, start, select, disconnect, len, NULL}; \
206 S9xAppendMapping(&desc); \
207 } while(0)
208
209 #define MAP_LIBRETRO(flags, ptr, offset, disconnect, len, bank_s,bank_e,addr_s,addr_e) \
210 MAP_LIBRETRO_RAW(flags, ptr, offset, \
211 (bank_s<<16 | addr_s), ((bank_s<<16 | addr_s) ^ (bank_e<<16 | addr_e) ^ 0xFFFFFF), \
212 disconnect, len)
213
214
215 static const uint32 crc32Table[256] =
216 {
217 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
218 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
219 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
220 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
221 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
222 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
223 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
224 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
225 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
226 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
227 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
228 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
229 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
230 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
231 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
232 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
233 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
234 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
235 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
236 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
237 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
238 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
239 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
240 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
241 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
242 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
243 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
244 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
245 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
246 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
247 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
248 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
249 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
250 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
251 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
252 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
253 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
254 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
255 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
256 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
257 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
258 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
259 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
260 };
261
262 /* deinterleave*/
263
S9xDeinterleaveType1(int size,uint8 * base)264 static void S9xDeinterleaveType1 (int size, uint8 *base)
265 {
266 uint8 *tmp;
267 uint8 blocks[256], b;
268 int nblocks;
269 int i, j;
270
271 nblocks = size >> 16;
272
273 for ( i = 0; i < nblocks; i++)
274 {
275 blocks[i * 2] = i + nblocks;
276 blocks[i * 2 + 1] = i;
277 }
278
279 tmp = (uint8 *) malloc(0x8000);
280 if (tmp)
281 {
282 for ( i = 0; i < nblocks * 2; i++)
283 {
284 for ( j = i; j < nblocks * 2; j++)
285 {
286 if (blocks[j] == i)
287 {
288 memcpy(tmp, &base[blocks[j] * 0x8000], 0x8000);
289 memmove(&base[blocks[j] * 0x8000], &base[blocks[i] * 0x8000], 0x8000);
290 memcpy(&base[blocks[i] * 0x8000], tmp, 0x8000);
291 b = blocks[j];
292 blocks[j] = blocks[i];
293 blocks[i] = b;
294 break;
295 }
296 }
297 }
298
299 free(tmp);
300 }
301 }
302
S9xDeinterleaveType2(int size,uint8 * base)303 static void S9xDeinterleaveType2 (int size, uint8 *base)
304 {
305 /* for odd Super FX images */
306 uint8 *tmp;
307 uint8 blocks[256], b;
308 int nblocks, step, i, j;
309
310 nblocks = size >> 16;
311 step = 64;
312
313 while (nblocks <= step)
314 step >>= 1;
315 nblocks = step;
316
317 for ( i = 0; i < nblocks * 2; i++)
318 blocks[i] = (i & ~0xf) | ((i & 3) << 2) | ((i & 12) >> 2);
319
320 tmp = (uint8 *) malloc(0x10000);
321 if (tmp)
322 {
323 for ( i = 0; i < nblocks * 2; i++)
324 {
325 for ( j = i; j < nblocks * 2; j++)
326 {
327 if (blocks[j] == i)
328 {
329 memcpy(tmp, &base[blocks[j] * 0x10000], 0x10000);
330 memmove(&base[blocks[j] * 0x10000], &base[blocks[i] * 0x10000], 0x10000);
331 memcpy(&base[blocks[i] * 0x10000], tmp, 0x10000);
332 b = blocks[j];
333 blocks[j] = blocks[i];
334 blocks[i] = b;
335 break;
336 }
337 }
338 }
339
340 free(tmp);
341 }
342 }
343
S9xDeinterleaveGD24(int size,uint8 * base)344 static void S9xDeinterleaveGD24 (int size, uint8 *base)
345 {
346 uint8 *tmp;
347 /* for 24Mbit images dumped with Game Doctor */
348 if (size != 0x300000)
349 return;
350
351 tmp = (uint8 *) malloc(0x80000);
352 if (tmp)
353 {
354 memcpy(tmp, &base[0x180000], 0x80000);
355 memcpy(&base[0x180000], &base[0x200000], 0x80000);
356 memcpy(&base[0x200000], &base[0x280000], 0x80000);
357 memcpy(&base[0x280000], tmp, 0x80000);
358
359 free(tmp);
360
361 S9xDeinterleaveType1(size, base);
362 }
363 }
364
365 /* allocation and deallocation */
366
Init(void)367 bool8 Init (void)
368 {
369 Memory.RAM = (uint8 *) malloc(0x20000);
370 Memory.SRAM = (uint8 *) malloc(0x80000);
371 Memory.VRAM = (uint8 *) malloc(0x10000);
372 Memory.ROM = (uint8 *) malloc(MAX_ROM_SIZE + 0x200 + 0x8000);
373
374 IPPU.TileCache[TILE_2BIT] = (uint8 *) malloc(MAX_2BIT_TILES * 64);
375 IPPU.TileCache[TILE_4BIT] = (uint8 *) malloc(MAX_4BIT_TILES * 64);
376 IPPU.TileCache[TILE_8BIT] = (uint8 *) malloc(MAX_8BIT_TILES * 64);
377 IPPU.TileCache[TILE_2BIT_EVEN] = (uint8 *) malloc(MAX_2BIT_TILES * 64);
378 IPPU.TileCache[TILE_2BIT_ODD] = (uint8 *) malloc(MAX_2BIT_TILES * 64);
379 IPPU.TileCache[TILE_4BIT_EVEN] = (uint8 *) malloc(MAX_4BIT_TILES * 64);
380 IPPU.TileCache[TILE_4BIT_ODD] = (uint8 *) malloc(MAX_4BIT_TILES * 64);
381
382 IPPU.TileCached[TILE_2BIT] = (uint8 *) malloc(MAX_2BIT_TILES);
383 IPPU.TileCached[TILE_4BIT] = (uint8 *) malloc(MAX_4BIT_TILES);
384 IPPU.TileCached[TILE_8BIT] = (uint8 *) malloc(MAX_8BIT_TILES);
385 IPPU.TileCached[TILE_2BIT_EVEN] = (uint8 *) malloc(MAX_2BIT_TILES);
386 IPPU.TileCached[TILE_2BIT_ODD] = (uint8 *) malloc(MAX_2BIT_TILES);
387 IPPU.TileCached[TILE_4BIT_EVEN] = (uint8 *) malloc(MAX_4BIT_TILES);
388 IPPU.TileCached[TILE_4BIT_ODD] = (uint8 *) malloc(MAX_4BIT_TILES);
389
390
391 /* don't render subscreen speed hack - disable this by default by
392 turning the variable (RenderSub - opposite of don't render sub) on */
393
394 PPU.RenderSub = TRUE;
395 PPU.FullClipping = TRUE;
396 coldata_update_screen = TRUE;
397
398 if (!Memory.RAM || !Memory.SRAM || !Memory.VRAM || !Memory.ROM ||
399 !IPPU.TileCache[TILE_2BIT] ||
400 !IPPU.TileCache[TILE_4BIT] ||
401 !IPPU.TileCache[TILE_8BIT] ||
402 !IPPU.TileCache[TILE_2BIT_EVEN] ||
403 !IPPU.TileCache[TILE_2BIT_ODD] ||
404 !IPPU.TileCache[TILE_4BIT_EVEN] ||
405 !IPPU.TileCache[TILE_4BIT_ODD] ||
406 !IPPU.TileCached[TILE_2BIT] ||
407 !IPPU.TileCached[TILE_4BIT] ||
408 !IPPU.TileCached[TILE_8BIT] ||
409 !IPPU.TileCached[TILE_2BIT_EVEN] ||
410 !IPPU.TileCached[TILE_2BIT_ODD] ||
411 !IPPU.TileCached[TILE_4BIT_EVEN] ||
412 !IPPU.TileCached[TILE_4BIT_ODD])
413 {
414 Deinit();
415 return (FALSE);
416 }
417
418 memset(Memory.RAM, 0, 0x20000);
419 memset(Memory.SRAM, 0, 0x80000);
420 memset(Memory.VRAM, 0, 0x10000);
421 memset(Memory.ROM, 0, MAX_ROM_SIZE + 0x200 + 0x8000);
422
423 memset(IPPU.TileCache[TILE_2BIT], 0, MAX_2BIT_TILES * 64);
424 memset(IPPU.TileCache[TILE_4BIT], 0, MAX_4BIT_TILES * 64);
425 memset(IPPU.TileCache[TILE_8BIT], 0, MAX_8BIT_TILES * 64);
426 memset(IPPU.TileCache[TILE_2BIT_EVEN], 0, MAX_2BIT_TILES * 64);
427 memset(IPPU.TileCache[TILE_2BIT_ODD], 0, MAX_2BIT_TILES * 64);
428 memset(IPPU.TileCache[TILE_4BIT_EVEN], 0, MAX_4BIT_TILES * 64);
429 memset(IPPU.TileCache[TILE_4BIT_ODD], 0, MAX_4BIT_TILES * 64);
430
431 memset(IPPU.TileCached[TILE_2BIT], 0, MAX_2BIT_TILES);
432 memset(IPPU.TileCached[TILE_4BIT], 0, MAX_4BIT_TILES);
433 memset(IPPU.TileCached[TILE_8BIT], 0, MAX_8BIT_TILES);
434 memset(IPPU.TileCached[TILE_2BIT_EVEN], 0, MAX_2BIT_TILES);
435 memset(IPPU.TileCached[TILE_2BIT_ODD], 0, MAX_2BIT_TILES);
436 memset(IPPU.TileCached[TILE_4BIT_EVEN], 0, MAX_4BIT_TILES);
437 memset(IPPU.TileCached[TILE_4BIT_ODD], 0, MAX_4BIT_TILES);
438
439 /* FillRAM uses first 32K of ROM image area, otherwise space just
440 wasted. Might be read by the SuperFX code. */
441
442 Memory.FillRAM = Memory.ROM;
443
444 /* Add 0x8000 to ROM image pointer to stop SuperFX code accessing
445 unallocated memory (can cause crash on some ports). */
446
447 Memory.ROM += 0x8000;
448
449 Memory.C4RAM = Memory.ROM + 0x400000 + 8192 * 8; /* C4 */
450 Memory.OBC1RAM = Memory.ROM + 0x400000; /* OBC1 */
451 Memory.BIOSROM = Memory.ROM + 0x300000; /* BS */
452 Memory.BSRAM = Memory.ROM + 0x400000; /* BS */
453
454 SuperFX.pvRegisters = Memory.FillRAM + 0x3000;
455 SuperFX.nRamBanks = 2; /* Most only use 1. 1=64KB=512Mb, 2=128KB=1024Mb */
456 SuperFX.pvRam = Memory.SRAM;
457 SuperFX.nRomBanks = (2 * 1024 * 1024) / (32 * 1024);
458 SuperFX.pvRom = (uint8 *) Memory.ROM;
459
460 return (TRUE);
461 }
462
Safe(const char * s)463 static char * Safe (const char *s)
464 {
465 static char *safe = NULL;
466 static int safe_len = 0;
467 int i, len;
468
469 if (s == NULL)
470 {
471 if (safe)
472 {
473 free(safe);
474 safe = NULL;
475 }
476
477 return (NULL);
478 }
479
480 len = strlen(s);
481 if (!safe || len + 1 > safe_len)
482 {
483 if (safe)
484 free(safe);
485
486 safe_len = len + 1;
487 safe = (char *) malloc(safe_len);
488 }
489
490 for ( i = 0; i < len; i++)
491 {
492 if (s[i] >= 32 && s[i] < 127)
493 safe[i] = s[i];
494 else
495 safe[i] = '_';
496 }
497
498 safe[len] = 0;
499
500 return (safe);
501 }
502
SafeANK(uint8 ROMRegion,const char * s)503 static char * SafeANK (uint8 ROMRegion, const char *s)
504 {
505 static char *safe = NULL;
506 static int safe_len = 0;
507 int i, len;
508
509 if (s == NULL)
510 {
511 if (safe)
512 {
513 free(safe);
514 safe = NULL;
515 }
516
517 return (NULL);
518 }
519
520 len = strlen(s);
521 if (!safe || len + 1 > safe_len)
522 {
523 if (safe)
524 free(safe);
525
526 safe_len = len + 1;
527 safe = (char *) malloc(safe_len);
528 }
529
530 for ( i = 0; i < len; i++)
531 {
532 if (s[i] >= 32 && s[i] < 127) /* ASCII */
533 safe [i] = s[i];
534 else
535 if (ROMRegion == 0 && ((uint8) s[i] >= 0xa0 && (uint8) s[i] < 0xe0)) /* JIS X 201 - Katakana */
536 safe [i] = s[i];
537 else
538 safe [i] = '_';
539 }
540
541 safe [len] = 0;
542
543 return (safe);
544 }
545
Deinit(void)546 void Deinit (void)
547 {
548 int t;
549 if (Memory.RAM)
550 {
551 free(Memory.RAM);
552 Memory.RAM = NULL;
553 }
554
555 if (Memory.SRAM)
556 {
557 free(Memory.SRAM);
558 Memory.SRAM = NULL;
559 }
560
561 if (Memory.VRAM)
562 {
563 free(Memory.VRAM);
564 Memory.VRAM = NULL;
565 }
566
567 if (Memory.ROM)
568 {
569 Memory.ROM -= 0x8000;
570 free(Memory.ROM);
571 Memory.ROM = NULL;
572 }
573
574 if(Settings.SPC7110 || Settings.SPC7110RTC)
575 {
576 S9xFreeSPC7110();
577 }
578
579 for ( t = 0; t < 7; t++)
580 {
581 if (IPPU.TileCache[t])
582 {
583 free(IPPU.TileCache[t]);
584 IPPU.TileCache[t] = NULL;
585 }
586
587 if (IPPU.TileCached[t])
588 {
589 free(IPPU.TileCached[t]);
590 IPPU.TileCached[t] = NULL;
591 }
592 }
593
594 Safe(NULL);
595 SafeANK(Memory.ROMRegion, NULL);
596 }
597
598 /* file management and ROM detection */
599
allASCII(uint8 * b,int size)600 static bool8 allASCII (uint8 *b, int size)
601 {
602 int i;
603 for ( i = 0; i < size; i++)
604 {
605 if (b[i] < 32 || b[i] > 126)
606 return (FALSE);
607 }
608
609 return (TRUE);
610 }
611
612 #if SNES_SUPPORT_MULTI_CART
is_SufamiTurbo_BIOS(uint8 * data,uint32 size)613 static bool8 is_SufamiTurbo_BIOS (uint8 *data, uint32 size)
614 {
615 if (size == 0x40000 && strncmp((char *) data, "BANDAI SFC-ADX", 14) == 0
616 && strncmp((char * ) (data + 0x10), "SFC-ADX BACKUP", 14) == 0)
617 return TRUE;
618 return FALSE;
619 }
620
is_SufamiTurbo_Cart(uint8 * data,uint32 size)621 static bool8 is_SufamiTurbo_Cart (uint8 *data, uint32 size)
622 {
623 if (size >= 0x80000 && size <= 0x100000 && strncmp((char *) data, "BANDAI SFC-ADX", 14) == 0
624 && strncmp((char * ) (data + 0x10), "SFC-ADX BACKUP", 14) != 0)
625 return TRUE;
626 return FALSE;
627 }
628
is_SameGame_BIOS(uint8 * data,uint32 size)629 static bool8 is_SameGame_BIOS (uint8 *data, uint32 size)
630 {
631 if (size == 0x100000 && strncmp((char *) (data + 0xffc0), "Same Game Tsume Game", 20) == 0)
632 return (TRUE);
633 return (FALSE);
634 }
635
is_SameGame_Add_On(uint8 * data,uint32 size)636 static bool8 is_SameGame_Add_On (uint8 *data, uint32 size)
637 {
638 if (size == 0x80000)
639 return (TRUE);
640 return (FALSE);
641 }
642 #endif
643
ScoreHiROM(uint32 calculated_size,uint8 * rom,bool8 skip_header,int32 romoff)644 static int ScoreHiROM (uint32 calculated_size, uint8 * rom, bool8 skip_header, int32 romoff)
645 {
646 uint8 *buf;
647 int score;
648
649 score = 0;
650 buf = rom + 0xff00 + romoff + (skip_header ? 0x200 : 0);
651
652 if (buf[0xd5] & 0x1)
653 score += 2;
654
655 /* Mode23 is SA-1 */
656 if (buf[0xd5] == 0x23)
657 score -= 2;
658
659 if (buf[0xd4] == 0x20)
660 score += 2;
661
662 if ((buf[0xdc] + (buf[0xdd] << 8)) + (buf[0xde] + (buf[0xdf] << 8)) == 0xffff)
663 {
664 score += 2;
665 if (0 != (buf[0xde] + (buf[0xdf] << 8)))
666 score++;
667 }
668
669 if (buf[0xda] == 0x33)
670 score += 2;
671
672 if ((buf[0xd5] & 0xf) < 4)
673 score += 2;
674
675 if (!(buf[0xfd] & 0x80))
676 score -= 6;
677
678 if ((buf[0xfc] + (buf[0xfd] << 8)) > 0xffb0)
679 score -= 2; /* reduced after looking at a scan by Cowering */
680
681 if (calculated_size > 1024 * 1024 * 3)
682 score += 4;
683
684 if ((1 << (buf[0xd7] - 7)) > 48)
685 score -= 1;
686
687 if (!allASCII(&buf[0xb0], 6))
688 score -= 1;
689
690 if (!allASCII(&buf[0xc0], ROM_NAME_LEN - 1))
691 score -= 1;
692
693 return (score);
694 }
695
ScoreLoROM(uint32 calculated_size,uint8 * rom,bool8 skip_header,int32 romoff)696 static int ScoreLoROM (uint32 calculated_size, uint8 * rom, bool8 skip_header, int32 romoff)
697 {
698 uint8 *buf;
699 int score;
700
701 score = 0;
702 buf = rom + 0x7f00 + romoff + (skip_header ? 0x200 : 0);
703
704 if (!(buf[0xd5] & 0x1))
705 score += 3;
706
707 /* Mode23 is SA-1 */
708 if (buf[0xd5] == 0x23)
709 score += 2;
710
711 if ((buf[0xdc] + (buf[0xdd] << 8)) + (buf[0xde] + (buf[0xdf] << 8)) == 0xffff)
712 {
713 score += 2;
714 if (0 != (buf[0xde] + (buf[0xdf] << 8)))
715 score++;
716 }
717
718 if (buf[0xda] == 0x33)
719 score += 2;
720
721 if ((buf[0xd5] & 0xf) < 4)
722 score += 2;
723
724 if (!(buf[0xfd] & 0x80))
725 score -= 6;
726
727 if ((buf[0xfc] + (buf[0xfd] << 8)) > 0xffb0)
728 score -= 2; /* reduced per Cowering suggestion */
729
730 if (calculated_size <= 1024 * 1024 * 16)
731 score += 2;
732
733 if ((1 << (buf[0xd7] - 7)) > 48)
734 score -= 1;
735
736 if (!allASCII(&buf[0xb0], 6))
737 score -= 1;
738
739 if (!allASCII(&buf[0xc0], ROM_NAME_LEN - 1))
740 score -= 1;
741
742 return (score);
743 }
744
HeaderRemove(uint32 size,int32 * headerCount,uint8 * buf)745 static uint32 HeaderRemove (uint32 size, int32 * headerCount, uint8 *buf)
746 {
747 uint32 calc_size = (size / 0x2000) * 0x2000;
748
749 if (size - calc_size == 512)
750 {
751 memmove(buf, buf + 512, calc_size);
752 (*headerCount)++;
753 size -= 512;
754 }
755
756 return (size);
757 }
758
FileLoader(uint8 * buffer,int32 maxsize)759 static uint32 FileLoader (uint8 *buffer, int32 maxsize)
760 {
761 /* <- ROM size without header */
762 /* ** Memory.HeaderCount */
763 /* ** Memory.ROMFilename */
764
765 uint8 *ptr;
766 uint64_t size = 0;
767 STREAM fp = OPEN_STREAM();
768
769 Memory.HeaderCount = 0;
770 if (!fp)
771 return (0);
772
773 ptr = buffer;
774
775 size = READ_STREAM(ptr, (uint64_t)(
776 maxsize + 0x200), fp);
777 CLOSE_STREAM(fp);
778
779 return HeaderRemove(size, &Memory.HeaderCount, ptr);
780 }
781
caCRC32(uint8 * array,uint32 size,uint32 crc32)782 static uint32 caCRC32 (uint8 *array, uint32 size, uint32 crc32)
783 {
784 uint32 i;
785
786 for ( i = 0; i < size; i++)
787 crc32 = ((crc32 >> 8) & 0x00FFFFFF) ^ crc32Table[(crc32 ^ array[i]) & 0xFF];
788
789 return (~crc32);
790 }
791
LoadROM(void)792 bool8 LoadROM (void)
793 {
794 int hi_score, lo_score, retry_count;
795 bool8 interleaved, tales;
796 uint8 * RomHeader;
797 int32 totalFileSize;
798
799 retry_count = 0;
800
801 memset(Memory.ROM, 0, MAX_ROM_SIZE);
802 memset(&Multi, 0, sizeof(Multi));
803
804 again:
805 Memory.CalculatedSize = 0;
806 Memory.ExtendedFormat = NOPE;
807
808 totalFileSize = FileLoader(Memory.ROM, MAX_ROM_SIZE);
809 if (!totalFileSize)
810 {
811 S9xMessage(S9X_MSG_ERROR, S9X_CATEGORY_ROM,
812 "Unable to load ROM");
813 return FALSE;
814 }
815
816 hi_score = ScoreHiROM(Memory.CalculatedSize, Memory.ROM, FALSE, 0);
817 lo_score = ScoreLoROM(Memory.CalculatedSize, Memory.ROM, FALSE, 0);
818
819 if (Memory.HeaderCount == 0 && !Settings.ForceNoHeader &&
820 ((hi_score > lo_score && ScoreHiROM(Memory.CalculatedSize, Memory.ROM, TRUE, 0) > hi_score) ||
821 (hi_score <= lo_score && ScoreLoROM(Memory.CalculatedSize, Memory.ROM, TRUE, 0) > lo_score)))
822 {
823 memmove(Memory.ROM, Memory.ROM + 512, totalFileSize - 512);
824 totalFileSize -= 512;
825 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_ROM, "Try 'force no-header' option if the game doesn't work");
826 /* modifying ROM, so we need to rescore */
827 hi_score = ScoreHiROM(Memory.CalculatedSize, Memory.ROM, FALSE, 0);
828 lo_score = ScoreLoROM(Memory.CalculatedSize, Memory.ROM, FALSE, 0);
829 }
830
831 Memory.CalculatedSize = (totalFileSize / 0x2000) * 0x2000;
832
833 if (Memory.CalculatedSize > 0x400000 &&
834 (Memory.ROM[0x7fd5] + (Memory.ROM[0x7fd6] << 8)) != 0x4332 && /* exclude S-DD1 */
835 (Memory.ROM[0x7fd5] + (Memory.ROM[0x7fd6] << 8)) != 0x4532 &&
836 (Memory.ROM[0xffd5] + (Memory.ROM[0xffd6] << 8)) != 0xF93a && /* exclude SPC7110 */
837 (Memory.ROM[0xffd5] + (Memory.ROM[0xffd6] << 8)) != 0xF53a)
838 Memory.ExtendedFormat = YEAH;
839
840 /* if both vectors are invalid, it's type 1 interleaved LoROM */
841 if (Memory.ExtendedFormat == NOPE &&
842 ((Memory.ROM[0x7ffc] + (Memory.ROM[0x7ffd] << 8)) < 0x8000) &&
843 ((Memory.ROM[0xfffc] + (Memory.ROM[0xfffd] << 8)) < 0x8000))
844 {
845 if (!Settings.ForceInterleaved && !Settings.ForceNotInterleaved)
846 S9xDeinterleaveType1(totalFileSize, Memory.ROM);
847 }
848
849 /* CalculatedSize is now set, so rescore */
850 hi_score = ScoreHiROM(Memory.CalculatedSize, Memory.ROM, FALSE, 0);
851 lo_score = ScoreLoROM(Memory.CalculatedSize, Memory.ROM, FALSE, 0);
852
853 RomHeader = Memory.ROM;
854
855 if (Memory.ExtendedFormat != NOPE)
856 {
857 int swappedhirom, swappedlorom;
858
859 swappedhirom = ScoreHiROM(Memory.CalculatedSize, Memory.ROM, FALSE, 0x400000);
860 swappedlorom = ScoreLoROM(Memory.CalculatedSize, Memory.ROM, FALSE, 0x400000);
861
862 /* set swapped here */
863 if (max(swappedlorom, swappedhirom) >= max(lo_score, hi_score))
864 {
865 Memory.ExtendedFormat = BIGFIRST;
866 hi_score = swappedhirom;
867 lo_score = swappedlorom;
868 RomHeader += 0x400000;
869 }
870 else
871 Memory.ExtendedFormat = SMALLFIRST;
872 }
873
874 interleaved = FALSE;
875 tales = FALSE;
876
877 interleaved = Settings.ForceInterleaved || Settings.ForceInterleaved2 || Settings.ForceInterleaveGD24;
878
879 if (Settings.ForceLoROM || (!Settings.ForceHiROM && lo_score >= hi_score))
880 {
881 Memory.LoROM = TRUE;
882 Memory.HiROM = FALSE;
883
884 /* ignore map type byte if not 0x2x or 0x3x */
885 if ((RomHeader[0x7fd5] & 0xf0) == 0x20 || (RomHeader[0x7fd5] & 0xf0) == 0x30)
886 {
887 switch (RomHeader[0x7fd5] & 0xf)
888 {
889 case 1:
890 interleaved = TRUE;
891 break;
892
893 case 5:
894 interleaved = TRUE;
895 tales = TRUE;
896 break;
897 }
898 }
899 }
900 else
901 {
902 Memory.LoROM = FALSE;
903 Memory.HiROM = TRUE;
904
905 if ((RomHeader[0xffd5] & 0xf0) == 0x20 || (RomHeader[0xffd5] & 0xf0) == 0x30)
906 {
907 switch (RomHeader[0xffd5] & 0xf)
908 {
909 case 0:
910 case 3:
911 interleaved = TRUE;
912 break;
913 }
914 }
915 }
916
917 /* these two games fail to be detected otherwise */
918 if (!Settings.ForceHiROM && !Settings.ForceLoROM)
919 {
920 if (strncmp((char *) &Memory.ROM[0x7fc0], "YUYU NO QUIZ DE GO!GO!", 22) == 0 ||
921 (strncmp((char *) &Memory.ROM[0xffc0], "BATMAN--REVENGE JOKER", 21) == 0))
922 {
923 Memory.LoROM = TRUE;
924 Memory.HiROM = FALSE;
925 interleaved = FALSE;
926 tales = FALSE;
927 }
928 }
929
930 if (!Settings.ForceNotInterleaved && interleaved)
931 {
932 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_ROM, "ROM image is in interleaved format - converting...");
933
934 if (tales)
935 {
936 if (Memory.ExtendedFormat == BIGFIRST)
937 {
938 S9xDeinterleaveType1(0x400000, Memory.ROM);
939 S9xDeinterleaveType1(Memory.CalculatedSize - 0x400000, Memory.ROM + 0x400000);
940 }
941 else
942 {
943 S9xDeinterleaveType1(Memory.CalculatedSize - 0x400000, Memory.ROM);
944 S9xDeinterleaveType1(0x400000, Memory.ROM + Memory.CalculatedSize - 0x400000);
945 }
946
947 Memory.LoROM = FALSE;
948 Memory.HiROM = TRUE;
949 }
950 else
951 if (Settings.ForceInterleaveGD24 && Memory.CalculatedSize == 0x300000)
952 {
953 bool8 t = Memory.LoROM;
954 Memory.LoROM = Memory.HiROM;
955 Memory.HiROM = t;
956 S9xDeinterleaveGD24(Memory.CalculatedSize, Memory.ROM);
957 }
958 else
959 if (Settings.ForceInterleaved2)
960 S9xDeinterleaveType2(Memory.CalculatedSize, Memory.ROM);
961 else
962 {
963 bool8 t = Memory.LoROM;
964 Memory.LoROM = Memory.HiROM;
965 Memory.HiROM = t;
966 S9xDeinterleaveType1(Memory.CalculatedSize, Memory.ROM);
967 }
968
969 hi_score = ScoreHiROM(Memory.CalculatedSize, Memory.ROM, FALSE, 0);
970 lo_score = ScoreLoROM(Memory.CalculatedSize, Memory.ROM, FALSE, 0);
971
972 if ((Memory.HiROM && (lo_score >= hi_score || hi_score < 0)) ||
973 (Memory.LoROM && (hi_score > lo_score || lo_score < 0)))
974 {
975 if (retry_count == 0)
976 {
977 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_ROM, "ROM lied about its type! Trying again.");
978 Settings.ForceNotInterleaved = TRUE;
979 Settings.ForceInterleaved = FALSE;
980 retry_count++;
981 goto again;
982 }
983 }
984 }
985
986 if (Memory.ExtendedFormat == SMALLFIRST)
987 tales = TRUE;
988
989 if (tales)
990 {
991 uint8 *tmp = (uint8 *) malloc(Memory.CalculatedSize - 0x400000);
992 if (tmp)
993 {
994 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_ROM, "Fixing swapped ExHiROM...");
995 memcpy(tmp, Memory.ROM, Memory.CalculatedSize - 0x400000);
996 memmove(Memory.ROM, Memory.ROM + Memory.CalculatedSize - 0x400000, 0x400000);
997 memcpy(Memory.ROM + 0x400000, tmp, Memory.CalculatedSize - 0x400000);
998 free(tmp);
999 }
1000 }
1001
1002 memset(&SNESGameFixes, 0, sizeof(SNESGameFixes));
1003 SNESGameFixes.SRAMInitialValue = 0x60;
1004
1005 if(InitROM() != TRUE)
1006 return (FALSE);
1007
1008 S9xInitCheatData();
1009 S9xApplyCheats();
1010
1011 S9xReset();
1012
1013 return (TRUE);
1014 }
1015
1016 #if SNES_SUPPORT_MULTI_CART
LoadMultiCart(const char * cartA,const char * cartB)1017 bool8 LoadMultiCart (const char *cartA, const char *cartB)
1018 {
1019 bool8 r;
1020
1021 r = TRUE;
1022
1023 memset(Memory.ROM, 0, MAX_ROM_SIZE);
1024 memset(&Multi, 0, sizeof(Multi));
1025
1026 Memory.CalculatedSize = 0;
1027 Memory.ExtendedFormat = NOPE;
1028
1029 if (cartA && cartA[0])
1030 Multi.cartSizeA = FileLoader(Memory.ROM, cartA, MAX_ROM_SIZE);
1031
1032 if (Multi.cartSizeA == 0)
1033 {
1034 if (cartB && cartB[0])
1035 Multi.cartSizeB = FileLoader(Memory.ROM, cartB, MAX_ROM_SIZE);
1036 }
1037
1038 if (Multi.cartSizeA)
1039 {
1040 if (is_SufamiTurbo_Cart(Memory.ROM, Multi.cartSizeA))
1041 Multi.cartType = 4;
1042 else
1043 if (is_SameGame_BIOS(Memory.ROM, Multi.cartSizeA))
1044 Multi.cartType = 3;
1045 }
1046 else
1047 if (Multi.cartSizeB)
1048 {
1049 if (is_SufamiTurbo_Cart(Memory.ROM, Multi.cartSizeB))
1050 Multi.cartType = 4;
1051 }
1052 else
1053 Multi.cartType = 4; /* assuming BIOS only */
1054
1055 switch (Multi.cartType)
1056 {
1057 case 4:
1058 r = LoadSufamiTurbo(cartA, cartB);
1059 break;
1060
1061 case 3:
1062 r = LoadSameGame(cartA, cartB);
1063 break;
1064
1065 default:
1066 r = FALSE;
1067 }
1068
1069 if (!r)
1070 {
1071 memset(&Multi, 0, sizeof(Multi));
1072 return (FALSE);
1073 }
1074
1075 memset(&SNESGameFixes, 0, sizeof(SNESGameFixes));
1076 SNESGameFixes.SRAMInitialValue = 0x60;
1077
1078 if(InitROM() != TRUE)
1079 return (FALSE);
1080
1081 S9xInitCheatData();
1082 S9xApplyCheats();
1083
1084 S9xReset();
1085
1086 return (TRUE);
1087 }
1088
LoadSufamiTurbo(const char * cartA,const char * cartB)1089 bool8 LoadSufamiTurbo (const char *cartA, const char *cartB)
1090 {
1091 RFILE *fp = NULL;
1092 int64_t size;
1093 char path[PATH_MAX + 1];
1094
1095 Multi.cartOffsetA = 0x100000;
1096 Multi.cartOffsetB = 0x200000;
1097 Multi.sramA = Memory.SRAM;
1098 Multi.sramB = Memory.SRAM + 0x10000;
1099
1100 if (Multi.cartSizeA)
1101 {
1102 Multi.sramSizeA = 4; /* ROM[0x37]? */
1103 Multi.sramMaskA = Multi.sramSizeA ? ((1 << (Multi.sramSizeA + 3)) * 128 - 1) : 0;
1104
1105 strcpy(Multi.fileNameA, cartA);
1106 memcpy(Memory.ROM + Multi.cartOffsetA, Memory.ROM, Multi.cartSizeA);
1107 }
1108
1109 if (Multi.cartSizeA && !Multi.cartSizeB)
1110 {
1111 if (cartB && cartB[0])
1112 Multi.cartSizeB = FileLoader(Memory.ROM, cartB, MAX_ROM_SIZE);
1113
1114 if (Multi.cartSizeB)
1115 {
1116 if (!is_SufamiTurbo_Cart(Memory.ROM, Multi.cartSizeB))
1117 Multi.cartSizeB = 0;
1118 }
1119 }
1120
1121 if (Multi.cartSizeB)
1122 {
1123 Multi.sramSizeB = 4; /* ROM[0x37]? */
1124 Multi.sramMaskB = Multi.sramSizeB ? ((1 << (Multi.sramSizeB + 3)) * 128 - 1) : 0;
1125
1126 strcpy(Multi.fileNameB, cartB);
1127 memcpy(Memory.ROM + Multi.cartOffsetB, Memory.ROM, Multi.cartSizeB);
1128 }
1129
1130 strcpy(path, S9xGetDirectory(BIOS_DIR));
1131 strcat(path, SLASH_STR);
1132 strcat(path, "STBIOS.bin");
1133
1134 fp = filestream_open(path, RETRO_VFS_FILE_ACCESS_READ,
1135 RETRO_VFS_FILE_ACCESS_HINT_NONE);
1136
1137 if (fp)
1138 {
1139 size = filestream_read(fp, (void *)Memory.ROM, 0x40000);
1140 filestream_close(fp);
1141
1142 if ((size <= 0) || !is_SufamiTurbo_BIOS(Memory.ROM, (size_t)size))
1143 return (FALSE);
1144 }
1145 else
1146 return (FALSE);
1147
1148 Memory.LoROM = TRUE;
1149 Memory.HiROM = FALSE;
1150 Memory.CalculatedSize = 0x40000;
1151
1152 return (TRUE);
1153 }
1154
LoadSameGame(const char * cartA,const char * cartB)1155 bool8 LoadSameGame (const char *cartA, const char *cartB)
1156 {
1157 Multi.cartOffsetA = 0;
1158 Multi.cartOffsetB = 0x200000;
1159 Multi.sramA = Memory.SRAM;
1160 Multi.sramB = NULL;
1161
1162 Multi.sramSizeA = Memory.ROM[0xffd8];
1163 Multi.sramMaskA = Multi.sramSizeA ? ((1 << (Multi.sramSizeA + 3)) * 128 - 1) : 0;
1164 Multi.sramSizeB = 0;
1165 Multi.sramMaskB = 0;
1166
1167 strcpy(Multi.fileNameA, cartA);
1168
1169 if (cartB && cartB[0])
1170 Multi.cartSizeB = FileLoader(Memory.ROM + Multi.cartOffsetB, cartB, MAX_ROM_SIZE - Multi.cartOffsetB);
1171
1172 if (Multi.cartSizeB)
1173 {
1174 if (!is_SameGame_Add_On(Memory.ROM + Multi.cartOffsetB, Multi.cartSizeB))
1175 Multi.cartSizeB = 0;
1176 else
1177 strcpy(Multi.fileNameB, cartB);
1178 }
1179
1180 Memory.LoROM = FALSE;
1181 Memory.HiROM = TRUE;
1182 Memory.CalculatedSize = Multi.cartSizeA;
1183
1184 return (TRUE);
1185 }
1186 #endif /* SNES_SUPPORT_MULTI_CART */
1187
1188 #define MAP_INITIALIZE() \
1189 { \
1190 int c; \
1191 for ( c = 0; c < 0x1000; c++) \
1192 { \
1193 Memory.Map[c] = (uint8 *) MAP_NONE; \
1194 Memory.WriteMap[c] = (uint8 *) MAP_NONE; \
1195 Memory.BlockIsROM[c] = FALSE; \
1196 Memory.BlockIsRAM[c] = FALSE; \
1197 } \
1198 }
1199
checksum_calc_sum(uint8 * data,uint32 length)1200 static uint16 checksum_calc_sum (uint8 *data, uint32 length)
1201 {
1202 uint32 i;
1203 uint16 sum;
1204
1205 sum = 0;
1206
1207 for ( i = 0; i < length; i++)
1208 sum += data[i];
1209
1210 return (sum);
1211 }
1212
checksum_mirror_sum(uint8 * start,uint32 * length,uint32 mask)1213 static uint16 checksum_mirror_sum (uint8 *start, uint32 * length, uint32 mask)
1214 {
1215 uint16 part1, part2;
1216 uint32 next_length;
1217
1218 /* from NSRT */
1219 while (!(*length & mask))
1220 mask >>= 1;
1221
1222 part1 = checksum_calc_sum(start, mask);
1223 part2 = 0;
1224
1225 next_length = *length - mask;
1226 if (next_length)
1227 {
1228 part2 = checksum_mirror_sum(start + mask, &next_length, mask >> 1);
1229
1230 while (next_length < mask)
1231 {
1232 next_length += next_length;
1233 part2 += part2;
1234 }
1235
1236 *length = mask + mask;
1237 }
1238
1239 return (part1 + part2);
1240 }
1241
map_mirror(uint32 size,uint32 pos)1242 static uint32 map_mirror (uint32 size, uint32 pos)
1243 {
1244 uint32 mask;
1245 /* from bsnes */
1246 if (size == 0)
1247 return (0);
1248 if (pos < size)
1249 return (pos);
1250
1251 mask = UINT32_C(1) << 31;
1252 while (!(pos & mask))
1253 mask >>= 1;
1254
1255 if (size <= (pos & mask))
1256 return (map_mirror(size, pos - mask));
1257 return (mask + map_mirror(size - mask, pos - mask));
1258 }
1259
1260 #define MATCH_NA(str) (strcmp(Memory.ROMName, str) == 0)
1261 #define MATCH_NN(str) (strncmp(Memory.ROMName, str, strlen(str)) == 0)
1262 #define MATCH_NC(str) (strncasecmp(Memory.ROMName, str, strlen(str)) == 0)
1263 #define MATCH_ID(str) (strncmp(Memory.ROMId, str, strlen(str)) == 0)
1264
1265 #define MAP_HIROM(bank_s, bank_e, addr_s, addr_e, size, auto_export_map) \
1266 { \
1267 uint32 i, c; \
1268 for ( c = bank_s; c <= bank_e; c++) \
1269 { \
1270 for ( i = addr_s; i <= addr_e; i += 0x1000) \
1271 { \
1272 uint32 p = (c << 4) | (i >> 12); \
1273 uint32 addr = c << 16; \
1274 Memory.Map[p] = Memory.ROM + map_mirror(size, addr); \
1275 Memory.BlockIsROM[p] = TRUE; \
1276 Memory.BlockIsRAM[p] = FALSE; \
1277 } \
1278 } \
1279 if (auto_export_map) \
1280 { \
1281 MAP_LIBRETRO(RETRO_MEMDESC_CONST, Memory.ROM, map_mirror(size, addr_s), 0, \
1282 size - map_mirror(size, addr_s), bank_s,bank_e,addr_s,addr_e); \
1283 } \
1284 }
1285
1286 #define MAP_INDEX(bank_s, bank_e, addr_s, addr_e, index, type, auto_export_map) \
1287 { \
1288 uint32 i, c; \
1289 for ( c = bank_s; c <= bank_e; c++) \
1290 { \
1291 for ( i = addr_s; i <= addr_e; i += 0x1000) \
1292 { \
1293 uint32 p = (c << 4) | (i >> 12); \
1294 Memory.Map[p] = (uint8 *) index; \
1295 Memory.BlockIsROM[p] = ((type == MAP_TYPE_I_O) || (type == MAP_TYPE_RAM)) ? FALSE : TRUE; \
1296 Memory.BlockIsRAM[p] = ((type == MAP_TYPE_I_O) || (type == MAP_TYPE_ROM)) ? FALSE : TRUE; \
1297 } \
1298 } \
1299 if (auto_export_map) \
1300 { \
1301 if (type==MAP_LOROM_SRAM || type==MAP_SA1RAM) \
1302 MAP_LIBRETRO(0, Memory.SRAM, 0, 0x8000, Memory.SRAMMask+1, bank_s,bank_e,addr_s,addr_e); \
1303 if (type==MAP_LOROM_SRAM_B) \
1304 MAP_LIBRETRO(0, Multi.sramB, 0, 0x8000, Multi.sramMaskB+1, bank_s,bank_e,addr_s,addr_e); \
1305 if (type==MAP_HIROM_SRAM || type==MAP_RONLY_SRAM) \
1306 MAP_LIBRETRO(0, Memory.SRAM, 0, 0xE000, Memory.SRAMMask+1, bank_s,bank_e,addr_s,addr_e); \
1307 } \
1308 }
1309
1310 #define MAP_SPACE(bank_s, bank_e, addr_s, addr_e, data, auto_export_map) \
1311 { \
1312 uint32 i,x; \
1313 for ( x = bank_s; x <= bank_e; x++) \
1314 { \
1315 for ( i = addr_s; i <= addr_e; i += 0x1000) \
1316 { \
1317 uint32 p = (x << 4) | (i >> 12); \
1318 Memory.Map[p] = data; \
1319 Memory.BlockIsROM[p] = FALSE; \
1320 Memory.BlockIsRAM[p] = TRUE; \
1321 } \
1322 } \
1323 if (auto_export_map) \
1324 { \
1325 MAP_LIBRETRO(0, data, 0, 0xFF0000, 0, bank_s,bank_e,addr_s,addr_e); \
1326 } \
1327 }
1328
1329 #define MAP_LOROM_OFFSET(bank_s, bank_e, addr_s, addr_e, size, offset, auto_export_map) \
1330 { \
1331 uint32 i, c; \
1332 for ( c = bank_s; c <= bank_e; c++) \
1333 { \
1334 for ( i = addr_s; i <= addr_e; i += 0x1000) \
1335 { \
1336 uint32 p = (c << 4) | (i >> 12); \
1337 uint32 addr = ((c - bank_s) & 0x7f) * 0x8000; \
1338 Memory.Map[p] = Memory.ROM + offset + map_mirror(size, addr) - (i & 0x8000); \
1339 Memory.BlockIsROM[p] = TRUE; \
1340 Memory.BlockIsRAM[p] = FALSE; \
1341 } \
1342 } \
1343 if (auto_export_map) \
1344 { \
1345 MAP_LIBRETRO(RETRO_MEMDESC_CONST, Memory.ROM, offset, 0x8000, size, bank_s,bank_e,addr_s,addr_e); \
1346 } \
1347 }
1348
1349 #define MAP_HIROM_OFFSET(bank_s, bank_e, addr_s, addr_e, size, offset, auto_export_map) \
1350 { \
1351 uint32 i, c; \
1352 for ( c = bank_s; c <= bank_e; c++) \
1353 { \
1354 for ( i = addr_s; i <= addr_e; i += 0x1000) \
1355 { \
1356 uint32 p = (c << 4) | (i >> 12); \
1357 uint32 addr = (c - bank_s) << 16; \
1358 Memory.Map[p] = Memory.ROM + offset + map_mirror(size, addr); \
1359 Memory.BlockIsROM[p] = TRUE; \
1360 Memory.BlockIsRAM[p] = FALSE; \
1361 } \
1362 } \
1363 if (auto_export_map) \
1364 { \
1365 MAP_LIBRETRO(RETRO_MEMDESC_CONST, Memory.ROM, map_mirror(size, offset + addr_s), 0, size, bank_s,bank_e,addr_s,addr_e); \
1366 } \
1367 }
1368
1369 #define MAP_LOROMSRAM() \
1370 MAP_INDEX(0x70, 0x7f, 0x0000, 0x7fff, MAP_LOROM_SRAM, MAP_TYPE_RAM, true); \
1371 MAP_INDEX(0xf0, 0xff, 0x0000, 0x7fff, MAP_LOROM_SRAM, MAP_TYPE_RAM, true);
1372
1373 #define MAP_WRAM() \
1374 /* will overwrite others */ \
1375 MAP_SPACE(0x7e, 0x7e, 0x0000, 0xffff, Memory.RAM, true); \
1376 MAP_SPACE(0x7f, 0x7f, 0x0000, 0xffff, Memory.RAM + 0x10000, true);
1377
1378 #define MAP_SYSTEM() \
1379 /* will be overwritten */ \
1380 MAP_SPACE(0x00, 0x3f, 0x0000, 0x1fff, Memory.RAM, true); \
1381 MAP_INDEX(0x00, 0x3f, 0x2000, 0x3fff, MAP_PPU, MAP_TYPE_I_O, true); \
1382 MAP_INDEX(0x00, 0x3f, 0x4000, 0x5fff, MAP_CPU, MAP_TYPE_I_O, true); \
1383 MAP_SPACE(0x80, 0xbf, 0x0000, 0x1fff, Memory.RAM, true); \
1384 MAP_INDEX(0x80, 0xbf, 0x2000, 0x3fff, MAP_PPU, MAP_TYPE_I_O, true); \
1385 MAP_INDEX(0x80, 0xbf, 0x4000, 0x5fff, MAP_CPU, MAP_TYPE_I_O, true);
1386
map_WriteProtectROM(void)1387 void map_WriteProtectROM (void)
1388 {
1389 int c;
1390 memcpy((void *) Memory.WriteMap, (void *)Memory.Map, sizeof(Memory.Map));
1391
1392 for ( c = 0; c < 0x1000; c++)
1393 {
1394 if (Memory.BlockIsROM[c])
1395 Memory.WriteMap[c] = (uint8 *) MAP_NONE;
1396 }
1397 }
1398
1399 #define MAP_JUMBOLOROMMAP() \
1400 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, "Map_JumboLoROMMap"); \
1401 MAP_SYSTEM(); \
1402 MAP_LOROM_OFFSET(0x00, 0x3f, 0x8000, 0xffff, Memory.CalculatedSize - 0x400000, 0x400000, true); \
1403 MAP_LOROM_OFFSET(0x40, 0x7f, 0x0000, 0xffff, Memory.CalculatedSize - 0x600000, 0x600000, true); \
1404 MAP_LOROM_OFFSET(0x80, 0xbf, 0x8000, 0xffff, 0x400000, 0, true); \
1405 MAP_LOROM_OFFSET(0xc0, 0xff, 0x0000, 0xffff, 0x400000, 0x200000, true); \
1406 MAP_LOROMSRAM(); \
1407 MAP_WRAM(); \
1408 map_WriteProtectROM();
1409
1410 #define MAP_LOROM(bank_s, bank_e, addr_s, addr_e, size, auto_export_map) \
1411 { \
1412 uint32 i, c; \
1413 for ( c = bank_s; c <= bank_e; c++) \
1414 { \
1415 for ( i = addr_s; i <= addr_e; i += 0x1000) \
1416 { \
1417 uint32 p = (c << 4) | (i >> 12); \
1418 uint32 addr = (c & 0x7f) * 0x8000; \
1419 Memory.Map[p] = Memory.ROM + map_mirror(size, addr) - (i & 0x8000); \
1420 Memory.BlockIsROM[p] = TRUE; \
1421 Memory.BlockIsRAM[p] = FALSE; \
1422 } \
1423 } \
1424 if (auto_export_map) \
1425 { \
1426 MAP_LIBRETRO(RETRO_MEMDESC_CONST, Memory.ROM, 0, 0x8000, size, bank_s,bank_e,addr_s,addr_e); \
1427 } \
1428 }
1429
1430 #define MAP_SRAM512KLOROMMAP() \
1431 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, "Map_SRAM512KLoROMMap"); \
1432 MAP_SYSTEM(); \
1433 MAP_LOROM(0x00, 0x3f, 0x8000, 0xffff, Memory.CalculatedSize, true); \
1434 MAP_LOROM(0x40, 0x7f, 0x0000, 0xffff, Memory.CalculatedSize, true); \
1435 MAP_LOROM(0x80, 0xbf, 0x8000, 0xffff, Memory.CalculatedSize, true); \
1436 MAP_LOROM(0xc0, 0xff, 0x0000, 0xffff, Memory.CalculatedSize, true); \
1437 MAP_SPACE(0x70, 0x70, 0x0000, 0xffff, Memory.SRAM, true); \
1438 MAP_SPACE(0x71, 0x71, 0x0000, 0xffff, Memory.SRAM + 0x8000, true); \
1439 MAP_SPACE(0x72, 0x72, 0x0000, 0xffff, Memory.SRAM + 0x10000, true); \
1440 MAP_SPACE(0x73, 0x73, 0x0000, 0xffff, Memory.SRAM + 0x18000, true); \
1441 MAP_WRAM(); \
1442 map_WriteProtectROM();
1443
1444 #define MAP_DSP_() \
1445 switch (DSP0.maptype) \
1446 { \
1447 case M_DSP1_LOROM_S: \
1448 MAP_INDEX(0x20, 0x3f, 0x8000, 0xffff, MAP_DSP, MAP_TYPE_I_O, true); \
1449 MAP_INDEX(0xa0, 0xbf, 0x8000, 0xffff, MAP_DSP, MAP_TYPE_I_O, true); \
1450 break; \
1451 case M_DSP1_LOROM_L: \
1452 MAP_INDEX(0x60, 0x6f, 0x0000, 0x7fff, MAP_DSP, MAP_TYPE_I_O, true); \
1453 MAP_INDEX(0xe0, 0xef, 0x0000, 0x7fff, MAP_DSP, MAP_TYPE_I_O, true); \
1454 break; \
1455 case M_DSP1_HIROM: \
1456 MAP_INDEX(0x00, 0x1f, 0x6000, 0x7fff, MAP_DSP, MAP_TYPE_I_O, true); \
1457 MAP_INDEX(0x80, 0x9f, 0x6000, 0x7fff, MAP_DSP, MAP_TYPE_I_O, true); \
1458 break; \
1459 case M_DSP2_LOROM: \
1460 MAP_INDEX(0x20, 0x3f, 0x6000, 0x6fff, MAP_DSP, MAP_TYPE_I_O, true); \
1461 MAP_INDEX(0x20, 0x3f, 0x8000, 0xbfff, MAP_DSP, MAP_TYPE_I_O, true); \
1462 MAP_INDEX(0xa0, 0xbf, 0x6000, 0x6fff, MAP_DSP, MAP_TYPE_I_O, true); \
1463 MAP_INDEX(0xa0, 0xbf, 0x8000, 0xbfff, MAP_DSP, MAP_TYPE_I_O, true); \
1464 break; \
1465 case M_DSP3_LOROM: \
1466 MAP_INDEX(0x20, 0x3f, 0x8000, 0xffff, MAP_DSP, MAP_TYPE_I_O, true); \
1467 MAP_INDEX(0xa0, 0xbf, 0x8000, 0xffff, MAP_DSP, MAP_TYPE_I_O, true); \
1468 break; \
1469 case M_DSP4_LOROM: \
1470 MAP_INDEX(0x30, 0x3f, 0x8000, 0xffff, MAP_DSP, MAP_TYPE_I_O, true); \
1471 MAP_INDEX(0xb0, 0xbf, 0x8000, 0xffff, MAP_DSP, MAP_TYPE_I_O, true); \
1472 break; \
1473 }
1474
1475 #define MAP_C4_() \
1476 MAP_INDEX(0x00, 0x3f, 0x6000, 0x7fff, MAP_C4, MAP_TYPE_I_O, true); \
1477 MAP_INDEX(0x80, 0xbf, 0x6000, 0x7fff, MAP_C4, MAP_TYPE_I_O, true);
1478
1479 #define MAP_OBC1() \
1480 MAP_INDEX(0x00, 0x3f, 0x6000, 0x7fff, MAP_OBC_RAM, MAP_TYPE_I_O, true); \
1481 MAP_INDEX(0x80, 0xbf, 0x6000, 0x7fff, MAP_OBC_RAM, MAP_TYPE_I_O, true);
1482
1483 #define MAP_SETARISC() \
1484 MAP_INDEX(0x00, 0x3f, 0x3000, 0x3fff, MAP_SETA_RISC, MAP_TYPE_I_O, true); \
1485 MAP_INDEX(0x80, 0xbf, 0x3000, 0x3fff, MAP_SETA_RISC, MAP_TYPE_I_O, true);
1486
1487 #define MAP_LOROMMAP() \
1488 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, "Map_LoROMMap"); \
1489 MAP_SYSTEM(); \
1490 \
1491 MAP_LOROM(0x00, 0x3f, 0x8000, 0xffff, Memory.CalculatedSize, true); \
1492 MAP_LOROM(0x40, 0x7f, 0x0000, 0xffff, Memory.CalculatedSize, true); \
1493 MAP_LOROM(0x80, 0xbf, 0x8000, 0xffff, Memory.CalculatedSize, true); \
1494 MAP_LOROM(0xc0, 0xff, 0x0000, 0xffff, Memory.CalculatedSize, true); \
1495 if (Settings.DSP) \
1496 { \
1497 MAP_DSP_(); \
1498 } \
1499 else if (Settings.C4) \
1500 { \
1501 MAP_C4_(); \
1502 } \
1503 else if (Settings.OBC1) \
1504 { \
1505 MAP_OBC1(); \
1506 } \
1507 else if (Settings.SETA == ST_018) \
1508 { \
1509 MAP_SETARISC(); \
1510 } \
1511 MAP_LOROMSRAM(); \
1512 MAP_WRAM(); \
1513 map_WriteProtectROM();
1514
1515 #define MAP_HIROMSRAM() \
1516 MAP_INDEX(0x20, 0x3f, 0x6000, 0x7fff, MAP_HIROM_SRAM, MAP_TYPE_RAM, true); \
1517 MAP_INDEX(0xa0, 0xbf, 0x6000, 0x7fff, MAP_HIROM_SRAM, MAP_TYPE_RAM, true);
1518
1519 #define MAP_HIROMMAP() \
1520 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_ROM, "Map_HiROMMap"); \
1521 MAP_SYSTEM(); \
1522 MAP_HIROM(0x00, 0x3f, 0x8000, 0xffff, Memory.CalculatedSize, true); \
1523 MAP_HIROM(0x40, 0x7f, 0x0000, 0xffff, Memory.CalculatedSize, true); \
1524 MAP_HIROM(0x80, 0xbf, 0x8000, 0xffff, Memory.CalculatedSize, true); \
1525 MAP_HIROM(0xc0, 0xff, 0x0000, 0xffff, Memory.CalculatedSize, true); \
1526 \
1527 if (Settings.DSP) \
1528 { \
1529 MAP_DSP_(); \
1530 } \
1531 MAP_HIROMSRAM(); \
1532 MAP_WRAM(); \
1533 map_WriteProtectROM();
1534
KartContents(uint8 ROMType)1535 static const char * KartContents (uint8 ROMType)
1536 {
1537 static char str[64];
1538 static const char *contents[3] = { "ROM", "ROM+RAM", "ROM+RAM+BAT" };
1539 char chip[16];
1540
1541 if (ROMType == 0 && !Settings.BS)
1542 return ("ROM");
1543
1544 if (Settings.BS)
1545 strcpy(chip, "+BS");
1546 else
1547 if (Settings.SuperFX)
1548 strcpy(chip, "+Super FX");
1549 else
1550 if (Settings.SDD1)
1551 strcpy(chip, "+S-DD1");
1552 else
1553 if (Settings.OBC1)
1554 strcpy(chip, "+OBC1");
1555 else
1556 if (Settings.SA1)
1557 {
1558 strcpy(chip, "+SA-1");
1559 }
1560 else
1561 if (Settings.SPC7110RTC)
1562 strcpy(chip, "+SPC7110+RTC");
1563 else
1564 if (Settings.SPC7110)
1565 strcpy(chip, "+SPC7110");
1566 else
1567 if (Settings.SRTC)
1568 strcpy(chip, "+S-RTC");
1569 else
1570 if (Settings.C4)
1571 strcpy(chip, "+C4");
1572 else
1573 if (Settings.SETA == ST_010)
1574 strcpy(chip, "+ST-010");
1575 else
1576 if (Settings.SETA == ST_011)
1577 strcpy(chip, "+ST-011");
1578 else
1579 if (Settings.SETA == ST_018)
1580 strcpy(chip, "+ST-018");
1581 else
1582 if (Settings.DSP)
1583 snprintf(chip, sizeof(chip), "+DSP-%d", Settings.DSP);
1584 else
1585 strcpy(chip, "");
1586
1587 snprintf(str, sizeof(str), "%s%s", contents[(ROMType & 0xf) % 3], chip);
1588
1589 return (str);
1590 }
1591
Map_NoMAD1LoROMMap(void)1592 static void Map_NoMAD1LoROMMap (void)
1593 {
1594 printf("Map_NoMAD1LoROMMap\n");
1595 MAP_SYSTEM();
1596
1597 MAP_LOROM(0x00, 0x3f, 0x8000, 0xffff, Memory.CalculatedSize, true);
1598 MAP_LOROM(0x40, 0x7f, 0x0000, 0xffff, Memory.CalculatedSize, true);
1599 MAP_LOROM(0x80, 0xbf, 0x8000, 0xffff, Memory.CalculatedSize, true);
1600 MAP_LOROM(0xc0, 0xff, 0x0000, 0xffff, Memory.CalculatedSize, true);
1601
1602 MAP_INDEX(0x70, 0x7f, 0x0000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM, true);
1603 MAP_INDEX(0xf0, 0xff, 0x0000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM, true);
1604
1605 MAP_WRAM();
1606
1607 map_WriteProtectROM();
1608 }
1609
Map_ROM24MBSLoROMMap(void)1610 static void Map_ROM24MBSLoROMMap (void)
1611 {
1612 /* PCB: BSC-1A5M-01, BSC-1A7M-10*/
1613 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, "Map_ROM24MBSLoROMMap");
1614 MAP_SYSTEM();
1615
1616 MAP_LOROM_OFFSET(0x00, 0x1f, 0x8000, 0xffff, 0x100000, 0, true);
1617 MAP_LOROM_OFFSET(0x20, 0x3f, 0x8000, 0xffff, 0x100000, 0x100000, true);
1618 MAP_LOROM_OFFSET(0x80, 0x9f, 0x8000, 0xffff, 0x100000, 0x200000, true);
1619 MAP_LOROM_OFFSET(0xa0, 0xbf, 0x8000, 0xffff, 0x100000, 0x100000, true);
1620
1621 MAP_LOROMSRAM();
1622 MAP_WRAM();
1623
1624 map_WriteProtectROM();
1625 }
1626
Map_SufamiTurboLoROMMap(void)1627 static void Map_SufamiTurboLoROMMap (void)
1628 {
1629 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, "Map_SufamiTurboLoROMMap");
1630 MAP_SYSTEM();
1631
1632 MAP_LOROM_OFFSET(0x00, 0x1f, 0x8000, 0xffff, 0x40000, 0, true);
1633 MAP_LOROM_OFFSET(0x20, 0x3f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA, true);
1634 MAP_LOROM_OFFSET(0x40, 0x5f, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB, true);
1635 MAP_LOROM_OFFSET(0x80, 0x9f, 0x8000, 0xffff, 0x40000, 0, true);
1636 MAP_LOROM_OFFSET(0xa0, 0xbf, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA, true);
1637 MAP_LOROM_OFFSET(0xc0, 0xdf, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB, true);
1638
1639 if (Multi.sramSizeA)
1640 {
1641 MAP_INDEX(0x60, 0x63, 0x8000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM, true);
1642 MAP_INDEX(0xe0, 0xe3, 0x8000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM, true);
1643 }
1644
1645 if (Multi.sramSizeB)
1646 {
1647 MAP_INDEX(0x70, 0x73, 0x8000, 0xffff, MAP_LOROM_SRAM_B, MAP_TYPE_RAM, true);
1648 MAP_INDEX(0xf0, 0xf3, 0x8000, 0xffff, MAP_LOROM_SRAM_B, MAP_TYPE_RAM, true);
1649 }
1650
1651 MAP_WRAM();
1652
1653 map_WriteProtectROM();
1654 }
1655
Map_SufamiTurboPseudoLoROMMap(void)1656 static void Map_SufamiTurboPseudoLoROMMap (void)
1657 {
1658 /* for combined images */
1659 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, "Map_SufamiTurboPseudoLoROMMap");
1660 MAP_SYSTEM();
1661
1662 MAP_LOROM_OFFSET(0x00, 0x1f, 0x8000, 0xffff, 0x40000, 0, true);
1663 MAP_LOROM_OFFSET(0x20, 0x3f, 0x8000, 0xffff, 0x100000, 0x100000, true);
1664 MAP_LOROM_OFFSET(0x40, 0x5f, 0x8000, 0xffff, 0x100000, 0x200000, true);
1665 MAP_LOROM_OFFSET(0x80, 0x9f, 0x8000, 0xffff, 0x40000, 0, true);
1666 MAP_LOROM_OFFSET(0xa0, 0xbf, 0x8000, 0xffff, 0x100000, 0x100000, true);
1667 MAP_LOROM_OFFSET(0xc0, 0xdf, 0x8000, 0xffff, 0x100000, 0x200000, true);
1668
1669 /* I don't care :P */
1670 MAP_SPACE(0x60, 0x63, 0x8000, 0xffff, Memory.SRAM - 0x8000, true);
1671 MAP_SPACE(0xe0, 0xe3, 0x8000, 0xffff, Memory.SRAM - 0x8000, true);
1672 MAP_SPACE(0x70, 0x73, 0x8000, 0xffff, Memory.SRAM + 0x4000 - 0x8000, false);//these two seem to duplicate the above ones in
1673 MAP_SPACE(0xf0, 0xf3, 0x8000, 0xffff, Memory.SRAM + 0x4000 - 0x8000, false);//way that makes the duplicates hard to find.
1674
1675 MAP_WRAM();
1676
1677 map_WriteProtectROM();
1678 }
1679
Map_SuperFXLoROMMap(void)1680 static void Map_SuperFXLoROMMap (void)
1681 {
1682 int c;
1683 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, "Map_SuperFXLoROMMap");
1684 MAP_SYSTEM();
1685
1686 /* Replicate the first 2Mbit of the ROM at ROM + 2Mbit such that each 32K
1687 block is repeated twice in each 64K block. */
1688 for ( c = 0; c < 64; c++)
1689 {
1690 memcpy(&Memory.ROM[0x200000 + c * 0x10000], &Memory.ROM[c * 0x8000], 0x8000);
1691 memcpy(&Memory.ROM[0x208000 + c * 0x10000], &Memory.ROM[c * 0x8000], 0x8000);
1692 }
1693
1694 MAP_LOROM(0x00, 0x3f, 0x8000, 0xffff, Memory.CalculatedSize, true);
1695 MAP_LOROM(0x80, 0xbf, 0x8000, 0xffff, Memory.CalculatedSize, true);
1696
1697 MAP_HIROM_OFFSET(0x40, 0x7f, 0x0000, 0xffff, Memory.CalculatedSize, 0, true);
1698 MAP_HIROM_OFFSET(0xc0, 0xff, 0x0000, 0xffff, Memory.CalculatedSize, 0, true);
1699
1700 MAP_SPACE(0x00, 0x3f, 0x6000, 0x7fff, Memory.SRAM - 0x6000, true);
1701 MAP_SPACE(0x80, 0xbf, 0x6000, 0x7fff, Memory.SRAM - 0x6000, true);
1702 MAP_SPACE(0x70, 0x70, 0x0000, 0xffff, Memory.SRAM, true);
1703 MAP_SPACE(0x71, 0x71, 0x0000, 0xffff, Memory.SRAM + 0x10000, true);
1704
1705 MAP_WRAM();
1706
1707 map_WriteProtectROM();
1708 }
1709
Map_SetaDSPLoROMMap(void)1710 static void Map_SetaDSPLoROMMap (void)
1711 {
1712 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, "Map_SetaDSPLoROMMap");
1713 MAP_SYSTEM();
1714
1715 MAP_LOROM(0x00, 0x3f, 0x8000, 0xffff, Memory.CalculatedSize, true);
1716 MAP_LOROM(0x40, 0x7f, 0x8000, 0xffff, Memory.CalculatedSize, true);
1717 MAP_LOROM(0x80, 0xbf, 0x8000, 0xffff, Memory.CalculatedSize, true);
1718 MAP_LOROM(0xc0, 0xff, 0x8000, 0xffff, Memory.CalculatedSize, true);
1719
1720 /* where does the SETA chip access, anyway? */
1721 /* please confirm this? */
1722 MAP_INDEX(0x68, 0x6f, 0x0000, 0x7fff, MAP_SETA_DSP, MAP_TYPE_RAM, true);
1723 /* and this! */
1724 MAP_INDEX(0x60, 0x67, 0x0000, 0x3fff, MAP_SETA_DSP, MAP_TYPE_I_O, true);
1725 /* ST-0010: */
1726 /* MAP_INDEX(0x68, 0x6f, 0x0000, 0x0fff, MAP_SETA_DSP, ?); */
1727
1728 MAP_LOROMSRAM();
1729 MAP_WRAM();
1730
1731 map_WriteProtectROM();
1732 }
1733
Map_SDD1LoROMMap(void)1734 static void Map_SDD1LoROMMap (void)
1735 {
1736 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, "Map_SDD1LoROMMap");
1737 MAP_SYSTEM();
1738
1739 MAP_LOROM(0x00, 0x3f, 0x8000, 0xffff, Memory.CalculatedSize, true);
1740 MAP_LOROM(0x80, 0xbf, 0x8000, 0xffff, Memory.CalculatedSize, true);
1741
1742 MAP_HIROM_OFFSET(0x40, 0x7f, 0x0000, 0xffff, Memory.CalculatedSize, 0, true);
1743 MAP_HIROM_OFFSET(0xc0, 0xff, 0x0000, 0xffff, Memory.CalculatedSize, 0, true); /* will be overwritten dynamically*/
1744
1745 MAP_INDEX(0x70, 0x7f, 0x0000, 0x7fff, MAP_LOROM_SRAM, MAP_TYPE_RAM, true);
1746
1747 MAP_WRAM();
1748
1749 map_WriteProtectROM();
1750 }
1751
Map_SA1LoROMMap(void)1752 static void Map_SA1LoROMMap (void)
1753 {
1754 int c;
1755 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, "Map_SA1LoROMMap");
1756 MAP_SYSTEM();
1757
1758 MAP_LOROM(0x00, 0x3f, 0x8000, 0xffff, Memory.CalculatedSize, true);
1759 MAP_LOROM(0x80, 0xbf, 0x8000, 0xffff, Memory.CalculatedSize, true);
1760
1761 MAP_HIROM_OFFSET(0xc0, 0xff, 0x0000, 0xffff, Memory.CalculatedSize, 0, true);
1762
1763 MAP_SPACE(0x00, 0x3f, 0x3000, 0x3fff, Memory.FillRAM, true);
1764 MAP_SPACE(0x80, 0xbf, 0x3000, 0x3fff, Memory.FillRAM, true);
1765 MAP_INDEX(0x00, 0x3f, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O, true);
1766 MAP_INDEX(0x80, 0xbf, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O, true);
1767
1768 for ( c = 0x40; c < 0x80; c++)
1769 {
1770 MAP_SPACE(c, c, 0x0000, 0xffff, Memory.SRAM + (c & 1) * 0x10000, false);
1771 }
1772
1773 MAP_LIBRETRO_RAW(0, Memory.SRAM, 0, 0x400000, 0xC00000, 0xFE0000, 0x20000);
1774
1775 MAP_WRAM();
1776
1777 map_WriteProtectROM();
1778
1779 /* Now copy the map and correct it for the SA1 CPU. */
1780 memcpy((void *) SA1.Map, (void *) Memory.Map, sizeof(Memory.Map));
1781 memcpy((void *) SA1.WriteMap, (void *) Memory.WriteMap, sizeof(Memory.WriteMap));
1782
1783 /* SA-1 Banks 00->3f and 80->bf */
1784 for ( c = 0x000; c < 0x400; c += 0x10)
1785 {
1786 SA1.Map[c + 0] = SA1.Map[c + 0x800] = Memory.FillRAM + 0x3000;
1787 SA1.Map[c + 1] = SA1.Map[c + 0x801] = (uint8 *) MAP_NONE;
1788 SA1.WriteMap[c + 0] = SA1.WriteMap[c + 0x800] = Memory.FillRAM + 0x3000;
1789 SA1.WriteMap[c + 1] = SA1.WriteMap[c + 0x801] = (uint8 *) MAP_NONE;
1790 }
1791
1792 /* SA-1 Banks 60->6f */
1793 for ( c = 0x600; c < 0x700; c++)
1794 SA1.Map[c] = SA1.WriteMap[c] = (uint8 *) MAP_BWRAM_BITMAP;
1795
1796 Memory.BWRAM = Memory.SRAM;
1797 }
1798
Map_ExtendedHiROMMap(void)1799 static void Map_ExtendedHiROMMap (void)
1800 {
1801 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, "Map_ExtendedHiROMMap");
1802 MAP_SYSTEM();
1803
1804 MAP_HIROM_OFFSET(0x00, 0x3f, 0x8000, 0xffff, Memory.CalculatedSize - 0x400000, 0x400000, true);
1805 MAP_HIROM_OFFSET(0x40, 0x7f, 0x0000, 0xffff, Memory.CalculatedSize - 0x400000, 0x400000, true);
1806 MAP_HIROM_OFFSET(0x80, 0xbf, 0x8000, 0xffff, 0x400000, 0, true);
1807 MAP_HIROM_OFFSET(0xc0, 0xff, 0x0000, 0xffff, 0x400000, 0, true);
1808
1809 MAP_HIROMSRAM();
1810 MAP_WRAM();
1811
1812 map_WriteProtectROM();
1813 }
1814
Map_SameGameHiROMMap(void)1815 static void Map_SameGameHiROMMap (void)
1816 {
1817 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, "Map_SameGameHiROMMap");
1818 MAP_SYSTEM();
1819
1820 MAP_HIROM_OFFSET(0x00, 0x1f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA, true);
1821 MAP_HIROM_OFFSET(0x20, 0x3f, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB, true);
1822 MAP_HIROM_OFFSET(0x40, 0x5f, 0x0000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA, true);
1823 MAP_HIROM_OFFSET(0x60, 0x7f, 0x0000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB, true);
1824 MAP_HIROM_OFFSET(0x80, 0x9f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA, true);
1825 MAP_HIROM_OFFSET(0xa0, 0xbf, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB, true);
1826 MAP_HIROM_OFFSET(0xc0, 0xdf, 0x0000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA, true);
1827 MAP_HIROM_OFFSET(0xe0, 0xff, 0x0000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB, true);
1828
1829 MAP_HIROMSRAM();
1830 MAP_WRAM();
1831
1832 map_WriteProtectROM();
1833 }
1834
Map_SPC7110HiROMMap(void)1835 static void Map_SPC7110HiROMMap (void)
1836 {
1837 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, "Map_SPC7110HiROMMap");
1838 MAP_SYSTEM();
1839
1840 MAP_INDEX(0x00, 0x00, 0x6000, 0x7fff, MAP_HIROM_SRAM, MAP_TYPE_RAM, true);
1841 MAP_HIROM(0x00, 0x0f, 0x8000, 0xffff, Memory.CalculatedSize, true);
1842 MAP_INDEX(0x30, 0x30, 0x6000, 0x7fff, MAP_HIROM_SRAM, MAP_TYPE_RAM, true);
1843 MAP_INDEX(0x50, 0x50, 0x0000, 0xffff, MAP_SPC7110_DRAM, MAP_TYPE_ROM, true);
1844 MAP_HIROM(0x80, 0x8f, 0x8000, 0xffff, Memory.CalculatedSize, true);
1845 MAP_HIROM_OFFSET(0xc0, 0xcf, 0x0000, 0xffff, Memory.CalculatedSize, 0, true);
1846 MAP_INDEX(0xd0, 0xff, 0x0000, 0xffff, MAP_SPC7110_ROM, MAP_TYPE_ROM, true);
1847
1848 MAP_WRAM();
1849
1850 map_WriteProtectROM();
1851 }
1852
StaticRAMSize(void)1853 static const char * StaticRAMSize (void)
1854 {
1855 static char str[20];
1856
1857 if (Memory.SRAMSize > 16)
1858 strcpy(str, "Corrupt");
1859 else
1860 snprintf(str, sizeof(str), "%dKbits", 8 * (Memory.SRAMMask + 1) / 1024);
1861
1862 return (str);
1863 }
1864
Size(void)1865 static const char * Size (void)
1866 {
1867 static char str[20];
1868
1869 if (Multi.cartType == 4)
1870 strcpy(str, "N/A");
1871 else
1872 if (Memory.ROMSize < 7 || Memory.ROMSize - 7 > 23)
1873 strcpy(str, "Corrupt");
1874 else
1875 snprintf(str, sizeof(str), "%dMbits", 1 << (Memory.ROMSize - 7));
1876
1877 return (str);
1878 }
1879
InitROM(void)1880 static bool8 InitROM (void)
1881 {
1882 int p;
1883 bool8 bs, isChecksumOK;
1884 uint8 *RomHeader;
1885 uint16 sum;
1886 uint32 identifier;
1887 char displayName[ROM_NAME_LEN], String[513];
1888
1889 Settings.SuperFX = FALSE;
1890 Settings.DSP = 0;
1891 Settings.SA1 = FALSE;
1892 Settings.C4 = FALSE;
1893 Settings.SDD1 = FALSE;
1894 Settings.SPC7110 = FALSE;
1895 Settings.SPC7110RTC = FALSE;
1896 Settings.OBC1 = FALSE;
1897 Settings.SETA = 0;
1898 Settings.SRTC = FALSE;
1899 Settings.BS = FALSE;
1900 SuperFX.nRomBanks = Memory.CalculatedSize >> 15;
1901
1902 Settings.SupportHiRes = TRUE;
1903
1904 /* Parse ROM header and read ROM information */
1905
1906 Memory.CompanyId = -1;
1907 memset(Memory.ROMId, 0, 5);
1908
1909 RomHeader = Memory.ROM + 0x7FB0;
1910 if (Memory.ExtendedFormat == BIGFIRST)
1911 RomHeader += 0x400000;
1912 if (Memory.HiROM)
1913 RomHeader += 0x8000;
1914
1915 S9xInitBSX(); /* Set BS header before parsing */
1916
1917 /* Parse SNES Header */
1918
1919 bs = Settings.BS & !Settings.BSXItself;
1920
1921 strncpy(Memory.ROMName, (char *) &RomHeader[0x10], ROM_NAME_LEN - 1);
1922 if (bs)
1923 memset(Memory.ROMName + 16, 0x20, ROM_NAME_LEN - 17);
1924
1925 if (bs)
1926 {
1927 if (!(((RomHeader[0x29] & 0x20) && Memory.CalculatedSize < 0x100000) ||
1928 (!(RomHeader[0x29] & 0x20) && Memory.CalculatedSize == 0x100000)))
1929 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, "BS: Size mismatch");
1930
1931 /* FIXME*/
1932 p = 0;
1933 while ((1 << p) < (int) Memory.CalculatedSize)
1934 p++;
1935 Memory.ROMSize = p - 10;
1936 }
1937 else
1938 Memory.ROMSize = RomHeader[0x27];
1939
1940 Memory.SRAMSize = bs ? 5 /* BS-X */ : RomHeader[0x28];
1941 Memory.ROMSpeed = bs ? RomHeader[0x28] : RomHeader[0x25];
1942 Memory.ROMType = bs ? 0xE5 /* BS-X */ : RomHeader[0x26];
1943 Memory.ROMRegion = bs ? 0 : RomHeader[0x29];
1944
1945 Memory.ROMChecksum = RomHeader[0x2E] + (RomHeader[0x2F] << 8);
1946 Memory.ROMComplementChecksum = RomHeader[0x2C] + (RomHeader[0x2D] << 8);
1947
1948 memcpy(Memory.ROMId, &RomHeader[0x02], 4);
1949
1950 if (RomHeader[0x2A] != 0x33)
1951 Memory.CompanyId = ((RomHeader[0x2A] >> 4) & 0x0F) * 36 + (RomHeader[0x2A] & 0x0F);
1952 else
1953 if (isalnum(RomHeader[0x00]) && isalnum(RomHeader[0x01]))
1954 {
1955 int l, r, l2, r2;
1956 l = toupper(RomHeader[0x00]);
1957 r = toupper(RomHeader[0x01]);
1958 l2 = (l > '9') ? l - '7' : l - '0';
1959 r2 = (r > '9') ? r - '7' : r - '0';
1960 Memory.CompanyId = l2 * 36 + r2;
1961 }
1962
1963 if (Memory.SRAMSize > 16 || Memory.ROMSize < 7 || Memory.ROMSize - 7 > 23)
1964 {
1965 S9xMessage(S9X_MSG_ERROR, S9X_CATEGORY_ROM,
1966 "ROM is corrupt or invalid");
1967 return (FALSE);
1968 }
1969
1970 /* End of Parse SNES Header */
1971
1972 /* Detect and initialize chips
1973 detection codes are compatible with NSRT */
1974
1975 /* DSP1/2/3/4 */
1976 if (Memory.ROMType == 0x03)
1977 {
1978 if (Memory.ROMSpeed == 0x30)
1979 Settings.DSP = 4; /* DSP4 */
1980 else
1981 Settings.DSP = 1; /* DSP1 */
1982 }
1983 else if (Memory.ROMType == 0x05)
1984 {
1985 if (Memory.ROMSpeed == 0x20)
1986 Settings.DSP = 2; /* DSP2 */
1987 else
1988 if (Memory.ROMSpeed == 0x30 && RomHeader[0x2a] == 0xb2)
1989 Settings.DSP = 3; /* DSP3 */
1990 else
1991 Settings.DSP = 1; /* DSP1 */
1992 }
1993
1994 switch (Settings.DSP)
1995 {
1996 case 1: /* DSP1 */
1997 if (Memory.HiROM)
1998 {
1999 DSP0.boundary = 0x7000;
2000 DSP0.maptype = M_DSP1_HIROM;
2001 }
2002 else
2003 if (Memory.CalculatedSize > 0x100000)
2004 {
2005 DSP0.boundary = 0x4000;
2006 DSP0.maptype = M_DSP1_LOROM_L;
2007 }
2008 else
2009 {
2010 DSP0.boundary = 0xc000;
2011 DSP0.maptype = M_DSP1_LOROM_S;
2012 }
2013
2014 SetDSP = &DSP1SetByte;
2015 GetDSP = &DSP1GetByte;
2016 break;
2017
2018 case 2: /* DSP2 */
2019 DSP0.boundary = 0x10000;
2020 DSP0.maptype = M_DSP2_LOROM;
2021 SetDSP = &DSP2SetByte;
2022 GetDSP = &DSP2GetByte;
2023 break;
2024
2025 case 3: /* DSP3 */
2026 DSP0.boundary = 0xc000;
2027 DSP0.maptype = M_DSP3_LOROM;
2028 SetDSP = &DSP3SetByte;
2029 GetDSP = &DSP3GetByte;
2030 break;
2031
2032 case 4: /* DSP4 */
2033 DSP0.boundary = 0xc000;
2034 DSP0.maptype = M_DSP4_LOROM;
2035 SetDSP = &DSP4SetByte;
2036 GetDSP = &DSP4GetByte;
2037 break;
2038
2039 default:
2040 SetDSP = NULL;
2041 GetDSP = NULL;
2042 break;
2043 }
2044
2045 identifier = ((Memory.ROMType & 0xff) << 8) + (Memory.ROMSpeed & 0xff);
2046
2047 switch (identifier)
2048 {
2049 /* SRTC*/
2050 case 0x5535:
2051 Settings.SRTC = TRUE;
2052 S9xInitSRTC();
2053 break;
2054
2055 /* SPC7110*/
2056 case 0xF93A:
2057 Settings.SPC7110RTC = TRUE;
2058 Settings.SPC7110 = TRUE;
2059 S9xInitSPC7110();
2060 break;
2061 case 0xF53A:
2062 Settings.SPC7110 = TRUE;
2063 S9xInitSPC7110();
2064 break;
2065
2066 /* OBC1*/
2067 case 0x2530:
2068 Settings.OBC1 = TRUE;
2069 break;
2070
2071 /* SA1*/
2072 case 0x3423:
2073 case 0x3523:
2074 Settings.SA1 = TRUE;
2075 break;
2076
2077 /* SuperFX*/
2078 case 0x1320:
2079 case 0x1420:
2080 case 0x1520:
2081 case 0x1A20:
2082 Settings.SuperFX = TRUE;
2083 memset((uint8 *) &GSU, 0, sizeof(struct FxRegs_s));
2084 if (Memory.ROM[0x7FDA] == 0x33)
2085 Memory.SRAMSize = Memory.ROM[0x7FBD];
2086 else
2087 Memory.SRAMSize = 5;
2088 break;
2089
2090 /* SDD1*/
2091 case 0x4332:
2092 case 0x4532:
2093 Settings.SDD1 = TRUE;
2094 break;
2095
2096 /* ST018*/
2097 case 0xF530:
2098 Settings.SETA = ST_018;
2099 SetSETA = NULL;
2100 GetSETA = NULL;
2101 Memory.SRAMSize = 2;
2102 SNESGameFixes.SRAMInitialValue = 0x00;
2103 break;
2104
2105 /* ST010/011*/
2106 case 0xF630:
2107 if (Memory.ROM[0x7FD7] == 0x09)
2108 {
2109 Settings.SETA = ST_011;
2110 SetSETA = &S9xSetST011;
2111 GetSETA = &S9xGetST011;
2112 }
2113 else
2114 {
2115 Settings.SETA = ST_010;
2116 SetSETA = &S9xSetST010;
2117 GetSETA = &S9xGetST010;
2118 }
2119
2120 Memory.SRAMSize = 2;
2121 SNESGameFixes.SRAMInitialValue = 0x00;
2122 break;
2123
2124 /* C4*/
2125 case 0xF320:
2126 Settings.C4 = TRUE;
2127 break;
2128 }
2129
2130 /* Map memory and calculate checksum */
2131
2132 MAP_INITIALIZE();
2133 Memory.CalculatedChecksum = 0;
2134
2135 /* SRAM size */
2136 Memory.SRAMMask = Memory.SRAMSize ? ((1 << (Memory.SRAMSize + 3)) * 128) - 1 : 0;
2137
2138 if (Memory.HiROM)
2139 {
2140 if (Settings.BS)
2141 /* Do nothing */;
2142 else
2143 if (Settings.SPC7110)
2144 Map_SPC7110HiROMMap();
2145 else
2146 if (Memory.ExtendedFormat != NOPE)
2147 Map_ExtendedHiROMMap();
2148 else
2149 if (Multi.cartType == 3)
2150 Map_SameGameHiROMMap();
2151 else
2152 {
2153 MAP_HIROMMAP();
2154 }
2155 }
2156 else
2157 {
2158 if (Settings.BS)
2159 /* Do nothing */;
2160 else if (Settings.SETA && Settings.SETA != ST_018)
2161 Map_SetaDSPLoROMMap();
2162 else if (Settings.SuperFX)
2163 Map_SuperFXLoROMMap();
2164 else if (Settings.SA1)
2165 Map_SA1LoROMMap();
2166 else if (Settings.SDD1)
2167 Map_SDD1LoROMMap();
2168 else if (Memory.ExtendedFormat != NOPE)
2169 {
2170 MAP_JUMBOLOROMMAP();
2171 }
2172 else if (strncmp(Memory.ROMName, "WANDERERS FROM YS", 17) == 0)
2173 Map_NoMAD1LoROMMap();
2174 else if (strncmp(Memory.ROMName, "SOUND NOVEL-TCOOL", 17) == 0 ||
2175 strncmp(Memory.ROMName, "DERBY STALLION 96", 17) == 0)
2176 Map_ROM24MBSLoROMMap();
2177 else if (strncmp(Memory.ROMName, "THOROUGHBRED BREEDER3", 21) == 0 ||
2178 strncmp(Memory.ROMName, "RPG-TCOOL 2", 11) == 0)
2179 {
2180 MAP_SRAM512KLOROMMAP();
2181 }
2182 else if (strncmp(Memory.ROMName, "ADD-ON BASE CASSETE", 19) == 0)
2183 {
2184 if (Multi.cartType == 4)
2185 {
2186 Memory.SRAMSize = Multi.sramSizeA;
2187 Map_SufamiTurboLoROMMap();
2188 }
2189 else
2190 {
2191 Memory.SRAMSize = 5;
2192 Map_SufamiTurboPseudoLoROMMap();
2193 }
2194 }
2195 else
2196 {
2197 MAP_LOROMMAP();
2198 }
2199 }
2200
2201 /* from NSRT */
2202 sum = 0;
2203
2204 if (Settings.BS && !Settings.BSXItself)
2205 sum = checksum_calc_sum(Memory.ROM, Memory.CalculatedSize) - checksum_calc_sum(Memory.ROM + (Memory.HiROM ? 0xffb0 : 0x7fb0), 48);
2206 else
2207 if (Settings.SPC7110)
2208 {
2209 sum = checksum_calc_sum(Memory.ROM, Memory.CalculatedSize);
2210 if (Memory.CalculatedSize == 0x300000)
2211 sum += sum;
2212 }
2213 else
2214 {
2215 if (Memory.CalculatedSize & 0x7fff)
2216 sum = checksum_calc_sum(Memory.ROM, Memory.CalculatedSize);
2217 else
2218 {
2219 uint32 length = Memory.CalculatedSize;
2220 sum = checksum_mirror_sum(Memory.ROM, &length, 0x800000);
2221 }
2222 }
2223
2224 Memory.CalculatedChecksum = sum;
2225
2226 isChecksumOK = (Memory.ROMChecksum + Memory.ROMComplementChecksum == 0xffff) &
2227 (Memory.ROMChecksum == Memory.CalculatedChecksum);
2228
2229 /* Build more ROM information */
2230
2231 /* CRC32 */
2232 if (!Settings.BS || Settings.BSXItself) /* Not BS Dump */
2233 Memory.ROMCRC32 = caCRC32(Memory.ROM, Memory.CalculatedSize, 0xffffffff);
2234 else /* Convert to correct format before scan */
2235 {
2236 int offset = Memory.HiROM ? 0xffc0 : 0x7fc0;
2237 /* Backup */
2238 uint8 BSMagic0 = Memory.ROM[offset + 22];
2239 uint8 BSMagic1 = Memory.ROM[offset + 23];
2240
2241 /* uCONSRT standard */
2242 Memory.ROM[offset + 22] = 0x42;
2243 Memory.ROM[offset + 23] = 0x00;
2244
2245 /* Calc */
2246 Memory.ROMCRC32 = caCRC32(Memory.ROM, Memory.CalculatedSize, 0xffffffff);
2247
2248 /* Convert back */
2249 Memory.ROM[offset + 22] = BSMagic0;
2250 Memory.ROM[offset + 23] = BSMagic1;
2251 }
2252
2253 /* NTSC/PAL */
2254 if (Settings.ForceNTSC)
2255 Settings.PAL = FALSE;
2256 else if (Settings.ForcePAL)
2257 Settings.PAL = TRUE;
2258 else if (!Settings.BS && (Memory.ROMRegion >= 2) && (Memory.ROMRegion <= 12))
2259 Settings.PAL = TRUE;
2260 else
2261 Settings.PAL = FALSE;
2262
2263 /* truncate cart name */
2264 Memory.ROMName[ROM_NAME_LEN - 1] = 0;
2265 if (strlen(Memory.ROMName))
2266 {
2267 char *p = Memory.ROMName + strlen(Memory.ROMName);
2268 if (p > Memory.ROMName + 21 && Memory.ROMName[20] == ' ')
2269 p = Memory.ROMName + 21;
2270 while (p > Memory.ROMName && *(p - 1) == ' ')
2271 p--;
2272 *p = 0;
2273 }
2274
2275 /* checksum */
2276 if (!isChecksumOK || ((uint32) Memory.CalculatedSize > (uint32) (((1 << (Memory.ROMSize - 7)) * 128) * 1024)))
2277 {
2278 }
2279
2280 if (Multi.cartType == 4)
2281 {
2282 }
2283
2284 /* Initialize emulation */
2285
2286 Timings.H_Max_Master = SNES_CYCLES_PER_SCANLINE;
2287 Timings.H_Max = Timings.H_Max_Master;
2288 Timings.HBlankStart = SNES_HBLANK_START_HC;
2289 Timings.HBlankEnd = SNES_HBLANK_END_HC;
2290 Timings.HDMAInit = SNES_HDMA_INIT_HC;
2291 Timings.HDMAStart = SNES_HDMA_START_HC;
2292 Timings.RenderPos = SNES_RENDER_START_HC;
2293 Timings.V_Max_Master = Settings.PAL ? SNES_MAX_PAL_VCOUNTER : SNES_MAX_NTSC_VCOUNTER;
2294 Timings.V_Max = Timings.V_Max_Master;
2295
2296 /* From byuu: The total delay time for both the initial (H)DMA sync (to the DMA clock),
2297 and the end (H)DMA sync (back to the last CPU cycle's mcycle rate (6, 8, or 12))
2298 always takes between 12-24 mcycles.
2299
2300 Possible delays: { 12, 14, 16, 18, 20, 22, 24 }
2301 XXX: Snes9x can't emulate this timing :( so let's use the average value... */
2302
2303 Timings.DMACPUSync = 18;
2304
2305 /* If the CPU is halted (i.e. for DMA) while /NMI goes low, the NMI will trigger
2306 after the DMA completes (even if /NMI goes high again before the DMA
2307 completes). In this case, there is a 24-30 cycle delay between the end of DMA
2308 and the NMI handler, time enough for an instruction or two.
2309
2310 Examples: Wild Guns, Mighty Morphin Power Rangers - The Fighting Edition */
2311
2312 Timings.NMIDMADelay = 24;
2313 Timings.IRQPendCount = 0;
2314
2315 /* Hack games */
2316
2317 Settings.BlockInvalidVRAMAccess = Settings.BlockInvalidVRAMAccessMaster;
2318
2319 /* Warnings */
2320
2321 /* Reject strange hacked games */
2322 if ((Memory.ROMCRC32 == 0x6810aa95) ||
2323 (Memory.ROMCRC32 == 0x340f23e5) ||
2324 (Memory.ROMCRC32 == 0x77fd806a) ||
2325 (MATCH_NN("HIGHWAY BATTLE 2")) ||
2326 (MATCH_NA("FX SKIING NINTENDO 96") && (Memory.ROM[0x7fda] == 0)) ||
2327 (MATCH_NN("HONKAKUHA IGO GOSEI") && (Memory.ROM[0xffd5] != 0x31)))
2328 {
2329 }
2330
2331 /* APU timing hacks */
2332
2333 Timings.APUSpeedup = 0;
2334 Timings.APUAllowTimeOverflow = FALSE;
2335
2336 if (!Settings.DisableGameSpecificHacks)
2337 {
2338 if (MATCH_ID("AVCJ")) /* Rendering Ranger R2*/
2339 Timings.APUSpeedup = 4;
2340
2341 if (MATCH_NA("GAIA GENSOUKI 1 JPN") || /* Gaia Gensouki*/
2342 MATCH_ID("JG ") || /* Illusion of Gaia*/
2343 MATCH_ID("CQ ") || /* Stunt Race FX*/
2344 MATCH_NA("SOULBLADER - 1") || /* Soul Blader*/
2345 MATCH_NA("SOULBLAZER - 1 USA") || /* Soul Blazer*/
2346 MATCH_NA("SLAP STICK 1 JPN") || /* Slap Stick*/
2347 MATCH_ID("E9 ") || /* Robotrek*/
2348 MATCH_NN("ACTRAISER") || /* Actraiser*/
2349 MATCH_NN("ActRaiser-2") || /* Actraiser 2*/
2350 MATCH_ID("AQT") || /* Tenchi Souzou, Terranigma*/
2351 MATCH_ID("ATV") || /* Tales of Phantasia*/
2352 MATCH_ID("ARF") || /* Star Ocean*/
2353 MATCH_ID("APR") || /* Zen-Nippon Pro Wrestling 2 - 3-4 Budoukan*/
2354 MATCH_ID("A4B") || /* Super Bomberman 4*/
2355 MATCH_ID("Y7 ") || /* U.F.O. Kamen Yakisoban - Present Ban*/
2356 MATCH_ID("Y9 ") || /* U.F.O. Kamen Yakisoban - Shihan Ban*/
2357 MATCH_ID("APB") || /* Super Bomberman - Panic Bomber W*/
2358 MATCH_NA("DARK KINGDOM") || /* Dark Kingdom*/
2359 MATCH_NA("ZAN3 SFC") || /* Zan III Spirits*/
2360 MATCH_NA("HIOUDEN") || /* Hiouden - Mamono-tachi Tono Chikai*/
2361 MATCH_NA("\xC3\xDD\xBC\xC9\xB3\xC0") || /* Tenshi no Uta*/
2362 MATCH_NA("FORTUNE QUEST") || /* Fortune Quest - Dice wo Korogase*/
2363 MATCH_NA("FISHING TO BASSING") || /* Shimono Masaki no Fishing To Bassing*/
2364 MATCH_NA("OHMONO BLACKBASS") || /* Oomono Black Bass Fishing - Jinzouko Hen*/
2365 MATCH_NA("MASTERS") || /* Harukanaru Augusta 2 - Masters*/
2366 MATCH_NA("SFC \xB6\xD2\xDD\xD7\xB2\xC0\xDE\xB0") || /* Kamen Rider*/
2367 MATCH_NA("ZENKI TENCHIMEIDOU") || /* Kishin Douji Zenki - Tenchi Meidou*/
2368 MATCH_NN("TokyoDome '95Battle 7") || /* Shin Nippon Pro Wrestling Kounin '95 - Tokyo Dome Battle 7*/
2369 MATCH_NN("SWORD WORLD SFC") || /* Sword World SFC/2*/
2370 MATCH_NN("LETs PACHINKO(") || /* BS Lets Pachinko Nante Gindama 1/2/3/4*/
2371 MATCH_NN("THE FISHING MASTER") || /* Mark Davis The Fishing Master*/
2372 MATCH_NN("Parlor") || /* Parlor mini/2/3/4/5/6/7, Parlor Parlor!/2/3/4/5*/
2373 MATCH_NA("HEIWA Parlor!Mini8") || /* Parlor mini 8*/
2374 MATCH_NN("SANKYO Fever! \xCC\xA8\xB0\xCA\xDE\xB0!")) /* SANKYO Fever! Fever!*/
2375 Timings.APUSpeedup = 1;
2376
2377 if (MATCH_NA ("EARTHWORM JIM 2") || /* Earthworm Jim 2*/
2378 MATCH_NA ("NBA Hangtime") || /* NBA Hang Time*/
2379 MATCH_NA ("MSPACMAN") || /* Ms Pacman*/
2380 MATCH_NA ("THE MASK") || /* The Mask*/
2381 MATCH_NA ("PRIMAL RAGE") || /* Primal Rage*/
2382 MATCH_NA ("DOOM TROOPERS") || /* Doom Troopers*/
2383 MATCH_NA ("PORKY PIGS HAUNTED") || /* Porky Pig's Haunted Holiday*/
2384 MATCH_NA ("Big Sky Trooper") || /* Big Sky Trooper*/
2385 MATCH_NA ("A35")) /* Mechwarrior 3050/Battle Tech 3050*/
2386 Timings.APUAllowTimeOverflow = TRUE;
2387
2388 /* SWAP MOSAIC HI-RES WITH HI-RES
2389
2390 We don't want Seiken Densetsu 3/Romancing Saga 3 unbearably
2391 slow in hi-res mosaic mode - no difference with these games
2392 between normal hi-res renderer and mosaic version - only double the FPS */
2393
2394 if (
2395 MATCH_NN("SeikenDensetsu3") ||
2396 MATCH_NA("SeikenDensetsu3Sample1") || /* Seiken Densetsu 3 */
2397 MATCH_NA("ROMANCING SAGA3")) /* Romancing Saga 3 */
2398 {
2399 PPU.DisableMosaicHack = FALSE;
2400 }
2401 else
2402 PPU.DisableMosaicHack = TRUE;
2403
2404 /* Speedup hack for Star Fox 2/Vortex */
2405 if (
2406 MATCH_NA("VORTEX") || /* Vortex */
2407 MATCH_NA("Super Street Fighter21") || /* Super Street Fighter II */
2408 MATCH_NA("STAR FOX") || /* Star Fox (US/JP)*/
2409 MATCH_NA("STAR WING") || /* Star Wing (EU)*/
2410 MATCH_NA("STAR FOX 2") || /* Star Fox 2 (Beta) */
2411 MATCH_NA("STARFOX2")) /* Star Fox 2 (SNES Classic) */
2412 PPU.SFXSpeedupHack = TRUE;
2413 else
2414 PPU.SFXSpeedupHack = FALSE;
2415
2416
2417 /* FORCIBLY DISABLE HIGH-RES */
2418
2419 if (
2420 MATCH_NA("DONKEY KONG COUNTRY") /* Donkey Kong Country */
2421 //|| MATCH_ID("ADNE") /* Donkey Kong Country 2 (US) */
2422 || MATCH_ID("AD8") /* Doom */
2423 )
2424 Settings.SupportHiRes = FALSE;
2425
2426
2427 /* DON'T RENDER SUBSCREEN */
2428
2429 /* Don't render subscreen for games that don't switch to high-res mode
2430 in-game or don't use hi-res at all - and yet still need to do stuff
2431 with the subscreen FPS improvement ranges from 7/10fps to 20/25fps
2432 depending on the game ( +25/30fps in some occassions - benchmarked
2433 on PC).
2434
2435 TODO: This glitches with rewind enabled (RetroArch), force-disable it
2436 when rewind is active */
2437 if(
2438 MATCH_NA("Super Metroid") /* Super Metroid*/
2439 || MATCH_NA("DONKEY KONG COUNTRY") /* Donkey Kong Country 1 */
2440 || MATCH_NA("AREA88") /* Area 88 */
2441 || MATCH_NA("U.N.Squadron") /* UN Squadron */
2442 || MATCH_NA("Perfect Eleven") /* Perfect Eleven - ISS1 */
2443 //|| MATCH_ID("ADNE") /* Donkey Kong Country 2 (US) */
2444 || MATCH_ID("AWJ") /* ISS Deluxe / World Soccer 2 Fighting Eleven */
2445 || MATCH_NA("JIM POWER THE LOST DIO") /* Jim Power The Lost Dimension */
2446 || MATCH_ID("A3C") /* Donkey Kong Country 3*/
2447 || MATCH_NA("Secret of MANA") /* Secret of Mana */
2448 || MATCH_NA("Street Fighter2 Turbo1") /* Street Fighter II Turbo */
2449 || MATCH_NA("Super Street Fighter21") /* Super Street Fighter II (US) */
2450 || MATCH_ID("A2J") /* Jurassic Park 2 */
2451 || MATCH_ID("AJL") /* Justice League */
2452 || MATCH_NA("JOE AND MAC") /* Joe and Mac */
2453 || MATCH_NA("JOE & MAC 2") /* Joe & Mac 2 */
2454 || MATCH_ID("J3") /* Joe & Mac 3 EU) */
2455 || MATCH_NA("JYUTEI SENKI") /* Jyutei Senki */
2456 || MATCH_ID("CQ ") /* Stunt Race FX */
2457 #if defined(_XBOX1) || defined(GEKKO)
2458 || MATCH_ID("AD8") /* Doom */
2459 #endif
2460 || MATCH_NA("T.M.H.T.4") /* Teenage Mutant Hero Turtles 4 - Turtles In Time (E) */
2461 || MATCH_NA("T.M.N.T.") /* Teenage Mutant Ninja Turtles 4 - Turtles In Time (J) */
2462 || MATCH_NA("T.M.N.T.4") /* Teenage Mutant Ninja Turtles 4 - Turtles In Time (AU) */
2463 || MATCH_NA("T.M.N.T. 4") /* Teenage Mutant Ninja Turtles 4 - Turtles In Time (US) */
2464 || MATCH_NA("T.M.N.T. MW") /* Teenage Mutant Ninja Turtles - Mutant Warriors (J) */
2465 || MATCH_NA("T.M.H.T TF") /* Teenage Mutant Hero Turtles - Tour Fighters (EU) */
2466 || MATCH_NA("T.M.N.T. TF") /* Teenage Mutant Ninja Turtles - Tour Fighters (AU) */
2467 || MATCH_NA("T.M.N.T.5") /* Teenage Mutant Ninja Turtles - Tour Fighters (U) */
2468 || MATCH_NA("SUPER CASTLEVANIA 4") /* Super Castlevania IV */
2469 || MATCH_NA("AKUMAJO DRACULA") /* Super Castlevania IV */
2470 || MATCH_ID("ATVE") /* Tales of Phantasia (EN) (DeJap)*/
2471 || MATCH_NA("MEGAMAN X") /* Mega Man X (US) */
2472 || MATCH_ID("A7R") /* Rockman / Mega Man 7 */
2473 || MATCH_NA("F-ZERO") /* Rockman / Mega Man 7 */
2474 || MATCH_NA("EQUINOX") /* Equinox */
2475 || MATCH_NA("SUPER MARIO KART") /* Super Mario Kart */
2476 || MATCH_ID("AR3") /* Mega Man X3 (JP/US) */
2477 || MATCH_NA("SECRET OF EVERMORE") /* Secret of Evermore*/
2478 || MATCH_ID("AKL") /* Killer Instinct*/
2479 || MATCH_NA("NBA JAM") /* NBA Jam */
2480 || MATCH_NA("PILOTWINGS") /* Pilotwings */
2481 || MATCH_NA("FINAL FIGHT") /* Final Fight */
2482 || MATCH_NA("FINAL FANTASY 6") /* Final Fantasy VI (JP)*/
2483 || MATCH_NA("FINAL FANTASY 3") /* Final Fantasy III (US)*/
2484 || MATCH_NA("ILLUSION OF GAIA USA") /* Illusion of Gaia (US)*/
2485 || MATCH_NA("GAIA GENSOUKI 1 JPN") /* Gaia Gensouki (JPN)*/
2486 || MATCH_ID("AEJ") /* Earthworm Jim*/
2487 || MATCH_ID("YI") /* Yoshi's Island*/
2488 || MATCH_NA("SUPER MARIOWORLD") /* Super Mario World*/
2489 || MATCH_NA("THE LEGEND OF ZELDA") /* Zelda 3*/
2490 || MATCH_NA("LA LEGENDE DE ZELDA") /* Zelda 3 (FR)*/
2491 || MATCH_NA("ZELDANODENSETSU") /* Zelda 3 (JPN)*/
2492 || MATCH_NA("SPARKSTER") /* Sparkster*/
2493 || MATCH_NA("SIMCITY") /* Sim City */
2494 || MATCH_NA("T2 ARCADE") /* T2 Arcade */
2495 || MATCH_NA("PLOK") /* Plok!*/
2496 || MATCH_NA("ALADDIN") /* Aladdin */
2497 || MATCH_NA("ActRaiser-2 JPN") /* ActRaiser 2 (JPN) */
2498 || MATCH_NA("ActRaiser-2 USA") /* ActRaiser 2 (US) */
2499 || MATCH_ID("A8") /* ActRaiser 2 (EU) */
2500 || MATCH_ID("APT") /* Pac In Time */
2501 || MATCH_ID("AXG") /*NBA Hangtime */
2502 || MATCH_NA("THE CHAOS ENGINE") /* Chaos Engine */
2503 || MATCH_ID("AWD") /* Weaponlord */
2504 || MATCH_NA("TALES OF PHANTASIA") /* Tales of Phantasia */
2505 || MATCH_NA("GS MIKAMI") /* GS Mikami - Joreishi wa Nice Body*/
2506 || MATCH_ID("ATQ") /* Theme Park */
2507 || MATCH_NA("TOTAL CARNAGE") /* Total Carnage */
2508 || MATCH_ID("AJOJ") /* Jikkyou Oshaberi Parodius*/
2509 || MATCH_NA("ROCK N' ROLL RACING") /* Rock 'n Roll Racing */
2510 || MATCH_NA("RISE OF THE ROBOTS") /* Rise Of The Robots*/
2511 || MATCH_ID("A3T") /* Top Gear 3000 */
2512 || MATCH_NA("MORTAL KOMBAT") /* Mortal Kombat I*/
2513 || MATCH_NA("MORTAL KOMBAT II") /* Mortal Kombat II*/
2514 || MATCH_NA("STAR FOX") /* Star Fox (US/JP)*/
2515 || MATCH_ID("ST2") /* Star Fox 2 */
2516 || MATCH_NA("STAR WING") /* Star Wing (EU)*/
2517 || MATCH_NA("TINYTOON adventures") /* Buster Busts Loose */
2518 || MATCH_ID("3Z") /* Demon's Crest*/
2519 || MATCH_NA("AXELAY") /* Axelay*/
2520 || MATCH_NA("JAKI CRUSH") /* Jaki Crush */
2521 || MATCH_NA("ZOMBIES") /* Zombies (EU)*/
2522 || MATCH_NA("THE JUNGLE BOOK") /* Jungle Book */
2523 || MATCH_NA("ZOMBIES ATE MY NEIGHB") /* Zombies Ate My Neighbors*/
2524 || MATCH_NA("UNIRACERS") /* Uniracers*/
2525 || MATCH_NA("UNIRALLY") /* Unirally*/
2526 || MATCH_NA("CHRONO TRIGGER") /* Chrono Trigger*/
2527 || MATCH_NA("JURASSIC PARK") /* Jurassic Park*/
2528 || MATCH_NA("THE MAGICAL QUEST") /* The Magical Quest*/
2529 || MATCH_NA("SOULBLAZER - 1 USA") /* Soul Blazer (US)*/
2530 || MATCH_NA("SOULBLAZER - 1 ENG") /* Soul Blazer (PAL)*/
2531 || MATCH_NA("SOULBLADER - 1") /* Soul Blader*/
2532 || MATCH_NA("GOKUJYOU PARODIUS") /* Gokujou Parodius*/
2533 || MATCH_ID("ABT") /* Adventures of Batman and Robin*/
2534 || MATCH_ID("5M") /* Mario All-Stars + World*/
2535 || MATCH_NA("SUPER MARIO ALL_STARS") /* Super Mario All-Stars (EU/US)*/
2536 || MATCH_NA("SUPERMARIO COLLECTION") /* Super Mario Collection (JP)*/
2537 || MATCH_ID("4Q") /* Super Punch-Out*/
2538 || MATCH_NA("HARVEST MOON") /* Harvest Moon*/
2539 || MATCH_ID("ADZ") /* Dracula X*/
2540 || MATCH_ID("A3M") /* Mortal Kombat 3*/
2541 || MATCH_ID("AM4J") /* Do-Re-Mi Fantasy - Milon no Dokidoki Daibouken*/
2542 || MATCH_NA("BT IN BATTLEMANIACS") /* Battletoads in Battlemaniacs*/
2543 || MATCH_NA("SPACE MEGAFORCE") /* Space Megaforce (US)*/
2544 || MATCH_ID("ARX") /* Mega Man X2 */
2545 || MATCH_NA("SUPER ALESTE") /* Super Aleste (EU/JP)*/
2546 || MATCH_NA("VALKEN") /* Assault Suits Valken (JP)*/
2547 || MATCH_NA("CYBERNATOR") /* Cybernator (EU/US)*/
2548 || MATCH_NA("SUPER BOMBERMAN") /* Super Bomberman 1*/
2549 || MATCH_NA("SUPER BOMBERMAN2") /* Super Bomberman 2*/
2550 || MATCH_ID("AS6") /* Super Bomberman 3*/
2551 || MATCH_ID("A4B") /* Super Bomberman 4*/
2552 || MATCH_ID("AYL") /* Tetris Attack*/
2553 || MATCH_NA("POCKY ROCKY") /* Pocky & Rocky (US/EU)*/
2554 || MATCH_NA("KIKIKAIKAI") /* Kiki Kaikai (JP)*/
2555 || MATCH_ID("ANI") /* Lufia 2 / Estpolis Denki 2*/
2556 || MATCH_ID("AQT") /* Terranigma*/
2557 || MATCH_NA("twinbee") /* Twinbee Rainbow Bell Adventures*/
2558 || MATCH_ID("AO7") /* Tactics Ogre*/
2559 || MATCH_NA("Ogre Battle USA") /* Ogre Battle (US)*/
2560 || MATCH_ID("AQ3") /* Dragon Quest 3*/
2561 || MATCH_NA("DRAGONQUEST5") /* Dragon Quest 5*/
2562 || MATCH_ID("AQ6J") /* Dragon Quest 6*/
2563 || MATCH_NA("DARIUS FORCE") /* Darius Force*/
2564 || MATCH_ID("AGC") /* Front Mission*/
2565 || MATCH_ID("AZGJ") /* Front Mission Gun Hazard*/
2566 || MATCH_NA("GANBARE GOEMON") /* Ganbare Goemon (JP)*/
2567 || MATCH_NA("GANBARE GOEMON 2") /* Ganbare Goemon 2*/
2568 || MATCH_NA("mystical ninja") /* Legend of Mystical Ninja (US/EU)*/
2569 || MATCH_NA("NOSFERATU") /* Nosferatu*/
2570 || MATCH_NA("PAC ATTACK") /* Pac Attack*/
2571 || MATCH_NA("PARODIUS") /* Parodius 1*/
2572 || MATCH_NA("PRINCE OF PERSIA") /* Prince of Persia*/
2573 || MATCH_NA("FINAL FANTASY 5") /* Final Fantasy 5*/
2574 || MATCH_NA("OUT OF THIS WORLD") /* Out Of This World (US)*/
2575 || MATCH_NA("OUTER WORLD") /* Outer World (JP)*/
2576 || MATCH_NA("ANOTHER WORLD") /* Another World (EU)*/
2577 || MATCH_ID("ABZE") /* Ballz 3D*/
2578 || MATCH_ID("AXSP") /* Winter Gold*/
2579 || MATCH_ID("APJJ") /* Wonder Project J*/
2580 || MATCH_NA("KRUSTYS SUPER FUNHOUSE") /* Krustys Super Fun House*/
2581 || MATCH_NA("KRUSTYS SUPERFUNHOUSE") /* Krustys Super Fun House*/
2582 || MATCH_NA("LEMMINGS") /* Lemmings 1*/
2583 || MATCH_ID("A3Z") /* Ultimate Mortal Kombat 3*/
2584 || MATCH_ID("ARFJ") /* Star Ocean*/
2585 || MATCH_ID("AXBE") /* Bahamut Lagoon*/
2586 || MATCH_ID("ARQ") /* Realm */
2587 || MATCH_NA("S O S") /* SOS */
2588 || MATCH_NA("SUPER DONKEY KONG") /* Super Donkey Kong */
2589 || MATCH_ID("AC6J") /* Cu-On-Pa*/
2590 || MATCH_ID("ASR") /* Street Racer*/
2591 || MATCH_NA("SUPER WIDGET") /* Super Widget*/
2592 || MATCH_NA("WILD GUNS") /* Wild Guns */
2593 || MATCH_NA("R-TYPE 3") /* R-Type 3*/
2594 || MATCH_NA("THE NINJAWARRIORS") /* Ninja Warriors */
2595 || MATCH_ID("ARW") /* Super Mario RPG*/
2596 || MATCH_NA("SHVC FIREEMBLEM") /* Fire Emblem - Monshou no Nazo*/
2597 || MATCH_ID("BFRJ") /* Fire Emblem - Thracia 776*/
2598 || MATCH_ID("A32J") /* Fire Emblem - Seisen no Keifu*/
2599 || MATCH_ID("AR9") /* Primal Rage*/
2600 || MATCH_ID("APUE") /* Prehistorik Man*/
2601 || MATCH_ID("ALSJ") /* Lady Stalker*/
2602 || MATCH_NA("ROCKMAN&FORTE") /* Rockman & Forte*/
2603 || MATCH_NA("SUPER SWIV") /* Super SWIV*/
2604 || MATCH_NA("CONTRA3 THE ALIEN WARS") /* Contra 3 The Alien Wars*/
2605 || MATCH_NA("EARTHWORM JIM 2") /* Earthworm Jim 2*/
2606 || MATCH_NA("CHOHMAKAIMURA") /* Chou Makai Mura*/
2607 || MATCH_NA("SUPER GHOULS'N GHOSTS") /* Super Ghouls 'n Ghosts*/
2608 || MATCH_NA("X-KALIBER 2097") /* X-Kaliber 2097*/
2609 || MATCH_NA("PHALANX") /* Phalanx */
2610 || MATCH_NA("FINAL FIGHT 2") /* Final Fight 2*/
2611 || MATCH_NA("SUPER TURRICAN 2") /* Super Turrican 2*/
2612 || MATCH_NA("DUNGEON MASTER") /* Dungeon Master*/
2613 || MATCH_NA("DOOM TROOPERS") /* Doom Troopers*/
2614 || MATCH_NA("DOOM") /* Doom */
2615 || MATCH_NA("XAK 1") /* Xak 1*/
2616 || MATCH_NA("XARDION") /* Xardion*/
2617 )
2618 PPU.RenderSub = FALSE;
2619 else
2620 PPU.RenderSub = TRUE;
2621
2622 if(
2623 //MATCH_NA("Super Metroid") /* Super Metroid*/
2624 //|| MATCH_NA("DONKEY KONG COUNTRY") /* Donkey Kong Country 1 */
2625 //|| MATCH_NA("AREA88") /* Area 88 */
2626 //|| MATCH_NA("U.N.Squadron") /* UN Squadron */
2627 //|| MATCH_NA("Perfect Eleven") /* Perfect Eleven - ISS1 */
2628 //MATCH_ID("ADNE") /* Donkey Kong Country 2 (US) */
2629 //|| MATCH_ID("AWJ") /* ISS Deluxe / World Soccer 2 Fighting Eleven */
2630 //|| MATCH_NA("JIM POWER THE LOST DIO") /* Jim Power The Lost Dimension */
2631 //|| MATCH_ID("A3C") /* Donkey Kong Country 3*/
2632 //|| MATCH_NA("Secret of MANA") /* Secret of Mana */
2633 //|| MATCH_ID("A2J") /* Jurassic Park 2 */
2634 //|| MATCH_ID("AJL") /* Justice League */
2635 //|| MATCH_NA("JOE AND MAC") /* Joe and Mac */
2636 //|| MATCH_NA("JOE & MAC 2") /* Joe & Mac 2 */
2637 //|| MATCH_ID("J3") /* Joe & Mac 3 EU) */
2638 //|| MATCH_NA("JYUTEI SENKI") /* Jyutei Senki */
2639 //|| MATCH_ID("CQ ") /* Stunt Race FX */
2640 #if defined(_XBOX1) || defined(GEKKO)
2641 //|| MATCH_ID("AD8") /* Doom */
2642 //|| MATCH_ID("A3D") /* Seiken Densetsu 3 */
2643 //|| MATCH_NA("SeikenDensetsu3Sample1") /* Seiken Densetsu 3 */
2644 //|| MATCH_NA("ROMANCING SAGA3") /* Romancing Saga 3 */
2645 #endif
2646 //|| MATCH_NA("T.M.H.T.4") /* Teenage Mutant Hero Turtles 4 - Turtles In Time (E) */
2647 //|| MATCH_NA("T.M.N.T.") /* Teenage Mutant Ninja Turtles 4 - Turtles In Time (J) */
2648 //|| MATCH_NA("T.M.N.T.4") /* Teenage Mutant Ninja Turtles 4 - Turtles In Time (AU) */
2649 //|| MATCH_NA("T.M.N.T. 4") /* Teenage Mutant Ninja Turtles 4 - Turtles In Time (US) */
2650 MATCH_NA("T.M.N.T. MW") /* Teenage Mutant Ninja Turtles - Mutant Warriors (J) */
2651 || MATCH_NA("T.M.H.T TF") /* Teenage Mutant Hero Turtles - Tour Fighters (EU) */
2652 || MATCH_NA("T.M.N.T. TF") /* Teenage Mutant Ninja Turtles - Tour Fighters (AU) */
2653 || MATCH_NA("T.M.N.T.5") /* Teenage Mutant Ninja Turtles - Tour Fighters (U) */
2654 //|| MATCH_NA("SUPER CASTLEVANIA 4") /* Super Castlevania IV */
2655 //|| MATCH_NA("AKUMAJO DRACULA") /* Super Castlevania IV */
2656 //|| MATCH_ID("ATVE") /* Tales of Phantasia (EN) (DeJap)*/
2657 //|| MATCH_NA("MEGAMAN X") /* Mega Man X (US) */
2658 //|| MATCH_ID("A7R") /* Rockman / Mega Man 7 */
2659 //|| MATCH_NA("F-ZERO") /* Rockman / Mega Man 7 */
2660 //|| MATCH_NA("EQUINOX") /* Equinox */
2661 //|| MATCH_NA("SUPER MARIO KART") /* Super Mario Kart */
2662 //|| MATCH_ID("AR3") /* Mega Man X3 (JP/US) */
2663 //|| MATCH_NA("SECRET OF EVERMORE") /* Secret of Evermore*/
2664 || MATCH_ID("AKL") /* Killer Instinct*/
2665 //|| MATCH_NA("NBA JAM") /* NBA Jam */
2666 //|| MATCH_NA("PILOTWINGS") /* Pilotwings */
2667 //|| MATCH_NA("FINAL FIGHT") /* Final Fight */
2668 //|| MATCH_NA("FINAL FANTASY 6") /* Final Fantasy VI (JP)*/
2669 //|| MATCH_NA("FINAL FANTASY 3") /* Final Fantasy III (US)*/
2670 //|| MATCH_NA("ILLUSION OF GAIA USA") /* Illusion of Gaia (US)*/
2671 //|| MATCH_NA("GAIA GENSOUKI 1 JPN") /* Gaia Gensouki (JPN)*/
2672 //|| MATCH_ID("AEJ") /* Earthworm Jim*/
2673 //|| MATCH_ID("AFJ") /* Kirby's Dreamland 3 */
2674 || MATCH_NA("SUPER MARIOWORLD") /* Super Mario World*/
2675 //|| MATCH_NA("THE LEGEND OF ZELDA") /* Zelda 3*/
2676 //|| MATCH_NA("LA LEGENDE DE ZELDA") /* Zelda 3 (FR)*/
2677 //|| MATCH_NA("ZELDANODENSETSU") /* Zelda 3 (JPN)*/
2678 //|| MATCH_NA("SPARKSTER") /* Sparkster*/
2679 //|| MATCH_NA("SIMCITY") /* Sim City */
2680 //|| MATCH_NA("T2 ARCADE") /* T2 Arcade */
2681 //|| MATCH_NA("PLOK") /* Plok!*/
2682 //|| MATCH_NA("ALADDIN") /* Aladdin */
2683 //|| MATCH_NA("ActRaiser-2 JPN") /* ActRaiser 2 (JPN) */
2684 //|| MATCH_NA("ActRaiser-2 USA") /* ActRaiser 2 (US) */
2685 //|| MATCH_ID("A8") /* ActRaiser 2 (EU) */
2686 //|| MATCH_ID("APT") /* Pac In Time */
2687 //|| MATCH_ID("AXG") /*NBA Hangtime */
2688 //|| MATCH_NA("THE CHAOS ENGINE") /* Chaos Engine */
2689 //|| MATCH_ID("AWD") /* Weaponlord */
2690 //|| MATCH_NA("TALES OF PHANTASIA") /* Tales of Phantasia */
2691 //|| MATCH_NA("GS MIKAMI") /* GS Mikami - Joreishi wa Nice Body*/
2692 //|| MATCH_ID("ATQ") /* Theme Park */
2693 //|| MATCH_NA("TOTAL CARNAGE") /* Total Carnage */
2694 || MATCH_ID("AJOJ") /* Jikkyou Oshaberi Parodius*/
2695 //|| MATCH_NA("ROCK N' ROLL RACING") /* Rock 'n Roll Racing */
2696 //|| MATCH_NA("RISE OF THE ROBOTS") /* Rise Of The Robots*/
2697 //|| MATCH_ID("A3T") /* Top Gear 3000 */
2698 //|| MATCH_NA("MORTAL KOMBAT") /* Mortal Kombat I*/
2699 //|| MATCH_NA("MORTAL KOMBAT II") /* Mortal Kombat II*/
2700 //|| MATCH_NA("STAR FOX") /* Star Fox (US/JP)*/
2701 //|| MATCH_ID("ST2") /* Star Fox 2 */
2702 //|| MATCH_NA("STAR WING") /* Star Wing (EU)*/
2703 //|| MATCH_NA("TINYTOON adventures") /* Buster Busts Loose */
2704 //|| MATCH_ID("3Z") /* Demon's Crest*/
2705 //|| MATCH_NA("AXELAY") /* Axelay*/
2706 //|| MATCH_NA("JAKI CRUSH") /* Jaki Crush */
2707 //|| MATCH_NA("ZOMBIES") /* Zombies (EU)*/
2708 //|| MATCH_NA("THE JUNGLE BOOK") /* Jungle Book */
2709 //|| MATCH_NA("ZOMBIES ATE MY NEIGHB") /* Zombies Ate My Neighbors*/
2710 //|| MATCH_NA("UNIRACERS") /* Uniracers*/
2711 //|| MATCH_NA("UNIRALLY") /* Unirally*/
2712 //|| MATCH_NA("CHRONO TRIGGER") /* Chrono Trigger*/
2713 //|| MATCH_NA("JURASSIC PARK") /* Jurassic Park*/
2714 //|| MATCH_NA("THE MAGICAL QUEST") /* The Magical Quest*/
2715 //|| MATCH_NA("SOULBLAZER - 1 USA") /* Soul Blazer (US)*/
2716 //|| MATCH_NA("SOULBLAZER - 1 ENG") /* Soul Blazer (PAL)*/
2717 //|| MATCH_NA("SOULBLADER - 1") /* Soul Blader*/
2718 //|| MATCH_NA("GOKUJYOU PARODIUS") /* Gokujou Parodius*/
2719 //|| MATCH_ID("ABT") /* Adventures of Batman and Robin*/
2720 //|| MATCH_ID("5M") /* Mario All-Stars + World*/
2721 //|| MATCH_NA("SUPER MARIO ALL_STARS") /* Super Mario All-Stars (EU/US)*/
2722 //|| MATCH_NA("SUPERMARIO COLLECTION") /* Super Mario Collection (JP)*/
2723 //|| MATCH_ID("4Q") /* Super Punch-Out*/
2724 //|| MATCH_NA("HARVEST MOON") /* Harvest Moon*/
2725 //|| MATCH_ID("ADZ") /* Dracula X*/
2726 //|| MATCH_ID("A3M") /* Mortal Kombat 3*/
2727 //|| MATCH_ID("AM4J") /* Do-Re-Mi Fantasy - Milon no Dokidoki Daibouken*/
2728 //|| MATCH_NA("BT IN BATTLEMANIACS") /* Battletoads in Battlemaniacs*/
2729 //|| MATCH_NA("SPACE MEGAFORCE") /* Space Megaforce (US)*/
2730 //|| MATCH_ID("ARX") /* Mega Man X2 */
2731 //|| MATCH_NA("SUPER ALESTE") /* Super Aleste (EU/JP)*/
2732 //|| MATCH_NA("VALKEN") /* Assault Suits Valken (JP)*/
2733 //|| MATCH_NA("CYBERNATOR") /* Cybernator (EU/US)*/
2734 //|| MATCH_NA("SUPER BOMBERMAN") /* Super Bomberman 1*/
2735 //|| MATCH_NA("SUPER BOMBERMAN2") /* Super Bomberman 2*/
2736 //|| MATCH_ID("AS6") /* Super Bomberman 3*/
2737 //|| MATCH_ID("A4B") /* Super Bomberman 4*/
2738 //|| MATCH_ID("AYL") /* Tetris Attack*/
2739 //|| MATCH_NA("POCKY ROCKY") /* Pocky & Rocky (US/EU)*/
2740 //|| MATCH_NA("KIKIKAIKAI") /* Kiki Kaikai (JP)*/
2741 //|| MATCH_ID("ANI") /* Lufia 2 / Estpolis Denki 2*/
2742 //|| MATCH_ID("AQT") /* Terranigma*/
2743 //|| MATCH_NA("twinbee") /* Twinbee Rainbow Bell Adventures*/
2744 //|| MATCH_ID("AO7") /* Tactics Ogre*/
2745 //|| MATCH_NA("Ogre Battle USA") /* Ogre Battle (US)*/
2746 //|| MATCH_ID("AQ3") /* Dragon Quest 3*/
2747 //|| MATCH_NA("DRAGONQUEST5") /* Dragon Quest 5*/
2748 //|| MATCH_ID("AQ6J") /* Dragon Quest 6*/
2749 //|| MATCH_NA("DARIUS FORCE") /* Darius Force*/
2750 //|| MATCH_ID("AZGJ") /* Front Mission Gun Hazard*/
2751 //|| MATCH_NA("GANBARE GOEMON") /* Ganbare Goemon (JP)*/
2752 //|| MATCH_NA("GANBARE GOEMON 2") /* Ganbare Goemon 2*/
2753 //|| MATCH_NA("mystical ninja") /* Legend of Mystical Ninja (US/EU)*/
2754 //|| MATCH_NA("NOSFERATU") /* Nosferatu*/
2755 //|| MATCH_NA("PAC ATTACK") /* Pac Attack*/
2756 //|| MATCH_NA("PARODIUS") /* Parodius 1*/
2757 //|| MATCH_NA("PRINCE OF PERSIA") /* Prince of Persia*/
2758 //|| MATCH_NA("FINAL FANTASY 5") /* Final Fantasy 5*/
2759 //|| MATCH_NA("OUT OF THIS WORLD") /* Out Of This World (US)*/
2760 //|| MATCH_NA("OUTER WORLD") /* Outer World (JP)*/
2761 //|| MATCH_NA("ANOTHER WORLD") /* Another World (EU)*/
2762 //|| MATCH_ID("ABZE") /* Ballz 3D*/
2763 //|| MATCH_ID("AXSP") /* Winter Gold*/
2764 //|| MATCH_ID("APJJ") /* Wonder Project J*/
2765 //|| MATCH_NA("KRUSTYS SUPER FUNHOUSE") /* Krustys Super Fun House*/
2766 //|| MATCH_NA("KRUSTYS SUPERFUNHOUSE") /* Krustys Super Fun House*/
2767 //|| MATCH_NA("LEMMINGS") /* Lemmings 1*/
2768 //|| MATCH_ID("A3Z") /* Ultimate Mortal Kombat 3*/
2769 //|| MATCH_ID("ARFJ") /* Star Ocean*/
2770 //|| MATCH_ID("AXBE") /* Bahamut Lagoon*/
2771 //|| MATCH_ID("ARQ") /* Realm */
2772 //|| MATCH_NA("S O S") /* SOS */
2773 //|| MATCH_NA("SUPER DONKEY KONG") /* Super Donkey Kong */
2774 //|| MATCH_ID("AC6J") /* Cu-On-Pa*/
2775 //|| MATCH_ID("ASR") /* Street Racer*/
2776 //|| MATCH_NA("SUPER WIDGET") /* Super Widget*/
2777 //|| MATCH_NA("WILD GUNS") /* Wild Guns */
2778 //|| MATCH_NA("R-TYPE 3") /* R-Type 3*/
2779 //|| MATCH_NA("THE NINJAWARRIORS") /* Ninja Warriors */
2780 //|| MATCH_ID("ARW") /* Super Mario RPG*/
2781 //|| MATCH_NA("SHVC FIREEMBLEM") /* Fire Emblem - Monshou no Nazo*/
2782 //|| MATCH_ID("BFRJ") /* Fire Emblem - Thracia 776*/
2783 //|| MATCH_ID("A32J") /* Fire Emblem - Seisen no Keifu*/
2784 //|| MATCH_ID("AR9") /* Primal Rage*/
2785 //|| MATCH_ID("APUE") /* Prehistorik Man*/
2786 //|| MATCH_ID("ALSJ") /* Lady Stalker*/
2787 //|| MATCH_NA("ROCKMAN&FORTE") /* Rockman & Forte*/
2788 //|| MATCH_NA("SUPER SWIV") /* Super SWIV*/
2789 //|| MATCH_NA("CONTRA3 THE ALIEN WARS") /* Contra 3 The Alien Wars*/
2790 //|| MATCH_NA("EARTHWORM JIM 2") /* Earthworm Jim 2*/
2791 //|| MATCH_NA("CHOHMAKAIMURA") /* Chou Makai Mura*/
2792 //|| MATCH_NA("SUPER GHOULS'N GHOSTS") /* Super Ghouls 'n Ghosts*/
2793 //|| MATCH_NA("X-KALIBER 2097") /* X-Kaliber 2097*/
2794 //|| MATCH_NA("PHALANX") /* Phalanx */
2795 //|| MATCH_NA("FINAL FIGHT 2") /* Final Fight 2*/
2796 //|| MATCH_NA("SUPER TURRICAN 2") /* Super Turrican 2*/
2797 //|| MATCH_NA("DUNGEON MASTER") /* Dungeon Master*/
2798 //|| MATCH_NA("DOOM TROOPERS") /* Doom Troopers*/
2799 //|| MATCH_NA("DOOM") /* Doom */
2800 //|| MATCH_NA("XAK 1") /* Xak 1*/
2801 //|| MATCH_NA("XARDION") /* Xardion*/
2802 )
2803 coldata_update_screen = FALSE;
2804 else
2805 coldata_update_screen = TRUE;
2806
2807 Settings.SpeedhackGameID = SPEEDHACK_NONE;
2808
2809 /* Clipping hack - gains around 5-7 extra fps - only use it
2810 for specific games where nothing breaks with this hack on */
2811
2812 if(
2813 MATCH_NA("FINAL FANTASY 6") /* Final Fantasy VI (JP) */
2814 || MATCH_NA("FINAL FANTASY 3") /* Final Fantasy III (US) */
2815 )
2816 PPU.FullClipping = FALSE;
2817 else
2818 PPU.FullClipping = TRUE;
2819
2820 /* SPEED HACK PATHS */
2821 if(
2822 MATCH_NA("DONKEY KONG COUNTRY") /* Donkey Kong Country 1 */
2823 )
2824 Settings.SpeedhackGameID = SPEEDHACK_DKC1;
2825
2826 if(
2827 MATCH_NA("FINAL FANTASY 6") /* Final Fantasy VI (JP) */
2828 || MATCH_NA("FINAL FANTASY 3") /* Final Fantasy III (US) */
2829 )
2830 Settings.SpeedhackGameID = SPEEDHACK_FF6;
2831
2832 /* Check if Chrono Trigger is loaded, if so, we need to set a variable to
2833 true to get rid of an annoying mid-frame resolution switch to 256x239
2834 which can cause an undesirable flicker/breakup of the screen for a
2835 split second - this happens whenever the game switches from normal
2836 mode to battle mode and vice versa */
2837 if( MATCH_NC("CHRONO TRIGGER") || /* Chrono Trigger */
2838 MATCH_ID("ACT") ||
2839 MATCH_ID("AC9J") /* Chrono Trigger (Sample) */
2840 )
2841 Settings.SpeedhackGameID = SPEEDHACK_CT;
2842
2843 if(
2844 MATCH_NA("STAR FOX") || /* Star Fox (US/JP)*/
2845 MATCH_NA("STAR WING")) /* Star Wing (EU)*/
2846 Settings.SpeedhackGameID = SPEEDHACK_STAR_FOX_1;
2847
2848 #if 0
2849 if(MATCH_ID("AKL")) /* Killer Instinct*/
2850 Settings.SpeedhackGameID = SPEEDHACK_KILLER_INSTINCT;
2851 else if(
2852 MATCH_NA("Super Metroid") /* Super Metroid*/
2853 )
2854 Settings.SpeedhackGameID = SPEEDHACK_SUPER_METROID;
2855 #endif
2856
2857 if( MATCH_NA("SUPER MARIOWORLD")) /* Super Mario World*/
2858 Settings.SpeedhackGameID = SPEEDHACK_SUPER_MARIO_WORLD;
2859
2860 }
2861
2862 {
2863 unsigned i;
2864 const struct {
2865 const char *fmt;
2866 int val;
2867 } fmt_val[6] = {
2868 { "PPU.RenderSub = %d", PPU.RenderSub },
2869 { "PPU.FullClipping = %d", PPU.FullClipping },
2870 { "Settings.Transparency = %d", Settings.Transparency },
2871 { "Settings.SpeedhackGameID = %d", Settings.SpeedhackGameID },
2872 { "PPU.SFXSpeedupHack = %d", PPU.SFXSpeedupHack },
2873 { "coldata_update_screen = %d", coldata_update_screen }
2874 };
2875
2876 for (i = 0; i < 6; i++)
2877 {
2878 snprintf(String, sizeof(String), fmt_val[i].fmt, fmt_val[i].val);
2879 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, String);
2880 }
2881 }
2882
2883 if (Settings.AccessoryAutoDetection == ACCESSORY_AUTODETECTION_CONFIRM)
2884 {
2885 /* Multitap accessory detection */
2886 if(
2887 MATCH_NN("BARKLEY") || /* Barkley Shut Up and Jam!*/
2888 MATCH_ID("ABCJ") || /* Battle Cross*/
2889 MATCH_NA("Bill Walsh College FB1") || /* Bill Walsh College Football*/
2890 MATCH_ID("ANYE") || /* College Slam*/
2891 MATCH_ID("AC3J") || /* Crystal Beans from Dungeon Explorer*/
2892 MATCH_NC("Bruce Lee") || /* Dragon - Bruce Lee Story*/
2893 MATCH_ID("AVS") || /* Fever Pitch Soccer (EU) (*)*/
2894 /* Head-On Soccer (US) (*)*/
2895 MATCH_NA("FURI-FURI GIRLS") || /* Furi-Furi Girls*/
2896 MATCH_NA("HAT TRICK HERO 2") || /* Hat Trick Hero 2*/
2897 MATCH_NA("HEBEREKE NO PUZZLE") || /* Hebereke no Oishii Puzzle wa Irimasenka*/
2898 MATCH_ID("AWJ") || /* International Superstar Soccer Deluxe (EU/US) (*)*/
2899 /* Jikkyou World Soccer 2 - Fighting Eleven (JP) (*)*/
2900 MATCH_NA("J-LEAGUE SUPER SOCCER0") || /* J-League Super Soccer (JP)*/
2901 /* Virtual Soccer (EU)*/
2902 MATCH_NA("JIGSAW PARTY") || /* Jigsaw Party (US) (*)*/
2903 /* Pieces (JP)*/
2904 MATCH_NA("JIMMY CONNORS TENNIS") || /* Jimmy Connors Pro Tennis Tour*/
2905 MATCH_NA("LAS VEGAS DREAM") || /* Las Vegas Dream in Golden Paradise (JP) (*)*/
2906 /* Vegas Stakes (EU/US)*/
2907 MATCH_ID("ALT") || /* Looney Tunes B-Ball (US) (*)*/
2908 /* Looney Tunes Basketball (EU) (*)*/
2909 MATCH_ID("AYHJ") || /* Mizuki Shigeru no Youkai Hyakkiyakou*/
2910 MATCH_ID("A3VJ") || /* Multi Play Volleyball*/
2911 MATCH_NA("MUSCLE BOMBER") || /* Muscle Bomber: The Body Explosion (JP) (*)*/
2912 /* Saturday Night Slam Masters (US)*/
2913 MATCH_ID("CHAMP WRESTLING") || /* Natsume Championship Wrestling*/
2914 MATCH_ID("ANJ") || /* NBA Give 'n Go*/
2915 MATCH_ID("AXG") || /* NBA Hangtime*/
2916 MATCH_ID("AJT") || /* NBA Jam Tournament Edition (EU/US/JP)*/
2917 MATCH_NA("NBA JAM") || /* NBA Jam*/
2918 MATCH_ID("AFIE") || /* NCAA Final Four Basketball*/
2919 MATCH_ID("AFBE") || /* NCAA Football*/
2920 MATCH_ID("Q9") || /* NFL Quarterback Club / NFL Quarterback Club '95*/
2921 MATCH_ID("AQB") || /* NFL Quarterback Club '96*/
2922 MATCH_NA("PIECES") ||
2923 MATCH_ID("Z5") || /* Pieces (JP) (*)*/
2924 /* Jigsaw Party (US)*/
2925 MATCH_ID("ARVE") || /* Rap Jam - Volume One*/
2926 MATCH_NA("RUSHING BEAT SYURA") || /* Rushing Beat Shura (JP) (*)*/
2927 /* The Peace Keepers (US)*/
2928 MATCH_NA("S.Night SLAM MASTERS") || /* Saturday Night Slam Masters (US) (*)*/
2929 /* Muscle Bomber: The Body Explosion (JP)*/
2930 MATCH_NA("Secret of MANA") || /* Secret of Mana (EU/US) (*)*/
2931 /* Seiken Densetsu 2 (JP)*/
2932 MATCH_NA("SeikenDensetsu 2") || /* Seiken Densetsu 2 (JP) (*) / */
2933 /* Secret of Mana (EU/US)*/
2934 MATCH_NN("SeikenDensetsu3") || /* Seiken Densetsu 3 (in case you use*/
2935 /* 3-player IPS patch)*/
2936 MATCH_NA("SMASH TENNIS") || /* Smash Tennis (EU) (*) / */
2937 /* Super Family Tennis (JP)*/
2938 /*FIXME: TODO - Add CRC32 for Super Family Tennis - CRC32: 2BCBFF26*/
2939 MATCH_ID("ASR") || /* Street Racer*/
2940 MATCH_NA("SUGOI HEBEREKE") || /* Sugoi Hebereke*/
2941 MATCH_NA("Sugoro Quest++") || /* Sugoro Quest++: Dicenics*/
2942 MATCH_ID("AO9") || /* Summer Olympics*/
2943 MATCH_ID("AS6") || /* Super Bomberman 3*/
2944 MATCH_ID("A4BJ") || /* Super Bomberman 4*/
2945 MATCH_ID("A5SJ") || /* Super Bomberman 5*/
2946 MATCH_ID("AK8J") || /* Super Bomberman 5 - Caravan Event Ban*/
2947 MATCH_ID("APBJ") || /* Super Bomberman Panic Bomber W*/
2948 MATCH_ID("AF5J") || /* Super Fire Pro Wrestling X*/
2949 MATCH_ID("AP4J") || /* Super Fire Pro Wrestling Special*/
2950 MATCH_ID("AQQJ") || /* Super Fire Pro Wrestling - Queen's Special*/
2951 MATCH_ID("A7PJ") || /* Super Puyo Puyo Tsuu Remix*/
2952 MATCH_ID("AT3J") || /* Super Tetris 3*/
2953 MATCH_ID("AFY") || /* Syndicate*/
2954 MATCH_NA("THE PEACE KEEPERS") || /* The Peace Keepers (US) (*)*/
2955 /* Rushing Beat Shura (JP)*/
2956 MATCH_NA("Tiny Toon Sports") || /* Tiny Toon Adventures: Dotabata Daiundoukai (JP) (*)*/
2957 /* Tiny Toon Adventures: Wacky Sports Challenge (US) (*)*/
2958 /* Tiny Toon Adventures: Wild & Wacky Sports (EU) (*)*/
2959 MATCH_ID("A3T") || /* Top Gear 3000 (EU/US) (*)*/
2960 /* Planet's Champ TG 3000 (JP) (*)*/
2961 MATCH_NA("VEGAS STAKES") || /* Vegas Stakes (EU/US) (*)*/
2962 /* Las Vegas Dream in Golden Paradise (JP)*/
2963 MATCH_NA("Virtual Soccer") || /* Virtual Soccer (EU) (*)*/
2964 /* J-League Super Soccer (JP)*/
2965 MATCH_ID("AWF") || /* WWF RAW*/
2966
2967 /*Catch-alls*/
2968 MATCH_NC("SUPER BOMBERMAN") || /* All Bomberman games (FIXME: remove*/
2969 /* individual two Bomberman entries if this works)*/
2970 MATCH_NC("FIFA") || /* All FIFA games*/
2971 MATCH_NN("NHL") || /* All NHL games*/
2972 MATCH_NC("MADDEN") || /* All Madden games*/
2973 MATCH_NC("MICRO MACHINES") || /* All Micro Machines games*/
2974 MATCH_ID("Q4") /* ?*/
2975 )
2976 Settings.CurrentROMisMultitapCompatible = TRUE;
2977 else
2978 Settings.CurrentROMisMultitapCompatible = FALSE;
2979
2980 /* Mouse accessory detection */
2981 if (
2982 MATCH_NC("ACME ANIMATION FACTOR") || /* ACME Animation Factory*/
2983 MATCH_ID("ACM") ||
2984 MATCH_NC("ALICE PAINT") || /* Alice no Paint Adventure*/
2985 MATCH_ID("AALJ") ||
2986 MATCH_NC("ARKANOID DOH IT AGAIN0") || /* Arkanoid: Doh It Again*/
2987 MATCH_ID("A6") ||
2988 MATCH_NA("SFC SAILORMOON S") || /* Bishojou Senshi Sailor Moon S: Kondowa Puzzle de*/
2989 /* Oshiokiyo!*/
2990 MATCH_NA("BRANDISH2 EXPERT") || /* Brandish 2: Expert*/
2991 MATCH_ID("AQIJ") ||
2992 MATCH_NA("BREAKTRHU!") || /* BreakThru!*/
2993 MATCH_ID("ABXE") ||
2994 MATCH_NA("CIVILIZATION") || /* Civilization*/
2995 MATCH_ID("EQ") ||
2996 MATCH_NA("CAMELTRY") || /* Cameltry (JP) (*)*/
2997 /* On The Ball (EU/US)*/
2998 MATCH_NA("CANNON FODDER") || /* Cannon Fodder*/
2999 MATCH_ID("ACNP") ||
3000 MATCH_ID("M Ve") || /* Dai-3-ji Super Robot Taisen*/
3001 MATCH_ID("AR4J") || /* Dai-4-ji Super Robot Taisen*/
3002 MATCH_NA("SUPER ROBOT WARS 4") ||
3003 MATCH_NA("DOOM") || /* Doom*/
3004 MATCH_ID("AD8") ||
3005 MATCH_ID("A88J") || /* Doukyuusei 2 (JP) (NP)*/
3006 MATCH_NA("DRAGON KNIGHT 4") || /* Dragon Knight 4*/
3007 MATCH_ID("A87J") ||
3008 MATCH_NA("Eye of the Beholder") || /* Eye of the Beholder*/
3009 MATCH_NA("FARLANDSTORY2") || /* Farland Story 2*/
3010 MATCH_ID("A2FJ") ||
3011 MATCH_NA("Fun 'N Games") || /* Fun 'N Games (EU/US)*/
3012 MATCH_NA("GALAXY ROBO") || /* Galaxy Robo*/
3013 MATCH_NA("HIOUDEN") || /* Hiouden: Mamono-tachi tono Chikai*/
3014 MATCH_NA("JIGSAW PARTY") || /* Jigsaw Party (US) (*)*/
3015 /* Pieces (JP)*/
3016 /*MATCH_NA("JURASSIC PARK") || // Jurassic Park*/
3017 MATCH_NA("King Arthurs World") || /* King Arthur's World (EU/US) (*)*/
3018 /* Royal Conquest (JP)*/
3019 MATCH_NA("KOUTETSU-NO KISHI") || /* Koutetsu No Kishi*/
3020 MATCH_NA("KOUTETSU-NO KISHI 2") || /* Koutetsu No Kishi 2*/
3021 MATCH_NA("KOUTETSU-NO KISHI 3") || /* Koutetsu No Kishi 3*/
3022 MATCH_ID("APZJ") ||
3023 MATCH_NA("LAMBORGHINI AMERICAN") || /* Lamborghini American Challenge (EU/US)*/
3024 MATCH_NA("LAS VEGAS DREAM") || /* Las Vegas Dream in Golden Paradise (JP) (*)*/
3025 /* Vegas Stakes (EU/US)*/
3026 MATCH_NA("Lemmings 2,The Tribes") || /* Lemmings 2: The Tribes*/
3027 MATCH_ID("L2") ||
3028 MATCH_NA("LORD MONARCH") || /* Lord Monarch*/
3029 MATCH_NA("Mario&Wario") || /* Mario & Wario*/
3030 MATCH_NA("SUPER PICROSS") || /* Mario no Super Picross*/
3031 MATCH_ID("ACXJ") ||
3032 MATCH_NC("MARIOPAINT") || /* Mario Paint*/
3033 MATCH_NA("MEY Preschool Fun") || /* Mario's Early Years: Preschool Fun*/
3034 MATCH_ID("AMEE") ||
3035 MATCH_NA("MEGA LO MANIA") || /* Mega-Lo Mania*/
3036 MATCH_NA("MIGHT AND MAGIC III") || /* Might And Magic III - Isles of Terra*/
3037 MATCH_NA("WONDER KITCHEN") || /* Motoko-chan no Wonder Kitchen*/
3038 MATCH_NA("Nobunaga's Ambition") || /* Nobunaga's Ambition (US) (*)*/
3039 /* Super Nobunaga no Yabou: Zenkokuban (JP)*/
3040 MATCH_NA("ON THE BALL") || /* On The Ball (EU/US) (*)*/
3041 /* Cameltry (JP)*/
3042 MATCH_NA("OPERATION THUNDERBOLT1") || /* Operation Thunderbolt*/
3043 MATCH_NA("PIECES") ||
3044 MATCH_ID("Z5") || /* Pieces (JP) (*)*/
3045 /* Jigsaw Party (US)*/
3046 MATCH_NC("POPULOUS II") || /* Populous II*/
3047 MATCH_NA("POWERMONGER") || /* Power Monger*/
3048 MATCH_NA("Revolution X") || /* Revolution X*/
3049 MATCH_ID("AXR") ||
3050 MATCH_NA("Royal Conquest") || /* Royal Conquest (JP) (*)*/
3051 /* King Arthur's World (EU/US)*/
3052 MATCH_NA("TENBU SPIRIT") || /* San Goku Shi Seishi: Tenbu Spirits*/
3053 MATCH_NA("SHIEN THE BLADE CHASE0") || /* Shien The Blade Chaser (JP) (*)*/
3054 MATCH_NA("SHIEN'S REVENGE") || /* Shien's Revenge (*)*/
3055 MATCH_NC("SimAnt") || /* SimAnt*/
3056 MATCH_NA("SNOOPY CONCERT") || /* Snoopy Concert*/
3057 MATCH_NA("SUPER CAESARS PALACE") || /* Super Caesar's Palace*/
3058 MATCH_NA("SUPER CASTLES") || /* Super Castles*/
3059 MATCH_ID("AVIJ") ||
3060 /*FIXME: TODO: Super Noah's Ark 3D: - bad checksum - CRC32: A2315A14*/
3061 MATCH_NA("SuperPachiSlotMahjong") || /* Super Pachi Slot Mahjong*/
3062 MATCH_NA("SUPER SOLITAIRE") || /* Super Solitaire*/
3063 MATCH_NA("SUPER ZENKOKUBAN") || /* Super Nobunaga no Yabou: Zenkokuban (JP) (*)*/
3064 /* Nobunaga's Ambition (US)*/
3065 MATCH_NA("TERMINATOR2 THE MOVIE0") || /* Terminator 2: The Arcade Game*/
3066 MATCH_NA("TINSTAR") || /* Tin Star*/
3067 MATCH_ID("9N") ||
3068 MATCH_NA("TOKIMEKI MEMORIAL") || /* Tokimeki Memorial*/
3069 MATCH_ID("AM8J") ||
3070 MATCH_NA("Troddlers") || /* Troddlers*/
3071 MATCH_NA("UTOPIA") || /* Utopia*/
3072 MATCH_NA("VEGAS STAKES") || /* Vegas Stakes (EU/US) (*)*/
3073 /* Las Vegas Dream in Golden Paradise (JP)*/
3074 MATCH_NC("WOLFENSTEIN 3D") || /* Wolfenstein 3D*/
3075 MATCH_NA("WONDERPROJECT J") || /* Wonder Project J*/
3076 MATCH_ID("APJJ") ||
3077 MATCH_NA("ZAN2 SPIRITS") || /* Zan 2: Spirits*/
3078 MATCH_NA("ZAN3 SFC") /* Zan 3: Spirits*/
3079 )
3080 Settings.CurrentROMisMouseCompatible = TRUE;
3081 else
3082 Settings.CurrentROMisMouseCompatible = FALSE;
3083
3084 /* Super Scope accessory detection */
3085 if (
3086 MATCH_NA("BATTLE CLASH") || /* Battle Clash (EU/US) (*)*/
3087 /* Space Bazooka (JP)*/
3088 MATCH_NA("SPACE BAZOOKA") || /* Space Bazooka (JP) (*)*/
3089 /* Battle Clash (EU/US)*/
3090 /*FIXME: TODO: Add The Hunt for Red October - used for bonus game*/
3091 /*FIXME: TODO: Add Lamborghini American Challenge - if needed*/
3092 MATCH_NA("METAL COMBAT") || /* Metal Combat: Falcon's Revenge*/
3093 MATCH_NA("OPERATION THUNDERBOLT1") || /* Operation Thunderbolt*/
3094 MATCH_NA("SUPER SCOPE 6") || /* Super Scope 6*/
3095 /*MATCH_NA("TERMINATOR2 THE MOVIE0") || // Terminator 2: The Arcade Game*/
3096 MATCH_NA("TINSTAR") || /* Tin Star*/
3097 MATCH_ID("9N") ||
3098 MATCH_NA("X ZONE") || /* X-Zone*/
3099 /*FIXME: TODO: Add Yoshi no Road Hunting - CRC32: 52948F3C*/
3100 MATCH_NA("YOSHI'S SAFARI") /* Yoshi's Safari*/
3101 )
3102 Settings.CurrentROMisSuperScopeCompatible = TRUE;
3103 else
3104 Settings.CurrentROMisSuperScopeCompatible = FALSE;
3105 }
3106
3107 S9xAPUTimingSetSpeedup(Timings.APUSpeedup);
3108 S9xAPUAllowTimeOverflow(Timings.APUAllowTimeOverflow);
3109
3110 /* Other timing hacks */
3111
3112 Timings.HDMAStart = SNES_HDMA_START_HC + Settings.HDMATimingHack - 100;
3113 Timings.HBlankStart = SNES_HBLANK_START_HC + Timings.HDMAStart - SNES_HDMA_START_HC;
3114
3115 if (!Settings.DisableGameSpecificHacks)
3116 {
3117 /* The delay to sync CPU and DMA which Snes9x cannot emulate.
3118 Some games need really severe delay timing... */
3119
3120 /* Battle Grandprix */
3121 if (MATCH_NA("BATTLE GRANDPRIX"))
3122 {
3123 Timings.DMACPUSync = 20;
3124 snprintf(String, sizeof(String),
3125 "DMA sync: %d", Timings.DMACPUSync);
3126 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, String);
3127 }
3128 }
3129
3130 if (!Settings.DisableGameSpecificHacks)
3131 {
3132 /* Opcode-based emulators cannot escape from "reading $4211/BPL" infinite loop...
3133 The true IRQ can be triggered inside an opcode. */
3134 if (MATCH_NA("TRAVERSE")) /* Traverse - Starlight & Prairie*/
3135 {
3136 Timings.IRQPendCount = 1;
3137 snprintf(String, sizeof(String),
3138 "IRQ count hack: %d", Timings.IRQPendCount);
3139 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, String);
3140 }
3141
3142 /* An infinite loop reads $4212 and waits V-blank end, whereas
3143 VIRQ is set V=0.
3144
3145 If Snes9x succeeds to escape from the loop before jumping
3146 into the IRQ handler, the game goes further.
3147
3148 If Snes9x jumps into the IRQ handler before escaping from
3149 the loop, Snes9x cannot escape from the loop permanently
3150 because the RTI is in the next V-blank. */
3151
3152 if (MATCH_NA("Aero the AcroBat 2"))
3153 {
3154 Timings.IRQPendCount = 2;
3155 snprintf(String, sizeof(String),
3156 "IRQ count hack: %d", Timings.IRQPendCount);
3157 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, String);
3158 }
3159
3160 if (MATCH_NA("BATTLE BLAZE"))
3161 {
3162 Timings.IRQPendCount = 1;
3163 snprintf(String, sizeof(String),
3164 "IRQ count hack: %d", Timings.IRQPendCount);
3165 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP, String);
3166 }
3167 }
3168
3169 if (!Settings.DisableGameSpecificHacks)
3170 {
3171 /* XXX: What's happening? */
3172
3173 /* Spider-Man and the X-Men */
3174 if (MATCH_NA("X-MEN"))
3175 {
3176 Settings.BlockInvalidVRAMAccess = FALSE;
3177 S9xMessage(S9X_MSG_WARN, S9X_CATEGORY_MAP,
3178 "Invalid VRAM access hack");
3179 }
3180 }
3181
3182 /* SRAM initial value */
3183
3184 if (!Settings.DisableGameSpecificHacks)
3185 {
3186 if (MATCH_NA("HITOMI3"))
3187 {
3188 Memory.SRAMSize = 1;
3189 Memory.SRAMMask = ((1 << (Memory.SRAMSize + 3)) * 128) - 1;
3190 }
3191
3192 /* SRAM value fixes */
3193 if (MATCH_NA("SUPER DRIFT OUT") || /* Super Drift Out*/
3194 MATCH_NA("SATAN IS OUR FATHER!") ||
3195 MATCH_NA("goemon 4")) /* Ganbare Goemon Kirakira Douchuu*/
3196 SNESGameFixes.SRAMInitialValue = 0x00;
3197
3198 /* Additional game fixes by sanmaiwashi ...*/
3199 /* XXX: unnecessary?*/
3200 if (MATCH_NA("SFX \xC5\xB2\xC4\xB6\xDE\xDD\xC0\xDE\xD1\xD3\xC9\xB6\xDE\xC0\xD8 1")) /* SD Gundam Gaiden - Knight Gundam Monogatari*/
3201 SNESGameFixes.SRAMInitialValue = 0x6b;
3202
3203 /* others: BS and ST-01x games are 0x00.*/
3204 }
3205
3206 /* OAM hacks */
3207
3208 if (!Settings.DisableGameSpecificHacks)
3209 {
3210 /* OAM hacks because we don't fully understand the behavior of
3211 the SNES.
3212
3213 Totally wacky display in 2P mode...
3214
3215 seems to need a disproven behavior, so we're definitely
3216 overlooking some other bug? */
3217
3218 /* Uniracers */
3219 if (MATCH_NN("UNIRACERS"))
3220 {
3221 SNESGameFixes.Uniracers = TRUE;
3222 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_MAP,
3223 "Applied Uniracers hack.");
3224 }
3225 }
3226
3227 /* Show ROM information */
3228
3229 strcpy(Memory.RawROMName, Memory.ROMName);
3230 snprintf(displayName, sizeof(displayName), "%s",
3231 SafeANK(Memory.ROMRegion, Memory.ROMName));
3232 snprintf(Memory.ROMName, sizeof(Memory.ROMName),
3233 "%s", Safe(Memory.ROMName));
3234 snprintf(Memory.ROMId, sizeof(Memory.ROMId), "%s", Safe(Memory.ROMId));
3235
3236 snprintf(String, sizeof(String), "\"%s\" [%s] %s, %s, %s, %s, SRAM:%s, ID:%s, CRC32:%08X",
3237 displayName, isChecksumOK ? "checksum ok" : ((Multi.cartType == 4) ? "no checksum" : "bad checksum"),
3238 (Memory.HiROM ? ((Memory.ExtendedFormat != NOPE) ? "ExHiROM": "HiROM") : "LoROM"), Size(), KartContents(Memory.ROMType), Settings.PAL ? "PAL" : "NTSC", StaticRAMSize(), Memory.ROMId, Memory.ROMCRC32);
3239 S9xMessage(S9X_MSG_INFO, S9X_CATEGORY_ROM, String);
3240
3241 Settings.ForceLoROM = FALSE;
3242 Settings.ForceHiROM = FALSE;
3243 Settings.ForceHeader = FALSE;
3244 Settings.ForceNoHeader = FALSE;
3245 Settings.ForceInterleaved = FALSE;
3246 Settings.ForceInterleaved2 = FALSE;
3247 Settings.ForceInterleaveGD24 = FALSE;
3248 Settings.ForceNotInterleaved = FALSE;
3249 Settings.ForcePAL = FALSE;
3250 Settings.ForceNTSC = FALSE;
3251
3252 S9xVerifyControllers();
3253
3254 return (TRUE);
3255 }
3256