v1.20.0: Limited stepping support and a couple signed/unsigned division fixes
This commit is contained in:
parent
8c67a50f92
commit
dc8baec9f0
7 changed files with 2266 additions and 2224 deletions
|
|
@ -104,7 +104,7 @@ XBTS (Extract Bit String) instruction -- an instruction that existed only on B0
|
|||
&0654:12E8 CF IRET
|
||||
|
||||
If the above function returns 0xB0, then the 80386 is a B0 or earlier stepping, so Windows 95 displays the
|
||||
following message and exits:
|
||||
following message and aborts:
|
||||
|
||||
Windows may not run correctly with the 80386 processor that is installed in this computer.
|
||||
Upgrade your 80386 processor.
|
||||
|
|
@ -168,5 +168,40 @@ Windows 95 using a newer 80386, and then later "downgraded" the CPU to a B1, Win
|
|||
suffered from the multiplication flaw, you would see the 32-bit multiplication warning on start-up, but you could
|
||||
still continue to run, and if there was no multiplication problem, you would not see any message at all.
|
||||
|
||||
---
|
||||
|
||||
PCjs v1.20.0 now supports a "stepping" attribute on the <cpu> element, which you can use to simulate specific
|
||||
stepping behavior. For example, a *machine.xml* file with the following CPU definition:
|
||||
|
||||
<cpu id="cpu386" model="80386" stepping="b0"/>
|
||||
|
||||
will cause Windows 95 to abort exactly as described as above. Similarly, selecting a 80386 B1 stepping:
|
||||
|
||||
<cpu id="cpu386" model="80386" stepping="b1"/>
|
||||
|
||||
will cause Windows 95 to display the 32-bit multiplication warning shown above (PCjs deliberately fails the exact
|
||||
multiplication test that Windows 95 performs).
|
||||
|
||||
If you want to simulate a B1 stepping that does *not* have the 32-bit multiplication flaw, set the stepping to B2:
|
||||
|
||||
<cpu id="cpu386" model="80386" stepping="b2"/>
|
||||
|
||||
B2 was not an actual 80386 stepping; it is a *pseudo-stepping* that provides a simple way of specifying a B1 80386 that
|
||||
passes all 32-bit multiplication tests.
|
||||
|
||||
As previously discussed, Windows 95 SETUP will refuse to install on any "A" or "B" stepping, but if it's already been
|
||||
installed, it *will* start up.
|
||||
|
||||
PCjs stepping support is extremely limited at this point. Here's a summary:
|
||||
|
||||
1. 80386 steppings A0-B0 provide *limited* support for the short-lived XBTS and IBTS instructions
|
||||
2. 80386 steppings A0-B1 enable [Errata #7](/blog/2015/02/23/) for STOSB (as tested by Windows 95; see above)
|
||||
3. 80386 stepping B1 enables 32-bit multiplication errors (as tested by Windows 95; see above)
|
||||
4. 80386 stepping B2 includes all supported B1 errata, but without 32-bit multiplication errors
|
||||
|
||||
In addition, on 80386 reset, we set the CPU revision number in DX to the appropriate value for the specified stepping.
|
||||
|
||||
Support for additional 80286 and 80386 errata may be added over time, as interesting scenarios or test cases are discovered.
|
||||
|
||||
*[@jeffpar](http://twitter.com/jeffpar)*
|
||||
*October 27, 2015*
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -957,7 +957,7 @@ X86CPU.prototype.setReg = function(i, reg)
|
|||
*
|
||||
* All other 80386 registers are undefined after a reset (ie, Intel did not document how or if they are set).
|
||||
*
|
||||
* We've elected to set DX to 0x0304 on a reset, which is consistent with a 80386-C0, since we have no desire to
|
||||
* We've elected to set DX to 0x0308 on a reset, the highest known 80386 revision, since we have no desire to
|
||||
* try to emulate all the bugs in older (eg, B1) steppings -- at least not initially. We leave stepping-accurate
|
||||
* emulation for another day. It's also known that the B1 (and possibly B0) reported 0x0303 in DX, and that
|
||||
* the D0 stepping reported 0x0305; beyond that, it's not known exactly what revision numbers Intel used for all
|
||||
|
|
@ -1079,9 +1079,10 @@ X86CPU.prototype.resetRegs = function()
|
|||
break;
|
||||
case X86.STEPPING_80386_D1:
|
||||
case X86.STEPPING_80386_D2:
|
||||
default:
|
||||
this.regEDX = 0x0308; // in the absence of a specific stepping, default to the highest known revision
|
||||
this.regEDX = 0x0308;
|
||||
break;
|
||||
default:
|
||||
break; // in the absence of a specific stepping, we leave DX set to zero
|
||||
}
|
||||
this.regCR0 = X86.CR0.ET; // formerly MSW
|
||||
this.regCR1 = 0; // reserved
|
||||
|
|
|
|||
|
|
@ -2955,7 +2955,7 @@ X86.opSTOSb = function()
|
|||
* TODO: Extend this errata to STOSW, as well as MOVSB, MOVSW, INSB, and INSW. Also, scope out the
|
||||
* extent to which this errara also existed on earlier steppings.
|
||||
*/
|
||||
if (this.stepping == X86.STEPPING_80386_B1) {
|
||||
if (this.stepping >= X86.STEPPING_80386_A0 && this.stepping <= X86.STEPPING_80386_B1) {
|
||||
if (!(this.opPrefixes & X86.OPFLAG.ADDRSIZE) != (this.getByte(this.regLIP) != X86.OPCODE.AS)) {
|
||||
maskAddr ^= (0xffff0000|0);
|
||||
}
|
||||
|
|
@ -4169,9 +4169,7 @@ X86.opGRP3b = function()
|
|||
{
|
||||
this.fMDSet = false;
|
||||
this.aOpModGrpByte[this.getIPByte()].call(this, X86.aOpGrp3b, X86.fnSRCNone);
|
||||
if (this.fMDSet) {
|
||||
this.regEAX = (this.regEAX & ~this.maskData) | (this.regMDLo & this.maskData);
|
||||
}
|
||||
if (this.fMDSet) this.regEAX = (this.regEAX & ~this.maskData) | (this.regMDLo & this.maskData);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue