refactor: further split Common and SegmentCache

This commit is contained in:
Christopher Mosher 2013-12-14 22:48:06 -05:00
parent ca692a6fc8
commit 5b009ee67e
13 changed files with 171 additions and 167 deletions

View File

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

View File

@ -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 */

View File

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

View File

@ -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 */

View File

@ -18,7 +18,7 @@
#include <set>
#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)});
}

View File

@ -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 */

View File

@ -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)

View File

@ -6,107 +6,39 @@
*/
#include "SegmentCache.h"
#include "Common.h"
#include <memory>
#include <string>
#include <map>
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<Segment>(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);
}

View File

@ -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 std::string, std::shared_ptr<Segment > >::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 */

View File

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

View File

@ -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 */

View File

@ -12,6 +12,7 @@
#include <memory>
#include <iostream>
#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());
}

View File

@ -3,12 +3,12 @@
#include "Cpu6502Helper.h"
#include "TransNetwork.h"
#include "Trace.h"
#include "Common.h"
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <set>
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);