using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace GUI { class transistor { public string name; public bool on; public int gate; public int c1; public int c2; public List bb; } class node { public List> segs = new List>(); public int num = -1; public bool pullup = false; public bool pulldown = false; public bool state = false; public List gates = new List(); public List c1c2s = new List(); public Int64 area = 0; public bool floating = true; } class transdef { public string name; public int gate; public int c1; public int c2; public List bb; //public List unused; //public bool unused2; } public class ChipDefinitions { List _nodes = new List(); List _transistors = new List(); Dictionary _nodeNumberByName = new Dictionary(); Dictionary _nodeNameByNumber = new Dictionary(); Dictionary _transistorIndexes = new Dictionary(); List> _segmentDefs = new List>(); List _transDefs = new List(); int ngnd; int npwr; internal List> SegmentDefs { get { return _segmentDefs; } } internal List Nodes { get { return _nodes; } } internal List Transistors { get { return _transistors; } } internal Dictionary NodeNumberByName { get { return _nodeNumberByName; } } const int cpuOffset = 13000; const int cpuXOffset = 0; const int cpuYOffset = 0; const int ppuXOffset = 1500; const int ppuYOffset = 12500; Dictionary idConvertTable = new Dictionary() { { 10000 + cpuOffset, 1 }, //vcc { 10001 + cpuOffset, 2 }, //vss { 10004 + cpuOffset, 1934 }, //reset { 11669 + cpuOffset, 772 }, //cpu_clk_in -> clk0 { 1013, 11819 + cpuOffset }, //io_db0 -> cpu_db0 { 765, 11966 + cpuOffset }, //db1 { 431, 12056 + cpuOffset }, //db2 { 87, 12091 + cpuOffset }, //db3 { 11, 12090 + cpuOffset }, //db4 { 10, 12089 + cpuOffset }, //db5 { 9, 12088 + cpuOffset }, //db6 { 8, 12087 + cpuOffset }, //db7 { 12, 10020 + cpuOffset }, //io_ab0 -> cpu_ab0 { 6, 10019 + cpuOffset }, //io_ab1 -> cpu_ab1 { 7, 10030 + cpuOffset }, //io_ab2 -> cpu_ab2 { 10331 + cpuOffset, 1031 }, //nmi -> int { 10092 + cpuOffset, 1224 }, //cpu_rw -> io_rw }; public ChipDefinitions() { loadSegmentDefinitions(); loadTransistorDefinitions(); loadNodeNames(); ngnd = _nodeNumberByName["vss"]; npwr = _nodeNumberByName["vcc"]; setupNodes(); setupTransistors(); } public string getNodeName(int nn) { string name; _nodeNameByNumber.TryGetValue(nn, out name); return name ?? ""; } public int getTransistorIndex(string transName) { int index = 0; _transistorIndexes.TryGetValue(transName, out index); return index; } public HashSet getNodeGroup(int nn) { HashSet group = new HashSet(); addNodeToGroup(nn, group); return group; } void addNodeToGroup(int nn, HashSet group) { if(nn == ngnd) { return; } if(nn == npwr) { return; } if(group.Add(nn)) { foreach(transistor t in _nodes[nn].c1c2s) { if(CoreWrapper.isTransistorOn(t.name)) { addNodeToGroup(t.c1 == nn ? t.c2 : t.c1, group); } } } } int convertId(int id) { if(idConvertTable.ContainsKey(id)) { return idConvertTable[id]; } return id; } void loadSegmentDefinitions() { Action loadDefs = (filename, idOffset, xOffset, yOffset) => { foreach(string line in File.ReadAllLines(filename)) { List segmentDef = new List(); string[] values = line.Split(','); for(int i = 0; i < values.Length; i++) { if(i == 0) { segmentDef.Add(convertId(int.Parse(values[i]) + idOffset)); } else if(i > 2) { segmentDef.Add(int.Parse(values[i]) + (i % 2 == 0 ? yOffset : xOffset)); } else { segmentDef.Add(int.Parse(values[i])); } } _segmentDefs.Add(segmentDef); } }; loadDefs("segdefs.txt", 0, ppuXOffset, ppuYOffset); loadDefs("cpusegdefs.txt", cpuOffset, cpuXOffset, cpuYOffset); } void loadTransistorDefinitions() { Action loadDefs = (filename, namePrefix, idOffset, xOffset, yOffset) => { foreach(string line in File.ReadAllLines(filename)) { if(line.StartsWith("#")) { continue; } string[] values = line.Split(','); string[] bbValues = values[4].Split('|'); List bb = new List(); for(int i = 0; i < 4; i++) { bb.Add(int.Parse(bbValues[i]) + (i < 2 ? xOffset : yOffset)); } _transDefs.Add(new transdef() { name = namePrefix + values[0], gate = convertId(int.Parse(values[1]) + idOffset), c1 = convertId(int.Parse(values[2]) + idOffset), c2 = convertId(int.Parse(values[3]) + idOffset), bb = bb }); } }; loadDefs("transdefs.txt", "", 0, ppuXOffset, ppuYOffset); loadDefs("cputransdefs.txt", "cpu_", cpuOffset, cpuXOffset, cpuYOffset); } void loadNodeNames() { Action loadDefs = (filename, namePrefix, idOffset) => { foreach(string line in File.ReadAllLines(filename)) { string[] values = line.Split(','); _nodeNumberByName[namePrefix + values[0]] = int.Parse(values[1]) + idOffset; _nodeNameByNumber[int.Parse(values[1]) + idOffset] = namePrefix + values[0]; } }; loadDefs("nodenames.txt", "", 0); loadDefs("cpunodenames.txt", "cpu_", cpuOffset); } void setupNodes() { int maxID = 0; for(int i = 0, len = _segmentDefs.Count; i < len; i++) { maxID = Math.Max(maxID, _segmentDefs[i][0]); } for(int i = 0; i <= maxID; i++) { _nodes.Add(null); } for(int i = 0, len = _segmentDefs.Count; i < len; i++) { List segmentDef = _segmentDefs[i]; int w = segmentDef[0]; if(_nodes[w] == null) { _nodes[w] = new node(); _nodes[w].num = w; _nodes[w].pullup = segmentDef[1] == 1; _nodes[w].state = false; _nodes[w].area = 0; _nodes[w].segs = new List>(); } if(w == ngnd) continue; if(w == npwr) continue; int area = segmentDef[segmentDef.Count - 2] * segmentDef[4] - segmentDef[3] * segmentDef[segmentDef.Count - 1]; for(int j = 3; j + 4 < segmentDef.Count; j += 2) { area += segmentDef[j] * segmentDef[j + 3] - segmentDef[j + 2] * segmentDef[j - 1]; } if(area < 0) { area = -area; } _nodes[w].area += area; _nodes[w].segs.Add(segmentDef.GetRange(3, segmentDef.Count - 3)); } } void setupTransistors() { int i = 0; foreach(transdef tdef in _transDefs) { string name = tdef.name; int gate = tdef.gate; int c1 = tdef.c1; int c2 = tdef.c2; if(c1 == ngnd) { c1 = c2; c2 = ngnd; } if(c1 == npwr) { c1 = c2; c2 = npwr; } transistor trans = new transistor { name = name, on = false, gate = gate, c1 = c1, c2 = c2, bb = tdef.bb }; _nodes[gate].gates.Add(trans); _nodes[c1].c1c2s.Add(trans); _nodes[c2].c1c2s.Add(trans); _transistorIndexes[name] = i; _transistors.Add(trans); i++; } } } }