Johnny/out/index.html

500 lines
20 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="de">
<head>
<!-- Basic Page Needs
-->
<meta charset="utf-8" />
<title>Johnny Simulator</title>
<meta name="description" content="Web based Johhny-Simulator" />
<meta name="author" content="Christian" />
<!-- Mobile Specific Metas
-->
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<!-- CSS
-->
<link rel="stylesheet" href="css/normalize.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-dark.css">
<link rel="stylesheet" href="css/loader.css" />
<link rel="stylesheet" href="css/pc.css" />
<link rel="stylesheet" href="css/style.css" />
<!-- Favicon
-->
<!-- <link rel="icon" type="image/png" href="images/favicon.png" /> -->
</head>
<body>
<!-- Primary Page Layout
-->
<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 Instruktion 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>Configs</b>
Hier können sie die momentane Konfiguration herunterladen, selber eine Hochladen oder aus einer Liste von Beispielen laden.
</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 Adresse 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>Adressbus</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&nbsp;Register alle Werte separiert.
</p>
<pre><code>0 0 2 0 0 5 0 4
Instr Argument
</code></pre>
<p>
In den ersten 3&nbsp;Stellen wird hier der OpCode der Instruction codiert. Wenn dieser Teil in der Control&nbsp;Unit in den µCode&nbsp;Counter geladen wird, dann wird der OpCode mit 10 multipliziert.
</p>
<p>
In den letzten 5&nbsp;Stellen wird ein beliebiger Zahlenwert gespeichert. Dieser kann als Argument für einen Befehl genutzt werden.
</p>
<p>
In diesem Beispiel hier würden die µCodes ab Adresse 20 im µCode Speicher ausgeführt werden.
</p>
<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><code>ProgCounter -> AddrBus</td>
<td>Lade den Wert des Programm Counters in den Adressbus</td>
</tr>
<tr>
<td><code>InstrReg -> ProgCounter</code></td>
<td>Lade das Argument des Instruktionsregisters in den Programm Counter</td>
</tr>
<tr>
<td><code>ProgCounter ++</td>
<td>Erhöhe den Wert des Programm Counter um 1</td></td>
</tr>
<tr>
<td><code>Acc == 0 => InstReg -> ProgCounter</code></td>
<td>Wenn der Wert des Akkumulators 0 ist, dann lade das Argument des Instruktionsregisters in den Programm Counter</td>
</tr>
<tr>
<td><code>Ram -> DataBus</code></td>
<td>Schreibe den aktuellen Wert aus den RAM auf den Datenbus</td>
</tr>
<tr>
<td><code>DataBus -> Ram</code></td>
<td>Schreibe den Wert des Datenbus in die momentane Stelle des RAM</td>
</tr>
<tr>
<td><code>DataBus -> InstReg</code></td>
<td>Lade den Befehl vom Datenbus in das Instruktionsregister</td>
</tr>
<tr>
<td><code>DataBus -> Acc</code></td>
<td>Lade den Wert vom Datenbus in den Akkumulator der ALU</td>
</tr>
<tr>
<td><code>Acc -> DataBus</code></td>
<td>Schreibe den Wert vom Akkumulator auf den Datenbus</td>
</tr>
<tr>
<td><code>Acc ++</code></td>
<td>Erhöhe den Wert des Akkumulators um 1</td>
</tr>
<tr>
<td><code>Acc --</code></td>
<td>Verringere den Wert des Akkumulators um 1</td>
</tr>
<tr>
<td><code>Acc << DataBus</code></td>
<td>Verschiebt den Wert im Akkumulator nach links um den Wert im DatenBus.</td>
</tr>
<tr>
<td><code>Acc >> DataBus</code></td>
<td>Verschiebt den Wert im Akkumulator nach rechts um den Wert im DatenBus.</td>
</tr>
<tr>
<td><code>Acc + DataBus</code></td>
<td>Addiere den Wert im Datenbus auf den Akkumulator</td>
</tr>
<tr>
<td><code>Acc - DataBus</code></td>
<td>Subtrahiere den Wert im Datenbus auf den Akkumulator</td>
</tr>
<tr>
<td><code>Acc * DataBus</code></td>
<td>Multipliziere den Wert im Datenbus mit dem Akkumulator</td>
</tr>
<tr>
<td><code>Acc / DataBus</code></td>
<td>Dividiere den Akkumulator durch den Datenbus</td>
</tr>
<tr>
<td><code>Acc AND DataBus</code></td>
<td>Führe bitweise UND auf Akkumulator mit Datenbus aus</td>
</tr>
<tr>
<td><code>Acc OR DataBus</code></td>
<td>Führe bitweise ODER auf Akkumulator mit Datenbus aus</td>
</tr>
<tr>
<td><code>Acc XOR DataBus</code></td>
<td>Führe bitweise XOR auf Akkumulator mit Datenbus aus</td>
</tr>
<tr>
<td><code>Acc NOT DataBus</code></td>
<td>Führe bitweise NOT auf Akkumulator mit Datenbus aus</td>
</tr>
<tr>
<td><code>InstReg -> µCounter</code></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><code>InstReg -> AddrBus</code></td>
<td>Lade das Argument im Instruktionsregister in den Adressbus</td>
</tr>
<tr>
<td><code>InstReg -> DataBus</code></td>
<td>Lade das Argument im Instruktionsregister in den Adressbus</td>
</tr>
<tr>
<td><code>µCounter = 0</code></td>
<td>Setzte den µCounter zurück</td>
</tr>
<tr>
<td><code>Signal End of Program</code></td>
<td>Zeigt ein Popup, dass das Ende des Programms signalisiert.</td>
</tr>
</tbody>
</table>
<h1>Source</h1>
<p>
Das hier ist ein kleines Hobbyprojekt. Meine Implementation ist also nur mit Vorsicht als "best-practice" Vorlage zu verwenden.
</p>
<a href="https://git.yokta.de/Christian/Johnny" class="button">Zum Source Code</a>
<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>Configs</b>
Download the current config, import a config from your machine or choose an example.
</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 program is stored in the RAM. Every entry is separated 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 entries 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 more things attached to this bus.
</p>
<a id="entry"></a>
<h2>Entry</h2>
<p>
Each entry consists of a instruction and an argument. That's why the entrys in RAM and in µCodes are displayed separately.
<pre><code>0 0 2 0 0 5 0 4
Instr Argument
</code></pre>
<p>
Here, the first 3 digits are the opCode of the instruction. When you try to load this part into the µCode&nbsp;Counter of the Control&nbsp;Unit, it will be automatically multiplied by 10.
<br>
In this example µCodes starting at the Address 20 will be executed.
</p>
<p>
The last 5 digits are a numerical value that can be used as an argument for the command.
</p>
<h2>µCodes</h2>
<p>
Every instruction consists of a list of µCodes. Here is an explanation for all of them:
</p>
<table>
<thead>
<tr>
<th>µCode</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>ProgCounter -> AddrBus</code></td>
<td>Load the value from program counter to addressbus</td>
</tr>
<tr>
<td><code>InstrReg -> ProgCounter</code></td>
<td>Load the argument from instruction register to program counter</td>
</tr>
<tr>
<td><code>ProgCounter ++</code></td>
<td>Increment program counter by 1</td>
</tr>
<tr>
<td><code>Acc == 0 => InstReg -> ProgCounter</code></td>
<td>If the accumulator is 0 then write the argument from instruction register to program counter</td>
</tr>
<tr>
<td><code>Ram -> DataBus</code></td>
<td>Load selected value from RAM to databus</td>
</tr>
<tr>
<td><code>DataBus -> Ram</code></td>
<td>Write value from databus to selected value in RAM</td>
</tr>
<tr>
<td><code>DataBus -> InstReg</code></td>
<td>Write entry from databus to instruction register</td>
</tr>
<tr>
<td><code>DataBus -> Acc</code></td>
<td>Write value from databus to accumulator</td>
</tr>
<tr>
<td><code>Acc -> DataBus</code></td>
<td>Load value from accumulator to databus</td>
</tr>
<tr>
<td><code>Acc ++</code></td>
<td>Increment accumulator by 1</td>
</tr>
<tr>
<td><code>Acc --</code></td>
<td>Decrement accumulator by 1</td>
</tr>
<tr>
<td><code>Acc << DataBus</code></td>
<td>Shift the Accumulator left by the value in databus</td>
</tr>
<tr>
<td><code>Acc >> DataBus</code></td>
<td>Shift the Accumulator right by the value in databus</td>
</tr>
<tr>
<td><code>Acc + DataBus</code></td>
<td>Add the value of the databus to the accumulator</td>
</tr>
<tr>
<td><code>Acc - DataBus</code></td>
<td>Subtract the value of the databus from the accumulator</td>
</tr>
<tr>
<td><code>Acc * DataBus</code></td>
<td>Multiply the value of the databus with the accumulator</td>
</tr>
<tr>
<td><code>Acc / DataBus</code></td>
<td>Divide the accumulator by the value of the databus</td>
</tr>
<tr>
<td><code>Acc AND DataBus</code></td>
<td>Do a bitwise AND to accumulator with the value of the databus</td>
</tr>
<tr>
<td><code>Acc OR DataBus</code></td>
<td>Do a bitwise OR to accumulator with the value of the databus</td>
</tr>
<tr>
<td><code>Acc XOR DataBus</code></td>
<td>Do a bitwise XOR to accumulator with the value of the databus</td>
</tr>
<tr>
<td><code>Acc NOT DataBus</code></td>
<td>Do a bitwise NOT to accumulator with the value of the databus</td>
</tr>
<tr>
<td><code>InstReg -> µCounter</code></td>
<td>Take the instruction from instruction register, add a 0 at the tail and write it to µCounter</td>
</tr>
<tr>
<td><code>InstReg -> AddrBus</code></td>
<td>Write the argument from instruction register to addressbus</td>
</tr>
<tr>
<td><code>InstReg -> DataBus</code></td>
<td>Write the argument from instruction register to databus</td>
</tr>
<tr>
<td><code>µCounter = 0</code></td>
<td>Set µCounter to 0</td>
</tr>
<tr>
<td><code>Signal End of Program</code></td>
<td>Show an alert that the end of program is reached.</td>
</tr>
</tbody>
</table>
<h1>Source</h1>
<p>
This is a hobby project so please don't take my code as a "best-practice" implementation.<br>
</p>
<a href="https://git.yokta.de/Christian/Johnny" class="button">See Source Code</a>
<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 ☕ <br>
© <a href="https://github.com/ChrisgammaDE" target="_blank">Christian</a>, 2022
</p>
<p>
<a href="https://yokta.de/i/impressum.html" target="_blank">Impressum</a>
</p>
</div>
</footer>
<!-- End Document
-->
<script src="js/elm.js"></script>
<script src="js/cookie.js"></script>
<script src="js/pc.js"></script>
<script src="js/script.js"></script>
</body>
</html>