Browse code

* Fixes for gcc and clang (while they can compile the code, the DLLs made aren't functional, but oh well).

* [2SF] Used more up-to-date asmjit, despite the ugly looking code.

Naram Qashat authored on 2014/09/17 19:51:45
Showing 1 changed files
... ...
@@ -185,53 +185,6 @@
185 185
 #include "apu/apu.h"
186 186
 #include "sdd1.h"
187 187
 
188
-static const uint32_t crc32Table[] =
189
-{
190
-	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
191
-	0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
192
-	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
193
-	0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
194
-	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
195
-	0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
196
-	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
197
-	0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
198
-	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
199
-	0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
200
-	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
201
-	0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
202
-	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
203
-	0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
204
-	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
205
-	0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
206
-	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
207
-	0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
208
-	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
209
-	0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
210
-	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
211
-	0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
212
-	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
213
-	0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
214
-	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
215
-	0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
216
-	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
217
-	0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
218
-	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
219
-	0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
220
-	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
221
-	0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
222
-	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
223
-	0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
224
-	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
225
-	0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
226
-	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
227
-	0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
228
-	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
229
-	0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
230
-	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
231
-	0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
232
-	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
233
-};
234
-
235 188
 // deinterleave
236 189
 
237 190
 static void S9xDeinterleaveType1(int size, uint8_t *base)
Browse code

[SNSF] Replaced most uses of fill/copy with fill_n/copy_n, and a few other minor code cleanups.

Naram Qashat authored on 2013/05/27 22:34:22
Showing 1 changed files
... ...
@@ -270,10 +270,10 @@ bool CMemory::Init()
270 270
 		return false;
271 271
 	}
272 272
 
273
-	std::fill(&this->RAM[0], &this->RAM[0x20000], 0);
274
-	std::fill(&this->SRAM[0], &this->SRAM[0x20000], 0);
275
-	std::fill(&this->VRAM[0], &this->VRAM[0x10000], 0);
276
-	std::fill(&this->RealROM[0], &this->RealROM[MAX_ROM_SIZE + 0x200 + 0x8000], 0);
273
+	std::fill_n(&this->RAM[0], 0x20000, 0);
274
+	std::fill_n(&this->SRAM[0], 0x20000, 0);
275
+	std::fill_n(&this->VRAM[0], 0x10000, 0);
276
+	std::fill_n(&this->RealROM[0], MAX_ROM_SIZE + 0x200 + 0x8000, 0);
277 277
 
278 278
 	// FillRAM uses first 32K of ROM image area, otherwise space just
279 279
 	// wasted. Might be read by the SuperFX code.
... ...
@@ -409,7 +409,7 @@ bool CMemory::LoadROMSNSF(const uint8_t *lrombuf, int32_t lromsize, const uint8_
409 409
 {
410 410
 	int retry_count = 0;
411 411
 
412
-	std::fill(&this->ROM[0], &this->ROM[MAX_ROM_SIZE], 0);
412
+	std::fill_n(&this->ROM[0], static_cast<int>(MAX_ROM_SIZE), 0);
413 413
 
414 414
 again:
415 415
 	this->CalculatedSize = 0;
... ...
@@ -418,18 +418,17 @@ again:
418 418
 	int32_t totalFileSize = std::min<int32_t>(MAX_ROM_SIZE, lromsize);
419 419
 	if (!totalFileSize)
420 420
 		return false;
421
-	std::copy(&lrombuf[0], &lrombuf[totalFileSize], &this->ROM[0]);
422
-	SNESGameFixes.SRAMInitialValue = 0xff;
423
-	std::fill(&this->SRAM[0], &this->SRAM[0x20000], SNESGameFixes.SRAMInitialValue);
421
+	std::copy_n(&lrombuf[0], totalFileSize, &this->ROM[0]);
422
+	std::fill_n(&this->SRAM[0], 0x20000, 0xff);
424 423
 	if (srambuf && sramsize)
425
-		std::copy(&srambuf[0], &srambuf[sramsize], &this->SRAM[0]);
424
+		std::copy_n(&srambuf[0], sramsize, &this->SRAM[0]);
426 425
 
427 426
 	int hi_score = this->ScoreHiROM(false);
428 427
 	int lo_score = this->ScoreLoROM(false);
429 428
 
430 429
 	if (((hi_score > lo_score && this->ScoreHiROM(true) > hi_score) || (hi_score <= lo_score && this->ScoreLoROM(true) > lo_score)))
431 430
 	{
432
-		memmove(&this->ROM[0], &this->ROM[512], totalFileSize - 512);
431
+		std::copy_n(&this->ROM[512], totalFileSize - 512, &this->ROM[0]);
433 432
 		totalFileSize -= 512;
434 433
 		// modifying ROM, so we need to rescore
435 434
 		hi_score = this->ScoreHiROM(false);
... ...
@@ -486,7 +485,6 @@ again:
486 485
 
487 486
 		// ignore map type byte if not 0x2x or 0x3x
488 487
 		if ((RomHeader[0x7fd5] & 0xf0) == 0x20 || (RomHeader[0x7fd5] & 0xf0) == 0x30)
489
-		{
490 488
 			switch (RomHeader[0x7fd5] & 0xf)
491 489
 			{
492 490
 				case 1:
... ...
@@ -494,11 +492,8 @@ again:
494 492
 					break;
495 493
 
496 494
 				case 5:
497
-					interleaved = true;
498
-					tales = true;
499
-					break;
495
+					interleaved = tales = true;
500 496
 			}
501
-		}
502 497
 	}
503 498
 	else
504 499
 	{
... ...
@@ -506,24 +501,19 @@ again:
506 501
 		this->HiROM = true;
507 502
 
508 503
 		if ((RomHeader[0xffd5] & 0xf0) == 0x20 || (RomHeader[0xffd5] & 0xf0) == 0x30)
509
-		{
510 504
 			switch (RomHeader[0xffd5] & 0xf)
511 505
 			{
512 506
 				case 0:
513 507
 				case 3:
514 508
 					interleaved = true;
515
-					break;
516 509
 			}
517
-		}
518 510
 	}
519 511
 
520 512
 	// this two games fail to be detected
521 513
 	if (!strncmp(reinterpret_cast<char *>(&this->ROM[0x7fc0]), "YUYU NO QUIZ DE GO!GO!", 22) || !strncmp(reinterpret_cast<char *>(&this->ROM[0xffc0]), "BATMAN--REVENGE JOKER",  21))
522 514
 	{
523 515
 		this->LoROM = true;
524
-		this->HiROM = false;
525
-		interleaved = false;
526
-		tales = false;
516
+		this->HiROM = interleaved = tales = false;
527 517
 	}
528 518
 
529 519
 	if (!Settings.ForceNotInterleaved && interleaved)
... ...
@@ -567,13 +557,12 @@ again:
567 557
 	if (tales)
568 558
 	{
569 559
 		auto tmp = std::vector<uint8_t>(this->CalculatedSize - 0x400000);
570
-		memmove(&tmp[0], &this->ROM[0], this->CalculatedSize - 0x400000);
571
-		memmove(&this->ROM[0], &this->ROM[this->CalculatedSize - 0x400000], 0x400000);
572
-		memmove(&this->ROM[0x400000], &tmp[0], this->CalculatedSize - 0x400000);
560
+		std::copy_n(&this->ROM[0], this->CalculatedSize - 0x400000, &tmp[0]);
561
+		std::copy_n(&this->ROM[this->CalculatedSize - 0x400000], 0x400000, &this->ROM[0]);
562
+		std::copy_n(&tmp[0], this->CalculatedSize - 0x400000, &this->ROM[0x400000]);
573 563
 	}
574 564
 
575 565
 	memset(&SNESGameFixes, 0, sizeof(SNESGameFixes));
576
-	SNESGameFixes.SRAMInitialValue = 0x60;
577 566
 
578 567
 	this->InitROM();
579 568
 
... ...
@@ -626,14 +615,14 @@ void CMemory::ParseSNESHeader(uint8_t *RomHeader)
626 615
 	this->ROMType = RomHeader[0x26];
627 616
 	this->ROMRegion = RomHeader[0x29];
628 617
 
629
-	std::copy(&RomHeader[0x02], &RomHeader[0x06], &this->ROMId[0]);
618
+	std::copy_n(&RomHeader[0x02], 4, &this->ROMId[0]);
630 619
 }
631 620
 
632 621
 void CMemory::InitROM()
633 622
 {
634 623
 	//// Parse ROM header and read ROM informatoin
635 624
 
636
-	std::fill(&this->ROMId[0], &this->ROMId[5], 0);
625
+	std::fill_n(&this->ROMId[0], 5, 0);
637 626
 
638 627
 	uint8_t *RomHeader = &this->ROM[0x7FB0];
639 628
 	if (this->ExtendedFormat == BIGFIRST)
... ...
@@ -817,7 +806,6 @@ void CMemory::map_space(uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint3
817 806
 
818 807
 void CMemory::map_index(uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, int index, int type)
819 808
 {
820
-	bool isROM = !(type == MAP_TYPE_I_O || type == MAP_TYPE_RAM);
821 809
 	bool isRAM = type != MAP_TYPE_I_O;
822 810
 
823 811
 	for (uint32_t c = bank_s; c <= bank_e; ++c)
... ...
@@ -825,7 +813,7 @@ void CMemory::map_index(uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint3
825 813
 		{
826 814
 			uint32_t p = (c << 4) | (i >> 12);
827 815
 			this->Map[p] = reinterpret_cast<uint8_t *>(index);
828
-			this->BlockIsROM[p] = isROM;
816
+			this->BlockIsROM[p] = false;
829 817
 			this->BlockIsRAM[p] = isRAM;
830 818
 		}
831 819
 }
... ...
@@ -862,7 +850,7 @@ void CMemory::map_HiROMSRAM()
862 850
 
863 851
 void CMemory::map_WriteProtectROM()
864 852
 {
865
-	std::copy(&this->Map[0], &this->Map[0x1000], &this->WriteMap[0]);
853
+	std::copy_n(&this->Map[0], 0x1000, &this->WriteMap[0]);
866 854
 
867 855
 	for (int c = 0; c < 0x1000; ++c)
868 856
 		if (this->BlockIsROM[c])
... ...
@@ -1119,17 +1107,6 @@ void CMemory::ApplyROMFixes()
1119 1107
 			SRAMMask = ((1 << (SRAMSize + 3)) * 128) - 1;
1120 1108
 		}
1121 1109
 
1122
-		// SRAM value fixes
1123
-		if (this->match_na("SUPER DRIFT OUT") || // Super Drift Out
1124
-			this->match_na("SATAN IS OUR FATHER!") ||
1125
-			this->match_na("goemon 4")) // Ganbare Goemon Kirakira Douchuu
1126
-			SNESGameFixes.SRAMInitialValue = 0x00;
1127
-
1128
-		// Additional game fixes by sanmaiwashi ...
1129
-		// XXX: unnecessary?
1130
-		if (this->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
1131
-			SNESGameFixes.SRAMInitialValue = 0x6b;
1132
-
1133 1110
 		// others: BS and ST-01x games are 0x00.
1134 1111
 
1135 1112
 		//// OAM hacks :(
Browse code

[SNSF] Massive code cleanup, as well as removing as much unused code/variables as possible.

Naram Qashat authored on 2013/05/23 06:02:16
Showing 1 changed files
... ...
@@ -175,718 +175,17 @@
175 175
   Nintendo Co., Limited and its subsidiary companies.
176 176
  ***********************************************************************************/
177 177
 
178
+#include <vector>
178 179
 #include <algorithm>
179 180
 #include <string>
180 181
 #include <numeric>
181
-#include <assert.h>
182
-
183
-#ifdef UNZIP_SUPPORT
184
-#include "unzip/unzip.h"
185
-#endif
186
-
187
-#ifdef JMA_SUPPORT
188
-#include "jma/s9x-jma.h"
189
-#endif
190
-
182
+#include <cassert>
191 183
 #include "snes9x.h"
192 184
 #include "memmap.h"
193 185
 #include "apu/apu.h"
194
-//#include "fxemu.h"
195 186
 #include "sdd1.h"
196
-//#include "srtc.h"
197
-//#include "controls.h"
198
-//#include "cheats.h"
199
-//#include "movie.h"
200
-//#include "reader.h"
201
-//#include "display.h"
202
-
203
-/*#ifndef SET_UI_COLOR
204
-#define SET_UI_COLOR(r, g, b) ;
205
-#endif*/
206
-
207
-/*#ifndef max
208
-#define max(a, b) (((a) > (b)) ? (a) : (b))
209
-#endif*/
210
-
211
-/*#ifndef min
212
-#define min(a, b) (((a) < (b)) ? (a) : (b))
213
-#endif*/
214
-
215
-//static bool	stopMovie = true;
216
-//static char		LastRomFilename[PATH_MAX + 1] = "";
217
-
218
-// from NSRT
219
-/*static const char	*nintendo_licensees[] =
220
-{
221
-	"Unlicensed",
222
-	"Nintendo",
223
-	"Rocket Games/Ajinomoto",
224
-	"Imagineer-Zoom",
225
-	"Gray Matter",
226
-	"Zamuse",
227
-	"Falcom",
228
-	NULL,
229
-	"Capcom",
230
-	"Hot B Co.",
231
-	"Jaleco",
232
-	"Coconuts Japan",
233
-	"Coconuts Japan/G.X.Media",
234
-	"Micronet",
235
-	"Technos",
236
-	"Mebio Software",
237
-	"Shouei System",
238
-	"Starfish",
239
-	NULL,
240
-	"Mitsui Fudosan/Dentsu",
241
-	NULL,
242
-	"Warashi Inc.",
243
-	NULL,
244
-	"Nowpro",
245
-	NULL,
246
-	"Game Village",
247
-	"IE Institute",
248
-	NULL,
249
-	NULL,
250
-	NULL,
251
-	NULL,
252
-	NULL,
253
-	NULL,
254
-	NULL,
255
-	NULL,
256
-	NULL,
257
-	"Banarex",
258
-	"Starfish",
259
-	"Infocom",
260
-	"Electronic Arts Japan",
261
-	NULL,
262
-	"Cobra Team",
263
-	"Human/Field",
264
-	"KOEI",
265
-	"Hudson Soft",
266
-	"S.C.P./Game Village",
267
-	"Yanoman",
268
-	NULL,
269
-	"Tecmo Products",
270
-	"Japan Glary Business",
271
-	"Forum/OpenSystem",
272
-	"Virgin Games (Japan)",
273
-	"SMDE",
274
-	"Yojigen",
275
-	NULL,
276
-	"Daikokudenki",
277
-	NULL,
278
-	NULL,
279
-	NULL,
280
-	NULL,
281
-	NULL,
282
-	"Creatures Inc.",
283
-	"TDK Deep Impresion",
284
-	NULL,
285
-	NULL,
286
-	NULL,
287
-	NULL,
288
-	NULL,
289
-	NULL,
290
-	NULL,
291
-	NULL,
292
-	NULL,
293
-	"Destination Software/KSS",
294
-	"Sunsoft/Tokai Engineering",
295
-	"POW (Planning Office Wada)/VR 1 Japan",
296
-	"Micro World",
297
-	NULL,
298
-	"San-X",
299
-	"Enix",
300
-	"Loriciel/Electro Brain",
301
-	"Kemco Japan",
302
-	"Seta Co.,Ltd.",
303
-	"Culture Brain",
304
-	"Irem Corp.",
305
-	"Palsoft",
306
-	"Visit Co., Ltd.",
307
-	"Intec",
308
-	"System Sacom",
309
-	"Poppo",
310
-	"Ubisoft Japan",
311
-	NULL,
312
-	"Media Works",
313
-	"NEC InterChannel",
314
-	"Tam",
315
-	"Gajin/Jordan",
316
-	"Smilesoft",
317
-	NULL,
318
-	NULL,
319
-	"Mediakite",
320
-	NULL,
321
-	NULL,
322
-	NULL,
323
-	NULL,
324
-	NULL,
325
-	NULL,
326
-	NULL,
327
-	NULL,
328
-	NULL,
329
-	"Viacom",
330
-	"Carrozzeria",
331
-	"Dynamic",
332
-	NULL,
333
-	"Magifact",
334
-	"Hect",
335
-	"Codemasters",
336
-	"Taito/GAGA Communications",
337
-	"Laguna",
338
-	"Telstar Fun & Games/Event/Taito",
339
-	NULL,
340
-	"Arcade Zone Ltd.",
341
-	"Entertainment International/Empire Software",
342
-	"Loriciel",
343
-	"Gremlin Graphics",
344
-	NULL,
345
-	NULL,
346
-	NULL,
347
-	NULL,
348
-	NULL,
349
-	NULL,
350
-	NULL,
351
-	NULL,
352
-	NULL,
353
-	NULL,
354
-	NULL,
355
-	NULL,
356
-	NULL,
357
-	NULL,
358
-	NULL,
359
-	NULL,
360
-	NULL,
361
-	NULL,
362
-	NULL,
363
-	NULL,
364
-	NULL,
365
-	"Seika Corp.",
366
-	"UBI SOFT Entertainment Software",
367
-	"Sunsoft US",
368
-	NULL,
369
-	"Life Fitness",
370
-	NULL,
371
-	"System 3",
372
-	"Spectrum Holobyte",
373
-	NULL,
374
-	"Irem",
375
-	NULL,
376
-	"Raya Systems",
377
-	"Renovation Products",
378
-	"Malibu Games",
379
-	NULL,
380
-	"Eidos/U.S. Gold",
381
-	"Playmates Interactive",
382
-	NULL,
383
-	NULL,
384
-	"Fox Interactive",
385
-	"Time Warner Interactive",
386
-	NULL,
387
-	NULL,
388
-	NULL,
389
-	NULL,
390
-	NULL,
391
-	"Disney Interactive",
392
-	NULL,
393
-	"Black Pearl",
394
-	NULL,
395
-	"Advanced Productions",
396
-	NULL,
397
-	NULL,
398
-	"GT Interactive",
399
-	"RARE",
400
-	"Crave Entertainment",
401
-	"Absolute Entertainment",
402
-	"Acclaim",
403
-	"Activision",
404
-	"American Sammy",
405
-	"Take 2/GameTek",
406
-	"Hi Tech",
407
-	"LJN Ltd.",
408
-	NULL,
409
-	"Mattel",
410
-	NULL,
411
-	"Mindscape/Red Orb Entertainment",
412
-	"Romstar",
413
-	"Taxan",
414
-	"Midway/Tradewest",
415
-	NULL,
416
-	"American Softworks Corp.",
417
-	"Majesco Sales Inc.",
418
-	"3DO",
419
-	NULL,
420
-	NULL,
421
-	"Hasbro",
422
-	"NewKidCo",
423
-	"Telegames",
424
-	"Metro3D",
425
-	NULL,
426
-	"Vatical Entertainment",
427
-	"LEGO Media",
428
-	NULL,
429
-	"Xicat Interactive",
430
-	"Cryo Interactive",
431
-	NULL,
432
-	NULL,
433
-	"Red Storm Entertainment",
434
-	"Microids",
435
-	NULL,
436
-	"Conspiracy/Swing",
437
-	"Titus",
438
-	"Virgin Interactive",
439
-	"Maxis",
440
-	NULL,
441
-	"LucasArts Entertainment",
442
-	NULL,
443
-	NULL,
444
-	"Ocean",
445
-	NULL,
446
-	"Electronic Arts",
447
-	NULL,
448
-	"Laser Beam",
449
-	NULL,
450
-	NULL,
451
-	"Elite Systems",
452
-	"Electro Brain",
453
-	"The Learning Company",
454
-	"BBC",
455
-	NULL,
456
-	"Software 2000",
457
-	NULL,
458
-	"BAM! Entertainment",
459
-	"Studio 3",
460
-	NULL,
461
-	NULL,
462
-	NULL,
463
-	"Classified Games",
464
-	NULL,
465
-	"TDK Mediactive",
466
-	NULL,
467
-	"DreamCatcher",
468
-	"JoWood Produtions",
469
-	"SEGA",
470
-	"Wannado Edition",
471
-	"LSP (Light & Shadow Prod.)",
472
-	"ITE Media",
473
-	"Infogrames",
474
-	"Interplay",
475
-	"JVC (US)",
476
-	"Parker Brothers",
477
-	NULL,
478
-	"SCI (Sales Curve Interactive)/Storm",
479
-	NULL,
480
-	NULL,
481
-	"THQ Software",
482
-	"Accolade Inc.",
483
-	"Triffix Entertainment",
484
-	NULL,
485
-	"Microprose Software",
486
-	"Universal Interactive/Sierra/Simon & Schuster",
487
-	NULL,
488
-	"Kemco",
489
-	"Rage Software",
490
-	"Encore",
491
-	NULL,
492
-	"Zoo",
493
-	"Kiddinx",
494
-	"Simon & Schuster Interactive",
495
-	"Asmik Ace Entertainment Inc./AIA",
496
-	"Empire Interactive",
497
-	NULL,
498
-	NULL,
499
-	"Jester Interactive",
500
-	NULL,
501
-	"Rockstar Games",
502
-	"Scholastic",
503
-	"Ignition Entertainment",
504
-	"Summitsoft",
505
-	"Stadlbauer",
506
-	NULL,
507
-	NULL,
508
-	NULL,
509
-	"Misawa",
510
-	"Teichiku",
511
-	"Namco Ltd.",
512
-	"LOZC",
513
-	"KOEI",
514
-	NULL,
515
-	"Tokuma Shoten Intermedia",
516
-	"Tsukuda Original",
517
-	"DATAM-Polystar",
518
-	NULL,
519
-	NULL,
520
-	"Bullet-Proof Software",
521
-	"Vic Tokai Inc.",
522
-	NULL,
523
-	"Character Soft",
524
-	"I'Max",
525
-	"Saurus",
526
-	NULL,
527
-	NULL,
528
-	"General Entertainment",
529
-	NULL,
530
-	NULL,
531
-	"I'Max",
532
-	"Success",
533
-	NULL,
534
-	"SEGA Japan",
535
-	NULL,
536
-	NULL,
537
-	NULL,
538
-	NULL,
539
-	NULL,
540
-	NULL,
541
-	NULL,
542
-	NULL,
543
-	NULL,
544
-	NULL,
545
-	"Takara",
546
-	"Chun Soft",
547
-	"Video System Co., Ltd./McO'River",
548
-	"BEC",
549
-	NULL,
550
-	"Varie",
551
-	"Yonezawa/S'pal",
552
-	"Kaneko",
553
-	NULL,
554
-	"Victor Interactive Software/Pack-in-Video",
555
-	"Nichibutsu/Nihon Bussan",
556
-	"Tecmo",
557
-	"Imagineer",
558
-	NULL,
559
-	NULL,
560
-	"Nova",
561
-	"Den'Z",
562
-	"Bottom Up",
563
-	NULL,
564
-	"TGL (Technical Group Laboratory)",
565
-	NULL,
566
-	"Hasbro Japan",
567
-	NULL,
568
-	"Marvelous Entertainment",
569
-	NULL,
570
-	"Keynet Inc.",
571
-	"Hands-On Entertainment",
572
-	NULL,
573
-	NULL,
574
-	NULL,
575
-	NULL,
576
-	NULL,
577
-	NULL,
578
-	NULL,
579
-	NULL,
580
-	NULL,
581
-	"Telenet",
582
-	"Hori",
583
-	NULL,
584
-	NULL,
585
-	"Konami",
586
-	"K.Amusement Leasing Co.",
587
-	"Kawada",
588
-	"Takara",
589
-	NULL,
590
-	"Technos Japan Corp.",
591
-	"JVC (Europe/Japan)/Victor Musical Industries",
592
-	NULL,
593
-	"Toei Animation",
594
-	"Toho",
595
-	NULL,
596
-	"Namco",
597
-	"Media Rings Corp.",
598
-	"J-Wing",
599
-	NULL,
600
-	"Pioneer LDC",
601
-	"KID",
602
-	"Mediafactory",
603
-	NULL,
604
-	NULL,
605
-	NULL,
606
-	"Infogrames Hudson",
607
-	NULL,
608
-	NULL,
609
-	NULL,
610
-	NULL,
611
-	NULL,
612
-	NULL,
613
-	NULL,
614
-	NULL,
615
-	NULL,
616
-	NULL,
617
-	"Acclaim Japan",
618
-	"ASCII Co./Nexoft",
619
-	"Bandai",
620
-	NULL,
621
-	"Enix",
622
-	NULL,
623
-	"HAL Laboratory/Halken",
624
-	"SNK",
625
-	NULL,
626
-	"Pony Canyon Hanbai",
627
-	"Culture Brain",
628
-	"Sunsoft",
629
-	"Toshiba EMI",
630
-	"Sony Imagesoft",
631
-	NULL,
632
-	"Sammy",
633
-	"Magical",
634
-	"Visco",
635
-	NULL,
636
-	"Compile",
637
-	NULL,
638
-	"MTO Inc.",
639
-	NULL,
640
-	"Sunrise Interactive",
641
-	NULL,
642
-	"Global A Entertainment",
643
-	"Fuuki",
644
-	NULL,
645
-	NULL,
646
-	NULL,
647
-	NULL,
648
-	NULL,
649
-	NULL,
650
-	NULL,
651
-	NULL,
652
-	NULL,
653
-	"Taito",
654
-	NULL,
655
-	"Kemco",
656
-	"Square",
657
-	"Tokuma Shoten",
658
-	"Data East",
659
-	"Tonkin House",
660
-	NULL,
661
-	"KOEI",
662
-	NULL,
663
-	"Konami/Ultra/Palcom",
664
-	"NTVIC/VAP",
665
-	"Use Co., Ltd.",
666
-	"Meldac",
667
-	"Pony Canyon (Japan)/FCI (US)",
668
-	"Angel/Sotsu Agency/Sunrise",
669
-	"Yumedia/Aroma Co., Ltd.",
670
-	NULL,
671
-	NULL,
672
-	"Boss",
673
-	"Axela/Crea-Tech",
674
-	"Sekaibunka-Sha/Sumire kobo/Marigul Management Inc.",
675
-	"Konami Computer Entertainment Osaka",
676
-	NULL,
677
-	NULL,
678
-	"Enterbrain",
679
-	NULL,
680
-	NULL,
681
-	NULL,
682
-	NULL,
683
-	NULL,
684
-	NULL,
685
-	NULL,
686
-	NULL,
687
-	NULL,
688
-	NULL,
689
-	"Taito/Disco",
690
-	"Sofel",
691
-	"Quest Corp.",
692
-	"Sigma",
693
-	"Ask Kodansha",
694
-	NULL,
695
-	"Naxat",
696
-	"Copya System",
697
-	"Capcom Co., Ltd.",
698
-	"Banpresto",
699
-	"TOMY",
700
-	"Acclaim/LJN Japan",
701
-	NULL,
702
-	"NCS",
703
-	"Human Entertainment",
704
-	"Altron",
705
-	"Jaleco",
706
-	"Gaps Inc.",
707
-	NULL,
708
-	NULL,
709
-	NULL,
710
-	NULL,
711
-	NULL,
712
-	"Elf",
713
-	NULL,
714
-	NULL,
715
-	NULL,
716
-	NULL,
717
-	NULL,
718
-	NULL,
719
-	NULL,
720
-	NULL,
721
-	NULL,
722
-	NULL,
723
-	NULL,
724
-	NULL,
725
-	"Jaleco",
726
-	NULL,
727
-	"Yutaka",
728
-	"Varie",
729
-	"T&ESoft",
730
-	"Epoch Co., Ltd.",
731
-	NULL,
732
-	"Athena",
733
-	"Asmik",
734
-	"Natsume",
735
-	"King Records",
736
-	"Atlus",
737
-	"Epic/Sony Records (Japan)",
738
-	NULL,
739
-	"IGS (Information Global Service)",
740
-	NULL,
741
-	"Chatnoir",
742
-	"Right Stuff",
743
-	NULL,
744
-	"NTT COMWARE",
745
-	NULL,
746
-	"Spike",
747
-	"Konami Computer Entertainment Tokyo",
748
-	"Alphadream Corp.",
749
-	NULL,
750
-	"Sting",
751
-	NULL,
752
-	NULL,
753
-	NULL,
754
-	NULL,
755
-	NULL,
756
-	NULL,
757
-	NULL,
758
-	NULL,
759
-	NULL,
760
-	NULL,
761
-	"A Wave",
762
-	"Motown Software",
763
-	"Left Field Entertainment",
764
-	"Extreme Entertainment Group",
765
-	"TecMagik",
766
-	NULL,
767
-	NULL,
768
-	NULL,
769
-	NULL,
770
-	"Cybersoft",
771
-	NULL,
772
-	"Psygnosis",
773
-	NULL,
774
-	NULL,
775
-	"Davidson/Western Tech.",
776
-	"Unlicensed",
777
-	NULL,
778
-	NULL,
779
-	NULL,
780
-	NULL,
781
-	"The Game Factory Europe",
782
-	"Hip Games",
783
-	"Aspyr",
784
-	NULL,
785
-	NULL,
786
-	"Mastiff",
787
-	"iQue",
788
-	"Digital Tainment Pool",
789
-	"XS Games",
790
-	"Daiwon",
791
-	NULL,
792
-	NULL,
793
-	NULL,
794
-	NULL,
795
-	NULL,
796
-	NULL,
797
-	NULL,
798
-	"PCCW Japan",
799
-	NULL,
800
-	NULL,
801
-	"KiKi Co. Ltd.",
802
-	"Open Sesame Inc.",
803
-	"Sims",
804
-	"Broccoli",
805
-	"Avex",
806
-	"D3 Publisher",
807
-	NULL,
808
-	"Konami Computer Entertainment Japan",
809
-	NULL,
810
-	"Square-Enix",
811
-	"KSG",
812
-	"Micott & Basara Inc.",
813
-	NULL,
814
-	"Orbital Media",
815
-	NULL,
816
-	NULL,
817
-	NULL,
818
-	NULL,
819
-	NULL,
820
-	NULL,
821
-	NULL,
822
-	NULL,
823
-	NULL,
824
-	NULL,
825
-	NULL,
826
-	NULL,
827
-	NULL,
828
-	NULL,
829
-	NULL,
830
-	NULL,
831
-	"The Game Factory USA",
832
-	NULL,
833
-	NULL,
834
-	"Treasure",
835
-	"Aruze",
836
-	"Ertain",
837
-	"SNK Playmore",
838
-	NULL,
839
-	NULL,
840
-	NULL,
841
-	NULL,
842
-	NULL,
843
-	NULL,
844
-	NULL,
845
-	NULL,
846
-	NULL,
847
-	NULL,
848
-	NULL,
849
-	NULL,
850
-	NULL,
851
-	NULL,
852
-	NULL,
853
-	NULL,
854
-	NULL,
855
-	NULL,
856
-	NULL,
857
-	NULL,
858
-	NULL,
859
-	NULL,
860
-	NULL,
861
-	NULL,
862
-	NULL,
863
-	NULL,
864
-	NULL,
865
-	NULL,
866
-	NULL,
867
-	NULL,
868
-	NULL,
869
-	NULL,
870
-	NULL,
871
-	NULL,
872
-	NULL,
873
-	NULL,
874
-	NULL,
875
-	NULL,
876
-	NULL,
877
-	NULL,
878
-	NULL,
879
-	NULL,
880
-	NULL,
881
-	NULL,
882
-	NULL,
883
-	NULL,
884
-	NULL,
885
-	NULL,
886
-	"Yojigen"
887
-};*/
888
-
889
-static const uint32_t	crc32Table[256] =
187
+
188
+static const uint32_t crc32Table[] =
890 189
 {
891 190
 	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
892 191
 	0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
... ...
@@ -933,316 +232,88 @@ static const uint32_t	crc32Table[256] =
933 232
 	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
934 233
 };
935 234
 
936
-//static void S9xDeinterleaveType1 (int, uint8_t *);
937
-//static void S9xDeinterleaveType2 (int, uint8_t *);
938
-//static void S9xDeinterleaveGD24 (int, uint8_t *);
939
-//static bool allASCII (uint8_t *, int);
940
-//static bool is_SufamiTurbo_BIOS (uint8_t *, uint32_t);
941
-//static bool is_SufamiTurbo_Cart (uint8_t *, uint32_t);
942
-//static bool is_SameGame_BIOS (uint8_t *, uint32_t);
943
-//static bool is_SameGame_Add_On (uint8_t *, uint32_t);
944
-//static uint32_t caCRC32 (uint8_t *, uint32_t, uint32_t crc32 = 0xffffffff);
945
-/*static uint32_t ReadUPSPointer (const uint8_t *, unsigned &, unsigned);
946
-static bool ReadUPSPatch (Reader *, long, int32_t &);
947
-static long ReadInt (Reader *, unsigned);
948
-static bool ReadIPSPatch (Reader *, long, int32_t &);*/
949
-#ifdef UNZIP_SUPPORT
950
-static int unzFindExtension (unzFile &, const char *, bool restart = true, bool print = true);
951
-#endif
952
-
953 235
 // deinterleave
954 236
 
955
-static void S9xDeinterleaveType1 (int size, uint8_t *base)
237
+static void S9xDeinterleaveType1(int size, uint8_t *base)
956 238
 {
957
-	//Settings.DisplayColor = BUILD_PIXEL(0, 31, 0);
958
-	//SET_UI_COLOR(0, 255, 0);
239
+	uint8_t blocks[256];
240
+	int nblocks = size >> 16;
959 241
 
960
-	uint8_t	blocks[256];
961
-	int		nblocks = size >> 16;
962
-
963
-	for (int i = 0; i < nblocks; i++)
242
+	for (int i = 0; i < nblocks; ++i)
964 243
 	{
965 244
 		blocks[i * 2] = i + nblocks;
966 245
 		blocks[i * 2 + 1] = i;
967 246
 	}
968 247
 
969
-	uint8_t	*tmp = (uint8_t *) malloc(0x8000);
970
-	if (tmp)
971
-	{
972
-		for (int i = 0; i < nblocks * 2; i++)
973
-		{
974
-			for (int j = i; j < nblocks * 2; j++)
248
+	for (int i = 0; i < nblocks * 2; ++i)
249
+		for (int j = i; j < nblocks * 2; ++j)
250
+			if (blocks[j] == i)
975 251
 			{
976
-				if (blocks[j] == i)
977
-				{
978
-					memmove(tmp, &base[blocks[j] * 0x8000], 0x8000);
979
-					memmove(&base[blocks[j] * 0x8000], &base[blocks[i] * 0x8000], 0x8000);
980
-					memmove(&base[blocks[i] * 0x8000], tmp, 0x8000);
981
-					uint8_t	b = blocks[j];
982
-					blocks[j] = blocks[i];
983
-					blocks[i] = b;
984
-					break;
985
-				}
252
+				std::swap_ranges(&base[blocks[i] * 0x8000], &base[(blocks[i] + 1) * 0x8000], &base[blocks[j] * 0x8000]);
253
+				std::swap(blocks[i], blocks[j]);
254
+				break;
986 255
 			}
987
-		}
988
-
989
-		free(tmp);
990
-	}
991 256
 }
992 257
 
993
-static void S9xDeinterleaveType2 (int size, uint8_t *base)
994
-{
995
-	// for odd Super FX images
996
-	//Settings.DisplayColor = BUILD_PIXEL(31, 14, 6);
997
-	//SET_UI_COLOR(255, 119, 25);
998
-
999
-	uint8_t	blocks[256];
1000
-	int		nblocks = size >> 16;
1001
-	int		step = 64;
1002
-
1003
-	while (nblocks <= step)
1004
-		step >>= 1;
1005
-	nblocks = step;
1006
-
1007
-	for (int i = 0; i < nblocks * 2; i++)
1008
-		blocks[i] = (i & ~0xf) | ((i & 3) << 2) | ((i & 12) >> 2);
1009
-
1010
-	uint8_t	*tmp = (uint8_t *) malloc(0x10000);
1011
-	if (tmp)
1012
-	{
1013
-		for (int i = 0; i < nblocks * 2; i++)
1014
-		{
1015
-			for (int j = i; j < nblocks * 2; j++)
1016
-			{
1017
-				if (blocks[j] == i)
1018
-				{
1019
-					memmove(tmp, &base[blocks[j] * 0x10000], 0x10000);
1020
-					memmove(&base[blocks[j] * 0x10000], &base[blocks[i] * 0x10000], 0x10000);
1021
-					memmove(&base[blocks[i] * 0x10000], tmp, 0x10000);
1022
-					uint8_t	b = blocks[j];
1023
-					blocks[j] = blocks[i];
1024
-					blocks[i] = b;
1025
-					break;
1026
-				}
1027
-			}
1028
-		}
1029
-
1030
-		free(tmp);
1031
-	}
1032
-}
258
+// allocation and deallocation
1033 259
 
1034
-static void S9xDeinterleaveGD24 (int size, uint8_t *base)
260
+bool CMemory::Init()
1035 261
 {
1036
-	// for 24Mb images dumped with Game Doctor
1037
-	if (size != 0x300000)
1038
-		return;
262
+	this->RAM.reset(new uint8_t[0x20000]);
263
+	this->SRAM.reset(new uint8_t[0x20000]);
264
+	this->VRAM.reset(new uint8_t[0x10000]);
265
+	this->RealROM.reset(new uint8_t[MAX_ROM_SIZE + 0x200 + 0x8000]);
1039 266
 
1040
-	//Settings.DisplayColor = BUILD_PIXEL(0, 31, 31);
1041
-	//SET_UI_COLOR(0, 255, 255);
1042
-
1043
-	uint8_t	*tmp = (uint8_t *) malloc(0x80000);
1044
-	if (tmp)
267
+	if (!this->RAM || !this->SRAM || !this->VRAM || !this->RealROM)
1045 268
 	{
1046
-		memmove(tmp, &base[0x180000], 0x80000);
1047
-		memmove(&base[0x180000], &base[0x200000], 0x80000);
1048
-		memmove(&base[0x200000], &base[0x280000], 0x80000);
1049
-		memmove(&base[0x280000], tmp, 0x80000);
1050
-
1051
-		free(tmp);
1052
-
1053
-		S9xDeinterleaveType1(size, base);
269
+		this->Deinit();
270
+		return false;
1054 271
 	}
1055
-}
1056
-
1057
-// allocation and deallocation
1058 272
 
1059
-bool CMemory::Init()
1060
-{
1061
-    RAM	 = (uint8_t *) malloc(0x20000);
1062
-    SRAM = (uint8_t *) malloc(0x20000);
1063
-    VRAM = (uint8_t *) malloc(0x10000);
1064
-    ROM  = (uint8_t *) malloc(MAX_ROM_SIZE + 0x200 + 0x8000);
1065
-
1066
-	IPPU.TileCache[TILE_2BIT]       = (uint8_t *) malloc(MAX_2BIT_TILES * 64);
1067
-	IPPU.TileCache[TILE_4BIT]       = (uint8_t *) malloc(MAX_4BIT_TILES * 64);
1068
-	IPPU.TileCache[TILE_8BIT]       = (uint8_t *) malloc(MAX_8BIT_TILES * 64);
1069
-	IPPU.TileCache[TILE_2BIT_EVEN]  = (uint8_t *) malloc(MAX_2BIT_TILES * 64);
1070
-	IPPU.TileCache[TILE_2BIT_ODD]   = (uint8_t *) malloc(MAX_2BIT_TILES * 64);
1071
-	IPPU.TileCache[TILE_4BIT_EVEN]  = (uint8_t *) malloc(MAX_4BIT_TILES * 64);
1072
-	IPPU.TileCache[TILE_4BIT_ODD]   = (uint8_t *) malloc(MAX_4BIT_TILES * 64);
1073
-
1074
-	IPPU.TileCached[TILE_2BIT]      = (uint8_t *) malloc(MAX_2BIT_TILES);
1075
-	IPPU.TileCached[TILE_4BIT]      = (uint8_t *) malloc(MAX_4BIT_TILES);
1076
-	IPPU.TileCached[TILE_8BIT]      = (uint8_t *) malloc(MAX_8BIT_TILES);
1077
-	IPPU.TileCached[TILE_2BIT_EVEN] = (uint8_t *) malloc(MAX_2BIT_TILES);
1078
-	IPPU.TileCached[TILE_2BIT_ODD]  = (uint8_t *) malloc(MAX_2BIT_TILES);
1079
-	IPPU.TileCached[TILE_4BIT_EVEN] = (uint8_t *) malloc(MAX_4BIT_TILES);
1080
-	IPPU.TileCached[TILE_4BIT_ODD]  = (uint8_t *) malloc(MAX_4BIT_TILES);
1081
-
1082
-	if (!RAM || !SRAM || !VRAM || !ROM ||
1083
-		!IPPU.TileCache[TILE_2BIT]       ||
1084
-		!IPPU.TileCache[TILE_4BIT]       ||
1085
-		!IPPU.TileCache[TILE_8BIT]       ||
1086
-		!IPPU.TileCache[TILE_2BIT_EVEN]  ||
1087
-		!IPPU.TileCache[TILE_2BIT_ODD]   ||
1088
-		!IPPU.TileCache[TILE_4BIT_EVEN]  ||
1089
-		!IPPU.TileCache[TILE_4BIT_ODD]   ||
1090
-		!IPPU.TileCached[TILE_2BIT]      ||
1091
-		!IPPU.TileCached[TILE_4BIT]      ||
1092
-		!IPPU.TileCached[TILE_8BIT]      ||
1093
-		!IPPU.TileCached[TILE_2BIT_EVEN] ||
1094
-		!IPPU.TileCached[TILE_2BIT_ODD]  ||
1095
-		!IPPU.TileCached[TILE_4BIT_EVEN] ||
1096
-		!IPPU.TileCached[TILE_4BIT_ODD])
1097
-    {
1098
-		Deinit();
1099
-		return false;
1100
-    }
1101
-
1102
-	ZeroMemory(RAM,  0x20000);
1103
-	ZeroMemory(SRAM, 0x20000);
1104
-	ZeroMemory(VRAM, 0x10000);
1105
-	ZeroMemory(ROM,  MAX_ROM_SIZE + 0x200 + 0x8000);
1106
-
1107
-	ZeroMemory(IPPU.TileCache[TILE_2BIT],       MAX_2BIT_TILES * 64);
1108
-	ZeroMemory(IPPU.TileCache[TILE_4BIT],       MAX_4BIT_TILES * 64);
1109
-	ZeroMemory(IPPU.TileCache[TILE_8BIT],       MAX_8BIT_TILES * 64);
1110
-	ZeroMemory(IPPU.TileCache[TILE_2BIT_EVEN],  MAX_2BIT_TILES * 64);
1111
-	ZeroMemory(IPPU.TileCache[TILE_2BIT_ODD],   MAX_2BIT_TILES * 64);
1112
-	ZeroMemory(IPPU.TileCache[TILE_4BIT_EVEN],  MAX_4BIT_TILES * 64);
1113
-	ZeroMemory(IPPU.TileCache[TILE_4BIT_ODD],   MAX_4BIT_TILES * 64);
1114
-
1115
-	ZeroMemory(IPPU.TileCached[TILE_2BIT],      MAX_2BIT_TILES);
1116
-	ZeroMemory(IPPU.TileCached[TILE_4BIT],      MAX_4BIT_TILES);
1117
-	ZeroMemory(IPPU.TileCached[TILE_8BIT],      MAX_8BIT_TILES);
1118
-	ZeroMemory(IPPU.TileCached[TILE_2BIT_EVEN], MAX_2BIT_TILES);
1119
-	ZeroMemory(IPPU.TileCached[TILE_2BIT_ODD],  MAX_2BIT_TILES);
1120
-	ZeroMemory(IPPU.TileCached[TILE_4BIT_EVEN], MAX_4BIT_TILES);
1121
-	ZeroMemory(IPPU.TileCached[TILE_4BIT_ODD],  MAX_4BIT_TILES);
273
+	std::fill(&this->RAM[0], &this->RAM[0x20000], 0);
274
+	std::fill(&this->SRAM[0], &this->SRAM[0x20000], 0);
275
+	std::fill(&this->VRAM[0], &this->VRAM[0x10000], 0);
276
+	std::fill(&this->RealROM[0], &this->RealROM[MAX_ROM_SIZE + 0x200 + 0x8000], 0);
1122 277
 
1123 278
 	// FillRAM uses first 32K of ROM image area, otherwise space just
1124 279
 	// wasted. Might be read by the SuperFX code.
1125 280
 
1126
-	FillRAM = ROM;
281
+	this->FillRAM = &this->RealROM[0];
1127 282
 
1128 283
 	// Add 0x8000 to ROM image pointer to stop SuperFX code accessing
1129 284
 	// unallocated memory (can cause crash on some ports).
1130 285
 
1131
-	ROM += 0x8000;
1132
-
1133
-	C4RAM   = ROM + 0x400000 + 8192 * 8; // C4
1134
-	OBC1RAM = ROM + 0x400000; // OBC1
1135
-	BIOSROM = ROM + 0x300000; // BS
1136
-	BSRAM   = ROM + 0x400000; // BS
1137
-
1138
-	/*SuperFX.pvRegisters = FillRAM + 0x3000;
1139
-	SuperFX.nRamBanks   = 2; // Most only use 1.  1=64KB=512Mb, 2=128KB=1024Mb
1140
-	SuperFX.pvRam       = SRAM;
1141
-	SuperFX.nRomBanks   = (2 * 1024 * 1024) / (32 * 1024);
1142
-	SuperFX.pvRom       = (uint8_t *) ROM;*/
1143
-
1144
-	PostRomInitFunc = NULL;
286
+	this->ROM = &this->RealROM[0x8000];
1145 287
 
1146 288
 	return true;
1147 289
 }
1148 290
 
1149 291
 void CMemory::Deinit()
1150 292
 {
1151
-	if (RAM)
1152
-	{
1153
-		free(RAM);
1154
-		RAM = NULL;
1155
-	}
1156
-
1157
-	if (SRAM)
1158
-	{
1159
-		free(SRAM);
1160
-		SRAM = NULL;
1161
-	}
293
+	this->RAM.reset();
294
+	this->SRAM.reset();
295
+	this->VRAM.reset();
296
+	this->ROM = nullptr;
297
+	this->RealROM.reset();
1162 298
 
1163
-	if (VRAM)
1164
-	{
1165
-		free(VRAM);
1166
-		VRAM = NULL;
1167
-	}
1168
-
1169
-	if (ROM)
1170
-	{
1171
-		ROM -= 0x8000;
1172
-		free(ROM);
1173
-		ROM = NULL;
1174
-	}
1175
-
1176
-	for (int t = 0; t < 7; t++)
1177
-	{
1178
-		if (IPPU.TileCache[t])
1179
-		{
1180
-			free(IPPU.TileCache[t]);
1181
-			IPPU.TileCache[t] = NULL;
1182
-		}
1183
-
1184
-		if (IPPU.TileCached[t])
1185
-		{
1186
-			free(IPPU.TileCached[t]);
1187
-			IPPU.TileCached[t] = NULL;
1188
-		}
1189
-	}
1190
-
1191
-	Safe(NULL);
1192
-	SafeANK(NULL);
299
+	this->Safe(nullptr);
1193 300
 }
1194 301
 
1195 302
 // file management and ROM detection
1196 303
 
1197
-static bool allASCII (uint8_t *b, int size)
304
+static bool allASCII(uint8_t *b, int size)
1198 305
 {
1199
-	for (int i = 0; i < size; i++)
1200
-	{
306
+	for (int i = 0; i < size; ++i)
1201 307
 		if (b[i] < 32 || b[i] > 126)
1202 308
 			return false;
1203
-	}
1204 309
 
1205 310
 	return true;
1206 311
 }
1207 312
 
1208
-/*static bool is_SufamiTurbo_BIOS (uint8_t *data, uint32_t size)
313
+int CMemory::ScoreHiROM(bool skip_header, int32_t romoff)
1209 314
 {
1210
-	if (size == 0x40000 &&
1211
-		strncmp((char *) data, "BANDAI SFC-ADX", 14) == 0 && strncmp((char * ) (data + 0x10), "SFC-ADX BACKUP", 14) == 0)
1212
-		return true;
1213
-	else
1214
-		return false;
1215
-}*/
1216
-
1217
-/*static bool is_SufamiTurbo_Cart (uint8_t *data, uint32_t size)
1218
-{
1219
-	if (size >= 0x80000 && size <= 0x100000 &&
1220
-		strncmp((char *) data, "BANDAI SFC-ADX", 14) == 0 && strncmp((char * ) (data + 0x10), "SFC-ADX BACKUP", 14) != 0)
1221
-		return true;
1222
-	else
1223
-		return false;
1224
-}*/
1225
-
1226
-/*static bool is_SameGame_BIOS (uint8_t *data, uint32_t size)
1227
-{
1228
-	if (size == 0x100000 && strncmp((char *) (data + 0xffc0), "Same Game Tsume Game", 20) == 0)
1229
-		return true;
1230
-	else
1231
-		return false;
1232
-}*/
1233
-
1234
-/*static bool is_SameGame_Add_On (uint8_t *data, uint32_t size)
1235
-{
1236
-	if (size == 0x80000)
1237
-		return true;
1238
-	else
1239
-		return false;
1240
-}*/
1241
-
1242
-int CMemory::ScoreHiROM (bool skip_header, int32_t romoff)
1243
-{
1244
-	uint8_t	*buf = ROM + 0xff00 + romoff + (skip_header ? 0x200 : 0);
1245
-	int		score = 0;
315
+	uint8_t *buf = &this->ROM[0xff00 + romoff + (skip_header ? 0x200 : 0)];
316
+	int score = 0;
1246 317
 
1247 318
 	if (buf[0xd5] & 0x1)
1248 319
 		score += 2;
... ...
@@ -1257,8 +328,8 @@ int CMemory::ScoreHiROM (bool skip_header, int32_t romoff)
1257 328
 	if ((buf[0xdc] + (buf[0xdd] << 8)) + (buf[0xde] + (buf[0xdf] << 8)) == 0xffff)
1258 329
 	{
1259 330
 		score += 2;
1260
-		if (0 != (buf[0xde] + (buf[0xdf] << 8)))
1261
-			score++;
331
+		if (buf[0xde] + (buf[0xdf] << 8))
332
+			++score;
1262 333
 	}
1263 334
 
1264 335
 	if (buf[0xda] == 0x33)
... ...
@@ -1273,25 +344,25 @@ int CMemory::ScoreHiROM (bool skip_header, int32_t romoff)
1273 344
 	if ((buf[0xfc] + (buf[0xfd] << 8)) > 0xffb0)
1274 345
 		score -= 2; // reduced after looking at a scan by Cowering
1275 346
 
1276
-	if (CalculatedSize > 1024 * 1024 * 3)
347
+	if (this->CalculatedSize > 1024 * 1024 * 3)
1277 348
 		score += 4;
1278 349
 
1279 350
 	if ((1 << (buf[0xd7] - 7)) > 48)
1280
-		score -= 1;
351
+		--score;
1281 352
 
1282 353
 	if (!allASCII(&buf[0xb0], 6))
1283
-		score -= 1;
354
+		--score;
1284 355
 
1285 356
 	if (!allASCII(&buf[0xc0], ROM_NAME_LEN - 1))
1286
-		score -= 1;
357
+		--score;
1287 358
 
1288 359
 	return score;
1289 360
 }
1290 361
 
1291
-int CMemory::ScoreLoROM (bool skip_header, int32_t romoff)
362
+int CMemory::ScoreLoROM(bool skip_header, int32_t romoff)
1292 363
 {
1293
-	uint8_t	*buf = ROM + 0x7f00 + romoff + (skip_header ? 0x200 : 0);
1294
-	int		score = 0;
364
+	uint8_t *buf = &this->ROM[0x7f00 + romoff + (skip_header ? 0x200 : 0)];
365
+	int score = 0;
1295 366
 
1296 367
 	if (!(buf[0xd5] & 0x1))
1297 368
 		score += 3;
... ...
@@ -1303,8 +374,8 @@ int CMemory::ScoreLoROM (bool skip_header, int32_t romoff)
1303 374
 	if ((buf[0xdc] + (buf[0xdd] << 8)) + (buf[0xde] + (buf[0xdf] << 8)) == 0xffff)
1304 375
 	{
1305 376
 		score += 2;
1306
-		if (0 != (buf[0xde] + (buf[0xdf] << 8)))
1307
-			score++;
377
+		if (buf[0xde] + (buf[0xdf] << 8))
378
+			++score;
1308 379
 	}
1309 380
 
1310 381
 	if (buf[0xda] == 0x33)
... ...
@@ -1319,281 +390,99 @@ int CMemory::ScoreLoROM (bool skip_header, int32_t romoff)
1319 390
 	if ((buf[0xfc] + (buf[0xfd] << 8)) > 0xffb0)
1320 391
 		score -= 2; // reduced per Cowering suggestion
1321 392
 
1322
-	if (CalculatedSize <= 1024 * 1024 * 16)
393
+	if (this->CalculatedSize <= 1024 * 1024 * 16)
1323 394
 		score += 2;
1324 395
 
1325 396
 	if ((1 << (buf[0xd7] - 7)) > 48)
1326
-		score -= 1;
397
+		--score;
1327 398
 
1328 399
 	if (!allASCII(&buf[0xb0], 6))
1329
-		score -= 1;
400
+		--score;
1330 401
 
1331 402
 	if (!allASCII(&buf[0xc0], ROM_NAME_LEN - 1))
1332
-		score -= 1;
403
+		--score;
1333 404
 
1334 405
 	return score;
1335 406
 }
1336 407
 
1337
-/*uint32_t CMemory::HeaderRemove (uint32_t size, int32_t &headerCount, uint8_t *buf)
1338
-{
1339
-	uint32_t	calc_size = (size / 0x2000) * 0x2000;
1340
-
1341
-	if ((size - calc_size == 512 && !Settings.ForceNoHeader) || Settings.ForceHeader)
1342
-	{
1343
-		uint8_t	*NSRTHead = buf + 0x1D0; // NSRT Header Location
1344
-
1345
-		// detect NSRT header
1346
-		if (!strncmp("NSRT", (char *) &NSRTHead[24], 4))
1347
-		{
1348
-			if (NSRTHead[28] == 22)
1349
-			{
1350
-				if (((std::accumulate(NSRTHead, NSRTHead + sizeof(NSRTHeader), 0) & 0xFF) == NSRTHead[30]) &&
1351
-					(NSRTHead[30] + NSRTHead[31] == 255) && ((NSRTHead[0] & 0x0F) <= 13) &&
1352
-					(((NSRTHead[0] & 0xF0) >> 4) <= 3) && ((NSRTHead[0] & 0xF0) >> 4))
1353
-					memcpy(NSRTHeader, NSRTHead, sizeof(NSRTHeader));
1354
-			}
1355
-		}
1356
-
1357
-		memmove(buf, buf + 512, calc_size);
1358
-		headerCount++;
1359
-		size -= 512;
1360
-	}
1361
-
1362
-	return size;
1363
-}*/
1364
-
1365
-/*uint32_t CMemory::FileLoader (uint8_t *buffer, const char *filename, int32_t maxsize)
1366
-{
1367
-	// <- ROM size without header
1368
-	// ** Memory.HeaderCount
1369
-	// ** Memory.ROMFilename
1370
-
1371
-	int32_t	totalSize = 0;
1372
-    char	fname[PATH_MAX + 1];
1373
-    char	drive[_MAX_DRIVE + 1], dir[_MAX_DIR + 1], name[_MAX_FNAME + 1], exts[_MAX_EXT + 1];
1374
-	char	*ext;
1375
-
1376
-#if defined(_WIN32) || defined(__MACOSX__)
1377
-	ext = &exts[1];
1378
-#else
1379
-	ext = &exts[0];
1380
-#endif
1381
-
1382
-	memset(NSRTHeader, 0, sizeof(NSRTHeader));
1383
-	HeaderCount = 0;
1384
-
1385
-	_splitpath(filename, drive, dir, name, exts);
1386
-	_makepath(fname, drive, dir, name, exts);
1387
-
1388
-	int	nFormat = FILE_DEFAULT;
1389
-	if (strcasecmp(ext, "zip") == 0)
1390
-		nFormat = FILE_ZIP;
1391
-	else
1392
-	if (strcasecmp(ext, "jma") == 0)
1393
-		nFormat = FILE_JMA;
1394
-
1395
-	switch (nFormat)
1396
-	{
1397
-		case FILE_ZIP:
1398
-		{
1399
-		#ifdef UNZIP_SUPPORT
1400
-			if (!LoadZip(fname, &totalSize, &HeaderCount, buffer))
1401
-			{
1402
-			 	S9xMessage(S9X_ERROR, S9X_ROM_INFO, "Invalid Zip archive.");
1403
-				return 0;
1404
-			}
1405
-
1406
-			strcpy(ROMFilename, fname);
1407
-		#else
1408
-			//S9xMessage(S9X_ERROR, S9X_ROM_INFO, "This binary was not created with Zip support.");
1409
-			return 0;
1410
-		#endif
1411
-			break;
1412
-		}
1413
-
1414
-		case FILE_JMA:
1415
-		{
1416
-		#ifdef JMA_SUPPORT
1417
-			size_t	size = load_jma_file(fname, buffer);
1418
-			if (!size)
1419
-			{
1420
-			 	S9xMessage(S9X_ERROR, S9X_ROM_INFO, "Invalid JMA archive.");
1421
-				return 0;
1422
-			}
1423
-
1424
-			totalSize = HeaderRemove(size, HeaderCount, buffer);
1425
-
1426
-			strcpy(ROMFilename, fname);
1427
-		#else
1428
-			//S9xMessage(S9X_ERROR, S9X_ROM_INFO, "This binary was not created with JMA support.");
1429
-			return 0;
1430
-		#endif
1431
-			break;
1432
-		}
1433
-
1434
-		case FILE_DEFAULT:
1435
-		default:
1436
-		{
1437
-			STREAM	fp = OPEN_STREAM(fname, "rb");
1438
-			if (!fp)
1439
-				return 0;
1440
-
1441
-			strcpy(ROMFilename, fname);
1442
-
1443
-			int 	len  = 0;
1444
-			uint32_t	size = 0;
1445
-			bool	more = false;
1446
-			uint8_t	*ptr = buffer;
1447
-
1448
-			do
1449
-			{
1450
-				size = READ_STREAM(ptr, maxsize + 0x200 - (ptr - buffer), fp);
1451
-				CLOSE_STREAM(fp);
1452
-
1453
-				size = HeaderRemove(size, HeaderCount, ptr);
1454
-				totalSize += size;
1455
-				ptr += size;
1456
-
1457
-				// check for multi file roms
1458
-				if (ptr - buffer < maxsize + 0x200 &&
1459
-					(isdigit(ext[0]) && ext[1] == 0 && ext[0] < '9'))
1460
-				{
1461
-					more = true;
1462
-					ext[0]++;
1463
-					_makepath(fname, drive, dir, name, exts);
1464
-				}
1465
-				else
1466
-				if (ptr - buffer < maxsize + 0x200 &&
1467
-					(((len = strlen(name)) == 7 || len == 8) &&
1468
-					strncasecmp(name, "sf", 2) == 0 &&
1469
-					isdigit(name[2]) && isdigit(name[3]) && isdigit(name[4]) && isdigit(name[5]) &&
1470
-					isalpha(name[len - 1])))
1471
-				{
1472
-					more = true;
1473
-					name[len - 1]++;
1474
-					_makepath(fname, drive, dir, name, exts);
1475
-				}
1476
-				else
1477
-					more = false;
1478
-
1479
-			}	while (more && (fp = OPEN_STREAM(fname, "rb")) != NULL);
1480
-
1481
-			break;
1482
-		}
1483
-	}
1484
-
1485
-    if (HeaderCount == 0)
1486
-		S9xMessage(S9X_INFO, S9X_HEADERS_INFO, "No ROM file header found.");
1487
-    else
1488
-    if (HeaderCount == 1)
1489
-		S9xMessage(S9X_INFO, S9X_HEADERS_INFO, "Found ROM file header (and ignored it).");
1490
-	else
1491
-		S9xMessage(S9X_INFO, S9X_HEADERS_INFO, "Found multiple ROM file headers (and ignored them).");
1492
-
1493
-	return (uint32_t) totalSize;
1494
-}*/
1495
-
1496
-//bool CMemory::LoadROM (const char *filename)
1497
-bool CMemory::LoadROMSNSF(const unsigned char *lrombuf, int32_t lromsize, const unsigned char *srambuf, int32_t sramsize)
408
+bool CMemory::LoadROMSNSF(const uint8_t *lrombuf, int32_t lromsize, const uint8_t *srambuf, int32_t sramsize)
1498 409
 {
1499
-	int	retry_count = 0;
410
+	int retry_count = 0;
1500 411
 
1501
-	/*if (!filename || !*filename)
1502
-		return false;*/
1503
-
1504
-	ZeroMemory(ROM, MAX_ROM_SIZE);
1505
-	ZeroMemory(&Multi, sizeof(Multi));
412
+	std::fill(&this->ROM[0], &this->ROM[MAX_ROM_SIZE], 0);
1506 413
 
1507 414
 again:
1508
-	//Settings.DisplayColor = BUILD_PIXEL(31, 31, 31);
1509
-	//SET_UI_COLOR(255, 255, 255);
1510
-
1511
-	CalculatedSize = 0;
1512
-	ExtendedFormat = NOPE;
415
+	this->CalculatedSize = 0;
416
+	this->ExtendedFormat = NOPE;
1513 417
 
1514
-	int32_t totalFileSize;
1515
-
1516
-	//totalFileSize = FileLoader(ROM, filename, MAX_ROM_SIZE);
1517
-	totalFileSize  = std::min<int32_t>(MAX_ROM_SIZE, lromsize);
418
+	int32_t totalFileSize = std::min<int32_t>(MAX_ROM_SIZE, lromsize);
1518 419
 	if (!totalFileSize)
1519 420
 		return false;
1520
-	memcpy(ROM, lrombuf, totalFileSize);
421
+	std::copy(&lrombuf[0], &lrombuf[totalFileSize], &this->ROM[0]);
1521 422
 	SNESGameFixes.SRAMInitialValue = 0xff;
1522
-	memset(SRAM, SNESGameFixes.SRAMInitialValue, 0x20000);
423
+	std::fill(&this->SRAM[0], &this->SRAM[0x20000], SNESGameFixes.SRAMInitialValue);
1523 424
 	if (srambuf && sramsize)
1524
-		memcpy(SRAM, srambuf, sramsize);
1525
-
1526
-	/*if (!Settings.NoPatch)
1527
-		CheckForAnyPatch(filename, HeaderCount != 0, totalFileSize);*/
425
+		std::copy(&srambuf[0], &srambuf[sramsize], &this->SRAM[0]);
1528 426
 
1529
-	int	hi_score, lo_score;
427
+	int hi_score = this->ScoreHiROM(false);
428
+	int lo_score = this->ScoreLoROM(false);
1530 429
 
1531
-	hi_score = ScoreHiROM(false);
1532
-	lo_score = ScoreLoROM(false);
1533
-
1534
-	if (HeaderCount == 0 && !Settings.ForceNoHeader &&
1535
-		((hi_score >  lo_score && ScoreHiROM(true) > hi_score) ||
1536
-		 (hi_score <= lo_score && ScoreLoROM(true) > lo_score)))
430
+	if (((hi_score > lo_score && this->ScoreHiROM(true) > hi_score) || (hi_score <= lo_score && this->ScoreLoROM(true) > lo_score)))
1537 431
 	{
1538
-		memmove(ROM, ROM + 512, totalFileSize - 512);
432
+		memmove(&this->ROM[0], &this->ROM[512], totalFileSize - 512);
1539 433
 		totalFileSize -= 512;
1540
-		//S9xMessage(S9X_INFO, S9X_HEADER_WARNING, "Try 'force no-header' option if the game doesn't work");
1541 434
 		// modifying ROM, so we need to rescore
1542
-		hi_score = ScoreHiROM(false);
1543
-		lo_score = ScoreLoROM(false);
435
+		hi_score = this->ScoreHiROM(false);
436
+		lo_score = this->ScoreLoROM(false);
1544 437
 	}
1545 438
 
1546
-	CalculatedSize = (totalFileSize / 0x2000) * 0x2000;
439
+	this->CalculatedSize = (totalFileSize / 0x2000) * 0x2000;
1547 440
 
1548
-	if (CalculatedSize > 0x400000 &&
1549
-		(ROM[0x7fd5] + (ROM[0x7fd6] << 8)) != 0x4332 && // exclude S-DD1
1550
-		(ROM[0x7fd5] + (ROM[0x7fd6] << 8)) != 0x4532 &&
1551
-		(ROM[0xffd5] + (ROM[0xffd6] << 8)) != 0xF93a && // exclude SPC7110
1552
-		(ROM[0xffd5] + (ROM[0xffd6] << 8)) != 0xF53a)
1553
-		ExtendedFormat = YEAH;
441
+	if (this->CalculatedSize > 0x400000 &&
442
+		this->ROM[0x7fd5] + (this->ROM[0x7fd6] << 8) != 0x4332 && // exclude S-DD1
443
+		this->ROM[0x7fd5] + (this->ROM[0x7fd6] << 8) != 0x4532 &&
444
+		this->ROM[0xffd5] + (this->ROM[0xffd6] << 8) != 0xF93a && // exclude SPC7110
445
+		this->ROM[0xffd5] + (this->ROM[0xffd6] << 8) != 0xF53a)
446
+		this->ExtendedFormat = YEAH;
1554 447
 
1555 448
 	// if both vectors are invalid, it's type 1 interleaved LoROM
1556
-	if (ExtendedFormat == NOPE &&
1557
-		((ROM[0x7ffc] + (ROM[0x7ffd] << 8)) < 0x8000) &&
1558
-		((ROM[0xfffc] + (ROM[0xfffd] << 8)) < 0x8000))
449
+	if (this->ExtendedFormat == NOPE && this->ROM[0x7ffc] + (this->ROM[0x7ffd] << 8) < 0x8000 && this->ROM[0xfffc] + (this->ROM[0xfffd] << 8) < 0x8000)
1559 450
 	{
1560
-		if (!Settings.ForceInterleaved && !Settings.ForceNotInterleaved)
1561
-			S9xDeinterleaveType1(totalFileSize, ROM);
451
+		if (!Settings.ForceNotInterleaved)
452
+			S9xDeinterleaveType1(totalFileSize, &this->ROM[0]);
1562 453
 	}
1563 454
 
1564 455
 	// CalculatedSize is now set, so rescore
1565
-	hi_score = ScoreHiROM(false);
1566
-	lo_score = ScoreLoROM(false);
456
+	hi_score = this->ScoreHiROM(false);
457
+	lo_score = this->ScoreLoROM(false);
1567 458
 
1568
-	uint8_t	*RomHeader = ROM;
459
+	uint8_t *RomHeader = &this->ROM[0];
1569 460
 
1570
-	if (ExtendedFormat != NOPE)
461
+	if (this->ExtendedFormat != NOPE)
1571 462
 	{
1572
-		int	swappedhirom, swappedlorom;
1573
-
1574
-		swappedhirom = ScoreHiROM(false, 0x400000);
1575
-		swappedlorom = ScoreLoROM(false, 0x400000);
463
+		int swappedhirom = this->ScoreHiROM(false, 0x400000);
464
+		int swappedlorom = this->ScoreLoROM(false, 0x400000);
1576 465
 
1577 466
 		// set swapped here
1578 467
 		if (std::max(swappedlorom, swappedhirom) >= std::max(lo_score, hi_score))
1579 468
 		{
1580
-			ExtendedFormat = BIGFIRST;
469
+			this->ExtendedFormat = BIGFIRST;
1581 470
 			hi_score = swappedhirom;
1582 471
 			lo_score = swappedlorom;
1583 472
 			RomHeader += 0x400000;
1584 473
 		}
1585 474
 		else
1586
-			ExtendedFormat = SMALLFIRST;
475
+			this->ExtendedFormat = SMALLFIRST;
1587 476
 	}
1588 477
 
1589
-	bool	interleaved, tales = false;
478
+	bool tales = false;
1590 479
 
1591
-    interleaved = Settings.ForceInterleaved || Settings.ForceInterleaved2 || Settings.ForceInterleaveGD24;
480
+	bool interleaved = false;
1592 481
 
1593
-	if (Settings.ForceLoROM || (!Settings.ForceHiROM && lo_score >= hi_score))
482
+	if (lo_score >= hi_score)
1594 483
 	{
1595
-		LoROM = true;
1596
-		HiROM = false;
484
+		this->LoROM = true;
485
+		this->HiROM = false;
1597 486
 
1598 487
 		// ignore map type byte if not 0x2x or 0x3x
1599 488
 		if ((RomHeader[0x7fd5] & 0xf0) == 0x20 || (RomHeader[0x7fd5] & 0xf0) == 0x30)
... ...
@@ -1613,8 +502,8 @@ again:
1613 502
 	}
1614 503
 	else
1615 504
 	{
1616
-		LoROM = false;
1617
-		HiROM = true;
505
+		this->LoROM = false;
506
+		this->HiROM = true;
1618 507
 
1619 508
 		if ((RomHeader[0xffd5] & 0xf0) == 0x20 || (RomHeader[0xffd5] & 0xf0) == 0x30)
1620 509
 		{
... ...
@@ -1629,2698 +518,626 @@ again:
1629 518
 	}
1630 519
 
1631 520
 	// this two games fail to be detected
1632
-	if (!Settings.ForceHiROM && !Settings.ForceLoROM)
521
+	if (!strncmp(reinterpret_cast<char *>(&this->ROM[0x7fc0]), "YUYU NO QUIZ DE GO!GO!", 22) || !strncmp(reinterpret_cast<char *>(&this->ROM[0xffc0]), "BATMAN--REVENGE JOKER",  21))
1633 522
 	{
1634
-		if (strncmp((char *) &ROM[0x7fc0], "YUYU NO QUIZ DE GO!GO!", 22) == 0 ||
1635
-		   (strncmp((char *) &ROM[0xffc0], "BATMAN--REVENGE JOKER",  21) == 0))
1636
-		{
1637
-			LoROM = true;
1638
-			HiROM = false;
1639
-			interleaved = false;
1640
-			tales = false;
1641
-		}
523
+		this->LoROM = true;
524
+		this->HiROM = false;
525
+		interleaved = false;
526
+		tales = false;
1642 527
 	}
1643 528
 
1644 529
 	if (!Settings.ForceNotInterleaved && interleaved)
1645 530
 	{
1646
-		//S9xMessage(S9X_INFO, S9X_ROM_INTERLEAVED_INFO, "ROM image is in interleaved format - converting...");
1647
-
1648 531
 		if (tales)
1649 532
 		{
1650
-			if (ExtendedFormat == BIGFIRST)
533
+			if (this->ExtendedFormat == BIGFIRST)
1651 534
 			{
1652
-				S9xDeinterleaveType1(0x400000, ROM);
1653
-				S9xDeinterleaveType1(CalculatedSize - 0x400000, ROM + 0x400000);
535
+				S9xDeinterleaveType1(0x400000, &this->ROM[0]);
536
+				S9xDeinterleaveType1(this->CalculatedSize - 0x400000, &this->ROM[0x400000]);
1654 537
 			}
1655 538
 			else
1656 539
 			{
1657
-				S9xDeinterleaveType1(CalculatedSize - 0x400000, ROM);
1658
-				S9xDeinterleaveType1(0x400000, ROM + CalculatedSize - 0x400000);
540
+				S9xDeinterleaveType1(this->CalculatedSize - 0x400000, &this->ROM[0]);
541
+				S9xDeinterleaveType1(0x400000, &this->ROM[this->CalculatedSize - 0x400000]);
1659 542
 			}
1660 543
 
1661
-			LoROM = false;
1662
-			HiROM = true;
1663
-		}
1664
-		else
1665
-		if (Settings.ForceInterleaveGD24 && CalculatedSize == 0x300000)
1666
-		{
1667
-			bool	t = LoROM;
1668
-			LoROM = HiROM;
1669
-			HiROM = t;
1670
-			S9xDeinterleaveGD24(CalculatedSize, ROM);
544
+			this->LoROM = false;
545
+			this->HiROM = true;
1671 546
 		}
1672 547
 		else
1673
-		if (Settings.ForceInterleaved2)
1674
-			S9xDeinterleaveType2(CalculatedSize, ROM);
1675
-		else
1676 548
 		{
1677
-			bool	t = LoROM;
1678
-			LoROM = HiROM;
1679
-			HiROM = t;
1680
-			S9xDeinterleaveType1(CalculatedSize, ROM);
549
+			std::swap(this->LoROM, this->HiROM);
550
+			S9xDeinterleaveType1(this->CalculatedSize, &this->ROM[0]);
1681 551
 		}
1682 552
 
1683
-		hi_score = ScoreHiROM(false);
1684
-		lo_score = ScoreLoROM(false);
553
+		hi_score = this->ScoreHiROM(false);
554
+		lo_score = this->ScoreLoROM(false);
1685 555
 
1686
-		if ((HiROM && (lo_score >= hi_score || hi_score < 0)) ||
1687
-			(LoROM && (hi_score >  lo_score || lo_score < 0)))
556
+		if (((this->HiROM && (lo_score >= hi_score || hi_score < 0)) || (this->LoROM && (hi_score > lo_score || lo_score < 0))) && !retry_count)
1688 557
 		{
1689
-			if (retry_count == 0)
1690
-			{
1691
-				//S9xMessage(S9X_INFO, S9X_ROM_CONFUSING_FORMAT_INFO, "ROM lied about its type! Trying again.");
1692
-				Settings.ForceNotInterleaved = true;
1693
-				Settings.ForceInterleaved = false;
1694
-				retry_count++;
1695
-				goto again;
1696
-			}
558
+			Settings.ForceNotInterleaved = true;
559
+			++retry_count;
560
+			goto again;
1697 561
 		}
1698
-    }
562
+	}
1699 563
 
1700
-	if (ExtendedFormat == SMALLFIRST)
564
+	if (this->ExtendedFormat == SMALLFIRST)
1701 565
 		tales = true;
1702 566
 
1703 567
 	if (tales)
1704 568
 	{
1705
-		uint8_t	*tmp = (uint8_t *) malloc(CalculatedSize - 0x400000);
1706
-		if (tmp)
1707
-		{
1708
-			//S9xMessage(S9X_INFO, S9X_ROM_INTERLEAVED_INFO, "Fixing swapped ExHiROM...");
1709
-			memmove(tmp, ROM, CalculatedSize - 0x400000);
1710
-			memmove(ROM, ROM + CalculatedSize - 0x400000, 0x400000);
1711
-			memmove(ROM + 0x400000, tmp, CalculatedSize - 0x400000);
1712
-			free(tmp);
1713
-		}
569
+		auto tmp = std::vector<uint8_t>(this->CalculatedSize - 0x400000);
570
+		memmove(&tmp[0], &this->ROM[0], this->CalculatedSize - 0x400000);
571
+		memmove(&this->ROM[0], &this->ROM[this->CalculatedSize - 0x400000], 0x400000);
572
+		memmove(&this->ROM[0x400000], &tmp[0], this->CalculatedSize - 0x400000);
1714 573
 	}
1715 574
 
1716
-	/*if (strncmp(LastRomFilename, filename, PATH_MAX + 1))
1717
-	{
1718
-		strncpy(LastRomFilename, filename, PATH_MAX + 1);
1719
-		LastRomFilename[PATH_MAX] = 0;
1720
-	}*/
1721
-
1722
-	ZeroMemory(&SNESGameFixes, sizeof(SNESGameFixes));
575
+	memset(&SNESGameFixes, 0, sizeof(SNESGameFixes));
1723 576
 	SNESGameFixes.SRAMInitialValue = 0x60;
1724 577
 
1725
-	//S9xLoadCheatFile(S9xGetFilename(".cht", CHEAT_DIR));
1726
-
1727
-	InitROM();
1728
-
1729
-	/*S9xInitCheatData();
1730
-	S9xApplyCheats();*/
578
+	this->InitROM();
1731 579
 
1732 580
 	S9xReset();
1733 581
 
1734
-    return true;
582
+	return true;
1735 583
 }
1736 584
 
1737
-/*bool CMemory::LoadMultiCart (const char *cartA, const char *cartB)
1738
-{
1739
-	bool	r = true;
1740
-
1741
-	ZeroMemory(ROM, MAX_ROM_SIZE);
1742
-	ZeroMemory(&Multi, sizeof(Multi));
1743
-
1744
-	Settings.DisplayColor = BUILD_PIXEL(31, 31, 31);
1745
-	SET_UI_COLOR(255, 255, 255);
1746
-
1747
-	CalculatedSize = 0;
1748
-	ExtendedFormat = NOPE;
585
+// initialization
1749 586
 
1750
-	if (cartA && cartA[0])
1751
-		Multi.cartSizeA = FileLoader(ROM, cartA, MAX_ROM_SIZE);
587
+char *CMemory::Safe(const char *s)
588
+{
589
+	static std::unique_ptr<char[]> safe;
590
+	static int safe_len = 0;
1752 591
 
1753
-	if (Multi.cartSizeA == 0)
592
+	if (!s)
1754 593
 	{
1755
-		if (cartB && cartB[0])
1756
-			Multi.cartSizeB = FileLoader(ROM, cartB, MAX_ROM_SIZE);
1757
-	}
594
+		if (safe)
595
+			safe.reset();
1758 596
 
1759
-	if (Multi.cartSizeA)
1760
-	{
1761
-		if (is_SufamiTurbo_Cart(ROM, Multi.cartSizeA))
1762
-			Multi.cartType = 4;
1763
-		else
1764
-		if (is_SameGame_BIOS(ROM, Multi.cartSizeA))
1765
-			Multi.cartType = 3;
1766
-	}
1767
-	else
1768
-	if (Multi.cartSizeB)
1769
-	{
1770
-		if (is_SufamiTurbo_Cart(ROM, Multi.cartSizeB))
1771
-			Multi.cartType = 4;
597
+		return nullptr;
1772 598
 	}
1773
-	else
1774
-		Multi.cartType = 4; // assuming BIOS only
1775 599
 
1776
-	switch (Multi.cartType)
600
+	int len = strlen(s);
601
+	if (!safe || len + 1 > safe_len)
1777 602
 	{
1778
-		case 4:
1779
-			r = LoadSufamiTurbo(cartA, cartB);
1780
-			break;
1781
-
1782
-		case 3:
1783
-			r = LoadSameGame(cartA, cartB);
1784
-			break;
1785
-
1786
-		default:
1787
-			r = false;
603
+		safe_len = len + 1;
604
+		safe.reset(new char[safe_len]);
1788 605
 	}
1789 606
 
1790
-	if (!r)
607
+	for (int i = 0; i < len; ++i)
1791 608
 	{
1792
-		ZeroMemory(&Multi, sizeof(Multi));
1793
-		return false;
609
+		if (s[i] >= 32 && s[i] < 127)
610
+			safe[i] = s[i];
611
+		else
612
+			safe[i] = '_';
1794 613
 	}
1795 614
 
1796
-	ZeroMemory(&SNESGameFixes, sizeof(SNESGameFixes));
1797
-	SNESGameFixes.SRAMInitialValue = 0x60;
1798
-
1799
-	S9xLoadCheatFile(S9xGetFilename(".cht", CHEAT_DIR));
615
+	safe[len] = 0;
1800 616
 
1801
-	InitROM();
617
+	return safe.get();
618
+}
1802 619
 
1803
-	S9xInitCheatData();
1804
-	S9xApplyCheats();
620
+void CMemory::ParseSNESHeader(uint8_t *RomHeader)
621
+{
622
+	strncpy(this->ROMName, reinterpret_cast<char *>(&RomHeader[0x10]), ROM_NAME_LEN - 1);
1805 623
 
1806
-	S9xReset();
624
+	this->SRAMSize = RomHeader[0x28];
625
+	this->ROMSpeed = RomHeader[0x25];
626
+	this->ROMType = RomHeader[0x26];
627
+	this->ROMRegion = RomHeader[0x29];
1807 628
 
1808
-	return true;
629
+	std::copy(&RomHeader[0x02], &RomHeader[0x06], &this->ROMId[0]);
1809 630
 }
1810 631
 
1811
-bool CMemory::LoadSufamiTurbo (const char *cartA, const char *cartB)
632
+void CMemory::InitROM()
1812 633
 {
1813
-	Multi.cartOffsetA = 0x100000;
1814
-	Multi.cartOffsetB = 0x200000;
1815
-	Multi.sramA = SRAM;
1816
-	Multi.sramB = SRAM + 0x10000;
1817
-
1818
-	if (Multi.cartSizeA)
1819
-	{
1820
-		Multi.sramSizeA = 4; // ROM[0x37]?
1821
-		Multi.sramMaskA = Multi.sramSizeA ? ((1 << (Multi.sramSizeA + 3)) * 128 - 1) : 0;
1822
-
1823
-		if (!Settings.NoPatch)
1824
-			CheckForAnyPatch(cartA, HeaderCount != 0, Multi.cartSizeA);
634
+	//// Parse ROM header and read ROM informatoin
1825 635
 
1826
-		strcpy(Multi.fileNameA, cartA);
1827
-		memcpy(ROM + Multi.cartOffsetA, ROM, Multi.cartSizeA);
1828
-	}
636
+	std::fill(&this->ROMId[0], &this->ROMId[5], 0);
1829 637
 
1830
-	if (Multi.cartSizeA && !Multi.cartSizeB)
1831
-	{
1832
-		if (cartB && cartB[0])
1833
-			Multi.cartSizeB = FileLoader(ROM, cartB, MAX_ROM_SIZE);
638
+	uint8_t *RomHeader = &this->ROM[0x7FB0];
639
+	if (this->ExtendedFormat == BIGFIRST)
640
+		RomHeader += 0x400000;
641
+	if (this->HiROM)
642
+		RomHeader += 0x8000;
1834 643
 
1835
-		if (Multi.cartSizeB)
1836
-		{
1837
-			if (!is_SufamiTurbo_Cart(ROM, Multi.cartSizeB))
1838
-				Multi.cartSizeB = 0;
1839
-		}
1840
-	}
644
+	this->ParseSNESHeader(RomHeader);
1841 645
 
1842
-	if (Multi.cartSizeB)
1843
-	{
1844
-		Multi.sramSizeB = 4; // ROM[0x37]?
1845
-		Multi.sramMaskB = Multi.sramSizeB ? ((1 << (Multi.sramSizeB + 3)) * 128 - 1) : 0;
646
+	//// Detect and initialize chips
647
+	//// detection codes are compatible with NSRT
1846 648
 
1847
-		if (!Settings.NoPatch)
1848
-			CheckForAnyPatch(cartB, HeaderCount != 0, Multi.cartSizeB);
649
+	uint32_t identifier = ((this->ROMType & 0xff) << 8) + (this->ROMSpeed & 0xff);
1849 650
 
1850
-		strcpy(Multi.fileNameB, cartB);
1851
-		memcpy(ROM + Multi.cartOffsetB, ROM, Multi.cartSizeB);
1852
-	}
651
+	Settings.SDD1 = identifier == 0x4332 || identifier == 0x4532;
1853 652
 
1854
-	FILE	*fp;
1855
-	size_t	size;
1856
-	char	path[PATH_MAX + 1];
653
+	//// Map memory and calculate checksum
1857 654
 
1858
-	strcpy(path, S9xGetDirectory(BIOS_DIR));
1859
-	strcat(path, SLASH_STR);
1860
-	strcat(path, "STBIOS.bin");
655
+	this->Map_Initialize();
1861 656
 
1862
-	fp = fopen(path, "rb");
1863
-	if (fp)
657
+	if (this->HiROM)
1864 658
 	{
1865
-		size = fread((void *) ROM, 1, 0x40000, fp);
1866
-		fclose(fp);
1867
-		if (!is_SufamiTurbo_BIOS(ROM, size))
1868
-			return false;
659
+		if (this->ExtendedFormat != NOPE)
660
+			this->Map_ExtendedHiROMMap();
661
+		else
662
+			this->Map_HiROMMap();
1869 663
 	}
1870 664
 	else
1871
-		return false;
1872
-
1873
-	if (Multi.cartSizeA)
1874
-		strcpy(ROMFilename, Multi.fileNameA);
1875
-	else
1876
-	if (Multi.cartSizeB)
1877
-		strcpy(ROMFilename, Multi.fileNameB);
1878
-	else
1879
-		strcpy(ROMFilename, path);
1880
-
1881
-	LoROM = true;
1882
-	HiROM = false;
1883
-	CalculatedSize = 0x40000;
665
+	{
666
+		if (Settings.SDD1)
667
+			this->Map_SDD1LoROMMap();
668
+		else if (this->ExtendedFormat != NOPE)
669
+			this->Map_JumboLoROMMap();
670
+		else if (!strncmp(this->ROMName, "WANDERERS FROM YS", 17))
671
+			this->Map_NoMAD1LoROMMap();
672
+		else if (!strncmp(this->ROMName, "SOUND NOVEL-TCOOL", 17) || !strncmp(this->ROMName, "DERBY STALLION 96", 17))
673
+			this->Map_ROM24MBSLoROMMap();
674
+		else if (!strncmp(this->ROMName, "THOROUGHBRED BREEDER3", 21) || !strncmp(this->ROMName, "RPG-TCOOL 2", 11))
675
+			this->Map_SRAM512KLoROMMap();
676
+		else
677
+			this->Map_LoROMMap();
678
+	}
1884 679
 
1885
-	return true;
1886
-}
680
+	//// Build more ROM information
1887 681
 
1888
-bool CMemory::LoadSameGame (const char *cartA, const char *cartB)
1889
-{
1890
-	Multi.cartOffsetA = 0;
1891
-	Multi.cartOffsetB = 0x200000;
1892
-	Multi.sramA = SRAM;
1893
-	Multi.sramB = NULL;
682
+	// NTSC/PAL
683
+	Settings.PAL = this->ROMRegion >= 2 && this->ROMRegion <= 12;
1894 684
 
1895
-	Multi.sramSizeA = ROM[0xffd8];
1896
-	Multi.sramMaskA = Multi.sramSizeA ? ((1 << (Multi.sramSizeA + 3)) * 128 - 1) : 0;
1897
-	Multi.sramSizeB = 0;
1898
-	Multi.sramMaskB = 0;
685
+	// truncate cart name
686
+	this->ROMName[ROM_NAME_LEN - 1] = 0;
687
+	if (strlen(this->ROMName))
688
+	{
689
+		char *p = this->ROMName + strlen(this->ROMName);
690
+		if (p > this->ROMName + 21 && this->ROMName[20] == ' ')
691
+			p = this->ROMName + 21;
692
+		while (p > this->ROMName && *(p - 1) == ' ')
693
+			--p;
694
+		*p = 0;
695
+	}
1899 696
 
1900
-	if (!Settings.NoPatch)
1901
-		CheckForAnyPatch(cartA, HeaderCount != 0, Multi.cartSizeA);
697
+	// SRAM size
698
+	this->SRAMMask = this->SRAMSize ? ((1 << (this->SRAMSize + 3)) * 128) - 1 : 0;
1902 699
 
1903
-	strcpy(Multi.fileNameA, cartA);
700
+	//// Initialize emulation
1904 701
 
1905
-	if (cartB && cartB[0])
1906
-		Multi.cartSizeB = FileLoader(ROM + Multi.cartOffsetB, cartB, MAX_ROM_SIZE - Multi.cartOffsetB);
702
+	Timings.H_Max_Master = SNES_CYCLES_PER_SCANLINE;
703
+	Timings.H_Max = Timings.H_Max_Master;
704
+	Timings.HBlankStart = SNES_HBLANK_START_HC;
705
+	Timings.HBlankEnd = SNES_HBLANK_END_HC;
706
+	Timings.HDMAInit = SNES_HDMA_INIT_HC;
707
+	Timings.HDMAStart = SNES_HDMA_START_HC;
708
+	Timings.RenderPos = SNES_RENDER_START_HC;
709
+	Timings.V_Max_Master = Settings.PAL ? SNES_MAX_PAL_VCOUNTER : SNES_MAX_NTSC_VCOUNTER;
710
+	Timings.V_Max = Timings.V_Max_Master;
711
+	/* From byuu: The total delay time for both the initial (H)DMA sync (to the DMA clock),
712
+	   and the end (H)DMA sync (back to the last CPU cycle's mcycle rate (6, 8, or 12)) always takes between 12-24 mcycles.
713
+	   Possible delays: { 12, 14, 16, 18, 20, 22, 24 }
714
+	   XXX: Snes9x can't emulate this timing :( so let's use the average value... */
715
+	Timings.DMACPUSync = 18;
716
+	/* If the CPU is halted (i.e. for DMA) while /NMI goes low, the NMI will trigger
717
+	   after the DMA completes (even if /NMI goes high again before the DMA
718
+	   completes). In this case, there is a 24-30 cycle delay between the end of DMA
719
+	   and the NMI handler, time enough for an instruction or two. */
720
+	// Wild Guns, Mighty Morphin Power Rangers - The Fighting Edition
721
+	Timings.NMIDMADelay = 24;
722
+	Timings.IRQPendCount = 0;
1907 723
 
1908
-	if (Multi.cartSizeB)
1909
-	{
1910
-		if (!is_SameGame_Add_On(ROM + Multi.cartOffsetB, Multi.cartSizeB))
1911
-			Multi.cartSizeB = 0;
1912
-		else
1913
-			strcpy(Multi.fileNameB, cartB);
1914
-	}
724
+	//// Hack games
1915 725
 
1916
-	strcpy(ROMFilename, Multi.fileNameA);
726
+	this->ApplyROMFixes();
1917 727
 
1918
-	LoROM = false;
1919
-	HiROM = true;
1920
-	CalculatedSize = Multi.cartSizeA;
728
+	sprintf(this->ROMName, "%s", Safe(this->ROMName));
729
+	sprintf(this->ROMId, "%s", Safe(this->ROMId));
1921 730
 
1922
-	return true;
731
+	Settings.ForceNotInterleaved = false;
1923 732
 }
1924 733
 
1925
-bool CMemory::LoadSRTC()
1926
-{
1927
-	FILE	*fp;
1928
-	size_t	ignore;
734
+// memory map
1929 735
 
1930
-	fp = fopen(S9xGetFilename(".rtc", SRAM_DIR), "rb");
1931
-	if (!fp)
1932
-		return false;
736
+uint32_t CMemory::map_mirror(uint32_t size, uint32_t pos)
737
+{
738
+	// from bsnes
739
+	if (!size)
740
+		return 0;
741
+	if (pos < size)
742
+		return pos;
1933 743
 
1934
-	ignore = fread(RTCData.reg, 1, 20, fp);
1935
-	fclose(fp);
744
+	uint32_t mask = 1 << 31;
745
+	while (!(pos & mask))
746
+		mask >>= 1;
1936 747
 
1937
-	return true;
748
+	if (size <= (pos & mask))
749
+		return this->map_mirror(size, pos - mask);
750
+	else
751
+		return mask + this->map_mirror(size - mask, pos - mask);
1938 752
 }
1939 753
 
1940
-bool CMemory::SaveSRTC()
754
+void CMemory::map_lorom(uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, uint32_t size)
1941 755
 {
1942
-	FILE	*fp;
1943
-	size_t	ignore;
1944
-
1945
-	fp = fopen(S9xGetFilename(".rtc", SRAM_DIR), "wb");
1946
-	if (!fp)
1947
-		return false;
1948
-
1949
-	ignore = fwrite(RTCData.reg, 1, 20, fp);
1950
-	fclose(fp);
1951
-
1952
-	return true;
756
+	for (uint32_t c = bank_s; c <= bank_e; ++c)
757
+		for (uint32_t i = addr_s; i <= addr_e; i += 0x1000)
758
+		{
759
+			uint32_t p = (c << 4) | (i >> 12);
760
+			uint32_t addr = (c & 0x7f) * 0x8000;
761
+			this->Map[p] = &this->ROM[this->map_mirror(size, addr) - (i & 0x8000)];
762
+			this->BlockIsROM[p] = true;
763
+			this->BlockIsRAM[p] = false;
764
+		}
1953 765
 }
1954 766
 
1955
-void CMemory::ClearSRAM (bool onlyNonSavedSRAM)
767
+void CMemory::map_hirom(uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, uint32_t size)
1956 768
 {
1957
-	if (onlyNonSavedSRAM)
1958
-		if (!(Settings.SuperFX && ROMType < 0x15) && !(Settings.SA1 && ROMType == 0x34)) // can have SRAM
1959
-			return;
1960
-
1961
-	memset(SRAM, SNESGameFixes.SRAMInitialValue, 0x20000);
769
+	for (uint32_t c = bank_s; c <= bank_e; ++c)
770
+		for (uint32_t i = addr_s; i <= addr_e; i += 0x1000)
771
+		{
772
+			uint32_t p = (c << 4) | (i >> 12);
773
+			uint32_t addr = c << 16;
774
+			this->Map[p] = &this->ROM[this->map_mirror(size, addr)];
775
+			this->BlockIsROM[p] = true;
776
+			this->BlockIsRAM[p] = false;
777
+		}
1962 778
 }
1963 779
 
1964
-bool CMemory::LoadSRAM (const char *filename)
780
+void CMemory::map_lorom_offset(uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, uint32_t size, uint32_t offset)
1965 781
 {
1966
-	FILE	*file;
1967
-	int		size, len;
1968
-	char	sramName[PATH_MAX + 1];
1969
-
1970
-	strcpy(sramName, filename);
782
+	for (uint32_t c = bank_s; c <= bank_e; ++c)
783
+		for (uint32_t i = addr_s; i <= addr_e; i += 0x1000)
784
+		{
785
+			uint32_t p = (c << 4) | (i >> 12);
786
+			uint32_t addr = ((c - bank_s) & 0x7f) * 0x8000;
787
+			this->Map[p] = &this->ROM[offset + this->map_mirror(size, addr) - (i & 0x8000)];
788
+			this->BlockIsROM[p] = true;
789
+			this->BlockIsRAM[p] = false;
790
+		}
791
+}
1971 792
 
1972
-	ClearSRAM();
1973
-
1974
-	if (Multi.cartType && Multi.sramSizeB)
1975
-	{
1976
-		char	temp[PATH_MAX + 1];
1977
-
1978
-		strcpy(temp, ROMFilename);
1979
-		strcpy(ROMFilename, Multi.fileNameB);
1980
-
1981
-		size = (1 << (Multi.sramSizeB + 3)) * 128;
1982
-
1983
-		file = fopen(S9xGetFilename(".srm", SRAM_DIR), "rb");
1984
-		if (file)
1985
-		{
1986
-			len = fread((char *) Multi.sramB, 1, 0x10000, file);
1987
-			fclose(file);
1988
-			if (len - size == 512)
1989
-				memmove(Multi.sramB, Multi.sramB + 512, size);
1990
-		}
1991
-
1992
-		strcpy(ROMFilename, temp);
1993
-	}
1994
-
1995
-	size = SRAMSize ? (1 << (SRAMSize + 3)) * 128 : 0;
1996
-	if (size > 0x20000)
1997
-		size = 0x20000;
1998
-
1999
-	if (size)
2000
-	{
2001
-		file = fopen(sramName, "rb");
2002
-		if (file)
2003
-		{
2004
-			len = fread((char *) SRAM, 1, 0x20000, file);
2005
-			fclose(file);
2006
-			if (len - size == 512)
2007
-				memmove(SRAM, SRAM + 512, size);
2008
-
2009
-			if (Settings.SRTC || Settings.SPC7110RTC)
2010
-				LoadSRTC();
2011
-
2012
-			return true;
2013
-		}
2014
-		else
2015
-		if (Settings.BS && !Settings.BSXItself)
2016
-		{
2017
-			// The BS game's SRAM was not found
2018
-			// Try to read BS-X.srm instead
2019
-			char	path[PATH_MAX + 1];
2020
-
2021
-			strcpy(path, S9xGetDirectory(SRAM_DIR));
2022
-			strcat(path, SLASH_STR);
2023
-			strcat(path, "BS-X.srm");
2024
-
2025
-			file = fopen(path, "rb");
2026
-			if (file)
2027
-			{
2028
-				len = fread((char *) SRAM, 1, 0x20000, file);
2029
-				fclose(file);
2030
-				if (len - size == 512)
2031
-					memmove(SRAM, SRAM + 512, size);
2032
-
2033
-				S9xMessage(S9X_INFO, S9X_ROM_INFO, "The SRAM file wasn't found: BS-X.srm was read instead.");
2034
-				return true;
2035
-			}
2036
-			else
2037
-			{
2038
-				S9xMessage(S9X_INFO, S9X_ROM_INFO, "The SRAM file wasn't found, BS-X.srm wasn't found either.");
2039
-				return false;
2040
-			}
2041
-		}
2042
-
2043
-		return false;
2044
-	}
2045
-
2046
-	return true;
2047
-}
2048
-
2049
-bool CMemory::SaveSRAM (const char *filename)
2050
-{
2051
-	if (Settings.SuperFX && ROMType < 0x15) // doesn't have SRAM
2052
-		return true;
2053
-
2054
-	if (Settings.SA1 && ROMType == 0x34)    // doesn't have SRAM
2055
-		return true;
2056
-
2057
-	FILE	*file;
2058
-	int		size;
2059
-	char	sramName[PATH_MAX + 1];
2060
-
2061
-	strcpy(sramName, filename);
2062
-
2063
-	if (Multi.cartType && Multi.sramSizeB)
2064
-	{
2065
-		char	name[PATH_MAX + 1], temp[PATH_MAX + 1];
2066
-
2067
-		strcpy(temp, ROMFilename);
2068
-		strcpy(ROMFilename, Multi.fileNameB);
2069
-		strcpy(name, S9xGetFilename(".srm", SRAM_DIR));
2070
-
2071
-		size = (1 << (Multi.sramSizeB + 3)) * 128;
2072
-
2073
-		file = fopen(name, "wb");
2074
-		if (file)
2075
-		{
2076
-			size_t	ignore;
2077
-			ignore = fwrite((char *) Multi.sramB, size, 1, file);
2078
-			fclose(file);
2079
-		#ifdef __linux
2080
-			ignore = chown(name, getuid(), getgid());
2081
-		#endif
2082
-		}
2083
-
2084
-		strcpy(ROMFilename, temp);
2085
-    }
2086
-
2087
-    size = SRAMSize ? (1 << (SRAMSize + 3)) * 128 : 0;
2088
-	if (size > 0x20000)
2089
-		size = 0x20000;
2090
-
2091
-	if (size)
2092
-	{
2093
-		file = fopen(sramName, "wb");
2094
-		if (file)
2095
-		{
2096
-			size_t	ignore;
2097
-			ignore = fwrite((char *) SRAM, size, 1, file);
2098
-			fclose(file);
2099
-		#ifdef __linux
2100
-			ignore = chown(sramName, getuid(), getgid());
2101
-		#endif
2102
-
2103
-			if (Settings.SRTC || Settings.SPC7110RTC)
2104
-				SaveSRTC();
2105
-
2106
-			return true;
2107
-		}
2108
-	}
2109
-
2110
-	return false;
2111
-}*/
2112
-
2113
-// initialization
2114
-
2115
-static uint32_t caCRC32 (uint8_t *array, uint32_t size, uint32_t crc32 = 0xffffffff)
2116
-{
2117
-	for (uint32_t i = 0; i < size; i++)
2118
-		crc32 = ((crc32 >> 8) & 0x00FFFFFF) ^ crc32Table[(crc32 ^ array[i]) & 0xFF];
2119
-
2120
-	return ~crc32;
2121
-}
2122
-
2123
-char * CMemory::Safe (const char *s)
2124
-{
2125
-	static char	*safe = NULL;
2126
-	static int	safe_len = 0;
2127
-
2128
-	if (s == NULL)
2129
-	{
2130
-		if (safe)
2131
-		{
2132
-			free(safe);
2133
-			safe = NULL;
2134
-		}
2135
-
2136
-		return NULL;
2137
-	}
2138
-
2139
-	int	len = strlen(s);
2140
-	if (!safe || len + 1 > safe_len)
2141
-	{
2142
-		if (safe)
2143
-			free(safe);
2144
-
2145
-		safe_len = len + 1;
2146
-		safe = (char *) malloc(safe_len);
2147
-	}
2148
-
2149
-	for (int i = 0; i < len; i++)
2150
-	{
2151
-		if (s[i] >= 32 && s[i] < 127)
2152
-			safe[i] = s[i];
2153
-		else
2154
-			safe[i] = '_';
2155
-	}
2156
-
2157
-	safe[len] = 0;
2158
-
2159
-	return safe;
2160
-}
2161
-
2162
-char * CMemory::SafeANK (const char *s)
2163
-{
2164
-	static char	*safe = NULL;
2165
-	static int	safe_len = 0;
2166
-
2167
-	if (s == NULL)
2168
-	{
2169
-		if (safe)
2170
-		{
2171
-			free(safe);
2172
-			safe = NULL;
2173
-		}
2174
-
2175
-		return NULL;
2176
-	}
2177
-
2178
-	int	len = strlen(s);
2179
-	if (!safe || len + 1 > safe_len)
2180
-	{
2181
-		if (safe)
2182
-			free(safe);
2183
-
2184
-		safe_len = len + 1;
2185
-		safe = (char *) malloc(safe_len);
2186
-	}
2187
-
2188
-	for (int i = 0; i < len; i++)
2189
-	{
2190
-		if (s[i] >= 32 && s[i] < 127) // ASCII
2191
-			safe [i] = s[i];
2192
-		else
2193
-		if (ROMRegion == 0 && ((uint8_t) s[i] >= 0xa0 && (uint8_t) s[i] < 0xe0)) // JIS X 201 - Katakana
2194
-			safe [i] = s[i];
2195
-		else
2196
-			safe [i] = '_';
2197
-	}
2198
-
2199
-	safe [len] = 0;
2200
-
2201
-	return safe;
2202
-}
2203
-
2204
-void CMemory::ParseSNESHeader (uint8_t *RomHeader)
2205
-{
2206
-	bool	bs = Settings.BS & !Settings.BSXItself;
2207
-
2208
-	strncpy(ROMName, (char *) &RomHeader[0x10], ROM_NAME_LEN - 1);
2209
-	if (bs)
2210
-		memset(ROMName + 16, 0x20, ROM_NAME_LEN - 17);
2211
-
2212
-	if (bs)
2213
-	{
2214
-		if (!(((RomHeader[0x29] & 0x20) && CalculatedSize <  0x100000) ||
2215
-			 (!(RomHeader[0x29] & 0x20) && CalculatedSize == 0x100000)))
2216
-			printf("BS: Size mismatch\n");
2217
-
2218
-		// FIXME
2219
-		int	p = 0;
2220
-		while ((1 << p) < (int) CalculatedSize)
2221
-			p++;
2222
-		ROMSize = p - 10;
2223
-	}
2224
-	else
2225
-		ROMSize = RomHeader[0x27];
2226
-
2227
-	SRAMSize  = bs ? 5 /* BS-X */    : RomHeader[0x28];
2228
-	ROMSpeed  = bs ? RomHeader[0x28] : RomHeader[0x25];
2229
-	ROMType   = bs ? 0xE5 /* BS-X */ : RomHeader[0x26];
2230
-	ROMRegion = bs ? 0               : RomHeader[0x29];
2231
-
2232
-	ROMChecksum           = RomHeader[0x2E] + (RomHeader[0x2F] << 8);
2233
-	ROMComplementChecksum = RomHeader[0x2C] + (RomHeader[0x2D] << 8);
2234
-
2235
-	memmove(ROMId, &RomHeader[0x02], 4);
2236
-
2237
-	if (RomHeader[0x2A] != 0x33)
2238
-		CompanyId = ((RomHeader[0x2A] >> 4) & 0x0F) * 36 + (RomHeader[0x2A] & 0x0F);
2239
-	else
2240
-	if (isalnum(RomHeader[0x00]) && isalnum(RomHeader[0x01]))
2241
-	{
2242
-		int	l, r, l2, r2;
2243
-		l = toupper(RomHeader[0x00]);
2244
-		r = toupper(RomHeader[0x01]);
2245
-		l2 = (l > '9') ? l - '7' : l - '0';
2246
-		r2 = (r > '9') ? r - '7' : r - '0';
2247
-		CompanyId = l2 * 36 + r2;
2248
-	}
2249
-}
2250
-
2251
-void CMemory::InitROM()
2252
-{
2253
-	Settings.SuperFX = false;
2254
-	Settings.DSP = 0;
2255
-	Settings.SA1 = false;
2256
-	Settings.C4 = false;
2257
-	Settings.SDD1 = false;
2258
-	Settings.SPC7110 = false;
2259
-	Settings.SPC7110RTC = false;
2260
-	Settings.OBC1 = false;
2261
-	Settings.SETA = 0;
2262
-	Settings.SRTC = false;
2263
-	Settings.BS = false;
2264
-
2265
-	//SuperFX.nRomBanks = CalculatedSize >> 15;
2266
-
2267
-	//// Parse ROM header and read ROM informatoin
2268
-
2269
-	CompanyId = -1;
2270
-	memset(ROMId, 0, 5);
2271
-
2272
-	uint8_t	*RomHeader = ROM + 0x7FB0;
2273
-	if (ExtendedFormat == BIGFIRST)
2274
-		RomHeader += 0x400000;
2275
-	if (HiROM)
2276
-		RomHeader += 0x8000;
2277
-
2278
-	//S9xInitBSX(); // Set BS header before parsing
2279
-
2280
-	ParseSNESHeader(RomHeader);
2281
-
2282
-	//// Detect and initialize chips
2283
-	//// detection codes are compatible with NSRT
2284
-
2285
-	// DSP1/2/3/4
2286
-	if (ROMType == 0x03)
2287
-	{
2288
-		if (ROMSpeed == 0x30)
2289
-			Settings.DSP = 4; // DSP4
2290
-		else
2291
-			Settings.DSP = 1; // DSP1
2292
-	}
2293
-	else
2294
-	if (ROMType == 0x05)
2295
-	{
2296
-		if (ROMSpeed == 0x20)
2297
-			Settings.DSP = 2; // DSP2
2298
-		else
2299
-		if (ROMSpeed == 0x30 && RomHeader[0x2a] == 0xb2)
2300
-			Settings.DSP = 3; // DSP3
2301
-		else
2302
-			Settings.DSP = 1; // DSP1
2303
-	}
2304
-
2305
-	/*switch (Settings.DSP)
2306
-	{
2307
-		case 1:	// DSP1
2308
-			if (HiROM)
2309
-			{
2310
-				DSP0.boundary = 0x7000;
2311
-				DSP0.maptype = M_DSP1_HIROM;
2312
-			}
2313
-			else
2314
-			if (CalculatedSize > 0x100000)
2315
-			{
2316
-				DSP0.boundary = 0x4000;
2317
-				DSP0.maptype = M_DSP1_LOROM_L;
2318
-			}
2319
-			else
2320
-			{
2321
-				DSP0.boundary = 0xc000;
2322
-				DSP0.maptype = M_DSP1_LOROM_S;
2323
-			}
2324
-
2325
-			SetDSP = &DSP1SetByte;
2326
-			GetDSP = &DSP1GetByte;
2327
-			break;
2328
-
2329
-		case 2: // DSP2
2330
-			DSP0.boundary = 0x10000;
2331
-			DSP0.maptype = M_DSP2_LOROM;
2332
-			SetDSP = &DSP2SetByte;
2333
-			GetDSP = &DSP2GetByte;
2334
-			break;
2335
-
2336
-		case 3: // DSP3
2337
-			DSP0.boundary = 0xc000;
2338
-			DSP0.maptype = M_DSP3_LOROM;
2339
-			SetDSP = &DSP3SetByte;
2340
-			GetDSP = &DSP3GetByte;
2341
-			break;
2342
-
2343
-		case 4: // DSP4
2344
-			DSP0.boundary = 0xc000;
2345
-			DSP0.maptype = M_DSP4_LOROM;
2346
-			SetDSP = &DSP4SetByte;
2347
-			GetDSP = &DSP4GetByte;
2348
-			break;
2349
-
2350
-		default:
2351
-			SetDSP = NULL;
2352
-			GetDSP = NULL;
2353
-			break;
2354
-	}*/
2355
-
2356
-	uint32_t	identifier = ((ROMType & 0xff) << 8) + (ROMSpeed & 0xff);
2357
-
2358
-	switch (identifier)
2359
-	{
2360
-	    // SRTC
2361
-		/*case 0x5535:
2362
-			Settings.SRTC = true;
2363
-			S9xInitSRTC();
2364
-			break;
2365
-
2366
-		// SPC7110
2367
-		case 0xF93A:
2368
-			Settings.SPC7110RTC = true;
2369
-		case 0xF53A:
2370
-			Settings.SPC7110 = true;
2371
-			S9xInitSPC7110();
2372
-			break;
2373
-
2374
-		// OBC1
2375
-		case 0x2530:
2376
-			Settings.OBC1 = true;
2377
-			break;
2378
-
2379
-		// SA1
2380
-		case 0x3423:
2381
-		case 0x3523:
2382
-			Settings.SA1 = true;
2383
-			break;
2384
-
2385
-		// SuperFX
2386
-		case 0x1320:
2387
-		case 0x1420:
2388
-		case 0x1520:
2389
-		case 0x1A20:
2390
-			Settings.SuperFX = true;
2391
-			S9xInitSuperFX();
2392
-			if (ROM[0x7FDA] == 0x33)
2393
-				SRAMSize = ROM[0x7FBD];
2394
-			else
2395
-				SRAMSize = 5;
2396
-			break;*/
2397
-
2398
-		// SDD1
2399
-		case 0x4332:
2400
-		case 0x4532:
2401
-			Settings.SDD1 = true;
2402
-			break;
2403
-
2404
-		// ST018
2405
-		/*case 0xF530:
2406
-			Settings.SETA = ST_018;
2407
-			SetSETA = NULL;
2408
-			GetSETA = NULL;
2409
-			SRAMSize = 2;
2410
-			SNESGameFixes.SRAMInitialValue = 0x00;
2411
-			break;
2412
-
2413
-		// ST010/011
2414
-		case 0xF630:
2415
-			if (ROM[0x7FD7] == 0x09)
2416
-			{
2417
-				Settings.SETA = ST_011;
2418
-				SetSETA = &S9xSetST011;
2419
-				GetSETA = &S9xGetST011;
2420
-			}
2421
-			else
2422
-			{
2423
-				Settings.SETA = ST_010;
2424
-				SetSETA = &S9xSetST010;
2425
-				GetSETA = &S9xGetST010;
2426
-			}
2427
-
2428
-			SRAMSize = 2;
2429
-			SNESGameFixes.SRAMInitialValue = 0x00;
2430
-			break;
2431
-
2432
-		// C4
2433
-		case 0xF320:
2434
-			Settings.C4 = true;
2435
-			break;*/
2436
-	}
2437
-
2438
-	//// Map memory and calculate checksum
2439
-
2440
-	Map_Initialize();
2441
-	CalculatedChecksum = 0;
2442
-
2443
-	if (HiROM)
2444
-    {
2445
-		if (Settings.BS)
2446
-			/* Do nothing */;
2447
-		else
2448
-		/*if (Settings.SPC7110)
2449
-			Map_SPC7110HiROMMap();
2450
-		else*/
2451
-		if (ExtendedFormat != NOPE)
2452
-			Map_ExtendedHiROMMap();
2453
-		/*else
2454
-		if (Multi.cartType == 3)
2455
-			Map_SameGameHiROMMap();*/
2456
-		else
2457
-			Map_HiROMMap();
2458
-    }
2459
-    else
2460
-    {
2461
-		if (Settings.BS)
2462
-			/* Do nothing */;
2463
-		else
2464
-		/*if (Settings.SETA && Settings.SETA != ST_018)
2465
-			Map_SetaDSPLoROMMap();
2466
-		else
2467
-		if (Settings.SuperFX)
2468
-			Map_SuperFXLoROMMap();
2469
-		else
2470
-		if (Settings.SA1)
2471
-			Map_SA1LoROMMap();
2472
-		else*/
2473
-		if (Settings.SDD1)
2474
-			Map_SDD1LoROMMap();
2475
-		else
2476
-		if (ExtendedFormat != NOPE)
2477
-			Map_JumboLoROMMap();
2478
-		else
2479
-		if (strncmp(ROMName, "WANDERERS FROM YS", 17) == 0)
2480
-			Map_NoMAD1LoROMMap();
2481
-		else
2482
-		if (strncmp(ROMName, "SOUND NOVEL-TCOOL", 17) == 0 ||
2483
-			strncmp(ROMName, "DERBY STALLION 96", 17) == 0)
2484
-			Map_ROM24MBSLoROMMap();
2485
-		else
2486
-		if (strncmp(ROMName, "THOROUGHBRED BREEDER3", 21) == 0 ||
2487
-			strncmp(ROMName, "RPG-TCOOL 2", 11) == 0)
2488
-			Map_SRAM512KLoROMMap();
2489
-		/*else
2490
-		if (strncmp(ROMName, "ADD-ON BASE CASSETE", 19) == 0)
2491
-		{
2492
-			if (Multi.cartType == 4)
2493
-			{
2494
-				SRAMSize = Multi.sramSizeA;
2495
-				Map_SufamiTurboLoROMMap();
2496
-			}
2497
-			else
2498
-			{
2499
-				SRAMSize = 5;
2500
-				Map_SufamiTurboPseudoLoROMMap();
2501
-			}
2502
-		}*/
2503
-		else
2504
-			Map_LoROMMap();
2505
-    }
2506
-
2507
-	Checksum_Calculate();
2508
-
2509
-	/*bool isChecksumOK = (ROMChecksum + ROMComplementChecksum == 0xffff) &
2510
-						 (ROMChecksum == CalculatedChecksum);*/
2511
-
2512
-	//// Build more ROM information
2513
-
2514
-	// CRC32
2515
-	if (!Settings.BS || Settings.BSXItself) // Not BS Dump
2516
-		ROMCRC32 = caCRC32(ROM, CalculatedSize);
2517
-	else // Convert to correct format before scan
2518
-	{
2519
-		int offset = HiROM ? 0xffc0 : 0x7fc0;
2520
-		// Backup
2521
-		uint8_t BSMagic0 = ROM[offset + 22],
2522
-			  BSMagic1 = ROM[offset + 23];
2523
-		// uCONSRT standard
2524
-		ROM[offset + 22] = 0x42;
2525
-		ROM[offset + 23] = 0x00;
2526
-		// Calc
2527
-		ROMCRC32 = caCRC32(ROM, CalculatedSize);
2528
-		// Convert back
2529
-		ROM[offset + 22] = BSMagic0;
2530
-		ROM[offset + 23] = BSMagic1;
2531
-	}
2532
-
2533
-	// NTSC/PAL
2534
-	if (Settings.ForceNTSC)
2535
-		Settings.PAL = false;
2536
-	else
2537
-	if (Settings.ForcePAL)
2538
-		Settings.PAL = true;
2539
-	else
2540
-	if (!Settings.BS && (ROMRegion >= 2) && (ROMRegion <= 12))
2541
-		Settings.PAL = true;
2542
-	else
2543
-		Settings.PAL = false;
2544
-
2545
-	if (Settings.PAL)
2546
-	{
2547
-		Settings.FrameTime = Settings.FrameTimePAL;
2548
-		ROMFramesPerSecond = 50;
2549
-	}
2550
-	else
2551
-	{
2552
-		Settings.FrameTime = Settings.FrameTimeNTSC;
2553
-		ROMFramesPerSecond = 60;
2554
-	}
2555
-
2556
-	// truncate cart name
2557
-	ROMName[ROM_NAME_LEN - 1] = 0;
2558
-	if (strlen(ROMName))
2559
-	{
2560
-		char *p = ROMName + strlen(ROMName);
2561
-		if (p > ROMName + 21 && ROMName[20] == ' ')
2562
-			p = ROMName + 21;
2563
-		while (p > ROMName && *(p - 1) == ' ')
2564
-			p--;
2565
-		*p = 0;
2566
-	}
2567
-
2568
-	// SRAM size
2569
-	SRAMMask = SRAMSize ? ((1 << (SRAMSize + 3)) * 128) - 1 : 0;
2570
-
2571
-	// checksum
2572
-	/*if (!isChecksumOK || ((uint32_t) CalculatedSize > (uint32_t) (((1 << (ROMSize - 7)) * 128) * 1024)))
2573
-	{
2574
-		Settings.DisplayColor = BUILD_PIXEL(31, 31, 0);
2575
-		SET_UI_COLOR(255, 255, 0);
2576
-	}*/
2577
-
2578
-	/*if (Multi.cartType == 4)
2579
-	{
2580
-		Settings.DisplayColor = BUILD_PIXEL(0, 16, 31);
2581
-		SET_UI_COLOR(0, 128, 255);
2582
-	}*/
2583
-
2584
-	//// Initialize emulation
2585
-
2586
-	Timings.H_Max_Master = SNES_CYCLES_PER_SCANLINE;
2587
-	Timings.H_Max        = Timings.H_Max_Master;
2588
-	Timings.HBlankStart  = SNES_HBLANK_START_HC;
2589
-	Timings.HBlankEnd    = SNES_HBLANK_END_HC;
2590
-	Timings.HDMAInit     = SNES_HDMA_INIT_HC;
2591
-	Timings.HDMAStart    = SNES_HDMA_START_HC;
2592
-	Timings.RenderPos    = SNES_RENDER_START_HC;
2593
-	Timings.V_Max_Master = Settings.PAL ? SNES_MAX_PAL_VCOUNTER : SNES_MAX_NTSC_VCOUNTER;
2594
-	Timings.V_Max        = Timings.V_Max_Master;
2595
-	/* From byuu: The total delay time for both the initial (H)DMA sync (to the DMA clock),
2596
-	   and the end (H)DMA sync (back to the last CPU cycle's mcycle rate (6, 8, or 12)) always takes between 12-24 mcycles.
2597
-	   Possible delays: { 12, 14, 16, 18, 20, 22, 24 }
2598
-	   XXX: Snes9x can't emulate this timing :( so let's use the average value... */
2599
-	Timings.DMACPUSync   = 18;
2600
-	/* If the CPU is halted (i.e. for DMA) while /NMI goes low, the NMI will trigger
2601
-	   after the DMA completes (even if /NMI goes high again before the DMA
2602
-	   completes). In this case, there is a 24-30 cycle delay between the end of DMA
2603
-	   and the NMI handler, time enough for an instruction or two. */
2604
-	// Wild Guns, Mighty Morphin Power Rangers - The Fighting Edition
2605
-	Timings.NMIDMADelay  = 24;
2606
-	Timings.IRQPendCount = 0;
2607
-
2608
-	IPPU.TotalEmulatedFrames = 0;
2609
-
2610
-	//// Hack games
2611
-
2612
-	ApplyROMFixes();
2613
-
2614
-	//// Show ROM information
2615
-	//char displayName[ROM_NAME_LEN];
2616
-
2617
-	strcpy(RawROMName, ROMName);
2618
-	//sprintf(displayName, "%s", SafeANK(ROMName));
2619
-	sprintf(ROMName, "%s", Safe(ROMName));
2620
-	sprintf(ROMId, "%s", Safe(ROMId));
2621
-
2622
-	/*sprintf(String, "\"%s\" [%s] %s, %s, %s, %s, SRAM:%s, ID:%s, CRC32:%08X",
2623
-		displayName, isChecksumOK ? "checksum ok" : ((Multi.cartType == 4) ? "no checksum" : "bad checksum"),
2624
-		MapType(), Size(), KartContents(), Settings.PAL ? "PAL" : "NTSC", StaticRAMSize(), ROMId, ROMCRC32);*/
2625
-	//S9xMessage(S9X_INFO, S9X_ROM_INFO, String);
2626
-
2627
-	Settings.ForceLoROM = false;
2628
-	Settings.ForceHiROM = false;
2629
-	Settings.ForceHeader = false;
2630
-	Settings.ForceNoHeader = false;
2631
-	Settings.ForceInterleaved = false;
2632
-	Settings.ForceInterleaved2 = false;
2633
-	Settings.ForceInterleaveGD24 = false;
2634
-	Settings.ForceNotInterleaved = false;
2635
-	Settings.ForcePAL = false;
2636
-	Settings.ForceNTSC = false;
2637
-
2638
-	Settings.TakeScreenshot = false;
2639
-
2640
-	/*if (stopMovie)
2641
-		S9xMovieStop(true);*/
2642
-
2643
-	if (PostRomInitFunc)
2644
-		PostRomInitFunc();
2645
-
2646
-    //S9xVerifyControllers();
2647
-}
2648
-
2649
-// memory map
2650
-
2651
-uint32_t CMemory::map_mirror (uint32_t size, uint32_t pos)
2652
-{
2653
-	// from bsnes
2654
-	if (size == 0)
2655
-		return 0;
2656
-	if (pos < size)
2657
-		return pos;
2658
-
2659
-	uint32_t	mask = 1 << 31;
2660
-	while (!(pos & mask))
2661
-		mask >>= 1;
2662
-
2663
-	if (size <= (pos & mask))
2664
-		return map_mirror(size, pos - mask);
2665
-	else
2666
-		return mask + map_mirror(size - mask, pos - mask);
2667
-}
2668
-
2669
-void CMemory::map_lorom (uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, uint32_t size)
2670
-{
2671
-	uint32_t	c, i, p, addr;
2672
-
2673
-	for (c = bank_s; c <= bank_e; c++)
2674
-	{
2675
-		for (i = addr_s; i <= addr_e; i += 0x1000)
2676
-		{
2677
-			p = (c << 4) | (i >> 12);
2678
-			addr = (c & 0x7f) * 0x8000;
2679
-			Map[p] = ROM + map_mirror(size, addr) - (i & 0x8000);
2680
-			BlockIsROM[p] = true;
2681
-			BlockIsRAM[p] = false;
2682
-		}
2683
-	}
2684
-}
2685
-
2686
-void CMemory::map_hirom (uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, uint32_t size)
2687
-{
2688
-	uint32_t	c, i, p, addr;
2689
-
2690
-	for (c = bank_s; c <= bank_e; c++)
2691
-	{
2692
-		for (i = addr_s; i <= addr_e; i += 0x1000)
2693
-		{
2694
-			p = (c << 4) | (i >> 12);
2695
-			addr = c << 16;
2696
-			Map[p] = ROM + map_mirror(size, addr);
2697
-			BlockIsROM[p] = true;
2698
-			BlockIsRAM[p] = false;
2699
-		}
2700
-	}
2701
-}
2702
-
2703
-void CMemory::map_lorom_offset (uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, uint32_t size, uint32_t offset)
2704
-{
2705
-	uint32_t	c, i, p, addr;
2706
-
2707
-	for (c = bank_s; c <= bank_e; c++)
2708
-	{
2709
-		for (i = addr_s; i <= addr_e; i += 0x1000)
2710
-		{
2711
-			p = (c << 4) | (i >> 12);
2712
-			addr = ((c - bank_s) & 0x7f) * 0x8000;
2713
-			Map[p] = ROM + offset + map_mirror(size, addr) - (i & 0x8000);
2714
-			BlockIsROM[p] = true;
2715
-			BlockIsRAM[p] = false;
2716
-		}
2717
-	}
2718
-}
2719
-
2720
-void CMemory::map_hirom_offset (uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, uint32_t size, uint32_t offset)
2721
-{
2722
-	uint32_t	c, i, p, addr;
2723
-
2724
-	for (c = bank_s; c <= bank_e; c++)
2725
-	{
2726
-		for (i = addr_s; i <= addr_e; i += 0x1000)
2727
-		{
2728
-			p = (c << 4) | (i >> 12);
2729
-			addr = (c - bank_s) << 16;
2730
-			Map[p] = ROM + offset + map_mirror(size, addr);
2731
-			BlockIsROM[p] = true;
2732
-			BlockIsRAM[p] = false;
2733
-		}
2734
-	}
2735
-}
2736
-
2737
-void CMemory::map_space (uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, uint8_t *data)
2738
-{
2739
-	uint32_t	c, i, p;
2740
-
2741
-	for (c = bank_s; c <= bank_e; c++)
2742
-	{
2743
-		for (i = addr_s; i <= addr_e; i += 0x1000)
2744
-		{
2745
-			p = (c << 4) | (i >> 12);
2746
-			Map[p] = data;
2747
-			BlockIsROM[p] = false;
2748
-			BlockIsRAM[p] = true;
2749
-		}
2750
-	}
2751
-}
2752
-
2753
-void CMemory::map_index (uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, int index, int type)
2754
-{
2755
-	uint32_t	c, i, p;
2756
-	bool	isROM, isRAM;
2757
-
2758
-	isROM = ((type == MAP_TYPE_I_O) || (type == MAP_TYPE_RAM)) ? false : true;
2759
-	isRAM = ((type == MAP_TYPE_I_O) || (type == MAP_TYPE_ROM)) ? false : true;
2760
-
2761
-	for (c = bank_s; c <= bank_e; c++)
2762
-	{
2763
-		for (i = addr_s; i <= addr_e; i += 0x1000)
2764
-		{
2765
-			p = (c << 4) | (i >> 12);
2766
-			Map[p] = (uint8_t *) index;
2767
-			BlockIsROM[p] = isROM;
2768
-			BlockIsRAM[p] = isRAM;
2769
-		}
2770
-	}
2771
-}
2772
-
2773
-void CMemory::map_System()
2774
-{
2775
-	// will be overwritten
2776
-	map_space(0x00, 0x3f, 0x0000, 0x1fff, RAM);
2777
-	map_index(0x00, 0x3f, 0x2000, 0x3fff, MAP_PPU, MAP_TYPE_I_O);
2778
-	map_index(0x00, 0x3f, 0x4000, 0x5fff, MAP_CPU, MAP_TYPE_I_O);
2779
-	map_space(0x80, 0xbf, 0x0000, 0x1fff, RAM);
2780
-	map_index(0x80, 0xbf, 0x2000, 0x3fff, MAP_PPU, MAP_TYPE_I_O);
2781
-	map_index(0x80, 0xbf, 0x4000, 0x5fff, MAP_CPU, MAP_TYPE_I_O);
2782
-}
2783
-
2784
-void CMemory::map_WRAM()
2785
-{
2786
-	// will overwrite others
2787
-	map_space(0x7e, 0x7e, 0x0000, 0xffff, RAM);
2788
-	map_space(0x7f, 0x7f, 0x0000, 0xffff, RAM + 0x10000);
2789
-}
2790
-
2791
-void CMemory::map_LoROMSRAM()
2792
-{
2793
-	map_index(0x70, 0x7f, 0x0000, 0x7fff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
2794
-	map_index(0xf0, 0xff, 0x0000, 0x7fff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
2795
-}
2796
-
2797
-void CMemory::map_HiROMSRAM()
2798
-{
2799
-	map_index(0x20, 0x3f, 0x6000, 0x7fff, MAP_HIROM_SRAM, MAP_TYPE_RAM);
2800
-	map_index(0xa0, 0xbf, 0x6000, 0x7fff, MAP_HIROM_SRAM, MAP_TYPE_RAM);
2801
-}
2802
-
2803
-/*void CMemory::map_DSP()
2804
-{
2805
-	switch (DSP0.maptype)
2806
-	{
2807
-		case M_DSP1_LOROM_S:
2808
-			map_index(0x20, 0x3f, 0x8000, 0xffff, MAP_DSP, MAP_TYPE_I_O);
2809
-			map_index(0xa0, 0xbf, 0x8000, 0xffff, MAP_DSP, MAP_TYPE_I_O);
2810
-			break;
2811
-
2812
-		case M_DSP1_LOROM_L:
2813
-			map_index(0x60, 0x6f, 0x0000, 0x7fff, MAP_DSP, MAP_TYPE_I_O);
2814
-			map_index(0xe0, 0xef, 0x0000, 0x7fff, MAP_DSP, MAP_TYPE_I_O);
2815
-			break;
2816
-
2817
-		case M_DSP1_HIROM:
2818
-			map_index(0x00, 0x1f, 0x6000, 0x7fff, MAP_DSP, MAP_TYPE_I_O);
2819
-			map_index(0x80, 0x9f, 0x6000, 0x7fff, MAP_DSP, MAP_TYPE_I_O);
2820
-			break;
2821
-
2822
-		case M_DSP2_LOROM:
2823
-			map_index(0x20, 0x3f, 0x6000, 0x6fff, MAP_DSP, MAP_TYPE_I_O);
2824
-			map_index(0x20, 0x3f, 0x8000, 0xbfff, MAP_DSP, MAP_TYPE_I_O);
2825
-			map_index(0xa0, 0xbf, 0x6000, 0x6fff, MAP_DSP, MAP_TYPE_I_O);
2826
-			map_index(0xa0, 0xbf, 0x8000, 0xbfff, MAP_DSP, MAP_TYPE_I_O);
2827
-			break;
2828
-
2829
-		case M_DSP3_LOROM:
2830
-			map_index(0x20, 0x3f, 0x8000, 0xffff, MAP_DSP, MAP_TYPE_I_O);
2831
-			map_index(0xa0, 0xbf, 0x8000, 0xffff, MAP_DSP, MAP_TYPE_I_O);
2832
-			break;
2833
-
2834
-		case M_DSP4_LOROM:
2835
-			map_index(0x30, 0x3f, 0x8000, 0xffff, MAP_DSP, MAP_TYPE_I_O);
2836
-			map_index(0xb0, 0xbf, 0x8000, 0xffff, MAP_DSP, MAP_TYPE_I_O);
2837
-			break;
2838
-	}
2839
-}*/
2840
-
2841
-/*void CMemory::map_C4()
2842
-{
2843
-	map_index(0x00, 0x3f, 0x6000, 0x7fff, MAP_C4, MAP_TYPE_I_O);
2844
-	map_index(0x80, 0xbf, 0x6000, 0x7fff, MAP_C4, MAP_TYPE_I_O);
2845
-}*/
2846
-
2847
-/*void CMemory::map_OBC1()
2848
-{
2849
-	map_index(0x00, 0x3f, 0x6000, 0x7fff, MAP_OBC_RAM, MAP_TYPE_I_O);
2850
-	map_index(0x80, 0xbf, 0x6000, 0x7fff, MAP_OBC_RAM, MAP_TYPE_I_O);
2851
-}*/
2852
-
2853
-/*void CMemory::map_SetaRISC()
2854
-{
2855
-	map_index(0x00, 0x3f, 0x3000, 0x3fff, MAP_SETA_RISC, MAP_TYPE_I_O);
2856
-	map_index(0x80, 0xbf, 0x3000, 0x3fff, MAP_SETA_RISC, MAP_TYPE_I_O);
2857
-}*/
2858
-
2859
-/*void CMemory::map_SetaDSP()
2860
-{
2861
-	// where does the SETA chip access, anyway?
2862
-	// please confirm this?
2863
-	map_index(0x68, 0x6f, 0x0000, 0x7fff, MAP_SETA_DSP, MAP_TYPE_RAM);
2864
-	// and this!
2865
-	map_index(0x60, 0x67, 0x0000, 0x3fff, MAP_SETA_DSP, MAP_TYPE_I_O);
2866
-
2867
-	// ST-0010:
2868
-	// map_index(0x68, 0x6f, 0x0000, 0x0fff, MAP_SETA_DSP, ?);
2869
-}*/
2870
-
2871
-void CMemory::map_WriteProtectROM()
2872
-{
2873
-	memmove((void *) WriteMap, (void *) Map, sizeof(Map));
2874
-
2875
-	for (int c = 0; c < 0x1000; c++)
2876
-	{
2877
-		if (BlockIsROM[c])
2878
-			WriteMap[c] = (uint8_t *) MAP_NONE;
2879
-	}
2880
-}
2881
-
2882
-void CMemory::Map_Initialize()
2883
-{
2884
-	for (int c = 0; c < 0x1000; c++)
2885
-	{
2886
-		Map[c]      = (uint8_t *) MAP_NONE;
2887
-		WriteMap[c] = (uint8_t *) MAP_NONE;
2888
-		BlockIsROM[c] = false;
2889
-		BlockIsRAM[c] = false;
2890
-	}
2891
-}
2892
-
2893
-void CMemory::Map_LoROMMap()
2894
-{
2895
-	printf("Map_LoROMMap\n");
2896
-	map_System();
2897
-
2898
-	map_lorom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize);
2899
-	map_lorom(0x40, 0x7f, 0x0000, 0xffff, CalculatedSize);
2900
-	map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize);
2901
-	map_lorom(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize);
2902
-
2903
-	/*if (Settings.DSP)
2904
-		map_DSP();
2905
-	else
2906
-	if (Settings.C4)
2907
-		map_C4();
2908
-	else
2909
-	if (Settings.OBC1)
2910
-		map_OBC1();
2911
-	else
2912
-	if (Settings.SETA == ST_018)
2913
-		map_SetaRISC();*/
2914
-
2915
-    map_LoROMSRAM();
2916
-	map_WRAM();
2917
-
2918
-	map_WriteProtectROM();
2919
-}
2920
-
2921
-void CMemory::Map_NoMAD1LoROMMap()
2922
-{
2923
-	printf("Map_NoMAD1LoROMMap\n");
2924
-	map_System();
2925
-
2926
-	map_lorom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize);
2927
-	map_lorom(0x40, 0x7f, 0x0000, 0xffff, CalculatedSize);
2928
-	map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize);
2929
-	map_lorom(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize);
2930
-
2931
-	map_index(0x70, 0x7f, 0x0000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
2932
-	map_index(0xf0, 0xff, 0x0000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
2933
-
2934
-	map_WRAM();
2935
-
2936
-	map_WriteProtectROM();
2937
-}
2938
-
2939
-void CMemory::Map_JumboLoROMMap()
2940
-{
2941
-	// XXX: Which game uses this?
2942
-	printf("Map_JumboLoROMMap\n");
2943
-	map_System();
2944
-
2945
-	map_lorom_offset(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize - 0x400000, 0x400000);
2946
-	map_lorom_offset(0x40, 0x7f, 0x0000, 0xffff, CalculatedSize - 0x400000, 0x400000);
2947
-	map_lorom_offset(0x80, 0xbf, 0x8000, 0xffff, 0x400000, 0);
2948
-	map_lorom_offset(0xc0, 0xff, 0x0000, 0xffff, 0x400000, 0x200000);
2949
-
2950
-	map_LoROMSRAM();
2951
-	map_WRAM();
2952
-
2953
-	map_WriteProtectROM();
2954
-}
2955
-
2956
-void CMemory::Map_ROM24MBSLoROMMap()
2957
-{
2958
-	// PCB: BSC-1A5M-01, BSC-1A7M-10
2959
-	printf("Map_ROM24MBSLoROMMap\n");
2960
-	map_System();
2961
-
2962
-	map_lorom_offset(0x00, 0x1f, 0x8000, 0xffff, 0x100000, 0);
2963
-	map_lorom_offset(0x20, 0x3f, 0x8000, 0xffff, 0x100000, 0x100000);
2964
-	map_lorom_offset(0x80, 0x9f, 0x8000, 0xffff, 0x100000, 0x200000);
2965
-	map_lorom_offset(0xa0, 0xbf, 0x8000, 0xffff, 0x100000, 0x100000);
2966
-
2967
-	map_LoROMSRAM();
2968
-	map_WRAM();
2969
-
2970
-	map_WriteProtectROM();
2971
-}
2972
-
2973
-void CMemory::Map_SRAM512KLoROMMap()
2974
-{
2975
-	printf("Map_SRAM512KLoROMMap\n");
2976
-	map_System();
2977
-
2978
-	map_lorom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize);
2979
-	map_lorom(0x40, 0x7f, 0x0000, 0xffff, CalculatedSize);
2980
-	map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize);
2981
-	map_lorom(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize);
2982
-
2983
-	map_space(0x70, 0x70, 0x0000, 0xffff, SRAM);
2984
-	map_space(0x71, 0x71, 0x0000, 0xffff, SRAM + 0x8000);
2985
-	map_space(0x72, 0x72, 0x0000, 0xffff, SRAM + 0x10000);
2986
-	map_space(0x73, 0x73, 0x0000, 0xffff, SRAM + 0x18000);
2987
-
2988
-	map_WRAM();
2989
-
2990
-	map_WriteProtectROM();
2991
-}
2992
-
2993
-/*void CMemory::Map_SufamiTurboLoROMMap()
2994
-{
2995
-	printf("Map_SufamiTurboLoROMMap\n");
2996
-	map_System();
2997
-
2998
-	map_lorom_offset(0x00, 0x1f, 0x8000, 0xffff, 0x40000, 0);
2999
-	map_lorom_offset(0x20, 0x3f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
3000
-	map_lorom_offset(0x40, 0x5f, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
3001
-	map_lorom_offset(0x80, 0x9f, 0x8000, 0xffff, 0x40000, 0);
3002
-	map_lorom_offset(0xa0, 0xbf, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
3003
-	map_lorom_offset(0xc0, 0xdf, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
3004
-
3005
-	if (Multi.sramSizeA)
3006
-	{
3007
-		map_index(0x60, 0x63, 0x8000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
3008
-		map_index(0xe0, 0xe3, 0x8000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
3009
-	}
3010
-
3011
-	if (Multi.sramSizeB)
3012
-	{
3013
-		map_index(0x70, 0x73, 0x8000, 0xffff, MAP_LOROM_SRAM_B, MAP_TYPE_RAM);
3014
-		map_index(0xf0, 0xf3, 0x8000, 0xffff, MAP_LOROM_SRAM_B, MAP_TYPE_RAM);
3015
-	}
3016
-
3017
-	map_WRAM();
3018
-
3019
-	map_WriteProtectROM();
3020
-}*/
3021
-
3022
-/*void CMemory::Map_SufamiTurboPseudoLoROMMap()
3023
-{
3024
-	// for combined images
3025
-	printf("Map_SufamiTurboPseudoLoROMMap\n");
3026
-	map_System();
3027
-
3028
-	map_lorom_offset(0x00, 0x1f, 0x8000, 0xffff, 0x40000, 0);
3029
-	map_lorom_offset(0x20, 0x3f, 0x8000, 0xffff, 0x100000, 0x100000);
3030
-	map_lorom_offset(0x40, 0x5f, 0x8000, 0xffff, 0x100000, 0x200000);
3031
-	map_lorom_offset(0x80, 0x9f, 0x8000, 0xffff, 0x40000, 0);
3032
-	map_lorom_offset(0xa0, 0xbf, 0x8000, 0xffff, 0x100000, 0x100000);
3033
-	map_lorom_offset(0xc0, 0xdf, 0x8000, 0xffff, 0x100000, 0x200000);
3034
-
3035
-	// I don't care :P
3036
-	map_space(0x60, 0x63, 0x8000, 0xffff, SRAM - 0x8000);
3037
-	map_space(0xe0, 0xe3, 0x8000, 0xffff, SRAM - 0x8000);
3038
-	map_space(0x70, 0x73, 0x8000, 0xffff, SRAM + 0x4000 - 0x8000);
3039
-	map_space(0xf0, 0xf3, 0x8000, 0xffff, SRAM + 0x4000 - 0x8000);
3040
-
3041
-	map_WRAM();
3042
-
3043
-	map_WriteProtectROM();
3044
-}*/
3045
-
3046
-/*void CMemory::Map_SuperFXLoROMMap()
3047
-{
3048
-	printf("Map_SuperFXLoROMMap\n");
3049
-	map_System();
3050
-
3051
-	// Replicate the first 2Mb of the ROM at ROM + 2MB such that each 32K
3052
-	// block is repeated twice in each 64K block.
3053
-	for (int c = 0; c < 64; c++)
3054
-	{
3055
-		memmove(&ROM[0x200000 + c * 0x10000], &ROM[c * 0x8000], 0x8000);
3056
-		memmove(&ROM[0x208000 + c * 0x10000], &ROM[c * 0x8000], 0x8000);
3057
-	}
3058
-
3059
-	map_lorom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize);
3060
-	map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize);
3061
-
3062
-	map_hirom_offset(0x40, 0x7f, 0x0000, 0xffff, CalculatedSize, 0);
3063
-	map_hirom_offset(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize, 0);
3064
-
3065
-	map_space(0x00, 0x3f, 0x6000, 0x7fff, SRAM - 0x6000);
3066
-	map_space(0x80, 0xbf, 0x6000, 0x7fff, SRAM - 0x6000);
3067
-	map_space(0x70, 0x70, 0x0000, 0xffff, SRAM);
3068
-	map_space(0x71, 0x71, 0x0000, 0xffff, SRAM + 0x10000);
3069
-
3070
-	map_WRAM();
3071
-
3072
-	map_WriteProtectROM();
3073
-}*/
3074
-
3075
-/*void CMemory::Map_SetaDSPLoROMMap()
3076
-{
3077
-	printf("Map_SetaDSPLoROMMap\n");
3078
-	map_System();
3079
-
3080
-	map_lorom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize);
3081
-	map_lorom(0x40, 0x7f, 0x8000, 0xffff, CalculatedSize);
3082
-	map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize);
3083
-	map_lorom(0xc0, 0xff, 0x8000, 0xffff, CalculatedSize);
3084
-
3085
-	map_SetaDSP();
3086
-
3087
-    map_LoROMSRAM();
3088
-	map_WRAM();
3089
-
3090
-	map_WriteProtectROM();
3091
-}*/
3092
-
3093
-void CMemory::Map_SDD1LoROMMap()
3094
-{
3095
-	printf("Map_SDD1LoROMMap\n");
3096
-	map_System();
3097
-
3098
-	map_lorom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize);
3099
-	map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize);
3100
-
3101
-	map_hirom_offset(0x40, 0x7f, 0x0000, 0xffff, CalculatedSize, 0);
3102
-	map_hirom_offset(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize, 0); // will be overwritten dynamically
3103
-
3104
-	map_index(0x70, 0x7f, 0x0000, 0x7fff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
3105
-
3106
-	map_WRAM();
3107
-
3108
-	map_WriteProtectROM();
3109
-}
3110
-
3111
-/*void CMemory::Map_SA1LoROMMap()
3112
-{
3113
-	printf("Map_SA1LoROMMap\n");
3114
-	map_System();
3115
-
3116
-	map_lorom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize);
3117
-	map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize);
3118
-
3119
-	map_hirom_offset(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize, 0);
3120
-
3121
-	map_space(0x00, 0x3f, 0x3000, 0x3fff, FillRAM);
3122
-	map_space(0x80, 0xbf, 0x3000, 0x3fff, FillRAM);
3123
-	map_index(0x00, 0x3f, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O);
3124
-	map_index(0x80, 0xbf, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O);
3125
-
3126
-	for (int c = 0x40; c < 0x80; c++)
3127
-		map_space(c, c, 0x0000, 0xffff, SRAM + (c & 1) * 0x10000);
3128
-
3129
-	map_WRAM();
3130
-
3131
-	map_WriteProtectROM();
3132
-
3133
-	// Now copy the map and correct it for the SA1 CPU.
3134
-	memmove((void *) SA1.Map, (void *) Map, sizeof(Map));
3135
-	memmove((void *) SA1.WriteMap, (void *) WriteMap, sizeof(WriteMap));
3136
-
3137
-	// SA-1 Banks 00->3f and 80->bf
3138
-	for (int c = 0x000; c < 0x400; c += 0x10)
3139
-	{
3140
-		SA1.Map[c + 0] = SA1.Map[c + 0x800] = FillRAM + 0x3000;
3141
-		SA1.Map[c + 1] = SA1.Map[c + 0x801] = (uint8_t *) MAP_NONE;
3142
-		SA1.WriteMap[c + 0] = SA1.WriteMap[c + 0x800] = FillRAM + 0x3000;
3143
-		SA1.WriteMap[c + 1] = SA1.WriteMap[c + 0x801] = (uint8_t *) MAP_NONE;
3144
-	}
3145
-
3146
-	// SA-1 Banks 60->6f
3147
-	for (int c = 0x600; c < 0x700; c++)
3148
-		SA1.Map[c] = SA1.WriteMap[c] = (uint8_t *) MAP_BWRAM_BITMAP;
3149
-
3150
-	BWRAM = SRAM;
3151
-}*/
3152
-
3153
-void CMemory::Map_HiROMMap()
3154
-{
3155
-	printf("Map_HiROMMap\n");
3156
-	map_System();
3157
-
3158
-	map_hirom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize);
3159
-	map_hirom(0x40, 0x7f, 0x0000, 0xffff, CalculatedSize);
3160
-	map_hirom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize);
3161
-	map_hirom(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize);
3162
-
3163
-	/*if (Settings.DSP)
3164
-		map_DSP();*/
3165
-
3166
-	map_HiROMSRAM();
3167
-	map_WRAM();
3168
-
3169
-	map_WriteProtectROM();
3170
-}
3171
-
3172
-void CMemory::Map_ExtendedHiROMMap()
3173
-{
3174
-	printf("Map_ExtendedHiROMMap\n");
3175
-	map_System();
3176
-
3177
-	map_hirom_offset(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize - 0x400000, 0x400000);
3178
-	map_hirom_offset(0x40, 0x7f, 0x0000, 0xffff, CalculatedSize - 0x400000, 0x400000);
3179
-	map_hirom_offset(0x80, 0xbf, 0x8000, 0xffff, 0x400000, 0);
3180
-	map_hirom_offset(0xc0, 0xff, 0x0000, 0xffff, 0x400000, 0);
3181
-
3182
-	map_HiROMSRAM();
3183
-	map_WRAM();
3184
-
3185
-	map_WriteProtectROM();
3186
-}
3187
-
3188
-/*void CMemory::Map_SameGameHiROMMap()
3189
-{
3190
-	printf("Map_SameGameHiROMMap\n");
3191
-	map_System();
3192
-
3193
-	map_hirom_offset(0x00, 0x1f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
3194
-	map_hirom_offset(0x20, 0x3f, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
3195
-	map_hirom_offset(0x40, 0x5f, 0x0000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
3196
-	map_hirom_offset(0x60, 0x7f, 0x0000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
3197
-	map_hirom_offset(0x80, 0x9f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
3198
-	map_hirom_offset(0xa0, 0xbf, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
3199
-	map_hirom_offset(0xc0, 0xdf, 0x0000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
3200
-	map_hirom_offset(0xe0, 0xff, 0x0000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
3201
-
3202
-	map_HiROMSRAM();
3203
-	map_WRAM();
3204
-
3205
-	map_WriteProtectROM();
3206
-}*/
3207
-
3208
-/*void CMemory::Map_SPC7110HiROMMap()
3209
-{
3210
-	printf("Map_SPC7110HiROMMap\n");
3211
-	map_System();
3212
-
3213
-	map_index(0x00, 0x00, 0x6000, 0x7fff, MAP_HIROM_SRAM, MAP_TYPE_RAM);
3214
-	map_hirom(0x00, 0x0f, 0x8000, 0xffff, CalculatedSize);
3215
-	map_index(0x30, 0x30, 0x6000, 0x7fff, MAP_HIROM_SRAM, MAP_TYPE_RAM);
3216
-	map_index(0x50, 0x50, 0x0000, 0xffff, MAP_SPC7110_DRAM, MAP_TYPE_ROM);
3217
-	map_hirom(0x80, 0x8f, 0x8000, 0xffff, CalculatedSize);
3218
-	map_hirom_offset(0xc0, 0xcf, 0x0000, 0xffff, CalculatedSize, 0);
3219
-	map_index(0xd0, 0xff, 0x0000, 0xffff, MAP_SPC7110_ROM,  MAP_TYPE_ROM);
3220
-
3221
-	map_WRAM();
3222
-
3223
-	map_WriteProtectROM();
3224
-}*/
3225
-
3226
-// checksum
3227
-
3228
-uint16_t CMemory::checksum_calc_sum (uint8_t *data, uint32_t length)
3229
-{
3230
-	uint16_t	sum = 0;
3231
-
3232
-	for (uint32_t i = 0; i < length; i++)
3233
-		sum += data[i];
3234
-
3235
-	return sum;
3236
-}
3237
-
3238
-uint16_t CMemory::checksum_mirror_sum (uint8_t *start, uint32_t &length, uint32_t mask)
3239
-{
3240
-	// from NSRT
3241
-	while (!(length & mask))
3242
-		mask >>= 1;
3243
-
3244
-	uint16_t	part1 = checksum_calc_sum(start, mask);
3245
-	uint16_t	part2 = 0;
3246
-
3247
-	uint32_t	next_length = length - mask;
3248
-	if (next_length)
3249
-	{
3250
-		part2 = checksum_mirror_sum(start + mask, next_length, mask >> 1);
3251
-
3252
-		while (next_length < mask)
3253
-		{
3254
-			next_length += next_length;
3255
-			part2 += part2;
3256
-		}
3257
-
3258
-		length = mask + mask;
3259
-	}
3260
-
3261
-	return part1 + part2;
3262
-}
3263
-
3264
-void CMemory::Checksum_Calculate()
3265
-{
3266
-	// from NSRT
3267
-	uint16_t	sum = 0;
3268
-
3269
-	if (Settings.BS && !Settings.BSXItself)
3270
-		sum = checksum_calc_sum(ROM, CalculatedSize) - checksum_calc_sum(ROM + (HiROM ? 0xffb0 : 0x7fb0), 48);
3271
-	else
3272
-	if (Settings.SPC7110)
3273
-	{
3274
-		sum = checksum_calc_sum(ROM, CalculatedSize);
3275
-		if (CalculatedSize == 0x300000)
3276
-			sum += sum;
3277
-	}
3278
-	else
3279
-	{
3280
-		if (CalculatedSize & 0x7fff)
3281
-			sum = checksum_calc_sum(ROM, CalculatedSize);
3282
-		else
3283
-		{
3284
-			uint32_t	length = CalculatedSize;
3285
-			sum = checksum_mirror_sum(ROM, length);
3286
-		}
3287
-	}
3288
-
3289
-	CalculatedChecksum = sum;
3290
-}
3291
-
3292
-// information
3293
-
3294
-/*const char * CMemory::MapType()
3295
-{
3296
-	return HiROM ? ((ExtendedFormat != NOPE) ? "ExHiROM": "HiROM") : "LoROM";
3297
-}*/
3298
-
3299
-/*const char * CMemory::StaticRAMSize()
3300
-{
3301
-	static char	str[20];
3302
-
3303
-	if (SRAMSize > 16)
3304
-		strcpy(str, "Corrupt");
3305
-	else
3306
-		sprintf(str, "%dKbits", 8 * (SRAMMask + 1) / 1024);
3307
-
3308
-	return str;
3309
-}*/
3310
-
3311
-/*const char * CMemory::Size()
3312
-{
3313
-	static char	str[20];
3314
-
3315
-	if (Multi.cartType == 4)
3316
-		strcpy(str, "N/A");
3317
-	else
3318
-	if (ROMSize < 7 || ROMSize - 7 > 23)
3319
-		strcpy(str, "Corrupt");
3320
-	else
3321
-		sprintf(str, "%dMbits", 1 << (ROMSize - 7));
3322
-
3323
-	return str;
3324
-}*/
3325
-
3326
-/*const char * CMemory::Revision()
3327
-{
3328
-	static char	str[20];
3329
-
3330
-	sprintf(str, "1.%d", HiROM ? ((ExtendedFormat != NOPE) ? ROM[0x40ffdb] : ROM[0xffdb]) : ROM[0x7fdb]);
3331
-
3332
-	return str;
3333
-}*/
3334
-
3335
-/*const char * CMemory::KartContents()
3336
-{
3337
-	static char			str[64];
3338
-	static const char	*contents[3] = { "ROM", "ROM+RAM", "ROM+RAM+BAT" };
3339
-
3340
-	char	chip[16];
3341
-
3342
-	if (ROMType == 0 && !Settings.BS)
3343
-		return "ROM";
3344
-
3345
-	if (Settings.BS)
3346
-		strcpy(chip, "+BS");
3347
-	else
3348
-	if (Settings.SuperFX)
3349
-		strcpy(chip, "+Super FX");
3350
-	else
3351
-	if (Settings.SDD1)
3352
-		strcpy(chip, "+S-DD1");
3353
-	else
3354
-	if (Settings.OBC1)
3355
-		strcpy(chip, "+OBC1");
3356
-	else
3357
-	if (Settings.SA1)
3358
-		strcpy(chip, "+SA-1");
3359
-	else
3360
-	if (Settings.SPC7110RTC)
3361
-		strcpy(chip, "+SPC7110+RTC");
3362
-	else
3363
-	if (Settings.SPC7110)
3364
-		strcpy(chip, "+SPC7110");
3365
-	else
3366
-	if (Settings.SRTC)
3367
-		strcpy(chip, "+S-RTC");
3368
-	else
3369
-	if (Settings.C4)
3370
-		strcpy(chip, "+C4");
3371
-	else
3372
-	if (Settings.SETA == ST_010)
3373
-		strcpy(chip, "+ST-010");
3374
-	else
3375
-	if (Settings.SETA == ST_011)
3376
-		strcpy(chip, "+ST-011");
3377
-	else
3378
-	if (Settings.SETA == ST_018)
3379
-		strcpy(chip, "+ST-018");
3380
-	else
3381
-	if (Settings.DSP)
3382
-		sprintf(chip, "+DSP-%d", Settings.DSP);
3383
-	else
3384
-		strcpy(chip, "");
3385
-
3386
-	sprintf(str, "%s%s", contents[(ROMType & 0xf) % 3], chip);
3387
-
3388
-	return str;
3389
-}*/
3390
-
3391
-/*const char * CMemory::Country()
3392
-{
3393
-	switch (ROMRegion)
3394
-	{
3395
-		case 0:		return "Japan";
3396
-		case 1:		return "USA and Canada";
3397
-		case 2:		return "Oceania, Europe and Asia";
3398
-		case 3:		return "Sweden";
3399
-		case 4:		return "Finland";
3400
-		case 5:		return "Denmark";
3401
-		case 6:		return "France";
3402
-		case 7:		return "Holland";
3403
-		case 8:		return "Spain";
3404
-		case 9:		return "Germany, Austria and Switzerland";
3405
-		case 10:	return "Italy";
3406
-		case 11:	return "Hong Kong and China";
3407
-		case 12:	return "Indonesia";
3408
-		case 13:	return "South Korea";
3409
-		default:	return "Unknown";
3410
-	}
3411
-}*/
3412
-
3413
-/*const char * CMemory::PublishingCompany()
3414
-{
3415
-	if (CompanyId >= (int) (sizeof(nintendo_licensees) / sizeof(nintendo_licensees[0])) || CompanyId < 0)
3416
-		return "Unknown";
3417
-
3418
-	if (nintendo_licensees[CompanyId] == NULL)
3419
-		return "Unknown";
3420
-
3421
-	return nintendo_licensees[CompanyId];
3422
-}*/
3423
-
3424
-/*void CMemory::MakeRomInfoText (char *romtext)
3425
-{
3426
-	char	temp[256];
3427
-
3428
-	romtext[0] = 0;
3429
-
3430
-	sprintf(temp,   "            Cart Name: %s", ROMName);
3431
-	strcat(romtext, temp);
3432
-	sprintf(temp, "\n            Game Code: %s", ROMId);
3433
-	strcat(romtext, temp);
3434
-	sprintf(temp, "\n             Contents: %s", KartContents());
3435
-	strcat(romtext, temp);
3436
-	sprintf(temp, "\n                  Map: %s", MapType());
3437
-	strcat(romtext, temp);
3438
-	sprintf(temp, "\n                Speed: 0x%02X (%s)", ROMSpeed, (ROMSpeed & 0x10) ? "FastROM" : "SlowROM");
3439
-	strcat(romtext, temp);
3440
-	sprintf(temp, "\n                 Type: 0x%02X", ROMType);
3441
-	strcat(romtext, temp);
3442
-	sprintf(temp, "\n    Size (calculated): %dMbits", CalculatedSize / 0x20000);
3443
-	strcat(romtext, temp);
3444
-	sprintf(temp, "\n        Size (header): %s", Size());
3445
-	strcat(romtext, temp);
3446
-	sprintf(temp, "\n            SRAM size: %s", StaticRAMSize());
3447
-	strcat(romtext, temp);
3448
-	sprintf(temp, "\nChecksum (calculated): 0x%04X", CalculatedChecksum);
3449
-	strcat(romtext, temp);
3450
-	sprintf(temp, "\n    Checksum (header): 0x%04X", ROMChecksum);
3451
-	strcat(romtext, temp);
3452
-	sprintf(temp, "\n  Complement (header): 0x%04X", ROMComplementChecksum);
3453
-	strcat(romtext, temp);
3454
-	sprintf(temp, "\n         Video Output: %s", (ROMRegion > 12 || ROMRegion < 2) ? "NTSC 60Hz" : "PAL 50Hz");
3455
-	strcat(romtext, temp);
3456
-	sprintf(temp, "\n             Revision: %s", Revision());
3457
-	strcat(romtext, temp);
3458
-	sprintf(temp, "\n             Licensee: %s", PublishingCompany());
3459
-	strcat(romtext, temp);
3460
-	sprintf(temp, "\n               Region: %s", Country());
3461
-	strcat(romtext, temp);
3462
-	sprintf(temp, "\n                CRC32: 0x%08X", ROMCRC32);
3463
-	strcat(romtext, temp);
3464
-}*/
3465
-
3466
-// hack
3467
-
3468
-bool CMemory::match_na (const char *str)
3469
-{
3470
-	return strcmp(ROMName, str) == 0;
3471
-}
3472
-
3473
-bool CMemory::match_nn (const char *str)
3474
-{
3475
-	return strncmp(ROMName, str, strlen(str)) == 0;
3476
-}
3477
-
3478
-/*bool CMemory::match_nc (const char *str)
3479
-{
3480
-	return strncasecmp(ROMName, str, strlen(str)) == 0;
3481
-}*/
3482
-
3483
-bool CMemory::match_id (const char *str)
3484
-{
3485
-	return strncmp(ROMId, str, strlen(str)) == 0;
3486
-}
3487
-
3488
-void CMemory::ApplyROMFixes()
3489
-{
3490
-	Settings.BlockInvalidVRAMAccess = Settings.BlockInvalidVRAMAccessMaster;
3491
-
3492
-	//// Warnings
3493
-
3494
-	// Reject strange hacked games
3495
-	/*if ((ROMCRC32 == 0x6810aa95) ||
3496
-		(ROMCRC32 == 0x340f23e5) ||
3497
-		(ROMCRC32 == 0x77fd806a) ||
3498
-		(match_nn("HIGHWAY BATTLE 2")) ||
3499
-		(match_na("FX SKIING NINTENDO 96") && (ROM[0x7fda] == 0)) ||
3500
-		(match_nn("HONKAKUHA IGO GOSEI")   && (ROM[0xffd5] != 0x31)))
3501
-	{
3502
-		Settings.DisplayColor = BUILD_PIXEL(31, 0, 0);
3503
-		SET_UI_COLOR(255, 0, 0);
3504
-	}*/
3505
-
3506
-	//// APU timing hacks :(
3507
-
3508
-	Timings.APUSpeedup = 0;
3509
-	Timings.APUAllowTimeOverflow = false;
3510
-
3511
-	if (!Settings.DisableGameSpecificHacks)
3512
-	{
3513
-		if (match_id("AVCJ"))                                      // Rendering Ranger R2
3514
-			Timings.APUSpeedup = 4;
3515
-
3516
-		if (match_na("GAIA GENSOUKI 1 JPN")                     || // Gaia Gensouki
3517
-			match_id("JG  ")                                    || // Illusion of Gaia
3518
-			match_id("CQ  ")                                    || // Stunt Race FX
3519
-			match_na("SOULBLADER - 1")                          || // Soul Blader
3520
-			match_na("SOULBLAZER - 1 USA")                      || // Soul Blazer
3521
-			match_na("SLAP STICK 1 JPN")                        || // Slap Stick
3522
-			match_id("E9 ")                                     || // Robotrek
3523
-			match_nn("ACTRAISER")                               || // Actraiser
3524
-			match_nn("ActRaiser-2")                             || // Actraiser 2
3525
-			match_id("AQT")                                     || // Tenchi Souzou, Terranigma
3526
-			match_id("ATV")                                     || // Tales of Phantasia
3527
-			match_id("ARF")                                     || // Star Ocean
3528
-			match_id("APR")                                     || // Zen-Nippon Pro Wrestling 2 - 3-4 Budoukan
3529
-			match_id("A4B")                                     || // Super Bomberman 4
3530
-			match_id("Y7 ")                                     || // U.F.O. Kamen Yakisoban - Present Ban
3531
-			match_id("Y9 ")                                     || // U.F.O. Kamen Yakisoban - Shihan Ban
3532
-			match_id("APB")                                     || // Super Bomberman - Panic Bomber W
3533
-			match_na("DARK KINGDOM")                            || // Dark Kingdom
3534
-			match_na("ZAN3 SFC")                                || // Zan III Spirits
3535
-			match_na("HIOUDEN")                                 || // Hiouden - Mamono-tachi Tono Chikai
3536
-			match_na("\xC3\xDD\xBC\xC9\xB3\xC0")                || // Tenshi no Uta
3537
-			match_na("FORTUNE QUEST")                           || // Fortune Quest - Dice wo Korogase
3538
-			match_na("FISHING TO BASSING")                      || // Shimono Masaki no Fishing To Bassing
3539
-			match_na("OHMONO BLACKBASS")                        || // Oomono Black Bass Fishing - Jinzouko Hen
3540
-			match_na("MASTERS")                                 || // Harukanaru Augusta 2 - Masters
3541
-			match_na("SFC \xB6\xD2\xDD\xD7\xB2\xC0\xDE\xB0")    || // Kamen Rider
3542
-			match_na("ZENKI TENCHIMEIDOU")					    || // Kishin Douji Zenki - Tenchi Meidou
3543
-			match_nn("TokyoDome '95Battle 7")                   || // Shin Nippon Pro Wrestling Kounin '95 - Tokyo Dome Battle 7
3544
-			match_nn("SWORD WORLD SFC")                         || // Sword World SFC/2
3545
-			match_nn("LETs PACHINKO(")                          || // BS Lets Pachinko Nante Gindama 1/2/3/4
3546
-			match_nn("THE FISHING MASTER")                      || // Mark Davis The Fishing Master
3547
-			match_nn("Parlor")                                  || // Parlor mini/2/3/4/5/6/7, Parlor Parlor!/2/3/4/5
3548
-			match_na("HEIWA Parlor!Mini8")                      || // Parlor mini 8
3549
-			match_nn("SANKYO Fever! \xCC\xA8\xB0\xCA\xDE\xB0!"))   // SANKYO Fever! Fever!
3550
-			Timings.APUSpeedup = 1;
3551
-
3552
-		if (match_na ("EARTHWORM JIM 2")						|| // Earthworm Jim 2
3553
-			match_na ("NBA Hangtime")							|| // NBA Hang Time
3554
-			match_na ("MSPACMAN")								|| // Ms Pacman
3555
-			match_na ("THE MASK")								|| // The Mask
3556
-			match_na ("PRIMAL RAGE")							|| // Primal Rage
3557
-			match_na ("DOOM TROOPERS"))							   // Doom Troopers
3558
-			Timings.APUAllowTimeOverflow = true;
3559
-	}
3560
-
3561
-	S9xAPUTimingSetSpeedup(Timings.APUSpeedup);
3562
-	S9xAPUAllowTimeOverflow(Timings.APUAllowTimeOverflow);
3563
-
3564
-	//// Other timing hacks :(
3565
-
3566
-	Timings.HDMAStart   = SNES_HDMA_START_HC + Settings.HDMATimingHack - 100;
3567
-	Timings.HBlankStart = SNES_HBLANK_START_HC + Timings.HDMAStart - SNES_HDMA_START_HC;
3568
-	Timings.IRQTriggerCycles = 10;
3569
-
3570
-	if (!Settings.DisableGameSpecificHacks)
3571
-	{
3572
-		// The delay to sync CPU and DMA which Snes9x cannot emulate.
3573
-		// Some games need really severe delay timing...
3574
-		if (match_na("BATTLE GRANDPRIX")) // Battle Grandprix
3575
-		{
3576
-			Timings.DMACPUSync = 20;
3577
-			printf("DMA sync: %d\n", Timings.DMACPUSync);
3578
-		}
3579
-	}
3580
-
3581
-	if (!Settings.DisableGameSpecificHacks)
3582
-	{
3583
-		// An infinite loop reads $4212 and waits V-blank end, whereas VIRQ is set V=0.
3584
-		// If Snes9x succeeds to escape from the loop before jumping into the IRQ handler, the game goes further.
3585
-		// If Snes9x jumps into the IRQ handler before escaping from the loop,
3586
-		// Snes9x cannot escape from the loop permanently because the RTI is in the next V-blank.
3587
-		if (match_na("Aero the AcroBat 2"))
3588
-		{
3589
-			Timings.IRQPendCount = 2;
3590
-			printf("IRQ count hack: %d\n", Timings.IRQPendCount);
3591
-		}
3592
-	}
3593
-
3594
-	if (!Settings.DisableGameSpecificHacks)
3595
-	{
3596
-		// XXX: What's happening?
3597
-		if (match_na("X-MEN")) // Spider-Man and the X-Men
3598
-		{
3599
-			Settings.BlockInvalidVRAMAccess = false;
3600
-			printf("Invalid VRAM access hack\n");
3601
-		}
3602
-	}
3603
-
3604
-	//// SRAM initial value
3605
-
3606
-	if (!Settings.DisableGameSpecificHacks)
3607
-	{
3608
-		if (match_na("HITOMI3"))
3609
-		{
3610
-			SRAMSize = 1;
3611
-			SRAMMask = ((1 << (SRAMSize + 3)) * 128) - 1;
3612
-		}
3613
-
3614
-		// SRAM value fixes
3615
-		if (match_na("SUPER DRIFT OUT")      || // Super Drift Out
3616
-			match_na("SATAN IS OUR FATHER!") ||
3617
-			match_na("goemon 4"))               // Ganbare Goemon Kirakira Douchuu
3618
-			SNESGameFixes.SRAMInitialValue = 0x00;
3619
-
3620
-		// Additional game fixes by sanmaiwashi ...
3621
-		// XXX: unnecessary?
3622
-		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
3623
-			SNESGameFixes.SRAMInitialValue = 0x6b;
3624
-
3625
-		// others: BS and ST-01x games are 0x00.
3626
-	}
3627
-
3628
-	//// OAM hacks :(
3629
-
3630
-	if (!Settings.DisableGameSpecificHacks)
3631
-	{
3632
-		// OAM hacks because we don't fully understand the behavior of the SNES.
3633
-		// Totally wacky display in 2P mode...
3634
-		// seems to need a disproven behavior, so we're definitely overlooking some other bug?
3635
-		if (match_nn("UNIRACERS")) // Uniracers
793
+void CMemory::map_hirom_offset(uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, uint32_t size, uint32_t offset)
794
+{
795
+	for (uint32_t c = bank_s; c <= bank_e; ++c)
796
+		for (uint32_t i = addr_s; i <= addr_e; i += 0x1000)
3636 797
 		{
3637
-			SNESGameFixes.Uniracers = true;
3638
-			printf("Applied Uniracers hack.\n");
798
+			uint32_t p = (c << 4) | (i >> 12);
799
+			uint32_t addr = (c - bank_s) << 16;
800
+			this->Map[p] = &this->ROM[offset + this->map_mirror(size, addr)];
801
+			this->BlockIsROM[p] = true;
802
+			this->BlockIsRAM[p] = false;
3639 803
 		}
3640
-	}
3641 804
 }
3642 805
 
3643
-// UPS % IPS
3644
-
3645
-/*static uint32_t ReadUPSPointer (const uint8_t *data, unsigned &addr, unsigned size)
806
+void CMemory::map_space(uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, uint8_t *data)
3646 807
 {
3647
-	uint32_t offset = 0, shift = 1;
3648
-	while(addr < size) {
3649
-		uint8_t x = data[addr++];
3650
-		offset += (x & 0x7f) * shift;
3651
-		if(x & 0x80) break;
3652
-		shift <<= 7;
3653
-		offset += shift;
3654
-	}
3655
-	return offset;
808
+	for (uint32_t c = bank_s; c <= bank_e; ++c)
809
+		for (uint32_t i = addr_s; i <= addr_e; i += 0x1000)
810
+		{
811
+			uint32_t p = (c << 4) | (i >> 12);
812
+			this->Map[p] = data;
813
+			this->BlockIsROM[p] = false;
814
+			this->BlockIsRAM[p] = true;
815
+		}
3656 816
 }
3657 817
 
3658
-//NOTE: UPS patches are *never* created against a headered ROM!
3659
-//this is per the UPS file specification. however, do note that it is
3660
-//technically possible for a non-compliant patcher to ignore this requirement.
3661
-//therefore, it is *imperative* that no emulator support such patches.
3662
-//thusly, we ignore the "long offset" parameter below. failure to do so would
3663
-//completely invalidate the purpose of UPS; which is to avoid header vs
3664
-//no-header patching errors that result in IPS patches having a 50/50 chance of
3665
-//being applied correctly.
3666
-
3667
-static bool ReadUPSPatch (Reader *r, long, int32_t &rom_size)
818
+void CMemory::map_index(uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, int index, int type)
3668 819
 {
3669
-	//Reader lacks size() and rewind(), so we need to read in the file to get its size
3670
-	uint8_t *data = new uint8_t[8 * 1024 * 1024];  //allocate a lot of memory, better safe than sorry ...
3671
-	uint32_t size = 0;
3672
-	while(true) {
3673
-		int value = r->get_char();
3674
-		if(value == EOF) break;
3675
-		data[size++] = value;
3676
-		if(size >= 8 * 1024 * 1024) {
3677
-			//prevent buffer overflow: SNES-made UPS patches should never be this big anyway ...
3678
-			delete[] data;
3679
-			return false;
3680
-		}
3681
-	}
3682
-
3683
-	//4-byte header + 1-byte input size + 1-byte output size + 4-byte patch CRC32 + 4-byte unpatched CRC32 + 4-byte patched CRC32
3684
-	if(size < 18) { delete[] data; return false; }  //patch is too small
3685
-
3686
-	uint32_t addr = 0;
3687
-	if(data[addr++] != 'U') { delete[] data; return false; }  //patch has an invalid header
3688
-	if(data[addr++] != 'P') { delete[] data; return false; }  //...
3689
-	if(data[addr++] != 'S') { delete[] data; return false; }  //...
3690
-	if(data[addr++] != '1') { delete[] data; return false; }  //...
3691
-
3692
-	uint32_t patch_crc32 = caCRC32(data, size - 4);  //don't include patch CRC32 itself in CRC32 calculation
3693
-	uint32_t rom_crc32 = caCRC32(Memory.ROM, rom_size);
3694
-	uint32_t px_crc32 = (data[size - 12] << 0) + (data[size - 11] << 8) + (data[size - 10] << 16) + (data[size -  9] << 24);
3695
-	uint32_t py_crc32 = (data[size -  8] << 0) + (data[size -  7] << 8) + (data[size -  6] << 16) + (data[size -  5] << 24);
3696
-	uint32_t pp_crc32 = (data[size -  4] << 0) + (data[size -  3] << 8) + (data[size -  2] << 16) + (data[size -  1] << 24);
3697
-	if(patch_crc32 != pp_crc32) { delete[] data; return false; }  //patch is corrupted
3698
-	if((rom_crc32 != px_crc32) && (rom_crc32 != py_crc32)) { delete[] data; return false; }  //patch is for a different ROM
3699
-
3700
-	uint32_t px_size = ReadUPSPointer(data, addr, size);
3701
-	uint32_t py_size = ReadUPSPointer(data, addr, size);
3702
-	uint32_t out_size = ((uint32_t) rom_size == px_size) ? py_size : px_size;
3703
-	if(out_size > CMemory::MAX_ROM_SIZE) { delete[] data; return false; }  //applying this patch will overflow Memory.ROM buffer
3704
-
3705
-	//fill expanded area with 0x00s; so that XORing works as expected below.
3706
-	//note that this is needed (and works) whether output ROM is larger or smaller than pre-patched ROM
3707
-	for(unsigned i = min((uint32_t) rom_size, out_size); i < max((uint32_t) rom_size, out_size); i++) {
3708
-		Memory.ROM[i] = 0x00;
3709
-	}
820
+	bool isROM = !(type == MAP_TYPE_I_O || type == MAP_TYPE_RAM);
821
+	bool isRAM = type != MAP_TYPE_I_O;
3710 822
 
3711
-	uint32_t relative = 0;
3712
-	while(addr < size - 12) {
3713
-		relative += ReadUPSPointer(data, addr, size);
3714
-		while(addr < size - 12) {
3715
-			uint8_t x = data[addr++];
3716
-			Memory.ROM[relative++] ^= x;
3717
-			if(!x) break;
823
+	for (uint32_t c = bank_s; c <= bank_e; ++c)
824
+		for (uint32_t i = addr_s; i <= addr_e; i += 0x1000)
825
+		{
826
+			uint32_t p = (c << 4) | (i >> 12);
827
+			this->Map[p] = reinterpret_cast<uint8_t *>(index);
828
+			this->BlockIsROM[p] = isROM;
829
+			this->BlockIsRAM[p] = isRAM;
3718 830
 		}
3719
-	}
3720
-
3721
-	rom_size = out_size;
3722
-	delete[] data;
3723
-
3724
-	uint32_t out_crc32 = caCRC32(Memory.ROM, rom_size);
3725
-	if(((rom_crc32 == px_crc32) && (out_crc32 == py_crc32))
3726
-	|| ((rom_crc32 == py_crc32) && (out_crc32 == px_crc32))
3727
-	) {
3728
-		return true;
3729
-	} else {
3730
-		//technically, reaching here means that patching has failed.
3731
-		//we should return false, but unfortunately Memory.ROM has already
3732
-		//been modified above and cannot be undone. to do this properly, we
3733
-		//would need to make a copy of Memory.ROM, apply the patch, and then
3734
-		//copy that back to Memory.ROM.
3735
-		//
3736
-		//however, the only way for this case to happen is if the UPS patch file
3737
-		//itself is corrupted, which should be detected by the patch CRC32 check
3738
-		//above anyway. errors due to the wrong ROM or patch file being used are
3739
-		//already caught above.
3740
-		fprintf(stderr, "WARNING: UPS patching appears to have failed.\nGame may not be playable.\n");
3741
-		return true;
3742
-	}
3743 831
 }
3744 832
 
3745
-static long ReadInt (Reader *r, unsigned nbytes)
833
+void CMemory::map_System()
3746 834
 {
3747
-	long	v = 0;
3748
-
3749
-	while (nbytes--)
3750
-	{
3751
-		int	c = r->get_char();
3752
-		if (c == EOF)
3753
-			return -1;
3754
-		v = (v << 8) | (c & 0xFF);
3755
-	}
3756
-
3757
-	return v;
835
+	// will be overwritten
836
+	this->map_space(0x00, 0x3f, 0x0000, 0x1fff, &this->RAM[0]);
837
+	this->map_index(0x00, 0x3f, 0x2000, 0x3fff, MAP_PPU, MAP_TYPE_I_O);
838
+	this->map_index(0x00, 0x3f, 0x4000, 0x5fff, MAP_CPU, MAP_TYPE_I_O);
839
+	this->map_space(0x80, 0xbf, 0x0000, 0x1fff, &this->RAM[0]);
840
+	this->map_index(0x80, 0xbf, 0x2000, 0x3fff, MAP_PPU, MAP_TYPE_I_O);
841
+	this->map_index(0x80, 0xbf, 0x4000, 0x5fff, MAP_CPU, MAP_TYPE_I_O);
3758 842
 }
3759 843
 
3760
-static bool ReadIPSPatch (Reader *r, long offset, int32_t &rom_size)
844
+void CMemory::map_WRAM()
3761 845
 {
3762
-	const int32_t	IPS_EOF = 0x00454F46l;
3763
-	int32_t		ofs;
3764
-	char		fname[6];
3765
-
3766
-	fname[5] = 0;
3767
-	for (int i = 0; i < 5; i++)
3768
-	{
3769
-		int	c = r->get_char();
3770
-		if (c == EOF)
3771
-			return 0;
3772
-		fname[i] = (char) c;
3773
-	}
3774
-
3775
-	if (strncmp(fname, "PATCH", 5))
3776
-		return 0;
3777
-
3778
-	for (;;)
3779
-	{
3780
-		long	len, rlen;
3781
-		int		rchar;
3782
-
3783
-		ofs = ReadInt(r, 3);
3784
-		if (ofs == -1)
3785
-			return 0;
3786
-
3787
-		if (ofs == IPS_EOF)
3788
-			break;
3789
-
3790
-		ofs -= offset;
3791
-
3792
-		len = ReadInt(r, 2);
3793
-		if (len == -1)
3794
-			return 0;
3795
-
3796
-		if (len)
3797
-		{
3798
-			if (ofs + len > CMemory::MAX_ROM_SIZE)
3799
-				return 0;
3800
-
3801
-			while (len--)
3802
-			{
3803
-				rchar = r->get_char();
3804
-				if (rchar == EOF)
3805
-					return 0;
3806
-				Memory.ROM[ofs++] = (uint8_t) rchar;
3807
-			}
3808
-
3809
-			if (ofs > rom_size)
3810
-				rom_size = ofs;
3811
-		}
3812
-		else
3813
-		{
3814
-			rlen = ReadInt(r, 2);
3815
-			if (rlen == -1)
3816
-				return 0;
3817
-
3818
-			rchar = r->get_char();
3819
-			if (rchar == EOF)
3820
-				return 0;
3821
-
3822
-			if (ofs + rlen > CMemory::MAX_ROM_SIZE)
3823
-				return 0;
3824
-
3825
-			while (rlen--)
3826
-				Memory.ROM[ofs++] = (uint8_t) rchar;
3827
-
3828
-			if (ofs > rom_size)
3829
-				rom_size = ofs;
3830
-		}
3831
-	}
3832
-
3833
-	ofs = ReadInt(r, 3);
3834
-	if (ofs != -1 && ofs - offset < rom_size)
3835
-		rom_size = ofs - offset;
3836
-
3837
-	return 1;
3838
-}*/
846
+	// will overwrite others
847
+	this->map_space(0x7e, 0x7e, 0x0000, 0xffff, &this->RAM[0]);
848
+	this->map_space(0x7f, 0x7f, 0x0000, 0xffff, &this->RAM[0x10000]);
849
+}
3839 850
 
3840
-#ifdef UNZIP_SUPPORT
3841
-static int unzFindExtension (unzFile &file, const char *ext, bool restart, bool print)
851
+void CMemory::map_LoROMSRAM()
3842 852
 {
3843
-	unz_file_info	info;
3844
-	int				port, l = strlen(ext);
3845
-
3846
-	if (restart)
3847
-		port = unzGoToFirstFile(file);
3848
-	else
3849
-		port = unzGoToNextFile(file);
3850
-
3851
-	while (port == UNZ_OK)
3852
-	{
3853
-		int		len;
3854
-		char	name[132];
3855
-
3856
-		unzGetCurrentFileInfo(file, &info, name, 128, NULL, 0, NULL, 0);
3857
-		len = strlen(name);
3858
-
3859
-		if (len >= l + 1 && name[len - l - 1] == '.' && strcasecmp(name + len - l, ext) == 0 && unzOpenCurrentFile(file) == UNZ_OK)
3860
-		{
3861
-			if (print)
3862
-				printf("Using IPS or UPS patch %s", name);
3863
-
3864
-			return port;
3865
-		}
3866
-
3867
-		port = unzGoToNextFile(file);
3868
-	}
3869
-
3870
-	return port;
853
+	this->map_index(0x70, 0x7f, 0x0000, 0x7fff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
854
+	this->map_index(0xf0, 0xff, 0x0000, 0x7fff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
3871 855
 }
3872
-#endif
3873 856
 
3874
-/*void CMemory::CheckForAnyPatch (const char *rom_filename, bool header, int32_t &rom_size)
857
+void CMemory::map_HiROMSRAM()
3875 858
 {
3876
-	if (Settings.NoPatch)
3877
-		return;
3878
-
3879
-	STREAM		patch_file  = NULL;
3880
-	uint32_t		i;
3881
-	long		offset = header ? 512 : 0;
3882
-	int			ret;
3883
-	bool		flag;
3884
-	char		dir[_MAX_DIR + 1], drive[_MAX_DRIVE + 1], name[_MAX_FNAME + 1], ext[_MAX_EXT + 1], ips[_MAX_EXT + 3], fname[PATH_MAX + 1];
3885
-	const char	*n;
859
+	this->map_index(0x20, 0x3f, 0x6000, 0x7fff, MAP_HIROM_SRAM, MAP_TYPE_RAM);
860
+	this->map_index(0xa0, 0xbf, 0x6000, 0x7fff, MAP_HIROM_SRAM, MAP_TYPE_RAM);
861
+}
3886 862
 
3887
-	// UPS
863
+void CMemory::map_WriteProtectROM()
864
+{
865
+	std::copy(&this->Map[0], &this->Map[0x1000], &this->WriteMap[0]);
3888 866
 
3889
-	_splitpath(rom_filename, drive, dir, name, ext);
3890
-	_makepath(fname, drive, dir, name, "ups");
867
+	for (int c = 0; c < 0x1000; ++c)
868
+		if (this->BlockIsROM[c])
869
+			this->WriteMap[c] = reinterpret_cast<uint8_t *>(MAP_NONE);
870
+}
3891 871
 
3892
-	if ((patch_file = OPEN_STREAM(fname, "rb")) != NULL)
872
+void CMemory::Map_Initialize()
873
+{
874
+	for (int c = 0; c < 0x1000; ++c)
3893 875
 	{
3894
-		printf("Using UPS patch %s", fname);
3895
-
3896
-		ret = ReadUPSPatch(new fReader(patch_file), 0, rom_size);
3897
-		CLOSE_STREAM(patch_file);
3898
-
3899
-		if (ret)
3900
-		{
3901
-			printf("!\n");
3902
-			return;
3903
-		}
3904
-		else
3905
-			printf(" failed!\n");
876
+		this->Map[c] = this->WriteMap[c] = reinterpret_cast<uint8_t *>(MAP_NONE);
877
+		this->BlockIsROM[c] = this->BlockIsRAM[c] = false;
3906 878
 	}
879
+}
3907 880
 
3908
-#ifdef UNZIP_SUPPORT
3909
-	if (!strcasecmp(ext, "zip") || !strcasecmp(ext, ".zip"))
3910
-	{
3911
-		unzFile	file = unzOpen(rom_filename);
3912
-		if (file)
3913
-		{
3914
-			int	port = unzFindExtension(file, "ups");
3915
-			if (port == UNZ_OK)
3916
-			{
3917
-				printf(" in %s", rom_filename);
881
+void CMemory::Map_LoROMMap()
882
+{
883
+	this->map_System();
3918 884
 
3919
-				ret = ReadUPSPatch(new unzReader(file), offset, rom_size);
3920
-				unzCloseCurrentFile(file);
885
+	this->map_lorom(0x00, 0x3f, 0x8000, 0xffff, this->CalculatedSize);
886
+	this->map_lorom(0x40, 0x7f, 0x0000, 0xffff, this->CalculatedSize);
887
+	this->map_lorom(0x80, 0xbf, 0x8000, 0xffff, this->CalculatedSize);
888
+	this->map_lorom(0xc0, 0xff, 0x0000, 0xffff, this->CalculatedSize);
3921 889
 
3922
-				if (ret)
3923
-					printf("!\n");
3924
-				else
3925
-					printf(" failed!\n");
3926
-			}
3927
-		}
3928
-	}
3929
-#endif
890
+	this->map_LoROMSRAM();
891
+	this->map_WRAM();
3930 892
 
3931
-	n = S9xGetFilename(".ups", IPS_DIR);
893
+	this->map_WriteProtectROM();
894
+}
3932 895
 
3933
-	if ((patch_file = OPEN_STREAM(n, "rb")) != NULL)
3934
-	{
3935
-		printf("Using UPS patch %s", n);
896
+void CMemory::Map_NoMAD1LoROMMap()
897
+{
898
+	this->map_System();
3936 899
 
3937
-		ret = ReadUPSPatch(new fReader(patch_file), 0, rom_size);
3938
-		CLOSE_STREAM(patch_file);
900
+	this->map_lorom(0x00, 0x3f, 0x8000, 0xffff, this->CalculatedSize);
901
+	this->map_lorom(0x40, 0x7f, 0x0000, 0xffff, this->CalculatedSize);
902
+	this->map_lorom(0x80, 0xbf, 0x8000, 0xffff, this->CalculatedSize);
903
+	this->map_lorom(0xc0, 0xff, 0x0000, 0xffff, this->CalculatedSize);
3939 904
 
3940
-		if (ret)
3941
-		{
3942
-			printf("!\n");
3943
-			return;
3944
-		}
3945
-		else
3946
-			printf(" failed!\n");
3947
-	}
905
+	this->map_index(0x70, 0x7f, 0x0000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
906
+	this->map_index(0xf0, 0xff, 0x0000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
3948 907
 
3949
-	// IPS
908
+	this->map_WRAM();
3950 909
 
3951
-	_splitpath(rom_filename, drive, dir, name, ext);
3952
-	_makepath(fname, drive, dir, name, "ips");
910
+	this->map_WriteProtectROM();
911
+}
3953 912
 
3954
-	if ((patch_file = OPEN_STREAM(fname, "rb")) != NULL)
3955
-	{
3956
-		printf("Using IPS patch %s", fname);
913
+void CMemory::Map_JumboLoROMMap()
914
+{
915
+	// XXX: Which game uses this?
916
+	this->map_System();
3957 917
 
3958
-		ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size);
3959
-		CLOSE_STREAM(patch_file);
918
+	this->map_lorom_offset(0x00, 0x3f, 0x8000, 0xffff, this->CalculatedSize - 0x400000, 0x400000);
919
+	this->map_lorom_offset(0x40, 0x7f, 0x0000, 0xffff, this->CalculatedSize - 0x400000, 0x400000);
920
+	this->map_lorom_offset(0x80, 0xbf, 0x8000, 0xffff, 0x400000, 0);
921
+	this->map_lorom_offset(0xc0, 0xff, 0x0000, 0xffff, 0x400000, 0x200000);
3960 922
 
3961
-		if (ret)
3962
-		{
3963
-			printf("!\n");
3964
-			return;
3965
-		}
3966
-		else
3967
-			printf(" failed!\n");
3968
-	}
923
+	this->map_LoROMSRAM();
924
+	this->map_WRAM();
3969 925
 
3970
-	if (_MAX_EXT > 6)
3971
-	{
3972
-		i = 0;
3973
-		flag = false;
926
+	this->map_WriteProtectROM();
927
+}
3974 928
 
3975
-		do
3976
-		{
3977
-			snprintf(ips, 8, "%03d.ips", i);
3978
-			_makepath(fname, drive, dir, name, ips);
929
+void CMemory::Map_ROM24MBSLoROMMap()
930
+{
931
+	// PCB: BSC-1A5M-01, BSC-1A7M-10
932
+	this->map_System();
3979 933
 
3980
-			if (!(patch_file = OPEN_STREAM(fname, "rb")))
3981
-				break;
934
+	this->map_lorom_offset(0x00, 0x1f, 0x8000, 0xffff, 0x100000, 0);
935
+	this->map_lorom_offset(0x20, 0x3f, 0x8000, 0xffff, 0x100000, 0x100000);
936
+	this->map_lorom_offset(0x80, 0x9f, 0x8000, 0xffff, 0x100000, 0x200000);
937
+	this->map_lorom_offset(0xa0, 0xbf, 0x8000, 0xffff, 0x100000, 0x100000);
3982 938
 
3983
-			printf("Using IPS patch %s", fname);
939
+	this->map_LoROMSRAM();
940
+	this->map_WRAM();
3984 941
 
3985
-			ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size);
3986
-			CLOSE_STREAM(patch_file);
942
+	this->map_WriteProtectROM();
943
+}
3987 944
 
3988
-			if (ret)
3989
-			{
3990
-				printf("!\n");
3991
-				flag = true;
3992
-			}
3993
-			else
3994
-			{
3995
-				printf(" failed!\n");
3996
-				break;
3997
-			}
3998
-		} while (++i < 1000);
945
+void CMemory::Map_SRAM512KLoROMMap()
946
+{
947
+	this->map_System();
3999 948
 
4000
-		if (flag)
4001
-			return;
4002
-	}
949
+	this->map_lorom(0x00, 0x3f, 0x8000, 0xffff, this->CalculatedSize);
950
+	this->map_lorom(0x40, 0x7f, 0x0000, 0xffff, this->CalculatedSize);
951
+	this->map_lorom(0x80, 0xbf, 0x8000, 0xffff, this->CalculatedSize);
952
+	this->map_lorom(0xc0, 0xff, 0x0000, 0xffff, this->CalculatedSize);
4003 953
 
4004
-	if (_MAX_EXT > 3)
4005
-	{
4006
-		i = 0;
4007
-		flag = false;
954
+	this->map_space(0x70, 0x70, 0x0000, 0xffff, &this->SRAM[0]);
955
+	this->map_space(0x71, 0x71, 0x0000, 0xffff, &this->SRAM[0x8000]);
956
+	this->map_space(0x72, 0x72, 0x0000, 0xffff, &this->SRAM[0x10000]);
957
+	this->map_space(0x73, 0x73, 0x0000, 0xffff, &this->SRAM[0x18000]);
4008 958
 
4009
-		do
4010
-		{
4011
-			snprintf(ips, _MAX_EXT + 2, "ips%d", i);
4012
-			if (strlen(ips) > _MAX_EXT)
4013
-				break;
4014
-			_makepath(fname, drive, dir, name, ips);
959
+	this->map_WRAM();
4015 960
 
4016
-			if (!(patch_file = OPEN_STREAM(fname, "rb")))
4017
-				break;
961
+	this->map_WriteProtectROM();
962
+}
4018 963
 
4019
-			printf("Using IPS patch %s", fname);
964
+void CMemory::Map_SDD1LoROMMap()
965
+{
966
+	this->map_System();
4020 967
 
4021
-			ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size);
4022
-			CLOSE_STREAM(patch_file);
968
+	this->map_lorom(0x00, 0x3f, 0x8000, 0xffff, this->CalculatedSize);
969
+	this->map_lorom(0x80, 0xbf, 0x8000, 0xffff, this->CalculatedSize);
4023 970
 
4024
-			if (ret)
4025
-			{
4026
-				printf("!\n");
4027
-				flag = true;
4028
-			}
4029
-			else
4030
-			{
4031
-				printf(" failed!\n");
4032
-				break;
4033
-			}
4034
-		} while (++i != 0);
971
+	this->map_hirom_offset(0x40, 0x7f, 0x0000, 0xffff, this->CalculatedSize, 0);
972
+	this->map_hirom_offset(0xc0, 0xff, 0x0000, 0xffff, this->CalculatedSize, 0); // will be overwritten dynamically
4035 973
 
4036
-		if (flag)
4037
-			return;
4038
-	}
974
+	this->map_index(0x70, 0x7f, 0x0000, 0x7fff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
4039 975
 
4040
-	if (_MAX_EXT > 2)
4041
-	{
4042
-		i = 0;
4043
-		flag = false;
976
+	this->map_WRAM();
4044 977
 
4045
-		do
4046
-		{
4047
-			snprintf(ips, 4, "ip%d", i);
4048
-			_makepath(fname, drive, dir, name, ips);
978
+	this->map_WriteProtectROM();
979
+}
4049 980
 
4050
-			if (!(patch_file = OPEN_STREAM(fname, "rb")))
4051
-				break;
981
+void CMemory::Map_HiROMMap()
982
+{
983
+	this->map_System();
4052 984
 
4053
-			printf("Using IPS patch %s", fname);
985
+	this->map_hirom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize);
986
+	this->map_hirom(0x40, 0x7f, 0x0000, 0xffff, CalculatedSize);
987
+	this->map_hirom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize);
988
+	this->map_hirom(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize);
4054 989
 
4055
-			ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size);
4056
-			CLOSE_STREAM(patch_file);
990
+	this->map_HiROMSRAM();
991
+	this->map_WRAM();
4057 992
 
4058
-			if (ret)
4059
-			{
4060
-				printf("!\n");
4061
-				flag = true;
4062
-			}
4063
-			else
4064
-			{
4065
-				printf(" failed!\n");
4066
-				break;
4067
-			}
4068
-		} while (++i < 10);
993
+	this->map_WriteProtectROM();
994
+}
4069 995
 
4070
-		if (flag)
4071
-			return;
4072
-	}
996
+void CMemory::Map_ExtendedHiROMMap()
997
+{
998
+	this->map_System();
4073 999
 
4074
-#ifdef UNZIP_SUPPORT
4075
-	if (!strcasecmp(ext, "zip") || !strcasecmp(ext, ".zip"))
4076
-	{
4077
-		unzFile	file = unzOpen(rom_filename);
4078
-		if (file)
4079
-		{
4080
-			int	port = unzFindExtension(file, "ips");
4081
-			while (port == UNZ_OK)
4082
-			{
4083
-				printf(" in %s", rom_filename);
1000
+	this->map_hirom_offset(0x00, 0x3f, 0x8000, 0xffff, this->CalculatedSize - 0x400000, 0x400000);
1001
+	this->map_hirom_offset(0x40, 0x7f, 0x0000, 0xffff, this->CalculatedSize - 0x400000, 0x400000);
1002
+	this->map_hirom_offset(0x80, 0xbf, 0x8000, 0xffff, 0x400000, 0);
1003
+	this->map_hirom_offset(0xc0, 0xff, 0x0000, 0xffff, 0x400000, 0);
4084 1004
 
4085
-				ret = ReadIPSPatch(new unzReader(file), offset, rom_size);
4086
-				unzCloseCurrentFile(file);
1005
+	this->map_HiROMSRAM();
1006
+	this->map_WRAM();
4087 1007
 
4088
-				if (ret)
4089
-				{
4090
-					printf("!\n");
4091
-					flag = true;
4092
-				}
4093
-				else
4094
-					printf(" failed!\n");
1008
+	this->map_WriteProtectROM();
1009
+}
4095 1010
 
4096
-				port = unzFindExtension(file, "ips", false);
4097
-			}
1011
+// hack
4098 1012
 
4099
-			if (!flag)
4100
-			{
4101
-				i = 0;
4102
-
4103
-				do
4104
-				{
4105
-					snprintf(ips, 8, "%03d.ips", i);
4106
-
4107
-					if (unzFindExtension(file, ips) != UNZ_OK)
4108
-						break;
4109
-
4110
-					printf(" in %s", rom_filename);
4111
-
4112
-					ret = ReadIPSPatch(new unzReader(file), offset, rom_size);
4113
-					unzCloseCurrentFile(file);
4114
-
4115
-					if (ret)
4116
-					{
4117
-						printf("!\n");
4118
-						flag = true;
4119
-					}
4120
-					else
4121
-					{
4122
-						printf(" failed!\n");
4123
-						break;
4124
-					}
4125
-
4126
-					if (unzFindExtension(file, ips, false, false) == UNZ_OK)
4127
-						printf("WARNING: Ignoring extra .%s files!\n", ips);
4128
-				} while (++i < 1000);
4129
-			}
1013
+bool CMemory::match_na(const char *str)
1014
+{
1015
+	return !strcmp(this->ROMName, str);
1016
+}
4130 1017
 
4131
-			if (!flag)
4132
-			{
4133
-				i = 0;
4134
-
4135
-				do
4136
-				{
4137
-					snprintf(ips, _MAX_EXT + 2, "ips%d", i);
4138
-					if (strlen(ips) > _MAX_EXT)
4139
-						break;
4140
-
4141
-					if (unzFindExtension(file, ips) != UNZ_OK)
4142
-						break;
4143
-
4144
-					printf(" in %s", rom_filename);
4145
-
4146
-					ret = ReadIPSPatch(new unzReader(file), offset, rom_size);
4147
-					unzCloseCurrentFile(file);
4148
-
4149
-					if (ret)
4150
-					{
4151
-						printf("!\n");
4152
-						flag = true;
4153
-					}
4154
-					else
4155
-					{
4156
-						printf(" failed!\n");
4157
-						break;
4158
-					}
4159
-
4160
-					if (unzFindExtension(file, ips, false, false) == UNZ_OK)
4161
-						printf("WARNING: Ignoring extra .%s files!\n", ips);
4162
-				} while (++i != 0);
4163
-			}
1018
+bool CMemory::match_nn(const char *str)
1019
+{
1020
+	return !strncmp(this->ROMName, str, strlen(str));
1021
+}
4164 1022
 
4165
-			if (!flag)
4166
-			{
4167
-				i = 0;
4168
-
4169
-				do
4170
-				{
4171
-					snprintf(ips, 4, "ip%d", i);
4172
-
4173
-					if (unzFindExtension(file, ips) != UNZ_OK)
4174
-						break;
4175
-
4176
-					printf(" in %s", rom_filename);
4177
-
4178
-					ret = ReadIPSPatch(new unzReader(file), offset, rom_size);
4179
-					unzCloseCurrentFile(file);
4180
-
4181
-					if (ret)
4182
-					{
4183
-						printf("!\n");
4184
-						flag = true;
4185
-					}
4186
-					else
4187
-					{
4188
-						printf(" failed!\n");
4189
-						break;
4190
-					}
4191
-
4192
-					if (unzFindExtension(file, ips, false, false) == UNZ_OK)
4193
-						printf("WARNING: Ignoring extra .%s files!\n", ips);
4194
-				} while (++i < 10);
4195
-			}
1023
+bool CMemory::match_id(const char *str)
1024
+{
1025
+	return !strncmp(this->ROMId, str, strlen(str));
1026
+}
4196 1027
 
4197
-			assert(unzClose(file) == UNZ_OK);
1028
+void CMemory::ApplyROMFixes()
1029
+{
1030
+	Settings.BlockInvalidVRAMAccess = Settings.BlockInvalidVRAMAccessMaster;
4198 1031
 
4199
-			if (flag)
4200
-				return;
4201
-		}
4202
-	}
4203
-#endif
1032
+	//// APU timing hacks :(
4204 1033
 
4205
-	n = S9xGetFilename(".ips", IPS_DIR);
1034
+	Timings.APUSpeedup = 0;
1035
+	Timings.APUAllowTimeOverflow = false;
4206 1036
 
4207
-	if ((patch_file = OPEN_STREAM(n, "rb")) != NULL)
1037
+	if (!Settings.DisableGameSpecificHacks)
4208 1038
 	{
4209
-		printf("Using IPS patch %s", n);
1039
+		if (this->match_id("AVCJ")) // Rendering Ranger R2
1040
+			Timings.APUSpeedup = 4;
4210 1041
 
4211
-		ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size);
4212
-		CLOSE_STREAM(patch_file);
1042
+		if (this->match_na("GAIA GENSOUKI 1 JPN") || // Gaia Gensouki
1043
+			this->match_id("JG  ") || // Illusion of Gaia
1044
+			this->match_id("CQ  ") || // Stunt Race FX
1045
+			this->match_na("SOULBLADER - 1") || // Soul Blader
1046
+			this->match_na("SOULBLAZER - 1 USA") || // Soul Blazer
1047
+			this->match_na("SLAP STICK 1 JPN") || // Slap Stick
1048
+			this->match_id("E9 ") || // Robotrek
1049
+			this->match_nn("ACTRAISER") || // Actraiser
1050
+			this->match_nn("ActRaiser-2") || // Actraiser 2
1051
+			this->match_id("AQT") || // Tenchi Souzou, Terranigma
1052
+			this->match_id("ATV") || // Tales of Phantasia
1053
+			this->match_id("ARF") || // Star Ocean
1054
+			this->match_id("APR") || // Zen-Nippon Pro Wrestling 2 - 3-4 Budoukan
1055
+			this->match_id("A4B") || // Super Bomberman 4
1056
+			this->match_id("Y7 ") || // U.F.O. Kamen Yakisoban - Present Ban
1057
+			this->match_id("Y9 ") || // U.F.O. Kamen Yakisoban - Shihan Ban
1058
+			this->match_id("APB") || // Super Bomberman - Panic Bomber W
1059
+			this->match_na("DARK KINGDOM") || // Dark Kingdom
1060
+			this->match_na("ZAN3 SFC") || // Zan III Spirits
1061
+			this->match_na("HIOUDEN") || // Hiouden - Mamono-tachi Tono Chikai
1062
+			this->match_na("\xC3\xDD\xBC\xC9\xB3\xC0") || // Tenshi no Uta
1063
+			this->match_na("FORTUNE QUEST") || // Fortune Quest - Dice wo Korogase
1064
+			this->match_na("FISHING TO BASSING") || // Shimono Masaki no Fishing To Bassing
1065
+			this->match_na("OHMONO BLACKBASS") || // Oomono Black Bass Fishing - Jinzouko Hen
1066
+			this->match_na("MASTERS") || // Harukanaru Augusta 2 - Masters
1067
+			this->match_na("SFC \xB6\xD2\xDD\xD7\xB2\xC0\xDE\xB0") || // Kamen Rider
1068
+			this->match_na("ZENKI TENCHIMEIDOU") || // Kishin Douji Zenki - Tenchi Meidou
1069
+			this->match_nn("TokyoDome '95Battle 7") || // Shin Nippon Pro Wrestling Kounin '95 - Tokyo Dome Battle 7
1070
+			this->match_nn("SWORD WORLD SFC") || // Sword World SFC/2
1071
+			this->match_nn("LETs PACHINKO(") || // BS Lets Pachinko Nante Gindama 1/2/3/4
1072
+			this->match_nn("THE FISHING MASTER") || // Mark Davis The Fishing Master
1073
+			this->match_nn("Parlor") || // Parlor mini/2/3/4/5/6/7, Parlor Parlor!/2/3/4/5
1074
+			this->match_na("HEIWA Parlor!Mini8") || // Parlor mini 8
1075
+			this->match_nn("SANKYO Fever! \xCC\xA8\xB0\xCA\xDE\xB0!")) // SANKYO Fever! Fever!
1076
+			Timings.APUSpeedup = 1;
4213 1077
 
4214
-		if (ret)
4215
-		{
4216
-			printf("!\n");
4217
-			return;
4218
-		}
4219
-		else
4220
-			printf(" failed!\n");
1078
+		if (this->match_na("EARTHWORM JIM 2") || // Earthworm Jim 2
1079
+			this->match_na("NBA Hangtime") || // NBA Hang Time
1080
+			this->match_na("MSPACMAN") || // Ms Pacman
1081
+			this->match_na("THE MASK") || // The Mask
1082
+			this->match_na("PRIMAL RAGE") || // Primal Rage
1083
+			this->match_na("DOOM TROOPERS")) // Doom Troopers
1084
+			Timings.APUAllowTimeOverflow = true;
4221 1085
 	}
4222 1086
 
4223
-	if (_MAX_EXT > 6)
4224
-	{
4225
-		i = 0;
4226
-		flag = false;
4227
-
4228
-		do
4229
-		{
4230
-			snprintf(ips, 9, ".%03d.ips", i);
4231
-			n = S9xGetFilename(ips, IPS_DIR);
4232
-
4233
-			if (!(patch_file = OPEN_STREAM(n, "rb")))
4234
-				break;
4235
-
4236
-			printf("Using IPS patch %s", n);
4237
-
4238
-			ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size);
4239
-			CLOSE_STREAM(patch_file);
1087
+	S9xAPUTimingSetSpeedup(Timings.APUSpeedup);
1088
+	S9xAPUAllowTimeOverflow(Timings.APUAllowTimeOverflow);
4240 1089
 
4241
-			if (ret)
4242
-			{
4243
-				printf("!\n");
4244
-				flag = true;
4245
-			}
4246
-			else
4247
-			{
4248
-				printf(" failed!\n");
4249
-				break;
4250
-			}
4251
-		} while (++i < 1000);
1090
+	//// Other timing hacks :(
4252 1091
 
4253
-		if (flag)
4254
-			return;
4255
-	}
1092
+	Timings.HDMAStart = SNES_HDMA_START_HC + Settings.HDMATimingHack - 100;
1093
+	Timings.HBlankStart = SNES_HBLANK_START_HC + Timings.HDMAStart - SNES_HDMA_START_HC;
1094
+	Timings.IRQTriggerCycles = 10;
4256 1095
 
4257
-	if (_MAX_EXT > 3)
1096
+	if (!Settings.DisableGameSpecificHacks)
4258 1097
 	{
4259
-		i = 0;
4260
-		flag = false;
4261
-
4262
-		do
4263
-		{
4264
-			snprintf(ips, _MAX_EXT + 3, ".ips%d", i);
4265
-			if (strlen(ips) > _MAX_EXT + 1)
4266
-				break;
4267
-			n = S9xGetFilename(ips, IPS_DIR);
4268
-
4269
-			if (!(patch_file = OPEN_STREAM(n, "rb")))
4270
-				break;
4271
-
4272
-			printf("Using IPS patch %s", n);
4273
-
4274
-			ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size);
4275
-			CLOSE_STREAM(patch_file);
1098
+		// The delay to sync CPU and DMA which Snes9x cannot emulate.
1099
+		// Some games need really severe delay timing...
1100
+		if (this->match_na("BATTLE GRANDPRIX")) // Battle Grandprix
1101
+			Timings.DMACPUSync = 20;
4276 1102
 
4277
-			if (ret)
4278
-			{
4279
-				printf("!\n");
4280
-				flag = true;
4281
-			}
4282
-			else
4283
-			{
4284
-				printf(" failed!\n");
4285
-				break;
4286
-			}
4287
-		} while (++i != 0);
1103
+		// An infinite loop reads $4212 and waits V-blank end, whereas VIRQ is set V=0.
1104
+		// If Snes9x succeeds to escape from the loop before jumping into the IRQ handler, the game goes further.
1105
+		// If Snes9x jumps into the IRQ handler before escaping from the loop,
1106
+		// Snes9x cannot escape from the loop permanently because the RTI is in the next V-blank.
1107
+		if (this->match_na("Aero the AcroBat 2"))
1108
+			Timings.IRQPendCount = 2;
4288 1109
 
4289
-		if (flag)
4290
-			return;
4291
-	}
1110
+		// XXX: What's happening?
1111
+		if (this->match_na("X-MEN")) // Spider-Man and the X-Men
1112
+			Settings.BlockInvalidVRAMAccess = false;
4292 1113
 
4293
-	if (_MAX_EXT > 2)
4294
-	{
4295
-		i = 0;
4296
-		flag = false;
1114
+		//// SRAM initial value
4297 1115
 
4298
-		do
1116
+		if (this->match_na("HITOMI3"))
4299 1117
 		{
4300
-			snprintf(ips, 5, ".ip%d", i);
4301
-			n = S9xGetFilename(ips, IPS_DIR);
1118
+			SRAMSize = 1;
1119
+			SRAMMask = ((1 << (SRAMSize + 3)) * 128) - 1;
1120
+		}
4302 1121
 
4303
-			if (!(patch_file = OPEN_STREAM(n, "rb")))
4304
-				break;
1122
+		// SRAM value fixes
1123
+		if (this->match_na("SUPER DRIFT OUT") || // Super Drift Out
1124
+			this->match_na("SATAN IS OUR FATHER!") ||
1125
+			this->match_na("goemon 4")) // Ganbare Goemon Kirakira Douchuu
1126
+			SNESGameFixes.SRAMInitialValue = 0x00;
4305 1127
 
4306
-			printf("Using IPS patch %s", n);
1128
+		// Additional game fixes by sanmaiwashi ...
1129
+		// XXX: unnecessary?
1130
+		if (this->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
1131
+			SNESGameFixes.SRAMInitialValue = 0x6b;
4307 1132
 
4308
-			ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size);
4309
-			CLOSE_STREAM(patch_file);
1133
+		// others: BS and ST-01x games are 0x00.
4310 1134
 
4311
-			if (ret)
4312
-			{
4313
-				printf("!\n");
4314
-				flag = true;
4315
-			}
4316
-			else
4317
-			{
4318
-				printf(" failed!\n");
4319
-				break;
4320
-			}
4321
-		} while (++i < 10);
1135
+		//// OAM hacks :(
4322 1136
 
4323
-		if (flag)
4324
-			return;
1137
+		// OAM hacks because we don't fully understand the behavior of the SNES.
1138
+		// Totally wacky display in 2P mode...
1139
+		// seems to need a disproven behavior, so we're definitely overlooking some other bug?
1140
+		if (match_nn("UNIRACERS")) // Uniracers
1141
+			SNESGameFixes.Uniracers = true;
4325 1142
 	}
4326
-}*/
1143
+}
Browse code

Cleanup of some warnings, updating modification dates, using nullptr instead of NULL in some cases.

Naram Qashat authored on 2013/03/30 16:17:42
Showing 1 changed files
... ...
@@ -2506,8 +2506,8 @@ void CMemory::InitROM()
2506 2506
 
2507 2507
 	Checksum_Calculate();
2508 2508
 
2509
-	bool isChecksumOK = (ROMChecksum + ROMComplementChecksum == 0xffff) &
2510
-						 (ROMChecksum == CalculatedChecksum);
2509
+	/*bool isChecksumOK = (ROMChecksum + ROMComplementChecksum == 0xffff) &
2510
+						 (ROMChecksum == CalculatedChecksum);*/
2511 2511
 
2512 2512
 	//// Build more ROM information
2513 2513
 
Browse code

Import actual code.

Naram Qashat authored on 2013/03/26 02:41:19
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,4326 @@
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
+
21
+  (c) Copyright 2002 - 2011  zones (kasumitokoduck@yahoo.com)
22
+
23
+  (c) Copyright 2006 - 2007  nitsuja
24
+
25
+  (c) Copyright 2009 - 2011  BearOso,
26
+                             OV2
27
+
28
+
29
+  BS-X C emulator code
30
+  (c) Copyright 2005 - 2006  Dreamer Nom,
31
+                             zones
32
+
33
+  C4 x86 assembler and some C emulation code
34
+  (c) Copyright 2000 - 2003  _Demo_ (_demo_@zsnes.com),
35
+                             Nach,
36
+                             zsKnight (zsknight@zsnes.com)
37
+
38
+  C4 C++ code
39
+  (c) Copyright 2003 - 2006  Brad Jorsch,
40
+                             Nach
41
+
42
+  DSP-1 emulator code
43
+  (c) Copyright 1998 - 2006  _Demo_,
44
+                             Andreas Naive (andreasnaive@gmail.com),
45
+                             Gary Henderson,
46
+                             Ivar (ivar@snes9x.com),
47
+                             John Weidman,
48
+                             Kris Bleakley,
49
+                             Matthew Kendora,
50
+                             Nach,
51
+                             neviksti (neviksti@hotmail.com)
52
+
53
+  DSP-2 emulator code
54
+  (c) Copyright 2003         John Weidman,
55
+                             Kris Bleakley,
56
+                             Lord Nightmare (lord_nightmare@users.sourceforge.net),
57
+                             Matthew Kendora,
58
+                             neviksti
59
+
60
+  DSP-3 emulator code
61
+  (c) Copyright 2003 - 2006  John Weidman,
62
+                             Kris Bleakley,
63
+                             Lancer,
64
+                             z80 gaiden
65
+
66
+  DSP-4 emulator code
67
+  (c) Copyright 2004 - 2006  Dreamer Nom,
68
+                             John Weidman,
69
+                             Kris Bleakley,
70
+                             Nach,
71
+                             z80 gaiden
72
+
73
+  OBC1 emulator code
74
+  (c) Copyright 2001 - 2004  zsKnight,
75
+                             pagefault (pagefault@zsnes.com),
76
+                             Kris Bleakley
77
+                             Ported from x86 assembler to C by sanmaiwashi
78
+
79
+  SPC7110 and RTC C++ emulator code used in 1.39-1.51
80
+  (c) Copyright 2002         Matthew Kendora with research by
81
+                             zsKnight,
82
+                             John Weidman,
83
+                             Dark Force
84
+
85
+  SPC7110 and RTC C++ emulator code used in 1.52+
86
+  (c) Copyright 2009         byuu,
87
+                             neviksti
88
+
89
+  S-DD1 C emulator code
90
+  (c) Copyright 2003         Brad Jorsch with research by
91
+                             Andreas Naive,
92
+                             John Weidman
93
+
94
+  S-RTC C emulator code
95
+  (c) Copyright 2001 - 2006  byuu,
96
+                             John Weidman
97
+
98
+  ST010 C++ emulator code
99
+  (c) Copyright 2003         Feather,
100
+                             John Weidman,
101
+                             Kris Bleakley,
102
+                             Matthew Kendora
103
+
104
+  Super FX x86 assembler emulator code
105
+  (c) Copyright 1998 - 2003  _Demo_,
106
+                             pagefault,
107
+                             zsKnight
108
+
109
+  Super FX C emulator code
110
+  (c) Copyright 1997 - 1999  Ivar,
111
+                             Gary Henderson,
112
+                             John Weidman
113
+
114
+  Sound emulator code used in 1.5-1.51
115
+  (c) Copyright 1998 - 2003  Brad Martin
116
+  (c) Copyright 1998 - 2006  Charles Bilyue'
117
+
118
+  Sound emulator code used in 1.52+
119
+  (c) Copyright 2004 - 2007  Shay Green (gblargg@gmail.com)
120
+
121
+  SH assembler code partly based on x86 assembler code
122
+  (c) Copyright 2002 - 2004  Marcus Comstedt (marcus@mc.pp.se)
123
+
124
+  2xSaI filter
125
+  (c) Copyright 1999 - 2001  Derek Liauw Kie Fa
126
+
127
+  HQ2x, HQ3x, HQ4x filters
128
+  (c) Copyright 2003         Maxim Stepin (maxim@hiend3d.com)
129
+
130
+  NTSC filter
131
+  (c) Copyright 2006 - 2007  Shay Green
132
+
133
+  GTK+ GUI code
134
+  (c) Copyright 2004 - 2011  BearOso
135
+
136
+  Win32 GUI code
137
+  (c) Copyright 2003 - 2006  blip,
138
+                             funkyass,
139
+                             Matthew Kendora,
140
+                             Nach,
141
+                             nitsuja
142
+  (c) Copyright 2009 - 2011  OV2
143
+
144
+  Mac OS GUI code
145
+  (c) Copyright 1998 - 2001  John Stiles
146
+  (c) Copyright 2001 - 2011  zones
147
+
148
+
149
+  Specific ports contains the works of other authors. See headers in
150
+  individual files.
151
+
152
+
153
+  Snes9x homepage: http://www.snes9x.com/
154
+
155
+  Permission to use, copy, modify and/or distribute Snes9x in both binary
156
+  and source form, for non-commercial purposes, is hereby granted without
157
+  fee, providing that this license information and copyright notice appear
158
+  with all copies and any derived work.
159
+
160
+  This software is provided 'as-is', without any express or implied
161
+  warranty. In no event shall the authors be held liable for any damages
162
+  arising from the use of this software or it's derivatives.
163
+
164
+  Snes9x is freeware for PERSONAL USE only. Commercial users should
165
+  seek permission of the copyright holders first. Commercial use includes,
166
+  but is not limited to, charging money for Snes9x or software derived from
167
+  Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
168
+  using Snes9x as a promotion for your commercial product.
169
+
170
+  The copyright holders request that bug fixes and improvements to the code
171
+  should be forwarded to them so everyone can benefit from the modifications
172
+  in future versions.
173
+
174
+  Super NES and Super Nintendo Entertainment System are trademarks of
175
+  Nintendo Co., Limited and its subsidiary companies.
176
+ ***********************************************************************************/
177
+
178
+#include <algorithm>
179
+#include <string>
180
+#include <numeric>
181
+#include <assert.h>
182
+
183
+#ifdef UNZIP_SUPPORT
184
+#include "unzip/unzip.h"
185
+#endif
186
+
187
+#ifdef JMA_SUPPORT
188
+#include "jma/s9x-jma.h"
189
+#endif
190
+
191
+#include "snes9x.h"
192
+#include "memmap.h"
193
+#include "apu/apu.h"
194
+//#include "fxemu.h"
195
+#include "sdd1.h"
196
+//#include "srtc.h"
197
+//#include "controls.h"
198
+//#include "cheats.h"
199
+//#include "movie.h"
200
+//#include "reader.h"
201
+//#include "display.h"
202
+
203
+/*#ifndef SET_UI_COLOR
204
+#define SET_UI_COLOR(r, g, b) ;
205
+#endif*/
206
+
207
+/*#ifndef max
208
+#define max(a, b) (((a) > (b)) ? (a) : (b))
209
+#endif*/
210
+
211
+/*#ifndef min
212
+#define min(a, b) (((a) < (b)) ? (a) : (b))
213
+#endif*/
214
+
215
+//static bool	stopMovie = true;
216
+//static char		LastRomFilename[PATH_MAX + 1] = "";
217
+
218
+// from NSRT
219
+/*static const char	*nintendo_licensees[] =
220
+{
221
+	"Unlicensed",
222
+	"Nintendo",
223
+	"Rocket Games/Ajinomoto",
224
+	"Imagineer-Zoom",
225
+	"Gray Matter",
226
+	"Zamuse",
227
+	"Falcom",
228
+	NULL,
229
+	"Capcom",
230
+	"Hot B Co.",
231
+	"Jaleco",
232
+	"Coconuts Japan",
233
+	"Coconuts Japan/G.X.Media",
234
+	"Micronet",
235
+	"Technos",
236
+	"Mebio Software",
237
+	"Shouei System",
238
+	"Starfish",
239
+	NULL,
240
+	"Mitsui Fudosan/Dentsu",
241
+	NULL,
242
+	"Warashi Inc.",
243
+	NULL,
244
+	"Nowpro",
245
+	NULL,
246
+	"Game Village",
247
+	"IE Institute",
248
+	NULL,
249
+	NULL,
250
+	NULL,
251
+	NULL,
252
+	NULL,
253
+	NULL,
254
+	NULL,
255
+	NULL,
256
+	NULL,
257
+	"Banarex",
258
+	"Starfish",
259
+	"Infocom",
260
+	"Electronic Arts Japan",
261
+	NULL,
262
+	"Cobra Team",
263
+	"Human/Field",
264
+	"KOEI",
265
+	"Hudson Soft",
266
+	"S.C.P./Game Village",
267
+	"Yanoman",
268
+	NULL,
269
+	"Tecmo Products",
270
+	"Japan Glary Business",
271
+	"Forum/OpenSystem",
272
+	"Virgin Games (Japan)",
273
+	"SMDE",
274
+	"Yojigen",
275
+	NULL,
276
+	"Daikokudenki",
277
+	NULL,
278
+	NULL,
279
+	NULL,
280
+	NULL,
281
+	NULL,
282
+	"Creatures Inc.",
283
+	"TDK Deep Impresion",
284
+	NULL,
285
+	NULL,
286
+	NULL,
287
+	NULL,
288
+	NULL,
289
+	NULL,
290
+	NULL,
291
+	NULL,
292
+	NULL,
293
+	"Destination Software/KSS",
294
+	"Sunsoft/Tokai Engineering",
295
+	"POW (Planning Office Wada)/VR 1 Japan",
296
+	"Micro World",
297
+	NULL,
298
+	"San-X",
299
+	"Enix",
300
+	"Loriciel/Electro Brain",
301
+	"Kemco Japan",
302
+	"Seta Co.,Ltd.",
303
+	"Culture Brain",
304
+	"Irem Corp.",
305
+	"Palsoft",
306
+	"Visit Co., Ltd.",
307
+	"Intec",
308
+	"System Sacom",
309
+	"Poppo",
310
+	"Ubisoft Japan",
311
+	NULL,
312
+	"Media Works",
313
+	"NEC InterChannel",
314
+	"Tam",
315
+	"Gajin/Jordan",
316
+	"Smilesoft",
317
+	NULL,
318
+	NULL,
319
+	"Mediakite",
320
+	NULL,
321
+	NULL,
322
+	NULL,
323
+	NULL,
324
+	NULL,
325
+	NULL,
326
+	NULL,
327
+	NULL,
328
+	NULL,
329
+	"Viacom",
330
+	"Carrozzeria",
331
+	"Dynamic",
332
+	NULL,
333
+	"Magifact",
334
+	"Hect",
335
+	"Codemasters",
336
+	"Taito/GAGA Communications",
337
+	"Laguna",
338
+	"Telstar Fun & Games/Event/Taito",
339
+	NULL,
340
+	"Arcade Zone Ltd.",
341
+	"Entertainment International/Empire Software",
342
+	"Loriciel",
343
+	"Gremlin Graphics",
344
+	NULL,
345
+	NULL,
346
+	NULL,
347
+	NULL,
348
+	NULL,
349
+	NULL,
350
+	NULL,
351
+	NULL,
352
+	NULL,
353
+	NULL,
354
+	NULL,
355
+	NULL,
356
+	NULL,
357
+	NULL,
358
+	NULL,
359
+	NULL,
360
+	NULL,
361
+	NULL,
362
+	NULL,
363
+	NULL,
364
+	NULL,
365
+	"Seika Corp.",
366
+	"UBI SOFT Entertainment Software",
367
+	"Sunsoft US",
368
+	NULL,
369
+	"Life Fitness",
370
+	NULL,
371
+	"System 3",
372
+	"Spectrum Holobyte",
373
+	NULL,
374
+	"Irem",
375
+	NULL,
376
+	"Raya Systems",
377
+	"Renovation Products",
378
+	"Malibu Games",
379
+	NULL,
380
+	"Eidos/U.S. Gold",
381
+	"Playmates Interactive",
382
+	NULL,
383
+	NULL,
384
+	"Fox Interactive",
385
+	"Time Warner Interactive",
386
+	NULL,
387
+	NULL,
388
+	NULL,
389
+	NULL,
390
+	NULL,
391
+	"Disney Interactive",
392
+	NULL,
393
+	"Black Pearl",
394
+	NULL,
395
+	"Advanced Productions",
396
+	NULL,
397
+	NULL,
398
+	"GT Interactive",
399
+	"RARE",
400
+	"Crave Entertainment",
401
+	"Absolute Entertainment",
402
+	"Acclaim",
403
+	"Activision",
404
+	"American Sammy",
405
+	"Take 2/GameTek",
406
+	"Hi Tech",
407
+	"LJN Ltd.",
408
+	NULL,
409
+	"Mattel",
410
+	NULL,
411
+	"Mindscape/Red Orb Entertainment",
412
+	"Romstar",
413
+	"Taxan",
414
+	"Midway/Tradewest",
415
+	NULL,
416
+	"American Softworks Corp.",
417
+	"Majesco Sales Inc.",
418
+	"3DO",
419
+	NULL,
420
+	NULL,
421
+	"Hasbro",
422
+	"NewKidCo",
423
+	"Telegames",
424
+	"Metro3D",
425
+	NULL,
426
+	"Vatical Entertainment",
427
+	"LEGO Media",
428
+	NULL,
429
+	"Xicat Interactive",
430
+	"Cryo Interactive",
431
+	NULL,
432
+	NULL,
433
+	"Red Storm Entertainment",
434
+	"Microids",
435
+	NULL,
436
+	"Conspiracy/Swing",
437
+	"Titus",
438
+	"Virgin Interactive",
439
+	"Maxis",
440
+	NULL,
441
+	"LucasArts Entertainment",
442
+	NULL,
443
+	NULL,
444
+	"Ocean",
445
+	NULL,
446
+	"Electronic Arts",
447
+	NULL,
448
+	"Laser Beam",
449
+	NULL,
450
+	NULL,
451
+	"Elite Systems",
452
+	"Electro Brain",
453
+	"The Learning Company",
454
+	"BBC",
455
+	NULL,
456
+	"Software 2000",
457
+	NULL,
458
+	"BAM! Entertainment",
459
+	"Studio 3",
460
+	NULL,
461
+	NULL,
462
+	NULL,
463
+	"Classified Games",
464
+	NULL,
465
+	"TDK Mediactive",
466
+	NULL,
467
+	"DreamCatcher",
468
+	"JoWood Produtions",
469
+	"SEGA",
470
+	"Wannado Edition",
471
+	"LSP (Light & Shadow Prod.)",
472
+	"ITE Media",
473
+	"Infogrames",
474
+	"Interplay",
475
+	"JVC (US)",
476
+	"Parker Brothers",
477
+	NULL,
478
+	"SCI (Sales Curve Interactive)/Storm",
479
+	NULL,
480
+	NULL,
481
+	"THQ Software",
482
+	"Accolade Inc.",
483
+	"Triffix Entertainment",
484
+	NULL,
485
+	"Microprose Software",
486
+	"Universal Interactive/Sierra/Simon & Schuster",
487
+	NULL,
488
+	"Kemco",
489
+	"Rage Software",
490
+	"Encore",
491
+	NULL,
492
+	"Zoo",
493
+	"Kiddinx",
494
+	"Simon & Schuster Interactive",
495
+	"Asmik Ace Entertainment Inc./AIA",
496
+	"Empire Interactive",
497
+	NULL,
498
+	NULL,
499
+	"Jester Interactive",
500
+	NULL,
501
+	"Rockstar Games",
502
+	"Scholastic",
503
+	"Ignition Entertainment",
504
+	"Summitsoft",
505
+	"Stadlbauer",
506
+	NULL,
507
+	NULL,
508
+	NULL,
509
+	"Misawa",
510
+	"Teichiku",
511
+	"Namco Ltd.",
512
+	"LOZC",
513
+	"KOEI",
514
+	NULL,
515
+	"Tokuma Shoten Intermedia",
516
+	"Tsukuda Original",
517
+	"DATAM-Polystar",
518
+	NULL,
519
+	NULL,
520
+	"Bullet-Proof Software",
521
+	"Vic Tokai Inc.",
522
+	NULL,
523
+	"Character Soft",
524
+	"I'Max",
525
+	"Saurus",
526
+	NULL,
527
+	NULL,
528
+	"General Entertainment",
529
+	NULL,
530
+	NULL,
531
+	"I'Max",
532
+	"Success",
533
+	NULL,
534
+	"SEGA Japan",
535
+	NULL,
536
+	NULL,
537
+	NULL,
538
+	NULL,
539
+	NULL,
540
+	NULL,
541
+	NULL,
542
+	NULL,
543
+	NULL,
544
+	NULL,
545
+	"Takara",
546
+	"Chun Soft",
547
+	"Video System Co., Ltd./McO'River",
548
+	"BEC",
549
+	NULL,
550
+	"Varie",
551
+	"Yonezawa/S'pal",
552
+	"Kaneko",
553
+	NULL,
554
+	"Victor Interactive Software/Pack-in-Video",
555
+	"Nichibutsu/Nihon Bussan",
556
+	"Tecmo",
557
+	"Imagineer",
558
+	NULL,
559
+	NULL,
560
+	"Nova",
561
+	"Den'Z",
562
+	"Bottom Up",
563
+	NULL,
564
+	"TGL (Technical Group Laboratory)",
565
+	NULL,
566
+	"Hasbro Japan",
567
+	NULL,
568
+	"Marvelous Entertainment",
569
+	NULL,
570
+	"Keynet Inc.",
571
+	"Hands-On Entertainment",
572
+	NULL,
573
+	NULL,
574
+	NULL,
575
+	NULL,
576
+	NULL,
577
+	NULL,
578
+	NULL,
579
+	NULL,
580
+	NULL,
581
+	"Telenet",
582
+	"Hori",
583
+	NULL,
584
+	NULL,
585
+	"Konami",
586
+	"K.Amusement Leasing Co.",
587
+	"Kawada",
588
+	"Takara",
589
+	NULL,
590
+	"Technos Japan Corp.",
591
+	"JVC (Europe/Japan)/Victor Musical Industries",
592
+	NULL,
593
+	"Toei Animation",
594
+	"Toho",
595
+	NULL,
596
+	"Namco",
597
+	"Media Rings Corp.",
598
+	"J-Wing",
599
+	NULL,
600
+	"Pioneer LDC",
601
+	"KID",
602
+	"Mediafactory",
603
+	NULL,
604
+	NULL,
605
+	NULL,
606
+	"Infogrames Hudson",
607
+	NULL,
608
+	NULL,
609
+	NULL,
610
+	NULL,
611
+	NULL,
612
+	NULL,
613
+	NULL,
614
+	NULL,
615
+	NULL,
616
+	NULL,
617
+	"Acclaim Japan",
618
+	"ASCII Co./Nexoft",
619
+	"Bandai",
620
+	NULL,
621
+	"Enix",
622
+	NULL,
623
+	"HAL Laboratory/Halken",
624
+	"SNK",
625
+	NULL,
626
+	"Pony Canyon Hanbai",
627
+	"Culture Brain",
628
+	"Sunsoft",
629
+	"Toshiba EMI",
630
+	"Sony Imagesoft",
631
+	NULL,
632
+	"Sammy",
633
+	"Magical",
634
+	"Visco",
635
+	NULL,
636
+	"Compile",
637
+	NULL,
638
+	"MTO Inc.",
639
+	NULL,
640
+	"Sunrise Interactive",
641
+	NULL,
642
+	"Global A Entertainment",
643
+	"Fuuki",
644
+	NULL,
645
+	NULL,
646
+	NULL,
647
+	NULL,
648
+	NULL,
649
+	NULL,
650
+	NULL,
651
+	NULL,
652
+	NULL,
653
+	"Taito",
654
+	NULL,
655
+	"Kemco",
656
+	"Square",
657
+	"Tokuma Shoten",
658
+	"Data East",
659
+	"Tonkin House",
660
+	NULL,
661
+	"KOEI",
662
+	NULL,
663
+	"Konami/Ultra/Palcom",
664
+	"NTVIC/VAP",
665
+	"Use Co., Ltd.",
666
+	"Meldac",
667
+	"Pony Canyon (Japan)/FCI (US)",
668
+	"Angel/Sotsu Agency/Sunrise",
669
+	"Yumedia/Aroma Co., Ltd.",
670
+	NULL,
671
+	NULL,
672
+	"Boss",
673
+	"Axela/Crea-Tech",
674
+	"Sekaibunka-Sha/Sumire kobo/Marigul Management Inc.",
675
+	"Konami Computer Entertainment Osaka",
676
+	NULL,
677
+	NULL,
678
+	"Enterbrain",
679
+	NULL,
680
+	NULL,
681
+	NULL,
682
+	NULL,
683
+	NULL,
684
+	NULL,
685
+	NULL,
686
+	NULL,
687
+	NULL,
688
+	NULL,
689
+	"Taito/Disco",
690
+	"Sofel",
691
+	"Quest Corp.",
692
+	"Sigma",
693
+	"Ask Kodansha",
694
+	NULL,
695
+	"Naxat",
696
+	"Copya System",
697
+	"Capcom Co., Ltd.",
698
+	"Banpresto",
699
+	"TOMY",
700
+	"Acclaim/LJN Japan",
701
+	NULL,
702
+	"NCS",
703
+	"Human Entertainment",
704
+	"Altron",
705
+	"Jaleco",
706
+	"Gaps Inc.",
707
+	NULL,
708
+	NULL,
709
+	NULL,
710
+	NULL,
711
+	NULL,
712
+	"Elf",
713
+	NULL,
714
+	NULL,
715
+	NULL,
716
+	NULL,
717
+	NULL,
718
+	NULL,
719
+	NULL,
720
+	NULL,
721
+	NULL,
722
+	NULL,
723
+	NULL,
724
+	NULL,
725
+	"Jaleco",
726
+	NULL,
727
+	"Yutaka",
728
+	"Varie",
729
+	"T&ESoft",
730
+	"Epoch Co., Ltd.",
731
+	NULL,
732
+	"Athena",
733
+	"Asmik",
734
+	"Natsume",
735
+	"King Records",
736
+	"Atlus",
737
+	"Epic/Sony Records (Japan)",
738
+	NULL,
739
+	"IGS (Information Global Service)",
740
+	NULL,
741
+	"Chatnoir",
742
+	"Right Stuff",
743
+	NULL,
744
+	"NTT COMWARE",
745
+	NULL,
746
+	"Spike",
747
+	"Konami Computer Entertainment Tokyo",
748
+	"Alphadream Corp.",
749
+	NULL,
750
+	"Sting",
751
+	NULL,
752
+	NULL,
753
+	NULL,
754
+	NULL,
755
+	NULL,
756
+	NULL,
757
+	NULL,
758
+	NULL,
759
+	NULL,
760
+	NULL,
761
+	"A Wave",
762
+	"Motown Software",
763
+	"Left Field Entertainment",
764
+	"Extreme Entertainment Group",
765
+	"TecMagik",
766
+	NULL,
767
+	NULL,
768
+	NULL,
769
+	NULL,
770
+	"Cybersoft",
771
+	NULL,
772
+	"Psygnosis",
773
+	NULL,
774
+	NULL,
775
+	"Davidson/Western Tech.",
776
+	"Unlicensed",
777
+	NULL,
778
+	NULL,
779
+	NULL,
780
+	NULL,
781
+	"The Game Factory Europe",
782
+	"Hip Games",
783
+	"Aspyr",
784
+	NULL,
785
+	NULL,
786
+	"Mastiff",
787
+	"iQue",
788
+	"Digital Tainment Pool",
789
+	"XS Games",
790
+	"Daiwon",
791
+	NULL,
792
+	NULL,
793
+	NULL,
794
+	NULL,
795
+	NULL,
796
+	NULL,
797
+	NULL,
798
+	"PCCW Japan",
799
+	NULL,
800
+	NULL,
801
+	"KiKi Co. Ltd.",
802
+	"Open Sesame Inc.",
803
+	"Sims",
804
+	"Broccoli",
805
+	"Avex",
806
+	"D3 Publisher",
807
+	NULL,
808
+	"Konami Computer Entertainment Japan",
809
+	NULL,
810
+	"Square-Enix",
811
+	"KSG",
812
+	"Micott & Basara Inc.",
813
+	NULL,
814
+	"Orbital Media",
815
+	NULL,
816
+	NULL,
817
+	NULL,
818
+	NULL,
819
+	NULL,
820
+	NULL,
821
+	NULL,
822
+	NULL,
823
+	NULL,
824
+	NULL,
825
+	NULL,
826
+	NULL,
827
+	NULL,
828
+	NULL,
829
+	NULL,
830
+	NULL,
831
+	"The Game Factory USA",
832
+	NULL,
833
+	NULL,
834
+	"Treasure",
835
+	"Aruze",
836
+	"Ertain",
837
+	"SNK Playmore",
838
+	NULL,
839
+	NULL,
840
+	NULL,
841
+	NULL,
842
+	NULL,
843
+	NULL,
844
+	NULL,
845
+	NULL,
846
+	NULL,
847
+	NULL,
848
+	NULL,
849
+	NULL,
850
+	NULL,
851
+	NULL,
852
+	NULL,
853
+	NULL,
854
+	NULL,
855
+	NULL,
856
+	NULL,
857
+	NULL,
858
+	NULL,
859
+	NULL,
860
+	NULL,
861
+	NULL,
862
+	NULL,
863
+	NULL,
864
+	NULL,
865
+	NULL,
866
+	NULL,
867
+	NULL,
868
+	NULL,
869
+	NULL,
870
+	NULL,
871
+	NULL,
872
+	NULL,
873
+	NULL,
874
+	NULL,
875
+	NULL,
876
+	NULL,
877
+	NULL,
878
+	NULL,
879
+	NULL,
880
+	NULL,
881
+	NULL,
882
+	NULL,
883
+	NULL,
884
+	NULL,
885
+	NULL,
886
+	"Yojigen"
887
+};*/
888
+
889
+static const uint32_t	crc32Table[256] =
890
+{
891
+	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
892
+	0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
893
+	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
894
+	0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
895
+	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
896
+	0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
897
+	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
898
+	0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
899
+	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
900
+	0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
901
+	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
902
+	0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
903
+	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
904
+	0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
905
+	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
906
+	0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
907
+	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
908
+	0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
909
+	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
910
+	0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
911
+	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
912
+	0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
913
+	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
914
+	0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
915
+	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
916
+	0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
917
+	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
918
+	0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
919
+	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
920
+	0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
921
+	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
922
+	0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
923
+	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
924
+	0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
925
+	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
926
+	0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
927
+	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
928
+	0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
929
+	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
930
+	0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
931
+	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
932
+	0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
933
+	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
934
+};
935
+
936
+//static void S9xDeinterleaveType1 (int, uint8_t *);
937
+//static void S9xDeinterleaveType2 (int, uint8_t *);
938
+//static void S9xDeinterleaveGD24 (int, uint8_t *);
939
+//static bool allASCII (uint8_t *, int);
940
+//static bool is_SufamiTurbo_BIOS (uint8_t *, uint32_t);
941
+//static bool is_SufamiTurbo_Cart (uint8_t *, uint32_t);
942
+//static bool is_SameGame_BIOS (uint8_t *, uint32_t);
943
+//static bool is_SameGame_Add_On (uint8_t *, uint32_t);
944
+//static uint32_t caCRC32 (uint8_t *, uint32_t, uint32_t crc32 = 0xffffffff);
945
+/*static uint32_t ReadUPSPointer (const uint8_t *, unsigned &, unsigned);
946
+static bool ReadUPSPatch (Reader *, long, int32_t &);
947
+static long ReadInt (Reader *, unsigned);
948
+static bool ReadIPSPatch (Reader *, long, int32_t &);*/
949
+#ifdef UNZIP_SUPPORT
950
+static int unzFindExtension (unzFile &, const char *, bool restart = true, bool print = true);
951
+#endif
952
+
953
+// deinterleave
954
+
955
+static void S9xDeinterleaveType1 (int size, uint8_t *base)
956
+{
957
+	//Settings.DisplayColor = BUILD_PIXEL(0, 31, 0);
958
+	//SET_UI_COLOR(0, 255, 0);
959
+
960
+	uint8_t	blocks[256];
961
+	int		nblocks = size >> 16;
962
+
963
+	for (int i = 0; i < nblocks; i++)
964
+	{
965
+		blocks[i * 2] = i + nblocks;
966
+		blocks[i * 2 + 1] = i;
967
+	}
968
+
969
+	uint8_t	*tmp = (uint8_t *) malloc(0x8000);
970
+	if (tmp)
971
+	{
972
+		for (int i = 0; i < nblocks * 2; i++)
973
+		{
974
+			for (int j = i; j < nblocks * 2; j++)
975
+			{
976
+				if (blocks[j] == i)
977
+				{
978
+					memmove(tmp, &base[blocks[j] * 0x8000], 0x8000);
979
+					memmove(&base[blocks[j] * 0x8000], &base[blocks[i] * 0x8000], 0x8000);
980
+					memmove(&base[blocks[i] * 0x8000], tmp, 0x8000);
981
+					uint8_t	b = blocks[j];
982
+					blocks[j] = blocks[i];
983
+					blocks[i] = b;
984
+					break;
985
+				}
986
+			}
987
+		}
988
+
989
+		free(tmp);
990
+	}
991
+}
992
+
993
+static void S9xDeinterleaveType2 (int size, uint8_t *base)
994
+{
995
+	// for odd Super FX images
996
+	//Settings.DisplayColor = BUILD_PIXEL(31, 14, 6);
997
+	//SET_UI_COLOR(255, 119, 25);
998
+
999
+	uint8_t	blocks[256];
1000
+	int		nblocks = size >> 16;
1001
+	int		step = 64;
1002
+
1003
+	while (nblocks <= step)
1004
+		step >>= 1;
1005
+	nblocks = step;
1006
+
1007
+	for (int i = 0; i < nblocks * 2; i++)
1008
+		blocks[i] = (i & ~0xf) | ((i & 3) << 2) | ((i & 12) >> 2);
1009
+
1010
+	uint8_t	*tmp = (uint8_t *) malloc(0x10000);
1011
+	if (tmp)
1012
+	{
1013
+		for (int i = 0; i < nblocks * 2; i++)
1014
+		{
1015
+			for (int j = i; j < nblocks * 2; j++)
1016
+			{
1017
+				if (blocks[j] == i)
1018
+				{
1019
+					memmove(tmp, &base[blocks[j] * 0x10000], 0x10000);
1020
+					memmove(&base[blocks[j] * 0x10000], &base[blocks[i] * 0x10000], 0x10000);
1021
+					memmove(&base[blocks[i] * 0x10000], tmp, 0x10000);
1022
+					uint8_t	b = blocks[j];
1023
+					blocks[j] = blocks[i];
1024
+					blocks[i] = b;
1025
+					break;
1026
+				}
1027
+			}
1028
+		}
1029
+
1030
+		free(tmp);
1031
+	}
1032
+}
1033
+
1034
+static void S9xDeinterleaveGD24 (int size, uint8_t *base)
1035
+{
1036
+	// for 24Mb images dumped with Game Doctor
1037
+	if (size != 0x300000)
1038
+		return;
1039
+
1040
+	//Settings.DisplayColor = BUILD_PIXEL(0, 31, 31);
1041
+	//SET_UI_COLOR(0, 255, 255);
1042
+
1043
+	uint8_t	*tmp = (uint8_t *) malloc(0x80000);
1044
+	if (tmp)
1045
+	{
1046
+		memmove(tmp, &base[0x180000], 0x80000);
1047
+		memmove(&base[0x180000], &base[0x200000], 0x80000);
1048
+		memmove(&base[0x200000], &base[0x280000], 0x80000);
1049
+		memmove(&base[0x280000], tmp, 0x80000);
1050
+
1051
+		free(tmp);
1052
+
1053
+		S9xDeinterleaveType1(size, base);
1054
+	}
1055
+}
1056
+
1057
+// allocation and deallocation
1058
+
1059
+bool CMemory::Init()
1060
+{
1061
+    RAM	 = (uint8_t *) malloc(0x20000);
1062
+    SRAM = (uint8_t *) malloc(0x20000);
1063
+    VRAM = (uint8_t *) malloc(0x10000);
1064
+    ROM  = (uint8_t *) malloc(MAX_ROM_SIZE + 0x200 + 0x8000);
1065
+
1066
+	IPPU.TileCache[TILE_2BIT]       = (uint8_t *) malloc(MAX_2BIT_TILES * 64);
1067
+	IPPU.TileCache[TILE_4BIT]       = (uint8_t *) malloc(MAX_4BIT_TILES * 64);
1068
+	IPPU.TileCache[TILE_8BIT]       = (uint8_t *) malloc(MAX_8BIT_TILES * 64);
1069
+	IPPU.TileCache[TILE_2BIT_EVEN]  = (uint8_t *) malloc(MAX_2BIT_TILES * 64);
1070
+	IPPU.TileCache[TILE_2BIT_ODD]   = (uint8_t *) malloc(MAX_2BIT_TILES * 64);
1071
+	IPPU.TileCache[TILE_4BIT_EVEN]  = (uint8_t *) malloc(MAX_4BIT_TILES * 64);
1072
+	IPPU.TileCache[TILE_4BIT_ODD]   = (uint8_t *) malloc(MAX_4BIT_TILES * 64);
1073
+
1074
+	IPPU.TileCached[TILE_2BIT]      = (uint8_t *) malloc(MAX_2BIT_TILES);
1075
+	IPPU.TileCached[TILE_4BIT]      = (uint8_t *) malloc(MAX_4BIT_TILES);
1076
+	IPPU.TileCached[TILE_8BIT]      = (uint8_t *) malloc(MAX_8BIT_TILES);
1077
+	IPPU.TileCached[TILE_2BIT_EVEN] = (uint8_t *) malloc(MAX_2BIT_TILES);
1078
+	IPPU.TileCached[TILE_2BIT_ODD]  = (uint8_t *) malloc(MAX_2BIT_TILES);
1079
+	IPPU.TileCached[TILE_4BIT_EVEN] = (uint8_t *) malloc(MAX_4BIT_TILES);
1080
+	IPPU.TileCached[TILE_4BIT_ODD]  = (uint8_t *) malloc(MAX_4BIT_TILES);
1081
+
1082
+	if (!RAM || !SRAM || !VRAM || !ROM ||
1083
+		!IPPU.TileCache[TILE_2BIT]       ||
1084
+		!IPPU.TileCache[TILE_4BIT]       ||
1085
+		!IPPU.TileCache[TILE_8BIT]       ||
1086
+		!IPPU.TileCache[TILE_2BIT_EVEN]  ||
1087
+		!IPPU.TileCache[TILE_2BIT_ODD]   ||
1088
+		!IPPU.TileCache[TILE_4BIT_EVEN]  ||
1089
+		!IPPU.TileCache[TILE_4BIT_ODD]   ||
1090
+		!IPPU.TileCached[TILE_2BIT]      ||
1091
+		!IPPU.TileCached[TILE_4BIT]      ||
1092
+		!IPPU.TileCached[TILE_8BIT]      ||
1093
+		!IPPU.TileCached[TILE_2BIT_EVEN] ||
1094
+		!IPPU.TileCached[TILE_2BIT_ODD]  ||
1095
+		!IPPU.TileCached[TILE_4BIT_EVEN] ||
1096
+		!IPPU.TileCached[TILE_4BIT_ODD])
1097
+    {
1098
+		Deinit();
1099
+		return false;
1100
+    }
1101
+
1102
+	ZeroMemory(RAM,  0x20000);
1103
+	ZeroMemory(SRAM, 0x20000);
1104
+	ZeroMemory(VRAM, 0x10000);
1105
+	ZeroMemory(ROM,  MAX_ROM_SIZE + 0x200 + 0x8000);
1106
+
1107
+	ZeroMemory(IPPU.TileCache[TILE_2BIT],       MAX_2BIT_TILES * 64);
1108
+	ZeroMemory(IPPU.TileCache[TILE_4BIT],       MAX_4BIT_TILES * 64);
1109
+	ZeroMemory(IPPU.TileCache[TILE_8BIT],       MAX_8BIT_TILES * 64);
1110
+	ZeroMemory(IPPU.TileCache[TILE_2BIT_EVEN],  MAX_2BIT_TILES * 64);
1111
+	ZeroMemory(IPPU.TileCache[TILE_2BIT_ODD],   MAX_2BIT_TILES * 64);
1112
+	ZeroMemory(IPPU.TileCache[TILE_4BIT_EVEN],  MAX_4BIT_TILES * 64);
1113
+	ZeroMemory(IPPU.TileCache[TILE_4BIT_ODD],   MAX_4BIT_TILES * 64);
1114
+
1115
+	ZeroMemory(IPPU.TileCached[TILE_2BIT],      MAX_2BIT_TILES);
1116
+	ZeroMemory(IPPU.TileCached[TILE_4BIT],      MAX_4BIT_TILES);
1117
+	ZeroMemory(IPPU.TileCached[TILE_8BIT],      MAX_8BIT_TILES);
1118
+	ZeroMemory(IPPU.TileCached[TILE_2BIT_EVEN], MAX_2BIT_TILES);
1119
+	ZeroMemory(IPPU.TileCached[TILE_2BIT_ODD],  MAX_2BIT_TILES);
1120
+	ZeroMemory(IPPU.TileCached[TILE_4BIT_EVEN], MAX_4BIT_TILES);
1121
+	ZeroMemory(IPPU.TileCached[TILE_4BIT_ODD],  MAX_4BIT_TILES);
1122
+
1123
+	// FillRAM uses first 32K of ROM image area, otherwise space just
1124
+	// wasted. Might be read by the SuperFX code.
1125
+
1126
+	FillRAM = ROM;
1127
+
1128
+	// Add 0x8000 to ROM image pointer to stop SuperFX code accessing
1129
+	// unallocated memory (can cause crash on some ports).
1130
+
1131
+	ROM += 0x8000;
1132
+
1133
+	C4RAM   = ROM + 0x400000 + 8192 * 8; // C4
1134
+	OBC1RAM = ROM + 0x400000; // OBC1
1135
+	BIOSROM = ROM + 0x300000; // BS
1136
+	BSRAM   = ROM + 0x400000; // BS
1137
+
1138
+	/*SuperFX.pvRegisters = FillRAM + 0x3000;
1139
+	SuperFX.nRamBanks   = 2; // Most only use 1.  1=64KB=512Mb, 2=128KB=1024Mb
1140
+	SuperFX.pvRam       = SRAM;
1141
+	SuperFX.nRomBanks   = (2 * 1024 * 1024) / (32 * 1024);
1142
+	SuperFX.pvRom       = (uint8_t *) ROM;*/
1143
+
1144
+	PostRomInitFunc = NULL;
1145
+
1146
+	return true;
1147
+}
1148
+
1149
+void CMemory::Deinit()
1150
+{
1151
+	if (RAM)
1152
+	{
1153
+		free(RAM);
1154
+		RAM = NULL;
1155
+	}
1156
+
1157
+	if (SRAM)
1158
+	{
1159
+		free(SRAM);
1160
+		SRAM = NULL;
1161
+	}
1162
+
1163
+	if (VRAM)
1164
+	{
1165
+		free(VRAM);
1166
+		VRAM = NULL;
1167
+	}
1168
+
1169
+	if (ROM)
1170
+	{
1171
+		ROM -= 0x8000;
1172
+		free(ROM);
1173
+		ROM = NULL;
1174
+	}
1175
+
1176
+	for (int t = 0; t < 7; t++)
1177
+	{
1178
+		if (IPPU.TileCache[t])
1179
+		{
1180
+			free(IPPU.TileCache[t]);
1181
+			IPPU.TileCache[t] = NULL;
1182
+		}
1183
+
1184
+		if (IPPU.TileCached[t])
1185
+		{
1186
+			free(IPPU.TileCached[t]);
1187
+			IPPU.TileCached[t] = NULL;
1188
+		}
1189
+	}
1190
+
1191
+	Safe(NULL);
1192
+	SafeANK(NULL);
1193
+}
1194
+
1195
+// file management and ROM detection
1196
+
1197
+static bool allASCII (uint8_t *b, int size)
1198
+{
1199
+	for (int i = 0; i < size; i++)
1200
+	{
1201
+		if (b[i] < 32 || b[i] > 126)
1202
+			return false;
1203
+	}
1204
+
1205
+	return true;
1206
+}
1207
+
1208
+/*static bool is_SufamiTurbo_BIOS (uint8_t *data, uint32_t size)
1209
+{
1210
+	if (size == 0x40000 &&
1211
+		strncmp((char *) data, "BANDAI SFC-ADX", 14) == 0 && strncmp((char * ) (data + 0x10), "SFC-ADX BACKUP", 14) == 0)
1212
+		return true;
1213
+	else
1214
+		return false;
1215
+}*/
1216
+
1217
+/*static bool is_SufamiTurbo_Cart (uint8_t *data, uint32_t size)
1218
+{
1219
+	if (size >= 0x80000 && size <= 0x100000 &&
1220
+		strncmp((char *) data, "BANDAI SFC-ADX", 14) == 0 && strncmp((char * ) (data + 0x10), "SFC-ADX BACKUP", 14) != 0)
1221
+		return true;
1222
+	else
1223
+		return false;
1224
+}*/
1225
+
1226
+/*static bool is_SameGame_BIOS (uint8_t *data, uint32_t size)
1227
+{
1228
+	if (size == 0x100000 && strncmp((char *) (data + 0xffc0), "Same Game Tsume Game", 20) == 0)
1229
+		return true;
1230
+	else
1231
+		return false;
1232
+}*/
1233
+
1234
+/*static bool is_SameGame_Add_On (uint8_t *data, uint32_t size)
1235
+{
1236
+	if (size == 0x80000)
1237
+		return true;
1238
+	else
1239
+		return false;
1240
+}*/
1241
+
1242
+int CMemory::ScoreHiROM (bool skip_header, int32_t romoff)
1243
+{
1244
+	uint8_t	*buf = ROM + 0xff00 + romoff + (skip_header ? 0x200 : 0);
1245
+	int		score = 0;
1246
+
1247
+	if (buf[0xd5] & 0x1)
1248
+		score += 2;
1249
+
1250
+	// Mode23 is SA-1
1251
+	if (buf[0xd5] == 0x23)
1252
+		score -= 2;
1253
+
1254
+	if (buf[0xd4] == 0x20)
1255
+		score += 2;
1256
+
1257
+	if ((buf[0xdc] + (buf[0xdd] << 8)) + (buf[0xde] + (buf[0xdf] << 8)) == 0xffff)
1258
+	{
1259
+		score += 2;
1260
+		if (0 != (buf[0xde] + (buf[0xdf] << 8)))
1261
+			score++;
1262
+	}
1263
+
1264
+	if (buf[0xda] == 0x33)
1265
+		score += 2;
1266
+
1267
+	if ((buf[0xd5] & 0xf) < 4)
1268
+		score += 2;
1269
+
1270
+	if (!(buf[0xfd] & 0x80))
1271
+		score -= 6;
1272
+
1273
+	if ((buf[0xfc] + (buf[0xfd] << 8)) > 0xffb0)
1274
+		score -= 2; // reduced after looking at a scan by Cowering
1275
+
1276
+	if (CalculatedSize > 1024 * 1024 * 3)
1277
+		score += 4;
1278
+
1279
+	if ((1 << (buf[0xd7] - 7)) > 48)
1280
+		score -= 1;
1281
+
1282
+	if (!allASCII(&buf[0xb0], 6))
1283
+		score -= 1;
1284
+
1285
+	if (!allASCII(&buf[0xc0], ROM_NAME_LEN - 1))
1286
+		score -= 1;
1287
+
1288
+	return score;
1289
+}
1290
+
1291
+int CMemory::ScoreLoROM (bool skip_header, int32_t romoff)
1292
+{
1293
+	uint8_t	*buf = ROM + 0x7f00 + romoff + (skip_header ? 0x200 : 0);
1294
+	int		score = 0;
1295
+
1296
+	if (!(buf[0xd5] & 0x1))
1297
+		score += 3;
1298
+
1299
+	// Mode23 is SA-1
1300
+	if (buf[0xd5] == 0x23)
1301
+		score += 2;
1302
+
1303
+	if ((buf[0xdc] + (buf[0xdd] << 8)) + (buf[0xde] + (buf[0xdf] << 8)) == 0xffff)
1304
+	{
1305
+		score += 2;
1306
+		if (0 != (buf[0xde] + (buf[0xdf] << 8)))
1307
+			score++;
1308
+	}
1309
+
1310
+	if (buf[0xda] == 0x33)
1311
+		score += 2;
1312
+
1313
+	if ((buf[0xd5] & 0xf) < 4)
1314
+		score += 2;
1315
+
1316
+	if (!(buf[0xfd] & 0x80))
1317
+		score -= 6;
1318
+
1319
+	if ((buf[0xfc] + (buf[0xfd] << 8)) > 0xffb0)
1320
+		score -= 2; // reduced per Cowering suggestion
1321
+
1322
+	if (CalculatedSize <= 1024 * 1024 * 16)
1323
+		score += 2;
1324
+
1325
+	if ((1 << (buf[0xd7] - 7)) > 48)
1326
+		score -= 1;
1327
+
1328
+	if (!allASCII(&buf[0xb0], 6))
1329
+		score -= 1;
1330
+
1331
+	if (!allASCII(&buf[0xc0], ROM_NAME_LEN - 1))
1332
+		score -= 1;
1333
+
1334
+	return score;
1335
+}
1336
+
1337
+/*uint32_t CMemory::HeaderRemove (uint32_t size, int32_t &headerCount, uint8_t *buf)
1338
+{
1339
+	uint32_t	calc_size = (size / 0x2000) * 0x2000;
1340
+
1341
+	if ((size - calc_size == 512 && !Settings.ForceNoHeader) || Settings.ForceHeader)
1342
+	{
1343
+		uint8_t	*NSRTHead = buf + 0x1D0; // NSRT Header Location
1344
+
1345
+		// detect NSRT header
1346
+		if (!strncmp("NSRT", (char *) &NSRTHead[24], 4))
1347
+		{
1348
+			if (NSRTHead[28] == 22)
1349
+			{
1350
+				if (((std::accumulate(NSRTHead, NSRTHead + sizeof(NSRTHeader), 0) & 0xFF) == NSRTHead[30]) &&
1351
+					(NSRTHead[30] + NSRTHead[31] == 255) && ((NSRTHead[0] & 0x0F) <= 13) &&
1352
+					(((NSRTHead[0] & 0xF0) >> 4) <= 3) && ((NSRTHead[0] & 0xF0) >> 4))
1353
+					memcpy(NSRTHeader, NSRTHead, sizeof(NSRTHeader));
1354
+			}
1355
+		}
1356
+
1357
+		memmove(buf, buf + 512, calc_size);
1358
+		headerCount++;
1359
+		size -= 512;
1360
+	}
1361
+
1362
+	return size;
1363
+}*/
1364
+
1365
+/*uint32_t CMemory::FileLoader (uint8_t *buffer, const char *filename, int32_t maxsize)
1366
+{
1367
+	// <- ROM size without header
1368
+	// ** Memory.HeaderCount
1369
+	// ** Memory.ROMFilename
1370
+
1371
+	int32_t	totalSize = 0;
1372
+    char	fname[PATH_MAX + 1];
1373
+    char	drive[_MAX_DRIVE + 1], dir[_MAX_DIR + 1], name[_MAX_FNAME + 1], exts[_MAX_EXT + 1];
1374
+	char	*ext;
1375
+
1376
+#if defined(_WIN32) || defined(__MACOSX__)
1377
+	ext = &exts[1];
1378
+#else
1379
+	ext = &exts[0];
1380
+#endif
1381
+
1382
+	memset(NSRTHeader, 0, sizeof(NSRTHeader));
1383
+	HeaderCount = 0;
1384
+
1385
+	_splitpath(filename, drive, dir, name, exts);
1386
+	_makepath(fname, drive, dir, name, exts);
1387
+
1388
+	int	nFormat = FILE_DEFAULT;
1389
+	if (strcasecmp(ext, "zip") == 0)
1390
+		nFormat = FILE_ZIP;
1391
+	else
1392
+	if (strcasecmp(ext, "jma") == 0)
1393
+		nFormat = FILE_JMA;
1394
+
1395
+	switch (nFormat)
1396
+	{
1397
+		case FILE_ZIP:
1398
+		{
1399
+		#ifdef UNZIP_SUPPORT
1400
+			if (!LoadZip(fname, &totalSize, &HeaderCount, buffer))
1401
+			{
1402
+			 	S9xMessage(S9X_ERROR, S9X_ROM_INFO, "Invalid Zip archive.");
1403
+				return 0;
1404
+			}
1405
+
1406
+			strcpy(ROMFilename, fname);
1407
+		#else
1408
+			//S9xMessage(S9X_ERROR, S9X_ROM_INFO, "This binary was not created with Zip support.");
1409
+			return 0;
1410
+		#endif
1411
+			break;
1412
+		}
1413
+
1414
+		case FILE_JMA:
1415
+		{
1416
+		#ifdef JMA_SUPPORT
1417
+			size_t	size = load_jma_file(fname, buffer);
1418
+			if (!size)
1419
+			{
1420
+			 	S9xMessage(S9X_ERROR, S9X_ROM_INFO, "Invalid JMA archive.");
1421
+				return 0;
1422
+			}
1423
+
1424
+			totalSize = HeaderRemove(size, HeaderCount, buffer);
1425
+
1426
+			strcpy(ROMFilename, fname);
1427
+		#else
1428
+			//S9xMessage(S9X_ERROR, S9X_ROM_INFO, "This binary was not created with JMA support.");
1429
+			return 0;
1430
+		#endif
1431
+			break;
1432
+		}
1433
+
1434
+		case FILE_DEFAULT:
1435
+		default:
1436
+		{
1437
+			STREAM	fp = OPEN_STREAM(fname, "rb");
1438
+			if (!fp)
1439
+				return 0;
1440
+
1441
+			strcpy(ROMFilename, fname);
1442
+
1443
+			int 	len  = 0;
1444
+			uint32_t	size = 0;
1445
+			bool	more = false;
1446
+			uint8_t	*ptr = buffer;
1447
+
1448
+			do
1449
+			{
1450
+				size = READ_STREAM(ptr, maxsize + 0x200 - (ptr - buffer), fp);
1451
+				CLOSE_STREAM(fp);
1452
+
1453
+				size = HeaderRemove(size, HeaderCount, ptr);
1454
+				totalSize += size;
1455
+				ptr += size;
1456
+
1457
+				// check for multi file roms
1458
+				if (ptr - buffer < maxsize + 0x200 &&
1459
+					(isdigit(ext[0]) && ext[1] == 0 && ext[0] < '9'))
1460
+				{
1461
+					more = true;
1462
+					ext[0]++;
1463
+					_makepath(fname, drive, dir, name, exts);
1464
+				}
1465
+				else
1466
+				if (ptr - buffer < maxsize + 0x200 &&
1467
+					(((len = strlen(name)) == 7 || len == 8) &&
1468
+					strncasecmp(name, "sf", 2) == 0 &&
1469
+					isdigit(name[2]) && isdigit(name[3]) && isdigit(name[4]) && isdigit(name[5]) &&
1470
+					isalpha(name[len - 1])))
1471
+				{
1472
+					more = true;
1473
+					name[len - 1]++;
1474
+					_makepath(fname, drive, dir, name, exts);
1475
+				}
1476
+				else
1477
+					more = false;
1478
+
1479
+			}	while (more && (fp = OPEN_STREAM(fname, "rb")) != NULL);
1480
+
1481
+			break;
1482
+		}
1483
+	}
1484
+
1485
+    if (HeaderCount == 0)
1486
+		S9xMessage(S9X_INFO, S9X_HEADERS_INFO, "No ROM file header found.");
1487
+    else
1488
+    if (HeaderCount == 1)
1489
+		S9xMessage(S9X_INFO, S9X_HEADERS_INFO, "Found ROM file header (and ignored it).");
1490
+	else
1491
+		S9xMessage(S9X_INFO, S9X_HEADERS_INFO, "Found multiple ROM file headers (and ignored them).");
1492
+
1493
+	return (uint32_t) totalSize;
1494
+}*/
1495
+
1496
+//bool CMemory::LoadROM (const char *filename)
1497
+bool CMemory::LoadROMSNSF(const unsigned char *lrombuf, int32_t lromsize, const unsigned char *srambuf, int32_t sramsize)
1498
+{
1499
+	int	retry_count = 0;
1500
+
1501
+	/*if (!filename || !*filename)
1502
+		return false;*/
1503
+
1504
+	ZeroMemory(ROM, MAX_ROM_SIZE);
1505
+	ZeroMemory(&Multi, sizeof(Multi));
1506
+
1507
+again:
1508
+	//Settings.DisplayColor = BUILD_PIXEL(31, 31, 31);
1509
+	//SET_UI_COLOR(255, 255, 255);
1510
+
1511
+	CalculatedSize = 0;
1512
+	ExtendedFormat = NOPE;
1513
+
1514
+	int32_t totalFileSize;
1515
+
1516
+	//totalFileSize = FileLoader(ROM, filename, MAX_ROM_SIZE);
1517
+	totalFileSize  = std::min<int32_t>(MAX_ROM_SIZE, lromsize);
1518
+	if (!totalFileSize)
1519
+		return false;
1520
+	memcpy(ROM, lrombuf, totalFileSize);
1521
+	SNESGameFixes.SRAMInitialValue = 0xff;
1522
+	memset(SRAM, SNESGameFixes.SRAMInitialValue, 0x20000);
1523
+	if (srambuf && sramsize)
1524
+		memcpy(SRAM, srambuf, sramsize);
1525
+
1526
+	/*if (!Settings.NoPatch)
1527
+		CheckForAnyPatch(filename, HeaderCount != 0, totalFileSize);*/
1528
+
1529
+	int	hi_score, lo_score;
1530
+
1531
+	hi_score = ScoreHiROM(false);
1532
+	lo_score = ScoreLoROM(false);
1533
+
1534
+	if (HeaderCount == 0 && !Settings.ForceNoHeader &&
1535
+		((hi_score >  lo_score && ScoreHiROM(true) > hi_score) ||
1536
+		 (hi_score <= lo_score && ScoreLoROM(true) > lo_score)))
1537
+	{
1538
+		memmove(ROM, ROM + 512, totalFileSize - 512);
1539
+		totalFileSize -= 512;
1540
+		//S9xMessage(S9X_INFO, S9X_HEADER_WARNING, "Try 'force no-header' option if the game doesn't work");
1541
+		// modifying ROM, so we need to rescore
1542
+		hi_score = ScoreHiROM(false);
1543
+		lo_score = ScoreLoROM(false);
1544
+	}
1545
+
1546
+	CalculatedSize = (totalFileSize / 0x2000) * 0x2000;
1547
+
1548
+	if (CalculatedSize > 0x400000 &&
1549
+		(ROM[0x7fd5] + (ROM[0x7fd6] << 8)) != 0x4332 && // exclude S-DD1
1550
+		(ROM[0x7fd5] + (ROM[0x7fd6] << 8)) != 0x4532 &&
1551
+		(ROM[0xffd5] + (ROM[0xffd6] << 8)) != 0xF93a && // exclude SPC7110
1552
+		(ROM[0xffd5] + (ROM[0xffd6] << 8)) != 0xF53a)
1553
+		ExtendedFormat = YEAH;
1554
+
1555
+	// if both vectors are invalid, it's type 1 interleaved LoROM
1556
+	if (ExtendedFormat == NOPE &&
1557
+		((ROM[0x7ffc] + (ROM[0x7ffd] << 8)) < 0x8000) &&
1558
+		((ROM[0xfffc] + (ROM[0xfffd] << 8)) < 0x8000))
1559
+	{
1560
+		if (!Settings.ForceInterleaved && !Settings.ForceNotInterleaved)
1561
+			S9xDeinterleaveType1(totalFileSize, ROM);
1562
+	}
1563
+
1564
+	// CalculatedSize is now set, so rescore
1565
+	hi_score = ScoreHiROM(false);
1566
+	lo_score = ScoreLoROM(false);
1567
+
1568
+	uint8_t	*RomHeader = ROM;
1569
+
1570
+	if (ExtendedFormat != NOPE)
1571
+	{
1572
+		int	swappedhirom, swappedlorom;
1573
+
1574
+		swappedhirom = ScoreHiROM(false, 0x400000);
1575
+		swappedlorom = ScoreLoROM(false, 0x400000);
1576
+
1577
+		// set swapped here
1578
+		if (std::max(swappedlorom, swappedhirom) >= std::max(lo_score, hi_score))
1579
+		{
1580
+			ExtendedFormat = BIGFIRST;
1581
+			hi_score = swappedhirom;
1582
+			lo_score = swappedlorom;
1583
+			RomHeader += 0x400000;
1584
+		}
1585
+		else
1586
+			ExtendedFormat = SMALLFIRST;
1587
+	}
1588
+
1589
+	bool	interleaved, tales = false;
1590
+
1591
+    interleaved = Settings.ForceInterleaved || Settings.ForceInterleaved2 || Settings.ForceInterleaveGD24;
1592
+
1593
+	if (Settings.ForceLoROM || (!Settings.ForceHiROM && lo_score >= hi_score))
1594
+	{
1595
+		LoROM = true;
1596
+		HiROM = false;
1597
+
1598
+		// ignore map type byte if not 0x2x or 0x3x
1599
+		if ((RomHeader[0x7fd5] & 0xf0) == 0x20 || (RomHeader[0x7fd5] & 0xf0) == 0x30)
1600
+		{
1601
+			switch (RomHeader[0x7fd5] & 0xf)
1602
+			{
1603
+				case 1:
1604
+					interleaved = true;
1605
+					break;
1606
+
1607
+				case 5:
1608
+					interleaved = true;
1609
+					tales = true;
1610
+					break;
1611
+			}
1612
+		}
1613
+	}
1614
+	else
1615
+	{
1616
+		LoROM = false;
1617
+		HiROM = true;
1618
+
1619
+		if ((RomHeader[0xffd5] & 0xf0) == 0x20 || (RomHeader[0xffd5] & 0xf0) == 0x30)
1620
+		{
1621
+			switch (RomHeader[0xffd5] & 0xf)
1622
+			{
1623
+				case 0:
1624
+				case 3:
1625
+					interleaved = true;
1626
+					break;
1627
+			}
1628
+		}
1629
+	}
1630
+
1631
+	// this two games fail to be detected
1632
+	if (!Settings.ForceHiROM && !Settings.ForceLoROM)
1633
+	{
1634
+		if (strncmp((char *) &ROM[0x7fc0], "YUYU NO QUIZ DE GO!GO!", 22) == 0 ||
1635
+		   (strncmp((char *) &ROM[0xffc0], "BATMAN--REVENGE JOKER",  21) == 0))
1636
+		{
1637
+			LoROM = true;
1638
+			HiROM = false;
1639
+			interleaved = false;
1640
+			tales = false;
1641
+		}
1642
+	}
1643
+
1644
+	if (!Settings.ForceNotInterleaved && interleaved)
1645
+	{
1646
+		//S9xMessage(S9X_INFO, S9X_ROM_INTERLEAVED_INFO, "ROM image is in interleaved format - converting...");
1647
+
1648
+		if (tales)
1649
+		{
1650
+			if (ExtendedFormat == BIGFIRST)
1651
+			{
1652
+				S9xDeinterleaveType1(0x400000, ROM);
1653
+				S9xDeinterleaveType1(CalculatedSize - 0x400000, ROM + 0x400000);
1654
+			}
1655
+			else
1656
+			{
1657
+				S9xDeinterleaveType1(CalculatedSize - 0x400000, ROM);
1658
+				S9xDeinterleaveType1(0x400000, ROM + CalculatedSize - 0x400000);
1659
+			}
1660
+
1661
+			LoROM = false;
1662
+			HiROM = true;
1663
+		}
1664
+		else
1665
+		if (Settings.ForceInterleaveGD24 && CalculatedSize == 0x300000)
1666
+		{
1667
+			bool	t = LoROM;
1668
+			LoROM = HiROM;
1669
+			HiROM = t;
1670
+			S9xDeinterleaveGD24(CalculatedSize, ROM);
1671
+		}
1672
+		else
1673
+		if (Settings.ForceInterleaved2)
1674
+			S9xDeinterleaveType2(CalculatedSize, ROM);
1675
+		else
1676
+		{
1677
+			bool	t = LoROM;
1678
+			LoROM = HiROM;
1679
+			HiROM = t;
1680
+			S9xDeinterleaveType1(CalculatedSize, ROM);
1681
+		}
1682
+
1683
+		hi_score = ScoreHiROM(false);
1684
+		lo_score = ScoreLoROM(false);
1685
+
1686
+		if ((HiROM && (lo_score >= hi_score || hi_score < 0)) ||
1687
+			(LoROM && (hi_score >  lo_score || lo_score < 0)))
1688
+		{
1689
+			if (retry_count == 0)
1690
+			{
1691
+				//S9xMessage(S9X_INFO, S9X_ROM_CONFUSING_FORMAT_INFO, "ROM lied about its type! Trying again.");
1692
+				Settings.ForceNotInterleaved = true;
1693
+				Settings.ForceInterleaved = false;
1694
+				retry_count++;
1695
+				goto again;
1696
+			}
1697
+		}
1698
+    }
1699
+
1700
+	if (ExtendedFormat == SMALLFIRST)
1701
+		tales = true;
1702
+
1703
+	if (tales)
1704
+	{
1705
+		uint8_t	*tmp = (uint8_t *) malloc(CalculatedSize - 0x400000);
1706
+		if (tmp)
1707
+		{
1708
+			//S9xMessage(S9X_INFO, S9X_ROM_INTERLEAVED_INFO, "Fixing swapped ExHiROM...");
1709
+			memmove(tmp, ROM, CalculatedSize - 0x400000);
1710
+			memmove(ROM, ROM + CalculatedSize - 0x400000, 0x400000);
1711
+			memmove(ROM + 0x400000, tmp, CalculatedSize - 0x400000);
1712
+			free(tmp);
1713
+		}
1714
+	}
1715
+
1716
+	/*if (strncmp(LastRomFilename, filename, PATH_MAX + 1))
1717
+	{
1718
+		strncpy(LastRomFilename, filename, PATH_MAX + 1);
1719
+		LastRomFilename[PATH_MAX] = 0;
1720
+	}*/
1721
+
1722
+	ZeroMemory(&SNESGameFixes, sizeof(SNESGameFixes));
1723
+	SNESGameFixes.SRAMInitialValue = 0x60;
1724
+
1725
+	//S9xLoadCheatFile(S9xGetFilename(".cht", CHEAT_DIR));
1726
+
1727
+	InitROM();
1728
+
1729
+	/*S9xInitCheatData();
1730
+	S9xApplyCheats();*/
1731
+
1732
+	S9xReset();
1733
+
1734
+    return true;
1735
+}
1736
+
1737
+/*bool CMemory::LoadMultiCart (const char *cartA, const char *cartB)
1738
+{
1739
+	bool	r = true;
1740
+
1741
+	ZeroMemory(ROM, MAX_ROM_SIZE);
1742
+	ZeroMemory(&Multi, sizeof(Multi));
1743
+
1744
+	Settings.DisplayColor = BUILD_PIXEL(31, 31, 31);
1745
+	SET_UI_COLOR(255, 255, 255);
1746
+
1747
+	CalculatedSize = 0;
1748
+	ExtendedFormat = NOPE;
1749
+
1750
+	if (cartA && cartA[0])
1751
+		Multi.cartSizeA = FileLoader(ROM, cartA, MAX_ROM_SIZE);
1752
+
1753
+	if (Multi.cartSizeA == 0)
1754
+	{
1755
+		if (cartB && cartB[0])
1756
+			Multi.cartSizeB = FileLoader(ROM, cartB, MAX_ROM_SIZE);
1757
+	}
1758
+
1759
+	if (Multi.cartSizeA)
1760
+	{
1761
+		if (is_SufamiTurbo_Cart(ROM, Multi.cartSizeA))
1762
+			Multi.cartType = 4;
1763
+		else
1764
+		if (is_SameGame_BIOS(ROM, Multi.cartSizeA))
1765
+			Multi.cartType = 3;
1766
+	}
1767
+	else
1768
+	if (Multi.cartSizeB)
1769
+	{
1770
+		if (is_SufamiTurbo_Cart(ROM, Multi.cartSizeB))
1771
+			Multi.cartType = 4;
1772
+	}
1773
+	else
1774
+		Multi.cartType = 4; // assuming BIOS only
1775
+
1776
+	switch (Multi.cartType)
1777
+	{
1778
+		case 4:
1779
+			r = LoadSufamiTurbo(cartA, cartB);
1780
+			break;
1781
+
1782
+		case 3:
1783
+			r = LoadSameGame(cartA, cartB);
1784
+			break;
1785
+
1786
+		default:
1787
+			r = false;
1788
+	}
1789
+
1790
+	if (!r)
1791
+	{
1792
+		ZeroMemory(&Multi, sizeof(Multi));
1793
+		return false;
1794
+	}
1795
+
1796
+	ZeroMemory(&SNESGameFixes, sizeof(SNESGameFixes));
1797
+	SNESGameFixes.SRAMInitialValue = 0x60;
1798
+
1799
+	S9xLoadCheatFile(S9xGetFilename(".cht", CHEAT_DIR));
1800
+
1801
+	InitROM();
1802
+
1803
+	S9xInitCheatData();
1804
+	S9xApplyCheats();
1805
+
1806
+	S9xReset();
1807
+
1808
+	return true;
1809
+}
1810
+
1811
+bool CMemory::LoadSufamiTurbo (const char *cartA, const char *cartB)
1812
+{
1813
+	Multi.cartOffsetA = 0x100000;
1814
+	Multi.cartOffsetB = 0x200000;
1815
+	Multi.sramA = SRAM;
1816
+	Multi.sramB = SRAM + 0x10000;
1817
+
1818
+	if (Multi.cartSizeA)
1819
+	{
1820
+		Multi.sramSizeA = 4; // ROM[0x37]?
1821
+		Multi.sramMaskA = Multi.sramSizeA ? ((1 << (Multi.sramSizeA + 3)) * 128 - 1) : 0;
1822
+
1823
+		if (!Settings.NoPatch)
1824
+			CheckForAnyPatch(cartA, HeaderCount != 0, Multi.cartSizeA);
1825
+
1826
+		strcpy(Multi.fileNameA, cartA);
1827
+		memcpy(ROM + Multi.cartOffsetA, ROM, Multi.cartSizeA);
1828
+	}
1829
+
1830
+	if (Multi.cartSizeA && !Multi.cartSizeB)
1831
+	{
1832
+		if (cartB && cartB[0])
1833
+			Multi.cartSizeB = FileLoader(ROM, cartB, MAX_ROM_SIZE);
1834
+
1835
+		if (Multi.cartSizeB)
1836
+		{
1837
+			if (!is_SufamiTurbo_Cart(ROM, Multi.cartSizeB))
1838
+				Multi.cartSizeB = 0;
1839
+		}
1840
+	}
1841
+
1842
+	if (Multi.cartSizeB)
1843
+	{
1844
+		Multi.sramSizeB = 4; // ROM[0x37]?
1845
+		Multi.sramMaskB = Multi.sramSizeB ? ((1 << (Multi.sramSizeB + 3)) * 128 - 1) : 0;
1846
+
1847
+		if (!Settings.NoPatch)
1848
+			CheckForAnyPatch(cartB, HeaderCount != 0, Multi.cartSizeB);
1849
+
1850
+		strcpy(Multi.fileNameB, cartB);
1851
+		memcpy(ROM + Multi.cartOffsetB, ROM, Multi.cartSizeB);
1852
+	}
1853
+
1854
+	FILE	*fp;
1855
+	size_t	size;
1856
+	char	path[PATH_MAX + 1];
1857
+
1858
+	strcpy(path, S9xGetDirectory(BIOS_DIR));
1859
+	strcat(path, SLASH_STR);
1860
+	strcat(path, "STBIOS.bin");
1861
+
1862
+	fp = fopen(path, "rb");
1863
+	if (fp)
1864
+	{
1865
+		size = fread((void *) ROM, 1, 0x40000, fp);
1866
+		fclose(fp);
1867
+		if (!is_SufamiTurbo_BIOS(ROM, size))
1868
+			return false;
1869
+	}
1870
+	else
1871
+		return false;
1872
+
1873
+	if (Multi.cartSizeA)
1874
+		strcpy(ROMFilename, Multi.fileNameA);
1875
+	else
1876
+	if (Multi.cartSizeB)
1877
+		strcpy(ROMFilename, Multi.fileNameB);
1878
+	else
1879
+		strcpy(ROMFilename, path);
1880
+
1881
+	LoROM = true;
1882
+	HiROM = false;
1883
+	CalculatedSize = 0x40000;
1884
+
1885
+	return true;
1886
+}
1887
+
1888
+bool CMemory::LoadSameGame (const char *cartA, const char *cartB)
1889
+{
1890
+	Multi.cartOffsetA = 0;
1891
+	Multi.cartOffsetB = 0x200000;
1892
+	Multi.sramA = SRAM;
1893
+	Multi.sramB = NULL;
1894
+
1895
+	Multi.sramSizeA = ROM[0xffd8];
1896
+	Multi.sramMaskA = Multi.sramSizeA ? ((1 << (Multi.sramSizeA + 3)) * 128 - 1) : 0;
1897
+	Multi.sramSizeB = 0;
1898
+	Multi.sramMaskB = 0;
1899
+
1900
+	if (!Settings.NoPatch)
1901
+		CheckForAnyPatch(cartA, HeaderCount != 0, Multi.cartSizeA);
1902
+
1903
+	strcpy(Multi.fileNameA, cartA);
1904
+
1905
+	if (cartB && cartB[0])
1906
+		Multi.cartSizeB = FileLoader(ROM + Multi.cartOffsetB, cartB, MAX_ROM_SIZE - Multi.cartOffsetB);
1907
+
1908
+	if (Multi.cartSizeB)
1909
+	{
1910
+		if (!is_SameGame_Add_On(ROM + Multi.cartOffsetB, Multi.cartSizeB))
1911
+			Multi.cartSizeB = 0;
1912
+		else
1913
+			strcpy(Multi.fileNameB, cartB);
1914
+	}
1915
+
1916
+	strcpy(ROMFilename, Multi.fileNameA);
1917
+
1918
+	LoROM = false;
1919
+	HiROM = true;
1920
+	CalculatedSize = Multi.cartSizeA;
1921
+
1922
+	return true;
1923
+}
1924
+
1925
+bool CMemory::LoadSRTC()
1926
+{
1927
+	FILE	*fp;
1928
+	size_t	ignore;
1929
+
1930
+	fp = fopen(S9xGetFilename(".rtc", SRAM_DIR), "rb");
1931
+	if (!fp)
1932
+		return false;
1933
+
1934
+	ignore = fread(RTCData.reg, 1, 20, fp);
1935
+	fclose(fp);
1936
+
1937
+	return true;
1938
+}
1939
+
1940
+bool CMemory::SaveSRTC()
1941
+{
1942
+	FILE	*fp;
1943
+	size_t	ignore;
1944
+
1945
+	fp = fopen(S9xGetFilename(".rtc", SRAM_DIR), "wb");
1946
+	if (!fp)
1947
+		return false;
1948
+
1949
+	ignore = fwrite(RTCData.reg, 1, 20, fp);
1950
+	fclose(fp);
1951
+
1952
+	return true;
1953
+}
1954
+
1955
+void CMemory::ClearSRAM (bool onlyNonSavedSRAM)
1956
+{
1957
+	if (onlyNonSavedSRAM)
1958
+		if (!(Settings.SuperFX && ROMType < 0x15) && !(Settings.SA1 && ROMType == 0x34)) // can have SRAM
1959
+			return;
1960
+
1961
+	memset(SRAM, SNESGameFixes.SRAMInitialValue, 0x20000);
1962
+}
1963
+
1964
+bool CMemory::LoadSRAM (const char *filename)
1965
+{
1966
+	FILE	*file;
1967
+	int		size, len;
1968
+	char	sramName[PATH_MAX + 1];
1969
+
1970
+	strcpy(sramName, filename);
1971
+
1972
+	ClearSRAM();
1973
+
1974
+	if (Multi.cartType && Multi.sramSizeB)
1975
+	{
1976
+		char	temp[PATH_MAX + 1];
1977
+
1978
+		strcpy(temp, ROMFilename);
1979
+		strcpy(ROMFilename, Multi.fileNameB);
1980
+
1981
+		size = (1 << (Multi.sramSizeB + 3)) * 128;
1982
+
1983
+		file = fopen(S9xGetFilename(".srm", SRAM_DIR), "rb");
1984
+		if (file)
1985
+		{
1986
+			len = fread((char *) Multi.sramB, 1, 0x10000, file);
1987
+			fclose(file);
1988
+			if (len - size == 512)
1989
+				memmove(Multi.sramB, Multi.sramB + 512, size);
1990
+		}
1991
+
1992
+		strcpy(ROMFilename, temp);
1993
+	}
1994
+
1995
+	size = SRAMSize ? (1 << (SRAMSize + 3)) * 128 : 0;
1996
+	if (size > 0x20000)
1997
+		size = 0x20000;
1998
+
1999
+	if (size)
2000
+	{
2001
+		file = fopen(sramName, "rb");
2002
+		if (file)
2003
+		{
2004
+			len = fread((char *) SRAM, 1, 0x20000, file);
2005
+			fclose(file);
2006
+			if (len - size == 512)
2007
+				memmove(SRAM, SRAM + 512, size);
2008
+
2009
+			if (Settings.SRTC || Settings.SPC7110RTC)
2010
+				LoadSRTC();
2011
+
2012
+			return true;
2013
+		}
2014
+		else
2015
+		if (Settings.BS && !Settings.BSXItself)
2016
+		{
2017
+			// The BS game's SRAM was not found
2018
+			// Try to read BS-X.srm instead
2019
+			char	path[PATH_MAX + 1];
2020
+
2021
+			strcpy(path, S9xGetDirectory(SRAM_DIR));
2022
+			strcat(path, SLASH_STR);
2023
+			strcat(path, "BS-X.srm");
2024
+
2025
+			file = fopen(path, "rb");
2026
+			if (file)
2027
+			{
2028
+				len = fread((char *) SRAM, 1, 0x20000, file);
2029
+				fclose(file);
2030
+				if (len - size == 512)
2031
+					memmove(SRAM, SRAM + 512, size);
2032
+
2033
+				S9xMessage(S9X_INFO, S9X_ROM_INFO, "The SRAM file wasn't found: BS-X.srm was read instead.");
2034
+				return true;
2035
+			}
2036
+			else
2037
+			{
2038
+				S9xMessage(S9X_INFO, S9X_ROM_INFO, "The SRAM file wasn't found, BS-X.srm wasn't found either.");
2039
+				return false;
2040
+			}
2041
+		}
2042
+
2043
+		return false;
2044
+	}
2045
+
2046
+	return true;
2047
+}
2048
+
2049
+bool CMemory::SaveSRAM (const char *filename)
2050
+{
2051
+	if (Settings.SuperFX && ROMType < 0x15) // doesn't have SRAM
2052
+		return true;
2053
+
2054
+	if (Settings.SA1 && ROMType == 0x34)    // doesn't have SRAM
2055
+		return true;
2056
+
2057
+	FILE	*file;
2058
+	int		size;
2059
+	char	sramName[PATH_MAX + 1];
2060
+
2061
+	strcpy(sramName, filename);
2062
+
2063
+	if (Multi.cartType && Multi.sramSizeB)
2064
+	{
2065
+		char	name[PATH_MAX + 1], temp[PATH_MAX + 1];
2066
+
2067
+		strcpy(temp, ROMFilename);
2068
+		strcpy(ROMFilename, Multi.fileNameB);
2069
+		strcpy(name, S9xGetFilename(".srm", SRAM_DIR));
2070
+
2071
+		size = (1 << (Multi.sramSizeB + 3)) * 128;
2072
+
2073
+		file = fopen(name, "wb");
2074
+		if (file)
2075
+		{
2076
+			size_t	ignore;
2077
+			ignore = fwrite((char *) Multi.sramB, size, 1, file);
2078
+			fclose(file);
2079
+		#ifdef __linux
2080
+			ignore = chown(name, getuid(), getgid());
2081
+		#endif
2082
+		}
2083
+
2084
+		strcpy(ROMFilename, temp);
2085
+    }
2086
+
2087
+    size = SRAMSize ? (1 << (SRAMSize + 3)) * 128 : 0;
2088
+	if (size > 0x20000)
2089
+		size = 0x20000;
2090
+
2091
+	if (size)
2092
+	{
2093
+		file = fopen(sramName, "wb");
2094
+		if (file)
2095
+		{
2096
+			size_t	ignore;
2097
+			ignore = fwrite((char *) SRAM, size, 1, file);
2098
+			fclose(file);
2099
+		#ifdef __linux
2100
+			ignore = chown(sramName, getuid(), getgid());
2101
+		#endif
2102
+
2103
+			if (Settings.SRTC || Settings.SPC7110RTC)
2104
+				SaveSRTC();
2105
+
2106
+			return true;
2107
+		}
2108
+	}
2109
+
2110
+	return false;
2111
+}*/
2112
+
2113
+// initialization
2114
+
2115
+static uint32_t caCRC32 (uint8_t *array, uint32_t size, uint32_t crc32 = 0xffffffff)
2116
+{
2117
+	for (uint32_t i = 0; i < size; i++)
2118
+		crc32 = ((crc32 >> 8) & 0x00FFFFFF) ^ crc32Table[(crc32 ^ array[i]) & 0xFF];
2119
+
2120
+	return ~crc32;
2121
+}
2122
+
2123
+char * CMemory::Safe (const char *s)
2124
+{
2125
+	static char	*safe = NULL;
2126
+	static int	safe_len = 0;
2127
+
2128
+	if (s == NULL)
2129
+	{
2130
+		if (safe)
2131
+		{
2132
+			free(safe);
2133
+			safe = NULL;
2134
+		}
2135
+
2136
+		return NULL;
2137
+	}
2138
+
2139
+	int	len = strlen(s);
2140
+	if (!safe || len + 1 > safe_len)
2141
+	{
2142
+		if (safe)
2143
+			free(safe);
2144
+
2145
+		safe_len = len + 1;
2146
+		safe = (char *) malloc(safe_len);
2147
+	}
2148
+
2149
+	for (int i = 0; i < len; i++)
2150
+	{
2151
+		if (s[i] >= 32 && s[i] < 127)
2152
+			safe[i] = s[i];
2153
+		else
2154
+			safe[i] = '_';
2155
+	}
2156
+
2157
+	safe[len] = 0;
2158
+
2159
+	return safe;
2160
+}
2161
+
2162
+char * CMemory::SafeANK (const char *s)
2163
+{
2164
+	static char	*safe = NULL;
2165
+	static int	safe_len = 0;
2166
+
2167
+	if (s == NULL)
2168
+	{
2169
+		if (safe)
2170
+		{
2171
+			free(safe);
2172
+			safe = NULL;
2173
+		}
2174
+
2175
+		return NULL;
2176
+	}
2177
+
2178
+	int	len = strlen(s);
2179
+	if (!safe || len + 1 > safe_len)
2180
+	{
2181
+		if (safe)
2182
+			free(safe);
2183
+
2184
+		safe_len = len + 1;
2185
+		safe = (char *) malloc(safe_len);
2186
+	}
2187
+
2188
+	for (int i = 0; i < len; i++)
2189
+	{
2190
+		if (s[i] >= 32 && s[i] < 127) // ASCII
2191
+			safe [i] = s[i];
2192
+		else
2193
+		if (ROMRegion == 0 && ((uint8_t) s[i] >= 0xa0 && (uint8_t) s[i] < 0xe0)) // JIS X 201 - Katakana
2194
+			safe [i] = s[i];
2195
+		else
2196
+			safe [i] = '_';
2197
+	}
2198
+
2199
+	safe [len] = 0;
2200
+
2201
+	return safe;
2202
+}
2203
+
2204
+void CMemory::ParseSNESHeader (uint8_t *RomHeader)
2205
+{
2206
+	bool	bs = Settings.BS & !Settings.BSXItself;
2207
+
2208
+	strncpy(ROMName, (char *) &RomHeader[0x10], ROM_NAME_LEN - 1);
2209
+	if (bs)
2210
+		memset(ROMName + 16, 0x20, ROM_NAME_LEN - 17);
2211
+
2212
+	if (bs)
2213
+	{
2214
+		if (!(((RomHeader[0x29] & 0x20) && CalculatedSize <  0x100000) ||
2215
+			 (!(RomHeader[0x29] & 0x20) && CalculatedSize == 0x100000)))
2216
+			printf("BS: Size mismatch\n");
2217
+
2218
+		// FIXME
2219
+		int	p = 0;
2220
+		while ((1 << p) < (int) CalculatedSize)
2221
+			p++;
2222
+		ROMSize = p - 10;
2223
+	}
2224
+	else
2225
+		ROMSize = RomHeader[0x27];
2226
+
2227
+	SRAMSize  = bs ? 5 /* BS-X */    : RomHeader[0x28];
2228
+	ROMSpeed  = bs ? RomHeader[0x28] : RomHeader[0x25];
2229
+	ROMType   = bs ? 0xE5 /* BS-X */ : RomHeader[0x26];
2230
+	ROMRegion = bs ? 0               : RomHeader[0x29];
2231
+
2232
+	ROMChecksum           = RomHeader[0x2E] + (RomHeader[0x2F] << 8);
2233
+	ROMComplementChecksum = RomHeader[0x2C] + (RomHeader[0x2D] << 8);
2234
+
2235
+	memmove(ROMId, &RomHeader[0x02], 4);
2236
+
2237
+	if (RomHeader[0x2A] != 0x33)
2238
+		CompanyId = ((RomHeader[0x2A] >> 4) & 0x0F) * 36 + (RomHeader[0x2A] & 0x0F);
2239
+	else
2240
+	if (isalnum(RomHeader[0x00]) && isalnum(RomHeader[0x01]))
2241
+	{
2242
+		int	l, r, l2, r2;
2243
+		l = toupper(RomHeader[0x00]);
2244
+		r = toupper(RomHeader[0x01]);
2245
+		l2 = (l > '9') ? l - '7' : l - '0';
2246
+		r2 = (r > '9') ? r - '7' : r - '0';
2247
+		CompanyId = l2 * 36 + r2;
2248
+	}
2249
+}
2250
+
2251
+void CMemory::InitROM()
2252
+{
2253
+	Settings.SuperFX = false;
2254
+	Settings.DSP = 0;
2255
+	Settings.SA1 = false;
2256
+	Settings.C4 = false;
2257
+	Settings.SDD1 = false;
2258
+	Settings.SPC7110 = false;
2259
+	Settings.SPC7110RTC = false;
2260
+	Settings.OBC1 = false;
2261
+	Settings.SETA = 0;
2262
+	Settings.SRTC = false;
2263
+	Settings.BS = false;
2264
+
2265
+	//SuperFX.nRomBanks = CalculatedSize >> 15;
2266
+
2267
+	//// Parse ROM header and read ROM informatoin
2268
+
2269
+	CompanyId = -1;
2270
+	memset(ROMId, 0, 5);
2271
+
2272
+	uint8_t	*RomHeader = ROM + 0x7FB0;
2273
+	if (ExtendedFormat == BIGFIRST)
2274
+		RomHeader += 0x400000;
2275
+	if (HiROM)
2276
+		RomHeader += 0x8000;
2277
+
2278
+	//S9xInitBSX(); // Set BS header before parsing
2279
+
2280
+	ParseSNESHeader(RomHeader);
2281
+
2282
+	//// Detect and initialize chips
2283
+	//// detection codes are compatible with NSRT
2284
+
2285
+	// DSP1/2/3/4
2286
+	if (ROMType == 0x03)
2287
+	{
2288
+		if (ROMSpeed == 0x30)
2289
+			Settings.DSP = 4; // DSP4
2290
+		else
2291
+			Settings.DSP = 1; // DSP1
2292
+	}
2293
+	else
2294
+	if (ROMType == 0x05)
2295
+	{
2296
+		if (ROMSpeed == 0x20)
2297
+			Settings.DSP = 2; // DSP2
2298
+		else
2299
+		if (ROMSpeed == 0x30 && RomHeader[0x2a] == 0xb2)
2300
+			Settings.DSP = 3; // DSP3
2301
+		else
2302
+			Settings.DSP = 1; // DSP1
2303
+	}
2304
+
2305
+	/*switch (Settings.DSP)
2306
+	{
2307
+		case 1:	// DSP1
2308
+			if (HiROM)
2309
+			{
2310
+				DSP0.boundary = 0x7000;
2311
+				DSP0.maptype = M_DSP1_HIROM;
2312
+			}
2313
+			else
2314
+			if (CalculatedSize > 0x100000)
2315
+			{
2316
+				DSP0.boundary = 0x4000;
2317
+				DSP0.maptype = M_DSP1_LOROM_L;
2318
+			}
2319
+			else
2320
+			{
2321
+				DSP0.boundary = 0xc000;
2322
+				DSP0.maptype = M_DSP1_LOROM_S;
2323
+			}
2324
+
2325
+			SetDSP = &DSP1SetByte;
2326
+			GetDSP = &DSP1GetByte;
2327
+			break;
2328
+
2329
+		case 2: // DSP2
2330
+			DSP0.boundary = 0x10000;
2331
+			DSP0.maptype = M_DSP2_LOROM;
2332
+			SetDSP = &DSP2SetByte;
2333
+			GetDSP = &DSP2GetByte;
2334
+			break;
2335
+
2336
+		case 3: // DSP3
2337
+			DSP0.boundary = 0xc000;
2338
+			DSP0.maptype = M_DSP3_LOROM;
2339
+			SetDSP = &DSP3SetByte;
2340
+			GetDSP = &DSP3GetByte;
2341
+			break;
2342
+
2343
+		case 4: // DSP4
2344
+			DSP0.boundary = 0xc000;
2345
+			DSP0.maptype = M_DSP4_LOROM;
2346
+			SetDSP = &DSP4SetByte;
2347
+			GetDSP = &DSP4GetByte;
2348
+			break;
2349
+
2350
+		default:
2351
+			SetDSP = NULL;
2352
+			GetDSP = NULL;
2353
+			break;
2354
+	}*/
2355
+
2356
+	uint32_t	identifier = ((ROMType & 0xff) << 8) + (ROMSpeed & 0xff);
2357
+
2358
+	switch (identifier)
2359
+	{
2360
+	    // SRTC
2361
+		/*case 0x5535:
2362
+			Settings.SRTC = true;
2363
+			S9xInitSRTC();
2364
+			break;
2365
+
2366
+		// SPC7110
2367
+		case 0xF93A:
2368
+			Settings.SPC7110RTC = true;
2369
+		case 0xF53A:
2370
+			Settings.SPC7110 = true;
2371
+			S9xInitSPC7110();
2372
+			break;
2373
+
2374
+		// OBC1
2375
+		case 0x2530:
2376
+			Settings.OBC1 = true;
2377
+			break;
2378
+
2379
+		// SA1
2380
+		case 0x3423:
2381
+		case 0x3523:
2382
+			Settings.SA1 = true;
2383
+			break;
2384
+
2385
+		// SuperFX
2386
+		case 0x1320:
2387
+		case 0x1420:
2388
+		case 0x1520:
2389
+		case 0x1A20:
2390
+			Settings.SuperFX = true;
2391
+			S9xInitSuperFX();
2392
+			if (ROM[0x7FDA] == 0x33)
2393
+				SRAMSize = ROM[0x7FBD];
2394
+			else
2395
+				SRAMSize = 5;
2396
+			break;*/
2397
+
2398
+		// SDD1
2399
+		case 0x4332:
2400
+		case 0x4532:
2401
+			Settings.SDD1 = true;
2402
+			break;
2403
+
2404
+		// ST018
2405
+		/*case 0xF530:
2406
+			Settings.SETA = ST_018;
2407
+			SetSETA = NULL;
2408
+			GetSETA = NULL;
2409
+			SRAMSize = 2;
2410
+			SNESGameFixes.SRAMInitialValue = 0x00;
2411
+			break;
2412
+
2413
+		// ST010/011
2414
+		case 0xF630:
2415
+			if (ROM[0x7FD7] == 0x09)
2416
+			{
2417
+				Settings.SETA = ST_011;
2418
+				SetSETA = &S9xSetST011;
2419
+				GetSETA = &S9xGetST011;
2420
+			}
2421
+			else
2422
+			{
2423
+				Settings.SETA = ST_010;
2424
+				SetSETA = &S9xSetST010;
2425
+				GetSETA = &S9xGetST010;
2426
+			}
2427
+
2428
+			SRAMSize = 2;
2429
+			SNESGameFixes.SRAMInitialValue = 0x00;
2430
+			break;
2431
+
2432
+		// C4
2433
+		case 0xF320:
2434
+			Settings.C4 = true;
2435
+			break;*/
2436
+	}
2437
+
2438
+	//// Map memory and calculate checksum
2439
+
2440
+	Map_Initialize();
2441
+	CalculatedChecksum = 0;
2442
+
2443
+	if (HiROM)
2444
+    {
2445
+		if (Settings.BS)
2446
+			/* Do nothing */;
2447
+		else
2448
+		/*if (Settings.SPC7110)
2449
+			Map_SPC7110HiROMMap();
2450
+		else*/
2451
+		if (ExtendedFormat != NOPE)
2452
+			Map_ExtendedHiROMMap();
2453
+		/*else
2454
+		if (Multi.cartType == 3)
2455
+			Map_SameGameHiROMMap();*/
2456
+		else
2457
+			Map_HiROMMap();
2458
+    }
2459
+    else
2460
+    {
2461
+		if (Settings.BS)
2462
+			/* Do nothing */;
2463
+		else
2464
+		/*if (Settings.SETA && Settings.SETA != ST_018)
2465
+			Map_SetaDSPLoROMMap();
2466
+		else
2467
+		if (Settings.SuperFX)
2468
+			Map_SuperFXLoROMMap();
2469
+		else
2470
+		if (Settings.SA1)
2471
+			Map_SA1LoROMMap();
2472
+		else*/
2473
+		if (Settings.SDD1)
2474
+			Map_SDD1LoROMMap();
2475
+		else
2476
+		if (ExtendedFormat != NOPE)
2477
+			Map_JumboLoROMMap();
2478
+		else
2479
+		if (strncmp(ROMName, "WANDERERS FROM YS", 17) == 0)
2480
+			Map_NoMAD1LoROMMap();
2481
+		else
2482
+		if (strncmp(ROMName, "SOUND NOVEL-TCOOL", 17) == 0 ||
2483
+			strncmp(ROMName, "DERBY STALLION 96", 17) == 0)
2484
+			Map_ROM24MBSLoROMMap();
2485
+		else
2486
+		if (strncmp(ROMName, "THOROUGHBRED BREEDER3", 21) == 0 ||
2487
+			strncmp(ROMName, "RPG-TCOOL 2", 11) == 0)
2488
+			Map_SRAM512KLoROMMap();
2489
+		/*else
2490
+		if (strncmp(ROMName, "ADD-ON BASE CASSETE", 19) == 0)
2491
+		{
2492
+			if (Multi.cartType == 4)
2493
+			{
2494
+				SRAMSize = Multi.sramSizeA;
2495
+				Map_SufamiTurboLoROMMap();
2496
+			}
2497
+			else
2498
+			{
2499
+				SRAMSize = 5;
2500
+				Map_SufamiTurboPseudoLoROMMap();
2501
+			}
2502
+		}*/
2503
+		else
2504
+			Map_LoROMMap();
2505
+    }
2506
+
2507
+	Checksum_Calculate();
2508
+
2509
+	bool isChecksumOK = (ROMChecksum + ROMComplementChecksum == 0xffff) &
2510
+						 (ROMChecksum == CalculatedChecksum);
2511
+
2512
+	//// Build more ROM information
2513
+
2514
+	// CRC32
2515
+	if (!Settings.BS || Settings.BSXItself) // Not BS Dump
2516
+		ROMCRC32 = caCRC32(ROM, CalculatedSize);
2517
+	else // Convert to correct format before scan
2518
+	{
2519
+		int offset = HiROM ? 0xffc0 : 0x7fc0;
2520
+		// Backup
2521
+		uint8_t BSMagic0 = ROM[offset + 22],
2522
+			  BSMagic1 = ROM[offset + 23];
2523
+		// uCONSRT standard
2524
+		ROM[offset + 22] = 0x42;
2525
+		ROM[offset + 23] = 0x00;
2526
+		// Calc
2527
+		ROMCRC32 = caCRC32(ROM, CalculatedSize);
2528
+		// Convert back
2529
+		ROM[offset + 22] = BSMagic0;
2530
+		ROM[offset + 23] = BSMagic1;
2531
+	}
2532
+
2533
+	// NTSC/PAL
2534
+	if (Settings.ForceNTSC)
2535
+		Settings.PAL = false;
2536
+	else
2537
+	if (Settings.ForcePAL)
2538
+		Settings.PAL = true;
2539
+	else
2540
+	if (!Settings.BS && (ROMRegion >= 2) && (ROMRegion <= 12))
2541
+		Settings.PAL = true;
2542
+	else
2543
+		Settings.PAL = false;
2544
+
2545
+	if (Settings.PAL)
2546
+	{
2547
+		Settings.FrameTime = Settings.FrameTimePAL;
2548
+		ROMFramesPerSecond = 50;
2549
+	}
2550
+	else
2551
+	{
2552
+		Settings.FrameTime = Settings.FrameTimeNTSC;
2553
+		ROMFramesPerSecond = 60;
2554
+	}
2555
+
2556
+	// truncate cart name
2557
+	ROMName[ROM_NAME_LEN - 1] = 0;
2558
+	if (strlen(ROMName))
2559
+	{
2560
+		char *p = ROMName + strlen(ROMName);
2561
+		if (p > ROMName + 21 && ROMName[20] == ' ')
2562
+			p = ROMName + 21;
2563
+		while (p > ROMName && *(p - 1) == ' ')
2564
+			p--;
2565
+		*p = 0;
2566
+	}
2567
+
2568
+	// SRAM size
2569
+	SRAMMask = SRAMSize ? ((1 << (SRAMSize + 3)) * 128) - 1 : 0;
2570
+
2571
+	// checksum
2572
+	/*if (!isChecksumOK || ((uint32_t) CalculatedSize > (uint32_t) (((1 << (ROMSize - 7)) * 128) * 1024)))
2573
+	{
2574
+		Settings.DisplayColor = BUILD_PIXEL(31, 31, 0);
2575
+		SET_UI_COLOR(255, 255, 0);
2576
+	}*/
2577
+
2578
+	/*if (Multi.cartType == 4)
2579
+	{
2580
+		Settings.DisplayColor = BUILD_PIXEL(0, 16, 31);
2581
+		SET_UI_COLOR(0, 128, 255);
2582
+	}*/
2583
+
2584
+	//// Initialize emulation
2585
+
2586
+	Timings.H_Max_Master = SNES_CYCLES_PER_SCANLINE;
2587
+	Timings.H_Max        = Timings.H_Max_Master;
2588
+	Timings.HBlankStart  = SNES_HBLANK_START_HC;
2589
+	Timings.HBlankEnd    = SNES_HBLANK_END_HC;
2590
+	Timings.HDMAInit     = SNES_HDMA_INIT_HC;
2591
+	Timings.HDMAStart    = SNES_HDMA_START_HC;
2592
+	Timings.RenderPos    = SNES_RENDER_START_HC;
2593
+	Timings.V_Max_Master = Settings.PAL ? SNES_MAX_PAL_VCOUNTER : SNES_MAX_NTSC_VCOUNTER;
2594
+	Timings.V_Max        = Timings.V_Max_Master;
2595
+	/* From byuu: The total delay time for both the initial (H)DMA sync (to the DMA clock),
2596
+	   and the end (H)DMA sync (back to the last CPU cycle's mcycle rate (6, 8, or 12)) always takes between 12-24 mcycles.
2597
+	   Possible delays: { 12, 14, 16, 18, 20, 22, 24 }
2598
+	   XXX: Snes9x can't emulate this timing :( so let's use the average value... */
2599
+	Timings.DMACPUSync   = 18;
2600
+	/* If the CPU is halted (i.e. for DMA) while /NMI goes low, the NMI will trigger
2601
+	   after the DMA completes (even if /NMI goes high again before the DMA
2602
+	   completes). In this case, there is a 24-30 cycle delay between the end of DMA
2603
+	   and the NMI handler, time enough for an instruction or two. */
2604
+	// Wild Guns, Mighty Morphin Power Rangers - The Fighting Edition
2605
+	Timings.NMIDMADelay  = 24;
2606
+	Timings.IRQPendCount = 0;
2607
+
2608
+	IPPU.TotalEmulatedFrames = 0;
2609
+
2610
+	//// Hack games
2611
+
2612
+	ApplyROMFixes();
2613
+
2614
+	//// Show ROM information
2615
+	//char displayName[ROM_NAME_LEN];
2616
+
2617
+	strcpy(RawROMName, ROMName);
2618
+	//sprintf(displayName, "%s", SafeANK(ROMName));
2619
+	sprintf(ROMName, "%s", Safe(ROMName));
2620
+	sprintf(ROMId, "%s", Safe(ROMId));
2621
+
2622
+	/*sprintf(String, "\"%s\" [%s] %s, %s, %s, %s, SRAM:%s, ID:%s, CRC32:%08X",
2623
+		displayName, isChecksumOK ? "checksum ok" : ((Multi.cartType == 4) ? "no checksum" : "bad checksum"),
2624
+		MapType(), Size(), KartContents(), Settings.PAL ? "PAL" : "NTSC", StaticRAMSize(), ROMId, ROMCRC32);*/
2625
+	//S9xMessage(S9X_INFO, S9X_ROM_INFO, String);
2626
+
2627
+	Settings.ForceLoROM = false;
2628
+	Settings.ForceHiROM = false;
2629
+	Settings.ForceHeader = false;
2630
+	Settings.ForceNoHeader = false;
2631
+	Settings.ForceInterleaved = false;
2632
+	Settings.ForceInterleaved2 = false;
2633
+	Settings.ForceInterleaveGD24 = false;
2634
+	Settings.ForceNotInterleaved = false;
2635
+	Settings.ForcePAL = false;
2636
+	Settings.ForceNTSC = false;
2637
+
2638
+	Settings.TakeScreenshot = false;
2639
+
2640
+	/*if (stopMovie)
2641
+		S9xMovieStop(true);*/
2642
+
2643
+	if (PostRomInitFunc)
2644
+		PostRomInitFunc();
2645
+
2646
+    //S9xVerifyControllers();
2647
+}
2648
+
2649
+// memory map
2650
+
2651
+uint32_t CMemory::map_mirror (uint32_t size, uint32_t pos)
2652
+{
2653
+	// from bsnes
2654
+	if (size == 0)
2655
+		return 0;
2656
+	if (pos < size)
2657
+		return pos;
2658
+
2659
+	uint32_t	mask = 1 << 31;
2660
+	while (!(pos & mask))
2661
+		mask >>= 1;
2662
+
2663
+	if (size <= (pos & mask))
2664
+		return map_mirror(size, pos - mask);
2665
+	else
2666
+		return mask + map_mirror(size - mask, pos - mask);
2667
+}
2668
+
2669
+void CMemory::map_lorom (uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, uint32_t size)
2670
+{
2671
+	uint32_t	c, i, p, addr;
2672
+
2673
+	for (c = bank_s; c <= bank_e; c++)
2674
+	{
2675
+		for (i = addr_s; i <= addr_e; i += 0x1000)
2676
+		{
2677
+			p = (c << 4) | (i >> 12);
2678
+			addr = (c & 0x7f) * 0x8000;
2679
+			Map[p] = ROM + map_mirror(size, addr) - (i & 0x8000);
2680
+			BlockIsROM[p] = true;
2681
+			BlockIsRAM[p] = false;
2682
+		}
2683
+	}
2684
+}
2685
+
2686
+void CMemory::map_hirom (uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, uint32_t size)
2687
+{
2688
+	uint32_t	c, i, p, addr;
2689
+
2690
+	for (c = bank_s; c <= bank_e; c++)
2691
+	{
2692
+		for (i = addr_s; i <= addr_e; i += 0x1000)
2693
+		{
2694
+			p = (c << 4) | (i >> 12);
2695
+			addr = c << 16;
2696
+			Map[p] = ROM + map_mirror(size, addr);
2697
+			BlockIsROM[p] = true;
2698
+			BlockIsRAM[p] = false;
2699
+		}
2700
+	}
2701
+}
2702
+
2703
+void CMemory::map_lorom_offset (uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, uint32_t size, uint32_t offset)
2704
+{
2705
+	uint32_t	c, i, p, addr;
2706
+
2707
+	for (c = bank_s; c <= bank_e; c++)
2708
+	{
2709
+		for (i = addr_s; i <= addr_e; i += 0x1000)
2710
+		{
2711
+			p = (c << 4) | (i >> 12);
2712
+			addr = ((c - bank_s) & 0x7f) * 0x8000;
2713
+			Map[p] = ROM + offset + map_mirror(size, addr) - (i & 0x8000);
2714
+			BlockIsROM[p] = true;
2715
+			BlockIsRAM[p] = false;
2716
+		}
2717
+	}
2718
+}
2719
+
2720
+void CMemory::map_hirom_offset (uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, uint32_t size, uint32_t offset)
2721
+{
2722
+	uint32_t	c, i, p, addr;
2723
+
2724
+	for (c = bank_s; c <= bank_e; c++)
2725
+	{
2726
+		for (i = addr_s; i <= addr_e; i += 0x1000)
2727
+		{
2728
+			p = (c << 4) | (i >> 12);
2729
+			addr = (c - bank_s) << 16;
2730
+			Map[p] = ROM + offset + map_mirror(size, addr);
2731
+			BlockIsROM[p] = true;
2732
+			BlockIsRAM[p] = false;
2733
+		}
2734
+	}
2735
+}
2736
+
2737
+void CMemory::map_space (uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, uint8_t *data)
2738
+{
2739
+	uint32_t	c, i, p;
2740
+
2741
+	for (c = bank_s; c <= bank_e; c++)
2742
+	{
2743
+		for (i = addr_s; i <= addr_e; i += 0x1000)
2744
+		{
2745
+			p = (c << 4) | (i >> 12);
2746
+			Map[p] = data;
2747
+			BlockIsROM[p] = false;
2748
+			BlockIsRAM[p] = true;
2749
+		}
2750
+	}
2751
+}
2752
+
2753
+void CMemory::map_index (uint32_t bank_s, uint32_t bank_e, uint32_t addr_s, uint32_t addr_e, int index, int type)
2754
+{
2755
+	uint32_t	c, i, p;
2756
+	bool	isROM, isRAM;
2757
+
2758
+	isROM = ((type == MAP_TYPE_I_O) || (type == MAP_TYPE_RAM)) ? false : true;
2759
+	isRAM = ((type == MAP_TYPE_I_O) || (type == MAP_TYPE_ROM)) ? false : true;
2760
+
2761
+	for (c = bank_s; c <= bank_e; c++)
2762
+	{
2763
+		for (i = addr_s; i <= addr_e; i += 0x1000)
2764
+		{
2765
+			p = (c << 4) | (i >> 12);
2766
+			Map[p] = (uint8_t *) index;
2767
+			BlockIsROM[p] = isROM;
2768
+			BlockIsRAM[p] = isRAM;
2769
+		}
2770
+	}
2771
+}
2772
+
2773
+void CMemory::map_System()
2774
+{
2775
+	// will be overwritten
2776
+	map_space(0x00, 0x3f, 0x0000, 0x1fff, RAM);
2777
+	map_index(0x00, 0x3f, 0x2000, 0x3fff, MAP_PPU, MAP_TYPE_I_O);
2778
+	map_index(0x00, 0x3f, 0x4000, 0x5fff, MAP_CPU, MAP_TYPE_I_O);
2779
+	map_space(0x80, 0xbf, 0x0000, 0x1fff, RAM);
2780
+	map_index(0x80, 0xbf, 0x2000, 0x3fff, MAP_PPU, MAP_TYPE_I_O);
2781
+	map_index(0x80, 0xbf, 0x4000, 0x5fff, MAP_CPU, MAP_TYPE_I_O);
2782
+}
2783
+
2784
+void CMemory::map_WRAM()
2785
+{
2786
+	// will overwrite others
2787
+	map_space(0x7e, 0x7e, 0x0000, 0xffff, RAM);
2788
+	map_space(0x7f, 0x7f, 0x0000, 0xffff, RAM + 0x10000);
2789
+}
2790
+
2791
+void CMemory::map_LoROMSRAM()
2792
+{
2793
+	map_index(0x70, 0x7f, 0x0000, 0x7fff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
2794
+	map_index(0xf0, 0xff, 0x0000, 0x7fff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
2795
+}
2796
+
2797
+void CMemory::map_HiROMSRAM()
2798
+{
2799
+	map_index(0x20, 0x3f, 0x6000, 0x7fff, MAP_HIROM_SRAM, MAP_TYPE_RAM);
2800
+	map_index(0xa0, 0xbf, 0x6000, 0x7fff, MAP_HIROM_SRAM, MAP_TYPE_RAM);
2801
+}
2802
+
2803
+/*void CMemory::map_DSP()
2804
+{
2805
+	switch (DSP0.maptype)
2806
+	{
2807
+		case M_DSP1_LOROM_S:
2808
+			map_index(0x20, 0x3f, 0x8000, 0xffff, MAP_DSP, MAP_TYPE_I_O);
2809
+			map_index(0xa0, 0xbf, 0x8000, 0xffff, MAP_DSP, MAP_TYPE_I_O);
2810
+			break;
2811
+
2812
+		case M_DSP1_LOROM_L:
2813
+			map_index(0x60, 0x6f, 0x0000, 0x7fff, MAP_DSP, MAP_TYPE_I_O);
2814
+			map_index(0xe0, 0xef, 0x0000, 0x7fff, MAP_DSP, MAP_TYPE_I_O);
2815
+			break;
2816
+
2817
+		case M_DSP1_HIROM:
2818
+			map_index(0x00, 0x1f, 0x6000, 0x7fff, MAP_DSP, MAP_TYPE_I_O);
2819
+			map_index(0x80, 0x9f, 0x6000, 0x7fff, MAP_DSP, MAP_TYPE_I_O);
2820
+			break;
2821
+
2822
+		case M_DSP2_LOROM:
2823
+			map_index(0x20, 0x3f, 0x6000, 0x6fff, MAP_DSP, MAP_TYPE_I_O);
2824
+			map_index(0x20, 0x3f, 0x8000, 0xbfff, MAP_DSP, MAP_TYPE_I_O);
2825
+			map_index(0xa0, 0xbf, 0x6000, 0x6fff, MAP_DSP, MAP_TYPE_I_O);
2826
+			map_index(0xa0, 0xbf, 0x8000, 0xbfff, MAP_DSP, MAP_TYPE_I_O);
2827
+			break;
2828
+
2829
+		case M_DSP3_LOROM:
2830
+			map_index(0x20, 0x3f, 0x8000, 0xffff, MAP_DSP, MAP_TYPE_I_O);
2831
+			map_index(0xa0, 0xbf, 0x8000, 0xffff, MAP_DSP, MAP_TYPE_I_O);
2832
+			break;
2833
+
2834
+		case M_DSP4_LOROM:
2835
+			map_index(0x30, 0x3f, 0x8000, 0xffff, MAP_DSP, MAP_TYPE_I_O);
2836
+			map_index(0xb0, 0xbf, 0x8000, 0xffff, MAP_DSP, MAP_TYPE_I_O);
2837
+			break;
2838
+	}
2839
+}*/
2840
+
2841
+/*void CMemory::map_C4()
2842
+{
2843
+	map_index(0x00, 0x3f, 0x6000, 0x7fff, MAP_C4, MAP_TYPE_I_O);
2844
+	map_index(0x80, 0xbf, 0x6000, 0x7fff, MAP_C4, MAP_TYPE_I_O);
2845
+}*/
2846
+
2847
+/*void CMemory::map_OBC1()
2848
+{
2849
+	map_index(0x00, 0x3f, 0x6000, 0x7fff, MAP_OBC_RAM, MAP_TYPE_I_O);
2850
+	map_index(0x80, 0xbf, 0x6000, 0x7fff, MAP_OBC_RAM, MAP_TYPE_I_O);
2851
+}*/
2852
+
2853
+/*void CMemory::map_SetaRISC()
2854
+{
2855
+	map_index(0x00, 0x3f, 0x3000, 0x3fff, MAP_SETA_RISC, MAP_TYPE_I_O);
2856
+	map_index(0x80, 0xbf, 0x3000, 0x3fff, MAP_SETA_RISC, MAP_TYPE_I_O);
2857
+}*/
2858
+
2859
+/*void CMemory::map_SetaDSP()
2860
+{
2861
+	// where does the SETA chip access, anyway?
2862
+	// please confirm this?
2863
+	map_index(0x68, 0x6f, 0x0000, 0x7fff, MAP_SETA_DSP, MAP_TYPE_RAM);
2864
+	// and this!
2865
+	map_index(0x60, 0x67, 0x0000, 0x3fff, MAP_SETA_DSP, MAP_TYPE_I_O);
2866
+
2867
+	// ST-0010:
2868
+	// map_index(0x68, 0x6f, 0x0000, 0x0fff, MAP_SETA_DSP, ?);
2869
+}*/
2870
+
2871
+void CMemory::map_WriteProtectROM()
2872
+{
2873
+	memmove((void *) WriteMap, (void *) Map, sizeof(Map));
2874
+
2875
+	for (int c = 0; c < 0x1000; c++)
2876
+	{
2877
+		if (BlockIsROM[c])
2878
+			WriteMap[c] = (uint8_t *) MAP_NONE;
2879
+	}
2880
+}
2881
+
2882
+void CMemory::Map_Initialize()
2883
+{
2884
+	for (int c = 0; c < 0x1000; c++)
2885
+	{
2886
+		Map[c]      = (uint8_t *) MAP_NONE;
2887
+		WriteMap[c] = (uint8_t *) MAP_NONE;
2888
+		BlockIsROM[c] = false;
2889
+		BlockIsRAM[c] = false;
2890
+	}
2891
+}
2892
+
2893
+void CMemory::Map_LoROMMap()
2894
+{
2895
+	printf("Map_LoROMMap\n");
2896
+	map_System();
2897
+
2898
+	map_lorom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize);
2899
+	map_lorom(0x40, 0x7f, 0x0000, 0xffff, CalculatedSize);
2900
+	map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize);
2901
+	map_lorom(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize);
2902
+
2903
+	/*if (Settings.DSP)
2904
+		map_DSP();
2905
+	else
2906
+	if (Settings.C4)
2907
+		map_C4();
2908
+	else
2909
+	if (Settings.OBC1)
2910
+		map_OBC1();
2911
+	else
2912
+	if (Settings.SETA == ST_018)
2913
+		map_SetaRISC();*/
2914
+
2915
+    map_LoROMSRAM();
2916
+	map_WRAM();
2917
+
2918
+	map_WriteProtectROM();
2919
+}
2920
+
2921
+void CMemory::Map_NoMAD1LoROMMap()
2922
+{
2923
+	printf("Map_NoMAD1LoROMMap\n");
2924
+	map_System();
2925
+
2926
+	map_lorom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize);
2927
+	map_lorom(0x40, 0x7f, 0x0000, 0xffff, CalculatedSize);
2928
+	map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize);
2929
+	map_lorom(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize);
2930
+
2931
+	map_index(0x70, 0x7f, 0x0000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
2932
+	map_index(0xf0, 0xff, 0x0000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
2933
+
2934
+	map_WRAM();
2935
+
2936
+	map_WriteProtectROM();
2937
+}
2938
+
2939
+void CMemory::Map_JumboLoROMMap()
2940
+{
2941
+	// XXX: Which game uses this?
2942
+	printf("Map_JumboLoROMMap\n");
2943
+	map_System();
2944
+
2945
+	map_lorom_offset(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize - 0x400000, 0x400000);
2946
+	map_lorom_offset(0x40, 0x7f, 0x0000, 0xffff, CalculatedSize - 0x400000, 0x400000);
2947
+	map_lorom_offset(0x80, 0xbf, 0x8000, 0xffff, 0x400000, 0);
2948
+	map_lorom_offset(0xc0, 0xff, 0x0000, 0xffff, 0x400000, 0x200000);
2949
+
2950
+	map_LoROMSRAM();
2951
+	map_WRAM();
2952
+
2953
+	map_WriteProtectROM();
2954
+}
2955
+
2956
+void CMemory::Map_ROM24MBSLoROMMap()
2957
+{
2958
+	// PCB: BSC-1A5M-01, BSC-1A7M-10
2959
+	printf("Map_ROM24MBSLoROMMap\n");
2960
+	map_System();
2961
+
2962
+	map_lorom_offset(0x00, 0x1f, 0x8000, 0xffff, 0x100000, 0);
2963
+	map_lorom_offset(0x20, 0x3f, 0x8000, 0xffff, 0x100000, 0x100000);
2964
+	map_lorom_offset(0x80, 0x9f, 0x8000, 0xffff, 0x100000, 0x200000);
2965
+	map_lorom_offset(0xa0, 0xbf, 0x8000, 0xffff, 0x100000, 0x100000);
2966
+
2967
+	map_LoROMSRAM();
2968
+	map_WRAM();
2969
+
2970
+	map_WriteProtectROM();
2971
+}
2972
+
2973
+void CMemory::Map_SRAM512KLoROMMap()
2974
+{
2975
+	printf("Map_SRAM512KLoROMMap\n");
2976
+	map_System();
2977
+
2978
+	map_lorom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize);
2979
+	map_lorom(0x40, 0x7f, 0x0000, 0xffff, CalculatedSize);
2980
+	map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize);
2981
+	map_lorom(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize);
2982
+
2983
+	map_space(0x70, 0x70, 0x0000, 0xffff, SRAM);
2984
+	map_space(0x71, 0x71, 0x0000, 0xffff, SRAM + 0x8000);
2985
+	map_space(0x72, 0x72, 0x0000, 0xffff, SRAM + 0x10000);
2986
+	map_space(0x73, 0x73, 0x0000, 0xffff, SRAM + 0x18000);
2987
+
2988
+	map_WRAM();
2989
+
2990
+	map_WriteProtectROM();
2991
+}
2992
+
2993
+/*void CMemory::Map_SufamiTurboLoROMMap()
2994
+{
2995
+	printf("Map_SufamiTurboLoROMMap\n");
2996
+	map_System();
2997
+
2998
+	map_lorom_offset(0x00, 0x1f, 0x8000, 0xffff, 0x40000, 0);
2999
+	map_lorom_offset(0x20, 0x3f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
3000
+	map_lorom_offset(0x40, 0x5f, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
3001
+	map_lorom_offset(0x80, 0x9f, 0x8000, 0xffff, 0x40000, 0);
3002
+	map_lorom_offset(0xa0, 0xbf, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
3003
+	map_lorom_offset(0xc0, 0xdf, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
3004
+
3005
+	if (Multi.sramSizeA)
3006
+	{
3007
+		map_index(0x60, 0x63, 0x8000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
3008
+		map_index(0xe0, 0xe3, 0x8000, 0xffff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
3009
+	}
3010
+
3011
+	if (Multi.sramSizeB)
3012
+	{
3013
+		map_index(0x70, 0x73, 0x8000, 0xffff, MAP_LOROM_SRAM_B, MAP_TYPE_RAM);
3014
+		map_index(0xf0, 0xf3, 0x8000, 0xffff, MAP_LOROM_SRAM_B, MAP_TYPE_RAM);
3015
+	}
3016
+
3017
+	map_WRAM();
3018
+
3019
+	map_WriteProtectROM();
3020
+}*/
3021
+
3022
+/*void CMemory::Map_SufamiTurboPseudoLoROMMap()
3023
+{
3024
+	// for combined images
3025
+	printf("Map_SufamiTurboPseudoLoROMMap\n");
3026
+	map_System();
3027
+
3028
+	map_lorom_offset(0x00, 0x1f, 0x8000, 0xffff, 0x40000, 0);
3029
+	map_lorom_offset(0x20, 0x3f, 0x8000, 0xffff, 0x100000, 0x100000);
3030
+	map_lorom_offset(0x40, 0x5f, 0x8000, 0xffff, 0x100000, 0x200000);
3031
+	map_lorom_offset(0x80, 0x9f, 0x8000, 0xffff, 0x40000, 0);
3032
+	map_lorom_offset(0xa0, 0xbf, 0x8000, 0xffff, 0x100000, 0x100000);
3033
+	map_lorom_offset(0xc0, 0xdf, 0x8000, 0xffff, 0x100000, 0x200000);
3034
+
3035
+	// I don't care :P
3036
+	map_space(0x60, 0x63, 0x8000, 0xffff, SRAM - 0x8000);
3037
+	map_space(0xe0, 0xe3, 0x8000, 0xffff, SRAM - 0x8000);
3038
+	map_space(0x70, 0x73, 0x8000, 0xffff, SRAM + 0x4000 - 0x8000);
3039
+	map_space(0xf0, 0xf3, 0x8000, 0xffff, SRAM + 0x4000 - 0x8000);
3040
+
3041
+	map_WRAM();
3042
+
3043
+	map_WriteProtectROM();
3044
+}*/
3045
+
3046
+/*void CMemory::Map_SuperFXLoROMMap()
3047
+{
3048
+	printf("Map_SuperFXLoROMMap\n");
3049
+	map_System();
3050
+
3051
+	// Replicate the first 2Mb of the ROM at ROM + 2MB such that each 32K
3052
+	// block is repeated twice in each 64K block.
3053
+	for (int c = 0; c < 64; c++)
3054
+	{
3055
+		memmove(&ROM[0x200000 + c * 0x10000], &ROM[c * 0x8000], 0x8000);
3056
+		memmove(&ROM[0x208000 + c * 0x10000], &ROM[c * 0x8000], 0x8000);
3057
+	}
3058
+
3059
+	map_lorom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize);
3060
+	map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize);
3061
+
3062
+	map_hirom_offset(0x40, 0x7f, 0x0000, 0xffff, CalculatedSize, 0);
3063
+	map_hirom_offset(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize, 0);
3064
+
3065
+	map_space(0x00, 0x3f, 0x6000, 0x7fff, SRAM - 0x6000);
3066
+	map_space(0x80, 0xbf, 0x6000, 0x7fff, SRAM - 0x6000);
3067
+	map_space(0x70, 0x70, 0x0000, 0xffff, SRAM);
3068
+	map_space(0x71, 0x71, 0x0000, 0xffff, SRAM + 0x10000);
3069
+
3070
+	map_WRAM();
3071
+
3072
+	map_WriteProtectROM();
3073
+}*/
3074
+
3075
+/*void CMemory::Map_SetaDSPLoROMMap()
3076
+{
3077
+	printf("Map_SetaDSPLoROMMap\n");
3078
+	map_System();
3079
+
3080
+	map_lorom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize);
3081
+	map_lorom(0x40, 0x7f, 0x8000, 0xffff, CalculatedSize);
3082
+	map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize);
3083
+	map_lorom(0xc0, 0xff, 0x8000, 0xffff, CalculatedSize);
3084
+
3085
+	map_SetaDSP();
3086
+
3087
+    map_LoROMSRAM();
3088
+	map_WRAM();
3089
+
3090
+	map_WriteProtectROM();
3091
+}*/
3092
+
3093
+void CMemory::Map_SDD1LoROMMap()
3094
+{
3095
+	printf("Map_SDD1LoROMMap\n");
3096
+	map_System();
3097
+
3098
+	map_lorom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize);
3099
+	map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize);
3100
+
3101
+	map_hirom_offset(0x40, 0x7f, 0x0000, 0xffff, CalculatedSize, 0);
3102
+	map_hirom_offset(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize, 0); // will be overwritten dynamically
3103
+
3104
+	map_index(0x70, 0x7f, 0x0000, 0x7fff, MAP_LOROM_SRAM, MAP_TYPE_RAM);
3105
+
3106
+	map_WRAM();
3107
+
3108
+	map_WriteProtectROM();
3109
+}
3110
+
3111
+/*void CMemory::Map_SA1LoROMMap()
3112
+{
3113
+	printf("Map_SA1LoROMMap\n");
3114
+	map_System();
3115
+
3116
+	map_lorom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize);
3117
+	map_lorom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize);
3118
+
3119
+	map_hirom_offset(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize, 0);
3120
+
3121
+	map_space(0x00, 0x3f, 0x3000, 0x3fff, FillRAM);
3122
+	map_space(0x80, 0xbf, 0x3000, 0x3fff, FillRAM);
3123
+	map_index(0x00, 0x3f, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O);
3124
+	map_index(0x80, 0xbf, 0x6000, 0x7fff, MAP_BWRAM, MAP_TYPE_I_O);
3125
+
3126
+	for (int c = 0x40; c < 0x80; c++)
3127
+		map_space(c, c, 0x0000, 0xffff, SRAM + (c & 1) * 0x10000);
3128
+
3129
+	map_WRAM();
3130
+
3131
+	map_WriteProtectROM();
3132
+
3133
+	// Now copy the map and correct it for the SA1 CPU.
3134
+	memmove((void *) SA1.Map, (void *) Map, sizeof(Map));
3135
+	memmove((void *) SA1.WriteMap, (void *) WriteMap, sizeof(WriteMap));
3136
+
3137
+	// SA-1 Banks 00->3f and 80->bf
3138
+	for (int c = 0x000; c < 0x400; c += 0x10)
3139
+	{
3140
+		SA1.Map[c + 0] = SA1.Map[c + 0x800] = FillRAM + 0x3000;
3141
+		SA1.Map[c + 1] = SA1.Map[c + 0x801] = (uint8_t *) MAP_NONE;
3142
+		SA1.WriteMap[c + 0] = SA1.WriteMap[c + 0x800] = FillRAM + 0x3000;
3143
+		SA1.WriteMap[c + 1] = SA1.WriteMap[c + 0x801] = (uint8_t *) MAP_NONE;
3144
+	}
3145
+
3146
+	// SA-1 Banks 60->6f
3147
+	for (int c = 0x600; c < 0x700; c++)
3148
+		SA1.Map[c] = SA1.WriteMap[c] = (uint8_t *) MAP_BWRAM_BITMAP;
3149
+
3150
+	BWRAM = SRAM;
3151
+}*/
3152
+
3153
+void CMemory::Map_HiROMMap()
3154
+{
3155
+	printf("Map_HiROMMap\n");
3156
+	map_System();
3157
+
3158
+	map_hirom(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize);
3159
+	map_hirom(0x40, 0x7f, 0x0000, 0xffff, CalculatedSize);
3160
+	map_hirom(0x80, 0xbf, 0x8000, 0xffff, CalculatedSize);
3161
+	map_hirom(0xc0, 0xff, 0x0000, 0xffff, CalculatedSize);
3162
+
3163
+	/*if (Settings.DSP)
3164
+		map_DSP();*/
3165
+
3166
+	map_HiROMSRAM();
3167
+	map_WRAM();
3168
+
3169
+	map_WriteProtectROM();
3170
+}
3171
+
3172
+void CMemory::Map_ExtendedHiROMMap()
3173
+{
3174
+	printf("Map_ExtendedHiROMMap\n");
3175
+	map_System();
3176
+
3177
+	map_hirom_offset(0x00, 0x3f, 0x8000, 0xffff, CalculatedSize - 0x400000, 0x400000);
3178
+	map_hirom_offset(0x40, 0x7f, 0x0000, 0xffff, CalculatedSize - 0x400000, 0x400000);
3179
+	map_hirom_offset(0x80, 0xbf, 0x8000, 0xffff, 0x400000, 0);
3180
+	map_hirom_offset(0xc0, 0xff, 0x0000, 0xffff, 0x400000, 0);
3181
+
3182
+	map_HiROMSRAM();
3183
+	map_WRAM();
3184
+
3185
+	map_WriteProtectROM();
3186
+}
3187
+
3188
+/*void CMemory::Map_SameGameHiROMMap()
3189
+{
3190
+	printf("Map_SameGameHiROMMap\n");
3191
+	map_System();
3192
+
3193
+	map_hirom_offset(0x00, 0x1f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
3194
+	map_hirom_offset(0x20, 0x3f, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
3195
+	map_hirom_offset(0x40, 0x5f, 0x0000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
3196
+	map_hirom_offset(0x60, 0x7f, 0x0000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
3197
+	map_hirom_offset(0x80, 0x9f, 0x8000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
3198
+	map_hirom_offset(0xa0, 0xbf, 0x8000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
3199
+	map_hirom_offset(0xc0, 0xdf, 0x0000, 0xffff, Multi.cartSizeA, Multi.cartOffsetA);
3200
+	map_hirom_offset(0xe0, 0xff, 0x0000, 0xffff, Multi.cartSizeB, Multi.cartOffsetB);
3201
+
3202
+	map_HiROMSRAM();
3203
+	map_WRAM();
3204
+
3205
+	map_WriteProtectROM();
3206
+}*/
3207
+
3208
+/*void CMemory::Map_SPC7110HiROMMap()
3209
+{
3210
+	printf("Map_SPC7110HiROMMap\n");
3211
+	map_System();
3212
+
3213
+	map_index(0x00, 0x00, 0x6000, 0x7fff, MAP_HIROM_SRAM, MAP_TYPE_RAM);
3214
+	map_hirom(0x00, 0x0f, 0x8000, 0xffff, CalculatedSize);
3215
+	map_index(0x30, 0x30, 0x6000, 0x7fff, MAP_HIROM_SRAM, MAP_TYPE_RAM);
3216
+	map_index(0x50, 0x50, 0x0000, 0xffff, MAP_SPC7110_DRAM, MAP_TYPE_ROM);
3217
+	map_hirom(0x80, 0x8f, 0x8000, 0xffff, CalculatedSize);
3218
+	map_hirom_offset(0xc0, 0xcf, 0x0000, 0xffff, CalculatedSize, 0);
3219
+	map_index(0xd0, 0xff, 0x0000, 0xffff, MAP_SPC7110_ROM,  MAP_TYPE_ROM);
3220
+
3221
+	map_WRAM();
3222
+
3223
+	map_WriteProtectROM();
3224
+}*/
3225
+
3226
+// checksum
3227
+
3228
+uint16_t CMemory::checksum_calc_sum (uint8_t *data, uint32_t length)
3229
+{
3230
+	uint16_t	sum = 0;
3231
+
3232
+	for (uint32_t i = 0; i < length; i++)
3233
+		sum += data[i];
3234
+
3235
+	return sum;
3236
+}
3237
+
3238
+uint16_t CMemory::checksum_mirror_sum (uint8_t *start, uint32_t &length, uint32_t mask)
3239
+{
3240
+	// from NSRT
3241
+	while (!(length & mask))
3242
+		mask >>= 1;
3243
+
3244
+	uint16_t	part1 = checksum_calc_sum(start, mask);
3245
+	uint16_t	part2 = 0;
3246
+
3247
+	uint32_t	next_length = length - mask;
3248
+	if (next_length)
3249
+	{
3250
+		part2 = checksum_mirror_sum(start + mask, next_length, mask >> 1);
3251
+
3252
+		while (next_length < mask)
3253
+		{
3254
+			next_length += next_length;
3255
+			part2 += part2;
3256
+		}
3257
+
3258
+		length = mask + mask;
3259
+	}
3260
+
3261
+	return part1 + part2;
3262
+}
3263
+
3264
+void CMemory::Checksum_Calculate()
3265
+{
3266
+	// from NSRT
3267
+	uint16_t	sum = 0;
3268
+
3269
+	if (Settings.BS && !Settings.BSXItself)
3270
+		sum = checksum_calc_sum(ROM, CalculatedSize) - checksum_calc_sum(ROM + (HiROM ? 0xffb0 : 0x7fb0), 48);
3271
+	else
3272
+	if (Settings.SPC7110)
3273
+	{
3274
+		sum = checksum_calc_sum(ROM, CalculatedSize);
3275
+		if (CalculatedSize == 0x300000)
3276
+			sum += sum;
3277
+	}
3278
+	else
3279
+	{
3280
+		if (CalculatedSize & 0x7fff)
3281
+			sum = checksum_calc_sum(ROM, CalculatedSize);
3282
+		else
3283
+		{
3284
+			uint32_t	length = CalculatedSize;
3285
+			sum = checksum_mirror_sum(ROM, length);
3286
+		}
3287
+	}
3288
+
3289
+	CalculatedChecksum = sum;
3290
+}
3291
+
3292
+// information
3293
+
3294
+/*const char * CMemory::MapType()
3295
+{
3296
+	return HiROM ? ((ExtendedFormat != NOPE) ? "ExHiROM": "HiROM") : "LoROM";
3297
+}*/
3298
+
3299
+/*const char * CMemory::StaticRAMSize()
3300
+{
3301
+	static char	str[20];
3302
+
3303
+	if (SRAMSize > 16)
3304
+		strcpy(str, "Corrupt");
3305
+	else
3306
+		sprintf(str, "%dKbits", 8 * (SRAMMask + 1) / 1024);
3307
+
3308
+	return str;
3309
+}*/
3310
+
3311
+/*const char * CMemory::Size()
3312
+{
3313
+	static char	str[20];
3314
+
3315
+	if (Multi.cartType == 4)
3316
+		strcpy(str, "N/A");
3317
+	else
3318
+	if (ROMSize < 7 || ROMSize - 7 > 23)
3319
+		strcpy(str, "Corrupt");
3320
+	else
3321
+		sprintf(str, "%dMbits", 1 << (ROMSize - 7));
3322
+
3323
+	return str;
3324
+}*/
3325
+
3326
+/*const char * CMemory::Revision()
3327
+{
3328
+	static char	str[20];
3329
+
3330
+	sprintf(str, "1.%d", HiROM ? ((ExtendedFormat != NOPE) ? ROM[0x40ffdb] : ROM[0xffdb]) : ROM[0x7fdb]);
3331
+
3332
+	return str;
3333
+}*/
3334
+
3335
+/*const char * CMemory::KartContents()
3336
+{
3337
+	static char			str[64];
3338
+	static const char	*contents[3] = { "ROM", "ROM+RAM", "ROM+RAM+BAT" };
3339
+
3340
+	char	chip[16];
3341
+
3342
+	if (ROMType == 0 && !Settings.BS)
3343
+		return "ROM";
3344
+
3345
+	if (Settings.BS)
3346
+		strcpy(chip, "+BS");
3347
+	else
3348
+	if (Settings.SuperFX)
3349
+		strcpy(chip, "+Super FX");
3350
+	else
3351
+	if (Settings.SDD1)
3352
+		strcpy(chip, "+S-DD1");
3353
+	else
3354
+	if (Settings.OBC1)
3355
+		strcpy(chip, "+OBC1");
3356
+	else
3357
+	if (Settings.SA1)
3358
+		strcpy(chip, "+SA-1");
3359
+	else
3360
+	if (Settings.SPC7110RTC)
3361
+		strcpy(chip, "+SPC7110+RTC");
3362
+	else
3363
+	if (Settings.SPC7110)
3364
+		strcpy(chip, "+SPC7110");
3365
+	else
3366
+	if (Settings.SRTC)
3367
+		strcpy(chip, "+S-RTC");
3368
+	else
3369
+	if (Settings.C4)
3370
+		strcpy(chip, "+C4");
3371
+	else
3372
+	if (Settings.SETA == ST_010)
3373
+		strcpy(chip, "+ST-010");
3374
+	else
3375
+	if (Settings.SETA == ST_011)
3376
+		strcpy(chip, "+ST-011");
3377
+	else
3378
+	if (Settings.SETA == ST_018)
3379
+		strcpy(chip, "+ST-018");
3380
+	else
3381
+	if (Settings.DSP)
3382
+		sprintf(chip, "+DSP-%d", Settings.DSP);
3383
+	else
3384
+		strcpy(chip, "");
3385
+
3386
+	sprintf(str, "%s%s", contents[(ROMType & 0xf) % 3], chip);
3387
+
3388
+	return str;
3389
+}*/
3390
+
3391
+/*const char * CMemory::Country()
3392
+{
3393
+	switch (ROMRegion)
3394
+	{
3395
+		case 0:		return "Japan";
3396
+		case 1:		return "USA and Canada";
3397
+		case 2:		return "Oceania, Europe and Asia";
3398
+		case 3:		return "Sweden";
3399
+		case 4:		return "Finland";
3400
+		case 5:		return "Denmark";
3401
+		case 6:		return "France";
3402
+		case 7:		return "Holland";
3403
+		case 8:		return "Spain";
3404
+		case 9:		return "Germany, Austria and Switzerland";
3405
+		case 10:	return "Italy";
3406
+		case 11:	return "Hong Kong and China";
3407
+		case 12:	return "Indonesia";
3408
+		case 13:	return "South Korea";
3409
+		default:	return "Unknown";
3410
+	}
3411
+}*/
3412
+
3413
+/*const char * CMemory::PublishingCompany()
3414
+{
3415
+	if (CompanyId >= (int) (sizeof(nintendo_licensees) / sizeof(nintendo_licensees[0])) || CompanyId < 0)
3416
+		return "Unknown";
3417
+
3418
+	if (nintendo_licensees[CompanyId] == NULL)
3419
+		return "Unknown";
3420
+
3421
+	return nintendo_licensees[CompanyId];
3422
+}*/
3423
+
3424
+/*void CMemory::MakeRomInfoText (char *romtext)
3425
+{
3426
+	char	temp[256];
3427
+
3428
+	romtext[0] = 0;
3429
+
3430
+	sprintf(temp,   "            Cart Name: %s", ROMName);
3431
+	strcat(romtext, temp);
3432
+	sprintf(temp, "\n            Game Code: %s", ROMId);
3433
+	strcat(romtext, temp);
3434
+	sprintf(temp, "\n             Contents: %s", KartContents());
3435
+	strcat(romtext, temp);
3436
+	sprintf(temp, "\n                  Map: %s", MapType());
3437
+	strcat(romtext, temp);
3438
+	sprintf(temp, "\n                Speed: 0x%02X (%s)", ROMSpeed, (ROMSpeed & 0x10) ? "FastROM" : "SlowROM");
3439
+	strcat(romtext, temp);
3440
+	sprintf(temp, "\n                 Type: 0x%02X", ROMType);
3441
+	strcat(romtext, temp);
3442
+	sprintf(temp, "\n    Size (calculated): %dMbits", CalculatedSize / 0x20000);
3443
+	strcat(romtext, temp);
3444
+	sprintf(temp, "\n        Size (header): %s", Size());
3445
+	strcat(romtext, temp);
3446
+	sprintf(temp, "\n            SRAM size: %s", StaticRAMSize());
3447
+	strcat(romtext, temp);
3448
+	sprintf(temp, "\nChecksum (calculated): 0x%04X", CalculatedChecksum);
3449
+	strcat(romtext, temp);
3450
+	sprintf(temp, "\n    Checksum (header): 0x%04X", ROMChecksum);
3451
+	strcat(romtext, temp);
3452
+	sprintf(temp, "\n  Complement (header): 0x%04X", ROMComplementChecksum);
3453
+	strcat(romtext, temp);
3454
+	sprintf(temp, "\n         Video Output: %s", (ROMRegion > 12 || ROMRegion < 2) ? "NTSC 60Hz" : "PAL 50Hz");
3455
+	strcat(romtext, temp);
3456
+	sprintf(temp, "\n             Revision: %s", Revision());
3457
+	strcat(romtext, temp);
3458
+	sprintf(temp, "\n             Licensee: %s", PublishingCompany());
3459
+	strcat(romtext, temp);
3460
+	sprintf(temp, "\n               Region: %s", Country());
3461
+	strcat(romtext, temp);
3462
+	sprintf(temp, "\n                CRC32: 0x%08X", ROMCRC32);
3463
+	strcat(romtext, temp);
3464
+}*/
3465
+
3466
+// hack
3467
+
3468
+bool CMemory::match_na (const char *str)
3469
+{
3470
+	return strcmp(ROMName, str) == 0;
3471
+}
3472
+
3473
+bool CMemory::match_nn (const char *str)
3474
+{
3475
+	return strncmp(ROMName, str, strlen(str)) == 0;
3476
+}
3477
+
3478
+/*bool CMemory::match_nc (const char *str)
3479
+{
3480
+	return strncasecmp(ROMName, str, strlen(str)) == 0;
3481
+}*/
3482
+
3483
+bool CMemory::match_id (const char *str)
3484
+{
3485
+	return strncmp(ROMId, str, strlen(str)) == 0;
3486
+}
3487
+
3488
+void CMemory::ApplyROMFixes()
3489
+{
3490
+	Settings.BlockInvalidVRAMAccess = Settings.BlockInvalidVRAMAccessMaster;
3491
+
3492
+	//// Warnings
3493
+
3494
+	// Reject strange hacked games
3495
+	/*if ((ROMCRC32 == 0x6810aa95) ||
3496
+		(ROMCRC32 == 0x340f23e5) ||
3497
+		(ROMCRC32 == 0x77fd806a) ||
3498
+		(match_nn("HIGHWAY BATTLE 2")) ||
3499
+		(match_na("FX SKIING NINTENDO 96") && (ROM[0x7fda] == 0)) ||
3500
+		(match_nn("HONKAKUHA IGO GOSEI")   && (ROM[0xffd5] != 0x31)))
3501
+	{
3502
+		Settings.DisplayColor = BUILD_PIXEL(31, 0, 0);
3503
+		SET_UI_COLOR(255, 0, 0);
3504
+	}*/
3505
+
3506
+	//// APU timing hacks :(
3507
+
3508
+	Timings.APUSpeedup = 0;
3509
+	Timings.APUAllowTimeOverflow = false;
3510
+
3511
+	if (!Settings.DisableGameSpecificHacks)
3512
+	{
3513
+		if (match_id("AVCJ"))                                      // Rendering Ranger R2
3514
+			Timings.APUSpeedup = 4;
3515
+
3516
+		if (match_na("GAIA GENSOUKI 1 JPN")                     || // Gaia Gensouki
3517
+			match_id("JG  ")                                    || // Illusion of Gaia
3518
+			match_id("CQ  ")                                    || // Stunt Race FX
3519
+			match_na("SOULBLADER - 1")                          || // Soul Blader
3520
+			match_na("SOULBLAZER - 1 USA")                      || // Soul Blazer
3521
+			match_na("SLAP STICK 1 JPN")                        || // Slap Stick
3522
+			match_id("E9 ")                                     || // Robotrek
3523
+			match_nn("ACTRAISER")                               || // Actraiser
3524
+			match_nn("ActRaiser-2")                             || // Actraiser 2
3525
+			match_id("AQT")                                     || // Tenchi Souzou, Terranigma
3526
+			match_id("ATV")                                     || // Tales of Phantasia
3527
+			match_id("ARF")                                     || // Star Ocean
3528
+			match_id("APR")                                     || // Zen-Nippon Pro Wrestling 2 - 3-4 Budoukan
3529
+			match_id("A4B")                                     || // Super Bomberman 4
3530
+			match_id("Y7 ")                                     || // U.F.O. Kamen Yakisoban - Present Ban
3531
+			match_id("Y9 ")                                     || // U.F.O. Kamen Yakisoban - Shihan Ban
3532
+			match_id("APB")                                     || // Super Bomberman - Panic Bomber W
3533
+			match_na("DARK KINGDOM")                            || // Dark Kingdom
3534
+			match_na("ZAN3 SFC")                                || // Zan III Spirits
3535
+			match_na("HIOUDEN")                                 || // Hiouden - Mamono-tachi Tono Chikai
3536
+			match_na("\xC3\xDD\xBC\xC9\xB3\xC0")                || // Tenshi no Uta
3537
+			match_na("FORTUNE QUEST")                           || // Fortune Quest - Dice wo Korogase
3538
+			match_na("FISHING TO BASSING")                      || // Shimono Masaki no Fishing To Bassing
3539
+			match_na("OHMONO BLACKBASS")                        || // Oomono Black Bass Fishing - Jinzouko Hen
3540
+			match_na("MASTERS")                                 || // Harukanaru Augusta 2 - Masters
3541
+			match_na("SFC \xB6\xD2\xDD\xD7\xB2\xC0\xDE\xB0")    || // Kamen Rider
3542
+			match_na("ZENKI TENCHIMEIDOU")					    || // Kishin Douji Zenki - Tenchi Meidou
3543
+			match_nn("TokyoDome '95Battle 7")                   || // Shin Nippon Pro Wrestling Kounin '95 - Tokyo Dome Battle 7
3544
+			match_nn("SWORD WORLD SFC")                         || // Sword World SFC/2
3545
+			match_nn("LETs PACHINKO(")                          || // BS Lets Pachinko Nante Gindama 1/2/3/4
3546
+			match_nn("THE FISHING MASTER")                      || // Mark Davis The Fishing Master
3547
+			match_nn("Parlor")                                  || // Parlor mini/2/3/4/5/6/7, Parlor Parlor!/2/3/4/5
3548
+			match_na("HEIWA Parlor!Mini8")                      || // Parlor mini 8
3549
+			match_nn("SANKYO Fever! \xCC\xA8\xB0\xCA\xDE\xB0!"))   // SANKYO Fever! Fever!
3550
+			Timings.APUSpeedup = 1;
3551
+
3552
+		if (match_na ("EARTHWORM JIM 2")						|| // Earthworm Jim 2
3553
+			match_na ("NBA Hangtime")							|| // NBA Hang Time
3554
+			match_na ("MSPACMAN")								|| // Ms Pacman
3555
+			match_na ("THE MASK")								|| // The Mask
3556
+			match_na ("PRIMAL RAGE")							|| // Primal Rage
3557
+			match_na ("DOOM TROOPERS"))							   // Doom Troopers
3558
+			Timings.APUAllowTimeOverflow = true;
3559
+	}
3560
+
3561
+	S9xAPUTimingSetSpeedup(Timings.APUSpeedup);
3562
+	S9xAPUAllowTimeOverflow(Timings.APUAllowTimeOverflow);
3563
+
3564
+	//// Other timing hacks :(
3565
+
3566
+	Timings.HDMAStart   = SNES_HDMA_START_HC + Settings.HDMATimingHack - 100;
3567
+	Timings.HBlankStart = SNES_HBLANK_START_HC + Timings.HDMAStart - SNES_HDMA_START_HC;
3568
+	Timings.IRQTriggerCycles = 10;
3569
+
3570
+	if (!Settings.DisableGameSpecificHacks)
3571
+	{
3572
+		// The delay to sync CPU and DMA which Snes9x cannot emulate.
3573
+		// Some games need really severe delay timing...
3574
+		if (match_na("BATTLE GRANDPRIX")) // Battle Grandprix
3575
+		{
3576
+			Timings.DMACPUSync = 20;
3577
+			printf("DMA sync: %d\n", Timings.DMACPUSync);
3578
+		}
3579
+	}
3580
+
3581
+	if (!Settings.DisableGameSpecificHacks)
3582
+	{
3583
+		// An infinite loop reads $4212 and waits V-blank end, whereas VIRQ is set V=0.
3584
+		// If Snes9x succeeds to escape from the loop before jumping into the IRQ handler, the game goes further.
3585
+		// If Snes9x jumps into the IRQ handler before escaping from the loop,
3586
+		// Snes9x cannot escape from the loop permanently because the RTI is in the next V-blank.
3587
+		if (match_na("Aero the AcroBat 2"))
3588
+		{
3589
+			Timings.IRQPendCount = 2;
3590
+			printf("IRQ count hack: %d\n", Timings.IRQPendCount);
3591
+		}
3592
+	}
3593
+
3594
+	if (!Settings.DisableGameSpecificHacks)
3595
+	{
3596
+		// XXX: What's happening?
3597
+		if (match_na("X-MEN")) // Spider-Man and the X-Men
3598
+		{
3599
+			Settings.BlockInvalidVRAMAccess = false;
3600
+			printf("Invalid VRAM access hack\n");
3601
+		}
3602
+	}
3603
+
3604
+	//// SRAM initial value
3605
+
3606
+	if (!Settings.DisableGameSpecificHacks)
3607
+	{
3608
+		if (match_na("HITOMI3"))
3609
+		{
3610
+			SRAMSize = 1;
3611
+			SRAMMask = ((1 << (SRAMSize + 3)) * 128) - 1;
3612
+		}
3613
+
3614
+		// SRAM value fixes
3615
+		if (match_na("SUPER DRIFT OUT")      || // Super Drift Out
3616
+			match_na("SATAN IS OUR FATHER!") ||
3617
+			match_na("goemon 4"))               // Ganbare Goemon Kirakira Douchuu
3618
+			SNESGameFixes.SRAMInitialValue = 0x00;
3619
+
3620
+		// Additional game fixes by sanmaiwashi ...
3621
+		// XXX: unnecessary?
3622
+		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
3623
+			SNESGameFixes.SRAMInitialValue = 0x6b;
3624
+
3625
+		// others: BS and ST-01x games are 0x00.
3626
+	}
3627
+
3628
+	//// OAM hacks :(
3629
+
3630
+	if (!Settings.DisableGameSpecificHacks)
3631
+	{
3632
+		// OAM hacks because we don't fully understand the behavior of the SNES.
3633
+		// Totally wacky display in 2P mode...
3634
+		// seems to need a disproven behavior, so we're definitely overlooking some other bug?
3635
+		if (match_nn("UNIRACERS")) // Uniracers
3636
+		{
3637
+			SNESGameFixes.Uniracers = true;
3638
+			printf("Applied Uniracers hack.\n");
3639
+		}
3640
+	}
3641
+}
3642
+
3643
+// UPS % IPS
3644
+
3645
+/*static uint32_t ReadUPSPointer (const uint8_t *data, unsigned &addr, unsigned size)
3646
+{
3647
+	uint32_t offset = 0, shift = 1;
3648
+	while(addr < size) {
3649
+		uint8_t x = data[addr++];
3650
+		offset += (x & 0x7f) * shift;
3651
+		if(x & 0x80) break;
3652
+		shift <<= 7;
3653
+		offset += shift;
3654
+	}
3655
+	return offset;
3656
+}
3657
+
3658
+//NOTE: UPS patches are *never* created against a headered ROM!
3659
+//this is per the UPS file specification. however, do note that it is
3660
+//technically possible for a non-compliant patcher to ignore this requirement.
3661
+//therefore, it is *imperative* that no emulator support such patches.
3662
+//thusly, we ignore the "long offset" parameter below. failure to do so would
3663
+//completely invalidate the purpose of UPS; which is to avoid header vs
3664
+//no-header patching errors that result in IPS patches having a 50/50 chance of
3665
+//being applied correctly.
3666
+
3667
+static bool ReadUPSPatch (Reader *r, long, int32_t &rom_size)
3668
+{
3669
+	//Reader lacks size() and rewind(), so we need to read in the file to get its size
3670
+	uint8_t *data = new uint8_t[8 * 1024 * 1024];  //allocate a lot of memory, better safe than sorry ...
3671
+	uint32_t size = 0;
3672
+	while(true) {
3673
+		int value = r->get_char();
3674
+		if(value == EOF) break;
3675
+		data[size++] = value;
3676
+		if(size >= 8 * 1024 * 1024) {
3677
+			//prevent buffer overflow: SNES-made UPS patches should never be this big anyway ...
3678
+			delete[] data;
3679
+			return false;
3680
+		}
3681
+	}
3682
+
3683
+	//4-byte header + 1-byte input size + 1-byte output size + 4-byte patch CRC32 + 4-byte unpatched CRC32 + 4-byte patched CRC32
3684
+	if(size < 18) { delete[] data; return false; }  //patch is too small
3685
+
3686
+	uint32_t addr = 0;
3687
+	if(data[addr++] != 'U') { delete[] data; return false; }  //patch has an invalid header
3688
+	if(data[addr++] != 'P') { delete[] data; return false; }  //...
3689
+	if(data[addr++] != 'S') { delete[] data; return false; }  //...
3690
+	if(data[addr++] != '1') { delete[] data; return false; }  //...
3691
+
3692
+	uint32_t patch_crc32 = caCRC32(data, size - 4);  //don't include patch CRC32 itself in CRC32 calculation
3693
+	uint32_t rom_crc32 = caCRC32(Memory.ROM, rom_size);
3694
+	uint32_t px_crc32 = (data[size - 12] << 0) + (data[size - 11] << 8) + (data[size - 10] << 16) + (data[size -  9] << 24);
3695
+	uint32_t py_crc32 = (data[size -  8] << 0) + (data[size -  7] << 8) + (data[size -  6] << 16) + (data[size -  5] << 24);
3696
+	uint32_t pp_crc32 = (data[size -  4] << 0) + (data[size -  3] << 8) + (data[size -  2] << 16) + (data[size -  1] << 24);
3697
+	if(patch_crc32 != pp_crc32) { delete[] data; return false; }  //patch is corrupted
3698
+	if((rom_crc32 != px_crc32) && (rom_crc32 != py_crc32)) { delete[] data; return false; }  //patch is for a different ROM
3699
+
3700
+	uint32_t px_size = ReadUPSPointer(data, addr, size);
3701
+	uint32_t py_size = ReadUPSPointer(data, addr, size);
3702
+	uint32_t out_size = ((uint32_t) rom_size == px_size) ? py_size : px_size;
3703
+	if(out_size > CMemory::MAX_ROM_SIZE) { delete[] data; return false; }  //applying this patch will overflow Memory.ROM buffer
3704
+
3705
+	//fill expanded area with 0x00s; so that XORing works as expected below.
3706
+	//note that this is needed (and works) whether output ROM is larger or smaller than pre-patched ROM
3707
+	for(unsigned i = min((uint32_t) rom_size, out_size); i < max((uint32_t) rom_size, out_size); i++) {
3708
+		Memory.ROM[i] = 0x00;
3709
+	}
3710
+
3711
+	uint32_t relative = 0;
3712
+	while(addr < size - 12) {
3713
+		relative += ReadUPSPointer(data, addr, size);
3714
+		while(addr < size - 12) {
3715
+			uint8_t x = data[addr++];
3716
+			Memory.ROM[relative++] ^= x;
3717
+			if(!x) break;
3718
+		}
3719
+	}
3720
+
3721
+	rom_size = out_size;
3722
+	delete[] data;
3723
+
3724
+	uint32_t out_crc32 = caCRC32(Memory.ROM, rom_size);
3725
+	if(((rom_crc32 == px_crc32) && (out_crc32 == py_crc32))
3726
+	|| ((rom_crc32 == py_crc32) && (out_crc32 == px_crc32))
3727
+	) {
3728
+		return true;
3729
+	} else {
3730
+		//technically, reaching here means that patching has failed.
3731
+		//we should return false, but unfortunately Memory.ROM has already
3732
+		//been modified above and cannot be undone. to do this properly, we
3733
+		//would need to make a copy of Memory.ROM, apply the patch, and then
3734
+		//copy that back to Memory.ROM.
3735
+		//
3736
+		//however, the only way for this case to happen is if the UPS patch file
3737
+		//itself is corrupted, which should be detected by the patch CRC32 check
3738
+		//above anyway. errors due to the wrong ROM or patch file being used are
3739
+		//already caught above.
3740
+		fprintf(stderr, "WARNING: UPS patching appears to have failed.\nGame may not be playable.\n");
3741
+		return true;
3742
+	}
3743
+}
3744
+
3745
+static long ReadInt (Reader *r, unsigned nbytes)
3746
+{
3747
+	long	v = 0;
3748
+
3749
+	while (nbytes--)
3750
+	{
3751
+		int	c = r->get_char();
3752
+		if (c == EOF)
3753
+			return -1;
3754
+		v = (v << 8) | (c & 0xFF);
3755
+	}
3756
+
3757
+	return v;
3758
+}
3759
+
3760
+static bool ReadIPSPatch (Reader *r, long offset, int32_t &rom_size)
3761
+{
3762
+	const int32_t	IPS_EOF = 0x00454F46l;
3763
+	int32_t		ofs;
3764
+	char		fname[6];
3765
+
3766
+	fname[5] = 0;
3767
+	for (int i = 0; i < 5; i++)
3768
+	{
3769
+		int	c = r->get_char();
3770
+		if (c == EOF)
3771
+			return 0;
3772
+		fname[i] = (char) c;
3773
+	}
3774
+
3775
+	if (strncmp(fname, "PATCH", 5))
3776
+		return 0;
3777
+
3778
+	for (;;)
3779
+	{
3780
+		long	len, rlen;
3781
+		int		rchar;
3782
+
3783
+		ofs = ReadInt(r, 3);
3784
+		if (ofs == -1)
3785
+			return 0;
3786
+
3787
+		if (ofs == IPS_EOF)
3788
+			break;
3789
+
3790
+		ofs -= offset;
3791
+
3792
+		len = ReadInt(r, 2);
3793
+		if (len == -1)
3794
+			return 0;
3795
+
3796
+		if (len)
3797
+		{
3798
+			if (ofs + len > CMemory::MAX_ROM_SIZE)
3799
+				return 0;
3800
+
3801
+			while (len--)
3802
+			{
3803
+				rchar = r->get_char();
3804
+				if (rchar == EOF)
3805
+					return 0;
3806
+				Memory.ROM[ofs++] = (uint8_t) rchar;
3807
+			}
3808
+
3809
+			if (ofs > rom_size)
3810
+				rom_size = ofs;
3811
+		}
3812
+		else
3813
+		{
3814
+			rlen = ReadInt(r, 2);
3815
+			if (rlen == -1)
3816
+				return 0;
3817
+
3818
+			rchar = r->get_char();
3819
+			if (rchar == EOF)
3820
+				return 0;
3821
+
3822
+			if (ofs + rlen > CMemory::MAX_ROM_SIZE)
3823
+				return 0;
3824
+
3825
+			while (rlen--)
3826
+				Memory.ROM[ofs++] = (uint8_t) rchar;
3827
+
3828
+			if (ofs > rom_size)
3829
+				rom_size = ofs;
3830
+		}
3831
+	}
3832
+
3833
+	ofs = ReadInt(r, 3);
3834
+	if (ofs != -1 && ofs - offset < rom_size)
3835
+		rom_size = ofs - offset;
3836
+
3837
+	return 1;
3838
+}*/
3839
+
3840
+#ifdef UNZIP_SUPPORT
3841
+static int unzFindExtension (unzFile &file, const char *ext, bool restart, bool print)
3842
+{
3843
+	unz_file_info	info;
3844
+	int				port, l = strlen(ext);
3845
+
3846
+	if (restart)
3847
+		port = unzGoToFirstFile(file);
3848
+	else
3849
+		port = unzGoToNextFile(file);
3850
+
3851
+	while (port == UNZ_OK)
3852
+	{
3853
+		int		len;
3854
+		char	name[132];
3855
+
3856
+		unzGetCurrentFileInfo(file, &info, name, 128, NULL, 0, NULL, 0);
3857
+		len = strlen(name);
3858
+
3859
+		if (len >= l + 1 && name[len - l - 1] == '.' && strcasecmp(name + len - l, ext) == 0 && unzOpenCurrentFile(file) == UNZ_OK)
3860
+		{
3861
+			if (print)
3862
+				printf("Using IPS or UPS patch %s", name);
3863
+
3864
+			return port;
3865
+		}
3866
+
3867
+		port = unzGoToNextFile(file);
3868
+	}
3869
+
3870
+	return port;
3871
+}
3872
+#endif
3873
+
3874
+/*void CMemory::CheckForAnyPatch (const char *rom_filename, bool header, int32_t &rom_size)
3875
+{
3876
+	if (Settings.NoPatch)
3877
+		return;
3878
+
3879
+	STREAM		patch_file  = NULL;
3880
+	uint32_t		i;
3881
+	long		offset = header ? 512 : 0;
3882
+	int			ret;
3883
+	bool		flag;
3884
+	char		dir[_MAX_DIR + 1], drive[_MAX_DRIVE + 1], name[_MAX_FNAME + 1], ext[_MAX_EXT + 1], ips[_MAX_EXT + 3], fname[PATH_MAX + 1];
3885
+	const char	*n;
3886
+
3887
+	// UPS
3888
+
3889
+	_splitpath(rom_filename, drive, dir, name, ext);
3890
+	_makepath(fname, drive, dir, name, "ups");
3891
+
3892
+	if ((patch_file = OPEN_STREAM(fname, "rb")) != NULL)
3893
+	{
3894
+		printf("Using UPS patch %s", fname);
3895
+
3896
+		ret = ReadUPSPatch(new fReader(patch_file), 0, rom_size);
3897
+		CLOSE_STREAM(patch_file);
3898
+
3899
+		if (ret)
3900
+		{
3901
+			printf("!\n");
3902
+			return;
3903
+		}
3904
+		else
3905
+			printf(" failed!\n");
3906
+	}
3907
+
3908
+#ifdef UNZIP_SUPPORT
3909
+	if (!strcasecmp(ext, "zip") || !strcasecmp(ext, ".zip"))
3910
+	{
3911
+		unzFile	file = unzOpen(rom_filename);
3912
+		if (file)
3913
+		{
3914
+			int	port = unzFindExtension(file, "ups");
3915
+			if (port == UNZ_OK)
3916
+			{
3917
+				printf(" in %s", rom_filename);
3918
+
3919
+				ret = ReadUPSPatch(new unzReader(file), offset, rom_size);
3920
+				unzCloseCurrentFile(file);
3921
+
3922
+				if (ret)
3923
+					printf("!\n");
3924
+				else
3925
+					printf(" failed!\n");
3926
+			}
3927
+		}
3928
+	}
3929
+#endif
3930
+
3931
+	n = S9xGetFilename(".ups", IPS_DIR);
3932
+
3933
+	if ((patch_file = OPEN_STREAM(n, "rb")) != NULL)
3934
+	{
3935
+		printf("Using UPS patch %s", n);
3936
+
3937
+		ret = ReadUPSPatch(new fReader(patch_file), 0, rom_size);
3938
+		CLOSE_STREAM(patch_file);
3939
+
3940
+		if (ret)
3941
+		{
3942
+			printf("!\n");
3943
+			return;
3944
+		}
3945
+		else
3946
+			printf(" failed!\n");
3947
+	}
3948
+
3949
+	// IPS
3950
+
3951
+	_splitpath(rom_filename, drive, dir, name, ext);
3952
+	_makepath(fname, drive, dir, name, "ips");
3953
+
3954
+	if ((patch_file = OPEN_STREAM(fname, "rb")) != NULL)
3955
+	{
3956
+		printf("Using IPS patch %s", fname);
3957
+
3958
+		ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size);
3959
+		CLOSE_STREAM(patch_file);
3960
+
3961
+		if (ret)
3962
+		{
3963
+			printf("!\n");
3964
+			return;
3965
+		}
3966
+		else
3967
+			printf(" failed!\n");
3968
+	}
3969
+
3970
+	if (_MAX_EXT > 6)
3971
+	{
3972
+		i = 0;
3973
+		flag = false;
3974
+
3975
+		do
3976
+		{
3977
+			snprintf(ips, 8, "%03d.ips", i);
3978
+			_makepath(fname, drive, dir, name, ips);
3979
+
3980
+			if (!(patch_file = OPEN_STREAM(fname, "rb")))
3981
+				break;
3982
+
3983
+			printf("Using IPS patch %s", fname);
3984
+
3985
+			ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size);
3986
+			CLOSE_STREAM(patch_file);
3987
+
3988
+			if (ret)
3989
+			{
3990
+				printf("!\n");
3991
+				flag = true;
3992
+			}
3993
+			else
3994
+			{
3995
+				printf(" failed!\n");
3996
+				break;
3997
+			}
3998
+		} while (++i < 1000);
3999
+
4000
+		if (flag)
4001
+			return;
4002
+	}
4003
+
4004
+	if (_MAX_EXT > 3)
4005
+	{
4006
+		i = 0;
4007
+		flag = false;
4008
+
4009
+		do
4010
+		{
4011
+			snprintf(ips, _MAX_EXT + 2, "ips%d", i);
4012
+			if (strlen(ips) > _MAX_EXT)
4013
+				break;
4014
+			_makepath(fname, drive, dir, name, ips);
4015
+
4016
+			if (!(patch_file = OPEN_STREAM(fname, "rb")))
4017
+				break;
4018
+
4019
+			printf("Using IPS patch %s", fname);
4020
+
4021
+			ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size);
4022
+			CLOSE_STREAM(patch_file);
4023
+
4024
+			if (ret)
4025
+			{
4026
+				printf("!\n");
4027
+				flag = true;
4028
+			}
4029
+			else
4030
+			{
4031
+				printf(" failed!\n");
4032
+				break;
4033
+			}
4034
+		} while (++i != 0);
4035
+
4036
+		if (flag)
4037
+			return;
4038
+	}
4039
+
4040
+	if (_MAX_EXT > 2)
4041
+	{
4042
+		i = 0;
4043
+		flag = false;
4044
+
4045
+		do
4046
+		{
4047
+			snprintf(ips, 4, "ip%d", i);
4048
+			_makepath(fname, drive, dir, name, ips);
4049
+
4050
+			if (!(patch_file = OPEN_STREAM(fname, "rb")))
4051
+				break;
4052
+
4053
+			printf("Using IPS patch %s", fname);
4054
+
4055
+			ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size);
4056
+			CLOSE_STREAM(patch_file);
4057
+
4058
+			if (ret)
4059
+			{
4060
+				printf("!\n");
4061
+				flag = true;
4062
+			}
4063
+			else
4064
+			{
4065
+				printf(" failed!\n");
4066
+				break;
4067
+			}
4068
+		} while (++i < 10);
4069
+
4070
+		if (flag)
4071
+			return;
4072
+	}
4073
+
4074
+#ifdef UNZIP_SUPPORT
4075
+	if (!strcasecmp(ext, "zip") || !strcasecmp(ext, ".zip"))
4076
+	{
4077
+		unzFile	file = unzOpen(rom_filename);
4078
+		if (file)
4079
+		{
4080
+			int	port = unzFindExtension(file, "ips");
4081
+			while (port == UNZ_OK)
4082
+			{
4083
+				printf(" in %s", rom_filename);
4084
+
4085
+				ret = ReadIPSPatch(new unzReader(file), offset, rom_size);
4086
+				unzCloseCurrentFile(file);
4087
+
4088
+				if (ret)
4089
+				{
4090
+					printf("!\n");
4091
+					flag = true;
4092
+				}
4093
+				else
4094
+					printf(" failed!\n");
4095
+
4096
+				port = unzFindExtension(file, "ips", false);
4097
+			}
4098
+
4099
+			if (!flag)
4100
+			{
4101
+				i = 0;
4102
+
4103
+				do
4104
+				{
4105
+					snprintf(ips, 8, "%03d.ips", i);
4106
+
4107
+					if (unzFindExtension(file, ips) != UNZ_OK)
4108
+						break;
4109
+
4110
+					printf(" in %s", rom_filename);
4111
+
4112
+					ret = ReadIPSPatch(new unzReader(file), offset, rom_size);
4113
+					unzCloseCurrentFile(file);
4114
+
4115
+					if (ret)
4116
+					{
4117
+						printf("!\n");
4118
+						flag = true;
4119
+					}
4120
+					else
4121
+					{
4122
+						printf(" failed!\n");
4123
+						break;
4124
+					}
4125
+
4126
+					if (unzFindExtension(file, ips, false, false) == UNZ_OK)
4127
+						printf("WARNING: Ignoring extra .%s files!\n", ips);
4128
+				} while (++i < 1000);
4129
+			}
4130
+
4131
+			if (!flag)
4132
+			{
4133
+				i = 0;
4134
+
4135
+				do
4136
+				{
4137
+					snprintf(ips, _MAX_EXT + 2, "ips%d", i);
4138
+					if (strlen(ips) > _MAX_EXT)
4139
+						break;
4140
+
4141
+					if (unzFindExtension(file, ips) != UNZ_OK)
4142
+						break;
4143
+
4144
+					printf(" in %s", rom_filename);
4145
+
4146
+					ret = ReadIPSPatch(new unzReader(file), offset, rom_size);
4147
+					unzCloseCurrentFile(file);
4148
+
4149
+					if (ret)
4150
+					{
4151
+						printf("!\n");
4152
+						flag = true;
4153
+					}
4154
+					else
4155
+					{
4156
+						printf(" failed!\n");
4157
+						break;
4158
+					}
4159
+
4160
+					if (unzFindExtension(file, ips, false, false) == UNZ_OK)
4161
+						printf("WARNING: Ignoring extra .%s files!\n", ips);
4162
+				} while (++i != 0);
4163
+			}
4164
+
4165
+			if (!flag)
4166
+			{
4167
+				i = 0;
4168
+
4169
+				do
4170
+				{
4171
+					snprintf(ips, 4, "ip%d", i);
4172
+
4173
+					if (unzFindExtension(file, ips) != UNZ_OK)
4174
+						break;
4175
+
4176
+					printf(" in %s", rom_filename);
4177
+
4178
+					ret = ReadIPSPatch(new unzReader(file), offset, rom_size);
4179
+					unzCloseCurrentFile(file);
4180
+
4181
+					if (ret)
4182
+					{
4183
+						printf("!\n");
4184
+						flag = true;
4185
+					}
4186
+					else
4187
+					{
4188
+						printf(" failed!\n");
4189
+						break;
4190
+					}
4191
+
4192
+					if (unzFindExtension(file, ips, false, false) == UNZ_OK)
4193
+						printf("WARNING: Ignoring extra .%s files!\n", ips);
4194
+				} while (++i < 10);
4195
+			}
4196
+
4197
+			assert(unzClose(file) == UNZ_OK);
4198
+
4199
+			if (flag)
4200
+				return;
4201
+		}
4202
+	}
4203
+#endif
4204
+
4205
+	n = S9xGetFilename(".ips", IPS_DIR);
4206
+
4207
+	if ((patch_file = OPEN_STREAM(n, "rb")) != NULL)
4208
+	{
4209
+		printf("Using IPS patch %s", n);
4210
+
4211
+		ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size);
4212
+		CLOSE_STREAM(patch_file);
4213
+
4214
+		if (ret)
4215
+		{
4216
+			printf("!\n");
4217
+			return;
4218
+		}
4219
+		else
4220
+			printf(" failed!\n");
4221
+	}
4222
+
4223
+	if (_MAX_EXT > 6)
4224
+	{
4225
+		i = 0;
4226
+		flag = false;
4227
+
4228
+		do
4229
+		{
4230
+			snprintf(ips, 9, ".%03d.ips", i);
4231
+			n = S9xGetFilename(ips, IPS_DIR);
4232
+
4233
+			if (!(patch_file = OPEN_STREAM(n, "rb")))
4234
+				break;
4235
+
4236
+			printf("Using IPS patch %s", n);
4237
+
4238
+			ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size);
4239
+			CLOSE_STREAM(patch_file);
4240
+
4241
+			if (ret)
4242
+			{
4243
+				printf("!\n");
4244
+				flag = true;
4245
+			}
4246
+			else
4247
+			{
4248
+				printf(" failed!\n");
4249
+				break;
4250
+			}
4251
+		} while (++i < 1000);
4252
+
4253
+		if (flag)
4254
+			return;
4255
+	}
4256
+
4257
+	if (_MAX_EXT > 3)
4258
+	{
4259
+		i = 0;
4260
+		flag = false;
4261
+
4262
+		do
4263
+		{
4264
+			snprintf(ips, _MAX_EXT + 3, ".ips%d", i);
4265
+			if (strlen(ips) > _MAX_EXT + 1)
4266
+				break;
4267
+			n = S9xGetFilename(ips, IPS_DIR);
4268
+
4269
+			if (!(patch_file = OPEN_STREAM(n, "rb")))
4270
+				break;
4271
+
4272
+			printf("Using IPS patch %s", n);
4273
+
4274
+			ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size);
4275
+			CLOSE_STREAM(patch_file);
4276
+
4277
+			if (ret)
4278
+			{
4279
+				printf("!\n");
4280
+				flag = true;
4281
+			}
4282
+			else
4283
+			{
4284
+				printf(" failed!\n");
4285
+				break;
4286
+			}
4287
+		} while (++i != 0);
4288
+
4289
+		if (flag)
4290
+			return;
4291
+	}
4292
+
4293
+	if (_MAX_EXT > 2)
4294
+	{
4295
+		i = 0;
4296
+		flag = false;
4297
+
4298
+		do
4299
+		{
4300
+			snprintf(ips, 5, ".ip%d", i);
4301
+			n = S9xGetFilename(ips, IPS_DIR);
4302
+
4303
+			if (!(patch_file = OPEN_STREAM(n, "rb")))
4304
+				break;
4305
+
4306
+			printf("Using IPS patch %s", n);
4307
+
4308
+			ret = ReadIPSPatch(new fReader(patch_file), offset, rom_size);
4309
+			CLOSE_STREAM(patch_file);
4310
+
4311
+			if (ret)
4312
+			{
4313
+				printf("!\n");
4314
+				flag = true;
4315
+			}
4316
+			else
4317
+			{
4318
+				printf(" failed!\n");
4319
+				break;
4320
+			}
4321
+		} while (++i < 10);
4322
+
4323
+		if (flag)
4324
+			return;
4325
+	}
4326
+}*/