📄 protectedmodeublock.java
字号:
/* 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 ProtectedModeUBlock implements ProtectedModeCodeBlock, MicrocodeSet
{
private static final ProcessorException exceptionDE = new ProcessorException(Processor.PROC_EXCEPTION_DE, true);
private static final ProcessorException exceptionGP = new ProcessorException(Processor.PROC_EXCEPTION_GP, 0, true);
private static final ProcessorException exceptionSS = new ProcessorException(Processor.PROC_EXCEPTION_SS, 0, true);
private static final ProcessorException exceptionUD = new ProcessorException(Processor.PROC_EXCEPTION_UD, 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 ProtectedModeUBlock()
{
}
public ProtectedModeUBlock(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 boolean handleMemoryRegionChange(int startAddress, int endAddress)
{
return false;
}
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 String toString()
{
return "Protected Mode Interpreted Block";
}
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;
}
public int execute(Processor cpu)
{
this.fpu = cpu.fpu;
this.cpu = cpu;
Segment seg0 = null;
int addr0 = 0, reg0 = 0, reg1 = 0, reg2 = 0;
long reg0l = 0;
double freg0 = 0.0, freg1 = 0.0;
executeCount = this.getX86Count();
boolean eipUpdated = false;
int position = 0;
try {
while (position < microcodes.length)
{
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_BX: reg1 = cpu.ebx & 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_BL: cpu.ebx = (cpu.ebx & ~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_DR0: reg0 = cpu.getDR0(); break;
case LOAD0_DR1: reg0 = cpu.getDR1(); break;
case LOAD0_DR2: reg0 = cpu.getDR2(); break;
case LOAD0_DR3: reg0 = cpu.getDR3(); break;
case LOAD0_DR6: reg0 = cpu.getDR6(); break;
case LOAD0_DR7: reg0 = cpu.getDR7(); break;
case STORE0_DR0: cpu.setDR0(reg0); break;
case STORE0_DR1: cpu.setDR1(reg0); break;
case STORE0_DR2: cpu.setDR2(reg0); break;
case STORE0_DR3: cpu.setDR3(reg0); break;
case STORE0_DR6: cpu.setDR6(reg0); break;
case STORE0_DR7: cpu.setDR7(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 = loadSegment(reg0); break;
//case STORE0_CS:
case STORE0_SS: {
Segment temp = loadSegment(reg0);
if (temp == SegmentFactory.NULL_SEGMENT)
throw (ProcessorException) exceptionGP;
cpu.ss = temp; cpu.eflagsInterruptEnable = false;
} break;
case STORE0_DS: cpu.ds = loadSegment(reg0); break;
case STORE0_FS: cpu.fs = loadSegment(reg0); break;
case STORE0_GS: cpu.gs = loadSegment(reg0); break;
case STORE1_ES: cpu.es = loadSegment(reg1); break;
//case STORE1_CS:
case STORE1_SS: {
Segment temp = loadSegment(reg1);
if (temp == SegmentFactory.NULL_SEGMENT)
throw (ProcessorException) exceptionGP;
cpu.ss = temp; cpu.eflagsInterruptEnable = false;
} break;
case STORE1_DS: cpu.ds = loadSegment(reg1); break;
case STORE1_FS: cpu.fs = loadSegment(reg1); break;
case STORE1_GS: cpu.gs = loadSegment(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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -