From 7babb1586802765a0cf2902839d9ddc62aeeda9a Mon Sep 17 00:00:00 2001 From: Jeff Parsons Date: Tue, 20 Oct 2015 19:23:45 -0700 Subject: [PATCH] Fixed WDEB386 fielding of V86-mode exceptions --- modules/pcjs/lib/debugger.js | 4 ++++ modules/pcjs/lib/x86func.js | 24 ++++++++++++++---------- modules/pcjs/lib/x86seg.js | 16 ++++++++++++++++ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/modules/pcjs/lib/debugger.js b/modules/pcjs/lib/debugger.js index 6052f7177..72829d664 100644 --- a/modules/pcjs/lib/debugger.js +++ b/modules/pcjs/lib/debugger.js @@ -4572,10 +4572,14 @@ if (DEBUGGER) { var sOpcode = Debugger.INS_NAMES[aOpDesc[0]]; var cOperands = aOpDesc.length - 1; var sOperands = ""; + if (this.isStringIns(bOpcode)) { cOperands = 0; // suppress display of operands for string instructions if (dbgAddr.fData32 && sOpcode.slice(-1) == 'W') sOpcode = sOpcode.slice(0, -1) + 'D'; } + /* + * TODO: We need a similar fixup for POPF and POPA when OPERAND size is 4 (to make them POPFD and POPAD) + */ var typeCPU = null; var fComplete = true; diff --git a/modules/pcjs/lib/x86func.js b/modules/pcjs/lib/x86func.js index 348682074..11f30b644 100644 --- a/modules/pcjs/lib/x86func.js +++ b/modules/pcjs/lib/x86func.js @@ -1506,19 +1506,23 @@ X86.fnIRET = function() } else { if (newPS & X86.PS.VM) { - this.assert(!!(this.regCR0 & X86.CR0.MSW.PE)); + /* + * As noted in loadDesc8(), where the V86-mode frame we're about to pop was originally pushed, + * these frames ALWAYS contain 32-bit values, so make sure that sizeData reflects that. + */ + this.assert(!!(this.regCR0 & X86.CR0.MSW.PE) && this.sizeData == 4); /* * We have to assume that a full V86-mode interrupt frame was on the protected-mode stack; namely: * - * GS - * FS - * DS - * ES - * SS - * ESP - * EFLAGS - * CS - * EIP + * low: EIP + * CS (padded to 32 bits) + * EFLAGS + * ESP + * SS (padded to 32 bits) + * ES (padded to 32 bits) + * DS (padded to 32 bits) + * FS (padded to 32 bits) + * high: GS (padded to 32 bits) * * We've already popped EIP, CS, and EFLAGS into newIP, newCS and newPS, respectively, so we must now * pop the rest, while we're still in protected-mode, before the switch to V86-mode alters the current diff --git a/modules/pcjs/lib/x86seg.js b/modules/pcjs/lib/x86seg.js index df98dc14d..c7ba8cb22 100644 --- a/modules/pcjs/lib/x86seg.js +++ b/modules/pcjs/lib/x86seg.js @@ -887,6 +887,22 @@ X86Seg.prototype.loadDesc8 = function(addrDesc, sel, fProbe) cpu.resetSizes(); if (regPS & X86.PS.VM) { + /* + * Frames coming from V86-mode ALWAYS contain 32-bit values, and look like this: + * + * low: EIP + * CS (padded to 32 bits) + * EFLAGS + * ESP + * SS (padded to 32 bits) + * ES (padded to 32 bits) + * DS (padded to 32 bits) + * FS (padded to 32 bits) + * high: GS (padded to 32 bits) + * + * Our caller (eg, fnINT()) will take care of pushing the final bits (EFLAGS, CS, and EIP). + */ + cpu.setDataSize(this.sizeFrame = 4); cpu.assert(I386 && cpu.model >= X86.MODEL_80386); cpu.pushWord(cpu.segGS.sel); cpu.setGS(0);