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,
64 void (*BoardClose)(void);
65 void (*BoardPower)(void);
66 void (*BoardReset)(void);
69 static int mirrortodo;
71 static char *boardname;
72 static char *sboardname;
75 static UNIF_HEADER unhead;
76 static UNIF_HEADER uchead;
79 static uint8 *malloced[32];
81 static int FixRomSize(uint32 size, uint32 minimum)
92 static void FreeUNIF(void)
96 {free(UNIFchrrama);UNIFchrrama=0;}
98 {free(boardname);boardname=0;}
102 {free(malloced[x]);malloced[x]=0;}
106 static void ResetUNIF(void)
115 BoardReset=BoardPower=BoardClose=0;
119 static uint8 exntar[2048];
121 static void MooMirroring(void)
124 SetupCartMirroring(mirrortodo,1,0);
125 else if(mirrortodo==0x4)
127 SetupCartMirroring(4,1,exntar);
128 AddExState(exntar, 2048, 0,"EXNR");
131 SetupCartMirroring(0,0,0);
134 static int DoMirroring(int fp)
141 static char *stuffo[6]={"Horizontal","Vertical","$2000","$2400","\"Four-screen\"","Controlled by Mapper Hardware"};
143 printf(" Name/Attribute Table Mirroring: %s\n",stuffo[t]);
148 static int CTRL(int fp)
152 if((t=FCEU_fgetc(fp))==EOF)
154 /* The information stored in this byte isn't very helpful, but it's
155 better than nothing...maybe.
158 if(t&1) FCEUGameInfo.input[0]=FCEUGameInfo.input[1]=SI_GAMEPAD;
159 else FCEUGameInfo.input[0]=FCEUGameInfo.input[1]=SI_NONE;
161 if(t&2) FCEUGameInfo.input[1]=SI_ZAPPER;
162 else if(t&0x10) FCEUGameInfo.input[1]=SI_POWERPAD;
167 static int TVCI(int fp)
170 if( (t=FCEU_fgetc(fp)) ==EOF)
174 char *stuffo[3]={"NTSC","PAL","NTSC and PAL"};
176 FCEUGameInfo.vidsys=GIV_NTSC;
178 FCEUGameInfo.vidsys=GIV_PAL;
179 printf(" TV Standard Compatibility: %s\n",stuffo[t]);
184 static int EnableBattery(int fp)
186 puts(" Battery-backed.");
187 if(FCEU_fgetc(fp)==EOF)
193 static int LoadPRG(int fp)
200 printf(" PRG ROM %d size: %d",z,(int) uchead.info);
203 t=FixRomSize(uchead.info,2048);
204 if(!(malloced[z]=FCEU_malloc(t)))
206 memset(malloced[z]+uchead.info,0xFF,t-uchead.info);
207 if(FCEU_fread(malloced[z],1,uchead.info,fp)!=uchead.info)
215 SetupCartPRGMapping(z,malloced[z],t,0);
219 static int SetBoardName(int fp)
221 if(!(boardname=FCEU_malloc(uchead.info+1)))
223 FCEU_fread(boardname,1,uchead.info,fp);
224 boardname[uchead.info]=0;
225 printf(" Board name: %s\n",boardname);
226 sboardname=boardname;
227 if(!memcmp(boardname,"NES-",4) || !memcmp(boardname,"UNL-",4) || !memcmp(boardname,"HVC-",4) || !memcmp(boardname,"BTL-",4) || !memcmp(boardname,"BMC-",4))
232 static int LoadCHR(int fp)
238 printf(" CHR ROM %d size: %d",z,(int) uchead.info);
240 free(malloced[16+z]);
241 t=FixRomSize(uchead.info,8192);
242 if(!(malloced[16+z]=FCEU_malloc(t)))
244 memset(malloced[16+z]+uchead.info,0xFF,t-uchead.info);
245 if(FCEU_fread(malloced[16+z],1,uchead.info,fp)!=uchead.info)
253 SetupCartCHRMapping(z,malloced[16+z],t,0);
258 #define BMCFLAG_FORCE4 1
259 #define BMCFLAG_CHRROK 2 // Ok for generic UNIF code to make available
260 // 8KB of CHR RAM if no CHR ROM is present.
263 BMAPPING bmap[BMC] = {
266 { "TC-U01-1.5M", TCU01_Init,0},
267 { "Sachen-8259B", S8259B_Init,BMCFLAG_CHRROK},
268 { "Sachen-8259A", S8259A_Init,BMCFLAG_CHRROK},
269 { "Sachen-74LS374N", S74LS374N_Init,0},
270 { "SA-016-1M", SA0161M_Init,0},
271 { "SA-72007", SA72007_Init,0},
272 { "SA-72008", SA72008_Init,0},
273 { "SA-0036", SA0036_Init,0},
274 { "SA-0037", SA0037_Init,0},
276 { "H2288", H2288_Init,0},
278 // { "MB-91", MB91_Init,0}, // DeathBots
279 // { "NINA-06", NINA06_Init,0}, // F-15 City War
280 // { "NINA-03", NINA03_Init,0}, // Tiles of Fate
281 // { "NINA-001", NINA001_Init,0}, // Impossible Mission 2
283 { "HKROM", HKROM_Init,0},
285 { "EWROM", EWROM_Init,0},
286 { "EKROM", EKROM_Init,0},
287 { "ELROM", ELROM_Init,0},
288 { "ETROM", ETROM_Init,0},
290 { "SAROM", SAROM_Init,0},
291 { "SBROM", SBROM_Init,0},
292 { "SCROM", SCROM_Init,0},
293 { "SEROM", SEROM_Init,0},
294 { "SGROM", SGROM_Init,0},
295 { "SKROM", SKROM_Init,0},
296 { "SLROM", SLROM_Init,0},
297 { "SL1ROM", SL1ROM_Init,0},
298 { "SNROM", SNROM_Init,0},
299 { "SOROM", SOROM_Init,0},
301 { "TGROM", TGROM_Init,0},
302 { "TR1ROM", TFROM_Init,BMCFLAG_FORCE4},
303 { "TFROM", TFROM_Init,0},
304 { "TLROM", TLROM_Init,0},
305 { "TKROM", TKROM_Init,0},
306 { "TSROM", TSROM_Init,0},
308 { "TLSROM", TLSROM_Init,0},
309 { "TKSROM", TKSROM_Init,0},
310 { "TQROM", TQROM_Init,0},
311 { "TVROM", TLROM_Init,BMCFLAG_FORCE4},
313 { "CPROM", CPROM_Init,0},
314 { "CNROM", CNROM_Init,0},
315 { "NROM", NROM256_Init,0 },
316 { "RROM", NROM128_Init,0 },
317 { "RROM-128", NROM128_Init,0 },
318 { "NROM-128", NROM128_Init,0 },
319 { "NROM-256", NROM256_Init,0 },
320 { "MHROM", MHROM_Init,0},
321 { "UNROM", UNROM_Init,0},
322 { "MARIO1-MALEE2", MALEE_Init,0},
323 { "Supervision16in1", Supervision16_Init,0},
324 { "NovelDiamond9999999in1", Novel_Init,0},
325 { "Super24in1SC03", Super24_Init,0}
329 BFMAPPING bfunc[BMF] = {
332 { "BATR", EnableBattery },
333 { "MIRR", DoMirroring },
336 { "MAPR", SetBoardName }
339 int LoadUNIFChunks(int fp)
345 t=FCEU_fread(&uchead,1,4,fp);
352 if(!(FCEU_read32(&uchead.info,fp)))
357 if(memcmp(&uchead,bfunc[x].name,strlen(bfunc[x].name)))
359 if(!bfunc[x].init(fp))
365 if(FCEU_fseek(fp,uchead.info,SEEK_CUR))
370 static int InitializeBoard(void)
376 if(strcmp(sboardname,bmap[x].name)) continue;
377 if(!malloced[16] && (bmap[x].flags&BMCFLAG_CHRROK))
379 UNIFchrrama=FCEU_malloc(8192);
380 if((malloced[16]=(uint8 *)UNIFchrrama))
382 SetupCartCHRMapping(0,(uint8 *)UNIFchrrama,8192,1);
383 AddExState(UNIFchrrama, 8192, 0,"CHRR");
388 if(bmap[x].flags&BMCFLAG_FORCE4)
394 FCEU_PrintError("Board type not supported.");
398 static void UNIFGI(int h)
403 if(BoardReset) BoardReset();
406 if(BoardPower) BoardPower();
407 if(UNIFchrrama) memset(UNIFchrrama,0,8192);
417 int UNIFLoad(char *name, int fp)
419 FCEU_fseek(fp,0,SEEK_SET);
420 FCEU_fread(&unhead,1,4,fp);
421 if(memcmp(&unhead,"UNIF",4))
428 if(!FCEU_read32(&unhead.info,fp))
430 if(FCEU_fseek(fp,0x20,SEEK_SET)<0)
432 if(!LoadUNIFChunks(fp))
434 if(!InitializeBoard())
437 GameInterface=UNIFGI;
449 void UNIFOpenWRAM(int t, char *ext, int override)
451 if(UNIFbattery|override)
453 fssp=fopen(FCEU_MakeFName(FCEUMKF_SAV,0,(ext?ext:"sav")),(t==UOW_RD)?"rb":"wb");
457 void UNIFWriteWRAM(uint8 *p, int size)
460 fwrite(p, size, 1, fssp);
463 void UNIFReadWRAM(uint8 *p, int size)
466 fread(p, size, 1, fssp);
468 void UNIFCloseWRAM(void)