* [2SF] Used more up-to-date asmjit, despite the ugly looking code.
| ... | ... |
@@ -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) |
| ... | ... |
@@ -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 :( |
| ... | ... |
@@ -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 |
+} |
| ... | ... |
@@ -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 |
|
| 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 |
+}*/ |