+\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