Performance improvements
This commit is contained in:
parent
da58c2aeaf
commit
e1d760c814
33 changed files with 7769 additions and 1733 deletions
|
|
@ -3323,7 +3323,7 @@ ChipSet.prototype.getIRRVector = function(iPIC)
|
|||
|
||||
var nIRQ = pic.nIRQBase + nIRL;
|
||||
if (DEBUG && this.messageEnabled(this.messageBitsIRQ(nIRQ))) {
|
||||
this.printMessage("getIRRVector(): IRQ " + nIRQ + " interrupting @" + str.toHexAddr(this.cpu.regEIP, this.cpu.segCS.sel) + " stack=" + str.toHexAddr(this.cpu.regESP, this.cpu.segSS.sel), true);
|
||||
this.printMessage("getIRRVector(): IRQ " + nIRQ + " interrupting @" + str.toHexAddr(this.cpu.getIP(), this.cpu.getCS()) + " stack=" + str.toHexAddr(this.cpu.regESP, this.cpu.getSS()), true);
|
||||
}
|
||||
if (MAXDEBUG && DEBUGGER) {
|
||||
this.acInterrupts[nIRQ]++;
|
||||
|
|
|
|||
|
|
@ -1576,11 +1576,11 @@ if (DEBUGGER) {
|
|||
this.aMessageRegs[asRegs[13]] = str.toHexWord(cpu.regEBP);
|
||||
this.aMessageRegs[asRegs[14]] = str.toHexWord(cpu.regESI);
|
||||
this.aMessageRegs[asRegs[15]] = str.toHexWord(cpu.regEDI);
|
||||
this.aMessageRegs[asRegs[16]] = str.toHexWord(cpu.segES.sel);
|
||||
this.aMessageRegs[asRegs[17]] = str.toHexWord(cpu.segCS.sel);
|
||||
this.aMessageRegs[asRegs[18]] = str.toHexWord(cpu.segSS.sel);
|
||||
this.aMessageRegs[asRegs[19]] = str.toHexWord(cpu.segDS.sel);
|
||||
this.aMessageRegs[asRegs[20]] = str.toHexWord(cpu.regEIP);
|
||||
this.aMessageRegs[asRegs[16]] = str.toHexWord(cpu.getES());
|
||||
this.aMessageRegs[asRegs[17]] = str.toHexWord(cpu.getCS());
|
||||
this.aMessageRegs[asRegs[18]] = str.toHexWord(cpu.getSS());
|
||||
this.aMessageRegs[asRegs[19]] = str.toHexWord(cpu.getDS());
|
||||
this.aMessageRegs[asRegs[20]] = str.toHexWord(cpu.getIP());
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -1593,7 +1593,7 @@ if (DEBUGGER) {
|
|||
Debugger.prototype.message = function(sMessage, fAddress)
|
||||
{
|
||||
if (fAddress) {
|
||||
sMessage += " @" + str.toHexAddr(this.cpu.regEIP, this.cpu.segCS.sel);
|
||||
sMessage += " @" + str.toHexAddr(this.cpu.getIP(), this.cpu.getCS());
|
||||
}
|
||||
|
||||
if (this.sMessagePrev && sMessage == this.sMessagePrev) return;
|
||||
|
|
@ -1659,7 +1659,7 @@ if (DEBUGGER) {
|
|||
* at the moment. If that changes, then this will have to change as well.
|
||||
*/
|
||||
addr -= 2;
|
||||
this.message("INT 0x" + str.toHexByte(nInt) + ": AH=" + str.toHexByte(AH) + " @" + str.toHexAddr(addr - this.cpu.segCS.base, this.cpu.segCS.sel) + sFunc);
|
||||
this.message("INT 0x" + str.toHexByte(nInt) + ": AH=" + str.toHexByte(AH) + " @" + str.toHexAddr(addr - this.cpu.segCS.base, this.cpu.getCS()) + sFunc);
|
||||
}
|
||||
return fMessage;
|
||||
};
|
||||
|
|
@ -1696,7 +1696,7 @@ if (DEBUGGER) {
|
|||
if (addrFrom == null || (this.bitsMessage & bitsMessage) == bitsMessage) {
|
||||
var segFrom = null;
|
||||
if (addrFrom != null) {
|
||||
segFrom = this.cpu.segCS.sel;
|
||||
segFrom = this.cpu.getCS();
|
||||
addrFrom -= this.cpu.segCS.base;
|
||||
}
|
||||
this.message(component.idComponent + "." + (bOut != null? "outPort" : "inPort") + "(0x" + str.toHexWord(port) + "," + (name? name : "unknown") + (bOut != null? ",0x" + str.toHexByte(bOut) : "") + ")" + (bIn != null? (": 0x" + str.toHexByte(bIn)) : "") + (addrFrom != null? (" @" + str.toHexAddr(addrFrom, segFrom)) : ""));
|
||||
|
|
@ -1737,7 +1737,7 @@ if (DEBUGGER) {
|
|||
if (this.traceEnabled !== undefined && this.traceEnabled[prop]) {
|
||||
var trace = Debugger.TRACE[prop];
|
||||
var len = (trace.size >> 2);
|
||||
var s = str.toHexAddr(this.cpu.opLIP - this.cpu.segCS.base, this.cpu.segCS.sel) + " " + Debugger.asIns[trace.ins] + "(" + str.toHex(dst, len) + "," + str.toHex(src, len) + "," + (flagsIn === null? "-" : str.toHexWord(flagsIn)) + ") " + str.toHex(result, len) + "," + (flagsOut === null? "-" : str.toHexWord(flagsOut));
|
||||
var s = str.toHexAddr(this.cpu.opLIP - this.cpu.segCS.base, this.cpu.getCS()) + " " + Debugger.asIns[trace.ins] + "(" + str.toHex(dst, len) + "," + str.toHex(src, len) + "," + (flagsIn === null? "-" : str.toHexWord(flagsIn)) + ") " + str.toHex(result, len) + "," + (flagsOut === null? "-" : str.toHexWord(flagsOut));
|
||||
if (!this.aTraceBuffer.length) this.aTraceBuffer = new Array(Debugger.TRACE_LIMIT);
|
||||
this.aTraceBuffer[this.iTraceBuffer++] = s;
|
||||
if (this.iTraceBuffer >= this.aTraceBuffer.length) {
|
||||
|
|
@ -1893,7 +1893,7 @@ if (DEBUGGER) {
|
|||
if (fRegs === undefined) fRegs = true;
|
||||
if (fCompact === undefined) fCompact = true;
|
||||
|
||||
this.aAddrNextCode = this.newAddr(this.cpu.regEIP, this.cpu.segCS.sel);
|
||||
this.aAddrNextCode = this.newAddr(this.cpu.getIP(), this.cpu.getCS());
|
||||
/*
|
||||
* this.fProcStep used to be a simple boolean, but now it's 0 (or undefined)
|
||||
* if inactive, 1 if stepping over an instruction without a register dump, or 2
|
||||
|
|
@ -1979,7 +1979,7 @@ if (DEBUGGER) {
|
|||
this.historyInit();
|
||||
this.cInstructions = 0;
|
||||
this.nCycles = 0;
|
||||
this.aAddrNextCode = this.newAddr(this.cpu.regEIP, this.cpu.segCS.sel);
|
||||
this.aAddrNextCode = this.newAddr(this.cpu.getIP(), this.cpu.getCS());
|
||||
/*
|
||||
* fRunning is set by start() and cleared by stop(). In addition, we clear
|
||||
* it here, so that if the CPU is reset while running, we can prevent stop()
|
||||
|
|
@ -2168,13 +2168,13 @@ if (DEBUGGER) {
|
|||
* This is a good example of what NOT to do in a high-frequency function, and defeats
|
||||
* the purpose of preallocating and preinitializing the history array in historyInit():
|
||||
*
|
||||
* this.aOpcodeHistory[this.iOpcodeHistory] = this.newAddr(this.cpu.regEIP, this.cpu.segCS.sel, addr);
|
||||
* 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.regEIP;
|
||||
a[1] = this.cpu.segCS.sel;
|
||||
a[0] = this.cpu.getIP();
|
||||
a[1] = this.cpu.getCS();
|
||||
a[2] = addr;
|
||||
if (++this.iOpcodeHistory == this.aOpcodeHistory.length) this.iOpcodeHistory = 0;
|
||||
}
|
||||
|
|
@ -2273,10 +2273,10 @@ if (DEBUGGER) {
|
|||
*/
|
||||
Debugger.prototype.getSegment = function(sel)
|
||||
{
|
||||
if (sel == this.cpu.segCS.sel) return this.cpu.segCS;
|
||||
if (sel == this.cpu.segDS.sel) return this.cpu.segDS;
|
||||
if (sel == this.cpu.segES.sel) return this.cpu.segES;
|
||||
if (sel == this.cpu.segSS.sel) return this.cpu.segSS;
|
||||
if (sel == this.cpu.getCS()) return this.cpu.segCS;
|
||||
if (sel == this.cpu.getDS()) return this.cpu.segDS;
|
||||
if (sel == this.cpu.getES()) return this.cpu.segES;
|
||||
if (sel == this.cpu.getSS()) return this.cpu.segSS;
|
||||
var seg = new X86Seg(this.cpu, X86Seg.ID.DEBUG, "DBG");
|
||||
/*
|
||||
* TODO: Confirm that it's OK for this function to drop any error from seg.load() on the floor....
|
||||
|
|
@ -3044,7 +3044,7 @@ if (DEBUGGER) {
|
|||
" DI=" + str.toHexWord(this.cpu.regEDI) + '\n';
|
||||
s += this.getSegStr(this.cpu.segDS, fProt) + ' ' + this.getSegStr(this.cpu.segES, fProt) + ' ' + this.getSegStr(this.cpu.segSS, fProt);
|
||||
s += (fProt? '\n' : ' ');
|
||||
s += this.getSegStr(this.cpu.segCS, fProt) + " IP=" + str.toHexWord(this.cpu.regEIP) +
|
||||
s += this.getSegStr(this.cpu.segCS, fProt) + " IP=" + str.toHexWord(this.cpu.getIP()) +
|
||||
this.getFlagStr("V") + this.getFlagStr("D") + this.getFlagStr("I") + this.getFlagStr("T") +
|
||||
this.getFlagStr("S") + this.getFlagStr("Z") + this.getFlagStr("A") + this.getFlagStr("P") + this.getFlagStr("C") +
|
||||
" PS=" + str.toHexWord(this.cpu.getPS());
|
||||
|
|
@ -3158,23 +3158,23 @@ if (DEBUGGER) {
|
|||
value = this.cpu.regESP;
|
||||
break;
|
||||
case "CS":
|
||||
value = this.cpu.segCS.sel;
|
||||
value = this.cpu.getCS();
|
||||
break;
|
||||
case "DS":
|
||||
value = this.cpu.segDS.sel;
|
||||
value = this.cpu.getDS();
|
||||
break;
|
||||
case "ES":
|
||||
value = this.cpu.segES.sel;
|
||||
value = this.cpu.getES();
|
||||
break;
|
||||
case "SS":
|
||||
value = this.cpu.segSS.sel;
|
||||
value = this.cpu.getSS();
|
||||
break;
|
||||
/*
|
||||
* I used to alias "PC" to "IP", until I discovered that early (perhaps even ALL) versions of DEBUG.COM
|
||||
* treat "PC" as an alias for the 16-bit flags register. So for purposes of parseValue(), "PC" has been removed.
|
||||
*/
|
||||
case "IP":
|
||||
value = this.cpu.regEIP;
|
||||
value = this.cpu.getIP();
|
||||
break;
|
||||
default:
|
||||
value = str.parseInt(sValue);
|
||||
|
|
@ -4342,12 +4342,12 @@ if (DEBUGGER) {
|
|||
case "CS":
|
||||
// fIns = true;
|
||||
this.cpu.setCS(w);
|
||||
this.aAddrNextCode = this.newAddr(this.cpu.regEIP, this.cpu.segCS.sel);
|
||||
this.aAddrNextCode = this.newAddr(this.cpu.getIP(), this.cpu.getCS());
|
||||
break;
|
||||
case "IP":
|
||||
// fIns = true;
|
||||
this.cpu.setIP(w);
|
||||
this.aAddrNextCode = this.newAddr(this.cpu.regEIP, this.cpu.segCS.sel);
|
||||
this.aAddrNextCode = this.newAddr(this.cpu.getIP(), this.cpu.getCS());
|
||||
break;
|
||||
/*
|
||||
* I used to alias "PC" to "IP", until I discovered that early (perhaps ALL) versions of
|
||||
|
|
@ -4420,7 +4420,7 @@ if (DEBUGGER) {
|
|||
this.println((fCompact? '' : '\n') + this.getRegStr(fProt));
|
||||
|
||||
if (fIns) {
|
||||
this.aAddrNextCode = this.newAddr(this.cpu.regEIP, this.cpu.segCS.sel);
|
||||
this.aAddrNextCode = this.newAddr(this.cpu.getIP(), this.cpu.getCS());
|
||||
this.doUnassemble(this.hexAddr(this.aAddrNextCode));
|
||||
}
|
||||
};
|
||||
|
|
@ -4461,7 +4461,7 @@ if (DEBUGGER) {
|
|||
if (!this.fProcStep) {
|
||||
var fPrefix;
|
||||
var fRepeat = false;
|
||||
var aAddr = this.newAddr(this.cpu.regEIP, this.cpu.segCS.sel);
|
||||
var aAddr = this.newAddr(this.cpu.getIP(), this.cpu.getCS());
|
||||
do {
|
||||
fPrefix = false;
|
||||
var bOpcode = this.getByte(aAddr);
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ Memory.TYPE = {
|
|||
Memory.readNone = function readNone(off)
|
||||
{
|
||||
if (DEBUGGER && this.dbg.messageEnabled(Messages.MEM) /* && !off */) {
|
||||
this.dbg.message("attempt to read invalid block %" + str.toHex(this.addr) + " from " + str.toHexAddr(this.cpu.regEIP, this.cpu.segCS.sel));
|
||||
this.dbg.message("attempt to read invalid block %" + str.toHex(this.addr) + " from " + str.toHexAddr(this.cpu.getIP(), this.cpu.getCS()));
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -468,11 +468,11 @@ Panel.prototype.updateRegisters = function()
|
|||
this.drawText("SP", this.cpu.regESP, 0, 1);
|
||||
this.drawText("DX", this.cpu.regEDX, 2);
|
||||
this.drawText("BP", this.cpu.regEBP, 0, 2);
|
||||
this.drawText("CS", this.cpu.segCS.sel, 2);
|
||||
this.drawText("DS", this.cpu.segDS.sel, 0, 1);
|
||||
this.drawText("SS", this.cpu.segSS.sel, 2);
|
||||
this.drawText("ES", this.cpu.segES.sel, 0, 2);
|
||||
this.drawText("IP", this.cpu.regEIP, 2);
|
||||
this.drawText("CS", this.cpu.getCS(), 2);
|
||||
this.drawText("DS", this.cpu.getDS(), 0, 1);
|
||||
this.drawText("SS", this.cpu.getSS(), 2);
|
||||
this.drawText("ES", this.cpu.getES(), 0, 2);
|
||||
this.drawText("IP", this.cpu.getIP(), 2);
|
||||
var regPS;
|
||||
this.drawText("PS", regPS = this.cpu.getPS(), 0, 2);
|
||||
this.initCols(9);
|
||||
|
|
|
|||
|
|
@ -795,11 +795,12 @@ X86CPU.prototype.reset = function()
|
|||
* CS Base = 0xFF0000 DS/ES/SS Base = 0x000000 IDT Base = 0x000000
|
||||
* CS Limit = 0xFFFF DS/ES/SS Limit = 0xFFFF IDT Limit = 0x03FF
|
||||
*
|
||||
* We define some additional "registers", such as regLIP. which mirrors the linear address corresponding
|
||||
* to CS:IP (ie, the address of the next opcode). This means that whenever segCS or regEIP are explicitly
|
||||
* modified, regLIP must be updated as well. So, when setting segCS or regEIP, you should always use setCSIP(),
|
||||
* which takes both an offset and a segment, or setIP(), whichever is appropriate; in unusual cases where only
|
||||
* segCS is changing (eg, undocumented 8086 opcodes), use setCS().
|
||||
* We define some additional "registers", such as regLIP. which mirrors the linear address corresponding to
|
||||
* CS:IP (the address of the next opcode byte). In fact, regLIP functions as our internal IP register, so any
|
||||
* code that needs the real IP must call getIP(). This, in turn, means that whenever CS or IP must be modified,
|
||||
* regLIP must be recalculated, so you must use either setCSIP(), which takes both an offset and a segment,
|
||||
* or setIP(), whichever is appropriate; in unusual cases where only segCS is changing (eg, undocumented 8086
|
||||
* opcodes), use setCS().
|
||||
*
|
||||
* The other segment registers (DS, SS and ES) have similar setters (for segDS, segSS and segES), but those
|
||||
* functions do not mirror any segment:offset values in the same way that regLIP mirrors CS:IP.
|
||||
|
|
@ -910,7 +911,7 @@ X86CPU.prototype.resetRegs = function()
|
|||
this.segTSS = new X86Seg(this, X86Seg.ID.TSS, "TSS", true); // TR
|
||||
this.segVER = new X86Seg(this, X86Seg.ID.OTHER, "VER", true); // a scratch segment register for VERR and VERW instructions
|
||||
this.setCSIP(0xFFF0, 0xF000); // in real-mode, 0xF000 defaults the CS base address to 0x0F0000
|
||||
this.segCS.setBase(0xFF0000); // which is why we must manually adjust the CS base address to 0xFF0000
|
||||
this.setCSBase(0xFF0000); // which is why we must manually adjust the CS base address to 0xFF0000
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -972,6 +973,7 @@ X86CPU.prototype.resetRegs = function()
|
|||
*/
|
||||
this.addrSize = this.segCS.addrSize;
|
||||
this.addrMask = this.segCS.addrMask;
|
||||
|
||||
/*
|
||||
* It's also worth noting that instructions that implicitly use the stack also rely on something called STACK size,
|
||||
* which is based on the BIG bit of the last descriptor loaded into SS; use the following segSS properties:
|
||||
|
|
@ -1047,7 +1049,7 @@ X86CPU.prototype.setOpMod = function()
|
|||
X86CPU.prototype.getChecksum = function()
|
||||
{
|
||||
var sum = (this.regEAX + this.regEBX + this.regECX + this.regEDX + this.regESP + this.regEBP + this.regESI + this.regEDI) | 0;
|
||||
sum = (sum + this.regEIP + this.segCS.sel + this.segDS.sel + this.segSS.sel + this.segES.sel + this.getPS()) | 0;
|
||||
sum = (sum + this.getIP() + this.getCS() + this.getDS() + this.getSS() + this.getES() + this.getPS()) | 0;
|
||||
return sum;
|
||||
};
|
||||
|
||||
|
|
@ -1238,7 +1240,7 @@ X86CPU.prototype.save = function()
|
|||
{
|
||||
var state = new State(this);
|
||||
state.set(0, [this.regEAX, this.regEBX, this.regECX, this.regEDX, this.regESP, this.regEBP, this.regESI, this.regEDI, this.nIOPL]);
|
||||
state.set(1, [this.regEIP, this.segCS.save(), this.segDS.save(), this.segSS.save(), this.segES.save(), this.saveProtMode(), this.getPS()]);
|
||||
state.set(1, [this.getIP(), this.segCS.save(), this.segDS.save(), this.segSS.save(), this.segES.save(), this.saveProtMode(), this.getPS()]);
|
||||
state.set(2, [this.segData.sName, this.segStack.sName, this.opFlags, this.opPrefixes, this.intFlags, this.regEA, this.regEAWrite]);
|
||||
state.set(3, [0, this.nTotalCycles, this.getSpeed()]);
|
||||
state.set(4, this.bus.saveMemory());
|
||||
|
|
@ -1322,6 +1324,17 @@ X86CPU.prototype.getSeg = function(sName)
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* getCS()
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @return {number}
|
||||
*/
|
||||
X86CPU.prototype.getCS = function()
|
||||
{
|
||||
return this.segCS.sel;
|
||||
};
|
||||
|
||||
/**
|
||||
* setCS(sel)
|
||||
*
|
||||
|
|
@ -1336,11 +1349,24 @@ X86CPU.prototype.getSeg = function(sName)
|
|||
*/
|
||||
X86CPU.prototype.setCS = function(sel)
|
||||
{
|
||||
this.regLIP = this.segCS.load(sel & 0xffff) + this.regEIP;
|
||||
var regEIP = this.getIP();
|
||||
this.regLIP = this.segCS.load(sel & 0xffff) + regEIP;
|
||||
this.regLIPLimit = this.segCS.base + this.segCS.limit;
|
||||
this.opFlags |= this.OPFLAG_NOINTR8086;
|
||||
if (PREFETCH) this.flushPrefetch(this.regLIP);
|
||||
};
|
||||
|
||||
/**
|
||||
* getDS()
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @return {number}
|
||||
*/
|
||||
X86CPU.prototype.getDS = function()
|
||||
{
|
||||
return this.segDS.sel;
|
||||
};
|
||||
|
||||
/**
|
||||
* setDS(sel)
|
||||
*
|
||||
|
|
@ -1353,6 +1379,17 @@ X86CPU.prototype.setDS = function(sel)
|
|||
this.opFlags |= this.OPFLAG_NOINTR8086;
|
||||
};
|
||||
|
||||
/**
|
||||
* getSS()
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @return {number}
|
||||
*/
|
||||
X86CPU.prototype.getSS = function()
|
||||
{
|
||||
return this.segSS.sel;
|
||||
};
|
||||
|
||||
/**
|
||||
* setSS(sel)
|
||||
*
|
||||
|
|
@ -1365,6 +1402,17 @@ X86CPU.prototype.setSS = function(sel)
|
|||
this.opFlags |= X86.OPFLAG.NOINTR;
|
||||
};
|
||||
|
||||
/**
|
||||
* getES()
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @return {number}
|
||||
*/
|
||||
X86CPU.prototype.getES = function()
|
||||
{
|
||||
return this.segES.sel;
|
||||
};
|
||||
|
||||
/**
|
||||
* setES(sel)
|
||||
*
|
||||
|
|
@ -1377,13 +1425,24 @@ X86CPU.prototype.setES = function(sel)
|
|||
this.opFlags |= this.OPFLAG_NOINTR8086;
|
||||
};
|
||||
|
||||
/**
|
||||
* getIP()
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @return {number}
|
||||
*/
|
||||
X86CPU.prototype.getIP = function()
|
||||
{
|
||||
return this.regLIP - this.segCS.base;
|
||||
};
|
||||
|
||||
/**
|
||||
* setIP(off)
|
||||
*
|
||||
* With the addition of flushPrefetch(), this function should only be called
|
||||
* for non-incremental IP updates; setIP(this.regEIP+1) is no longer appropriate.
|
||||
* for non-incremental IP updates; setIP(this.getIP()+1) is no longer appropriate.
|
||||
*
|
||||
* In fact, for performance reasons, it's preferable to increment regEIP yourself,
|
||||
* In fact, for performance reasons, it's preferable to increment regLIP yourself,
|
||||
* but you can also call advanceIP() if speed is not important.
|
||||
*
|
||||
* @this {X86CPU}
|
||||
|
|
@ -1391,7 +1450,7 @@ X86CPU.prototype.setES = function(sel)
|
|||
*/
|
||||
X86CPU.prototype.setIP = function(off)
|
||||
{
|
||||
this.regLIP = this.segCS.base + (this.regEIP = off & (I386? this.addrMask : 0xffff));
|
||||
this.regLIP = this.segCS.base + (off & (I386? this.addrMask : 0xffff));
|
||||
if (PREFETCH) this.flushPrefetch(this.regLIP);
|
||||
};
|
||||
|
||||
|
|
@ -1421,19 +1480,39 @@ X86CPU.prototype.setCSIP = function(off, sel, fCall)
|
|||
this.assert(!this.addrMask || (off & this.addrMask) == off);
|
||||
this.segCS.fCall = fCall;
|
||||
/*
|
||||
* We break this operation into the following discrete steps (eg, set IP, load CS, and then update LIP)
|
||||
* so that segCS.load(sel) has the option of modifying IP when sel refers to a gate (call, interrupt, trap, etc).
|
||||
* We break this operation into the following discrete steps (eg, set IP, load CS, and then update IP) so
|
||||
* that segCS.load(sel) has the ability to modify IP when sel refers to a gate (call, interrupt, trap, etc).
|
||||
*
|
||||
* NOTE: regEIP acts merely as a conduit for the IP, if any, that segCS.load() may load; regLIP is still our
|
||||
* internal instruction pointer. Callers that need the real IP must call getIP().
|
||||
*/
|
||||
this.regEIP = off;
|
||||
var base = this.segCS.load(sel);
|
||||
if (base != X86.ADDR_INVALID) {
|
||||
this.regLIP = base + this.regEIP;
|
||||
this.regLIPLimit = base + this.segCS.limit;
|
||||
if (PREFETCH) this.flushPrefetch(this.regLIP);
|
||||
return this.segCS.fStackSwitch;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* setCSBase(addr)
|
||||
*
|
||||
* Since the CPU must maintain regLIP as the sum of the CS base and the current IP, all calls to setBase()
|
||||
* for segCS need to go through here.
|
||||
*
|
||||
* @param {number} addr
|
||||
*/
|
||||
X86CPU.prototype.setCSBase = function(addr)
|
||||
{
|
||||
var regIP = this.getIP();
|
||||
this.segCS.setBase(addr);
|
||||
this.regLIP = addr + regIP;
|
||||
this.regLIPLimit = addr + this.segCS.limit;
|
||||
};
|
||||
|
||||
/**
|
||||
* advanceIP(inc)
|
||||
*
|
||||
|
|
@ -1442,8 +1521,12 @@ X86CPU.prototype.setCSIP = function(off, sel, fCall)
|
|||
*/
|
||||
X86CPU.prototype.advanceIP = function(inc)
|
||||
{
|
||||
this.regLIP = this.segCS.base + (this.regEIP = (this.regEIP + inc) & (I386? this.addrMask : 0xffff));
|
||||
if (PREFETCH) this.advancePrefetch(inc);
|
||||
this.regLIP += inc;
|
||||
if (this.regLIP <= this.regLIPLimit) {
|
||||
if (PREFETCH) this.advancePrefetch(inc);
|
||||
} else {
|
||||
this.setIP(this.regLIP - this.segCS.base);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2028,6 +2111,30 @@ X86CPU.prototype.getEAByte = function(seg, off)
|
|||
return b;
|
||||
};
|
||||
|
||||
/**
|
||||
* getEAByteData(off)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} off is a segment-relative offset
|
||||
* @return {number} byte (8-bit) value at that address
|
||||
*/
|
||||
X86CPU.prototype.getEAByteData = function(off)
|
||||
{
|
||||
return this.getEAByte(this.segData, off & (I386? this.addrMask : 0xffff));
|
||||
};
|
||||
|
||||
/**
|
||||
* getEAByteStack(off)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} off is a segment-relative offset
|
||||
* @return {number} byte (8-bit) value at that address
|
||||
*/
|
||||
X86CPU.prototype.getEAByteStack = function(off)
|
||||
{
|
||||
return this.getEAByte(this.segStack, off & (I386? this.addrMask : 0xffff));
|
||||
};
|
||||
|
||||
/**
|
||||
* getEAWord(seg, off)
|
||||
*
|
||||
|
|
@ -2049,6 +2156,30 @@ X86CPU.prototype.getEAWord = function(seg, off)
|
|||
return w;
|
||||
};
|
||||
|
||||
/**
|
||||
* getEAWordData(off)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} off is a segment-relative offset
|
||||
* @return {number} word (16-bit) value at that address
|
||||
*/
|
||||
X86CPU.prototype.getEAWordData = function(off)
|
||||
{
|
||||
return this.getEAWord(this.segData, off & (I386? this.addrMask : 0xffff));
|
||||
};
|
||||
|
||||
/**
|
||||
* getEAWordStack(off)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} off is a segment-relative offset
|
||||
* @return {number} word (16-bit) value at that address
|
||||
*/
|
||||
X86CPU.prototype.getEAWordStack = function(off)
|
||||
{
|
||||
return this.getEAWord(this.segStack, off & (I386? this.addrMask : 0xffff));
|
||||
};
|
||||
|
||||
/**
|
||||
* modEAByte(seg, off)
|
||||
*
|
||||
|
|
@ -2067,6 +2198,30 @@ X86CPU.prototype.modEAByte = function(seg, off)
|
|||
return b;
|
||||
};
|
||||
|
||||
/**
|
||||
* modEAByteData(off)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} off is a segment-relative offset
|
||||
* @return {number} byte (8-bit) value at that address
|
||||
*/
|
||||
X86CPU.prototype.modEAByteData = function(off)
|
||||
{
|
||||
return this.modEAByte(this.segData, off & (I386? this.addrMask : 0xffff));
|
||||
};
|
||||
|
||||
/**
|
||||
* modEAByteStack(off)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} off is a segment-relative offset
|
||||
* @return {number} byte (8-bit) value at that address
|
||||
*/
|
||||
X86CPU.prototype.modEAByteStack = function(off)
|
||||
{
|
||||
return this.modEAByte(this.segStack, off & (I386? this.addrMask : 0xffff));
|
||||
};
|
||||
|
||||
/**
|
||||
* modEAWord(seg, off)
|
||||
*
|
||||
|
|
@ -2088,120 +2243,6 @@ X86CPU.prototype.modEAWord = function(seg, off)
|
|||
return w;
|
||||
};
|
||||
|
||||
/**
|
||||
* getEAByteData(off)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} off is a segment-relative offset
|
||||
* @return {number} byte (8-bit) value at that address
|
||||
*/
|
||||
X86CPU.prototype.getEAByteData = function(off)
|
||||
{
|
||||
// return this.getEAByte(this.segData, off & this.addrMask);
|
||||
this.segEA = this.segData;
|
||||
this.regEA = this.segData.checkRead(this.offEA = off & (I386? this.addrMask : 0xffff), 0);
|
||||
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
|
||||
var b = this.getByte(this.regEA);
|
||||
if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiMemLo;
|
||||
return b;
|
||||
};
|
||||
|
||||
/**
|
||||
* getEAByteStack(off)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} off is a segment-relative offset
|
||||
* @return {number} byte (8-bit) value at that address
|
||||
*/
|
||||
X86CPU.prototype.getEAByteStack = function(off)
|
||||
{
|
||||
// return this.getEAByte(this.segStack, off & this.addrMask);
|
||||
this.segEA = this.segStack;
|
||||
this.regEA = this.segStack.checkRead(this.offEA = off & (I386? this.addrMask : 0xffff), 0);
|
||||
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
|
||||
var b = this.getByte(this.regEA);
|
||||
if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiMemLo;
|
||||
return b;
|
||||
};
|
||||
|
||||
/**
|
||||
* getEAWordData(off)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} off is a segment-relative offset
|
||||
* @return {number} word (16-bit) value at that address
|
||||
*/
|
||||
X86CPU.prototype.getEAWordData = function(off)
|
||||
{
|
||||
// return this.getEAWord(this.segData, off & this.addrMask);
|
||||
this.segEA = this.segData;
|
||||
this.regEA = this.segData.checkRead(this.offEA = off & (I386? this.addrMask : 0xffff), (I386? this.dataSize-1 : 1));
|
||||
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
|
||||
var w = I386? this.opMem.getWord(this.regEA) : this.getShort(this.regEA);
|
||||
if (BACKTRACK) {
|
||||
this.backTrack.btiEALo = this.backTrack.btiMemLo;
|
||||
this.backTrack.btiEAHi = this.backTrack.btiMemHi;
|
||||
}
|
||||
return w;
|
||||
};
|
||||
|
||||
/**
|
||||
* getEAWordStack(off)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} off is a segment-relative offset
|
||||
* @return {number} word (16-bit) value at that address
|
||||
*/
|
||||
X86CPU.prototype.getEAWordStack = function(off)
|
||||
{
|
||||
// return this.getEAWord(this.segStack, off & this.addrMask);
|
||||
this.segEA = this.segStack;
|
||||
this.regEA = this.segStack.checkRead(this.offEA = off & (I386? this.addrMask : 0xffff), (I386? this.dataSize-1 : 1));
|
||||
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
|
||||
var w = I386? this.opMem.getWord(this.regEA) : this.getShort(this.regEA);
|
||||
if (BACKTRACK) {
|
||||
this.backTrack.btiEALo = this.backTrack.btiMemLo;
|
||||
this.backTrack.btiEAHi = this.backTrack.btiMemHi;
|
||||
}
|
||||
return w;
|
||||
};
|
||||
|
||||
/**
|
||||
* modEAByteData(off)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} off is a segment-relative offset
|
||||
* @return {number} byte (8-bit) value at that address
|
||||
*/
|
||||
X86CPU.prototype.modEAByteData = function(off)
|
||||
{
|
||||
// return this.modEAByte(this.segData, off & this.addrMask);
|
||||
this.segEA = this.segData;
|
||||
this.regEAWrite = this.regEA = this.segData.checkRead(this.offEA = off & (I386? this.addrMask : 0xffff), 0);
|
||||
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
|
||||
var b = this.getByte(this.regEA);
|
||||
if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiMemLo;
|
||||
return b;
|
||||
};
|
||||
|
||||
/**
|
||||
* modEAByteStack(off)
|
||||
*
|
||||
* @this {X86CPU}
|
||||
* @param {number} off is a segment-relative offset
|
||||
* @return {number} byte (8-bit) value at that address
|
||||
*/
|
||||
X86CPU.prototype.modEAByteStack = function(off)
|
||||
{
|
||||
// return this.modEAByte(this.segStack, off & this.addrMask);
|
||||
this.segEA = this.segStack;
|
||||
this.regEAWrite = this.regEA = this.segStack.checkRead(this.offEA = off & (I386? this.addrMask : 0xffff), 0);
|
||||
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
|
||||
var b = this.getByte(this.regEA);
|
||||
if (BACKTRACK) this.backTrack.btiEALo = this.backTrack.btiMemLo;
|
||||
return b;
|
||||
};
|
||||
|
||||
/**
|
||||
* modEAWordData(off)
|
||||
*
|
||||
|
|
@ -2211,16 +2252,7 @@ X86CPU.prototype.modEAByteStack = function(off)
|
|||
*/
|
||||
X86CPU.prototype.modEAWordData = function(off)
|
||||
{
|
||||
// return this.modEAWord(this.segData, off & this.addrMask);
|
||||
this.segEA = this.segData;
|
||||
this.regEAWrite = this.regEA = this.segData.checkRead(this.offEA = off & (I386? this.addrMask : 0xffff), (I386? this.dataSize-1 : 1));
|
||||
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
|
||||
var w = I386? this.opMem.getWord(this.regEA) : this.getShort(this.regEA);
|
||||
if (BACKTRACK) {
|
||||
this.backTrack.btiEALo = this.backTrack.btiMemLo;
|
||||
this.backTrack.btiEAHi = this.backTrack.btiMemHi;
|
||||
}
|
||||
return w;
|
||||
return this.modEAWord(this.segData, off & (I386? this.addrMask : 0xffff));
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2232,16 +2264,7 @@ X86CPU.prototype.modEAWordData = function(off)
|
|||
*/
|
||||
X86CPU.prototype.modEAWordStack = function(off)
|
||||
{
|
||||
// return this.modEAWord(this.segStack, off & this.addrMask);
|
||||
this.segEA = this.segStack;
|
||||
this.regEAWrite = this.regEA = this.segStack.checkRead(this.offEA = off & (I386? this.addrMask : 0xffff), (I386? this.dataSize-1 : 1));
|
||||
if (this.opFlags & X86.OPFLAG.NOREAD) return 0;
|
||||
var w = I386? this.opMem.getWord(this.regEA) : this.getShort(this.regEA);
|
||||
if (BACKTRACK) {
|
||||
this.backTrack.btiEALo = this.backTrack.btiMemLo;
|
||||
this.backTrack.btiEAHi = this.backTrack.btiMemHi;
|
||||
}
|
||||
return w;
|
||||
return this.modEAWord(this.segStack, off & (I386? this.addrMask : 0xffff));
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2485,7 +2508,9 @@ X86CPU.prototype.getIPByte = function()
|
|||
{
|
||||
var b = (PREFETCH? this.getBytePrefetch(this.regLIP) : this.getByte(this.regLIP));
|
||||
if (BACKTRACK) this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMemLo);
|
||||
this.regLIP = this.segCS.base + (this.regEIP = (this.regEIP + 1) & (I386? this.addrMask : 0xffff));
|
||||
if (++this.regLIP > this.regLIPLimit) {
|
||||
this.setIP(this.regLIP - this.segCS.base);
|
||||
}
|
||||
return b;
|
||||
};
|
||||
|
||||
|
|
@ -2497,10 +2522,12 @@ X86CPU.prototype.getIPByte = function()
|
|||
*/
|
||||
X86CPU.prototype.getIPDisp = function()
|
||||
{
|
||||
var b = ((PREFETCH? this.getBytePrefetch(this.regLIP) : this.getByte(this.regLIP)) << 24) >> 24;
|
||||
var w = ((PREFETCH? this.getBytePrefetch(this.regLIP) : this.getByte(this.regLIP)) << 24) >> 24;
|
||||
if (BACKTRACK) this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMemLo);
|
||||
this.regLIP = this.segCS.base + (this.regEIP = (this.regEIP + 1) & (I386? this.addrMask : 0xffff));
|
||||
return b & (I386? this.addrMask : 0xffff);
|
||||
if (++this.regLIP > this.regLIPLimit) {
|
||||
this.setIP(this.regLIP - this.segCS.base);
|
||||
}
|
||||
return w & (I386? this.addrMask : 0xffff);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -2516,7 +2543,10 @@ X86CPU.prototype.getIPWord = function()
|
|||
this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMemLo);
|
||||
this.bus.updateBackTrackCode(this.regLIP + 1, this.backTrack.btiMemHi);
|
||||
}
|
||||
this.regLIP = this.segCS.base + (this.regEIP = (this.regEIP + (I386? this.dataSize : 2)) & (I386? this.addrMask : 0xffff));
|
||||
this.regLIP += this.addrSize;
|
||||
if (this.regLIP > this.regLIPLimit) {
|
||||
this.setIP(this.regLIP - this.segCS.base);
|
||||
}
|
||||
return w;
|
||||
};
|
||||
|
||||
|
|
@ -2531,6 +2561,9 @@ X86CPU.prototype.getSIBAddr = function(mod)
|
|||
{
|
||||
var b = PREFETCH? this.getBytePrefetch(this.regLIP) : this.getByte(this.regLIP);
|
||||
if (BACKTRACK) this.bus.updateBackTrackCode(this.regLIP, this.backTrack.btiMemLo);
|
||||
if (++this.regLIP > this.regLIPLimit) {
|
||||
this.setIP(this.regLIP - this.segCS.base);
|
||||
}
|
||||
return X86ModSIB.aOpModSIB[b].call(this, mod);
|
||||
};
|
||||
|
||||
|
|
@ -2728,11 +2761,11 @@ X86CPU.prototype.updateStatus = function(fForce)
|
|||
this.displayReg("BP", this.regEBP);
|
||||
this.displayReg("SI", this.regESI);
|
||||
this.displayReg("DI", this.regEDI);
|
||||
this.displayReg("CS", this.segCS.sel);
|
||||
this.displayReg("DS", this.segDS.sel);
|
||||
this.displayReg("SS", this.segSS.sel);
|
||||
this.displayReg("ES", this.segES.sel);
|
||||
this.displayReg("IP", this.regEIP);
|
||||
this.displayReg("CS", this.getCS());
|
||||
this.displayReg("DS", this.getDS());
|
||||
this.displayReg("SS", this.getSS());
|
||||
this.displayReg("ES", this.getES());
|
||||
this.displayReg("IP", this.getIP());
|
||||
var regPS = this.getPS();
|
||||
this.displayReg("PS", regPS);
|
||||
this.displayReg("V", (regPS & X86.PS.OF)? 1 : 0, 1);
|
||||
|
|
|
|||
|
|
@ -1112,7 +1112,7 @@ var X86Grps = {
|
|||
* @return {number}
|
||||
*/
|
||||
opGrpCALLw: function(dst, src) {
|
||||
this.pushWord(this.regEIP);
|
||||
this.pushWord(this.getIP());
|
||||
this.setIP(dst);
|
||||
this.nStepCycles -= (this.regEA < 0? this.CYCLES.nOpCyclesCallWR : this.CYCLES.nOpCyclesCallWM);
|
||||
this.opFlags |= X86.OPFLAG.NOWRITE;
|
||||
|
|
|
|||
|
|
@ -489,8 +489,8 @@ var X86Help = {
|
|||
* @param {number} sel
|
||||
*/
|
||||
opHelpCALLF: function(off, sel) {
|
||||
var regCS = this.segCS.sel;
|
||||
var regEIP = this.regEIP;
|
||||
var regCS = this.getCS();
|
||||
var regEIP = this.getIP();
|
||||
if (this.setCSIP(off, sel, true) != null) {
|
||||
this.pushWord(regCS);
|
||||
this.pushWord(regEIP);
|
||||
|
|
@ -553,11 +553,11 @@ var X86Help = {
|
|||
this.nStepCycles -= this.CYCLES.nOpCyclesInt + nCycles;
|
||||
this.segCS.fCall = true;
|
||||
var regPS = this.getPS();
|
||||
var regCS = this.segCS.sel;
|
||||
var regEIP = this.regEIP;
|
||||
var base = this.segCS.loadIDT(nIDT);
|
||||
if (base != X86.ADDR_INVALID) {
|
||||
this.regLIP = base + this.regEIP;
|
||||
var regCS = this.getCS();
|
||||
var regEIP = this.getIP();
|
||||
var addr = this.segCS.loadIDT(nIDT);
|
||||
if (addr != X86.ADDR_INVALID) {
|
||||
this.regLIP = addr;
|
||||
if (PREFETCH) this.flushPrefetch(this.regLIP);
|
||||
this.pushWord(regPS);
|
||||
this.pushWord(regCS);
|
||||
|
|
@ -727,7 +727,7 @@ var X86Help = {
|
|||
}
|
||||
|
||||
if (this.messageEnabled(bitsMessage) || fHalt) {
|
||||
var sMessage = (fHalt? '\n' : '') + "Fault " + str.toHexByte(nFault) + (nError != null? " (" + str.toHexWord(nError) + ")" : "") + " on opcode 0x" + str.toHexByte(bOpcode) + " at " + str.toHexAddr(this.regEIP, this.segCS.sel) + " (%" + str.toHex(this.regLIP, 6) + ")";
|
||||
var sMessage = (fHalt? '\n' : '') + "Fault " + str.toHexByte(nFault) + (nError != null? " (" + str.toHexWord(nError) + ")" : "") + " on opcode 0x" + str.toHexByte(bOpcode) + " at " + str.toHexAddr(this.getIP(), this.getCS()) + " (%" + str.toHex(this.regLIP, 6) + ")";
|
||||
var fRunning = this.aFlags.fRunning;
|
||||
if (this.printMessage(sMessage, bitsMessage)) {
|
||||
if (fHalt) {
|
||||
|
|
@ -766,7 +766,7 @@ var X86Help = {
|
|||
*/
|
||||
opHelpUndefined: function() {
|
||||
this.setIP(this.opLIP - this.segCS.base);
|
||||
this.setError("Undefined opcode 0x" + str.toHexByte(this.bus.getByteDirect(this.regLIP)) + " at " + str.toHexAddr(this.regEIP, this.segCS.sel));
|
||||
this.setError("Undefined opcode 0x" + str.toHexByte(this.bus.getByteDirect(this.regLIP)) + " at " + str.toHexAddr(this.getIP(), this.getCS()));
|
||||
this.stopCPU();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1525,7 +1525,7 @@ var X86OpXX = {
|
|||
opJO: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if (this.getOF()) {
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmpC;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1539,7 +1539,7 @@ var X86OpXX = {
|
|||
opJNO: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if (!this.getOF()) {
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmpC;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1553,7 +1553,7 @@ var X86OpXX = {
|
|||
opJC: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if (this.getCF()) {
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmpC;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1567,7 +1567,7 @@ var X86OpXX = {
|
|||
opJNC: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if (!this.getCF()) {
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmpC;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1581,7 +1581,7 @@ var X86OpXX = {
|
|||
opJZ: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if (this.getZF()) {
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmpC;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1595,7 +1595,7 @@ var X86OpXX = {
|
|||
opJNZ: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if (!this.getZF()) {
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmpC;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1609,7 +1609,7 @@ var X86OpXX = {
|
|||
opJBE: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if (this.getCF() || this.getZF()) {
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmpC;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1623,7 +1623,7 @@ var X86OpXX = {
|
|||
opJNBE: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if (!this.getCF() && !this.getZF()) {
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmpC;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1637,7 +1637,7 @@ var X86OpXX = {
|
|||
opJS: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if (this.getSF()) {
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmpC;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1651,7 +1651,7 @@ var X86OpXX = {
|
|||
opJNS: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if (!this.getSF()) {
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmpC;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1665,7 +1665,7 @@ var X86OpXX = {
|
|||
opJP: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if (this.getPF()) {
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmpC;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1679,7 +1679,7 @@ var X86OpXX = {
|
|||
opJNP: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if (!this.getPF()) {
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmpC;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1693,7 +1693,7 @@ var X86OpXX = {
|
|||
opJL: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if (!this.getSF() != !this.getOF()) { // jshint ignore:line
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmpC;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1707,7 +1707,7 @@ var X86OpXX = {
|
|||
opJNL: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if (!this.getSF() == !this.getOF()) { // jshint ignore:line
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmpC;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1721,7 +1721,7 @@ var X86OpXX = {
|
|||
opJLE: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if (this.getZF() || !this.getSF() != !this.getOF()) { // jshint ignore:line
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmpC;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1735,7 +1735,7 @@ var X86OpXX = {
|
|||
opJNLE: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if (!this.getZF() && !this.getSF() == !this.getOF()) { // jshint ignore:line
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmpC;
|
||||
return;
|
||||
}
|
||||
|
|
@ -3211,7 +3211,7 @@ var X86OpXX = {
|
|||
opLOOPNZ: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if ((this.regECX = (this.regECX - 1) & this.addrMask) && (this.resultValue & (this.resultSize - 1))) {
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesLoopNZ;
|
||||
return;
|
||||
}
|
||||
|
|
@ -3225,7 +3225,7 @@ var X86OpXX = {
|
|||
opLOOPZ: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if ((this.regECX = (this.regECX - 1) & this.addrMask) && !(this.resultValue & (this.resultSize - 1))) {
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesLoopZ;
|
||||
return;
|
||||
}
|
||||
|
|
@ -3239,7 +3239,7 @@ var X86OpXX = {
|
|||
opLOOP: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if ((this.regECX = (this.regECX - 1) & this.addrMask)) {
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesLoop;
|
||||
return;
|
||||
}
|
||||
|
|
@ -3253,7 +3253,7 @@ var X86OpXX = {
|
|||
opJCXZ: function() {
|
||||
var disp = this.getIPDisp();
|
||||
if (!this.regECX) {
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesLoopZ;
|
||||
return;
|
||||
}
|
||||
|
|
@ -3311,8 +3311,8 @@ var X86OpXX = {
|
|||
*/
|
||||
opCALL: function() {
|
||||
var disp = this.getIPWord();
|
||||
this.pushWord(this.regEIP);
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.pushWord(this.getIP());
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesCall;
|
||||
},
|
||||
/**
|
||||
|
|
@ -3322,7 +3322,7 @@ var X86OpXX = {
|
|||
*/
|
||||
opJMP: function() {
|
||||
var disp = this.getIPWord();
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmp;
|
||||
},
|
||||
/**
|
||||
|
|
@ -3341,7 +3341,7 @@ var X86OpXX = {
|
|||
*/
|
||||
opJMPs: function() {
|
||||
var disp = this.getIPDisp();
|
||||
this.setIP(this.regEIP + disp);
|
||||
this.setIP(this.getIP() + disp);
|
||||
this.nStepCycles -= this.CYCLES.nOpCyclesJmp;
|
||||
},
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ X86Seg.loadReal = function loadReal(sel, fSuppress)
|
|||
*
|
||||
* See X86.DESC for offset and bit definitions.
|
||||
*
|
||||
* IDT descriptor entries are handled separately by loadIDT(), which is mapped to loadRealIDT() or loadProtIDT().
|
||||
* IDT descriptor entries are handled separately by loadIDT(), which is mapped to loadIDTReal() or loadIDTProt().
|
||||
*
|
||||
* @this {X86Seg}
|
||||
* @param {number} sel
|
||||
|
|
@ -189,13 +189,13 @@ X86Seg.loadProt = function loadProt(sel, fSuppress)
|
|||
};
|
||||
|
||||
/**
|
||||
* loadRealIDT(nIDT)
|
||||
* loadIDTReal(nIDT)
|
||||
*
|
||||
* @this {X86Seg}
|
||||
* @param {number} nIDT
|
||||
* @return {number} base address of selected segment, or ADDR_INVALID if error (TODO: No error conditions exist yet)
|
||||
* @return {number} address from selected veector, or ADDR_INVALID if error (TODO: No error conditions exist yet)
|
||||
*/
|
||||
X86Seg.loadRealIDT = function loadRealIDT(nIDT)
|
||||
X86Seg.loadIDTReal = function loadIDTReal(nIDT)
|
||||
{
|
||||
var cpu = this.cpu;
|
||||
cpu.assert(nIDT >= 0 && nIDT < 256 && !cpu.addrIDT && cpu.addrIDTLimit == 0x03FF);
|
||||
|
|
@ -207,19 +207,19 @@ X86Seg.loadRealIDT = function loadRealIDT(nIDT)
|
|||
* TODO: Verify that 80286 real-mode actually enforces the above. See http://localhost:8088/pubs/pc/reference/intel/80286/progref/#page-260
|
||||
*/
|
||||
var addrIDT = cpu.addrIDT + (nIDT << 2);
|
||||
cpu.regEIP = cpu.getShort(addrIDT);
|
||||
var off = cpu.getShort(addrIDT);
|
||||
cpu.regPS &= ~(X86.PS.TF | X86.PS.IF);
|
||||
return this.load(cpu.getShort(addrIDT + 2));
|
||||
return this.load(cpu.getShort(addrIDT + 2)) + off;
|
||||
};
|
||||
|
||||
/**
|
||||
* loadProtIDT(nIDT)
|
||||
* loadIDTProt(nIDT)
|
||||
*
|
||||
* @this {X86Seg}
|
||||
* @param {number} nIDT
|
||||
* @return {number} base address of selected segment, or ADDR_INVALID if error (TODO: No error conditions exist yet)
|
||||
* @return {number} address from selected vector, or ADDR_INVALID if error (TODO: No error conditions exist yet)
|
||||
*/
|
||||
X86Seg.loadProtIDT = function loadProtIDT(nIDT)
|
||||
X86Seg.loadIDTProt = function loadIDTProt(nIDT)
|
||||
{
|
||||
var cpu = this.cpu;
|
||||
cpu.assert(nIDT >= 0 && nIDT < 256);
|
||||
|
|
@ -227,7 +227,7 @@ X86Seg.loadProtIDT = function loadProtIDT(nIDT)
|
|||
nIDT <<= 3;
|
||||
var addrDesc = cpu.addrIDT + nIDT;
|
||||
if (addrDesc + 7 <= cpu.addrIDTLimit) {
|
||||
return this.loadDesc8(addrDesc, nIDT);
|
||||
return this.loadDesc8(addrDesc, nIDT) + cpu.regEIP;
|
||||
}
|
||||
X86Help.opHelpFault.call(cpu, X86.EXCEPTION.GP_FAULT, nIDT | X86.ERRCODE.IDT | X86.ERRCODE.EXT, true);
|
||||
return X86.ADDR_INVALID;
|
||||
|
|
@ -423,7 +423,7 @@ X86Seg.switchTSS = function switchTSS(selNew, fNest)
|
|||
cpu.setShort(cpu.segTSS.addrDesc + X86.DESC.ACC.OFFSET, cpu.segTSS.acc |= X86.DESC.ACC.TYPE.TSS_BUSY);
|
||||
cpu.segTSS.type = X86.DESC.ACC.TYPE.TSS_BUSY;
|
||||
}
|
||||
cpu.setShort(addrOld + X86.TSS.TASK_IP, cpu.regEIP);
|
||||
cpu.setShort(addrOld + X86.TSS.TASK_IP, cpu.getIP());
|
||||
cpu.setShort(addrOld + X86.TSS.TASK_PS, cpu.getPS());
|
||||
cpu.setShort(addrOld + X86.TSS.TASK_AX, cpu.regEAX);
|
||||
cpu.setShort(addrOld + X86.TSS.TASK_CX, cpu.regECX);
|
||||
|
|
@ -821,7 +821,7 @@ X86Seg.prototype.updateMode = function(fProt)
|
|||
}
|
||||
if (fProt) {
|
||||
this.load = X86Seg.loadProt;
|
||||
this.loadIDT = X86Seg.loadProtIDT;
|
||||
this.loadIDT = X86Seg.loadIDTProt;
|
||||
this.checkRead = X86Seg.checkReadProt;
|
||||
this.checkWrite = X86Seg.checkWriteProt;
|
||||
if (this.acc & X86.DESC.ACC.TYPE.SEG) {
|
||||
|
|
@ -856,7 +856,7 @@ X86Seg.prototype.updateMode = function(fProt)
|
|||
}
|
||||
} else {
|
||||
this.load = X86Seg.loadReal;
|
||||
this.loadIDT = X86Seg.loadRealIDT;
|
||||
this.loadIDT = X86Seg.loadIDTReal;
|
||||
this.checkRead = X86Seg.checkReadReal;
|
||||
this.checkWrite = X86Seg.checkWriteReal;
|
||||
this.limit = 0xffff;
|
||||
|
|
|
|||
Loading…
Reference in a new issue