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

📄 virtual8086modeublock.java

📁 JPC: x86 PC Hardware Emulator. 牛津大学开发的一个纯JAVA的x86系统结构硬件模拟器。
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                
	    case STORE0_FPUCW: fpu.setControl(reg0); break;
	    case LOAD0_FPUCW: reg0 = fpu.getControl(); break;

	    case STORE0_FPUSW: fpu.setStatus(reg0); break;
	    case LOAD0_FPUSW: reg0 = fpu.getStatus(); break;

	    case FCOM: {
		int newcode = 0xd;
		if (Double.isNaN(freg0) || Double.isNaN(freg1))
		    fpu.setInvalidOperation();
		else {
		    if (freg0 > freg1) newcode = 0;
		    else if (freg0 < freg1) newcode = 1;
		    else newcode = 8;
		}
		fpu.conditionCode &= 2;
		fpu.conditionCode |= newcode;
	    } break;
	    case FUCOM: {
		int newcode = 0xd;
		if (!(Double.isNaN(freg0) || Double.isNaN(freg1)))
                    {
                        if (freg0 > freg1) newcode = 0;
                        else if (freg0 < freg1) newcode = 1;
                        else newcode = 8;
                    }
		fpu.conditionCode &= 2;
		fpu.conditionCode |= newcode;
	    } break;

	    case FPOP: fpu.pop(); break;
	    case FPUSH: fpu.push(freg0); break;
                
	    case FCHS: freg0 = -freg0; break;
	    case FABS: freg0 = Math.abs(freg0); break;
                    
	    case FADD: {
		if ((freg0 == Double.NEGATIVE_INFINITY && freg1 == Double.POSITIVE_INFINITY) || (freg0 == Double.POSITIVE_INFINITY && freg1 == Double.NEGATIVE_INFINITY))
		    fpu.setInvalidOperation();
		freg0 = freg0 + freg1;
	    } break;

	    case FMUL: {
		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 * Math.log(freg0)/Math.log(2);
// 	    } break;

// 	    case FYL2XP1: {
// 		freg0 = freg1 * Math.log1p(freg0)/Math.log(2);
// 	    } 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) {
	    throw e;
	} finally {
	    //copy local variables back to instance storage
	    transferSeg0 = seg0;
	    transferAddr0 = addr0;
	    transferReg0 = reg0;
	    transferReg1 = reg1;
	    transferReg2 = reg2;
	    transferReg0l = reg0l;
            transferFReg0 = freg0;
            transferFReg1 = freg1;
	    transferEipUpdated = eipUpdated;
	    transferPosition = position;
	}
    }

    public int execute(Processor cpu)
    {
 	this.fpu = cpu.fpu;
 	this.cpu = cpu;        
	
	Segment seg0 = null;
	int addr0 = 0;
	int reg0 = 0, reg1 = 0, reg2 = 0;
	long reg0l = 0;

        double freg0 = 0, freg1 = 0;

        executeCount = this.getX86Count();
	boolean eipUpdated = false;

	int position = 0;

	try 
        {
	    while (position < microcodes.length) {
                if (uCodeXferLoaded)
                {
                    uCodeXferLoaded = false;
                    reg0 = uCodeXferReg0;
                    reg1 = uCodeXferReg1;
                    reg2 = uCodeXferReg2;
                }
		switch (microcodes[position++]) {
		case MEM_RESET: addr0 = 0; seg0 = null; break; //4653406
		case ADDR_MASK16: addr0 &= 0xffff; break; //4653406
		case EIP_UPDATE:  if (!eipUpdated) { //4253320
                        eipUpdated = true;
                        cpu.eip += cumulativeX86Length[position - 1];
                    } break;
		case ADDR_IB: addr0 += ((byte)microcodes[position++]); break; //3832219
		case PUSH_O16_A16: push_o16_a16((short)reg0); break; //3221577
		case LOAD_SEG_SS: seg0 = cpu.ss; break; //2739696
		case LOAD0_AX: reg0 = cpu.eax & 0xffff; break; //2718333
		case ADDR_BP: addr0 += ((short)cpu.ebp); break; //2701629
		case LOAD0_IB: reg0 = microcodes[position++] & 0xff; break; //2567113
		case LOAD0_MEM_WORD:  reg0 = 0xffff & seg0.getWord(addr0); break; //2352051
                    
		case STORE1_ESP: cpu.esp = reg1; break; //2252894
		case POP_O16_A16: //2251454
		    reg1 = (cpu.esp & ~0xffff) | ((cpu.esp + 2) & 0xffff);		
		    if ((microcodes[position] == STORE0_SS)) 	
			cpu.eflagsInterruptEnable = false;	
		    reg0 = cpu.ss.getWord(cpu.esp & 0xffff); 
		    break;
		case STORE0_AX:	cpu.eax = (cpu.eax & ~0xffff) | (reg0 & 0xffff); break; //2211780
		case LOAD0_IW: reg0 = microcodes[position++] & 0xffff; break; //1748064
		case LOAD_SEG_DS: seg0 = cpu.ds; break; //1556141
		case STORE0_BX: cpu.ebx = (cpu.ebx & ~0xffff) | (reg0 & 0xffff); break; //1295862
		case SUB: reg2 = reg0; reg0 = reg2 - reg1; break; //1166414
		case STORE0_BP: cpu.ebp = (cpu.ebp & ~0xffff) | (reg0 & 0xffff); break; //1077742
		case ADDR_BX: addr0 += ((short)cpu.ebx); break; //1018423
		case LOAD0_SP: reg0 = cpu.esp & 0xffff; break; //1017910
                    
		case ADD: reg2 = reg0; reg0 = reg2 + reg1; break; //1004121
	    	case STORE0_MEM_WORD:  seg0.setWord(addr0, (short)reg0); break; //896323
		case LOAD0_MEM_BYTE:  reg0 = 0xff & seg0.getByte(addr0); break; //839821
		case JNZ_O8: jnz_o8((byte)reg0); break; //837018

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -