Files
ci-libretro-fceumm/src/ines.c

1062 lines
40 KiB
C
Raw Normal View History

/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 1998 BERO
* Copyright (C) 2002 Xodnizel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fceu-types.h"
#include "x6502.h"
#include "fceu.h"
#include "cart.h"
#include "ppu.h"
#include "ines.h"
#include "unif.h"
#include "state.h"
#include "file.h"
#include "general.h"
2014-03-30 22:29:30 +02:00
#include "fceu-memory.h"
#include "crc32.h"
#include "md5.h"
#include "cheat.h"
#include "vsuni.h"
extern SFORMAT FCEUVSUNI_STATEINFO[];
uint8 *trainerpoo = NULL;
uint8 *ROM = NULL;
uint8 *VROM = NULL;
uint8 *ExtraNTARAM = NULL;
iNES_HEADER head;
2015-08-06 13:01:26 +02:00
CartInfo iNESCart;
uint8 Mirroring = 0;
uint32 ROM_size = 0;
uint32 VROM_size = 0;
static int CHRRAMSize = -1;
static int iNES_Init(int num);
static int iNES2 = 0;
static int MapperNo = 0;
static int subMapper = 0;
static DECLFR(TrainerRead) {
return(trainerpoo[A & 0x1FF]);
}
static void iNES_ExecPower() {
if (iNESCart.Power)
iNESCart.Power();
if (trainerpoo) {
int x;
for (x = 0; x < 512; x++) {
X6502_DMW(0x7000 + x, trainerpoo[x]);
if (X6502_DMR(0x7000 + x) != trainerpoo[x]) {
SetReadHandler(0x7000, 0x71FF, TrainerRead);
break;
}
}
}
}
static void iNESGI(int h) {
switch (h)
{
case GI_RESETM2:
if (iNESCart.Reset)
iNESCart.Reset();
break;
case GI_POWER:
iNES_ExecPower();
break;
case GI_CLOSE:
if (iNESCart.Close)
iNESCart.Close();
if (ROM) {
free(ROM);
ROM = NULL;
}
if (VROM) {
free(VROM);
VROM = NULL;
}
if (trainerpoo) {
free(trainerpoo);
trainerpoo = NULL;
}
if (ExtraNTARAM) {
free(ExtraNTARAM);
ExtraNTARAM = NULL;
}
break;
}
}
struct CRCMATCH {
uint32 crc;
char *name;
};
struct INPSEL {
uint32 crc32;
int input1;
int input2;
int inputfc;
};
static void SetInput(void) {
static struct INPSEL moo[] =
{
2017-10-15 03:13:11 +08:00
{0x19b0a9f1, SI_GAMEPAD, SI_ZAPPER, SIFC_NONE }, /* 6-in-1 (MGC-023)(Unl)[!] */
{0x29de87af, SI_GAMEPAD, SI_GAMEPAD, SIFC_FTRAINERB }, /* Aerobics Studio */
{0xd89e5a67, SI_UNSET, SI_UNSET, SIFC_ARKANOID }, /* Arkanoid (J) */
{0x0f141525, SI_UNSET, SI_UNSET, SIFC_ARKANOID }, /* Arkanoid 2(J) */
{0x32fb0583, SI_UNSET, SI_ARKANOID, SIFC_NONE }, /* Arkanoid(NES) */
{0x60ad090a, SI_GAMEPAD, SI_GAMEPAD, SIFC_FTRAINERA }, /* Athletic World */
{0x48ca0ee1, SI_GAMEPAD, SI_GAMEPAD, SIFC_BWORLD }, /* Barcode World */
{0x4318a2f8, SI_UNSET, SI_ZAPPER, SIFC_NONE }, /* Barker Bill's Trick Shooting */
{0x6cca1c1f, SI_GAMEPAD, SI_GAMEPAD, SIFC_FTRAINERB }, /* Dai Undoukai */
{0x24598791, SI_UNSET, SI_ZAPPER, SIFC_NONE }, /* Duck Hunt */
{0xd5d6eac4, SI_UNSET, SI_UNSET, SIFC_SUBORKB }, /* Edu (As) */
{0xe9a7fe9e, SI_UNSET, SI_MOUSE, SIFC_NONE }, /* Educational Computer 2000 */
{0x8f7b1669, SI_UNSET, SI_UNSET, SIFC_SUBORKB }, /* FP BASIC 3.3 by maxzhou88 */
{0xf7606810, SI_UNSET, SI_UNSET, SIFC_FKB }, /* Family BASIC 2.0A */
{0x895037bc, SI_UNSET, SI_UNSET, SIFC_FKB }, /* Family BASIC 2.1a */
{0xb2530afc, SI_UNSET, SI_UNSET, SIFC_FKB }, /* Family BASIC 3.0 */
{0xea90f3e2, SI_GAMEPAD, SI_GAMEPAD, SIFC_FTRAINERB }, /* Family Trainer: Running Stadium */
{0xbba58be5, SI_GAMEPAD, SI_GAMEPAD, SIFC_FTRAINERB }, /* Family Trainer: Manhattan Police */
{0x3e58a87e, SI_UNSET, SI_ZAPPER, SIFC_NONE }, /* Freedom Force */
{0xd9f45be9, SI_GAMEPAD, SI_GAMEPAD, SIFC_QUIZKING }, /* Gimme a Break ... */
{0x1545bd13, SI_GAMEPAD, SI_GAMEPAD, SIFC_QUIZKING }, /* Gimme a Break ... 2 */
{0x4e959173, SI_UNSET, SI_ZAPPER, SIFC_NONE }, /* Gotcha! - The Sport! */
{0xbeb8ab01, SI_UNSET, SI_ZAPPER, SIFC_NONE }, /* Gumshoe */
{0xff24d794, SI_UNSET, SI_ZAPPER, SIFC_NONE }, /* Hogan's Alley */
{0x21f85681, SI_GAMEPAD, SI_GAMEPAD, SIFC_HYPERSHOT }, /* Hyper Olympic (Gentei Ban) */
{0x980be936, SI_GAMEPAD, SI_GAMEPAD, SIFC_HYPERSHOT }, /* Hyper Olympic */
{0x915a53a7, SI_GAMEPAD, SI_GAMEPAD, SIFC_HYPERSHOT }, /* Hyper Sports */
{0x9fae4d46, SI_GAMEPAD, SI_GAMEPAD, SIFC_MAHJONG }, /* Ide Yousuke Meijin no Jissen Mahjong */
{0x7b44fb2a, SI_GAMEPAD, SI_GAMEPAD, SIFC_MAHJONG }, /* Ide Yousuke Meijin no Jissen Mahjong 2 */
{0x2f128512, SI_GAMEPAD, SI_GAMEPAD, SIFC_FTRAINERA }, /* Jogging Race */
{0xbb33196f, SI_UNSET, SI_UNSET, SIFC_FKB }, /* Keyboard Transformer */
{0x8587ee00, SI_UNSET, SI_UNSET, SIFC_FKB }, /* Keyboard Transformer */
{0x543ab532, SI_UNSET, SI_UNSET, SIFC_SUBORKB }, /* LIKO Color Lines */
{0x368c19a8, SI_UNSET, SI_UNSET, SIFC_SUBORKB }, /* LIKO Study Cartridge */
{0x5ee6008e, SI_UNSET, SI_ZAPPER, SIFC_NONE }, /* Mechanized Attack */
{0x370ceb65, SI_GAMEPAD, SI_GAMEPAD, SIFC_FTRAINERB }, /* Meiro Dai Sakusen */
{0x3a1694f9, SI_GAMEPAD, SI_GAMEPAD, SIFC_4PLAYER }, /* Nekketsu Kakutou Densetsu */
{0x9d048ea4, SI_GAMEPAD, SI_GAMEPAD, SIFC_OEKAKIDS }, /* Oeka Kids */
{0x2a6559a1, SI_UNSET, SI_ZAPPER, SIFC_NONE }, /* Operation Wolf (J) */
{0xedc3662b, SI_UNSET, SI_ZAPPER, SIFC_NONE }, /* Operation Wolf */
{0x912989dc, SI_UNSET, SI_UNSET, SIFC_FKB }, /* Playbox BASIC */
{0x9044550e, SI_GAMEPAD, SI_GAMEPAD, SIFC_FTRAINERA }, /* Rairai Kyonshizu */
{0xea90f3e2, SI_GAMEPAD, SI_GAMEPAD, SIFC_FTRAINERB }, /* Running Stadium */
{0x851eb9be, SI_GAMEPAD, SI_ZAPPER, SIFC_NONE }, /* Shooting Range */
{0x6435c095, SI_GAMEPAD, SI_POWERPADB, SIFC_UNSET }, /* Short Order/Eggsplode */
{0xc043a8df, SI_UNSET, SI_MOUSE, SIFC_NONE }, /* Shu Qi Yu - Shu Xue Xiao Zhuan Yuan (Ch) */
{0x2cf5db05, SI_UNSET, SI_MOUSE, SIFC_NONE }, /* Shu Qi Yu - Zhi Li Xiao Zhuan Yuan (Ch) */
{0xad9c63e2, SI_GAMEPAD, SI_UNSET, SIFC_SHADOW }, /* Space Shadow */
{0x61d86167, SI_GAMEPAD, SI_POWERPADB, SIFC_UNSET }, /* Street Cop */
{0xabb2f974, SI_UNSET, SI_UNSET, SIFC_SUBORKB }, /* Study and Game 32-in-1 */
{0x41ef9ac4, SI_UNSET, SI_UNSET, SIFC_SUBORKB }, /* Subor */
{0x8b265862, SI_UNSET, SI_UNSET, SIFC_SUBORKB }, /* Subor */
{0x82f1fb96, SI_UNSET, SI_UNSET, SIFC_SUBORKB }, /* Subor 1.0 Russian */
{0x9f8f200a, SI_GAMEPAD, SI_GAMEPAD, SIFC_FTRAINERA }, /* Super Mogura Tataki!! - Pokkun Moguraa */
{0xd74b2719, SI_GAMEPAD, SI_POWERPADB, SIFC_UNSET }, /* Super Team Games */
{0x74bea652, SI_GAMEPAD, SI_ZAPPER, SIFC_NONE }, /* Supergun 3-in-1 */
{0x5e073a1b, SI_UNSET, SI_UNSET, SIFC_SUBORKB }, /* Supor English (Chinese) */
{0x589b6b0d, SI_UNSET, SI_UNSET, SIFC_SUBORKB }, /* SuporV20 */
{0x41401c6d, SI_UNSET, SI_UNSET, SIFC_SUBORKB }, /* SuporV40 */
{0x23d17f5e, SI_GAMEPAD, SI_ZAPPER, SIFC_NONE }, /* The Lone Ranger */
{0xc3c0811d, SI_GAMEPAD, SI_GAMEPAD, SIFC_OEKAKIDS }, /* The two "Oeka Kids" games */
{0xde8fd935, SI_UNSET, SI_ZAPPER, SIFC_NONE }, /* To the Earth */
{0x47232739, SI_GAMEPAD, SI_GAMEPAD, SIFC_TOPRIDER }, /* Top Rider */
{0x8a12a7d9, SI_GAMEPAD, SI_GAMEPAD, SIFC_FTRAINERB }, /* Totsugeki Fuuun Takeshi Jou */
{0xb8b9aca3, SI_UNSET, SI_ZAPPER, SIFC_NONE }, /* Wild Gunman */
{0x5112dc21, SI_UNSET, SI_ZAPPER, SIFC_NONE }, /* Wild Gunman */
{0xaf4010ea, SI_GAMEPAD, SI_POWERPADB, SIFC_UNSET }, /* World Class Track Meet */
{0xb3cc4d26, SI_GAMEPAD, SI_UNSET, SIFC_SHADOW }, /* 2-in-1 Uzi Lightgun (MGC-002) */
{0x00000000, SI_UNSET, SI_UNSET, SIFC_UNSET }
};
int x = 0;
while (moo[x].input1 >= 0 || moo[x].input2 >= 0 || moo[x].inputfc >= 0) {
if (moo[x].crc32 == iNESCart.CRC32) {
GameInfo->input[0] = moo[x].input1;
GameInfo->input[1] = moo[x].input2;
GameInfo->inputfc = moo[x].inputfc;
break;
}
x++;
}
}
#define INESB_INCOMPLETE 1
#define INESB_CORRUPT 2
#define INESB_HACKED 4
struct BADINF {
uint64 md5partial;
uint8 *name;
uint32 type;
};
static struct BADINF BadROMImages[] =
{
#include "ines-bad.h"
};
void CheckBad(uint64 md5partial) {
int32 x = 0;
while (BadROMImages[x].name) {
if (BadROMImages[x].md5partial == md5partial) {
FCEU_PrintError("The copy game you have loaded, \"%s\", is bad, and will not work properly in FCE Ultra.", BadROMImages[x].name);
return;
}
x++;
}
}
struct CHINF {
uint32 crc32;
int32 mapper;
int32 mirror;
};
static void CheckHInfo(void) {
/* ROM images that have the battery-backed bit set in the header that really
don't have battery-backed RAM is not that big of a problem, so I'll
treat this differently by only listing games that should have battery-backed RAM.
Lower 64 bits of the MD5 hash.
*/
static uint64 savie[] =
{
0xc04361e499748382LL, /* AD&D Heroes of the Lance */
0xb72ee2337ced5792LL, /* AD&D Hillsfar */
0x2b7103b7a27bd72fLL, /* AD&D Pool of Radiance */
0x498c10dc463cfe95LL, /* Battle Fleet */
0x854d7947a3177f57LL, /* Crystalis */
0x4a1f5336b86851b6LL, /* DW */
0xb0bcc02c843c1b79LL, /* DW */
0x2dcf3a98c7937c22LL, /* DW 2 */
0x98e55e09dfcc7533LL, /* DW 4*/
0x733026b6b72f2470LL, /* Dw 3 */
0x6917ffcaca2d8466LL, /* Famista '90 */
0x8da46db592a1fcf4LL, /* Faria */
0xedba17a2c4608d20LL, /* Final Fantasy */
0x91a6846d3202e3d6LL, /* Final Fantasy */
0x012df596e2b31174LL, /* Final Fantasy 1+2 */
0xf6b359a720549ecdLL, /* Final Fantasy 2 */
0x5a30da1d9b4af35dLL, /* Final Fantasy 3 */
0xd63dcc68c2b20adcLL, /* Final Fantasy J */
0x2ee3417ba8b69706LL, /* Hydlide 3*/
0xebbce5a54cf3ecc0LL, /* Justbreed */
0x6a858da551ba239eLL, /* Kaijuu Monogatari */
0x2db8f5d16c10b925LL, /* Kyonshiizu 2 */
0x04a31647de80fdabLL, /* Legend of Zelda */
0x94b9484862a26cbaLL, /* Legend of Zelda */
0xa40666740b7d22feLL, /* Mindseeker */
0x82000965f04a71bbLL, /* Mirai Shinwa Jarvas */
0x77b811b2760104b9LL, /* Mouryou Senki Madara */
0x11b69122efe86e8cLL, /* RPG Jinsei Game */
0x9aa1dc16c05e7de5LL, /* Startropics */
0x1b084107d0878bd0LL, /* Startropics 2*/
0xa70b495314f4d075LL, /* Ys 3 */
0x836c0ff4f3e06e45LL, /* Zelda 2 */
0 /* Abandon all hope if the game has 0 in the lower 64-bits of its MD5 hash */
};
static struct CHINF moo[] =
{
#include "ines-correct.h"
};
int32 tofix = 0, x;
uint64 partialmd5 = 0;
int32 current_mapper = 0;
int32 cur_mirr = 0;
for (x = 0; x < 8; x++)
partialmd5 |= (uint64)iNESCart.MD5[15 - x] << (x * 8);
CheckBad(partialmd5);
x = 0;
do {
if (moo[x].crc32 == iNESCart.CRC32) {
if (moo[x].mapper >= 0) {
if (moo[x].mapper & 0x800 && VROM_size) {
VROM_size = 0;
free(VROM);
VROM = NULL;
tofix |= 8;
}
if (MapperNo != (moo[x].mapper & 0xFFF)) {
tofix |= 1;
current_mapper = MapperNo;
MapperNo = moo[x].mapper & 0xFFF;
}
}
if (moo[x].mirror >= 0) {
cur_mirr = Mirroring;
if (moo[x].mirror == 8) {
if (Mirroring == 2) { /* Anything but hard-wired(four screen). */
tofix |= 2;
Mirroring = 0;
}
} else if (Mirroring != moo[x].mirror) {
if (Mirroring != (moo[x].mirror & ~4))
if ((moo[x].mirror & ~4) <= 2) /* Don't complain if one-screen mirroring
needs to be set(the iNES header can't
hold this information).
*/
tofix |= 2;
Mirroring = moo[x].mirror;
}
}
break;
}
x++;
} while (moo[x].mirror >= 0 || moo[x].mapper >= 0);
x = 0;
while (savie[x] != 0) {
if (savie[x] == partialmd5) {
if (!(head.ROM_type & 2)) {
tofix |= 4;
head.ROM_type |= 2;
}
}
x++;
}
/* Games that use these iNES mappers tend to have the four-screen bit set
when it should not be.
*/
if ((MapperNo == 118 || MapperNo == 24 || MapperNo == 26) && (Mirroring == 2)) {
Mirroring = 0;
tofix |= 2;
}
/* Four-screen mirroring implicitly set. */
if (MapperNo == 99)
Mirroring = 2;
if (tofix) {
char gigastr[768];
strcpy(gigastr, "The iNES header contains incorrect information. For now, the information will be corrected in RAM. ");
if (tofix & 1)
sprintf(gigastr + strlen(gigastr), "Current mapper # is %d. The mapper number should be set to %d. ", current_mapper, MapperNo);
if (tofix & 2) {
2016-09-09 08:09:38 +02:00
uint8 *mstr[3] = { (uint8_t*)"Horizontal", (uint8_t*)"Vertical", (uint8_t*)"Four-screen" };
sprintf(gigastr + strlen(gigastr), "Current mirroring is %s. Mirroring should be set to \"%s\". ", mstr[cur_mirr & 3], mstr[Mirroring & 3]);
}
if (tofix & 4)
strcat(gigastr, "The battery-backed bit should be set. ");
if (tofix & 8)
strcat(gigastr, "This game should not have any CHR ROM. ");
strcat(gigastr, "\n");
FCEU_printf("%s\n", gigastr);
}
}
typedef struct {
int32 mapper;
void (*init)(CartInfo *);
} NewMI;
typedef struct {
uint8 *name;
int32 number;
void (*init)(CartInfo *);
} BMAPPINGLocal;
static BMAPPINGLocal bmap[] = {
2016-09-09 09:10:10 +02:00
{(uint8_t*)"NROM", 0, NROM_Init},
{(uint8_t*)"MMC1", 1, Mapper1_Init},
{(uint8_t*)"UNROM", 2, UNROM_Init},
{(uint8_t*)"CNROM", 3, CNROM_Init},
{(uint8_t*)"MMC3", 4, Mapper4_Init},
{(uint8_t*)"MMC5", 5, Mapper5_Init},
{(uint8_t*)"FFE Rev. A", 6, Mapper6_Init},
{(uint8_t*)"ANROM", 7, ANROM_Init},
2017-10-15 03:13:11 +08:00
{(uint8_t*)"", 8, Mapper8_Init}, /* Nogaems, it's worthless */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"MMC2", 9, Mapper9_Init},
{(uint8_t*)"MMC4", 10, Mapper10_Init},
{(uint8_t*)"Color Dreams", 11, Mapper11_Init},
{(uint8_t*)"REX DBZ 5", 12, Mapper12_Init},
{(uint8_t*)"CPROM", 13, CPROM_Init},
{(uint8_t*)"REX SL-1632", 14, UNLSL1632_Init},
{(uint8_t*)"100-in-1", 15, Mapper15_Init},
{(uint8_t*)"BANDAI 24C02", 16, Mapper16_Init},
{(uint8_t*)"FFE Rev. B", 17, Mapper17_Init},
2017-10-15 03:13:11 +08:00
{(uint8_t*)"JALECO SS880006", 18, Mapper18_Init}, /* JF-NNX (EB89018-30007) boards */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"Namcot 106", 19, Mapper19_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 20, Mapper20_Init}, */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"Konami VRC2/VRC4 A", 21, Mapper21_Init},
{(uint8_t*)"Konami VRC2/VRC4 B", 22, Mapper22_Init},
{(uint8_t*)"Konami VRC2/VRC4 C", 23, Mapper23_Init},
{(uint8_t*)"Konami VRC6 Rev. A", 24, Mapper24_Init},
{(uint8_t*)"Konami VRC2/VRC4 D", 25, Mapper25_Init},
{(uint8_t*)"Konami VRC6 Rev. B", 26, Mapper26_Init},
2017-10-15 03:13:11 +08:00
{(uint8_t*)"CC-21 MI HUN CHE", 27, UNLCC21_Init}, /* Former dupe for VRC2/VRC4 mapper, redefined with crc to mihunche boards */
{(uint8_t*)"Action 53", 28, Mapper28_Init},
{(uint8_t*)"", 29, Mapper29_Init},
2017-04-30 06:44:51 +08:00
{(uint8_t*)"UNROM 512", 30, UNROM512_Init},
{(uint8_t*)"infineteNesLives-NSF", 31, Mapper31_Init},
2016-09-09 09:10:10 +02:00
{(uint8_t*)"IREM G-101", 32, Mapper32_Init},
{(uint8_t*)"TC0190FMC/TC0350FMR", 33, Mapper33_Init},
{(uint8_t*)"IREM I-IM/BNROM", 34, Mapper34_Init},
{(uint8_t*)"Wario Land 2", 35, UNLSC127_Init},
{(uint8_t*)"TXC Policeman", 36, Mapper36_Init},
{(uint8_t*)"PAL-ZZ SMB/TETRIS/NWC",37, Mapper37_Init},
2017-10-15 03:13:11 +08:00
{(uint8_t*)"Bit Corp.", 38, Mapper38_Init}, /* Crime Busters */
/* {(uint8_t*)"", 39, Mapper39_Init}, */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"SMB2j FDS", 40, Mapper40_Init},
{(uint8_t*)"CALTRON 6-in-1", 41, Mapper41_Init},
{(uint8_t*)"BIO MIRACLE FDS", 42, Mapper42_Init},
{(uint8_t*)"FDS SMB2j LF36", 43, Mapper43_Init},
{(uint8_t*)"MMC3 BMC PIRATE A", 44, Mapper44_Init},
{(uint8_t*)"MMC3 BMC PIRATE B", 45, Mapper45_Init},
{(uint8_t*)"RUMBLESTATION 15-in-1",46, Mapper46_Init},
{(uint8_t*)"NES-QJ SSVB/NWC", 47, Mapper47_Init},
{(uint8_t*)"TAITO TCxxx", 48, Mapper48_Init},
{(uint8_t*)"MMC3 BMC PIRATE C", 49, Mapper49_Init},
{(uint8_t*)"SMB2j FDS Rev. A", 50, Mapper50_Init},
2017-10-15 03:13:11 +08:00
{(uint8_t*)"11-in-1 BALL SERIES", 51, Mapper51_Init}, /* 1993 year version */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"MMC3 BMC PIRATE D", 52, Mapper52_Init},
{(uint8_t*)"SUPERVISION 16-in-1", 53, Supervision16_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 54, Mapper54_Init}, */
/* {(uint8_t*)"", 55, Mapper55_Init}, */
{(uint8_t*)"UNLKS202", 56, UNLKS202_Init},
2016-09-09 09:10:10 +02:00
{(uint8_t*)"SIMBPLE BMC PIRATE A", 57, Mapper57_Init},
{(uint8_t*)"SIMBPLE BMC PIRATE B", 58, BMCGK192_Init},
2017-10-15 03:13:11 +08:00
{(uint8_t*)"", 59, Mapper59_Init}, /* Check this out */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"SIMBPLE BMC PIRATE C", 60, BMCD1038_Init},
{(uint8_t*)"20-in-1 KAISER Rev. A",61, Mapper61_Init},
{(uint8_t*)"700-in-1", 62, Mapper62_Init},
{(uint8_t*)"", 63, Mapper63_Init},
2016-09-09 09:10:10 +02:00
{(uint8_t*)"TENGEN RAMBO1", 64, Mapper64_Init},
{(uint8_t*)"IREM-H3001", 65, Mapper65_Init},
{(uint8_t*)"MHROM", 66, MHROM_Init},
{(uint8_t*)"SUNSOFT-FZII", 67, Mapper67_Init},
{(uint8_t*)"Sunsoft Mapper #4", 68, Mapper68_Init},
{(uint8_t*)"SUNSOFT-5/FME-7", 69, Mapper69_Init},
{(uint8_t*)"BA KAMEN DISCRETE", 70, Mapper70_Init},
{(uint8_t*)"CAMERICA BF9093", 71, Mapper71_Init},
{(uint8_t*)"JALECO JF-17", 72, Mapper72_Init},
{(uint8_t*)"KONAMI VRC3", 73, Mapper73_Init},
{(uint8_t*)"TW MMC3+VRAM Rev. A", 74, Mapper74_Init},
{(uint8_t*)"KONAMI VRC1", 75, Mapper75_Init},
{(uint8_t*)"NAMCOT 108 Rev. A", 76, Mapper76_Init},
{(uint8_t*)"IREM LROG017", 77, Mapper77_Init},
{(uint8_t*)"Irem 74HC161/32", 78, Mapper78_Init},
{(uint8_t*)"AVE/C&E/TXC BOARD", 79, Mapper79_Init},
{(uint8_t*)"TAITO X1-005 Rev. A", 80, Mapper80_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 81, Mapper81_Init}, */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"TAITO X1-017", 82, Mapper82_Init},
2016-09-09 07:59:43 +02:00
{(uint8_t*)"YOKO VRC Rev. B", 83, Mapper83_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 84, Mapper84_Init}, */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"KONAMI VRC7", 85, Mapper85_Init},
{(uint8_t*)"JALECO JF-13", 86, Mapper86_Init},
{(uint8_t*)"74*139/74 DISCRETE", 87, Mapper87_Init},
{(uint8_t*)"NAMCO 3433", 88, Mapper88_Init},
2017-10-15 03:13:11 +08:00
{(uint8_t*)"SUNSOFT-3", 89, Mapper89_Init}, /* SUNSOFT-2 mapper */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"HUMMER/JY BOARD", 90, Mapper90_Init},
{(uint8_t*)"EARLY HUMMER/JY BOARD",91, Mapper91_Init},
{(uint8_t*)"JALECO JF-19", 92, Mapper92_Init},
2017-10-15 03:13:11 +08:00
{(uint8_t*)"SUNSOFT-3R", 93, SUNSOFT_UNROM_Init},/* SUNSOFT-2 mapper with VRAM, different wiring */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"HVC-UN1ROM", 94, Mapper94_Init},
{(uint8_t*)"NAMCOT 108 Rev. B", 95, Mapper95_Init},
{(uint8_t*)"BANDAI OEKAKIDS", 96, Mapper96_Init},
{(uint8_t*)"IREM TAM-S1", 97, Mapper97_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 98, Mapper98_Init}, */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"VS Uni/Dual- system", 99, Mapper99_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 100, Mapper100_Init}, */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"", 101, Mapper101_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 102, Mapper102_Init}, */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"FDS DOKIDOKI FULL", 103, Mapper103_Init},
{(uint8_t*)"CAMERICA GOLDENFIVE", 104, Mapper104_Init},
2016-09-09 09:10:10 +02:00
{(uint8_t*)"NES-EVENT NWC1990", 105, Mapper105_Init},
{(uint8_t*)"SMB3 PIRATE A", 106, Mapper106_Init},
{(uint8_t*)"MAGIC CORP A", 107, Mapper107_Init},
{(uint8_t*)"FDS UNROM BOARD", 108, Mapper108_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 109, Mapper109_Init}, */
/* {(uint8_t*)"", 110, Mapper110_Init}, */
{(uint8_t*)"Cheapocabra", 111, Mapper111_Init},
2016-09-09 09:10:10 +02:00
{(uint8_t*)"ASDER/NTDEC BOARD", 112, Mapper112_Init},
{(uint8_t*)"HACKER/SACHEN BOARD", 113, Mapper113_Init},
{(uint8_t*)"MMC3 SG PROT. A", 114, Mapper114_Init},
{(uint8_t*)"MMC3 PIRATE A", 115, Mapper115_Init},
{(uint8_t*)"MMC1/MMC3/VRC PIRATE",116, UNLSL12_Init},
{(uint8_t*)"FUTURE MEDIA BOARD", 117, Mapper117_Init},
{(uint8_t*)"TSKROM", 118, TKSROM_Init},
{(uint8_t*)"NES-TQROM", 119, Mapper119_Init},
{(uint8_t*)"FDS TOBIDASE", 120, Mapper120_Init},
{(uint8_t*)"MMC3 PIRATE PROT. A", 121, Mapper121_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 122, Mapper122_Init}, */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"MMC3 PIRATE H2288", 123, UNLH2288_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 124, Mapper124_Init}, */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"FDS LH32", 125, LH32_Init},
{(uint8_t*)"PowerJoy 84-in-1 PJ-008", 126, Mapper126_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 127, Mapper127_Init}, */
/* {(uint8_t*)"", 128, Mapper128_Init}, */
/* {(uint8_t*)"", 129, Mapper129_Init}, */
/* {(uint8_t*)"", 130, Mapper130_Init}, */
/* {(uint8_t*)"", 131, Mapper131_Init}, */
{(uint8_t*)"TXC/UNL-22211", 132, Mapper132_Init},
2016-09-09 09:10:10 +02:00
{(uint8_t*)"SA72008", 133, SA72008_Init},
/* {(uint8_t*)"MMC3 BMC PIRATE", 134, Mapper134_Init}, */
{(uint8_t*)"MMC3 BMC PIRATE", 134, Bs5652_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 135, Mapper135_Init}, */
{(uint8_t*)"Sachen 3011", 136, Mapper136_Init},
2016-09-09 09:10:10 +02:00
{(uint8_t*)"S8259D", 137, S8259D_Init},
{(uint8_t*)"S8259B", 138, S8259B_Init},
{(uint8_t*)"S8259C", 139, S8259C_Init},
{(uint8_t*)"JALECO JF-11/14", 140, Mapper140_Init},
{(uint8_t*)"S8259A", 141, S8259A_Init},
{(uint8_t*)"UNLKS7032", 142, UNLKS7032_Init},
{(uint8_t*)"TCA01", 143, TCA01_Init},
{(uint8_t*)"AGCI 50282", 144, Mapper144_Init},
{(uint8_t*)"SA72007", 145, SA72007_Init},
{(uint8_t*)"SA0161M", 146, SA0161M_Init},
{(uint8_t*)"Sachen 3018 board", 147, Mapper147_Init},
2016-09-09 09:10:10 +02:00
{(uint8_t*)"SA0037", 148, SA0037_Init},
{(uint8_t*)"SA0036", 149, SA0036_Init},
{(uint8_t*)"SA-015/SA-630", 150, S74LS374N_Init},
2016-09-09 09:10:10 +02:00
{(uint8_t*)"", 151, Mapper151_Init},
{(uint8_t*)"", 152, Mapper152_Init},
2017-10-15 03:13:11 +08:00
{(uint8_t*)"BANDAI SRAM", 153, Mapper153_Init}, /* Bandai board 16 with SRAM instead of EEPROM */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"", 154, Mapper154_Init},
{(uint8_t*)"", 155, Mapper155_Init},
{(uint8_t*)"", 156, Mapper156_Init},
{(uint8_t*)"BANDAI BARCODE", 157, Mapper157_Init},
2017-05-10 04:07:50 +08:00
{(uint8_t*)"TENGEN 800037", 158, Mapper158_Init},
2017-10-15 03:13:11 +08:00
{(uint8_t*)"BANDAI 24C01", 159, Mapper159_Init}, /* Different type of EEPROM on the bandai board */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"SA009", 160, SA009_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 161, Mapper161_Init}, */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"", 162, UNLFS304_Init},
{(uint8_t*)"", 163, Mapper163_Init},
{(uint8_t*)"", 164, Mapper164_Init},
{(uint8_t*)"", 165, Mapper165_Init},
{(uint8_t*)"SUBOR Rev. A", 166, Mapper166_Init},
{(uint8_t*)"SUBOR Rev. B", 167, Mapper167_Init},
{(uint8_t*)"", 168, Mapper168_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 169, Mapper169_Init}, */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"", 170, Mapper170_Init},
{(uint8_t*)"", 171, Mapper171_Init},
{(uint8_t*)"Super Mega P-4070", 172, Mapper172_Init},
{(uint8_t*)"Idea-Tek ET.xx", 173, Mapper173_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 174, Mapper174_Init}, */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"", 175, Mapper175_Init},
2017-10-15 03:13:11 +08:00
{(uint8_t*)"BMCFK23C", 176, BMCFK23C_Init}, /* zero 26-may-2012 - well, i have some WXN junk games that use 176 for instance ????. i dont know what game uses this BMCFK23C as mapper 176. we'll have to make a note when we find it. */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"", 177, Mapper177_Init},
{(uint8_t*)"", 178, Mapper178_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 179, Mapper179_Init}, */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"", 180, Mapper180_Init},
{(uint8_t*)"", 181, Mapper181_Init},
/* {(uint8_t*)"", 182, Mapper182_Init}, */ /* Deprecated, dupe of Mapper 114 */
{(uint8_t*)"", 183, Mapper183_Init},
2016-09-09 09:10:10 +02:00
{(uint8_t*)"", 184, Mapper184_Init},
{(uint8_t*)"", 185, Mapper185_Init},
{(uint8_t*)"", 186, Mapper186_Init},
{(uint8_t*)"", 187, Mapper187_Init},
{(uint8_t*)"", 188, Mapper188_Init},
2016-09-09 09:10:10 +02:00
{(uint8_t*)"", 189, Mapper189_Init},
2017-02-18 01:51:59 +08:00
{(uint8_t*)"", 190, Mapper190_Init},
2016-09-09 09:10:10 +02:00
{(uint8_t*)"", 191, Mapper191_Init},
{(uint8_t*)"TW MMC3+VRAM Rev. B", 192, Mapper192_Init},
2017-10-15 03:13:11 +08:00
{(uint8_t*)"NTDEC TC-112", 193, Mapper193_Init}, /* War in the Gulf */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"TW MMC3+VRAM Rev. C", 194, Mapper194_Init},
{(uint8_t*)"TW MMC3+VRAM Rev. D", 195, Mapper195_Init},
{(uint8_t*)"", 196, Mapper196_Init},
{(uint8_t*)"", 197, Mapper197_Init},
{(uint8_t*)"TW MMC3+VRAM Rev. E", 198, Mapper198_Init},
{(uint8_t*)"", 199, Mapper199_Init},
{(uint8_t*)"", 200, Mapper200_Init},
{(uint8_t*)"", 201, Mapper201_Init},
{(uint8_t*)"", 202, Mapper202_Init},
{(uint8_t*)"", 203, Mapper203_Init},
{(uint8_t*)"", 204, Mapper204_Init},
{(uint8_t*)"BMC 15-in-1/3-in-1", 205, Mapper205_Init},
2017-10-15 03:13:11 +08:00
{(uint8_t*)"NAMCOT 108 Rev. C", 206, Mapper206_Init}, /* Deprecated, Used to be "DEIROM" whatever it means, but actually simple version of MMC3 */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"TAITO X1-005 Rev. B", 207, Mapper207_Init},
{(uint8_t*)"", 208, Mapper208_Init},
2017-04-30 17:35:33 +08:00
{(uint8_t*)"HUMMER/JY BOARD", 209, Mapper209_Init},
{(uint8_t*)"", 210, Mapper210_Init},
2017-04-30 17:35:33 +08:00
{(uint8_t*)"HUMMER/JY BOARD", 211, Mapper211_Init},
2016-09-09 09:10:10 +02:00
{(uint8_t*)"", 212, Mapper212_Init},
{(uint8_t*)"", 213, Mapper213_Init},
{(uint8_t*)"", 214, Mapper214_Init},
{(uint8_t*)"UNL-8237", 215, UNL8237_Init},
2016-09-09 09:10:10 +02:00
{(uint8_t*)"", 216, Mapper216_Init},
2017-10-15 03:13:11 +08:00
{(uint8_t*)"", 217, Mapper217_Init}, /* Redefined to a new Discrete BMC mapper */
2020-02-18 09:46:47 +08:00
{(uint8_t*)"Magic Floor", 218, Mapper218_Init},
2016-09-09 09:10:10 +02:00
{(uint8_t*)"UNLA9746", 219, UNLA9746_Init},
2017-04-30 06:44:51 +08:00
{(uint8_t*)"Debug Mapper", 220, UNLKS7057_Init},
2016-09-09 09:10:10 +02:00
{(uint8_t*)"UNLN625092", 221, UNLN625092_Init},
{(uint8_t*)"", 222, Mapper222_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 223, Mapper223_Init}, */
{(uint8_t*)"KT-008", 224, Mapper224_Init},
2016-09-09 09:10:10 +02:00
{(uint8_t*)"", 225, Mapper225_Init},
{(uint8_t*)"BMC 22+20-in-1", 226, Mapper226_Init},
{(uint8_t*)"", 227, Mapper227_Init},
{(uint8_t*)"", 228, Mapper228_Init},
{(uint8_t*)"", 229, Mapper229_Init},
{(uint8_t*)"BMC Contra+22-in-1", 230, Mapper230_Init},
{(uint8_t*)"", 231, Mapper231_Init},
{(uint8_t*)"BMC QUATTRO", 232, Mapper232_Init},
{(uint8_t*)"BMC 22+20-in-1 RST", 233, Mapper233_Init},
{(uint8_t*)"BMC MAXI", 234, Mapper234_Init},
{(uint8_t*)"Golden Game", 235, Mapper235_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 236, Mapper236_Init}, */
{(uint8_t*)"Teletubbies / Y2K", 237, Mapper237_Init},
2016-09-09 09:10:10 +02:00
{(uint8_t*)"UNL6035052", 238, UNL6035052_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 239, Mapper239_Init}, */
2016-09-09 09:10:10 +02:00
{(uint8_t*)"", 240, Mapper240_Init},
{(uint8_t*)"", 241, Mapper241_Init},
{(uint8_t*)"", 242, Mapper242_Init},
{(uint8_t*)"SA-020A", 243, S74LS374N_Init},
2016-09-09 07:59:43 +02:00
{(uint8_t*)"DECATHLON", 244, Mapper244_Init},
{(uint8_t*)"", 245, Mapper245_Init},
{(uint8_t*)"FONG SHEN BANG", 246, Mapper246_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 247, Mapper247_Init}, */
/* {(uint8_t*)"", 248, Mapper248_Init}, */
2016-09-09 07:59:43 +02:00
{(uint8_t*)"", 249, Mapper249_Init},
{(uint8_t*)"", 250, Mapper250_Init},
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 251, Mapper251_Init}, */ /* No good dumps for this mapper, use UNIF version */
2016-09-09 07:59:43 +02:00
{(uint8_t*)"SAN GUO ZHI PIRATE", 252, Mapper252_Init},
{(uint8_t*)"DRAGON BALL PIRATE", 253, Mapper253_Init},
{(uint8_t*)"", 254, Mapper254_Init},
{(uint8_t*)"", 255, Mapper255_Init}, /* Duplicate of M225? */
/* -------------- ----NES 2.0 -------------------------- */
/* NES 2.0 BOARDS THAT DO NOT HAVE UNIF ASSOCIATION */
{(uint8_t*)"OK-411", 361, GN45_Init}, /* OK-411 is emulated together with GN-45 */
{(uint8_t*)"HUMMER/JY-052", 281, Mapper281_Init},
{(uint8_t*)"GN-45", 366, GN45_Init},
2020-01-28 11:06:43 +08:00
2020-01-28 13:45:59 +08:00
{(uint8_t*)"GKCX1", 288, Mapper288_Init },
2020-01-28 02:05:10 +08:00
{(uint8_t*)"Bit Corp 4-in-1", 357, Mapper357_Init },
2020-01-28 08:15:53 +08:00
{(uint8_t*)"MMC3 PIRATE SFC-12", 372, Mapper372_Init },
2020-01-29 01:09:31 +08:00
{(uint8_t*)"95/96 Super HiK 4-in-1", 374, Mapper374_Init },
2020-01-28 12:07:47 +08:00
{(uint8_t*)"KN-42", 381, Mapper381_Init },
2020-01-29 03:10:11 +08:00
{(uint8_t*)"Realtec 8031", 390, Mapper390_Init },
2020-01-28 11:42:04 +08:00
{(uint8_t*)"60-1064-16L (FDS)", 538, Mapper538_Init },
2020-01-28 11:06:43 +08:00
{(uint8_t*)"LittleCom 160-in-1", 541, Mapper541_Init },
2020-02-05 12:00:54 +08:00
{(uint8_t*)"8-in-1 JY-119", 267, Mapper267_Init },
2020-01-31 00:13:09 +08:00
{(uint8_t*)"MMC3 BMC PIRATE", 294, Bs5652_Init}, /* nesdev redirects this as mapper 134 */
{(uint8_t*)"TXC 01-22110-000", 297, Mapper297_Init},
2020-02-01 09:33:44 +08:00
{(uint8_t*)"Bitcorp 31-in-1", 360, Mapper360_Init},
2020-02-05 12:00:54 +08:00
{(uint8_t*)"Sachen 3014", 533, Mapper533_Init},
{(uint8_t*)"830928C", 382, Mapper382_Init},
{(uint8_t*)"NJ064", 534, Mapper534_Init},
{(uint8_t*)"Kid Ikarus (FDS)", 539, Mapper539_Init},
2020-02-06 20:02:32 +08:00
{(uint8_t*)"5-in-1 (CH-501)", 543, Mapper543_Init},
{(uint8_t*)"", 550, Mapper550_Init},
{(uint8_t*)"Brilliant Com Cocoma Pack", 516, Mapper516_Init},
{(uint8_t*)"SB-5013/GCL8050/841242C", 359, Mapper359_Init},
{(uint8_t*)"82112C", 540, Mapper540_Init},
{(uint8_t*)"7-in-1 Rockman (JY-208)", 356, Mapper356_Init},
{(uint8_t*)"Games Xplosion 121-in-1", 269, Mapper269_Init},
{(uint8_t*)"Super Mario Family", 353, Mapper353_Init},
2020-01-28 02:05:10 +08:00
/* UNIF to NES 2.0 BOARDS */
{(uint8_t*)"OneBus", 256, UNLOneBus_Init },
{(uint8_t*)"158B", 258, UNL158B_Init },
{(uint8_t*)"F-15", 259, BMCF15_Init },
{(uint8_t*)"HPxx / HP2018-A", 260, BMCHPxx_Init },
{(uint8_t*)"810544-C-A1", 261, BMC810544CA1_Init },
{(uint8_t*)"SHERO", 262, UNLSHeroes_Init },
{(uint8_t*)"KOF97", 263, UNLKOF97_Init },
{(uint8_t*)"YOKO", 264, UNLYOKO_Init },
{(uint8_t*)"T-262", 265, BMCT262_Init },
{(uint8_t*)"CITYFIGHT", 266, UNLCITYFIGHT_Init },
{(uint8_t*)"COOLBOY", 268, COOLBOY_Init },
/* {(uint8_t*)"MINDKIDS", 268, MINDKIDS_Init }, */
{(uint8_t*)"80013-B", 274, BMC80013B_Init },
{(uint8_t*)"GS-2004", 283, BMCGS2004_Init },
/* {(uint8_t*)"GS-2013", 283, BMCGS2013_Init }, */
{(uint8_t*)"A65AS", 285, BMCA65AS_Init },
{(uint8_t*)"BS-5", 286, BMCBS5_Init },
{(uint8_t*)"411120-C", 287, BMC411120C_Init },
/* {(uint8_t*)"K-3088", 287, BMCK3088_Init }, */
{(uint8_t*)"60311C", 289, BMC60311C_Init },
{(uint8_t*)"NTD-03", 290, BMCNTD03_Init },
{(uint8_t*)"DRAGONFIGHTER", 292, UNLBMW8544_Init },
{(uint8_t*)"13in1JY110", 295, BMC13in1JY110_Init },
{(uint8_t*)"TF1201", 298, UNLTF1201_Init },
{(uint8_t*)"11160", 299, BMC11160_Init },
{(uint8_t*)"190in1", 300, BMC190in1_Init },
{(uint8_t*)"8157", 301, UNL8157_Init },
{(uint8_t*)"KS7057", 302, UNLKS7057_Init },
{(uint8_t*)"KS7017", 303, UNLKS7017_Init },
{(uint8_t*)"SMB2J", 304, UNLSMB2J_Init },
{(uint8_t*)"KS7031", 305, UNLKS7031_Init },
{(uint8_t*)"KS7016", 306, UNLKS7016_Init },
{(uint8_t*)"KS7037", 307, UNLKS7037_Init },
{(uint8_t*)"TH2131-1", 308, UNLTH21311_Init },
{(uint8_t*)"LH51", 309, LH51_Init },
{(uint8_t*)"KS7013B", 312, UNLKS7013B_Init },
{(uint8_t*)"RESET-TXROM", 313, BMCRESETTXROM_Init },
{(uint8_t*)"64in1NoRepeat", 314, BMC64in1nr_Init },
{(uint8_t*)"830134C", 315, BMC830134C_Init },
{(uint8_t*)"HP898F", 319, BMCHP898F_Init },
{(uint8_t*)"830425C-4391T", 320, BMC830425C4391T_Init },
{(uint8_t*)"K-3033", 322, BMCK3033_Init },
{(uint8_t*)"FARID_SLROM_8-IN-1", 323, FARIDSLROM8IN1_Init },
{(uint8_t*)"FARID_UNROM_8-IN-1", 324, FARIDUNROM_Init },
{(uint8_t*)"MALISB", 325, UNLMaliSB_Init },
{(uint8_t*)"10-24-C-A1", 327, BMC1024CA1_Init },
{(uint8_t*)"RT-01", 328, UNLRT01_Init },
{(uint8_t*)"EDU2000", 329, UNLEDU2000_Init },
{(uint8_t*)"12-IN-1", 331, BMC12IN1_Init },
{(uint8_t*)"WS", 332, BMCWS_Init },
{(uint8_t*)"NEWSTAR-GRM070-8IN1", 333, BMC8IN1_Init },
{(uint8_t*)"CTC-09", 335, BMCCTC09_Init },
{(uint8_t*)"K-3046", 336, BMCK3046_Init },
{(uint8_t*)"CTC-12IN1", 337, BMCCTC12IN1_Init },
{(uint8_t*)"SA005-A", 338, BMCSA005A_Init },
{(uint8_t*)"K-3006", 339, BMCK3006_Init },
{(uint8_t*)"K-3036", 340, BMCK3036_Init },
{(uint8_t*)"TJ-03", 341, BMCTJ03_Init },
{(uint8_t*)"GN-26", 344, BMCGN26_Init },
{(uint8_t*)"L6IN1", 345, BMCL6IN1_Init },
{(uint8_t*)"KS7012", 346, UNLKS7012_Init },
{(uint8_t*)"KS7030", 347, UNLKS7030_Init },
{(uint8_t*)"830118C", 348, BMC830118C_Init },
{(uint8_t*)"G-146", 349, BMCG146_Init },
{(uint8_t*)"891227", 350, BMC891227_Init },
{(uint8_t*)"3D-BLOCK", 355, UNL3DBlock_Init },
{(uint8_t*)"NC7000M", 391, NC7000M_Init },
{(uint8_t*)"831019C J-2282", 402, J2282_Init },
{(uint8_t*)"SA-9602B", 513, SA9602B_Init },
{(uint8_t*)"DANCE2000", 518, UNLD2000_Init },
{(uint8_t*)"EH8813A", 519, UNLEH8813A_Init },
{(uint8_t*)"DREAMTECH01", 521, DreamTech01_Init },
{(uint8_t*)"LH10", 522, LH10_Init },
{(uint8_t*)"900218", 524, BTL900218_Init },
{(uint8_t*)"KS7021A", 525, UNLKS7021A_Init },
{(uint8_t*)"BJ-56", 526, UNLBJ56_Init },
{(uint8_t*)"AX-40G", 527, UNLAX40G_Init },
{(uint8_t*)"T-230", 529, UNLT230_Init },
{(uint8_t*)"AX5705", 530, UNLAX5705_Init },
{(uint8_t*)"LH53", 535, LH53_Init },
{(uint8_t*)"", 0, NULL}
};
2014-03-30 22:50:28 +02:00
int iNESLoad(const char *name, FCEUFILE *fp) {
struct md5_context md5;
char* mappername = NULL;
uint64 filesize = FCEU_fgetsize(fp);
uint64 romSize = 0;
uint32 mappertest = 0;
uint32 prgRom = 0;
uint32 chrRom = 0;
uint32 region = 0;
if (FCEU_fread(&head, 1, 16, fp) != 16)
return 0;
filesize -= 16; /* remove header size from total size */
if (memcmp(&head, "NES\x1a", 4)) {
FCEU_PrintError("Not an iNES file!\n");
return 0;
}
memset(&iNESCart, 0, sizeof(iNESCart));
if (!memcmp((char*)(&head) + 0x7, "DiskDude", 8)) {
memset((char*)(&head) + 0x7, 0, 0x9);
}
if (!memcmp((char*)(&head) + 0x7, "demiforce", 9)) {
memset((char*)(&head) + 0x7, 0, 0x9);
}
if (!memcmp((char*)(&head) + 0xA, "Ni03", 4)) {
if (!memcmp((char*)(&head) + 0x7, "Dis", 3))
memset((char*)(&head) + 0x7, 0, 0x9);
else
memset((char*)(&head) + 0xA, 0, 0x6);
}
subMapper = 0;
MapperNo = (head.ROM_type >> 4) | (head.ROM_type2 & 0xF0);
Mirroring = (head.ROM_type & 8) ? 2 : (head.ROM_type & 1);
prgRom = head.ROM_size;
chrRom = head.VROM_size;
iNES2 = ((head.ROM_type2 & 0x0C) == 0x08) ? 1 : 0;
if (iNES2) {
MapperNo |= ((uint32)head.ROM_type3 << 8) & 0xF00;
prgRom |= ((uint32)head.upper_PRG_CHR_size << 8) & 0xF00;
chrRom |= ((uint32)head.upper_PRG_CHR_size << 4) & 0xF00;
subMapper = (head.ROM_type3 >> 4) & 0x0F;
2020-02-16 22:30:15 +08:00
iNESCart.PRGRamSize = (head.PRGRAM_size & 0x0F) ? (64 << (head.PRGRAM_size & 0x0F)) : 0;
iNESCart.CHRRamSize = (head.CHRRAM_size & 0x0F) ? (64 << (head.CHRRAM_size & 0x0F)) : 0;
iNESCart.PRGRamSaveSize = (head.PRGRAM_size & 0xF0) ? (64 << ((head.PRGRAM_size & 0xF0) >> 4)) : 0;
iNESCart.CHRRamSaveSize = (head.CHRRAM_size & 0xF0) ? (64 << ((head.CHRRAM_size & 0xF0) >> 4)) : 0;
region = (head.Region & 3);
} else {
if (!prgRom)
prgRom = 256;
}
/* Trainer */
if (head.ROM_type & 4) {
trainerpoo = (uint8*)FCEU_gmalloc(512);
FCEU_fread(trainerpoo, 512, 1, fp);
filesize -= 512;
}
romSize = (prgRom * 0x4000) + (chrRom * 0x2000);
if (romSize > filesize) {
FCEU_PrintError(" File length is too short to contain all data reported from header by %llu\n", romSize - filesize);
return 0;
} else if (romSize < filesize)
FCEU_PrintError(" File contains %llu bytes of unused data\n", filesize - romSize);
iNESCart.PRGRomSize = prgRom;
iNESCart.CHRRomSize = chrRom;
ROM_size = uppow2(prgRom);
if (chrRom)
VROM_size = uppow2(chrRom);
if ((ROM = (uint8*)FCEU_malloc(ROM_size << 14)) == NULL)
return 0;
memset(ROM, 0xFF, ROM_size << 14);
if (VROM_size) {
if ((VROM = (uint8*)FCEU_malloc(VROM_size << 13)) == NULL) {
free(ROM);
ROM = NULL;
return 0;
}
memset(VROM, 0xFF, VROM_size << 13);
}
ResetCartMapping();
ResetExState(0, 0);
SetupCartPRGMapping(0, ROM, ROM_size << 14, 0);
FCEU_fread(ROM, 0x4000, prgRom, fp);
if (VROM_size)
FCEU_fread(VROM, 0x2000, chrRom, fp);
iNESCart.PRGCRC32 = CalcCRC32(0, ROM, prgRom * 0x4000);
iNESCart.CHRCRC32 = CalcCRC32(0, VROM, chrRom * 0x2000);
iNESCart.CRC32 = CalcCRC32(iNESCart.PRGCRC32, VROM, chrRom * 0x2000);
md5_starts(&md5);
md5_update(&md5, ROM, prgRom << 14);
if (VROM_size)
md5_update(&md5, VROM, chrRom << 13);
md5_finish(&md5, iNESCart.MD5);
memcpy(&GameInfo->MD5, &iNESCart.MD5, sizeof(iNESCart.MD5));
mappername = "Not Listed";
for (mappertest = 0; mappertest < (sizeof bmap / sizeof bmap[0]) - 1; mappertest++) {
if (bmap[mappertest].number == MapperNo) {
mappername = (char*)bmap[mappertest].name;
break;
}
}
FCEU_printf(" PRG-ROM CRC32: 0x%08X\n", iNESCart.PRGCRC32);
FCEU_printf(" PRG+CHR CRC32: 0x%08X\n", iNESCart.CRC32);
FCEU_printf(" PRG+CHR MD5: 0x%s\n", md5_asciistr(iNESCart.MD5));
FCEU_printf(" PRG-ROM: %3d x 16KiB\n", prgRom);
FCEU_printf(" CHR-ROM: %3d x 8KiB\n", chrRom);
if (iNES2) {
const char *tv_region[] = { "NTSC", "PAL", "Multi-region", "Dendy" };
unsigned PRGRAM = iNESCart.PRGRamSize + iNESCart.PRGRamSaveSize;
unsigned CHRRAM = iNESCart.CHRRamSize + iNESCart.CHRRamSaveSize;
FCEU_printf(" NES 2.0 extended iNES.\n");
FCEU_printf(" Mapper #: %3d\n", MapperNo);
FCEU_printf(" Sub Mapper #: %3d\n", subMapper);
FCEU_printf(" Mapper name: %s\n", mappername);
if (PRGRAM || CHRRAM) {
FCEU_printf(" PRG RAM: %d KB\n", PRGRAM / 1024);
FCEU_printf(" CHR RAM: %d KB\n", CHRRAM / 1024);
if (head.ROM_type & 0x02) {
FCEU_printf(" PRG RAM backed by battery: %d KiB\n", iNESCart.PRGRamSaveSize / 1024);
FCEU_printf(" CHR RAM backed by battery: %d KiB\n", iNESCart.CHRRamSaveSize / 1024);
}
}
FCEU_printf(" Mirroring: %s\n", Mirroring == 2 ? "None (Four-screen)" : Mirroring ? "Vertical" : "Horizontal");
FCEU_printf(" System: %s\n", tv_region[region]);
FCEU_printf(" Trained: %s\n", (head.ROM_type & 4) ? "Yes" : "No");
} else {
FCEU_printf(" Mapper #: %3d\n", MapperNo);
FCEU_printf(" Mapper name: %s\n", mappername);
FCEU_printf(" Mirroring: %s\n", Mirroring == 2 ? "None (Four-screen)" : Mirroring ? "Vertical" : "Horizontal");
FCEU_printf(" Battery-backed: %s\n", (head.ROM_type & 2) ? "Yes" : "No");
FCEU_printf(" Trained: %s\n", (head.ROM_type & 4) ? "Yes" : "No");
}
SetInput();
CheckHInfo();
{
int x;
uint64 partialmd5 = 0;
for (x = 0; x < 8; x++) {
partialmd5 |= (uint64)iNESCart.MD5[7 - x] << (x * 8);
}
FCEU_VSUniCheck(partialmd5, &MapperNo, &Mirroring);
}
/* Must remain here because above functions might change value of
* VROM_size and free(VROM).
*/
if (VROM_size)
SetupCartCHRMapping(0, VROM, VROM_size * 0x2000, 0);
if (Mirroring == 2) {
ExtraNTARAM = (uint8*)FCEU_gmalloc(2048);
SetupCartMirroring(4, 1, ExtraNTARAM);
} else if (Mirroring >= 0x10)
SetupCartMirroring(2 + (Mirroring & 1), 1, 0);
else
SetupCartMirroring(Mirroring & 1, (Mirroring & 4) >> 2, 0);
iNESCart.iNES2 = iNES2;
iNESCart.mapper = MapperNo;
iNESCart.submapper = subMapper;
iNESCart.battery = (head.ROM_type & 2) ? 1 : 0;
iNESCart.mirror = Mirroring;
if (!iNES_Init(MapperNo)) {
FCEU_printf("\n");
FCEU_PrintError(" iNES mapper #%d is not supported at all.\n", MapperNo);
return 0;
}
GameInterface = iNESGI;
if (iNES2 == 0) {
if (strstr(name, "(E)") || strstr(name, "(e)") ||
strstr(name, "(Europe)") || strstr(name, "(PAL)") ||
strstr(name, "(F)") || strstr(name, "(f)") ||
strstr(name, "(G)") || strstr(name, "(g)") ||
strstr(name, "(I)") || strstr(name, "(i)") ||
strstr(name, "(S)") || strstr(name, "(s)") ||
strstr(name, "(France)") || strstr(name, "(Germany)") ||
strstr(name, "(Italy)") || strstr(name, "(Spain)") ||
strstr(name, "(Sweden)") || strstr(name, "(Sw)") ||
strstr(name, "(Australia)") || strstr(name, "(A)") ||
strstr(name, "(a)")) {
region = 1;
} else {
region = 0;
}
}
iNESCart.region = region;
switch (region) {
/* 0: RP2C02 ("NTSC NES")
* 1: RP2C07 ("Licensed PAL NES")
* 2: Multiple-region
* 3: UMC 6527P ("Dendy")
*/
case 1:
FCEUI_SetVidSystem(1);
break;
case 3:
dendy = 1;
/* fallthrough */
case 0:
case 2:
FCEUI_SetVidSystem(0);
break;
}
return 1;
}
static int iNES_Init(int num) {
BMAPPINGLocal *tmp = bmap;
CHRRAMSize = -1;
if (GameInfo->type == GIT_VSUNI)
AddExState(FCEUVSUNI_STATEINFO, ~0, 0, 0);
while (tmp->init) {
if (num == tmp->number) {
2017-10-15 03:13:11 +08:00
UNIFchrrama = 0; /* need here for compatibility with UNIF mapper code */
if (!VROM_size) {
if (iNESCart.iNES2) {
CHRRAMSize = iNESCart.CHRRamSize + iNESCart.CHRRamSaveSize;
} else {
switch (num) { /* FIXME, mapper or game data base with the board parameters and ROM/RAM sizes */
case 13: CHRRAMSize = 16 * 1024; break;
case 6:
case 28:
case 29:
case 30:
case 45:
case 96:
case 513: CHRRAMSize = 32 * 1024; break;
case 176: CHRRAMSize = 128 * 1024; break;
case 268: CHRRAMSize = 256 * 1024; break;
default: CHRRAMSize = 8 * 1024; break;
}
iNESCart.CHRRamSize = CHRRAMSize;
}
if (CHRRAMSize) { /* TODO: CHR-RAM are sometimes handled in mappers e.g. MMC1 using submapper 1/2/4 and CHR-RAM can be zero here */
if ((VROM = (uint8*)malloc(CHRRAMSize)) == NULL) return 0;
FCEU_MemoryRand(VROM, CHRRAMSize);
UNIFchrrama = VROM;
SetupCartCHRMapping(0, VROM, CHRRAMSize, 1);
AddExState(VROM, CHRRAMSize, 0, "CHRR");
2020-02-18 09:53:45 +08:00
FCEU_printf(" CHR-RAM: %3d KiB\n", CHRRAMSize / 1024);
}
}
if (head.ROM_type & 8)
AddExState(ExtraNTARAM, 2048, 0, "EXNR");
tmp->init(&iNESCart);
return 1;
}
tmp++;
}
return 0;
}