diff --git a/src/Chip8.Replay/BenchmarkResult.cs b/src/Chip8.Replay/BenchmarkResult.cs new file mode 100644 index 0000000..5a744e4 --- /dev/null +++ b/src/Chip8.Replay/BenchmarkResult.cs @@ -0,0 +1,58 @@ +using System.Globalization; +using System.Text; + +namespace Chip8.Replay; + +public sealed class BenchmarkResult +{ + public string romName { get; } + public int stepsExecuted { get; } + public int framesExecuted { get; } + public double elapsedMilliseconds { get; } + public ulong framebufferHash { get; } + public bool exited { get; } + + public BenchmarkResult( + string romName, + int stepsExecuted, + int framesExecuted, + double elapsedMilliseconds, + ulong framebufferHash, + bool exited) + { + this.romName = romName; + this.stepsExecuted = stepsExecuted; + this.framesExecuted = framesExecuted; + this.elapsedMilliseconds = elapsedMilliseconds; + this.framebufferHash = framebufferHash; + this.exited = exited; + } + + public double elapsedSeconds => elapsedMilliseconds / 1000.0; + + public double instructionsPerSecond => + elapsedMilliseconds > 0 ? stepsExecuted / elapsedSeconds : double.NaN; + + public double framesPerSecond => + elapsedMilliseconds > 0 ? framesExecuted / elapsedSeconds : double.NaN; + + public string format() + { + var builder = new StringBuilder(); + builder.Append(romName).Append(": "); + builder.Append(stepsExecuted).Append(" steps / "); + builder.Append(framesExecuted).Append(" frames in "); + builder.Append(elapsedMilliseconds.ToString("F2", CultureInfo.InvariantCulture)).Append(" ms"); + if (elapsedMilliseconds > 0) + { + builder.Append(" ("); + builder.Append((instructionsPerSecond / 1_000_000.0).ToString("F2", CultureInfo.InvariantCulture)); + builder.Append(" Mips, "); + builder.Append(framesPerSecond.ToString("F0", CultureInfo.InvariantCulture)); + builder.Append(" fps)"); + } + return builder.ToString(); + } + + public override string ToString() => format(); +} diff --git a/src/Chip8.Replay/RomExpectation.cs b/src/Chip8.Replay/RomExpectation.cs new file mode 100644 index 0000000..c8f6c56 --- /dev/null +++ b/src/Chip8.Replay/RomExpectation.cs @@ -0,0 +1,47 @@ +using Chip8.Core; + +namespace Chip8.Replay; + +public sealed class RomExpectation +{ + public string romName { get; } + public Platform platform { get; } + public Quirks quirks { get; } + public int cycles { get; } + public int instructionsPerFrame { get; } + public int randomSeed { get; } + public int minLitPixels { get; } + public int maxLitPixels { get; } + public ulong? framebufferHash { get; } + public string description { get; } + + public RomExpectation( + string romName, + Platform platform, + Quirks quirks, + int cycles, + int minLitPixels, + int maxLitPixels, + int instructionsPerFrame = 11, + int randomSeed = 1, + ulong? framebufferHash = null, + string description = "") + { + this.romName = romName; + this.platform = platform; + this.quirks = quirks; + this.cycles = cycles; + this.minLitPixels = minLitPixels; + this.maxLitPixels = maxLitPixels; + this.instructionsPerFrame = instructionsPerFrame; + this.randomSeed = randomSeed; + this.framebufferHash = framebufferHash; + this.description = description; + } + + public bool litPixelsInRange(int litPixels) => litPixels >= minLitPixels && litPixels <= maxLitPixels; + + public RomExpectation withHash(ulong hash) => new RomExpectation( + romName, platform, quirks, cycles, minLitPixels, maxLitPixels, + instructionsPerFrame, randomSeed, hash, description); +} diff --git a/src/Chip8.Replay/TestRomResult.cs b/src/Chip8.Replay/TestRomResult.cs new file mode 100644 index 0000000..60d19b3 --- /dev/null +++ b/src/Chip8.Replay/TestRomResult.cs @@ -0,0 +1,59 @@ +using System.Text; + +namespace Chip8.Replay; + +public sealed class TestRomResult +{ + public string romName { get; } + public bool passed { get; } + public int litPixels { get; } + public int minLitPixels { get; } + public int maxLitPixels { get; } + public ulong framebufferHash { get; } + public ulong registerHash { get; } + public int cyclesExecuted { get; } + public bool exited { get; } + public string detail { get; } + + public TestRomResult( + string romName, + bool passed, + int litPixels, + int minLitPixels, + int maxLitPixels, + ulong framebufferHash, + ulong registerHash, + int cyclesExecuted, + bool exited, + string detail) + { + this.romName = romName; + this.passed = passed; + this.litPixels = litPixels; + this.minLitPixels = minLitPixels; + this.maxLitPixels = maxLitPixels; + this.framebufferHash = framebufferHash; + this.registerHash = registerHash; + this.cyclesExecuted = cyclesExecuted; + this.exited = exited; + this.detail = detail; + } + + public string format() + { + var builder = new StringBuilder(); + builder.Append(passed ? "PASS " : "FAIL "); + builder.Append(romName); + builder.Append(" lit=").Append(litPixels); + builder.Append(" range=[").Append(minLitPixels).Append("..").Append(maxLitPixels).Append(']'); + builder.Append(" fb=").Append(FramebufferHash.format(framebufferHash)); + builder.Append(" cycles=").Append(cyclesExecuted); + if (detail.Length > 0) + { + builder.Append(" (").Append(detail).Append(')'); + } + return builder.ToString(); + } + + public override string ToString() => format(); +}