mirror of https://github.com/chyyuu/v8-cpu.git
Add support to timer and timer interrupts
Signed-off-by: Junjie Mao <junjie.mao@enight.me>
This commit is contained in:
parent
3536e7e27b
commit
bbbbf66ebb
21
index.html
21
index.html
|
@ -35,7 +35,7 @@
|
|||
<textarea id="sourceCode"
|
||||
class="form-control source-code"
|
||||
style="margin-bottom:5px;"
|
||||
rows="35"
|
||||
rows="30"
|
||||
tab-support
|
||||
select-line
|
||||
ng-model="code"></textarea>
|
||||
|
@ -52,11 +52,10 @@
|
|||
<h4 class="panel-title">CPU & Memory</h4>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<p class="text-muted">Registers</p>
|
||||
<p class="text-muted">General Registers</p>
|
||||
<table class="table table-condensed table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="text-align:center">IP</th>
|
||||
<th style="text-align:center">0</th>
|
||||
<th style="text-align:center">1</th>
|
||||
<th style="text-align:center">2</th>
|
||||
|
@ -77,7 +76,6 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
<tr style="text-align:center;" class="source-code">
|
||||
<td><div style="margin:auto;" class="marker marker-ip"><small>{{ cpu.ip | number:displayHex }}</small></div></td>
|
||||
<td><div style="margin:auto;" ng-class="displayA && 'marker marker-a'"><small>{{ cpu.gpr[0] | number:displayHex }}</small></div></td>
|
||||
<td><div style="margin:auto;" ng-class="displayB && 'marker marker-b'"><small>{{ cpu.gpr[1] | number:displayHex }}</small></div></td>
|
||||
<td><div style="margin:auto;" ng-class="displayC && 'marker marker-c'"><small>{{ cpu.gpr[2] | number:displayHex }}</small></div></td>
|
||||
|
@ -95,7 +93,20 @@
|
|||
<td><div style="margin:auto;" ng-class="displayD && 'marker marker-d'"><small>{{ cpu.gpr[14] | number:displayHex }}</small></div></td>
|
||||
<td><div style="margin:auto;" ng-class="displayD && 'marker marker-d'"><small>{{ cpu.gpr[15] | number:displayHex }}</small></div></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="text-muted">Other Registers</p>
|
||||
<table class="table table-condensed table-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="text-align:left">IP <font color="E81F1F">{{ cpu.status }}</font> </td>
|
||||
<td style="text-align:center;" class="source-code"><div style="margin:auto;" class="marker marker-ip"><small>{{ cpu.ip | number:displayHex }}</small></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:left">Timer Countdown</td>
|
||||
<td style="text-align:center;" class="source-code"><div style="margin:auto;"><small>{{ cpu.countdown | number:displayHex }}</small></div></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="text-muted">RAM</p>
|
||||
<div style="width:29em;" class="source-code">
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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 '';
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue