2014-03-30 22:15:17 +02:00
/* 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"
2014-03-30 22:15:17 +02:00
# 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 ;
2014-03-30 22:15:17 +02:00
uint8 Mirroring = 0 ;
uint32 ROM_size = 0 ;
uint32 VROM_size = 0 ;
static int CHRRAMSize = - 1 ;
static int iNES_Init ( int num ) ;
static int MapperNo = 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 ) {
2017-05-08 04:24:03 +02:00
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 ;
}
2014-03-30 22:15:17 +02:00
}
uint32 iNESGameCRC32 = 0 ;
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 */
2014-03-30 22:15:17 +02:00
{ 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 = = iNESGameCRC32 ) {
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 ;
for ( x = 0 ; x < 8 ; x + + )
partialmd5 | = ( uint64 ) iNESCart . MD5 [ 15 - x ] < < ( x * 8 ) ;
CheckBad ( partialmd5 ) ;
x = 0 ;
do {
if ( moo [ x ] . crc32 = = iNESGameCRC32 ) {
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 & 0xFF ) ) {
tofix | = 1 ;
MapperNo = moo [ x ] . mapper & 0xFF ;
}
}
if ( moo [ x ] . mirror > = 0 ) {
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 ) , " The mapper number should be set to %d. " , 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 " } ;
2014-03-30 22:15:17 +02:00
sprintf ( gigastr + strlen ( gigastr ) , " Mirroring should be set to \" %s \" . " , 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 " , 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*)"", 28, Mapper28_Init}, */ /* Custom Multidiscrete mapper for PDs */
/* {(uint8_t*)"", 29, Mapper29_Init}, */
2017-04-30 06:44:51 +08:00
{ ( uint8_t * ) " UNROM 512 " , 30 , UNROM512_Init } ,
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 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*)"", 56, Mapper56_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 } ,
2017-10-15 03:13:11 +08:00
/* {(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 } ,
2017-04-27 01:04:04 +08:00
{ ( 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*)"", 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 } ,
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 126, Mapper126_Init}, */
/* {(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}, */
2016-09-09 09:10:10 +02:00
{ ( uint8_t * ) " TXC/MGENIUS 22111 " , 132 , UNL22211_Init } ,
{ ( uint8_t * ) " SA72008 " , 133 , SA72008_Init } ,
2017-04-25 00:52:18 +08:00
{ ( uint8_t * ) " MMC3 BMC PIRATE " , 134 , Mapper134_Init } ,
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 135, Mapper135_Init}, */
2016-09-09 09:10:10 +02:00
{ ( uint8_t * ) " TCU02 " , 136 , TCU02_Init } ,
{ ( 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 * ) " TCU01 " , 147 , TCU01_Init } ,
{ ( uint8_t * ) " SA0037 " , 148 , SA0037_Init } ,
{ ( uint8_t * ) " SA0036 " , 149 , SA0036_Init } ,
{ ( uint8_t * ) " S74LS374N " , 150 , S74LS374N_Init } ,
{ ( 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 * ) " " , 172 , Mapper172_Init } ,
{ ( uint8_t * ) " " , 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 } ,
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 182, Mapper182_Init}, */ /* Deprecated, dupe */
2017-04-25 00:52:18 +08:00
{ ( uint8_t * ) " " , 183 , Mapper183_Init } ,
2016-09-09 09:10:10 +02:00
{ ( uint8_t * ) " " , 184 , Mapper184_Init } ,
{ ( uint8_t * ) " " , 185 , Mapper185_Init } ,
2017-04-25 00:52:18 +08:00
{ ( 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 * ) " " , 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 } ,
2017-04-25 00:52:18 +08:00
{ ( 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 * ) " " , 215 , UNL8237_Init } ,
{ ( 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 */
/* {(uint8_t*)"", 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*)"", 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 * ) " " , 235 , Mapper235_Init } ,
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 236, Mapper236_Init}, */
/* {(uint8_t*)"", 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 } ,
2016-09-09 07:59:43 +02:00
{ ( uint8_t * ) " S74LS374NA " , 243 , S74LS374NA_Init } ,
{ ( 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 } ,
2017-10-15 03:13:11 +08:00
/* {(uint8_t*)"", 255, Mapper255_Init}, */ /* No good dumps for this mapper */
2016-09-09 07:59:43 +02:00
{ ( uint8_t * ) " " , 0 , NULL }
2014-03-30 22:15:17 +02:00
} ;
2014-03-30 22:50:28 +02:00
int iNESLoad ( const char * name , FCEUFILE * fp ) {
2014-03-30 22:15:17 +02:00
struct md5_context md5 ;
2017-04-25 00:52:18 +08:00
char * mappername ;
uint32 mappertest ;
2014-03-30 22:15:17 +02:00
if ( FCEU_fread ( & head , 1 , 16 , fp ) ! = 16 )
return 0 ;
2017-09-25 16:50:24 +08:00
if ( memcmp ( & head , " NES \x1a " , 4 ) ) {
FCEU_PrintError ( " Missing header or invalid iNES format file! \n " ) ;
return 0 ;
}
2014-03-30 22:15:17 +02:00
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 ) ;
}
MapperNo = ( head . ROM_type > > 4 ) ;
MapperNo | = ( head . ROM_type2 & 0xF0 ) ;
if ( head . ROM_type & 8 ) {
Mirroring = 2 ;
} else
Mirroring = ( head . ROM_type & 1 ) ;
if ( ! head . ROM_size )
ROM_size = 256 ;
else
ROM_size = uppow2 ( head . ROM_size ) ;
VROM_size = uppow2 ( head . VROM_size ) ;
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 ) ;
}
if ( head . ROM_type & 4 ) { /* Trainer */
trainerpoo = ( uint8 * ) FCEU_gmalloc ( 512 ) ;
FCEU_fread ( trainerpoo , 512 , 1 , fp ) ;
}
ResetCartMapping ( ) ;
ResetExState ( 0 , 0 ) ;
SetupCartPRGMapping ( 0 , ROM , ROM_size < < 14 , 0 ) ;
if ( head . ROM_size )
FCEU_fread ( ROM , 0x4000 , head . ROM_size , fp ) ;
else
FCEU_fread ( ROM , 0x4000 , ROM_size , fp ) ;
if ( VROM_size )
FCEU_fread ( VROM , 0x2000 , VROM_size , fp ) ;
md5_starts ( & md5 ) ;
2017-04-24 10:58:56 +08:00
if ( head . ROM_size ) {
md5_update ( & md5 , ROM , head . ROM_size < < 14 ) ;
iNESGameCRC32 = CalcCRC32 ( 0 , ROM , head . ROM_size < < 14 ) ;
} else {
md5_update ( & md5 , ROM , ROM_size < < 14 ) ;
iNESGameCRC32 = CalcCRC32 ( 0 , ROM , ROM_size < < 14 ) ;
}
2014-03-30 22:15:17 +02:00
if ( VROM_size ) {
iNESGameCRC32 = CalcCRC32 ( iNESGameCRC32 , VROM , VROM_size < < 13 ) ;
md5_update ( & md5 , VROM , VROM_size < < 13 ) ;
}
md5_finish ( & md5 , iNESCart . MD5 ) ;
memcpy ( & GameInfo - > MD5 , & iNESCart . MD5 , sizeof ( iNESCart . MD5 ) ) ;
iNESCart . CRC32 = iNESGameCRC32 ;
2017-04-24 10:58:56 +08:00
FCEU_printf ( " PRG ROM: %3d x 16KiB \n " , head . ROM_size ? head . ROM_size : 256 ) ;
2014-03-30 22:15:17 +02:00
FCEU_printf ( " CHR ROM: %3d x 8KiB \n " , head . VROM_size ) ;
FCEU_printf ( " ROM CRC32: 0x%08lx \n " , iNESGameCRC32 ) ;
FCEU_printf ( " ROM MD5: 0x%s \n " , md5_asciistr ( iNESCart . MD5 ) ) ;
2014-04-15 01:59:54 -07:00
mappername = " Not Listed " ;
2014-03-30 22:15:17 +02:00
for ( mappertest = 0 ; mappertest < ( sizeof bmap / sizeof bmap [ 0 ] ) - 1 ; mappertest + + ) {
if ( bmap [ mappertest ] . number = = MapperNo ) {
2016-09-09 07:59:43 +02:00
mappername = ( char * ) bmap [ mappertest ] . name ;
2014-03-30 22:15:17 +02:00
break ;
}
}
FCEU_printf ( " Mapper #: %d \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
2017-10-15 03:13:11 +08:00
* VROM_size and free ( VROM ) .
2014-03-30 22:15:17 +02:00
*/
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 . battery = ( head . ROM_type & 2 ) ? 1 : 0 ;
iNESCart . mirror = Mirroring ;
if ( ! iNES_Init ( MapperNo ) )
FCEU_PrintError ( " iNES mapper #%d is not supported at all. " , MapperNo ) ;
2019-05-11 23:11:55 +08:00
iNESCart . mapper = MapperNo ;
2014-03-30 22:15:17 +02:00
GameInterface = iNESGI ;
FCEU_printf ( " \n " ) ;
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) " )
2017-04-25 00:52:18 +08:00
| | 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) " ) ) {
2017-10-07 13:35:00 +08:00
FCEUI_SetVidSystem ( 1 ) ;
2017-04-25 00:52:18 +08:00
}
2017-10-07 13:35:00 +08:00
else
FCEUI_SetVidSystem ( 0 ) ;
2014-03-30 22:15:17 +02:00
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 */
2014-03-30 22:15:17 +02:00
if ( ! VROM_size ) {
2017-10-15 03:13:11 +08:00
switch ( num ) { /* FIXME, mapper or game data base with the board parameters and ROM/RAM sizes */
2014-03-30 22:15:17 +02:00
case 13 : CHRRAMSize = 16 * 1024 ; break ;
case 6 :
2017-04-30 06:44:51 +08:00
case 30 :
case 45 :
2014-03-30 22:15:17 +02:00
case 96 : CHRRAMSize = 32 * 1024 ; break ;
2017-04-27 00:45:40 +08:00
case 176 : CHRRAMSize = 128 * 1024 ; break ;
2014-03-30 22:15:17 +02:00
default : CHRRAMSize = 8 * 1024 ; break ;
}
2017-04-30 06:44:51 +08:00
iNESCart . vram_size = CHRRAMSize ;
2014-03-30 22:15:17 +02:00
if ( ( VROM = ( uint8 * ) malloc ( CHRRAMSize ) ) = = NULL ) return 0 ;
2017-04-30 06:44:51 +08:00
FCEU_MemoryRand ( VROM , CHRRAMSize ) ;
2014-03-30 22:15:17 +02:00
UNIFchrrama = VROM ;
SetupCartCHRMapping ( 0 , VROM , CHRRAMSize , 1 ) ;
AddExState ( VROM , CHRRAMSize , 0 , " CHRR " ) ;
}
if ( head . ROM_type & 8 )
AddExState ( ExtraNTARAM , 2048 , 0 , " EXNR " ) ;
tmp - > init ( & iNESCart ) ;
return 1 ;
}
tmp + + ;
}
return 0 ;
}