| 1 | /* FCE Ultra - NES/Famicom Emulator\r |
| 2 | *\r |
| 3 | * Copyright notice for this file:\r |
| 4 | * Copyright (C) 1998 BERO\r |
| 5 | * Copyright (C) 2002 Xodnizel\r |
| 6 | *\r |
| 7 | * This program is free software; you can redistribute it and/or modify\r |
| 8 | * it under the terms of the GNU General Public License as published by\r |
| 9 | * the Free Software Foundation; either version 2 of the License, or\r |
| 10 | * (at your option) any later version.\r |
| 11 | *\r |
| 12 | * This program is distributed in the hope that it will be useful,\r |
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of\r |
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r |
| 15 | * GNU General Public License for more details.\r |
| 16 | *\r |
| 17 | * You should have received a copy of the GNU General Public License\r |
| 18 | * along with this program; if not, write to the Free Software\r |
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\r |
| 20 | */\r |
| 21 | \r |
| 22 | #include <stdio.h>\r |
| 23 | #include <stdlib.h>\r |
| 24 | #include <string.h>\r |
| 25 | \r |
| 26 | #include "types.h"\r |
| 27 | #include "x6502.h"\r |
| 28 | #include "fce.h"\r |
| 29 | #include "cart.h"\r |
| 30 | #include "ppu.h"\r |
| 31 | \r |
| 32 | #define INESPRIV\r |
| 33 | #include "ines.h"\r |
| 34 | #include "unif.h"\r |
| 35 | #include "state.h"\r |
| 36 | #include "file.h"\r |
| 37 | #include "general.h"\r |
| 38 | #include "memory.h"\r |
| 39 | #include "crc32.h"\r |
| 40 | #include "md5.h"\r |
| 41 | #include "cheat.h"\r |
| 42 | #include "vsuni.h"\r |
| 43 | #include "driver.h"\r |
| 44 | #include "svga.h"\r |
| 45 | \r |
| 46 | extern SFORMAT FCEUVSUNI_STATEINFO[];\r |
| 47 | \r |
| 48 | //mbg merge 6/29/06 - these need to be global\r |
| 49 | uint8 *trainerpoo=0;\r |
| 50 | uint8 *ROM = NULL;\r |
| 51 | uint8 *VROM = NULL;\r |
| 52 | struct iNES_HEADER head;\r |
| 53 | \r |
| 54 | \r |
| 55 | \r |
| 56 | static CartInfo iNESCart;\r |
| 57 | \r |
| 58 | uint8 iNESMirroring=0;\r |
| 59 | uint16 iNESCHRBankList[8]={0,0,0,0,0,0,0,0};\r |
| 60 | int32 iNESIRQLatch=0,iNESIRQCount=0;\r |
| 61 | uint8 iNESIRQa=0;\r |
| 62 | \r |
| 63 | uint32 ROM_size=0;\r |
| 64 | uint32 VROM_size=0;\r |
| 65 | //char LoadedRomFName[2048]; //mbg merge 7/17/06 added\r |
| 66 | \r |
| 67 | static int CHRRAMSize = -1;\r |
| 68 | static void iNESPower(void);\r |
| 69 | static int NewiNES_Init(int num);\r |
| 70 | \r |
| 71 | void (*MapClose)(void);\r |
| 72 | void (*MapperReset)(void);\r |
| 73 | \r |
| 74 | static int MapperNo=0;\r |
| 75 | \r |
| 76 | /* MapperReset() is called when the NES is reset(with the reset button).\r |
| 77 | Mapperxxx_init is called when the NES has been powered on.\r |
| 78 | */\r |
| 79 | \r |
| 80 | \r |
| 81 | static DECLFR(TrainerRead)\r |
| 82 | {\r |
| 83 | return(trainerpoo[A&0x1FF]);\r |
| 84 | }\r |
| 85 | \r |
| 86 | static void iNES_ExecPower()\r |
| 87 | {\r |
| 88 | if(CHRRAMSize != -1)\r |
| 89 | FCEU_MemoryRand(VROM,CHRRAMSize);\r |
| 90 | \r |
| 91 | if(iNESCart.Power)\r |
| 92 | iNESCart.Power();\r |
| 93 | \r |
| 94 | if(trainerpoo)\r |
| 95 | {\r |
| 96 | int x;\r |
| 97 | for(x=0;x<512;x++)\r |
| 98 | {\r |
| 99 | //X6502_DMW(0x7000+x,trainerpoo[x]);\r |
| 100 | //if(X6502_DMR(0x7000+x)!=trainerpoo[x])\r |
| 101 | unsigned int A=0x7000+x;\r |
| 102 | BWrite[A](A,trainerpoo[x]);\r |
| 103 | if(ARead[A](A)!=trainerpoo[x])\r |
| 104 | {\r |
| 105 | SetReadHandler(0x7000,0x71FF,TrainerRead);\r |
| 106 | break;\r |
| 107 | }\r |
| 108 | }\r |
| 109 | }\r |
| 110 | }\r |
| 111 | \r |
| 112 | static void iNESGI(int h, void *param)\r |
| 113 | {\r |
| 114 | switch(h)\r |
| 115 | {\r |
| 116 | case GI_RESETSAVE:\r |
| 117 | //FCEU_ClearGameSave(&iNESCart);\r |
| 118 | break;\r |
| 119 | \r |
| 120 | case GI_RESETM2:\r |
| 121 | if(MapperReset)\r |
| 122 | MapperReset();\r |
| 123 | if(iNESCart.Reset)\r |
| 124 | iNESCart.Reset();\r |
| 125 | break;\r |
| 126 | case GI_POWER:\r |
| 127 | iNES_ExecPower();\r |
| 128 | \r |
| 129 | break;\r |
| 130 | case GI_CLOSE:\r |
| 131 | {\r |
| 132 | FCEU_SaveGameSave(&iNESCart);\r |
| 133 | \r |
| 134 | if(iNESCart.Close) iNESCart.Close();\r |
| 135 | if(ROM) {free(ROM); ROM = NULL;}\r |
| 136 | if(VROM) {free(VROM); VROM = NULL;}\r |
| 137 | if(MapClose) MapClose();\r |
| 138 | if(trainerpoo) {FCEU_gfree(trainerpoo);trainerpoo=0;}\r |
| 139 | }\r |
| 140 | break;\r |
| 141 | case GI_INFOSTRING:\r |
| 142 | {\r |
| 143 | int MapperNo;\r |
| 144 | MapperNo = (head.ROM_type>>4);\r |
| 145 | MapperNo|=(head.ROM_type2&0xF0);\r |
| 146 | sprintf(param, "iNES, %s, Mapper: %d%s%s", PAL?"PAL":"NTSC",\r |
| 147 | MapperNo, (head.ROM_type&2)?", BB":"", (head.ROM_type&4)?", T":"");\r |
| 148 | }\r |
| 149 | break;\r |
| 150 | }\r |
| 151 | }\r |
| 152 | \r |
| 153 | uint32 iNESGameCRC32=0;\r |
| 154 | \r |
| 155 | struct CRCMATCH {\r |
| 156 | uint32 crc;\r |
| 157 | char *name;\r |
| 158 | };\r |
| 159 | \r |
| 160 | struct INPSEL {\r |
| 161 | uint32 crc32;\r |
| 162 | int input1;\r |
| 163 | int input2;\r |
| 164 | int inputfc;\r |
| 165 | };\r |
| 166 | \r |
| 167 | static void SetInput(void)\r |
| 168 | {\r |
| 169 | static struct INPSEL moo[]=\r |
| 170 | {\r |
| 171 | {0x3a1694f9,SI_GAMEPAD,SI_GAMEPAD,SIFC_4PLAYER}, // Nekketsu Kakutou Densetsu\r |
| 172 | \r |
| 173 | {0xc3c0811d,SI_GAMEPAD,SI_GAMEPAD,SIFC_OEKAKIDS}, // The two "Oeka Kids" games\r |
| 174 | {0x9d048ea4,SI_GAMEPAD,SI_GAMEPAD,SIFC_OEKAKIDS}, //\r |
| 175 | \r |
| 176 | {0xaf4010ea,SI_GAMEPAD,SI_POWERPADB,SIFC_UNSET}, // World Class Track Meet\r |
| 177 | {0xd74b2719,SI_GAMEPAD,SI_POWERPADB,SIFC_UNSET}, // Super Team Games\r |
| 178 | {0x61d86167,SI_GAMEPAD,SI_POWERPADB,SIFC_UNSET}, // Street Cop\r |
| 179 | {0x6435c095,SI_GAMEPAD,SI_POWERPADB,SIFC_UNSET}, // Short Order/Eggsplode\r |
| 180 | \r |
| 181 | \r |
| 182 | {0x47232739,SI_GAMEPAD,SI_GAMEPAD,SIFC_TOPRIDER}, // Top Rider\r |
| 183 | \r |
| 184 | {0x48ca0ee1,SI_GAMEPAD,SI_GAMEPAD,SIFC_BWORLD}, // Barcode World\r |
| 185 | {0x9f8f200a,SI_GAMEPAD,SI_GAMEPAD,SIFC_FTRAINERA}, // Super Mogura Tataki!! - Pokkun Moguraa\r |
| 186 | {0x9044550e,SI_GAMEPAD,SI_GAMEPAD,SIFC_FTRAINERA}, // Rairai Kyonshizu\r |
| 187 | {0x2f128512,SI_GAMEPAD,SI_GAMEPAD,SIFC_FTRAINERA}, // Jogging Race\r |
| 188 | {0x60ad090a,SI_GAMEPAD,SI_GAMEPAD,SIFC_FTRAINERA}, // Athletic World\r |
| 189 | \r |
| 190 | {0x8a12a7d9,SI_GAMEPAD,SI_GAMEPAD,SIFC_FTRAINERB}, // Totsugeki Fuuun Takeshi Jou\r |
| 191 | {0xea90f3e2,SI_GAMEPAD,SI_GAMEPAD,SIFC_FTRAINERB}, // Running Stadium\r |
| 192 | {0x370ceb65,SI_GAMEPAD,SI_GAMEPAD,SIFC_FTRAINERB}, // Meiro Dai Sakusen\r |
| 193 | // Bad dump? {0x69ffb014,SI_GAMEPAD,SI_GAMEPAD,SIFC_FTRAINERB}, // Fuun Takeshi Jou 2\r |
| 194 | {0x6cca1c1f,SI_GAMEPAD,SI_GAMEPAD,SIFC_FTRAINERB}, // Dai Undoukai\r |
| 195 | {0x29de87af,SI_GAMEPAD,SI_GAMEPAD,SIFC_FTRAINERB}, // Aerobics Studio\r |
| 196 | {0xbba58be5,SI_GAMEPAD,SI_GAMEPAD,SIFC_FTRAINERB}, // Family Trainer: Manhattan Police\r |
| 197 | {0xea90f3e2,SI_GAMEPAD,SI_GAMEPAD,SIFC_FTRAINERB}, // Family Trainer: Running Stadium\r |
| 198 | \r |
| 199 | {0xd9f45be9,SI_GAMEPAD,SI_GAMEPAD,SIFC_QUIZKING}, // Gimme a Break ...\r |
| 200 | {0x1545bd13,SI_GAMEPAD,SI_GAMEPAD,SIFC_QUIZKING}, // Gimme a Break ... 2\r |
| 201 | \r |
| 202 | {0x7b44fb2a,SI_GAMEPAD,SI_GAMEPAD,SIFC_MAHJONG}, // Ide Yousuke Meijin no Jissen Mahjong 2\r |
| 203 | {0x9fae4d46,SI_GAMEPAD,SI_GAMEPAD,SIFC_MAHJONG}, // Ide Yousuke Meijin no Jissen Mahjong\r |
| 204 | \r |
| 205 | {0x980be936,SI_GAMEPAD,SI_GAMEPAD,SIFC_HYPERSHOT}, // Hyper Olympic\r |
| 206 | {0x21f85681,SI_GAMEPAD,SI_GAMEPAD,SIFC_HYPERSHOT}, // Hyper Olympic (Gentei Ban)\r |
| 207 | {0x915a53a7,SI_GAMEPAD,SI_GAMEPAD,SIFC_HYPERSHOT}, // Hyper Sports\r |
| 208 | {0xad9c63e2,SI_GAMEPAD,SI_UNSET,SIFC_SHADOW}, // Space Shadow\r |
| 209 | \r |
| 210 | {0x24598791,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // Duck Hunt\r |
| 211 | {0xff24d794,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // Hogan's Alley\r |
| 212 | {0xbeb8ab01,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // Gumshoe\r |
| 213 | {0xde8fd935,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // To the Earth\r |
| 214 | {0xedc3662b,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // Operation Wolf\r |
| 215 | {0x2a6559a1,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // Operation Wolf (J)\r |
| 216 | {0x4e959173,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // Gotcha! - The Sport!\r |
| 217 | \r |
| 218 | {0x23d17f5e,SI_GAMEPAD,SI_ZAPPER,SIFC_NONE}, // The Lone Ranger\r |
| 219 | {0xb8b9aca3,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // Wild Gunman\r |
| 220 | {0x5112dc21,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // Wild Gunman\r |
| 221 | {0x4318a2f8,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // Barker Bill's Trick Shooting\r |
| 222 | {0x5ee6008e,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // Mechanized Attack\r |
| 223 | {0x3e58a87e,SI_UNSET,SI_ZAPPER,SIFC_NONE}, // Freedom Force\r |
| 224 | {0xe9a7fe9e,SI_UNSET,SI_MOUSE,SIFC_NONE}, // Educational Computer 2000 //mbg merge 7/17/06 added -- appears to be from newer MM build\r |
| 225 | {0x851eb9be,SI_GAMEPAD,SI_ZAPPER,SIFC_NONE}, // Shooting Range\r |
| 226 | {0x74bea652,SI_GAMEPAD,SI_ZAPPER,SIFC_NONE}, // Supergun 3-in-1\r |
| 227 | {0x32fb0583,SI_UNSET,SI_ARKANOID,SIFC_NONE}, // Arkanoid(NES)\r |
| 228 | {0xd89e5a67,SI_UNSET,SI_UNSET,SIFC_ARKANOID}, // Arkanoid (J)\r |
| 229 | {0x0f141525,SI_UNSET,SI_UNSET,SIFC_ARKANOID}, // Arkanoid 2(J)\r |
| 230 | \r |
| 231 | {0x912989dc,SI_UNSET,SI_UNSET,SIFC_FKB}, // Playbox BASIC\r |
| 232 | {0xf7606810,SI_UNSET,SI_UNSET,SIFC_FKB}, // Family BASIC 2.0A\r |
| 233 | {0x895037bc,SI_UNSET,SI_UNSET,SIFC_FKB}, // Family BASIC 2.1a\r |
| 234 | {0xb2530afc,SI_UNSET,SI_UNSET,SIFC_FKB}, // Family BASIC 3.0\r |
| 235 | {0x82f1fb96,SI_UNSET,SI_UNSET,SIFC_SUBORKB}, // Subor 1.0 Russian\r |
| 236 | {0xabb2f974,SI_UNSET,SI_UNSET,SIFC_SUBORKB}, // Study and Game 32-in-1\r |
| 237 | {0xd5d6eac4,SI_UNSET,SI_UNSET,SIFC_SUBORKB}, // Edu (As)\r |
| 238 | {0x589b6b0d,SI_UNSET,SI_UNSET,SIFC_SUBORKB}, // SuporV20\r |
| 239 | {0x5e073a1b,SI_UNSET,SI_UNSET,SIFC_SUBORKB}, // Supor English (Chinese)\r |
| 240 | {0x8b265862,SI_UNSET,SI_UNSET,SIFC_SUBORKB},\r |
| 241 | {0x41401c6d,SI_UNSET,SI_UNSET,SIFC_SUBORKB}, // SuporV40\r |
| 242 | {0x41ef9ac4,SI_UNSET,SI_UNSET,SIFC_SUBORKB},\r |
| 243 | {0x368c19a8,SI_UNSET,SI_UNSET,SIFC_SUBORKB}, // LIKO Study Cartridge\r |
| 244 | {0x543ab532,SI_UNSET,SI_UNSET,SIFC_SUBORKB}, // LIKO Color Lines\r |
| 245 | {0,SI_UNSET,SI_UNSET,SIFC_UNSET}\r |
| 246 | };\r |
| 247 | int x=0;\r |
| 248 | \r |
| 249 | while(moo[x].input1>=0 || moo[x].input2>=0 || moo[x].inputfc>=0)\r |
| 250 | {\r |
| 251 | if(moo[x].crc32==iNESGameCRC32)\r |
| 252 | {\r |
| 253 | GameInfo->input[0]=moo[x].input1;\r |
| 254 | GameInfo->input[1]=moo[x].input2;\r |
| 255 | GameInfo->inputfc=moo[x].inputfc;\r |
| 256 | break;\r |
| 257 | }\r |
| 258 | x++;\r |
| 259 | }\r |
| 260 | }\r |
| 261 | \r |
| 262 | #define INESB_INCOMPLETE 1\r |
| 263 | #define INESB_CORRUPT 2\r |
| 264 | #define INESB_HACKED 4\r |
| 265 | \r |
| 266 | struct BADINF {\r |
| 267 | uint64 md5partial;\r |
| 268 | char *name;\r |
| 269 | uint32 type;\r |
| 270 | };\r |
| 271 | \r |
| 272 | \r |
| 273 | static struct BADINF BadROMImages[]=\r |
| 274 | {\r |
| 275 | #include "ines-bad.h"\r |
| 276 | };\r |
| 277 | \r |
| 278 | void CheckBad(uint64 md5partial)\r |
| 279 | {\r |
| 280 | int x;\r |
| 281 | \r |
| 282 | x=0;\r |
| 283 | //printf("0x%llx\n",md5partial);\r |
| 284 | while(BadROMImages[x].name)\r |
| 285 | {\r |
| 286 | if(BadROMImages[x].md5partial == md5partial)\r |
| 287 | {\r |
| 288 | FCEU_PrintError("The copy game you have loaded, \"%s\", is bad, and will not work properly in FCEUX.", BadROMImages[x].name);\r |
| 289 | return;\r |
| 290 | }\r |
| 291 | x++;\r |
| 292 | }\r |
| 293 | \r |
| 294 | }\r |
| 295 | \r |
| 296 | \r |
| 297 | struct CHINF {\r |
| 298 | uint32 crc32;\r |
| 299 | int32 mapper;\r |
| 300 | int32 mirror;\r |
| 301 | const char* params;\r |
| 302 | };\r |
| 303 | \r |
| 304 | void MapperInit()\r |
| 305 | {\r |
| 306 | if(NewiNES_Init(MapperNo))\r |
| 307 | {\r |
| 308 | \r |
| 309 | }\r |
| 310 | else\r |
| 311 | {\r |
| 312 | iNESCart.Power=iNESPower;\r |
| 313 | if(head.ROM_type&2)\r |
| 314 | {\r |
| 315 | iNESCart.SaveGame[0]=WRAM;\r |
| 316 | iNESCart.SaveGameLen[0]=8192;\r |
| 317 | }\r |
| 318 | }\r |
| 319 | }\r |
| 320 | \r |
| 321 | #if 0\r |
| 322 | static const TMasterRomInfo sMasterRomInfo[] = {\r |
| 323 | { 0x62b51b108a01d2beLL, "bonus=0" }, //4-in-1 (FK23C8021)[p1][!].nes\r |
| 324 | { 0x8bb48490d8d22711LL, "bonus=0" }, //4-in-1 (FK23C8033)[p1][!].nes\r |
| 325 | { 0xc75888d7b48cd378LL, "bonus=0" }, //4-in-1 (FK23C8043)[p1][!].nes\r |
| 326 | { 0xf81a376fa54fdd69LL, "bonus=0" }, //4-in-1 (FK23Cxxxx, S-0210A PCB)[p1][!].nes\r |
| 327 | { 0xa37eb9163e001a46LL, "bonus=0" }, //4-in-1 (FK23C8026) [p1][!].nes\r |
| 328 | { 0xde5ce25860233f7eLL, "bonus=0" }, //4-in-1 (FK23C8045) [p1][!].nes\r |
| 329 | { 0x5b3aa4cdc484a088LL, "bonus=0" }, //4-in-1 (FK23C8056) [p1][!].nes\r |
| 330 | { 0x9342bf9bae1c798aLL, "bonus=0" }, //4-in-1 (FK23C8079) [p1][!].nes\r |
| 331 | { 0x164eea6097a1e313LL, "busc=1" }, //Cybernoid - The Fighting Machine (U)[!].nes -- needs bus conflict emulation\r |
| 332 | };\r |
| 333 | const TMasterRomInfo* MasterRomInfo;\r |
| 334 | TMasterRomInfoParams MasterRomInfoParams;\r |
| 335 | #endif\r |
| 336 | \r |
| 337 | static void CheckHInfo(void)\r |
| 338 | {\r |
| 339 | /* ROM images that have the battery-backed bit set in the header that really\r |
| 340 | don't have battery-backed RAM is not that big of a problem, so I'll\r |
| 341 | treat this differently by only listing games that should have battery-backed RAM.\r |
| 342 | \r |
| 343 | Lower 64 bits of the MD5 hash.\r |
| 344 | */\r |
| 345 | \r |
| 346 | static uint64 savie[]=\r |
| 347 | {\r |
| 348 | 0x498c10dc463cfe95LL, /* Battle Fleet */\r |
| 349 | 0x6917ffcaca2d8466LL, /* Famista '90 */\r |
| 350 | \r |
| 351 | 0xd63dcc68c2b20adcLL, /* Final Fantasy J */\r |
| 352 | 0x012df596e2b31174LL, /* Final Fantasy 1+2 */\r |
| 353 | 0xf6b359a720549ecdLL, /* Final Fantasy 2 */\r |
| 354 | 0x5a30da1d9b4af35dLL, /* Final Fantasy 3 */\r |
| 355 | \r |
| 356 | 0x2ee3417ba8b69706LL, /* Hydlide 3*/\r |
| 357 | \r |
| 358 | 0xebbce5a54cf3ecc0LL, /* Justbreed */\r |
| 359 | \r |
| 360 | 0x6a858da551ba239eLL, /* Kaijuu Monogatari */\r |
| 361 | 0xa40666740b7d22feLL, /* Mindseeker */\r |
| 362 | \r |
| 363 | 0x77b811b2760104b9LL, /* Mouryou Senki Madara */\r |
| 364 | \r |
| 365 | 0x11b69122efe86e8cLL, /* RPG Jinsei Game */\r |
| 366 | \r |
| 367 | 0xa70b495314f4d075LL, /* Ys 3 */\r |
| 368 | \r |
| 369 | \r |
| 370 | 0xc04361e499748382LL, /* AD&D Heroes of the Lance */\r |
| 371 | 0xb72ee2337ced5792LL, /* AD&D Hillsfar */\r |
| 372 | 0x2b7103b7a27bd72fLL, /* AD&D Pool of Radiance */\r |
| 373 | \r |
| 374 | 0x854d7947a3177f57LL, /* Crystalis */\r |
| 375 | \r |
| 376 | 0xb0bcc02c843c1b79LL, /* DW */\r |
| 377 | 0x4a1f5336b86851b6LL, /* DW */\r |
| 378 | \r |
| 379 | 0x2dcf3a98c7937c22LL, /* DW 2 */\r |
| 380 | 0x733026b6b72f2470LL, /* Dw 3 */\r |
| 381 | 0x98e55e09dfcc7533LL, /* DW 4*/\r |
| 382 | 0x8da46db592a1fcf4LL, /* Faria */\r |
| 383 | 0x91a6846d3202e3d6LL, /* Final Fantasy */\r |
| 384 | 0xedba17a2c4608d20LL, /* "" */\r |
| 385 | \r |
| 386 | 0x94b9484862a26cbaLL, /* Legend of Zelda */\r |
| 387 | 0x04a31647de80fdabLL, /* "" */\r |
| 388 | \r |
| 389 | 0x9aa1dc16c05e7de5LL, /* Startropics */\r |
| 390 | 0x1b084107d0878bd0LL, /* Startropics 2*/\r |
| 391 | \r |
| 392 | 0x836c0ff4f3e06e45LL, /* Zelda 2 */\r |
| 393 | \r |
| 394 | 0x82000965f04a71bbLL, /* Mirai Shinwa Jarvas */\r |
| 395 | \r |
| 396 | 0 /* Abandon all hope if the game has 0 in the lower 64-bits of its MD5 hash */\r |
| 397 | };\r |
| 398 | \r |
| 399 | static struct CHINF moo[]=\r |
| 400 | {\r |
| 401 | #include "ines-correct.h"\r |
| 402 | };\r |
| 403 | int tofix=0;\r |
| 404 | int x;\r |
| 405 | uint64 partialmd5=0;\r |
| 406 | \r |
| 407 | for(x=0;x<8;x++)\r |
| 408 | {\r |
| 409 | partialmd5 |= (uint64)iNESCart.MD5[15-x] << (x*8);\r |
| 410 | //printf("%16llx\n",partialmd5);\r |
| 411 | }\r |
| 412 | CheckBad(partialmd5);\r |
| 413 | \r |
| 414 | #if 0\r |
| 415 | MasterRomInfo = NULL;\r |
| 416 | MasterRomInfoParams = TMasterRomInfoParams();\r |
| 417 | for(int i=0;i<ARRAY_SIZE(sMasterRomInfo);i++)\r |
| 418 | {\r |
| 419 | const TMasterRomInfo& info = sMasterRomInfo[i];\r |
| 420 | if(info.md5lower != partialmd5)\r |
| 421 | continue;\r |
| 422 | \r |
| 423 | MasterRomInfo = &info;\r |
| 424 | if(!info.params) break;\r |
| 425 | \r |
| 426 | std::vector<std::string> toks = tokenize_str(info.params,",");\r |
| 427 | for(int j=0;j<(int)toks.size();j++)\r |
| 428 | {\r |
| 429 | std::vector<std::string> parts = tokenize_str(toks[j],"=");\r |
| 430 | MasterRomInfoParams[parts[0]] = parts[1];\r |
| 431 | }\r |
| 432 | break;\r |
| 433 | }\r |
| 434 | #endif\r |
| 435 | \r |
| 436 | x=0;\r |
| 437 | \r |
| 438 | do\r |
| 439 | {\r |
| 440 | if(moo[x].crc32==iNESGameCRC32)\r |
| 441 | {\r |
| 442 | if(moo[x].mapper>=0)\r |
| 443 | {\r |
| 444 | if(moo[x].mapper&0x800 && VROM_size)\r |
| 445 | {\r |
| 446 | VROM_size=0;\r |
| 447 | free(VROM);\r |
| 448 | VROM = NULL;\r |
| 449 | tofix|=8;\r |
| 450 | }\r |
| 451 | if(MapperNo!=(moo[x].mapper&0xFF))\r |
| 452 | {\r |
| 453 | tofix|=1;\r |
| 454 | MapperNo=moo[x].mapper&0xFF;\r |
| 455 | }\r |
| 456 | }\r |
| 457 | if(moo[x].mirror>=0)\r |
| 458 | {\r |
| 459 | if(moo[x].mirror==8)\r |
| 460 | {\r |
| 461 | if(Mirroring==2) /* Anything but hard-wired(four screen). */\r |
| 462 | {\r |
| 463 | tofix|=2;\r |
| 464 | Mirroring=0;\r |
| 465 | }\r |
| 466 | }\r |
| 467 | else if(Mirroring!=moo[x].mirror)\r |
| 468 | {\r |
| 469 | if(Mirroring!=(moo[x].mirror&~4))\r |
| 470 | if((moo[x].mirror&~4)<=2) /* Don't complain if one-screen mirroring\r |
| 471 | needs to be set(the iNES header can't\r |
| 472 | hold this information).\r |
| 473 | */\r |
| 474 | tofix|=2;\r |
| 475 | Mirroring=moo[x].mirror;\r |
| 476 | }\r |
| 477 | }\r |
| 478 | break;\r |
| 479 | }\r |
| 480 | x++;\r |
| 481 | } while(moo[x].mirror>=0 || moo[x].mapper>=0);\r |
| 482 | \r |
| 483 | x=0;\r |
| 484 | while(savie[x] != 0)\r |
| 485 | {\r |
| 486 | if(savie[x] == partialmd5)\r |
| 487 | {\r |
| 488 | if(!(head.ROM_type&2))\r |
| 489 | {\r |
| 490 | tofix|=4;\r |
| 491 | head.ROM_type|=2;\r |
| 492 | }\r |
| 493 | }\r |
| 494 | x++;\r |
| 495 | }\r |
| 496 | \r |
| 497 | /* Games that use these iNES mappers tend to have the four-screen bit set\r |
| 498 | when it should not be.\r |
| 499 | */\r |
| 500 | if((MapperNo==118 || MapperNo==24 || MapperNo==26) && (Mirroring==2))\r |
| 501 | {\r |
| 502 | Mirroring=0;\r |
| 503 | tofix|=2;\r |
| 504 | }\r |
| 505 | \r |
| 506 | /* Four-screen mirroring implicitly set. */\r |
| 507 | if(MapperNo==99)\r |
| 508 | Mirroring=2;\r |
| 509 | \r |
| 510 | if(tofix)\r |
| 511 | {\r |
| 512 | char gigastr[768];\r |
| 513 | strcpy(gigastr,"The iNES header contains incorrect information. For now, the information will be corrected in RAM. ");\r |
| 514 | if(tofix&1)\r |
| 515 | sprintf(gigastr+strlen(gigastr),"The mapper number should be set to %d. ",MapperNo);\r |
| 516 | if(tofix&2)\r |
| 517 | {\r |
| 518 | char *mstr[3]={"Horizontal","Vertical","Four-screen"};\r |
| 519 | sprintf(gigastr+strlen(gigastr),"Mirroring should be set to \"%s\". ",mstr[Mirroring&3]);\r |
| 520 | }\r |
| 521 | if(tofix&4)\r |
| 522 | strcat(gigastr,"The battery-backed bit should be set. ");\r |
| 523 | if(tofix&8)\r |
| 524 | strcat(gigastr,"This game should not have any CHR ROM. ");\r |
| 525 | strcat(gigastr,"\n");\r |
| 526 | FCEU_printf("%s",gigastr);\r |
| 527 | }\r |
| 528 | }\r |
| 529 | \r |
| 530 | typedef struct {\r |
| 531 | int mapper;\r |
| 532 | void (*init)(CartInfo *);\r |
| 533 | } NewMI;\r |
| 534 | \r |
| 535 | //this is for games that is not the a power of 2\r |
| 536 | //mapper based for now...\r |
| 537 | //not really accurate but this works since games\r |
| 538 | //that are not in the power of 2 tends to come\r |
| 539 | //in obscure mappers themselves which supports such\r |
| 540 | //size\r |
| 541 | static int not_power2[] =\r |
| 542 | {\r |
| 543 | 228\r |
| 544 | };\r |
| 545 | typedef struct {\r |
| 546 | char* name;\r |
| 547 | int number;\r |
| 548 | void (*init)(CartInfo *);\r |
| 549 | } BMAPPINGLocal;\r |
| 550 | \r |
| 551 | static BMAPPINGLocal bmap[] = {\r |
| 552 | {"NROM", 0, NROM_Init},\r |
| 553 | {"MMC1", 1, Mapper1_Init},\r |
| 554 | {"UNROM", 2, UNROM_Init},\r |
| 555 | {"CNROM", 3, CNROM_Init},\r |
| 556 | {"MMC3", 4, Mapper4_Init},\r |
| 557 | {"MMC5", 5, Mapper5_Init},\r |
| 558 | {"ANROM", 7, ANROM_Init},\r |
| 559 | {"Color Dreams", 11, Mapper11_Init},\r |
| 560 | {"", 12, Mapper12_Init},\r |
| 561 | {"CPROM", 13, CPROM_Init},\r |
| 562 | {"100-in1", 15, Mapper15_Init},\r |
| 563 | {"Bandai", 16, Mapper16_Init},\r |
| 564 | {"Namcot 106", 19, Mapper19_Init},\r |
| 565 | {"Konami VRC2 type B", 23, Mapper23_Init},\r |
| 566 | {"Wario Land 2", 35, UNLSC127_Init}, // Wario Land 2\r |
| 567 | {"TXC Policeman", 36, Mapper36_Init}, // TXC Policeman\r |
| 568 | {"", 37, Mapper37_Init},\r |
| 569 | {"Bit Corp. Crime Busters", 38, Mapper38_Init}, // Bit Corp. Crime Busters\r |
| 570 | {"", 43, Mapper43_Init},\r |
| 571 | {"", 44, Mapper44_Init},\r |
| 572 | {"", 45, Mapper45_Init},\r |
| 573 | {"", 47, Mapper47_Init},\r |
| 574 | {"", 49, Mapper49_Init},\r |
| 575 | {"", 52, Mapper52_Init},\r |
| 576 | {"", 57, Mapper57_Init},\r |
| 577 | {"", 58, BMCGK192_Init},\r |
| 578 | {"", 60, BMCD1038_Init},\r |
| 579 | {"MHROM", 66, MHROM_Init},\r |
| 580 | {"Sunsoft Mapper #4", 68, Mapper68_Init},\r |
| 581 | {"", 70, Mapper70_Init},\r |
| 582 | {"", 74, Mapper74_Init},\r |
| 583 | {"Irem 74HC161/32", 78, Mapper78_Init},\r |
| 584 | {"", 87, Mapper87_Init},\r |
| 585 | {"", 88, Mapper88_Init},\r |
| 586 | {"", 90, Mapper90_Init},\r |
| 587 | {"Sunsoft UNROM", 93, SUNSOFT_UNROM_Init},\r |
| 588 | {"", 94, Mapper94_Init},\r |
| 589 | {"", 95, Mapper95_Init},\r |
| 590 | {"", 101, Mapper101_Init},\r |
| 591 | {"", 103, Mapper103_Init},\r |
| 592 | {"", 105, Mapper105_Init},\r |
| 593 | {"", 106, Mapper106_Init},\r |
| 594 | {"", 107, Mapper107_Init},\r |
| 595 | {"", 108, Mapper108_Init},\r |
| 596 | {"", 112, Mapper112_Init},\r |
| 597 | {"", 113, Mapper113_Init},\r |
| 598 | {"", 114, Mapper114_Init},\r |
| 599 | {"", 115, Mapper115_Init},\r |
| 600 | {"", 116, Mapper116_Init},\r |
| 601 | // {116, UNLSL1632_Init},\r |
| 602 | {"", 117, Mapper117_Init},\r |
| 603 | {"TSKROM", 118, TKSROM_Init},\r |
| 604 | {"", 119, Mapper119_Init},\r |
| 605 | {"", 120, Mapper120_Init},\r |
| 606 | {"", 121, Mapper121_Init},\r |
| 607 | {"UNLH2288", 123, UNLH2288_Init},\r |
| 608 | {"UNL22211", 132, UNL22211_Init},\r |
| 609 | {"SA72008", 133, SA72008_Init},\r |
| 610 | {"", 134, Mapper134_Init},\r |
| 611 | {"TCU02", 136, TCU02_Init},\r |
| 612 | {"S8259D", 137, S8259D_Init},\r |
| 613 | {"S8259B", 138, S8259B_Init},\r |
| 614 | {"S8259C", 139, S8259C_Init},\r |
| 615 | {"", 140, Mapper140_Init},\r |
| 616 | {"S8259A", 141, S8259A_Init},\r |
| 617 | {"UNLKS7032", 142, UNLKS7032_Init},\r |
| 618 | {"TCA01", 143, TCA01_Init},\r |
| 619 | {"", 144, Mapper144_Init},\r |
| 620 | {"SA72007", 145, SA72007_Init},\r |
| 621 | {"SA0161M", 146, SA0161M_Init},\r |
| 622 | {"TCU01", 147, TCU01_Init},\r |
| 623 | {"SA0037", 148, SA0037_Init},\r |
| 624 | {"SA0036", 149, SA0036_Init},\r |
| 625 | {"S74LS374N", 150, S74LS374N_Init},\r |
| 626 | {"", 152, Mapper152_Init},\r |
| 627 | {"", 153, Mapper153_Init},\r |
| 628 | {"", 154, Mapper154_Init},\r |
| 629 | {"", 155, Mapper155_Init},\r |
| 630 | {"", 156, Mapper156_Init},\r |
| 631 | {"", 159, Mapper159_Init},\r |
| 632 | {"SA009", 160, SA009_Init},\r |
| 633 | {"", 163, Mapper163_Init},\r |
| 634 | {"", 164, Mapper164_Init},\r |
| 635 | {"", 165, Mapper165_Init},\r |
| 636 | // {169, Mapper169_Init},\r |
| 637 | {"", 171, Mapper171_Init},\r |
| 638 | {"", 172, Mapper172_Init},\r |
| 639 | {"", 173, Mapper173_Init},\r |
| 640 | {"", 175, Mapper175_Init},\r |
| 641 | {"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.\r |
| 642 | //{"BMCFK23C", 176, Mapper176_Init}, \r |
| 643 | {"", 177, Mapper177_Init},\r |
| 644 | {"", 178, Mapper178_Init},\r |
| 645 | {"", 180, Mapper180_Init},\r |
| 646 | {"", 181, Mapper181_Init},\r |
| 647 | // {"", 182, Mapper182_Init}, // identical to 114\r |
| 648 | {"", 183, Mapper183_Init},\r |
| 649 | {"", 184, Mapper184_Init},\r |
| 650 | {"", 185, Mapper185_Init},\r |
| 651 | {"", 186, Mapper186_Init},\r |
| 652 | {"", 187, Mapper187_Init},\r |
| 653 | {"", 188, Mapper188_Init},\r |
| 654 | {"", 189, Mapper189_Init},\r |
| 655 | {"", 191, Mapper191_Init},\r |
| 656 | {"", 192, Mapper192_Init},\r |
| 657 | {"", 194, Mapper194_Init},\r |
| 658 | {"", 195, Mapper195_Init},\r |
| 659 | {"", 196, Mapper196_Init},\r |
| 660 | {"", 197, Mapper197_Init},\r |
| 661 | {"", 198, Mapper198_Init},\r |
| 662 | {"", 199, Mapper199_Init},\r |
| 663 | {"", 200, Mapper200_Init},\r |
| 664 | {"", 205, Mapper205_Init},\r |
| 665 | {"DEIROM", 206, DEIROM_Init},\r |
| 666 | {"", 208, Mapper208_Init},\r |
| 667 | {"", 209, Mapper209_Init},\r |
| 668 | {"", 210, Mapper210_Init},\r |
| 669 | {"", 211, Mapper211_Init},\r |
| 670 | {"", 215, UNL8237_Init},\r |
| 671 | {"", 216, Mapper216_Init},\r |
| 672 | // {"", 217, Mapper217_Init},\r |
| 673 | {"UNLA9746", 219, UNLA9746_Init},\r |
| 674 | {"OneBus", 220, UNLOneBus_Init},\r |
| 675 | \r |
| 676 | // {220, BMCFK23C_Init},\r |
| 677 | // {220, UNL3DBlock_Init},\r |
| 678 | // {220, UNLTF1201_Init},\r |
| 679 | // {220, TCU02_Init},\r |
| 680 | // {220, UNLCN22M_Init},\r |
| 681 | // {220, BMCT2271_Init},\r |
| 682 | // {220, UNLDANCE_Init},\r |
| 683 | \r |
| 684 | {"UNLN625092", 221, UNLN625092_Init},\r |
| 685 | {"", 222, Mapper222_Init},\r |
| 686 | {"", 226, Mapper226_Init},\r |
| 687 | {"", 235, Mapper235_Init},\r |
| 688 | {"UNL6035052", 238, UNL6035052_Init},\r |
| 689 | {"", 240, Mapper240_Init},\r |
| 690 | {"S74LS374NA", 243, S74LS374NA_Init},\r |
| 691 | {"", 245, Mapper245_Init},\r |
| 692 | {"", 249, Mapper249_Init},\r |
| 693 | {"", 250, Mapper250_Init},\r |
| 694 | {"", 253, Mapper253_Init},\r |
| 695 | {"", 254, Mapper254_Init},\r |
| 696 | {"", 0, 0}\r |
| 697 | };\r |
| 698 | \r |
| 699 | void cleanup(struct iNES_HEADER *this)\r |
| 700 | {\r |
| 701 | if(!memcmp((char *)(this)+0x7,"DiskDude",8))\r |
| 702 | {\r |
| 703 | memset((char *)(this)+0x7,0,0x9);\r |
| 704 | }\r |
| 705 | \r |
| 706 | if(!memcmp((char *)(this)+0x7,"demiforce",9))\r |
| 707 | {\r |
| 708 | memset((char *)(this)+0x7,0,0x9);\r |
| 709 | }\r |
| 710 | \r |
| 711 | if(!memcmp((char *)(this)+0xA,"Ni03",4))\r |
| 712 | {\r |
| 713 | if(!memcmp((char *)(this)+0x7,"Dis",3))\r |
| 714 | memset((char *)(this)+0x7,0,0x9);\r |
| 715 | else\r |
| 716 | memset((char *)(this)+0xA,0,0x6);\r |
| 717 | }\r |
| 718 | }\r |
| 719 | \r |
| 720 | int iNESLoad(const char *name, int fp, int OverwriteVidMode)\r |
| 721 | {\r |
| 722 | struct md5_context md5;\r |
| 723 | \r |
| 724 | if(FCEU_fread(&head,1,16,fp)!=16)\r |
| 725 | return 0;\r |
| 726 | \r |
| 727 | if(memcmp(&head,"NES\x1a",4))\r |
| 728 | return 0;\r |
| 729 | \r |
| 730 | cleanup(&head);\r |
| 731 | \r |
| 732 | memset(&iNESCart,0,sizeof(iNESCart));\r |
| 733 | \r |
| 734 | MapperNo = (head.ROM_type>>4);\r |
| 735 | MapperNo|=(head.ROM_type2&0xF0);\r |
| 736 | Mirroring = (head.ROM_type&1);\r |
| 737 | \r |
| 738 | \r |
| 739 | // int ROM_size=0;\r |
| 740 | if(!head.ROM_size)\r |
| 741 | {\r |
| 742 | // FCEU_PrintError("No PRG ROM!");\r |
| 743 | // return(0);\r |
| 744 | ROM_size=256;\r |
| 745 | //head.ROM_size++;\r |
| 746 | }\r |
| 747 | else\r |
| 748 | ROM_size=uppow2(head.ROM_size);\r |
| 749 | \r |
| 750 | // ROM_size = head.ROM_size;\r |
| 751 | VROM_size = head.VROM_size;\r |
| 752 | \r |
| 753 | int round = 1;\r |
| 754 | int i;\r |
| 755 | for (i = 0; i != sizeof(not_power2)/sizeof(not_power2[0]); ++i)\r |
| 756 | {\r |
| 757 | //for games not to the power of 2, so we just read enough\r |
| 758 | //prg rom from it, but we have to keep ROM_size to the power of 2\r |
| 759 | //since PRGCartMapping wants ROM_size to be to the power of 2\r |
| 760 | //so instead if not to power of 2, we just use head.ROM_size when\r |
| 761 | //we use FCEU_read\r |
| 762 | if (not_power2[i] == MapperNo)\r |
| 763 | {\r |
| 764 | round = 0;\r |
| 765 | break;\r |
| 766 | }\r |
| 767 | }\r |
| 768 | \r |
| 769 | if(VROM_size)\r |
| 770 | VROM_size=uppow2(VROM_size);\r |
| 771 | \r |
| 772 | \r |
| 773 | if(head.ROM_type&8) Mirroring=2;\r |
| 774 | \r |
| 775 | if((ROM = (uint8 *)FCEU_malloc(ROM_size<<14)) == NULL) return 0;\r |
| 776 | \r |
| 777 | if(VROM_size)\r |
| 778 | {\r |
| 779 | if((VROM = (uint8 *)FCEU_malloc(VROM_size<<13)) == NULL)\r |
| 780 | {\r |
| 781 | free(ROM);\r |
| 782 | ROM = NULL;\r |
| 783 | return 0;\r |
| 784 | }\r |
| 785 | }\r |
| 786 | memset(ROM,0xFF,ROM_size<<14);\r |
| 787 | if(VROM_size) memset(VROM,0xFF,VROM_size<<13);\r |
| 788 | if(head.ROM_type&4) /* Trainer */\r |
| 789 | {\r |
| 790 | trainerpoo=(uint8 *)FCEU_gmalloc(512);\r |
| 791 | FCEU_fread(trainerpoo,512,1,fp);\r |
| 792 | }\r |
| 793 | \r |
| 794 | ResetCartMapping();\r |
| 795 | ResetExState(0,0);\r |
| 796 | \r |
| 797 | SetupCartPRGMapping(0,ROM,ROM_size*0x4000,0);\r |
| 798 | // SetupCartPRGMapping(1,WRAM,8192,1); // ?\r |
| 799 | \r |
| 800 | FCEU_fread(ROM,0x4000,(round) ? ROM_size : head.ROM_size,fp);\r |
| 801 | \r |
| 802 | if(VROM_size)\r |
| 803 | FCEU_fread(VROM,0x2000,head.VROM_size,fp);\r |
| 804 | \r |
| 805 | md5_starts(&md5);\r |
| 806 | md5_update(&md5,ROM,ROM_size<<14);\r |
| 807 | \r |
| 808 | iNESGameCRC32=CalcCRC32(0,ROM,ROM_size<<14);\r |
| 809 | \r |
| 810 | if(VROM_size)\r |
| 811 | {\r |
| 812 | iNESGameCRC32=CalcCRC32(iNESGameCRC32,VROM,VROM_size<<13);\r |
| 813 | md5_update(&md5,VROM,VROM_size<<13);\r |
| 814 | }\r |
| 815 | md5_finish(&md5,iNESCart.MD5);\r |
| 816 | memcpy(&GameInfo->MD5,&iNESCart.MD5,sizeof(iNESCart.MD5));\r |
| 817 | \r |
| 818 | iNESCart.CRC32=iNESGameCRC32;\r |
| 819 | \r |
| 820 | FCEU_printf(" PRG ROM: %3d x 16KiB\n CHR ROM: %3d x 8KiB\n ROM CRC32: 0x%08lx\n",\r |
| 821 | (round) ? ROM_size : head.ROM_size, head.VROM_size,\r |
| 822 | (unsigned long)iNESGameCRC32);\r |
| 823 | \r |
| 824 | {\r |
| 825 | int x;\r |
| 826 | FCEU_printf(" ROM MD5: 0x");\r |
| 827 | for(x=0;x<16;x++)\r |
| 828 | FCEU_printf("%02x",iNESCart.MD5[x]);\r |
| 829 | FCEU_printf("\n");\r |
| 830 | }\r |
| 831 | \r |
| 832 | char* mappername = "Not Listed";\r |
| 833 | int mappertest;\r |
| 834 | \r |
| 835 | for(mappertest=0;mappertest< (sizeof bmap / sizeof bmap[0]) - 1;mappertest++)\r |
| 836 | {\r |
| 837 | if (bmap[mappertest].number == MapperNo) {\r |
| 838 | mappername = bmap[mappertest].name;\r |
| 839 | break;\r |
| 840 | }\r |
| 841 | }\r |
| 842 | \r |
| 843 | FCEU_printf(" Mapper #: %d\n Mapper name: %s\n Mirroring: %s\n",\r |
| 844 | MapperNo, mappername, Mirroring==2?"None (Four-screen)":Mirroring?"Vertical":"Horizontal");\r |
| 845 | \r |
| 846 | FCEU_printf(" Battery-backed: %s\n", (head.ROM_type&2)?"Yes":"No");\r |
| 847 | FCEU_printf(" Trained: %s\n", (head.ROM_type&4)?"Yes":"No");\r |
| 848 | // (head.ROM_type&8) = Mirroring: None(Four-screen)\r |
| 849 | \r |
| 850 | SetInput();\r |
| 851 | CheckHInfo();\r |
| 852 | {\r |
| 853 | int x;\r |
| 854 | uint64 partialmd5=0;\r |
| 855 | \r |
| 856 | for(x=0;x<8;x++)\r |
| 857 | {\r |
| 858 | partialmd5 |= (uint64)iNESCart.MD5[7-x] << (x*8);\r |
| 859 | }\r |
| 860 | \r |
| 861 | FCEU_VSUniCheck(partialmd5, &MapperNo, &Mirroring);\r |
| 862 | }\r |
| 863 | /* Must remain here because above functions might change value of\r |
| 864 | VROM_size and free(VROM).\r |
| 865 | */\r |
| 866 | if(VROM_size)\r |
| 867 | SetupCartCHRMapping(0,VROM,VROM_size*0x2000,0);\r |
| 868 | \r |
| 869 | if(Mirroring==2)\r |
| 870 | SetupCartMirroring(4,1,ExtraNTARAM);\r |
| 871 | else if(Mirroring>=0x10)\r |
| 872 | SetupCartMirroring(2+(Mirroring&1),1,0);\r |
| 873 | else\r |
| 874 | SetupCartMirroring(Mirroring&1,(Mirroring&4)>>2,0);\r |
| 875 | \r |
| 876 | iNESCart.battery=(head.ROM_type&2)?1:0;\r |
| 877 | iNESCart.mirror=Mirroring;\r |
| 878 | \r |
| 879 | //if(MapperNo != 18) {\r |
| 880 | // if(ROM) free(ROM);\r |
| 881 | // if(VROM) free(VROM);\r |
| 882 | // ROM=VROM=0;\r |
| 883 | // return(0);\r |
| 884 | // }\r |
| 885 | \r |
| 886 | \r |
| 887 | GameInfo->mappernum = MapperNo;\r |
| 888 | MapperInit();\r |
| 889 | FCEU_LoadGameSave(&iNESCart);\r |
| 890 | \r |
| 891 | //strcpy(LoadedRomFName,name); //bbit edited: line added\r |
| 892 | \r |
| 893 | // Extract Filename only. Should account for Windows/Unix this way.\r |
| 894 | if (strrchr(name, '/')) {\r |
| 895 | name = strrchr(name, '/') + 1;\r |
| 896 | } else if(strrchr(name, '\\')) {\r |
| 897 | name = strrchr(name, '\\') + 1;\r |
| 898 | }\r |
| 899 | \r |
| 900 | GameInterface=iNESGI;\r |
| 901 | FCEU_printf("\n");\r |
| 902 | \r |
| 903 | // since apparently the iNES format doesn't store this information,\r |
| 904 | // guess if the settings should be PAL or NTSC from the ROM name\r |
| 905 | // TODO: MD5 check against a list of all known PAL games instead?\r |
| 906 | if(OverwriteVidMode)\r |
| 907 | {\r |
| 908 | if(strstr(name,"(E)") || strstr(name,"(e)")\r |
| 909 | || strstr(name,"(F)") || strstr(name,"(f)")\r |
| 910 | || strstr(name,"(G)") || strstr(name,"(g)")\r |
| 911 | || strstr(name,"(I)") || strstr(name,"(i)"))\r |
| 912 | FCEUI_SetVidSystem(1);\r |
| 913 | else\r |
| 914 | FCEUI_SetVidSystem(0);\r |
| 915 | }\r |
| 916 | return 1;\r |
| 917 | }\r |
| 918 | \r |
| 919 | \r |
| 920 | //bbit edited: the whole function below was added\r |
| 921 | int iNesSave(){\r |
| 922 | FILE *fp;\r |
| 923 | char name[2048];\r |
| 924 | \r |
| 925 | if(GameInfo->type != GIT_CART)return 0;\r |
| 926 | if(GameInterface!=iNESGI)return 0;\r |
| 927 | \r |
| 928 | //strcpy(name,LoadedRomFName);\r |
| 929 | if (strcmp(name+strlen(name)-4,".nes") != 0) { //para edit\r |
| 930 | strcat(name,".nes");\r |
| 931 | }\r |
| 932 | \r |
| 933 | fp = fopen(name,"wb");\r |
| 934 | \r |
| 935 | if(fwrite(&head,1,16,fp)!=16)\r |
| 936 | {\r |
| 937 | fclose(fp);\r |
| 938 | return 0;\r |
| 939 | }\r |
| 940 | \r |
| 941 | if(head.ROM_type&4) /* Trainer */\r |
| 942 | {\r |
| 943 | fwrite(trainerpoo,512,1,fp);\r |
| 944 | }\r |
| 945 | \r |
| 946 | fwrite(ROM,0x4000,ROM_size,fp);\r |
| 947 | \r |
| 948 | if(head.VROM_size)fwrite(VROM,0x2000,head.VROM_size,fp);\r |
| 949 | fclose(fp);\r |
| 950 | \r |
| 951 | return 1;\r |
| 952 | }\r |
| 953 | \r |
| 954 | int iNesSaveAs(char* name)\r |
| 955 | {\r |
| 956 | //adelikat: TODO: iNesSave() and this have pretty much the same code, outsource the common code to a single function\r |
| 957 | FILE *fp;\r |
| 958 | \r |
| 959 | if(GameInfo->type != GIT_CART)return 0;\r |
| 960 | if(GameInterface != iNESGI)return 0;\r |
| 961 | \r |
| 962 | fp = fopen(name,"wb");\r |
| 963 | \r |
| 964 | if(fwrite(&head,1,16,fp)!=16)\r |
| 965 | {\r |
| 966 | fclose(fp);\r |
| 967 | return 0;\r |
| 968 | }\r |
| 969 | \r |
| 970 | if(head.ROM_type&4) /* Trainer */\r |
| 971 | {\r |
| 972 | fwrite(trainerpoo,512,1,fp);\r |
| 973 | }\r |
| 974 | \r |
| 975 | fwrite(ROM,0x4000,ROM_size,fp);\r |
| 976 | \r |
| 977 | if(head.VROM_size)fwrite(VROM,0x2000,head.VROM_size,fp);\r |
| 978 | fclose(fp);\r |
| 979 | \r |
| 980 | return 1;\r |
| 981 | }\r |
| 982 | \r |
| 983 | //para edit: added function below\r |
| 984 | #if 0\r |
| 985 | char *iNesShortFName() {\r |
| 986 | char *ret;\r |
| 987 | \r |
| 988 | if (!(ret = strrchr(LoadedRomFName,'\\'))) {\r |
| 989 | if (!(ret = strrchr(LoadedRomFName,'/'))) return 0;\r |
| 990 | }\r |
| 991 | return ret+1;\r |
| 992 | }\r |
| 993 | #endif\r |
| 994 | \r |
| 995 | void VRAM_BANK1(uint32 A, uint8 V)\r |
| 996 | {\r |
| 997 | V&=7;\r |
| 998 | PPUCHRRAM|=(1<<(A>>10));\r |
| 999 | CHRBankList[(A)>>10]=V;\r |
| 1000 | VPage[(A)>>10]=&CHRRAM[V<<10]-(A);\r |
| 1001 | }\r |
| 1002 | \r |
| 1003 | void VRAM_BANK4(uint32 A, uint32 V)\r |
| 1004 | {\r |
| 1005 | V&=1;\r |
| 1006 | PPUCHRRAM|=(0xF<<(A>>10));\r |
| 1007 | CHRBankList[(A)>>10]=(V<<2);\r |
| 1008 | CHRBankList[((A)>>10)+1]=(V<<2)+1;\r |
| 1009 | CHRBankList[((A)>>10)+2]=(V<<2)+2;\r |
| 1010 | CHRBankList[((A)>>10)+3]=(V<<2)+3;\r |
| 1011 | VPage[(A)>>10]=&CHRRAM[V<<10]-(A);\r |
| 1012 | }\r |
| 1013 | void VROM_BANK1(uint32 A,uint32 V)\r |
| 1014 | {\r |
| 1015 | setchr1(A,V);\r |
| 1016 | CHRBankList[(A)>>10]=V;\r |
| 1017 | }\r |
| 1018 | \r |
| 1019 | void VROM_BANK2(uint32 A,uint32 V)\r |
| 1020 | {\r |
| 1021 | setchr2(A,V);\r |
| 1022 | CHRBankList[(A)>>10]=(V<<1);\r |
| 1023 | CHRBankList[((A)>>10)+1]=(V<<1)+1;\r |
| 1024 | }\r |
| 1025 | \r |
| 1026 | void VROM_BANK4(uint32 A, uint32 V)\r |
| 1027 | {\r |
| 1028 | setchr4(A,V);\r |
| 1029 | CHRBankList[(A)>>10]=(V<<2);\r |
| 1030 | CHRBankList[((A)>>10)+1]=(V<<2)+1;\r |
| 1031 | CHRBankList[((A)>>10)+2]=(V<<2)+2;\r |
| 1032 | CHRBankList[((A)>>10)+3]=(V<<2)+3;\r |
| 1033 | }\r |
| 1034 | \r |
| 1035 | void VROM_BANK8(uint32 V)\r |
| 1036 | {\r |
| 1037 | setchr8(V);\r |
| 1038 | CHRBankList[0]=(V<<3);\r |
| 1039 | CHRBankList[1]=(V<<3)+1;\r |
| 1040 | CHRBankList[2]=(V<<3)+2;\r |
| 1041 | CHRBankList[3]=(V<<3)+3;\r |
| 1042 | CHRBankList[4]=(V<<3)+4;\r |
| 1043 | CHRBankList[5]=(V<<3)+5;\r |
| 1044 | CHRBankList[6]=(V<<3)+6;\r |
| 1045 | CHRBankList[7]=(V<<3)+7;\r |
| 1046 | }\r |
| 1047 | \r |
| 1048 | void ROM_BANK8(uint32 A, uint32 V)\r |
| 1049 | {\r |
| 1050 | setprg8(A,V);\r |
| 1051 | if(A>=0x8000)\r |
| 1052 | PRGBankList[((A-0x8000)>>13)]=V;\r |
| 1053 | }\r |
| 1054 | \r |
| 1055 | void ROM_BANK16(uint32 A, uint32 V)\r |
| 1056 | {\r |
| 1057 | setprg16(A,V);\r |
| 1058 | if(A>=0x8000)\r |
| 1059 | {\r |
| 1060 | PRGBankList[((A-0x8000)>>13)]=V<<1;\r |
| 1061 | PRGBankList[((A-0x8000)>>13)+1]=(V<<1)+1;\r |
| 1062 | }\r |
| 1063 | }\r |
| 1064 | \r |
| 1065 | void ROM_BANK32(uint32 V)\r |
| 1066 | {\r |
| 1067 | setprg32(0x8000,V);\r |
| 1068 | PRGBankList[0]=V<<2;\r |
| 1069 | PRGBankList[1]=(V<<2)+1;\r |
| 1070 | PRGBankList[2]=(V<<2)+2;\r |
| 1071 | PRGBankList[3]=(V<<2)+3;\r |
| 1072 | }\r |
| 1073 | \r |
| 1074 | void onemir(uint8 V)\r |
| 1075 | {\r |
| 1076 | if(Mirroring==2) return;\r |
| 1077 | if(V>1)\r |
| 1078 | V=1;\r |
| 1079 | Mirroring=0x10|V;\r |
| 1080 | setmirror(MI_0+V);\r |
| 1081 | }\r |
| 1082 | \r |
| 1083 | void MIRROR_SET2(uint8 V)\r |
| 1084 | {\r |
| 1085 | if(Mirroring==2) return;\r |
| 1086 | Mirroring=V;\r |
| 1087 | setmirror(V);\r |
| 1088 | }\r |
| 1089 | \r |
| 1090 | void MIRROR_SET(uint8 V)\r |
| 1091 | {\r |
| 1092 | if(Mirroring==2) return;\r |
| 1093 | V^=1;\r |
| 1094 | Mirroring=V;\r |
| 1095 | setmirror(V);\r |
| 1096 | }\r |
| 1097 | \r |
| 1098 | static void NONE_init(void)\r |
| 1099 | {\r |
| 1100 | ROM_BANK16(0x8000,0);\r |
| 1101 | ROM_BANK16(0xC000,~0);\r |
| 1102 | \r |
| 1103 | if(VROM_size)\r |
| 1104 | VROM_BANK8(0);\r |
| 1105 | else\r |
| 1106 | setvram8(CHRRAM);\r |
| 1107 | }\r |
| 1108 | void (*MapInitTab[256])(void)=\r |
| 1109 | {\r |
| 1110 | 0,\r |
| 1111 | 0,\r |
| 1112 | 0, //Mapper2_init,\r |
| 1113 | 0, //Mapper3_init,\r |
| 1114 | 0,\r |
| 1115 | 0,\r |
| 1116 | Mapper6_init,\r |
| 1117 | 0,//Mapper7_init,\r |
| 1118 | Mapper8_init,\r |
| 1119 | Mapper9_init,\r |
| 1120 | Mapper10_init,\r |
| 1121 | 0, //Mapper11_init,\r |
| 1122 | 0,\r |
| 1123 | 0, //Mapper13_init,\r |
| 1124 | 0,\r |
| 1125 | 0, //Mapper15_init,\r |
| 1126 | 0, //Mapper16_init,\r |
| 1127 | Mapper17_init,\r |
| 1128 | Mapper18_init,\r |
| 1129 | 0,\r |
| 1130 | 0,\r |
| 1131 | Mapper21_init,\r |
| 1132 | Mapper22_init,\r |
| 1133 | 0, //Mapper23_init,\r |
| 1134 | Mapper24_init,\r |
| 1135 | Mapper25_init,\r |
| 1136 | Mapper26_init,\r |
| 1137 | Mapper27_init,\r |
| 1138 | 0,\r |
| 1139 | 0,\r |
| 1140 | 0,\r |
| 1141 | 0,\r |
| 1142 | Mapper32_init,\r |
| 1143 | Mapper33_init,\r |
| 1144 | Mapper34_init,\r |
| 1145 | 0,\r |
| 1146 | 0,\r |
| 1147 | 0,\r |
| 1148 | 0,\r |
| 1149 | 0,\r |
| 1150 | Mapper40_init,\r |
| 1151 | Mapper41_init,\r |
| 1152 | Mapper42_init,\r |
| 1153 | 0, //Mapper43_init,\r |
| 1154 | 0,\r |
| 1155 | 0,\r |
| 1156 | Mapper46_init,\r |
| 1157 | 0,\r |
| 1158 | Mapper48_init,\r |
| 1159 | 0,\r |
| 1160 | Mapper50_init,\r |
| 1161 | Mapper51_init,\r |
| 1162 | 0,\r |
| 1163 | 0,\r |
| 1164 | 0,\r |
| 1165 | 0,\r |
| 1166 | 0,\r |
| 1167 | 0,// Mapper57_init,\r |
| 1168 | 0,// Mapper58_init,\r |
| 1169 | Mapper59_init,\r |
| 1170 | 0,// Mapper60_init,\r |
| 1171 | Mapper61_init,\r |
| 1172 | Mapper62_init,\r |
| 1173 | 0,\r |
| 1174 | Mapper64_init,\r |
| 1175 | Mapper65_init,\r |
| 1176 | 0,//Mapper66_init,\r |
| 1177 | Mapper67_init,\r |
| 1178 | 0,//Mapper68_init,\r |
| 1179 | Mapper69_init,\r |
| 1180 | 0,//Mapper70_init,\r |
| 1181 | Mapper71_init,\r |
| 1182 | Mapper72_init,\r |
| 1183 | Mapper73_init,\r |
| 1184 | 0,\r |
| 1185 | Mapper75_init,\r |
| 1186 | Mapper76_init,\r |
| 1187 | Mapper77_init,\r |
| 1188 | 0, //Mapper78_init,\r |
| 1189 | Mapper79_init,\r |
| 1190 | Mapper80_init,\r |
| 1191 | 0,\r |
| 1192 | Mapper82_init,\r |
| 1193 | Mapper83_init,\r |
| 1194 | 0,\r |
| 1195 | Mapper85_init,\r |
| 1196 | Mapper86_init,\r |
| 1197 | 0, //Mapper87_init,\r |
| 1198 | 0, //Mapper88_init,\r |
| 1199 | Mapper89_init,\r |
| 1200 | 0,\r |
| 1201 | Mapper91_init,\r |
| 1202 | Mapper92_init,\r |
| 1203 | 0, //Mapper93_init,\r |
| 1204 | 0, //Mapper94_init,\r |
| 1205 | 0,\r |
| 1206 | Mapper96_init,\r |
| 1207 | Mapper97_init,\r |
| 1208 | 0,\r |
| 1209 | Mapper99_init,\r |
| 1210 | 0,\r |
| 1211 | 0,\r |
| 1212 | 0,\r |
| 1213 | 0,\r |
| 1214 | 0,\r |
| 1215 | 0,\r |
| 1216 | 0,\r |
| 1217 | 0, //Mapper107_init,\r |
| 1218 | 0,\r |
| 1219 | 0,\r |
| 1220 | 0,\r |
| 1221 | 0,\r |
| 1222 | 0,\r |
| 1223 | 0, // Mapper113_init,\r |
| 1224 | 0,\r |
| 1225 | 0,\r |
| 1226 | 0, //Mapper116_init,\r |
| 1227 | 0, //Mapper117_init,\r |
| 1228 | 0,\r |
| 1229 | 0,\r |
| 1230 | 0,\r |
| 1231 | 0,\r |
| 1232 | 0,\r |
| 1233 | 0,\r |
| 1234 | 0,\r |
| 1235 | 0,\r |
| 1236 | 0,\r |
| 1237 | 0,\r |
| 1238 | 0,\r |
| 1239 | 0,\r |
| 1240 | 0,\r |
| 1241 | 0,\r |
| 1242 | 0,\r |
| 1243 | 0,\r |
| 1244 | 0,\r |
| 1245 | 0,\r |
| 1246 | 0,\r |
| 1247 | 0,\r |
| 1248 | 0,\r |
| 1249 | 0,\r |
| 1250 | 0, //Mapper140_init,\r |
| 1251 | 0,\r |
| 1252 | 0,\r |
| 1253 | 0,\r |
| 1254 | 0, //Mapper144_init,\r |
| 1255 | 0,\r |
| 1256 | 0,\r |
| 1257 | 0,\r |
| 1258 | 0,\r |
| 1259 | 0,\r |
| 1260 | 0,\r |
| 1261 | Mapper151_init,\r |
| 1262 | 0, //Mapper152_init,\r |
| 1263 | 0, //Mapper153_init,\r |
| 1264 | 0, //Mapper154_init,\r |
| 1265 | 0,\r |
| 1266 | 0,\r |
| 1267 | Mapper157_init,\r |
| 1268 | 0, //Mapper158_init, removed\r |
| 1269 | 0,\r |
| 1270 | 0,\r |
| 1271 | 0,\r |
| 1272 | 0,\r |
| 1273 | 0,\r |
| 1274 | 0,\r |
| 1275 | 0,\r |
| 1276 | Mapper166_init,\r |
| 1277 | Mapper167_init,\r |
| 1278 | 0,\r |
| 1279 | 0,\r |
| 1280 | 0,\r |
| 1281 | 0,\r |
| 1282 | 0,\r |
| 1283 | 0,\r |
| 1284 | 0,\r |
| 1285 | 0,\r |
| 1286 | 0,\r |
| 1287 | 0,\r |
| 1288 | 0,\r |
| 1289 | 0,\r |
| 1290 | 0, //Mapper180_init,\r |
| 1291 | 0,\r |
| 1292 | 0,\r |
| 1293 | 0,\r |
| 1294 | 0, //Mapper184_init,\r |
| 1295 | 0, //Mapper185_init,\r |
| 1296 | 0,\r |
| 1297 | 0,\r |
| 1298 | 0,\r |
| 1299 | 0, //Mapper189_init,\r |
| 1300 | 0,\r |
| 1301 | 0, //Mapper191_init,\r |
| 1302 | 0,\r |
| 1303 | Mapper193_init,\r |
| 1304 | 0,\r |
| 1305 | 0,\r |
| 1306 | 0,\r |
| 1307 | 0,\r |
| 1308 | 0,\r |
| 1309 | 0,\r |
| 1310 | 0, //Mapper200_init,\r |
| 1311 | Mapper201_init,\r |
| 1312 | Mapper202_init,\r |
| 1313 | Mapper203_init,\r |
| 1314 | Mapper204_init,\r |
| 1315 | 0,\r |
| 1316 | 0,\r |
| 1317 | Mapper207_init,\r |
| 1318 | 0,\r |
| 1319 | 0,\r |
| 1320 | 0,\r |
| 1321 | 0, //Mapper211_init,\r |
| 1322 | Mapper212_init,\r |
| 1323 | Mapper213_init,\r |
| 1324 | Mapper214_init,\r |
| 1325 | 0,\r |
| 1326 | 0,\r |
| 1327 | 0,\r |
| 1328 | 0,\r |
| 1329 | 0,\r |
| 1330 | 0,\r |
| 1331 | 0,\r |
| 1332 | 0,\r |
| 1333 | 0,\r |
| 1334 | 0,\r |
| 1335 | Mapper225_init,\r |
| 1336 | 0, //Mapper226_init,\r |
| 1337 | Mapper227_init,\r |
| 1338 | Mapper228_init,\r |
| 1339 | Mapper229_init,\r |
| 1340 | Mapper230_init,\r |
| 1341 | Mapper231_init,\r |
| 1342 | Mapper232_init,\r |
| 1343 | 0,\r |
| 1344 | Mapper234_init,\r |
| 1345 | 0, //Mapper235_init,\r |
| 1346 | 0,\r |
| 1347 | 0,\r |
| 1348 | 0,\r |
| 1349 | 0,\r |
| 1350 | 0, //Mapper240_init,\r |
| 1351 | Mapper241_init,\r |
| 1352 | Mapper242_init,\r |
| 1353 | 0,\r |
| 1354 | Mapper244_init,\r |
| 1355 | 0,\r |
| 1356 | Mapper246_init,\r |
| 1357 | 0,\r |
| 1358 | 0,\r |
| 1359 | 0,\r |
| 1360 | 0,\r |
| 1361 | 0,\r |
| 1362 | 0,\r |
| 1363 | 0,\r |
| 1364 | 0,\r |
| 1365 | Mapper255_init\r |
| 1366 | };\r |
| 1367 | \r |
| 1368 | static DECLFW(BWRAM)\r |
| 1369 | {\r |
| 1370 | WRAM[A-0x6000]=V;\r |
| 1371 | }\r |
| 1372 | \r |
| 1373 | static DECLFR(AWRAM)\r |
| 1374 | {\r |
| 1375 | return WRAM[A-0x6000];\r |
| 1376 | }\r |
| 1377 | \r |
| 1378 | \r |
| 1379 | void (*MapStateRestore)(int version);\r |
| 1380 | void iNESStateRestore(int version)\r |
| 1381 | {\r |
| 1382 | int x;\r |
| 1383 | \r |
| 1384 | if(!MapperNo) return;\r |
| 1385 | \r |
| 1386 | for(x=0;x<4;x++)\r |
| 1387 | setprg8(0x8000+x*8192,PRGBankList[x]);\r |
| 1388 | \r |
| 1389 | if(VROM_size)\r |
| 1390 | for(x=0;x<8;x++)\r |
| 1391 | setchr1(0x400*x,CHRBankList[x]);\r |
| 1392 | \r |
| 1393 | if(0) switch(Mirroring)\r |
| 1394 | {\r |
| 1395 | case 0:setmirror(MI_H);break;\r |
| 1396 | case 1:setmirror(MI_V);break;\r |
| 1397 | case 0x12:\r |
| 1398 | case 0x10:setmirror(MI_0);break;\r |
| 1399 | case 0x13:\r |
| 1400 | case 0x11:setmirror(MI_1);break;\r |
| 1401 | }\r |
| 1402 | if(MapStateRestore) MapStateRestore(version);\r |
| 1403 | }\r |
| 1404 | \r |
| 1405 | static void iNESPower(void)\r |
| 1406 | {\r |
| 1407 | int x;\r |
| 1408 | int type=MapperNo;\r |
| 1409 | \r |
| 1410 | SetReadHandler(0x8000,0xFFFF,CartBR);\r |
| 1411 | GameStateRestore=iNESStateRestore;\r |
| 1412 | MapClose=0;\r |
| 1413 | MapperReset=0;\r |
| 1414 | MapStateRestore=0;\r |
| 1415 | \r |
| 1416 | setprg8r(1,0x6000,0);\r |
| 1417 | \r |
| 1418 | SetReadHandler(0x6000,0x7FFF,AWRAM);\r |
| 1419 | #ifdef ASM_6502\r |
| 1420 | // asm code needs pages to be set again..\r |
| 1421 | Page[12]=Page[13]=Page[14]=Page[15]=WRAM-0x6000;\r |
| 1422 | #endif\r |
| 1423 | SetWriteHandler(0x6000,0x7FFF,BWRAM);\r |
| 1424 | FCEU_CheatAddRAM(8,0x6000,WRAM);\r |
| 1425 | \r |
| 1426 | /* This statement represents atrocious code. I need to rewrite\r |
| 1427 | all of the iNES mapper code... */\r |
| 1428 | IRQCount=IRQLatch=IRQa=0;\r |
| 1429 | if(head.ROM_type&2)\r |
| 1430 | memset(GameMemBlock+8192,0,GAME_MEM_BLOCK_SIZE-8192);\r |
| 1431 | else\r |
| 1432 | memset(GameMemBlock,0,GAME_MEM_BLOCK_SIZE);\r |
| 1433 | \r |
| 1434 | NONE_init();\r |
| 1435 | ResetExState(0,0);\r |
| 1436 | \r |
| 1437 | if(GameInfo->type == GIT_VSUNI)\r |
| 1438 | AddExState(FCEUVSUNI_STATEINFO, ~0, 0, 0);\r |
| 1439 | \r |
| 1440 | AddExState(WRAM, 8192, 0, "WRAM");\r |
| 1441 | if(type==19 || type==6 || type==69 || type==85 || type==96)\r |
| 1442 | AddExState(MapperExRAM, 32768, 0, "MEXR");\r |
| 1443 | if((!VROM_size || type==6 || type==19) && (type!=13 && type!=96))\r |
| 1444 | AddExState(CHRRAM, 8192, 0, "CHRR");\r |
| 1445 | if(head.ROM_type&8)\r |
| 1446 | AddExState(ExtraNTARAM, 2048, 0, "EXNR");\r |
| 1447 | \r |
| 1448 | /* Exclude some mappers whose emulation code handle save state stuff\r |
| 1449 | themselves. */\r |
| 1450 | if(type && type!=13 && type!=96)\r |
| 1451 | {\r |
| 1452 | AddExState(mapbyte1, 32, 0, "MPBY");\r |
| 1453 | AddExState(&Mirroring, 1, 0, "MIRR");\r |
| 1454 | AddExState(&IRQCount, 4, 1, "IRQC");\r |
| 1455 | AddExState(&IRQLatch, 4, 1, "IQL1");\r |
| 1456 | AddExState(&IRQa, 1, 0, "IRQA");\r |
| 1457 | AddExState(PRGBankList, 4, 0, "PBL");\r |
| 1458 | for(x=0;x<8;x++)\r |
| 1459 | {\r |
| 1460 | char tak[8];\r |
| 1461 | sprintf(tak,"CBL%d",x);\r |
| 1462 | AddExState(&CHRBankList[x], 2, 1,tak);\r |
| 1463 | }\r |
| 1464 | }\r |
| 1465 | \r |
| 1466 | if(MapInitTab[type]) MapInitTab[type]();\r |
| 1467 | else if(type)\r |
| 1468 | {\r |
| 1469 | FCEU_PrintError("iNES mapper #%d is not supported at all.",type);\r |
| 1470 | }\r |
| 1471 | }\r |
| 1472 | \r |
| 1473 | static int NewiNES_Init(int num)\r |
| 1474 | {\r |
| 1475 | BMAPPINGLocal *tmp=bmap;\r |
| 1476 | \r |
| 1477 | CHRRAMSize = -1;\r |
| 1478 | \r |
| 1479 | if(GameInfo->type == GIT_VSUNI)\r |
| 1480 | AddExState(FCEUVSUNI_STATEINFO, ~0, 0, 0);\r |
| 1481 | \r |
| 1482 | while(tmp->init)\r |
| 1483 | {\r |
| 1484 | if(num==tmp->number)\r |
| 1485 | {\r |
| 1486 | UNIFchrrama=0; // need here for compatibility with UNIF mapper code\r |
| 1487 | if(!VROM_size)\r |
| 1488 | {\r |
| 1489 | if(num==13)\r |
| 1490 | {\r |
| 1491 | CHRRAMSize=16384;\r |
| 1492 | }\r |
| 1493 | else\r |
| 1494 | {\r |
| 1495 | CHRRAMSize=8192;\r |
| 1496 | }\r |
| 1497 | if((VROM = (uint8 *)FCEU_malloc(CHRRAMSize)) == NULL) return 0;\r |
| 1498 | FCEU_MemoryRand(VROM,CHRRAMSize);\r |
| 1499 | \r |
| 1500 | UNIFchrrama=VROM;\r |
| 1501 | SetupCartCHRMapping(0,VROM,CHRRAMSize,1);\r |
| 1502 | AddExState(VROM,CHRRAMSize, 0, "CHRR");\r |
| 1503 | }\r |
| 1504 | if(head.ROM_type&8)\r |
| 1505 | AddExState(ExtraNTARAM, 2048, 0, "EXNR");\r |
| 1506 | tmp->init(&iNESCart);\r |
| 1507 | return 1;\r |
| 1508 | }\r |
| 1509 | tmp++;\r |
| 1510 | }\r |
| 1511 | return 0;\r |
| 1512 | }\r |
| 1513 | \r |
| 1514 | // vim:ts=4\r |