Created
April 6, 2013 04:41
-
-
Save forestbelton/5324832 to your computer and use it in GitHub Desktop.
Tenyr simulator in Javascript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var tenyr = (function() { | |
"use strict"; | |
var regbuf = new ArrayBuffer(4 * 16); | |
var regs = new Int32Array(regbuf); | |
var mem = {}; | |
var hooks = []; | |
var add_hook = function(hook) { | |
hooks.push(hook); | |
} | |
var put = function(addr, word) { | |
for(var i = 0; i < hooks.length; ++i) | |
if(addr >= hooks[i].min && addr <= hooks[i].max && hooks[i].fn(0, addr, word)) | |
return; | |
mem[addr] = word; | |
}; | |
var get = function(addr) { | |
for(var i = 0; i < hooks.length; ++i) | |
if(addr >= hooks[i].min && addr <= hooks[i].max && hooks[i].fn(1, addr, word)) | |
return; | |
if(typeof mem[addr] !== 'undefined') | |
return mem[addr]; | |
return 0; | |
}; | |
var op = function(idx, x, y) { | |
switch(idx) { | |
case 0: return x | y; | |
case 1: return x & y; | |
case 2: return x + y; | |
case 3: return x * y; | |
case 5: return x << y; | |
case 6: return 0 - ((x ^ 0x80000000) < (y ^ 0x80000000)); | |
case 7: return 0 - (x == y); | |
case 8: return 0 - ((x ^ 0x80000000) > (y ^ 0x80000000)); | |
case 9: return x & ~y; | |
case 10: return x ^ y; | |
case 11: return x - y; | |
case 12: return x ^ ~y; | |
case 13: return x >> y; | |
case 14: return 0 - (x != y); | |
} | |
}; | |
var step = function() { | |
var word = get(regs[15]++); | |
if(word == 0xffffffff) | |
return false; | |
var imm = word & 0xfff; | |
imm = imm | (0xfffff800 * ((imm >> 11) & 1)); | |
var i = { | |
p : (word >> 30) & 0x3, | |
dd : (word >> 28) & 0x3, | |
z : (word >> 24) & 0xf, | |
x : (word >> 20) & 0xf, | |
y : (word >> 16) & 0xf, | |
op : (word >> 12) & 0xf, | |
imm : imm | |
}; | |
if(i.p) | |
var expr = op(i.op, regs[i.x], i.imm) + regs[i.y]; | |
else | |
var expr = op(i.op, regs[i.x], regs[i.y]) + i.imm; | |
switch(i.dd) { | |
case 0: regs[i.z] = expr; break; | |
case 1: regs[i.z] = get(expr); break; | |
case 2: put(regs[i.z], expr); break; | |
case 3: put(expr, regs[i.z]); break; | |
} | |
return true; | |
}; | |
var run = function(bytes) { | |
for(var i = 0; i < regs.length; ++i) | |
regs[i] = 0; | |
regs[15] = 0x1000; | |
for(var i = 0; i < bytes.length; ++i) | |
mem[0x1000 + i] = bytes[i]; | |
while(step()); | |
return regs; | |
}; | |
return { | |
add : add_hook, | |
run : run | |
}; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment