1
0
mirror of https://github.com/pkimpel/retro-b5500.git synced 2026-02-12 03:07:30 +00:00
Files
pkimpel.retro-b5500/webUI/prototypes/B5500DDPanel.js

203 lines
7.5 KiB
JavaScript

/***********************************************************************
* retro-b5500/emulator B5500DDPanel.js
************************************************************************
* Copyright (c) 2012, Nigel Williams and Paul Kimpel.
* Licensed under the MIT License, see http://www.opensource.org/licenses/mit-license.php
************************************************************************
* JavaScript object definition for the B5500 Distribution & Display panel
* utility constructors.
************************************************************************
* 2012-06-18 P.Kimpel
* Original version, from thin air.
***********************************************************************/
/***********************************************************************
* Panel Lamp *
***********************************************************************/
function B5500DDLamp(x, y) {
/* Constructor for the lamp objects used within D&D. x & y are the
coordinates of the lamp within its containing element */
this.state = 0; // current lamp state, 0=off
// visible DOM element
this.element = document.createElement("div");
this.element.className = "ddLamp";
this.element.style.left = String(x) + "px";
this.element.style.top = String(y) + "px";
}
/**************************************/
B5500DDLamp.onColor = "#FF9900";
B5500DDLamp.offColor = "#999999";
/**************************************/
B5500DDLamp.prototype.set = function(v) {
/* Changes the visible state of the lamp according to the low-order
bit of "v". */
var newState = v & 1;
if (this.state ^ newState) { // the state has changed
this.element.style.backgroundColor = (newState ? B5500DDLamp.onColor : B5500DDLamp.offColor);
this.state = newState;
}
}
/**************************************/
B5500DDLamp.prototype.flip = function() {
/* Complements the visible state of the lamp */
var newState = this.state ^ 1;
this.element.style.backgroundColor = (newState ? B5500DDLamp.onColor : B5500DDLamp.offColor);
this.state = newState;
}
/**************************************/
B5500DDLamp.prototype.setCaption = function(caption) {
/* Establishes an optional caption for a single lamp */
var e = document.createElement("div");
e.className = "ddLampCaption";
e.appendChild(document.createTextNode(caption));
this.element.appendChild(e);
}
/***********************************************************************
* Panel Register *
***********************************************************************/
function B5500DDRegister(bits, x, y, rows, caption) {
/* Constructor for the register objects used within D&D:
bits: number of bits in register
x: horizontal coordinate of upper-left corner [hSpacing increments]
y: vertical coordinate of upper-left corner [vSpacing increments]
rows: number of rows used to display the bit lamps
*/
var cols = Math.floor((bits+rows-1)/rows);
var height = rows*B5500DDRegister.vSpacing;
var width = cols*B5500DDRegister.hSpacing;
var b;
var cx = Math.floor((x-0.25)*B5500DDRegister.hSpacing);
var cy = Math.floor((y-0.25)*B5500DDRegister.vSpacing);
var lamp;
this.bits = bits; // number of bits in the register
this.left = cx; // horizontal offset relative to container
this.top = cy; // vertical offset relative to container
this.caption = caption || ""; // panel caption
this.lastValue = 0; // prior register value
this.lamps = new Array(bits+1); // bit lamps
// visible DOM element
this.element = document.createElement("div");
this.element.className = "ddRegister";
this.element.style.left = String(cx) + "px";
this.element.style.top = String(cy) + "px";
this.element.style.width = String(width) + "px";
this.element.style.height = String(height) + "px";
cx = cols*B5500DDRegister.hSpacing + B5500DDRegister.hOffset;
for (b=1; b<=bits; b++) {
if ((b-1)%rows == 0) {
cy = (rows-1)*B5500DDRegister.vSpacing + B5500DDRegister.vOffset;
cx -= B5500DDRegister.hSpacing;
} else {
cy -= B5500DDRegister.vSpacing;
}
lamp = new B5500DDLamp(cx, cy);
this.lamps[b] = lamp;
this.element.appendChild(lamp.element);
}
this.captionDiv = document.createElement("div");
this.captionDiv.className = "ddRegCaption";
this.captionDiv.style.left = "2px";
this.captionDiv.style.right = "2px";
this.captionDiv.style.top = String(-B5500DDRegister.vOffset) + "px";
if (caption) {
lamp = document.createElement("span");
lamp.className = "ddRegSpan";
lamp.appendChild(document.createTextNode(caption));
this.captionDiv.appendChild(lamp);
}
this.element.appendChild(this.captionDiv);
}
/**************************************/
B5500DDRegister.hSpacing = 24; // horizontal lamp spacing, pixels
B5500DDRegister.hOffset = 5; // horizontal lamp offset within container
B5500DDRegister.vSpacing = 24; // vertical lamp spacing, pixels
B5500DDRegister.vOffset = 5; // vertical lamp offset within container
/**************************************/
B5500DDRegister.prototype.xCoord = function(col) {
/* Returns the horizontal lamp coordinate in "px" format */
return String((col-1)*B5500DDRegister.hSpacing + B5500DDRegister.hOffset) + "px";
}
/**************************************/
B5500DDRegister.prototype.yCoord = function(row) {
/* Returns the vertical lamp coordinate in "px" format */
return String((row-1)*B5500DDRegister.vSpacing + B5500DDRegister.vOffset) + "px";
}
/**************************************/
B5500DDRegister.prototype.YYupdate = function(value) {
/* Update the register lamps from the value of the parameter */
var bitNr = 0;
var low = (this.lastValue % 0x1000000) ^ (value % 0x1000000);
var high = (Math.floor(this.lastValue / 0x1000000) % 0x1000000) ^ (Math.floor(value / 0x1000000) % 0x1000000);
while (low) {
bitNr++;
if (low & 1) {
this.lamps[bitNr].flip();
}
low >>>= 1;
}
bitNr = 23;
while (high) {
bitNr++;
if (high & 1) {
this.lamps[bitNr].flip();
}
high >>>= 1;
}
this.lastValue = value;
}
/**************************************/
B5500DDRegister.prototype.XXupdate = function(value) {
/* Update the register lamps from the value of the parameter */
var bitNr = 0;
var bit;
var mask = value % 0x1000000000000;
while (mask) {
bitNr++;
bit = mask % 2;
this.lamps[bitNr].set(bit);
mask = (mask-bit)/2;
}
}
/**************************************/
B5500DDRegister.prototype.update = function(value) {
/* Update the register lamps from the value of the parameter */
var bitNr = 0;
var bit;
var mask = value % 0x1000000000000;
while (bitNr < this.bits) {
bitNr++;
bit = mask % 2;
this.lamps[bitNr].element.style.backgroundColor = (bit ? B5500DDLamp.onColor : B5500DDLamp.offColor);
mask = (mask-bit)/2;
}
}