diff --git a/tests/GameBoy.Core.Tests/SaveStateTests.cs b/tests/GameBoy.Core.Tests/SaveStateTests.cs new file mode 100644 index 0000000..03da4bd --- /dev/null +++ b/tests/GameBoy.Core.Tests/SaveStateTests.cs @@ -0,0 +1,72 @@ +using Xunit; +using Xunit.Abstractions; + +namespace GameBoy.Tests +{ + public sealed class SaveStateTests + { + private readonly ITestOutputHelper output; + + public SaveStateTests(ITestOutputHelper output) + { + this.output = output; + } + + [Fact] + public void RestoreContinuesIdenticallyToUninterruptedRun() + { + byte[] rom = TestRoms.Load("cpu_instrs.gb"); + + var reference = new Emulator(rom); + for (int frame = 0; frame < 300; frame++) + reference.RunFrame(); + + byte[] snapshot = reference.SaveState(); + + for (int frame = 0; frame < 150; frame++) + reference.RunFrame(); + + var restored = new Emulator(rom); + restored.LoadState(snapshot); + for (int frame = 0; frame < 150; frame++) + restored.RunFrame(); + + output.WriteLine($"snapshot size: {snapshot.Length} bytes"); + output.WriteLine($"reference cycles: {reference.TotalCycles}, restored cycles: {restored.TotalCycles}"); + + Assert.Equal(reference.TotalCycles, restored.TotalCycles); + Assert.Equal(reference.SerialOutput, restored.SerialOutput); + Assert.Equal(reference.Framebuffer, restored.Framebuffer); + + Assert.Equal(reference.Cpu.AF, restored.Cpu.AF); + Assert.Equal(reference.Cpu.BC, restored.Cpu.BC); + Assert.Equal(reference.Cpu.DE, restored.Cpu.DE); + Assert.Equal(reference.Cpu.HL, restored.Cpu.HL); + Assert.Equal(reference.Cpu.SP, restored.Cpu.SP); + Assert.Equal(reference.Cpu.PC, restored.Cpu.PC); + } + + [Fact] + public void SnapshotTakenMidTransferSurvivesRoundTrip() + { + byte[] rom = TestRoms.Load("dmg-acid2.gb"); + + var reference = new Emulator(rom); + for (int frame = 0; frame < 120; frame++) + reference.RunFrame(); + + byte[] snapshot = reference.SaveState(); + var restored = new Emulator(rom); + restored.LoadState(snapshot); + + for (int frame = 0; frame < 90; frame++) + { + reference.RunFrame(); + restored.RunFrame(); + } + + Assert.Equal(reference.Framebuffer, restored.Framebuffer); + Assert.Equal(reference.Cpu.PC, restored.Cpu.PC); + } + } +}