merge mappers from FCEU-mm
[fceu.git] / boards / mmc3.c
index 14ce5cb..6d3af95 100644 (file)
  */
 
 /*  Code for emulating iNES mappers 4,12,44,45,47,49,52,74,114,115,116,118,
-    119,148,165,205,214,215,245,249,250,254
+    119,165,205,245,249,250,254
 */
 
 #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. */
-
-static uint8 A000B=0,A001B=0;
-static uint8 DRegBuf[8]={0,0,0,0,0,0,0,0};
+uint8 MMC3_cmd;
+uint8 *WRAM;
+uint8 *CHRRAM;
+uint32 CHRRAMSize;
+uint8 DRegBuf[8];
+uint8 EXPREGS[8];    /* For bootleg games, mostly. */
+uint8 A000B,A001B;
+int mmc3opts=0;
 
 #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[]=
 {
@@ -55,8 +55,8 @@ static SFORMAT MMC3_StateRegs[]=
  {0}
 };
 
-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);
@@ -101,6 +101,8 @@ void FixMMC3CHR(int V)
  cwrap(cbase^0x1400,DRegBuf[3]);
  cwrap(cbase^0x1800,DRegBuf[4]);
  cwrap(cbase^0x1c00,DRegBuf[5]);
+
+ if(mwrap) mwrap(A000B);
 }
 
 void MMC3RegReset(void)
@@ -122,6 +124,7 @@ void MMC3RegReset(void)
 
 DECLFW(MMC3_CMDWrite)
 {
+// FCEU_printf("bs %04x %02x\n",A,V);
  switch(A&0xE001)
  {
   case 0x8000:
@@ -164,7 +167,7 @@ DECLFW(MMC3_CMDWrite)
        }
        break;
   case 0xA000:
-       if(mwrap) mwrap(V&1);
+       if(mwrap) mwrap(V);
        break;
   case 0xA001:
        A001B=V;
@@ -174,6 +177,7 @@ DECLFW(MMC3_CMDWrite)
 
 DECLFW(MMC3_IRQWrite)
 {
+// FCEU_printf("%04x:%04x\n",A,V);
  switch(A&0xE001)
  {
   case 0xC000:IRQLatch=V;break;
@@ -193,7 +197,7 @@ static void ClockMMC3Counter(void)
  }
  else
     IRQCount--;
- if(count && !IRQCount)
+ if((count|isRevB) && !IRQCount)
  {
     if(IRQa)
     {
@@ -219,27 +223,26 @@ static void MMC3_hb_PALStarWarsHack(void)
  ClockMMC3Counter();
 }
 
-static void genmmc3restore(int version)
+void GenMMC3Restore(int version)
 {
- if(mwrap) mwrap(A000B&1);
  FixMMC3PRG(MMC3_cmd);
  FixMMC3CHR(MMC3_cmd);
 }
 
 static void GENCWRAP(uint32 A, uint8 V)
 {
- setchr1(A,V);
+   setchr1(A,V);    // Business Wars NEEDS THIS for 8K CHR-RAM
 }
 
 static void GENPWRAP(uint32 A, uint8 V)
 {
- setprg8(A,V&0x3F);
+ setprg8(A,V&0x7F); // [NJ102] Mo Dao Jie (C) has 1024Mb MMC3 BOARD, maybe something other will be broken
 }
 
 static void GENMWRAP(uint8 V)
 {
  A000B=V;
- setmirror(V^1);
+ setmirror((V&1)^1);
 }
 
 static void GENNOMWRAP(uint8 V)
@@ -247,16 +250,6 @@ static void GENNOMWRAP(uint8 V)
  A000B=V;
 }
 
-static DECLFW(MBWRAM)
-{
-  WRAM[A-0x6000]=V;
-}
-
-static DECLFR(MAWRAM)
-{
- return(WRAM[A-0x6000]);
-}
-
 static DECLFW(MBWRAMMMC6)
 {
  WRAM[A&0x3ff]=V;
@@ -269,6 +262,8 @@ static DECLFR(MAWRAMMMC6)
 
 void GenMMC3Power(void)
 {
+ if(UNIFchrrama) setchr8(0);
+
  SetWriteHandler(0x8000,0xBFFF,MMC3_CMDWrite);
  SetWriteHandler(0xC000,0xFFFF,MMC3_IRQWrite);
  SetReadHandler(0x8000,0xFFFF,CartBR);
@@ -284,16 +279,17 @@ void GenMMC3Power(void)
   }
   else
   {
-   FCEU_CheatAddRAM(wrams>>10,0x6000,WRAM);
-   SetReadHandler(0x6000,0x6000+wrams-1,MAWRAM);
-   SetWriteHandler(0x6000,0x6000+wrams-1,MBWRAM);
+   FCEU_CheatAddRAM((wrams&0x1fff)>>10,0x6000,WRAM);
+   SetWriteHandler(0x6000,0x6000 + ((wrams - 1) & 0x1fff),CartBW);
+   SetReadHandler(0x6000,0x6000 + ((wrams - 1) & 0x1fff),CartBR);
+   setprg8r(0x10,0x6000,0);
   }
   if(!(mmc3opts&2))
      FCEU_dwmemset(WRAM,0,wrams);
  }
  MMC3RegReset();
  if(CHRRAM)
-  FCEU_dwmemset(CHRRAM,0,CHRRAMSize);
+   FCEU_dwmemset(CHRRAM,0,CHRRAMSize);
 }
 
 static void GenMMC3Close(void)
@@ -307,7 +303,7 @@ static void GenMMC3Close(void)
 
 void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery)
 {
-pwrap=GENPWRAP;
+ pwrap=GENPWRAP;
  cwrap=GENCWRAP;
  mwrap=GENMWRAP;
 
@@ -321,7 +317,8 @@ pwrap=GENPWRAP;
  {
   mmc3opts|=1;
   WRAM=(uint8*)FCEU_gmalloc(wrams);
-  AddExState(WRAM, wrams, 0, "WRAM");
+  SetupCartPRGMapping(0x10,WRAM,wrams,1);
+  AddExState(WRAM, wrams, 0, "MRAM");
  }
 
  if(battery)
@@ -331,14 +328,6 @@ pwrap=GENPWRAP;
   info->SaveGameLen[0]=wrams;
  }
 
- if(!chr)
- {
-  CHRRAM=(uint8*)FCEU_gmalloc(8192);
-  CHRRAMSize=8192;
-  SetupCartCHRMapping(0, CHRRAM, 8192, 1);
-  AddExState(CHRRAM, 8192, 0, "CHRR");
- }
-
  AddExState(MMC3_StateRegs, ~0, 0, 0);
 
  info->Power=GenMMC3Power;
@@ -353,7 +342,7 @@ pwrap=GENPWRAP;
   GameHBIRQHook = MMC3_hb_PALStarWarsHack;
  else
   GameHBIRQHook=MMC3_hb;
- GameStateRestore=genmmc3restore;
+ GameStateRestore=GenMMC3Restore;
 }
 
 // ----------------------------------------------------------------------
@@ -413,6 +402,56 @@ void Mapper12_Init(CartInfo *info)
  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)
@@ -464,16 +503,17 @@ void Mapper44_Init(CartInfo *info)
 
 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
+      if(EXPREGS[2])
+         NV&=0; // hack ;( don't know exactly how it should be
+   NV|=EXPREGS[0]|((EXPREGS[2]&0xF0)<<4);
+   setchr1(A,NV);
+ }
 }
 
 static void M45PW(uint32 A, uint8 V)
@@ -492,22 +532,43 @@ static DECLFW(M45Write)
  }
  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 DECLFR(M45Read)
+{
+  uint32 addr = 1<<(EXPREGS[5]+4);
+  if(A&(addr|(addr-1)))
+    return X.DB | 1;
+  else
+    return X.DB;
+}
+
 static void M45Reset(void)
 {
- FCEU_dwmemset(EXPREGS,0,5);
+ EXPREGS[0]=EXPREGS[1]=EXPREGS[2]=EXPREGS[3]=EXPREGS[4]=0;
+ EXPREGS[5]++;
+ EXPREGS[5] &= 7;
  MMC3RegReset();
 }
 
 static void M45Power(void)
 {
M45Reset();
setchr8(0);
  GenMMC3Power();
- SetWriteHandler(0x6000,0x7FFF,M45Write);
+ EXPREGS[0]=EXPREGS[1]=EXPREGS[2]=EXPREGS[3]=EXPREGS[4]=EXPREGS[5]=0;
+ SetWriteHandler(0x5000,0x7FFF,M45Write);
+ SetReadHandler(0x5000,0x5FFF,M45Read);
 }
 
 void Mapper45_Init(CartInfo *info)
@@ -549,12 +610,12 @@ static void M47Power(void)
  EXPREGS[0]=0;
  GenMMC3Power();
  SetWriteHandler(0x6000,0x7FFF,M47Write);
- SetReadHandler(0x6000,0x7FFF,0);
+// SetReadHandler(0x6000,0x7FFF,0);
 }
 
 void Mapper47_Init(CartInfo *info)
 {
- GenMMC3_Init(info, 512, 256, 8, info->battery);
+ GenMMC3_Init(info, 512, 256, 8, 0);
  pwrap=M47PW;
  cwrap=M47CW;
  info->Power=M47Power;
@@ -618,21 +679,19 @@ void Mapper49_Init(CartInfo *info)
 }
 
 // ---------------------------- Mapper 52 -------------------------------
-
 static void M52PW(uint32 A, uint8 V)
 {
- uint32 NV=V;
- NV&=0x1F^((EXPREGS[0]&8)<<1);
- NV|=((EXPREGS[0]&6)|((EXPREGS[0]>>3)&EXPREGS[0]&1))<<4;
- setprg8(A,NV);
+ uint32 mask = 0x1F^((EXPREGS[0]&8)<<1);
+ uint32 bank = ((EXPREGS[0]&6)|((EXPREGS[0]>>3)&EXPREGS[0]&1))<<4;
+ setprg8(A, bank|(V & mask));
 }
 
 static void M52CW(uint32 A, uint8 V)
 {
- uint32 NV=V;
- NV&=0xFF^((EXPREGS[0]&0x40)<<1);
- NV|=(((EXPREGS[0]>>3)&4)|((EXPREGS[0]>>1)&2)|((EXPREGS[0]>>6)&(EXPREGS[0]>>4)&1))<<7;
- setchr1(A,NV);
+ uint32 mask = 0xFF^((EXPREGS[0]&0x40)<<1);
+// uint32 bank = (((EXPREGS[0]>>3)&4)|((EXPREGS[0]>>1)&2)|((EXPREGS[0]>>6)&(EXPREGS[0]>>4)&1))<<7;
+ uint32 bank = (((EXPREGS[0]>>4)&2)|(EXPREGS[0]&4)|((EXPREGS[0]>>6)&(EXPREGS[0]>>4)&1))<<7; // actually 256K CHR banks index bits is inverted!
+ setchr1(A, bank|(V & mask));
 }
 
 static DECLFW(M52Write)
@@ -642,7 +701,7 @@ static DECLFW(M52Write)
   WRAM[A-0x6000]=V;
   return;
  }
- EXPREGS[1]=1;
+ EXPREGS[1]=V&0x80;
  EXPREGS[0]=V;
  FixMMC3PRG(MMC3_cmd);
  FixMMC3CHR(MMC3_cmd);
@@ -663,7 +722,7 @@ static void M52Power(void)
 
 void Mapper52_Init(CartInfo *info)
 {
- GenMMC3_Init(info, 512, 256, 8, info->battery);
+ GenMMC3_Init(info, 256, 256, 8, info->battery);
  cwrap=M52CW;
  pwrap=M52PW;
  info->Reset=M52Reset;
@@ -675,22 +734,17 @@ void Mapper52_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");
@@ -705,84 +759,82 @@ static void M114PWRAP(uint32 A, uint8 V)
 {
   if(EXPREGS[0]&0x80)
   {
+//    FCEU_printf("8000-C000:%02X\n",EXPREGS[0]&0xF);
     setprg16(0x8000,EXPREGS[0]&0xF);
     setprg16(0xC000,EXPREGS[0]&0xF);
   }
-  else
+  else {
+//    FCEU_printf("%04X:%02X\n",A,V&0x3F);
     setprg8(A,V&0x3F);
+  }
 }
 
 static DECLFW(M114Write)
 {
- if(A==0xE003)
- {
-  IRQa=1;
-  IRQCount=V;
- }
- else if(A==0xE002)
- {
-  IRQa=0;
-  X6502_IRQEnd(FCEU_IQEXT);
- }
- else switch(A&0xE000)
- {
-  case 0x8000: setmirror((V&1)^1); break;
-  case 0xA000: MMC3_CMDWrite(0x8000,(V&0xC0)|(m114_perm[V&7])); cmdin=1; break;
-  case 0xC000: if(!cmdin) break;
-               MMC3_CMDWrite(0x8001,V);
-               cmdin=0;
-               break;
- }
+  switch(A&0xE001)
+  {
+   case 0x8001: MMC3_CMDWrite(0xA000,V); break;
+   case 0xA000: MMC3_CMDWrite(0x8000,(V&0xC0)|(m114_perm[V&7])); cmdin=1; break;
+   case 0xC000: if(!cmdin) break; MMC3_CMDWrite(0x8001,V); cmdin=0; break;
+   case 0xA001: IRQLatch=V; break;
+   case 0xC001: IRQReload=1; break;
+   case 0xE000: X6502_IRQEnd(FCEU_IQEXT);IRQa=0; break;
+   case 0xE001: IRQa=1; break;
+  }
 }
 
 static DECLFW(M114ExWrite)
 {
   if(A<=0x7FFF)
   {
-   EXPREGS[0]=V;
-   FixMMC3PRG(MMC3_cmd);
+    EXPREGS[0]=V;
+    FixMMC3PRG(MMC3_cmd);
   }
 }
 
 static void M114Power(void)
 {
- GenMMC3Power();
- SetWriteHandler(0x8000,0xFFFF,M114Write);
- SetWriteHandler(0x5000,0x7FFF,M114ExWrite);
 GenMMC3Power();
 SetWriteHandler(0x8000,0xFFFF,M114Write);
 SetWriteHandler(0x5000,0x7FFF,M114ExWrite);
 }
 
 static void M114Reset(void)
 {
- EXPREGS[0]=0;
- MMC3RegReset();
 EXPREGS[0]=0;
 MMC3RegReset();
 }
 
 void Mapper114_Init(CartInfo *info)
 {
- GenMMC3_Init(info, 256, 256, 0, 0);
- pwrap=M114PWRAP;
- info->Power=M114Power;
- info->Reset=M114Reset;
- AddExState(EXPREGS, 1, 0, "EXPR");
- AddExState(&cmdin, 1, 0, "CMDIN");
+  isRevB=0;
+  GenMMC3_Init(info, 256, 256, 0, 0);
+  pwrap=M114PWRAP;
+  info->Power=M114Power;
+  info->Reset=M114Reset;
+  AddExState(EXPREGS, 1, 0, "EXPR");
+  AddExState(&cmdin, 1, 0, "CMDI");
 }
 
-// ---------------------------- Mapper 115 ------------------------------
+// ---------------------------- Mapper 115 KN-658 board ------------------------------
 
 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)
 {
+// FCEU_printf("%04x:%04x\n",A,V);
+ if(A==0x5080) EXPREGS[2]=V;
  if(A==0x6000)
     EXPREGS[0]=V;
  else if(A==0x6001)
@@ -790,11 +842,16 @@ static DECLFW(M115Write)
  FixMMC3PRG(MMC3_cmd);
 }
 
+static DECLFR(M115Read)
+{
+ return EXPREGS[2];
+}
+
 static void M115Power(void)
 {
  GenMMC3Power();
  SetWriteHandler(0x4100,0x7FFF,M115Write);
- SetReadHandler(0x4100,0x7FFF,0);
+ SetReadHandler(0x5000,0x5FFF,M115Read);
 }
 
 void Mapper115_Init(CartInfo *info)
@@ -806,34 +863,6 @@ void Mapper115_Init(CartInfo *info)
  AddExState(EXPREGS, 2, 0, "EXPR");
 }
 
-// ---------------------------- Mapper 116 ------------------------------
-
-static void M116CW(uint32 A, uint8 V)
-{
- setchr1(A,V|((EXPREGS[0]&0x4)<<6));
-}
-
-static DECLFW(M116Write)
-{
- EXPREGS[0]=V;
- FixMMC3PRG(MMC3_cmd);
- FixMMC3CHR(MMC3_cmd);
-}
-
-static void M116Power(void)
-{
- GenMMC3Power();
- SetWriteHandler(0x4100,0x4100,M116Write);
-}
-
-void Mapper116_Init(CartInfo *info)
-{
- GenMMC3_Init(info, 128, 512, 0, 0);
- cwrap=M116CW;
- info->Power=M116Power;
- AddExState(EXPREGS, 4, 0, "EXPR");
-}
-
 // ---------------------------- Mapper 118 ------------------------------
 
 static uint8 PPUCHRBus;
@@ -855,15 +884,6 @@ static void TKSWRAP(uint32 A, uint8 V)
     setmirror(MI_0+(V>>7));
 }
 
-void Mapper118_Init(CartInfo *info)
-{
- GenMMC3_Init(info, 512, 256, 8, info->battery);
- cwrap=TKSWRAP;
- mwrap=GENNOMWRAP;
- PPU_hook=TKSPPU;
- AddExState(&PPUCHRBus, 1, 0, "PPUC");
-}
-
 // ---------------------------- Mapper 119 ------------------------------
 
 static void TQWRAP(uint32 A, uint8 V)
@@ -880,21 +900,46 @@ void Mapper119_Init(CartInfo *info)
  SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
 }
 
-// ---------------------------- Mapper 191 ------------------------------
+// ---------------------------- Mapper 134 ------------------------------
 
-static void M191CW(uint32 A, uint8 V)
+static void M134PW(uint32 A, uint8 V)
 {
-  setchr1r((V&0x80)>>3,A,V);
+  setprg8(A,(V&0x1F)|((EXPREGS[0]&2)<<4));
 }
 
-void Mapper191_Init(CartInfo *info)
+static void M134CW(uint32 A, uint8 V)
 {
- 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");
+  setchr1(A,(V&0xFF)|((EXPREGS[0]&0x20)<<3));
+}
+
+static DECLFW(M134Write)
+{
+  EXPREGS[0]=V;
+  FixMMC3CHR(MMC3_cmd);
+  FixMMC3PRG(MMC3_cmd);
+}
+
+static void M134Power(void)
+{
+ EXPREGS[0]=0;
+ GenMMC3Power();
+ SetWriteHandler(0x6001,0x6001,M134Write);
+}
+
+static void M134Reset(void)
+{
+ EXPREGS[0]=0;
+ MMC3RegReset();
+}
+
+void Mapper134_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 256, 256, 0, 0);
+ pwrap=M134PW;
+ cwrap=M134CW;
+ info->Power=M134Power;
+ info->Reset=M134Reset;
+ AddExState(EXPREGS, 4, 0, "EXPR");
 }
 
 // ---------------------------- Mapper 165 ------------------------------
@@ -927,8 +972,10 @@ static void M165PPUFE(void)
 
 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)
@@ -963,256 +1010,249 @@ void Mapper165_Init(CartInfo *info)
  AddExState(EXPREGS, 4, 0, "EXPR");
 }
 
-// ---------------------------- Mapper 182 ------------------------------
-// òàáëèöà ïåðìóòàöè àíàëîãè÷íà 114 ìàïïåðó, ðåãèñòðû ìàïïåðà ãîðàçäî ñëîæíåå,
-// ÷åì èñïîëüçóþòñÿ çäåñü, õîòÿ âñå ïðåêðàñíî ðàáîòàåò.
+// ---------------------------- Mapper 191 ------------------------------
 
-//static uint8 m182_perm[8] = {0, 3, 1, 5, 6, 7, 2, 4};
-static DECLFW(M182Write)
+static void M191CW(uint32 A, uint8 V)
 {
- switch(A&0xF003)
- {
-  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;
- }
+  setchr1r((V&0x80)>>3,A,V);
 }
 
-static void M182Power(void)
+void Mapper191_Init(CartInfo *info)
 {
- GenMMC3Power();
- SetWriteHandler(0x8000,0xFFFF,M182Write);
+ 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");
 }
 
-void Mapper182_Init(CartInfo *info)
+// ---------------------------- Mapper 192 -------------------------------
+
+static void M192CW(uint32 A, uint8 V)
 {
- GenMMC3_Init(info, 256, 256, 0, 0);
- info->Power=M182Power;
+  if((V==8)||(V==9)||(V==0xA)||(V==0xB)) //Ying Lie Qun Xia Zhuan (Chinese),
+    setchr1r(0x10,A,V);
+  else
+    setchr1r(0,A,V);
 }
 
-// ---------------------------- Mapper 205 ------------------------------
-
-static void M205PW(uint32 A, uint8 V)
+void Mapper192_Init(CartInfo *info)
 {
- if(EXPREGS[0]&2)
-    setprg8(A,(V&0x0f)|((EXPREGS[0]&3)<<4));
- else
-    setprg8(A,(V&0x1f)|((EXPREGS[0]&3)<<4));
+ 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");
 }
 
-static void M205CW(uint32 A, uint8 V)
+// ---------------------------- Mapper 194 -------------------------------
+
+static void M194CW(uint32 A, uint8 V)
 {
- setchr1(A,V|((EXPREGS[0]&3)*128));
+  if(V<=1) //Dai-2-Ji - Super Robot Taisen (As).nes
+    setchr1r(0x10,A,V);
+  else
+    setchr1r(0,A,V);
 }
 
-static DECLFW(M205Write)
+void Mapper194_Init(CartInfo *info)
 {
- if((A&0x6800)==0x6800) EXPREGS[0]= V;
- FixMMC3PRG(MMC3_cmd);
- FixMMC3CHR(MMC3_cmd);
+ 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");
 }
 
-static void M205Reset(void)
+// ---------------------------- Mapper 195 -------------------------------
+static uint8 *wramtw;
+static uint16 wramsize;
+
+static void M195CW(uint32 A, uint8 V)
 {
- EXPREGS[0]=0;
- MMC3RegReset();
+  if(V<=3) // Crystalis (c).nes, Captain Tsubasa Vol 2 - Super Striker (C)
+    setchr1r(0x10,A,V);
+  else
+    setchr1r(0,A,V);
 }
 
-static void M205Power(void)
+static void M195Power(void)
 {
  GenMMC3Power();
- SetWriteHandler(0x4020,0x7FFF,M205Write);
+ setprg4r(0x10,0x5000,0);
+ SetWriteHandler(0x5000,0x5fff,CartBW);
+ SetReadHandler(0x5000,0x5fff,CartBR);
 }
 
-void Mapper205_Init(CartInfo *info)
+static void M195Close(void)
 {
- GenMMC3_Init(info, 512, 256, 8, 0);
- pwrap=M205PW;
- cwrap=M205CW;
- info->Power=M205Power;
- info->Reset=M205Reset;
- AddExState(EXPREGS, 1, 0, "EXPR");
+  if(wramtw)
+    FCEU_gfree(wramtw);
+  wramtw=NULL;
 }
 
-// ---------------------------- Mapper 215 ------------------------------
-
-static uint8 m215_perm[8] = {0, 2, 5, 3, 6, 1, 7, 4};
-
-static void M215CW(uint32 A, uint8 V)
+void Mapper195_Init(CartInfo *info)
 {
- if(EXPREGS[1]&0x04)
-   setchr1(A,V|0x100);
- else
-   setchr1(A,(V&0x7F)|((EXPREGS[1]&0x10)<<3));
+ GenMMC3_Init(info, 512, 256, 8, info->battery);
+ cwrap=M195CW;
+ info->Power=M195Power;
+ info->Close=M195Close;
+ 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, "TRAM");
 }
 
-static void M215PW(uint32 A, uint8 V)
+// ---------------------------- Mapper 196 -------------------------------
+// MMC3 board with optional command address line connection, allows to
+// make three-four different wirings to IRQ address lines and separately to
+// CMD address line, Mali Boss additionally check if wiring are correct for
+// game
+
+static void M196PW(uint32 A, uint8 V)
 {
- if(EXPREGS[0]&0x80)
- {
-   setprg16(0x8000,(EXPREGS[0]&0x0F)|(EXPREGS[1]&0x10));
-   setprg16(0xC000,(EXPREGS[0]&0x0F)|(EXPREGS[1]&0x10));
- }
- else if(EXPREGS[1]&0x08)
-        setprg8(A,(V&0x1F)|0x20);
-      else
-        setprg8(A,(V&0x0F)|(EXPREGS[1]&0x10));
+  if(EXPREGS[0]) // Tenchi o Kurau II - Shokatsu Koumei Den (J) (C).nes
+    setprg32(0x8000,EXPREGS[1]);
+  else
+    setprg8(A,V);
 }
 
-static DECLFW(M215Write)
+static DECLFW(Mapper196Write)
 {
- if(!(EXPREGS[2]))
- {
-  if(A >= 0xc000)
+  if(A >= 0xC000) {
+   A=(A&0xFFFE)|((A>>2)&1)|((A>>3)&1);
    MMC3_IRQWrite(A,V);
-  else
+  }
+  else {
+   A=(A&0xFFFE)|((A>>2)&1)|((A>>3)&1)|((A>>1)&1);
    MMC3_CMDWrite(A,V);
- }
- else switch(A&0xE001)
- {
-  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;
-               MMC3_CMDWrite(0x8001,V);
-               cmdin=0;
-               break;
- }
+  }
 }
 
-static DECLFW(M215ExWrite)
+static DECLFW(Mapper196WriteLo)
 {
- switch(A)
- {
-  case 0x5000:
-       EXPREGS[0]=V;
-       FixMMC3PRG(MMC3_cmd);
-       break;
-  case 0x5001:
-       EXPREGS[1]=V;
-       FixMMC3CHR(MMC3_cmd);
-       break;
-  case 0x5007:
-       EXPREGS[2]=V;
-       MMC3RegReset();
-       break;
- }
+  EXPREGS[0]=1;
+  EXPREGS[1]=(V&0xf)|(V>>4);
+  FixMMC3PRG(MMC3_cmd);
 }
 
-static void M215Power(void)
+static void Mapper196Power(void)
 {
- EXPREGS[0]=0;
- EXPREGS[1]=0xFF;
- EXPREGS[2]=4;
- GenMMC3Power();
- SetWriteHandler(0x8000,0xFFFF,M215Write);
- SetWriteHandler(0x5000,0x7FFF,M215ExWrite);
+  GenMMC3Power();
+  EXPREGS[0] = EXPREGS[1] = 0;
+  SetWriteHandler(0x6000,0x6FFF,Mapper196WriteLo);
+  SetWriteHandler(0x8000,0xFFFF,Mapper196Write);
 }
 
-void Mapper215_Init(CartInfo *info)
+void Mapper196_Init(CartInfo *info)
 {
- GenMMC3_Init(info, 256, 256, 0, 0);
- cwrap=M215CW;
- pwrap=M215PW;
- info->Power=M215Power;
- AddExState(EXPREGS, 3, 0, "EXPR");
- AddExState(&cmdin, 1, 0, "CMDIN");
+  GenMMC3_Init(info, 128, 128, 0, 0);
+  pwrap=M196PW;
+  info->Power=Mapper196Power;
 }
 
-// ---------------------------- Mapper 217 ------------------------------
-
-static uint8 m217_perm[8] = {0, 6, 3, 7, 5, 2, 4, 1};
+// ---------------------------- Mapper 197 -------------------------------
 
-static void M217CW(uint32 A, uint8 V)
+static void M197CW(uint32 A, uint8 V)
 {
- if(EXPREGS[1]&0x08)
-   setchr1(A,V|((EXPREGS[1]&3)<<8));
- else
-   setchr1(A,(V&0x7F)|((EXPREGS[1]&3)<<8)|((EXPREGS[1]&0x10)<<3));
+  if(A==0x0000)
+    setchr4(0x0000,V>>1);
+  else if(A==0x1000)
+    setchr2(0x1000,V);
+  else if(A==0x1400)
+    setchr2(0x1800,V);
 }
 
-static void M217PW(uint32 A, uint8 V)
+void Mapper197_Init(CartInfo *info)
 {
- if(EXPREGS[0]&0x80)
- {
-   setprg16(0x8000,(EXPREGS[0]&0x0F)|((EXPREGS[1]&3)<<4));
-   setprg16(0xC000,(EXPREGS[0]&0x0F)|((EXPREGS[1]&3)<<4));
- }
- else if(EXPREGS[1]&0x08)
-        setprg8(A,(V&0x1F)|((EXPREGS[1]&3)<<5));
-      else
-        setprg8(A,(V&0x0F)|((EXPREGS[1]&3)<<5)|(EXPREGS[1]&0x10));
+ GenMMC3_Init(info, 128, 512, 8, 0);
+ cwrap=M197CW;
 }
 
-static DECLFW(M217Write)
+// ---------------------------- Mapper 198 -------------------------------
+
+static void M198PW(uint32 A, uint8 V)
 {
- if(!EXPREGS[2])
- {
-  if(A >= 0xc000)
-   MMC3_IRQWrite(A, V);
+  if(V>=0x50) // Tenchi o Kurau II - Shokatsu Koumei Den (J) (C).nes
+    setprg8(A,V&0x4F);
   else
-   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;
- }
+    setprg8(A,V);
 }
 
-static DECLFW(M217ExWrite)
+void Mapper198_Init(CartInfo *info)
 {
- switch(A)
- {
-  case 0x5000:
-       EXPREGS[0]=V;
-       FixMMC3PRG(MMC3_cmd);
-       break;
-  case 0x5001:
-       EXPREGS[1]=V;
-       FixMMC3PRG(MMC3_cmd);
-       break;
-  case 0x5007:
-       EXPREGS[2]=V;
-       break;
+ GenMMC3_Init(info, 1024, 256, 8, info->battery);
+ pwrap=M198PW;
+ info->Power=M195Power;
+ info->Close=M195Close;
+ wramsize=4096;
+ wramtw=(uint8*)FCEU_gmalloc(wramsize);
+ SetupCartPRGMapping(0x10, wramtw, wramsize, 1);
+ AddExState(wramtw, wramsize, 0, "TRAM");
+}
+
+// ---------------------------- Mapper 205 ------------------------------
+// GN-45 BOARD
+
+static void M205PW(uint32 A, uint8 V)
+{
+// GN-30A - íà÷àëüíàÿ ìàñêà äîëæíà áûòü 1F + àïïàðàòíûé ïåðåêëþ÷àòåëü íà øèíå àäðåñà
+ setprg8(A,(V&0x0f)|EXPREGS[0]);
+}
+
+static void M205CW(uint32 A, uint8 V)
+{
+// GN-30A - íà÷àëüíàÿ ìàñêà äîëæíà áûòü FF
+ setchr1(A,(V&0x7F)|(EXPREGS[0]<<3));
+}
+
+static DECLFW(M205Write)
+{
+ if(EXPREGS[2] == 0) {
+   EXPREGS[0] = A & 0x30;
+   EXPREGS[2] = A & 0x80;
+   FixMMC3PRG(MMC3_cmd);
+   FixMMC3CHR(MMC3_cmd);
  }
+ else
+   CartBW(A,V);
 }
 
-static void M217Power(void)
+static void M205Reset(void)
+{
+ EXPREGS[0]=EXPREGS[2]=0;
+ MMC3RegReset();
+}
+
+static void M205Power(void)
 {
- EXPREGS[0]=0;
- EXPREGS[1]=0xFF;
- EXPREGS[2]=3;
  GenMMC3Power();
- SetWriteHandler(0x8000,0xFFFF,M217Write);
- SetWriteHandler(0x5000,0x7FFF,M217ExWrite);
+ SetWriteHandler(0x6000,0x6fff,M205Write);
 }
 
-void Mapper217_Init(CartInfo *info)
+void Mapper205_Init(CartInfo *info)
 {
- GenMMC3_Init(info, 256, 256, 0, 0);
cwrap=M217CW;
pwrap=M217PW;
- info->Power=M217Power;
AddExState(EXPREGS, 3, 0, "EXPR");
- AddExState(&cmdin, 1, 0, "CMDIN");
+ GenMMC3_Init(info, 256, 256, 8, 0);
pwrap=M205PW;
cwrap=M205CW;
+ info->Power=M205Power;
info->Reset=M205Reset;
+ AddExState(EXPREGS, 1, 0, "EXPR");
 }
 
 // ---------------------------- Mapper 245 ------------------------------
 
 static void M245CW(uint32 A, uint8 V)
 {
- setchr1(A,V&7);
+ if(!UNIFchrrama) // Yong Zhe Dou E Long - Dragon Quest VI (As).nes NEEDS THIS for RAM cart
+  setchr1(A,V&7);
  EXPREGS[0]=V;
  FixMMC3PRG(MMC3_cmd);
 }
@@ -1345,6 +1385,11 @@ void Mapper254_Init(CartInfo *info)
 
 // ---------------------------- UNIF Boards -----------------------------
 
+void TBROM_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 64, 64, 0, 0);
+}
+
 void TEROM_Init(CartInfo *info)
 {
  GenMMC3_Init(info, 32, 32, 0, 0);