2021-10-10 20:26:30 +00:00
|
|
|
#pragma once
|
|
|
|
|
2021-10-11 09:20:18 +00:00
|
|
|
#include <cstdint>
|
2021-10-21 12:38:44 +00:00
|
|
|
#include <set>
|
2021-10-11 13:59:23 +00:00
|
|
|
#include <sstream>
|
2021-10-11 09:20:18 +00:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
2021-10-10 20:26:30 +00:00
|
|
|
#include <Bus.h>
|
|
|
|
#include <Ram.h>
|
|
|
|
#include <mos6502.h>
|
2021-10-19 12:13:59 +00:00
|
|
|
#include <Disassembly.h>
|
|
|
|
#include <Symbols.h>
|
2021-10-10 20:26:30 +00:00
|
|
|
|
|
|
|
#include "test_t.h"
|
|
|
|
|
|
|
|
class TestRunner final : public EightBit::Bus {
|
|
|
|
private:
|
2021-10-21 21:03:07 +00:00
|
|
|
static std::set<uint8_t> m_undocumented_opcodes;
|
|
|
|
static bool m_undocumented_opcodes_initialised;
|
|
|
|
|
2021-10-10 20:26:30 +00:00
|
|
|
EightBit::Ram m_ram = 0x10000;
|
|
|
|
EightBit::MOS6502 m_cpu = { *this };
|
2021-10-19 12:13:59 +00:00
|
|
|
EightBit::Symbols m_symbols;
|
|
|
|
EightBit::Disassembly m_disassembler = { *this, m_cpu, m_symbols };
|
|
|
|
|
2021-10-21 21:43:16 +00:00
|
|
|
const test_t m_test;
|
2021-10-11 10:41:50 +00:00
|
|
|
|
|
|
|
std::ostringstream m_os;
|
2021-10-11 09:20:18 +00:00
|
|
|
std::vector<std::string> m_messages;
|
2021-10-10 20:26:30 +00:00
|
|
|
|
2021-10-18 10:54:01 +00:00
|
|
|
cycles_t m_actualCycles;
|
|
|
|
bool m_cycle_count_mismatch = false;
|
2021-10-10 20:26:30 +00:00
|
|
|
|
2021-10-21 12:38:44 +00:00
|
|
|
int m_cycles = 0;
|
|
|
|
bool m_valid = true;
|
|
|
|
bool m_undocumented = false;
|
|
|
|
|
|
|
|
void seedUndocumentedOpcodes();
|
2021-10-10 20:26:30 +00:00
|
|
|
void initialiseState();
|
2021-10-11 09:43:33 +00:00
|
|
|
[[nodiscard]] bool checkState();
|
2021-10-10 20:26:30 +00:00
|
|
|
|
2021-10-21 12:38:44 +00:00
|
|
|
void pushCurrentMessage();
|
|
|
|
|
2021-10-10 20:26:30 +00:00
|
|
|
void raise(std::string what, uint16_t expected, uint16_t actual);
|
|
|
|
void raise(std::string what, uint8_t expected, uint8_t actual);
|
2021-10-20 22:06:42 +00:00
|
|
|
void raise(std::string what, std::string expected, std::string actual);
|
2021-10-10 20:26:30 +00:00
|
|
|
|
|
|
|
template<class T>
|
2021-10-11 10:41:50 +00:00
|
|
|
bool check(std::string what, T expected, T actual) {
|
2021-10-10 20:26:30 +00:00
|
|
|
const auto success = actual == expected;
|
|
|
|
if (!success)
|
|
|
|
raise(what, expected, actual);
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
2021-10-11 10:41:50 +00:00
|
|
|
bool check(std::string what, uint16_t address, uint8_t expected, uint8_t actual);
|
|
|
|
|
2021-10-18 10:54:01 +00:00
|
|
|
void addActualCycle(const cycle_t& value);
|
2021-10-20 22:06:42 +00:00
|
|
|
void addActualCycle(uint16_t address, uint8_t value, std::string action);
|
|
|
|
void addActualCycle(EightBit::register16_t address, uint8_t value, std::string action);
|
2021-10-10 20:26:30 +00:00
|
|
|
|
2021-10-18 10:54:01 +00:00
|
|
|
void addActualReadCycle(EightBit::register16_t address, uint8_t value);
|
|
|
|
void addActualWriteCycle(EightBit::register16_t address, uint8_t value);
|
|
|
|
|
2021-10-21 12:38:44 +00:00
|
|
|
void disassemble(uint16_t address);
|
|
|
|
|
2021-10-18 10:54:01 +00:00
|
|
|
void dumpCycles(std::string which, const cycles_t& cycles);
|
|
|
|
void dumpCycles(const cycles_t& cycles);
|
|
|
|
void dumpCycle(const cycle_t& cycle);
|
2021-10-11 22:56:20 +00:00
|
|
|
|
2021-10-11 10:41:50 +00:00
|
|
|
[[nodiscard]] auto& os() { return m_os; }
|
|
|
|
|
2021-10-10 20:26:30 +00:00
|
|
|
protected:
|
|
|
|
virtual EightBit::MemoryMapping mapping(uint16_t address) noexcept final;
|
|
|
|
|
|
|
|
public:
|
2021-10-21 21:43:16 +00:00
|
|
|
TestRunner(test_t test);
|
2021-10-10 20:26:30 +00:00
|
|
|
|
|
|
|
virtual void raisePOWER() final;
|
|
|
|
virtual void lowerPOWER() final;
|
|
|
|
|
|
|
|
virtual void initialise() final;
|
|
|
|
|
2021-10-11 09:43:33 +00:00
|
|
|
[[nodiscard]] constexpr auto& RAM() noexcept { return m_ram; }
|
|
|
|
[[nodiscard]] constexpr auto& CPU() noexcept { return m_cpu; }
|
2021-10-21 21:43:16 +00:00
|
|
|
[[nodiscard]] auto test() const noexcept { return m_test; }
|
2021-10-11 09:43:33 +00:00
|
|
|
[[nodiscard]] constexpr const auto& messages() const noexcept { return m_messages; }
|
2021-10-10 20:26:30 +00:00
|
|
|
|
2021-10-21 12:38:44 +00:00
|
|
|
[[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();
|
2021-10-10 20:26:30 +00:00
|
|
|
};
|