Fixed MMR1/MMR2 updates, and synced boot monitor code with http://skn.noip.me/pdp11/boot.mac
This commit is contained in:
parent
7342ea254e
commit
9d67f243ef
9 changed files with 1401 additions and 809 deletions
|
|
@ -254,8 +254,8 @@ CPUStatePDP11.prototype.resetMMU = function()
|
|||
this.mmuLastMode = 0;
|
||||
this.mmuMask = 0x3ffff;
|
||||
|
||||
this.lastAI = 0; // last auto-incs and/or auto-decs; this gets propagated to MMR1
|
||||
this.lastPC = 0; // last PC at the time of getOpcode(); this get propagated to MMR2
|
||||
this.lastAI = 0; // last auto-incs and/or auto-decs; this is propagated to MMR1 as appropriate
|
||||
this.lastPC = 0; // last PC at the time of getOpcode(); this is propagated to MMR2 as appropriate
|
||||
|
||||
this.resetTriggers();
|
||||
|
||||
|
|
@ -327,6 +327,15 @@ CPUStatePDP11.prototype.setMMR0 = function(newMMR0)
|
|||
{
|
||||
newMMR0 &= 0xf381;
|
||||
if (this.regMMR0 != newMMR0) {
|
||||
/*
|
||||
* If updates to MMR1 and MMR2 are being shut off (ie, MMR0.ABORT bits are transitioning from clear to set),
|
||||
* then do one final sync with their real-time counterparts (lastAI and lastPC).
|
||||
*/
|
||||
if (!(this.regMMR0 & PDP11.MMR0.ABORT) && (newMMR0 & PDP11.MMR0.ABORT)) {
|
||||
this.assert(!(this.lastAI & ~0xffff));
|
||||
this.regMMR1 = this.lastAI & 0xffff;
|
||||
this.regMMR2 = this.lastPC;
|
||||
}
|
||||
this.regMMR0 = newMMR0;
|
||||
this.mmuLastMode = (newMMR0 >> 5) & 3;
|
||||
this.mmuLastPage = (newMMR0 >> 1) & 0xf;
|
||||
|
|
@ -352,7 +361,12 @@ CPUStatePDP11.prototype.setMMR0 = function(newMMR0)
|
|||
*/
|
||||
CPUStatePDP11.prototype.getMMR1 = function()
|
||||
{
|
||||
/*
|
||||
* If updates to MMR1 have not been shut off (ie, MMR0.ABORT bits are clear),
|
||||
* then we are always allowed to sync MMR1 with it real-time counterpart (lastAI).
|
||||
*/
|
||||
if (!(this.regMMR0 & PDP11.MMR0.ABORT)) {
|
||||
this.assert(!(this.lastAI & ~0xffff));
|
||||
this.regMMR1 = this.lastAI & 0xffff;
|
||||
}
|
||||
var result = this.regMMR1;
|
||||
|
|
@ -370,6 +384,10 @@ CPUStatePDP11.prototype.getMMR1 = function()
|
|||
*/
|
||||
CPUStatePDP11.prototype.getMMR2 = function()
|
||||
{
|
||||
/*
|
||||
* If updates to MMR2 have not been shut off (ie, MMR0.ABORT bits are clear),
|
||||
* then we are always allowed to sync MMR2 with it real-time counterpart (lastPC).
|
||||
*/
|
||||
if (!(this.regMMR0 & PDP11.MMR0.ABORT)) {
|
||||
this.regMMR2 = this.lastPC;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -559,7 +559,7 @@ if (DEBUGGER) {
|
|||
var fCompleted = false;
|
||||
if (!dbg.isBusy(true)) {
|
||||
dbg.setBusy(true);
|
||||
fCompleted = dbg.stepCPU(fRepeat? 1 : 0);
|
||||
fCompleted = dbg.stepCPU(fRepeat? 1 : 0, null);
|
||||
dbg.setBusy(false);
|
||||
}
|
||||
return fCompleted;
|
||||
|
|
@ -1317,7 +1317,7 @@ if (DEBUGGER) {
|
|||
*
|
||||
* @this {DebuggerPDP11}
|
||||
* @param {number} nCycles (0 for one instruction without checking breakpoints)
|
||||
* @param {boolean} [fRegs] is true to display registers after step (default is false)
|
||||
* @param {boolean|null} [fRegs] is true to display registers after step (default is false; use null for previous setting)
|
||||
* @param {boolean} [fUpdateDisplays] is false to disable Computer display updates (default is true)
|
||||
* @return {boolean}
|
||||
*/
|
||||
|
|
@ -1325,6 +1325,10 @@ if (DEBUGGER) {
|
|||
{
|
||||
if (!this.checkCPU()) return false;
|
||||
|
||||
if (fRegs === null) {
|
||||
fRegs = (!this.sTraceCmdPrev || this.sTraceCmdPrev == "tr");
|
||||
}
|
||||
|
||||
this.nCycles = 0;
|
||||
|
||||
if (!nCycles) {
|
||||
|
|
@ -2773,12 +2777,12 @@ if (DEBUGGER) {
|
|||
{
|
||||
if (sAddr == '?') {
|
||||
this.println("breakpoint commands:");
|
||||
this.println("\tbp [a]\tset exec breakpoint at addr [a]");
|
||||
this.println("\tbr [a]\tset read breakpoint at addr [a]");
|
||||
this.println("\tbw [a]\tset write breakpoint at addr [a]");
|
||||
this.println("\tbc [a]\tclear breakpoint at addr [a]");
|
||||
this.println("\tbp [#]\tset exec breakpoint at addr #");
|
||||
this.println("\tbr [#]\tset read breakpoint at addr #");
|
||||
this.println("\tbw [#]\tset write breakpoint at addr #");
|
||||
this.println("\tbc [#]\tclear breakpoint at addr #");
|
||||
this.println("\tbl\tlist all breakpoints");
|
||||
this.println("\tbn [n]\tbreak after [n] instruction(s)");
|
||||
this.println("\tbn [#]\tbreak after # instruction(s)");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -3681,6 +3685,15 @@ if (DEBUGGER) {
|
|||
*/
|
||||
DebuggerPDP11.prototype.doTrace = function(sCmd, sCount)
|
||||
{
|
||||
if (sCount == '?') {
|
||||
this.println("trace commands:");
|
||||
this.println("\tt [#]\ttrace # instructions");
|
||||
this.println("\ttr [#]\ttrace # instructions with register updates");
|
||||
this.println("\ttc [#]\ttrace # cycles");
|
||||
this.println("note: bn [#] to break after # instructions is much faster");
|
||||
return;
|
||||
}
|
||||
|
||||
var dbg = this;
|
||||
var fRegs = (sCmd != "t");
|
||||
var nCount = this.parseValue(sCount, null, true) || 1;
|
||||
|
|
@ -3689,6 +3702,7 @@ if (DEBUGGER) {
|
|||
nCycles = nCount;
|
||||
nCount = 1;
|
||||
}
|
||||
this.sTraceCmdPrev = sCmd;
|
||||
web.onCountRepeat(
|
||||
nCount,
|
||||
function onCountStep() {
|
||||
|
|
|
|||
|
|
@ -364,11 +364,11 @@ var PDP11 = {
|
|||
* is enabled, the top 5 bits of an address select one of the 31 mapping registers, and the bottom 13 bits
|
||||
* are then added to the contents of the selected mapping register.
|
||||
*
|
||||
* ES6 ALERT: By using octal constants, this is the first place I'm dipping my toe into ECMAScript 6 waters.
|
||||
* If you're loading this raw source code into your browser, then by now (2016) you're almost certainly using
|
||||
* an ES6-aware browser. Everyone else should be using code compiled by Google's Closure Compiler, which
|
||||
* we configure to produce code that's backward-compatible with ES5 (for example, octal constants are
|
||||
* converted to decimal values).
|
||||
* ES6 ALERT: By using octal constants, I'm finally dipping my toe into ES6 (aka ECMAScript 2015) waters.
|
||||
* You'll even see a few binary constants below, too. If you're loading this raw source code into your browser,
|
||||
* then by now (2016) you're almost certainly using an ES6-aware browser. Production sites should be using code
|
||||
* compiled by Google's Closure Compiler, which we configure to produce code that's backward-compatible with ES5
|
||||
* (for example, all binary, octal, and hex constants are converted to decimal values).
|
||||
*
|
||||
* For more details: https://github.com/google/closure-compiler/wiki/ECMAScript6
|
||||
*/
|
||||
|
|
@ -498,22 +498,22 @@ var PDP11 = {
|
|||
UDPAR6: 0o177674, // User D Page Address Register 6
|
||||
UDPAR7: 0o177676, // User D Page Address Register 7
|
||||
|
||||
R0SET0: 0o177700,
|
||||
R1SET0: 0o177701,
|
||||
R2SET0: 0o177702,
|
||||
R3SET0: 0o177703,
|
||||
R4SET0: 0o177704,
|
||||
R5SET0: 0o177705,
|
||||
R6KERNEL: 0o177706,
|
||||
R7KERNEL: 0o177707,
|
||||
R0SET1: 0o177710,
|
||||
R1SET1: 0o177711,
|
||||
R2SET1: 0o177712,
|
||||
R3SET1: 0o177713,
|
||||
R4SET1: 0o177714,
|
||||
R5SET1: 0o177715,
|
||||
R6SUPER: 0o177716,
|
||||
R6USER: 0o177717,
|
||||
R0SET0: 0o177700, //
|
||||
R1SET0: 0o177701, //
|
||||
R2SET0: 0o177702, //
|
||||
R3SET0: 0o177703, //
|
||||
R4SET0: 0o177704, //
|
||||
R5SET0: 0o177705, //
|
||||
R6KERNEL: 0o177706, //
|
||||
R7KERNEL: 0o177707, //
|
||||
R0SET1: 0o177710, //
|
||||
R1SET1: 0o177711, //
|
||||
R2SET1: 0o177712, //
|
||||
R3SET1: 0o177713, //
|
||||
R4SET1: 0o177714, //
|
||||
R5SET1: 0o177715, //
|
||||
R6SUPER: 0o177716, //
|
||||
R6USER: 0o177717, //
|
||||
|
||||
/*
|
||||
* This next group of registers is largely ignored; all accesses are routed to regsControl[],
|
||||
|
|
|
|||
|
|
@ -655,7 +655,7 @@ PanelPDP11.prototype.processContinue = function(value, index)
|
|||
var dbg = this.dbg;
|
||||
if (dbg && !dbg.isBusy(true)) {
|
||||
dbg.setBusy(true);
|
||||
dbg.stepCPU(0);
|
||||
dbg.stepCPU(0, null);
|
||||
dbg.setBusy(false);
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
Loading…
Reference in a new issue