📄 apu.cpp
字号:
(((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; } 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; }}uint8 S9xGetAPUDSP (){ uint8 reg = IAPU.RAM [0xf2] & 0x7f; uint8 byte = APU.DSP [reg]; switch (reg) { 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 + -