d97315ac |
1 | /* FCE Ultra - NES/Famicom Emulator\r |
386f5371 |
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 |
d97315ac |
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 |
d97315ac |
35 | #include "state.h"\r |
36 | #include "file.h"\r |
386f5371 |
37 | #include "general.h"\r |
d97315ac |
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 |
d97315ac |
43 | #include "driver.h"\r |
44 | #include "svga.h"\r |
45 | \r |
46 | extern SFORMAT FCEUVSUNI_STATEINFO[];\r |
47 | \r |
386f5371 |
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 |
d97315ac |
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 |
386f5371 |
65 | //char LoadedRomFName[2048]; //mbg merge 7/17/06 added\r |
d97315ac |
66 | \r |
386f5371 |
67 | static int CHRRAMSize = -1;\r |
d97315ac |
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 |
d97315ac |
76 | /* MapperReset() is called when the NES is reset(with the reset button).\r |
386f5371 |
77 | Mapperxxx_init is called when the NES has been powered on.\r |
d97315ac |
78 | */\r |
79 | \r |
386f5371 |
80 | \r |
d97315ac |
81 | static DECLFR(TrainerRead)\r |
82 | {\r |
386f5371 |
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 |
d97315ac |
110 | }\r |
111 | \r |
c4980f9e |
112 | static void iNESGI(int h, void *param)\r |
d97315ac |
113 | {\r |
386f5371 |
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 |
d97315ac |
121 | if(MapperReset)\r |
386f5371 |
122 | MapperReset();\r |
d97315ac |
123 | if(iNESCart.Reset)\r |
386f5371 |
124 | iNESCart.Reset();\r |
125 | break;\r |
126 | case GI_POWER:\r |
127 | iNES_ExecPower();\r |
128 | \r |
d97315ac |
129 | break;\r |
386f5371 |
130 | case GI_CLOSE:\r |
d97315ac |
131 | {\r |
386f5371 |
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 |
d97315ac |
139 | }\r |
140 | break;\r |
386f5371 |
141 | case GI_INFOSTRING:\r |
c4980f9e |
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 |
386f5371 |
150 | }\r |
d97315ac |
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 |
d97315ac |
167 | static void SetInput(void)\r |
168 | {\r |
386f5371 |
169 | static struct INPSEL moo[]=\r |
d97315ac |
170 | {\r |
386f5371 |
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 |
d97315ac |
246 | };\r |
386f5371 |
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 |
d97315ac |
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 |
386f5371 |
275 | #include "ines-bad.h"\r |
d97315ac |
276 | };\r |
277 | \r |
278 | void CheckBad(uint64 md5partial)\r |
279 | {\r |
386f5371 |
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 |
d97315ac |
293 | \r |
294 | }\r |
295 | \r |
296 | \r |
297 | struct CHINF {\r |
298 | uint32 crc32;\r |
299 | int32 mapper;\r |
300 | int32 mirror;\r |
386f5371 |
301 | const char* params;\r |
d97315ac |
302 | };\r |
303 | \r |
386f5371 |
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 |
d97315ac |
337 | static void CheckHInfo(void)\r |
338 | {\r |
386f5371 |
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 |
d97315ac |
342 | \r |
386f5371 |
343 | Lower 64 bits of the MD5 hash.\r |
344 | */\r |
d97315ac |
345 | \r |
386f5371 |
346 | static uint64 savie[]=\r |
d97315ac |
347 | {\r |
386f5371 |
348 | 0x498c10dc463cfe95LL, /* Battle Fleet */\r |
349 | 0x6917ffcaca2d8466LL, /* Famista '90 */\r |
d97315ac |
350 | \r |
386f5371 |
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 |
d97315ac |
355 | \r |
386f5371 |
356 | 0x2ee3417ba8b69706LL, /* Hydlide 3*/\r |
d97315ac |
357 | \r |
386f5371 |
358 | 0xebbce5a54cf3ecc0LL, /* Justbreed */\r |
d97315ac |
359 | \r |
386f5371 |
360 | 0x6a858da551ba239eLL, /* Kaijuu Monogatari */\r |
361 | 0xa40666740b7d22feLL, /* Mindseeker */\r |
d97315ac |
362 | \r |
386f5371 |
363 | 0x77b811b2760104b9LL, /* Mouryou Senki Madara */\r |
d97315ac |
364 | \r |
386f5371 |
365 | 0x11b69122efe86e8cLL, /* RPG Jinsei Game */\r |
d97315ac |
366 | \r |
386f5371 |
367 | 0xa70b495314f4d075LL, /* Ys 3 */\r |
d97315ac |
368 | \r |
369 | \r |
386f5371 |
370 | 0xc04361e499748382LL, /* AD&D Heroes of the Lance */\r |
371 | 0xb72ee2337ced5792LL, /* AD&D Hillsfar */\r |
372 | 0x2b7103b7a27bd72fLL, /* AD&D Pool of Radiance */\r |
d97315ac |
373 | \r |
386f5371 |
374 | 0x854d7947a3177f57LL, /* Crystalis */\r |
d97315ac |
375 | \r |
386f5371 |
376 | 0xb0bcc02c843c1b79LL, /* DW */\r |
377 | 0x4a1f5336b86851b6LL, /* DW */\r |
d97315ac |
378 | \r |
386f5371 |
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 |
d97315ac |
385 | \r |
386f5371 |
386 | 0x94b9484862a26cbaLL, /* Legend of Zelda */\r |
387 | 0x04a31647de80fdabLL, /* "" */\r |
d97315ac |
388 | \r |
386f5371 |
389 | 0x9aa1dc16c05e7de5LL, /* Startropics */\r |
390 | 0x1b084107d0878bd0LL, /* Startropics 2*/\r |
d97315ac |
391 | \r |
386f5371 |
392 | 0x836c0ff4f3e06e45LL, /* Zelda 2 */\r |
d97315ac |
393 | \r |
386f5371 |
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 |
d97315ac |
397 | };\r |
398 | \r |
386f5371 |
399 | static struct CHINF moo[]=\r |
d97315ac |
400 | {\r |
386f5371 |
401 | #include "ines-correct.h"\r |
d97315ac |
402 | };\r |
386f5371 |
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 |
d97315ac |
528 | }\r |
529 | \r |
530 | typedef struct {\r |
531 | int mapper;\r |
532 | void (*init)(CartInfo *);\r |
533 | } NewMI;\r |
534 | \r |
386f5371 |
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 |
d97315ac |
721 | {\r |
386f5371 |
722 | struct md5_context md5;\r |
d97315ac |
723 | \r |
724 | if(FCEU_fread(&head,1,16,fp)!=16)\r |
386f5371 |
725 | return 0;\r |
d97315ac |
726 | \r |
386f5371 |
727 | if(memcmp(&head,"NES\x1a",4))\r |
728 | return 0;\r |
729 | \r |
730 | cleanup(&head);\r |
d97315ac |
731 | \r |
732 | memset(&iNESCart,0,sizeof(iNESCart));\r |
733 | \r |
386f5371 |
734 | MapperNo = (head.ROM_type>>4);\r |
735 | MapperNo|=(head.ROM_type2&0xF0);\r |
736 | Mirroring = (head.ROM_type&1);\r |
d97315ac |
737 | \r |
d97315ac |
738 | \r |
386f5371 |
739 | // int ROM_size=0;\r |
740 | if(!head.ROM_size)\r |
d97315ac |
741 | {\r |
386f5371 |
742 | // FCEU_PrintError("No PRG ROM!");\r |
743 | // return(0);\r |
744 | ROM_size=256;\r |
745 | //head.ROM_size++;\r |
d97315ac |
746 | }\r |
386f5371 |
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 |
d97315ac |
752 | \r |
386f5371 |
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 |
d97315ac |
768 | \r |
386f5371 |
769 | if(VROM_size)\r |
770 | VROM_size=uppow2(VROM_size);\r |
d97315ac |
771 | \r |
d97315ac |
772 | \r |
773 | if(head.ROM_type&8) Mirroring=2;\r |
774 | \r |
386f5371 |
775 | if((ROM = (uint8 *)FCEU_malloc(ROM_size<<14)) == NULL) return 0;\r |
d97315ac |
776 | \r |
386f5371 |
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 |
d97315ac |
789 | {\r |
386f5371 |
790 | trainerpoo=(uint8 *)FCEU_gmalloc(512);\r |
791 | FCEU_fread(trainerpoo,512,1,fp);\r |
d97315ac |
792 | }\r |
793 | \r |
794 | ResetCartMapping();\r |
795 | ResetExState(0,0);\r |
796 | \r |
797 | SetupCartPRGMapping(0,ROM,ROM_size*0x4000,0);\r |
386f5371 |
798 | // SetupCartPRGMapping(1,WRAM,8192,1); // ?\r |
d97315ac |
799 | \r |
386f5371 |
800 | FCEU_fread(ROM,0x4000,(round) ? ROM_size : head.ROM_size,fp);\r |
d97315ac |
801 | \r |
802 | if(VROM_size)\r |
386f5371 |
803 | FCEU_fread(VROM,0x2000,head.VROM_size,fp);\r |
d97315ac |
804 | \r |
386f5371 |
805 | md5_starts(&md5);\r |
806 | md5_update(&md5,ROM,ROM_size<<14);\r |
d97315ac |
807 | \r |
808 | iNESGameCRC32=CalcCRC32(0,ROM,ROM_size<<14);\r |
809 | \r |
810 | if(VROM_size)\r |
811 | {\r |
386f5371 |
812 | iNESGameCRC32=CalcCRC32(iNESGameCRC32,VROM,VROM_size<<13);\r |
813 | md5_update(&md5,VROM,VROM_size<<13);\r |
d97315ac |
814 | }\r |
815 | md5_finish(&md5,iNESCart.MD5);\r |
386f5371 |
816 | memcpy(&GameInfo->MD5,&iNESCart.MD5,sizeof(iNESCart.MD5));\r |
d97315ac |
817 | \r |
818 | iNESCart.CRC32=iNESGameCRC32;\r |
819 | \r |
386f5371 |
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 |
d97315ac |
823 | \r |
386f5371 |
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 |
d97315ac |
849 | \r |
850 | SetInput();\r |
851 | CheckHInfo();\r |
852 | {\r |
386f5371 |
853 | int x;\r |
854 | uint64 partialmd5=0;\r |
d97315ac |
855 | \r |
386f5371 |
856 | for(x=0;x<8;x++)\r |
857 | {\r |
858 | partialmd5 |= (uint64)iNESCart.MD5[7-x] << (x*8);\r |
859 | }\r |
d97315ac |
860 | \r |
386f5371 |
861 | FCEU_VSUniCheck(partialmd5, &MapperNo, &Mirroring);\r |
d97315ac |
862 | }\r |
863 | /* Must remain here because above functions might change value of\r |
386f5371 |
864 | VROM_size and free(VROM).\r |
d97315ac |
865 | */\r |
866 | if(VROM_size)\r |
386f5371 |
867 | SetupCartCHRMapping(0,VROM,VROM_size*0x2000,0);\r |
d97315ac |
868 | \r |
386f5371 |
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 |
d97315ac |
873 | else\r |
386f5371 |
874 | SetupCartMirroring(Mirroring&1,(Mirroring&4)>>2,0);\r |
d97315ac |
875 | \r |
876 | iNESCart.battery=(head.ROM_type&2)?1:0;\r |
877 | iNESCart.mirror=Mirroring;\r |
878 | \r |
879 | //if(MapperNo != 18) {\r |
386f5371 |
880 | // if(ROM) free(ROM);\r |
881 | // if(VROM) free(VROM);\r |
882 | // ROM=VROM=0;\r |
883 | // return(0);\r |
d97315ac |
884 | // }\r |
885 | \r |
d97315ac |
886 | \r |
386f5371 |
887 | GameInfo->mappernum = MapperNo;\r |
888 | MapperInit();\r |
d97315ac |
889 | FCEU_LoadGameSave(&iNESCart);\r |
890 | \r |
386f5371 |
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 |
d97315ac |
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 |
386f5371 |
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 |
d97315ac |
979 | \r |
980 | return 1;\r |
981 | }\r |
982 | \r |
386f5371 |
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 |
d97315ac |
996 | {\r |
386f5371 |
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 |
d97315ac |
1001 | }\r |
1002 | \r |
386f5371 |
1003 | void VRAM_BANK4(uint32 A, uint32 V)\r |
d97315ac |
1004 | {\r |
386f5371 |
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 |
d97315ac |
1012 | }\r |
386f5371 |
1013 | void VROM_BANK1(uint32 A,uint32 V)\r |
d97315ac |
1014 | {\r |
386f5371 |
1015 | setchr1(A,V);\r |
1016 | CHRBankList[(A)>>10]=V;\r |
d97315ac |
1017 | }\r |
1018 | \r |
386f5371 |
1019 | void VROM_BANK2(uint32 A,uint32 V)\r |
d97315ac |
1020 | {\r |
386f5371 |
1021 | setchr2(A,V);\r |
1022 | CHRBankList[(A)>>10]=(V<<1);\r |
1023 | CHRBankList[((A)>>10)+1]=(V<<1)+1;\r |
d97315ac |
1024 | }\r |
1025 | \r |
386f5371 |
1026 | void VROM_BANK4(uint32 A, uint32 V)\r |
d97315ac |
1027 | {\r |
386f5371 |
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 |
d97315ac |
1033 | }\r |
1034 | \r |
386f5371 |
1035 | void VROM_BANK8(uint32 V)\r |
d97315ac |
1036 | {\r |
386f5371 |
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 |
d97315ac |
1046 | }\r |
1047 | \r |
386f5371 |
1048 | void ROM_BANK8(uint32 A, uint32 V)\r |
d97315ac |
1049 | {\r |
386f5371 |
1050 | setprg8(A,V);\r |
1051 | if(A>=0x8000)\r |
1052 | PRGBankList[((A-0x8000)>>13)]=V;\r |
d97315ac |
1053 | }\r |
1054 | \r |
386f5371 |
1055 | void ROM_BANK16(uint32 A, uint32 V)\r |
d97315ac |
1056 | {\r |
386f5371 |
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 |
d97315ac |
1063 | }\r |
1064 | \r |
386f5371 |
1065 | void ROM_BANK32(uint32 V)\r |
d97315ac |
1066 | {\r |
386f5371 |
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 |
d97315ac |
1072 | }\r |
1073 | \r |
386f5371 |
1074 | void onemir(uint8 V)\r |
d97315ac |
1075 | {\r |
1076 | if(Mirroring==2) return;\r |
386f5371 |
1077 | if(V>1)\r |
1078 | V=1;\r |
d97315ac |
1079 | Mirroring=0x10|V;\r |
1080 | setmirror(MI_0+V);\r |
1081 | }\r |
1082 | \r |
386f5371 |
1083 | void MIRROR_SET2(uint8 V)\r |
d97315ac |
1084 | {\r |
1085 | if(Mirroring==2) return;\r |
1086 | Mirroring=V;\r |
1087 | setmirror(V);\r |
1088 | }\r |
1089 | \r |
386f5371 |
1090 | void MIRROR_SET(uint8 V)\r |
d97315ac |
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 |
386f5371 |
1100 | ROM_BANK16(0x8000,0);\r |
1101 | ROM_BANK16(0xC000,~0);\r |
d97315ac |
1102 | \r |
386f5371 |
1103 | if(VROM_size)\r |
1104 | VROM_BANK8(0);\r |
1105 | else\r |
1106 | setvram8(CHRRAM);\r |
d97315ac |
1107 | }\r |
d97315ac |
1108 | void (*MapInitTab[256])(void)=\r |
1109 | {\r |
386f5371 |
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 |
d97315ac |
1366 | };\r |
1367 | \r |
1368 | static DECLFW(BWRAM)\r |
1369 | {\r |
386f5371 |
1370 | WRAM[A-0x6000]=V;\r |
d97315ac |
1371 | }\r |
1372 | \r |
1373 | static DECLFR(AWRAM)\r |
1374 | {\r |
386f5371 |
1375 | return WRAM[A-0x6000];\r |
d97315ac |
1376 | }\r |
1377 | \r |
d97315ac |
1378 | \r |
1379 | void (*MapStateRestore)(int version);\r |
1380 | void iNESStateRestore(int version)\r |
1381 | {\r |
386f5371 |
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 |
d97315ac |
1403 | }\r |
1404 | \r |
1405 | static void iNESPower(void)\r |
1406 | {\r |
386f5371 |
1407 | int x;\r |
d97315ac |
1408 | int type=MapperNo;\r |
1409 | \r |
386f5371 |
1410 | SetReadHandler(0x8000,0xFFFF,CartBR);\r |
1411 | GameStateRestore=iNESStateRestore;\r |
1412 | MapClose=0;\r |
d97315ac |
1413 | MapperReset=0;\r |
386f5371 |
1414 | MapStateRestore=0;\r |
d97315ac |
1415 | \r |
386f5371 |
1416 | setprg8r(1,0x6000,0);\r |
d97315ac |
1417 | \r |
386f5371 |
1418 | SetReadHandler(0x6000,0x7FFF,AWRAM);\r |
e7f52878 |
1419 | #ifdef ASM_6502\r |
386f5371 |
1420 | // asm code needs pages to be set again..\r |
1421 | Page[12]=Page[13]=Page[14]=Page[15]=WRAM-0x6000;\r |
e7f52878 |
1422 | #endif\r |
386f5371 |
1423 | SetWriteHandler(0x6000,0x7FFF,BWRAM);\r |
1424 | FCEU_CheatAddRAM(8,0x6000,WRAM);\r |
d97315ac |
1425 | \r |
1426 | /* This statement represents atrocious code. I need to rewrite\r |
386f5371 |
1427 | all of the iNES mapper code... */\r |
d97315ac |
1428 | IRQCount=IRQLatch=IRQa=0;\r |
386f5371 |
1429 | if(head.ROM_type&2)\r |
1430 | memset(GameMemBlock+8192,0,GAME_MEM_BLOCK_SIZE-8192);\r |
d97315ac |
1431 | else\r |
386f5371 |
1432 | memset(GameMemBlock,0,GAME_MEM_BLOCK_SIZE);\r |
d97315ac |
1433 | \r |
386f5371 |
1434 | NONE_init();\r |
1435 | ResetExState(0,0);\r |
d97315ac |
1436 | \r |
386f5371 |
1437 | if(GameInfo->type == GIT_VSUNI)\r |
1438 | AddExState(FCEUVSUNI_STATEINFO, ~0, 0, 0);\r |
d97315ac |
1439 | \r |
386f5371 |
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 |
d97315ac |
1447 | \r |
1448 | /* Exclude some mappers whose emulation code handle save state stuff\r |
386f5371 |
1449 | themselves. */\r |
d97315ac |
1450 | if(type && type!=13 && type!=96)\r |
1451 | {\r |
386f5371 |
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 |
d97315ac |
1464 | }\r |
1465 | \r |
386f5371 |
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 |
d97315ac |
1471 | }\r |
1472 | \r |
386f5371 |
1473 | static int NewiNES_Init(int num)\r |
1474 | {\r |
1475 | BMAPPINGLocal *tmp=bmap;\r |
d97315ac |
1476 | \r |
386f5371 |
1477 | CHRRAMSize = -1;\r |
d97315ac |
1478 | \r |
386f5371 |
1479 | if(GameInfo->type == GIT_VSUNI)\r |
1480 | AddExState(FCEUVSUNI_STATEINFO, ~0, 0, 0);\r |
e2d0dd92 |
1481 | \r |
386f5371 |
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 |
d97315ac |
1512 | }\r |
6587f346 |
1513 | \r |
386f5371 |
1514 | // vim:ts=4\r |