From f8d7c5d5181a5bbba1d800cf0af498f17e183d29 Mon Sep 17 00:00:00 2001 From: Jeff Parsons Date: Thu, 23 Jul 2015 16:58:01 -0700 Subject: [PATCH] Updated reset to reset page tables, fixed RET[F]n instructions, and added some Debugger improvements --- modules/pcjs/lib/debugger.js | 51 +++++++++++++++++------------------- modules/pcjs/lib/x86.js | 4 ++- modules/pcjs/lib/x86cpu.js | 1 + modules/pcjs/lib/x86func.js | 14 ++++++---- modules/pcjs/lib/x86ops.js | 14 +++++++--- 5 files changed, 47 insertions(+), 37 deletions(-) diff --git a/modules/pcjs/lib/debugger.js b/modules/pcjs/lib/debugger.js index af048be5e..b71db3878 100644 --- a/modules/pcjs/lib/debugger.js +++ b/modules/pcjs/lib/debugger.js @@ -3407,7 +3407,7 @@ if (DEBUGGER) { } if (sComment && fNonPrefix) { - sLine = str.pad(sLine, dbgAddrIns.fAddr32? 68 : 56) + ';' + sComment; + sLine = str.pad(sLine, dbgAddrIns.fAddr32? 74 : 56) + ';' + sComment; if (!this.cpu.aFlags.fChecksum) { sLine += (nSequence != null? '=' + nSequence.toString() : ""); } else { @@ -3444,7 +3444,7 @@ if (DEBUGGER) { } break; case Debugger.TYPE_SBYTE: - sOperand = str.toHex((this.getByte(dbgAddr, 1) << 24) >> 24, 4); + sOperand = str.toHex((this.getByte(dbgAddr, 1) << 24) >> 24, dbgAddr.fData32? 8: 4); break; case Debugger.TYPE_VWORD: case Debugger.TYPE_2WORD: @@ -3888,15 +3888,15 @@ if (DEBUGGER) { var iColon = sAddr.indexOf(":"); if (iColon < 0) { if (sel != null) { - off = this.parseValue(sAddr); + off = this.parseExpression(sAddr); addr = null; } else { - addr = this.parseValue(sAddr); + addr = this.parseExpression(sAddr); } } else { - sel = this.parseValue(sAddr.substring(0, iColon)); - off = this.parseValue(sAddr.substring(iColon + 1)); + sel = this.parseExpression(sAddr.substring(0, iColon)); + off = this.parseExpression(sAddr.substring(iColon + 1)); addr = null; } } @@ -4413,7 +4413,7 @@ if (DEBUGGER) { { var sParm = sCmd.charAt(1); if (!sParm || sParm == "?") { - this.println("\nbreakpoint commands:"); + this.println("breakpoint commands:"); this.println("\tbi [p]\ttoggle break on input port [p]"); this.println("\tbo [p]\ttoggle break on output port [p]"); this.println("\tbp [a]\tset exec breakpoint at addr [a]"); @@ -4521,7 +4521,7 @@ if (DEBUGGER) { } } sDumpers += ",state,symbols"; - this.println("\ndump commands:"); + this.println("dump commands:"); 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"); @@ -4598,7 +4598,7 @@ if (DEBUGGER) { } sChars += (b >= 32 && b < 128? String.fromCharCode(b) : "."); } - if (sDump) sDump += "\n"; + if (sDump) sDump += '\n'; sDump += sAddr + " " + sData + " " + sChars; } } @@ -4641,7 +4641,7 @@ if (DEBUGGER) { Debugger.prototype.doFreqs = function(sParm) { if (sParm == "?") { - this.println("\nfrequency commands:"); + this.println("frequency commands:"); this.println("\tclear\tclear all frequency counts"); return; } @@ -4733,7 +4733,7 @@ if (DEBUGGER) { * * this.println(s); */ - sDump += (sDump? "\n" : "") + s; + sDump += (sDump? '\n' : "") + s; cLines--; } if (i >= this.aTraceBuffer.length) @@ -4774,7 +4774,7 @@ if (DEBUGGER) { Debugger.prototype.doInput = function(sPort) { if (!sPort || sPort == "?") { - this.println("\ninput commands:"); + this.println("input commands:"); this.println("\ti [p]\tread port [p]"); /* * TODO: Regarding this warning, consider adding an "unchecked" version of @@ -4850,7 +4850,7 @@ if (DEBUGGER) { Debugger.prototype.doLoad = function(asArgs) { if (asArgs[0] == 'l' && asArgs[1] === undefined || asArgs[1] == "?") { - this.println("\nlist/load commands:"); + this.println("list/load commands:"); this.println("\tl [address] [drive #] [sector #] [# sectors]"); this.println("\tln [address] lists symbol(s) nearest to address"); return; @@ -4996,7 +4996,7 @@ if (DEBUGGER) { var bitMessage = Debugger.MESSAGES[m]; var fEnabled = !!(this.bitsMessage & bitMessage); if (fCriteria !== null && fCriteria != fEnabled) continue; - if (sCategories) sCategories += ","; + if (sCategories) sCategories += ','; if (!(++n % 10)) sCategories += "\n\t"; // jshint ignore:line if (m == "key") m = "keys"; sCategories += m; @@ -5004,7 +5004,7 @@ if (DEBUGGER) { } if (sCategory === undefined) { - this.println("\nmessage commands:\n\tm [category] [on|off]\tturn categories on/off"); + this.println("message commands:\n\tm [category] [on|off]\tturn categories on/off"); } this.println((fCriteria !== null? (fCriteria? "messages on: " : "messages off: ") : "message categories:\n\t") + (sCategories || "none")); @@ -5021,7 +5021,7 @@ if (DEBUGGER) { Debugger.prototype.doExecOptions = function(asArgs) { if (asArgs[1] === undefined || asArgs[1] == "?") { - this.println("\nexecution options:"); + this.println("execution options:"); this.println("\tcs int #\tset checksum cycle interval to #"); this.println("\tcs start #\tset checksum cycle start count to #"); this.println("\tcs stop #\tset checksum cycle stop count to #"); @@ -5073,7 +5073,7 @@ if (DEBUGGER) { Debugger.prototype.doOutput = function(sPort, sByte) { if (!sPort || sPort == "?") { - this.println("\noutput commands:"); + this.println("output commands:"); this.println("\to [p] [b]\twrite byte [b] to port [p]"); /* * TODO: Regarding this warning, consider adding an "unchecked" version of @@ -5104,7 +5104,7 @@ if (DEBUGGER) { Debugger.prototype.doRegisters = function(asArgs, fCompact) { if (asArgs && asArgs[1] == "?") { - this.println("\nregister commands:"); + this.println("register commands:"); this.println("\tr\t\tdisplay all registers"); this.println("\tr [target=#]\tmodify target register"); this.println("supported targets:"); @@ -5324,12 +5324,12 @@ if (DEBUGGER) { return; } this.cpu.updateCPU(); - this.println("\nupdated registers:"); + this.println("updated registers:"); fCompact = true; } } - this.println((fCompact? '' : '\n') + this.getRegDump(fProt)); + this.println(this.getRegDump(fProt)); if (fIns) { this.dbgAddrNextCode = this.newAddr(this.cpu.getIP(), this.cpu.getCS()); @@ -5654,8 +5654,6 @@ if (DEBUGGER) { n = -1; } - var fBlank = (dbgAddr.off != this.dbgAddrNextCode.off); - var cLines = 0; this.initAddrSize(dbgAddr, true); @@ -5669,13 +5667,10 @@ if (DEBUGGER) { if (aSymbol[0]) { var sLabel = aSymbol[0] + ":"; - fBlank = false; if (aSymbol[2]) sLabel += " " + aSymbol[2]; this.println(sLabel); } - if (fBlank) this.println(); - if (aSymbol[3]) { sComment = aSymbol[3]; nSequence = null; @@ -5693,7 +5688,6 @@ if (DEBUGGER) { this.println(sIns); this.dbgAddrNextCode = dbgAddr; cb -= dbgAddr.addr - addr; - fBlank = false; cLines++; } }; @@ -5752,6 +5746,9 @@ if (DEBUGGER) { sCmd = '?'; } } + else { + this.println(">> " + sCmd); + } sCmd = sCmd.toLowerCase(); @@ -5766,7 +5763,7 @@ if (DEBUGGER) { } else { /* - * Process any "whole" commands here first (eg, "debug", "nodebug", "reset", etc.) + * Process any "whole word" commands here first (eg, "debug", "nodebug", "reset", etc.) * * For all other commands, if they lack a space between the command and argument portions, * insert a space before the first non-alpha character, so that split() will have the desired effect. diff --git a/modules/pcjs/lib/x86.js b/modules/pcjs/lib/x86.js index feae59db9..74f4b23f2 100644 --- a/modules/pcjs/lib/x86.js +++ b/modules/pcjs/lib/x86.js @@ -80,7 +80,9 @@ var X86 = { SHIFT: 12 }, NT: 0x4000, // bit 14: Nested Task flag (always set on 8086/80186, clear on 80286 reset) - BIT15: 0x8000 // bit 15: reserved (always set on 8086/80186, clear otherwise) + BIT15: 0x8000, // bit 15: reserved (always set on 8086/80186, clear otherwise) + RF: 0x10000, // bit 16: Resume Flag (temporarily disables debug exceptions; 80386 only) + VM: 0x20000 // bit 17: Virtual 8086 Mode (80386 only) }, CR0: { /* diff --git a/modules/pcjs/lib/x86cpu.js b/modules/pcjs/lib/x86cpu.js index b55b50f99..e228cfde4 100644 --- a/modules/pcjs/lib/x86cpu.js +++ b/modules/pcjs/lib/x86cpu.js @@ -1233,6 +1233,7 @@ X86CPU.prototype.resetRegs = function() this.aRegTR = new Array(8); // Test Registers TR0-TR7 this.segFS = new X86Seg(this, X86Seg.ID.DATA, "FS"); this.segGS = new X86Seg(this, X86Seg.ID.DATA, "GS"); + this.disablePageBlocks(); } this.segNULL = new X86Seg(this, X86Seg.ID.NULL, "NULL"); diff --git a/modules/pcjs/lib/x86func.js b/modules/pcjs/lib/x86func.js index 859eecb23..f5db355fc 100644 --- a/modules/pcjs/lib/x86func.js +++ b/modules/pcjs/lib/x86func.js @@ -341,7 +341,8 @@ X86.fnBTS = function BTS(dst, src) */ X86.fnCALLw = function CALLw(dst, src) { - if (DEBUG) this.printMessage("calling " + str.toHex(dst, this.dataSize << 1), this.bitsMessage, true); + // if (DEBUG) this.printMessage("calling " + str.toHex(dst, this.dataSize << 1), this.bitsMessage, true); + this.pushWord(this.getIP()); this.setIP(dst); this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesCallWR : this.cycleCounts.nOpCyclesCallWM); @@ -361,7 +362,8 @@ X86.fnCALLw = function CALLw(dst, src) */ X86.fnCALLF = function CALLF(off, sel) { - if (DEBUG) this.printMessage("calling " + str.toHex(sel, 4) + ':' + str.toHex(off, this.dataSize << 1), this.bitsMessage, true); + // if (DEBUG) this.printMessage("calling " + str.toHex(sel, 4) + ':' + str.toHex(off, this.dataSize << 1), this.bitsMessage, true); + var oldCS = this.getCS(); var oldIP = this.getIP(); if (this.setCSIP(off, sel, true) != null) { @@ -1256,7 +1258,9 @@ X86.fnIRET = function IRET() var newIP = this.popWord(); var newCS = this.popWord(); var newPS = this.popWord(); - if (DEBUG) this.printMessage(" returning to " + str.toHex(newCS, 4) + ':' + str.toHex(newIP, this.dataSize << 1), this.bitsMessage, true); + + // if (DEBUG) this.printMessage(" returning to " + str.toHex(newCS, 4) + ':' + str.toHex(newIP, this.dataSize << 1), this.bitsMessage, true); + if (this.setCSIP(newIP, newCS, false) != null) { this.setPS(newPS, cpl); if (MAXDEBUG && this.cIntReturn) this.checkIntReturn(this.regLIP); @@ -2149,9 +2153,9 @@ 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 (DEBUG) this.printMessage(" returning to " + str.toHex(newCS, 4) + ':' + str.toHex(newIP, this.dataSize << 1), this.bitsMessage, true); + if (n) this.setSP(this.getSP() + n); // TODO: optimize if (this.setCSIP(newIP, newCS, false)) { // returns true if a stack switch occurred diff --git a/modules/pcjs/lib/x86ops.js b/modules/pcjs/lib/x86ops.js index 30d7f4378..127800ad8 100644 --- a/modules/pcjs/lib/x86ops.js +++ b/modules/pcjs/lib/x86ops.js @@ -3204,9 +3204,11 @@ X86.opGRP2wn = function GRP2wn() */ X86.opRETn = function RETn() { - var n = this.getIPShort() << (this.dataSize >> 2); + var n = this.getIPShort(); var newIP = this.popWord(); - if (DEBUG) this.printMessage(" returning to " + str.toHex(this.segCS.sel, 4) + ':' + str.toHex(newIP, this.dataSize << 1), this.bitsMessage, true); + + // if (DEBUG) this.printMessage(" returning to " + str.toHex(this.segCS.sel, 4) + ':' + str.toHex(newIP, this.dataSize << 1), this.bitsMessage, true); + this.setIP(newIP); if (n) this.setSP(this.getSP() + n); // TODO: optimize this.nStepCycles -= this.cycleCounts.nOpCyclesRetn; @@ -3220,7 +3222,9 @@ X86.opRETn = function RETn() X86.opRET = function RET() { var newIP = this.popWord(); - if (DEBUG) this.printMessage(" returning to " + str.toHex(this.segCS.sel, 4) + ':' + str.toHex(newIP, this.dataSize << 1), this.bitsMessage, true); + + // if (DEBUG) this.printMessage(" returning to " + str.toHex(this.segCS.sel, 4) + ':' + str.toHex(newIP, this.dataSize << 1), this.bitsMessage, true); + this.setIP(newIP); this.nStepCycles -= this.cycleCounts.nOpCyclesRet; }; @@ -3700,7 +3704,9 @@ X86.opCALL = function CALL() var disp = this.getIPWord(); var oldIP = this.getIP(); var newIP = oldIP + disp; - if (DEBUG) this.printMessage("calling " + str.toHex(newIP, this.dataSize << 1), this.bitsMessage, true); + + // if (DEBUG) this.printMessage("calling " + str.toHex(newIP, this.dataSize << 1), this.bitsMessage, true); + this.pushWord(oldIP); this.setIP(newIP); this.nStepCycles -= this.cycleCounts.nOpCyclesCall;