22589ecd014363911841fe47ef2eab8313cc6640
[fceu.git] / boards / 164.c
1 /* FCE Ultra - NES/Famicom Emulator
2  *
3  * Copyright notice for this file:
4  *  Copyright (C) 2002 Xodnizel 2006 CaH4e3
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20
21 #include "mapinc.h"
22
23 static uint8 cmd, laststrobe, trigger;
24 static uint8 DRegs[8];
25 static SFORMAT StateRegs[]=
26 {
27   {&cmd, 1, "CMD"},
28   {&laststrobe, 1, "STB"},
29   {&trigger, 1, "TRG"},
30   {DRegs, 8, "DREG"},
31   {0}
32 };
33
34 static void Sync(void)
35 {
36   setprg32(0x8000,(DRegs[0]<<4)|(DRegs[1]&0xF));
37 }
38
39 static void StateRestore(int version)
40 {
41   Sync();
42 }
43
44 static DECLFR(ReadLow)
45 {
46   switch (A&0x7700)
47   {
48     case 0x5100: return DRegs[2]; break;
49     case 0x5500: if(trigger)
50                    return DRegs[2];
51                  else
52                    return 0;
53   }
54   return 4;
55 }
56
57 static DECLFW(Write)
58 {
59   switch (A&0x7300)
60   {
61     case 0x5100: DRegs[0]=V; Sync(); break;
62     case 0x5000: DRegs[1]=V; Sync(); break;
63     case 0x5300: DRegs[2]=V; break;
64   }
65 }
66
67 static DECLFW(Write2)
68 {
69   if(A==0x5101)
70   {
71     if(laststrobe&&!V)
72     {
73       trigger^=1;
74     }
75     laststrobe=V;
76   }else if(A==0x5100&&V==6) //damn thoose protected games
77     setprg32(0x8000,3);
78   else
79   switch (A&0x7300)
80   {
81     case 0x5200: DRegs[0]=V; Sync(); break;
82     case 0x5000: DRegs[1]=V; Sync(); if(!(DRegs[1]&0x80)&&(scanline<128)) setchr8(0); break;
83     case 0x5300: DRegs[2]=V; break;
84   }
85 }
86
87 static uint8 WRAM[8192];
88 static DECLFR(AWRAM)
89 {
90   return(WRAM[A-0x6000]);
91 }
92
93 static DECLFW(BWRAM)
94 {
95   WRAM[A-0x6000]=V;
96 }
97
98 static void Power(void)
99 {
100   memset(DRegs,0,8);
101   DRegs[1]=0xFF;
102   cmd=0;
103   SetReadHandler(0x8000,0xFFFF,CartBR);
104   SetWriteHandler(0x4020,0x5FFF,Write);
105   SetReadHandler(0x6000,0x7FFF,AWRAM);
106   SetWriteHandler(0x6000,0x7FFF,BWRAM);
107   setchr8(0);
108   Sync();
109 }
110
111 static void M163HB(void)
112 {
113     if(DRegs[1]&0x80)
114     {
115       if(scanline==239)
116       {
117         setchr4(0x0000,0);
118         setchr4(0x1000,0);
119       }
120       else if(scanline==127)
121       {
122         setchr4(0x0000,1);
123         setchr4(0x1000,1);
124       }
125     }
126 }
127
128 static void Power2(void)
129 {
130   memset(DRegs,0,8);
131   DRegs[1]=0xFF;
132   laststrobe=1;
133   cmd=0;
134   SetReadHandler(0x8000,0xFFFF,CartBR);
135   SetWriteHandler(0x4020,0x5FFF,Write2);
136   SetReadHandler(0x6000,0x7FFF,AWRAM);
137   SetWriteHandler(0x6000,0x7FFF,BWRAM);
138   SetReadHandler(0x5000,0x5FFF,ReadLow);
139   setchr8(0);
140   Sync();
141 }
142
143 void Mapper164_Init(CartInfo *info)
144 {
145   info->Power=Power;
146   GameStateRestore=StateRestore;
147   AddExState(&StateRegs, ~0, 0, 0);
148   AddExState(WRAM, 8192, 0, "WRAM");
149   info->SaveGame[0]=WRAM;\r
150   info->SaveGameLen[0]=8192;
151 }
152
153 void Mapper163_Init(CartInfo *info)
154 {
155   info->Power=Power2;
156   GameHBIRQHook=M163HB;
157   GameStateRestore=StateRestore;
158   AddExState(&StateRegs, ~0, 0, 0);
159   AddExState(WRAM, 8192, 0, "WRAM");
160 }