1
/* FCE Ultra - NES/Famicom Emulator
3
* Copyright notice for this file:
4
* Copyright (C) 1998 BERO
5
* Copyright (C) 2002 Xodnizel
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.
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.
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
26
#ifdef _USE_SHARED_MEMORY_
41
#include "utils/general.h"
42
#include "utils/memory.h"
43
#include "utils/crc32.h"
44
#include "utils/md5.h"
49
extern SFORMAT FCEUVSUNI_STATEINFO[];
51
//mbg merge 6/29/06 - these need to be global
58
#ifdef _USE_SHARED_MEMORY_
59
HANDLE mapROM, mapVROM;
62
static CartInfo iNESCart;
64
uint8 iNESMirroring=0;
65
uint16 iNESCHRBankList[8]={0,0,0,0,0,0,0,0};
66
int32 iNESIRQLatch=0,iNESIRQCount=0;
71
char LoadedRomFName[2048]; //mbg merge 7/17/06 added
73
static void iNESPower(void);
74
static int NewiNES_Init(int num);
76
void (*MapClose)(void);
77
void (*MapperReset)(void);
79
static int MapperNo=0;
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.
86
static DECLFR(TrainerRead)
88
return(trainerpoo[A&0x1FF]);
92
void iNESGI(GI h) //bbit edited: removed static keyword
97
FCEU_ClearGameSave(&iNESCart);
114
X6502_DMW(0x7000+x,trainerpoo[x]);
115
if(X6502_DMR(0x7000+x)!=trainerpoo[x])
117
SetReadHandler(0x7000,0x71FF,TrainerRead);
125
FCEU_SaveGameSave(&iNESCart);
127
if(iNESCart.Close) iNESCart.Close();
128
#ifdef _USE_SHARED_MEMORY_
133
UnmapViewOfFile(mapROM);
147
UnmapViewOfFile(mapVROM);
148
CloseHandle(mapVROM);
158
if(ROM) {free(ROM);ROM=0;}
159
if(VROM) {free(VROM);VROM=0;}
161
if(MapClose) MapClose();
162
if(trainerpoo) {FCEU_gfree(trainerpoo);trainerpoo=0;}
168
uint32 iNESGameCRC32=0;
182
static void SetInput(void)
184
static struct INPSEL moo[]=
186
{0x3a1694f9,SI_GAMEPAD,SI_GAMEPAD,SIFC_4PLAYER}, // Nekketsu Kakutou Densetsu
188
{0xc3c0811d,SI_GAMEPAD,SI_GAMEPAD,SIFC_OEKAKIDS}, // The two "Oeka Kids" games
189
{0x9d048ea4,SI_GAMEPAD,SI_GAMEPAD,SIFC_OEKAKIDS}, //
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
197
{0x47232739,SI_GAMEPAD,SI_GAMEPAD,SIFC_TOPRIDER}, // Top Rider
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
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
214
{0xd9f45be9,SI_GAMEPAD,SI_GAMEPAD,SIFC_QUIZKING}, // Gimme a Break ...
215
{0x1545bd13,SI_GAMEPAD,SI_GAMEPAD,SIFC_QUIZKING}, // Gimme a Break ... 2
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
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
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)
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)
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}
263
while(moo[x].input1>=0 || moo[x].input2>=0 || moo[x].inputfc>=0)
265
if(moo[x].crc32==iNESGameCRC32)
267
GameInfo->input[0]=moo[x].input1;
268
GameInfo->input[1]=moo[x].input2;
269
GameInfo->inputfc=moo[x].inputfc;
276
#define INESB_INCOMPLETE 1
277
#define INESB_CORRUPT 2
278
#define INESB_HACKED 4
287
static struct BADINF BadROMImages[]=
289
#include "ines-bad.h"
292
void CheckBad(uint64 md5partial)
297
//printf("0x%llx\n",md5partial);
298
while(BadROMImages[x].name)
300
if(BadROMImages[x].md5partial == md5partial)
302
FCEU_PrintError("The copy game you have loaded, \"%s\", is bad, and will not work properly on FCE Ultra.", BadROMImages[x].name);
319
if(NewiNES_Init(MapperNo))
325
iNESCart.Power=iNESPower;
328
iNESCart.SaveGame[0]=WRAM;
329
iNESCart.SaveGameLen[0]=8192;
335
static void CheckHInfo(void)
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.
341
Lower 64 bits of the MD5 hash.
344
static uint64 savie[]=
346
0x498c10dc463cfe95LL, /* Battle Fleet */
347
0x6917ffcaca2d8466LL, /* Famista '90 */
349
0xd63dcc68c2b20adcLL, /* Final Fantasy J */
350
0x012df596e2b31174LL, /* Final Fantasy 1+2 */
351
0xf6b359a720549ecdLL, /* Final Fantasy 2 */
352
0x5a30da1d9b4af35dLL, /* Final Fantasy 3 */
354
0x2ee3417ba8b69706LL, /* Hydlide 3*/
356
0xebbce5a54cf3ecc0LL, /* Justbreed */
358
0x6a858da551ba239eLL, /* Kaijuu Monogatari */
359
0xa40666740b7d22feLL, /* Mindseeker */
361
0x77b811b2760104b9LL, /* Mouryou Senki Madara */
363
0x11b69122efe86e8cLL, /* RPG Jinsei Game */
365
0xa70b495314f4d075LL, /* Ys 3 */
368
0xc04361e499748382LL, /* AD&D Heroes of the Lance */
369
0xb72ee2337ced5792LL, /* AD&D Hillsfar */
370
0x2b7103b7a27bd72fLL, /* AD&D Pool of Radiance */
372
0x854d7947a3177f57LL, /* Crystalis */
374
0xb0bcc02c843c1b79LL, /* DW */
375
0x4a1f5336b86851b6LL, /* DW */
377
0x2dcf3a98c7937c22LL, /* DW 2 */
378
0x733026b6b72f2470LL, /* Dw 3 */
379
0x98e55e09dfcc7533LL, /* DW 4*/
380
0x8da46db592a1fcf4LL, /* Faria */
381
0x91a6846d3202e3d6LL, /* Final Fantasy */
382
0xedba17a2c4608d20LL, /* "" */
384
0x94b9484862a26cbaLL, /* Legend of Zelda */
385
0x04a31647de80fdabLL, /* "" */
387
0x9aa1dc16c05e7de5LL, /* Startropics */
388
0x1b084107d0878bd0LL, /* Startropics 2*/
390
0x836c0ff4f3e06e45LL, /* Zelda 2 */
392
0 /* Abandon all hope if the game has 0 in the lower 64-bits of its MD5 hash */
395
static struct CHINF moo[]=
397
#include "ines-correct.h"
405
partialmd5 |= (uint64)iNESCart.MD5[15-x] << (x*8);
406
//printf("%16llx\n",partialmd5);
408
CheckBad(partialmd5);
414
if(moo[x].crc32==iNESGameCRC32)
418
if(moo[x].mapper&0x800 && VROM_size)
421
#ifdef _USE_SHARED_MEMORY_
424
UnmapViewOfFile(mapVROM);
425
CloseHandle(mapVROM);
437
if(MapperNo!=(moo[x].mapper&0xFF))
440
MapperNo=moo[x].mapper&0xFF;
447
if(Mirroring==2) /* Anything but hard-wired(four screen). */
453
else if(Mirroring!=moo[x].mirror)
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).
461
Mirroring=moo[x].mirror;
467
} while(moo[x].mirror>=0 || moo[x].mapper>=0);
472
if(savie[x] == partialmd5)
474
if(!(head.ROM_type&2))
483
/* Games that use these iNES mappers tend to have the four-screen bit set
484
when it should not be.
486
if((MapperNo==118 || MapperNo==24 || MapperNo==26) && (Mirroring==2))
492
/* Four-screen mirroring implicitly set. */
499
strcpy(gigastr,"The iNES header contains incorrect information. For now, the information will be corrected in RAM. ");
501
sprintf(gigastr+strlen(gigastr),"The mapper number should be set to %d. ",MapperNo);
504
char *mstr[3]={"Horizontal","Vertical","Four-screen"};
505
sprintf(gigastr+strlen(gigastr),"Mirroring should be set to \"%s\". ",mstr[Mirroring&3]);
508
strcat(gigastr,"The battery-backed bit should be set. ");
510
strcat(gigastr,"This game should not have any CHR ROM. ");
511
strcat(gigastr,"\n");
512
FCEU_printf("%s",gigastr);
518
void (*init)(CartInfo *);
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
527
static int not_power2[] =
532
int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode)
534
struct md5_context md5;
536
if(FCEU_fread(&head,1,16,fp)!=16)
539
if(memcmp(&head,"NES\x1a",4))
544
memset(&iNESCart,0,sizeof(iNESCart));
546
MapperNo = (head.ROM_type>>4);
547
MapperNo|=(head.ROM_type2&0xF0);
548
Mirroring = (head.ROM_type&1);
554
// FCEU_PrintError("No PRG ROM!");
560
ROM_size=uppow2(head.ROM_size);
562
// ROM_size = head.ROM_size;
563
VROM_size = head.VROM_size;
566
for (int i = 0; i != sizeof(not_power2)/sizeof(not_power2[0]); ++i)
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
573
if (not_power2[i] == MapperNo)
581
VROM_size=uppow2(VROM_size);
584
if(head.ROM_type&8) Mirroring=2;
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)
593
if(!(ROM=(uint8 *)FCEU_malloc(ROM_size<<14)))
598
if(!(VROM=(uint8 *)FCEU_malloc(VROM_size<<13)))
608
ROM = (uint8 *)MapViewOfFile(mapROM, FILE_MAP_WRITE, 0, 0, 0);
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);
617
UnmapViewOfFile(mapROM);
624
if(!(ROM=(uint8 *)FCEU_malloc(ROM_size<<14)))
629
if(!(VROM=(uint8 *)FCEU_malloc(VROM_size<<13)))
636
memset(ROM,0xFF,ROM_size<<14);
637
if(VROM_size) memset(VROM,0xFF,VROM_size<<13);
638
if(head.ROM_type&4) /* Trainer */
640
trainerpoo=(uint8 *)FCEU_gmalloc(512);
641
FCEU_fread(trainerpoo,512,1,fp);
647
SetupCartPRGMapping(0,ROM,ROM_size*0x4000,0);
648
// SetupCartPRGMapping(1,WRAM,8192,1);
650
FCEU_fread(ROM,0x4000,(round) ? ROM_size : head.ROM_size,fp);
653
FCEU_fread(VROM,0x2000,head.VROM_size,fp);
656
md5_update(&md5,ROM,ROM_size<<14);
658
iNESGameCRC32=CalcCRC32(0,ROM,ROM_size<<14);
662
iNESGameCRC32=CalcCRC32(iNESGameCRC32,VROM,VROM_size<<13);
663
md5_update(&md5,VROM,VROM_size<<13);
665
md5_finish(&md5,iNESCart.MD5);
666
memcpy(&GameInfo->MD5,&iNESCart.MD5,sizeof(iNESCart.MD5));
668
iNESCart.CRC32=iNESGameCRC32;
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);
675
FCEU_printf(" ROM MD5: 0x");
677
FCEU_printf("%02x",iNESCart.MD5[x]);
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");
692
partialmd5 |= (uint64)iNESCart.MD5[7-x] << (x*8);
695
FCEU_VSUniCheck(partialmd5, &MapperNo, &Mirroring);
697
/* Must remain here because above functions might change value of
698
VROM_size and free(VROM).
701
SetupCartCHRMapping(0,VROM,VROM_size*0x2000,0);
704
SetupCartMirroring(4,1,ExtraNTARAM);
705
else if(Mirroring>=0x10)
706
SetupCartMirroring(2+(Mirroring&1),1,0);
708
SetupCartMirroring(Mirroring&1,(Mirroring&4)>>2,0);
710
iNESCart.battery=(head.ROM_type&2)?1:0;
711
iNESCart.mirror=Mirroring;
713
//if(MapperNo != 18) {
714
// if(ROM) free(ROM);
715
// if(VROM) free(VROM);
721
GameInfo->mappernum = MapperNo;
723
FCEU_LoadGameSave(&iNESCart);
725
strcpy(LoadedRomFName,name); //bbit edited: line added
726
GameInterface=iNESGI;
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?
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);
740
FCEUI_SetVidSystem(0);
746
//bbit edited: the whole function below was added
751
if(GameInfo->type != GIT_CART)return 0;
752
if(GameInterface!=iNESGI)return 0;
754
strcpy(name,LoadedRomFName);
755
if (strcmp(name+strlen(name)-4,".nes") != 0) { //para edit
759
fp = fopen(name,"wb");
761
if(fwrite(&head,1,16,fp)!=16)return 0;
763
if(head.ROM_type&4) /* Trainer */
765
fwrite(trainerpoo,512,1,fp);
768
fwrite(ROM,0x4000,ROM_size,fp);
770
if(head.VROM_size)fwrite(VROM,0x2000,head.VROM_size,fp);
776
int iNesSaveAs(char* name)
778
//adelikat: TODO: iNesSave() and this have pretty much the same code, outsource the common code to a single function
781
if(GameInfo->type != GIT_CART)return 0;
782
if(GameInterface!=iNESGI)return 0;
784
fp = fopen(name,"wb");
788
if(fwrite(&head,1,16,fp)!=16)return 0;
790
if(head.ROM_type&4) /* Trainer */
792
fwrite(trainerpoo,512,1,fp);
795
fwrite(ROM,0x4000,ROM_size,fp);
797
if(head.VROM_size)fwrite(VROM,0x2000,head.VROM_size,fp);
803
//para edit: added function below
804
char *iNesShortFName() {
807
if (!(ret = strrchr(LoadedRomFName,'\\'))) {
808
if (!(ret = strrchr(LoadedRomFName,'/'))) return 0;
813
void VRAM_BANK1(uint32 A, uint8 V)
816
PPUCHRRAM|=(1<<(A>>10));
817
CHRBankList[(A)>>10]=V;
818
VPage[(A)>>10]=&CHRRAM[V<<10]-(A);
821
void VRAM_BANK4(uint32 A, uint32 V)
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);
831
void VROM_BANK1(uint32 A,uint32 V)
834
CHRBankList[(A)>>10]=V;
837
void VROM_BANK2(uint32 A,uint32 V)
840
CHRBankList[(A)>>10]=(V<<1);
841
CHRBankList[((A)>>10)+1]=(V<<1)+1;
844
void VROM_BANK4(uint32 A, uint32 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;
853
void VROM_BANK8(uint32 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;
866
void ROM_BANK8(uint32 A, uint32 V)
870
PRGBankList[((A-0x8000)>>13)]=V;
873
void ROM_BANK16(uint32 A, uint32 V)
878
PRGBankList[((A-0x8000)>>13)]=V<<1;
879
PRGBankList[((A-0x8000)>>13)+1]=(V<<1)+1;
883
void ROM_BANK32(uint32 V)
887
PRGBankList[1]=(V<<2)+1;
888
PRGBankList[2]=(V<<2)+2;
889
PRGBankList[3]=(V<<2)+3;
894
if(Mirroring==2) return;
901
void MIRROR_SET2(uint8 V)
903
if(Mirroring==2) return;
908
void MIRROR_SET(uint8 V)
910
if(Mirroring==2) return;
916
static void NONE_init(void)
918
ROM_BANK16(0x8000,0);
919
ROM_BANK16(0xC000,~0);
926
void (*MapInitTab[256])(void)=
1035
0, //Mapper107_init,
1041
0, // Mapper113_init,
1044
0, //Mapper116_init,
1045
0, //Mapper117_init,
1068
0, //Mapper140_init,
1072
0, //Mapper144_init,
1080
0, //Mapper152_init,
1081
0, //Mapper153_init,
1082
0, //Mapper154_init,
1086
0, //Mapper158_init, removed
1108
0, //Mapper180_init,
1112
0, //Mapper184_init,
1113
0, //Mapper185_init,
1117
0, //Mapper189_init,
1119
0, //Mapper191_init,
1128
0, //Mapper200_init,
1139
0, //Mapper211_init,
1154
0, //Mapper226_init,
1163
0, //Mapper235_init,
1168
0, //Mapper240_init,
1186
static DECLFW(BWRAM)
1191
static DECLFR(AWRAM)
1193
return WRAM[A-0x6000];
1197
void (*MapStateRestore)(int version);
1198
void iNESStateRestore(int version)
1202
if(!MapperNo) return;
1205
setprg8(0x8000+x*8192,PRGBankList[x]);
1209
setchr1(0x400*x,CHRBankList[x]);
1211
if(0) switch(Mirroring)
1213
case 0:setmirror(MI_H);break;
1214
case 1:setmirror(MI_V);break;
1216
case 0x10:setmirror(MI_0);break;
1218
case 0x11:setmirror(MI_1);break;
1220
if(MapStateRestore) MapStateRestore(version);
1223
static void iNESPower(void)
1228
SetReadHandler(0x8000,0xFFFF,CartBR);
1229
GameStateRestore=iNESStateRestore;
1234
setprg8r(1,0x6000,0);
1236
SetReadHandler(0x6000,0x7FFF,AWRAM);
1237
SetWriteHandler(0x6000,0x7FFF,BWRAM);
1238
FCEU_CheatAddRAM(8,0x6000,WRAM);
1240
/* This statement represents atrocious code. I need to rewrite
1241
all of the iNES mapper code... */
1242
IRQCount=IRQLatch=IRQa=0;
1244
memset(GameMemBlock+8192,0,sizeof(GameMemBlock)-8192);
1246
memset(GameMemBlock,0,sizeof(GameMemBlock));
1251
if(GameInfo->type == GIT_VSUNI)
1252
AddExState(FCEUVSUNI_STATEINFO, ~0, 0, 0);
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");
1260
AddExState(ExtraNTARAM, 2048, 0, "EXNR");
1262
/* Exclude some mappers whose emulation code handle save state stuff
1264
if(type && type!=13 && type!=96)
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");
1275
sprintf(tak,"CBL%d",x);
1276
AddExState(&CHRBankList[x], 2, 1,tak);
1280
if(MapInitTab[type]) MapInitTab[type]();
1283
FCEU_PrintError("iNES mapper #%d is not supported at all.",type);
1290
void (*init)(CartInfo *);
1293
static BMAPPING bmap[] = {
1301
{11, Mapper11_Init},
1302
{12, Mapper12_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},
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},
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},
1357
{140, Mapper140_Init},
1359
{142, UNLKS7032_Init},
1361
{144, Mapper144_Init},
1362
{145, SA72007_Init},
1363
{146, SA0161M_Init},
1367
{150, S74LS374N_Init},
1368
{152, Mapper152_Init},
1369
{153, Mapper153_Init},
1370
{154, Mapper154_Init},
1371
{155, Mapper155_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},
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},
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},
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},
1437
static int NewiNES_Init(int num)
1441
if(GameInfo->type == GIT_VSUNI)
1442
AddExState(FCEUVSUNI_STATEINFO, ~0, 0, 0);
1446
if(num==tmp->number)
1448
UNIFchrrama=0; // need here for compatibility with UNIF mapper code
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)
1464
CloseHandle(mapVROM);
1466
VROM=(uint8 *)malloc(CHRRAMSize);
1470
VROM = (uint8 *)MapViewOfFile(mapVROM, FILE_MAP_WRITE, 0, 0, 0);
1473
VROM=(uint8 *)malloc(CHRRAMSize);
1476
SetupCartCHRMapping(0,VROM,CHRRAMSize,1);
1477
AddExState(VROM,CHRRAMSize, 0, "CHRR");
1480
AddExState(ExtraNTARAM, 2048, 0, "EXNR");
1481
tmp->init(&iNESCart);