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

View File

@ -9,28 +9,43 @@
#define CIRCUIT_H
#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 {
public:
Circuit(Segment* extendFrom);
Circuit(Segment* extendFrom) {
extend(extendFrom);
}
virtual ~Circuit() {
}
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:
Circuit(const Circuit&);
Circuit& operator=(const Circuit&);
Circuit(const Circuit&) = delete;
Circuit& operator=(const Circuit&) = delete;
void extend(Segment* extendFrom);
std::set<Segment*> segs;
setpSeg segs;
};
#endif /* CIRCUIT_H */

View File

@ -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<Segment*> 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<Segment*> s;
setpSeg s;
segs.addDataToRecalc(s);
recalc(s);
StateCalculator::recalc(s);
writeBus();
}

View File

@ -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<Segment*> s);
TransNetwork& transNetwork;
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)
DEPS = $(SRCS:.cpp=.d)

View File

@ -95,7 +95,7 @@ void SegmentCache::setDataSegs(const unsigned char data) {
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->DB1);
s.insert(this->c->DB2);

View File

@ -27,8 +27,8 @@ public:
Segment* getOrAdd(const std::string& id);
Segment* get(const std::string& id) const;
std::set<Segment*> all() {
std::set<Segment*> 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<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:
std::map<const std::string, std::shared_ptr<Segment > > cache;

View File

@ -10,16 +10,8 @@
#include "trans.h"
#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) {
std::set<Segment*> 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<Segment*>& segs) {
void StateCalculator::recalc(const setpSeg& segs) {
int sanity(0);
std::set<Segment*> 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<Segment*>& segs) {
for (auto s : changed) {
c.recalcNode(s);
}
changed = c.getChanged();
changed = c.segs;
}
}

View File

@ -9,17 +9,15 @@
#define STATECALCULATOR_H
#include <set>
class Segment;
class Trans;
#include "trans.h"
class StateCalculator {
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:
std::set<Segment*> 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<Segment*> getChanged() {
return this->segs;
}
setpSeg segs;
};
#endif /* STATECALCULATOR_H */

View File

@ -9,6 +9,7 @@
#include "SegmentCache.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;
@ -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 {

View File

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

View File

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

View File

@ -5,32 +5,9 @@
#include <cstdlib>
#include <iostream>
#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[]) {
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);