Change how optional opcode tables are built
This commit is contained in:
parent
0cbae3ea11
commit
e3a5408031
10 changed files with 145 additions and 104 deletions
92
blog/2015/03/26/README.md
Normal file
92
blog/2015/03/26/README.md
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
JavaScript Idiosyncrasies
|
||||
---
|
||||
Time to mention a few JavaScript idiosyncrasies that newcomers may not be aware of, and how I deal with them.
|
||||
|
||||
Also, see my previous posts on [PCjs Coding Conventions](/blog/2014/09/30/) and [JavaScript Negativity](/blog/2014/10/26/).
|
||||
|
||||
### Strict Equality
|
||||
|
||||
Most sites will advise you to *never* use the "==" and "!=" JavaScript operators, because when they compare variables
|
||||
containing different data types, JavaScript will coerce one of the operands to a matching type, sometimes in unexpected
|
||||
ways. We can thank the early days of JavaScript for this feature, when it was trying to be extraordinarily forgiving
|
||||
of sloppy code. I'm not going to list all the odd results that can arise from JavaScript's operand coercion, because
|
||||
there are more than enough examples on the web already.
|
||||
|
||||
To avoid unexpected coercion, and thus unexpected matches and/or mismatches, the usual advice is to *always* use
|
||||
strict equality operators instead ("===" and "!==").
|
||||
|
||||
I disagree. In properly written code, you should always know what type of data your variables contain. In fact,
|
||||
the more you're able to use JSDoc types to declare the data types of all your parameters, return values, and other
|
||||
variables, the fewer errors you'll have. And coercion will never be a problem as long as you're always comparing
|
||||
variables with matching types, because no coercion will be performed.
|
||||
|
||||
Another problem with strict equality operators is that they require more work to check for both *undefined* and *null*
|
||||
values. For example, when I write a method with optional parameters, I generally allow those parameters to either
|
||||
be omitted or set to *null*. Using "==", you can check both cases with a single comparison:
|
||||
|
||||
if (parameter == null) { ... }
|
||||
|
||||
whereas strict equality requires more work:
|
||||
|
||||
if (parameter === undefined || parameter === null) { ... }
|
||||
|
||||
This is one of the few times I think coercion (of *undefined* to *null*) is beneficial, so I rely on it.
|
||||
|
||||
When I recommend that you *not* use strict comparisons, I'm not saying that coercion is good. I agree that it
|
||||
generally should be avoided (except in situations like the last example). The point is, know your variable data
|
||||
types, only compare variables of the same type, and you'll never have to worry about coercion.
|
||||
|
||||
### Enumerating Array or Object Properties
|
||||
|
||||
When using *for*...*in* loops like this:
|
||||
|
||||
var a = [100, 200, 300];
|
||||
for (var i in a) { ... }
|
||||
|
||||
the type of variable *i* will be **string** rather than **number**; that is, it will contain "0", "1" and "2" rather
|
||||
than 0, 1 and 2. If you then use *i* to set a matching element in another array, that element will not be stored in
|
||||
the same (numeric) position as the original array.
|
||||
|
||||
One solution is to convert *i* to a **number**:
|
||||
|
||||
parseInt(i, 10);
|
||||
|
||||
However, a more elegant solution is to use the unary "+" operator to coerce the **string** to a **number**:
|
||||
|
||||
+i;
|
||||
|
||||
### Shift Counts For Bit-wise Shifts
|
||||
|
||||
It turns out that shifting an integer value by more than 31 bits in either direction may not shift as many bits as
|
||||
you'd expect. For example:
|
||||
|
||||
n = 0x10000000;
|
||||
n >>>= 32;
|
||||
|
||||
will not change n at all. This is because, just like the shift instructions on Intel processors, JavaScript converts
|
||||
the shift count to a *mod 32* value (in other words, it truncates the shift count to a 5-bit value).
|
||||
|
||||
So the above example is equivalent to:
|
||||
|
||||
n >>>= 0;
|
||||
|
||||
If you really need larger shift counts to work in a consistent manner, you can perform multiple shifts, where each
|
||||
shift count is in the range 0-31:
|
||||
|
||||
n = (n >>> 31) >>> 1;
|
||||
|
||||
Also, it's not quite correct to say that a shift count of zero has *no* effect on a value:
|
||||
|
||||
n = 0x88888888|0; // n is displayed as -2004318072
|
||||
n >>>= 0; // n is displayed as 2290649224
|
||||
|
||||
It's true that the bottom 32 bits of the value were not changed, but a side-effect of the unsigned shift operator is
|
||||
that all the upper sign bits are stripped from the (64-bit) result.
|
||||
|
||||
However, as soon as you perform another bit-wise operation on the value, even one that has no effect on the lower 32
|
||||
bits, the upper bits will once be updated to match the sign of the lower 32-bit value:
|
||||
|
||||
n |= 0; // n is displayed as -2004318072 again
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*March 26, 2015*
|
||||
|
|
@ -1316,11 +1316,7 @@ Bus.prototype.addPortInputTable = function(component, table, offset)
|
|||
{
|
||||
if (offset === undefined) offset = 0;
|
||||
for (var port in table) {
|
||||
/*
|
||||
* JavaScript coerces property keys to strings, so we use parseInt() to coerce them back to numbers.
|
||||
*/
|
||||
port = parseInt(port, 10);
|
||||
this.addPortInputNotify(port + offset, port + offset, component, table[port]);
|
||||
this.addPortInputNotify(+port + offset, +port + offset, component, table[port]);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1440,11 +1436,7 @@ Bus.prototype.addPortOutputTable = function(component, table, offset)
|
|||
{
|
||||
if (offset === undefined) offset = 0;
|
||||
for (var port in table) {
|
||||
/*
|
||||
* JavaScript converts property keys to strings (brilliant), so we use parseInt() to convert them back to numbers.
|
||||
*/
|
||||
port = parseInt(port, 10);
|
||||
this.addPortOutputNotify(port + offset, port + offset, component, table[port]);
|
||||
this.addPortOutputNotify(+port + offset, +port + offset, component, table[port]);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2187,7 +2187,7 @@ ChipSet.prototype.toggleSwitch = function(control)
|
|||
this.setSwitch(control, f);
|
||||
var sID = control.getAttribute("id");
|
||||
var asParts = sID.split("-");
|
||||
var b = (0x1 << (parseInt(asParts[1], 10) - 1));
|
||||
var b = (0x1 << (+asParts[1] - 1));
|
||||
switch (asParts[0]) {
|
||||
case "sw1":
|
||||
this.sw1Init = (this.sw1Init & ~b) | (f? 0 : b);
|
||||
|
|
@ -4795,13 +4795,16 @@ ChipSet.prototype.intBIOSRTC = function(addr)
|
|||
* parseSwitches(s, def)
|
||||
*
|
||||
* @this {ChipSet}
|
||||
* @param {string|undefined} s describing switch settings (can't simply use parseInt() with a base of 2, because the bit order is reversed, as well as the bit sense)
|
||||
* @param {string|undefined} s describing switch settings
|
||||
* @param {number} def is a default value to use if s is undefined
|
||||
* @return {number} value representing the switch settings
|
||||
*/
|
||||
ChipSet.prototype.parseSwitches = function(s, def)
|
||||
{
|
||||
if (s === undefined) return def;
|
||||
/*
|
||||
* NOTE: We can't simply use parseInt() with a base of 2, because the bit order is reversed, as well as the bit sense.
|
||||
*/
|
||||
var b = 0, bit = 0x1;
|
||||
for (var i = 0; i < s.length; i++) {
|
||||
if (s.charAt(i) == "0") b |= bit;
|
||||
|
|
|
|||
|
|
@ -187,10 +187,10 @@ function Computer(parmsComputer, parmsMachine, fSuspended) {
|
|||
var sStatePath = null;
|
||||
var sResume = parmsComputer['resume'];
|
||||
if (sResume !== undefined) {
|
||||
if (sResume.length > 1) {
|
||||
sStatePath = this.sResumePath = sResume;
|
||||
if (sResume.length == 1) {
|
||||
this.resume = +sResume;
|
||||
} else {
|
||||
this.resume = parseInt(sResume, 10);
|
||||
sStatePath = this.sResumePath = sResume;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4015,7 +4015,7 @@ if (DEBUGGER) {
|
|||
var fWords = (sCmd == "dw");
|
||||
if (sLen !== undefined) {
|
||||
if (sLen.charAt(0) == "l") sLen = sLen.substr(1);
|
||||
cLines = parseInt(sLen, 10);
|
||||
cLines = +sLen;
|
||||
if (cLines) cLines = fWords? ((cLines + 7) >> 3) : ((cLines + 15) >> 4);
|
||||
}
|
||||
if (!cLines) cLines = 8;
|
||||
|
|
@ -4061,7 +4061,7 @@ if (DEBUGGER) {
|
|||
if (aAddr[0] == null)
|
||||
return;
|
||||
for (var i = 2; i < asArgs.length; i++) {
|
||||
var b = parseInt(asArgs[i], 16);
|
||||
var b = str.parseInt(asArgs[i], 16);
|
||||
this.println("setting " + this.hexAddr(aAddr) + " to " + str.toHexByte(b));
|
||||
this.setByte(aAddr, b, 1);
|
||||
}
|
||||
|
|
@ -4133,7 +4133,7 @@ if (DEBUGGER) {
|
|||
var iHistory = this.iOpcodeHistory;
|
||||
var aHistory = this.aOpcodeHistory;
|
||||
if (aHistory.length) {
|
||||
var n = (sCount === undefined? this.nextHistory : parseInt(sCount, 10));
|
||||
var n = (sCount === undefined? this.nextHistory : +sCount);
|
||||
if (isNaN(n))
|
||||
n = cLines;
|
||||
else
|
||||
|
|
@ -4203,7 +4203,7 @@ if (DEBUGGER) {
|
|||
var fPrint = false;
|
||||
if (sCategory == "DUMP") {
|
||||
var sDump = "";
|
||||
var cLines = (sEnable === undefined? -1 : parseInt(sEnable, 10));
|
||||
var cLines = (sEnable === undefined? -1 : +sEnable);
|
||||
var i = this.iTraceBuffer;
|
||||
do {
|
||||
var s = this.aTraceBuffer[i++];
|
||||
|
|
@ -4509,9 +4509,7 @@ if (DEBUGGER) {
|
|||
switch (asArgs[1]) {
|
||||
case "cs":
|
||||
var nCycles;
|
||||
if (asArgs[3] !== undefined) {
|
||||
nCycles = parseInt(asArgs[3], 10);
|
||||
}
|
||||
if (asArgs[3] !== undefined) nCycles = +asArgs[3];
|
||||
switch (asArgs[2]) {
|
||||
case "int":
|
||||
this.cpu.aCounts.nCyclesChecksumInterval = nCycles;
|
||||
|
|
@ -4533,7 +4531,7 @@ if (DEBUGGER) {
|
|||
break;
|
||||
case "sp":
|
||||
if (asArgs[2] !== undefined) {
|
||||
this.cpu.setSpeed(parseInt(asArgs[2], 10));
|
||||
this.cpu.setSpeed(+asArgs[2]);
|
||||
}
|
||||
this.println("target speed: " + this.cpu.getSpeedTarget() + " (" + this.cpu.getSpeed() + "x)");
|
||||
break;
|
||||
|
|
@ -4610,7 +4608,7 @@ if (DEBUGGER) {
|
|||
this.println("missing value for " + asArgs[1]);
|
||||
return;
|
||||
}
|
||||
var w = parseInt(sValue, 16);
|
||||
var w = str.parseInt(sValue, 16);
|
||||
if (!isNaN(w)) {
|
||||
var sRegMatch = sReg.toUpperCase();
|
||||
if (sRegMatch.charAt(0) == 'E' && this.cchReg <= 4) {
|
||||
|
|
@ -4938,7 +4936,7 @@ if (DEBUGGER) {
|
|||
{
|
||||
var dbg = this;
|
||||
var fRegs = (sCmd == "tr");
|
||||
var count = (sCount != null? parseInt(sCount, 10) : 1);
|
||||
var count = (sCount != null? +sCount : 1);
|
||||
var nCycles = (count == 1? 0 : 1);
|
||||
web.onCountRepeat(
|
||||
count,
|
||||
|
|
|
|||
|
|
@ -1194,7 +1194,7 @@ FDC.prototype.loadSelectedDrive = function(sDisketteName, sDiskettePath, file)
|
|||
{
|
||||
var iDrive;
|
||||
var controlDrives = this.bindings["listDrives"];
|
||||
if (controlDrives && !isNaN(iDrive = parseInt(controlDrives.value, 10)) && iDrive >= 0 && iDrive < this.aDrives.length) {
|
||||
if (controlDrives && !isNaN(iDrive = str.parseInt(controlDrives.value, 10)) && iDrive >= 0 && iDrive < this.aDrives.length) {
|
||||
|
||||
if (!sDiskettePath) {
|
||||
this.unloadDrive(iDrive);
|
||||
|
|
@ -1437,7 +1437,7 @@ FDC.prototype.displayDiskette = function(iDrive, fUpdateDrive)
|
|||
* Next, make sure the drive whose disk we're updating is the currently selected drive.
|
||||
*/
|
||||
var i;
|
||||
var iDriveSelected = parseInt(controlDrives.value, 10);
|
||||
var iDriveSelected = str.parseInt(controlDrives.value, 10);
|
||||
var sTargetPath = (drive.fLocal? "?" : drive.sDiskettePath);
|
||||
if (!isNaN(iDriveSelected) && iDriveSelected == iDrive) {
|
||||
for (i = 0; i < controlDisks.options.length; i++) {
|
||||
|
|
@ -1452,7 +1452,7 @@ FDC.prototype.displayDiskette = function(iDrive, fUpdateDrive)
|
|||
}
|
||||
if (fUpdateDrive) {
|
||||
for (i = 0; i < controlDrives.options.length; i++) {
|
||||
if (parseInt(controlDrives.options[i].value, 10) == drive.iDrive) {
|
||||
if (str.parseInt(controlDrives.options[i].value, 10) == drive.iDrive) {
|
||||
if (controlDrives.selectedIndex != i) {
|
||||
controlDrives.selectedIndex = i;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1090,7 +1090,7 @@ Keyboard.prototype.findBinding = function(simCode, sType, fDown)
|
|||
if (this.cSoftCodes) {
|
||||
for (var code in Keyboard.SHIFTED_KEYCODES) {
|
||||
if (simCode == Keyboard.SHIFTED_KEYCODES[code]) {
|
||||
simCode = parseInt(code, 10);
|
||||
simCode = +code;
|
||||
code = Keyboard.STUPID_KEYCODES[code];
|
||||
if (code) simCode = code;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ ROM.prototype.onLoadROM = function(sROMFile, sROMData, nErrorCode)
|
|||
var asHexData = sHexData.split(" ");
|
||||
this.abROM = new Array(asHexData.length);
|
||||
for (var i = 0; i < asHexData.length; i++) {
|
||||
this.abROM[i] = parseInt(asHexData[i], 16);
|
||||
this.abROM[i] = str.parseInt(asHexData[i], 16);
|
||||
}
|
||||
}
|
||||
this.copyROM();
|
||||
|
|
|
|||
|
|
@ -761,13 +761,15 @@ X86CPU.prototype.initProcessor = function()
|
|||
this.aOps[X86.OPCODE.PUSHSP] = X86.opPUSHSP;
|
||||
|
||||
if (I386 && this.model >= X86.MODEL_80386) {
|
||||
var bOpcode;
|
||||
this.aOps[X86.OPCODE.FS] = X86.opFS;
|
||||
this.aOps[X86.OPCODE.GS] = X86.opGS;
|
||||
this.aOps[X86.OPCODE.OS] = X86.opOS;
|
||||
this.aOps[X86.OPCODE.AS] = X86.opAS;
|
||||
this.aOps0F = X86.aOps0F.slice();
|
||||
this.aOps0F[0x20] = X86.opMOVrcr;
|
||||
this.aOps0F[0x22] = X86.opMOVcrr;
|
||||
for (bOpcode in X86.aOps0F386) {
|
||||
this.aOps0F[+bOpcode] = X86.aOps0F386[bOpcode];
|
||||
}
|
||||
/*
|
||||
* Extend the opcode table by creating a mirror of the first 256 opcodes, but with dword-based
|
||||
* opcode handlers (as defined in aOpsD) instead word-based opcode handlers. Whenever dataSize
|
||||
|
|
@ -775,8 +777,8 @@ X86CPU.prototype.initProcessor = function()
|
|||
* bOpcodeBias from 0 to 256.
|
||||
*/
|
||||
this.aOps = this.aOps.concat(this.aOps);
|
||||
for (var bOpcode in X86.aOpsD) {
|
||||
this.aOps[parseInt(bOpcode, 10) + 256] = X86.aOpsD[bOpcode];
|
||||
for (bOpcode in X86.aOpsD) {
|
||||
this.aOps[+bOpcode + 256] = X86.aOpsD[bOpcode];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -311,76 +311,30 @@ X86.opMOVcrr = function MOVcrr()
|
|||
}
|
||||
};
|
||||
|
||||
X86.aOps0F = [
|
||||
X86.opGrp6, X86.opGrp7, X86.opLAR, X86.opLSL, // 0x00-0x03
|
||||
X86.opUndefined, X86.opLOADALL, X86.opCLTS, X86.opUndefined, // 0x04-0x07
|
||||
/*
|
||||
* On all processors (except the 8086/8088, of course), 0x0F,0x0B is also referred to as "UD2": an
|
||||
* instruction guaranteed to raise a #UD (Invalid Opcode) exception (INT 0x06) on all future x86 processors.
|
||||
*/
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opInvalid, // 0x08-0x0B
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x0C-0x0F
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x10-0x13
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x14-0x17
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x18-0x1B
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x1C-0x1F
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x20-0x23
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x24-0x27
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x28-0x2B
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x2C-0x2F
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x30-0x33
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x34-0x37
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x38-0x3B
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x3C-0x3F
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x40-0x43
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x44-0x47
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x48-0x4B
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x4C-0x4F
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x50-0x53
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x54-0x57
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x58-0x5B
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x5C-0x5F
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x60-0x63
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x64-0x67
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x68-0x6B
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x6C-0x6F
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x70-0x73
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x74-0x77
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x78-0x7B
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x7C-0x7F
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x80-0x83
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x84-0x87
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x88-0x8B
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x8C-0x8F
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x90-0x93
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x94-0x97
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x98-0x9B
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0x9C-0x9F
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xA0-0xA3
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xA4-0xA7
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xA8-0xAB
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xAC-0xAF
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xB0-0xB3
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xB4-0xB7
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xB8-0xBB
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xBC-0xBF
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xC0-0xC3
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xC4-0xC7
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xC8-0xCB
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xCC-0xCF
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xD0-0xD3
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xD4-0xD7
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xD8-0xDB
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xDC-0xDF
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xE0-0xE3
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xE4-0xE7
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xE8-0xEB
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xEC-0xEF
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xF0-0xF3
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xF4-0xF7
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined, // 0xF8-0xFB
|
||||
X86.opUndefined, X86.opUndefined, X86.opUndefined, X86.opUndefined // 0xFC-0xFF
|
||||
];
|
||||
X86.aOps0F = new Array(256);
|
||||
|
||||
X86.aOps0F[0x00] = X86.opGrp6;
|
||||
X86.aOps0F[0x01] = X86.opGrp7;
|
||||
X86.aOps0F[0x02] = X86.opLAR;
|
||||
X86.aOps0F[0x03] = X86.opLSL;
|
||||
X86.aOps0F[0x05] = X86.opLOADALL;
|
||||
X86.aOps0F[0x06] = X86.opCLTS;
|
||||
|
||||
/*
|
||||
* On all processors (except the 8086/8088, of course), 0x0F,0x0B is also referred to as "UD2": an
|
||||
* instruction guaranteed to raise a #UD (Invalid Opcode) exception (INT 0x06) on all future x86 processors.
|
||||
*/
|
||||
X86.aOps0F[0x0B] = X86.opInvalid;
|
||||
|
||||
for (var i = 0; i < X86.aOps0F.length; i++) {
|
||||
if (!X86.aOps0F[i]) X86.aOps0F[i] = X86.opUndefined;
|
||||
}
|
||||
|
||||
if (I386) {
|
||||
X86.aOps0F386 = [];
|
||||
X86.aOps0F386[0x20] = X86.opMOVrcr;
|
||||
X86.aOps0F386[0x22] = X86.opMOVcrr;
|
||||
}
|
||||
|
||||
/*
|
||||
* These instruction groups are not as orthogonal as the original 8086/8088 groups (Grp1 through Grp4): some of
|
||||
|
|
|
|||
Loading…
Reference in a new issue