Some improvements for FOOTBALL, including support for the 386 LOADALL instruction
This commit is contained in:
parent
763b02794b
commit
a5b9e0cae7
27 changed files with 4431 additions and 3981 deletions
|
|
@ -554,11 +554,12 @@ X86.fnCALLw = function(dst, src)
|
|||
X86.fnCALLF = function(off, sel)
|
||||
{
|
||||
/*
|
||||
* Since we always push the return address AFTER calling setCSIP(), and since either push could trigger
|
||||
* Since we always push the return address AFTER calling setCSIP(), and since either push could trigger a
|
||||
* fault (eg, segment fault, page fault, etc), we must not only snapshot regLSP into opLSP, but also the
|
||||
* current CS into opCS, so that fnFault() can always make CALLF restartable.
|
||||
* current CS into opCS, so that fnFault() can always make CALLF restartable. Ditto for opSS and the SS register.
|
||||
*/
|
||||
this.opCS = this.getCS();
|
||||
this.opSS = this.getSS();
|
||||
this.opLSP = this.regLSP;
|
||||
var oldIP = this.getIP();
|
||||
var oldSize = (I386? this.sizeData : 2);
|
||||
|
|
@ -572,7 +573,7 @@ X86.fnCALLF = function(off, sel)
|
|||
this.pushData(oldIP, oldSize, oldSize);
|
||||
}
|
||||
this.opLSP = X86.ADDR_INVALID;
|
||||
this.opCS = -1;
|
||||
this.opCS = this.opSS = -1;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -3942,8 +3943,7 @@ X86.fnFault = function(nFault, nError, nCycles, fHalt)
|
|||
* Prior to each new burst of instructions, stepCPU() sets fComplete to true, and the only (normal) way
|
||||
* for fComplete to become false is through stopCPU(), which isn't ordinarily called, except by the Debugger.
|
||||
*/
|
||||
this.resetSizes();
|
||||
this.setIP(this.opLIP - this.segCS.base);
|
||||
this.setLIP(this.opLIP);
|
||||
}
|
||||
else if (this.model >= X86.MODEL_80186) {
|
||||
|
||||
|
|
@ -3951,16 +3951,24 @@ X86.fnFault = function(nFault, nError, nCycles, fHalt)
|
|||
|
||||
if (this.nFault < 0) {
|
||||
/*
|
||||
* Single-fault (error code is passed through, and the responsible instruction is restartable;
|
||||
* the call to resetSizes() is critical, otherwise setIP() may update IP with the wrong size if
|
||||
* the current instruction contains an OPERAND size override).
|
||||
* Single-fault (error code is passed through, and the responsible instruction is restartable.
|
||||
*/
|
||||
this.resetSizes();
|
||||
if (this.opCS != -1) {
|
||||
/*
|
||||
* HACK: We must slam 3 into this.segCS.cpl to ensure that loading the original CS segment doesn't
|
||||
* fail. For example, if we faulted in the middle of a ring transition that loaded CS with a higher
|
||||
* privilege (lower CPL) code segment, then our attempt here to reload the lower privilege (higher CPL)
|
||||
* code segment could be viewed as a privilege violation (which it would be outside this context).
|
||||
*/
|
||||
this.segCS.cpl = 3;
|
||||
this.setCS(this.opCS);
|
||||
this.opCS = -1;
|
||||
}
|
||||
this.setIP(this.opLIP - this.segCS.base);
|
||||
this.setLIP(this.opLIP);
|
||||
if (this.opSS != -1) {
|
||||
this.setSS(this.opSS);
|
||||
this.opSS = -1;
|
||||
}
|
||||
if (this.opLSP !== X86.ADDR_INVALID) {
|
||||
this.setSP((this.regESP & ~this.segSS.maskAddr) | (this.opLSP - this.segSS.base));
|
||||
this.opLSP = X86.ADDR_INVALID;
|
||||
|
|
@ -3970,22 +3978,24 @@ X86.fnFault = function(nFault, nError, nCycles, fHalt)
|
|||
/*
|
||||
* Double-fault (error code is always zero, and the responsible instruction is not restartable)
|
||||
*/
|
||||
nError = 0; nFault = X86.EXCEPTION.DF_FAULT;
|
||||
nError = 0;
|
||||
nFault = X86.EXCEPTION.DF_FAULT;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Triple-fault (usually referred to in Intel literature as a "shutdown", but at least on the 80286,
|
||||
* it's actually a "reset")
|
||||
*/
|
||||
nFault = -1; nError = 0;
|
||||
nError = 0;
|
||||
nFault = -1;
|
||||
this.resetRegs();
|
||||
fDispatch = fHalt = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (X86.fnFaultMessage.call(this, nFault, nError, fHalt)) {
|
||||
if (X86.fnCheckFault.call(this, nFault, nError, fHalt)) {
|
||||
/*
|
||||
* If this is a fault that would normally be dispatched BUT fnFaultMessage() wants us to halt,
|
||||
* If this is a fault that would normally be dispatched BUT fnCheckFault() wants us to halt,
|
||||
* then we throw a bogus fault number (-1), simply to interrupt the current instruction in exactly
|
||||
* the same way that a dispatched fault would interrupt it.
|
||||
*/
|
||||
|
|
@ -4060,7 +4070,7 @@ X86.fnPageFault = function(addr, fPresent, fWrite)
|
|||
};
|
||||
|
||||
/**
|
||||
* fnFaultMessage(nFault, nError, fHalt)
|
||||
* fnCheckFault(nFault, nError, fHalt)
|
||||
*
|
||||
* Aside from giving the Debugger an opportunity to report every fault, this also gives us the ability to
|
||||
* halt exception processing in tracks: return true to prevent the fault handler from being dispatched.
|
||||
|
|
@ -4076,7 +4086,7 @@ X86.fnPageFault = function(addr, fPresent, fWrite)
|
|||
* @param {boolean} [fHalt] (true to halt the CPU, false to not, undefined if "it depends")
|
||||
* @return {boolean|undefined} true to block the fault (often desirable when fHalt is true), otherwise dispatch it
|
||||
*/
|
||||
X86.fnFaultMessage = function(nFault, nError, fHalt)
|
||||
X86.fnCheckFault = function(nFault, nError, fHalt)
|
||||
{
|
||||
var bitsMessage = Messages.FAULT;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue