mirror of
https://github.com/pkimpel/retro-b5500.git
synced 2026-02-14 12:14:34 +00:00
2. Implement interrupt and device status latching in B5500CentralControl to support better UI display. 3. Implement B5500CardPunch device. 4. Implement preliminary and experimental B5500DummyPrinter device; correct printer I/O initiation in IOUnit. 5. Correct the way that Printer Finished interrupts are handled in IOUnit and CentralControl. 6. Implement Card Load Select in B5500Console and B5500SyllableDebugger. 7. Fix lack of presence-bit detection in return ops for returned values. 8. Redesign B5500CardReader UI to show last two cards read; change method of emptying the input hopper. 9. Set CHECK option and rework SYSTEM/LOG initialization in B5500ColdLoader.html. 10. Centralize system memory cycle time setting; change from 6us to 4us memory cycle time. 11. Increase Processor timeslice to 16ms and rework Processor.schedule() internals for more accurate performance throttling in browsers with poor setTimeout() granularity. 12. Reduce Processor syllable overhead from 2 cycles to 1. 13. Change B5500SPOUnit method of output to "paper" to work better in Google Chrome. 14. Make documentation and debugging enhancements in B5500IOUnit. 15. Release initial test website HTML and Unisys license PDF. 16. Commit Mark XVI DCMCP transcription as of 2013-06-21.
366 lines
14 KiB
HTML
366 lines
14 KiB
HTML
<!DOCTYPE html>
|
|
<head>
|
|
<title>retro-B5500 Emulator Operator Console</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="B5500Console.css">
|
|
|
|
<script src="./B5500DummyUnit.js"></script>
|
|
<script src="./B5500SPOUnit.js"></script>
|
|
<script src="./B5500DiskUnit.js"></script>
|
|
<script src="./B5500CardReader.js"></script>
|
|
<script src="./B5500CardPunch.js"></script>
|
|
<script src="./B5500DummyPrinter.js"></script>
|
|
|
|
<script src="../emulator/B5500SystemConfiguration.js"></script>
|
|
<script src="../emulator/B5500CentralControl.js"></script>
|
|
<script src="../emulator/B5500Processor.js"></script>
|
|
<script src="../emulator/B5500IOUnit.js"></script>
|
|
|
|
<script>
|
|
window.addEventListener("load", function() {
|
|
var aControl;
|
|
var aNormal;
|
|
var bControl;
|
|
var bNormal;
|
|
var boundBlinkenlicht;
|
|
var cc = new B5500CentralControl();
|
|
var intLightsMap = new Array(48);
|
|
var iouLightsMap = new Array(4);
|
|
var lastInterruptMask = 0;
|
|
var lastIOUMask = 0;
|
|
var lastUnitBusyMask = 0;
|
|
var lastPAState = -1;
|
|
var lastPBState = -1;
|
|
var perLightsMap = new Array(48);
|
|
var procRate;
|
|
var procSlack;
|
|
var timer;
|
|
var timerInterval = 50; // milliseconds
|
|
|
|
function $$(id) {
|
|
return document.getElementById(id)
|
|
}
|
|
|
|
function bindMethod(f, context) {
|
|
return function() {f.apply(context, arguments)};
|
|
}
|
|
|
|
function PowerOnBtn_Click(ev) {
|
|
$$("PowerOnBtn").className = "whiteButton whiteLit";
|
|
$$("AControlBtn").className = "yellowButton yellowLit";
|
|
cc.powerOn();
|
|
$$("PowerOnBtn").disabled = true;
|
|
$$("PowerOffBtn").disabled = false;
|
|
$$("LoadBtn").disabled = false;
|
|
$$("HaltBtn").disabled = true;
|
|
window.focus();
|
|
return true;
|
|
}
|
|
|
|
function PowerOffBtn_Click(ev) {
|
|
$$("PowerOnBtn").className = "whiteButton";
|
|
$$("ANormalBtn").className = "yellowButton";
|
|
$$("AControlBtn").className = "yellowButton";
|
|
$$("BNormalBtn").className = "yellowButton";
|
|
cc.powerOff();
|
|
$$("PowerOnBtn").disabled = false;
|
|
$$("PowerOffBtn").disabled = true;
|
|
$$("HaltBtn").disabled = true;
|
|
$$("LoadBtn").disabled = true;
|
|
if (timer) {
|
|
clearTimeout(timer);
|
|
timer = null;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function HaltBtn_Click(ev) {
|
|
cc.halt();
|
|
$$("HaltBtn").disabled = true;
|
|
$$("LoadBtn").disabled = false;
|
|
}
|
|
|
|
function LoadBtn_Click(ev) {
|
|
cc.load(false);
|
|
$$("HaltBtn").disabled = false;
|
|
$$("LoadBtn").disabled = true;
|
|
boundBlinkenlicht();
|
|
}
|
|
|
|
function LoadSelectBtn_Click(ev) {
|
|
if (cc.cardLoadSelect) {
|
|
cc.cardLoadSelect = 0;
|
|
$$("LoadSelectBtn").className = "blackButton silverBorder";
|
|
} else {
|
|
cc.cardLoadSelect = 1;
|
|
$$("LoadSelectBtn").className = "blackButton yellowBorder";
|
|
}
|
|
}
|
|
|
|
function displayCentralControl() {
|
|
/* Displays the I/O and interrupt status in Central Control */
|
|
var cells;
|
|
var s;
|
|
var interruptMask = cc.fetchInterruptLatch() % 0x4000;
|
|
var interruptChange = lastInterruptMask ^ interruptMask;
|
|
var iouMask = cc.fetchIOUnitLatch();
|
|
var iouChange = lastIOUMask ^ iouMask;
|
|
var unitBusyMask = cc.fetchUnitBusyLatch();
|
|
var unitBusyChange = lastUnitBusyMask ^ unitBusyMask;
|
|
var x;
|
|
|
|
lastInterruptMask = interruptMask;
|
|
lastIOUMask = iouMask;
|
|
lastUnitBusyMask = unitBusyMask;
|
|
|
|
$$("AD1F").className = (cc.AD1F ? "busy" : "");
|
|
$$("AD2F").className = (cc.AD2F ? "busy" : "");
|
|
$$("AD3F").className = (cc.AD3F ? "busy" : "");
|
|
$$("AD4F").className = (cc.AD4F ? "busy" : "");
|
|
|
|
x = 0;
|
|
while (iouChange) {
|
|
if (iouChange & 0x01) {
|
|
iouLightsMap[x].className = (iouMask & 0x01 ? "busy" : "");
|
|
}
|
|
iouMask >>>= 1;
|
|
iouChange >>>= 1;
|
|
x++;
|
|
}
|
|
|
|
x = 47;
|
|
while (interruptChange) {
|
|
if (interruptChange & 0x01) {
|
|
intLightsMap[x].className = (interruptMask & 0x01 ? "busy" : "");
|
|
}
|
|
interruptMask >>>= 1;
|
|
interruptChange >>>= 1;
|
|
x--;
|
|
}
|
|
|
|
x = 47;
|
|
while (unitBusyChange) {
|
|
if (unitBusyChange & 0x01) {
|
|
perLightsMap[x].className = (unitBusyMask & 0x01 ? "busy" : "");
|
|
}
|
|
unitBusyMask >>>= 1;
|
|
unitBusyChange >>>= 1;
|
|
x--;
|
|
}
|
|
}
|
|
|
|
function dasBlinkenlicht() {
|
|
var et;
|
|
var pa = cc.PA;
|
|
var pb = cc.PB;
|
|
|
|
if (pa) {
|
|
if (!pa.busy) {
|
|
if (lastPAState != -1) {
|
|
aControl.className = "yellowButton";
|
|
aNormal.className = "yellowButton";
|
|
lastPAState = -1;
|
|
}
|
|
} else if (pa.NCSF != lastPAState) {
|
|
lastPAState = pa.NCSF;
|
|
if (lastPAState) {
|
|
aControl.className = "yellowButton";
|
|
aNormal.className = "yellowButton yellowLit";
|
|
} else {
|
|
aNormal.className = "yellowButton";
|
|
if (pa === cc.P1) {
|
|
aControl.className = "yellowButton yellowLit";
|
|
}
|
|
}
|
|
et = new Date().getTime() - pa.procStart;
|
|
procRate.innerHTML = (pa.procTime/et*100).toFixed(1) + "%";
|
|
procSlack.innerHTML = (pa.procSlack/et*100).toFixed(1) + "%";
|
|
}
|
|
}
|
|
if (pb) {
|
|
if (!pb.busy) {
|
|
if (lastPBState != -1) {
|
|
bControl.className = "yellowButton";
|
|
bNormal.className = "yellowButton";
|
|
lastPBState = -1;
|
|
}
|
|
} else if (pb.NCSF != lastPBState) {
|
|
lastPBState = pb.NCSF;
|
|
if (lastPBState) {
|
|
bControl.className = "yellowButton";
|
|
bNormal.className = "yellowButton yellowLit";
|
|
} else {
|
|
bNormal.className = "yellowButton";
|
|
if (pb === cc.P1) {
|
|
bControl.className = "yellowButton yellowLit";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
displayCentralControl();
|
|
timer = setTimeout(boundBlinkenlicht, timerInterval);
|
|
}
|
|
|
|
function checkBrowser() {
|
|
/* Checks whether this browser can support the necessary stuff */
|
|
var missing = "";
|
|
|
|
if (!window.indexedDB) {missing += ", IndexedDB"}
|
|
if (!window.ArrayBuffer) {missing += ", ArrayBuffer"}
|
|
if (!window.DataView) {missing += ", DataView"}
|
|
if (!window.Blob) {missing += ", Blob"}
|
|
if (!window.File) {missing += ", File"}
|
|
if (!window.FileReader) {missing += ", FileReader"}
|
|
if (!window.FileList) {missing += ", FileList"}
|
|
|
|
if (missing.length == 0) {
|
|
return false;
|
|
} else {
|
|
alert("No can do... your browser does not support the following features:\n" +
|
|
missing.substring(2));
|
|
return true;
|
|
}
|
|
}
|
|
|
|
function buildLightMaps() {
|
|
/* Builds tables of the DOM entries for the annunciator lights, for efficient access */
|
|
var mnem;
|
|
var spec;
|
|
var x;
|
|
|
|
iouLightsMap[0] = $$("AD1F");
|
|
iouLightsMap[1] = $$("AD2F");
|
|
iouLightsMap[2] = $$("AD3F");
|
|
iouLightsMap[3] = $$("AD4F");
|
|
|
|
for (x=3; x<=16; x++) {
|
|
intLightsMap[50-x] = $$("CCI" + (x+100).toString().substring(1) + "F");
|
|
}
|
|
|
|
for (mnem in B5500CentralControl.unitSpecs) {
|
|
spec = B5500CentralControl.unitSpecs[mnem];
|
|
perLightsMap[spec.unitIndex] = $$(mnem);
|
|
}
|
|
}
|
|
|
|
/***** window.onload() outer block *****/
|
|
|
|
$$("RetroVersion").innerHTML = B5500CentralControl.version;
|
|
if (!checkBrowser()) {
|
|
$$("PowerOnBtn").addEventListener("click", PowerOnBtn_Click);
|
|
$$("PowerOffBtn").addEventListener("click", PowerOffBtn_Click);
|
|
$$("HaltBtn").addEventListener("click", HaltBtn_Click);
|
|
$$("LoadBtn").addEventListener("click", LoadBtn_Click);
|
|
$$("LoadSelectBtn").addEventListener("click", LoadSelectBtn_Click);
|
|
|
|
aControl = $$("AControlBtn");
|
|
aNormal = $$("ANormalBtn");
|
|
bControl = $$("BControlBtn");
|
|
bNormal = $$("BNormalBtn");
|
|
procRate = $$("procRate");
|
|
procSlack = $$("procSlack");
|
|
boundBlinkenlicht = bindMethod(dasBlinkenlicht, this);
|
|
buildLightMaps();
|
|
}
|
|
}, false);
|
|
</script>
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div id=consoleDiv>
|
|
<button id=HaltBtn class=blackButton DISABLED>HALT</button>
|
|
|
|
<button id=NotReadyBtn class=yellowButton>NOT READY</button>
|
|
<button id=LoadSelectBtn class="blackButton silverBorder">LOAD SELECT</button>
|
|
<button id=LoadBtn class=blackButton DISABLED>LOAD</button>
|
|
|
|
<button id=MemoryCheckBtn class=yellowButton>MEMORY CHECK</button>
|
|
<button id=ANormalBtn class=yellowButton>A NORMAL</button>
|
|
<button id=AControlBtn class=yellowButton>A CONTROL</button>
|
|
<button id=BNormalBtn class=yellowButton>B NORMAL</button>
|
|
<button id=BControlBtn class=yellowButton>B CONTROL</button>
|
|
|
|
<button id=PowerOnBtn class=whiteButton>POWER<br>ON</button>
|
|
<button id=PowerOffBtn class=blackButton DISABLED>POWER OFF</button>
|
|
|
|
<div id=BurroughsLogo>
|
|
<img id=BurroughsLogoImage src="Burroughs-Logo-Neg.jpg" alt="Burroughs logo">
|
|
</div>
|
|
<div id=RetroVersion>
|
|
?.??
|
|
</div>
|
|
<div id=B5500Logo>
|
|
<img src="retro-B5500-Logo.png" alt="retro-B5500 logo"><!-- B 5500 -->
|
|
</div>
|
|
|
|
<table id=CentralControl>
|
|
<colgroup>
|
|
<col span=32 class=AnnunciatorCol>
|
|
<col>
|
|
</colgroup>
|
|
<tbody>
|
|
<tr id=CCInterruptRow>
|
|
<td id=AD1F>IOU1 <!-- I/O unit 1 busy -->
|
|
<td id=AD2F>IOU2 <!-- I/O unit 2 busy -->
|
|
<td id=AD3F>IOU3 <!-- I/O unit 3 busy -->
|
|
<td id=AD4F>IOU4 <!-- I/O unit 4 busy -->
|
|
<td id=CCI03F>TIMR <!-- Time interval interrupt -->
|
|
<td id=CCI04F>IOBZ <!-- I/O busy interrupt -->
|
|
<td id=CCI05F>KBD <!-- Keyboard request interrupt -->
|
|
<td id=CCI06F>PR1F <!-- Printer 1 finished interrupt -->
|
|
<td id=CCI07F>PR2F <!-- Printer 2 finished interrupt -->
|
|
<td id=CCI08F>IO1F <!-- I/O unit 1 finished interrupt (RD in @14) -->
|
|
<td id=CCI09F>IO2F <!-- I/O unit 2 finished interrupt (RD in @15) -->
|
|
<td id=CCI10F>IO3F <!-- I/O unit 3 finished interrupt (RD in @16) -->
|
|
<td id=CCI11F>IO4F <!-- I/O unit 4 finished interrupt (RD in @17) -->
|
|
<td id=CCI12F>P2BZ <!-- P2 busy interrupt -->
|
|
<td id=CCI13F>INQ <!-- Remote inquiry request interrupt -->
|
|
<td id=CCI14F>SPEC <!-- Special interrupt #1 (not used) -->
|
|
<td id=CCI15F>DK1F <!-- Disk file #1 read check finished -->
|
|
<td id=CCI16F>DK2F <!-- Disk file #2 read check finished -->
|
|
<td colspan=13>
|
|
<td id=procSlack>
|
|
<td class=busy>PA Slack
|
|
<tr id=CCPeripheralRow>
|
|
<td id=DCA>DCA <!-- 17 -->
|
|
<td id=PPB>PPB <!-- 18 -->
|
|
<td id=PRB>PRB <!-- 19 -->
|
|
<td id=PRA>PRA <!-- 20 -->
|
|
<td id=PPA>PPA <!-- 21 -->
|
|
<td id=SPO>SPO <!-- 22 -->
|
|
<td id=CRB>CRB <!-- 23 -->
|
|
<td id=CRA>CRA <!-- 24 -->
|
|
<td id=CPA>CPA <!-- 25 -->
|
|
<td id=LPB>LPB <!-- 26 -->
|
|
<td id=LPA>LPA <!-- 27 -->
|
|
<td id=DKB>DKB <!-- 28 -->
|
|
<td id=DKA>DKA <!-- 29 -->
|
|
<td id=DRB>DRB <!-- 30 -->
|
|
<td id=DRA>DRA <!-- 31 -->
|
|
<td id=MTA>MTA <!-- 47 -->
|
|
<td id=MTB>MTB <!-- 46 -->
|
|
<td id=MTC>MTC <!-- 45 -->
|
|
<td id=MTD>MTD <!-- 44 -->
|
|
<td id=MTE>MTE <!-- 43 -->
|
|
<td id=MTF>MTF <!-- 42 -->
|
|
<td id=MTH>MTH <!-- 41 -->
|
|
<td id=MTJ>MTJ <!-- 40 -->
|
|
<td id=MTK>MTK <!-- 39 -->
|
|
<td id=MTL>MTL <!-- 38 -->
|
|
<td id=MTM>MTM <!-- 37 -->
|
|
<td id=MTN>MTN <!-- 36 -->
|
|
<td id=MTP>MTP <!-- 35 -->
|
|
<td id=MTR>MTR <!-- 34 -->
|
|
<td id=MTS>MTS <!-- 33 -->
|
|
<td id=MTT>MTT <!-- 32 -->
|
|
<td id=procRate>
|
|
<td class=busy>PA Rate
|
|
</table>
|
|
</div>
|
|
|
|
</body>
|
|
</html> |