Updated 80386 A0 and B0 stepping information
(and some minor CPU tweaks for the 80386 as well)
This commit is contained in:
parent
568c4e031e
commit
76932246ec
10 changed files with 1764 additions and 1470 deletions
|
|
@ -3044,7 +3044,7 @@ if (DEBUGGER) {
|
|||
* @this {Debugger}
|
||||
* @param {number} bReg
|
||||
* @param {number} type
|
||||
* @param {Array} aAddr (aAddr[4] is true if 32-bit operands, aAddr[5] is true if 32-bit addressing)
|
||||
* @param {Array} aAddr (aAddr[4] is true if 32-bit operands, aAddr[5] is true if 32-bit addresses)
|
||||
* @return {string} operand
|
||||
*/
|
||||
Debugger.prototype.getRegOperand = function(bReg, type, aAddr)
|
||||
|
|
@ -3077,7 +3077,7 @@ if (DEBUGGER) {
|
|||
*
|
||||
* @this {Debugger}
|
||||
* @param {number} bMod
|
||||
* @param {Array} aAddr (aAddr[4] is true if 32-bit operands, aAddr[5] is true if 32-bit addressing)
|
||||
* @param {Array} aAddr (aAddr[4] is true if 32-bit operands, aAddr[5] is true if 32-bit addresses)
|
||||
* @return {string} operand
|
||||
*/
|
||||
Debugger.prototype.getSIBOperand = function(bMod, aAddr)
|
||||
|
|
@ -3104,7 +3104,7 @@ if (DEBUGGER) {
|
|||
* @this {Debugger}
|
||||
* @param {number} bModRM
|
||||
* @param {number} type
|
||||
* @param {Array} aAddr (aAddr[4] is true if 32-bit operands, aAddr[5] is true if 32-bit addressing)
|
||||
* @param {Array} aAddr (aAddr[4] is true if 32-bit operands, aAddr[5] is true if 32-bit addresses)
|
||||
* @return {string} operand
|
||||
*/
|
||||
Debugger.prototype.getModRMOperand = function(bModRM, type, aAddr)
|
||||
|
|
|
|||
|
|
@ -50,11 +50,12 @@ var X86 = {
|
|||
* we must add checks to those functions or throw a special JavaScript exception to bypass them.
|
||||
*
|
||||
* This value is also used to indicate non-existent EA address calculations, which are usually
|
||||
* detected with "regEA < 0" and "regEAWrite < 0" tests, so be careful if you change this value.
|
||||
* If/when we ever extend our physical address space beyond 24 bits (ie, when we break the 2Gb barrier),
|
||||
* negative 32-bit values values will become valid addresses, so those tests will have to be revised.
|
||||
* detected with "regEA === ADDR_INVALID" and "regEAWrite === ADDR_INVALID" tests. In a 32-bit CPU,
|
||||
* -1 could actually be a valid address, so consider changing it to NaN or null; my concern is that,
|
||||
* by mixing non-numbers (specifically, values outside the range of 32-bit integers), performance
|
||||
* may suffer.
|
||||
*/
|
||||
ADDR_INVALID: -4,
|
||||
ADDR_INVALID: -1,
|
||||
|
||||
/*
|
||||
* Processor Status flag definitions (stored in regPS)
|
||||
|
|
|
|||
|
|
@ -3199,7 +3199,7 @@ X86CPU.prototype.stepCPU = function(nMinCycles)
|
|||
* instructions with multiple prefixes (eg, a REP and a segment override) would not be restarted
|
||||
* properly following a hardware interrupt. The recommended workarounds were to either turn off
|
||||
* interrupts or to follow the string instruction with a LOOPNZ back to the first prefix byte.
|
||||
* To emulate this flawed behavior, turn on BUGS_8086.
|
||||
* To emulate the flawed behavior, turn on BUGS_8086.
|
||||
*/
|
||||
this.opLIP = this.regLIP;
|
||||
this.segData = this.segDS;
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ X86.fnADCb = function ADCb(dst, src)
|
|||
this.resultAuxOverflow = dst ^ src;
|
||||
this.resultZeroCarry = this.resultParitySign = dst + src + ((this.resultZeroCarry & this.resultSize)? 1 : 0);
|
||||
this.resultSize = X86.RESULT.SIZE_BYTE;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
return this.resultZeroCarry & 0xff;
|
||||
};
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ X86.fnADCw = function ADCw(dst, src)
|
|||
this.resultAuxOverflow = dst ^ src;
|
||||
this.resultZeroCarry = this.resultParitySign = dst + src + ((this.resultZeroCarry & this.resultSize)? 1 : 0);
|
||||
this.resultSize = X86.RESULT.SIZE_WORD;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
return this.resultZeroCarry & 0xffff;
|
||||
};
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ X86.fnADDb = function ADDb(dst, src)
|
|||
{
|
||||
this.resultAuxOverflow = dst ^ src;
|
||||
this.resultSize = X86.RESULT.SIZE_BYTE;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
return (this.resultZeroCarry = this.resultParitySign = dst + src) & 0xff;
|
||||
};
|
||||
|
||||
|
|
@ -101,7 +101,7 @@ X86.fnADDw = function ADDw(dst, src)
|
|||
{
|
||||
this.resultAuxOverflow = dst ^ src;
|
||||
this.resultSize = X86.RESULT.SIZE_WORD;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
return (this.resultZeroCarry = this.resultParitySign = dst + src) & 0xffff;
|
||||
};
|
||||
|
||||
|
|
@ -114,7 +114,7 @@ X86.fnADDw = function ADDw(dst, src)
|
|||
X86.fnANDb = function ANDb(dst, src)
|
||||
{
|
||||
this.resultSize = X86.RESULT.SIZE_BYTE;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
return (this.resultZeroCarry = this.resultParitySign = this.resultAuxOverflow = dst & src) & 0xff;
|
||||
};
|
||||
|
||||
|
|
@ -127,7 +127,7 @@ X86.fnANDb = function ANDb(dst, src)
|
|||
X86.fnANDw = function ANDw(dst, src)
|
||||
{
|
||||
this.resultSize = X86.RESULT.SIZE_WORD;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
return (this.resultZeroCarry = this.resultParitySign = this.resultAuxOverflow = dst & src) & 0xffff;
|
||||
};
|
||||
|
||||
|
|
@ -140,7 +140,7 @@ X86.fnANDw = function ANDw(dst, src)
|
|||
X86.fnANDd = function ANDd(dst, src)
|
||||
{
|
||||
this.resultSize = X86.RESULT.SIZE_WORD;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
var dw = this.resultParitySign = this.resultAuxOverflow = (dst & src);
|
||||
this.resultZeroCarry = ((dw >>> 16) | (dw & 0xffff));
|
||||
return dw;
|
||||
|
|
@ -154,7 +154,7 @@ X86.fnANDd = function ANDd(dst, src)
|
|||
*/
|
||||
X86.fnARPL = function ARPL(dst, src)
|
||||
{
|
||||
this.nStepCycles -= (10 + (this.regEA < 0? 0 : 1));
|
||||
this.nStepCycles -= (10 + (this.regEA === X86.ADDR_INVALID? 0 : 1));
|
||||
if ((dst & X86.SEL.RPL) < (src & X86.SEL.RPL)) {
|
||||
dst = (dst & ~X86.SEL.RPL) | (src & X86.SEL.RPL);
|
||||
this.setZF();
|
||||
|
|
@ -172,7 +172,7 @@ X86.fnARPL = function ARPL(dst, src)
|
|||
*/
|
||||
X86.fnBOUND = function BOUND(dst, src)
|
||||
{
|
||||
if (this.regEA < 0) {
|
||||
if (this.regEA === X86.ADDR_INVALID) {
|
||||
/*
|
||||
* Generate UD_FAULT (INT 0x06: Invalid Opcode) if src is not a memory operand.
|
||||
*/
|
||||
|
|
@ -229,7 +229,7 @@ X86.fnCALLw = function CALLw(dst, src)
|
|||
{
|
||||
this.pushWord(this.getIP());
|
||||
this.setIP(dst);
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesCallWR : this.CYCLES.nOpCyclesCallWM);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesCallWR : this.CYCLES.nOpCyclesCallWM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
};
|
||||
|
|
@ -242,7 +242,7 @@ X86.fnCALLw = function CALLw(dst, src)
|
|||
*/
|
||||
X86.fnCALLFdw = function CALLFdw(dst, src)
|
||||
{
|
||||
if (this.regEA < 0) {
|
||||
if (this.regEA === X86.ADDR_INVALID) {
|
||||
return X86.fnGRPUndefined.call(this, dst, src);
|
||||
}
|
||||
X86.fnCALLF.call(this, dst, this.getShort(this.regEA + 2));
|
||||
|
|
@ -264,7 +264,7 @@ X86.fnCMPb = function CMPb(dst, src)
|
|||
this.resultAuxOverflow = dst ^ src;
|
||||
this.resultSize = X86.RESULT.SIZE_BYTE;
|
||||
this.resultZeroCarry = this.resultParitySign = dst - src;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesCompareRM) : this.CYCLES.nOpCyclesArithRM);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesCompareRM) : this.CYCLES.nOpCyclesArithRM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
};
|
||||
|
|
@ -280,7 +280,7 @@ X86.fnCMPw = function CMPw(dst, src)
|
|||
this.resultAuxOverflow = dst ^ src;
|
||||
this.resultSize = X86.RESULT.SIZE_WORD;
|
||||
this.resultZeroCarry = this.resultParitySign = dst - src;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesCompareRM) : this.CYCLES.nOpCyclesArithRM);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesCompareRM) : this.CYCLES.nOpCyclesArithRM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
};
|
||||
|
|
@ -297,7 +297,7 @@ X86.fnDECb = function DECb(dst, src)
|
|||
dst = (this.resultParitySign = dst - 1) & 0xff;
|
||||
this.resultZeroCarry = dst | (((this.resultZeroCarry & this.resultSize)? 1 : 0) << 8);
|
||||
this.resultSize = X86.RESULT.SIZE_BYTE;
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesIncR : this.CYCLES.nOpCyclesIncM);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesIncR : this.CYCLES.nOpCyclesIncM);
|
||||
return dst;
|
||||
};
|
||||
|
||||
|
|
@ -313,7 +313,7 @@ X86.fnDECw = function DECw(dst, src)
|
|||
dst = (this.resultParitySign = dst - 1) & 0xffff;
|
||||
this.resultZeroCarry = dst | (((this.resultZeroCarry & this.resultSize)? 1 : 0) << 16);
|
||||
this.resultSize = X86.RESULT.SIZE_WORD;
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesIncR : this.CYCLES.nOpCyclesIncM);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesIncR : this.CYCLES.nOpCyclesIncM);
|
||||
return dst;
|
||||
};
|
||||
|
||||
|
|
@ -353,7 +353,7 @@ X86.fnDIVb = function DIVb(dst, src)
|
|||
* dst unchanged). So, to make traceLog() more consistent, we reverse the order of dst and src.
|
||||
*/
|
||||
if (DEBUG && DEBUGGER) this.traceLog('DIVB', src, dst, null, this.getPS(), this.regMD16);
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesDivBR : this.CYCLES.nOpCyclesDivBM);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesDivBR : this.CYCLES.nOpCyclesDivBM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
};
|
||||
|
|
@ -400,7 +400,7 @@ X86.fnDIVw = function DIVw(dst, src)
|
|||
* dst unchanged). So, to make traceLog() more consistent, we reverse the order of dst and src.
|
||||
*/
|
||||
if (DEBUG && DEBUGGER) this.traceLog('DIVW', src, dst, null, this.getPS(), this.regMD16 | (this.regMD32 << 16));
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesDivWR : this.CYCLES.nOpCyclesDivWM);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesDivWR : this.CYCLES.nOpCyclesDivWM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
};
|
||||
|
|
@ -460,7 +460,7 @@ X86.fnIDIVb = function IDIVb(dst, src)
|
|||
* dst unchanged). So, to make traceLog() more consistent, we reverse the order of dst and src.
|
||||
*/
|
||||
if (DEBUG && DEBUGGER) this.traceLog('IDIVB', src, dst, null, this.getPS(), this.regMD16);
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesIDivBR : this.CYCLES.nOpCyclesIDivBM);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesIDivBR : this.CYCLES.nOpCyclesIDivBM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
};
|
||||
|
|
@ -512,7 +512,7 @@ X86.fnIDIVw = function IDIVw(dst, src)
|
|||
* dst unchanged). So, to make traceLog() more consistent, we reverse the order of dst and src.
|
||||
*/
|
||||
if (DEBUG && DEBUGGER) this.traceLog('IDIVW', src, dst, null, this.getPS(), this.regMD16 | (this.regMD32 << 16));
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesIDivWR : this.CYCLES.nOpCyclesIDivWM);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesIDivWR : this.CYCLES.nOpCyclesIDivWM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
};
|
||||
|
|
@ -553,7 +553,7 @@ X86.fnIMUL8 = function IMUL8(dst, src)
|
|||
* 22-25 and 29-32 instead of 21 and 24, respectively. However, accurate cycle counts for the 80186/80188 is
|
||||
* not super-critical. TODO: Fix this someday.
|
||||
*/
|
||||
this.nStepCycles -= (this.regEA < 0? 21 : 24);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 21 : 24);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
@ -593,7 +593,7 @@ X86.fnIMUL16 = function IMUL16(dst, src)
|
|||
* 22-25 and 29-32 instead of 21 and 24, respectively. However, accurate cycle counts for the 80186/80188 is
|
||||
* not super-critical. TODO: Fix this someday.
|
||||
*/
|
||||
this.nStepCycles -= (this.regEA < 0? 21 : 24);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 21 : 24);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
@ -638,7 +638,7 @@ X86.fnIMULb = function IMULb(dst, src)
|
|||
* dst unchanged). So, to make traceLog() more consistent, we reverse the order of dst and src.
|
||||
*/
|
||||
if (DEBUG && DEBUGGER) this.traceLog('IMULB', src, dst, null, this.getPS(), this.regMD16);
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesIMulBR : this.CYCLES.nOpCyclesIMulBM);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesIMulBR : this.CYCLES.nOpCyclesIMulBM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
};
|
||||
|
|
@ -685,7 +685,7 @@ X86.fnIMULw = function IMULw(dst, src)
|
|||
* dst unchanged). So, to make traceLog() more consistent, we reverse the order of dst and src.
|
||||
*/
|
||||
if (DEBUG && DEBUGGER) this.traceLog('IMULW', src, dst, null, this.getPS(), this.regMD16 | (this.regMD32 << 16));
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesIMulWR : this.CYCLES.nOpCyclesIMulWM);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesIMulWR : this.CYCLES.nOpCyclesIMulWM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
};
|
||||
|
|
@ -702,7 +702,7 @@ X86.fnINCb = function INCb(dst, src)
|
|||
dst = (this.resultParitySign = dst + 1) & 0xff;
|
||||
this.resultZeroCarry = dst | (((this.resultZeroCarry & this.resultSize)? 1 : 0) << 8);
|
||||
this.resultSize = X86.RESULT.SIZE_BYTE;
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesIncR : this.CYCLES.nOpCyclesIncM);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesIncR : this.CYCLES.nOpCyclesIncM);
|
||||
return dst;
|
||||
};
|
||||
|
||||
|
|
@ -718,7 +718,7 @@ X86.fnINCw = function INCw(dst, src)
|
|||
dst = (this.resultParitySign = dst + 1) & 0xffff;
|
||||
this.resultZeroCarry = dst | (((this.resultZeroCarry & this.resultSize)? 1 : 0) << 16);
|
||||
this.resultSize = X86.RESULT.SIZE_WORD;
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesIncR : this.CYCLES.nOpCyclesIncM);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesIncR : this.CYCLES.nOpCyclesIncM);
|
||||
return dst;
|
||||
};
|
||||
|
||||
|
|
@ -796,7 +796,7 @@ X86.fnIRET = function IRET()
|
|||
*/
|
||||
X86.fnJMPFdw = function JMPFdw(dst, src)
|
||||
{
|
||||
if (this.regEA < 0) {
|
||||
if (this.regEA === X86.ADDR_INVALID) {
|
||||
return X86.fnGRPUndefined.call(this, dst, src);
|
||||
}
|
||||
this.setCSIP(dst, this.getShort(this.regEA + 2));
|
||||
|
|
@ -815,7 +815,7 @@ X86.fnJMPFdw = function JMPFdw(dst, src)
|
|||
X86.fnJMPw = function JMPw(dst, src)
|
||||
{
|
||||
this.setIP(dst);
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesJmpWR : this.CYCLES.nOpCyclesJmpWM);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesJmpWR : this.CYCLES.nOpCyclesJmpWM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
};
|
||||
|
|
@ -828,7 +828,7 @@ X86.fnJMPw = function JMPw(dst, src)
|
|||
*/
|
||||
X86.fnLAR = function LAR(dst, src)
|
||||
{
|
||||
this.nStepCycles -= (14 + (this.regEA < 0? 0 : 2));
|
||||
this.nStepCycles -= (14 + (this.regEA === X86.ADDR_INVALID? 0 : 2));
|
||||
/*
|
||||
* Currently, segVER.load() will return an error only if the selector is beyond the bounds of the
|
||||
* descriptor table or the descriptor is not for a segment.
|
||||
|
|
@ -870,7 +870,7 @@ X86.fnLCR0 = function LCR0(l)
|
|||
*/
|
||||
X86.fnLDS = function LDS(dst, src)
|
||||
{
|
||||
if (this.regEA < 0) {
|
||||
if (this.regEA === X86.ADDR_INVALID) {
|
||||
X86.opUndefined.call(this);
|
||||
return dst;
|
||||
}
|
||||
|
|
@ -887,7 +887,7 @@ X86.fnLDS = function LDS(dst, src)
|
|||
*/
|
||||
X86.fnLEA = function LEA(dst, src)
|
||||
{
|
||||
if (this.regEA < 0) {
|
||||
if (this.regEA === X86.ADDR_INVALID) {
|
||||
/*
|
||||
* TODO: After reading http://www.os2museum.com/wp/undocumented-8086-opcodes/, it seems that this
|
||||
* form of LEA (eg, "LEA AX,DX") simply returns the last calculated EA. Since we always reset regEA
|
||||
|
|
@ -920,7 +920,7 @@ X86.fnLEA = function LEA(dst, src)
|
|||
*/
|
||||
X86.fnLGDT = function LGDT(dst, src)
|
||||
{
|
||||
if (this.regEA < 0) {
|
||||
if (this.regEA === X86.ADDR_INVALID) {
|
||||
X86.opInvalid.call(this);
|
||||
} else {
|
||||
this.addrGDT = this.getShort(this.regEA + 2) | (this.getByte(this.regEA + 4) << 16);
|
||||
|
|
@ -939,7 +939,7 @@ X86.fnLGDT = function LGDT(dst, src)
|
|||
*/
|
||||
X86.fnLES = function LES(dst, src)
|
||||
{
|
||||
if (this.regEA < 0) {
|
||||
if (this.regEA === X86.ADDR_INVALID) {
|
||||
X86.opUndefined.call(this);
|
||||
return dst;
|
||||
}
|
||||
|
|
@ -964,7 +964,7 @@ X86.fnLES = function LES(dst, src)
|
|||
*/
|
||||
X86.fnLIDT = function LIDT(dst, src)
|
||||
{
|
||||
if (this.regEA < 0) {
|
||||
if (this.regEA === X86.ADDR_INVALID) {
|
||||
X86.opInvalid.call(this);
|
||||
} else {
|
||||
this.addrIDT = this.getShort(this.regEA + 2) | (this.getByte(this.regEA + 4) << 16);
|
||||
|
|
@ -988,7 +988,7 @@ X86.fnLIDT = function LIDT(dst, src)
|
|||
X86.fnLLDT = function LLDT(dst, src) {
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
this.segLDT.load(dst);
|
||||
this.nStepCycles -= (17 + (this.regEA < 0? 0 : 2));
|
||||
this.nStepCycles -= (17 + (this.regEA === X86.ADDR_INVALID? 0 : 2));
|
||||
return dst;
|
||||
};
|
||||
|
||||
|
|
@ -1005,7 +1005,7 @@ X86.fnLLDT = function LLDT(dst, src) {
|
|||
X86.fnLMSW = function LMSW(dst, src)
|
||||
{
|
||||
this.setMSW(dst);
|
||||
this.nStepCycles -= (this.regEA < 0? 3 : 6);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 3 : 6);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
};
|
||||
|
|
@ -1021,7 +1021,7 @@ X86.fnLSL = function LSL(dst, src)
|
|||
/*
|
||||
* TODO: Is this an invalid operation if regEAWrite is set? dst is required to be a register.
|
||||
*/
|
||||
this.nStepCycles -= (14 + (this.regEA < 0? 0 : 2));
|
||||
this.nStepCycles -= (14 + (this.regEA === X86.ADDR_INVALID? 0 : 2));
|
||||
/*
|
||||
* Currently, segVER.load() will return an error only if the selector is beyond the bounds of the
|
||||
* descriptor table or the descriptor is not for a segment.
|
||||
|
|
@ -1057,7 +1057,7 @@ X86.fnLTR = function LTR(dst, src)
|
|||
this.setShort(this.segTSS.addrDesc + X86.DESC.ACC.OFFSET, this.segTSS.acc |= X86.DESC.ACC.TYPE.LDT);
|
||||
this.segTSS.type = X86.DESC.ACC.TYPE.TSS_BUSY;
|
||||
}
|
||||
this.nStepCycles -= (17 + (this.regEA < 0? 0 : 2));
|
||||
this.nStepCycles -= (17 + (this.regEA === X86.ADDR_INVALID? 0 : 2));
|
||||
return dst;
|
||||
};
|
||||
|
||||
|
|
@ -1069,7 +1069,7 @@ X86.fnLTR = function LTR(dst, src)
|
|||
*/
|
||||
X86.fnMOV = function MOV(dst, src)
|
||||
{
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesMovRR : this.CYCLES.nOpCyclesMovRM) : this.CYCLES.nOpCyclesMovMR);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesMovRR : this.CYCLES.nOpCyclesMovRM) : this.CYCLES.nOpCyclesMovMR);
|
||||
return src;
|
||||
};
|
||||
|
||||
|
|
@ -1081,7 +1081,7 @@ X86.fnMOV = function MOV(dst, src)
|
|||
*/
|
||||
X86.fnMOVImm = function MOVImm(dst, src)
|
||||
{
|
||||
this.nStepCycles -= (this.regEAWrite < 0? this.CYCLES.nOpCyclesMovRI : this.CYCLES.nOpCyclesMovMI);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? this.CYCLES.nOpCyclesMovRI : this.CYCLES.nOpCyclesMovMI);
|
||||
return src;
|
||||
};
|
||||
|
||||
|
|
@ -1123,7 +1123,7 @@ X86.fnMULb = function MULb(dst, src)
|
|||
* dst unchanged). So, to make traceLog() more consistent, we reverse the order of dst and src.
|
||||
*/
|
||||
if (DEBUG && DEBUGGER) this.traceLog('MULB', src, dst, null, this.getPS(), this.regMD16);
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesMulBR : this.CYCLES.nOpCyclesMulBM);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesMulBR : this.CYCLES.nOpCyclesMulBM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
};
|
||||
|
|
@ -1156,7 +1156,7 @@ X86.fnMULw = function MULw(dst, src)
|
|||
* dst unchanged). So, to make traceLog() more consistent, we reverse the order of dst and src.
|
||||
*/
|
||||
if (DEBUG && DEBUGGER) this.traceLog('MULW', src, dst, null, this.getPS(), this.regMD16 | (this.regMD32 << 16));
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesMulWR : this.CYCLES.nOpCyclesMulWM);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesMulWR : this.CYCLES.nOpCyclesMulWM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
};
|
||||
|
|
@ -1172,7 +1172,7 @@ X86.fnNEGb = function NEGb(dst, src)
|
|||
src = 0;
|
||||
this.resultAuxOverflow = dst ^ src;
|
||||
this.resultSize = X86.RESULT.SIZE_BYTE;
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesNegR : this.CYCLES.nOpCyclesNegM);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesNegR : this.CYCLES.nOpCyclesNegM);
|
||||
return (this.resultZeroCarry = this.resultParitySign = src - dst) & 0xff;
|
||||
};
|
||||
|
||||
|
|
@ -1187,7 +1187,7 @@ X86.fnNEGw = function NEGw(dst, src)
|
|||
src = 0;
|
||||
this.resultAuxOverflow = dst ^ src;
|
||||
this.resultSize = X86.RESULT.SIZE_WORD;
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesNegR : this.CYCLES.nOpCyclesNegM);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesNegR : this.CYCLES.nOpCyclesNegM);
|
||||
return (this.resultZeroCarry = this.resultParitySign = src - dst) & 0xffff;
|
||||
};
|
||||
|
||||
|
|
@ -1199,7 +1199,7 @@ X86.fnNEGw = function NEGw(dst, src)
|
|||
*/
|
||||
X86.fnNOTb = function NOTb(dst, src)
|
||||
{
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesNegR : this.CYCLES.nOpCyclesNegM);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesNegR : this.CYCLES.nOpCyclesNegM);
|
||||
return dst ^ 0xff;
|
||||
};
|
||||
|
||||
|
|
@ -1211,7 +1211,7 @@ X86.fnNOTb = function NOTb(dst, src)
|
|||
*/
|
||||
X86.fnNOTw = function NOTw(dst, src)
|
||||
{
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesNegR : this.CYCLES.nOpCyclesNegM);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesNegR : this.CYCLES.nOpCyclesNegM);
|
||||
return dst ^ 0xffff;
|
||||
};
|
||||
|
||||
|
|
@ -1224,7 +1224,7 @@ X86.fnNOTw = function NOTw(dst, src)
|
|||
X86.fnORb = function ORb(dst, src)
|
||||
{
|
||||
this.resultSize = X86.RESULT.SIZE_BYTE;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
return (this.resultZeroCarry = this.resultParitySign = this.resultAuxOverflow = dst | src) & 0xff;
|
||||
};
|
||||
|
||||
|
|
@ -1237,7 +1237,7 @@ X86.fnORb = function ORb(dst, src)
|
|||
X86.fnORw = function ORw(dst, src)
|
||||
{
|
||||
this.resultSize = X86.RESULT.SIZE_WORD;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
return (this.resultZeroCarry = this.resultParitySign = this.resultAuxOverflow = dst | src) & 0xffff;
|
||||
};
|
||||
|
||||
|
|
@ -1249,7 +1249,7 @@ X86.fnORw = function ORw(dst, src)
|
|||
*/
|
||||
X86.fnPOPw = function POPw(dst, src)
|
||||
{
|
||||
this.nStepCycles -= (this.regEAWrite < 0? this.CYCLES.nOpCyclesPopReg : this.CYCLES.nOpCyclesPopMem);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? this.CYCLES.nOpCyclesPopReg : this.CYCLES.nOpCyclesPopMem);
|
||||
return src;
|
||||
};
|
||||
|
||||
|
|
@ -1275,7 +1275,7 @@ X86.fnPUSHw = function PUSHw(dst, src)
|
|||
if (this.model < X86.MODEL_80286) w = dst;
|
||||
}
|
||||
this.pushWord(w);
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesPushReg : this.CYCLES.nOpCyclesPushMem);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesPushReg : this.CYCLES.nOpCyclesPushMem);
|
||||
/*
|
||||
* The PUSH is the only write that needs to occur; dst was the source operand and does not need to be rewritten.
|
||||
*/
|
||||
|
|
@ -1571,7 +1571,7 @@ X86.fnSBBb = function SBBb(dst, src)
|
|||
this.resultAuxOverflow = dst ^ src;
|
||||
this.resultZeroCarry = this.resultParitySign = dst - src - ((this.resultZeroCarry & this.resultSize)? 1 : 0);
|
||||
this.resultSize = X86.RESULT.SIZE_BYTE;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
return this.resultZeroCarry & 0xff;
|
||||
};
|
||||
|
||||
|
|
@ -1589,7 +1589,7 @@ X86.fnSBBw = function SBBw(dst, src)
|
|||
this.resultAuxOverflow = dst ^ src;
|
||||
this.resultZeroCarry = this.resultParitySign = dst - src - ((this.resultZeroCarry & this.resultSize)? 1 : 0);
|
||||
this.resultSize = X86.RESULT.SIZE_WORD;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
return this.resultZeroCarry & 0xffff;
|
||||
};
|
||||
|
||||
|
|
@ -1605,7 +1605,7 @@ X86.fnSBBw = function SBBw(dst, src)
|
|||
*/
|
||||
X86.fnSGDT = function SGDT(dst, src)
|
||||
{
|
||||
if (this.regEA < 0) {
|
||||
if (this.regEA === X86.ADDR_INVALID) {
|
||||
X86.opInvalid.call(this);
|
||||
} else {
|
||||
/*
|
||||
|
|
@ -1779,7 +1779,7 @@ X86.fnSHRw = function SHRw(dst, src)
|
|||
*/
|
||||
X86.fnSIDT = function SIDT(dst, src)
|
||||
{
|
||||
if (this.regEA < 0) {
|
||||
if (this.regEA === X86.ADDR_INVALID) {
|
||||
X86.opInvalid.call(this);
|
||||
} else {
|
||||
/*
|
||||
|
|
@ -1812,7 +1812,7 @@ X86.fnSIDT = function SIDT(dst, src)
|
|||
*/
|
||||
X86.fnSLDT = function SLDT(dst, src)
|
||||
{
|
||||
this.nStepCycles -= (2 + (this.regEA < 0? 0 : 1));
|
||||
this.nStepCycles -= (2 + (this.regEA === X86.ADDR_INVALID? 0 : 1));
|
||||
return this.segLDT.sel;
|
||||
};
|
||||
|
||||
|
|
@ -1828,7 +1828,7 @@ X86.fnSLDT = function SLDT(dst, src)
|
|||
*/
|
||||
X86.fnSMSW = function SMSW(dst, src)
|
||||
{
|
||||
this.nStepCycles -= (2 + (this.regEA < 0? 0 : 1));
|
||||
this.nStepCycles -= (2 + (this.regEA === X86.ADDR_INVALID? 0 : 1));
|
||||
return this.regCR0;
|
||||
};
|
||||
|
||||
|
|
@ -1844,7 +1844,7 @@ X86.fnSMSW = function SMSW(dst, src)
|
|||
*/
|
||||
X86.fnSTR = function STR(dst, src)
|
||||
{
|
||||
this.nStepCycles -= (2 + (this.regEA < 0? 0 : 1));
|
||||
this.nStepCycles -= (2 + (this.regEA === X86.ADDR_INVALID? 0 : 1));
|
||||
return this.segTSS.sel;
|
||||
};
|
||||
|
||||
|
|
@ -1858,7 +1858,7 @@ X86.fnSUBb = function SUBb(dst, src)
|
|||
{
|
||||
this.resultAuxOverflow = dst ^ src;
|
||||
this.resultSize = X86.RESULT.SIZE_BYTE;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
return (this.resultZeroCarry = this.resultParitySign = dst - src) & 0xff;
|
||||
};
|
||||
|
||||
|
|
@ -1872,7 +1872,7 @@ X86.fnSUBw = function SUBw(dst, src)
|
|||
{
|
||||
this.resultAuxOverflow = dst ^ src;
|
||||
this.resultSize = X86.RESULT.SIZE_WORD;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
return (this.resultZeroCarry = this.resultParitySign = dst - src) & 0xffff;
|
||||
};
|
||||
|
||||
|
|
@ -1887,7 +1887,7 @@ X86.fnTEST8 = function TEST8(dst, src)
|
|||
src = this.getIPByte();
|
||||
this.resultZeroCarry = this.resultParitySign = this.resultAuxOverflow = dst & src;
|
||||
this.resultSize = X86.RESULT.SIZE_BYTE;
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesTestRI : this.CYCLES.nOpCyclesTestMI);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesTestRI : this.CYCLES.nOpCyclesTestMI);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
};
|
||||
|
|
@ -1903,7 +1903,7 @@ X86.fnTEST16 = function TEST16(dst, src)
|
|||
src = this.getIPWord();
|
||||
this.resultZeroCarry = this.resultParitySign = this.resultAuxOverflow = dst & src;
|
||||
this.resultSize = X86.RESULT.SIZE_WORD;
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesTestRI : this.CYCLES.nOpCyclesTestMI);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesTestRI : this.CYCLES.nOpCyclesTestMI);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
};
|
||||
|
|
@ -1918,7 +1918,7 @@ X86.fnTESTb = function TESTb(dst, src)
|
|||
{
|
||||
this.resultZeroCarry = this.resultParitySign = this.resultAuxOverflow = dst & src;
|
||||
this.resultSize = X86.RESULT.SIZE_BYTE;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesTestRR : this.CYCLES.nOpCyclesTestRM) : this.CYCLES.nOpCyclesTestRM);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesTestRR : this.CYCLES.nOpCyclesTestRM) : this.CYCLES.nOpCyclesTestRM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
};
|
||||
|
|
@ -1933,7 +1933,7 @@ X86.fnTESTw = function TESTw(dst, src)
|
|||
{
|
||||
this.resultZeroCarry = this.resultParitySign = this.resultAuxOverflow = dst & src;
|
||||
this.resultSize = X86.RESULT.SIZE_WORD;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesTestRR : this.CYCLES.nOpCyclesTestRM) : this.CYCLES.nOpCyclesTestRM);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesTestRR : this.CYCLES.nOpCyclesTestRM) : this.CYCLES.nOpCyclesTestRM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
};
|
||||
|
|
@ -1955,7 +1955,7 @@ X86.fnVERR = function VERR(dst, src)
|
|||
* Currently, segVER.load() will return an error only if the selector is beyond the bounds of the
|
||||
* descriptor table or the descriptor is not for a segment.
|
||||
*/
|
||||
this.nStepCycles -= (14 + (this.regEA < 0? 0 : 2));
|
||||
this.nStepCycles -= (14 + (this.regEA === X86.ADDR_INVALID? 0 : 2));
|
||||
if (this.segVER.load(dst, true) != X86.ADDR_INVALID) {
|
||||
/*
|
||||
* Verify that this is a readable segment; that is, of these four combinations (code+readable,
|
||||
|
|
@ -1997,7 +1997,7 @@ X86.fnVERW = function VERW(dst, src)
|
|||
* Currently, segVER.load() will return an error only if the selector is beyond the bounds of the
|
||||
* descriptor table or the descriptor is not for a segment.
|
||||
*/
|
||||
this.nStepCycles -= (14 + (this.regEA < 0? 0 : 2));
|
||||
this.nStepCycles -= (14 + (this.regEA === X86.ADDR_INVALID? 0 : 2));
|
||||
if (this.segVER.load(dst, true) != X86.ADDR_INVALID) {
|
||||
/*
|
||||
* Verify that this is a writable data segment
|
||||
|
|
@ -2043,7 +2043,7 @@ X86.fnVERW = function VERW(dst, src)
|
|||
*/
|
||||
X86.fnXCHGrb = function XCHGRb(dst, src)
|
||||
{
|
||||
if (this.regEA < 0) {
|
||||
if (this.regEA === X86.ADDR_INVALID) {
|
||||
/*
|
||||
* Decode which register was src
|
||||
*/
|
||||
|
|
@ -2107,7 +2107,7 @@ X86.fnXCHGrb = function XCHGRb(dst, src)
|
|||
*/
|
||||
X86.fnXCHGrw = function XCHGRw(dst, src)
|
||||
{
|
||||
if (this.regEA < 0) {
|
||||
if (this.regEA === X86.ADDR_INVALID) {
|
||||
/*
|
||||
* Decode which register was src
|
||||
*/
|
||||
|
|
@ -2162,7 +2162,7 @@ X86.fnXCHGrw = function XCHGRw(dst, src)
|
|||
X86.fnXORb = function XORb(dst, src)
|
||||
{
|
||||
this.resultSize = X86.RESULT.SIZE_BYTE;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
return (this.resultZeroCarry = this.resultParitySign = this.resultAuxOverflow = dst ^ src) & 0xff;
|
||||
};
|
||||
|
||||
|
|
@ -2175,7 +2175,7 @@ X86.fnXORb = function XORb(dst, src)
|
|||
X86.fnXORw = function XORw(dst, src)
|
||||
{
|
||||
this.resultSize = X86.RESULT.SIZE_WORD;
|
||||
this.nStepCycles -= (this.regEAWrite < 0? (this.regEA < 0? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesArithRR : this.CYCLES.nOpCyclesArithRM) : this.CYCLES.nOpCyclesArithMR);
|
||||
return (this.resultZeroCarry = this.resultParitySign = this.resultAuxOverflow = dst ^ src) & 0xffff;
|
||||
};
|
||||
|
||||
|
|
@ -2210,7 +2210,7 @@ X86.fnRotateFlags = function(result, size)
|
|||
* @return {number}
|
||||
*/
|
||||
X86.fnGRPCount1 = function() {
|
||||
this.nStepCycles -= (this.regEA < 0? 2 : this.CYCLES.nOpCyclesShift1M);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? 2 : this.CYCLES.nOpCyclesShift1M);
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
|
@ -2220,7 +2220,7 @@ X86.fnGRPCount1 = function() {
|
|||
*/
|
||||
X86.fnGRPCountCL = function() {
|
||||
var count = this.regECX & this.nShiftCountMask;
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesShiftCR : this.CYCLES.nOpCyclesShiftCM) + (count << this.CYCLES.nOpCyclesShiftCS);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesShiftCR : this.CYCLES.nOpCyclesShiftCM) + (count << this.CYCLES.nOpCyclesShiftCS);
|
||||
return count;
|
||||
};
|
||||
|
||||
|
|
@ -2230,7 +2230,7 @@ X86.fnGRPCountCL = function() {
|
|||
*/
|
||||
X86.fnGRPCountImm = function() {
|
||||
var count = this.getIPByte();
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesShiftCR : this.CYCLES.nOpCyclesShiftCM) + (count << this.CYCLES.nOpCyclesShiftCS);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.CYCLES.nOpCyclesShiftCR : this.CYCLES.nOpCyclesShiftCM) + (count << this.CYCLES.nOpCyclesShiftCS);
|
||||
return count;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -47,10 +47,13 @@ X86.opADDmb = function ADDmb()
|
|||
{
|
||||
var b = this.getIPByte();
|
||||
/*
|
||||
* Opcode bytes 0x00 0x00 are sufficiently uncommon that it's more likely we've started executing
|
||||
* in the weeds, so we'll stop the CPU if we're in DEBUG mode.
|
||||
* Opcode bytes 0x00 0x00 are sufficiently uncommon that it's more likely we've started
|
||||
* executing in the weeds, so we'll print a warning if Messages.CPU is enabled (at which
|
||||
* point you can also choose to halt if Messages.HALT is enabled).
|
||||
*/
|
||||
if (DEBUG && DEBUGGER && !b) this.stopCPU();
|
||||
if (DEBUG && !b) {
|
||||
this.printMessage("suspicious opcode: 0x00 0x00");
|
||||
}
|
||||
this.aOpModMemByte[b].call(this, X86.fnADDb);
|
||||
};
|
||||
|
||||
|
|
@ -2133,7 +2136,7 @@ X86.opJNLE = function JNLE()
|
|||
X86.opGrp1b = function GRP1b()
|
||||
{
|
||||
this.aOpModGrpByte[this.getIPByte()].call(this, X86.aOpGrp1b, this.getIPByte);
|
||||
this.nStepCycles -= (this.regEAWrite < 0? 1 : this.CYCLES.nOpCyclesArithMID);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? 1 : this.CYCLES.nOpCyclesArithMID);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2144,7 +2147,7 @@ X86.opGrp1b = function GRP1b()
|
|||
X86.opGrp1w = function GRP1w()
|
||||
{
|
||||
this.aOpModGrpWord[this.getIPByte()].call(this, X86.aOpGrp1w, this.getIPWord);
|
||||
this.nStepCycles -= (this.regEAWrite < 0? 1 : this.CYCLES.nOpCyclesArithMID);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? 1 : this.CYCLES.nOpCyclesArithMID);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2155,7 +2158,7 @@ X86.opGrp1w = function GRP1w()
|
|||
X86.opGrp1sw = function GRP1sw()
|
||||
{
|
||||
this.aOpModGrpWord[this.getIPByte()].call(this, X86.aOpGrp1w, this.getIPDisp);
|
||||
this.nStepCycles -= (this.regEAWrite < 0? 1 : this.CYCLES.nOpCyclesArithMID);
|
||||
this.nStepCycles -= (this.regEAWrite === X86.ADDR_INVALID? 1 : this.CYCLES.nOpCyclesArithMID);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2627,7 +2630,7 @@ X86.opCALLF = function CALLF()
|
|||
*/
|
||||
X86.opWAIT = function WAIT()
|
||||
{
|
||||
this.printMessage("WAIT not implemented", Messages.CPU);
|
||||
this.printMessage("WAIT not implemented");
|
||||
this.nStepCycles--;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue