merge mappers from FCEU-mm
[fceu.git] / boards / addrlatch.c
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
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
23 static uint16 latche, latcheinit;\r
24 static uint16 addrreg0, addrreg1;\r
25 static void(*WSync)(void);\r
26 static readfunc defread;\r
27 \r
28 static DECLFW(LatchWrite)\r
29 {\r
30 //  FCEU_printf("%04x:%02x\n",A,V);\r
31   latche=A;\r
32   WSync();\r
33 }\r
34 \r
35 static void LatchReset(void)\r
36 {\r
37   latche=latcheinit;\r
38   WSync();\r
39 }\r
40 \r
41 static 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
49 static void StateRestore(int version)\r
50 {\r
51   WSync();\r
52 }\r
53 \r
54 static 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
72 static 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
79 void 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
86 static uint8 dipswitch;\r
87 static 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
100 static 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
108 static void BMCD1038Reset(void)\r
109 {\r
110   dipswitch++;\r
111   dipswitch&=3; \r
112 }\r
113 \r
114 void 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
122 //------------------ UNL43272 ---------------------------\r
123 // mapper much complex, including 16K bankswitching \r
124 static 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
136 static 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
144 static void UNL43272Reset(void)\r
145 {\r
146   latche = 0;\r
147   UNL43272Sync();\r
148 }\r
149 \r
150 void 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
157 //------------------ Map 058 ---------------------------\r
158 \r
159 static 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
172 void BMCGK192_Init(CartInfo *info)\r
173 {\r
174   Latch_Init(info, BMCGK192Sync, 0, 0, 0x8000, 0xFFFF);\r
175 }\r
176 \r
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
183 static 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
205 void Mapper92_Init(CartInfo *info)\r
206 {\r
207   Latch_Init(info, M92Sync, 0, 0x80B0, 0x8000, 0xFFFF);\r
208 }\r
209 \r
210 //------------------ Map 200 ---------------------------\r
211 \r
212 static 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
221 void 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
228 static 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
236 void BMC190in1_Init(CartInfo *info)\r
237\r
238   Latch_Init(info, BMC190in1Sync, 0, 0, 0x8000, 0xFFFF);\r
239 }\r
240 \r
241 //-------------- BMC810544-C-A1 ------------------------\r
242 \r
243 static 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
257 void 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
264 static 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
283 void BMCNTD03_Init(CartInfo *info)\r
284\r
285   Latch_Init(info, BMCNTD03Sync, 0, 0, 0x8000, 0xFFFF);\r
286 }\r