diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/APU.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/APU.cs
index 24f3adfbd9..465f71131a 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/NES/APU.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/APU.cs
@@ -9,6 +9,8 @@ using BizHawk.Emulation.Sound;
//http://wiki.nesdev.com/w/index.php/APU_Pulse
//sequencer ref: http://wiki.nesdev.com/w/index.php/APU_Frame_Counter
+//TODO - refactor length counter to be separate component
+
namespace BizHawk.Emulation.Consoles.Nintendo
{
@@ -61,6 +63,26 @@ namespace BizHawk.Emulation.Consoles.Nintendo
//misc..
int lenctr_en;
+ public void SyncState(Serializer ser)
+ {
+ ser.Sync("duty_cnt", ref duty_cnt);
+ ser.Sync("env_loop", ref env_loop);
+ ser.Sync("env_constant", ref env_constant);
+ ser.Sync("env_cnt_value", ref env_cnt_value);
+
+ ser.Sync("sweep_en", ref sweep_en);
+ ser.Sync("sweep_divider_cnt", ref sweep_divider_cnt);
+ ser.Sync("sweep_negate", ref sweep_negate);
+ ser.Sync("sweep_shiftcount", ref sweep_shiftcount);
+ ser.Sync("sweep_reload", ref sweep_reload);
+
+ ser.Sync("len_cnt", ref len_cnt);
+ ser.Sync("timer_raw_reload_value", ref timer_raw_reload_value);
+ ser.Sync("timer_reload_value", ref timer_reload_value);
+
+ ser.Sync("lenctr_en", ref lenctr_en);
+ }
+
public bool IsLenCntNonZero() { return len_cnt > 0; }
public void WriteReg(int addr, byte val)
@@ -238,6 +260,31 @@ namespace BizHawk.Emulation.Consoles.Nintendo
int env_output, env_start_flag, env_divider, env_counter;
bool noise_bit = true;
+ public void SyncState(Serializer ser)
+ {
+ ser.Sync("env_cnt_value", ref env_cnt_value);
+ ser.Sync("env_loop", ref env_loop);
+ ser.Sync("env_constant", ref env_constant);
+ ser.Sync("mode_cnt", ref mode_cnt);
+ ser.Sync("period_cnt", ref period_cnt);
+
+ ser.Sync("mode_cnt", ref mode_cnt);
+ ser.Sync("period_cnt", ref period_cnt);
+
+ ser.Sync("lenctr_en", ref lenctr_en);
+
+ ser.Sync("shift_register", ref shift_register);
+ ser.Sync("timer_counter", ref timer_counter);
+ ser.Sync("sample", ref sample);
+
+ ser.Sync("env_output", ref env_output);
+ ser.Sync("env_start_flag", ref env_start_flag);
+ ser.Sync("env_divider", ref env_divider);
+ ser.Sync("env_counter", ref env_counter);
+ ser.Sync("noise_bit", ref noise_bit);
+ }
+
+
public bool IsLenCntNonZero() { return len_cnt > 0; }
public void WriteReg(int addr, byte val)
@@ -334,7 +381,38 @@ namespace BizHawk.Emulation.Consoles.Nintendo
int linear_counter_reload, control_flag;
//reg1 (n/a)
//reg2/3
- int timer_cnt, length_counter_load, halt_flag;
+ int timer_cnt, halt_flag, len_cnt;
+
+ //misc..
+ int lenctr_en;
+ int linear_counter, timer, timer_cnt_reload;
+ int seq;
+ public int sample;
+
+ public void SyncState(Serializer ser)
+ {
+ ser.Sync("linear_counter_reload", ref linear_counter_reload);
+ ser.Sync("control_flag", ref control_flag);
+ ser.Sync("timer_cnt", ref timer_cnt);
+ ser.Sync("halt_flag", ref halt_flag);
+ ser.Sync("len_cnt", ref len_cnt);
+
+ ser.Sync("lenctr_en", ref lenctr_en);
+ ser.Sync("linear_counter", ref linear_counter);
+ ser.Sync("timer", ref timer);
+ ser.Sync("timer_cnt_reload", ref timer_cnt_reload);
+ ser.Sync("seq", ref seq);
+ ser.Sync("sample", ref sample);
+ }
+
+ public bool IsLenCntNonZero() { return len_cnt > 0; }
+
+ public void set_lenctr_en(int value)
+ {
+ lenctr_en = value;
+ //if the length counter is not enabled, then we must disable the length system in this way
+ if (lenctr_en == 0) len_cnt = 0;
+ }
public void WriteReg(int addr, byte val)
{
@@ -352,17 +430,16 @@ namespace BizHawk.Emulation.Consoles.Nintendo
case 3:
timer_cnt = (timer_cnt & 0xFF) | ((val & 0x7) << 8);
timer_cnt_reload = timer_cnt + 1;
- length_counter_load = (val>>3)&0x1F;
+ len_cnt = LENGTH_TABLE[(val >> 3) & 0x1F];
halt_flag = 1;
+
+ //allow the lenctr_en to kill the len_cnt
+ set_lenctr_en(lenctr_en);
break;
}
//Console.WriteLine("tri timer_reload_value: {0}", timer_cnt_reload);
}
- int linear_counter, timer, timer_cnt_reload;
- int seq;
- public int sample;
-
public void Run()
{
//when clocked by timer
@@ -370,7 +447,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
//except when linear counter or
//length counter is 0
- bool en = length_counter_load != 0 && linear_counter != 0;
+ bool en = len_cnt != 0 && linear_counter != 0;
//length counter and linear counter
//is clocked in frame counter.
@@ -392,6 +469,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo
public void clock_length_and_sweep()
{
+ //env_loopdoubles as "halt length counter"
+ if (len_cnt > 0)
+ len_cnt--;
}
public void clock_linear_counter()
@@ -412,6 +492,18 @@ namespace BizHawk.Emulation.Consoles.Nintendo
}
}
+ public void SyncState(Serializer ser)
+ {
+ ser.Sync("sequencer_counter", ref sequencer_counter);
+ ser.Sync("sequencer_step", ref sequencer_step);
+ ser.Sync("sequencer_mode", ref sequencer_mode);
+ ser.Sync("sequencer_irq_inhibit", ref sequencer_irq_inhibit);
+ pulse[0].SyncState(ser);
+ pulse[1].SyncState(ser);
+ triangle.SyncState(ser);
+ noise.SyncState(ser);
+ }
+
PulseUnit[] pulse = { new PulseUnit(0), new PulseUnit(1) };
TriangleUnit triangle = new TriangleUnit();
NoiseUnit noise = new NoiseUnit();
@@ -503,7 +595,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
case 0x4015:
pulse[0].set_lenctr_en(val & 1);
pulse[1].set_lenctr_en((val >> 1) & 1);
- //todo - triangle length counter?
+ triangle.set_lenctr_en((val >> 2) & 1);
noise.set_lenctr_en((val >> 3) & 1);
break;
case 0x4017:
@@ -527,7 +619,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
int dmc_irq_flag = 0; //todo
int dmc_nonzero = 0; //todo
int noise_nonzero = noise.IsLenCntNonZero() ? 1 : 0;
- int tri_nonzero = 0; //todo
+ int tri_nonzero = triangle.IsLenCntNonZero() ? 1 : 0;
int pulse1_nonzero = pulse[1].IsLenCntNonZero() ? 1 : 0;
int pulse0_nonzero = pulse[0].IsLenCntNonZero() ? 1 : 0;
int ret = (dmc_irq_flag << 7) | ((nes.irq_apu?1:0) << 6) | (dmc_nonzero << 4) | (noise_nonzero << 3) | (tri_nonzero<<2) | (pulse1_nonzero<<1) | (pulse0_nonzero);
diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs
index 05bbcb8842..887816b384 100644
--- a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs
+++ b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs
@@ -479,6 +479,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
//ser.SyncFixedString("input", ref inp, 32);
board.SyncState(ser);
ppu.SyncState(ser);
+ apu.SyncState(ser);
ser.EndSection();
}
diff --git a/BizHawk.MultiClient/BizHawk.MultiClient.csproj b/BizHawk.MultiClient/BizHawk.MultiClient.csproj
index 0c4b3e4092..38440f833b 100644
--- a/BizHawk.MultiClient/BizHawk.MultiClient.csproj
+++ b/BizHawk.MultiClient/BizHawk.MultiClient.csproj
@@ -52,6 +52,7 @@
4
x86
true
+ false