diff --git a/emulator/B5500CentralControl.js b/emulator/B5500CentralControl.js index 62d1d91..c176fe5 100644 --- a/emulator/B5500CentralControl.js +++ b/emulator/B5500CentralControl.js @@ -108,7 +108,7 @@ B5500CentralControl.unitIndex = [ [null, 47,null, 46, 31, 45, 29, 44, 30, 43, 24, 42, 28, 41, 23, 40, 17, 39, 20, 38, 19, 37,null, 36,null, 35,null, 34,null, 33, 22, 32]]; -// The following object maps the unit mnemonics from B5500SystemConfiguration.Units +// The following object maps the unit mnemonics from B5500SystemConfiguration.units // to the attributes needed to configure the CC unit[] array. B5500CentralControl.unitSpecs = { @@ -814,7 +814,7 @@ B5500CentralControl.prototype.configureSystem = function() { function makeChange(cc, maskBit) { return function(ready) { cc.unitStatusMask = (ready ? cc.bitSet(cc.unitStatusMask, maskBit) - : cc.bitReset(cc.unitStatusMask, maskBit); + : cc.bitReset(cc.unitStatusMask, maskBit)); }; } @@ -865,18 +865,15 @@ B5500CentralControl.prototype.configureSystem = function() { } // Configure the peripheral units - for (mnem in cfg.Units) { - if (cfg.Units[mnem]) { + for (mnem in cfg.units) { + if (cfg.units[mnem]) { specs = B5500CentralControl.unitSpecs[mnem]; if (specs) { unitClass = specs.unitClass || B5500DummyUnit; if (unitClass) { u = new unitClass(mnem, specs.index, specs.designate, - makeChange(this, specs.index), makeSignal(this, mnem); + makeChange(this, specs.index), makeSignal(this, mnem)); this.unit[specs.index] = u; - u.mnemonic = mnem; - u.index = specs.index; - u.designate = specs.designate; } } } diff --git a/emulator/B5500IOUnit.js b/emulator/B5500IOUnit.js index 941efdc..bb88927 100644 --- a/emulator/B5500IOUnit.js +++ b/emulator/B5500IOUnit.js @@ -549,7 +549,7 @@ B5500IOUnit.prototype.finish = function () { }; /**************************************/ -B5500IOUnit.prototype.makeFinish(f) { +B5500IOUnit.prototype.makeFinish = function(f) { /* Utility function to create a closure for I/O finish handlers */ var that = this; diff --git a/emulator/B5500SystemConfiguration.js b/emulator/B5500SystemConfiguration.js index f4679f1..5d01fcc 100644 --- a/emulator/B5500SystemConfiguration.js +++ b/emulator/B5500SystemConfiguration.js @@ -27,7 +27,7 @@ var B5500SystemConfiguration = { IO3: false, // I/O Unit 3 available IO4: false, // I/O Unit 4 available - MemMod: [ + memMod: [ true, // Memory module 0 available (4KW) true, // Memory module 1 available (4KW) false, // Memory module 2 available (4KW) @@ -37,7 +37,7 @@ var B5500SystemConfiguration = { false, // Memory module 6 available (4KW) false], // Memory module 7 available (4KW) - Units: { + units: { SPO: true, // SPO keyboard/printer DKA: false, // Disk File Control A DKB: false, // Disk File Control B @@ -68,5 +68,5 @@ var B5500SystemConfiguration = { MTP: false, // Magnetic Tape Unit P MTR: false, // Magnetic Tape Unit R MTS: false, // Magnetic Tape Unit S - MTT: false}; // Magnetic Tape Unit X + MTT: false}, // Magnetic Tape Unit X }; diff --git a/webUI/B5500Console.html b/webUI/B5500Console.html index fc7ee85..049f337 100644 --- a/webUI/B5500Console.html +++ b/webUI/B5500Console.html @@ -7,83 +7,105 @@ + + + + + + + @@ -103,10 +125,8 @@ window.onload = function() { - - + +
diff --git a/webUI/B5500DummyUnit.js b/webUI/B5500DummyUnit.js
index 633d15b..e915c6d 100644
--- a/webUI/B5500DummyUnit.js
+++ b/webUI/B5500DummyUnit.js
@@ -45,54 +45,54 @@ B5500DummyUnit.prototype.clear = function() {
B5500DummyUnit.prototype.read = function(finish, buffer, length, mode, control) {
/* Initiates a read operation on the unit */
- finish(0x04, 0);
+ finish(0x04, 0); // report unit not ready
};
/**************************************/
B5500DummyUnit.prototype.space = function(finish, length, control) {
/* Initiates a space operation on the unit */
- finish(0x04, 0);
+ finish(0x04, 0); // report unit not ready
};
/**************************************/
B5500DummyUnit.prototype.write = function(finish, buffer, length, mode, control) {
/* Initiates a write operation on the unit */
- finish(0x04, 0);
+ finish(0x04, 0); // report unit not ready
};
/**************************************/
B5500DummyUnit.prototype.erase = function(finish, length) {
/* Initiates an erase operation on the unit */
- finish(0x04, 0);
+ finish(0x04, 0); // report unit not ready
};
/**************************************/
B5500DummyUnit.prototype.rewind = function(finish) {
/* Initiates a rewind operation on the unit */
- finish(0x04, 0);
+ finish(0x04, 0); // report unit not ready
};
/**************************************/
B5500DummyUnit.prototype.readCheck = function(finish, length) {
/* Initiates a read check operation on the unit */
- finish(0x04, 0);
+ finish(0x04, 0); // report unit not ready
};
/**************************************/
B5500DummyUnit.prototype.readInterrogate = function(finish) {
/* Initiates a read interrogate operation on the unit */
- finish(0x04, 0);
+ finish(0x04, 0); // report unit not ready
};
/**************************************/
B5500DummyUnit.prototype.writeInterrogate = function (finish) {
/* Initiates a write interrogate operation on the unit */
- finish(0x04, 0);
+ finish(0x04, 0); // report unit not ready
};
diff --git a/webUI/B5500SPOUnit.html b/webUI/B5500SPOUnit.html
index f8d9d9b..918a2f5 100644
--- a/webUI/B5500SPOUnit.html
+++ b/webUI/B5500SPOUnit.html
@@ -6,429 +6,6 @@
-
-
diff --git a/webUI/B5500SPOUnit.js b/webUI/B5500SPOUnit.js
new file mode 100644
index 0000000..c52bc76
--- /dev/null
+++ b/webUI/B5500SPOUnit.js
@@ -0,0 +1,540 @@
+/***********************************************************************
+* retro-b5500/emulator B5500SPOUnit.js
+************************************************************************
+* Copyright (c) 2012, Nigel Williams and Paul Kimpel.
+* Licensed under the MIT License, see
+* http://www.opensource.org/licenses/mit-license.php
+************************************************************************
+* B5500 SPO Peripheral Unit module.
+*
+* Defines a SPO peripheral unit type that implements the Supervisory
+* Print Out device on the operator's console.
+*
+************************************************************************
+* 2012-12-22 P.Kimpel
+* Original version, from B5500DummyUnit.js.
+***********************************************************************/
+"use strict";
+
+/**************************************/
+function B5500SPOUnit(mnemonic, index, designate, statusChange, signal) {
+ /* Constructor for the SPOUnit object */
+ var that = this;
+
+ this.maxScrollLines = 500; // Maximum amount of printer scrollback
+ this.charPeriod = 100; // Printer speed, milliseconds per character
+
+ this.mnemonic = mnemonic; // Unit mnemonic
+ this.index = index; // Ready-mask bit number
+ this.designate = designate; // IOD unit designate number
+ this.statusChange = statusChange; // external function to call for ready-status change
+ this.signal = signal; // external function to call for special signals (e.g,. SPO input request)
+ this.finish = null; // external function to call for I/O completion
+
+ this.clear();
+
+ this.backspaceChar.that = this; // Store object context these functions
+ this.printChar.that = this;
+ this.writeChar.that = this;
+
+ this.window = window.open("B5500SPOUnit.html", "SPOWin", "scrollbars,resizable,width=600,height=500");
+
+ this.window.onload = function() {
+ /* Initializes the SPO window and user interface */
+ var x;
+
+ that.doc = that.window.document;
+ that.paper = that.$$("SPOUT").contentDocument.body;
+ that.$$("SPOUT").contentDocument.head.innerHTML += "";
+
+ window.resizeBy(that.$$("SPODiv").scrollWidth-document.body.scrollWidth,
+ that.$$("SPODiv").scrollHeight-document.body.scrollHeight);
+ window.moveTo((screen.availWidth-window.outerWidth)/2, (screen.availHeight-window.outerHeight)/2);
+
+ that.$$("SPORemoteBtn").onclick = function() {
+ that.setRemote();
+ };
+
+ that.$$("SPOPowerBtn").onclick = function() {
+ that.window.alert("Don't DO that");
+ };
+
+ that.$$("SPOLocalBtn").onclick = function() {
+ that.setLocal();
+ };
+
+ that.$$("SPOInputRequestBtn").onclick = function() {
+ if (that.spoState == that.spoRemote) {
+ that.signal();
+ } else if (that.spoState == that.spoOutput) {
+ that.signal();
+ }
+ };
+
+ that.$$("SPOErrorBtn").onclick = function() {
+ that.cancelInput();
+ };
+
+ that.$$("SPOEndOfMessageBtn").onclick = function() {
+ that.terminateInput();
+ };
+
+ window.onkeypress = function(ev) {
+ that.keyPress(ev);
+ };
+
+ window.onkeydown = function(ev) {
+ that.keyDown(ev);
+ };
+
+ for (x=0; x<32; x++) {
+ that.appendEmptyLine();
+ }
+ that.setReady();
+ that.printText("retro-B5500 Emulator Version 0.01", function() {
+ that.setRemote();
+ that.appendEmptyLine();
+ });
+ };
+}
+
+// this.spoState enumerations
+B5500SPOUnit.prototype.spoNotReady = 0;
+B5500SPOUnit.prototype.spoLocal = 1;
+B5500SPOUnit.prototype.spoRemote = 2;
+B5500SPOUnit.prototype.spoInput = 3;
+B5500SPOUnit.prototype.spoOutput = 4;
+
+B5500SPOUnit.prototype.keyFilter = [ // Filter keyCode values to valid B5500 ones
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, // 00-0F
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, // 10-1F
+ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x3F,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, // 20-2F
+ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F, // 30-3F
+ 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, // 40-4F
+ 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x3F,0x5D,0x3F,0x3F, // 50-5F
+ 0x3F,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, // 60-6F
+ 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x3F]; // 70-7F
+
+/**************************************/
+B5500SPOUnit.prototype.$$ = function(e) {
+ return this.doc.getElementById(e)};
+
+/**************************************/
+B5500SPOUnit.prototype.clear = function() {
+ /* Initializes (and if necessary, creates) the SPO unit state */
+
+ this.ready = false; // ready status
+ this.busy = false; // busy status
+ this.activeIOUnit = 0; // I/O unit currently using this device
+ this.spoState = this.spoNotReady; // Current state of SPO interface
+ this.spoLocalRequested = false; // LOCAL button pressed while active
+ this.errorMask = 0; // error mask for finish()
+
+ this.buffer = null;
+ this.bufLength = 0;
+ this.bufIndex = 0;
+ this.printCol = 0;
+ this.nextCharTime = 0;
+};
+
+/**************************************/
+B5500SPOUnit.prototype.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);
+ }
+};
+
+/**************************************/
+B5500SPOUnit.prototype.addClass = function(e, name) {
+ /* Adds a class "name" to the element "e"s class list */
+
+ if (!this.hasClass(e, name)) {
+ e.className += (" " + name);
+ }
+};
+
+/**************************************/
+B5500SPOUnit.prototype.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"), "");
+};
+
+/**************************************/
+B5500SPOUnit.prototype.setNotReady = function() {
+ /* Sets the status of the SPO to Not Ready */
+ var readyBtn = this.$$("SPOReadyBtn");
+
+ if (this.spoState == this.spoLocal) {
+ this.spoState = this.spoNotReady;
+ this.removeClass(readyBtn, "yellowLit");
+ }
+};
+
+/**************************************/
+B5500SPOUnit.prototype.setReady = function() {
+ /* Sets the status of the SPO to Ready */
+ var readyBtn = this.$$("SPOReadyBtn");
+
+ if (this.spoState == this.spoNotReady) {
+ this.addClass(readyBtn, "yellowLit");
+ this.spoState = this.spoLocal;
+ }
+};
+
+/**************************************/
+B5500SPOUnit.prototype.setLocal = function() {
+ /* Sets the status of the SPO to Local */
+ var localBtn = this.$$("SPOLocalBtn");
+ var remoteBtn = this.$$("SPORemoteBtn");
+
+ if (this.spoState == this.spoRemote) {
+ this.spoState = this.spoLocal;
+ this.addClass(localBtn, "yellowLit");
+ this.removeClass(remoteBtn, "yellowLit");
+
+ // Set up to echo characters from the keyboard
+ this.buffer = null;
+ this.bufLength = 0;
+ this.bufIndex = 0;
+ this.printCol = 0;
+ this.nextCharTime = new Date().getTime();
+ this.finish = null;
+ }
+};
+
+/**************************************/
+B5500SPOUnit.prototype.setRemote = function() {
+ /* Sets the status of the SPO to Remote */
+ var localBtn = this.$$("SPOLocalBtn");
+ var remoteBtn = this.$$("SPORemoteBtn");
+
+ if (this.spoState == this.spoLocal) {
+ this.spoState = this.spoRemote;
+ this.addClass(remoteBtn, "yellowLit");
+ this.removeClass(localBtn, "yellowLit");
+ }
+};
+
+/**************************************/
+B5500SPOUnit.prototype.appendEmptyLine = function() {
+ /* Removes excess lines already printed, then appends a new element + to the