This commit is contained in:
cmosher 2011-06-26 23:52:13 +00:00
parent cb855b7f3f
commit 27ec3d4d32
2 changed files with 150 additions and 59 deletions

49
nodes.h
View File

@ -1,5 +1,16 @@
/* power */
#define VCC (657)
#define VSS (558)
/* inputs */
#define CLK0 (1171)
#define IRQ (103)
#define RES (159) #define RES (159)
#define RW (1156) #define NMI (1297)
#define RDY (89)
#define SO (1672)
/* data bus (I/O) */
#define DB0 (1005) #define DB0 (1005)
#define DB1 (82) #define DB1 (82)
#define DB3 (650) #define DB3 (650)
@ -8,6 +19,8 @@
#define DB4 (1393) #define DB4 (1393)
#define DB7 (1349) #define DB7 (1349)
#define DB6 (1591) #define DB6 (1591)
/* address bus (output) */
#define AB0 (268) #define AB0 (268)
#define AB1 (451) #define AB1 (451)
#define AB2 (1340) #define AB2 (1340)
@ -24,16 +37,14 @@
#define AB11 (399) #define AB11 (399)
#define AB14 (672) #define AB14 (672)
#define AB15 (195) #define AB15 (195)
/* outputs */
#define RW (1156)
#define SYNC (539) #define SYNC (539)
#define SO (1672)
#define CLK0 (1171)
#define CLK1OUT (1163) #define CLK1OUT (1163)
#define CLK2OUT (421) #define CLK2OUT (421)
#define RDY (89)
#define NMI (1297) /* internal registers */
#define IRQ (103)
#define VCC (657)
#define VSS (558)
#define A0 (737) #define A0 (737)
#define A1 (1234) #define A1 (1234)
#define A2 (978) #define A2 (978)
@ -42,14 +53,7 @@
#define A5 (858) #define A5 (858)
#define A6 (1136) #define A6 (1136)
#define A7 (1653) #define A7 (1653)
#define Y0 (64)
#define Y1 (1148)
#define Y2 (573)
#define Y3 (305)
#define Y4 (989)
#define Y5 (615)
#define Y6 (115)
#define Y7 (843)
#define X0 (1216) #define X0 (1216)
#define X1 (98) #define X1 (98)
#define X2 (1) #define X2 (1)
@ -58,6 +62,16 @@
#define X5 (589) #define X5 (589)
#define X6 (448) #define X6 (448)
#define X7 (777) #define X7 (777)
#define Y0 (64)
#define Y1 (1148)
#define Y2 (573)
#define Y3 (305)
#define Y4 (989)
#define Y5 (615)
#define Y6 (115)
#define Y7 (843)
#define PCL0 (1139) #define PCL0 (1139)
#define PCL1 (1022) #define PCL1 (1022)
#define PCL2 (655) #define PCL2 (655)
@ -66,6 +80,7 @@
#define PCL5 (622) #define PCL5 (622)
#define PCL6 (377) #define PCL6 (377)
#define PCL7 (1611) #define PCL7 (1611)
#define PCH0 (1670) #define PCH0 (1670)
#define PCH1 (292) #define PCH1 (292)
#define PCH2 (502) #define PCH2 (502)
@ -74,6 +89,7 @@
#define PCH5 (49) #define PCH5 (49)
#define PCH6 (1551) #define PCH6 (1551)
#define PCH7 (205) #define PCH7 (205)
#define P0 (32) #define P0 (32)
#define P1 (627) #define P1 (627)
#define P2 (1553) #define P2 (1553)
@ -81,6 +97,7 @@
#define P4 (1119) #define P4 (1119)
#define P6 (77) #define P6 (77)
#define P7 (1370) #define P7 (1370)
#define S0 (1403) #define S0 (1403)
#define S1 (183) #define S1 (183)
#define S2 (81) #define S2 (81)

160
v6502.cpp
View File

@ -1,4 +1,6 @@
#include <algorithm>
#include <utility> #include <utility>
#include <iterator>
#include <vector> #include <vector>
#include <set> #include <set>
#include <map> #include <map>
@ -8,7 +10,7 @@
#include "nodes.h" #include "nodes.h"
#define TRACE 1 //#define TRACE 1
class seg { class seg {
public: public:
@ -101,6 +103,26 @@ void pHexw(unsigned short x) {
std::cout << std::setw(4) << std::setfill('0') << std::hex << (unsigned long)x << std::dec; std::cout << std::setw(4) << std::setfill('0') << std::hex << (unsigned long)x << std::dec;
} }
void dumpSegs() {
for (int i = 0; i < segs.size(); ++i) {
std::cout << i << " ";
seg& s = segs[i];
if (s.pullup) {
std::cout << "+";
} else if (s.pulldown) {
std::cout << "-";
} else {
std::cout << "0";
}
if (s.state) {
std::cout << "+";
} else {
std::cout << "-";
}
std::cout << std::endl;
}
}
void dumpRegs() { void dumpRegs() {
std::cout << "A"; std::cout << "A";
pHex(rA()); pHex(rA());
@ -113,8 +135,26 @@ void dumpRegs() {
std::cout << " PC"; std::cout << " PC";
pHexw(rPC()); pHexw(rPC());
std::cout << " "; std::cout << " ";
std::cout << (isHigh(CLK0) ? "+" : "-"); if (isHigh(CLK1OUT)) {
std::cout << (isHigh(RW) ? "R" : "W"); std::cout << "PH1 ";
}
if (isHigh(CLK2OUT)) {
std::cout << "PH2 ";
if (isHigh(RW)) {
std::cout << "R ";
} else {
std::cout << "W ";
}
}
/*
if (isHigh(CLK2OUT) && !isHigh(RW)) {
std::cout << "W";
} else if (!isHigh(CLK2OUT) && isHigh(RW)) {
std::cout << "R";
} else {
std::cout << " ";
}
*/
std::cout << " DB"; std::cout << " DB";
pHex(rData()); pHex(rData());
std::cout << " AB"; std::cout << " AB";
@ -136,6 +176,7 @@ void onTrans(trn& t, std::set<int>& rcl) {
} }
t.on = true; t.on = true;
addRecalc(t.c1,rcl); addRecalc(t.c1,rcl);
// addRecalc(t.c2,rcl); //???
} }
void offTrans(trn& t, std::set<int>& rcl) { void offTrans(trn& t, std::set<int>& rcl) {
@ -208,22 +249,35 @@ void recalcNode(int n, std::set<int>& rcl) {
void recalc(const std::set<int>& s) { void recalc(const std::set<int>& s) {
std::set<int> list(s); std::set<int> list(s);
for (int sane = 0; sane < 1000; ++sane) { std::set<int> done;
for (int sane = 0; sane < 100; ++sane) {
//std::cout << "rc: " << list.size() << std::endl;
if (!list.size()) { if (!list.size()) {
#ifdef TRACE
dumpRegs();
#endif
return; return;
} }
std::set<int> rcl; std::set<int> rcl;
for (std::set<int>::const_iterator ilist = list.begin(); ilist != list.end(); ++ilist) { for (std::set<int>::const_iterator ilist = list.begin(); ilist != list.end(); ++ilist) {
recalcNode(*ilist,rcl); recalcNode(*ilist,rcl);
} }
//done.insert(rcl.begin(),rcl.end());
//std::set<int> v;
//std::set_difference(rcl.begin(),rcl.end(),done.begin(),done.end(),std::inserter(v,v.end()));
//list = v;
// if (std::equal(list.begin(),list.end(),rcl.begin())) {
//std::cout << "hit stasis" << std::endl;
// return;
// }
list = rcl; list = rcl;
} }
std::cerr << "ERROR: reached maximum iteration limit while recalculating CPU state" << std::endl; std::cerr << "ERROR: reached maximum iteration limit while recalculating CPU state" << std::endl;
} }
void recalc(int n) {
std::set<int> s;
s.insert(n);
recalc(s);
}
void recalcAll() { void recalcAll() {
std::set<int> s; std::set<int> s;
for (int i = 0; i < segs.size(); ++i) { for (int i = 0; i < segs.size(); ++i) {
@ -260,24 +314,30 @@ unsigned char mRead(unsigned short addr) {
case 1: x = 0x5A; break; // case 1: x = 0x5A; break; //
case 2: x = 0x85; break; // STA $88 case 2: x = 0x85; break; // STA $88
case 3: x = 0x88; break; // case 3: x = 0x88; break; //
case 4: x = 0xD0; break; // BNE 0 case 4: x = 0xA9; break; // LDA #$23
case 5: x = 0xFA; break; // case 5: x = 0x23; break; //
case 6: x = 0xD0; break; // BNE 0
case 7: x = 0xF8; break; //
} }
#ifdef TRACEMEM
std::cout << "--------------------------------------------- ";
pHex(x); pHex(x);
std::cout << "<"; std::cout << "<";
pHexw(addr); pHexw(addr);
std::cout << std::endl; std::cout << std::endl;
#endif
return x; return x;
} }
void mWrite(unsigned short addr, unsigned char data) { void mWrite(unsigned short addr, unsigned char data) {
/* TODO write data to addr in memory */ /* TODO write data to addr in memory */
#ifdef TRACEMEM
std::cout << "--------------------------------------------- ";
pHex(data); pHex(data);
std::cout << ">"; std::cout << ">";
pHexw(addr); pHexw(addr);
std::cout << std::endl; std::cout << std::endl;
#endif
} }
void putDataToChip(unsigned char data) { void putDataToChip(unsigned char data) {
@ -328,21 +388,27 @@ void addDataToRecalc(std::set<int>& s) {
s.insert(DB7); s.insert(DB7);
} }
void step() { void rw() {
readBus();
std::set<int> s; std::set<int> s;
addDataToRecalc(s);
recalc(s);
writeBus();
}
s.insert(CLK0); void step() {
if (isHigh(CLK0)) { if (isHigh(CLK0)) {
setLow(CLK0); setLow(CLK0);
readBus(); recalc(CLK0);
addDataToRecalc(s);
} else { } else {
setHigh(CLK0); setHigh(CLK0);
writeBus(); recalc(CLK0);
rw();
} }
#ifdef TRACE
dumpRegs();
#endif
recalc(s);
} }
@ -351,34 +417,42 @@ void step() {
void init() { void init() {
std::cout << "initializing CPU..." << std::endl; std::cout << "initializing CPU..." << std::endl;
std::cout << " VCC" << std::endl; //dumpSegs();
setHigh(VCC);
std::cout << " 'RESET" << std::endl;
setLow(RES);
std::cout << " 'CLK0" << std::endl;
setLow(CLK0);
std::cout << " RDY" << std::endl;
setHigh(RDY);
std::cout << " 'SO" << std::endl;
setLow(SO);
std::cout << " IRQ" << std::endl;
setHigh(IRQ);
std::cout << " NMI" << std::endl;
setHigh(NMI);
std::cout << "recalc all" << std::endl;
recalcAll(); recalcAll();
//dumpSegs();
std::cout << " [10 cycles]" << std::endl; setHigh(VCC);
for (int i(0); i < 10; ++i) { setLow(VSS);
setLow(CLK0);
setHigh(IRQ);
setLow(RES);
setHigh(NMI);
setHigh(RDY);
setLow(SO);
std::set<int> s;
s.insert(VCC);
s.insert(VSS);
s.insert(CLK0);
s.insert(IRQ);
s.insert(RES);
s.insert(NMI);
s.insert(RDY);
s.insert(SO);
recalc(s);
//dumpSegs();
// std::cout << "recalc all" << std::endl;
// recalcAll();
std::cout << " [50 cycles]" << std::endl;
for (int i(0); i < 50; ++i) {
step(); step();
} }
std::cout << " RESET" << std::endl; std::cout << " RESET" << std::endl;
setHigh(RES); setHigh(RES);
std::set<int> s; recalc(RES);
s.insert(RES);
recalc(s);
} }
@ -407,7 +481,7 @@ int main(int argc, char *argv[])
std::cout << "."; std::cout << ".";
seg s; seg s;
s.pullup = b_on; s.pullup = b_on;
s.pulldown = false; /* ??? !b_on */ s.pulldown = false;
s.state = false; s.state = false;
segs.push_back(s); segs.push_back(s);
} }
@ -457,13 +531,13 @@ int main(int argc, char *argv[])
segs[t.c1].c1c2s.push_back(i); segs[t.c1].c1c2s.push_back(i);
segs[t.c2].c1c2s.push_back(i); segs[t.c2].c1c2s.push_back(i);
} }
init(); init();
std::cerr << "running some..." << std::endl; std::cout << "running some..." << std::endl;
for (int i(0); i < 80; ++i) { for (int i(0); i < 10000; ++i) {
step(); step();
} }
std::cout << "end" << std::endl;
/*dump chip /*dump chip
for (std::map<int,seg>::iterator i = segs.begin(); i != segs.end(); ++i) { for (std::map<int,seg>::iterator i = segs.begin(); i != segs.end(); ++i) {