mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2026-10-25 11:02:27 +00:00
Lots of miscellaneous cycle accurate updates
This commit is contained in:
1 parent
81c1703ea9
commit
d533593a14
25 files changed
+603
-615
No files matched your search
+13
-10
@@ -4,44 +4,47 @@
|
||||
EightBit::BigEndianProcessor::BigEndianProcessor(Bus& memory) noexcept
|
||||
: Processor(memory) {}
|
||||
|
||||
EightBit::register16_t EightBit::BigEndianProcessor::getWord() {
|
||||
EightBit::BigEndianProcessor::BigEndianProcessor(const BigEndianProcessor& rhs) noexcept
|
||||
: Processor(rhs) {}
|
||||
|
||||
EightBit::register16_t EightBit::BigEndianProcessor::getWord() noexcept {
|
||||
const auto high = memoryRead();
|
||||
++BUS().ADDRESS();
|
||||
const auto low = memoryRead();
|
||||
return { low, high };
|
||||
}
|
||||
|
||||
void EightBit::BigEndianProcessor::setWord(const register16_t value) {
|
||||
void EightBit::BigEndianProcessor::setWord(const register16_t value) noexcept {
|
||||
memoryWrite(value.high);
|
||||
++BUS().ADDRESS();
|
||||
memoryWrite(value.low);
|
||||
}
|
||||
|
||||
EightBit::register16_t EightBit::BigEndianProcessor::getWordPaged() {
|
||||
EightBit::register16_t EightBit::BigEndianProcessor::getWordPaged() noexcept {
|
||||
const auto high = memoryRead();
|
||||
++BUS().ADDRESS().low;
|
||||
const auto low = memoryRead();
|
||||
return { low, high };
|
||||
}
|
||||
|
||||
void EightBit::BigEndianProcessor::setWordPaged(const register16_t value) {
|
||||
void EightBit::BigEndianProcessor::setWordPaged(const register16_t value) noexcept {
|
||||
memoryWrite(value.high);
|
||||
++BUS().ADDRESS().low;
|
||||
memoryWrite(value.low);
|
||||
}
|
||||
|
||||
EightBit::register16_t EightBit::BigEndianProcessor::fetchWord() {
|
||||
const auto high = fetchByte();
|
||||
const auto low = fetchByte();
|
||||
return { low, high };
|
||||
EightBit::register16_t EightBit::BigEndianProcessor::fetchWord() noexcept {
|
||||
intermediate().high = fetchByte();
|
||||
intermediate().low = fetchByte();
|
||||
return intermediate();
|
||||
}
|
||||
|
||||
void EightBit::BigEndianProcessor::pushWord(const register16_t value) {
|
||||
void EightBit::BigEndianProcessor::pushWord(const register16_t value) noexcept {
|
||||
push(value.low);
|
||||
push(value.high);
|
||||
}
|
||||
|
||||
EightBit::register16_t EightBit::BigEndianProcessor::popWord() {
|
||||
EightBit::register16_t EightBit::BigEndianProcessor::popWord() noexcept {
|
||||
const auto high = pop();
|
||||
const auto low = pop();
|
||||
return { low, high };
|
||||
|
||||
+2
-2
@@ -8,14 +8,14 @@ void EightBit::Bus::raisePOWER() noexcept {}
|
||||
|
||||
void EightBit::Bus::lowerPOWER() noexcept {}
|
||||
|
||||
uint8_t EightBit::Bus::read() {
|
||||
uint8_t EightBit::Bus::read() noexcept {
|
||||
ReadingByte.fire();
|
||||
const auto returned = DATA() = reference();
|
||||
ReadByte.fire();
|
||||
return returned;
|
||||
}
|
||||
|
||||
void EightBit::Bus::write() {
|
||||
void EightBit::Bus::write() noexcept {
|
||||
WritingByte.fire();
|
||||
reference() = DATA();
|
||||
WrittenByte.fire();
|
||||
|
||||
+55
-37
@@ -4,7 +4,7 @@
|
||||
std::array<int, 8> EightBit::IntelProcessor::m_halfCarryTableAdd = { { 0, 0, 1, 0, 1, 0, 1, 1 } };
|
||||
std::array<int, 8> EightBit::IntelProcessor::m_halfCarryTableSub = { { 0, 1, 1, 1, 0, 0, 0, 1 } };
|
||||
|
||||
EightBit::IntelProcessor::IntelProcessor(Bus& bus)
|
||||
EightBit::IntelProcessor::IntelProcessor(Bus& bus) noexcept
|
||||
: LittleEndianProcessor(bus) {
|
||||
for (int i = 0; i < 0x100; ++i)
|
||||
m_decodedOpcodes.at(i) = i;
|
||||
@@ -17,11 +17,9 @@ EightBit::IntelProcessor::IntelProcessor(Bus& bus)
|
||||
}
|
||||
|
||||
EightBit::IntelProcessor::IntelProcessor(const IntelProcessor& rhs) noexcept
|
||||
: LittleEndianProcessor(rhs) {
|
||||
|
||||
m_sp = rhs.m_sp;
|
||||
m_memptr = rhs.m_memptr;
|
||||
|
||||
: LittleEndianProcessor(rhs),
|
||||
m_sp(rhs.m_sp),
|
||||
m_memptr(rhs.m_memptr) {
|
||||
HALT() = rhs.HALT();
|
||||
}
|
||||
|
||||
@@ -31,73 +29,72 @@ void EightBit::IntelProcessor::resetWorkingRegisters() noexcept {
|
||||
|
||||
DEFINE_PIN_LEVEL_CHANGERS(HALT, IntelProcessor);
|
||||
|
||||
void EightBit::IntelProcessor::handleRESET() {
|
||||
void EightBit::IntelProcessor::handleRESET() noexcept {
|
||||
Processor::handleRESET();
|
||||
disableInterrupts();
|
||||
Processor::jump(0);
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::handleINT() {
|
||||
void EightBit::IntelProcessor::handleINT() noexcept {
|
||||
Processor::handleINT();
|
||||
disableInterrupts();
|
||||
raiseHALT();
|
||||
disableInterrupts();
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::push(const uint8_t value) {
|
||||
void EightBit::IntelProcessor::push(const uint8_t value) noexcept {
|
||||
memoryWrite(--SP(), value);
|
||||
}
|
||||
|
||||
uint8_t EightBit::IntelProcessor::pop() {
|
||||
uint8_t EightBit::IntelProcessor::pop() noexcept {
|
||||
return memoryRead(SP()++);
|
||||
}
|
||||
|
||||
|
||||
EightBit::register16_t& EightBit::IntelProcessor::incrementPC() {
|
||||
if (raised(HALT()))
|
||||
EightBit::register16_t& EightBit::IntelProcessor::incrementPC() noexcept {
|
||||
if (proceeding())
|
||||
Processor::incrementPC();
|
||||
return PC();
|
||||
}
|
||||
|
||||
uint8_t EightBit::IntelProcessor::fetchInstruction() {
|
||||
uint8_t EightBit::IntelProcessor::fetchInstruction() noexcept {
|
||||
const auto data = fetchByte();
|
||||
return lowered(HALT()) ? (uint8_t)0 : data;
|
||||
return proceeding() ? data : (uint8_t)0;
|
||||
}
|
||||
|
||||
EightBit::register16_t EightBit::IntelProcessor::getWord() {
|
||||
EightBit::register16_t EightBit::IntelProcessor::getWord() noexcept {
|
||||
const auto returned = LittleEndianProcessor::getWord();
|
||||
MEMPTR() = BUS().ADDRESS();
|
||||
return returned;
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::setWord(const register16_t value) {
|
||||
void EightBit::IntelProcessor::setWord(const register16_t value) noexcept {
|
||||
LittleEndianProcessor::setWord(value);
|
||||
MEMPTR() = BUS().ADDRESS();
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::restart(const uint8_t address) {
|
||||
void EightBit::IntelProcessor::restart(const uint8_t address) noexcept {
|
||||
MEMPTR() = { address, 0 };
|
||||
call();
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::callConditional(bool condition) {
|
||||
void EightBit::IntelProcessor::callConditional(bool condition) noexcept {
|
||||
MEMPTR() = fetchWord();
|
||||
if (condition)
|
||||
call();
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::jumpConditional(bool condition) {
|
||||
void EightBit::IntelProcessor::jumpConditional(bool condition) noexcept {
|
||||
MEMPTR() = fetchWord();
|
||||
if (condition)
|
||||
jump();
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::jumpRelativeConditional(bool condition) {
|
||||
void EightBit::IntelProcessor::jumpRelativeConditional(bool condition) noexcept {
|
||||
const auto offset = fetchByte();
|
||||
if (condition)
|
||||
jumpRelative(offset);
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::returnConditional(bool condition) {
|
||||
void EightBit::IntelProcessor::returnConditional(bool condition) noexcept {
|
||||
if (condition)
|
||||
ret();
|
||||
}
|
||||
@@ -107,42 +104,63 @@ void EightBit::IntelProcessor::jumpRelative(const int8_t offset) noexcept {
|
||||
jump();
|
||||
}
|
||||
|
||||
|
||||
void EightBit::IntelProcessor::ret() {
|
||||
void EightBit::IntelProcessor::ret() noexcept {
|
||||
LittleEndianProcessor::ret();
|
||||
MEMPTR() = PC();
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::jumpIndirect() {
|
||||
void EightBit::IntelProcessor::jumpIndirect() noexcept {
|
||||
MEMPTR() = fetchWord();
|
||||
jump();
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::jump() {
|
||||
void EightBit::IntelProcessor::jump() noexcept {
|
||||
Processor::jump(MEMPTR());
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::callIndirect() {
|
||||
void EightBit::IntelProcessor::callIndirect() noexcept {
|
||||
MEMPTR() = fetchWord();
|
||||
call();
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::call() {
|
||||
void EightBit::IntelProcessor::call() noexcept {
|
||||
call(MEMPTR());
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::call(register16_t destination) {
|
||||
void EightBit::IntelProcessor::call(register16_t destination) noexcept {
|
||||
Processor::call(destination);
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::jumpConditionalFlag(int flag) noexcept {
|
||||
jumpConditional(convertCondition(flag));
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::jumpRelativeConditionalFlag(int flag) noexcept {
|
||||
jumpRelativeConditional(convertCondition(flag));
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::returnConditionalFlag(int flag) noexcept {
|
||||
returnConditional(convertCondition(flag));
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::callConditionalFlag(int flag) noexcept {
|
||||
callConditional(convertCondition(flag));
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::cpl() noexcept {
|
||||
A() = ~A();
|
||||
}
|
||||
|
||||
bool EightBit::IntelProcessor::operator==(const EightBit::IntelProcessor& rhs) const noexcept {
|
||||
auto& left = const_cast<IntelProcessor&>(*this);
|
||||
auto& right = const_cast<IntelProcessor&>(rhs);
|
||||
return
|
||||
LittleEndianProcessor::operator==(rhs)
|
||||
&& HALT() == rhs.HALT()
|
||||
&& MEMPTR() == rhs.MEMPTR()
|
||||
&& SP() == rhs.SP()
|
||||
&& AF() == rhs.AF()
|
||||
&& BC() == rhs.BC()
|
||||
&& DE() == rhs.DE()
|
||||
&& HL() == rhs.HL();
|
||||
&& left.HALT() == right.HALT()
|
||||
&& left.MEMPTR() == right.MEMPTR()
|
||||
&& left.SP() == right.SP()
|
||||
&& left.AF() == right.AF()
|
||||
&& left.BC() == right.BC()
|
||||
&& left.DE() == right.DE()
|
||||
&& left.HL() == right.HL();
|
||||
}
|
||||
@@ -7,44 +7,44 @@ EightBit::LittleEndianProcessor::LittleEndianProcessor(Bus& memory) noexcept
|
||||
EightBit::LittleEndianProcessor::LittleEndianProcessor(const LittleEndianProcessor& rhs) noexcept
|
||||
: Processor(rhs) {}
|
||||
|
||||
EightBit::register16_t EightBit::LittleEndianProcessor::getWord() {
|
||||
EightBit::register16_t EightBit::LittleEndianProcessor::getWord() noexcept {
|
||||
const auto low = memoryRead();
|
||||
++BUS().ADDRESS();
|
||||
const auto high = memoryRead();
|
||||
return { low, high };
|
||||
}
|
||||
|
||||
void EightBit::LittleEndianProcessor::setWord(const register16_t value) {
|
||||
void EightBit::LittleEndianProcessor::setWord(const register16_t value) noexcept {
|
||||
memoryWrite(value.low);
|
||||
++BUS().ADDRESS();
|
||||
memoryWrite(value.high);
|
||||
}
|
||||
|
||||
EightBit::register16_t EightBit::LittleEndianProcessor::getWordPaged() {
|
||||
EightBit::register16_t EightBit::LittleEndianProcessor::getWordPaged() noexcept {
|
||||
const auto low = memoryRead();
|
||||
++BUS().ADDRESS().low;
|
||||
const auto high = memoryRead();
|
||||
return { low, high };
|
||||
}
|
||||
|
||||
void EightBit::LittleEndianProcessor::setWordPaged(register16_t value) {
|
||||
void EightBit::LittleEndianProcessor::setWordPaged(register16_t value) noexcept {
|
||||
memoryWrite(value.low);
|
||||
++BUS().ADDRESS().low;
|
||||
memoryWrite(value.high);
|
||||
}
|
||||
|
||||
EightBit::register16_t EightBit::LittleEndianProcessor::fetchWord() {
|
||||
EightBit::register16_t EightBit::LittleEndianProcessor::fetchWord() noexcept {
|
||||
intermediate().low = fetchByte();
|
||||
intermediate().high = fetchByte();
|
||||
return intermediate();
|
||||
}
|
||||
|
||||
void EightBit::LittleEndianProcessor::pushWord(const register16_t value) {
|
||||
void EightBit::LittleEndianProcessor::pushWord(const register16_t value) noexcept {
|
||||
push(value.high);
|
||||
push(value.low);
|
||||
}
|
||||
|
||||
EightBit::register16_t EightBit::LittleEndianProcessor::popWord() {
|
||||
EightBit::register16_t EightBit::LittleEndianProcessor::popWord() noexcept {
|
||||
const auto low = pop();
|
||||
const auto high = pop();
|
||||
return { low, high };
|
||||
|
||||
+31
-31
@@ -7,109 +7,109 @@ EightBit::Processor::Processor(Bus& bus) noexcept
|
||||
|
||||
EightBit::Processor::Processor(const Processor& rhs) noexcept
|
||||
: ClockedChip(rhs),
|
||||
m_bus(rhs.m_bus) {
|
||||
m_bus(rhs.m_bus),
|
||||
m_opcode(rhs.m_opcode),
|
||||
m_pc(rhs.m_pc),
|
||||
m_intermediate(rhs.m_intermediate) {
|
||||
RESET() = rhs.RESET();
|
||||
INT() = rhs.INT();
|
||||
PC() = rhs.PC();
|
||||
}
|
||||
|
||||
DEFINE_PIN_LEVEL_CHANGERS(RESET, Processor)
|
||||
DEFINE_PIN_LEVEL_CHANGERS(INT, Processor)
|
||||
|
||||
void EightBit::Processor::handleRESET() {
|
||||
void EightBit::Processor::handleRESET() noexcept {
|
||||
raiseRESET();
|
||||
}
|
||||
|
||||
void EightBit::Processor::handleINT() {
|
||||
void EightBit::Processor::handleINT() noexcept {
|
||||
raiseINT();
|
||||
}
|
||||
|
||||
void EightBit::Processor::memoryWrite(const register16_t address, const uint8_t data) {
|
||||
void EightBit::Processor::memoryWrite(const register16_t address, const uint8_t data) noexcept {
|
||||
BUS().ADDRESS() = address;
|
||||
memoryWrite(data);
|
||||
}
|
||||
|
||||
void EightBit::Processor::memoryWrite(const register16_t address) {
|
||||
void EightBit::Processor::memoryWrite(const register16_t address) noexcept {
|
||||
BUS().ADDRESS() = address;
|
||||
memoryWrite();
|
||||
}
|
||||
|
||||
void EightBit::Processor::memoryWrite(const uint8_t data) {
|
||||
void EightBit::Processor::memoryWrite(const uint8_t data) noexcept {
|
||||
BUS().DATA() = data;
|
||||
memoryWrite();
|
||||
}
|
||||
|
||||
void EightBit::Processor::memoryWrite() {
|
||||
void EightBit::Processor::memoryWrite() noexcept {
|
||||
busWrite();
|
||||
}
|
||||
|
||||
void EightBit::Processor::busWrite() {
|
||||
void EightBit::Processor::busWrite() noexcept {
|
||||
BUS().write();
|
||||
}
|
||||
|
||||
uint8_t EightBit::Processor::memoryRead(const register16_t address) {
|
||||
uint8_t EightBit::Processor::memoryRead(const register16_t address) noexcept {
|
||||
BUS().ADDRESS() = address;
|
||||
return memoryRead();
|
||||
}
|
||||
|
||||
uint8_t EightBit::Processor::memoryRead() {
|
||||
uint8_t EightBit::Processor::memoryRead() noexcept {
|
||||
return busRead();
|
||||
}
|
||||
|
||||
uint8_t EightBit::Processor::busRead() {
|
||||
uint8_t EightBit::Processor::busRead() noexcept {
|
||||
return BUS().read();
|
||||
}
|
||||
|
||||
EightBit::register16_t EightBit::Processor::getWordPaged(register16_t address) {
|
||||
EightBit::register16_t EightBit::Processor::getWordPaged(register16_t address) noexcept {
|
||||
BUS().ADDRESS() = address;
|
||||
return getWordPaged();
|
||||
}
|
||||
|
||||
EightBit::register16_t EightBit::Processor::getWordPaged(const uint8_t page, const uint8_t offset) {
|
||||
EightBit::register16_t EightBit::Processor::getWordPaged(const uint8_t page, const uint8_t offset) noexcept {
|
||||
BUS().ADDRESS() = { offset, page };
|
||||
return getWordPaged();
|
||||
}
|
||||
|
||||
void EightBit::Processor::setWordPaged(register16_t address, const register16_t value) {
|
||||
void EightBit::Processor::setWordPaged(register16_t address, const register16_t value) noexcept {
|
||||
BUS().ADDRESS() = address;
|
||||
setWordPaged(value);
|
||||
}
|
||||
|
||||
void EightBit::Processor::setWordPaged(const uint8_t page, const uint8_t offset, const register16_t value) {
|
||||
void EightBit::Processor::setWordPaged(const uint8_t page, const uint8_t offset, const register16_t value) noexcept {
|
||||
BUS().ADDRESS() = { offset, page };
|
||||
setWordPaged(value);
|
||||
}
|
||||
|
||||
EightBit::register16_t& EightBit::Processor::incrementPC() {
|
||||
PC()++;
|
||||
return PC();
|
||||
EightBit::register16_t& EightBit::Processor::incrementPC() noexcept {
|
||||
return ++PC();
|
||||
}
|
||||
|
||||
EightBit::register16_t& EightBit::Processor::decrementPC() {
|
||||
PC()--;
|
||||
return PC();
|
||||
EightBit::register16_t& EightBit::Processor::decrementPC() noexcept {
|
||||
return --PC();
|
||||
}
|
||||
|
||||
void EightBit::Processor::immediateAddress() {
|
||||
void EightBit::Processor::immediateAddress() noexcept {
|
||||
BUS().ADDRESS() = PC();
|
||||
incrementPC();
|
||||
}
|
||||
|
||||
uint8_t EightBit::Processor::fetchByte() {
|
||||
uint8_t EightBit::Processor::fetchByte() noexcept {
|
||||
immediateAddress();
|
||||
return memoryRead();
|
||||
}
|
||||
|
||||
uint8_t EightBit::Processor::fetchInstruction() {
|
||||
uint8_t EightBit::Processor::fetchInstruction() noexcept {
|
||||
return fetchByte();
|
||||
}
|
||||
|
||||
EightBit::register16_t EightBit::Processor::getWord(const register16_t address) {
|
||||
EightBit::register16_t EightBit::Processor::getWord(const register16_t address) noexcept {
|
||||
BUS().ADDRESS() = address;
|
||||
return getWord();
|
||||
}
|
||||
|
||||
void EightBit::Processor::setWord(const register16_t address, const register16_t value) {
|
||||
void EightBit::Processor::setWord(const register16_t address, const register16_t value) noexcept {
|
||||
BUS().ADDRESS() = address;
|
||||
setWord(value);
|
||||
}
|
||||
@@ -120,7 +120,7 @@ int EightBit::Processor::step() noexcept {
|
||||
if (LIKELY(powered()))
|
||||
poweredStep();
|
||||
ExecutedInstruction.fire();
|
||||
ASSUME(cycles() > 0);
|
||||
// ASSUME(cycles() > 0); Not if unpowered!!
|
||||
return cycles();
|
||||
}
|
||||
|
||||
@@ -141,15 +141,15 @@ void EightBit::Processor::jump(const register16_t destination) noexcept {
|
||||
}
|
||||
|
||||
void EightBit::Processor::jump(const uint16_t destination) noexcept {
|
||||
PC().word = destination;
|
||||
PC() = destination;
|
||||
}
|
||||
|
||||
void EightBit::Processor::call(const register16_t destination) {
|
||||
void EightBit::Processor::call(const register16_t destination) noexcept {
|
||||
pushWord(PC());
|
||||
jump(destination);
|
||||
}
|
||||
|
||||
void EightBit::Processor::ret() {
|
||||
void EightBit::Processor::ret() noexcept {
|
||||
jump(popWord());
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
bool EightBit::Rom::operator==(const Rom& rhs) const {
|
||||
bool EightBit::Rom::operator==(const Rom& rhs) const noexcept {
|
||||
return BYTES() == rhs.BYTES();
|
||||
}
|
||||
|
||||
@@ -48,10 +48,10 @@ void EightBit::Rom::poke(const uint16_t address, const uint8_t value) noexcept {
|
||||
EightBit::Rom::Rom(const size_t size) noexcept
|
||||
: m_bytes(size) {}
|
||||
|
||||
EightBit::Rom::Rom(const Rom& rhs)
|
||||
EightBit::Rom::Rom(const Rom& rhs) noexcept
|
||||
: m_bytes(rhs.m_bytes) {}
|
||||
|
||||
EightBit::Rom& EightBit::Rom::operator=(const Rom& rhs) {
|
||||
EightBit::Rom& EightBit::Rom::operator=(const Rom& rhs) noexcept {
|
||||
if (this != &rhs)
|
||||
m_bytes = rhs.m_bytes;
|
||||
return *this;
|
||||
|
||||
Reference in new issue
Block a user