1 /* FCE Ultra - NES/Famicom Emulator
\r
3 * Copyright notice for this file:
\r
4 * Copyright (C) 1998 BERO
\r
5 * Copyright (C) 2002 Xodnizel
\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
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
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
37 #include "general.h"
\r
46 extern SFORMAT FCEUVSUNI_STATEINFO[];
\r
48 //mbg merge 6/29/06 - these need to be global
\r
49 uint8 *trainerpoo=0;
\r
52 struct iNES_HEADER head;
\r
56 static CartInfo iNESCart;
\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
65 //char LoadedRomFName[2048]; //mbg merge 7/17/06 added
\r
67 static int CHRRAMSize = -1;
\r
68 static void iNESPower(void);
\r
69 static int NewiNES_Init(int num);
\r
71 void (*MapClose)(void);
\r
72 void (*MapperReset)(void);
\r
74 static int MapperNo=0;
\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
81 static DECLFR(TrainerRead)
\r
83 return(trainerpoo[A&0x1FF]);
\r
86 static void iNES_ExecPower()
\r
88 if(CHRRAMSize != -1)
\r
89 FCEU_MemoryRand(VROM,CHRRAMSize);
\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
105 SetReadHandler(0x7000,0x71FF,TrainerRead);
\r
112 static void iNESGI(int h, void *param)
\r
117 //FCEU_ClearGameSave(&iNESCart);
\r
132 FCEU_SaveGameSave(&iNESCart);
\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
141 case GI_INFOSTRING:
\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
153 uint32 iNESGameCRC32=0;
\r
167 static void SetInput(void)
\r
169 static struct INPSEL moo[]=
\r
171 {0x3a1694f9,SI_GAMEPAD,SI_GAMEPAD,SIFC_4PLAYER}, // Nekketsu Kakutou Densetsu
\r
173 {0xc3c0811d,SI_GAMEPAD,SI_GAMEPAD,SIFC_OEKAKIDS}, // The two "Oeka Kids" games
\r
174 {0x9d048ea4,SI_GAMEPAD,SI_GAMEPAD,SIFC_OEKAKIDS}, //
\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
182 {0x47232739,SI_GAMEPAD,SI_GAMEPAD,SIFC_TOPRIDER}, // Top Rider
\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
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
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
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
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
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
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
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
249 while(moo[x].input1>=0 || moo[x].input2>=0 || moo[x].inputfc>=0)
\r
251 if(moo[x].crc32==iNESGameCRC32)
\r
253 GameInfo->input[0]=moo[x].input1;
\r
254 GameInfo->input[1]=moo[x].input2;
\r
255 GameInfo->inputfc=moo[x].inputfc;
\r
262 #define INESB_INCOMPLETE 1
\r
263 #define INESB_CORRUPT 2
\r
264 #define INESB_HACKED 4
\r
273 static struct BADINF BadROMImages[]=
\r
275 #include "ines-bad.h"
\r
278 void CheckBad(uint64 md5partial)
\r
283 //printf("0x%llx\n",md5partial);
\r
284 while(BadROMImages[x].name)
\r
286 if(BadROMImages[x].md5partial == md5partial)
\r
288 FCEU_PrintError("The copy game you have loaded, \"%s\", is bad, and will not work properly in FCEUX.", BadROMImages[x].name);
\r
301 const char* params;
\r
306 if(NewiNES_Init(MapperNo))
\r
312 iNESCart.Power=iNESPower;
\r
313 if(head.ROM_type&2)
\r
315 iNESCart.SaveGame[0]=WRAM;
\r
316 iNESCart.SaveGameLen[0]=8192;
\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
333 const TMasterRomInfo* MasterRomInfo;
\r
334 TMasterRomInfoParams MasterRomInfoParams;
\r
337 static void CheckHInfo(void)
\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
343 Lower 64 bits of the MD5 hash.
\r
346 static uint64 savie[]=
\r
348 0x498c10dc463cfe95LL, /* Battle Fleet */
\r
349 0x6917ffcaca2d8466LL, /* Famista '90 */
\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
356 0x2ee3417ba8b69706LL, /* Hydlide 3*/
\r
358 0xebbce5a54cf3ecc0LL, /* Justbreed */
\r
360 0x6a858da551ba239eLL, /* Kaijuu Monogatari */
\r
361 0xa40666740b7d22feLL, /* Mindseeker */
\r
363 0x77b811b2760104b9LL, /* Mouryou Senki Madara */
\r
365 0x11b69122efe86e8cLL, /* RPG Jinsei Game */
\r
367 0xa70b495314f4d075LL, /* Ys 3 */
\r
370 0xc04361e499748382LL, /* AD&D Heroes of the Lance */
\r
371 0xb72ee2337ced5792LL, /* AD&D Hillsfar */
\r
372 0x2b7103b7a27bd72fLL, /* AD&D Pool of Radiance */
\r
374 0x854d7947a3177f57LL, /* Crystalis */
\r
376 0xb0bcc02c843c1b79LL, /* DW */
\r
377 0x4a1f5336b86851b6LL, /* DW */
\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
386 0x94b9484862a26cbaLL, /* Legend of Zelda */
\r
387 0x04a31647de80fdabLL, /* "" */
\r
389 0x9aa1dc16c05e7de5LL, /* Startropics */
\r
390 0x1b084107d0878bd0LL, /* Startropics 2*/
\r
392 0x836c0ff4f3e06e45LL, /* Zelda 2 */
\r
394 0x82000965f04a71bbLL, /* Mirai Shinwa Jarvas */
\r
396 0 /* Abandon all hope if the game has 0 in the lower 64-bits of its MD5 hash */
\r
399 static struct CHINF moo[]=
\r
401 #include "ines-correct.h"
\r
405 uint64 partialmd5=0;
\r
409 partialmd5 |= (uint64)iNESCart.MD5[15-x] << (x*8);
\r
410 //printf("%16llx\n",partialmd5);
\r
412 CheckBad(partialmd5);
\r
415 MasterRomInfo = NULL;
\r
416 MasterRomInfoParams = TMasterRomInfoParams();
\r
417 for(int i=0;i<ARRAY_SIZE(sMasterRomInfo);i++)
\r
419 const TMasterRomInfo& info = sMasterRomInfo[i];
\r
420 if(info.md5lower != partialmd5)
\r
423 MasterRomInfo = &info;
\r
424 if(!info.params) break;
\r
426 std::vector<std::string> toks = tokenize_str(info.params,",");
\r
427 for(int j=0;j<(int)toks.size();j++)
\r
429 std::vector<std::string> parts = tokenize_str(toks[j],"=");
\r
430 MasterRomInfoParams[parts[0]] = parts[1];
\r
440 if(moo[x].crc32==iNESGameCRC32)
\r
442 if(moo[x].mapper>=0)
\r
444 if(moo[x].mapper&0x800 && VROM_size)
\r
451 if(MapperNo!=(moo[x].mapper&0xFF))
\r
454 MapperNo=moo[x].mapper&0xFF;
\r
457 if(moo[x].mirror>=0)
\r
459 if(moo[x].mirror==8)
\r
461 if(Mirroring==2) /* Anything but hard-wired(four screen). */
\r
467 else if(Mirroring!=moo[x].mirror)
\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
475 Mirroring=moo[x].mirror;
\r
481 } while(moo[x].mirror>=0 || moo[x].mapper>=0);
\r
484 while(savie[x] != 0)
\r
486 if(savie[x] == partialmd5)
\r
488 if(!(head.ROM_type&2))
\r
497 /* Games that use these iNES mappers tend to have the four-screen bit set
\r
498 when it should not be.
\r
500 if((MapperNo==118 || MapperNo==24 || MapperNo==26) && (Mirroring==2))
\r
506 /* Four-screen mirroring implicitly set. */
\r
513 strcpy(gigastr,"The iNES header contains incorrect information. For now, the information will be corrected in RAM. ");
\r
515 sprintf(gigastr+strlen(gigastr),"The mapper number should be set to %d. ",MapperNo);
\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
522 strcat(gigastr,"The battery-backed bit should be set. ");
\r
524 strcat(gigastr,"This game should not have any CHR ROM. ");
\r
525 strcat(gigastr,"\n");
\r
526 FCEU_printf("%s",gigastr);
\r
532 void (*init)(CartInfo *);
\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
541 static int not_power2[] =
\r
548 void (*init)(CartInfo *);
\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
811 void cleanup(struct iNES_HEADER *this)
\r
813 if(!memcmp((char *)(this)+0x7,"DiskDude",8))
\r
815 memset((char *)(this)+0x7,0,0x9);
\r
818 if(!memcmp((char *)(this)+0x7,"demiforce",9))
\r
820 memset((char *)(this)+0x7,0,0x9);
\r
823 if(!memcmp((char *)(this)+0xA,"Ni03",4))
\r
825 if(!memcmp((char *)(this)+0x7,"Dis",3))
\r
826 memset((char *)(this)+0x7,0,0x9);
\r
828 memset((char *)(this)+0xA,0,0x6);
\r
832 int iNESLoad(const char *name, int fp, int OverwriteVidMode)
\r
834 struct md5_context md5;
\r
836 if(FCEU_fread(&head,1,16,fp)!=16)
\r
839 if(memcmp(&head,"NES\x1a",4))
\r
844 memset(&iNESCart,0,sizeof(iNESCart));
\r
846 MapperNo = (head.ROM_type>>4);
\r
847 MapperNo|=(head.ROM_type2&0xF0);
\r
848 Mirroring = (head.ROM_type&1);
\r
854 // FCEU_PrintError("No PRG ROM!");
\r
860 ROM_size=uppow2(head.ROM_size);
\r
862 // ROM_size = head.ROM_size;
\r
863 VROM_size = head.VROM_size;
\r
867 for (i = 0; i != sizeof(not_power2)/sizeof(not_power2[0]); ++i)
\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
874 if (not_power2[i] == MapperNo)
\r
882 VROM_size=uppow2(VROM_size);
\r
885 if(head.ROM_type&8) Mirroring=2;
\r
887 if((ROM = (uint8 *)FCEU_malloc(ROM_size<<14)) == NULL) return 0;
\r
891 if((VROM = (uint8 *)FCEU_malloc(VROM_size<<13)) == NULL)
\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
902 trainerpoo=(uint8 *)FCEU_gmalloc(512);
\r
903 FCEU_fread(trainerpoo,512,1,fp);
\r
906 ResetCartMapping();
\r
909 SetupCartPRGMapping(0,ROM,ROM_size*0x4000,0);
\r
910 // SetupCartPRGMapping(1,WRAM,8192,1); // ?
\r
912 FCEU_fread(ROM,0x4000,(round) ? ROM_size : head.ROM_size,fp);
\r
915 FCEU_fread(VROM,0x2000,head.VROM_size,fp);
\r
918 md5_update(&md5,ROM,ROM_size<<14);
\r
920 iNESGameCRC32=CalcCRC32(0,ROM,ROM_size<<14);
\r
924 iNESGameCRC32=CalcCRC32(iNESGameCRC32,VROM,VROM_size<<13);
\r
925 md5_update(&md5,VROM,VROM_size<<13);
\r
927 md5_finish(&md5,iNESCart.MD5);
\r
928 memcpy(&GameInfo->MD5,&iNESCart.MD5,sizeof(iNESCart.MD5));
\r
930 iNESCart.CRC32=iNESGameCRC32;
\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
938 FCEU_printf(" ROM MD5: 0x");
\r
940 FCEU_printf("%02x",iNESCart.MD5[x]);
\r
944 char* mappername = "Not Listed";
\r
947 for(mappertest=0;mappertest< (sizeof bmap / sizeof bmap[0]) - 1;mappertest++)
\r
949 if (bmap[mappertest].number == MapperNo) {
\r
950 mappername = bmap[mappertest].name;
\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
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
966 uint64 partialmd5=0;
\r
970 partialmd5 |= (uint64)iNESCart.MD5[7-x] << (x*8);
\r
973 FCEU_VSUniCheck(partialmd5, &MapperNo, &Mirroring);
\r
975 /* Must remain here because above functions might change value of
\r
976 VROM_size and free(VROM).
\r
979 SetupCartCHRMapping(0,VROM,VROM_size*0x2000,0);
\r
982 SetupCartMirroring(4,1,ExtraNTARAM);
\r
983 else if(Mirroring>=0x10)
\r
984 SetupCartMirroring(2+(Mirroring&1),1,0);
\r
986 SetupCartMirroring(Mirroring&1,(Mirroring&4)>>2,0);
\r
988 iNESCart.battery=(head.ROM_type&2)?1:0;
\r
989 iNESCart.mirror=Mirroring;
\r
991 //if(MapperNo != 18) {
\r
992 // if(ROM) free(ROM);
\r
993 // if(VROM) free(VROM);
\r
999 GameInfo->mappernum = MapperNo;
\r
1001 FCEU_LoadGameSave(&iNESCart);
\r
1003 //strcpy(LoadedRomFName,name); //bbit edited: line added
\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
1012 GameInterface=iNESGI;
\r
1013 FCEU_printf("\n");
\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
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
1026 FCEUI_SetVidSystem(0);
\r
1032 //bbit edited: the whole function below was added
\r
1037 if(GameInfo->type != GIT_CART)return 0;
\r
1038 if(GameInterface!=iNESGI)return 0;
\r
1040 //strcpy(name,LoadedRomFName);
\r
1041 if (strcmp(name+strlen(name)-4,".nes") != 0) { //para edit
\r
1042 strcat(name,".nes");
\r
1045 fp = fopen(name,"wb");
\r
1047 if(fwrite(&head,1,16,fp)!=16)
\r
1053 if(head.ROM_type&4) /* Trainer */
\r
1055 fwrite(trainerpoo,512,1,fp);
\r
1058 fwrite(ROM,0x4000,ROM_size,fp);
\r
1060 if(head.VROM_size)fwrite(VROM,0x2000,head.VROM_size,fp);
\r
1066 int iNesSaveAs(char* name)
\r
1068 //adelikat: TODO: iNesSave() and this have pretty much the same code, outsource the common code to a single function
\r
1071 if(GameInfo->type != GIT_CART)return 0;
\r
1072 if(GameInterface != iNESGI)return 0;
\r
1074 fp = fopen(name,"wb");
\r
1076 if(fwrite(&head,1,16,fp)!=16)
\r
1082 if(head.ROM_type&4) /* Trainer */
\r
1084 fwrite(trainerpoo,512,1,fp);
\r
1087 fwrite(ROM,0x4000,ROM_size,fp);
\r
1089 if(head.VROM_size)fwrite(VROM,0x2000,head.VROM_size,fp);
\r
1095 //para edit: added function below
\r
1097 char *iNesShortFName() {
\r
1100 if (!(ret = strrchr(LoadedRomFName,'\\'))) {
\r
1101 if (!(ret = strrchr(LoadedRomFName,'/'))) return 0;
\r
1107 void VRAM_BANK1(uint32 A, uint8 V)
\r
1110 PPUCHRRAM|=(1<<(A>>10));
\r
1111 CHRBankList[(A)>>10]=V;
\r
1112 VPage[(A)>>10]=&CHRRAM[V<<10]-(A);
\r
1115 void VRAM_BANK4(uint32 A, uint32 V)
\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
1125 void VROM_BANK1(uint32 A,uint32 V)
\r
1128 CHRBankList[(A)>>10]=V;
\r
1131 void VROM_BANK2(uint32 A,uint32 V)
\r
1134 CHRBankList[(A)>>10]=(V<<1);
\r
1135 CHRBankList[((A)>>10)+1]=(V<<1)+1;
\r
1138 void VROM_BANK4(uint32 A, uint32 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
1147 void VROM_BANK8(uint32 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
1160 void ROM_BANK8(uint32 A, uint32 V)
\r
1164 PRGBankList[((A-0x8000)>>13)]=V;
\r
1167 void ROM_BANK16(uint32 A, uint32 V)
\r
1172 PRGBankList[((A-0x8000)>>13)]=V<<1;
\r
1173 PRGBankList[((A-0x8000)>>13)+1]=(V<<1)+1;
\r
1177 void ROM_BANK32(uint32 V)
\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
1186 void onemir(uint8 V)
\r
1188 if(Mirroring==2) return;
\r
1192 setmirror(MI_0+V);
\r
1195 void MIRROR_SET2(uint8 V)
\r
1197 if(Mirroring==2) return;
\r
1202 void MIRROR_SET(uint8 V)
\r
1204 if(Mirroring==2) return;
\r
1210 static void NONE_init(void)
\r
1212 ROM_BANK16(0x8000,0);
\r
1213 ROM_BANK16(0xC000,~0);
\r
1221 void (*MapInitTab[256])(void)=
\r
1225 0, //Mapper2_init,
\r
1226 0, //Mapper3_init,
\r
1230 0, //Mapper7_init,
\r
1231 0, //Mapper8_init,
\r
1234 0, //Mapper11_init,
\r
1236 0, //Mapper13_init,
\r
1238 0, //Mapper15_init,
\r
1239 0, //Mapper16_init,
\r
1240 0, //Mapper17_init,
\r
1241 0, //Mapper18_init,
\r
1246 0, //Mapper23_init,
\r
1257 0, //Mapper34_init,
\r
1266 0, //Mapper43_init,
\r
1280 0, //Mapper57_init,
\r
1281 0, //Mapper58_init,
\r
1283 0, //Mapper60_init,
\r
1289 0, //Mapper66_init,
\r
1291 0, //Mapper68_init,
\r
1293 0, //Mapper70_init,
\r
1301 0, //Mapper78_init,
\r
1305 0, //Mapper82_init,
\r
1306 0, //Mapper83_init,
\r
1309 0, //Mapper86_init,
\r
1310 0, //Mapper87_init,
\r
1311 0, //Mapper88_init,
\r
1312 0, //Mapper89_init,
\r
1314 0, //Mapper91_init,
\r
1315 0, //Mapper92_init,
\r
1316 0, //Mapper93_init,
\r
1317 0, //Mapper94_init,
\r
1319 0, //Mapper96_init,
\r
1320 0, //Mapper97_init,
\r
1322 0, //Mapper99_init,
\r
1330 0, //Mapper107_init,
\r
1336 0, //Mapper113_init,
\r
1339 0, //Mapper116_init,
\r
1340 0, //Mapper117_init,
\r
1363 0, //Mapper140_init,
\r
1367 0, //Mapper144_init,
\r
1374 0, //Mapper151_init,
\r
1375 0, //Mapper152_init,
\r
1376 0, //Mapper153_init,
\r
1377 0, //Mapper154_init,
\r
1379 0, //Mapper156_init,
\r
1380 0, //Mapper157_init,
\r
1381 0, //Mapper158_init, removed
\r
1403 0, //Mapper180_init,
\r
1407 0, //Mapper184_init,
\r
1408 0, //Mapper185_init,
\r
1412 0, //Mapper189_init,
\r
1414 0, //Mapper191_init,
\r
1416 0, //Mapper193_init,
\r
1423 0, //Mapper200_init,
\r
1434 0, //Mapper211_init,
\r
1448 0, //Mapper225_init,
\r
1449 0, //Mapper226_init,
\r
1458 0, //Mapper235_init,
\r
1463 0, //Mapper240_init,
\r
1481 static DECLFW(BWRAM)
\r
1486 static DECLFR(AWRAM)
\r
1488 return WRAM[A-0x6000];
\r
1492 void (*MapStateRestore)(int version);
\r
1493 void iNESStateRestore(int version)
\r
1497 if(!MapperNo) return;
\r
1500 setprg8(0x8000+x*8192,PRGBankList[x]);
\r
1504 setchr1(0x400*x,CHRBankList[x]);
\r
1506 if(0) switch(Mirroring)
\r
1508 case 0:setmirror(MI_H);break;
\r
1509 case 1:setmirror(MI_V);break;
\r
1511 case 0x10:setmirror(MI_0);break;
\r
1513 case 0x11:setmirror(MI_1);break;
\r
1515 if(MapStateRestore) MapStateRestore(version);
\r
1518 static void iNESPower(void)
\r
1521 int type=MapperNo;
\r
1523 SetReadHandler(0x8000,0xFFFF,CartBR);
\r
1524 GameStateRestore=iNESStateRestore;
\r
1527 MapStateRestore=0;
\r
1529 setprg8r(1,0x6000,0);
\r
1531 SetReadHandler(0x6000,0x7FFF,AWRAM);
\r
1533 // asm code needs pages to be set again..
\r
1534 Page[12]=Page[13]=Page[14]=Page[15]=WRAM-0x6000;
\r
1536 SetWriteHandler(0x6000,0x7FFF,BWRAM);
\r
1537 FCEU_CheatAddRAM(8,0x6000,WRAM);
\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
1545 memset(GameMemBlock,0,GAME_MEM_BLOCK_SIZE);
\r
1548 ResetExState(0,0);
\r
1550 if(GameInfo->type == GIT_VSUNI)
\r
1551 AddExState(FCEUVSUNI_STATEINFO, ~0, 0, 0);
\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
1561 /* Exclude some mappers whose emulation code handle save state stuff
\r
1563 if(type && type!=13 && type!=96)
\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
1574 sprintf(tak,"CBL%d",x);
\r
1575 AddExState(&CHRBankList[x], 2, 1,tak);
\r
1579 if(MapInitTab[type]) MapInitTab[type]();
\r
1582 FCEU_PrintError("iNES mapper #%d is not supported at all.",type);
\r
1586 static int NewiNES_Init(int num)
\r
1588 BMAPPINGLocal *tmp=bmap;
\r
1592 if(GameInfo->type == GIT_VSUNI)
\r
1593 AddExState(FCEUVSUNI_STATEINFO, ~0, 0, 0);
\r
1597 if(num==tmp->number)
\r
1599 UNIFchrrama=0; // need here for compatibility with UNIF mapper code
\r
1610 if((VROM = (uint8 *)FCEU_malloc(CHRRAMSize)) == NULL) return 0;
\r
1611 FCEU_MemoryRand(VROM,CHRRAMSize);
\r
1614 SetupCartCHRMapping(0,VROM,CHRRAMSize,1);
\r
1615 AddExState(VROM,CHRRAMSize, 0, "CHRR");
\r
1617 if(head.ROM_type&8)
\r
1618 AddExState(ExtraNTARAM, 2048, 0, "EXNR");
\r
1619 tmp->init(&iNESCart);
\r