mapper fixes for ncpu, debug is broken atm
[fceu.git] / boards / super24.c
CommitLineData
c62d2810 1/* FCE Ultra - NES/Famicom Emulator
2 *
3 * Copyright notice for this file:
4 * Copyright (C) 2002 Ben Parnell
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//undef printf
23
24static int32 IRQCount,IRQLatch;
25static uint8 IRQa,resetmode,mbia;
26static uint8 sizer,bigbank,bigbank2;
27
28static uint8 DRegBuf[8],MMC3_cmd;
29
30static int masko8[8]={63,31,15,1,3,0,0,0};
31//static int masko1[8]={511,255,127,7,7,0,0,0};
32
33static void swsetprg8(uint32 A, uint32 V)
34{
35 V&=masko8[sizer&7];
36 V|=(bigbank*2);
37 setprg8r((V/64)&15,A,V);
38}
39
40static void swsetchr1(uint32 A, uint32 V)
41{
42 if(sizer&0x20)
43 setchr1r(0x10,A,V);
44 else
45 {
46// V&=masko1[sizer&7];
47 V|=bigbank2*8;
48 setchr1r((V/512)&15,A,V);
49 }
50}
51
52static void swsetchr2(uint32 A, uint32 V)
53{
54 if(sizer&0x20)
55 setchr2r(0x10,A,V);
56 else
57 {
58 //V&=masko1[sizer&7]>>1;
c0bf6f9f 59 V|=bigbank2*4;
c62d2810 60 setchr2r((V/256)&15,A,V);
61 }
62}
63
64static void Sup24_hb(void)
65{
66 if(ScreenON || SpriteON)
67 {
68 resetmode=0;
69 if(IRQCount>=0)
70 {
71 IRQCount--;
72 if(IRQCount<0)
73 {
74 if(IRQa)
75 {
76 resetmode = 1;
77 X6502_IRQBegin(FCEU_IQEXT);
78 }
79 }
80 }
81 }
82}
83
84static DECLFW(Sup24IRQWrite)
85{
86 switch(A&0xE001)
87 {
88 case 0xc000:IRQLatch=V;
89 if(resetmode==1)
90 IRQCount=IRQLatch;
91 break;
92 case 0xc001:resetmode=1;
93 IRQCount=IRQLatch;
94 break;
95 case 0xE000:IRQa=0;X6502_IRQEnd(FCEU_IQEXT);
96 if(resetmode==1)
97 {IRQCount=IRQLatch;}
98 break;
99 case 0xE001:IRQa=1;
100 if(resetmode==1)
101 {IRQCount=IRQLatch;}
102 break;
103 }
104}
105
106static INLINE void FixMMC3PRG(int V)
107{
108 swsetprg8(0xA000,DRegBuf[7]);
109 swsetprg8(0xE000,~0);
110 if(V&0x40)
111 {
112 swsetprg8(0xC000,DRegBuf[6]);
113 swsetprg8(0x8000,~1);
114 }
115 else
116 {
117 swsetprg8(0x8000,DRegBuf[6]);
118 swsetprg8(0xC000,~1);
119 }
c0bf6f9f 120 X6502_Rebase();
c62d2810 121}
122
123static INLINE void FixMMC3CHR(int V)
124{
125 int cbase=(V&0x80)<<5;
126 swsetchr2((cbase^0x000),DRegBuf[0]>>1);
127 swsetchr2((cbase^0x800),DRegBuf[1]>>1);
128 swsetchr1(cbase^0x1000,DRegBuf[2]);
129 swsetchr1(cbase^0x1400,DRegBuf[3]);
130 swsetchr1(cbase^0x1800,DRegBuf[4]);
131 swsetchr1(cbase^0x1c00,DRegBuf[5]);
132}
133
134static DECLFW(Super24hiwrite)
135{
136 //printf("$%04x:$%02x, %d\n",A,V,scanline);
137 switch(A&0xE001)
138 {
139 case 0x8000:
140 if((V&0x40) != (MMC3_cmd&0x40))
141 FixMMC3PRG(V);
142 if((V&0x80) != (MMC3_cmd&0x80))
143 FixMMC3CHR(V);
144 MMC3_cmd = V;
145 break;
146
147 case 0x8001:
148 {
149 int cbase=(MMC3_cmd&0x80)<<5;
150 DRegBuf[MMC3_cmd&0x7]=V;
151 switch(MMC3_cmd&0x07)
152 {
153 case 0: V>>=1;swsetchr2((cbase^0x000),V);break;
154 case 1: V>>=1;swsetchr2((cbase^0x800),V);break;
155 case 2: swsetchr1(cbase^0x1000,V); break;
156 case 3: swsetchr1(cbase^0x1400,V); break;
157 case 4: swsetchr1(cbase^0x1800,V); break;
158 case 5: swsetchr1(cbase^0x1C00,V); break;
159 case 6: if (MMC3_cmd&0x40) swsetprg8(0xC000,V);
160 else swsetprg8(0x8000,V);
c0bf6f9f 161 X6502_Rebase();
c62d2810 162 break;
163 case 7: swsetprg8(0xA000,V);
c0bf6f9f 164 X6502_Rebase();
c62d2810 165 break;
166 }
167 }
168 break;
169
170 case 0xA000:
171 mbia=V;
172 setmirror((V&1)^1);
173 break;
174 }
175}
176
177
178DECLFW(Super24Write)
179{
180 //printf("$%04x:$%02x\n",A,V);
181 switch(A)
182 {
183 case 0x5ff0:sizer=V;
184 FixMMC3PRG(MMC3_cmd);
185 FixMMC3CHR(MMC3_cmd);
186 break;
187 case 0x5FF1:
188 bigbank=V;
189 FixMMC3PRG(MMC3_cmd);
190 break;
191 case 0x5FF2:
192 bigbank2=V;
193 FixMMC3CHR(MMC3_cmd);
194 break;
195 }
196}
197
198static void Super24Reset(void)
199{
200 SetWriteHandler(0x8000,0xBFFF,Super24hiwrite);
201 SetWriteHandler(0x5000,0x7FFF,Super24Write);
202 SetWriteHandler(0xC000,0xFFFF,Sup24IRQWrite);
203 SetReadHandler(0x8000,0xFFFF,CartBR);
204 GameHBIRQHook=Sup24_hb;
205 IRQCount=IRQLatch=IRQa=resetmode=0;
206 sizer=0x24;
207 bigbank=159;
208 bigbank2=0;
209
210 MMC3_cmd=0;
211 DRegBuf[6]=0;
212 DRegBuf[7]=1;
213
214 FixMMC3PRG(0);
215 FixMMC3CHR(0);
216}
217
218static void MrRestore(int version)
219{
220 FixMMC3PRG(MMC3_cmd);
221 FixMMC3CHR(MMC3_cmd);
222 setmirror((mbia&1)^1);
223}
224
225void Super24_Init(void)
226{
227 BoardPower=Super24Reset;
228 SetupCartCHRMapping(0x10, GameMemBlock, 8192, 1);
229 GameStateRestore=MrRestore;
230
231 AddExState(GameMemBlock, 8192, 0, "CHRR");
232 AddExState(DRegBuf, 8, 0, "DREG");
233 AddExState(&IRQCount, 4, 1, "IRQC");
234 AddExState(&IRQLatch, 4, 1, "IQL1");
235 AddExState(&IRQa, 1, 0, "IRQA");
236 AddExState(&sizer, 1, 0, "SIZA");
237 AddExState(&bigbank, 1, 0, "BIG1");
238 AddExState(&bigbank2, 1, 0, "BIG2");
239}