merge mappers from FCEU-mm
[fceu.git] / boards / bandai.c
index 8468aad..8928bfb 100644 (file)
@@ -2,7 +2,6 @@
  *\r
  * Copyright notice for this file:\r
  *  Copyright (C) 2007 CaH4e3\r
- *  Copyright (C) 2011 FCEUX team\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
  *\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
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
  *\r
  * Bandai mappers\r
  *\r
  */\r
 \r
-//Famicom Jump 2 should get transformed to m153\r
-//All other games are not supporting EEPROM saving right now. \r
-//We may need to distinguish between 16 and 159 in order to know the EEPROM configuration.\r
-//Until then, we just return 0x00 from the EEPROM read\r
-\r
 #include "mapinc.h"\r
 \r
 static uint8 reg[16], is153;\r
@@ -45,33 +39,37 @@ static SFORMAT StateRegs[]=
   {0}\r
 };\r
 \r
-static void BandaiIRQHook(int a)\r
+static void FP_FASTAPASS(1) BandaiIRQHook(int a)\r
 {\r
   if(IRQa)\r
   {\r
-    IRQCount -= a;\r
+    IRQCount-=a;\r
     if(IRQCount<0)\r
     {\r
       X6502_IRQBegin(FCEU_IQEXT);\r
-      IRQa = 0;\r
-      IRQCount = -1;\r
+      IRQa=0;\r
+      IRQCount=0xFFFF;\r
     }\r
   }\r
 }\r
 \r
 static void BandaiSync(void)\r
 {\r
+  if(!UNIFchrrama)\r
+  {\r
+    int i;\r
+    for(i=0; i<8; i++) setchr1(i<<10,reg[i]);\r
+  }\r
+  else\r
+    setchr8(0);\r
   if(is153)\r
   {\r
     int base=(reg[0]&1)<<4;\r
-    setchr8(0);\r
     setprg16(0x8000,(reg[8]&0x0F)|base);\r
     setprg16(0xC000,0x0F|base);\r
   }\r
   else\r
   {\r
-    int i;\r
-    for(i=0; i<8; i++) setchr1(i<<10,reg[i]);\r
     setprg16(0x8000,reg[8]);\r
     setprg16(0xC000,~0);\r
   }\r
@@ -96,41 +94,17 @@ static DECLFW(BandaiWrite)
     switch(A)\r
     {\r
       case 0x0A: X6502_IRQEnd(FCEU_IQEXT); IRQa=V&1; IRQCount=IRQLatch; break;\r
-      case 0x0B: IRQLatch&=0xFF00; IRQLatch|=V;  break;\r
+      case 0x0B: IRQLatch&=0xFF00; IRQLatch|=V; break;\r
       case 0x0C: IRQLatch&=0xFF; IRQLatch|=V<<8; break;\r
       case 0x0D: break;// Serial EEPROM control port\r
     }\r
 }\r
 \r
-DECLFR(BandaiRead)
-{
-       return 0;
-}\r
-\r
 static void BandaiPower(void)\r
 {\r
   BandaiSync();\r
   SetReadHandler(0x8000,0xFFFF,CartBR);\r
   SetWriteHandler(0x6000,0xFFFF,BandaiWrite);\r
-  SetReadHandler(0x6000,0x7FFF,BandaiRead);\r
-}\r
-\r
-static void M153Power(void)\r
-{\r
-  BandaiSync();\r
-  setprg8r(0x10,0x6000,0);\r
-  SetReadHandler(0x6000,0x7FFF,CartBR);\r
-  SetWriteHandler(0x6000,0x7FFF,CartBW);\r
-  SetReadHandler(0x8000,0xFFFF,CartBR);\r
-  SetWriteHandler(0x8000,0xFFFF,BandaiWrite);\r
-}\r
-\r
-\r
-static void M153Close(void)\r
-{\r
-  if(WRAM)\r
-    FCEU_gfree(WRAM);\r
-  WRAM=NULL;\r
 }\r
 \r
 static void StateRestore(int version)\r
@@ -147,12 +121,31 @@ void Mapper16_Init(CartInfo *info)
   AddExState(&StateRegs, ~0, 0, 0);\r
 }\r
 \r
-void Mapper159_Init(CartInfo *info)\r
+// Famicom jump 2:\r
+// 0-7: Lower bit of data selects which 256KB PRG block is in use.\r
+// This seems to be a hack on the developers' part, so I'll make emulation\r
+// of it a hack(I think the current PRG block would depend on whatever the\r
+// lowest bit of the CHR bank switching register that corresponds to the\r
+// last CHR address read).\r
+\r
+static void M153Power(void)\r
 {\r
-  Mapper16_Init(info);\r
+  BandaiSync();\r
+  setprg8r(0x10,0x6000,0);\r
+  SetReadHandler(0x6000,0x7FFF,CartBR);\r
+  SetWriteHandler(0x6000,0x7FFF,CartBW);\r
+  SetReadHandler(0x8000,0xFFFF,CartBR);\r
+  SetWriteHandler(0x8000,0xFFFF,BandaiWrite);\r
 }\r
 \r
 \r
+static void M153Close(void)\r
+{\r
+  if(WRAM)\r
+    FCEU_gfree(WRAM);\r
+  WRAM=NULL;\r
+}\r
+\r
 void Mapper153_Init(CartInfo *info)\r
 {\r
   is153=1;\r
@@ -174,3 +167,190 @@ void Mapper153_Init(CartInfo *info)
   GameStateRestore=StateRestore;\r
   AddExState(&StateRegs, ~0, 0, 0);\r
 }\r
+\r
+// Datach Barcode Battler\r
+\r
+static uint8 BarcodeData[256];\r
+static int BarcodeReadPos;\r
+static int BarcodeCycleCount;\r
+static uint32 BarcodeOut;\r
+\r
+int FCEUI_DatachSet(const uint8 *rcode)\r
+{\r
+  int prefix_parity_type[10][6] = {\r
+    {0,0,0,0,0,0}, {0,0,1,0,1,1}, {0,0,1,1,0,1}, {0,0,1,1,1,0},\r
+    {0,1,0,0,1,1}, {0,1,1,0,0,1}, {0,1,1,1,0,0}, {0,1,0,1,0,1},\r
+    {0,1,0,1,1,0}, {0,1,1,0,1,0}\r
+  };\r
+  int data_left_odd[10][7] = {\r
+    {0,0,0,1,1,0,1}, {0,0,1,1,0,0,1}, {0,0,1,0,0,1,1}, {0,1,1,1,1,0,1},\r
+    {0,1,0,0,0,1,1}, {0,1,1,0,0,0,1}, {0,1,0,1,1,1,1}, {0,1,1,1,0,1,1},\r
+    {0,1,1,0,1,1,1}, {0,0,0,1,0,1,1}\r
+  };\r
+  int  data_left_even[10][7] = {\r
+    {0,1,0,0,1,1,1}, {0,1,1,0,0,1,1}, {0,0,1,1,0,1,1}, {0,1,0,0,0,0,1},\r
+    {0,0,1,1,1,0,1}, {0,1,1,1,0,0,1}, {0,0,0,0,1,0,1}, {0,0,1,0,0,0,1},\r
+    {0,0,0,1,0,0,1}, {0,0,1,0,1,1,1}\r
+  };\r
+  int  data_right[10][7] = {\r
+    {1,1,1,0,0,1,0}, {1,1,0,0,1,1,0}, {1,1,0,1,1,0,0}, {1,0,0,0,0,1,0},\r
+    {1,0,1,1,1,0,0}, {1,0,0,1,1,1,0}, {1,0,1,0,0,0,0}, {1,0,0,0,1,0,0},\r
+    {1,0,0,1,0,0,0}, {1,1,1,0,1,0,0}\r
+  };\r
+  uint8 code[13+1];\r
+  uint32 tmp_p=0;\r
+  int i, j;\r
+  int len;\r
+\r
+  for(i=len=0;i<13;i++)\r
+  {\r
+    if(!rcode[i]) break;\r
+    if((code[i]=rcode[i]-'0') > 9)\r
+      return(0);\r
+    len++;\r
+  }\r
+  if(len!=13 && len!=12 && len!=8 && len!=7) return(0);\r
+\r
+  #define BS(x) BarcodeData[tmp_p]=x;tmp_p++\r
+\r
+  for(j=0;j<32;j++)\r
+  {\r
+    BS(0x00);\r
+  }\r
+\r
+  /* Left guard bars */\r
+  BS(1);    BS(0); BS(1);\r
+\r
+  if(len==13 || len==12)\r
+  {\r
+    uint32 csum;\r
+\r
+    for(i=0;i<6;i++)\r
+      if(prefix_parity_type[code[0]][i])\r
+      {\r
+        for(j=0;j<7;j++)\r
+        {\r
+          BS(data_left_even[code[i+1]][j]);\r
+        }\r
+      }\r
+      else\r
+        for(j=0;j<7;j++)\r
+        {\r
+          BS(data_left_odd[code[i+1]][j]);\r
+        }\r
+\r
+    /* Center guard bars */\r
+    BS(0); BS(1); BS(0); BS(1); BS(0);\r
+\r
+    for(i=7;i<12;i++)\r
+      for(j=0;j<7;j++)\r
+      {\r
+        BS(data_right[code[i]][j]);\r
+      }\r
+    csum=0;\r
+    for(i=0;i<12;i++) csum+=code[i]*((i&1)?3:1);\r
+      csum=(10-(csum%10))%10;\r
+    for(j=0;j<7;j++)\r
+    {\r
+      BS(data_right[csum][j]);\r
+    }\r
+\r
+  }\r
+  else if(len==8 || len==7)\r
+  {\r
+    uint32 csum=0;\r
+\r
+    for(i=0;i<7;i++) csum+=(i&1)?code[i]:(code[i]*3);\r
+\r
+    csum=(10-(csum%10))%10;\r
+\r
+    for(i=0;i<4;i++)\r
+      for(j=0;j<7;j++)\r
+      {\r
+        BS(data_left_odd[code[i]][j]);\r
+      }\r
+\r
+\r
+    /* Center guard bars */\r
+    BS(0); BS(1); BS(0); BS(1); BS(0);\r
+\r
+    for(i=4;i<7;i++)\r
+      for(j=0;j<7;j++)\r
+      {\r
+        BS(data_right[code[i]][j]);\r
+      }\r
+\r
+    for(j=0;j<7;j++)\r
+      { BS(data_right[csum][j]);}\r
+\r
+  }\r
+\r
+  /* Right guard bars */\r
+  BS(1); BS(0); BS(1);\r
+\r
+  for(j=0;j<32;j++)\r
+  {\r
+    BS(0x00);\r
+  }\r
+\r
+  BS(0xFF);\r
+\r
+  #undef BS\r
+\r
+  BarcodeReadPos=0;\r
+  BarcodeOut=0x8;\r
+  BarcodeCycleCount=0;\r
+  return(1);\r
+}\r
+\r
+static void FP_FASTAPASS(1) BarcodeIRQHook(int a)\r
+{\r
+ BandaiIRQHook(a);\r
+\r
+ BarcodeCycleCount+=a;\r
+\r
+ if(BarcodeCycleCount >= 1000)\r
+ {\r
+  BarcodeCycleCount -= 1000;\r
+  if(BarcodeData[BarcodeReadPos]==0xFF)\r
+  {\r
+   BarcodeOut=0;\r
+  }\r
+  else\r
+  {\r
+   BarcodeOut=(BarcodeData[BarcodeReadPos]^1)<<3;\r
+   BarcodeReadPos++;\r
+  }\r
+ }\r
+}\r
+\r
+static DECLFR(BarcodeRead)\r
+{\r
+  return BarcodeOut;\r
+}\r
+\r
+static void M157Power(void)\r
+{\r
+  BarcodeData[0]=0xFF;\r
+  BarcodeReadPos=0;\r
+  BarcodeOut=0;\r
+  BarcodeCycleCount=0;\r
+\r
+  BandaiSync();\r
+\r
+  SetWriteHandler(0x6000,0xFFFF,BandaiWrite);\r
+  SetReadHandler(0x6000,0x7FFF,BarcodeRead);\r
+  SetReadHandler(0x8000,0xFFFF,CartBR);\r
+}\r
+\r
+void Mapper157_Init(CartInfo *info)\r
+{\r
+  is153=0;\r
+  info->Power=M157Power;\r
+  MapIRQHook=BarcodeIRQHook;\r
+\r
+  FCEUGameInfo->cspecial = SIS_DATACH;\r
+\r
+  GameStateRestore=StateRestore;\r
+  AddExState(&StateRegs, ~0, 0, 0);\r
+}\r