From 5b009ee67e74f4a9d0e1f1ec98866fedf95f6d15 Mon Sep 17 00:00:00 2001 From: Christopher Mosher Date: Sat, 14 Dec 2013 22:48:06 -0500 Subject: [PATCH] refactor: further split Common and SegmentCache --- Common.cpp | 80 ++++++++++++++++++++++++++++++++++ Common.h | 24 +++++++---- Cpu6502.cpp | 19 ++++----- Cpu6502.h | 10 ++--- Cpu6502Helper.cpp | 18 ++++---- Cpu6502Helper.h | 6 +-- Makefile | 2 +- SegmentCache.cpp | 106 +++++++++------------------------------------- SegmentCache.h | 21 +++------ Trace.cpp | 36 ++++++++-------- Trace.h | 4 +- TransNetwork.cpp | 3 +- v6502.cpp | 9 ++-- 13 files changed, 171 insertions(+), 167 deletions(-) diff --git a/Common.cpp b/Common.cpp index 72831d8..24f29ad 100644 --- a/Common.cpp +++ b/Common.cpp @@ -6,3 +6,83 @@ */ #include "Common.h" +#include "SegmentCache.h" + +Common Common::create(const SegmentCache& segs) { + return Common( + segs.get("-vss"), segs.get("+vcc"), + segs.get("-clk0"), + segs.get("-irq"), segs.get("-res"), segs.get("-nmi"), + segs.get("+rdy"), segs.get("+so"), + segs.get("-db0"), segs.get("-db1"), segs.get("-db2"), segs.get("-db3"), segs.get("-db4"), segs.get("-db5"), segs.get("-db6"), segs.get("-db7"), + segs.get("-ab0"), segs.get("-ab1"), segs.get("-ab2"), segs.get("-ab3"), segs.get("-ab4"), segs.get("-ab5"), segs.get("-ab6"), segs.get("-ab7"), + segs.get("-ab8"), segs.get("-ab9"), segs.get("-ab10"), segs.get("-ab11"), segs.get("-ab12"), segs.get("-ab13"), segs.get("-ab14"), segs.get("-ab15"), + segs.get("-rw"), segs.get("-sync"), + segs.get("-clk1out"), segs.get("-clk2out"), + segs.get("-a0"), segs.get("-a1"), segs.get("-a2"), segs.get("-a3"), segs.get("-a4"), segs.get("-a5"), segs.get("-a6"), segs.get("-a7"), + segs.get("-x0"), segs.get("-x1"), segs.get("-x2"), segs.get("-x3"), segs.get("-x4"), segs.get("-x5"), segs.get("-x6"), segs.get("-x7"), + segs.get("-y0"), segs.get("-y1"), segs.get("-y2"), segs.get("-y3"), segs.get("-y4"), segs.get("-y5"), segs.get("-y6"), segs.get("-y7"), + segs.get("-pcl0"), segs.get("-pcl1"), segs.get("-pcl2"), segs.get("-pcl3"), segs.get("-pcl4"), segs.get("-pcl5"), segs.get("-pcl6"), segs.get("-pcl7"), + segs.get("-pch0"), segs.get("-pch1"), segs.get("-pch2"), segs.get("-pch3"), segs.get("-pch4"), segs.get("-pch5"), segs.get("-pch6"), segs.get("-pch7"), + segs.get("+Pout0"), segs.get("+Pout1"), segs.get("+Pout2"), segs.get("+Pout3"), segs.get("+Pout4"), /*no P5 */segs.get("+Pout6"), segs.get("+Pout7"), + segs.get("-s0"), segs.get("-s1"), segs.get("-s2"), segs.get("-s3"), segs.get("-s4"), segs.get("-s5"), segs.get("-s6"), segs.get("-s7")); +} + +unsigned short Common::rAddr() const { + return Segment::asWord(this->AB15, this->AB14, this->AB13, this->AB12, this->AB11, this->AB10, this->AB9, this->AB8, this->AB7, this->AB6, this->AB5, this->AB4, this->AB3, this->AB2, this->AB1, this->AB0); +} + +unsigned char Common::rData() const { + return Segment::asByte(this->DB7, this->DB6, this->DB5, this->DB4, this->DB3, this->DB2, this->DB1, this->DB0); +} + +unsigned char Common::rA() const { + return Segment::asByte(this->A7, this->A6, this->A5, this->A4, this->A3, this->A2, this->A1, this->A0); +} + +unsigned char Common::rX() const { + return Segment::asByte(this->X7, this->X6, this->X5, this->X4, this->X3, this->X2, this->X1, this->X0); +} + +unsigned char Common::rY() const { + return Segment::asByte(this->Y7, this->Y6, this->Y5, this->Y4, this->Y3, this->Y2, this->Y1, this->Y0); +} + +unsigned char Common::rS() const { + return Segment::asByte(this->S7, this->S6, this->S5, this->S4, this->S3, this->S2, this->S1, this->S0); +} + +unsigned short Common::rPC() const { + return Segment::asWord(this->PCH7, this->PCH6, this->PCH5, this->PCH4, this->PCH3, this->PCH2, this->PCH1, this->PCH0, this->PCL7, this->PCL6, this->PCL5, this->PCL4, this->PCL3, this->PCL2, this->PCL1, this->PCL0); +} + +void Common::setDataSegs(const unsigned char data) { + unsigned char x = data; + + this->DB0->set(x & 1); + x >>= 1; + this->DB1->set(x & 1); + x >>= 1; + this->DB2->set(x & 1); + x >>= 1; + this->DB3->set(x & 1); + x >>= 1; + this->DB4->set(x & 1); + x >>= 1; + this->DB5->set(x & 1); + x >>= 1; + this->DB6->set(x & 1); + x >>= 1; + this->DB7->set(x & 1); +} + +void Common::addDataToRecalc(setpSeg& s) const { + s.insert(this->DB0); + s.insert(this->DB1); + s.insert(this->DB2); + s.insert(this->DB3); + s.insert(this->DB4); + s.insert(this->DB5); + s.insert(this->DB6); + s.insert(this->DB7); +} diff --git a/Common.h b/Common.h index a6bffd3..ba3efb4 100644 --- a/Common.h +++ b/Common.h @@ -8,11 +8,14 @@ #ifndef COMMON_H #define COMMON_H -class Segment; +#include "trans.h" + class SegmentCache; class Common { public: + static Common create(const SegmentCache& segs); + Segment *VSS, *VCC; Segment *CLK0; Segment *IRQ, *RES, *NMI; @@ -31,6 +34,17 @@ public: + unsigned char rA() const; + unsigned char rX() const; + unsigned char rY() const; + unsigned char rS() const; + unsigned short rPC() const; + unsigned short rAddr() const; + unsigned char rData() const; + + void setDataSegs(const unsigned char data); + void addDataToRecalc(setpSeg& s) const; + private: @@ -68,14 +82,6 @@ private: P0(P0), P1(P1), P2(P2), P3(P3), P4(P4), /* no P5 */ P6(P6), P7(P7), S0(S0), S1(S1), S2(S2), S3(S3), S4(S4), S5(S5), S6(S6), S7(S7) { } - - ~Common() { - } - - Common(const Common&) = delete; - Common& operator=(const Common&) = delete; - - friend SegmentCache; }; #endif /* COMMON_H */ diff --git a/Cpu6502.cpp b/Cpu6502.cpp index 2689d95..b8c29d6 100644 --- a/Cpu6502.cpp +++ b/Cpu6502.cpp @@ -22,7 +22,7 @@ -Cpu6502::Cpu6502(TransNetwork& transNetwork, AddressBus& addressBus, Trace& trace) : transNetwork(transNetwork), addressBus(addressBus), trace(trace), segs(transNetwork.segs), n(segs.c) { +Cpu6502::Cpu6502(AddressBus& addressBus, Trace& trace, Common& common) : addressBus(addressBus), trace(trace), common(common) { } void Cpu6502::setPins(const PinSettings& ps) { @@ -35,7 +35,7 @@ void Cpu6502::setPins(const PinSettings& ps) { } void Cpu6502::clock(bool phase) { - setPins(PinSettings{std::make_pair(n->CLK0,phase)}); + setPins(PinSettings{std::make_pair(common.CLK0,phase)}); rw(); #ifdef TRACEREG @@ -48,26 +48,25 @@ void Cpu6502::clock(bool phase) { } void Cpu6502::rw() { - // database read/write happens during Clock Phase 2 (only) - if (n->CLK2OUT->on) { + /* database read/write happens (only) during Clock Phase 2 */ + if (common.CLK2OUT->on) { readData(); writeData(); } } void Cpu6502::readData() { - if (this->transNetwork.segs.c->RW->on) { - this->transNetwork.segs.setDataSegs(this->addressBus.read(this->transNetwork.segs.rAddr())); + if (this->common.RW->on) { + this->common.setDataSegs(this->addressBus.read(this->common.rAddr())); - //???? TODO ???? can this be inside the if block ???? setpSeg s; - segs.addDataToRecalc(s); + this->common.addDataToRecalc(s); StateCalculator::recalc(s); } } void Cpu6502::writeData() { - if (!this->transNetwork.segs.c->RW->on) { - this->addressBus.write(this->transNetwork.segs.rAddr(), this->transNetwork.segs.rData()); + if (!this->common.RW->on) { + this->addressBus.write(this->common.rAddr(), this->common.rData()); } } diff --git a/Cpu6502.h b/Cpu6502.h index 685a6b5..4533040 100644 --- a/Cpu6502.h +++ b/Cpu6502.h @@ -17,11 +17,12 @@ class Common; class TransNetwork; class AddressBus; class Trace; +class Common; class Cpu6502 { public: - Cpu6502(TransNetwork& transNetwork, AddressBus& addressBus, Trace& trace); + Cpu6502(AddressBus& addressBus, Trace& trace, Common& common); virtual ~Cpu6502() { } @@ -31,6 +32,7 @@ public: void clock(bool phase); + private: Cpu6502(const Cpu6502&) = delete; @@ -40,13 +42,9 @@ private: void readData(); void writeData(); - TransNetwork& transNetwork; AddressBus& addressBus; - Trace& trace; -public: - SegmentCache& segs; - Common* n; + Common& common; }; #endif /* CPU6502_H */ diff --git a/Cpu6502Helper.cpp b/Cpu6502Helper.cpp index d8fded6..9effb4a 100644 --- a/Cpu6502Helper.cpp +++ b/Cpu6502Helper.cpp @@ -18,7 +18,7 @@ #include #include "Common.h" -Cpu6502Helper::Cpu6502Helper(Cpu6502& cpu) : cpu(cpu), nextPhase(true), n(cpu.segs.c) { +Cpu6502Helper::Cpu6502Helper(Cpu6502& cpu, Common& common) : cpu(cpu), common(common), nextPhase(true) { } Cpu6502Helper::~Cpu6502Helper() { @@ -28,18 +28,18 @@ void Cpu6502Helper::powerOn() { Cpu6502::PinSettings ps; // set voltage supply and ground. - ps.insert(std::make_pair(n->VCC, true)); - ps.insert(std::make_pair(n->VSS, false)); + ps.insert(std::make_pair(common.VCC, true)); + ps.insert(std::make_pair(common.VSS, false)); // don't do the set-overflow overriding functionality - ps.insert(std::make_pair(n->SO, false)); + ps.insert(std::make_pair(common.SO, false)); // ready to run (i.e., do not do single-stepping of instructions) - ps.insert(std::make_pair(n->RDY, true)); + ps.insert(std::make_pair(common.RDY, true)); // pull up to indicate that we are not interrupting now - ps.insert(std::make_pair(n->IRQ, true)); - ps.insert(std::make_pair(n->NMI, true)); + ps.insert(std::make_pair(common.IRQ, true)); + ps.insert(std::make_pair(common.NMI, true)); /* @@ -53,7 +53,7 @@ void Cpu6502Helper::powerOn() { * CPU does not start up normal operations yet. The caller can set RES_BAR high (by calling * reset) whenever he is ready to start the CPU running. */ - ps.insert(std::make_pair(n->RES, false)); + ps.insert(std::make_pair(common.RES, false)); cpu.setPins(ps); @@ -82,5 +82,5 @@ void Cpu6502Helper::step() { } void Cpu6502Helper::reset() { - cpu.setPins(Cpu6502::PinSettings{std::make_pair(n->RES, true)}); + cpu.setPins(Cpu6502::PinSettings{std::make_pair(common.RES, true)}); } diff --git a/Cpu6502Helper.h b/Cpu6502Helper.h index aef5bc0..ecaa41b 100644 --- a/Cpu6502Helper.h +++ b/Cpu6502Helper.h @@ -9,13 +9,12 @@ #define CPU6502HELPER_H class Cpu6502; - class Common; class Cpu6502Helper { public: - explicit Cpu6502Helper(Cpu6502& cpu); + explicit Cpu6502Helper(Cpu6502& cpu, Common& common); virtual ~Cpu6502Helper(); void powerOn(); @@ -30,9 +29,8 @@ private: void step(); Cpu6502& cpu; + Common& common; bool nextPhase; - - Common* n; }; #endif /* CPU6502HELPER_H */ diff --git a/Makefile b/Makefile index 1ab2384..7920f0a 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CXXFLAGS=-g -std=c++11 -Wall -O0 +CXXFLAGS=-g -std=c++11 -Wall -O3 SRCS = v6502.cpp SegmentCache.cpp Common.cpp TransNetwork.cpp Trace.cpp Circuit.cpp StateCalculator.cpp Cpu6502.cpp Cpu6502Helper.cpp OBJS = $(SRCS:.cpp=.o) diff --git a/SegmentCache.cpp b/SegmentCache.cpp index d38cef6..10d9439 100644 --- a/SegmentCache.cpp +++ b/SegmentCache.cpp @@ -6,107 +6,39 @@ */ #include "SegmentCache.h" -#include "Common.h" #include #include #include -SegmentCache::~SegmentCache() { - delete this->c; +bool SegmentCache::cached(const std::string& id) const { + return this->cache.find(id) != this->cache.end(); } Segment* SegmentCache::getOrAdd(const std::string& id) { - if (this->cache.find(id) == this->cache.end()) { + if (!cached(id)) { this->cache[id] = std::make_shared(id); + + /* + * We want to optimize VSS and VCC checking in + * the rest of the program, so we check here + * for those two special cases, and flag them. + * So, for example, checking (s->vss) is equivalent + * to checking (s==VCC). + */ + if (id == "-vss") { + this->cache[id]->vss = true; + } else if (id == "+vcc") { + this->cache[id]->vcc = true; + } } + return get(id); } Segment* SegmentCache::get(const std::string& id) const { - if (this->cache.find(id) == this->cache.end()) { + if (!cached(id)) { throw "Cannot find segment: " + id; } + return this->cache.at(id).get(); } - -void SegmentCache::initCommon() { - this->c = new Common( - get("-vss"), get("+vcc"), - get("-clk0"), - get("-irq"), get("-res"), get("-nmi"), - get("+rdy"), get("+so"), - get("-db0"), get("-db1"), get("-db2"), get("-db3"), get("-db4"), get("-db5"), get("-db6"), get("-db7"), - get("-ab0"), get("-ab1"), get("-ab2"), get("-ab3"), get("-ab4"), get("-ab5"), get("-ab6"), get("-ab7"), - get("-ab8"), get("-ab9"), get("-ab10"), get("-ab11"), get("-ab12"), get("-ab13"), get("-ab14"), get("-ab15"), - get("-rw"), get("-sync"), - get("-clk1out"), get("-clk2out"), - get("-a0"), get("-a1"), get("-a2"), get("-a3"), get("-a4"), get("-a5"), get("-a6"), get("-a7"), - get("-x0"), get("-x1"), get("-x2"), get("-x3"), get("-x4"), get("-x5"), get("-x6"), get("-x7"), - get("-y0"), get("-y1"), get("-y2"), get("-y3"), get("-y4"), get("-y5"), get("-y6"), get("-y7"), - get("-pcl0"), get("-pcl1"), get("-pcl2"), get("-pcl3"), get("-pcl4"), get("-pcl5"), get("-pcl6"), get("-pcl7"), - get("-pch0"), get("-pch1"), get("-pch2"), get("-pch3"), get("-pch4"), get("-pch5"), get("-pch6"), get("-pch7"), - get("+Pout0"), get("+Pout1"), get("+Pout2"), get("+Pout3"), get("+Pout4"), /*no P5 */get("+Pout6"), get("+Pout7"), - get("-s0"), get("-s1"), get("-s2"), get("-s3"), get("-s4"), get("-s5"), get("-s6"), get("-s7")); - - this->c->VSS->vss = true; - this->c->VCC->vcc = true; -} - -unsigned char SegmentCache::rData() const { - return Segment::asByte(this->c->DB7, this->c->DB6, this->c->DB5, this->c->DB4, this->c->DB3, this->c->DB2, this->c->DB1, this->c->DB0); -} - -unsigned short SegmentCache::rAddr() const { - return Segment::asWord(this->c->AB15, this->c->AB14, this->c->AB13, this->c->AB12, this->c->AB11, this->c->AB10, this->c->AB9, this->c->AB8, this->c->AB7, this->c->AB6, this->c->AB5, this->c->AB4, this->c->AB3, this->c->AB2, this->c->AB1, this->c->AB0); -} - -unsigned char SegmentCache::rA() const { - return Segment::asByte(this->c->A7, this->c->A6, this->c->A5, this->c->A4, this->c->A3, this->c->A2, this->c->A1, this->c->A0); -} - -unsigned char SegmentCache::rX() const { - return Segment::asByte(this->c->X7, this->c->X6, this->c->X5, this->c->X4, this->c->X3, this->c->X2, this->c->X1, this->c->X0); -} - -unsigned char SegmentCache::rY() const { - return Segment::asByte(this->c->Y7, this->c->Y6, this->c->Y5, this->c->Y4, this->c->Y3, this->c->Y2, this->c->Y1, this->c->Y0); -} - -unsigned char SegmentCache::rS() const { - return Segment::asByte(this->c->S7, this->c->S6, this->c->S5, this->c->S4, this->c->S3, this->c->S2, this->c->S1, this->c->S0); -} - -unsigned short SegmentCache::rPC() const { - return Segment::asWord(this->c->PCH7, this->c->PCH6, this->c->PCH5, this->c->PCH4, this->c->PCH3, this->c->PCH2, this->c->PCH1, this->c->PCH0, this->c->PCL7, this->c->PCL6, this->c->PCL5, this->c->PCL4, this->c->PCL3, this->c->PCL2, this->c->PCL1, this->c->PCL0); -} - -void SegmentCache::setDataSegs(const unsigned char data) { - unsigned char x = data; - - this->c->DB0->set(x & 1); - x >>= 1; - this->c->DB1->set(x & 1); - x >>= 1; - this->c->DB2->set(x & 1); - x >>= 1; - this->c->DB3->set(x & 1); - x >>= 1; - this->c->DB4->set(x & 1); - x >>= 1; - this->c->DB5->set(x & 1); - x >>= 1; - this->c->DB6->set(x & 1); - x >>= 1; - this->c->DB7->set(x & 1); -} - -void SegmentCache::addDataToRecalc(setpSeg& s) const { - s.insert(this->c->DB0); - s.insert(this->c->DB1); - s.insert(this->c->DB2); - s.insert(this->c->DB3); - s.insert(this->c->DB4); - s.insert(this->c->DB5); - s.insert(this->c->DB6); - s.insert(this->c->DB7); -} diff --git a/SegmentCache.h b/SegmentCache.h index a74ad90..a704e22 100644 --- a/SegmentCache.h +++ b/SegmentCache.h @@ -19,10 +19,11 @@ class Common; class SegmentCache { public: - SegmentCache() : c(nullptr) { + SegmentCache() { } - virtual ~SegmentCache(); + virtual ~SegmentCache() { + } Segment* getOrAdd(const std::string& id); @@ -35,17 +36,6 @@ public: } - unsigned char rData() const; - unsigned short rAddr() const; - unsigned char rA() const; - unsigned char rX() const; - unsigned char rY() const; - unsigned char rS() const; - unsigned short rPC() const; - - void setDataSegs(const unsigned char data); - void addDataToRecalc(setpSeg& s) const; - std::map >::const_iterator begin() const { return this->cache.begin(); } @@ -61,10 +51,9 @@ private: SegmentCache& operator=(const SegmentCache&) = delete; Segment* get(const std::string& id) const; + bool cached(const std::string& id) const; -public: - void initCommon(); - Common* c; + friend Common; }; #endif /* SEGMENTCACHE_H */ diff --git a/Trace.cpp b/Trace.cpp index b813245..d78d58a 100644 --- a/Trace.cpp +++ b/Trace.cpp @@ -41,41 +41,41 @@ void Trace::dumpSegments() const { void Trace::dumpRegisters() const { std::cout << "A"; - pHexb(s.rA()); + pHexb(common.rA()); std::cout << " X"; - pHexb(s.rX()); + pHexb(common.rX()); std::cout << " Y"; - pHexb(s.rY()); + pHexb(common.rY()); std::cout << " "; - std::cout << (s.c->P7->on ? "N" : "n"); - std::cout << (s.c->P6->on ? "V" : "v"); + std::cout << (this->common.P7->on ? "N" : "n"); + std::cout << (this->common.P6->on ? "V" : "v"); std::cout << "."; - std::cout << (s.c->P4->on ? "B" : "b"); - std::cout << (s.c->P3->on ? "D" : "d"); - std::cout << (s.c->P2->on ? "I" : "i"); - std::cout << (s.c->P1->on ? "Z" : "z"); - std::cout << (s.c->P0->on ? "C" : "c"); + std::cout << (this->common.P4->on ? "B" : "b"); + std::cout << (this->common.P3->on ? "D" : "d"); + std::cout << (this->common.P2->on ? "I" : "i"); + std::cout << (this->common.P1->on ? "Z" : "z"); + std::cout << (this->common.P0->on ? "C" : "c"); std::cout << " S"; - pHexb(s.rS()); + pHexb(common.rS()); std::cout << " PC"; - pHexw(s.rPC()); - if (s.c->CLK1OUT->on) { + pHexw(common.rPC()); + if (this->common.CLK1OUT->on) { std::cout << " PH1 "; } - if (s.c->CLK2OUT->on) { + if (this->common.CLK2OUT->on) { std::cout << " PH2"; - if (s.c->RW->on) { + if (this->common.RW->on) { std::cout << " R"; } else { std::cout << " W"; } } - if (!(s.c->CLK1OUT->on || s.c->CLK2OUT->on)) { + if (!(this->common.CLK1OUT->on || this->common.CLK2OUT->on)) { std::cout << " PH- "; } std::cout << " DB"; - pHexb(s.rData()); + pHexb(common.rData()); std::cout << " AB"; - pHexw(s.rAddr()); + pHexw(common.rAddr()); std::cout << std::endl; } diff --git a/Trace.h b/Trace.h index f6e21cb..60033a8 100644 --- a/Trace.h +++ b/Trace.h @@ -9,10 +9,11 @@ #define TRACE_H class SegmentCache; +class Common; class Trace { public: - Trace(const SegmentCache& s) : s(s) {} + Trace(const SegmentCache& s, const Common& common) : s(s), common(common) {} virtual ~Trace() {} void dumpSegments() const; @@ -23,6 +24,7 @@ private: Trace& operator=(const Trace&) = delete; const SegmentCache& s; + const Common& common; }; #endif /* TRACE_H */ diff --git a/TransNetwork.cpp b/TransNetwork.cpp index d75ae3c..f0eb75b 100644 --- a/TransNetwork.cpp +++ b/TransNetwork.cpp @@ -12,6 +12,7 @@ #include #include #include "StateCalculator.h" +#include "Common.h" TransNetwork::TransNetwork(std::istream& in) { std::string c1, gate, c2; @@ -21,8 +22,6 @@ TransNetwork::TransNetwork(std::istream& in) { in >> c1 >> gate >> c2; } - this->segs.initCommon(); - StateCalculator::recalc(this->segs.all()); } diff --git a/v6502.cpp b/v6502.cpp index ba0b083..dbd76c7 100644 --- a/v6502.cpp +++ b/v6502.cpp @@ -3,12 +3,12 @@ #include "Cpu6502Helper.h" #include "TransNetwork.h" #include "Trace.h" +#include "Common.h" #include #include #include #include - int main(int argc, char *argv[]) { AddressBus mem; @@ -35,9 +35,10 @@ int main(int argc, char *argv[]) { exit(EXIT_FAILURE); } TransNetwork tn(if_trans); - Trace trace(tn.segs); - Cpu6502 cpu(tn, mem, trace); - Cpu6502Helper cpuhelper(cpu); + Common c = Common::create(tn.segs); + Trace trace(tn.segs, c); + Cpu6502 cpu(mem, trace, c); + Cpu6502Helper cpuhelper(cpu, c);