Ensure virtual methods are no longer defined inline.

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2018-11-25 10:43:51 +00:00
parent 85bc2aab12
commit 887b89308a
13 changed files with 118 additions and 67 deletions

View File

@ -162,10 +162,7 @@ namespace EightBit {
return !!condition; return !!condition;
} }
virtual void ret() final { virtual void ret() final;
Processor::ret();
MEMPTR() = PC();
}
private: private:
std::array<opcode_decoded_t, 0x100> m_decodedOpcodes; std::array<opcode_decoded_t, 0x100> m_decodedOpcodes;

View File

@ -2,7 +2,6 @@
#include <cstdint> #include <cstdint>
#include <fstream> #include <fstream>
#include <stdexcept>
#include <string> #include <string>
#include <vector> #include <vector>
@ -20,9 +19,7 @@ namespace EightBit {
virtual size_t size() const = 0; virtual size_t size() const = 0;
virtual uint8_t peek(uint16_t address) const = 0; virtual uint8_t peek(uint16_t address) const = 0;
virtual uint8_t& reference(uint16_t) { virtual uint8_t& reference(uint16_t);
throw new std::logic_error("Reference operation not allowed.");
}
virtual int load(std::ifstream& file, int writeOffset = 0, int readOffset = 0, int limit = -1) = 0; virtual int load(std::ifstream& file, int writeOffset = 0, int readOffset = 0, int limit = -1) = 0;
virtual int load(const std::string& path, int writeOffset = 0, int readOffset = 0, int limit = -1) = 0; virtual int load(const std::string& path, int writeOffset = 0, int readOffset = 0, int limit = -1) = 0;

View File

@ -71,7 +71,7 @@ namespace EightBit {
virtual void push(uint8_t value) = 0; virtual void push(uint8_t value) = 0;
virtual uint8_t pop() = 0; virtual uint8_t pop() = 0;
virtual void pushWord(const register16_t value) = 0; virtual void pushWord(register16_t value) = 0;
virtual register16_t popWord() = 0; virtual register16_t popWord() = 0;
auto getWord(const register16_t address) { auto getWord(const register16_t address) {
@ -93,9 +93,7 @@ namespace EightBit {
jump(destination); jump(destination);
} }
virtual void ret() { virtual void ret();
jump(popWord());
}
void resetCycles() { m_cycles = 0; } void resetCycles() { m_cycles = 0; }
void addCycles(const int extra) { m_cycles += extra; } void addCycles(const int extra) { m_cycles += extra; }

View File

@ -9,16 +9,9 @@ namespace EightBit {
// it's externally 'reference'able and 'poke'able. // it's externally 'reference'able and 'poke'able.
class Ram : public Rom { class Ram : public Rom {
public: public:
Ram(const size_t size = 0) noexcept Ram(size_t size = 0) noexcept;
: Rom(size) {
}
virtual uint8_t& reference(const uint16_t address) final { virtual uint8_t& reference(uint16_t address) final;
return BYTES()[address]; virtual void poke(uint16_t address, uint8_t value) final;
}
virtual void poke(const uint16_t address, const uint8_t value) final {
Rom::poke(address, value);
}
}; };
} }

View File

@ -20,7 +20,7 @@
#endif #endif
namespace EightBit { namespace EightBit {
union register16_t { union register16_t final {
struct { struct {
#ifdef HOST_LITTLE_ENDIAN #ifdef HOST_LITTLE_ENDIAN
uint8_t low; uint8_t low;

View File

@ -19,39 +19,20 @@ namespace EightBit {
const auto& BYTES() const { return m_bytes; } const auto& BYTES() const { return m_bytes; }
auto& BYTES() { return m_bytes; } auto& BYTES() { return m_bytes; }
virtual void poke(const uint16_t address, const uint8_t value) override { virtual void poke(uint16_t address, uint8_t value) override;
BYTES()[address] = value;
}
public: public:
static int load(std::ifstream& file, std::vector<uint8_t>& output, int writeOffset = 0, int readOffset = 0, int limit = -1, int maximumSize = -1); static int load(std::ifstream& file, std::vector<uint8_t>& output, int writeOffset = 0, int readOffset = 0, int limit = -1, int maximumSize = -1);
static int load(const std::string& path, std::vector<uint8_t>& output, int writeOffset = 0, int readOffset = 0, int limit = -1, int maximumSize = -1); static int load(const std::string& path, std::vector<uint8_t>& output, int writeOffset = 0, int readOffset = 0, int limit = -1, int maximumSize = -1);
Rom(const size_t size = 0) noexcept Rom(size_t size = 0) noexcept;
: m_bytes(size) {
}
virtual size_t size() const final { return m_bytes.size(); } virtual size_t size() const final;
virtual int load(std::ifstream& file, const int writeOffset = 0, const int readOffset = 0, const int limit = -1) final { virtual int load(std::ifstream& file, int writeOffset = 0, int readOffset = 0, int limit = -1) final;
const auto maximumSize = (int)size() - writeOffset; virtual int load(const std::string& path, int writeOffset = 0, int readOffset = 0, int limit = -1) final;
return load(file, m_bytes, writeOffset, readOffset, limit, maximumSize); virtual int load(const std::vector<uint8_t>& bytes, int writeOffset = 0, int readOffset = 0, int limit = -1) final;
}
virtual int load(const std::string& path, const int writeOffset = 0, const int readOffset = 0, const int limit = -1) final { virtual uint8_t peek(uint16_t address) const final;
const auto maximumSize = (int)size() - writeOffset;
return load(path, m_bytes, writeOffset, readOffset, limit, maximumSize);
}
virtual int load(const std::vector<uint8_t>& bytes, const int writeOffset = 0, const int readOffset = 0, int limit = -1) final {
if (limit < 0)
limit = (int)bytes.size() - readOffset;
std::copy(bytes.cbegin() + readOffset, bytes.cbegin() + limit, m_bytes.begin() + writeOffset);
return limit;
}
virtual uint8_t peek(const uint16_t address) const final {
return BYTES()[address];
}
}; };
} }

View File

@ -1,5 +1,10 @@
#pragma once #pragma once
#include <cstdint>
#include <fstream>
#include <string>
#include <vector>
#include "Memory.h" #include "Memory.h"
namespace EightBit { namespace EightBit {
@ -8,29 +13,18 @@ namespace EightBit {
// is being read. // is being read.
class UnusedMemory final : public Memory { class UnusedMemory final : public Memory {
public: public:
UnusedMemory(const size_t size, const uint8_t value) UnusedMemory(size_t size, uint8_t value);
: m_size(size), m_value(value) {}
virtual ~UnusedMemory() = default; virtual ~UnusedMemory() = default;
virtual size_t size() const final { return m_size; } virtual size_t size() const final;
virtual uint8_t peek(uint16_t address) const final { return m_value; } virtual uint8_t peek(uint16_t address) const final;
virtual int load(std::ifstream& file, int writeOffset = 0, int readOffset = 0, int limit = -1) final { virtual int load(std::ifstream& file, int writeOffset = 0, int readOffset = 0, int limit = -1) final;
throw new std::logic_error("load operation not allowed."); virtual int load(const std::string& path, int writeOffset = 0, int readOffset = 0, int limit = -1) final;
} virtual int load(const std::vector<uint8_t>& bytes, int writeOffset = 0, int readOffset = 0, int limit = -1) final;
virtual int load(const std::string& path, int writeOffset = 0, int readOffset = 0, int limit = -1) final {
throw new std::logic_error("load operation not allowed.");
}
virtual int load(const std::vector<uint8_t>& bytes, int writeOffset = 0, int readOffset = 0, int limit = -1) final {
throw new std::logic_error("load operation not allowed.");
}
protected: protected:
virtual void poke(uint16_t address, uint8_t value) { virtual void poke(uint16_t address, uint8_t value) final;
throw new std::logic_error("Poke operation not allowed.");
}
private: private:
size_t m_size; size_t m_size;

View File

@ -30,3 +30,8 @@ void EightBit::IntelProcessor::setWord(const register16_t value) {
LittleEndianProcessor::setWord(value); LittleEndianProcessor::setWord(value);
MEMPTR() = BUS().ADDRESS(); MEMPTR() = BUS().ADDRESS();
} }
void EightBit::IntelProcessor::ret() {
Processor::ret();
MEMPTR() = PC();
}

8
src/Memory.cpp Normal file
View File

@ -0,0 +1,8 @@
#include "stdafx.h"
#include "Memory.h"
#include <stdexcept>
uint8_t& EightBit::Memory::reference(uint16_t) {
throw new std::logic_error("Reference operation not allowed.");
}

View File

@ -39,3 +39,7 @@ int8_t EightBit::Processor::signExtend(const int b, uint8_t x) {
const auto result = (x ^ m) - m; const auto result = (x ^ m) - m;
return result; return result;
} }
void EightBit::Processor::ret() {
jump(popWord());
}

13
src/Ram.cpp Normal file
View File

@ -0,0 +1,13 @@
#include "stdafx.h"
#include "Ram.h"
EightBit::Ram::Ram(const size_t size) noexcept
: Rom(size) {}
uint8_t& EightBit::Ram::reference(const uint16_t address) {
return BYTES()[address];
}
void EightBit::Ram::poke(const uint16_t address, const uint8_t value) {
Rom::poke(address, value);
}

View File

@ -36,3 +36,35 @@ int EightBit::Rom::load(const std::string& path, std::vector<uint8_t>& output, c
return size; return size;
} }
void EightBit::Rom::poke(const uint16_t address, const uint8_t value) {
BYTES()[address] = value;
}
EightBit::Rom::Rom(const size_t size) noexcept
: m_bytes(size) {}
size_t EightBit::Rom::size() const {
return m_bytes.size();
}
int EightBit::Rom::load(std::ifstream& file, const int writeOffset, const int readOffset, const int limit) {
const auto maximumSize = (int)size() - writeOffset;
return load(file, m_bytes, writeOffset, readOffset, limit, maximumSize);
}
int EightBit::Rom::load(const std::string& path, const int writeOffset, const int readOffset, const int limit) {
const auto maximumSize = (int)size() - writeOffset;
return load(path, m_bytes, writeOffset, readOffset, limit, maximumSize);
}
int EightBit::Rom::load(const std::vector<uint8_t>& bytes, const int writeOffset, const int readOffset, int limit) {
if (limit < 0)
limit = (int)bytes.size() - readOffset;
std::copy(bytes.cbegin() + readOffset, bytes.cbegin() + limit, m_bytes.begin() + writeOffset);
return limit;
}
uint8_t EightBit::Rom::peek(const uint16_t address) const {
return BYTES()[address];
}

29
src/UnusedMemory.cpp Normal file
View File

@ -0,0 +1,29 @@
#include "stdafx.h"
#include "UnusedMemory.h"
EightBit::UnusedMemory::UnusedMemory(const size_t size, const uint8_t value)
: m_size(size), m_value(value) {}
size_t EightBit::UnusedMemory::size() const {
return m_size;
}
uint8_t EightBit::UnusedMemory::peek(uint16_t) const {
return m_value;
}
int EightBit::UnusedMemory::load(std::ifstream&, int, int, int) {
throw new std::logic_error("load operation not allowed.");
}
int EightBit::UnusedMemory::load(const std::string&, int, int, int) {
throw new std::logic_error("load operation not allowed.");
}
int EightBit::UnusedMemory::load(const std::vector<uint8_t>&, int, int, int) {
throw new std::logic_error("load operation not allowed.");
}
void EightBit::UnusedMemory::poke(uint16_t, uint8_t) {
throw new std::logic_error("Poke operation not allowed.");
}