A little more meat on the X86FPU bones

This commit is contained in:
Jeff Parsons 2015-11-15 11:13:59 -08:00
commit a1556df5a5
14 changed files with 801 additions and 81 deletions

View file

@ -1129,7 +1129,7 @@ ChipSet.prototype.powerUp = function(data, fRepower)
*/
ChipSet.prototype.powerDown = function(fSave, fShutdown)
{
return fSave && this.save? this.save() : true;
return fSave? this.save() : true;
};
/**

View file

@ -301,7 +301,7 @@ CPU.prototype.powerDown = function(fSave, fShutdown)
*
* this.aFlags.fPowered = false;
*/
return fSave && this.save ? this.save() : true;
return fSave? this.save() : true;
};
/**

View file

@ -432,6 +432,8 @@ if (DEBUGGER) {
"FINCSTP","FDECSTP","FFREE", "FNOP", "FWAIT"
];
Debugger.FPU_TAGS = ["VALID", "ZERO", "SPECIAL", "EMPTY"];
Debugger.CPU_8086 = 0;
Debugger.CPU_80186 = 1;
Debugger.CPU_80286 = 2;
@ -1404,6 +1406,7 @@ if (DEBUGGER) {
this.cmp = cmp;
this.fdc = cmp.getMachineComponent("FDC");
this.hdc = cmp.getMachineComponent("HDC");
this.fpu = cmp.getMachineComponent("FPU");
this.mouse = cmp.getMachineComponent("Mouse");
if (MAXDEBUG) this.chipset = cmp.getMachineComponent("ChipSet");
@ -3962,7 +3965,7 @@ if (DEBUGGER) {
Debugger.prototype.powerDown = function(fSave, fShutdown)
{
if (fShutdown) this.println(fSave? "suspending" : "shutting down");
return fSave && this.save? this.save() : true;
return fSave? this.save() : true;
};
/**
@ -4904,14 +4907,15 @@ if (DEBUGGER) {
var r_m = (bModRM & 0x7);
/*
* Similar to how fnFPU() decodes FPU instructions, we combine mod and reg into one
* Similar to how opFPU() decodes FPU instructions, we combine mod and reg into one
* decodable value: put mod in the high nibble and reg in the low nibble, after first
* collapsing all mod values < 3 to zero.
*/
var modReg = (mod < 3? 0 : 0x30) + reg;
/*
* Use values >= 0x40 to indicate mod == 0x3, with reg in the high nibble and r_m in the low.
* All values >= 0x34 imply mod == 3 and reg >= 4, so now we shift reg into the high
* nibble and r_m into the low.
*/
if ((bOpcode == X86.OPCODE.ESC1 || bOpcode == X86.OPCODE.ESC3) && modReg >= 0x34) {
modReg = (reg << 4) | r_m;
@ -7021,6 +7025,7 @@ if (DEBUGGER) {
if (asArgs && asArgs[1] == '?') {
this.println("register commands:");
this.println("\tr\tdump registers");
if (this.fpu) this.println("\trfp\tdump floating-point registers");
this.println("\trp\tdump all registers");
this.println("\trx [#]\tset flag or register x to [#]");
return;
@ -7031,9 +7036,14 @@ if (DEBUGGER) {
if (asArgs != null && asArgs.length > 1) {
var sReg = asArgs[1];
if (this.fpu && sReg == "fp") {
this.doFPURegisters(asArgs);
return;
}
if (sReg == 'p') {
fProt = (this.cpu.model >= X86.MODEL_80286);
} else {
}
else {
// fInstruction = false;
var sValue = null;
var i = sReg.indexOf('=');
@ -7269,6 +7279,26 @@ if (DEBUGGER) {
}
};
/**
* doFPURegisters(asArgs)
*
* NOTE: If we're called, the existence of an FPU has already been verified.
*
* @this {Debugger}
* @param {Array.<string>} [asArgs]
*/
Debugger.prototype.doFPURegisters = function(asArgs)
{
this.assert(this.fpu);
for (var i = 0; i < 8; i++) {
var a = this.fpu.readFPUStack(i);
if (!a) break;
var sValue = str.pad(a[2].toFixed(15), 24, true);
this.println("ST" + i + ": " + sValue + " " + str.toHex(a[4]) + "," + str.toHex(a[3]) + " [" + Debugger.FPU_TAGS[a[1]] + "]");
// this.println(" REG" + a[0] + " " + str.toBin(a[7], 16) + str.toBin(a[6]) + str.toBin(a[5]));
}
};
/**
* doRun(sCmd, sAddr, sOptions, fQuiet)
*

View file

@ -614,7 +614,7 @@ FDC.prototype.powerUp = function(data, fRepower)
*/
FDC.prototype.powerDown = function(fSave, fShutdown)
{
return fSave && this.save? this.save() : true;
return fSave? this.save() : true;
};
/**

View file

@ -572,7 +572,7 @@ HDC.prototype.powerUp = function(data, fRepower)
*/
HDC.prototype.powerDown = function(fSave, fShutdown)
{
return fSave && this.save? this.save() : true;
return fSave? this.save() : true;
};
/**

View file

@ -1373,7 +1373,7 @@ Keyboard.prototype.powerUp = function(data, fRepower)
*/
Keyboard.prototype.powerDown = function(fSave, fShutdown)
{
return fSave && this.save? this.save() : true;
return fSave? this.save() : true;
};
/**

View file

@ -294,7 +294,7 @@ Mouse.prototype.powerUp = function(data, fRepower)
*/
Mouse.prototype.powerDown = function(fSave, fShutdown)
{
return fSave && this.save? this.save() : true;
return fSave? this.save() : true;
};
/**

View file

@ -444,7 +444,7 @@ SerialPort.prototype.powerUp = function(data, fRepower)
*/
SerialPort.prototype.powerDown = function(fSave, fShutdown)
{
return fSave && this.save ? this.save() : true;
return fSave? this.save() : true;
};
/**

View file

@ -3497,7 +3497,7 @@ Video.prototype.powerUp = function(data, fRepower)
*/
Video.prototype.powerDown = function(fSave, fShutdown)
{
return fSave && this.save? this.save() : true;
return fSave? this.save() : true;
};
/**

View file

@ -524,6 +524,7 @@ var X86 = {
FPU: {
MODEL_8087: 8087,
MODEL_80287: 80287,
MODEL_80287XL: 80387, // internally, the 80287XL was an 80387SX, so I'm not sure we really want/need a unique identifier
MODEL_80387: 80387,
CONTROL: { // FPU Control Word
IM: 0x0001, // bit 0: Invalid Operation Mask
@ -532,13 +533,15 @@ var X86 = {
OM: 0x0008, // bit 3: Overflow Mask
UM: 0x0010, // bit 4: Underflow Mask
PM: 0x0020, // bit 5: Precision Mask
EXC: 0x003F, // all of the above exceptions
// bit 6: unused
IEM: 0x0080, // bit 7: Interrupt Enable Mask (0 enables interrupts, 1 masks them; 8087 only)
PC: 0x0300, // bits 8-9: Precision Control
RC: 0x0C00, // bits 10-11: Rounding Control
IC: 0x1000, // bit 12: Infinity Control (0 for Projective, 1 for Affine)
// bits 13-15: unused
INIT: 0x03BF // X86.FPU.CONTROL.IM | X86.FPU.CONTROL.DM | X86.FPU.CONTROL.ZM | X86.FPU.CONTROL.OM | X86.FPU.CONTROL.UM | X86.FPU.CONTROL.PM | X86.FPU.CONTROL.IEM | X86.FPU.CONTROL.PC
INIT: 0x03BF, // X86.FPU.CONTROL.IM | X86.FPU.CONTROL.DM | X86.FPU.CONTROL.ZM | X86.FPU.CONTROL.OM | X86.FPU.CONTROL.UM | X86.FPU.CONTROL.PM | X86.FPU.CONTROL.IEM | X86.FPU.CONTROL.PC
UNUSED: 0xE040
},
STATUS: { // FPU Status Word
IE: 0x0001, // bit 0: Invalid Operation
@ -555,7 +558,8 @@ var X86 = {
C2: 0x0400, // bit 10: Condition Code 2
ST: 0x3800, // bits 11-13: Stack Top
C3: 0x4000, // bit 14: Condition Code 3
BUSY: 0x8000 // bit 15: Busy
BUSY: 0x8000, // bit 15: Busy
ST_SHIFT: 11
},
TAGS: {
VALID: 0x0,

View file

@ -1186,6 +1186,8 @@ X86CPU.prototype.resetRegs = function()
this.opFlags = this.opPrefixes = 0;
this.regEA = this.regEAWrite = X86.ADDR_INVALID;
this.segEA = this.segNULL;
/*
* intFlags contains some internal states we use to indicate whether a hardware interrupt (INTFLAG.INTR) or
* Trap software interrupt (INTR.TRAP) has been requested, as well as when we're in a "HLT" state (INTFLAG.HALT)

File diff suppressed because it is too large Load diff

View file

@ -142,7 +142,8 @@ X86Seg.ID = {
TSS: 4, // "TSS"
LDT: 5, // "LDT"
VER: 6, // "VER"
DBG: 7 // "DBG"
FPU: 7, // "FPU"
DBG: 8 // "DBG"
};
X86Seg.CALLBREAK_SEL = 0x0001;

View file

@ -375,17 +375,19 @@ str.replaceArray = function(a, s)
};
/**
* pad(s, cch)
* pad(s, cch, fPadLeft)
*
* NOTE: the maximum amount of padding currently supported is 40 spaces.
*
* @param {string} s is a string
* @param {number} cch is desired length
* @param {boolean} [fPadLeft] (default is padding on the right)
* @returns {string} the original string (s) with spaces padding it to the specified length
*/
str.pad = function(s, cch)
str.pad = function(s, cch, fPadLeft)
{
return s + " ".substr(0, cch - s.length);
var sPadding = " ";
return fPadLeft? (sPadding + s).slice(-cch) : (s + sPadding).slice(0, cch);
};
/**