More 80386 instructions and more 80386 Debugger support
This commit is contained in:
parent
ed99d4702c
commit
051e12c87e
15 changed files with 220 additions and 90 deletions
|
|
@ -13,7 +13,7 @@
|
|||
<debugger id="debugger" messages="fault|port" commands=""/>
|
||||
<panel ref="/devices/pc/panel/btpanel.xml"/>
|
||||
<fdc ref="/disks/pc/library.xml" width="340px" automount='{A: {name: "PC-DOS 3.00 (Disk 1)", path: "/disks/pc/dos/ibm/3.00/PCDOS300-DISK1.json"}, B: {name: "PC-DOS 3.00 (Disk 2)", path: "/disks/pc/dos/ibm/3.00/PCDOS300-DISK2.json"}}'/>
|
||||
<hdc id="hdcAT" type="at" drives='[{name:"20Mb Hard Disk",type:2}]'/>
|
||||
<hdcFoo id="hdcAT" type="at" drives='[{name:"20Mb Hard Disk",type:2}]'/>
|
||||
<chipset id="chipset" model="deskpro386" floppies="[1200,1200]"/>
|
||||
<serial id="com1" adapter="1"/>
|
||||
<serial id="com2" adapter="2" binding="print"/>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
<disk path="">None</disk>
|
||||
<manifest ref="/disks/pc/cpm/manifest.xml" disk="*"/>
|
||||
</control>
|
||||
<control type="button" binding="loadDrive">Load Drive</control>
|
||||
<control type="button" binding="loadDrive">Load</control>
|
||||
<control type="description" binding="descDisk" padleft="8px"/>
|
||||
</fdc>
|
||||
<chipset id="chipset" model="5150" sw1="01000001" sw2="11110000"/>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
<manifest ref="/disks/pc/dos/ibm/2.00/manifest.xml" disk="*"/>
|
||||
<manifest ref="/disks/pc/diags/ibm/2.20/manifest.xml" disk="*"/>
|
||||
</control>
|
||||
<control type="button" binding="loadDrive">Load Drive</control>
|
||||
<control type="button" binding="loadDrive">Load</control>
|
||||
<control type="description" binding="descDisk" padleft="8px"/>
|
||||
</fdc>
|
||||
<chipset id="chipset" model="5150" sw1="01000001" sw2="11110000"/>
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
<manifest ref="/apps/pc/1987/thinktank/manifest.xml" disk="disk01"/>
|
||||
<manifest ref="/apps/pc/1992/moria/manifest.xml" disk="disk01"/>
|
||||
</control>
|
||||
<control type="button" binding="loadDrive" padright="8px">Download</control>
|
||||
<control type="button" binding="loadDrive" padright="8px">Load</control>
|
||||
<control type="description" binding="descDisk" padright="8px"/>
|
||||
<control type="file" binding="mountDrive"/>
|
||||
</fdc>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<manifest ref="/disks/pc/games/microsoft/adventure/manifest.xml" disk="*"/>
|
||||
<manifest ref="/apps/pc/1981/visicalc/manifest.xml" disk="*"/>
|
||||
</control>
|
||||
<control type="button" binding="loadDrive" padright="8px">Download</control>
|
||||
<control type="button" binding="loadDrive" padright="8px">Load</control>
|
||||
<control type="description" binding="descDisk" padright="8px"/>
|
||||
<control type="file" binding="mountDrive"/>
|
||||
</fdc>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,6 @@
|
|||
<disk path="/disks/pc/windows/1.03/05-APPS/">Windows 1.03 (APPS)</disk>
|
||||
<disk path="/disks/pc/windows/1.03/06-WRITE/">Windows 1.03 (WRITE)</disk>
|
||||
</control>
|
||||
<control type="button" binding="loadDrive">Load Drive</control>
|
||||
<control type="button" binding="loadDrive">Load</control>
|
||||
<control type="description" binding="descDisk" padleft="8px"/>
|
||||
</fdc>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
<disk path="">None</disk>
|
||||
<disk path="PCDOS100.json">PC-DOS 1.00</disk>
|
||||
</control>
|
||||
<control type="button" binding="loadDrive">Load Drive</control>
|
||||
<control type="button" binding="loadDrive">Load</control>
|
||||
</control>
|
||||
</fdc>
|
||||
<chipset id="chipset" model="5150" sw1="01000001" sw2="11110000"/>
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@
|
|||
<disk path="PCDOS100.json">PC-DOS 1.00</disk>
|
||||
<disk path="visicalc.json" href="http://www.bricklin.com/history/vclicense.htm" desc="VisiCalc License">VisiCalc</disk>
|
||||
</control>
|
||||
<control type="button" binding="loadDrive">Load Drive</control>
|
||||
<control type="button" binding="loadDrive">Load</control>
|
||||
<control type="description" binding="descDisk" padleft="8px"/>
|
||||
</control>
|
||||
</fdc>
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@
|
|||
<form class="{$APPCLASS}-binding" style="{$border}{$width}{$height}{$style}" data-value="{$type},{$binding}">
|
||||
<fieldset class="{$APPCLASS}-fieldset">
|
||||
<input type="file"/>
|
||||
<input type="submit" value="Load" disabled="true"/>
|
||||
<input type="submit" value="Mount" disabled="true"/>
|
||||
</fieldset>
|
||||
</form>
|
||||
</xsl:when>
|
||||
|
|
|
|||
|
|
@ -879,20 +879,38 @@ if (DEBUGGER) {
|
|||
Debugger.aaOp0FDescs = {
|
||||
0x00: [Debugger.INS.GRP6, Debugger.TYPE_MODRM | Debugger.TYPE_WORD | Debugger.TYPE_BOTH],
|
||||
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_OUT | Debugger.TYPE_80286, Debugger.TYPE_MEM | Debugger.TYPE_WORD | Debugger.TYPE_IN],
|
||||
0x03: [Debugger.INS.LSL, Debugger.TYPE_REG | Debugger.TYPE_WORD | Debugger.TYPE_OUT | Debugger.TYPE_80286, Debugger.TYPE_MEM | Debugger.TYPE_WORD | Debugger.TYPE_IN],
|
||||
0x02: [Debugger.INS.LAR, Debugger.TYPE_REG | Debugger.TYPE_WORD | Debugger.TYPE_OUT | Debugger.TYPE_80286, Debugger.TYPE_MEM | Debugger.TYPE_WORD | Debugger.TYPE_IN],
|
||||
0x03: [Debugger.INS.LSL, Debugger.TYPE_REG | Debugger.TYPE_WORD | Debugger.TYPE_OUT | Debugger.TYPE_80286, Debugger.TYPE_MEM | Debugger.TYPE_WORD | Debugger.TYPE_IN],
|
||||
0x05: [Debugger.INS.LOADALL,Debugger.TYPE_80286],
|
||||
0x06: [Debugger.INS.CLTS, Debugger.TYPE_80286],
|
||||
0x20: [Debugger.INS.MOV, Debugger.TYPE_REG | Debugger.TYPE_DWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_CTLREG | Debugger.TYPE_DWORD | Debugger.TYPE_IN],
|
||||
0x22: [Debugger.INS.MOV, Debugger.TYPE_CTLREG | Debugger.TYPE_DWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_DWORD | Debugger.TYPE_IN],
|
||||
0x20: [Debugger.INS.MOV, Debugger.TYPE_REG | Debugger.TYPE_DWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_CTLREG | Debugger.TYPE_DWORD | Debugger.TYPE_IN],
|
||||
0x22: [Debugger.INS.MOV, Debugger.TYPE_CTLREG | Debugger.TYPE_DWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_DWORD | Debugger.TYPE_IN],
|
||||
0x80: [Debugger.INS.JO, Debugger.TYPE_IMMREL | Debugger.TYPE_WORDV | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0x81: [Debugger.INS.JNO, Debugger.TYPE_IMMREL | Debugger.TYPE_WORDV | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0x82: [Debugger.INS.JC, Debugger.TYPE_IMMREL | Debugger.TYPE_WORDV | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0x83: [Debugger.INS.JNC, Debugger.TYPE_IMMREL | Debugger.TYPE_WORDV | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0x84: [Debugger.INS.JZ, Debugger.TYPE_IMMREL | Debugger.TYPE_WORDV | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0x85: [Debugger.INS.JNZ, Debugger.TYPE_IMMREL | Debugger.TYPE_WORDV | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0x86: [Debugger.INS.JBE, Debugger.TYPE_IMMREL | Debugger.TYPE_WORDV | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0x87: [Debugger.INS.JNBE, Debugger.TYPE_IMMREL | Debugger.TYPE_WORDV | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0x88: [Debugger.INS.JS, Debugger.TYPE_IMMREL | Debugger.TYPE_WORDV | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0x89: [Debugger.INS.JNS, Debugger.TYPE_IMMREL | Debugger.TYPE_WORDV | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0x8A: [Debugger.INS.JP, Debugger.TYPE_IMMREL | Debugger.TYPE_WORDV | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0x8B: [Debugger.INS.JNP, Debugger.TYPE_IMMREL | Debugger.TYPE_WORDV | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0x8C: [Debugger.INS.JL, Debugger.TYPE_IMMREL | Debugger.TYPE_WORDV | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0x8D: [Debugger.INS.JGE, Debugger.TYPE_IMMREL | Debugger.TYPE_WORDV | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0x8E: [Debugger.INS.JLE, Debugger.TYPE_IMMREL | Debugger.TYPE_WORDV | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0x8F: [Debugger.INS.JG, Debugger.TYPE_IMMREL | Debugger.TYPE_WORDV | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0xA0: [Debugger.INS.PUSH, Debugger.TYPE_FS | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0xA1: [Debugger.INS.POP, Debugger.TYPE_FS | Debugger.TYPE_OUT | Debugger.TYPE_80386],
|
||||
0xA4: [Debugger.INS.SHLD, Debugger.TYPE_MODRM | Debugger.TYPE_WORDV | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_WORDV | Debugger.TYPE_IN, Debugger.TYPE_IMM | Debugger.TYPE_BYTE | Debugger.TYPE_IN],
|
||||
0xA5: [Debugger.INS.SHLD, Debugger.TYPE_MODRM | Debugger.TYPE_WORDV | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_WORDV | Debugger.TYPE_IN, Debugger.TYPE_IMPREG | Debugger.TYPE_CL | Debugger.TYPE_IN],
|
||||
0xA4: [Debugger.INS.SHLD, Debugger.TYPE_MODRM | Debugger.TYPE_WORDV | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_WORDV | Debugger.TYPE_IN, Debugger.TYPE_IMM | Debugger.TYPE_BYTE | Debugger.TYPE_IN],
|
||||
0xA5: [Debugger.INS.SHLD, Debugger.TYPE_MODRM | Debugger.TYPE_WORDV | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_WORDV | Debugger.TYPE_IN, Debugger.TYPE_IMPREG | Debugger.TYPE_CL | Debugger.TYPE_IN],
|
||||
0xA8: [Debugger.INS.PUSH, Debugger.TYPE_GS | Debugger.TYPE_IN | Debugger.TYPE_80386],
|
||||
0xA9: [Debugger.INS.POP, Debugger.TYPE_GS | Debugger.TYPE_OUT | Debugger.TYPE_80386],
|
||||
0xAC: [Debugger.INS.SHRD, Debugger.TYPE_MODRM | Debugger.TYPE_WORDV | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_WORDV | Debugger.TYPE_IN, Debugger.TYPE_IMM | Debugger.TYPE_BYTE | Debugger.TYPE_IN],
|
||||
0xAD: [Debugger.INS.SHRD, Debugger.TYPE_MODRM | Debugger.TYPE_WORDV | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_WORDV | Debugger.TYPE_IN, Debugger.TYPE_IMPREG | Debugger.TYPE_CL | Debugger.TYPE_IN]
|
||||
0xAC: [Debugger.INS.SHRD, Debugger.TYPE_MODRM | Debugger.TYPE_WORDV | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_WORDV | Debugger.TYPE_IN, Debugger.TYPE_IMM | Debugger.TYPE_BYTE | Debugger.TYPE_IN],
|
||||
0xAD: [Debugger.INS.SHRD, Debugger.TYPE_MODRM | Debugger.TYPE_WORDV | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_REG | Debugger.TYPE_WORDV | Debugger.TYPE_IN, Debugger.TYPE_IMPREG | Debugger.TYPE_CL | Debugger.TYPE_IN],
|
||||
0xB6: [Debugger.INS.MOVZX, Debugger.TYPE_REG | Debugger.TYPE_WORDV | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_MODRM | Debugger.TYPE_BYTE | Debugger.TYPE_IN],
|
||||
0xB7: [Debugger.INS.MOVZX, Debugger.TYPE_REG | Debugger.TYPE_DWORD | Debugger.TYPE_OUT | Debugger.TYPE_80386, Debugger.TYPE_MODRM | Debugger.TYPE_WORD | Debugger.TYPE_IN]
|
||||
};
|
||||
|
||||
Debugger.aaGrpDescs = [
|
||||
|
|
@ -2421,15 +2439,6 @@ if (DEBUGGER) {
|
|||
this.cInstructions++;
|
||||
var bOpcode = this.bus.getByteDirect(addr);
|
||||
this.aaOpcodeCounts[bOpcode][1]++;
|
||||
|
||||
/*
|
||||
* This is a good example of what NOT to do in a high-frequency function, and defeats
|
||||
* the purpose of pre-allocating and pre-initializing the history array in historyInit():
|
||||
*
|
||||
* this.aOpcodeHistory[this.iOpcodeHistory] = this.newAddr(this.cpu.getIP(), this.cpu.getCS(), addr);
|
||||
*
|
||||
* As the name implies, newAddr() returns a new "Addr" (Array) object every time it's called.
|
||||
*/
|
||||
var a = this.aOpcodeHistory[this.iOpcodeHistory];
|
||||
a[0] = this.cpu.getIP();
|
||||
a[1] = this.cpu.getCS();
|
||||
|
|
@ -4225,18 +4234,23 @@ if (DEBUGGER) {
|
|||
this.println(n + " instructions earlier:");
|
||||
}
|
||||
while (cLines && iHistory != this.iOpcodeHistory) {
|
||||
var aAddr = aHistory[iHistory];
|
||||
var aAddr = aHistory[iHistory++];
|
||||
if (aAddr[1] == null) break;
|
||||
/*
|
||||
* We must create a new aAddr from the address we obtained from aHistory, because aAddr
|
||||
* was a reference, not a copy, and we don't want getInstruction() modifying the original.
|
||||
*
|
||||
* TODO: By using a new address each time, history dumps will not disassemble 32-bit overrides properly.
|
||||
*/
|
||||
aAddr = this.newAddr(aAddr[0], aAddr[1], aAddr[2]);
|
||||
this.println(this.getInstruction(aAddr, "history", n));
|
||||
if (++iHistory == aHistory.length) iHistory = 0;
|
||||
this.nextHistory = --n;
|
||||
this.println(this.getInstruction(aAddr, "history", n--));
|
||||
/*
|
||||
* If there was an OPERAND or ADDRESS override on the previous instruction, getInstruction()
|
||||
* will have automatically disassembled the next instruction, so skip one more history entry.
|
||||
*/
|
||||
if (aAddr[6]) {
|
||||
iHistory++; n--;
|
||||
}
|
||||
if (iHistory >= aHistory.length) iHistory = 0;
|
||||
this.nextHistory = n;
|
||||
cLines--;
|
||||
}
|
||||
}
|
||||
|
|
@ -5039,6 +5053,10 @@ if (DEBUGGER) {
|
|||
*/
|
||||
Debugger.prototype.initAddrSize = function(aAddr, fNonPrefix)
|
||||
{
|
||||
/*
|
||||
* Use aAddr[6] to record whether we previously processed any OPERAND or ADDRESS overrides.
|
||||
*/
|
||||
aAddr[6] = (aAddr[4] || aAddr[5]);
|
||||
/*
|
||||
* For proper disassembly of instructions preceded by an OPERAND (0x66) size prefix, we set aAddr[4]
|
||||
* to true whenever the operand size is 32-bit; similarly, for an ADDRESS (0x67) size prefix, we set
|
||||
|
|
@ -5050,10 +5068,10 @@ if (DEBUGGER) {
|
|||
aAddr[5] = (this.cpu.segCS.addrSize == 4);
|
||||
}
|
||||
/*
|
||||
* We also use aAddr[6] to record whether the caller (ie, getInstruction()) is reporting that it
|
||||
* We also use aAddr[7] to record whether the caller (ie, getInstruction()) is reporting that it
|
||||
* processed a complete instruction (ie, a non-prefix) or not.
|
||||
*/
|
||||
aAddr[6] = fNonPrefix;
|
||||
aAddr[7] = fNonPrefix;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -5128,11 +5146,11 @@ if (DEBUGGER) {
|
|||
var sIns = this.getInstruction(aAddr, sComment, nSequence);
|
||||
|
||||
/*
|
||||
* If getInstruction() reported that it did not yet process a complete instruction (via aAddr[6]),
|
||||
* If getInstruction() reported that it did not yet process a complete instruction (via aAddr[7]),
|
||||
* then bump the instruction count by one, so that we display one more line (and hopefully the complete
|
||||
* instruction).
|
||||
*/
|
||||
if (!aAddr[6] && !n) n++;
|
||||
if (!aAddr[7] && !n) n++;
|
||||
|
||||
this.println(sIns);
|
||||
this.aAddrNextCode = aAddr;
|
||||
|
|
|
|||
|
|
@ -1203,7 +1203,7 @@ FDC.prototype.loadSelectedDrive = function(sDisketteName, sDiskettePath, file)
|
|||
}
|
||||
|
||||
if (sDiskettePath == "?") {
|
||||
this.notice('Use "Choose File" and "Load" to select and load a local disk.');
|
||||
this.notice('Use "Choose File" and "Mount" to select and load a local disk.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1337,14 +1337,14 @@ FDC.prototype.doneLoadDiskette = function onFDCLoadNotify(drive, disk, sDiskette
|
|||
|
||||
/*
|
||||
* Adding local disk image names to the disk list seems like a nice idea, but it's too confusing,
|
||||
* because then it looks like the "Load" button should be able to (re)load them, and that can NEVER
|
||||
* because then it looks like the "Mount" button should be able to (re)load them, and that can NEVER
|
||||
* happen, for security reasons; local disk images can ONLY be loaded via the "Mount" button after
|
||||
* the user has selected them via the "Choose File" button.
|
||||
*
|
||||
* this.addDiskette(sDisketteName, sDiskettePath);
|
||||
*
|
||||
* So we're going to take a different approach: when displayDiskette() is asked to display the name
|
||||
* of a local disk image, it will map all such disks to "Local Disk", and any attempt to "Load" such
|
||||
* of a local disk image, it will map all such disks to "Local Disk", and any attempt to "Mount" such
|
||||
* a disk, will essentially result in a "Disk not found" error.
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -659,7 +659,7 @@ X86.fnDIVb = function DIVb(dst, src)
|
|||
* However, src is technically an output, and dst is merely an input (which is why we must return
|
||||
* dst unchanged). So, to make traceLog() more consistent, we reverse the order of dst and src.
|
||||
*/
|
||||
if (DEBUG && DEBUGGER) this.traceLog('DIVB', src, dst, null, this.getPS(), this.regMDLo);
|
||||
if (DEBUG && DEBUGGER) this.traceLog('DIVb', src, dst, null, this.getPS(), this.regMDLo);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesDivBR : this.cycleCounts.nOpCyclesDivBM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
|
|
@ -718,9 +718,9 @@ X86.fnDIVw = function DIVw(dst, src)
|
|||
*/
|
||||
if (DEBUG && DEBUGGER) {
|
||||
if (this.dataSize == 2) {
|
||||
this.traceLog('DIVW', src, dst, null, this.getPS(), this.regMDLo | (this.regMDHi << 16));
|
||||
this.traceLog('DIVw', src, dst, null, this.getPS(), this.regMDLo | (this.regMDHi << 16));
|
||||
} else {
|
||||
this.traceLog('DIVD', src, dst, null, this.getPS(), this.regMDLo, this.regMDHi);
|
||||
this.traceLog('DIVd', src, dst, null, this.getPS(), this.regMDLo, this.regMDHi);
|
||||
}
|
||||
}
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesDivWR : this.cycleCounts.nOpCyclesDivWM);
|
||||
|
|
@ -788,7 +788,7 @@ X86.fnIDIVb = function IDIVb(dst, src)
|
|||
* However, src is technically an output, and dst is merely an input (which is why we must return
|
||||
* dst unchanged). So, to make traceLog() more consistent, we reverse the order of dst and src.
|
||||
*/
|
||||
if (DEBUG && DEBUGGER) this.traceLog('IDIVB', src, dst, null, this.getPS(), this.regMDLo);
|
||||
if (DEBUG && DEBUGGER) this.traceLog('IDIVb', src, dst, null, this.getPS(), this.regMDLo);
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIDivBR : this.cycleCounts.nOpCyclesIDivBM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
return dst;
|
||||
|
|
@ -855,9 +855,9 @@ X86.fnIDIVw = function IDIVw(dst, src)
|
|||
*/
|
||||
if (DEBUG && DEBUGGER) {
|
||||
if (this.dataSize == 2) {
|
||||
this.traceLog('IDIVW', src, dst, null, this.getPS(), this.regMDLo | (this.regMDHi << 16));
|
||||
this.traceLog('IDIVw', src, dst, null, this.getPS(), this.regMDLo | (this.regMDHi << 16));
|
||||
} else {
|
||||
this.traceLog('IDIVD', src, dst, null, this.getPS(), this.regMDLo, this.regMDHi);
|
||||
this.traceLog('IDIVd', src, dst, null, this.getPS(), this.regMDLo, this.regMDHi);
|
||||
}
|
||||
}
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIDivWR : this.cycleCounts.nOpCyclesIDivWM);
|
||||
|
|
@ -945,7 +945,7 @@ X86.fnIMULb = function IMULb(dst, src)
|
|||
* However, src is technically an output, and dst is merely an input (which is why we must return
|
||||
* dst unchanged). So, to make traceLog() more consistent, we reverse the order of dst and src.
|
||||
*/
|
||||
if (DEBUG && DEBUGGER) this.traceLog('IMULB', src, dst, null, this.getPS(), this.regMDLo);
|
||||
if (DEBUG && DEBUGGER) this.traceLog('IMULb', src, dst, null, this.getPS(), this.regMDLo);
|
||||
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIMulBR : this.cycleCounts.nOpCyclesIMulBM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
|
|
@ -989,7 +989,7 @@ X86.fnIMULn = function IMULn(dst, src)
|
|||
}
|
||||
|
||||
result &= this.dataMask;
|
||||
if (DEBUG && DEBUGGER) this.traceLog('IMULN', dst, src, null, this.getPS(), result);
|
||||
if (DEBUG && DEBUGGER) this.traceLog('IMULn', dst, src, null, this.getPS(), result);
|
||||
|
||||
/*
|
||||
* NOTE: These are the cycle counts for the 80286; the 80186/80188 have slightly different values (ranges):
|
||||
|
|
@ -1086,9 +1086,9 @@ X86.fnIMULw = function IMULw(dst, src)
|
|||
*/
|
||||
if (DEBUG && DEBUGGER) {
|
||||
if (this.dataSize == 2) {
|
||||
this.traceLog('IMULW', src, dst, null, this.getPS(), this.regMDLo | (this.regMDHi << 16));
|
||||
this.traceLog('IMULw', src, dst, null, this.getPS(), this.regMDLo | (this.regMDHi << 16));
|
||||
} else {
|
||||
this.traceLog('IMULD', src, dst, null, this.getPS(), this.regMDLo, this.regMDHi);
|
||||
this.traceLog('IMULd', src, dst, null, this.getPS(), this.regMDLo, this.regMDHi);
|
||||
}
|
||||
}
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesIMulWR : this.cycleCounts.nOpCyclesIMulWM);
|
||||
|
|
@ -1683,7 +1683,7 @@ X86.fnMULb = function MULb(dst, src)
|
|||
* However, src is technically an output, and dst is merely an input (which is why we must return
|
||||
* dst unchanged). So, to make traceLog() more consistent, we reverse the order of dst and src.
|
||||
*/
|
||||
if (DEBUG && DEBUGGER) this.traceLog('MULB', src, dst, null, this.getPS(), this.regMDLo);
|
||||
if (DEBUG && DEBUGGER) this.traceLog('MULb', src, dst, null, this.getPS(), this.regMDLo);
|
||||
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesMulBR : this.cycleCounts.nOpCyclesMulBM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
|
|
@ -1760,9 +1760,9 @@ X86.fnMULw = function MULw(dst, src)
|
|||
*/
|
||||
if (DEBUG && DEBUGGER) {
|
||||
if (this.dataSize == 2) {
|
||||
this.traceLog('MULW', src, dst, null, this.getPS(), this.regMDLo | (this.regMDHi << 16));
|
||||
this.traceLog('MULw', src, dst, null, this.getPS(), this.regMDLo | (this.regMDHi << 16));
|
||||
} else {
|
||||
this.traceLog('MULD', src, dst, null, this.getPS(), this.regMDLo, this.regMDHi);
|
||||
this.traceLog('MULd', src, dst, null, this.getPS(), this.regMDLo, this.regMDHi);
|
||||
}
|
||||
}
|
||||
this.nStepCycles -= (this.regEA === X86.ADDR_INVALID? this.cycleCounts.nOpCyclesMulWR : this.cycleCounts.nOpCyclesMulWM);
|
||||
|
|
@ -1928,7 +1928,7 @@ X86.fnRCLb = function RCLb(dst, src)
|
|||
}
|
||||
this.setRotateResult(result, carry, X86.RESULT.BYTE);
|
||||
}
|
||||
if (DEBUG && DEBUGGER) this.traceLog('RCLB', dst, src, flagsIn, this.getPS(), result);
|
||||
if (DEBUG && DEBUGGER) this.traceLog('RCLb', dst, src, flagsIn, this.getPS(), result);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
@ -1956,7 +1956,7 @@ X86.fnRCLw = function RCLw(dst, src)
|
|||
}
|
||||
this.setRotateResult(result, carry, X86.RESULT.WORD);
|
||||
}
|
||||
if (DEBUG && DEBUGGER) this.traceLog('RCLW', dst, src, flagsIn, this.getPS(), result);
|
||||
if (DEBUG && DEBUGGER) this.traceLog('RCLw', dst, src, flagsIn, this.getPS(), result);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
@ -1972,7 +1972,7 @@ X86.fnRCLd = function RCLd(dst, src)
|
|||
{
|
||||
var result = dst;
|
||||
var flagsIn = (DEBUG? this.getPS() : 0);
|
||||
var count = src & this.nShiftCountMask; // Yes, this 32-bit-only function could mask with 0x1f directly
|
||||
var count = src & this.nShiftCountMask; // this 32-bit-only function could mask with 0x1f directly
|
||||
if (count) {
|
||||
var carry = this.getCarry();
|
||||
/*
|
||||
|
|
@ -1984,7 +1984,7 @@ X86.fnRCLd = function RCLd(dst, src)
|
|||
carry = dst << (count - 1);
|
||||
this.setRotateResult(result, carry, X86.RESULT.DWORD);
|
||||
}
|
||||
if (DEBUG && DEBUGGER) this.traceLog('RCLD', dst, src, flagsIn, this.getPS(), result);
|
||||
if (DEBUG && DEBUGGER) this.traceLog('RCLd', dst, src, flagsIn, this.getPS(), result);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
@ -2012,7 +2012,7 @@ X86.fnRCRb = function RCRb(dst, src)
|
|||
}
|
||||
this.setRotateResult(result, carry, X86.RESULT.BYTE);
|
||||
}
|
||||
if (DEBUG && DEBUGGER) this.traceLog('RCRB', dst, src, flagsIn, this.getPS(), result);
|
||||
if (DEBUG && DEBUGGER) this.traceLog('RCRb', dst, src, flagsIn, this.getPS(), result);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
@ -2040,7 +2040,7 @@ X86.fnRCRw = function RCRw(dst, src)
|
|||
}
|
||||
this.setRotateResult(result, carry, X86.RESULT.WORD);
|
||||
}
|
||||
if (DEBUG && DEBUGGER) this.traceLog('RCRW', dst, src, flagsIn, this.getPS(), result);
|
||||
if (DEBUG && DEBUGGER) this.traceLog('RCRw', dst, src, flagsIn, this.getPS(), result);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
@ -2056,7 +2056,7 @@ X86.fnRCRd = function RCRd(dst, src)
|
|||
{
|
||||
var result = dst;
|
||||
var flagsIn = (DEBUG? this.getPS() : 0);
|
||||
var count = src & this.nShiftCountMask; // Yes, this 32-bit-only function could mask with 0x1f directly
|
||||
var count = src & this.nShiftCountMask; // this 32-bit-only function could mask with 0x1f directly
|
||||
if (count) {
|
||||
var carry = this.getCarry();
|
||||
/*
|
||||
|
|
@ -2068,7 +2068,7 @@ X86.fnRCRd = function RCRd(dst, src)
|
|||
carry = dst << (32 - count);
|
||||
this.setRotateResult(result, carry, X86.RESULT.DWORD);
|
||||
}
|
||||
if (DEBUG && DEBUGGER) this.traceLog('RCRD', dst, src, flagsIn, this.getPS(), result);
|
||||
if (DEBUG && DEBUGGER) this.traceLog('RCRd', dst, src, flagsIn, this.getPS(), result);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
@ -2130,12 +2130,12 @@ X86.fnROLb = function ROLb(dst, src)
|
|||
if (!count) {
|
||||
carry = dst << 7;
|
||||
} else {
|
||||
result = ((dst << count) | (dst >> (8 - count))) & 0xff;
|
||||
carry = dst << (count - 1);
|
||||
result = ((dst << count) | (dst >> (8 - count))) & 0xff;
|
||||
}
|
||||
this.setRotateResult(result, carry, X86.RESULT.BYTE);
|
||||
}
|
||||
if (DEBUG && DEBUGGER) this.traceLog('ROLB', dst, src, flagsIn, this.getPS(), result);
|
||||
if (DEBUG && DEBUGGER) this.traceLog('ROLb', dst, src, flagsIn, this.getPS(), result);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
@ -2158,12 +2158,34 @@ X86.fnROLw = function ROLw(dst, src)
|
|||
if (!count) {
|
||||
carry = dst << 15;
|
||||
} else {
|
||||
result = ((dst << count) | (dst >> (16 - count))) & 0xffff;
|
||||
carry = dst << (count - 1);
|
||||
result = ((dst << count) | (dst >> (16 - count))) & 0xffff;
|
||||
}
|
||||
this.setRotateResult(result, carry, X86.RESULT.WORD);
|
||||
}
|
||||
if (DEBUG && DEBUGGER) this.traceLog('ROLW', dst, src, flagsIn, this.getPS(), result);
|
||||
if (DEBUG && DEBUGGER) this.traceLog('ROLw', dst, src, flagsIn, this.getPS(), result);
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnROLd(dst, src)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} dst
|
||||
* @param {number} src (1 or CL)
|
||||
* @return {number}
|
||||
*/
|
||||
X86.fnROLd = function ROLd(dst, src)
|
||||
{
|
||||
var result = dst;
|
||||
var flagsIn = (DEBUG? this.getPS() : 0);
|
||||
var count = src & this.nShiftCountMask;
|
||||
if (count) {
|
||||
var carry = dst << (count - 1);
|
||||
result = (dst << count) | (dst >>> (32 - count));
|
||||
this.setRotateResult(result, carry, X86.RESULT.DWORD);
|
||||
}
|
||||
if (DEBUG && DEBUGGER) this.traceLog('ROLd', dst, src, flagsIn, this.getPS(), result);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
@ -2186,12 +2208,12 @@ X86.fnRORb = function RORb(dst, src)
|
|||
if (!count) {
|
||||
carry = dst;
|
||||
} else {
|
||||
result = ((dst >> count) | (dst << (8 - count))) & 0xff;
|
||||
carry = dst << (8 - count);
|
||||
result = ((dst >>> count) | carry) & 0xff;
|
||||
}
|
||||
this.setRotateResult(result, carry, X86.RESULT.BYTE);
|
||||
}
|
||||
if (DEBUG && DEBUGGER) this.traceLog('RORB', dst, src, flagsIn, this.getPS(), result);
|
||||
if (DEBUG && DEBUGGER) this.traceLog('RORb', dst, src, flagsIn, this.getPS(), result);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
@ -2214,12 +2236,34 @@ X86.fnRORw = function RORw(dst, src)
|
|||
if (!count) {
|
||||
carry = dst;
|
||||
} else {
|
||||
result = ((dst >> count) | (dst << (16 - count))) & 0xffff;
|
||||
carry = dst << (16 - count);
|
||||
result = ((dst >>> count) | carry) & 0xffff;
|
||||
}
|
||||
this.setRotateResult(result, carry, X86.RESULT.WORD);
|
||||
}
|
||||
if (DEBUG && DEBUGGER) this.traceLog('RORW', dst, src, flagsIn, this.getPS(), result);
|
||||
if (DEBUG && DEBUGGER) this.traceLog('RORw', dst, src, flagsIn, this.getPS(), result);
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnRORd(dst, src)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} dst
|
||||
* @param {number} src (1 or CL)
|
||||
* @return {number}
|
||||
*/
|
||||
X86.fnRORd = function RORd(dst, src)
|
||||
{
|
||||
var result = dst;
|
||||
var flagsIn = (DEBUG? this.getPS() : 0);
|
||||
var count = src & this.nShiftCountMask;
|
||||
if (count) {
|
||||
var carry = dst << (32 - count);
|
||||
result = (dst >>> count) | carry;
|
||||
this.setRotateResult(result, carry, X86.RESULT.DWORD);
|
||||
}
|
||||
if (DEBUG && DEBUGGER) this.traceLog('RORd', dst, src, flagsIn, this.getPS(), result);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
@ -2235,7 +2279,7 @@ X86.fnSARb = function SARb(dst, src)
|
|||
{
|
||||
var count = src & this.nShiftCountMask;
|
||||
if (count) {
|
||||
if (count > 8) count = 9;
|
||||
if (count > 9) count = 9;
|
||||
var carry = ((dst << 24) >> 24) >> (count - 1);
|
||||
dst = (carry >> 1) & 0xff;
|
||||
this.setLogicResult(dst, X86.RESULT.BYTE, carry & 0x1);
|
||||
|
|
@ -2255,7 +2299,7 @@ X86.fnSARw = function SARw(dst, src)
|
|||
{
|
||||
var count = src & this.nShiftCountMask;
|
||||
if (count) {
|
||||
if (count > 16) count = 17;
|
||||
if (count > 17) count = 17;
|
||||
var carry = ((dst << 16) >> 16) >> (count - 1);
|
||||
dst = (carry >> 1) & 0xffff;
|
||||
this.setLogicResult(dst, X86.RESULT.WORD, carry & 0x1);
|
||||
|
|
@ -2263,6 +2307,25 @@ X86.fnSARw = function SARw(dst, src)
|
|||
return dst;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnSARd(dst, src)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} dst
|
||||
* @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)
|
||||
* @return {number}
|
||||
*/
|
||||
X86.fnSARd = function SARd(dst, src)
|
||||
{
|
||||
var count = src & this.nShiftCountMask;
|
||||
if (count) {
|
||||
var carry = dst >> (count - 1);
|
||||
dst = (carry >> 1);
|
||||
this.setLogicResult(dst, X86.RESULT.DWORD, carry & 0x1);
|
||||
}
|
||||
return dst;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnSBBb(dst, src)
|
||||
*
|
||||
|
|
@ -2596,7 +2659,7 @@ X86.fnSHLb = function SHLb(dst, src)
|
|||
}
|
||||
this.setLogicResult(result, X86.RESULT.BYTE, carry & X86.RESULT.BYTE, (result ^ carry) & X86.RESULT.BYTE);
|
||||
}
|
||||
if (DEBUG && DEBUGGER) this.traceLog('SHLB', dst, src, flagsIn, this.getPS(), result);
|
||||
if (DEBUG && DEBUGGER) this.traceLog('SHLb', dst, src, flagsIn, this.getPS(), result);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
@ -2623,7 +2686,29 @@ X86.fnSHLw = function SHLw(dst, src)
|
|||
}
|
||||
this.setLogicResult(result, X86.RESULT.WORD, carry & X86.RESULT.WORD, (result ^ carry) & X86.RESULT.WORD);
|
||||
}
|
||||
if (DEBUG && DEBUGGER) this.traceLog('SHLW', dst, src, flagsIn, this.getPS(), result);
|
||||
if (DEBUG && DEBUGGER) this.traceLog('SHLw', dst, src, flagsIn, this.getPS(), result);
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnSHLd(dst, src)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} dst
|
||||
* @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)
|
||||
* @return {number}
|
||||
*/
|
||||
X86.fnSHLd = function SHLd(dst, src)
|
||||
{
|
||||
var result = dst;
|
||||
var flagsIn = (DEBUG? this.getPS() : 0);
|
||||
var count = src & this.nShiftCountMask; // this 32-bit-only function could mask with 0x1f directly
|
||||
if (count) {
|
||||
var carry = dst << (count - 1);
|
||||
result = (carry << 1);
|
||||
this.setLogicResult(result, X86.RESULT.DWORD, carry & X86.RESULT.DWORD, (result ^ carry) & X86.RESULT.DWORD);
|
||||
}
|
||||
if (DEBUG && DEBUGGER) this.traceLog('SHLd', dst, src, flagsIn, this.getPS(), result);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
|
@ -2733,8 +2818,8 @@ X86.fnSHRb = function SHRb(dst, src)
|
|||
{
|
||||
var count = src & this.nShiftCountMask;
|
||||
if (count) {
|
||||
var carry = (count > 8? 0 : (dst >> (count - 1)));
|
||||
dst = (carry >> 1) & 0xff;
|
||||
var carry = (count > 8? 0 : (dst >>> (count - 1)));
|
||||
dst = (carry >>> 1) & 0xff;
|
||||
this.setLogicResult(dst, X86.RESULT.BYTE, carry & 0x1, dst & X86.RESULT.BYTE);
|
||||
}
|
||||
return dst;
|
||||
|
|
@ -2752,13 +2837,32 @@ X86.fnSHRw = function SHRw(dst, src)
|
|||
{
|
||||
var count = src & this.nShiftCountMask;
|
||||
if (count) {
|
||||
var carry = (count > 16? 0 : (dst >> (count - 1)));
|
||||
dst = (carry >> 1) & 0xffff;
|
||||
var carry = (count > 16? 0 : (dst >>> (count - 1)));
|
||||
dst = (carry >>> 1) & 0xffff;
|
||||
this.setLogicResult(dst, X86.RESULT.WORD, carry & 0x1, dst & X86.RESULT.WORD);
|
||||
}
|
||||
return dst;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnSHRd(dst, src)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} dst
|
||||
* @param {number} src (1 or CL, or an immediate byte for 80186/80188 and up)
|
||||
* @return {number}
|
||||
*/
|
||||
X86.fnSHRd = function SHRd(dst, src)
|
||||
{
|
||||
var count = src & this.nShiftCountMask;
|
||||
if (count) {
|
||||
var carry = (dst >>> (count - 1));
|
||||
dst = (carry >>> 1);
|
||||
this.setLogicResult(dst, X86.RESULT.DWORD, carry & 0x1, dst & X86.RESULT.DWORD);
|
||||
}
|
||||
return dst;
|
||||
};
|
||||
|
||||
/**
|
||||
* fnSHRDw(dst, src, count)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -4146,18 +4146,18 @@ X86.aOpGrpMOVn = [
|
|||
];
|
||||
|
||||
X86.aOpGrp2b = [
|
||||
X86.fnROLb, X86.fnRORb, X86.fnRCLb, X86.fnRCRb, // 0xD0/0xD2(reg=0x0-0x3)
|
||||
X86.fnSHLb, X86.fnSHRb, X86.fnGRPUndefined, X86.fnSARb // 0xD0/0xD2(reg=0x4-0x7)
|
||||
X86.fnROLb, X86.fnRORb, X86.fnRCLb, X86.fnRCRb, // 0xC0/0xD0/0xD2(reg=0x0-0x3)
|
||||
X86.fnSHLb, X86.fnSHRb, X86.fnGRPUndefined, X86.fnSARb // 0xC0/0xD0/0xD2(reg=0x4-0x7)
|
||||
];
|
||||
|
||||
X86.aOpGrp2w = [
|
||||
X86.fnROLw, X86.fnRORw, X86.fnRCLw, X86.fnRCRw, // 0xD1/0xD3(reg=0x0-0x3)
|
||||
X86.fnSHLw, X86.fnSHRw, X86.fnGRPUndefined, X86.fnSARw // 0xD1/0xD3(reg=0x4-0x7)
|
||||
X86.fnROLw, X86.fnRORw, X86.fnRCLw, X86.fnRCRw, // 0xC1/0xD1/0xD3(reg=0x0-0x3)
|
||||
X86.fnSHLw, X86.fnSHRw, X86.fnGRPUndefined, X86.fnSARw // 0xC1/0xD1/0xD3(reg=0x4-0x7)
|
||||
];
|
||||
|
||||
X86.aOpGrp2d = [
|
||||
X86.fnTBD, X86.fnTBD, X86.fnRCLd, X86.fnRCRd, // 0xD1/0xD3(reg=0x0-0x3)
|
||||
X86.fnTBD, X86.fnTBD, X86.fnGRPUndefined, X86.fnTBD // 0xD1/0xD3(reg=0x4-0x7)
|
||||
X86.fnROLd, X86.fnRORd, X86.fnRCLd, X86.fnRCRd, // 0xC1/0xD1/0xD3(reg=0x0-0x3)
|
||||
X86.fnSHLd, X86.fnSHRd, X86.fnGRPUndefined, X86.fnSARd // 0xC1/0xD1/0xD3(reg=0x4-0x7)
|
||||
];
|
||||
|
||||
X86.aOpGrp3b = [
|
||||
|
|
|
|||
|
|
@ -54,13 +54,12 @@ function X86Seg(cpu, id, sName, fProt)
|
|||
this.id = id;
|
||||
this.sName = sName || "";
|
||||
this.sel = 0;
|
||||
this.base = 0;
|
||||
this.limit = 0xffff;
|
||||
this.acc = 0;
|
||||
this.ext = 0;
|
||||
this.limit = 0xffff; // in protected-mode, this is descriptor word 0x0 (word 0x6 on the 80386 supplements limit bits 16-19)
|
||||
this.base = 0; // in protected-mode, this is descriptor word 0x2 (word 0x6 on the 80386 supplements base bits 24-31)
|
||||
this.acc = 0; // in protected-mode, this is descriptor word 0x4, masked with 0xff00 (bits 0-7 supplement base bits 16-23)
|
||||
this.ext = 0; // in protected-mode, this is descriptor word 0x6 (used only on the 80386)
|
||||
this.cpl = this.dpl = 0;
|
||||
this.addrDesc = X86.ADDR_INVALID;
|
||||
this.cpl = 0;
|
||||
this.dpl = 0;
|
||||
/*
|
||||
* The following properties are used for CODE segments only (ie, segCS); if the process of loading
|
||||
* CS also requires a stack switch, then fStackSwitch will be set to true; additionally, if the stack
|
||||
|
|
@ -839,6 +838,15 @@ X86Seg.prototype.updateMode = function(fProt)
|
|||
}
|
||||
this.fExpDown = false;
|
||||
if (fProt) {
|
||||
/*
|
||||
* If we've just transitioned from real-mode, then CPL (which is meaningful for segCS only)
|
||||
* should be left alone (ie, should remain at zero). On the first protected-mode CS selector
|
||||
* load (normally an intersegment JMP immediately following the protected-mode switch), CPL
|
||||
* (along with the rest of the segment settings) will be properly set.
|
||||
*/
|
||||
if (this.load !== this.loadReal) {
|
||||
this.cpl = this.sel & X86.SEL.RPL;
|
||||
}
|
||||
this.load = this.loadProt;
|
||||
this.loadIDT = this.loadIDTProt;
|
||||
this.checkRead = this.checkReadProt;
|
||||
|
|
@ -865,7 +873,6 @@ X86Seg.prototype.updateMode = function(fProt)
|
|||
this.fExpDown = true;
|
||||
}
|
||||
}
|
||||
this.cpl = this.sel & X86.SEL.RPL;
|
||||
this.dpl = (this.acc & X86.DESC.ACC.DPL.MASK) >> X86.DESC.ACC.DPL.SHIFT;
|
||||
if (this.cpu.model < X86.MODEL_80386 || !(this.ext & X86.DESC.EXT.BIG)) {
|
||||
this.addrSize = 2;
|
||||
|
|
@ -880,6 +887,7 @@ X86Seg.prototype.updateMode = function(fProt)
|
|||
this.checkRead = this.checkReadReal;
|
||||
this.checkWrite = this.checkWriteReal;
|
||||
this.limit = 0xffff;
|
||||
this.acc = this.ext = 0;
|
||||
this.cpl = this.dpl = 0;
|
||||
this.addrDesc = X86.ADDR_INVALID;
|
||||
this.addrSize = 2;
|
||||
|
|
|
|||
|
|
@ -377,7 +377,7 @@
|
|||
<form class="{$APPCLASS}-binding" data-value="{$type},{$binding}">
|
||||
<fieldset class="{$APPCLASS}-fieldset">
|
||||
<input type="file"/>
|
||||
<input type="submit" value="Load" disabled="true"/>
|
||||
<input type="submit" value="Mount" disabled="true"/>
|
||||
</fieldset>
|
||||
</form>
|
||||
</xsl:when>
|
||||
|
|
|
|||
Loading…
Reference in a new issue