📄 lazycodeblockmemory.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;import org.jpc.emulator.memory.codeblock.*;import org.jpc.emulator.processor.Processor;import org.jpc.emulator.processor.ProcessorException;public class LazyCodeBlockMemory extends LazyMemory{ private static CodeBlockManager codeBlockManager; private static final BlankCodeBlock PLACEHOLDER = new BlankCodeBlock(0, 0); protected RealModeCodeBlock[] realCodeBuffer; protected ProtectedModeCodeBlock[] protectedCodeBuffer; protected Virtual8086ModeCodeBlock[] virtual8086CodeBuffer; public LazyCodeBlockMemory(Memory src) { super((int) src.getSize()); if (src.getSize() > 1024*1024*32) throw new IllegalStateException("Cannot create code block of size "+src.getSize()); constructCodeBlocksArray(); byte[] temp = new byte[(int) src.getSize()]; src.copyContentsInto(0, temp, 0, temp.length); copyContentsFrom(0, temp, 0, temp.length); if (codeBlockManager == null) codeBlockManager = new CodeBlockManager(); } public LazyCodeBlockMemory(byte[] buf) { super(buf); constructCodeBlocksArray(); if (codeBlockManager == null) codeBlockManager = new CodeBlockManager(); } public LazyCodeBlockMemory(int size) { super(size); constructCodeBlocksArray(); if (codeBlockManager == null) codeBlockManager = new CodeBlockManager(); } protected void constructCodeBlocksArray() { realCodeBuffer = new RealModeCodeBlock[(int)getSize()]; protectedCodeBuffer = new ProtectedModeCodeBlock[(int)getSize()]; virtual8086CodeBuffer = new Virtual8086ModeCodeBlock[(int)getSize()]; } public void relinquishCache() { } public int execute(Processor cpu, int offset) { if (cpu.isProtectedMode()) if (cpu.isVirtual8086Mode()) return executeVirtual8086(cpu, offset); else return executeProtected(cpu, offset); else return executeReal(cpu, offset); } public CodeBlock decodeCodeBlockAt(Processor cpu, int offset) { if (cpu.isProtectedMode()) if (cpu.isVirtual8086Mode()) return decodeVirtual8086(cpu, offset); else return decodeProtected(cpu, offset); else return decodeReal(cpu, offset); } private int executeProtected(Processor cpu, int offset) { int x86Count = 0; int ip = cpu.getInstructionPointer(); int startingBlock = ip & AddressSpace.INDEX_MASK; do { try { offset = ip & AddressSpace.BLOCK_MASK; ProtectedModeCodeBlock block = getProtectedModeCodeBlockAt(offset); try { try { x86Count += block.execute(cpu); } catch (NullPointerException e) { block = codeBlockManager.getProtectedModeCodeBlockAt(this, offset, cpu.cs.getDefaultSizeFlag()); x86Count += block.execute(cpu); } } catch (CodeBlockReplacementException e) { block = (ProtectedModeCodeBlock)e.getReplacement(); setProtectedCodeBlockAt(offset, block); x86Count += block.execute(cpu); } cpu.processProtectedModeInterrupts(); } catch (ProcessorException p) { cpu.handleProtectedModeException(p.getVector(), p.hasErrorCode(), p.getErrorCode()); } } while (((ip = cpu.getInstructionPointer()) & AddressSpace.INDEX_MASK) == startingBlock); return x86Count; } private CodeBlock decodeProtected(Processor cpu, int offset) { ProtectedModeCodeBlock block = getProtectedModeCodeBlockAt(offset); try { try { block.getX86Length(); } catch (NullPointerException e) { block = codeBlockManager.getProtectedModeCodeBlockAt(this, offset, cpu.cs.getDefaultSizeFlag()); block.getX86Length(); } } catch (CodeBlockReplacementException e) { block = (ProtectedModeCodeBlock)e.getReplacement(); setProtectedCodeBlockAt(offset, block); } return block; } private int executeReal(Processor cpu, int offset) { int x86Count = 0; int ip = cpu.getInstructionPointer(); int startingBlock = ip & AddressSpace.INDEX_MASK; do { try { offset = ip & AddressSpace.BLOCK_MASK; RealModeCodeBlock block = getRealModeCodeBlockAt(offset); try { try { x86Count += block.execute(cpu); } catch (NullPointerException e) { block = codeBlockManager.getRealModeCodeBlockAt(this, offset); x86Count += block.execute(cpu); } } catch (CodeBlockReplacementException e) { block = (RealModeCodeBlock)e.getReplacement(); setRealCodeBlockAt(offset, block); x86Count += block.execute(cpu); } cpu.processRealModeInterrupts(); } catch (ProcessorException p) { cpu.handleRealModeException(p.getVector()); } } while (((ip = cpu.getInstructionPointer()) & AddressSpace.INDEX_MASK) == startingBlock); return x86Count; } private CodeBlock decodeReal(Processor cpu, int offset) { RealModeCodeBlock block= getRealModeCodeBlockAt(offset); try { try { block.getX86Length(); } catch (NullPointerException e) { block = codeBlockManager.getRealModeCodeBlockAt(this, offset); } } catch (CodeBlockReplacementException e) { block = (RealModeCodeBlock)e.getReplacement(); setRealCodeBlockAt(offset, block); } return block; } private int executeVirtual8086(Processor cpu, int offset) { int x86Count = 0; int ip = cpu.getInstructionPointer(); int startingBlock = ip & AddressSpace.INDEX_MASK; do { try { offset = ip & AddressSpace.BLOCK_MASK; Virtual8086ModeCodeBlock block = getVirtual8086ModeCodeBlockAt(offset); try { try { x86Count += block.execute(cpu); } catch (NullPointerException e) { block = codeBlockManager.getVirtual8086ModeCodeBlockAt(this, offset); x86Count += block.execute(cpu); } } catch (CodeBlockReplacementException e) { block = (Virtual8086ModeCodeBlock)e.getReplacement(); setVirtual8086CodeBlockAt(offset, block); x86Count += block.execute(cpu); } cpu.processVirtual8086ModeInterrupts(); } catch (ProcessorException p) { cpu.handleVirtual8086ModeException(p.getVector(), p.hasErrorCode(), p.getErrorCode()); } } while (((ip = cpu.getInstructionPointer()) & AddressSpace.INDEX_MASK) == startingBlock); return x86Count; } private CodeBlock decodeVirtual8086(Processor cpu, int offset) { Virtual8086ModeCodeBlock block = getVirtual8086ModeCodeBlockAt(offset); try { try { block.getX86Length(); } catch (NullPointerException e) { block = codeBlockManager.getVirtual8086ModeCodeBlockAt(this, offset); block.getX86Length(); } } catch (CodeBlockReplacementException e) { block = (Virtual8086ModeCodeBlock)e.getReplacement(); setVirtual8086CodeBlockAt(offset, block); } return block; } private RealModeCodeBlock getRealModeCodeBlockAt(int offset) { return realCodeBuffer[offset]; } private ProtectedModeCodeBlock getProtectedModeCodeBlockAt(int offset) { return protectedCodeBuffer[offset]; } private Virtual8086ModeCodeBlock getVirtual8086ModeCodeBlockAt(int offset) { return virtual8086CodeBuffer[offset];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -