258 lines
8.8 KiB
Java
258 lines
8.8 KiB
Java
package app;
|
|
|
|
// Java imports
|
|
import java.awt.*;
|
|
import java.awt.event.*;
|
|
import java.util.*;
|
|
import javax.swing.*;
|
|
|
|
// Project imports
|
|
import util.*;
|
|
import vue.*;
|
|
|
|
// CPU window
|
|
class CPU extends ChildWindow {
|
|
|
|
// Instance fields
|
|
private int expandWidth; // Width of expand buttons
|
|
private Font font; // Display font
|
|
private int fontHeight; // Font line height
|
|
private int fontWidth; // Font maximum character width
|
|
private boolean shown; // Window has been shown
|
|
private int systemHeight; // Initial height of system register list
|
|
|
|
// UI components
|
|
private JPanel dasm; // Disassembler
|
|
private JPanel system; // System registers
|
|
private JPanel program; // Program registers
|
|
private ArrayList<Register> registers; // Register controls
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// Constructors //
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Default constructor
|
|
CPU(MainWindow parent) {
|
|
super(parent, "cpu.title");
|
|
var client = getContentPane();
|
|
|
|
// Configure instance fields
|
|
font = new Font(Util.fontFamily(new String[]
|
|
{ "Consolas", Font.MONOSPACED } ), Font.PLAIN, 14);
|
|
registers = new ArrayList<Register>();
|
|
|
|
dasm = new JPanel(null);
|
|
dasm.setBackground(SystemColor.window);
|
|
dasm.setFocusable(true);
|
|
|
|
var inner = initRegisters();
|
|
var outer = Util.splitPane(JSplitPane.HORIZONTAL_SPLIT);
|
|
outer.setLeftComponent(new JScrollPane(dasm,
|
|
JScrollPane.VERTICAL_SCROLLBAR_NEVER,
|
|
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));
|
|
outer.setRightComponent(inner);
|
|
outer.setResizeWeight(1);
|
|
|
|
client.add(outer);
|
|
client.setPreferredSize(new Dimension(480, 300));
|
|
setFont2(font);
|
|
pack();
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// Register Constructors //
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Initialize program register list
|
|
private void initProgram() {
|
|
Dimension target = null;
|
|
|
|
// Program register container
|
|
var lst = program = new JPanel(new GridBagLayout()) {
|
|
public Dimension getPreferredSize() {
|
|
var ret = super.getPreferredSize();
|
|
if (!shown)
|
|
ret.height = 0;
|
|
return ret;
|
|
}
|
|
public void paintComponent(Graphics g) {
|
|
super.paintComponent(g);
|
|
if (shown)
|
|
return;
|
|
shown = true;
|
|
system.revalidate();
|
|
program.revalidate();
|
|
}
|
|
};
|
|
lst.setBackground(SystemColor.window);
|
|
lst.setFocusable(true);
|
|
lst.addMouseListener(Util.onMouse(e->lst.requestFocus(),null));
|
|
|
|
// Produce the list of program registers
|
|
for (int x = 0; x < 32; x++) {
|
|
String name = "r" + x;
|
|
switch (x) {
|
|
case VUE.GP: name = "gp"; break;
|
|
case VUE.HP: name = "hp"; break;
|
|
case VUE.LP: name = "lp"; break;
|
|
case VUE.SP: name = "sp"; break;
|
|
case VUE.TP: name = "tp"; break;
|
|
}
|
|
registers.add(new Register(
|
|
parent, lst, name, x, Register.PROGRAM));
|
|
}
|
|
endList(lst);
|
|
}
|
|
|
|
// Initialize register lists
|
|
private JSplitPane initRegisters() {
|
|
initSystem();
|
|
initProgram();
|
|
|
|
var ret = Util.splitPane(JSplitPane.VERTICAL_SPLIT);
|
|
ret.setTopComponent(new JScrollPane(system,
|
|
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
|
|
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED
|
|
));
|
|
ret.setBottomComponent(new JScrollPane(program,
|
|
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
|
|
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED
|
|
));
|
|
return ret;
|
|
}
|
|
|
|
// Initialize system register list
|
|
private void initSystem() {
|
|
|
|
// System register container
|
|
var lst = system = new JPanel(new GridBagLayout()) {
|
|
public Dimension getPreferredSize() {
|
|
var ret = super.getPreferredSize();
|
|
if (!shown)
|
|
ret.height = systemHeight;
|
|
return ret;
|
|
}
|
|
};
|
|
system.setBackground(SystemColor.window);
|
|
system.setFocusable(true);
|
|
system.addMouseListener(Util.onMouse(e->system.requestFocus(), null));
|
|
system.putClientProperty("shown", true);
|
|
|
|
// Add the first two system registers and expand PSW
|
|
int plain = Register.PLAIN;
|
|
registers.add(new Register(parent, lst, "PC" , VUE.PC , plain ));
|
|
Register psw =new Register(parent, lst, "PSW" , VUE.PSW , VUE.PSW );
|
|
psw.setExpanded(true);
|
|
registers.add(psw);
|
|
shown = true;
|
|
systemHeight = system.getPreferredSize().height + 6;
|
|
shown = false;
|
|
|
|
// Add the remaining system registers
|
|
registers.add(new Register(parent, lst, "EIPC" , VUE.EIPC , plain ));
|
|
registers.add(new Register(parent, lst, "EIPSW", VUE.EIPSW, VUE.PSW ));
|
|
registers.add(new Register(parent, lst, "FEPC" , VUE.FEPC , plain ));
|
|
registers.add(new Register(parent, lst, "FEPSW", VUE.FEPSW, VUE.PSW ));
|
|
registers.add(new Register(parent, lst, "ECR" , VUE.ECR , VUE.ECR ));
|
|
registers.add(new Register(parent, lst, "ADTRE", VUE.ADTRE, plain ));
|
|
registers.add(new Register(parent, lst, "CHCW" , VUE.CHCW , VUE.CHCW));
|
|
registers.add(new Register(parent, lst, "PIR" , VUE.PIR , VUE.PIR ));
|
|
registers.add(new Register(parent, lst, "TKCW" , VUE.TKCW , VUE.TKCW));
|
|
registers.add(new Register(parent, lst, "29" , 29, plain ));
|
|
registers.add(new Register(parent, lst, "30" , 30, plain ));
|
|
registers.add(new Register(parent, lst, "31" , 31, plain ));
|
|
endList(lst);
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// Event Handlers //
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Client resize
|
|
private void onResize() {
|
|
//refreshDasm();
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// Package Methods //
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Update the display
|
|
void refresh() {
|
|
|
|
// The element is not ready
|
|
if (registers == null)
|
|
return;
|
|
|
|
// Refresh registers
|
|
for (var reg : registers)
|
|
reg.refresh();
|
|
}
|
|
|
|
// Specify a new font
|
|
void setFont2(Font font) {
|
|
this.font = font;
|
|
|
|
// Configure the maximum font dimensions
|
|
var fontMax = new JLabel("!");
|
|
fontMax.setFont(font);
|
|
fontHeight = Math.max(1, fontMax.getPreferredSize().height);
|
|
fontWidth = -1;
|
|
for (int x = 0; x < 16; x++) {
|
|
fontMax.setText(Integer.toString(x, 16).toUpperCase());
|
|
fontWidth = Math.max(fontWidth, fontMax.getPreferredSize().width);
|
|
}
|
|
|
|
// Configure register list scrolling
|
|
for (int x = 0; x < 2; x++) {
|
|
Component ctrl = x == 0 ? system : program;
|
|
while (!(ctrl instanceof JScrollPane))
|
|
ctrl = ctrl.getParent();
|
|
((JScrollPane) ctrl).getVerticalScrollBar()
|
|
.setUnitIncrement(fontHeight);
|
|
}
|
|
|
|
// Determine the width of the register expand buttons
|
|
var expand = new JLabel("+");
|
|
int width = expand.getPreferredSize().width;
|
|
expand.setText("-");
|
|
width = Math.max(width, expand.getPreferredSize().width) + 4;
|
|
|
|
// Configure registers
|
|
for (var reg : registers) {
|
|
reg.setExpandWidth(width);
|
|
reg.setFont(font, fontWidth, fontHeight);
|
|
}
|
|
|
|
onResize();
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// Private Methods //
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Terminate a register list
|
|
private JPanel endList(JPanel list) {
|
|
var spacer = new JPanel(null);
|
|
spacer.setOpaque(false);
|
|
spacer.setPreferredSize(new Dimension(1, 1));
|
|
var gbc = new GridBagConstraints();
|
|
gbc.gridheight = GridBagConstraints.REMAINDER;
|
|
gbc.gridwidth = GridBagConstraints.REMAINDER;
|
|
gbc.weighty = 1;
|
|
list.add(spacer, gbc);
|
|
return spacer;
|
|
}
|
|
|
|
}
|