fixed inconsistent breaking; other refactoring

the sets of Segment* 's needed to be sorted consistently
This commit is contained in:
Christopher Mosher 2013-12-14 18:10:32 -05:00
parent e05f941086
commit 40ba79a34d
16 changed files with 111 additions and 146 deletions

View File

@ -8,10 +8,6 @@
#include "Circuit.h" #include "Circuit.h"
#include "trans.h" #include "trans.h"
Circuit::Circuit(Segment* extendFrom) {
extend(extendFrom);
}
/* /*
* Adds segment extendFrom, and all segments electrically connected to it. * Adds segment extendFrom, and all segments electrically connected to it.
* This happens recursively, but we don't recurse past ground or voltage supply. * 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) { void Circuit::extend(Segment* extendFrom) {
auto ret = this->segs.insert(extendFrom); auto ret = this->segs.insert(extendFrom);
if (!ret.second) { if (!ret.second) {
/* We've already processed this segment. */
return; return;
} }
/* Don't recurse past ground or voltage supply. */
if (extendFrom->vss || extendFrom->vcc) { if (extendFrom->vss || extendFrom->vcc) {
return; return;
} }

View File

@ -9,28 +9,43 @@
#define CIRCUIT_H #define CIRCUIT_H
#include <set> #include <set>
#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 { class Circuit {
public: public:
Circuit(Segment* extendFrom);
Circuit(Segment* extendFrom) {
extend(extendFrom);
}
virtual ~Circuit() { virtual ~Circuit() {
} }
bool getValue(); bool getValue();
std::set<Segment*>::iterator begin() { return this->segs.begin(); }
std::set<Segment*>::iterator end() { return this->segs.end(); } setpSeg::iterator begin() {
return this->segs.begin();
}
setpSeg::iterator end() {
return this->segs.end();
}
private: private:
Circuit(const Circuit&);
Circuit& operator=(const Circuit&); Circuit(const Circuit&) = delete;
Circuit& operator=(const Circuit&) = delete;
void extend(Segment* extendFrom); void extend(Segment* extendFrom);
std::set<Segment*> segs; setpSeg segs;
}; };
#endif /* CIRCUIT_H */ #endif /* CIRCUIT_H */

View File

@ -29,7 +29,7 @@
#endif #endif
#ifdef TRACESEG #ifdef TRACESEG
#define dumpSegs() dumpSegments() #define dumpSegs() this->trace.dumpSegments()
#else #else
#define dumpSegs() #define dumpSegs()
#endif #endif
@ -59,7 +59,7 @@ void Cpu6502::powerOn() {
initPins(); initPins();
std::cout << "initial full calculation..." << std::endl; std::cout << "initial full calculation..." << std::endl;
recalc(segs.all()); StateCalculator::recalc(segs.all());
dumpRegs(); dumpRegs();
dumpSegs(); dumpSegs();
} }
@ -68,14 +68,6 @@ void Cpu6502::setSeg(Segment* s, bool on) {
s->set(on); s->set(on);
} }
void Cpu6502::recalc(Segment* s) {
StateCalculator::recalc(s);
}
void Cpu6502::recalc(std::set<Segment*> s) {
StateCalculator::recalc(s);
}
void Cpu6502::initPins() { void Cpu6502::initPins() {
// set voltage supply and ground. // set voltage supply and ground.
setSeg(n->VCC, true); setSeg(n->VCC, true);
@ -108,7 +100,7 @@ void Cpu6502::initPins() {
void Cpu6502::reset() { void Cpu6502::reset() {
setSeg(n->RES, true); setSeg(n->RES, true);
recalc(n->RES); StateCalculator::recalc(n->RES);
} }
void Cpu6502::tick() { void Cpu6502::tick() {
@ -138,7 +130,7 @@ void Cpu6502::step() {
void Cpu6502::clock(bool phase) { void Cpu6502::clock(bool phase) {
setSeg(n->CLK0, phase); setSeg(n->CLK0, phase);
recalc(n->CLK0); StateCalculator::recalc(n->CLK0);
} }
void Cpu6502::rw() { void Cpu6502::rw() {
@ -146,9 +138,9 @@ void Cpu6502::rw() {
if (n->CLK2OUT->on) { if (n->CLK2OUT->on) {
readBus(); readBus();
std::set<Segment*> s; setpSeg s;
segs.addDataToRecalc(s); segs.addDataToRecalc(s);
recalc(s); StateCalculator::recalc(s);
writeBus(); writeBus();
} }

View File

@ -42,8 +42,6 @@ private:
void write(unsigned short addr, unsigned char data); void write(unsigned short addr, unsigned char data);
static void setSeg(Segment* s, bool on); static void setSeg(Segment* s, bool on);
void recalc(Segment* s);
void recalc(std::set<Segment*> s);
TransNetwork& transNetwork; TransNetwork& transNetwork;
AddressBus& addressBus; AddressBus& addressBus;

View File

@ -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) OBJS = $(SRCS:.cpp=.o)
DEPS = $(SRCS:.cpp=.d) DEPS = $(SRCS:.cpp=.d)

View File

@ -95,7 +95,7 @@ void SegmentCache::setDataSegs(const unsigned char data) {
this->c->DB7->set(x & 1); this->c->DB7->set(x & 1);
} }
void SegmentCache::addDataToRecalc(std::set<Segment*>& s) { void SegmentCache::addDataToRecalc(setpSeg& s) {
s.insert(this->c->DB0); s.insert(this->c->DB0);
s.insert(this->c->DB1); s.insert(this->c->DB1);
s.insert(this->c->DB2); s.insert(this->c->DB2);

View File

@ -27,8 +27,8 @@ public:
Segment* getOrAdd(const std::string& id); Segment* getOrAdd(const std::string& id);
Segment* get(const std::string& id) const; Segment* get(const std::string& id) const;
std::set<Segment*> all() { setpSeg all() const {
std::set<Segment*> s; setpSeg s;
for (auto i : this->cache) { for (auto i : this->cache) {
s.insert(i.second.get()); s.insert(i.second.get());
} }
@ -182,7 +182,10 @@ public:
unsigned short rPC() const; unsigned short rPC() const;
void setDataSegs(const unsigned char data); void setDataSegs(const unsigned char data);
void addDataToRecalc(std::set<Segment*>& s); void addDataToRecalc(setpSeg& s);
std::map<const std::string, std::shared_ptr<Segment > >::const_iterator begin() const { return this->cache.begin(); }
std::map<const std::string, std::shared_ptr<Segment > >::const_iterator end() const { return this->cache.end(); }
private: private:
std::map<const std::string, std::shared_ptr<Segment > > cache; std::map<const std::string, std::shared_ptr<Segment > > cache;

View File

@ -10,16 +10,8 @@
#include "trans.h" #include "trans.h"
#include <set> #include <set>
//void StateCalculator::recalcAll() {
// std::set<int> riSeg;
// for (int iSeg = 0; iSeg < segs.size(); ++iSeg) {
// addRecalc(iSeg,riSeg);
// }
// recalc(riSeg);
//}
void StateCalculator::recalc(Segment* seg) { void StateCalculator::recalc(Segment* seg) {
std::set<Segment*> rSeg; setpSeg rSeg;
rSeg.insert(seg); rSeg.insert(seg);
recalc(rSeg); recalc(rSeg);
} }
@ -32,10 +24,10 @@ void StateCalculator::recalc(Segment* seg) {
*/ */
#define SANE (100) #define SANE (100)
void StateCalculator::recalc(const std::set<Segment*>& segs) { void StateCalculator::recalc(const setpSeg& segs) {
int sanity(0); int sanity(0);
std::set<Segment*> changed(segs); setpSeg changed(segs);
while (!changed.empty()) { while (!changed.empty()) {
if (++sanity >= SANE) { if (++sanity >= SANE) {
throw "ERROR: reached maximum iteration limit while recalculating CPU state"; throw "ERROR: reached maximum iteration limit while recalculating CPU state";
@ -45,7 +37,7 @@ void StateCalculator::recalc(const std::set<Segment*>& segs) {
for (auto s : changed) { for (auto s : changed) {
c.recalcNode(s); c.recalcNode(s);
} }
changed = c.getChanged(); changed = c.segs;
} }
} }

View File

@ -9,17 +9,15 @@
#define STATECALCULATOR_H #define STATECALCULATOR_H
#include <set> #include <set>
#include "trans.h"
class Segment;
class Trans;
class StateCalculator { class StateCalculator {
public: public:
static void recalc(const std::set<Segment*>& rSeg);
static void recalc(Segment* seg); static void recalc(const setpSeg& rSeg);
static void recalc(Segment* seg); // convenience method
private: private:
std::set<Segment*> segs;
StateCalculator() { StateCalculator() {
} }
@ -27,17 +25,15 @@ private:
virtual ~StateCalculator() { virtual ~StateCalculator() {
} }
StateCalculator(const StateCalculator&); StateCalculator(const StateCalculator&) = delete;
StateCalculator& operator=(const StateCalculator&); StateCalculator& operator=(const StateCalculator&) = delete;
void recalcNode(Segment* seg); void recalcNode(Segment* seg);
void setSeg(Segment* s, const bool on); void setSeg(Segment* s, const bool on);
void setTrans(Trans* t, const bool on); void setTrans(Trans* t, const bool on);
void addRecalc(Segment* seg); void addRecalc(Segment* seg);
std::set<Segment*> getChanged() { setpSeg segs;
return this->segs;
}
}; };
#endif /* STATECALCULATOR_H */ #endif /* STATECALCULATOR_H */

View File

@ -9,6 +9,7 @@
#include "SegmentCache.h" #include "SegmentCache.h"
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
#include <cassert>
static void pHex(const unsigned long x, const int width) { static void pHex(const unsigned long x, const int width) {
std::cout << std::setw(width) << std::setfill('0') << std::hex << x << std::dec; 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 { void Trace::dumpSegments() const {
// for (int i = 0; i < segs.size(); ++i) { for (auto sp : this->s) {
// seg& s = segs[i]; Segment* seg = sp.second.get();
// if (s.pullup) { assert(!(seg->pullup && seg->pulldown));
// std::cout << "U"; if (seg->pullup) {
// } else if (s.pulldown) { std::cout << (seg->on ? "U" : "u");
// std::cout << "D"; } else if (seg->pulldown) {
// } else { std::cout << (seg->on ? "D" : "d");
// std::cout << "f"; } else {
// } std::cout << (seg->on ? "F" : "f");
// if (s->on) { }
// std::cout << "+"; }
// } else { std::cout << std::endl;
// std::cout << "-";
// }
// }
// std::cout << std::endl;
} }
void Trace::dumpRegisters() const { void Trace::dumpRegisters() const {

View File

@ -7,6 +7,8 @@
#include "TransNetwork.h" #include "TransNetwork.h"
#include "trans.h" #include "trans.h"
#include <set>
#include <string>
#include <memory> #include <memory>
#include <iostream> #include <iostream>

View File

@ -8,22 +8,26 @@
#ifndef TRANSNETWORK_H #ifndef TRANSNETWORK_H
#define TRANSNETWORK_H #define TRANSNETWORK_H
#include "trans.h" class Trans;
#include "SegmentCache.h" #include "SegmentCache.h"
#include <set>
#include <memory>
#include <istream> #include <istream>
class TransNetwork { class TransNetwork {
public: public:
SegmentCache segs;
std::set<std::shared_ptr<Trans>> transes;
public: SegmentCache segs;
TransNetwork(std::istream& readFromHere); TransNetwork(std::istream& readFromHere);
virtual ~TransNetwork(); virtual ~TransNetwork();
private: private:
TransNetwork(const TransNetwork&) = delete; TransNetwork(const TransNetwork&) = delete;
TransNetwork& operator=(const TransNetwork&) = delete; TransNetwork& operator=(const TransNetwork&) = delete;
std::set<std::shared_ptr<Trans >> transes;
}; };
#endif /* TRANSNETWORK_H */ #endif /* TRANSNETWORK_H */

20
ptr_less.h Normal file
View File

@ -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<typename T>
struct ptr_less {
bool operator()(T* pa, T* pb) {
return *pa < *pb;
}
};
#endif /* PTR_LESS_H */

View File

@ -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;
}

14
trans.h
View File

@ -10,6 +10,7 @@
#include <string> #include <string>
#include <set> #include <set>
#include "ptr_less.h"
class Trans; class Trans;
@ -34,10 +35,19 @@ public:
this->pulldown = !up; 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 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); 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<Segment*,ptr_less<Segment>> setpSeg;
class Trans { class Trans {
public: public:
Segment* c1; Segment* c1;

View File

@ -5,32 +5,9 @@
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <set>
//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[]) { int main(int argc, char *argv[]) {
AddressBus mem; AddressBus mem;
@ -58,9 +35,9 @@ int main(int argc, char *argv[]) {
} }
TransNetwork tn(if_trans); TransNetwork tn(if_trans);
Trace trace(tn.segs); Trace trace(tn.segs);
Cpu6502 cpu(tn,mem,trace); Cpu6502 cpu(tn, mem, trace);