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 @@

CPU & Memory

-

Registers

+

General Registers

- @@ -77,7 +76,6 @@ - @@ -95,7 +93,20 @@ - + +
IP 0 1 2
{{ cpu.ip | number:displayHex }}
{{ cpu.gpr[0] | number:displayHex }}
{{ cpu.gpr[1] | number:displayHex }}
{{ cpu.gpr[2] | number:displayHex }}
{{ 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 ''; }