diff --git a/Circuit.cpp b/Circuit.cpp index b6ef4e7..497bb09 100644 --- a/Circuit.cpp +++ b/Circuit.cpp @@ -8,10 +8,6 @@ #include "Circuit.h" #include "trans.h" -Circuit::Circuit(Segment* extendFrom) { - extend(extendFrom); -} - /* * Adds segment extendFrom, and all segments electrically connected to it. * This happens recursively, but we don't recurse past ground or voltage supply. @@ -19,8 +15,11 @@ Circuit::Circuit(Segment* extendFrom) { void Circuit::extend(Segment* extendFrom) { auto ret = this->segs.insert(extendFrom); if (!ret.second) { + /* We've already processed this segment. */ return; } + + /* Don't recurse past ground or voltage supply. */ if (extendFrom->vss || extendFrom->vcc) { return; } diff --git a/Circuit.h b/Circuit.h index edfb112..1657aa2 100644 --- a/Circuit.h +++ b/Circuit.h @@ -9,28 +9,43 @@ #define CIRCUIT_H #include +#include "trans.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. + */ class Circuit { public: - Circuit(Segment* extendFrom); + + Circuit(Segment* extendFrom) { + extend(extendFrom); + } virtual ~Circuit() { } bool getValue(); - std::set::iterator begin() { return this->segs.begin(); } - std::set::iterator end() { return this->segs.end(); } + + setpSeg::iterator begin() { + return this->segs.begin(); + } + + setpSeg::iterator end() { + return this->segs.end(); + } private: - Circuit(const Circuit&); - Circuit& operator=(const Circuit&); + + Circuit(const Circuit&) = delete; + Circuit& operator=(const Circuit&) = delete; void extend(Segment* extendFrom); - std::set segs; + setpSeg segs; }; #endif /* CIRCUIT_H */ - diff --git a/Cpu6502.cpp b/Cpu6502.cpp index 9616172..1d3c097 100644 --- a/Cpu6502.cpp +++ b/Cpu6502.cpp @@ -29,7 +29,7 @@ #endif #ifdef TRACESEG -#define dumpSegs() dumpSegments() +#define dumpSegs() this->trace.dumpSegments() #else #define dumpSegs() #endif @@ -59,7 +59,7 @@ void Cpu6502::powerOn() { initPins(); std::cout << "initial full calculation..." << std::endl; - recalc(segs.all()); + StateCalculator::recalc(segs.all()); dumpRegs(); dumpSegs(); } @@ -68,14 +68,6 @@ void Cpu6502::setSeg(Segment* s, bool on) { s->set(on); } -void Cpu6502::recalc(Segment* s) { - StateCalculator::recalc(s); -} - -void Cpu6502::recalc(std::set s) { - StateCalculator::recalc(s); -} - void Cpu6502::initPins() { // set voltage supply and ground. setSeg(n->VCC, true); @@ -108,7 +100,7 @@ void Cpu6502::initPins() { void Cpu6502::reset() { setSeg(n->RES, true); - recalc(n->RES); + StateCalculator::recalc(n->RES); } void Cpu6502::tick() { @@ -138,7 +130,7 @@ void Cpu6502::step() { void Cpu6502::clock(bool phase) { setSeg(n->CLK0, phase); - recalc(n->CLK0); + StateCalculator::recalc(n->CLK0); } void Cpu6502::rw() { @@ -146,9 +138,9 @@ void Cpu6502::rw() { if (n->CLK2OUT->on) { readBus(); - std::set s; + setpSeg s; segs.addDataToRecalc(s); - recalc(s); + StateCalculator::recalc(s); writeBus(); } diff --git a/Cpu6502.h b/Cpu6502.h index 05bf5c5..0d96611 100644 --- a/Cpu6502.h +++ b/Cpu6502.h @@ -42,8 +42,6 @@ private: void write(unsigned short addr, unsigned char data); static void setSeg(Segment* s, bool on); - void recalc(Segment* s); - void recalc(std::set s); TransNetwork& transNetwork; AddressBus& addressBus; diff --git a/Makefile b/Makefile index 24a8624..8ccfa5e 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ -CXXFLAGS=-g -std=c++11 -Wall -O4 +CXXFLAGS=-g -std=c++11 -Wall -O0 -SRCS = v6502.cpp trans.cpp SegmentCache.cpp TransNetwork.cpp Trace.cpp Circuit.cpp StateCalculator.cpp Cpu6502.cpp +SRCS = v6502.cpp SegmentCache.cpp TransNetwork.cpp Trace.cpp Circuit.cpp StateCalculator.cpp Cpu6502.cpp OBJS = $(SRCS:.cpp=.o) DEPS = $(SRCS:.cpp=.d) diff --git a/SegmentCache.cpp b/SegmentCache.cpp index 74935d4..0e58373 100644 --- a/SegmentCache.cpp +++ b/SegmentCache.cpp @@ -95,7 +95,7 @@ void SegmentCache::setDataSegs(const unsigned char data) { this->c->DB7->set(x & 1); } -void SegmentCache::addDataToRecalc(std::set& s) { +void SegmentCache::addDataToRecalc(setpSeg& s) { s.insert(this->c->DB0); s.insert(this->c->DB1); s.insert(this->c->DB2); diff --git a/SegmentCache.h b/SegmentCache.h index c004a40..5113117 100644 --- a/SegmentCache.h +++ b/SegmentCache.h @@ -27,8 +27,8 @@ public: Segment* getOrAdd(const std::string& id); Segment* get(const std::string& id) const; - std::set all() { - std::set s; + setpSeg all() const { + setpSeg s; for (auto i : this->cache) { s.insert(i.second.get()); } @@ -182,7 +182,10 @@ public: unsigned short rPC() const; void setDataSegs(const unsigned char data); - void addDataToRecalc(std::set& s); + void addDataToRecalc(setpSeg& s); + + std::map >::const_iterator begin() const { return this->cache.begin(); } + std::map >::const_iterator end() const { return this->cache.end(); } private: std::map > cache; diff --git a/StateCalculator.cpp b/StateCalculator.cpp index 33c7fd4..aca7068 100644 --- a/StateCalculator.cpp +++ b/StateCalculator.cpp @@ -10,16 +10,8 @@ #include "trans.h" #include -//void StateCalculator::recalcAll() { -// std::set riSeg; -// for (int iSeg = 0; iSeg < segs.size(); ++iSeg) { -// addRecalc(iSeg,riSeg); -// } -// recalc(riSeg); -//} - void StateCalculator::recalc(Segment* seg) { - std::set rSeg; + setpSeg rSeg; rSeg.insert(seg); recalc(rSeg); } @@ -32,10 +24,10 @@ void StateCalculator::recalc(Segment* seg) { */ #define SANE (100) -void StateCalculator::recalc(const std::set& segs) { +void StateCalculator::recalc(const setpSeg& segs) { int sanity(0); - std::set changed(segs); + setpSeg changed(segs); while (!changed.empty()) { if (++sanity >= SANE) { throw "ERROR: reached maximum iteration limit while recalculating CPU state"; @@ -45,7 +37,7 @@ void StateCalculator::recalc(const std::set& segs) { for (auto s : changed) { c.recalcNode(s); } - changed = c.getChanged(); + changed = c.segs; } } diff --git a/StateCalculator.h b/StateCalculator.h index 2eebcd7..3337ecf 100644 --- a/StateCalculator.h +++ b/StateCalculator.h @@ -9,17 +9,15 @@ #define STATECALCULATOR_H #include - -class Segment; -class Trans; +#include "trans.h" class StateCalculator { public: - static void recalc(const std::set& rSeg); - static void recalc(Segment* seg); + + static void recalc(const setpSeg& rSeg); + static void recalc(Segment* seg); // convenience method private: - std::set segs; StateCalculator() { } @@ -27,17 +25,15 @@ private: virtual ~StateCalculator() { } - StateCalculator(const StateCalculator&); - StateCalculator& operator=(const 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); - std::set getChanged() { - return this->segs; - } + setpSeg segs; }; #endif /* STATECALCULATOR_H */ diff --git a/Trace.cpp b/Trace.cpp index 5da30ff..7864436 100644 --- a/Trace.cpp +++ b/Trace.cpp @@ -9,6 +9,7 @@ #include "SegmentCache.h" #include #include +#include static void pHex(const unsigned long x, const int width) { std::cout << std::setw(width) << std::setfill('0') << std::hex << x << std::dec; @@ -23,22 +24,18 @@ static void pHexw(const unsigned short x) { } void Trace::dumpSegments() const { -// for (int i = 0; i < segs.size(); ++i) { -// seg& s = segs[i]; -// if (s.pullup) { -// std::cout << "U"; -// } else if (s.pulldown) { -// std::cout << "D"; -// } else { -// std::cout << "f"; -// } -// if (s->on) { -// std::cout << "+"; -// } else { -// std::cout << "-"; -// } -// } -// std::cout << std::endl; + for (auto sp : this->s) { + Segment* seg = sp.second.get(); + assert(!(seg->pullup && seg->pulldown)); + if (seg->pullup) { + std::cout << (seg->on ? "U" : "u"); + } else if (seg->pulldown) { + std::cout << (seg->on ? "D" : "d"); + } else { + std::cout << (seg->on ? "F" : "f"); + } + } + std::cout << std::endl; } void Trace::dumpRegisters() const { diff --git a/TransNetwork.cpp b/TransNetwork.cpp index b9f3db1..f87884a 100644 --- a/TransNetwork.cpp +++ b/TransNetwork.cpp @@ -7,6 +7,8 @@ #include "TransNetwork.h" #include "trans.h" +#include +#include #include #include diff --git a/TransNetwork.h b/TransNetwork.h index c41a0a3..30d7826 100644 --- a/TransNetwork.h +++ b/TransNetwork.h @@ -8,22 +8,26 @@ #ifndef TRANSNETWORK_H #define TRANSNETWORK_H -#include "trans.h" +class Trans; #include "SegmentCache.h" +#include +#include #include class TransNetwork { public: - SegmentCache segs; - std::set> transes; -public: + SegmentCache segs; + TransNetwork(std::istream& readFromHere); virtual ~TransNetwork(); private: + TransNetwork(const TransNetwork&) = delete; TransNetwork& operator=(const TransNetwork&) = delete; + + std::set> transes; }; #endif /* TRANSNETWORK_H */ diff --git a/ptr_less.h b/ptr_less.h new file mode 100644 index 0000000..98dd6d4 --- /dev/null +++ b/ptr_less.h @@ -0,0 +1,20 @@ +/* + * File: ptr_less.h + * Author: Christopher + * + * Created on December 14, 2013, 5:44 PM + */ + +#ifndef PTR_LESS_H +#define PTR_LESS_H + +template +struct ptr_less { + + bool operator()(T* pa, T* pb) { + return *pa < *pb; + } + +}; + +#endif /* PTR_LESS_H */ diff --git a/trans.cpp b/trans.cpp deleted file mode 100644 index 56996cb..0000000 --- a/trans.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * File: Trans.cpp - * Author: cmosher - * - * Created on December 11, 2013, 10:44 AM - */ - -#include "trans.h" - -unsigned char Segment::asByte(Segment* b7, Segment* b6, Segment* b5, Segment* b4, Segment* b3, Segment* b2, Segment* b1, Segment* b0) { - return - b7->on << 0x7 | - b6->on << 0x6 | - b5->on << 0x5 | - b4->on << 0x4 | - b3->on << 0x3 | - b2->on << 0x2 | - b1->on << 0x1 | - b0->on; -} - -unsigned short Segment::asWord(Segment* bf, Segment* be, Segment* bd, Segment* bc, Segment* bb, Segment* ba, Segment* b9, Segment* b8, Segment* b7, Segment* b6, Segment* b5, Segment* b4, Segment* b3, Segment* b2, Segment* b1, Segment* b0) { - return - bf->on << 0xf | - be->on << 0xe | - bd->on << 0xd | - bc->on << 0xc | - bb->on << 0xb | - ba->on << 0xa | - b9->on << 0x9 | - b8->on << 0x8 | - b7->on << 0x7 | - b6->on << 0x6 | - b5->on << 0x5 | - b4->on << 0x4 | - b3->on << 0x3 | - b2->on << 0x2 | - b1->on << 0x1 | - b0->on; -} diff --git a/trans.h b/trans.h index c7238a0..893a79a 100644 --- a/trans.h +++ b/trans.h @@ -10,6 +10,7 @@ #include #include +#include "ptr_less.h" class Trans; @@ -34,10 +35,19 @@ public: this->pulldown = !up; } - static unsigned char asByte(Segment* b7, Segment* b6, Segment* b5, Segment* b4, Segment* b3, Segment* b2, Segment* b1, Segment* b0); - static unsigned short asWord(Segment* b15, Segment* b14, Segment* b13, Segment* b12, Segment* b11, Segment* b10, Segment* b9, Segment* b8, Segment* b7, Segment* b6, Segment* b5, Segment* b4, Segment* b3, Segment* b2, Segment* b1, Segment* b0); + static unsigned char asByte(Segment* b7, Segment* b6, Segment* b5, Segment* b4, Segment* b3, Segment* b2, Segment* b1, Segment* b0) { + return b7->on << 0x7 | b6->on << 0x6 | b5->on << 0x5 | b4->on << 0x4 | b3->on << 0x3 | b2->on << 0x2 | b1->on << 0x1 | b0->on; + } + + static unsigned short asWord(Segment* bf, Segment* be, Segment* bd, Segment* bc, Segment* bb, Segment* ba, Segment* b9, Segment* b8, Segment* b7, Segment* b6, Segment* b5, Segment* b4, Segment* b3, Segment* b2, Segment* b1, Segment* b0) { + return bf->on << 0xf | be->on << 0xe | bd->on << 0xd | bc->on << 0xc | bb->on << 0xb | ba->on << 0xa | b9->on << 0x9 | b8->on << 0x8 | b7->on << 0x7 | b6->on << 0x6 | b5->on << 0x5 | b4->on << 0x4 | b3->on << 0x3 | b2->on << 0x2 | b1->on << 0x1 | b0->on; + } + + bool operator<(const Segment& that) { return this->id < that.id; } }; +typedef std::set> setpSeg; + class Trans { public: Segment* c1; diff --git a/v6502.cpp b/v6502.cpp index 801b475..5cab3ed 100644 --- a/v6502.cpp +++ b/v6502.cpp @@ -5,32 +5,9 @@ #include #include #include +#include - -//memory[0xFF] = 0x68; // PLA - -//memory[0xFF] = 0xFF; -//memory[0xFFFF] = 0xFE; -//memory[0xFEFE] = 0xFD; -//memory[0xFDFD] = 0xFC; -//memory[0xFCFC] = 0xFB; -//memory[0xFBFB] = 0xFA; -//memory[0xFAFA] = 0xF9; - -//void pZP() { -// int a = 0; -// for (int i = 0; i < 16; ++i) { -// pHexw(a); -// std::cout << ": "; -// for (int j = 0; j < 16; ++j) { -// pHex(memory[a++]); -// std::cout << " "; -// } -// std::cout << std::endl; -// } -//} - int main(int argc, char *argv[]) { AddressBus mem; @@ -58,9 +35,9 @@ int main(int argc, char *argv[]) { } TransNetwork tn(if_trans); Trace trace(tn.segs); - Cpu6502 cpu(tn,mem,trace); + Cpu6502 cpu(tn, mem, trace); + -