Initial commit (C++ port of Visual 2C02)

This commit is contained in:
Souryo 2017-01-02 16:38:16 -05:00
commit dd133ff3f6
19 changed files with 55933 additions and 0 deletions

168
.gitignore vendored Normal file
View file

@ -0,0 +1,168 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
[Oo]bj.x86/
[Oo]bj.x64/
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac desktop service store files
.DS_Store
*.nes
*.sav
*.svs
*.trt
*.rar
*.VC.opendb
*.VC.db
out.txt

28
Visual2C02.sln Normal file
View file

@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Visual2C02", "Visual2C02\Visual2C02.vcxproj", "{484A59BB-63D7-4F4A-925C-9F82B106D575}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{484A59BB-63D7-4F4A-925C-9F82B106D575}.Debug|x64.ActiveCfg = Debug|x64
{484A59BB-63D7-4F4A-925C-9F82B106D575}.Debug|x64.Build.0 = Debug|x64
{484A59BB-63D7-4F4A-925C-9F82B106D575}.Debug|x86.ActiveCfg = Debug|Win32
{484A59BB-63D7-4F4A-925C-9F82B106D575}.Debug|x86.Build.0 = Debug|Win32
{484A59BB-63D7-4F4A-925C-9F82B106D575}.Release|x64.ActiveCfg = Release|x64
{484A59BB-63D7-4F4A-925C-9F82B106D575}.Release|x64.Build.0 = Release|x64
{484A59BB-63D7-4F4A-925C-9F82B106D575}.Release|x86.ActiveCfg = Release|Win32
{484A59BB-63D7-4F4A-925C-9F82B106D575}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{484A59BB-63D7-4F4A-925C-9F82B106D575}</ProjectGuid>
<RootNamespace>Visual2C02</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<PrecompiledHeader>Use</PrecompiledHeader>
<BasicRuntimeChecks />
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<PrecompiledHeader>Use</PrecompiledHeader>
<BasicRuntimeChecks />
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<PrecompiledHeader>Use</PrecompiledHeader>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<StringPooling>true</StringPooling>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<DisableLanguageExtensions>true</DisableLanguageExtensions>
<PrecompiledHeader>Use</PrecompiledHeader>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<StringPooling>true</StringPooling>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="chipsim.h" />
<ClInclude Include="datadefs.h" />
<ClInclude Include="datastructures.h" />
<ClInclude Include="macros.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="wires.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="macros.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="datadefs.cpp" />
<ClCompile Include="chipsim.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="wires.cpp" />
</ItemGroup>
<ItemGroup>
<Text Include="nodenames.txt">
<DeploymentContent>false</DeploymentContent>
</Text>
<Text Include="segdefs.txt" />
<Text Include="transdefs.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="datastructures.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="datadefs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="wires.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="chipsim.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="macros.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="chipsim.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="wires.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="datadefs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="macros.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="nodenames.txt">
<Filter>Resource Files</Filter>
</Text>
<Text Include="segdefs.txt">
<Filter>Resource Files</Filter>
</Text>
<Text Include="transdefs.txt">
<Filter>Resource Files</Filter>
</Text>
</ItemGroup>
</Project>

272
Visual2C02/chipsim.cpp Normal file
View file

@ -0,0 +1,272 @@
/*
Copyright (c) 2010 Brian Silverman, Barry Silverman
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "stdafx.h"
#include <iostream>
#include "datastructures.h"
#include "chipsim.h"
extern vector<node> nodes;
extern unordered_map<string, shared_ptr<transistor>> transistors;
//extern unordered_map<int, string> nodenameByNumber;
extern unordered_map<string, int> nodenames;
extern int ngnd;
extern int npwr;
vector<int> processesNodes;
shared_ptr<vector<int>> recalclists[2];
shared_ptr<vector<int>> recalclist;
vector<int> group;
bool groupEmpty = true;
bool hasGnd = false;
bool hasPwr = false;
void recalcNodeList(shared_ptr<vector<int>> list) {
//var n = list[0];
if(processesNodes.empty()) {
processesNodes.insert(processesNodes.end(), nodes.size(), 0);
recalclists[0].reset(new vector<int>(100));
recalclists[1].reset(new vector<int>(100));
} else {
memset(processesNodes.data(), 0, processesNodes.size() * sizeof(int));
recalclists[0]->clear();
recalclists[1]->clear();
}
recalclist = recalclists[0];
for(int j = 0; j<100; j++) { // loop limiter
if(j == 99) {
throw std::runtime_error("Maximum loop exceeded");
//console.log('Encountered loop!');
}
/*if(ctrace) {
var i;
for(i = 0; i<traceTheseNodes.length; i++) {
if(list.indexOf(traceTheseNodes[i]) != -1) break;
}
if((traceTheseNodes.length == 0) || (list.indexOf(traceTheseNodes[i]) == -1)) {
console.log('recalcNodeList iteration: ', j, ' ', list.length, ' nodes');
} else {
console.log('recalcNodeList iteration: ', j, ' ', list.length, ' nodes ', list);
}
}*/
for(int nodeNumber : *list) {
recalcNode(nodeNumber);
}
if(groupEmpty) return;
for(int nodeNumber : *recalclist) {
processesNodes[nodeNumber] = 0;
}
list = recalclist;
recalclist = (recalclist == recalclists[1]) ? recalclists[0] : recalclists[1];
recalclist->clear();
groupEmpty = true;
}
//if(ctrace) console.log(n, ' looping...');
}
void recalcNode(int nodeNumber) {
if(nodeNumber == ngnd) return;
if(nodeNumber == npwr) return;
getNodeGroup(nodeNumber);
bool newState = getNodeValue();
/*if(ctrace) {
var i;
for(i = 0; i<group.length; i++) {
if(traceTheseNodes.indexOf(group[i]) != -1) break;
}
if((traceTheseNodes.indexOf(node) != -1) || (i != group.length))
console.log('recalc ', node, ' ', group, ' to ', newState);
}*/
for(int nn : group) {
node& n = nodes[nn];
if(n.state != newState) {
n.state = newState;
for(shared_ptr<transistor> &t : n.gates) {
if(n.state) turnTransistorOn(*t);
else turnTransistorOff(*t);
}
}
}
}
void turnTransistorOn(transistor &t) {
if(t.on) return;
/*if(ctrace && ((traceTheseTransistors.indexOf(t.name) != -1) || (traceTheseNodes.indexOf(t.c1) != -1) || (traceTheseNodes.indexOf(t.c2) != -1)))
console.log(t.name, ' on ', t.gate, ' ', t.c1, ' ', t.c2);*/
t.on = true;
addRecalcNode(t.c1);
}
void turnTransistorOff(transistor &t) {
if(!t.on) return;
/*if(ctrace && ((traceTheseTransistors.indexOf(t.name) != -1) || (traceTheseNodes.indexOf(t.c1) != -1) || (traceTheseNodes.indexOf(t.c2) != -1)))
console.log(t.name, ' off ', t.gate, ' ', t.c1, ' ', t.c2);*/
t.on = false;
addRecalcNode(t.c1);
addRecalcNode(t.c2);
}
void addRecalcNode(int nn) {
if(nn == ngnd) return;
if(nn == npwr) return;
if(!processesNodes[nn]) {
recalclist->push_back(nn);
processesNodes[nn] = 1;
}
groupEmpty = false;
}
void getNodeGroup(int i) {
hasGnd = false;
hasPwr = false;
group.clear();
addNodeToGroup(i);
}
void addNodeToGroup(int i) {
if(i == ngnd) {
hasGnd = true;
return;
}
if(i == npwr) {
hasPwr = true;
return;
}
if(find(group.begin(), group.end(), i) != group.end()) return;
group.push_back(i);
for(shared_ptr<transistor> &t : nodes[i].c1c2s) {
if(t->on) {
addNodeToGroup(t->c1 == i ? t->c2 : t->c1);
}
}
}
bool getNodeValue() {
if(hasGnd && hasPwr) {
for(int i : group) {
if(i == 359 || i == 566 || i == 691 || i == 871 || i == 870 || i == 864 || i == 856 || i == 818) {
hasGnd = hasPwr = false;
break;
}
}
}
if(hasGnd) {
return false;
} else if(hasPwr) {
return true;
}
int hi_area = 0;
int lo_area = 0;
for(int nn : group) {
node &n = nodes[nn];
if(n.pullup) return true;
if(n.pulldown) return false;
if(n.state) hi_area += n.area;
else lo_area += n.area;
}
return (hi_area > lo_area);
}
bool isNodeHigh(int nn) {
return(nodes[nn].state);
}
/*
void saveString(name, str) {
var request = new XMLHttpRequest();
request.onreadystatechange = function() {};
request.open('PUT', 'save.php?name=' + name, true);
request.setRequestHeader('Content-Type', 'text/plain');
request.send(str);
}*/
shared_ptr<vector<int>> allNodes() {
shared_ptr<vector<int>> result(new vector<int>());
for(node& node : nodes) {
if(node.num != npwr && node.num != ngnd && node.num >= 0) {
result->push_back(node.num);
}
}
return result;
}
string getState() {
char codes[2] = { 'l', 'h' };
string res;
for(node& n : nodes) {
if(n.num < 0) res += 'x';
else if(n.num == ngnd) res += 'g';
else if(n.num == npwr) res += 'v';
else res += codes[n.state ? 1 : 0];
}
return res;
}
void setState(string str) {
unordered_map<char, bool> codes = { {'g', false}, {'h', true}, {'v',true}, {'l', false } };
for(size_t i = 0; i < str.size(); i++) {
char c = str[i];
if(c == 'x') continue;
bool state = codes[c];
if(nodes[i].num < 0) continue;
nodes[i].state = state;
for(shared_ptr<transistor> &t : nodes[i].gates) {
t->on = state;
}
}
}
void setFloat(string name) {
int nn = nodenames[name];
nodes[nn].pullup = false;
nodes[nn].pulldown = false;
recalcNodeList(shared_ptr<vector<int>>(new vector<int> { nn }));
}
void setHigh(string name) {
int nn = nodenames[name];
nodes[nn].pullup = true;
nodes[nn].pulldown = false;
recalcNodeList(shared_ptr<vector<int>>(new vector<int>{ nn }));
}
void setLow(string name) {
int nn = nodenames[name];
nodes[nn].pullup = false;
nodes[nn].pulldown = true;
recalcNodeList(shared_ptr<vector<int>>(new vector<int>{ nn }));
}
//function arrayContains(arr, el) { return arr.indexOf(el) != -1; }

18
Visual2C02/chipsim.h Normal file
View file

@ -0,0 +1,18 @@
#pragma once
#include "datastructures.h"
void recalcNodeList(shared_ptr<vector<int>> list);
void recalcNode(int nodeNumber);
void turnTransistorOn(transistor &t);
void turnTransistorOff(transistor &t);
void addRecalcNode(int nn);
void getNodeGroup(int i);
void addNodeToGroup(int i);
bool getNodeValue();
bool isNodeHigh(int nn);
string getState();
void setState(string str);
void setFloat(string name);
void setHigh(string name);
void setLow(string name);
shared_ptr<vector<int>> allNodes();

93
Visual2C02/datadefs.cpp Normal file
View file

@ -0,0 +1,93 @@
#include "stdafx.h"
#include "datastructures.h"
#include "datadefs.h"
vector<vector<int>> segdefs;
vector<transdef> transdefs;
unordered_map<string, int> nodenames;
vector<string> split(const string &s, char delim)
{
vector<string> tokens;
std::stringstream ss(s);
std::string item;
while(std::getline(ss, item, delim)) {
tokens.push_back(item);
}
return tokens;
}
void loadSegmentDefinitions()
{
ifstream file("../Visual2C02/segdefs.txt", ios::in | ios::binary);
while(file.good()) {
string lineContent;
std::getline(file, lineContent);
if(lineContent.empty()) {
continue;
}
vector<string> values = split(lineContent, ',');
vector<int> segDef;
for(string value : values) {
segDef.push_back(std::stoi(value));
}
segdefs.push_back(segDef);
}
}
void loadTransistorDefinitions()
{
ifstream file("../Visual2C02/transdefs.txt", ios::in | ios::binary);
while(file.good()) {
string lineContent;
std::getline(file, lineContent);
if(lineContent.empty()) {
continue;
}
vector<string> values = split(lineContent, ',');
vector<string> bbValues = split(values[4], '|');
vector<int> bb;
for(string value : bbValues) {
bb.push_back(std::stoi(value));
}
transdef def = {
values[0],
std::stoi(values[1]),
std::stoi(values[2]),
std::stoi(values[3]),
bb,
{},
false
};
transdefs.push_back(def);
}
}
void loadNodeNames()
{
ifstream file("../Visual2C02/nodenames.txt", ios::in | ios::binary);
while(file.good()) {
string lineContent;
std::getline(file, lineContent);
if(lineContent.empty()) {
continue;
}
vector<string> values = split(lineContent, ',');
nodenames[values[0]] = stoi(values[1]);
}
}
void loadDataDefinitions()
{
loadSegmentDefinitions();
loadTransistorDefinitions();
loadNodeNames();
}

8
Visual2C02/datadefs.h Normal file
View file

@ -0,0 +1,8 @@
#pragma once
#include "datastructures.h"
extern vector<vector<int>> segdefs;
extern vector<transdef> transdefs;
extern unordered_map<string, int> nodenames;
void loadDataDefinitions();

View file

@ -0,0 +1,36 @@
#pragma once
#include "stdafx.h"
struct transdef
{
string name;
int gate;
int c1;
int c2;
vector<int> bb;
vector<int> unused;
bool unused2;
};
struct transistor
{
string name;
bool on;
int gate;
int c1;
int c2;
vector<int> bb;
};
struct node
{
vector<int> segs;
int num = -1;
bool pullup = false;
bool pulldown = false;
bool state = false;
vector<shared_ptr<transistor>> gates;
vector<shared_ptr<transistor>> c1c2s;
int area = 0;
bool floating = true;
};

279
Visual2C02/macros.cpp Normal file
View file

@ -0,0 +1,279 @@
#pragma once
#include "stdafx.h"
#include "datastructures.h"
#include "wires.h"
#include "chipsim.h"
#include "macros.h"
string nodenamereset = "res";
extern std::unordered_map<std::string, int> nodenames;
uint8_t memory[0xFFFF];
std::unordered_map<string, bool> chrStatus;
int lastAddress = 0;
int lastData = 0;
int chrAddress = 0;
int cycle = 0;
int ioParms = 0;
int ioCounter = 0;
int testprogramAddress = 0;
vector<uint16_t> testprogram = {
0x2000, // $00 -> $2000
0x2100, // $00 -> $2001
0x2300, // $00 -> $2003, sprite DMA follows
0x3200, // read $2002
0x2500, // $00 -> $2005
0x2500, // $00 -> $2005
0x2090, // $90 -> $2000
0x211E, // $1E -> $2001
0x00FF, // terminator
};
void initChip()
{
memset(memory, 0, 0xFFFF);
for(node &n : nodes) {
n.state = false;
n.floating = true;
}
nodes[ngnd].state = false;
nodes[ngnd].floating = false;
nodes[npwr].state = true;
nodes[npwr].floating = false;
for(auto kvp : transistors) {
kvp.second->on = (kvp.second->gate == npwr);
}
setLow(nodenamereset);
setLow("clk0");
setHigh("io_ce");
setHigh("int");
recalcNodeList(allNodes());
for(int i = 0; i < 4; i++) {
setHigh("clk0");
setLow("clk0");
}
setHigh(nodenamereset);
cycle = 0;
testprogramAddress = 0;
ioCounter = 0;
handleIoBus(); // to get it properly synchronized
chrAddress = 0;
chrStatus["rd"] = 1;
chrStatus["wr"] = 1;
chrStatus["ale"] = 0;
}
void halfStep()
{
bool clk = isNodeHigh(nodenames["clk0"]);
//eval(clockTriggers[cycle]);
handleIoBus();
if(clk) {
setLow("clk0");
} else {
setHigh("clk0");
}
handleChrBus();
}
void step()
{
halfStep();
cycle++;
}
int readBit(string name) {
return isNodeHigh(nodenames[name]) ? 1 : 0;
}
unordered_map<string, vector<int>> nodeNumberCache;
unordered_map<string, int> bitCountCache;
vector<string> numbers = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31" };
int readBits(string name, int n = 0) {
if(name.compare("cycle") == 0) {
return cycle;
}
int res = 0;
if(n == 0) {
if(name[name.size() - 1] >= '0' && name[name.size() - 1] <= '9') {
return readBit(name);
} else {
auto result = bitCountCache.find(name);
if(result == bitCountCache.end()) {
nodeNumberCache[name] = vector<int>();
while(nodenames.find(name + numbers[n]) != nodenames.end()) {
nodeNumberCache[name].push_back(nodenames[name + numbers[n]]);
n++;
};
bitCountCache[name] = n;
if(n == 0 && nodenames.find(name) != nodenames.end()) {
bitCountCache[name] = 1;
}
} else {
n = result->second;
}
if(n == 1) {
return readBit(name);
}
}
int i = 0;
for(int nn : nodeNumberCache[name]) {
res += ((isNodeHigh(nn)) ? 1 : 0) << i;
i++;
}
} else {
for(int i = 0; i<n; i++) {
int nn = nodenames[name + numbers[i]];
res += ((isNodeHigh(nn)) ? 1 : 0) << i;
}
}
return res;
}
void writeBit(string name, int x) {
if(x) {
setHigh(name);
} else {
setLow(name);
}
}
void writeBits(string name, int n, int x) {
shared_ptr<vector<int>> recalcs(new vector<int>());
for(int i = 0; i<n; i++) {
int nn = nodenames[name + std::to_string(i)];
if((x % 2) == 0) {
nodes[nn].pulldown = true;
nodes[nn].pullup = false;
} else {
nodes[nn].pulldown = false;
nodes[nn].pullup = true;
}
recalcs->push_back(nn);
x >>= 1;
}
recalcNodeList(recalcs);
}
void floatBits(string name, int n) {
shared_ptr<vector<int>> recalcs(new vector<int>());
for(int i = 0; i<n; i++) {
int nn = nodenames[name + std::to_string(i)];
nodes[nn].pulldown = false;
nodes[nn].pullup = false;
recalcs->push_back(nn);
}
recalcNodeList(recalcs);
}
int readAddressBus() {
if(isNodeHigh(nodenames["ale"])) {
lastAddress = readBits("ab", 14);
}
return lastAddress;
}
int readDataBus() {
if(!isNodeHigh(nodenames["rd"]) || !isNodeHigh(nodenames["wr"])) {
lastData = readBits("db", 8);
}
return lastData;
}
uint8_t mRead(int a) {
return memory[a];
}
void mWrite(int a, int d) {
//vram_setCellValue(a, d);
// mirror all writes
for(int i = 0; i < 8; i++) {
memory[(a & 0x23FF) | (0x400 * i)] = d;
}
}
void handleChrBus() {
std::unordered_map<string, bool> newStatus;
newStatus["ale"] = isNodeHigh(nodenames["ale"]);
newStatus["rd"] = isNodeHigh(nodenames["rd"]);
newStatus["wr"] = isNodeHigh(nodenames["wr"]);
// rising edge of ALE
if(!chrStatus["ale"] && newStatus["ale"]) {
chrAddress = readAddressBus();
}
// falling edge of /RD - put bits on bus
if(chrStatus["rd"] && !newStatus["rd"]) {
int a = chrAddress;
/*var d = eval(readTriggers[a]);*/
//if(d == undefined) {
uint8_t d = mRead(a);
writeBits("db", 8, d);
}
// rising edge of /RD - float the data bus
if(!chrStatus["rd"] && newStatus["rd"]) {
floatBits("db", 8);
}
// rising edge of /WR - store data in RAM
if(!chrStatus["wr"] && newStatus["wr"]) {
int a = chrAddress;
int d = readDataBus();
//eval(writeTriggers[a]);
mWrite(a, d);
}
chrStatus = newStatus;
}
void handleIoBus() {
if((ioCounter == 0) && (testprogramAddress < testprogram.size())) {
//cmd_highlightCurrent();
ioParms = testprogram[testprogramAddress];
if(ioParms & 0x3000)
ioCounter = 24;
else {
ioCounter = ioParms & 0x7FF;
floatBits("io_db", 8);
}
}
if(ioCounter > 0) {
int ce = (ioParms & 0x2000) >> 13;
int rw = (ioParms & 0x1000) >> 12;
int a = (ioParms & 0x700) >> 8;
int d = (ioParms & 0xFF);
if((ioCounter == 24) && ce) {
writeBits("io_ab", 3, a);
if(rw) {
floatBits("io_db", 8);
} else {
writeBits("io_db", 8, d);
}
writeBit("io_rw", rw);
}
if((ioCounter == 16) && ce) {
setLow("io_ce");
}
if(ioCounter == 1) {
if(rw) {
d = readBits("io_db", 8);
// store result in the test program
//cmd_setCellValue(testprogramAddress * 8 + 5, d);
}
setHigh("io_ce");
}
ioCounter--;
if(ioCounter == 0)
testprogramAddress++;
}
}

17
Visual2C02/macros.h Normal file
View file

@ -0,0 +1,17 @@
#pragma once
#include "stdafx.h"
void initChip();
void halfStep();
void step();
int readBit(string name);
int readBits(string name, int n);
void writeBits(string name, int n, int x);
void writeBit(string name, int x);
void floatBits(string name, int n);
int readAddressBus();
int readDataBus();
uint8_t mRead(int a);
void mWrite(int a, int d);
void handleChrBus();
void handleIoBus();

62
Visual2C02/main.cpp Normal file
View file

@ -0,0 +1,62 @@
#include "stdafx.h"
#include <iostream>
#include "datadefs.h"
#include "macros.h"
#include "wires.h"
#include <thread>
std::thread loggingThread;
ofstream out("out.txt", ios::out | ios::binary);
void log(vector<string> logVars, vector<int> logBuffer)
{
if(loggingThread.joinable()) {
loggingThread.join();
}
loggingThread = std::thread([=]() {
int i = 0;
for(int val : logBuffer) {
out << logVars[i] + ": " + std::to_string(val) + " ";
i = (i + 1) % logVars.size();
if(i == 0) {
out << "\r\n";
}
}
});
}
int main()
{
loadDataDefinitions();
initDataStructures();
initChip();
int prevPos = -1;
vector<string> logVars = { "cycle" ,"hpos", "vpos", "vbl_flag", "vramaddr_t", "vramaddr_v", "io_db", "io_ab", "io_rw", "io_ce", "rd", "wr", "ab", "ale", "db" };
vector<int> logBuffer;
for(int i = 0; i < 10000000; i++) {
step();
for(size_t j = 0; j < logVars.size(); j++) {
logBuffer.push_back(readBits(logVars[j], 0));
}
if(i % 2728 == 0) {
int vpos = readBits("vpos", 0);
int hpos = readBits("hpos", 0);
int cycle = readBits("cycle", 0);
std::cout << "cyc: " << std::to_string(cycle) << " hpos: " << std::to_string(hpos) << " vpos: " << std::to_string(vpos);
}
if(i % 10000 == 0) {
log(logVars, logBuffer);
logBuffer.clear();
}
}
log(logVars, logBuffer);
loggingThread.join();
out.close();
return 0;
}

1983
Visual2C02/nodenames.txt Normal file

File diff suppressed because it is too large Load diff

35615
Visual2C02/segdefs.txt Normal file

File diff suppressed because one or more lines are too long

1
Visual2C02/stdafx.cpp Normal file
View file

@ -0,0 +1 @@
#include "stdafx.h"

18
Visual2C02/stdafx.h Normal file
View file

@ -0,0 +1,18 @@
#pragma once
#include <string>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <memory>
#include <algorithm>
#include <fstream>
#include <sstream>
using std::vector;
using std::string;
using std::ios;
using std::shared_ptr;
using std::unordered_map;
using std::unordered_set;
using std::ifstream;
using std::ofstream;

16758
Visual2C02/transdefs.txt Normal file

File diff suppressed because it is too large Load diff

333
Visual2C02/wires.cpp Normal file
View file

@ -0,0 +1,333 @@
/*
Copyright (c) 2010 Brian Silverman, Barry Silverman
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "stdafx.h"
#include "datastructures.h"
#include "wires.h"
extern std::vector<std::vector<int>> segdefs;
extern std::vector<transdef> transdefs;
extern std::unordered_map<std::string, int> nodenames;
vector<node> nodes;
unordered_map<string, shared_ptr<transistor>> transistors;
unordered_map<int, std::string> nodenameByNumber;
int ngnd;
int npwr;
void setupNodes()
{
int maxID = 0;
for(size_t i = 0, len = segdefs.size(); i < len; i++) {
maxID = std::max(maxID, segdefs[i][0]);
}
nodes.insert(nodes.end(), maxID + 1, node());
for(size_t i = 0, len = segdefs.size(); i < len; i++) {
std::vector<int> &seg = segdefs[i];
int segmentID = seg[0];
}
for(size_t i = 0, len = segdefs.size(); i < len; i++) {
std::vector<int> &seg = segdefs[i];
int w = seg[0];
if(nodes[w].num == -1) {
nodes[w].num = w;
nodes[w].pullup = seg[1] == 1;
nodes[w].state = false;
nodes[w].area = 0;
}
if(w == ngnd) continue;
if(w == npwr) continue;
int area = seg[seg.size() - 2] * seg[4] - seg[3] * seg[seg.size() - 1];
for(size_t j = 3; j + 4 < seg.size(); j += 2) {
area += seg[j] * seg[j + 3] - seg[j + 2] * seg[j - 1];
}
if(area < 0) {
area = -area;
}
nodes[w].area += area;
nodes[w].segs.insert(nodes[w].segs.end(), &seg[3], &seg[seg.size()-1]);
}
}
void setupTransistors()
{
for(transdef &tdef : transdefs) {
std::string name = tdef.name;
int gate = tdef.gate;
int c1 = tdef.c1;
int c2 = tdef.c2;
std::vector<int> bb = tdef.bb;
if(c1 == ngnd) { c1 = c2; c2 = ngnd; }
if(c1 == npwr) { c1 = c2; c2 = npwr; }
shared_ptr<transistor> trans = shared_ptr<transistor>(new transistor { name, false, gate, c1, c2, bb });
nodes[gate].gates.push_back(trans);
nodes[c1].c1c2s.push_back(trans);
nodes[c2].c1c2s.push_back(trans);
transistors[name] = trans;
}
}
void setupNodeNameList()
{
for(auto kvp : nodenames) {
nodenameByNumber[kvp.second] = kvp.first;
}
}
std::string nodeName(int nodeNumber) {
auto result = nodenameByNumber.find(nodeNumber);
if(result != nodenameByNumber.end()) {
return result->second;
}
return "";
}
void initDataStructures()
{
ngnd = nodenames["vss"];
npwr = nodenames["vcc"];
setupNodes();
setupTransistors();
setupNodeNameList();
}
//var frame, chipbg, overlay, hilite, hitbuffer, ctx;
//var chipLayoutIsVisible = true; // only modified in expert mode
//var hilited = [];
/*
function setupLayerVisibility() {
var x = document.getElementById('updateShow');
for(var i = 0; i<x.childNodes.length; i++) {
if(x.childNodes[i].type == 'checkbox') {
x.childNodes[i].checked = drawlayers[x.childNodes[i].name];
}
}
}
function setupBackground() {
chipbg = document.getElementById('chipbg');
chipbg.width = grCanvasSize;
chipbg.height = grCanvasSize;
var ctx = chipbg.getContext('2d');
ctx.fillStyle = '#000000';
ctx.strokeStyle = 'rgba(255,255,255,0.5)';
ctx.lineWidth = grLineWidth;
ctx.fillRect(0, 0, grCanvasSize, grCanvasSize);
for(var i in segdefs) {
var seg = segdefs[i];
var c = seg[2];
if(drawlayers[c]) {
ctx.fillStyle = colors[c];
drawSeg(ctx, segdefs[i].slice(3));
ctx.fill();
if((c == 0) || (c == 6)) ctx.stroke();
}
}
}
function setupOverlay() {
overlay = document.getElementById('overlay');
overlay.width = grCanvasSize;
overlay.height = grCanvasSize;
ctx = overlay.getContext('2d');
}
function setupHilite() {
hilite = document.getElementById('hilite');
hilite.width = grCanvasSize;
hilite.height = grCanvasSize;
var ctx = hilite.getContext('2d');
}
function setupHitBuffer() {
hitbuffer = document.getElementById('hitbuffer');
hitbuffer.width = grCanvasSize;
hitbuffer.height = grCanvasSize;
hitbuffer.style.visibility = 'hidden';
var ctx = hitbuffer.getContext('2d');
ctx.fillStyle = '#FFFFFF';
ctx.fillRect(0, 0, grCanvasSize, grCanvasSize);
for(i in nodes) hitBufferNode(ctx, nodes[i].num, nodes[i].segs);
}
function hitBufferNode(ctx, i, w) {
var low = ((i >> 0) & 0x1F) << 3 | 0x7;
var mid = ((i >> 5) & 0x1F) << 3 | 0x7;
var high = ((i >> 10) & 0x1F) << 3 | 0x7;
ctx.fillStyle = '#' + hexdigit(high) + hexdigit(mid) + hexdigit(low);
for(i in w) {
drawSeg(ctx, w[i]);
ctx.fill();
}
}
function hexdigit(n) { return '0123456789ABCDEF'.charAt((n >> 4) & 0xF) + '0123456789ABCDEF'.charAt(n & 0xF); }
/////////////////////////
//
// Drawing Runtime
//
/////////////////////////
function refresh() {
if(!chipLayoutIsVisible) return;
ctx.clearRect(0, 0, grCanvasSize, grCanvasSize);
for(i in nodes) {
if(isNodeHigh(i)) overlayNode(nodes[i].segs);
}
hiliteNode(hilited);
}
function overlayNode(w) {
ctx.fillStyle = 'rgba(255,0,64,0.4)';
for(i in w) {
drawSeg(ctx, w[i]);
ctx.fill();
}
}
// originally to highlight using a list of node numbers
// but can now include transistor names
function hiliteNode(n) {
var ctx = hilite.getContext('2d');
ctx.clearRect(0, 0, grCanvasSize, grCanvasSize);
if(n == -1) return;
hilited = n;
for(var i in n) {
if(typeof n[i] != "number") {
hiliteTrans([n[i]]);
continue;
}
if(isNodeHigh(n[i])) {
ctx.fillStyle = 'rgba(255,0,0,0.7)';
} else {
ctx.fillStyle = 'rgba(255,255,255,0.7)';
}
var segs = nodes[n[i]].segs;
for(var s in segs) { drawSeg(ctx, segs[s]); ctx.fill(); }
}
}
// highlight a single transistor (additively - does not clear highlighting)
function hiliteTrans(n) {
var ctx = hilite.getContext('2d');
ctx.strokeStyle = 'rgba(255,255,255,0.7)';
ctx.lineWidth = 4
for(var t in n) {
var bb = transistors[n[t]].bb
var segs = [[bb[0], bb[2], bb[1], bb[2], bb[1], bb[3], bb[0], bb[3]]]
for(var s in segs) { drawSeg(ctx, segs[s]); ctx.stroke(); }
}
}
function ctxDrawBox(ctx, xMin, yMin, xMax, yMax) {
var cap = ctx.lineCap;
ctx.lineCap = "square";
ctx.beginPath();
ctx.moveTo(xMin, yMin);
ctx.lineTo(xMin, yMax);
ctx.lineTo(xMax, yMax);
ctx.lineTo(xMax, yMin);
ctx.lineTo(xMin, yMin);
ctx.stroke();
ctx.lineCap = cap;
}
// takes a bounding box in chip coords and centres the display over it
function zoomToBox(xmin, xmax, ymin, ymax) {
var xmid = (xmin + xmax) / 2;
var ymid = (ymin + ymax) / 2;
var x = (xmid + 400) / grChipSize * 600;
var y = 600 - ymid / grChipSize * 600;
var zoom = 5; // pending a more careful calculation
moveHere([x, y, zoom]);
}
function drawSeg(ctx, seg) {
var dx = 400;
ctx.beginPath();
ctx.moveTo(grScale(seg[0] + dx), grScale(grChipSize - seg[1]));
for(var i = 2; i<seg.length; i += 2) ctx.lineTo(grScale(seg[i] + dx), grScale(grChipSize - seg[i + 1]));
ctx.lineTo(grScale(seg[0] + dx), grScale(grChipSize - seg[1]));
}
function findNodeNumber(x, y) {
var ctx = hitbuffer.getContext('2d');
var pixels = ctx.getImageData(x*grCanvasSize / 600, y*grCanvasSize / 600, 2, 2).data;
if(pixels[0] == 0xFF && pixels[1] == 0xFF && pixels[2] == 0xFF) return -1;
var high = (pixels[0] >> 3) & 0x1F;
var mid = (pixels[1] >> 3) & 0x1F;
var low = (pixels[2] >> 3) & 0x1F;
return (high << 10) + (mid << 5) + low;
}
function clearHighlight() {
// remove red/white overlay according to logic value
// for easier layout navigation
ctx.clearRect(0, 0, grCanvasSize, grCanvasSize);
}
function updateShow(layer, on) {
drawlayers[layer] = on;
setupBackground();
}
// we draw the chip data scaled down to the canvas
// and so avoid scaling a large canvas
function grScale(x) {
return Math.round(x*grCanvasSize / grChipSize);
}
function localx(el, gx) {
return gx - el.getBoundingClientRect().left;
}
function localy(el, gy) {
return gy - el.getBoundingClientRect().top;
}
function setStatus() {
var res = '';
// pad the arguments to make this a three-line display
// there must be a clean way to do this
if(arguments[1] == undefined)arguments[1] = "";
if(arguments[2] == undefined)arguments[2] = "";
arguments.length = 3;
for(var i = 0; i<arguments.length; i++) res = res + arguments[i] + '<br>';
statbox.innerHTML = res;
}
function setupNodeNameList() {
for(var i in nodenames)
nodenamelist.push(i);
}*/

12
Visual2C02/wires.h Normal file
View file

@ -0,0 +1,12 @@
#pragma once
#include "datastructures.h"
extern vector<node> nodes;
extern unordered_map<string, shared_ptr<transistor>> transistors;
extern unordered_map<int, std::string> nodenameByNumber;
extern int ngnd;
extern int npwr;
void initDataStructures();
//string nodeName(int nodeNumber);