Compare commits
5 Commits
RamEditor
...
loadExampl
Author | SHA1 | Date | |
---|---|---|---|
8e131d3ee4 | |||
182662e2e0 | |||
dc9b5c725e | |||
20fb9914ef | |||
0aa08315d1 |
3
elm.json
3
elm.json
@ -9,9 +9,12 @@
|
|||||||
"elm/browser": "1.0.2",
|
"elm/browser": "1.0.2",
|
||||||
"elm/core": "1.0.5",
|
"elm/core": "1.0.5",
|
||||||
"elm/html": "1.0.0",
|
"elm/html": "1.0.0",
|
||||||
|
"elm/http": "2.0.0",
|
||||||
"elm/json": "1.1.3"
|
"elm/json": "1.1.3"
|
||||||
},
|
},
|
||||||
"indirect": {
|
"indirect": {
|
||||||
|
"elm/bytes": "1.0.8",
|
||||||
|
"elm/file": "1.0.5",
|
||||||
"elm/time": "1.0.0",
|
"elm/time": "1.0.0",
|
||||||
"elm/url": "1.0.0",
|
"elm/url": "1.0.0",
|
||||||
"elm/virtual-dom": "1.0.2"
|
"elm/virtual-dom": "1.0.2"
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
@media (prefers-color-scheme: dark){
|
||||||
:root {
|
:root {
|
||||||
--color-black: #05050F;
|
--color-black: #05050F;
|
||||||
--color-white: #FFFFFF;
|
--color-white: #FFFFFF;
|
||||||
@ -39,7 +40,7 @@
|
|||||||
|
|
||||||
|
|
||||||
--color-body: var(--color-black);
|
--color-body: var(--color-black);
|
||||||
--color-body-text: var(--color-black);
|
--color-body-text: var(--color-white);
|
||||||
|
|
||||||
--color-addressbus: var(--color-addressbus-main);
|
--color-addressbus: var(--color-addressbus-main);
|
||||||
--color-addressbus-text: var(--color-white);
|
--color-addressbus-text: var(--color-white);
|
||||||
@ -73,18 +74,33 @@
|
|||||||
--color-table-ram-head-text: var(--color-white);
|
--color-table-ram-head-text: var(--color-white);
|
||||||
--color-table-ram-highlight: var(--color-ram-light2);
|
--color-table-ram-highlight: var(--color-ram-light2);
|
||||||
--color-table-ram-highlight-text: var(--color-black);
|
--color-table-ram-highlight-text: var(--color-black);
|
||||||
|
--color-table-ram-select: transparent;
|
||||||
|
--color-table-ram-select-text: inherit;
|
||||||
|
--color-table-ram-select-border: var(--color-grey-light2);
|
||||||
|
|
||||||
--color-table-cu-head: var(--color-cu-dark1);
|
--color-table-cu-head: var(--color-cu-dark1);
|
||||||
--color-table-cu-head-text: var(--color-white);
|
--color-table-cu-head-text: var(--color-white);
|
||||||
--color-table-cu-highlight: var(--color-cu-light2);
|
--color-table-cu-highlight: var(--color-cu-light2);
|
||||||
--color-table-cu-highlight-text: var(--color-black);
|
--color-table-cu-highlight-text: var(--color-black);
|
||||||
|
--color-table-cu-select: transparent;
|
||||||
|
--color-table-cu-select-text: inherit;
|
||||||
|
--color-table-cu-select-border: var(--color-grey-light2);
|
||||||
|
|
||||||
--color-arrow: var(--color-arrow-main);
|
--color-arrow: var(--color-arrow-main);
|
||||||
--color-arrow-text: var(--color-white);
|
--color-arrow-text: var(--color-white);
|
||||||
--color-arrow-text-hover: var(--color-white-light2);
|
--color-arrow-text-hover: var(--color-white-light2);
|
||||||
--color-arrow-border: var(--color-black-light1);
|
--color-arrow-border: var(--color-black-light1);
|
||||||
|
|
||||||
|
--color-modal: var(--color-black);
|
||||||
|
--color-modal-text: var(--color-white);
|
||||||
|
--color-modal-shadow: rgba( 0,0,0, 0.4 );
|
||||||
|
|
||||||
|
--color-code: var(--color-black-light1);
|
||||||
|
--color-code-text: var(--color-white);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* https://coolors.co/aa8f66-ed9b40-ffeedb-61c9a8-ba3b46-071013 */
|
/* https://coolors.co/aa8f66-ed9b40-ffeedb-61c9a8-ba3b46-071013 */
|
||||||
/* https://coolors.co/faf3dd-000022-9c528b-62a87c-247ba0-429ea6-8fb8de-72705b */
|
/* https://coolors.co/faf3dd-000022-9c528b-62a87c-247ba0-429ea6-8fb8de-72705b */
|
||||||
|
|
||||||
|
}
|
@ -89,6 +89,13 @@
|
|||||||
--color-arrow-text: var(--color-white);
|
--color-arrow-text: var(--color-white);
|
||||||
--color-arrow-text-hover: var(--color-white-light2);
|
--color-arrow-text-hover: var(--color-white-light2);
|
||||||
--color-arrow-border: var(--color-black-light1);
|
--color-arrow-border: var(--color-black-light1);
|
||||||
|
|
||||||
|
--color-modal: var(--color-white-light1);
|
||||||
|
--color-modal-text: var(--color-black);
|
||||||
|
--color-modal-shadow: rgba( 0,0,0, 0.4 );
|
||||||
|
|
||||||
|
--color-code: var(--color-white-light2);
|
||||||
|
--color-code-text: var(--color-black);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
36
out/css/cookie.css
Normal file
36
out/css/cookie.css
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
.cookie-banner{
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100vw;
|
||||||
|
height: min-content;
|
||||||
|
|
||||||
|
background-color: white;
|
||||||
|
border-top: 1px solid black;
|
||||||
|
|
||||||
|
padding: .75rem 2rem;
|
||||||
|
z-index: 2500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cookie-banner button {
|
||||||
|
display: inline;
|
||||||
|
height: 2.5rem;
|
||||||
|
padding: .5rem 1rem;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cookie-banner * {
|
||||||
|
margin-right: 1rem !important;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cookie-banner > :first-child {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cookie-banner > :last-child {
|
||||||
|
margin-right: 0 !important;
|
||||||
|
}
|
589
out/css/pc.css
Normal file
589
out/css/pc.css
Normal file
@ -0,0 +1,589 @@
|
|||||||
|
/* COLORS */
|
||||||
|
.pc .addressbus {
|
||||||
|
background-color: var(--color-addressbus);
|
||||||
|
color: var(--color-addressbus-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .databus {
|
||||||
|
background-color: var(--color-databus);
|
||||||
|
color: var(--color-databus-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .ram {
|
||||||
|
background-color: var(--color-ram);
|
||||||
|
color: var(--color-ram-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .cu {
|
||||||
|
background-color: var(--color-cu);
|
||||||
|
color: var(--color-cu-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .alu {
|
||||||
|
background-color: var(--color-alu);
|
||||||
|
color: var(--color-alu-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .section h1.header {
|
||||||
|
background-color: var(--color-header);
|
||||||
|
color: var(--color-header-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* TABLE COLORS */
|
||||||
|
.pc .ram .scroller table thead.head th {
|
||||||
|
background-color: var(--color-table-ram-head);
|
||||||
|
color: var(--color-table-ram-head-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .cu .scroller table thead.head th {
|
||||||
|
background-color: var(--color-table-cu-head);
|
||||||
|
color: var(--color-table-cu-head-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .scroller table tr td {
|
||||||
|
background-color: var(--color-table-row);
|
||||||
|
color: var(--color-table-text);
|
||||||
|
border-bottom: 1px solid var(--color-table-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .scroller table tr:nth-child(even) td{
|
||||||
|
background-color: var(--color-table-row-alt);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .scroller table tr.empty td {
|
||||||
|
color: var(--color-table-text-empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .ram .scroller table tr.current td {
|
||||||
|
background-color: var(--color-table-ram-highlight);
|
||||||
|
color: var(--color-table-ram-highlight-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .cu .scroller table tr.current td {
|
||||||
|
background-color: var(--color-table-cu-highlight);
|
||||||
|
color: var(--color-table-cu-highlight-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.pc button,
|
||||||
|
.pc .button{
|
||||||
|
text-transform: none !important;
|
||||||
|
font-weight: 600;
|
||||||
|
height: 2.5em;
|
||||||
|
line-height: 1em;
|
||||||
|
margin: 0;
|
||||||
|
vertical-align: top;
|
||||||
|
padding: 0.25em 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CONTROLS COLORS */
|
||||||
|
.controls button, .controls .button {
|
||||||
|
/* background-color: whitesmoke; */
|
||||||
|
color: var(--color-controls-button-text);
|
||||||
|
border-color: var(--color-controls-button-border);
|
||||||
|
}
|
||||||
|
.controls button:hover, .controls .button:hover{
|
||||||
|
color: var(--color-controls-button-text-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .controls .checker::before {
|
||||||
|
border: 1px solid var(--color-controls-button-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .controls .checker.checked::before {
|
||||||
|
color: var(--color-controls-button-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* FORMATTING STUFF */
|
||||||
|
|
||||||
|
.pc {
|
||||||
|
/*height: 400px;
|
||||||
|
height: 99vh;*/
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
padding: 1em;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto auto auto;
|
||||||
|
/* grid-template-columns: max-content auto max-content; */
|
||||||
|
gap: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .grid-fullwidth{
|
||||||
|
grid-column: 1 / span 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .section {
|
||||||
|
min-height: 25em;
|
||||||
|
max-height: calc(80vh - 8em);
|
||||||
|
min-width: 20%;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 2.5em 1em 1em 1em;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
/*top: 0;
|
||||||
|
left: 0;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .section h1.header {
|
||||||
|
font-size: 1.2em;
|
||||||
|
position: absolute;
|
||||||
|
top: 3px;
|
||||||
|
left: 4px;
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .scroller {
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: scroll;
|
||||||
|
|
||||||
|
/*position: relative;*/
|
||||||
|
|
||||||
|
/* max-height: 60%; */
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
margin: 1em 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .scroller:last-child {
|
||||||
|
margin-bottom: -1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .scroller table {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .scroller table thead.head {
|
||||||
|
position: sticky;
|
||||||
|
top: -2px;
|
||||||
|
left: 0;
|
||||||
|
height: 1em;
|
||||||
|
padding: 1em;
|
||||||
|
|
||||||
|
transition: 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .scroller table thead th {
|
||||||
|
position: -webkit-sticky;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .scroller table thead.head.shrunk {
|
||||||
|
height: .5rem;
|
||||||
|
font-size: .8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .scroller table thead.head th {
|
||||||
|
padding: 12px 4px 12px 15px;
|
||||||
|
transition: 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .scroller table thead.head.shrunk th {
|
||||||
|
padding-top: .2em;
|
||||||
|
padding-bottom: .2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .scroller table .num {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .scroller table td:first-child,
|
||||||
|
.pc .scroller table td:last-child {
|
||||||
|
padding: 12px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .scroller table tr.empty td {
|
||||||
|
padding: 3px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .scroller table tbody button:last-child {
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: none;
|
||||||
|
height: max-content;
|
||||||
|
line-height: 2em;
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: inherit;
|
||||||
|
padding: 0px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .scroller tr:first-child td{
|
||||||
|
padding-top: 1.5rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
th.address {
|
||||||
|
width: 5rem;
|
||||||
|
padding-left: 8px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc input[type=number] {
|
||||||
|
margin: 0 .5em 0 0;
|
||||||
|
padding: 0 .25em;
|
||||||
|
height: 2.5rem;
|
||||||
|
line-height: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc input[type=number].instruction {
|
||||||
|
width: 5em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc input[type=number].address {
|
||||||
|
width: 7em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* CONTROLS */
|
||||||
|
.pc .controls > :not(:last-child) {
|
||||||
|
margin-right: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .controls .checker {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: 3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .controls .checker label {
|
||||||
|
display: inline;
|
||||||
|
/*font-size: 0.8em;*/
|
||||||
|
white-space: initial;
|
||||||
|
white-space: break-spaces;
|
||||||
|
text-transform: none;
|
||||||
|
width: 6em;
|
||||||
|
width: min-content;
|
||||||
|
vertical-align: middle;
|
||||||
|
line-height: .9em;
|
||||||
|
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .controls input[type=checkbox]{
|
||||||
|
display: none;
|
||||||
|
margin-left: -1em;
|
||||||
|
margin-right: 1em;
|
||||||
|
opacity: 0;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .controls .checker::before{
|
||||||
|
content: "✔";
|
||||||
|
display: inline-block;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
color: rgba(0,0,0,0);
|
||||||
|
border-radius: 4px;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin: 0 .5em 0 -1em;
|
||||||
|
|
||||||
|
line-height: 1.8rem;
|
||||||
|
font-size: 1.4em;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* END CONTROLS */
|
||||||
|
|
||||||
|
/* RAM */
|
||||||
|
|
||||||
|
.pc .ram .scroller {
|
||||||
|
/* height: 100%; */
|
||||||
|
/* padding: 0.2em; */
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .ram .scroller table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .ram input[type=number] {
|
||||||
|
background-color: var(--color-table-ram-select);
|
||||||
|
color: var(--color-table-ram-select-text);
|
||||||
|
border-color: var(--color-table-ram-select-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .ram table tr td:nth-child(2){
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .ram .scroller table tbody button:last-child{
|
||||||
|
background-color: var(--color-table-ram-select);
|
||||||
|
color: var(--color-table-ram-select-text);
|
||||||
|
border-color: var(--color-table-ram-select-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* CONTROL UNIT */
|
||||||
|
|
||||||
|
.pc .cu p {
|
||||||
|
margin: 0 0 .2em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .cu .scroller table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .cu .input-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0 0 .5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .cu .input-row:last-child {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .cu input {
|
||||||
|
color: var(--color-cu-text);
|
||||||
|
border-color: var(--color-cu-text);
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .cu input[type=number] {
|
||||||
|
width: 12.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .cu label {
|
||||||
|
display: inline;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .cu select{
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
background-color: var(--color-table-cu-select);
|
||||||
|
color: var(--color-table-cu-select-text);
|
||||||
|
border: 1px solid var(--color-table-cu-select-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .cu .scroller table tbody button:last-child {
|
||||||
|
background-color: var(--color-table-cu-select);
|
||||||
|
color: var(--color-table-cu-select-text);
|
||||||
|
border: 1px solid var(--color-table-cu-select-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .cu button,
|
||||||
|
.pc .cu .button {
|
||||||
|
height: 2.5rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
color: var(--color-cu-text);
|
||||||
|
border-color: var(--color-cu-text);
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ALU */
|
||||||
|
.pc .alu input, .pc .alu .button, .pc .alu button{
|
||||||
|
color: var(--color-alu-text);
|
||||||
|
border-color: var(--color-alu-text);
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .alu button {
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .alu button:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BUSSES */
|
||||||
|
|
||||||
|
.pc .databus,
|
||||||
|
.pc .addressbus{
|
||||||
|
/*position: relative;*/
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
margin: 0;
|
||||||
|
padding: .75em .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .databus .label,
|
||||||
|
.pc .addressbus .label {
|
||||||
|
/* position: absolute; */
|
||||||
|
/* left: .5em; */
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .addressbus input {
|
||||||
|
color: var(--color-addressbus-text);
|
||||||
|
border-color: var(--color-addressbus-text);
|
||||||
|
background-color: var(--color-addressbus);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .databus input {
|
||||||
|
color: var(--color-databus-text);
|
||||||
|
border-color: var(--color-databus-text);
|
||||||
|
background-color: var(--color-databus);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .addressbus {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .databus {
|
||||||
|
margin-top: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARROWS */
|
||||||
|
.pc .arrow {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
width: 3rem;
|
||||||
|
height: 5rem;
|
||||||
|
|
||||||
|
/* transform: rotate(90deg) translate(1.5rem, 2.5rem) ; */
|
||||||
|
transform: translate(0, 3rem);
|
||||||
|
z-index: 100;
|
||||||
|
|
||||||
|
font-size: 0.5em;
|
||||||
|
color: var(--color-arrow-text);
|
||||||
|
background-color: var(--color-arrow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .arrow.down {
|
||||||
|
left: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .arrow.up {
|
||||||
|
left: 75%;
|
||||||
|
transform: rotate(180deg) translate(0, -4.5rem);
|
||||||
|
}
|
||||||
|
.pc .arrow.up > :nth-child(1){
|
||||||
|
/* transform: rotate(90deg) translate(0rem, 2rem); */
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .arrow.up.arrow2 {
|
||||||
|
left: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .arrow.top {
|
||||||
|
bottom: auto;
|
||||||
|
top: -6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.pc .arrow > :nth-child(1) {
|
||||||
|
font-size: 1.2em;
|
||||||
|
line-height: 1.1em;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-arrow-text) !important;
|
||||||
|
background-color: var(--color-arrow) !important;
|
||||||
|
border-color: var(--color-arrow-text) !important;
|
||||||
|
text-transform: none;
|
||||||
|
padding: 2px 10px;
|
||||||
|
margin: 0;
|
||||||
|
/* transform: rotate(-90deg) translate(0rem, -2rem); */
|
||||||
|
|
||||||
|
white-space: normal;
|
||||||
|
height: min-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .arrow > :nth-child(1) *{
|
||||||
|
color: var(--color-arrow-text);
|
||||||
|
display: block;
|
||||||
|
white-space: break-spaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .arrow > :nth-child(1):hover, .pc .arrow > :nth-child(1) *:hover {
|
||||||
|
color: var(--color-arrow-text-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pc .arrow > :nth-child(2) {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
|
||||||
|
border-left: 2.5rem solid transparent;
|
||||||
|
border-right: 2.5rem solid transparent;
|
||||||
|
border-top: 2rem solid var(--color-arrow);
|
||||||
|
border-bottom: 0rem solid transparent;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
left: -1rem;
|
||||||
|
bottom: -2rem;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* MODALS */
|
||||||
|
.modal {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.modal.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-card {
|
||||||
|
z-index: 1500;
|
||||||
|
display: block;
|
||||||
|
width: 40em;
|
||||||
|
min-width: 45vw;
|
||||||
|
min-height: 5em;
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
padding: 2.5em 2em 1em 2em;
|
||||||
|
|
||||||
|
background-color: var(--color-modal);
|
||||||
|
color: var(--color-modal-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal > :first-child {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
background-color: var(--color-modal-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal .modal-close {
|
||||||
|
position: absolute;
|
||||||
|
top: .5em;
|
||||||
|
right: .5em;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal .modal-close::before {
|
||||||
|
content: "❌";
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
@ -1,511 +1,41 @@
|
|||||||
/* COLORS */
|
|
||||||
body {
|
body {
|
||||||
background-color: var(--color-body);
|
background-color: var(--color-body);
|
||||||
color: var(--color-body-text);
|
color: var(--color-body-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pc .addressbus {
|
code {
|
||||||
background-color: var(--color-addressbus);
|
background-color: var(--color-code);
|
||||||
color: var(--color-addressbus-text);
|
border-color: var(--color-code-text);
|
||||||
|
color: var(--color-code-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pc .databus {
|
.noscript {
|
||||||
background-color: var(--color-databus);
|
box-sizing: border-box;
|
||||||
color: var(--color-databus-text);
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pc .ram {
|
.spacer {
|
||||||
background-color: var(--color-ram);
|
height: 3rem;
|
||||||
color: var(--color-ram-text);
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pc .cu {
|
.hidden {
|
||||||
background-color: var(--color-cu);
|
display: none !important;
|
||||||
color: var(--color-cu-text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.pc .alu {
|
section.fullheight {
|
||||||
background-color: var(--color-alu);
|
min-height: 100vh;
|
||||||
color: var(--color-alu-text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.pc .section h1.header {
|
footer{
|
||||||
background-color: var(--color-header);
|
margin-top: 20rem;
|
||||||
color: var(--color-header-text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* TABLE COLORS */
|
|
||||||
.pc .ram .scroller table thead.head th {
|
|
||||||
background-color: var(--color-table-ram-head);
|
|
||||||
color: var(--color-table-ram-head-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .cu .scroller table thead.head th {
|
|
||||||
background-color: var(--color-table-cu-head);
|
|
||||||
color: var(--color-table-cu-head-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .scroller table tr td {
|
|
||||||
background-color: var(--color-table-row);
|
|
||||||
color: var(--color-table-text);
|
|
||||||
border-bottom: 1px solid var(--color-table-border);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .scroller table tr:nth-child(even) td{
|
|
||||||
background-color: var(--color-table-row-alt);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .scroller table tr.empty td {
|
|
||||||
color: var(--color-table-text-empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .ram .scroller table tr.current td {
|
|
||||||
background-color: var(--color-table-ram-highlight);
|
|
||||||
color: var(--color-table-ram-highlight-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .cu .scroller table tr.current td {
|
|
||||||
background-color: var(--color-table-cu-highlight);
|
|
||||||
color: var(--color-table-cu-highlight-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* CONTROLS COLORS */
|
|
||||||
.controls button, .controls .button {
|
|
||||||
/* background-color: whitesmoke; */
|
|
||||||
color: var(--color-controls-button-text);
|
|
||||||
border-color: var(--color-controls-button-border);
|
|
||||||
}
|
|
||||||
.controls button:hover, .controls .button:hover{
|
|
||||||
color: var(--color-controls-button-text-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .controls .checker::before {
|
|
||||||
border: 1px solid var(--color-controls-button-border);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .controls .checker.checked::before {
|
|
||||||
color: var(--color-controls-button-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* FORMATTING STUFF */
|
|
||||||
|
|
||||||
button {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc {
|
|
||||||
height: 400px;
|
|
||||||
height: 99vh;
|
|
||||||
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
padding: 1em;
|
|
||||||
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: auto auto auto;
|
|
||||||
/* grid-template-columns: max-content auto max-content; */
|
|
||||||
gap: 9px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .grid-fullwidth{
|
|
||||||
grid-column: 1 / span 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .section {
|
|
||||||
min-height: 25em;
|
|
||||||
max-height: calc(80vh - 8em);
|
|
||||||
min-width: 20%;
|
|
||||||
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 2.5em 1em 1em 1em;
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
position: relative;
|
|
||||||
/*top: 0;
|
|
||||||
left: 0;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .section h1.header {
|
|
||||||
font-size: 1.2em;
|
|
||||||
position: absolute;
|
|
||||||
top: 3px;
|
|
||||||
left: 4px;
|
|
||||||
padding: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .row {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-evenly;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .scroller {
|
|
||||||
overflow-x: auto;
|
|
||||||
overflow-y: scroll;
|
|
||||||
|
|
||||||
/*position: relative;*/
|
|
||||||
|
|
||||||
/* max-height: 60%; */
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
margin: 1em 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .scroller:last-child {
|
|
||||||
margin-bottom: -1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .scroller table thead.head {
|
|
||||||
position: sticky;
|
|
||||||
top: -2px;
|
|
||||||
left: 0;
|
|
||||||
height: 1em;
|
|
||||||
padding: 1em;
|
|
||||||
|
|
||||||
transition: 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .scroller table thead th {
|
|
||||||
position: -webkit-sticky;
|
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .scroller table thead.head.shrunk {
|
|
||||||
height: .5em;
|
|
||||||
font-size: .8em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .scroller table thead.head th {
|
|
||||||
padding: 12px 4px 12px 15px;
|
|
||||||
transition: 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .scroller table thead.head.shrunk th {
|
|
||||||
padding-top: .2em;
|
|
||||||
padding-bottom: .2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .scroller table .num {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .scroller table td:first-child,
|
|
||||||
.pc .scroller table td:last-child {
|
|
||||||
padding: 12px 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .scroller table tr.empty td {
|
|
||||||
padding: 3px 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .scroller table tbody button:last-child {
|
|
||||||
text-decoration: none;
|
|
||||||
text-transform: none;
|
|
||||||
height: max-content;
|
|
||||||
line-height: 2em;
|
|
||||||
font-weight: normal;
|
|
||||||
font-size: inherit;
|
|
||||||
padding: 0px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
th.address {
|
|
||||||
width: 5rem;
|
|
||||||
padding-left: 8px;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc input[type=number] {
|
|
||||||
margin: 0 .5em 0 0;
|
|
||||||
padding: 0 .25em;
|
|
||||||
height: 1.5em;
|
|
||||||
line-height: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* CONTROLS */
|
|
||||||
.pc .controls button,
|
|
||||||
.pc .controls .button{
|
|
||||||
text-transform: none !important;
|
|
||||||
font-weight: 600;
|
|
||||||
height: 2.5em;
|
|
||||||
line-height: 1em;
|
|
||||||
margin: 0;
|
|
||||||
vertical-align: top;
|
|
||||||
padding: 0.25em 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .controls > :not(:last-child) {
|
|
||||||
margin-right: 0.75em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .controls .checker {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
padding-left: 3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .controls .checker label {
|
|
||||||
display: inline;
|
|
||||||
/*font-size: 0.8em;*/
|
|
||||||
white-space: initial;
|
|
||||||
white-space: break-spaces;
|
|
||||||
text-transform: none;
|
|
||||||
width: 6em;
|
|
||||||
width: min-content;
|
|
||||||
vertical-align: middle;
|
|
||||||
line-height: .9em;
|
|
||||||
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .controls input[type=checkbox]{
|
|
||||||
display: none;
|
|
||||||
margin-left: -1em;
|
|
||||||
margin-right: 1em;
|
|
||||||
opacity: 0;
|
|
||||||
z-index: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .controls .checker::before{
|
|
||||||
content: "✔";
|
|
||||||
display: inline-block;
|
|
||||||
width: 2rem;
|
|
||||||
height: 2rem;
|
|
||||||
color: rgba(0,0,0,0);
|
|
||||||
border-radius: 4px;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin: 0 .5em 0 -1em;
|
|
||||||
|
|
||||||
line-height: 1.8rem;
|
|
||||||
font-size: 1.4em;
|
|
||||||
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* END CONTROLS */
|
|
||||||
|
|
||||||
/* RAM */
|
|
||||||
|
|
||||||
.pc .ram .scroller {
|
|
||||||
/* height: 100%; */
|
|
||||||
/* padding: 0.2em; */
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .ram .scroller table {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .ram input[type=number] {
|
|
||||||
background-color: var(--color-table-ram-select);
|
|
||||||
color: var(--color-table-ram-select-text);
|
|
||||||
border-color: var(--color-table-ram-select-border);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .ram input[type=number].instruction {
|
|
||||||
width: 5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .ram input[type=number].address {
|
|
||||||
width: 7em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .ram table tr td:nth-child(2){
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .ram .scroller table tbody button:last-child{
|
|
||||||
background-color: var(--color-table-ram-select);
|
|
||||||
color: var(--color-table-ram-select-text);
|
|
||||||
border-color: var(--color-table-ram-select-border);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* CONTROL UNIT */
|
|
||||||
|
|
||||||
.pc .cu p {
|
|
||||||
margin: 0 0 .2em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .cu .scroller table {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .cu .input-row {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: baseline;
|
|
||||||
margin: 0 0 .5em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .cu .input-row:last-child {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .cu input {
|
|
||||||
color: var(--color-cu-text);
|
|
||||||
border-color: var(--color-cu-text);
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .cu label {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .cu select{
|
|
||||||
margin: 0;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
background-color: var(--color-table-cu-select);
|
|
||||||
color: var(--color-table-cu-select-text);
|
|
||||||
border: 1px solid var(--color-table-cu-select-border);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .cu .scroller table tbody button:last-child {
|
|
||||||
background-color: var(--color-table-cu-select);
|
|
||||||
color: var(--color-table-cu-select-text);
|
|
||||||
border: 1px solid var(--color-table-cu-select-border);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ALU */
|
|
||||||
.pc .alu input {
|
|
||||||
color: var(--color-alu-text);
|
|
||||||
border-color: var(--color-alu-text);
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* BUSSES */
|
|
||||||
|
|
||||||
.pc .databus,
|
|
||||||
.pc .addressbus{
|
|
||||||
/*position: relative;*/
|
|
||||||
text-align: left;
|
|
||||||
|
|
||||||
margin: 0;
|
|
||||||
padding: .75em .5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .databus .label,
|
|
||||||
.pc .addressbus .label {
|
|
||||||
/* position: absolute; */
|
|
||||||
/* left: .5em; */
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .addressbus input {
|
|
||||||
color: var(--color-addressbus-text);
|
|
||||||
border-color: var(--color-addressbus-text);
|
|
||||||
background-color: var(--color-addressbus);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .databus input {
|
|
||||||
color: var(--color-databus-text);
|
|
||||||
border-color: var(--color-databus-text);
|
|
||||||
background-color: var(--color-databus);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .addressbus {
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pc .databus {
|
|
||||||
margin-top: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ARROWS */
|
|
||||||
.arrow {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 50%;
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
width: 3rem;
|
|
||||||
height: 5rem;
|
|
||||||
|
|
||||||
/* transform: rotate(90deg) translate(1.5rem, 2.5rem) ; */
|
|
||||||
transform: translate(0, 3rem);
|
|
||||||
z-index: 100;
|
|
||||||
|
|
||||||
font-size: 0.5em;
|
|
||||||
color: var(--color-arrow-text);
|
|
||||||
background-color: var(--color-arrow);
|
|
||||||
}
|
|
||||||
|
|
||||||
.arrow.down {
|
|
||||||
left: 25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arrow.up {
|
|
||||||
left: 75%;
|
|
||||||
transform: rotate(180deg) translate(0, -4.5rem);
|
|
||||||
}
|
|
||||||
.arrow.up > :nth-child(1){
|
|
||||||
/* transform: rotate(90deg) translate(0rem, 2rem); */
|
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.arrow.up.arrow2 {
|
|
||||||
left: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arrow.top {
|
|
||||||
bottom: auto;
|
|
||||||
top: -6rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.arrow > :nth-child(1) {
|
|
||||||
font-size: 1.2em;
|
|
||||||
line-height: 1.1em;
|
|
||||||
font-weight: 600;
|
|
||||||
color: var(--color-arrow-text);
|
|
||||||
background-color: var(--color-arrow);
|
|
||||||
border-color: var(--color-arrow-text);
|
|
||||||
text-transform: none;
|
|
||||||
padding: 2px 10px;
|
|
||||||
margin: 0;
|
|
||||||
/* transform: rotate(-90deg) translate(0rem, -2rem); */
|
|
||||||
|
|
||||||
white-space: normal;
|
|
||||||
height: min-content;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arrow > :nth-child(1) *{
|
|
||||||
color: var(--color-arrow-text);
|
|
||||||
display: block;
|
|
||||||
white-space: break-spaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arrow > :nth-child(1):hover, .arrow > :nth-child(1) *:hover {
|
|
||||||
color: var(--color-arrow-text-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
.arrow > :nth-child(2) {
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
|
|
||||||
border-left: 2.5rem solid transparent;
|
|
||||||
border-right: 2.5rem solid transparent;
|
|
||||||
border-top: 2rem solid var(--color-arrow);
|
|
||||||
border-bottom: 0rem solid transparent;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
left: -1rem;
|
|
||||||
bottom: -2rem;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
17
out/examples-list.json
Normal file
17
out/examples-list.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"available":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"title": "Simple Counter",
|
||||||
|
"version": "0.1",
|
||||||
|
"url": "examples/simple-counter.json",
|
||||||
|
"enabled": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Add 2 numbers(placeholder)",
|
||||||
|
"version": "0.1",
|
||||||
|
"url": "examples/adding.json",
|
||||||
|
"enabled": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
1
out/examples/simple-counter.json
Normal file
1
out/examples/simple-counter.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"model-version":1,"pc":{"addressBus":0,"dataBus":0,"instructionReg":0,"programmCounter":0,"uCounter":0,"accumulator":0,"ram":[100005,300000,200005,400000,0,5,0,0,0,0,0]},"uCode":["pc2ab","ram2db","db2ir","pcInc","ir2uc","n","n","n","n","n","ir2ab","ram2db","db2acc","ucReset","n","n","n","n","n","n","acc2db","ir2ab","db2ram","ucReset","n","n","n","n","n","n","accInc","ucReset","n","n","n","n","n","n","n","n","ir2pc","ucReset","n","n","n","n","n","n","n","n"],"autoscroll":true}
|
10
out/icon/cross.svg
Normal file
10
out/icon/cross.svg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" id="Cross" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">
|
||||||
|
<path d="M14.348,14.849c-0.469,0.469-1.229,0.469-1.697,0L10,11.819l-2.651,3.029c-0.469,0.469-1.229,0.469-1.697,0
|
||||||
|
c-0.469-0.469-0.469-1.229,0-1.697l2.758-3.15L5.651,6.849c-0.469-0.469-0.469-1.228,0-1.697c0.469-0.469,1.228-0.469,1.697,0
|
||||||
|
L10,8.183l2.651-3.031c0.469-0.469,1.228-0.469,1.697,0c0.469,0.469,0.469,1.229,0,1.697l-2.758,3.152l2.758,3.15
|
||||||
|
C14.817,13.62,14.817,14.38,14.348,14.849z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 835 B |
364
out/index.html
364
out/index.html
@ -4,9 +4,9 @@
|
|||||||
<!-- Basic Page Needs
|
<!-- Basic Page Needs
|
||||||
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>Zähler</title>
|
<title>Johnny Simulator</title>
|
||||||
<meta name="description" content="" />
|
<meta name="description" content="Web based Johhny-Simulator" />
|
||||||
<meta name="author" content="" />
|
<meta name="author" content="Christian" />
|
||||||
|
|
||||||
<!-- Mobile Specific Metas
|
<!-- Mobile Specific Metas
|
||||||
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
@ -16,7 +16,10 @@
|
|||||||
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
<link rel="stylesheet" href="css/normalize.css" />
|
<link rel="stylesheet" href="css/normalize.css" />
|
||||||
<link rel="stylesheet" href="css/skeleton.css" />
|
<link rel="stylesheet" href="css/skeleton.css" />
|
||||||
|
<link rel="stylesheet" href="css/cookie.css" />
|
||||||
<link rel="stylesheet" href="css/colors-light.css">
|
<link rel="stylesheet" href="css/colors-light.css">
|
||||||
|
<link rel="stylesheet" href="css/colors-dark.css">
|
||||||
|
<link rel="stylesheet" href="css/pc.css" />
|
||||||
<link rel="stylesheet" href="css/style.css" />
|
<link rel="stylesheet" href="css/style.css" />
|
||||||
|
|
||||||
<!-- Favicon
|
<!-- Favicon
|
||||||
@ -27,11 +30,360 @@
|
|||||||
<body>
|
<body>
|
||||||
<!-- Primary Page Layout
|
<!-- Primary Page Layout
|
||||||
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
<div id="elm"></div>
|
<div id="elm">
|
||||||
|
<div class="noscript">Sorry, but this app needs Javascript to run :/</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spacer"></div>
|
||||||
|
|
||||||
|
<section class="container fullheight">
|
||||||
|
<div id="langPicker">
|
||||||
|
<button id="langPickerDE">German</button>
|
||||||
|
<button id="langPickerEN">English</button>
|
||||||
|
</div>
|
||||||
|
<div id="langDE" class="hidden">
|
||||||
|
<h1>Wie diese App funktioniert</h1>
|
||||||
|
<p>
|
||||||
|
Hallo, schön dass du dir diese Seite anschaust.<br>
|
||||||
|
Damit du besser verstehst, wie diese Anwendung funktioniert, hier einmal die Basics:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Kontrollknöpfe</h2>
|
||||||
|
<p>
|
||||||
|
Ganz oben findest du eine Reihe mit Kontrollknöpfen. Jeder Knopf hat seine eigene Funktion.
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<b>µCycle</b>
|
||||||
|
Mit diesem Knopf kannst du einen einzelnen Schritt im µCode ausführen.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>Instruction</b>
|
||||||
|
Hiermit kannst du eine ganze Instruction ausführen lassen und musst nicht durch jeden µCode Schritt einzeln durchdrücken.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>Reset PC</b>
|
||||||
|
Damit kannst du den PC zurücksetzten. Dabei bleibt der RAM und der µCode erhalten.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>Autoscroll</b>
|
||||||
|
Nachdem im RAM oder im µCode ein anderer Eintrag ausgewählt wurde, kann automatisch zum Eintrag gescrollt werden
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>Load Example</b>
|
||||||
|
Mit diesem Knopf kannst du ein Beispielprogramm in den PC laden. Dabei wird dein momentanes Programm überschrieben.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Bausteine</h2>
|
||||||
|
<p>
|
||||||
|
Der Computer ist in mehrere Bausteine aufgeteilt. Jeder Baustein hat eine eigene spezielle Funktion. Ein echter Computer ist natürlich deutlich komplizierter, aber so ist der PC deutlich verständlicher.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>RAM</h3>
|
||||||
|
<p>
|
||||||
|
Im Arbeitsspeicher wird das Programm gespeichert. Jeder Eintrag ist dabei in ein Low-Byte und ein High-Byte unterteilt. Dadurch kann man in einem Eintrag die Instruktion und Addresse einfacher unterscheiden.<br>
|
||||||
|
<a href="#befehl">Siehe Befehle</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Control Unit</h3>
|
||||||
|
<p>
|
||||||
|
Wie der Name es schon sagt, steuert und verwaltet die Control Unit alle Vorgänge im Computer. Das passiert dadurch, dass eine Instruktion in viele kleine µCodes aufgeteilt wird.
|
||||||
|
</p><p>
|
||||||
|
Diese µCodes sind in der Tabelle aufgeführt. Jede Instruktion besteht hier aus bis zu 10 µCodes. <br>
|
||||||
|
Bei einem Befehl z.B. <code>001 00000</code> ist die Instruktion in den ersten drei Stellen zu finden. Dieser Wert wird dann mit 10 multipliziert und in den µCode Counter geladen. <br>
|
||||||
|
In diesem Fall stände dann <code>0010</code> im Counter.<br>
|
||||||
|
In der Tabelle sind dann alle Befehle für die Instruktion <code>001</code> zu finden.
|
||||||
|
</p>
|
||||||
|
<h3>ALU</h3>
|
||||||
|
<p>
|
||||||
|
Die Arithmetik Logic Unit ist hier sehr einfach aufgebaut.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Sie kann den Akkumulator nur erhöhen oder erniedrigen. Dafür können Werte aber direkt vom Datenbus geladen werden.
|
||||||
|
</p>
|
||||||
|
<h3>Datenbus</h3>
|
||||||
|
<p>
|
||||||
|
Über den Datenbus können Daten und Befehle zwischen RAM, Control Unit und ALU übertragen werden.
|
||||||
|
</p>
|
||||||
|
<h3>Addressbus</h3>
|
||||||
|
<p>
|
||||||
|
Über diesen Bus kann die Control Unit steuern, welcher Wert im RAM ausgewählt wird.<br>
|
||||||
|
Bei normalen Rechnern sind hier natürlich noch deutlich mehr Werte angeschlossen.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<a id="befehl"></a>
|
||||||
|
<h2>Befehle</h2>
|
||||||
|
<p>
|
||||||
|
Ein Befehl besteht aus einer Instruktion und einem Argument. Deshalb sind im RAM und im Instruction Register alle Werte separiert.
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
<code>
|
||||||
|
0 0 0 0 0 0 0 0
|
||||||
|
Instr Argument
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h2>µCodes</h2>
|
||||||
|
<p>
|
||||||
|
Eine Instruktion kann nicht direkt ausgeführt werden. Deshalb wird sie durch mehrere kleine Befehle, sog. µCodes zusammengesetzt.
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>µCode</th>
|
||||||
|
<th>Beschreibung</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>ProgCounter -> AddrBus</td>
|
||||||
|
<td>Lade den Wert des Programm Counters in den Adressbus</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>InstrReg -> ProgCounter</td>
|
||||||
|
<td>Lade das Argument des Instruktionsregisters in den Programm Counter</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>ProgCounter ++</td>
|
||||||
|
<td>Erhöhe den Wert des Programm Counter um 1</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Acc == 0 => InstReg -> ProgCounter</td>
|
||||||
|
<td>Wenn der Wert des Akkumulators 0 ist, dann lade das Arggument des Instruktionsregisters in den Programm Counter</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Ram -> DataBus</td>
|
||||||
|
<td>Schreibe den aktuellen Wert aus den RAM auf den Datembus</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>DataBus -> Ram</td>
|
||||||
|
<td>Schreibe den Wert des Datenbus in die momentane Stelle des RAM</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>DataBus -> InstReg</td>
|
||||||
|
<td>Lade den Befehl vom Datenbus in das Instruktionsregister</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>DataBus -> Acc</td>
|
||||||
|
<td>Lade den Wert vom Datenbus in den Akkumulator der ALU</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Acc -> DataBus</td>
|
||||||
|
<td>Schreibe den Wert vom Akkumulator auf den Datenbus</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Acc ++</td>
|
||||||
|
<td>Erhöhe den Wert des Akkumulators um 1</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Acc --</td>
|
||||||
|
<td>Verringere den Wert des Akkumulators um 1</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>InstReg -> µCounter</td>
|
||||||
|
<td>Nehme das Argument des Befehls im Instruktionsregister, füge am Ende eine 0 an und Lade ihn in den µCounter</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>InstReg -> AddrBus</td>
|
||||||
|
<td>Lade das Argument im Instruktionsregister in den Addressbus</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>µCounter = 0</td>
|
||||||
|
<td>Setzte den µCounter zurück</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h1>Source</h1>
|
||||||
|
<p>
|
||||||
|
Im Moment ist dieser Code noch nicht ordentlich genug, dass es Sinn hat ihn zu veröffentlichen.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Dieses Projekt ist angelehnt an den <a href="https://sourceforge.net/projects/johnnysimulator/" target="_blank">Johnny-Simulator</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div id="langEN">
|
||||||
|
<h1>How this App works</h1>
|
||||||
|
<p>
|
||||||
|
Hello. In order for you to understand what this App does, I want to show you some basics of this app.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>Control Buttons</h2>
|
||||||
|
<p>
|
||||||
|
At the top of the application you can see a row of control buttons:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<b>µCycle</b>
|
||||||
|
With this button you can execute a single µCode Step.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>Instruction</b>
|
||||||
|
This button executes a whole instruction at a time. This way you don't have to press µCycle all the time.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>Reset PC</b>
|
||||||
|
With this, you can reset the pc. Please note that ram und µCodes are not reset.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>Autoscroll</b>
|
||||||
|
After a value in RAM or in the µCodes is selected you can automatically scroll to them
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<b>Load Example</b>
|
||||||
|
Click this button and select an example you want to load. This will overwrite the whole pc including ram and µCode
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Blocks</h2>
|
||||||
|
<p>
|
||||||
|
This computer is made up by multiple blocks like any other neumann-maschiene. Every block has it's own unique set of functions. A normal computer is much more complex than this, but the principle is the same.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>RAM</h3>
|
||||||
|
<p>
|
||||||
|
The current programm is stored in the RAM. Every entry is seperated as mentioned in <a href="#entry">entry</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>Control Unit</h3>
|
||||||
|
<p>
|
||||||
|
As the name suggests, the control unit manages everything that is done. To know what needs to be done it has a list of µCodes that gets executed when a instruction is requested.
|
||||||
|
</p><p>
|
||||||
|
These µCodes can be found in the table. Every instruction consists of up to 10 µCodes. <br>
|
||||||
|
When a entry is executed, the first three digits (the instruction) gets multiplied by 10. This now is written into the µCounter and the µCodes for it get's executed.
|
||||||
|
</p><p>
|
||||||
|
Example:<br>
|
||||||
|
When the entry <code>001 00000</code> gets executed, the µCounter would be set to <code>0010</code>. Now every µCode starting at location <code>0010</code> in the µCodes gets executed.
|
||||||
|
</p>
|
||||||
|
<h3>ALU</h3>
|
||||||
|
<p>
|
||||||
|
The Arithmetic Logic Unit is pretty simple in this case.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The ALU can only increment or decrement the accumulator. But it can read numbers from databus.
|
||||||
|
</p>
|
||||||
|
<h3>Databus</h3>
|
||||||
|
<p>
|
||||||
|
Via the Databus values and entrys can be transported between RAM, Control Unit and ALU.
|
||||||
|
</p>
|
||||||
|
<h3>Addressbus</h3>
|
||||||
|
<p>
|
||||||
|
With the addressbus the Control Unit can control which value is selected in RAM. On a normal computer there are a lot mor things attached to this bus.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<a id="entry"></a>
|
||||||
|
<h2>Entry</h2>
|
||||||
|
<p>
|
||||||
|
Each entry consits of a instruction and an argument. That's why the entrys in RAM and in µCodes are displayed seperatly.
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
<code>
|
||||||
|
0 0 0 0 0 0 0 0
|
||||||
|
Instr Argument
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h2>µCodes</h2>
|
||||||
|
<p>
|
||||||
|
Every instruction consists of a list of µCodes. Here is an explanaition for all of them:
|
||||||
|
</p>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>µCode</th>
|
||||||
|
<th>Description</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>ProgCounter -> AddrBus</td>
|
||||||
|
<td>Load the value from programm counter to addressbus</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>InstrReg -> ProgCounter</td>
|
||||||
|
<td>Load the argument from instruction register to programm counter</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>ProgCounter ++</td>
|
||||||
|
<td>Increment programm counter by 1</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Acc == 0 => InstReg -> ProgCounter</td>
|
||||||
|
<td>If the accumulator is 0 then write the argument from instruction register to programm counter</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Ram -> DataBus</td>
|
||||||
|
<td>Load selected value from RAM to databus</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>DataBus -> Ram</td>
|
||||||
|
<td>Write value from databus to selected value in RAM</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>DataBus -> InstReg</td>
|
||||||
|
<td>Write entry from databus to instruction register</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>DataBus -> Acc</td>
|
||||||
|
<td>Write value from databus to accumulator</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Acc -> DataBus</td>
|
||||||
|
<td>Load value from accumulator to databus</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Acc ++</td>
|
||||||
|
<td>Increment accumulator by 1</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Acc --</td>
|
||||||
|
<td>Decrement accumulator by 1</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>InstReg -> µCounter</td>
|
||||||
|
<td>Take the instruction from instruction register, add a 0 at the tail and write it to µCounter</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>InstReg -> AddrBus</td>
|
||||||
|
<td>Write the argument from instruction register to addressbus</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>µCounter = 0</td>
|
||||||
|
<td>Set µCounter to 0</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h1>Source</h1>
|
||||||
|
<p>
|
||||||
|
At the moment the code for this project isn't good enough to share it online.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This project is my take on <a href="https://sourceforge.net/projects/johnnysimulator/" target="_blank">Johnny-Simulator</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<div class="container">
|
||||||
|
<p>
|
||||||
|
Made with ☕
|
||||||
|
by <a href="https://github.com/ChrisgammaDE" target="_blank">Christian</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="https://yokta.de/i/impressum.html" target="_blank">Impressum</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
<!-- End Document
|
<!-- End Document
|
||||||
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
<script src="elm.js"></script>
|
<script src="js/elm.js"></script>
|
||||||
<script src="script.js"></script>
|
<script src="js/cookie.js"></script>
|
||||||
|
<script src="js/pc.js"></script>
|
||||||
|
<script src="js/script.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
65
out/js/cookie.js
Normal file
65
out/js/cookie.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// Check if cookie banner has been accepted by running cookieAccepted()
|
||||||
|
|
||||||
|
// Please import cookie.css!!!!
|
||||||
|
|
||||||
|
function __cookie_internal_addBanner__(){
|
||||||
|
let banner = document.createElement("div");
|
||||||
|
let text = document.createElement("div");
|
||||||
|
let link_datenschutz = document.createElement("a");
|
||||||
|
let button_accept = document.createElement("button");
|
||||||
|
let button_deny = document.createElement("button");
|
||||||
|
|
||||||
|
banner.classList.add("cookie-banner");
|
||||||
|
|
||||||
|
text.innerText =
|
||||||
|
"In order for this computer to keep it's data after reloading,\
|
||||||
|
this page uses cookies and localStorage. ";
|
||||||
|
|
||||||
|
link_datenschutz.href = "https://yokta.de/i/datenschutz.html";
|
||||||
|
link_datenschutz.innerText = "Privacy Policy";
|
||||||
|
link_datenschutz.target = "_blank";
|
||||||
|
text.appendChild( link_datenschutz );
|
||||||
|
|
||||||
|
button_accept.innerText = "I'm ok with that"
|
||||||
|
button_deny.innerText = "Not on my watch!"
|
||||||
|
|
||||||
|
button_accept.addEventListener("click", (message) => {
|
||||||
|
localStorage.setItem("cookie", "accepted");
|
||||||
|
let parent = message.target.parentElement;
|
||||||
|
document.body.removeChild(parent);
|
||||||
|
});
|
||||||
|
button_deny.addEventListener("click", (message) => {
|
||||||
|
let parent = message.target.parentElement;
|
||||||
|
document.body.removeChild(parent);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
banner.appendChild( text );
|
||||||
|
banner.appendChild( button_accept );
|
||||||
|
banner.appendChild( button_deny );
|
||||||
|
|
||||||
|
document.body.appendChild(banner);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if cookies are accepted
|
||||||
|
function cookieAccepted() {
|
||||||
|
let maybe_cookie_status = localStorage.getItem("cookie");
|
||||||
|
let cookie_status = 0; // 0 = not answered, 1 = accepted, 2 = denied
|
||||||
|
|
||||||
|
if( maybe_cookie_status == null ) cookie_status = 0;
|
||||||
|
else if(maybe_cookie_status == "accepted") cookie_status = 1;
|
||||||
|
else cookie_status = 2;
|
||||||
|
|
||||||
|
if (cookie_status == 1) return true;
|
||||||
|
if (cookie_status == 0) {
|
||||||
|
let maybe_banner = document.getElementsByClassName("cookie-banner")[0];
|
||||||
|
if(maybe_banner == undefined){
|
||||||
|
__cookie_internal_addBanner__();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cookieAccepted();
|
File diff suppressed because it is too large
Load Diff
89
out/js/pc.js
Normal file
89
out/js/pc.js
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// Init Elm
|
||||||
|
var app = Elm.Main.init({
|
||||||
|
node: document.getElementById("elm"),
|
||||||
|
// flags: Date.now()
|
||||||
|
});
|
||||||
|
|
||||||
|
// Dom Objects
|
||||||
|
let pc = document.getElementsByClassName("pc")[0];
|
||||||
|
let pc_ram = pc.getElementsByClassName("ram")[0];
|
||||||
|
let pc_cu = pc.getElementsByClassName("cu")[0];
|
||||||
|
let pc_alu = pc.getElementsByClassName("alu")[0];
|
||||||
|
|
||||||
|
let pc_ram_scroller = pc_ram.getElementsByClassName("scroller")[0];
|
||||||
|
let pc_cu_scroller = pc_cu.getElementsByClassName("scroller")[0];
|
||||||
|
|
||||||
|
let control_autoscroll = document.getElementById("enableScrolling");
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
function scrollToCurrent(){
|
||||||
|
if( control_autoscroll.checked == false ) return;
|
||||||
|
|
||||||
|
let current_ram = pc_ram.getElementsByClassName("current")[0];
|
||||||
|
let current_uCode = pc_cu.getElementsByClassName("current")[0];
|
||||||
|
|
||||||
|
if( pc.scrollIntoViewIfNeeded == undefined ){
|
||||||
|
if( typeof current_ram != "undefined"){
|
||||||
|
current_ram.scrollIntoView({behavior: "smooth", block: "nearest"});
|
||||||
|
}
|
||||||
|
if( typeof current_uCode != "undefined"){
|
||||||
|
current_uCode.scrollIntoView({behavior: "smooth", block: "nearest"});
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if( typeof current_ram != "undefined"){
|
||||||
|
current_ram.scrollIntoViewIfNeeded({behavior: "smooth", block: "nearest"});
|
||||||
|
}
|
||||||
|
if( typeof current_uCode != "undefined"){
|
||||||
|
current_uCode.scrollIntoViewIfNeeded({behavior: "smooth", block: "nearest"});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pc.scrollIntoView();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function shrinkTableHead(scroll){
|
||||||
|
let scroller = scroll.target;
|
||||||
|
let pos = scroller.scrollTop;
|
||||||
|
let thead = scroller.getElementsByClassName("head")[0];
|
||||||
|
|
||||||
|
if( pos > 70 ){
|
||||||
|
thead.classList.add("shrunk");
|
||||||
|
}else if (pos < 40){
|
||||||
|
thead.classList.remove("shrunk");
|
||||||
|
}
|
||||||
|
thead.classList.add("shrunk");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadStorage() {
|
||||||
|
let content = localStorage.getItem("pc_data");
|
||||||
|
if( typeof content == "string" ){
|
||||||
|
app.ports.localStorageRecieve.send( content );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Load last state of pc
|
||||||
|
loadStorage();
|
||||||
|
|
||||||
|
// EVENT LISTENERS
|
||||||
|
pc_ram_scroller.addEventListener("scroll", shrinkTableHead);
|
||||||
|
pc_cu_scroller.addEventListener("scroll", shrinkTableHead);
|
||||||
|
|
||||||
|
// Recieve Elm updates via ports
|
||||||
|
app.ports.sendUUpdate.subscribe( (message) => {
|
||||||
|
// console.log("Update: ", message);
|
||||||
|
scrollToCurrent();
|
||||||
|
|
||||||
|
// Make sure that even when the calculation takes longer it will scroll correctly
|
||||||
|
setTimeout( scrollToCurrent, 100 );
|
||||||
|
} );
|
||||||
|
|
||||||
|
// Recieve LocalSession Updates via Ports
|
||||||
|
app.ports.localStorageSend.subscribe( (message) => {
|
||||||
|
// console.log("localSessionSend: ", message);
|
||||||
|
if( cookieAccepted() )
|
||||||
|
localStorage.setItem("pc_data", message);
|
||||||
|
} );
|
26
out/js/script.js
Normal file
26
out/js/script.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
let text_de = document.getElementById("langDE");
|
||||||
|
let text_en = document.getElementById("langEN");
|
||||||
|
|
||||||
|
let btn_changeToDe = document.getElementById("langPickerDE");
|
||||||
|
let btn_changeToEn = document.getElementById("langPickerEN");
|
||||||
|
|
||||||
|
let lang = (typeof document.documentElement.lang == "string") ? document.documentElement.lang: "en"
|
||||||
|
|
||||||
|
|
||||||
|
function changeLang(lang){
|
||||||
|
if(lang == "de"){
|
||||||
|
text_de.classList.remove("hidden");
|
||||||
|
text_en.classList.add("hidden");
|
||||||
|
}else{
|
||||||
|
text_en.classList.remove("hidden");
|
||||||
|
text_de.classList.add("hidden");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
btn_changeToEn.addEventListener("click", () => { changeLang("en") } );
|
||||||
|
btn_changeToDe.addEventListener("click", () => { changeLang("de") } );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Do stuff on loading
|
||||||
|
changeLang( lang );
|
@ -1,76 +1,26 @@
|
|||||||
// Init Elm
|
let text_de = document.getElementById("langDE");
|
||||||
var app = Elm.Main.init({
|
let text_en = document.getElementById("langEN");
|
||||||
node: document.getElementById("elm"),
|
|
||||||
// flags: Date.now()
|
|
||||||
});
|
|
||||||
|
|
||||||
// Dom Objects
|
let btn_changeToDe = document.getElementById("langPickerDE");
|
||||||
let pc = document.getElementsByClassName("pc")[0];
|
let btn_changeToEn = document.getElementById("langPickerEN");
|
||||||
let pc_ram = pc.getElementsByClassName("ram")[0];
|
|
||||||
let pc_cu = pc.getElementsByClassName("cu")[0];
|
|
||||||
let pc_alu = pc.getElementsByClassName("alu")[0];
|
|
||||||
|
|
||||||
let pc_ram_scroller = pc_ram.getElementsByClassName("scroller")[0];
|
let lang = (typeof document.documentElement.lang == "string") ? document.documentElement.lang: "en"
|
||||||
let pc_cu_scroller = pc_cu.getElementsByClassName("scroller")[0];
|
|
||||||
|
|
||||||
let control_autoscroll = document.getElementById("enableScrolling");
|
|
||||||
|
|
||||||
// Methods
|
function changeLang(lang){
|
||||||
function scrollToCurrent(){
|
if(lang == "de"){
|
||||||
if( control_autoscroll.checked == false ) return;
|
text_de.classList.remove("hidden");
|
||||||
|
text_en.classList.add("hidden");
|
||||||
let current_ram = pc_ram.getElementsByClassName("current")[0];
|
}else{
|
||||||
if( typeof current_ram != "undefined"){
|
text_en.classList.remove("hidden");
|
||||||
current_ram.scrollIntoView({behavior: "smooth", block: "center"});
|
text_de.classList.add("hidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
let current_uCode = pc_cu.getElementsByClassName("current")[0];
|
|
||||||
if( typeof current_uCode != "undefined"){
|
|
||||||
current_uCode.scrollIntoView({behavior: "smooth", block: "center"});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
btn_changeToEn.addEventListener("click", () => { changeLang("en") } );
|
||||||
function shrinkTableHead(scroll){
|
btn_changeToDe.addEventListener("click", () => { changeLang("de") } );
|
||||||
let scroller = scroll.target;
|
|
||||||
let pos = scroller.scrollTop;
|
|
||||||
let thead = scroller.getElementsByClassName("head")[0];
|
|
||||||
|
|
||||||
if( pos > 70 ){
|
|
||||||
thead.classList.add("shrunk");
|
|
||||||
}else if (pos < 40){
|
|
||||||
thead.classList.remove("shrunk");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadStorage() {
|
|
||||||
let content = localStorage.getItem("pc_data");
|
|
||||||
if( typeof content == "string" ){
|
|
||||||
app.ports.localStorageRecieve.send( content );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Load last state of pc
|
// Do stuff on loading
|
||||||
loadStorage();
|
changeLang( lang );
|
||||||
|
|
||||||
// EVENT LISTENERS
|
|
||||||
pc_ram_scroller.addEventListener("scroll", shrinkTableHead);
|
|
||||||
pc_cu_scroller.addEventListener("scroll", shrinkTableHead);
|
|
||||||
|
|
||||||
// Recieve Elm updates via ports
|
|
||||||
app.ports.sendUUpdate.subscribe( (message) => {
|
|
||||||
// console.log("Update: ", message);
|
|
||||||
scrollToCurrent();
|
|
||||||
|
|
||||||
// Make sure that even when the calculation takes longer it will scroll correctly
|
|
||||||
setTimeout( scrollToCurrent, 100 );
|
|
||||||
} );
|
|
||||||
|
|
||||||
// Recieve LocalSession Updates via Ports
|
|
||||||
app.ports.localStorageSend.subscribe( (message) => {
|
|
||||||
console.log("localSessionSend: ", message);
|
|
||||||
localStorage.setItem("pc_data", message);
|
|
||||||
} );
|
|
307
src/Main.elm
307
src/Main.elm
@ -14,8 +14,10 @@ import Html exposing (address)
|
|||||||
import Json.Encode as JE
|
import Json.Encode as JE
|
||||||
import Json.Decode as JD
|
import Json.Decode as JD
|
||||||
import Html.Events exposing (targetValue)
|
import Html.Events exposing (targetValue)
|
||||||
|
import Http
|
||||||
|
|
||||||
modelVersion = 1
|
modelVersion = 1
|
||||||
|
examplesListUrl = "examples-list.json"
|
||||||
|
|
||||||
-- Note that general Stuff is at the end of the document
|
-- Note that general Stuff is at the end of the document
|
||||||
-- PORTS
|
-- PORTS
|
||||||
@ -45,8 +47,21 @@ type alias Model =
|
|||||||
{ pc : PC
|
{ pc : PC
|
||||||
, uCode : List UAction
|
, uCode : List UAction
|
||||||
, autoscroll : Bool
|
, autoscroll : Bool
|
||||||
|
, examples : List Example
|
||||||
|
, exampleChooserOpen : Bool
|
||||||
|
, examplesListStatus : LoaderState
|
||||||
|
, exampleLoaderStatus : LoaderState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type alias Example =
|
||||||
|
{ title : String
|
||||||
|
, version : String
|
||||||
|
, url : String
|
||||||
|
, enabled : Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type LoaderState = Failure String | Waiting | Success
|
||||||
|
|
||||||
|
|
||||||
type UAction
|
type UAction
|
||||||
= ActAccumulator2DataBus
|
= ActAccumulator2DataBus
|
||||||
@ -59,12 +74,12 @@ type UAction
|
|||||||
| ActInstructionReg2ProgrammCounter
|
| ActInstructionReg2ProgrammCounter
|
||||||
| ActInstructionReg2UCounter
|
| ActInstructionReg2UCounter
|
||||||
| ActProgrammCounterIncrement
|
| ActProgrammCounterIncrement
|
||||||
|
| ActInstructionReg2ProgrammCounterIfAccEq0
|
||||||
| ActRam2DataBus
|
| ActRam2DataBus
|
||||||
| ActResetUCounter
|
| ActResetUCounter
|
||||||
| ActProgrammCounter2AddressBus
|
| ActProgrammCounter2AddressBus
|
||||||
| ActNothing
|
| ActNothing
|
||||||
|
|
||||||
|
|
||||||
uCodeDescriptions : List ( UAction, String )
|
uCodeDescriptions : List ( UAction, String )
|
||||||
uCodeDescriptions =
|
uCodeDescriptions =
|
||||||
[ ( ActAccumulator2DataBus, "Acc -> DataBus" )
|
[ ( ActAccumulator2DataBus, "Acc -> DataBus" )
|
||||||
@ -77,6 +92,7 @@ uCodeDescriptions =
|
|||||||
, ( ActInstructionReg2ProgrammCounter, "InstReg -> ProgCount" )
|
, ( ActInstructionReg2ProgrammCounter, "InstReg -> ProgCount" )
|
||||||
, ( ActInstructionReg2UCounter, "InstReg -> µCounter" )
|
, ( ActInstructionReg2UCounter, "InstReg -> µCounter" )
|
||||||
, ( ActProgrammCounterIncrement, "ProgCounter ++" )
|
, ( ActProgrammCounterIncrement, "ProgCounter ++" )
|
||||||
|
, ( ActInstructionReg2ProgrammCounterIfAccEq0, "Acc == 0 => InstReg -> ProgCounter")
|
||||||
, ( ActRam2DataBus, "Ram -> DataBus" )
|
, ( ActRam2DataBus, "Ram -> DataBus" )
|
||||||
, ( ActResetUCounter, "µCounter = 0" )
|
, ( ActResetUCounter, "µCounter = 0" )
|
||||||
, ( ActProgrammCounter2AddressBus, "ProgCounter -> AddrBus" )
|
, ( ActProgrammCounter2AddressBus, "ProgCounter -> AddrBus" )
|
||||||
@ -95,6 +111,7 @@ uCodeIds =
|
|||||||
, ( ActInstructionReg2ProgrammCounter, "ir2pc" )
|
, ( ActInstructionReg2ProgrammCounter, "ir2pc" )
|
||||||
, ( ActInstructionReg2UCounter, "ir2uc" )
|
, ( ActInstructionReg2UCounter, "ir2uc" )
|
||||||
, ( ActProgrammCounterIncrement, "pcInc" )
|
, ( ActProgrammCounterIncrement, "pcInc" )
|
||||||
|
, ( ActInstructionReg2ProgrammCounterIfAccEq0, "ir2pciacceq0")
|
||||||
, ( ActRam2DataBus, "ram2db" )
|
, ( ActRam2DataBus, "ram2db" )
|
||||||
, ( ActResetUCounter, "ucReset" )
|
, ( ActResetUCounter, "ucReset" )
|
||||||
, ( ActProgrammCounter2AddressBus, "pc2ab" )
|
, ( ActProgrammCounter2AddressBus, "pc2ab" )
|
||||||
@ -113,6 +130,7 @@ uCodeMaps =
|
|||||||
, ( ActInstructionReg2ProgrammCounter, actInstructionReg2ProgrammCounter )
|
, ( ActInstructionReg2ProgrammCounter, actInstructionReg2ProgrammCounter )
|
||||||
, ( ActInstructionReg2UCounter, actInstructionReg2UCounter )
|
, ( ActInstructionReg2UCounter, actInstructionReg2UCounter )
|
||||||
, ( ActProgrammCounterIncrement, actProgrammCounterIncrement )
|
, ( ActProgrammCounterIncrement, actProgrammCounterIncrement )
|
||||||
|
, ( ActInstructionReg2ProgrammCounterIfAccEq0, actInstructionReg2ProgrammCounterIfAccEq0 )
|
||||||
, ( ActRam2DataBus, actRam2DataBus )
|
, ( ActRam2DataBus, actRam2DataBus )
|
||||||
, ( ActResetUCounter, actResetUCounter )
|
, ( ActResetUCounter, actResetUCounter )
|
||||||
, ( ActProgrammCounter2AddressBus, actProgrammCounter2AddressBus )
|
, ( ActProgrammCounter2AddressBus, actProgrammCounter2AddressBus )
|
||||||
@ -222,7 +240,8 @@ type Msg
|
|||||||
| MsgRamAddBelow
|
| MsgRamAddBelow
|
||||||
| MsgCuEditAction Int String
|
| MsgCuEditAction Int String
|
||||||
| MsgCuAddBelow
|
| MsgCuAddBelow
|
||||||
| MsgCuInstrRegEdit String
|
| MsgCuInstrRegEditAddr String
|
||||||
|
| MsgCuInstrRegEditInstr String
|
||||||
| MsgCuUCounterEdit String
|
| MsgCuUCounterEdit String
|
||||||
| MsgCuProgCounterEdit String
|
| MsgCuProgCounterEdit String
|
||||||
| MsgEditAddressBus String
|
| MsgEditAddressBus String
|
||||||
@ -230,6 +249,11 @@ type Msg
|
|||||||
| MsgAluEdit String
|
| MsgAluEdit String
|
||||||
| MsgLocalSessionExport
|
| MsgLocalSessionExport
|
||||||
| MsgLocalSessionRecieve String
|
| MsgLocalSessionRecieve String
|
||||||
|
| MsgToggleLoadExample
|
||||||
|
| MsgLoadExamplesList
|
||||||
|
| MsgLoadExample Int
|
||||||
|
| MsgLoadExampleArrived (Result Http.Error Model)
|
||||||
|
| MsgExamplesArrived (Result Http.Error (List Example))
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||||
@ -246,16 +270,22 @@ update msg model =
|
|||||||
)
|
)
|
||||||
|
|
||||||
MsgInstructionStep ->
|
MsgInstructionStep ->
|
||||||
( model, Cmd.none )
|
( executeInstruction model
|
||||||
|
, cmdSenduUpdate model )
|
||||||
|
|
||||||
|
|
||||||
MsgReset ->
|
MsgReset ->
|
||||||
updateModel { model | pc = { initialPC | ram = model.pc.ram } }
|
let
|
||||||
|
new_model = { model | pc = { initialPC | ram = model.pc.ram } }
|
||||||
|
in
|
||||||
|
( new_model, cmdSenduUpdate new_model )
|
||||||
|
|
||||||
MsgManualStep action ->
|
MsgManualStep action ->
|
||||||
let
|
let
|
||||||
instruction = getAction action
|
instruction = getAction action
|
||||||
|
new_model = { model | pc = instruction model.pc }
|
||||||
in
|
in
|
||||||
updateModel { model | pc = instruction model.pc}
|
( new_model, cmdSenduUpdate new_model )
|
||||||
|
|
||||||
MsgRamEditAddress addr may_int ->
|
MsgRamEditAddress addr may_int ->
|
||||||
case String.toInt may_int of
|
case String.toInt may_int of
|
||||||
@ -300,11 +330,22 @@ update msg model =
|
|||||||
MsgCuAddBelow ->
|
MsgCuAddBelow ->
|
||||||
updateModel {model | uCode = model.uCode ++ [ ActNothing ]}
|
updateModel {model | uCode = model.uCode ++ [ ActNothing ]}
|
||||||
|
|
||||||
MsgCuInstrRegEdit text ->
|
MsgCuInstrRegEditAddr text ->
|
||||||
case String.toInt text of
|
case String.toInt text of
|
||||||
Just int ->
|
Just int ->
|
||||||
let old_pc = model.pc
|
let old_pc = model.pc
|
||||||
new_pc = { old_pc | instructionReg = int }
|
(instr,_) = seperateInstructionsEntry old_pc.instructionReg
|
||||||
|
new_pc = { old_pc | instructionReg = instr * 100000 + int }
|
||||||
|
in
|
||||||
|
updateModel { model | pc = new_pc }
|
||||||
|
_ -> ( model, Cmd.none )
|
||||||
|
|
||||||
|
MsgCuInstrRegEditInstr text ->
|
||||||
|
case String.toInt text of
|
||||||
|
Just int ->
|
||||||
|
let old_pc = model.pc
|
||||||
|
(_,addr) = seperateInstructionsEntry old_pc.instructionReg
|
||||||
|
new_pc = { old_pc | instructionReg = int * 100000 + addr }
|
||||||
in
|
in
|
||||||
updateModel { model | pc = new_pc }
|
updateModel { model | pc = new_pc }
|
||||||
_ -> ( model, Cmd.none )
|
_ -> ( model, Cmd.none )
|
||||||
@ -355,19 +396,65 @@ update msg model =
|
|||||||
_ -> ( model, Cmd.none )
|
_ -> ( model, Cmd.none )
|
||||||
|
|
||||||
MsgAutoscrollUpdate ->
|
MsgAutoscrollUpdate ->
|
||||||
updateModel { model | autoscroll = not model.autoscroll }
|
if model.autoscroll then
|
||||||
|
updateModel { model | autoscroll = False }
|
||||||
|
else
|
||||||
|
let
|
||||||
|
new_model = { model | autoscroll = True }
|
||||||
|
in
|
||||||
|
( new_model
|
||||||
|
, cmdSenduUpdate new_model )
|
||||||
|
|
||||||
MsgLocalSessionExport ->
|
MsgLocalSessionExport ->
|
||||||
( model, cmdUpdateLocalStorage model )
|
( model, cmdUpdateLocalStorage model )
|
||||||
|
|
||||||
MsgLocalSessionRecieve message_in ->
|
MsgLocalSessionRecieve message_in ->
|
||||||
case decodeModel message_in of
|
case decodeModel model message_in of
|
||||||
Just new_model ->
|
Just new_model ->
|
||||||
( new_model , Cmd.none )
|
( { new_model | examples = model.examples } , Cmd.none )
|
||||||
_ -> ( model, Cmd.none )
|
_ -> ( model, Cmd.none )
|
||||||
|
|
||||||
|
MsgToggleLoadExample ->
|
||||||
|
if model.exampleChooserOpen then
|
||||||
|
( { model | exampleChooserOpen = False }
|
||||||
|
, Cmd.none )
|
||||||
|
else
|
||||||
|
( { model | exampleChooserOpen = True }
|
||||||
|
, cmdLoadExamples model)
|
||||||
|
|
||||||
|
|
||||||
|
MsgLoadExamplesList ->
|
||||||
|
( model, Cmd.none )
|
||||||
|
|
||||||
|
MsgLoadExample i ->
|
||||||
|
case valueAt i model.examples of
|
||||||
|
Just example ->
|
||||||
|
({ model | exampleChooserOpen = False }
|
||||||
|
, cmdLoadExampleSing model example )
|
||||||
|
Nothing ->
|
||||||
|
( model, Cmd.none )
|
||||||
|
|
||||||
|
MsgLoadExampleArrived result ->
|
||||||
|
case result of
|
||||||
|
Ok new_model ->
|
||||||
|
updateModel { model | pc = new_model.pc
|
||||||
|
, uCode = new_model.uCode
|
||||||
|
, exampleLoaderStatus = Success }
|
||||||
|
Err err ->
|
||||||
|
( { model | exampleLoaderStatus = Failure <| httpError2String err }
|
||||||
|
, Cmd.none )
|
||||||
|
|
||||||
|
|
||||||
|
MsgExamplesArrived result ->
|
||||||
|
case result of
|
||||||
|
Ok exampleList ->
|
||||||
|
( { model | examples = exampleList, examplesListStatus = Success }
|
||||||
|
, Cmd.none )
|
||||||
|
Err err ->
|
||||||
|
( { model | examplesListStatus = Failure <| httpError2String err }
|
||||||
|
, Cmd.none )
|
||||||
|
|
||||||
|
|
||||||
-- Practically a part of uStepPC but sepeated for manual mode
|
-- Practically a part of uStepPC but sepeated for manual mode
|
||||||
getAction : UAction -> (PC -> PC)
|
getAction : UAction -> (PC -> PC)
|
||||||
getAction uAction =
|
getAction uAction =
|
||||||
@ -423,6 +510,16 @@ uStepPC model =
|
|||||||
model
|
model
|
||||||
|
|
||||||
|
|
||||||
|
executeInstruction : Model -> Model
|
||||||
|
executeInstruction model =
|
||||||
|
let
|
||||||
|
new_model = uStepPC model
|
||||||
|
in
|
||||||
|
if new_model.pc.uCounter == 0 then
|
||||||
|
uStepPC new_model
|
||||||
|
else
|
||||||
|
executeInstruction new_model
|
||||||
|
|
||||||
encodeModel : Model -> String
|
encodeModel : Model -> String
|
||||||
encodeModel model =
|
encodeModel model =
|
||||||
JE.object
|
JE.object
|
||||||
@ -443,41 +540,53 @@ encodeModel model =
|
|||||||
]
|
]
|
||||||
|> JE.encode 0
|
|> JE.encode 0
|
||||||
|
|
||||||
|
decodeModel : Model -> String -> Maybe Model
|
||||||
decodeModel : String -> Maybe Model
|
decodeModel model text =
|
||||||
decodeModel text =
|
|
||||||
let
|
let
|
||||||
error2maybe err =
|
error2maybe err =
|
||||||
case err of
|
case err of
|
||||||
Ok val -> Just val
|
Ok val -> Just val
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
|
|
||||||
uCodeDecoder =
|
|
||||||
JD.map
|
|
||||||
(\s -> Maybe.withDefault ActNothing <| string2uAction s )
|
|
||||||
(JD.string)
|
|
||||||
in
|
in
|
||||||
text
|
text
|
||||||
|> JD.decodeString
|
|> JD.decodeString modelDecoder
|
||||||
( JD.map3
|
|
||||||
Model
|
|
||||||
( JD.field "pc"
|
|
||||||
( JD.map7
|
|
||||||
PC
|
|
||||||
(JD.field "ram" (JD.list JD.int))
|
|
||||||
(JD.field "dataBus" JD.int)
|
|
||||||
(JD.field "addressBus" JD.int)
|
|
||||||
(JD.field "instructionReg" JD.int)
|
|
||||||
(JD.field "programmCounter" JD.int)
|
|
||||||
(JD.field "uCounter" JD.int)
|
|
||||||
(JD.field "accumulator" JD.int)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
( JD.field "uCode" (JD.list uCodeDecoder) )
|
|
||||||
( JD.field "autoscroll" JD.bool )
|
|
||||||
)
|
|
||||||
|> error2maybe
|
|> error2maybe
|
||||||
|
|
||||||
|
exampleListDecoder : JD.Decoder (List Example)
|
||||||
|
exampleListDecoder =
|
||||||
|
JD.field "available"
|
||||||
|
<| JD.list
|
||||||
|
<| JD.map4
|
||||||
|
Example
|
||||||
|
( JD.field "title" JD.string )
|
||||||
|
( JD.field "version" JD.string )
|
||||||
|
( JD.field "url" JD.string )
|
||||||
|
( JD.field "enabled" (JD.map (\s -> s == 1) JD.int) )
|
||||||
|
|
||||||
|
modelDecoder : JD.Decoder Model
|
||||||
|
modelDecoder =
|
||||||
|
JD.map3
|
||||||
|
(\a b c -> Model a b c [] False Waiting Waiting)
|
||||||
|
( JD.field "pc"
|
||||||
|
( JD.map7
|
||||||
|
PC
|
||||||
|
(JD.field "ram" (JD.list JD.int))
|
||||||
|
(JD.field "dataBus" JD.int)
|
||||||
|
(JD.field "addressBus" JD.int)
|
||||||
|
(JD.field "instructionReg" JD.int)
|
||||||
|
(JD.field "programmCounter" JD.int)
|
||||||
|
(JD.field "uCounter" JD.int)
|
||||||
|
(JD.field "accumulator" JD.int)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
( JD.field "uCode"
|
||||||
|
<| JD.list
|
||||||
|
<| JD.map (\s -> Maybe.withDefault ActNothing <| string2uAction s )
|
||||||
|
<| JD.string
|
||||||
|
)
|
||||||
|
( JD.field "autoscroll" JD.bool )
|
||||||
|
|
||||||
|
|
||||||
cmdUpdateLocalStorage : Model -> Cmd Msg
|
cmdUpdateLocalStorage : Model -> Cmd Msg
|
||||||
cmdUpdateLocalStorage model =
|
cmdUpdateLocalStorage model =
|
||||||
localStorageSend (encodeModel model)
|
localStorageSend (encodeModel model)
|
||||||
@ -489,6 +598,30 @@ cmdSenduUpdate model =
|
|||||||
, sendUUpdate "update"
|
, sendUUpdate "update"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
cmdLoadExamples : Model -> Cmd Msg
|
||||||
|
cmdLoadExamples model =
|
||||||
|
Http.get
|
||||||
|
{ url = examplesListUrl
|
||||||
|
, expect = Http.expectJson MsgExamplesArrived exampleListDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdLoadExampleSing : Model -> Example -> Cmd Msg
|
||||||
|
cmdLoadExampleSing model example =
|
||||||
|
Http.get
|
||||||
|
{ url = example.url
|
||||||
|
, expect = Http.expectJson MsgLoadExampleArrived modelDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
httpError2String : Http.Error -> String
|
||||||
|
httpError2String err =
|
||||||
|
case err of
|
||||||
|
Http.BadUrl str -> "Bad Url: " ++ str
|
||||||
|
Http.Timeout -> "Timeout"
|
||||||
|
Http.NetworkError -> "Network Error"
|
||||||
|
Http.BadStatus num -> "Bad Status: " ++ String.fromInt num
|
||||||
|
Http.BadBody str -> "Bad Body: " ++ str
|
||||||
|
|
||||||
-- VIEWERS
|
-- VIEWERS
|
||||||
|
|
||||||
view : Model -> Html Msg
|
view : Model -> Html Msg
|
||||||
@ -501,7 +634,7 @@ viewPC model =
|
|||||||
div
|
div
|
||||||
[ class "pc" ]
|
[ class "pc" ]
|
||||||
[ div [ class "controls", class "grid-fullwidth" ]
|
[ div [ class "controls", class "grid-fullwidth" ]
|
||||||
[ button [ onClick MsgUCycleStep ] [ text "µZyklus" ]
|
[ button [ onClick MsgUCycleStep ] [ text "µCycle" ]
|
||||||
, button [ onClick MsgInstructionStep ] [ text "Instruction" ]
|
, button [ onClick MsgInstructionStep ] [ text "Instruction" ]
|
||||||
, button [ onClick MsgReset ] [ text "Reset PC" ]
|
, button [ onClick MsgReset ] [ text "Reset PC" ]
|
||||||
, div
|
, div
|
||||||
@ -522,13 +655,15 @@ viewPC model =
|
|||||||
[ HAttr.for "enableScrolling" ]
|
[ HAttr.for "enableScrolling" ]
|
||||||
[ text "Autoscroll" ]
|
[ text "Autoscroll" ]
|
||||||
]
|
]
|
||||||
, button [ onClick MsgLocalSessionExport ] [ text "Export" ]
|
, button [ onClick MsgToggleLoadExample ] [ text "Load Example" ]
|
||||||
]
|
]
|
||||||
, div [ class "grid-fullwidth" ] [ lazy viewAddressBus model ]
|
, div [ class "grid-fullwidth" ] [ lazy viewAddressBus model ]
|
||||||
, lazy viewRam model
|
, lazy viewRam model
|
||||||
, lazy viewCu model
|
, lazy viewCu model
|
||||||
, lazy viewAlu model
|
, lazy viewAlu model
|
||||||
, div [ class "grid-fullwidth" ] [ lazy viewDataBus model ]
|
, div [ class "grid-fullwidth" ] [ lazy viewDataBus model ]
|
||||||
|
, lazy viewExamples model
|
||||||
|
, lazy viewExamplesLoaderError model
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -618,6 +753,9 @@ viewRamContent model =
|
|||||||
|
|
||||||
viewCu : Model -> Html Msg
|
viewCu : Model -> Html Msg
|
||||||
viewCu model =
|
viewCu model =
|
||||||
|
let
|
||||||
|
( instrRegInst, instrRegAddr ) = seperateInstructionsEntry model.pc.instructionReg
|
||||||
|
in
|
||||||
div [ class "section", class "cu" ]
|
div [ class "section", class "cu" ]
|
||||||
[ div [ class "arrow", class "up", class "top"]
|
[ div [ class "arrow", class "up", class "top"]
|
||||||
[ div [ class "button" ]
|
[ div [ class "button" ]
|
||||||
@ -633,6 +771,9 @@ viewCu model =
|
|||||||
, p []
|
, p []
|
||||||
[ div [class "input-row"]
|
[ div [class "input-row"]
|
||||||
[ Html.label [ HAttr.for "cu-progcounter" ] [ text "Programm Counter:" ]
|
[ Html.label [ HAttr.for "cu-progcounter" ] [ text "Programm Counter:" ]
|
||||||
|
, button
|
||||||
|
[ onClick <| MsgManualStep ActInstructionReg2ProgrammCounter ]
|
||||||
|
[ text "InstRA -> " ]
|
||||||
, Html.input
|
, Html.input
|
||||||
[ HAttr.type_ "number"
|
[ HAttr.type_ "number"
|
||||||
, HAttr.id "cu-progcounter"
|
, HAttr.id "cu-progcounter"
|
||||||
@ -643,16 +784,30 @@ viewCu model =
|
|||||||
|
|
||||||
, div [class "input-row"]
|
, div [class "input-row"]
|
||||||
[ Html.label [ HAttr.for "cu-instrReg" ] [ text "Instruction Register:" ]
|
[ Html.label [ HAttr.for "cu-instrReg" ] [ text "Instruction Register:" ]
|
||||||
, Html.input
|
, div []
|
||||||
[ HAttr.type_ "number"
|
[ Html.input
|
||||||
, HAttr.id "cu-instrReg"
|
[ HAttr.type_ "number"
|
||||||
, value (addLeadingZero model.pc.instructionReg 8)
|
, HAttr.id "cu-instrReg"
|
||||||
, onInput MsgCuInstrRegEdit
|
, class "instruction"
|
||||||
] []
|
, value (addLeadingZero instrRegInst 3)
|
||||||
|
, onInput MsgCuInstrRegEditInstr
|
||||||
|
] []
|
||||||
|
, Html.input
|
||||||
|
[ HAttr.type_ "number"
|
||||||
|
, HAttr.id "cu-instrReg"
|
||||||
|
, class "address"
|
||||||
|
, value (addLeadingZero instrRegAddr 5)
|
||||||
|
, onInput MsgCuInstrRegEditAddr
|
||||||
|
] []
|
||||||
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
, div [class "input-row"]
|
, div [class "input-row"]
|
||||||
[ Html.label [ HAttr.for "cu-uCounter" ] [ text "µCode Counter:" ]
|
[ Html.label [ HAttr.for "cu-uCounter" ] [ text "µCode Counter:" ]
|
||||||
|
, button
|
||||||
|
[ onClick <| MsgManualStep ActInstructionReg2UCounter
|
||||||
|
]
|
||||||
|
[ text "IntrRI ->" ]
|
||||||
, Html.input
|
, Html.input
|
||||||
[ HAttr.type_ "number"
|
[ HAttr.type_ "number"
|
||||||
, HAttr.id "cu-uCounter"
|
, HAttr.id "cu-uCounter"
|
||||||
@ -678,8 +833,8 @@ viewCuUCode model =
|
|||||||
Html.table []
|
Html.table []
|
||||||
[ Html.thead [ class "head" ]
|
[ Html.thead [ class "head" ]
|
||||||
[ Html.tr []
|
[ Html.tr []
|
||||||
[ Html.th [ class "address" ] [ text "Addr" ]
|
[ Html.th [ class "address" ] [ text "µCounter" ]
|
||||||
, Html.th [] [ text "Code" ]
|
, Html.th [] [ text "µCode" ]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, lazy viewCuUCodeContent model
|
, lazy viewCuUCodeContent model
|
||||||
@ -749,7 +904,10 @@ viewAlu model =
|
|||||||
, value (addLeadingZero model.pc.accumulator 8)
|
, value (addLeadingZero model.pc.accumulator 8)
|
||||||
, onInput MsgAluEdit
|
, onInput MsgAluEdit
|
||||||
] []
|
] []
|
||||||
|
]
|
||||||
|
, p []
|
||||||
|
[ button [ onClick <| MsgManualStep ActAccumulatorIncrement ] [ text "Acc ++" ]
|
||||||
|
, button [ onClick <| MsgManualStep ActAccumulatorDecrement ] [ text "Acc --" ]
|
||||||
]
|
]
|
||||||
, div [ class "arrow", class "up"]
|
, div [ class "arrow", class "up"]
|
||||||
[ div [ class "button" ]
|
[ div [ class "button" ]
|
||||||
@ -800,8 +958,50 @@ viewInstrEntry i =
|
|||||||
text ( (addLeadingZero instruction 3) ++ " " ++ (addLeadingZero address 5) )
|
text ( (addLeadingZero instruction 3) ++ " " ++ (addLeadingZero address 5) )
|
||||||
|
|
||||||
|
|
||||||
|
viewExamples : Model -> Html Msg
|
||||||
|
viewExamples model =
|
||||||
|
div [ classList [("modal", True), ("hidden", (not model.exampleChooserOpen))] ]
|
||||||
|
[ div [] []
|
||||||
|
, div [ class "modal-card" ]
|
||||||
|
[ Html.a [ class "modal-close", onClick MsgToggleLoadExample ] []
|
||||||
|
, lazy viewExamplesEntrys model
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
viewExamplesEntrys : Model -> Html Msg
|
||||||
|
viewExamplesEntrys model =
|
||||||
|
let
|
||||||
|
entry2html (id, example) =
|
||||||
|
Html.tr []
|
||||||
|
[ Html.td [] [ text <| "Example: " ++ example.title ]
|
||||||
|
, Html.td [] [ button [ onClick <| MsgLoadExample id ] [ text "Laden" ] ]
|
||||||
|
]
|
||||||
|
in
|
||||||
|
case model.examplesListStatus of
|
||||||
|
Failure msg ->
|
||||||
|
div [] [ text <| "That didn't work: " ++ msg]
|
||||||
|
Waiting ->
|
||||||
|
div [] [ text "Loading..." ]
|
||||||
|
Success ->
|
||||||
|
div [ class "scroller" ]
|
||||||
|
[ Html.table []
|
||||||
|
<| List.map entry2html
|
||||||
|
<| List.indexedMap Tuple.pair model.examples
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
viewExamplesLoaderError : Model -> Html Msg
|
||||||
|
viewExamplesLoaderError model =
|
||||||
|
case model.exampleLoaderStatus of
|
||||||
|
Failure msg ->
|
||||||
|
div [ class "modal" ]
|
||||||
|
[ div [] []
|
||||||
|
, div [ class "modal-card" ]
|
||||||
|
[ Html.p [] [ text "Something didn't work. Please refresh the page"]
|
||||||
|
, Html.p [] [ text msg ]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
_ -> text ""
|
||||||
|
|
||||||
-- END VIEWERS
|
-- END VIEWERS
|
||||||
-- ACTIONS
|
-- ACTIONS
|
||||||
@ -864,6 +1064,15 @@ actProgrammCounter2AddressBus : PC -> PC
|
|||||||
actProgrammCounter2AddressBus pc =
|
actProgrammCounter2AddressBus pc =
|
||||||
{ pc | addressBus = pc.programmCounter }
|
{ pc | addressBus = pc.programmCounter }
|
||||||
|
|
||||||
|
actInstructionReg2ProgrammCounterIfAccEq0 : PC -> PC
|
||||||
|
actInstructionReg2ProgrammCounterIfAccEq0 pc =
|
||||||
|
if pc.accumulator == 0 then
|
||||||
|
let
|
||||||
|
(_,addr) = seperateInstructionsEntry pc.instructionReg
|
||||||
|
in
|
||||||
|
{ pc | programmCounter = addr }
|
||||||
|
else
|
||||||
|
pc
|
||||||
|
|
||||||
actDataBus2Accumulator : PC -> PC
|
actDataBus2Accumulator : PC -> PC
|
||||||
actDataBus2Accumulator pc =
|
actDataBus2Accumulator pc =
|
||||||
@ -1013,7 +1222,7 @@ subscriptions model =
|
|||||||
|
|
||||||
init : () -> ( Model, Cmd Msg )
|
init : () -> ( Model, Cmd Msg )
|
||||||
init flags =
|
init flags =
|
||||||
( Model initialPC initialUCodes True, Cmd.none )
|
( Model initialPC initialUCodes True [] False Waiting Waiting, Cmd.none )
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
main : Program () Model Msg
|
||||||
|
Reference in New Issue
Block a user