Some performance tweaks
This commit is contained in:
parent
e2ddc497c3
commit
da58c2aeaf
11 changed files with 19094 additions and 1478 deletions
|
|
@ -57,10 +57,11 @@ try {
|
|||
* See p. 3-41 of "The 8086 Book" for more details.
|
||||
*/
|
||||
|
||||
var f16Only = true;
|
||||
var aDst = ["Mem", "Reg"];
|
||||
var aSize = ["Byte", "Word"];
|
||||
var aOpPrefix = ["B", "W"];
|
||||
var aAddrPrefix = ["", "32"];
|
||||
var aAddrPrefix = [f16Only? "" : "16", "32"];
|
||||
var aDisp = ["8", "16"];
|
||||
|
||||
/*
|
||||
|
|
@ -215,12 +216,17 @@ else {
|
|||
var sOpMods, sOpMod, sContainer;
|
||||
|
||||
print('"use strict";\n');
|
||||
print("var X86ModB = {};");
|
||||
print("var X86ModW = {};");
|
||||
print("var X86ModB32 = {};");
|
||||
print("var X86ModW32 = {};\n");
|
||||
if (f16Only) {
|
||||
print("var X86ModB = {};");
|
||||
print("var X86ModW = {};\n");
|
||||
} else {
|
||||
print("var X86ModB16 = {};");
|
||||
print("var X86ModW16 = {};");
|
||||
print("var X86ModB32 = {};");
|
||||
print("var X86ModW32 = {};\n");
|
||||
}
|
||||
|
||||
for (var a = 0; a <= 1 && !sError; a++) {
|
||||
for (var a = 0; a <= (f16Only? 0 : 1) && !sError; a++) {
|
||||
|
||||
for (w = 0; w <= 1 && !sError; w++) {
|
||||
|
||||
|
|
@ -259,13 +265,14 @@ else {
|
|||
}
|
||||
}
|
||||
|
||||
sContainer = "X86ModSIB" + ".aOpModSIB";
|
||||
|
||||
print(sContainer + " = [");
|
||||
for (var sib = 0x00; sib <= 0xff && !sError; sib++) {
|
||||
genSIB(sib);
|
||||
if (!f16Only) {
|
||||
sContainer = "X86ModSIB" + ".aOpModSIB";
|
||||
print(sContainer + " = [");
|
||||
for (var sib = 0x00; sib <= 0xff && !sError; sib++) {
|
||||
genSIB(sib);
|
||||
}
|
||||
print("];\n");
|
||||
}
|
||||
print("];\n");
|
||||
|
||||
if (sEAFuncs) {
|
||||
print("var X86Mods = {\n" + sEAFuncs + "};\n");
|
||||
|
|
@ -329,26 +336,26 @@ function genMode(a, d, w, mrm, sGroup, sRO) {
|
|||
sRegBTLo = "this.backTrack.btiBL";
|
||||
break;
|
||||
case 4:
|
||||
sRegGet = "(this.regEAX >> 8) & 0xff";
|
||||
sRegSet = "this.regEAX = (this.regEAX & ~0xff00) | ";
|
||||
sRegGet = f16Only? "this.regEAX >> 8" : "(this.regEAX >> 8) & 0xff";
|
||||
sRegSet = f16Only? "this.regEAX = (this.regEAX & 0xff) | " : "this.regEAX = (this.regEAX & ~0xff00) | ";
|
||||
sRegSetEnd = " << 8";
|
||||
sRegBTLo = "this.backTrack.btiAH";
|
||||
break;
|
||||
case 5:
|
||||
sRegGet = "(this.regECX >> 8) & 0xff";
|
||||
sRegSet = "this.regECX = (this.regECX & ~0xff00) | ";
|
||||
sRegGet = f16Only? "this.regECX >> 8" : "(this.regECX >> 8) & 0xff";
|
||||
sRegSet = f16Only? "this.regECX = (this.regECX & 0xff) | " : "this.regECX = (this.regECX & ~0xff00) | ";
|
||||
sRegSetEnd = " << 8";
|
||||
sRegBTLo = "this.backTrack.btiCH";
|
||||
break;
|
||||
case 6:
|
||||
sRegGet = "(this.regEDX >> 8) & 0xff";
|
||||
sRegSet = "this.regEDX = (this.regEDX & ~0xff00) | ";
|
||||
sRegGet = f16Only? "this.regEDX >> 8" : "(this.regEDX >> 8) & 0xff";
|
||||
sRegSet = f16Only? "this.regEDX = (this.regEDX & 0xff) | " : "this.regEDX = (this.regEDX & ~0xff00) | ";
|
||||
sRegSetEnd = " << 8";
|
||||
sRegBTLo = "this.backTrack.btiDH";
|
||||
break;
|
||||
case 7:
|
||||
sRegGet = "(this.regEBX >> 8) & 0xff";
|
||||
sRegSet = "this.regEBX = (this.regEBX & ~0xff00) | ";
|
||||
sRegGet = f16Only? "this.regEBX >> 8" : "(this.regEBX >> 8) & 0xff";
|
||||
sRegSet = f16Only? "this.regEBX = (this.regEBX & 0xff) | " : "this.regEBX = (this.regEBX & ~0xff00) | ";
|
||||
sRegSetEnd = " << 8";
|
||||
sRegBTLo = "this.backTrack.btiBH";
|
||||
break;
|
||||
|
|
@ -360,50 +367,50 @@ function genMode(a, d, w, mrm, sGroup, sRO) {
|
|||
else {
|
||||
switch (reg) {
|
||||
case 0:
|
||||
sRegGet = "this.regEAX & this.dataMask";
|
||||
sRegSet = "this.regEAX = (this.regEAX & ~this.dataMask) | ";
|
||||
sRegGet = f16Only? "this.regEAX" : "this.regEAX & this.dataMask";
|
||||
sRegSet = f16Only? "" : "this.regEAX = (this.regEAX & ~this.dataMask) | ";
|
||||
sRegBTLo = "this.backTrack.btiAL";
|
||||
sRegBTHi = "this.backTrack.btiAH";
|
||||
break;
|
||||
case 1:
|
||||
sRegGet = "this.regECX & this.dataMask";
|
||||
sRegSet = "this.regECX = (this.regECX & ~this.dataMask) | ";
|
||||
sRegGet = f16Only? "this.regECX" : "this.regECX & this.dataMask";
|
||||
sRegSet = f16Only? "" : "this.regECX = (this.regECX & ~this.dataMask) | ";
|
||||
sRegBTLo = "this.backTrack.btiCL";
|
||||
sRegBTHi = "this.backTrack.btiCH";
|
||||
break;
|
||||
case 2:
|
||||
sRegGet = "this.regEDX & this.dataMask";
|
||||
sRegSet = "this.regEDX = (this.regEDX & ~this.dataMask) | ";
|
||||
sRegGet = f16Only? "this.regEDX" : "this.regEDX & this.dataMask";
|
||||
sRegSet = f16Only? "" : "this.regEDX = (this.regEDX & ~this.dataMask) | ";
|
||||
sRegBTLo = "this.backTrack.btiDL";
|
||||
sRegBTHi = "this.backTrack.btiDH";
|
||||
break;
|
||||
case 3:
|
||||
sRegGet = "this.regEBX & this.dataMask";
|
||||
sRegSet = "this.regEBX = (this.regEBX & ~this.dataMask) | ";
|
||||
sRegGet = f16Only? "this.regEBX" : "this.regEBX & this.dataMask";
|
||||
sRegSet = f16Only? "" : "this.regEBX = (this.regEBX & ~this.dataMask) | ";
|
||||
sRegBTLo = "this.backTrack.btiBL";
|
||||
sRegBTHi = "this.backTrack.btiBH";
|
||||
break;
|
||||
case 4:
|
||||
sRegGet = "this.regESP & this.dataMask";
|
||||
sRegSet = "this.regESP = (this.regESP & ~this.dataMask) | ";
|
||||
sRegGet = f16Only? "this.regESP" : "this.regESP & this.dataMask";
|
||||
sRegSet = f16Only? "" : "this.regESP = (this.regESP & ~this.dataMask) | ";
|
||||
sRegBTLo = "X86.BACKTRACK.SP_LO";
|
||||
sRegBTHi = "X86.BACKTRACK.SP_HI";
|
||||
break;
|
||||
case 5:
|
||||
sRegGet = "this.regEBP & this.dataMask";
|
||||
sRegSet = "this.regEBP = (this.regEBP & ~this.dataMask) | ";
|
||||
sRegGet = f16Only? "this.regEBP" : "this.regEBP & this.dataMask";
|
||||
sRegSet = f16Only? "" : "this.regEBP = (this.regEBP & ~this.dataMask) | ";
|
||||
sRegBTLo = "this.backTrack.btiBPLo";
|
||||
sRegBTHi = "this.backTrack.btiBPHi";
|
||||
break;
|
||||
case 6:
|
||||
sRegGet = "this.regESI & this.dataMask";
|
||||
sRegSet = "this.regESI = (this.regESI & ~this.dataMask) | ";
|
||||
sRegGet = f16Only? "this.regESI" : "this.regESI & this.dataMask";
|
||||
sRegSet = f16Only? "" : "this.regESI = (this.regESI & ~this.dataMask) | ";
|
||||
sRegBTLo = "this.backTrack.btiSILo";
|
||||
sRegBTHi = "this.backTrack.btiSIHi";
|
||||
break;
|
||||
case 7:
|
||||
sRegGet = "this.regEDI & this.dataMask";
|
||||
sRegSet = "this.regEDI = (this.regEDI & ~this.dataMask) | ";
|
||||
sRegGet = f16Only? "this.regEDI" : "this.regEDI & this.dataMask";
|
||||
sRegSet = f16Only? "" : "this.regEDI = (this.regEDI & ~this.dataMask) | ";
|
||||
sRegBTLo = "this.backTrack.btiDILo";
|
||||
sRegBTHi = "this.backTrack.btiDIHi";
|
||||
break;
|
||||
|
|
@ -604,26 +611,26 @@ function genMode(a, d, w, mrm, sGroup, sRO) {
|
|||
sModRegBTLo = "this.backTrack.btiBL";
|
||||
break;
|
||||
case 4:
|
||||
sModRegGet = "(this.regEAX >> 8) & 0xff";
|
||||
sModRegSet = "this.regEAX = (this.regEAX & ~0xff00) | ";
|
||||
sModRegGet = f16Only? "(this.regEAX >> 8)" : "(this.regEAX >> 8) & 0xff";
|
||||
sModRegSet = f16Only? "this.regEAX = (this.regEAX & 0xff) | " : "this.regEAX = (this.regEAX & ~0xff00) | ";
|
||||
sModRegSetEnd = " << 8";
|
||||
sModRegBTLo = "this.backTrack.btiAH";
|
||||
break;
|
||||
case 5:
|
||||
sModRegGet = "(this.regECX >> 8) & 0xff";
|
||||
sModRegSet = "this.regECX = (this.regECX & ~0xff00) | ";
|
||||
sModRegGet = f16Only? "(this.regECX >> 8)" : "(this.regECX >> 8) & 0xff";
|
||||
sModRegSet = f16Only? "this.regECX = (this.regECX & 0xff) | " : "this.regECX = (this.regECX & ~0xff00) | ";
|
||||
sModRegSetEnd = " << 8";
|
||||
sModRegBTLo = "this.backTrack.btiCH";
|
||||
break;
|
||||
case 6:
|
||||
sModRegGet = "(this.regEDX >> 8) & 0xff";
|
||||
sModRegSet = "this.regEDX = (this.regEDX & ~0xff00) | ";
|
||||
sModRegGet = f16Only? "(this.regEDX >> 8)" : "(this.regEDX >> 8) & 0xff";
|
||||
sModRegSet = f16Only? "this.regEDX = (this.regEDX & 0xff) | " : "this.regEDX = (this.regEDX & ~0xff00) | ";
|
||||
sModRegSetEnd = " << 8";
|
||||
sModRegBTLo = "this.backTrack.btiDH";
|
||||
break;
|
||||
case 7:
|
||||
sModRegGet = "(this.regEBX >> 8) & 0xff";
|
||||
sModRegSet = "this.regEBX = (this.regEBX & ~0xff00) | ";
|
||||
sModRegGet = f16Only? "(this.regEBX >> 8)" : "(this.regEBX >> 8) & 0xff";
|
||||
sModRegSet = f16Only? "this.regEBX = (this.regEBX & 0xff) | " : "this.regEBX = (this.regEBX & ~0xff00) | ";
|
||||
sModRegSetEnd = " << 8";
|
||||
sModRegBTLo = "this.backTrack.btiBH";
|
||||
break;
|
||||
|
|
@ -635,50 +642,50 @@ function genMode(a, d, w, mrm, sGroup, sRO) {
|
|||
else {
|
||||
switch (r_m) {
|
||||
case 0:
|
||||
sModRegGet = "this.regEAX & this.dataMask";
|
||||
sModRegSet = "this.regEAX = (this.regEAX & ~this.dataMask) | ";
|
||||
sModRegGet = f16Only? "this.regEAX" : "this.regEAX & this.dataMask";
|
||||
sModRegSet = f16Only? "" : "this.regEAX = (this.regEAX & ~this.dataMask) | ";
|
||||
sModRegBTLo = "this.backTrack.btiAL";
|
||||
sModRegBTHi = "this.backTrack.btiAH";
|
||||
break;
|
||||
case 1:
|
||||
sModRegGet = "this.regECX & this.dataMask";
|
||||
sModRegSet = "this.regECX = (this.regECX & ~this.dataMask) | ";
|
||||
sModRegGet = f16Only? "this.regECX" : "this.regECX & this.dataMask";
|
||||
sModRegSet = f16Only? "" : "this.regECX = (this.regECX & ~this.dataMask) | ";
|
||||
sModRegBTLo = "this.backTrack.btiCL";
|
||||
sModRegBTHi = "this.backTrack.btiCH";
|
||||
break;
|
||||
case 2:
|
||||
sModRegGet = "this.regEDX & this.dataMask";
|
||||
sModRegSet = "this.regEDX = (this.regEDX & ~this.dataMask) | ";
|
||||
sModRegGet = f16Only? "this.regEDX" : "this.regEDX & this.dataMask";
|
||||
sModRegSet = f16Only? "" : "this.regEDX = (this.regEDX & ~this.dataMask) | ";
|
||||
sModRegBTLo = "this.backTrack.btiDL";
|
||||
sModRegBTHi = "this.backTrack.btiDH";
|
||||
break;
|
||||
case 3:
|
||||
sModRegGet = "this.regEBX & this.dataMask";
|
||||
sModRegSet = "this.regEBX = (this.regEBX & ~this.dataMask) | ";
|
||||
sModRegGet = f16Only? "this.regEBX" : "this.regEBX & this.dataMask";
|
||||
sModRegSet = f16Only? "" : "this.regEBX = (this.regEBX & ~this.dataMask) | ";
|
||||
sModRegBTLo = "this.backTrack.btiBL";
|
||||
sModRegBTHi = "this.backTrack.btiBH";
|
||||
break;
|
||||
case 4:
|
||||
sModRegGet = "this.regESP & this.dataMask";
|
||||
sModRegSet = "this.regESP = (this.regESP & ~this.dataMask) | ";
|
||||
sModRegGet = f16Only? "this.regESP" : "this.regESP & this.dataMask";
|
||||
sModRegSet = f16Only? "" : "this.regESP = (this.regESP & ~this.dataMask) | ";
|
||||
sModRegBTLo = "X86.BACKTRACK.SP_LO";
|
||||
sModRegBTHi = "X86.BACKTRACK.SP_HI";
|
||||
break;
|
||||
case 5:
|
||||
sModRegGet = "this.regEBP & this.dataMask";
|
||||
sModRegSet = "this.regEBP = (this.regEBP & ~this.dataMask) | ";
|
||||
sModRegGet = f16Only? "this.regEBP" : "this.regEBP & this.dataMask";
|
||||
sModRegSet = f16Only? "" : "this.regEBP = (this.regEBP & ~this.dataMask) | ";
|
||||
sModRegBTLo = "this.backTrack.btiBPLo";
|
||||
sModRegBTHi = "this.backTrack.btiBPHi";
|
||||
break;
|
||||
case 6:
|
||||
sModRegGet = "this.regESI & this.dataMask";
|
||||
sModRegSet = "this.regESI = (this.regESI & ~this.dataMask) | ";
|
||||
sModRegGet = f16Only? "this.regESI" : "this.regESI & this.dataMask";
|
||||
sModRegSet = f16Only? "" : "this.regESI = (this.regESI & ~this.dataMask) | ";
|
||||
sModRegBTLo = "this.backTrack.btiSILo";
|
||||
sModRegBTHi = "this.backTrack.btiSIHi";
|
||||
break;
|
||||
case 7:
|
||||
sModRegGet = "this.regEDI & this.dataMask";
|
||||
sModRegSet = "this.regEDI = (this.regEDI & ~this.dataMask) | ";
|
||||
sModRegGet = f16Only? "this.regEDI" : "this.regEDI & this.dataMask";
|
||||
sModRegSet = f16Only? "" : "this.regEDI = (this.regEDI & ~this.dataMask) | ";
|
||||
sModRegBTLo = "this.backTrack.btiDILo";
|
||||
sModRegBTHi = "this.backTrack.btiDIHi";
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -4746,7 +4746,7 @@ if (DEBUGGER) {
|
|||
if (this.cmp) this.cmp.reset();
|
||||
return true;
|
||||
case "ver":
|
||||
this.println((APPNAME || "PCjs") + " version " + APPVERSION + " (" + (I386? "80386" : "80286") + (COMPILED? ",RELEASE" : (DEBUG? ",DEBUG" : ",NODEBUG")) + (PREFETCH? ",PREFETCH" : ",NOPREFETCH") + (TYPEDARRAYS? ",TYPEDARRAYS" : (FATARRAYS? ",FATARRAYS" : ",LONGARRAYS")) + (BACKTRACK? ",BACKTRACK" : "") + ")");
|
||||
this.println((APPNAME || "PCjs") + " version " + APPVERSION + " (" + this.cpu.model + (COMPILED? ",RELEASE" : (DEBUG? ",DEBUG" : ",NODEBUG")) + (PREFETCH? ",PREFETCH" : ",NOPREFETCH") + (TYPEDARRAYS? ",TYPEDARRAYS" : (FATARRAYS? ",FATARRAYS" : ",LONGARRAYS")) + (BACKTRACK? ",BACKTRACK" : ",NOBACKTRACK") + ")");
|
||||
return true;
|
||||
default:
|
||||
ch0 = sCmd.charAt(0);
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ if (typeof module !== 'undefined') {
|
|||
var Component = require("../../shared/lib/component");
|
||||
var Messages = require("./messages");
|
||||
}
|
||||
|
||||
/**
|
||||
* @class DataView
|
||||
* @property {function(number,boolean):number} getUint8
|
||||
|
|
@ -63,6 +64,12 @@ if (typeof module !== 'undefined') {
|
|||
* @property {function(number,number,boolean)} setInt32
|
||||
*/
|
||||
|
||||
var littleEndian = (function() {
|
||||
var buffer = new ArrayBuffer(2);
|
||||
new DataView(buffer).setUint16(0, 256, true);
|
||||
return new Uint16Array(buffer)[0] === 256;
|
||||
})();
|
||||
|
||||
/**
|
||||
* Memory(addr, size, type, controller)
|
||||
*
|
||||
|
|
@ -163,11 +170,14 @@ function Memory(addr, size, type, controller)
|
|||
this.buffer = new ArrayBuffer(size);
|
||||
this.dv = new DataView(this.buffer, 0, size);
|
||||
/*
|
||||
* We could also use dv.getUint8() and dv.setUint8(), but using ab[] to get/set bytes
|
||||
* in this.buffer is more convenient and presents no "endianness" issues.
|
||||
* If littleEndian is true, we can use ab[], aw[] and adw[] directly; well, we can use them
|
||||
* whenever the offset is a multiple of 1, 2 or 4, respectively. Otherwise, we must fallback to
|
||||
* dv.getUint8()/dv.setUint8(), dv.getUint16()/dv.setUint16() and db.getInt32()/dv.setInt32().
|
||||
*/
|
||||
this.ab = new Uint8Array(this.buffer, 0, size);
|
||||
this.setAccess(Memory.afnTypedArray);
|
||||
this.aw = new Uint16Array(this.buffer, 0, size >> 1);
|
||||
this.adw = new Int32Array(this.buffer, 0, size >> 2);
|
||||
this.setAccess(littleEndian? Memory.afnLittleEndian : Memory.afnBigEndian);
|
||||
} else {
|
||||
if (FATARRAYS) {
|
||||
this.ab = new Array(size);
|
||||
|
|
@ -473,86 +483,199 @@ Memory.writeLongChecked = function writeLongChecked(off, l)
|
|||
};
|
||||
|
||||
/**
|
||||
* readByteTypedArray(off)
|
||||
* readByteBigEndian(off)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @param {number} off
|
||||
* @return {number}
|
||||
*/
|
||||
Memory.readByteTypedArray = function readByteTypedArray(off)
|
||||
Memory.readByteBigEndian = function readByteBigEndian(off)
|
||||
{
|
||||
Component.assert(off >= 0 && off < this.size);
|
||||
return this.ab[off];
|
||||
};
|
||||
|
||||
/**
|
||||
* readShortTypedArray(off)
|
||||
* readByteLittleEndian(off)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @param {number} off
|
||||
* @return {number}
|
||||
*/
|
||||
Memory.readShortTypedArray = function readShortTypedArray(off)
|
||||
Memory.readByteLittleEndian = function readByteLittleEndian(off)
|
||||
{
|
||||
Component.assert(off >= 0 && off < this.size);
|
||||
return this.ab[off];
|
||||
};
|
||||
|
||||
/**
|
||||
* readShortBigEndian(off)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @param {number} off
|
||||
* @return {number}
|
||||
*/
|
||||
Memory.readShortBigEndian = function readShortBigEndian(off)
|
||||
{
|
||||
Component.assert(off >= 0 && off < this.size - 1);
|
||||
return this.dv.getUint16(off, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* readLongTypedArray(off)
|
||||
* readShortLittleEndian(off)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @param {number} off
|
||||
* @return {number}
|
||||
*/
|
||||
Memory.readLongTypedArray = function readLongTypedArray(off)
|
||||
Memory.readShortLittleEndian = function readShortLittleEndian(off)
|
||||
{
|
||||
Component.assert(off >= 0 && off < this.size - 1);
|
||||
/*
|
||||
* TODO: It remains to be seen if there's any advantage to checking the offset
|
||||
* for an aligned read vs. always reading the bytes separately; it seems a safe bet
|
||||
* for longs, but it's less clear for shorts.
|
||||
*/
|
||||
return (off & 0x1)? (this.ab[off] | (this.ab[off+1] << 8)) : this.aw[off >> 1];
|
||||
};
|
||||
|
||||
/**
|
||||
* readLongBigEndian(off)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @param {number} off
|
||||
* @return {number}
|
||||
*/
|
||||
Memory.readLongBigEndian = function readLongBigEndian(off)
|
||||
{
|
||||
Component.assert(off >= 0 && off < this.size - 3);
|
||||
return this.dv.getInt32(off, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* writeByteTypedArray(off, b)
|
||||
* readLongLittleEndian(off)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @param {number} off
|
||||
* @return {number}
|
||||
*/
|
||||
Memory.readLongLittleEndian = function readLongLittleEndian(off)
|
||||
{
|
||||
Component.assert(off >= 0 && off < this.size - 3);
|
||||
/*
|
||||
* TODO: It remains to be seen if there's any advantage to checking the offset
|
||||
* for an aligned read vs. always reading the bytes separately; it seems a safe bet
|
||||
* for longs, but it's less clear for shorts.
|
||||
*/
|
||||
return (off & 0x3)? (this.ab[off] | (this.ab[off+1] << 8) | (this.ab[off+2] << 16) | (this.ab[off+3] << 24)) : this.adw[off >> 2];
|
||||
};
|
||||
|
||||
/**
|
||||
* writeByteBigEndian(off, b)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @param {number} off
|
||||
* @param {number} b
|
||||
*/
|
||||
Memory.writeByteTypedArray = function writeByteTypedArray(off, b)
|
||||
Memory.writeByteBigEndian = function writeByteBigEndian(off, b)
|
||||
{
|
||||
Component.assert(off >= 0 && off < this.size && (b & 0xff) == b);
|
||||
Component.assert(off >= 0 && off < this.size);
|
||||
this.ab[off] = b;
|
||||
this.fDirty = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* writeShortTypedArray(off, w)
|
||||
* writeByteLittleEndian(off, b)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @param {number} off
|
||||
* @param {number} b
|
||||
*/
|
||||
Memory.writeByteLittleEndian = function writeByteLittleEndian(off, b)
|
||||
{
|
||||
Component.assert(off >= 0 && off < this.size);
|
||||
this.ab[off] = b;
|
||||
this.fDirty = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* writeShortBigEndian(off, w)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @param {number} off
|
||||
* @param {number} w
|
||||
*/
|
||||
Memory.writeShortTypedArray = function writeShortTypedArray(off, w)
|
||||
Memory.writeShortBigEndian = function writeShortBigEndian(off, w)
|
||||
{
|
||||
Component.assert(off >= 0 && off < this.size - 1 && (w & 0xffff) == w);
|
||||
Component.assert(off >= 0 && off < this.size - 1);
|
||||
this.dv.setUint16(off, w, true);
|
||||
this.fDirty = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* writeLongTypedArray(off, l)
|
||||
* writeShortLittleEndian(off, w)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @param {number} off
|
||||
* @param {number} w
|
||||
*/
|
||||
Memory.writeShortLittleEndian = function writeShortLittleEndian(off, w)
|
||||
{
|
||||
Component.assert(off >= 0 && off < this.size - 1);
|
||||
/*
|
||||
* TODO: It remains to be seen if there's any advantage to checking the offset
|
||||
* for an aligned write vs. always writing the bytes separately; it seems a safe bet
|
||||
* for longs, but it's less clear for shorts.
|
||||
*/
|
||||
if (off & 0x1) {
|
||||
this.ab[off] = w;
|
||||
this.ab[off+1] = w >> 8;
|
||||
} else {
|
||||
this.aw[off >> 1] = w;
|
||||
}
|
||||
this.fDirty = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* writeLongBigEndian(off, l)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @param {number} off
|
||||
* @param {number} l
|
||||
*/
|
||||
Memory.writeLongTypedArray = function writeLongTypedArray(off, l)
|
||||
Memory.writeLongBigEndian = function writeLongBigEndian(off, l)
|
||||
{
|
||||
Component.assert(off >= 0 && off < this.size - 3);
|
||||
this.dv.setInt32(off, l, true);
|
||||
this.fDirty = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* writeLongLittleEndian(off, l)
|
||||
*
|
||||
* @this {Memory}
|
||||
* @param {number} off
|
||||
* @param {number} l
|
||||
*/
|
||||
Memory.writeLongLittleEndian = function writeLongLittleEndian(off, l)
|
||||
{
|
||||
Component.assert(off >= 0 && off < this.size - 3);
|
||||
/*
|
||||
* TODO: It remains to be seen if there's any advantage to checking the offset
|
||||
* for an aligned write vs. always writing the bytes separately; it seems a safe bet
|
||||
* for longs, but it's less clear for shorts.
|
||||
*/
|
||||
if (off & 0x3) {
|
||||
this.ab[off] = l;
|
||||
this.ab[off+1] = (l >> 8);
|
||||
this.ab[off+2] = (l >> 16);
|
||||
this.ab[off+3] = (l >> 24);
|
||||
} else {
|
||||
this.adw[off >> 2] = l;
|
||||
}
|
||||
this.fDirty = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* readBackTrackNone(off)
|
||||
*
|
||||
|
|
@ -635,7 +758,8 @@ Memory.afnMemory = [Memory.readByteMemory, Memory.readShortMemory, Mem
|
|||
Memory.afnChecked = [Memory.readByteChecked, Memory.readShortChecked, Memory.readLongChecked, Memory.writeByteChecked, Memory.writeShortChecked, Memory.writeLongChecked];
|
||||
|
||||
if (TYPEDARRAYS) {
|
||||
Memory.afnTypedArray = [Memory.readByteTypedArray, Memory.readShortTypedArray, Memory.readLongTypedArray, Memory.writeByteTypedArray, Memory.writeShortTypedArray, Memory.writeLongTypedArray];
|
||||
Memory.afnBigEndian = [Memory.readByteBigEndian, Memory.readShortBigEndian, Memory.readLongBigEndian, Memory.writeByteBigEndian, Memory.writeShortBigEndian, Memory.writeLongBigEndian];
|
||||
Memory.afnLittleEndian = [Memory.readByteLittleEndian, Memory.readShortLittleEndian, Memory.readLongLittleEndian, Memory.writeByteLittleEndian, Memory.writeShortLittleEndian, Memory.writeLongLittleEndian];
|
||||
}
|
||||
|
||||
Memory.prototype = {
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ if (typeof module !== 'undefined') {
|
|||
|
||||
if (I386) {
|
||||
if (typeof module !== 'undefined') {
|
||||
var X86ModB16 = require("./x86modb16");
|
||||
var X86ModW16 = require("./x86modw16");
|
||||
var X86ModB32 = require("./x86modb32");
|
||||
var X86ModW32 = require("./x86modw32");
|
||||
var X86ModSIB = require("./x86modsib");
|
||||
|
|
@ -970,7 +972,6 @@ X86CPU.prototype.resetRegs = function()
|
|||
*/
|
||||
this.addrSize = this.segCS.addrSize;
|
||||
this.addrMask = this.segCS.addrMask;
|
||||
|
||||
/*
|
||||
* It's also worth noting that instructions that implicitly use the stack also rely on something called STACK size,
|
||||
* which is based on the BIG bit of the last descriptor loaded into SS; use the following segSS properties:
|
||||
|
|
@ -986,7 +987,7 @@ X86CPU.prototype.resetRegs = function()
|
|||
* The memory dispatch tables; opMem refers to the active set, based on the current OPERAND size (dataSize),
|
||||
* which is based foremost on segCS.dataSize, but can also be overridden by an OPERAND size instruction prefix.
|
||||
*/
|
||||
this.aaOpMem = new Array(5);
|
||||
this.aaOpMem = [];
|
||||
this.aaOpMem[2] = {
|
||||
getWord: this.getShort.bind(this),
|
||||
setWord: this.setShort.bind(this)
|
||||
|
|
@ -998,31 +999,43 @@ X86CPU.prototype.resetRegs = function()
|
|||
};
|
||||
}
|
||||
this.opMem = this.aaOpMem[this.segCS.dataSize];
|
||||
this.setOpMod();
|
||||
};
|
||||
|
||||
/*
|
||||
* The ModRM dispatch tables; opMod refers to the active set, based on the current ADDRESS size (addrSize),
|
||||
* which is based foremost on segCS.addrSize, but can also be overridden by an ADDRESS size instruction prefix.
|
||||
*/
|
||||
this.aaOpMod = new Array(5);
|
||||
this.aaOpMod[2] = {
|
||||
aOpModRegByte: X86ModB.aOpModReg,
|
||||
aOpModMemByte: X86ModB.aOpModMem,
|
||||
aOpModGrpByte: X86ModB.aOpModGrp,
|
||||
aOpModRegWord: X86ModW.aOpModReg,
|
||||
aOpModMemWord: X86ModW.aOpModMem,
|
||||
aOpModGrpWord: X86ModW.aOpModGrp
|
||||
};
|
||||
if (I386) {
|
||||
this.aaOpMod[4] = {
|
||||
aOpModRegByte: X86ModB32.aOpModReg,
|
||||
aOpModMemByte: X86ModB32.aOpModMem,
|
||||
aOpModGrpByte: X86ModB32.aOpModGrp,
|
||||
aOpModRegWord: X86ModW32.aOpModReg,
|
||||
aOpModMemWord: X86ModW32.aOpModMem,
|
||||
aOpModGrpWord: X86ModW32.aOpModGrp
|
||||
};
|
||||
/**
|
||||
* setOpMod()
|
||||
*
|
||||
* Select the appropriate ModRM dispatch tables, based on the current ADDRESS size (addrSize), which
|
||||
* is based foremost on segCS.addrSize, but can also be overridden by an ADDRESS size instruction prefix.
|
||||
*
|
||||
* @this {X86CPU}
|
||||
*/
|
||||
X86CPU.prototype.setOpMod = function()
|
||||
{
|
||||
if (!I386) {
|
||||
this.aOpModRegByte = X86ModB.aOpModReg;
|
||||
this.aOpModMemByte = X86ModB.aOpModMem;
|
||||
this.aOpModGrpByte = X86ModB.aOpModGrp;
|
||||
this.aOpModRegWord = X86ModW.aOpModReg;
|
||||
this.aOpModMemWord = X86ModW.aOpModMem;
|
||||
this.aOpModGrpWord = X86ModW.aOpModGrp;
|
||||
} else {
|
||||
if (this.addrSize == 2) {
|
||||
this.aOpModRegByte = X86ModB16.aOpModReg;
|
||||
this.aOpModMemByte = X86ModB16.aOpModMem;
|
||||
this.aOpModGrpByte = X86ModB16.aOpModGrp;
|
||||
this.aOpModRegWord = X86ModW16.aOpModReg;
|
||||
this.aOpModMemWord = X86ModW16.aOpModMem;
|
||||
this.aOpModGrpWord = X86ModW16.aOpModGrp;
|
||||
} else {
|
||||
this.aOpModRegByte = X86ModB32.aOpModReg;
|
||||
this.aOpModMemByte = X86ModB32.aOpModMem;
|
||||
this.aOpModGrpByte = X86ModB32.aOpModGrp;
|
||||
this.aOpModRegWord = X86ModW32.aOpModReg;
|
||||
this.aOpModMemWord = X86ModW32.aOpModMem;
|
||||
this.aOpModGrpWord = X86ModW32.aOpModGrp;
|
||||
}
|
||||
}
|
||||
this.opMod = this.aaOpMod[this.segCS.addrSize];
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1378,7 +1391,7 @@ X86CPU.prototype.setES = function(sel)
|
|||
*/
|
||||
X86CPU.prototype.setIP = function(off)
|
||||
{
|
||||
this.regLIP = this.segCS.base + (this.regEIP = off & this.addrMask);
|
||||
this.regLIP = this.segCS.base + (this.regEIP = off & (I386? this.addrMask : 0xffff));
|
||||
if (PREFETCH) this.flushPrefetch(this.regLIP);
|
||||
};
|
||||
|
||||
|
|
@ -1429,7 +1442,7 @@ X86CPU.prototype.setCSIP = function(off, sel, fCall)
|
|||
*/
|
||||
X86CPU.prototype.advanceIP = function(inc)
|
||||
{
|
||||
this.regLIP = this.segCS.base + (this.regEIP = (this.regEIP + inc) & this.addrMask);
|
||||
this.regLIP = this.segCS.base + (this.regEIP = (this.regEIP + inc) & (I386? this.addrMask : 0xffff));
|
||||
if (PREFETCH) this.advancePrefetch(inc);
|
||||
};
|
||||
|
||||
|
|
@ -2026,9 +2039,9 @@ X86CPU.prototype.getEAByte = function(seg, off)
|
|||
X86CPU.prototype.getEAWord = function(seg, off)
|
||||
{
|
||||
this.segEA = seg;
|
||||
this.regEA = seg.checkRead(this.offEA = off, this.dataSize-1);
|
||||
this.regEA = seg.checkRead(this.offEA = off, (I386? this.dataSize-1 : 1));
|
||||
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
|
||||
var w = this.opMem.getWord(this.regEA);
|
||||
var w = I386? this.opMem.getWord(this.regEA) : this.getShort(this.regEA);
|
||||
if (BACKTRACK) {
|
||||
this.backTrack.btiEALo = this.backTrack.btiMemLo;
|
||||
this.backTrack.btiEAHi = this.backTrack.btiMemHi;
|
||||
|
|
@ -2065,9 +2078,9 @@ X86CPU.prototype.modEAByte = function(seg, off)
|
|||
X86CPU.prototype.modEAWord = function(seg, off)
|
||||
{
|
||||
this.segEA = seg;
|
||||
this.regEAWrite = this.regEA = seg.checkRead(this.offEA = off, this.dataSize-1);
|
||||
this.regEAWrite = this.regEA = seg.checkRead(this.offEA = off, (I386? this.dataSize-1 : 1));
|
||||
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
|
||||
var w = this.opMem.getWord(this.regEA);
|
||||
var w = I386? this.opMem.getWord(this.regEA) : this.getShort(this.regEA);
|
||||
if (BACKTRACK) {
|
||||
this.backTrack.btiEALo = this.backTrack.btiMemLo;
|
||||
this.backTrack.btiEAHi = this.backTrack.btiMemHi;
|
||||
|
|
@ -2086,7 +2099,7 @@ X86CPU.prototype.getEAByteData = function(off)
|
|||
{
|
||||
// return this.getEAByte(this.segData, off & this.addrMask);
|
||||
this.segEA = this.segData;
|
||||
this.regEA = this.segData.checkRead(this.offEA = off & this.addrMask, 0);
|
||||
this.regEA = this.segData.checkRead(this.offEA = off & (I386? this.addrMask : 0xffff), 0);
|
||||
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
|
||||
var b = this.getByte(this.regEA);
|
||||
if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiMemLo;
|
||||
|
|
@ -2104,7 +2117,7 @@ X86CPU.prototype.getEAByteStack = function(off)
|
|||
{
|
||||
// return this.getEAByte(this.segStack, off & this.addrMask);
|
||||
this.segEA = this.segStack;
|
||||
this.regEA = this.segStack.checkRead(this.offEA = off & this.addrMask, 0);
|
||||
this.regEA = this.segStack.checkRead(this.offEA = off & (I386? this.addrMask : 0xffff), 0);
|
||||
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
|
||||
var b = this.getByte(this.regEA);
|
||||
if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiMemLo;
|
||||
|
|
@ -2122,9 +2135,9 @@ X86CPU.prototype.getEAWordData = function(off)
|
|||
{
|
||||
// return this.getEAWord(this.segData, off & this.addrMask);
|
||||
this.segEA = this.segData;
|
||||
this.regEA = this.segData.checkRead(this.offEA = off & this.addrMask, this.dataSize-1);
|
||||
this.regEA = this.segData.checkRead(this.offEA = off & (I386? this.addrMask : 0xffff), (I386? this.dataSize-1 : 1));
|
||||
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
|
||||
var w = this.opMem.getWord(this.regEA);
|
||||
var w = I386? this.opMem.getWord(this.regEA) : this.getShort(this.regEA);
|
||||
if (BACKTRACK) {
|
||||
this.backTrack.btiEALo = this.backTrack.btiMemLo;
|
||||
this.backTrack.btiEAHi = this.backTrack.btiMemHi;
|
||||
|
|
@ -2143,9 +2156,9 @@ X86CPU.prototype.getEAWordStack = function(off)
|
|||
{
|
||||
// return this.getEAWord(this.segStack, off & this.addrMask);
|
||||
this.segEA = this.segStack;
|
||||
this.regEA = this.segStack.checkRead(this.offEA = off & this.addrMask, this.dataSize-1);
|
||||
this.regEA = this.segStack.checkRead(this.offEA = off & (I386? this.addrMask : 0xffff), (I386? this.dataSize-1 : 1));
|
||||
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
|
||||
var w = this.opMem.getWord(this.regEA);
|
||||
var w = I386? this.opMem.getWord(this.regEA) : this.getShort(this.regEA);
|
||||
if (BACKTRACK) {
|
||||
this.backTrack.btiEALo = this.backTrack.btiMemLo;
|
||||
this.backTrack.btiEAHi = this.backTrack.btiMemHi;
|
||||
|
|
@ -2164,7 +2177,7 @@ X86CPU.prototype.modEAByteData = function(off)
|
|||
{
|
||||
// return this.modEAByte(this.segData, off & this.addrMask);
|
||||
this.segEA = this.segData;
|
||||
this.regEAWrite = this.regEA = this.segData.checkRead(this.offEA = off & this.addrMask, 0);
|
||||
this.regEAWrite = this.regEA = this.segData.checkRead(this.offEA = off & (I386? this.addrMask : 0xffff), 0);
|
||||
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
|
||||
var b = this.getByte(this.regEA);
|
||||
if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiMemLo;
|
||||
|
|
@ -2182,7 +2195,7 @@ X86CPU.prototype.modEAByteStack = function(off)
|
|||
{
|
||||
// return this.modEAByte(this.segStack, off & this.addrMask);
|
||||
this.segEA = this.segStack;
|
||||
this.regEAWrite = this.regEA = this.segStack.checkRead(this.offEA = off & this.addrMask, 0);
|
||||
this.regEAWrite = this.regEA = this.segStack.checkRead(this.offEA = off & (I386? this.addrMask : 0xffff), 0);
|
||||
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
|
||||
var b = this.getByte(this.regEA);
|
||||
if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiMemLo;
|
||||
|
|
@ -2200,9 +2213,9 @@ X86CPU.prototype.modEAWordData = function(off)
|
|||
{
|
||||
// return this.modEAWord(this.segData, off & this.addrMask);
|
||||
this.segEA = this.segData;
|
||||
this.regEAWrite = this.regEA = this.segData.checkRead(this.offEA = off & this.addrMask, this.dataSize-1);
|
||||
this.regEAWrite = this.regEA = this.segData.checkRead(this.offEA = off & (I386? this.addrMask : 0xffff), (I386? this.dataSize-1 : 1));
|
||||
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
|
||||
var w = this.opMem.getWord(this.regEA);
|
||||
var w = I386? this.opMem.getWord(this.regEA) : this.getShort(this.regEA);
|
||||
if (BACKTRACK) {
|
||||
this.backTrack.btiEALo = this.backTrack.btiMemLo;
|
||||
this.backTrack.btiEAHi = this.backTrack.btiMemHi;
|
||||
|
|
@ -2221,9 +2234,9 @@ X86CPU.prototype.modEAWordStack = function(off)
|
|||
{
|
||||
// return this.modEAWord(this.segStack, off & this.addrMask);
|
||||
this.segEA = this.segStack;
|
||||
this.regEAWrite = this.regEA = this.segStack.checkRead(this.offEA = off & this.addrMask, this.dataSize-1);
|
||||
this.regEAWrite = this.regEA = this.segStack.checkRead(this.offEA = off & (I386? this.addrMask : 0xffff), (I386? this.dataSize-1 : 1));
|
||||
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
|
||||
var w = this.opMem.getWord(this.regEA);
|
||||
var w = I386? this.opMem.getWord(this.regEA) : this.getShort(this.regEA);
|
||||
if (BACKTRACK) {
|
||||
this.backTrack.btiEALo = this.backTrack.btiMemLo;
|
||||
this.backTrack.btiEAHi = this.backTrack.btiMemHi;
|
||||
|
|
@ -2257,7 +2270,11 @@ X86CPU.prototype.setEAWord = function(w)
|
|||
this.backTrack.btiMemLo = this.backTrack.btiEALo;
|
||||
this.backTrack.btiMemHi = this.backTrack.btiEAHi;
|
||||
}
|
||||
this.opMem.setWord(this.segEA.checkWrite(this.offEA, this.dataSize-1), w);
|
||||
if (!I386) {
|
||||
this.setShort(this.segEA.checkWrite(this.offEA, 1), w);
|
||||
} else {
|
||||
this.opMem.setWord(this.segEA.checkWrite(this.offEA, this.dataSize-1), w);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2287,7 +2304,11 @@ X86CPU.prototype.getSOByte = function(seg, off)
|
|||
*/
|
||||
X86CPU.prototype.getSOWord = function(seg, off)
|
||||
{
|
||||
return this.opMem.getWord(seg.checkRead(off, this.dataSize-1));
|
||||
if (!I386) {
|
||||
return this.getShort(seg.checkRead(off, 1));
|
||||
} else {
|
||||
return this.opMem.getWord(seg.checkRead(off, this.dataSize-1));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2317,7 +2338,11 @@ X86CPU.prototype.setSOByte = function(seg, off, b)
|
|||
*/
|
||||
X86CPU.prototype.setSOWord = function(seg, off, w)
|
||||
{
|
||||
this.opMem.setWord(seg.checkWrite(off, this.dataSize-1), w);
|
||||
if (!I386) {
|
||||
this.setShort(seg.checkWrite(off, 1), w);
|
||||
} else {
|
||||
this.opMem.setWord(seg.checkWrite(off, this.dataSize-1), w);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2460,7 +2485,7 @@ X86CPU.prototype.getIPByte = function()
|
|||
{
|
||||
var b = (PREFETCH? this.getBytePrefetch(this.regLIP) : this.getByte(this.regLIP));
|
||||
if (BACKTRACK) this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMemLo);
|
||||
this.regLIP = this.segCS.base + (this.regEIP = (this.regEIP + 1) & this.addrMask);
|
||||
this.regLIP = this.segCS.base + (this.regEIP = (this.regEIP + 1) & (I386? this.addrMask : 0xffff));
|
||||
return b;
|
||||
};
|
||||
|
||||
|
|
@ -2474,8 +2499,8 @@ X86CPU.prototype.getIPDisp = function()
|
|||
{
|
||||
var b = ((PREFETCH? this.getBytePrefetch(this.regLIP) : this.getByte(this.regLIP)) << 24) >> 24;
|
||||
if (BACKTRACK) this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMemLo);
|
||||
this.regLIP = this.segCS.base + (this.regEIP = (this.regEIP + 1) & this.addrMask);
|
||||
return b & this.addrMask;
|
||||
this.regLIP = this.segCS.base + (this.regEIP = (this.regEIP + 1) & (I386? this.addrMask : 0xffff));
|
||||
return b & (I386? this.addrMask : 0xffff);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2486,12 +2511,12 @@ X86CPU.prototype.getIPDisp = function()
|
|||
*/
|
||||
X86CPU.prototype.getIPWord = function()
|
||||
{
|
||||
var w = (PREFETCH? this.getWordPrefetch(this.regLIP) : this.opMem.getWord(this.regLIP));
|
||||
var w = (PREFETCH? this.getWordPrefetch(this.regLIP) : (I386? this.opMem.getWord(this.regLIP) : this.getShort(this.regLIP)));
|
||||
if (BACKTRACK) {
|
||||
this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMemLo);
|
||||
this.bus.updateBackTrackCode(this.regLIP + 1, this.backTrack.btiMemHi);
|
||||
}
|
||||
this.regLIP = this.segCS.base + (this.regEIP = (this.regEIP + this.dataSize) & this.addrMask);
|
||||
this.regLIP = this.segCS.base + (this.regEIP = (this.regEIP + (I386? this.dataSize : 2)) & (I386? this.addrMask : 0xffff));
|
||||
return w;
|
||||
};
|
||||
|
||||
|
|
@ -2518,7 +2543,7 @@ X86CPU.prototype.getSIBAddr = function(mod)
|
|||
X86CPU.prototype.popWord = function()
|
||||
{
|
||||
var regESP = this.regESP;
|
||||
this.regESP = (this.regESP + this.dataSize) & this.addrMask;
|
||||
this.regESP = (this.regESP + (I386? this.dataSize : 2)) & (I386? this.addrMask : 0xffff);
|
||||
return this.getSOWord(this.segSS, regESP);
|
||||
};
|
||||
|
||||
|
|
@ -2531,7 +2556,7 @@ X86CPU.prototype.popWord = function()
|
|||
X86CPU.prototype.pushWord = function(w)
|
||||
{
|
||||
this.assert((w & this.dataMask) == w);
|
||||
this.setSOWord(this.segSS, (this.regESP = (this.regESP - this.dataSize) & this.addrMask), w);
|
||||
this.setSOWord(this.segSS, (this.regESP = (this.regESP - (I386? this.dataSize : 2)) & (I386? this.addrMask : 0xffff)), w);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2823,7 +2848,6 @@ X86CPU.prototype.stepCPU = function(nMinCycles)
|
|||
this.addrSize = this.segCS.addrSize;
|
||||
this.addrMask = this.segCS.addrMask;
|
||||
this.opMem = this.aaOpMem[this.dataSize];
|
||||
this.opMod = this.aaOpMod[this.addrSize];
|
||||
}
|
||||
|
||||
this.opPrefixes = this.opFlags & X86.OPFLAG.REPEAT;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
8442
modules/pcjs/lib/x86modb16.js
Normal file
8442
modules/pcjs/lib/x86modb16.js
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
9333
modules/pcjs/lib/x86modw16.js
Normal file
9333
modules/pcjs/lib/x86modw16.js
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -49,7 +49,7 @@ var X86Op0F = {
|
|||
if ((bModRM & 0x38) < 0x10) { // possible reg values: 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
|
||||
this.opFlags |= X86.OPFLAG.NOREAD;
|
||||
}
|
||||
this.opMod.aOpModGrpWord[bModRM].call(this, this.aOpGrp6, X86Grps.opGrpNoSrc);
|
||||
this.aOpModGrpWord[bModRM].call(this, this.aOpGrp6, X86Grps.opGrpNoSrc);
|
||||
},
|
||||
/**
|
||||
* @this {X86CPU}
|
||||
|
|
@ -61,7 +61,7 @@ var X86Op0F = {
|
|||
if (!(bModRM & 0x10)) {
|
||||
this.opFlags |= X86.OPFLAG.NOREAD;
|
||||
}
|
||||
this.opMod.aOpModGrpWord[bModRM].call(this, X86Op0F.aOpGrp7, X86Grps.opGrpNoSrc);
|
||||
this.aOpModGrpWord[bModRM].call(this, X86Op0F.aOpGrp7, X86Grps.opGrpNoSrc);
|
||||
},
|
||||
/**
|
||||
* @this {X86CPU}
|
||||
|
|
@ -69,7 +69,7 @@ var X86Op0F = {
|
|||
* op=0x0F,0x02 (lar reg,rm)
|
||||
*/
|
||||
opLAR: function() {
|
||||
this.opMod.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpLAR);
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpLAR);
|
||||
},
|
||||
/**
|
||||
* @this {X86CPU}
|
||||
|
|
@ -77,7 +77,7 @@ var X86Op0F = {
|
|||
* op=0x0F,0x03 (lsl reg,rm)
|
||||
*/
|
||||
opLSL: function() {
|
||||
this.opMod.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpLSL);
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpLSL);
|
||||
},
|
||||
/**
|
||||
* opLOADALL()
|
||||
|
|
|
|||
|
|
@ -53,8 +53,8 @@ var X86OpXX = {
|
|||
* 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.
|
||||
*/
|
||||
if (DEBUG && !b) this.stopCPU();
|
||||
this.opMod.aOpModMemByte[b].call(this, X86Grps.opGrpADDb);
|
||||
if (DEBUG && DEBUGGER && !b) this.stopCPU();
|
||||
this.aOpModMemByte[b].call(this, X86Grps.opGrpADDb);
|
||||
},
|
||||
/**
|
||||
* op=0x01 (ADD word,reg)
|
||||
|
|
@ -62,7 +62,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opADDmw: function() {
|
||||
this.opMod.aOpModMemWord[this.getIPByte()].call(this, X86Grps.opGrpADDw);
|
||||
this.aOpModMemWord[this.getIPByte()].call(this, X86Grps.opGrpADDw);
|
||||
},
|
||||
/**
|
||||
* op=0x02 (ADD reg,byte)
|
||||
|
|
@ -70,7 +70,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opADDrb: function() {
|
||||
this.opMod.aOpModRegByte[this.getIPByte()].call(this, X86Grps.opGrpADDb);
|
||||
this.aOpModRegByte[this.getIPByte()].call(this, X86Grps.opGrpADDb);
|
||||
},
|
||||
/**
|
||||
* op=0x03 (ADD reg,word)
|
||||
|
|
@ -78,7 +78,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opADDrw: function() {
|
||||
this.opMod.aOpModRegWord[this.getIPByte()].call(this, X86Grps.opGrpADDw);
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86Grps.opGrpADDw);
|
||||
},
|
||||
/**
|
||||
* op=0x04 (ADD AL,imm8)
|
||||
|
|
@ -139,7 +139,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opORmb: function() {
|
||||
this.opMod.aOpModMemByte[this.getIPByte()].call(this, X86Grps.opGrpORb);
|
||||
this.aOpModMemByte[this.getIPByte()].call(this, X86Grps.opGrpORb);
|
||||
},
|
||||
/**
|
||||
* op=0x09 (OR word,reg)
|
||||
|
|
@ -147,7 +147,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opORmw: function() {
|
||||
this.opMod.aOpModMemWord[this.getIPByte()].call(this, X86Grps.opGrpORw);
|
||||
this.aOpModMemWord[this.getIPByte()].call(this, X86Grps.opGrpORw);
|
||||
},
|
||||
/**
|
||||
* op=0x0A (OR reg,byte)
|
||||
|
|
@ -155,7 +155,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opORrb: function() {
|
||||
this.opMod.aOpModRegByte[this.getIPByte()].call(this, X86Grps.opGrpORb);
|
||||
this.aOpModRegByte[this.getIPByte()].call(this, X86Grps.opGrpORb);
|
||||
},
|
||||
/**
|
||||
* op=0x0B (OR reg,word)
|
||||
|
|
@ -163,7 +163,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opORrw: function() {
|
||||
this.opMod.aOpModRegWord[this.getIPByte()].call(this, X86Grps.opGrpORw);
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86Grps.opGrpORw);
|
||||
},
|
||||
/**
|
||||
* op=0x0C (OR AL,imm8)
|
||||
|
|
@ -227,7 +227,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opADCmb: function() {
|
||||
this.opMod.aOpModMemByte[this.getIPByte()].call(this, X86Grps.opGrpADCb);
|
||||
this.aOpModMemByte[this.getIPByte()].call(this, X86Grps.opGrpADCb);
|
||||
},
|
||||
/**
|
||||
* op=0x11 (ADC word,reg)
|
||||
|
|
@ -235,7 +235,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opADCmw: function() {
|
||||
this.opMod.aOpModMemWord[this.getIPByte()].call(this, X86Grps.opGrpADCw);
|
||||
this.aOpModMemWord[this.getIPByte()].call(this, X86Grps.opGrpADCw);
|
||||
},
|
||||
/**
|
||||
* op=0x12 (ADC reg,byte)
|
||||
|
|
@ -243,7 +243,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opADCrb: function() {
|
||||
this.opMod.aOpModRegByte[this.getIPByte()].call(this, X86Grps.opGrpADCb);
|
||||
this.aOpModRegByte[this.getIPByte()].call(this, X86Grps.opGrpADCb);
|
||||
},
|
||||
/**
|
||||
* op=0x13 (ADC reg,word)
|
||||
|
|
@ -251,7 +251,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opADCrw: function() {
|
||||
this.opMod.aOpModRegWord[this.getIPByte()].call(this, X86Grps.opGrpADCw);
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86Grps.opGrpADCw);
|
||||
},
|
||||
/**
|
||||
* op=0x14 (ADC AL,imm8)
|
||||
|
|
@ -307,7 +307,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opSBBmb: function() {
|
||||
this.opMod.aOpModMemByte[this.getIPByte()].call(this, X86Grps.opGrpSBBb);
|
||||
this.aOpModMemByte[this.getIPByte()].call(this, X86Grps.opGrpSBBb);
|
||||
},
|
||||
/**
|
||||
* op=0x19 (SBB word,reg)
|
||||
|
|
@ -315,7 +315,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opSBBmw: function() {
|
||||
this.opMod.aOpModMemWord[this.getIPByte()].call(this, X86Grps.opGrpSBBw);
|
||||
this.aOpModMemWord[this.getIPByte()].call(this, X86Grps.opGrpSBBw);
|
||||
},
|
||||
/**
|
||||
* op=0x1A (SBB reg,byte)
|
||||
|
|
@ -323,7 +323,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opSBBrb: function() {
|
||||
this.opMod.aOpModRegByte[this.getIPByte()].call(this, X86Grps.opGrpSBBb);
|
||||
this.aOpModRegByte[this.getIPByte()].call(this, X86Grps.opGrpSBBb);
|
||||
},
|
||||
/**
|
||||
* op=0x1B (SBB reg,word)
|
||||
|
|
@ -331,7 +331,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opSBBrw: function() {
|
||||
this.opMod.aOpModRegWord[this.getIPByte()].call(this, X86Grps.opGrpSBBw);
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86Grps.opGrpSBBw);
|
||||
},
|
||||
/**
|
||||
* op=0x1C (SBB AL,imm8)
|
||||
|
|
@ -387,7 +387,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opANDmb: function() {
|
||||
this.opMod.aOpModMemByte[this.getIPByte()].call(this, X86Grps.opGrpANDb);
|
||||
this.aOpModMemByte[this.getIPByte()].call(this, X86Grps.opGrpANDb);
|
||||
},
|
||||
/**
|
||||
* op=0x21 (AND word,reg)
|
||||
|
|
@ -395,7 +395,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opANDmw: function() {
|
||||
this.opMod.aOpModMemWord[this.getIPByte()].call(this, X86Grps.opGrpANDw);
|
||||
this.aOpModMemWord[this.getIPByte()].call(this, X86Grps.opGrpANDw);
|
||||
},
|
||||
/**
|
||||
* op=0x22 (AND reg,byte)
|
||||
|
|
@ -403,7 +403,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opANDrb: function() {
|
||||
this.opMod.aOpModRegByte[this.getIPByte()].call(this, X86Grps.opGrpANDb);
|
||||
this.aOpModRegByte[this.getIPByte()].call(this, X86Grps.opGrpANDb);
|
||||
},
|
||||
/**
|
||||
* op=0x23 (AND reg,word)
|
||||
|
|
@ -411,7 +411,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opANDrw: function() {
|
||||
this.opMod.aOpModRegWord[this.getIPByte()].call(this, X86Grps.opGrpANDw);
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86Grps.opGrpANDw);
|
||||
},
|
||||
/**
|
||||
* op=0x24 (AND AL,imm8)
|
||||
|
|
@ -486,7 +486,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opSUBmb: function() {
|
||||
this.opMod.aOpModMemByte[this.getIPByte()].call(this, X86Grps.opGrpSUBb);
|
||||
this.aOpModMemByte[this.getIPByte()].call(this, X86Grps.opGrpSUBb);
|
||||
},
|
||||
/**
|
||||
* op=0x29 (SUB word,reg)
|
||||
|
|
@ -494,7 +494,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opSUBmw: function() {
|
||||
this.opMod.aOpModMemWord[this.getIPByte()].call(this, X86Grps.opGrpSUBw);
|
||||
this.aOpModMemWord[this.getIPByte()].call(this, X86Grps.opGrpSUBw);
|
||||
},
|
||||
/**
|
||||
* op=0x2A (SUB reg,byte)
|
||||
|
|
@ -502,7 +502,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opSUBrb: function() {
|
||||
this.opMod.aOpModRegByte[this.getIPByte()].call(this, X86Grps.opGrpSUBb);
|
||||
this.aOpModRegByte[this.getIPByte()].call(this, X86Grps.opGrpSUBb);
|
||||
},
|
||||
/**
|
||||
* op=0x2B (SUB reg,word)
|
||||
|
|
@ -510,7 +510,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opSUBrw: function() {
|
||||
this.opMod.aOpModRegWord[this.getIPByte()].call(this, X86Grps.opGrpSUBw);
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86Grps.opGrpSUBw);
|
||||
},
|
||||
/**
|
||||
* op=0x2C (SUB AL,imm8)
|
||||
|
|
@ -585,7 +585,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opXORmb: function() {
|
||||
this.opMod.aOpModMemByte[this.getIPByte()].call(this, X86Grps.opGrpXORb);
|
||||
this.aOpModMemByte[this.getIPByte()].call(this, X86Grps.opGrpXORb);
|
||||
},
|
||||
/**
|
||||
* op=0x31 (XOR word,reg)
|
||||
|
|
@ -593,7 +593,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opXORmw: function() {
|
||||
this.opMod.aOpModMemWord[this.getIPByte()].call(this, X86Grps.opGrpXORw);
|
||||
this.aOpModMemWord[this.getIPByte()].call(this, X86Grps.opGrpXORw);
|
||||
},
|
||||
/**
|
||||
* op=0x32 (XOR reg,byte)
|
||||
|
|
@ -601,7 +601,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opXORrb: function() {
|
||||
this.opMod.aOpModRegByte[this.getIPByte()].call(this, X86Grps.opGrpXORb);
|
||||
this.aOpModRegByte[this.getIPByte()].call(this, X86Grps.opGrpXORb);
|
||||
},
|
||||
/**
|
||||
* op=0x33 (XOR reg,word)
|
||||
|
|
@ -609,7 +609,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opXORrw: function() {
|
||||
this.opMod.aOpModRegWord[this.getIPByte()].call(this, X86Grps.opGrpXORw);
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86Grps.opGrpXORw);
|
||||
},
|
||||
/**
|
||||
* op=0x34 (XOR AL,imm8)
|
||||
|
|
@ -684,7 +684,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opCMPmb: function() {
|
||||
this.opMod.aOpModMemByte[this.getIPByte()].call(this, X86Grps.opGrpCMPb);
|
||||
this.aOpModMemByte[this.getIPByte()].call(this, X86Grps.opGrpCMPb);
|
||||
},
|
||||
/**
|
||||
* op=0x39 (CMP word,reg)
|
||||
|
|
@ -692,7 +692,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opCMPmw: function() {
|
||||
this.opMod.aOpModMemWord[this.getIPByte()].call(this, X86Grps.opGrpCMPw);
|
||||
this.aOpModMemWord[this.getIPByte()].call(this, X86Grps.opGrpCMPw);
|
||||
},
|
||||
/**
|
||||
* op=0x3A (CMP reg,byte)
|
||||
|
|
@ -700,7 +700,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opCMPrb: function() {
|
||||
this.opMod.aOpModRegByte[this.getIPByte()].call(this, X86Grps.opGrpCMPb);
|
||||
this.aOpModRegByte[this.getIPByte()].call(this, X86Grps.opGrpCMPb);
|
||||
},
|
||||
/**
|
||||
* op=0x3B (CMP reg,word)
|
||||
|
|
@ -708,7 +708,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opCMPrw: function() {
|
||||
this.opMod.aOpModRegWord[this.getIPByte()].call(this, X86Grps.opGrpCMPw);
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86Grps.opGrpCMPw);
|
||||
},
|
||||
/**
|
||||
* op=0x3C (CMP AL,imm8)
|
||||
|
|
@ -1249,7 +1249,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opBOUND: function() {
|
||||
this.opMod.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpBOUND);
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpBOUND);
|
||||
},
|
||||
/**
|
||||
* op=0x63 (ARPL word,reg) (80286 and up)
|
||||
|
|
@ -1257,7 +1257,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opARPL: function() {
|
||||
this.opMod.aOpModMemWord[this.getIPByte()].call(this, X86Help.opHelpARPL);
|
||||
this.aOpModMemWord[this.getIPByte()].call(this, X86Help.opHelpARPL);
|
||||
},
|
||||
/**
|
||||
* op=0x66 (OS:) (80386 and up)
|
||||
|
|
@ -1267,11 +1267,13 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opOS: function() {
|
||||
this.opFlags |= X86.OPFLAG.SEG;
|
||||
this.dataSize ^= 0x6; // that which is 2 shall become 4, and vice versa
|
||||
this.dataMask ^= 0xffff0000; // that which is 0x0000ffff shall become 0xffffffff, and vice versa
|
||||
this.opMem = this.aaOpMem[this.dataSize];
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesPrefix;
|
||||
if (I386) {
|
||||
this.opFlags |= X86.OPFLAG.SEG;
|
||||
this.dataSize ^= 0x6; // that which is 2 shall become 4, and vice versa
|
||||
this.dataMask ^= 0xffff0000; // that which is 0x0000ffff shall become 0xffffffff, and vice versa
|
||||
this.opMem = this.aaOpMem[this.dataSize];
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesPrefix;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* op=0x67 (AS:) (80386 and up)
|
||||
|
|
@ -1281,11 +1283,13 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opAS: function() {
|
||||
this.opFlags |= X86.OPFLAG.SEG;
|
||||
this.addrSize ^= 0x06; // that which is 2 shall become 4, and vice versa
|
||||
this.addrMask ^= 0xffff0000; // that which is 0x0000ffff shall become 0xffffffff, and vice versa
|
||||
this.opMod = this.aaOpMod[this.addrSize];
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesPrefix;
|
||||
if (I386) {
|
||||
this.opFlags |= X86.OPFLAG.SEG;
|
||||
this.addrSize ^= 0x06; // that which is 2 shall become 4, and vice versa
|
||||
this.addrMask ^= 0xffff0000; // that which is 0x0000ffff shall become 0xffffffff, and vice versa
|
||||
this.setOpMod();
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesPrefix;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* op=0x68 (PUSH imm16) (80186/80188 and up)
|
||||
|
|
@ -1302,7 +1306,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opIMUL16: function() {
|
||||
this.opMod.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpIMUL16);
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpIMUL16);
|
||||
},
|
||||
/**
|
||||
* op=0x6A (PUSH imm8) (80186/80188 and up)
|
||||
|
|
@ -1320,7 +1324,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opIMUL8: function() {
|
||||
this.opMod.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpIMUL8);
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpIMUL8);
|
||||
},
|
||||
/**
|
||||
* op=0x6C (INSB) (80186/80188 and up)
|
||||
|
|
@ -1743,7 +1747,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opGrp1b: function() {
|
||||
this.opMod.aOpModGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrp1b, this.getIPByte);
|
||||
this.aOpModGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrp1b, this.getIPByte);
|
||||
this.nStepCycles -= (this.regEAWrite < 0? 1 : this.CYCLES.nOpCyclesArithMID);
|
||||
},
|
||||
/**
|
||||
|
|
@ -1752,7 +1756,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opGrp1w: function() {
|
||||
this.opMod.aOpModGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp1w, this.getIPWord);
|
||||
this.aOpModGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp1w, this.getIPWord);
|
||||
this.nStepCycles -= (this.regEAWrite < 0? 1 : this.CYCLES.nOpCyclesArithMID);
|
||||
},
|
||||
/**
|
||||
|
|
@ -1761,7 +1765,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opGrp1sw: function() {
|
||||
this.opMod.aOpModGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp1w, this.getIPDisp);
|
||||
this.aOpModGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp1w, this.getIPDisp);
|
||||
this.nStepCycles -= (this.regEAWrite < 0? 1 : this.CYCLES.nOpCyclesArithMID);
|
||||
},
|
||||
/**
|
||||
|
|
@ -1770,7 +1774,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opTESTrb: function() {
|
||||
this.opMod.aOpModMemByte[this.getIPByte()].call(this, X86Help.opHelpTESTb);
|
||||
this.aOpModMemByte[this.getIPByte()].call(this, X86Help.opHelpTESTb);
|
||||
},
|
||||
/**
|
||||
* op=0x85 (TEST reg,word)
|
||||
|
|
@ -1778,7 +1782,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opTESTrw: function() {
|
||||
this.opMod.aOpModMemWord[this.getIPByte()].call(this, X86Help.opHelpTESTw);
|
||||
this.aOpModMemWord[this.getIPByte()].call(this, X86Help.opHelpTESTw);
|
||||
},
|
||||
/**
|
||||
* op=0x86 (XCHG reg,byte)
|
||||
|
|
@ -1807,7 +1811,7 @@ var X86OpXX = {
|
|||
* this.regEDX = (this.regEDX & 0xff) | (b << 8);
|
||||
* }
|
||||
*/
|
||||
this.opMod.aOpModRegByte[this.bModRM = this.getIPByte()].call(this, X86Help.opHelpXCHGrb);
|
||||
this.aOpModRegByte[this.bModRM = this.getIPByte()].call(this, X86Help.opHelpXCHGrb);
|
||||
},
|
||||
/**
|
||||
* op=0x87 (XCHG reg,word)
|
||||
|
|
@ -1818,7 +1822,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opXCHGrw: function() {
|
||||
this.opMod.aOpModRegWord[this.bModRM = this.getIPByte()].call(this, X86Help.opHelpXCHGrw);
|
||||
this.aOpModRegWord[this.bModRM = this.getIPByte()].call(this, X86Help.opHelpXCHGrw);
|
||||
},
|
||||
/**
|
||||
* op=0x88 (MOV byte,reg)
|
||||
|
|
@ -1830,7 +1834,7 @@ var X86OpXX = {
|
|||
* Like other MOV operations, the destination does not need to be read, just written.
|
||||
*/
|
||||
this.opFlags |= X86.OPFLAG.NOREAD;
|
||||
this.opMod.aOpModMemByte[this.getIPByte()].call(this, X86Help.opHelpMOV);
|
||||
this.aOpModMemByte[this.getIPByte()].call(this, X86Help.opHelpMOV);
|
||||
},
|
||||
/**
|
||||
* op=0x89 (MOV word,reg)
|
||||
|
|
@ -1842,7 +1846,7 @@ var X86OpXX = {
|
|||
* Like other MOV operations, the destination does not need to be read, just written.
|
||||
*/
|
||||
this.opFlags |= X86.OPFLAG.NOREAD;
|
||||
this.opMod.aOpModMemWord[this.getIPByte()].call(this, X86Help.opHelpMOV);
|
||||
this.aOpModMemWord[this.getIPByte()].call(this, X86Help.opHelpMOV);
|
||||
},
|
||||
/**
|
||||
* op=0x8A (MOV reg,byte)
|
||||
|
|
@ -1850,7 +1854,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opMOVrb: function() {
|
||||
this.opMod.aOpModRegByte[this.getIPByte()].call(this, X86Help.opHelpMOV);
|
||||
this.aOpModRegByte[this.getIPByte()].call(this, X86Help.opHelpMOV);
|
||||
},
|
||||
/**
|
||||
* op=0x8B (MOV reg,word)
|
||||
|
|
@ -1858,7 +1862,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opMOVrw: function() {
|
||||
this.opMod.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpMOV);
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpMOV);
|
||||
},
|
||||
/**
|
||||
* op=0x8C (MOV word,sr)
|
||||
|
|
@ -1893,7 +1897,7 @@ var X86OpXX = {
|
|||
* Like other MOV operations, the destination does not need to be read, just written.
|
||||
*/
|
||||
this.opFlags |= X86.OPFLAG.NOREAD;
|
||||
this.opMod.aOpModMemWord[bModRM].call(this, X86Help.opHelpMOVSegSrc);
|
||||
this.aOpModMemWord[bModRM].call(this, X86Help.opHelpMOVSegSrc);
|
||||
},
|
||||
/**
|
||||
* op=0x8D (LEA reg,word)
|
||||
|
|
@ -1903,7 +1907,7 @@ var X86OpXX = {
|
|||
opLEA: function() {
|
||||
this.opFlags |= X86.OPFLAG.NOREAD;
|
||||
this.segData = this.segStack = this.segNULL; // we can't have the EA calculation, if any, "polluted" by segment arithmetic
|
||||
this.opMod.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpLEA);
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpLEA);
|
||||
},
|
||||
/**
|
||||
* op=0x8E (MOV sr,word)
|
||||
|
|
@ -1954,7 +1958,7 @@ var X86OpXX = {
|
|||
}
|
||||
break;
|
||||
}
|
||||
this.opMod.aOpModRegWord[bModRM].call(this, X86Help.opHelpMOV);
|
||||
this.aOpModRegWord[bModRM].call(this, X86Help.opHelpMOV);
|
||||
switch (reg) {
|
||||
case 0x0:
|
||||
this.setES(this.regEAX);
|
||||
|
|
@ -2002,7 +2006,7 @@ var X86OpXX = {
|
|||
* Like other MOV operations, the destination does not need to be read, just written.
|
||||
*/
|
||||
this.opFlags |= X86.OPFLAG.NOREAD;
|
||||
this.opMod.aOpModGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrpPOPw, this.popWord);
|
||||
this.aOpModGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrpPOPw, this.popWord);
|
||||
},
|
||||
/**
|
||||
* op=0x90 (NOP, aka XCHG AX,AX)
|
||||
|
|
@ -2892,7 +2896,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opGrp2bi: function() {
|
||||
this.opMod.aOpModGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrp2b, X86Grps.opGrp2CountImm);
|
||||
this.aOpModGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrp2b, X86Grps.opGrp2CountImm);
|
||||
},
|
||||
/**
|
||||
* op=0xC1 (GRP2 word,imm16) (80186/80188 and up)
|
||||
|
|
@ -2900,7 +2904,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opGrp2wi: function() {
|
||||
this.opMod.aOpModGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp2w, X86Grps.opGrp2CountImm);
|
||||
this.aOpModGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp2w, X86Grps.opGrp2CountImm);
|
||||
},
|
||||
/**
|
||||
* op=0xC2 (RET n)
|
||||
|
|
@ -2931,7 +2935,7 @@ var X86OpXX = {
|
|||
/*
|
||||
* This is like a "MOV reg,rm" operation, but it also loads ES from the next word.
|
||||
*/
|
||||
this.opMod.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpLES);
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpLES);
|
||||
},
|
||||
/**
|
||||
* op=0xC5 (LDS reg,word)
|
||||
|
|
@ -2942,7 +2946,7 @@ var X86OpXX = {
|
|||
/*
|
||||
* This is like a "MOV reg,rm" operation, but it also loads DS from the next word.
|
||||
*/
|
||||
this.opMod.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpLDS);
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpLDS);
|
||||
},
|
||||
/**
|
||||
* op=0xC6 (MOV byte,imm8)
|
||||
|
|
@ -2954,7 +2958,7 @@ var X86OpXX = {
|
|||
* Like other MOV operations, the destination does not need to be read, just written.
|
||||
*/
|
||||
this.opFlags |= X86.OPFLAG.NOREAD;
|
||||
this.opMod.aOpModGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrpMOVImm, this.getIPByte);
|
||||
this.aOpModGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrpMOVImm, this.getIPByte);
|
||||
},
|
||||
/**
|
||||
* op=0xC7 (MOV word,imm16)
|
||||
|
|
@ -2966,7 +2970,7 @@ var X86OpXX = {
|
|||
* Like other MOV operations, the destination does not need to be read, just written.
|
||||
*/
|
||||
this.opFlags |= X86.OPFLAG.NOREAD;
|
||||
this.opMod.aOpModGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrpMOVImm, this.getIPWord);
|
||||
this.aOpModGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrpMOVImm, this.getIPWord);
|
||||
},
|
||||
/**
|
||||
* op=0xC8 (ENTER imm16,imm8) (80186/80188 and up)
|
||||
|
|
@ -3093,7 +3097,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opGrp2b1: function() {
|
||||
this.opMod.aOpModGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrp2b, X86Grps.opGrp2Count1);
|
||||
this.aOpModGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrp2b, X86Grps.opGrp2Count1);
|
||||
},
|
||||
/**
|
||||
* op=0xD1 (GRP2 word,1)
|
||||
|
|
@ -3101,7 +3105,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opGrp2w1: function() {
|
||||
this.opMod.aOpModGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp2w, X86Grps.opGrp2Count1);
|
||||
this.aOpModGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp2w, X86Grps.opGrp2Count1);
|
||||
},
|
||||
/**
|
||||
* op=0xD2 (GRP2 byte,CL)
|
||||
|
|
@ -3109,7 +3113,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opGrp2bCL: function() {
|
||||
this.opMod.aOpModGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrp2b, X86Grps.opGrp2CountCL);
|
||||
this.aOpModGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrp2b, X86Grps.opGrp2CountCL);
|
||||
},
|
||||
/**
|
||||
* op=0xD3 (GRP2 word,CL)
|
||||
|
|
@ -3117,7 +3121,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opGrp2wCL: function() {
|
||||
this.opMod.aOpModGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp2w, X86Grps.opGrp2CountCL);
|
||||
this.aOpModGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp2w, X86Grps.opGrp2CountCL);
|
||||
},
|
||||
/**
|
||||
* op=0xD4 0x0A (AAM)
|
||||
|
|
@ -3196,7 +3200,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opESC: function() {
|
||||
this.opMod.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpESC);
|
||||
this.aOpModRegWord[this.getIPByte()].call(this, X86Help.opHelpESC);
|
||||
this.nStepCycles -= 8; // TODO: Fix
|
||||
},
|
||||
/**
|
||||
|
|
@ -3497,7 +3501,7 @@ var X86OpXX = {
|
|||
*/
|
||||
opGrp3b: function() {
|
||||
this.regMD16 = -1;
|
||||
this.opMod.aOpModGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrp3b, X86Grps.opGrpNoSrc);
|
||||
this.aOpModGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrp3b, X86Grps.opGrpNoSrc);
|
||||
if (this.regMD16 >= 0) this.regEAX = this.regMD16;
|
||||
},
|
||||
/**
|
||||
|
|
@ -3520,7 +3524,7 @@ var X86OpXX = {
|
|||
*/
|
||||
opGrp3w: function() {
|
||||
this.regMD16 = -1;
|
||||
this.opMod.aOpModGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp3w, X86Grps.opGrpNoSrc);
|
||||
this.aOpModGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp3w, X86Grps.opGrpNoSrc);
|
||||
if (this.regMD16 >= 0) {
|
||||
this.regEAX = this.regMD16;
|
||||
this.regEDX = this.regMD32;
|
||||
|
|
@ -3587,7 +3591,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opGrp4b: function() {
|
||||
this.opMod.aOpModGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrp4b, X86Grps.opGrpNoSrc);
|
||||
this.aOpModGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrp4b, X86Grps.opGrpNoSrc);
|
||||
},
|
||||
/**
|
||||
* op=0xFF (GRP4 word)
|
||||
|
|
@ -3595,7 +3599,7 @@ var X86OpXX = {
|
|||
* @this {X86CPU}
|
||||
*/
|
||||
opGrp4w: function() {
|
||||
this.opMod.aOpModGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp4w, X86Grps.opGrpNoSrc);
|
||||
this.aOpModGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp4w, X86Grps.opGrpNoSrc);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue