mirror of
https://github.com/pkimpel/retro-b5500.git
synced 2026-01-12 00:42:59 +00:00
571 lines
22 KiB
JavaScript
571 lines
22 KiB
JavaScript
/***********************************************************************
|
|
* retro-b5500/emulator B5500CardReader.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 Reader Peripheral Unit module.
|
|
*
|
|
* Defines a card reader peripheral unit type.
|
|
*
|
|
************************************************************************
|
|
* 2013-06-05 P.Kimpel
|
|
* Original version, from B5500SPOUnit.js.
|
|
***********************************************************************/
|
|
"use strict";
|
|
|
|
/**************************************/
|
|
function B5500CardReader(mnemonic, unitIndex, designate, statusChange, signal, options) {
|
|
/* Constructor for the CardReader object */
|
|
var x = (mnemonic == "CRA" ? 0 : 1)*110;
|
|
|
|
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.clear();
|
|
|
|
this.doc = null;
|
|
this.window = null;
|
|
this.keyinWindow = null;
|
|
B5500Util.openPopup(window, "../webUI/B5500CardReader.html", mnemonic,
|
|
"location=no,scrollbars=no,resizable,width=560,height=160,left=0,top="+x,
|
|
this, B5500CardReader.prototype.readerOnload);
|
|
|
|
this.hopperBar = null;
|
|
this.outHopperFrame = null;
|
|
this.outHopper = null;
|
|
}
|
|
|
|
B5500CardReader.prototype.eolRex = /([^\n\r\f]*)((:?\r[\n\f]?)|\n|\f)?/g;
|
|
|
|
B5500CardReader.prototype.cardsPerMinute = 1400; // B129 card reader
|
|
B5500CardReader.prototype.msPerCard = 60000/B5500CardReader.prototype.cardsPerMinute;
|
|
|
|
B5500CardReader.prototype.cardFilter = [ // Filter ASCII character values to valid BIC ones
|
|
0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, // 00-0F
|
|
0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, // 10-1F
|
|
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x3F,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, // 20-2F
|
|
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F, // 30-3F
|
|
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, // 40-4F
|
|
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x3F,0x5D,0x3F,0x7E, // 50-5F
|
|
0x3F,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, // 60-6F
|
|
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x7B,0x7C,0x7D,0x7E,0x3F]; // 70-7F
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.clear = function clear() {
|
|
/* Initializes (and if necessary, creates) the reader 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.buffer = ""; // Card reader "input hopper"
|
|
this.bufLength = 0; // Current input buffer length (characters)
|
|
this.bufIndex = 0; // 0-relative offset to next "card" to be read
|
|
this.eofArmed = false; // EOF button: armed state
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.$$ = function $$(e) {
|
|
return this.doc.getElementById(e);
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.appendDeckText = function appendDeckText(text) {
|
|
/* Appends "text" to the card reader "input stacker" buffer, discards any
|
|
portion of the buffer that has already been read, and updates the hopper
|
|
progress bar */
|
|
|
|
if (this.bufIndex >= this.bufLength) {
|
|
this.buffer = text;
|
|
} else {
|
|
switch (this.buffer.charAt(this.buffer.length-1)) {
|
|
case "\r":
|
|
case "\n":
|
|
case "\f":
|
|
break; // do nothing -- the last card has a delimiter
|
|
default:
|
|
this.buffer += "\n"; // so the next deck starts on a new line
|
|
break;
|
|
}
|
|
this.buffer = this.buffer.substring(this.bufIndex) + text;
|
|
}
|
|
|
|
this.bufIndex = 0;
|
|
this.bufLength = this.buffer.length;
|
|
if (this.bufLength > 0) {
|
|
this.$$("CRHopperBar").value = this.bufLength;
|
|
this.$$("CRHopperBar").max = this.bufLength;
|
|
}
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.setReaderReady = function setReaderReady(ready) {
|
|
/* Controls the ready-state of the card reader */
|
|
|
|
this.$$("CRFileSelector").disabled = ready;
|
|
this.ready = ready;
|
|
if (ready) {
|
|
this.statusChange(1);
|
|
this.$$("CRStartBtn").classList.add("greenLit")
|
|
this.$$("CRNotReadyLight").classList.remove("whiteLit");
|
|
this.$$("CRKeyinDeckBtn").disabled = true;
|
|
this.$$("CRKeyinDeckBtn").classList.remove("whiteLit");
|
|
} else {
|
|
this.statusChange(0);
|
|
this.$$("CRStartBtn").classList.remove("greenLit")
|
|
this.$$("CRNotReadyLight").classList.add("whiteLit");
|
|
this.$$("CRKeyinDeckBtn").disabled = false;
|
|
this.$$("CRKeyinDeckBtn").classList.add("whiteLit");
|
|
}
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.armEOF = function armEOF(armed) {
|
|
/* Controls the arming/disarming of the EOF signal when starting with
|
|
an empty input hopper */
|
|
|
|
this.eofArmed = armed;
|
|
if (armed) {
|
|
this.$$("CREOFBtn").classList.add("whiteLit");
|
|
} else {
|
|
this.$$("CREOFBtn").classList.remove("whiteLit");
|
|
}
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.CRStartBtn_onClick = function CRStartBtn_onClick(ev) {
|
|
/* Handle the click event for the START button */
|
|
|
|
if (!this.ready) {
|
|
if (this.bufIndex < this.bufLength) {
|
|
this.setReaderReady(true);
|
|
}
|
|
}
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.CRStopBtn_onClick = function CRStopBtn_onClick(ev) {
|
|
/* Handle the click event for the STOP button */
|
|
|
|
this.$$("CRFileSelector").value = null; // reset the control so the same file can be reloaded
|
|
if (this.ready) {
|
|
this.setReaderReady(false);
|
|
} else if (this.eofArmed) {
|
|
this.armEOF(false);
|
|
}
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.CREOFBtn_onClick = function CREOFBtn_onClick(ev) {
|
|
/* Handle the click event for the EOF button */
|
|
|
|
this.armEOF(!this.eofArmed);
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.CRKeyinDeckBtn_onClick = function CRKeyinDeckBtn_onClick(ev) {
|
|
/* Handler for the click event for the Insert Deck button on the reader window */
|
|
var cr = this; // this B5500CardReader instance
|
|
var $$$ = null; // getElementById shortcut for keyin window
|
|
var doc = null; // loader window.document
|
|
var keyinText = null; // keyin text area
|
|
var win = null;
|
|
|
|
function keyinCancelDeck(ev) {
|
|
/* Handler for the Cancel button on the deck keyin window -- closes it */
|
|
|
|
win.close();
|
|
}
|
|
|
|
function keyinInsertDeck(ev) {
|
|
/* Handler for the Insert buttons on the deck keyin window -- extracts the
|
|
text from the window and appends it to the reader's "input stacker" buffer */
|
|
|
|
switch (ev.target) {
|
|
case $$$("CRKeyinControlDeckBtn"):
|
|
keyinText.value += "?LABEL 0CONTROL0DECK\n";
|
|
keyinText.focus();
|
|
break;
|
|
case $$$("CRKeyinEndControlBtn"):
|
|
keyinText.value += "?END CONTROL\n";
|
|
keyinText.focus();
|
|
break;
|
|
case $$$("CRKeyinEndCardBtn"):
|
|
keyinText.value += "?END\n";
|
|
keyinText.focus();
|
|
break;
|
|
default:
|
|
cr.appendDeckText(keyinText.value);
|
|
win.close();
|
|
break;
|
|
} // switch ev.target
|
|
}
|
|
|
|
function keyinOnload(ev) {
|
|
/* On-load handler for the deck keyin window */
|
|
var de;
|
|
|
|
doc = ev.target;
|
|
win = doc.defaultView;
|
|
this.keyinWindow = win;
|
|
de = doc.documentElement;
|
|
this.$$("CRStartBtn").disabled = true;
|
|
this.$$("CRKeyinDeckBtn").disabled = true;
|
|
this.$$("CRKeyinDeckBtn").classList.remove("whiteLit");
|
|
$$$ = function $$$(id) {
|
|
return doc.getElementById(id);
|
|
};
|
|
|
|
doc.title = "B5500 " + cr.mnemonic + " Deck Keyin";
|
|
|
|
keyinText = $$$("CRKeyinText")
|
|
keyinText.focus();
|
|
$$$("CRKeyinControlDeckBtn").addEventListener("click", keyinInsertDeck, false);
|
|
$$$("CRKeyinEndControlBtn").addEventListener("click", keyinInsertDeck, false);
|
|
$$$("CRKeyinEndCardBtn").addEventListener("click", keyinInsertDeck, false);
|
|
$$$("CRKeyinInsertBtn").addEventListener("click", keyinInsertDeck, false);
|
|
$$$("CRKeyinCancelBtn").addEventListener("click", keyinCancelDeck, false);
|
|
win.addEventListener("unload", keyinOnUnload, false);
|
|
|
|
win.resizeBy(de.scrollWidth - win.innerWidth,
|
|
de.scrollHeight - win.innerHeight);
|
|
}
|
|
|
|
function keyinOnUnload(ev) {
|
|
/* On-unload handler for the deck keyin window */
|
|
|
|
$$$("CRKeyinControlDeckBtn").removeEventListener("click", keyinInsertDeck, false);
|
|
$$$("CRKeyinEndControlBtn").removeEventListener("click", keyinInsertDeck, false);
|
|
$$$("CRKeyinEndCardBtn").removeEventListener("click", keyinInsertDeck, false);
|
|
$$$("CRKeyinInsertBtn").removeEventListener("click", keyinInsertDeck, false);
|
|
$$$("CRKeyinCancelBtn").removeEventListener("click", keyinCancelDeck, false);
|
|
win.removeEventListener("unload", keyinOnUnload, false);
|
|
|
|
keyinText = null;
|
|
cr.keyinWindow = null;
|
|
cr.$$("CRStartBtn").disabled = false;
|
|
cr.$$("CRKeyinDeckBtn").disabled = false;
|
|
cr.$$("CRKeyinDeckBtn").classList.add("whiteLit");
|
|
|
|
}
|
|
|
|
// Outer block of loadTape
|
|
if (this.keyinWindow && !this.keyinWindow.closed) {
|
|
this.keyinWindow.close();
|
|
}
|
|
|
|
B5500Util.openPopup(this.window, "B5500CardReaderKeyin.html", this.mnemonic + "-Keyin",
|
|
"location=no,scrollbars=no,resizable,width=640,height=240,left=" +
|
|
(this.window.screenX+32) +",top=" + (this.window.screenY+32),
|
|
this, keyinOnload);
|
|
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.CRHopperBar_onClick = function CRHopperBar_onClick(ev) {
|
|
/* Handle the click event for the "input hopper" meter bar */
|
|
|
|
if (this.bufIndex < this.bufLength && !this.ready) {
|
|
if (this.window.confirm((this.bufLength-this.bufIndex).toString() + " of " + this.bufLength.toString() +
|
|
" characters remaining to read.\nDo you want to clear the input hopper?")) {
|
|
this.buffer = "";
|
|
this.bufLength = 0;
|
|
this.bufIndex = 0;
|
|
this.hopperBar.value = 0;
|
|
this.$$("CRFileSelector").value = null; // reset the control
|
|
while (this.outHopper.childNodes.length > 0) {
|
|
this.outHopper.removeChild(this.outHopper.firstChild);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.fileSelector_onChange = function fileSelector_onChange(ev) {
|
|
/* Handle the <input type=file> onchange event when files are selected. For each
|
|
file, load it and add it to the "input hopper" of the reader */
|
|
var f = ev.target.files;
|
|
var that = this;
|
|
var index = 0;
|
|
|
|
function fileLoader_onLoad(ev) {
|
|
/* Handle the onload event for a Text FileReader and advances to the next
|
|
selected deck, if any */
|
|
|
|
that.appendDeckText(ev.target.result);
|
|
if (++index < f.length) {
|
|
loadDeck(index);
|
|
}
|
|
}
|
|
|
|
function loadDeck(x) {
|
|
/* Initiates the load for the selected file indicated by "x" */
|
|
var deck;
|
|
|
|
deck = new FileReader();
|
|
deck.onload = fileLoader_onLoad;
|
|
deck.readAsText(f[x]);
|
|
}
|
|
|
|
loadDeck(index);
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.readCardAlpha = function readCardAlpha(buffer, length) {
|
|
/* Reads one card image from the buffer in alpha mode; pads or trims the
|
|
image as necessary to the I/O buffer length. Invalid BCL characters are
|
|
translated to ASCII "?" and the invalid character bit is set in the errorMask.
|
|
Returns the raw card image as a string */
|
|
var c; // current character
|
|
var card; // card image
|
|
var cardLength; // length of card image
|
|
var match; // result of eolRex.exec()
|
|
var x; // for loop index
|
|
|
|
this.eolRex.lastIndex = this.bufIndex;
|
|
match = this.eolRex.exec(this.buffer);
|
|
if (!match) {
|
|
card = "";
|
|
cardLength = 0;
|
|
} else {
|
|
this.bufIndex += match[0].length;
|
|
card = match[1];
|
|
cardLength = card.length;
|
|
if (length < cardLength) {
|
|
cardLength = length;
|
|
}
|
|
for (x=0; x<cardLength; x++) {
|
|
c = card.charCodeAt(x);
|
|
if (c == 0x3F) { // an actual "?"
|
|
buffer[x] = 0x3F;
|
|
if (x == 0) { // it's an invalid char only if in first column
|
|
this.errorMask |= 0x08;
|
|
}
|
|
} else if (c > 0x7F) { // possibly a Unicode Algol glyph
|
|
switch (c) {
|
|
case 0x00A0: buffer[x] = 0x20; break; // non-breaking space
|
|
case 0x00D7: buffer[x] = 0x7C; break; // multiply
|
|
case 0x2190: buffer[x] = 0x7E; break; // left-arrow
|
|
case 0x2260: buffer[x] = 0x21; break; // not-equal
|
|
case 0x2264: buffer[x] = 0x7B; break; // less-than-or-equal
|
|
case 0x2265: buffer[x] = 0x7D; break; // greater-than-or-equal
|
|
default:
|
|
buffer[x] = 0x3F;
|
|
this.errorMask |= 0x08;
|
|
break;
|
|
}
|
|
} else if ((buffer[x] = this.cardFilter[c]) == 0x3F) { // intentional assignment
|
|
this.errorMask |= 0x08;
|
|
}
|
|
}
|
|
}
|
|
|
|
while (cardLength < length) {
|
|
buffer[cardLength++] = 0x20; // pad with spaces
|
|
}
|
|
|
|
return card;
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.readCardBinary = function readCardBinary(buffer, length) {
|
|
/* Reads one card image from the buffer in binary mode; pads or trims the
|
|
image as necessary to the I/O buffer length. Invalid BCL characters are
|
|
translated to ASCII "?", but are not reported in the errorMask.
|
|
Returns the raw card image as a string */
|
|
var card; // card image
|
|
var cardLength; // length of card image
|
|
var match; // result of eolRex.exec()
|
|
var x; // for loop index
|
|
|
|
this.eolRex.lastIndex = this.bufIndex;
|
|
match = this.eolRex.exec(this.buffer);
|
|
if (!match) {
|
|
card = "";
|
|
cardLength = 0;
|
|
} else {
|
|
this.bufIndex += match[0].length;
|
|
card = match[1];
|
|
cardLength = card.length;
|
|
if (length < cardLength) {
|
|
cardLength = length;
|
|
}
|
|
for (x=0; x<cardLength; x++) {
|
|
buffer[x] = this.cardFilter[card.charCodeAt(x) & 0x7F];
|
|
}
|
|
}
|
|
|
|
while (cardLength < length) {
|
|
buffer[cardLength++] = 0x30; // pad with ASCII zeroes
|
|
}
|
|
|
|
return card;
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.beforeUnload = function beforeUnload(ev) {
|
|
var msg = "Closing this window will make the device unusable.\n" +
|
|
"Suggest you stay on the page and minimize this window instead";
|
|
|
|
ev.preventDefault();
|
|
ev.returnValue = msg;
|
|
return msg;
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.readerOnload = function readerOnload(ev) {
|
|
/* Initializes the reader window and user interface */
|
|
var de;
|
|
|
|
this.doc = ev.target;
|
|
this.window = this.doc.defaultView;
|
|
de = this.doc.documentElement;
|
|
this.doc.title = "retro-B5500 Card Reader " + this.mnemonic;
|
|
|
|
this.hopperBar = this.$$("CRHopperBar");
|
|
this.outHopperFrame = this.$$("CROutHopperFrame");
|
|
this.outHopper = this.outHopperFrame.contentDocument.getElementById("Paper");
|
|
|
|
this.armEOF(false);
|
|
this.setReaderReady(false);
|
|
|
|
this.window.addEventListener("beforeunload",
|
|
B5500CardReader.prototype.beforeUnload, false);
|
|
this.$$("CRFileSelector").addEventListener("change",
|
|
B5500CardReader.prototype.fileSelector_onChange.bind(this), false);
|
|
this.$$("CRStartBtn").addEventListener("click",
|
|
B5500CardReader.prototype.CRStartBtn_onClick.bind(this), false);
|
|
this.$$("CRStopBtn").addEventListener("click",
|
|
B5500CardReader.prototype.CRStopBtn_onClick.bind(this), false);
|
|
this.$$("CREOFBtn").addEventListener("click",
|
|
B5500CardReader.prototype.CREOFBtn_onClick.bind(this), false);
|
|
this.$$("CRKeyinDeckBtn").addEventListener("click",
|
|
B5500CardReader.prototype.CRKeyinDeckBtn_onClick.bind(this), false);
|
|
this.hopperBar.addEventListener("click",
|
|
B5500CardReader.prototype.CRHopperBar_onClick.bind(this), false);
|
|
|
|
this.window.resizeBy(de.scrollWidth - this.window.innerWidth + 4, // kludge for right-padding/margin
|
|
de.scrollHeight - this.window.innerHeight);
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.read = function read(finish, buffer, length, mode, control) {
|
|
/* Initiates a read operation on the unit. If the reader is not ready and the input
|
|
buffer is empty and EOF is armed, returns EOF; otherwise if not ready,
|
|
returns Not Ready */
|
|
var card;
|
|
|
|
this.errorMask = 0;
|
|
if (this.busy) {
|
|
finish(0x01, 0); // report unit busy
|
|
} else if (!this.ready) {
|
|
if (this.eofArmed && this.bufIndex >= this.bufLength) {
|
|
this.armEOF(false);
|
|
finish(0x24, 0); // report unit EOF + not ready
|
|
} else {
|
|
finish(0x04, 0); // report unit not ready
|
|
}
|
|
} else {
|
|
this.busy = true;
|
|
if (mode == 0) {
|
|
card = this.readCardAlpha(buffer, length);
|
|
} else {
|
|
card = this.readCardBinary(buffer, length);
|
|
}
|
|
|
|
this.timer = setCallback(this.mnemonic, this,
|
|
this.msPerCard + this.initiateStamp - performance.now(),
|
|
function readDelay() {
|
|
this.busy = false;
|
|
finish(this.errorMask, length);
|
|
});
|
|
|
|
if (this.bufIndex < this.bufLength) {
|
|
this.hopperBar.value = this.bufLength-this.bufIndex;
|
|
} else {
|
|
this.hopperBar.value = 0;
|
|
this.buffer = ""; // discard the input buffer
|
|
this.bufLength = 0;
|
|
this.bufIndex = 0;
|
|
this.setReaderReady(false);
|
|
this.$$("CRFileSelector").value = null; // reset the control so the same file can be reloaded
|
|
}
|
|
|
|
while (this.outHopper.childNodes.length > 1) {
|
|
this.outHopper.removeChild(this.outHopper.firstChild);
|
|
}
|
|
this.outHopper.appendChild(this.doc.createTextNode("\n"));
|
|
this.outHopper.appendChild(this.doc.createTextNode(card));
|
|
}
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.space = function space(finish, length, control) {
|
|
/* Initiates a space operation on the unit */
|
|
|
|
finish(0x04, 0); // report unit not ready
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.write = function write(finish, buffer, length, mode, control) {
|
|
/* Initiates a write operation on the unit */
|
|
|
|
finish(0x04, 0); // report unit not ready
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.erase = function erase(finish, length) {
|
|
/* Initiates an erase operation on the unit */
|
|
|
|
finish(0x04, 0); // report unit not ready
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.rewind = function rewind(finish) {
|
|
/* Initiates a rewind operation on the unit */
|
|
|
|
finish(0x04, 0); // report unit not ready
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.readCheck = function readCheck(finish, length, control) {
|
|
/* Initiates a read check operation on the unit */
|
|
|
|
finish(0x04, 0); // report unit not ready
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.readInterrogate = function readInterrogate(finish, control) {
|
|
/* Initiates a read interrogate operation on the unit */
|
|
|
|
finish(0x04, 0); // report unit not ready
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.writeInterrogate = function writeInterrogate(finish, control) {
|
|
/* Initiates a write interrogate operation on the unit */
|
|
|
|
finish(0x04, 0); // report unit not ready
|
|
};
|
|
|
|
/**************************************/
|
|
B5500CardReader.prototype.shutDown = function shutDown() {
|
|
/* Shuts down the device */
|
|
|
|
if (this.timer) {
|
|
clearCallback(this.timer);
|
|
}
|
|
this.window.removeEventListener("beforeunload", B5500CardReader.prototype.beforeUnload, false);
|
|
this.window.close();
|
|
};
|