merge mappers from FCEU-mm
[fceu.git] / boards / datalatch.c
CommitLineData
43725da7 1/* FCE Ultra - NES/Famicom Emulator\r
2 *\r
3 * Copyright notice for this file:\r
4 * Copyright (C) 2002 Xodnizel\r
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
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
19 */\r
20\r
21#include "mapinc.h"\r
22\r
23static uint8 latche, latcheinit, bus_conflict;\r
24static uint16 addrreg0, addrreg1;\r
25static uint8 *WRAM=NULL;\r
26static uint32 WRAMSIZE;\r
27static void(*WSync)(void);\r
28\r
29static DECLFW(LatchWrite)\r
30{\r
31// FCEU_printf("bs %04x %02x\n",A,V);\r
32 if(bus_conflict)\r
33 latche=V&CartBR(A);\r
34 else\r
35 latche=V;\r
36 WSync();\r
37}\r
38\r
39static void LatchPower(void)\r
40{\r
41 latche=latcheinit;\r
42 WSync();\r
43 SetReadHandler(0x6000,0xFFFF,CartBR);\r
44 SetWriteHandler(0x6000,0x7FFF,CartBW);\r
45 SetWriteHandler(addrreg0,addrreg1,LatchWrite);\r
46}\r
47\r
48static void LatchClose(void)\r
49{\r
50 if(WRAM)\r
51 FCEU_gfree(WRAM);\r
52 WRAM=NULL;\r
53}\r
54\r
55static void StateRestore(int version)\r
56{\r
57 WSync();\r
58}\r
59\r
60static void Latch_Init(CartInfo *info, void (*proc)(void), uint8 init, uint16 adr0, uint16 adr1, uint8 wram, uint8 busc)\r
61{\r
62 bus_conflict = busc;\r
63 latcheinit=init;\r
64 addrreg0=adr0;\r
65 addrreg1=adr1;\r
66 WSync=proc;\r
67 info->Power=LatchPower;\r
68 info->Close=LatchClose;\r
69 GameStateRestore=StateRestore;\r
70 if(wram)\r
71 {\r
72 WRAMSIZE=8192;\r
73 WRAM=(uint8*)FCEU_gmalloc(WRAMSIZE);\r
74 SetupCartPRGMapping(0x10,WRAM,WRAMSIZE,1);\r
75 if(info->battery)\r
76 {\r
77 info->SaveGame[0]=WRAM;\r
78 info->SaveGameLen[0]=WRAMSIZE;\r
79 }\r
80 AddExState(WRAM, WRAMSIZE, 0, "WRAM");\r
81 }\r
82 AddExState(&latche, 1, 0, "LATC");\r
83}\r
84\r
85//------------------ Map 0 ---------------------------\r
86\r
87#ifdef DEBUG_MAPPER\r
88static DECLFW(NROMWrite)\r
89{\r
90 FCEU_printf("bs %04x %02x\n",A,V);\r
91 CartBW(A,V);\r
92}\r
93#endif\r
94\r
95static void NROMPower(void)\r
96{\r
97 setprg8r(0x10,0x6000,0); // Famili BASIC (v3.0) need it (uses only 4KB), FP-BASIC uses 8KB\r
98 setprg16(0x8000,0);\r
99 setprg16(0xC000,~0);\r
100 setchr8(0);\r
101\r
102 SetReadHandler(0x6000,0x7FFF,CartBR);\r
103 SetWriteHandler(0x6000,0x7FFF,CartBW);\r
104 SetReadHandler(0x8000,0xFFFF,CartBR);\r
105\r
106 #ifdef DEBUG_MAPPER\r
107 SetWriteHandler(0x4020,0xFFFF,NROMWrite);\r
108 #endif\r
109}\r
110\r
111void NROM_Init(CartInfo *info)\r
112{\r
113 info->Power=NROMPower;\r
114 info->Close=LatchClose;\r
115\r
116 WRAMSIZE=8192;\r
117 WRAM=(uint8*)FCEU_gmalloc(WRAMSIZE);\r
118 SetupCartPRGMapping(0x10,WRAM,WRAMSIZE,1);\r
119 if(info->battery)\r
120 {\r
121 info->SaveGame[0]=WRAM;\r
122 info->SaveGameLen[0]=WRAMSIZE;\r
123 }\r
124 AddExState(WRAM, WRAMSIZE, 0, "WRAM");\r
125}\r
126\r
127//------------------ Map 2 ---------------------------\r
128\r
129static void UNROMSync(void)\r
130{\r
131 static uint32 mirror_in_use = 0;\r
132 setprg16(0x8000,latche&7);\r
133 if(latche&8) mirror_in_use = 1;\r
134 if(mirror_in_use)\r
135 setmirror(((latche >> 3)&1)^1); // Higway Star Hacked mapper\r
136 setprg16(0xc000,~0);\r
137 setchr8(0);\r
138}\r
139\r
140void UNROM_Init(CartInfo *info)\r
141{\r
142 Latch_Init(info, UNROMSync, 0, 0x8000, 0xFFFF, 0, 1);\r
143}\r
144\r
145//------------------ Map 3 ---------------------------\r
146\r
147static void CNROMSync(void)\r
148{\r
149 setchr8(latche);\r
150 setprg32(0x8000,0);\r
151 setprg8r(0x10,0x6000,0); // Hayauchy IGO uses 2Kb or RAM\r
152}\r
153\r
154void CNROM_Init(CartInfo *info)\r
155{\r
156 Latch_Init(info, CNROMSync, 0, 0x8000, 0xFFFF, 1, 0);\r
157}\r
158\r
159//------------------ Map 7 ---------------------------\r
160\r
161static void ANROMSync()\r
162{\r
163 setprg32(0x8000,latche&0xf);\r
164 setmirror(MI_0+((latche>>4)&1));\r
165 setchr8(0);\r
166}\r
167\r
168void ANROM_Init(CartInfo *info)\r
169{\r
170 Latch_Init(info, ANROMSync, 0, 0x8000, 0xFFFF, 0, 0);\r
171}\r
172\r
173//------------------ Map 8 ---------------------------\r
174\r
175static void M8Sync()\r
176{\r
177 setprg16(0x8000,latche>>3);\r
178 setprg16(0xc000,1);\r
179 setchr8(latche&3);\r
180}\r
181\r
182void Mapper8_Init(CartInfo *info)\r
183{\r
184 Latch_Init(info, M8Sync, 0, 0x8000, 0xFFFF, 0, 0);\r
185}\r
186\r
187//------------------ Map 11 ---------------------------\r
188\r
189static void M11Sync(void)\r
190{\r
191 setprg32(0x8000,latche&0xf);\r
192 setchr8(latche>>4);\r
193}\r
194\r
195void Mapper11_Init(CartInfo *info)\r
196{\r
197 Latch_Init(info, M11Sync, 0, 0x8000, 0xFFFF, 0, 0);\r
198}\r
199\r
200void Mapper144_Init(CartInfo *info)\r
201{\r
202 Latch_Init(info, M11Sync, 0, 0x8001, 0xFFFF, 0, 0);\r
203}\r
204\r
205//------------------ Map 13 ---------------------------\r
206\r
207static void CPROMSync(void)\r
208{\r
209 setchr4(0x0000,0);\r
210 setchr4(0x1000,latche&3);\r
211 setprg32(0x8000,0);\r
212}\r
213\r
214void CPROM_Init(CartInfo *info)\r
215{\r
216 Latch_Init(info, CPROMSync, 0, 0x8000, 0xFFFF, 0, 0);\r
217}\r
218\r
219//------------------ Map 36 ---------------------------\r
220\r
221static void M36Sync(void)\r
222{\r
223 setprg32(0x8000,latche>>4);\r
224 setchr8((latche)&0xF);\r
225}\r
226\r
227void Mapper36_Init(CartInfo *info)\r
228{\r
229 Latch_Init(info, M36Sync, 0, 0x8400, 0xfffe, 0, 0);\r
230}\r
231\r
232//------------------ Map 38 ---------------------------\r
233\r
234static void M38Sync(void)\r
235{\r
236 setprg32(0x8000,latche&3);\r
237 setchr8(latche>>2);\r
238}\r
239\r
240void Mapper38_Init(CartInfo *info)\r
241{\r
242 Latch_Init(info, M38Sync, 0, 0x7000, 0x7FFF, 0, 0);\r
243}\r
244\r
245//------------------ Map 66 ---------------------------\r
246\r
247static void MHROMSync(void)\r
248{\r
249 setprg32(0x8000,latche>>4);\r
250 setchr8(latche&0xf);\r
251}\r
252\r
253void MHROM_Init(CartInfo *info)\r
254{\r
255 Latch_Init(info, MHROMSync, 0, 0x8000, 0xFFFF, 0, 0);\r
256}\r
257\r
258//------------------ Map 70 ---------------------------\r
259\r
260static void M70Sync()\r
261{\r
262 setprg16(0x8000,latche>>4);\r
263 setprg16(0xc000,~0);\r
264 setchr8(latche&0xf);\r
265}\r
266\r
267void Mapper70_Init(CartInfo *info)\r
268{\r
269 Latch_Init(info, M70Sync, 0, 0x8000, 0xFFFF, 0, 0);\r
270}\r
271\r
272//------------------ Map 78 ---------------------------\r
273/* Should be two separate emulation functions for this "mapper". Sigh. URGE TO KILL RISING. */\r
274static void M78Sync()\r
275{\r
276 setprg16(0x8000,(latche&7));\r
277 setprg16(0xc000,~0);\r
278 setchr8(latche>>4);\r
279 setmirror(MI_0+((latche>>3)&1));\r
280}\r
281\r
282void Mapper78_Init(CartInfo *info)\r
283{\r
284 Latch_Init(info, M78Sync, 0, 0x8000, 0xFFFF, 0, 0);\r
285}\r
286\r
287//------------------ Map 86 ---------------------------\r
288\r
289static void M86Sync(void)\r
290{\r
291 setprg32(0x8000,(latche >> 4) & 3);\r
292 setchr8((latche & 3) | ((latche >> 4) & 4));\r
293}\r
294\r
295void Mapper86_Init(CartInfo *info)\r
296{\r
297 Latch_Init(info, M86Sync, ~0, 0x6000, 0x6FFF, 0, 0);\r
298}\r
299\r
300//------------------ Map 87 ---------------------------\r
301\r
302static void M87Sync(void)\r
303{\r
304 setprg32(0x8000,0);\r
305 setchr8(((latche>>1)&1)|((latche<<1)&2));\r
306}\r
307\r
308void Mapper87_Init(CartInfo *info)\r
309{\r
310 Latch_Init(info, M87Sync, ~0, 0x6000, 0xFFFF, 0, 0);\r
311}\r
312\r
313//------------------ Map 89 ---------------------------\r
314\r
315static void M89Sync(void)\r
316{\r
317 setprg16(0x8000,(latche >> 4) & 7);\r
318 setprg16(0xc000, ~0);\r
319 setchr8((latche & 7) | ((latche >> 4) & 8));\r
320 setmirror(MI_0 + ((latche >> 3) & 1));\r
321}\r
322\r
323void Mapper89_Init(CartInfo *info)\r
324{\r
325 Latch_Init(info, M89Sync, 0, 0x8000, 0xFFFF, 0, 0);\r
326}\r
327\r
328//------------------ Map 93 ---------------------------\r
329\r
330static void SSUNROMSync(void)\r
331{\r
332 setprg16(0x8000,latche>>4);\r
333 setprg16(0xc000,~0);\r
334 setchr8(0);\r
335}\r
336\r
337void SUNSOFT_UNROM_Init(CartInfo *info)\r
338{\r
339 Latch_Init(info, SSUNROMSync, 0, 0x8000, 0xFFFF, 0, 0);\r
340}\r
341\r
342//------------------ Map 94 ---------------------------\r
343\r
344static void M94Sync(void)\r
345{\r
346 setprg16(0x8000,latche>>2);\r
347 setprg16(0xc000,~0);\r
348 setchr8(0);\r
349}\r
350\r
351void Mapper94_Init(CartInfo *info)\r
352{\r
353 Latch_Init(info, M94Sync, 0, 0x8000, 0xFFFF, 0, 0);\r
354}\r
355\r
356//------------------ Map 97 ---------------------------\r
357\r
358static void M97Sync(void)\r
359{\r
360 setchr8(0);\r
361 setprg16(0x8000,~0);\r
362 setprg16(0xc000,latche & 15);\r
363 switch(latche >> 6)\r
364 {\r
365 case 0: break;\r
366 case 1: setmirror(MI_H); break;\r
367 case 2: setmirror(MI_V); break;\r
368 case 3: break;\r
369 }\r
370 setchr8(((latche>>1)&1)|((latche<<1)&2));\r
371}\r
372\r
373void Mapper97_Init(CartInfo *info)\r
374{\r
375 Latch_Init(info, M97Sync, ~0, 0x8000, 0xFFFF, 0, 0);\r
376}\r
377\r
378//------------------ Map 101 ---------------------------\r
379\r
380static void M101Sync(void)\r
381{\r
382 setprg32(0x8000,0);\r
383 setchr8(latche);\r
384}\r
385\r
386void Mapper101_Init(CartInfo *info)\r
387{\r
388 Latch_Init(info, M101Sync, ~0, 0x6000, 0x7FFF, 0, 0);\r
389}\r
390\r
391//------------------ Map 107 ---------------------------\r
392\r
393static void M107Sync(void)\r
394{\r
395 setprg32(0x8000,(latche>>1)&3);\r
396 setchr8(latche&7);\r
397}\r
398\r
399void Mapper107_Init(CartInfo *info)\r
400{\r
401 Latch_Init(info, M107Sync, ~0, 0x8000, 0xFFFF, 0, 0);\r
402}\r
403\r
404//------------------ Map 113 ---------------------------\r
405\r
406static void M113Sync(void)\r
407{\r
408 setprg32(0x8000,(latche>>3)&7);\r
409 setchr8(((latche>>3)&8)|(latche&7));\r
410// setmirror(latche>>7); // only for HES 6in1\r
411}\r
412\r
413void Mapper113_Init(CartInfo *info)\r
414{\r
415 Latch_Init(info, M113Sync, 0, 0x4100, 0x7FFF, 0, 0);\r
416}\r
417\r
418//------------------ Map 140 ---------------------------\r
419\r
420void Mapper140_Init(CartInfo *info)\r
421{\r
422 Latch_Init(info, MHROMSync, 0, 0x6000, 0x7FFF, 0, 0);\r
423}\r
424\r
425//------------------ Map 152 ---------------------------\r
426\r
427static void M152Sync()\r
428{\r
429 setprg16(0x8000,(latche>>4)&7);\r
430 setprg16(0xc000,~0);\r
431 setchr8(latche&0xf);\r
432 setmirror(MI_0+((latche>>7)&1)); /* Saint Seiya...hmm. */\r
433}\r
434\r
435void Mapper152_Init(CartInfo *info)\r
436{\r
437 Latch_Init(info, M152Sync, 0, 0x8000, 0xFFFF, 0, 0);\r
438}\r
439\r
440//------------------ Map 180 ---------------------------\r
441\r
442static void M180Sync(void)\r
443{\r
444 setprg16(0x8000,0);\r
445 setprg16(0xc000,latche);\r
446 setchr8(0);\r
447}\r
448\r
449void Mapper180_Init(CartInfo *info)\r
450{\r
451 Latch_Init(info, M180Sync, 0, 0x8000, 0xFFFF, 0, 0);\r
452}\r
453\r
454//------------------ Map 184 ---------------------------\r
455\r
456static void M184Sync(void)\r
457{\r
458 setchr4(0x0000,latche);\r
459 setchr4(0x1000,latche>>4);\r
460 setprg32(0x8000,0);\r
461}\r
462\r
463void Mapper184_Init(CartInfo *info)\r
464{\r
465 Latch_Init(info, M184Sync, 0, 0x6000, 0x7FFF, 0, 0);\r
466}\r
467\r
468//------------------ Map 240 ---------------------------\r
469\r
470void Mapper240_Init(CartInfo *info)\r
471{\r
472 Latch_Init(info, MHROMSync, 0, 0x4020, 0x5FFF, 0, 0);\r
473 // need SRAM.\r
474}\r
475\r
476//------------------ A65AS ---------------------------\r
477\r
478// actually, there is two cart in one... First have extra mirroring\r
479// mode (one screen) and 32K bankswitching, second one have only\r
480// 16 bankswitching mode and normal mirroring... But there is no any\r
481// correlations between modes and they can be used in one mapper code.\r
482\r
483static void BMCA65ASSync(void)\r
484{\r
485 if(latche&0x40)\r
486 setprg32(0x8000,(latche>>1)&0x0F);\r
487 else\r
488 {\r
489 setprg16(0x8000,((latche&0x30)>>1)|(latche&7));\r
490 setprg16(0xC000,((latche&0x30)>>1)|7);\r
491 }\r
492 setchr8(0);\r
493 if(latche&0x80)\r
494 setmirror(MI_0+(((latche>>5)&1)));\r
495 else\r
496 setmirror(((latche>>3)&1)^1);\r
497}\r
498\r
499void BMCA65AS_Init(CartInfo *info)\r
500{\r
501 Latch_Init(info, BMCA65ASSync, 0, 0x8000, 0xFFFF, 0, 0);\r
502}\r
503\r