Merge branch 'master' into gh-pages
This commit is contained in:
commit
a7f9667b55
24 changed files with 1070 additions and 915 deletions
|
|
@ -318,15 +318,6 @@ class BusPDP11 extends Component {
|
|||
/**
|
||||
* powerUp(data, fRepower)
|
||||
*
|
||||
* We don't need a powerDown() handler, because for largely historical reasons, our state is saved by saveMemory(),
|
||||
* which called by the CPU.
|
||||
*
|
||||
* However, we do need a powerUp() handler, because on resumable machines, the Computer's onReset() function calls
|
||||
* everyone's powerUp() handler rather than their reset() handler.
|
||||
*
|
||||
* TODO: Perhaps Computer should be smarter: if there's no powerUp() handler, then fallback to the reset() handler.
|
||||
* In that case, however, we'd either need to remove the powerUp() stub in Component, or detect the existence of the stub.
|
||||
*
|
||||
* @this {BusPDP11}
|
||||
* @param {Object|null} data (always null because we supply no powerDown() handler)
|
||||
* @param {boolean} [fRepower]
|
||||
|
|
@ -334,10 +325,54 @@ class BusPDP11 extends Component {
|
|||
*/
|
||||
powerUp(data, fRepower)
|
||||
{
|
||||
if (!fRepower) this.reset();
|
||||
if (!fRepower) {
|
||||
if (!data) {
|
||||
this.reset();
|
||||
} else {
|
||||
if (!this.restore(data)) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* powerDown(fSave, fShutdown)
|
||||
*
|
||||
* @this {BusPDP11}
|
||||
* @param {boolean} [fSave]
|
||||
* @param {boolean} [fShutdown]
|
||||
* @return {Object|boolean} component state if fSave; otherwise, true if successful, false if failure
|
||||
*/
|
||||
powerDown(fSave, fShutdown)
|
||||
{
|
||||
return fSave? this.save() : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* save()
|
||||
*
|
||||
* @this {BusPDP11}
|
||||
* @return {Object|null}
|
||||
*/
|
||||
save()
|
||||
{
|
||||
var state = new State(this);
|
||||
state.set(0, this.saveMemory());
|
||||
return state.data();
|
||||
}
|
||||
|
||||
/**
|
||||
* restore(data)
|
||||
*
|
||||
* @this {BusPDP11}
|
||||
* @param {Object} data
|
||||
* @return {boolean} true if restore successful, false if not
|
||||
*/
|
||||
restore(data)
|
||||
{
|
||||
return this.restoreMemory(data[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* addMemory(addr, size, type, controller)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -128,14 +128,14 @@ class ComputerPDP11 extends Component {
|
|||
*/
|
||||
this.nBusWidth = +parmsComputer['busWidth'] || +parmsComputer['buswidth'];
|
||||
|
||||
this.resume = ComputerPDP11.RESUME_NONE;
|
||||
this.sResumePath = this.sStatePath = null;
|
||||
this.sStateData = null;
|
||||
this.fStateData = false; // remembers if sStateData was loaded
|
||||
this.fServerState = false;
|
||||
this.stateComputer = this.stateFailSafe = null;
|
||||
this.fInitialized = this.fReload = this.fRestoreError = false;
|
||||
this.stateFailSafe = null;
|
||||
|
||||
this.url = this.getMachineParm('url') || "";
|
||||
this.url = /** @type {string} */ (this.getMachineParm('url') || "");
|
||||
|
||||
/*
|
||||
* Generate a random number x (where 0 <= x < 1), add 0.1 so that it's guaranteed to be
|
||||
|
|
@ -145,7 +145,7 @@ class ComputerPDP11 extends Component {
|
|||
this.sUserID = this.queryUserID();
|
||||
|
||||
/*
|
||||
* Find the appropriate CPU (and Debugger and Control Panel, if any)
|
||||
* Find the appropriate CPU (and Debugger and Control Panel, if any).
|
||||
*
|
||||
* CLOSURE COMPILER TIP: To override the type of a right-hand expression (as we need to do here,
|
||||
* where we know getComponentByType() will only return an CPUState object or null), wrap the expression
|
||||
|
|
@ -198,20 +198,7 @@ class ComputerPDP11 extends Component {
|
|||
if (component.initBus) component.initBus(this, this.bus, this.cpu, this.dbg);
|
||||
}
|
||||
|
||||
var sStatePath = null;
|
||||
var sResume = parmsComputer['resume'];
|
||||
if (sResume !== undefined) {
|
||||
/*
|
||||
* DEPRECATE: This goofiness is a holdover from when the 'resume' property was a string (either a
|
||||
* single-digit string or a path); now it's always a number, so it never has a 'length' property and
|
||||
* the call to parseInt() is unnecessary.
|
||||
*/
|
||||
if (sResume.length > 1) {
|
||||
sStatePath = this.sResumePath = sResume;
|
||||
} else {
|
||||
this.resume = parseInt(sResume, 10);
|
||||
}
|
||||
}
|
||||
this.resume = /** @type {number} */ (this.getMachineParm('resume', parmsComputer, Str.TYPES.NUMBER, ComputerPDP11.RESUME_NONE));
|
||||
|
||||
/*
|
||||
* The Computer 'state' property allows a state file to be specified independent of the 'resume' feature;
|
||||
|
|
@ -227,11 +214,11 @@ class ComputerPDP11 extends Component {
|
|||
* OVERRIDES everything; it overrides any 'state' Computer parameter AND it disables resume of any saved state in
|
||||
* localStorage (in other words, it prevents fAllowResume from being true, and forcing resume off).
|
||||
*/
|
||||
var fAllowResume;
|
||||
var fAllowResume, sStatePath = null;
|
||||
var sState = this.getMachineParm('state') || (fAllowResume = true) && parmsComputer['state'];
|
||||
|
||||
if (sState) {
|
||||
sStatePath = this.sStatePath = sState;
|
||||
this.sStatePath = sStatePath = sState;
|
||||
if (!fAllowResume) {
|
||||
this.fServerState = true;
|
||||
this.resume = ComputerPDP11.RESUME_NONE;
|
||||
|
|
@ -305,21 +292,26 @@ class ComputerPDP11 extends Component {
|
|||
}
|
||||
|
||||
/**
|
||||
* getMachineParm(sParm, parmsComponent, type)
|
||||
* getMachineParm(sParm, parmsComponent, type, defaultValue)
|
||||
*
|
||||
* If the machine parameter doesn't exist, we check for a matching component parameter (if parmsComponent is provided),
|
||||
* and failing that, we check the bundled resources (if any).
|
||||
* If the machine parameter doesn't exist, we check for a matching component parameter
|
||||
* (if parmsComponent is provided), and failing that, we check the bundled resources (if any).
|
||||
*
|
||||
* At the moment, the only bundled resource request we expect to encounter is 'state'; if it exists, then we return
|
||||
* 'state' back to the caller (ie, the name of the resource), so that the caller will then attempt to load the 'state'
|
||||
* resource to obtain the actual state.
|
||||
* At the moment, the only bundled resource request we expect to encounter is 'state'; if it exists,
|
||||
* then we return 'state' back to the caller (ie, the name of the resource), so that the caller will
|
||||
* then attempt to load the 'state' resource to obtain the actual state.
|
||||
*
|
||||
* TODO: It would be nice if we could tell the Closure Compiler that when a specific type parameter
|
||||
* (eg, Str.TYPES.NUMBER) is used, the return value will be that type; unfortunately, every caller
|
||||
* must coerce their own return value.
|
||||
*
|
||||
* @param {string} sParm
|
||||
* @param {Object|null} [parmsComponent]
|
||||
* @param {number} [type] (from Str.TYPES)
|
||||
* @return {string|undefined}
|
||||
* @param {*} [defaultValue]
|
||||
* @return {*}
|
||||
*/
|
||||
getMachineParm(sParm, parmsComponent, type)
|
||||
getMachineParm(sParm, parmsComponent, type, defaultValue)
|
||||
{
|
||||
/*
|
||||
* When checking parmsURL, the check is allowed be a bit looser, because URL parameters are
|
||||
|
|
@ -329,20 +321,15 @@ class ComputerPDP11 extends Component {
|
|||
*/
|
||||
var sParmLC = sParm.toLowerCase();
|
||||
var value = Web.getURLParm(sParm) || Web.getURLParm(sParmLC);
|
||||
|
||||
if (value === undefined && this.parmsMachine) {
|
||||
value = this.parmsMachine[sParm];
|
||||
}
|
||||
if (value === undefined && parmsComponent) {
|
||||
value = parmsComponent[sParm];
|
||||
}
|
||||
if (value === undefined && typeof resources == 'object' && resources[sParm]) {
|
||||
value = sParm;
|
||||
}
|
||||
if (value === undefined && this.parmsMachine) value = this.parmsMachine[sParm];
|
||||
if (value === undefined && parmsComponent) value = parmsComponent[sParm];
|
||||
if (value === undefined && typeof resources == 'object' && resources[sParm]) value = sParm;
|
||||
if (value === undefined) value = defaultValue;
|
||||
if (typeof value == "string" && type) {
|
||||
switch(type) {
|
||||
case Str.TYPES.NUMBER:
|
||||
value = +value;
|
||||
if (isNaN(/** @type {number} */(value))) value = defaultValue || 0;
|
||||
break;
|
||||
case Str.TYPES.BOOLEAN:
|
||||
value = (value == "true");
|
||||
|
|
@ -428,6 +415,7 @@ class ComputerPDP11 extends Component {
|
|||
}
|
||||
}
|
||||
if (DEBUG && this.messageEnabled()) this.printMessage("ComputerPDP11.wait(ready)");
|
||||
//noinspection JSUnresolvedFunction
|
||||
fn.call(this, parms);
|
||||
}
|
||||
|
||||
|
|
@ -615,11 +603,15 @@ class ComputerPDP11 extends Component {
|
|||
{
|
||||
if (!component.flags.powered) {
|
||||
|
||||
/*
|
||||
* TODO: If all components called super.powerUp(), the powered flag would be set automatically.
|
||||
*/
|
||||
this.assert(component.powerUp);
|
||||
component.flags.powered = true;
|
||||
|
||||
if (component.powerUp) {
|
||||
var data = null;
|
||||
|
||||
var data = null;
|
||||
try {
|
||||
if (fRestore) {
|
||||
data = stateComputer.get(component.id);
|
||||
if (!data) {
|
||||
|
|
@ -692,14 +684,17 @@ class ComputerPDP11 extends Component {
|
|||
*/
|
||||
fRestore = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fRepower && component.comment) {
|
||||
var asComments = component.comment.split("|");
|
||||
for (var i = 0; i < asComments.length; i++) {
|
||||
component.status(asComments[i]);
|
||||
if (!fRepower && component.comment) {
|
||||
var asComments = component.comment.split("|");
|
||||
for (var i = 0; i < asComments.length; i++) {
|
||||
component.status(asComments[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
Component.error("Error restoring state for " + component.type + " (" + err.message + ")");
|
||||
}
|
||||
}
|
||||
return fRestore;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ class CPUPDP11 extends Component {
|
|||
}
|
||||
|
||||
if (!fRepower) {
|
||||
if (!data || !this.restore) {
|
||||
if (!data) {
|
||||
this.reset();
|
||||
} else {
|
||||
this.resetCycles();
|
||||
|
|
@ -293,12 +293,6 @@ class CPUPDP11 extends Component {
|
|||
*/
|
||||
powerDown(fSave, fShutdown)
|
||||
{
|
||||
/*
|
||||
* The Computer component (which is responsible for all powerDown and powerUp notifications)
|
||||
* is now responsible for managing a component's fPowered flag, not us.
|
||||
*
|
||||
* this.flags.powered = false;
|
||||
*/
|
||||
return fSave? this.save() : true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,11 @@ if (NODE) {
|
|||
}
|
||||
|
||||
/*
|
||||
* Decoding starts at the bottom of this file, in op1120() and op1145().
|
||||
* Decoding starts near the bottom of this file, in op1120() and op1140(). Obviously, there are
|
||||
* MANY more PDP-11 models than the 11/20 and 11/40, but for the broad model categories that PDPjs
|
||||
* supports (ie, MODEL_1120, MODEL_1140, MODEL_1145, and MODEL_1170), the biggest differences are
|
||||
* between MODEL_1120 and MODEL_1140, so decoding is divided into those two categories, and all
|
||||
* other differences are handled inside the opcode handlers.
|
||||
*
|
||||
* The basic decoding approach is to dispatch on the top 4 bits of the opcode, and if further
|
||||
* decoding is required, the dispatched function will dispatch on the next 4 bits, and so on
|
||||
|
|
@ -53,6 +57,11 @@ if (NODE) {
|
|||
* For example, opADD() passes the helper function fnADD() to the appropriate update method. This
|
||||
* allows the update method to perform the entire read/modify/write operation, because the modify
|
||||
* step is performed internally, via the fnXXX() helper function.
|
||||
*
|
||||
* For the handful of instructions in the 1140 tables that actually exist only on the 11/45 and
|
||||
* 11/70 (ie, MFPD, MTPD, and SPL), those opcode handlers perform their own model checks. That's
|
||||
* simpler than creating additional tables, and seems fine for instructions that are not commonly
|
||||
* executed.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
@ -1302,6 +1311,23 @@ PDP11.opMFPI = function(opCode)
|
|||
this.nStepCycles -= (10 + 1);
|
||||
};
|
||||
|
||||
/**
|
||||
* opMFPS(opCode)
|
||||
*
|
||||
* 1067XX MFPS - Move Byte From PSW
|
||||
*
|
||||
* The 8-bit contents of the PS are moved to the effective destination. If destination is mode 0,
|
||||
* PS bit 7 is sign extended through the upper byte of the register. The destination operand is treated
|
||||
* as a byte address. 11/34A only.
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} opCode
|
||||
*/
|
||||
PDP11.opMFPS = function(opCode)
|
||||
{
|
||||
PDP11.opUndefined.call(this, opCode);
|
||||
};
|
||||
|
||||
/**
|
||||
* opMFPT(opCode)
|
||||
*
|
||||
|
|
@ -1321,10 +1347,7 @@ PDP11.opMFPI = function(opCode)
|
|||
*/
|
||||
PDP11.opMFPT = function(opCode)
|
||||
{
|
||||
/*
|
||||
* TODO: Review
|
||||
*/
|
||||
this.trap(PDP11.TRAP.RESERVED, 0, PDP11.REASON.OPCODE);
|
||||
PDP11.opUndefined.call(this, opCode);
|
||||
};
|
||||
|
||||
PDP11.MOV_CYCLES = [
|
||||
|
|
@ -1405,6 +1428,23 @@ PDP11.opMTPI = function(opCode)
|
|||
this.nStepCycles = this.nSnapCycles - PDP11.MTP_CYCLES[this.dstMode];
|
||||
};
|
||||
|
||||
/**
|
||||
* opMTPS(opCode)
|
||||
*
|
||||
* 1064XX MTPS - Move Byte To PSW
|
||||
*
|
||||
* The 8 bits of the effective operand replace the current contents of the PS <0:7>. The source operand
|
||||
* address is treated as a byte address. Note that PS bit 4 cannot be set with this instruction. The
|
||||
* src operand remains unchanged. 11/34A only.
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} opCode
|
||||
*/
|
||||
PDP11.opMTPS = function(opCode)
|
||||
{
|
||||
PDP11.opUndefined.call(this, opCode);
|
||||
};
|
||||
|
||||
/**
|
||||
* opMUL(opCode)
|
||||
*
|
||||
|
|
@ -1588,6 +1628,7 @@ PDP11.opRTI = function(opCode)
|
|||
PDP11.opRTS = function(opCode)
|
||||
{
|
||||
if (opCode & 0x08) {
|
||||
//noinspection JSUnresolvedFunction
|
||||
PDP11.opUndefined.call(this, opCode);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1731,7 +1772,8 @@ PDP11.opSOB = function(opCode)
|
|||
*/
|
||||
PDP11.opSPL = function(opCode)
|
||||
{
|
||||
if (!(opCode & 0x08)) {
|
||||
if (!(opCode & 0x08) || this.model < PDP11.MODEL_1145) {
|
||||
//noinspection JSUnresolvedFunction
|
||||
PDP11.opUndefined.call(this, opCode);
|
||||
return;
|
||||
}
|
||||
|
|
@ -2219,103 +2261,108 @@ PDP11.aOp8CXn_1120 = [
|
|||
];
|
||||
|
||||
/**
|
||||
* op1145(opCode)
|
||||
* op1140(opCode)
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} opCode
|
||||
*/
|
||||
PDP11.op1145 = function(opCode)
|
||||
PDP11.op1140 = function(opCode)
|
||||
{
|
||||
PDP11.aOpXnnn_1145[opCode >> 12].call(this, opCode);
|
||||
PDP11.aOpXnnn_1140[opCode >> 12].call(this, opCode);
|
||||
};
|
||||
|
||||
/**
|
||||
* op0Xnn_1145(opCode)
|
||||
* op0Xnn_1140(opCode)
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} opCode
|
||||
*/
|
||||
PDP11.op0Xnn_1145 = function(opCode)
|
||||
PDP11.op0Xnn_1140 = function(opCode)
|
||||
{
|
||||
PDP11.aOp0Xnn_1145[(opCode >> 8) & 0xf].call(this, opCode);
|
||||
PDP11.aOp0Xnn_1140[(opCode >> 8) & 0xf].call(this, opCode);
|
||||
};
|
||||
|
||||
/**
|
||||
* op0DXn_1145(opCode)
|
||||
* op0DXn_1140(opCode)
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} opCode
|
||||
*/
|
||||
PDP11.op0DXn_1145 = function(opCode)
|
||||
PDP11.op0DXn_1140 = function(opCode)
|
||||
{
|
||||
PDP11.aOp0DXn_1145[(opCode >> 6) & 0x3].call(this, opCode);
|
||||
PDP11.aOp0DXn_1140[(opCode >> 6) & 0x3].call(this, opCode);
|
||||
};
|
||||
|
||||
/**
|
||||
* op00Xn_1145(opCode)
|
||||
* op00Xn_1140(opCode)
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} opCode
|
||||
*/
|
||||
PDP11.op00Xn_1145 = function(opCode)
|
||||
PDP11.op00Xn_1140 = function(opCode)
|
||||
{
|
||||
PDP11.aOp00Xn_1145[(opCode >> 4) & 0xf].call(this, opCode);
|
||||
PDP11.aOp00Xn_1140[(opCode >> 4) & 0xf].call(this, opCode);
|
||||
};
|
||||
|
||||
/**
|
||||
* op000X_1145(opCode)
|
||||
* op000X_1140(opCode)
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} opCode
|
||||
*/
|
||||
PDP11.op000X_1145 = function(opCode)
|
||||
PDP11.op000X_1140 = function(opCode)
|
||||
{
|
||||
PDP11.aOp000X_1145[opCode & 0xf].call(this, opCode);
|
||||
PDP11.aOp000X_1140[opCode & 0xf].call(this, opCode);
|
||||
};
|
||||
|
||||
/**
|
||||
* op7Xnn_1145(opCode)
|
||||
* op7Xnn_1140(opCode)
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} opCode
|
||||
*/
|
||||
PDP11.op7Xnn_1145 = function(opCode)
|
||||
PDP11.op7Xnn_1140 = function(opCode)
|
||||
{
|
||||
PDP11.aOp7Xnn_1145[(opCode >> 8) & 0xf].call(this, opCode);
|
||||
PDP11.aOp7Xnn_1140[(opCode >> 8) & 0xf].call(this, opCode);
|
||||
};
|
||||
|
||||
/**
|
||||
* op8Xnn_1145(opCode)
|
||||
* op8Xnn_1140(opCode)
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} opCode
|
||||
*/
|
||||
PDP11.op8Xnn_1145 = function(opCode)
|
||||
PDP11.op8Xnn_1140 = function(opCode)
|
||||
{
|
||||
PDP11.aOp8Xnn_1145[(opCode >> 8) & 0xf].call(this, opCode);
|
||||
PDP11.aOp8Xnn_1140[(opCode >> 8) & 0xf].call(this, opCode);
|
||||
};
|
||||
|
||||
/**
|
||||
* op8DXn_1145(opCode)
|
||||
* op8DXn_1140(opCode)
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} opCode
|
||||
*/
|
||||
PDP11.op8DXn_1145 = function(opCode)
|
||||
PDP11.op8DXn_1140 = function(opCode)
|
||||
{
|
||||
PDP11.aOp8DXn_1145[(opCode >> 6) & 0x3].call(this, opCode);
|
||||
if (this.model < PDP11.MODEL_1145) {
|
||||
//noinspection JSUnresolvedFunction
|
||||
PDP11.opUndefined.call(this, opCode);
|
||||
return;
|
||||
}
|
||||
PDP11.aOp8DXn_1140[(opCode >> 6) & 0x3].call(this, opCode);
|
||||
};
|
||||
|
||||
PDP11.aOpXnnn_1145 = [
|
||||
PDP11.op0Xnn_1145, // 0x0nnn
|
||||
PDP11.aOpXnnn_1140 = [
|
||||
PDP11.op0Xnn_1140, // 0x0nnn
|
||||
PDP11.opMOV, // 0x1nnn 01SSDD 11/20+ 2.3
|
||||
PDP11.opCMP, // 0x2nnn 02SSDD 11/20+ 2.3*
|
||||
PDP11.opBIT, // 0x3nnn 03SSDD 11/20+ 2.9*
|
||||
PDP11.opBIC, // 0x4nnn 04SSDD 11/20+ 2.9
|
||||
PDP11.opBIS, // 0x5nnn 05SSDD 11/20+ 2.3
|
||||
PDP11.opADD, // 0x6nnn 06SSDD 11/20+ 2.3
|
||||
PDP11.op7Xnn_1145, // 0x7nnn
|
||||
PDP11.op8Xnn_1145, // 0x8nnn
|
||||
PDP11.op7Xnn_1140, // 0x7nnn
|
||||
PDP11.op8Xnn_1140, // 0x8nnn
|
||||
PDP11.opMOVB, // 0x9nnn 11SSDD 11/20+ 2.3
|
||||
PDP11.opCMPB, // 0xAnnn 12SSDD 11/20+ 2.3
|
||||
PDP11.opBITB, // 0xBnnn 13SSDD 11/20+ 2.9
|
||||
|
|
@ -2325,8 +2372,8 @@ PDP11.aOpXnnn_1145 = [
|
|||
PDP11.opUndefined // 0xFnnn
|
||||
];
|
||||
|
||||
PDP11.aOp0Xnn_1145 = [
|
||||
PDP11.op00Xn_1145, // 0x00nn
|
||||
PDP11.aOp0Xnn_1140 = [
|
||||
PDP11.op00Xn_1140, // 0x00nn
|
||||
PDP11.opBR, // 0x01nn 0004XX 11/20+ 2.6
|
||||
PDP11.opBNE, // 0x02nn 0010XX 11/20+ 2.6**
|
||||
PDP11.opBEQ, // 0x03nn 0014XX 11/20+ 2.6**
|
||||
|
|
@ -2339,20 +2386,20 @@ PDP11.aOp0Xnn_1145 = [
|
|||
PDP11.op0AXn_1120, // 0x0Ann
|
||||
PDP11.op0BXn_1120, // 0x0Bnn
|
||||
PDP11.op0CXn_1120, // 0x0Cnn
|
||||
PDP11.op0DXn_1145, // 0x0Dnn
|
||||
PDP11.op0DXn_1140, // 0x0Dnn
|
||||
PDP11.opUndefined, // 0x0Enn
|
||||
PDP11.opUndefined // 0x0Fnn
|
||||
];
|
||||
|
||||
PDP11.aOp0DXn_1145 = [
|
||||
PDP11.opMARK, // 0x0D0n 11/45+
|
||||
PDP11.opMFPI, // 0x0D4n 11/45+
|
||||
PDP11.opMTPI, // 0x0D8n 11/45+
|
||||
PDP11.opSXT // 0x0DCn 11/45+
|
||||
PDP11.aOp0DXn_1140 = [
|
||||
PDP11.opMARK, // 0x0D0n 11/40+ LEIS
|
||||
PDP11.opMFPI, // 0x0D4n 11/40+
|
||||
PDP11.opMTPI, // 0x0D8n 11/40+
|
||||
PDP11.opSXT // 0x0DCn 11/40+ LEIS
|
||||
];
|
||||
|
||||
PDP11.aOp00Xn_1145 = [
|
||||
PDP11.op000X_1145, // 0x000n 000000-000017
|
||||
PDP11.aOp00Xn_1140 = [
|
||||
PDP11.op000X_1140, // 0x000n 000000-000017
|
||||
PDP11.opUndefined, // 0x001n 000020-000037
|
||||
PDP11.opUndefined, // 0x002n 000040-000057
|
||||
PDP11.opUndefined, // 0x003n 000060-000077
|
||||
|
|
@ -2370,15 +2417,15 @@ PDP11.aOp00Xn_1145 = [
|
|||
PDP11.opSWAB // 0x00Fn 0003DD 11/20+ 2.3
|
||||
];
|
||||
|
||||
PDP11.aOp000X_1145 = [
|
||||
PDP11.aOp000X_1140 = [
|
||||
PDP11.opHALT, // 0x0000 000000 11/20+ 1.8
|
||||
PDP11.opWAIT, // 0x0001 000001 11/20+ 1.8
|
||||
PDP11.opRTI, // 0x0002 000002 11/20+ 4.8
|
||||
PDP11.opBPT, // 0x0003 000003
|
||||
PDP11.opIOT, // 0x0004 000004 11/20+ 9.3
|
||||
PDP11.opRESET, // 0x0005 000005 11/20+ 20ms
|
||||
PDP11.opRTT, // 0x0006 000006 11/45+
|
||||
PDP11.opMFPT, // 0x0007 000007 TBD
|
||||
PDP11.opRTT, // 0x0006 000006 11/40+ LEIS
|
||||
PDP11.opMFPT, // 0x0007 000007 11/44+
|
||||
PDP11.opUndefined, // 0x0008
|
||||
PDP11.opUndefined, // 0x0009
|
||||
PDP11.opUndefined, // 0x000A
|
||||
|
|
@ -2389,26 +2436,26 @@ PDP11.aOp000X_1145 = [
|
|||
PDP11.opUndefined // 0x000F
|
||||
];
|
||||
|
||||
PDP11.aOp7Xnn_1145 = [
|
||||
PDP11.opMUL, // 0x70nn 11/45+
|
||||
PDP11.opMUL, // 0x71nn 11/45+
|
||||
PDP11.opDIV, // 0x72nn 11/45+
|
||||
PDP11.opDIV, // 0x73nn 11/45+
|
||||
PDP11.opASH, // 0x74nn 11/45+
|
||||
PDP11.opASH, // 0x75nn 11/45+
|
||||
PDP11.opASHC, // 0x76nn 11/45+
|
||||
PDP11.opASHC, // 0x77nn 11/45+
|
||||
PDP11.opXOR, // 0x78nn 11/45+
|
||||
PDP11.opXOR, // 0x79nn 11/45+
|
||||
PDP11.aOp7Xnn_1140 = [
|
||||
PDP11.opMUL, // 0x70nn 11/40+ EIS
|
||||
PDP11.opMUL, // 0x71nn 11/40+ EIS
|
||||
PDP11.opDIV, // 0x72nn 11/40+ EIS
|
||||
PDP11.opDIV, // 0x73nn 11/40+ EIS
|
||||
PDP11.opASH, // 0x74nn 11/40+ EIS
|
||||
PDP11.opASH, // 0x75nn 11/40+ EIS
|
||||
PDP11.opASHC, // 0x76nn 11/40+ EIS
|
||||
PDP11.opASHC, // 0x77nn 11/40+ EIS
|
||||
PDP11.opXOR, // 0x78nn 11/40+ LEIS
|
||||
PDP11.opXOR, // 0x79nn 11/40+ LEIS
|
||||
PDP11.opUndefined, // 0x7Ann
|
||||
PDP11.opUndefined, // 0x7Bnn
|
||||
PDP11.opUndefined, // 0x7Cnn
|
||||
PDP11.opUndefined, // 0x7Dnn
|
||||
PDP11.opSOB, // 0x7Enn 11/45+
|
||||
PDP11.opSOB // 0x7Fnn 11/45+
|
||||
PDP11.opSOB, // 0x7Enn 11/40+ LEIS
|
||||
PDP11.opSOB // 0x7Fnn 11/40+ LEIS
|
||||
];
|
||||
|
||||
PDP11.aOp8Xnn_1145 = [
|
||||
PDP11.aOp8Xnn_1140 = [
|
||||
PDP11.opBPL, // 0x80nn 1000XX 11/20+ 2.6**
|
||||
PDP11.opBMI, // 0x81nn 1004XX 11/20+ 2.6**
|
||||
PDP11.opBHI, // 0x82nn 1010XX 11/20+ 2.6**
|
||||
|
|
@ -2419,17 +2466,17 @@ PDP11.aOp8Xnn_1145 = [
|
|||
PDP11.opBCS, // 0x87nn 1034XX 11/20+ 2.6**
|
||||
PDP11.opEMT, // 0x88nn 104000-104377 11/20+ 9.3
|
||||
PDP11.opTRAP, // 0x89nn 104400-104777 11/20+ 9.3
|
||||
PDP11.op8AXn_1120, // 0x8Ann
|
||||
PDP11.op8BXn_1120, // 0x8Bnn
|
||||
PDP11.op8CXn_1120, // 0x8Cnn
|
||||
PDP11.op8DXn_1145, // 0x8Dnn
|
||||
PDP11.opUndefined, // 0x8Enn
|
||||
PDP11.opUndefined // 0x8Fnn
|
||||
PDP11.op8AXn_1120, // 0x8Ann 1050XX
|
||||
PDP11.op8BXn_1120, // 0x8Bnn 1054XX
|
||||
PDP11.op8CXn_1120, // 0x8Cnn 1060XX
|
||||
PDP11.op8DXn_1140, // 0x8Dnn 106400-106777
|
||||
PDP11.opUndefined, // 0x8Enn 1070XX
|
||||
PDP11.opUndefined // 0x8Fnn 1074XX
|
||||
];
|
||||
|
||||
PDP11.aOp8DXn_1145 = [
|
||||
PDP11.opUndefined, // 0x8D0n
|
||||
PDP11.opMFPD, // 0x8D4n 11/45+
|
||||
PDP11.opMTPD, // 0x8D8n 11/45+
|
||||
PDP11.opUndefined // 0x8DCn
|
||||
PDP11.aOp8DXn_1140 = [
|
||||
PDP11.opMTPS, // 0x8D0n 1064XX 11/34A only
|
||||
PDP11.opMFPD, // 0x8D4n 1065XX 11/45+
|
||||
PDP11.opMTPD, // 0x8D8n 1066XX 11/45+
|
||||
PDP11.opMFPS // 0x8DCn 1067XX 11/34A only
|
||||
];
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ class CPUStatePDP11 extends CPUPDP11 {
|
|||
}
|
||||
|
||||
/*
|
||||
* WARNING: With ES6 classes, you cannot access "this" until all superclasses have been initialized as well.
|
||||
* ES6 ALERT: Classes cannot access "this" until all superclasses have been initialized as well.
|
||||
*/
|
||||
super(parmsCPU, nCyclesDefault);
|
||||
|
||||
|
|
@ -156,10 +156,14 @@ class CPUStatePDP11 extends CPUPDP11 {
|
|||
this.pswUsed = ~(PDP11.PSW.UNUSED | PDP11.PSW.REGSET | PDP11.PSW.PMODE | PDP11.PSW.CMODE) & 0xffff;
|
||||
this.pswRegSet = 0;
|
||||
} else {
|
||||
this.decode = PDP11.op1145.bind(this);
|
||||
this.checkStackLimit = this.checkStackLimit1145;
|
||||
this.pswUsed = ~(PDP11.PSW.UNUSED | (this.model < PDP11.MODEL_1145? PDP11.PSW.REGSET : 0)) & 0xffff;
|
||||
this.pswRegSet = (this.model >= PDP11.MODEL_1145? PDP11.PSW.REGSET : 0);
|
||||
this.decode = PDP11.op1140.bind(this);
|
||||
this.checkStackLimit = this.checkStackLimit1140;
|
||||
/*
|
||||
* The alternate register set (REGSET) doesn't exist on the 11/20 or 11/40; it's available on the 11/45 and 11/70.
|
||||
* Ditto for separate I/D spaces, SUPER mode, and the instructions MFPD, MTPD, and SPL.
|
||||
*/
|
||||
this.pswUsed = ~(PDP11.PSW.UNUSED | (this.model <= PDP11.MODEL_1140? PDP11.PSW.REGSET : 0)) & 0xffff;
|
||||
this.pswRegSet = (this.model > PDP11.MODEL_1140? PDP11.PSW.REGSET : 0);
|
||||
}
|
||||
|
||||
this.nDisableTraps = 0;
|
||||
|
|
@ -209,6 +213,9 @@ class CPUStatePDP11 extends CPUPDP11 {
|
|||
/**
|
||||
* powerUp(data, fRepower)
|
||||
*
|
||||
* We hook the powerUp() notification only because it's our best opportunity to take care of any
|
||||
* floating vector assignments.
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {Object|null} data
|
||||
* @param {boolean} [fRepower]
|
||||
|
|
@ -265,8 +272,7 @@ class CPUStatePDP11 extends CPUPDP11 {
|
|||
this.flagN = 0x8000; // PSW N bit
|
||||
this.regPSW = 0x000f; // PSW other bits (TODO: What's the point of setting the flag bits here, too?)
|
||||
this.regsGen = [ // General R0-R7
|
||||
0, 0, 0, 0, 0, 0, 0, this.addrReset,
|
||||
-1, -2, -3, -4, -5, -6, -7, -8
|
||||
0, 0, 0, 0, 0, 0, 0, this.addrReset, -1, -2, -3, -4, -5, -6, -7, -8
|
||||
];
|
||||
|
||||
this.regsAlt = [ // Alternate R0-R5
|
||||
|
|
@ -550,7 +556,7 @@ class CPUStatePDP11 extends CPUPDP11 {
|
|||
setMMR3(newMMR3)
|
||||
{
|
||||
/*
|
||||
* Don't allow the 11/45 to use 22-bit addressing or the UNIBUS map.
|
||||
* Don't allow non-11/70 models to use 22-bit addressing or the UNIBUS map.
|
||||
*/
|
||||
if (this.model < PDP11.MODEL_1170) {
|
||||
newMMR3 &= ~(PDP11.MMR3.MMU_22BIT | PDP11.MMR3.UNIBUS_MAP);
|
||||
|
|
@ -610,19 +616,19 @@ class CPUStatePDP11 extends CPUPDP11 {
|
|||
/**
|
||||
* getChecksum()
|
||||
*
|
||||
* TODO: Implement
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @return {number} a 32-bit summation of key elements of the current CPU state (used by the CPU checksum code)
|
||||
*/
|
||||
getChecksum()
|
||||
{
|
||||
return 0; // TODO: Implement
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* save()
|
||||
*
|
||||
* This implements save support for the CPUStatePDP11 component.
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @return {Object|null}
|
||||
*/
|
||||
|
|
@ -639,7 +645,6 @@ class CPUStatePDP11 extends CPUPDP11 {
|
|||
this.regMBR,
|
||||
this.regPIR,
|
||||
this.regSLR,
|
||||
this.getPSW(),
|
||||
this.pswTrap,
|
||||
this.pswMode,
|
||||
this.opFlags,
|
||||
|
|
@ -656,26 +661,60 @@ class CPUStatePDP11 extends CPUPDP11 {
|
|||
this.addrLast,
|
||||
this.opLast
|
||||
]);
|
||||
state.set(1, [this.nTotalCycles, this.getSpeed()]);
|
||||
state.set(2, this.bus.saveMemory());
|
||||
state.set(1, [this.getPSW()]);
|
||||
state.set(2, [this.nTotalCycles, this.getSpeed()]);
|
||||
return state.data();
|
||||
}
|
||||
|
||||
/**
|
||||
* restore(data)
|
||||
*
|
||||
* This implements restore support for the CPUStatePDP11 component.
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {Object} data
|
||||
* @return {boolean} true if restore successful, false if not
|
||||
*/
|
||||
restore(data)
|
||||
{
|
||||
var a = data[1];
|
||||
this.nTotalCycles = a[1];
|
||||
this.setSpeed(a[3]);
|
||||
return this.bus.restoreMemory(data[2]);
|
||||
var a;
|
||||
/*
|
||||
* ES6 ALERT: Gotta love these destructuring assignments, which make it easy to perform the inverse
|
||||
* of what save() does when it collects a bunch of object properties into an array.
|
||||
*/
|
||||
[
|
||||
this.regsGen,
|
||||
this.regsAlt,
|
||||
this.regsAltStack,
|
||||
this.regsUniMap,
|
||||
this.regsControl,
|
||||
this.regErr,
|
||||
this.regMBR,
|
||||
this.regPIR,
|
||||
this.regSLR,
|
||||
this.pswTrap,
|
||||
this.pswMode,
|
||||
this.opFlags,
|
||||
this.regMMR0,
|
||||
this.regMMR1,
|
||||
this.regMMR2,
|
||||
this.regMMR3,
|
||||
this.mmuLastMode,
|
||||
this.mmuLastPage,
|
||||
this.mmuPDR,
|
||||
this.mmuPAR,
|
||||
this.mmuEnable,
|
||||
this.mmuMask,
|
||||
this.addrLast,
|
||||
this.opLast
|
||||
] = data[0];
|
||||
|
||||
a = data[1];
|
||||
this.setPSW(a[0]);
|
||||
|
||||
a = data[2];
|
||||
this.nTotalCycles = a[0];
|
||||
this.setSpeed(a[1]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1213,13 +1252,6 @@ class CPUStatePDP11 extends CPUPDP11 {
|
|||
*/
|
||||
getPSW()
|
||||
{
|
||||
/*
|
||||
* TODO: I'm not sure why this function can't simply be written as:
|
||||
*
|
||||
* return (this.regPSW & ~PDP11.PSW.FLAGS) | (this.getNF() | this.getZF() | this.getVF() | this.getCF());
|
||||
*
|
||||
* but for now, I'm keeping the same masking logic as the original pdp11.js.
|
||||
*/
|
||||
var mask = PDP11.PSW.CMODE | PDP11.PSW.PMODE | PDP11.PSW.REGSET | PDP11.PSW.PRI | PDP11.PSW.TF;
|
||||
return this.regPSW = (this.regPSW & mask) | this.getNF() | this.getZF() | this.getVF() | this.getCF();
|
||||
}
|
||||
|
|
@ -2148,14 +2180,14 @@ class CPUStatePDP11 extends CPUPDP11 {
|
|||
}
|
||||
|
||||
/**
|
||||
* checkStackLimit1145(access, step, addr)
|
||||
* checkStackLimit1140(access, step, addr)
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} access
|
||||
* @param {number} step
|
||||
* @param {number} addr
|
||||
*/
|
||||
checkStackLimit1145(access, step, addr)
|
||||
checkStackLimit1140(access, step, addr)
|
||||
{
|
||||
if (!this.pswMode) {
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -303,10 +303,15 @@ class DebuggerPDP11 extends Debugger {
|
|||
/*
|
||||
* Re-initialize Debugger message support if necessary
|
||||
*/
|
||||
var sMessages = cmp.getMachineParm('messages');
|
||||
var sMessages = /** @type {string|undefined} */ (cmp.getMachineParm('messages'));
|
||||
if (sMessages) this.messageInit(sMessages);
|
||||
|
||||
if (this.cpu.model < PDP11.MODEL_1145) this.aOpReserved = DebuggerPDP11.OP1145;
|
||||
if (this.cpu.model < PDP11.MODEL_1140) {
|
||||
this.aOpReserved = this.aOpReserved.concat(DebuggerPDP11.OP1140);
|
||||
}
|
||||
if (this.cpu.model < PDP11.MODEL_1145) {
|
||||
this.aOpReserved = this.aOpReserved.concat(DebuggerPDP11.OP1145);
|
||||
}
|
||||
|
||||
this.messageDump(MessagesPDP11.BUS, function onDumpBus(asArgs) { dbg.dumpBus(asArgs); });
|
||||
|
||||
|
|
@ -4350,21 +4355,27 @@ if (DEBUGGER) {
|
|||
DebuggerPDP11.OPNONE = [DebuggerPDP11.OPS.NONE];
|
||||
|
||||
/*
|
||||
* Table of opcodes specific to the 11/45 and newer
|
||||
* Table of opcodes added to the 11/40 and newer
|
||||
*/
|
||||
DebuggerPDP11.OP1145 = [
|
||||
DebuggerPDP11.OP1140 = [
|
||||
DebuggerPDP11.OPS.MARK,
|
||||
DebuggerPDP11.OPS.MFPI,
|
||||
DebuggerPDP11.OPS.MTPI,
|
||||
DebuggerPDP11.OPS.SXT,
|
||||
DebuggerPDP11.OPS.SPL,
|
||||
DebuggerPDP11.OPS.RTT,
|
||||
DebuggerPDP11.OPS.MUL,
|
||||
DebuggerPDP11.OPS.DIV,
|
||||
DebuggerPDP11.OPS.ASH,
|
||||
DebuggerPDP11.OPS.ASHC,
|
||||
DebuggerPDP11.OPS.XOR,
|
||||
DebuggerPDP11.OPS.SOB,
|
||||
DebuggerPDP11.OPS.SOB
|
||||
];
|
||||
|
||||
/*
|
||||
* Table of opcodes added to the 11/45 and newer
|
||||
*/
|
||||
DebuggerPDP11.OP1145 = [
|
||||
DebuggerPDP11.OPS.SPL,
|
||||
DebuggerPDP11.OPS.MFPD,
|
||||
DebuggerPDP11.OPS.MTPD
|
||||
];
|
||||
|
|
|
|||
|
|
@ -131,8 +131,9 @@ var PDP11 = {
|
|||
* The 11/40 added the MODE bits to the PSW (but only KERNEL=00 and USER=11) and 18-bit
|
||||
* addressing via an MMU; there was still only one register set.
|
||||
*
|
||||
* The 11/45 added REGSET bit to the PSW (along with the second register set), and added
|
||||
* SUPERVISOR=01 to the set of modes.
|
||||
* The 11/45 added REGSET bit to the PSW (to support a second register set), SUPER=01
|
||||
* mode to the existing KERNEL=00 and USER=11 modes, separate I/D spaces, and other MMU
|
||||
* extensions (eg, MMR1 and MMR3).
|
||||
*
|
||||
* The 11/70 added 22-bit addressing and corresponding extensions to the MMU.
|
||||
*/
|
||||
|
|
@ -163,10 +164,10 @@ var PDP11 = {
|
|||
* Processor modes
|
||||
*/
|
||||
MODE: {
|
||||
KERNEL: 0x0, // 11/40 and higher only
|
||||
SUPER: 0x1, // 11/45 and higher only
|
||||
KERNEL: 0x0, // 11/40 and higher
|
||||
SUPER: 0x1, // 11/45 and higher
|
||||
UNUSED: 0x2,
|
||||
USER: 0x3, // 11/40 and higher only
|
||||
USER: 0x3, // 11/40 and higher
|
||||
MASK: 0x3
|
||||
},
|
||||
/*
|
||||
|
|
@ -364,14 +365,14 @@ var PDP11 = {
|
|||
MMR0: { // 177572
|
||||
ENABLED: 0x0001, // 000001 address relocation enabled
|
||||
PAGE_NUM: 0x000E, // 000016 page number of last fault
|
||||
PAGE_D: 0x0010, // 000020 last fault occurred in D space (11/44 and 11/70 only)
|
||||
PAGE_D: 0x0010, // 000020 last fault occurred in D space (11/45 and 11/70)
|
||||
PAGE: 0x001E, // 000176 (all of the PAGE bits)
|
||||
MODE: 0x0060, // 000140 processor mode as of last fault
|
||||
COMPLETED: 0x0080, // 000200 last instruction completed (R/O) (11/70 only)
|
||||
COMPLETED: 0x0080, // 000200 last instruction completed (R/O) (11/70)
|
||||
MAINT: 0x0100, // 000400 only destination mode references will be relocated
|
||||
MMU_TRAPS: 0x0200, // 001000 enable MMU traps (11/70 only)
|
||||
MMU_TRAPS: 0x0200, // 001000 enable MMU traps (11/70)
|
||||
UNUSED: 0x0C00, // 006000
|
||||
TRAP_MMU: 0x1000, // 010000 trap: MMU (11/70 only)
|
||||
TRAP_MMU: 0x1000, // 010000 trap: MMU (11/70)
|
||||
ABORT_RO: 0x2000, // 020000 abort: read-only
|
||||
ABORT_PL: 0x4000, // 040000 abort: page length
|
||||
ABORT_NR: 0x8000, // 100000 abort: non-resident
|
||||
|
|
@ -382,7 +383,7 @@ var PDP11 = {
|
|||
MODE: 5
|
||||
}
|
||||
},
|
||||
MMR1: { // 177574: general purpose auto-inc/auto-dec register (11/44 and 11/70 only)
|
||||
MMR1: { // 177574: general purpose auto-inc/auto-dec register (11/45 and 11/70)
|
||||
REG1_NUM: 0x0007, //
|
||||
REG1_DELTA: 0x00F8, //
|
||||
REG2_NUM: 0x0700, //
|
||||
|
|
@ -390,7 +391,7 @@ var PDP11 = {
|
|||
},
|
||||
MMR2: { // 177576: virtual program counter register
|
||||
},
|
||||
MMR3: { // 172516: mapping register (11/44 and 11/70 only)
|
||||
MMR3: { // 172516: mapping register (11/45 and 11/70)
|
||||
USER_D: 0x0001, // (000001)
|
||||
SUPER_D: 0x0002, // (000002)
|
||||
KERNEL_D: 0x0004, // (000004)
|
||||
|
|
@ -400,11 +401,11 @@ var PDP11 = {
|
|||
PDR: {
|
||||
ACF: {
|
||||
NR: 0x0, // non-resident, abort all accesses
|
||||
RO1: 0x1, // read-only, abort on write attempt, memory management trap on read (11/70 only)
|
||||
RO1: 0x1, // read-only, abort on write attempt, memory management trap on read (11/70)
|
||||
RO: 0x2, // read-only, abort on write attempt
|
||||
U1: 0x3, // unused, abort all accesses--reserved for future use
|
||||
RW1: 0x4, // read/write, memory management trap upon completion of a read or write
|
||||
RW2: 0x5, // read/write, memory management trap upon completion of a write (11/70 only)
|
||||
RW2: 0x5, // read/write, memory management trap upon completion of a write (11/70)
|
||||
RW: 0x6, // read/write, no system trap/abort action
|
||||
U2: 0x7, // unused, abort all accesses--reserved for future use
|
||||
MASK: 0x7
|
||||
|
|
@ -412,7 +413,7 @@ var PDP11 = {
|
|||
ED: 0x0008, // expansion direction (if set, the page expands downward from block number 127)
|
||||
UNUSED: 0x0030,
|
||||
MODIFIED: 0x0040, // page has been written (bit cleared when either PDR or PAR is written)
|
||||
ACCESSED: 0x0080, // page has been accessed (bit cleared when either PDR or PAR is written) (11/70 only)
|
||||
ACCESSED: 0x0080, // page has been accessed (bit cleared when either PDR or PAR is written) (11/70)
|
||||
PLF: 0x7F00, // page length field
|
||||
BC: 0x8000 // bypass cache (11/44 only)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1145,18 +1145,18 @@ DevicePDP11.UNIBUS_IOTABLE = {
|
|||
[PDP11.UNIBUS.SDPDR0]: /* 172220 */ [null, null, DevicePDP11.prototype.readSDPDR, DevicePDP11.prototype.writeSDPDR, "SDPDR", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.SIPAR0]: /* 172240 */ [null, null, DevicePDP11.prototype.readSIPAR, DevicePDP11.prototype.writeSIPAR, "SIPAR", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.SDPAR0]: /* 172260 */ [null, null, DevicePDP11.prototype.readSDPAR, DevicePDP11.prototype.writeSDPAR, "SDPAR", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.KIPDR0]: /* 172300 */ [null, null, DevicePDP11.prototype.readKIPDR, DevicePDP11.prototype.writeKIPDR, "KIPDR", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.KIPDR0]: /* 172300 */ [null, null, DevicePDP11.prototype.readKIPDR, DevicePDP11.prototype.writeKIPDR, "KIPDR", 8, PDP11.MODEL_1140, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.KDPDR0]: /* 172320 */ [null, null, DevicePDP11.prototype.readKDPDR, DevicePDP11.prototype.writeKDPDR, "KDPDR", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.KIPAR0]: /* 172340 */ [null, null, DevicePDP11.prototype.readKIPAR, DevicePDP11.prototype.writeKIPAR, "KIPAR", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.KIPAR0]: /* 172340 */ [null, null, DevicePDP11.prototype.readKIPAR, DevicePDP11.prototype.writeKIPAR, "KIPAR", 8, PDP11.MODEL_1140, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.KDPAR0]: /* 172360 */ [null, null, DevicePDP11.prototype.readKDPAR, DevicePDP11.prototype.writeKDPAR, "KDPAR", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.MMR3]: /* 172516 */ [null, null, DevicePDP11.prototype.readMMR3, DevicePDP11.prototype.writeMMR3, "MMR3", 1, PDP11.MODEL_1145, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.LKS]: /* 177546 */ [null, null, DevicePDP11.prototype.readLKS, DevicePDP11.prototype.writeLKS, "LKS"],
|
||||
[PDP11.UNIBUS.MMR0]: /* 177572 */ [null, null, DevicePDP11.prototype.readMMR0, DevicePDP11.prototype.writeMMR0, "MMR0", 1, PDP11.MODEL_1145, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.MMR0]: /* 177572 */ [null, null, DevicePDP11.prototype.readMMR0, DevicePDP11.prototype.writeMMR0, "MMR0", 1, PDP11.MODEL_1140, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.MMR1]: /* 177574 */ [null, null, DevicePDP11.prototype.readMMR1, DevicePDP11.prototype.writeIgnored, "MMR1", 1, PDP11.MODEL_1145, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.MMR2]: /* 177576 */ [null, null, DevicePDP11.prototype.readMMR2, DevicePDP11.prototype.writeIgnored, "MMR2", 1, PDP11.MODEL_1145, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.UIPDR0]: /* 177600 */ [null, null, DevicePDP11.prototype.readUIPDR, DevicePDP11.prototype.writeUIPDR, "UIPDR", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.MMR2]: /* 177576 */ [null, null, DevicePDP11.prototype.readMMR2, DevicePDP11.prototype.writeIgnored, "MMR2", 1, PDP11.MODEL_1140, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.UIPDR0]: /* 177600 */ [null, null, DevicePDP11.prototype.readUIPDR, DevicePDP11.prototype.writeUIPDR, "UIPDR", 8, PDP11.MODEL_1140, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.UDPDR0]: /* 177620 */ [null, null, DevicePDP11.prototype.readUDPDR, DevicePDP11.prototype.writeUDPDR, "UDPDR", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.UIPAR0]: /* 177640 */ [null, null, DevicePDP11.prototype.readUIPAR, DevicePDP11.prototype.writeUIPAR, "UIPAR", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.UIPAR0]: /* 177640 */ [null, null, DevicePDP11.prototype.readUIPAR, DevicePDP11.prototype.writeUIPAR, "UIPAR", 8, PDP11.MODEL_1140, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.UDPAR0]: /* 177660 */ [null, null, DevicePDP11.prototype.readUDPAR, DevicePDP11.prototype.writeUDPAR, "UDPAR", 8, PDP11.MODEL_1145, MessagesPDP11.MMU],
|
||||
[PDP11.UNIBUS.R0SET0]: /* 177700 */ [null, null, DevicePDP11.prototype.readRSET0, DevicePDP11.prototype.writeRSET0, "R0SET0"],
|
||||
[PDP11.UNIBUS.R1SET0]: /* 177701 */ [null, null, DevicePDP11.prototype.readRSET0, DevicePDP11.prototype.writeRSET0, "R1SET0"],
|
||||
|
|
|
|||
|
|
@ -847,7 +847,7 @@ class PanelPDP11 extends Component {
|
|||
*/
|
||||
advanceAddr()
|
||||
{
|
||||
var nRegs = this.cpu.model < PDP11.MODEL_1145? 8 : 16;
|
||||
var nRegs = this.cpu.model <= PDP11.MODEL_1140? 8 : 16;
|
||||
var fGenRegs = (this.regAddr >= PDP11.UNIBUS.R0SET0 /*177700*/ && this.regAddr < PDP11.UNIBUS.R0SET0 + nRegs);
|
||||
var inc = fGenRegs? 1 : 2;
|
||||
var mask = fGenRegs? 0xf : this.bus.nBusMask;
|
||||
|
|
|
|||
|
|
@ -69,8 +69,8 @@ class PC11 extends Component {
|
|||
this.sDevice = "PTR"; // TODO: Make the device name configurable
|
||||
|
||||
/*
|
||||
* We record any 'autoMount' object now, but we no longer parse it until initBus(), because the
|
||||
* Computer's getMachineParm() service may have an override for us.
|
||||
* We preliminarily parse and record any 'autoMount' object now, but we no longer process it
|
||||
* until initBus(), because the Computer's getMachineParm() service may have an override for us.
|
||||
*/
|
||||
this.configMount = this.parseConfig(parms['autoMount']);
|
||||
this.cAutoMount = 0;
|
||||
|
|
|
|||
|
|
@ -61,8 +61,8 @@ class RK11 extends Component {
|
|||
super("RK11", parms, RK11, MessagesPDP11.RK11);
|
||||
|
||||
/*
|
||||
* We record any 'autoMount' object now, but we no longer parse it until initBus(),
|
||||
* because the Computer's getMachineParm() service may have an override for us.
|
||||
* We preliminarily parse and record any 'autoMount' object now, but we no longer process it
|
||||
* until initBus(), because the Computer's getMachineParm() service may have an override for us.
|
||||
*/
|
||||
this.configMount = this.parseConfig(parms['autoMount']);
|
||||
this.cAutoMount = 0;
|
||||
|
|
@ -309,7 +309,7 @@ class RK11 extends Component {
|
|||
*/
|
||||
this.initController();
|
||||
|
||||
this.irq = this.cpu.addIRQ(PDP11.RK11.VEC, PDP11.RK11.PRI, MessagesPDP11.RK11);
|
||||
this.irq = this.cpu.addIRQ(RK11.VEC, RK11.PRI, MessagesPDP11.RK11);
|
||||
|
||||
bus.addIOTable(this, RK11.UNIBUS_IOTABLE);
|
||||
bus.addResetHandler(this.reset.bind(this));
|
||||
|
|
@ -863,9 +863,9 @@ class RK11 extends Component {
|
|||
{
|
||||
var i = 0;
|
||||
if (!data) data = [];
|
||||
this.regRKDS = data[i++] || (PDP11.RK11.RKDS.RK05 | PDP11.RK11.RKDS.SOK | PDP11.RK11.RKDS.RRDY);
|
||||
this.regRKDS = data[i++] || (RK11.RKDS.RK05 | RK11.RKDS.SOK | RK11.RKDS.RRDY);
|
||||
this.regRKER = data[i++] || 0;
|
||||
this.regRKCS = data[i++] || (PDP11.RK11.RKCS.CRDY);
|
||||
this.regRKCS = data[i++] || (RK11.RKCS.CRDY);
|
||||
this.regRKWC = data[i++] || 0;
|
||||
this.regRKBA = data[i++] || 0;
|
||||
this.regRKDA = data[i++] || 0;
|
||||
|
|
@ -933,7 +933,7 @@ class RK11 extends Component {
|
|||
|
||||
if (!drive.disk) drive.sDiskPath = ""; // ensure this is initialized to a default that displayDisk() can deal with
|
||||
|
||||
drive.status = PDP11.RK11.RKDS.RK05 | PDP11.RK11.RKDS.SOK | PDP11.RK11.RKDS.RRDY;
|
||||
drive.status = RK11.RKDS.RK05 | RK11.RKDS.SOK | RK11.RKDS.RRDY;
|
||||
|
||||
return fSuccess;
|
||||
}
|
||||
|
|
@ -947,73 +947,73 @@ class RK11 extends Component {
|
|||
{
|
||||
var fInterrupt = true;
|
||||
var fnReadWrite, func, sFunc = "";
|
||||
var iDrive = (this.regRKDA & PDP11.RK11.RKDA.DS) >> PDP11.RK11.RKDA.SHIFT.DS;
|
||||
var iDrive = (this.regRKDA & RK11.RKDA.DS) >> RK11.RKDA.SHIFT.DS;
|
||||
var drive = this.aDrives[iDrive];
|
||||
var iCylinder, iHead, iSector, nWords, addr, inc;
|
||||
|
||||
this.regRKCS &= ~(PDP11.RK11.RKCS.CRDY | PDP11.RK11.RKCS.SCP);
|
||||
this.regRKER &= ~(PDP11.RK11.RKER.SE);
|
||||
this.regRKCS &= ~(RK11.RKCS.CRDY | RK11.RKCS.SCP);
|
||||
this.regRKER &= ~(RK11.RKER.SE);
|
||||
|
||||
switch(func = this.regRKCS & PDP11.RK11.RKCS.FUNC) {
|
||||
switch(func = this.regRKCS & RK11.RKCS.FUNC) {
|
||||
|
||||
case PDP11.RK11.FUNC.CRESET:
|
||||
case RK11.FUNC.CRESET:
|
||||
if (this.messageEnabled()) this.printMessage(this.type + ": CRESET(" + iDrive + ")", true);
|
||||
this.regRKER = this.regRKDA = 0;
|
||||
this.regRKCS = PDP11.RK11.RKCS.CRDY;
|
||||
this.regRKCS = RK11.RKCS.CRDY;
|
||||
break;
|
||||
|
||||
case PDP11.RK11.FUNC.RCHK:
|
||||
case RK11.FUNC.RCHK:
|
||||
sFunc = "RCHK";
|
||||
/* falls through */
|
||||
|
||||
case PDP11.RK11.FUNC.READ:
|
||||
case RK11.FUNC.READ:
|
||||
if (!sFunc) sFunc = "READ";
|
||||
fnReadWrite = this.readData;
|
||||
/* falls through */
|
||||
|
||||
case PDP11.RK11.FUNC.WCHK:
|
||||
case RK11.FUNC.WCHK:
|
||||
if (!sFunc) sFunc = "WCHK";
|
||||
/* falls through */
|
||||
|
||||
case PDP11.RK11.FUNC.WRITE:
|
||||
case RK11.FUNC.WRITE:
|
||||
if (!sFunc) sFunc = "WRITE";
|
||||
if (!fnReadWrite) fnReadWrite = this.writeData;
|
||||
|
||||
iCylinder = (this.regRKDA & PDP11.RK11.RKDA.CA) >> PDP11.RK11.RKDA.SHIFT.CA;
|
||||
iHead = (this.regRKDA & PDP11.RK11.RKDA.HS) >> PDP11.RK11.RKDA.SHIFT.HS;
|
||||
iSector = this.regRKDA & PDP11.RK11.RKDA.SA;
|
||||
iCylinder = (this.regRKDA & RK11.RKDA.CA) >> RK11.RKDA.SHIFT.CA;
|
||||
iHead = (this.regRKDA & RK11.RKDA.HS) >> RK11.RKDA.SHIFT.HS;
|
||||
iSector = this.regRKDA & RK11.RKDA.SA;
|
||||
nWords = (0x10000 - this.regRKWC) & 0xffff;
|
||||
addr = (((this.regRKCS & PDP11.RK11.RKCS.MEX)) << (16 - PDP11.RK11.RKCS.SHIFT.MEX)) | this.regRKBA;
|
||||
inc = (this.regRKCS & PDP11.RK11.RKCS.IBA)? 0 : 2;
|
||||
addr = (((this.regRKCS & RK11.RKCS.MEX)) << (16 - RK11.RKCS.SHIFT.MEX)) | this.regRKBA;
|
||||
inc = (this.regRKCS & RK11.RKCS.IBA)? 0 : 2;
|
||||
|
||||
if (this.messageEnabled()) this.printMessage(this.type + ": " + sFunc + "(" + iCylinder + ":" + iHead + ":" + iSector + ") " + Str.toOct(addr) + "--" + Str.toOct(addr + (nWords << 1)), true, true);
|
||||
|
||||
if (iCylinder >= drive.nCylinders) {
|
||||
this.regRKER |= PDP11.RK11.RKER.NXC;
|
||||
this.regRKER |= RK11.RKER.NXC;
|
||||
break;
|
||||
}
|
||||
if (iSector >= drive.nSectors) {
|
||||
this.regRKER |= PDP11.RK11.RKER.NXS;
|
||||
this.regRKER |= RK11.RKER.NXS;
|
||||
break;
|
||||
}
|
||||
|
||||
fInterrupt = fnReadWrite.call(this, drive, iCylinder, iHead, iSector, nWords, addr, inc, (func >= PDP11.RK11.FUNC.WCHK), this.doneReadWrite.bind(this));
|
||||
fInterrupt = fnReadWrite.call(this, drive, iCylinder, iHead, iSector, nWords, addr, inc, (func >= RK11.FUNC.WCHK), this.doneReadWrite.bind(this));
|
||||
break;
|
||||
|
||||
case PDP11.RK11.FUNC.SEEK:
|
||||
iCylinder = (this.regRKDA & PDP11.RK11.RKDA.CA) >> PDP11.RK11.RKDA.SHIFT.CA;
|
||||
case RK11.FUNC.SEEK:
|
||||
iCylinder = (this.regRKDA & RK11.RKDA.CA) >> RK11.RKDA.SHIFT.CA;
|
||||
if (this.messageEnabled()) this.printMessage(this.type + ": SEEK(" + iCylinder + ")", true);
|
||||
if (iCylinder < drive.nCylinders) {
|
||||
this.regRKCS |= PDP11.RK11.RKCS.SCP;
|
||||
this.regRKCS |= RK11.RKCS.SCP;
|
||||
} else {
|
||||
this.regRKER |= PDP11.RK11.RKER.NXC;
|
||||
this.regRKER |= RK11.RKER.NXC;
|
||||
}
|
||||
break;
|
||||
|
||||
case PDP11.RK11.FUNC.DRESET:
|
||||
case RK11.FUNC.DRESET:
|
||||
if (this.messageEnabled()) this.printMessage(this.type + ": DRESET(" + iDrive + ")");
|
||||
this.regRKER = this.regRKDA = 0;
|
||||
this.regRKCS = PDP11.RK11.RKCS.CRDY | PDP11.RK11.RKCS.SCP;
|
||||
this.regRKCS = RK11.RKCS.CRDY | RK11.RKCS.SCP;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -1021,14 +1021,14 @@ class RK11 extends Component {
|
|||
break;
|
||||
}
|
||||
|
||||
this.regRKDS = drive.status | (drive.disk? PDP11.RK11.RKDS.DRDY : 0) | (iDrive << PDP11.RK11.RKDS.SHIFT.ID) | (this.regRKDA & PDP11.RK11.RKDS.SC);
|
||||
this.regRKDS = drive.status | (drive.disk? RK11.RKDS.DRDY : 0) | (iDrive << RK11.RKDS.SHIFT.ID) | (this.regRKDA & RK11.RKDS.SC);
|
||||
|
||||
this.updateErrors();
|
||||
|
||||
if (fInterrupt) {
|
||||
this.regRKCS &= ~PDP11.RK11.RKCS.GO;
|
||||
this.regRKCS |= PDP11.RK11.RKCS.CRDY;
|
||||
if (this.regRKCS & PDP11.RK11.RKCS.IE) this.cpu.setIRQ(this.irq);
|
||||
this.regRKCS &= ~RK11.RKCS.GO;
|
||||
this.regRKCS |= RK11.RKCS.CRDY;
|
||||
if (this.regRKCS & RK11.RKCS.IE) this.cpu.setIRQ(this.irq);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1054,7 +1054,7 @@ class RK11 extends Component {
|
|||
var sector = null, ibSector;
|
||||
|
||||
if (!disk) {
|
||||
err = PDP11.RK11.RKER.NXD;
|
||||
err = RK11.RKER.NXD;
|
||||
nWords = 0;
|
||||
}
|
||||
|
||||
|
|
@ -1062,12 +1062,12 @@ class RK11 extends Component {
|
|||
while (nWords) {
|
||||
if (!sector) {
|
||||
if (iCylinder >= disk.nCylinders) {
|
||||
err = PDP11.RK11.RKER.NXC;
|
||||
err = RK11.RKER.NXC;
|
||||
break;
|
||||
}
|
||||
sector = disk.seek(iCylinder, iHead, iSector + 1);
|
||||
if (!sector) {
|
||||
err = PDP11.RK11.RKER.SKE;
|
||||
err = RK11.RKER.SKE;
|
||||
break;
|
||||
}
|
||||
ibSector = 0;
|
||||
|
|
@ -1081,7 +1081,7 @@ class RK11 extends Component {
|
|||
}
|
||||
var b0, b1;
|
||||
if ((b0 = disk.read(sector, ibSector++)) < 0 || (b1 = disk.read(sector, ibSector++)) < 0) {
|
||||
err = PDP11.RK11.RKER.NXS;
|
||||
err = RK11.RKER.NXS;
|
||||
break;
|
||||
}
|
||||
if (!fCheck) {
|
||||
|
|
@ -1096,7 +1096,7 @@ class RK11 extends Component {
|
|||
}
|
||||
}
|
||||
if (this.bus.checkFault()) {
|
||||
err = PDP11.RK11.RKER.NXM;
|
||||
err = RK11.RKER.NXM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1129,24 +1129,24 @@ class RK11 extends Component {
|
|||
var sector = null, ibSector;
|
||||
|
||||
if (!disk) {
|
||||
err = PDP11.RK11.RKER.NXD;
|
||||
err = RK11.RKER.NXD;
|
||||
nWords = 0;
|
||||
}
|
||||
|
||||
while (nWords) {
|
||||
var data = this.bus.getWordDirect(this.cpu.mapUnibus(addr));
|
||||
if (this.bus.checkFault()) {
|
||||
err = PDP11.RK11.RKER.NXM;
|
||||
err = RK11.RKER.NXM;
|
||||
break;
|
||||
}
|
||||
if (!sector) {
|
||||
if (iCylinder >= disk.nCylinders) {
|
||||
err = PDP11.RK11.RKER.NXC;
|
||||
err = RK11.RKER.NXC;
|
||||
break;
|
||||
}
|
||||
sector = disk.seek(iCylinder, iHead, iSector + 1, true);
|
||||
if (!sector) {
|
||||
err = PDP11.RK11.RKER.SKE;
|
||||
err = RK11.RKER.SKE;
|
||||
break;
|
||||
}
|
||||
ibSector = 0;
|
||||
|
|
@ -1161,7 +1161,7 @@ class RK11 extends Component {
|
|||
if (fCheck) {
|
||||
var b0, b1;
|
||||
if ((b0 = disk.read(sector, ibSector++)) < 0 || (b1 = disk.read(sector, ibSector++)) < 0) {
|
||||
err = PDP11.RK11.RKER.NXS;
|
||||
err = RK11.RKER.NXS;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
|
|
@ -1175,12 +1175,12 @@ class RK11 extends Component {
|
|||
* trigger the RKCS HE (Hard Error) bit. This is all taken care of in updateErrors() now.
|
||||
*/
|
||||
if (data != (b0 | (b1 << 8))) {
|
||||
err = PDP11.RK11.RKER.WCE;
|
||||
err = RK11.RKER.WCE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!disk.write(sector, ibSector++, data & 0xff) || !disk.write(sector, ibSector++, data >> 8)) {
|
||||
err = PDP11.RK11.RKER.NXS;
|
||||
err = RK11.RKER.NXS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1206,9 +1206,9 @@ class RK11 extends Component {
|
|||
doneReadWrite(err, iCylinder, iHead, iSector, nWords, addr)
|
||||
{
|
||||
this.regRKBA = addr & 0xffff;
|
||||
this.regRKCS = (this.regRKCS & ~PDP11.RK11.RKCS.MEX) | ((addr >> (16 - PDP11.RK11.RKCS.SHIFT.MEX)) & PDP11.RK11.RKCS.MEX);
|
||||
this.regRKCS = (this.regRKCS & ~RK11.RKCS.MEX) | ((addr >> (16 - RK11.RKCS.SHIFT.MEX)) & RK11.RKCS.MEX);
|
||||
this.regRKWC = (0x10000 - nWords) & 0xffff;
|
||||
this.regRKDA = (this.regRKDA & ~PDP11.RK11.RKDA.SA) | (iSector & PDP11.RK11.RKDA.SA);
|
||||
this.regRKDA = (this.regRKDA & ~RK11.RKDA.SA) | (iSector & RK11.RKDA.SA);
|
||||
this.regRKER |= err;
|
||||
this.updateErrors();
|
||||
return true;
|
||||
|
|
@ -1233,11 +1233,11 @@ class RK11 extends Component {
|
|||
* much like the high error bit found in other hardware registers: we always set it if any lower error bits
|
||||
* are also set.
|
||||
*/
|
||||
this.regRKCS &= ~PDP11.RK11.RKCS.ERR;
|
||||
this.regRKCS &= ~RK11.RKCS.ERR;
|
||||
if (this.regRKER) {
|
||||
this.regRKER |= PDP11.RK11.RKER.DRE;
|
||||
this.regRKCS |= PDP11.RK11.RKCS.ERR;
|
||||
if (this.regRKER & PDP11.RK11.RKER.HE) this.regRKCS |= PDP11.RK11.RKCS.HE;
|
||||
this.regRKER |= RK11.RKER.DRE;
|
||||
this.regRKCS |= RK11.RKCS.ERR;
|
||||
if (this.regRKER & RK11.RKER.HE) this.regRKCS |= RK11.RKCS.HE;
|
||||
if (this.messageEnabled()) this.printMessage(this.type + ": ERROR: " + Str.toOct(this.regRKER));
|
||||
}
|
||||
}
|
||||
|
|
@ -1303,7 +1303,7 @@ class RK11 extends Component {
|
|||
*/
|
||||
readRKCS(addr)
|
||||
{
|
||||
return this.regRKCS & PDP11.RK11.RKCS.RMASK;
|
||||
return this.regRKCS & RK11.RKCS.RMASK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1315,9 +1315,9 @@ class RK11 extends Component {
|
|||
*/
|
||||
writeRKCS(data, addr)
|
||||
{
|
||||
this.regRKCS = (this.regRKCS & ~PDP11.RK11.RKCS.WMASK) | (data & PDP11.RK11.RKCS.WMASK);
|
||||
this.regRKCS = (this.regRKCS & ~RK11.RKCS.WMASK) | (data & RK11.RKCS.WMASK);
|
||||
|
||||
if (this.regRKCS & PDP11.RK11.RKCS.GO) this.processCommand();
|
||||
if (this.regRKCS & RK11.RKCS.GO) this.processCommand();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1426,6 +1426,17 @@ RK11.SOURCE = {
|
|||
REMOTE: "??"
|
||||
};
|
||||
|
||||
/*
|
||||
* Alias RK11 definitions as class constants
|
||||
*/
|
||||
RK11.PRI = PDP11.RK11.PRI;
|
||||
RK11.VEC = PDP11.RK11.VEC;
|
||||
RK11.RKDS = PDP11.RK11.RKDS; // 177400: Drive Status Register
|
||||
RK11.RKER = PDP11.RK11.RKER; // 177402: Error Register
|
||||
RK11.RKCS = PDP11.RK11.RKCS; // 177404: Control Status Register
|
||||
RK11.RKDA = PDP11.RK11.RKDA; // 177412: Disk Address Register
|
||||
RK11.FUNC = PDP11.RK11.FUNC;
|
||||
|
||||
/*
|
||||
* ES6 ALERT: As you can see below, I've finally started using computed property names.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -63,8 +63,8 @@ class RL11 extends Component {
|
|||
super("RL11", parms, RL11, MessagesPDP11.RL11);
|
||||
|
||||
/*
|
||||
* We record any 'autoMount' object now, but we no longer parse it until initBus(),
|
||||
* because the Computer's getMachineParm() service may have an override for us.
|
||||
* We preliminarily parse and record any 'autoMount' object now, but we no longer process it
|
||||
* until initBus(), because the Computer's getMachineParm() service may have an override for us.
|
||||
*/
|
||||
this.configMount = this.parseConfig(parms['autoMount']);
|
||||
this.cAutoMount = 0;
|
||||
|
|
@ -311,7 +311,7 @@ class RL11 extends Component {
|
|||
*/
|
||||
this.initController();
|
||||
|
||||
this.irq = this.cpu.addIRQ(PDP11.RL11.VEC, PDP11.RL11.PRI, MessagesPDP11.RL11);
|
||||
this.irq = this.cpu.addIRQ(RL11.VEC, RL11.PRI, MessagesPDP11.RL11);
|
||||
|
||||
bus.addIOTable(this, RL11.UNIBUS_IOTABLE);
|
||||
bus.addResetHandler(this.reset.bind(this));
|
||||
|
|
@ -863,7 +863,7 @@ class RL11 extends Component {
|
|||
{
|
||||
var i = 0;
|
||||
if (!data) data = [];
|
||||
this.regRLCS = data[i++] || (PDP11.RL11.RLCS.DRDY | PDP11.RL11.RLCS.CRDY);
|
||||
this.regRLCS = data[i++] || (RL11.RLCS.DRDY | RL11.RLCS.CRDY);
|
||||
this.regRLBA = data[i++] || 0;
|
||||
this.regRLDA = data[i++] || 0;
|
||||
this.tmpRLDA = data[i++] || 0;
|
||||
|
|
@ -935,7 +935,7 @@ class RL11 extends Component {
|
|||
/*
|
||||
* 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.status = RL11.RLMP.GS_ST.LOCKON | RL11.RLMP.GS_BH | RL11.RLMP.GS_HO;
|
||||
|
||||
return fSuccess;
|
||||
}
|
||||
|
|
@ -949,7 +949,7 @@ class RL11 extends Component {
|
|||
{
|
||||
var fInterrupt = true;
|
||||
var fnReadWrite, sFunc = "";
|
||||
var iDrive = (this.regRLCS & PDP11.RL11.RLCS.DS) >> PDP11.RL11.RLCS.SHIFT.DS;
|
||||
var iDrive = (this.regRLCS & RL11.RLCS.DS) >> RL11.RLCS.SHIFT.DS;
|
||||
var drive = this.aDrives[iDrive];
|
||||
var disk = drive.disk;
|
||||
var iCylinder, iHead, iSector, nWords, addr;
|
||||
|
|
@ -961,62 +961,62 @@ class RL11 extends Component {
|
|||
* 2) CRDY is cleared to process a command
|
||||
* 3) DRDY is cleared to indicate a command in process
|
||||
*/
|
||||
this.regRLCS &= ~PDP11.RL11.RLCS.DRDY;
|
||||
this.regRLCS &= ~RL11.RLCS.DRDY;
|
||||
|
||||
switch(this.regRLCS & PDP11.RL11.RLCS.FUNC) {
|
||||
switch(this.regRLCS & RL11.RLCS.FUNC) {
|
||||
|
||||
case PDP11.RL11.FUNC.NOP:
|
||||
case PDP11.RL11.FUNC.WCHK:
|
||||
case PDP11.RL11.FUNC.RDNC:
|
||||
case RL11.FUNC.NOP:
|
||||
case RL11.FUNC.WCHK:
|
||||
case RL11.FUNC.RDNC:
|
||||
break;
|
||||
|
||||
case PDP11.RL11.FUNC.STATUS:
|
||||
if (this.regRLMP & PDP11.RL11.RLMP.GS_BH) {
|
||||
this.regRLCS &= (PDP11.RL11.RLCS.DRDY | PDP11.RL11.RLCS.FUNC | PDP11.RL11.RLCS.BAE); // TODO: Review
|
||||
case RL11.FUNC.STATUS:
|
||||
if (this.regRLMP & RL11.RLMP.GS_BH) {
|
||||
this.regRLCS &= (RL11.RLCS.DRDY | RL11.RLCS.FUNC | RL11.RLCS.BAE); // TODO: Review
|
||||
}
|
||||
/*
|
||||
* The bit indicating whether or not the disk contains 256 or 512 cylinders is critical;
|
||||
* for example, the first RSTS/E disk image we tried was an RL01K, which has only 256 cylinders,
|
||||
* and the operating system would crash mysteriously if we didn't report the correct geometry.
|
||||
*/
|
||||
this.regRLMP = drive.status | (this.tmpRLDA & PDP11.RL11.RLDA.RW_HS) | (disk && disk.nCylinders == 512? PDP11.RL11.RLMP.GS_DT : 0);
|
||||
this.regRLMP = drive.status | (this.tmpRLDA & RL11.RLDA.RW_HS) | (disk && disk.nCylinders == 512? RL11.RLMP.GS_DT : 0);
|
||||
break;
|
||||
|
||||
case PDP11.RL11.FUNC.SEEK:
|
||||
if ((this.regRLDA & PDP11.RL11.RLDA.GS_CMD) == PDP11.RL11.RLDA.SEEK_CMD) {
|
||||
var darCA = (this.regRLDA & PDP11.RL11.RLDA.RW_CA);
|
||||
var darHS = (this.regRLDA & PDP11.RL11.RLDA.SEEK_HS) << 2;
|
||||
if (this.regRLDA & PDP11.RL11.RLDA.SEEK_DIR) {
|
||||
case RL11.FUNC.SEEK:
|
||||
if ((this.regRLDA & RL11.RLDA.GS_CMD) == RL11.RLDA.SEEK_CMD) {
|
||||
var darCA = (this.regRLDA & RL11.RLDA.RW_CA);
|
||||
var darHS = (this.regRLDA & RL11.RLDA.SEEK_HS) << 2;
|
||||
if (this.regRLDA & RL11.RLDA.SEEK_DIR) {
|
||||
this.tmpRLDA += darCA;
|
||||
} else {
|
||||
this.tmpRLDA -= darCA;
|
||||
}
|
||||
this.regRLDA = this.tmpRLDA = (this.tmpRLDA & PDP11.RL11.RLDA.RW_CA) | darHS;
|
||||
this.regRLDA = this.tmpRLDA = (this.tmpRLDA & RL11.RLDA.RW_CA) | darHS;
|
||||
}
|
||||
break;
|
||||
|
||||
case PDP11.RL11.FUNC.RHDR:
|
||||
case RL11.FUNC.RHDR:
|
||||
this.regRLMP = this.tmpRLDA;
|
||||
break;
|
||||
|
||||
case PDP11.RL11.FUNC.RDATA:
|
||||
case RL11.FUNC.RDATA:
|
||||
sFunc = "READ";
|
||||
fnReadWrite = this.readData;
|
||||
/* falls through */
|
||||
|
||||
case PDP11.RL11.FUNC.WDATA:
|
||||
case RL11.FUNC.WDATA:
|
||||
if (!sFunc) sFunc = "WRITE";
|
||||
if (!fnReadWrite) fnReadWrite = this.writeData;
|
||||
|
||||
iCylinder = this.regRLDA >> PDP11.RL11.RLDA.SHIFT.RW_CA;
|
||||
iHead = (this.regRLDA & PDP11.RL11.RLDA.RW_HS)? 1 : 0;
|
||||
iSector = this.regRLDA & PDP11.RL11.RLDA.RW_SA;
|
||||
iCylinder = this.regRLDA >> RL11.RLDA.SHIFT.RW_CA;
|
||||
iHead = (this.regRLDA & RL11.RLDA.RW_HS)? 1 : 0;
|
||||
iSector = this.regRLDA & RL11.RLDA.RW_SA;
|
||||
if (!disk || iCylinder >= disk.nCylinders || iSector >= disk.nSectors) {
|
||||
this.regRLCS |= PDP11.RL11.ERRC.HNF | PDP11.RL11.RLCS.ERR;
|
||||
this.regRLCS |= RL11.ERRC.HNF | RL11.RLCS.ERR;
|
||||
break;
|
||||
}
|
||||
nWords = (0x10000 - this.regRLMP) & 0xffff;
|
||||
addr = (((this.regRLBE & PDP11.RL11.RLBE.MASK)) << 16) | this.regRLBA; // 22 bit mode
|
||||
addr = (((this.regRLBE & RL11.RLBE.MASK)) << 16) | this.regRLBA; // 22 bit mode
|
||||
|
||||
if (this.messageEnabled()) this.printMessage(this.type + ": " + sFunc + "(" + iCylinder + ":" + iHead + ":" + iSector + ") " + Str.toOct(addr) + "--" + Str.toOct(addr + (nWords << 1)), true, true);
|
||||
|
||||
|
|
@ -1028,8 +1028,8 @@ class RL11 extends Component {
|
|||
}
|
||||
|
||||
if (fInterrupt) {
|
||||
this.regRLCS |= PDP11.RL11.RLCS.DRDY | PDP11.RL11.RLCS.CRDY;
|
||||
if (this.regRLCS & PDP11.RL11.RLCS.IE) this.cpu.setIRQ(this.irq);
|
||||
this.regRLCS |= RL11.RLCS.DRDY | RL11.RLCS.CRDY;
|
||||
if (this.regRLCS & RL11.RLCS.IE) this.cpu.setIRQ(this.irq);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1054,7 +1054,7 @@ class RL11 extends Component {
|
|||
var sector = null, ibSector;
|
||||
|
||||
if (!disk) {
|
||||
err = PDP11.RL11.ERRC.HNF; // TODO: Review
|
||||
err = RL11.ERRC.HNF; // TODO: Review
|
||||
nWords = 0;
|
||||
}
|
||||
|
||||
|
|
@ -1063,14 +1063,14 @@ class RL11 extends Component {
|
|||
if (!sector) {
|
||||
sector = disk.seek(iCylinder, iHead, iSector + 1);
|
||||
if (!sector) {
|
||||
err = PDP11.RL11.ERRC.HNF;
|
||||
err = RL11.ERRC.HNF;
|
||||
break;
|
||||
}
|
||||
ibSector = 0;
|
||||
}
|
||||
var b0, b1, data;
|
||||
if ((b0 = disk.read(sector, ibSector++)) < 0 || (b1 = disk.read(sector, ibSector++)) < 0) {
|
||||
err = PDP11.RL11.ERRC.HNF;
|
||||
err = RL11.ERRC.HNF;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
|
|
@ -1088,7 +1088,7 @@ class RL11 extends Component {
|
|||
}
|
||||
}
|
||||
if (this.bus.checkFault()) {
|
||||
err = PDP11.RL11.ERRC.NXM;
|
||||
err = RL11.ERRC.NXM;
|
||||
break;
|
||||
}
|
||||
addr += 2;
|
||||
|
|
@ -1101,7 +1101,7 @@ class RL11 extends Component {
|
|||
if (++iHead >= disk.nHeads) {
|
||||
iHead = 0;
|
||||
if (++iCylinder >= disk.nCylinders) {
|
||||
err = PDP11.RL11.ERRC.HNF;
|
||||
err = RL11.ERRC.HNF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1137,7 +1137,7 @@ class RL11 extends Component {
|
|||
var sector = null, ibSector;
|
||||
|
||||
if (!disk) {
|
||||
err = PDP11.RL11.ERRC.HNF; // TODO: Review
|
||||
err = RL11.ERRC.HNF; // TODO: Review
|
||||
nWords = 0;
|
||||
}
|
||||
|
||||
|
|
@ -1150,7 +1150,7 @@ class RL11 extends Component {
|
|||
*/
|
||||
var data = this.bus.getWordDirect(this.cpu.mapUnibus(addr));
|
||||
if (this.bus.checkFault()) {
|
||||
err = PDP11.RL11.ERRC.NXM;
|
||||
err = RL11.ERRC.NXM;
|
||||
break;
|
||||
}
|
||||
if (DEBUG && this.messageEnabled(MessagesPDP11.WRITE)) {
|
||||
|
|
@ -1167,13 +1167,13 @@ class RL11 extends Component {
|
|||
if (!sector) {
|
||||
sector = disk.seek(iCylinder, iHead, iSector + 1, true);
|
||||
if (!sector) {
|
||||
err = PDP11.RL11.ERRC.HNF;
|
||||
err = RL11.ERRC.HNF;
|
||||
break;
|
||||
}
|
||||
ibSector = 0;
|
||||
}
|
||||
if (!disk.write(sector, ibSector++, data & 0xff) || !disk.write(sector, ibSector++, data >> 8)) {
|
||||
err = PDP11.RL11.ERRC.HNF;
|
||||
err = RL11.ERRC.HNF;
|
||||
break;
|
||||
}
|
||||
if (ibSector >= disk.cbSector) {
|
||||
|
|
@ -1183,7 +1183,7 @@ class RL11 extends Component {
|
|||
if (++iHead >= disk.nHeads) {
|
||||
iHead = 0;
|
||||
if (++iCylinder >= disk.nCylinders) {
|
||||
err = PDP11.RL11.ERRC.HNF;
|
||||
err = RL11.ERRC.HNF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1213,13 +1213,13 @@ class RL11 extends Component {
|
|||
doneReadWrite(err, iCylinder, iHead, iSector, nWords, addr)
|
||||
{
|
||||
this.regRLBA = addr & 0xffff;
|
||||
this.regRLCS = (this.regRLCS & ~PDP11.RL11.RLCS.BAE) | ((addr >> (16 - PDP11.RL11.RLCS.SHIFT.BAE)) & PDP11.RL11.RLCS.BAE);
|
||||
this.regRLBE = (addr >> 16) & PDP11.RL11.RLBE.MASK; // 22 bit mode
|
||||
this.regRLDA = (iCylinder << PDP11.RL11.RLDA.SHIFT.RW_CA) | (iHead? PDP11.RL11.RLDA.RW_HS : 0) | (iSector & PDP11.RL11.RLDA.RW_SA);
|
||||
this.regRLCS = (this.regRLCS & ~RL11.RLCS.BAE) | ((addr >> (16 - RL11.RLCS.SHIFT.BAE)) & RL11.RLCS.BAE);
|
||||
this.regRLBE = (addr >> 16) & RL11.RLBE.MASK; // 22 bit mode
|
||||
this.regRLDA = (iCylinder << RL11.RLDA.SHIFT.RW_CA) | (iHead? RL11.RLDA.RW_HS : 0) | (iSector & RL11.RLDA.RW_SA);
|
||||
this.tmpRLDA = this.regRLDA;
|
||||
this.regRLMP = (0x10000 - nWords) & 0xffff;
|
||||
if (err) {
|
||||
this.regRLCS |= err | PDP11.RL11.RLCS.ERR;
|
||||
this.regRLCS |= err | RL11.RLCS.ERR;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1233,7 +1233,7 @@ class RL11 extends Component {
|
|||
*/
|
||||
readRLCS(addr)
|
||||
{
|
||||
return this.regRLCS & PDP11.RL11.RLCS.RMASK;
|
||||
return this.regRLCS & RL11.RLCS.RMASK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1245,9 +1245,9 @@ class RL11 extends Component {
|
|||
*/
|
||||
writeRLCS(data, addr)
|
||||
{
|
||||
this.regRLCS = (this.regRLCS & ~PDP11.RL11.RLCS.WMASK) | (data & PDP11.RL11.RLCS.WMASK);
|
||||
this.regRLBE = (this.regRLBE & 0x3C) | ((data & PDP11.RL11.RLCS.BAE) >> PDP11.RL11.RLCS.SHIFT.BAE);
|
||||
if (!(this.regRLCS & PDP11.RL11.RLCS.CRDY)) this.processCommand();
|
||||
this.regRLCS = (this.regRLCS & ~RL11.RLCS.WMASK) | (data & RL11.RLCS.WMASK);
|
||||
this.regRLBE = (this.regRLBE & 0x3C) | ((data & RL11.RLCS.BAE) >> RL11.RLCS.SHIFT.BAE);
|
||||
if (!(this.regRLCS & RL11.RLCS.CRDY)) this.processCommand();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1271,7 +1271,7 @@ class RL11 extends Component {
|
|||
*/
|
||||
writeRLBA(data, addr)
|
||||
{
|
||||
this.regRLBA = data & PDP11.RL11.RLBA.WMASK;
|
||||
this.regRLBA = data & RL11.RLBA.WMASK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1349,8 +1349,8 @@ class RL11 extends Component {
|
|||
*/
|
||||
writeRLBE(data, addr)
|
||||
{
|
||||
this.regRLBE = data & PDP11.RL11.RLBE.MASK;
|
||||
this.regRLCS = (this.regRLCS & ~PDP11.RL11.RLCS.BAE) | ((this.regRLBE & 0x3) << PDP11.RL11.RLCS.SHIFT.BAE);
|
||||
this.regRLBE = data & RL11.RLBE.MASK;
|
||||
this.regRLCS = (this.regRLCS & ~RL11.RLCS.BAE) | ((this.regRLBE & 0x3) << RL11.RLCS.SHIFT.BAE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1363,6 +1363,19 @@ RL11.SOURCE = {
|
|||
REMOTE: "??"
|
||||
};
|
||||
|
||||
/*
|
||||
* Alias RL11 definitions as class constants
|
||||
*/
|
||||
RL11.PRI = PDP11.RL11.PRI;
|
||||
RL11.VEC = PDP11.RL11.VEC;
|
||||
RL11.RLCS = PDP11.RL11.RLCS; // 174400: Control Status Register
|
||||
RL11.RLBA = PDP11.RL11.RLBA; // 174402: Bus Address Register
|
||||
RL11.RLDA = PDP11.RL11.RLDA; // 174404: Disk Address Register
|
||||
RL11.RLMP = PDP11.RL11.RLMP; // 177406: Multi-Purpose Register
|
||||
RL11.RLBE = PDP11.RL11.RLBE; // 174410: Bus (Address) Extension Register
|
||||
RL11.ERRC = PDP11.RL11.ERRC; // NOTE: These error codes are pre-shifted to read/write directly from/to RLCS.ERRC
|
||||
RL11.FUNC = PDP11.RL11.FUNC; // NOTE: These function codes are pre-shifted to read/write directly from/to RLCS.FUNC
|
||||
|
||||
/*
|
||||
* ES6 ALERT: As you can see below, I've finally started using computed property names.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ if (NODE) {
|
|||
var http = require("http");
|
||||
var path = require("path");
|
||||
var url = require("url");
|
||||
var Str = require("../../shared/es6/strlib");
|
||||
}
|
||||
|
||||
class Net {
|
||||
|
|
|
|||
|
|
@ -28,9 +28,11 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var Str = require("../../shared/es6/strlib");
|
||||
var Web = require("../../shared/es6/weblib");
|
||||
var Component = require("../../shared/es6/component");
|
||||
if (NODE) {
|
||||
var Str = require("../../shared/es6/strlib");
|
||||
var Web = require("../../shared/es6/weblib");
|
||||
var Component = require("../../shared/es6/component");
|
||||
}
|
||||
|
||||
/**
|
||||
* savePC(idMachine, sPCJSFile, callback)
|
||||
|
|
|
|||
|
|
@ -28,8 +28,10 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var Web = require("../../shared/es6/weblib");
|
||||
var Component = require("../../shared/es6/component");
|
||||
if (NODE) {
|
||||
var Web = require("../../shared/es6/weblib");
|
||||
var Component = require("../../shared/es6/component");
|
||||
}
|
||||
|
||||
class State {
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -341,7 +341,19 @@ net.getResource = function(sURL, dataPost, fAsync, done)
|
|||
var nErrorCode = -1, sResource = null, response = null;
|
||||
|
||||
if (net.isRemote(sURL)) {
|
||||
console.log('net.getResource("' + sURL + '"): unimplemented');
|
||||
/*
|
||||
* TODO: This code is nothing more than a band-aid. It assumes the URL uses "http:"
|
||||
* (hence the call to getFile(), which only supports HTTP GET operations), it assumes
|
||||
* the requested data is UTF-8 string data (which is normally the case, because nearly
|
||||
* all our requests are for JSON files), it doesn't deal with dataPost, it assumes
|
||||
* that fAsync is true, and it performs very simplistic error code mapping.
|
||||
*
|
||||
* But, it gets the job done for what little we actually ask of it, when our machines
|
||||
* are running in the Node environment.
|
||||
*/
|
||||
Net.getFile(sURL, "utf8", function(err, status, data) {
|
||||
if (done) done(sURL, data, err? status : 0);
|
||||
});
|
||||
} else {
|
||||
if (!sServerRoot) {
|
||||
sServerRoot = path.join(path.dirname(fs.realpathSync(__filename)), "../../../");
|
||||
|
|
|
|||
Loading…
Reference in a new issue