#include "mapinc.h"
#include "mmc3.h"
-uint8 MMC3_cmd=0;
-uint8 *WRAM=0;
-uint8 *CHRRAM=0;
-uint32 CHRRAMSize=0;
-uint8 EXPREGS[8]={0,0,0,0,0,0,0,0}; /* For bootleg games, mostly. */
+uint8 MMC3_cmd;
+uint8 *WRAM;
+uint8 *CHRRAM;
+uint32 CHRRAMSize;
+uint8 EXPREGS[8]; /* For bootleg games, mostly. */
-static uint8 A000B=0,A001B=0;
-static uint8 DRegBuf[8]={0,0,0,0,0,0,0,0};
+static uint8 A000B,A001B;
+static uint8 DRegBuf[8];
#undef IRQCount
#undef IRQLatch
#undef IRQa
-uint8 IRQCount=0,IRQLatch=0,IRQa=0;
-uint8 IRQReload=0;
+uint8 IRQCount,IRQLatch,IRQa;
+uint8 IRQReload;
static SFORMAT MMC3_StateRegs[]=
{
};
static int mmc3opts=0;
-static int wrams=0;
+static int wrams;
+static int isRevB=1;
void (*pwrap)(uint32 A, uint8 V);
void (*cwrap)(uint32 A, uint8 V);
DECLFW(MMC3_CMDWrite)
{
+// FCEU_printf("%04x:%04x\n",A,V);
switch(A&0xE001)
{
case 0x8000:
break;
case 0xA001:
A001B=V;
+ //Write_IRQFM(0x4017,0x40);
+ {
+ writefunc f = GetWriteHandler(0x4017);
+ f(0x4017,0x40);
+ }
break;
}
}
DECLFW(MMC3_IRQWrite)
{
+// FCEU_printf("%04x:%04x\n",A,V);
switch(A&0xE001)
{
case 0xC000:IRQLatch=V;break;
}
else
IRQCount--;
- if(count && !IRQCount)
+ if((count|isRevB) && !IRQCount)
{
if(IRQa)
{
ClockMMC3Counter();
}
-static void genmmc3restore(int version)
+void GenMMC3Restore(int version)
{
if(mwrap) mwrap(A000B&1);
FixMMC3PRG(MMC3_cmd);
static void GENCWRAP(uint32 A, uint8 V)
{
- setchr1(A,V);
+ if(!UNIFchrrama) setchr1(A,V);
}
static void GENPWRAP(uint32 A, uint8 V)
void GenMMC3Power(void)
{
+ if(UNIFchrrama) setchr8(0);
+
SetWriteHandler(0x8000,0xBFFF,MMC3_CMDWrite);
SetWriteHandler(0xC000,0xFFFF,MMC3_IRQWrite);
SetReadHandler(0x8000,0xFFFF,CartBR);
FCEU_CheatAddRAM(1,0x7000,WRAM);
SetReadHandler(0x7000,0x7FFF,MAWRAMMMC6);
SetWriteHandler(0x7000,0x7FFF,MBWRAMMMC6);
+#ifdef ASM_6502
+ // asm code needs pages to be set again..
+ Page[14]=Page[15]=WRAM-0x7000;
+#endif
}
else
{
FCEU_CheatAddRAM(wrams>>10,0x6000,WRAM);
SetReadHandler(0x6000,0x6000+wrams-1,MAWRAM);
SetWriteHandler(0x6000,0x6000+wrams-1,MBWRAM);
+#ifdef ASM_6502
+ {
+ int addr;
+ for (addr=0x6000; addr < 0x6000+wrams-0x7ff; addr += 0x800)
+ {
+ Page[addr>>11]=WRAM - 0x6000;
+ }
+ }
+#endif
}
if(!(mmc3opts&2))
FCEU_dwmemset(WRAM,0,wrams);
CHRRAM=WRAM=NULL;
}
+//static uint16 _a12;
+//static void FP_FASTAPASS(1) MMC3_PPU(uint32 A)
+//{
+// if(A&0x2000)return;
+// if((!_a12)&&(A&0x1000))
+// ClockMMC3Counter();
+// _a12=A&0x1000;
+//}
+
void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery)
{
-pwrap=GENPWRAP;
+ pwrap=GENPWRAP;
cwrap=GENCWRAP;
mwrap=GENMWRAP;
info->SaveGameLen[0]=wrams;
}
- if(!chr)
- {
- CHRRAM=(uint8*)FCEU_gmalloc(8192);
- CHRRAMSize=8192;
- SetupCartCHRMapping(0, CHRRAM, 8192, 1);
- AddExState(CHRRAM, 8192, 0, "CHRR");
- }
+// if(!chr) // duplicated CHR RAM set up
+// {
+// CHRRAM=(uint8*)FCEU_gmalloc(8192);
+// CHRRAMSize=8192;
+// SetupCartCHRMapping(0, CHRRAM, 8192, 1);
+// AddExState(CHRRAM, 8192, 0, "CHRR");
+// }
AddExState(MMC3_StateRegs, ~0, 0, 0);
else if(info->CRC32 == 0xfcd772eb) // PAL Star Wars, similar problem as Kick Master.
GameHBIRQHook = MMC3_hb_PALStarWarsHack;
else
- GameHBIRQHook=MMC3_hb;
- GameStateRestore=genmmc3restore;
+ GameHBIRQHook=MMC3_hb;
+// PPU_hook=MMC3_PPU;
+ GameStateRestore=GenMMC3Restore;
}
// ----------------------------------------------------------------------
AddExState(EXPREGS, 2, 0, "EXPR");
}
+// ---------------------------- Mapper 37 -------------------------------
+
+static void M37PW(uint32 A, uint8 V)
+{
+ if(EXPREGS[0]!=2)
+ V&=0x7;
+ else
+ V&=0xF;
+ V|=EXPREGS[0]<<3;
+ setprg8(A,V);
+}
+
+static void M37CW(uint32 A, uint8 V)
+{
+ uint32 NV=V;
+ NV&=0x7F;
+ NV|=EXPREGS[0]<<6;
+ setchr1(A,NV);
+}
+
+static DECLFW(M37Write)
+{
+ EXPREGS[0]=(V&6)>>1;
+ FixMMC3PRG(MMC3_cmd);
+ FixMMC3CHR(MMC3_cmd);
+}
+
+static void M37Reset(void)
+{
+ EXPREGS[0]=0;
+ MMC3RegReset();
+}
+
+static void M37Power(void)
+{
+ EXPREGS[0]=0;
+ GenMMC3Power();
+ SetWriteHandler(0x6000,0x7FFF,M37Write);
+}
+
+void Mapper37_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 256, 8, info->battery);
+ pwrap=M37PW;
+ cwrap=M37CW;
+ info->Power=M37Power;
+ info->Reset=M37Reset;
+ AddExState(EXPREGS, 1, 0, "EXPR");
+}
+
// ---------------------------- Mapper 44 -------------------------------
static void M44PW(uint32 A, uint8 V)
static void M45CW(uint32 A, uint8 V)
{
- uint32 NV=V;
- if(EXPREGS[2]&8)
- NV&=(1<<((EXPREGS[2]&7)+1))-1;
- else
- NV&=0;
- NV|=EXPREGS[0]|((EXPREGS[2]&0xF0)<<4);
- // &0x10(not 0xf0) is valid given the original
- // description of mapper 45 by kevtris,
- // but this fixes Super 8 in 1.
- setchr1(A,NV);
+ if(!UNIFchrrama)
+ {
+ uint32 NV=V;
+ if(EXPREGS[2]&8)
+ NV&=(1<<((EXPREGS[2]&7)+1))-1;
+// else
+// NV&=0;
+ NV|=EXPREGS[0]|((EXPREGS[2]&0xF0)<<4);
+ setchr1(A,NV);
+ }
}
static void M45PW(uint32 A, uint8 V)
}
EXPREGS[EXPREGS[4]]=V;
EXPREGS[4]=(EXPREGS[4]+1)&3;
-// FCEU_printf("write 0=%04x 1=%04x 2=%04x 3=%04x (%04x:%04x)\n",EXPREGS[0],EXPREGS[1],EXPREGS[2],EXPREGS[3],A,V);
+ if(!EXPREGS[4])
+ {
+ FCEU_printf("CHROR %02x, PRGOR %02x, CHRAND %02x, PRGAND %02x\n",EXPREGS[0],EXPREGS[1],EXPREGS[2],EXPREGS[3]);
+ FCEU_printf("CHR0 %03x, CHR1 %03x, PRG0 %03x, PRG1 %03x\n",
+ (0x00&((1<<((EXPREGS[2]&7)+1))-1))|(EXPREGS[0]|((EXPREGS[2]&0xF0)<<4)),
+ (0xFF&((1<<((EXPREGS[2]&7)+1))-1))|(EXPREGS[0]|((EXPREGS[2]&0xF0)<<4)),
+ (0x00&((EXPREGS[3]&0x3F)^0x3F))|(EXPREGS[1]),
+ (0xFF&((EXPREGS[3]&0x3F)^0x3F))|(EXPREGS[1]));
+ }
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
static void M45Reset(void)
{
- FCEU_dwmemset(EXPREGS,0,5);
+ EXPREGS[0]=EXPREGS[1]=EXPREGS[2]=EXPREGS[3]=EXPREGS[4]=0;
MMC3RegReset();
}
static void M45Power(void)
{
- M45Reset();
+ setchr8(0);
GenMMC3Power();
SetWriteHandler(0x6000,0x7FFF,M45Write);
}
EXPREGS[0]=0;
GenMMC3Power();
SetWriteHandler(0x6000,0x7FFF,M47Write);
- SetReadHandler(0x6000,0x7FFF,0);
+// SetReadHandler(0x6000,0x7FFF,0);
}
void Mapper47_Init(CartInfo *info)
static void M74CW(uint32 A, uint8 V)
{
-// FCEU_printf("%04x:%04x\n",A,V);
-// if((V==0)||(V==1)) //Dai-2-Ji - Super Robot Taisen (As).nes
- if((V==0)||(V==1)||(V==2)||(V==3)) //Ying Lie Qun Xia Zhuan (Chinese).nes, 4096 CHR RAM
-// if((V==8)||(V==9)) //Di 4 Ci - Ji Qi Ren Dai Zhan (As).nes
-// if((V==8)||(V==9)||(V==0xA)||(V==0xB)) //Ying Lie Qun Xia Zhuan (Chinese).nes, 4096 CHR RAM
- setchr1r(0x10,A,V);
+ if((V==8)||(V==9)) //Di 4 Ci - Ji Qi Ren Dai Zhan (As).nes, Ji Jia Zhan Shi (As).nes
+ setchr1r(0x10,A,V);
else
- setchr1r(0x0,A,V);
+ setchr1r(0,A,V);
}
void Mapper74_Init(CartInfo *info)
{
GenMMC3_Init(info, 512, 256, 8, info->battery);
cwrap=M74CW;
-// CHRRAMSize=2048;
- CHRRAMSize=4096;
+ CHRRAMSize=2048;
CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
if(A==0xE003)
{
IRQa=1;
- IRQCount=V;
+ IRQLatch=V;
+ IRQReload=1;
}
else if(A==0xE002)
{
static void M115PW(uint32 A, uint8 V)
{
- setprg8(A,V);
- if(EXPREGS[0]&0x80)
- setprg16(0x8000,EXPREGS[0]&7);
+ if(EXPREGS[0]&0x80)
+ setprg32(0x8000,(EXPREGS[0]&7)>>1);
+ else
+ setprg8(A,V);
}
static void M115CW(uint32 A, uint8 V)
{
- setchr1(A,(uint32)V|((EXPREGS[1]&1)<<8));
+ setchr1(A,(uint32)V|((EXPREGS[1]&1)<<8));
}
static DECLFW(M115Write)
static void M116CW(uint32 A, uint8 V)
{
- setchr1(A,V|((EXPREGS[0]&0x4)<<6));
+// setchr1(A,V|((EXPREGS[0]&0x4)<<6));
+ if(EXPREGS[0]&2)
+ setchr8r(0x10,0);
+ else
+ setchr1(A,V);
}
static DECLFW(M116Write)
{
EXPREGS[0]=V;
- FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
GenMMC3_Init(info, 128, 512, 0, 0);
cwrap=M116CW;
info->Power=M116Power;
+ CHRRAM = (uint8*)FCEU_gmalloc(8192);
+ SetupCartCHRMapping(0x10, CHRRAM, 8192, 1);
AddExState(EXPREGS, 4, 0, "EXPR");
}
SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
}
-// ---------------------------- Mapper 191 ------------------------------
-
-static void M191CW(uint32 A, uint8 V)
-{
- setchr1r((V&0x80)>>3,A,V);
-}
-
-void Mapper191_Init(CartInfo *info)
-{
- GenMMC3_Init(info, 256, 256, 8, info->battery);
- cwrap=M191CW;
- CHRRAMSize=2048;
- CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
- SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
- AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
-}
-
// ---------------------------- Mapper 165 ------------------------------
static void M165CW(uint32 A, uint8 V)
static void M165CWM(uint32 A, uint8 V)
{
- if(((MMC3_cmd&0x7)==0)||((MMC3_cmd&0x7)==2)) M165PPUFD();
- if(((MMC3_cmd&0x7)==1)||((MMC3_cmd&0x7)==4)) M165PPUFE();
+ if(((MMC3_cmd&0x7)==0)||((MMC3_cmd&0x7)==2))
+ M165PPUFD();
+ if(((MMC3_cmd&0x7)==1)||((MMC3_cmd&0x7)==4))
+ M165PPUFE();
}
static void FP_FASTAPASS(1) M165PPU(uint32 A)
case 0x8001: setmirror((V&1)^1); break;
case 0xA000: MMC3_CMDWrite(0x8000,m114_perm[V&7]); break;
case 0xC000: MMC3_CMDWrite(0x8001,V); break;
- case 0xE003: IRQCount=V; IRQa=1; X6502_IRQEnd(FCEU_IQEXT); break;
+ case 0xE003: if(V)
+ {
+ IRQLatch=V;
+ IRQReload=1;
+ IRQa=1;
+ }
+ X6502_IRQEnd(FCEU_IQEXT);
+ break;
}
}
info->Power=M182Power;
}
+// ---------------------------- Mapper 191 ------------------------------
+
+static void M191CW(uint32 A, uint8 V)
+{
+ setchr1r((V&0x80)>>3,A,V);
+}
+
+void Mapper191_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 256, 256, 8, info->battery);
+ cwrap=M191CW;
+ CHRRAMSize=2048;
+ CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
+ SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
+ AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
+}
+
+// ---------------------------- Mapper 192 -------------------------------
+
+static void M192CW(uint32 A, uint8 V)
+{
+ if((V==8)||(V==9)||(V==0xA)||(V==0xB)) //Ying Lie Qun Xia Zhuan (Chinese),
+ setchr1r(0x10,A,V);
+ else
+ setchr1r(0,A,V);
+}
+
+void Mapper192_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 256, 8, info->battery);
+ cwrap=M192CW;
+ CHRRAMSize=4096;
+ CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
+ SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
+ AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
+}
+
+// ---------------------------- Mapper 194 -------------------------------
+
+static void M194CW(uint32 A, uint8 V)
+{
+ if(V<=1) //Dai-2-Ji - Super Robot Taisen (As).nes
+ setchr1r(0x10,A,V);
+ else
+ setchr1r(0,A,V);
+}
+
+void Mapper194_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 256, 8, info->battery);
+ cwrap=M194CW;
+ CHRRAMSize=2048;
+ CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
+ SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
+ AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
+}
+
+// ---------------------------- Mapper 198 -------------------------------
+
+static uint8 *wramtw;
+static uint16 wramsize;
+static void M198CW(uint32 A, uint8 V)
+{
+ if(V<=3) // Crystalis (c).nes, Captain Tsubasa Vol 2 - Super Striker (C)
+ setchr1r(0x10,A,V);
+ else
+ setchr1r(0,A,V);
+}
+
+static void M198Power(void)
+{
+ GenMMC3Power();
+ setprg4r(0x10,0x5000,0);
+ SetWriteHandler(0x5000,0x5fff,CartBW);
+ SetReadHandler(0x5000,0x5fff,CartBR);
+}
+
+static void M198Close(void)
+{
+ if(wramtw)
+ FCEU_gfree(wramtw);
+ wramtw=NULL;
+}
+
+void Mapper198_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 256, 8, info->battery);
+ cwrap=M198CW;
+ info->Power=M198Power;
+ info->Close=M198Close;
+ CHRRAMSize=4096;
+ CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
+ SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
+ wramsize=4096;
+ wramtw=(uint8*)FCEU_gmalloc(wramsize);
+ SetupCartPRGMapping(0x10, wramtw, wramsize, 1);
+ AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
+ AddExState(wramtw, wramsize, 0, "WRAMTW");
+}
+
+// ---------------------------- Mapper 199 -------------------------------
+
+static uint8 *wramtw;
+static uint16 wramsize;
+static void M199PW(uint32 A, uint8 V)
+{
+ if(V>=0x50)
+ setprg8(A,V&0x4F);
+ else
+ setprg8(A,V);
+}
+
+void Mapper199_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 1024, 256, 8, info->battery);
+ pwrap=M199PW;
+ info->Power=M198Power;
+ info->Close=M198Close;
+ wramsize=4096;
+ wramtw=(uint8*)FCEU_gmalloc(wramsize);
+ SetupCartPRGMapping(0x10, wramtw, wramsize, 1);
+ AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
+ AddExState(wramtw, wramsize, 0, "WRAMTW");
+}
+
// ---------------------------- Mapper 205 ------------------------------
static void M205PW(uint32 A, uint8 V)
static void M205CW(uint32 A, uint8 V)
{
- setchr1(A,V|((EXPREGS[0]&3)*128));
+ setchr1(A,V|((EXPREGS[0]&3)<<7));
}
static DECLFW(M205Write)
}
else switch(A&0xE001)
{
+ case 0xC001: IRQLatch=V; break;
+ case 0xA001: IRQReload=1; break;
+ case 0xE001: IRQa=1; break;
case 0xE000: X6502_IRQEnd(FCEU_IQEXT); IRQa=0; break;
- case 0xE001: IRQCount=V; break;
- case 0xC001: IRQa=1; break;
case 0xC000: setmirror(((V|(V>>7))&1)^1); break;
case 0xA000: MMC3_CMDWrite(0x8000,(V&0xC0)|(m215_perm[V&7])); cmdin=1; break;
case 0x8001: if(!cmdin) break;
if(!EXPREGS[2])
{
if(A >= 0xc000)
- MMC3_IRQWrite(A, V);
+ MMC3_IRQWrite(A, V);
else
- MMC3_CMDWrite(A,V);
+ MMC3_CMDWrite(A,V);
}
else switch(A&0xE001)
{
- case 0x8000: IRQCount=V; break;
- case 0xE000: X6502_IRQEnd(FCEU_IQEXT);IRQa=0; break;
- case 0xC001: IRQa=1; break;
- case 0xA001: setmirror((V&1)^1); break;
- case 0x8001: MMC3_CMDWrite(0x8000,(V&0xC0)|(m217_perm[V&7])); cmdin=1; break;
- case 0xA000: if(!cmdin) break;
- MMC3_CMDWrite(0x8001,V);
- cmdin=0;
- break;
+ case 0x8000: IRQCount=V; break;
+ case 0xE000: X6502_IRQEnd(FCEU_IQEXT);IRQa=0; break;
+ case 0xC001: IRQa=1; break;
+ case 0xA001: setmirror((V&1)^1); break;
+ case 0x8001: MMC3_CMDWrite(0x8000,(V&0xC0)|(m217_perm[V&7])); cmdin=1; break;
+ case 0xA000: if(!cmdin) break;
+ MMC3_CMDWrite(0x8001,V);
+ cmdin=0;
+ break;
}
}
GenMMC3Power();
SetWriteHandler(0x8000,0xBFFF,M254Write);
SetReadHandler(0x6000,0x7FFF,MR254WRAM);
+#ifdef ASM_6502
+ // hrrr.. can't handle those evil xors here..
+ Page[12]=Page[13]=Page[14]=Page[15]=WRAM-0x6000;
+#endif
}
void Mapper254_Init(CartInfo *info)