Fixed space handling on iOS 9.1
This commit is contained in:
parent
3bad5547c2
commit
bf75b8a059
5 changed files with 136 additions and 50 deletions
|
|
@ -60,7 +60,7 @@ if (NODE) {
|
|||
*
|
||||
* FPU Coprocessor Trivia
|
||||
*
|
||||
* Microsoft C libraries executed software interrupts in the range 0x34-0x3B immediately after
|
||||
* Microsoft C 4.00 libraries executed software interrupts in the range 0x34-0x3B immediately after
|
||||
* FPU operations, to assist with floating-point emulation when no coprocessor was present, since
|
||||
* processors prior to the 80286 had no mechanism for generating a fault when an unsupported FPU
|
||||
* instruction was executed.
|
||||
|
|
@ -68,7 +68,7 @@ if (NODE) {
|
|||
* In short, INT 0x34 through INT 0x3B was used after ESC opcodes 0xD8 through 0xDF, INT 0x3C was
|
||||
* used for FPU instructions containing a segment override, and INT 0x3D was used for FWAIT.
|
||||
*
|
||||
* A sample piece of code is available in x86ops.js, because it also highlights the Microsoft C
|
||||
* A sample piece of code is available in x86ops.js, because it also highlights the Microsoft C 4.00
|
||||
* library's dependency on the 8086/8088 behavior of "PUSH SP" (see the opPUSHSP_8086() function).
|
||||
*/
|
||||
|
||||
|
|
@ -276,6 +276,8 @@ X86FPU.prototype.restore = function(data)
|
|||
* us whenever an I/O operation that resets the coprocessor is performed. Only 80487 coprocessors and higher will
|
||||
* also clear the "exception" registers, but the 80487 is currently beyond my planned level of support.
|
||||
*
|
||||
* TODO: Add support for X86.FPU.CONTROL.PC (Precision Control) and X86.FPU.CONTROL.IC (Infinity Control)
|
||||
*
|
||||
* @this {X86FPU}
|
||||
*/
|
||||
X86FPU.prototype.resetFPU = function()
|
||||
|
|
@ -287,8 +289,8 @@ X86FPU.prototype.resetFPU = function()
|
|||
this.iST = 0; // the ST bits for regStatus are actually stored here
|
||||
if (DEBUG) {
|
||||
/*
|
||||
* All the registers were tagged "unused" above, which is all that would normally happen,
|
||||
* but debugging is a little easier if we also zero everything, too.
|
||||
* All the registers were tagged "unused" above, which is all that would normally happen, but debugging is
|
||||
* a little easier if we zero all the registers as well.
|
||||
*/
|
||||
for (var iReg = 0; iReg < this.regStack.length; iReg++) {
|
||||
this.regStack[iReg] = 0.0;
|
||||
|
|
@ -315,7 +317,7 @@ X86FPU.prototype.isModel = function(model)
|
|||
/**
|
||||
* isAtLeastModel(model)
|
||||
*
|
||||
* If the current model is greater than or equal to the specified model, then it's assumed the
|
||||
* If the current model is greater than or equal to the specified model, then it's assumed that the
|
||||
* current operation is supported, and we return true.
|
||||
*
|
||||
* @this {X86FPU}
|
||||
|
|
@ -334,9 +336,9 @@ X86FPU.prototype.isAtLeastModel = function(model)
|
|||
* to a "temp-real" (REAL80) and back again losslessly, otherwise a bug in either getTRFromLR() or getLRFromTR()
|
||||
* might exist. That test code can be resurrected from the repo; this code is being retained for future tests.
|
||||
*
|
||||
* NOTE: If either min or max is a value containing 32 or more bits AND bit 31 is set AND it has passed
|
||||
* through some bit-wise operation(s), then that value may end up being negative, so you may end up with an
|
||||
* inverted (or empty) range or other unexpected results.
|
||||
* NOTE: If either min or max is a value containing 32 or more significant bits AND bit 31 is set AND it has passed
|
||||
* through some bit-wise operation(s), then that value may end up being negative, so you may end up with an inverted
|
||||
* range, or a range that's smaller or larger than intended.
|
||||
*
|
||||
* @this {X86FPU}
|
||||
* @param {number} min (inclusive)
|
||||
|
|
@ -712,16 +714,16 @@ X86FPU.prototype.roundInteger = function(operand, max)
|
|||
{
|
||||
if (operand == null) return null;
|
||||
|
||||
var rc = (this.regControl & X86.FPU.CONTROL.RC), result;
|
||||
var rc = (this.regControl & X86.FPU.CONTROL.RC.MASK), result;
|
||||
|
||||
if (rc == X86.FPU.CONTROL.RC_NEAR) {
|
||||
if (rc == X86.FPU.CONTROL.RC.NEAR) {
|
||||
result = Math.round(operand);
|
||||
if (result - operand === 0.5 && (result % 2)) result--;
|
||||
}
|
||||
else if (rc == X86.FPU.CONTROL.RC_DOWN || rc == X86.FPU.CONTROL.RC_CHOP && operand > 0) {
|
||||
else if (rc == X86.FPU.CONTROL.RC.DOWN || rc == X86.FPU.CONTROL.RC.CHOP && operand > 0) {
|
||||
result = Math.floor(operand);
|
||||
}
|
||||
else { // X86.FPU.CONTROL.RC_UP or X86.FPU.CONTROL.RC_CHOP && operand <= 0
|
||||
else { // X86.FPU.CONTROL.RC.UP or X86.FPU.CONTROL.RC.CHOP && operand <= 0
|
||||
result = Math.ceil(operand);
|
||||
}
|
||||
|
||||
|
|
@ -1417,6 +1419,8 @@ X86FPU.prototype.saveEnv = function(addr)
|
|||
/**
|
||||
* opFPU(bOpcode, bModRM, dst, src)
|
||||
*
|
||||
* This is called by the CPU's ESC opcode handlers, after each instruction has been fully decoded.
|
||||
*
|
||||
* @this {X86FPU}
|
||||
* @param {number} bOpcode (0xD8-0xDF)
|
||||
* @param {number} bModRM
|
||||
|
|
@ -1485,6 +1489,23 @@ X86FPU.prototype.opFPU = function(bOpcode, bModRM, dst, src)
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* opWAIT()
|
||||
*
|
||||
* This is called by the CPU's WAIT opcode handler, giving us the opportunity to synchronize the FPU with the CPU,
|
||||
* charge an appropriate number of cycles, and return true. In this context, it's considered an FWAIT instruction,
|
||||
* but technically, it's the same opcode.
|
||||
*
|
||||
* If we choose to do nothing, then we must return false, so that the CPU can charge a default number of cycles.
|
||||
*
|
||||
* @this {X86FPU}
|
||||
* @return {boolean} true if implemented, false if not
|
||||
*/
|
||||
X86FPU.prototype.opWAIT = function()
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
||||
if (DEBUGGER) {
|
||||
/**
|
||||
* readFPUStack(i)
|
||||
|
|
|
|||
Loading…
Reference in a new issue