bcec3a9001e4fa12af02e91a27b954fde6c2f915
[fceu.git] / boards / sachen.c
1 /* FCE Ultra - NES/Famicom Emulator
2  *
3  * Copyright notice for this file:
4  *  Copyright (C) 2002 Xodnizel
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];
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 }
36
37 static void S74LS374NSynco(void)
38 {
39   setprg32(0x8000,latch[0]);
40   setchr8(latch[1]|latch[3]|latch[4]);
41   MSync(latch[2]);
42 }
43
44 static DECLFW(S74LS374NWrite)
45 {
46   A&=0x4101;
47   if(A==0x4100)
48     cmd=V&7;
49   else
50   {
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();
60   }
61 }
62
63 static void S74LS374NPower(void)
64 {
65    latch[0]=latch[1]=latch[2]=latch[3]=latch[4]=0;
66    S74LS374NSynco();
67    SetReadHandler(0x8000,0xFFFF,CartBR);
68    SetWriteHandler(0x4100,0x7FFF,S74LS374NWrite);
69 }
70
71 static void S74LS374NRestore(int version)
72 {
73    S74LS374NSynco();
74 }
75
76 void S74LS374N_Init(CartInfo *info)
77 {
78   info->Power=S74LS374NPower;
79   GameStateRestore=S74LS374NRestore;
80   AddExState(latch, 5, 0, "LATC");
81   AddExState(&cmd, 1, 0, "CMD");
82 }
83
84 static void S74LS374NASynco(void)
85 {
86   setprg32(0x8000,latch[0]);
87   setchr8(latch[1]);
88   MSync(latch[2]);
89 }
90
91 static DECLFW(S74LS374NAWrite)
92 {
93   A&=0x4101;
94   if(A==0x4100)
95     cmd=V&7;
96   else
97   {
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();
108   }
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.
136   {
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     }
161   }
162   MSync(latch[7]>>1);
163 }
164
165 static DECLFW(S8259Write)
166 {
167   A&=0x4101;
168   if(A==0x4100)
169     cmd=V;
170   else
171   {
172     latch[cmd&7]=V;
173     S8259Synco();
174   }
175 }
176
177 static void S8259Reset(void)
178 {
179   int x;
180   cmd=0;
181
182   for(x=0;x<8;x++) latch[x]=0;
183   setchr8(0);
184
185   S8259Synco();
186   SetReadHandler(0x8000,0xFFFF,CartBR);
187   SetWriteHandler(0x4100,0x7FFF,S8259Write);
188 }
189
190 static void S8259Restore(int version)
191 {
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;
202 }
203
204 void S8259B_Init(CartInfo *info) // Kevin's Horton 138 mapper
205 {
206   info->Power=S8259Reset;
207   GameStateRestore=S8259Restore;
208   AddExState(latch, 8, 0, "LATC");
209   AddExState(&cmd, 1, 0, "CMD");
210   type=1;
211 }
212
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;
220 }
221
222 void S8259D_Init(CartInfo *info) // Kevin's Horton 137 mapper
223 {
224   info->Power=S8259Reset;
225   GameStateRestore=S8259Restore;
226   AddExState(latch, 8, 0, "LATC");
227   AddExState(&cmd, 1, 0, "CMD");
228   type=3;
229 }
230
231 static void(*WSync)(void);
232
233 static void SA0161MSynco()
234 {
235   setprg32(0x8000,(latch[0]>>3)&1);
236   setchr8(latch[0]&7);
237 }
238
239 static DECLFW(SAWrite)
240 {
241   if(A&0x100)
242   {
243     latch[0]=V;
244     WSync();
245   }
246 }
247
248 static void SAReset(void)
249 {
250   latch[0]=0;
251   WSync();
252   SetReadHandler(0x8000,0xFFFF,CartBR);
253   SetWriteHandler(0x4100,0x5FFF,SAWrite);
254 }
255
256 static void SA0161MRestore(int version)
257 {
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");
267 }
268
269 static void SA72007Synco()
270 {
271   setprg32(0x8000,0);
272   setchr8(latch[0]>>7);
273 }
274
275 static void SA72007Restore(int version)
276 {
277   SA72007Synco();
278 }
279
280 void SA72007_Init(CartInfo *info)
281 {
282   WSync=SA72007Synco;
283   GameStateRestore=SA72007Restore;
284   info->Power=SAReset;
285   AddExState(&latch[0], 1, 0, "LATC");
286 }
287
288 static void SA72008Synco()
289 {
290   setprg32(0x8000,(latch[0]>>2)&1);
291   setchr8(latch[0]&3);
292 }
293
294 static void SA72008Restore(int version)
295 {
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");
305 }
306
307 static DECLFW(SADWrite)
308 {
309   latch[0]=V;
310   WSync();
311 }
312
313 static void SADReset(void)
314 {
315   latch[0]=0;
316   WSync();
317   SetReadHandler(0x8000,0xFFFF,CartBR);
318   SetWriteHandler(0x8000,0xFFFF,SADWrite);
319 }
320
321 static void SA0037Synco()
322 {
323   setprg32(0x8000,(latch[0]>>3)&1);
324   setchr8(latch[0]&7);
325 }
326
327 static void SA0037Restore(int version)
328 {
329   SA0037Synco();
330 }
331
332 void SA0036_Init(CartInfo *info)
333 {
334   WSync=SA72007Synco;
335   GameStateRestore=SA72007Restore;
336   info->Power=SADReset;
337   AddExState(&latch[0], 1, 0, "LATC");
338 }
339
340 void SA0037_Init(CartInfo *info)
341 {
342   WSync=SA0037Synco;
343   GameStateRestore=SA0037Restore;
344   info->Power=SADReset;
345   AddExState(&latch[0], 1, 0, "LATC");
346 }
347
348 static void TCU01Synco()
349 {
350   setprg32(0x8000,(latch[0]>>2)&1);
351   setchr8((latch[0]>>3)&0xF);
352 }
353
354 static DECLFW(TCWrite)
355 {
356   if((A&0x103)==0x102)
357     latch[0]=V;
358   TCU01Synco();
359 }
360
361 static void TCU01Reset(void)
362 {
363   latch[0]=0;
364   SetReadHandler(0x8000,0xFFFF,CartBR);
365   SetWriteHandler(0x4100,0xFFFF,TCWrite);
366   TCU01Synco();
367 }
368
369 static void TCU01Restore(int version)
370 {
371   TCU01Synco();
372 }
373
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 }