c62d2810 |
1 | /* FCE Ultra - NES/Famicom Emulator |
2 | * |
3 | * Copyright notice for this file: |
4 | * Copyright (C) 1998 BERO |
d97315ac |
5 | * Copyright (C) 2002 Xodnizel |
c62d2810 |
6 | * |
7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation; either version 2 of the License, or |
10 | * (at your option) any later version. |
11 | * |
12 | * This program is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * GNU General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU General Public License |
18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ |
21 | |
22 | #include "mapinc.h" |
23 | |
24 | static void FP_FASTAPASS(1) BandaiIRQHook(int a) |
25 | { |
26 | if(IRQa) |
27 | { |
28 | IRQCount-=a; |
29 | if(IRQCount<0) |
30 | { |
31 | X6502_IRQBegin(FCEU_IQEXT); |
32 | //printf("IRQ: %d, %d\n",scanline,timestamp); |
33 | IRQa=0; |
34 | IRQCount=0xFFFF; |
35 | } |
36 | } |
37 | } |
38 | |
39 | static DECLFW(Mapper16_write) |
40 | { |
41 | A&=0xF; |
42 | |
43 | if(A<=0x7) |
44 | VROM_BANK1(A<<10,V); |
45 | else if(A==0x8) |
46 | ROM_BANK16(0x8000,V); |
47 | else switch(A) { |
48 | case 0x9: switch(V&3) { |
49 | case 0x00:MIRROR_SET2(1);break; |
50 | case 0x01:MIRROR_SET2(0);break; |
51 | case 0x02:onemir(0);break; |
52 | case 0x03:onemir(1);break; |
53 | } |
54 | break; |
55 | case 0xA:X6502_IRQEnd(FCEU_IQEXT); |
56 | IRQa=V&1; |
57 | IRQCount=IRQLatch; |
58 | break; |
59 | case 0xB:IRQLatch&=0xFF00; |
60 | IRQLatch|=V; |
61 | break; |
62 | case 0xC:IRQLatch&=0xFF; |
63 | IRQLatch|=V<<8; |
64 | break; |
65 | case 0xD: break;/* Serial EEPROM control port */ |
66 | } |
67 | } |
68 | |
69 | // Famicom jump 2: |
70 | // 0-7: Lower bit of data selects which 256KB PRG block is in use. |
71 | // This seems to be a hack on the developers' part, so I'll make emulation |
72 | // of it a hack(I think the current PRG block would depend on whatever the |
73 | // lowest bit of the CHR bank switching register that corresponds to the |
74 | // last CHR address read). |
75 | |
76 | static void PRGO(void) |
77 | { |
78 | uint32 base=(mapbyte1[0]&1)<<4; |
79 | ROM_BANK16(0x8000,(mapbyte2[0]&0xF)|base); |
80 | ROM_BANK16(0xC000,base|0xF); |
81 | } |
82 | |
83 | static DECLFW(Mapper153_write) |
84 | { |
d97315ac |
85 | A&=0xF; |
c0bf6f9f |
86 | if(A<=0x7) |
d97315ac |
87 | { |
88 | mapbyte1[A&7]=V; |
89 | PRGO(); |
90 | } |
c0bf6f9f |
91 | else if(A==0x8) |
d97315ac |
92 | { |
93 | mapbyte2[0]=V; |
94 | PRGO(); |
95 | } |
96 | else switch(A) { |
97 | case 0x9: switch(V&3) { |
98 | case 0x00:MIRROR_SET2(1);break; |
c62d2810 |
99 | case 0x01:MIRROR_SET2(0);break; |
100 | case 0x02:onemir(0);break; |
101 | case 0x03:onemir(1);break; |
102 | } |
103 | break; |
104 | case 0xA:X6502_IRQEnd(FCEU_IQEXT); |
d97315ac |
105 | IRQa=V&1; |
106 | IRQCount=IRQLatch; |
107 | break; |
c62d2810 |
108 | case 0xB:IRQLatch&=0xFF00; |
d97315ac |
109 | IRQLatch|=V; |
110 | break; |
c62d2810 |
111 | case 0xC:IRQLatch&=0xFF; |
d97315ac |
112 | IRQLatch|=V<<8; |
113 | break; |
c62d2810 |
114 | } |
115 | } |
116 | |
117 | void Mapper16_init(void) |
118 | { |
119 | MapIRQHook=BandaiIRQHook; |
120 | SetWriteHandler(0x6000,0xFFFF,Mapper16_write); |
121 | } |
122 | |
123 | void Mapper153_init(void) |
124 | { |
125 | MapIRQHook=BandaiIRQHook; |
126 | SetWriteHandler(0x8000,0xFFFF,Mapper153_write); |
127 | /* This mapper/board seems to have WRAM at $6000-$7FFF, so I'll let the |
128 | main ines code take care of that memory region. */ |
129 | } |
d97315ac |
130 | |
131 | |
132 | static uint8 BarcodeData[256]; |
133 | static int BarcodeReadPos; |
134 | static int BarcodeCycleCount; |
135 | static uint32 BarcodeOut; |
136 | |
137 | int FCEUI_DatachSet(const uint8 *rcode) |
138 | { |
139 | int prefix_parity_type[10][6] = { |
140 | {0,0,0,0,0,0}, {0,0,1,0,1,1}, {0,0,1,1,0,1}, {0,0,1,1,1,0}, |
141 | {0,1,0,0,1,1}, {0,1,1,0,0,1}, {0,1,1,1,0,0}, {0,1,0,1,0,1}, |
142 | {0,1,0,1,1,0}, {0,1,1,0,1,0} |
143 | }; |
144 | int data_left_odd[10][7] = { |
145 | {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}, |
146 | {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}, |
147 | {0,1,1,0,1,1,1}, {0,0,0,1,0,1,1} |
148 | }; |
149 | int data_left_even[10][7] = { |
150 | {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}, |
151 | {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}, |
152 | {0,0,0,1,0,0,1}, {0,0,1,0,1,1,1} |
153 | }; |
154 | int data_right[10][7] = { |
155 | {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}, |
156 | {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}, |
157 | {1,0,0,1,0,0,0}, {1,1,1,0,1,0,0} |
158 | }; |
159 | uint8 code[13+1]; |
160 | uint32 tmp_p=0; |
161 | int i, j; |
162 | int len; |
163 | |
164 | for(i=len=0;i<13;i++) |
165 | { |
166 | if(!rcode[i]) break; |
167 | |
168 | if((code[i]=rcode[i]-'0') > 9) |
169 | return(0); |
170 | len++; |
171 | } |
172 | if(len!=13 && len!=12 && len!=8 && len!=7) return(0); |
173 | |
174 | #define BS(x) BarcodeData[tmp_p]=x;tmp_p++ |
175 | |
176 | for(j=0;j<32;j++) |
177 | { |
178 | BS(0x00); |
179 | } |
180 | |
181 | /* Left guard bars */ |
182 | BS(1); BS(0); BS(1); |
183 | |
184 | if(len==13 || len==12) |
185 | { |
186 | uint32 csum; |
187 | |
188 | for(i=0;i<6;i++) |
189 | if(prefix_parity_type[code[0]][i]) |
190 | { |
191 | for(j=0;j<7;j++) |
192 | { |
193 | BS(data_left_even[code[i+1]][j]); |
194 | } |
195 | } |
196 | else |
197 | for(j=0;j<7;j++) |
198 | { |
199 | BS(data_left_odd[code[i+1]][j]); |
200 | } |
201 | |
202 | /* Center guard bars */ |
203 | BS(0); BS(1); BS(0); BS(1); BS(0); |
204 | |
205 | for(i=7;i<12;i++) |
206 | for(j=0;j<7;j++) |
207 | { |
208 | BS(data_right[code[i]][j]); |
209 | } |
210 | csum=0; |
211 | for(i=0;i<12;i++) csum+=code[i]*((i&1)?3:1); |
212 | csum=(10-(csum%10))%10; |
213 | //printf("%d\n",csum); |
214 | for(j=0;j<7;j++) |
215 | { |
216 | BS(data_right[csum][j]); |
217 | } |
218 | |
219 | } |
220 | else if(len==8 || len==7) |
221 | { |
222 | uint32 csum=0; |
223 | |
224 | for(i=0;i<7;i++) csum+=(i&1)?code[i]:(code[i]*3); |
225 | |
226 | csum=(10-(csum%10))%10; |
227 | |
228 | for(i=0;i<4;i++) |
229 | for(j=0;j<7;j++) |
230 | { |
231 | BS(data_left_odd[code[i]][j]); |
232 | } |
233 | |
234 | |
235 | /* Center guard bars */ |
236 | BS(0); BS(1); BS(0); BS(1); BS(0); |
237 | |
238 | for(i=4;i<7;i++) |
239 | for(j=0;j<7;j++) |
240 | { |
241 | BS(data_right[code[i]][j]); |
242 | } |
243 | |
244 | for(j=0;j<7;j++) |
245 | { BS(data_right[csum][j]);} |
246 | |
247 | } |
248 | |
249 | /* Right guard bars */ |
250 | BS(1); BS(0); BS(1); |
251 | |
252 | for(j=0;j<32;j++) |
253 | { |
254 | BS(0x00); |
255 | } |
256 | |
257 | BS(0xFF); |
258 | #undef BS |
259 | BarcodeReadPos=0; |
260 | BarcodeOut=0x8; |
261 | BarcodeCycleCount=0; |
262 | return(1); |
263 | } |
264 | |
265 | static void FP_FASTAPASS(1) BarcodeIRQHook(int a) |
266 | { |
267 | BandaiIRQHook(a); |
268 | |
269 | BarcodeCycleCount+=a; |
270 | |
271 | if(BarcodeCycleCount >= 1000) |
272 | { |
273 | BarcodeCycleCount -= 1000; |
274 | if(BarcodeData[BarcodeReadPos]==0xFF) |
275 | { |
276 | BarcodeOut=0; |
277 | } |
278 | else |
279 | { |
280 | BarcodeOut=(BarcodeData[BarcodeReadPos]^1)<<3; |
281 | BarcodeReadPos++; |
282 | } |
283 | } |
284 | } |
285 | |
286 | static DECLFR(Mapper157_read) |
287 | { |
288 | uint8 ret; |
289 | |
290 | ret=BarcodeOut; |
291 | return(ret); |
292 | } |
293 | |
294 | void Mapper157_init(void) |
295 | { |
296 | FCEUGameInfo.cspecial = SIS_DATACH; |
297 | MapIRQHook=BarcodeIRQHook; |
298 | SetWriteHandler(0x6000,0xFFFF,Mapper16_write); |
299 | SetReadHandler(0x6000,0x7FFF,Mapper157_read); |
300 | |
301 | BarcodeData[0]=0xFF; |
302 | BarcodeReadPos=0; |
303 | BarcodeOut=0; |
304 | BarcodeCycleCount=0; |
305 | } |