Added some RL11 register definitions
This commit is contained in:
parent
9e480d7574
commit
04be27b47b
7 changed files with 249 additions and 164 deletions
|
|
@ -203,7 +203,7 @@ CPUStatePDP11.prototype.initRegs = function()
|
|||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
];
|
||||
this.regsControl = [ // various control registers we don't really care about
|
||||
this.regsControl = [ // various control registers (177740-177756) we don't really care about
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
];
|
||||
this.regMB = 0;
|
||||
|
|
@ -1194,7 +1194,7 @@ CPUStatePDP11.prototype.trap = function(vector, reason)
|
|||
this.trapPSW = -1; // reset flag that we have a trap within a trap
|
||||
|
||||
/*
|
||||
* These next properties are purely for bookkeeping purposes; see getTrapStatus()
|
||||
* These next properties are purely an aid for the Debugger; see getTrapStatus()
|
||||
*/
|
||||
this.opFlags |= PDP11.OPFLAG.TRAP;
|
||||
this.trapVector = vector;
|
||||
|
|
|
|||
|
|
@ -431,6 +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
|
||||
|
||||
LKS: 0o177546, // KW11-L Clock Status
|
||||
|
||||
PRS: 0o177550, // PC11 (and PR11) Reader Status Register
|
||||
|
|
@ -597,8 +602,79 @@ var PDP11 = {
|
|||
},
|
||||
},
|
||||
RL11: { // RL11 Disk Controller
|
||||
PRI: 5, // TODO: Review controller defaults and their configurability
|
||||
VEC: 0o160
|
||||
PRI: 5,
|
||||
VEC: 0o160,
|
||||
RLCS: { // Control Status Register (174400)
|
||||
DRDY: 0x0001, // Drive Ready (R/O)
|
||||
FUNC: 0x000E, // Function Code (F2,F1,F0) (R/W)
|
||||
BAE: 0x0030, // Bus Address Extension bits (BA17,BA16) (R/W)
|
||||
IE: 0x0040, // Interrupt Enable (R/W)
|
||||
CRDY: 0x0080, // Controller Ready (R/W)
|
||||
DS: 0x0300, // Drive Select (DS1,DS0) (R/W)
|
||||
ERRC: 0x3C00, // Error Code (R/O)
|
||||
DE: 0x4000, // Drive Error (R/O)
|
||||
ERR: 0x8000, // Composite Error (R/O)
|
||||
CLEAR: 0x3F7E, // bits cleared on INIT (bits 1-6 and 8-13 are cleared)
|
||||
SET: 0x0080, // bits set on INIT (bit 7 is set)
|
||||
RMASK: 0xFFFF, // no write-only bits
|
||||
WMASK: 0x03FE, // bits writable
|
||||
},
|
||||
RLBA: { // Bus Address Register (174402)
|
||||
WMASK: 0xFFFE // bit 0 is effectively not writable (always zero)
|
||||
},
|
||||
/*
|
||||
* This register has 3 formats: one for Seek, another for Read/Write, and a third for Get Status
|
||||
*/
|
||||
RLDA: { // Disk Address Register (174404)
|
||||
SEEK_CMD: 0x0001, // Seek: bit 0 must be set, bits 1 and 3 must be clear
|
||||
SEEK_DIR: 0x0004, // Direction (clear to move heads away from spindle (lower cylinder), set to move to higher cylinder)
|
||||
SEEK_HS: 0x0010, // Head Select (clear to select upper head, set to select lower head)
|
||||
SEEK_CAD: 0xFF80, // Cylinder Address Difference
|
||||
RW_SA: 0x003F, // Sector Address
|
||||
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)
|
||||
},
|
||||
/*
|
||||
* 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
|
||||
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_WGE: 0x0400, // Write Gate Error
|
||||
GS_SPE: 0x0800, // Spin Error
|
||||
GS_SKTO: 0x1000, // Seek Time-Out
|
||||
GS_WL: 0x2000, // Write Lock
|
||||
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
|
||||
},
|
||||
ERRC: { // NOTE: These error codes are pre-shifted to read directly from RLCS.ERRC
|
||||
OPI: 0x0400, // Operation Incomplete
|
||||
DCRC: 0x0800, // Read Data CRC
|
||||
WCE: 0x0800, // Write Check Error
|
||||
HCRC: 0x0C00, // Header CRC
|
||||
DLT: 0x1000, // Data Late
|
||||
HNF: 0x1400, // Header Not Found
|
||||
NXM: 0x2000, // Non-Existent Memory
|
||||
MPE: 0x2400 // Memory Parity Error (RLV12 only)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -273,6 +273,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().
|
||||
*/
|
||||
this.initController();
|
||||
|
||||
this.triggerReaderInterrupt = this.cpu.addTrigger(PDP11.RL11.VEC, PDP11.RL11.PRI);
|
||||
|
||||
bus.addIOTable(this, RL11.UNIBUS_IOTABLE);
|
||||
|
|
@ -296,6 +303,23 @@ RL11.prototype.getDriveName = function(iDrive)
|
|||
return "RL" + iDrive;
|
||||
};
|
||||
|
||||
/**
|
||||
* getDriveNumber(sDrive)
|
||||
*
|
||||
* @this {RL11}
|
||||
* @param {string} sDrive
|
||||
* @return {number} (0-3, or -1 if error)
|
||||
*/
|
||||
RL11.prototype.getDriveNumber = function(sDrive)
|
||||
{
|
||||
var iDrive = -1;
|
||||
if (sDrive) {
|
||||
iDrive = sDrive.charCodeAt(sDrive.length - 1) - 0x30;
|
||||
if (iDrive < 0 || iDrive > 9) iDrive = -1;
|
||||
}
|
||||
return iDrive;
|
||||
};
|
||||
|
||||
/**
|
||||
* powerUp(data, fRepower)
|
||||
*
|
||||
|
|
@ -332,11 +356,6 @@ RL11.prototype.powerUp = function(data, fRepower)
|
|||
for (var iDrive = 0; iDrive < this.nDrives; iDrive++) {
|
||||
var controlOption = document.createElement("option");
|
||||
controlOption.value = iDrive;
|
||||
/*
|
||||
* TODO: This conversion of drive number to drive letter, starting with A:, is very simplistic
|
||||
* and will NOT match the drive mappings that DOS ultimately uses. We'll need to spiff this up at
|
||||
* some point.
|
||||
*/
|
||||
controlOption.text = this.getDriveName(iDrive);
|
||||
controlDrives.appendChild(controlOption);
|
||||
}
|
||||
|
|
@ -431,8 +450,7 @@ RL11.prototype.initController = function(data)
|
|||
*/
|
||||
RL11.prototype.saveController = function()
|
||||
{
|
||||
var data = [];
|
||||
return data;
|
||||
return [];
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -502,11 +520,7 @@ RL11.prototype.autoMount = function(fRemount)
|
|||
var sDiskPath = configDrive['path'] || "";
|
||||
var sDiskName = configDrive['name'] || this.findDisk(sDiskPath);
|
||||
if (sDiskPath && sDiskName) {
|
||||
/*
|
||||
* WARNING: This conversion of drive letter to drive number, starting with A:, is very simplistic
|
||||
* and is not guaranteed to match the drive mapping that DOS ultimately uses.
|
||||
*/
|
||||
var iDrive = sDrive.charCodeAt(0) - 0x41;
|
||||
var iDrive = this.getDriveNumber(sDrive);
|
||||
if (iDrive >= 0 && iDrive < this.aDrives.length) {
|
||||
if (!this.loadDrive(iDrive, sDiskName, sDiskPath, true) && fRemount) {
|
||||
this.setReady(false);
|
||||
|
|
@ -668,7 +682,7 @@ RL11.prototype.doneLoadDrive = function onLoadDrive(drive, disk, sDiskName, sDis
|
|||
* For a local disk (ie, one loaded via mountDrive()), the disk.restore() performed by addDiskHistory()
|
||||
* may have altered the disk geometry, so refresh the disk info.
|
||||
*/
|
||||
aDiskInfo = disk.info();
|
||||
// aDiskInfo = disk.info();
|
||||
|
||||
/*
|
||||
* Clearly, a successful mount implies a disk change, and I suppose that, technically, an *unsuccessful*
|
||||
|
|
@ -684,9 +698,6 @@ RL11.prototype.doneLoadDrive = function onLoadDrive(drive, disk, sDiskName, sDis
|
|||
/*
|
||||
* With the addition of notify(), users are now "alerted" whenever a disk has finished loading;
|
||||
* notify() is selective about its output, using print() if a print window is open, alert() otherwise.
|
||||
*
|
||||
* WARNING: This conversion of drive number to drive letter, starting with A:, is very simplistic
|
||||
* and will not match the drive mappings that DOS ultimately uses (ie, for drives beyond B:).
|
||||
*/
|
||||
this.notice("Mounted disk \"" + sDiskName + "\" in drive " + this.getDriveName(drive.iDrive), drive.fAutoMount || fAutoMount);
|
||||
|
||||
|
|
@ -832,10 +843,6 @@ RL11.prototype.unloadDrive = function(iDrive, fLoading)
|
|||
|
||||
// this.regInput |= FDC.REG_INPUT.DISK_CHANGE;
|
||||
|
||||
/*
|
||||
* WARNING: This conversion of drive number to drive letter, starting with A:, is very simplistic
|
||||
* and is not guaranteed to match the drive mapping that DOS ultimately uses.
|
||||
*/
|
||||
if (!fLoading) {
|
||||
this.notice("Drive " + this.getDriveName(iDrive) + " unloaded", fLoading);
|
||||
this.sDiskSource = RL11.SOURCE.NONE;
|
||||
|
|
|
|||
Loading…
Reference in a new issue