JSFiddle - React, Tailwind, and code Playground
by Ari Viinikainen
HTML
<h1>ALU</h1>
<div>
<form name="input">
x (dec):
<input type="text" id="xdec" name="xdec" maxlength="6" size="6" onblur="dec2binID(this.id, this.value)"> x (bin):
<input type="text" id="xbin" name="xbin" maxlength="16" size="16" onblur="bin2dec(this.id, this.value)"> y (dec):
<input type="text" id="ydec" name="ydec" maxlength="6" size="6" onblur="dec2binID(this.id, this.value)"> y (bin):
<input type="text" id="ybin" name="ybin" maxlength="16" size="16" onblur="bin2dec(this.id, this.value)">
</form>
</div>
<div>
<form name="ModInput">
<label for="zx">| Zero x</label>
<input type="checkbox" id="zx" name="inputmod" value="zx" onclick="update()">
<label for="nx">| Negate x</label>
<input type="checkbox" id="nx" name="inputmod" value="nx" onclick="update()">
<label for="zy">| Zero y</label>
<input type="checkbox" id="zy" name="inputmod" value="zy" onclick="update()">
<label for="ny">| Negate y</label>
<input type="checkbox" id="ny" name="inputmod" value="ny" onclick="update()">
<label for="f">| ADD ☑/AND ☐</label>
<input type="checkbox" id="f" name="inputmod" value="f" onclick="update()">
<label for="no">| Negate output</label>
<input type="checkbox" id="no" name="inputmod" value="no" onclick="update()">|
</form>
</div>
<div>
<form name="ALUinput">
ALU input x:
<input class="noteditable" type="text" id="ALUxField" name="ALUxField" maxlength="16" size="16" readonly> ALU input y:
<input class="noteditable" type="text" id="ALUyField" name="ALUyField" maxlength="16" size="16" readonly>
</form>
</div>
<div>
<form name="f">
x AND y:
<input class="noteditable" type="text" id="andField" name="andField" maxlength="16" size="16" readonly> x + y:
<input class="noteditable" type="text" id="addField" name="addField" maxlength="16" size="16" readonly>
</form>
</div>
<div>
<form name="output">
output (bin):
<input class="noteditable" type="text"...
CSS
div {
background-color: #CCCCFF;
margin: 2px;
padding: 1%;
width: 100%;
margin-left: auto;
margin-right: auto;
text-align: center;
}
.noteditable {
background-color: #F0F0F0;
}
JavaScript
function dec2binID(id, dec) {
if (dec.length == 0) {
return;
}
document.getElementById(id.charAt(0) + 'bin').value = dec2bin(dec);
update();
}
function bin2dec(id, bin) {
if (bin.length == 0) {
return "";
}
if (bin[0] == 0) { // check sign, bin is string so left-most 'bit' is indexed by [0]
var dec = parseInt(bin, 2);
document.getElementById(id.charAt(0) + 'dec').value = dec;
} else { // negative, i.e. bin[0] == 1
var dectemp = parseInt(bin, 2);
var dec = ((dectemp ^ parseInt((new Array(dectemp.toString(2).length + 1)).join("1"), 2)) + 1) * -1;
document.getElementById(id.charAt(0) + 'dec').value = dec;
}
// if binary number had less than 16 bits, add zeros (if MSB is 0, i.e. assume positive) or ones (if MSB is 1, i.e. assume negative)
// assumption based on left-most bit, positive values should always have one or more 0 bits at MSB
var length = 16;
var out16 = "";
while (length--) {
out16 += (dec >> length) & 1;
}
document.getElementById(id).value = out16;
update();
}
function dec2bin(dec) {
if (dec.length == 0) {
return "";
}
if (dec > -32769 && dec < 32768) {
var out = "";
var length = 16;
while (length--) {
out += (dec >> length) & 1;
}
return out;
} else {
// return "Needs > 16 bits";
return "";
}
}
function update() {
var tempx, tempy, and, add, output;
tempx = parseInt(document.getElementById('xdec').value, 10);
tempy = parseInt(document.getElementById('ydec').value, 10);
if (tempx.length != 0 && tempy.length != 0) {
if (document.getElementById('zx').checked) {
tempx = 0;
}
if (document.getElementById('nx').checked) {
tempx = ~tempx;
}
if (document.getElementById('zy').checked) {
tempy = 0;
}
if (document.getElementById('ny').checked) {
tempy = ~tempy;
}
document.getElementById('ALUxField').value = dec2bin(tempx);
document.getElementById('ALUyField').value =...