c62d2810 |
1 | /* FCE Ultra - NES/Famicom Emulator |
2 | * |
3 | * Copyright notice for this file: |
d97315ac |
4 | * Copyright (C) 2002 Xodnizel |
c62d2810 |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. |
10 | * |
11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ |
20 | |
21 | #include "mapinc.h" |
22 | |
23 | static uint8 cmd; |
24 | static uint8 latch[8]; |
d97315ac |
25 | |
26 | static void MSync(uint8 mirr) |
27 | { |
28 | switch(mirr&3) |
29 | { |
30 | case 0:setmirror(MI_V);break; |
31 | case 1:setmirror(MI_H);break; |
32 | case 2:setmirrorw(0,1,1,1);break; |
33 | case 3:setmirror(MI_0);break; |
34 | } |
35 | } |
c62d2810 |
36 | |
37 | static void S74LS374NSynco(void) |
38 | { |
d97315ac |
39 | setprg32(0x8000,latch[0]); |
40 | setchr8(latch[1]|latch[3]|latch[4]); |
41 | MSync(latch[2]); |
c62d2810 |
42 | } |
43 | |
44 | static DECLFW(S74LS374NWrite) |
45 | { |
d97315ac |
46 | A&=0x4101; |
47 | if(A==0x4100) |
48 | cmd=V&7; |
49 | else |
c62d2810 |
50 | { |
d97315ac |
51 | switch(cmd) |
52 | { |
53 | case 2:latch[3]=(V&1)<<3;break; |
54 | case 4:latch[4]=(V&1)<<2;break; |
55 | case 5:latch[0]=V&0x7;break; |
56 | case 6:latch[1]=V&3;break; |
57 | case 7:latch[2]=V>>1;break; |
58 | } |
59 | S74LS374NSynco(); |
c62d2810 |
60 | } |
c62d2810 |
61 | } |
62 | |
d97315ac |
63 | static void S74LS374NPower(void) |
c62d2810 |
64 | { |
d97315ac |
65 | latch[0]=latch[1]=latch[2]=latch[3]=latch[4]=0; |
66 | S74LS374NSynco(); |
67 | SetReadHandler(0x8000,0xFFFF,CartBR); |
68 | SetWriteHandler(0x4100,0x7FFF,S74LS374NWrite); |
c62d2810 |
69 | } |
70 | |
71 | static void S74LS374NRestore(int version) |
72 | { |
d97315ac |
73 | S74LS374NSynco(); |
c62d2810 |
74 | } |
75 | |
d97315ac |
76 | void S74LS374N_Init(CartInfo *info) |
c62d2810 |
77 | { |
d97315ac |
78 | info->Power=S74LS374NPower; |
79 | GameStateRestore=S74LS374NRestore; |
80 | AddExState(latch, 5, 0, "LATC"); |
81 | AddExState(&cmd, 1, 0, "CMD"); |
c62d2810 |
82 | } |
83 | |
d97315ac |
84 | static void S74LS374NASynco(void) |
c62d2810 |
85 | { |
d97315ac |
86 | setprg32(0x8000,latch[0]); |
87 | setchr8(latch[1]); |
88 | MSync(latch[2]); |
89 | } |
c62d2810 |
90 | |
d97315ac |
91 | static DECLFW(S74LS374NAWrite) |
92 | { |
93 | A&=0x4101; |
94 | if(A==0x4100) |
95 | cmd=V&7; |
96 | else |
c62d2810 |
97 | { |
d97315ac |
98 | switch(cmd) |
99 | { |
100 | case 0:latch[0]=0;latch[1]=3;break; |
101 | case 2:latch[3]=(V&1)<<3;break; |
102 | case 4:latch[1]=(latch[1]&6)|(V&3);break; |
103 | case 5:latch[0]=V&1;break; |
104 | case 6:latch[1]=(latch[1]&1)|latch[3]|((V&3)<<1);break; |
105 | case 7:latch[2]=V&1;break; |
106 | } |
107 | S74LS374NSynco(); |
c62d2810 |
108 | } |
d97315ac |
109 | } |
110 | |
111 | static void S74LS374NAPower(void) |
112 | { |
113 | latch[0]=latch[2]=latch[3]=latch[4]=0; |
114 | latch[1]=3; |
115 | S74LS374NASynco(); |
116 | SetReadHandler(0x8000,0xFFFF,CartBR); |
117 | SetWriteHandler(0x4100,0x7FFF,S74LS374NAWrite); |
118 | } |
119 | |
120 | void S74LS374NA_Init(CartInfo *info) |
121 | { |
122 | info->Power=S74LS374NAPower; |
123 | GameStateRestore=S74LS374NRestore; |
124 | AddExState(latch, 5, 0, "LATC"); |
125 | AddExState(&cmd, 1, 0, "CMD"); |
126 | } |
127 | |
128 | static int type; |
129 | //static int PPUbus; |
130 | static void S8259Synco(void) |
131 | { |
132 | int x; |
133 | setprg32(0x8000,latch[5]&7); |
134 | |
135 | if(!UNIFchrrama) // No CHR RAM? Then BS'ing is ok. |
c62d2810 |
136 | { |
d97315ac |
137 | for(x=0;x<4;x++) |
138 | { |
139 | int bank; |
140 | if(latch[7]&1) |
141 | bank=(latch[0]&0x7)|((latch[4]&7)<<3); |
142 | else |
143 | bank=(latch[x]&0x7)|((latch[4]&7)<<3); |
144 | switch (type) |
145 | { |
146 | case 00: bank=(bank<<1)|(x&1); setchr2(0x800*x,bank); break; |
147 | case 01: setchr2(0x800*x,bank); break; |
148 | case 02: bank=(bank<<2)|(x&3); setchr2(0x800*x,bank); break; |
149 | case 03: bank=latch[x]&7; |
150 | switch (x&3) |
151 | { |
152 | case 01: bank|=(latch[4]&1)<<4;break; |
153 | case 02: bank|=(latch[4]&2)<<3;break; |
154 | case 03: bank|=((latch[4]&4)<<2)|((latch[6]&1)<<3);break; |
155 | } |
156 | setchr1(0x400*x,bank); |
157 | setchr4(0x1000,~0); |
158 | break; |
159 | } |
160 | } |
c62d2810 |
161 | } |
d97315ac |
162 | MSync(latch[7]>>1); |
c62d2810 |
163 | } |
164 | |
165 | static DECLFW(S8259Write) |
166 | { |
d97315ac |
167 | A&=0x4101; |
168 | if(A==0x4100) |
169 | cmd=V; |
170 | else |
171 | { |
172 | latch[cmd&7]=V; |
173 | S8259Synco(); |
174 | } |
c62d2810 |
175 | } |
176 | |
177 | static void S8259Reset(void) |
178 | { |
d97315ac |
179 | int x; |
180 | cmd=0; |
c62d2810 |
181 | |
d97315ac |
182 | for(x=0;x<8;x++) latch[x]=0; |
183 | setchr8(0); |
c62d2810 |
184 | |
d97315ac |
185 | S8259Synco(); |
186 | SetReadHandler(0x8000,0xFFFF,CartBR); |
187 | SetWriteHandler(0x4100,0x7FFF,S8259Write); |
c62d2810 |
188 | } |
189 | |
190 | static void S8259Restore(int version) |
191 | { |
d97315ac |
192 | S8259Synco(); |
193 | } |
194 | |
195 | void S8259A_Init(CartInfo *info) // Kevin's Horton 141 mapper |
196 | { |
197 | info->Power=S8259Reset; |
198 | GameStateRestore=S8259Restore; |
199 | AddExState(latch, 8, 0, "LATC"); |
200 | AddExState(&cmd, 1, 0, "CMD"); |
201 | type=0; |
c62d2810 |
202 | } |
203 | |
d97315ac |
204 | void S8259B_Init(CartInfo *info) // Kevin's Horton 138 mapper |
c62d2810 |
205 | { |
d97315ac |
206 | info->Power=S8259Reset; |
207 | GameStateRestore=S8259Restore; |
208 | AddExState(latch, 8, 0, "LATC"); |
209 | AddExState(&cmd, 1, 0, "CMD"); |
210 | type=1; |
211 | } |
c62d2810 |
212 | |
d97315ac |
213 | void S8259C_Init(CartInfo *info) // Kevin's Horton 139 mapper |
214 | { |
215 | info->Power=S8259Reset; |
216 | GameStateRestore=S8259Restore; |
217 | AddExState(latch, 8, 0, "LATC"); |
218 | AddExState(&cmd, 1, 0, "CMD"); |
219 | type=2; |
c62d2810 |
220 | } |
221 | |
d97315ac |
222 | void S8259D_Init(CartInfo *info) // Kevin's Horton 137 mapper |
c62d2810 |
223 | { |
d97315ac |
224 | info->Power=S8259Reset; |
225 | GameStateRestore=S8259Restore; |
226 | AddExState(latch, 8, 0, "LATC"); |
227 | AddExState(&cmd, 1, 0, "CMD"); |
228 | type=3; |
c62d2810 |
229 | } |
230 | |
231 | static void(*WSync)(void); |
232 | |
233 | static void SA0161MSynco() |
234 | { |
d97315ac |
235 | setprg32(0x8000,(latch[0]>>3)&1); |
236 | setchr8(latch[0]&7); |
c62d2810 |
237 | } |
238 | |
239 | static DECLFW(SAWrite) |
240 | { |
d97315ac |
241 | if(A&0x100) |
242 | { |
243 | latch[0]=V; |
244 | WSync(); |
245 | } |
c62d2810 |
246 | } |
247 | |
248 | static void SAReset(void) |
249 | { |
d97315ac |
250 | latch[0]=0; |
251 | WSync(); |
252 | SetReadHandler(0x8000,0xFFFF,CartBR); |
253 | SetWriteHandler(0x4100,0x5FFF,SAWrite); |
c62d2810 |
254 | } |
255 | |
d97315ac |
256 | static void SA0161MRestore(int version) |
c62d2810 |
257 | { |
d97315ac |
258 | SA0161MSynco(); |
259 | } |
260 | |
261 | void SA0161M_Init(CartInfo *info) |
262 | { |
263 | WSync=SA0161MSynco; |
264 | GameStateRestore=SA0161MRestore; |
265 | info->Power=SAReset; |
266 | AddExState(&latch[0], 1, 0, "LATC"); |
c62d2810 |
267 | } |
268 | |
269 | static void SA72007Synco() |
270 | { |
d97315ac |
271 | setprg32(0x8000,0); |
272 | setchr8(latch[0]>>7); |
273 | } |
274 | |
275 | static void SA72007Restore(int version) |
276 | { |
277 | SA72007Synco(); |
c62d2810 |
278 | } |
279 | |
d97315ac |
280 | void SA72007_Init(CartInfo *info) |
c62d2810 |
281 | { |
d97315ac |
282 | WSync=SA72007Synco; |
283 | GameStateRestore=SA72007Restore; |
284 | info->Power=SAReset; |
285 | AddExState(&latch[0], 1, 0, "LATC"); |
c62d2810 |
286 | } |
287 | |
288 | static void SA72008Synco() |
289 | { |
d97315ac |
290 | setprg32(0x8000,(latch[0]>>2)&1); |
291 | setchr8(latch[0]&3); |
c62d2810 |
292 | } |
293 | |
d97315ac |
294 | static void SA72008Restore(int version) |
c62d2810 |
295 | { |
d97315ac |
296 | SA72008Synco(); |
297 | } |
298 | |
299 | void SA72008_Init(CartInfo *info) |
300 | { |
301 | WSync=SA72008Synco; |
302 | GameStateRestore=SA72008Restore; |
303 | info->Power=SAReset; |
304 | AddExState(&latch[0], 1, 0, "LATC"); |
c62d2810 |
305 | } |
306 | |
307 | static DECLFW(SADWrite) |
308 | { |
d97315ac |
309 | latch[0]=V; |
310 | WSync(); |
c62d2810 |
311 | } |
312 | |
313 | static void SADReset(void) |
314 | { |
d97315ac |
315 | latch[0]=0; |
316 | WSync(); |
317 | SetReadHandler(0x8000,0xFFFF,CartBR); |
318 | SetWriteHandler(0x8000,0xFFFF,SADWrite); |
c62d2810 |
319 | } |
320 | |
d97315ac |
321 | static void SA0037Synco() |
c62d2810 |
322 | { |
d97315ac |
323 | setprg32(0x8000,(latch[0]>>3)&1); |
324 | setchr8(latch[0]&7); |
c62d2810 |
325 | } |
326 | |
d97315ac |
327 | static void SA0037Restore(int version) |
c62d2810 |
328 | { |
d97315ac |
329 | SA0037Synco(); |
c62d2810 |
330 | } |
331 | |
d97315ac |
332 | void SA0036_Init(CartInfo *info) |
c62d2810 |
333 | { |
d97315ac |
334 | WSync=SA72007Synco; |
335 | GameStateRestore=SA72007Restore; |
336 | info->Power=SADReset; |
337 | AddExState(&latch[0], 1, 0, "LATC"); |
c62d2810 |
338 | } |
339 | |
d97315ac |
340 | void SA0037_Init(CartInfo *info) |
c62d2810 |
341 | { |
d97315ac |
342 | WSync=SA0037Synco; |
343 | GameStateRestore=SA0037Restore; |
344 | info->Power=SADReset; |
345 | AddExState(&latch[0], 1, 0, "LATC"); |
c62d2810 |
346 | } |
347 | |
348 | static void TCU01Synco() |
349 | { |
d97315ac |
350 | setprg32(0x8000,(latch[0]>>2)&1); |
351 | setchr8((latch[0]>>3)&0xF); |
c62d2810 |
352 | } |
353 | |
354 | static DECLFW(TCWrite) |
355 | { |
d97315ac |
356 | if((A&0x103)==0x102) |
357 | latch[0]=V; |
358 | TCU01Synco(); |
c62d2810 |
359 | } |
360 | |
361 | static void TCU01Reset(void) |
362 | { |
d97315ac |
363 | latch[0]=0; |
364 | SetReadHandler(0x8000,0xFFFF,CartBR); |
365 | SetWriteHandler(0x4100,0xFFFF,TCWrite); |
366 | TCU01Synco(); |
c62d2810 |
367 | } |
368 | |
d97315ac |
369 | static void TCU01Restore(int version) |
c62d2810 |
370 | { |
d97315ac |
371 | TCU01Synco(); |
c62d2810 |
372 | } |
373 | |
d97315ac |
374 | void TCU01_Init(CartInfo *info) |
375 | { |
376 | GameStateRestore=TCU01Restore; |
377 | info->Power=TCU01Reset; |
378 | AddExState(&latch[0], 1, 0, "LATC"); |
379 | } |
380 | |
381 | static DECLFR(TCA01Read) |
382 | { |
383 | uint8 ret; |
384 | if((A&0x4100)==0x4100) |
385 | ret=(X.DB&0xC0)|((~A)&0x3F); |
386 | else |
387 | ret=X.DB; |
388 | return ret; |
389 | } |
390 | |
391 | static void TCA01Reset(void) |
392 | { |
393 | setprg16(0x8000,0); |
394 | setprg16(0xC000,1); |
395 | setchr8(0); |
396 | SetReadHandler(0x8000,0xFFFF,CartBR); |
397 | SetReadHandler(0x4100,0x5FFF,TCA01Read); |
398 | } |
399 | |
400 | void TCA01_Init(CartInfo *info) |
401 | { |
402 | info->Power=TCA01Reset; |
403 | } |