mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-08-13 12:24:58 +00:00
Start refactoring the processor classes to allow big/little endian processors to be specified.
Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
@@ -7,11 +7,11 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <Bus.h>
|
#include <Bus.h>
|
||||||
#include <Processor.h>
|
#include <LittleEndianProcessor.h>
|
||||||
#include <Signal.h>
|
#include <Signal.h>
|
||||||
|
|
||||||
namespace EightBit {
|
namespace EightBit {
|
||||||
class MOS6502 : public Processor {
|
class MOS6502 : public LittleEndianProcessor {
|
||||||
public:
|
public:
|
||||||
enum StatusBits {
|
enum StatusBits {
|
||||||
NF = Bit7, // Negative
|
NF = Bit7, // Negative
|
||||||
@@ -65,10 +65,6 @@ namespace EightBit {
|
|||||||
adjustNegative(datum);
|
adjustNegative(datum);
|
||||||
}
|
}
|
||||||
|
|
||||||
register16_t getWordPaged(uint8_t page, uint8_t offset);
|
|
||||||
uint8_t getBytePaged(uint8_t page, uint8_t offset);
|
|
||||||
void setBytePaged(uint8_t page, uint8_t offset, uint8_t value);
|
|
||||||
|
|
||||||
virtual void push(uint8_t value) final;
|
virtual void push(uint8_t value) final;
|
||||||
virtual uint8_t pop() final;
|
virtual uint8_t pop() final;
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
#include "mos6502.h"
|
#include "mos6502.h"
|
||||||
|
|
||||||
EightBit::MOS6502::MOS6502(Bus& bus)
|
EightBit::MOS6502::MOS6502(Bus& bus)
|
||||||
: Processor(bus) {}
|
: LittleEndianProcessor(bus) {}
|
||||||
|
|
||||||
void EightBit::MOS6502::powerOn() {
|
void EightBit::MOS6502::powerOn() {
|
||||||
|
|
||||||
@@ -50,21 +50,6 @@ void EightBit::MOS6502::reset() {
|
|||||||
jump(getWordPaged(0xff, RSTvector));
|
jump(getWordPaged(0xff, RSTvector));
|
||||||
}
|
}
|
||||||
|
|
||||||
EightBit::register16_t EightBit::MOS6502::getWordPaged(uint8_t page, uint8_t offset) {
|
|
||||||
const auto low = getBytePaged(page, offset);
|
|
||||||
++BUS().ADDRESS().low;
|
|
||||||
const auto high = BUS().read();
|
|
||||||
return register16_t(low, high);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t EightBit::MOS6502::getBytePaged(uint8_t page, uint8_t offset) {
|
|
||||||
return BUS().read(register16_t(offset, page));
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::MOS6502::setBytePaged(uint8_t page, uint8_t offset, uint8_t value) {
|
|
||||||
BUS().write(register16_t(offset, page), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::MOS6502::interrupt(uint8_t vector) {
|
void EightBit::MOS6502::interrupt(uint8_t vector) {
|
||||||
raise(HALT());
|
raise(HALT());
|
||||||
pushWord(PC());
|
pushWord(PC());
|
||||||
|
56
inc/BigEndianProcessor.h
Normal file
56
inc/BigEndianProcessor.h
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Bus.h"
|
||||||
|
#include "Register.h"
|
||||||
|
#include "Processor.h"
|
||||||
|
|
||||||
|
namespace EightBit {
|
||||||
|
class BigEndianProcessor : public Processor {
|
||||||
|
protected:
|
||||||
|
BigEndianProcessor(Bus& memory) : Processor(memory) {}
|
||||||
|
virtual ~BigEndianProcessor() = default;
|
||||||
|
|
||||||
|
virtual register16_t getWord() {
|
||||||
|
const auto high = BUS().read();
|
||||||
|
++BUS().ADDRESS();
|
||||||
|
const auto low = BUS().read();
|
||||||
|
return register16_t(low, high);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setWord(const register16_t value) {
|
||||||
|
BUS().write(value.high);
|
||||||
|
++BUS().ADDRESS();
|
||||||
|
BUS().write(value.low);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual register16_t getWordPaged(uint8_t page, uint8_t offset) override {
|
||||||
|
const auto high = getBytePaged(page, offset);
|
||||||
|
++BUS().ADDRESS().low;
|
||||||
|
const auto low = BUS().read();
|
||||||
|
return register16_t(low, high);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setWordPaged(uint8_t page, uint8_t offset, register16_t value) override {
|
||||||
|
setBytePaged(page, offset, value.high);
|
||||||
|
++BUS().ADDRESS().low;
|
||||||
|
BUS().read(value.low);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual register16_t fetchWord() final {
|
||||||
|
const auto high = fetchByte();
|
||||||
|
const auto low = fetchByte();
|
||||||
|
return register16_t(low, high);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void pushWord(const register16_t value) final {
|
||||||
|
push(value.low);
|
||||||
|
push(value.high);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual register16_t popWord() final {
|
||||||
|
const auto high = pop();
|
||||||
|
const auto low = pop();
|
||||||
|
return register16_t(low, high);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@@ -4,13 +4,13 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "Bus.h"
|
#include "Bus.h"
|
||||||
#include "Processor.h"
|
#include "LittleEndianProcessor.h"
|
||||||
#include "Register.h"
|
#include "Register.h"
|
||||||
|
|
||||||
#include "EightBitCompilerDefinitions.h"
|
#include "EightBitCompilerDefinitions.h"
|
||||||
|
|
||||||
namespace EightBit {
|
namespace EightBit {
|
||||||
class IntelProcessor : public Processor
|
class IntelProcessor : public LittleEndianProcessor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct opcode_decoded_t {
|
struct opcode_decoded_t {
|
||||||
@@ -122,8 +122,8 @@ namespace EightBit {
|
|||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
register16_t getWord();
|
virtual register16_t getWord() final;
|
||||||
void setWord(register16_t value);
|
virtual void setWord(register16_t value) final;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
56
inc/LittleEndianProcessor.h
Normal file
56
inc/LittleEndianProcessor.h
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Bus.h"
|
||||||
|
#include "Register.h"
|
||||||
|
#include "Processor.h"
|
||||||
|
|
||||||
|
namespace EightBit {
|
||||||
|
class LittleEndianProcessor : public Processor {
|
||||||
|
protected:
|
||||||
|
LittleEndianProcessor(Bus& memory) : Processor(memory) {}
|
||||||
|
virtual ~LittleEndianProcessor() = default;
|
||||||
|
|
||||||
|
virtual register16_t getWord() {
|
||||||
|
const auto low = BUS().read();
|
||||||
|
++BUS().ADDRESS();
|
||||||
|
const auto high = BUS().read();
|
||||||
|
return register16_t(low, high);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setWord(const register16_t value) {
|
||||||
|
BUS().write(value.low);
|
||||||
|
++BUS().ADDRESS();
|
||||||
|
BUS().write(value.high);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual register16_t getWordPaged(uint8_t page, uint8_t offset) override {
|
||||||
|
const auto low = getBytePaged(page, offset);
|
||||||
|
++BUS().ADDRESS().low;
|
||||||
|
const auto high = BUS().read();
|
||||||
|
return register16_t(low, high);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setWordPaged(uint8_t page, uint8_t offset, register16_t value) override {
|
||||||
|
setBytePaged(page, offset, value.low);
|
||||||
|
++BUS().ADDRESS().low;
|
||||||
|
BUS().read(value.high);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual register16_t fetchWord() final {
|
||||||
|
const auto low = fetchByte();
|
||||||
|
const auto high = fetchByte();
|
||||||
|
return register16_t(low, high);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void pushWord(const register16_t value) final {
|
||||||
|
push(value.high);
|
||||||
|
push(value.low);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual register16_t popWord() final {
|
||||||
|
const auto low = pop();
|
||||||
|
const auto high = pop();
|
||||||
|
return register16_t(low, high);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@@ -97,7 +97,7 @@ namespace EightBit {
|
|||||||
|
|
||||||
static void clearFlag(uint8_t& f, const int flag, const int condition) { clearFlag(f, flag, !!condition); }
|
static void clearFlag(uint8_t& f, const int flag, const int condition) { clearFlag(f, flag, !!condition); }
|
||||||
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 uint32_t condition) { clearFlag(f, flag, !!condition); }
|
||||||
static void clearFlag(uint8_t& f, const int flag, const bool condition) { condition ? clearFlag(f, flag) : setFlag(f, flag); }
|
static void clearFlag(uint8_t& f, const int flag, const bool condition) { setFlag(f, flag, !condition); }
|
||||||
|
|
||||||
Processor(Bus& memory);
|
Processor(Bus& memory);
|
||||||
virtual ~Processor() = default;
|
virtual ~Processor() = default;
|
||||||
@@ -108,29 +108,31 @@ namespace EightBit {
|
|||||||
void halt() { --PC(); lower(HALT()); }
|
void halt() { --PC(); lower(HALT()); }
|
||||||
void proceed() { ++PC(); raise(HALT()); }
|
void proceed() { ++PC(); raise(HALT()); }
|
||||||
|
|
||||||
|
uint8_t getBytePaged(uint8_t page, uint8_t offset) {
|
||||||
|
return BUS().read(register16_t(offset, page));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBytePaged(uint8_t page, uint8_t offset, uint8_t value) {
|
||||||
|
BUS().write(register16_t(offset, page), value);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t fetchByte() {
|
uint8_t fetchByte() {
|
||||||
return BUS().read(PC()++);
|
return BUS().read(PC()++);
|
||||||
}
|
}
|
||||||
|
|
||||||
register16_t fetchWord() {
|
virtual register16_t getWord() = 0;
|
||||||
const auto low = fetchByte();
|
virtual void setWord(register16_t value) = 0;
|
||||||
const auto high = fetchByte();
|
|
||||||
return register16_t(low, high);
|
virtual register16_t getWordPaged(uint8_t page, uint8_t offset) = 0;
|
||||||
}
|
virtual void setWordPaged(uint8_t page, uint8_t offset, register16_t value) = 0;
|
||||||
|
|
||||||
|
virtual register16_t fetchWord() = 0;
|
||||||
|
|
||||||
virtual void push(uint8_t value) = 0;
|
virtual void push(uint8_t value) = 0;
|
||||||
virtual uint8_t pop() = 0;
|
virtual uint8_t pop() = 0;
|
||||||
|
|
||||||
void pushWord(const register16_t value) {
|
virtual void pushWord(const register16_t value) = 0;
|
||||||
push(value.high);
|
virtual register16_t popWord() = 0;
|
||||||
push(value.low);
|
|
||||||
}
|
|
||||||
|
|
||||||
register16_t popWord() {
|
|
||||||
const auto low = pop();
|
|
||||||
const auto high = pop();
|
|
||||||
return register16_t(low, high);
|
|
||||||
}
|
|
||||||
|
|
||||||
void jump(const register16_t destination) {
|
void jump(const register16_t destination) {
|
||||||
PC() = destination;
|
PC() = destination;
|
||||||
|
@@ -136,11 +136,13 @@
|
|||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\inc\BigEndianProcessor.h" />
|
||||||
<ClInclude Include="..\inc\Bus.h" />
|
<ClInclude Include="..\inc\Bus.h" />
|
||||||
<ClInclude Include="..\inc\EightBitCompilerDefinitions.h" />
|
<ClInclude Include="..\inc\EightBitCompilerDefinitions.h" />
|
||||||
<ClInclude Include="..\inc\EventArgs.h" />
|
<ClInclude Include="..\inc\EventArgs.h" />
|
||||||
<ClInclude Include="..\inc\InputOutput.h" />
|
<ClInclude Include="..\inc\InputOutput.h" />
|
||||||
<ClInclude Include="..\inc\IntelProcessor.h" />
|
<ClInclude Include="..\inc\IntelProcessor.h" />
|
||||||
|
<ClInclude Include="..\inc\LittleEndianProcessor.h" />
|
||||||
<ClInclude Include="..\inc\Memory.h" />
|
<ClInclude Include="..\inc\Memory.h" />
|
||||||
<ClInclude Include="..\inc\Processor.h" />
|
<ClInclude Include="..\inc\Processor.h" />
|
||||||
<ClInclude Include="..\inc\Ram.h" />
|
<ClInclude Include="..\inc\Ram.h" />
|
||||||
|
@@ -47,6 +47,12 @@
|
|||||||
<ClInclude Include="..\inc\EightBitCompilerDefinitions.h">
|
<ClInclude Include="..\inc\EightBitCompilerDefinitions.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\LittleEndianProcessor.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\inc\BigEndianProcessor.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="stdafx.cpp">
|
<ClCompile Include="stdafx.cpp">
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
#include "IntelProcessor.h"
|
#include "IntelProcessor.h"
|
||||||
|
|
||||||
EightBit::IntelProcessor::IntelProcessor(Bus& bus)
|
EightBit::IntelProcessor::IntelProcessor(Bus& bus)
|
||||||
: Processor(bus) {
|
: LittleEndianProcessor(bus) {
|
||||||
for (int i = 0; i < 0x100; ++i)
|
for (int i = 0; i < 0x100; ++i)
|
||||||
m_decodedOpcodes[i] = i;
|
m_decodedOpcodes[i] = i;
|
||||||
}
|
}
|
||||||
@@ -21,14 +21,12 @@ uint8_t EightBit::IntelProcessor::pop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EightBit::register16_t EightBit::IntelProcessor::getWord() {
|
EightBit::register16_t EightBit::IntelProcessor::getWord() {
|
||||||
const auto low = BUS().read();
|
const auto returned = LittleEndianProcessor::getWord();
|
||||||
MEMPTR() = ++BUS().ADDRESS();
|
MEMPTR() = BUS().ADDRESS();
|
||||||
const auto high = BUS().read();
|
return returned;
|
||||||
return register16_t(low, high);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::IntelProcessor::setWord(const register16_t value) {
|
void EightBit::IntelProcessor::setWord(const register16_t value) {
|
||||||
BUS().write(value.low);
|
LittleEndianProcessor::setWord(value);
|
||||||
MEMPTR() = ++BUS().ADDRESS();
|
MEMPTR() = BUS().ADDRESS();
|
||||||
BUS().write(value.high);
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user