80386 CPU detection fix
This commit is contained in:
parent
32675aea39
commit
75d8e1e193
24 changed files with 123 additions and 60 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue