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 |
44 | typedef struct {\r |
386f5371 |
45 | char ID[4];\r |
46 | uint32 info;\r |
d97315ac |
47 | } UNIF_HEADER;\r |
48 | \r |
49 | typedef struct {\r |
386f5371 |
50 | char *name;\r |
51 | void (*init)(CartInfo *);\r |
52 | int flags;\r |
d97315ac |
53 | } BMAPPING;\r |
54 | \r |
55 | typedef struct {\r |
386f5371 |
56 | char *name;\r |
57 | int (*init)(int fp);\r |
d97315ac |
58 | } BFMAPPING;\r |
59 | \r |
60 | static CartInfo UNIFCart;\r |
61 | \r |
62 | static int vramo;\r |
63 | static int mirrortodo;\r |
386f5371 |
64 | static uint8 *boardname;\r |
65 | static uint8 *sboardname;\r |
d97315ac |
66 | \r |
67 | static uint32 CHRRAMSize;\r |
68 | uint8 *UNIFchrrama=0;\r |
69 | \r |
70 | static UNIF_HEADER unhead;\r |
71 | static UNIF_HEADER uchead;\r |
72 | \r |
73 | \r |
74 | static uint8 *malloced[32];\r |
75 | static uint32 mallocedsizes[32];\r |
76 | \r |
77 | static 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 |
88 | static 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 |
102 | static 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 |
114 | static uint8 exntar[2048];\r |
115 | \r |
116 | static 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 |
129 | static 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 |
143 | static 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 |
166 | static 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 |
196 | static 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 |
215 | static 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 |
238 | static 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 |
247 | static 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 |
274 | static 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 |
287 | static 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 |
319 | static 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 |
480 | static 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 |
493 | int 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 |
528 | static 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 |
568 | static 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 |
602 | int 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 |
647 | aborto:\r |
d97315ac |
648 | \r |
649 | FreeUNIF();\r |
650 | ResetUNIF();\r |
651 | \r |
652 | \r |
653 | return 0;\r |
654 | }\r |