80386 0x0F opcodes more or less fleshed out
This commit is contained in:
parent
f9cb8a5bec
commit
177032223c
4 changed files with 452 additions and 15 deletions
|
|
@ -204,6 +204,76 @@ X86.fnBOUND = function BOUND(dst, src)
|
|||
return dst;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnBSF(dst, src)
|
||||
*
|
||||
* Scan src starting at bit 0. If a set bit is found, the bit index is stored in dst and ZF is cleared;
|
||||
* otherwise, ZF is set and dst is unchanged.
|
||||
*
|
||||
* NOTES: Early versions of the 80386 manuals misstated how ZF was set/cleared. Also, Intel insists that
|
||||
* dst is undefined whenever ZF is set, but in fact, the 80386 leaves dst unchanged when that happens;
|
||||
* unfortunately, some early 80486s would always modify dst, so it is unsafe to rely on dst when ZF is set.
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} dst
|
||||
* @param {number} src
|
||||
* @return {number}
|
||||
*/
|
||||
X86.fnBSF = function BSF(dst, src)
|
||||
{
|
||||
if (!src) {
|
||||
this.setZF();
|
||||
} else {
|
||||
this.clearZF();
|
||||
var i = 0, bit = 0x1;
|
||||
while (bit & this.dataMask) {
|
||||
if (src & bit) {
|
||||
dst = i;
|
||||
break;
|
||||
}
|
||||
bit <<= 1;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
this.nStepCycles -= X86CPU.CYCLES_80386.nOpCyclesBitScan + i * 3;
|
||||
return dst;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnBSR(dst, src)
|
||||
*
|
||||
* Scan src starting from the highest bit. If a set bit is found, the bit index is stored in dst and ZF is
|
||||
* cleared; otherwise, ZF is set and dst is unchanged.
|
||||
*
|
||||
* NOTES: Early versions of the 80386 manuals misstated how ZF was set/cleared. Also, Intel insists that
|
||||
* dst is undefined whenever ZF is set, but in fact, the 80386 leaves dst unchanged when that happens;
|
||||
* unfortunately, some early 80486s would always modify dst, so it is unsafe to rely on dst when ZF is set.
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} dst
|
||||
* @param {number} src
|
||||
* @return {number}
|
||||
*/
|
||||
X86.fnBSR = function BSR(dst, src)
|
||||
{
|
||||
if (!src) {
|
||||
this.setZF();
|
||||
} else {
|
||||
this.clearZF();
|
||||
var i = (this.dataSize == 2? 15 : 31), j = i, bit = 1 << i;
|
||||
while (bit) {
|
||||
if (src & bit) {
|
||||
dst = i;
|
||||
break;
|
||||
}
|
||||
bit >>>= 1;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
this.nStepCycles -= X86CPU.CYCLES_80386.nOpCyclesBitScan + (j - i) * 3;
|
||||
return dst;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnBT(dst, src)
|
||||
*
|
||||
|
|
@ -1052,6 +1122,25 @@ X86.fnLES = function LES(dst, src)
|
|||
return src;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnLFS(dst, src)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} dst
|
||||
* @param {number} src
|
||||
* @return {number}
|
||||
*/
|
||||
X86.fnLFS = function LFS(dst, src)
|
||||
{
|
||||
if (this.regEA === X86.ADDR_INVALID) {
|
||||
X86.opUndefined.call(this);
|
||||
return dst;
|
||||
}
|
||||
this.setFS(this.getShort(this.regEA + 2));
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesLS;
|
||||
return src;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnLGDT(dst, src)
|
||||
*
|
||||
|
|
@ -1079,6 +1168,25 @@ X86.fnLGDT = function LGDT(dst, src)
|
|||
return dst;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnLGS(dst, src)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} dst
|
||||
* @param {number} src
|
||||
* @return {number}
|
||||
*/
|
||||
X86.fnLGS = function LGS(dst, src)
|
||||
{
|
||||
if (this.regEA === X86.ADDR_INVALID) {
|
||||
X86.opUndefined.call(this);
|
||||
return dst;
|
||||
}
|
||||
this.setGS(this.getShort(this.regEA + 2));
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesLS;
|
||||
return src;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnLIDT(dst, src)
|
||||
*
|
||||
|
|
@ -1173,6 +1281,25 @@ X86.fnLSL = function LSL(dst, src)
|
|||
return dst;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnLSS(dst, src)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} dst
|
||||
* @param {number} src
|
||||
* @return {number}
|
||||
*/
|
||||
X86.fnLSS = function LSS(dst, src)
|
||||
{
|
||||
if (this.regEA === X86.ADDR_INVALID) {
|
||||
X86.opUndefined.call(this);
|
||||
return dst;
|
||||
}
|
||||
this.setSS(this.getShort(this.regEA + 2));
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesLS;
|
||||
return src;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnLTR(dst, src)
|
||||
*
|
||||
|
|
@ -1208,6 +1335,19 @@ X86.fnMOV = function MOV(dst, src)
|
|||
return src;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnMOVX(dst, src)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} dst (current value, ignored)
|
||||
* @param {number} src (new value)
|
||||
* @return {number} dst (updated value, from src)
|
||||
*/
|
||||
X86.fnMOVX = function MOVX(dst, src)
|
||||
{
|
||||
return src;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnMOVn(dst, src)
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in a new issue