*\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
{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
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
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
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
+ GameInfo->cspecial = SIS_DATACH;\r
+\r
+ GameStateRestore=StateRestore;\r
+ AddExState(&StateRegs, ~0, 0, 0);\r
+}\r