First set of C++17/14 changes to the core library

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2018-10-27 17:30:23 +01:00
parent 8dbb3eafec
commit 62f3cd717b
14 changed files with 99 additions and 99 deletions

View File

@ -21,21 +21,21 @@ namespace EightBit {
Signal<EventArgs> ReadingByte;
Signal<EventArgs> ReadByte;
register16_t ADDRESS() const { return m_address; }
register16_t& ADDRESS() { return m_address; }
auto ADDRESS() const { return m_address; }
auto& ADDRESS() { return m_address; }
uint8_t DATA() const { return m_data; }
uint8_t& DATA() { return m_data; }
auto DATA() const { return m_data; }
auto& DATA() { return m_data; }
uint8_t peek() { return reference(); }
uint8_t peek(const uint16_t address) { return reference(address); }
uint8_t peek(const register16_t address) { return reference(address.word); }
auto peek() { return reference(); }
auto peek(const uint16_t address) { return reference(address); }
auto peek(const register16_t address) { return reference(address.word); }
void poke(const uint8_t value) { reference() = value; }
void poke(const uint16_t address, const uint8_t value) { reference(address) = value; }
void poke(const register16_t address, const uint8_t value) { reference(address.word) = value; }
uint8_t read();
template<class T> uint8_t read(const T address) {
template<class T> auto read(const T address) {
ADDRESS() = address;
return read();
}
@ -50,7 +50,7 @@ namespace EightBit {
protected:
virtual MemoryMapping mapping(uint16_t address) = 0;
uint8_t& reference(uint16_t address);
uint8_t& reference(const register16_t address) { return reference(address.word); }
auto& reference(const register16_t address) { return reference(address.word); }
uint8_t& reference() { return reference(ADDRESS()); }
static std::map<uint16_t, std::vector<uint8_t>> parseHexFile(std::string path);

View File

@ -59,25 +59,25 @@ namespace EightBit {
static void clearFlag(uint8_t& f, const int flag, const uint32_t condition) { clearFlag(f, flag, !!condition); }
static void clearFlag(uint8_t& f, const int flag, const bool condition) { setFlag(f, flag, !condition); }
static bool raised(const PinLevel line) { return line == High; }
static auto raised(const PinLevel line) { return line == High; }
static void raise(PinLevel& line) { line = High; }
static bool lowered(const PinLevel line) { return line == Low; }
static auto lowered(const PinLevel line) { return line == Low; }
static void lower(PinLevel& line) { line = Low; }
static void match(PinLevel& line, int value);
static int highNibble(const int value) { return value >> 4; }
static int lowNibble(const int value) { return value & Mask4; }
static auto highNibble(const int value) { return value >> 4; }
static auto lowNibble(const int value) { return value & Mask4; }
static int higherNibble(const int value) { return value & 0xf0; }
static int lowerNibble(const int value) { return lowNibble(value); }
static auto higherNibble(const int value) { return value & 0xf0; }
static auto lowerNibble(const int value) { return lowNibble(value); }
static int promoteNibble(const int value) { return value << 4; }
static int demoteNibble(const int value) { return highNibble(value); }
static auto promoteNibble(const int value) { return value << 4; }
static auto demoteNibble(const int value) { return highNibble(value); }
PinLevel& POWER() { return m_powerLine; }
auto& POWER() { return m_powerLine; }
bool powered() { return raised(POWER()); }
auto powered() { return raised(POWER()); }
virtual void powerOn();
void powerOff() { lower(POWER()); }

View File

@ -6,6 +6,6 @@ namespace EightBit {
static EventArgs m_empty;
public:
static EventArgs& empty() { return m_empty; }
static auto& empty() { return m_empty; }
};
}

View File

@ -10,13 +10,13 @@ namespace EightBit {
public:
InputOutput() = default;
uint8_t read(const uint8_t port) { return readInputPort(port); }
auto read(const uint8_t port) { return readInputPort(port); }
void write(const uint8_t port, const uint8_t value) { return writeOutputPort(port, value); }
uint8_t readInputPort(uint8_t port);
void writeInputPort(const uint8_t port, const uint8_t value) { m_input[port] = value; }
uint8_t readOutputPort(const uint8_t port) { return m_output[port]; }
auto readOutputPort(const uint8_t port) { return m_output[port]; }
void writeOutputPort(uint8_t port, uint8_t value);
Signal<uint8_t> ReadingPort;

View File

@ -32,29 +32,29 @@ namespace EightBit {
}
};
const opcode_decoded_t& getDecodedOpcode(const int i) const {
const auto& getDecodedOpcode(const int i) const {
return m_decodedOpcodes[i];
}
register16_t& MEMPTR() { return m_memptr; }
auto& MEMPTR() { return m_memptr; }
register16_t& SP() { return m_sp; }
auto& SP() { return m_sp; }
virtual register16_t& AF() = 0;
uint8_t& A() { return AF().high; }
uint8_t& F() { return AF().low; }
auto& A() { return AF().high; }
auto& F() { return AF().low; }
virtual register16_t& BC() = 0;
uint8_t& B() { return BC().high; }
uint8_t& C() { return BC().low; }
auto& B() { return BC().high; }
auto& C() { return BC().low; }
virtual register16_t& DE() = 0;
uint8_t& D() { return DE().high; }
uint8_t& E() { return DE().low; }
auto& D() { return DE().high; }
auto& E() { return DE().low; }
virtual register16_t& HL() = 0;
uint8_t& H() { return HL().high; }
uint8_t& L() { return HL().low; }
auto& H() { return HL().high; }
auto& L() { return HL().low; }
virtual void powerOn() override;
@ -101,17 +101,17 @@ namespace EightBit {
//
static int buildHalfCarryIndex(const uint8_t before, const uint8_t value, const int calculation) {
static auto buildHalfCarryIndex(const uint8_t before, const uint8_t value, const int calculation) {
return ((before & 0x88) >> 1) | ((value & 0x88) >> 2) | ((calculation & 0x88) >> 3);
}
static bool calculateHalfCarryAdd(const uint8_t before, const uint8_t value, const int calculation) {
static auto calculateHalfCarryAdd(const uint8_t before, const uint8_t value, const int calculation) {
static std::array<bool, 8> m_halfCarryTableAdd = { { false, false, true, false, true, false, true, true } };
const auto index = buildHalfCarryIndex(before, value, calculation);
return m_halfCarryTableAdd[index & Mask3];
}
static bool calculateHalfCarrySub(const uint8_t before, const uint8_t value, const int calculation) {
static auto calculateHalfCarrySub(const uint8_t before, const uint8_t value, const int calculation) {
std::array<bool, 8> m_halfCarryTableSub = { { false, true, true, true, false, false, false, true } };
const auto index = buildHalfCarryIndex(before, value, calculation);
return m_halfCarryTableSub[index & Mask3];
@ -128,24 +128,24 @@ namespace EightBit {
//
void restart(const uint8_t address) {
call(MEMPTR() = register16_t(address, 0));
call(MEMPTR() = { address, 0 });
}
bool callConditional(const int condition) {
auto callConditional(const int condition) {
MEMPTR() = fetchWord();
if (condition)
call(MEMPTR());
return !!condition;
}
bool jumpConditional(const int condition) {
auto jumpConditional(const int condition) {
MEMPTR() = fetchWord();
if (condition)
jump(MEMPTR());
return !!condition;
}
bool returnConditional(const int condition) {
auto returnConditional(const int condition) {
if (condition)
ret();
return !!condition;
@ -155,7 +155,7 @@ namespace EightBit {
jump(MEMPTR() = PC() + offset);
}
bool jrConditional(const int condition) {
auto jrConditional(const int condition) {
const auto offset = fetchByte();
if (condition)
jr(offset);

View File

@ -7,6 +7,17 @@
namespace EightBit {
class Memory {
private:
std::vector<uint8_t> m_bytes;
protected:
const auto& BYTES() const { return m_bytes; }
auto& BYTES() { return m_bytes; }
void poke(const uint16_t address, const uint8_t value) {
BYTES()[address] = value;
}
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(const std::string& path, std::vector<uint8_t>& output, int writeOffset = 0, int readOffset = 0, int limit = -1, int maximumSize = -1);
@ -15,39 +26,28 @@ namespace EightBit {
: m_bytes(size) {
}
size_t size() const { return m_bytes.size(); }
auto size() const { return m_bytes.size(); }
int load(std::ifstream& file, const int writeOffset = 0, const int readOffset = 0, const int limit = -1) {
auto load(std::ifstream& file, const int writeOffset = 0, const int readOffset = 0, const int limit = -1) {
const auto maximumSize = (int)m_bytes.size() - writeOffset;
return load(file, m_bytes, writeOffset, readOffset, limit, maximumSize);
}
int load(const std::string& path, const int writeOffset = 0, const int readOffset = 0, const int limit = -1) {
auto load(const std::string& path, const int writeOffset = 0, const int readOffset = 0, const int limit = -1) {
const auto maximumSize = (int)m_bytes.size() - writeOffset;
return load(path, m_bytes, writeOffset, readOffset, limit, maximumSize);
}
int load(const std::vector<uint8_t>& bytes, const int writeOffset = 0, const int readOffset = 0, int limit = -1) {
auto load(const std::vector<uint8_t>& bytes, const int writeOffset = 0, const int readOffset = 0, int limit = -1) {
if (limit < 0)
limit = (int)bytes.size() - readOffset;
std::copy(bytes.cbegin() + readOffset, bytes.cbegin() + limit, m_bytes.begin() + writeOffset);
return limit;
}
uint8_t peek(const uint16_t address) const {
auto peek(const uint16_t address) const {
return BYTES()[address];
}
protected:
const std::vector<uint8_t>& BYTES() const { return m_bytes; }
std::vector<uint8_t>& BYTES() { return m_bytes; }
void poke(const uint16_t address, const uint8_t value) {
BYTES()[address] = value;
}
private:
std::vector<uint8_t> m_bytes;
};
typedef Memory Rom;

View File

@ -7,7 +7,7 @@
namespace EightBit {
struct MemoryMapping {
enum AccessLevel { Unknown, ReadWrite, ReadOnly };
enum AccessLevel { Unknown, ReadOnly, ReadWrite, };
Memory& memory;
uint16_t begin = 0xffff;

View File

@ -15,12 +15,12 @@ namespace EightBit {
// x: sign extend this b-bit number to r
static int8_t signExtend(int b, uint8_t x);
register16_t& PC() { return m_pc; }
auto& PC() { return m_pc; }
PinLevel& RESET() { return m_resetLine; }
PinLevel& HALT() { return m_haltLine; }
PinLevel& INT() { return m_intLine; }
PinLevel& IRQ() { return INT(); } // Synonym
auto& RESET() { return m_resetLine; }
auto& HALT() { return m_haltLine; }
auto& INT() { return m_intLine; }
auto& IRQ() { return INT(); } // Synonym
virtual void powerOn();
void reset() { lower(RESET()); }
@ -29,7 +29,7 @@ namespace EightBit {
virtual int step() = 0;
virtual int execute(uint8_t opcode) = 0;
int cycles() const { return m_cycles; }
auto cycles() const { return m_cycles; }
virtual register16_t peekWord(register16_t address) = 0;
virtual void pokeWord(register16_t address, register16_t value) = 0;
@ -38,17 +38,17 @@ namespace EightBit {
Processor(Bus& memory);
virtual ~Processor() = default;
Bus& BUS() { return m_bus; }
auto& BUS() { return m_bus; }
bool halted() { return lowered(HALT()); }
void halt() { --PC(); lower(HALT()); }
void proceed() { ++PC(); raise(HALT()); }
auto halted() { return lowered(HALT()); }
auto halt() { --PC(); lower(HALT()); }
auto proceed() { ++PC(); raise(HALT()); }
virtual void handleRESET();
virtual void handleINT();
virtual void handleIRQ();
uint8_t getBytePaged(const uint8_t page, const uint8_t offset) {
auto getBytePaged(const uint8_t page, const uint8_t offset) {
return BUS().read(register16_t(offset, page));
}
@ -56,7 +56,7 @@ namespace EightBit {
BUS().write(register16_t(offset, page), value);
}
uint8_t fetchByte() {
auto fetchByte() {
return BUS().read(PC()++);
}
@ -74,7 +74,7 @@ namespace EightBit {
virtual void pushWord(const register16_t value) = 0;
virtual register16_t popWord() = 0;
register16_t getWord(const register16_t address) {
auto getWord(const register16_t address) {
BUS().ADDRESS() = address;
return getWord();
}

View File

@ -10,7 +10,7 @@ namespace EightBit {
: Memory(size) {
}
uint8_t& reference(const uint16_t address) {
auto& reference(const uint16_t address) {
return BYTES()[address];
}

View File

@ -36,58 +36,58 @@ namespace EightBit {
register16_t(const uint16_t w) noexcept : word(w) {}
register16_t(const uint8_t l, const uint8_t h) noexcept : low(l), high(h) {}
register16_t& operator++() noexcept {
auto& operator++() noexcept {
++word;
return *this;
}
register16_t& operator--() noexcept {
auto& operator--() noexcept {
--word;
return *this;
}
register16_t operator++(int) noexcept {
auto operator++(int) noexcept {
register16_t temporary(*this);
operator++();
return temporary;
}
register16_t operator--(int) noexcept {
auto operator--(int) noexcept {
register16_t temporary(*this);
operator--();
return temporary;
}
register16_t& operator+=(const register16_t rhs) noexcept {
auto& operator+=(const register16_t rhs) noexcept {
this->word += rhs.word;
return *this;
}
register16_t& operator-=(const register16_t rhs) noexcept {
auto& operator-=(const register16_t rhs) noexcept {
this->word -= rhs.word;
return *this;
}
};
inline bool operator==(const register16_t lhs, const register16_t rhs) noexcept {
inline auto operator==(const register16_t lhs, const register16_t rhs) noexcept {
return lhs.word == rhs.word;
}
inline bool operator!=(const register16_t lhs, const register16_t rhs) noexcept {
inline auto operator!=(const register16_t lhs, const register16_t rhs) noexcept {
return !(lhs == rhs);
}
inline register16_t operator+(register16_t lhs, const register16_t rhs) noexcept {
inline auto operator+(register16_t lhs, const register16_t rhs) noexcept {
lhs += rhs;
return lhs;
}
inline register16_t operator-(register16_t lhs, const register16_t rhs) noexcept {
inline auto operator-(register16_t lhs, const register16_t rhs) noexcept {
lhs -= rhs;
return lhs;
}
inline std::ostream& operator<<(std::ostream& output, const register16_t value) {
inline auto& operator<<(std::ostream& output, const register16_t value) {
return output << std::hex << std::setw(4) << std::setfill('0') << value.word;
}
}

View File

@ -42,15 +42,15 @@ namespace EightBit {
return m_finishTime - m_startTime;
}
double getElapsedSeconds() const {
auto getElapsedSeconds() const {
return std::chrono::duration_cast<std::chrono::duration<double>>(getElapsedTime()).count();
}
double getCyclesPerSecond() const {
auto getCyclesPerSecond() const {
return (m_totalCycles / 1000000 ) / getElapsedSeconds();
}
long long getInstructionsPerSecond() {
auto getInstructionsPerSecond() {
auto floating = m_instructions / getElapsedSeconds();
return (long long)floating;
}
@ -84,7 +84,7 @@ namespace EightBit {
uint64_t m_startHostCycles = 0;
uint64_t m_finishHostCycles = 0;
static std::chrono::steady_clock::time_point now() {
static auto now() {
return std::chrono::steady_clock::now();
}

View File

@ -8,7 +8,7 @@ EightBit::register16_t EightBit::BigEndianProcessor::getWord() {
const auto high = BUS().read();
++BUS().ADDRESS();
const auto low = BUS().read();
return register16_t(low, high);
return { low, high };
}
void EightBit::BigEndianProcessor::setWord(const register16_t value) {
@ -21,7 +21,7 @@ EightBit::register16_t EightBit::BigEndianProcessor::getWordPaged(const uint8_t
const auto high = getBytePaged(page, offset);
++BUS().ADDRESS().low;
const auto low = BUS().read();
return register16_t(low, high);
return { low, high };
}
void EightBit::BigEndianProcessor::setWordPaged(const uint8_t page, const uint8_t offset, const register16_t value) {
@ -33,7 +33,7 @@ void EightBit::BigEndianProcessor::setWordPaged(const uint8_t page, const uint8_
EightBit::register16_t EightBit::BigEndianProcessor::fetchWord() {
const auto high = fetchByte();
const auto low = fetchByte();
return register16_t(low, high);
return { low, high };
}
void EightBit::BigEndianProcessor::pushWord(const register16_t value) {
@ -44,13 +44,13 @@ void EightBit::BigEndianProcessor::pushWord(const register16_t value) {
EightBit::register16_t EightBit::BigEndianProcessor::popWord() {
const auto high = pop();
const auto low = pop();
return register16_t(low, high);
return { low, high };
}
EightBit::register16_t EightBit::BigEndianProcessor::peekWord(const register16_t address) {
const auto high = BUS().peek(address);
const auto low = BUS().peek(address + 1);
return register16_t(low, high);
return { low, high };
}
void EightBit::BigEndianProcessor::pokeWord(const register16_t address, const register16_t value) {

View File

@ -10,9 +10,9 @@
uint8_t EightBit::Bus::read() {
ReadingByte.fire(EventArgs::empty());
DATA() = reference();
const auto returned = DATA() = reference();
ReadByte.fire(EventArgs::empty());
return DATA();
return returned;
}
void EightBit::Bus::write() {

View File

@ -8,7 +8,7 @@ EightBit::register16_t EightBit::LittleEndianProcessor::getWord() {
const auto low = BUS().read();
++BUS().ADDRESS();
const auto high = BUS().read();
return register16_t(low, high);
return { low, high };
}
void EightBit::LittleEndianProcessor::setWord(const register16_t value) {
@ -21,7 +21,7 @@ EightBit::register16_t EightBit::LittleEndianProcessor::getWordPaged(const uint8
const auto low = getBytePaged(page, offset);
++BUS().ADDRESS().low;
const auto high = BUS().read();
return register16_t(low, high);
return { low, high };
}
void EightBit::LittleEndianProcessor::setWordPaged(const uint8_t page, const uint8_t offset, const register16_t value) {
@ -33,7 +33,7 @@ void EightBit::LittleEndianProcessor::setWordPaged(const uint8_t page, const uin
EightBit::register16_t EightBit::LittleEndianProcessor::fetchWord() {
const auto low = fetchByte();
const auto high = fetchByte();
return register16_t(low, high);
return { low, high };
}
void EightBit::LittleEndianProcessor::pushWord(const register16_t value) {
@ -44,13 +44,13 @@ void EightBit::LittleEndianProcessor::pushWord(const register16_t value) {
EightBit::register16_t EightBit::LittleEndianProcessor::popWord() {
const auto low = pop();
const auto high = pop();
return register16_t(low, high);
return { low, high };
}
EightBit::register16_t EightBit::LittleEndianProcessor::peekWord(const register16_t address) {
const auto low = BUS().peek(address);
const auto high = BUS().peek(address + 1);
return register16_t(low, high);
return { low, high };
}
void EightBit::LittleEndianProcessor::pokeWord(const register16_t address, const register16_t value) {