mirror of
https://github.com/SourMesen/VisualNes.git
synced 2024-06-01 02:48:05 -04:00
Initial commit (C++ port of Visual 2C02)
This commit is contained in:
commit
dd133ff3f6
168
.gitignore
vendored
Normal file
168
.gitignore
vendored
Normal 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
28
Visual2C02.sln
Normal 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
|
164
Visual2C02/Visual2C02.vcxproj
Normal file
164
Visual2C02/Visual2C02.vcxproj
Normal 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>
|
68
Visual2C02/Visual2C02.vcxproj.filters
Normal file
68
Visual2C02/Visual2C02.vcxproj.filters
Normal 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
272
Visual2C02/chipsim.cpp
Normal 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
18
Visual2C02/chipsim.h
Normal 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
93
Visual2C02/datadefs.cpp
Normal 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
8
Visual2C02/datadefs.h
Normal 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();
|
36
Visual2C02/datastructures.h
Normal file
36
Visual2C02/datastructures.h
Normal 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
279
Visual2C02/macros.cpp
Normal 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
17
Visual2C02/macros.h
Normal 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
62
Visual2C02/main.cpp
Normal 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
1983
Visual2C02/nodenames.txt
Normal file
File diff suppressed because it is too large
Load diff
35615
Visual2C02/segdefs.txt
Normal file
35615
Visual2C02/segdefs.txt
Normal file
File diff suppressed because one or more lines are too long
1
Visual2C02/stdafx.cpp
Normal file
1
Visual2C02/stdafx.cpp
Normal file
|
@ -0,0 +1 @@
|
|||
#include "stdafx.h"
|
18
Visual2C02/stdafx.h
Normal file
18
Visual2C02/stdafx.h
Normal 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
16758
Visual2C02/transdefs.txt
Normal file
File diff suppressed because it is too large
Load diff
333
Visual2C02/wires.cpp
Normal file
333
Visual2C02/wires.cpp
Normal 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
12
Visual2C02/wires.h
Normal 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);
|
Loading…
Reference in a new issue