merge mappers from FCEU-mm
[fceu.git] / unif.c
CommitLineData
d97315ac 1/* FCE Ultra - NES/Famicom Emulator\r
386f5371 2*\r
3* Copyright notice for this file:\r
4* Copyright (C) 2002 Xodnizel\r
5*\r
6* This program is free software; you can redistribute it and/or modify\r
7* it under the terms of the GNU General Public License as published by\r
8* the Free Software Foundation; either version 2 of the License, or\r
9* (at your option) any later version.\r
10*\r
11* This program is distributed in the hope that it will be useful,\r
12* but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
14* GNU General Public License for more details.\r
15*\r
16* You should have received a copy of the GNU General Public License\r
17* along with this program; if not, write to the Free Software\r
18* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\r
19*/\r
d97315ac 20\r
21/* TODO: Battery backup file saving, mirror force */\r
22/* **INCOMPLETE** */\r
23/* Override stuff: CHR RAM instead of CHR ROM, mirroring. */\r
24\r
25#include <stdio.h>\r
26#include <stdlib.h>\r
27#include <string.h>\r
28\r
29\r
386f5371 30#include "types.h"\r
31#include "fce.h"\r
32#include "cart.h"\r
33#include "unif.h"\r
34#include "ines.h"\r
35#include "endian.h"\r
36#include "memory.h"\r
37#include "md5.h"\r
38#include "state.h"\r
39#include "file.h"\r
40#include "input.h"\r
41#include "driver.h"\r
42#include "svga.h"\r
d97315ac 43\r
44typedef struct {\r
386f5371 45 char ID[4];\r
46 uint32 info;\r
d97315ac 47} UNIF_HEADER;\r
48\r
49typedef struct {\r
386f5371 50 char *name;\r
51 void (*init)(CartInfo *);\r
52 int flags;\r
d97315ac 53} BMAPPING;\r
54\r
55typedef struct {\r
386f5371 56 char *name;\r
57 int (*init)(int fp);\r
d97315ac 58} BFMAPPING;\r
59\r
60static CartInfo UNIFCart;\r
61\r
62static int vramo;\r
63static int mirrortodo;\r
386f5371 64static uint8 *boardname;\r
65static uint8 *sboardname;\r
d97315ac 66\r
67static uint32 CHRRAMSize;\r
68uint8 *UNIFchrrama=0;\r
69\r
70static UNIF_HEADER unhead;\r
71static UNIF_HEADER uchead;\r
72\r
73\r
74static uint8 *malloced[32];\r
75static uint32 mallocedsizes[32];\r
76\r
77static int FixRomSize(uint32 size, uint32 minimum)\r
78{\r
386f5371 79 uint32 x=1; //mbg merge 7/17/06 made uint\r
d97315ac 80\r
386f5371 81 if(size<minimum)\r
82 return minimum;\r
83 while(x<size)\r
84 x<<=1;\r
85 return x;\r
d97315ac 86}\r
87\r
88static void FreeUNIF(void)\r
89{\r
386f5371 90 int x;\r
91 if(UNIFchrrama)\r
92 {free(UNIFchrrama);UNIFchrrama=0;}\r
93 if(boardname)\r
94 {free(boardname);boardname=0;}\r
95 for(x=0;x<32;x++)\r
96 {\r
97 if(malloced[x])\r
98 {free(malloced[x]);malloced[x]=0;}\r
99 }\r
d97315ac 100}\r
101\r
102static void ResetUNIF(void)\r
103{\r
386f5371 104 int x;\r
105 for(x=0;x<32;x++)\r
106 malloced[x]=0;\r
107 vramo=0;\r
108 boardname=0;\r
109 mirrortodo=0;\r
110 memset(&UNIFCart,0,sizeof(UNIFCart));\r
111 UNIFchrrama=0;\r
d97315ac 112}\r
113\r
114static uint8 exntar[2048];\r
115\r
116static void MooMirroring(void)\r
117{\r
386f5371 118 if(mirrortodo<0x4)\r
119 SetupCartMirroring(mirrortodo,1,0);\r
120 else if(mirrortodo==0x4)\r
121 {\r
122 SetupCartMirroring(4,1,exntar);\r
123 AddExState(exntar, 2048, 0,"EXNR");\r
124 }\r
125 else\r
126 SetupCartMirroring(0,0,0);\r
d97315ac 127}\r
128\r
129static int DoMirroring(int fp)\r
130{\r
386f5371 131 uint8 t;\r
132 t=FCEU_fgetc(fp);\r
133 mirrortodo=t;\r
134\r
135 {\r
136 static char *stuffo[6]={"Horizontal","Vertical","$2000","$2400","\"Four-screen\"","Controlled by Mapper Hardware"};\r
137 if(t<6)\r
138 FCEU_printf(" Name/Attribute Table Mirroring: %s\n",stuffo[t]);\r
139 }\r
140 return(1);\r
d97315ac 141}\r
142\r
143static int NAME(int fp)\r
144{\r
386f5371 145 char namebuf[100];\r
146 int index;\r
147 int t;\r
148\r
149 FCEU_printf(" Name: ");\r
150 index=0;\r
151\r
152 while((t=FCEU_fgetc(fp))>0)\r
153 if(index<99)\r
154 namebuf[index++]=t;\r
155\r
156 namebuf[index]=0;\r
157 FCEU_printf("%s\n",namebuf);\r
158\r
159 if(!GameInfo->name)\r
160 {\r
161 GameInfo->name=(uint8*)malloc(strlen(namebuf)+1); //mbg merge 7/17/06 added cast\r
162 strcpy((char*)GameInfo->name,namebuf); //mbg merge 7/17/06 added cast\r
163 }\r
164 return(1);\r
d97315ac 165}\r
166static int DINF(int fp)\r
167{\r
386f5371 168 char name[100], method[100];\r
169 uint8 d, m;\r
170 uint16 y;\r
171 int t;\r
172\r
173 if(FCEU_fread(name,1,100,fp)!=100)\r
174 return(0);\r
175 if((t=FCEU_fgetc(fp))==EOF) return(0);\r
176 d=t;\r
177 if((t=FCEU_fgetc(fp))==EOF) return(0);\r
178 m=t;\r
179 if((t=FCEU_fgetc(fp))==EOF) return(0);\r
180 y=t;\r
181 if((t=FCEU_fgetc(fp))==EOF) return(0);\r
182 y|=t<<8;\r
183 if(FCEU_fread(method,1,100,fp)!=100)\r
184 return(0);\r
185 name[99]=method[99]=0;\r
186 FCEU_printf(" Dumped by: %s\n",name);\r
187 FCEU_printf(" Dumped with: %s\n",method);\r
188 {\r
189 char *months[12]={"January","February","March","April","May","June","July",\r
190 "August","September","October","November","December"};\r
191 FCEU_printf(" Dumped on: %s %d, %d\n",months[(m-1)%12],d,y);\r
192 }\r
193 return(1);\r
d97315ac 194}\r
195\r
196static int CTRL(int fp)\r
197{\r
386f5371 198 int t;\r
d97315ac 199\r
386f5371 200 if((t=FCEU_fgetc(fp))==EOF)\r
201 return(0);\r
202 /* The information stored in this byte isn't very helpful, but it's\r
203 better than nothing...maybe.\r
204 */\r
d97315ac 205\r
386f5371 206 if(t&1) GameInfo->input[0]=GameInfo->input[1]=SI_GAMEPAD;\r
207 else GameInfo->input[0]=GameInfo->input[1]=SI_NONE;\r
d97315ac 208\r
386f5371 209 if(t&2) GameInfo->input[1]=SI_ZAPPER;\r
210 //else if(t&0x10) GameInfo->input[1]=SI_POWERPAD;\r
d97315ac 211\r
386f5371 212 return(1);\r
d97315ac 213}\r
214\r
215static int TVCI(int fp)\r
216{\r
386f5371 217 int t;\r
218 if( (t=FCEU_fgetc(fp)) ==EOF)\r
219 return(0);\r
220 if(t<=2)\r
221 {\r
222 char *stuffo[3]={"NTSC","PAL","NTSC and PAL"};\r
223 if(t==0)\r
224 {\r
225 GameInfo->vidsys=GIV_NTSC;\r
226 FCEUI_SetVidSystem(0);\r
227 }\r
228 else if(t==1)\r
229 {\r
230 GameInfo->vidsys=GIV_PAL;\r
231 FCEUI_SetVidSystem(1);\r
232 }\r
233 FCEU_printf(" TV Standard Compatibility: %s\n",stuffo[t]);\r
234 }\r
235 return(1);\r
d97315ac 236}\r
237\r
238static int EnableBattery(int fp)\r
239{\r
386f5371 240 FCEU_printf(" Battery-backed.\n");\r
241 if(FCEU_fgetc(fp)==EOF)\r
242 return(0);\r
243 UNIFCart.battery=1;\r
244 return(1);\r
d97315ac 245}\r
246\r
247static int LoadPRG(int fp)\r
248{\r
386f5371 249 int z,t;\r
250 z=uchead.ID[3]-'0';\r
251\r
252 if(z<0 || z>15)\r
253 return(0);\r
254 FCEU_printf(" PRG ROM %d size: %d",z,(int) uchead.info);\r
255 if(malloced[z])\r
256 free(malloced[z]);\r
257 t=FixRomSize(uchead.info,2048);\r
258 if(!(malloced[z]=(uint8 *)FCEU_malloc(t)))\r
259 return(0);\r
260 mallocedsizes[z]=t;\r
261 memset(malloced[z]+uchead.info,0xFF,t-uchead.info);\r
262 if(FCEU_fread(malloced[z],1,uchead.info,fp)!=uchead.info)\r
263 {\r
264 FCEU_printf("Read Error!\n");\r
265 return(0);\r
266 }\r
267 else\r
268 FCEU_printf("\n");\r
269\r
270 SetupCartPRGMapping(z,malloced[z],t,0);\r
271 return(1);\r
d97315ac 272}\r
273\r
274static int SetBoardName(int fp)\r
275{\r
386f5371 276 if(!(boardname=(uint8 *)FCEU_malloc(uchead.info+1)))\r
277 return(0);\r
278 FCEU_fread(boardname,1,uchead.info,fp);\r
279 boardname[uchead.info]=0;\r
280 FCEU_printf(" Board name: %s\n",boardname);\r
281 sboardname=boardname;\r
282 if(!memcmp(boardname,"NES-",4) || !memcmp(boardname,"UNL-",4) || !memcmp(boardname,"HVC-",4) || !memcmp(boardname,"BTL-",4) || !memcmp(boardname,"BMC-",4))\r
283 sboardname+=4;\r
284 return(1);\r
d97315ac 285}\r
286\r
287static int LoadCHR(int fp)\r
288{\r
386f5371 289 int z,t;\r
290 z=uchead.ID[3]-'0';\r
291 if(z<0 || z>15)\r
292 return(0);\r
293 FCEU_printf(" CHR ROM %d size: %d",z,(int) uchead.info);\r
294 if(malloced[16+z])\r
295 free(malloced[16+z]);\r
296 t=FixRomSize(uchead.info,8192);\r
297 if(!(malloced[16+z]=(uint8 *)FCEU_malloc(t)))\r
298 return(0);\r
299 mallocedsizes[16+z]=t;\r
300 memset(malloced[16+z]+uchead.info,0xFF,t-uchead.info);\r
301 if(FCEU_fread(malloced[16+z],1,uchead.info,fp)!=uchead.info)\r
302 {\r
303 FCEU_printf("Read Error!\n");\r
304 return(0);\r
305 }\r
306 else\r
307 FCEU_printf("\n");\r
308\r
309 SetupCartCHRMapping(z,malloced[16+z],t,0);\r
310 return(1);\r
d97315ac 311}\r
312\r
313\r
314#define BMCFLAG_FORCE4 1\r
315#define BMCFLAG_16KCHRR 2\r
316#define BMCFLAG_32KCHRR 4\r
386f5371 317#define BMCFLAG_EXPCHRR 8\r
d97315ac 318\r
319static BMAPPING bmap[] = {\r
320\r
43725da7 321/* Sachen Carts */\r
322 { "TC-U01-1.5M", TCU01_Init,0},\r
323 { "Sachen-8259A", S8259A_Init,0},\r
324 { "Sachen-8259B", S8259B_Init,0},\r
325 { "Sachen-8259C", S8259C_Init,0},\r
326 { "Sachen-8259D", S8259D_Init,0},\r
327 { "Sachen-74LS374N", S74LS374N_Init,0},\r
328 { "Sachen-74LS374NA", S74LS374NA_Init,0}, //seems to be custom mapper\r
329 { "SA-002", TCU02_Init, 0},\r
330 { "SA-016-1M", SA0161M_Init,0},\r
331 { "SA-72007", SA72007_Init,0},\r
332 { "SA-72008", SA72008_Init,0},\r
333 { "SA-009", SA009_Init,0},\r
334 { "SA-0036", SA0036_Init,0},\r
335 { "SA-0037", SA0037_Init,0},\r
336 { "SA-NROM", TCA01_Init,0},\r
337 { "SA-9602B", SA9602B_Init, BMCFLAG_32KCHRR},\r
338\r
339// /* AVE carts. */\r
340// { "MB-91", MB91_Init,0}, // DeathBots\r
341// { "NINA-06", NINA06_Init,0}, // F-15 City War\r
342// { "NINA-03", NINA03_Init,0}, // Tiles of Fate\r
343// { "NINA-001", NINA001_Init,0}, // Impossible Mission 2\r
344\r
345 { "ANROM", ANROM_Init,0},\r
346\r
347 { "HKROM", HKROM_Init,0},\r
348\r
349 { "EWROM", EWROM_Init,0},\r
350 { "EKROM", EKROM_Init,0},\r
351 { "ELROM", ELROM_Init,0},\r
352 { "ETROM", ETROM_Init,0},\r
353\r
354 { "SAROM", SAROM_Init,0},\r
355 { "SBROM", SBROM_Init,0},\r
356 { "SCROM", SCROM_Init,0},\r
357 { "SEROM", SEROM_Init,0},\r
358 { "SGROM", SGROM_Init,0},\r
359 { "SKROM", SKROM_Init,0},\r
360 { "SLROM", SLROM_Init,0},\r
361 { "SL1ROM", SL1ROM_Init,0},\r
362 { "SNROM", SNROM_Init,0},\r
363 { "SOROM", SOROM_Init,0},\r
364\r
365 { "TGROM", TGROM_Init,0},\r
366 { "TR1ROM", TFROM_Init,BMCFLAG_FORCE4},\r
367\r
368 { "TBROM", TBROM_Init,0},\r
369 { "TEROM", TEROM_Init,0},\r
370 { "TFROM", TFROM_Init,0},\r
371 { "TLROM", TLROM_Init,0},\r
372 { "TKROM", TKROM_Init,0},\r
373 { "TSROM", TSROM_Init,0},\r
374\r
375 { "TLSROM", TLSROM_Init,0},\r
376 { "TKSROM", TKSROM_Init,0},\r
377 { "TQROM", TQROM_Init,0},\r
378 { "TVROM", TLROM_Init,BMCFLAG_FORCE4},\r
379\r
380 { "NTBROM", Mapper68_Init,0},\r
381\r
382 { "CPROM", CPROM_Init,BMCFLAG_16KCHRR},\r
383 { "CNROM", CNROM_Init,0},\r
384 { "NROM", NROM_Init,0 }, //NROM256_Init,0 },\r
385 { "NROM-128", NROM_Init,0 }, //NROM128_Init,0 },\r
386 { "NROM-256", NROM_Init,0 }, //NROM256_Init,0 },\r
387 { "SSS-NROM-256", SSSNROM_Init,0 },\r
388 { "RROM", NROM_Init,0 }, //NROM128_Init,0 },\r
389 { "RROM-128", NROM_Init,0 }, //NROM128_Init,0 },\r
390 { "MHROM", MHROM_Init,0},\r
391 { "UNROM", UNROM_Init,0},\r
392 { "UOROM", UNROM_Init,0},\r
393 { "SUNSOFT_UNROM", SUNSOFT_UNROM_Init,0},\r
394 { "MARIO1-MALEE2", MALEE_Init,0},\r
395 { "3D-BLOCK", UNL3DBlock_Init, 0},\r
396 { "SMB2J", UNLSMB2J_Init, 0},\r
397 { "AX5705", UNLAX5705_Init, 0},\r
398 { "CC-21", UNLCC21_Init,0},\r
399 { "LE05", LE05_Init,0},\r
400 { "AC08", AC08_Init,0},\r
401 { "LH10", LH10_Init,0},\r
402 { "LH32", LH32_Init,0},\r
403 { "LH53", LH53_Init,0},\r
404 { "BB", UNLBB_Init,0},\r
405\r
406 { "H2288", UNLH2288_Init,0},\r
407 { "KOF97", UNLKOF97_Init,0},\r
408 { "SL1632", UNLSL1632_Init,0},\r
409 { "SL12", UNLSL12_Init,0},\r
410 { "SHERO", UNLSHeroes_Init,0},\r
411 { "8237", UNL8237_Init,0},\r
412 { "8237A", UNL8237A_Init,0},\r
413 { "8157", UNL8157_Init,0},\r
414 { "T-262", BMCT262_Init,0},\r
386f5371 415 { "FK23C", BMCFK23C_Init,BMCFLAG_EXPCHRR},\r
416 { "FK23CA", BMCFK23CA_Init,BMCFLAG_EXPCHRR},\r
43725da7 417 { "A65AS", BMCA65AS_Init,0},\r
418 { "YOKO", UNLYOKO_Init,0},\r
419 { "FS304", UNLFS304_Init,0},\r
420 { "43272", UNL43272_Init,0},\r
421 { "EDU2000", UNLEDU2000_Init,0},\r
422 { "603-5052", UNL6035052_Init,0},\r
423 { "N625092", UNLN625092_Init,0},\r
424 { "Supervision16in1", Supervision16_Init,0},\r
425 { "NovelDiamond9999999in1", Novel_Init,0},\r
426 { "Super24in1SC03", Super24_Init,0},\r
427 { "64in1NoRepeat", BMC64in1nr_Init, 0},\r
428 { "42in1ResetSwitch", Mapper226_Init, 0},\r
429 { "13in1JY110", BMC13in1JY110_Init, 0},\r
430 { "70in1", BMC70in1_Init, 0},\r
431 { "70in1B", BMC70in1B_Init, 0},\r
432 { "D1038", BMCD1038_Init, 0},\r
433 { "GK-192", BMCGK192_Init, 0},\r
434 { "SuperHIK8in1", Mapper45_Init,0},\r
435 { "22211", UNL22211_Init,0},\r
436 { "TF1201", UNLTF1201_Init, 0},\r
437 { "GS-2004", BMCGS2004_Init, 0},\r
438 { "GS-2013", BMCGS2013_Init, 0},\r
439 { "KS7057", UNLKS7057_Init, 0},\r
440 { "KS7037", UNLKS7037_Init, 0},\r
441 { "KS7030", UNLKS7030_Init, 0},\r
442 { "KS7031", UNLKS7031_Init, 0},\r
443 { "KS7032", UNLKS7032_Init, 0},\r
444 { "KS7017", UNLKS7017_Init, 0},\r
445 { "KS7012", UNLKS7012_Init, 0},\r
446 { "KS7013B", UNLKS7013B_Init, 0},\r
447 { "T-230", UNLT230_Init, 0},\r
448 { "CITYFIGHT", UNLCITYFIGHT_Init, 0},\r
449 { "190in1", BMC190in1_Init, 0},\r
450 { "Ghostbusters63in1", BMCGhostbusters63in1_Init, 0},\r
451 { "BS-5",BMCBS5_Init, 0},\r
452 { "411120-C",BMC411120C_Init, 0},\r
453 { "830118C",BMC830118C_Init, 0},\r
454 { "T-227-1",BMCT2271_Init,0},\r
455 { "PEC-586",UNLPEC586Init,0},\r
456 { "12-IN-1",BMC12IN1_Init,0},\r
457 { "VRC7", UNLVRC7_Init,0},\r
458 { "810544-C-A1", BMC810544CA1_Init,0},\r
459 { "NTD-03", BMCNTD03_Init,0},\r
460\r
461 { "DREAMTECH01", DreamTech01_Init,0},\r
462 { "KONAMI-QTAI", Mapper190_Init,0},\r
463\r
464 { "DANCE", UNLOneBus_Init,0}, // redundant\r
465 { "OneBus", UNLOneBus_Init,0},\r
466 { "SC-127", UNLSC127_Init,0},\r
467 { "DANCE2000", UNLD2000_Init,0},\r
468 { "Transformer", Transformer_Init, 0},\r
469\r
470 { "TEK90", Mapper90_Init,0},\r
471\r
472#ifdef COPYFAMI\r
473 { "COPYFAMI_MMC3", MapperCopyFamiMMC3_Init,0},\r
474 { "COPYFAMI", MapperCopyFami_Init,0},\r
475#endif\r
476\r
477 {0,0,0}\r
d97315ac 478};\r
479\r
480static BFMAPPING bfunc[] = {\r
386f5371 481 { "CTRL", CTRL },\r
482 { "TVCI", TVCI },\r
483 { "BATR", EnableBattery },\r
484 { "MIRR", DoMirroring },\r
485 { "PRG", LoadPRG },\r
486 { "CHR", LoadCHR },\r
487 { "NAME", NAME },\r
488 { "MAPR", SetBoardName },\r
489 { "DINF", DINF },\r
490 { 0, 0 }\r
d97315ac 491};\r
492\r
493int LoadUNIFChunks(int fp)\r
494{\r
386f5371 495 int x;\r
496 int t;\r
497 for(;;)\r
498 {\r
499 t=FCEU_fread(&uchead,1,4,fp);\r
500 if(t<4)\r
501 {\r
502 if(t>0)\r
503 return 0;\r
504 return 1;\r
505 }\r
506 if(!(FCEU_read32le(&uchead.info,fp)))\r
507 return 0;\r
508 t=0;\r
509 x=0;\r
510 //printf("Funky: %s\n",((uint8 *)&uchead));\r
511 while(bfunc[x].name)\r
512 {\r
513 if(!memcmp(&uchead,bfunc[x].name,strlen(bfunc[x].name)))\r
514 {\r
515 if(!bfunc[x].init(fp))\r
516 return 0;\r
517 t=1;\r
518 break;\r
519 }\r
520 x++;\r
521 }\r
522 if(!t)\r
523 if(FCEU_fseek(fp,uchead.info,SEEK_CUR)<0)\r
524 return(0);\r
525 }\r
d97315ac 526}\r
527\r
528static int InitializeBoard(void)\r
529{\r
386f5371 530 int x=0;\r
d97315ac 531\r
386f5371 532 if(!sboardname) return(0);\r
d97315ac 533\r
386f5371 534 while(bmap[x].name)\r
535 {\r
536 if(!strcmp((char *)sboardname,(char *)bmap[x].name))\r
537 {\r
538 if(!malloced[16])\r
539 {\r
d97315ac 540 if(bmap[x].flags & BMCFLAG_16KCHRR)\r
541 CHRRAMSize = 16384;\r
386f5371 542 else if(bmap[x].flags & BMCFLAG_32KCHRR)\r
543 CHRRAMSize = 32768;\r
544 else if(bmap[x].flags & BMCFLAG_EXPCHRR)\r
545 CHRRAMSize = 128 * 1024;\r
d97315ac 546 else\r
386f5371 547 CHRRAMSize = 8192;\r
548 if((UNIFchrrama=(uint8 *)FCEU_malloc(CHRRAMSize)))\r
549 {\r
550 SetupCartCHRMapping(0,UNIFchrrama,CHRRAMSize,1);\r
551 AddExState(UNIFchrrama, CHRRAMSize, 0,"CHRR");\r
552 }\r
553 else\r
554 return(-1);\r
555 }\r
556 if(bmap[x].flags&BMCFLAG_FORCE4)\r
557 mirrortodo=4;\r
558 MooMirroring();\r
559 bmap[x].init(&UNIFCart);\r
560 return(1);\r
561 }\r
562 x++;\r
563 }\r
564 FCEU_PrintError("Board type not supported.");\r
565 return(0);\r
d97315ac 566}\r
567\r
c4980f9e 568static void UNIFGI(int h, void *param)\r
d97315ac 569{\r
386f5371 570 switch(h)\r
571 {\r
572 case GI_RESETSAVE:\r
573 //FCEU_ClearGameSave(&UNIFCart);\r
d97315ac 574 break;\r
386f5371 575\r
576 case GI_RESETM2:\r
577 if(UNIFCart.Reset)\r
578 UNIFCart.Reset();\r
579 break;\r
580 case GI_POWER:\r
581 if(UNIFCart.Power)\r
582 UNIFCart.Power();\r
d97315ac 583 if(UNIFchrrama) memset(UNIFchrrama,0,8192);\r
584 break;\r
386f5371 585 case GI_CLOSE:\r
586 FCEU_SaveGameSave(&UNIFCart);\r
d97315ac 587 if(UNIFCart.Close)\r
386f5371 588 UNIFCart.Close();\r
589 FreeUNIF();\r
590 break;\r
591 case GI_INFOSTRING:\r
c4980f9e 592 {\r
593 char board[24];\r
386f5371 594 strncpy(board, (char *)sboardname, 20);\r
c4980f9e 595 board[20] = 0;\r
596 sprintf(param, "UNIF, %s, %s%s", board, PAL?"PAL":"NTSC", UNIFCart.battery?", BB":"");\r
597 }\r
598 break;\r
386f5371 599 }\r
d97315ac 600}\r
601\r
602int UNIFLoad(const char *name, int fp)\r
603{\r
386f5371 604 FCEU_fseek(fp,0,SEEK_SET);\r
605 FCEU_fread(&unhead,1,4,fp);\r
606 if(memcmp(&unhead,"UNIF",4))\r
607 return 0;\r
d97315ac 608\r
609 ResetCartMapping();\r
610\r
386f5371 611 ResetExState(0,0);\r
612 ResetUNIF();\r
613 if(!FCEU_read32le(&unhead.info,fp))\r
614 goto aborto;\r
615 if(FCEU_fseek(fp,0x20,SEEK_SET)<0)\r
616 goto aborto;\r
617 if(!LoadUNIFChunks(fp))\r
618 goto aborto;\r
d97315ac 619 {\r
386f5371 620 int x;\r
621 struct md5_context md5;\r
622\r
623 md5_starts(&md5);\r
624\r
625 for(x=0;x<32;x++)\r
626 if(malloced[x])\r
627 {\r
628 md5_update(&md5,malloced[x],mallocedsizes[x]);\r
629 }\r
630 md5_finish(&md5,UNIFCart.MD5);\r
631 FCEU_printf(" ROM MD5: 0x");\r
632 for(x=0;x<16;x++)\r
633 FCEU_printf("%02x",UNIFCart.MD5[x]);\r
634 FCEU_printf("\n");\r
635 memcpy(&GameInfo->MD5,&UNIFCart.MD5,sizeof(UNIFCart.MD5));\r
d97315ac 636 }\r
637\r
386f5371 638 if(!InitializeBoard())\r
639 goto aborto;\r
d97315ac 640\r
641 FCEU_LoadGameSave(&UNIFCart);\r
d97315ac 642\r
386f5371 643 //strcpy(LoadedRomFName,name); //For the debugger list\r
644 GameInterface=UNIFGI;\r
645 return 1;\r
646\r
647aborto:\r
d97315ac 648\r
649 FreeUNIF();\r
650 ResetUNIF();\r
651\r
652\r
653 return 0;\r
654}\r