| 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 | // {6, Mapper6_Init},\r |
| 559 | {"ANROM", 7, ANROM_Init},\r |
| 560 | {"", 8, Mapper8_Init}, // Nogaems, it's worthless\r |
| 561 | // {9, Mapper9_Init},\r |
| 562 | // {10, Mapper10_Init},\r |
| 563 | {"Color Dreams", 11, Mapper11_Init},\r |
| 564 | {"", 12, Mapper12_Init},\r |
| 565 | {"CPROM", 13, CPROM_Init},\r |
| 566 | // {14, Mapper14_Init},\r |
| 567 | {"100-in1", 15, Mapper15_Init},\r |
| 568 | {"Bandai", 16, Mapper16_Init},\r |
| 569 | {"", 17, Mapper17_Init},\r |
| 570 | {"", 18, Mapper18_Init},\r |
| 571 | {"Namcot 106", 19, Mapper19_Init},\r |
| 572 | // {20, Mapper20_Init},\r |
| 573 | // {21, Mapper21_Init},\r |
| 574 | // {22, Mapper22_Init},\r |
| 575 | {"Konami VRC2 type B", 23, Mapper23_Init},\r |
| 576 | // {24, Mapper24_Init},\r |
| 577 | // {25, Mapper25_Init},\r |
| 578 | // {26, Mapper26_Init},\r |
| 579 | // {27, Mapper27_Init},\r |
| 580 | // {28, Mapper28_Init},\r |
| 581 | // {29, Mapper29_Init},\r |
| 582 | // {30, Mapper30_Init},\r |
| 583 | // {31, Mapper31_Init},\r |
| 584 | // {32, Mapper32_Init},\r |
| 585 | // {33, Mapper33_Init},\r |
| 586 | {"", 34, Mapper34_Init},\r |
| 587 | {"Wario Land 2", 35, UNLSC127_Init}, // Wario Land 2\r |
| 588 | {"TXC Policeman", 36, Mapper36_Init}, // TXC Policeman\r |
| 589 | {"", 37, Mapper37_Init},\r |
| 590 | {"Bit Corp. Crime Busters", 38, Mapper38_Init}, // Bit Corp. Crime Busters\r |
| 591 | // {39, Mapper39_Init},\r |
| 592 | // {40, Mapper40_Init},\r |
| 593 | // {41, Mapper41_Init},\r |
| 594 | // {42, Mapper42_Init},\r |
| 595 | {"", 43, Mapper43_Init},\r |
| 596 | {"", 44, Mapper44_Init},\r |
| 597 | {"", 45, Mapper45_Init},\r |
| 598 | // {46, Mapper46_Init},\r |
| 599 | {"", 47, Mapper47_Init},\r |
| 600 | // {48, Mapper48_Init},\r |
| 601 | {"", 49, Mapper49_Init},\r |
| 602 | // {50, Mapper50_Init},\r |
| 603 | // {51, Mapper51_Init},\r |
| 604 | {"", 52, Mapper52_Init},\r |
| 605 | // {53, Mapper53_Init},\r |
| 606 | // {54, Mapper54_Init},\r |
| 607 | // {55, Mapper55_Init},\r |
| 608 | // {56, Mapper56_Init},\r |
| 609 | {"", 57, Mapper57_Init},\r |
| 610 | {"", 58, BMCGK192_Init},\r |
| 611 | // {59, Mapper59_Init},\r |
| 612 | {"", 60, BMCD1038_Init},\r |
| 613 | // {61, Mapper61_Init},\r |
| 614 | // {62, Mapper62_Init},\r |
| 615 | // {63, Mapper63_Init},\r |
| 616 | // {64, Mapper64_Init},\r |
| 617 | // {65, Mapper65_Init},\r |
| 618 | {"MHROM", 66, MHROM_Init},\r |
| 619 | // {67, Mapper67_Init},\r |
| 620 | {"Sunsoft Mapper #4", 68, Mapper68_Init},\r |
| 621 | // {69, Mapper69_Init},\r |
| 622 | {"", 70, Mapper70_Init},\r |
| 623 | // {71, Mapper71_Init},\r |
| 624 | // {72, Mapper72_Init},\r |
| 625 | // {73, Mapper73_Init},\r |
| 626 | {"", 74, Mapper74_Init},\r |
| 627 | // {75, Mapper75_Init},\r |
| 628 | // {76, Mapper76_Init},\r |
| 629 | // {77, Mapper77_Init},\r |
| 630 | {"Irem 74HC161/32", 78, Mapper78_Init},\r |
| 631 | // {79, Mapper79_Init},\r |
| 632 | // {80, Mapper80_Init},\r |
| 633 | // {81, Mapper81_Init},\r |
| 634 | {"", 82, Mapper82_Init},\r |
| 635 | {"", 83, Mapper83_Init},\r |
| 636 | // {84, Mapper84_Init},\r |
| 637 | // {85, Mapper85_Init},\r |
| 638 | {"", 86, Mapper86_Init},\r |
| 639 | {"", 87, Mapper87_Init},\r |
| 640 | {"", 88, Mapper88_Init},\r |
| 641 | {"", 89, Mapper89_Init},\r |
| 642 | {"", 90, Mapper90_Init},\r |
| 643 | {"", 91, Mapper91_Init},\r |
| 644 | {"", 92, Mapper92_Init},\r |
| 645 | {"Sunsoft UNROM", 93, SUNSOFT_UNROM_Init},\r |
| 646 | {"", 94, Mapper94_Init},\r |
| 647 | {"", 95, Mapper95_Init},\r |
| 648 | {"", 96, Mapper96_Init},\r |
| 649 | {"", 97, Mapper97_Init},\r |
| 650 | // {98, Mapper98_Init},\r |
| 651 | {"", 99, Mapper99_Init},\r |
| 652 | // {100, Mapper100_Init},\r |
| 653 | {"", 101, Mapper101_Init},\r |
| 654 | // {102, Mapper102_Init},\r |
| 655 | {"", 103, Mapper103_Init},\r |
| 656 | // {104, Mapper104_Init},\r |
| 657 | {"", 105, Mapper105_Init},\r |
| 658 | {"", 106, Mapper106_Init},\r |
| 659 | {"", 107, Mapper107_Init},\r |
| 660 | {"", 108, Mapper108_Init},\r |
| 661 | // {109, Mapper109_Init},\r |
| 662 | // {110, Mapper110_Init},\r |
| 663 | // {111, Mapper111_Init},\r |
| 664 | {"", 112, Mapper112_Init},\r |
| 665 | {"", 113, Mapper113_Init},\r |
| 666 | {"", 114, Mapper114_Init},\r |
| 667 | {"", 115, Mapper115_Init},\r |
| 668 | {"UNLSL12", 116, UNLSL12_Init},\r |
| 669 | {"", 117, Mapper117_Init},\r |
| 670 | {"TSKROM", 118, TKSROM_Init},\r |
| 671 | {"", 119, Mapper119_Init},\r |
| 672 | {"", 120, Mapper120_Init},\r |
| 673 | {"", 121, Mapper121_Init},\r |
| 674 | // {122, Mapper122_Init},\r |
| 675 | {"UNLH2288", 123, UNLH2288_Init},\r |
| 676 | // {124, Mapper124_Init},\r |
| 677 | // {125, Mapper125_Init},\r |
| 678 | // {126, Mapper126_Init},\r |
| 679 | // {127, Mapper127_Init},\r |
| 680 | // {128, Mapper128_Init},\r |
| 681 | // {129, Mapper129_Init},\r |
| 682 | // {130, Mapper130_Init},\r |
| 683 | // {131, Mapper131_Init},\r |
| 684 | {"UNL22211", 132, UNL22211_Init},\r |
| 685 | {"SA72008", 133, SA72008_Init},\r |
| 686 | {"", 134, Mapper134_Init},\r |
| 687 | // {135, Mapper135_Init},\r |
| 688 | {"TCU02", 136, TCU02_Init},\r |
| 689 | {"S8259D", 137, S8259D_Init},\r |
| 690 | {"S8259B", 138, S8259B_Init},\r |
| 691 | {"S8259C", 139, S8259C_Init},\r |
| 692 | {"", 140, Mapper140_Init},\r |
| 693 | {"S8259A", 141, S8259A_Init},\r |
| 694 | {"UNLKS7032", 142, UNLKS7032_Init},\r |
| 695 | {"TCA01", 143, TCA01_Init},\r |
| 696 | {"", 144, Mapper144_Init},\r |
| 697 | {"SA72007", 145, SA72007_Init},\r |
| 698 | {"SA0161M", 146, SA0161M_Init},\r |
| 699 | {"TCU01", 147, TCU01_Init},\r |
| 700 | {"SA0037", 148, SA0037_Init},\r |
| 701 | {"SA0036", 149, SA0036_Init},\r |
| 702 | {"S74LS374N", 150, S74LS374N_Init},\r |
| 703 | {"", 151, Mapper151_Init},\r |
| 704 | {"", 152, Mapper152_Init},\r |
| 705 | {"", 153, Mapper153_Init},\r |
| 706 | {"", 154, Mapper154_Init},\r |
| 707 | {"", 155, Mapper155_Init},\r |
| 708 | {"", 156, Mapper156_Init},\r |
| 709 | {"", 157, Mapper157_Init},\r |
| 710 | // {158, Mapper158_Init},\r |
| 711 | // {159, Mapper159_Init},\r |
| 712 | {"SA009", 160, SA009_Init},\r |
| 713 | // {161, Mapper161_Init},\r |
| 714 | {"", 162, UNLFS304_Init},\r |
| 715 | {"", 163, Mapper163_Init},\r |
| 716 | {"", 164, Mapper164_Init},\r |
| 717 | {"", 165, Mapper165_Init},\r |
| 718 | // {166, Mapper166_Init},\r |
| 719 | // {167, Mapper167_Init},\r |
| 720 | {"", 168, Mapper168_Init},\r |
| 721 | // {169, Mapper169_Init},\r |
| 722 | {"", 171, Mapper171_Init},\r |
| 723 | {"", 172, Mapper172_Init},\r |
| 724 | {"", 173, Mapper173_Init},\r |
| 725 | {"", 175, Mapper175_Init},\r |
| 726 | // {174, Mapper174_Init},\r |
| 727 | {"", 175, Mapper175_Init},\r |
| 728 | {"BMCFK23C", 176, BMCFK23C_Init},\r |
| 729 | {"", 177, Mapper177_Init},\r |
| 730 | {"", 178, Mapper178_Init},\r |
| 731 | // {179, Mapper179_Init},\r |
| 732 | {"", 180, Mapper180_Init},\r |
| 733 | {"", 181, Mapper181_Init},\r |
| 734 | // {"", 182, Mapper182_Init}, // identical to 114\r |
| 735 | {"", 183, Mapper183_Init},\r |
| 736 | {"", 184, Mapper184_Init},\r |
| 737 | {"", 185, Mapper185_Init},\r |
| 738 | {"", 186, Mapper186_Init},\r |
| 739 | {"", 187, Mapper187_Init},\r |
| 740 | {"", 188, Mapper188_Init},\r |
| 741 | {"", 189, Mapper189_Init},\r |
| 742 | // {190, Mapper190_Init},\r |
| 743 | {"", 191, Mapper191_Init},\r |
| 744 | {"", 192, Mapper192_Init},\r |
| 745 | {"", 193, Mapper193_Init},\r |
| 746 | {"", 194, Mapper194_Init},\r |
| 747 | {"", 195, Mapper195_Init},\r |
| 748 | {"", 196, Mapper196_Init},\r |
| 749 | {"", 197, Mapper197_Init},\r |
| 750 | {"", 198, Mapper198_Init},\r |
| 751 | {"", 199, Mapper199_Init},\r |
| 752 | {"", 200, Mapper200_Init},\r |
| 753 | // {201, Mapper201_Init},\r |
| 754 | // {202, Mapper202_Init},\r |
| 755 | // {203, Mapper203_Init},\r |
| 756 | // {204, Mapper204_Init},\r |
| 757 | {"", 205, Mapper205_Init},\r |
| 758 | {"DEIROM", 206, DEIROM_Init},\r |
| 759 | // {207, Mapper207_Init},\r |
| 760 | {"", 208, Mapper208_Init},\r |
| 761 | {"", 209, Mapper209_Init},\r |
| 762 | {"", 210, Mapper210_Init},\r |
| 763 | {"", 211, Mapper211_Init},\r |
| 764 | // {212, Mapper212_Init},\r |
| 765 | // {213, Mapper213_Init},\r |
| 766 | // {214, Mapper214_Init},\r |
| 767 | {"", 215, UNL8237_Init},\r |
| 768 | {"", 216, Mapper216_Init},\r |
| 769 | // {"", 217, Mapper217_Init},\r |
| 770 | // {218, Mapper218_Init},\r |
| 771 | {"UNLA9746", 219, UNLA9746_Init},\r |
| 772 | {"", 220, UNLKS7057_Init}, // DEBUG mapper\r |
| 773 | {"UNLN625092", 221, UNLN625092_Init},\r |
| 774 | {"", 222, Mapper222_Init},\r |
| 775 | // {223, Mapper223_Init},\r |
| 776 | // {224, Mapper224_Init},\r |
| 777 | {"", 225, Mapper225_Init},\r |
| 778 | {"", 226, Mapper226_Init},\r |
| 779 | // {227, Mapper227_Init},\r |
| 780 | // {228, Mapper228_Init},\r |
| 781 | // {229, Mapper229_Init},\r |
| 782 | // {230, Mapper230_Init},\r |
| 783 | // {231, Mapper231_Init},\r |
| 784 | // {232, Mapper232_Init},\r |
| 785 | {"BMC42in1r", 233, BMC42in1r_Init},\r |
| 786 | // {234, Mapper234_Init},\r |
| 787 | {"", 235, Mapper235_Init},\r |
| 788 | // {236, Mapper236_Init},\r |
| 789 | // {237, Mapper237_Init},\r |
| 790 | {"UNL6035052", 238, UNL6035052_Init},\r |
| 791 | // {239, Mapper239_Init},\r |
| 792 | {"", 240, Mapper240_Init},\r |
| 793 | // {241, Mapper241_Init},\r |
| 794 | // {242, Mapper242_Init},\r |
| 795 | {"S74LS374NA", 243, S74LS374NA_Init},\r |
| 796 | // {244, Mapper244_Init},\r |
| 797 | {"", 245, Mapper245_Init},\r |
| 798 | // {246, Mapper246_Init},\r |
| 799 | // {247, Mapper247_Init},\r |
| 800 | // {248, Mapper248_Init},\r |
| 801 | {"", 249, Mapper249_Init},\r |
| 802 | {"", 250, Mapper250_Init},\r |
| 803 | // {251, Mapper251_Init},\r |
| 804 | // {252, Mapper252_Init},\r |
| 805 | {"", 253, Mapper253_Init},\r |
| 806 | {"", 254, Mapper254_Init},\r |
| 807 | // {255, Mapper255_Init},\r |
| 808 | {"", 0, 0}\r |
| 809 | };\r |
| 810 | \r |
| 811 | void cleanup(struct iNES_HEADER *this)\r |
| 812 | {\r |
| 813 | if(!memcmp((char *)(this)+0x7,"DiskDude",8))\r |
| 814 | {\r |
| 815 | memset((char *)(this)+0x7,0,0x9);\r |
| 816 | }\r |
| 817 | \r |
| 818 | if(!memcmp((char *)(this)+0x7,"demiforce",9))\r |
| 819 | {\r |
| 820 | memset((char *)(this)+0x7,0,0x9);\r |
| 821 | }\r |
| 822 | \r |
| 823 | if(!memcmp((char *)(this)+0xA,"Ni03",4))\r |
| 824 | {\r |
| 825 | if(!memcmp((char *)(this)+0x7,"Dis",3))\r |
| 826 | memset((char *)(this)+0x7,0,0x9);\r |
| 827 | else\r |
| 828 | memset((char *)(this)+0xA,0,0x6);\r |
| 829 | }\r |
| 830 | }\r |
| 831 | \r |
| 832 | int iNESLoad(const char *name, int fp, int OverwriteVidMode)\r |
| 833 | {\r |
| 834 | struct md5_context md5;\r |
| 835 | \r |
| 836 | if(FCEU_fread(&head,1,16,fp)!=16)\r |
| 837 | return 0;\r |
| 838 | \r |
| 839 | if(memcmp(&head,"NES\x1a",4))\r |
| 840 | return 0;\r |
| 841 | \r |
| 842 | cleanup(&head);\r |
| 843 | \r |
| 844 | memset(&iNESCart,0,sizeof(iNESCart));\r |
| 845 | \r |
| 846 | MapperNo = (head.ROM_type>>4);\r |
| 847 | MapperNo|=(head.ROM_type2&0xF0);\r |
| 848 | Mirroring = (head.ROM_type&1);\r |
| 849 | \r |
| 850 | \r |
| 851 | // int ROM_size=0;\r |
| 852 | if(!head.ROM_size)\r |
| 853 | {\r |
| 854 | // FCEU_PrintError("No PRG ROM!");\r |
| 855 | // return(0);\r |
| 856 | ROM_size=256;\r |
| 857 | //head.ROM_size++;\r |
| 858 | }\r |
| 859 | else\r |
| 860 | ROM_size=uppow2(head.ROM_size);\r |
| 861 | \r |
| 862 | // ROM_size = head.ROM_size;\r |
| 863 | VROM_size = head.VROM_size;\r |
| 864 | \r |
| 865 | int round = 1;\r |
| 866 | int i;\r |
| 867 | for (i = 0; i != sizeof(not_power2)/sizeof(not_power2[0]); ++i)\r |
| 868 | {\r |
| 869 | //for games not to the power of 2, so we just read enough\r |
| 870 | //prg rom from it, but we have to keep ROM_size to the power of 2\r |
| 871 | //since PRGCartMapping wants ROM_size to be to the power of 2\r |
| 872 | //so instead if not to power of 2, we just use head.ROM_size when\r |
| 873 | //we use FCEU_read\r |
| 874 | if (not_power2[i] == MapperNo)\r |
| 875 | {\r |
| 876 | round = 0;\r |
| 877 | break;\r |
| 878 | }\r |
| 879 | }\r |
| 880 | \r |
| 881 | if(VROM_size)\r |
| 882 | VROM_size=uppow2(VROM_size);\r |
| 883 | \r |
| 884 | \r |
| 885 | if(head.ROM_type&8) Mirroring=2;\r |
| 886 | \r |
| 887 | if((ROM = (uint8 *)FCEU_malloc(ROM_size<<14)) == NULL) return 0;\r |
| 888 | \r |
| 889 | if(VROM_size)\r |
| 890 | {\r |
| 891 | if((VROM = (uint8 *)FCEU_malloc(VROM_size<<13)) == NULL)\r |
| 892 | {\r |
| 893 | free(ROM);\r |
| 894 | ROM = NULL;\r |
| 895 | return 0;\r |
| 896 | }\r |
| 897 | }\r |
| 898 | memset(ROM,0xFF,ROM_size<<14);\r |
| 899 | if(VROM_size) memset(VROM,0xFF,VROM_size<<13);\r |
| 900 | if(head.ROM_type&4) /* Trainer */\r |
| 901 | {\r |
| 902 | trainerpoo=(uint8 *)FCEU_gmalloc(512);\r |
| 903 | FCEU_fread(trainerpoo,512,1,fp);\r |
| 904 | }\r |
| 905 | \r |
| 906 | ResetCartMapping();\r |
| 907 | ResetExState(0,0);\r |
| 908 | \r |
| 909 | SetupCartPRGMapping(0,ROM,ROM_size*0x4000,0);\r |
| 910 | // SetupCartPRGMapping(1,WRAM,8192,1); // ?\r |
| 911 | \r |
| 912 | FCEU_fread(ROM,0x4000,(round) ? ROM_size : head.ROM_size,fp);\r |
| 913 | \r |
| 914 | if(VROM_size)\r |
| 915 | FCEU_fread(VROM,0x2000,head.VROM_size,fp);\r |
| 916 | \r |
| 917 | md5_starts(&md5);\r |
| 918 | md5_update(&md5,ROM,ROM_size<<14);\r |
| 919 | \r |
| 920 | iNESGameCRC32=CalcCRC32(0,ROM,ROM_size<<14);\r |
| 921 | \r |
| 922 | if(VROM_size)\r |
| 923 | {\r |
| 924 | iNESGameCRC32=CalcCRC32(iNESGameCRC32,VROM,VROM_size<<13);\r |
| 925 | md5_update(&md5,VROM,VROM_size<<13);\r |
| 926 | }\r |
| 927 | md5_finish(&md5,iNESCart.MD5);\r |
| 928 | memcpy(&GameInfo->MD5,&iNESCart.MD5,sizeof(iNESCart.MD5));\r |
| 929 | \r |
| 930 | iNESCart.CRC32=iNESGameCRC32;\r |
| 931 | \r |
| 932 | FCEU_printf(" PRG ROM: %3d x 16KiB\n CHR ROM: %3d x 8KiB\n ROM CRC32: 0x%08lx\n",\r |
| 933 | (round) ? ROM_size : head.ROM_size, head.VROM_size,\r |
| 934 | (unsigned long)iNESGameCRC32);\r |
| 935 | \r |
| 936 | {\r |
| 937 | int x;\r |
| 938 | FCEU_printf(" ROM MD5: 0x");\r |
| 939 | for(x=0;x<16;x++)\r |
| 940 | FCEU_printf("%02x",iNESCart.MD5[x]);\r |
| 941 | FCEU_printf("\n");\r |
| 942 | }\r |
| 943 | \r |
| 944 | char* mappername = "Not Listed";\r |
| 945 | int mappertest;\r |
| 946 | \r |
| 947 | for(mappertest=0;mappertest< (sizeof bmap / sizeof bmap[0]) - 1;mappertest++)\r |
| 948 | {\r |
| 949 | if (bmap[mappertest].number == MapperNo) {\r |
| 950 | mappername = bmap[mappertest].name;\r |
| 951 | break;\r |
| 952 | }\r |
| 953 | }\r |
| 954 | \r |
| 955 | FCEU_printf(" Mapper #: %d\n Mapper name: %s\n Mirroring: %s\n",\r |
| 956 | MapperNo, mappername, Mirroring==2?"None (Four-screen)":Mirroring?"Vertical":"Horizontal");\r |
| 957 | \r |
| 958 | FCEU_printf(" Battery-backed: %s\n", (head.ROM_type&2)?"Yes":"No");\r |
| 959 | FCEU_printf(" Trained: %s\n", (head.ROM_type&4)?"Yes":"No");\r |
| 960 | // (head.ROM_type&8) = Mirroring: None(Four-screen)\r |
| 961 | \r |
| 962 | SetInput();\r |
| 963 | CheckHInfo();\r |
| 964 | {\r |
| 965 | int x;\r |
| 966 | uint64 partialmd5=0;\r |
| 967 | \r |
| 968 | for(x=0;x<8;x++)\r |
| 969 | {\r |
| 970 | partialmd5 |= (uint64)iNESCart.MD5[7-x] << (x*8);\r |
| 971 | }\r |
| 972 | \r |
| 973 | FCEU_VSUniCheck(partialmd5, &MapperNo, &Mirroring);\r |
| 974 | }\r |
| 975 | /* Must remain here because above functions might change value of\r |
| 976 | VROM_size and free(VROM).\r |
| 977 | */\r |
| 978 | if(VROM_size)\r |
| 979 | SetupCartCHRMapping(0,VROM,VROM_size*0x2000,0);\r |
| 980 | \r |
| 981 | if(Mirroring==2)\r |
| 982 | SetupCartMirroring(4,1,ExtraNTARAM);\r |
| 983 | else if(Mirroring>=0x10)\r |
| 984 | SetupCartMirroring(2+(Mirroring&1),1,0);\r |
| 985 | else\r |
| 986 | SetupCartMirroring(Mirroring&1,(Mirroring&4)>>2,0);\r |
| 987 | \r |
| 988 | iNESCart.battery=(head.ROM_type&2)?1:0;\r |
| 989 | iNESCart.mirror=Mirroring;\r |
| 990 | \r |
| 991 | //if(MapperNo != 18) {\r |
| 992 | // if(ROM) free(ROM);\r |
| 993 | // if(VROM) free(VROM);\r |
| 994 | // ROM=VROM=0;\r |
| 995 | // return(0);\r |
| 996 | // }\r |
| 997 | \r |
| 998 | \r |
| 999 | GameInfo->mappernum = MapperNo;\r |
| 1000 | MapperInit();\r |
| 1001 | FCEU_LoadGameSave(&iNESCart);\r |
| 1002 | \r |
| 1003 | //strcpy(LoadedRomFName,name); //bbit edited: line added\r |
| 1004 | \r |
| 1005 | // Extract Filename only. Should account for Windows/Unix this way.\r |
| 1006 | if (strrchr(name, '/')) {\r |
| 1007 | name = strrchr(name, '/') + 1;\r |
| 1008 | } else if(strrchr(name, '\\')) {\r |
| 1009 | name = strrchr(name, '\\') + 1;\r |
| 1010 | }\r |
| 1011 | \r |
| 1012 | GameInterface=iNESGI;\r |
| 1013 | FCEU_printf("\n");\r |
| 1014 | \r |
| 1015 | // since apparently the iNES format doesn't store this information,\r |
| 1016 | // guess if the settings should be PAL or NTSC from the ROM name\r |
| 1017 | // TODO: MD5 check against a list of all known PAL games instead?\r |
| 1018 | if(OverwriteVidMode)\r |
| 1019 | {\r |
| 1020 | if(strstr(name,"(E)") || strstr(name,"(e)")\r |
| 1021 | || strstr(name,"(F)") || strstr(name,"(f)")\r |
| 1022 | || strstr(name,"(G)") || strstr(name,"(g)")\r |
| 1023 | || strstr(name,"(I)") || strstr(name,"(i)"))\r |
| 1024 | FCEUI_SetVidSystem(1);\r |
| 1025 | else\r |
| 1026 | FCEUI_SetVidSystem(0);\r |
| 1027 | }\r |
| 1028 | return 1;\r |
| 1029 | }\r |
| 1030 | \r |
| 1031 | \r |
| 1032 | //bbit edited: the whole function below was added\r |
| 1033 | int iNesSave(){\r |
| 1034 | FILE *fp;\r |
| 1035 | char name[2048];\r |
| 1036 | \r |
| 1037 | if(GameInfo->type != GIT_CART)return 0;\r |
| 1038 | if(GameInterface!=iNESGI)return 0;\r |
| 1039 | \r |
| 1040 | //strcpy(name,LoadedRomFName);\r |
| 1041 | if (strcmp(name+strlen(name)-4,".nes") != 0) { //para edit\r |
| 1042 | strcat(name,".nes");\r |
| 1043 | }\r |
| 1044 | \r |
| 1045 | fp = fopen(name,"wb");\r |
| 1046 | \r |
| 1047 | if(fwrite(&head,1,16,fp)!=16)\r |
| 1048 | {\r |
| 1049 | fclose(fp);\r |
| 1050 | return 0;\r |
| 1051 | }\r |
| 1052 | \r |
| 1053 | if(head.ROM_type&4) /* Trainer */\r |
| 1054 | {\r |
| 1055 | fwrite(trainerpoo,512,1,fp);\r |
| 1056 | }\r |
| 1057 | \r |
| 1058 | fwrite(ROM,0x4000,ROM_size,fp);\r |
| 1059 | \r |
| 1060 | if(head.VROM_size)fwrite(VROM,0x2000,head.VROM_size,fp);\r |
| 1061 | fclose(fp);\r |
| 1062 | \r |
| 1063 | return 1;\r |
| 1064 | }\r |
| 1065 | \r |
| 1066 | int iNesSaveAs(char* name)\r |
| 1067 | {\r |
| 1068 | //adelikat: TODO: iNesSave() and this have pretty much the same code, outsource the common code to a single function\r |
| 1069 | FILE *fp;\r |
| 1070 | \r |
| 1071 | if(GameInfo->type != GIT_CART)return 0;\r |
| 1072 | if(GameInterface != iNESGI)return 0;\r |
| 1073 | \r |
| 1074 | fp = fopen(name,"wb");\r |
| 1075 | \r |
| 1076 | if(fwrite(&head,1,16,fp)!=16)\r |
| 1077 | {\r |
| 1078 | fclose(fp);\r |
| 1079 | return 0;\r |
| 1080 | }\r |
| 1081 | \r |
| 1082 | if(head.ROM_type&4) /* Trainer */\r |
| 1083 | {\r |
| 1084 | fwrite(trainerpoo,512,1,fp);\r |
| 1085 | }\r |
| 1086 | \r |
| 1087 | fwrite(ROM,0x4000,ROM_size,fp);\r |
| 1088 | \r |
| 1089 | if(head.VROM_size)fwrite(VROM,0x2000,head.VROM_size,fp);\r |
| 1090 | fclose(fp);\r |
| 1091 | \r |
| 1092 | return 1;\r |
| 1093 | }\r |
| 1094 | \r |
| 1095 | //para edit: added function below\r |
| 1096 | #if 0\r |
| 1097 | char *iNesShortFName() {\r |
| 1098 | char *ret;\r |
| 1099 | \r |
| 1100 | if (!(ret = strrchr(LoadedRomFName,'\\'))) {\r |
| 1101 | if (!(ret = strrchr(LoadedRomFName,'/'))) return 0;\r |
| 1102 | }\r |
| 1103 | return ret+1;\r |
| 1104 | }\r |
| 1105 | #endif\r |
| 1106 | \r |
| 1107 | void VRAM_BANK1(uint32 A, uint8 V)\r |
| 1108 | {\r |
| 1109 | V&=7;\r |
| 1110 | PPUCHRRAM|=(1<<(A>>10));\r |
| 1111 | CHRBankList[(A)>>10]=V;\r |
| 1112 | VPage[(A)>>10]=&CHRRAM[V<<10]-(A);\r |
| 1113 | }\r |
| 1114 | \r |
| 1115 | void VRAM_BANK4(uint32 A, uint32 V)\r |
| 1116 | {\r |
| 1117 | V&=1;\r |
| 1118 | PPUCHRRAM|=(0xF<<(A>>10));\r |
| 1119 | CHRBankList[(A)>>10]=(V<<2);\r |
| 1120 | CHRBankList[((A)>>10)+1]=(V<<2)+1;\r |
| 1121 | CHRBankList[((A)>>10)+2]=(V<<2)+2;\r |
| 1122 | CHRBankList[((A)>>10)+3]=(V<<2)+3;\r |
| 1123 | VPage[(A)>>10]=&CHRRAM[V<<10]-(A);\r |
| 1124 | }\r |
| 1125 | void VROM_BANK1(uint32 A,uint32 V)\r |
| 1126 | {\r |
| 1127 | setchr1(A,V);\r |
| 1128 | CHRBankList[(A)>>10]=V;\r |
| 1129 | }\r |
| 1130 | \r |
| 1131 | void VROM_BANK2(uint32 A,uint32 V)\r |
| 1132 | {\r |
| 1133 | setchr2(A,V);\r |
| 1134 | CHRBankList[(A)>>10]=(V<<1);\r |
| 1135 | CHRBankList[((A)>>10)+1]=(V<<1)+1;\r |
| 1136 | }\r |
| 1137 | \r |
| 1138 | void VROM_BANK4(uint32 A, uint32 V)\r |
| 1139 | {\r |
| 1140 | setchr4(A,V);\r |
| 1141 | CHRBankList[(A)>>10]=(V<<2);\r |
| 1142 | CHRBankList[((A)>>10)+1]=(V<<2)+1;\r |
| 1143 | CHRBankList[((A)>>10)+2]=(V<<2)+2;\r |
| 1144 | CHRBankList[((A)>>10)+3]=(V<<2)+3;\r |
| 1145 | }\r |
| 1146 | \r |
| 1147 | void VROM_BANK8(uint32 V)\r |
| 1148 | {\r |
| 1149 | setchr8(V);\r |
| 1150 | CHRBankList[0]=(V<<3);\r |
| 1151 | CHRBankList[1]=(V<<3)+1;\r |
| 1152 | CHRBankList[2]=(V<<3)+2;\r |
| 1153 | CHRBankList[3]=(V<<3)+3;\r |
| 1154 | CHRBankList[4]=(V<<3)+4;\r |
| 1155 | CHRBankList[5]=(V<<3)+5;\r |
| 1156 | CHRBankList[6]=(V<<3)+6;\r |
| 1157 | CHRBankList[7]=(V<<3)+7;\r |
| 1158 | }\r |
| 1159 | \r |
| 1160 | void ROM_BANK8(uint32 A, uint32 V)\r |
| 1161 | {\r |
| 1162 | setprg8(A,V);\r |
| 1163 | if(A>=0x8000)\r |
| 1164 | PRGBankList[((A-0x8000)>>13)]=V;\r |
| 1165 | }\r |
| 1166 | \r |
| 1167 | void ROM_BANK16(uint32 A, uint32 V)\r |
| 1168 | {\r |
| 1169 | setprg16(A,V);\r |
| 1170 | if(A>=0x8000)\r |
| 1171 | {\r |
| 1172 | PRGBankList[((A-0x8000)>>13)]=V<<1;\r |
| 1173 | PRGBankList[((A-0x8000)>>13)+1]=(V<<1)+1;\r |
| 1174 | }\r |
| 1175 | }\r |
| 1176 | \r |
| 1177 | void ROM_BANK32(uint32 V)\r |
| 1178 | {\r |
| 1179 | setprg32(0x8000,V);\r |
| 1180 | PRGBankList[0]=V<<2;\r |
| 1181 | PRGBankList[1]=(V<<2)+1;\r |
| 1182 | PRGBankList[2]=(V<<2)+2;\r |
| 1183 | PRGBankList[3]=(V<<2)+3;\r |
| 1184 | }\r |
| 1185 | \r |
| 1186 | void onemir(uint8 V)\r |
| 1187 | {\r |
| 1188 | if(Mirroring==2) return;\r |
| 1189 | if(V>1)\r |
| 1190 | V=1;\r |
| 1191 | Mirroring=0x10|V;\r |
| 1192 | setmirror(MI_0+V);\r |
| 1193 | }\r |
| 1194 | \r |
| 1195 | void MIRROR_SET2(uint8 V)\r |
| 1196 | {\r |
| 1197 | if(Mirroring==2) return;\r |
| 1198 | Mirroring=V;\r |
| 1199 | setmirror(V);\r |
| 1200 | }\r |
| 1201 | \r |
| 1202 | void MIRROR_SET(uint8 V)\r |
| 1203 | {\r |
| 1204 | if(Mirroring==2) return;\r |
| 1205 | V^=1;\r |
| 1206 | Mirroring=V;\r |
| 1207 | setmirror(V);\r |
| 1208 | }\r |
| 1209 | \r |
| 1210 | static void NONE_init(void)\r |
| 1211 | {\r |
| 1212 | ROM_BANK16(0x8000,0);\r |
| 1213 | ROM_BANK16(0xC000,~0);\r |
| 1214 | \r |
| 1215 | if(VROM_size)\r |
| 1216 | VROM_BANK8(0);\r |
| 1217 | else\r |
| 1218 | setvram8(CHRRAM);\r |
| 1219 | }\r |
| 1220 | \r |
| 1221 | void (*MapInitTab[256])(void)=\r |
| 1222 | {\r |
| 1223 | 0,\r |
| 1224 | 0,\r |
| 1225 | 0, //Mapper2_init,\r |
| 1226 | 0, //Mapper3_init,\r |
| 1227 | 0,\r |
| 1228 | 0,\r |
| 1229 | Mapper6_init,\r |
| 1230 | 0, //Mapper7_init,\r |
| 1231 | 0, //Mapper8_init,\r |
| 1232 | Mapper9_init,\r |
| 1233 | Mapper10_init,\r |
| 1234 | 0, //Mapper11_init,\r |
| 1235 | 0, \r |
| 1236 | 0, //Mapper13_init,\r |
| 1237 | 0,\r |
| 1238 | 0, //Mapper15_init,\r |
| 1239 | 0, //Mapper16_init,\r |
| 1240 | 0, //Mapper17_init,\r |
| 1241 | 0, //Mapper18_init,\r |
| 1242 | 0,\r |
| 1243 | 0,\r |
| 1244 | Mapper21_init,\r |
| 1245 | Mapper22_init,\r |
| 1246 | 0, //Mapper23_init,\r |
| 1247 | Mapper24_init,\r |
| 1248 | Mapper25_init,\r |
| 1249 | Mapper26_init,\r |
| 1250 | Mapper27_init,\r |
| 1251 | 0,\r |
| 1252 | 0,\r |
| 1253 | 0,\r |
| 1254 | 0,\r |
| 1255 | Mapper32_init,\r |
| 1256 | Mapper33_init,\r |
| 1257 | 0, //Mapper34_init,\r |
| 1258 | 0,\r |
| 1259 | 0,\r |
| 1260 | 0,\r |
| 1261 | 0,\r |
| 1262 | 0,\r |
| 1263 | Mapper40_init,\r |
| 1264 | Mapper41_init,\r |
| 1265 | Mapper42_init,\r |
| 1266 | 0, //Mapper43_init,\r |
| 1267 | 0,\r |
| 1268 | 0,\r |
| 1269 | Mapper46_init,\r |
| 1270 | 0,\r |
| 1271 | Mapper48_init,\r |
| 1272 | 0,\r |
| 1273 | Mapper50_init,\r |
| 1274 | Mapper51_init,\r |
| 1275 | 0,\r |
| 1276 | 0,\r |
| 1277 | 0,\r |
| 1278 | 0,\r |
| 1279 | 0,\r |
| 1280 | 0, //Mapper57_init,\r |
| 1281 | 0, //Mapper58_init,\r |
| 1282 | Mapper59_init,\r |
| 1283 | 0, //Mapper60_init,\r |
| 1284 | Mapper61_init,\r |
| 1285 | Mapper62_init,\r |
| 1286 | 0,\r |
| 1287 | Mapper64_init,\r |
| 1288 | Mapper65_init,\r |
| 1289 | 0, //Mapper66_init,\r |
| 1290 | Mapper67_init,\r |
| 1291 | 0, //Mapper68_init,\r |
| 1292 | Mapper69_init,\r |
| 1293 | 0, //Mapper70_init,\r |
| 1294 | Mapper71_init,\r |
| 1295 | Mapper72_init,\r |
| 1296 | Mapper73_init,\r |
| 1297 | 0,\r |
| 1298 | Mapper75_init,\r |
| 1299 | Mapper76_init,\r |
| 1300 | Mapper77_init,\r |
| 1301 | 0, //Mapper78_init,\r |
| 1302 | Mapper79_init,\r |
| 1303 | Mapper80_init,\r |
| 1304 | 0,\r |
| 1305 | 0, //Mapper82_init,\r |
| 1306 | 0, //Mapper83_init,\r |
| 1307 | 0,\r |
| 1308 | Mapper85_init,\r |
| 1309 | 0, //Mapper86_init,\r |
| 1310 | 0, //Mapper87_init,\r |
| 1311 | 0, //Mapper88_init,\r |
| 1312 | 0, //Mapper89_init,\r |
| 1313 | 0,\r |
| 1314 | 0, //Mapper91_init,\r |
| 1315 | 0, //Mapper92_init,\r |
| 1316 | 0, //Mapper93_init,\r |
| 1317 | 0, //Mapper94_init,\r |
| 1318 | 0,\r |
| 1319 | 0, //Mapper96_init,\r |
| 1320 | 0, //Mapper97_init,\r |
| 1321 | 0,\r |
| 1322 | 0, //Mapper99_init,\r |
| 1323 | 0,\r |
| 1324 | 0,\r |
| 1325 | 0,\r |
| 1326 | 0,\r |
| 1327 | 0,\r |
| 1328 | 0,\r |
| 1329 | 0,\r |
| 1330 | 0, //Mapper107_init,\r |
| 1331 | 0,\r |
| 1332 | 0,\r |
| 1333 | 0,\r |
| 1334 | 0,\r |
| 1335 | 0,\r |
| 1336 | 0, //Mapper113_init,\r |
| 1337 | 0,\r |
| 1338 | 0,\r |
| 1339 | 0, //Mapper116_init,\r |
| 1340 | 0, //Mapper117_init,\r |
| 1341 | 0,\r |
| 1342 | 0,\r |
| 1343 | 0,\r |
| 1344 | 0,\r |
| 1345 | 0,\r |
| 1346 | 0,\r |
| 1347 | 0,\r |
| 1348 | 0,\r |
| 1349 | 0,\r |
| 1350 | 0,\r |
| 1351 | 0,\r |
| 1352 | 0,\r |
| 1353 | 0,\r |
| 1354 | 0,\r |
| 1355 | 0,\r |
| 1356 | 0,\r |
| 1357 | 0,\r |
| 1358 | 0,\r |
| 1359 | 0,\r |
| 1360 | 0,\r |
| 1361 | 0,\r |
| 1362 | 0,\r |
| 1363 | 0, //Mapper140_init,\r |
| 1364 | 0,\r |
| 1365 | 0,\r |
| 1366 | 0,\r |
| 1367 | 0, //Mapper144_init,\r |
| 1368 | 0,\r |
| 1369 | 0,\r |
| 1370 | 0,\r |
| 1371 | 0,\r |
| 1372 | 0,\r |
| 1373 | 0,\r |
| 1374 | 0, //Mapper151_init,\r |
| 1375 | 0, //Mapper152_init,\r |
| 1376 | 0, //Mapper153_init,\r |
| 1377 | 0, //Mapper154_init,\r |
| 1378 | 0,\r |
| 1379 | 0, //Mapper156_init,\r |
| 1380 | 0, //Mapper157_init,\r |
| 1381 | 0, //Mapper158_init, removed\r |
| 1382 | 0,\r |
| 1383 | 0,\r |
| 1384 | 0,\r |
| 1385 | 0,\r |
| 1386 | 0,\r |
| 1387 | 0,\r |
| 1388 | 0,\r |
| 1389 | Mapper166_init,\r |
| 1390 | Mapper167_init,\r |
| 1391 | 0,\r |
| 1392 | 0,\r |
| 1393 | 0,\r |
| 1394 | 0,\r |
| 1395 | 0,\r |
| 1396 | 0,\r |
| 1397 | 0,\r |
| 1398 | 0,\r |
| 1399 | 0,\r |
| 1400 | 0,\r |
| 1401 | 0,\r |
| 1402 | 0,\r |
| 1403 | 0, //Mapper180_init,\r |
| 1404 | 0,\r |
| 1405 | 0,\r |
| 1406 | 0,\r |
| 1407 | 0, //Mapper184_init,\r |
| 1408 | 0, //Mapper185_init,\r |
| 1409 | 0,\r |
| 1410 | 0,\r |
| 1411 | 0,\r |
| 1412 | 0, //Mapper189_init,\r |
| 1413 | 0,\r |
| 1414 | 0, //Mapper191_init,\r |
| 1415 | 0,\r |
| 1416 | 0, //Mapper193_init,\r |
| 1417 | 0,\r |
| 1418 | 0,\r |
| 1419 | 0,\r |
| 1420 | 0,\r |
| 1421 | 0,\r |
| 1422 | 0,\r |
| 1423 | 0, //Mapper200_init,\r |
| 1424 | Mapper201_init,\r |
| 1425 | Mapper202_init,\r |
| 1426 | Mapper203_init,\r |
| 1427 | Mapper204_init,\r |
| 1428 | 0,\r |
| 1429 | 0,\r |
| 1430 | Mapper207_init,\r |
| 1431 | 0,\r |
| 1432 | 0,\r |
| 1433 | 0,\r |
| 1434 | 0, //Mapper211_init,\r |
| 1435 | Mapper212_init,\r |
| 1436 | Mapper213_init,\r |
| 1437 | Mapper214_init,\r |
| 1438 | 0,\r |
| 1439 | 0,\r |
| 1440 | 0,\r |
| 1441 | 0,\r |
| 1442 | 0,\r |
| 1443 | 0,\r |
| 1444 | 0,\r |
| 1445 | 0,\r |
| 1446 | 0,\r |
| 1447 | 0,\r |
| 1448 | 0, //Mapper225_init,\r |
| 1449 | 0, //Mapper226_init,\r |
| 1450 | Mapper227_init,\r |
| 1451 | Mapper228_init,\r |
| 1452 | Mapper229_init,\r |
| 1453 | Mapper230_init,\r |
| 1454 | Mapper231_init,\r |
| 1455 | Mapper232_init,\r |
| 1456 | 0,\r |
| 1457 | Mapper234_init,\r |
| 1458 | 0, //Mapper235_init,\r |
| 1459 | 0,\r |
| 1460 | 0,\r |
| 1461 | 0,\r |
| 1462 | 0,\r |
| 1463 | 0, //Mapper240_init,\r |
| 1464 | Mapper241_init,\r |
| 1465 | Mapper242_init,\r |
| 1466 | 0,\r |
| 1467 | Mapper244_init,\r |
| 1468 | 0,\r |
| 1469 | Mapper246_init,\r |
| 1470 | 0,\r |
| 1471 | 0,\r |
| 1472 | 0,\r |
| 1473 | 0,\r |
| 1474 | 0,\r |
| 1475 | 0,\r |
| 1476 | 0,\r |
| 1477 | 0,\r |
| 1478 | Mapper255_init\r |
| 1479 | };\r |
| 1480 | \r |
| 1481 | static DECLFW(BWRAM)\r |
| 1482 | {\r |
| 1483 | WRAM[A-0x6000]=V;\r |
| 1484 | }\r |
| 1485 | \r |
| 1486 | static DECLFR(AWRAM)\r |
| 1487 | {\r |
| 1488 | return WRAM[A-0x6000];\r |
| 1489 | }\r |
| 1490 | \r |
| 1491 | \r |
| 1492 | void (*MapStateRestore)(int version);\r |
| 1493 | void iNESStateRestore(int version)\r |
| 1494 | {\r |
| 1495 | int x;\r |
| 1496 | \r |
| 1497 | if(!MapperNo) return;\r |
| 1498 | \r |
| 1499 | for(x=0;x<4;x++)\r |
| 1500 | setprg8(0x8000+x*8192,PRGBankList[x]);\r |
| 1501 | \r |
| 1502 | if(VROM_size)\r |
| 1503 | for(x=0;x<8;x++)\r |
| 1504 | setchr1(0x400*x,CHRBankList[x]);\r |
| 1505 | \r |
| 1506 | if(0) switch(Mirroring)\r |
| 1507 | {\r |
| 1508 | case 0:setmirror(MI_H);break;\r |
| 1509 | case 1:setmirror(MI_V);break;\r |
| 1510 | case 0x12:\r |
| 1511 | case 0x10:setmirror(MI_0);break;\r |
| 1512 | case 0x13:\r |
| 1513 | case 0x11:setmirror(MI_1);break;\r |
| 1514 | }\r |
| 1515 | if(MapStateRestore) MapStateRestore(version);\r |
| 1516 | }\r |
| 1517 | \r |
| 1518 | static void iNESPower(void)\r |
| 1519 | {\r |
| 1520 | int x;\r |
| 1521 | int type=MapperNo;\r |
| 1522 | \r |
| 1523 | SetReadHandler(0x8000,0xFFFF,CartBR);\r |
| 1524 | GameStateRestore=iNESStateRestore;\r |
| 1525 | MapClose=0;\r |
| 1526 | MapperReset=0;\r |
| 1527 | MapStateRestore=0;\r |
| 1528 | \r |
| 1529 | setprg8r(1,0x6000,0);\r |
| 1530 | \r |
| 1531 | SetReadHandler(0x6000,0x7FFF,AWRAM);\r |
| 1532 | #ifdef ASM_6502\r |
| 1533 | // asm code needs pages to be set again..\r |
| 1534 | Page[12]=Page[13]=Page[14]=Page[15]=WRAM-0x6000;\r |
| 1535 | #endif\r |
| 1536 | SetWriteHandler(0x6000,0x7FFF,BWRAM);\r |
| 1537 | FCEU_CheatAddRAM(8,0x6000,WRAM);\r |
| 1538 | \r |
| 1539 | /* This statement represents atrocious code. I need to rewrite\r |
| 1540 | all of the iNES mapper code... */\r |
| 1541 | IRQCount=IRQLatch=IRQa=0;\r |
| 1542 | if(head.ROM_type&2)\r |
| 1543 | memset(GameMemBlock+8192,0,GAME_MEM_BLOCK_SIZE-8192);\r |
| 1544 | else\r |
| 1545 | memset(GameMemBlock,0,GAME_MEM_BLOCK_SIZE);\r |
| 1546 | \r |
| 1547 | NONE_init();\r |
| 1548 | ResetExState(0,0);\r |
| 1549 | \r |
| 1550 | if(GameInfo->type == GIT_VSUNI)\r |
| 1551 | AddExState(FCEUVSUNI_STATEINFO, ~0, 0, 0);\r |
| 1552 | \r |
| 1553 | AddExState(WRAM, 8192, 0, "WRAM");\r |
| 1554 | if(type==19 || type==6 || type==69 || type==85 || type==96)\r |
| 1555 | AddExState(MapperExRAM, 32768, 0, "MEXR");\r |
| 1556 | if((!VROM_size || type==6 || type==19) && (type!=13 && type!=96))\r |
| 1557 | AddExState(CHRRAM, 8192, 0, "CHRR");\r |
| 1558 | if(head.ROM_type&8)\r |
| 1559 | AddExState(ExtraNTARAM, 2048, 0, "EXNR");\r |
| 1560 | \r |
| 1561 | /* Exclude some mappers whose emulation code handle save state stuff\r |
| 1562 | themselves. */\r |
| 1563 | if(type && type!=13 && type!=96)\r |
| 1564 | {\r |
| 1565 | AddExState(mapbyte1, 32, 0, "MPBY");\r |
| 1566 | AddExState(&Mirroring, 1, 0, "MIRR");\r |
| 1567 | AddExState(&IRQCount, 4, 1, "IRQC");\r |
| 1568 | AddExState(&IRQLatch, 4, 1, "IQL1");\r |
| 1569 | AddExState(&IRQa, 1, 0, "IRQA");\r |
| 1570 | AddExState(PRGBankList, 4, 0, "PBL");\r |
| 1571 | for(x=0;x<8;x++)\r |
| 1572 | {\r |
| 1573 | char tak[8];\r |
| 1574 | sprintf(tak,"CBL%d",x);\r |
| 1575 | AddExState(&CHRBankList[x], 2, 1,tak);\r |
| 1576 | }\r |
| 1577 | }\r |
| 1578 | \r |
| 1579 | if(MapInitTab[type]) MapInitTab[type]();\r |
| 1580 | else if(type)\r |
| 1581 | {\r |
| 1582 | FCEU_PrintError("iNES mapper #%d is not supported at all.",type);\r |
| 1583 | }\r |
| 1584 | }\r |
| 1585 | \r |
| 1586 | static int NewiNES_Init(int num)\r |
| 1587 | {\r |
| 1588 | BMAPPINGLocal *tmp=bmap;\r |
| 1589 | \r |
| 1590 | CHRRAMSize = -1;\r |
| 1591 | \r |
| 1592 | if(GameInfo->type == GIT_VSUNI)\r |
| 1593 | AddExState(FCEUVSUNI_STATEINFO, ~0, 0, 0);\r |
| 1594 | \r |
| 1595 | while(tmp->init)\r |
| 1596 | {\r |
| 1597 | if(num==tmp->number)\r |
| 1598 | {\r |
| 1599 | UNIFchrrama=0; // need here for compatibility with UNIF mapper code\r |
| 1600 | if(!VROM_size)\r |
| 1601 | {\r |
| 1602 | if(num==13)\r |
| 1603 | {\r |
| 1604 | CHRRAMSize=16384;\r |
| 1605 | }\r |
| 1606 | else\r |
| 1607 | {\r |
| 1608 | CHRRAMSize=8192;\r |
| 1609 | }\r |
| 1610 | if((VROM = (uint8 *)FCEU_malloc(CHRRAMSize)) == NULL) return 0;\r |
| 1611 | FCEU_MemoryRand(VROM,CHRRAMSize);\r |
| 1612 | \r |
| 1613 | UNIFchrrama=VROM;\r |
| 1614 | SetupCartCHRMapping(0,VROM,CHRRAMSize,1);\r |
| 1615 | AddExState(VROM,CHRRAMSize, 0, "CHRR");\r |
| 1616 | }\r |
| 1617 | if(head.ROM_type&8)\r |
| 1618 | AddExState(ExtraNTARAM, 2048, 0, "EXNR");\r |
| 1619 | tmp->init(&iNESCart);\r |
| 1620 | return 1;\r |
| 1621 | }\r |
| 1622 | tmp++;\r |
| 1623 | }\r |
| 1624 | return 0;\r |
| 1625 | }\r |
| 1626 | \r |
| 1627 | // vim:ts=4\r |