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 RW (1156)
#define NMI (1297)
#define RDY (89)
#define SO (1672)
/* data bus (I/O) */
#define DB0 (1005)
#define DB1 (82)
#define DB3 (650)
@ -8,6 +19,8 @@
#define DB4 (1393)
#define DB7 (1349)
#define DB6 (1591)
/* address bus (output) */
#define AB0 (268)
#define AB1 (451)
#define AB2 (1340)
@ -24,16 +37,14 @@
#define AB11 (399)
#define AB14 (672)
#define AB15 (195)
/* outputs */
#define RW (1156)
#define SYNC (539)
#define SO (1672)
#define CLK0 (1171)
#define CLK1OUT (1163)
#define CLK2OUT (421)
#define RDY (89)
#define NMI (1297)
#define IRQ (103)
#define VCC (657)
#define VSS (558)
/* internal registers */
#define A0 (737)
#define A1 (1234)
#define A2 (978)
@ -42,14 +53,7 @@
#define A5 (858)
#define A6 (1136)
#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 X1 (98)
#define X2 (1)
@ -58,6 +62,16 @@
#define X5 (589)
#define X6 (448)
#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 PCL1 (1022)
#define PCL2 (655)
@ -66,6 +80,7 @@
#define PCL5 (622)
#define PCL6 (377)
#define PCL7 (1611)
#define PCH0 (1670)
#define PCH1 (292)
#define PCH2 (502)
@ -74,6 +89,7 @@
#define PCH5 (49)
#define PCH6 (1551)
#define PCH7 (205)
#define P0 (32)
#define P1 (627)
#define P2 (1553)
@ -81,6 +97,7 @@
#define P4 (1119)
#define P6 (77)
#define P7 (1370)
#define S0 (1403)
#define S1 (183)
#define S2 (81)

160
v6502.cpp
View File

@ -1,4 +1,6 @@
#include <algorithm>
#include <utility>
#include <iterator>
#include <vector>
#include <set>
#include <map>
@ -8,7 +10,7 @@
#include "nodes.h"
#define TRACE 1
//#define TRACE 1
class seg {
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;
}
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() {
std::cout << "A";
pHex(rA());
@ -113,8 +135,26 @@ void dumpRegs() {
std::cout << " PC";
pHexw(rPC());
std::cout << " ";
std::cout << (isHigh(CLK0) ? "+" : "-");
std::cout << (isHigh(RW) ? "R" : "W");
if (isHigh(CLK1OUT)) {
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";
pHex(rData());
std::cout << " AB";
@ -136,6 +176,7 @@ void onTrans(trn& t, std::set<int>& rcl) {
}
t.on = true;
addRecalc(t.c1,rcl);
// addRecalc(t.c2,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) {
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()) {
#ifdef TRACE
dumpRegs();
#endif
return;
}
std::set<int> rcl;
for (std::set<int>::const_iterator ilist = list.begin(); ilist != list.end(); ++ilist) {
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;
}
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() {
std::set<int> s;
for (int i = 0; i < segs.size(); ++i) {
@ -260,24 +314,30 @@ unsigned char mRead(unsigned short addr) {
case 1: x = 0x5A; break; //
case 2: x = 0x85; break; // STA $88
case 3: x = 0x88; break; //
case 4: x = 0xD0; break; // BNE 0
case 5: x = 0xFA; break; //
case 4: x = 0xA9; break; // LDA #$23
case 5: x = 0x23; break; //
case 6: x = 0xD0; break; // BNE 0
case 7: x = 0xF8; break; //
}
#ifdef TRACEMEM
std::cout << "--------------------------------------------- ";
pHex(x);
std::cout << "<";
pHexw(addr);
std::cout << std::endl;
#endif
return x;
}
void mWrite(unsigned short addr, unsigned char data) {
/* TODO write data to addr in memory */
#ifdef TRACEMEM
std::cout << "--------------------------------------------- ";
pHex(data);
std::cout << ">";
pHexw(addr);
std::cout << std::endl;
#endif
}
void putDataToChip(unsigned char data) {
@ -328,21 +388,27 @@ void addDataToRecalc(std::set<int>& s) {
s.insert(DB7);
}
void step() {
void rw() {
readBus();
std::set<int> s;
addDataToRecalc(s);
recalc(s);
writeBus();
}
s.insert(CLK0);
void step() {
if (isHigh(CLK0)) {
setLow(CLK0);
readBus();
addDataToRecalc(s);
recalc(CLK0);
} else {
setHigh(CLK0);
writeBus();
recalc(CLK0);
rw();
}
#ifdef TRACE
dumpRegs();
#endif
recalc(s);
}
@ -351,34 +417,42 @@ void step() {
void init() {
std::cout << "initializing CPU..." << std::endl;
std::cout << " VCC" << std::endl;
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;
//dumpSegs();
recalcAll();
//dumpSegs();
std::cout << " [10 cycles]" << std::endl;
for (int i(0); i < 10; ++i) {
setHigh(VCC);
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();
}
std::cout << " RESET" << std::endl;
setHigh(RES);
std::set<int> s;
s.insert(RES);
recalc(s);
recalc(RES);
}
@ -407,7 +481,7 @@ int main(int argc, char *argv[])
std::cout << ".";
seg s;
s.pullup = b_on;
s.pulldown = false; /* ??? !b_on */
s.pulldown = false;
s.state = false;
segs.push_back(s);
}
@ -457,13 +531,13 @@ int main(int argc, char *argv[])
segs[t.c1].c1c2s.push_back(i);
segs[t.c2].c1c2s.push_back(i);
}
init();
std::cerr << "running some..." << std::endl;
for (int i(0); i < 80; ++i) {
std::cout << "running some..." << std::endl;
for (int i(0); i < 10000; ++i) {
step();
}
std::cout << "end" << std::endl;
/*dump chip
for (std::map<int,seg>::iterator i = segs.begin(); i != segs.end(); ++i) {