mapper fixes for ncpu, debug is broken atm
[fceu.git] / mappers / 19.c
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
23 #define dopol mapbyte1[0]
24 #define gorfus mapbyte1[1]
25 #define gorko mapbyte1[2]
26
27 static void NamcoSound(int Count);
28 static void NamcoSoundHack(void);
29
30 static int32 inc;
31 void FP_FASTAPASS(1) NamcoIRQHook(int a)
32 {
33   if(IRQa)
34   {
35    IRQCount+=a;
36    if(IRQCount>=0x7fff)
37    {
38     X6502_IRQBegin(FCEU_IQEXT);
39     IRQa=0;
40     IRQCount=0x7fff;
41    }
42   }
43 }
44
45 DECLFR(Namco_Read4800)
46 {
47         uint8 ret=MapperExRAM[dopol&0x7f];
48         if(dopol&0x80)
49          dopol=(dopol&0x80)|((dopol+1)&0x7f);
50         return ret;
51 }
52
53 DECLFR(Namco_Read5000)
54 {
55  return(IRQCount);
56 }
57
58 DECLFR(Namco_Read5800)
59 {
60  return(IRQCount>>8);
61 }
62
63 static void FASTAPASS(2) DoNTARAMROM(int w, uint8 V)
64 {
65         mapbyte2[w]=V;
66         //if(V>=0xE0)
67         // setntamem(NTARAM+((V&1)<<10), 1, w);
68         if((V>=0xE0)) // || ((gorko>>(6+(w>>1)))&1) )
69          setntamem(NTARAM+((V&1)<<10), 1, w);
70         else
71         {
72          V&=CHRmask1[0];
73          setntamem(VROM+(V<<10), 0, w);
74         }
75 //      else
76 //       setntamem(NTARAM+((V&1)<<10), 1, w);
77 }
78
79 static void FixNTAR(void)
80 {
81  int x;
82
83  for(x=0;x<4;x++)
84   DoNTARAMROM(x,mapbyte2[x]);
85 }
86
87 static void FASTAPASS(2) DoCHRRAMROM(int x, uint8 V)
88 {
89          mapbyte3[x]=V;
90          if(!((gorfus>>((x>>2)+6))&1) && (V>=0xE0))
91           VRAM_BANK1(x<<10,V&7);
92          else
93           VROM_BANK1(x<<10,V);
94 }
95
96 static void FixCRR(void)
97 {
98  int x;
99  for(x=0;x<8;x++)
100   DoCHRRAMROM(x,mapbyte3[x]);
101 }
102
103 static DECLFW(Mapper19_write)
104 {
105         A&=0xF800;
106
107         if(A>=0x8000 && A<=0xb800)
108          DoCHRRAMROM((A-0x8000)>>11,V);
109         else if(A>=0xC000 && A<=0xd800)
110          DoNTARAMROM((A-0xC000)>>11,V);
111         else switch(A)
112         {
113          case 0x4800:
114                    if(dopol&0x40)
115                    {
116                     if(FSettings.SndRate)
117                     {
118                      NamcoSoundHack();
119                      GameExpSound.Fill=NamcoSound;
120                     }
121                    }
122                    MapperExRAM[dopol&0x7f]=V;
123                    if(dopol&0x80)
124                     dopol=(dopol&0x80)|((dopol+1)&0x7f);
125                    break;
126
127         case 0xf800: dopol=V;break;
128         case 0x5000: IRQCount&=0xFF00;IRQCount|=V;X6502_IRQEnd(FCEU_IQEXT);break;
129         case 0x5800: IRQCount&=0x00ff;IRQCount|=(V&0x7F)<<8;
130                      IRQa=V&0x80;
131                      X6502_IRQEnd(FCEU_IQEXT);
132                      break;
133
134         case 0xE000:gorko=V&0xC0;
135                     //FixNTAR();
136                     ROM_BANK8(0x8000,V);
137                     X6502_Rebase();
138                     break;
139         case 0xE800:gorfus=V&0xC0;
140                     FixCRR();
141                     ROM_BANK8(0xA000,V);
142                     X6502_Rebase();
143                     break;
144         case 0xF000:
145                     ROM_BANK8(0xC000,V);
146                     X6502_Rebase();
147                     break;
148         }
149 }
150
151 static int dwave=0;
152 static void DoNamcoSound(uint32 *Wave, int Count);
153
154 static void NamcoSoundHack(void)
155 {
156  int32 z,a;
157
158  z=((timestamp<<16)/soundtsinc)>>4;
159  a=z-dwave;
160  if(a)
161   DoNamcoSound(&Wave[dwave], a);
162  dwave+=a;
163 }
164
165 static void NamcoSound(int Count)
166 {
167  int32 z,a;
168
169  z=((timestamp<<16)/soundtsinc)>>4;
170  a=z-dwave;
171  if(a)
172    DoNamcoSound(&Wave[dwave], a);
173  dwave=0;
174 }
175
176 static uint8 PlayIndex[8];
177 static int32 vcount[8];
178
179 static void DoNamcoSound(uint32 *Wave, int Count)
180 {
181         int P,V;
182
183
184       //FCEU_DispMessage("%d",MapperExRAM[0x7F]>>4);
185       for(P=7;P>=7-((MapperExRAM[0x7F]>>4)&7);P--)
186       {
187        if((MapperExRAM[0x44+(P<<3)]&0xE0) && (MapperExRAM[0x47+(P<<3)]&0xF))
188        {
189         uint32 freq;
190         int32 vco;
191         uint32 duff,duff2,lengo,envelope;
192         //uint64 ta;
193
194         vco=vcount[P];
195         freq=MapperExRAM[0x40+(P<<3)];
196         freq|=MapperExRAM[0x42+(P<<3)]<<8;
197         freq|=(MapperExRAM[0x44+(P<<3)]&3)<<16;
198
199         if(!freq) continue;
200
201         {
202          int c=((MapperExRAM[0x7F]>>4)&7)+1;
203
204          inc=(long double)(FSettings.SndRate<<15)/((long double)freq*
205                 21477272/((long double)0x400000*c*45));
206         }
207
208         envelope=((MapperExRAM[0x47+(P<<3)]&0xF)<<18)/15;
209         duff=MapperExRAM[(((MapperExRAM[0x46+(P<<3)]+PlayIndex[P])>>1)&0xFF)];
210         if((MapperExRAM[0x46+(P<<3)]+PlayIndex[P])&1)
211          duff>>=4;
212         duff&=0xF;
213         duff2=(duff*envelope)>>14;
214
215         lengo=((8-((MapperExRAM[0x44+(P<<3)]>>2)&7)))<<2;
216         for(V=0;V<Count OVERSAMPLE;V++)
217         {
218          if(vco>=inc)
219          {
220           PlayIndex[P]++;
221           if(PlayIndex[P]>=lengo)
222            PlayIndex[P]=0;
223           vco-=inc;
224           duff=MapperExRAM[(((MapperExRAM[0x46+(P<<3)]+PlayIndex[P])&0xFF)>>1)];
225           if((MapperExRAM[0x46+(P<<3)]+PlayIndex[P])&1)
226            duff>>=4;
227           duff&=0xF;
228           duff2=(duff*envelope)>>14;
229          }
230           Wave[V>>4]+=duff2;
231           vco+=0x8000;
232         }
233         vcount[P]=vco;
234        }
235       }
236 }
237
238 static void Mapper19_StateRestore(int version)
239 {
240  FixNTAR();
241  if(version>=80)
242   FixCRR();
243 }
244
245 static void M19SC(void)
246 {
247  if(FSettings.SndRate)
248   Mapper19_ESI();
249 }
250
251 void Mapper19_ESI(void)
252 {
253   GameExpSound.RChange=M19SC;
254   SetWriteHandler(0xf800,0xffff,Mapper19_write);
255   SetWriteHandler(0x4800,0x4fff,Mapper19_write);
256   SetReadHandler(0x4800,0x4fff,Namco_Read4800);
257 }
258
259 void Mapper19_init(void)
260 {
261         if(!Mirroring)
262         {
263          DoNTARAMROM(0,0xE0);
264          DoNTARAMROM(1,0xE0);
265          DoNTARAMROM(2,0xE1);
266          DoNTARAMROM(3,0xE1);
267         }
268         else
269         {
270          DoNTARAMROM(0,0xE0);
271          DoNTARAMROM(2,0xE0);
272          DoNTARAMROM(1,0xE1);
273          DoNTARAMROM(3,0xE1);
274         }
275         VROM_BANK8(~0);
276         SetWriteHandler(0x8000,0xffff,Mapper19_write);
277         SetWriteHandler(0x4020,0x5fff,Mapper19_write);
278         SetReadHandler(0x4800,0x4fff,Namco_Read4800);
279         SetReadHandler(0x5000,0x57ff,Namco_Read5000);
280         SetReadHandler(0x5800,0x5fff,Namco_Read5800);
281
282         MapIRQHook=NamcoIRQHook;
283         MapStateRestore=Mapper19_StateRestore;
284         GameExpSound.RChange=M19SC;
285         if(FSettings.SndRate)
286          Mapper19_ESI();
287         gorfus=0xFF;
288 }
289