diff --git a/modules/pcjs/lib/x86.js b/modules/pcjs/lib/x86.js index 48f74a9a9..04ebc3265 100644 --- a/modules/pcjs/lib/x86.js +++ b/modules/pcjs/lib/x86.js @@ -407,21 +407,23 @@ X86.BACKTRACK = { }; /* - * Some PS flags are always stored directly in regPS, hence the "direct" designation. + * These PS flags are always stored directly in regPS for the 8086/8088, hence the + * "direct" designation; other processors must adjust these bits accordingly. The final + * adjusted value is stored in PS_DIRECT. */ -X86.PS.DIRECT = (X86.PS.TF | X86.PS.IF | X86.PS.DF); - -/* - * However, PS arithmetic and logical flags may be "cached" across several result registers. - */ -X86.PS.CACHED = (X86.PS.CF | X86.PS.PF | X86.PS.AF | X86.PS.ZF | X86.PS.SF | X86.PS.OF); +X86.PS.DIRECT_8086 = (X86.PS.TF | X86.PS.IF | X86.PS.DF); /* * These are the default "always set" PS bits for the 8086/8088; other processors must - * adjust these bits accordingly. The final adjusted value is then stored in the X86CPU - * object as PS_SET; setPS() must use PS_SET, *not* PS.SET. + * adjust these bits accordingly. The final adjusted value is stored in PS_SET. */ -X86.PS.SET = (X86.PS.BIT1 | X86.PS.IOPL.MASK | X86.PS.NT | X86.PS.BIT15); +X86.PS.SET_8086 = (X86.PS.BIT1 | X86.PS.IOPL.MASK | X86.PS.NT | X86.PS.BIT15); + +/* + * These PS arithmetic and logical flags may be "cached" across several result registers; + * whether or not they're currently cached depends on the RESULT bits in resultType. + */ +X86.PS.CACHED = (X86.PS.CF | X86.PS.PF | X86.PS.AF | X86.PS.ZF | X86.PS.SF | X86.PS.OF); /* * PS.SAHF is a subset of the arithmetic flags, and refers only to those flags that the diff --git a/modules/pcjs/lib/x86cpu.js b/modules/pcjs/lib/x86cpu.js index b667d80af..71b67fedd 100644 --- a/modules/pcjs/lib/x86cpu.js +++ b/modules/pcjs/lib/x86cpu.js @@ -694,10 +694,10 @@ X86CPU.prototype.setAddressMask = function(busMask) */ X86CPU.prototype.initProcessor = function() { - this.PS_SET = X86.PS.SET; - this.PS_DIRECT = X86.PS.DIRECT; + this.PS_SET = X86.PS.SET_8086; + this.PS_DIRECT = X86.PS.DIRECT_8086; - this.OPFLAG_NOINTR8086 = X86.OPFLAG.NOINTR; + this.OPFLAG_NOINTR_8086 = X86.OPFLAG.NOINTR; this.nShiftCountMask = 0xff; // on an 8086/8088, all shift counts are used as-is /* @@ -753,7 +753,7 @@ X86CPU.prototype.initProcessor = function() this.PS_SET = X86.PS.BIT1; // on the 80286, only BIT1 of Processor Status (flags) is always set this.PS_DIRECT |= X86.PS.IOPL.MASK | X86.PS.NT; - this.OPFLAG_NOINTR8086 = 0; // used with instructions that should *not* set NOINTR on an 80286 (eg, non-SS segment loads) + this.OPFLAG_NOINTR_8086 = 0; // used with instructions that should *not* set NOINTR on an 80286 (eg, non-SS segment loads) this.aOps0F = X86.aOps0F; this.aOps[0x0F] = X86.op0F; @@ -1460,7 +1460,7 @@ X86CPU.prototype.setCS = function(sel) this.regLIP = this.segCS.load(sel) + regEIP; this.regLIPLimit = this.segCS.base + this.segCS.limit; if (I386) this.resetSizes(); - if (!BUGS_8086) this.opFlags |= this.OPFLAG_NOINTR8086; + if (!BUGS_8086) this.opFlags |= this.OPFLAG_NOINTR_8086; if (PREFETCH) this.flushPrefetch(this.regLIP); }; @@ -1484,7 +1484,7 @@ X86CPU.prototype.getDS = function() X86CPU.prototype.setDS = function(sel) { this.segDS.load(sel); - if (!BUGS_8086) this.opFlags |= this.OPFLAG_NOINTR8086; + if (!BUGS_8086) this.opFlags |= this.OPFLAG_NOINTR_8086; }; /** @@ -1539,7 +1539,7 @@ X86CPU.prototype.getES = function() X86CPU.prototype.setES = function(sel) { this.segES.load(sel); - if (!BUGS_8086) this.opFlags |= this.OPFLAG_NOINTR8086; + if (!BUGS_8086) this.opFlags |= this.OPFLAG_NOINTR_8086; }; /** diff --git a/modules/pcjs/lib/x86func.js b/modules/pcjs/lib/x86func.js index 1bea121b3..8d8419906 100644 --- a/modules/pcjs/lib/x86func.js +++ b/modules/pcjs/lib/x86func.js @@ -742,8 +742,8 @@ X86.fnINCw = function INCw(dst, src) * only knows how to load GDT and LDT descriptors, whereas interrupts must use setCS.loadIDT(), which * deals exclusively with IDT descriptors. * - * This means we must take care to replicate critical features of setCSIP(); eg, setting segCS.fCall before - * calling loadIDT(), updating LIP, and flushing the prefetch queue. + * This means we must take care to replicate critical features of setCSIP(); eg, setting segCS.fCall + * before calling loadIDT(), updating LIP, and flushing the prefetch queue. * * @this {X86CPU} * @param {number} nIDT @@ -2371,55 +2371,6 @@ X86.setRotateResult = function(result, carry, size) if ((result ^ carry) & size) this.setOF(); else this.clearOF(); }; -/** - * fnGRPCount1() - * - * @this {X86CPU} - * @return {number} - */ -X86.fnGRPCount1 = function() -{ - this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 2 : this.CYCLES.nOpCyclesShift1M); - return 1; -}; - -/** - * fnGRPCountCL() - * - * @this {X86CPU} - * @return {number} - */ -X86.fnGRPCountCL = function() -{ - var count = this.regECX & 0xff; - this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesShiftCR : this.CYCLES.nOpCyclesShiftCM) + (count << this.CYCLES.nOpCyclesShiftCS); - return count; -}; - -/** - * fnGRPCountImm() - * - * @this {X86CPU} - * @return {number} - */ -X86.fnGRPCountImm = function() -{ - var count = this.getIPByte(); - this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesShiftCR : this.CYCLES.nOpCyclesShiftCM) + (count << this.CYCLES.nOpCyclesShiftCS); - return count; -}; - -/** - * fnGRPSrcNone() - * - * @this {X86CPU} - * @return {number|null} - */ -X86.fnGRPSrcNone = function() -{ - return null; -}; - /** * fnGRPFault(dst, src) * @@ -2428,7 +2379,7 @@ X86.fnGRPSrcNone = function() * @param {number} src * @return {number} */ -X86.fnGRPFault = function(dst, src) +X86.fnGRPFault = function GRPFault(dst, src) { X86.fnFault.call(this, X86.EXCEPTION.GP_FAULT, 0); return dst; @@ -2442,7 +2393,7 @@ X86.fnGRPFault = function(dst, src) * @param {number} src * @return {number} */ -X86.fnGRPInvalid = function(dst, src) +X86.fnGRPInvalid = function GRPInvalid(dst, src) { X86.opInvalid.call(this); return dst; @@ -2456,7 +2407,7 @@ X86.fnGRPInvalid = function(dst, src) * @param {number} src * @return {number} */ -X86.fnGRPUndefined = function(dst, src) +X86.fnGRPUndefined = function GRPUndefined(dst, src) { X86.opUndefined.call(this); return dst; @@ -2467,7 +2418,7 @@ X86.fnGRPUndefined = function(dst, src) * * @this {X86CPU} */ -X86.fnDIVOverflow = function() +X86.fnDIVOverflow = function DIVOverflow() { this.setIP(this.opLIP - this.segCS.base); /* @@ -2476,6 +2427,55 @@ X86.fnDIVOverflow = function() X86.fnINT.call(this, X86.EXCEPTION.DIV_ERR, null, 2); }; +/** + * fnSrcCount1() + * + * @this {X86CPU} + * @return {number} + */ +X86.fnSrcCount1 = function SrcCount1() +{ + this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 2 : this.CYCLES.nOpCyclesShift1M); + return 1; +}; + +/** + * fnSrcCountCL() + * + * @this {X86CPU} + * @return {number} + */ +X86.fnSrcCountCL = function SrcCountCL() +{ + var count = this.regECX & 0xff; + this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesShiftCR : this.CYCLES.nOpCyclesShiftCM) + (count << this.CYCLES.nOpCyclesShiftCS); + return count; +}; + +/** + * fnSrcCountImm() + * + * @this {X86CPU} + * @return {number} + */ +X86.fnSrcCountImm = function SrcCountImm() +{ + var count = this.getIPByte(); + this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesShiftCR : this.CYCLES.nOpCyclesShiftCM) + (count << this.CYCLES.nOpCyclesShiftCS); + return count; +}; + +/** + * fnSrcNone() + * + * @this {X86CPU} + * @return {number|null} + */ +X86.fnSrcNone = function SrcNone() +{ + return null; +}; + /** * fnFault(nFault, nError, fHalt) * diff --git a/modules/pcjs/lib/x86op0f.js b/modules/pcjs/lib/x86op0f.js index 26589c733..9fbf1f82b 100644 --- a/modules/pcjs/lib/x86op0f.js +++ b/modules/pcjs/lib/x86op0f.js @@ -47,7 +47,7 @@ X86.opGrp6 = function GRP6() if ((bModRM & 0x38) < 0x10) { // possible reg values: 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38 this.opFlags |= X86.OPFLAG.NOREAD; } - this.aOpModGrpWord[bModRM].call(this, this.aOpGrp6, X86.fnGRPSrcNone); + this.aOpModGrpWord[bModRM].call(this, this.aOpGrp6, X86.fnSrcNone); }; /** @@ -61,7 +61,7 @@ X86.opGrp7 = function GRP7() if (!(bModRM & 0x10)) { this.opFlags |= X86.OPFLAG.NOREAD; } - this.aOpModGrpWord[bModRM].call(this, X86.aOpGrp7, X86.fnGRPSrcNone); + this.aOpModGrpWord[bModRM].call(this, X86.aOpGrp7, X86.fnSrcNone); }; /** diff --git a/modules/pcjs/lib/x86opxx.js b/modules/pcjs/lib/x86opxx.js index c93b9640c..7ec7508cb 100644 --- a/modules/pcjs/lib/x86opxx.js +++ b/modules/pcjs/lib/x86opxx.js @@ -1168,7 +1168,7 @@ X86.opPUSHBX = function PUSHBX() * * @this {X86CPU} */ -X86.opPUSHSP8086 = function PUSHSP8086() +X86.opPUSHSP_8086 = function PUSHSP_8086() { var w = (this.getSP() - this.dataSize) & this.dataMask; this.pushWord(w); @@ -1667,7 +1667,7 @@ X86.opINSw = function INSw() * * @this {X86CPU} */ -X86.opOUTSb = function() +X86.opOUTSb = function OUTSb() { var nReps = 1; var nDelta = 0; @@ -3268,7 +3268,7 @@ X86.opMOVDIw = function MOVDIw() */ X86.opGrp2bi = function GRP2bi() { - this.aOpModGrpByte[this.getIPByte()].call(this, X86.aOpGrp2b, X86.fnGRPCountImm); + this.aOpModGrpByte[this.getIPByte()].call(this, X86.aOpGrp2b, X86.fnSrcCountImm); }; /** @@ -3278,7 +3278,7 @@ X86.opGrp2bi = function GRP2bi() */ X86.opGrp2wi = function GRP2wi() { - this.aOpModGrpWord[this.getIPByte()].call(this, X86.aOpGrp2w, X86.fnGRPCountImm); + this.aOpModGrpWord[this.getIPByte()].call(this, X86.aOpGrp2w, X86.fnSrcCountImm); }; /** @@ -3288,7 +3288,7 @@ X86.opGrp2wi = function GRP2wi() */ X86.opGrp2di = function GRP2di() { - this.aOpModGrpWord[this.getIPByte()].call(this, X86.aOpGrp2d, X86.fnGRPCountImm); + this.aOpModGrpWord[this.getIPByte()].call(this, X86.aOpGrp2d, X86.fnSrcCountImm); }; /** @@ -3511,7 +3511,7 @@ X86.opIRET = function IRET() */ X86.opGrp2b1 = function GRP2b1() { - this.aOpModGrpByte[this.getIPByte()].call(this, X86.aOpGrp2b, X86.fnGRPCount1); + this.aOpModGrpByte[this.getIPByte()].call(this, X86.aOpGrp2b, X86.fnSrcCount1); }; /** @@ -3521,7 +3521,7 @@ X86.opGrp2b1 = function GRP2b1() */ X86.opGrp2w1 = function GRP2w1() { - this.aOpModGrpWord[this.getIPByte()].call(this, X86.aOpGrp2w, X86.fnGRPCount1); + this.aOpModGrpWord[this.getIPByte()].call(this, X86.aOpGrp2w, X86.fnSrcCount1); }; /** @@ -3531,7 +3531,7 @@ X86.opGrp2w1 = function GRP2w1() */ X86.opGrp2d1 = function GRP2d1() { - this.aOpModGrpWord[this.getIPByte()].call(this, X86.aOpGrp2d, X86.fnGRPCount1); + this.aOpModGrpWord[this.getIPByte()].call(this, X86.aOpGrp2d, X86.fnSrcCount1); }; /** @@ -3541,7 +3541,7 @@ X86.opGrp2d1 = function GRP2d1() */ X86.opGrp2bCL = function GRP2bCL() { - this.aOpModGrpByte[this.getIPByte()].call(this, X86.aOpGrp2b, X86.fnGRPCountCL); + this.aOpModGrpByte[this.getIPByte()].call(this, X86.aOpGrp2b, X86.fnSrcCountCL); }; /** @@ -3551,7 +3551,7 @@ X86.opGrp2bCL = function GRP2bCL() */ X86.opGrp2wCL = function GRP2wCL() { - this.aOpModGrpWord[this.getIPByte()].call(this, X86.aOpGrp2w, X86.fnGRPCountCL); + this.aOpModGrpWord[this.getIPByte()].call(this, X86.aOpGrp2w, X86.fnSrcCountCL); }; /** @@ -3561,7 +3561,7 @@ X86.opGrp2wCL = function GRP2wCL() */ X86.opGrp2dCL = function GRP2dCL() { - this.aOpModGrpWord[this.getIPByte()].call(this, X86.aOpGrp2d, X86.fnGRPCountCL); + this.aOpModGrpWord[this.getIPByte()].call(this, X86.aOpGrp2d, X86.fnSrcCountCL); }; /** @@ -3998,7 +3998,7 @@ X86.opCMC = function CMC() X86.opGrp3b = function GRP3b() { this.regMD16 = -1; - this.aOpModGrpByte[this.getIPByte()].call(this, X86.aOpGrp3b, X86.fnGRPSrcNone); + this.aOpModGrpByte[this.getIPByte()].call(this, X86.aOpGrp3b, X86.fnSrcNone); if (this.regMD16 >= 0) this.regEAX = this.regMD16; }; @@ -4024,7 +4024,7 @@ X86.opGrp3b = function GRP3b() X86.opGrp3w = function GRP3w() { this.regMD16 = -1; - this.aOpModGrpWord[this.getIPByte()].call(this, X86.aOpGrp3w, X86.fnGRPSrcNone); + this.aOpModGrpWord[this.getIPByte()].call(this, X86.aOpGrp3w, X86.fnSrcNone); if (this.regMD16 >= 0) { this.regEAX = this.regMD16; this.regEDX = this.regMD32; @@ -4105,7 +4105,7 @@ X86.opSTD = function STD() */ X86.opGrp4b = function GRP4b() { - this.aOpModGrpByte[this.getIPByte()].call(this, X86.aOpGrp4b, X86.fnGRPSrcNone); + this.aOpModGrpByte[this.getIPByte()].call(this, X86.aOpGrp4b, X86.fnSrcNone); }; /** @@ -4115,7 +4115,7 @@ X86.opGrp4b = function GRP4b() */ X86.opGrp4w = function GRP4w() { - this.aOpModGrpWord[this.getIPByte()].call(this, X86.aOpGrp4w, X86.fnGRPSrcNone); + this.aOpModGrpWord[this.getIPByte()].call(this, X86.aOpGrp4w, X86.fnSrcNone); }; /** @@ -4181,7 +4181,7 @@ X86.aOps = [ X86.opDECAX, X86.opDECCX, X86.opDECDX, X86.opDECBX, // 0x48-0x4B X86.opDECSP, X86.opDECBP, X86.opDECSI, X86.opDECDI, // 0x4C-0x4F X86.opPUSHAX, X86.opPUSHCX, X86.opPUSHDX, X86.opPUSHBX, // 0x50-0x53 - X86.opPUSHSP8086, X86.opPUSHBP, X86.opPUSHSI, X86.opPUSHDI, // 0x54-0x57 + X86.opPUSHSP_8086, X86.opPUSHBP, X86.opPUSHSI, X86.opPUSHDI, // 0x54-0x57 X86.opPOPAX, X86.opPOPCX, X86.opPOPDX, X86.opPOPBX, // 0x58-0x5B X86.opPOPSP, X86.opPOPBP, X86.opPOPSI, X86.opPOPDI, // 0x5C-0x5F /*