~ubuntu-branches/ubuntu/lucid/fceux/lucid

« back to all changes in this revision

Viewing changes to fceu/src/ines.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Fabrice Coutadeur
  • Date: 2009-12-14 08:05:17 UTC
  • Revision ID: james.westby@ubuntu.com-20091214080517-abi5tj8avthfan7c
Tags: upstream-2.1.2+repack
ImportĀ upstreamĀ versionĀ 2.1.2+repack

Show diffs side-by-side

added added

removed removed

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