mirror of
https://github.com/pkimpel/retro-220.git
synced 2026-01-11 23:52:46 +00:00
Commit retro-220 emulator version 0.07:
1. Implement centralized pop-up window opening mechanism to enforce a delay between pop-up opens. This is to satisfy new restrictions on multiple pop-ups imposed by the Apple Safari 11.0 browser. 2. Correct Reload-Lockout behavior and format band 6 initialization in B220CardatronInput. 3. Correct translation of sign digits and skip-to-channel behavior in B220CardatronOutput. 4. Strip sign digit from search/scan argument word when storing into B220MagTapeControl T register. 5. Remove option for 1000-word system memory size and correct handling of memory size list selection in B220SystemConfig. 6. Change reel-to-reel magnetic tape name from DataReader to TSU in B220SystemConfig.
This commit is contained in:
parent
f19f4e9b65
commit
a29f2cac5d
33
.gitattributes
vendored
Normal file
33
.gitattributes
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||
* text=auto
|
||||
|
||||
# Explicitly declare text files you want to always be normalized and converted
|
||||
# to native line endings on checkout.
|
||||
*.html text
|
||||
*.css text
|
||||
*.js text
|
||||
*.md text
|
||||
*.txt text
|
||||
*.lst text
|
||||
*.svg text
|
||||
*.card text
|
||||
*.tape text
|
||||
*.pt text
|
||||
*.bacg text
|
||||
*.baca text
|
||||
*.cmd text
|
||||
*.bat text
|
||||
*.wsf text
|
||||
*.vbs text
|
||||
|
||||
# Denote all files that are truly binary and should not be modified.
|
||||
*.png binary
|
||||
*.gif binary
|
||||
*.jpg binary
|
||||
*.ttf binary
|
||||
*.woff binary
|
||||
*.pdf binary
|
||||
*.doc binary
|
||||
*.docx binary
|
||||
*.xls binary
|
||||
*.xlsx binary
|
||||
38
.gitignore
vendored
38
.gitignore
vendored
@ -1,19 +1,19 @@
|
||||
#############
|
||||
## Windows detritus
|
||||
#############
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
#IIS config file
|
||||
web.config
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
#############
|
||||
## Windows detritus
|
||||
#############
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
#IIS config file
|
||||
web.config
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
|
||||
42
LICENSE.txt
42
LICENSE.txt
@ -1,21 +1,21 @@
|
||||
Copyright (c) 2016 Paul Kimpel
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
Copyright (c) 2016 Paul Kimpel
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
38
README.md
38
README.md
@ -1,19 +1,19 @@
|
||||
The Burroughs 220 was a late-1950s, decimal, vacuum-tube, core-memory computer system. Some consider it to be the last of the major vacuum-tube computers.
|
||||
|
||||
The 220 was the follow-on product to the ElectroData/Burroughs Datatron 205. It was initially developed as the ElectroData Datatron 220 but renamed after Burroughs bought ElectroData in 1956. The system was initially released in 1958. It did well with both scientific and commercial applications, but being a vacuum-tube system at the beginning of the transistorized era, was only modestly successful.
|
||||
|
||||
The ElectroData Division of Burroughs went on to create a number of successful systems after the 220, including the B100/200/300 series, the B1700/1800/1900 series, the B2000/3000/4000/V Series, the B5000/5500, and finally the B6000/7000/A Series, which are still produced and sold today as Unisys ClearPath MCP systems.
|
||||
|
||||
The main goal of this project is creation of a web browser-based emulator for the 220.
|
||||
|
||||
A second goal is reconstruction of the Burroughs Algebraic Compiler (BALGOL), an Algol-58 compiler written for the 220 by a team from Burroughs that included Joel Erdwinn, Jack Merner, Donald Knuth, Dave Dahm, and Clark Oliphint.
|
||||
|
||||
The contents of this project are licensed under the [MIT License](http://www.opensource.org/licenses/mit-license.php).
|
||||
|
||||
| Related Sites | URL |
|
||||
| ------------- | ----- |
|
||||
| Emulator hosting site | http://www.phkimpel.us/Burroughs-220/ |
|
||||
| Burroughs 205/220 blog | http://datatron.blogspot.com |
|
||||
| Datatron 205 site | http://www.phkimpel.us/ElectroData-205/ |
|
||||
| Documents at bitsavers | http://bitsavers.org/pdf/burroughs/electrodata/220/ |
|
||||
| BALGOL compiler listing | http://archive.computerhistory.org/resources/text/Knuth_Don_X4100/PDF_index/k-1-pdf/k-1-u2196-balgol220compiler.pdf |
|
||||
The Burroughs 220 was a late-1950s, decimal, vacuum-tube, core-memory computer system. Some consider it to be the last of the major vacuum-tube computers.
|
||||
|
||||
The 220 was the follow-on product to the ElectroData/Burroughs Datatron 205. It was initially developed as the ElectroData Datatron 220 but renamed after Burroughs bought ElectroData in 1956. The system was initially released in 1958. It did well with both scientific and commercial applications, but being a vacuum-tube system at the beginning of the transistorized era, was only modestly successful.
|
||||
|
||||
The ElectroData Division of Burroughs went on to create a number of successful systems after the 220, including the B100/200/300 series, the B1700/1800/1900 series, the B2000/3000/4000/V Series, the B5000/5500, and finally the B6000/7000/A Series, which are still produced and sold today as Unisys ClearPath MCP systems.
|
||||
|
||||
The main goal of this project is creation of a web browser-based emulator for the 220.
|
||||
|
||||
A second goal is reconstruction of the Burroughs Algebraic Compiler (BALGOL), an Algol-58 compiler written for the 220 by a team from Burroughs that included Joel Erdwinn, Jack Merner, Donald Knuth, Dave Dahm, and Clark Oliphint.
|
||||
|
||||
The contents of this project are licensed under the [MIT License](http://www.opensource.org/licenses/mit-license.php).
|
||||
|
||||
| Related Sites | URL |
|
||||
| ------------- | ----- |
|
||||
| Emulator hosting site | http://www.phkimpel.us/Burroughs-220/ |
|
||||
| Burroughs 205/220 blog | http://datatron.blogspot.com |
|
||||
| Datatron 205 site | http://www.phkimpel.us/ElectroData-205/ |
|
||||
| Documents at bitsavers | http://bitsavers.org/pdf/burroughs/electrodata/220/ |
|
||||
| BALGOL compiler listing | http://archive.computerhistory.org/resources/text/Knuth_Don_X4100/PDF_index/k-1-pdf/k-1-u2196-balgol220compiler.pdf |
|
||||
|
||||
@ -61,6 +61,7 @@
|
||||
/**************************************/
|
||||
function B220Processor(config, devices) {
|
||||
/* Constructor for the 220 Processor module object */
|
||||
var staticLampGlow = false; // compute fractional lamp glow (experimental)
|
||||
|
||||
this.mnemonic = "CPU";
|
||||
B220Processor.instance = this; // externally-available object reference (for DiagMonitor)
|
||||
@ -101,14 +102,14 @@ function B220Processor(config, devices) {
|
||||
this.delayRequested = 0; // last requested setCallback() delay, ms
|
||||
|
||||
// Primary Registers
|
||||
this.A = new B220Processor.Register(11*4, this, false);
|
||||
this.B = new B220Processor.Register( 4*4, this, false);
|
||||
this.C = new B220Processor.Register(10*4, this, false);
|
||||
this.D = new B220Processor.Register(11*4, this, false);
|
||||
this.E = new B220Processor.Register( 4*4, this, false);
|
||||
this.P = new B220Processor.Register( 4*4, this, false);
|
||||
this.R = new B220Processor.Register(11*4, this, false);
|
||||
this.S = new B220Processor.Register( 4*4, this, false);
|
||||
this.A = new B220Processor.Register(11*4, this, staticLampGlow);
|
||||
this.B = new B220Processor.Register( 4*4, this, staticLampGlow);
|
||||
this.C = new B220Processor.Register(10*4, this, staticLampGlow);
|
||||
this.D = new B220Processor.Register(11*4, this, staticLampGlow);
|
||||
this.E = new B220Processor.Register( 4*4, this, staticLampGlow);
|
||||
this.P = new B220Processor.Register( 4*4, this, staticLampGlow);
|
||||
this.R = new B220Processor.Register(11*4, this, staticLampGlow);
|
||||
this.S = new B220Processor.Register( 4*4, this, staticLampGlow);
|
||||
|
||||
// Register E decrements modulo the system memory size, so override dec().
|
||||
this.E.dec = function decE() {
|
||||
@ -119,14 +120,14 @@ function B220Processor(config, devices) {
|
||||
};
|
||||
|
||||
// Control Console Lamps
|
||||
this.digitCheckAlarm = new B220Processor.FlipFlop(this, false);
|
||||
this.digitCheckAlarm = new B220Processor.FlipFlop(this, staticLampGlow);
|
||||
|
||||
this.systemNotReady = new B220Processor.FlipFlop(this, false);
|
||||
this.computerNotReady = new B220Processor.FlipFlop(this, false);
|
||||
this.systemNotReady = new B220Processor.FlipFlop(this, staticLampGlow);
|
||||
this.computerNotReady = new B220Processor.FlipFlop(this, staticLampGlow);
|
||||
|
||||
this.compareLowLamp = new B220Processor.FlipFlop(this, false);
|
||||
this.compareEqualLamp = new B220Processor.FlipFlop(this, false);
|
||||
this.compareHighLamp = new B220Processor.FlipFlop(this, false);
|
||||
this.compareLowLamp = new B220Processor.FlipFlop(this, staticLampGlow);
|
||||
this.compareEqualLamp = new B220Processor.FlipFlop(this, staticLampGlow);
|
||||
this.compareHighLamp = new B220Processor.FlipFlop(this, staticLampGlow);
|
||||
|
||||
// Control Console Switches
|
||||
this.PC1SW = 0; // program control switches 1-10
|
||||
@ -159,29 +160,29 @@ function B220Processor(config, devices) {
|
||||
this.HOLDSEQUENCE8SW = 0;
|
||||
|
||||
// Left-Hand Maintenance Panel Registers & Flip-Flops
|
||||
this.CI = new B220Processor.Register(5, this, false); // carry inverters
|
||||
this.DC = new B220Processor.Register(6, this, false); // digit counter (modulo 20)
|
||||
this.SC = new B220Processor.Register(4, this, false); // sequence counter
|
||||
this.SI = new B220Processor.Register(4, this, false); // sum inverters
|
||||
this.X = new B220Processor.Register(4, this, false); // adder X (augend) input
|
||||
this.Y = new B220Processor.Register(4, this, false); // adder Y (addend) input
|
||||
this.Z = new B220Processor.Register(4, this, false); // decimal sum inverters, adder output
|
||||
this.CI = new B220Processor.Register(5, this, staticLampGlow); // carry inverters
|
||||
this.DC = new B220Processor.Register(6, this, staticLampGlow); // digit counter (modulo 20)
|
||||
this.SC = new B220Processor.Register(4, this, staticLampGlow); // sequence counter
|
||||
this.SI = new B220Processor.Register(4, this, staticLampGlow); // sum inverters
|
||||
this.X = new B220Processor.Register(4, this, staticLampGlow); // adder X (augend) input
|
||||
this.Y = new B220Processor.Register(4, this, staticLampGlow); // adder Y (addend) input
|
||||
this.Z = new B220Processor.Register(4, this, staticLampGlow); // decimal sum inverters, adder output
|
||||
|
||||
this.CI.checkFC = B220Processor.emptyFunction; // these registers generate A-F undigits
|
||||
this.SI.checkFC = B220Processor.emptyFunction;
|
||||
|
||||
this.C10 = new B220Processor.FlipFlop(this, false); // decimal carry toggle
|
||||
this.DST = new B220Processor.FlipFlop(this, false); // D-sign toggle
|
||||
this.LT1 = new B220Processor.FlipFlop(this, false); // logical toggle 1
|
||||
this.LT2 = new B220Processor.FlipFlop(this, false); // logical toggle 2
|
||||
this.LT3 = new B220Processor.FlipFlop(this, false); // logical toggle 3
|
||||
this.SCI = new B220Processor.FlipFlop(this, false); // sequence counter inverter
|
||||
this.SGT = new B220Processor.FlipFlop(this, false); // sign toggle
|
||||
this.SUT = new B220Processor.FlipFlop(this, false); // subtract toggle
|
||||
this.TBT = new B220Processor.FlipFlop(this, false); // tape busy toggle
|
||||
this.TCT = new B220Processor.FlipFlop(this, false); // tape clock toggle
|
||||
this.TPT = new B220Processor.FlipFlop(this, false); // tape pulse toggle
|
||||
this.TWT = new B220Processor.FlipFlop(this, false); // tape write toggle
|
||||
this.C10 = new B220Processor.FlipFlop(this, staticLampGlow); // decimal carry toggle
|
||||
this.DST = new B220Processor.FlipFlop(this, staticLampGlow); // D-sign toggle
|
||||
this.LT1 = new B220Processor.FlipFlop(this, staticLampGlow); // logical toggle 1
|
||||
this.LT2 = new B220Processor.FlipFlop(this, staticLampGlow); // logical toggle 2
|
||||
this.LT3 = new B220Processor.FlipFlop(this, staticLampGlow); // logical toggle 3
|
||||
this.SCI = new B220Processor.FlipFlop(this, staticLampGlow); // sequence counter inverter
|
||||
this.SGT = new B220Processor.FlipFlop(this, staticLampGlow); // sign toggle
|
||||
this.SUT = new B220Processor.FlipFlop(this, staticLampGlow); // subtract toggle
|
||||
this.TBT = new B220Processor.FlipFlop(this, staticLampGlow); // tape busy toggle
|
||||
this.TCT = new B220Processor.FlipFlop(this, staticLampGlow); // tape clock toggle
|
||||
this.TPT = new B220Processor.FlipFlop(this, staticLampGlow); // tape pulse toggle
|
||||
this.TWT = new B220Processor.FlipFlop(this, staticLampGlow); // tape write toggle
|
||||
|
||||
// Right-Hand Maintenance Panel Switches
|
||||
this.MULTIPLEACCESSSW = 0;
|
||||
@ -197,33 +198,33 @@ function B220Processor(config, devices) {
|
||||
this.FETCHEXECUTELOCKSW = 0;
|
||||
|
||||
// Right-Hand Maintenance Panel Registers & Flip-Flops
|
||||
this.AX = new B220Processor.Register(10, this, false); // A exponent register
|
||||
this.BI = new B220Processor.Register( 8, this, false); // paper tape buffer inverters
|
||||
this.DX = new B220Processor.Register( 8, this, false); // D exponent register
|
||||
this.PA = new B220Processor.Register( 8, this, false); // PA register
|
||||
this.AX = new B220Processor.Register(10, this, staticLampGlow); // A exponent register
|
||||
this.BI = new B220Processor.Register( 8, this, staticLampGlow); // paper tape buffer inverters
|
||||
this.DX = new B220Processor.Register( 8, this, staticLampGlow); // D exponent register
|
||||
this.PA = new B220Processor.Register( 8, this, staticLampGlow); // PA register
|
||||
|
||||
this.ALT = new B220Processor.FlipFlop(this, false); // program check alarm toggle
|
||||
this.AST = new B220Processor.FlipFlop(this, false); // asynchronous toggle
|
||||
this.CCT = new B220Processor.FlipFlop(this, false); // ?? toggle
|
||||
this.CRT = new B220Processor.FlipFlop(this, false); // Cardatron alarm toggle
|
||||
this.DPT = new B220Processor.FlipFlop(this, false); // decimal point toggle (SPO)
|
||||
this.EWT = new B220Processor.FlipFlop(this, false); // end of word toggle
|
||||
this.EXT = new B220Processor.FlipFlop(this, false); // fetch(0)/execute(1) toggle
|
||||
this.HAT = new B220Processor.FlipFlop(this, false); // high-speed printer alarm toggle
|
||||
this.HCT = new B220Processor.FlipFlop(this, false); // halt control toggle, for SOR, SOH, IOM
|
||||
this.HIT = new B220Processor.FlipFlop(this, false); // high comparison toggle
|
||||
this.MAT = new B220Processor.FlipFlop(this, false); // multiple access toggle
|
||||
this.MET = new B220Processor.FlipFlop(this, false); // memory (storage) alarm toggle
|
||||
this.MNT = new B220Processor.FlipFlop(this, false); // manual toggle
|
||||
this.OFT = new B220Processor.FlipFlop(this, false); // overflow toggle
|
||||
this.PAT = new B220Processor.FlipFlop(this, false); // paper tape alarm toggle
|
||||
this.PRT = new B220Processor.FlipFlop(this, false); // paper tape read toggle
|
||||
this.PZT = new B220Processor.FlipFlop(this, false); // paper tape zone toggle
|
||||
this.RPT = new B220Processor.FlipFlop(this, false); // repeat toggle
|
||||
this.RUT = new B220Processor.FlipFlop(this, false); // run toggle
|
||||
this.SST = new B220Processor.FlipFlop(this, false); // single-step toggle
|
||||
this.TAT = new B220Processor.FlipFlop(this, false); // magnetic tape alarm toggle
|
||||
this.UET = new B220Processor.FlipFlop(this, false); // unequal comparison toggle (HIT=UET=0 => off)
|
||||
this.ALT = new B220Processor.FlipFlop(this, staticLampGlow); // program check alarm toggle
|
||||
this.AST = new B220Processor.FlipFlop(this, staticLampGlow); // asynchronous toggle
|
||||
this.CCT = new B220Processor.FlipFlop(this, staticLampGlow); // ?? toggle
|
||||
this.CRT = new B220Processor.FlipFlop(this, staticLampGlow); // Cardatron alarm toggle
|
||||
this.DPT = new B220Processor.FlipFlop(this, staticLampGlow); // decimal point toggle (SPO)
|
||||
this.EWT = new B220Processor.FlipFlop(this, staticLampGlow); // end of word toggle
|
||||
this.EXT = new B220Processor.FlipFlop(this, staticLampGlow); // fetch(0)/execute(1) toggle
|
||||
this.HAT = new B220Processor.FlipFlop(this, staticLampGlow); // high-speed printer alarm toggle
|
||||
this.HCT = new B220Processor.FlipFlop(this, staticLampGlow); // halt control toggle, for SOR, SOH, IOM
|
||||
this.HIT = new B220Processor.FlipFlop(this, staticLampGlow); // high comparison toggle
|
||||
this.MAT = new B220Processor.FlipFlop(this, staticLampGlow); // multiple access toggle
|
||||
this.MET = new B220Processor.FlipFlop(this, staticLampGlow); // memory (storage) alarm toggle
|
||||
this.MNT = new B220Processor.FlipFlop(this, staticLampGlow); // manual toggle
|
||||
this.OFT = new B220Processor.FlipFlop(this, staticLampGlow); // overflow toggle
|
||||
this.PAT = new B220Processor.FlipFlop(this, staticLampGlow); // paper tape alarm toggle
|
||||
this.PRT = new B220Processor.FlipFlop(this, staticLampGlow); // paper tape read toggle
|
||||
this.PZT = new B220Processor.FlipFlop(this, staticLampGlow); // paper tape zone toggle
|
||||
this.RPT = new B220Processor.FlipFlop(this, staticLampGlow); // repeat toggle
|
||||
this.RUT = new B220Processor.FlipFlop(this, staticLampGlow); // run toggle
|
||||
this.SST = new B220Processor.FlipFlop(this, staticLampGlow); // single-step toggle
|
||||
this.TAT = new B220Processor.FlipFlop(this, staticLampGlow); // magnetic tape alarm toggle
|
||||
this.UET = new B220Processor.FlipFlop(this, staticLampGlow); // unequal comparison toggle (HIT=UET=0 => off)
|
||||
|
||||
// Left/Right Maintenance Panel
|
||||
this.leftPanelOpen = false;
|
||||
@ -257,7 +258,7 @@ function B220Processor(config, devices) {
|
||||
* Global Constants *
|
||||
***********************************************************************/
|
||||
|
||||
B220Processor.version = "0.06";
|
||||
B220Processor.version = "0.07";
|
||||
|
||||
B220Processor.tick = 1000/200000; // milliseconds per clock cycle (200KHz)
|
||||
B220Processor.cyclesPerMilli = 1/B220Processor.tick;
|
||||
|
||||
@ -96,11 +96,15 @@ window.addEventListener("load", function() {
|
||||
/**************************************/
|
||||
function openDiagPanel(ev) {
|
||||
/* Opens the emulator's diagnostic monitor panel in a new sub-window */
|
||||
var global = window;
|
||||
|
||||
diagWindow = window.open("B220DiagMonitor.html", "DiagPanel",
|
||||
"resizable,width=300,height=500,left=0,top=" + screen.availHeight-500);
|
||||
diagWindow.global = window; // give it access to our globals.
|
||||
diagWindow.focus();
|
||||
B220Util.openPopup(window, "B220DiagMonitor.html", "DiagPanel",
|
||||
"resizable,width=300,height=500,left=0,top=" + screen.availHeight-500,
|
||||
this, function(ev) {
|
||||
diagWindow = ev.target.defaultView;
|
||||
diagWindow.global = global; // give it access to our globals.
|
||||
diagWindow.focus();
|
||||
});
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
|
||||
@ -26,11 +26,11 @@ function B220CardatronControl(p) {
|
||||
// Do not call this.clear() here -- call from onLoad instead
|
||||
|
||||
this.doc = null;
|
||||
this.window = window.open("../webUI/B220CardatronControl.html", this.mnemonic,
|
||||
this.window = null;
|
||||
B220Util.openPopup(window, "../webUI/B220CardatronControl.html", this.mnemonic,
|
||||
"location=no,scrollbars=no,resizable,width=140,height=140,left=" + left +
|
||||
",top=" + (screen.availHeight-140));
|
||||
this.window.addEventListener("load",
|
||||
B220CardatronControl.prototype.cardatronOnLoad.bind(this), false);
|
||||
",top=" + (screen.availHeight-140),
|
||||
this, B220CardatronControl.prototype.cardatronOnLoad);
|
||||
|
||||
// Set up the I/O devices from the system configuration
|
||||
this.inputUnit = [
|
||||
@ -127,14 +127,15 @@ B220CardatronControl.prototype.beforeUnload = function beforeUnload(ev) {
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220CardatronControl.prototype.cardatronOnLoad = function cardatronOnLoad() {
|
||||
B220CardatronControl.prototype.cardatronOnLoad = function cardatronOnLoad(ev) {
|
||||
/* Initializes the Cardatron Control window and user interface */
|
||||
var body;
|
||||
var box;
|
||||
var e;
|
||||
var x;
|
||||
|
||||
this.doc = this.window.document;
|
||||
this.doc = ev.target;
|
||||
this.window = this.doc.defaultView;
|
||||
body = this.$$("PanelSurface");
|
||||
|
||||
this.bufferReadLamp = new NeonLampBox(body, null, null, "BufferReadLamp");
|
||||
|
||||
@ -45,17 +45,22 @@ function B220CardatronInput(mnemonic, unitIndex, config) {
|
||||
new Uint8Array(this.bufferDrum, tks*6, tks), // format band 6 (fixed)
|
||||
new Uint8Array(this.bufferDrum, tks*7, tks)]; // format band 7 (dummy)
|
||||
|
||||
// Initialize format band 6 for all-numeric transfer
|
||||
// (note that ArrayBuffer storage is initialized to zero, so band[160..233] == 0)
|
||||
for (x=0; x<160; x+=2) {
|
||||
// Initialize format band 6 for all-numeric transfer.
|
||||
for (x=0; x<160; x+=2) { // transfer 80 numeric digits
|
||||
this.formatBand[6][x] = 1;
|
||||
this.formatBand[6][x+1] = 3;
|
||||
}
|
||||
for (x=234; x<this.info.length; ++x) {
|
||||
|
||||
// Fill 77 digits of zeroes (8 to complete the word from cols 1-3, 66 to supply six
|
||||
// computer words of zeroes, and three "pusher" digits to release the last word from D
|
||||
// (note that ArrayBuffer storage is initialized to zero, so band[160..236] == 0).
|
||||
|
||||
for (x=237; x<this.info.length; ++x) { // fill inactive segment with delete codes
|
||||
this.formatBand[6][x] = 3;
|
||||
}
|
||||
|
||||
this.doc = null;
|
||||
this.window = null;
|
||||
this.hopperBar = null;
|
||||
this.outHopperFrame = null;
|
||||
this.outHopper = null;
|
||||
@ -63,12 +68,12 @@ function B220CardatronInput(mnemonic, unitIndex, config) {
|
||||
this.formatColumnList = null;
|
||||
this.formatSelect = 0; // current format selection
|
||||
this.formatSelectList = null;
|
||||
this.window = window.open("../webUI/B220CardatronInput.html", mnemonic,
|
||||
|
||||
B220Util.openPopup(window, "../webUI/B220CardatronInput.html", mnemonic,
|
||||
"location=no,scrollbars,resizable,width=" + w + ",height=" + h +
|
||||
",left=" + ((unitIndex-1)*32) +
|
||||
",top=" + (screen.availHeight - h - (unitIndex-1)*32));
|
||||
this.window.addEventListener("load",
|
||||
B220CardatronInput.prototype.readerOnLoad.bind(this), false);
|
||||
",left=" + ((unitIndex-1)*32) +
|
||||
",top=" + (screen.availHeight - h - (unitIndex-1)*32),
|
||||
this, B220CardatronInput.prototype.readerOnLoad);
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
@ -119,6 +124,7 @@ B220CardatronInput.prototype.clear = function clear() {
|
||||
this.ready = false; // ready status
|
||||
this.bufferReady = false; // buffer drum info band is ready to send data to Processor
|
||||
this.noFormatAlarm = false; // No Formal Alarm toggle
|
||||
this.noReload = false; // Reload/Format Lockout was set on last op or card
|
||||
this.reloadLockout = false; // Reload Lockout toggle
|
||||
this.formatLockout = false; // Format Lockout toggle
|
||||
this.readRequested = false; // Processor has initiated a read, waiting for buffer
|
||||
@ -282,6 +288,7 @@ B220CardatronInput.prototype.CIHopperBar_onClick = function CIHopperBar_onClick(
|
||||
this.bufLength = 0;
|
||||
this.bufIndex = 0;
|
||||
this.hopperBar.value = 0;
|
||||
this.clearUnit();
|
||||
this.$$("CIFileSelector").value = null; // reset the control
|
||||
while (this.outHopper.childNodes.length > 0) {
|
||||
this.outHopper.removeChild(this.outHopper.firstChild);
|
||||
@ -439,33 +446,40 @@ B220CardatronInput.prototype.determineFormatBand = function determineFormatBand(
|
||||
break;
|
||||
case "`": // 1-8 punch
|
||||
format = 1;
|
||||
this.noReload = true;
|
||||
this.setFormatLockout(true);
|
||||
break;
|
||||
case ":": // 2-8 punch
|
||||
format = 2;
|
||||
this.noReload = true;
|
||||
this.setFormatLockout(true);
|
||||
break;
|
||||
case "#": // 3-8 punch
|
||||
format = 3;
|
||||
this.noReload = true;
|
||||
this.setFormatLockout(true);
|
||||
break;
|
||||
case "@": // 4-8 punch
|
||||
format = 4;
|
||||
this.noReload = true;
|
||||
this.setFormatLockout(true);
|
||||
break;
|
||||
case "'": // 5-8 punch
|
||||
case "|": // translates to a 5-numeric digit
|
||||
format = 5;
|
||||
this.noReload = true;
|
||||
this.setFormatLockout(true);
|
||||
break;
|
||||
case "=": // 6-8 punch
|
||||
case "}": // translates to a 6-numeric digit
|
||||
format = 6;
|
||||
this.noReload = true;
|
||||
this.setFormatLockout(true);
|
||||
break;
|
||||
case "\"": // 7-8 punch -- reject plus lockout
|
||||
case "~": // translates to a 7-numeric digit
|
||||
format = 7+8;
|
||||
this.noReload = true;
|
||||
this.setFormatLockout(true);
|
||||
break;
|
||||
default:
|
||||
@ -573,13 +587,14 @@ B220CardatronInput.prototype.beforeUnload = function beforeUnload(ev) {
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220CardatronInput.prototype.readerOnLoad = function readerOnLoad() {
|
||||
B220CardatronInput.prototype.readerOnLoad = function readerOnLoad(ev) {
|
||||
/* Initializes the reader window and user interface */
|
||||
var body;
|
||||
var de;
|
||||
var prefs = this.config.getNode("Cardatron.units", this.unitIndex);
|
||||
|
||||
this.doc = this.window.document;
|
||||
this.doc = ev.target;
|
||||
this.window = this.doc.defaultView;
|
||||
de = this.doc.documentElement;
|
||||
this.doc.title = "retro-220 Cardatron Reader " + this.mnemonic;
|
||||
|
||||
@ -742,7 +757,8 @@ B220CardatronInput.prototype.inputStop = function inputStop() {
|
||||
/* Terminates data transfer from the input unit and releases the card */
|
||||
|
||||
this.setFormatSelectLamps(0);
|
||||
if (this.rDigit % 2) { // set reload-lockout
|
||||
if (this.noReload) { // set reload-lockout
|
||||
this.noReload = false;
|
||||
if (!this.reloadLockout) {
|
||||
this.setReloadLockout(true);
|
||||
}
|
||||
@ -785,6 +801,7 @@ B220CardatronInput.prototype.inputInitiate = function inputInitiate(rDigit, word
|
||||
}
|
||||
} else {
|
||||
this.rDigit = rDigit;
|
||||
this.noReload |= (rDigit%2 == 1);
|
||||
this.infoIndex = 0; // start at the beginning of the info band
|
||||
this.digitCount = 0;
|
||||
this.pendingInputWord = 0;
|
||||
@ -831,7 +848,16 @@ B220CardatronInput.prototype.inputFormatTransfer = function inputFormatTransfer(
|
||||
|
||||
this.pendingFinish(); // call signalFinished();
|
||||
this.pendingFinish = null;
|
||||
this.inputStop();
|
||||
this.setFormatSelectLamps(0);
|
||||
if (this.noReload) { // set reload-lockout
|
||||
this.noReload = false;
|
||||
if (!this.reloadLockout) {
|
||||
this.setReloadLockout(true);
|
||||
}
|
||||
} else if (this.reloadLockout) { // reset reload-lockout
|
||||
this.setReloadLockout(false);
|
||||
this.initiateCardRead();
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
@ -849,6 +875,7 @@ B220CardatronInput.prototype.inputFormatInitiate = function inputFormatInitiate(
|
||||
signalFinished();
|
||||
} else {
|
||||
this.rDigit = rDigit;
|
||||
this.noReload |= (rDigit%2 == 1);
|
||||
this.selectedFormat = ((rDigit >>> 1) & 0x07) + 1;
|
||||
this.pendingFinish = signalFinished; // stash the call-back function
|
||||
this.setFormatSelectLamps(this.selectedFormat);
|
||||
@ -872,7 +899,7 @@ B220CardatronInput.prototype.clearUnit = function clearUnit() {
|
||||
|
||||
// If there is a pending read, confirm that this.pendingParams[1] is a
|
||||
// function and call it with the end-of-data signal. We assume it's the
|
||||
// Processor's wordReceiver function. This will prevent the Processor
|
||||
// Processor's wordReceiver function. This will prevent the Processor
|
||||
// from hanging on an I/O to a cleared input unit.
|
||||
if (this.readRequested) {
|
||||
if (Object.prototype.toString.call(this.pendingParams) === "[object Array]") {
|
||||
|
||||
@ -59,18 +59,19 @@ function B220CardatronOutput(mnemonic, unitIndex, config) {
|
||||
|
||||
// Device window
|
||||
this.doc = null;
|
||||
this.window = null;
|
||||
this.barGroup = null; // current greenbar line group
|
||||
this.supplyDoc = null; // the content document for the supply frame
|
||||
this.supply = null; // the "paper" or "cards" we print/punch on
|
||||
this.endOfSupply = null; // dummy element used to control scrolling
|
||||
this.supplyMeter = null; // <meter> element showing amount of paper/card supply remaining
|
||||
w = (this.isPrinter ? 790 : 608);
|
||||
this.window = window.open("../webUI/B220CardatronOutput.html", mnemonic,
|
||||
|
||||
B220Util.openPopup(window, "../webUI/B220CardatronOutput.html", mnemonic,
|
||||
"location=no,scrollbars,resizable,width=" + w + ",height=" + h +
|
||||
",left=" + (screen.availWidth - w) +
|
||||
",top=" + (screen.availHeight - h - (unitIndex-3)*32));
|
||||
this.window.addEventListener("load",
|
||||
B220CardatronOutput.prototype.deviceOnLoad.bind(this), false);
|
||||
",left=" + (screen.availWidth - w) +
|
||||
",top=" + (screen.availHeight - h - (unitIndex-3)*32),
|
||||
this, B220CardatronOutput.prototype.deviceOnLoad);
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
@ -93,8 +94,8 @@ B220CardatronOutput.prototype.outputXlate = [
|
||||
[0x2D,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x20,0x24,0x2A], // zone digit 2
|
||||
[0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20], // zone digit 3
|
||||
[0x30,0x2F,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x20,0x2C,0x25], // zone digit 4
|
||||
[0x40,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20], // zone digit 5
|
||||
[0x2D,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20], // zone digit 6
|
||||
[0x26,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x20,0x2E,0xA4], // zone digit 5
|
||||
[0x2D,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x20,0x24,0x2A], // zone digit 6
|
||||
[0x20,0x20,0x39,0x2E,0xA4,0xA4,0x2E,0xA4,0x20,0x20,0x20,0x2E,0xA4], // zone digit 7
|
||||
[0x20,0x4A,0x49,0x24,0x2A,0x2A,0x24,0x2A,0x20,0x20,0x20,0x24,0x2A], // zone digit 8
|
||||
[0x20,0x20,0x52,0x27,0x25,0x25,0x2C,0x25,0x20,0x20,0x20,0x27,0x25], // zone digit 9
|
||||
@ -102,9 +103,9 @@ B220CardatronOutput.prototype.outputXlate = [
|
||||
[0x20,0x26,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20], // zone digit 11
|
||||
[0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20]]; // zone digit 12
|
||||
|
||||
// Translate buffer zone digits to internal zone decades.
|
||||
// Each row is indexed by the zone digit from the buffer drum info band;
|
||||
// each column is indexed by the PREVIOUS numeric digit from the info band.
|
||||
// Translate internal zone decades to buffer zone digits.
|
||||
// Each row is indexed by the zone digit from the internal character code;
|
||||
// each column is indexed by the PREVIOUS numeric digit from the character code.
|
||||
// See U.S. Patent 3,072,328, January 8, 1963, L.L. Bewley et al, Figure 12;
|
||||
// and ElectroData Technical Newsletter #5 of February 14, 1958.
|
||||
B220CardatronOutput.prototype.zoneXlate = [ // numeric digit:0 1 2 3 4 5 6 7 8 9
|
||||
@ -157,7 +158,7 @@ B220CardatronOutput.prototype.clear = function clear() {
|
||||
this.supplyLeft = this.maxSupplyLines; // lines/cards remaining in output supply
|
||||
this.runoutSupplyCount = 0; // counter for triple-formfeed => rip paper/empty hopper
|
||||
this.groupLinesLeft = 0; // lines remaining in current greenbar group
|
||||
this.topOfForm = false; // start new page flag
|
||||
this.atTopOfForm = false; // start new page flag
|
||||
this.pendingSpaceBefore = -1; // pending carriage control (eat the initial space-before)
|
||||
|
||||
this.pendingCall = null; // stashed pending function reference
|
||||
@ -244,22 +245,22 @@ B220CardatronOutput.prototype.copySupply = function copySupply(ev) {
|
||||
var barGroup = this.supply.firstChild;
|
||||
var text = "";
|
||||
var title = "B220 " + this.mnemonic + " Text Snapshot";
|
||||
var win = window.open("./B220FramePaper.html", this.mnemonic + "-Snapshot",
|
||||
"scrollbars,resizable,width=500,height=500");
|
||||
|
||||
while (barGroup) {
|
||||
text += barGroup.textContent + "\n";
|
||||
barGroup = barGroup.nextSibling;
|
||||
}
|
||||
|
||||
win.moveTo((screen.availWidth-win.outerWidth)/2, (screen.availHeight-win.outerHeight)/2);
|
||||
win.addEventListener("load", function() {
|
||||
var doc;
|
||||
B220Util.openPopup(this.window, "./B220FramePaper.html", this.mnemonic + "-Snapshot",
|
||||
"scrollbars,resizable,width=500,height=500",
|
||||
this, function(ev) {
|
||||
var doc = ev.target;
|
||||
var win = doc.defaultView;
|
||||
|
||||
doc = win.document;
|
||||
doc.title = title;
|
||||
win.moveTo((screen.availWidth-win.outerWidth)/2, (screen.availHeight-win.outerHeight)/2);
|
||||
doc.getElementById("Paper").textContent = text;
|
||||
}, false);
|
||||
});
|
||||
|
||||
this.runoutSupply();
|
||||
ev.preventDefault();
|
||||
@ -303,30 +304,36 @@ B220CardatronOutput.prototype.appendLine = function appendLine(text) {
|
||||
--this.groupLinesLeft;
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220CardatronOutput.prototype.skipToChannel = function skipToChannel() {
|
||||
/* Finishes the current page and sets up for top-of-form formatting on the
|
||||
next line printed. Adjusts the supply of forms left */
|
||||
var lines = 0;
|
||||
|
||||
while(this.groupLinesLeft > 0) {
|
||||
++lines;
|
||||
this.appendLine("\xA0");
|
||||
}
|
||||
|
||||
this.atTopOfForm = true;
|
||||
this.supplyMeter.value = this.supplyLeft -= lines;
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220CardatronOutput.prototype.printLine = function printLine(text, spaceBefore) {
|
||||
/* Prints one line to the output, handling carriage control and greenbar
|
||||
group completion. For now, SPACE 0 (overprinting) is treated as single-spacing */
|
||||
var lines = 0;
|
||||
var lines = spaceBefore;
|
||||
|
||||
if (spaceBefore < 0) { // skip to channel 1
|
||||
while(this.groupLinesLeft > 0) {
|
||||
++lines;
|
||||
this.appendLine("\xA0");
|
||||
}
|
||||
this.atTopOfForm = true;
|
||||
} else { // space before print
|
||||
lines = spaceBefore;
|
||||
while (lines > 1) {
|
||||
--lines;
|
||||
--this.supplyLeft;
|
||||
this.appendLine("\xA0");
|
||||
}
|
||||
while (lines > 1) { // space before print
|
||||
--lines;
|
||||
--this.supplyLeft;
|
||||
this.appendLine("\xA0");
|
||||
}
|
||||
|
||||
this.appendLine(text || "\xA0");
|
||||
if (this.supplyLeft > 0) {
|
||||
this.supplyMeter.value = this.supplyLeft -= lines;
|
||||
this.supplyMeter.value = this.supplyLeft -= 1;
|
||||
} else {
|
||||
this.setDeviceReady(false);
|
||||
B220Util.addClass(this.$$("COEndOfSupplyBtn"), "redLit");
|
||||
@ -433,7 +440,8 @@ B220CardatronOutput.prototype.initiateWrite = function initiateWrite() {
|
||||
case 1: // Relay 1 (eject page after printing)
|
||||
case 9: // same as 1
|
||||
this.printLine(line, this.pendingSpaceBefore);
|
||||
this.pendingSpaceBefore = -99;
|
||||
this.skipToChannel();
|
||||
this.pendingSpaceBefore = 0;
|
||||
break;
|
||||
case 2: // Relay 2 (single space before and after printing)
|
||||
this.printLine(line, this.pendingSpaceBefore+1);
|
||||
@ -442,7 +450,8 @@ B220CardatronOutput.prototype.initiateWrite = function initiateWrite() {
|
||||
case 3: // Relay 3 (eject page before printing)
|
||||
case 5: // Relay 5 (skip to channel 2 before printing)
|
||||
case 7: // Relay 3+5 (skip to channel 3 before printing)
|
||||
this.printLine(line, -1);
|
||||
this.skipToChannel();
|
||||
this.printLine(line, 0);
|
||||
this.pendingSpaceBefore = 0;
|
||||
break;
|
||||
case 4: // Relay 4 (double space before printing)
|
||||
@ -627,11 +636,9 @@ B220CardatronOutput.prototype.parseZeroSuppressList = function parseZeroSuppress
|
||||
B220CardatronOutput.prototype.COSetZSBtn_onClick = function COSetZSBtn_onClick(ev) {
|
||||
/* Displays the Zero Suppress Panel window to capture a list of column numbers */
|
||||
var $$$ = null; // getElementById shortcut for loader window
|
||||
var doc = null; // loader window.document
|
||||
var doc = null; // zero-suppress window.document
|
||||
var tron = this; // this B220CardatronOutput device instance
|
||||
var win = this.window.open("B220CardatronZeroSuppressPanel.html", this.mnemonic + "ZS",
|
||||
"location=no,scrollbars=no,resizable,width=508,height=120,left=" +
|
||||
(this.window.screenX+16) +",top=" + (this.window.screenY+16));
|
||||
var win = null; // zero-suppress window defaultView
|
||||
|
||||
function zsOK(ev) {
|
||||
/* Handler for the OK button. Parses the list of column numbers; if successful,
|
||||
@ -660,7 +667,9 @@ B220CardatronOutput.prototype.COSetZSBtn_onClick = function COSetZSBtn_onClick(e
|
||||
/* Driver for the tape loader window */
|
||||
var de;
|
||||
|
||||
doc = win.document;
|
||||
doc = ev.target;
|
||||
win = doc.defaultView;
|
||||
this.zsWindow = win;
|
||||
doc.title = "retro-220 " + tron.mnemonic + " Zero-Suppress Panel";
|
||||
de = doc.documentElement;
|
||||
$$$ = function $$$(id) {
|
||||
@ -676,17 +685,20 @@ B220CardatronOutput.prototype.COSetZSBtn_onClick = function COSetZSBtn_onClick(e
|
||||
win.resizeBy(de.scrollWidth - win.innerWidth,
|
||||
de.scrollHeight - win.innerHeight);
|
||||
$$$("COZSColumnList").focus();
|
||||
win.addEventListener("unload", function zsUnload(ev) {
|
||||
this.zsWindow = null;
|
||||
}, false);
|
||||
}
|
||||
|
||||
// Outer block of COSetZSBtn_onClick
|
||||
if (this.zsWindow && !this.zsWindow.closed) {
|
||||
this.zsWindow.close();
|
||||
}
|
||||
this.zsWindow = win;
|
||||
win.addEventListener("load", zsOnload, false);
|
||||
win.addEventListener("unload", function zsUnload(ev) {
|
||||
this.zsWindow = null;
|
||||
}, false);
|
||||
|
||||
B220Util.openPopup(this.window, "B220CardatronZeroSuppressPanel.html", this.mnemonic + "ZS",
|
||||
"location=no,scrollbars=no,resizable,width=508,height=120,left=" +
|
||||
(this.window.screenX+16) +",top=" + (this.window.screenY+16),
|
||||
this, zsOnload);
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
@ -700,7 +712,7 @@ B220CardatronOutput.prototype.beforeUnload = function beforeUnload(ev) {
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220CardatronOutput.prototype.deviceOnLoad = function deviceOnLoad() {
|
||||
B220CardatronOutput.prototype.deviceOnLoad = function deviceOnLoad(ev) {
|
||||
/* Initializes the printer/punch window and user interface */
|
||||
var body;
|
||||
var de;
|
||||
@ -708,7 +720,8 @@ B220CardatronOutput.prototype.deviceOnLoad = function deviceOnLoad() {
|
||||
var prefs = this.config.getNode("Cardatron.units", this.unitIndex);
|
||||
var zsCol;
|
||||
|
||||
this.doc = this.window.document;
|
||||
this.doc = ev.target;
|
||||
this.window = this.doc.defaultView;
|
||||
de = this.doc.documentElement;
|
||||
this.doc.title = "retro-220 Cardatron " +
|
||||
(this.isPrinter ? "Printer " : "Punch ") + this.mnemonic;
|
||||
@ -841,11 +854,13 @@ B220CardatronOutput.prototype.outputWord = function outputWord(requestNextWord)
|
||||
nu = true; // next is a numeric digit
|
||||
if (x > 9) {
|
||||
// For a zone digit in the sign position, store a 5 (+) or 6 (-)
|
||||
// so that the sign will be printed/punched as a zone 11/12.
|
||||
if (d == 0 && this.suppress12Mode) {
|
||||
// so that the sign will be printed/punched as a zone 11/12, UNLESS
|
||||
// the sign is positive and Suppress-12 mode is in effect. In that
|
||||
// case, store a zero to the zone so the sign will not print/punch.
|
||||
if (d%2 == 0 && this.suppress12Mode) {
|
||||
info[ix] = 0; // suppress the 12-zone output
|
||||
} else {
|
||||
info[ix] = (d & 0x01) + 5;
|
||||
info[ix] = d%2 + 5;
|
||||
}
|
||||
} else if (d > 3) {
|
||||
info[ix] = this.zoneXlate[d][lastNumeric];
|
||||
|
||||
@ -25,7 +25,6 @@ function B220ConsoleKeyboard(p) {
|
||||
|
||||
this.boundKeypress = B220ConsoleKeyboard.prototype.keypress.bind(this);
|
||||
this.boundButton_Click = B220ConsoleKeyboard.prototype.button_Click.bind(this);
|
||||
this.boundKeyboard_OnLoad = B220ConsoleKeyboard.prototype.keyboardOnLoad.bind(this);
|
||||
this.boundKeyboard_Unload = B220ConsoleKeyboard.prototype.keyboardUnload.bind(this);
|
||||
|
||||
this.clear();
|
||||
@ -188,10 +187,10 @@ B220ConsoleKeyboard.prototype.keyboardOpen = function keyboardOpen() {
|
||||
var w = 240;
|
||||
|
||||
if (!this.window) {
|
||||
this.window = window.open("../webUI/B220ConsoleKeyboard.html", this.mnemonic,
|
||||
B220Util.openPopup(window, "../webUI/B220ConsoleKeyboard.html", this.mnemonic,
|
||||
"resizable,width=" + w + ",height=" + h +
|
||||
",left=" + (screen.availWidth - w) + ",top=" + (screen.availHeight - h));
|
||||
this.window.addEventListener("load", this.boundKeyboard_OnLoad, false);
|
||||
",left=" + (screen.availWidth - w) + ",top=" + (screen.availHeight - h),
|
||||
this, B220ConsoleKeyboard.prototype.keyboardOnLoad);
|
||||
}
|
||||
};
|
||||
|
||||
@ -207,13 +206,13 @@ B220ConsoleKeyboard.prototype.keyboardUnload = function keyboardUnload(ev) {
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220ConsoleKeyboard.prototype.keyboardOnLoad = function keyboardOnLoad() {
|
||||
B220ConsoleKeyboard.prototype.keyboardOnLoad = function keyboardOnLoad(ev) {
|
||||
/* Initializes the Control Console window and user interface */
|
||||
var body;
|
||||
var de;
|
||||
|
||||
this.window.removeEventListener("load", this.boundKeyboard_OnLoad, false);
|
||||
this.doc = this.window.document;
|
||||
this.doc = ev.target;
|
||||
this.window = this.doc.defaultView;
|
||||
body = this.$$("KeyboardCase");
|
||||
de = this.doc.documentElement;
|
||||
|
||||
@ -237,7 +236,7 @@ B220ConsoleKeyboard.prototype.keyboardOnLoad = function keyboardOnLoad() {
|
||||
|
||||
// Kludge for Chrome window.outerWidth/Height timing bug
|
||||
setCallback(null, this, 100, function chromeBug() {
|
||||
this.window.moveTo(screen.availWidth-this.window.outerWidth,
|
||||
this.window.moveTo(screen.availWidth - this.window.outerWidth,
|
||||
screen.availHeight - this.window.outerHeight);
|
||||
});
|
||||
};
|
||||
|
||||
@ -49,11 +49,10 @@ function B220ConsolePrinter(mnemonic, unitIndex, config) {
|
||||
this.printerEOP = null;
|
||||
this.printerLine = 0;
|
||||
this.printerCol = 0;
|
||||
this.window = window.open("../webUI/B220ConsolePrinter.html", mnemonic,
|
||||
B220Util.openPopup(window, "../webUI/B220ConsolePrinter.html", mnemonic,
|
||||
"location=no,scrollbars=no,resizable,width=640,height=240," +
|
||||
"left=" + left + ",top=" + top);
|
||||
this.window.addEventListener("load",
|
||||
B220ConsolePrinter.prototype.printerOnLoad.bind(this), false);
|
||||
"left=" + left + ",top=" + top,
|
||||
this, B220ConsolePrinter.prototype.printerOnLoad);
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
@ -210,17 +209,17 @@ B220ConsolePrinter.prototype.copyPaper = function copyPaper(ev) {
|
||||
or saved by the user */
|
||||
var text = this.paper.textContent;
|
||||
var title = "B220 " + this.mnemonic + " Text Snapshot";
|
||||
var win = window.open("./B220FramePaper.html", "TTY-Snapshot",
|
||||
"scrollbars,resizable,width=500,height=500");
|
||||
|
||||
win.moveTo((screen.availWidth-win.outerWidth)/2, (screen.availHeight-win.outerHeight)/2);
|
||||
win.addEventListener("load", function() {
|
||||
var doc;
|
||||
B220Util.openPopup(this.window, "./B220FramePaper.html", this.mnemonic + "-Snapshot",
|
||||
"scrollbars,resizable,width=500,height=500",
|
||||
this, function(ev) {
|
||||
var doc = ev.target;
|
||||
var win = doc.defaultView;
|
||||
|
||||
doc = win.document;
|
||||
doc.title = title;
|
||||
win.moveTo((screen.availWidth-win.outerWidth)/2, (screen.availHeight-win.outerHeight)/2);
|
||||
doc.getElementById("Paper").textContent = text;
|
||||
}, false);
|
||||
});
|
||||
|
||||
this.emptyPaper();
|
||||
this.emptyLine();
|
||||
@ -381,7 +380,7 @@ B220ConsolePrinter.prototype.parseTabStops = function parsetabStops(text, alertW
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220ConsolePrinter.prototype.printerOnLoad = function printerOnLoad() {
|
||||
B220ConsolePrinter.prototype.printerOnLoad = function printerOnLoad(ev) {
|
||||
/* Initializes the Teletype printer window and user interface */
|
||||
var body;
|
||||
var id;
|
||||
@ -390,7 +389,8 @@ B220ConsolePrinter.prototype.printerOnLoad = function printerOnLoad() {
|
||||
var tabStop;
|
||||
var x;
|
||||
|
||||
this.doc = this.window.document;
|
||||
this.doc = ev.target;
|
||||
this.window = this.doc.defaultView;
|
||||
this.doc.title = "retro-220 Printer - " + this.mnemonic;
|
||||
this.paper = this.$$("Paper");
|
||||
this.printerEOP = this.$$("EndOfPaper");
|
||||
|
||||
@ -95,11 +95,11 @@ function B220ControlConsole(p, systemShutdown) {
|
||||
|
||||
// Create the Console window
|
||||
this.doc = null;
|
||||
this.window = window.open("../webUI/B220ControlConsole.html", mnemonic,
|
||||
this.window = null;
|
||||
B220Util.openPopup(window, "../webUI/B220ControlConsole.html", mnemonic,
|
||||
"location=no,scrollbars,resizable,width=" + w + ",height=" + h +
|
||||
",top=0,left=" + (screen.availWidth - w));
|
||||
this.window.addEventListener("load",
|
||||
B220ControlConsole.prototype.consoleOnLoad.bind(this), false);
|
||||
",top=0,left=" + (screen.availWidth - w),
|
||||
this, B220ControlConsole.prototype.consoleOnLoad);
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
@ -172,12 +172,11 @@ B220ControlConsole.prototype.beforeUnload = function beforeUnload(ev) {
|
||||
B220ControlConsole.prototype.meatballMemdump = function meatballMemdump() {
|
||||
/* Opens a temporary window and formats the current processor and memory
|
||||
state to it */
|
||||
var doc = null; // loader window.document
|
||||
var doc = null; // dump window.document
|
||||
var p = this.p; // local copy of Processor object
|
||||
var paper = null; // <pre> element to receive dump lines
|
||||
var trimRightRex = /[\s\uFEFF\xA0]+$/;
|
||||
var win = this.window.open("./B220FramePaper.html", this.mnemonic + "-MEMDUMP",
|
||||
"location=no,scrollbars=yes,resizable,width=800,height=600");
|
||||
var win = null; // dump window
|
||||
var xlate = B220ControlConsole.codeXlate; // local copy
|
||||
|
||||
function formatWord(w) {
|
||||
@ -378,22 +377,24 @@ B220ControlConsole.prototype.meatballMemdump = function meatballMemdump() {
|
||||
writer("End dump, memory size: " + (top+1).toString() + " words");
|
||||
}
|
||||
|
||||
function memdumpSetup() {
|
||||
function memdumpSetup(ev) {
|
||||
/* Loads a status message into the "paper" rendering area, then calls
|
||||
dumpDriver after a short wait to allow the message to appear */
|
||||
|
||||
win.removeEventListener("load", memdumpSetup, false);
|
||||
doc = win.document;
|
||||
doc = ev.target;
|
||||
win = doc.defaultView
|
||||
doc.title = "retro-220 Console: Meatball Memdump";
|
||||
win.moveTo((screen.availWidth-win.outerWidth)/2, (screen.availHeight-win.outerHeight)/2);
|
||||
paper = doc.getElementById("Paper");
|
||||
writer("Rendering the dump... please wait...");
|
||||
setTimeout(memdumpDriver, 50);
|
||||
win.focus();
|
||||
}
|
||||
|
||||
// Outer block of meatBallMemdump
|
||||
win.moveTo((screen.availWidth-win.outerWidth)/2, (screen.availHeight-win.outerHeight)/2);
|
||||
win.focus();
|
||||
win.addEventListener("load", memdumpSetup, false);
|
||||
B220Util.openPopup(this.window, "./B220FramePaper.html", this.mnemonic + "-MEMDUMP",
|
||||
"location=no,scrollbars=yes,resizable,width=800,height=600",
|
||||
this, memdumpSetup);
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
@ -789,7 +790,7 @@ B220ControlConsole.prototype.switch_Click = function switch_Click(ev) {
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220ControlConsole.prototype.consoleOnLoad = function consoleOnLoad() {
|
||||
B220ControlConsole.prototype.consoleOnLoad = function consoleOnLoad(ev) {
|
||||
/* Initializes the Supervisory Panel window and user interface */
|
||||
var body;
|
||||
var p = this.p; // local copy of processor object
|
||||
@ -797,7 +798,8 @@ B220ControlConsole.prototype.consoleOnLoad = function consoleOnLoad() {
|
||||
var prefs = this.config.getNode("ControlConsole");
|
||||
var x;
|
||||
|
||||
this.doc = this.window.document;
|
||||
this.doc = ev.target;
|
||||
this.window = this.doc.defaultView;
|
||||
body = this.$$("PanelSurface");
|
||||
|
||||
this.intervalTimer = this.$$("IntervalTimer");
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
function B220MagTapeControl(p) {
|
||||
/* Constructor for the MagTapeControl object */
|
||||
var left = 0; // control window left position
|
||||
var top = 412; // control window top-from-bottom position
|
||||
var top = 432; // control window top-from-bottom position
|
||||
var u; // unit configuration object
|
||||
var x; // unit index
|
||||
|
||||
@ -28,11 +28,11 @@ function B220MagTapeControl(p) {
|
||||
// Do not call this.clear() here -- call this.clearUnit() from onLoad instead
|
||||
|
||||
this.doc = null;
|
||||
this.window = window.open("../webUI/B220MagTapeControl.html", this.mnemonic,
|
||||
this.window = null;
|
||||
B220Util.openPopup(window, "../webUI/B220MagTapeControl.html", this.mnemonic,
|
||||
"location=no,scrollbars=no,resizable,width=712,height=144,top=" +
|
||||
(screen.availHeight - top) + ",left=" + left);
|
||||
this.window.addEventListener("load",
|
||||
B220MagTapeControl.prototype.magTapeOnLoad.bind(this), false);
|
||||
(screen.availHeight - top) + ",left=" + left,
|
||||
this, B220MagTapeControl.prototype.magTapeOnLoad);
|
||||
|
||||
this.boundReleaseControl = B220MagTapeControl.prototype.releaseControl.bind(this);
|
||||
this.boundCancelIO = B220MagTapeControl.prototype.cancelIO.bind(this);
|
||||
@ -212,7 +212,7 @@ B220MagTapeControl.prototype.findDesignate = function findDesignate(u) {
|
||||
var unit;
|
||||
var x;
|
||||
|
||||
for (x=this.tapeUnit.length-1; x>=0; --x) {
|
||||
for (x=this.tapeUnit.length-1; x>0; --x) {
|
||||
unit = this.tapeUnit[x];
|
||||
if (unit && unit.ready) {
|
||||
if (unit.unitDesignate == u) {
|
||||
@ -523,14 +523,15 @@ B220MagTapeControl.prototype.beforeUnload = function beforeUnload(ev) {
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220MagTapeControl.prototype.magTapeOnLoad = function magTapeOnLoad() {
|
||||
B220MagTapeControl.prototype.magTapeOnLoad = function magTapeOnLoad(ev) {
|
||||
/* Initializes the MagTape Control window and user interface */
|
||||
var body;
|
||||
var box;
|
||||
var e;
|
||||
var x;
|
||||
|
||||
this.doc = this.window.document;
|
||||
this.doc = ev.target;
|
||||
this.window = this.doc.defaultView;
|
||||
body = this.$$("PanelSurface");
|
||||
|
||||
// Misc Register
|
||||
@ -656,7 +657,7 @@ B220MagTapeControl.prototype.scan = function scan(dReg, bReg) {
|
||||
this.releaseControl();
|
||||
} else {
|
||||
// Start the scan after changing lane, as appropriate
|
||||
this.T = searchWord;
|
||||
this.T = searchWord%0x10000000000;
|
||||
this.regT.update(this.T);
|
||||
this.releaseProcessor(false, 0);
|
||||
this.TFLamp.set(1);
|
||||
@ -773,7 +774,7 @@ B220MagTapeControl.prototype.search = function search(dReg, bReg) {
|
||||
this.releaseControl();
|
||||
} else {
|
||||
// Start the search after changing lane, as appropriate
|
||||
this.T = searchWord;
|
||||
this.T = searchWord%0x10000000000;
|
||||
this.regT.update(this.T);
|
||||
this.releaseProcessor(false, 0);
|
||||
this.TFLamp.set(1);
|
||||
|
||||
@ -141,10 +141,10 @@ function B220MagTapeDrive(mnemonic, unitIndex, tcu, config) {
|
||||
this.boundStartUpForward = B220MagTapeDrive.prototype.startUpForward.bind(this);
|
||||
|
||||
this.doc = null;
|
||||
this.window = window.open("../webUI/B220MagTapeDrive.html", mnemonic,
|
||||
"location=no,scrollbars=no,resizable,width=384,height=184,left=0,top=" + y);
|
||||
this.window.addEventListener("load",
|
||||
B220MagTapeDrive.prototype.tapeDriveOnload.bind(this), false);
|
||||
this.window = null;
|
||||
B220Util.openPopup(window, "../webUI/B220MagTapeDrive.html", mnemonic,
|
||||
"location=no,scrollbars=no,resizable,width=384,height=184,left=0,top=" + y,
|
||||
this, B220MagTapeDrive.prototype.tapeDriveOnload);
|
||||
}
|
||||
|
||||
// this.tapeState enumerations
|
||||
@ -554,9 +554,7 @@ B220MagTapeDrive.prototype.loadTape = function loadTape() {
|
||||
var file = null; // FileReader instance
|
||||
var fileSelect = null; // file picker element
|
||||
var mt = this; // this B220MagTapeDrive instance
|
||||
var win = this.window.open("B220MagTapeLoadPanel.html", this.mnemonic + "Load",
|
||||
"location=no,scrollbars=no,resizable,width=508,height=112,left=" +
|
||||
(this.window.screenX+16) +",top=" + (this.window.screenY+16));
|
||||
var win = null; // loader window
|
||||
|
||||
function fileSelector_onChange(ev) {
|
||||
/* Handle the <input type=file> onchange event when a file is selected */
|
||||
@ -891,14 +889,16 @@ B220MagTapeDrive.prototype.loadTape = function loadTape() {
|
||||
/* Driver for the tape loader window */
|
||||
var de;
|
||||
|
||||
doc = win.document;
|
||||
doc = ev.target;
|
||||
win = doc.defaultView;
|
||||
doc.title = "retro-220 " + mt.mnemonic + " Tape Loader";
|
||||
this.loadWindow = win;
|
||||
de = doc.documentElement;
|
||||
$$$ = function $$$(id) {
|
||||
return doc.getElementById(id);
|
||||
};
|
||||
|
||||
win.removeEventListener("load", tapeLoadOnload, false);
|
||||
win.addEventListener("unload", tapeLoadUnload, false);
|
||||
|
||||
fileSelect = $$$("MTLoadFileSelector");
|
||||
fileSelect.addEventListener("change", fileSelector_onChange, false);
|
||||
@ -921,20 +921,21 @@ B220MagTapeDrive.prototype.loadTape = function loadTape() {
|
||||
if (this.loadWindow && !this.loadWindow.closed) {
|
||||
this.loadWindow.close();
|
||||
}
|
||||
this.loadWindow = win;
|
||||
win.addEventListener("load", tapeLoadOnload, false);
|
||||
win.addEventListener("unload", tapeLoadUnload, false);
|
||||
|
||||
B220Util.openPopup(this.window, "B220MagTapeLoadPanel.html", this.mnemonic + "Load",
|
||||
"location=no,scrollbars=no,resizable,width=508,height=112,left=" +
|
||||
(this.window.screenX+16) +",top=" + (this.window.screenY+16),
|
||||
this, tapeLoadOnload);
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220MagTapeDrive.prototype.unloadTape = function unloadTape() {
|
||||
/* Reformats the tape image data as ASCII text and displays it in a new
|
||||
window so the user can save or copy/paste it elsewhere */
|
||||
var doc = null; // loader window.document
|
||||
var doc = null; // unloader window.document
|
||||
var image; // <pre> element to receive tape image data
|
||||
var mt = this; // tape drive object
|
||||
var win = this.window.open("./B220FramePaper.html", this.mnemonic + "-Unload",
|
||||
"location=no,scrollbars=yes,resizable,width=800,height=600");
|
||||
var win = null; // unloader window
|
||||
|
||||
function findBlockStart() {
|
||||
/* Searches forward in the tape image on the currently-selected lane for the
|
||||
@ -1071,23 +1072,25 @@ B220MagTapeDrive.prototype.unloadTape = function unloadTape() {
|
||||
mt.setTapeUnloaded();
|
||||
}
|
||||
|
||||
function unloadSetup() {
|
||||
function unloadSetup(ev) {
|
||||
/* Loads a status message into the "paper" rendering area, then calls
|
||||
unloadDriver after a short wait to allow the message to appear */
|
||||
|
||||
win.removeEventListener("load", unloadSetup, false);
|
||||
doc = win.document;
|
||||
doc = ev.target;
|
||||
win = doc.defaultView;
|
||||
doc.title = "retro-220 " + mt.mnemonic + " Unload Tape";
|
||||
win.moveTo((screen.availWidth-win.outerWidth)/2, (screen.availHeight-win.outerHeight)/2);
|
||||
image = doc.getElementById("Paper");
|
||||
image.appendChild(win.document.createTextNode(
|
||||
"Rendering tape image... please wait..."));
|
||||
setTimeout(unloadDriver, 50);
|
||||
win.focus();
|
||||
}
|
||||
|
||||
// Outer block of unloadTape
|
||||
win.moveTo((screen.availWidth-win.outerWidth)/2, (screen.availHeight-win.outerHeight)/2);
|
||||
win.focus();
|
||||
win.addEventListener("load", unloadSetup, false);
|
||||
B220Util.openPopup(this.window, "./B220FramePaper.html", this.mnemonic + "-Unload",
|
||||
"location=no,scrollbars=yes,resizable,width=800,height=600",
|
||||
this, unloadSetup);
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
@ -1174,12 +1177,13 @@ B220MagTapeDrive.prototype.beforeUnload = function beforeUnload(ev) {
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220MagTapeDrive.prototype.tapeDriveOnload = function tapeDriveOnload() {
|
||||
B220MagTapeDrive.prototype.tapeDriveOnload = function tapeDriveOnload(ev) {
|
||||
/* Initializes the reader window and user interface */
|
||||
var body;
|
||||
var prefs = this.config.getNode("MagTape.units", this.unitIndex);
|
||||
|
||||
this.doc = this.window.document;
|
||||
this.doc = ev.target;
|
||||
this.window = this.doc.defaultView;
|
||||
this.doc.title = "retro-220 Tape Drive " + this.mnemonic;
|
||||
|
||||
body = this.$$("MTDiv");
|
||||
|
||||
@ -34,13 +34,13 @@ function B220PaperTapePunch(mnemonic, unitIndex, config) {
|
||||
|
||||
// Create the punch window and onload event
|
||||
this.doc = null;
|
||||
this.window = null;
|
||||
this.punchTape = null;
|
||||
this.punchEOP = null;
|
||||
this.window = window.open("../webUI/B220PaperTapePunch.html", mnemonic,
|
||||
B220Util.openPopup(window, "../webUI/B220PaperTapePunch.html", mnemonic,
|
||||
"location=no,scrollbars=no,resizable,width=240,height=160," +
|
||||
"left=" + left + ",top=" + top);
|
||||
this.window.addEventListener("load",
|
||||
B220PaperTapePunch.prototype.punchOnLoad.bind(this), false);
|
||||
"left=" + left + ",top=" + top,
|
||||
this, B220PaperTapePunch.prototype.punchOnLoad);
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
@ -156,15 +156,15 @@ B220PaperTapePunch.prototype.punchCopyTape = function punchCopyTape(ev) {
|
||||
or saved by the user */
|
||||
var text = this.punchTape.textContent;
|
||||
var title = "B220 " + this.mnemonic + " Text Snapshot";
|
||||
var win = window.open("./B220FramePaper.html", "PaperTape-Snapshot",
|
||||
"scrollbars,resizable,width=500,height=500");
|
||||
|
||||
win.moveTo((screen.availWidth-win.outerWidth)/2, (screen.availHeight-win.outerHeight)/2);
|
||||
win.addEventListener("load", function() {
|
||||
var doc;
|
||||
B220Util.openPopup(this.window, "./B220FramePaper.html", this.mnemonic + "-Snapshot",
|
||||
"scrollbars,resizable,width=500,height=500",
|
||||
this, function(ev) {
|
||||
var doc = ev.target;
|
||||
var win = doc.defaultView;
|
||||
|
||||
doc = win.document;
|
||||
doc.title = title;
|
||||
win.moveTo((screen.availWidth-win.outerWidth)/2, (screen.availHeight-win.outerHeight)/2);
|
||||
doc.getElementById("Paper").textContent = text;
|
||||
});
|
||||
|
||||
@ -205,14 +205,15 @@ B220PaperTapePunch.prototype.flipSwitch = function flipSwitch(ev) {
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapePunch.prototype.punchOnLoad = function punchOnLoad() {
|
||||
B220PaperTapePunch.prototype.punchOnLoad = function punchOnLoad(ev) {
|
||||
/* Initializes the Paper Tape Punch window and user interface */
|
||||
var body;
|
||||
var mask;
|
||||
var prefs = this.config.getNode("ConsoleOutput.units", this.unitIndex);
|
||||
var x;
|
||||
|
||||
this.doc = this.window.document;
|
||||
this.doc = ev.target;
|
||||
this.window = this.doc.defaultView;
|
||||
this.doc.title = "retro-220 Punch - " + this.mnemonic;
|
||||
|
||||
this.punchTape = this.$$("Paper");
|
||||
|
||||
@ -43,12 +43,12 @@ function B220PaperTapeReader(mnemonic, unitIndex, config) {
|
||||
|
||||
// Create the reader window and onload event
|
||||
this.doc = null;
|
||||
this.window = null;
|
||||
this.tapeSupplyBar = null;
|
||||
this.tapeView = null;
|
||||
this.window = window.open("../webUI/B220PaperTapeReader.html", mnemonic,
|
||||
"location=no,scrollbars=no,resizable,width=420,height=160,left=" + left + ",top=" + top);
|
||||
this.window.addEventListener("load",
|
||||
B220PaperTapeReader.prototype.readerOnload.bind(this), false);
|
||||
B220Util.openPopup(window, "../webUI/B220PaperTapeReader.html", mnemonic,
|
||||
"location=no,scrollbars=no,resizable,width=420,height=160,left=" + left + ",top=" + top,
|
||||
this, B220PaperTapeReader.prototype.readerOnload);
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
@ -229,14 +229,15 @@ B220PaperTapeReader.prototype.flipSwitch = function flipSwitch(ev) {
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220PaperTapeReader.prototype.readerOnload = function readerOnload() {
|
||||
B220PaperTapeReader.prototype.readerOnload = function readerOnload(ev) {
|
||||
/* Initializes the reader window and user interface */
|
||||
var body;
|
||||
var mask;
|
||||
var prefs = this.config.getNode("ConsoleInput.units", this.unitIndex);
|
||||
var x;
|
||||
|
||||
this.doc = this.window.document;
|
||||
this.doc = ev.target;
|
||||
this.window = this.doc.defaultView;
|
||||
//de = this.doc.documentElement;
|
||||
this.doc.title = "retro-220 - Reader - " + this.mnemonic;
|
||||
|
||||
|
||||
@ -1,275 +1,275 @@
|
||||
/***********************************************************************
|
||||
* retro-220/webUI B220SetCallback.js
|
||||
************************************************************************
|
||||
* Copyright (c) 2014,2017, Paul Kimpel.
|
||||
* Licensed under the MIT License, see
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
************************************************************************
|
||||
* B220 emulator universal function call-back module.
|
||||
*
|
||||
* Implements a combination setTimeout() and setImmediate() facility for the
|
||||
* B220 emulator web-based user interface. setCallback() is used in a manner
|
||||
* similar to setTimeout(), except that for low values of the timeout parameter
|
||||
* it merely yields control to any other pending events and timers before calling
|
||||
* the call-back function.
|
||||
*
|
||||
* This facility is needed because modern browsers implement a minimum delay
|
||||
* when calling setTimeout(). HTML5 specs require 4ms, but browsers vary in the
|
||||
* minimum they use, and their precision in activating the call-back function
|
||||
* once the actual delay is established varies even more. This module will use
|
||||
* setTimeout() if the requested delay time is above a certain threshold, and
|
||||
* a setImmediate-like mechanism (based on Promise) if the requested delay is
|
||||
* below that threshold.
|
||||
*
|
||||
* To help compensate for the fact that the call-back function may be called
|
||||
* sooner than requested, and that due either to other activity or to browser
|
||||
* limitations the delay may be longer than requested, the timing behavior of
|
||||
* setCallback() may be divided into "categories." For each category, a separate
|
||||
* record is kept of the current total deviation between the requested delay and
|
||||
* the actual delay. A portion of this deviation is then applied to the requested
|
||||
* delay on subsequent calls in an attempt to smooth out the differences. We are
|
||||
* going for good average behavior here, and some too-quick call-backs are better
|
||||
* than consistently too-long callbacks in this environment, particularly so that
|
||||
* I/Os can be initiated and their finish detected in finer-grained time increments.
|
||||
*
|
||||
* The SetCallback mechanism defines three functions that become members of the
|
||||
* global (window) object:
|
||||
*
|
||||
* token = setCallback(category, context, delay, fcn[, arg])
|
||||
*
|
||||
* Requests that the function "fcn" be called after "delay" milliseconds.
|
||||
* The function will be called as a method of "context", passing a
|
||||
* single optional argument "arg". The call-back "fcn" may be called
|
||||
* earlier or later than the specified delay. The string "category" (which
|
||||
* may be empty, null, or undefined) defines the category under which the
|
||||
* average delay difference will be maintained. setCallBack returns a
|
||||
* numeric token identifying the call-back event, which can be used with
|
||||
* clearCallback() to cancel the callback. Note that passing a string in
|
||||
* lieu of a function object is not permitted.
|
||||
*
|
||||
* clearCallBack(token)
|
||||
*
|
||||
* Cancels a pending call-back event, if in fact it is still pending.
|
||||
* The "token" parameter is a value returned from setCallback().
|
||||
*
|
||||
* object = getCallbackState(optionMask)
|
||||
*
|
||||
* This is a diagnostic function intended for use in monitoring the callback
|
||||
* mechanism. It returns an object that, depending upon bits set in its mask
|
||||
* parameter, contains copies of the lastTokenNr value, poolLength
|
||||
* value, current delayDev hash, pendingCallbacks hash, and pool array.
|
||||
* The optionMask parameter supports the following bit values:
|
||||
* bit 0x01: delayDev hash
|
||||
* bit 0x02: pendingCallbacks hash
|
||||
* bit 0x04: pool array
|
||||
* The lastTokenNr and poolLength values are always returned. If no mask
|
||||
* is supplied, no additional items are returned.
|
||||
*
|
||||
* This implementation has been inspired by Domenic Denicola's shim for the
|
||||
* setImmediate() API at https://github.com/NobleJS/setImmediate, and
|
||||
* David Baron's setZeroTimeout() implemenmentation described in his blog
|
||||
* at http://dbaron.org/log/20100309-faster-timeouts.
|
||||
*
|
||||
* I stole a little of their code, too.
|
||||
*
|
||||
************************************************************************
|
||||
* 2017-01-01 P.Kimpel
|
||||
* Original version, cloned from retro-205 emulator D205SetCallback.js.
|
||||
* 2017-02-18 P.Kimpel
|
||||
* Redesign yet again the delay adjustment mechanism with one from the
|
||||
* retro-205 project.
|
||||
* 2017-10-16 P.Kimpel
|
||||
* Replace window.postMessage yield mechanism with one based on Promise().
|
||||
***********************************************************************/
|
||||
"use strict";
|
||||
|
||||
(function (global) {
|
||||
/* Define a closure for the setCallback() mechanism */
|
||||
var alpha = 0.25; // decay factor for delay deviation adjustment
|
||||
var delayDev = {NUL: 0}; // hash of delay time deviations by category
|
||||
var minTimeout = 4; // minimum setTimeout() threshold, milliseconds
|
||||
var lastTokenNr = 0; // last setCallback token return value
|
||||
var pendingCallbacks = {}; // hash of pending callbacks, indexed by token as a string
|
||||
var perf = global.performance; // cached window.performance object
|
||||
var pool = []; // pool of reusable callback objects
|
||||
var poolLength = 0; // length of active entries in pool
|
||||
|
||||
/**************************************/
|
||||
function activateCallback(token) {
|
||||
/* Activates a callback after its delay period has expired */
|
||||
var endStamp = perf.now();
|
||||
var thisCallback;
|
||||
var tokenName = token.toString();
|
||||
|
||||
thisCallback = pendingCallbacks[tokenName];
|
||||
if (thisCallback) {
|
||||
delete pendingCallbacks[tokenName];
|
||||
delayDev[thisCallback.category] += endStamp - thisCallback.startStamp - thisCallback.delay;
|
||||
try {
|
||||
thisCallback.fcn.call(thisCallback.context, thisCallback.arg);
|
||||
} catch (err) {
|
||||
console.log("B220SetCallback.activateCallback: " + err.name + ", " + err.message);
|
||||
}
|
||||
|
||||
thisCallback.context = null;
|
||||
thisCallback.fcn = null;
|
||||
thisCallback.arg = null;
|
||||
pool[poolLength++] = thisCallback;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
function clearCallback(token) {
|
||||
/* Disables a pending callback, if it still exists and is still pending */
|
||||
var thisCallback;
|
||||
var tokenName = token.toString();
|
||||
|
||||
thisCallback = pendingCallbacks[tokenName];
|
||||
if (thisCallback) {
|
||||
delete pendingCallbacks[tokenName];
|
||||
if (thisCallback.cancelToken) {
|
||||
global.clearTimeout(thisCallback.cancelToken);
|
||||
}
|
||||
|
||||
thisCallback.context = null;
|
||||
thisCallback.fcn = null;
|
||||
thisCallback.arg = null;
|
||||
pool[poolLength++] = thisCallback;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
function setCallback(category, context, callbackDelay, fcn, arg) {
|
||||
/* Sets up and schedules a callback for function "fcn", called with context
|
||||
"context", after a delay of "delay" ms. An optional "arg" value will be passed
|
||||
to "fcn". If the delay is less than "minTimeout", a setImmediate-like mechanism
|
||||
based on DOM Promise() will be used; otherwise the environment's standard
|
||||
setTimeout mechanism will be used */
|
||||
var adj = 0; // adjustment to delay and delayDev[]
|
||||
var categoryName = (category || "NUL").toString();
|
||||
var delay = callbackDelay || 0; // actual delay to be generated
|
||||
var delayBias; // current amount of delay deviation
|
||||
var thisCallback; // call-back object to be used
|
||||
var token = ++lastTokenNr; // call-back token number
|
||||
var tokenName = token.toString(); // call-back token ID
|
||||
|
||||
// Allocate a call-back object from the pool.
|
||||
if (poolLength <= 0) {
|
||||
thisCallback = {};
|
||||
} else {
|
||||
thisCallback = pool[--poolLength];
|
||||
pool[poolLength] = null;
|
||||
}
|
||||
|
||||
thisCallback.startStamp = perf.now();
|
||||
|
||||
// Adjust the requested delay based on the current delay deviation
|
||||
// for this category.
|
||||
delayBias = delayDev[categoryName];
|
||||
if (!delayBias) {
|
||||
delayDev[categoryName] = 0; // bias was zero, or got a new one: no adjustment
|
||||
} else {
|
||||
if (delayBias > 0) {
|
||||
// We are delaying too much and should try to delay less.
|
||||
if (delay < 0) {
|
||||
adj = 0; // don't make delay any more negative
|
||||
} else {
|
||||
adj = -Math.min(delay, delayBias, minTimeout)*alpha;
|
||||
}
|
||||
} else { // delayBias < 0
|
||||
// We are delaying too little and should try to delay more.
|
||||
if (delay < 0) {
|
||||
if (delay - minTimeout < delayBias) {
|
||||
adj = -delayBias;
|
||||
} else {
|
||||
adj = minTimeout - delay;
|
||||
}
|
||||
} else {
|
||||
if (delay > minTimeout) {
|
||||
adj = 0;
|
||||
} else if (delay - minTimeout < delayBias) {
|
||||
adj = -delayBias;
|
||||
} else {
|
||||
adj = minTimeout - delay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delay += adj;
|
||||
delayDev[categoryName] += adj;
|
||||
}
|
||||
|
||||
// Fill in the call-back object and tank it in pendingCallbacks.
|
||||
thisCallback.category = categoryName;
|
||||
thisCallback.delay = delay;
|
||||
thisCallback.context = context || this;
|
||||
thisCallback.fcn = fcn;
|
||||
thisCallback.arg = arg;
|
||||
pendingCallbacks[tokenName] = thisCallback;
|
||||
|
||||
// Decide whether to do a time wait or just a yield.
|
||||
if (delay > minTimeout) {
|
||||
thisCallback.cancelToken = global.setTimeout(activateCallback, delay, token);
|
||||
} else {
|
||||
thisCallback.cancelToken = 0;
|
||||
Promise.resolve(token).then(activateCallback);
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
function getCallbackState(optionMask) {
|
||||
/* Diagnostic function. Returns an object that, depending upon bits in
|
||||
the option mask, contains copies of the lastTokenNr value, poolLength
|
||||
value, current delayDev hash, pendingCallbacks hash, and pool array.
|
||||
bit 0x01: delayDev hash
|
||||
bit 0x02: pendingCallbacks hash
|
||||
bit 0x04: pool array
|
||||
If no mask is supplied, no additional items are returned */
|
||||
var e;
|
||||
var mask = optionMask || 0;
|
||||
var state = {
|
||||
lastTokenNr: lastTokenNr,
|
||||
poolLength: poolLength,
|
||||
delayDev: {},
|
||||
pendingCallbacks: {},
|
||||
pool: []};
|
||||
|
||||
if (mask & 0x01) {
|
||||
for (e in delayDev) {
|
||||
state.delayDev[e] = delayDev[e];
|
||||
}
|
||||
}
|
||||
if (mask & 0x02) {
|
||||
for (e in pendingCallbacks) {
|
||||
state.pendingCallbacks[e] = pendingCallbacks[e];
|
||||
}
|
||||
}
|
||||
if (mask & 0x04) {
|
||||
for (e=0; e<poolLength; ++e) {
|
||||
state.pool[e] = pool[e];
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/********** Outer block of anonymous closure **********/
|
||||
if (!global.setCallback && !global.importScripts) {
|
||||
// Attach to the prototype of global, if possible, otherwise to global itself
|
||||
var attachee = global;
|
||||
|
||||
/*****
|
||||
if (typeof Object.getPrototypeOf === "function") {
|
||||
if ("setTimeout" in Object.getPrototypeOf(global)) {
|
||||
attachee = Object.getPrototypeOf(global);
|
||||
}
|
||||
}
|
||||
*****/
|
||||
|
||||
attachee.setCallback = setCallback;
|
||||
attachee.clearCallback = clearCallback;
|
||||
attachee.getCallbackState = getCallbackState;
|
||||
}
|
||||
}(typeof global === "object" && global ? global : this));
|
||||
/***********************************************************************
|
||||
* retro-220/webUI B220SetCallback.js
|
||||
************************************************************************
|
||||
* Copyright (c) 2014,2017, Paul Kimpel.
|
||||
* Licensed under the MIT License, see
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
************************************************************************
|
||||
* B220 emulator universal function call-back module.
|
||||
*
|
||||
* Implements a combination setTimeout() and setImmediate() facility for the
|
||||
* B220 emulator web-based user interface. setCallback() is used in a manner
|
||||
* similar to setTimeout(), except that for low values of the timeout parameter
|
||||
* it merely yields control to any other pending events and timers before calling
|
||||
* the call-back function.
|
||||
*
|
||||
* This facility is needed because modern browsers implement a minimum delay
|
||||
* when calling setTimeout(). HTML5 specs require 4ms, but browsers vary in the
|
||||
* minimum they use, and their precision in activating the call-back function
|
||||
* once the actual delay is established varies even more. This module will use
|
||||
* setTimeout() if the requested delay time is above a certain threshold, and
|
||||
* a setImmediate-like mechanism (based on Promise) if the requested delay is
|
||||
* below that threshold.
|
||||
*
|
||||
* To help compensate for the fact that the call-back function may be called
|
||||
* sooner than requested, and that due either to other activity or to browser
|
||||
* limitations the delay may be longer than requested, the timing behavior of
|
||||
* setCallback() may be divided into "categories." For each category, a separate
|
||||
* record is kept of the current total deviation between the requested delay and
|
||||
* the actual delay. A portion of this deviation is then applied to the requested
|
||||
* delay on subsequent calls in an attempt to smooth out the differences. We are
|
||||
* going for good average behavior here, and some too-quick call-backs are better
|
||||
* than consistently too-long callbacks in this environment, particularly so that
|
||||
* I/Os can be initiated and their finish detected in finer-grained time increments.
|
||||
*
|
||||
* The SetCallback mechanism defines three functions that become members of the
|
||||
* global (window) object:
|
||||
*
|
||||
* token = setCallback(category, context, delay, fcn[, arg])
|
||||
*
|
||||
* Requests that the function "fcn" be called after "delay" milliseconds.
|
||||
* The function will be called as a method of "context", passing a
|
||||
* single optional argument "arg". The call-back "fcn" may be called
|
||||
* earlier or later than the specified delay. The string "category" (which
|
||||
* may be empty, null, or undefined) defines the category under which the
|
||||
* average delay difference will be maintained. setCallBack returns a
|
||||
* numeric token identifying the call-back event, which can be used with
|
||||
* clearCallback() to cancel the callback. Note that passing a string in
|
||||
* lieu of a function object is not permitted.
|
||||
*
|
||||
* clearCallBack(token)
|
||||
*
|
||||
* Cancels a pending call-back event, if in fact it is still pending.
|
||||
* The "token" parameter is a value returned from setCallback().
|
||||
*
|
||||
* object = getCallbackState(optionMask)
|
||||
*
|
||||
* This is a diagnostic function intended for use in monitoring the callback
|
||||
* mechanism. It returns an object that, depending upon bits set in its mask
|
||||
* parameter, contains copies of the lastTokenNr value, poolLength
|
||||
* value, current delayDev hash, pendingCallbacks hash, and pool array.
|
||||
* The optionMask parameter supports the following bit values:
|
||||
* bit 0x01: delayDev hash
|
||||
* bit 0x02: pendingCallbacks hash
|
||||
* bit 0x04: pool array
|
||||
* The lastTokenNr and poolLength values are always returned. If no mask
|
||||
* is supplied, no additional items are returned.
|
||||
*
|
||||
* This implementation has been inspired by Domenic Denicola's shim for the
|
||||
* setImmediate() API at https://github.com/NobleJS/setImmediate, and
|
||||
* David Baron's setZeroTimeout() implemenmentation described in his blog
|
||||
* at http://dbaron.org/log/20100309-faster-timeouts.
|
||||
*
|
||||
* I stole a little of their code, too.
|
||||
*
|
||||
************************************************************************
|
||||
* 2017-01-01 P.Kimpel
|
||||
* Original version, cloned from retro-205 emulator D205SetCallback.js.
|
||||
* 2017-02-18 P.Kimpel
|
||||
* Redesign yet again the delay adjustment mechanism with one from the
|
||||
* retro-205 project.
|
||||
* 2017-10-16 P.Kimpel
|
||||
* Replace window.postMessage yield mechanism with one based on Promise().
|
||||
***********************************************************************/
|
||||
"use strict";
|
||||
|
||||
(function (global) {
|
||||
/* Define a closure for the setCallback() mechanism */
|
||||
var alpha = 0.25; // decay factor for delay deviation adjustment
|
||||
var delayDev = {NUL: 0}; // hash of delay time deviations by category
|
||||
var minTimeout = 4; // minimum setTimeout() threshold, milliseconds
|
||||
var lastTokenNr = 0; // last setCallback token return value
|
||||
var pendingCallbacks = {}; // hash of pending callbacks, indexed by token as a string
|
||||
var perf = global.performance; // cached window.performance object
|
||||
var pool = []; // pool of reusable callback objects
|
||||
var poolLength = 0; // length of active entries in pool
|
||||
|
||||
/**************************************/
|
||||
function activateCallback(token) {
|
||||
/* Activates a callback after its delay period has expired */
|
||||
var endStamp = perf.now();
|
||||
var thisCallback;
|
||||
var tokenName = token.toString();
|
||||
|
||||
thisCallback = pendingCallbacks[tokenName];
|
||||
if (thisCallback) {
|
||||
delete pendingCallbacks[tokenName];
|
||||
delayDev[thisCallback.category] += endStamp - thisCallback.startStamp - thisCallback.delay;
|
||||
try {
|
||||
thisCallback.fcn.call(thisCallback.context, thisCallback.arg);
|
||||
} catch (err) {
|
||||
console.log("B220SetCallback.activateCallback: " + err.name + ", " + err.message);
|
||||
}
|
||||
|
||||
thisCallback.context = null;
|
||||
thisCallback.fcn = null;
|
||||
thisCallback.arg = null;
|
||||
pool[poolLength++] = thisCallback;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
function clearCallback(token) {
|
||||
/* Disables a pending callback, if it still exists and is still pending */
|
||||
var thisCallback;
|
||||
var tokenName = token.toString();
|
||||
|
||||
thisCallback = pendingCallbacks[tokenName];
|
||||
if (thisCallback) {
|
||||
delete pendingCallbacks[tokenName];
|
||||
if (thisCallback.cancelToken) {
|
||||
global.clearTimeout(thisCallback.cancelToken);
|
||||
}
|
||||
|
||||
thisCallback.context = null;
|
||||
thisCallback.fcn = null;
|
||||
thisCallback.arg = null;
|
||||
pool[poolLength++] = thisCallback;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
function setCallback(category, context, callbackDelay, fcn, arg) {
|
||||
/* Sets up and schedules a callback for function "fcn", called with context
|
||||
"context", after a delay of "delay" ms. An optional "arg" value will be passed
|
||||
to "fcn". If the delay is less than "minTimeout", a setImmediate-like mechanism
|
||||
based on DOM Promise() will be used; otherwise the environment's standard
|
||||
setTimeout mechanism will be used */
|
||||
var adj = 0; // adjustment to delay and delayDev[]
|
||||
var categoryName = (category || "NUL").toString();
|
||||
var delay = callbackDelay || 0; // actual delay to be generated
|
||||
var delayBias; // current amount of delay deviation
|
||||
var thisCallback; // call-back object to be used
|
||||
var token = ++lastTokenNr; // call-back token number
|
||||
var tokenName = token.toString(); // call-back token ID
|
||||
|
||||
// Allocate a call-back object from the pool.
|
||||
if (poolLength <= 0) {
|
||||
thisCallback = {};
|
||||
} else {
|
||||
thisCallback = pool[--poolLength];
|
||||
pool[poolLength] = null;
|
||||
}
|
||||
|
||||
thisCallback.startStamp = perf.now();
|
||||
|
||||
// Adjust the requested delay based on the current delay deviation
|
||||
// for this category.
|
||||
delayBias = delayDev[categoryName];
|
||||
if (!delayBias) {
|
||||
delayDev[categoryName] = 0; // bias was zero, or got a new one: no adjustment
|
||||
} else {
|
||||
if (delayBias > 0) {
|
||||
// We are delaying too much and should try to delay less.
|
||||
if (delay < 0) {
|
||||
adj = 0; // don't make delay any more negative
|
||||
} else {
|
||||
adj = -Math.min(delay, delayBias, minTimeout)*alpha;
|
||||
}
|
||||
} else { // delayBias < 0
|
||||
// We are delaying too little and should try to delay more.
|
||||
if (delay < 0) {
|
||||
if (delay - minTimeout < delayBias) {
|
||||
adj = -delayBias;
|
||||
} else {
|
||||
adj = minTimeout - delay;
|
||||
}
|
||||
} else {
|
||||
if (delay > minTimeout) {
|
||||
adj = 0;
|
||||
} else if (delay - minTimeout < delayBias) {
|
||||
adj = -delayBias;
|
||||
} else {
|
||||
adj = minTimeout - delay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delay += adj;
|
||||
delayDev[categoryName] += adj;
|
||||
}
|
||||
|
||||
// Fill in the call-back object and tank it in pendingCallbacks.
|
||||
thisCallback.category = categoryName;
|
||||
thisCallback.delay = delay;
|
||||
thisCallback.context = context || this;
|
||||
thisCallback.fcn = fcn;
|
||||
thisCallback.arg = arg;
|
||||
pendingCallbacks[tokenName] = thisCallback;
|
||||
|
||||
// Decide whether to do a time wait or just a yield.
|
||||
if (delay > minTimeout) {
|
||||
thisCallback.cancelToken = global.setTimeout(activateCallback, delay, token);
|
||||
} else {
|
||||
thisCallback.cancelToken = 0;
|
||||
Promise.resolve(token).then(activateCallback);
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
function getCallbackState(optionMask) {
|
||||
/* Diagnostic function. Returns an object that, depending upon bits in
|
||||
the option mask, contains copies of the lastTokenNr value, poolLength
|
||||
value, current delayDev hash, pendingCallbacks hash, and pool array.
|
||||
bit 0x01: delayDev hash
|
||||
bit 0x02: pendingCallbacks hash
|
||||
bit 0x04: pool array
|
||||
If no mask is supplied, no additional items are returned */
|
||||
var e;
|
||||
var mask = optionMask || 0;
|
||||
var state = {
|
||||
lastTokenNr: lastTokenNr,
|
||||
poolLength: poolLength,
|
||||
delayDev: {},
|
||||
pendingCallbacks: {},
|
||||
pool: []};
|
||||
|
||||
if (mask & 0x01) {
|
||||
for (e in delayDev) {
|
||||
state.delayDev[e] = delayDev[e];
|
||||
}
|
||||
}
|
||||
if (mask & 0x02) {
|
||||
for (e in pendingCallbacks) {
|
||||
state.pendingCallbacks[e] = pendingCallbacks[e];
|
||||
}
|
||||
}
|
||||
if (mask & 0x04) {
|
||||
for (e=0; e<poolLength; ++e) {
|
||||
state.pool[e] = pool[e];
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/********** Outer block of anonymous closure **********/
|
||||
if (!global.setCallback && !global.importScripts) {
|
||||
// Attach to the prototype of global, if possible, otherwise to global itself
|
||||
var attachee = global;
|
||||
|
||||
/*****
|
||||
if (typeof Object.getPrototypeOf === "function") {
|
||||
if ("setTimeout" in Object.getPrototypeOf(global)) {
|
||||
attachee = Object.getPrototypeOf(global);
|
||||
}
|
||||
}
|
||||
*****/
|
||||
|
||||
attachee.setCallback = setCallback;
|
||||
attachee.clearCallback = clearCallback;
|
||||
attachee.getCallbackState = getCallbackState;
|
||||
}
|
||||
}(typeof global === "object" && global ? global : this));
|
||||
|
||||
@ -47,7 +47,6 @@
|
||||
<div class=heading>System Properties:</div>
|
||||
|
||||
<select id=SystemMemorySize>
|
||||
<option value=1000>1000
|
||||
<option value=2000>2000
|
||||
<option value=3000>3000
|
||||
<option value=4000>4000
|
||||
@ -935,7 +934,7 @@
|
||||
<td class=center>
|
||||
<select id=MagTape1Type>
|
||||
<option value=NONE>(not used)
|
||||
<option selected value=MTA>DataReader
|
||||
<option selected value=MTA>TSU
|
||||
<option value=DFA>DataFile
|
||||
</select>
|
||||
<td class=center>
|
||||
@ -955,7 +954,7 @@
|
||||
<td class=center>
|
||||
<select id=MagTape2Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=MTB>DataReader
|
||||
<option value=MTB>TSU
|
||||
<option value=DFB>DataFile
|
||||
</select>
|
||||
<td class=center>
|
||||
@ -975,7 +974,7 @@
|
||||
<td class=center>
|
||||
<select id=MagTape3Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=MTC>DataReader
|
||||
<option value=MTC>TSU
|
||||
<option value=DFC>DataFile
|
||||
</select>
|
||||
<td class=center>
|
||||
@ -995,7 +994,7 @@
|
||||
<td class=center>
|
||||
<select id=MagTape4Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=MTD>DataReader
|
||||
<option value=MTD>TSU
|
||||
<option value=DFD>DataFile
|
||||
</select>
|
||||
<td class=center>
|
||||
@ -1015,7 +1014,7 @@
|
||||
<td class=center>
|
||||
<select id=MagTape5Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=MTE>DataReader
|
||||
<option value=MTE>TSU
|
||||
<option value=DFE>DataFile
|
||||
</select>
|
||||
<td class=center>
|
||||
@ -1035,7 +1034,7 @@
|
||||
<td class=center>
|
||||
<select id=MagTape6Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=MTF>DataReader
|
||||
<option value=MTF>TSU
|
||||
<option value=DFG>DataFile
|
||||
</select>
|
||||
<td class=center>
|
||||
@ -1055,7 +1054,7 @@
|
||||
<td class=center>
|
||||
<select id=MagTape7Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=MTG>DataReader
|
||||
<option value=MTG>TSU
|
||||
<option value=DFG>DataFile
|
||||
</select>
|
||||
<td class=center>
|
||||
@ -1075,7 +1074,7 @@
|
||||
<td class=center>
|
||||
<select id=MagTape8Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=MTH>DataReader
|
||||
<option value=MTH>TSU
|
||||
<option value=DFH>DataFile
|
||||
</select>
|
||||
<td class=center>
|
||||
@ -1095,7 +1094,7 @@
|
||||
<td class=center>
|
||||
<select id=MagTape9Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=MTI>DataReader
|
||||
<option value=MTI>TSU
|
||||
<option value=DFI>DataFile
|
||||
</select>
|
||||
<td class=center>
|
||||
@ -1115,7 +1114,7 @@
|
||||
<td class=center>
|
||||
<select id=MagTape10Type>
|
||||
<option selected value=NONE>(not used)
|
||||
<option value=MTJ>DataReader
|
||||
<option value=MTJ>TSU
|
||||
<option value=DFJ>DataFile
|
||||
</select>
|
||||
<td class=center>
|
||||
|
||||
@ -41,7 +41,7 @@ B220SystemConfig.prototype.flushDelay = 60000; // flush timer setting, ms
|
||||
|
||||
B220SystemConfig.defaultConfig = {
|
||||
version: this.configVersion,
|
||||
memorySize: 5000, // 11-digit words
|
||||
memorySize: 5000, // 11-digit words
|
||||
|
||||
ControlConsole: {
|
||||
PCS1SW: 0, // Program Control Switches 1-0
|
||||
@ -123,7 +123,7 @@ B220SystemConfig.defaultConfig = {
|
||||
|
||||
/**************************************/
|
||||
B220SystemConfig.prototype.$$ = function $$(id) {
|
||||
return this.window.document.getElementById(id);
|
||||
return this.doc.getElementById(id);
|
||||
}
|
||||
|
||||
/**************************************/
|
||||
@ -412,7 +412,7 @@ B220SystemConfig.prototype.saveConfigDialog = function saveConfigDialog() {
|
||||
// System Properties
|
||||
|
||||
e = this.$$("SystemMemorySize");
|
||||
x = parseInt(e.options[e.selectedIndex], 10);
|
||||
x = parseInt(e.options[e.selectedIndex].value, 10);
|
||||
cd.memorySize = (isNaN(x) ? 5000 : x);
|
||||
|
||||
// Console Input units
|
||||
@ -543,6 +543,12 @@ B220SystemConfig.prototype.openConfigUI = function openConfigUI() {
|
||||
system configuration */
|
||||
|
||||
function configUI_Load(ev) {
|
||||
this.doc = ev.target;
|
||||
this.window = this.doc.defaultView;
|
||||
this.window.moveTo(screen.availWidth-this.window.outerWidth-40,
|
||||
(screen.availHeight-this.window.outerHeight)/2);
|
||||
this.window.focus();
|
||||
this.alertWin = this.window;
|
||||
this.$$("SaveBtn").addEventListener("click",
|
||||
this.saveConfigDialog.bind(this), false);
|
||||
this.$$("CancelBtn").addEventListener("click",
|
||||
@ -558,12 +564,8 @@ B220SystemConfig.prototype.openConfigUI = function openConfigUI() {
|
||||
}
|
||||
|
||||
this.doc = null;
|
||||
this.window = window.open("../webUI/B220SystemConfig.html", this.configStorageName,
|
||||
"location=no,scrollbars,resizable,width=800,height=800");
|
||||
this.window.moveTo(screen.availWidth-this.window.outerWidth-40,
|
||||
(screen.availHeight-this.window.outerHeight)/2);
|
||||
this.window.focus();
|
||||
this.alertWin = this.window;
|
||||
this.window.addEventListener("load",
|
||||
configUI_Load.bind(this), false);
|
||||
this.window = null;
|
||||
B220Util.openPopup(window, "../webUI/B220SystemConfig.html", this.configStorageName,
|
||||
"location=no,scrollbars,resizable,width=800,height=800",
|
||||
this, configUI_Load);
|
||||
};
|
||||
|
||||
@ -18,6 +18,13 @@ function B220Util() {
|
||||
// Nothing to construct at present...
|
||||
}
|
||||
|
||||
|
||||
/**************************************/
|
||||
B220Util.popupOpenDelayIncrement = 250; // increment for pop-up open delay adjustment, ms
|
||||
B220Util.popupOpenDelay = 500; // current pop-up open delay, ms
|
||||
B220Util.popupOpenQueue = []; // queue of pop-up open argument objects
|
||||
|
||||
|
||||
/**************************************/
|
||||
B220Util.xlateASCIIToAlgolRex = // For translation of 220-ASCII to Algol-ASCII glyphs
|
||||
/[^\r\n\xA0 $()*+,-./0-9=@A-Za-z]/g;
|
||||
@ -73,9 +80,9 @@ B220Util.deepCopy = function deepCopy(source, dest) {
|
||||
Adapted (with thanks) from the "extend" routine by poster Kamarey on 2011-03-26 at
|
||||
http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-an-object
|
||||
*/
|
||||
var constr;
|
||||
var copy;
|
||||
var name;
|
||||
var constr = null;
|
||||
var copy = null;
|
||||
var name = "";
|
||||
|
||||
if (source === null) {
|
||||
return source;
|
||||
@ -141,7 +148,7 @@ B220Util.xlateAlgolToASCII = function xlateAlgolToASCII(text) {
|
||||
B220Util.xlateDOMTreeText = function xlateDOMTreeText(n, xlate) {
|
||||
/* If Node "n" is a text node, translates its value using the "xlate"
|
||||
function. For all other Node types, translates all subordinate text nodes */
|
||||
var kid;
|
||||
var kid = null;
|
||||
|
||||
if (n.nodeType == Node.TEXT_NODE) {
|
||||
n.nodeValue = xlate(n.nodeValue);
|
||||
@ -153,3 +160,78 @@ B220Util.xlateDOMTreeText = function xlateDOMTreeText(n, xlate) {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220Util.openPopup = function openPopup(parent, url, windowName, options, context, onload) {
|
||||
/* Schedules the opening of a pop-up window so that browsers such as Apple
|
||||
Safari (11.0+) will not block the opens if they occur too close together.
|
||||
Parameters:
|
||||
parent: parent window for the pop-up
|
||||
url: url of window context, passed to window.open()
|
||||
windowName: internal name of the window, passed to window.open()
|
||||
options: string of window options, passed to window.open()
|
||||
context: object context ("this") for the onload function (may be null)
|
||||
onload: event handler for the window's onload event (may be null).
|
||||
If the queue of pending pop-up opens in B220Util.popupOpenQueue[] is empty,
|
||||
then attempts to open the window immediately. Otherwise queues the open
|
||||
parameters, which will be dequeued and acted upon after the previously-
|
||||
queued entries are completed by B220Util.dequeuePopup() */
|
||||
|
||||
B220Util.popupOpenQueue.push({
|
||||
parent: parent,
|
||||
url: url,
|
||||
windowName: windowName,
|
||||
options: options,
|
||||
context: context,
|
||||
onload: onload});
|
||||
if (B220Util.popupOpenQueue.length == 1) { // queue was empty
|
||||
B220Util.dequeuePopup();
|
||||
}
|
||||
};
|
||||
|
||||
/**************************************/
|
||||
B220Util.dequeuePopup = function dequeuePopup() {
|
||||
/* Dequeues a popupOpenQueue[] entry and attempts to open the pop-up window.
|
||||
Called either directly by B220Util.openPopup() when an entry is inserted
|
||||
into an empty queue, or by setTimeout() after a delay. If the open fails,
|
||||
the entry is reinserted into the head of the queue, the open delay is
|
||||
incremented, and this function is rescheduled for the new delay. If the
|
||||
open is successful, and the queue is non-empty, then this function is
|
||||
scheduled for the current open delay to process the next entry in the queue */
|
||||
var entry = B220Util.popupOpenQueue.shift();
|
||||
var loader1 = null;
|
||||
var loader2 = null;
|
||||
var win = null;
|
||||
|
||||
if (entry) {
|
||||
try {
|
||||
win = entry.parent.open(entry.url, entry.windowName, entry.options);
|
||||
} catch (e) {
|
||||
win = null;
|
||||
}
|
||||
|
||||
if (!win) { // window open failed, requeue
|
||||
B220Util.popupOpenQueue.unshift(entry);
|
||||
B220Util.popupOpenDelay += B220Util.popupOpenDelayIncrement;
|
||||
setTimeout(B220Util.dequeuePopup, B220Util.popupOpenDelay);
|
||||
//console.log("Pop-up open failed: " + entry.windowName + ", new delay=" + B220Util.popupOpenDelay + "ms");
|
||||
} else { // window open was successful
|
||||
if (entry.onload) {
|
||||
loader1 = entry.onload.bind(entry.context);
|
||||
win.addEventListener("load", loader1, false);
|
||||
}
|
||||
|
||||
loader2 = function(ev) { // remove the load event listeners after loading
|
||||
win.removeEventListener("load", loader2, false);
|
||||
if (loader1) {
|
||||
win.removeEventListener("load", loader1, false);
|
||||
}
|
||||
};
|
||||
|
||||
win.addEventListener("load", loader2, false);
|
||||
if (B220Util.popupOpenQueue.length > 0) {
|
||||
setTimeout(B220Util.dequeuePopup, B220Util.popupOpenDelay);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -1,97 +1,97 @@
|
||||
Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
|
||||
Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
|
||||
|
||||
Bitstream Vera Fonts Copyright
|
||||
------------------------------
|
||||
|
||||
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
|
||||
a trademark of Bitstream, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of the fonts accompanying this license ("Fonts") and associated
|
||||
documentation files (the "Font Software"), to reproduce and distribute the
|
||||
Font Software, including without limitation the rights to use, copy, merge,
|
||||
publish, distribute, and/or sell copies of the Font Software, and to permit
|
||||
persons to whom the Font Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright and trademark notices and this permission notice shall
|
||||
be included in all copies of one or more of the Font Software typefaces.
|
||||
|
||||
The Font Software may be modified, altered, or added to, and in particular
|
||||
the designs of glyphs or characters in the Fonts may be modified and
|
||||
additional glyphs or characters may be added to the Fonts, only if the fonts
|
||||
are renamed to names not containing either the words "Bitstream" or the word
|
||||
"Vera".
|
||||
|
||||
This License becomes null and void to the extent applicable to Fonts or Font
|
||||
Software that has been modified and is distributed under the "Bitstream
|
||||
Vera" names.
|
||||
|
||||
The Font Software may be sold as part of a larger software package but no
|
||||
copy of one or more of the Font Software typefaces may be sold by itself.
|
||||
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
|
||||
TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
|
||||
FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING
|
||||
ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE
|
||||
FONT SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the names of Gnome, the Gnome
|
||||
Foundation, and Bitstream Inc., shall not be used in advertising or
|
||||
otherwise to promote the sale, use or other dealings in this Font Software
|
||||
without prior written authorization from the Gnome Foundation or Bitstream
|
||||
Inc., respectively. For further information, contact: fonts at gnome dot
|
||||
org.
|
||||
|
||||
Arev Fonts Copyright
|
||||
------------------------------
|
||||
|
||||
Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the fonts accompanying this license ("Fonts") and
|
||||
associated documentation files (the "Font Software"), to reproduce
|
||||
and distribute the modifications to the Bitstream Vera Font Software,
|
||||
including without limitation the rights to use, copy, merge, publish,
|
||||
distribute, and/or sell copies of the Font Software, and to permit
|
||||
persons to whom the Font Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright and trademark notices and this permission notice
|
||||
shall be included in all copies of one or more of the Font Software
|
||||
typefaces.
|
||||
|
||||
The Font Software may be modified, altered, or added to, and in
|
||||
particular the designs of glyphs or characters in the Fonts may be
|
||||
modified and additional glyphs or characters may be added to the
|
||||
Fonts, only if the fonts are renamed to names not containing either
|
||||
the words "Tavmjong Bah" or the word "Arev".
|
||||
|
||||
This License becomes null and void to the extent applicable to Fonts
|
||||
or Font Software that has been modified and is distributed under the
|
||||
"Tavmjong Bah Arev" names.
|
||||
|
||||
The Font Software may be sold as part of a larger software package but
|
||||
no copy of one or more of the Font Software typefaces may be sold by
|
||||
itself.
|
||||
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
|
||||
TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Tavmjong Bah shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other
|
||||
dealings in this Font Software without prior written authorization
|
||||
from Tavmjong Bah. For further information, contact: tavmjong @ free
|
||||
Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
|
||||
Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
|
||||
|
||||
Bitstream Vera Fonts Copyright
|
||||
------------------------------
|
||||
|
||||
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
|
||||
a trademark of Bitstream, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of the fonts accompanying this license ("Fonts") and associated
|
||||
documentation files (the "Font Software"), to reproduce and distribute the
|
||||
Font Software, including without limitation the rights to use, copy, merge,
|
||||
publish, distribute, and/or sell copies of the Font Software, and to permit
|
||||
persons to whom the Font Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright and trademark notices and this permission notice shall
|
||||
be included in all copies of one or more of the Font Software typefaces.
|
||||
|
||||
The Font Software may be modified, altered, or added to, and in particular
|
||||
the designs of glyphs or characters in the Fonts may be modified and
|
||||
additional glyphs or characters may be added to the Fonts, only if the fonts
|
||||
are renamed to names not containing either the words "Bitstream" or the word
|
||||
"Vera".
|
||||
|
||||
This License becomes null and void to the extent applicable to Fonts or Font
|
||||
Software that has been modified and is distributed under the "Bitstream
|
||||
Vera" names.
|
||||
|
||||
The Font Software may be sold as part of a larger software package but no
|
||||
copy of one or more of the Font Software typefaces may be sold by itself.
|
||||
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
|
||||
TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
|
||||
FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING
|
||||
ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE
|
||||
FONT SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the names of Gnome, the Gnome
|
||||
Foundation, and Bitstream Inc., shall not be used in advertising or
|
||||
otherwise to promote the sale, use or other dealings in this Font Software
|
||||
without prior written authorization from the Gnome Foundation or Bitstream
|
||||
Inc., respectively. For further information, contact: fonts at gnome dot
|
||||
org.
|
||||
|
||||
Arev Fonts Copyright
|
||||
------------------------------
|
||||
|
||||
Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the fonts accompanying this license ("Fonts") and
|
||||
associated documentation files (the "Font Software"), to reproduce
|
||||
and distribute the modifications to the Bitstream Vera Font Software,
|
||||
including without limitation the rights to use, copy, merge, publish,
|
||||
distribute, and/or sell copies of the Font Software, and to permit
|
||||
persons to whom the Font Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright and trademark notices and this permission notice
|
||||
shall be included in all copies of one or more of the Font Software
|
||||
typefaces.
|
||||
|
||||
The Font Software may be modified, altered, or added to, and in
|
||||
particular the designs of glyphs or characters in the Fonts may be
|
||||
modified and additional glyphs or characters may be added to the
|
||||
Fonts, only if the fonts are renamed to names not containing either
|
||||
the words "Tavmjong Bah" or the word "Arev".
|
||||
|
||||
This License becomes null and void to the extent applicable to Fonts
|
||||
or Font Software that has been modified and is distributed under the
|
||||
"Tavmjong Bah Arev" names.
|
||||
|
||||
The Font Software may be sold as part of a larger software package but
|
||||
no copy of one or more of the Font Software typefaces may be sold by
|
||||
itself.
|
||||
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
|
||||
TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Tavmjong Bah shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other
|
||||
dealings in this Font Software without prior written authorization
|
||||
from Tavmjong Bah. For further information, contact: tavmjong @ free
|
||||
. fr.
|
||||
Loading…
x
Reference in New Issue
Block a user