Start big refactor of device/CPU pin usage (to allow pin events throughout).

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2019-01-14 02:10:17 +00:00
parent 9755a5fcd2
commit 92d23d82d6
36 changed files with 508 additions and 248 deletions

View File

@ -8,6 +8,7 @@
#include <Bus.h>
#include <InputOutput.h>
#include <IntelProcessor.h>
#include <EventArgs.h>
#include <Signal.h>
#include <Register.h>

View File

@ -10,15 +10,16 @@ Board::Board(const Configuration& configuration)
m_disassembler(*this) {
}
void Board::powerOn() {
EightBit::Bus::powerOn();
CPU().powerOn();
CPU().reset();
void Board::raisePOWER() {
EightBit::Bus::raisePOWER();
CPU().raisePOWER();
CPU().raiseRESET();
CPU().raiseINT();
}
void Board::powerOff() {
CPU().powerOff();
EightBit::Bus::powerOff();
void Board::lowerPOWER() {
CPU().lowerPOWER();
EightBit::Bus::lowerPOWER();
}
void Board::initialise() {
@ -30,6 +31,10 @@ void Board::initialise() {
m_ram.load(romDirectory + "/8080EX1.COM", 0x100); // Cringle/Bartholomew
//m_ram.load(romDirectory + "/CPUTEST.COM", 0x100); // SuperSoft diagnostics
m_cpu.LoweredHALT.connect([this](EightBit::EventArgs) {
lowerPOWER();
});
m_cpu.ExecutingInstruction.connect(std::bind(&Board::Cpu_ExecutingInstruction_Cpm, this, std::placeholders::_1));
if (m_configuration.isProfileMode()) {
@ -49,8 +54,8 @@ void Board::initialise() {
void Board::Cpu_ExecutingInstruction_Cpm(EightBit::Intel8080& cpu) {
switch (cpu.PC().word) {
case 0x0: // CP/M warm start
if (++m_warmstartCount == 3) {
powerOff();
if (++m_warmstartCount == 2) {
lowerPOWER();
if (m_configuration.isProfileMode()) {
m_profiler.dump();
}

View File

@ -17,11 +17,12 @@ public:
EightBit::Intel8080& CPU() { return m_cpu; }
const EightBit::Intel8080& CPU() const { return m_cpu; }
virtual void powerOn() final;
virtual void powerOff() final;
virtual void raisePOWER() final;
virtual void lowerPOWER() final;
virtual void initialise() final;
protected:
virtual void initialise() final;
virtual EightBit::MemoryMapping mapping(uint16_t address) final {
return { m_ram, 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite };
}

View File

@ -9,16 +9,18 @@ Fuse::TestRunner::TestRunner(const Test& test, const ExpectedTestResult& expecte
//
void Fuse::TestRunner::powerOn() {
EightBit::Bus::powerOn();
CPU().powerOn();
void Fuse::TestRunner::raisePOWER() {
EightBit::Bus::raisePOWER();
CPU().raisePOWER();
CPU().raiseRESET();
CPU().raiseINT();
initialiseRegisters();
initialiseMemory();
}
void Fuse::TestRunner::powerOff() {
CPU().powerOff();
EightBit::Bus::powerOff();
void Fuse::TestRunner::lowerPOWER() {
CPU().lowerPOWER();
EightBit::Bus::lowerPOWER();
}
void Fuse::TestRunner::initialise() {
@ -182,7 +184,8 @@ void Fuse::TestRunner::checkMemory() {
void Fuse::TestRunner::run() {
powerOn();
raisePOWER();
initialise();
auto allowedCycles = m_test.registerState.tstates;
try {
CPU().run(allowedCycles);

View File

@ -21,7 +21,6 @@ namespace Fuse {
EightBit::Ram m_ram = 0x10000;
void initialise();
void initialiseRegisters();
void initialiseMemory();
@ -47,7 +46,9 @@ namespace Fuse {
bool failed() const { return m_failed; }
bool unimplemented() const { return m_unimplemented; }
virtual void powerOn() final;
virtual void powerOff() final;
virtual void raisePOWER() final;
virtual void lowerPOWER() final;
void initialise();
};
}

View File

@ -36,8 +36,8 @@ namespace EightBit {
Bus() noexcept;
virtual void powerOn() override;
virtual void powerOff() override;
virtual void raisePOWER() override;
virtual void lowerPOWER() override;
auto& CPU() { return m_cpu; }
auto& VRAM() { return m_videoRam; }

View File

@ -8,15 +8,15 @@ EightBit::GameBoy::Bus::Bus() noexcept
WrittenByte.connect(std::bind(&GameBoy::Bus::Bus_WrittenByte, this, std::placeholders::_1));
}
void EightBit::GameBoy::Bus::powerOn() {
EightBit::Bus::powerOn();
CPU().powerOn();
void EightBit::GameBoy::Bus::raisePOWER() {
EightBit::Bus::raisePOWER();
CPU().raisePOWER();
reset();
}
void EightBit::GameBoy::Bus::powerOff() {
CPU().powerOff();
EightBit::Bus::powerOff();
void EightBit::GameBoy::Bus::lowerPOWER() {
CPU().lowerPOWER();
EightBit::Bus::lowerPOWER();
}
void EightBit::GameBoy::Bus::reset() {

View File

@ -7,6 +7,7 @@
#include <LittleEndianProcessor.h>
#include <Register.h>
#include <Signal.h>
#include <EventArgs.h>
namespace EightBit {
@ -30,9 +31,30 @@ namespace EightBit {
Signal<MOS6502> ExecutingInstruction;
Signal<MOS6502> ExecutedInstruction;
virtual int execute() final;
virtual int step() final;
virtual void powerOn() final;
Signal<EventArgs> RaisedNMI;
Signal<EventArgs> LoweredNMI;
Signal<EventArgs> RaisedSO;
Signal<EventArgs> LoweredSO;
Signal<EventArgs> RaisedSYNC;
Signal<EventArgs> LoweredSYNC;
Signal<EventArgs> RaisedRDY;
Signal<EventArgs> LoweredRDY;
int execute() final;
int step() final;
void raisePOWER() final;
virtual void lowerNMI();
virtual void raiseNMI();
virtual void lowerSO();
virtual void raiseSO();
virtual void lowerRDY();
virtual void raiseRDY();
auto& X() { return x; }
auto& Y() { return y; }
@ -48,8 +70,11 @@ namespace EightBit {
auto& RDY() { return m_rdyLine; } // In
protected:
virtual void lowerSYNC();
virtual void raiseSYNC();
virtual void handleRESET() final;
virtual void handleIRQ() final;
virtual void handleINT() final;
virtual void busWrite() final;
virtual uint8_t busRead() final;
@ -186,15 +211,15 @@ namespace EightBit {
uint8_t s = 0; // stack pointer
uint8_t p = 0; // processor status
PinLevel m_nmiLine = PinLevel::Low; // Active low
PinLevel m_soLine = PinLevel::Low; // Active low
PinLevel m_syncLine = PinLevel::Low; // Active high
PinLevel m_rdyLine = PinLevel::Low; // Active high
PinLevel m_nmiLine = PinLevel::Low; // In, Active low
PinLevel m_soLine = PinLevel::Low; // In, Active low
PinLevel m_syncLine = PinLevel::Low; // Out, Active high
PinLevel m_rdyLine = PinLevel::Low; // In, Active high
register16_t m_intermediate;
bool m_handlingRESET = false;
bool m_handlingNMI = false;
bool m_handlingIRQ = false;
bool m_handlingINT = false;
};
}

View File

@ -4,18 +4,45 @@
EightBit::MOS6502::MOS6502(Bus& bus)
: LittleEndianProcessor(bus) {}
void EightBit::MOS6502::powerOn() {
LittleEndianProcessor::powerOn();
void EightBit::MOS6502::raisePOWER() {
LittleEndianProcessor::raisePOWER();
X() = Bit7;
Y() = 0;
A() = 0;
P() = RF;
S() = Mask8;
lowerSYNC();
}
void EightBit::MOS6502::lowerNMI() {
lower(NMI());
}
void EightBit::MOS6502::raiseNMI() {
raise(NMI());
}
void EightBit::MOS6502::lowerSO() {
lower(SO());
}
void EightBit::MOS6502::raiseSO() {
raise(SO());
}
void EightBit::MOS6502::lowerSYNC() {
lower(SYNC());
}
void EightBit::MOS6502::raiseSYNC() {
raise(SYNC());
}
void EightBit::MOS6502::lowerRDY() {
lower(RDY());
}
void EightBit::MOS6502::raiseRDY() {
raise(RDY());
}
@ -27,14 +54,14 @@ int EightBit::MOS6502::step() {
if (UNLIKELY(lowered(SO())))
handleSO();
if (LIKELY(raised(RDY()))) {
lower(SYNC()); // Instruction fetch beginning
lowerSYNC(); // Instruction fetch beginning
opcode() = BUS().read(PC()++); // can't use fetchByte
if (UNLIKELY(lowered(RESET())))
handleRESET();
else if (UNLIKELY(lowered(NMI())))
handleNMI();
else if (UNLIKELY(lowered(IRQ()) && !interruptMasked()))
handleIRQ();
else if (UNLIKELY(lowered(INT()) && !interruptMasked()))
handleINT();
execute();
}
}
@ -45,33 +72,33 @@ int EightBit::MOS6502::step() {
// Interrupt (etc.) handlers
void EightBit::MOS6502::handleSO() {
raise(SO());
raiseSO();
P() |= VF;
}
void EightBit::MOS6502::handleRESET() {
raise(RESET());
raiseRESET();
m_handlingRESET = true;
opcode() = 0x00; // BRK
}
void EightBit::MOS6502::handleNMI() {
raise(NMI());
raiseNMI();
m_handlingNMI = true;
opcode() = 0x00; // BRK
}
void EightBit::MOS6502::handleIRQ() {
void EightBit::MOS6502::handleINT() {
raise(INT());
m_handlingIRQ = true;
m_handlingINT = true;
opcode() = 0x00; // BRK
}
void EightBit::MOS6502::interrupt() {
const bool reset = m_handlingRESET;
const bool nmi = m_handlingNMI;
const bool irq = m_handlingIRQ;
const bool irq = m_handlingINT;
const bool hardware = nmi || irq || reset;
const bool software = !hardware;
if (reset) {
@ -85,7 +112,7 @@ void EightBit::MOS6502::interrupt() {
setFlag(P(), IF); // Disable IRQ
const uint8_t vector = reset ? RSTvector : (nmi ? NMIvector : IRQvector);
jump(getWordPaged(0xff, vector));
m_handlingRESET = m_handlingNMI = m_handlingIRQ = false;
m_handlingRESET = m_handlingNMI = m_handlingINT = false;
}
//
@ -104,7 +131,7 @@ uint8_t EightBit::MOS6502::busRead() {
int EightBit::MOS6502::execute() {
raise(SYNC()); // Instruction fetch has now completed
raiseSYNC(); // Instruction fetch has now completed
switch (opcode()) {

View File

@ -10,14 +10,19 @@
Board::Board(const Configuration& configuration)
: m_configuration(configuration) {}
void Board::powerOn() {
EightBit::Bus::powerOn();
CPU().powerOn();
void Board::raisePOWER() {
EightBit::Bus::raisePOWER();
CPU().raisePOWER();
CPU().raiseRESET();
CPU().raiseINT();
CPU().raiseNMI();
CPU().raiseSO();
CPU().raiseRDY();
}
void Board::powerOff() {
CPU().powerOff();
EightBit::Bus::powerOff();
void Board::lowerPOWER() {
CPU().lowerPOWER();
EightBit::Bus::lowerPOWER();
}
void Board::initialise() {
@ -53,7 +58,7 @@ void Board::initialise() {
if (m_oldPC != pc) {
m_oldPC = pc;
} else {
powerOff();
lowerPOWER();
auto test = peek(0x0200);
std::cout << std::endl << "** Test=" << std::hex << (int)test;
}

View File

@ -17,11 +17,12 @@ public:
EightBit::MOS6502& CPU() { return m_cpu; }
virtual void powerOn() final;
virtual void powerOff() final;
virtual void raisePOWER() final;
virtual void lowerPOWER() final;
virtual void initialise() final;
protected:
virtual void initialise() final;
virtual EightBit::MemoryMapping mapping(uint16_t address) final {
return { m_ram, 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite };
}

View File

@ -57,10 +57,34 @@ namespace EightBit {
Signal<mc6809> ExecutingInstruction;
Signal<mc6809> ExecutedInstruction;
Signal<EventArgs> RaisedNMI;
Signal<EventArgs> LoweredNMI;
Signal<EventArgs> RaisedFIRQ;
Signal<EventArgs> LoweredFIRQ;
Signal<EventArgs> RaisedHALT;
Signal<EventArgs> LoweredHALT;
Signal<EventArgs> RaisedBA;
Signal<EventArgs> LoweredBA;
Signal<EventArgs> RaisedBS;
Signal<EventArgs> LoweredBS;
virtual int execute() final;
virtual int step() final;
virtual void powerOn() final;
virtual void raisePOWER() final;
virtual void lowerNMI();
virtual void raiseNMI();
virtual void lowerFIRQ();
virtual void raiseFIRQ();
virtual void lowerHALT();
virtual void raiseHALT();
auto& D() { return m_d; }
auto& A() { return D().high; }
@ -75,8 +99,9 @@ namespace EightBit {
auto& CC() { return m_cc; }
const auto& CC() const { return m_cc; }
auto& NMI() { return m_nmiLine; } // In
auto& FIRQ() { return m_firqLine; } // In
[[nodiscard]] auto& NMI() noexcept { return m_nmiLine; } // In
[[nodiscard]] auto& FIRQ() noexcept { return m_firqLine; } // In
[[nodiscard]] auto& HALT() noexcept { return m_haltLine; } // In
// |---------------|-----------------------------------|
// | MPU State | |
@ -92,6 +117,10 @@ namespace EightBit {
auto& BA() { return m_baLine; } // Out
auto& BS() { return m_bsLine; } // Out
[[nodiscard]] auto halted() noexcept { return lowered(HALT()); }
void halt() noexcept { --PC(); lowerHALT(); }
void proceed() noexcept { ++PC(); raiseHALT(); }
protected:
// Default push/pop handlers
@ -101,7 +130,15 @@ namespace EightBit {
// Interrupt (etc.) handlers
virtual void handleRESET() final;
virtual void handleIRQ() final;
virtual void handleINT() final;
// Line handlers
virtual void lowerBA();
virtual void raiseBA();
virtual void lowerBS();
virtual void raiseBS();
private:
const uint8_t RESETvector = 0xfe; // RESET vector
@ -368,11 +405,12 @@ namespace EightBit {
uint8_t m_dp = 0;
uint8_t m_cc = 0;
PinLevel m_nmiLine = PinLevel::Low;
PinLevel m_firqLine = PinLevel::Low;
PinLevel m_nmiLine = PinLevel::Low; // In, Active low
PinLevel m_firqLine = PinLevel::Low; // In, Active low
PinLevel m_haltLine = PinLevel::Low; // In, Active low
PinLevel m_baLine = PinLevel::Low;
PinLevel m_bsLine = PinLevel::Low;
PinLevel m_baLine = PinLevel::Low; // Out, Bus available
PinLevel m_bsLine = PinLevel::Low; // Out, Bus status
bool m_prefix10 = false;
bool m_prefix11 = false;

View File

@ -108,7 +108,7 @@ bool EightBit::Disassembly::ignore() {
|| CPU().lowered(CPU().RESET())
|| CPU().lowered(CPU().NMI())
|| (CPU().lowered(CPU().FIRQ()) && !(CPU().CC() & mc6809::FF))
|| (CPU().lowered(CPU().IRQ()) && !(CPU().CC() & mc6809::IF));
|| (CPU().lowered(CPU().INT()) && !(CPU().CC() & mc6809::IF));
}
std::string EightBit::Disassembly::disassemble(uint16_t current) {

View File

@ -7,10 +7,60 @@
EightBit::mc6809::mc6809(Bus& bus)
: BigEndianProcessor(bus) {}
void EightBit::mc6809::powerOn() {
BigEndianProcessor::powerOn();
void EightBit::mc6809::raisePOWER() {
BigEndianProcessor::raisePOWER();
lowerBA();
lowerBS();
}
void EightBit::mc6809::lowerNMI() {
lower(NMI());
LoweredNMI.fire(EventArgs::empty());
}
void EightBit::mc6809::raiseNMI() {
raise(NMI());
RaisedNMI.fire(EventArgs::empty());
}
void EightBit::mc6809::lowerFIRQ() {
lower(FIRQ());
LoweredFIRQ.fire(EventArgs::empty());
}
void EightBit::mc6809::raiseFIRQ() {
raise(FIRQ());
RaisedFIRQ.fire(EventArgs::empty());
}
void EightBit::mc6809::lowerHALT() {
lower(HALT());
LoweredHALT.fire(EventArgs::empty());
}
void EightBit::mc6809::raiseHALT() {
raise(HALT());
RaisedHALT.fire(EventArgs::empty());
}
void EightBit::mc6809::lowerBA() {
lower(BA());
LoweredNMI.fire(EventArgs::empty());
}
void EightBit::mc6809::raiseBA() {
raise(BA());
RaisedBA.fire(EventArgs::empty());
}
void EightBit::mc6809::lowerBS() {
lower(BS());
LoweredBS.fire(EventArgs::empty());
}
void EightBit::mc6809::raiseBS() {
raise(BS());
RaisedBS.fire(EventArgs::empty());
}
int EightBit::mc6809::step() {
@ -26,8 +76,8 @@ int EightBit::mc6809::step() {
handleNMI();
else if (UNLIKELY(lowered(FIRQ()) && !fastInterruptMasked()))
handleFIRQ();
else if (UNLIKELY(lowered(IRQ()) && !interruptMasked()))
handleIRQ();
else if (UNLIKELY(lowered(INT()) && !interruptMasked()))
handleINT();
else
Processor::execute(fetchByte());
}
@ -38,15 +88,15 @@ int EightBit::mc6809::step() {
// Interrupt (etc.) handlers
void EightBit::mc6809::handleHALT() {
raise(BA());
raise(BS());
raiseBA();
raiseBS();
}
void EightBit::mc6809::handleRESET() {
BigEndianProcessor::handleRESET();
raise(NMI());
lower(BA());
raise(BS());
raiseNMI();
lowerBA();
raiseBS();
DP() = 0;
setFlag(CC(), IF); // Disable IRQ
setFlag(CC(), FF); // Disable FIRQ
@ -55,9 +105,9 @@ void EightBit::mc6809::handleRESET() {
}
void EightBit::mc6809::handleNMI() {
raise(NMI());
lower(BA());
raise(BS());
raiseNMI();
lowerBA();
raiseBS();
saveEntireRegisterState();
setFlag(CC(), IF); // Disable IRQ
setFlag(CC(), FF); // Disable FIRQ
@ -65,10 +115,10 @@ void EightBit::mc6809::handleNMI() {
tick(12);
}
void EightBit::mc6809::handleIRQ() {
BigEndianProcessor::handleIRQ();
lower(BA());
raise(BS());
void EightBit::mc6809::handleINT() {
BigEndianProcessor::handleINT();
lowerBA();
raiseBS();
saveEntireRegisterState();
setFlag(CC(), IF); // Disable IRQ
jump(getWordPaged(0xff, IRQvector));
@ -76,9 +126,9 @@ void EightBit::mc6809::handleIRQ() {
}
void EightBit::mc6809::handleFIRQ() {
raise(FIRQ());
lower(BA());
raise(BS());
raiseFIRQ();
lowerBA();
raiseBS();
savePartialRegisterState();
setFlag(CC(), IF); // Disable IRQ
setFlag(CC(), FF); // Disable FIRQ
@ -89,8 +139,8 @@ void EightBit::mc6809::handleFIRQ() {
//
int EightBit::mc6809::execute() {
lower(BA());
lower(BS());
lowerBA();
lowerBS();
const bool prefixed = m_prefix10 || m_prefix11;
const bool unprefixed = !prefixed;
if (unprefixed) {

View File

@ -4,29 +4,31 @@
Board::Board(const Configuration& configuration)
: m_configuration(configuration) {}
void Board::powerOn() {
void Board::raisePOWER() {
EightBit::Bus::powerOn();
EightBit::Bus::raisePOWER();
// Get the CPU ready for action
CPU().powerOn();
CPU().raise(CPU().NMI());
CPU().raise(CPU().FIRQ());
CPU().reset();
CPU().raisePOWER();
CPU().lowerRESET();
CPU().raiseINT();
CPU().raiseNMI();
CPU().raiseFIRQ();
CPU().raiseHALT();
// Get the ACIA ready for action
ADDRESS() = 0b1010000000000000;
ACIA().DATA() = EightBit::mc6850::CR0 | EightBit::mc6850::CR1; // Master reset
updateAciaPinsWrite();
ACIA().lower(ACIA().CTS());
ACIA().powerOn();
ACIA().raisePOWER();
accessAcia();
}
void Board::powerOff() {
ACIA().powerOff();
CPU().powerOff();
EightBit::Bus::powerOff();
void Board::lowerPOWER() {
ACIA().lowerPOWER();
CPU().lowerPOWER();
EightBit::Bus::lowerPOWER();
}
void Board::initialise() {
@ -88,7 +90,7 @@ void Board::initialise() {
assert(cpu.cycles() > 0);
m_totalCycleCount += cpu.cycles();
if (m_totalCycleCount > Configuration::TerminationCycles)
powerOff();
lowerPOWER();
});
}
}
@ -107,13 +109,12 @@ EightBit::MemoryMapping Board::mapping(uint16_t address) {
return { m_rom, 0xc000, EightBit::Chip::Mask16, EightBit::MemoryMapping::AccessLevel::ReadOnly };
}
void Board::updateAciaPins(const EightBit::Chip::PinLevel rw) {
ACIA().RW() = rw;
void Board::updateAciaPins() {
ACIA().DATA() = DATA();
ACIA().match(ACIA().RS(), ADDRESS().word & EightBit::Chip::Bit0);
ACIA().match(ACIA().CS0(), ADDRESS().word & EightBit::Chip::Bit15);
ACIA().match(ACIA().CS1(), ADDRESS().word & EightBit::Chip::Bit13);
ACIA().match(ACIA().CS2(), ADDRESS().word & EightBit::Chip::Bit14);
ADDRESS().word & EightBit::Chip::Bit0 ? ACIA().raise(ACIA().RS()) : ACIA().lower(ACIA().RS());
ADDRESS().word & EightBit::Chip::Bit15 ? ACIA().raise(ACIA().CS0()) : ACIA().lower(ACIA().CS0());
ADDRESS().word & EightBit::Chip::Bit13 ? ACIA().raise(ACIA().CS1()) : ACIA().lower(ACIA().CS1());
ADDRESS().word & EightBit::Chip::Bit14 ? ACIA().raise(ACIA().CS2()) : ACIA().lower(ACIA().CS2());
}
bool Board::accessAcia() {

View File

@ -19,11 +19,12 @@ public:
auto& CPU() { return m_cpu; }
auto& ACIA() { return m_acia; }
virtual void powerOn() final;
virtual void powerOff() final;
virtual void raisePOWER() final;
virtual void lowerPOWER() final;
virtual void initialise() final;
protected:
virtual void initialise() final;
virtual EightBit::MemoryMapping mapping(uint16_t address) final;
private:
@ -46,9 +47,17 @@ private:
bool m_ignoreDisassembly = false;
// Use the bus data to update the ACIA access/address pins
void updateAciaPinsRead() { updateAciaPins(EightBit::Chip::PinLevel::High); }
void updateAciaPinsWrite() { updateAciaPins(EightBit::Chip::PinLevel::Low); }
void updateAciaPins(EightBit::Chip::PinLevel rw);
void updateAciaPinsRead() {
ACIA().raise(ACIA().RW());
updateAciaPins();
}
void updateAciaPinsWrite() {
ACIA().lower(ACIA().RW());
updateAciaPins();
}
void updateAciaPins();
bool accessAcia();
};

View File

@ -6,17 +6,22 @@ Board::Board()
m_disassembler(*this, m_cpu) {
}
void Board::powerOn() {
EightBit::Bus::powerOn();
CPU().powerOn();
CPU().raise(CPU().NMI());
CPU().raise(CPU().FIRQ());
CPU().reset();
void Board::raisePOWER() {
EightBit::Bus::raisePOWER();
CPU().raisePOWER();
CPU().lowerRESET();
CPU().raiseINT();
CPU().raiseNMI();
CPU().raiseFIRQ();
CPU().raiseHALT();
}
void Board::powerOff() {
CPU().powerOff();
EightBit::Bus::powerOff();
void Board::lowerPOWER() {
CPU().lowerPOWER();
EightBit::Bus::lowerPOWER();
}
void Board::initialise() {

View File

@ -11,11 +11,12 @@ public:
EightBit::mc6809& CPU() { return m_cpu; }
virtual void powerOn() final;
virtual void powerOff() final;
virtual void raisePOWER() final;
virtual void lowerPOWER() final;
protected:
virtual void initialise() final;
virtual EightBit::MemoryMapping mapping(uint16_t address) final;
private:

View File

@ -9,7 +9,7 @@
TEST_CASE("Add Accumulator B to Index Register X Unsigned", "[ABX]") {
Board board;
board.powerOn();
board.raisePOWER();
auto& cpu = board.CPU();
cpu.step(); // Step over the reset
@ -70,7 +70,7 @@ TEST_CASE("Add Accumulator B to Index Register X Unsigned", "[ABX]") {
TEST_CASE("Add Memory Plus Carry to Accumulator", "[ADC][ADCA]") {
Board board;
board.powerOn();
board.raisePOWER();
auto& cpu = board.CPU();
cpu.step(); // Step over the reset
@ -153,7 +153,7 @@ TEST_CASE("Add Memory Plus Carry to Accumulator", "[ADC][ADCA]") {
TEST_CASE("Add Memory to Accumulator", "[ADD][ADDA][ADDB][ADDD]") {
Board board;
board.powerOn();
board.raisePOWER();
auto& cpu = board.CPU();
cpu.step(); // Step over the reset
@ -350,7 +350,7 @@ TEST_CASE("Add Memory to Accumulator", "[ADD][ADDA][ADDB][ADDD]") {
TEST_CASE("Logical AND Accumulator", "[AND][ANDA]") {
Board board;
board.powerOn();
board.raisePOWER();
auto& cpu = board.CPU();
cpu.step(); // Step over the reset
@ -370,7 +370,7 @@ TEST_CASE("Logical AND Accumulator", "[AND][ANDA]") {
TEST_CASE("Shift Accumulator or Memory Byte Left", "[ASL][ASLA]") {
Board board;
board.powerOn();
board.raisePOWER();
auto& cpu = board.CPU();
cpu.step(); // Step over the reset
@ -389,7 +389,7 @@ TEST_CASE("Shift Accumulator or Memory Byte Left", "[ASL][ASLA]") {
TEST_CASE("Shift Accumulator or Memory Byte Right", "[ASR][ASRA]") {
Board board;
board.powerOn();
board.raisePOWER();
auto& cpu = board.CPU();
cpu.step(); // Step over the reset
@ -408,7 +408,7 @@ TEST_CASE("Shift Accumulator or Memory Byte Right", "[ASR][ASRA]") {
TEST_CASE("Bit Test", "[BIT][BITA]") {
Board board;
board.powerOn();
board.raisePOWER();
auto& cpu = board.CPU();
cpu.step(); // Step over the reset
@ -427,7 +427,7 @@ TEST_CASE("Bit Test", "[BIT][BITA]") {
TEST_CASE("Clear Accumulator or Memory", "[CLR][CLRA]") {
Board board;
board.powerOn();
board.raisePOWER();
auto& cpu = board.CPU();
cpu.step(); // Step over the reset
@ -447,7 +447,7 @@ TEST_CASE("Clear Accumulator or Memory", "[CLR][CLRA]") {
TEST_CASE("Compare Memory with a Register", "[CMP][CMPA][CMPB][CMPX]") {
Board board;
board.powerOn();
board.raisePOWER();
auto& cpu = board.CPU();
cpu.step(); // Step over the reset
@ -544,7 +544,7 @@ TEST_CASE("Compare Memory with a Register", "[CMP][CMPA][CMPB][CMPX]") {
TEST_CASE("Decrement Accumulator or Memory", "[DEC][DECA]") {
Board board;
board.powerOn();
board.raisePOWER();
auto& cpu = board.CPU();
cpu.step(); // Step over the reset
@ -593,7 +593,7 @@ TEST_CASE("Decrement Accumulator or Memory", "[DEC][DECA]") {
TEST_CASE("Increment Accumulator or Memory Location by 1", "[INC][INCA]") {
Board board;
board.powerOn();
board.raisePOWER();
auto& cpu = board.CPU();
cpu.step(); // Step over the reset
@ -640,7 +640,7 @@ TEST_CASE("Increment Accumulator or Memory Location by 1", "[INC][INCA]") {
TEST_CASE("Subtract Memory from Accumulator with Borrow (8-bit)", "[SBC][SBCA][SBCB]") {
Board board;
board.powerOn();
board.raisePOWER();
auto& cpu = board.CPU();
cpu.step(); // Step over the reset
@ -729,7 +729,7 @@ TEST_CASE("Subtract Memory from Accumulator with Borrow (8-bit)", "[SBC][SBCA][S
TEST_CASE("Subtract Memory from Register", "[SUB][SUBA]") {
Board board;
board.powerOn();
board.raisePOWER();
auto& cpu = board.CPU();
cpu.step(); // Step over the reset
@ -826,7 +826,7 @@ TEST_CASE("Subtract Memory from Register", "[SUB][SUBA]") {
TEST_CASE(" Branch if Greater Than Zero", "[BGT]") {
Board board;
board.powerOn();
board.raisePOWER();
auto& cpu = board.CPU();
cpu.step(); // Step over the reset
@ -847,7 +847,7 @@ TEST_CASE(" Branch if Greater Than Zero", "[BGT]") {
REQUIRE(cpu.A() == 1);
}
cpu.reset();
cpu.lowerRESET();
cpu.step();
SECTION("BGT2") {
@ -858,7 +858,7 @@ TEST_CASE(" Branch if Greater Than Zero", "[BGT]") {
REQUIRE(cpu.A() == 2);
}
cpu.reset();
cpu.lowerRESET();
cpu.step();
SECTION("BGT3") {
@ -869,7 +869,7 @@ TEST_CASE(" Branch if Greater Than Zero", "[BGT]") {
REQUIRE(cpu.A() == 1);
}
cpu.reset();
cpu.lowerRESET();
cpu.step();
SECTION("BGT4") {
@ -880,7 +880,7 @@ TEST_CASE(" Branch if Greater Than Zero", "[BGT]") {
REQUIRE(cpu.A() == 2);
}
cpu.reset();
cpu.lowerRESET();
cpu.step();
SECTION("BGT5") {
@ -895,7 +895,7 @@ TEST_CASE(" Branch if Greater Than Zero", "[BGT]") {
TEST_CASE(" Branch if Higher", "[BHI]") {
Board board;
board.powerOn();
board.raisePOWER();
auto& cpu = board.CPU();
cpu.step(); // Step over the reset
@ -920,7 +920,7 @@ TEST_CASE(" Branch if Higher", "[BHI]") {
TEST_CASE("Branch on Less than or Equal to Zero", "[BLE]") {
Board board;
board.powerOn();
board.raisePOWER();
auto& cpu = board.CPU();
cpu.step(); // Step over the reset
@ -941,7 +941,7 @@ TEST_CASE("Branch on Less than or Equal to Zero", "[BLE]") {
REQUIRE(cpu.A() == 2);
}
cpu.reset();
cpu.lowerRESET();
cpu.step();
SECTION("BLE2") {
@ -952,7 +952,7 @@ TEST_CASE("Branch on Less than or Equal to Zero", "[BLE]") {
REQUIRE(cpu.A() == 1);
}
cpu.reset();
cpu.lowerRESET();
cpu.step();
SECTION("BLE3") {
@ -963,7 +963,7 @@ TEST_CASE("Branch on Less than or Equal to Zero", "[BLE]") {
REQUIRE(cpu.A() == 2);
}
cpu.reset();
cpu.lowerRESET();
cpu.step();
SECTION("BLE4") {
@ -974,7 +974,7 @@ TEST_CASE("Branch on Less than or Equal to Zero", "[BLE]") {
REQUIRE(cpu.A() == 1);
}
cpu.reset();
cpu.lowerRESET();
cpu.step();
SECTION("BLE5") {

View File

@ -8,7 +8,7 @@
namespace EightBit {
class mc6850 final : public ClockedChip {
public:
void powerOn() final;
void raisePOWER() final;
// +--------+----------------------------------------------------------------------------------+
// | | Buffer address |
@ -271,10 +271,6 @@ namespace EightBit {
void startTransmit();
void completeReceive();
bool isInterruptRequired() const;
bool isTransmitInterruptRequired() const;
bool isReceiveInterruptRequired() const;
bool transmitInterruptEnabled() const { return m_transmitControl == ReadyLowInterruptEnabled; }
bool receiveInterruptEnabled() const { return m_receiveControl == ReceiveInterruptEnable; }

Binary file not shown.

View File

@ -10,15 +10,18 @@ Fuse::TestRunner::TestRunner(const Test& test, const ExpectedTestResult& expecte
//
void Fuse::TestRunner::powerOn() {
EightBit::Bus::powerOn();
m_cpu.powerOn();
void Fuse::TestRunner::raisePOWER() {
EightBit::Bus::raisePOWER();
m_cpu.raisePOWER();
m_cpu.raiseRESET();
m_cpu.raiseINT();
m_cpu.raiseNMI();
initialiseRegisters();
}
void Fuse::TestRunner::powerOff() {
m_cpu.powerOff();
EightBit::Bus::powerOff();
void Fuse::TestRunner::lowerPOWER() {
m_cpu.lowerPOWER();
EightBit::Bus::lowerPOWER();
}
void Fuse::TestRunner::initialise() {
@ -327,8 +330,8 @@ void Fuse::TestRunner::checkMemory() {
}
void Fuse::TestRunner::run() {
powerOn();
raisePOWER();
initialise();
auto allowedCycles = m_test.registerState.tstates;
try {
m_cpu.run(allowedCycles);

View File

@ -35,7 +35,6 @@ namespace Fuse {
EightBit::register16_t actual, EightBit::register16_t expected) const;
protected:
virtual void initialise() final;
virtual EightBit::MemoryMapping mapping(uint16_t address) final {
return { m_ram, 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite };
}
@ -47,7 +46,9 @@ namespace Fuse {
bool failed() const { return m_failed; }
bool unimplemented() const { return m_unimplemented; }
virtual void powerOn() final;
virtual void powerOff() final;
virtual void raisePOWER() final;
virtual void lowerPOWER() final;
virtual void initialise() final;
};
}

View File

@ -7,6 +7,7 @@
#include <Bus.h>
#include <InputOutput.h>
#include <IntelProcessor.h>
#include <EventArgs.h>
#include <Signal.h>
#include <Register.h>
#include <EightBitCompilerDefinitions.h>
@ -51,12 +52,22 @@ namespace EightBit {
Signal<Z80> ExecutingInstruction;
Signal<Z80> ExecutedInstruction;
Signal<EventArgs> RaisedNMI;
Signal<EventArgs> LoweredNMI;
Signal<EventArgs> RaisedM1;
Signal<EventArgs> LoweredM1;
[[nodiscard]] auto& NMI() { return m_nmiLine; } // In
[[nodiscard]] auto& M1() { return m_m1Line; } // Out
int execute() final;
int step() final;
void powerOn() final;
void raisePOWER() final;
void raiseNMI();
void lowerNMI();
[[nodiscard]] register16_t& AF() final;
[[nodiscard]] register16_t& BC() final;
@ -90,8 +101,8 @@ namespace EightBit {
void handleINT() final;
private:
PinLevel m_nmiLine = PinLevel::Low;
PinLevel m_m1Line = PinLevel::Low;
PinLevel m_nmiLine = PinLevel::Low; // In, Active low
PinLevel m_m1Line = PinLevel::Low; // Out, Active low
InputOutput& m_ports;
@ -121,6 +132,9 @@ namespace EightBit {
int8_t m_displacement = 0;
bool m_displaced = false;
void raiseM1();
void lowerM1();
void handleNMI();
[[nodiscard]] uint16_t displacedAddress() {

View File

@ -24,12 +24,11 @@ EightBit::register16_t& EightBit::Z80::HL() {
return m_registers[m_registerSet][HL_IDX];
}
void EightBit::Z80::powerOn() {
void EightBit::Z80::raisePOWER() {
IntelProcessor::powerOn();
IntelProcessor::raisePOWER();
raise(NMI());
raise(M1());
raiseM1();
di();
IM() = 0;
@ -46,6 +45,26 @@ void EightBit::Z80::powerOn() {
m_prefixCB = m_prefixDD = m_prefixED = m_prefixFD = false;
}
void EightBit::Z80::raiseNMI() {
raise(NMI());
RaisedNMI.fire(EventArgs::empty());
}
void EightBit::Z80::lowerNMI() {
lower(NMI());
LoweredNMI.fire(EventArgs::empty());
}
void EightBit::Z80::raiseM1() {
raise(M1());
RaisedM1.fire(EventArgs::empty());
}
void EightBit::Z80::lowerM1() {
lower(M1());
LoweredM1.fire(EventArgs::empty());
}
void EightBit::Z80::handleRESET() {
IntelProcessor::handleRESET();
di();
@ -53,8 +72,8 @@ void EightBit::Z80::handleRESET() {
}
void EightBit::Z80::handleNMI() {
raise(NMI());
raise(HALT());
raiseNMI();
raiseHALT();
IFF1() = false;
restart(0x66);
tick(13);
@ -62,12 +81,12 @@ void EightBit::Z80::handleNMI() {
void EightBit::Z80::handleINT() {
IntelProcessor::handleINT();
raise(HALT());
raiseHALT();
if (IFF1()) {
di();
switch (IM()) {
case 0: // i8080 equivalent
Processor::execute(BUS().DATA());
IntelProcessor::execute(BUS().DATA());
break;
case 1:
restart(7 << 3);
@ -663,7 +682,7 @@ int EightBit::Z80::step() {
ExecutingInstruction.fire(*this);
if (LIKELY(powered())) {
m_displaced = m_prefixCB = m_prefixDD = m_prefixED = m_prefixFD = false;
lower(M1());
lowerM1();
if (UNLIKELY(lowered(RESET()))) {
handleRESET();
} else if (UNLIKELY(lowered(NMI()))) {
@ -671,9 +690,9 @@ int EightBit::Z80::step() {
} else if (UNLIKELY(lowered(INT()))) {
handleINT();
} else if (UNLIKELY(lowered(HALT()))) {
Processor::execute(0); // NOP
IntelProcessor::execute(0); // NOP
} else {
Processor::execute(fetchByte());
IntelProcessor::execute(fetchByte());
}
}
ExecutedInstruction.fire(*this);
@ -686,7 +705,7 @@ int EightBit::Z80::execute() {
if (LIKELY(!(m_prefixCB && m_displaced))) {
++REFRESH();
raise(M1());
raiseM1();
}
const auto& decoded = getDecodedOpcode(opcode());
@ -1363,8 +1382,8 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
m_prefixCB = true;
if (UNLIKELY(m_displaced))
fetchDisplacement();
lower(M1());
Processor::execute(fetchByte());
lowerM1();
IntelProcessor::execute(fetchByte());
break;
case 2: // OUT (n),A
writePort(fetchByte());
@ -1413,18 +1432,18 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
break;
case 1: // DD prefix
m_displaced = m_prefixDD = true;
lower(M1());
Processor::execute(fetchByte());
lowerM1();
IntelProcessor::execute(fetchByte());
break;
case 2: // ED prefix
m_prefixED = true;
lower(M1());
Processor::execute(fetchByte());
lowerM1();
IntelProcessor::execute(fetchByte());
break;
case 3: // FD prefix
m_displaced = m_prefixFD = true;
lower(M1());
Processor::execute(fetchByte());
lowerM1();
IntelProcessor::execute(fetchByte());
break;
default:
UNREACHABLE;

View File

@ -4,15 +4,17 @@
Board::Board(const Configuration& configuration)
: m_configuration(configuration) {}
void Board::powerOn() {
EightBit::Bus::powerOn();
CPU().powerOn();
CPU().reset();
void Board::raisePOWER() {
EightBit::Bus::raisePOWER();
CPU().raisePOWER();
CPU().raiseRESET();
CPU().raiseINT();
CPU().raiseNMI();
}
void Board::powerOff() noexcept {
CPU().powerOff();
EightBit::Bus::powerOff();
void Board::lowerPOWER() noexcept {
CPU().lowerPOWER();
EightBit::Bus::lowerPOWER();
}
void Board::initialise() {
@ -20,13 +22,15 @@ void Board::initialise() {
auto romDirectory = m_configuration.getRomDirectory();
m_ram.load(romDirectory + "/zexall.com", 0x100); // Cringle/Bartholomew
m_cpu.LoweredHALT.connect([this](EightBit::EventArgs) {
lowerPOWER();
});
m_cpu.ExecutingInstruction.connect([this] (EightBit::Z80& cpu) {
if (UNLIKELY(EightBit::Chip::lowered(cpu.HALT())))
powerOff();
switch (cpu.PC().word) {
case 0x0: // CP/M warm start
if (++m_warmstartCount == 3) {
powerOff();
if (++m_warmstartCount == 2) {
lowerPOWER();
if (m_configuration.isProfileMode())
m_profiler.dump();
}

View File

@ -18,11 +18,12 @@ public:
EightBit::Z80& CPU() noexcept { return m_cpu; }
void powerOn() final;
void powerOff() noexcept final;
void raisePOWER() final;
void lowerPOWER() noexcept final;
void initialise() final;
protected:
void initialise() final;
EightBit::MemoryMapping mapping(uint16_t address) noexcept final {
return { m_ram, 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite };
}

View File

@ -48,12 +48,12 @@ namespace EightBit {
write(value);
}
virtual void powerOn();
virtual void powerOff();
virtual void raisePOWER();
virtual void lowerPOWER();
protected:
virtual void initialise() = 0;
protected:
[[nodiscard]] uint8_t& reference(uint16_t address);
[[nodiscard]] auto& reference(const register16_t address) { return reference(address.word); }
[[nodiscard]] uint8_t& reference() { return reference(ADDRESS()); }

View File

@ -1,5 +1,8 @@
#pragma once
#include "EventArgs.h"
#include "Signal.h"
namespace EightBit {
class Device {
public:
@ -12,20 +15,21 @@ namespace EightBit {
static constexpr auto lowered(const PinLevel line) { return line == PinLevel::Low; }
static void lower(PinLevel& line) noexcept { line = PinLevel::Low; }
static void match(PinLevel& line, int value);
virtual ~Device() {};
Signal<EventArgs> RaisedPOWER;
Signal<EventArgs> LoweredPOWER;
[[nodiscard]] auto& POWER() noexcept { return m_powerLine; }
[[nodiscard]] auto powered() noexcept { return raised(POWER()); }
virtual void powerOn();
virtual void powerOff() { lower(POWER()); }
virtual void raisePOWER();
virtual void lowerPOWER();
protected:
Device() {};
private:
PinLevel m_powerLine = PinLevel::Low;
PinLevel m_powerLine = PinLevel::Low; // In
};
}

View File

@ -6,7 +6,8 @@
#include "Bus.h"
#include "LittleEndianProcessor.h"
#include "Register.h"
#include "EventArgs.h"
#include "Signal.h"
#include "EightBitCompilerDefinitions.h"
namespace EightBit {
@ -33,6 +34,11 @@ namespace EightBit {
~IntelProcessor() = default;
Signal<EventArgs> RaisedHALT;
Signal<EventArgs> LoweredHALT;
[[nodiscard]] auto& HALT() noexcept { return m_haltLine; }
[[nodiscard]] const auto& getDecodedOpcode(const size_t i) const noexcept {
return m_decodedOpcodes[i];
}
@ -57,7 +63,7 @@ namespace EightBit {
[[nodiscard]] auto& H() { return HL().high; }
[[nodiscard]] auto& L() { return HL().low; }
void powerOn() override;
void raisePOWER() override;
protected:
IntelProcessor(Bus& bus);
@ -117,6 +123,8 @@ namespace EightBit {
return m_halfCarryTableSub[index & Mask3];
}
void handleRESET() override;
void push(uint8_t value) final;
[[nodiscard]] uint8_t pop() final;
@ -164,9 +172,18 @@ namespace EightBit {
void ret() final;
[[nodiscard]] auto halted() noexcept { return lowered(HALT()); }
void halt() noexcept { --PC(); lowerHALT(); }
void proceed() noexcept { ++PC(); raiseHALT(); }
virtual void lowerHALT();
virtual void raiseHALT();
private:
std::array<opcode_decoded_t, 0x100> m_decodedOpcodes;
register16_t m_sp = Mask16;
register16_t m_memptr;
PinLevel m_haltLine = PinLevel::Low; // Out, Active low
};
}

View File

@ -5,6 +5,8 @@
#include "ClockedChip.h"
#include "Bus.h"
#include "Register.h"
#include "EventArgs.h"
#include "Signal.h"
#include "EightBitCompilerDefinitions.h"
@ -17,15 +19,22 @@ namespace EightBit {
~Processor() {};
Signal<EventArgs> RaisedRESET;
Signal<EventArgs> LoweredRESET;
Signal<EventArgs> RaisedINT;
Signal<EventArgs> LoweredINT;
[[nodiscard]] auto& PC() noexcept { return m_pc; }
[[nodiscard]] auto& RESET() noexcept { return m_resetLine; }
[[nodiscard]] auto& HALT() noexcept { return m_haltLine; }
[[nodiscard]] auto& INT() noexcept { return m_intLine; }
[[nodiscard]] auto& IRQ() noexcept { return INT(); } // Synonym
void powerOn() override;
void reset() noexcept { lower(RESET()); }
virtual void lowerRESET();
virtual void raiseRESET();
virtual void lowerINT();
virtual void raiseINT();
int run(int limit);
virtual int step() = 0;
@ -41,13 +50,8 @@ namespace EightBit {
[[nodiscard]] auto& opcode() noexcept { return m_opcode; }
[[nodiscard]] auto& BUS() noexcept { return m_bus; }
[[nodiscard]] auto halted() noexcept { return lowered(HALT()); }
void halt() noexcept { --PC(); lower(HALT()); }
void proceed() noexcept { ++PC(); raise(HALT()); }
virtual void handleRESET();
virtual void handleINT();
virtual void handleIRQ();
void busWrite(register16_t address, uint8_t data);
void busWrite(uint8_t data);
@ -108,8 +112,7 @@ namespace EightBit {
uint8_t m_opcode = Mask8;
register16_t m_pc;
PinLevel m_intLine = PinLevel::Low;
PinLevel m_haltLine = PinLevel::Low;
PinLevel m_resetLine = PinLevel::Low;
PinLevel m_intLine = PinLevel::Low; // In
PinLevel m_resetLine = PinLevel::Low; // In
};
}

View File

@ -60,7 +60,8 @@ namespace EightBit {
m_totalCycles = m_instructions = 0L;
m_startHostCycles = currentHostCycles();
m_board.powerOn();
m_board.initialise();
m_board.raisePOWER();
auto& cpu = m_board.CPU();

View File

@ -8,11 +8,9 @@
#include <stdexcept>
#include <cassert>
void EightBit::Bus::powerOn() {
initialise();
}
void EightBit::Bus::raisePOWER() {}
void EightBit::Bus::powerOff() {}
void EightBit::Bus::lowerPOWER() {}
uint8_t EightBit::Bus::read() {
ReadingByte.fire(EventArgs::empty());

View File

@ -1,10 +1,12 @@
#include "stdafx.h"
#include "Device.h"
void EightBit::Device::powerOn() {
void EightBit::Device::raisePOWER() {
raise(POWER());
RaisedPOWER.fire(EventArgs::empty());
}
void EightBit::Device::match(PinLevel& line, int value) {
value ? raise(line) : lower(line);
void EightBit::Device::lowerPOWER() {
lower(POWER());
LoweredPOWER.fire(EventArgs::empty());
}

View File

@ -7,11 +7,27 @@ EightBit::IntelProcessor::IntelProcessor(Bus& bus)
m_decodedOpcodes[i] = i;
}
void EightBit::IntelProcessor::powerOn() {
Processor::powerOn();
void EightBit::IntelProcessor::raisePOWER() {
Processor::raisePOWER();
raiseHALT();
SP() = AF() = BC() = DE() = HL() = Mask16;
}
void EightBit::IntelProcessor::lowerHALT() {
lower(HALT());
LoweredHALT.fire(EventArgs::empty());
}
void EightBit::IntelProcessor::raiseHALT() {
raise(HALT());
RaisedHALT.fire(EventArgs::empty());
}
void EightBit::IntelProcessor::handleRESET() {
Processor::handleRESET();
PC() = 0;
}
void EightBit::IntelProcessor::push(const uint8_t value) {
BUS().write(--SP(), value);
}

View File

@ -5,24 +5,32 @@ EightBit::Processor::Processor(Bus& bus)
: m_bus(bus) {
}
void EightBit::Processor::powerOn() {
Chip::powerOn();
void EightBit::Processor::lowerRESET() {
lower(RESET());
LoweredRESET.fire(EventArgs::empty());
}
void EightBit::Processor::raiseRESET() {
raise(RESET());
raise(HALT());
RaisedRESET.fire(EventArgs::empty());
}
void EightBit::Processor::lowerINT() {
lower(INT());
LoweredINT.fire(EventArgs::empty());
}
void EightBit::Processor::raiseINT() {
raise(INT());
RaisedINT.fire(EventArgs::empty());
}
void EightBit::Processor::handleRESET() {
raise(RESET());
PC() = 0;
raiseRESET();
}
void EightBit::Processor::handleINT() {
raise(INT());
}
void EightBit::Processor::handleIRQ() {
raise(IRQ());
raiseINT();
}
void EightBit::Processor::busWrite(const register16_t address, const uint8_t data) {