Use macros to define our device pins.

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2019-01-14 23:17:54 +00:00
parent 4d08487513
commit f0376fa81e
14 changed files with 92 additions and 287 deletions

View File

@ -32,7 +32,7 @@ void EightBit::Intel8080::handleRESET() {
void EightBit::Intel8080::handleINT() {
IntelProcessor::handleINT();
raise(HALT());
raiseHALT();
if (m_interruptEnable) {
di();
Processor::execute(BUS().DATA());

View File

@ -35,7 +35,7 @@ void EightBit::GameBoy::LR35902::handleRESET() {
void EightBit::GameBoy::LR35902::handleINT() {
IntelProcessor::handleINT();
raise(HALT());
raiseHALT();
di();
restart(BUS().DATA());
tick(4);
@ -312,7 +312,7 @@ int EightBit::GameBoy::LR35902::step() {
if (masked) {
if (IME()) {
m_bus.IO().poke(IoRegisters::IF, 0);
lower(INT());
lowerINT();
const int index = EightBit::findFirstSet(masked);
BUS().DATA() = 0x38 + (index << 3);
} else {

View File

@ -31,31 +31,10 @@ namespace EightBit {
Signal<MOS6502> ExecutingInstruction;
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 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; }
auto& A() { return a; }
@ -64,15 +43,12 @@ namespace EightBit {
auto& P() { return p; }
const auto& P() const { return p; }
auto& NMI() { return m_nmiLine; } // In
auto& SO() { return m_soLine; } // In
auto& SYNC() { return m_syncLine; } // Out
auto& RDY() { return m_rdyLine; } // In
DECLARE_PIN_INPUT(NMI)
DECLARE_PIN_INPUT(SO)
DECLARE_PIN_OUTPUT(SYNC)
DECLARE_PIN_INPUT(RDY)
protected:
virtual void lowerSYNC();
virtual void raiseSYNC();
virtual void handleRESET() final;
virtual void handleINT() final;
@ -211,11 +187,6 @@ namespace EightBit {
uint8_t s = 0; // stack pointer
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;
bool m_handlingRESET = false;

View File

@ -4,6 +4,11 @@
EightBit::MOS6502::MOS6502(Bus& 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() {
LittleEndianProcessor::raisePOWER();
X() = Bit7;
@ -14,46 +19,6 @@ void EightBit::MOS6502::raisePOWER() {
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() {
resetCycles();
ExecutingInstruction.fire(*this);
@ -98,7 +63,7 @@ void EightBit::MOS6502::handleNMI() {
}
void EightBit::MOS6502::handleINT() {
raise(INT());
raiseINT();
m_handlingINT = true;
opcode() = 0x00; // BRK
}

View File

@ -57,35 +57,11 @@ 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 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; }
auto& B() { return D().low; }
@ -99,10 +75,6 @@ namespace EightBit {
auto& CC() { 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 Definition |
@ -114,13 +86,16 @@ namespace EightBit {
// | 1 | 1 | HALT Acknowledge |
// |-------|-------|-----------------------------------|
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(); }
DECLARE_PIN_INPUT(NMI)
DECLARE_PIN_INPUT(FIRQ)
DECLARE_PIN_INPUT(HALT)
DECLARE_PIN_OUTPUT(BA)
DECLARE_PIN_OUTPUT(BS)
protected:
// Default push/pop handlers
@ -132,14 +107,6 @@ namespace EightBit {
virtual void handleRESET() 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
const uint8_t NMIvector = 0xfc; // NMI vector
@ -405,13 +372,6 @@ namespace EightBit {
uint8_t m_dp = 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_prefix11 = false;
};

View File

@ -7,62 +7,18 @@
EightBit::mc6809::mc6809(Bus& 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() {
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() {
resetCycles();
ExecutingInstruction.fire(*this);

View File

@ -52,23 +52,11 @@ 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 raisePOWER() final;
void raiseNMI();
void lowerNMI();
[[nodiscard]] register16_t& AF() final;
[[nodiscard]] register16_t& BC() final;
[[nodiscard]] register16_t& DE() final;
@ -96,14 +84,14 @@ namespace EightBit {
m_accumulatorFlagsSet = !m_accumulatorFlagsSet;
}
DECLARE_PIN_INPUT(NMI)
DECLARE_PIN_OUTPUT(M1)
protected:
void handleRESET() final;
void handleINT() final;
private:
PinLevel m_nmiLine = PinLevel::Low; // In, Active low
PinLevel m_m1Line = PinLevel::Low; // Out, Active low
InputOutput& m_ports;
enum { BC_IDX, DE_IDX, HL_IDX };
@ -132,9 +120,6 @@ namespace EightBit {
int8_t m_displacement = 0;
bool m_displaced = false;
void raiseM1();
void lowerM1();
void handleNMI();
[[nodiscard]] uint16_t displacedAddress() {

View File

@ -8,6 +8,9 @@ EightBit::Z80::Z80(Bus& bus, InputOutput& ports)
m_ports(ports) {
}
DEFINE_PIN_LEVEL_CHANGERS(NMI, Z80);
DEFINE_PIN_LEVEL_CHANGERS(M1, Z80);
EightBit::register16_t& EightBit::Z80::AF() {
return m_accumulatorFlags[m_accumulatorFlagsSet];
}
@ -45,26 +48,6 @@ void EightBit::Z80::raisePOWER() {
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();

View File

@ -3,6 +3,55 @@
#include "EventArgs.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 {
class Device {
public:
@ -17,19 +66,11 @@ namespace EightBit {
virtual ~Device() {};
Signal<EventArgs> RaisedPOWER;
Signal<EventArgs> LoweredPOWER;
[[nodiscard]] bool powered() noexcept { return raised(POWER()); }
[[nodiscard]] auto& POWER() noexcept { return m_powerLine; }
[[nodiscard]] auto powered() noexcept { return raised(POWER()); }
virtual void raisePOWER();
virtual void lowerPOWER();
DECLARE_PIN_INPUT(POWER)
protected:
Device() {};
private:
PinLevel m_powerLine = PinLevel::Low; // In
};
}

View File

@ -34,11 +34,6 @@ 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];
}
@ -65,6 +60,8 @@ namespace EightBit {
void raisePOWER() override;
DECLARE_PIN_INPUT(HALT)
protected:
IntelProcessor(Bus& bus);
@ -176,14 +173,9 @@ namespace EightBit {
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

@ -19,23 +19,8 @@ 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& INT() noexcept { return m_intLine; }
virtual void lowerRESET();
virtual void raiseRESET();
virtual void lowerINT();
virtual void raiseINT();
int run(int limit);
virtual int step() = 0;
virtual int execute() = 0;
@ -44,6 +29,9 @@ namespace EightBit {
[[nodiscard]] virtual register16_t peekWord(register16_t address) = 0;
virtual void pokeWord(register16_t address, register16_t value) = 0;
DECLARE_PIN_INPUT(RESET)
DECLARE_PIN_INPUT(INT)
protected:
Processor(Bus& memory);
@ -111,8 +99,5 @@ namespace EightBit {
Bus& m_bus;
uint8_t m_opcode = Mask8;
register16_t m_pc;
PinLevel m_intLine = PinLevel::Low; // In
PinLevel m_resetLine = PinLevel::Low; // In
};
}

View File

@ -1,12 +1,4 @@
#include "stdafx.h"
#include "Device.h"
void EightBit::Device::raisePOWER() {
raise(POWER());
RaisedPOWER.fire(EventArgs::empty());
}
void EightBit::Device::lowerPOWER() {
lower(POWER());
LoweredPOWER.fire(EventArgs::empty());
}
DEFINE_PIN_LEVEL_CHANGERS(POWER, Device);

View File

@ -7,22 +7,14 @@ EightBit::IntelProcessor::IntelProcessor(Bus& bus)
m_decodedOpcodes[i] = i;
}
DEFINE_PIN_LEVEL_CHANGERS(HALT, IntelProcessor);
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;

View File

@ -5,25 +5,8 @@ EightBit::Processor::Processor(Bus& bus)
: m_bus(bus) {
}
void EightBit::Processor::lowerRESET() {
lower(RESET());
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());
}
DEFINE_PIN_LEVEL_CHANGERS(RESET, Processor);
DEFINE_PIN_LEVEL_CHANGERS(INT, Processor);
void EightBit::Processor::handleRESET() {
raiseRESET();