diff --git a/modules/pcjs/lib/bus.js b/modules/pcjs/lib/bus.js index 386bcae7e..2de7cc040 100644 --- a/modules/pcjs/lib/bus.js +++ b/modules/pcjs/lib/bus.js @@ -1116,10 +1116,7 @@ Bus.prototype.getBackTrackObject = function(bti) { if (BACKTRACK) { var slot = bti >>> Bus.BACKTRACK.SLOT_SHIFT; - if (slot) { - var bto = this.abtObjects[slot-1]; - if (bto) return bto.obj; - } + if (slot) return this.abtObjects[slot-1]; } return null; }; @@ -1152,9 +1149,9 @@ Bus.prototype.getBackTrackInfo = function(bti) var file = bto.obj.file; if (file) { this.assert(!bto.off); - return file.sName + '[' + (bto.obj.offFile + off) + ']'; + return file.sName + '[' + str.toHexLong(bto.obj.offFile + off) + ']'; } - return bto.obj.idComponent + '[' + (bto.off + off) + ']'; + return bto.obj.idComponent + '[' + str.toHexLong(bto.off + off) + ']'; } } return null; diff --git a/modules/pcjs/lib/debugger.js b/modules/pcjs/lib/debugger.js index 83011b85f..e32d15697 100644 --- a/modules/pcjs/lib/debugger.js +++ b/modules/pcjs/lib/debugger.js @@ -1909,15 +1909,17 @@ if (DEBUGGER) { }; /** - * dumpHistory(sCount) + * dumpHistory(sCount, cLines) * * @this {Debugger} - * @param {string|undefined} sCount is the number of instructions to rewind to (default is 10) + * @param {string} [sCount] is the number of instructions to rewind to (default is 10) + * @param {number} [cLines] is the number of instructions to print (default is, again, 10) */ - Debugger.prototype.dumpHistory = function(sCount) + Debugger.prototype.dumpHistory = function(sCount, cLines) { var sMore = ""; - var cLines = 10; + cLines = cLines || 10; + var cHistory = 0; var iHistory = this.iOpcodeHistory; var aHistory = this.aOpcodeHistory; if (aHistory.length) { @@ -1960,10 +1962,11 @@ if (DEBUGGER) { } if (iHistory >= aHistory.length) iHistory = 0; this.nextHistory = n; + cHistory++; cLines--; } } - if (cLines == 10) { + if (!cHistory) { this.println("no " + sMore + "history available"); this.nextHistory = undefined; } @@ -2050,7 +2053,7 @@ if (DEBUGGER) { }; /** - * getRegIndex(sReg) + * getRegIndex(sReg, off) * * @this {Debugger} * @param {string} sReg @@ -2203,7 +2206,7 @@ if (DEBUGGER) { }; /** - * replaceRegs() + * replaceRegs(s) * * @this {Debugger} * @param {string} s @@ -4325,8 +4328,10 @@ if (DEBUGGER) { this.println("\tdb [a] [#] dump # bytes at address a"); this.println("\tdw [a] [#] dump # words at address a"); this.println("\tdd [a] [#] dump # dwords at address a"); - this.println("\tdh [#] dump # instructions prior"); - if (BACKTRACK) this.println("\tdi [a] dump backtrack info at address a"); + this.println("\tdh [#] [#] dump # instructions prior"); + if (BACKTRACK) { + this.println("\tdi [a] dump backtrack info at address a"); + } if (sDumpers.length) this.println("dump extensions:\n\t" + sDumpers); return; } @@ -4338,8 +4343,13 @@ if (DEBUGGER) { this.dumpSymbols(); return; } + var cLines = 0; + if (sLen) { + if (sLen.charAt(0) == "l") sLen = sLen.substr(1); + cLines = +sLen; + } if (sCmd == "dh") { - this.dumpHistory(sAddr); + this.dumpHistory(sAddr, cLines); return; } if (sCmd == "ds") { // transform a "ds" command into a "d desc" command @@ -4369,15 +4379,14 @@ if (DEBUGGER) { sDump += sInfo || "no information"; } else { - var cLines = 0; var cBytes = (sCmd == "dd"? 4 : (sCmd == "dw"? 2 : 1)); var cNumbers = (16 / cBytes)|0; - if (sLen) { - if (sLen.charAt(0) == "l") sLen = sLen.substr(1); - cLines = +sLen; - if (cLines) cLines = ((cLines + cNumbers - 1) / cNumbers)|0; + if (!cLines) { + cLines = 8; + } else { + cLines = ((cLines + cNumbers - 1) / cNumbers)|0; + if (!cLines) cLines = 1; } - if (!cLines) cLines = 8; for (var iLine = 0; iLine < cLines; iLine++) { var data = 0, iByte = 0; var sData = "", sChars = ""; diff --git a/modules/pcjs/lib/x86func.js b/modules/pcjs/lib/x86func.js index c19fdc23e..5bc81de8c 100644 --- a/modules/pcjs/lib/x86func.js +++ b/modules/pcjs/lib/x86func.js @@ -2147,9 +2147,18 @@ X86.fnRETF = function RETF(n) var newIP = this.popWord(); var newCS = this.popWord(); if (DEBUG) this.printMessage(" returning to " + str.toHex(newCS, 4) + ':' + str.toHex(newIP, this.dataSize << 1), this.bitsMessage, true); + n <<= (this.dataSize >> 2); if (n) this.setSP(this.getSP() + n); // TODO: optimize - if (this.setCSIP(newIP, newCS, false)) { + + if (this.setCSIP(newIP, newCS, false)) { // returns true if a stack switch occurred + /* + * Fool me once, shame on... whatever. If setCSIP() indicates a stack switch occurred, + * make sure we're in protected mode, because automatic stack switches can't occur in real mode, + * and adjusting SP again under those circumstances will likely cause great harm. + */ + this.assert(!!(this.regCR0 & X86.CR0.MSW.PE)); + if (n) this.setSP(this.getSP() + n); // TODO: optimize /* * As per Intel documentation: "If any of [the DS or ES] registers refer to segments whose DPL is diff --git a/modules/pcjs/lib/x86seg.js b/modules/pcjs/lib/x86seg.js index 6821d9148..d959f6ea2 100644 --- a/modules/pcjs/lib/x86seg.js +++ b/modules/pcjs/lib/x86seg.js @@ -1037,6 +1037,7 @@ X86Seg.prototype.updateMode = function(fLoad, fProt) this.checkWrite = this.checkWriteReal; this.cpl = this.dpl = 0; this.addrDesc = X86.ADDR_INVALID; + this.fStackSwitch = false; } return fProt; };