From 700ac116ddac66d3342c486bf4254733178679fb Mon Sep 17 00:00:00 2001 From: beirich Date: Sun, 29 Apr 2012 18:33:21 +0000 Subject: [PATCH] ym2612: more ports processed, DAC now plays in stereo --- BizHawk.Emulation/Sound/YM2612.Channel.cs | 40 +++++++++++++++++- BizHawk.Emulation/Sound/YM2612.IO.cs | 48 ++++++++++++++++++++++ BizHawk.Emulation/Sound/YM2612.Operator.cs | 11 ++++- BizHawk.Emulation/Sound/YM2612.cs | 4 +- 4 files changed, 98 insertions(+), 5 deletions(-) diff --git a/BizHawk.Emulation/Sound/YM2612.Channel.cs b/BizHawk.Emulation/Sound/YM2612.Channel.cs index 6b636cc53c..4f66d2d38c 100644 --- a/BizHawk.Emulation/Sound/YM2612.Channel.cs +++ b/BizHawk.Emulation/Sound/YM2612.Channel.cs @@ -8,7 +8,8 @@ namespace BizHawk.Emulation.Sound { public readonly Operator[] Operators; - public int Frequency; + public int FrequencyNumber; + public int Block; public int Feedback; public int Algorithm; @@ -27,6 +28,43 @@ namespace BizHawk.Emulation.Sound Operators[1] = new Operator(); Operators[2] = new Operator(); Operators[3] = new Operator(); + + LeftOutput = true; // Revenge of Shinobi does not output DAC if these arent initialized ?? + RightOutput = true; + } + + public void WriteFrequencyLow(byte value) + { + FrequencyNumber &= 0x700; + FrequencyNumber |= value; + + // TODO maybe its 4-frequency mode + // TODO is this right, only reflect change when writing LSB? + Operators[0].FrequencyNumber = FrequencyNumber; + Operators[1].FrequencyNumber = FrequencyNumber; + Operators[2].FrequencyNumber = FrequencyNumber; + Operators[3].FrequencyNumber = FrequencyNumber; + } + + public void WriteFrequencyHigh(byte value) + { + FrequencyNumber &= 0x0FF; + FrequencyNumber |= (value & 15) << 8; + Block = (value >> 3) & 7; + } + + public void Write_Feedback_Algorithm(byte value) + { + Algorithm = value & 7; + Feedback = (value >> 3) & 7; + } + + public void Write_Stereo_LfoSensitivy(byte value) + { + FMS_FrequencyModulationSensitivity = value & 3; + AMS_AmplitudeModulationSensitivity = (value >> 3) & 7; + RightOutput = (value & 0x40) != 0; + LeftOutput = (value & 0x80) != 0; } //---------------------- diff --git a/BizHawk.Emulation/Sound/YM2612.IO.cs b/BizHawk.Emulation/Sound/YM2612.IO.cs index 2d88cb37a0..6fbd0add88 100644 --- a/BizHawk.Emulation/Sound/YM2612.IO.cs +++ b/BizHawk.Emulation/Sound/YM2612.IO.cs @@ -138,6 +138,8 @@ namespace BizHawk.Emulation.Sound case 0x70: Channels[chan].Operators[oper].Write_SR(value); break; case 0x80: Channels[chan].Operators[oper].Write_RR_SL(value); break; case 0x90: Channels[chan].Operators[oper].Write_SSGEG(value); break; + case 0xA0: + case 0xB0: WriteHighBlockP1(register, value); break; } break; @@ -169,6 +171,52 @@ namespace BizHawk.Emulation.Sound case 0x70: Channels[chan].Operators[oper].Write_SR(value); break; case 0x80: Channels[chan].Operators[oper].Write_RR_SL(value); break; case 0x90: Channels[chan].Operators[oper].Write_SSGEG(value); break; + case 0xA0: + case 0xB0: WriteHighBlockP2(register, value); break; + } + } + + void WriteHighBlockP1(byte register, byte value) + { + switch (register) + { + case 0xA0: Channels[0].WriteFrequencyLow(value); break; + case 0xA1: Channels[1].WriteFrequencyLow(value); break; + case 0xA2: Channels[2].WriteFrequencyLow(value); break; + + case 0xA4: Channels[0].WriteFrequencyHigh(value); break; + case 0xA5: Channels[1].WriteFrequencyHigh(value); break; + case 0xA6: Channels[2].WriteFrequencyHigh(value); break; + + case 0xB0: Channels[0].Write_Feedback_Algorithm(value); break; + case 0xB1: Channels[1].Write_Feedback_Algorithm(value); break; + case 0xB2: Channels[2].Write_Feedback_Algorithm(value); break; + + case 0xB4: Channels[0].Write_Stereo_LfoSensitivy(value); break; + case 0xB5: Channels[1].Write_Stereo_LfoSensitivy(value); break; + case 0xB6: Channels[2].Write_Stereo_LfoSensitivy(value); break; + } + } + + void WriteHighBlockP2(byte register, byte value) + { + switch (register) + { + case 0xA0: Channels[3].WriteFrequencyLow(value); break; + case 0xA1: Channels[4].WriteFrequencyLow(value); break; + case 0xA2: Channels[5].WriteFrequencyLow(value); break; + + case 0xA4: Channels[3].WriteFrequencyHigh(value); break; + case 0xA5: Channels[4].WriteFrequencyHigh(value); break; + case 0xA6: Channels[5].WriteFrequencyHigh(value); break; + + case 0xB0: Channels[3].Write_Feedback_Algorithm(value); break; + case 0xB1: Channels[4].Write_Feedback_Algorithm(value); break; + case 0xB2: Channels[5].Write_Feedback_Algorithm(value); break; + + case 0xB4: Channels[3].Write_Stereo_LfoSensitivy(value); break; + case 0xB5: Channels[4].Write_Stereo_LfoSensitivy(value); break; + case 0xB6: Channels[5].Write_Stereo_LfoSensitivy(value); break; } } diff --git a/BizHawk.Emulation/Sound/YM2612.Operator.cs b/BizHawk.Emulation/Sound/YM2612.Operator.cs index 046a5e968d..53f94d0f2e 100644 --- a/BizHawk.Emulation/Sound/YM2612.Operator.cs +++ b/BizHawk.Emulation/Sound/YM2612.Operator.cs @@ -21,8 +21,9 @@ namespace BizHawk.Emulation.Sound public bool AM_AmplitudeModulation; - public int Frequency; - + public int FrequencyNumber; + public int Block; + // Internal State public int PhaseCounter; @@ -65,6 +66,12 @@ namespace BizHawk.Emulation.Sound { SSG_EG = value & 15; } + + public void UpdateFrequency(int frequencyNumber, int block) + { + FrequencyNumber = frequencyNumber; + Block = block; + } } } //TODO "the shape of the waves of the envelope changes in a exponential when attacking it, and it changes in the straight line at other rates." diff --git a/BizHawk.Emulation/Sound/YM2612.cs b/BizHawk.Emulation/Sound/YM2612.cs index b6a5566b44..021c59acc4 100644 --- a/BizHawk.Emulation/Sound/YM2612.cs +++ b/BizHawk.Emulation/Sound/YM2612.cs @@ -73,8 +73,8 @@ namespace BizHawk.Emulation.Sound if (DacEnable) { short dacValue = (short)(((DacValue-80) * channelVolume) / 80); - samples[pos] += dacValue; - samples[pos + 1] += dacValue; + if (Channels[5].LeftOutput) samples[pos] += dacValue; + if (Channels[5].RightOutput) samples[pos + 1] += dacValue; } pos += 2; }