v1.20.0: Limited stepping support and a couple signed/unsigned division fixes

This commit is contained in:
Jeff Parsons 2015-10-31 08:31:31 -07:00
commit dc8baec9f0
7 changed files with 2266 additions and 2224 deletions

View file

@ -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

View file

@ -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

View file

@ -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