386f5371 |
1 | /* FCE Ultra - NES/Famicom Emulator\r |
2 | *\r |
3 | * Copyright notice for this file:\r |
4 | * Copyright (C) 2007 CaH4e3\r |
386f5371 |
5 | *\r |
6 | * This program is free software; you can redistribute it and/or modify\r |
7 | * it under the terms of the GNU General Public License as published by\r |
8 | * the Free Software Foundation; either version 2 of the License, or\r |
9 | * (at your option) any later version.\r |
10 | *\r |
11 | * This program is distributed in the hope that it will be useful,\r |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of\r |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r |
14 | * GNU General Public License for more details.\r |
15 | *\r |
16 | * You should have received a copy of the GNU General Public License\r |
17 | * along with this program; if not, write to the Free Software\r |
43725da7 |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r |
386f5371 |
19 | *\r |
20 | * Bandai mappers\r |
21 | *\r |
22 | */\r |
23 | \r |
386f5371 |
24 | #include "mapinc.h"\r |
25 | \r |
26 | static uint8 reg[16], is153;\r |
27 | static uint8 IRQa;\r |
28 | static int16 IRQCount, IRQLatch;\r |
29 | \r |
30 | static uint8 *WRAM=NULL;\r |
31 | static uint32 WRAMSIZE;\r |
32 | \r |
33 | static SFORMAT StateRegs[]=\r |
34 | {\r |
35 | {reg, 16, "REGS"},\r |
36 | {&IRQa, 1, "IRQA"},\r |
37 | {&IRQCount, 2, "IRQC"},\r |
38 | {&IRQLatch, 2, "IRQL"}, // need for Famicom Jump II - Saikyou no 7 Nin (J) [!]\r |
39 | {0}\r |
40 | };\r |
41 | \r |
43725da7 |
42 | static void FP_FASTAPASS(1) BandaiIRQHook(int a)\r |
386f5371 |
43 | {\r |
44 | if(IRQa)\r |
45 | {\r |
43725da7 |
46 | IRQCount-=a;\r |
386f5371 |
47 | if(IRQCount<0)\r |
48 | {\r |
49 | X6502_IRQBegin(FCEU_IQEXT);\r |
43725da7 |
50 | IRQa=0;\r |
51 | IRQCount=0xFFFF;\r |
386f5371 |
52 | }\r |
53 | }\r |
54 | }\r |
55 | \r |
56 | static void BandaiSync(void)\r |
57 | {\r |
43725da7 |
58 | if(!UNIFchrrama)\r |
59 | {\r |
60 | int i;\r |
61 | for(i=0; i<8; i++) setchr1(i<<10,reg[i]);\r |
62 | }\r |
63 | else\r |
64 | setchr8(0);\r |
386f5371 |
65 | if(is153)\r |
66 | {\r |
67 | int base=(reg[0]&1)<<4;\r |
386f5371 |
68 | setprg16(0x8000,(reg[8]&0x0F)|base);\r |
69 | setprg16(0xC000,0x0F|base);\r |
70 | }\r |
71 | else\r |
72 | {\r |
386f5371 |
73 | setprg16(0x8000,reg[8]);\r |
74 | setprg16(0xC000,~0);\r |
75 | }\r |
76 | switch(reg[9]&3)\r |
77 | {\r |
78 | case 0: setmirror(MI_V); break;\r |
79 | case 1: setmirror(MI_H); break;\r |
80 | case 2: setmirror(MI_0); break;\r |
81 | case 3: setmirror(MI_1); break;\r |
82 | }\r |
83 | }\r |
84 | \r |
85 | static DECLFW(BandaiWrite)\r |
86 | {\r |
87 | A&=0x0F;\r |
88 | if(A<0x0A)\r |
89 | {\r |
90 | reg[A&0x0F]=V;\r |
91 | BandaiSync();\r |
92 | }\r |
93 | else\r |
94 | switch(A)\r |
95 | {\r |
96 | case 0x0A: X6502_IRQEnd(FCEU_IQEXT); IRQa=V&1; IRQCount=IRQLatch; break;\r |
43725da7 |
97 | case 0x0B: IRQLatch&=0xFF00; IRQLatch|=V; break;\r |
386f5371 |
98 | case 0x0C: IRQLatch&=0xFF; IRQLatch|=V<<8; break;\r |
99 | case 0x0D: break;// Serial EEPROM control port\r |
100 | }\r |
101 | }\r |
102 | \r |
386f5371 |
103 | static void BandaiPower(void)\r |
104 | {\r |
105 | BandaiSync();\r |
106 | SetReadHandler(0x8000,0xFFFF,CartBR);\r |
107 | SetWriteHandler(0x6000,0xFFFF,BandaiWrite);\r |
386f5371 |
108 | }\r |
109 | \r |
110 | static void StateRestore(int version)\r |
111 | {\r |
112 | BandaiSync();\r |
113 | }\r |
114 | \r |
115 | void Mapper16_Init(CartInfo *info)\r |
116 | {\r |
117 | is153=0;\r |
118 | info->Power=BandaiPower;\r |
119 | MapIRQHook=BandaiIRQHook;\r |
120 | GameStateRestore=StateRestore;\r |
121 | AddExState(&StateRegs, ~0, 0, 0);\r |
122 | }\r |
123 | \r |
43725da7 |
124 | // Famicom jump 2:\r |
125 | // 0-7: Lower bit of data selects which 256KB PRG block is in use.\r |
126 | // This seems to be a hack on the developers' part, so I'll make emulation\r |
127 | // of it a hack(I think the current PRG block would depend on whatever the\r |
128 | // lowest bit of the CHR bank switching register that corresponds to the\r |
129 | // last CHR address read).\r |
130 | \r |
131 | static void M153Power(void)\r |
386f5371 |
132 | {\r |
43725da7 |
133 | BandaiSync();\r |
134 | setprg8r(0x10,0x6000,0);\r |
135 | SetReadHandler(0x6000,0x7FFF,CartBR);\r |
136 | SetWriteHandler(0x6000,0x7FFF,CartBW);\r |
137 | SetReadHandler(0x8000,0xFFFF,CartBR);\r |
138 | SetWriteHandler(0x8000,0xFFFF,BandaiWrite);\r |
386f5371 |
139 | }\r |
140 | \r |
141 | \r |
43725da7 |
142 | static void M153Close(void)\r |
143 | {\r |
144 | if(WRAM)\r |
145 | FCEU_gfree(WRAM);\r |
146 | WRAM=NULL;\r |
147 | }\r |
148 | \r |
386f5371 |
149 | void Mapper153_Init(CartInfo *info)\r |
150 | {\r |
151 | is153=1;\r |
152 | info->Power=M153Power;\r |
153 | info->Close=M153Close;\r |
154 | MapIRQHook=BandaiIRQHook;\r |
155 | \r |
156 | WRAMSIZE=8192;\r |
157 | WRAM=(uint8*)FCEU_gmalloc(WRAMSIZE);\r |
158 | SetupCartPRGMapping(0x10,WRAM,WRAMSIZE,1);\r |
159 | AddExState(WRAM, WRAMSIZE, 0, "WRAM");\r |
160 | \r |
161 | if(info->battery)\r |
162 | {\r |
163 | info->SaveGame[0]=WRAM;\r |
164 | info->SaveGameLen[0]=WRAMSIZE;\r |
165 | }\r |
166 | \r |
167 | GameStateRestore=StateRestore;\r |
168 | AddExState(&StateRegs, ~0, 0, 0);\r |
169 | }\r |
43725da7 |
170 | \r |
171 | // Datach Barcode Battler\r |
172 | \r |
173 | static uint8 BarcodeData[256];\r |
174 | static int BarcodeReadPos;\r |
175 | static int BarcodeCycleCount;\r |
176 | static uint32 BarcodeOut;\r |
177 | \r |
178 | int FCEUI_DatachSet(const uint8 *rcode)\r |
179 | {\r |
180 | int prefix_parity_type[10][6] = {\r |
181 | {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 |
182 | {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 |
183 | {0,1,0,1,1,0}, {0,1,1,0,1,0}\r |
184 | };\r |
185 | int data_left_odd[10][7] = {\r |
186 | {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 |
187 | {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 |
188 | {0,1,1,0,1,1,1}, {0,0,0,1,0,1,1}\r |
189 | };\r |
190 | int data_left_even[10][7] = {\r |
191 | {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 |
192 | {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 |
193 | {0,0,0,1,0,0,1}, {0,0,1,0,1,1,1}\r |
194 | };\r |
195 | int data_right[10][7] = {\r |
196 | {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 |
197 | {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 |
198 | {1,0,0,1,0,0,0}, {1,1,1,0,1,0,0}\r |
199 | };\r |
200 | uint8 code[13+1];\r |
201 | uint32 tmp_p=0;\r |
202 | int i, j;\r |
203 | int len;\r |
204 | \r |
205 | for(i=len=0;i<13;i++)\r |
206 | {\r |
207 | if(!rcode[i]) break;\r |
208 | if((code[i]=rcode[i]-'0') > 9)\r |
209 | return(0);\r |
210 | len++;\r |
211 | }\r |
212 | if(len!=13 && len!=12 && len!=8 && len!=7) return(0);\r |
213 | \r |
214 | #define BS(x) BarcodeData[tmp_p]=x;tmp_p++\r |
215 | \r |
216 | for(j=0;j<32;j++)\r |
217 | {\r |
218 | BS(0x00);\r |
219 | }\r |
220 | \r |
221 | /* Left guard bars */\r |
222 | BS(1); BS(0); BS(1);\r |
223 | \r |
224 | if(len==13 || len==12)\r |
225 | {\r |
226 | uint32 csum;\r |
227 | \r |
228 | for(i=0;i<6;i++)\r |
229 | if(prefix_parity_type[code[0]][i])\r |
230 | {\r |
231 | for(j=0;j<7;j++)\r |
232 | {\r |
233 | BS(data_left_even[code[i+1]][j]);\r |
234 | }\r |
235 | }\r |
236 | else\r |
237 | for(j=0;j<7;j++)\r |
238 | {\r |
239 | BS(data_left_odd[code[i+1]][j]);\r |
240 | }\r |
241 | \r |
242 | /* Center guard bars */\r |
243 | BS(0); BS(1); BS(0); BS(1); BS(0);\r |
244 | \r |
245 | for(i=7;i<12;i++)\r |
246 | for(j=0;j<7;j++)\r |
247 | {\r |
248 | BS(data_right[code[i]][j]);\r |
249 | }\r |
250 | csum=0;\r |
251 | for(i=0;i<12;i++) csum+=code[i]*((i&1)?3:1);\r |
252 | csum=(10-(csum%10))%10;\r |
253 | for(j=0;j<7;j++)\r |
254 | {\r |
255 | BS(data_right[csum][j]);\r |
256 | }\r |
257 | \r |
258 | }\r |
259 | else if(len==8 || len==7)\r |
260 | {\r |
261 | uint32 csum=0;\r |
262 | \r |
263 | for(i=0;i<7;i++) csum+=(i&1)?code[i]:(code[i]*3);\r |
264 | \r |
265 | csum=(10-(csum%10))%10;\r |
266 | \r |
267 | for(i=0;i<4;i++)\r |
268 | for(j=0;j<7;j++)\r |
269 | {\r |
270 | BS(data_left_odd[code[i]][j]);\r |
271 | }\r |
272 | \r |
273 | \r |
274 | /* Center guard bars */\r |
275 | BS(0); BS(1); BS(0); BS(1); BS(0);\r |
276 | \r |
277 | for(i=4;i<7;i++)\r |
278 | for(j=0;j<7;j++)\r |
279 | {\r |
280 | BS(data_right[code[i]][j]);\r |
281 | }\r |
282 | \r |
283 | for(j=0;j<7;j++)\r |
284 | { BS(data_right[csum][j]);}\r |
285 | \r |
286 | }\r |
287 | \r |
288 | /* Right guard bars */\r |
289 | BS(1); BS(0); BS(1);\r |
290 | \r |
291 | for(j=0;j<32;j++)\r |
292 | {\r |
293 | BS(0x00);\r |
294 | }\r |
295 | \r |
296 | BS(0xFF);\r |
297 | \r |
298 | #undef BS\r |
299 | \r |
300 | BarcodeReadPos=0;\r |
301 | BarcodeOut=0x8;\r |
302 | BarcodeCycleCount=0;\r |
303 | return(1);\r |
304 | }\r |
305 | \r |
306 | static void FP_FASTAPASS(1) BarcodeIRQHook(int a)\r |
307 | {\r |
308 | BandaiIRQHook(a);\r |
309 | \r |
310 | BarcodeCycleCount+=a;\r |
311 | \r |
312 | if(BarcodeCycleCount >= 1000)\r |
313 | {\r |
314 | BarcodeCycleCount -= 1000;\r |
315 | if(BarcodeData[BarcodeReadPos]==0xFF)\r |
316 | {\r |
317 | BarcodeOut=0;\r |
318 | }\r |
319 | else\r |
320 | {\r |
321 | BarcodeOut=(BarcodeData[BarcodeReadPos]^1)<<3;\r |
322 | BarcodeReadPos++;\r |
323 | }\r |
324 | }\r |
325 | }\r |
326 | \r |
327 | static DECLFR(BarcodeRead)\r |
328 | {\r |
329 | return BarcodeOut;\r |
330 | }\r |
331 | \r |
332 | static void M157Power(void)\r |
333 | {\r |
334 | BarcodeData[0]=0xFF;\r |
335 | BarcodeReadPos=0;\r |
336 | BarcodeOut=0;\r |
337 | BarcodeCycleCount=0;\r |
338 | \r |
339 | BandaiSync();\r |
340 | \r |
341 | SetWriteHandler(0x6000,0xFFFF,BandaiWrite);\r |
342 | SetReadHandler(0x6000,0x7FFF,BarcodeRead);\r |
343 | SetReadHandler(0x8000,0xFFFF,CartBR);\r |
344 | }\r |
345 | \r |
346 | void Mapper157_Init(CartInfo *info)\r |
347 | {\r |
348 | is153=0;\r |
349 | info->Power=M157Power;\r |
350 | MapIRQHook=BarcodeIRQHook;\r |
351 | \r |
352 | FCEUGameInfo->cspecial = SIS_DATACH;\r |
353 | \r |
354 | GameStateRestore=StateRestore;\r |
355 | AddExState(&StateRegs, ~0, 0, 0);\r |
356 | }\r |