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/B5500SPOUnit.html
2012-12-17 03:08:39 +00:00

334 lines
12 KiB
HTML

<!DOCTYPE html>
<head>
<title>B5500 Emulator SPO Unit</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Nigel Williams & Paul Kimpel">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<meta http-equiv="Content-Style-Type" content="text/css">
<link id=defaultStyleSheet rel=stylesheet type="text/css" href="B5500SPOUnit.css">
<script>
window.onload = function() {
var $$ = function(e) {return document.getElementById(e)};
var msgTank = [];
var spoRemote = false;
var spoLocalRequested = false;
var spoInputActive = false;
var spoInputRequested = false;
var msgCtl = {
buffer: null,
length: 0,
index: 0,
col: 0,
nextCharTime: 0,
finished: null};
var hasClass = function(e, name) {
/* returns true if element "e" has class "name" in its class list */
var classes = e.className;
if (!e) {
return false;
} else if (classes == name) {
return true;
} else {
return (classes.search("\\b" + name + "\\b") >= 0);
}
};
var addClass = function(e, name) {
/* Adds a class "name" to the element "e"s class list */
if (!hasClass(e, name)) {
e.className += (" " + name);
}
};
var removeClass = function(e, name) {
/* Removes the class "name" from the element "e"s class list */
e.className = e.className.replace(new RegExp("\\b" + name + "\\b\\s*", "g"), "");
};
var accept = function() {
var inputBtn = $$("SPOInputRequestBtn");
var spin = $$("SPIN");
var body = $$("SPOUT").contentDocument.body;
var line;
spoInputActive = true;
addClass(inputBtn, "yellowLit");
spin.disabled = false;
spin.focus();
line = document.createTextNode("");
body.appendChild(line);
body.parentNode.defaultView.scrollBy(0, 12);
};
var printChar = function(finished) {
/* Prints one character to the SPO. If more characters remain to be printed,
schedules itself 100 ms later to print the next one, otherwise calls finished().
If the column counter exceeds 72, a CR/LF are output. A CR/LF are also output
at the end of the message */
var body = $$("SPOUT").contentDocument.body;
var c;
var nextTime = msgCtl.nextCharTime + 100;
var delay = nextTime - new Date().getTime();
var line = body.lastChild;
msgCtl.nextCharTime = nextTime;
if (msgCtl.col < 72) { // print the character
if (msgCtl.index < msgCtl.length) {
c = String.fromCharCode(msgCtl.buffer[msgCtl.index])
if (line && line.nodeName == "#text") {
line.nodeValue += c;
} else {
line = document.createTextNode(c);
body.appendChild(line);
$$("SPOUT").contentDocument.defaultView.scrollBy(0, 12);
}
msgCtl.index++;
msgCtl.col++;
setTimeout(printChar, delay);
} else { // set up for the final CR/LF
msgCtl.col = 72;
setTimeout(printChar, delay);
}
} else if (msgCtl.col == 72) { // delay to fake the output of a carriage-return
msgCtl.col++;
setTimeout(printChar, delay);
} else { // actually output the CR/LF
line = document.createElement("br");
body.appendChild(line);
line.scrollIntoView();
if (msgCtl.index < msgCtl.length) {
msgCtl.col = 0; // more characters to print after the CR/LF
setTimeout(printChar, delay);
} else { // message text is exhausted
msgCtl.finished();
}
}
};
var print = function(buffer, length, finished) {
/* Prints the contents of the "buffer" for "length" characters */
var body = $$("SPOUT").contentDocument.body;
var count = body.childNodes.length;
while (count-- > 500) {
body.removeChild(body.firstChild);
}
msgCtl.buffer = buffer;
msgCtl.length = length;
msgCtl.index = 0;
msgCtl.col = 0;
msgCtl.nextCharTime = new Date().getTime();
msgCtl.finished = finished;
printChar();
};
var printFinished = function() {
/* Called to report that all printing to the SPO is complete */
if (msgTank.length > 1) {
msgTank = msgTank.slice(1);
print(msgTank[0], msgTank[0].length, printFinished);
} else {
msgTank = [];
//alert("Printing finished");
if (spoLocalRequested) {
spoLocalRequested = false;
setRemote(false);
} else if (spoInputRequested) {
spoInputRequested = false;
accept();
}
}
};
var printText = function(msg) {
/* Utility function to convert a string to a Typed Array buffer and queue
it for printing */
var buf = new Uint8Array(msg.length);
var length = msg.length;
var x;
for (x=0; x<length; x++) {
buf[x] = msg.charCodeAt(x);
}
msgTank.push(buf);
if (msgTank.length <= 1) {
print(buf, length, printFinished);
}
};
var setReady = function(ready) {
/* Sets the ready status of the SPO based on the truth of "ready" */
var readyBtn = $$("SPOReadyBtn");
if (ready) {
addClass(readyBtn, "yellowLit");
} else {
removeClass(readyBtn, "yellowLit");
}
};
var setRemote = function(remote) {
/* Sets the remote status of the SPO based on the truth of "remote" */
var localBtn = $$("SPOLocalBtn");
var remoteBtn = $$("SPORemoteBtn");
spoRemote = remote;
if (remote) {
addClass(remoteBtn, "yellowLit");
removeClass(localBtn, "yellowLit");
} else {
spoInputRequested = false;
spoInputActive = false;
addClass(localBtn, "yellowLit");
removeClass(remoteBtn, "yellowLit");
}
};
var doTests = function() {
printText("*** B5500 SPO Test ***");
printText(" ");
printText("What hath Barton wrought?");
printText("");
/*****
printText("123456789.123456789.123456789.123456789.123456789.123456789.123456789.1");
printText("123456789.123456789.123456789.123456789.123456789.123456789.123456789.12");
printText("123456789.123456789.123456789.123456789.123456789.123456789.123456789.123");
printText("");
printText(" 10 20 30 40 50 60 70 80 90 100");
printText("123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.");
printText("~");
printText("END");
*****/
}
/***** window.onload() outer block *****/
window.resizeBy($$("SPODiv").scrollWidth-document.body.scrollWidth,
$$("SPODiv").scrollHeight-document.body.scrollHeight);
window.moveTo((screen.availWidth-window.outerWidth)/2, (screen.availHeight-window.outerHeight)/2);
$$("SPORemoteBtn").onclick = function() {
setRemote(true);
};
$$("SPOPowerBtn").onclick = function() {
alert("Don't DO that");
};
$$("SPOLocalBtn").onclick = function() {
spoInputRequested = false;
if (msgTank.length > 0) {
spoLocalRequested = true;
} else {
setRemote(false);
}
};
$$("SPOInputRequestBtn").onclick = function() {
if (spoRemote) {
if (msgTank.length > 0) {
spoInputRequested = true;
} else {
accept();
}
}
};
$$("SPOErrorBtn").onclick = function() {
spoInputActive = false;
$$("SPIN").disabled = true;
removeClass($$("SPOInputRequestBtn"), "yellowLit");
};
$$("SPOEndOfMessageBtn").onclick = function() {
spoInputActive = false;
$$("SPIN").disabled = true;
removeClass($$("SPOInputRequestBtn"), "yellowLit");
};
$$("SPIN").onkeyup = function(ev) {
var body = $$("SPOUT").contentDocument.body;
var line = body.lastChild;
if (spoInputActive) {
line.nodeValue = $$("SPIN").value;
if (ev.keyCode == 27) {
spoInputActive = false;
removeClass($$("SPOInputRequestBtn"), "yellowLit");
} else if (ev.keyCode == 13) {
if (spoInputActive) {
spoInputActive = false;
}
}
}
};
window.onkeydown = function(ev) {
if (ev.keyCode == 27) {
if (spoRemote) {
if (spoInputActive) {
spoInputActive = false;
removeClass($$("SPOInputRequestBtn"), "yellowLit");
} else if (msgTank.length > 0) {
spoInputRequested = true;
} else {
accept();
}
}
}
};
setReady(true);
setRemote(true);
// Since we are not loading a document into the IFRAME, we must specify the body styles for it here.
$$("SPOUT").contentDocument.body.style.backgroundColor = "#FFE";
$$("SPOUT").contentDocument.body.style.fontFamily = "Lucida Sans Typewriter, Courier New, Courier, monospace";
$$("SPOUT").contentDocument.body.style.fontSize = "10pt";
$$("SPOUT").contentDocument.body.style.whiteSpace = "pre";
// Scroll to the bottom of the IFRAME viewport
$$("SPOUT").contentDocument.body.innerHTML =
"<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>" +
"<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>";
doTests();
};
</script>
</head>
<body>
<div id=SPODiv>
<iframe id=SPOUT scrolling=auto></iframe>
<br>
<input id=SPIN type=text disabled>
<div id=SPOControlsDiv>
<img id=TeletypeLogo src="TeletypeLogo.gif">
<button id=SPOReadyBtn class="yellowButton blackBorder">READY</button>
<button id=SPOPowerBtn class="blackButton blackBorder">POWER</button>
<button id=SPORemoteBtn class="yellowButton blackBorder">REMOTE</button>
<button id=SPOLocalBtn class="yellowButton blackBorder">LOCAL</button>
<button id=SPOInputRequestBtn class="yellowButton blackBorder">INPUT REQUEST</button>
<button id=SPOEndOfMessageBtn class="yellowButton blackBorder">END OF MESSAGE</button>
<button id=SPOBlank1Btn class="yellowButton blackBorder"></button>
<button id=SPOErrorBtn class="yellowButton blackBorder">ERROR</button>
<button id=SPOBlank2Btn class="yellowButton blackBorder"></button>
<button id=SPOBlank3Btn class="yellowButton blackBorder"></button>
</div>
</div>
</body>
</html>