⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 apu.cpp

📁 SFC游戏模拟器 snes9x 1.43 的原代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    case APU_P_LOW + 0x20:    case APU_P_LOW + 0x30:    case APU_P_LOW + 0x40:    case APU_P_LOW + 0x50:    case APU_P_LOW + 0x60:    case APU_P_LOW + 0x70:#ifdef DEBUGGER		if (Settings.TraceSoundDSP)			S9xTraceSoundDSP ("[%d] %d freq low: %d\n",			ICPU.Scanline, reg>>4, byte);#endif		S9xSetSoundHertz (reg >> 4, ((byte + (APU.DSP [reg + 1] << 8)) & FREQUENCY_MASK) * 8);		break;		    case APU_P_HIGH + 0x00:    case APU_P_HIGH + 0x10:    case APU_P_HIGH + 0x20:    case APU_P_HIGH + 0x30:    case APU_P_HIGH + 0x40:    case APU_P_HIGH + 0x50:    case APU_P_HIGH + 0x60:    case APU_P_HIGH + 0x70:#ifdef DEBUGGER		if (Settings.TraceSoundDSP)			S9xTraceSoundDSP ("[%d] %d freq high: %d\n",			ICPU.Scanline, reg>>4, byte);#endif		S9xSetSoundHertz (reg >> 4, 			(((byte << 8) + APU.DSP [reg - 1]) & FREQUENCY_MASK) * 8);		break;		    case APU_SRCN + 0x00:    case APU_SRCN + 0x10:    case APU_SRCN + 0x20:    case APU_SRCN + 0x30:    case APU_SRCN + 0x40:    case APU_SRCN + 0x50:    case APU_SRCN + 0x60:    case APU_SRCN + 0x70:		if (byte != APU.DSP [reg])		{#ifdef DEBUGGER			if (Settings.TraceSoundDSP)				S9xTraceSoundDSP ("[%d] %d sample number: %d\n",				ICPU.Scanline, reg>>4, byte);#endif			S9xSetSoundSample (reg >> 4, byte);		}		break;		    case APU_ADSR1 + 0x00:    case APU_ADSR1 + 0x10:    case APU_ADSR1 + 0x20:    case APU_ADSR1 + 0x30:    case APU_ADSR1 + 0x40:    case APU_ADSR1 + 0x50:    case APU_ADSR1 + 0x60:    case APU_ADSR1 + 0x70:		if (byte != APU.DSP [reg])		{#ifdef DEBUGGER			if (Settings.TraceSoundDSP)				S9xTraceSoundDSP ("[%d] %d adsr1: %02x\n",				ICPU.Scanline, reg>>4, byte);#endif			{				S9xFixEnvelope (reg >> 4, APU.DSP [reg + 2], byte, 					APU.DSP [reg + 1]);			}		}		break;		    case APU_ADSR2 + 0x00:    case APU_ADSR2 + 0x10:    case APU_ADSR2 + 0x20:    case APU_ADSR2 + 0x30:    case APU_ADSR2 + 0x40:    case APU_ADSR2 + 0x50:    case APU_ADSR2 + 0x60:    case APU_ADSR2 + 0x70:		if (byte != APU.DSP [reg])		{#ifdef DEBUGGER			if (Settings.TraceSoundDSP)				S9xTraceSoundDSP ("[%d] %d adsr2: %02x\n", 				ICPU.Scanline, reg>>4, byte);#endif			{				S9xFixEnvelope (reg >> 4, APU.DSP [reg + 1], APU.DSP [reg - 1],					byte);			}		}		break;		    case APU_GAIN + 0x00:    case APU_GAIN + 0x10:    case APU_GAIN + 0x20:    case APU_GAIN + 0x30:    case APU_GAIN + 0x40:    case APU_GAIN + 0x50:    case APU_GAIN + 0x60:    case APU_GAIN + 0x70:		if (byte != APU.DSP [reg])		{#ifdef DEBUGGER			if (Settings.TraceSoundDSP)				S9xTraceSoundDSP ("[%d] %d gain: %02x\n",				ICPU.Scanline, reg>>4, byte);#endif			{				S9xFixEnvelope (reg >> 4, byte, APU.DSP [reg - 2],					APU.DSP [reg - 1]);			}		}		break;		    case APU_ENVX + 0x00:    case APU_ENVX + 0x10:    case APU_ENVX + 0x20:    case APU_ENVX + 0x30:    case APU_ENVX + 0x40:    case APU_ENVX + 0x50:    case APU_ENVX + 0x60:    case APU_ENVX + 0x70:		break;		    case APU_OUTX + 0x00:    case APU_OUTX + 0x10:    case APU_OUTX + 0x20:    case APU_OUTX + 0x30:    case APU_OUTX + 0x40:    case APU_OUTX + 0x50:    case APU_OUTX + 0x60:    case APU_OUTX + 0x70:		break;		    case APU_DIR:#ifdef DEBUGGER		if (Settings.TraceSoundDSP)			S9xTraceSoundDSP ("[%d] Sample directory to: %02x\n",			ICPU.Scanline, byte);#endif		break;		    case APU_PMON:		if (byte != APU.DSP [APU_PMON])		{#ifdef DEBUGGER			if (Settings.TraceSoundDSP)			{				S9xTraceSoundDSP ("[%d] FreqMod:", ICPU.Scanline);				uint8 mask = 1;				for (int c = 0; c < 8; c++, mask <<= 1)				{					if (byte & mask)					{						if (APU.DSP [reg] & mask)							S9xTraceSoundDSP ("%d", c);						else							S9xTraceSoundDSP ("%d(on),", c);					}					else					{						if (APU.DSP [reg] & mask)							S9xTraceSoundDSP ("%d(off),", c);					}				}				S9xTraceSoundDSP ("\n");			}#endif			S9xSetFrequencyModulationEnable (byte);		}		break;		    case APU_EON:		if (byte != APU.DSP [APU_EON])		{#ifdef DEBUGGER			if (Settings.TraceSoundDSP)			{				S9xTraceSoundDSP ("[%d] Echo:", ICPU.Scanline);				uint8 mask = 1;				for (int c = 0; c < 8; c++, mask <<= 1)				{					if (byte & mask)					{						if (APU.DSP [reg] & mask)							S9xTraceSoundDSP ("%d", c);						else							S9xTraceSoundDSP ("%d(on),", c);					}					else					{						if (APU.DSP [reg] & mask)							S9xTraceSoundDSP ("%d(off),", c);					}				}				S9xTraceSoundDSP ("\n");			}#endif			S9xSetEchoEnable (byte);		}		break;		    case APU_EFB:		S9xSetEchoFeedback ((signed char) byte);		break;		    case APU_ESA:		break;		    case APU_EDL:		S9xSetEchoDelay (byte & 0xf);		break;		    case APU_C0:    case APU_C1:    case APU_C2:    case APU_C3:    case APU_C4:    case APU_C5:    case APU_C6:    case APU_C7:		S9xSetFilterCoefficient (reg >> 4, (signed char) byte);		break;    default:		// XXX		//printf ("Write %02x to unknown APU register %02x\n", byte, reg);		break;    }		KeyOnPrev|=KeyOn;	KeyOn=0;	    if (reg < 0x80)		APU.DSP [reg] = byte;}void S9xFixEnvelope (int channel, uint8 gain, uint8 adsr1, uint8 adsr2){    if (adsr1 & 0x80)    {		// ADSR mode		static unsigned long AttackRate [16] = {			4100, 2600, 1500, 1000, 640, 380, 260, 160,				96, 64, 40, 24, 16, 10, 6, 1		};		static unsigned long DecayRate [8] = {			1200, 740, 440, 290, 180, 110, 74, 37		};		static unsigned long SustainRate [32] = {			~0, 38000, 28000, 24000, 19000, 14000, 12000, 9400,				7100, 5900, 4700, 3500, 2900, 2400, 1800, 1500,				1200, 880, 740, 590, 440, 370, 290, 220,				180, 150, 110, 92, 74, 55, 37, 18		};		// XXX: can DSP be switched to ADSR mode directly from GAIN/INCREASE/		// DECREASE mode? And if so, what stage of the sequence does it start		// at?		if (S9xSetSoundMode (channel, MODE_ADSR))		{			// Hack for ROMs that use a very short attack rate, key on a 			// channel, then switch to decay mode. e.g. Final Fantasy II.						int attack = AttackRate [adsr1 & 0xf];						if (attack == 1 && (!Settings.SoundSync#ifdef __WIN32__                || Settings.SoundDriver != WIN_SNES9X_DIRECT_SOUND_DRIVER#endif                ))				attack = 0;						S9xSetSoundADSR (channel, attack,				DecayRate [(adsr1 >> 4) & 7],				SustainRate [adsr2 & 0x1f],				(adsr2 >> 5) & 7, 8);		}    }    else    {		// Gain mode		if ((gain & 0x80) == 0)		{			if (S9xSetSoundMode (channel, MODE_GAIN))			{				S9xSetEnvelopeRate (channel, 0, 0, gain & 0x7f);				S9xSetEnvelopeHeight (channel, gain & 0x7f);			}		}		else		{			static unsigned long IncreaseRate [32] = {				~0, 4100, 3100, 2600, 2000, 1500, 1300, 1000,					770, 640, 510, 380, 320, 260, 190, 160,					130, 96, 80, 64, 48, 40, 32, 24,					20, 16, 12, 10, 8, 6, 4, 2			};			static unsigned long DecreaseRateExp [32] = {				~0, 38000, 28000, 24000, 19000, 14000, 12000, 9400,					7100, 5900, 4700, 3500, 2900, 2400, 1800, 1500,					1200, 880, 740, 590, 440, 370, 290, 220,					180, 150, 110, 92, 74, 55, 37, 18			};			if (gain & 0x40)			{				// Increase mode				if (S9xSetSoundMode (channel, (gain & 0x20) ?MODE_INCREASE_BENT_LINE :				MODE_INCREASE_LINEAR))				{					S9xSetEnvelopeRate (channel, IncreaseRate [gain & 0x1f],						1, 127);				}			}			else			{				uint32 rate = (gain & 0x20) ? DecreaseRateExp [gain & 0x1f] / 2 :			IncreaseRate [gain & 0x1f];			int mode = (gain & 0x20) ? MODE_DECREASE_EXPONENTIAL				: MODE_DECREASE_LINEAR;						if (S9xSetSoundMode (channel, mode))				S9xSetEnvelopeRate (channel, rate, -1, 0);			}		}    }}void S9xSetAPUControl (uint8 byte){	//if (byte & 0x40)	//printf ("*** Special SPC700 timing enabled\n");    if ((byte & 1) != 0 && !APU.TimerEnabled [0])    {		APU.Timer [0] = 0;		IAPU.RAM [0xfd] = 0;		if ((APU.TimerTarget [0] = IAPU.RAM [0xfa]) == 0)			APU.TimerTarget [0] = 0x100;    }    if ((byte & 2) != 0 && !APU.TimerEnabled [1])    {		APU.Timer [1] = 0;		IAPU.RAM [0xfe] = 0;		if ((APU.TimerTarget [1] = IAPU.RAM [0xfb]) == 0)			APU.TimerTarget [1] = 0x100;    }    if ((byte & 4) != 0 && !APU.TimerEnabled [2])    {		APU.Timer [2] = 0;		IAPU.RAM [0xff] = 0;		if ((APU.TimerTarget [2] = IAPU.RAM [0xfc]) == 0)			APU.TimerTarget [2] = 0x100;    }    APU.TimerEnabled [0] = byte & 1;    APU.TimerEnabled [1] = (byte & 2) >> 1;    APU.TimerEnabled [2] = (byte & 4) >> 2;	    if (byte & 0x10)		IAPU.RAM [0xF4] = IAPU.RAM [0xF5] = 0;	    if (byte & 0x20)		IAPU.RAM [0xF6] = IAPU.RAM [0xF7] = 0;	    if (byte & 0x80)    {		if (!APU.ShowROM)		{			memmove (&IAPU.RAM [0xffc0], APUROM, sizeof (APUROM));			APU.ShowROM = TRUE;		}    }    else    {		if (APU.ShowROM)		{			APU.ShowROM = FALSE;			memmove (&IAPU.RAM [0xffc0], APU.ExtraRAM, sizeof (APUROM));		}    }    IAPU.RAM [0xf1] = byte;}void S9xSetAPUTimer (uint16 Address, uint8 byte){    IAPU.RAM [Address] = byte;	    switch (Address)    {    case 0xfa:		if ((APU.TimerTarget [0] = IAPU.RAM [0xfa]) == 0)			APU.TimerTarget [0] = 0x100;		APU.TimerValueWritten [0] = TRUE;		break;    case 0xfb:		if ((APU.TimerTarget [1] = IAPU.RAM [0xfb]) == 0)			APU.TimerTarget [1] = 0x100;		APU.TimerValueWritten [1] = TRUE;		break;    case 0xfc:		if ((APU.TimerTarget [2] = IAPU.RAM [0xfc]) == 0)			APU.TimerTarget [2] = 0x100;		APU.TimerValueWritten [2] = TRUE;		break;    }}void S9xUpdateAPUTimer (void){	while (CPU.Cycles * 10000L >= IAPU.NextAPUTimerPos)	//if (CPU.Cycles * 10000L >= IAPU.NextAPUTimerPos)	{		//APU_EXECUTE();				IAPU.NextAPUTimerPos += SNES_APUTIMER2_CYCLEx10000;						if (APU.TimerEnabled [2])		{			APU.Timer [2] ++;			if (APU.Timer [2] >= APU.TimerTarget [2])			{			    IAPU.RAM [0xff] = (IAPU.RAM [0xff] + 1) & 0xf;			    APU.Timer [2] = 0;			#ifdef SPC700_SHUTDOWN					    IAPU.WaitCounter++;			    IAPU.APUExecuting = TRUE;			#endif					}		}		if (++IAPU.APUTimerCounter == 8)		{			IAPU.APUTimerCounter = 0;						if (APU.TimerEnabled [0])			{			    APU.Timer [0]++;			    if (APU.Timer [0] >= APU.TimerTarget [0])			    {					IAPU.RAM [0xfd] = (IAPU.RAM [0xfd] + 1) & 0xf;					APU.Timer [0] = 0;				#ifdef SPC700_SHUTDOWN							IAPU.WaitCounter++;					IAPU.APUExecuting = TRUE;				#endif		    			    }			}			if (APU.TimerEnabled [1])			{			    APU.Timer [1]++;			    if (APU.Timer [1] >= APU.TimerTarget [1])			    {					IAPU.RAM [0xfe] = (IAPU.RAM [0xfe] + 1) & 0xf;					APU.Timer [1] = 0;				#ifdef SPC700_SHUTDOWN							IAPU.WaitCounter++;					IAPU.APUExecuting = TRUE;				#endif		    			    }			}		}	}}uint8 S9xGetAPUDSP (){    uint8 reg = IAPU.RAM [0xf2] & 0x7f;    uint8 byte = APU.DSP [reg];	    switch (reg)    {    case APU_KON:		break;    case APU_KOFF:		break;    case APU_OUTX + 0x00:    case APU_OUTX + 0x10:    case APU_OUTX + 0x20:    case APU_OUTX + 0x30:    case APU_OUTX + 0x40:    case APU_OUTX + 0x50:    case APU_OUTX + 0x60:    case APU_OUTX + 0x70:		if (SoundData.channels [reg >> 4].state == SOUND_SILENT)			return (0);		return ((SoundData.channels [reg >> 4].sample >> 8) |			(SoundData.channels [reg >> 4].sample & 0xff));		    case APU_ENVX + 0x00:    case APU_ENVX + 0x10:    case APU_ENVX + 0x20:    case APU_ENVX + 0x30:    case APU_ENVX + 0x40:    case APU_ENVX + 0x50:    case APU_ENVX + 0x60:    case APU_ENVX + 0x70:		return ((uint8) S9xGetEnvelopeHeight (reg >> 4));		    case APU_ENDX:		// To fix speech in Magical Drop 2 6/11/00		//	APU.DSP [APU_ENDX] = 0;		break;    default:		break;    }    return (byte);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -