From cffa72205aa2d367c66891e939b150a825c5d335 Mon Sep 17 00:00:00 2001 From: Jeff Parsons Date: Mon, 3 Aug 2015 17:13:43 -0700 Subject: [PATCH] More Debug register tweaks --- modules/pcjs/lib/x86cpu.js | 10 +++++----- modules/pcjs/lib/x86func.js | 18 ++++++++++++------ 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/modules/pcjs/lib/x86cpu.js b/modules/pcjs/lib/x86cpu.js index 105de30ad..92e79a81f 100644 --- a/modules/pcjs/lib/x86cpu.js +++ b/modules/pcjs/lib/x86cpu.js @@ -1785,10 +1785,10 @@ X86CPU.prototype.checkMemoryException = function(addr, nb, fWrite) * NOTE: We're preventing redundant X86.EXCEPTION.DEBUG exceptions for a single instruction by checking * X86.OPFLAG.DEBUG. I decided not to rely on the generic X86.OPFLAG.FAULT, because if an instruction * first triggers a DIFFERENT exception which then triggers a DEBUG exception (eg, because a Debug register - * was set on the IDT entry of the first exception), that we'd actually like to see the DEBUG exception, - * as opposed to, say, a double fault. TODO: Determine if that SHOULD generate a double-fault. + * was set on the IDT entry of the first exception), then presumably we'd like to see that DEBUG exception, + * as opposed to, say, a double fault. TODO: Determine whether that SHOULD generate a double-fault. */ - if (!(this.opFlags & X86.OPFLAG.FAULT) && (this.regDR[7] & X86.DR7.ENABLE)) { + if (!(this.opFlags & X86.OPFLAG.DEBUG) && (this.regDR[7] & X86.DR7.ENABLE)) { nb--; /* * We use a constant mask for the enable bits (X86.DR7.L0 | X86.DR7.G0) and shift our copy of regDR7 @@ -1814,7 +1814,6 @@ X86CPU.prototype.checkMemoryException = function(addr, nb, fWrite) */ if (addr + nb >= this.regDR[i] && addr <= this.regDR[i] + len) { this.regDR[6] |= (1 << i); - this.opFlags |= X86.OPFLAG.DEBUG; X86.fnFault.call(this, X86.EXCEPTION.DEBUG); return; } @@ -1884,7 +1883,7 @@ X86CPU.prototype.saveProtMode = function() this.segTSS.save(), this.nIOPL ]; - if (I386) { + if (I386 && this.model >= X86.MODEL_80386) { a.push(this.regCR1); a.push(this.regCR2); a.push(this.regCR3); @@ -3978,6 +3977,7 @@ X86CPU.prototype.checkINTR = function() case 1: if ((this.intFlags & X86.INTFLAG.TRAP)) { this.intFlags &= ~X86.INTFLAG.TRAP; + if (I386 && this.model >= X86.MODEL_80386) this.regDR[6] |= X86.DR6.BS; X86.fnINT.call(this, X86.EXCEPTION.DEBUG, null, 11); return true; } diff --git a/modules/pcjs/lib/x86func.js b/modules/pcjs/lib/x86func.js index 4e77ff2d4..97cef61b4 100644 --- a/modules/pcjs/lib/x86func.js +++ b/modules/pcjs/lib/x86func.js @@ -3694,13 +3694,19 @@ X86.fnSrcNone = function SrcNone() X86.fnFault = function(nFault, nError, fHalt, nCycles) { /* - * This flag is used by selected opcodes to provide an early exit if X86.OPFLAG.FAULT is set, in some cases - * making it possible for an instruction to be restarted (eg, opINSw()), and in other cases preventing a redundant - * fault from being generated. However, to prevent multiple X86.EXCEPTION.DEBUG exceptions on a single instruction, - * checkMemoryException() currently relies on its own OPFLAG.DEBUG, on the theory that we should be allowed to see - * DEBUG exceptions triggered by other exceptions. + * X86.OPFLAG.FAULT flag is used by selected opcodes to provide an early exit, restore register(s), or whatever is + * needed to help ensure instruction restartability; there is currently no mechanism for snapping and restoring all + * registers for any instruction that might fault, so it's every opcode for themselves.... + * + * X86.EXCEPTION.DEBUG exceptions set their own special flag, X86.OPFLAG.DEBUG, to prevent redundant DEBUG exceptions, + * so we don't need to set OPFLAG.FAULT in that case, because a DEBUG exception doesn't actually prevent an instruction + * from executing. */ - this.opFlags |= X86.OPFLAG.FAULT; + if (nFault == X86.EXCEPTION.DEBUG) { + this.opFlags |= X86.OPFLAG.DEBUG; + } else { + this.opFlags |= X86.OPFLAG.FAULT; + } if (!this.aFlags.fComplete) { this.printMessage("Fault " + str.toHexByte(nFault) + " blocked by PCjs", Messages.WARN);