📄 jpc.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.debugger;import java.util.*;import java.util.zip.*;import java.io.*;import java.text.*;import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;import javax.swing.text.*;import javax.swing.undo.*;import org.jpc.debugger.util.*;import org.jpc.emulator.*;import org.jpc.support.*;import org.jpc.emulator.motherboard.*;import org.jpc.emulator.memory.*;import org.jpc.emulator.processor.*;import org.jpc.emulator.peripheral.*;import org.jpc.emulator.pci.peripheral.*;import org.jpc.j2se.*;public class JPC extends ApplicationFrame implements ActionListener{ private static JPC instance = null; private ObjectDatabase objects; private RunMenu runMenu; private CodeBlockRecord codeBlocks; private JDesktopPane desktop; private DiskSelector floppyDisk, hardDisk; private JMenuItem createPC, scanForImages, loadSnapshot, saveSnapshot, quit, createBlankDisk; private JMenuItem processorFrame, physicalMemoryViewer, linearMemoryViewer, breakpoints, opcodeFrame, traceFrame, monitor, frequencies, codeBlockTreeFrame; private MemoryViewer physicalViewer, linearViewer; private JPC(boolean fullScreen) { super("JPC Debugger"); if (fullScreen) setBoundsToMaximum(); else setBounds(0, 0, 1024, 900); objects = new ObjectDatabase(); desktop = new JDesktopPane(); add("Center", desktop); physicalViewer = null; linearViewer = null; JFileChooser chooser = new JFileChooser(System.getProperty("user.dir")); chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); objects.addObject(chooser); JMenuBar bar = new JMenuBar(); JMenu actions = new JMenu("Actions"); createPC = actions.add("Create New PC"); createPC.setEnabled(false); createPC.addActionListener(this); scanForImages = actions.add("Scan Directory for Images"); scanForImages.addActionListener(this); actions.addSeparator(); loadSnapshot = actions.add("Load Snapshot"); loadSnapshot.addActionListener(this); saveSnapshot = actions.add("Save Snapshot"); saveSnapshot.addActionListener(this); actions.addSeparator(); quit = actions.add("Quit"); quit.addActionListener(this); JMenu windows = new JMenu("Windows"); monitor = windows.add("PC Monitor"); monitor.addActionListener(this); processorFrame = windows.add("Processor Frame"); processorFrame.addActionListener(this); physicalMemoryViewer = windows.add("Physical Memory Viewer"); physicalMemoryViewer.addActionListener(this); linearMemoryViewer = windows.add("Linear Memory Viewer"); linearMemoryViewer.addActionListener(this); breakpoints = windows.add("Breakpoints"); breakpoints.addActionListener(this); opcodeFrame = windows.add("Opcode Frame"); opcodeFrame.addActionListener(this); traceFrame = windows.add("Execution Trace Frame"); traceFrame.addActionListener(this);// frequencies = windows.add("Opcode Frequency Frame");// frequencies.addActionListener(this); codeBlockTreeFrame = windows.add("Code Block Tree Frame"); codeBlockTreeFrame.addActionListener(this); JMenu tools = new JMenu("Tools"); createBlankDisk = tools.add("Create Blank Disk (file)"); createBlankDisk.addActionListener(this); runMenu = new RunMenu(); floppyDisk = new DiskSelector("FDD", Color.red); hardDisk = new DiskSelector("HDD", Color.blue); bar.add(actions); bar.add(windows); bar.add(runMenu); bar.add(tools); bar.add(floppyDisk); bar.add(hardDisk); bar.add(Box.createHorizontalGlue()); bar.add(new Hz()); codeBlocks = null; setJMenuBar(bar); resyncImageSelection(new File(System.getProperty("user.dir"))); } private void resyncImageSelection(File dir) { floppyDisk.rescan(dir); hardDisk.rescan(dir); checkBootEnabled(); } private void checkBootEnabled() { createPC.setEnabled(floppyDisk.isBootDevice() || hardDisk.isBootDevice()); } class DiskSelector extends JMenu implements ActionListener { String mainTitle; ButtonGroup group; Vector<File> diskImages; Hashtable<ButtonModel, File> lookup; JCheckBoxMenuItem bootFrom; JMenuItem openFile; public DiskSelector(String mainTitle, Color fg) { super(mainTitle); this.mainTitle = mainTitle; setForeground(fg); lookup = new Hashtable<ButtonModel, File>(); diskImages = new Vector<File>(); group = new ButtonGroup(); bootFrom = new JCheckBoxMenuItem("Set as Boot Device"); bootFrom.addActionListener(this); openFile = new JMenuItem("Select Image File"); openFile.addActionListener(this); } public void actionPerformed(ActionEvent evt) { if (evt.getSource() == openFile) { JFileChooser chooser = (JFileChooser) objects.getObject(JFileChooser.class); if (chooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) return; rescan(chooser.getSelectedFile()); } resetTitle(); } public void setSelectedFile(File f, boolean isBootDevice) { rescan(f); bootFrom.setState(isBootDevice); resetTitle(); } private void resetTitle() { String fileName = ""; File f = getSelectedFile(); if (f != null) fileName = f.getAbsolutePath(); if (isBootDevice()) setText(mainTitle+" >"+fileName+"<"); else setText(mainTitle+" "+fileName); checkBootEnabled(); if (bootFrom.getState() && (getSelectedFile() == null)) bootFrom.setState(false); } public File getSelectedFile() { ButtonModel selectedModel = group.getSelection(); if (selectedModel == null) return null; return lookup.get(selectedModel); } public boolean isBootDevice() { return bootFrom.getState() && (getSelectedFile() != null); } void rescan(File f) { File selected = getSelectedFile(); boolean isBoot = isBootDevice(); for (int i=diskImages.size()-1; i>=0; i--) if (!diskImages.elementAt(i).exists()) diskImages.removeElementAt(i); if (f.isDirectory()) { File[] files = f.listFiles(); for (int i=0; i<files.length; i++) if (files[i].getName().toLowerCase().endsWith(".img")) { if (!diskImages.contains(files[i])) diskImages.add(files[i]); } } else if (f.exists()) { boolean found = false; for (int i=0; i<diskImages.size(); i++) if (diskImages.elementAt(i).getAbsolutePath().equals(f.getAbsolutePath())) { selected = diskImages.elementAt(i); found = true; } if (!found) { diskImages.add(f); selected = f; } } removeAll(); lookup.clear(); group = new ButtonGroup(); bootFrom.setState(isBoot); add(bootFrom); addSeparator(); for (int i=0; i<diskImages.size(); i++) { File ff = diskImages.elementAt(i); JRadioButtonMenuItem item = new JRadioButtonMenuItem(ff.getAbsolutePath()); item.addActionListener(this); lookup.put(item.getModel(), ff); group.add(item); add(item); if (ff.equals(selected)) group.setSelected(item.getModel(), true); } addSeparator(); add(openFile); } } // Hook for F2 - print status report public void statusReport() { System.out.println("No status to report"); } public Object get(Class cls) { return objects.getObject(cls); } public ObjectDatabase objects() { return objects; } public JDesktopPane getDesktop() { return desktop; } protected void frameCloseRequested() { BreakpointsFrame bp = (BreakpointsFrame) objects.getObject(BreakpointsFrame.class); if ((bp != null) && bp.isEdited()) bp.dispose(); System.exit(0); } public void bringToFront(JInternalFrame f) { desktop.moveToFront(f); desktop.setSelectedFrame(f); } public void actionPerformed(ActionEvent evt) { Object src = evt.getSource(); if (src == quit) frameCloseRequested(); else if (src == scanForImages) { JFileChooser chooser = (JFileChooser) objects.getObject(JFileChooser.class); if (chooser.showOpenDialog(this) != JFileChooser.APPROVE_OPTION) return; File dir = chooser.getSelectedFile(); if (!dir.isDirectory()) dir = dir.getParentFile(); resyncImageSelection(dir); } else if (src == createPC) { try { File floppyImage = floppyDisk.getSelectedFile(); File hardImage = hardDisk.getSelectedFile(); int bootType = DriveSet.HARD_DRIVE_BOOT; if (floppyDisk.isBootDevice()) { if (!floppyImage.exists()) { alert("Floppy Image: "+floppyImage+" does not exist", "Boot", JOptionPane.ERROR_MESSAGE); return; } bootType = DriveSet.FLOPPY_BOOT; } else { if (!hardImage.exists()) { alert("Hard disk Image: "+hardImage+" does not exist", "Boot", JOptionPane.ERROR_MESSAGE); return; } } String[] args; int argc = 0; if (floppyImage != null) argc += 2; if (hardImage != null) argc += 2; if (argc > 2) argc += 2; args = new String[argc]; int pos = 0; if (floppyImage != null) { args[pos++] = "-fda"; args[pos++] = floppyImage.getAbsolutePath(); } if (hardImage != null) { args[pos++] = "-hda"; args[pos++] = hardImage.getAbsolutePath(); } if (pos <= (argc - 2)) { args[pos++] = "-boot"; if (bootType == DriveSet.HARD_DRIVE_BOOT) args[pos++] = "hda"; else args[pos++] = "fda"; } instance.createPC(args); resyncImageSelection(new File(System.getProperty("user.dir"))); } catch (Exception e) { alert("Failed to create PC: "+e, "Boot", JOptionPane.ERROR_MESSAGE); } } else if (src == loadSnapshot) { runMenu.stop(); JFileChooser fc = new JFileChooser(); try { BufferedReader in = new BufferedReader(new FileReader("prefs.txt")); String path = in.readLine(); in.close(); if (path != null) { File f = new File(path); if (f.isDirectory()) fc.setCurrentDirectory(f); } } catch (Exception e) {} int returnVal = fc.showDialog(this, "Load JPC Snapshot"); File file = fc.getSelectedFile(); try { if (file != null) { BufferedWriter out = new BufferedWriter(new FileWriter("prefs.txt")); out.write(file.getPath()); out.close(); } } catch (Exception e) {e.printStackTrace();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -