1 /* FCE Ultra - NES/Famicom Emulator
3 * Copyright notice for this file:
4 * Copyright (C) 2002 Xodnizel
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.
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.
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
23 static uint16 IRQCount;
26 static uint8 WRAM[8192];
27 static uint8 IRAM[128];
31 return(WRAM[A-0x6000]);
39 void Mapper19_ESI(void);
41 static uint8 NTAPage[4];
47 static void NamcoSound(int Count);
48 static void NamcoSoundHack(void);
49 static void DoNamcoSound(int32 *Wave, int Count);
50 static void DoNamcoSoundHQ(void);
51 static void SyncHQ(int32 ts);
53 static int is210; /* Lesser mapper. */
58 static SFORMAT N106_StateRegs[]={
65 static void SyncPRG(void)
67 setprg8(0x8000,PRG[0]);
68 setprg8(0xa000,PRG[1]);
69 setprg8(0xc000,PRG[2]);
73 static void FP_FASTAPASS(1) NamcoIRQHook(int a)
80 X6502_IRQBegin(FCEU_IQEXT);
82 IRQCount=0x7FFF; //7FFF;
87 static DECLFR(Namco_Read4800)
89 uint8 ret=IRAM[dopol&0x7f];
90 /* Maybe I should call NamcoSoundHack() here? */
91 #ifdef FCEUDEF_DEBUGGER
95 dopol=(dopol&0x80)|((dopol+1)&0x7f);
99 static DECLFR(Namco_Read5000)
104 static DECLFR(Namco_Read5800)
109 static void FASTAPASS(2) DoNTARAMROM(int w, uint8 V)
113 setntamem(NTARAM+((V&1)<<10), 1, w);
117 setntamem(CHRptr[0]+(V<<10), 0, w);
121 static void FixNTAR(void)
125 DoNTARAMROM(x,NTAPage[x]);
128 static void FASTAPASS(2) DoCHRRAMROM(int x, uint8 V)
131 if(!is210 && !((gorfus>>((x>>2)+6))&1) && (V>=0xE0))
133 // printf("BLAHAHA: %d, %02x\n",x,V);
134 //setchr1r(0x10,x<<10,V&7);
140 static void FixCRR(void)
144 DoCHRRAMROM(x,CHR[x]);
147 static DECLFW(Mapper19C0D8_write)
149 DoNTARAMROM((A-0xC000)>>11,V);
152 static uint32 FreqCache[8];
153 static uint32 EnvCache[8];
154 static uint32 LengthCache[8];
156 static void FixCache(int a,int V)
161 case 0x00:FreqCache[w]&=~0x000000FF;FreqCache[w]|=V;break;
162 case 0x02:FreqCache[w]&=~0x0000FF00;FreqCache[w]|=V<<8;break;
163 case 0x04:FreqCache[w]&=~0x00030000;FreqCache[w]|=(V&3)<<16;
164 LengthCache[w]=(8-((V>>2)&7))<<2;
166 case 0x07:EnvCache[w]=(double)(V&0xF)*576716;break;
170 static DECLFW(Mapper19_write)
173 if(A>=0x8000 && A<=0xb800)
174 DoCHRRAMROM((A-0x8000)>>11,V);
180 if(FSettings.SndRate)
183 GameExpSound.Fill=NamcoSound;
184 GameExpSound.HiFill=DoNamcoSoundHQ;
185 GameExpSound.HiSync=SyncHQ;
191 dopol=(dopol&0x80)|((dopol+1)&0x7f);
196 IRQCount&=0xFF00;IRQCount|=V;X6502_IRQEnd(FCEU_IQEXT);break;
198 IRQCount&=0x00ff;IRQCount|=(V&0x7F)<<8;
200 X6502_IRQEnd(FCEU_IQEXT);
222 static void NamcoSoundHack(void)
225 if(FSettings.soundq>=1)
230 z=((SOUNDTS<<16)/soundtsinc)>>4;
232 if(a) DoNamcoSound(&Wave[dwave], a);
236 static void NamcoSound(int Count)
239 z=((SOUNDTS<<16)/soundtsinc)>>4;
241 if(a) DoNamcoSound(&Wave[dwave], a);
245 static uint32 PlayIndex[8];
246 static int32 vcount[8];
249 #define TOINDEX (16+1)
252 static void SyncHQ(int32 ts)
266 static INLINE uint32 FetchDuff(uint32 P, uint32 envelope)
269 duff=IRAM[((IRAM[0x46+(P<<3)]+(PlayIndex[P]>>TOINDEX))&0xFF)>>1];
270 if((IRAM[0x46+(P<<3)]+(PlayIndex[P]>>TOINDEX))&1)
273 duff=(duff*envelope)>>16;
277 static void DoNamcoSoundHQ(void)
280 int32 cyclesuck=(((IRAM[0x7F]>>4)&7)+1)*15;
282 for(P=7;P>=(7-((IRAM[0x7F]>>4)&7));P--)
284 if((IRAM[0x44+(P<<3)]&0xE0) && (IRAM[0x47+(P<<3)]&0xF))
288 uint32 duff2,lengo,envelope;
292 envelope=EnvCache[P];
293 lengo=LengthCache[P];
295 duff2=FetchDuff(P,envelope);
296 for(V=CVBC<<1;V<SOUNDTS<<1;V++)
302 while((PlayIndex[P]>>TOINDEX)>=lengo) PlayIndex[P]-=lengo<<TOINDEX;
303 duff2=FetchDuff(P,envelope);
315 static void DoNamcoSound(int32 *Wave, int Count)
318 for(P=7;P>=7-((IRAM[0x7F]>>4)&7);P--)
320 if((IRAM[0x44+(P<<3)]&0xE0) && (IRAM[0x47+(P<<3)]&0xF))
325 uint32 duff,duff2,lengo,envelope;
329 envelope=EnvCache[P];
330 lengo=LengthCache[P];
332 if(!freq) {/*printf("Ack");*/ continue;}
335 int c=((IRAM[0x7F]>>4)&7)+1;
336 inc=(long double)(FSettings.SndRate<<15)/((long double)freq*21477272/((long double)0x400000*c*45));
339 duff=IRAM[(((IRAM[0x46+(P<<3)]+PlayIndex[P])&0xFF)>>1)];
340 if((IRAM[0x46+(P<<3)]+PlayIndex[P])&1)
343 duff2=(duff*envelope)>>19;
344 for(V=0;V<Count*16;V++)
349 if(PlayIndex[P]>=lengo)
352 duff=IRAM[(((IRAM[0x46+(P<<3)]+PlayIndex[P])&0xFF)>>1)];
353 if((IRAM[0x46+(P<<3)]+PlayIndex[P])&1)
356 duff2=(duff*envelope)>>19;
366 static void Mapper19_StateRestore(int version)
372 for(x=0x40;x<0x80;x++)
376 static void M19SC(void)
378 if(FSettings.SndRate)
382 void Mapper19_ESI(void)
384 GameExpSound.RChange=M19SC;
385 memset(vcount,0,sizeof(vcount));
386 memset(PlayIndex,0,sizeof(PlayIndex));
390 void NSFN106_Init(void)
392 SetWriteHandler(0xf800,0xffff,Mapper19_write);
393 SetWriteHandler(0x4800,0x4fff,Mapper19_write);
394 SetReadHandler(0x4800,0x4fff,Namco_Read4800);
398 static int battery=0;
400 static void N106_Power(void)
403 SetReadHandler(0x8000,0xFFFF,CartBR);
404 SetWriteHandler(0x8000,0xffff,Mapper19_write);
405 SetWriteHandler(0x4020,0x5fff,Mapper19_write);
408 SetWriteHandler(0xc000,0xdfff,Mapper19C0D8_write);
409 SetReadHandler(0x4800,0x4fff,Namco_Read4800);
410 SetReadHandler(0x5000,0x57ff,Namco_Read5000);
411 SetReadHandler(0x5800,0x5fff,Namco_Read5800);
412 NTAPage[0]=NTAPage[1]=NTAPage[2]=NTAPage[3]=0xFF;
416 SetReadHandler(0x6000,0x7FFF,AWRAM);
417 SetWriteHandler(0x6000,0x7FFF,BWRAM);
418 FCEU_CheatAddRAM(8,0x6000,WRAM);
426 FCEU_dwmemset(WRAM,0,8192);
427 FCEU_dwmemset(IRAM,0,128);
429 for(x=0x40;x<0x80;x++)
433 void Mapper19_Init(CartInfo *info)
436 battery=info->battery;
437 info->Power=N106_Power;
439 MapIRQHook=NamcoIRQHook;
440 GameStateRestore=Mapper19_StateRestore;
441 GameExpSound.RChange=M19SC;
443 if(FSettings.SndRate)
446 AddExState(WRAM, 8192, 0, "WRAM");
447 AddExState(IRAM, 128, 0, "IRAM");
448 AddExState(N106_StateRegs, ~0, 0, 0);
452 info->SaveGame[0]=WRAM;
453 info->SaveGameLen[0]=8192;
454 info->SaveGame[1]=IRAM;
455 info->SaveGameLen[1]=128;
459 static void Mapper210_StateRestore(int version)
465 void Mapper210_Init(CartInfo *info)
468 GameStateRestore=Mapper210_StateRestore;
469 info->Power=N106_Power;
470 AddExState(WRAM, 8192, 0, "WRAM");
471 AddExState(N106_StateRegs, ~0, 0, 0);