Matt Coles 9 gadi atpakaļ
revīzija
432c54a056
7 mainītis faili ar 191 papildinājumiem un 0 dzēšanām
  1. 26 0
      index.css
  2. 82 0
      index.html
  3. 1 0
      index.js
  4. 16 0
      js/assembler.js
  5. 29 0
      js/encoders.js
  6. 2 0
      js/test.asm
  7. 35 0
      js/utils.js

+ 26 - 0
index.css

@@ -0,0 +1,26 @@
1
+textarea {
2
+  font-family: 'Source Code Pro', monospace;
3
+  font-size: 14px !important;
4
+  resize: none;
5
+}
6
+
7
+html, body {
8
+  height:100%;
9
+}
10
+
11
+canvas {
12
+  background-color: #000;
13
+  margin-left: auto;
14
+  margin-right: auto;
15
+  width: 160px;
16
+  height: 160px;
17
+  display: block;
18
+}
19
+
20
+#code {
21
+  height:75vh;
22
+}
23
+
24
+.buttons {
25
+  margin-bottom: 2%;
26
+}

+ 82 - 0
index.html

@@ -0,0 +1,82 @@
1
+<!DOCTYPE html>
2
+<html lang="en">
3
+  <head>
4
+    <meta charset="utf-8">
5
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+    <meta name="viewport" content="width=device-width, initial-scale=1">
7
+    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
8
+    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
9
+    <!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"> -->
10
+    <link href="https://fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet">
11
+    <link rel="stylesheet" href="index.css">
12
+    <title>MIPS.js</title>
13
+
14
+    <link href='https://fonts.googleapis.com/css?family=Work+Sans' rel='stylesheet' type='text/css'>
15
+
16
+    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
17
+    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
18
+    <!--[if lt IE 9]>
19
+      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
20
+      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
21
+    <![endif]-->
22
+  </head>
23
+  <body>
24
+    <div class="container">
25
+      <div class="row">
26
+        <h1>MIPS.js <small>See MIPS run, really!</small></h1>
27
+        <hr />
28
+      </div>
29
+      <div class="row">
30
+        <div class="col-md-4">
31
+          <p>
32
+          <span class="buttons">
33
+            <button class="btn btn-primary">Assemble</button>
34
+            <button class="btn btn-success">Run</button>
35
+            <button class="btn btn-warning">Step</button>
36
+          </span>
37
+          </p>
38
+        </div>
39
+      </div>
40
+      <div class="row">
41
+        <div class="col-md-4">
42
+          <textarea placeholder="Try some assembly here..." class="form-control" id="code"></textarea>
43
+        </div>
44
+        <div class="row">
45
+          <div class="col-md-2">
46
+            <canvas id="display"></canvas>
47
+            <hr />
48
+            <p class="text-center">PC: 0xbfc0 0000</p>
49
+          </div>
50
+          <div class="col-md-3">
51
+            <table class="table table-condensed table-responsive">
52
+              <thead>
53
+                <tr><th>GPR</th><th>Value</th><th>GPR</th><th>Value</th></tr>
54
+              </thead>
55
+              <tbody>
56
+                <tr><th class="zero active">zero</th><td class="zero active">0x0000 0000</td><th class="s0">$s0</th><td class="s0">0x0000 0000</td></tr>
57
+                <tr><th class="at">$at</th><td class="at">0x0000 0000<th class="s1">$s1</th><td class="s1">0x0000 0000</td></td></tr>
58
+                <tr><th class="v0">$v0</th><td class="v0">0x0000 0000<th class="s2">$s2</th><td class="s2">0x0000 0000</td></td></tr>
59
+                <tr><th class="v1">$v1</th><td class="v1">0x0000 0000<th class="s3">$s3</th><td class="s3">0x0000 0000</td></td></tr>
60
+                <tr><th class="a0">$a0</th><td class="a0">0x0000 0000<th class="s4">$s4</th><td class="s4">0x0000 0000</td></td></tr>
61
+                <tr><th class="a1">$a1</th><td class="a1">0x0000 0000<th class="s5">$s5</th><td class="s5">0x0000 0000</td></td></tr>
62
+                <tr><th class="a2">$a2</th><td class="a2">0x0000 0000<th class="s6">$s6</th><td class="s6">0x0000 0000</td></td></tr>
63
+                <tr><th class="a3">$a3</th><td class="a3">0x0000 0000<th class="s7">$s7</th><td class="s7">0x0000 0000</td></td></tr>
64
+                <tr><th class="t0">$t0</th><td class="t0">0x0000 0000<th class="t8">$t8</th><td class="t8">0x0000 0000</td></td></tr>
65
+                <tr><th class="t1">$t1</th><td class="t1">0x0000 0000<th class="t9">$t9</th><td class="t9">0x0000 0000</td></td></tr>
66
+                <tr><th class="t2">$t2</th><td class="t2">0x0000 0000<th class="k0">$k0</th><td class="k0">0x0000 0000</td></td></tr>
67
+                <tr><th class="t3">$t3</th><td class="t3">0x0000 0000<th class="k1">$k1</th><td class="k1">0x0000 0000</td></td></tr>
68
+                <tr><th class="t4">$t4</th><td class="t4">0x0000 0000<th class="gp">$gp</th><td class="gp">0x0000 0000</td></td></tr>
69
+                <tr><th class="t5">$t5</th><td class="t5">0x0000 0000<th class="sp">$sp</th><td class="sp">0x0000 0000</td></td></tr>
70
+                <tr><th class="t6">$t6</th><td class="t6">0x0000 0000<th class="s8">$s8</th><td class="s8">0x0000 0000</td></td></tr>
71
+                <tr><th class="t7">$t7</th><td class="t7">0x0000 0000<th class="ra">$ra</th><td class="ra">0x0000 0000</td></td></tr>
72
+              </tbody>
73
+            </table>
74
+          </div>
75
+        </div>
76
+      </div>
77
+    </div>
78
+    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
79
+    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
80
+    <script src="index.js"></script>
81
+  </body>
82
+</html>

+ 1 - 0
index.js

@@ -0,0 +1 @@
1
+// Will eventually be replaced with a bundle consisting of the 'js' folder

+ 16 - 0
js/assembler.js

@@ -0,0 +1,16 @@
1
+// --- START DEBUG ONLY CODE ---
2
+const fs = require('fs')
3
+const input = fs.readFileSync('test.asm', { encoding: 'utf-8' })
4
+// --- END DEBUG ONLY CODE ---
5
+
6
+const encoders = require('./encoders.js')
7
+const lines = raw => raw.split('\n').map(s => s.trim()).filter(s => !!s)
8
+
9
+const parse = lineArray => lineArray.map(line => {
10
+  return { 
11
+    instruction: line.substr(0, line.indexOf(' ')),
12
+    arguments: line.substr(line.indexOf(' ')+1).split(',').map(s => s.trim())
13
+  }
14
+}).map(line => encoders[line.instruction].apply(null, line.arguments))
15
+
16
+console.log(parse(lines(input)))

+ 29 - 0
js/encoders.js

@@ -0,0 +1,29 @@
1
+const utils = require('./utils.js')
2
+
3
+const regmap = [
4
+  'zero', 'at', 'v0', 'v1', 'a0', 'a1', 'a2', 't0', 't1', 't2', 't3', 't4', 't5',
5
+  't6', 't7', 's0', 's1', 's2', 's3', 's4', 's5', 's6', 's7', 't8', 't9', 'k0',
6
+  'k1', 'gp', 'sp', 's8', 'ra' ]
7
+
8
+const getReg = (id) => {
9
+  if (id.startsWith('$')) {
10
+    id = id.slice(1)
11
+  }
12
+  if ((isNaN(id) === false && +id >= 0 && +id <= 31) || (id = regmap.indexOf(id)) > -1) {
13
+    return id
14
+  } else {
15
+    utils.error("Invalid register: " + id)
16
+  }
17
+}
18
+
19
+const encoders = {
20
+  'LUI': (rt, immediate) => {
21
+    let encoded = '001111'
22
+    encoded = encoded + '0'.repeat(5)
23
+    encoded = encoded + utils.dec2binu(getReg(rt))
24
+    encoded = encoded + utils.hex2bin(immediate, 16)
25
+    return '0x' + utils.bin2hex(encoded, 8)
26
+  }
27
+}
28
+
29
+module.exports = encoders

+ 2 - 0
js/test.asm

@@ -0,0 +1,2 @@
1
+LUI $s8, 0x2000
2
+

+ 35 - 0
js/utils.js

@@ -0,0 +1,35 @@
1
+const error = (error) => console.error(error)
2
+
3
+const dec2binu = (dec, length) => {
4
+  let unsigned = Math.abs(dec)
5
+  let bin = unsigned.toString(2)
6
+  if (bin.length >= length) {
7
+    return bin
8
+  } else {
9
+    return '0'.repeat(length - bin.length).concat(bin)
10
+  }
11
+}
12
+
13
+const hex2bin = (hex, length) => {
14
+  if (hex.startsWith('0x')) {
15
+    return dec2binu(parseInt(hex.slice(2), 16), length)
16
+  } else {
17
+    console.error("Hex immediates must start with 0x")
18
+  }
19
+}
20
+
21
+const bin2hex = (bin, length) => {
22
+  let hex = parseInt(bin, 2).toString(16)
23
+  if (hex.length >= length) {
24
+    return hex
25
+  } else {
26
+    return '0'.repeat(length - hex.length).concat(hex)
27
+  }
28
+}
29
+
30
+module.exports = {
31
+  'error': error,
32
+  'dec2binu': dec2binu,
33
+  'hex2bin': hex2bin,
34
+  'bin2hex': bin2hex
35
+}