Use iterator, rather than index access for JSON data, if possible. Bit of a speed up!

This commit is contained in:
Adrian Conlon 2022-01-06 09:50:58 +00:00
parent 70a785b5c2
commit 83b7efdd03
7 changed files with 53 additions and 53 deletions

View File

@ -91,12 +91,12 @@ bool checker_t::check(const std::string what, const uint16_t address, const uint
checker_t::checker_t(TestRunner& runner)
: m_runner(runner) {}
void checker_t::initialiseState() {
void checker_t::initialiseState(const test_t test) {
auto& cpu = runner().CPU();
auto& ram = runner().RAM();
const auto initial = test().initial();
const auto initial = test.initial();
cpu.PC().word = initial.pc();
cpu.S() = initial.s();
@ -105,10 +105,10 @@ void checker_t::initialiseState() {
cpu.Y() = initial.y();
cpu.P() = initial.p();
for (const auto entry : initial.ram()) {
const byte_t byte(entry);
const auto address = byte.address();
const auto value = byte.value();
ram.poke(address, value);
auto data = entry.begin();
const int64_t address = (*data).get_int64();
const int64_t value = (*++data).get_int64();
ram.poke((uint16_t)address, (uint8_t)value);
}
}
@ -130,12 +130,12 @@ void checker_t::initialise() {
}
//
bool checker_t::checkState() {
bool checker_t::checkState(test_t test) {
auto& cpu = runner().CPU();
auto& ram = runner().RAM();
const auto expected_cycles = test().cycles();
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)
@ -144,23 +144,23 @@ bool checker_t::checkState() {
size_t actual_idx = 0;
for (const auto expected_cycle : expected_cycles) {
const auto expected = cycle_t(expected_cycle);
auto expected_data = expected_cycle.begin();
const auto& actual = actual_cycles.at(actual_idx++); // actual could be less than expected
const auto expected_address = expected.address();
const int64_t expected_address = (*expected_data).get_int64();
const auto actual_address = std::get<0>(actual);
check("Cycle address", expected_address, actual_address);
check("Cycle address", (uint16_t)expected_address, actual_address);
const auto expected_value = expected.value();
const int64_t expected_value = (*++expected_data).get_int64();
const auto actual_value = std::get<1>(actual);
check("Cycle value", expected_value, actual_value);
check("Cycle value", (uint8_t)expected_value, actual_value);
const auto expected_action = expected.action();
const std::string_view expected_action = (*++expected_data).get_string();
const auto& actual_action = std::get<2>(actual);
check("Cycle action", expected_action, std::string_view(actual_action));
}
const auto final = test().final();
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());
@ -170,9 +170,9 @@ bool checker_t::checkState() {
bool ram_problem = false;
for (const auto entry : final.ram()) {
const byte_t byte(entry);
const auto address = byte.address();
const auto value = byte.value();
auto data = entry.begin();
const int64_t address = (*data).get_int64();
const int64_t value = (*++data).get_int64();
const auto ram_good = check("RAM", address, value, ram.peek(address));
if (!ram_good && !ram_problem)
ram_problem = true;
@ -196,9 +196,7 @@ void checker_t::disassemble(uint16_t address) {
pushCurrentMessage();
}
void checker_t::check(test_t current) {
m_test = current;
void checker_t::check(test_t test) {
auto& cpu = runner().CPU();
@ -206,7 +204,7 @@ void checker_t::check(test_t current) {
m_actualCycles.clear();
runner().raisePOWER();
initialiseState();
initialiseState(test);
const auto pc = cpu.PC().word;
const auto start_opcode = runner().peek(pc);
@ -224,7 +222,7 @@ void checker_t::check(test_t current) {
m_cycles = cpu.step();
runner().lowerPOWER();
m_valid = checkState();
m_valid = checkState(test);
if (unimplemented()) {
m_messages.push_back("Unimplemented");
@ -235,7 +233,7 @@ void checker_t::check(test_t current) {
disassemble(pc);
const auto final = test().final();
const auto final = test.final();
raise("PC", final.pc(), cpu.PC().word);
raise("S", final.s(), cpu.S());
raise("A", final.a(), cpu.A());
@ -246,11 +244,11 @@ void checker_t::check(test_t current) {
os()
<< std::dec << std::setfill(' ')
<< "Stepped cycles: " << cycles()
<< ", expected events: " << test().cycles().size()
<< ", expected events: " << test.cycles().size()
<< ", actual events: " << m_actualCycles.size();
pushCurrentMessage();
dumpCycles("-- Expected cycles", test().cycles());
dumpCycles("-- Expected cycles", test.cycles());
dumpCycles("-- Actual cycles", m_actualCycles);
}
}

View File

@ -21,8 +21,6 @@ private:
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<std::string> m_messages;
@ -35,12 +33,12 @@ private:
bool m_valid = true;
bool m_undocumented = false;
[[nodiscard]] auto& os() { return m_os; }
[[nodiscard]] constexpr auto& os() noexcept { return m_os; }
[[nodiscard]] auto& runner() noexcept { return m_runner; }
[[nodiscard]] constexpr auto& runner() noexcept { return m_runner; }
void seedUndocumentedOpcodes();
[[nodiscard]] bool checkState();
[[nodiscard]] bool checkState(test_t test);
void pushCurrentMessage();
@ -84,9 +82,7 @@ private:
void dumpCycles(const actual_cycles_t& cycles);
void dumpCycle(const actual_cycle_t& cycle);
[[nodiscard]] auto test() const noexcept { return m_test; }
void initialiseState();
void initialiseState(test_t test);
public:
checker_t(TestRunner& runner);
@ -103,5 +99,5 @@ public:
void initialise();
void check(test_t current);
void check(test_t test);
};

View File

@ -6,19 +6,20 @@ opcode_test_suite_t::opcode_test_suite_t(const std::string path) noexcept
#ifdef USE_COROUTINES
#if __cplusplus >= 202002L
EightBit::co_generator_t<test_t> opcode_test_suite_t::generator() {
EightBit::co_generator_t<test_t> opcode_test_suite_t::generator() const {
for (const auto element : *this)
co_yield test_t(element);
}
#else
void opcode_test_suite_t::generator(boost::coroutines2::coroutine<test_t>::push_type& sink) {
void opcode_test_suite_t::generator(boost::coroutines2::coroutine<test_t>::push_type& sink) const {
for (const auto element : *this)
sink(test_t(element));
}
#endif
#else
std::vector<test_t> opcode_test_suite_t::generate() {
std::vector<test_t> opcode_test_suite_t::generate() const {
std::vector<test_t> returned;
returned.reserve(size());
for (const auto element : *this)
returned.push_back(test_t(element));
return returned;

View File

@ -24,14 +24,15 @@ public:
[[nodiscard]] auto begin() const noexcept { return array().begin(); }
[[nodiscard]] auto end() const noexcept { return array().end(); }
[[nodiscard]] auto size() const noexcept { return array().size(); }
#ifdef USE_COROUTINES
#if __cplusplus >= 202002L
[[nodiscard]] EightBit::co_generator_t<test_t> generator();
[[nodiscard]] EightBit::co_generator_t<test_t> generator() const;
#else
void generator(boost::coroutines2::coroutine<test_t>::push_type& sink);
void generator(boost::coroutines2::coroutine<test_t>::push_type& sink) const;
#endif
#else
std::vector<test_t> generate();
std::vector<test_t> generate() const;
#endif
};

View File

@ -9,20 +9,20 @@ processor_test_suite_t::processor_test_suite_t(std::string location) noexcept
#ifdef USE_COROUTINES
#if __cplusplus >= 202002L
EightBit::co_generator_t<opcode_test_suite_t> processor_test_suite_t::generator() {
EightBit::co_generator_t<opcode_test_suite_t> processor_test_suite_t::generator() const {
std::filesystem::path directory = location();
for (const auto& entry : std::filesystem::directory_iterator{ directory })
co_yield opcode_test_suite_t(entry.path().string());
}
#else
void processor_test_suite_t::generator(boost::coroutines2::coroutine<opcode_test_suite_t>::push_type& sink) {
void processor_test_suite_t::generator(boost::coroutines2::coroutine<opcode_test_suite_t>::push_type& sink) const {
std::filesystem::path directory = location();
for (const auto& entry : std::filesystem::directory_iterator{ directory })
sink(opcode_test_suite_t(entry.path().string()));
}
#endif
#else
std::vector<opcode_test_suite_t> processor_test_suite_t::generate() {
std::vector<opcode_test_suite_t> processor_test_suite_t::generate() const {
std::vector<opcode_test_suite_t> returned;
std::filesystem::path directory = location();
for (const auto& entry : std::filesystem::directory_iterator{ directory })

View File

@ -22,15 +22,19 @@ private:
public:
processor_test_suite_t(std::string location) noexcept;
std::string_view location() const noexcept { return m_location; }
#if __cplusplus >= 202002L
[[nodiscard]] constexpr std::string_view location() const noexcept { return m_location; }
#else
[[nodiscard]] std::string_view location() const noexcept { return m_location; }
#endif
#ifdef USE_COROUTINES
#if __cplusplus >= 202002L
[[nodiscard]] EightBit::co_generator_t<opcode_test_suite_t> generator();
[[nodiscard]] EightBit::co_generator_t<opcode_test_suite_t> generator() const;
#else
void generator(boost::coroutines2::coroutine<opcode_test_suite_t>::push_type& sink);
void generator(boost::coroutines2::coroutine<opcode_test_suite_t>::push_type& sink) const;
#endif
#else
std::vector<opcode_test_suite_t> generate();
[[nodiscard]] std::vector<opcode_test_suite_t> generate() const;
#endif
};

View File

@ -66,7 +66,7 @@ int main() {
#else
processor_test_suite_t m6502_tests(directory);
const processor_test_suite_t m6502_tests(directory);
boost::coroutines2::coroutine<opcode_test_suite_t>::pull_type opcodes(boost::bind(&processor_test_suite_t::generator, &m6502_tests, _1));
for (auto& opcode : opcodes) {
@ -75,7 +75,7 @@ int main() {
opcode.load();
boost::coroutines2::coroutine<test_t>::pull_type tests(boost::bind(&opcode_test_suite_t::generator, &opcode, _1));
for (auto& test : tests) {
for (const auto& test : tests) {
checker.check(test);
@ -97,7 +97,7 @@ int main() {
#else
processor_test_suite_t m6502_tests(directory);
const processor_test_suite_t m6502_tests(directory);
auto opcodes = m6502_tests.generate();
for (auto& opcode : opcodes) {
@ -105,8 +105,8 @@ int main() {
std::cout << "Processing: " << path.filename() << "\n";
opcode.load();
auto tests = opcode.generate();
for (auto& test : tests) {
const auto tests = opcode.generate();
for (const auto& test : tests) {
checker.check(test);