mirror of
https://github.com/cmosher01/v6502cpp.git
synced 2024-05-31 20:41:32 +00:00
git-svn-id: https://subversion.assembla.com/svn/cmosher/apple2/emu/v6502@10087 884d43a4-ffbe-47e9-90ca-fd8c37d7eb32
This commit is contained in:
parent
77a69187bf
commit
b3edf147d3
234
v6502.cpp
234
v6502.cpp
|
@ -16,7 +16,7 @@ public:
|
||||||
std::vector<int> gates;
|
std::vector<int> gates;
|
||||||
std::vector<int> c1c2s;
|
std::vector<int> c1c2s;
|
||||||
};
|
};
|
||||||
std::map<int,seg> segs;
|
std::vector<seg> segs;
|
||||||
|
|
||||||
class trn {
|
class trn {
|
||||||
public:
|
public:
|
||||||
|
@ -25,15 +25,7 @@ public:
|
||||||
int c2;
|
int c2;
|
||||||
bool on;
|
bool on;
|
||||||
};
|
};
|
||||||
std::map<int,trn> trns;
|
std::vector<trn> trns;
|
||||||
|
|
||||||
void pHex(unsigned char x) {
|
|
||||||
std::cout << std::setw(2) << std::setfill('0') << std::hex << (unsigned long)x << std::dec;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pHexw(unsigned short x) {
|
|
||||||
std::cout << std::setw(4) << std::setfill('0') << std::hex << (unsigned long)x << std::dec;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char readByte(int b7, int b6, int b5, int b4, int b3, int b2, int b1, int b0) {
|
unsigned char readByte(int b7, int b6, int b5, int b4, int b3, int b2, int b1, int b0) {
|
||||||
return
|
return
|
||||||
|
@ -67,6 +59,15 @@ unsigned short readWord(int b15, int b14, int b13, int b12, int b11, int b10, in
|
||||||
segs[b0].state;
|
segs[b0].state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char rData() {
|
||||||
|
return readByte(DB7,DB6,DB5,DB4,DB3,DB2,DB1,DB0);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short rAddr() {
|
||||||
|
return readWord(AB15,AB14,AB13,AB12,AB11,AB10,AB9,AB8,AB7,AB6,AB5,AB4,AB3,AB2,AB1,AB0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
unsigned char rA() {
|
unsigned char rA() {
|
||||||
return readByte(A7,A6,A5,A4,A3,A2,A1,A0);
|
return readByte(A7,A6,A5,A4,A3,A2,A1,A0);
|
||||||
}
|
}
|
||||||
|
@ -87,12 +88,12 @@ unsigned char rPC() {
|
||||||
return readWord(PCH7,PCH6,PCH5,PCH4,PCH3,PCH2,PCH1,PCH0,PCL7,PCL6,PCL5,PCL4,PCL3,PCL2,PCL1,PCL0);
|
return readWord(PCH7,PCH6,PCH5,PCH4,PCH3,PCH2,PCH1,PCH0,PCL7,PCL6,PCL5,PCL4,PCL3,PCL2,PCL1,PCL0);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char rData() {
|
void pHex(unsigned char x) {
|
||||||
return readByte(DB7,DB6,DB5,DB4,DB3,DB2,DB1,DB0);
|
std::cout << std::setw(2) << std::setfill('0') << std::hex << (unsigned long)x << std::dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short rAddr() {
|
void pHexw(unsigned short x) {
|
||||||
return readWord(AB15,AB14,AB13,AB12,AB11,AB10,AB9,AB8,AB7,AB6,AB5,AB4,AB3,AB2,AB1,AB0);
|
std::cout << std::setw(4) << std::setfill('0') << std::hex << (unsigned long)x << std::dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dumpRegs() {
|
void dumpRegs() {
|
||||||
|
@ -112,69 +113,7 @@ void dumpRegs() {
|
||||||
pHexw(rAddr());
|
pHexw(rAddr());
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
void setSeg(int iseg, bool up) {
|
|
||||||
seg& s = segs[iseg];
|
|
||||||
s.pullup = up;
|
|
||||||
s.pulldown = !up;
|
|
||||||
}
|
|
||||||
|
|
||||||
void recalc(const std::set<int>& s);
|
|
||||||
|
|
||||||
void setSegRC(int iseg, bool up) {
|
|
||||||
setSeg(iseg,up);
|
|
||||||
std::set<int> s;
|
|
||||||
s.insert(iseg);
|
|
||||||
recalc(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setHigh(int iseg) {
|
|
||||||
setSegRC(iseg,true);
|
|
||||||
}
|
|
||||||
void setLow(int iseg) {
|
|
||||||
setSegRC(iseg,false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isHigh(int iseg) {
|
|
||||||
return segs[iseg].state;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getGroupValue(const std::set<int>& s) {
|
|
||||||
if (s.find(VSS) != s.end()) {
|
|
||||||
return false; /* ground always pulls down */
|
|
||||||
}
|
|
||||||
if (s.find(VCC) != s.end()) {
|
|
||||||
return true; /* power always pulls up */
|
|
||||||
}
|
|
||||||
for (std::set<int>::const_iterator i = s.begin(); i != s.end(); ++i) {
|
|
||||||
const seg& s = segs[*i];
|
|
||||||
if (s.pullup) { return true; }
|
|
||||||
if (s.pulldown) { return false; }
|
|
||||||
if (s.state) { return true; }
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addToGroup(int n, std::set<int>& s) {
|
|
||||||
std::pair<std::set<int>::iterator,bool> ret = s.insert(n);
|
|
||||||
if (!ret.second) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (n==VCC || n==VSS) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
seg& sg = segs[n];
|
|
||||||
for (std::vector<int>::const_iterator itrn = sg.c1c2s.begin(); itrn != sg.c1c2s.end(); ++itrn) {
|
|
||||||
const trn& t = trns[*itrn];
|
|
||||||
if (t.on) {
|
|
||||||
if (t.c1==n) {
|
|
||||||
addToGroup(t.c2,s);
|
|
||||||
} else if (t.c2==n) {
|
|
||||||
addToGroup(t.c1,s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void addRecalc(int n, std::set<int>& rcl) {
|
void addRecalc(int n, std::set<int>& rcl) {
|
||||||
if (n==VCC || n==VSS) {
|
if (n==VCC || n==VSS) {
|
||||||
|
@ -200,28 +139,63 @@ void offTrans(trn& t, std::set<int>& rcl) {
|
||||||
addRecalc(t.c2,rcl);
|
addRecalc(t.c2,rcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void recalcNode(int n, std::set<int>& rcl) {
|
bool getGroupValue(const std::set<int>& s) {
|
||||||
|
if (s.find(VSS) != s.end()) {
|
||||||
|
return false; /* ground always pulls down */
|
||||||
|
}
|
||||||
|
if (s.find(VCC) != s.end()) {
|
||||||
|
return true; /* power always pulls up */
|
||||||
|
}
|
||||||
|
for (std::set<int>::const_iterator i = s.begin(); i != s.end(); ++i) {
|
||||||
|
const seg& s = segs[*i];
|
||||||
|
if (s.pullup) { return true; }
|
||||||
|
if (s.pulldown) { return false; }
|
||||||
|
if (s.state) { return true; }
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addToGroup(int n, std::set<int>& s) {
|
||||||
|
const std::pair<std::set<int>::iterator,bool> ret = s.insert(n);
|
||||||
|
if (!ret.second) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (n==VCC || n==VSS) {
|
if (n==VCC || n==VSS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::set<int> g;
|
const seg& sg = segs[n];
|
||||||
addToGroup(n,g);
|
for (std::vector<int>::const_iterator itrn = sg.c1c2s.begin(); itrn != sg.c1c2s.end(); ++itrn) {
|
||||||
const bool gval = getGroupValue(g);
|
const trn& t = trns[*itrn];
|
||||||
for (std::set<int>::iterator ig = g.begin(); ig != g.end(); ++ig) {
|
if (t.on) {
|
||||||
seg& seg = segs[*ig];
|
if (t.c1==n) {
|
||||||
if (seg.state != gval) {
|
addToGroup(t.c2,s);
|
||||||
seg.state = gval;
|
} else if (t.c2==n) {
|
||||||
for (std::vector<int>::iterator igate = seg.gates.begin(); igate != seg.gates.end(); ++igate) {
|
addToGroup(t.c1,s);
|
||||||
trn& t = trns[*igate];
|
}
|
||||||
if (seg.state) {
|
}
|
||||||
onTrans(t,rcl);
|
}
|
||||||
} else {
|
}
|
||||||
offTrans(t,rcl);
|
|
||||||
|
void recalcNode(int n, std::set<int>& rcl) {
|
||||||
|
if (!(n==VCC || n==VSS)) {
|
||||||
|
std::set<int> g;
|
||||||
|
addToGroup(n,g);
|
||||||
|
const bool gval = getGroupValue(g);
|
||||||
|
for (std::set<int>::iterator ig = g.begin(); ig != g.end(); ++ig) {
|
||||||
|
seg& seg = segs[*ig];
|
||||||
|
if (seg.state != gval) {
|
||||||
|
seg.state = gval;
|
||||||
|
for (std::vector<int>::iterator igate = seg.gates.begin(); igate != seg.gates.end(); ++igate) {
|
||||||
|
trn& t = trns[*igate];
|
||||||
|
if (seg.state) {
|
||||||
|
onTrans(t,rcl);
|
||||||
|
} else {
|
||||||
|
offTrans(t,rcl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void recalc(const std::set<int>& s) {
|
void recalc(const std::set<int>& s) {
|
||||||
|
@ -237,21 +211,46 @@ void recalc(const std::set<int>& s) {
|
||||||
}
|
}
|
||||||
list = rcl;
|
list = rcl;
|
||||||
if (sane >= 999) {
|
if (sane >= 999) {
|
||||||
std::cout << "WARNING: hit iteration limit during CPU state recalculation" << std::endl;
|
std::cerr << "WARNING: hit iteration limit during CPU state recalculation" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void recalcAll() {
|
void recalcAll() {
|
||||||
std::set<int> s;
|
std::set<int> s;
|
||||||
for (std::map<int,seg>::iterator i = segs.begin(); i != segs.end(); ++i) {
|
for (int i = 0; i < segs.size(); ++i) {
|
||||||
if (!(i->first == VCC || i->first == VSS)) {
|
if (!(i == VCC || i == VSS)) {
|
||||||
s.insert(i->first);
|
s.insert(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
recalc(s);
|
recalc(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setSeg(int iseg, bool up) {
|
||||||
|
seg& s = segs[iseg];
|
||||||
|
s.pullup = up;
|
||||||
|
s.pulldown = !up;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSegRC(int iseg, bool up) {
|
||||||
|
setSeg(iseg,up);
|
||||||
|
std::set<int> s;
|
||||||
|
s.insert(iseg);
|
||||||
|
recalc(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setHigh(int iseg) {
|
||||||
|
setSegRC(iseg,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLow(int iseg) {
|
||||||
|
setSegRC(iseg,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isHigh(int iseg) {
|
||||||
|
return segs[iseg].state;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char mRead(unsigned short addr) {
|
unsigned char mRead(unsigned short addr) {
|
||||||
//std::cout << "read mem: ";
|
//std::cout << "read mem: ";
|
||||||
//pHexw(addr);
|
//pHexw(addr);
|
||||||
|
@ -369,24 +368,29 @@ void init() {
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
std::cout << "reading segs";
|
std::cout << "reading segsonly";
|
||||||
std::ifstream if_segs("segs");
|
std::ifstream if_segs("segsonly");
|
||||||
if (!if_segs.is_open()) {
|
if (!if_segs.is_open()) {
|
||||||
std::cerr << "error opening file: segs" << std::endl;
|
std::cerr << "error opening file: segs" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int i_seg(0);
|
||||||
while (if_segs.good()) {
|
while (if_segs.good()) {
|
||||||
int i_seg(-1);
|
int i_segin(-1);
|
||||||
bool b_on(false);
|
bool b_on(false);
|
||||||
if_segs >> i_seg >> b_on;
|
if_segs >> i_segin >> b_on;
|
||||||
if (i_seg >= 0) {
|
if (i_segin >= 0) {
|
||||||
|
if (i_segin != i_seg++) {
|
||||||
|
std::cerr << "error: mismatch in segsonly file near " << i_segin << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
std::cout << ".";
|
std::cout << ".";
|
||||||
seg s;
|
seg s;
|
||||||
s.pullup = b_on;
|
s.pullup = b_on;
|
||||||
s.pulldown = false; /* ??? !b_on */
|
s.pulldown = false; /* ??? !b_on */
|
||||||
s.state = false;
|
s.state = false;
|
||||||
segs[i_seg] = s;
|
segs.push_back(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << std::endl << "read " << segs.size() << " segs" << std::endl;
|
std::cout << std::endl << "read " << segs.size() << " segs" << std::endl;
|
||||||
|
@ -400,25 +404,29 @@ int main(int argc, char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int i_trn(0);
|
||||||
while (if_trns.good()) {
|
while (if_trns.good()) {
|
||||||
std::cout << ".";
|
std::cout << ".";
|
||||||
int i_trn(-1);
|
int i_trnin(-1);
|
||||||
int i_gate, i_c1, i_c2;
|
int i_gate, i_c1, i_c2;
|
||||||
if_trns >> i_trn >> i_gate >> i_c1 >> i_c2;
|
if_trns >> i_trnin >> i_gate >> i_c1 >> i_c2;
|
||||||
if (i_trn >= 0) {
|
if (i_trnin >= 0) {
|
||||||
|
if (i_trnin != i_trn++) {
|
||||||
|
std::cerr << "error: mismatch in trns file near " << i_trnin << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
trn t;
|
trn t;
|
||||||
t.gate = i_gate;
|
t.gate = i_gate;
|
||||||
t.c1 = i_c1;
|
t.c1 = i_c1;
|
||||||
t.c2 = i_c2;
|
t.c2 = i_c2;
|
||||||
t.on = false;
|
t.on = false;
|
||||||
trns[i_trn] = t;
|
trns.push_back(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << std::endl << "read " << trns.size() << " trns" << std::endl;
|
std::cout << std::endl << "read " << trns.size() << " trns" << std::endl;
|
||||||
|
|
||||||
for (std::map<int,trn>::iterator i = trns.begin(); i != trns.end(); ++i) {
|
for (int i = 0; i != trns.size(); ++i) {
|
||||||
const int n = (*i).first;
|
trn& t = trns[i];
|
||||||
trn& t = (*i).second;
|
|
||||||
if (t.c1==VSS) {
|
if (t.c1==VSS) {
|
||||||
t.c1 = t.c2;
|
t.c1 = t.c2;
|
||||||
t.c2 = VSS;
|
t.c2 = VSS;
|
||||||
|
@ -426,15 +434,15 @@ int main(int argc, char *argv[])
|
||||||
t.c1 = t.c2;
|
t.c1 = t.c2;
|
||||||
t.c2 = VCC;
|
t.c2 = VCC;
|
||||||
}
|
}
|
||||||
segs[t.gate].gates.push_back(n);
|
segs[t.gate].gates.push_back(i);
|
||||||
segs[t.c1].c1c2s.push_back(n);
|
segs[t.c1].c1c2s.push_back(i);
|
||||||
segs[t.c2].c1c2s.push_back(n);
|
segs[t.c2].c1c2s.push_back(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
std::cerr << "running some..." << std::endl;
|
std::cerr << "running some..." << std::endl;
|
||||||
for (int i(0); i < 500; ++i) {
|
for (int i(0); i < 5000; ++i) {
|
||||||
step();
|
step();
|
||||||
//dumpRegs();
|
//dumpRegs();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user