merge mappers from FCEU-mm
[fceu.git] / boards / addrlatch.c
CommitLineData
386f5371 1/* FCE Ultra - NES/Famicom Emulator\r
2 *\r
3 * Copyright notice for this file:\r
4 * Copyright (C) 2006 CaH4e3\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
43725da7 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
386f5371 19 */\r
20\r
21#include "mapinc.h"\r
22\r
23static uint16 latche, latcheinit;\r
24static uint16 addrreg0, addrreg1;\r
25static void(*WSync)(void);\r
26static readfunc defread;\r
27\r
28static DECLFW(LatchWrite)\r
29{\r
43725da7 30// FCEU_printf("%04x:%02x\n",A,V);\r
386f5371 31 latche=A;\r
32 WSync();\r
33}\r
34\r
35static void LatchReset(void)\r
36{\r
37 latche=latcheinit;\r
38 WSync();\r
39}\r
40\r
41static void LatchPower(void)\r
42{\r
43 latche=latcheinit;\r
44 WSync();\r
45 SetReadHandler(0x8000,0xFFFF,defread);\r
46 SetWriteHandler(addrreg0,addrreg1,LatchWrite);\r
47}\r
48\r
49static void StateRestore(int version)\r
50{\r
51 WSync();\r
52}\r
53\r
54static void Latch_Init(CartInfo *info, void (*proc)(void), readfunc func, uint16 init, uint16 adr0, uint16 adr1)\r
55{\r
56 latcheinit=init;\r
57 addrreg0=adr0;\r
58 addrreg1=adr1;\r
59 WSync=proc;\r
60 if(func)\r
61 defread=func;\r
62 else\r
63 defread=CartBR;\r
64 info->Power=LatchPower;\r
65 info->Reset=LatchReset;\r
66 GameStateRestore=StateRestore;\r
67 AddExState(&latche, 2, 0, "LATC");\r
68}\r
69\r
70//------------------ UNLCC21 ---------------------------\r
71\r
72static void UNLCC21Sync(void)\r
73{\r
74 setprg32(0x8000,0);\r
75 setchr8(latche&1);\r
76 setmirror(MI_0+((latche&2)>>1));\r
77}\r
78\r
79void UNLCC21_Init(CartInfo *info)\r
80{ \r
81 Latch_Init(info, UNLCC21Sync, 0, 0, 0x8000, 0xFFFF);\r
82}\r
83\r
84//------------------ BMCD1038 ---------------------------\r
85\r
86static uint8 dipswitch;\r
87static void BMCD1038Sync(void)\r
88{\r
89 if(latche&0x80)\r
90 {\r
91 setprg16(0x8000,(latche&0x70)>>4);\r
92 setprg16(0xC000,(latche&0x70)>>4);\r
93 }\r
94 else\r
95 setprg32(0x8000,(latche&0x60)>>5);\r
96 setchr8(latche&7);\r
97 setmirror(((latche&8)>>3)^1);\r
98}\r
99\r
100static DECLFR(BMCD1038Read)\r
101{\r
102 if(latche&0x100)\r
103 return dipswitch;\r
104 else\r
105 return CartBR(A);\r
106}\r
107\r
108static void BMCD1038Reset(void)\r
109{\r
110 dipswitch++;\r
111 dipswitch&=3; \r
112}\r
113\r
114void BMCD1038_Init(CartInfo *info)\r
115{ \r
116 Latch_Init(info, BMCD1038Sync, BMCD1038Read, 0, 0x8000, 0xFFFF);\r
117 info->Reset=BMCD1038Reset;\r
118 AddExState(&dipswitch, 1, 0, "DIPSW");\r
119}\r
120\r
121\r
43725da7 122//------------------ UNL43272 ---------------------------\r
123// mapper much complex, including 16K bankswitching \r
124static void UNL43272Sync(void)\r
125{\r
126 if((latche&0x81) == 0x81)\r
127 {\r
128 setprg32(0x8000,(latche&0x38)>>3);\r
129 }\r
130 else\r
131 FCEU_printf("unrecognized command %04!\n",latche);\r
132 setchr8(0);\r
133 setmirror(0);\r
134}\r
135\r
136static DECLFR(UNL43272Read)\r
137{\r
138 if(latche&0x400)\r
139 return CartBR(A & 0xFE);\r
140 else\r
141 return CartBR(A);\r
142}\r
143\r
144static void UNL43272Reset(void)\r
145{\r
146 latche = 0;\r
147 UNL43272Sync();\r
148}\r
149\r
150void UNL43272_Init(CartInfo *info)\r
151{ \r
152 Latch_Init(info, UNL43272Sync, UNL43272Read, 0x81, 0x8000, 0xFFFF);\r
153 info->Reset=UNL43272Reset;\r
154 AddExState(&dipswitch, 1, 0, "DIPSW");\r
155}\r
156\r
386f5371 157//------------------ Map 058 ---------------------------\r
158\r
159static void BMCGK192Sync(void)\r
160{\r
161 if(latche&0x40)\r
162 {\r
163 setprg16(0x8000,latche&7);\r
164 setprg16(0xC000,latche&7);\r
165 }\r
166 else\r
167 setprg32(0x8000,(latche>>1)&3);\r
168 setchr8((latche>>3)&7);\r
169 setmirror(((latche&0x80)>>7)^1);\r
170}\r
171\r
172void BMCGK192_Init(CartInfo *info)\r
173{\r
174 Latch_Init(info, BMCGK192Sync, 0, 0, 0x8000, 0xFFFF);\r
175}\r
176\r
43725da7 177//------------------ Map 092 ---------------------------\r
178// Another two-in-one mapper, two Jaleco carts uses similar\r
179// hardware, but with different wiring.\r
180// Original code provided by LULU\r
181// Additionally, PCB contains DSP extra sound chip, used for voice samples (unemulated)\r
182\r
183static void M92Sync(void)\r
184{\r
185 uint8 reg = latche & 0xF0;\r
186 setprg16(0x8000,0);\r
187 if(latche>=0x9000)\r
188 {\r
189 switch (reg)\r
190 {\r
191 case 0xD0: setprg16(0xc000, latche & 15); break;\r
192 case 0xE0: setchr8(latche & 15); break;\r
193 }\r
194 }\r
195 else\r
196 {\r
197 switch (reg)\r
198 {\r
199 case 0xB0: setprg16(0xc000, latche & 15); break;\r
200 case 0x70: setchr8(latche & 15); break;\r
201 }\r
202 }\r
203}\r
204\r
205void Mapper92_Init(CartInfo *info)\r
206{\r
207 Latch_Init(info, M92Sync, 0, 0x80B0, 0x8000, 0xFFFF);\r
208}\r
209\r
386f5371 210//------------------ Map 200 ---------------------------\r
211\r
212static void M200Sync(void)\r
213{\r
214// FCEU_printf("A\n");\r
215 setprg16(0x8000,latche&7);\r
216 setprg16(0xC000,latche&7);\r
217 setchr8(latche&7);\r
218 setmirror((latche&8)>>3);\r
219}\r
220\r
221void Mapper200_Init(CartInfo *info)\r
222{ \r
223 Latch_Init(info, M200Sync, 0, 0xff, 0x8000, 0xFFFF);\r
224}\r
225\r
226//------------------ 190in1 ---------------------------\r
227\r
228static void BMC190in1Sync(void)\r
229{\r
230 setprg16(0x8000,(latche>>2)&0x07);\r
231 setprg16(0xC000,(latche>>2)&0x07);\r
232 setchr8((latche>>2)&0x07);\r
233 setmirror((latche&1)^1);\r
234}\r
235\r
236void BMC190in1_Init(CartInfo *info)\r
237{ \r
238 Latch_Init(info, BMC190in1Sync, 0, 0, 0x8000, 0xFFFF);\r
239}\r
240\r
43725da7 241//-------------- BMC810544-C-A1 ------------------------\r
242\r
243static void BMC810544CA1Sync(void)\r
244{\r
245 uint32 bank = latche>>7;\r
246 if(latche&0x40)\r
247 setprg32(0x8000,bank);\r
248 else\r
249 {\r
250 setprg16(0x8000,(bank<<1)|((latche>>5)&1));\r
251 setprg16(0xC000,(bank<<1)|((latche>>5)&1));\r
252 }\r
253 setchr8(latche&0x0f);\r
254 setmirror(((latche>>4)&1)^1);\r
255}\r
256\r
257void BMC810544CA1_Init(CartInfo *info)\r
258{ \r
259 Latch_Init(info, BMC810544CA1Sync, 0, 0, 0x8000, 0xFFFF);\r
260}\r
261\r
262//-------------- BMCNTD-03 ------------------------\r
263\r
264static void BMCNTD03Sync(void)\r
265{\r
266 // 1PPP Pmcc spxx xccc\r
267 // 1000 0000 0000 0000 v\r
268 // 1001 1100 0000 0100 h\r
269 // 1011 1010 1100 0100\r
270 uint32 prg = ((latche>>10)&0x1e);\r
271 uint32 chr = ((latche&0x0300)>>5)|(latche&7);\r
272 if(latche&0x80)\r
273 {\r
274 setprg16(0x8000,prg|((latche>>6)&1));\r
275 setprg16(0xC000,prg|((latche>>6)&1));\r
276 }\r
277 else\r
278 setprg32(0x8000,prg>>1);\r
279 setchr8(chr);\r
280 setmirror(((latche>>10)&1)^1);\r
281}\r
282\r
283void BMCNTD03_Init(CartInfo *info)\r
284{ \r
285 Latch_Init(info, BMCNTD03Sync, 0, 0, 0x8000, 0xFFFF);\r
286}\r