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);
58 setchr4(0x0000,MMC1_reg[1]);
59 setchr4(0x1000,MMC1_reg[2]);
62 setchr8(MMC1_reg[1]>>1);
65 static void MMC1PRG(void)
69 offs=MMC1_reg[1]&0x10;
70 switch(MMC1_reg[0]&0xC)
72 case 0xC: setprg16(0x8000,(MMC1_reg[3]+offs));
73 setprg16(0xC000,0xF+offs);
75 case 0x8: setprg16(0xC000,(MMC1_reg[3]+offs));
76 setprg16(0x8000,offs);
80 setprg16(0x8000,((MMC1_reg[3]&~1)+offs));
81 setprg16(0xc000,((MMC1_reg[3]&~1)+offs+1));
85 static void MMC1MIRROR(void)
89 case 2: setmirror(MI_V);break;
90 case 3: setmirror(MI_H);break;
91 case 0: setmirror(MI_0);break;
92 case 1: setmirror(MI_1);break;
98 static DECLFW(MMC1_write)
101 //FCEU_DispMessage("%016x",timestampbase+timestamp);
102 //printf("$%04x:$%02x, $%04x\n",A,V,X.PC);
103 //DumpMem("out",0xe000,0xffff);
105 /* The MMC1 is busy so ignore the write. */
106 /* As of version FCE Ultra 0.81, the timestamp is only
107 increased before each instruction is executed(in other words
108 precision isn't that great), but this should still work to
109 deal with 2 writes in a row from a single RMW instruction.
111 if( (timestampbase+timestamp)<(lreset+2))
118 lreset=timestampbase+timestamp;
122 MMC1_buf|=(V&1)<<(MMC1_sft++);
125 MMC1_reg[n]=MMC1_buf;
126 MMC1_sft = MMC1_buf=0;
148 static void MMC1_Restore(int version)
155 static void MMC1CMReset(void)
161 MMC1_sft = MMC1_buf =0;
165 MMC1_reg[2]=0; // Should this be something other than 0?
173 void DetectMMC1WRAMSize(void)
175 switch(iNESGameCRC32)
177 default:MMC1WRAMsize=1;break;
178 case 0xc6182024: /* Romance of the 3 Kingdoms */
179 case 0x2225c20f: /* Genghis Khan */
180 case 0x4642dda6: /* Nobunaga's Ambition */
181 case 0x29449ba9: /* "" "" (J) */
182 case 0x2b11e0b0: /* "" "" (J) */
188 void Mapper1_init(void)
193 SetWriteHandler(0x8000,0xFFFF,MMC1_write);
194 MapStateRestore=MMC1_Restore;
195 AddExState(&lreset, 8, 1, "LRST");
198 SetupCartCHRMapping(0, CHRRAM, 8192, 1);
203 SetupCartPRGMapping(0x10,WRAM,MMC1WRAMsize*8192,1);
204 SetReadHandler(0x6000,0x7FFF,MAWRAM);
205 SetWriteHandler(0x6000,0x7FFF,MBWRAM);
206 setprg8r(0x10,0x6000,0);
209 static void GenMMC1Close(void)
211 UNIFOpenWRAM(UOW_WR,0,0);
212 UNIFWriteWRAM(WRAM+((mmc1opts&4)?8192:0),8192);
217 static void GenMMC1Power(void)
222 FCEU_CheatAddRAM(8,0x6000,WRAM);
224 FCEU_dwmemset(WRAM,0,8192)
225 else if(!(mmc1opts&2))
226 FCEU_dwmemset(WRAM,0,8192);
228 SetWriteHandler(0x8000,0xFFFF,MMC1_write);
229 SetReadHandler(0x8000,0xFFFF,CartBR);
233 SetReadHandler(0x6000,0x7FFF,MAWRAM);
234 SetWriteHandler(0x6000,0x7FFF,MBWRAM);
235 setprg8r(0x10,0x6000,0);
241 static void GenMMC1Init(int prg, int chr, int wram, int battery)
244 PRGmask16[0]&=(prg>>14)-1;
245 CHRmask4[0]&=(chr>>12)-1;
246 CHRmask8[0]&=(chr>>13)-1;
251 if(wram>8) mmc1opts|=4;
252 SetupCartPRGMapping(0x10,WRAM,wram*1024,1);
253 AddExState(WRAM, wram*1024, 0, "WRAM");
256 if(battery && UNIFbattery)
259 BoardClose=GenMMC1Close;
261 UNIFOpenWRAM(UOW_RD,0,0);
262 UNIFReadWRAM(WRAM+((mmc1opts&4)?8192:0),8192);
269 SetupCartCHRMapping(0, CHRRAM, 8192, 1);
270 AddExState(CHRRAM, 8192, 0, "CHRR");
272 AddExState(mapbyte1, 32, 0, "MPBY");
273 BoardPower=GenMMC1Power;
275 GameStateRestore=MMC1_Restore;
276 AddExState(&lreset, 8, 1, "LRST");
279 //static void GenMMC1Init(int prg, int chr, int wram, int battery)
280 void SAROM_Init(void)
282 GenMMC1Init(128, 64, 8, 1);
285 void SBROM_Init(void)
287 GenMMC1Init(128, 64, 0, 0);
290 void SCROM_Init(void)
292 GenMMC1Init(128, 128, 0, 0);
295 void SEROM_Init(void)
297 GenMMC1Init(32, 64, 0, 0);
300 void SGROM_Init(void)
302 GenMMC1Init(256, 0, 0, 0);
305 void SKROM_Init(void)
307 GenMMC1Init(256, 64, 8, 1);
310 void SLROM_Init(void)
312 GenMMC1Init(256, 128, 0, 0);
315 void SL1ROM_Init(void)
317 GenMMC1Init(128, 128, 0, 0);
320 /* Begin unknown - may be wrong - perhaps they use different MMC1s from the
321 similarly functioning boards?
324 void SL2ROM_Init(void)
326 GenMMC1Init(256, 256, 0, 0);
329 void SFROM_Init(void)
331 GenMMC1Init(256, 256, 0, 0);
334 void SHROM_Init(void)
336 GenMMC1Init(256, 256, 0, 0);
343 void SNROM_Init(void)
345 GenMMC1Init(256, 0, 8, 1);
348 void SOROM_Init(void)
350 GenMMC1Init(256, 0, 16, 1);