Skip to content

Commit

Permalink
Merge branch 'release/v.04.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Schweigi committed Jan 23, 2015
2 parents 25bb380 + 31fc8ec commit 20cc9a4
Show file tree
Hide file tree
Showing 10 changed files with 340 additions and 162 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Run `grunt` to build the project.
### License
**The MIT License**

Copyright (c) 2014 Marco Schweighauser
Copyright (c) 2015 Marco Schweighauser

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

Expand Down
182 changes: 118 additions & 64 deletions assets/asmsimulator.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions assets/asmsimulator.min.js

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions assets/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,27 @@
background-color:#EEA236;
color:#FFFFFF;
border-radius:2px;
}
.marker-a {
width:1.8em;
background-color:#4d8c20; /*6EC72E; /* 83ED37; */
color:#FFFFFF;
border-radius:2px;
}.marker-b {
width:1.8em;
background-color:#22d19d; /* 37EDA1; */
color:#FFFFFF;
border-radius:2px;
}
.marker-c {
width:1.8em;
background-color:#A137ED;
color:#FFFFFF;
border-radius:2px;
}
.marker-d {
width:1.8em;
background-color:#e81f1f; /*ED3783; */
color:#FFFFFF;
border-radius:2px;
}
83 changes: 63 additions & 20 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<title>Simple 8-bit Assembler Simulator in Javascript</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/style.css">
<script type="text/javascript" src="//use.typekit.net/tor0zlh.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
Expand Down Expand Up @@ -45,18 +45,47 @@ <h4 class="panel-title">Code <small>(<a href="./instruction-set.html" target="_b
</form>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">Output</h4>
</div>
<div class="panel-body source-code">
<div style="float:left;" class="output"
ng-style="($index % 8 === 0 && {'clear': 'left'}) || {'float': 'left'}"
ng-repeat="m in memory.data | startFrom: 232 track by $index">
<span>{{ getChar(m) }}</span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">Output</h4>
</div>
<div class="panel-body source-code">
<div style="float:left;" class="output"
ng-style="($index % 8 === 0 && {'clear': 'left'}) || {'float': 'left'}"
ng-repeat="m in memory.data | startFrom: 232 track by $index">
<span>{{ getChar(m) }}</span>
</div>
</div>
</div>
</div>
<div class="col-md-8">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">Labels</h4>
</div>
<div class="panel-body source-code">
<table class="table table-condensed table-striped">
<tr>
<th>Name</th>
<th>Address</th>
<th>Value</th>
</tr>
<tr ng-repeat="(name, value) in labels">
<td>{{ name }}</td>
<td>{{ value | number:displayHex }}</td>
<td>{{ memory.data[value] | number:displayHex }}
<span ng-if="memory.data[value] >= 32 && memory.data[value] <= 126">
('{{ getChar(memory.data[value]) }}')
</span>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="clearfix visible-xs visible-sm"></div>
<div class="col-lg-5 col-md-6">
Expand All @@ -82,10 +111,10 @@ <h4 class="panel-title">CPU & Memory</h4>
</thead>
<tbody>
<tr style="text-align:center;" class="source-code">
<td><small>{{ cpu.gpr[0] | number:displayHex }}</small></td>
<td><small>{{ cpu.gpr[1] | number:displayHex }}</small></td>
<td><small>{{ cpu.gpr[2] | number:displayHex }}</small></td>
<td><small>{{ cpu.gpr[3] | number:displayHex }}</small></td>
<td><div style="margin:auto;" ng-class="displayA && 'marker-a'"><small>{{ cpu.gpr[0] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" ng-class="displayB && 'marker-b'"><small>{{ cpu.gpr[1] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" ng-class="displayC && 'marker-c'"><small>{{ cpu.gpr[2] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" ng-class="displayD && 'marker-d'"><small>{{ cpu.gpr[3] | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" class="marker-ip"><small>{{ cpu.ip | number:displayHex }}</small></div></td>
<td><div style="margin:auto;" class="marker-sp"><small>{{ cpu.sp | number:displayHex }}</small></div></td>
<td><small>{{ cpu.zero | flag }}</small></td>
Expand All @@ -99,7 +128,7 @@ <h4 class="panel-title">CPU & Memory</h4>
<div class="memory-block"
ng-repeat="m in memory.data track by $index"
ng-class="($index >= 232 && 'output-bg' || (mapping[$index] !== undefined && displayInstr && 'instr-bg' || ''))">
<div ng-class="(cpu.ip === $index && 'marker-ip' || (cpu.sp === $index && 'marker-sp' || ''))">
<div ng-class="(cpu.ip === $index && 'marker-ip' || (cpu.sp === $index && 'marker-sp' || ( cpu.gpr[0] === $index && displayA && 'marker-a' || ( cpu.gpr[1] === $index && displayB && 'marker-b' || ( cpu.gpr[2] === $index && displayC && 'marker-c' || ( cpu.gpr[3] === $index && displayD && 'marker-d' || ''))))))">
<small>{{ m | number:displayHex }}</small>
</div>
</div>
Expand All @@ -114,16 +143,30 @@ <h4 class="panel-title">CPU & Memory</h4>
<span style="margin-left:5px;">View:</span>
<a ng-click="displayHex = true" ng-hide="displayHex">Hex</a>
<a ng-click="displayHex = false" ng-show="displayHex">Decimal</a>
<br>
Register addressing:
<span style="margin-left:5px;">A:</span>
<a ng-click="displayA = true" ng-hide="displayA">Show</a>
<a ng-click="displayA = false" ng-show="displayA">Hide</a>
<span style="margin-left:5px;">B:</span>
<a ng-click="displayB = true" ng-hide="displayB">Show</a>
<a ng-click="displayB = false" ng-show="displayB">Hide</a>
<span style="margin-left:5px;">C:</span>
<a ng-click="displayC = true" ng-hide="displayC">Show</a>
<a ng-click="displayC = false" ng-show="displayC">Hide</a>
<span style="margin-left:5px;">D:</span>
<a ng-click="displayD = true" ng-hide="displayD">Show</a>
<a ng-click="displayD = false" ng-show="displayD">Hide</a>
</small>
</p>
</div>
</div>
</div>
</div>
<hr style="margin-top:10px;margin-bottom:10px;"/>
<p><small>by Marco Schweighauser (2014) | MIT License</small></p>
<p><small>by Marco Schweighauser (2015) | MIT License</small></p>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.10/angular.min.js"></script>
<script src="assets/asmsimulator.js"></script>
</body>
</html>
24 changes: 14 additions & 10 deletions instruction-set.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<title>Simple 8-bit Assembler - Instruction Set Help</title>
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/style.css">
</head>
<body>
Expand Down Expand Up @@ -43,18 +43,22 @@ <h4>Syntax</h4>
Character: 'A'
String: "Hello World!"
</pre>
<p>Operands can either be one of the four general purpose registers, a memory address or a constant. Instead of defining an address as a constant or by using a register you can use labels. The assembler will then replace the label with the corresponding constant.</p>
<p>Operands can either be one of the four general purpose registers, stack pointer register, a memory address or a constant.
Stack pointer register can only be used as operand in MOV, ADD, SUB, CMP, INC and DEC instructions.
Instead of defining an address as a constant or by using a register you can use labels. The assembler will then replace the label with the corresponding constant.</p>
<pre>
Register: A, B, C, D
Address using a register: [A]
General purpose (GP) register: A, B, C, D
Stack pointer register: SP
Address using a GP register: [A]
Address using a GP register and offset: [D-3]
Address using SP register and offset: [SP+2]
Address using a constant: [100]
Address using a label: label
Constant: Any number between 0..255 (8bit unsigned)
Offset for indirect addressing with SP: Integer between -16..+15 (sign is mandatory)
Offset for indirect addressing: Integer between -16..+15 (sign is mandatory)
</pre>
<h4>MOV - Copy a value</h4>
<p>Copies a value from <i>src</i> to <i>dest</i>. The MOV instruction is the only one able to directly modify the memory.</p>
<p>Copies a value from <i>src</i> to <i>dest</i>. The MOV instruction is the only one able to directly modify the memory. SP can be used as operand with MOV.</p>
<pre>
MOV reg, reg
MOV reg, address
Expand All @@ -69,7 +73,7 @@ <h4>DB - Variable</h4>
</pre>
<h4>Math operations</h4>
<b>Addition and Subtraction</b>
<p>Adds two numbers together or subtract one number form another. This operations will modify the carry and zero flag.</p>
<p>Adds two numbers together or subtract one number form another. This operations will modify the carry and zero flag. SP can be used as operand with ADD and SUB.</p>
<pre>
ADD reg, reg
ADD reg, address
Expand All @@ -79,7 +83,7 @@ <h4>Math operations</h4>
SUB reg, constant
</pre>
<b>Increment and Decrement</b>
<p>Increments or decrements a register by one. This operations will modify the carry and zero flag.</p>
<p>Increments or decrements a register by one. This operations will modify the carry and zero flag. SP can be used as operand with INC and DEC.</p>
<pre>
INC reg
DEC reg
Expand Down Expand Up @@ -119,7 +123,7 @@ <h4>Math operations</h4>
SHR reg, constant
</pre>
<h4>CMP - Compare</h4>
<p>Compares two values and sets the zero flag to true if they are equal. Use this instruction before a conditional jump.</p>
<p>Compares two values and sets the zero flag to true if they are equal. SP can be used as operand with CMP. Use this instruction before a conditional jump.</p>
<pre>
CMP reg, reg
CMP reg, address
Expand Down Expand Up @@ -259,7 +263,7 @@ <h4>Other instructions</h4>
HLT
</pre>
<hr style="margin-bottom:10px;"/>
<p><small>by Marco Schweighauser (2014) | MIT License</small></p>
<p><small>by Marco Schweighauser (2015) | MIT License</small></p>
</div>
</body>
</html>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "asmsimulator",
"version": "0.3.0",
"version": "0.4.0",
"description": "Simple 8-bit Assembler Simulator in Javascript",
"author": "Marco Schweighauser",
"license": "MIT",
Expand Down
61 changes: 41 additions & 20 deletions src/assembler/asm.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ app.service('assembler', ['opcodes', function(opcodes) {

// Use https://www.debuggex.com/
// Matches: "label: INSTRUCTION (["')OPERAND1(]"'), (["')OPERAND2(]"')
// GROUPS: 1 2 3 6
var regex = /^[\t ]*(?:([.A-Za-z]\w*)[:])?(?:[\t ]*([A-Za-z]{2,4})(?:[\t ]+(\[(\w+|SP(\+|-)\d+)\]|\".+?\"|\'.+?\'|[.A-Za-z0-9]\w*)(?:[\t ]*[,][\t ]*(\[(\w+|SP(\+|-)\d+)\]|\".+?\"|\'.+?\'|[.A-Za-z0-9]\w*))?)?)?/;
var op1_group=3; // group indexes for operands
var op2_group=6;
// GROUPS: 1 2 3 7
var regex = /^[\t ]*(?:([.A-Za-z]\w*)[:])?(?:[\t ]*([A-Za-z]{2,4})(?:[\t ]+(\[(\w+((\+|-)\d+)?)\]|\".+?\"|\'.+?\'|[.A-Za-z0-9]\w*)(?:[\t ]*[,][\t ]*(\[(\w+((\+|-)\d+)?)\]|\".+?\"|\'.+?\'|[.A-Za-z0-9]\w*))?)?)?/;

var op1_group=3; // group indexes for operands
var op2_group=7;
// MATCHES: "(+|-)INTEGER"
var regexNum = /^[-+]?[0-9]+$/;
// MATCHES: "(.L)abel"
Expand Down Expand Up @@ -39,7 +40,7 @@ app.service('assembler', ['opcodes', function(opcodes) {
throw "Invalid number format";
}
};
// Allowed registers: A, B, C, D
// Allowed registers: A, B, C, D, SP
var parseRegister = function(input) {
input = input.toUpperCase();

Expand All @@ -51,34 +52,54 @@ app.service('assembler', ['opcodes', function(opcodes) {
return 2;
} else if (input === 'D') {
return 3;
} else {
} else if (input === 'SP') {
return 4;
} else {
return undefined;
}
};

var parseSPAddressing=function(input) {
var parseOffsetAddressing=function(input) {
input = input.toUpperCase();
var m=0;
var m = 0;
var base = 0;

if(input.slice(0,3) === "SP+") {
m=1;
} else if(input.slice(0,3) === "SP-") {
m=-1;
if (input[0] === 'A') {
base = 0;
} else if (input[0] === 'B') {
base = 1;
} else if (input[0] === 'C') {
base = 2;
} else if (input[0] === 'D') {
base = 3;
} else if( input.slice(0,2) === "SP") {
base = 4;
} else {
return undefined;
}
var offset = m*parseInt(input.slice(3),10);
var offset_start = 1;
if (base === 4) {
offset_start = 2;
}

if (input[offset_start] === '-') {
m = -1;
} else if (input[offset_start] === '+') {
m = 1;
} else {
return undefined;
}

var offset = m*parseInt(input.slice(offset_start+1),10);

if (offset < -16 || offset > 15)
throw "offset must be a value between -16...+15";

if (offset < 0) {
// two's complement representation in 5-bit
offset=32+offset;
offset=32+offset; // two's complement representation in 5-bit
}

// shift offset 3 bits right and add 4 as code for SP register
return offset*8+4;

return offset*8+base; // shift offset 3 bits right and add code for register
};

// Allowed: Register, Label or Number; SP+/-Number is allowed for 'regaddress' type
Expand All @@ -94,7 +115,7 @@ app.service('assembler', ['opcodes', function(opcodes) {
} else {
if (typeReg === "regaddress") {

register = parseSPAddressing(input);
register = parseOffsetAddressing(input);

if (register !== undefined) {
return { type: typeReg, value: register};
Expand Down Expand Up @@ -598,7 +619,7 @@ app.service('assembler', ['opcodes', function(opcodes) {
}
}

return { code: code, mapping: mapping };
return { code: code, mapping: mapping, labels: labels };
}
};
}]);
Loading

0 comments on commit 20cc9a4

Please sign in to comment.