Added CLTS support, TSS dumping, proper setting of the NT and IOPL flag bits, and more

This commit is contained in:
Jeff Parsons 2014-11-19 10:38:58 -08:00 committed by jeffpar
commit 2a7bc0f454
9 changed files with 312 additions and 208 deletions

View file

@ -305,6 +305,17 @@ Bus.prototype.setA20 = function(fEnable)
}
};
/**
* getWidth()
*
* @this {Bus}
* @return {number}
*/
Bus.prototype.getWidth = function()
{
return this.nBusWidth;
};
/**
* setMemoryAccess(addr, size)
*

View file

@ -80,6 +80,11 @@ function Debugger(parmsDbg)
this.nCycles = -1;
this.cInstructions = -1;
/*
* The default numder of hex characters in a physical address; updated by initBus().
*/
this.cchAddr = 5;
/*
* Most commands that require an address call parseAddr(), which defaults to aAddrNextCode
* or aAddrNextData when no address has been given. doDump() and doUnassemble(), in turn,
@ -183,31 +188,33 @@ function Debugger(parmsDbg)
*/
Debugger.MESSAGE = {
CPU: 0x00000001,
INT: 0x00000002,
SEG: 0x00000004,
FAULT: 0x00000008,
MEM: 0x00000010,
PORT: 0x00000020,
DMA: 0x00000040,
PIC: 0x00000080,
TIMER: 0x00000100,
CMOS: 0x00000200,
RTC: 0x00000400,
C8042: 0x00000800,
CHIPSET: 0x00001000,
KBD: 0x00002000,
KEYS: 0x00004000,
VIDEO: 0x00008000,
FDC: 0x00010000,
HDC: 0x00020000,
DISK: 0x00040000,
SERIAL: 0x00080000,
SPEAKER: 0x00100000,
STATE: 0x00200000,
MOUSE: 0x00400000,
COMPUTER: 0x00800000,
LOG: 0x01000000,
DOS: 0x02000000,
SEG: 0x00000002,
DESC: 0x00000004,
TSS: 0x00000008,
INT: 0x00000010,
FAULT: 0x00000020,
MEM: 0x00000040,
PORT: 0x00000080,
DMA: 0x00000100,
PIC: 0x00000200,
TIMER: 0x00000400,
CMOS: 0x00000800,
RTC: 0x00001000,
C8042: 0x00002000,
CHIPSET: 0x00004000,
KBD: 0x00008000,
KEYS: 0x00010000,
VIDEO: 0x00020000,
FDC: 0x00040000,
HDC: 0x00080000,
DISK: 0x00100000,
SERIAL: 0x00200000,
SPEAKER: 0x00400000,
STATE: 0x00800000,
MOUSE: 0x01000000,
COMPUTER: 0x02000000,
LOG: 0x04000000,
DOS: 0x08000000,
HALT: 0x80000000
};
@ -495,8 +502,10 @@ if (DEBUGGER) {
*/
Debugger.MESSAGES = {
"cpu": Debugger.MESSAGE.CPU,
"int": Debugger.MESSAGE.INT,
"seg": Debugger.MESSAGE.SEG,
"desc": Debugger.MESSAGE.DESC,
"tss": Debugger.MESSAGE.TSS,
"int": Debugger.MESSAGE.INT,
"fault": Debugger.MESSAGE.FAULT,
"mem": Debugger.MESSAGE.MEM,
"port": Debugger.MESSAGE.PORT,
@ -886,7 +895,8 @@ if (DEBUGGER) {
0x01: [Debugger.INS.GRP7, Debugger.TYPE_MODRM | Debugger.TYPE_WORD | Debugger.TYPE_BOTH],
0x02: [Debugger.INS.LAR, Debugger.TYPE_REG | Debugger.TYPE_WORD | Debugger.TYPE_IN | Debugger.TYPE_286, Debugger.TYPE_MEM | Debugger.TYPE_WORD | Debugger.TYPE_IN],
0x03: [Debugger.INS.LSL, Debugger.TYPE_REG | Debugger.TYPE_WORD | Debugger.TYPE_IN | Debugger.TYPE_286, Debugger.TYPE_MEM | Debugger.TYPE_WORD | Debugger.TYPE_IN],
0x05: [Debugger.INS.LOADALL,Debugger.TYPE_286]
0x05: [Debugger.INS.LOADALL,Debugger.TYPE_286],
0x06: [Debugger.INS.CLTS, Debugger.TYPE_286]
};
Debugger.aaGrpDescs = [
@ -1197,6 +1207,8 @@ if (DEBUGGER) {
this.hdc = cmp.getComponentByType("HDC");
if (MAXDEBUG) this.chipset = cmp.getComponentByType("ChipSet");
this.cchAddr = bus.getWidth() >> 2;
this.aaOpDescs = Debugger.aaOpDescs;
if (this.cpu.model >= X86.MODEL_80186) {
this.aaOpDescs = Debugger.aaOpDescs.slice();
@ -1206,9 +1218,8 @@ if (DEBUGGER) {
}
}
this.messageDump(Debugger.MESSAGE.DOS, function onDumpDOS(s) {
dbg.dumpDOS(s);
});
this.messageDump(Debugger.MESSAGE.TSS, function onDumpTSS(s) { dbg.dumpTSS(s); });
this.messageDump(Debugger.MESSAGE.DOS, function onDumpDOS(s) { dbg.dumpDOS(s); });
this.setReady();
@ -1320,6 +1331,8 @@ if (DEBUGGER) {
/**
* dumpDOS(s)
*
* This dumps DOS MCBs (Memory Control Blocks).
*
* @this {Debugger}
* @param {string} [s]
*/
@ -1345,6 +1358,67 @@ if (DEBUGGER) {
}
};
Debugger.aTSSFields = {
"PREV_TSS": 0x00,
"CPL0_SP": 0x02,
"CPL0_SS": 0x04,
"CPL1_SP": 0x06,
"CPL1_SS": 0x08,
"CPL2_SP": 0x0a,
"CPL2_SS": 0x0c,
"TASK_IP": 0x0e,
"TASK_PS": 0x10,
"TASK_AX": 0x12,
"TASK_CX": 0x14,
"TASK_DX": 0x16,
"TASK_BX": 0x18,
"TASK_SP": 0x1a,
"TASK_BP": 0x1c,
"TASK_SI": 0x1e,
"TASK_DI": 0x20,
"TASK_ES": 0x22,
"TASK_CS": 0x24,
"TASK_SS": 0x26,
"TASK_DS": 0x28,
"TASK_LDT": 0x2a
};
/**
* dumpTSS(s)
*
* This dumps a TSS using the given selector. If none is specified, the current TR is used.
*
* @this {Debugger}
* @param {string} [s]
*/
Debugger.prototype.dumpTSS = function(s)
{
var seg;
if (!s) {
seg = this.cpu.segTSS;
} else {
var sel = str.parseInt(s);
if (sel === undefined) {
this.println("invalid task selector: " + s);
return;
}
seg = this.getSegment(sel);
}
this.println("dumpTSS(" + str.toHexWord(seg.sel) + "): %" + str.toHex(seg.base, this.cchAddr));
var sDump = "";
for (var sField in Debugger.aTSSFields) {
var off = Debugger.aTSSFields[sField];
var ch = (sField.length < 8? ' ' : '');
var w = this.bus.getWordDirect(seg.base + off);
if (sDump) sDump += '\n';
sDump += str.toHexWord(off) + " " + sField + ": " + ch + str.toHexWord(w);
}
this.println(sDump);
};
/**
* dumpSZ(aAddr, cchMax)
*
@ -2869,7 +2943,7 @@ if (DEBUGGER) {
*/
Debugger.prototype.getSegStr = function(seg, fProt)
{
return seg.sName + '=' + str.toHexWord(seg.sel) + (fProt? '[' + str.toHex(seg.base, 6) + ',' + str.toHexWord(seg.limit) + ']' : "");
return seg.sName + '=' + str.toHexWord(seg.sel) + (fProt? '[' + str.toHex(seg.base, this.cchAddr) + ',' + str.toHexWord(seg.limit) + ']' : "");
};
/**
@ -2884,7 +2958,7 @@ if (DEBUGGER) {
*/
Debugger.prototype.getDTRStr = function(sName, sel, addr, addrLimit)
{
return sName + '=' + (sel != null? str.toHexWord(sel) : "") + '[' + str.toHex(addr, 6) + ',' + str.toHexWord(addrLimit - addr) + ']';
return sName + '=' + (sel != null? str.toHexWord(sel) : "") + '[' + str.toHex(addr, this.cchAddr) + ',' + str.toHexWord(addrLimit - addr) + ']';
};
/**
@ -3843,6 +3917,41 @@ if (DEBUGGER) {
}
};
/**
* doList(sSymbol)
*
* @this {Debugger}
* @param {string} sSymbol
*/
Debugger.prototype.doList = function(sSymbol)
{
var aAddr = this.parseAddr(sSymbol, Debugger.ADDR_CODE);
if (aAddr[0] == null && aAddr[2] == null) return;
var addr = this.getAddr(aAddr);
this.println(sSymbol + ": " + this.hexAddr(aAddr) + " (%" + str.toHex(addr, this.cchAddr) + ")");
var aSymbol = this.findSymbolAtAddr(aAddr, true);
if (aSymbol.length) {
var nDelta, sDelta;
if (aSymbol[0]) {
sDelta = "";
nDelta = aAddr[0] - aSymbol[1];
if (nDelta) sDelta = " + " + str.toHexWord(nDelta);
this.println(aSymbol[0] + " (" + str.toHexAddr(aSymbol[1], aAddr[1]) + ")" + sDelta);
}
if (aSymbol.length > 4 && aSymbol[4]) {
sDelta = "";
nDelta = aSymbol[5] - aAddr[0];
if (nDelta) sDelta = " - " + str.toHexWord(nDelta);
this.println(aSymbol[4] + " (" + str.toHexAddr(aSymbol[5], aAddr[1]) + ")" + sDelta);
}
} else {
this.println("no symbols");
}
};
/**
* doLoad(asArgs)
*
@ -3869,37 +3978,15 @@ if (DEBUGGER) {
return;
}
var aAddr = [], iDrive, iSector = 0, nSectors = 0;
var fJSON = false;
if (asArgs[1] == "json") {
fJSON = true;
} else {
var fListSymbols = (asArgs[0] == "ln");
aAddr = this.parseAddr(asArgs[1], fListSymbols? Debugger.ADDR_CODE : Debugger.ADDR_DATA);
if (fListSymbols) {
var aSymbol = this.findSymbolAtAddr(aAddr, true);
if (aSymbol.length) {
var nDelta, sDelta;
if (aSymbol[0]) {
sDelta = "";
nDelta = aAddr[0] - aSymbol[1];
if (nDelta) sDelta = " + " + str.toHexWord(nDelta);
this.println(aSymbol[0] + " (" + str.toHexAddr(aSymbol[1], aAddr[1]) + ")" + sDelta);
}
if (aSymbol.length > 4 && aSymbol[4]) {
sDelta = "";
nDelta = aSymbol[5] - aAddr[0];
if (nDelta) sDelta = " - " + str.toHexWord(nDelta);
this.println(aSymbol[4] + " (" + str.toHexAddr(aSymbol[5], aAddr[1]) + ")" + sDelta);
}
} else {
this.println("no symbols");
}
return;
}
if (asArgs[0] == "ln") {
this.doList(asArgs[1]);
return;
}
var fJSON = (asArgs[1] == "json");
var iDrive, iSector = 0, nSectors = 0;
var aAddr = (fJSON? [] : this.parseAddr(asArgs[1], Debugger.ADDR_DATA));
iDrive = this.parseValue(asArgs[2], "drive #");
if (iDrive === undefined) return;
if (!fJSON) {
@ -4147,14 +4234,11 @@ if (DEBUGGER) {
var sReg = asArgs[1];
if (sReg == 'p') {
/*
* If the CPU has not defined addrGDT, then there are no protected-mode registers
*
* TODO: Come up with a more formal way of determining the CPU's support for protected-mode,
* and/or report an error.
* If the CPU has not defined addrGDT, then there are no protected-mode registers.
*/
fProt = (this.cpu.addrGDT !== undefined);
} else {
fIns = false;
// fIns = false;
var sValue = null;
var i = sReg.indexOf("=");
if (i > 0) {
@ -4230,20 +4314,21 @@ if (DEBUGGER) {
this.cpu.setSS(w);
break;
case "CS":
fIns = true;
// fIns = true;
this.cpu.setCS(w);
this.aAddrNextCode = this.newAddr(this.cpu.regIP, this.cpu.segCS.sel);
break;
case "IP":
fIns = true;
// fIns = true;
this.cpu.setIP(w);
this.aAddrNextCode = this.newAddr(this.cpu.regIP, this.cpu.segCS.sel);
break;
/*
* I used to alias "PC" to "IP", until I discovered that early (perhaps ALL) versions of
* DEBUG.COM treat "PC" as an alias for the 16-bit flags register.
* DEBUG.COM treat "PC" as an alias for the 16-bit flags register. I, of course, prefer "PS".
*/
case "PC":
case "PS":
this.cpu.setPS(w);
break;
case "C":

View file

@ -146,21 +146,21 @@ var X86 = {
CPL1_SS: 0x08,
CPL2_SP: 0x0a,
CPL2_SS: 0x0c,
CURR_IP: 0x0e,
CURR_PS: 0x10,
CURR_AX: 0x12,
CURR_CX: 0x14,
CURR_DX: 0x16,
CURR_BX: 0x18,
CURR_SP: 0x1a,
CURR_BP: 0x1c,
CURR_SI: 0x1e,
CURR_DI: 0x20,
CURR_ES: 0x22,
CURR_CS: 0x24,
CURR_SS: 0x26,
CURR_DS: 0x28, // end of values altered by task switches
CURR_LDT: 0x2a
TASK_IP: 0x0e,
TASK_PS: 0x10,
TASK_AX: 0x12,
TASK_CX: 0x14,
TASK_DX: 0x16,
TASK_BX: 0x18,
TASK_SP: 0x1a,
TASK_BP: 0x1c,
TASK_SI: 0x1e,
TASK_DI: 0x20,
TASK_ES: 0x22,
TASK_CS: 0x24,
TASK_SS: 0x26,
TASK_DS: 0x28, // end of values altered by task switches
TASK_LDT: 0x2a
},
/*
* Processor Exception Interrupts
@ -320,7 +320,7 @@ X86.PS.DIRECT = (X86.PS.TF | X86.PS.IF | X86.PS.DF);
X86.PS.INDIRECT = (X86.PS.CF | X86.PS.PF | X86.PS.AF | X86.PS.ZF | X86.PS.SF | X86.PS.OF);
/*
* NOTE: These are the default "always set" PS bits for the 8086/8088; other processors must
* These are the default "always set" PS bits for the 8086/8088; other processors must
* adjust these bits accordingly. The final adjusted value is then stored in the X86CPU object
* as "this.PS_SET"; setPS() must use that value, NOT this one.
*

View file

@ -671,12 +671,17 @@ X86CPU.prototype.setAddressMask = function(addrMask)
X86CPU.prototype.initProcessor = function()
{
this.PS_SET = X86.PS.SET;
this.PS_DIRECT = X86.PS.DIRECT;
this.OPFLAG_NOINTR8086 = X86.OPFLAG.NOINTR;
this.nShiftCountMask = 0xff; // on an 8086/8088, all shift counts are used as-is
this.CYCLES = (this.model >= X86.MODEL_80286? X86CPU.CYCLES_80286 : X86CPU.CYCLES_8088);
this.aOps = X86OpXX.aOps.slice(); // make a copy of aOps before modifying it
this.aOps = X86OpXX.aOps.slice(); // make a copy of aOps and others before modifying them
this.aOpGrp4b = X86Grps.aOpGrp4b.slice();
this.aOpGrp4w = X86Grps.aOpGrp4w.slice();
this.aOpGrp6 = X86Op0F.aOpGrp6Real; // setProtMode() will ensure that aOpGrp6 is switched
if (this.model >= X86.MODEL_80186) {
/*
@ -686,35 +691,39 @@ X86CPU.prototype.initProcessor = function()
* opOUTSw, opENTER, and opLEAVE.
*/
this.nShiftCountMask = 0x1f; // on newer processors, all shift counts are MOD 32
this.aOps[0x0F] = X86OpXX.opInvalid;
this.aOps[X86.OPCODE.PUSHA] = X86OpXX.opPUSHA;
this.aOps[X86.OPCODE.POPA] = X86OpXX.opPOPA;
this.aOps[X86.OPCODE.BOUND] = X86OpXX.opBOUND;
this.aOps[0x63] = X86OpXX.opInvalid;
this.aOps[0x64] = X86OpXX.opInvalid;
this.aOps[0x65] = X86OpXX.opInvalid;
this.aOps[0x66] = X86OpXX.opInvalid;
this.aOps[0x67] = X86OpXX.opInvalid;
this.aOps[X86.OPCODE.PUSH16]= X86OpXX.opPUSH16;
this.aOps[X86.OPCODE.IMUL16]= X86OpXX.opIMUL16;
this.aOps[X86.OPCODE.PUSH8] = X86OpXX.opPUSH8;
this.aOps[X86.OPCODE.IMUL8] = X86OpXX.opIMUL8;
this.aOps[X86.OPCODE.INSB] = X86OpXX.opINSb;
this.aOps[X86.OPCODE.INSW] = X86OpXX.opINSw;
this.aOps[X86.OPCODE.OUTSB] = X86OpXX.opOUTSb;
this.aOps[X86.OPCODE.OUTSW] = X86OpXX.opOUTSw;
this.aOps[0xC0] = X86OpXX.opGRP2ab;
this.aOps[0xC1] = X86OpXX.opGRP2aw;
this.aOps[X86.OPCODE.ENTER] = X86OpXX.opENTER;
this.aOps[X86.OPCODE.LEAVE] = X86OpXX.opLEAVE;
this.aOps[0xF1] = X86OpXX.opINT1;
X86Grps.aOpGRP4b[0x07] = X86Grps.opGrpInvalid;
X86Grps.aOpGRP4w[0x07] = X86Grps.opGrpInvalid;
this.aOps[0x0F] = X86OpXX.opInvalid;
this.aOps[X86.OPCODE.PUSHA] = X86OpXX.opPUSHA;
this.aOps[X86.OPCODE.POPA] = X86OpXX.opPOPA;
this.aOps[X86.OPCODE.BOUND] = X86OpXX.opBOUND;
this.aOps[0x63] = X86OpXX.opInvalid;
this.aOps[0x64] = X86OpXX.opInvalid;
this.aOps[0x65] = X86OpXX.opInvalid;
this.aOps[0x66] = X86OpXX.opInvalid;
this.aOps[0x67] = X86OpXX.opInvalid;
this.aOps[X86.OPCODE.PUSH16] = X86OpXX.opPUSH16;
this.aOps[X86.OPCODE.IMUL16] = X86OpXX.opIMUL16;
this.aOps[X86.OPCODE.PUSH8] = X86OpXX.opPUSH8;
this.aOps[X86.OPCODE.IMUL8] = X86OpXX.opIMUL8;
this.aOps[X86.OPCODE.INSB] = X86OpXX.opINSb;
this.aOps[X86.OPCODE.INSW] = X86OpXX.opINSw;
this.aOps[X86.OPCODE.OUTSB] = X86OpXX.opOUTSb;
this.aOps[X86.OPCODE.OUTSW] = X86OpXX.opOUTSw;
this.aOps[0xC0] = X86OpXX.opGRP2ab;
this.aOps[0xC1] = X86OpXX.opGRP2aw;
this.aOps[X86.OPCODE.ENTER] = X86OpXX.opENTER;
this.aOps[X86.OPCODE.LEAVE] = X86OpXX.opLEAVE;
this.aOps[0xF1] = X86OpXX.opINT1;
this.aOpGrp4b[0x07] = X86Grps.opGrpInvalid;
this.aOpGrp4w[0x07] = X86Grps.opGrpInvalid;
if (this.model >= X86.MODEL_80286) {
this.PS_SET = X86.PS.BIT1; // on the 80286, only BIT1 of Processor Status (flags) is always set
this.PS_DIRECT |= X86.PS.IOPL.MASK | X86.PS.NT;
this.OPFLAG_NOINTR8086 = 0; // used with instructions that should *not* set NOINTR on an 80286 (eg, non-SS segment loads)
this.aOps[0x0F] = X86OpXX.op0F;
this.aOps[0x0F] = X86OpXX.op0F;
this.aOps[X86.OPCODE.ARPL] = X86OpXX.opARPL;
this.aOps[X86.OPCODE.PUSHSP]= X86OpXX.opPUSHSP;
}
@ -1010,11 +1019,7 @@ X86CPU.prototype.setProtMode = function(fProt)
if (fProt === undefined) {
fProt = !!(this.regMSW & X86.MSW.PE);
}
if (fProt) {
X86Op0F.aOpGRP6 = X86Op0F.aOpGRP6Prot;
} else {
X86Op0F.aOpGRP6 = X86Op0F.aOpGRP6Real;
}
this.aOpGrp6 = (fProt? X86Op0F.aOpGrp6Prot : X86Op0F.aOpGrp6Real);
this.segCS.updateAccess(fProt);
this.segDS.updateAccess(fProt);
this.segSS.updateAccess(fProt);
@ -1600,8 +1605,9 @@ X86CPU.prototype.setPS = function(regPS)
if (regPS & X86.PS.OF) this.setOF();
/*
* Since PS.IOPL and PS.IF are part of PS.DIRECT, we need to take care of any 80286-specific checks before
* setting the PS.DIRECT bits. Specifically, PS.IOPL is unchanged if CPL > 0, and PS.IF is unchanged if CPL > IOPL.
* Since PS.IOPL and PS.IF are part of PS_DIRECT, we need to take care of any 80286-specific checks before
* setting the PS_DIRECT bits from the incoming regPS bits. Specifically, PS.IOPL is unchanged if CPL > 0,
* and PS.IF is unchanged if CPL > IOPL.
*/
if (!this.segCS.cpl) {
this.nIOPL = (regPS & X86.PS.IOPL.MASK) >> X86.PS.IOPL.SHIFT; // IOPL allowed to change
@ -1609,11 +1615,12 @@ X86CPU.prototype.setPS = function(regPS)
} else {
regPS = (regPS & ~X86.PS.IOPL.MASK) | (this.regPS & X86.PS.IOPL.MASK); // IOPL not allowed to change
}
if (this.segCS.cpl > this.nIOPL) {
regPS = (regPS & ~X86.PS.IF) | (this.regPS & X86.PS.IF); // IF not allowed to change
}
this.regPS = (this.regPS & ~X86.PS.DIRECT) | (regPS & X86.PS.DIRECT) | this.PS_SET;
this.regPS = (this.regPS & ~this.PS_DIRECT) | (regPS & this.PS_DIRECT) | this.PS_SET;
/*
* Assert that all requested flag bits now agree with our simulated (PS_INDIRECT) bits

View file

@ -1282,12 +1282,12 @@ var X86Grps = {
* GRP4w, so I think my nomenclature makes more sense. To compensate, I don't use GRP5, so that the
* remaining group numbers remain in sync with Intel's.
*/
X86Grps.aOpGRP1b = [
X86Grps.aOpGrp1b = [
X86Grps.opGrpADDb, X86Grps.opGrpORb, X86Grps.opGrpADCb, X86Grps.opGrpSBBb, // 0x80/0x82(reg=0x0-0x3)
X86Grps.opGrpANDb, X86Grps.opGrpSUBb, X86Grps.opGrpXORb, X86Grps.opGrpCMPb // 0x80/0x82(reg=0x4-0x7)
];
X86Grps.aOpGRP1w = [
X86Grps.aOpGrp1w = [
X86Grps.opGrpADDw, X86Grps.opGrpORw, X86Grps.opGrpADCw, X86Grps.opGrpSBBw, // 0x81/0x83(reg=0x0-0x3)
X86Grps.opGrpANDw, X86Grps.opGrpSUBw, X86Grps.opGrpXORw, X86Grps.opGrpCMPw // 0x81/0x83(reg=0x4-0x7)
];
@ -1302,32 +1302,32 @@ X86Grps.aOpGrpMOVImm = [
X86Grps.opGrpUndefined, X86Grps.opGrpUndefined, X86Grps.opGrpUndefined, X86Grps.opGrpUndefined // 0xC6/0xC7(reg=0x4-0x7)
];
X86Grps.aOpGRP2b = [
X86Grps.aOpGrp2b = [
X86Grps.opGrpROLb, X86Grps.opGrpRORb, X86Grps.opGrpRCLb, X86Grps.opGrpRCRb, // 0xD0/0xD2(reg=0x0-0x3)
X86Grps.opGrpSHLb, X86Grps.opGrpSHRb, X86Grps.opGrpUndefined, X86Grps.opGrpSARb // 0xD0/0xD2(reg=0x4-0x7)
];
X86Grps.aOpGRP2w = [
X86Grps.aOpGrp2w = [
X86Grps.opGrpROLw, X86Grps.opGrpRORw, X86Grps.opGrpRCLw, X86Grps.opGrpRCRw, // 0xD1/0xD3(reg=0x0-0x3)
X86Grps.opGrpSHLw, X86Grps.opGrpSHRw, X86Grps.opGrpUndefined, X86Grps.opGrpSARw // 0xD1/0xD3(reg=0x4-0x7)
];
X86Grps.aOpGRP3b = [
X86Grps.aOpGrp3b = [
X86Grps.opGrpTEST8, X86Grps.opGrpUndefined, X86Grps.opGrpNOTb, X86Grps.opGrpNEGb, // 0xF6(reg=0x0-0x3)
X86Grps.opGrpMULb, X86Grps.opGrpIMULb, X86Grps.opGrpDIVb, X86Grps.opGrpIDIVb // 0xF6(reg=0x4-0x7)
];
X86Grps.aOpGRP3w = [
X86Grps.aOpGrp3w = [
X86Grps.opGrpTEST16, X86Grps.opGrpUndefined, X86Grps.opGrpNOTw, X86Grps.opGrpNEGw, // 0xF7(reg=0x0-0x3)
X86Grps.opGrpMULw, X86Grps.opGrpIMULw, X86Grps.opGrpDIVw, X86Grps.opGrpIDIVw // 0xF7(reg=0x4-0x7)
];
X86Grps.aOpGRP4b = [
X86Grps.aOpGrp4b = [
X86Grps.opGrpINCb, X86Grps.opGrpDECb, X86Grps.opGrpUndefined, X86Grps.opGrpUndefined, // 0xFE(reg=0x0-0x3)
X86Grps.opGrpUndefined, X86Grps.opGrpUndefined, X86Grps.opGrpUndefined, X86Grps.opGrpUndefined // 0xFE(reg=0x4-0x7)
];
X86Grps.aOpGRP4w = [
X86Grps.aOpGrp4w = [
X86Grps.opGrpINCw, X86Grps.opGrpDECw, X86Grps.opGrpCALLw, X86Grps.opGrpCALLdw, // 0xFF(reg=0x0-0x3)
X86Grps.opGrpJMPw, X86Grps.opGrpJMPf, X86Grps.opGrpPUSHw, X86Grps.opGrpFault // 0xFF(reg=0x4-0x7)
];
@ -1335,12 +1335,12 @@ X86Grps.aOpGRP4w = [
/*
* The following are for 80186/80188 and up...
*/
X86Grps.aOpGRP2ab = [
X86Grps.aOpGrp2ab = [
X86Grps.opGrpROLb, X86Grps.opGrpRORb, X86Grps.opGrpRCLb, X86Grps.opGrpRCRb, // 0xC0(reg=0x0-0x3)
X86Grps.opGrpSHLb, X86Grps.opGrpSHRb, X86Grps.opGrpUndefined, X86Grps.opGrpSARb // 0xC0(reg=0x4-0x7)
];
X86Grps.aOpGRP2aw = [
X86Grps.aOpGrp2aw = [
X86Grps.opGrpROLw, X86Grps.opGrpRORw, X86Grps.opGrpRCLw, X86Grps.opGrpRCRw, // 0xC1(reg=0x0-0x3)
X86Grps.opGrpSHLw, X86Grps.opGrpSHRw, X86Grps.opGrpUndefined, X86Grps.opGrpSARw // 0xC1(reg=0x4-0x7)
];

View file

@ -485,7 +485,7 @@ var X86Help = {
if (this.regPS & X86.PS.NT) {
var addrNew = this.segTSS.base;
var sel = this.getWord(addrNew + X86.TSS.PREV_TSS);
X86Help.opHelpSwitchTSS.call(this, sel);
X86Help.opHelpSwitchTSS.call(this, sel, false);
return;
}
}
@ -569,7 +569,7 @@ var X86Help = {
*
* @this {X86CPU}
* @param {number} selNew
* @param {boolean} [fNest]
* @param {boolean} fNest is true if nesting, false if un-nesting
* @return {boolean} true if successful, false if error
*/
opHelpSwitchTSS: function(selNew, fNest) {
@ -581,65 +581,59 @@ var X86Help = {
X86Help.opHelpFault.call(this, X86.EXCEPTION.TS_FAULT, selNew, true);
return false;
}
this.setWord(this.segTSS.addrDesc + X86.DESC.ACC.OFFSET, this.segTSS.acc &= ~X86.DESC.ACC.TYPE.LDT);
this.segTSS.type = X86.DESC.ACC.TYPE.TSS;
this.setWord(this.segTSS.addrDesc + X86.DESC.ACC.OFFSET, (this.segTSS.acc & ~X86.DESC.ACC.TYPE.TSS_BUSY) | X86.DESC.ACC.TYPE.TSS);
}
if (this.segTSS.load(selNew) == null) {
return false;
}
if (this.segTSS.load(selNew) == null) return false;
var addrNew = this.segTSS.base;
if (DEBUG) {
this.messageDebugger((fNest? "switchTSS" : "returnTSS") + ": old TR=" + str.toHexWord(selOld) + " TSS=" + str.toHex(addrOld, 6) + ", new TR=" + str.toHexWord(selNew) + " TSS=" + str.toHex(addrNew, 6));
this.messageDebugger((fNest? "Task switch" : "Task return") + ": TR " + str.toHexWord(selOld) + " (%" + str.toHex(addrOld, 6) + "), new TR " + str.toHexWord(selNew) + " (%" + str.toHex(addrNew, 6) + ")", Debugger.MESSAGE.TSS);
}
if (fNest) {
if (this.segTSS.type == X86.DESC.ACC.TYPE.TSS_BUSY) {
X86Help.opHelpFault.call(this, X86.EXCEPTION.GP_FAULT, selNew, true);
return false;
}
this.setWord(this.segTSS.addrDesc + X86.DESC.ACC.OFFSET, this.segTSS.acc |= X86.DESC.ACC.TYPE.LDT);
this.setWord(this.segTSS.addrDesc + X86.DESC.ACC.OFFSET, this.segTSS.acc |= X86.DESC.ACC.TYPE.TSS_BUSY);
this.segTSS.type = X86.DESC.ACC.TYPE.TSS_BUSY;
}
this.setWord(addrOld + X86.TSS.CURR_IP, this.regIP);
this.setWord(addrOld + X86.TSS.CURR_PS, this.getPS());
this.setWord(addrOld + X86.TSS.CURR_AX, this.regAX);
this.setWord(addrOld + X86.TSS.CURR_CX, this.regCX);
this.setWord(addrOld + X86.TSS.CURR_DX, this.regDX);
this.setWord(addrOld + X86.TSS.CURR_BX, this.regBX);
this.setWord(addrOld + X86.TSS.CURR_SP, this.regSP);
this.setWord(addrOld + X86.TSS.CURR_BP, this.regBP);
this.setWord(addrOld + X86.TSS.CURR_SI, this.regSI);
this.setWord(addrOld + X86.TSS.CURR_DI, this.regDI);
this.setWord(addrOld + X86.TSS.CURR_ES, this.segES.sel);
this.setWord(addrOld + X86.TSS.CURR_CS, this.segCS.sel);
this.setWord(addrOld + X86.TSS.CURR_SS, this.segSS.sel);
this.setWord(addrOld + X86.TSS.CURR_DS, this.segDS.sel);
var offSS = X86.TSS.CURR_SS;
var offSP = X86.TSS.CURR_SP;
var regPS = this.getWord(addrNew + X86.TSS.CURR_PS);
this.setPS(regPS);
/*
* We have to set the NT (Nested Task) flag manually, because setPS() doesn't allow it.
*/
this.regPS = (this.regPS & ~X86.PS.NT) | (regPS | X86.PS.NT);
this.regAX = this.getWord(addrNew + X86.TSS.CURR_AX);
this.regCX = this.getWord(addrNew + X86.TSS.CURR_CX);
this.regDX = this.getWord(addrNew + X86.TSS.CURR_DX);
this.regBX = this.getWord(addrNew + X86.TSS.CURR_BX);
this.regBP = this.getWord(addrNew + X86.TSS.CURR_BP);
this.regSI = this.getWord(addrNew + X86.TSS.CURR_SI);
this.regDI = this.getWord(addrNew + X86.TSS.CURR_DI);
this.segES.load(this.getWord(addrNew + X86.TSS.CURR_ES));
this.segDS.load(this.getWord(addrNew + X86.TSS.CURR_DS));
this.setCSIP(this.getWord(addrNew + X86.TSS.CURR_IP), this.getWord(addrNew + X86.TSS.CURR_CS));
this.setWord(addrOld + X86.TSS.TASK_IP, this.regIP);
this.setWord(addrOld + X86.TSS.TASK_PS, this.getPS());
this.setWord(addrOld + X86.TSS.TASK_AX, this.regAX);
this.setWord(addrOld + X86.TSS.TASK_CX, this.regCX);
this.setWord(addrOld + X86.TSS.TASK_DX, this.regDX);
this.setWord(addrOld + X86.TSS.TASK_BX, this.regBX);
this.setWord(addrOld + X86.TSS.TASK_SP, this.regSP);
this.setWord(addrOld + X86.TSS.TASK_BP, this.regBP);
this.setWord(addrOld + X86.TSS.TASK_SI, this.regSI);
this.setWord(addrOld + X86.TSS.TASK_DI, this.regDI);
this.setWord(addrOld + X86.TSS.TASK_ES, this.segES.sel);
this.setWord(addrOld + X86.TSS.TASK_CS, this.segCS.sel);
this.setWord(addrOld + X86.TSS.TASK_SS, this.segSS.sel);
this.setWord(addrOld + X86.TSS.TASK_DS, this.segDS.sel);
var offSS = X86.TSS.TASK_SS;
var offSP = X86.TSS.TASK_SP;
this.setPS(this.getWord(addrNew + X86.TSS.TASK_PS) | (fNest? X86.PS.NT : 0));
if (DEBUG) this.assert(!fNest || !!(this.regPS & X86.PS.NT));
this.regAX = this.getWord(addrNew + X86.TSS.TASK_AX);
this.regCX = this.getWord(addrNew + X86.TSS.TASK_CX);
this.regDX = this.getWord(addrNew + X86.TSS.TASK_DX);
this.regBX = this.getWord(addrNew + X86.TSS.TASK_BX);
this.regBP = this.getWord(addrNew + X86.TSS.TASK_BP);
this.regSI = this.getWord(addrNew + X86.TSS.TASK_SI);
this.regDI = this.getWord(addrNew + X86.TSS.TASK_DI);
this.segES.load(this.getWord(addrNew + X86.TSS.TASK_ES));
this.segDS.load(this.getWord(addrNew + X86.TSS.TASK_DS));
this.setCSIP(this.getWord(addrNew + X86.TSS.TASK_IP), this.getWord(addrNew + X86.TSS.TASK_CS));
if (this.segCS.cpl < cplOld) {
offSP = (this.segCS.cpl << 2) + X86.TSS.CPL0_SP;
offSS = offSP + 2;
}
this.regSP = this.getWord(addrNew + offSP);
this.segSS.load(this.getWord(addrNew + offSS));
this.segLDT.load(this.getWord(addrNew + X86.TSS.CURR_LDT));
if (fNest) {
this.setWord(addrNew + X86.TSS.PREV_TSS, selOld);
this.regPS |= X86.PS.NT;
}
this.segLDT.load(this.getWord(addrNew + X86.TSS.TASK_LDT));
if (fNest) this.setWord(addrNew + X86.TSS.PREV_TSS, selOld);
this.regMSW |= X86.MSW.TS;
return true;
},
@ -690,20 +684,22 @@ var X86Help = {
var bOpcode = this.bus.getByteDirect(this.regEIP);
/*
* OS/2 1.0 uses an INT3 (0xCC) opcode in conjunction with an invalid IDT to trigger a triple-fault
* reset and return to real-mode, and these resets happen quite frequently during boot; for example, OS/2
* startup messages are displayed using a series of INT 0x10 BIOS calls for each character, and each
* series of BIOS calls requires a round-trip mode switch.
* reset and return to real-mode, and these resets happen quite frequently during boot; for example,
* OS/2 startup messages are displayed using a series of INT 0x10 BIOS calls for each character, and
* each series of BIOS calls requires a round-trip mode switch.
*
* Since we really only want to halt on "bad" faults, not "good" (ie, intentional) faults, we take
* advantage of the fact that all 3 faults comprising the triple-fault point to the INT3 (0xCC) opcode,
* advantage of the fact that all 3 faults comprising the triple-fault point to an INT3 (0xCC) opcode,
* and so whenever we see that opcode, we ignore the caller's fHalt flag, and suppress FAULT messages
* unless CPU messages are also enabled.
*
* When a triple fault shows up, nFault is -1; it displays as "ff" only because we truncate it to a byte.
*/
if (bOpcode == X86.OPCODE.INT3) {
fHalt = false;
bitsMessage |= Debugger.MESSAGE.CPU;
}
this.messageDebugger("Fault 0x" + str.toHexByte(nFault) + (nError != null? " (0x" + str.toHexWord(nError) + ")" : "") + " on opcode 0x" + str.toHexByte(bOpcode) + " at " + str.toHexAddr(this.regIP, this.segCS.sel) + " (" + str.toHex(this.regEIP, 6) + ")", bitsMessage);
this.messageDebugger("Fault " + str.toHexByte(nFault) + (nError != null? " (" + str.toHexWord(nError) + ")" : "") + " on opcode 0x" + str.toHexByte(bOpcode) + " at " + str.toHexAddr(this.regIP, this.segCS.sel) + " (%" + str.toHex(this.regEIP, 6) + ")", bitsMessage);
if (fHalt) this.dbg.stopCPU();
}
}

View file

@ -51,7 +51,7 @@ var X86Op0F = {
if ((bModRM & 0x38) < 0x10) { // possible reg values: 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
if (EAFUNCS) this.modEAWord = this.modEAWordDisabled; else this.opFlags |= X86.OPFLAG.NOREAD;
}
X86Mods.aOpModsGrpWord[bModRM].call(this, X86Op0F.aOpGRP6, X86Grps.opGrpNoSrc);
X86Mods.aOpModsGrpWord[bModRM].call(this, this.aOpGrp6, X86Grps.opGrpNoSrc);
if (EAFUNCS) { this.modEAWord = this.modEAWordEnabled; this.setEAWord = this.setEAWordEnabled; }
},
/**
@ -64,7 +64,7 @@ var X86Op0F = {
if (!(bModRM & 0x10)) {
if (EAFUNCS) this.modEAWord = this.modEAWordDisabled; else this.opFlags |= X86.OPFLAG.NOREAD;
}
X86Mods.aOpModsGrpWord[bModRM].call(this, X86Op0F.aOpGRP7, X86Grps.opGrpNoSrc);
X86Mods.aOpModsGrpWord[bModRM].call(this, X86Op0F.aOpGrp7, X86Grps.opGrpNoSrc);
if (EAFUNCS) { this.modEAWord = this.modEAWordEnabled; this.setEAWord = this.setEAWordEnabled; }
},
/**
@ -159,6 +159,19 @@ var X86Op0F = {
*/
if (DEBUG && DEBUGGER && (this.regMSW & X86.MSW.PE)) this.stopCPU();
},
/**
* @this {X86CPU}
*
* op=0x0F,0x06 (clts)
*/
opCLTS: function() {
if (this.segCS.cpl) {
X86Help.opHelpFault.call(this, X86.EXCEPTION.GP_FAULT, 0, true);
return;
}
this.regMSW &= ~X86.MSW.TS;
this.nStepCycles -= 2;
},
/**
* @this {X86CPU}
* @param {number} dst
@ -426,7 +439,7 @@ var X86Op0F = {
X86Op0F.aOps0F = [
X86Op0F.opGRP6, X86Op0F.opGRP7, X86Op0F.opLAR, X86Op0F.opLSL, // 0x00-0x03
X86OpXX.opUndefined, X86Op0F.opLOADALL, X86OpXX.opUndefined, X86OpXX.opUndefined, // 0x04-0x07
X86OpXX.opUndefined, X86Op0F.opLOADALL, X86Op0F.opCLTS, X86OpXX.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.
@ -502,27 +515,21 @@ X86Op0F.aOps0F = [
* getEAWord() should be disabled *prior* to calling the ModRM helper function. This latter case requires that
* we decode the reg field of the ModRM byte before dispatching.
*/
X86Op0F.aOpGRP6Prot = [
X86Op0F.aOpGrp6Prot = [
X86Op0F.opSLDT, X86Op0F.opSTR, X86Op0F.opLLDT, X86Op0F.opLTR, // 0x0F,0x00(reg=0x0-0x3)
X86Op0F.opVERR, X86Op0F.opVERW, X86Grps.opGrpUndefined, X86Grps.opGrpUndefined // 0x0F,0x00(reg=0x4-0x7)
];
X86Op0F.aOpGRP6Real = [
X86Op0F.aOpGrp6Real = [
X86Grps.opGrpInvalid, X86Grps.opGrpInvalid, X86Grps.opGrpInvalid, X86Grps.opGrpInvalid, // 0x0F,0x00(reg=0x0-0x3)
X86Grps.opGrpInvalid, X86Grps.opGrpInvalid, X86Grps.opGrpUndefined, X86Grps.opGrpUndefined // 0x0F,0x00(reg=0x4-0x7)
];
/*
* setProtMode() will ensure that aOpGRP6 is set to the appropriate group, but it doesn't hurt to statically
* initialize to its real-mode default, either.
*/
X86Op0F.aOpGRP6 = X86Op0F.aOpGRP6Real;
/*
* Unlike GRP6, GRP7 does not require separate real-mode and protected-mode dispatch tables, because all GRP7
* instructions are valid in both modes.
*/
X86Op0F.aOpGRP7 = [
X86Op0F.aOpGrp7 = [
X86Op0F.opSGDT, X86Op0F.opSIDT, X86Op0F.opLGDT, X86Op0F.opLIDT, // 0x0F,0x01(reg=0x0-0x3)
X86Op0F.opSMSW, X86Grps.opGrpUndefined, X86Op0F.opLMSW, X86Grps.opGrpUndefined // 0x0F,0x01(reg=0x4-0x7)
];

View file

@ -1591,7 +1591,7 @@ var X86OpXX = {
* op=0x80/0x82 (grp1b rm,imm8)
*/
opGRP1b: function() {
X86Mods.aOpModsGrpByte[this.getIPByte()].call(this, X86Grps.aOpGRP1b, this.getIPByte);
X86Mods.aOpModsGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrp1b, this.getIPByte);
if (EAFUNCS) this.setEAByte = this.setEAByteEnabled;
this.nStepCycles -= (this.regEAWrite < 0? 1 : this.CYCLES.nOpCyclesArithMID);
},
@ -1601,7 +1601,7 @@ var X86OpXX = {
* op=0x81 (grp1w rm,imm16)
*/
opGRP1w: function() {
X86Mods.aOpModsGrpWord[this.getIPByte()].call(this, X86Grps.aOpGRP1w, this.getIPWord);
X86Mods.aOpModsGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp1w, this.getIPWord);
if (EAFUNCS) this.setEAWord = this.setEAWordEnabled;
this.nStepCycles -= (this.regEAWrite < 0? 1 : this.CYCLES.nOpCyclesArithMID);
},
@ -1611,7 +1611,7 @@ var X86OpXX = {
* op=0x83 (grp1sw rm,disp)
*/
opGRP1sw: function() {
X86Mods.aOpModsGrpWord[this.getIPByte()].call(this, X86Grps.aOpGRP1w, this.getIPDisp);
X86Mods.aOpModsGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp1w, this.getIPDisp);
if (EAFUNCS) this.setEAWord = this.setEAWordEnabled;
this.nStepCycles -= (this.regEAWrite < 0? 1 : this.CYCLES.nOpCyclesArithMID);
},
@ -1984,10 +1984,8 @@ var X86OpXX = {
* op=0x9B (wait)
*/
opWAIT: function() {
/*
* TODO: Implement
*/
X86OpXX.opUndefined.call(this);
this.messageDebugger("WAIT not implemented");
this.nStepCycles--;
},
/**
* @this {X86CPU}
@ -2646,7 +2644,7 @@ var X86OpXX = {
* op=0xC0 (grp2ab rm) (80186/80188 and up)
*/
opGRP2ab: function() {
X86Mods.aOpModsGrpByte[this.getIPByte()].call(this, X86Grps.aOpGRP2ab, X86Grps.opGrp2CountImm);
X86Mods.aOpModsGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrp2ab, X86Grps.opGrp2CountImm);
},
/**
* @this {X86CPU}
@ -2654,7 +2652,7 @@ var X86OpXX = {
* op=0xC1 (grp2aw rm) (80186/80188 and up)
*/
opGRP2aw: function() {
X86Mods.aOpModsGrpWord[this.getIPByte()].call(this, X86Grps.aOpGRP2aw, X86Grps.opGrp2CountImm);
X86Mods.aOpModsGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp2aw, X86Grps.opGrp2CountImm);
},
/**
* @this {X86CPU}
@ -2852,7 +2850,7 @@ var X86OpXX = {
* op=0xD0 (grp2b rm,1)
*/
opGRP2b1: function() {
X86Mods.aOpModsGrpByte[this.getIPByte()].call(this, X86Grps.aOpGRP2b, X86Grps.opGrp2Count1);
X86Mods.aOpModsGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrp2b, X86Grps.opGrp2Count1);
},
/**
* @this {X86CPU}
@ -2860,7 +2858,7 @@ var X86OpXX = {
* op=0xD1 (grp2w rm,1)
*/
opGRP2w1: function() {
X86Mods.aOpModsGrpWord[this.getIPByte()].call(this, X86Grps.aOpGRP2w, X86Grps.opGrp2Count1);
X86Mods.aOpModsGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp2w, X86Grps.opGrp2Count1);
},
/**
* @this {X86CPU}
@ -2868,7 +2866,7 @@ var X86OpXX = {
* op=0xD2 (grp2b rm,CL)
*/
opGRP2bCL: function() {
X86Mods.aOpModsGrpByte[this.getIPByte()].call(this, X86Grps.aOpGRP2b, X86Grps.opGrp2CountCL);
X86Mods.aOpModsGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrp2b, X86Grps.opGrp2CountCL);
},
/**
* @this {X86CPU}
@ -2876,7 +2874,7 @@ var X86OpXX = {
* op=0xD3 (grp2w rm,CL)
*/
opGRP2wCL: function() {
X86Mods.aOpModsGrpWord[this.getIPByte()].call(this, X86Grps.aOpGRP2w, X86Grps.opGrp2CountCL);
X86Mods.aOpModsGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp2w, X86Grps.opGrp2CountCL);
},
/**
* @this {X86CPU}
@ -3245,7 +3243,7 @@ var X86OpXX = {
*/
opGRP3b: function() {
this.regMD16 = -1;
X86Mods.aOpModsGrpByte[this.getIPByte()].call(this, X86Grps.aOpGRP3b, X86Grps.opGrpNoSrc);
X86Mods.aOpModsGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrp3b, X86Grps.opGrpNoSrc);
if (this.regMD16 >= 0) this.regAX = this.regMD16;
if (EAFUNCS) this.setEAByte = this.setEAByteEnabled;
},
@ -3269,7 +3267,7 @@ var X86OpXX = {
*/
opGRP3w: function() {
this.regMD16 = -1;
X86Mods.aOpModsGrpWord[this.getIPByte()].call(this, X86Grps.aOpGRP3w, X86Grps.opGrpNoSrc);
X86Mods.aOpModsGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp3w, X86Grps.opGrpNoSrc);
if (this.regMD16 >= 0) {
this.regAX = this.regMD16;
this.regDX = this.regMD32;
@ -3337,7 +3335,7 @@ var X86OpXX = {
* op=0xFE (grp4b rm)
*/
opGRP4b: function() {
X86Mods.aOpModsGrpByte[this.getIPByte()].call(this, X86Grps.aOpGRP4b, X86Grps.opGrpNoSrc);
X86Mods.aOpModsGrpByte[this.getIPByte()].call(this, X86Grps.aOpGrp4b, X86Grps.opGrpNoSrc);
},
/**
* @this {X86CPU}
@ -3345,7 +3343,7 @@ var X86OpXX = {
* op=0xFF (grp4w rm)
*/
opGRP4w: function() {
X86Mods.aOpModsGrpWord[this.getIPByte()].call(this, X86Grps.aOpGRP4w, X86Grps.opGrpNoSrc);
X86Mods.aOpModsGrpWord[this.getIPByte()].call(this, X86Grps.aOpGrp4w, X86Grps.opGrpNoSrc);
if (EAFUNCS) this.setEAWord = this.setEAWordEnabled;
},
/**

View file

@ -446,7 +446,7 @@ X86Seg.prototype.messageDebugger = function(base, limit, acc, ext)
var ch = (this.sName.length < 3? " " : "");
var sDPL = " dpl=" + this.dpl;
if (this.id == X86Seg.ID.CODE) sDPL += " cpl=" + this.cpl;
this.cpu.messageDebugger("loadDesc(" + this.sName + "):" + ch + " base=" + str.toHex(base) + " limit=" + str.toHexWord(limit) + " acc=" + str.toHexWord(acc) + sDPL, Debugger.MESSAGE.SEG);
this.cpu.messageDebugger("loadSeg(" + this.sName + "):" + ch + " base=" + str.toHex(base) + " limit=" + str.toHexWord(limit) + " acc=" + str.toHexWord(acc) + sDPL, Debugger.MESSAGE.SEG);
}
this.cpu.assert(!ext || ext == X86.DESC.EXT.AVAIL);
}