/*
JPC: An x86 PC Hardware Emulator for a pure Java Virtual Machine
Copyright (C) 2012-2013 Ian Preston
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/
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;
import org.jpc.emulator.processor.fpu64.FpuState64;
public class FPUFrame extends UtilityFrame implements PCListener
{
private FpuState64 fpu;
private FPUAccess access;
private FPUModel model;
private boolean editableModel;
private JTable registerTable;
private Font f = new Font("Monospaced", Font.BOLD, 12);
public FPUFrame()
{
super("FPU State");
editableModel = false;
fpu = null;
model = new FPUModel();
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(3).setCellEditor(new DefaultCellEditor(hex));
add("Center", new JScrollPane(registerTable));
setPreferredSize(new Dimension(260, 220));
JPC.getInstance().objects().addObject(this);
pcCreated();
}
public void frameClosed()
{
JPC.getInstance().objects().removeObject(this);
}
public void pcCreated()
{
fpu = (FpuState64)((Processor) JPC.getObject(Processor.class)).fpu;
access = (FPUAccess) JPC.getObject(FPUAccess.class);
if (fpu != null)
editableModel = true;
model.recreateWrappers();
refreshDetails();
}
public void pcDisposed()
{
fpu = null;
access = null;
editableModel = false;
model.recreateWrappers();
refreshDetails();
}
public void executionStarted()
{
editableModel = false;
}
public void executionStopped()
{
editableModel = true;
refreshDetails();
}
public void refreshDetails()
{
model.fireTableDataChanged();
}
class FieldWrapper
{
String title, fieldName;
FieldWrapper(String title, String fieldName)
{
this.title = title;
this.fieldName = fieldName;
}
long getLongValue()
{
if (access == null)
return -1;
return access.getLongValue(fieldName, -1);
}
void setLongValue(long val)
{
if (access != null)
access.setLongValue(fieldName, val);
}
}
class FPUModel extends BasicTableModel
{
FieldWrapper[] registers;
FPUModel()
{
super(new String[]{"Register", "High", "Low", "double"}, new int[]{50, 40, 40, 40});
recreateWrappers();
}
public void recreateWrappers()
{
registers = new FieldWrapper[9];
registers[0] = new FieldWrapper("ST0", "ST0");
registers[1] = new FieldWrapper("ST1", "ST1");
registers[2] = new FieldWrapper("ST2", "ST2");
registers[3] = new FieldWrapper("ST3", "ST3");
registers[4] = new FieldWrapper("ST4", "ST4");
registers[5] = new FieldWrapper("ST5", "ST5");
registers[6] = new FieldWrapper("ST6", "ST6");
registers[7] = new FieldWrapper("ST7", "ST7");
registers[8] = new FieldWrapper("status", "statusWord");
}
public int getRowCount()
{
return registers.length;
}
public boolean isCellEditable(int rowIndex, int columnIndex)
{
return columnIndex > 0;
}
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)
{
long value = registers[row].getLongValue();
switch (column)
{
case 0:
return registers[row].title;
case 1:
return getZeroExtendedHexString((int) (value >> 32));
case 2:
return getZeroExtendedHexString((int) value);
case 3:
if (row < 8)
return ""+Double.longBitsToDouble(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].setLongValue(value);
}
else if (column > 0)
{
int value = Integer.parseInt(obj.toString(), 2);
long current = registers[row].getLongValue();
int shift = 32*(4 - column);
long mask = 0xFFFFFFFFL << shift;
current &= (0xFFFFFFFF ^ mask);
current |= value << shift;
if ((row >= 8) && (row < 14))
current = 0xFFFF & current;
registers[row].setLongValue(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;
}
}
}