Lot's of small niggles corrected across the EightBit libraries
This commit is contained in:
parent
739ce39360
commit
8b6c4a205e
|
@ -103,8 +103,8 @@ void checker_t::initialiseState(const test_t test) {
|
||||||
cpu.P() = initial.p();
|
cpu.P() = initial.p();
|
||||||
for (const auto entry : initial.ram()) {
|
for (const auto entry : initial.ram()) {
|
||||||
auto data = entry.begin();
|
auto data = entry.begin();
|
||||||
const auto address = uint16_t(int64_t(*data++));
|
const auto address = uint16_t(int64_t(*data));
|
||||||
const auto value = uint8_t(int64_t(*data));
|
const auto value = uint8_t(int64_t(*++data));
|
||||||
ram.poke(address, value);
|
ram.poke(address, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,12 +113,12 @@ void checker_t::initialise() {
|
||||||
|
|
||||||
auto& bus = runner();
|
auto& bus = runner();
|
||||||
|
|
||||||
bus.ReadByte.connect([this, &bus](EightBit::EventArgs&) {
|
bus.ReadByte.connect([this](EightBit::EventArgs&) {
|
||||||
addActualReadCycle(bus.ADDRESS(), bus.DATA());
|
addActualReadCycle(runner().ADDRESS(), runner().DATA());
|
||||||
});
|
});
|
||||||
|
|
||||||
bus.WrittenByte.connect([this, &bus](EightBit::EventArgs&) {
|
bus.WrittenByte.connect([this](EightBit::EventArgs&) {
|
||||||
addActualWriteCycle(bus.ADDRESS(), bus.DATA());
|
addActualWriteCycle(runner().ADDRESS(), runner().DATA());
|
||||||
});
|
});
|
||||||
|
|
||||||
os() << std::hex << std::uppercase;
|
os() << std::hex << std::uppercase;
|
||||||
|
@ -144,15 +144,15 @@ bool checker_t::checkState(test_t test) {
|
||||||
auto expected_data = expected_cycle.begin();
|
auto expected_data = expected_cycle.begin();
|
||||||
const auto& actual = actual_cycles[actual_idx++];
|
const auto& actual = actual_cycles[actual_idx++];
|
||||||
|
|
||||||
const auto expected_address = uint16_t(int64_t(*expected_data++));
|
const auto expected_address = uint16_t(int64_t(*expected_data));
|
||||||
const auto actual_address = std::get<0>(actual);
|
const auto actual_address = std::get<0>(actual);
|
||||||
check("Cycle address", expected_address, actual_address);
|
check("Cycle address", expected_address, actual_address);
|
||||||
|
|
||||||
const auto expected_value = uint8_t(int64_t(*expected_data++));
|
const auto expected_value = uint8_t(int64_t(*++expected_data));
|
||||||
const auto actual_value = std::get<1>(actual);
|
const auto actual_value = std::get<1>(actual);
|
||||||
check("Cycle value", expected_value, actual_value);
|
check("Cycle value", expected_value, actual_value);
|
||||||
|
|
||||||
const auto expected_action = (*expected_data).get_string();
|
const auto expected_action = (*++expected_data).get_string();
|
||||||
const auto actual_action = std::get<2>(actual);
|
const auto actual_action = std::get<2>(actual);
|
||||||
check("Cycle action", expected_action.value_unsafe(), actual_action);
|
check("Cycle action", expected_action.value_unsafe(), actual_action);
|
||||||
}
|
}
|
||||||
|
@ -176,8 +176,8 @@ bool checker_t::checkState(test_t test) {
|
||||||
bool ram_problem = false;
|
bool ram_problem = false;
|
||||||
for (const auto entry : final.ram()) {
|
for (const auto entry : final.ram()) {
|
||||||
auto data = entry.begin();
|
auto data = entry.begin();
|
||||||
const auto address = uint16_t(int64_t(*data++));
|
const auto address = uint16_t(int64_t(*data));
|
||||||
const auto value = uint8_t(int64_t(*data));
|
const auto value = uint8_t(int64_t(*++data));
|
||||||
const auto ram_good = check("RAM", address, value, ram.peek(address));
|
const auto ram_good = check("RAM", address, value, ram.peek(address));
|
||||||
if (!ram_good && !ram_problem)
|
if (!ram_good && !ram_problem)
|
||||||
ram_problem = true;
|
ram_problem = true;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#define SIMDJSON_DISABLE_DEPRECATED_API
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
|
@ -214,7 +214,7 @@ namespace EightBit {
|
||||||
|
|
||||||
// Chew up a cycle
|
// Chew up a cycle
|
||||||
void swallow() noexcept { memoryRead(PC()); }
|
void swallow() noexcept { memoryRead(PC()); }
|
||||||
void swallow_stack() noexcept { getBytePaged(1, S()); }
|
void swallow_stack() noexcept { memoryRead({ S(), 1 }); }
|
||||||
void swallow_fetch() noexcept { fetchByte(); }
|
void swallow_fetch() noexcept { fetchByte(); }
|
||||||
|
|
||||||
// Instruction implementations
|
// Instruction implementations
|
||||||
|
|
|
@ -115,13 +115,13 @@ void EightBit::MOS6502::interrupt() noexcept {
|
||||||
void EightBit::MOS6502::busWrite() noexcept {
|
void EightBit::MOS6502::busWrite() noexcept {
|
||||||
tick();
|
tick();
|
||||||
lowerRW();
|
lowerRW();
|
||||||
base::busWrite();
|
LittleEndianProcessor::busWrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::MOS6502::busRead() noexcept {
|
uint8_t EightBit::MOS6502::busRead() noexcept {
|
||||||
tick();
|
tick();
|
||||||
raiseRW();
|
raiseRW();
|
||||||
return base::busRead();
|
return LittleEndianProcessor::busRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -23,8 +23,8 @@ public:
|
||||||
void initialise() final;
|
void initialise() final;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual EightBit::MemoryMapping mapping(uint16_t address) noexcept final {
|
virtual constexpr EightBit::MemoryMapping mapping(uint16_t address) noexcept final {
|
||||||
return { m_ram, 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite };
|
return m_mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -33,6 +33,7 @@ private:
|
||||||
EightBit::MOS6502 m_cpu = *this;
|
EightBit::MOS6502 m_cpu = *this;
|
||||||
EightBit::Symbols m_symbols;
|
EightBit::Symbols m_symbols;
|
||||||
EightBit::Disassembly m_disassembler = { *this, m_cpu, m_symbols };
|
EightBit::Disassembly m_disassembler = { *this, m_cpu, m_symbols };
|
||||||
|
const EightBit::MemoryMapping m_mapping = { m_ram, 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite };
|
||||||
|
|
||||||
EightBit::register16_t m_oldPC = EightBit::Chip::Mask16;
|
EightBit::register16_t m_oldPC = EightBit::Chip::Mask16;
|
||||||
bool m_stopped = false;
|
bool m_stopped = false;
|
||||||
|
|
|
@ -36,7 +36,7 @@ int EightBit::mc6809::step() noexcept {
|
||||||
else if (UNLIKELY(lowered(INT()) && !interruptMasked()))
|
else if (UNLIKELY(lowered(INT()) && !interruptMasked()))
|
||||||
handleINT();
|
handleINT();
|
||||||
else
|
else
|
||||||
Processor::execute(fetchByte());
|
BigEndianProcessor::execute(fetchByte());
|
||||||
}
|
}
|
||||||
ExecutedInstruction.fire(*this);
|
ExecutedInstruction.fire(*this);
|
||||||
assert(cycles() > 0);
|
assert(cycles() > 0);
|
||||||
|
@ -115,13 +115,13 @@ void EightBit::mc6809::handleFIRQ() {
|
||||||
void EightBit::mc6809::busWrite() noexcept {
|
void EightBit::mc6809::busWrite() noexcept {
|
||||||
tick();
|
tick();
|
||||||
lowerRW();
|
lowerRW();
|
||||||
Processor::busWrite();
|
BigEndianProcessor::busWrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::mc6809::busRead() noexcept {
|
uint8_t EightBit::mc6809::busRead() noexcept {
|
||||||
tick();
|
tick();
|
||||||
raiseRW();
|
raiseRW();
|
||||||
return Processor::busRead();
|
return BigEndianProcessor::busRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -25,7 +25,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EightBit::MemoryMapping mapping(uint16_t address) noexcept final {
|
EightBit::MemoryMapping mapping(uint16_t address) noexcept final {
|
||||||
return { m_ram, 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite };
|
return m_mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -35,6 +35,7 @@ private:
|
||||||
EightBit::Z80 m_cpu = *this;
|
EightBit::Z80 m_cpu = *this;
|
||||||
EightBit::Disassembler m_disassembler = *this;
|
EightBit::Disassembler m_disassembler = *this;
|
||||||
EightBit::Profiler m_profiler = { m_cpu, m_disassembler };
|
EightBit::Profiler m_profiler = { m_cpu, m_disassembler };
|
||||||
|
const EightBit::MemoryMapping m_mapping = { m_ram, 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite };
|
||||||
int m_warmstartCount = 0;
|
int m_warmstartCount = 0;
|
||||||
|
|
||||||
void bdos();
|
void bdos();
|
||||||
|
|
|
@ -14,8 +14,6 @@ namespace EightBit {
|
||||||
void pokeWord(register16_t address, register16_t value) noexcept final;
|
void pokeWord(register16_t address, register16_t value) noexcept final;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
using base = BigEndianProcessor;
|
|
||||||
|
|
||||||
BigEndianProcessor(Bus& memory) noexcept;
|
BigEndianProcessor(Bus& memory) noexcept;
|
||||||
|
|
||||||
[[nodiscard]] register16_t getWord() override;
|
[[nodiscard]] register16_t getWord() override;
|
||||||
|
|
|
@ -70,8 +70,6 @@ namespace EightBit {
|
||||||
: Device(rhs) {}
|
: Device(rhs) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
using base = Chip;
|
|
||||||
|
|
||||||
Chip() noexcept = default;
|
Chip() noexcept = default;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,16 +14,17 @@ namespace EightBit {
|
||||||
|
|
||||||
[[nodiscard]] constexpr auto cycles() const noexcept { return m_cycles; }
|
[[nodiscard]] constexpr auto cycles() const noexcept { return m_cycles; }
|
||||||
|
|
||||||
void tick(int extra = 1) {
|
void tick() {
|
||||||
for (int i = 0; i < extra; ++i) {
|
++m_cycles;
|
||||||
++m_cycles;
|
Ticked.fire();
|
||||||
Ticked.fire();
|
}
|
||||||
}
|
|
||||||
|
void tick(int extra) {
|
||||||
|
for (int i = 0; i < extra; ++i)
|
||||||
|
tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
using base = ClockedChip;
|
|
||||||
|
|
||||||
ClockedChip() noexcept = default;
|
ClockedChip() noexcept = default;
|
||||||
|
|
||||||
constexpr void resetCycles() noexcept { m_cycles = 0; }
|
constexpr void resetCycles() noexcept { m_cycles = 0; }
|
||||||
|
|
|
@ -114,8 +114,6 @@ namespace EightBit {
|
||||||
[[nodiscard]] constexpr bool powered() const noexcept { return raised(POWER()); }
|
[[nodiscard]] constexpr bool powered() const noexcept { return raised(POWER()); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
using base = Device;
|
|
||||||
|
|
||||||
Device() noexcept {};
|
Device() noexcept {};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,18 +71,18 @@ inline int EightBit::findFirstSet(const unsigned long value) noexcept {
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
# define ASSUME(x) __assume(x);
|
# define ASSUME(x) __assume(x);
|
||||||
|
|
||||||
# define LIKELY(x) (x)
|
# define LIKELY(x) (x)
|
||||||
# define UNLIKELY(x) (x)
|
# define UNLIKELY(x) (x)
|
||||||
|
|
||||||
# define UNREACHABLE { ASSUME(0); assert(false && "unreachable"); }
|
# define UNREACHABLE { ASSUME(0); assert(false && "unreachable"); }
|
||||||
|
|
||||||
#elif defined(__GNUG__)
|
#elif defined(__GNUG__)
|
||||||
|
|
||||||
# define ASSUME(x) { if (!x) __builtin_unreachable(); }
|
# define ASSUME(x) { if (!x) __builtin_unreachable(); }
|
||||||
|
|
||||||
# define LIKELY(x) __builtin_expect(!!(x), 1)
|
# define LIKELY(x) __builtin_expect(!!(x), 1)
|
||||||
# define UNLIKELY(x) __builtin_expect(!!(x), 0)
|
# define UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||||
|
|
||||||
# define UNREACHABLE __builtin_unreachable();
|
# define UNREACHABLE __builtin_unreachable();
|
||||||
|
@ -91,7 +91,7 @@ inline int EightBit::findFirstSet(const unsigned long value) noexcept {
|
||||||
|
|
||||||
# define ASSUME(x) assert(x);
|
# define ASSUME(x) assert(x);
|
||||||
|
|
||||||
# define LIKELY(x) (x)
|
# define LIKELY(x) (x)
|
||||||
# define UNLIKELY(x) (x)
|
# define UNLIKELY(x) (x)
|
||||||
|
|
||||||
# define UNREACHABLE ASSUME(0)
|
# define UNREACHABLE ASSUME(0)
|
||||||
|
|
|
@ -80,8 +80,6 @@ namespace EightBit {
|
||||||
DECLARE_PIN_OUTPUT(HALT)
|
DECLARE_PIN_OUTPUT(HALT)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
using base = IntelProcessor;
|
|
||||||
|
|
||||||
IntelProcessor(Bus& bus);
|
IntelProcessor(Bus& bus);
|
||||||
|
|
||||||
template<class T> [[nodiscard]] static constexpr uint8_t adjustSign(uint8_t f, const uint8_t value) noexcept {
|
template<class T> [[nodiscard]] static constexpr uint8_t adjustSign(uint8_t f, const uint8_t value) noexcept {
|
||||||
|
|
|
@ -14,8 +14,6 @@ namespace EightBit {
|
||||||
void pokeWord(register16_t address, register16_t value) noexcept final;
|
void pokeWord(register16_t address, register16_t value) noexcept final;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
using base = LittleEndianProcessor;
|
|
||||||
|
|
||||||
LittleEndianProcessor(Bus& memory) noexcept;
|
LittleEndianProcessor(Bus& memory) noexcept;
|
||||||
|
|
||||||
[[nodiscard]] register16_t getWord() override;
|
[[nodiscard]] register16_t getWord() override;
|
||||||
|
|
|
@ -39,8 +39,6 @@ namespace EightBit {
|
||||||
DECLARE_PIN_INPUT(INT)
|
DECLARE_PIN_INPUT(INT)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
using base = Processor;
|
|
||||||
|
|
||||||
Processor(Bus& memory) noexcept;
|
Processor(Bus& memory) noexcept;
|
||||||
|
|
||||||
[[nodiscard]] constexpr auto& opcode() noexcept { return m_opcode; }
|
[[nodiscard]] constexpr auto& opcode() noexcept { return m_opcode; }
|
||||||
|
@ -59,11 +57,6 @@ namespace EightBit {
|
||||||
virtual uint8_t memoryRead();
|
virtual uint8_t memoryRead();
|
||||||
virtual uint8_t busRead();
|
virtual uint8_t busRead();
|
||||||
|
|
||||||
uint8_t getBytePaged() { return memoryRead(); }
|
|
||||||
uint8_t getBytePaged(uint8_t page, uint8_t offset);
|
|
||||||
void setBytePaged(uint8_t value) { memoryWrite(value); }
|
|
||||||
void setBytePaged(uint8_t page, uint8_t offset, uint8_t value);
|
|
||||||
|
|
||||||
uint8_t fetchByte();
|
uint8_t fetchByte();
|
||||||
|
|
||||||
[[nodiscard]] virtual register16_t getWord() = 0;
|
[[nodiscard]] virtual register16_t getWord() = 0;
|
||||||
|
|
|
@ -45,8 +45,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
handle_t h_;
|
handle_t h_;
|
||||||
|
|
||||||
private:
|
|
||||||
bool full_ = false;
|
bool full_ = false;
|
||||||
|
|
||||||
constexpr void fill() {
|
constexpr void fill() {
|
||||||
|
|
|
@ -18,14 +18,14 @@ void EightBit::BigEndianProcessor::setWord(const register16_t value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
EightBit::register16_t EightBit::BigEndianProcessor::getWordPaged() {
|
EightBit::register16_t EightBit::BigEndianProcessor::getWordPaged() {
|
||||||
const auto high = getBytePaged();
|
const auto high = memoryRead();
|
||||||
++BUS().ADDRESS().low;
|
++BUS().ADDRESS().low;
|
||||||
const auto low = memoryRead();
|
const auto low = memoryRead();
|
||||||
return { low, high };
|
return { low, high };
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::BigEndianProcessor::setWordPaged(const register16_t value) {
|
void EightBit::BigEndianProcessor::setWordPaged(const register16_t value) {
|
||||||
setBytePaged(value.high);
|
memoryWrite(value.high);
|
||||||
++BUS().ADDRESS().low;
|
++BUS().ADDRESS().low;
|
||||||
memoryWrite(value.low);
|
memoryWrite(value.low);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,6 @@ EightBit::ClockedChip::ClockedChip(const ClockedChip& rhs) noexcept
|
||||||
|
|
||||||
bool EightBit::ClockedChip::operator==(const EightBit::ClockedChip& rhs) const noexcept {
|
bool EightBit::ClockedChip::operator==(const EightBit::ClockedChip& rhs) const noexcept {
|
||||||
return
|
return
|
||||||
Device::operator==(rhs)
|
Chip::operator==(rhs)
|
||||||
&& cycles() == rhs.cycles();
|
&& cycles() == rhs.cycles();
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,13 +96,13 @@ int EightBit::IntelProcessor::jrConditional(const int condition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::IntelProcessor::ret() {
|
void EightBit::IntelProcessor::ret() {
|
||||||
Processor::ret();
|
LittleEndianProcessor::ret();
|
||||||
MEMPTR() = PC();
|
MEMPTR() = PC();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EightBit::IntelProcessor::operator==(const EightBit::IntelProcessor& rhs) const noexcept {
|
bool EightBit::IntelProcessor::operator==(const EightBit::IntelProcessor& rhs) const noexcept {
|
||||||
return
|
return
|
||||||
Processor::operator==(rhs)
|
LittleEndianProcessor::operator==(rhs)
|
||||||
&& HALT() == rhs.HALT()
|
&& HALT() == rhs.HALT()
|
||||||
&& MEMPTR() == rhs.MEMPTR()
|
&& MEMPTR() == rhs.MEMPTR()
|
||||||
&& SP() == rhs.SP()
|
&& SP() == rhs.SP()
|
||||||
|
|
|
@ -21,14 +21,14 @@ void EightBit::LittleEndianProcessor::setWord(const register16_t value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
EightBit::register16_t EightBit::LittleEndianProcessor::getWordPaged() {
|
EightBit::register16_t EightBit::LittleEndianProcessor::getWordPaged() {
|
||||||
const auto low = getBytePaged();
|
const auto low = memoryRead();
|
||||||
++BUS().ADDRESS().low;
|
++BUS().ADDRESS().low;
|
||||||
const auto high = memoryRead();
|
const auto high = memoryRead();
|
||||||
return { low, high };
|
return { low, high };
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::LittleEndianProcessor::setWordPaged(register16_t value) {
|
void EightBit::LittleEndianProcessor::setWordPaged(register16_t value) {
|
||||||
setBytePaged(value.low);
|
memoryWrite(value.low);
|
||||||
++BUS().ADDRESS().low;
|
++BUS().ADDRESS().low;
|
||||||
memoryWrite(value.high);
|
memoryWrite(value.high);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,14 +60,6 @@ uint8_t EightBit::Processor::busRead() {
|
||||||
return BUS().read();
|
return BUS().read();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::Processor::getBytePaged(const uint8_t page, const uint8_t offset) {
|
|
||||||
return memoryRead(register16_t(offset, page));
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::Processor::setBytePaged(const uint8_t page, const uint8_t offset, const uint8_t value) {
|
|
||||||
memoryWrite(register16_t(offset, page), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
EightBit::register16_t EightBit::Processor::getWordPaged(register16_t address) {
|
EightBit::register16_t EightBit::Processor::getWordPaged(register16_t address) {
|
||||||
BUS().ADDRESS() = address;
|
BUS().ADDRESS() = address;
|
||||||
return getWordPaged();
|
return getWordPaged();
|
||||||
|
|
Loading…
Reference in New Issue