diff --git a/assets/style.css b/assets/style.css
index 1cf2e7c..1d8a012 100644
--- a/assets/style.css
+++ b/assets/style.css
@@ -64,4 +64,4 @@
.codelabel-line a {
cursor: pointer;
-}
\ No newline at end of file
+}
diff --git a/index.html b/index.html
index d1588d0..2122c2d 100644
--- a/index.html
+++ b/index.html
@@ -35,7 +35,7 @@
@@ -52,11 +52,10 @@
-
Registers
+
General Registers
- IP |
0 |
1 |
2 |
@@ -77,7 +76,6 @@
- {{ cpu.ip | number:displayHex }} |
{{ cpu.gpr[0] | number:displayHex }} |
{{ cpu.gpr[1] | number:displayHex }} |
{{ cpu.gpr[2] | number:displayHex }} |
@@ -95,7 +93,20 @@
{{ cpu.gpr[14] | number:displayHex }} |
{{ cpu.gpr[15] | number:displayHex }} |
-
+
+
+
Other Registers
+
+
+
+ IP {{ cpu.status }} |
+ {{ cpu.ip | number:displayHex }} |
+
+
+ Timer Countdown |
+ {{ cpu.countdown | number:displayHex }} |
+
+
RAM
diff --git a/src/emulator/cpu.js b/src/emulator/cpu.js
index 6ad5fc7..4eb8920 100644
--- a/src/emulator/cpu.js
+++ b/src/emulator/cpu.js
@@ -17,67 +17,93 @@ app.service('cpu', ['opcodes', 'memory', function(opcodes, memory) {
}
};
+ var readReg = function(id) {
+ return self.gpr[id];
+ };
+
+ var writeReg = function(id, val) {
+ self.gpr[id] = val;
+ if (id == 15) {
+ self.updateTimer = true;
+ if (val > 0) {
+ self.countdown = val;
+ } else {
+ self.countdown = 0;
+ }
+ }
+ };
+
+ self.updateTimer = false;
+ self.status = '';
+
var instr = [memory.load(self.ip), memory.load(self.ip + 1)];
var opcode = instr[0] >> 4;
var regDest = instr[0] & 0x0F, regSource1 = instr[1] >> 4, regSource2 = instr[1] & 0x0F;
var mem = instr[1], num = instr[1];
- self.ip = self.ip + 2;
+ self.ip = (self.ip + 2) & 0xFF;
switch(opcode) {
- case opcodes.NONE:
- self.ip = self.ip - 2;
- return false; // Abort step
case opcodes.LOAD_FROM_MEMORY:
- self.gpr[regDest] = memory.load(mem);
+ writeReg(regDest, memory.load(mem));
break;
case opcodes.LOAD_WITH_CONSTANT:
- self.gpr[regDest] = num;
+ writeReg(regDest, num);
break;
case opcodes.STORE_TO_MEMORY:
- memory.store(mem, self.gpr[regDest]);
+ memory.store(mem, readReg(regDest));
break;
case opcodes.MOVE:
- self.gpr[regSource2] = self.gpr[regSource1];
+ writeReg(regSource2, readReg(regSource1));
break;
case opcodes.ADD_INT:
- self.gpr[regDest] = (self.gpr[regSource1] + self.gpr[regSource2]) & 0xFF;
+ writeReg(regDest, (readReg(regSource1) + readReg(regSource2)) & 0xFF);
break;
case opcodes.ADD_FLOAT:
// TODO
break;
case opcodes.OR:
- self.gpr[regDest] = self.gpr[regSource1] | self.gpr[regSource2];
+ writeReg(regDest, readReg(regSource1) | readReg(regSource2));
break;
case opcodes.AND:
- self.gpr[regDest] = self.gpr[regSource1] & self.gpr[regSource2];
+ writeReg(regDest, readReg(regSource1) & readReg(regSource2));
break;
case opcodes.XOR:
- self.gpr[regDest] = self.gpr[regSource1] ^ self.gpr[regSource2];
+ writeReg(regDest, readReg(regSource1) ^ readReg(regSource2));
break;
case opcodes.ROTATE:
- var delta = num % 8, val = self.gpr[regDest];
- self.gpr[regDest] = (val >> delta) + ((val & ((1 << delta) - 1)) << (8 - delta));
+ var delta = num % 8, val = readReg(regDest);
+ writeReg(regDest, (val >> delta) + ((val & ((1 << delta) - 1)) << (8 - delta)));
break;
case opcodes.JUMP_IF_EQUAL:
- if (self.gpr[regDest] == self.gpr[0]) {
+ if (readReg(regDest) == readReg(0)) {
self.ip = mem;
}
break;
case opcodes.HALT:
- self.ip = self.ip - 2;
+ self.ip = (self.ip - 2) & 0xFF;
return false;
case opcodes.LOAD_FROM_POINTER:
- self.gpr[regDest] = memory.load(self.gpr[regSource2]);
+ writeReg(regDest, memory.load(readReg(regSource2)));
break;
case opcodes.STORE_TO_POINTER:
- memory.store(self.gpr[regSource2], self.gpr[regDest]);
+ memory.store(readReg(regSource2), readReg(regDest));
break;
case opcodes.JUMP_IF_LESS:
- if (byteToNumber(self.gpr[regDest]) < byteToNumber(self.gpr[0])) { // TODO
+ if (byteToNumber(readReg(regDest)) < byteToNumber(readReg(0))) {
self.ip = mem;
}
break;
}
+ if (self.countdown > 0 && !self.updateTimer) {
+ self.countdown -= 1;
+ if (self.countdown === 0) {
+ memory.store(0xFE, self.ip);
+ self.ip = 0x80;
+ self.countdown = readReg(15);
+ self.status = '(Interrupted!)';
+ }
+ }
+
return true;
},
reset: function() {
@@ -85,6 +111,10 @@ app.service('cpu', ['opcodes', 'memory', function(opcodes, memory) {
self.gpr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
self.ip = 0;
+ self.status = '';
+
+ self.countdown = 0;
+ self.updateTimer = false;
}
};
diff --git a/src/ui/controller.js b/src/ui/controller.js
index b3c14e1..2ce2a77 100644
--- a/src/ui/controller.js
+++ b/src/ui/controller.js
@@ -150,12 +150,8 @@ app.controller('Ctrl', ['$document', '$scope', '$timeout', 'cpu', 'memory', 'ass
};
$scope.getMemoryCellCss = function (index) {
- if (index >= $scope.outputStartIndex) {
- return 'output-bg';
- } else if ($scope.isInstruction(index)) {
+ if ($scope.isInstruction(index)) {
return 'instr-bg';
- } else if (index > cpu.sp && index <= cpu.maxSP) {
- return 'stack-bg';
} else {
return '';
}