add M-HT's neon scalers
[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 S74LS374MSync(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   S74LS374MSync(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[0]=V&1; latch[3]=(V&1)<<3;break;
54       case 4:latch[4]=(V&1)<<2;break;
55       case 5:latch[0]=V&7;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 DECLFR(S74LS374NRead)
64 {
65   uint8 ret;
66   if((A&0x4100)==0x4100)
67     ret=(X.DB&0xC0)|((~cmd)&0x3F);
68   else
69     ret=X.DB;
70   return ret;
71 }
72
73 static void S74LS374NPower(void)
74 {
75    latch[0]=latch[1]=latch[2]=latch[3]=latch[4]=0;
76    S74LS374NSynco();
77    SetReadHandler(0x8000,0xFFFF,CartBR);
78    SetWriteHandler(0x4100,0x7FFF,S74LS374NWrite);
79    SetReadHandler(0x4100,0x5fff,S74LS374NRead);
80 }
81
82 static void S74LS374NRestore(int version)
83 {
84    S74LS374NSynco();
85 }
86
87 void S74LS374N_Init(CartInfo *info)
88 {
89   info->Power=S74LS374NPower;
90   GameStateRestore=S74LS374NRestore;
91   AddExState(latch, 5, 0, "LATC");
92   AddExState(&cmd, 1, 0, "CMD");
93 }
94
95 static void S74LS374NASynco(void)
96 {
97   setprg32(0x8000,latch[0]);
98   setchr8(latch[1]);
99   S74LS374MSync(latch[2]);
100 }
101
102 static DECLFW(S74LS374NAWrite)
103 {
104   A&=0x4101;
105   if(A==0x4100)
106     cmd=V&7;
107   else
108   {
109     switch(cmd)
110     {
111       case 0:latch[0]=0;latch[1]=3;break;
112       case 2:latch[3]=(V&1)<<3;break;
113       case 4:latch[1]=(latch[1]&6)|(V&3);break;
114       case 5:latch[0]=V&1;break;
115       case 6:latch[1]=(latch[1]&1)|latch[3]|((V&3)<<1);break;
116       case 7:latch[2]=V&1;break;
117     }
118     S74LS374NASynco();
119   }
120 }
121
122 static void S74LS374NAPower(void)
123 {
124    latch[0]=latch[2]=latch[3]=latch[4]=0;
125    latch[1]=3;
126    S74LS374NASynco();
127    SetReadHandler(0x8000,0xFFFF,CartBR);
128    SetWriteHandler(0x4100,0x7FFF,S74LS374NAWrite);
129 }
130
131 void S74LS374NA_Init(CartInfo *info)
132 {
133   info->Power=S74LS374NAPower;
134   GameStateRestore=S74LS374NRestore;
135   AddExState(latch, 5, 0, "LATC");
136   AddExState(&cmd, 1, 0, "CMD");
137 }
138
139 static int type;
140 static void S8259Synco(void)
141 {
142   int x;
143   setprg32(0x8000,latch[5]&7);
144
145   if(!UNIFchrrama)        // No CHR RAM?  Then BS'ing is ok.
146   {
147     for(x=0;x<4;x++)
148     {
149       int bank;
150       if(latch[7]&1)
151         bank=(latch[0]&0x7)|((latch[4]&7)<<3);
152       else
153         bank=(latch[x]&0x7)|((latch[4]&7)<<3);
154       switch (type)
155       {
156         case 00: bank=(bank<<1)|(x&1); setchr2(0x800*x,bank); break;
157         case 01: setchr2(0x800*x,bank); break;
158         case 02: bank=(bank<<2)|(x&3); setchr2(0x800*x,bank); break;
159         case 03: bank=latch[x]&7;
160                  switch (x&3)
161                  {
162                    case 01: bank|=(latch[4]&1)<<4;break;
163                    case 02: bank|=(latch[4]&2)<<3;break;
164                    case 03: bank|=((latch[4]&4)<<2)|((latch[6]&1)<<3);break;
165                  }
166                  setchr1(0x400*x,bank);
167                  setchr4(0x1000,~0);
168                  break;
169       }
170     }
171   }
172   if(!(latch[7]&1))
173     S74LS374MSync(latch[7]>>1);
174   else
175     setmirror(MI_V);
176 }
177
178 static DECLFW(S8259Write)
179 {
180   A&=0x4101;
181   if(A==0x4100)
182     cmd=V;
183   else
184   {
185     latch[cmd&7]=V;
186     S8259Synco();
187   }
188 }
189
190 static void S8259Reset(void)
191 {
192   int x;
193   cmd=0;
194
195   for(x=0;x<8;x++) latch[x]=0;
196   setchr8(0);
197
198   S8259Synco();
199   SetReadHandler(0x8000,0xFFFF,CartBR);
200   SetWriteHandler(0x4100,0x7FFF,S8259Write);
201 }
202
203 static void S8259Restore(int version)
204 {
205   S8259Synco();
206 }
207
208 void S8259A_Init(CartInfo *info) // Kevin's Horton 141 mapper
209 {
210   info->Power=S8259Reset;
211   GameStateRestore=S8259Restore;
212   AddExState(latch, 8, 0, "LATC");
213   AddExState(&cmd, 1, 0, "CMD");
214   type=0;
215 }
216
217 void S8259B_Init(CartInfo *info) // Kevin's Horton 138 mapper
218 {
219   info->Power=S8259Reset;
220   GameStateRestore=S8259Restore;
221   AddExState(latch, 8, 0, "LATC");
222   AddExState(&cmd, 1, 0, "CMD");
223   type=1;
224 }
225
226 void S8259C_Init(CartInfo *info) // Kevin's Horton 139 mapper
227 {
228   info->Power=S8259Reset;
229   GameStateRestore=S8259Restore;
230   AddExState(latch, 8, 0, "LATC");
231   AddExState(&cmd, 1, 0, "CMD");
232   type=2;
233 }
234
235 void S8259D_Init(CartInfo *info) // Kevin's Horton 137 mapper
236 {
237   info->Power=S8259Reset;
238   GameStateRestore=S8259Restore;
239   AddExState(latch, 8, 0, "LATC");
240   AddExState(&cmd, 1, 0, "CMD");
241   type=3;
242 }
243
244 static void(*WSync)(void);
245
246 static DECLFW(SAWrite)
247 {
248   if(A&0x100)
249   {
250     latch[0]=V;
251     WSync();
252   }
253 }
254
255 static void SAPower(void)
256 {
257   latch[0]=0;
258   WSync();
259   SetReadHandler(0x8000,0xFFFF,CartBR);
260   SetWriteHandler(0x4100,0x5FFF,SAWrite);
261 }
262
263 static void SARestore(int version)
264 {
265   WSync();
266 }
267
268 static DECLFW(SADWrite)
269 {
270   latch[0]=V;
271   WSync();
272 }
273
274 static void SADPower(void)
275 {
276   latch[0]=0;
277   WSync();
278   SetReadHandler(0x8000,0xFFFF,CartBR);
279   SetWriteHandler(0x8000,0xFFFF,SADWrite);
280 }
281
282 static void SA0161MSynco()
283 {
284   setprg32(0x8000,(latch[0]>>3)&1);
285   setchr8(latch[0]&7);
286 }
287
288 static void SA72007Synco()
289 {
290   setprg32(0x8000,0);
291   setchr8(latch[0]>>7);
292 }
293
294 static void SA72008Synco()
295 {
296   setprg32(0x8000,(latch[0]>>2)&1);
297   setchr8(latch[0]&3);
298 }
299
300 void SA0161M_Init(CartInfo *info)
301 {
302   WSync=SA0161MSynco;
303   GameStateRestore=SARestore;
304   info->Power=SAPower;
305   AddExState(&latch[0], 1, 0, "LATC");
306 }
307
308 void SA72007_Init(CartInfo *info)
309 {
310   WSync=SA72007Synco;
311   GameStateRestore=SARestore;
312   info->Power=SAPower;
313   AddExState(&latch[0], 1, 0, "LATC");
314 }
315
316 void SA72008_Init(CartInfo *info)
317 {
318   WSync=SA72008Synco;
319   GameStateRestore=SARestore;
320   info->Power=SAPower;
321   AddExState(&latch[0], 1, 0, "LATC");
322 }
323
324 void SA0036_Init(CartInfo *info)
325 {
326   WSync=SA72007Synco;
327   GameStateRestore=SARestore;
328   info->Power=SADPower;
329   AddExState(&latch[0], 1, 0, "LATC");
330 }
331
332 void SA0037_Init(CartInfo *info)
333 {
334   WSync=SA0161MSynco;
335   GameStateRestore=SARestore;
336   info->Power=SADPower;
337   AddExState(&latch[0], 1, 0, "LATC");
338 }
339
340 static void TCU01Synco()
341 {
342   setprg32(0x8000,(latch[0]>>2)&1);
343   setchr8((latch[0]>>3)&0xF);
344 }
345
346 static DECLFW(TCWrite)
347 {
348   if((A&0x103)==0x102)
349   {
350     latch[0]=V;
351     TCU01Synco();
352   }
353 }
354
355 static void TCU01Reset(void)
356 {
357   latch[0]=0;
358   SetReadHandler(0x8000,0xFFFF,CartBR);
359   SetWriteHandler(0x4100,0xFFFF,TCWrite);
360   TCU01Synco();
361 }
362
363 static void TCU01Restore(int version)
364 {
365   TCU01Synco();
366 }
367
368 void TCU01_Init(CartInfo *info)
369 {
370   GameStateRestore=TCU01Restore;
371   info->Power=TCU01Reset;
372   AddExState(&latch[0], 1, 0, "LATC");
373 }
374
375 static DECLFR(TCA01Read)
376 {
377   uint8 ret;
378   if((A&0x4100)==0x4100)
379     ret=(X.DB&0xC0)|((~A)&0x3F);
380   else
381     ret=X.DB;
382   return ret;
383 }
384
385 static void TCA01Reset(void)
386 {
387   setprg16(0x8000,0);
388   setprg16(0xC000,1);
389   setchr8(0);
390   SetReadHandler(0x8000,0xFFFF,CartBR);
391   SetReadHandler(0x4100,0x5FFF,TCA01Read);
392 }
393
394 void TCA01_Init(CartInfo *info)
395 {
396   info->Power=TCA01Reset;
397 }
398