Lots of miscellaneous cycle accurate updates

This commit is contained in:
Adrian Conlon committed 2026-03-21 16:18:39 +00:00
1 parent 81c1703ea9
commit d533593a14
25 files changed
+603 -615

No files matched your search

+13 -10
View File
@@ -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
View File
@@ -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
View File
@@ -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 -7
View File
@@ -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
View File
@@ -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
View File
@@ -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;