/*
JPC: An x86 PC Hardware Emulator for a pure Java Virtual Machine
Release Version 2.4
A project from the Physics Dept, The University of Oxford
Copyright (C) 2007-2010 The University of Oxford
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:
jpc.sourceforge.net
or the developer website
sourceforge.net/projects/jpc/
Conceived and Developed by:
Rhys Newman, Ian Preston, Chris Dennis
End of licence header
*/
package org.jpc.debugger;
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import org.jpc.debugger.util.*;
import org.jpc.emulator.processor.Processor;
public class ProcessorFrame extends UtilityFrame implements PCListener
{
private ProcessorAccess access;
private ProcessorModel model;
private JTable registerTable;
private Font f = new Font("Monospaced", Font.BOLD, 12);
public ProcessorFrame()
{
super("Processor Registers");
model = new ProcessorModel();
registerTable = new JTable(model);
registerTable.setRowHeight(18);
model.setupColumnWidths(registerTable);
registerTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
registerTable.setDefaultRenderer(Object.class, new CellRenderer());
ValidatingTextField binary = new ValidatingTextField("01", '0', 8);
ValidatingTextField hex = new ValidatingTextField("0123456789abcdefABCDEF", '0', 8);
binary.setFont(f);
binary.setHorizontalAlignment(JLabel.RIGHT);
hex.setFont(f);
hex.setHorizontalAlignment(JLabel.RIGHT);
registerTable.setDefaultEditor(Object.class, new DefaultCellEditor(binary));
registerTable.getColumnModel().getColumn(5).setCellEditor(new DefaultCellEditor(hex));
add("Center", new JScrollPane(registerTable));
setPreferredSize(new Dimension(430, 500));
JPC.getInstance().objects().addObject(this);
pcCreated();
}
public void refreshAccess()
{
access = (ProcessorAccess) JPC.getObject(ProcessorAccess.class);
}
public void frameClosed()
{
JPC.getInstance().objects().removeObject(this);
}
public void pcCreated()
{
access = (ProcessorAccess) JPC.getObject(ProcessorAccess.class);
model.recreateWrappers();
refreshDetails();
}
public void pcDisposed()
{
access = null;
model.recreateWrappers();
refreshDetails();
}
public void executionStarted()
{
}
public void executionStopped()
{
refreshDetails();
}
public void refreshDetails()
{
model.fireTableDataChanged();
}
class FieldWrapper
{
String title, fieldName;
FieldWrapper(String title, String fieldName)
{
this.title = title;
this.fieldName = fieldName;
}
int getValue()
{
if (access == null)
return -1;
return access.getValue(fieldName, -1);
}
void setValue(int val)
{
if (access != null)
access.setValue(fieldName, val);
}
}
class ProcessorModel extends BasicTableModel
{
FieldWrapper[] registers;
ProcessorModel()
{
super(new String[]{"Register", "B0", "B1", "B2", "B3", "Hex"}, new int[]{50, 80, 80, 80, 80, 80});
recreateWrappers();
}
public void recreateWrappers()
{
registers = new FieldWrapper[24];
registers[0] = new FieldWrapper("EAX", "r_eax");
registers[1] = new FieldWrapper("ECX", "r_ecx");
registers[2] = new FieldWrapper("EDX", "r_edx");
registers[3] = new FieldWrapper("EBX", "r_ebx");
registers[4] = new FieldWrapper("ESP", "r_esp");
registers[5] = new FieldWrapper("EBP", "r_ebp");
registers[6] = new FieldWrapper("ESI", "r_esi");
registers[7] = new FieldWrapper("EDI", "r_edi");
registers[8] = new FieldWrapper("CS", "cs");
registers[9] = new FieldWrapper("DS", "ds");
registers[10] = new FieldWrapper("SS", "ss");
registers[11] = new FieldWrapper("ES", "es");
registers[12] = new FieldWrapper("FS", "fs");
registers[13] = new FieldWrapper("GS", "gs");
registers[14] = new FieldWrapper("EIP", "eip");
registers[15] = new FieldWrapper("Flags", "eflags");
registers[16] = new FieldWrapper("CR0", "cr0");
registers[17] = new FieldWrapper("CR1", "cr1");
registers[18] = new FieldWrapper("CR2", "cr2");
registers[19] = new FieldWrapper("CR3", "cr3");
registers[20] = new FieldWrapper("CR4", "cr4");
registers[21] = new FieldWrapper("GDTR", "gdtr");
registers[22] = new FieldWrapper("LDTR", "ldtr");
registers[23] = new FieldWrapper("IDTR", "idtr");
}
public int getRowCount()
{
return registers.length;
}
public boolean isCellEditable(int rowIndex, int columnIndex)
{
if (rowIndex >= 8)
return columnIndex > 2;
else
return columnIndex > 0;
}
private String getZeroExtendedBinaryString(int value)
{
StringBuffer buf = new StringBuffer(Integer.toBinaryString(value));
while (buf.length() < 8)
buf.insert(0, "0");
return buf.toString();
}
private String getZeroExtendedHexString(int value)
{
StringBuffer buf = new StringBuffer(Integer.toHexString(value).toUpperCase());
while (buf.length() < 8)
buf.insert(0, "0");
return buf.toString();
}
public Object getValueAt(int row, int column)
{
int value = registers[row].getValue();
switch (column)
{
case 0:
return registers[row].title;
case 1:
return getZeroExtendedBinaryString((0xFF & (value >> 24)));
case 2:
return getZeroExtendedBinaryString((0xFF & (value >> 16)));
case 3:
return getZeroExtendedBinaryString((0xFF & (value >> 8)));
case 4:
return getZeroExtendedBinaryString((0xFF & (value)));
case 5:
return getZeroExtendedHexString(value);
default:
return "";
}
}
public void setValueAt(Object obj, int row, int column)
{
try
{
if (column == 5)
{
long value = Long.parseLong(obj.toString(), 16);
registers[row].setValue((int) value);
}
else if (column > 0)
{
int value = Integer.parseInt(obj.toString(), 2);
long current = registers[row].getValue();
int shift = 8*(4 - column);
long mask = 0xFF << shift;
current &= (0xFFFFFFFF ^ mask);
current |= value << shift;
if ((row >= 8) && (row < 14))
current = 0xFFFF & current;
registers[row].setValue((int) current);
}
}
catch (Exception e) {}
JPC.getInstance().refresh();
}
}
class CellRenderer extends DefaultTableCellRenderer
{
Color bg = new Color(0xFFF0F0);
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
setFont(f);
setBackground(Color.white);
setForeground(Color.black);
setHorizontalAlignment(JLabel.RIGHT);
if (column == 0)
{
setBackground(Color.blue);
setForeground(Color.white);
setHorizontalAlignment(JLabel.CENTER);
}
else
{
if (row < 8)
setBackground(bg);
if (column < 5)
setForeground(Color.blue);
else
setForeground(Color.magenta);
}
if ((row >= 8) && (row < 14) && ((column == 1) || (column == 2)))
{
setBackground(Color.lightGray);
setForeground(Color.blue);
}
else if (row == 14)
{
if (column > 0)
{
setBackground(Color.red);
setForeground(Color.white);
}
}
else if (row == 15)
setBackground(Color.cyan);
else if ((row > 15) && (row < 21))
{
setBackground(Color.green);
setForeground(Color.black);
}
else if (row >= 21)
{
setBackground(Color.white);
setForeground(Color.blue);
}
return this;
}
}
}