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

📄 realmodeublock.java

📁 JPC: x86 PC Hardware Emulator. 牛津大学开发的一个纯JAVA的x86系统结构硬件模拟器。
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/*    JPC: A x86 PC Hardware Emulator for a pure Java Virtual Machine    Release Version 2.0    A project from the Physics Dept, The University of Oxford    Copyright (C) 2007 Isis Innovation Limited    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License version 2 as published by    the Free Software Foundation.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License along    with this program; if not, write to the Free Software Foundation, Inc.,    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.     Details (including contact information) can be found at:     www.physics.ox.ac.uk/jpc*/package org.jpc.emulator.memory.codeblock.optimised;

import org.jpc.emulator.processor.*;
import org.jpc.emulator.processor.fpu64.*;
import org.jpc.emulator.memory.*;
import org.jpc.emulator.memory.codeblock.*;

public class RealModeUBlock implements RealModeCodeBlock, MicrocodeSet
{
    private static final ProcessorException exceptionDE = new ProcessorException(Processor.PROC_EXCEPTION_DE, true);
    private static final ProcessorException exceptionGP = new ProcessorException(Processor.PROC_EXCEPTION_GP, true);
    private static final ProcessorException exceptionSS = new ProcessorException(Processor.PROC_EXCEPTION_SS, true);
    private static final ProcessorException exceptionUD = new ProcessorException(Processor.PROC_EXCEPTION_UD, true);
    private static final ProcessorException exceptionBR = new ProcessorException(Processor.PROC_EXCEPTION_BR, true);

    private static final boolean[] parityMap;

    static
    {
        parityMap = new boolean[256];
        for (int i=0; i<256; i++)
        {
            boolean val = true;
            for (int j=0; j<8; j++)
                if ((0x1 & (i >> j)) == 1)
                    val = !val;

            parityMap[i] = val;
        }
    } 

    private static final double L2TEN = Math.log(10)/Math.log(2);
    private static final double L2E = Math.log(10)/Math.log(2);
    private static final double LOG2 = Math.log(10)/Math.log(2);
    private static final double LN2 = Math.log(2);
    private static final double POS0 = Double.longBitsToDouble(0x0l);


    private Processor cpu;
    private FpuState fpu;

    private int x86Count;

    protected int[] microcodes;
    protected int[] cumulativeX86Length;
    private int executeCount;

    public RealModeUBlock()
    {
    }

    public RealModeUBlock(int[] microcodes, int[] x86lengths)
    {
        this.microcodes = microcodes;
        cumulativeX86Length = x86lengths;
	if (cumulativeX86Length.length == 0)
	    x86Count = 0;
	else {
	    int count = 1;
	    for (int i = 1; i < cumulativeX86Length.length; i++) {
		if (cumulativeX86Length[i] > cumulativeX86Length[i-1]) count++;
	    }
	    x86Count = count;
	}
    }

    public int getX86Length()
    {
        if (microcodes.length == 0)
            return 0;
	return cumulativeX86Length[microcodes.length-1];
    }

    public int getX86Count()
    {
        return x86Count;
    }

    public String getDisplayString()
    {
        StringBuffer buf = new StringBuffer();
	buf.append(this.toString() + "\n");
        for (int i=0; i<microcodes.length; i++)
            buf.append(i+": "+microcodes[i]+"\n");
        return buf.toString();
    }

    public boolean handleMemoryRegionChange(int startAddress, int endAddress)
    {
        return false;
    }

    public String toString()
    {
	return "Real Mode Interpreted Block: "+hashCode();
    }

    public InstructionSource getAsInstructionSource()
    {
        int[] codes = new int[microcodes.length];
	int[] positions = new int[microcodes.length];
        System.arraycopy(microcodes, 0, codes, 0, codes.length);
        System.arraycopy(cumulativeX86Length, 0, positions, 0, positions.length);

	return new ArrayBackedInstructionSource(codes, positions);
    }

    public int[] getMicrocodes()
    {
        int[] result = new int[microcodes.length];
        System.arraycopy(microcodes, 0, result, 0, result.length);
        return result;
    }

    private Segment transferSeg0 = null;
    private int transferAddr0 = 0;
    private int transferReg0 = 0, transferReg1 = 0, transferReg2 = 0;
    private long transferReg0l = 0;
    private boolean transferEipUpdated = false;
    private int transferPosition = 0;
    private double transferFReg0 = 0, transferFReg1 = 0;

    private int uCodeXferReg0 = 0, uCodeXferReg1 = 0, uCodeXferReg2 = 0;
    private boolean uCodeXferLoaded = false;

    private void fullExecute(Processor cpu)
    {
        FpuState fpu = cpu.fpu;

	//recover variables from instance storage
	Segment seg0 = transferSeg0;
	int addr0 = transferAddr0;
	int reg0 = transferReg0, reg1 = transferReg1, reg2 = transferReg2;
	long reg0l = transferReg0l;
        double freg0 = transferFReg0, freg1 = transferFReg1;

	boolean eipUpdated = transferEipUpdated;
	int position = transferPosition;

	try {
	    switch (microcodes[position++]) {
	    case EIP_UPDATE:
		if (!eipUpdated) {
		    eipUpdated = true;
		    cpu.eip += cumulativeX86Length[position - 1];
		}
		break;
	    
	    case UNDEFINED: System.err.println("Undefined Opcode"); throw exceptionUD;
	    
	    case MEM_RESET: addr0 = 0; seg0 = null; break;
	    
	    case LOAD0_EAX: reg0 = cpu.eax; break;
	    case LOAD0_ECX: reg0 = cpu.ecx; break;
	    case LOAD0_EDX: reg0 = cpu.edx; break;
	    case LOAD0_EBX: reg0 = cpu.ebx; break;
	    case LOAD0_ESP: reg0 = cpu.esp; break;
	    case LOAD0_EBP: reg0 = cpu.ebp; break;
	    case LOAD0_ESI: reg0 = cpu.esi; break;
	    case LOAD0_EDI: reg0 = cpu.edi; break;
	    
	    case STORE0_EAX: cpu.eax = reg0; break;
	    case STORE0_ECX: cpu.ecx = reg0; break;
	    case STORE0_EDX: cpu.edx = reg0; break;
	    case STORE0_EBX: cpu.ebx = reg0; break;
	    case STORE0_ESP: cpu.esp = reg0; break;
	    case STORE0_EBP: cpu.ebp = reg0; break;
	    case STORE0_ESI: cpu.esi = reg0; break;
	    case STORE0_EDI: cpu.edi = reg0; break;
	    
	    case LOAD1_EAX: reg1 = cpu.eax; break;
	    case LOAD1_ECX: reg1 = cpu.ecx; break;
	    case LOAD1_EDX: reg1 = cpu.edx; break;
	    case LOAD1_EBX: reg1 = cpu.ebx; break;
	    case LOAD1_ESP: reg1 = cpu.esp; break;
	    case LOAD1_EBP: reg1 = cpu.ebp; break;
	    case LOAD1_ESI: reg1 = cpu.esi; break;
	    case LOAD1_EDI: reg1 = cpu.edi; break;
	    
	    case STORE1_EAX: cpu.eax = reg1; break;
	    case STORE1_ECX: cpu.ecx = reg1; break;
	    case STORE1_EDX: cpu.edx = reg1; break;
	    case STORE1_EBX: cpu.ebx = reg1; break;
	    case STORE1_ESP: cpu.esp = reg1; break;
	    case STORE1_EBP: cpu.ebp = reg1; break;
	    case STORE1_ESI: cpu.esi = reg1; break;
	    case STORE1_EDI: cpu.edi = reg1; break;
	    
	    case LOAD0_AX: reg0 = cpu.eax & 0xffff; break;
	    case LOAD0_CX: reg0 = cpu.ecx & 0xffff; break;
	    case LOAD0_DX: reg0 = cpu.edx & 0xffff; break;
	    case LOAD0_BX: reg0 = cpu.ebx & 0xffff; break;
	    case LOAD0_SP: reg0 = cpu.esp & 0xffff; break;
	    case LOAD0_BP: reg0 = cpu.ebp & 0xffff; break;
	    case LOAD0_SI: reg0 = cpu.esi & 0xffff; break;
	    case LOAD0_DI: reg0 = cpu.edi & 0xffff; break;
	    
	    case STORE0_AX: cpu.eax = (cpu.eax & ~0xffff) | (reg0 & 0xffff); break;
	    case STORE0_CX: cpu.ecx = (cpu.ecx & ~0xffff) | (reg0 & 0xffff); break;
	    case STORE0_DX: cpu.edx = (cpu.edx & ~0xffff) | (reg0 & 0xffff); break;
	    case STORE0_BX: cpu.ebx = (cpu.ebx & ~0xffff) | (reg0 & 0xffff); break;
	    case STORE0_SP: cpu.esp = (cpu.esp & ~0xffff) | (reg0 & 0xffff); break;
	    case STORE0_BP: cpu.ebp = (cpu.ebp & ~0xffff) | (reg0 & 0xffff); break;
	    case STORE0_SI: cpu.esi = (cpu.esi & ~0xffff) | (reg0 & 0xffff); break;
	    case STORE0_DI: cpu.edi = (cpu.edi & ~0xffff) | (reg0 & 0xffff); break;
	    
	    case STORE1_AX: cpu.eax = (cpu.eax & ~0xffff) | (reg1 & 0xffff); break;
	    case STORE1_CX: cpu.ecx = (cpu.ecx & ~0xffff) | (reg1 & 0xffff); break;
	    case STORE1_DX: cpu.edx = (cpu.edx & ~0xffff) | (reg1 & 0xffff); break;
	    case STORE1_BX: cpu.ebx = (cpu.ebx & ~0xffff) | (reg1 & 0xffff); break;
	    case STORE1_SP: cpu.esp = (cpu.esp & ~0xffff) | (reg1 & 0xffff); break;
	    case STORE1_BP: cpu.ebp = (cpu.ebp & ~0xffff) | (reg1 & 0xffff); break;
	    case STORE1_SI: cpu.esi = (cpu.esi & ~0xffff) | (reg1 & 0xffff); break;
	    case STORE1_DI: cpu.edi = (cpu.edi & ~0xffff) | (reg1 & 0xffff); break;
	    
	    case LOAD1_AX: reg1 = cpu.eax & 0xffff; break;
	    case LOAD1_CX: reg1 = cpu.ecx & 0xffff; break;
	    case LOAD1_DX: reg1 = cpu.edx & 0xffff; break;
	    case LOAD1_SP: reg1 = cpu.esp & 0xffff; break;
	    case LOAD1_BP: reg1 = cpu.ebp & 0xffff; break;
	    case LOAD1_SI: reg1 = cpu.esi & 0xffff; break;
	    case LOAD1_DI: reg1 = cpu.edi & 0xffff; break;
	    
	    case LOAD0_AL: reg0 = cpu.eax & 0xff; break;
	    case LOAD0_CL: reg0 = cpu.ecx & 0xff; break;
	    case LOAD0_DL: reg0 = cpu.edx & 0xff; break;
	    case LOAD0_BL: reg0 = cpu.ebx & 0xff; break;
	    case LOAD0_AH: reg0 = (cpu.eax >> 8) & 0xff; break;
	    case LOAD0_CH: reg0 = (cpu.ecx >> 8) & 0xff; break;
	    case LOAD0_DH: reg0 = (cpu.edx >> 8) & 0xff; break;
	    case LOAD0_BH: reg0 = (cpu.ebx >> 8) & 0xff; break;
	    
	    case STORE0_AL: cpu.eax = (cpu.eax & ~0xff) | (reg0 & 0xff); break;
	    case STORE0_CL: cpu.ecx = (cpu.ecx & ~0xff) | (reg0 & 0xff); break;
	    case STORE0_DL: cpu.edx = (cpu.edx & ~0xff) | (reg0 & 0xff); break;
	    case STORE0_AH: cpu.eax = (cpu.eax & ~0xff00) | ((reg0 << 8) & 0xff00); break;
	    case STORE0_CH: cpu.ecx = (cpu.ecx & ~0xff00) | ((reg0 << 8) & 0xff00); break;
	    case STORE0_DH: cpu.edx = (cpu.edx & ~0xff00) | ((reg0 << 8) & 0xff00); break;
	    case STORE0_BH: cpu.ebx = (cpu.ebx & ~0xff00) | ((reg0 << 8) & 0xff00); break;
	    
	    case LOAD1_AL: reg1 = cpu.eax & 0xff; break;
	    case LOAD1_CL: reg1 = cpu.ecx & 0xff; break;
	    case LOAD1_DL: reg1 = cpu.edx & 0xff; break;
	    case LOAD1_BL: reg1 = cpu.ebx & 0xff; break;
	    case LOAD1_AH: reg1 = (cpu.eax >> 8) & 0xff; break;
	    case LOAD1_CH: reg1 = (cpu.ecx >> 8) & 0xff; break;
	    case LOAD1_DH: reg1 = (cpu.edx >> 8) & 0xff; break;
	    case LOAD1_BH: reg1 = (cpu.ebx >> 8) & 0xff; break;
	    
	    case STORE1_AL: cpu.eax = (cpu.eax & ~0xff) | (reg1 & 0xff); break;
	    case STORE1_CL: cpu.ecx = (cpu.ecx & ~0xff) | (reg1 & 0xff); break;
	    case STORE1_DL: cpu.edx = (cpu.edx & ~0xff) | (reg1 & 0xff); break;
	    case STORE1_BL: cpu.ebx = (cpu.ebx & ~0xff) | (reg1 & 0xff); break;
	    case STORE1_AH: cpu.eax = (cpu.eax & ~0xff00) | ((reg1 << 8) & 0xff00); break;
	    case STORE1_CH: cpu.ecx = (cpu.ecx & ~0xff00) | ((reg1 << 8) & 0xff00); break;
	    case STORE1_DH: cpu.edx = (cpu.edx & ~0xff00) | ((reg1 << 8) & 0xff00); break;
	    case STORE1_BH: cpu.ebx = (cpu.ebx & ~0xff00) | ((reg1 << 8) & 0xff00); break;

	    case LOAD0_CR0: reg0 = cpu.getCR0(); break;
	    case LOAD0_CR2: reg0 = cpu.getCR2(); break;
	    case LOAD0_CR3: reg0 = cpu.getCR3(); break;
	    case LOAD0_CR4: reg0 = cpu.getCR4(); break;
			
	    case STORE0_CR0: cpu.setCR0(reg0); break;
	    case STORE0_CR2: cpu.setCR2(reg0); break;
	    case STORE0_CR3: cpu.setCR3(reg0); break;
	    case STORE0_CR4: cpu.setCR4(reg0); break;

	    case LOAD0_ES: reg0 = 0xffff & cpu.es.getSelector(); break;
	    case LOAD0_CS: reg0 = 0xffff & cpu.cs.getSelector(); break;
	    case LOAD0_SS: reg0 = 0xffff & cpu.ss.getSelector(); break;
	    case LOAD0_DS: reg0 = 0xffff & cpu.ds.getSelector(); break;
	    case LOAD0_FS: reg0 = 0xffff & cpu.fs.getSelector(); break;
	    case LOAD0_GS: reg0 = 0xffff & cpu.gs.getSelector(); break;

	    case STORE0_ES: cpu.es.setSelector(0xffff & reg0); break;
	    case STORE0_CS: cpu.cs.setSelector(0xffff & reg0); break;
	    case STORE0_SS: cpu.ss.setSelector(0xffff & reg0); break;
	    case STORE0_DS: cpu.ds.setSelector(0xffff & reg0); break;
	    case STORE0_FS: cpu.fs.setSelector(0xffff & reg0); break;
	    case STORE0_GS: cpu.gs.setSelector(0xffff & reg0); break;

	    case STORE1_CS: cpu.cs.setSelector(0xffff & reg1); break;
	    case STORE1_SS: cpu.ss.setSelector(0xffff & reg1); break;
	    case STORE1_DS: cpu.ds.setSelector(0xffff & reg1); break;
	    case STORE1_FS: cpu.fs.setSelector(0xffff & reg1); break;
	    case STORE1_GS: cpu.gs.setSelector(0xffff & reg1); break;
	    
	    case STORE0_FLAGS: cpu.setEFlags((cpu.getEFlags() & ~0xffff) | (reg0 & 0xffff)); break;
	    case STORE0_EFLAGS: cpu.setEFlags(reg0); break;

	    case LOAD0_FLAGS: reg0 = 0xffff & cpu.getEFlags(); break;
	    case LOAD0_EFLAGS: reg0 = cpu.getEFlags(); break;

	    case LOAD0_IB: reg0 = microcodes[position++] & 0xff; break;
	    case LOAD0_IW: reg0 = microcodes[position++] & 0xffff; break;
	    case LOAD0_ID: reg0 = microcodes[position++]; break;

	    case LOAD1_IB: reg1 = microcodes[position++] & 0xff; break;
	    case LOAD1_IW: reg1 = microcodes[position++] & 0xffff; break;
	    case LOAD1_ID: reg1 = microcodes[position++]; break;

	    case LOAD2_EAX: reg2 = cpu.eax; break;
	    case LOAD2_AX: reg2 = 0xffff & cpu.eax; break;

⌨️ 快捷键说明

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