mirror of
https://github.com/dborth/fceugx.git
synced 2024-11-01 15:05:05 +01:00
253 lines
5.6 KiB
C
253 lines
5.6 KiB
C
/* FCE Ultra - NES/Famicom Emulator
|
|
*
|
|
* Copyright notice for this file:
|
|
* Copyright (C) 2002 Xodnizel
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include "mapinc.h"
|
|
|
|
static void AYSound(int Count);
|
|
static void AYSoundHQ(void);
|
|
static void DoAYSQ(int x);
|
|
static void DoAYSQHQ(int x);
|
|
|
|
#define sunselect mapbyte1[0]
|
|
#define sungah mapbyte1[1]
|
|
static uint8 sunindex;
|
|
|
|
static DECLFW(SUN5BWRAM)
|
|
{
|
|
if((sungah&0xC0)==0xC0)
|
|
(WRAM-0x6000)[A]=V;
|
|
}
|
|
|
|
static DECLFR(SUN5AWRAM)
|
|
{
|
|
if((sungah&0xC0)==0x40)
|
|
return X.DB;
|
|
return CartBR(A);
|
|
}
|
|
|
|
static DECLFW(Mapper69_SWL)
|
|
{
|
|
sunindex=V%14;
|
|
}
|
|
|
|
static DECLFW(Mapper69_SWH)
|
|
{
|
|
int x;
|
|
GameExpSound.Fill=AYSound;
|
|
GameExpSound.HiFill=AYSoundHQ;
|
|
if(FSettings.SndRate);
|
|
switch(sunindex)
|
|
{
|
|
case 0:
|
|
case 1:
|
|
case 8:if(FSettings.soundq>=1) DoAYSQHQ(0); else DoAYSQ(0);break;
|
|
case 2:
|
|
case 3:
|
|
case 9:if(FSettings.soundq>=1) DoAYSQHQ(1); else DoAYSQ(1);break;
|
|
case 4:
|
|
case 5:
|
|
case 10:if(FSettings.soundq>=1) DoAYSQHQ(2); else DoAYSQ(2);break;
|
|
case 7:
|
|
for(x=0;x<2;x++)
|
|
if(FSettings.soundq>=1) DoAYSQHQ(x); else DoAYSQ(x);
|
|
break;
|
|
}
|
|
MapperExRAM[sunindex]=V;
|
|
}
|
|
|
|
static DECLFW(Mapper69_write)
|
|
{
|
|
switch(A&0xE000)
|
|
{
|
|
case 0x8000:sunselect=V;break;
|
|
case 0xa000:
|
|
sunselect&=0xF;
|
|
if(sunselect<=7)
|
|
VROM_BANK1(sunselect<<10,V);
|
|
else
|
|
switch(sunselect&0x0f)
|
|
{
|
|
case 8:
|
|
sungah=V;
|
|
if(V&0x40)
|
|
{
|
|
if(V&0x80) // Select WRAM
|
|
setprg8r(0x10,0x6000,0);
|
|
}
|
|
else
|
|
setprg8(0x6000,V);
|
|
break;
|
|
case 9:ROM_BANK8(0x8000,V);break;
|
|
case 0xa:ROM_BANK8(0xa000,V);break;
|
|
case 0xb:ROM_BANK8(0xc000,V);break;
|
|
case 0xc:
|
|
switch(V&3)
|
|
{
|
|
case 0:MIRROR_SET2(1);break;
|
|
case 1:MIRROR_SET2(0);break;
|
|
case 2:onemir(0);break;
|
|
case 3:onemir(1);break;
|
|
}
|
|
break;
|
|
case 0xd:IRQa=V;X6502_IRQEnd(FCEU_IQEXT);break;
|
|
case 0xe:IRQCount&=0xFF00;IRQCount|=V;X6502_IRQEnd(FCEU_IQEXT);break;
|
|
case 0xf:IRQCount&=0x00FF;IRQCount|=V<<8;X6502_IRQEnd(FCEU_IQEXT);break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
static int32 vcount[3];
|
|
static int32 dcount[3];
|
|
static int CAYBC[3];
|
|
|
|
static void DoAYSQ(int x)
|
|
{
|
|
int32 freq=((MapperExRAM[x<<1]|((MapperExRAM[(x<<1)+1]&15)<<8))+1)<<(4+17);
|
|
int32 amp=(MapperExRAM[0x8+x]&15)<<2;
|
|
int32 start,end;
|
|
int V;
|
|
|
|
amp+=amp>>1;
|
|
|
|
start=CAYBC[x];
|
|
end=(SOUNDTS<<16)/soundtsinc;
|
|
if(end<=start) return;
|
|
CAYBC[x]=end;
|
|
|
|
if(amp)
|
|
for(V=start;V<end;V++)
|
|
{
|
|
if(dcount[x])
|
|
Wave[V>>4]+=amp;
|
|
vcount[x]-=nesincsize;
|
|
while(vcount[x]<=0)
|
|
{
|
|
dcount[x]^=1;
|
|
vcount[x]+=freq;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void DoAYSQHQ(int x)
|
|
{
|
|
int32 V;
|
|
int32 freq=((MapperExRAM[x<<1]|((MapperExRAM[(x<<1)+1]&15)<<8))+1)<<4;
|
|
int32 amp=(MapperExRAM[0x8+x]&15)<<6;
|
|
|
|
amp+=amp>>1;
|
|
|
|
if(!(MapperExRAM[0x7]&(1<<x)))
|
|
{
|
|
for(V=CAYBC[x];V<SOUNDTS;V++)
|
|
{
|
|
if(dcount[x])
|
|
WaveHi[V]+=amp;
|
|
vcount[x]--;
|
|
if(vcount[x]<=0)
|
|
{
|
|
dcount[x]^=1;
|
|
vcount[x]=freq;
|
|
}
|
|
}
|
|
}
|
|
CAYBC[x]=SOUNDTS;
|
|
}
|
|
|
|
static void AYSound(int Count)
|
|
{
|
|
int x;
|
|
DoAYSQ(0);
|
|
DoAYSQ(1);
|
|
DoAYSQ(2);
|
|
for(x=0;x<3;x++)
|
|
CAYBC[x]=Count;
|
|
}
|
|
|
|
static void AYSoundHQ(void)
|
|
{
|
|
DoAYSQHQ(0);
|
|
DoAYSQHQ(1);
|
|
DoAYSQHQ(2);
|
|
}
|
|
|
|
static void AYHiSync(int32 ts)
|
|
{
|
|
int x;
|
|
|
|
for(x=0;x<3;x++)
|
|
CAYBC[x]=ts;
|
|
}
|
|
|
|
static void FP_FASTAPASS(1) SunIRQHook(int a)
|
|
{
|
|
if(IRQa)
|
|
{
|
|
IRQCount-=a;
|
|
if(IRQCount<=0)
|
|
{X6502_IRQBegin(FCEU_IQEXT);IRQa=0;IRQCount=0xFFFF;}
|
|
}
|
|
}
|
|
|
|
void Mapper69_StateRestore(int version)
|
|
{
|
|
if(mapbyte1[1]&0x40)
|
|
{
|
|
if(mapbyte1[1]&0x80) // Select WRAM
|
|
setprg8r(0x10,0x6000,0);
|
|
}
|
|
else
|
|
setprg8(0x6000,mapbyte1[1]);
|
|
}
|
|
|
|
void Mapper69_ESI(void)
|
|
{
|
|
GameExpSound.RChange=Mapper69_ESI;
|
|
GameExpSound.HiSync=AYHiSync;
|
|
memset(dcount,0,sizeof(dcount));
|
|
memset(vcount,0,sizeof(vcount));
|
|
memset(CAYBC,0,sizeof(CAYBC));
|
|
}
|
|
|
|
void NSFAY_Init(void)
|
|
{
|
|
sunindex=0;
|
|
SetWriteHandler(0xc000,0xdfff,Mapper69_SWL);
|
|
SetWriteHandler(0xe000,0xffff,Mapper69_SWH);
|
|
Mapper69_ESI();
|
|
}
|
|
|
|
void Mapper69_init(void)
|
|
{
|
|
sunindex=0;
|
|
|
|
SetupCartPRGMapping(0x10,WRAM,8192,1);
|
|
|
|
SetWriteHandler(0x8000,0xbfff,Mapper69_write);
|
|
SetWriteHandler(0xc000,0xdfff,Mapper69_SWL);
|
|
SetWriteHandler(0xe000,0xffff,Mapper69_SWH);
|
|
SetWriteHandler(0x6000,0x7fff,SUN5BWRAM);
|
|
SetReadHandler(0x6000,0x7fff,SUN5AWRAM);
|
|
Mapper69_ESI();
|
|
MapIRQHook=SunIRQHook;
|
|
MapStateRestore=Mapper69_StateRestore;
|
|
}
|
|
|