Made some progress with DEC's "TRAP TEST", but looks like it still needs some work
This commit is contained in:
parent
eb6bf8a5a5
commit
db63c30c1e
24 changed files with 1252 additions and 555 deletions
|
|
@ -1398,7 +1398,7 @@ BusPDP11.prototype.fault = function(addr, err, access)
|
|||
this.dbg.printMessage("memory fault (" + access + ") on address " + this.dbg.toStrBase(addr), true, true);
|
||||
}
|
||||
if (err) this.cpu.regErr |= err;
|
||||
this.cpu.trap(PDP11.TRAP.BUS_ERROR, addr);
|
||||
this.cpu.trap(PDP11.TRAP.BUS_ERROR, 0, addr);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -827,7 +827,7 @@ PDP11.opBPL = function(opCode)
|
|||
*/
|
||||
PDP11.opBPT = function(opCode)
|
||||
{
|
||||
this.trap(PDP11.TRAP.BPT, PDP11.REASON.BPT);
|
||||
this.trap(PDP11.TRAP.BPT, 0, PDP11.REASON.BPT);
|
||||
this.nStepCycles -= (4 + 1);
|
||||
};
|
||||
|
||||
|
|
@ -1101,7 +1101,7 @@ PDP11.opDIV = function(opCode)
|
|||
*/
|
||||
PDP11.opEMT = function(opCode)
|
||||
{
|
||||
this.trap(PDP11.TRAP.EMT, PDP11.REASON.EMT);
|
||||
this.trap(PDP11.TRAP.EMT, 0, PDP11.REASON.EMT);
|
||||
this.nStepCycles -= (22 + 3);
|
||||
};
|
||||
|
||||
|
|
@ -1115,8 +1115,11 @@ PDP11.opHALT = function(opCode)
|
|||
{
|
||||
if (this.regPSW & PDP11.PSW.CMODE) {
|
||||
this.regErr |= PDP11.CPUERR.BADHALT;
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.HALT);
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, 0, PDP11.REASON.HALT);
|
||||
} else {
|
||||
if (this.panel) {
|
||||
this.panel.setData(this.regsGen[0], true);
|
||||
}
|
||||
if (!this.dbg) {
|
||||
/*
|
||||
* This will leave the PC exactly where it's supposed to be: at the address of the HALT + 2.
|
||||
|
|
@ -1171,7 +1174,7 @@ PDP11.opINCB = function(opCode)
|
|||
*/
|
||||
PDP11.opIOT = function(opCode)
|
||||
{
|
||||
this.trap(PDP11.TRAP.IOT, PDP11.REASON.IOT);
|
||||
this.trap(PDP11.TRAP.IOT, 0, PDP11.REASON.IOT);
|
||||
this.nStepCycles -= (22 + 3);
|
||||
};
|
||||
|
||||
|
|
@ -1291,7 +1294,7 @@ PDP11.opMFPT = function(opCode)
|
|||
/*
|
||||
* TODO: Review
|
||||
*/
|
||||
this.trap(PDP11.TRAP.RESERVED, PDP11.REASON.RESERVED);
|
||||
this.trap(PDP11.TRAP.RESERVED, 0, PDP11.REASON.RESERVED);
|
||||
};
|
||||
|
||||
PDP11.MOV_CYCLES = [
|
||||
|
|
@ -1713,7 +1716,7 @@ PDP11.opSXT = function(opCode)
|
|||
*/
|
||||
PDP11.opTRAP = function(opCode)
|
||||
{
|
||||
this.trap(PDP11.TRAP.TRAP, PDP11.REASON.TRAP);
|
||||
this.trap(PDP11.TRAP.TRAP, 0, PDP11.REASON.TRAP);
|
||||
this.nStepCycles -= (4 + 1);
|
||||
};
|
||||
|
||||
|
|
@ -1823,7 +1826,7 @@ PDP11.opUndefined = function(opCode)
|
|||
if (DEBUGGER && this.dbg) {
|
||||
if (this.dbg.undefinedInstruction(opCode)) return;
|
||||
}
|
||||
this.trap(PDP11.TRAP.RESERVED, PDP11.REASON.RESERVED);
|
||||
this.trap(PDP11.TRAP.RESERVED, 0, PDP11.REASON.RESERVED);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -825,7 +825,7 @@ CPUStatePDP11.prototype.dispatchInterrupt = function(vector, priority)
|
|||
this.advancePC(2);
|
||||
this.opFlags &= ~PDP11.OPFLAG.WAIT;
|
||||
}
|
||||
this.trap(vector, PDP11.REASON.INTERRUPT);
|
||||
this.trap(vector, 0, PDP11.REASON.INTERRUPT);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -1083,6 +1083,13 @@ CPUStatePDP11.prototype.updateMulFlags = function(result)
|
|||
/*
|
||||
* NOTE: Technically, the MUL instruction doesn't need to worry about NO_FLAGS, because that instruction
|
||||
* doesn't write to the bus, and therefore can't modify the PSW directly. But it doesn't hurt to be consistent.
|
||||
*
|
||||
* TODO: Conduct a review of all opcode handlers, because one possible alternative to all this NO_FLAGS nonsense
|
||||
* would be to pass the appropriate flag update function to the writeDstByte()/writeDstWord() functions, and
|
||||
* have them update the flags BEFORE the write occurs, thus allowing any subsequent write to the PSW to be honored.
|
||||
*
|
||||
* That already happens automatically with the updateDstByte()/updateDstWord() functions, since generally the
|
||||
* specified modify function also updates the flags BEFORE the write occurs.
|
||||
*/
|
||||
if (!(this.opFlags & PDP11.OPFLAG.NO_FLAGS)) {
|
||||
this.flagN = result >> 16;
|
||||
|
|
@ -1139,7 +1146,7 @@ CPUStatePDP11.prototype.panic = function(reason)
|
|||
};
|
||||
|
||||
/**
|
||||
* trap(vector, reason)
|
||||
* trap(vector, flag, reason)
|
||||
*
|
||||
* trap() handles all the trap/abort functions. It reads the trap vector from kernel
|
||||
* D space, changes mode to reflect the new PSW and PC, and then pushes the old PSW and
|
||||
|
|
@ -1147,9 +1154,10 @@ CPUStatePDP11.prototype.panic = function(reason)
|
|||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} vector
|
||||
* @param {number} flag
|
||||
* @param {number} [reason] (for diagnostic purposes only)
|
||||
*/
|
||||
CPUStatePDP11.prototype.trap = function(vector, reason)
|
||||
CPUStatePDP11.prototype.trap = function(vector, flag, reason)
|
||||
{
|
||||
if (DEBUG && this.dbg) {
|
||||
if (this.messageEnabled(MessagesPDP11.TRAP)) {
|
||||
|
|
@ -1194,8 +1202,15 @@ CPUStatePDP11.prototype.trap = function(vector, reason)
|
|||
this.pushWord(this.regsGen[7]);
|
||||
this.setPC(newPC);
|
||||
|
||||
this.opFlags &= ~PDP11.OPFLAG.TRAP_MASK; // lose interest in traps after an abort
|
||||
this.trapPSW = -1; // reset flag that we have a trap within a trap
|
||||
/*
|
||||
* Since DEC's "TRAP TEST" triggers a RESERVED (instruction) trap with the stack deliberately
|
||||
* set too low, and expects the stack overflow trap to be "sprung" immediately afterward, we only
|
||||
* want to "lose interest" in TRAP flags that were set on entry.
|
||||
*
|
||||
* this.opFlags &= ~PDP11.OPFLAG.TRAP_MASK; // lose interest in traps after an abort
|
||||
*/
|
||||
this.opFlags &= ~flag;
|
||||
this.trapPSW = -1; // reset flag that we have a trap within a trap
|
||||
|
||||
/*
|
||||
* These next properties are purely an aid for the Debugger; see getTrapStatus()
|
||||
|
|
@ -1435,7 +1450,7 @@ CPUStatePDP11.prototype.mapVirtualToPhysical = function(virtualAddress, accessFl
|
|||
}
|
||||
}
|
||||
if (fTrap) { // don't trap until the end, because it throws an exception
|
||||
this.trap(PDP11.TRAP.MMU, PDP11.REASON.MAPERROR);
|
||||
this.trap(PDP11.TRAP.MMU, 0, PDP11.REASON.MAPERROR);
|
||||
}
|
||||
}
|
||||
return physicalAddress;
|
||||
|
|
@ -1494,18 +1509,35 @@ CPUStatePDP11.prototype.pushWord = function(data)
|
|||
if (!(this.regMMR0 & 0xe000)) {
|
||||
this.regMMR1 = (this.regMMR1 << 8) | 0xf6;
|
||||
}
|
||||
this.checkStackLimit(0, virtualAddress);
|
||||
this.writeWord(virtualAddress, data);
|
||||
};
|
||||
|
||||
if ((!this.mmuMode) && virtualAddress <= this.regSL && virtualAddress > 4) {
|
||||
if (virtualAddress <= this.regSL - 32) {
|
||||
this.regErr |= PDP11.CPUERR.RED;
|
||||
this.regsGen[6] = 4;
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.PUSHERROR);
|
||||
} else {
|
||||
this.regErr |= PDP11.CPUERR.YELLOW;
|
||||
this.opFlags |= 4;
|
||||
/**
|
||||
* checkStackLimit(mode, addr)
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} mode (ie, the addressing mode; 0 if push)
|
||||
* @param {number} addr
|
||||
*/
|
||||
CPUStatePDP11.prototype.checkStackLimit = function(mode, addr)
|
||||
{
|
||||
if (!this.mmuMode && !(this.opFlags & PDP11.OPFLAG.TRAP_SP)) {
|
||||
if (addr <= this.regSL && (mode || addr > 4) || mode && addr >= 0xfffe) {
|
||||
if (this.model >= PDP11.MODEL_1145 && (addr <= this.regSL - 32 || mode == 1 && addr >= 0xfffe)) {
|
||||
this.regErr |= PDP11.CPUERR.RED;
|
||||
this.regsGen[6] = 4;
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, 0, PDP11.REASON.STACKMODE1);
|
||||
} else {
|
||||
/*
|
||||
* On older machines (eg, the PDP-11/20), the instruction is always allowed to complete,
|
||||
* so the trap must always be issued in this fashion.
|
||||
*/
|
||||
this.regErr |= PDP11.CPUERR.YELLOW;
|
||||
this.opFlags |= PDP11.OPFLAG.TRAP_SP;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.writeWord(virtualAddress, data);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1532,6 +1564,15 @@ CPUStatePDP11.prototype.pushWord = function(data)
|
|||
* incremented and decremented so that the OS can reset and restart an instruction
|
||||
* if a page fault occurs.
|
||||
*
|
||||
* Stack Overflow Traps
|
||||
* --------------------
|
||||
* On the PDP-11/20, stack overflow traps occur when an address below 400 is referenced
|
||||
* by SP in either mode 4 (auto-decrement) or 5 (auto-decrement deferred). The instruction
|
||||
* is allowed to complete before the trap is issued.
|
||||
*
|
||||
* On the PDP-11/70, the stack limit register (177774) allows a variable boundary for the
|
||||
* kernel stack.
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} mode
|
||||
* @param {number} reg
|
||||
|
|
@ -1544,8 +1585,8 @@ CPUStatePDP11.prototype.getAddrByMode = function(mode, reg, accessFlags)
|
|||
var addrDSpace = (accessFlags & PDP11.ACCESS.VIRT)? 0 : this.addrDSpace;
|
||||
|
||||
/*
|
||||
* Modes that need to auto-increment or auto-decrement will break, in order to perform the
|
||||
* update; others will return an address immediately.
|
||||
* Modes that need to auto-increment or auto-decrement will break, in order to perform
|
||||
* the update; others will return an address immediately.
|
||||
*/
|
||||
switch (mode) {
|
||||
/*
|
||||
|
|
@ -1556,26 +1597,18 @@ CPUStatePDP11.prototype.getAddrByMode = function(mode, reg, accessFlags)
|
|||
* "cause an 'illegal' instruction" condition", which presumably means a BUS_ERROR trap.
|
||||
*/
|
||||
case 0:
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.NOREGADDR);
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, 0, PDP11.REASON.NOREGADDR);
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Mode 1: (R)
|
||||
*/
|
||||
case 1:
|
||||
if (reg === 6 && (!this.mmuMode) && (accessFlags & PDP11.ACCESS.WRITE) &&
|
||||
(this.regsGen[6] <= this.regSL || this.regsGen[6] >= 0xfffe)) {
|
||||
if (this.regsGen[6] <= this.regSL - 32 || this.regsGen[6] >= 0xfffe) {
|
||||
this.regErr |= PDP11.CPUERR.RED;
|
||||
this.regsGen[6] = 4;
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.STACKMODE1);
|
||||
} else {
|
||||
this.regErr |= PDP11.CPUERR.YELLOW;
|
||||
this.opFlags |= PDP11.OPFLAG.TRAP_SP;
|
||||
}
|
||||
if (reg == 6 && (accessFlags & PDP11.ACCESS.WRITE)) {
|
||||
this.checkStackLimit(mode, this.regsGen[6]);
|
||||
}
|
||||
this.nStepCycles -= (2 + 1);
|
||||
return (reg === 7? this.regsGen[reg] : (this.regsGen[reg] | addrDSpace));
|
||||
return (reg == 7? this.regsGen[reg] : (this.regsGen[reg] | addrDSpace));
|
||||
|
||||
/*
|
||||
* Mode 2: (R)+
|
||||
|
|
@ -1583,7 +1616,7 @@ CPUStatePDP11.prototype.getAddrByMode = function(mode, reg, accessFlags)
|
|||
case 2:
|
||||
stepSize = 2;
|
||||
virtualAddress = this.regsGen[reg];
|
||||
if (reg !== 7) {
|
||||
if (reg != 7) {
|
||||
virtualAddress |= addrDSpace;
|
||||
if (reg < 6 && (accessFlags & PDP11.ACCESS.BYTE)) {
|
||||
stepSize = 1;
|
||||
|
|
@ -1598,7 +1631,7 @@ CPUStatePDP11.prototype.getAddrByMode = function(mode, reg, accessFlags)
|
|||
case 3:
|
||||
stepSize = 2;
|
||||
virtualAddress = this.regsGen[reg];
|
||||
if (reg !== 7) virtualAddress |= addrDSpace;
|
||||
if (reg != 7) virtualAddress |= addrDSpace;
|
||||
virtualAddress = this.readWord(virtualAddress);
|
||||
virtualAddress |= addrDSpace;
|
||||
this.nStepCycles -= (5 + 2);
|
||||
|
|
@ -1611,7 +1644,7 @@ CPUStatePDP11.prototype.getAddrByMode = function(mode, reg, accessFlags)
|
|||
stepSize = -2;
|
||||
if (reg < 6 && (accessFlags & PDP11.ACCESS.BYTE)) stepSize = -1;
|
||||
virtualAddress = (this.regsGen[reg] + stepSize) & 0xffff;
|
||||
if (reg !== 7) virtualAddress |= addrDSpace;
|
||||
if (reg != 7) virtualAddress |= addrDSpace;
|
||||
this.nStepCycles -= (3 + 1);
|
||||
break;
|
||||
|
||||
|
|
@ -1621,7 +1654,7 @@ CPUStatePDP11.prototype.getAddrByMode = function(mode, reg, accessFlags)
|
|||
case 5:
|
||||
stepSize = -2;
|
||||
virtualAddress = (this.regsGen[reg] - 2) & 0xffff;
|
||||
if (reg !== 7) virtualAddress |= addrDSpace;
|
||||
if (reg != 7) virtualAddress |= addrDSpace;
|
||||
virtualAddress = this.readWord(virtualAddress) | addrDSpace;
|
||||
this.nStepCycles -= (6 + 2);
|
||||
break;
|
||||
|
|
@ -1652,15 +1685,12 @@ CPUStatePDP11.prototype.getAddrByMode = function(mode, reg, accessFlags)
|
|||
this.regMMR1 = (this.regMMR1 << 8) | ((stepSize << 3) & 0xf8) | reg;
|
||||
}
|
||||
|
||||
if (reg == 6 && (!this.mmuMode) && (accessFlags & PDP11.ACCESS.WRITE) && stepSize <= 0 && (this.regsGen[6] <= this.regSL || this.regsGen[6] >= 0xfffe)) {
|
||||
if (this.regsGen[6] <= this.regSL - 32) {
|
||||
this.regErr |= PDP11.CPUERR.RED;
|
||||
this.regsGen[6] = 4;
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.STACKERROR);
|
||||
} else {
|
||||
this.regErr |= PDP11.CPUERR.YELLOW;
|
||||
this.opFlags |= PDP11.OPFLAG.TRAP_SP;
|
||||
}
|
||||
/*
|
||||
* NOTE: We had to eliminate the test for "(accessFlags & PDP11.ACCESS.WRITE)", because DEC's
|
||||
* "TRAP TEST" expects "TST -(SP)" to trap when SP is 150.
|
||||
*/
|
||||
if (reg == 6 && stepSize < 0) {
|
||||
this.checkStackLimit(mode, this.regsGen[6]);
|
||||
}
|
||||
return virtualAddress;
|
||||
};
|
||||
|
|
@ -2191,23 +2221,23 @@ CPUStatePDP11.prototype.stepCPU = function(nMinCycles)
|
|||
/*
|
||||
* Check for any pending traps.
|
||||
*
|
||||
* I've moved this TRAP_MASK check BEFORE we decode the next instruction instead
|
||||
* of immediately AFTER, because the last instruction may have thrown an exception,
|
||||
* kicking us out before we reach the bottom of this loop.
|
||||
* I've moved this TRAP_MASK check BEFORE we decode the next instruction instead of immediately AFTER,
|
||||
* just in case the last instruction threw an exception that kicked us out before we reached the bottom
|
||||
* of the stepCPU() loop.
|
||||
*
|
||||
* Note: I've swapped the order (priority) of the TF and SP traps, based on the PDP-11/20 Handbook.
|
||||
* TODO: Determine if 1) the 11/20 Handbook was wrong, or 2) the 11/70 really has different priorities.
|
||||
*/
|
||||
if (this.opFlags & PDP11.OPFLAG.TRAP_MASK) {
|
||||
if (this.opFlags & PDP11.OPFLAG.TRAP_MMU) {
|
||||
this.trap(PDP11.TRAP.MMU, PDP11.REASON.TRAPMMU); // MMU trap has priority
|
||||
} else {
|
||||
if (this.opFlags & PDP11.OPFLAG.TRAP_SP) {
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.REASON.TRAPSP); // then SP trap
|
||||
} else {
|
||||
if (this.opFlags & PDP11.OPFLAG.TRAP_TF) {
|
||||
this.trap(PDP11.TRAP.BPT, PDP11.REASON.TRAPTF); // and finally a TF trap
|
||||
}
|
||||
}
|
||||
this.trap(PDP11.TRAP.MMU, PDP11.OPFLAG.TRAP_MMU, PDP11.REASON.TRAPMMU);
|
||||
}
|
||||
else if (this.opFlags & PDP11.OPFLAG.TRAP_TF) {
|
||||
this.trap(PDP11.TRAP.BPT, PDP11.OPFLAG.TRAP_TF, PDP11.REASON.TRAPTF);
|
||||
}
|
||||
else if (this.opFlags & PDP11.OPFLAG.TRAP_SP) {
|
||||
this.trap(PDP11.TRAP.BUS_ERROR, PDP11.OPFLAG.TRAP_SP, PDP11.REASON.TRAPSP);
|
||||
}
|
||||
this.opFlags &= ~PDP11.OPFLAG.TRAP_MASK;
|
||||
}
|
||||
/*
|
||||
* If we're in the INTQ or WAIT state, see if any interrupts can kick us out of that state.
|
||||
|
|
|
|||
|
|
@ -1400,7 +1400,7 @@ if (DEBUGGER) {
|
|||
var trapStatus = this.cpu.getTrapStatus();
|
||||
if (trapStatus) {
|
||||
var trapReason = trapStatus >> 8;
|
||||
var sReason = trapReason? (" (" + this.toStrBase(trapReason) + ")") : "";
|
||||
var sReason = trapReason? (" (" + trapReason + ")") : "";
|
||||
this.println("trapped to " + this.toStrBase(trapStatus & 0xff, 1) + sReason);
|
||||
}
|
||||
|
||||
|
|
@ -1724,8 +1724,11 @@ if (DEBUGGER) {
|
|||
*/
|
||||
DebuggerPDP11.prototype.undefinedInstruction = function(opCode)
|
||||
{
|
||||
this.printMessage("undefined opcode " + this.toStrBase(opCode), true, true);
|
||||
return this.stopInstruction(); // allow the caller to step over it if they really want a trap generated
|
||||
if (this.messageEnabled(MessagesPDP11.CPU)) {
|
||||
this.printMessage("undefined opcode " + this.toStrBase(opCode), true, true);
|
||||
return this.stopInstruction(); // allow the caller to step over it if they really want a trap generated
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ var PDP11 = {
|
|||
TRAP: 0x08, // set if last operation was a trap (see trapLast for the vector, and trapReason for the reason)
|
||||
TRAP_TF: 0x10, // aka PDP11.PSW.TF
|
||||
TRAP_MMU: 0x20,
|
||||
TRAP_SP: 0x40,
|
||||
TRAP_SP: 0x40, // set for a deferred BUS_ERROR trap (due to a "yellow" stack overflow condition)
|
||||
TRAP_MASK: 0x70,
|
||||
NO_FLAGS: 0x80, // set whenever the PSW is written directly, requiring all updateXXXFlags() functions to leave flags unchanged
|
||||
PRESERVE: 0x07 // OPFLAG bits to preserve prior to the next instruction
|
||||
|
|
@ -264,24 +264,24 @@ var PDP11 = {
|
|||
* PDP-11 trap reasons (for diagnostic purposes only)
|
||||
*/
|
||||
REASON: {
|
||||
BPT: 1,
|
||||
EMT: 2,
|
||||
HALT: 3,
|
||||
IOT: 4,
|
||||
TRAP: 5,
|
||||
RESERVED: 6,
|
||||
ODDMEMADDR: 10,
|
||||
NOMEMORY: 12,
|
||||
ODDMMUADDR: 14,
|
||||
MAPERROR: 16,
|
||||
PUSHERROR: 18,
|
||||
NOREGADDR: 20,
|
||||
STACKMODE1: 22,
|
||||
STACKERROR: 24,
|
||||
INTERRUPT: 26,
|
||||
TRAPMMU: 28,
|
||||
TRAPSP: 30,
|
||||
TRAPTF: 32
|
||||
BPT: -1,
|
||||
EMT: -2,
|
||||
HALT: -3,
|
||||
IOT: -4,
|
||||
TRAP: -5,
|
||||
RESERVED: -6,
|
||||
TRAPMMU: -7,
|
||||
TRAPSP: -8,
|
||||
TRAPTF: -9,
|
||||
ODDMEMADDR: -10,
|
||||
NOMEMORY: -11,
|
||||
ODDMMUADDR: -12,
|
||||
MAPERROR: -13,
|
||||
PUSHERROR: -14,
|
||||
NOREGADDR: -15,
|
||||
STACKMODE1: -16,
|
||||
STACKERROR: -17,
|
||||
INTERRUPT: -18
|
||||
},
|
||||
/*
|
||||
* Internal memory access flags
|
||||
|
|
|
|||
|
|
@ -1048,7 +1048,16 @@ DevicePDP11.prototype.readPSW = function(addr)
|
|||
*/
|
||||
DevicePDP11.prototype.writePSW = function(data, addr)
|
||||
{
|
||||
var maskDisallowed = PDP11.PSW.UNUSED | PDP11.PSW.TF;
|
||||
/*
|
||||
* pdp11.js disallowed PSW.TF in addition to PSW.UNUSED, but DEC's "TRAP TEST" expects the
|
||||
* following instruction to trap:
|
||||
*
|
||||
* 004174: 052767 000020 173574 BIS #20,177776
|
||||
*
|
||||
* Since that test was written for the PDP-11/20, it's possible that newer machines
|
||||
* have a different behavior, but for now, we assume that all machines allow setting PSW.TF.
|
||||
*/
|
||||
var maskDisallowed = PDP11.PSW.UNUSED;
|
||||
this.cpu.setPSW((data & ~maskDisallowed) | (this.cpu.getPSW() & maskDisallowed));
|
||||
this.cpu.opFlags |= PDP11.OPFLAG.NO_FLAGS;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue