-/* FCE Ultra - NES/Famicom Emulator
- *
- * Copyright notice for this file:
- * Copyright (C) 2002 Ben Parnell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* TODO: Battery backup file saving, mirror force */
-/* **INCOMPLETE** */
-/* Override stuff: CHR RAM instead of CHR ROM,
- mirroring.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-#include "types.h"
-#include "fce.h"
-#include "unif.h"
-#include "version.h"
-#include "svga.h"
-#include "general.h"
-#include "state.h"
-#include "endian.h"
-#include "file.h"
-#include "cart.h"
-#include "memory.h"
-#include "input.h"
-
-typedef struct {
- char ID[4];
- uint32 info;
-} UNIF_HEADER;
-
-typedef struct {
- char *name;
- void (*init)(void);
- int flags;
-} BMAPPING;
-
-typedef struct {
- char *name;
- int (*init)(int fp);
-} BFMAPPING;
-
-void (*BoardClose)(void);
-void (*BoardPower)(void);
-void (*BoardReset)(void);
-
-static int vramo;
-static int mirrortodo;
-int UNIFbattery;
-static char *boardname;
-static char *sboardname;
-char *UNIFchrrama;
-
-static UNIF_HEADER unhead;
-static UNIF_HEADER uchead;
-
-
-static uint8 *malloced[32];
-
-static int FixRomSize(uint32 size, uint32 minimum)
-{
- int x=1;
-
- if(size<minimum)
- return minimum;
- while(x<size)
- x<<=1;
- return x;
-}
-
-static void FreeUNIF(void)
-{
- int x;
- if(UNIFchrrama)
- {free(UNIFchrrama);UNIFchrrama=0;}
- if(boardname)
- {free(boardname);boardname=0;}
- for(x=0;x<32;x++)
- {
- if(malloced[x])
- {free(malloced[x]);malloced[x]=0;}
- }
-}
-
-static void ResetUNIF(void)
-{
- int x;
- for(x=0;x<32;x++)
- malloced[x]=0;
- vramo=0;
- UNIFbattery=0;
- boardname=0;
- mirrortodo=0;
- BoardReset=BoardPower=BoardClose=0;
- UNIFchrrama=0;
-}
-
-static uint8 exntar[2048];
-
-static void MooMirroring(void)
-{
- if(mirrortodo<0x4)
- SetupCartMirroring(mirrortodo,1,0);
- else if(mirrortodo==0x4)
- {
- SetupCartMirroring(4,1,exntar);
- AddExState(exntar, 2048, 0,"EXNR");
- }
- else
- SetupCartMirroring(0,0,0);
-}
-
-static int DoMirroring(int fp)
-{
- uint8 t;
- t=FCEU_fgetc(fp);
- mirrortodo=t;
-
- {
- static char *stuffo[6]={"Horizontal","Vertical","$2000","$2400","\"Four-screen\"","Controlled by Mapper Hardware"};
- if(t<6)
- printf(" Name/Attribute Table Mirroring: %s\n",stuffo[t]);
- }
- return(1);
-}
-
-static int CTRL(int fp)
-{
- int t;
-
- if((t=FCEU_fgetc(fp))==EOF)
- return(0);
- /* The information stored in this byte isn't very helpful, but it's
- better than nothing...maybe.
- */
-
- if(t&1) FCEUGameInfo.input[0]=FCEUGameInfo.input[1]=SI_GAMEPAD;
- else FCEUGameInfo.input[0]=FCEUGameInfo.input[1]=SI_NONE;
-
- if(t&2) FCEUGameInfo.input[1]=SI_ZAPPER;
- else if(t&0x10) FCEUGameInfo.input[1]=SI_POWERPAD;
-
- return(1);
-}
-
-static int TVCI(int fp)
-{
- int t;
- if( (t=FCEU_fgetc(fp)) ==EOF)
- return(0);
- if(t<=2)
- {
- char *stuffo[3]={"NTSC","PAL","NTSC and PAL"};
- if(t==0)
- FCEUGameInfo.vidsys=GIV_NTSC;
- else if(t==1)
- FCEUGameInfo.vidsys=GIV_PAL;
- printf(" TV Standard Compatibility: %s\n",stuffo[t]);
- }
- return(1);
-}
-
-static int EnableBattery(int fp)
-{
- puts(" Battery-backed.");
- if(FCEU_fgetc(fp)==EOF)
- return(0);
- UNIFbattery=1;
- return(1);
-}
-
-static int LoadPRG(int fp)
-{
- int z,t;
- z=uchead.ID[3]-'0';
-
- if(z<0 || z>15)
- return(0);
- printf(" PRG ROM %d size: %d",z,(int) uchead.info);
- if(malloced[z])
- free(malloced[z]);
- t=FixRomSize(uchead.info,2048);
- if(!(malloced[z]=FCEU_malloc(t)))
- return(0);
- memset(malloced[z]+uchead.info,0xFF,t-uchead.info);
- if(FCEU_fread(malloced[z],1,uchead.info,fp)!=uchead.info)
- {
- puts("Read Error!");
- return(0);
- }
- else
- puts("");
-
- SetupCartPRGMapping(z,malloced[z],t,0);
- return(1);
-}
-
-static int SetBoardName(int fp)
-{
- if(!(boardname=FCEU_malloc(uchead.info+1)))
- return(0);
- FCEU_fread(boardname,1,uchead.info,fp);
- boardname[uchead.info]=0;
- printf(" Board name: %s\n",boardname);
- sboardname=boardname;
- if(!memcmp(boardname,"NES-",4) || !memcmp(boardname,"UNL-",4) || !memcmp(boardname,"HVC-",4) || !memcmp(boardname,"BTL-",4) || !memcmp(boardname,"BMC-",4))
- sboardname+=4;
- return(1);
-}
-
-static int LoadCHR(int fp)
-{
- int z,t;
- z=uchead.ID[3]-'0';
- if(z<0 || z>15)
- return(0);
- printf(" CHR ROM %d size: %d",z,(int) uchead.info);
- if(malloced[16+z])
- free(malloced[16+z]);
- t=FixRomSize(uchead.info,8192);
- if(!(malloced[16+z]=FCEU_malloc(t)))
- return(0);
- memset(malloced[16+z]+uchead.info,0xFF,t-uchead.info);
- if(FCEU_fread(malloced[16+z],1,uchead.info,fp)!=uchead.info)
- {
- puts("Read Error!");
- return(0);
- }
- else
- puts("");
-
- SetupCartCHRMapping(z,malloced[16+z],t,0);
- return(1);
-}
-
-
-#define BMCFLAG_FORCE4 1
-#define BMCFLAG_CHRROK 2 // Ok for generic UNIF code to make available
- // 8KB of CHR RAM if no CHR ROM is present.
-#define BMC 48
-
-BMAPPING bmap[BMC] = {
-
-/* Sachen Carts */
- { "TC-U01-1.5M", TCU01_Init,0},
- { "Sachen-8259B", S8259B_Init,BMCFLAG_CHRROK},
- { "Sachen-8259A", S8259A_Init,BMCFLAG_CHRROK},
- { "Sachen-74LS374N", S74LS374N_Init,0},
- { "SA-016-1M", SA0161M_Init,0},
- { "SA-72007", SA72007_Init,0},
- { "SA-72008", SA72008_Init,0},
- { "SA-0036", SA0036_Init,0},
- { "SA-0037", SA0037_Init,0},
-
- { "H2288", H2288_Init,0},
-// /* AVE carts. */
-// { "MB-91", MB91_Init,0}, // DeathBots
-// { "NINA-06", NINA06_Init,0}, // F-15 City War
-// { "NINA-03", NINA03_Init,0}, // Tiles of Fate
-// { "NINA-001", NINA001_Init,0}, // Impossible Mission 2
-
- { "HKROM", HKROM_Init,0},
-
- { "EWROM", EWROM_Init,0},
- { "EKROM", EKROM_Init,0},
- { "ELROM", ELROM_Init,0},
- { "ETROM", ETROM_Init,0},
-
- { "SAROM", SAROM_Init,0},
- { "SBROM", SBROM_Init,0},
- { "SCROM", SCROM_Init,0},
- { "SEROM", SEROM_Init,0},
- { "SGROM", SGROM_Init,0},
- { "SKROM", SKROM_Init,0},
- { "SLROM", SLROM_Init,0},
- { "SL1ROM", SL1ROM_Init,0},
- { "SNROM", SNROM_Init,0},
- { "SOROM", SOROM_Init,0},
-
- { "TGROM", TGROM_Init,0},
- { "TR1ROM", TFROM_Init,BMCFLAG_FORCE4},
- { "TFROM", TFROM_Init,0},
- { "TLROM", TLROM_Init,0},
- { "TKROM", TKROM_Init,0},
- { "TSROM", TSROM_Init,0},
-
- { "TLSROM", TLSROM_Init,0},
- { "TKSROM", TKSROM_Init,0},
- { "TQROM", TQROM_Init,0},
- { "TVROM", TLROM_Init,BMCFLAG_FORCE4},
-
- { "CPROM", CPROM_Init,0},
- { "CNROM", CNROM_Init,0},
- { "NROM", NROM256_Init,0 },
- { "RROM", NROM128_Init,0 },
- { "RROM-128", NROM128_Init,0 },
- { "NROM-128", NROM128_Init,0 },
- { "NROM-256", NROM256_Init,0 },
- { "MHROM", MHROM_Init,0},
- { "UNROM", UNROM_Init,0},
- { "MARIO1-MALEE2", MALEE_Init,0},
- { "Supervision16in1", Supervision16_Init,0},
- { "NovelDiamond9999999in1", Novel_Init,0},
- { "Super24in1SC03", Super24_Init,0}
-};
-
-#define BMF 7
-BFMAPPING bfunc[BMF] = {
- { "CTRL", CTRL },
- { "TVCI", TVCI },
- { "BATR", EnableBattery },
- { "MIRR", DoMirroring },
- { "PRG", LoadPRG },
- { "CHR", LoadCHR },
- { "MAPR", SetBoardName }
-};
-
-int LoadUNIFChunks(int fp)
-{
- int x;
- int t;
- for(;;)
- {
- t=FCEU_fread(&uchead,1,4,fp);
- if(t<4)
- {
- if(t>0)
- return 0;
- return 1;
- }
- if(!(FCEU_read32(&uchead.info,fp)))
- return 0;
- t=0;
- for(x=0;x<BMF;x++)
- {
- if(memcmp(&uchead,bfunc[x].name,strlen(bfunc[x].name)))
- continue;
- if(!bfunc[x].init(fp))
- return 0;
- t=1;
- break;
- }
- if(!t)
- if(FCEU_fseek(fp,uchead.info,SEEK_CUR))
- return(0);
- }
-}
-
-static int InitializeBoard(void)
-{
- int x;
-
- for(x=0;x<BMC;x++)
- {
- if(strcmp(sboardname,bmap[x].name)) continue;
- if(!malloced[16] && (bmap[x].flags&BMCFLAG_CHRROK))
- {
- UNIFchrrama=FCEU_malloc(8192);
- if((malloced[16]=(uint8 *)UNIFchrrama))
- {
- SetupCartCHRMapping(0,(uint8 *)UNIFchrrama,8192,1);
- AddExState(UNIFchrrama, 8192, 0,"CHRR");
- }
- else
- return(-1);
- }
- if(bmap[x].flags&BMCFLAG_FORCE4)
- mirrortodo=4;
- MooMirroring();
- bmap[x].init();
- return(1);
- }
- FCEU_PrintError("Board type not supported.");
- return(0);
-}
-
-static void UNIFGI(int h)
-{
- switch(h)
- {
- case GI_RESETM2:
- if(BoardReset) BoardReset();
- break;
- case GI_POWER:
- if(BoardPower) BoardPower();
- if(UNIFchrrama) memset(UNIFchrrama,0,8192);
- break;
- case GI_CLOSE:
- if(BoardClose)
- BoardClose();
- FreeUNIF();
- break;
- }
-}
-
-int UNIFLoad(char *name, int fp)
-{
- FCEU_fseek(fp,0,SEEK_SET);
- FCEU_fread(&unhead,1,4,fp);
- if(memcmp(&unhead,"UNIF",4))
- return 0;
-
- ResetCartMapping();
-
- ResetExState();
- ResetUNIF();
- if(!FCEU_read32(&unhead.info,fp))
- goto aborto;
- if(FCEU_fseek(fp,0x20,SEEK_SET)<0)
- goto aborto;
- if(!LoadUNIFChunks(fp))
- goto aborto;
- if(!InitializeBoard())
- goto aborto;
-
- GameInterface=UNIFGI;
- return 1;
-
- aborto:
-
- FreeUNIF();
- ResetUNIF();
- return 0;
-}
-
-static FILE *fssp=0;
-
-void UNIFOpenWRAM(int t, char *ext, int override)
-{
- if(UNIFbattery|override)
- {
- fssp=fopen(FCEU_MakeFName(FCEUMKF_SAV,0,(ext?ext:"sav")),(t==UOW_RD)?"rb":"wb");
- }
-}
-
-void UNIFWriteWRAM(uint8 *p, int size)
-{
- if(fssp)
- fwrite(p, size, 1, fssp);
-}
-
-void UNIFReadWRAM(uint8 *p, int size)
-{
- if(fssp)
- fread(p, size, 1, fssp);
-}
-void UNIFCloseWRAM(void)
-{
- if(fssp)
- fclose(fssp);
- fssp=0;
-}
+/* FCE Ultra - NES/Famicom Emulator\r
+ *\r
+ * Copyright notice for this file:\r
+ * Copyright (C) 2002 Xodnizel\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ */\r
+\r
+/* TODO: Battery backup file saving, mirror force */\r
+/* **INCOMPLETE** */\r
+/* Override stuff: CHR RAM instead of CHR ROM, mirroring. */\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+\r
+#include "types.h"\r
+#include "fce.h"\r
+#include "cart.h"\r
+#include "unif.h"\r
+#include "ines.h"\r
+#include "general.h"\r
+#include "state.h"\r
+#include "endian.h"\r
+#include "file.h"\r
+#include "memory.h"\r
+#include "input.h"\r
+#include "md5.h"\r
+\r
+#include "svga.h"\r
+\r
+typedef struct {\r
+ char ID[4];\r
+ uint32 info;\r
+} UNIF_HEADER;\r
+\r
+typedef struct {\r
+ char *name;\r
+ void (*init)(CartInfo *);\r
+ int flags;\r
+} BMAPPING;\r
+\r
+typedef struct {\r
+ char *name;\r
+ int (*init)(int fp);\r
+} BFMAPPING;\r
+\r
+static CartInfo UNIFCart;\r
+\r
+static int vramo;\r
+static int mirrortodo;\r
+static char *boardname;\r
+static char *sboardname;\r
+\r
+static uint32 CHRRAMSize;\r
+uint8 *UNIFchrrama=0;\r
+\r
+static UNIF_HEADER unhead;\r
+static UNIF_HEADER uchead;\r
+\r
+\r
+static uint8 *malloced[32];\r
+static uint32 mallocedsizes[32];\r
+\r
+static int FixRomSize(uint32 size, uint32 minimum)\r
+{\r
+ int x=1;\r
+\r
+ if(size<minimum)\r
+ return minimum;\r
+ while(x<size)\r
+ x<<=1;\r
+ return x;\r
+}\r
+\r
+static void FreeUNIF(void)\r
+{\r
+ int x;\r
+ if(UNIFchrrama)\r
+ {free(UNIFchrrama);UNIFchrrama=0;}\r
+ if(boardname)\r
+ {free(boardname);boardname=0;}\r
+ for(x=0;x<32;x++)\r
+ {\r
+ if(malloced[x])\r
+ {free(malloced[x]);malloced[x]=0;}\r
+ }\r
+}\r
+\r
+static void ResetUNIF(void)\r
+{\r
+ int x;\r
+ for(x=0;x<32;x++)\r
+ malloced[x]=0;\r
+ vramo=0;\r
+ boardname=0;\r
+ mirrortodo=0;\r
+ memset(&UNIFCart,0,sizeof(UNIFCart));\r
+ UNIFchrrama=0;\r
+}\r
+\r
+static uint8 exntar[2048];\r
+\r
+static void MooMirroring(void)\r
+{\r
+ if(mirrortodo<0x4)\r
+ SetupCartMirroring(mirrortodo,1,0);\r
+ else if(mirrortodo==0x4)\r
+ {\r
+ SetupCartMirroring(4,1,exntar);\r
+ AddExState(exntar, 2048, 0,"EXNR");\r
+ }\r
+ else\r
+ SetupCartMirroring(0,0,0);\r
+}\r
+\r
+static int DoMirroring(int fp)\r
+{\r
+ uint8 t;\r
+ t=FCEU_fgetc(fp);\r
+ mirrortodo=t;\r
+\r
+ {\r
+ static char *stuffo[6]={"Horizontal","Vertical","$2000","$2400","\"Four-screen\"","Controlled by Mapper Hardware"};\r
+ if(t<6)\r
+ FCEU_printf(" Name/Attribute Table Mirroring: %s\n",stuffo[t]);\r
+ }\r
+ return(1);\r
+}\r
+\r
+static int NAME(int fp)\r
+{\r
+ char namebuf[100];\r
+ int index;\r
+ int t;\r
+\r
+ FCEU_printf(" Name: ");\r
+ index=0;\r
+\r
+ while((t=FCEU_fgetc(fp))>0)\r
+ if(index<99)\r
+ namebuf[index++]=t;\r
+\r
+ namebuf[index]=0;\r
+ FCEU_printf("%s\n",namebuf);\r
+\r
+ if(!FCEUGameInfo.name)\r
+ {\r
+ FCEUGameInfo.name=malloc(strlen(namebuf)+1);\r
+ strcpy((char *)FCEUGameInfo.name,namebuf);\r
+ }\r
+ return(1);\r
+}\r
+static int DINF(int fp)\r
+{\r
+ char name[100], method[100];\r
+ uint8 d, m;\r
+ uint16 y;\r
+ int t;\r
+\r
+ if(FCEU_fread(name,1,100,fp)!=100)\r
+ return(0);\r
+ if((t=FCEU_fgetc(fp))==EOF) return(0);\r
+ d=t;\r
+ if((t=FCEU_fgetc(fp))==EOF) return(0);\r
+ m=t;\r
+ if((t=FCEU_fgetc(fp))==EOF) return(0);\r
+ y=t;\r
+ if((t=FCEU_fgetc(fp))==EOF) return(0);\r
+ y|=t<<8;\r
+ if(FCEU_fread(method,1,100,fp)!=100)\r
+ return(0);\r
+ name[99]=method[99]=0;\r
+ FCEU_printf(" Dumped by: %s\n",name);\r
+ FCEU_printf(" Dumped with: %s\n",method);\r
+ {\r
+ char *months[12]={"January","February","March","April","May","June","July",\r
+ "August","September","October","November","December"};\r
+ FCEU_printf(" Dumped on: %s %d, %d\n",months[(m-1)%12],d,y);\r
+ }\r
+ return(1);\r
+}\r
+\r
+static int CTRL(int fp)\r
+{\r
+ int t;\r
+\r
+ if((t=FCEU_fgetc(fp))==EOF)\r
+ return(0);\r
+ /* The information stored in this byte isn't very helpful, but it's\r
+ better than nothing...maybe.\r
+ */\r
+\r
+ if(t&1) FCEUGameInfo.input[0]=FCEUGameInfo.input[1]=SI_GAMEPAD;\r
+ else FCEUGameInfo.input[0]=FCEUGameInfo.input[1]=SI_NONE;\r
+\r
+ if(t&2) FCEUGameInfo.input[1]=SI_ZAPPER;\r
+ //else if(t&0x10) FCEUGameInfo->input[1]=SI_POWERPAD;\r
+\r
+ return(1);\r
+}\r
+\r
+static int TVCI(int fp)\r
+{\r
+ int t;\r
+ if( (t=FCEU_fgetc(fp)) ==EOF)\r
+ return(0);\r
+ if(t<=2)\r
+ {\r
+ char *stuffo[3]={"NTSC","PAL","NTSC and PAL"};\r
+ if(t==0)\r
+ {\r
+ FCEUGameInfo.vidsys=GIV_NTSC;\r
+ FCEUI_SetVidSystem(0);\r
+ }\r
+ else if(t==1)\r
+ {\r
+ FCEUGameInfo.vidsys=GIV_PAL;\r
+ FCEUI_SetVidSystem(1);\r
+ }\r
+ FCEU_printf(" TV Standard Compatibility: %s\n",stuffo[t]);\r
+ }\r
+ return(1);\r
+}\r
+\r
+static int EnableBattery(int fp)\r
+{\r
+ FCEU_printf(" Battery-backed.\n");\r
+ if(FCEU_fgetc(fp)==EOF)\r
+ return(0);\r
+ UNIFCart.battery=1;\r
+ return(1);\r
+}\r
+\r
+static int LoadPRG(int fp)\r
+{\r
+ int z,t;\r
+ z=uchead.ID[3]-'0';\r
+\r
+ if(z<0 || z>15)\r
+ return(0);\r
+ FCEU_printf(" PRG ROM %d size: %d",z,(int) uchead.info);\r
+ if(malloced[z])\r
+ free(malloced[z]);\r
+ t=FixRomSize(uchead.info,2048);\r
+ if(!(malloced[z]=(uint8 *)FCEU_malloc(t)))\r
+ return(0);\r
+ mallocedsizes[z]=t;\r
+ memset(malloced[z]+uchead.info,0xFF,t-uchead.info);\r
+ if(FCEU_fread(malloced[z],1,uchead.info,fp)!=uchead.info)\r
+ {\r
+ FCEU_printf("Read Error!\n");\r
+ return(0);\r
+ }\r
+ else\r
+ FCEU_printf("\n");\r
+\r
+ SetupCartPRGMapping(z,malloced[z],t,0);\r
+ return(1);\r
+}\r
+\r
+static int SetBoardName(int fp)\r
+{\r
+ if(!(boardname=FCEU_malloc(uchead.info+1)))\r
+ return(0);\r
+ FCEU_fread(boardname,1,uchead.info,fp);\r
+ boardname[uchead.info]=0;\r
+ FCEU_printf(" Board name: %s\n",boardname);\r
+ sboardname=boardname;\r
+ if(!memcmp(boardname,"NES-",4) || !memcmp(boardname,"UNL-",4) || !memcmp(boardname,"HVC-",4) || !memcmp(boardname,"BTL-",4) || !memcmp(boardname,"BMC-",4))\r
+ sboardname+=4;\r
+ return(1);\r
+}\r
+\r
+static int LoadCHR(int fp)\r
+{\r
+ int z,t;\r
+ z=uchead.ID[3]-'0';\r
+ if(z<0 || z>15)\r
+ return(0);\r
+ FCEU_printf(" CHR ROM %d size: %d",z,(int) uchead.info);\r
+ if(malloced[16+z])\r
+ free(malloced[16+z]);\r
+ t=FixRomSize(uchead.info,8192);\r
+ if(!(malloced[16+z]=(uint8 *)FCEU_malloc(t)))\r
+ return(0);\r
+ mallocedsizes[16+z]=t;\r
+ memset(malloced[16+z]+uchead.info,0xFF,t-uchead.info);\r
+ if(FCEU_fread(malloced[16+z],1,uchead.info,fp)!=uchead.info)\r
+ {\r
+ FCEU_printf("Read Error!\n");\r
+ return(0);\r
+ }\r
+ else\r
+ FCEU_printf("\n");\r
+\r
+ SetupCartCHRMapping(z,malloced[16+z],t,0);\r
+ return(1);\r
+}\r
+\r
+\r
+#define BMCFLAG_FORCE4 1\r
+#define BMCFLAG_16KCHRR 2\r
+#define BMCFLAG_32KCHRR 4\r
+\r
+static BMAPPING bmap[] = {\r
+\r
+/* Sachen Carts */\r
+ { "TC-U01-1.5M", TCU01_Init,0},\r
+ { "Sachen-8259A", S8259A_Init,0},\r
+ { "Sachen-8259B", S8259B_Init,0},\r
+ { "Sachen-8259C", S8259C_Init,0},\r
+ { "Sachen-8259D", S8259D_Init,0},\r
+ { "Sachen-74LS374N", S74LS374N_Init,0},\r
+ { "Sachen-74LS374NA", S74LS374NA_Init,0}, //seems to be custom mapper\r
+ { "SA-016-1M", SA0161M_Init,0},\r
+ { "SA-72007", SA72007_Init,0},\r
+ { "SA-72008", SA72008_Init,0},\r
+ { "SA-0036", SA0036_Init,0},\r
+ { "SA-0037", SA0037_Init,0},\r
+ { "SA-NROM", TCA01_Init,0},\r
+\r
+// /* AVE carts. */\r
+// { "MB-91", MB91_Init,0}, // DeathBots\r
+// { "NINA-06", NINA06_Init,0}, // F-15 City War\r
+// { "NINA-03", NINA03_Init,0}, // Tiles of Fate\r
+// { "NINA-001", NINA001_Init,0}, // Impossible Mission 2\r
+\r
+ { "ANROM", ANROM_Init,0},\r
+\r
+ { "HKROM", HKROM_Init,0},\r
+\r
+ { "EWROM", EWROM_Init,0},\r
+ { "EKROM", EKROM_Init,0},\r
+ { "ELROM", ELROM_Init,0},\r
+ { "ETROM", ETROM_Init,0},\r
+\r
+ { "SAROM", SAROM_Init,0},\r
+ { "SBROM", SBROM_Init,0},\r
+ { "SCROM", SCROM_Init,0},\r
+ { "SEROM", SEROM_Init,0},\r
+ { "SGROM", SGROM_Init,0},\r
+ { "SKROM", SKROM_Init,0},\r
+ { "SLROM", SLROM_Init,0},\r
+ { "SL1ROM", SL1ROM_Init,0},\r
+ { "SNROM", SNROM_Init,0},\r
+ { "SOROM", SOROM_Init,0},\r
+\r
+ { "TGROM", TGROM_Init,0},\r
+ { "TR1ROM", TFROM_Init,BMCFLAG_FORCE4},\r
+\r
+ { "TEROM", TEROM_Init,0},\r
+ { "TFROM", TFROM_Init,0},\r
+ { "TLROM", TLROM_Init,0},\r
+ { "TKROM", TKROM_Init,0},\r
+ { "TSROM", TSROM_Init,0},\r
+\r
+ { "TLSROM", TLSROM_Init,0},\r
+ { "TKSROM", TKSROM_Init,0},\r
+ { "TQROM", TQROM_Init,0},\r
+ { "TVROM", TLROM_Init,BMCFLAG_FORCE4},\r
+\r
+ { "CPROM", CPROM_Init,BMCFLAG_16KCHRR},\r
+ { "CNROM", CNROM_Init,0},\r
+ { "NROM", NROM_Init,0 }, //NROM256_Init,0 },\r
+ { "NROM-128", NROM_Init,0 }, //NROM128_Init,0 },\r
+ { "NROM-256", NROM_Init,0 }, //NROM256_Init,0 },\r
+ { "RROM", NROM_Init,0 }, //NROM128_Init,0 },\r
+ { "RROM-128", NROM_Init,0 }, //NROM128_Init,0 },\r
+ { "MHROM", MHROM_Init,0},\r
+ { "UNROM", UNROM_Init,0},\r
+ { "SUNSOFT_UNROM", SUNSOFT_UNROM_Init,0},\r
+ { "MARIO1-MALEE2", MALEE_Init,0},\r
+\r
+ { "CC-21", UNLCC21_Init,0},\r
+\r
+ { "H2288", UNLH2288_Init,0},\r
+ { "KOF97", UNLKOF97_Init,0},\r
+ { "SL1632", UNLSL1632_Init,0},\r
+ { "SHERO", UNLSHeroes_Init,0},\r
+ { "8237", UNL8237_Init,0},\r
+ { "8157", UNL8157_Init,0},\r
+ { "T-262", BMCT262_Init,0},\r
+ { "FK23C", BMCFK23C_Init,0},\r
+ { "Supervision16in1", Supervision16_Init,0},\r
+ { "NovelDiamond9999999in1", Novel_Init,0},\r
+ { "Super24in1SC03", Super24_Init,0},\r
+ { "42in1ResetSwitch", BMC42in1r_Init, 0},\r
+ { "64in1NoRepeat", BMC64in1nr_Init, 0},\r
+ { "13in1JY110", BMC13in1JY110_Init, 0},\r
+ { "70in1", BMC70in1_Init, 0},\r
+ { "70in1B", BMC70in1B_Init, 0},\r
+ { "GK-192", Mapper58_Init, 0},\r
+ { "SuperHIK8in1", Mapper45_Init,0},\r
+\r
+ { "DREAMTECH01", DreamTech01_Init,0},\r
+ { "KONAMI-QTAI", Mapper190_Init,0},\r
+\r
+ { "TEK90", Mapper90_Init,0},\r
+\r
+ {0,0,0}\r
+};\r
+\r
+static BFMAPPING bfunc[] = {\r
+ { "CTRL", CTRL },\r
+ { "TVCI", TVCI },\r
+ { "BATR", EnableBattery },\r
+ { "MIRR", DoMirroring },\r
+ { "PRG", LoadPRG },\r
+ { "CHR", LoadCHR },\r
+ { "NAME", NAME },\r
+ { "MAPR", SetBoardName },\r
+ { "DINF", DINF },\r
+ { 0, 0 }\r
+};\r
+\r
+int LoadUNIFChunks(int fp)\r
+{\r
+ int x;\r
+ int t;\r
+ for(;;)\r
+ {\r
+ t=FCEU_fread(&uchead,1,4,fp);\r
+ if(t<4)\r
+ {\r
+ if(t>0)\r
+ return 0;\r
+ return 1;\r
+ }\r
+ if(!(FCEU_read32(&uchead.info,fp)))\r
+ return 0;\r
+ t=0;\r
+ x=0;\r
+ //printf("Funky: %s\n",((uint8 *)&uchead));\r
+ while(bfunc[x].name)\r
+ {\r
+ if(!memcmp(&uchead,bfunc[x].name,strlen(bfunc[x].name)))\r
+ {\r
+ if(!bfunc[x].init(fp))\r
+ return 0;\r
+ t=1;\r
+ break;\r
+ }\r
+ x++;\r
+ }\r
+ if(!t)\r
+ if(FCEU_fseek(fp,uchead.info,SEEK_CUR))\r
+ return(0);\r
+ }\r
+}\r
+\r
+static int InitializeBoard(void)\r
+{\r
+ int x=0;\r
+\r
+ if(!sboardname) return(0);\r
+\r
+ while(bmap[x].name)\r
+ {\r
+ if(!strcmp(sboardname,(char *)bmap[x].name))\r
+ {\r
+ if(!malloced[16])\r
+ {\r
+ if(bmap[x].flags & BMCFLAG_16KCHRR)\r
+ CHRRAMSize = 16384;\r
+ else\r
+ CHRRAMSize = 8192;\r
+ if((UNIFchrrama=(uint8 *)FCEU_malloc(CHRRAMSize)))\r
+ {\r
+ SetupCartCHRMapping(0,UNIFchrrama,CHRRAMSize,1);\r
+ AddExState(UNIFchrrama, CHRRAMSize, 0,"CHRR");\r
+ }\r
+ else\r
+ return(-1);\r
+ }\r
+ if(bmap[x].flags&BMCFLAG_FORCE4)\r
+ mirrortodo=4;\r
+ MooMirroring();\r
+ bmap[x].init(&UNIFCart);\r
+ return(1);\r
+ }\r
+ x++;\r
+ }\r
+ FCEU_PrintError("Board type not supported.");\r
+ return(0);\r
+}\r
+\r
+static void UNIFGI(int h, void *param)\r
+{\r
+ switch(h)\r
+ {\r
+ case GI_RESETM2:\r
+ if(UNIFCart.Reset)\r
+ UNIFCart.Reset();\r
+ break;\r
+ case GI_POWER:\r
+ if(UNIFCart.Power)\r
+ UNIFCart.Power();\r
+ if(UNIFchrrama) memset(UNIFchrrama,0,8192);\r
+ break;\r
+ case GI_CLOSE:\r
+ FCEU_SaveGameSave(&UNIFCart);\r
+ if(UNIFCart.Close)\r
+ UNIFCart.Close();\r
+ FreeUNIF();\r
+ ResetExState(0,0);\r
+ break;\r
+ case GI_INFOSTRING:\r
+ {\r
+ char board[24];\r
+ strncpy(board, sboardname, 20);\r
+ board[20] = 0;\r
+ sprintf(param, "UNIF, %s, %s%s", board, PAL?"PAL":"NTSC", UNIFCart.battery?", BB":"");\r
+ }\r
+ break;\r
+ }\r
+}\r
+\r
+int UNIFLoad(const char *name, int fp)\r
+{\r
+ FCEU_fseek(fp,0,SEEK_SET);\r
+ FCEU_fread(&unhead,1,4,fp);\r
+ if(memcmp(&unhead,"UNIF",4))\r
+ return 0;\r
+\r
+ ResetCartMapping();\r
+\r
+ ResetExState(0,0);\r
+ ResetUNIF();\r
+ if(!FCEU_read32(&unhead.info,fp))\r
+ goto aborto;\r
+ if(FCEU_fseek(fp,0x20,SEEK_SET)<0)\r
+ goto aborto;\r
+ if(!LoadUNIFChunks(fp))\r
+ goto aborto;\r
+ {\r
+ int x;\r
+ struct md5_context md5;\r
+\r
+ md5_starts(&md5);\r
+\r
+ for(x=0;x<32;x++)\r
+ if(malloced[x])\r
+ {\r
+ md5_update(&md5,malloced[x],mallocedsizes[x]);\r
+ }\r
+ md5_finish(&md5,UNIFCart.MD5);\r
+ FCEU_printf(" ROM MD5: 0x");\r
+ for(x=0;x<16;x++)\r
+ FCEU_printf("%02x",UNIFCart.MD5[x]);\r
+ FCEU_printf("\n");\r
+ memcpy(FCEUGameInfo.MD5,UNIFCart.MD5,sizeof(UNIFCart.MD5));\r
+ }\r
+\r
+ if(!InitializeBoard())\r
+ goto aborto;\r
+\r
+ FCEU_LoadGameSave(&UNIFCart);\r
+ GameInterface=UNIFGI;\r
+ return 1;\r
+\r
+ aborto:\r
+\r
+ FreeUNIF();\r
+ ResetUNIF();\r
+\r
+\r
+ return 0;\r
+}\r