From 8853e1157c5a8acabe1c5af7cb8de896a6e29af5 Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Sun, 31 Oct 2021 09:49:10 +0000 Subject: [PATCH] Refactor the checking code into into it's own class. Signed-off-by: Adrian Conlon --- M6502/HarteTest_6502/HarteTest_6502.vcxproj | 2 + .../HarteTest_6502.vcxproj.filters | 6 + M6502/HarteTest_6502/TestRunner.cpp | 245 +----------------- M6502/HarteTest_6502/TestRunner.h | 89 ------- M6502/HarteTest_6502/checker_t.cpp | 156 ++++++----- M6502/HarteTest_6502/checker_t.h | 67 ++--- M6502/HarteTest_6502/tests.cpp | 28 +- 7 files changed, 144 insertions(+), 449 deletions(-) diff --git a/M6502/HarteTest_6502/HarteTest_6502.vcxproj b/M6502/HarteTest_6502/HarteTest_6502.vcxproj index 36ded50..3f7dfea 100644 --- a/M6502/HarteTest_6502/HarteTest_6502.vcxproj +++ b/M6502/HarteTest_6502/HarteTest_6502.vcxproj @@ -158,6 +158,7 @@ + @@ -184,6 +185,7 @@ + diff --git a/M6502/HarteTest_6502/HarteTest_6502.vcxproj.filters b/M6502/HarteTest_6502/HarteTest_6502.vcxproj.filters index 69c0257..7cc8619 100644 --- a/M6502/HarteTest_6502/HarteTest_6502.vcxproj.filters +++ b/M6502/HarteTest_6502/HarteTest_6502.vcxproj.filters @@ -56,6 +56,9 @@ Source Files + + Source Files + @@ -103,5 +106,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/M6502/HarteTest_6502/TestRunner.cpp b/M6502/HarteTest_6502/TestRunner.cpp index fd38f08..15117d6 100644 --- a/M6502/HarteTest_6502/TestRunner.cpp +++ b/M6502/HarteTest_6502/TestRunner.cpp @@ -1,9 +1,6 @@ #include "stdafx.h" #include "TestRunner.h" -std::set TestRunner::m_undocumented_opcodes; -bool TestRunner::m_undocumented_opcodes_initialised = false; - TestRunner::TestRunner() {} EightBit::MemoryMapping TestRunner::mapping(const uint16_t address) noexcept { @@ -25,244 +22,4 @@ void TestRunner::lowerPOWER() { EightBit::Bus::lowerPOWER(); } -void TestRunner::addActualCycle(const uint16_t address, const uint8_t value, std::string_view action) { - m_actualCycles.push_back({ address, value, std::string(action) }); -} - -void TestRunner::addActualCycle(const EightBit::register16_t address, const uint8_t value, std::string_view action) { - addActualCycle(address.word, value, action); -} - -void TestRunner::addActualReadCycle(const EightBit::register16_t address, const uint8_t value) { - addActualCycle(address, value, "read"); -} - -void TestRunner::addActualWriteCycle(const EightBit::register16_t address, const uint8_t value) { - addActualCycle(address, value, "write"); -} - -void TestRunner::dumpCycles(std::string_view which, const actual_cycles_t& events) { - m_messages.push_back(std::string(which)); - dumpCycles(events); -} - -void TestRunner::dumpCycles(const actual_cycles_t& cycles) { - for (const auto& cycle: cycles) - dumpCycle(cycle); -} - -void TestRunner::dumpCycle(const actual_cycle_t& cycle) { - dumpCycle(std::get<0>(cycle), std::get<1>(cycle), std::get<2>(cycle)); -} - -void TestRunner::dumpCycles(std::string_view which, const cycles_t events) { - m_messages.push_back(std::string(which)); - dumpCycles(events); -} - -void TestRunner::dumpCycles(const cycles_t cycles) { - for (const auto cycle: cycles) - dumpCycle(cycle_t(cycle)); -} - -void TestRunner::dumpCycle(const cycle_t cycle) { - dumpCycle(cycle.address(), cycle.value(), cycle.action()); -} - -void TestRunner::initialise() { - - seedUndocumentedOpcodes(); - - ReadByte.connect([this](EightBit::EventArgs&) { - addActualReadCycle(ADDRESS(), DATA()); - }); - - WrittenByte.connect([this](EightBit::EventArgs&) { - addActualWriteCycle(ADDRESS(), DATA()); - }); - - os() << std::hex << std::uppercase; -} - -void TestRunner::raise(std::string_view what, const uint16_t expected, const uint16_t actual) { - os() - << std::setw(2) << std::setfill(' ') - << what - << std::setw(4) << std::setfill('0') - << ": expected: " << (int)expected - << ", actual: " << (int)actual; - pushCurrentMessage(); -} - -void TestRunner::raise(std::string_view what, const uint8_t expected, const uint8_t actual) { - os() - << std::setw(2) << std::setfill(' ') - << what - << std::setfill('0') - << ": expected: " << (int)expected - << " (" << EightBit::Disassembly::dump_Flags(expected) << ")" - << ", actual: " << (int)actual - << " (" << EightBit::Disassembly::dump_Flags(actual) << ")"; - pushCurrentMessage(); -} - -void TestRunner::raise(std::string_view what, std::string_view expected, std::string_view actual) { - os() - << std::setw(0) << std::setfill(' ') - << what - << ": expected: " << expected - << ", actual: " << actual; - pushCurrentMessage(); -} - -bool TestRunner::check(std::string_view what, const uint16_t address, const uint8_t expected, const uint8_t actual) { - const auto success = actual == expected; - if (!success) { - os() << what << ": " << std::setw(4) << std::setfill('0') << (int)address; - raise(os().str(), expected, actual); - } - return success; -} - -void TestRunner::initialiseState() { - - const auto initial = test().initial(); - - CPU().PC().word = initial.pc(); - CPU().S() = initial.s(); - CPU().A() = initial.a(); - CPU().X() = initial.x(); - CPU().Y() = initial.y(); - CPU().P() = initial.p(); - for (const auto entry : initial.ram()) { - const byte_t byte(entry); - RAM().poke(byte.address(), byte.value()); - } -} - -bool TestRunner::checkState() { - - const auto expected_cycles = test().cycles(); - const auto actual_cycles = m_actualCycles; - m_cycle_count_mismatch = expected_cycles.size() != actual_cycles.size(); - if (m_cycle_count_mismatch) - return false; - - size_t actual_idx = 0; - for (const auto expected_cycle : expected_cycles) { - const auto expected = cycle_t(expected_cycle); - const auto actual = actual_cycles.at(actual_idx++); // actual could be less than expected - check("Cycle address", expected.address(), std::get<0>(actual)); - check("Cycle value", expected.value(), std::get<1>(actual)); - check("Cycle action", expected.action(), std::string_view(std::get<2>(actual))); - } - - const auto final = test().final(); - const auto pc_good = check("PC", final.pc(), CPU().PC().word); - const auto s_good = check("S", final.s(), CPU().S()); - const auto a_good = check("A", final.a(), CPU().A()); - const auto x_good = check("X", final.x(), CPU().X()); - const auto y_good = check("Y", final.y(), CPU().Y()); - const auto p_good = check("P", final.p(), CPU().P()); - - bool ram_problem = false; - for (const auto entry : final.ram()) { - const byte_t byte(entry); - const auto ram_good = check("RAM", byte.address(), byte.value(), RAM().peek(byte.address())); - if (!ram_good && !ram_problem) - ram_problem = true; - } - - return pc_good && s_good && a_good && x_good && y_good && p_good && !ram_problem; -} - -void TestRunner::pushCurrentMessage() { - m_messages.push_back(os().str()); - os().str(""); -} - -void TestRunner::disassemble(uint16_t address) { - try { - os() << m_disassembler.disassemble(address); - } catch (const std::domain_error& error) { - os() << "Disassembly problem: " << error.what(); - } - pushCurrentMessage(); -} - -void TestRunner::check(const test_t updated) { - - m_test = updated; - - m_messages.clear(); - m_actualCycles.clear(); - m_cycles = 0; - m_valid = true; - m_undocumented = false; - - raisePOWER(); - initialiseState(); - const auto pc = CPU().PC().word; - const auto start_opcode = peek(pc); - m_cycles = CPU().step(); - lowerPOWER(); - - m_valid = checkState(); - - m_undocumented = m_undocumented_opcodes.find(start_opcode) != m_undocumented_opcodes.end(); - if (undocumented()) { - m_messages.push_back("Undocumented"); - return; - } - - if (unimplemented()) { - m_messages.push_back("Unimplemented"); - return; - } - - if (invalid() && implemented()) { - - disassemble(pc); - - const auto final = test().final(); - raise("PC", final.pc(), CPU().PC().word); - raise("S", final.s(), CPU().S()); - raise("A", final.a(), CPU().A()); - raise("X", final.x(), CPU().X()); - raise("Y", final.y(), CPU().Y()); - raise("P", final.p(), CPU().P()); - - os() - << std::dec << std::setfill(' ') - << "Stepped cycles: " << cycles() - << ", expected events: " << test().cycles().size() - << ", actual events: " << m_actualCycles.size(); - pushCurrentMessage(); - - dumpCycles("-- Expected cycles", test().cycles()); - dumpCycles("-- Actual cycles", m_actualCycles); - } -} - -void TestRunner::seedUndocumentedOpcodes() { - if (m_undocumented_opcodes_initialised) return; - m_undocumented_opcodes = { - 0x02, 0x03, 0x04, 0x07, 0x0b, 0x0c, 0x0f, - 0x12, 0x13, 0x14, 0x17, 0x1a, 0x1b, 0x1c, 0x1f, - 0x22, 0x23, 0x27, 0x2b, 0x2f, - 0x32, 0x33, 0x34, 0x37, 0x3a, 0x3b, 0x3c, 0x3f, - 0x42, 0x43, 0x44, 0x47, 0x4b, 0x4f, - 0x52, 0x53, 0x54, 0x57, 0x5a, 0x5b, 0x5c, 0x5f, - 0x62, 0x63, 0x64, 0x67, 0x6b, 0x6f, - 0x72, 0x73, 0x74, 0x77, 0x7a, 0x7b, 0x7c, 0x7f, - 0x80, 0x82, 0x83, 0x87, 0x89, 0x8b, 0x8f, - 0x92, 0x93, 0x97, 0x9b, 0x9c, 0x9e, 0x9f, - 0xa3, 0xa7, 0xab, 0xaf, - 0xb2, 0xb3, 0xb7, 0xbb, 0xbf, - 0xc2, 0xc3, 0xc7, 0xcb, 0xcf, - 0xd2, 0xd3, 0xd4, 0xd7, 0xda, 0xdb, 0xdc, 0xdf, - 0xe2, 0xe3, 0xe7, 0xeb, 0xef, - 0xf1, 0xf2, 0xf3, 0xf4, 0xf7, 0xfa, 0xfb, 0xfc, 0xff, - }; - m_undocumented_opcodes_initialised = true; -} \ No newline at end of file +void TestRunner::initialise() {} diff --git a/M6502/HarteTest_6502/TestRunner.h b/M6502/HarteTest_6502/TestRunner.h index 90d6792..d1ab1c7 100644 --- a/M6502/HarteTest_6502/TestRunner.h +++ b/M6502/HarteTest_6502/TestRunner.h @@ -9,11 +9,6 @@ #include #include #include -#include -#include - -#include "test_t.h" -#include "cycle_t.h" class TestRunner final : public EightBit::Bus { private: @@ -22,78 +17,6 @@ private: EightBit::Ram m_ram = 0x10000; EightBit::MOS6502 m_cpu = { *this }; - EightBit::Symbols m_symbols; - EightBit::Disassembly m_disassembler = { *this, m_cpu, m_symbols }; - - test_t m_test; - - std::ostringstream m_os; - std::vector m_messages; - - typedef std::tuple actual_cycle_t; - typedef std::vector actual_cycles_t; - actual_cycles_t m_actualCycles; - bool m_cycle_count_mismatch = false; - - int m_cycles = 0; - bool m_valid = true; - bool m_undocumented = false; - - void seedUndocumentedOpcodes(); - void initialiseState(); - [[nodiscard]] bool checkState(); - - void pushCurrentMessage(); - - void raise(std::string_view what, uint16_t expected, uint16_t actual); - void raise(std::string_view what, uint8_t expected, uint8_t actual); - void raise(std::string_view what, std::string_view expected, std::string_view actual); - - template - bool check(std::string_view what, T expected, T actual) { - const auto success = actual == expected; - if (!success) - raise(what, expected, actual); - return success; - } - - bool check(std::string_view what, std::string_view expected, std::string_view actual) { - const auto success = actual == expected; - if (!success) - raise(what, expected, actual); - return success; - } - - bool check(std::string_view what, uint16_t address, uint8_t expected, uint8_t actual); - - void addActualCycle(const actual_cycle_t& value); - void addActualCycle(uint16_t address, uint8_t value, std::string_view action); - void addActualCycle(EightBit::register16_t address, uint8_t value, std::string_view action); - - void addActualReadCycle(EightBit::register16_t address, uint8_t value); - void addActualWriteCycle(EightBit::register16_t address, uint8_t value); - - void disassemble(uint16_t address); - - template - void dumpCycle(const uint16_t address, const uint8_t value, const T action) { - m_os - << std::setfill('0') << std::hex - << "Address: " << std::setw(4) << (int)address - << ", value: " << std::setw(2) << (int)value - << ", action: " << action; - pushCurrentMessage(); - } - - void dumpCycles(std::string_view which, cycles_t cycles); - void dumpCycles(cycles_t cycles); - void dumpCycle(cycle_t cycle); - - void dumpCycles(std::string_view which, const actual_cycles_t& cycles); - void dumpCycles(const actual_cycles_t& cycles); - void dumpCycle(const actual_cycle_t& cycle); - - [[nodiscard]] auto& os() { return m_os; } protected: virtual EightBit::MemoryMapping mapping(uint16_t address) noexcept final; @@ -108,16 +31,4 @@ public: [[nodiscard]] constexpr auto& RAM() noexcept { return m_ram; } [[nodiscard]] constexpr auto& CPU() noexcept { return m_cpu; } - [[nodiscard]] auto test() const noexcept { return m_test; } - [[nodiscard]] constexpr const auto& messages() const noexcept { return m_messages; } - - [[nodiscard]] constexpr auto cycles() const noexcept { return m_cycles; } - [[nodiscard]] constexpr auto valid() const noexcept { return m_valid; } - [[nodiscard]] constexpr auto invalid() const noexcept { return !valid(); } - [[nodiscard]] constexpr auto unimplemented() const noexcept { return invalid() && m_cycle_count_mismatch && (cycles() == 1); } - [[nodiscard]] constexpr auto implemented() const noexcept { return !unimplemented(); } - [[nodiscard]] constexpr auto undocumented() const noexcept { return m_undocumented; } - [[nodiscard]] constexpr auto documented() const noexcept { return !undocumented(); } - - void check(test_t updated); }; diff --git a/M6502/HarteTest_6502/checker_t.cpp b/M6502/HarteTest_6502/checker_t.cpp index a2ee7d8..cde11fe 100644 --- a/M6502/HarteTest_6502/checker_t.cpp +++ b/M6502/HarteTest_6502/checker_t.cpp @@ -78,21 +78,23 @@ void checker_t::raise(const std::string what, const std::string_view expected, c << ", actual: " << actual; pushCurrentMessage(); } -// -//bool TestRunner::check(const std::string what, const uint16_t address, const uint8_t expected, const uint8_t actual) { -// const auto success = actual == expected; -// if (!success) { -// os() << what << ": " << std::setw(4) << std::setfill('0') << (int)address; -// raise(os().str(), expected, actual); -// } -// return success; -//} -// -checker_t::checker_t(const test_t test) -: m_test(test) {} +bool checker_t::check(const std::string what, const uint16_t address, const uint8_t expected, const uint8_t actual) { + const auto success = actual == expected; + if (!success) { + os() << what << ": " << std::setw(4) << std::setfill('0') << (int)address; + raise(os().str(), expected, actual); + } + return success; +} -void checker_t::initialiseState(EightBit::MOS6502& cpu, EightBit::Ram& ram) { +checker_t::checker_t(TestRunner& runner) +: m_runner(runner) {} + +void checker_t::initialiseState() { + + auto& cpu = runner().CPU(); + auto& ram = runner().RAM(); const auto initial = test().initial(); @@ -108,10 +110,12 @@ void checker_t::initialiseState(EightBit::MOS6502& cpu, EightBit::Ram& ram) { } } -void checker_t::initialise(EightBit::Bus& bus) { +void checker_t::initialise() { seedUndocumentedOpcodes(); + auto& bus = runner(); + bus.ReadByte.connect([this, &bus](EightBit::EventArgs&) { addActualReadCycle(bus.ADDRESS(), bus.DATA()); }); @@ -124,7 +128,10 @@ void checker_t::initialise(EightBit::Bus& bus) { } // -bool checker_t::checkState(EightBit::MOS6502& cpu, EightBit::Ram& ram) { +bool checker_t::checkState() { + + auto& cpu = runner().CPU(); + auto& ram = runner().RAM(); const auto expected_cycles = test().cycles(); const auto actual_cycles = m_actualCycles; @@ -165,62 +172,69 @@ void checker_t::pushCurrentMessage() { os().str(""); } -//void TestRunner::disassemble(uint16_t address) { -// try { -// os() << m_disassembler.disassemble(address); -// } -// catch (const std::domain_error& error) { -// os() << "Disassembly problem: " << error.what(); -// } -// pushCurrentMessage(); -//} -// -//void TestRunner::check() { -// initialise(); -// raisePOWER(); -// initialiseState(); -// const auto pc = CPU().PC().word; -// const auto start_opcode = peek(pc); -// m_cycles = CPU().step(); -// lowerPOWER(); -// -// m_valid = checkState(); -// -// m_undocumented = m_undocumented_opcodes.find(start_opcode) != m_undocumented_opcodes.end(); -// if (undocumented()) { -// m_messages.push_back("Undocumented"); -// return; -// } -// -// if (unimplemented()) { -// m_messages.push_back("Unimplemented"); -// return; -// } -// -// if (invalid() && implemented()) { -// -// disassemble(pc); -// -// const auto final = test().final(); -// raise("PC", final.pc(), CPU().PC().word); -// raise("S", final.s(), CPU().S()); -// raise("A", final.a(), CPU().A()); -// raise("X", final.x(), CPU().X()); -// raise("Y", final.y(), CPU().Y()); -// raise("P", final.p(), CPU().P()); -// -// os() -// << std::dec << std::setfill(' ') -// << "Stepped cycles: " << cycles() -// << ", expected events: " << test().cycles().size() -// << ", actual events: " << m_actualCycles.size(); -// pushCurrentMessage(); -// -// dumpCycles("-- Expected cycles", test().cycles()); -// dumpCycles("-- Actual cycles", m_actualCycles); -// } -//} -// +void checker_t::disassemble(uint16_t address) { + try { + os() << m_disassembler.disassemble(address); + } + catch (const std::domain_error& error) { + os() << "Disassembly problem: " << error.what(); + } + pushCurrentMessage(); +} + +void checker_t::check(test_t current) { + + m_test = current; + + auto& cpu = runner().CPU(); + + m_messages.clear(); + m_actualCycles.clear(); + + runner().raisePOWER(); + initialiseState(); + const auto pc = cpu.PC().word; + const auto start_opcode = runner().peek(pc); + m_cycles = cpu.step(); + runner().lowerPOWER(); + + m_valid = checkState(); + + m_undocumented = m_undocumented_opcodes.find(start_opcode) != m_undocumented_opcodes.end(); + if (undocumented()) { + m_messages.push_back("Undocumented"); + return; + } + + if (unimplemented()) { + m_messages.push_back("Unimplemented"); + return; + } + + if (invalid() && implemented()) { + + disassemble(pc); + + const auto final = test().final(); + raise("PC", final.pc(), cpu.PC().word); + raise("S", final.s(), cpu.S()); + raise("A", final.a(), cpu.A()); + raise("X", final.x(), cpu.X()); + raise("Y", final.y(), cpu.Y()); + raise("P", final.p(), cpu.P()); + + os() + << std::dec << std::setfill(' ') + << "Stepped cycles: " << cycles() + << ", expected events: " << test().cycles().size() + << ", actual events: " << m_actualCycles.size(); + pushCurrentMessage(); + + dumpCycles("-- Expected cycles", test().cycles()); + dumpCycles("-- Actual cycles", m_actualCycles); + } +} + void checker_t::seedUndocumentedOpcodes() { if (m_undocumented_opcodes_initialised) return; m_undocumented_opcodes = { diff --git a/M6502/HarteTest_6502/checker_t.h b/M6502/HarteTest_6502/checker_t.h index 4eff3f5..3cfcda0 100644 --- a/M6502/HarteTest_6502/checker_t.h +++ b/M6502/HarteTest_6502/checker_t.h @@ -3,17 +3,26 @@ #include #include +#include +#include + #include "cycles_t.h" #include "cycle_t.h" #include "test_t.h" +#include "TestRunner.h" + class checker_t { public: private: static std::set m_undocumented_opcodes; static bool m_undocumented_opcodes_initialised; - const test_t m_test; + TestRunner& m_runner; + EightBit::Symbols m_symbols; + EightBit::Disassembly m_disassembler = { m_runner, m_runner.CPU(), m_symbols }; + + test_t m_test; std::ostringstream m_os; std::vector m_messages; @@ -23,14 +32,16 @@ private: actual_cycles_t m_actualCycles; bool m_cycle_count_mismatch = false; - //int m_cycles = 0; - //bool m_valid = true; - //bool m_undocumented = false; + int m_cycles = 0; + bool m_valid = true; + bool m_undocumented = false; [[nodiscard]] auto& os() { return m_os; } + [[nodiscard]] auto& runner() noexcept { return m_runner; } + void seedUndocumentedOpcodes(); - [[nodiscard]] bool checkState(EightBit::MOS6502& cpu, EightBit::Ram& ram); + [[nodiscard]] bool checkState(); void pushCurrentMessage(); @@ -48,18 +59,17 @@ private: bool check(std::string what, uint16_t address, uint8_t expected, uint8_t actual); - //void addActualCycle(const actual_cycle_t& value); void addActualCycle(uint16_t address, uint8_t value, std::string action); void addActualCycle(EightBit::register16_t address, uint8_t value, std::string action); void addActualReadCycle(EightBit::register16_t address, uint8_t value); void addActualWriteCycle(EightBit::register16_t address, uint8_t value); - //void disassemble(uint16_t address); + void disassemble(uint16_t address); template void dumpCycle(const uint16_t address, const uint8_t value, const T action) { - os() + m_os << std::setfill('0') << std::hex << "Address: " << std::setw(4) << (int)address << ", value: " << std::setw(2) << (int)value @@ -75,33 +85,24 @@ private: void dumpCycles(const actual_cycles_t& cycles); void dumpCycle(const actual_cycle_t& cycle); - - - - - - //[[nodiscard]] auto test() const noexcept { return m_test; } - //[[nodiscard]] constexpr const auto& messages() const noexcept { return m_messages; } - - //[[nodiscard]] constexpr auto cycles() const noexcept { return m_cycles; } - //[[nodiscard]] constexpr auto valid() const noexcept { return m_valid; } - //[[nodiscard]] constexpr auto invalid() const noexcept { return !valid(); } - //[[nodiscard]] constexpr auto unimplemented() const noexcept { return invalid() && m_cycle_count_mismatch && (cycles() == 1); } - //[[nodiscard]] constexpr auto implemented() const noexcept { return !unimplemented(); } - //[[nodiscard]] constexpr auto undocumented() const noexcept { return m_undocumented; } - //[[nodiscard]] constexpr auto documented() const noexcept { return !undocumented(); } - - //void check(); - - -public: - checker_t(const test_t test); - [[nodiscard]] auto test() const noexcept { return m_test; } + void initialiseState(); - void initialise(EightBit::Bus& bus); - void initialiseState(EightBit::MOS6502& cpu, EightBit::Ram& ram); +public: + checker_t(TestRunner& runner); + [[nodiscard]] constexpr auto cycles() const noexcept { return m_cycles; } + [[nodiscard]] constexpr auto valid() const noexcept { return m_valid; } + [[nodiscard]] constexpr auto invalid() const noexcept { return !valid(); } + [[nodiscard]] constexpr auto unimplemented() const noexcept { return invalid() && m_cycle_count_mismatch && (cycles() == 1); } + [[nodiscard]] constexpr auto implemented() const noexcept { return !unimplemented(); } + [[nodiscard]] constexpr auto undocumented() const noexcept { return m_undocumented; } + [[nodiscard]] constexpr auto documented() const noexcept { return !undocumented(); } + + [[nodiscard]] constexpr const auto& messages() const noexcept { return m_messages; } + + void initialise(); + + void check(test_t current); }; - diff --git a/M6502/HarteTest_6502/tests.cpp b/M6502/HarteTest_6502/tests.cpp index dd1b62b..37b00ba 100644 --- a/M6502/HarteTest_6502/tests.cpp +++ b/M6502/HarteTest_6502/tests.cpp @@ -5,6 +5,7 @@ #include #include "TestRunner.h" +#include "checker_t.h" #include "test_t.h" #include "opcode_test_suite_t.h" #include "processor_test_suite_t.h" @@ -24,6 +25,9 @@ int main() { TestRunner runner; runner.initialise(); + checker_t checker(runner); + checker.initialise(); + #ifdef USE_COROUTINES processor_test_suite_t m6502_tests(directory); @@ -40,16 +44,16 @@ int main() { while (test_generator) { const auto test = test_generator(); + checker.check(test); - runner.check(test); - if (runner.invalid()) { + if (checker.invalid()) { ++invalid_opcode_count; - if (runner.unimplemented()) + if (checker.unimplemented()) ++unimplemented_opcode_count; - if (runner.undocumented()) + if (checker.undocumented()) ++undocumented_opcode_count; std::cout << "** Failed: " << test.name() << "\n"; - for (const auto& message : runner.messages()) + for (const auto& message : checker.messages()) std::cout << "**** " << message << "\n"; break; } @@ -70,17 +74,17 @@ int main() { for (const auto opcode_test_element : opcode) { - const auto opcode_test = test_t(opcode_test_element); - runner.check(opcode_test); + const auto test = test_t(opcode_test_element); + checker.check(test); - if (runner.invalid()) { + if (checker.invalid()) { ++invalid_opcode_count; - if (runner.unimplemented()) + if (checker.unimplemented()) ++unimplemented_opcode_count; - if (runner.undocumented()) + if (checker.undocumented()) ++undocumented_opcode_count; - std::cout << "** Failed: " << opcode_test.name() << "\n"; - for (const auto& message : runner.messages()) + std::cout << "** Failed: " << test.name() << "\n"; + for (const auto& message : checker.messages()) std::cout << "**** " << message << "\n"; break; }