/*********************************************************************** * retro-b5500/emulator B5500CardPunch.js ************************************************************************ * Copyright (c) 2013, Nigel Williams and Paul Kimpel. * Licensed under the MIT License, see * http://www.opensource.org/licenses/mit-license.php ************************************************************************ * B5500 Card Punch Peripheral Unit module. * * Defines a card punch peripheral unit type. * ************************************************************************ * 2013-06-16 P.Kimpel * Original version, from B5500CardReader.js & B5500DummyPrinter.js. ***********************************************************************/ "use strict"; /**************************************/ function B5500CardPunch(mnemonic, unitIndex, designate, statusChange, signal, options) { /* Constructor for the CardPunch object */ this.mnemonic = mnemonic; // Unit mnemonic this.unitIndex = unitIndex; // Ready-mask bit number this.designate = designate; // IOD unit designate number this.statusChange = statusChange; // external function to call for ready-status change this.signal = signal; // external function to call for special signals (not used here) this.timer = 0; // setCallback() token this.initiateStamp = 0; // timestamp of last initiation (set by IOUnit) this.useAlgolGlyphs = options.algolGlyphs; // format Unicode for special Algol chars this.clear(); this.doc = null; this.stacker1 = null; this.endOfStacker1 = null; this.stacker2 = null; this.endOfStacker2 = null; this.window = window.open("../webUI/B5500CardPunch.html", mnemonic, "location=no,scrollbars=no,resizable,width=560,height=204,left=0,top=220"); this.window.addEventListener("load", B5500CentralControl.bindMethod(this, B5500CardPunch.prototype.punchOnload), false); } B5500CardPunch.prototype.cardsPerMinute = 300; // Punch speed B5500CardPunch.prototype.msPerCard = 60000/B5500CardPunch.prototype.cardsPerMinute; B5500CardPunch.prototype.maxScrollLines = 850; // Maximum punch stacker scrollback (stacker capacity) B5500CardPunch.prototype.rtrimRex = /\s+$/g; // regular expression for right-trimming card text /**************************************/ B5500CardPunch.prototype.$$ = function $$(e) { return this.doc.getElementById(e); }; /**************************************/ B5500CardPunch.prototype.clear = function clear() { /* Initializes (and if necessary, creates) the punch unit state */ this.ready = false; // ready status this.busy = false; // busy status this.errorMask = 0; // error mask for finish() this.finish = null; // external function to call for I/O completion this.runoutArmed = false; // EOF button: armed state this.stacker1Count = 0; // cards in stacker #1 this.stacker2Count = 0; // cards in stacker #2 }; /**************************************/ B5500CardPunch.prototype.emptyStacker = function emptyStacker(stacker) { /* Empties the stacker of all text lines */ while (stacker.firstChild) { stacker.removeChild(stacker.firstChild); } }; /**************************************/ B5500CardPunch.prototype.copyStacker = function copyStacker(ev) { /* Copies the text contents of a "stacker" area of the device, opens a new temporary window, and pastes that text into the window so it can be copied or saved by the user */ var stacker = ev.target; var text = stacker.textContent; var title = "B5500 " + this.mnemonic + " Stacker Snapshot"; var win = window.open("./B5500FramePaper.html", this.mnemonic + "-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; doc = win.document; doc.title = title; doc.getElementById("Paper").textContent = text; }); this.emptyStacker(stacker); ev.preventDefault(); ev.stopPropagation(); }; /**************************************/ B5500CardPunch.prototype.setPunchReady = function setPunchReady(ready) { /* Controls the ready-state of the card punch */ if (ready && !this.ready) { this.statusChange(1); B5500Util.addClass(this.$$("CPStartBtn"), "greenLit") B5500Util.removeClass(this.$$("CPNotReadyLight"), "whiteLit"); this.ready = true; if (this.runoutArmed) { if (this.stacker1Count || this.stacker2Count) { if (this.window.confirm("Empty both " + this.mnemonic + " stackers?")) { this.stacker1Count = this.stacker2Count = 0; this.$$("CPStacker1Bar").value = 0; B5500Util.removeClass(this.$$("CPStacker1Full"), "annunciatorLit"); this.emptyStacker(stacker1); this.$$("CPStacker2Bar").value = 0; B5500Util.removeClass(this.$$("CPStacker2Full"), "annunciatorLit"); this.emptyStacker(stacker2); } } this.armRunout(false); } } else if (!ready && this.ready) { this.statusChange(0); B5500Util.removeClass(this.$$("CPStartBtn"), "greenLit") B5500Util.addClass(this.$$("CPNotReadyLight"), "whiteLit"); this.ready = false; } }; /**************************************/ B5500CardPunch.prototype.setAlgolGlyphs = function setAlgolGlyphs(makeItPretty) { /* Controls the display of Unicode glyphs for the special Algol characters */ if (makeItPretty) { if (!this.useAlgolGlyphs) { B5500Util.xlateDOMTreeText(this.stacker1, B5500Util.xlateASCIIToAlgol); B5500Util.xlateDOMTreeText(this.stacker2, B5500Util.xlateASCIIToAlgol); } } else { if (this.useAlgolGlyphs) { B5500Util.xlateDOMTreeText(this.stacker1, B5500Util.xlateAlgolToASCII); B5500Util.xlateDOMTreeText(this.stacker2, B5500Util.xlateAlgolToASCII); } } this.$$("CPAlgolGlyphsCheck").checked = makeItPretty; this.useAlgolGlyphs = makeItPretty; }; /**************************************/ B5500CardPunch.prototype.appendLine = function appendLine(stacker, text) { /* Appends a new
element to the