⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 protectedmodeublock.java

📁 JPC: x86 PC Hardware Emulator. 牛津大学开发的一个纯JAVA的x86系统结构硬件模拟器。
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                    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 + -