mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-06-15 05:29:28 +00:00
Use iterator, rather than index access for JSON data, if possible. Bit of a speed up!
This commit is contained in:
parent
70a785b5c2
commit
83b7efdd03
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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 })
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user