📄 protectedmodeublock.java
字号:
if ((Double.isInfinite(freg0) && (freg1 == 0.0)) || (Double.isInfinite(freg1) && (freg0 == 0.0)))
fpu.setInvalidOperation();
freg0 = freg0 * freg1;
} break;
case FSUB: {
if ((freg0 == Double.NEGATIVE_INFINITY && freg1 == Double.NEGATIVE_INFINITY) || (freg0 == Double.POSITIVE_INFINITY && freg1 == Double.POSITIVE_INFINITY))
fpu.setInvalidOperation();
freg0 = freg0 - freg1;
} break;
case FDIV: {
if (((freg0 == 0.0) && (freg1 == 0.0)) || (Double.isInfinite(freg0) && Double.isInfinite(freg1)))
fpu.setInvalidOperation();
if ((freg1 == 0.0) && !Double.isNaN(freg0) && !Double.isInfinite(freg0))
fpu.setZeroDivide();
freg0 = freg0 / freg1;
} break;
case FSQRT: {
if (freg0 < 0)
fpu.setInvalidOperation();
freg0 = Math.sqrt(freg0);
} break;
case FSIN: {
if (Double.isInfinite(freg0))
fpu.setInvalidOperation();
if ((freg0 > Long.MAX_VALUE) || (freg0 < Long.MIN_VALUE))
fpu.conditionCode |= 4; // set C2
else
freg0 = Math.sin(freg0);
} break;
case FCOS: {
if (Double.isInfinite(freg0))
fpu.setInvalidOperation();
if ((freg0 > Long.MAX_VALUE) || (freg0 < Long.MIN_VALUE))
fpu.conditionCode |= 4; // set C2
else
freg0 = Math.cos(freg0);
} break;
case FBCD2F: {
long n = 0;
long decade = 1;
for (int i = 0; i < 9; i++)
{
byte b = seg0.getByte(addr0 + i);
n += (b & 0xf) * decade;
decade *= 10;
n += ((b >> 4) & 0xf) * decade;
decade *= 10;
}
byte sign = seg0.getByte(addr0 + 9);
double m = (double)n;
if (sign < 0)
m *= -1.0;
freg0 = m;
} break;
case FF2BCD: {
long n = (long)Math.abs(freg0);
long decade = 1;
for (int i = 0; i < 9; i++)
{
int val = (int) ((n % (decade * 10)) / decade);
byte b = (byte) val;
decade *= 10;
val = (int) ((n % (decade * 10)) / decade);
b |= (val << 4);
seg0.setByte(addr0 + i, b);
}
seg0.setByte(addr0 + 9, (freg0 < 0) ? (byte)0x80 : (byte)0x00);
} break;
case FPATAN: freg0 = Math.atan2(freg1, freg0); break;
case FPREM: {
int d = Math.getExponent(freg0) - Math.getExponent(freg1);
if (d < 64)
{
// full remainder
fpu.conditionCode &= ~4; // clear C2
freg0 = freg0 % freg1;
// compute least significant bits -> C0 C3 C1
long i = (long)Math.rint(freg0 / freg1);
fpu.conditionCode &= 4;
if ((i & 1) != 0) fpu.conditionCode |= 2;
if ((i & 2) != 0) fpu.conditionCode |= 8;
if ((i & 4) != 0) fpu.conditionCode |= 1;
}
else
{
// partial remainder
fpu.conditionCode |= 4; // set C2
int n = 63; // implementation dependent in manual
double f = Math.pow(2.0, (double)(d - n));
double z = (freg0 / freg1) / f;
double qq = (z < 0) ? Math.ceil(z) : Math.floor(z);
freg0 = freg0 - (freg1 * qq * f);
}
} break;
case FPREM1: {
int d = Math.getExponent(freg0) - Math.getExponent(freg1);
if (d < 64)
{
// full remainder
fpu.conditionCode &= ~4; // clear C2
double z = Math.IEEEremainder(freg0, freg1);
// compute least significant bits -> C0 C3 C1
long i = (long)Math.rint(freg0 / freg1);
fpu.conditionCode &= 4;
if ((i & 1) != 0) fpu.conditionCode |= 2;
if ((i & 2) != 0) fpu.conditionCode |= 8;
if ((i & 4) != 0) fpu.conditionCode |= 1;
fpu.setST(0, z);
}
else
{
// partial remainder
fpu.conditionCode |= 4; // set C2
int n = 63; // implementation dependent in manual
double f = Math.pow(2.0, (double)(d - n));
double z = (freg0 / freg1) / f;
double qq = (z < 0) ? Math.ceil(z) : Math.floor(z);
freg0 = freg0 - (freg1 * qq * f);
}
} break;
case FPTAN: {
if ((freg0 > Math.pow(2.0, 63.0)) || (freg0 < -1.0*Math.pow(2.0, 63.0))) {
if (Double.isInfinite(freg0))
fpu.setInvalidOperation();
fpu.conditionCode |= 4;
} else
{
fpu.conditionCode &= ~4;
freg0 = Math.tan(freg0);
}
} break;
case FSCALE: freg0 = Math.scalb(freg0, (int) freg1); break;
// case FSINCOS: {
// freg1 = sin(freg0);
// freg0 = cos(freg0);
// } break;
case FXTRACT: {
int e = Math.getExponent(freg0);
freg1 = (double) e;
freg0 = Math.scalb(freg0, -e);
} break;
// case FYL2X: {
// freg0 = freg1 * log2(freg0);
// } break;
// case FYL2XP1: {
// freg0 = freg1 * log2(freg0 + 1.0);
// } break;
case FRNDINT: {
if (Double.isInfinite(freg0))
break; // preserve infinities
switch(fpu.getRoundingControl())
{
case FpuState.FPU_ROUNDING_CONTROL_EVEN:
freg0 = Math.rint(freg0);
break;
case FpuState.FPU_ROUNDING_CONTROL_DOWN:
freg0 = Math.floor(freg0);
break;
case FpuState.FPU_ROUNDING_CONTROL_UP:
freg0 = Math.ceil(freg0);
break;
case FpuState.FPU_ROUNDING_CONTROL_TRUNCATE:
freg0 = Math.signum(freg0) * Math.floor(Math.abs(freg0));
break;
default:
throw new IllegalStateException("Invalid rounding control value");
}
reg0 = (int)freg0;
reg0l = (long)freg0;
} break;
case FCHECK0: checkResult(freg0); break;
case FCHECK1: checkResult(freg1); break;
case FINIT: fpu.init(); break;
// case FSAVE_108: {
// seg0.setDoubleWord(addr0, fpu.getControl() & 0xffff);
// seg0.setDoubleWord(addr0 + 4, fpu.getStatus() & 0xffff);
// seg0.setDoubleWord(addr0 + 8, fpu.getTagWord() & 0xffff);
// seg0.setDoubleWord(addr0 + 12, 0 /* fpu.getIP() */);
// seg0.setDoubleWord(addr0 + 16, 0 /* opcode + selector*/);
// seg0.setDoubleWord(addr0 + 20, 0 /* operand pntr */);
// seg0.setDoubleWord(addr0 + 24, 0 /* more operand pntr */);
// for (int i = 0; i < 8; i++) {
// byte[] extended = FpuState64.doubleToExtended(fpu.ST(i), false /* this is WRONG!!!!!!! */);
// for (int j = 0; j < 10; j++)
// seg0.setByte(addr0 + 28 + j + (10 * i), extended[j]);
// }
// fpu.init();
// } break;
default: throw new IllegalStateException("Unknown uCode " + microcodes[position - 1]);
}
}
} catch (ProcessorException e) {
if (e.getVector() == -1)
throw new IllegalStateException("Execute Failed");
int nextPosition = position - 1; //this makes position point at the microcode that just barfed
if (eipUpdated)
cpu.eip -= cumulativeX86Length[nextPosition]; // undo the eipUpdate
if (!e.pointsToSelf()) {
cpu.eip += cumulativeX86Length[nextPosition];
} else {
for (int selfPosition = nextPosition; selfPosition >= 0; selfPosition--) {
if (cumulativeX86Length[selfPosition] != cumulativeX86Length[nextPosition]) {
cpu.eip += cumulativeX86Length[selfPosition];
break;
}
}
}
if (e.getVector() != Processor.PROC_EXCEPTION_PF) {
System.err.println("@ 0x" + Integer.toHexString(cpu.cs.translateAddressRead(cpu.eip)));
e.printStackTrace();
}
cpu.handleProtectedModeException(e.getVector(), e.hasErrorCode(), e.getErrorCode());
}
return Math.max(executeCount, 0);
}
private final void cmpsb_a32(Segment seg0)
{
int addrOne = cpu.esi;
int addrTwo = cpu.edi;
int dataOne = 0xff & seg0.getByte(addrOne);
int dataTwo = 0xff & cpu.es.getByte(addrTwo);
if (cpu.eflagsDirection) {
addrOne -= 1;
addrTwo -= 1;
} else {
addrOne += 1;
addrTwo += 1;
}
cpu.esi = addrOne;
cpu.edi = addrTwo;
sub_o8_flags(dataOne - dataTwo, dataOne, dataTwo);
}
private final void cmpsw_a32(Segment seg0)
{
int addrOne = cpu.esi;
int addrTwo = cpu.edi;
int dataOne = 0xffff & seg0.getWord(addrOne);
int dataTwo = 0xffff & cpu.es.getWord(addrTwo);
if (cpu.eflagsDirection) {
addrOne -= 2;
addrTwo -= 2;
} else {
addrOne += 2;
addrTwo += 2;
}
cpu.esi = addrOne;
cpu.edi = addrTwo;
sub_o16_flags(dataOne - dataTwo, dataOne, dataTwo);
}
private final void cmpsd_a32(Segment seg0)
{
int addrOne = cpu.esi;
int addrTwo = cpu.edi;
int dataOne = seg0.getDoubleWord(addrOne);
int dataTwo = cpu.es.getDoubleWord(addrTwo);
if (cpu.eflagsDirection) {
addrOne -= 4;
addrTwo -= 4;
} else {
addrOne += 4;
addrTwo += 4;
}
cpu.esi = addrOne;
cpu.edi = addrTwo;
sub_o32_flags((0xffffffffl & dataOne) - (0xffffffffl & dataTwo), dataOne, dataTwo);
}
private final void repe_cmpsb_a16(Segment seg0)
{
int count = 0xFFFF & cpu.ecx;
int addrOne = 0xFFFF & cpu.esi;
int addrTwo = 0xFFFF & cpu.edi;
boolean used = count != 0;
int dataOne = 0;
int dataTwo = 0;
try {
if (cpu.eflagsDirection) {
while (count != 0) {
//check hardware interrupts
dataOne = 0xff & seg0.getByte(addrOne);
dataTwo = 0xff & cpu.es.getByte(addrTwo);
count--;
addrOne -= 1;
addrTwo -= 1;
if (dataOne != dataTwo) break;
}
} else {
while (count != 0) {
//check hardware interrupts
dataOne = 0xff & seg0.getByte(addrOne);
dataTwo = 0xff & cpu.es.getByte(addrTwo);
count--;
addrOne += 1;
addrTwo += 1;
if (dataOne != dataTwo) break;
}
}
}
finally {
executeCount += ((cpu.ecx &0xFFFF) - count);
cpu.ecx = (cpu.ecx & ~0xFFFF)|(count & 0xFFFF);
cpu.esi = (cpu.esi & ~0xFFFF)|(addrOne & 0xFFFF);
cpu.edi = (cpu.edi & ~0xFFFF)|(addrTwo & 0xFFFF);
if (used)
sub_o8_flags(dataOne - dataTwo, dataOne, dataTwo);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -