├── .gitignore
├── .paket
├── Paket.Restore.targets
├── paket.bootstrapper.exe
└── paket.exe
├── LICENSE
├── Nuget.Config
├── README.md
├── Visual2.sln
├── app
├── css
│ ├── material-icons.css
│ ├── photon.css
│ ├── vex-theme-default.css
│ ├── vex-theme-flat-attack.css
│ ├── vex-theme-os.css
│ ├── vex-theme-plain.css
│ ├── vex-theme-top.css
│ ├── vex-theme-wireframe.css
│ ├── vex.css
│ └── vistally.css
├── fonts
│ ├── fira-code.eot
│ ├── fira-code.ttf
│ ├── fira-code.woff
│ ├── material-icons.woff2
│ ├── photon-entypo.eot
│ ├── photon-entypo.ttf
│ └── photon-entypo.woff
├── hovers
│ ├── testhover.md
│ └── testhover1.md
├── index.html
├── js
│ └── monaco-init.js
├── resources
│ ├── errortest.html
│ └── visual.ico
├── samples
│ └── karatsuba.s
├── test-data
│ ├── ALLOWEDdp2ImmAll.txt
│ ├── ALLOWEDdp2ShiftsAll.txt
│ ├── ALLOWEDdp3ImmAll.txt
│ ├── ALLOWEDdp3ShiftsAll.txt
│ ├── ComputedBranchesAll.txt
│ ├── ConditionalBranchesAll.txt
│ ├── MemLoadsAll.txt
│ ├── MemStoresAll.txt
│ ├── MiscInstrAll.txt
│ ├── MultMemLoadsAll.txt
│ ├── MultMemStoresAll.txt
│ ├── dp2ImmAll.txt
│ ├── dp2ShiftsAll.txt
│ ├── dp3ImmAll.txt
│ └── dp3ShiftsAll.txt
└── test-results
│ ├── BETTERsMemLoadsAll.txt
│ ├── BETTERsMemStoresAll.txt
│ ├── ERRORsMemLoadsAll.txt
│ ├── ERRORsMemStoresAll.txt
│ ├── ERRORsdp2ImmAll.txt
│ ├── ERRORsdp3ImmAll.txt
│ ├── OKsMemLoadsAll.txt
│ ├── OKsMemStoresAll.txt
│ ├── OKsdp2ImmAll.txt
│ ├── OKsdp2ShiftsAll.txt
│ ├── OKsdp3ImmAll.txt
│ └── OKsdp3ShiftsAll.txt
├── build
├── icon.icns
└── icon.ico
├── docs
└── visual-screen.png
├── package.json
├── packages
└── build
│ └── FAKE
│ └── [Content_Types].xml
├── paket.dependencies
├── paket.lock
├── setup.bat
├── setup.sh
├── src
├── Emulator
│ ├── Branch.fs
│ ├── CommonData.fs
│ ├── CommonLex.fs
│ ├── DP.fs
│ ├── Emulator.fsproj
│ ├── Errors.fs
│ ├── ExecutionTop.fs
│ ├── Expressions.fs
│ ├── Extensions.fs
│ ├── Helpers.fs
│ ├── Memory.fs
│ ├── Misc.fs
│ ├── ParseTop.fs
│ ├── Testlib.fs
│ └── paket.references
├── Main
│ ├── Main.fs
│ ├── Main.fsproj
│ └── paket.references
└── Renderer
│ ├── Editors.fs
│ ├── ErrorDocs.fs
│ ├── Files.fs
│ ├── Integration.fs
│ ├── MenuBar.fs
│ ├── Refs.fs
│ ├── Renderer.fs
│ ├── Renderer.fsproj
│ ├── Settings.fs
│ ├── Stats.fs
│ ├── Tabs.fs
│ ├── Testbench.fs
│ ├── Tests.fs
│ ├── Tooltips.fs
│ ├── Views.fs
│ └── paket.references
├── webpack.config.js
└── yarn.lock
/.paket/paket.bootstrapper.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scc416/Visual2/9ebdcd84935acd724658c506acb4073c965ad9a5/.paket/paket.bootstrapper.exe
--------------------------------------------------------------------------------
/.paket/paket.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scc416/Visual2/9ebdcd84935acd724658c506acb4073c965ad9a5/.paket/paket.exe
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 scc416
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Nuget.Config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # VisUAL2: ARM assembler and simulator (Written in F#) with elmish, React Monaco Editor, Electron & Fable
2 | Read the [full user guide](https://scc416.github.io/Visual2-doc/)
3 | 
4 |
--------------------------------------------------------------------------------
/Visual2.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26124.0
5 | MinimumVisualStudioVersion = 15.0.26124.0
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{3E8DACEA-3E56-456A-A973-EC6F4AA8CFEA}"
7 | EndProject
8 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Emulator", "src\Emulator\Emulator.fsproj", "{B6AA1962-6D10-412A-A9B5-F573F68D47F6}"
9 | EndProject
10 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Main", "src\Main\Main.fsproj", "{953E9E20-5D1A-4B0F-93B2-FD6C331D67AF}"
11 | EndProject
12 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Renderer", "src\Renderer\Renderer.fsproj", "{4E732969-F73D-4B87-8F9F-BA8FCDDE01FC}"
13 | EndProject
14 | Global
15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
16 | Debug|Any CPU = Debug|Any CPU
17 | Debug|x64 = Debug|x64
18 | Debug|x86 = Debug|x86
19 | Release|Any CPU = Release|Any CPU
20 | Release|x64 = Release|x64
21 | Release|x86 = Release|x86
22 | EndGlobalSection
23 | GlobalSection(SolutionProperties) = preSolution
24 | HideSolutionNode = FALSE
25 | EndGlobalSection
26 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
27 | {B6AA1962-6D10-412A-A9B5-F573F68D47F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
28 | {B6AA1962-6D10-412A-A9B5-F573F68D47F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
29 | {B6AA1962-6D10-412A-A9B5-F573F68D47F6}.Debug|x64.ActiveCfg = Debug|x64
30 | {B6AA1962-6D10-412A-A9B5-F573F68D47F6}.Debug|x64.Build.0 = Debug|x64
31 | {B6AA1962-6D10-412A-A9B5-F573F68D47F6}.Debug|x86.ActiveCfg = Debug|x86
32 | {B6AA1962-6D10-412A-A9B5-F573F68D47F6}.Debug|x86.Build.0 = Debug|x86
33 | {B6AA1962-6D10-412A-A9B5-F573F68D47F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
34 | {B6AA1962-6D10-412A-A9B5-F573F68D47F6}.Release|Any CPU.Build.0 = Release|Any CPU
35 | {B6AA1962-6D10-412A-A9B5-F573F68D47F6}.Release|x64.ActiveCfg = Release|x64
36 | {B6AA1962-6D10-412A-A9B5-F573F68D47F6}.Release|x64.Build.0 = Release|x64
37 | {B6AA1962-6D10-412A-A9B5-F573F68D47F6}.Release|x86.ActiveCfg = Release|x86
38 | {B6AA1962-6D10-412A-A9B5-F573F68D47F6}.Release|x86.Build.0 = Release|x86
39 | {953E9E20-5D1A-4B0F-93B2-FD6C331D67AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
40 | {953E9E20-5D1A-4B0F-93B2-FD6C331D67AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
41 | {953E9E20-5D1A-4B0F-93B2-FD6C331D67AF}.Debug|x64.ActiveCfg = Debug|x64
42 | {953E9E20-5D1A-4B0F-93B2-FD6C331D67AF}.Debug|x64.Build.0 = Debug|x64
43 | {953E9E20-5D1A-4B0F-93B2-FD6C331D67AF}.Debug|x86.ActiveCfg = Debug|x86
44 | {953E9E20-5D1A-4B0F-93B2-FD6C331D67AF}.Debug|x86.Build.0 = Debug|x86
45 | {953E9E20-5D1A-4B0F-93B2-FD6C331D67AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
46 | {953E9E20-5D1A-4B0F-93B2-FD6C331D67AF}.Release|Any CPU.Build.0 = Release|Any CPU
47 | {953E9E20-5D1A-4B0F-93B2-FD6C331D67AF}.Release|x64.ActiveCfg = Release|x64
48 | {953E9E20-5D1A-4B0F-93B2-FD6C331D67AF}.Release|x64.Build.0 = Release|x64
49 | {953E9E20-5D1A-4B0F-93B2-FD6C331D67AF}.Release|x86.ActiveCfg = Release|x86
50 | {953E9E20-5D1A-4B0F-93B2-FD6C331D67AF}.Release|x86.Build.0 = Release|x86
51 | {4E732969-F73D-4B87-8F9F-BA8FCDDE01FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
52 | {4E732969-F73D-4B87-8F9F-BA8FCDDE01FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
53 | {4E732969-F73D-4B87-8F9F-BA8FCDDE01FC}.Debug|x64.ActiveCfg = Debug|x64
54 | {4E732969-F73D-4B87-8F9F-BA8FCDDE01FC}.Debug|x64.Build.0 = Debug|x64
55 | {4E732969-F73D-4B87-8F9F-BA8FCDDE01FC}.Debug|x86.ActiveCfg = Debug|x86
56 | {4E732969-F73D-4B87-8F9F-BA8FCDDE01FC}.Debug|x86.Build.0 = Debug|x86
57 | {4E732969-F73D-4B87-8F9F-BA8FCDDE01FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
58 | {4E732969-F73D-4B87-8F9F-BA8FCDDE01FC}.Release|Any CPU.Build.0 = Release|Any CPU
59 | {4E732969-F73D-4B87-8F9F-BA8FCDDE01FC}.Release|x64.ActiveCfg = Release|x64
60 | {4E732969-F73D-4B87-8F9F-BA8FCDDE01FC}.Release|x64.Build.0 = Release|x64
61 | {4E732969-F73D-4B87-8F9F-BA8FCDDE01FC}.Release|x86.ActiveCfg = Release|x86
62 | {4E732969-F73D-4B87-8F9F-BA8FCDDE01FC}.Release|x86.Build.0 = Release|x86
63 | EndGlobalSection
64 | GlobalSection(NestedProjects) = preSolution
65 | {B6AA1962-6D10-412A-A9B5-F573F68D47F6} = {3E8DACEA-3E56-456A-A973-EC6F4AA8CFEA}
66 | {953E9E20-5D1A-4B0F-93B2-FD6C331D67AF} = {3E8DACEA-3E56-456A-A973-EC6F4AA8CFEA}
67 | {4E732969-F73D-4B87-8F9F-BA8FCDDE01FC} = {3E8DACEA-3E56-456A-A973-EC6F4AA8CFEA}
68 | EndGlobalSection
69 | EndGlobal
70 |
--------------------------------------------------------------------------------
/app/css/material-icons.css:
--------------------------------------------------------------------------------
1 | /* fallback */
2 | @font-face {
3 | font-family: 'Material Icons';
4 | font-style: normal;
5 | font-weight: 400;
6 | src: url("../fonts/material-icons.woff2") format('woff2');
7 | }
8 |
9 | .material-icons {
10 | font-family: 'Material Icons';
11 | font-weight: normal;
12 | font-style: normal;
13 | font-size: 24px;
14 | line-height: 1;
15 | letter-spacing: normal;
16 | text-transform: none;
17 | display: inline-block;
18 | white-space: nowrap;
19 | word-wrap: normal;
20 | direction: ltr;
21 | -webkit-font-feature-settings: 'liga';
22 | -webkit-font-smoothing: antialiased;
23 | }
--------------------------------------------------------------------------------
/app/css/vex-theme-default.css:
--------------------------------------------------------------------------------
1 | @-webkit-keyframes vex-flyin {
2 | 0% {
3 | opacity: 0;
4 | -webkit-transform: translateY(-40px);
5 | transform: translateY(-40px); }
6 | 100% {
7 | opacity: 1;
8 | -webkit-transform: translateY(0);
9 | transform: translateY(0); } }
10 |
11 | @keyframes vex-flyin {
12 | 0% {
13 | opacity: 0;
14 | -webkit-transform: translateY(-40px);
15 | transform: translateY(-40px); }
16 | 100% {
17 | opacity: 1;
18 | -webkit-transform: translateY(0);
19 | transform: translateY(0); } }
20 |
21 | @-webkit-keyframes vex-flyout {
22 | 0% {
23 | opacity: 1;
24 | -webkit-transform: translateY(0);
25 | transform: translateY(0); }
26 | 100% {
27 | opacity: 0;
28 | -webkit-transform: translateY(-40px);
29 | transform: translateY(-40px); } }
30 |
31 | @keyframes vex-flyout {
32 | 0% {
33 | opacity: 1;
34 | -webkit-transform: translateY(0);
35 | transform: translateY(0); }
36 | 100% {
37 | opacity: 0;
38 | -webkit-transform: translateY(-40px);
39 | transform: translateY(-40px); } }
40 |
41 | @-webkit-keyframes vex-pulse {
42 | 0% {
43 | box-shadow: inset 0 0 0 300px transparent; }
44 | 70% {
45 | box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
46 | 100% {
47 | box-shadow: inset 0 0 0 300px transparent; } }
48 |
49 | @keyframes vex-pulse {
50 | 0% {
51 | box-shadow: inset 0 0 0 300px transparent; }
52 | 70% {
53 | box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
54 | 100% {
55 | box-shadow: inset 0 0 0 300px transparent; } }
56 |
57 | .vex.vex-theme-default {
58 | padding-top: 160px;
59 | padding-bottom: 160px; }
60 | .vex.vex-theme-default.vex-closing .vex-content {
61 | -webkit-animation: vex-flyout .5s forwards;
62 | animation: vex-flyout .5s forwards; }
63 | .vex.vex-theme-default .vex-content {
64 | -webkit-animation: vex-flyin .5s;
65 | animation: vex-flyin .5s; }
66 | .vex.vex-theme-default .vex-content {
67 | border-radius: 5px;
68 | font-family: "Helvetica Neue", sans-serif;
69 | background: #f0f0f0;
70 | color: #444;
71 | padding: 1em;
72 | position: relative;
73 | margin: 0 auto;
74 | max-width: 100%;
75 | width: 450px;
76 | font-size: 1.1em;
77 | line-height: 1.5em; }
78 | .vex.vex-theme-default .vex-content h1, .vex.vex-theme-default .vex-content h2, .vex.vex-theme-default .vex-content h3, .vex.vex-theme-default .vex-content h4, .vex.vex-theme-default .vex-content h5, .vex.vex-theme-default .vex-content h6, .vex.vex-theme-default .vex-content p, .vex.vex-theme-default .vex-content ul, .vex.vex-theme-default .vex-content li {
79 | color: inherit; }
80 | .vex.vex-theme-default .vex-close {
81 | border-radius: 5px;
82 | position: absolute;
83 | top: 0;
84 | right: 0;
85 | cursor: pointer; }
86 | .vex.vex-theme-default .vex-close:before {
87 | border-radius: 3px;
88 | position: absolute;
89 | content: "\00D7";
90 | font-size: 26px;
91 | font-weight: normal;
92 | line-height: 31px;
93 | height: 30px;
94 | width: 30px;
95 | text-align: center;
96 | top: 3px;
97 | right: 3px;
98 | color: #bbb;
99 | background: transparent; }
100 | .vex.vex-theme-default .vex-close:hover:before, .vex.vex-theme-default .vex-close:active:before {
101 | color: #777;
102 | background: #e0e0e0; }
103 | .vex.vex-theme-default .vex-dialog-form .vex-dialog-message {
104 | margin-bottom: .5em; }
105 | .vex.vex-theme-default .vex-dialog-form .vex-dialog-input {
106 | margin-bottom: 1em; }
107 | .vex.vex-theme-default .vex-dialog-form .vex-dialog-input select, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="week"] {
108 | border-radius: 3px;
109 | background: #fff;
110 | width: 100%;
111 | padding: .25em .67em;
112 | border: 0;
113 | font-family: inherit;
114 | font-weight: inherit;
115 | font-size: inherit;
116 | min-height: 2.5em;
117 | margin: 0 0 .25em; }
118 | .vex.vex-theme-default .vex-dialog-form .vex-dialog-input select:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
119 | box-shadow: inset 0 0 0 2px #8dbdf1;
120 | outline: none; }
121 | .vex.vex-theme-default .vex-dialog-form .vex-dialog-buttons {
122 | *zoom: 1; }
123 | .vex.vex-theme-default .vex-dialog-form .vex-dialog-buttons:after {
124 | content: "";
125 | display: table;
126 | clear: both; }
127 | .vex.vex-theme-default .vex-dialog-button {
128 | border-radius: 3px;
129 | border: 0;
130 | float: right;
131 | margin: 0 0 0 .5em;
132 | font-family: inherit;
133 | text-transform: uppercase;
134 | letter-spacing: .1em;
135 | font-size: .8em;
136 | line-height: 1em;
137 | padding: .75em 2em; }
138 | .vex.vex-theme-default .vex-dialog-button.vex-last {
139 | margin-left: 0; }
140 | .vex.vex-theme-default .vex-dialog-button:focus {
141 | -webkit-animation: vex-pulse 1.1s infinite;
142 | animation: vex-pulse 1.1s infinite;
143 | outline: none; }
144 | @media (max-width: 568px) {
145 | .vex.vex-theme-default .vex-dialog-button:focus {
146 | -webkit-animation: none;
147 | animation: none; } }
148 | .vex.vex-theme-default .vex-dialog-button.vex-dialog-button-primary {
149 | background: #3288e6;
150 | color: #fff; }
151 | .vex.vex-theme-default .vex-dialog-button.vex-dialog-button-secondary {
152 | background: #e0e0e0;
153 | color: #777; }
154 |
155 | .vex-loading-spinner.vex-theme-default {
156 | box-shadow: 0 0 0 0.5em #f0f0f0, 0 0 1px 0.5em rgba(0, 0, 0, 0.3);
157 | border-radius: 100%;
158 | background: #f0f0f0;
159 | border: .2em solid transparent;
160 | border-top-color: #bbb;
161 | top: -1.1em;
162 | bottom: auto; }
163 |
--------------------------------------------------------------------------------
/app/css/vex-theme-os.css:
--------------------------------------------------------------------------------
1 | @-webkit-keyframes vex-flyin {
2 | 0% {
3 | opacity: 0;
4 | -webkit-transform: translateY(-40px);
5 | transform: translateY(-40px); }
6 | 100% {
7 | opacity: 1;
8 | -webkit-transform: translateY(0);
9 | transform: translateY(0); } }
10 |
11 | @keyframes vex-flyin {
12 | 0% {
13 | opacity: 0;
14 | -webkit-transform: translateY(-40px);
15 | transform: translateY(-40px); }
16 | 100% {
17 | opacity: 1;
18 | -webkit-transform: translateY(0);
19 | transform: translateY(0); } }
20 |
21 | @-webkit-keyframes vex-flyout {
22 | 0% {
23 | opacity: 1;
24 | -webkit-transform: translateY(0);
25 | transform: translateY(0); }
26 | 100% {
27 | opacity: 0;
28 | -webkit-transform: translateY(-40px);
29 | transform: translateY(-40px); } }
30 |
31 | @keyframes vex-flyout {
32 | 0% {
33 | opacity: 1;
34 | -webkit-transform: translateY(0);
35 | transform: translateY(0); }
36 | 100% {
37 | opacity: 0;
38 | -webkit-transform: translateY(-40px);
39 | transform: translateY(-40px); } }
40 |
41 | @-webkit-keyframes vex-pulse {
42 | 0% {
43 | box-shadow: inset 0 0 0 300px transparent; }
44 | 70% {
45 | box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
46 | 100% {
47 | box-shadow: inset 0 0 0 300px transparent; } }
48 |
49 | @keyframes vex-pulse {
50 | 0% {
51 | box-shadow: inset 0 0 0 300px transparent; }
52 | 70% {
53 | box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
54 | 100% {
55 | box-shadow: inset 0 0 0 300px transparent; } }
56 |
57 | .vex.vex-theme-os {
58 | padding-top: 160px;
59 | padding-bottom: 160px; }
60 | .vex.vex-theme-os.vex-closing .vex-content {
61 | -webkit-animation: vex-flyout .5s forwards;
62 | animation: vex-flyout .5s forwards; }
63 | .vex.vex-theme-os .vex-content {
64 | -webkit-animation: vex-flyin .5s;
65 | animation: vex-flyin .5s; }
66 | .vex.vex-theme-os .vex-content {
67 | border-radius: 5px;
68 | box-shadow: inset 0 1px #a6a6a6, 0 0 0 1px rgba(0, 0, 0, 0.08);
69 | font-family: "Helvetica Neue", sans-serif;
70 | border-top: 20px solid #bbb;
71 | background: #f0f0f0;
72 | color: #444;
73 | padding: 1em;
74 | position: relative;
75 | margin: 0 auto;
76 | max-width: 100%;
77 | width: 450px;
78 | font-size: 1.1em;
79 | line-height: 1.5em; }
80 | .vex.vex-theme-os .vex-content h1, .vex.vex-theme-os .vex-content h2, .vex.vex-theme-os .vex-content h3, .vex.vex-theme-os .vex-content h4, .vex.vex-theme-os .vex-content h5, .vex.vex-theme-os .vex-content h6, .vex.vex-theme-os .vex-content p, .vex.vex-theme-os .vex-content ul, .vex.vex-theme-os .vex-content li {
81 | color: inherit; }
82 | .vex.vex-theme-os .vex-close {
83 | border-radius: 0 5px 0 0;
84 | position: absolute;
85 | top: 0;
86 | right: 0;
87 | cursor: pointer; }
88 | .vex.vex-theme-os .vex-close:before {
89 | border-radius: 3px;
90 | position: absolute;
91 | content: "\00D7";
92 | font-size: 26px;
93 | font-weight: normal;
94 | line-height: 31px;
95 | height: 30px;
96 | width: 30px;
97 | text-align: center;
98 | top: 3px;
99 | right: 3px;
100 | color: #bbb;
101 | background: transparent; }
102 | .vex.vex-theme-os .vex-close:hover:before, .vex.vex-theme-os .vex-close:active:before {
103 | color: #777;
104 | background: #e0e0e0; }
105 | .vex.vex-theme-os .vex-dialog-form .vex-dialog-message {
106 | margin-bottom: .5em; }
107 | .vex.vex-theme-os .vex-dialog-form .vex-dialog-input {
108 | margin-bottom: 1em; }
109 | .vex.vex-theme-os .vex-dialog-form .vex-dialog-input select, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="week"] {
110 | border-radius: 3px;
111 | background: #fff;
112 | width: 100%;
113 | padding: .25em .67em;
114 | border: 0;
115 | font-family: inherit;
116 | font-weight: inherit;
117 | font-size: inherit;
118 | min-height: 2.5em;
119 | margin: 0 0 .25em; }
120 | .vex.vex-theme-os .vex-dialog-form .vex-dialog-input select:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
121 | box-shadow: inset 0 0 0 1px #3288e6;
122 | outline: none; }
123 | .vex.vex-theme-os .vex-dialog-form .vex-dialog-buttons {
124 | *zoom: 1; }
125 | .vex.vex-theme-os .vex-dialog-form .vex-dialog-buttons:after {
126 | content: "";
127 | display: table;
128 | clear: both; }
129 | .vex.vex-theme-os .vex-dialog-button {
130 | border-radius: 3px;
131 | border: 0;
132 | float: right;
133 | margin: 0 0 0 .5em;
134 | font-family: inherit;
135 | text-transform: uppercase;
136 | letter-spacing: .1em;
137 | font-size: .8em;
138 | line-height: 1em;
139 | padding: .75em 2em; }
140 | .vex.vex-theme-os .vex-dialog-button.vex-last {
141 | margin-left: 0; }
142 | .vex.vex-theme-os .vex-dialog-button:focus {
143 | -webkit-animation: vex-pulse 1.1s infinite;
144 | animation: vex-pulse 1.1s infinite;
145 | outline: none; }
146 | @media (max-width: 568px) {
147 | .vex.vex-theme-os .vex-dialog-button:focus {
148 | -webkit-animation: none;
149 | animation: none; } }
150 | .vex.vex-theme-os .vex-dialog-button.vex-dialog-button-primary {
151 | background: #3288e6;
152 | color: #fff; }
153 | .vex.vex-theme-os .vex-dialog-button.vex-dialog-button-secondary {
154 | background: #e0e0e0;
155 | color: #777; }
156 |
157 | .vex-loading-spinner.vex-theme-os {
158 | box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2), 0 0 0.5em rgba(0, 0, 0, 0.2);
159 | border-radius: 100%;
160 | background: rgba(255, 255, 255, 0.2);
161 | width: 0;
162 | height: 0;
163 | border: 1.2em solid #bbb;
164 | border-top-color: #f0f0f0;
165 | border-bottom-color: #f0f0f0; }
166 |
--------------------------------------------------------------------------------
/app/css/vex-theme-plain.css:
--------------------------------------------------------------------------------
1 | @-webkit-keyframes vex-pulse {
2 | 0% {
3 | box-shadow: inset 0 0 0 300px transparent; }
4 | 70% {
5 | box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
6 | 100% {
7 | box-shadow: inset 0 0 0 300px transparent; } }
8 |
9 | @keyframes vex-pulse {
10 | 0% {
11 | box-shadow: inset 0 0 0 300px transparent; }
12 | 70% {
13 | box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
14 | 100% {
15 | box-shadow: inset 0 0 0 300px transparent; } }
16 |
17 | .vex.vex-theme-plain {
18 | padding-top: 160px;
19 | padding-bottom: 160px; }
20 | .vex.vex-theme-plain .vex-content {
21 | font-family: "Helvetica Neue", sans-serif;
22 | background: #fff;
23 | color: #444;
24 | padding: 1em;
25 | position: relative;
26 | margin: 0 auto;
27 | max-width: 100%;
28 | width: 450px;
29 | font-size: 1.1em;
30 | line-height: 1.5em; }
31 | .vex.vex-theme-plain .vex-content h1, .vex.vex-theme-plain .vex-content h2, .vex.vex-theme-plain .vex-content h3, .vex.vex-theme-plain .vex-content h4, .vex.vex-theme-plain .vex-content h5, .vex.vex-theme-plain .vex-content h6, .vex.vex-theme-plain .vex-content p, .vex.vex-theme-plain .vex-content ul, .vex.vex-theme-plain .vex-content li {
32 | color: inherit; }
33 | .vex.vex-theme-plain .vex-close {
34 | position: absolute;
35 | top: 0;
36 | right: 0;
37 | cursor: pointer; }
38 | .vex.vex-theme-plain .vex-close:before {
39 | position: absolute;
40 | content: "\00D7";
41 | font-size: 26px;
42 | font-weight: normal;
43 | line-height: 31px;
44 | height: 30px;
45 | width: 30px;
46 | text-align: center;
47 | top: 3px;
48 | right: 3px;
49 | color: #bbb;
50 | background: transparent; }
51 | .vex.vex-theme-plain .vex-close:hover:before, .vex.vex-theme-plain .vex-close:active:before {
52 | color: #777;
53 | background: #e0e0e0; }
54 | .vex.vex-theme-plain .vex-dialog-form .vex-dialog-message {
55 | margin-bottom: .5em; }
56 | .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input {
57 | margin-bottom: 1em; }
58 | .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input select, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="week"] {
59 | background: #f0f0f0;
60 | width: 100%;
61 | padding: .25em .67em;
62 | border: 0;
63 | font-family: inherit;
64 | font-weight: inherit;
65 | font-size: inherit;
66 | min-height: 2.5em;
67 | margin: 0 0 .25em; }
68 | .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input select:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
69 | box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.2);
70 | outline: none; }
71 | .vex.vex-theme-plain .vex-dialog-form .vex-dialog-buttons {
72 | *zoom: 1; }
73 | .vex.vex-theme-plain .vex-dialog-form .vex-dialog-buttons:after {
74 | content: "";
75 | display: table;
76 | clear: both; }
77 | .vex.vex-theme-plain .vex-dialog-button {
78 | border-radius: 0;
79 | border: 0;
80 | float: right;
81 | margin: 0 0 0 .5em;
82 | font-family: inherit;
83 | text-transform: uppercase;
84 | letter-spacing: .1em;
85 | font-size: .8em;
86 | line-height: 1em;
87 | padding: .75em 2em; }
88 | .vex.vex-theme-plain .vex-dialog-button.vex-last {
89 | margin-left: 0; }
90 | .vex.vex-theme-plain .vex-dialog-button:focus {
91 | -webkit-animation: vex-pulse 1.1s infinite;
92 | animation: vex-pulse 1.1s infinite;
93 | outline: none; }
94 | @media (max-width: 568px) {
95 | .vex.vex-theme-plain .vex-dialog-button:focus {
96 | -webkit-animation: none;
97 | animation: none; } }
98 | .vex.vex-theme-plain .vex-dialog-button.vex-dialog-button-primary {
99 | background: #3288e6;
100 | color: #fff; }
101 | .vex.vex-theme-plain .vex-dialog-button.vex-dialog-button-secondary {
102 | background: #e0e0e0;
103 | color: #777; }
104 |
105 | .vex-loading-spinner.vex-theme-plain {
106 | height: 2.5em;
107 | width: 2.5em; }
108 |
--------------------------------------------------------------------------------
/app/css/vex-theme-top.css:
--------------------------------------------------------------------------------
1 | @-webkit-keyframes vex-dropin {
2 | 0% {
3 | -webkit-transform: translateY(0);
4 | transform: translateY(0);
5 | opacity: 0; }
6 | 1% {
7 | -webkit-transform: translateY(-800px);
8 | transform: translateY(-800px);
9 | opacity: 0; }
10 | 2% {
11 | -webkit-transform: translateY(-800px);
12 | transform: translateY(-800px);
13 | opacity: 1; }
14 | 100% {
15 | -webkit-transform: translateY(0);
16 | transform: translateY(0);
17 | opacity: 1; } }
18 |
19 | @keyframes vex-dropin {
20 | 0% {
21 | -webkit-transform: translateY(0);
22 | transform: translateY(0);
23 | opacity: 0; }
24 | 1% {
25 | -webkit-transform: translateY(-800px);
26 | transform: translateY(-800px);
27 | opacity: 0; }
28 | 2% {
29 | -webkit-transform: translateY(-800px);
30 | transform: translateY(-800px);
31 | opacity: 1; }
32 | 100% {
33 | -webkit-transform: translateY(0);
34 | transform: translateY(0);
35 | opacity: 1; } }
36 |
37 | @-webkit-keyframes vex-dropout {
38 | 0% {
39 | -webkit-transform: translateY(0);
40 | transform: translateY(0); }
41 | 100% {
42 | -webkit-transform: translateY(-800px);
43 | transform: translateY(-800px); } }
44 |
45 | @keyframes vex-dropout {
46 | 0% {
47 | -webkit-transform: translateY(0);
48 | transform: translateY(0); }
49 | 100% {
50 | -webkit-transform: translateY(-800px);
51 | transform: translateY(-800px); } }
52 |
53 | @-webkit-keyframes vex-pulse {
54 | 0% {
55 | box-shadow: inset 0 0 0 300px transparent; }
56 | 70% {
57 | box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
58 | 100% {
59 | box-shadow: inset 0 0 0 300px transparent; } }
60 |
61 | @keyframes vex-pulse {
62 | 0% {
63 | box-shadow: inset 0 0 0 300px transparent; }
64 | 70% {
65 | box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
66 | 100% {
67 | box-shadow: inset 0 0 0 300px transparent; } }
68 |
69 | .vex.vex-theme-top.vex-closing .vex-content {
70 | -webkit-animation: vex-dropout .5s forwards;
71 | animation: vex-dropout .5s forwards; }
72 |
73 | .vex.vex-theme-top .vex-content {
74 | -webkit-animation: vex-dropin .5s;
75 | animation: vex-dropin .5s; }
76 |
77 | .vex.vex-theme-top .vex-content {
78 | border-radius: 0 0 5px 5px;
79 | font-family: "Helvetica Neue", sans-serif;
80 | background: #f0f0f0;
81 | color: #444;
82 | padding: 1em;
83 | position: relative;
84 | margin: 0 auto;
85 | max-width: 100%;
86 | width: 450px;
87 | font-size: 1.1em;
88 | line-height: 1.5em; }
89 | .vex.vex-theme-top .vex-content h1, .vex.vex-theme-top .vex-content h2, .vex.vex-theme-top .vex-content h3, .vex.vex-theme-top .vex-content h4, .vex.vex-theme-top .vex-content h5, .vex.vex-theme-top .vex-content h6, .vex.vex-theme-top .vex-content p, .vex.vex-theme-top .vex-content ul, .vex.vex-theme-top .vex-content li {
90 | color: inherit; }
91 |
92 | .vex.vex-theme-top .vex-close {
93 | border-radius: 5px;
94 | position: absolute;
95 | top: 0;
96 | right: 0;
97 | cursor: pointer; }
98 | .vex.vex-theme-top .vex-close:before {
99 | border-radius: 3px;
100 | position: absolute;
101 | content: "\00D7";
102 | font-size: 26px;
103 | font-weight: normal;
104 | line-height: 31px;
105 | height: 30px;
106 | width: 30px;
107 | text-align: center;
108 | top: 3px;
109 | right: 3px;
110 | color: #bbb;
111 | background: transparent; }
112 | .vex.vex-theme-top .vex-close:hover:before, .vex.vex-theme-top .vex-close:active:before {
113 | color: #777;
114 | background: #e0e0e0; }
115 |
116 | .vex.vex-theme-top .vex-dialog-form .vex-dialog-message {
117 | margin-bottom: .5em; }
118 |
119 | .vex.vex-theme-top .vex-dialog-form .vex-dialog-input {
120 | margin-bottom: 1em; }
121 | .vex.vex-theme-top .vex-dialog-form .vex-dialog-input select, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="week"] {
122 | border-radius: 3px;
123 | background: #fff;
124 | width: 100%;
125 | padding: .25em .67em;
126 | border: 0;
127 | font-family: inherit;
128 | font-weight: inherit;
129 | font-size: inherit;
130 | min-height: 2.5em;
131 | margin: 0 0 .25em; }
132 | .vex.vex-theme-top .vex-dialog-form .vex-dialog-input select:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
133 | box-shadow: inset 0 0 0 2px #8dbdf1;
134 | outline: none; }
135 |
136 | .vex.vex-theme-top .vex-dialog-form .vex-dialog-buttons {
137 | *zoom: 1; }
138 | .vex.vex-theme-top .vex-dialog-form .vex-dialog-buttons:after {
139 | content: "";
140 | display: table;
141 | clear: both; }
142 |
143 | .vex.vex-theme-top .vex-dialog-button {
144 | border-radius: 3px;
145 | border: 0;
146 | float: right;
147 | margin: 0 0 0 .5em;
148 | font-family: inherit;
149 | text-transform: uppercase;
150 | letter-spacing: .1em;
151 | font-size: .8em;
152 | line-height: 1em;
153 | padding: .75em 2em; }
154 | .vex.vex-theme-top .vex-dialog-button.vex-last {
155 | margin-left: 0; }
156 | .vex.vex-theme-top .vex-dialog-button:focus {
157 | -webkit-animation: vex-pulse 1.1s infinite;
158 | animation: vex-pulse 1.1s infinite;
159 | outline: none; }
160 | @media (max-width: 568px) {
161 | .vex.vex-theme-top .vex-dialog-button:focus {
162 | -webkit-animation: none;
163 | animation: none; } }
164 | .vex.vex-theme-top .vex-dialog-button.vex-dialog-button-primary {
165 | background: #3288e6;
166 | color: #fff; }
167 | .vex.vex-theme-top .vex-dialog-button.vex-dialog-button-secondary {
168 | background: #e0e0e0;
169 | color: #777; }
170 |
171 | .vex-loading-spinner.vex-theme-top {
172 | box-shadow: 0 0 0 0.5em #f0f0f0, 0 0 1px 0.5em rgba(0, 0, 0, 0.3);
173 | border-radius: 100%;
174 | background: #f0f0f0;
175 | border: .2em solid transparent;
176 | border-top-color: #bbb;
177 | top: -1.1em;
178 | bottom: auto; }
179 |
--------------------------------------------------------------------------------
/app/css/vex-theme-wireframe.css:
--------------------------------------------------------------------------------
1 | @-webkit-keyframes vex-pulse {
2 | 0% {
3 | box-shadow: inset 0 0 0 300px transparent; }
4 | 70% {
5 | box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
6 | 100% {
7 | box-shadow: inset 0 0 0 300px transparent; } }
8 |
9 | @keyframes vex-pulse {
10 | 0% {
11 | box-shadow: inset 0 0 0 300px transparent; }
12 | 70% {
13 | box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25); }
14 | 100% {
15 | box-shadow: inset 0 0 0 300px transparent; } }
16 |
17 | .vex.vex-theme-wireframe {
18 | padding-top: 160px;
19 | padding-bottom: 160px; }
20 | .vex.vex-theme-wireframe .vex-overlay {
21 | background: rgba(255, 255, 255, 0.4); }
22 | .vex.vex-theme-wireframe .vex-content {
23 | font-family: "Helvetica Neue", sans-serif;
24 | background: #fff;
25 | color: #000;
26 | border: 2px solid #000;
27 | padding: 2em;
28 | position: relative;
29 | margin: 0 auto;
30 | max-width: 100%;
31 | width: 400px;
32 | font-size: 1.1em;
33 | line-height: 1.5em; }
34 | .vex.vex-theme-wireframe .vex-content h1, .vex.vex-theme-wireframe .vex-content h2, .vex.vex-theme-wireframe .vex-content h3, .vex.vex-theme-wireframe .vex-content h4, .vex.vex-theme-wireframe .vex-content h5, .vex.vex-theme-wireframe .vex-content h6, .vex.vex-theme-wireframe .vex-content p, .vex.vex-theme-wireframe .vex-content ul, .vex.vex-theme-wireframe .vex-content li {
35 | color: inherit; }
36 | .vex.vex-theme-wireframe .vex-close {
37 | position: absolute;
38 | top: 0;
39 | right: 0;
40 | cursor: pointer; }
41 | .vex.vex-theme-wireframe .vex-close:before {
42 | position: absolute;
43 | content: "\00D7";
44 | font-size: 40px;
45 | font-weight: normal;
46 | line-height: 80px;
47 | height: 80px;
48 | width: 80px;
49 | text-align: center;
50 | top: 3px;
51 | right: 3px;
52 | color: #000; }
53 | .vex.vex-theme-wireframe .vex-close:hover:before, .vex.vex-theme-wireframe .vex-close:active:before {
54 | color: #000; }
55 | .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-message {
56 | margin-bottom: .5em; }
57 | .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input {
58 | margin-bottom: 1em; }
59 | .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input select, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="week"] {
60 | background: #fff;
61 | width: 100%;
62 | padding: .25em .67em;
63 | font-family: inherit;
64 | font-weight: inherit;
65 | font-size: inherit;
66 | min-height: 2.5em;
67 | margin: 0 0 .25em;
68 | border: 2px solid #000; }
69 | .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input select:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
70 | border-style: dashed;
71 | outline: none; }
72 | .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-buttons {
73 | *zoom: 1; }
74 | .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-buttons:after {
75 | content: "";
76 | display: table;
77 | clear: both; }
78 | .vex.vex-theme-wireframe .vex-dialog-button {
79 | border-radius: 0;
80 | border: 0;
81 | float: right;
82 | margin: 0 0 0 .5em;
83 | font-family: inherit;
84 | text-transform: uppercase;
85 | letter-spacing: .1em;
86 | font-size: .8em;
87 | line-height: 1em;
88 | padding: .75em 2em; }
89 | .vex.vex-theme-wireframe .vex-dialog-button.vex-last {
90 | margin-left: 0; }
91 | .vex.vex-theme-wireframe .vex-dialog-button:focus {
92 | -webkit-animation: vex-pulse 1.1s infinite;
93 | animation: vex-pulse 1.1s infinite;
94 | outline: none; }
95 | @media (max-width: 568px) {
96 | .vex.vex-theme-wireframe .vex-dialog-button:focus {
97 | -webkit-animation: none;
98 | animation: none; } }
99 | .vex.vex-theme-wireframe .vex-dialog-button.vex-dialog-button-primary {
100 | background: #000;
101 | color: #fff;
102 | border: 2px solid transparent; }
103 | .vex.vex-theme-wireframe .vex-dialog-button.vex-dialog-button-secondary {
104 | background: #fff;
105 | color: #000;
106 | border: 2px solid #000; }
107 |
108 | .vex-loading-spinner.vex-theme-wireframe {
109 | height: 2.5em;
110 | width: 2.5em; }
111 |
--------------------------------------------------------------------------------
/app/css/vex.css:
--------------------------------------------------------------------------------
1 | @-webkit-keyframes vex-fadein {
2 | 0% {
3 | opacity: 0; }
4 | 100% {
5 | opacity: 1; } }
6 |
7 | @keyframes vex-fadein {
8 | 0% {
9 | opacity: 0; }
10 | 100% {
11 | opacity: 1; } }
12 |
13 | @-webkit-keyframes vex-fadeout {
14 | 0% {
15 | opacity: 1; }
16 | 100% {
17 | opacity: 0; } }
18 |
19 | @keyframes vex-fadeout {
20 | 0% {
21 | opacity: 1; }
22 | 100% {
23 | opacity: 0; } }
24 |
25 | @-webkit-keyframes vex-rotation {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg); }
29 | 100% {
30 | -webkit-transform: rotate(359deg);
31 | transform: rotate(359deg); } }
32 |
33 | @keyframes vex-rotation {
34 | 0% {
35 | -webkit-transform: rotate(0deg);
36 | transform: rotate(0deg); }
37 | 100% {
38 | -webkit-transform: rotate(359deg);
39 | transform: rotate(359deg); } }
40 |
41 | .vex, .vex *, .vex *:before, .vex *:after {
42 | -moz-box-sizing: border-box;
43 | box-sizing: border-box; }
44 |
45 | .vex {
46 | position: fixed;
47 | overflow: auto;
48 | -webkit-overflow-scrolling: touch;
49 | z-index: 1111;
50 | top: 0;
51 | right: 0;
52 | bottom: 0;
53 | left: 0; }
54 |
55 | .vex-scrollbar-measure {
56 | position: absolute;
57 | top: -9999px;
58 | width: 50px;
59 | height: 50px;
60 | overflow: scroll; }
61 |
62 | .vex-overlay {
63 | -webkit-animation: vex-fadein .5s;
64 | animation: vex-fadein .5s;
65 | position: fixed;
66 | z-index: 1111;
67 | background: rgba(0, 0, 0, 0.4);
68 | top: 0;
69 | right: 0;
70 | bottom: 0;
71 | left: 0; }
72 |
73 | .vex-overlay.vex-closing {
74 | -webkit-animation: vex-fadeout .5s forwards;
75 | animation: vex-fadeout .5s forwards; }
76 |
77 | .vex-content {
78 | -webkit-animation: vex-fadein .5s;
79 | animation: vex-fadein .5s;
80 | background: #fff; }
81 |
82 | .vex.vex-closing .vex-content {
83 | -webkit-animation: vex-fadeout .5s forwards;
84 | animation: vex-fadeout .5s forwards; }
85 |
86 | .vex-close:before {
87 | font-family: Arial, sans-serif;
88 | content: "\00D7"; }
89 |
90 | .vex-dialog-form {
91 | margin: 0; }
92 |
93 | .vex-dialog-button {
94 | text-rendering: optimizeLegibility;
95 | -webkit-appearance: none;
96 | -moz-appearance: none;
97 | appearance: none;
98 | cursor: pointer;
99 | -webkit-tap-highlight-color: transparent; }
100 |
101 | .vex-loading-spinner {
102 | -webkit-animation: vex-rotation .7s linear infinite;
103 | animation: vex-rotation .7s linear infinite;
104 | box-shadow: 0 0 1em rgba(0, 0, 0, 0.1);
105 | position: fixed;
106 | z-index: 1112;
107 | margin: auto;
108 | top: 0;
109 | right: 0;
110 | bottom: 0;
111 | left: 0;
112 | height: 2em;
113 | width: 2em;
114 | background: #fff; }
115 |
116 | body.vex-open {
117 | overflow: hidden; }
118 |
--------------------------------------------------------------------------------
/app/css/vistally.css:
--------------------------------------------------------------------------------
1 | * {
2 | -webkit-user-drag: none; /* disable drag and drop */
3 | }
4 |
5 | /* used to animate app and settings windows */
6 | @keyframes fadein {
7 | from {
8 | opacity: 0;
9 | }
10 |
11 | to {
12 | opacity: 1;
13 | }
14 | }
15 |
16 |
17 |
18 | .window {
19 | animation: fadein 0.5s;
20 | }
21 |
22 |
23 | ::selection {
24 | background: #ffb7b7;
25 | }
26 |
27 | .unsaved {
28 | font-weight: bold;
29 | }
30 |
31 |
32 |
33 | .list-group-item {
34 | padding: 2px;
35 | border-color: lightgrey;
36 | }
37 |
38 | .toolbar-header {
39 | border-bottom: 1px solid #c2c0c2;
40 | background-color:cadetblue;
41 | }
42 |
43 | .toolbar-header .title {
44 | margin-top: 1px;
45 | }
46 |
47 | .toolbar-footer {
48 | position: absolute;
49 | bottom: 0;
50 | left: 0;
51 | width: 100%;
52 | height: 40px;
53 | background-color: lightgrey;
54 | border-top: 1px solid #c2c0c2;
55 | }
56 | .toolbar-header {
57 | padding: 5px;
58 | }
59 |
60 | .btn-reg, .btn-reg-con {
61 | height: calc(13pt + 7px);
62 | line-height: calc(13pt + 2px);
63 | font-size: 13pt;
64 | }
65 |
66 | .btn-reg, .btn-reg:active {
67 | width: 15%;
68 | font-size: 13px;
69 | }
70 |
71 | /* Register values */
72 | /*.btn-reg-con, .btn-reg-con:active {
73 | width: 85%;
74 |
75 | font-size: 13px;
76 | font-weight:600;
77 | cursor: text;
78 | }*/
79 |
80 | .btn-flag, .btn-flag-con {
81 | font-size: 15px;
82 | }
83 |
84 | .btn-rep {
85 | background-color: white;
86 | font-size: 15px;
87 | }
88 |
89 | .btn-rep-enabled {
90 | background-color: darkgray;
91 | }
92 |
93 | .btn-view {
94 | width: 33.3%;
95 | }
96 |
97 | .clock {
98 | margin-left:20px;
99 | }
100 |
101 | .clock-symbol {
102 | font-size: 15px;
103 | padding-top:3px;
104 | padding-bottom:3px;
105 | padding-left: 5px;
106 | padding-right: 5px;
107 | }
108 |
109 | .clock-time {
110 | font-size:15px;
111 | padding-top:3px;
112 | padding-bottom:3px;
113 | }
114 |
115 | .dashboard {
116 | position: relative;
117 | overflow: hidden;
118 | }
119 |
120 | .editor {
121 | height: calc(100% - 26px);
122 | width: 100%;
123 | }
124 |
125 | .viewer {
126 | position: fixed;
127 | top: 76px;
128 | padding-top: 5px;
129 | left: calc( 100vw - var(--dashboard-width));
130 | overflow-y: auto;
131 | height: calc( 100vh - 95px);
132 | background-color: lightgrey;
133 | padding-bottom: 30px; /* Allow scrolling slightly beyond the end */
134 | }
135 |
136 | .invisible {
137 | display: none !important;
138 | }
139 |
140 | .btn-byte-active {
141 | background-color: darkgray;
142 | }
143 |
144 | .th-mem {
145 | background-color: darkgray;
146 | color: white;
147 | }
148 |
149 |
150 | .tabs-files {
151 | background-color: lightgray;
152 | width: 100%;
153 | height: 27px;
154 | overflow: hidden;
155 | }
156 |
157 | .tab-file {
158 | max-width: 200px;
159 | overflow: hidden;
160 | }
161 |
162 | .tab-file-name {
163 | width: 20px;
164 | text-overflow: ellipsis;
165 | }
166 |
167 | .settings-menu {
168 | max-width: 36em;
169 | display: inline-block;
170 | background-color: lightgrey;
171 | text-align: left;
172 | padding-left: 1.25em;
173 | overflow: auto;
174 | animation: fadein 0.5s;
175 | }
176 |
177 | .file-view-pane {
178 | text-align: center;
179 | height: 100%;
180 | overflow: hidden;
181 | background-color: black;
182 | }
183 |
184 | .monaco-editor {
185 | text-align: left;
186 | /*-webkit-font-smoothing: antialiased;*/
187 |
188 | }
189 |
190 |
191 | .settings-select {
192 | max-width: 13em;
193 | font-size: 12px;
194 | border-width: 1px;
195 | border-color: grey;
196 | }
197 | .settings-input {
198 | font-size: 12px;
199 | text-indent: 0.75em;
200 | border-width: 1px;
201 | border-radius: 4px;
202 | border-color: grey;
203 | }
204 |
205 |
206 | .settings-label {
207 | margin-bottom: 0px;
208 | margin-top: 10px;
209 | }
210 |
211 | .editor-line-highlight {
212 | font-weight: bolder;
213 | background-color: rgba(56, 76, 141, 0.5)
214 | /*text-decoration: underline;*/
215 | /* width: 5px !important;
216 | left: 3px; */
217 | }
218 |
219 | .editor-line-highlight-next {
220 | font-weight: bolder;
221 | background-color: rgba(6, 41, 155, 0.25)
222 | /*text-decoration: underline;*/
223 | /* width: 5px !important;
224 | left: 3px; */
225 | }
226 |
227 | .editor-line-highlight-error {
228 | font-weight: bolder;
229 | background-color: rgba(180, 29, 79,0.5)
230 | /*text-decoration: underline;*/
231 | /* width: 5px !important;
232 | left: 3px; */
233 | }
234 |
235 | .disabled-click {
236 | pointer-events: none;
237 | }
238 |
239 | .darken-overlay {
240 | position: absolute;
241 | background-color: rgba(255, 255, 255, 0.1);
242 | top: 0px;
243 | left: 0px;
244 | width: 100%;
245 | height: 100%;
246 | z-index: 10;
247 | }
248 |
249 | .editor-line-error {
250 | border-bottom: 2px dotted red;
251 | }
252 |
253 | .editor-glyph-margin-error {
254 | color: red;
255 |
256 | text-align:right;
257 | font-weight:bolder;
258 | }
259 |
260 | .editor-glyph-margin-error:after {
261 | content: "\26a0";
262 | }
263 |
264 | .editor-glyph-margin-arrow {
265 | color: darkgrey;
266 | text-align: right;
267 | }
268 |
269 | .editor-glyph-margin-arrow:after {
270 | content: "\2192"
271 | }
272 |
273 | .editor-glyph-margin-pointer {
274 | color: red;
275 | text-align: right;
276 | }
277 |
278 | .editor-glyph-margin-pointer:after {
279 | font-weight:bold;
280 | content: "\027ff"
281 | }
282 |
283 | .button-back:before {
284 | content: "\25c0"
285 | }
286 |
287 | .button-forward:after {
288 | content: "\25ba"
289 | }
290 |
291 |
292 |
293 | .status-bar {
294 | width: 200px;
295 | align-self: center;
296 | }
297 |
298 | .float-left {
299 | float: left;
300 | width:50%
301 | }
302 |
303 | div.after {
304 | clear: left;
305 | }
306 |
307 |
308 |
309 |
310 | /*-------------------------------------------------------------------------------------*/
311 | /*---------------------------pretty CSS tooltips for info buttons----------------------*/
312 | /*-based on tippy.js library https://github.com/atomiks/tippyjs/blob/master/README.md--*/
313 | /*-------------------------------------------------------------------------------------*/
314 |
315 | .tippy-popper[x-placement^=top] .tippy-tooltip.light-theme .tippy-arrow {
316 | border-top: 7px solid #fff;
317 | border-right: 7px solid transparent;
318 | border-left: 7px solid transparent
319 | }
320 |
321 | .tippy-popper[x-placement^=bottom] .tippy-tooltip.light-theme .tippy-arrow {
322 | border-bottom: 7px solid #fff;
323 | border-right: 7px solid transparent;
324 | border-left: 7px solid transparent
325 | }
326 |
327 | .tippy-popper[x-placement^=left] .tippy-tooltip.light-theme .tippy-arrow {
328 | border-left: 7px solid #fff;
329 | border-top: 7px solid transparent;
330 | border-bottom: 7px solid transparent
331 | }
332 |
333 | .tippy-popper[x-placement^=right] .tippy-tooltip.light-theme .tippy-arrow {
334 | border-right: 7px solid #fff;
335 | border-top: 7px solid transparent;
336 | border-bottom: 7px solid transparent
337 | }
338 |
339 | .tippy-tooltip.light-theme {
340 | color: #26323d;
341 | box-shadow: 0 0 20px 4px rgba(154,161,177,.15),0 4px 80px -8px rgba(36,40,47,.25),0 4px 4px -2px rgba(91,94,105,.15);
342 | background-color: #fff;
343 | border-style: solid;
344 | border-color: blue;
345 | }
346 |
347 | .tippy-tooltip.light-theme .tippy-backdrop {
348 | background-color: #fff
349 | }
350 |
351 | .tippy-tooltip.light-theme .tippy-roundarrow {
352 | fill: #fff
353 | }
354 |
355 | .tippy-tooltip.light-theme[data-animatefill] {
356 | background-color: transparent
357 | }
358 |
359 | .tippy-tooltip.dark-theme {
360 | border-style: solid;
361 | border-color: blue;
362 | }
363 |
364 |
365 | .tooltip-stack-regs-light-theme {
366 | margin-left: 2px;
367 | padding: 0px;
368 | color: blue;
369 | font-weight:bold;
370 | }
371 |
372 | .tooltip-stack-regs-dark-theme {
373 | margin-left: 2px;
374 | padding: 0px;
375 | color: lightblue;
376 | font-weight: bold;
377 | }
378 |
379 | .tootip-fixed {
380 | font-size: 12px;
381 | }
382 |
383 | .tooltip-shift-reg-box {
384 | stroke-width:0.2px;
385 | stroke:blue;
386 | fill: white;
387 | }
388 |
389 | .tooltip-shift-carry-box {
390 | stroke-width: 0.2px;
391 | stroke: red;
392 | fill: white;
393 | }
394 | .tooltip-shift-reg-txt {
395 | font-size:1.8px;
396 | fill: green;
397 | }
398 |
399 | .tooltip-shift-alu-txt {
400 | font-size: 5px;
401 | fill: blue;
402 | }
403 |
404 |
--------------------------------------------------------------------------------
/app/fonts/fira-code.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scc416/Visual2/9ebdcd84935acd724658c506acb4073c965ad9a5/app/fonts/fira-code.eot
--------------------------------------------------------------------------------
/app/fonts/fira-code.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scc416/Visual2/9ebdcd84935acd724658c506acb4073c965ad9a5/app/fonts/fira-code.ttf
--------------------------------------------------------------------------------
/app/fonts/fira-code.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scc416/Visual2/9ebdcd84935acd724658c506acb4073c965ad9a5/app/fonts/fira-code.woff
--------------------------------------------------------------------------------
/app/fonts/material-icons.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scc416/Visual2/9ebdcd84935acd724658c506acb4073c965ad9a5/app/fonts/material-icons.woff2
--------------------------------------------------------------------------------
/app/fonts/photon-entypo.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scc416/Visual2/9ebdcd84935acd724658c506acb4073c965ad9a5/app/fonts/photon-entypo.eot
--------------------------------------------------------------------------------
/app/fonts/photon-entypo.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scc416/Visual2/9ebdcd84935acd724658c506acb4073c965ad9a5/app/fonts/photon-entypo.ttf
--------------------------------------------------------------------------------
/app/fonts/photon-entypo.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scc416/Visual2/9ebdcd84935acd724658c506acb4073c965ad9a5/app/fonts/photon-entypo.woff
--------------------------------------------------------------------------------
/app/hovers/testhover.md:
--------------------------------------------------------------------------------
1 | # Test 0
2 |
3 | [testhover1.md](testhover1.md)
4 |
--------------------------------------------------------------------------------
/app/hovers/testhover1.md:
--------------------------------------------------------------------------------
1 | # Test 1
2 |
3 | [testhover.md](testhover.md)
4 |
--------------------------------------------------------------------------------
/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | VisUAL2
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/resources/errortest.html:
--------------------------------------------------------------------------------
1 | HTML test file
--------------------------------------------------------------------------------
/app/resources/visual.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scc416/Visual2/9ebdcd84935acd724658c506acb4073c965ad9a5/app/resources/visual.ico
--------------------------------------------------------------------------------
/app/test-data/ALLOWEDdp2ShiftsAll.txt:
--------------------------------------------------------------------------------
1 |
2 | --------------dp2Shifts:2909----------------
3 | Visual2 cannot parse test assembler
4 |
5 | Register Input Actual Out Model Out
6 | R0 2147483647 0 2147483647
7 | R1 2147483649 0 2147483649
8 | R2 4294967292 0 4294967292
9 | R3 4294967294 0 4294967294
10 | R4 2147483646 0 2147483646
11 | R5 4 0 4
12 | R6 4294967292 0 4294967292
13 | R7 2147483644 0 2147483644
14 | R8 3 0 3
15 | R9 2147483646 0 2147483646
16 | R10 1 0 1
17 | R11 2147483647 0 2147483647
18 | R12 2147483644 0 2147483644
19 | R13 4 4278190080 4
20 | R14 2147483647 0 2147483647
21 | Flag Before After Model
22 | N 0 0 1
23 | Z 1 0
24 | C 0 0
25 | V 1 0 1
26 |
27 | ---------ASM----------
28 | TEQ R3 , R7 ,LSL #32
29 | ----------------------------------
30 |
31 |
32 |
33 | --------------dp2Shifts:985----------------
34 | Visual2 cannot parse test assembler
35 |
36 | Register Input Actual Out Model Out
37 | R0 4294967294 0 4294967294
38 | R1 4 0 4
39 | R2 2147483647 0 2147483647
40 | R3 4 0 4
41 | R4 3 0 3
42 | R5 2147483651 0 2147483651
43 | R6 1 0 1
44 | R7 4294967293 0 4294967293
45 | R8 4294967294 0 4294967294
46 | R9 4294967294 0 4294967294
47 | R10 2147483649 0 2147483649
48 | R11 4 0
49 | R12 0 0
50 | R13 1 4278190080 1
51 | R14 2 0 2
52 | Flag Before After Model
53 | N 0 0
54 | Z 0 0 1
55 | C 0 0 1
56 | V 1 0 1
57 |
58 | ---------ASM----------
59 | MVNS R11, R10 , ASR #32
60 | ----------------------------------
61 |
62 |
63 |
64 | --------------dp2Shifts:24----------------
65 | Visual2 cannot parse test assembler
66 |
67 | Register Input Actual Out Model Out
68 | R0 4 0 4
69 | R1 2147483644 0 2147483644
70 | R2 1 0 1
71 | R3 2147483652 0 2147483652
72 | R4 2147483652 0 2147483652
73 | R5 2147483645 0 2147483645
74 | R6 2147483646 0 2147483646
75 | R7 4294967295 0 4294967295
76 | R8 4294967295 0 4294967295
77 | R9 2147483645 0 2147483645
78 | R10 2 0 2
79 | R11 2 0 2
80 | R12 2147483647 0
81 | R13 2147483648 4278190080 2147483648
82 | R14 2147483646 0 2147483646
83 | Flag Before After Model
84 | N 0 0
85 | Z 1 0 1
86 | C 0 0
87 | V 0 0
88 |
89 | ---------ASM----------
90 | MOV R12 , R3 , LSL #32
91 | ----------------------------------
92 |
93 |
94 |
95 | --------------dp2Shifts:246----------------
96 | Flags:
97 | {FN = true;
98 | FZ = false;
99 | FC = false;
100 | FV = true}
101 | do not match model flags
102 | {FN = true;
103 | FZ = false;
104 | FC = true;
105 | FV = true}
106 |
107 | Register Input Actual Out Model Out
108 | R0 32 32
109 | R1 2147483649 2147483649
110 | R2 2147483644 2147483644
111 | R3 3 3
112 | R4 2147483651 2147483651
113 | R5 3 3
114 | R6 2147483646 2147483646
115 | R7 2147483647 4294967292
116 | R8 2147483646 2147483646
117 | R9 1 1
118 | R10 2147483652 2147483652
119 | R11 2147483651 2147483651
120 | R12 4294967294 4294967294
121 | R13 2147483646 2147483646
122 | R14 2147483651 2147483651
123 | Flag Before After Model
124 | N 0 1
125 | Z 0 0
126 | C 1 0 1
127 | V 1 1
128 |
129 | ---------ASM----------
130 | MVNS R7 ,R3 , ROR R0
131 | ----------------------------------
132 |
133 |
--------------------------------------------------------------------------------
/app/test-data/ALLOWEDdp3ShiftsAll.txt:
--------------------------------------------------------------------------------
1 |
2 | --------------dp3Shifts:2615----------------
3 | Visual2 cannot parse test assembler
4 |
5 | Register Input Actual Out Model Out
6 | R0 4294967293 0 4294967293
7 | R1 2147483650 0 2147483650
8 | R2 2147483646 0 2147483646
9 | R3 4294967294 0 4294967294
10 | R4 2147483649 0 4294967293
11 | R5 2147483647 0 2147483647
12 | R6 1 0 1
13 | R7 3 0 3
14 | R8 2147483650 0 2147483650
15 | R9 3 0 3
16 | R10 2147483645 0 2147483645
17 | R11 2147483645 0 2147483645
18 | R12 4294967292 0 4294967292
19 | R13 4294967293 4278190080 4294967293
20 | R14 2147483648 0 2147483648
21 | Flag Before After Model
22 | N 0 0
23 | Z 1 0 1
24 | C 1 0 1
25 | V 0 0
26 |
27 | ---------ASM----------
28 | ADD R4 ,R0 ,R6 , LSR #32
29 | ----------------------------------
30 |
31 |
32 |
33 | --------------dp3Shifts:2729----------------
34 | Visual2 cannot parse test assembler
35 |
36 | Register Input Actual Out Model Out
37 | R0 4294967295 0 4294967295
38 | R1 4294967292 0 4294967292
39 | R2 1 0 1
40 | R3 2147483649 0 2147483649
41 | R4 4 0 4
42 | R5 4294967293 0 4294967293
43 | R6 2147483649 0 2147483649
44 | R7 3 0 3
45 | R8 2147483651 0 2147483651
46 | R9 2 0 2
47 | R10 4294967294 0 4294967294
48 | R11 2147483651 0 2147483651
49 | R12 1 0
50 | R13 2147483646 4278190080 2147483646
51 | R14 2147483645 0 2147483645
52 | Flag Before After Model
53 | N 1 0 1
54 | Z 0 0
55 | C 0 0
56 | V 1 0 1
57 |
58 | ---------ASM----------
59 | SBC R12 ,R12,R10 , LSL #32
60 | ----------------------------------
61 |
62 |
63 |
64 | --------------dp3Shifts:1833----------------
65 | Visual2 cannot parse test assembler
66 |
67 | Register Input Actual Out Model Out
68 | R0 2147483644 0 2147483644
69 | R1 2147483648 0 2147483648
70 | R2 2147483651 0 2147483651
71 | R3 4294967295 0 2147483653
72 | R4 3 0 3
73 | R5 4294967294 0 4294967294
74 | R6 4 0 4
75 | R7 4294967293 0 4294967293
76 | R8 2147483650 0 2147483650
77 | R9 4294967292 0 4294967292
78 | R10 4294967293 0 4294967293
79 | R11 4294967292 0 4294967292
80 | R12 4294967293 0 4294967293
81 | R13 2147483644 4278190080 2147483644
82 | R14 2147483648 0 2147483648
83 | Flag Before After Model
84 | N 0 0 1
85 | Z 1 0
86 | C 1 0
87 | V 1 0
88 |
89 | ---------ASM----------
90 | RSCS R3 ,R12,R8 ,ROR #32
91 | ----------------------------------
92 |
93 |
94 |
95 | --------------dp3Shifts:1322----------------
96 | Visual2 cannot parse test assembler
97 |
98 | Register Input Actual Out Model Out
99 | R0 2147483649 0 2147483649
100 | R1 2147483647 0 2147483647
101 | R2 4294967293 0 4294967293
102 | R3 4294967293 0 4294967293
103 | R4 4294967295 0 4294967295
104 | R5 2 0 2
105 | R6 2147483649 0 2147483649
106 | R7 4 0 4
107 | R8 2147483650 0 2147483650
108 | R9 2147483651 0 2147483651
109 | R10 2147483650 0 2147483650
110 | R11 3 0 3
111 | R12 2147483650 0 2147483650
112 | R13 2147483648 4278190080 2147483648
113 | R14 2 0 2
114 | Flag Before After Model
115 | N 0 0
116 | Z 0 0
117 | C 1 0 1
118 | V 0 0
119 |
120 | ---------ASM----------
121 | ADD R2 ,R3 ,R6 ,LSL #32
122 | ----------------------------------
123 |
124 |
125 |
126 | --------------dp3Shifts:637----------------
127 | Visual2 cannot parse test assembler
128 |
129 | Register Input Actual Out Model Out
130 | R0 2147483645 0 2147483645
131 | R1 2147483652 0 2147483652
132 | R2 2147483648 0 2147483648
133 | R3 2147483650 0 2147483644
134 | R4 2147483647 0 2147483647
135 | R5 3 0 3
136 | R6 2147483648 0 2147483648
137 | R7 2147483652 0 2147483652
138 | R8 2147483652 0 2147483652
139 | R9 2147483644 0 2147483644
140 | R10 2147483648 0 2147483648
141 | R11 4 0 4
142 | R12 2 0 2
143 | R13 2147483648 4278190080 2147483648
144 | R14 0 0
145 | Flag Before After Model
146 | N 0 0
147 | Z 1 0
148 | C 0 0
149 | V 1 0 1
150 |
151 | ---------ASM----------
152 | BICS R3,R9, R3 ,LSL #32
153 | ----------------------------------
154 |
155 |
156 |
157 | --------------dp3Shifts:931----------------
158 | Visual2 cannot parse test assembler
159 |
160 | Register Input Actual Out Model Out
161 | R0 2147483645 0 2147483645
162 | R1 2147483647 0 2147483647
163 | R2 2147483645 0 2147483645
164 | R3 3 0 3
165 | R4 2147483650 0 2147483650
166 | R5 0 0
167 | R6 2147483645 0 2
168 | R7 2147483652 0 2147483652
169 | R8 2147483652 0 2147483652
170 | R9 2 0 2
171 | R10 2147483647 0 2147483647
172 | R11 2147483644 0 2147483644
173 | R12 4294967293 0 4294967293
174 | R13 0 4278190080 0
175 | R14 2 0 2
176 | Flag Before After Model
177 | N 0 0
178 | Z 1 0 1
179 | C 1 0 1
180 | V 1 0 1
181 |
182 | ---------ASM----------
183 | EOR R6,R1 ,R0 , ROR #32
184 | ----------------------------------
185 |
186 |
--------------------------------------------------------------------------------
/app/test-data/ComputedBranchesAll.txt:
--------------------------------------------------------------------------------
1 | ComputedBranches:0
2 | Regs 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xff000000 0x0
3 | NZCV 0 0 0 0
4 | ...
5 | MOV R0, #0
6 | ADR R1, TARGET
7 | ADR R2, TARGETADDR
8 | MOV PC, R1
9 | ADD R0, R0, #1
10 | ADD R0, R0, #1
11 | TARGET ADD R0, R0, #1
12 | ADD R0, R0, #1
13 | ADD R0, R0, #1
14 | LDR R3, [R2]
15 | TARGETADDR DCD TARGET
16 |
17 | ...
18 | Regs 0x3 0x18 0x200 0x18 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xff000000 0x0
19 | NZCV 0 0 0 0
20 |
21 | ComputedBranches:7
22 | Regs 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xff000000 0x0
23 | NZCV 0 0 0 0
24 | ...
25 | MOV R0, #0
26 | ADR R1, TARGET
27 | ADR R2, TARGETADDR
28 | MOV R1, PC
29 | ADD R0, R0, #1
30 | ADD R0, R0, #1
31 | TARGET ADD R0, R0, #1
32 | ADD R0, R0, #1
33 | ADD R0, R0, #1
34 | LDR R3, [R2]
35 | TARGETADDR DCD TARGET
36 |
37 | ...
38 | Regs 0x5 0x14 0x200 0x18 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xff000000 0x0
39 | NZCV 0 0 0 0
40 |
41 | ComputedBranches:14
42 | Regs 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xff000000 0x0
43 | NZCV 0 0 0 0
44 | ...
45 | MOV R0, #0
46 | ADR R1, TARGET
47 | ADR R2, TARGETADDR
48 | LDR PC, [R2]
49 | ADD R0, R0, #1
50 | ADD R0, R0, #1
51 | TARGET ADD R0, R0, #1
52 | ADD R0, R0, #1
53 | ADD R0, R0, #1
54 | LDR R3, [R2]
55 | TARGETADDR DCD TARGET
56 |
57 | ...
58 | Regs 0x3 0x18 0x200 0x18 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xff000000 0x0
59 | NZCV 0 0 0 0
60 |
61 | ComputedBranches:21
62 | Regs 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xff000000 0x0
63 | NZCV 0 0 0 0
64 | ...
65 | MOV R0, #0
66 | ADR R1, TARGET
67 | ADR R2, TARGETADDR
68 | STR PC, [R2]
69 | ADD R0, R0, #1
70 | ADD R0, R0, #1
71 | TARGET ADD R0, R0, #1
72 | ADD R0, R0, #1
73 | ADD R0, R0, #1
74 | LDR R3, [R2]
75 | TARGETADDR DCD TARGET
76 |
77 | ...
78 | Regs 0x5 0x18 0x200 0x14 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xff000000 0x0
79 | NZCV 0 0 0 0
80 |
81 | ComputedBranches:28
82 | Regs 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xff000000 0x0
83 | NZCV 0 0 0 0
84 | ...
85 | MOV R0, #0
86 | ADR R1, TARGET
87 | ADR R2, TARGETADDR
88 | BL TARGET
89 | ADD R0, R0, #1
90 | ADD R0, R0, #1
91 | TARGET ADD R0, R0, #1
92 | ADD R0, R0, #1
93 | ADD R0, R0, #1
94 | LDR R3, [R2]
95 | TARGETADDR DCD TARGET
96 |
97 | ...
98 | Regs 0x3 0x18 0x200 0x18 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xff000000 0x10
99 | NZCV 0 0 0 0
100 |
101 | ComputedBranches:35
102 | Regs 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xff000000 0x0
103 | NZCV 0 0 0 0
104 | ...
105 | MOV R0, #0
106 | ADR R1, TARGET
107 | ADR R2, TARGETADDR
108 | LDR R4, =TARGET
109 | ADD R0, R0, #1
110 | ADD R0, R0, #1
111 | TARGET ADD R0, R0, #1
112 | ADD R0, R0, #1
113 | ADD R0, R0, #1
114 | LDR R3, [R2]
115 | TARGETADDR DCD TARGET
116 |
117 | ...
118 | Regs 0x5 0x18 0x200 0x18 0x18 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xff000000 0x0
119 | NZCV 0 0 0 0
120 |
121 |
--------------------------------------------------------------------------------
/app/test-data/MiscInstrAll.txt:
--------------------------------------------------------------------------------
1 | MiscInstr:0
2 | Regs 0xc024988f 0x78df0399 0x7da72974 0x38781155 0xfb7e320d 0xa3eb489 0xc1128f3b 0x8291f43a 0x9ceaec4a 0xd4577bf4 0x6b40616a 0xeecbec3c 0x530d8f5 0xc77bfbc5 0xc13841f
3 | NZCV 1 0 0 1
4 | ...
5 | ADR R0, DAT
6 | LDMIA R0, {R1-R6}
7 | LDR R7, =TESTEQU
8 | DAT DCD 0x12345678
9 | DAT1 DCB 3,4,5,6
10 | DAT2 DCB 12,13,14,15,16,17,18,19
11 | FILL 4
12 | DAT4 DCD 111
13 | TESTEQU EQU DAT+3
14 |
15 | ...
16 | Regs 0x200 0x12345678 0x6050403 0xf0e0d0c 0x13121110 0x0 0x6f 0x203 0x9ceaec4a 0xd4577bf4 0x6b40616a 0xeecbec3c 0x530d8f5 0xc77bfbc5 0xc13841f
17 | NZCV 1 0 0 1
18 |
19 |
--------------------------------------------------------------------------------
/app/test-results/BETTERsMemLoadsAll.txt:
--------------------------------------------------------------------------------
1 |
2 | --------------MemLoads:479----------------
3 | Visual2 runs when VisuAL gives an error?
4 |
5 | Error in model
6 |
7 | ---------ASM----------
8 | ADR R7,DAT3
9 | LDR R8 , [R7 ] !
10 | DAT1 DCD 3903273698, 4284496457 , 306311911 ,1918985881 ,4085875476,4291926900 , 2983300192 , 2864149368 , 504412359, 3397904698 , 4268198127 ,1832337063 , 2513551886 ,1190878507 ,3162465754 ,4169910742
11 | DAT2 DCD 2089993674 ,1053652447 ,2071577171, 1111845843 ,467073668 , 2008014362 , 1326458183, 1487078627 ,2633889794 ,31061921,3345259356 , 1455447991 , 3450519736 ,2759282738,2884310325, 2853801390
12 | DAT3 DCD 2324248059 ,518188039 ,1301492952, 4160707516 , 1988189876, 3445883875 ,289443612, 4019679370 ,1768571416 , 3224290428,1677787370 ,41083189, 1862917909 , 2822027969 ,501019155,3219654304
13 | DAT4 DCD 1349184000 , 1402018069, 107244700 , 3075434533 , 239133 , 2166319280 ,3455603421 , 1316437646,3508548589 , 3871828434 ,1426515357 ,699238814 , 864632236, 2096983677, 2359508285 , 1038124142
14 | ----------------------------------
15 |
16 |
17 |
18 | --------------MemLoads:400----------------
19 | Visual2 runs when VisuAL gives an error?
20 |
21 | Error in model
22 |
23 | ---------ASM----------
24 | ADR R7 , DAT3
25 | LDRB R8 ,[ R7 ] !
26 | DAT1 DCD 3903273698 , 4284496457 ,306311911, 1918985881 , 4085875476,4291926900,2983300192, 2864149368, 504412359 , 3397904698 ,4268198127,1832337063 ,2513551886 , 1190878507 , 3162465754 ,4169910742
27 | DAT2 DCD 2089993674, 1053652447, 2071577171 , 1111845843 , 467073668, 2008014362 , 1326458183 , 1487078627 , 2633889794,31061921 , 3345259356, 1455447991 ,3450519736 , 2759282738 ,2884310325 , 2853801390
28 | DAT3 DCD 2324248059 , 518188039 , 1301492952 , 4160707516, 1988189876 ,3445883875 , 289443612, 4019679370 , 1768571416 , 3224290428 ,1677787370 ,41083189 ,1862917909 , 2822027969,501019155, 3219654304
29 | DAT4 DCD 1349184000 , 1402018069 , 107244700 , 3075434533 , 239133 ,2166319280 , 3455603421 , 1316437646, 3508548589 , 3871828434 , 1426515357 ,699238814 ,864632236 ,2096983677, 2359508285 , 1038124142
30 | ----------------------------------
31 |
32 |
33 |
34 | --------------MemLoads:243----------------
35 | Visual2 runs when VisuAL gives an error?
36 |
37 | Error in model
38 |
39 | ---------ASM----------
40 | ADR R7, DAT3
41 | LDRB R8 , [R7 ] !
42 | DAT1 DCD 3903273698 ,4284496457 ,306311911 ,1918985881, 4085875476, 4291926900, 2983300192 , 2864149368 , 504412359, 3397904698 ,4268198127 ,1832337063 , 2513551886 ,1190878507 ,3162465754, 4169910742
43 | DAT2 DCD 2089993674, 1053652447 , 2071577171, 1111845843,467073668 , 2008014362 ,1326458183 ,1487078627 , 2633889794 , 31061921 , 3345259356, 1455447991 , 3450519736, 2759282738 , 2884310325,2853801390
44 | DAT3 DCD 2324248059 ,518188039 , 1301492952, 4160707516 , 1988189876, 3445883875 ,289443612,4019679370 , 1768571416, 3224290428 , 1677787370 ,41083189, 1862917909 , 2822027969 , 501019155 ,3219654304
45 | DAT4 DCD 1349184000 ,1402018069, 107244700, 3075434533,239133 , 2166319280, 3455603421 , 1316437646, 3508548589 ,3871828434 , 1426515357 , 699238814 , 864632236 , 2096983677,2359508285,1038124142
46 | ----------------------------------
47 |
48 |
49 |
50 | --------------MemLoads:321----------------
51 | Visual2 runs when VisuAL gives an error?
52 |
53 | Error in model
54 |
55 | ---------ASM----------
56 | ADR R7 ,DAT3
57 | LDR R8 ,[R7] !
58 | DAT1 DCD 3903273698 ,4284496457 , 306311911 , 1918985881 , 4085875476, 4291926900,2983300192 , 2864149368,504412359 ,3397904698 ,4268198127 , 1832337063, 2513551886 ,1190878507 , 3162465754, 4169910742
59 | DAT2 DCD 2089993674 , 1053652447,2071577171 ,1111845843 ,467073668, 2008014362, 1326458183,1487078627, 2633889794, 31061921, 3345259356,1455447991 , 3450519736 , 2759282738 ,2884310325 , 2853801390
60 | DAT3 DCD 2324248059 , 518188039 , 1301492952 , 4160707516 ,1988189876, 3445883875,289443612 , 4019679370 , 1768571416 , 3224290428, 1677787370 , 41083189 , 1862917909, 2822027969 ,501019155 ,3219654304
61 | DAT4 DCD 1349184000,1402018069 , 107244700 , 3075434533 , 239133, 2166319280,3455603421 , 1316437646, 3508548589,3871828434 , 1426515357 , 699238814 , 864632236,2096983677 , 2359508285, 1038124142
62 | ----------------------------------
63 |
64 |
65 |
66 | --------------MemLoads:164----------------
67 | Visual2 runs when VisuAL gives an error?
68 |
69 | Error in model
70 |
71 | ---------ASM----------
72 | ADR R7 , DAT3
73 | LDR R8,[ R7 ] !
74 | DAT1 DCD 3903273698 ,4284496457, 306311911, 1918985881 ,4085875476, 4291926900, 2983300192 , 2864149368 , 504412359 , 3397904698 , 4268198127 ,1832337063 , 2513551886, 1190878507 ,3162465754, 4169910742
75 | DAT2 DCD 2089993674, 1053652447 , 2071577171 ,1111845843 ,467073668 , 2008014362,1326458183 , 1487078627 , 2633889794, 31061921,3345259356 , 1455447991 , 3450519736 , 2759282738,2884310325, 2853801390
76 | DAT3 DCD 2324248059 , 518188039 , 1301492952 , 4160707516 , 1988189876 , 3445883875 ,289443612, 4019679370 , 1768571416 ,3224290428,1677787370 , 41083189, 1862917909 ,2822027969 ,501019155 , 3219654304
77 | DAT4 DCD 1349184000, 1402018069,107244700 , 3075434533 ,239133,2166319280,3455603421 , 1316437646, 3508548589 , 3871828434, 1426515357 , 699238814 , 864632236 , 2096983677 , 2359508285 , 1038124142
78 | ----------------------------------
79 |
80 |
81 |
82 | --------------MemLoads:85----------------
83 | Visual2 runs when VisuAL gives an error?
84 |
85 | Error in model
86 |
87 | ---------ASM----------
88 | ADR R7 ,DAT3
89 | LDRB R8 ,[ R7] !
90 | DAT1 DCD 3903273698 ,4284496457 , 306311911 , 1918985881 , 4085875476 ,4291926900 , 2983300192 , 2864149368 , 504412359 ,3397904698, 4268198127 , 1832337063 , 2513551886 , 1190878507 , 3162465754 , 4169910742
91 | DAT2 DCD 2089993674 , 1053652447 , 2071577171 , 1111845843 , 467073668 ,2008014362 , 1326458183 , 1487078627 , 2633889794, 31061921 ,3345259356 , 1455447991 , 3450519736, 2759282738 ,2884310325,2853801390
92 | DAT3 DCD 2324248059, 518188039, 1301492952 ,4160707516,1988189876, 3445883875, 289443612 , 4019679370, 1768571416 , 3224290428 , 1677787370, 41083189 , 1862917909, 2822027969 , 501019155 , 3219654304
93 | DAT4 DCD 1349184000 , 1402018069, 107244700 , 3075434533,239133 ,2166319280 , 3455603421 , 1316437646, 3508548589 , 3871828434,1426515357 , 699238814,864632236, 2096983677 , 2359508285 , 1038124142
94 | ----------------------------------
95 |
96 |
97 |
98 | --------------MemLoads:6----------------
99 | Visual2 runs when VisuAL gives an error?
100 |
101 | Error in model
102 |
103 | ---------ASM----------
104 | ADR R7, DAT3
105 | LDR R8,[ R7 ] !
106 | DAT1 DCD 3903273698 ,4284496457 , 306311911 ,1918985881 , 4085875476,4291926900, 2983300192 ,2864149368 ,504412359 ,3397904698 , 4268198127 , 1832337063 ,2513551886 , 1190878507 ,3162465754 ,4169910742
107 | DAT2 DCD 2089993674, 1053652447 , 2071577171 ,1111845843 ,467073668, 2008014362,1326458183, 1487078627 , 2633889794 , 31061921 , 3345259356, 1455447991, 3450519736 , 2759282738,2884310325 , 2853801390
108 | DAT3 DCD 2324248059, 518188039 , 1301492952 , 4160707516 ,1988189876,3445883875 ,289443612,4019679370 , 1768571416 , 3224290428,1677787370 , 41083189 , 1862917909, 2822027969 ,501019155 , 3219654304
109 | DAT4 DCD 1349184000 ,1402018069 ,107244700 ,3075434533 , 239133, 2166319280 ,3455603421 , 1316437646 , 3508548589, 3871828434, 1426515357 ,699238814, 864632236 , 2096983677 ,2359508285 , 1038124142
110 | ----------------------------------
111 |
112 |
--------------------------------------------------------------------------------
/app/test-results/BETTERsMemStoresAll.txt:
--------------------------------------------------------------------------------
1 |
2 | --------------MemStores:479----------------
3 | Visual2 runs when VisuAL gives an error?
4 |
5 | Error in model
6 |
7 | ---------ASM----------
8 | ADR R11 , DAT3
9 | STR R9 , [ R11] !
10 | ; **** CheckSum in R1 ***
11 | ADR R3, DAT1+0x100
12 | MOV R1, #0
13 | CHECKLOOP LDR R12, [R3,#-4]!
14 | ADD R1, R1, R12
15 | ADR R12, DAT1
16 | CMP R3,R12
17 | BNE CHECKLOOP
18 | DAT1 DCD 1780874446, 2328385545 , 3296312804 , 2143984065 , 322772012 ,2426300838 ,3919636974 ,189486613, 2979621581 ,3226716658,3851208888 ,4020193489, 3682714309 , 1748827312 , 3387164468 , 2674075447
19 | DAT2 DCD 50657950, 3385321977 ,3741973757 , 555969480 ,164927943, 711942353, 3722388221 , 1402754033, 2032355510 ,355092652,1726771607,4042695021,221135350 , 2089222580, 1437041433,3487370249
20 | DAT3 DCD 2093508966 ,1721954050, 539369809 , 1997255836 , 1235833994 , 3223210948, 2655555278 , 1794291844 ,1864897610 ,2207088942 ,4060698295 ,3226177900 , 161949786 , 3704331539, 2155159407 , 371295930
21 | DAT4 DCD 3387498086, 3825759353, 3160040602,868898769, 3517603982, 4278325857 , 2977539377 , 52723296 , 3607413763 , 2458599772 , 4287319727 , 436151824 , 2837108022,3847944140, 1149688312 , 874981946
22 | ----------------------------------
23 |
24 |
25 |
26 | --------------MemStores:400----------------
27 | Visual2 runs when VisuAL gives an error?
28 |
29 | Error in model
30 |
31 | ---------ASM----------
32 | ADR R11, DAT3
33 | STRB R9 , [R11] !
34 | ; **** CheckSum in R1 ***
35 | ADR R3, DAT1+0x100
36 | MOV R1, #0
37 | CHECKLOOP LDR R12, [R3,#-4]!
38 | ADD R1, R1, R12
39 | ADR R12, DAT1
40 | CMP R3,R12
41 | BNE CHECKLOOP
42 | DAT1 DCD 1780874446 , 2328385545 ,3296312804 , 2143984065 , 322772012 , 2426300838 , 3919636974 ,189486613 , 2979621581 ,3226716658, 3851208888 , 4020193489, 3682714309, 1748827312 , 3387164468 , 2674075447
43 | DAT2 DCD 50657950 , 3385321977 , 3741973757 , 555969480 , 164927943, 711942353 , 3722388221, 1402754033 , 2032355510 , 355092652, 1726771607, 4042695021 ,221135350 , 2089222580 , 1437041433 , 3487370249
44 | DAT3 DCD 2093508966 , 1721954050 , 539369809 , 1997255836 , 1235833994, 3223210948, 2655555278 , 1794291844 , 1864897610 , 2207088942, 4060698295 , 3226177900 , 161949786,3704331539 , 2155159407 , 371295930
45 | DAT4 DCD 3387498086 , 3825759353 , 3160040602, 868898769 , 3517603982, 4278325857, 2977539377 , 52723296 ,3607413763 , 2458599772 ,4287319727 ,436151824, 2837108022 ,3847944140 ,1149688312, 874981946
46 | ----------------------------------
47 |
48 |
49 |
50 | --------------MemStores:243----------------
51 | Visual2 runs when VisuAL gives an error?
52 |
53 | Error in model
54 |
55 | ---------ASM----------
56 | ADR R11,DAT3
57 | STRB R9 , [R11 ]!
58 | ; **** CheckSum in R1 ***
59 | ADR R3, DAT1+0x100
60 | MOV R1, #0
61 | CHECKLOOP LDR R12, [R3,#-4]!
62 | ADD R1, R1, R12
63 | ADR R12, DAT1
64 | CMP R3,R12
65 | BNE CHECKLOOP
66 | DAT1 DCD 1780874446 , 2328385545 , 3296312804 , 2143984065,322772012 , 2426300838 ,3919636974 , 189486613, 2979621581 , 3226716658, 3851208888, 4020193489 , 3682714309 , 1748827312, 3387164468, 2674075447
67 | DAT2 DCD 50657950 ,3385321977, 3741973757 , 555969480 , 164927943 ,711942353 , 3722388221 , 1402754033 , 2032355510,355092652, 1726771607, 4042695021, 221135350 , 2089222580,1437041433 , 3487370249
68 | DAT3 DCD 2093508966 ,1721954050 ,539369809 , 1997255836 , 1235833994 ,3223210948 , 2655555278 ,1794291844 ,1864897610,2207088942 , 4060698295 , 3226177900 ,161949786 ,3704331539 , 2155159407,371295930
69 | DAT4 DCD 3387498086, 3825759353, 3160040602, 868898769, 3517603982 , 4278325857 , 2977539377, 52723296 , 3607413763,2458599772 , 4287319727 ,436151824,2837108022 , 3847944140 , 1149688312, 874981946
70 | ----------------------------------
71 |
72 |
73 |
74 | --------------MemStores:321----------------
75 | Visual2 runs when VisuAL gives an error?
76 |
77 | Error in model
78 |
79 | ---------ASM----------
80 | ADR R11 , DAT3
81 | STR R9,[ R11]!
82 | ; **** CheckSum in R1 ***
83 | ADR R3, DAT1+0x100
84 | MOV R1, #0
85 | CHECKLOOP LDR R12, [R3,#-4]!
86 | ADD R1, R1, R12
87 | ADR R12, DAT1
88 | CMP R3,R12
89 | BNE CHECKLOOP
90 | DAT1 DCD 1780874446 , 2328385545, 3296312804 ,2143984065 , 322772012 , 2426300838 ,3919636974, 189486613, 2979621581,3226716658 ,3851208888,4020193489,3682714309,1748827312 , 3387164468 , 2674075447
91 | DAT2 DCD 50657950 , 3385321977 , 3741973757 , 555969480, 164927943 , 711942353, 3722388221 , 1402754033, 2032355510 , 355092652 , 1726771607 ,4042695021 , 221135350 , 2089222580 , 1437041433 , 3487370249
92 | DAT3 DCD 2093508966 , 1721954050 ,539369809 , 1997255836 , 1235833994,3223210948, 2655555278 , 1794291844 , 1864897610 ,2207088942 , 4060698295,3226177900 , 161949786 , 3704331539 , 2155159407, 371295930
93 | DAT4 DCD 3387498086, 3825759353 , 3160040602, 868898769, 3517603982 , 4278325857, 2977539377 , 52723296 ,3607413763 , 2458599772, 4287319727 ,436151824 , 2837108022 ,3847944140 , 1149688312 , 874981946
94 | ----------------------------------
95 |
96 |
97 |
98 | --------------MemStores:164----------------
99 | Visual2 runs when VisuAL gives an error?
100 |
101 | Error in model
102 |
103 | ---------ASM----------
104 | ADR R11 , DAT3
105 | STR R9 ,[ R11 ] !
106 | ; **** CheckSum in R1 ***
107 | ADR R3, DAT1+0x100
108 | MOV R1, #0
109 | CHECKLOOP LDR R12, [R3,#-4]!
110 | ADD R1, R1, R12
111 | ADR R12, DAT1
112 | CMP R3,R12
113 | BNE CHECKLOOP
114 | DAT1 DCD 1780874446, 2328385545, 3296312804, 2143984065 , 322772012 , 2426300838, 3919636974, 189486613 , 2979621581 , 3226716658 , 3851208888 , 4020193489 , 3682714309 , 1748827312 , 3387164468, 2674075447
115 | DAT2 DCD 50657950 ,3385321977 , 3741973757 ,555969480,164927943, 711942353 ,3722388221 , 1402754033, 2032355510, 355092652 , 1726771607 ,4042695021,221135350 ,2089222580 , 1437041433,3487370249
116 | DAT3 DCD 2093508966, 1721954050,539369809 ,1997255836 ,1235833994 , 3223210948, 2655555278, 1794291844, 1864897610 ,2207088942, 4060698295 , 3226177900, 161949786 , 3704331539 , 2155159407 ,371295930
117 | DAT4 DCD 3387498086 ,3825759353, 3160040602, 868898769, 3517603982,4278325857,2977539377 ,52723296 ,3607413763 , 2458599772 ,4287319727 , 436151824 , 2837108022 , 3847944140 , 1149688312 , 874981946
118 | ----------------------------------
119 |
120 |
121 |
122 | --------------MemStores:85----------------
123 | Visual2 runs when VisuAL gives an error?
124 |
125 | Error in model
126 |
127 | ---------ASM----------
128 | ADR R11 ,DAT3
129 | STRB R9,[ R11 ] !
130 | ; **** CheckSum in R1 ***
131 | ADR R3, DAT1+0x100
132 | MOV R1, #0
133 | CHECKLOOP LDR R12, [R3,#-4]!
134 | ADD R1, R1, R12
135 | ADR R12, DAT1
136 | CMP R3,R12
137 | BNE CHECKLOOP
138 | DAT1 DCD 1780874446, 2328385545 , 3296312804 ,2143984065 , 322772012,2426300838 , 3919636974 ,189486613,2979621581 ,3226716658 ,3851208888 ,4020193489 , 3682714309 , 1748827312, 3387164468 , 2674075447
139 | DAT2 DCD 50657950 , 3385321977 ,3741973757 , 555969480 ,164927943,711942353 ,3722388221 ,1402754033 , 2032355510 , 355092652 , 1726771607 , 4042695021, 221135350 ,2089222580, 1437041433,3487370249
140 | DAT3 DCD 2093508966, 1721954050, 539369809 ,1997255836 , 1235833994 , 3223210948 , 2655555278 , 1794291844 ,1864897610,2207088942 , 4060698295 ,3226177900 , 161949786 , 3704331539 , 2155159407, 371295930
141 | DAT4 DCD 3387498086 , 3825759353 ,3160040602,868898769, 3517603982 ,4278325857 , 2977539377 , 52723296 ,3607413763,2458599772 , 4287319727 ,436151824 , 2837108022 , 3847944140 , 1149688312,874981946
142 | ----------------------------------
143 |
144 |
145 |
146 | --------------MemStores:6----------------
147 | Visual2 runs when VisuAL gives an error?
148 |
149 | Error in model
150 |
151 | ---------ASM----------
152 | ADR R11 , DAT3
153 | STR R9 , [ R11 ] !
154 | ; **** CheckSum in R1 ***
155 | ADR R3, DAT1+0x100
156 | MOV R1, #0
157 | CHECKLOOP LDR R12, [R3,#-4]!
158 | ADD R1, R1, R12
159 | ADR R12, DAT1
160 | CMP R3,R12
161 | BNE CHECKLOOP
162 | DAT1 DCD 1780874446 ,2328385545 , 3296312804,2143984065 , 322772012 ,2426300838, 3919636974, 189486613 , 2979621581 , 3226716658, 3851208888 ,4020193489, 3682714309 , 1748827312 , 3387164468 , 2674075447
163 | DAT2 DCD 50657950 , 3385321977 ,3741973757 ,555969480, 164927943 ,711942353, 3722388221 , 1402754033,2032355510 ,355092652, 1726771607, 4042695021 ,221135350, 2089222580 ,1437041433 ,3487370249
164 | DAT3 DCD 2093508966 , 1721954050 ,539369809 , 1997255836 , 1235833994 , 3223210948 , 2655555278 ,1794291844 , 1864897610 ,2207088942 , 4060698295 ,3226177900 , 161949786 ,3704331539 , 2155159407 , 371295930
165 | DAT4 DCD 3387498086, 3825759353 ,3160040602, 868898769 , 3517603982 ,4278325857 , 2977539377 , 52723296 , 3607413763 ,2458599772, 4287319727 ,436151824, 2837108022 , 3847944140 , 1149688312,874981946
166 | ----------------------------------
167 |
168 |
--------------------------------------------------------------------------------
/app/test-results/ERRORsMemLoadsAll.txt:
--------------------------------------------------------------------------------
1 |
2 | --------------MemLoads:388----------------
3 | Visual2 cannot parse test assembler
4 |
5 | Register Input Actual Out Model Out
6 | R0 1209282684 0 1209282684
7 | R1 393019475 0 393019475
8 | R2 2682578044 0 2682578044
9 | R3 2407440921 0 2407440921
10 | R4 2 0 2
11 | R5 283353208 0 283353208
12 | R6 4235107966 0 4235107966
13 | R7 2097705640 0 643
14 | R8 1349770796 0 2324248059
15 | R9 2025503319 0 2025503319
16 | R10 3024480132 0 3024480132
17 | R11 4039134891 0 4039134891
18 | R12 2443241327 0 2443241327
19 | R13 156803353 4278190080 156803353
20 | R14 1291646335 0 1291646335
21 | Flag Before After Model
22 | N 1 0 1
23 | Z 0 0
24 | C 1 0 1
25 | V 0 0
26 |
27 | ---------ASM----------
28 | ADR R7, DAT3
29 | LDR R8,[ R7 ] , #0x3
30 | DAT1 DCD 3903273698 , 4284496457, 306311911,1918985881,4085875476,4291926900,2983300192 , 2864149368 , 504412359 , 3397904698 , 4268198127 ,1832337063 , 2513551886 , 1190878507, 3162465754, 4169910742
31 | DAT2 DCD 2089993674 ,1053652447 , 2071577171 ,1111845843 , 467073668 , 2008014362 , 1326458183 ,1487078627 , 2633889794 ,31061921 , 3345259356, 1455447991 ,3450519736, 2759282738 , 2884310325, 2853801390
32 | DAT3 DCD 2324248059 ,518188039, 1301492952 , 4160707516,1988189876 , 3445883875 , 289443612, 4019679370, 1768571416 , 3224290428 ,1677787370 , 41083189,1862917909,2822027969 , 501019155 , 3219654304
33 | DAT4 DCD 1349184000 , 1402018069 , 107244700, 3075434533 , 239133, 2166319280 , 3455603421 , 1316437646, 3508548589, 3871828434 , 1426515357 ,699238814 , 864632236 ,2096983677 ,2359508285, 1038124142
34 | ----------------------------------
35 |
36 |
--------------------------------------------------------------------------------
/app/test-results/ERRORsMemStoresAll.txt:
--------------------------------------------------------------------------------
1 |
2 | --------------MemStores:230----------------
3 | Visual2 cannot parse test assembler
4 |
5 | Register Input Actual Out Model Out
6 | R0 4234037955 0 4234037955
7 | R1 473375332 0 748880547
8 | R2 926055158 0 926055158
9 | R3 2237691589 0 512
10 | R4 3829487160 0 3829487160
11 | R5 2252902908 0 2252902908
12 | R6 395102362 0 395102362
13 | R7 911580877 0 911580877
14 | R8 795843196 0 795843196
15 | R9 3185205050 0 3185205050
16 | R10 2 0 2
17 | R11 2473632534 0 639
18 | R12 945023029 0 512
19 | R13 960437613 4278190080 960437613
20 | R14 3971472291 0 3971472291
21 | Flag Before After Model
22 | N 0 0
23 | Z 0 0 1
24 | C 0 0 1
25 | V 0 0
26 |
27 | ---------ASM----------
28 | ADR R11 , DAT3
29 | STR R9 , [R11 ] , #0xffffffff
30 | ; **** CheckSum in R1 ***
31 | ADR R3, DAT1+0x100
32 | MOV R1, #0
33 | CHECKLOOP LDR R12, [R3,#-4]!
34 | ADD R1, R1, R12
35 | ADR R12, DAT1
36 | CMP R3,R12
37 | BNE CHECKLOOP
38 | DAT1 DCD 1780874446 , 2328385545,3296312804 , 2143984065 , 322772012 , 2426300838 , 3919636974 ,189486613 , 2979621581 , 3226716658 ,3851208888 ,4020193489,3682714309, 1748827312 , 3387164468,2674075447
39 | DAT2 DCD 50657950 ,3385321977 , 3741973757 ,555969480 ,164927943, 711942353 ,3722388221 ,1402754033, 2032355510, 355092652 , 1726771607, 4042695021 ,221135350 , 2089222580 ,1437041433 , 3487370249
40 | DAT3 DCD 2093508966 ,1721954050,539369809 ,1997255836 , 1235833994 , 3223210948 , 2655555278,1794291844 , 1864897610,2207088942 , 4060698295 , 3226177900 ,161949786, 3704331539, 2155159407 , 371295930
41 | DAT4 DCD 3387498086 , 3825759353 , 3160040602, 868898769 , 3517603982 ,4278325857 , 2977539377 ,52723296 , 3607413763, 2458599772 , 4287319727, 436151824, 2837108022 ,3847944140, 1149688312 , 874981946
42 | ----------------------------------
43 |
44 |
45 |
46 | --------------MemStores:72----------------
47 | Visual2 cannot parse test assembler
48 |
49 | Register Input Actual Out Model Out
50 | R0 2963348631 0 2963348631
51 | R1 4102862870 0 3284582859
52 | R2 360149278 0 360149278
53 | R3 4270874826 0 512
54 | R4 553611658 0 553611658
55 | R5 1874279578 0 1874279578
56 | R6 3862897032 0 3862897032
57 | R7 975347107 0 975347107
58 | R8 195976084 0 195976084
59 | R9 1425940066 0 1425940066
60 | R10 2 0 2
61 | R11 1028231749 0 635
62 | R12 1733850849 0 512
63 | R13 4282202758 4278190080 4282202758
64 | R14 2188650617 0 2188650617
65 | Flag Before After Model
66 | N 0 0
67 | Z 1 0 1
68 | C 1 0 1
69 | V 0 0
70 |
71 | ---------ASM----------
72 | ADR R11 , DAT3
73 | STR R9 , [ R11 ] , #0xfffffffb
74 | ; **** CheckSum in R1 ***
75 | ADR R3, DAT1+0x100
76 | MOV R1, #0
77 | CHECKLOOP LDR R12, [R3,#-4]!
78 | ADD R1, R1, R12
79 | ADR R12, DAT1
80 | CMP R3,R12
81 | BNE CHECKLOOP
82 | DAT1 DCD 1780874446, 2328385545,3296312804 , 2143984065 , 322772012 , 2426300838 , 3919636974 , 189486613, 2979621581, 3226716658 , 3851208888 ,4020193489 ,3682714309,1748827312 ,3387164468 , 2674075447
83 | DAT2 DCD 50657950 , 3385321977,3741973757 , 555969480,164927943 ,711942353 , 3722388221,1402754033 ,2032355510 , 355092652 ,1726771607, 4042695021 , 221135350 ,2089222580 ,1437041433,3487370249
84 | DAT3 DCD 2093508966 , 1721954050 , 539369809, 1997255836, 1235833994 , 3223210948,2655555278 , 1794291844, 1864897610 , 2207088942 , 4060698295 , 3226177900 , 161949786,3704331539 , 2155159407 ,371295930
85 | DAT4 DCD 3387498086,3825759353 ,3160040602, 868898769 , 3517603982 , 4278325857 , 2977539377 , 52723296 ,3607413763, 2458599772, 4287319727, 436151824 ,2837108022 , 3847944140, 1149688312 , 874981946
86 | ----------------------------------
87 |
88 |
--------------------------------------------------------------------------------
/app/test-results/ERRORsdp2ImmAll.txt:
--------------------------------------------------------------------------------
1 |
2 | --------------dp2Imm:545----------------
3 | Visual2 cannot parse test assembler
4 |
5 | Register Input Actual Out Model Out
6 | R0 2147483644 0 2147483644
7 | R1 3 0 3
8 | R2 4294967292 0 4294967292
9 | R3 2147483647 0 2147483647
10 | R4 2 0 2
11 | R5 4 0 4
12 | R6 4294967292 0 4294967292
13 | R7 4294967295 0 4294967295
14 | R8 2147483651 0 1073741802
15 | R9 2147483644 0 2147483644
16 | R10 4294967295 0 4294967295
17 | R11 4294967292 0 4294967292
18 | R12 3 0 3
19 | R13 2147483648 4278190080 2147483648
20 | R14 2147483647 0 2147483647
21 | Flag Before After Model
22 | N 1 0
23 | Z 0 0
24 | C 1 0 1
25 | V 0 0
26 |
27 | ---------ASM----------
28 | MVNS R8, #-1073741803
29 | ----------------------------------
30 |
31 |
32 |
33 | --------------dp2Imm:418----------------
34 | Flags:
35 | {FN = true;
36 | FZ = false;
37 | FC = false;
38 | FV = false}
39 | do not match model flags
40 | {FN = true;
41 | FZ = false;
42 | FC = true;
43 | FV = false}
44 |
45 | Register Input Actual Out Model Out
46 | R0 2 2
47 | R1 0 0
48 | R2 2147483647 2147483647
49 | R3 2147483651 2147483651
50 | R4 4 4
51 | R5 2147483650 2147483650
52 | R6 2147483652 2147483652
53 | R7 4294967293 4294773759
54 | R8 4294967295 4294967295
55 | R9 3 3
56 | R10 2147483649 2147483649
57 | R11 4 4
58 | R12 2 2
59 | R13 1 1
60 | R14 2147483652 2147483652
61 | Flag Before After Model
62 | N 0 1
63 | Z 0 0
64 | C 1 0 1
65 | V 0 0
66 |
67 | ---------ASM----------
68 | MVNS R7, #193536
69 | ----------------------------------
70 |
71 |
72 |
73 | --------------dp2Imm:303----------------
74 | Visual2 cannot parse test assembler
75 |
76 | Register Input Actual Out Model Out
77 | R0 4294967294 0 4294967294
78 | R1 2147483645 0 2147483645
79 | R2 4294967294 0 4294967294
80 | R3 2147483647 0 2147483647
81 | R4 2147483644 0 2147483644
82 | R5 3 0 1073741788
83 | R6 0 0
84 | R7 3 0 3
85 | R8 2 0 2
86 | R9 2 0 2
87 | R10 4 0 4
88 | R11 4294967295 0 4294967295
89 | R12 2147483644 0 2147483644
90 | R13 2147483648 4278190080 2147483648
91 | R14 2147483649 0 2147483649
92 | Flag Before After Model
93 | N 0 0
94 | Z 0 0
95 | C 0 0
96 | V 0 0
97 |
98 | ---------ASM----------
99 | MVN R5 ,#-1073741789
100 | ----------------------------------
101 |
102 |
103 |
104 | --------------dp2Imm:333----------------
105 | Flags:
106 | {FN = true;
107 | FZ = false;
108 | FC = false;
109 | FV = true}
110 | do not match model flags
111 | {FN = true;
112 | FZ = false;
113 | FC = true;
114 | FV = true}
115 |
116 | Register Input Actual Out Model Out
117 | R0 4 4
118 | R1 4 4
119 | R2 3 3
120 | R3 4294967292 4294967292
121 | R4 2147483646 4294964543
122 | R5 0 0
123 | R6 2147483651 2147483651
124 | R7 4 4
125 | R8 2147483646 2147483646
126 | R9 4294967292 4294967292
127 | R10 1 1
128 | R11 1 1
129 | R12 4294967294 4294967294
130 | R13 4294967294 4294967294
131 | R14 2147483650 2147483650
132 | Flag Before After Model
133 | N 0 1
134 | Z 0 0
135 | C 1 0 1
136 | V 1 1
137 |
138 | ---------ASM----------
139 | MVNS R4 ,#2752
140 | ----------------------------------
141 |
142 |
143 |
144 | --------------dp2Imm:375----------------
145 | Flags:
146 | {FN = true;
147 | FZ = false;
148 | FC = false;
149 | FV = false}
150 | do not match model flags
151 | {FN = true;
152 | FZ = false;
153 | FC = true;
154 | FV = false}
155 |
156 | Register Input Actual Out Model Out
157 | R0 2147483652 4289724415
158 | R1 2147483651 2147483651
159 | R2 2147483645 2147483645
160 | R3 4294967293 4294967293
161 | R4 0 0
162 | R5 4294967292 4294967292
163 | R6 2147483652 2147483652
164 | R7 0 0
165 | R8 4294967292 4294967292
166 | R9 4294967294 4294967294
167 | R10 4 4
168 | R11 2147483644 2147483644
169 | R12 2147483650 2147483650
170 | R13 2147483650 2147483650
171 | R14 4294967294 4294967294
172 | Flag Before After Model
173 | N 0 1
174 | Z 1 0
175 | C 1 0 1
176 | V 0 0
177 |
178 | ---------ASM----------
179 | MVNS R0, #5242880
180 | ----------------------------------
181 |
182 |
183 |
184 | --------------dp2Imm:260----------------
185 | Visual2 cannot parse test assembler
186 |
187 | Register Input Actual Out Model Out
188 | R0 3 0 3
189 | R1 2147483646 0 1073741810
190 | R2 1 0 1
191 | R3 0 0
192 | R4 2147483650 0 2147483650
193 | R5 2147483647 0 2147483647
194 | R6 2 0 2
195 | R7 2147483652 0 2147483652
196 | R8 2147483647 0 2147483647
197 | R9 2147483645 0 2147483645
198 | R10 4294967292 0 4294967292
199 | R11 4294967293 0 4294967293
200 | R12 2147483649 0 2147483649
201 | R13 2147483645 4278190080 2147483645
202 | R14 4294967292 0 4294967292
203 | Flag Before After Model
204 | N 0 0
205 | Z 0 0
206 | C 0 0
207 | V 1 0 1
208 |
209 | ---------ASM----------
210 | MVN R1 , #-1073741811
211 | ----------------------------------
212 |
213 |
214 |
215 | --------------dp2Imm:272----------------
216 | Visual2 cannot parse test assembler
217 |
218 | Register Input Actual Out Model Out
219 | R0 2147483647 0 2147483647
220 | R1 2147483651 0 2147483651
221 | R2 4294967295 0 4294967295
222 | R3 2147483652 0 2147483652
223 | R4 2147483649 0 2147483649
224 | R5 1 0 1
225 | R6 2147483650 0 2147483650
226 | R7 4294967294 0 4294967294
227 | R8 2147483648 0 2147483648
228 | R9 2147483647 0 2147483647
229 | R10 2147483651 0 2147483651
230 | R11 4294967292 0 4294967292
231 | R12 3 0 3
232 | R13 2147483652 4278190080 2147483652
233 | R14 4294967292 0 4294967292
234 | Flag Before After Model
235 | N 0 0 1
236 | Z 0 0
237 | C 0 0
238 | V 1 0 1
239 |
240 | ---------ASM----------
241 | TEQ R0 , #-1073741779
242 | ----------------------------------
243 |
244 |
245 |
246 | --------------dp2Imm:290----------------
247 | Flags:
248 | {FN = true;
249 | FZ = false;
250 | FC = false;
251 | FV = true}
252 | do not match model flags
253 | {FN = true;
254 | FZ = false;
255 | FC = true;
256 | FV = true}
257 |
258 | Register Input Actual Out Model Out
259 | R0 4294967294 4294967294
260 | R1 2147483651 2147483651
261 | R2 4294967295 4294967295
262 | R3 2147483649 4294955519
263 | R4 1 1
264 | R5 2147483646 2147483646
265 | R6 2147483649 2147483649
266 | R7 2147483652 2147483652
267 | R8 2147483644 2147483644
268 | R9 2147483651 2147483651
269 | R10 2147483652 2147483652
270 | R11 2147483644 2147483644
271 | R12 3 3
272 | R13 2147483650 2147483650
273 | R14 2147483652 2147483652
274 | Flag Before After Model
275 | N 1 1
276 | Z 0 0
277 | C 1 0 1
278 | V 1 1
279 |
280 | ---------ASM----------
281 | MVNS R3 , #11776
282 | ----------------------------------
283 |
284 |
285 |
286 | --------------dp2Imm:115----------------
287 | Flags:
288 | {FN = false;
289 | FZ = false;
290 | FC = false;
291 | FV = true}
292 | do not match model flags
293 | {FN = false;
294 | FZ = false;
295 | FC = true;
296 | FV = true}
297 |
298 | Register Input Actual Out Model Out
299 | R0 4294967295 4294967295
300 | R1 4294967294 4294967294
301 | R2 2147483648 2147483648
302 | R3 4294967295 4294967295
303 | R4 2147483648 2147483648
304 | R5 2147483645 720896
305 | R6 1 1
306 | R7 2147483647 2147483647
307 | R8 4 4
308 | R9 2147483646 2147483646
309 | R10 2147483647 2147483647
310 | R11 2147483652 2147483652
311 | R12 2147483649 2147483649
312 | R13 4294967295 4294967295
313 | R14 2147483652 2147483652
314 | Flag Before After Model
315 | N 1 0
316 | Z 0 0
317 | C 1 0 1
318 | V 1 1
319 |
320 | ---------ASM----------
321 | MOVS R5 ,#720896
322 | ----------------------------------
323 |
324 |
325 |
326 | --------------dp2Imm:78----------------
327 | Flags:
328 | {FN = false;
329 | FZ = false;
330 | FC = false;
331 | FV = true}
332 | do not match model flags
333 | {FN = false;
334 | FZ = false;
335 | FC = true;
336 | FV = true}
337 |
338 | Register Input Actual Out Model Out
339 | R0 4294967293 4294967293
340 | R1 0 0
341 | R2 4294967293 4294967293
342 | R3 4294967292 4294967292
343 | R4 2147483650 2147483650
344 | R5 2147483647 2147483647
345 | R6 2147483651 2147483651
346 | R7 4294967295 4294967295
347 | R8 2 2
348 | R9 2147483649 2147483649
349 | R10 2147483648 2147483648
350 | R11 4294967294 4294967294
351 | R12 2147483652 2147483652
352 | R13 4294967295 4294967295
353 | R14 4 56320
354 | Flag Before After Model
355 | N 0 0
356 | Z 0 0
357 | C 1 0 1
358 | V 1 1
359 |
360 | ---------ASM----------
361 | MVNS R14 , #-56321
362 | ----------------------------------
363 |
364 |
--------------------------------------------------------------------------------
/build/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scc416/Visual2/9ebdcd84935acd724658c506acb4073c965ad9a5/build/icon.icns
--------------------------------------------------------------------------------
/build/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scc416/Visual2/9ebdcd84935acd724658c506acb4073c965ad9a5/build/icon.ico
--------------------------------------------------------------------------------
/docs/visual-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scc416/Visual2/9ebdcd84935acd724658c506acb4073c965ad9a5/docs/visual-screen.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "visual",
3 | "productName": "VisUAL2",
4 | "main": "main.js",
5 | "description" : "F# written ARM assembler and simulator with elmish, React Monaco Editor, Electron & Fable",
6 | "author" : "Dr. Tom Clarke, 2018 3rd year HLP students at EEE ICL, Sally Chan",
7 | "version" : "1.07.0",
8 | "scripts": {
9 | "start": "cd src/Main && dotnet fable webpack -w --port free -- -w --config webpack.config.js -w --mode production",
10 | "build": "cd src/Main && dotnet fable webpack --port free -- --config webpack.config.js --mode production",
11 | "pack": "electron-builder --dir",
12 | "dist": "electron-builder",
13 | "pack-win": "electron-builder --windows",
14 | "pack-linux": "electron-builder --linux",
15 | "pack-osx": "electron-builder --macos",
16 | "pack-all": "yarn pack-osx && yarn pack-linux && yarn pack-win",
17 | "launch": "electron . -w",
18 | "launch-debug": "electron . -w --debug"
19 | },
20 | "dependencies": {
21 | "@babel/core": "^7.0.0",
22 | "@babel/plugin-transform-runtime": "^7.0.0",
23 | "@babel/preset-react": "^7.0.0",
24 | "@babel/runtime-corejs2": "^7.0.0",
25 | "@tippy.js/react": "^2.2.0",
26 | "copyfiles": "^2.1.0",
27 | "cross-zip": "^2.1.5",
28 | "css-loader": "^2.1.1",
29 | "electron-context-menu": "^0.9.1",
30 | "electron-settings": "^3.2.0",
31 | "electron-tabs": "^0.9.1",
32 | "fable-compiler": "^2.3.10",
33 | "lodash": ">=4.17.11",
34 | "monaco-editor": "0.16.2",
35 | "monaco-editor-webpack-plugin": "^1.7.0",
36 | "node-sass": "^4.12.0",
37 | "react": "^16.8.6",
38 | "react-dom": "^16.4.2",
39 | "react-monaco-editor": "^0.25.1",
40 | "react-resize-detector": "^4.1.3",
41 | "requirejs": "^2.3.5",
42 | "sass-loader": "^7.1.0",
43 | "style-loader": "^0.23.1",
44 | "tippy.js": "^2.5.4",
45 | "vex-dialog": "^1.1.0",
46 | "vex-js": "^4.1.0"
47 | },
48 | "devDependencies": {
49 | "@babel/core": "^7.0.0",
50 | "@babel/plugin-proposal-class-properties": "^7.4.4",
51 | "@babel/preset-env": "^7.0.0",
52 | "@babel/standalone": "^7.0.0",
53 | "@babel/template": "^7.0.0",
54 | "babel-loader": "^8.0.0",
55 | "cloc": "^2.3.3",
56 | "copy-webpack-plugin": "^4.5.1",
57 | "cross-zip-cli": "^1.0.0",
58 | "electron": "4.1.5",
59 | "electron-builder": "^20.43.0",
60 | "electron-installer-dmg": "^1.0.0",
61 | "fable-loader": "^2.1.6",
62 | "loglevel": "^1.4.1",
63 | "uglifyjs-webpack-plugin": "^1.2.5",
64 | "webpack": "^4.30.0",
65 | "webpack-cli": "^3.3.1"
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/packages/build/FAKE/[Content_Types].xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/paket.dependencies:
--------------------------------------------------------------------------------
1 | source https://nuget.org/api/v2
2 | storage:none
3 |
4 | clitool dotnet-fable
5 | nuget Fable.Core
6 | nuget Fable.Import.Browser
7 | nuget Fable.Import.Electron
8 | nuget Fable.Import.Node
9 | nuget Fable.React
10 | nuget FSharp.Core
11 | nuget Fable.Elmish
12 | nuget Fable.Elmish.React
13 | nuget Fable.Elmish.Browser
14 | nuget Fable.Elmish.Debugger
15 | nuget Fable.Elmish.HMR
16 | nuget Fable.PowerPack
17 | github fable-compiler/ts2fable-exports:dev Monaco.fs
18 |
19 | group Build
20 | source https://nuget.org/api/v2
21 |
22 | nuget FAKE
--------------------------------------------------------------------------------
/setup.bat:
--------------------------------------------------------------------------------
1 | .paket\paket.exe install
2 | git submodule update --init --recursive
3 | git submodule update --recursive --remote
4 | :: .paket\paket.bootstrapper.exe
5 | :: .paket\paket.exe install
6 | :: .paket\paket.exe update
7 | dotnet nuget locals all --clear
8 | dotnet restore src\Main\Main.fsproj
9 | dotnet restore src\Renderer\Renderer.fsproj
10 | dotnet restore src\Emulator\Emulator.fsproj
11 | yarn install
12 |
--------------------------------------------------------------------------------
/setup.sh:
--------------------------------------------------------------------------------
1 | paket install
2 | git submodule update --init --recursive
3 | git submodule update --recursive --remote
4 | dotnet nuget locals all --clear
5 | dotnet restore src/Main/Main.fsproj
6 | dotnet restore src/Renderer/Renderer.fsproj
7 | dotnet restore src/Emulator/Emulator.fsproj
8 | yarn install
9 |
--------------------------------------------------------------------------------
/src/Emulator/Branch.fs:
--------------------------------------------------------------------------------
1 | (*
2 | VisUAL2 @ Imperial College London
3 | Project: A user-friendly ARM emulator in F# and Web Technologies ( Github Electron & Fable Compiler )
4 | Module: Emulator.Branch
5 | Description: Implement ARM branch instructions
6 | *)
7 |
8 | /// emulate ARM branch instructions
9 | module Branch
10 | open CommonData
11 | open CommonLex
12 | open Expressions
13 | open Errors
14 | open Helpers
15 |
16 | type Instr =
17 | | B of uint32
18 | | BL of uint32
19 | | END
20 |
21 | let branchTarget = function | B t | BL t -> [ t ] | END -> []
22 |
23 | // Branch instructions have no suffixes
24 | let branchSpec = {
25 | InstrC = BRANCH
26 | Roots = [ "B"; "BL"; "END" ]
27 | Suffixes = [ "" ]
28 | }
29 |
30 | /// map of all possible opcodes recognised
31 | let opCodes = opCodeExpand branchSpec
32 |
33 | let parse (ls : LineData) : Parse option =
34 | let parse' (_iClass, (root, suffix, cond)) =
35 | let (WA la) = ls.LoadAddr // address this instruction is loaded into memory
36 | let target = parseEvalNumericExpression ls.SymTab ls.Operands
37 | match root, target with
38 | | "B", Ok t -> B t |> Ok
39 | | "BL", Ok t -> BL t |> Ok
40 | | "B", Error t
41 | | "BL", Error t -> Error t
42 | | "END", _ when ls.Operands = "" -> Ok END
43 | | "END", _ -> makeParseError "END (no operands)" ls.Operands "list#pseudo-instructions-and-directives"
44 | | _ -> failwithf "What? Unexpected root in Branch.parse'%s'" root
45 | |> fun ins ->
46 | copyParse ls ins cond
47 | |> (fun pa -> { pa with PStall = match root with | "B" | "BL" -> 2 | _ -> 0 })
48 | let OPC = ls.OpCode.ToUpper()
49 | if Map.containsKey OPC opCodes // lookup opcode to see if it is known
50 | then parse' opCodes.[OPC] |> Some
51 | else None
52 |
53 | /// Parse Active Pattern used by top-level code
54 | let (|IMatch|_|) = parse
55 |
56 |
57 | /// Execute a Branch instruction
58 | let executeBranch ins cpuData =
59 | let nxt = getPC cpuData + 4u // Address of the next instruction
60 | match ins with
61 | | B addr ->
62 | cpuData
63 | |> setReg R15 addr
64 | |> Ok
65 | | BL addr ->
66 | cpuData
67 | |> setReg R15 addr
68 | |> setReg R14 nxt
69 | |> Ok
70 | | END ->
71 | EXIT |> Error
72 |
73 |
74 |
--------------------------------------------------------------------------------
/src/Emulator/CommonData.fs:
--------------------------------------------------------------------------------
1 | (*
2 | VisUAL2 @ Imperial College London
3 | Project: A user-friendly ARM emulator in F# and Web Technologies ( Github Electron & Fable Compiler )
4 | Module: Emulator.CommonData
5 | Description: Low-level data structures used throughout the emulator
6 | *)
7 |
8 | /// Common data types and code for emulator
9 | module CommonData
10 |
11 | //////////////////////////////////////////////////////////////////////////////////////
12 | // Common types and code used by all modules
13 | //////////////////////////////////////////////////////////////////////////////////////
14 |
15 | /// ARM Status bits
16 | type Flags = { N : bool; C : bool; Z : bool; V : bool }
17 |
18 |
19 | ////////////////////////ARM register names and operations/////////////////////////////
20 |
21 |
22 | /// ARM register names
23 | /// NB R15 is the program counter as read
24 |
25 | type RName = | R0 | R1 | R2 | R3 | R4 | R5 | R6 | R7
26 | | R8 | R9 | R10 | R11 | R12 | R13 | R14 | R15
27 |
28 |
29 |
30 | /// Map used to convert strings into RName values,
31 | /// includes register aliasses PC, LR, SP
32 | let regNames =
33 | Map.ofList [
34 | "R0", R0; "R1", R1; "R2", R2; "R3", R3; "R4", R4; "R5", R5
35 | "R6", R6; "R7", R7; "R8", R8; "R9", R9; "R10", R10; "R11", R11;
36 | "R12", R12; "R13", R13; "R14", R14; "R15", R15;
37 | "PC", R15; "LR", R14; "SP", R13
38 | ]
39 |
40 | // various functions used to convert between string, RName, and register number
41 |
42 | /// Inverse of regNames, used to convert RName values to strings
43 | /// NB The string chosen will always be the register (not alias)
44 | let regStrings =
45 | regNames
46 | |> Map.toList
47 | |> List.map (fun (s, rn) -> (rn, s))
48 | |> List.filter (fun (_, s : string) -> s.StartsWith "R")
49 | |> Map.ofList
50 |
51 | /// Map converts RName into register number (no aliasses)
52 | let regNums = Map.map (fun _ (s : string) -> int (s.[1..])) regStrings
53 |
54 | /// Map converts register number into RName (no aliasses)
55 | let inverseRegNums =
56 | regNums |> Map.toList
57 | |> List.map (fun (rn, n) -> (n, rn)) |> Map.ofList
58 |
59 | /// Property on RName to return register number, for convenience
60 | /// Aliasses not included, since they are not RNames
61 | type RName with
62 | /// Return the number of a register as an integer
63 | member r.RegNum = regNums.[r]
64 |
65 | /// Return a register name from an integer
66 | let register n =
67 | if 0 <= n && n < 16
68 | then inverseRegNums.[n]
69 | else (failwithf "Register %d does not exist!" n)
70 |
71 | /// Type to represent the contents of one memory location
72 | /// 'INS is a parameter set to the type of an instruction
73 | /// needed because instruction type is only defined
74 | /// at top level.
75 | type MemLoc<'INS> =
76 | | DataLoc of uint32
77 | | Code of 'INS
78 |
79 | /// type to represent a (word) address
80 | /// there is some ambiguity. Does this contain the real address
81 | /// which is always divisible by 4
82 | /// or does it contain the word number (real address dvided by 4)
83 | /// either way multiply/divide by 4 will cause problems!
84 | /// document this well and be consistent.
85 | type WAddr = WA of uint32
86 |
87 | /// type to represent memory
88 | type CodeMemory<'INS> = Map
89 |
90 | type Data = | Dat of uint32 | CodeSpace
91 |
92 | type DataMemory = Map
93 |
94 | /// ARM state as values of all registers and status bits
95 | /// NB PC can be found as R15 - 8. (Pipelining)
96 | type DataPath = {
97 | Fl : Flags; // Flags
98 | Regs : Map // map representing registers.
99 | // Must be correctly initialised
100 | MM : DataMemory // map showing the contents of all memory
101 | }
102 |
--------------------------------------------------------------------------------
/src/Emulator/CommonLex.fs:
--------------------------------------------------------------------------------
1 |
2 | (*
3 | VisUAL2 @ Imperial College London
4 | Project: A user-friendly ARM emulator in F# and Web Technologies ( Github Electron & Fable Compiler )
5 | Module: Emulator.CommonLex
6 | Description: Perform common part of parsing and define parse types
7 | *)
8 |
9 | /// functions and types for initial assembly parse
10 | module CommonLex
11 |
12 | open CommonData
13 | open Expressions
14 | open Errors
15 |
16 | /// ARM execution conditions
17 | type Condition =
18 |
19 | | Ceq
20 | | Cne
21 | | Cmi
22 | | Cpl
23 | | Chi
24 | | Chs
25 | | Clo
26 | | Cls
27 | | Cge
28 | | Cgt
29 | | Cle
30 | | Clt
31 | | Cvs
32 | | Cvc
33 | | Cnv // the "never executed" condition NV - not often used!
34 | | Cal // the "always executed condition "AL". Used by default on no condition
35 |
36 | /// classes of instructions (example, add/change this is needed)
37 | type InstrClass = | DP | MEM | MISC | BRANCH | PSEUDO
38 |
39 | /// specification of set of instructions
40 | type OpSpec = {
41 | InstrC : InstrClass
42 | Roots : string list
43 | Suffixes : string list
44 | }
45 |
46 |
47 |
48 |
49 | /// result returned from instruction-specific module parsing
50 | /// an instruction class. If symbol definitions are found in a
51 | /// symbol table then a complete parse will be output
52 | /// otherwise some fields will be None
53 | type Parse<'INS> = {
54 | /// value representing instruction. NB type varies with instruction class
55 | PInstr : Result<'INS, Errors.ParseError>
56 | /// name and value of `label defined on this line, if one is.
57 | PLabel : (string * Resolvable) option
58 | /// number of bytes in instruction memory area taken up by this instruction
59 | ISize : uint32
60 | /// number of bytes in data memory area taken up by this instruction, if it needs this
61 | DSize : uint32 option
62 | /// execution condition for instruction
63 | PCond : Condition
64 | /// opcode: same as LineData.OpCode
65 | POpCode : string
66 | /// Number of cycles extra if instruction is executed
67 | PStall : int
68 | }
69 |
70 | /// data given to instruction-specific parse function
71 | type LineData = {
72 | /// memory address this instruction is loaded. Must be word address
73 | LoadAddr : WAddr
74 | /// name of label defined on this line, if one exists
75 | Label : string option
76 | /// table of symbols with defined values: see SymbolTable type for info
77 | SymTab : SymbolTable
78 | /// opcode string: this is the whole opcode including suffix and condition if present
79 | OpCode : string
80 | /// string of all the operands
81 | Operands : string
82 | }
83 |
84 | let copyParse ld ins cond =
85 | let la = match ld.LoadAddr with | WA la -> la
86 | {
87 | PInstr = ins
88 | PLabel = ld.Label |> Option.map (fun lab -> (lab, la |> Ok))
89 | ISize = 4u
90 | DSize = Some 0u
91 | PCond = cond
92 | POpCode = ld.OpCode
93 | PStall = 0
94 | }
95 |
96 | let copyDefault (ld : LineData) cond =
97 | copyParse ld (``Unimplemented parse`` |> Error) cond
98 |
99 |
100 |
101 | /// Strings with corresponding execution condition
102 | /// Note some conditions have multiple strings
103 | /// Note "" is a valid condition string (always execute condition)
104 | let condMap = [ "EQ", Ceq; "NE", Cne; "MI", Cmi; "PL", Cpl; "HI", Chi;
105 | "HS", Chs; "LO", Clo; "LS", Cls; "GE", Cge; "GT", Cgt;
106 | "LE", Cle; "LT", Clt; "VS", Cvs; "VC", Cvc; "CC", Clo; "CS", Chs
107 | "NV", Cnv; "AL", Cal; "", Cal ] |> Map.ofList
108 |
109 | /// list of all strings representing execution conditions
110 | /// includes ""
111 | let condStrings =
112 | condMap
113 | |> Map.toList
114 | |> List.map fst
115 | |> List.distinct
116 |
117 | /// generate all possible opcode strings for given specification
118 | /// each string is paired with info about instruction
119 | /// and the three parts of the opcode
120 | let opCodeExpand (spec : OpSpec)
121 | : // opcode class root suffix instr cond
122 | Map =
123 | spec.Roots
124 | |> List.collect (fun r ->
125 | spec.Suffixes
126 | |> List.collect (fun s ->
127 | condStrings
128 | |> List.map (fun c -> r + s + c, (spec.InstrC, (r, s, condMap.[c])))))
129 | |> Map.ofList
130 |
131 |
132 | let stripCondition (opc : string) =
133 | let n = opc.Length
134 | if n > 2 then
135 | match List.tryFind ((=) opc.[n - 2..n - 1]) condStrings with
136 | | None -> opc, None
137 | | Some cond -> opc.[0..n - 2], Some opc.[n - 2..n - 1]
138 | else opc, None
139 |
--------------------------------------------------------------------------------
/src/Emulator/Emulator.fsproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/Emulator/Errors.fs:
--------------------------------------------------------------------------------
1 | (*
2 | VisUAL2 @ Imperial College London
3 | Project: A user-friendly ARM emulator in F# and Web Technologies ( Github Electron & Fable Compiler )
4 | Module: Emulator.Errors
5 | Description: Handle Errors
6 | *)
7 |
8 |
9 | // WARNING - this code is out of date and needs TLC when errors are properly defined
10 |
11 | /// Error handling for parse and simulator
12 | module Errors
13 |
14 | open CommonData
15 |
16 |
17 | /// Failure message for impossible match cases
18 | let alwaysMatchesFM = "Should never happen! Match statement always matches."
19 |
20 | let noErrorsFM = "Should never happen! No errors at this stage."
21 |
22 | // *************************************************************************
23 | // Error messages for instruction parsing
24 | // *************************************************************************
25 |
26 | /// Error message for `Invalid register`
27 | let notValidRegEM = " is not a valid register."
28 |
29 | /// Error message for `Invalid offset`
30 | let notValidOffsetEM = " is not a valid offset."
31 |
32 | /// Error message for `Invalid instruction`
33 | let notValidFormatEM = " is not a valid instruction format."
34 |
35 | /// Error message for `Invalid literal`
36 | let notValidLiteralEM = " is not a valid literal."
37 |
38 | /// Error message for `Invalid shift` or `Invalid second operand`
39 | let notValidRegLitEM = " is not a valid literal or register."
40 |
41 | /// Error message for `Invalid flexible second operand`
42 | let notValidFlexOp2EM = " is an invalid flexible second operand"
43 |
44 | /// Error message for `Invalid suffix`
45 | let notValidSuffixEM = " is not a valid suffix for this instruction."
46 |
47 | let notImplementedInsEM = " is not a recognised instruction."
48 | // *************************************************************************
49 | // Error messages for instruction execution
50 | // *************************************************************************
51 |
52 | type ErrCode =
53 | | ``Invalid syntax`` of wanted : string * found : string * page : string
54 | | ``Invalid format`` of error : string * found : string * page : string
55 | | ``Invalid instruction`` of reason : string
56 | | ``Invalid Label`` of label: string
57 | | ``Label required`` of reason : string
58 | | ``Unimplemented parse``
59 | | ``Undefined symbol`` of symList : (string * string) list
60 | | ``Invalid opCode`` of root : string option * condition : string option * suffix : string
61 | | ``Unimplemented instruction`` of opCode : string
62 | | ``Duplicate symbol`` of sym : string * lines : int list
63 | | ``Literal more than 32 bits`` of literal : string
64 | | ``Literal is not a valid number`` of literal : string
65 |
66 | type ParseError = ErrCode
67 |
68 | /// The thing that stopped the simulation: EXIT means a normal program END.
69 | type ExecuteError =
70 | | NotInstrMem of uint32 // Trying to fetch from address where there is no instruction
71 | | ``Run time error`` of uint32 * string // a memory access error at given address (with error message)
72 | | ``Unknown symbol runtime error`` of string list // this should never happen, since symbols are resolved by parse
73 | | EXIT
74 | | TBEXIT
75 |
76 | let makeParseError wanted found page = ``Invalid syntax`` (wanted = wanted, found = found, page = page) |> Error
77 |
78 | let makeFormatError wanted found page = ``Invalid format`` (error = wanted, found = found, page = page) |> Error
79 |
80 | let makeInstructionError str = ``Invalid instruction`` str |> Error
81 |
82 | /// A function to combine results or forward errors.
83 | let combineError (res1 : Result<'T1, 'E>) (res2 : Result<'T2, 'E>) : Result<'T1 * 'T2, 'E> =
84 | match res1, res2 with
85 | | Error e1, _ -> Error e1
86 | | _, Error e2 -> Error e2
87 | | Ok rt1, Ok rt2 -> Ok(rt1, rt2)
88 |
89 | /// A function that combines two results by applying a function on them as a pair, or forwards errors.
90 | let combineErrorMapResult (res1 : Result<'T1, 'E>) (res2 : Result<'T2, 'E>) (mapf : 'T1 -> 'T2 -> 'T3) : Result<'T3, 'E> =
91 | combineError res1 res2
92 | |> Result.map (fun (r1, r2) -> mapf r1 r2)
93 |
94 | /// A function that applies a possibly erroneous function to a possibly erroneous argument, or forwards errors.
95 | let applyResultMapError (res : Result<'T1 -> 'T2, 'E>) (arg : Result<'T1, 'E>) =
96 | match arg, res with
97 | | Ok arg', Ok res' -> res' arg' |> Ok
98 | | _, Error e -> e |> Error
99 | | Error e, _ -> e |> Error
100 |
101 | let mapErrorApplyResult (arg : Result<'T1, 'E>) (res : Result<'T1 -> 'T2, 'E>) =
102 | match arg, res with
103 | | Ok arg', Ok res' -> res' arg' |> Ok
104 | | _, Error e -> e |> Error
105 | | Error e, _ -> e |> Error
106 |
107 | let condenseResultList transform (lst : Result<'a, 'b> list) : Result<'a list, 'b> =
108 | let rec condenser' inlst outlst =
109 | match inlst with
110 | | head :: tail ->
111 | match head with
112 | | Ok res -> condenser' tail ((transform res) :: outlst)
113 | | Error e -> e |> Error
114 | | [] -> List.rev outlst |> Ok
115 | condenser' lst []
116 |
--------------------------------------------------------------------------------
/src/Emulator/Expressions.fs:
--------------------------------------------------------------------------------
1 | (*
2 | VisUAL2 @ Imperial College London
3 | Project: A user-friendly ARM emulator in F# and Web Technologies ( Github Electron & Fable Compiler )
4 | Module: Emulator.Expressions
5 | Description: Parse expressions with constants, symbols, and arithmetic
6 | *)
7 |
8 |
9 | /// Assembler code expressions (symbols, operators, and constants)
10 | module Expressions
11 | open System.Text.RegularExpressions
12 | open Errors
13 | open EEExtensions
14 |
15 |
16 | /// Match the start of txt with pat
17 | /// Return a tuple of the matched text and the rest
18 | let (|RegexPrefix|_|) pat txt =
19 | // Match from start, ignore whitespace
20 | let m = Regex.Match(txt, "^[\\s]*" + pat + "[\\s]*")
21 | match m.Success with
22 | | true -> (m.Value, txt.Substring(m.Value.Length)) |> Some
23 | | false -> None
24 |
25 |
26 | /// Remove all whitespace from a matched string
27 | let removeWs txt = Regex.Replace(txt, "[\\s]*", "")
28 |
29 | /// Active pattern for matching labels
30 | /// Also removes any whitespace from around the label
31 | let (|LabelExpr|_|) txt =
32 | match txt with
33 | | RegexPrefix "[a-zA-Z][a-zA-Z0-9_]+" (var, rst) ->
34 | (// Remove whitespace from the label
35 | removeWs var, rst) |> Some
36 | | _ -> None
37 |
38 |
39 |
40 | type SymbolTable = Map
41 |
42 | // []
43 | type Expression =
44 | | BinOp of (uint32 -> uint32 -> uint32) * Expression * Expression
45 | | Label of string
46 | | Literal of uint32
47 | // override _x.Equals (_y) = false
48 |
49 | type Resolvable = Result
50 |
51 |
52 | /// Evaluate exp against the symbol table syms
53 | /// Returns a list of all errors or the result
54 | let rec eval (syms : Map) exp : Result =
55 | let joinErrors a b =
56 | match a, b with
57 | | ``Undefined symbol`` a', ``Undefined symbol`` b' ->
58 | ``Undefined symbol`` (a' @ b') |> Error
59 | | ``Undefined symbol`` _, a'
60 | | a', _ -> a' |> Error
61 | let doBinary op x y =
62 | match (eval syms x), (eval syms y) with
63 | | Ok resX, Ok resY -> ((op resX resY) >>> 0) |> Ok
64 | | Error a, Error b -> joinErrors a b
65 | | Error a, _ -> a |> Error
66 | | _, Error b -> b |> Error
67 | let getSymError x =
68 | let x' = String.toUpper x
69 | let symLst = syms |> Map.toList |> List.map fst
70 | match List.tryFind (fun sym -> x' = String.toUpper sym) symLst with
71 | | Some sym -> x, sprintf "'%s' which has different case from label '%s'" x sym
72 | | None -> x, sprintf "'%s' which is not defined as a label" x
73 | match exp with
74 | | BinOp(op, x, y) -> doBinary op x y
75 | | Literal x -> x |> Ok
76 | | Label x ->
77 | match (Map.containsKey x syms) with
78 | | true -> syms.[x] |> Ok
79 | | false ->
80 | ``Undefined symbol`` [ getSymError x ] |> Error
81 |
82 |
83 | let to32BitLiteral chars =
84 | try
85 | chars
86 | |> int64
87 | |> function
88 | | n when n > (1L <<< 32) || n < (-1L <<< 31) -> Error(``Literal more than 32 bits`` chars)
89 | | n -> Ok(uint32 n)
90 | with
91 | | e -> Error(``Literal is not a valid number`` chars)
92 |
93 |
94 |
95 |
96 | /// Active pattern for matching expressions
97 | /// Returns an Expression AST
98 | let rec (|Expr|_|) expTxt =
99 |
100 | let (|Minus|_|) (txt : string) =
101 | match txt.Length > 0 && txt.[0] = '-' with
102 | | true -> Some txt.[1..]
103 | | false -> None
104 |
105 | let (|PosLiteralExpr|_|) txt =
106 | match txt with
107 | | RegexPrefix "0[xX][0-9a-fA-F][0-9a-fA-F_]*" (num, rst)
108 | | RegexPrefix "0[bB][0-1][0-1_]*" (num, rst)
109 | | RegexPrefix "[0-9][0-9_]*" (num, rst) ->
110 | try
111 | let litNum =
112 | num
113 | |> String.replace "_" ""
114 | |> String.toLower
115 | |> int64
116 | |> function // check that literal constants are within 32 bit range under FABLE
117 | | n when n > ((1L <<< 32) - 1L) ->
118 | failwithf "Literal more than 32 bits"
119 | | n -> uint32 n
120 | |> Literal
121 | (litNum, rst) |> Some
122 | with
123 | | _ ->
124 | printfn "Exception in Expr: uint32(%A)" num
125 | None
126 | | RegexPrefix "&[0-9a-fA-F]+" (num, rst) ->
127 | ("0x" + (removeWs num).[1..] |> uint32 |> Literal, rst) |> Some
128 | | _ -> None
129 |
130 | let (|LiteralExpr|_|) (expTxt : string) =
131 | match expTxt with
132 | | PosLiteralExpr(num, txt) -> Some(num, txt)
133 | | Minus(PosLiteralExpr(num, txt)) -> Some(BinOp((-), Literal 0u, num), txt)
134 | | _ -> None
135 |
136 | /// Active pattern matching either labels, literals
137 | /// or a bracketed expression (recursively defined)
138 | let (|PrimExpr|_|) txt =
139 | match txt with
140 | | LabelExpr(lab, rst) -> (Label lab, rst) |> Some
141 | | LiteralExpr x -> Some x
142 | | RegexPrefix "\(" (_, Expr(exp, RegexPrefix "\)" (_, rst))) -> (exp, rst) |> Some
143 | | _ -> None
144 |
145 | /// Higher order active patterns to match lists of the form
146 | /// x op x op x ... to capture left associativity correctly.
147 | let rec (|LBinExprList|_|) (|NextExpr|_|) reg op lVal txt =
148 | match txt with
149 | | RegexPrefix reg (_, NextExpr(rVal, rst)) ->
150 | match rst with
151 | | LBinExprList (|NextExpr|_|) reg op (BinOp(op, lVal, rVal)) (exp, rst')
152 | -> Some(exp, rst')
153 | | _ -> Some(BinOp(op, lVal, rVal), rst)
154 | | _ -> None
155 |
156 | /// Higher order active pattern for defining binary operators
157 | /// NextExpr is the active pattern of the operator with the next
158 | /// highest precedence. reg is the regex which matches this operator
159 | /// op is the operation it performs
160 | let (|LBinExpr|_|) (|NextExpr|_|) reg op txt =
161 | match txt with
162 | | NextExpr(lVal, rhs) ->
163 | match rhs with
164 | | LBinExprList (|NextExpr|_|) reg op lVal x
165 | -> Some x
166 | // Can't nest this AP because its the
167 | // "pass-through" to the next operator
168 | | _ -> (lVal, rhs) |> Some
169 | | _ -> None
170 |
171 | // Define active patterns for the binary operators
172 | // Order of precedence: Add, Sub, Mul
173 | let (|MulExpr|_|) = (|LBinExpr|_|) (|PrimExpr|_|) "\*" (*)
174 | let (|SubExpr|_|) = (|LBinExpr|_|) (|MulExpr|_|) "\-" (-)
175 | let (|AddExpr|_|) = (|LBinExpr|_|) (|SubExpr|_|) "\+" (+)
176 |
177 | match expTxt with
178 | | AddExpr x -> Some x
179 | | _ -> None
180 |
181 |
182 | let printUintRes r =
183 | match r with
184 | | Ok u -> printfn "OK %d" u; r
185 | | Error(code, eTxt, eMess) -> printfn "Error:<%s><%s>" eTxt eMess; r
186 |
187 | let parseEvalNumericExpression syms op =
188 | match removeWs op with
189 | | Expr(ast, _) -> eval syms ast
190 | | _ when String.contains "#" op -> makeParseError "Numeric expression (without #)" op ""
191 | | _ -> makeParseError "Numeric expression" op ""
192 |
193 | let parse syms op =
194 | match removeWs op with
195 | | Expr(ast, txt) -> Result.map (fun e -> e, txt) (eval syms ast)
196 | | _ when String.contains "#" op -> makeParseError "Numeric expression (without #)" op ""
197 | | _ -> makeParseError "Numeric expression" op ""
198 |
199 |
200 | type PartsOfASM = | ALabel | AOpCode | AOperand of int
201 |
202 | /// Code to implement accurate error reporting
203 | /// Malformed lines will be best effort parsed into parts
204 | /// Each part will be returned with its position in the original line
205 | let getASMPart symTab isOpCode (part : PartsOfASM) (line : string) =
206 | let isSymbol s = Map.containsKey s symTab
207 | let pack (thing : string) (restOfLine : string) =
208 | let n = line.Length
209 | let r = restOfLine.Length
210 | let ePos = n - r + 1
211 | let sPos = ePos - thing.Length
212 | thing, sPos, ePos
213 | match part, line with
214 | | ALabel, LabelExpr(lab, rst) when isOpCode lab |> not -> pack lab rst
215 | | _ -> failwithf "Not implemented"
216 |
217 |
--------------------------------------------------------------------------------
/src/Emulator/Misc.fs:
--------------------------------------------------------------------------------
1 | (*
2 | VisUAL2 @ Imperial College London
3 | Project: A user-friendly ARM emulator in F# and Web Technologies ( Github Electron & Fable Compiler )
4 | Module: Emulator.Misc
5 | Description: Implement ARM miscellaneous instructions
6 | *)
7 |
8 | /// emulate DCD, DCB, FILL, EQU, ADR instructions
9 | module Misc
10 | open EEExtensions
11 | open CommonData
12 | open CommonLex
13 | open Expressions
14 | open Helpers
15 | open Errors
16 | open DP
17 |
18 |
19 | type FILLInstr = { NumBytes : uint32; FillValue : uint32 }
20 |
21 | type ADRInstr = { AReg : RName; AVal : uint32 }
22 |
23 | type Instr =
24 | | DCD of uint32 list
25 | | DCB of uint32 list
26 | | FILL of FILLInstr
27 | | EQU of uint32
28 | | ADR of ADRInstr
29 |
30 | let miscRoots = [ "DCD"; "DCB"; "FILL"; "EQU"; "ADR" ]
31 |
32 |
33 | /// Errors which can occur during parsing
34 | // type ErrInstr =
35 | // | InvalidExp of string
36 | // | InvalidExpList of string
37 | // | InvalidFill of string
38 | // | LabelRequired
39 | /// Error types for parsing.
40 |
41 | let commaSplit (x : string) =
42 | x.Split([| ',' |])
43 | |> Array.toList
44 | |> List.map String.trim
45 |
46 | let mergeResults (lst : Result<'T, 'E> list) =
47 | let folder (st : Result<'T list, 'E>) (r : Result<'T, 'E>) =
48 | match st with
49 | | Error st -> Error st
50 | | Ok st -> Result.map (fun r -> r :: st) r
51 | List.fold folder (Ok []) lst
52 | |> Result.map List.rev
53 |
54 |
55 | let parseNumExpr ls s =
56 | Ok((), s)
57 | |> ResExpr(fun _ e -> e)
58 | |> ResCheckDone
59 | |> Result.bind (fun exp ->
60 | eval ls.SymTab exp)
61 |
62 | let parseExprList symTab lst =
63 | List.map (parseNumExpr symTab) lst
64 | |> mergeResults
65 |
66 |
67 |
68 | let parse (ls : LineData) : Parse =
69 | let (WA la) = ls.LoadAddr // address this instruction is loaded into memory
70 | let opLst = commaSplit ls.Operands
71 | let resolvedOpLst = parseExprList ls opLst
72 | let (|PARSE|_|) op = parseNumExpr ls op |> Some
73 | let (|RESOLVEALL|_|) lst = match parseExprList ls lst with | Ok ops -> Some ops | _ -> None
74 | let opCode = ls.OpCode
75 | let offsetError wb b1 b2 ofs =
76 | let msg = sprintf "Valid %s offset in range %d..%d. Use 'LDR Rx, =SYMBOL' when offset is larger than this" wb b1 b2
77 | makeParseError msg (sprintf "Offset of %d" ofs) ""
78 | let checkAddrOffset (ofs : int) =
79 | match ofs - 8 with
80 | | x when x % 4 <> 0 && (x > 264 || x < -248) -> offsetError "byte" -248 264 (ofs - 8)
81 | | x when (x > 1032 || x < -1016) -> offsetError "word" -1016 1032 (ofs - 8)
82 | | x -> Ok()
83 |
84 | let labelBinder f =
85 | match ls.Label with
86 | | Some lab -> f lab
87 | | None -> ``Label required`` ("'" + ls.Operands + "' requires a label.")
88 |
89 |
90 | let makeDataInstr dataInstrCode = Result.map dataInstrCode resolvedOpLst
91 |
92 | let makeDataDirective dSizeOpt dataInstr =
93 | { copyDefault ls Cal with
94 | PInstr = dataInstr
95 | ISize = 0u
96 | DSize = dSizeOpt
97 | }
98 |
99 |
100 |
101 | let opNum = List.length opLst |> uint32
102 |
103 | let makeFILL ops =
104 | match resolvedOpLst with
105 | | Ok [ nBytes ] when nBytes % 4u = 0u ->
106 | makeDataDirective (Some nBytes) (FILL { NumBytes = nBytes; FillValue = 0u } |> Ok)
107 | | Ok [ nBytes; fillVal ] when nBytes % 4u = 0u ->
108 | makeDataDirective (Some nBytes) (FILL { NumBytes = nBytes; FillValue = fillVal } |> Ok)
109 | | Ok [ nBytes ]
110 | | Ok [ nBytes; _ ] ->
111 | let msg = sprintf "%d FILL bytes is invalid. Fill must have a number of bytes divisible by 4" nBytes
112 | makeDataDirective (Some 0u) (makeInstructionError msg)
113 |
114 | | _ -> makeDataDirective (Some 0u) <|
115 | makeInstructionError ("Invalid operands '" + ls.Operands + "'. Fill must have 1 or 2 operands")
116 |
117 | let makeEQU (op : Resolvable) =
118 | match op with
119 | | Ok addr -> makeDataDirective (Some 0u) (EQU addr |> Ok)
120 | | Error e -> makeDataDirective (Some 0u) (Error e)
121 | |> fun pa -> { pa with PLabel = Option.map (fun lab -> lab, op) ls.Label }
122 |
123 | let pa = copyDefault ls Cal
124 | match opCode.ToUpper(), opLst with
125 | | "DCD", RESOLVEALL ops -> makeDataDirective (Some(opNum * 4u)) (makeDataInstr DCD)
126 | | "DCB", RESOLVEALL ops when ops.Length % 4 = 0 -> makeDataDirective (Some opNum) (makeDataInstr DCB)
127 | | "DCB", _ ->
128 | let msg = "Invalid operands: '" + ls.Operands + "'. DCB must have a number of parameters divisible by 4"
129 | makeInstructionError msg
130 | |> makeDataDirective (Some 0u)
131 | | "FILL", RESOLVEALL [ op ] -> makeFILL [ op, 0u ]
132 | | "FILL", _ -> makeDataDirective None <| makeInstructionError ("Invalid operands for FILL: unresolved symbols")
133 | | "ADR", RegMatch(Ok rn) :: [ PARSE(Ok addr) ] ->
134 | match checkAddrOffset (int addr - int la) with
135 | | Ok _ -> { pa with PInstr = ADR { AReg = rn; AVal = addr } |> Ok; PStall = (if rn = R15 then 2 else 0) }
136 | | Error e -> { pa with PInstr = Error e }
137 | | "ADR", _ops ->
138 | let msg = "Invalid operands: '" + ls.Operands +
139 | "'. ADR must have a register followed by a numeric expression operand."
140 | { pa with PInstr = makeInstructionError msg }
141 | | "EQU", [ PARSE op ] when opLst <> [] -> makeEQU op
142 | | "EQU", x -> { pa with PInstr = makeInstructionError (sprintf "'%A' is an invalid expression for EQU" x) }
143 | | _, ops -> makeInstructionError ("Invalid instruction: '" + ls.OpCode + " " + ls.Operands + "'")
144 | |> makeDataDirective (Some 0u)
145 | | _ -> failwithf "What? unrecognised Misc opcode %s" opCode
146 |
147 |
148 |
149 | /// Parse Active Pattern used by top-level code
150 | let (|IMatch|_|) (ls : LineData) =
151 | if List.contains ls.OpCode miscRoots
152 | then
153 | //printfn "IMISC Parsing '%s'" ls.OpCode
154 | parse ls |> Some
155 | else
156 | //printfn "IMISC Not parsing '%s'" ls.OpCode
157 | None
158 |
159 |
--------------------------------------------------------------------------------
/src/Emulator/ParseTop.fs:
--------------------------------------------------------------------------------
1 | (*
2 | VisUAL2 @ Imperial College London
3 | Project: A user-friendly ARM emulator in F# and Web Technologies ( Github Electron & Fable Compiler )
4 | Module: Emulator.ParseTop
5 | Description: Top-level code to parse instructions
6 | *)
7 |
8 | /// Top-level code implementing assembler parsing
9 | module ParseTop
10 | open CommonLex
11 | open CommonData
12 |
13 | open Errors
14 | open Expressions
15 |
16 | /// allows different modules to return different instruction types
17 | type Instr =
18 | | IMEM of Memory.Instr
19 | | IDP of DP.Instr
20 | | IMISC of Misc.Instr
21 | | IBRANCH of Branch.Instr
22 | | EMPTY
23 |
24 |
25 |
26 | let Blank lab = {
27 | PCond = Cal
28 | PInstr = Ok EMPTY
29 | PLabel = lab
30 | ISize = 0u
31 | DSize = Some 0u
32 | POpCode = ""
33 | PStall = 0
34 | }
35 |
36 | /// Split line on whitespace into an list
37 | let splitIntoWords (line : string) =
38 | line.Split(([| ' '; '\t'; '\f'; '\r'; '\n'; '\b' |] : char array),
39 | System.StringSplitOptions.RemoveEmptyEntries)
40 | |> Array.collect (function | "" -> [||] | s -> [| s |])
41 | |> Array.map (fun s -> s.Trim())
42 | |> Array.toList
43 |
44 | /// Note that Instr in Mem and DP modules is NOT same as Instr in this module
45 | /// Instr here is all possible isntruction values combines with a D.U.
46 | /// that tags the Instruction class
47 | /// Similarly ErrParse
48 | /// Similarly IMatch here is combination of module IMatches
49 | let IMatch(ld : LineData) : Parse option =
50 | let copy cons pa =
51 | { // NB need this copy by fields because types do not match
52 |
53 | PCond = pa.PCond
54 | PInstr = Result.map cons pa.PInstr
55 | PLabel = pa.PLabel
56 | POpCode = pa.POpCode
57 | ISize = pa.ISize
58 | DSize = pa.DSize
59 | PStall = pa.PStall
60 | } |> Some
61 |
62 |
63 | match ld with
64 | | Memory.IMatch pa -> copy IMEM pa
65 | | DP.IMatch pa -> copy IDP pa
66 | | Misc.IMatch pa -> copy IMISC pa
67 | | Branch.IMatch pa -> copy IBRANCH pa
68 | | _ -> None
69 |
70 |
71 |
72 | type CondInstr = {
73 | Cond : Condition
74 | InsExec : Instr
75 | InsOpCode : string
76 | Cycles : int64
77 | }
78 |
79 | let makeParse labOpt la ins =
80 | {
81 | PInstr = ins
82 | PLabel = labOpt |> Option.map (fun lab -> lab, la)
83 | ISize = 0u
84 | DSize = Some 0u
85 | PCond = Cal
86 | POpCode = ""
87 | PStall = 0
88 | }
89 |
90 |
91 |
92 |
93 | let parseLine (symtab : SymbolTable) (loadI : uint32, loadD : uint32) (asmLine : string) =
94 | let isDataOp (op : string) = List.contains (op.ToUpper()) [ "DCD"; "DCB"; "FILL" ]
95 |
96 | let isLabel (str : string) =
97 | let isIdentifierChar ch = System.Char.IsLetterOrDigit ch || ch = '_'
98 | str.Length > 1 && System.Char.IsLetter str.[0] && Seq.forall isIdentifierChar str
99 |
100 | /// put parameters into a LineData record and parse
101 | let (|TRYPARSE|_|) (words : string list) =
102 | match words with
103 | | label :: opcode :: operands when label = "" || isLabel label ->
104 | {
105 | OpCode = opcode.ToUpper()
106 | Operands = (String.concat " " operands).Trim()
107 | Label = match label with | "" -> None | _ -> Some label
108 | LoadAddr = (if isDataOp opcode then loadD else loadI) |> WA
109 | SymTab = symtab
110 | } |> IMatch
111 | | _ -> None
112 |
113 | /// remove comments from string
114 | let removeComment (txt : string) =
115 | txt.Split ';'
116 | |> function
117 | | [| x |] -> x
118 | | [||] -> ""
119 | | lineWithComment -> lineWithComment.[0]
120 | /// try to parse 1st word, or 2nd word, as opcode
121 | /// If 2nd word is opcode 1st word must be label
122 | let parseLine' words =
123 | let defParse lab = makeParse lab (Ok loadI)
124 | match [ "" ] @ words @ [ "" ] with
125 | | "" :: TRYPARSE pa -> pa
126 | | TRYPARSE pa -> pa
127 | | [ ""; label; "" ] ->
128 | if isLabel label
129 | then defParse (Some label) (EMPTY |> Ok)
130 | else defParse None (``Invalid Label`` label |> Error)
131 | | [ ""; "" ] -> defParse None (EMPTY |> Ok)
132 | | "" :: opc :: _ ->
133 | defParse None (``Unimplemented instruction`` opc |> Error)
134 | | _ -> failwithf "What: should not be possible!"
135 | asmLine
136 | |> removeComment
137 | |> splitIntoWords
138 | |> parseLine'
139 |
140 |
141 |
142 |
--------------------------------------------------------------------------------
/src/Emulator/paket.references:
--------------------------------------------------------------------------------
1 | dotnet-fable
2 | Fable.Core
3 | Fable.Import.Browser
4 | Fable.React
--------------------------------------------------------------------------------
/src/Main/Main.fs:
--------------------------------------------------------------------------------
1 | (*
2 | VisUAL2 @ Imperial College London
3 | Project: A user-friendly ARM emulator in F# and Web Technologies ( Github Electron & Fable Compiler )
4 | Module: Main.Main
5 | Description: Electron Main Process
6 | *)
7 |
8 | /// This single module is compiled to JS to make the electron main process that runs node directly on teh host PC and starts up the app.
9 | /// This process is also used for any native resource access (files etc) via electron IPC calls
10 | module Main
11 |
12 |
13 |
14 | open Fable.Core
15 | open Fable.Core.JsInterop
16 | open Fable.Import
17 | open Fable.Import.Electron
18 | open Node.Exports
19 | open System.Diagnostics
20 |
21 | let printHelpMessage() =
22 | printfn """
23 | Visual2 command line options
24 | ----------------------------
25 | -h, --help - print this help message
26 | -d, --debug - run with browser dev tools initially open, for startup debug info logged to console
27 | - to open or close dev tools after startup
28 | """
29 |
30 | let args =
31 | Fable.Import.Node.Globals.``process``.argv
32 | |> Seq.toList
33 | |> List.map (fun s -> s.ToLower())
34 | /// returns true if any of flags are present as command line argument
35 | let argFlagIsOn (flags:string list) =
36 | let fl = List.map (fun (s:string) -> s.ToLower()) flags
37 | List.exists (fun flag -> List.contains flag args) fl
38 |
39 | /// returns true if fl is recognised as valid?
40 | let isValidFlag fl =
41 | List.contains fl ["-h";"--help";"-d";"--debug";"-w";".";]
42 |
43 | /// returns true if we need to disable startup and print help message
44 | let hasHelpArgs() =
45 | argFlagIsOn ["--help";"-h"] || List.exists (fun arg -> not (isValidFlag arg)) (List.tail args)
46 |
47 | if hasHelpArgs() && not (argFlagIsOn ["--help";"-h"]) then
48 | printfn "Bad arguments: %A" args
49 |
50 | /// returns true if we need to add debugging info and printout
51 | let hasDebugArgs() = argFlagIsOn ["--debug";"-d"]
52 |
53 | // Keep a global reference of the window object, if you don't, the window will
54 | // be closed automatically when the JavaScript object is garbage collected.
55 | let mutable mainWindow: BrowserWindow option = Option.None
56 |
57 | /// ensure that if app is started again the first instance is focussed and the second quits
58 | //let shouldQuit = electron.app.makeSingleInstance( fun _ _ ->
59 | //// Someone tried to run a second instance, we should focus our window.
60 | //match mainWindow with
61 | //| Some win ->
62 | // if (win.isMinimized()) then
63 | // win.restore();
64 | // win.focus();
65 | //| Core.Option.None -> ())
66 |
67 | //if (shouldQuit) then
68 | //electron.app.quit()
69 |
70 |
71 | // Used for right-click context menu
72 | []
73 | let contextMenu () = jsNative
74 |
75 | let settings:obj = importDefault "electron-settings"
76 |
77 | let dTrace fmt s = if hasDebugArgs() then printfn fmt s
78 |
79 | dTrace "settings=%A" (settings?get "editor-theme")
80 |
81 | let enableHotReload (window:BrowserWindow) =
82 | printfn "Enabling development hot reload..."
83 | fs.watch(path.join(Node.Globals.__dirname, "/main.js"), fun _ _ ->
84 | window.webContents.reloadIgnoringCache()
85 | ) |> ignore
86 | fs.watch(path.join(Node.Globals.__dirname, "/app/js"), fun _ _ ->
87 | window.webContents.reloadIgnoringCache()
88 | ) |> ignore
89 | fs.watch(path.join(Node.Globals.__dirname, "/app/css"), fun _ _ ->
90 | window.webContents.reloadIgnoringCache()
91 | ) |> ignore
92 | fs.watch(path.join(Node.Globals.__dirname, "/app/index.html"), fun _ _ ->
93 | window.webContents.reloadIgnoringCache()
94 | ) |> ignore
95 |
96 |
97 | /// create main renderer window of app
98 | let createMainWindow () =
99 | if hasHelpArgs() then printHelpMessage()
100 | else
101 | if hasDebugArgs() then printfn "Starting to create app window..."
102 | let options = createEmpty
103 | // Complete list of window options
104 | // https://electronjs.org/docs/api/browser-window#new-browserwindowoptions
105 | options.width <- Some 1200.
106 | options.height <- Some 800.
107 | options.show <- Some false
108 | let prefs = createEmpty
109 | prefs.devTools <- Some (argFlagIsOn ["-w"; "-d"; "--debug"])
110 | options.webPreferences <- Some prefs
111 |
112 | options.frame <- Some true
113 | options.hasShadow <- Some true
114 | options.backgroundColor <- Some "#5F9EA0"
115 | options.icon <- Some (U2.Case2 "app/visual.ico")
116 |
117 | let window = electron.BrowserWindow.Create(options)
118 | if hasDebugArgs() then window.webContents.openDevTools();
119 | // Load the index.html of the app.
120 | let opts = createEmpty>
121 | opts.pathname <- Some <| path.join(Node.Globals.__dirname, "/app/index.html")
122 | opts.protocol <- Some "file:"
123 | dTrace "Loading HTML: %A" opts.pathname
124 | window.loadURL(url.format(opts))
125 | dTrace "%s" "load complete"
126 | let mutable closeAfterSave = false
127 | window.on("close",
128 | unbox (fun e ->
129 | if not closeAfterSave then
130 | dTrace "%s" "Close event received!"
131 | e?preventDefault () |> ignore
132 | window.webContents.send "closingWindow"
133 | )) |> ignore
134 | // Emitted when the window is closed.
135 | window.on("closed", unbox(fun () ->
136 | // Dereference the window object, usually you would store windows
137 | // in an array if your app supports multi windows, this is the time
138 | // when you should delete the corresponding element.
139 | mainWindow <- Option.None
140 | )) |> ignore
141 |
142 | window.on("resize",
143 | unbox ( fun _ ->
144 | window.webContents.send "resizeWindow")) |> ignore
145 |
146 | window.webContents.on("new-window", (fun e x ->
147 | printfn "Opening new window! %A %A" e x
148 | e?preventDefault();
149 | electron.shell.openExternal x |> ignore
150 | )) |> ignore
151 |
152 | electron.ipcMain?on ("doClose", unbox (fun () ->
153 | closeAfterSave <- true
154 | dTrace "%s" "Closing window NOW!"
155 | window?close()
156 | )) |> ignore
157 |
158 |
159 | // Maximize the window
160 | //window.maximize()
161 |
162 | // Clear the menuBar, this is overwritten by the renderer process
163 | //let template = ResizeArray [
164 | // createEmpty
165 | // ]
166 | //electron.Menu.setApplicationMenu(electron.Menu.buildFromTemplate(template))
167 |
168 | window.on("ready-to-show", (fun () ->
169 | window.show()
170 | options.backgroundColor <- Some "#F0F0F0"
171 | window.focus()
172 | dTrace "%s" "Window on!"
173 | if argFlagIsOn ["-w"] then enableHotReload window)
174 | ) |> ignore
175 |
176 | mainWindow <- Some window
177 |
178 | // This method will be called when Electron has finished
179 | // initialization and is ready to create browser windows.
180 | electron.app.on("ready", unbox createMainWindow) |> ignore
181 |
182 | // Quit when all windows are closed.
183 | electron.app.on("window-all-closed", unbox(fun () ->
184 | // On OS X it is common for applications and their menu bar
185 | // to stay active until the user quits explicitly with Cmd + Q
186 | // if Node.Globals.``process``.platform <> Node.Base.NodeJS.Darwin then
187 | electron.app.quit()
188 | )) |> ignore
189 |
190 | electron.app.on("activate", unbox(fun () ->
191 | // On OS X it's common to re-create a window in the app when the
192 | // dock icon is clicked and there are no other windows open.
193 | if mainWindow.IsNone then
194 | createMainWindow()
195 | )) |> ignore
196 |
--------------------------------------------------------------------------------
/src/Main/Main.fsproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/Main/paket.references:
--------------------------------------------------------------------------------
1 | dotnet-fable
2 | Fable.Core
3 | Fable.Import.Browser
4 | Fable.Import.Electron
5 | Fable.Import.Node
--------------------------------------------------------------------------------
/src/Renderer/ErrorDocs.fs:
--------------------------------------------------------------------------------
1 | (*
2 | VisUAL2 @ Imperial College London
3 | Project: A user-friendly ARM emulator in F# and Web Technologies ( Github Electron & Fable Compiler )
4 | Module: Renderer.ErrorDocs
5 | Description: create markdown for assembler hover message hints
6 | *)
7 | module ErrorDocs
8 |
9 | open EEExtensions
10 | open Refs
11 | open Fable.PowerPack
12 |
13 |
14 | let opCodeData = [
15 | "ADD","dest := op1 + op2", DP3
16 | "SUB","dest := op1 - op2", DP3
17 | "RSB","dest := op2 - op1", DP3
18 | "ADC","dest := op1 + op2 + C", DP3
19 | "SBC","dest := op1 - op2 + C", DP3
20 | "RSC","dest := op2 - op1 + C - 1", DP3
21 | "MOV","dest := op2", DP2
22 | "MVN","dest := NOT op2", DP2
23 | "CMP","set NZCV on op1 - op2", CMP
24 | "CMN","set NZCV on op1 + op2", CMP
25 | "TST","set NZ on op1 bitwise AND op2", CMP
26 | "TEQ","set NZ on op1 bitwise XOR op2", CMP
27 | "LDR","load memory word or byte at address 'EA' into Rd. Optionally update Rb.", LDRSTR
28 | "STR","load memory word or byte at address 'EA' into Rd. Optionally update Rb.", LDRSTR
29 | "LDM","load multiple registers from memory", LDMSTM
30 | "STM","store multiple registers to memory", LDMSTM
31 | "FILL", "allocate op1 data bytes. Op1 must be divisible by 4. Fill words with 0.", MISC
32 | "DCD","allocate data words as specified by op1,...opn",MISC
33 | "DCB","allocate data bytes as specified by op1,...,opn. The number of operand must be divisible by 4",MISC
34 | "EQU","define label on this line to equal op1. Op1 may contain: labels,numbers, +,-,*,/", EQU
35 | ]
36 |
37 | /// match opcode with opcode list returning root instruction (without suffixes or conditions)
38 | /// return "unimplemented" on no match.
39 | let getRoot (opc:string) =
40 | opCodeData
41 | |> List.collect (fun (root,legend,opType) ->
42 | if String.startsWith (root.ToUpper()) (opc.ToUpper()) then
43 | [root,legend, opType]
44 | else [])
45 | |> function
46 | | [ spec] -> spec
47 | | _ -> "unimplemented", "",UNIMPLEMENTED
48 |
49 | /// Add extra diagnostic info for bad shift instructions
50 | let makeShiftModes (isShift, isRRX, isBadShift) =
51 | match isShift,isRRX,isBadShift with
52 | | None, None, None -> " #-1"
53 | | Some sft,_, _ -> sprintf " R2, %s #5" sft
54 | | _, Some _, _ -> " R10, RRX"
55 | | _, _, Some bad -> sprintf " R6, LSR #1**\n\n*Note: * **%s** *is not a valid shift, did you mean* **LSR** , **ASR** , **LSL** , **ROR** , **RRX** *?* **" (String.trim bad)
56 |
57 |
58 |
59 | let makeDPHover2 (opc,sfts) func =
60 | sprintf """
61 | *%s dest, op2; %s*
62 |
63 | **%s R0, R1**
64 |
65 | **%s R5, #101**
66 |
67 | **%s R10, #0x5a**
68 |
69 | **%s R7, %s**
70 |
71 | """ opc func opc opc opc opc (makeShiftModes sfts)
72 |
73 | let makeCMPHover (opc,sfts) func =
74 | sprintf """
75 | *%s op1, op2; %s*
76 |
77 | **%s R0, R1**
78 |
79 | **%s R5, #101**
80 |
81 | **%s R10, #0x5a**
82 |
83 | **%s R7, %s**
84 | """ opc func opc opc opc opc (makeShiftModes sfts)
85 |
86 | let makeLDRSTRHover opc func =
87 | sprintf """
88 | *%s Rd, EA; %s*
89 |
90 | **%s R0, [R10]**
91 |
92 | **%s R5, [R9,#100]**
93 |
94 | **%s R1, [R1], #0x5a**
95 |
96 | **%s R8, [R13, #-32]!**
97 |
98 | **%s R3, [R4, R5]**
99 |
100 | **%s R3, [R4, R5, LSL #2]!**
101 | """ opc func opc opc opc opc opc opc
102 |
103 | let makeLDMSTMHover opc func =
104 | sprintf """
105 | *%s Rs[!], {register-list}; %s*
106 |
107 | **LDMFD R0!, {R1}**
108 |
109 | **STMFD R10!, {R2,R14}**
110 |
111 | **LDMIB R10, {R2-R9,R11}**
112 | """ opc func
113 |
114 | let makeMISCHover opc func =
115 | let initLine =
116 | match opc with
117 | | "DCD" | "DCB" | "dcd" | "dcb" -> "op1, ..., opn; "
118 | | "FILL" | "fill" -> "op1 ; "
119 | | _ -> failwithf "%s is not a MISC opcode" opc
120 | sprintf """
121 | *%s %s %s*
122 |
123 | **DCD op1, ..., opn**
124 |
125 | **DCB op1, ..., opn**
126 |
127 | **FILL N**
128 | """ opc initLine func
129 |
130 | let makeEQUHover opc func =
131 | sprintf """
132 | *%s op1; %s*
133 |
134 | **X1 EQU 44**
135 |
136 | **MULTDATA EQU DATA1 + 0x100**
137 |
138 | **PTR EQU (X1 - 12) * 4 + X2**
139 | """ opc func
140 |
141 | let makeDPHover3 (opc,sfts) func =
142 | sprintf """
143 | *%s dest, op1, op2; %s*
144 |
145 | **%s R0, R1, R2**
146 |
147 | **%s R5, R5, #101**
148 |
149 | **%s R10, R0, #0x5a**
150 |
151 | **%s R7, R10, %s**
152 |
153 | """ opc func opc opc opc opc (makeShiftModes sfts)
154 |
155 | let unimplementedHover opc =
156 | sprintf " '%s': There is a problem with this instruction" opc
157 |
158 |
159 | let getOpcHover mess opc line =
160 | //printfn "getting hover: opc='%s' line='%s'" opc line
161 | let uLine =
162 | String.toUpper (line + " ")
163 | |> String.replaceChar ',' ' '
164 | |> String.replaceChar '#' ' '
165 | if opc = "" then failwithf "can't get hover for '' opcode"
166 | let lineContains lst = List.tryFind (fun sft -> String.contains sft uLine) lst
167 | let isShift = lineContains [" LSL";" LSR";" ASR";" ROR"]
168 | let isRRX = lineContains [" RRX"]
169 | let isBadShift = lineContains [" ASL ";" ROL "; " RRL "]
170 | let _, legend,typ = getRoot opc
171 | let opc' = opc,(isShift,isRRX,isBadShift)
172 | let hoverText =
173 | match typ with
174 | | DP3 -> mess + makeDPHover3 opc' legend
175 | | DP2 -> mess + makeDPHover2 opc' legend
176 | | CMP -> mess + makeCMPHover opc' legend
177 | | MISC -> mess + makeMISCHover opc legend
178 | | LDRSTR -> mess + makeLDRSTRHover opc legend
179 | | LDMSTM -> mess + makeLDMSTMHover opc legend
180 | | EQU -> mess + makeEQUHover opc legend
181 | | UNIMPLEMENTED -> unimplementedHover opc
182 | |> (fun s -> [s])
183 | let stripComment line =
184 | match String.split [|';'|] line |> Array.toList with
185 | | ins :: _ -> ins
186 | | _ -> failwithf "What? split should return at least one item!"
187 | let oLen = opc.Length
188 | let splitLine =
189 | " " + (stripComment line) + " "
190 | |> String.splitString [|opc|]
191 | |> Array.toList
192 | |> List.rev
193 | let oStart =
194 | match splitLine with
195 | | _afterPart :: before -> List.sumBy String.length before + 1
196 | | x -> failwithf "What? Unexpected split '%A' can't happen. line = '%s', opc = '%s'." x line opc
197 | let lineText = sprintf "```\n%s\n```\n" (stripComment line)
198 | if oStart + oLen - 1 >= line.Length then
199 | ([lineText] @ hoverText), (1, lineText.Length)
200 | else ([lineText] @ hoverText), (oStart, oStart + oLen - 1)
201 |
202 |
203 |
204 |
205 |
--------------------------------------------------------------------------------
/src/Renderer/Files.fs:
--------------------------------------------------------------------------------
1 | module Files
2 |
3 | open EEExtensions
4 | open Fable.Core.JsInterop
5 | open Fable.Import
6 | open Fable.Import.Electron
7 | open Node.Exports
8 | open Refs
9 | open Elmish
10 |
11 | let writeToFile str path =
12 | let errorHandler _err = // TODO: figure out how to handle errors which can occur
13 | ()
14 | fs.writeFile (path, str, errorHandler)
15 |
16 | /// merge 2 maps into 1
17 | /// if key repeated, the ones in the old map are kept
18 | let mapMerge newMap =
19 | newMap
20 | |> Map.fold (fun map key value ->
21 | Map.add key value map)
22 |
23 | /// return the file name from the file path
24 | let fileName path =
25 | path
26 | |> String.toList
27 | |> List.rev
28 | |> List.takeWhile (fun x -> x <> '/')
29 | |> List.rev
30 | |> List.toString
31 |
32 | /// return file path without file name
33 | let filePathSetting path =
34 | path
35 | |> String.toList
36 | |> List.rev
37 | |> List.skipWhile (fun x -> x <> '/')
38 | |> List.rev
39 | |> List.toString
40 |
41 | /// format the list of files into a list of Editors
42 | let openLstOfFiles (fLst : string list) : Editor List =
43 | let readFile (path:string) =
44 | Node.Exports.fs.readFileSync (path, "utf8")
45 | fLst
46 | |> List.map (fun x ->
47 | { DefaultValue = readFile x
48 | FilePath = Some x
49 | FileName = x |> fileName |> Some
50 | IEditor = Option.None
51 | Saved = true })
52 |
53 | let fileFilterOpts =
54 | ResizeArray [
55 | createObj [
56 | "name" ==> "Assembly Code"
57 | "extensions" ==> ResizeArray [ "s" ]
58 | ]
59 | ] |> Some
60 |
61 | /// open file dialog
62 | let openFile currentFilePath (dispatch : Msg -> Unit) =
63 | let options = createEmpty
64 | options.properties <- ResizeArray([ "openFile"; "multiSelections" ]) |> Some
65 | options.filters <- fileFilterOpts
66 | options.defaultPath <- Some currentFilePath
67 | // path of the opened files
68 | let seq = electron.remote.dialog.showOpenDialog (options) /// open dialog
69 | let fileLst =
70 | match isUndefined seq with
71 | | true -> /// the dialog is cancelled, so seq is undefined
72 | []
73 | | false ->
74 | seq
75 | |> Seq.toList
76 | |> openLstOfFiles
77 | OpenFile fileLst |> dispatch
78 |
79 | /// save file dialog
80 | let saveFileAs filePathSetting (editor : Editor) dispatch : (unit) =
81 | let options = createEmpty
82 | options.filters <- fileFilterOpts
83 | let savedFilePath =
84 | match editor.FilePath with
85 | | Some x -> x
86 | | _ -> filePathSetting
87 | options.defaultPath <- Some savedFilePath
88 | /// path of the saved file
89 | let result = electron.remote.dialog.showSaveDialog (options) ///open the save file dialog
90 | match isUndefined result with
91 | | true ->
92 | SaveAsFile Option.None |> dispatch
93 | | false ->
94 | writeToFile (editor.IEditor?getValue ()) result
95 | let fileInfo = result, fileName result
96 | fileInfo |> Some |> SaveAsFile |> dispatch
97 |
98 | /// top-level function for saving file
99 | /// open the save dialog when necessary
100 | let saveFileUpdate info settingTabs =
101 | match info.TabId, settingTabs with
102 | | -1, _ ->
103 | info, Cmd.none
104 | | id, Some x when x = id ->
105 | info, Cmd.ofMsg SaveSettingsOnly
106 | | id, _ ->
107 | let filePath = info.Editors.[id].FilePath
108 | match filePath with
109 | | Option.None ->
110 | info,
111 | SaveAsDl
112 | |> UpdateDialogBox
113 | |> Cmd.ofMsg /// open the dialog
114 | | Some fPath ->
115 | let currentEditor = info.Editors.[id]
116 | writeToFile (currentEditor.IEditor?getValue ()) fPath
117 | let newEditors =
118 | Map.add id
119 | { currentEditor with Saved = true }
120 | info.Editors
121 | { Editors = newEditors
122 | TabId = info.TabId },
123 | Cmd.none
124 |
125 | /// top-level function for save file as
126 | /// open the save file dialog when necessary
127 | let saveAsFileDialogUpdate =
128 | function
129 | | -1, _ -> Cmd.none /// make sure sure no other dialog is opened and there is at least one tab
130 | | x, Some y when x = y -> Cmd.ofMsg SaveSettingsOnly
131 | | _ -> SaveAsDl |> UpdateDialogBox |> Cmd.ofMsg
132 |
133 | /// top-level function for opening up the open file dialog
134 | let saveAsFileUpdate (info, filePathSettingStr)
135 | fileInfo =
136 | match fileInfo with
137 | | Option.None ->
138 | info, filePathSettingStr
139 | | Some (filePath, fileName) ->
140 | let newEditor =
141 | { info.Editors.[info.TabId] with FilePath = Some filePath
142 | FileName = Some fileName
143 | Saved = true }
144 | let newEditors =
145 | info.Editors
146 | |> Map.add info.TabId
147 | newEditor
148 | |> Map.filter (fun key value ->
149 | key = info.TabId ||
150 | value.FilePath <> newEditor.FilePath)
151 | let newFilePathSettings = filePathSetting filePath
152 | { info with Editors = newEditors }, newFilePathSettings
153 |
154 | /// top-level function for opening file
155 | let openFileUpdate (info, filePath)
156 | editor =
157 | let newId = uniqueTabId info.Editors
158 | let length = List.length editor
159 | match length with
160 | | 0 -> // no file is selected to be opened
161 | filePath, info
162 | | _ ->
163 | let newEditors =
164 | editor
165 | // zip it with number so it can be convert into map
166 | // number start at the unique tab id to avoid replacement
167 | |> List.zip [newId .. newId + length - 1]
168 | |> List.filter (fun (_, x) ->
169 | // check if the files are already opened
170 | info.Editors
171 | |> Map.forall (fun _ value ->
172 | value.FilePath <> x.FilePath))
173 | |> Map.ofList
174 | let mergedEditors = mapMerge newEditors info.Editors
175 | let currentEditor = List.head editor // find the first opened file
176 | let newId = // make the first file as current tab
177 | mergedEditors
178 | |> Map.findKey (fun _ value ->
179 | value.FilePath = currentEditor.FilePath)
180 | mergedEditors.[newId].FilePath.Value
181 | |> filePathSetting,
182 | { TabId = newId
183 | Editors = mergedEditors }
--------------------------------------------------------------------------------
/src/Renderer/MenuBar.fs:
--------------------------------------------------------------------------------
1 | module MenuBar
2 |
3 | open EEExtensions
4 | open Fable.Core
5 | open Fable.Core.JsInterop
6 | open Fable.Import
7 | open Fable.Import.Electron
8 | open Node.Base
9 | open Refs
10 | open Views
11 | open Elmish
12 | open Integration
13 | open Tests
14 | open Testbench
15 |
16 | let runExtPage url () =
17 | electron.shell.openExternal url |> ignore
18 |
19 | let display runMode =
20 | match runMode with
21 | | ExecutionTop.ResetMode -> "ResetMode"
22 | | ExecutionTop.FinishedMode _ -> "FinishedMode"
23 | | ExecutionTop.ActiveMode _ -> "ActiveMode"
24 | | ExecutionTop.ParseErrorMode -> "ParseErrorMode"
25 | | ExecutionTop.RunErrorMode _ -> "RunErrorMode"
26 |
27 | /// Wrap an action so that it can only happen if simulator is stopped.
28 | /// Converts unit -> unit into obj. Must be called as fun () -> interlock actionName action.
29 | /// Suitable for use as JS callback.
30 | let interlock (actionName : string) debugLevel runMode dispatch msg =
31 | let action = fun _ -> msg |> dispatch
32 | if debugLevel > 0 then printf "Interlock : runMode=%A" (display runMode)
33 | match runMode with
34 | | ExecutionTop.ResetMode
35 | | ExecutionTop.ParseErrorMode ->
36 | action ()
37 | | _ ->
38 | ((sprintf "Can't %s while simulator is running
Reset and %s
" actionName actionName), msg)
39 | |> ResetEmulatorDl
40 | |> UpdateDialogBox
41 | |> dispatch
42 |
43 | /// Wrap an action so that it can only happen if simulator is stopped.
44 | /// Operates on (Unit->Unit) to make (Unit->Unit).
45 | /// Suitable for use as action in menu.
46 | let interlockAction (actionName : string) debugLevel runMode dispatch msg = (fun () ->
47 | interlock actionName debugLevel runMode dispatch msg|> ignore
48 | )
49 |
50 | (****************************************************************************************************
51 | *
52 | * MENU OPERATIONS
53 | *
54 | ****************************************************************************************************)
55 |
56 | let loadDemo (editors : Map) =
57 | let sampleFileName = Tests.sampleDir + "karatsuba.s"
58 | let txt =
59 | Node.Exports.fs.readFileSync (sampleFileName, "utf8")
60 | let newEditor =
61 | { DefaultValue = txt
62 | FileName = Option.None
63 | FilePath = Option.None
64 | IEditor = Option.None
65 | Saved = true }
66 | let newId = Refs.uniqueTabId editors
67 | let newEditors= Map.add newId newEditor editors
68 | { Editors = newEditors
69 | TabId = newId }
70 |
71 | (****************************************************************************************************
72 | *
73 | * MENU HELPER FUNCTIONS
74 | *
75 | ****************************************************************************************************)
76 |
77 |
78 | let menuSeparator =
79 | let sep = createEmpty
80 | sep.``type`` <- Some Separator
81 | sep
82 |
83 | /// Make action menu item from name, opt key to trigger, and action.
84 | let makeItem (label : string) (accelerator : string option) (iAction : unit -> unit) =
85 | let handlerCaster f = System.Func