Koyaanisqatsi Emulator

Esoteric Processor

by Ruslan Alikberov

HTML

<body>
<button onclick='cpu()'>Step</button>
<button onclick='document.getElementById("Expression").textContent = parse(regs(0));'>Disassembly</button><hr />
<table>
<tr><td></td><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td></tr>
<tr id=RA>
<th>A</th>
<td><input type=text value='00' maxlength=2 size=2 id=RA0 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RA1 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RA2 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RA3 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RA4 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RA5 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RA6 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RA7 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RA8 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RA9 /></td>
</tr>
<tr id=RB>
<th>B</th>
<td><input type=text value='00' maxlength=2 size=2 id=RB0 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RB1 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RB2 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RB3 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RB4 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RB5 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RB6 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RB7 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RB8 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RB9 /></td>
</tr>
<tr id=RC>
<th>C</th>
<td><input type=text value='00' maxlength=2 size=2 id=RC0 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RC1 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RC2 /></td>
<td><input type=text value='00' maxlength=2 size=2 id=RC3 /></td>
<td><input type=text value='00' maxlength=2 size=2...

CSS

tr.w0 td:nth-child(2) input	{ background-color: red; }
tr.w1 td:nth-child(3) input	{ background-color: red; }
tr.w2 td:nth-child(4) input	{ background-color: red; }
tr.w3 td:nth-child(5) input	{ background-color: red; }
tr.w4 td:nth-child(6) input	{ background-color: red; }
tr.w5 td:nth-child(7) input	{ background-color: red; }
tr.w6 td:nth-child(8) input	{ background-color: red; }
tr.w7 td:nth-child(9) input	{ background-color: red; }
tr.w8 td:nth-child(10) input	{ background-color: red; }
tr.w9 td:nth-child(11) input	{ background-color: red; }
tr.r0 td:nth-child(2) input	{ background-color: lightgreen; }
tr.r1 td:nth-child(3) input	{ background-color: lightgreen; }
tr.r2 td:nth-child(4) input	{ background-color: lightgreen; }
tr.r3 td:nth-child(5) input	{ background-color: lightgreen; }
tr.r4 td:nth-child(6) input	{ background-color: lightgreen; }
tr.r5 td:nth-child(7) input	{ background-color: lightgreen; }
tr.r6 td:nth-child(8) input	{ background-color: lightgreen; }
tr.r7 td:nth-child(9) input	{ background-color: lightgreen; }
tr.r8 td:nth-child(10) input	{ background-color: lightgreen; }
tr.r9 td:nth-child(11) input	{ background-color: lightgreen; }

JavaScript

Number.prototype.HEX = function(n) {
	return	(n < 0 ? "0x" : "") + ("0000000" + this.toString(16)).substr(-Math.abs(n)).toUpperCase();
}
Number.prototype.HI = function(n) {
	if(isFinite(n))
		return (this & 0x00FF) | ((n & 0x00FF) << 8);
	return (this >> 8) & 0x00FF;
}
Number.prototype.LO = function(n) {
	if(isFinite(n))
		return (this & 0xFF00) | (n & 0x00FF);
	return this & 0x00FF;
}
var	REJ	= [];	// ALU-Shift table
var	ram	= [];
var	i, j, tmp, cmd = "...";
var	bytes = "";
var	rep = 0, ext = "_", mul = "_";
var	reg = [0, 0, 0, 0];
var	r_t = [0, 0];
var	op = "?,?";
var	cnd = "   ";

function hint(rep) {
	var	alu = ["", "", "", "", "", "", "", "", "", "", "ADD ", "SUB ", "AND ", "OR  ", "XOR ", "MOV "];
	var	apr = ["C", "D", "A", "B"];
	var	ip = regs(0);
	var	ic = ram[ip];
	var	lo = ic & 0x0F;
	var	hi = (ic >> 4) & 3;
	var	x = parseInt(apr[r_t[0]] + reg[r_t[0]], 16);
	var	y = parseInt(apr[r_t[1]] + (ic >> 4), 16);
	var	hex = ("0" + ic.toString(16)).substr(-2).toUpperCase();
	cmd = ("000" + ip.toString(16)).substr(-4).toUpperCase() + ":" + hex + "|";
	//
	if(0x00 == ic)
		cmd += "HLT" + cnd + (rep > 0 ? "0x00" + rep + "0" : ""),
		mul = ext = "_",
		cnd = "";
	else
	if(0x9F >= ic && lo == 0x00) {
		switch(rep = ic >> 4) {
		case 1: case 2: case 3:
			ext = "_<<" + rep + " ; shift bits";
			mul = rep + "*(_)";
			break;
		case 4: case 5: case 6: case 7:
			ext = "_>>" + (8 - rep) + " ; shift bits";
			mul = rep + "*(_)";
			break;
		case 8:
			ext = "~_   ; inverse bits";
			mul = rep + "*(_)";
			break;
		case 9:
			ext = "<_>  ; reverse bits order";
			mul = rep + "*(_)";
			break;
		}
		cmd += "REP " + (ic >> 4);
	} else
	if(0x9F >= ic && lo <= 0x09)
		cmd += "HLT" + cnd + "'\\x" + hex + "'" + (rep > 0 ? "*" + rep : ""),
		codes = bytes,
		bytes = "",
		mul = ext = "_",
		cnd = "",
		rep = 0;
	else
	if(0x9F >= ic && lo >= 0x0C)
		cmd += alu[lo] + cnd + apr[r_t[0]] + reg[r_t[0]] + "," + ext.replace("_", apr[r_t[1]] + (ic >> 4)),
		regs(parseInt(apr[r_t[0]] +...