diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC6.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC6.cs index 8f1f7d1afe..ccda43d7d2 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC6.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Boards/VRC6.cs @@ -149,6 +149,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo case 0x1002: //$9002 VRC6Sound.Write9002(value); break; + case 0x1003: //$9003 + VRC6Sound.Write9003(value); + break; case 0x2000: //$A000 VRC6Sound.WriteA000(value); diff --git a/BizHawk.Emulation/Sound/VRC6.cs b/BizHawk.Emulation/Sound/VRC6.cs index b92601cdbe..2a8ecb7171 100644 --- a/BizHawk.Emulation/Sound/VRC6.cs +++ b/BizHawk.Emulation/Sound/VRC6.cs @@ -5,6 +5,12 @@ using System.Text; namespace BizHawk.Emulation.Sound { + /* + * old VRC6 audio. + * not quite a drop in replacement for the new one. + * doesn't sound right. + */ + class VRC6 : ISoundProvider { public void DiscardSamples() { } diff --git a/BizHawk.Emulation/Sound/VRC6Alt.cs b/BizHawk.Emulation/Sound/VRC6Alt.cs index ebb17f139f..3dcda7e98e 100644 --- a/BizHawk.Emulation/Sound/VRC6Alt.cs +++ b/BizHawk.Emulation/Sound/VRC6Alt.cs @@ -8,7 +8,6 @@ namespace BizHawk.Emulation.Sound public class VRC6Alt : IDisposable { // http://wiki.nesdev.com/w/index.php/VRC6_audio - // $9003 not implemented @@ -94,18 +93,25 @@ namespace BizHawk.Emulation.Sound } } + // the two pulse channels are about the same volume as 2a03 pulse channels. + // everything is flipped, though; but that's taken care of in the classes void PulseAddDiff(int value) { dlist.Add(new Delta(sampleclock, value * 360)); } + // saw ends up being not that loud because of differences in implementation void SawAddDiff(int value) { - dlist.Add(new Delta(sampleclock, value * 180)); + dlist.Add(new Delta(sampleclock, value * 360)); } + // state + bool masterenable; + public void SyncState(Serializer ser) { ser.BeginSection("VRC6Alt"); + ser.Sync("masterenable", ref masterenable); pulse1.SyncState(ser); pulse2.SyncState(ser); saw.SyncState(ser); @@ -118,7 +124,15 @@ namespace BizHawk.Emulation.Sound public void Write9003(byte value) { - + masterenable = !value.Bit(0); + int RSHIFT = 0; + if (value.Bit(1)) + RSHIFT = 4; + if (value.Bit(2)) + RSHIFT = 8; + pulse1.SetRSHIFT(RSHIFT); + pulse2.SetRSHIFT(RSHIFT); + saw.SetRSHIFT(RSHIFT); } public void WriteA000(byte value) { pulse2.Write0(value); } @@ -131,9 +145,12 @@ namespace BizHawk.Emulation.Sound public void Clock() { - pulse1.Clock(); - pulse2.Clock(); - saw.Clock(); + if (masterenable) + { + pulse1.Clock(); + pulse2.Clock(); + saw.Clock(); + } sampleclock++; } @@ -143,22 +160,37 @@ namespace BizHawk.Emulation.Sound public Saw(Action SendDiff) { this.SendDiff = SendDiff; } // set by regs + /// rate of increment for accumulator byte A; + /// frequency. actually a reload value int F; + /// enable bool E; + /// reload shift, from $9003 + int RSHIFT; + // internal state + /// frequency counter int count; + /// accumulator byte accum; + /// saw reset counter int acount; - int value; + /// latched output, 0..31 + int output; + + public void SetRSHIFT(int RSHIFT) + { + this.RSHIFT = RSHIFT; + } void SendNew() { int newvalue = accum >> 3; - if (newvalue != value) + if (newvalue != output) { - SendDiff(value - newvalue); // intentionally flipped - value = newvalue; + SendDiff(output - newvalue); // intentionally flipped + output = newvalue; } } @@ -167,10 +199,11 @@ namespace BizHawk.Emulation.Sound ser.Sync("A", ref A); ser.Sync("F", ref F); ser.Sync("E", ref E); + ser.Sync("RSHIFT", ref RSHIFT); ser.Sync("count", ref count); ser.Sync("accum", ref accum); ser.Sync("acount", ref acount); - ser.Sync("value", ref value); + ser.Sync("output", ref output); } public void Write0(byte value) @@ -201,7 +234,7 @@ namespace BizHawk.Emulation.Sound count--; if (count <= 0) { - count = F; + count = F >> RSHIFT; acount++; if (acount % 2 == 0) { @@ -226,14 +259,29 @@ namespace BizHawk.Emulation.Sound public Pulse(Action SendDiff) { this.SendDiff = SendDiff; } // set by regs + /// volume, 0..15 int V; + /// duty comparison. forced to max when x000.7 == 1 int D; + /// frequency. actually a reload value int F; + /// enable bool E; + /// reload shift, from $9003 + int RSHIFT; + // internal state + /// frequency counter int count; + /// duty counter int duty; - int value; + /// latched output, 0..15 + int output; + + public void SetRSHIFT(int RSHIFT) + { + this.RSHIFT = RSHIFT; + } void SendNew() { @@ -242,19 +290,19 @@ namespace BizHawk.Emulation.Sound newvalue = V; else newvalue = 0; - if (newvalue != value) + if (newvalue != output) { - SendDiff(value - newvalue); // intentionally flipped - value = newvalue; + SendDiff(output - newvalue); // intentionally flipped + output = newvalue; } } void SendNewZero() { - if (0 != value) + if (0 != output) { - SendDiff(value - 0); // intentionally flipped - value = 0; + SendDiff(output - 0); // intentionally flipped + output = 0; } } @@ -264,9 +312,10 @@ namespace BizHawk.Emulation.Sound ser.Sync("D", ref D); ser.Sync("F", ref F); ser.Sync("E", ref E); + ser.Sync("RSHIFT", ref RSHIFT); ser.Sync("count", ref count); ser.Sync("duty", ref duty); - ser.Sync("value", ref value); + ser.Sync("output", ref output); } public void Write0(byte value) @@ -301,7 +350,7 @@ namespace BizHawk.Emulation.Sound count--; if (count <= 0) { - count = F; + count = F >> RSHIFT; duty--; if (duty < 0) duty += 16;