1 /* FCE Ultra - NES/Famicom Emulator
3 * Copyright notice for this file:
4 * Copyright (C) 1998 BERO
5 * Copyright (C) 2002 Ben Parnell
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #define MMC1_reg mapbyte1
25 #define MMC1_buf mapbyte2[0]
26 #define MMC1_sft mapbyte3[0]
31 uint8 MMC1WRAMsize; /* For use in iNES.c */
35 if(!(MMC1_reg[3]&0x10))
36 Page[A>>11][A]=V; // WRAM is enabled.
42 return X.DB; // WRAM is disabled
43 return(Page[A>>11][A]);
46 static void MMC1CHR(void)
51 setprg8r(0x10,0x6000,(MMC1_reg[1]>>4)&1);
53 setprg8r(0x10,0x6000,(MMC1_reg[1]>>3)&1);
59 setchr4(0x0000,MMC1_reg[1]);
60 setchr4(0x1000,MMC1_reg[2]);
63 setchr8(MMC1_reg[1]>>1);
66 static void MMC1PRG(void)
70 offs=MMC1_reg[1]&0x10;
71 switch(MMC1_reg[0]&0xC)
73 case 0xC: setprg16(0x8000,(MMC1_reg[3]+offs));
74 setprg16(0xC000,0xF+offs);
76 case 0x8: setprg16(0xC000,(MMC1_reg[3]+offs));
77 setprg16(0x8000,offs);
81 setprg16(0x8000,((MMC1_reg[3]&~1)+offs));
82 setprg16(0xc000,((MMC1_reg[3]&~1)+offs+1));
87 static void MMC1MIRROR(void)
91 case 2: setmirror(MI_V);break;
92 case 3: setmirror(MI_H);break;
93 case 0: setmirror(MI_0);break;
94 case 1: setmirror(MI_1);break;
100 static DECLFW(MMC1_write)
103 //FCEU_DispMessage("%016x",timestampbase+timestamp);
104 //printf("$%04x:$%02x, $%04x\n",A,V,X.PC);
105 //DumpMem("out",0xe000,0xffff);
107 /* The MMC1 is busy so ignore the write. */
108 /* As of version FCE Ultra 0.81, the timestamp is only
109 increased before each instruction is executed(in other words
110 precision isn't that great), but this should still work to
111 deal with 2 writes in a row from a single RMW instruction.
113 if( (timestampbase+timestamp)<(lreset+2))
120 lreset=timestampbase+timestamp;
124 MMC1_buf|=(V&1)<<(MMC1_sft++);
127 MMC1_reg[n]=MMC1_buf;
128 MMC1_sft = MMC1_buf=0;
150 static void MMC1_Restore(int version)
157 static void MMC1CMReset(void)
163 MMC1_sft = MMC1_buf =0;
167 MMC1_reg[2]=0; // Should this be something other than 0?
175 void DetectMMC1WRAMSize(void)
177 switch(iNESGameCRC32)
179 default:MMC1WRAMsize=1;break;
180 case 0xc6182024: /* Romance of the 3 Kingdoms */
181 case 0x2225c20f: /* Genghis Khan */
182 case 0x4642dda6: /* Nobunaga's Ambition */
183 case 0x29449ba9: /* "" "" (J) */
184 case 0x2b11e0b0: /* "" "" (J) */
190 void Mapper1_init(void)
195 SetWriteHandler(0x8000,0xFFFF,MMC1_write);
196 MapStateRestore=MMC1_Restore;
197 AddExState(&lreset, 8, 1, "LRST");
200 SetupCartCHRMapping(0, CHRRAM, 8192, 1);
205 SetupCartPRGMapping(0x10,WRAM,MMC1WRAMsize*8192,1);
206 SetReadHandler(0x6000,0x7FFF,MAWRAM);
207 SetWriteHandler(0x6000,0x7FFF,MBWRAM);
208 setprg8r(0x10,0x6000,0);
211 static void GenMMC1Close(void)
213 UNIFOpenWRAM(UOW_WR,0,0);
214 UNIFWriteWRAM(WRAM+((mmc1opts&4)?8192:0),8192);
219 static void GenMMC1Power(void)
224 FCEU_CheatAddRAM(8,0x6000,WRAM);
226 FCEU_dwmemset(WRAM,0,8192)
227 else if(!(mmc1opts&2))
228 FCEU_dwmemset(WRAM,0,8192);
230 SetWriteHandler(0x8000,0xFFFF,MMC1_write);
231 SetReadHandler(0x8000,0xFFFF,CartBR);
235 SetReadHandler(0x6000,0x7FFF,MAWRAM);
236 SetWriteHandler(0x6000,0x7FFF,MBWRAM);
237 setprg8r(0x10,0x6000,0);
243 static void GenMMC1Init(int prg, int chr, int wram, int battery)
246 PRGmask16[0]&=(prg>>14)-1;
247 CHRmask4[0]&=(chr>>12)-1;
248 CHRmask8[0]&=(chr>>13)-1;
253 if(wram>8) mmc1opts|=4;
254 SetupCartPRGMapping(0x10,WRAM,wram*1024,1);
255 AddExState(WRAM, wram*1024, 0, "WRAM");
258 if(battery && UNIFbattery)
261 BoardClose=GenMMC1Close;
263 UNIFOpenWRAM(UOW_RD,0,0);
264 UNIFReadWRAM(WRAM+((mmc1opts&4)?8192:0),8192);
271 SetupCartCHRMapping(0, CHRRAM, 8192, 1);
272 AddExState(CHRRAM, 8192, 0, "CHRR");
274 AddExState(mapbyte1, 32, 0, "MPBY");
275 BoardPower=GenMMC1Power;
277 GameStateRestore=MMC1_Restore;
278 AddExState(&lreset, 8, 1, "LRST");
281 //static void GenMMC1Init(int prg, int chr, int wram, int battery)
282 void SAROM_Init(void)
284 GenMMC1Init(128, 64, 8, 1);
287 void SBROM_Init(void)
289 GenMMC1Init(128, 64, 0, 0);
292 void SCROM_Init(void)
294 GenMMC1Init(128, 128, 0, 0);
297 void SEROM_Init(void)
299 GenMMC1Init(32, 64, 0, 0);
302 void SGROM_Init(void)
304 GenMMC1Init(256, 0, 0, 0);
307 void SKROM_Init(void)
309 GenMMC1Init(256, 64, 8, 1);
312 void SLROM_Init(void)
314 GenMMC1Init(256, 128, 0, 0);
317 void SL1ROM_Init(void)
319 GenMMC1Init(128, 128, 0, 0);
322 /* Begin unknown - may be wrong - perhaps they use different MMC1s from the
323 similarly functioning boards?
326 void SL2ROM_Init(void)
328 GenMMC1Init(256, 256, 0, 0);
331 void SFROM_Init(void)
333 GenMMC1Init(256, 256, 0, 0);
336 void SHROM_Init(void)
338 GenMMC1Init(256, 256, 0, 0);
345 void SNROM_Init(void)
347 GenMMC1Init(256, 0, 8, 1);
350 void SOROM_Init(void)
352 GenMMC1Init(256, 0, 16, 1);