mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-06-15 05:29:28 +00:00
Use macros to define our device pins.
Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
parent
4d08487513
commit
f0376fa81e
|
@ -32,7 +32,7 @@ void EightBit::Intel8080::handleRESET() {
|
||||||
|
|
||||||
void EightBit::Intel8080::handleINT() {
|
void EightBit::Intel8080::handleINT() {
|
||||||
IntelProcessor::handleINT();
|
IntelProcessor::handleINT();
|
||||||
raise(HALT());
|
raiseHALT();
|
||||||
if (m_interruptEnable) {
|
if (m_interruptEnable) {
|
||||||
di();
|
di();
|
||||||
Processor::execute(BUS().DATA());
|
Processor::execute(BUS().DATA());
|
||||||
|
|
|
@ -35,7 +35,7 @@ void EightBit::GameBoy::LR35902::handleRESET() {
|
||||||
|
|
||||||
void EightBit::GameBoy::LR35902::handleINT() {
|
void EightBit::GameBoy::LR35902::handleINT() {
|
||||||
IntelProcessor::handleINT();
|
IntelProcessor::handleINT();
|
||||||
raise(HALT());
|
raiseHALT();
|
||||||
di();
|
di();
|
||||||
restart(BUS().DATA());
|
restart(BUS().DATA());
|
||||||
tick(4);
|
tick(4);
|
||||||
|
@ -312,7 +312,7 @@ int EightBit::GameBoy::LR35902::step() {
|
||||||
if (masked) {
|
if (masked) {
|
||||||
if (IME()) {
|
if (IME()) {
|
||||||
m_bus.IO().poke(IoRegisters::IF, 0);
|
m_bus.IO().poke(IoRegisters::IF, 0);
|
||||||
lower(INT());
|
lowerINT();
|
||||||
const int index = EightBit::findFirstSet(masked);
|
const int index = EightBit::findFirstSet(masked);
|
||||||
BUS().DATA() = 0x38 + (index << 3);
|
BUS().DATA() = 0x38 + (index << 3);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -31,31 +31,10 @@ namespace EightBit {
|
||||||
Signal<MOS6502> ExecutingInstruction;
|
Signal<MOS6502> ExecutingInstruction;
|
||||||
Signal<MOS6502> ExecutedInstruction;
|
Signal<MOS6502> ExecutedInstruction;
|
||||||
|
|
||||||
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 execute() final;
|
||||||
int step() final;
|
int step() final;
|
||||||
void raisePOWER() 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& X() { return x; }
|
||||||
auto& Y() { return y; }
|
auto& Y() { return y; }
|
||||||
auto& A() { return a; }
|
auto& A() { return a; }
|
||||||
|
@ -64,15 +43,12 @@ namespace EightBit {
|
||||||
auto& P() { return p; }
|
auto& P() { return p; }
|
||||||
const auto& P() const { return p; }
|
const auto& P() const { return p; }
|
||||||
|
|
||||||
auto& NMI() { return m_nmiLine; } // In
|
DECLARE_PIN_INPUT(NMI)
|
||||||
auto& SO() { return m_soLine; } // In
|
DECLARE_PIN_INPUT(SO)
|
||||||
auto& SYNC() { return m_syncLine; } // Out
|
DECLARE_PIN_OUTPUT(SYNC)
|
||||||
auto& RDY() { return m_rdyLine; } // In
|
DECLARE_PIN_INPUT(RDY)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void lowerSYNC();
|
|
||||||
virtual void raiseSYNC();
|
|
||||||
|
|
||||||
virtual void handleRESET() final;
|
virtual void handleRESET() final;
|
||||||
virtual void handleINT() final;
|
virtual void handleINT() final;
|
||||||
|
|
||||||
|
@ -211,11 +187,6 @@ namespace EightBit {
|
||||||
uint8_t s = 0; // stack pointer
|
uint8_t s = 0; // stack pointer
|
||||||
uint8_t p = 0; // processor status
|
uint8_t p = 0; // processor status
|
||||||
|
|
||||||
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;
|
register16_t m_intermediate;
|
||||||
|
|
||||||
bool m_handlingRESET = false;
|
bool m_handlingRESET = false;
|
||||||
|
|
|
@ -4,6 +4,11 @@
|
||||||
EightBit::MOS6502::MOS6502(Bus& bus)
|
EightBit::MOS6502::MOS6502(Bus& bus)
|
||||||
: LittleEndianProcessor(bus) {}
|
: LittleEndianProcessor(bus) {}
|
||||||
|
|
||||||
|
DEFINE_PIN_LEVEL_CHANGERS(NMI, MOS6502);
|
||||||
|
DEFINE_PIN_LEVEL_CHANGERS(SO, MOS6502);
|
||||||
|
DEFINE_PIN_LEVEL_CHANGERS(SYNC, MOS6502);
|
||||||
|
DEFINE_PIN_LEVEL_CHANGERS(RDY, MOS6502);
|
||||||
|
|
||||||
void EightBit::MOS6502::raisePOWER() {
|
void EightBit::MOS6502::raisePOWER() {
|
||||||
LittleEndianProcessor::raisePOWER();
|
LittleEndianProcessor::raisePOWER();
|
||||||
X() = Bit7;
|
X() = Bit7;
|
||||||
|
@ -14,46 +19,6 @@ void EightBit::MOS6502::raisePOWER() {
|
||||||
lowerSYNC();
|
lowerSYNC();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::MOS6502::lowerNMI() {
|
|
||||||
lower(NMI());
|
|
||||||
LoweredNMI.fire(EventArgs::empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::MOS6502::raiseNMI() {
|
|
||||||
raise(NMI());
|
|
||||||
RaisedNMI.fire(EventArgs::empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::MOS6502::lowerSO() {
|
|
||||||
lower(SO());
|
|
||||||
LoweredSO.fire(EventArgs::empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::MOS6502::raiseSO() {
|
|
||||||
raise(SO());
|
|
||||||
RaisedSO.fire(EventArgs::empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::MOS6502::lowerSYNC() {
|
|
||||||
lower(SYNC());
|
|
||||||
LoweredSYNC.fire(EventArgs::empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::MOS6502::raiseSYNC() {
|
|
||||||
raise(SYNC());
|
|
||||||
RaisedSYNC.fire(EventArgs::empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::MOS6502::lowerRDY() {
|
|
||||||
lower(RDY());
|
|
||||||
LoweredRDY.fire(EventArgs::empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::MOS6502::raiseRDY() {
|
|
||||||
raise(RDY());
|
|
||||||
RaisedRDY.fire(EventArgs::empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
int EightBit::MOS6502::step() {
|
int EightBit::MOS6502::step() {
|
||||||
resetCycles();
|
resetCycles();
|
||||||
ExecutingInstruction.fire(*this);
|
ExecutingInstruction.fire(*this);
|
||||||
|
@ -98,7 +63,7 @@ void EightBit::MOS6502::handleNMI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::MOS6502::handleINT() {
|
void EightBit::MOS6502::handleINT() {
|
||||||
raise(INT());
|
raiseINT();
|
||||||
m_handlingINT = true;
|
m_handlingINT = true;
|
||||||
opcode() = 0x00; // BRK
|
opcode() = 0x00; // BRK
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,35 +57,11 @@ namespace EightBit {
|
||||||
Signal<mc6809> ExecutingInstruction;
|
Signal<mc6809> ExecutingInstruction;
|
||||||
Signal<mc6809> ExecutedInstruction;
|
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 execute() final;
|
||||||
virtual int step() final;
|
virtual int step() final;
|
||||||
|
|
||||||
virtual void raisePOWER() 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& D() { return m_d; }
|
||||||
auto& A() { return D().high; }
|
auto& A() { return D().high; }
|
||||||
auto& B() { return D().low; }
|
auto& B() { return D().low; }
|
||||||
|
@ -99,10 +75,6 @@ namespace EightBit {
|
||||||
auto& CC() { return m_cc; }
|
auto& CC() { return m_cc; }
|
||||||
const auto& CC() const { return m_cc; }
|
const auto& CC() const { return m_cc; }
|
||||||
|
|
||||||
[[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 | |
|
// | MPU State | |
|
||||||
// |_______________| MPU State Definition |
|
// |_______________| MPU State Definition |
|
||||||
|
@ -114,13 +86,16 @@ namespace EightBit {
|
||||||
// | 1 | 1 | HALT Acknowledge |
|
// | 1 | 1 | HALT Acknowledge |
|
||||||
// |-------|-------|-----------------------------------|
|
// |-------|-------|-----------------------------------|
|
||||||
|
|
||||||
auto& BA() { return m_baLine; } // Out
|
|
||||||
auto& BS() { return m_bsLine; } // Out
|
|
||||||
|
|
||||||
[[nodiscard]] auto halted() noexcept { return lowered(HALT()); }
|
[[nodiscard]] auto halted() noexcept { return lowered(HALT()); }
|
||||||
void halt() noexcept { --PC(); lowerHALT(); }
|
void halt() noexcept { --PC(); lowerHALT(); }
|
||||||
void proceed() noexcept { ++PC(); raiseHALT(); }
|
void proceed() noexcept { ++PC(); raiseHALT(); }
|
||||||
|
|
||||||
|
DECLARE_PIN_INPUT(NMI)
|
||||||
|
DECLARE_PIN_INPUT(FIRQ)
|
||||||
|
DECLARE_PIN_INPUT(HALT)
|
||||||
|
DECLARE_PIN_OUTPUT(BA)
|
||||||
|
DECLARE_PIN_OUTPUT(BS)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Default push/pop handlers
|
// Default push/pop handlers
|
||||||
|
|
||||||
|
@ -132,14 +107,6 @@ namespace EightBit {
|
||||||
virtual void handleRESET() final;
|
virtual void handleRESET() final;
|
||||||
virtual void handleINT() final;
|
virtual void handleINT() final;
|
||||||
|
|
||||||
// Line handlers
|
|
||||||
|
|
||||||
virtual void lowerBA();
|
|
||||||
virtual void raiseBA();
|
|
||||||
|
|
||||||
virtual void lowerBS();
|
|
||||||
virtual void raiseBS();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const uint8_t RESETvector = 0xfe; // RESET vector
|
const uint8_t RESETvector = 0xfe; // RESET vector
|
||||||
const uint8_t NMIvector = 0xfc; // NMI vector
|
const uint8_t NMIvector = 0xfc; // NMI vector
|
||||||
|
@ -405,13 +372,6 @@ namespace EightBit {
|
||||||
uint8_t m_dp = 0;
|
uint8_t m_dp = 0;
|
||||||
uint8_t m_cc = 0;
|
uint8_t m_cc = 0;
|
||||||
|
|
||||||
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; // Out, Bus available
|
|
||||||
PinLevel m_bsLine = PinLevel::Low; // Out, Bus status
|
|
||||||
|
|
||||||
bool m_prefix10 = false;
|
bool m_prefix10 = false;
|
||||||
bool m_prefix11 = false;
|
bool m_prefix11 = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,62 +7,18 @@
|
||||||
EightBit::mc6809::mc6809(Bus& bus)
|
EightBit::mc6809::mc6809(Bus& bus)
|
||||||
: BigEndianProcessor(bus) {}
|
: BigEndianProcessor(bus) {}
|
||||||
|
|
||||||
|
DEFINE_PIN_LEVEL_CHANGERS(NMI, mc6809);
|
||||||
|
DEFINE_PIN_LEVEL_CHANGERS(FIRQ, mc6809);
|
||||||
|
DEFINE_PIN_LEVEL_CHANGERS(HALT, mc6809);
|
||||||
|
DEFINE_PIN_LEVEL_CHANGERS(BA, mc6809);
|
||||||
|
DEFINE_PIN_LEVEL_CHANGERS(BS, mc6809);
|
||||||
|
|
||||||
void EightBit::mc6809::raisePOWER() {
|
void EightBit::mc6809::raisePOWER() {
|
||||||
BigEndianProcessor::raisePOWER();
|
BigEndianProcessor::raisePOWER();
|
||||||
lowerBA();
|
lowerBA();
|
||||||
lowerBS();
|
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() {
|
int EightBit::mc6809::step() {
|
||||||
resetCycles();
|
resetCycles();
|
||||||
ExecutingInstruction.fire(*this);
|
ExecutingInstruction.fire(*this);
|
||||||
|
|
|
@ -52,23 +52,11 @@ namespace EightBit {
|
||||||
Signal<Z80> ExecutingInstruction;
|
Signal<Z80> ExecutingInstruction;
|
||||||
Signal<Z80> ExecutedInstruction;
|
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 execute() final;
|
||||||
int step() final;
|
int step() final;
|
||||||
|
|
||||||
void raisePOWER() final;
|
void raisePOWER() final;
|
||||||
|
|
||||||
void raiseNMI();
|
|
||||||
void lowerNMI();
|
|
||||||
|
|
||||||
[[nodiscard]] register16_t& AF() final;
|
[[nodiscard]] register16_t& AF() final;
|
||||||
[[nodiscard]] register16_t& BC() final;
|
[[nodiscard]] register16_t& BC() final;
|
||||||
[[nodiscard]] register16_t& DE() final;
|
[[nodiscard]] register16_t& DE() final;
|
||||||
|
@ -96,14 +84,14 @@ namespace EightBit {
|
||||||
m_accumulatorFlagsSet = !m_accumulatorFlagsSet;
|
m_accumulatorFlagsSet = !m_accumulatorFlagsSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECLARE_PIN_INPUT(NMI)
|
||||||
|
DECLARE_PIN_OUTPUT(M1)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void handleRESET() final;
|
void handleRESET() final;
|
||||||
void handleINT() final;
|
void handleINT() final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PinLevel m_nmiLine = PinLevel::Low; // In, Active low
|
|
||||||
PinLevel m_m1Line = PinLevel::Low; // Out, Active low
|
|
||||||
|
|
||||||
InputOutput& m_ports;
|
InputOutput& m_ports;
|
||||||
|
|
||||||
enum { BC_IDX, DE_IDX, HL_IDX };
|
enum { BC_IDX, DE_IDX, HL_IDX };
|
||||||
|
@ -132,9 +120,6 @@ namespace EightBit {
|
||||||
int8_t m_displacement = 0;
|
int8_t m_displacement = 0;
|
||||||
bool m_displaced = false;
|
bool m_displaced = false;
|
||||||
|
|
||||||
void raiseM1();
|
|
||||||
void lowerM1();
|
|
||||||
|
|
||||||
void handleNMI();
|
void handleNMI();
|
||||||
|
|
||||||
[[nodiscard]] uint16_t displacedAddress() {
|
[[nodiscard]] uint16_t displacedAddress() {
|
||||||
|
|
|
@ -8,6 +8,9 @@ EightBit::Z80::Z80(Bus& bus, InputOutput& ports)
|
||||||
m_ports(ports) {
|
m_ports(ports) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_PIN_LEVEL_CHANGERS(NMI, Z80);
|
||||||
|
DEFINE_PIN_LEVEL_CHANGERS(M1, Z80);
|
||||||
|
|
||||||
EightBit::register16_t& EightBit::Z80::AF() {
|
EightBit::register16_t& EightBit::Z80::AF() {
|
||||||
return m_accumulatorFlags[m_accumulatorFlagsSet];
|
return m_accumulatorFlags[m_accumulatorFlagsSet];
|
||||||
}
|
}
|
||||||
|
@ -45,26 +48,6 @@ void EightBit::Z80::raisePOWER() {
|
||||||
m_prefixCB = m_prefixDD = m_prefixED = m_prefixFD = false;
|
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() {
|
void EightBit::Z80::handleRESET() {
|
||||||
IntelProcessor::handleRESET();
|
IntelProcessor::handleRESET();
|
||||||
di();
|
di();
|
||||||
|
|
61
inc/Device.h
61
inc/Device.h
|
@ -3,6 +3,55 @@
|
||||||
#include "EventArgs.h"
|
#include "EventArgs.h"
|
||||||
#include "Signal.h"
|
#include "Signal.h"
|
||||||
|
|
||||||
|
#define DECLARE_PIN_SIGNALS(name) \
|
||||||
|
Signal<EventArgs> Raising ## name; \
|
||||||
|
Signal<EventArgs> Raised ## name; \
|
||||||
|
Signal<EventArgs> Lowering ## name; \
|
||||||
|
Signal<EventArgs> Lowered ## name;
|
||||||
|
|
||||||
|
#define DECLARE_PIN_LEVEL_RAISE(name) \
|
||||||
|
virtual void raise ## name();
|
||||||
|
|
||||||
|
#define DECLARE_PIN_LEVEL_LOWER(name) \
|
||||||
|
virtual void lower ## name();
|
||||||
|
|
||||||
|
#define DECLARE_PIN_LEVEL_CHANGERS(name) \
|
||||||
|
DECLARE_PIN_LEVEL_RAISE(name) \
|
||||||
|
DECLARE_PIN_LEVEL_LOWER(name)
|
||||||
|
|
||||||
|
#define DEFINE_PIN_LEVEL_RAISE(name, within) \
|
||||||
|
void EightBit:: within ::raise ## name() { \
|
||||||
|
Raising ## name.fire(EventArgs::empty()); \
|
||||||
|
raise( name ()); \
|
||||||
|
Raised ## name.fire(EventArgs::empty()); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEFINE_PIN_LEVEL_LOWER(name, within) \
|
||||||
|
void EightBit:: within ::lower ## name() { \
|
||||||
|
Lowering ## name.fire(EventArgs::empty()); \
|
||||||
|
lower( name ()); \
|
||||||
|
Lowered ## name.fire(EventArgs::empty()); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEFINE_PIN_LEVEL_CHANGERS(name, within) \
|
||||||
|
DEFINE_PIN_LEVEL_RAISE(name, within) \
|
||||||
|
DEFINE_PIN_LEVEL_LOWER(name, within)
|
||||||
|
|
||||||
|
#define DECLARE_PIN_MEMBER(name) \
|
||||||
|
PinLevel m_## name ## _Line = PinLevel::Low;
|
||||||
|
|
||||||
|
#define DECLARE_PIN(name, visibility) \
|
||||||
|
public: DECLARE_PIN_SIGNALS(name) \
|
||||||
|
[[nodiscard]] PinLevel& name ## () noexcept { return m_## name ## _Line; } \
|
||||||
|
visibility : DECLARE_PIN_LEVEL_CHANGERS(name) \
|
||||||
|
private: DECLARE_PIN_MEMBER(name)
|
||||||
|
|
||||||
|
// Input pins have a degree of external control
|
||||||
|
#define DECLARE_PIN_INPUT(name) DECLARE_PIN(name, public)
|
||||||
|
|
||||||
|
// Output pins may only be internally controlled
|
||||||
|
#define DECLARE_PIN_OUTPUT(name) DECLARE_PIN(name, protected)
|
||||||
|
|
||||||
namespace EightBit {
|
namespace EightBit {
|
||||||
class Device {
|
class Device {
|
||||||
public:
|
public:
|
||||||
|
@ -17,19 +66,11 @@ namespace EightBit {
|
||||||
|
|
||||||
virtual ~Device() {};
|
virtual ~Device() {};
|
||||||
|
|
||||||
Signal<EventArgs> RaisedPOWER;
|
[[nodiscard]] bool powered() noexcept { return raised(POWER()); }
|
||||||
Signal<EventArgs> LoweredPOWER;
|
|
||||||
|
|
||||||
[[nodiscard]] auto& POWER() noexcept { return m_powerLine; }
|
DECLARE_PIN_INPUT(POWER)
|
||||||
|
|
||||||
[[nodiscard]] auto powered() noexcept { return raised(POWER()); }
|
|
||||||
virtual void raisePOWER();
|
|
||||||
virtual void lowerPOWER();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Device() {};
|
Device() {};
|
||||||
|
|
||||||
private:
|
|
||||||
PinLevel m_powerLine = PinLevel::Low; // In
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,11 +34,6 @@ namespace EightBit {
|
||||||
|
|
||||||
~IntelProcessor() = default;
|
~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 {
|
[[nodiscard]] const auto& getDecodedOpcode(const size_t i) const noexcept {
|
||||||
return m_decodedOpcodes[i];
|
return m_decodedOpcodes[i];
|
||||||
}
|
}
|
||||||
|
@ -65,6 +60,8 @@ namespace EightBit {
|
||||||
|
|
||||||
void raisePOWER() override;
|
void raisePOWER() override;
|
||||||
|
|
||||||
|
DECLARE_PIN_INPUT(HALT)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
IntelProcessor(Bus& bus);
|
IntelProcessor(Bus& bus);
|
||||||
|
|
||||||
|
@ -176,14 +173,9 @@ namespace EightBit {
|
||||||
void halt() noexcept { --PC(); lowerHALT(); }
|
void halt() noexcept { --PC(); lowerHALT(); }
|
||||||
void proceed() noexcept { ++PC(); raiseHALT(); }
|
void proceed() noexcept { ++PC(); raiseHALT(); }
|
||||||
|
|
||||||
virtual void lowerHALT();
|
|
||||||
virtual void raiseHALT();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::array<opcode_decoded_t, 0x100> m_decodedOpcodes;
|
std::array<opcode_decoded_t, 0x100> m_decodedOpcodes;
|
||||||
register16_t m_sp = Mask16;
|
register16_t m_sp = Mask16;
|
||||||
register16_t m_memptr;
|
register16_t m_memptr;
|
||||||
|
|
||||||
PinLevel m_haltLine = PinLevel::Low; // Out, Active low
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,23 +19,8 @@ namespace EightBit {
|
||||||
|
|
||||||
~Processor() {};
|
~Processor() {};
|
||||||
|
|
||||||
Signal<EventArgs> RaisedRESET;
|
|
||||||
Signal<EventArgs> LoweredRESET;
|
|
||||||
|
|
||||||
Signal<EventArgs> RaisedINT;
|
|
||||||
Signal<EventArgs> LoweredINT;
|
|
||||||
|
|
||||||
[[nodiscard]] auto& PC() noexcept { return m_pc; }
|
[[nodiscard]] auto& PC() noexcept { return m_pc; }
|
||||||
|
|
||||||
[[nodiscard]] auto& RESET() noexcept { return m_resetLine; }
|
|
||||||
[[nodiscard]] auto& INT() noexcept { return m_intLine; }
|
|
||||||
|
|
||||||
virtual void lowerRESET();
|
|
||||||
virtual void raiseRESET();
|
|
||||||
|
|
||||||
virtual void lowerINT();
|
|
||||||
virtual void raiseINT();
|
|
||||||
|
|
||||||
int run(int limit);
|
int run(int limit);
|
||||||
virtual int step() = 0;
|
virtual int step() = 0;
|
||||||
virtual int execute() = 0;
|
virtual int execute() = 0;
|
||||||
|
@ -44,6 +29,9 @@ namespace EightBit {
|
||||||
[[nodiscard]] virtual register16_t peekWord(register16_t address) = 0;
|
[[nodiscard]] virtual register16_t peekWord(register16_t address) = 0;
|
||||||
virtual void pokeWord(register16_t address, register16_t value) = 0;
|
virtual void pokeWord(register16_t address, register16_t value) = 0;
|
||||||
|
|
||||||
|
DECLARE_PIN_INPUT(RESET)
|
||||||
|
DECLARE_PIN_INPUT(INT)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Processor(Bus& memory);
|
Processor(Bus& memory);
|
||||||
|
|
||||||
|
@ -111,8 +99,5 @@ namespace EightBit {
|
||||||
Bus& m_bus;
|
Bus& m_bus;
|
||||||
uint8_t m_opcode = Mask8;
|
uint8_t m_opcode = Mask8;
|
||||||
register16_t m_pc;
|
register16_t m_pc;
|
||||||
|
|
||||||
PinLevel m_intLine = PinLevel::Low; // In
|
|
||||||
PinLevel m_resetLine = PinLevel::Low; // In
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,4 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "Device.h"
|
#include "Device.h"
|
||||||
|
|
||||||
void EightBit::Device::raisePOWER() {
|
DEFINE_PIN_LEVEL_CHANGERS(POWER, Device);
|
||||||
raise(POWER());
|
|
||||||
RaisedPOWER.fire(EventArgs::empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::Device::lowerPOWER() {
|
|
||||||
lower(POWER());
|
|
||||||
LoweredPOWER.fire(EventArgs::empty());
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,22 +7,14 @@ EightBit::IntelProcessor::IntelProcessor(Bus& bus)
|
||||||
m_decodedOpcodes[i] = i;
|
m_decodedOpcodes[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_PIN_LEVEL_CHANGERS(HALT, IntelProcessor);
|
||||||
|
|
||||||
void EightBit::IntelProcessor::raisePOWER() {
|
void EightBit::IntelProcessor::raisePOWER() {
|
||||||
Processor::raisePOWER();
|
Processor::raisePOWER();
|
||||||
raiseHALT();
|
raiseHALT();
|
||||||
SP() = AF() = BC() = DE() = HL() = Mask16;
|
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() {
|
void EightBit::IntelProcessor::handleRESET() {
|
||||||
Processor::handleRESET();
|
Processor::handleRESET();
|
||||||
PC() = 0;
|
PC() = 0;
|
||||||
|
|
|
@ -5,25 +5,8 @@ EightBit::Processor::Processor(Bus& bus)
|
||||||
: m_bus(bus) {
|
: m_bus(bus) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Processor::lowerRESET() {
|
DEFINE_PIN_LEVEL_CHANGERS(RESET, Processor);
|
||||||
lower(RESET());
|
DEFINE_PIN_LEVEL_CHANGERS(INT, Processor);
|
||||||
LoweredRESET.fire(EventArgs::empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EightBit::Processor::raiseRESET() {
|
|
||||||
raise(RESET());
|
|
||||||
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() {
|
void EightBit::Processor::handleRESET() {
|
||||||
raiseRESET();
|
raiseRESET();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user