#概要
jsdoでchip8やってみた。
開発環境を整備してみた。
アセンブラとディスアセンブラを合体した。
#写真
#サンプルコード
function _arrayBufferToBase64(buffer) {
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++)
{
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
function tob(url) {
var bin = atob(url);
var buffer = new Uint8Array(bin.length);
for (var i = 0; i < bin.length; i++)
{
buffer[i] = bin.charCodeAt(i);
}
var blob = new Blob([buffer.buffer], {
type : 'application/octet-binary'
});
var blob_url = window.URL.createObjectURL(blob);
return blob_url;
}
function run() {
var c1,
c2,
c3,
a,
i,
j;
var pc = 0;
var la = new Array(10);
var r = new Array(100);
var src = document.getElementById('src0').value;
var m = src.split("\n");
for (j = 0; j < m.length; j++)
{
var cm = m[j].split(" ");
if (cm[0] != "")
{
la[cm[0]] = pc;
}
switch (cm[1])
{
case "scroll":
r[pc] = 0x00;
pc++;
r[pc] = 0xC6;
pc++;
break;
case "disp":
var x = 0;
switch (cm[2])
{
case "v0":
x = 0;
break;
case "v1":
x = 1;
break;
case "v2":
x = 2;
break;
case "v3":
x = 3;
break;
case "v4":
x = 4;
break;
case "v5":
x = 5;
break;
case "v6":
y = 6;
break;
case "v7":
x = 7;
break;
case "v8":
x = 8;
break;
case "v9":
x = 9;
break;
case "v10":
x = 10;
break;
case "v11":
x = 11;
break;
case "v12":
x = 12;
break;
case "v13":
x = 13;
break;
case "v14":
x = 14;
break;
case "v15":
x = 15;
break;
}
var y = 0;
switch (cm[3])
{
case "v0":
y = 0;
break;
case "v1":
y = 1;
break;
case "v2":
y = 2;
break;
case "v3":
y = 3;
break;
case "v4":
y = 4;
break;
case "v5":
y = 5;
break;
case "v6":
y = 6;
break;
case "v7":
y = 7;
break;
case "v8":
y = 8;
break;
case "v9":
y = 9;
break;
case "v10":
y = 10;
break;
case "v11":
y = 11;
break;
case "v12":
y = 12;
break;
case "v13":
y = 13;
break;
case "v14":
y = 14;
break;
case "v15":
y = 15;
break;
}
r[pc] = 0xD0 + x;
pc++;
r[pc] = y * 16 + Number(cm[4]);
pc++;
break;
case "add":
if (cm[2] == "I")
{
var x = 0;
switch (cm[3])
{
case "v0":
x = 0;
break;
case "v1":
x = 1;
break;
case "v2":
x = 2;
break;
case "v3":
x = 3;
break;
case "v4":
x = 4;
break;
case "v5":
x = 5;
break;
case "v6":
y = 6;
break;
case "v7":
x = 7;
break;
case "v8":
x = 8;
break;
case "v9":
x = 9;
break;
case "v10":
x = 10;
break;
case "v11":
x = 11;
break;
case "v12":
x = 12;
break;
case "v13":
x = 13;
break;
case "v14":
x = 14;
break;
case "v15":
x = 15;
break;
}
r[pc] = 0xF0 + x;
pc++;
r[pc] = 0x1E;
pc++;
}
else if (cm[3].indexOf("v") > -1)
{
var x = 0;
switch (cm[2])
{
case "v0":
x = 0;
break;
case "v1":
x = 1;
break;
case "v2":
x = 2;
break;
case "v3":
x = 3;
break;
case "v4":
x = 4;
break;
case "v5":
x = 5;
break;
case "v6":
y = 6;
break;
case "v7":
x = 7;
break;
case "v8":
x = 8;
break;
case "v9":
x = 9;
break;
case "v10":
x = 10;
break;
case "v11":
x = 11;
break;
case "v12":
x = 12;
break;
case "v13":
x = 13;
break;
case "v14":
x = 14;
break;
case "v15":
x = 15;
break;
}
var y = 0;
switch (cm[3])
{
case "v0":
y = 0;
break;
case "v1":
y = 1;
break;
case "v2":
y = 2;
break;
case "v3":
y = 3;
break;
case "v4":
y = 4;
break;
case "v5":
y = 5;
break;
case "v6":
y = 6;
break;
case "v7":
y = 7;
break;
case "v8":
y = 8;
break;
case "v9":
y = 9;
break;
case "v10":
y = 10;
break;
case "v11":
y = 11;
break;
case "v12":
y = 12;
break;
case "v13":
y = 13;
break;
case "v14":
y = 14;
break;
case "v15":
y = 15;
break;
}
r[pc] = 0x80 + x;
pc++;
r[pc] = y * 16 + 4;
pc++;
}
else
{
var x = 0;
switch (cm[2])
{
case "v0":
x = 0;
break;
case "v1":
x = 1;
break;
case "v2":
x = 2;
break;
case "v3":
x = 3;
break;
case "v4":
x = 4;
break;
case "v5":
x = 5;
break;
case "v6":
y = 6;
break;
case "v7":
x = 7;
break;
case "v8":
x = 8;
break;
case "v9":
x = 9;
break;
case "v10":
x = 10;
break;
case "v11":
x = 11;
break;
case "v12":
x = 12;
break;
case "v13":
x = 13;
break;
case "v14":
x = 14;
break;
case "v15":
x = 15;
break;
}
r[pc] = 0x70 + x;
pc++;
r[pc] = cm[3];
pc++;
}
break;
case "load":
if (cm[2] == "I")
{
r[pc] = 0xA0 + Math.floor(cm[3] / 256);
pc++;
r[pc] = cm[3] % 256;
pc++;
}
else
{
var x = 0;
switch (cm[2])
{
case "v0":
x = 0;
break;
case "v1":
x = 1;
break;
case "v2":
x = 2;
break;
case "v3":
x = 3;
break;
case "v4":
x = 4;
break;
case "v5":
x = 5;
break;
case "v6":
y = 6;
break;
case "v7":
x = 7;
break;
case "v8":
x = 8;
break;
case "v9":
x = 9;
break;
case "v10":
x = 10;
break;
case "v11":
x = 11;
break;
case "v12":
x = 12;
break;
case "v13":
x = 13;
break;
case "v14":
x = 14;
break;
case "v15":
x = 15;
break;
}
r[pc] = 0x60 + x;
pc++;
r[pc] = Number(cm[3]);
pc++;
}
break;
case "goto":
r[pc] = 0x10;
pc++;
r[pc] = cm[2];
pc++;
break;
case "nsub":
var x = 0;
switch (cm[2])
{
case "v0":
x = 0;
break;
case "v1":
x = 1;
break;
case "v2":
x = 2;
break;
case "v3":
x = 3;
break;
case "v4":
x = 4;
break;
case "v5":
x = 5;
break;
case "v6":
y = 6;
break;
case "v7":
x = 7;
break;
case "v8":
x = 8;
break;
case "v9":
x = 9;
break;
case "v10":
x = 10;
break;
case "v11":
x = 11;
break;
case "v12":
x = 12;
break;
case "v13":
x = 13;
break;
case "v14":
x = 14;
break;
case "v15":
x = 15;
break;
}
var y = 0;
switch (cm[3])
{
case "v0":
y = 0;
break;
case "v1":
y = 1;
break;
case "v2":
y = 2;
break;
case "v3":
y = 3;
break;
case "v4":
y = 4;
break;
case "v5":
y = 5;
break;
case "v6":
y = 6;
break;
case "v7":
y = 7;
break;
case "v8":
y = 8;
break;
case "v9":
y = 9;
break;
case "v10":
y = 10;
break;
case "v11":
y = 11;
break;
case "v12":
y = 12;
break;
case "v13":
y = 13;
break;
case "v14":
y = 14;
break;
case "v15":
y = 15;
break;
}
r[pc] = 0x80 + x;
pc++;
r[pc] = y * 16 + 0x7;
pc++;
break;
case "eq":
if (cm[3].indexOf("v") > -1)
{
var x = 0;
switch (cm[2])
{
case "v0":
x = 0;
break;
case "v1":
x = 1;
break;
case "v2":
x = 2;
break;
case "v3":
x = 3;
break;
case "v4":
x = 4;
break;
case "v5":
x = 5;
break;
case "v6":
y = 6;
break;
case "v7":
x = 7;
break;
case "v8":
x = 8;
break;
case "v9":
x = 9;
break;
case "v10":
x = 10;
break;
case "v11":
x = 11;
break;
case "v12":
x = 12;
break;
case "v13":
x = 13;
break;
case "v14":
x = 14;
break;
case "v15":
x = 15;
break;
}
var y = 0;
switch (cm[3])
{
case "v0":
y = 0;
break;
case "v1":
y = 1;
break;
case "v2":
y = 2;
break;
case "v3":
y = 3;
break;
case "v4":
y = 4;
break;
case "v5":
y = 5;
break;
case "v6":
y = 6;
break;
case "v7":
y = 7;
break;
case "v8":
y = 8;
break;
case "v9":
y = 9;
break;
case "v10":
y = 10;
break;
case "v11":
y = 11;
break;
case "v12":
y = 12;
break;
case "v13":
y = 13;
break;
case "v14":
y = 14;
break;
case "v15":
y = 15;
break;
}
r[pc] = 0x50 + x;
pc++;
r[pc] = y * 16 + 0;
pc++;
}
else
{
var x = 0;
switch (cm[2])
{
case "v0":
x = 0;
break;
case "v1":
x = 1;
break;
case "v2":
x = 2;
break;
case "v3":
x = 3;
break;
case "v4":
x = 4;
break;
case "v5":
x = 5;
break;
case "v6":
y = 6;
break;
case "v7":
x = 7;
break;
case "v8":
x = 8;
break;
case "v9":
x = 9;
break;
case "v10":
x = 10;
break;
case "v11":
x = 11;
break;
case "v12":
x = 12;
break;
case "v13":
x = 13;
break;
case "v14":
x = 14;
break;
case "v15":
x = 15;
break;
}
r[pc] = 0x30 + x;
pc++;
r[pc] = cm[3];
pc++;
}
break;
}
}
for (var a in la)
{
for (i = 0; i < pc; i++)
{
if (r[i] == a)
{
var c3 = la[a] + 512;
r[i] = c3 % 256;
r[i - 1] += Math.floor(c3 / 256);
}
}
}
var out0 = document.getElementById('out');
for (i = 0; i < r.length; i += 2)
{
var m0 = r[i];
var m1 = r[i + 1];
var opcode = m0 << 8 | m1;
var asm = decode(opcode);
out0.value += (0x200 + i) + ": " + asm + "\n";
}
}
function decode(instr) {
var x = (instr & 0x0F00) >> 8,
y = (instr & 0x00F0) >> 4,
kk = instr & 0x00FF,
nnn = instr & 0x0FFF,
n = instr & 0x000F;
switch (instr & 0xF000)
{
case 0x0000:
switch (instr)
{
case 0x00E0:
return "cls";
case 0x00EE:
return "ret";
case 0x00C6:
return "scroll";
case 0x0000:
return "nop";
default:
return "sys " + nnn;
}
break;
case 0x1000:
return "goto " + nnn;
case 0x2000:
return "call " + nnn;
case 0x3000:
return "eq v" + x + " " + kk;
case 0x4000:
return "neq v" + x + " " + kk;
case 0x5000:
return "eq v" + x + " v" + y;
case 0x6000:
return "load v" + x + " " + kk;
case 0x7000:
return "add v" + x + " " + kk;
case 0x8000:
switch (instr & 0x000F)
{
case 0x0000:
return "load v" + x + " v" + y;
case 0x0001:
return "or v" + x + " v" + y;
case 0x0002:
return "and v" + x + " v" + y;
case 0x0003:
return "xor v" + x + " v" + y;
case 0x0004:
return "add v" + x + " v" + y;
case 0x0005:
return "sub v" + x + " v" + y;
case 0x0006:
return "rshift v" + x + " v" + y;
case 0x0007:
return "nsub v" + x + " v" + y;
case 0x000E:
return "lshift v" + x + " v" + y;
}
break;
case 0x9000:
return "neq v" + x + " v" + y;
case 0xA000:
return "load I " + nnn;
case 0xB000:
return "goto v0 " + nnn;
case 0xC000:
return "rand v" + x + " " + kk;
case 0xD000:
return "disp v" + x + " v" + y + " " + n;
case 0xE000:
switch (instr & 0x00FF)
{
case 0x009E:
return "keq v" + x;
case 0x00A1:
return "kneq v" + x;
}
break;
case 0xF000:
switch (instr & 0x00FF)
{
case 0x0007:
return "load v" + x + " DT";
case 0x000A:
return "load v" + x + " K";
case 0x0015:
return "load DT v" + x;
case 0x0018:
return "load ST v" + x;
case 0x001E:
return "add I v" + x;
case 0x0029:
return "load F v" + x;
case 0x0033:
return "load B v" + x;
case 0x0055:
return "load I v" + x;
case 0x0065:
return "load v" + x + " I";
}
break;
}
};
#成果物
以上。