merge mappers from FCEU-mm
[fceu.git] / boards / mmc3.c
index 2618db4..6d3af95 100644 (file)
-/* FCE Ultra - NES/Famicom Emulator\r
- *\r
- * Copyright notice for this file:\r
- *  Copyright (C) 1998 BERO\r
- *  Copyright (C) 2003 Xodnizel\r
- *  Mapper 12 code Copyright (C) 2003 CaH4e3\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r
- */\r
-\r
-/*  Code for emulating iNES mappers 4,12,44,45,47,49,52,74,114,115,116,118,\r
-    119,165,205,214,215,245,249,250,254\r
-*/\r
-\r
-#include "mapinc.h"\r
-#include "mmc3.h"\r
-\r
-uint8 MMC3_cmd;\r
-uint8 *WRAM;\r
-uint8 *CHRRAM;\r
-uint32 CHRRAMSize;\r
-uint8 DRegBuf[8];\r
-uint8 EXPREGS[8];    /* For bootleg games, mostly. */\r
-uint8 A000B,A001B;\r
-\r
-#undef IRQCount\r
-#undef IRQLatch\r
-#undef IRQa\r
-uint8 IRQCount,IRQLatch,IRQa;\r
-uint8 IRQReload;\r
-\r
-static SFORMAT MMC3_StateRegs[]=\r
-{\r
- {DRegBuf, 8, "REGS"},\r
- {&MMC3_cmd, 1, "CMD"},\r
- {&A000B, 1, "A000"},\r
- {&A001B, 1, "A001"},\r
- {&IRQReload, 1, "IRQR"},\r
- {&IRQCount, 1, "IRQC"},\r
- {&IRQLatch, 1, "IRQL"},\r
- {&IRQa, 1, "IRQA"},\r
- {0}\r
-};\r
-\r
-static int mmc3opts=0;\r
-static int wrams;\r
-static int isRevB=1;\r
-\r
-void (*pwrap)(uint32 A, uint8 V);\r
-void (*cwrap)(uint32 A, uint8 V);\r
-void (*mwrap)(uint8 V);\r
-\r
-void GenMMC3Power(void);\r
-void FixMMC3PRG(int V);\r
-void FixMMC3CHR(int V);\r
-\r
-void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery);\r
-\r
-// ----------------------------------------------------------------------\r
-// ------------------------- Generic MM3 Code ---------------------------\r
-// ----------------------------------------------------------------------\r
-\r
-void FixMMC3PRG(int V)\r
-{\r
- if(V&0x40)\r
- {\r
-  pwrap(0xC000,DRegBuf[6]);\r
-  pwrap(0x8000,~1);\r
- }\r
- else\r
- {\r
-  pwrap(0x8000,DRegBuf[6]);\r
-  pwrap(0xC000,~1);\r
- }\r
- pwrap(0xA000,DRegBuf[7]);\r
- pwrap(0xE000,~0);\r
-}\r
-\r
-void FixMMC3CHR(int V)\r
-{\r
- int cbase=(V&0x80)<<5;\r
-\r
- cwrap((cbase^0x000),DRegBuf[0]&(~1));\r
- cwrap((cbase^0x400),DRegBuf[0]|1);\r
- cwrap((cbase^0x800),DRegBuf[1]&(~1));\r
- cwrap((cbase^0xC00),DRegBuf[1]|1);\r
-\r
- cwrap(cbase^0x1000,DRegBuf[2]);\r
- cwrap(cbase^0x1400,DRegBuf[3]);\r
- cwrap(cbase^0x1800,DRegBuf[4]);\r
- cwrap(cbase^0x1c00,DRegBuf[5]);\r
-\r
- if(mwrap) mwrap(A000B);\r
-}\r
-\r
-void MMC3RegReset(void)\r
-{\r
- IRQCount=IRQLatch=IRQa=MMC3_cmd=0;\r
-\r
- DRegBuf[0]=0;\r
- DRegBuf[1]=2;\r
- DRegBuf[2]=4;\r
- DRegBuf[3]=5;\r
- DRegBuf[4]=6;\r
- DRegBuf[5]=7;\r
- DRegBuf[6]=0;\r
- DRegBuf[7]=1;\r
-\r
- FixMMC3PRG(0);\r
- FixMMC3CHR(0);\r
-}\r
-\r
-DECLFW(MMC3_CMDWrite)\r
-{\r
-// FCEU_printf("bs %04x %02x\n",A,V);\r
- switch(A&0xE001)\r
- {\r
-  case 0x8000:\r
-       if((V&0x40) != (MMC3_cmd&0x40))\r
-          FixMMC3PRG(V);\r
-       if((V&0x80) != (MMC3_cmd&0x80))\r
-          FixMMC3CHR(V);\r
-       MMC3_cmd = V;\r
-       break;\r
-  case 0x8001:\r
-       {\r
-        int cbase=(MMC3_cmd&0x80)<<5;\r
-        DRegBuf[MMC3_cmd&0x7]=V;\r
-        switch(MMC3_cmd&0x07)\r
-        {\r
-         case 0: cwrap((cbase^0x000),V&(~1));\r
-                 cwrap((cbase^0x400),V|1);\r
-                 break;\r
-         case 1: cwrap((cbase^0x800),V&(~1));\r
-                 cwrap((cbase^0xC00),V|1);\r
-                 break;\r
-         case 2: cwrap(cbase^0x1000,V);\r
-                 break;\r
-         case 3: cwrap(cbase^0x1400,V);\r
-                 break;\r
-         case 4: cwrap(cbase^0x1800,V);\r
-                 break;\r
-         case 5: cwrap(cbase^0x1C00,V);\r
-                 break;\r
-         case 6:\r
-                 if(MMC3_cmd&0x40)\r
-                    pwrap(0xC000,V);\r
-                 else\r
-                    pwrap(0x8000,V);\r
-                 break;\r
-         case 7:\r
-                 pwrap(0xA000,V);\r
-                 break;\r
-        }\r
-       }\r
-       break;\r
-  case 0xA000:\r
-       if(mwrap) mwrap(V);\r
-       break;\r
-  case 0xA001:\r
-       A001B=V;\r
-       break;\r
- }\r
-}\r
-\r
-DECLFW(MMC3_IRQWrite)\r
-{\r
-// FCEU_printf("%04x:%04x\n",A,V);\r
- switch(A&0xE001)\r
- {\r
-  case 0xC000:IRQLatch=V;break;\r
-  case 0xC001:IRQReload=1;break;\r
-  case 0xE000:X6502_IRQEnd(FCEU_IQEXT);IRQa=0;break;\r
-  case 0xE001:IRQa=1;break;\r
- }\r
-}\r
-\r
-static void ClockMMC3Counter(void)\r
-{\r
- int count = IRQCount;\r
- if(!count || IRQReload)\r
- {\r
-    IRQCount = IRQLatch;\r
-    IRQReload = 0;\r
- }\r
- else\r
-    IRQCount--;\r
- if((count|isRevB) && !IRQCount)\r
- {\r
-    if(IRQa)\r
-    {\r
-       X6502_IRQBegin(FCEU_IQEXT);\r
-    }\r
- }\r
-}\r
-\r
-static void MMC3_hb(void)\r
-{\r
- ClockMMC3Counter();\r
-}\r
-\r
-static void MMC3_hb_KickMasterHack(void)\r
-{\r
- if(scanline==238) ClockMMC3Counter();\r
- ClockMMC3Counter();\r
-}\r
-\r
-static void MMC3_hb_PALStarWarsHack(void)\r
-{\r
- if(scanline==240) ClockMMC3Counter();\r
- ClockMMC3Counter();\r
-}\r
-\r
-void GenMMC3Restore(int version)\r
-{\r
- FixMMC3PRG(MMC3_cmd);\r
- FixMMC3CHR(MMC3_cmd);\r
-}\r
-\r
-static void GENCWRAP(uint32 A, uint8 V)\r
-{\r
-   setchr1(A,V);    // Business Wars NEEDS THIS for 8K CHR-RAM\r
-}\r
-\r
-static void GENPWRAP(uint32 A, uint8 V)\r
-{\r
- setprg8(A,V&0x7F); // [NJ102] Mo Dao Jie (C) has 1024Mb MMC3 BOARD, maybe something other will be broken\r
-}\r
-\r
-static void GENMWRAP(uint8 V)\r
-{\r
- A000B=V;\r
- setmirror((V&1)^1);\r
-}\r
-\r
-static void GENNOMWRAP(uint8 V)\r
-{\r
- A000B=V;\r
-}\r
-\r
-static DECLFW(MBWRAMMMC6)\r
-{\r
- WRAM[A&0x3ff]=V;\r
-}\r
-\r
-static DECLFR(MAWRAMMMC6)\r
-{\r
- return(WRAM[A&0x3ff]);\r
-}\r
-\r
-void GenMMC3Power(void)\r
-{\r
- if(UNIFchrrama) setchr8(0);\r
-\r
- SetWriteHandler(0x8000,0xBFFF,MMC3_CMDWrite);\r
- SetWriteHandler(0xC000,0xFFFF,MMC3_IRQWrite);\r
- SetReadHandler(0x8000,0xFFFF,CartBR);\r
- A001B=A000B=0;\r
- setmirror(1);\r
- if(mmc3opts&1)\r
- {\r
-  if(wrams==1024)\r
-  {\r
-   FCEU_CheatAddRAM(1,0x7000,WRAM);\r
-   SetReadHandler(0x7000,0x7FFF,MAWRAMMMC6);\r
-   SetWriteHandler(0x7000,0x7FFF,MBWRAMMMC6);\r
-  }\r
-  else\r
-  {\r
-   FCEU_CheatAddRAM((wrams&0x1fff)>>10,0x6000,WRAM);\r
-   SetWriteHandler(0x6000,0x6000 + ((wrams - 1) & 0x1fff),CartBW);\r
-   SetReadHandler(0x6000,0x6000 + ((wrams - 1) & 0x1fff),CartBR);\r
-   setprg8r(0x10,0x6000,0);\r
-  }\r
-  if(!(mmc3opts&2))\r
-     FCEU_dwmemset(WRAM,0,wrams);\r
- }\r
- MMC3RegReset();\r
- if(CHRRAM)\r
-  FCEU_dwmemset(CHRRAM,0,CHRRAMSize);\r
-}\r
-\r
-static void GenMMC3Close(void)\r
-{\r
- if(CHRRAM)\r
-    FCEU_gfree(CHRRAM);\r
- if(WRAM)\r
-    FCEU_gfree(WRAM);\r
- CHRRAM=WRAM=NULL;\r
-}\r
-\r
-void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery)\r
-{\r
- pwrap=GENPWRAP;\r
- cwrap=GENCWRAP;\r
- mwrap=GENMWRAP;\r
-\r
- wrams=wram<<10;\r
-\r
- PRGmask8[0]&=(prg>>13)-1;\r
- CHRmask1[0]&=(chr>>10)-1;\r
- CHRmask2[0]&=(chr>>11)-1;\r
-\r
- if(wram)\r
- {\r
-  mmc3opts|=1;\r
-  WRAM=(uint8*)FCEU_gmalloc(wrams);\r
-  SetupCartPRGMapping(0x10,WRAM,wrams,1);\r
-  AddExState(WRAM, wrams, 0, "MMC3WRAM");\r
- }\r
-\r
- if(battery)\r
- {\r
-  mmc3opts|=2;\r
-  info->SaveGame[0]=WRAM;\r
-  info->SaveGameLen[0]=wrams;\r
- }\r
-\r
- AddExState(MMC3_StateRegs, ~0, 0, 0);\r
-\r
- info->Power=GenMMC3Power;\r
- info->Reset=MMC3RegReset;\r
- info->Close=GenMMC3Close;\r
-\r
- if(info->CRC32 == 0x5104833e)        // Kick Master\r
-  GameHBIRQHook = MMC3_hb_KickMasterHack;\r
- else if(info->CRC32 == 0x5a6860f1 || info->CRC32 == 0xae280e20) // Shougi Meikan '92/'93\r
-  GameHBIRQHook = MMC3_hb_KickMasterHack;\r
- else if(info->CRC32 == 0xfcd772eb)    // PAL Star Wars, similar problem as Kick Master.\r
-  GameHBIRQHook = MMC3_hb_PALStarWarsHack;\r
- else\r
-  GameHBIRQHook=MMC3_hb;\r
- GameStateRestore=GenMMC3Restore;\r
-}\r
-\r
-// ----------------------------------------------------------------------\r
-// -------------------------- MMC3 Based Code ---------------------------\r
-// ----------------------------------------------------------------------\r
-\r
-// ---------------------------- Mapper 4 --------------------------------\r
-\r
-static int hackm4=0;/* For Karnov, maybe others.  BLAH.  Stupid iNES format.*/\r
-\r
-static void M4Power(void)\r
-{\r
- GenMMC3Power();\r
- A000B=(hackm4^1)&1;\r
- setmirror(hackm4);\r
-}\r
-\r
-void Mapper4_Init(CartInfo *info)\r
-{\r
- int ws=8;\r
-\r
- if((info->CRC32==0x93991433 || info->CRC32==0xaf65aa84))\r
- {\r
-  FCEU_printf("Low-G-Man can not work normally in the iNES format.\nThis game has been recognized by its CRC32 value, and the appropriate changes will be made so it will run.\nIf you wish to hack this game, you should use the UNIF format for your hack.\n\n");\r
-  ws=0;\r
- }\r
- GenMMC3_Init(info,512,256,ws,info->battery);\r
- info->Power=M4Power;\r
- hackm4=info->mirror;\r
-}\r
-\r
-// ---------------------------- Mapper 12 -------------------------------\r
-\r
-static void M12CW(uint32 A, uint8 V)\r
-{\r
- setchr1(A,(EXPREGS[(A&0x1000)>>12]<<8)+V);\r
-}\r
-\r
-static DECLFW(M12Write)\r
-{\r
- EXPREGS[0]=V&0x01;\r
- EXPREGS[1]=(V&0x10)>>4;\r
-}\r
-\r
-static void M12Power(void)\r
-{\r
- EXPREGS[0]=EXPREGS[1]=0;\r
- GenMMC3Power();\r
- SetWriteHandler(0x4100,0x5FFF,M12Write);\r
-}\r
-\r
-void Mapper12_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 8, info->battery);\r
- cwrap=M12CW;\r
- isRevB=0;\r
-\r
- info->Power=M12Power;\r
- AddExState(EXPREGS, 2, 0, "EXPR");\r
-}\r
-\r
-// ---------------------------- Mapper 37 -------------------------------\r
-\r
-static void M37PW(uint32 A, uint8 V)\r
-{\r
-  if(EXPREGS[0]!=2)\r
-    V&=0x7;\r
-  else\r
-    V&=0xF;\r
-  V|=EXPREGS[0]<<3;\r
-  setprg8(A,V);\r
-}\r
-\r
-static void M37CW(uint32 A, uint8 V)\r
-{\r
-  uint32 NV=V;\r
-  NV&=0x7F;\r
-  NV|=EXPREGS[0]<<6;\r
-  setchr1(A,NV);\r
-}\r
-\r
-static DECLFW(M37Write)\r
-{\r
-  EXPREGS[0]=(V&6)>>1;\r
-  FixMMC3PRG(MMC3_cmd);\r
-  FixMMC3CHR(MMC3_cmd);\r
-}\r
-\r
-static void M37Reset(void)\r
-{\r
-  EXPREGS[0]=0;\r
-  MMC3RegReset();\r
-}\r
-\r
-static void M37Power(void)\r
-{\r
-  EXPREGS[0]=0;\r
-  GenMMC3Power();\r
-  SetWriteHandler(0x6000,0x7FFF,M37Write);\r
-}\r
-\r
-void Mapper37_Init(CartInfo *info)\r
-{\r
-  GenMMC3_Init(info, 512, 256, 8, info->battery);\r
-  pwrap=M37PW;\r
-  cwrap=M37CW;\r
-  info->Power=M37Power;\r
-  info->Reset=M37Reset;\r
-  AddExState(EXPREGS, 1, 0, "EXPR");\r
-}\r
-\r
-// ---------------------------- Mapper 44 -------------------------------\r
-\r
-static void M44PW(uint32 A, uint8 V)\r
-{\r
- uint32 NV=V;\r
- if(EXPREGS[0]>=6) NV&=0x1F;\r
- else NV&=0x0F;\r
- NV|=EXPREGS[0]<<4;\r
- setprg8(A,NV);\r
-}\r
-\r
-static void M44CW(uint32 A, uint8 V)\r
-{\r
- uint32 NV=V;\r
- if(EXPREGS[0]<6) NV&=0x7F;\r
- NV|=EXPREGS[0]<<7;\r
- setchr1(A,NV);\r
-}\r
-\r
-static DECLFW(M44Write)\r
-{\r
- if(A&1)\r
- {\r
-  EXPREGS[0]=V&7;\r
-  FixMMC3PRG(MMC3_cmd);\r
-  FixMMC3CHR(MMC3_cmd);\r
- }\r
- else\r
-  MMC3_CMDWrite(A,V);\r
-}\r
-\r
-static void M44Power(void)\r
-{\r
- EXPREGS[0]=0;\r
- GenMMC3Power();\r
- SetWriteHandler(0xA000,0xBFFF,M44Write);\r
-}\r
-\r
-void Mapper44_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 8, info->battery);\r
- cwrap=M44CW;\r
- pwrap=M44PW;\r
- info->Power=M44Power;\r
- AddExState(EXPREGS, 1, 0, "EXPR");\r
-}\r
-\r
-// ---------------------------- Mapper 45 -------------------------------\r
-\r
-static void M45CW(uint32 A, uint8 V)\r
-{\r
- if(!UNIFchrrama)\r
- {\r
-   uint32 NV=V;\r
-   if(EXPREGS[2]&8)\r
-      NV&=(1<<((EXPREGS[2]&7)+1))-1;\r
-   else\r
-      if(EXPREGS[2])\r
-         NV&=0; // hack ;( don't know exactly how it should be\r
-   NV|=EXPREGS[0]|((EXPREGS[2]&0xF0)<<4);\r
-   setchr1(A,NV);\r
- }\r
-}\r
-\r
-static void M45PW(uint32 A, uint8 V)\r
-{\r
- V&=(EXPREGS[3]&0x3F)^0x3F;\r
- V|=EXPREGS[1];\r
- setprg8(A,V);\r
-}\r
-\r
-static DECLFW(M45Write)\r
-{\r
- if(EXPREGS[3]&0x40)\r
- {\r
-  WRAM[A-0x6000]=V;\r
-  return;\r
- }\r
- EXPREGS[EXPREGS[4]]=V;\r
- EXPREGS[4]=(EXPREGS[4]+1)&3;\r
-// if(!EXPREGS[4]) \r
-// {\r
-//   FCEU_printf("CHROR %02x, PRGOR %02x, CHRAND %02x, PRGAND %02x\n",EXPREGS[0],EXPREGS[1],EXPREGS[2],EXPREGS[3]);\r
-//   FCEU_printf("CHR0 %03x, CHR1 %03x, PRG0 %03x, PRG1 %03x\n",\r
-//               (0x00&((1<<((EXPREGS[2]&7)+1))-1))|(EXPREGS[0]|((EXPREGS[2]&0xF0)<<4)),\r
-//               (0xFF&((1<<((EXPREGS[2]&7)+1))-1))|(EXPREGS[0]|((EXPREGS[2]&0xF0)<<4)),\r
-//               (0x00&((EXPREGS[3]&0x3F)^0x3F))|(EXPREGS[1]),\r
-//               (0xFF&((EXPREGS[3]&0x3F)^0x3F))|(EXPREGS[1]));\r
-// }\r
- FixMMC3PRG(MMC3_cmd);\r
- FixMMC3CHR(MMC3_cmd);\r
-}\r
-\r
-static void M45Reset(void)\r
-{\r
- EXPREGS[0]=EXPREGS[1]=EXPREGS[2]=EXPREGS[3]=EXPREGS[4]=0;\r
- MMC3RegReset();\r
-}\r
-\r
-static void M45Power(void)\r
-{\r
- setchr8(0);\r
- GenMMC3Power();\r
- SetWriteHandler(0x6000,0x7FFF,M45Write);\r
-}\r
-\r
-void Mapper45_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 8, info->battery);\r
- cwrap=M45CW;\r
- pwrap=M45PW;\r
- info->Reset=M45Reset;\r
- info->Power=M45Power;\r
- AddExState(EXPREGS, 5, 0, "EXPR");\r
-}\r
-\r
-// ---------------------------- Mapper 47 -------------------------------\r
-\r
-static void M47PW(uint32 A, uint8 V)\r
-{\r
- V&=0xF;\r
- V|=EXPREGS[0]<<4;\r
- setprg8(A,V);\r
-}\r
-\r
-static void M47CW(uint32 A, uint8 V)\r
-{\r
- uint32 NV=V;\r
- NV&=0x7F;\r
- NV|=EXPREGS[0]<<7;\r
- setchr1(A,NV);\r
-}\r
-\r
-static DECLFW(M47Write)\r
-{\r
- EXPREGS[0]=V&1;\r
- FixMMC3PRG(MMC3_cmd);\r
- FixMMC3CHR(MMC3_cmd);\r
-}\r
-\r
-static void M47Power(void)\r
-{\r
- EXPREGS[0]=0;\r
- GenMMC3Power();\r
- SetWriteHandler(0x6000,0x7FFF,M47Write);\r
-// SetReadHandler(0x6000,0x7FFF,0);\r
-}\r
-\r
-void Mapper47_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 8, 0);\r
- pwrap=M47PW;\r
- cwrap=M47CW;\r
- info->Power=M47Power;\r
- AddExState(EXPREGS, 1, 0, "EXPR");\r
-}\r
-\r
-// ---------------------------- Mapper 49 -------------------------------\r
-\r
-static void M49PW(uint32 A, uint8 V)\r
-{\r
- if(EXPREGS[0]&1)\r
- {\r
-  V&=0xF;\r
-  V|=(EXPREGS[0]&0xC0)>>2;\r
-  setprg8(A,V);\r
- }\r
- else\r
-  setprg32(0x8000,(EXPREGS[0]>>4)&3);\r
-}\r
-\r
-static void M49CW(uint32 A, uint8 V)\r
-{\r
- uint32 NV=V;\r
- NV&=0x7F;\r
- NV|=(EXPREGS[0]&0xC0)<<1;\r
- setchr1(A,NV);\r
-}\r
-\r
-static DECLFW(M49Write)\r
-{\r
- if(A001B&0x80)\r
- {\r
-  EXPREGS[0]=V;\r
-  FixMMC3PRG(MMC3_cmd);\r
-  FixMMC3CHR(MMC3_cmd);\r
- }\r
-}\r
-\r
-static void M49Reset(void)\r
-{\r
- EXPREGS[0]=0;\r
- MMC3RegReset();\r
-}\r
-\r
-static void M49Power(void)\r
-{\r
- M49Reset();\r
- GenMMC3Power();\r
- SetWriteHandler(0x6000,0x7FFF,M49Write);\r
- SetReadHandler(0x6000,0x7FFF,0);\r
-}\r
-\r
-void Mapper49_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 0, 0);\r
- cwrap=M49CW;\r
- pwrap=M49PW;\r
- info->Reset=M49Reset;\r
- info->Power=M49Power;\r
- AddExState(EXPREGS, 1, 0, "EXPR");\r
-}\r
-\r
-// ---------------------------- Mapper 52 -------------------------------\r
-\r
-static void M52PW(uint32 A, uint8 V)\r
-{\r
- uint32 NV=V;\r
- NV&=0x1F^((EXPREGS[0]&8)<<1);\r
- NV|=((EXPREGS[0]&6)|((EXPREGS[0]>>3)&EXPREGS[0]&1))<<4;\r
- setprg8(A,NV);\r
-}\r
-\r
-static void M52CW(uint32 A, uint8 V)\r
-{\r
- uint32 NV=V;\r
- NV&=0xFF^((EXPREGS[0]&0x40)<<1);\r
- NV|=(((EXPREGS[0]>>3)&4)|((EXPREGS[0]>>1)&2)|((EXPREGS[0]>>6)&(EXPREGS[0]>>4)&1))<<7;\r
- setchr1(A,NV);\r
-}\r
-\r
-static DECLFW(M52Write)\r
-{\r
- if(EXPREGS[1])\r
- {\r
-  WRAM[A-0x6000]=V;\r
-  return;\r
- }\r
- EXPREGS[1]=1;\r
- EXPREGS[0]=V;\r
- FixMMC3PRG(MMC3_cmd);\r
- FixMMC3CHR(MMC3_cmd);\r
-}\r
-\r
-static void M52Reset(void)\r
-{\r
- EXPREGS[0]=EXPREGS[1]=0;\r
- MMC3RegReset();\r
-}\r
-\r
-static void M52Power(void)\r
-{\r
- M52Reset();\r
- GenMMC3Power();\r
- SetWriteHandler(0x6000,0x7FFF,M52Write);\r
-}\r
-\r
-void Mapper52_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 8, info->battery);\r
- cwrap=M52CW;\r
- pwrap=M52PW;\r
- info->Reset=M52Reset;\r
- info->Power=M52Power;\r
- AddExState(EXPREGS, 2, 0, "EXPR");\r
-}\r
-\r
-// ---------------------------- Mapper 74 -------------------------------\r
-\r
-static void M74CW(uint32 A, uint8 V)\r
-{\r
-  if((V==8)||(V==9)) //Di 4 Ci - Ji Qi Ren Dai Zhan (As).nes, Ji Jia Zhan Shi (As).nes\r
-    setchr1r(0x10,A,V);\r
-  else\r
-    setchr1r(0,A,V);\r
-}\r
-\r
-void Mapper74_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 8, info->battery);\r
- cwrap=M74CW;\r
- CHRRAMSize=2048;\r
- CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);\r
- SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);\r
- AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");\r
-}\r
-\r
-// ---------------------------- Mapper 114 ------------------------------\r
-\r
-static uint8 cmdin;\r
-uint8 m114_perm[8] = {0, 3, 1, 5, 6, 7, 2, 4};\r
-\r
-static void M114PWRAP(uint32 A, uint8 V)\r
-{\r
-  if(EXPREGS[0]&0x80)\r
-  {\r
-    setprg16(0x8000,EXPREGS[0]&0xF);\r
-    setprg16(0xC000,EXPREGS[0]&0xF);\r
-  }\r
-  else\r
-    setprg8(A,V&0x3F);\r
-}\r
-\r
-static DECLFW(M114Write)\r
-{\r
- switch(A&0xE001)\r
- {\r
-  case 0x8001: MMC3_CMDWrite(0xA000,V); break;\r
-  case 0xA000: MMC3_CMDWrite(0x8000,(V&0xC0)|(m114_perm[V&7])); cmdin=1; break;\r
-  case 0xC000: if(!cmdin) break; MMC3_CMDWrite(0x8001,V); cmdin=0; break;\r
-  case 0xA001: IRQLatch=V; break;\r
-  case 0xC001: IRQReload=1; break;\r
-  case 0xE000: X6502_IRQEnd(FCEU_IQEXT);IRQa=0; break;\r
-  case 0xE001: IRQa=1; break;\r
- }\r
-}\r
-\r
-static DECLFW(M114ExWrite)\r
-{\r
-  if(A<=0x7FFF)\r
-  {\r
-   EXPREGS[0]=V;\r
-   FixMMC3PRG(MMC3_cmd);\r
-  }\r
-}\r
-\r
-static void M114Power(void)\r
-{\r
- GenMMC3Power();\r
- SetWriteHandler(0x8000,0xFFFF,M114Write);\r
- SetWriteHandler(0x5000,0x7FFF,M114ExWrite);\r
-}\r
-\r
-static void M114Reset(void)\r
-{\r
- EXPREGS[0]=0;\r
- MMC3RegReset();\r
-}\r
-\r
-void Mapper114_Init(CartInfo *info)\r
-{\r
- isRevB=0;\r
- GenMMC3_Init(info, 256, 256, 0, 0);\r
- pwrap=M114PWRAP;\r
- info->Power=M114Power;\r
- info->Reset=M114Reset;\r
- AddExState(EXPREGS, 1, 0, "EXPR");\r
- AddExState(&cmdin, 1, 0, "CMDIN");\r
-}\r
-\r
-// ---------------------------- Mapper 115 ------------------------------\r
-\r
-static void M115PW(uint32 A, uint8 V)\r
-{\r
-       //zero 09-apr-2012 - #3515357 - changed to support Bao Qing Tian (mapper 248) which was missing BG gfx. 115 game(s?) seem still to work OK.\r
-       GENPWRAP(A,V);\r
-       if(A==0x8000 && EXPREGS[0]&0x80)\r
-               setprg16(0x8000,(EXPREGS[0]&0xF));\r
-}\r
-\r
-static void M115CW(uint32 A, uint8 V)\r
-{\r
-  setchr1(A,(uint32)V|((EXPREGS[1]&1)<<8));\r
-}\r
-\r
-static DECLFW(M115Write)\r
-{\r
-// FCEU_printf("%04x:%04x\n",A,V);\r
- if(A==0x5080) EXPREGS[2]=V;\r
- if(A==0x6000)\r
-    EXPREGS[0]=V;\r
- else if(A==0x6001)\r
-    EXPREGS[1]=V;\r
- FixMMC3PRG(MMC3_cmd);\r
-}\r
-\r
-static DECLFR(M115Read)\r
-{\r
- return EXPREGS[2];\r
-}\r
-\r
-static void M115Power(void)\r
-{\r
- GenMMC3Power();\r
- SetWriteHandler(0x4100,0x7FFF,M115Write);\r
- SetReadHandler(0x5000,0x5FFF,M115Read);\r
-}\r
-\r
-void Mapper115_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 128, 512, 0, 0);\r
- cwrap=M115CW;\r
- pwrap=M115PW;\r
- info->Power=M115Power;\r
- AddExState(EXPREGS, 2, 0, "EXPR");\r
-}\r
-\r
-// ---------------------------- Mapper 118 ------------------------------\r
-\r
-static uint8 PPUCHRBus;\r
-static uint8 TKSMIR[8];\r
-\r
-static void TKSPPU(uint32 A)\r
-{\r
- A&=0x1FFF;\r
- A>>=10;\r
- PPUCHRBus=A;\r
- setmirror(MI_0+TKSMIR[A]);\r
-}\r
-\r
-static void TKSWRAP(uint32 A, uint8 V)\r
-{\r
- TKSMIR[A>>10]=V>>7;\r
- setchr1(A,V&0x7F);\r
- if(PPUCHRBus==(A>>10))\r
-    setmirror(MI_0+(V>>7));\r
-}\r
-\r
-// ---------------------------- Mapper 119 ------------------------------\r
-\r
-static void TQWRAP(uint32 A, uint8 V)\r
-{\r
- setchr1r((V&0x40)>>2,A,V&0x3F);\r
-}\r
-\r
-void Mapper119_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 64, 0, 0);\r
- cwrap=TQWRAP;\r
- CHRRAMSize=8192;\r
- CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);\r
- SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);\r
-}\r
-\r
-// ---------------------------- Mapper 134 ------------------------------\r
-\r
-static void M134PW(uint32 A, uint8 V)\r
-{\r
-  setprg8(A,(V&0x1F)|((EXPREGS[0]&2)<<4));\r
-}\r
-\r
-static void M134CW(uint32 A, uint8 V)\r
-{\r
-  setchr1(A,(V&0xFF)|((EXPREGS[0]&0x20)<<3));\r
-}\r
-\r
-static DECLFW(M134Write)\r
-{\r
-  EXPREGS[0]=V;\r
-  FixMMC3CHR(MMC3_cmd);\r
-  FixMMC3PRG(MMC3_cmd);\r
-}\r
-\r
-static void M134Power(void)\r
-{\r
- EXPREGS[0]=0;\r
- GenMMC3Power();\r
- SetWriteHandler(0x6001,0x6001,M134Write);\r
-}\r
-\r
-static void M134Reset(void)\r
-{\r
- EXPREGS[0]=0;\r
- MMC3RegReset();\r
-}\r
-\r
-void Mapper134_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 256, 256, 0, 0);\r
- pwrap=M134PW;\r
- cwrap=M134CW;\r
- info->Power=M134Power;\r
- info->Reset=M134Reset;\r
- AddExState(EXPREGS, 4, 0, "EXPR");\r
-}\r
-\r
-// ---------------------------- Mapper 165 ------------------------------\r
-\r
-static void M165CW(uint32 A, uint8 V)\r
-{\r
- if(V==0)\r
-    setchr4r(0x10,A,0);\r
- else\r
-    setchr4(A,V>>2);\r
-}\r
-\r
-static void M165PPUFD(void)\r
-{\r
- if(EXPREGS[0]==0xFD)\r
- {\r
-  M165CW(0x0000,DRegBuf[0]);\r
-  M165CW(0x1000,DRegBuf[2]);\r
- }\r
-}\r
-\r
-static void M165PPUFE(void)\r
-{\r
- if(EXPREGS[0]==0xFE)\r
- {\r
-  M165CW(0x0000,DRegBuf[1]);\r
-  M165CW(0x1000,DRegBuf[4]);\r
- }\r
-}\r
-\r
-static void M165CWM(uint32 A, uint8 V)\r
-{\r
- if(((MMC3_cmd&0x7)==0)||((MMC3_cmd&0x7)==2))\r
-   M165PPUFD();\r
- if(((MMC3_cmd&0x7)==1)||((MMC3_cmd&0x7)==4))\r
-   M165PPUFE();\r
-}\r
-\r
-static void M165PPU(uint32 A)\r
-{\r
- if((A&0x1FF0)==0x1FD0)\r
- {\r
-  EXPREGS[0]=0xFD;\r
-  M165PPUFD();\r
- } else if((A&0x1FF0)==0x1FE0)\r
- {\r
-  EXPREGS[0]=0xFE;\r
-  M165PPUFE();\r
- }\r
-}\r
-\r
-static void M165Power(void)\r
-{\r
- EXPREGS[0]=0xFD;\r
- GenMMC3Power();\r
-}\r
-\r
-void Mapper165_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 128, 8, info->battery);\r
- cwrap=M165CWM;\r
- PPU_hook=M165PPU;\r
- info->Power=M165Power;\r
- CHRRAMSize = 4096;\r
- CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSize);\r
- SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);\r
- AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");\r
- AddExState(EXPREGS, 4, 0, "EXPR");\r
-}\r
-\r
-// ---------------------------- Mapper 191 ------------------------------\r
-\r
-static void M191CW(uint32 A, uint8 V)\r
-{\r
-  setchr1r((V&0x80)>>3,A,V);\r
-}\r
-\r
-void Mapper191_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 256, 256, 8, info->battery);\r
- cwrap=M191CW;\r
- CHRRAMSize=2048;\r
- CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);\r
- SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);\r
- AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");\r
-}\r
-\r
-// ---------------------------- Mapper 192 -------------------------------\r
-\r
-static void M192CW(uint32 A, uint8 V)\r
-{\r
-  if((V==8)||(V==9)||(V==0xA)||(V==0xB)) //Ying Lie Qun Xia Zhuan (Chinese),\r
-    setchr1r(0x10,A,V);\r
-  else\r
-    setchr1r(0,A,V);\r
-}\r
-\r
-void Mapper192_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 8, info->battery);\r
- cwrap=M192CW;\r
- CHRRAMSize=4096;\r
- CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);\r
- SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);\r
- AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");\r
-}\r
-\r
-// ---------------------------- Mapper 194 -------------------------------\r
-\r
-static void M194CW(uint32 A, uint8 V)\r
-{\r
-  if(V<=1) //Dai-2-Ji - Super Robot Taisen (As).nes\r
-    setchr1r(0x10,A,V);\r
-  else\r
-    setchr1r(0,A,V);\r
-}\r
-\r
-void Mapper194_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 8, info->battery);\r
- cwrap=M194CW;\r
- CHRRAMSize=2048;\r
- CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);\r
- SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);\r
- AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");\r
-}\r
-\r
-// ---------------------------- Mapper 195 -------------------------------\r
-static uint8 *wramtw;\r
-static uint16 wramsize;\r
-\r
-static void M195CW(uint32 A, uint8 V)\r
-{\r
-  if(V<=3) // Crystalis (c).nes, Captain Tsubasa Vol 2 - Super Striker (C)\r
-    setchr1r(0x10,A,V);\r
-  else\r
-    setchr1r(0,A,V);\r
-}\r
-\r
-static void M195Power(void)\r
-{\r
- GenMMC3Power();\r
- setprg4r(0x10,0x5000,0);\r
- SetWriteHandler(0x5000,0x5fff,CartBW);\r
- SetReadHandler(0x5000,0x5fff,CartBR);\r
-}\r
-\r
-static void M195Close(void)\r
-{\r
-  if(wramtw)\r
-    FCEU_gfree(wramtw);\r
-  wramtw=NULL;\r
-}\r
-\r
-void Mapper195_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 8, info->battery);\r
- cwrap=M195CW;\r
- info->Power=M195Power;\r
- info->Close=M195Close;\r
- CHRRAMSize=4096;\r
- CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);\r
- SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);\r
- wramsize=4096;\r
- wramtw=(uint8*)FCEU_gmalloc(wramsize);\r
- SetupCartPRGMapping(0x10, wramtw, wramsize, 1);\r
- AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");\r
- AddExState(wramtw, wramsize, 0, "WRAMTW");\r
-}\r
-\r
-// ---------------------------- Mapper 196 -------------------------------\r
-\r
-static DECLFW(Mapper196Write)\r
-{\r
-  A=(A&0xFFFE)|((A>>2)&1)|((A>>3)&1)|((A>>1)&1);\r
-  if(A >= 0xC000)\r
-   MMC3_IRQWrite(A,V);\r
-  else\r
-   MMC3_CMDWrite(A,V);\r
-}\r
-\r
-static void Mapper196Power(void)\r
-{\r
-  GenMMC3Power();\r
-  SetWriteHandler(0x8000,0xFFFF,Mapper196Write);\r
-}\r
-\r
-void Mapper196_Init(CartInfo *info)\r
-{\r
-  GenMMC3_Init(info, 128, 128, 0, 0);\r
-  info->Power=Mapper196Power;\r
-}\r
-\r
-// ---------------------------- Mapper 197 -------------------------------\r
-\r
-static void M197CW(uint32 A, uint8 V)\r
-{\r
-  if(A==0x0000)\r
-    setchr4(0x0000,V>>1);\r
-  else if(A==0x1000)\r
-    setchr2(0x1000,V);\r
-  else if(A==0x1400)\r
-    setchr2(0x1800,V);\r
-}\r
-\r
-void Mapper197_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 128, 512, 8, 0);\r
- cwrap=M197CW;\r
-}\r
-\r
-// ---------------------------- Mapper 198 -------------------------------\r
-\r
-static void M198PW(uint32 A, uint8 V)\r
-{\r
-  if(V>=0x50) // Tenchi o Kurau II - Shokatsu Koumei Den (J) (C).nes\r
-    setprg8(A,V&0x4F);\r
-  else\r
-    setprg8(A,V);\r
-}\r
-\r
-void Mapper198_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 1024, 256, 8, info->battery);\r
- pwrap=M198PW;\r
- info->Power=M195Power;\r
- info->Close=M195Close;\r
- wramsize=4096;\r
- wramtw=(uint8*)FCEU_gmalloc(wramsize);\r
- SetupCartPRGMapping(0x10, wramtw, wramsize, 1);\r
- AddExState(wramtw, wramsize, 0, "WRAMTW");\r
-}\r
-\r
-// ---------------------------- Mapper 205 ------------------------------\r
-\r
-static void M205PW(uint32 A, uint8 V)\r
-{\r
- if(EXPREGS[0]&2)\r
-    setprg8(A,(V&0x0f)|((EXPREGS[0]&3)<<4));\r
- else\r
-    setprg8(A,(V&0x1f)|((EXPREGS[0]&3)<<4));\r
-}\r
-\r
-static void M205CW(uint32 A, uint8 V)\r
-{\r
- setchr1(A,V|((EXPREGS[0]&3)<<7));\r
-}\r
-\r
-static DECLFW(M205Write)\r
-{\r
- if((A&0x6800)==0x6800) EXPREGS[0]= V;\r
- FixMMC3PRG(MMC3_cmd);\r
- FixMMC3CHR(MMC3_cmd);\r
-}\r
-\r
-static void M205Reset(void)\r
-{\r
- EXPREGS[0]=0;\r
- MMC3RegReset();\r
-}\r
-\r
-static void M205Power(void)\r
-{\r
- GenMMC3Power();\r
- SetWriteHandler(0x4020,0x7FFF,M205Write);\r
-}\r
-\r
-void Mapper205_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 8, 0);\r
- pwrap=M205PW;\r
- cwrap=M205CW;\r
- info->Power=M205Power;\r
- info->Reset=M205Reset;\r
- AddExState(EXPREGS, 1, 0, "EXPR");\r
-}\r
-\r
-// ---------------------------- Mapper 245 ------------------------------\r
-\r
-static void M245CW(uint32 A, uint8 V)\r
-{\r
- if(!UNIFchrrama) // Yong Zhe Dou E Long - Dragon Quest VI (As).nes NEEDS THIS for RAM cart\r
-  setchr1(A,V&7);\r
- EXPREGS[0]=V;\r
- FixMMC3PRG(MMC3_cmd);\r
-}\r
-\r
-static void M245PW(uint32 A, uint8 V)\r
-{\r
- setprg8(A,(V&0x3F)|((EXPREGS[0]&2)<<5));\r
-}\r
-\r
-static void M245Power(void)\r
-{\r
- EXPREGS[0]=0;\r
- GenMMC3Power();\r
-}\r
-\r
-void Mapper245_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 8, info->battery);\r
- cwrap=M245CW;\r
- pwrap=M245PW;\r
- info->Power=M245Power;\r
- AddExState(EXPREGS, 1, 0, "EXPR");\r
-}\r
-\r
-// ---------------------------- Mapper 249 ------------------------------\r
-\r
-static void M249PW(uint32 A, uint8 V)\r
-{\r
- if(EXPREGS[0]&0x2)\r
- {\r
-  if(V<0x20)\r
-   V=(V&1)|((V>>3)&2)|((V>>1)&4)|((V<<2)&8)|((V<<2)&0x10);\r
-  else\r
-  {\r
-   V-=0x20;\r
-   V=(V&3)|((V>>1)&4)|((V>>4)&8)|((V>>2)&0x10)|((V<<3)&0x20)|((V<<2)&0xC0);\r
-  }\r
- }\r
- setprg8(A,V);\r
-}\r
-\r
-static void M249CW(uint32 A, uint8 V)\r
-{\r
- if(EXPREGS[0]&0x2)\r
-    V=(V&3)|((V>>1)&4)|((V>>4)&8)|((V>>2)&0x10)|((V<<3)&0x20)|((V<<2)&0xC0);\r
- setchr1(A,V);\r
-}\r
-\r
-static DECLFW(M249Write)\r
-{\r
- EXPREGS[0]=V;\r
- FixMMC3PRG(MMC3_cmd);\r
- FixMMC3CHR(MMC3_cmd);\r
-}\r
-\r
-static void M249Power(void)\r
-{\r
- EXPREGS[0]=0;\r
- GenMMC3Power();\r
- SetWriteHandler(0x5000,0x5000,M249Write);\r
-}\r
-\r
-void Mapper249_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 8, info->battery);\r
- cwrap=M249CW;\r
- pwrap=M249PW;\r
- info->Power=M249Power;\r
- AddExState(EXPREGS, 1, 0, "EXPR");\r
-}\r
-\r
-// ---------------------------- Mapper 250 ------------------------------\r
-\r
-static DECLFW(M250Write)\r
-{\r
- MMC3_CMDWrite((A&0xE000)|((A&0x400)>>10),A&0xFF);\r
-}\r
-\r
-static DECLFW(M250IRQWrite)\r
-{\r
- MMC3_IRQWrite((A&0xE000)|((A&0x400)>>10),A&0xFF);\r
-}\r
-\r
-static void M250_Power(void)\r
-{\r
- GenMMC3Power();\r
- SetWriteHandler(0x8000,0xBFFF,M250Write);\r
- SetWriteHandler(0xC000,0xFFFF,M250IRQWrite);\r
-}\r
-\r
-void Mapper250_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 8, info->battery);\r
- info->Power=M250_Power;\r
-}\r
-\r
-// ---------------------------- Mapper 254 ------------------------------\r
-\r
-static DECLFR(MR254WRAM)\r
-{\r
-  if(EXPREGS[0])\r
-    return WRAM[A-0x6000];\r
-  else\r
-    return WRAM[A-0x6000]^EXPREGS[1];\r
-}\r
-\r
-static DECLFW(M254Write)\r
-{\r
- switch (A) {\r
-  case 0x8000: EXPREGS[0]=0xff;\r
-               break;\r
-  case 0xA001: EXPREGS[1]=V;\r
- }\r
- MMC3_CMDWrite(A,V);\r
-}\r
-\r
-static void M254_Power(void)\r
-{\r
- GenMMC3Power();\r
- SetWriteHandler(0x8000,0xBFFF,M254Write);\r
- SetReadHandler(0x6000,0x7FFF,MR254WRAM);\r
-}\r
-\r
-void Mapper254_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 128, 128, 8, info->battery);\r
- info->Power=M254_Power;\r
- AddExState(EXPREGS, 2, 0, "EXPR");\r
-}\r
-\r
-// ---------------------------- UNIF Boards -----------------------------\r
-\r
-void TBROM_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 64, 64, 0, 0);\r
-}\r
-\r
-void TEROM_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 32, 32, 0, 0);\r
-}\r
-\r
-void TFROM_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 64, 0, 0);\r
-}\r
-\r
-void TGROM_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 0, 0, 0);\r
-}\r
-\r
-void TKROM_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 8, info->battery);\r
-}\r
-\r
-void TLROM_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 0, 0);\r
-}\r
-\r
-void TSROM_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 8, 0);\r
-}\r
-\r
-void TLSROM_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 8, 0);\r
- cwrap=TKSWRAP;\r
- mwrap=GENNOMWRAP;\r
- PPU_hook=TKSPPU;\r
- AddExState(&PPUCHRBus, 1, 0, "PPUC");\r
-}\r
-\r
-void TKSROM_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 256, 8, info->battery);\r
- cwrap=TKSWRAP;\r
- mwrap=GENNOMWRAP;\r
- PPU_hook=TKSPPU;\r
- AddExState(&PPUCHRBus, 1, 0, "PPUC");\r
-}\r
-\r
-void TQROM_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 64, 0, 0);\r
- cwrap=TQWRAP;\r
- CHRRAMSize=8192;\r
- CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);\r
- SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);\r
-}\r
-\r
-void HKROM_Init(CartInfo *info)\r
-{\r
- GenMMC3_Init(info, 512, 512, 1, info->battery);\r
-}\r
+/* FCE Ultra - NES/Famicom Emulator
+ *
+ * Copyright notice for this file:
+ *  Copyright (C) 1998 BERO
+ *  Copyright (C) 2003 Xodnizel
+ *  Mapper 12 code Copyright (C) 2003 CaH4e3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*  Code for emulating iNES mappers 4,12,44,45,47,49,52,74,114,115,116,118,
+    119,165,205,245,249,250,254
+*/
+
+#include "mapinc.h"
+#include "mmc3.h"
+
+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,IRQLatch,IRQa;
+uint8 IRQReload;
+
+static SFORMAT MMC3_StateRegs[]=
+{
+ {DRegBuf, 8, "REGS"},
+ {&MMC3_cmd, 1, "CMD"},
+ {&A000B, 1, "A000"},
+ {&A001B, 1, "A001"},
+ {&IRQReload, 1, "IRQR"},
+ {&IRQCount, 1, "IRQC"},
+ {&IRQLatch, 1, "IRQL"},
+ {&IRQa, 1, "IRQA"},
+ {0}
+};
+
+static int wrams;
+static int isRevB=1;
+
+void (*pwrap)(uint32 A, uint8 V);
+void (*cwrap)(uint32 A, uint8 V);
+void (*mwrap)(uint8 V);
+
+void GenMMC3Power(void);
+void FixMMC3PRG(int V);
+void FixMMC3CHR(int V);
+
+void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery);
+
+// ----------------------------------------------------------------------
+// ------------------------- Generic MM3 Code ---------------------------
+// ----------------------------------------------------------------------
+
+void FixMMC3PRG(int V)
+{
+ if(V&0x40)
+ {
+  pwrap(0xC000,DRegBuf[6]);
+  pwrap(0x8000,~1);
+ }
+ else
+ {
+  pwrap(0x8000,DRegBuf[6]);
+  pwrap(0xC000,~1);
+ }
+ pwrap(0xA000,DRegBuf[7]);
+ pwrap(0xE000,~0);
+}
+
+void FixMMC3CHR(int V)
+{
+ int cbase=(V&0x80)<<5;
+
+ cwrap((cbase^0x000),DRegBuf[0]&(~1));
+ cwrap((cbase^0x400),DRegBuf[0]|1);
+ cwrap((cbase^0x800),DRegBuf[1]&(~1));
+ cwrap((cbase^0xC00),DRegBuf[1]|1);
+
+ cwrap(cbase^0x1000,DRegBuf[2]);
+ cwrap(cbase^0x1400,DRegBuf[3]);
+ cwrap(cbase^0x1800,DRegBuf[4]);
+ cwrap(cbase^0x1c00,DRegBuf[5]);
+
+ if(mwrap) mwrap(A000B);
+}
+
+void MMC3RegReset(void)
+{
+ IRQCount=IRQLatch=IRQa=MMC3_cmd=0;
+
+ DRegBuf[0]=0;
+ DRegBuf[1]=2;
+ DRegBuf[2]=4;
+ DRegBuf[3]=5;
+ DRegBuf[4]=6;
+ DRegBuf[5]=7;
+ DRegBuf[6]=0;
+ DRegBuf[7]=1;
+
+ FixMMC3PRG(0);
+ FixMMC3CHR(0);
+}
+
+DECLFW(MMC3_CMDWrite)
+{
+// FCEU_printf("bs %04x %02x\n",A,V);
+ switch(A&0xE001)
+ {
+  case 0x8000:
+       if((V&0x40) != (MMC3_cmd&0x40))
+          FixMMC3PRG(V);
+       if((V&0x80) != (MMC3_cmd&0x80))
+          FixMMC3CHR(V);
+       MMC3_cmd = V;
+       break;
+  case 0x8001:
+       {
+        int cbase=(MMC3_cmd&0x80)<<5;
+        DRegBuf[MMC3_cmd&0x7]=V;
+        switch(MMC3_cmd&0x07)
+        {
+         case 0: cwrap((cbase^0x000),V&(~1));
+                 cwrap((cbase^0x400),V|1);
+                 break;
+         case 1: cwrap((cbase^0x800),V&(~1));
+                 cwrap((cbase^0xC00),V|1);
+                 break;
+         case 2: cwrap(cbase^0x1000,V);
+                 break;
+         case 3: cwrap(cbase^0x1400,V);
+                 break;
+         case 4: cwrap(cbase^0x1800,V);
+                 break;
+         case 5: cwrap(cbase^0x1C00,V);
+                 break;
+         case 6:
+                 if(MMC3_cmd&0x40)
+                    pwrap(0xC000,V);
+                 else
+                    pwrap(0x8000,V);
+                 break;
+         case 7:
+                 pwrap(0xA000,V);
+                 break;
+        }
+       }
+       break;
+  case 0xA000:
+       if(mwrap) mwrap(V);
+       break;
+  case 0xA001:
+       A001B=V;
+       break;
+ }
+}
+
+DECLFW(MMC3_IRQWrite)
+{
+// FCEU_printf("%04x:%04x\n",A,V);
+ switch(A&0xE001)
+ {
+  case 0xC000:IRQLatch=V;break;
+  case 0xC001:IRQReload=1;break;
+  case 0xE000:X6502_IRQEnd(FCEU_IQEXT);IRQa=0;break;
+  case 0xE001:IRQa=1;break;
+ }
+}
+
+static void ClockMMC3Counter(void)
+{
+ int count = IRQCount;
+ if(!count || IRQReload)
+ {
+    IRQCount = IRQLatch;
+    IRQReload = 0;
+ }
+ else
+    IRQCount--;
+ if((count|isRevB) && !IRQCount)
+ {
+    if(IRQa)
+    {
+       X6502_IRQBegin(FCEU_IQEXT);
+    }
+ }
+}
+
+static void MMC3_hb(void)
+{
+ ClockMMC3Counter();
+}
+
+static void MMC3_hb_KickMasterHack(void)
+{
+ if(scanline==238) ClockMMC3Counter();
+ ClockMMC3Counter();
+}
+
+static void MMC3_hb_PALStarWarsHack(void)
+{
+ if(scanline==240) ClockMMC3Counter();
+ ClockMMC3Counter();
+}
+
+void GenMMC3Restore(int version)
+{
+ FixMMC3PRG(MMC3_cmd);
+ FixMMC3CHR(MMC3_cmd);
+}
+
+static void GENCWRAP(uint32 A, uint8 V)
+{
+   setchr1(A,V);    // Business Wars NEEDS THIS for 8K CHR-RAM
+}
+
+static void GENPWRAP(uint32 A, uint8 V)
+{
+ 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)^1);
+}
+
+static void GENNOMWRAP(uint8 V)
+{
+ A000B=V;
+}
+
+static DECLFW(MBWRAMMMC6)
+{
+ WRAM[A&0x3ff]=V;
+}
+
+static DECLFR(MAWRAMMMC6)
+{
+ return(WRAM[A&0x3ff]);
+}
+
+void GenMMC3Power(void)
+{
+ if(UNIFchrrama) setchr8(0);
+
+ SetWriteHandler(0x8000,0xBFFF,MMC3_CMDWrite);
+ SetWriteHandler(0xC000,0xFFFF,MMC3_IRQWrite);
+ SetReadHandler(0x8000,0xFFFF,CartBR);
+ A001B=A000B=0;
+ setmirror(1);
+ if(mmc3opts&1)
+ {
+  if(wrams==1024)
+  {
+   FCEU_CheatAddRAM(1,0x7000,WRAM);
+   SetReadHandler(0x7000,0x7FFF,MAWRAMMMC6);
+   SetWriteHandler(0x7000,0x7FFF,MBWRAMMMC6);
+  }
+  else
+  {
+   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);
+}
+
+static void GenMMC3Close(void)
+{
+ if(CHRRAM)
+    FCEU_gfree(CHRRAM);
+ if(WRAM)
+    FCEU_gfree(WRAM);
+ CHRRAM=WRAM=NULL;
+}
+
+void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery)
+{
+ pwrap=GENPWRAP;
+ cwrap=GENCWRAP;
+ mwrap=GENMWRAP;
+
+ wrams=wram<<10;
+
+ PRGmask8[0]&=(prg>>13)-1;
+ CHRmask1[0]&=(chr>>10)-1;
+ CHRmask2[0]&=(chr>>11)-1;
+
+ if(wram)
+ {
+  mmc3opts|=1;
+  WRAM=(uint8*)FCEU_gmalloc(wrams);
+  SetupCartPRGMapping(0x10,WRAM,wrams,1);
+  AddExState(WRAM, wrams, 0, "MRAM");
+ }
+
+ if(battery)
+ {
+  mmc3opts|=2;
+  info->SaveGame[0]=WRAM;
+  info->SaveGameLen[0]=wrams;
+ }
+
+ AddExState(MMC3_StateRegs, ~0, 0, 0);
+
+ info->Power=GenMMC3Power;
+ info->Reset=MMC3RegReset;
+ info->Close=GenMMC3Close;
+
+ if(info->CRC32 == 0x5104833e)        // Kick Master
+  GameHBIRQHook = MMC3_hb_KickMasterHack;
+ else if(info->CRC32 == 0x5a6860f1 || info->CRC32 == 0xae280e20) // Shougi Meikan '92/'93
+  GameHBIRQHook = MMC3_hb_KickMasterHack;
+ else if(info->CRC32 == 0xfcd772eb)    // PAL Star Wars, similar problem as Kick Master.
+  GameHBIRQHook = MMC3_hb_PALStarWarsHack;
+ else
+  GameHBIRQHook=MMC3_hb;
+ GameStateRestore=GenMMC3Restore;
+}
+
+// ----------------------------------------------------------------------
+// -------------------------- MMC3 Based Code ---------------------------
+// ----------------------------------------------------------------------
+
+// ---------------------------- Mapper 4 --------------------------------
+
+static int hackm4=0;/* For Karnov, maybe others.  BLAH.  Stupid iNES format.*/
+
+static void M4Power(void)
+{
+ GenMMC3Power();
+ A000B=(hackm4^1)&1;
+ setmirror(hackm4);
+}
+
+void Mapper4_Init(CartInfo *info)
+{
+ int ws=8;
+
+ if((info->CRC32==0x93991433 || info->CRC32==0xaf65aa84))
+ {
+  FCEU_printf("Low-G-Man can not work normally in the iNES format.\nThis game has been recognized by its CRC32 value, and the appropriate changes will be made so it will run.\nIf you wish to hack this game, you should use the UNIF format for your hack.\n\n");
+  ws=0;
+ }
+ GenMMC3_Init(info,512,256,ws,info->battery);
+ info->Power=M4Power;
+ hackm4=info->mirror;
+}
+
+// ---------------------------- Mapper 12 -------------------------------
+
+static void M12CW(uint32 A, uint8 V)
+{
+ setchr1(A,(EXPREGS[(A&0x1000)>>12]<<8)+V);
+}
+
+static DECLFW(M12Write)
+{
+ EXPREGS[0]=V&0x01;
+ EXPREGS[1]=(V&0x10)>>4;
+}
+
+static void M12Power(void)
+{
+ EXPREGS[0]=EXPREGS[1]=0;
+ GenMMC3Power();
+ SetWriteHandler(0x4100,0x5FFF,M12Write);
+}
+
+void Mapper12_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 256, 8, info->battery);
+ cwrap=M12CW;
+ info->Power=M12Power;
+ 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)
+{
+ uint32 NV=V;
+ if(EXPREGS[0]>=6) NV&=0x1F;
+ else NV&=0x0F;
+ NV|=EXPREGS[0]<<4;
+ setprg8(A,NV);
+}
+
+static void M44CW(uint32 A, uint8 V)
+{
+ uint32 NV=V;
+ if(EXPREGS[0]<6) NV&=0x7F;
+ NV|=EXPREGS[0]<<7;
+ setchr1(A,NV);
+}
+
+static DECLFW(M44Write)
+{
+ if(A&1)
+ {
+  EXPREGS[0]=V&7;
+  FixMMC3PRG(MMC3_cmd);
+  FixMMC3CHR(MMC3_cmd);
+ }
+ else
+  MMC3_CMDWrite(A,V);
+}
+
+static void M44Power(void)
+{
+ EXPREGS[0]=0;
+ GenMMC3Power();
+ SetWriteHandler(0xA000,0xBFFF,M44Write);
+}
+
+void Mapper44_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 256, 8, info->battery);
+ cwrap=M44CW;
+ pwrap=M44PW;
+ info->Power=M44Power;
+ AddExState(EXPREGS, 1, 0, "EXPR");
+}
+
+// ---------------------------- Mapper 45 -------------------------------
+
+static void M45CW(uint32 A, uint8 V)
+{
+ 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)
+{
+ V&=(EXPREGS[3]&0x3F)^0x3F;
+ V|=EXPREGS[1];
+ setprg8(A,V);
+}
+
+static DECLFW(M45Write)
+{
+ if(EXPREGS[3]&0x40)
+ {
+  WRAM[A-0x6000]=V;
+  return;
+ }
+ EXPREGS[EXPREGS[4]]=V;
+ EXPREGS[4]=(EXPREGS[4]+1)&3;
+// 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)
+{
+ EXPREGS[0]=EXPREGS[1]=EXPREGS[2]=EXPREGS[3]=EXPREGS[4]=0;
+ EXPREGS[5]++;
+ EXPREGS[5] &= 7;
+ MMC3RegReset();
+}
+
+static void M45Power(void)
+{
+ setchr8(0);
+ GenMMC3Power();
+ 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)
+{
+ GenMMC3_Init(info, 512, 256, 8, info->battery);
+ cwrap=M45CW;
+ pwrap=M45PW;
+ info->Reset=M45Reset;
+ info->Power=M45Power;
+ AddExState(EXPREGS, 5, 0, "EXPR");
+}
+
+// ---------------------------- Mapper 47 -------------------------------
+
+static void M47PW(uint32 A, uint8 V)
+{
+ V&=0xF;
+ V|=EXPREGS[0]<<4;
+ setprg8(A,V);
+}
+
+static void M47CW(uint32 A, uint8 V)
+{
+ uint32 NV=V;
+ NV&=0x7F;
+ NV|=EXPREGS[0]<<7;
+ setchr1(A,NV);
+}
+
+static DECLFW(M47Write)
+{
+ EXPREGS[0]=V&1;
+ FixMMC3PRG(MMC3_cmd);
+ FixMMC3CHR(MMC3_cmd);
+}
+
+static void M47Power(void)
+{
+ EXPREGS[0]=0;
+ GenMMC3Power();
+ SetWriteHandler(0x6000,0x7FFF,M47Write);
+// SetReadHandler(0x6000,0x7FFF,0);
+}
+
+void Mapper47_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 256, 8, 0);
+ pwrap=M47PW;
+ cwrap=M47CW;
+ info->Power=M47Power;
+ AddExState(EXPREGS, 1, 0, "EXPR");
+}
+
+// ---------------------------- Mapper 49 -------------------------------
+
+static void M49PW(uint32 A, uint8 V)
+{
+ if(EXPREGS[0]&1)
+ {
+  V&=0xF;
+  V|=(EXPREGS[0]&0xC0)>>2;
+  setprg8(A,V);
+ }
+ else
+  setprg32(0x8000,(EXPREGS[0]>>4)&3);
+}
+
+static void M49CW(uint32 A, uint8 V)
+{
+ uint32 NV=V;
+ NV&=0x7F;
+ NV|=(EXPREGS[0]&0xC0)<<1;
+ setchr1(A,NV);
+}
+
+static DECLFW(M49Write)
+{
+ if(A001B&0x80)
+ {
+  EXPREGS[0]=V;
+  FixMMC3PRG(MMC3_cmd);
+  FixMMC3CHR(MMC3_cmd);
+ }
+}
+
+static void M49Reset(void)
+{
+ EXPREGS[0]=0;
+ MMC3RegReset();
+}
+
+static void M49Power(void)
+{
+ M49Reset();
+ GenMMC3Power();
+ SetWriteHandler(0x6000,0x7FFF,M49Write);
+ SetReadHandler(0x6000,0x7FFF,0);
+}
+
+void Mapper49_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 256, 0, 0);
+ cwrap=M49CW;
+ pwrap=M49PW;
+ info->Reset=M49Reset;
+ info->Power=M49Power;
+ AddExState(EXPREGS, 1, 0, "EXPR");
+}
+
+// ---------------------------- Mapper 52 -------------------------------
+static void M52PW(uint32 A, uint8 V)
+{
+ 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 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)
+{
+ if(EXPREGS[1])
+ {
+  WRAM[A-0x6000]=V;
+  return;
+ }
+ EXPREGS[1]=V&0x80;
+ EXPREGS[0]=V;
+ FixMMC3PRG(MMC3_cmd);
+ FixMMC3CHR(MMC3_cmd);
+}
+
+static void M52Reset(void)
+{
+ EXPREGS[0]=EXPREGS[1]=0;
+ MMC3RegReset();
+}
+
+static void M52Power(void)
+{
+ M52Reset();
+ GenMMC3Power();
+ SetWriteHandler(0x6000,0x7FFF,M52Write);
+}
+
+void Mapper52_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 256, 256, 8, info->battery);
+ cwrap=M52CW;
+ pwrap=M52PW;
+ info->Reset=M52Reset;
+ info->Power=M52Power;
+ AddExState(EXPREGS, 2, 0, "EXPR");
+}
+
+// ---------------------------- Mapper 74 -------------------------------
+
+static void M74CW(uint32 A, uint8 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(0,A,V);
+}
+
+void Mapper74_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 256, 8, info->battery);
+ cwrap=M74CW;
+ CHRRAMSize=2048;
+ CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
+ SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
+ AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
+}
+
+// ---------------------------- Mapper 114 ------------------------------
+
+static uint8 cmdin;
+uint8 m114_perm[8] = {0, 3, 1, 5, 6, 7, 2, 4};
+
+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 {
+//    FCEU_printf("%04X:%02X\n",A,V&0x3F);
+    setprg8(A,V&0x3F);
+  }
+}
+
+static DECLFW(M114Write)
+{
+  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);
+  }
+}
+
+static void M114Power(void)
+{
+  GenMMC3Power();
+  SetWriteHandler(0x8000,0xFFFF,M114Write);
+  SetWriteHandler(0x5000,0x7FFF,M114ExWrite);
+}
+
+static void M114Reset(void)
+{
+  EXPREGS[0]=0;
+  MMC3RegReset();
+}
+
+void Mapper114_Init(CartInfo *info)
+{
+  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 KN-658 board ------------------------------
+
+static void M115PW(uint32 A, uint8 V)
+{
+  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));
+}
+
+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)
+    EXPREGS[1]=V;
+ FixMMC3PRG(MMC3_cmd);
+}
+
+static DECLFR(M115Read)
+{
+ return EXPREGS[2];
+}
+
+static void M115Power(void)
+{
+ GenMMC3Power();
+ SetWriteHandler(0x4100,0x7FFF,M115Write);
+ SetReadHandler(0x5000,0x5FFF,M115Read);
+}
+
+void Mapper115_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 128, 512, 0, 0);
+ cwrap=M115CW;
+ pwrap=M115PW;
+ info->Power=M115Power;
+ AddExState(EXPREGS, 2, 0, "EXPR");
+}
+
+// ---------------------------- Mapper 118 ------------------------------
+
+static uint8 PPUCHRBus;
+static uint8 TKSMIR[8];
+
+static void FP_FASTAPASS(1) TKSPPU(uint32 A)
+{
+ A&=0x1FFF;
+ A>>=10;
+ PPUCHRBus=A;
+ setmirror(MI_0+TKSMIR[A]);
+}
+
+static void TKSWRAP(uint32 A, uint8 V)
+{
+ TKSMIR[A>>10]=V>>7;
+ setchr1(A,V&0x7F);
+ if(PPUCHRBus==(A>>10))
+    setmirror(MI_0+(V>>7));
+}
+
+// ---------------------------- Mapper 119 ------------------------------
+
+static void TQWRAP(uint32 A, uint8 V)
+{
+ setchr1r((V&0x40)>>2,A,V&0x3F);
+}
+
+void Mapper119_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 64, 0, 0);
+ cwrap=TQWRAP;
+ CHRRAMSize=8192;
+ CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
+ SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
+}
+
+// ---------------------------- Mapper 134 ------------------------------
+
+static void M134PW(uint32 A, uint8 V)
+{
+  setprg8(A,(V&0x1F)|((EXPREGS[0]&2)<<4));
+}
+
+static void M134CW(uint32 A, uint8 V)
+{
+  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 ------------------------------
+
+static void M165CW(uint32 A, uint8 V)
+{
+ if(V==0)
+    setchr4r(0x10,A,0);
+ else
+    setchr4(A,V>>2);
+}
+
+static void M165PPUFD(void)
+{
+ if(EXPREGS[0]==0xFD)
+ {
+  M165CW(0x0000,DRegBuf[0]);
+  M165CW(0x1000,DRegBuf[2]);
+ }
+}
+
+static void M165PPUFE(void)
+{
+ if(EXPREGS[0]==0xFE)
+ {
+  M165CW(0x0000,DRegBuf[1]);
+  M165CW(0x1000,DRegBuf[4]);
+ }
+}
+
+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();
+}
+
+static void FP_FASTAPASS(1) M165PPU(uint32 A)
+{
+ if((A&0x1FF0)==0x1FD0)
+ {
+  EXPREGS[0]=0xFD;
+  M165PPUFD();
+ } else if((A&0x1FF0)==0x1FE0)
+ {
+  EXPREGS[0]=0xFE;
+  M165PPUFE();
+ }
+}
+
+static void M165Power(void)
+{
+ EXPREGS[0]=0xFD;
+ GenMMC3Power();
+}
+
+void Mapper165_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 128, 8, info->battery);
+ cwrap=M165CWM;
+ PPU_hook=M165PPU;
+ info->Power=M165Power;
+ CHRRAMSize = 4096;
+ CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSize);
+ SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
+ AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
+ AddExState(EXPREGS, 4, 0, "EXPR");
+}
+
+// ---------------------------- 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 195 -------------------------------
+static uint8 *wramtw;
+static uint16 wramsize;
+
+static void M195CW(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 M195Power(void)
+{
+ GenMMC3Power();
+ setprg4r(0x10,0x5000,0);
+ SetWriteHandler(0x5000,0x5fff,CartBW);
+ SetReadHandler(0x5000,0x5fff,CartBR);
+}
+
+static void M195Close(void)
+{
+  if(wramtw)
+    FCEU_gfree(wramtw);
+  wramtw=NULL;
+}
+
+void Mapper195_Init(CartInfo *info)
+{
+ 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");
+}
+
+// ---------------------------- 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]) // Tenchi o Kurau II - Shokatsu Koumei Den (J) (C).nes
+    setprg32(0x8000,EXPREGS[1]);
+  else
+    setprg8(A,V);
+}
+
+static DECLFW(Mapper196Write)
+{
+  if(A >= 0xC000) {
+   A=(A&0xFFFE)|((A>>2)&1)|((A>>3)&1);
+   MMC3_IRQWrite(A,V);
+  }
+  else {
+   A=(A&0xFFFE)|((A>>2)&1)|((A>>3)&1)|((A>>1)&1);
+   MMC3_CMDWrite(A,V);
+  }
+}
+
+static DECLFW(Mapper196WriteLo)
+{
+  EXPREGS[0]=1;
+  EXPREGS[1]=(V&0xf)|(V>>4);
+  FixMMC3PRG(MMC3_cmd);
+}
+
+static void Mapper196Power(void)
+{
+  GenMMC3Power();
+  EXPREGS[0] = EXPREGS[1] = 0;
+  SetWriteHandler(0x6000,0x6FFF,Mapper196WriteLo);
+  SetWriteHandler(0x8000,0xFFFF,Mapper196Write);
+}
+
+void Mapper196_Init(CartInfo *info)
+{
+  GenMMC3_Init(info, 128, 128, 0, 0);
+  pwrap=M196PW;
+  info->Power=Mapper196Power;
+}
+
+// ---------------------------- Mapper 197 -------------------------------
+
+static void M197CW(uint32 A, uint8 V)
+{
+  if(A==0x0000)
+    setchr4(0x0000,V>>1);
+  else if(A==0x1000)
+    setchr2(0x1000,V);
+  else if(A==0x1400)
+    setchr2(0x1800,V);
+}
+
+void Mapper197_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 128, 512, 8, 0);
+ cwrap=M197CW;
+}
+
+// ---------------------------- Mapper 198 -------------------------------
+
+static void M198PW(uint32 A, uint8 V)
+{
+  if(V>=0x50) // Tenchi o Kurau II - Shokatsu Koumei Den (J) (C).nes
+    setprg8(A,V&0x4F);
+  else
+    setprg8(A,V);
+}
+
+void Mapper198_Init(CartInfo *info)
+{
+ 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 M205Reset(void)
+{
+ EXPREGS[0]=EXPREGS[2]=0;
+ MMC3RegReset();
+}
+
+static void M205Power(void)
+{
+ GenMMC3Power();
+ SetWriteHandler(0x6000,0x6fff,M205Write);
+}
+
+void Mapper205_Init(CartInfo *info)
+{
+ 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)
+{
+ 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);
+}
+
+static void M245PW(uint32 A, uint8 V)
+{
+ setprg8(A,(V&0x3F)|((EXPREGS[0]&2)<<5));
+}
+
+static void M245Power(void)
+{
+ EXPREGS[0]=0;
+ GenMMC3Power();
+}
+
+void Mapper245_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 256, 8, info->battery);
+ cwrap=M245CW;
+ pwrap=M245PW;
+ info->Power=M245Power;
+ AddExState(EXPREGS, 1, 0, "EXPR");
+}
+
+// ---------------------------- Mapper 249 ------------------------------
+
+static void M249PW(uint32 A, uint8 V)
+{
+ if(EXPREGS[0]&0x2)
+ {
+  if(V<0x20)
+   V=(V&1)|((V>>3)&2)|((V>>1)&4)|((V<<2)&8)|((V<<2)&0x10);
+  else
+  {
+   V-=0x20;
+   V=(V&3)|((V>>1)&4)|((V>>4)&8)|((V>>2)&0x10)|((V<<3)&0x20)|((V<<2)&0xC0);
+  }
+ }
+ setprg8(A,V);
+}
+
+static void M249CW(uint32 A, uint8 V)
+{
+ if(EXPREGS[0]&0x2)
+    V=(V&3)|((V>>1)&4)|((V>>4)&8)|((V>>2)&0x10)|((V<<3)&0x20)|((V<<2)&0xC0);
+ setchr1(A,V);
+}
+
+static DECLFW(M249Write)
+{
+ EXPREGS[0]=V;
+ FixMMC3PRG(MMC3_cmd);
+ FixMMC3CHR(MMC3_cmd);
+}
+
+static void M249Power(void)
+{
+ EXPREGS[0]=0;
+ GenMMC3Power();
+ SetWriteHandler(0x5000,0x5000,M249Write);
+}
+
+void Mapper249_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 256, 8, info->battery);
+ cwrap=M249CW;
+ pwrap=M249PW;
+ info->Power=M249Power;
+ AddExState(EXPREGS, 1, 0, "EXPR");
+}
+
+// ---------------------------- Mapper 250 ------------------------------
+
+static DECLFW(M250Write)
+{
+ MMC3_CMDWrite((A&0xE000)|((A&0x400)>>10),A&0xFF);
+}
+
+static DECLFW(M250IRQWrite)
+{
+ MMC3_IRQWrite((A&0xE000)|((A&0x400)>>10),A&0xFF);
+}
+
+static void M250_Power(void)
+{
+ GenMMC3Power();
+ SetWriteHandler(0x8000,0xBFFF,M250Write);
+ SetWriteHandler(0xC000,0xFFFF,M250IRQWrite);
+}
+
+void Mapper250_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 256, 8, info->battery);
+ info->Power=M250_Power;
+}
+
+// ---------------------------- Mapper 254 ------------------------------
+
+static DECLFR(MR254WRAM)
+{
+  if(EXPREGS[0])
+    return WRAM[A-0x6000];
+  else
+    return WRAM[A-0x6000]^EXPREGS[1];
+}
+
+static DECLFW(M254Write)
+{
+ switch (A) {
+  case 0x8000: EXPREGS[0]=0xff;
+               break;
+  case 0xA001: EXPREGS[1]=V;
+ }
+ MMC3_CMDWrite(A,V);
+}
+
+static void M254_Power(void)
+{
+ GenMMC3Power();
+ SetWriteHandler(0x8000,0xBFFF,M254Write);
+ SetReadHandler(0x6000,0x7FFF,MR254WRAM);
+}
+
+void Mapper254_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 128, 128, 8, info->battery);
+ info->Power=M254_Power;
+ AddExState(EXPREGS, 2, 0, "EXPR");
+}
+
+// ---------------------------- 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);
+}
+
+void TFROM_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 64, 0, 0);
+}
+
+void TGROM_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 0, 0, 0);
+}
+
+void TKROM_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 256, 8, info->battery);
+}
+
+void TLROM_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 256, 0, 0);
+}
+
+void TSROM_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 256, 8, 0);
+}
+
+void TLSROM_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 256, 8, 0);
+ cwrap=TKSWRAP;
+ mwrap=GENNOMWRAP;
+ PPU_hook=TKSPPU;
+ AddExState(&PPUCHRBus, 1, 0, "PPUC");
+}
+
+void TKSROM_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 256, 8, info->battery);
+ cwrap=TKSWRAP;
+ mwrap=GENNOMWRAP;
+ PPU_hook=TKSPPU;
+ AddExState(&PPUCHRBus, 1, 0, "PPUC");
+}
+
+void TQROM_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 64, 0, 0);
+ cwrap=TQWRAP;
+ CHRRAMSize=8192;
+ CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
+ SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
+}
+
+void HKROM_Init(CartInfo *info)
+{
+ GenMMC3_Init(info, 512, 512, 1, info->battery);
+}