refactoring: add final class, remove redundant code, etc.

This commit is contained in:
Christopher Mosher 2013-12-15 12:49:18 -05:00
parent 55df84b305
commit 90145f3d37
19 changed files with 158 additions and 215 deletions

View File

@ -56,23 +56,23 @@ bool Circuit::getValue() {
return false;
}
}
/* otherwise, if group contains voltage supply, it's ON. */
/*
* otherwise, if any segment in the group is not floating,
* return that segment as the value, otherwise if any floating
* segment is ON, then return ON as the value.
*/
for (auto s : this->segs) {
if (s->vcc) {
return true;
}
}
/* otherwise, this test: */
for (auto s : this->segs) {
if (s->pull == Pull::UP) {
return true;
}
if (s->pull == Pull::DOWN) {
return false;
}
if (s->on) {
if (s->pull != Pull::FLOAT) {
return (s->pull == Pull::UP);
} else if (s->on) {
return true;
}
}
/*
* otherwise, if we get here, it means that all segments in the
* group are floating and OFF, so return OFF as the value.
*/
return false;
}

View File

@ -8,35 +8,31 @@
#ifndef CIRCUIT_H
#define CIRCUIT_H
#include "SegmentTypes.h"
#include <set>
#include "setpSeg.h"
class Segment;
/*
* Builds a circuit, given one segment in that circuit.
* Extends the given segment by traversing the ON
* transistors it is connected to, recursively, until
* hitting ground and voltage supply. Provides iterators
* for retrieving all the circuit's segments.
* for retrieving all the circuit's segments, and a method
* to get the ON value of the circuit.
*/
class Circuit {
class Circuit final {
public:
Circuit(Segment* extendFrom) {
extend(extendFrom);
}
virtual ~Circuit() {
}
bool getValue();
setpSeg::iterator begin() {
SegmentSet::iterator begin() {
return this->segs.begin();
}
setpSeg::iterator end() {
SegmentSet::iterator end() {
return this->segs.end();
}
@ -47,7 +43,7 @@ private:
void extend(Segment* extendFrom);
setpSeg segs;
SegmentSet segs;
};
#endif /* CIRCUIT_H */

View File

@ -58,33 +58,26 @@ 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) {
PinSettings Common::getDataPinSettings(const unsigned char data) const {
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);
}
PinSettings ps;
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);
ps.insert(std::make_pair(this->DB0,x & 1));
x >>= 1;
ps.insert(std::make_pair(this->DB1,x & 1));
x >>= 1;
ps.insert(std::make_pair(this->DB2,x & 1));
x >>= 1;
ps.insert(std::make_pair(this->DB3,x & 1));
x >>= 1;
ps.insert(std::make_pair(this->DB4,x & 1));
x >>= 1;
ps.insert(std::make_pair(this->DB5,x & 1));
x >>= 1;
ps.insert(std::make_pair(this->DB6,x & 1));
x >>= 1;
ps.insert(std::make_pair(this->DB7,x & 1));
return ps;
}

View File

@ -8,31 +8,33 @@
#ifndef COMMON_H
#define COMMON_H
#include "setpSeg.h"
#include "SegmentTypes.h"
class TransNetwork;
class Segment;
class Common {
class Common final {
public:
Segment *VSS, *VCC;
Segment *CLK0;
Segment *IRQ, *RES, *NMI;
Segment *RDY, *SO;
Segment *DB0, *DB1, *DB2, *DB3, *DB4, *DB5, *DB6, *DB7;
Segment *AB0, *AB1, *AB2, *AB3, *AB4, *AB5, *AB6, *AB7, *AB8, *AB9, *AB10, *AB11, *AB12, *AB13, *AB14, *AB15;
Segment *RW, *SYNC;
Segment *CLK1OUT, *CLK2OUT;
Segment *A0, *A1, *A2, *A3, *A4, *A5, *A6, *A7;
Segment *X0, *X1, *X2, *X3, *X4, *X5, *X6, *X7;
Segment *Y0, *Y1, *Y2, *Y3, *Y4, *Y5, *Y6, *Y7;
Segment *PCL0, *PCL1, *PCL2, *PCL3, *PCL4, *PCL5, *PCL6, *PCL7;
Segment *PCH0, *PCH1, *PCH2, *PCH3, *PCH4, *PCH5, *PCH6, *PCH7;
Segment *P0, *P1, *P2, *P3, *P4, /* no P5 */ *P6, *P7;
Segment *S0, *S1, *S2, *S3, *S4, *S5, *S6, *S7;
Segment * const VSS, * const VCC;
Segment * const CLK0;
Segment * const IRQ, * const RES, * const NMI;
Segment * const RDY, * const SO;
Segment * const DB0, * const DB1, * const DB2, * const DB3, * const DB4, * const DB5, * const DB6, * const DB7;
Segment * const AB0, * const AB1, * const AB2, * const AB3, * const AB4, * const AB5, * const AB6, * const AB7, * const AB8, * const AB9, * const AB10, * const AB11, * const AB12, * const AB13, * const AB14, * const AB15;
Segment * const RW, * const SYNC;
Segment * const CLK1OUT, * const CLK2OUT;
Segment * const A0, * const A1, * const A2, * const A3, * const A4, * const A5, * const A6, * const A7;
Segment * const X0, * const X1, * const X2, * const X3, * const X4, * const X5, * const X6, * const X7;
Segment * const Y0, * const Y1, * const Y2, * const Y3, * const Y4, * const Y5, * const Y6, * const Y7;
Segment * const PCL0, * const PCL1, * const PCL2, * const PCL3, * const PCL4, * const PCL5, * const PCL6, * const PCL7;
Segment * const PCH0, * const PCH1, * const PCH2, * const PCH3, * const PCH4, * const PCH5, * const PCH6, * const PCH7;
Segment * const P0, * const P1, * const P2, * const P3, * const P4, /* no P5 */ * const P6, * const P7;
Segment * const S0, * const S1, * const S2, * const S3, * const S4, * const S5, * const S6, * const S7;
Common(const TransNetwork& segs);
unsigned char rA() const;
unsigned char rX() const;
unsigned char rY() const;
@ -41,13 +43,12 @@ public:
unsigned short rAddr() const;
unsigned char rData() const;
void setDataSegs(const unsigned char data);
void addDataToRecalc(setpSeg& s) const;
PinSettings getDataPinSettings(const unsigned char data) const;
Common(const TransNetwork& segs);
private:
Common(
Segment* VSS, Segment* VCC,
Segment* CLK0,

View File

@ -6,14 +6,11 @@
*/
#include "Cpu6502.h"
#include "TransNetwork.h"
#include "trans.h"
#include "addressbus.h"
#include "Trace.h"
#include <iostream>
#include <utility>
#include "StateCalculator.h"
#include "Trace.h"
#include "Common.h"
#include "trans.h"
@ -22,11 +19,9 @@
Cpu6502::Cpu6502(AddressBus& addressBus, Trace& trace, Common& common) : addressBus(addressBus), trace(trace), common(common) {
}
void Cpu6502::setPins(const PinSettings& ps) {
setpSeg rec;
SegmentSet rec;
for (auto p : ps) {
p.first->set(p.second);
rec.insert(p.first);
@ -57,11 +52,7 @@ void Cpu6502::rw() {
void Cpu6502::readData() {
if (this->common.RW->on) {
this->common.setDataSegs(this->addressBus.read(this->common.rAddr()));
setpSeg s;
this->common.addDataToRecalc(s);
StateCalculator::recalc(s);
setPins(this->common.getDataPinSettings(this->addressBus.read(this->common.rAddr())));
}
}

View File

@ -8,28 +8,19 @@
#ifndef CPU6502_H
#define CPU6502_H
#include <set>
#include <utility>
#include "SegmentTypes.h"
class Segment;
class SegmentCache;
class Common;
class TransNetwork;
class AddressBus;
class Trace;
class Common;
class Cpu6502 {
class Cpu6502 final {
public:
Cpu6502(AddressBus& addressBus, Trace& trace, Common& common);
virtual ~Cpu6502() {
Cpu6502(AddressBus& addressBus, Trace& trace, Common& common) : addressBus(addressBus), trace(trace), common(common) {
}
typedef std::set<std::pair<Segment*, bool >> PinSettings;
void setPins(const PinSettings& ps);
void clock(bool phase);

View File

@ -7,39 +7,25 @@
#include "Cpu6502Helper.h"
#include "Cpu6502.h"
#include "SegmentCache.h"
#include "TransNetwork.h"
#include "trans.h"
#include "addressbus.h"
#include "Trace.h"
#include <iostream>
#include "StateCalculator.h"
#include <utility>
#include <set>
#include "Common.h"
Cpu6502Helper::Cpu6502Helper(Cpu6502& cpu, Common& common) : cpu(cpu), common(common), nextPhase(true) {
}
Cpu6502Helper::~Cpu6502Helper() {
}
#include "SegmentTypes.h"
void Cpu6502Helper::powerOn() {
Cpu6502::PinSettings ps;
PinSettings ps;
// set voltage supply and ground.
ps.insert(std::make_pair(common.VCC, true));
ps.insert(std::make_pair(common.VSS, false));
ps.insert(std::make_pair(this->common.VCC, true));
ps.insert(std::make_pair(this->common.VSS, false));
// don't do the set-overflow overriding functionality
ps.insert(std::make_pair(common.SO, false));
ps.insert(std::make_pair(this->common.SO, false));
// ready to run (i.e., do not do single-stepping of instructions)
ps.insert(std::make_pair(common.RDY, true));
ps.insert(std::make_pair(this->common.RDY, true));
// pull up to indicate that we are not interrupting now
ps.insert(std::make_pair(common.IRQ, true));
ps.insert(std::make_pair(common.NMI, true));
ps.insert(std::make_pair(this->common.IRQ, true));
ps.insert(std::make_pair(this->common.NMI, true));
/*
@ -53,11 +39,11 @@ 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(common.RES, false));
ps.insert(std::make_pair(this->common.RES, false));
cpu.setPins(ps);
this->cpu.setPins(ps);
nextPhase = true;
this->nextPhase = true;
}
void Cpu6502Helper::tick() {
@ -76,11 +62,11 @@ void Cpu6502Helper::step() {
*
* The real 6502, of course, does not do this.
*/
nextPhase = !nextPhase;
this->nextPhase = !this->nextPhase;
cpu.clock(nextPhase);
this->cpu.clock(this->nextPhase);
}
void Cpu6502Helper::reset() {
cpu.setPins(Cpu6502::PinSettings{std::make_pair(common.RES, true)});
this->cpu.setPins(PinSettings{std::make_pair(this->common.RES, true)});
}

View File

@ -11,11 +11,11 @@
class Cpu6502;
class Common;
class Cpu6502Helper {
class Cpu6502Helper final {
public:
Cpu6502Helper(Cpu6502& cpu, Common& common);
virtual ~Cpu6502Helper();
Cpu6502Helper(Cpu6502& cpu, Common& common) : cpu(cpu), common(common), nextPhase(true) {
}
void powerOn();
void tick();
@ -30,6 +30,7 @@ private:
Cpu6502& cpu;
Common& common;
bool nextPhase;
};

View File

@ -44,8 +44,8 @@ Segment* SegmentCache::get(const std::string& id) const {
return this->cache.at(id).get();
}
setpSeg SegmentCache::all() const {
setpSeg s;
SegmentSet SegmentCache::all() const {
SegmentSet s;
for (auto i : this->cache) {
s.insert(i.second.get());
}

View File

@ -8,39 +8,39 @@
#ifndef SEGMENTCACHE_H
#define SEGMENTCACHE_H
#include "setpSeg.h"
#include <memory>
#include <string>
#include "SegmentTypes.h"
#include <map>
#include <set>
#include <string>
#include <memory>
class Segment;
class Common;
class SegmentCache {
class SegmentCache final {
public:
SegmentCache() {
}
virtual ~SegmentCache() {
}
Segment* getOrAdd(const std::string& id);
setpSeg all() const;
SegmentSet all() const;
std::map<const std::string, std::shared_ptr<Segment > >::const_iterator begin() const {
typedef std::map<const std::string, std::shared_ptr<Segment>> Map;
Map::const_iterator begin() const {
return this->cache.begin();
}
std::map<const std::string, std::shared_ptr<Segment > >::const_iterator end() const {
Map::const_iterator end() const {
return this->cache.end();
}
private:
std::map<const std::string, std::shared_ptr<Segment > > cache;
Map cache;
SegmentCache(const SegmentCache&) = delete;
SegmentCache& operator=(const SegmentCache&) = delete;

View File

@ -10,9 +10,12 @@
#include "ptr_less.h"
#include <set>
#include <utility>
class Segment;
typedef std::set<Segment*,ptr_less<Segment>> setpSeg;
typedef std::set<Segment*,ptr_less<Segment>> SegmentSet;
typedef std::set<std::pair<Segment*, bool>> PinSettings;
#endif /* SETPSEG_H */

View File

@ -8,26 +8,19 @@
#include "StateCalculator.h"
#include "Circuit.h"
#include "trans.h"
#include <set>
void StateCalculator::recalc(Segment* seg) {
setpSeg rSeg;
rSeg.insert(seg);
recalc(rSeg);
}
/*
* Recalculate segment states (on/off), based on the fact that the segments
* in riSeg have just changed state. Keep track of which other segments are
* in segs have just changed state. Keep track of which other segments are
* affected, and repeat the process on those segments. Repeat until no more
* segments change state.
*/
#define SANE (100)
void StateCalculator::recalc(const setpSeg& segs) {
void StateCalculator::recalc(const SegmentSet& segs) {
int sanity(0);
setpSeg changed(segs);
SegmentSet changed(segs);
while (!changed.empty()) {
if (++sanity >= SANE) {
throw "ERROR: reached maximum iteration limit while recalculating CPU state";
@ -42,12 +35,12 @@ void StateCalculator::recalc(const setpSeg& segs) {
}
/*
* Gets group of segments currently electrically connected to iSeg,
* Gets group of segments currently electrically connected to seg,
* gets what their group value is (or should be), goes through all
* those segments and sets their "on" value. For all connected gates,
* turn on/off, and indicate that the segments connected to those
* transistors' source and drain legs have changed, by adding them
* to riSegChanged.
* to this->segs.
*/
void StateCalculator::recalcNode(Segment* seg) {
if (!(seg->vss || seg->vcc)) {
@ -70,13 +63,7 @@ void StateCalculator::setSeg(Segment* s, const bool on) {
void StateCalculator::setTrans(Trans* t, const bool on) {
if (t->on != on) {
t->on = on;
addRecalc(t->c1);
addRecalc(t->c2);
}
}
void StateCalculator::addRecalc(Segment* seg) {
if (!(seg->vss || seg->vcc)) {
this->segs.insert(seg);
this->segs.insert(t->c1);
this->segs.insert(t->c2);
}
}

View File

@ -9,34 +9,28 @@
#define STATECALCULATOR_H
#include <set>
#include "setpSeg.h"
#include "SegmentTypes.h"
class Segment;
class Trans;
class StateCalculator {
class StateCalculator final {
public:
static void recalc(const setpSeg& rSeg);
static void recalc(Segment* seg); // convenience method
static void recalc(const SegmentSet& rSeg);
private:
StateCalculator() {
}
virtual ~StateCalculator() {
}
StateCalculator(const StateCalculator&) = delete;
StateCalculator& operator=(const StateCalculator&) = delete;
void recalcNode(Segment* seg);
void setSeg(Segment* s, const bool on);
void setTrans(Trans* t, const bool on);
void addRecalc(Segment* seg);
setpSeg segs;
SegmentSet segs;
};
#endif /* STATECALCULATOR_H */

View File

@ -7,26 +7,25 @@
#include "Trace.h"
#include "SegmentCache.h"
#include "trans.h"
#include "Common.h"
#include "trans.h"
#include <iostream>
#include <iomanip>
#include <cassert>
static void pHex(const unsigned long x, const int width) {
std::cout << std::setw(width) << std::setfill('0') << std::hex << x << std::dec;
}
static void pHexb(const unsigned char x) {
pHex(x,2);
pHex(x, 2);
}
static void pHexw(const unsigned short x) {
pHex(x,4);
pHex(x, 4);
}
void Trace::dumpSegments() const {
for (auto sp : this->s) {
for (auto sp : this->segs) {
Segment* seg = sp.second.get();
if (seg->pull == Pull::UP) {
std::cout << (seg->on ? "U" : "u");
@ -41,11 +40,14 @@ void Trace::dumpSegments() const {
void Trace::dumpRegisters() const {
std::cout << "A";
pHexb(common.rA());
pHexb(this->common.rA());
std::cout << " X";
pHexb(common.rX());
pHexb(this->common.rX());
std::cout << " Y";
pHexb(common.rY());
pHexb(this->common.rY());
std::cout << " ";
std::cout << (this->common.P7->on ? "N" : "n");
std::cout << (this->common.P6->on ? "V" : "v");
@ -55,10 +57,13 @@ void Trace::dumpRegisters() const {
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(common.rS());
pHexb(this->common.rS());
std::cout << " PC";
pHexw(common.rPC());
pHexw(this->common.rPC());
if (this->common.CLK1OUT->on) {
std::cout << " PH1 ";
}
@ -73,9 +78,12 @@ void Trace::dumpRegisters() const {
if (!(this->common.CLK1OUT->on || this->common.CLK2OUT->on)) {
std::cout << " PH- ";
}
std::cout << " DB";
pHexb(common.rData());
pHexb(this->common.rData());
std::cout << " AB";
pHexw(common.rAddr());
pHexw(this->common.rAddr());
std::cout << std::endl;
}

10
Trace.h
View File

@ -11,19 +11,21 @@
class SegmentCache;
class Common;
class Trace {
class Trace final {
public:
Trace(const SegmentCache& s, const Common& common) : s(s), common(common) {}
virtual ~Trace() {}
Trace(const SegmentCache& segs, const Common& common) : segs(segs), common(common) {
}
void dumpSegments() const;
void dumpRegisters() const;
private:
Trace(const Trace&) = delete;
Trace& operator=(const Trace&) = delete;
const SegmentCache& s;
const SegmentCache& segs;
const Common& common;
};

View File

@ -6,14 +6,13 @@
*/
#include "TransNetwork.h"
#include "SegmentCache.h"
#include "StateCalculator.h"
#include "trans.h"
#include <iostream>
#include <set>
#include <string>
#include <memory>
#include <iostream>
#include "StateCalculator.h"
#include "Common.h"
#include "SegmentCache.h"
TransNetwork::TransNetwork(std::istream& in, SegmentCache& segs) : segs(segs) {
std::string c1, gate, c2;
@ -25,6 +24,3 @@ TransNetwork::TransNetwork(std::istream& in, SegmentCache& segs) : segs(segs) {
StateCalculator::recalc(this->segs.all());
}
TransNetwork::~TransNetwork() {
}

View File

@ -8,19 +8,18 @@
#ifndef TRANSNETWORK_H
#define TRANSNETWORK_H
class Trans;
#include <istream>
#include <set>
#include <memory>
#include <istream>
class SegmentCache;
class Common;
class Trans;
class TransNetwork {
class TransNetwork final {
public:
TransNetwork(std::istream& readFromHere, SegmentCache& segs);
virtual ~TransNetwork();
private:
@ -28,7 +27,7 @@ private:
TransNetwork& operator=(const TransNetwork&) = delete;
SegmentCache& segs;
std::set<std::shared_ptr<Trans >> transes;
std::set<std::shared_ptr<Trans>> transes;
friend Common;
};

19
trans.h
View File

@ -8,7 +8,7 @@
#ifndef TRANS_H
#define TRANS_H
#include "setpSeg.h"
#include "SegmentTypes.h"
#include <set>
#include <string>
@ -18,10 +18,11 @@ class Trans;
enum class Pull { UP, DOWN, FLOAT };
class Segment {
public:
class Segment final {
private:
const std::string id;
public:
std::set<Trans*> gates;
std::set<Trans*> c1c2s;
bool vss;
@ -35,16 +36,13 @@ public:
Segment(const std::string& id) : id(id), vss(false), vcc(false), pull(id[0]=='+' ? Pull::UP : Pull::FLOAT), on(false) {
}
virtual ~Segment() {
}
void set(const bool up) {
this->pull = (up ? Pull::UP : Pull::DOWN);
}
bool operator<(const Segment& that) { return this->id < that.id; }
bool operator<(const Segment& that) const { return this->id < that.id; }
@ -68,7 +66,7 @@ private:
class Trans {
class Trans final {
public:
Segment* c1;
@ -84,9 +82,6 @@ public:
c2->c1c2s.insert(this);
}
virtual ~Trans() {
}
private:
Trans(const Trans&) = delete;

View File

@ -2180,7 +2180,7 @@ UML_LOOK = YES
# Minimum value: 0, maximum value: 100, default value: 10.
# This tag requires that the tag HAVE_DOT is set to YES.
UML_LIMIT_NUM_FIELDS = 10
UML_LIMIT_NUM_FIELDS = 100
# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
# collaboration graphs will show the relations between templates and their
@ -2298,7 +2298,7 @@ MSCFILE_DIRS =
# Minimum value: 0, maximum value: 10000, default value: 50.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_GRAPH_MAX_NODES = 50
DOT_GRAPH_MAX_NODES = 500
# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
# generated by dot. A depth value of 3 means that only nodes reachable from the