+
+
+static uint8 BarcodeData[256];
+static int BarcodeReadPos;
+static int BarcodeCycleCount;
+static uint32 BarcodeOut;
+
+int FCEUI_DatachSet(const uint8 *rcode)
+{
+ int prefix_parity_type[10][6] = {
+ {0,0,0,0,0,0}, {0,0,1,0,1,1}, {0,0,1,1,0,1}, {0,0,1,1,1,0},
+ {0,1,0,0,1,1}, {0,1,1,0,0,1}, {0,1,1,1,0,0}, {0,1,0,1,0,1},
+ {0,1,0,1,1,0}, {0,1,1,0,1,0}
+ };
+ int data_left_odd[10][7] = {
+ {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},
+ {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},
+ {0,1,1,0,1,1,1}, {0,0,0,1,0,1,1}
+ };
+ int data_left_even[10][7] = {
+ {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},
+ {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},
+ {0,0,0,1,0,0,1}, {0,0,1,0,1,1,1}
+ };
+ int data_right[10][7] = {
+ {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},
+ {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},
+ {1,0,0,1,0,0,0}, {1,1,1,0,1,0,0}
+ };
+ uint8 code[13+1];
+ uint32 tmp_p=0;
+ int i, j;
+ int len;
+
+ for(i=len=0;i<13;i++)
+ {
+ if(!rcode[i]) break;
+
+ if((code[i]=rcode[i]-'0') > 9)
+ return(0);
+ len++;
+ }
+ if(len!=13 && len!=12 && len!=8 && len!=7) return(0);
+
+ #define BS(x) BarcodeData[tmp_p]=x;tmp_p++
+
+ for(j=0;j<32;j++)
+ {
+ BS(0x00);
+ }
+
+ /* Left guard bars */
+ BS(1); BS(0); BS(1);
+
+ if(len==13 || len==12)
+ {
+ uint32 csum;
+
+ for(i=0;i<6;i++)
+ if(prefix_parity_type[code[0]][i])
+ {
+ for(j=0;j<7;j++)
+ {
+ BS(data_left_even[code[i+1]][j]);
+ }
+ }
+ else
+ for(j=0;j<7;j++)
+ {
+ BS(data_left_odd[code[i+1]][j]);
+ }
+
+ /* Center guard bars */
+ BS(0); BS(1); BS(0); BS(1); BS(0);
+
+ for(i=7;i<12;i++)
+ for(j=0;j<7;j++)
+ {
+ BS(data_right[code[i]][j]);
+ }
+ csum=0;
+ for(i=0;i<12;i++) csum+=code[i]*((i&1)?3:1);
+ csum=(10-(csum%10))%10;
+ //printf("%d\n",csum);
+ for(j=0;j<7;j++)
+ {
+ BS(data_right[csum][j]);
+ }
+
+ }
+ else if(len==8 || len==7)
+ {
+ uint32 csum=0;
+
+ for(i=0;i<7;i++) csum+=(i&1)?code[i]:(code[i]*3);
+
+ csum=(10-(csum%10))%10;
+
+ for(i=0;i<4;i++)
+ for(j=0;j<7;j++)
+ {
+ BS(data_left_odd[code[i]][j]);
+ }
+
+
+ /* Center guard bars */
+ BS(0); BS(1); BS(0); BS(1); BS(0);
+
+ for(i=4;i<7;i++)
+ for(j=0;j<7;j++)
+ {
+ BS(data_right[code[i]][j]);
+ }
+
+ for(j=0;j<7;j++)
+ { BS(data_right[csum][j]);}
+
+ }
+
+ /* Right guard bars */
+ BS(1); BS(0); BS(1);
+
+ for(j=0;j<32;j++)
+ {
+ BS(0x00);
+ }
+
+ BS(0xFF);
+ #undef BS
+ BarcodeReadPos=0;
+ BarcodeOut=0x8;
+ BarcodeCycleCount=0;
+ return(1);
+}
+
+static void FP_FASTAPASS(1) BarcodeIRQHook(int a)
+{
+ BandaiIRQHook(a);
+
+ BarcodeCycleCount+=a;
+
+ if(BarcodeCycleCount >= 1000)
+ {
+ BarcodeCycleCount -= 1000;
+ if(BarcodeData[BarcodeReadPos]==0xFF)
+ {
+ BarcodeOut=0;
+ }
+ else
+ {
+ BarcodeOut=(BarcodeData[BarcodeReadPos]^1)<<3;
+ BarcodeReadPos++;
+ }
+ }
+}
+
+static DECLFR(Mapper157_read)
+{
+ uint8 ret;
+
+ ret=BarcodeOut;
+ return(ret);
+}
+
+void Mapper157_init(void)
+{
+ FCEUGameInfo.cspecial = SIS_DATACH;
+ MapIRQHook=BarcodeIRQHook;
+ SetWriteHandler(0x6000,0xFFFF,Mapper16_write);
+ SetReadHandler(0x6000,0x7FFF,Mapper157_read);
+
+ BarcodeData[0]=0xFF;
+ BarcodeReadPos=0;
+ BarcodeOut=0;
+ BarcodeCycleCount=0;
+}