1 /* FCE Ultra - NES/Famicom Emulator
3 * Copyright notice for this file:
4 * Copyright (C) 2002 Ben Parnell
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 /* TODO: Battery backup file saving, mirror force */
23 /* Override stuff: CHR RAM instead of CHR ROM,
61 void (*BoardClose)(void);
62 void (*BoardPower)(void);
63 void (*BoardReset)(void);
66 static int mirrortodo;
68 static char *boardname;
69 static char *sboardname;
72 static UNIF_HEADER unhead;
73 static UNIF_HEADER uchead;
76 static uint8 *malloced[32];
78 static int FixRomSize(uint32 size, uint32 minimum)
89 static void FreeUNIF(void)
93 {free(UNIFchrrama);UNIFchrrama=0;}
95 {free(boardname);boardname=0;}
99 {free(malloced[x]);malloced[x]=0;}
103 static void ResetUNIF(void)
112 BoardReset=BoardPower=BoardClose=0;
116 static uint8 exntar[2048];
118 static void MooMirroring(void)
121 SetupCartMirroring(mirrortodo,1,0);
122 else if(mirrortodo==0x4)
124 SetupCartMirroring(4,1,exntar);
125 AddExState(exntar, 2048, 0,"EXNR");
128 SetupCartMirroring(0,0,0);
131 static int DoMirroring(int fp)
138 static char *stuffo[6]={"Horizontal","Vertical","$2000","$2400","\"Four-screen\"","Controlled by Mapper Hardware"};
140 printf(" Name/Attribute Table Mirroring: %s\n",stuffo[t]);
145 static int CTRL(int fp)
149 if((t=FCEU_fgetc(fp))==EOF)
151 /* The information stored in this byte isn't very helpful, but it's
152 better than nothing...maybe.
155 if(t&1) FCEUGameInfo.input[0]=FCEUGameInfo.input[1]=SI_GAMEPAD;
156 else FCEUGameInfo.input[0]=FCEUGameInfo.input[1]=SI_NONE;
158 if(t&2) FCEUGameInfo.input[1]=SI_ZAPPER;
159 else if(t&0x10) FCEUGameInfo.input[1]=SI_POWERPAD;
164 static int TVCI(int fp)
167 if( (t=FCEU_fgetc(fp)) ==EOF)
171 char *stuffo[3]={"NTSC","PAL","NTSC and PAL"};
173 FCEUGameInfo.vidsys=GIV_NTSC;
175 FCEUGameInfo.vidsys=GIV_PAL;
176 printf(" TV Standard Compatibility: %s\n",stuffo[t]);
181 static int EnableBattery(int fp)
183 puts(" Battery-backed.");
184 if(FCEU_fgetc(fp)==EOF)
190 static int LoadPRG(int fp)
197 printf(" PRG ROM %d size: %d",z,(int) uchead.info);
200 t=FixRomSize(uchead.info,2048);
201 if(!(malloced[z]=FCEU_malloc(t)))
203 memset(malloced[z]+uchead.info,0xFF,t-uchead.info);
204 if(FCEU_fread(malloced[z],1,uchead.info,fp)!=uchead.info)
212 SetupCartPRGMapping(z,malloced[z],t,0);
216 static int SetBoardName(int fp)
218 if(!(boardname=FCEU_malloc(uchead.info+1)))
220 FCEU_fread(boardname,1,uchead.info,fp);
221 boardname[uchead.info]=0;
222 printf(" Board name: %s\n",boardname);
223 sboardname=boardname;
224 if(!memcmp(boardname,"NES-",4) || !memcmp(boardname,"UNL-",4) || !memcmp(boardname,"HVC-",4) || !memcmp(boardname,"BTL-",4) || !memcmp(boardname,"BMC-",4))
229 static int LoadCHR(int fp)
235 printf(" CHR ROM %d size: %d",z,(int) uchead.info);
237 free(malloced[16+z]);
238 t=FixRomSize(uchead.info,8192);
239 if(!(malloced[16+z]=FCEU_malloc(t)))
241 memset(malloced[16+z]+uchead.info,0xFF,t-uchead.info);
242 if(FCEU_fread(malloced[16+z],1,uchead.info,fp)!=uchead.info)
250 SetupCartCHRMapping(z,malloced[16+z],t,0);
255 #define BMCFLAG_FORCE4 1
256 #define BMCFLAG_CHRROK 2 // Ok for generic UNIF code to make available
257 // 8KB of CHR RAM if no CHR ROM is present.
260 BMAPPING bmap[BMC] = {
263 { "TC-U01-1.5M", TCU01_Init,0},
264 { "Sachen-8259B", S8259B_Init,BMCFLAG_CHRROK},
265 { "Sachen-8259A", S8259A_Init,BMCFLAG_CHRROK},
266 { "Sachen-74LS374N", S74LS374N_Init,0},
267 { "SA-016-1M", SA0161M_Init,0},
268 { "SA-72007", SA72007_Init,0},
269 { "SA-72008", SA72008_Init,0},
270 { "SA-0036", SA0036_Init,0},
271 { "SA-0037", SA0037_Init,0},
273 { "H2288", H2288_Init,0},
275 // { "MB-91", MB91_Init,0}, // DeathBots
276 // { "NINA-06", NINA06_Init,0}, // F-15 City War
277 // { "NINA-03", NINA03_Init,0}, // Tiles of Fate
278 // { "NINA-001", NINA001_Init,0}, // Impossible Mission 2
280 { "HKROM", HKROM_Init,0},
282 { "EWROM", EWROM_Init,0},
283 { "EKROM", EKROM_Init,0},
284 { "ELROM", ELROM_Init,0},
285 { "ETROM", ETROM_Init,0},
287 { "SAROM", SAROM_Init,0},
288 { "SBROM", SBROM_Init,0},
289 { "SCROM", SCROM_Init,0},
290 { "SEROM", SEROM_Init,0},
291 { "SGROM", SGROM_Init,0},
292 { "SKROM", SKROM_Init,0},
293 { "SLROM", SLROM_Init,0},
294 { "SL1ROM", SL1ROM_Init,0},
295 { "SNROM", SNROM_Init,0},
296 { "SOROM", SOROM_Init,0},
298 { "TGROM", TGROM_Init,0},
299 { "TR1ROM", TFROM_Init,BMCFLAG_FORCE4},
300 { "TFROM", TFROM_Init,0},
301 { "TLROM", TLROM_Init,0},
302 { "TKROM", TKROM_Init,0},
303 { "TSROM", TSROM_Init,0},
305 { "TLSROM", TLSROM_Init,0},
306 { "TKSROM", TKSROM_Init,0},
307 { "TQROM", TQROM_Init,0},
308 { "TVROM", TLROM_Init,BMCFLAG_FORCE4},
310 { "CPROM", CPROM_Init,0},
311 { "CNROM", CNROM_Init,0},
312 { "NROM", NROM256_Init,0 },
313 { "RROM", NROM128_Init,0 },
314 { "RROM-128", NROM128_Init,0 },
315 { "NROM-128", NROM128_Init,0 },
316 { "NROM-256", NROM256_Init,0 },
317 { "MHROM", MHROM_Init,0},
318 { "UNROM", UNROM_Init,0},
319 { "MARIO1-MALEE2", MALEE_Init,0},
320 { "Supervision16in1", Supervision16_Init,0},
321 { "NovelDiamond9999999in1", Novel_Init,0},
322 { "Super24in1SC03", Super24_Init,0}
326 BFMAPPING bfunc[BMF] = {
329 { "BATR", EnableBattery },
330 { "MIRR", DoMirroring },
333 { "MAPR", SetBoardName }
336 int LoadUNIFChunks(int fp)
342 t=FCEU_fread(&uchead,1,4,fp);
349 if(!(FCEU_read32(&uchead.info,fp)))
354 if(memcmp(&uchead,bfunc[x].name,strlen(bfunc[x].name)))
356 if(!bfunc[x].init(fp))
362 if(FCEU_fseek(fp,uchead.info,SEEK_CUR))
367 static int InitializeBoard(void)
373 if(strcmp(sboardname,bmap[x].name)) continue;
374 if(!malloced[16] && (bmap[x].flags&BMCFLAG_CHRROK))
376 UNIFchrrama=FCEU_malloc(8192);
377 if((malloced[16]=(uint8 *)UNIFchrrama))
379 SetupCartCHRMapping(0,(uint8 *)UNIFchrrama,8192,1);
380 AddExState(UNIFchrrama, 8192, 0,"CHRR");
385 if(bmap[x].flags&BMCFLAG_FORCE4)
391 FCEU_PrintError("Board type not supported.");
395 static void UNIFGI(int h)
400 if(BoardReset) BoardReset();
403 if(BoardPower) BoardPower();
404 if(UNIFchrrama) memset(UNIFchrrama,0,8192);
414 int UNIFLoad(char *name, int fp)
416 FCEU_fseek(fp,0,SEEK_SET);
417 FCEU_fread(&unhead,1,4,fp);
418 if(memcmp(&unhead,"UNIF",4))
425 if(!FCEU_read32(&unhead.info,fp))
427 if(FCEU_fseek(fp,0x20,SEEK_SET)<0)
429 if(!LoadUNIFChunks(fp))
431 if(!InitializeBoard())
434 GameInterface=UNIFGI;
446 void UNIFOpenWRAM(int t, char *ext, int override)
448 if(UNIFbattery|override)
450 fssp=fopen(FCEU_MakeFName(FCEUMKF_SAV,0,(ext?ext:"sav")),(t==UOW_RD)?"rb":"wb");
454 void UNIFWriteWRAM(uint8 *p, int size)
457 fwrite(p, size, 1, fssp);
460 void UNIFReadWRAM(uint8 *p, int size)
463 fread(p, size, 1, fssp);
465 void UNIFCloseWRAM(void)