80386 CPU detection fix

This commit is contained in:
Jeff Parsons 2015-07-14 16:32:41 -07:00
commit 75d8e1e193
24 changed files with 123 additions and 60 deletions

View file

@ -2279,7 +2279,7 @@ if (DEBUGGER) {
/*
* For purposes of display only, rewind addr to the address of the responsible "INT n" instruction; we
* know it's the two-byte "INT n" instruction because that's the only opcode handler that calls checkIntNotify()
* at the moment. If that changes, then this will have to change as well.
* at the moment.
*/
addr -= 2;
this.message("INT " + str.toHexByte(nInt) + ": AH=" + str.toHexByte(AH) + " @" + this.hexOffset(addr - this.cpu.segCS.base, this.cpu.getCS()) + sFunc);

View file

@ -400,7 +400,7 @@ CompaqController.readByte = function readCompaqControllerByte(off, addr)
b = (off & 0x1)? (this.controller.wRAMSetup >> 8) : (this.controller.wRAMSetup & 0xff);
}
if (DEBUG) {
this.controller.ram.printMessage("CompaqController.readByte(" + str.toHexWord(off) + ") returned " + str.toHexByte(b), true, true);
this.controller.ram.printMessage("CompaqController.readByte(" + str.toHexWord(off) + ") returned " + str.toHexByte(b), 0, true);
if (MAXDEBUG && DEBUGGER && off >= 0x2) this.dbg.stopCPU();
}
return b;
@ -459,7 +459,7 @@ CompaqController.writeByte = function writeCompaqControllerByte(off, b, addr)
* All bits in 0x80C00001 and 0x80C00003 are reserved, so we can simply ignore those writes.
*/
if (DEBUG) {
this.controller.ram.printMessage("CompaqController.writeByte(" + str.toHexWord(off) + "," + str.toHexByte(b) + ")", true, true);
this.controller.ram.printMessage("CompaqController.writeByte(" + str.toHexWord(off) + "," + str.toHexByte(b) + ")", 0, true);
}
};

View file

@ -1285,8 +1285,8 @@ Card.ATC = {
INDX: 0x10, // ATC Mode Control Register
GRAPHICS: 0x01, // bit 0: set for graphics mode, clear for alphanumeric mode
MONOEM: 0x02, // bit 1: set for monochrome emulation mode, clear for color emulation
TEXTGRCC: 0x04, // bit 2: set for line graphics in character codes 0xC0-0xDF, clear otherwise
TEXTBLINK: 0x08, // bit 3: set for text blink attribute, clear for background intensity attribute
TEXT_9DOT: 0x04, // bit 2: set for 9-dot replication in character codes 0xC0-0xDF
BLINK_ENABLE: 0x08, // bit 3: set for text/graphics blink, clear for background intensity
RESERVED: 0x10, // bit 4: reserved
PANCOMPAT: 0x20, // bit 5: set for pixel-panning compatibility
PELWIDTH: 0x40, // bit 6: set for 256-color modes, clear for all other modes
@ -3904,6 +3904,9 @@ Video.prototype.createFontColor = function(font, iColor, rgbColor, nDouble, offD
* This "bit" of logic takes care of those characters (0xC0-0xDF) whose 9th bit must mirror the 8th bit;
* in all other cases, any bit past the 8th bit is automatically zero. It also takes care of embedding a solid
* row of bits whenever fUnderline is true.
*
* TODO: For EGA/VGA, replication of the 9th dot needs to be based on the TEXT_9DOT bit of the ATC.MODE
* register, which is particularly important for user-defined fonts that do not want that bit replicated.
*/
var bit = (fUnderline? 1 : (b & (0x80 >> (x >= 8 && iChar >= 0xC0 && iChar <= 0xDF? 7 : x))));
var xDst = (x << nDouble);
@ -5100,7 +5103,13 @@ Video.prototype.updateScreenText = function(addrScreen, addrScreenLimit, iCell,
var dataBlink = 0;
var dataDraw = (Video.ATTRS.DRAW_FGND << 8);
var dataMask = 0xfffff;
if (this.cardActive.regMode & Card.MDA.MODE.BLINK_ENABLE) {
var fBlinkEnable = (this.cardActive.regMode & Card.MDA.MODE.BLINK_ENABLE);
if (this.nCard >= Video.CARD.EGA) {
fBlinkEnable = (this.cardActive.regATCData[Card.ATC.MODE.INDX] & Card.ATC.MODE.BLINK_ENABLE);
}
if (fBlinkEnable) {
dataBlink = (Video.ATTRS.BGND_BLINK << 8);
dataMask &= ~dataBlink;
if (!(this.cBlinks & 0x2)) dataMask &= ~dataDraw;
@ -5223,6 +5232,8 @@ Video.prototype.updateScreenGraphicsCGA = function(addrScreen, addrScreenLimit)
/**
* updateScreenGraphicsEGA(addrScreen, addrScreenLimit)
*
* TODO: Add support for blinking graphics (ATC.MODE.BLINK_ENABLE)
*
* @param addrScreen
* @param addrScreenLimit
*/
@ -5346,6 +5357,8 @@ Video.prototype.updateScreenGraphicsEGA = function(addrScreen, addrScreenLimit)
* (320x200x256), where each pixel's bits are contained within a single plane. This is essentially all 256-color
* modes (CHAIN4, "Mode X", etc), hence the hard-coded call to getCardColors(8).
*
* TODO: Add support for blinking graphics (ATC.MODE.BLINK_ENABLE)
*
* @param addrScreen
* @param addrScreenLimit
*/

View file

@ -431,7 +431,8 @@ X86.BACKTRACK = {
/*
* These PS flags are always stored directly in regPS for the 8086/8088, hence the
* "direct" designation; other processors must adjust these bits accordingly. The final
* adjusted value is stored in PS_DIRECT.
* adjusted value is stored in PS_DIRECT (ie, 80286 and up also include PS.IOPL.MASK and
* PS.NT in PS_DIRECT).
*/
X86.PS_DIRECT_8086 = (X86.PS.TF | X86.PS.IF | X86.PS.DF);

View file

@ -1014,6 +1014,7 @@ X86CPU.prototype.initProcessor = function()
{
this.PS_SET = X86.PS_SET_8086;
this.PS_DIRECT = X86.PS_DIRECT_8086;
this.PS_CLEAR_RM = X86.PS.IOPL.MASK | X86.PS.NT;
this.OPFLAG_NOINTR_8086 = X86.OPFLAG.NOINTR;
this.nShiftCountMask = 0xff; // on an 8086/8088, all shift counts are used as-is
@ -1080,6 +1081,13 @@ X86CPU.prototype.initProcessor = function()
if (I386 && this.model >= X86.MODEL_80386) {
var bOpcode;
/*
* TODO: Determine if the Nested Task (PS.NT) flag should really be cleared in real-mode on an 80386
* (we already know based on the OS/2 CPU test discussed in setPS() that it can't be set in real-mode
* on an 80286); for now, we assume that it should remain clear on all CPUs, to avoid any unexpected
* nested-task weirdness in real-mode.
*/
this.PS_CLEAR_RM = X86.PS.NT;
this.aOps[X86.OPCODE.FS] = X86.opFS; // 0x64
this.aOps[X86.OPCODE.GS] = X86.opGS; // 0x65
this.aOps[X86.OPCODE.OS] = X86.opOS; // 0x66
@ -2680,14 +2688,17 @@ X86CPU.prototype.setPS = function(regPS, cpl)
/*
* OS/2 1.0 discriminates between an 80286 and an 80386 based on whether an IRET in real-mode that
* pops 0xF000 into the flags is able to set *any* of flag bits 12-15: if it can, then OS/2 declares
* the CPU an 80386. Therefore, in real-mode, we must zero all incoming bits 12-15.
* the CPU an 80386.
*
* This has the added benefit of relieving us from zeroing the effective IOPL (this.nIOPL) whenever
* we're in real-mode, since we're zeroing the incoming IOPL bits up front now.
* So, if the CPU is an 80286, we zero incoming bits 12-14 in real-mode (bit 15 is never allowed to
* be modified, so there's no need to mask it). And if the CPU is an 80386, we zero only bit 14 (PS.NT),
* allowing the IOPL bits to change; however, that should not affect any real-mode operations, since
* segCS.cpl will always be zero, making the IOPL setting irrelevant.
*
* It's still an open question whether an 80386 should also clear the Nested Task (PS.NT) flag in
* real-mode; if not, then initProcessor() should set PS_CLEAR_RM to zero.
*/
if (!(this.regCR0 & X86.CR0.MSW.PE)) {
regPS &= ~(X86.PS.IOPL.MASK | X86.PS.NT | X86.PS.BIT15);
}
if (!(this.regCR0 & X86.CR0.MSW.PE)) regPS &= ~this.PS_CLEAR_RM;
/*
* There are some cases (eg, an IRET returning to a less privileged code segment) where the CPL

View file

@ -78,7 +78,7 @@ if (typeof module !== 'undefined') {
* @param {string} type
* @param {Object} [parms]
* @param {Object} [constructor]
* @param {number} [bitsMessage]
* @param {number} [bitsMessage] selects message(s) that the component wants to enable (default is 0)
*/
function Component(type, parms, constructor, bitsMessage)
{
@ -123,7 +123,7 @@ function Component(type, parms, constructor, bitsMessage)
this.clearError();
this.bindings = {};
this.dbg = null; // by default, no connection to a Debugger
this.bitsMessage = bitsMessage || -1;
this.bitsMessage = bitsMessage || 0;
Component.add(this);
}
@ -946,7 +946,7 @@ Component.prototype = {
bitsMessage = bitsMessage || this.bitsMessage;
}
var bitsEnabled = this.dbg.bitsMessage & bitsMessage;
return (bitsEnabled === bitsMessage || !!(bitsEnabled & this.dbg.bitsWarning));
return (!!bitsMessage && bitsEnabled === bitsMessage || !!(bitsEnabled & this.dbg.bitsWarning));
}
return false;
},