Skip to content
This repository has been archived by the owner on Dec 24, 2020. It is now read-only.

Commit

Permalink
v1.20.0: Limited stepping support and a couple signed/unsigned divisi…
Browse files Browse the repository at this point in the history
…on fixes
  • Loading branch information
jeffpar committed Oct 31, 2015
1 parent 0ebb1cf commit 5108ac0
Show file tree
Hide file tree
Showing 7 changed files with 2,266 additions and 2,224 deletions.
37 changes: 36 additions & 1 deletion blog/2015/10/27/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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*
1,298 changes: 650 additions & 648 deletions docs/pcjs/demos/pc-dbg.js

Large diffs are not rendered by default.

922 changes: 462 additions & 460 deletions docs/pcjs/demos/pc.js

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions modules/pcjs/lib/x86cpu.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
6 changes: 2 additions & 4 deletions modules/pcjs/lib/x86ops.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
};

/**
Expand Down
Loading

0 comments on commit 5108ac0

Please sign in to comment.