1 /* FCE Ultra - NES/Famicom Emulator
\r
3 * Copyright notice for this file:
\r
4 * Copyright (C) 2002 Xodnizel
\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
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
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
23 static uint8 latche, latcheinit, bus_conflict;
\r
24 static uint16 addrreg0, addrreg1;
\r
25 static uint8 *WRAM=NULL;
\r
26 static uint32 WRAMSIZE;
\r
27 static void(*WSync)(void);
\r
29 static DECLFW(LatchWrite)
\r
31 // FCEU_printf("bs %04x %02x\n",A,V);
\r
39 static void LatchPower(void)
\r
43 SetReadHandler(0x6000,0xFFFF,CartBR);
\r
44 SetWriteHandler(0x6000,0x7FFF,CartBW);
\r
45 SetWriteHandler(addrreg0,addrreg1,LatchWrite);
\r
48 static void LatchClose(void)
\r
55 static void StateRestore(int version)
\r
60 static void Latch_Init(CartInfo *info, void (*proc)(void), uint8 init, uint16 adr0, uint16 adr1, uint8 wram, uint8 busc)
\r
62 bus_conflict = busc;
\r
67 info->Power=LatchPower;
\r
68 info->Close=LatchClose;
\r
69 GameStateRestore=StateRestore;
\r
73 WRAM=(uint8*)FCEU_gmalloc(WRAMSIZE);
\r
74 SetupCartPRGMapping(0x10,WRAM,WRAMSIZE,1);
\r
77 info->SaveGame[0]=WRAM;
\r
78 info->SaveGameLen[0]=WRAMSIZE;
\r
80 AddExState(WRAM, WRAMSIZE, 0, "WRAM");
\r
82 AddExState(&latche, 1, 0, "LATC");
\r
85 //------------------ Map 0 ---------------------------
\r
88 static DECLFW(NROMWrite)
\r
90 FCEU_printf("bs %04x %02x\n",A,V);
\r
95 static void NROMPower(void)
\r
97 setprg8r(0x10,0x6000,0); // Famili BASIC (v3.0) need it (uses only 4KB), FP-BASIC uses 8KB
\r
99 setprg16(0xC000,~0);
\r
102 SetReadHandler(0x6000,0x7FFF,CartBR);
\r
103 SetWriteHandler(0x6000,0x7FFF,CartBW);
\r
104 SetReadHandler(0x8000,0xFFFF,CartBR);
\r
106 #ifdef DEBUG_MAPPER
\r
107 SetWriteHandler(0x4020,0xFFFF,NROMWrite);
\r
111 void NROM_Init(CartInfo *info)
\r
113 info->Power=NROMPower;
\r
114 info->Close=LatchClose;
\r
117 WRAM=(uint8*)FCEU_gmalloc(WRAMSIZE);
\r
118 SetupCartPRGMapping(0x10,WRAM,WRAMSIZE,1);
\r
121 info->SaveGame[0]=WRAM;
\r
122 info->SaveGameLen[0]=WRAMSIZE;
\r
124 AddExState(WRAM, WRAMSIZE, 0, "WRAM");
\r
127 //------------------ Map 2 ---------------------------
\r
129 static void UNROMSync(void)
\r
131 static uint32 mirror_in_use = 0;
\r
132 setprg16(0x8000,latche&7);
\r
133 if(latche&8) mirror_in_use = 1;
\r
135 setmirror(((latche >> 3)&1)^1); // Higway Star Hacked mapper
\r
136 setprg16(0xc000,~0);
\r
140 void UNROM_Init(CartInfo *info)
\r
142 Latch_Init(info, UNROMSync, 0, 0x8000, 0xFFFF, 0, 1);
\r
145 //------------------ Map 3 ---------------------------
\r
147 static void CNROMSync(void)
\r
150 setprg32(0x8000,0);
\r
151 setprg8r(0x10,0x6000,0); // Hayauchy IGO uses 2Kb or RAM
\r
154 void CNROM_Init(CartInfo *info)
\r
156 Latch_Init(info, CNROMSync, 0, 0x8000, 0xFFFF, 1, 0);
\r
159 //------------------ Map 7 ---------------------------
\r
161 static void ANROMSync()
\r
163 setprg32(0x8000,latche&0xf);
\r
164 setmirror(MI_0+((latche>>4)&1));
\r
168 void ANROM_Init(CartInfo *info)
\r
170 Latch_Init(info, ANROMSync, 0, 0x8000, 0xFFFF, 0, 0);
\r
173 //------------------ Map 8 ---------------------------
\r
175 static void M8Sync()
\r
177 setprg16(0x8000,latche>>3);
\r
178 setprg16(0xc000,1);
\r
182 void Mapper8_Init(CartInfo *info)
\r
184 Latch_Init(info, M8Sync, 0, 0x8000, 0xFFFF, 0, 0);
\r
187 //------------------ Map 11 ---------------------------
\r
189 static void M11Sync(void)
\r
191 setprg32(0x8000,latche&0xf);
\r
192 setchr8(latche>>4);
\r
195 void Mapper11_Init(CartInfo *info)
\r
197 Latch_Init(info, M11Sync, 0, 0x8000, 0xFFFF, 0, 0);
\r
200 void Mapper144_Init(CartInfo *info)
\r
202 Latch_Init(info, M11Sync, 0, 0x8001, 0xFFFF, 0, 0);
\r
205 //------------------ Map 13 ---------------------------
\r
207 static void CPROMSync(void)
\r
210 setchr4(0x1000,latche&3);
\r
211 setprg32(0x8000,0);
\r
214 void CPROM_Init(CartInfo *info)
\r
216 Latch_Init(info, CPROMSync, 0, 0x8000, 0xFFFF, 0, 0);
\r
219 //------------------ Map 36 ---------------------------
\r
221 static void M36Sync(void)
\r
223 setprg32(0x8000,latche>>4);
\r
224 setchr8((latche)&0xF);
\r
227 void Mapper36_Init(CartInfo *info)
\r
229 Latch_Init(info, M36Sync, 0, 0x8400, 0xfffe, 0, 0);
\r
232 //------------------ Map 38 ---------------------------
\r
234 static void M38Sync(void)
\r
236 setprg32(0x8000,latche&3);
\r
237 setchr8(latche>>2);
\r
240 void Mapper38_Init(CartInfo *info)
\r
242 Latch_Init(info, M38Sync, 0, 0x7000, 0x7FFF, 0, 0);
\r
245 //------------------ Map 66 ---------------------------
\r
247 static void MHROMSync(void)
\r
249 setprg32(0x8000,latche>>4);
\r
250 setchr8(latche&0xf);
\r
253 void MHROM_Init(CartInfo *info)
\r
255 Latch_Init(info, MHROMSync, 0, 0x8000, 0xFFFF, 0, 0);
\r
258 //------------------ Map 70 ---------------------------
\r
260 static void M70Sync()
\r
262 setprg16(0x8000,latche>>4);
\r
263 setprg16(0xc000,~0);
\r
264 setchr8(latche&0xf);
\r
267 void Mapper70_Init(CartInfo *info)
\r
269 Latch_Init(info, M70Sync, 0, 0x8000, 0xFFFF, 0, 0);
\r
272 //------------------ Map 78 ---------------------------
\r
273 /* Should be two separate emulation functions for this "mapper". Sigh. URGE TO KILL RISING. */
\r
274 static void M78Sync()
\r
276 setprg16(0x8000,(latche&7));
\r
277 setprg16(0xc000,~0);
\r
278 setchr8(latche>>4);
\r
279 setmirror(MI_0+((latche>>3)&1));
\r
282 void Mapper78_Init(CartInfo *info)
\r
284 Latch_Init(info, M78Sync, 0, 0x8000, 0xFFFF, 0, 0);
\r
287 //------------------ Map 86 ---------------------------
\r
289 static void M86Sync(void)
\r
291 setprg32(0x8000,(latche >> 4) & 3);
\r
292 setchr8((latche & 3) | ((latche >> 4) & 4));
\r
295 void Mapper86_Init(CartInfo *info)
\r
297 Latch_Init(info, M86Sync, ~0, 0x6000, 0x6FFF, 0, 0);
\r
300 //------------------ Map 87 ---------------------------
\r
302 static void M87Sync(void)
\r
304 setprg32(0x8000,0);
\r
305 setchr8(((latche>>1)&1)|((latche<<1)&2));
\r
308 void Mapper87_Init(CartInfo *info)
\r
310 Latch_Init(info, M87Sync, ~0, 0x6000, 0xFFFF, 0, 0);
\r
313 //------------------ Map 89 ---------------------------
\r
315 static void M89Sync(void)
\r
317 setprg16(0x8000,(latche >> 4) & 7);
\r
318 setprg16(0xc000, ~0);
\r
319 setchr8((latche & 7) | ((latche >> 4) & 8));
\r
320 setmirror(MI_0 + ((latche >> 3) & 1));
\r
323 void Mapper89_Init(CartInfo *info)
\r
325 Latch_Init(info, M89Sync, 0, 0x8000, 0xFFFF, 0, 0);
\r
328 //------------------ Map 93 ---------------------------
\r
330 static void SSUNROMSync(void)
\r
332 setprg16(0x8000,latche>>4);
\r
333 setprg16(0xc000,~0);
\r
337 void SUNSOFT_UNROM_Init(CartInfo *info)
\r
339 Latch_Init(info, SSUNROMSync, 0, 0x8000, 0xFFFF, 0, 0);
\r
342 //------------------ Map 94 ---------------------------
\r
344 static void M94Sync(void)
\r
346 setprg16(0x8000,latche>>2);
\r
347 setprg16(0xc000,~0);
\r
351 void Mapper94_Init(CartInfo *info)
\r
353 Latch_Init(info, M94Sync, 0, 0x8000, 0xFFFF, 0, 0);
\r
356 //------------------ Map 97 ---------------------------
\r
358 static void M97Sync(void)
\r
361 setprg16(0x8000,~0);
\r
362 setprg16(0xc000,latche & 15);
\r
363 switch(latche >> 6)
\r
366 case 1: setmirror(MI_H); break;
\r
367 case 2: setmirror(MI_V); break;
\r
370 setchr8(((latche>>1)&1)|((latche<<1)&2));
\r
373 void Mapper97_Init(CartInfo *info)
\r
375 Latch_Init(info, M97Sync, ~0, 0x8000, 0xFFFF, 0, 0);
\r
378 //------------------ Map 101 ---------------------------
\r
380 static void M101Sync(void)
\r
382 setprg32(0x8000,0);
\r
386 void Mapper101_Init(CartInfo *info)
\r
388 Latch_Init(info, M101Sync, ~0, 0x6000, 0x7FFF, 0, 0);
\r
391 //------------------ Map 107 ---------------------------
\r
393 static void M107Sync(void)
\r
395 setprg32(0x8000,(latche>>1)&3);
\r
399 void Mapper107_Init(CartInfo *info)
\r
401 Latch_Init(info, M107Sync, ~0, 0x8000, 0xFFFF, 0, 0);
\r
404 //------------------ Map 113 ---------------------------
\r
406 static void M113Sync(void)
\r
408 setprg32(0x8000,(latche>>3)&7);
\r
409 setchr8(((latche>>3)&8)|(latche&7));
\r
410 // setmirror(latche>>7); // only for HES 6in1
\r
413 void Mapper113_Init(CartInfo *info)
\r
415 Latch_Init(info, M113Sync, 0, 0x4100, 0x7FFF, 0, 0);
\r
418 //------------------ Map 140 ---------------------------
\r
420 void Mapper140_Init(CartInfo *info)
\r
422 Latch_Init(info, MHROMSync, 0, 0x6000, 0x7FFF, 0, 0);
\r
425 //------------------ Map 152 ---------------------------
\r
427 static void M152Sync()
\r
429 setprg16(0x8000,(latche>>4)&7);
\r
430 setprg16(0xc000,~0);
\r
431 setchr8(latche&0xf);
\r
432 setmirror(MI_0+((latche>>7)&1)); /* Saint Seiya...hmm. */
\r
435 void Mapper152_Init(CartInfo *info)
\r
437 Latch_Init(info, M152Sync, 0, 0x8000, 0xFFFF, 0, 0);
\r
440 //------------------ Map 180 ---------------------------
\r
442 static void M180Sync(void)
\r
444 setprg16(0x8000,0);
\r
445 setprg16(0xc000,latche);
\r
449 void Mapper180_Init(CartInfo *info)
\r
451 Latch_Init(info, M180Sync, 0, 0x8000, 0xFFFF, 0, 0);
\r
454 //------------------ Map 184 ---------------------------
\r
456 static void M184Sync(void)
\r
458 setchr4(0x0000,latche);
\r
459 setchr4(0x1000,latche>>4);
\r
460 setprg32(0x8000,0);
\r
463 void Mapper184_Init(CartInfo *info)
\r
465 Latch_Init(info, M184Sync, 0, 0x6000, 0x7FFF, 0, 0);
\r
468 //------------------ Map 240 ---------------------------
\r
470 void Mapper240_Init(CartInfo *info)
\r
472 Latch_Init(info, MHROMSync, 0, 0x4020, 0x5FFF, 0, 0);
\r
476 //------------------ A65AS ---------------------------
\r
478 // actually, there is two cart in one... First have extra mirroring
\r
479 // mode (one screen) and 32K bankswitching, second one have only
\r
480 // 16 bankswitching mode and normal mirroring... But there is no any
\r
481 // correlations between modes and they can be used in one mapper code.
\r
483 static void BMCA65ASSync(void)
\r
486 setprg32(0x8000,(latche>>1)&0x0F);
\r
489 setprg16(0x8000,((latche&0x30)>>1)|(latche&7));
\r
490 setprg16(0xC000,((latche&0x30)>>1)|7);
\r
494 setmirror(MI_0+(((latche>>5)&1)));
\r
496 setmirror(((latche>>3)&1)^1);
\r
499 void BMCA65AS_Init(CartInfo *info)
\r
501 Latch_Init(info, BMCA65ASSync, 0, 0x8000, 0xFFFF, 0, 0);
\r