mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-01-18 01:29:49 +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:
parent
677b9a608e
commit
cc64e114a9
@ -7,11 +7,11 @@
|
||||
#include <cassert>
|
||||
|
||||
#include <Bus.h>
|
||||
#include <Processor.h>
|
||||
#include <LittleEndianProcessor.h>
|
||||
#include <Signal.h>
|
||||
|
||||
namespace EightBit {
|
||||
class MOS6502 : public Processor {
|
||||
class MOS6502 : public LittleEndianProcessor {
|
||||
public:
|
||||
enum StatusBits {
|
||||
NF = Bit7, // Negative
|
||||
@ -65,10 +65,6 @@ namespace EightBit {
|
||||
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 uint8_t pop() final;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include "mos6502.h"
|
||||
|
||||
EightBit::MOS6502::MOS6502(Bus& bus)
|
||||
: Processor(bus) {}
|
||||
: LittleEndianProcessor(bus) {}
|
||||
|
||||
void EightBit::MOS6502::powerOn() {
|
||||
|
||||
@ -50,21 +50,6 @@ void EightBit::MOS6502::reset() {
|
||||
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) {
|
||||
raise(HALT());
|
||||
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 "Bus.h"
|
||||
#include "Processor.h"
|
||||
#include "LittleEndianProcessor.h"
|
||||
#include "Register.h"
|
||||
|
||||
#include "EightBitCompilerDefinitions.h"
|
||||
|
||||
namespace EightBit {
|
||||
class IntelProcessor : public Processor
|
||||
class IntelProcessor : public LittleEndianProcessor
|
||||
{
|
||||
public:
|
||||
struct opcode_decoded_t {
|
||||
@ -122,8 +122,8 @@ namespace EightBit {
|
||||
|
||||
//
|
||||
|
||||
register16_t getWord();
|
||||
void setWord(register16_t value);
|
||||
virtual register16_t getWord() final;
|
||||
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 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);
|
||||
virtual ~Processor() = default;
|
||||
@ -108,29 +108,31 @@ namespace EightBit {
|
||||
void halt() { --PC(); lower(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() {
|
||||
return BUS().read(PC()++);
|
||||
}
|
||||
|
||||
register16_t fetchWord() {
|
||||
const auto low = fetchByte();
|
||||
const auto high = fetchByte();
|
||||
return register16_t(low, high);
|
||||
}
|
||||
virtual register16_t getWord() = 0;
|
||||
virtual void setWord(register16_t value) = 0;
|
||||
|
||||
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 uint8_t pop() = 0;
|
||||
|
||||
void pushWord(const register16_t value) {
|
||||
push(value.high);
|
||||
push(value.low);
|
||||
}
|
||||
|
||||
register16_t popWord() {
|
||||
const auto low = pop();
|
||||
const auto high = pop();
|
||||
return register16_t(low, high);
|
||||
}
|
||||
virtual void pushWord(const register16_t value) = 0;
|
||||
virtual register16_t popWord() = 0;
|
||||
|
||||
void jump(const register16_t destination) {
|
||||
PC() = destination;
|
||||
|
@ -136,11 +136,13 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\inc\BigEndianProcessor.h" />
|
||||
<ClInclude Include="..\inc\Bus.h" />
|
||||
<ClInclude Include="..\inc\EightBitCompilerDefinitions.h" />
|
||||
<ClInclude Include="..\inc\EventArgs.h" />
|
||||
<ClInclude Include="..\inc\InputOutput.h" />
|
||||
<ClInclude Include="..\inc\IntelProcessor.h" />
|
||||
<ClInclude Include="..\inc\LittleEndianProcessor.h" />
|
||||
<ClInclude Include="..\inc\Memory.h" />
|
||||
<ClInclude Include="..\inc\Processor.h" />
|
||||
<ClInclude Include="..\inc\Ram.h" />
|
||||
|
@ -47,6 +47,12 @@
|
||||
<ClInclude Include="..\inc\EightBitCompilerDefinitions.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\LittleEndianProcessor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\BigEndianProcessor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include "IntelProcessor.h"
|
||||
|
||||
EightBit::IntelProcessor::IntelProcessor(Bus& bus)
|
||||
: Processor(bus) {
|
||||
: LittleEndianProcessor(bus) {
|
||||
for (int i = 0; i < 0x100; ++i)
|
||||
m_decodedOpcodes[i] = i;
|
||||
}
|
||||
@ -21,14 +21,12 @@ uint8_t EightBit::IntelProcessor::pop() {
|
||||
}
|
||||
|
||||
EightBit::register16_t EightBit::IntelProcessor::getWord() {
|
||||
const auto low = BUS().read();
|
||||
MEMPTR() = ++BUS().ADDRESS();
|
||||
const auto high = BUS().read();
|
||||
return register16_t(low, high);
|
||||
const auto returned = LittleEndianProcessor::getWord();
|
||||
MEMPTR() = BUS().ADDRESS();
|
||||
return returned;
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::setWord(const register16_t value) {
|
||||
BUS().write(value.low);
|
||||
MEMPTR() = ++BUS().ADDRESS();
|
||||
BUS().write(value.high);
|
||||
LittleEndianProcessor::setWord(value);
|
||||
MEMPTR() = BUS().ADDRESS();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user