1
0
mirror of https://github.com/pkimpel/retro-220.git synced 2026-01-13 15:18:24 +00:00
pkimpel.retro-220/webUI/B220MagTapeControl.js

757 lines
32 KiB
JavaScript

/***********************************************************************
* retro-220/webUI B220MagTapeControl.js
************************************************************************
* Copyright (c) 2017, Paul Kimpel.
* Licensed under the MIT License, see
* http://www.opensource.org/licenses/mit-license.php
************************************************************************
* Burroughs 220 MagTape Control unit module.
************************************************************************
* 2017-07-09 P.Kimpel
* Original version, from retro-205 D205MagTapeControl.js.
***********************************************************************/
"use strict";
/**************************************/
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 u; // unit configuration object
var x; // unit index
this.config = p.config; // System configuration object
this.mnemonic = "MCU";
this.p = p; // B220Processor object
// Do not call this.clear() here -- call this.clearUnit() from onLoad instead
this.doc = null;
this.window = window.open("../webUI/B220MagTapeControl.html", this.mnemonic,
"location=no,scrollbars=no,resizable,width=712,height=144,top=" +
(screen.availHeight - top) + ",left=" + left);
this.window.addEventListener("load",
B220Util.bindMethod(this, B220MagTapeControl.prototype.magTapeOnLoad));
this.boundControlFinished = B220Util.bindMethod(this, B220MagTapeControl.prototype.controlFinished);
this.boundTapeUnitFinished = B220Util.bindMethod(this, B220MagTapeControl.prototype.tapeUnitFinished);
this.boundSwitch_Click = B220Util.bindMethod(this, B220MagTapeControl.prototype.switch_Click);
this.currentUnit = null; // stashed tape unit object
/* Set up the tape units from the system configuration. These can be any
combination of Tape Storage Units (DataReaders) and DataFiles. The indexes
into this array are physical unit numbers used internally -- unit designate
is set on the tape unit itself */
this.tapeUnit = [
null, // 0=not used
null, // tape unit A
null, // tape unit B
null, // tape unit C
null, // tape unit D
null, // tape unit E
null, // tape unit F
null, // tape unit G
null, // tape unit H
null, // tape unit I
null]; // tape unit J
for (x=1; x<this.tapeUnit.length; ++x) {
u = this.config.getNode("MagTape.units", x);
switch (u.type.substring(0, 2)) {
case "MT":
this.tapeUnit[x] = new B220MagTapeDrive(u.type, x, this, this.config);
break;
case "DF":
this.tapeUnit[x] = new B220DataFile(u.type, x, this, this.config);
break;
default:
this.tapeUnit[x] = null;
break;
} // switch u.type
} // for x
}
/**************************************/
B220MagTapeControl.prototype.$$ = function $$(e) {
return this.doc.getElementById(e);
};
/**************************************/
B220MagTapeControl.prototype.clear = function clear() {
/* Initializes (and if necessary, creates) the panel state */
this.C = 0; // C register (unit, block count, etc.)
this.T = 0; // T register
this.unitNr = 0; // current unit number from command
this.unitIndex = 0; // current index into this.tapeUnit[]
this.blockWords = 0; // number of words/block for current operation
this.controlBusy = false; // control unit is busy with read/write/search
this.pendingCallee = null; // method to call for a pending operation
this.pendingArgs = null; // Arguments object for a pending operation
};
/**************************************/
B220MagTapeControl.prototype.findDesignate = function findDesignate(u) {
/* Searches this.tapeUnit[] to find the internal index of the unit that is
designated as "u". If found, returns the internal index; if not found,
returns -1. If more than one ready unit with the same designate is found,
returns -2 */
var index = -1;
var unit;
var x;
for (x=this.tapeUnit.length-1; x>=0; --x) {
unit = this.tapeUnit[x];
if (unit && unit.ready) {
if (unit.unitDesignate == u) {
if (index == -1) {
index = x;
} else {
index = -2;
break; // out of for loop
}
}
}
} // for x
return index;
};
/**************************************/
B220MagTapeControl.prototype.queuePendingOperation = function queuePendingOperation(callee, args) {
/* Queues a pending tape operation */
//console.log(this.mnemonic + " queuePendingOperation: " + args[0].toString(16));
if (this.pendingCallee !== null) {
throw new Error("More than one pending tape control operation");
}
this.pendingCallee = callee;
this.pendingArgs = args;
};
/**************************************/
B220MagTapeControl.prototype.dequeuePendingOperation = function dequeuePendingOperation() {
/* Dequeues and reinitiates a pending tape operation */
var args = this.pendingArgs; // pending Arguments object
var callee = this.pendingCallee; // pending method to call
this.pendingCallee = this.pendingArgs = null;
callee.apply(this, args);
};
/**************************************/
B220MagTapeControl.prototype.loadCommand = function loadCommand(dReg, releaseProcessor, callee, args) {
/* If the control unit or the tape unit addressed by the unit field in dReg
are currently busy, queues the args parameter (an Arguments object) in
this.pendingCallee and -Args, and returns false. If the control is idle but
the tape unit is not ready or not present, or two units have the same designate,
calls the releaseProcessor call-back and returns false. If the control and
tape unit are ready for their next operation, loads the contents of the processor's
D register passed to the operation routines into the T, C, and MISC registers.
Sets this.unitNr, this.unitIndex, and this.blockWords from the digits in T.
Sets this.currentUnit to the current tape unit object. Then returns true */
var c; // scratch
var t = dReg%0x10000000000; // scratch
var ux; // internal unit index
var result = false; // return value
//console.log(this.mnemonic + " loadCommand: " + dReg.toString(16));
if (this.controlBusy) {
this.queuePendingOperation(callee, args);
} else {
this.T = t;
this.unitNr = (t - t%0x1000000000)/0x1000000000;
t = (t - t%0x10000)/0x10000;
c = t%0x10; // low-order digit of op code
t = (t - t%0x100)/0x100; // control digits from instruction
this.blockWords = t%0x100;
if (this.blockWords > 0) {
this.blockWords = B220Processor.bcdBinary(this.blockWords);
} else {
this.blockWords = 100;
}
this.C = this.unitNr*0x100000 + t*0x10 + c;
this.clearMisc();
this.regC.update(this.C);
this.regT.update(this.T);
this.unitIndex = ux = this.findDesignate(this.unitNr);
if (ux < 0) {
this.reportStatus(2); // drive not ready, not present
setCallback(this.mnemonic, this, 0, releaseProcessor, true);
} else {
this.currentUnit = this.tapeUnit[ux];
if (this.currentUnit.busy || this.currentUnit.rewindLock) {
this.queuePendingOperation(callee, args);
} else {
result = true;
}
}
}
return result;
};
/**************************************/
B220MagTapeControl.prototype.controlFinished = function controlFinished(alarm) {
/* Releases the busy status of the control. Typically used as a timed call-
back to simulate the amount of time the control unit is busy with an I/O.
If alarm is true, sets the Processor's Magnetic Tape Check alarm.
If another operation is pending, initiates that operation */
//console.log(this.mnemonic + " controlFinished: " + alarm + ", busy=" + this.controlBusy);
if (alarm) {
this.p.setMagneticTapeCheck(true);
}
this.controlBusy = false;
if (this.pendingCallee !== null) {
this.dequeuePendingOperation();
}
};
/**************************************/
B220MagTapeControl.prototype.tapeUnitFinished = function tapeUnitFinished() {
/* Call-back function passed to tape unit methods to signal when the unit has
completed its asynchronous operation */
if (!this.controlBusy) { // if the control unit is currently idle...
if (this.pendingCallee !== null) {
this.dequeuePendingOperation();
}
}
};
/**************************************/
B220MagTapeControl.prototype.decrementBlockCount = function decrementBlockCount() {
/* Decrements the block-count digit in the C register. Returns true if the
remaining block count is non-zero, false otherwise */
var c1 = this.C; // will hold two high-order digits of C: uu0000
var c2 = c1%0x10000; // four low-order digits of C: bddd, b=block count
var result = true;
c1 -= c2;
if (c2 < 0x1000) {
c2 += 0x9000; // decrement 0x0ddd to 0x9ddd as count=0 => 10
} else {
c2 -= 0x1000; // decrement 0xddd..0x9ddd
if (c2 < 0x1000) {
result = false; // decremented 0x1ddd to 0x0ddd: no more blocks
}
}
this.C = c1+c2;
this.regC.update(this.C);
return result;
};
/**************************************/
B220MagTapeControl.prototype.clearMisc = function clearMisc() {
/* Resets this.regMisc and the individual lamps for that register */
var bitNr;
var m = this.regMisc;
m.update(0);
for (bitNr=m.bits-1; bitNr>= 0; --bitNr) {
m.lamps[bitNr].set(0);
}
};
/**************************************/
B220MagTapeControl.prototype.reportStatus = function reportStatus(code) {
/* Sets bits in the MISC register to indicate various drive and control unit
status and error conditions */
switch (code) {
case 1: // report tape unit ready
this.TX2Lamp.set(0);
this.TX10Lamp.set(0);
break;
case 2: // report tape unit not ready
this.TX2Lamp.set(1);
this.TX10Lamp.set(1);
break;
case 4: // read check
this.TYC1Lamp.set(1);
this.TYC2Lamp.set(1);
break;
} // switch code
};
/**************************************/
B220MagTapeControl.prototype.switch_Click = function switch_Click(ev) {
/* Handle the click event for buttons and switches */
switch(ev.target.id) {
case "ClearBtn":
this.clearUnit();
break;
case "Misc_RightClear":
this.clearMisc();
break;
case "C_RightClear":
this.C = 0;
this.regC.update(0);
break;
case "T_RightClear":
this.T = 0;
this.regT.update(0);
break;
} // switch target.id
};
/**************************************/
B220MagTapeControl.prototype.beforeUnload = function beforeUnload(ev) {
var msg = "Closing this window will make the panel unusable.\n" +
"Suggest you stay on the page and minimize this window instead";
ev.preventDefault();
ev.returnValue = msg;
return msg;
};
/**************************************/
B220MagTapeControl.prototype.magTapeOnLoad = function magTapeOnLoad() {
/* Initializes the MagTape Control window and user interface */
var body;
var box;
var e;
var x;
this.doc = this.window.document;
body = this.$$("PanelSurface");
// Misc Register
this.regMisc = new PanelRegister(this.$$("MiscRegPanel"), 4*4, 4, "Misc_", " ");
this.regMisc.lamps[15].setCaption("MCL", true);
this.regMisc.lamps[14].setCaption("MC6", true);
this.TYC1Lamp = this.regMisc.lamps[13];
this.TYC1Lamp.setCaption("TYC", true);
this.TYC2Lamp = this.regMisc.lamps[12];
this.TYC2Lamp.setCaption("TYC", true);
this.TCFLamp = this.regMisc.lamps[10]; // not in this physical position on a 220
this.TCFLamp.setCaption("TCF", true);
this.TPCLamp = this.regMisc.lamps[7];
this.TPCLamp.setCaption("TPC", true);
this.regMisc.lamps[6].setCaption("TSX", true);
this.regMisc.lamps[5].setCaption("1R6", true);
this.TX1Lamp = this.regMisc.lamps[4];
this.TX1Lamp.setCaption("TX1", true);
this.TX10Lamp = this.regMisc.lamps[3];
this.TX10Lamp.setCaption("TX10", true);
this.TX8Lamp = this.regMisc.lamps[2];
this.TX8Lamp.setCaption("TX8", true);
this.TX4Lamp = this.regMisc.lamps[1];
this.TX4Lamp.setCaption("TX4", true);
this.TX2Lamp = this.regMisc.lamps[0];
this.TX2Lamp.setCaption("TX2", true);
// Full Registers
this.regC = new PanelRegister(this.$$("CRegPanel"), 6*4, 4, "C_", "C");
this.regT = new PanelRegister(this.$$("TRegPanel"), 10*4, 4, "T_", "T");
// Events
this.window.addEventListener("beforeunload", B220MagTapeControl.prototype.beforeUnload);
this.$$("ClearBtn").addEventListener("click", this.boundSwitch_Click, false);
this.regMisc.rightClearBar.addEventListener("click", this.boundSwitch_Click, false);
this.regC.rightClearBar.addEventListener("click", this.boundSwitch_Click, false);
this.regT.rightClearBar.addEventListener("click", this.boundSwitch_Click, false);
this.clearUnit();
};
/**************************************/
B220MagTapeControl.prototype.search = function search(dReg, releaseProcessor, bReg, fetchWord) {
/* Searches a tape unit for a block with a keyWord matching the word at the
operand address in memory. "bReg is the contents of the B register for a
search, or 0 for a full-word search. This routine is used by MTS and MFS */
var alarm = false; // error result
var blocksLeft = true; // true => more blocks to process
var searchWord; // target word to search for
var that = this; // local self-reference
function signalControl(controlWord) {
/* Call-back function to send the EOT or control word to the Processor
and release it for the next operation */
releaseProcessor(false, true, controlWord);
}
function blockReady(alarm, control, controlWord, readBlock, completed) {
/* Call-back function when the drive is ready to send the next block
of data, or when it has encountered an error such as EOT. "alarm"
indicates that an error has occurred and the operation is to be aborted.
"control" inidicates that an EOT or control block was encountered, and
"controlWord" is to be passed to the Processor for handling. Otherwise,
if there are more blocks to write, fetches the next block from the
Processor and calls the drive's "readBlock" function, Finally calls
"completed" to finish the operation */
if (alarm) {
setCallback(that.mnemonic, that, 0, releaseProcessor, true);
completed(true); // drive detected an error
} else if (control) {
setCallback(that.mnemonic, that, 0, signalControl, controlWord);
completed(false);
} else if (blocksLeft) {
blocksLeft = that.decrementBlockCount(); // set to false on last block
readBlock(storeWord, record, controlEnabled);// read the next block
} else {
setCallback(that.mnemonic, that, 0, releaseProcessor, false);
completed(false); // normal termination
}
}
if (this.loadCommand(dReg, releaseProcessor, search, arguments)) {
this.controlBusy = true;
searchWord = fetchWord(true);
if (searchWord < 0) {
alarm = true;
} else {
alarm = this.currentUnit.searchBlock(blockReady, this.boundControlFinished);
}
if (alarm) {
setCallback(this.mnemonic, this, 0, releaseProcessor, alarm);
this.controlFinished(true);
}
}
};
/**************************************/
B220MagTapeControl.prototype.read = function read(dReg, releaseProcessor, record, storeWord) {
/* Reads the number of blocks indicated in dReg. If "record" is true (MRR),
block lengths (preface words) are stored into the word in memory preceding
the data read from tape. "storeWord" is a function to store a word to the
Processor's memory. This routine is used by MRD and MRR */
var alarm = false; // error result
var blocksLeft = true; // true => more blocks to process
var controlEnabled = false; // true => control blocks will be recognized
var that = this; // local self-reference
function signalControl(controlWord) {
/* Call-back function to send the EOT or control word to the Processor
and release it for the next operation */
releaseProcessor(false, true, controlWord);
}
function blockReady(alarm, control, controlWord, readBlock, completed) {
/* Call-back function when the drive is ready to send the next block
of data, or when it has encountered an error such as EOT. "alarm"
indicates that an error has occurred and the operation is to be aborted.
"control" inidicates that an EOT or control block was encountered, and
"controlWord" is to be passed to the Processor for handling. Otherwise,
if there are more blocks to write, fetches the next block from the
Processor and calls the drive's "readBlock" function, Finally calls
"completed" to finish the operation */
if (alarm) {
setCallback(that.mnemonic, that, 0, releaseProcessor, true);
completed(true); // drive detected an error
} else if (control) {
setCallback(that.mnemonic, that, 0, signalControl, controlWord);
completed(false);
} else if (blocksLeft) {
blocksLeft = that.decrementBlockCount(); // set to false on last block
readBlock(storeWord, record, controlEnabled);// read the next block
} else {
setCallback(that.mnemonic, that, 0, releaseProcessor, false);
completed(false); // normal termination
}
}
if (this.loadCommand(dReg, releaseProcessor, read, arguments)) {
this.controlBusy = true;
controlEnabled = (this.blockWords%2 == 0); // low-order bit of v-digit
alarm = this.currentUnit.readBlock(blockReady, this.boundControlFinished);
if (alarm) {
setCallback(this.mnemonic, this, 0, releaseProcessor, alarm);
this.controlFinished(true);
}
}
};
/**************************************/
B220MagTapeControl.prototype.overwrite = function overwrite(dReg, releaseProcessor, record, fetchWord) {
/* Overwrites the number of blocks and of the size indicated in dReg. If
"record" is true (MOR), block lengths (preface words) are taken from the
word in memory preceding the data to be written. Otherwise, block lengths
are taken from the instruction control digits. "fetchWord" is a function to
read a word from the Processor's memory. This routine is used by MOW and MOR */
var alarm = false; // error result
var blocksLeft = true; // true => more blocks to process
var that = this; // local self-reference
var words;
function signalControl(controlWord) {
/* Call-back function to send the EOT control word to the Processor
and release it for the next operation */
releaseProcessor(false, true, controlWord);
}
function blockReady(alarm, control, controlWord, writeBlock, completed) {
/* Call-back function when the drive is ready to receive the next block
of data, or when it has encountered an error such as EOT. "alarm"
indicates that an error has occurred and the operation is to be aborted.
"control" inidicates that an EOT block with a preface mismatch occurred,
and "controlWord" is to be passed to the Processor for handling.
Otherwise, if there are more blocks to write, fetches the next block
from the Processor and calls the drive's "writeBlock" function, Finally
calls "completed" to finish the operation */
if (alarm) {
setCallback(that.mnemonic, that, 0, releaseProcessor, true);
completed(true); // drive detected an error
} else if (control) {
setCallback(that.mnemonic, that, 0, signalControl, controlWord);
completed(false);
} else if (blocksLeft) {
blocksLeft = that.decrementBlockCount(); // set to false on last block
writeBlock(fetchWord, words); // write the next block
} else {
setCallback(that.mnemonic, that, 0, releaseProcessor, false);
completed(false); // normal termination
}
}
if (this.loadCommand(dReg, releaseProcessor, overwrite, arguments)) {
this.controlBusy = true;
if (this.blockWords < this.currentUnit.minBlockWords && this.blockWords > 1) {
alarm = true; // invalid block length
} else {
words = (record ? 0 : this.blockWords);
alarm = this.currentUnit.overwriteBlock(blockReady, this.boundControlFinished);
}
if (alarm) {
setCallback(this.mnemonic, this, 0, releaseProcessor, alarm);
this.controlFinished(true);
}
}
};
/**************************************/
B220MagTapeControl.prototype.initialWrite = function initialWrite(dReg, releaseProcessor, record, fetchWord) {
/* Initial-writes the number of blocks and of the size indicated in dReg.
If "record" is true (MIR), block lengths (preface words) are taken from the
word in memory preceding the data to be written. Otherwise, block lengths
are taken from the instruction control digits. fetchWord" is a function to
read a word from the Processor's memory. This routine is used by MIW and MIR */
var alarm = false; // error result
var blocksLeft = true; // true => more blocks to process
var that = this; // local self-reference
var words;
function blockReady(alarm, writeBlock, completed) {
/* Call-back function when the drive is ready to receive the next block
of data, or when it has encountered an error such as EOT. "alarm"
indicates that an error has occurred and the operation is to be aborted.
Otherwise, if there are more blocks to write, fetches the next block
from the Processor and calls the drive's "writeBlock" function. Finally
calls "completed" to finish the operation */
if (alarm) {
setCallback(that.mnemonic, that, 0, releaseProcessor, true);
completed(true); // drive detected an error
} else if (blocksLeft) {
blocksLeft = that.decrementBlockCount(); // set to false on last block
writeBlock(fetchWord, words); // write the next block
} else {
setCallback(that.mnemonic, that, 0, releaseProcessor, false);
completed(false); // normal termination
}
}
if (this.loadCommand(dReg, releaseProcessor, initialWrite, arguments)) {
this.controlBusy = true;
if (this.blockWords < this.currentUnit.minBlockWords && this.blockWords > 1) {
alarm = true; // invalid block length
} else {
words = (record ? 0 : this.blockWords);
alarm = this.currentUnit.initialWriteBlock(blockReady, this.boundControlFinished);
}
if (alarm) {
setCallback(this.mnemonic, this, 0, releaseProcessor, alarm);
this.controlFinished(true);
}
}
};
/**************************************/
B220MagTapeControl.prototype.positionForward = function positionForward(dReg, releaseProcessor) {
/* Positions the tape forward the number of blocks indicated in dReg */
var alarm = false; // error result
var that = this; // local self-reference
function blockFinished(nextBlock, completed) {
/* Call-back function when the drive has finished spacing one block
forward. If there are more blocks to space, calls "nextBlock", otherwise
calls "completed" to finish the operation */
if (that.decrementBlockCount()) {
nextBlock(blockFinished);
} else {
completed(false);
}
}
if (this.loadCommand(dReg, releaseProcessor, positionForward, arguments)) {
this.controlBusy = true;
alarm = this.currentUnit.positionForward(blockFinished, this.boundControlFinished);
setCallback(this.mnemonic, this, 0, releaseProcessor, alarm);
}
};
/**************************************/
B220MagTapeControl.prototype.positionBackward = function positionBackward(dReg, releaseProcessor) {
/* Positions the tape backward the number of blocks indicated in dReg */
var alarm = false; // error result
var that = this; // local self-reference
function blockFinished(nextBlock, completed) {
/* Call-back function when the drive has finished spacing one block
backward. If there are more blocks to space, calls "nextBlock", otherwise
calls "completed" to finish the operation */
if (that.decrementBlockCount()) {
nextBlock(blockFinished);
} else {
completed(false);
}
}
if (this.loadCommand(dReg, releaseProcessor, positionBackward, arguments)) {
this.controlBusy = true;
alarm = this.currentUnit.positionBackward(blockFinished, this.boundControlFinished);
setCallback(this.mnemonic, this, 0, releaseProcessor, alarm);
}
};
/**************************************/
B220MagTapeControl.prototype.positionAtEnd = function positionAtEnd(dReg, releaseProcessor) {
/* Positions the tape to the end of recorded information (i.e., when a gap
longer than inter-block gap is detected. Leaves the tape at the end of the
prior recorded block */
var alarm = false; // error result
if (this.loadCommand(dReg, releaseProcessor, positionAtEnd, arguments)) {
this.controlBusy = true;
alarm = this.currentUnit.positionAtEnd(this.boundControlFinished);
setCallback(this.mnemonic, this, 0, releaseProcessor, alarm);
}
};
/**************************************/
B220MagTapeControl.prototype.laneSelect = function laneSelect(dReg, releaseProcessor, fetchWord) {
/* Selects the tape lane of the designated unit. Returns an alarm if the
unit does not exist or is not ready */
var alarm = false; // error result
var laneNr; // lane to select (0, 1)
if (this.loadCommand(dReg, releaseProcessor,laneSelect, arguments)) {
this.controlBusy = true;
laneNr = ((this.C - this.C%0x100)/0x100)%2;
fetchWord(true); // memory access for MTS/MFS not used by MLS
alarm = this.currentUnit.laneSelect(laneNr, this.boundControlFinished);
setCallback(this.mnemonic, this, 0, releaseProcessor, alarm);
}
};
/**************************************/
B220MagTapeControl.prototype.rewind = function rewind(dReg, releaseProcessor, fetchWord) {
/* Initiates rewind of the designated unit. Returns an alarm if the unit
does not exist or is not ready */
var alarm = false; // error result
var laneNr; // lane to select (0, 1)
var lockout; // lockout after rewind (0, 1)
if (this.loadCommand(dReg, releaseProcessor, rewind, arguments)) {
this.controlBusy = true;
laneNr = ((this.C - this.C%0x100)/0x100)%2;
lockout = ((this.C - this.C%0x10)/0x10)%2;
fetchWord(true); // memory access for MTS/MFS not used by MRW/MDA
alarm = this.currentUnit.rewind(laneNr, lockout);
setCallback(this.mnemonic, this, 50, this.controlFinished, false);
setCallback(this.mnemonic, this, 0, releaseProcessor, alarm);
}
};
/**************************************/
B220MagTapeControl.prototype.testUnitReady = function testUnitReady(dReg) {
/* Interrogates status of the designated unit. Returns true if ready */
var result = false; // return value
var ux; // internal unit index
ux = ((dReg - dReg%0x1000000000)/0x1000000000)%0x10;
ux = this.findDesignate(ux);
if (ux >= 0) {
if (this.tapeUnit[ux].ready) {
if (!this.tapeUnit[ux].busy) {
result = true;
}
}
}
return result;
};
/**************************************/
B220MagTapeControl.prototype.testUnitAtMagneticEOT = function testUnitAtMagneticEOT(dReg) {
/* Interrogates status of the designated unit. Returns true if ready and at
Magnetic-End-of-Tape */
var result = false; // return value
var ux; // internal unit index
ux = ((dReg - dReg%0x1000000000)/0x1000000000)%0x10;
ux = this.findDesignate(ux);
if (ux >= 0) {
if (this.tapeUnit[ux].ready) {
if (this.tapeUnit[ux].atEOT) {
result = true;
}
}
}
return result;
};
/**************************************/
B220MagTapeControl.prototype.clearUnit = function clearUnit() {
/* Clears the internal state of the control unit */
this.clear();
this.clearMisc();
this.regC.update(this.C);
this.regT.update(this.T);
};
/**************************************/
B220MagTapeControl.prototype.shutDown = function shutDown() {
/* Shuts down the panel */
var x;
if (this.tapeUnit) {
for (x=this.tapeUnit.length-1; x>=0; --x) {
if (this.tapeUnit[x]) {
this.tapeUnit[x].shutDown();
this.tapeUnit[x] = null;
}
}
}
this.window.removeEventListener("beforeunload", B220MagTapeControl.prototype.beforeUnload, false);
this.$$("ClearBtn").removeEventListener("click", this.boundSwitch_Click, false);
this.regMisc.rightClearBar.removeEventListener("click", this.boundSwitch_Click, false);
this.regC.rightClearBar.removeEventListener("click", this.boundSwitch_Click, false);
this.regT.rightClearBar.removeEventListener("click", this.boundSwitch_Click, false);
this.window.close();
};