Handle double-RED abort conditions by stopping the CPU and reporting a PANIC
This commit is contained in:
parent
4f7f72af57
commit
02b1b8a34a
12 changed files with 180 additions and 174 deletions
|
|
@ -10,6 +10,4 @@
|
|||
<panel ref="/devices/pdp11/panel/test/debugger/terminal.xml"/>
|
||||
<debugger id="debugger" base="8" messages="" commands=""/>
|
||||
<device ref="/devices/pdp11/pc11/default.xml"/>
|
||||
<device ref="/devices/pdp11/rk11/default.xml"/>
|
||||
<device ref="/devices/pdp11/rl11/default.xml"/>
|
||||
</machine>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,4 @@
|
|||
<serial id="dl11" adapter="0" binding="print"/>
|
||||
<panel ref="/devices/pdp11/panel/test/terminal.xml"/>
|
||||
<device ref="/devices/pdp11/pc11/default.xml"/>
|
||||
<device ref="/devices/pdp11/rk11/default.xml"/>
|
||||
<device ref="/devices/pdp11/rl11/default.xml"/>
|
||||
</machine>
|
||||
|
|
|
|||
|
|
@ -15,6 +15,6 @@ machines:
|
|||
|
||||
{% include machine.html id="test1170" %}
|
||||
|
||||
This PDP-11/70 is also available with our built-in [Debugger](debugger/).
|
||||
|
||||
{% include machine.html id="vt100" %}
|
||||
|
||||
This PDP-11/70 is also available with our built-in [Debugger](debugger/).
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml-stylesheet type="text/xsl" href="/versions/pdpjs/1.30.5/machine.xsl"?>
|
||||
<machine id="test1170" class="pdp11" border="1" pos="center" background="#FAEBD7">
|
||||
<machine id="test1170" class="pdp11 machine-left" border="1" pos="center" background="#FAEBD7">
|
||||
<name pos="center">PDP-11/70 with 256Kb, Front Panel, and Debugger</name>
|
||||
<computer id="computer" busWidth="22"/>
|
||||
<cpu id="cpu" model="1170" cycles="6666667" autoStart="true"/>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml-stylesheet type="text/xsl" href="/versions/pdpjs/1.30.5/machine.xsl"?>
|
||||
<machine id="test1170" class="pdp11" border="1" pos="center" background="#FAEBD7">
|
||||
<machine id="test1170" class="pdp11 machine-left" border="1" pos="center" background="#FAEBD7">
|
||||
<name pos="center">PDP-11/70 with 256Kb and Front Panel</name>
|
||||
<computer id="computer" busWidth="22"/>
|
||||
<cpu id="cpu" model="1170" cycles="6666667" autoStart="true"/>
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ disk cartridges.
|
|||
|
||||
Machines containing the [RK11 Component](/modules/pdp11/lib/rk11.js) include:
|
||||
|
||||
- [PDP-11/70 Boot Monitor](/devices/pdp11/machine/1170/monitor/) (with [Debugger](/devices/pdp11/machine/1170/monitor/debugger/))
|
||||
- [PDP-11/70 with Front Panel](/devices/pdp11/machine/1170/panel/) (with [Debugger](/devices/pdp11/machine/1170/panel/debugger/))
|
||||
- [PDP-11/70 with VT100 Terminal](/devices/pdp11/machine/1170/vt100/) (with [Debugger](/devices/pdp11/machine/1170/vt100/debugger/))
|
||||
|
||||
PCjs has archived a selection of [RK03 Disk Images](/disks/dec/rk03/) from [Paul Nankervis](http://skn.noip.me/pdp11/)
|
||||
for use by those machines, which are listed in the following RK11 Device XML file:
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ The RL11 Disk Controller controls up to four RL01 or RL02 disk drives, which in
|
|||
|
||||
Machines containing the [RL11 Component](/modules/pdp11/lib/pc11.js) include:
|
||||
|
||||
- [PDP-11/70 Boot Monitor](/devices/pdp11/machine/1170/monitor/) (with [Debugger](/devices/pdp11/machine/1170/monitor/debugger/))
|
||||
- [PDP-11/70 with Front Panel](/devices/pdp11/machine/1170/panel/) (with [Debugger](/devices/pdp11/machine/1170/panel/debugger/))
|
||||
- [PDP-11/70 with VT100 Terminal](/devices/pdp11/machine/1170/vt100/) (with [Debugger](/devices/pdp11/machine/1170/vt100/debugger/))
|
||||
|
||||
PCjs has archived a selection of [RL01K](/disks/dec/rl01k/) and [RL02K](/disks/dec/rl02k/) disk images
|
||||
from [Paul Nankervis](http://skn.noip.me/pdp11/) for use by those machines, which are also listed in the
|
||||
|
|
|
|||
|
|
@ -1368,18 +1368,20 @@ CPUStatePDP11.prototype.trap = function(vector, flag, reason)
|
|||
reason = PDP11.REASON.RED; // double-fault (nested trap) forces a RED condition
|
||||
}
|
||||
|
||||
var fRed = false;
|
||||
if (reason == PDP11.REASON.RED) {
|
||||
vector = 4;
|
||||
if (this.opFlags & PDP11.OPFLAG.TRAP_RED) {
|
||||
reason = PDP11.REASON.PANIC;
|
||||
}
|
||||
this.opFlags |= PDP11.OPFLAG.TRAP_RED;
|
||||
/*
|
||||
* The next two lines used to be deferred until after the setPSW() below, but
|
||||
* I'm not seeing any dependencies on these registers, so I'm consolidating the code.
|
||||
*/
|
||||
this.regErr |= PDP11.CPUERR.RED;
|
||||
this.regsGen[6] = 4;
|
||||
fRed = true;
|
||||
this.regsGen[6] = vector = 4;
|
||||
}
|
||||
|
||||
if (reason != PDP11.REASON.PANIC) {
|
||||
/*
|
||||
* NOTE: Pre-setting the auto-dec values for MMR1 to 0xF6F6 is a work-around for an "EKBEE1"
|
||||
* diagnostic (PC 056710), which tests what happens when a misaligned read triggers a BUS trap,
|
||||
|
|
@ -1406,9 +1408,10 @@ CPUStatePDP11.prototype.trap = function(vector, flag, reason)
|
|||
*/
|
||||
this.setPSW((newPSW & ~PDP11.PSW.PMODE) | ((this.trapPSW >> 2) & PDP11.PSW.PMODE));
|
||||
|
||||
this.pushWord(this.trapPSW, fRed);
|
||||
this.pushWord(this.regsGen[7], fRed);
|
||||
this.pushWord(this.trapPSW);
|
||||
this.pushWord(this.regsGen[7]);
|
||||
this.setPC(newPC);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Determine the appropriate number of cycles for traps; all I've done for now is move the
|
||||
|
|
@ -1459,6 +1462,9 @@ CPUStatePDP11.prototype.trap = function(vector, flag, reason)
|
|||
this.trapVector = vector;
|
||||
this.trapReason = reason;
|
||||
|
||||
if (reason == PDP11.REASON.PANIC) {
|
||||
this.stopCPU();
|
||||
}
|
||||
if (reason >= PDP11.REASON.RED) throw vector;
|
||||
};
|
||||
|
||||
|
|
@ -1790,18 +1796,17 @@ CPUStatePDP11.prototype.popWord = function()
|
|||
};
|
||||
|
||||
/**
|
||||
* pushWord(data, fRed)
|
||||
* pushWord(data)
|
||||
*
|
||||
* @this {CPUStatePDP11}
|
||||
* @param {number} data
|
||||
* @param {boolean} [fRed]
|
||||
*/
|
||||
CPUStatePDP11.prototype.pushWord = function(data, fRed)
|
||||
CPUStatePDP11.prototype.pushWord = function(data)
|
||||
{
|
||||
var addrVirtual = (this.regsGen[6] - 2) & 0xffff;
|
||||
this.regsGen[6] = addrVirtual; // BSD needs SP updated before any fault :-(
|
||||
this.opLast = (this.opLast & 0xffff) | ((this.opLast & ~0xffff) << 8) | (0x00f6 << 16);
|
||||
if (!fRed) this.checkStackLimit(PDP11.ACCESS.WRITE_WORD, -2, addrVirtual);
|
||||
if (!(this.opFlags & PDP11.OPFLAG.TRAP_RED)) this.checkStackLimit(PDP11.ACCESS.WRITE_WORD, -2, addrVirtual);
|
||||
this.writeWord(addrVirtual, data);
|
||||
};
|
||||
|
||||
|
|
@ -2623,6 +2628,7 @@ CPUStatePDP11.prototype.stepCPU = function(nMinCycles)
|
|||
} else {
|
||||
this.assert(!this.irqNext && !this.regPIR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Snapshot the TF bit in opFlags, while clearing all other opFlags (except those in PRESERVE);
|
||||
* we'll check the TRAP_TF bit in opFlags when we come back around for another opcode.
|
||||
|
|
|
|||
|
|
@ -219,18 +219,20 @@ var PDP11 = {
|
|||
* immediate (thrown) traps, as they are considered ABORTs; the rest generate synchronous traps.
|
||||
*/
|
||||
REASON: {
|
||||
ABORT: -1, // immediate MMU fault
|
||||
ILLEGAL: -2, // immediate invalid opcode (BUS)
|
||||
RED: -3, // immediate stack overflow fault (BUS)
|
||||
YELLOW: -4, // deferred stack overflow fault (BUS)
|
||||
FAULT: -5, // deferred MMU fault
|
||||
TRACE: -6, // deferred TF fault (BPT)
|
||||
HALT: -7, // illegal HALT (BUS)
|
||||
OPCODE: -8, // opcode-generated trap (eg, BPT, EMT, IOT, TRAP, or RESERVED opcode)
|
||||
INTERRUPT: -9, // device-generated trap (vector is device-specific)
|
||||
PANIC: -1, // immediate halt (internal error)
|
||||
ABORT: -2, // immediate MMU fault
|
||||
ILLEGAL: -3, // immediate invalid opcode (BUS)
|
||||
RED: -4, // immediate stack overflow fault (BUS)
|
||||
YELLOW: -5, // deferred stack overflow fault (BUS)
|
||||
FAULT: -6, // deferred MMU fault
|
||||
TRACE: -7, // deferred TF fault (BPT)
|
||||
HALT: -8, // illegal HALT (BUS)
|
||||
OPCODE: -9, // opcode-generated trap (eg, BPT, EMT, IOT, TRAP, or RESERVED opcode)
|
||||
INTERRUPT: -10, // device-generated trap (vector is device-specific)
|
||||
},
|
||||
REASONS: [
|
||||
"UNKNOWN",
|
||||
"PANIC",
|
||||
"ABORT",
|
||||
"ILLEGAL",
|
||||
"RED",
|
||||
|
|
@ -271,7 +273,8 @@ var PDP11 = {
|
|||
TRAP_MMU: 0x0040,
|
||||
TRAP_MASK: 0x0070,
|
||||
TRAP_LAST: 0x0080, // set if last operation was a trap (see trapLast for the vector, and trapReason for the reason)
|
||||
NO_FLAGS: 0x0100 // set whenever the PSW is written directly, requiring all updateXXXFlags() functions to leave flags unchanged
|
||||
TRAP_RED: 0x0100, // set whenever a RED trap occurs, used to catch double RED traps (time to PANIC)
|
||||
NO_FLAGS: 0x0200 // set whenever the PSW is written directly, requiring all updateXXXFlags() functions to leave flags unchanged
|
||||
},
|
||||
/*
|
||||
* Opcode reg (opcode bits 2-0)
|
||||
|
|
|
|||
|
|
@ -713,10 +713,10 @@ PC11.prototype.parseTape = function(sTapeName, sTapePath, nTapeTarget, aBytes, a
|
|||
this.sTapePath = "";
|
||||
this.sTapeSource = PC11.SOURCE.NONE;
|
||||
this.nTapeTarget = PC11.TARGET.NONE;
|
||||
this.notice("No load address available for tape: " + sTapeName);
|
||||
this.notice('No load address available for tape "' + sTapeName + '"');
|
||||
return;
|
||||
}
|
||||
this.status("tape loaded: " + sTapeName);
|
||||
this.status('Loaded tape "' + sTapeName + '"');
|
||||
return;
|
||||
}
|
||||
this.iTapeData = 0;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue