updated bords/mappers/stuff to 0.98.15, lots of them got broken, asmcore support...
[fceu.git] / mappers / 16.c
CommitLineData
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
24static 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
39static 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
76static 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
83static 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
117void Mapper16_init(void)
118{
119 MapIRQHook=BandaiIRQHook;
120 SetWriteHandler(0x6000,0xFFFF,Mapper16_write);
121}
122
123void 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
132static uint8 BarcodeData[256];
133static int BarcodeReadPos;
134static int BarcodeCycleCount;
135static uint32 BarcodeOut;
136
137int 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
265static 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
286static DECLFR(Mapper157_read)
287{
288 uint8 ret;
289
290 ret=BarcodeOut;
291 return(ret);
292}
293
294void 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}