Lots of work to try to bring the new RL11 component up to snuff

This commit is contained in:
Jeff 2016-10-29 11:32:31 -07:00 committed by Jeff Parsons
commit 96ad4ec37e
6 changed files with 978 additions and 558 deletions

View file

@ -152,6 +152,7 @@ function BusPDP11(parmsBus, cpu, dbg)
this.aIOHandlers = [];
this.fIOBreakAll = false;
this.nDisableFaults = 0;
this.fFault = false;
/*
* Array of RESET notification handlers registered by Device components.
@ -552,13 +553,11 @@ BusPDP11.prototype.reset = function()
BusPDP11.prototype.unknownAccess = function(addr, fByte, data)
{
if (DEBUGGER && this.dbg && this.dbg.messageEnabled(MessagesPDP11.WARN)) {
/*
* TODO: For 22-bit machines, let's display addr as a 3-byte value (for a total of 9 octal digits)
*/
this.dbg.printMessage("warning: unknown I/O access (" + this.dbg.toStrBase(addr) + "," + this.dbg.toStrBase(data, fByte?1:2) + ")", true, true);
this.dbg.stopInstruction();
}
if (!this.nDisableFaults) {
this.cpu.regErr |= PDP11.CPUERR.TIMEOUT;
this.cpu.trap(PDP11.TRAP.BUS_ERROR, addr);
}
return 0;
@ -925,6 +924,7 @@ BusPDP11.prototype.getByte = function(addr)
*/
BusPDP11.prototype.getByteDirect = function(addr)
{
this.fFault = false;
this.nDisableFaults++;
var b = this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].readByteDirect(addr & this.nBlockLimit, addr);
this.nDisableFaults--;
@ -962,6 +962,7 @@ BusPDP11.prototype.getWordDirect = function(addr)
var w;
var off = addr & this.nBlockLimit;
var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;
this.fFault = false;
this.nDisableFaults++;
if (!PDP11.WORDBUS && off == this.nBlockLimit) {
w = this.aMemBlocks[iBlock++].readByteDirect(off, addr) | (this.aMemBlocks[iBlock & this.nBlockMask].readByteDirect(0, addr + 1) << 8);
@ -996,6 +997,7 @@ BusPDP11.prototype.setByte = function(addr, b)
*/
BusPDP11.prototype.setByteDirect = function(addr, b)
{
this.fFault = false;
this.nDisableFaults++;
this.aMemBlocks[(addr & this.nBusMask) >>> this.nBlockShift].writeByteDirect(addr & this.nBlockLimit, b & 0xff, addr);
this.nDisableFaults--;
@ -1034,6 +1036,7 @@ BusPDP11.prototype.setWordDirect = function(addr, w)
{
var off = addr & this.nBlockLimit;
var iBlock = (addr & this.nBusMask) >>> this.nBlockShift;
this.fFault = false;
this.nDisableFaults++;
if (!PDP11.WORDBUS && off == this.nBlockLimit) {
this.aMemBlocks[iBlock++].writeByteDirect(off, w & 0xff, addr);
@ -1272,6 +1275,22 @@ BusPDP11.prototype.fault = function(addr, access)
}
this.cpu.trap(PDP11.TRAP.BUS_ERROR, addr);
}
this.fFault = true;
};
/**
* checkFault()
*
* This also serves as a clearFault() function.
*
* @this {BusPDP11}
* @return {boolean}
*/
BusPDP11.prototype.checkFault= function()
{
var f = this.fFault;
this.fFault = false;
return f;
};
/**

View file

@ -431,10 +431,11 @@ var PDP11 = {
MMR3: 0o172516, // 772516 17772516
RLCS: 0o174400, // RL11 Control Status
RLBA: 0o174402, // RL11 Bus Address
RLDA: 0o177404, // RL11 Disk Address
RLMP: 0o177406, // RL11 Multi-Purpose
RLCS: 0o174400, // RL11 Control Status Register
RLBA: 0o174402, // RL11 Bus Address Register
RLDA: 0o177404, // RL11 Disk Address Register
RLMP: 0o177406, // RL11 Multi-Purpose Register
RLBE: 0o177410, // RL11 Bus (Address) Extension Register (RLV12 controller only)
LKS: 0o177546, // KW11-L Clock Status
@ -618,6 +619,10 @@ var PDP11 = {
SET: 0x0080, // bits set on INIT (bit 7 is set)
RMASK: 0xFFFF, // no write-only bits
WMASK: 0x03FE, // bits writable
SHIFT: {
FUNC: 1,
DS: 8
}
},
RLBA: { // Bus Address Register (174402)
WMASK: 0xFFFE // bit 0 is effectively not writable (always zero)
@ -634,20 +639,33 @@ var PDP11 = {
RW_HS: 0x0040, // Head Select
RW_CA: 0xFF80, // Cylinder Address (RL01 has 256 cylinders, RL02 has 512)
GS_CMD: 0x0003, // Get Status: bit 0 must be set, bit 1 set, and bits 2 and 4-7 clear (bits 8-15 unused)
GS_RST: 0x0008 // Reset (when set, clears error register before sending status word to controller)
GS_RST: 0x0008, // Reset (when set, clears error register before sending status word to controller)
SHIFT: {
RW_HS: 6,
RW_CA: 7
}
},
/*
* This register has 3 formats: one for Read Header, another for Read/Write, and a third for Get Status
*/
RLMP: {
GS_ST: 0x0007, // Major State Code
RLMP: { // Multi-Purpose Register (177406)
GS_ST: { // Major State Code (of the drive)
LOADC: 0x0, // Load Cartridge
SPINUP: 0x1, // Spin-Up
BRUSHC: 0x2, // Brush Cycle
LOADH: 0x3, // Load Heads
SEEK: 0x4, // Seek
LOCKON: 0x5, // Lock On
UNLOADH:0x6, // Unload Heads
SPINDN: 0x7 // Spin-Down
},
GS_BH: 0x0008, // Brushes Home
GS_HO: 0x0010, // Heads Out
GS_CO: 0x0020, // Cover Open (or dust cover is not in place)
GS_HS: 0x0040, // Head Selected (0 for upper head, 1 for lower head)
GS_DT: 0x0080, // Drive Type (0 for RL01, 1 for RL02)
GS_DSE: 0x0100, // Drive Select Error
GS_VC: 0x0200, // Volume Check
GS_VC: 0x0200, // Volume Check (Set during transition from a head load state to a head-on-track state; cleared by execution of a Get Status command with Bit 3 asserted)
GS_WGE: 0x0400, // Write Gate Error
GS_SPE: 0x0800, // Spin Error
GS_SKTO: 0x1000, // Seek Time-Out
@ -655,17 +673,10 @@ var PDP11 = {
GS_CHE: 0x4000, // Current Head Error
GS_WDE: 0x8000 // Write Data Error
},
FUNC: { // NOTE: These function codes are pre-shifted to write directly into RLCS.FUNC
NOP: 0b0000, // No-Op
WCHK: 0b0010, // Write Check
STATUS: 0b0100, // Get Status
SEEK: 0b0110, // Seek
RHDR: 0b1000, // Read Header
WDATA: 0b1010, // Write Data
RDATA: 0b1100, // Read Data
RDNC: 0b1110 // Read Data without Header Check
RLBE: { // Bus (Address) Extension Register (174410)
MASK: 0x003F // bits 5-0 correspond to bus address bits 21-16
},
ERRC: { // NOTE: These error codes are pre-shifted to read directly from RLCS.ERRC
ERRC: { // NOTE: These error codes are pre-shifted to read/write directly from/to RLCS.ERRC
OPI: 0x0400, // Operation Incomplete
DCRC: 0x0800, // Read Data CRC
WCE: 0x0800, // Write Check Error
@ -674,6 +685,16 @@ var PDP11 = {
HNF: 0x1400, // Header Not Found
NXM: 0x2000, // Non-Existent Memory
MPE: 0x2400 // Memory Parity Error (RLV12 only)
},
FUNC: { // NOTE: These function codes are pre-shifted to read/write directly from/to RLCS.FUNC
NOP: 0b0000, // No-Op
WCHK: 0b0010, // Write Check
STATUS: 0b0100, // Get Status
SEEK: 0b0110, // Seek
RHDR: 0b1000, // Read Header
WDATA: 0b1010, // Write Data
RDATA: 0b1100, // Read Data
RDNC: 0b1110 // Read Data without Header Check
}
}
};

View file

@ -93,7 +93,7 @@ function DiskPDP11(controller, drive, mode)
this.drive = drive;
/*
* We pull out a number of drive properties that we may or may not need as defaults
* We pull out a number of drive properties that we may or may not need as defaults.
*/
this.sDiskName = drive.name;
this.fRemovable = drive.fRemovable;
@ -1230,4 +1230,4 @@ DiskPDP11.prototype.dumpSector = function(sector, pba, sDesc)
return sDump;
};
if (NODE) module.exports = Disk;
if (NODE) module.exports = DiskPDP11;

View file

@ -274,13 +274,13 @@ RL11.prototype.initBus = function(cmp, bus, cpu, dbg)
}
/*
* If we didn't need auto-mount support, we could defer controller initialization until we received a powerUp() notification,
* at which point reset() would call initController(), or restore() would restore the controller; in that case, all we'd need
* to do here is call setReady().
* If we didn't need auto-mount support, we could defer controller initialization until we received
* a powerUp() notification, at which point reset() would call initController(), or restore() would restore
* the controller; in that case, all we'd need to do here is call setReady().
*/
this.initController();
this.triggerReaderInterrupt = this.cpu.addTrigger(PDP11.RL11.VEC, PDP11.RL11.PRI);
this.triggerInterrupt = this.cpu.addTrigger(PDP11.RL11.VEC, PDP11.RL11.PRI);
bus.addIOTable(this, RL11.UNIBUS_IOTABLE);
@ -417,29 +417,7 @@ RL11.prototype.save = function()
*/
RL11.prototype.restore = function(data)
{
return true; // this.initController(data[0]);
};
/**
* initController(data)
*
* @this {RL11}
* @param {Array} [data]
* @return {boolean} true if successful, false if failure
*/
RL11.prototype.initController = function(data)
{
var fSuccess = true;
for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {
var drive = this.aDrives[iDrive];
if (drive === undefined) {
drive = this.aDrives[iDrive] = {};
}
if (!this.initDrive(drive, iDrive)) {
fSuccess = false;
}
}
return true;
return this.initController(data[0]);
};
/**
@ -453,57 +431,6 @@ RL11.prototype.saveController = function()
return [];
};
/**
* initDrive(drive, iDrive, data)
*
* TODO: Consider a separate Drive class that any drive controller can use, since there's a lot of commonality
* between the drive objects created by disk controllers. This will clean up overall drive management and allow
* us to factor out some common Drive methods.
*
* @this {RL11}
* @param {Object} drive
* @param {number} iDrive
* @param {Array|undefined} [data]
* @return {boolean} true if successful, false if failure
*/
RL11.prototype.initDrive = function(drive, iDrive, data)
{
var i = 0;
var fSuccess = true;
drive.iDrive = iDrive;
drive.fBusy = drive.fLocal = false;
drive.name = this.idComponent;
drive.nCylinders = 512;
drive.nHeads = 2;
drive.nSectors = 40;
drive.cbSector = 256;
drive.fRemovable = true;
/*
* The next group of properties are set by various controller command sequences.
*/
drive.bHead = 0;
drive.bCylinderSeek = 0;
drive.bCylinder = 0;
drive.bSector = 1;
drive.bSectorEnd = drive.nSectors; // aka EOT
drive.nBytes = drive.cbSector;
/*
* The next group of properties are managed by worker functions (eg, doRead()) to maintain state across DMA requests.
*/
drive.ibSector = 0;
drive.sector = null;
if (!drive.disk) {
drive.sDiskPath = ""; // ensure this is initialized to a default that displayDisk() can deal with
}
return fSuccess;
};
/**
* autoMount(fRemount)
*
@ -866,10 +793,446 @@ RL11.prototype.unloadAllDrives = function(fDiscard)
}
};
/**
* initController(data)
*
* @this {RL11}
* @param {Array} [data]
* @return {boolean} true if successful, false if failure
*/
RL11.prototype.initController = function(data)
{
var i = 0;
if (!data) data = [];
this.csr = data[i++] || 0;
this.bar = data[i++] || 0;
this.dar = data[i++] || 0;
this.darInternal = data[i++] || 0;
this.mpr = data[i++] || 0;
this.ber = data[i] || 0;
var fSuccess = true;
for (var iDrive = 0; iDrive < this.aDrives.length; iDrive++) {
var drive = this.aDrives[iDrive];
if (drive === undefined) {
drive = this.aDrives[iDrive] = {};
}
if (!this.initDrive(drive, iDrive)) {
fSuccess = false;
}
}
return fSuccess;
};
/**
* initDrive(drive, iDrive, data)
*
* TODO: Consider a separate Drive class that any drive controller can use, since there's a lot of commonality
* between the drive objects created by disk controllers. This will clean up overall drive management and allow
* us to factor out some common Drive methods.
*
* @this {RL11}
* @param {Object} drive
* @param {number} iDrive
* @param {Array|undefined} [data]
* @return {boolean} true if successful, false if failure
*/
RL11.prototype.initDrive = function(drive, iDrive, data)
{
var i = 0;
var fSuccess = true;
drive.iDrive = iDrive;
drive.fBusy = drive.fLocal = false;
drive.name = this.idComponent;
drive.nCylinders = 512;
drive.nHeads = 2;
drive.nSectors = 40;
drive.cbSector = 256;
drive.fRemovable = true;
/*
* The next group of properties are set by various controller command sequences.
*/
drive.bHead = 0;
drive.bCylinderSeek = 0;
drive.bCylinder = 0;
drive.bSector = 1;
drive.bSectorEnd = drive.nSectors; // aka EOT
drive.nBytes = drive.cbSector;
/*
* The next group of properties are managed by worker functions (eg, doRead()) to maintain state across DMA requests.
*/
drive.ibSector = 0;
drive.sector = null;
if (!drive.disk) {
drive.sDiskPath = ""; // ensure this is initialized to a default that displayDisk() can deal with
}
/*
* Default drive status bits returned via the controller's Get Status command via the RLMP register
*/
drive.status = PDP11.RL11.RLMP.GS_ST.LOCKON | PDP11.RL11.RLMP.GS_BH | PDP11.RL11.RLMP.GS_HO | (drive.nCylinders == 512? PDP11.RL11.RLMP.GS_DT : 0);
return fSuccess;
};
/**
* processCommand()
*
* @this {RL11}
*/
RL11.prototype.processCommand = function()
{
var fnReadWrite;
var fInterrupt = true;
var iDrive = (this.csr & PDP11.RL11.RLCS.DS) >> PDP11.RL11.RLCS.SHIFT.DS;
var drive = this.aDrives[iDrive];
var iCylinder, iHead, iSector, nWords, addr;
/*
* The typical pattern of DRDY and CRDY:
*
* 1) Normally both set
* 2) CRDY is cleared to process a command
* 3) DRDY is cleared to command is in process
*/
this.csr &= ~PDP11.RL11.RLCS.DRDY;
switch(this.csr & PDP11.RL11.RLCS.FUNC) {
case PDP11.RL11.FUNC.NOP:
case PDP11.RL11.FUNC.WCHK:
case PDP11.RL11.FUNC.RDNC:
break;
case PDP11.RL11.FUNC.STATUS:
if (this.dar & PDP11.RL11.RLDA.GS_RST) {
this.csr &= 0x3F; // TODO: Review
}
this.mpr = drive.status | (this.darInternal & PDP11.RL11.RLDA.RW_HS); // bit 6: Head Select, bit 7: Drive Type (1=RL02)
break;
case PDP11.RL11.FUNC.SEEK:
if ((this.dar & PDP11.RL11.RLDA.GS_CMD) == PDP11.RL11.RLDA.SEEK_CMD) {
var darCA = (this.dar & PDP11.RL11.RLDA.RW_CA);
var darHS = (this.dar & PDP11.RL11.RLDA.SEEK_HS) << 2;
if (this.dar & PDP11.RL11.RLDA.SEEK_DIR) {
this.darInternal += darCA;
} else {
this.darInternal -= darCA;
}
this.dar = this.darInternal = (this.darInternal & PDP11.RL11.RLDA.RW_CA) | darHS;
}
break;
case PDP11.RL11.FUNC.RHDR:
this.mpr = this.darInternal;
break;
case PDP11.RL11.FUNC.RDATA:
fnReadWrite = this.readData;
/* falls through */
case PDP11.RL11.FUNC.WDATA:
if (!fnReadWrite) fnReadWrite = this.writeData;
iCylinder = this.dar >> PDP11.RL11.RLDA.SHIFT.RW_CA;
iHead = (this.dar & PDP11.RL11.RLDA.RW_HS)? 0 : 1;
iSector = this.dar & PDP11.RL11.RLDA.RW_SA;
if (iCylinder >= drive.nCylinders || iSector >= drive.nSectors) {
this.csr |= PDP11.RL11.ERRC.HNF | PDP11.RL11.RLCS.ERR;
break;
}
addr = (((this.ber & PDP11.RL11.RLBE.MASK)) << 16) | this.bar; // 22 bit mode
nWords = (0x10000 - this.mpr) & 0xffff;
fInterrupt = fnReadWrite.call(this, drive, iCylinder, iHead, iSector, nWords, addr, this.endReadWrite.bind(this));
break;
default:
break;
}
if (fInterrupt) {
this.csr |= PDP11.RL11.RLCS.DRDY | PDP11.RL11.RLCS.CRDY;
if (this.csr & PDP11.RL11.RLCS.IE) {
this.cpu.setTrigger(this.triggerInterrupt);
}
}
};
/**
* endReadWrite(err, iCylinder, iHead, iSector, nWords, addr)
*
* @this {RL11}
* @param {number} err
* @param {number} iCylinder
* @param {number} iHead
* @param {number} iSector
* @param {number} nWords
* @param {number} addr
* @return {boolean}
*/
RL11.prototype.endReadWrite = function(err, iCylinder, iHead, iSector, nWords, addr)
{
this.bar = addr & 0xffff;
this.csr = (this.csr & ~PDP11.RL11.RLCS.BAE) | ((addr >> 12) & PDP11.RL11.RLCS.BAE);
this.ber = (addr >> 16) & PDP11.RL11.RLBE.MASK; // 22 bit mode
this.dar = (iCylinder << PDP11.RL11.RLDA.SHIFT.RW_CA) | (iHead? PDP11.RL11.RLDA.RW_HS : 0) | (iSector & PDP11.RL11.RLDA.RW_SA);
this.darInternal = this.dar;
this.mpr = (0x10000 - nWords) & 0xffff;
if (err) {
this.csr |= err | PDP11.RL11.RLCS.ERR;
}
return true;
};
/**
* readData(drive, iCylinder, iHead, iSector, nWords, addr, done)
*
* @this {RL11}
* @param {Object} drive
* @param {number} iCylinder
* @param {number} iHead
* @param {number} iSector
* @param {number} nWords
* @param {number} addr
* @param {function(...)} done
* @return {boolean} true if complete, false if queued
*/
RL11.prototype.readData = function(drive, iCylinder, iHead, iSector, nWords, addr, done)
{
var err = 0;
var disk = drive.disk;
var sector = null, ibSector;
while (nWords--) {
if (!sector) {
sector = drive.disk.seek(iCylinder, iHead, iSector, true);
if (!sector) {
err = PDP11.RL11.ERRC.HNF;
break;
}
ibSector = 0;
}
var b0, b1;
if ((b0 = drive.disk.read(sector, ibSector++)) < 0 || (b1 = drive.disk.read(sector, ibSector++)) < 0) {
err = PDP11.RL11.ERRC.HNF;
break;
}
var data = this.bus.setWordDirect(this.cpu.mapUnibus(addr), b0 | (b1 << 8));
if (this.bus.checkFault()) {
err = PDP11.RL11.ERRC.NXM;
break;
}
addr += 2;
if (ibSector >= disk.cbSector) {
sector = null;
if (++iSector >= disk.nSectors) {
iSector = 0;
if (++iHead >= disk.nHeads) {
iHead = 0;
if (++iCylinder >= disk.nCylinders) {
err = PDP11.RL11.ERRC.HNF;
break;
}
}
}
}
}
return done(err, iCylinder, iHead, iSector, nWords, addr);
};
/**
* writeData(drive, iCylinder, iHead, iSector, nWords, addr, done)
*
* @this {RL11}
* @param {Object} drive
* @param {number} iCylinder
* @param {number} iHead
* @param {number} iSector
* @param {number} nWords
* @param {number} addr
* @param {function(...)} done
* @return {boolean} true if complete, false if queued
*/
RL11.prototype.writeData = function(drive, iCylinder, iHead, iSector, nWords, addr, done)
{
var err = 0;
var disk = drive.disk;
var sector = null, ibSector;
while (nWords--) {
var data = this.bus.getWordDirect(this.cpu.mapUnibus(addr));
if (this.bus.checkFault()) {
err = PDP11.RL11.ERRC.NXM;
break;
}
addr += 2;
if (!sector) {
sector = drive.disk.seek(iCylinder, iHead, iSector, true);
if (!sector) {
err = PDP11.RL11.ERRC.HNF;
break;
}
ibSector = 0;
}
if (!drive.disk.write(sector, ibSector++, data & 0xff) || !drive.disk.write(sector, ibSector++, data >> 8)) {
err = PDP11.RL11.ERRC.HNF;
break;
}
if (ibSector >= disk.cbSector) {
sector = null;
if (++iSector >= disk.nSectors) {
iSector = 0;
if (++iHead >= disk.nHeads) {
iHead = 0;
if (++iCylinder >= disk.nCylinders) {
err = PDP11.RL11.ERRC.HNF;
break;
}
}
}
}
}
return done(err, iCylinder, iHead, iSector, nWords, addr);
};
/**
* readRLCS(addr)
*
* @this {RL11}
* @param {number} addr (eg, PDP11.UNIBUS.RLCS or 174400)
* @return {number}
*/
RL11.prototype.readRLCS = function(addr)
{
return this.csr & PDP11.RL11.RLCS.RMASK;
};
/**
* writeRLCS(data, addr)
*
* @this {RL11}
* @param {number} data
* @param {number} addr (eg, PDP11.UNIBUS.RLCS or 174400)
*/
RL11.prototype.writeRLCS = function(data, addr)
{
this.csr = (this.csr & ~PDP11.RL11.RLCS.WMASK) | (data & PDP11.RL11.RLCS.WMASK);
this.bae = (this.bae & ~0x3) | ((data & PDP11.RL11.RLCS.BAE) >> 4);
if (!(this.csr & PDP11.RL11.RLCS.CRDY)) this.processCommand();
};
/**
* readRLBA(addr)
*
* @this {RL11}
* @param {number} addr (eg, PDP11.UNIBUS.RLBA or 174402)
* @return {number}
*/
RL11.prototype.readRLBA = function(addr)
{
return this.bar;
};
/**
* writeRLBA(data, addr)
*
* @this {RL11}
* @param {number} data
* @param {number} addr (eg, PDP11.UNIBUS.RLBA or 174402)
*/
RL11.prototype.writeRLBA = function(data, addr)
{
this.bar = data & PDP11.RL11.RLBA.WMASK;
};
/**
* readRLDA(addr)
*
* @this {RL11}
* @param {number} addr (eg, PDP11.UNIBUS.RLDA or 174404)
* @return {number}
*/
RL11.prototype.readRLDA = function(addr)
{
return this.dar;
};
/**
* writeRLDA(data, addr)
*
* @this {RL11}
* @param {number} data
* @param {number} addr (eg, PDP11.UNIBUS.RLDA or 174404)
*/
RL11.prototype.writeRLDA = function(data, addr)
{
this.dar = data;
};
/**
* readRLMP(addr)
*
* @this {RL11}
* @param {number} addr (eg, PDP11.UNIBUS.RLMP or 174406)
* @return {number}
*/
RL11.prototype.readRLMP = function(addr)
{
return this.mpr;
};
/**
* writeRLMP(data, addr)
*
* @this {RL11}
* @param {number} data
* @param {number} addr (eg, PDP11.UNIBUS.RLMP or 174406)
*/
RL11.prototype.writeRLMP = function(data, addr)
{
this.mpr = data;
};
/**
* readRLBE(addr)
*
* @this {RL11}
* @param {number} addr (eg, PDP11.UNIBUS.RLBE or 174410)
* @return {number}
*/
RL11.prototype.readRLBE = function(addr)
{
return this.ber;
};
/**
* writeRLBE(data, addr)
*
* @this {RL11}
* @param {number} data
* @param {number} addr (eg, PDP11.UNIBUS.RLBE or 174410)
*/
RL11.prototype.writeRLBE = function(data, addr)
{
this.ber = data & PDP11.RL11.RLBE.MASK;
};
/*
* ES6 ALERT: As you can see below, I've finally started using computed property names.
*/
RL11.UNIBUS_IOTABLE = {
[PDP11.UNIBUS.RLCS]: /* 174400 */ [null, null, RL11.prototype.readRLCS, RL11.prototype.writeRLCS, "RLCS"],
[PDP11.UNIBUS.RLBA]: /* 174402 */ [null, null, RL11.prototype.readRLBA, RL11.prototype.writeRLBA, "RLBA"],
[PDP11.UNIBUS.RLDA]: /* 174404 */ [null, null, RL11.prototype.readRLDA, RL11.prototype.writeRLDA, "RLDA"],
[PDP11.UNIBUS.RLMP]: /* 174406 */ [null, null, RL11.prototype.readRLMP, RL11.prototype.writeRLMP, "RLMP"],
[PDP11.UNIBUS.RLBE]: /* 174410 */ [null, null, RL11.prototype.readRLBE, RL11.prototype.writeRLBE, "RLBE"]
};
if (NODE) module.exports = RL11;