diff --git a/EightBitNet.sln b/EightBitNet.sln index defccd0..22fc052 100644 --- a/EightBitNet.sln +++ b/EightBitNet.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 18 -VisualStudioVersion = 18.5.11801.241 oobstable +VisualStudioVersion = 18.5.11801.241 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EightBit", "EightBit\EightBit.csproj", "{B9DB62BA-F1C6-41B4-BE0F-85A1D4E64A33}" EndProject @@ -41,12 +41,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "M6502.Symbols", "M6502\M650 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SM83.HarteTest", "LR35902\SM83.HarteTest\SM83.HarteTest.csproj", "{9A85562F-986F-472B-AEAE-AAAFF0B02B48}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Z80.HarteTest", "Z80\Z80.HarteTest\Z80.HarteTest.csproj", "{4238F9DF-E58B-456D-86B4-A92381BC471D}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EightBit.UnitTest", "EightBit\EightBit.UnitTest\EightBit.UnitTest.csproj", "{A8B3D819-0E84-4586-ADB1-D57AB1A8165B}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Z80.UnitTests", "Z80\Z80.UnitTests\Z80.UnitTests.csproj", "{DB313D5B-9DC3-4844-9916-925678967112}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Z80.HarteTest", "Z80\Z80.HarteTest\Z80.HarteTest.csproj", "{63132DC1-94BC-4B00-9AE3-B95A9C9BC663}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -129,10 +129,6 @@ Global {9A85562F-986F-472B-AEAE-AAAFF0B02B48}.Debug|Any CPU.Build.0 = Debug|Any CPU {9A85562F-986F-472B-AEAE-AAAFF0B02B48}.Release|Any CPU.ActiveCfg = Release|Any CPU {9A85562F-986F-472B-AEAE-AAAFF0B02B48}.Release|Any CPU.Build.0 = Release|Any CPU - {4238F9DF-E58B-456D-86B4-A92381BC471D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4238F9DF-E58B-456D-86B4-A92381BC471D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4238F9DF-E58B-456D-86B4-A92381BC471D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4238F9DF-E58B-456D-86B4-A92381BC471D}.Release|Any CPU.Build.0 = Release|Any CPU {A8B3D819-0E84-4586-ADB1-D57AB1A8165B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A8B3D819-0E84-4586-ADB1-D57AB1A8165B}.Debug|Any CPU.Build.0 = Debug|Any CPU {A8B3D819-0E84-4586-ADB1-D57AB1A8165B}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -141,6 +137,10 @@ Global {DB313D5B-9DC3-4844-9916-925678967112}.Debug|Any CPU.Build.0 = Debug|Any CPU {DB313D5B-9DC3-4844-9916-925678967112}.Release|Any CPU.ActiveCfg = Release|Any CPU {DB313D5B-9DC3-4844-9916-925678967112}.Release|Any CPU.Build.0 = Release|Any CPU + {63132DC1-94BC-4B00-9AE3-B95A9C9BC663}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {63132DC1-94BC-4B00-9AE3-B95A9C9BC663}.Debug|Any CPU.Build.0 = Debug|Any CPU + {63132DC1-94BC-4B00-9AE3-B95A9C9BC663}.Release|Any CPU.ActiveCfg = Release|Any CPU + {63132DC1-94BC-4B00-9AE3-B95A9C9BC663}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Z80/Z80.HarteTest/ProcessorTestSuite.cs b/Z80/Z80.HarteTest/ProcessorTestSuite.cs deleted file mode 100644 index fcc9efc..0000000 --- a/Z80/Z80.HarteTest/ProcessorTestSuite.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Z80.HarteTest -{ - internal sealed class ProcessorTestSuite(string location) - { - public string Location { get; set; } = location; - - public IEnumerable OpcodeTests() - { - var pattern = "*.json"; - foreach (var filename in Directory.EnumerateFiles(this.Location, pattern)) - { - var fileInformation = new FileInfo(filename); - if (fileInformation.Length > 0) - { - yield return new OpcodeTestSuite(filename); - } - } - } - } -} diff --git a/Z80/Z80.HarteTest/Program.cs b/Z80/Z80.HarteTest/Program.cs deleted file mode 100644 index cd7d4ab..0000000 --- a/Z80/Z80.HarteTest/Program.cs +++ /dev/null @@ -1,86 +0,0 @@ -// -// Copyright (c) Adrian Conlon. All rights reserved. -// - -namespace Z80.HarteTest -{ - internal static class Program - { - public static async Task Main(string[] _) - { - var directory = @"C:\github\spectrum\libraries\EightBit\modules\z80\v2"; - await ProcessTestSuiteAsync(directory).ConfigureAwait(false); - } - - private static async Task ProcessTestSuiteAsync(string directory) - { - var startTime = DateTime.Now; - - var unimplemented_opcode_count = 0; - var invalid_opcode_count = 0; - - var runner = new TestRunner(); - runner.Initialize(); - - var checker = new Checker(runner); - checker.Initialise(); - - var testSuite = new ProcessorTestSuite(directory); - foreach (var opcode in testSuite.OpcodeTests()) - { - Console.WriteLine($"Processing: {Path.GetFileName(opcode.Path)}"); - - List testNames = []; - var tests = opcode.TestsAsync; - await foreach (var test in tests) - { - if (test is null) - { - throw new InvalidOperationException("Test cannot be null"); - } - - checker.Check(test); - if (checker.Invalid) - { - ++invalid_opcode_count; - - // Was it just unimplemented? - if (checker.Unimplemented) - { - ++unimplemented_opcode_count; - } - - // Let's see if we had any successes! - if (testNames.Count > 0) - { - Console.WriteLine("**** The follow test variations succeeded"); - foreach (var testName in testNames) - { - Console.WriteLine($"****** {testName}"); - } - } - - // OK, we've attempted an implementation, how did it fail? - foreach (var message in checker.Messages) - { - Console.WriteLine($"**** {message}"); - } - - // I'm not really interested in the remaining tests for this opcode - break; - } - - testNames.Add(test.Name); - } - } - - var finishTime = DateTime.Now; - var elapsedTime = finishTime - startTime; - - Console.Write($"Elapsed time: {elapsedTime.TotalSeconds} seconds"); - Console.Write($", unimplemented opcode count: {unimplemented_opcode_count}"); - Console.Write($", invalid opcode count: {invalid_opcode_count - unimplemented_opcode_count}"); - Console.WriteLine(); - } - } -} \ No newline at end of file diff --git a/Z80/Z80.HarteTest/SingleStepTests.cs b/Z80/Z80.HarteTest/SingleStepTests.cs new file mode 100644 index 0000000..d080d7e --- /dev/null +++ b/Z80/Z80.HarteTest/SingleStepTests.cs @@ -0,0 +1,71 @@ +// +// Copyright (c) Adrian Conlon. All rights reserved. +// +namespace Z80.HarteTest +{ + using System.Reflection; + + [TestClass] + public class SingleStepTests + { + private const string TestDataDirectory = @"C:\github\spectrum\libraries\EightBit\modules\z80\v2"; + + public static IEnumerable OpcodeFiles + { + get + { + if (!Directory.Exists(TestDataDirectory)) + { + yield break; + } + + foreach (var file in Directory.EnumerateFiles(TestDataDirectory, "*.json").OrderBy(f => f)) + { + if (new FileInfo(file).Length > 0) + { + yield return [file]; + } + } + } + } + + public static string GetDisplayName(MethodInfo _, object[] data) + { + ArgumentNullException.ThrowIfNull(data); + return System.IO.Path.GetFileNameWithoutExtension((string)data[0]); + } + + [TestMethod] + [DynamicData(nameof(OpcodeFiles), DynamicDataSourceType.Property, DynamicDataDisplayName = nameof(GetDisplayName))] + public async Task Opcode_SingleStep(string filePath) + { + var runner = new TestRunner(); + runner.Initialize(); + var checker = new Checker(runner); + checker.Initialise(); + + using var suite = new OpcodeTestSuite(filePath); + await foreach (var test in suite.TestsAsync) + { + if (test is null) + { + throw new InvalidOperationException("Test cannot be null"); + } + + checker.Check(test); + + if (checker.Unimplemented) + { + Assert.Inconclusive($"Opcode not implemented: {test.Name}"); + return; + } + + if (checker.Invalid) + { + Assert.Fail($"Test '{test.Name}' failed:{System.Environment.NewLine}{string.Join(System.Environment.NewLine, checker.Messages)}"); + return; + } + } + } + } +} diff --git a/Z80/Z80.HarteTest/State.cs b/Z80/Z80.HarteTest/State.cs index 532e794..efdef05 100644 --- a/Z80/Z80.HarteTest/State.cs +++ b/Z80/Z80.HarteTest/State.cs @@ -1,5 +1,6 @@ namespace Z80.HarteTest { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1812:Avoid uninstantiated internal classes", Justification = "Instantiated by JSON deserializer")] internal sealed class State { public ushort PC { get; set; } diff --git a/Z80/Z80.HarteTest/Test.cs b/Z80/Z80.HarteTest/Test.cs index 44b4442..58f6577 100644 --- a/Z80/Z80.HarteTest/Test.cs +++ b/Z80/Z80.HarteTest/Test.cs @@ -1,5 +1,6 @@ namespace Z80.HarteTest { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1812:Avoid uninstantiated internal classes", Justification = "Instantiated by JSON deserializer")] internal sealed class Test { public string? Name { get; set; } diff --git a/Z80/Z80.HarteTest/Z80.HarteTest.csproj b/Z80/Z80.HarteTest/Z80.HarteTest.csproj index 309d9be..ed83bc3 100644 --- a/Z80/Z80.HarteTest/Z80.HarteTest.csproj +++ b/Z80/Z80.HarteTest/Z80.HarteTest.csproj @@ -1,17 +1,43 @@ - + - Exe net10.0 + latest enable enable + true + False + False + Exe + true True latest-all + true + + 9999 + + + + 9999 + + + + + + + + + + + + + +