merge mapper code from FCEUX
[fceu.git] / boards / datalatch.c
index b3452fe..4a61f04 100644 (file)
  *
  * 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include "mapinc.h"
+#include "../ines.h"
 
-static uint8 latche, latcheinit;
+static uint8 latche, latcheinit, bus_conflict;
 static uint16 addrreg0, addrreg1;
+static uint8 *WRAM=NULL;
+static uint32 WRAMSIZE;
 static void(*WSync)(void);
 
 static DECLFW(LatchWrite)
 {
+//  FCEU_printf("bs %04x %02x\n",A,V);
+  if(bus_conflict)
+    latche=V&CartBR(A);
+  else
   latche=V;
   WSync();
 }
@@ -34,23 +41,52 @@ static void LatchPower(void)
 {
   latche=latcheinit;
   WSync();
-  SetReadHandler(0x8000,0xFFFF,CartBR);
+       if(WRAM)
+       {
+               SetReadHandler(0x6000,0xFFFF,CartBR);
+               SetWriteHandler(0x6000,0x7FFF,CartBW);
+       }
+       else
+       {
+               SetReadHandler(0x8000,0xFFFF,CartBR);
+       }
   SetWriteHandler(addrreg0,addrreg1,LatchWrite);
 }
 
+static void LatchClose(void)
+{
+  if(WRAM)
+    FCEU_gfree(WRAM);
+  WRAM=NULL;
+}
+
 static void StateRestore(int version)
 {
   WSync();
 }
 
-void Latch_Init(CartInfo *info, void (*proc)(void), uint8 init, uint16 adr0, uint16 adr1)
+static void Latch_Init(CartInfo *info, void (*proc)(void), uint8 init, uint16 adr0, uint16 adr1, uint8 wram, uint8 busc)
 {
+  bus_conflict = busc;
   latcheinit=init;
   addrreg0=adr0;
   addrreg1=adr1;
   WSync=proc;
   info->Power=LatchPower;
+  info->Close=LatchClose;
   GameStateRestore=StateRestore;
+  if(wram)
+  {
+    WRAMSIZE=8192;
+    WRAM=(uint8*)FCEU_gmalloc(WRAMSIZE);
+    SetupCartPRGMapping(0x10,WRAM,WRAMSIZE,1);
+    if(info->battery)
+    {
+      info->SaveGame[0]=WRAM;
+      info->SaveGameLen[0]=WRAMSIZE;
+    }
+    AddExState(WRAM, WRAMSIZE, 0, "WRAM");
+  }
   AddExState(&latche, 1, 0, "LATC");
 }
 
@@ -66,21 +102,40 @@ static void CPROMSync(void)
 
 void CPROM_Init(CartInfo *info)
 {
-  Latch_Init(info, CPROMSync, 0, 0x8000, 0xFFFF);
+  Latch_Init(info, CPROMSync, 0, 0x8000, 0xFFFF, 0, 0);
 }
 
-//------------------ CNROM ---------------------------
+//------------------ Map 184 ---------------------------
 
-static void CNROMSync(void)
+static void M184Sync(void)
 {
-  setchr8(latche&3);
+  setchr4(0x0000,latche);
+  setchr4(0x1000,latche>>4);
   setprg16(0x8000,0);
   setprg16(0xC000,1);
 }
 
+void Mapper184_Init(CartInfo *info)
+{
+  Latch_Init(info, M184Sync, 0, 0x6000, 0x7FFF, 0, 0);
+}
+
+//------------------ CNROM ---------------------------
+
+static void CNROMSync(void)
+{
+       //mbg 8/10/08 - fixed this so that large homebrew roms would work.
+       //setchr8(latche&3);
+       setchr8(latche);
+       setprg16(0x8000,0);
+       setprg16(0xC000,1);
+  setprg8r(0x10,0x6000,0); // Hayauchy IGO uses 2Kb or RAM
+}
+
 void CNROM_Init(CartInfo *info)
 {
-  Latch_Init(info, CNROMSync, 0, 0x8000, 0xFFFF);
+       bool busc = MasterRomInfoParams.ContainsKey("busc");
+       Latch_Init(info, CNROMSync, 0, 0x8000, 0xFFFF, 1, busc?1:0);
 }
 
 //------------------ ANROM ---------------------------
@@ -94,7 +149,7 @@ static void ANROMSync()
 
 void ANROM_Init(CartInfo *info)
 {
-  Latch_Init(info, ANROMSync, 0, 0x8000, 0xFFFF);
+  Latch_Init(info, ANROMSync, 0, 0x8000, 0xFFFF, 0, 0);
 }
 
 //------------------ Map 70 ---------------------------
@@ -108,7 +163,7 @@ static void M70Sync()
 
 void Mapper70_Init(CartInfo *info)
 {
-  Latch_Init(info, M70Sync, 0, 0x8000, 0xFFFF);
+  Latch_Init(info, M70Sync, 0, 0x8000, 0xFFFF, 0, 0);
 }
 
 //------------------ Map 152 ---------------------------
@@ -123,7 +178,7 @@ static void M152Sync()
 
 void Mapper152_Init(CartInfo *info)
 {
-  Latch_Init(info, M152Sync, 0, 0x8000, 0xFFFF);
+  Latch_Init(info, M152Sync, 0, 0x8000, 0xFFFF, 0, 0);
 }
 
 //------------------ Map 78 ---------------------------
@@ -138,7 +193,7 @@ static void M78Sync()
 
 void Mapper78_Init(CartInfo *info)
 {
-  Latch_Init(info, M78Sync, 0, 0x8000, 0xFFFF);
+  Latch_Init(info, M78Sync, 0, 0x8000, 0xFFFF, 0, 0);
 }
 
 //------------------ MHROM ---------------------------
@@ -150,13 +205,19 @@ static void MHROMSync(void)
 }
 
 void MHROM_Init(CartInfo *info)
-{ 
-  Latch_Init(info, MHROMSync, 0, 0x8000, 0xFFFF);
+{
+  Latch_Init(info, MHROMSync, 0, 0x8000, 0xFFFF, 0, 0);
 }
 
 void Mapper140_Init(CartInfo *info)
-{ 
-  Latch_Init(info, MHROMSync, 0, 0x6000, 0x7FFF);
+{
+  Latch_Init(info, MHROMSync, 0, 0x6000, 0x7FFF, 0, 0);
+}
+
+void Mapper240_Init(CartInfo *info)
+{
+  Latch_Init(info, MHROMSync, 0, 0x4020, 0x5FFF, 0, 0);
+  // need SRAM.
 }
 
 //------------------ Map 87 ---------------------------
@@ -165,12 +226,27 @@ static void M87Sync(void)
 {
   setprg16(0x8000,0);
   setprg16(0xC000,1);
-  setchr8(latche>>1);
+  setchr8(((latche>>1)&1)|((latche<<1)&2));
+//  setchr8(latche);
 }
 
 void Mapper87_Init(CartInfo *info)
-{ 
-  Latch_Init(info, M87Sync, ~0, 0x6000, 0xFFFF);
+{
+  Latch_Init(info, M87Sync, ~0, 0x6000, 0xFFFF, 0, 0);
+}
+
+//------------------ Map 101 ---------------------------
+
+static void M101Sync(void)
+{
+  setprg16(0x8000,0);
+  setprg16(0xC000,1);
+  setchr8(latche);
+}
+
+void Mapper101_Init(CartInfo *info)
+{
+  Latch_Init(info, M101Sync, ~0, 0x6000, 0x7FFF, 0, 0);
 }
 
 //------------------ Map 11 ---------------------------
@@ -182,15 +258,40 @@ static void M11Sync(void)
 }
 
 void Mapper11_Init(CartInfo *info)
-{ 
-  Latch_Init(info, M11Sync, 0, 0x8000, 0xFFFF);
+{
+  Latch_Init(info, M11Sync, 0, 0x8000, 0xFFFF, 0, 0);
 }
 
 void Mapper144_Init(CartInfo *info)
-{ 
-  Latch_Init(info, M11Sync, 0, 0x8001, 0xFFFF);
+{
+  Latch_Init(info, M11Sync, 0, 0x8001, 0xFFFF, 0, 0);
 }
 
+//------------------ Map 38 ---------------------------
+
+static void M38Sync(void)
+{
+  setprg32(0x8000,latche&3);
+  setchr8(latche>>2);
+}
+
+void Mapper38_Init(CartInfo *info)
+{
+  Latch_Init(info, M38Sync, 0, 0x7000, 0x7FFF, 0, 0);
+}
+
+//------------------ Map 36 ---------------------------
+
+static void M36Sync(void)
+{
+  setprg32(0x8000,latche>>4);
+  setchr8((latche)&0xF);
+}
+
+void Mapper36_Init(CartInfo *info)
+{
+  Latch_Init(info, M36Sync, 0, 0x8400, 0xfffe, 0, 0);
+}
 //------------------ UNROM ---------------------------
 
 static void UNROMSync(void)
@@ -202,7 +303,7 @@ static void UNROMSync(void)
 
 void UNROM_Init(CartInfo *info)
 {
-  Latch_Init(info, UNROMSync, 0, 0x8000, 0xFFFF);
+  Latch_Init(info, UNROMSync, 0, 0x8000, 0xFFFF, 0, 1);
 }
 
 //------------------ Map 93 ---------------------------
@@ -216,7 +317,7 @@ static void SSUNROMSync(void)
 
 void SUNSOFT_UNROM_Init(CartInfo *info)
 {
-  Latch_Init(info, SSUNROMSync, 0, 0x8000, 0xFFFF);
+  Latch_Init(info, SSUNROMSync, 0, 0x8000, 0xFFFF, 0, 0);
 }
 
 //------------------ Map 94 ---------------------------
@@ -230,7 +331,21 @@ static void M94Sync(void)
 
 void Mapper94_Init(CartInfo *info)
 {
-  Latch_Init(info, M94Sync, 0, 0x8000, 0xFFFF);
+  Latch_Init(info, M94Sync, 0, 0x8000, 0xFFFF, 0, 0);
+}
+
+//------------------ Map 180 ---------------------------
+
+static void M180Sync(void)
+{
+  setprg16(0x8000,0);
+  setprg16(0xc000,latche);
+  setchr8(0);
+}
+
+void Mapper180_Init(CartInfo *info)
+{
+  Latch_Init(info, M180Sync, 0, 0x8000, 0xFFFF, 0, 0);
 }
 
 //------------------ Map 107 ---------------------------
@@ -243,7 +358,49 @@ static void M107Sync(void)
 
 void Mapper107_Init(CartInfo *info)
 {
-  Latch_Init(info, M107Sync, ~0, 0x8000, 0xFFFF);
+  Latch_Init(info, M107Sync, ~0, 0x8000, 0xFFFF, 0, 0);
+}
+
+//------------------ Map 113 ---------------------------
+
+static void M113Sync(void)
+{
+  setprg32(0x8000,(latche>>3)&7);
+  setchr8(((latche>>3)&8)|(latche&7));
+//  setmirror(latche>>7); // only for HES 6in1
+}
+
+void Mapper113_Init(CartInfo *info)
+{
+  Latch_Init(info, M113Sync, 0, 0x4100, 0x7FFF, 0, 0);
+}
+
+//------------------ A65AS ---------------------------
+
+// actually, there is two cart in one... First have extra mirroring
+// mode (one screen) and 32K bankswitching, second one have only
+// 16 bankswitching mode and normal mirroring... But there is no any
+// correlations between modes and they can be used in one mapper code.
+
+static void BMCA65ASSync(void)
+{
+  if(latche&0x40)
+    setprg32(0x8000,(latche>>1)&0x0F);
+  else
+  {
+    setprg16(0x8000,((latche&0x30)>>1)|(latche&7));
+    setprg16(0xC000,((latche&0x30)>>1)|7);
+  }
+  setchr8(0);
+  if(latche&0x80)
+    setmirror(MI_0+(((latche>>5)&1)));
+  else
+    setmirror(((latche>>3)&1)^1);
+}
+
+void BMCA65AS_Init(CartInfo *info)
+{
+  Latch_Init(info, BMCA65ASSync, 0, 0x8000, 0xFFFF, 0, 0);
 }
 
 //------------------ NROM ---------------------------
@@ -251,16 +408,22 @@ void Mapper107_Init(CartInfo *info)
 #ifdef DEBUG_MAPPER
 static DECLFW(WriteHandler)
 {
- FCEU_printf("$%04x:$%02x\n",A,V);
+ FCEU_printf("bs %04x %02x\n",A,V);
+ CartBW(A,V);
 }
 #endif
 
 static void NROMPower(void)
 {
+  setprg8r(0x10,0x6000,0); // Famili BASIC (v3.0) need it (uses only 4KB), FP-BASIC uses 8KB
   setprg16(0x8000,0);
   setprg16(0xC000,~0);
   setchr8(0);
+
+  SetReadHandler(0x6000,0x7FFF,CartBR);
+  SetWriteHandler(0x6000,0x7FFF,CartBW);
   SetReadHandler(0x8000,0xFFFF,CartBR);
+
   #ifdef DEBUG_MAPPER
   SetWriteHandler(0x4020,0xFFFF,WriteHandler);
   #endif
@@ -269,4 +432,15 @@ static void NROMPower(void)
 void NROM_Init(CartInfo *info)
 {
   info->Power=NROMPower;
+  info->Close=LatchClose;
+
+  WRAMSIZE=8192;
+  WRAM=(uint8*)FCEU_gmalloc(WRAMSIZE);
+  SetupCartPRGMapping(0x10,WRAM,WRAMSIZE,1);
+  if(info->battery)
+  {
+    info->SaveGame[0]=WRAM;
+    info->SaveGameLen[0]=WRAMSIZE;
+  }
+  AddExState(WRAM, WRAMSIZE, 0, "WRAM");
 }