Implementing disassembler back-end, yet more adjustments to CPU window
This commit is contained in:
		
							parent
							
								
									b7c2545ea7
								
							
						
					
					
						commit
						76c95b0523
					
				| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
Copyright (C) 2019 Planet Virtual Boy
 | 
					Copyright (C) 2020 Planet Virtual Boy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This software is provided 'as-is', without any express or implied
 | 
					This software is provided 'as-is', without any express or implied
 | 
				
			||||||
warranty.  In no event will the authors be held liable for any damages
 | 
					warranty.  In no event will the authors be held liable for any damages
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -79,7 +79,6 @@ static void cpuDecode(VUE_INST *inst, int32_t bits) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Decode by format */
 | 
					    /* Decode by format */
 | 
				
			||||||
    switch (inst->format) {
 | 
					    switch (inst->format) {
 | 
				
			||||||
        case 0: return; /* Illegal opcode */
 | 
					 | 
				
			||||||
        case 1:
 | 
					        case 1:
 | 
				
			||||||
            inst->reg2 = bits >> 21 & 31;
 | 
					            inst->reg2 = bits >> 21 & 31;
 | 
				
			||||||
            inst->reg1 = bits >> 16 & 31;
 | 
					            inst->reg1 = bits >> 16 & 31;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -159,6 +159,7 @@ typedef struct {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Emulation state */
 | 
					/* Emulation state */
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    VUE_INST inst; /* Instruction state */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Memory bus */
 | 
					    /* Memory bus */
 | 
				
			||||||
    struct {
 | 
					    struct {
 | 
				
			||||||
| 
						 | 
					@ -221,8 +222,6 @@ typedef struct {
 | 
				
			||||||
        uint16_t ecr_fecc; /* Fatal Error Cause Code */
 | 
					        uint16_t ecr_fecc; /* Fatal Error Cause Code */
 | 
				
			||||||
    } cpu;
 | 
					    } cpu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Additional fields */
 | 
					 | 
				
			||||||
    VUE_INST inst; /* Instruction state */
 | 
					 | 
				
			||||||
} VUE;
 | 
					} VUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,257 +0,0 @@
 | 
				
			||||||
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;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,179 @@
 | 
				
			||||||
 | 
					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 CPUWindow extends ChildWindow {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Instance fields
 | 
				
			||||||
 | 
					    private int     expandWidth;  // Width of expand buttons
 | 
				
			||||||
 | 
					    private boolean shown;        // Window has been shown
 | 
				
			||||||
 | 
					    private int     systemHeight; // Initial height of system register list
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // UI components
 | 
				
			||||||
 | 
					    private JPanel       dasm;       // Disassembler
 | 
				
			||||||
 | 
					    private RegisterList lstProgram; // Program register list
 | 
				
			||||||
 | 
					    private RegisterList lstSystem;  // System register list
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    //                            Global Settings                            //
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static int       regExpandWidth; // Width of register list expand button
 | 
				
			||||||
 | 
					    static Font      regHexFont;     // Register list hex font
 | 
				
			||||||
 | 
					    static Dimension regHexFontSize; // Max dimensions
 | 
				
			||||||
 | 
					    static HashSet<CPUWindow> instances; // Spawned instances
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Static initializer
 | 
				
			||||||
 | 
					    static {
 | 
				
			||||||
 | 
					        setDefaults();
 | 
				
			||||||
 | 
					        instances = new HashSet<CPUWindow>();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    //                            Static Methods                             //
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Apply configuration settings to all instances
 | 
				
			||||||
 | 
					    static void configureAll() {
 | 
				
			||||||
 | 
					        for (var inst : instances)
 | 
				
			||||||
 | 
					            inst.configure();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Reset all settings to their default values
 | 
				
			||||||
 | 
					    static void setDefaults() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Register list hex font
 | 
				
			||||||
 | 
					        setRegHexFont(new Font(Util.fontFamily(new String[]
 | 
				
			||||||
 | 
					            { "Consolas", Font.MONOSPACED } ), Font.PLAIN, 14));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Width of register list expand button
 | 
				
			||||||
 | 
					        var label = new JLabel("+");
 | 
				
			||||||
 | 
					        regExpandWidth = label.getPreferredSize().width;
 | 
				
			||||||
 | 
					        label.setText("-");
 | 
				
			||||||
 | 
					        regExpandWidth = Math.max(regExpandWidth,
 | 
				
			||||||
 | 
					            label.getPreferredSize().width);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Specify a font to use as the register list hex font
 | 
				
			||||||
 | 
					    static void setRegHexFont(Font font) {
 | 
				
			||||||
 | 
					        regHexFont     = font;
 | 
				
			||||||
 | 
					        regHexFontSize = measureHex(font);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    //                             Constructors                              //
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Default constructor
 | 
				
			||||||
 | 
					    CPUWindow(MainWindow parent) {
 | 
				
			||||||
 | 
					        super(parent, "cpu.title");
 | 
				
			||||||
 | 
					        instances.add(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var client = getContentPane();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dasm = new JPanel(null);
 | 
				
			||||||
 | 
					        dasm.setBackground(SystemColor.window);
 | 
				
			||||||
 | 
					        dasm.setFocusable(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        lstSystem = new RegisterList(this, true);
 | 
				
			||||||
 | 
					        lstProgram = new RegisterList(this, false);
 | 
				
			||||||
 | 
					        var inner = Util.splitPane(JSplitPane.VERTICAL_SPLIT);
 | 
				
			||||||
 | 
					        inner.setTopComponent(lstSystem);
 | 
				
			||||||
 | 
					        inner.setBottomComponent(lstProgram);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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));
 | 
				
			||||||
 | 
					        configure();
 | 
				
			||||||
 | 
					        pack();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    //                            Public Methods                             //
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // The window is closing
 | 
				
			||||||
 | 
					    public void dispose() {
 | 
				
			||||||
 | 
					        instances.remove(this);
 | 
				
			||||||
 | 
					        super.dispose();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    //                            Package Methods                            //
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Apply configuration settings
 | 
				
			||||||
 | 
					    void configure() {
 | 
				
			||||||
 | 
					        lstProgram.configure();
 | 
				
			||||||
 | 
					        lstSystem .configure();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Update the display
 | 
				
			||||||
 | 
					    void refresh() {
 | 
				
			||||||
 | 
					        lstSystem.refresh();
 | 
				
			||||||
 | 
					        lstProgram.refresh();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    //                            Event Handlers                             //
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Client resize
 | 
				
			||||||
 | 
					    private void onResize() {
 | 
				
			||||||
 | 
					        //refreshDasm();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    //                            Private Methods                            //
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Determine the maximum character width of a hex character in a font
 | 
				
			||||||
 | 
					    private static Dimension measureHex(Font font) {
 | 
				
			||||||
 | 
					        int       ret  = 0;
 | 
				
			||||||
 | 
					        Dimension size = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Process all digits
 | 
				
			||||||
 | 
					        var label = new JLabel();
 | 
				
			||||||
 | 
					        label.setFont(font);
 | 
				
			||||||
 | 
					        for (int x = 0; x < 16; x++) {
 | 
				
			||||||
 | 
					            label.setText(String.format(
 | 
				
			||||||
 | 
					                "%" + (Disassembler.hexCaps ? "X" : "x"
 | 
				
			||||||
 | 
					            ), x));
 | 
				
			||||||
 | 
					            size = label.getPreferredSize();
 | 
				
			||||||
 | 
					            ret  = Math.max(ret, size.width);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return new Dimension(ret, size.height);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,7 @@ import java.awt.*;
 | 
				
			||||||
import javax.swing.*;
 | 
					import javax.swing.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Console window
 | 
					// Console window
 | 
				
			||||||
class Console extends ChildWindow {
 | 
					class ConsoleWindow extends ChildWindow {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Instance fields
 | 
					    // Instance fields
 | 
				
			||||||
    private boolean shown; // Component has been visible
 | 
					    private boolean shown; // Component has been visible
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ class Console extends ChildWindow {
 | 
				
			||||||
    ///////////////////////////////////////////////////////////////////////////
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Default constructor
 | 
					    // Default constructor
 | 
				
			||||||
    Console(MainWindow parent) {
 | 
					    ConsoleWindow(MainWindow parent) {
 | 
				
			||||||
        super(parent, "console.title");
 | 
					        super(parent, "console.title");
 | 
				
			||||||
        getContentPane().setPreferredSize(new Dimension(384, 224));
 | 
					        getContentPane().setPreferredSize(new Dimension(384, 224));
 | 
				
			||||||
        pack();
 | 
					        pack();
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,379 @@
 | 
				
			||||||
 | 
					package app;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Project imports
 | 
				
			||||||
 | 
					import vue.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Instruction disassembler
 | 
				
			||||||
 | 
					class Disassembler {
 | 
				
			||||||
 | 
					    private Disassembler() { } // Cannot be instantiated
 | 
				
			||||||
 | 
					    static { setDefaults(); }  // Initialize to default settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    //                            Global Settings                            //
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static boolean bcondCombine; // Merge Bcond condition into mnemonic
 | 
				
			||||||
 | 
					    static boolean bcondNames;   // Use symbolic condition names for Bcond
 | 
				
			||||||
 | 
					    static boolean condCaps;     // Uppercase condition mnemonics
 | 
				
			||||||
 | 
					    static boolean destLast;     // Destination register last
 | 
				
			||||||
 | 
					    static boolean dispDest;     // Resolve jump destination addresses
 | 
				
			||||||
 | 
					    static boolean dispInside;   // Load/store displacement inside brackets
 | 
				
			||||||
 | 
					    static boolean hexCaps;      // Upercase hexadecimal
 | 
				
			||||||
 | 
					    static int     hexMode;      // Hexadecimal decoration
 | 
				
			||||||
 | 
					    static boolean immNumber;    // Use number sign with immediate values
 | 
				
			||||||
 | 
					    static boolean jmpBrackets;  // Square brackets around JMP
 | 
				
			||||||
 | 
					    static boolean jumpAddress;  // Use jump destination addresses
 | 
				
			||||||
 | 
					    static boolean lower;        // Use L instead of C in conditions
 | 
				
			||||||
 | 
					    static boolean mnemonicCaps; // Uppercase mnemonics
 | 
				
			||||||
 | 
					    static boolean programCaps;  // Uppercase program register names
 | 
				
			||||||
 | 
					    static boolean programNames; // Use symbolic program register names
 | 
				
			||||||
 | 
					    static boolean setfCombine;  // Merge SETF condition into mnemonic
 | 
				
			||||||
 | 
					    static boolean setfNames;    // Use symbolic condition names for SETF
 | 
				
			||||||
 | 
					    static boolean systemCaps;   // Uppercase system register names
 | 
				
			||||||
 | 
					    static boolean systemNames;  // Use symbolic system register names
 | 
				
			||||||
 | 
					    static boolean zero;         // Use Z instead of E in conditions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    //                               Constants                               //
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Hexadecimal decorations
 | 
				
			||||||
 | 
					    static final int DOLLAR = 0;
 | 
				
			||||||
 | 
					    static final int H      = 1;
 | 
				
			||||||
 | 
					    static final int ZEROX  = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Condition mneonics
 | 
				
			||||||
 | 
					    static final String[] CONDITIONS = {
 | 
				
			||||||
 | 
					        "V" , "C" , "E" , "NH", "N", "T", "LT", "LE",
 | 
				
			||||||
 | 
					        "NV", "NC", "NE", "H" , "P", "F", "GE", "GT"
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Mnemonics
 | 
				
			||||||
 | 
					    static final String[] MNEMONICS = {
 | 
				
			||||||
 | 
					        "---"    , "ADD"    , "ADD"    , "ADDF.S", "ADDI"   , "AND"    ,
 | 
				
			||||||
 | 
					        "ANDBSU" , "ANDI"   , "ANDNBSU", "Bcond" , "CAXI"   , "CLI"    ,
 | 
				
			||||||
 | 
					        "CMP"    , "CMP"    , "CMPF.S" , "CVT.SW", "CVT.WS" , "DIV"    ,
 | 
				
			||||||
 | 
					        "DIVF.S" , "DIVU"   , "HALT"   , "IN.B"  , "IN.H"   , "IN.W"   ,
 | 
				
			||||||
 | 
					        "JAL"    , "JMP"    , "JR"     , "LD.B"  , "LD.H"   , "LD.W"   ,
 | 
				
			||||||
 | 
					        "LDSR"   , "MOV"    , "MOV"    , "MOVBSU", "MOVEA"  , "MOVHI"  ,
 | 
				
			||||||
 | 
					        "MPYHW"  , "MUL"    , "MULF.S" , "MULU"  , "NOT"    , "NOTBSU" ,
 | 
				
			||||||
 | 
					        "OR"     , "ORBSU"  , "ORI"    , "ORNBSU", "OUT.B"  , "OUT.H"  ,
 | 
				
			||||||
 | 
					        "OUT.W"  , "RETI"   , "REV"    , "SAR"   , "SAR"    , "SCH0BSD",
 | 
				
			||||||
 | 
					        "SCH0BSU", "SCH1BSD", "SCH1BSU", "SEI"   , "SETF"   , "SHL"    ,
 | 
				
			||||||
 | 
					        "SHL"    , "SHR"    , "SHR"    , "ST.B"  , "ST.H"   , "ST.W"   ,
 | 
				
			||||||
 | 
					        "STSR"   , "SUB"    , "SUBF.S" , "TRAP"  , "TRNC.SW", "XB"     ,
 | 
				
			||||||
 | 
					        "XH"     , "XOR"    , "XORBSU" , "XORI"  , "XORNBSU"
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Program register names
 | 
				
			||||||
 | 
					    private static final String[] PROGRAMS = {
 | 
				
			||||||
 | 
					        null, null, "hp", "sp", "gp", "tp", null, null,
 | 
				
			||||||
 | 
					        null, null, null, null, null, null, null, null,
 | 
				
			||||||
 | 
					        null, null, null, null, null, null, null, null,
 | 
				
			||||||
 | 
					        null, null, null, null, null, null, null, "lp"
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // System register names
 | 
				
			||||||
 | 
					    private static final String[] SYSTEMS = {
 | 
				
			||||||
 | 
					        "EIPC", "EIPSW", "FEPC", "FEPSW", "ECR", "PSW", "PIR", "TKCW",
 | 
				
			||||||
 | 
					        null  , null   , null  , null   , null , null , null , null  ,
 | 
				
			||||||
 | 
					        null  , null   , null  , null   , null , null , null , null  ,
 | 
				
			||||||
 | 
					        "CHCW", "ADTRE", null  , null   , null , null , null , null
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    //                                Classes                                //
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // One row of output
 | 
				
			||||||
 | 
					    static class Row {
 | 
				
			||||||
 | 
					        String address;  // Bus address
 | 
				
			||||||
 | 
					        String bytes;    // Encoded bytes in bus order
 | 
				
			||||||
 | 
					        String mnemonic; // Instruction mnemonic
 | 
				
			||||||
 | 
					        String operands; // Instruction operands, if any
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    //                            Static Methods                             //
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Reset all settings to their default values
 | 
				
			||||||
 | 
					    static void setDefaults() {
 | 
				
			||||||
 | 
					        bcondCombine = true;
 | 
				
			||||||
 | 
					        bcondNames   = true;
 | 
				
			||||||
 | 
					        condCaps     = true;
 | 
				
			||||||
 | 
					        destLast     = true;
 | 
				
			||||||
 | 
					        dispDest     = true;
 | 
				
			||||||
 | 
					        dispInside   = false;
 | 
				
			||||||
 | 
					        hexCaps      = true;
 | 
				
			||||||
 | 
					        hexMode      = ZEROX;
 | 
				
			||||||
 | 
					        immNumber    = false;
 | 
				
			||||||
 | 
					        jmpBrackets  = true;
 | 
				
			||||||
 | 
					        jumpAddress  = true;
 | 
				
			||||||
 | 
					        lower        = true;
 | 
				
			||||||
 | 
					        mnemonicCaps = true;
 | 
				
			||||||
 | 
					        programCaps  = false;
 | 
				
			||||||
 | 
					        programNames = true;
 | 
				
			||||||
 | 
					        setfCombine  = false;
 | 
				
			||||||
 | 
					        setfNames    = true;
 | 
				
			||||||
 | 
					        systemCaps   = true;
 | 
				
			||||||
 | 
					        systemNames  = true;
 | 
				
			||||||
 | 
					        zero         = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    //                            Package Methods                            //
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Represent an instruction as text fields
 | 
				
			||||||
 | 
					    static void disassemble(int address, Instruction inst, Row row) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Address
 | 
				
			||||||
 | 
					        String x = hexCaps ? "X" : "x";
 | 
				
			||||||
 | 
					        row.address = String.format("%08" + x, address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Bytes
 | 
				
			||||||
 | 
					        x = "%02" + x;
 | 
				
			||||||
 | 
					        row.bytes = inst.size == 2 ?
 | 
				
			||||||
 | 
					            String.format(x + " " + x,
 | 
				
			||||||
 | 
					                inst.bits >> 16 & 0xFF,
 | 
				
			||||||
 | 
					                inst.bits >> 24 & 0xFF
 | 
				
			||||||
 | 
					            ) : String.format(x + " " + x + " " + x + " " + x,
 | 
				
			||||||
 | 
					                inst.bits >> 16 & 0xFF,
 | 
				
			||||||
 | 
					                inst.bits >> 24 & 0xFF,
 | 
				
			||||||
 | 
					                inst.bits       & 0xFF,
 | 
				
			||||||
 | 
					                inst.bits >>  8 & 0xFF
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Bcond mnemonic
 | 
				
			||||||
 | 
					        if (inst.id == VUE.BCOND && bcondCombine) {
 | 
				
			||||||
 | 
					            row.mnemonic = "B" + CONDITIONS[inst.cond];
 | 
				
			||||||
 | 
					            if (lower && (inst.cond & 7) == 1)
 | 
				
			||||||
 | 
					                row.mnemonic = inst.cond == 1 ? "BL" : "BNL";
 | 
				
			||||||
 | 
					            if (zero  && (inst.cond & 7) == 2)
 | 
				
			||||||
 | 
					                row.mnemonic = inst.cond == 2 ? "BZ" : "BNZ";
 | 
				
			||||||
 | 
					            if (         (inst.cond & 7) == 5)
 | 
				
			||||||
 | 
					                row.mnemonic = inst.cond == 5 ? "BR" : "NOP";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // SETF mnemonic
 | 
				
			||||||
 | 
					        else if (inst.id == VUE.SETF && setfCombine)
 | 
				
			||||||
 | 
					            row.mnemonic = "SETF" + CONDITIONS[inst.imm];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // All other mnemonics
 | 
				
			||||||
 | 
					        else row.mnemonic = MNEMONICS[inst.id];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Adjust mnemonic case
 | 
				
			||||||
 | 
					        if (!mnemonicCaps)
 | 
				
			||||||
 | 
					            row.mnemonic = row.mnemonic.toLowerCase();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Operands by format
 | 
				
			||||||
 | 
					        row.operands = null;
 | 
				
			||||||
 | 
					        if (inst.id != VUE.ILLEGAL) switch (inst.format) {
 | 
				
			||||||
 | 
					            case 1: // Fallthrough
 | 
				
			||||||
 | 
					            case 7: row.operands = formatI_VII(inst         ); break;
 | 
				
			||||||
 | 
					            case 2: row.operands = formatII   (inst         ); break;
 | 
				
			||||||
 | 
					            case 3: row.operands = formatIII  (inst, address); break;
 | 
				
			||||||
 | 
					            case 4: row.operands = destination(inst, address); break;
 | 
				
			||||||
 | 
					            case 5: row.operands = formatV    (inst         ); break;
 | 
				
			||||||
 | 
					            case 6: row.operands = formatVI   (inst         ); break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    //                            Private Methods                            //
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Format the destination of a branch or jump
 | 
				
			||||||
 | 
					    private static String destination(Instruction inst, int address) {
 | 
				
			||||||
 | 
					        return !dispDest ? toHex(inst.disp, 1, immNumber) :
 | 
				
			||||||
 | 
					            String.format("%08" + (hexCaps ? "X" : "x"), address + inst.disp);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Operands for Format I and Format VII
 | 
				
			||||||
 | 
					    private static String formatI_VII(Instruction inst) {
 | 
				
			||||||
 | 
					        String reg1 = program(inst.reg1);
 | 
				
			||||||
 | 
					        String reg2 = program(inst.reg2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // One-operand instructions
 | 
				
			||||||
 | 
					        switch (inst.id) {
 | 
				
			||||||
 | 
					            case VUE.JMP:
 | 
				
			||||||
 | 
					                return String.format(jmpBrackets ? "[%s]" : "%s", reg1);
 | 
				
			||||||
 | 
					            case VUE.XB: // Fallthrough
 | 
				
			||||||
 | 
					            case VUE.XH:
 | 
				
			||||||
 | 
					                return reg2;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Generic
 | 
				
			||||||
 | 
					        return String.format("%s, %s",
 | 
				
			||||||
 | 
					            destLast ? reg1 : reg2,
 | 
				
			||||||
 | 
					            destLast ? reg2 : reg1
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Operands for Format II
 | 
				
			||||||
 | 
					    private static String formatII(Instruction inst) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Bit string
 | 
				
			||||||
 | 
					        if (inst.opcode == 0b011111)
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Zero- or one-operand instructions
 | 
				
			||||||
 | 
					        switch (inst.id) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Zero-operand
 | 
				
			||||||
 | 
					            case VUE.CLI : // Fallthrough
 | 
				
			||||||
 | 
					            case VUE.HALT: // Fallthrough
 | 
				
			||||||
 | 
					            case VUE.RETI: // Fallthrough
 | 
				
			||||||
 | 
					            case VUE.SEI :
 | 
				
			||||||
 | 
					                return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // One-operand
 | 
				
			||||||
 | 
					            case VUE.TRAP:
 | 
				
			||||||
 | 
					                return Integer.toString(inst.imm);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Combined SETF
 | 
				
			||||||
 | 
					        String reg2 = program(inst.reg2);
 | 
				
			||||||
 | 
					        if (inst.id == VUE.SETF && setfCombine)
 | 
				
			||||||
 | 
					            return reg2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Two-operand instructions
 | 
				
			||||||
 | 
					        String imm  = String.format("%s%d", immNumber ? "#" : "", inst.imm);
 | 
				
			||||||
 | 
					        switch (inst.id) {
 | 
				
			||||||
 | 
					            case VUE.LDSR: // Fallthrough
 | 
				
			||||||
 | 
					            case VUE.STSR:
 | 
				
			||||||
 | 
					                if (!systemNames || SYSTEMS[inst.imm] == null)
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                imm = SYSTEMS[inst.imm];
 | 
				
			||||||
 | 
					                if (!systemCaps)
 | 
				
			||||||
 | 
					                    imm = imm.toLowerCase();
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case VUE.SETF:
 | 
				
			||||||
 | 
					                if (!setfNames)
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                imm = CONDITIONS[inst.imm];
 | 
				
			||||||
 | 
					                if (!condCaps)
 | 
				
			||||||
 | 
					                    imm = imm.toLowerCase();
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Generic
 | 
				
			||||||
 | 
					        return String.format("%s, %s",
 | 
				
			||||||
 | 
					            destLast ? imm  : reg2,
 | 
				
			||||||
 | 
					            destLast ? reg2 : imm
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Operands for Format III
 | 
				
			||||||
 | 
					    private static String formatIII(Instruction inst, int address) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // NOP
 | 
				
			||||||
 | 
					        if (bcondCombine && inst.cond == 13)
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Format destination
 | 
				
			||||||
 | 
					        String dest = destination(inst, address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // One-operand notation
 | 
				
			||||||
 | 
					        if (bcondCombine)
 | 
				
			||||||
 | 
					            return dest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Two-operand notation
 | 
				
			||||||
 | 
					        String cond = bcondNames ?
 | 
				
			||||||
 | 
					            CONDITIONS[inst.cond] : Integer.toString(inst.cond);
 | 
				
			||||||
 | 
					        if (bcondNames && !condCaps)
 | 
				
			||||||
 | 
					            cond = cond.toLowerCase();
 | 
				
			||||||
 | 
					        return String.format("%s, %s", cond, dest);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Operands for Format V
 | 
				
			||||||
 | 
					    private static String formatV(Instruction inst) {
 | 
				
			||||||
 | 
					        String reg1 = program(inst.reg1);
 | 
				
			||||||
 | 
					        String reg2 = program(inst.reg2);
 | 
				
			||||||
 | 
					        String imm  = toHex(
 | 
				
			||||||
 | 
					            inst.id == VUE.MOVEA ? inst.imm & 0xFFFF : inst.imm,
 | 
				
			||||||
 | 
					            inst.id == VUE.ADDI  ? 1 : 4,
 | 
				
			||||||
 | 
					            immNumber
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        return String.format("%s, %s, %s",
 | 
				
			||||||
 | 
					            destLast ? imm  : reg2,
 | 
				
			||||||
 | 
					            reg1,
 | 
				
			||||||
 | 
					            destLast ? reg2 : imm
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Operands for Format VI
 | 
				
			||||||
 | 
					    private static String formatVI(Instruction inst) {
 | 
				
			||||||
 | 
					        String src  = program(inst.reg1);
 | 
				
			||||||
 | 
					        String dest = program(inst.reg2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Data operand
 | 
				
			||||||
 | 
					        src = inst.disp == 0 ? String.format("[%s]", src) :
 | 
				
			||||||
 | 
					            dispInside ? String.format(
 | 
				
			||||||
 | 
					                "[%s %s %s]",
 | 
				
			||||||
 | 
					                src,
 | 
				
			||||||
 | 
					                inst.disp < 0 ? "-" : "+",
 | 
				
			||||||
 | 
					                toHex(Math.abs(inst.disp), 1, immNumber)
 | 
				
			||||||
 | 
					            ) : String.format(
 | 
				
			||||||
 | 
					                "%s[%s]",
 | 
				
			||||||
 | 
					                toHex(inst.disp, 1, immNumber),
 | 
				
			||||||
 | 
					                src
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Write instruction
 | 
				
			||||||
 | 
					        switch (inst.id) {
 | 
				
			||||||
 | 
					            case VUE.OUT_B: // Fallthrough
 | 
				
			||||||
 | 
					            case VUE.OUT_H: // Fallthrough
 | 
				
			||||||
 | 
					            case VUE.OUT_W: // Fallthrough
 | 
				
			||||||
 | 
					            case VUE.ST_B : // Fallthrough
 | 
				
			||||||
 | 
					            case VUE.ST_H : // Fallthrough
 | 
				
			||||||
 | 
					            case VUE.ST_W :
 | 
				
			||||||
 | 
					                String temp = src;
 | 
				
			||||||
 | 
					                src  = dest;
 | 
				
			||||||
 | 
					                dest = temp;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Format operands
 | 
				
			||||||
 | 
					        return String.format("%s, %s",
 | 
				
			||||||
 | 
					            destLast ? src  : dest,
 | 
				
			||||||
 | 
					            destLast ? dest : src
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Format a program register
 | 
				
			||||||
 | 
					    private static String program(int index) {
 | 
				
			||||||
 | 
					        String ret = programNames ? PROGRAMS[index] : null;
 | 
				
			||||||
 | 
					        if (ret == null)
 | 
				
			||||||
 | 
					            ret = "r" + index;
 | 
				
			||||||
 | 
					        return programCaps ? ret.toUpperCase() : ret;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Represent an immediate value as hexadecimal
 | 
				
			||||||
 | 
					    private static String toHex(int value, int digits, boolean number) {
 | 
				
			||||||
 | 
					        return String.format(
 | 
				
			||||||
 | 
					            "%s%s%s%0" + digits + (hexCaps ? "X" : "x") + "%s",
 | 
				
			||||||
 | 
					            number ? "#" : "",
 | 
				
			||||||
 | 
					            value < 0 ? "-" : "",
 | 
				
			||||||
 | 
					            hexMode == DOLLAR ? "$" : hexMode == ZEROX ? "0x" : "",
 | 
				
			||||||
 | 
					            value < 0 ? -value : value,
 | 
				
			||||||
 | 
					            hexMode == H ? "h" : ""
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -28,12 +28,12 @@ class MainWindow extends JFrame {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // UI components
 | 
					    // UI components
 | 
				
			||||||
    private JPanel        client;   // Common client container
 | 
					    private JPanel        client;   // Common client container
 | 
				
			||||||
    private Console      console; // Console window
 | 
					    private ConsoleWindow console;  // Console window
 | 
				
			||||||
    private CPU          cpu;     // CPU window
 | 
					    private CPUWindow     cpu;      // CPU window
 | 
				
			||||||
    private JDesktopPane  desktop;  // Container for child windows
 | 
					    private JDesktopPane  desktop;  // Container for child windows
 | 
				
			||||||
    private Memory       memory;  // Memory window
 | 
					    private MemoryWindow  memory;   // Memory window
 | 
				
			||||||
    private JPanel       video;   // Video output
 | 
					 | 
				
			||||||
    private JMenu         mnuDebug; // Debug menu
 | 
					    private JMenu         mnuDebug; // Debug menu
 | 
				
			||||||
 | 
					    private JPanel        video;    // Video output
 | 
				
			||||||
    private JMenuItem mnuFileDebugMode; // File -> Debug mode
 | 
					    private JMenuItem mnuFileDebugMode; // File -> Debug mode
 | 
				
			||||||
    private JMenuItem mnuFileGameMode;  // File -> Game mode
 | 
					    private JMenuItem mnuFileGameMode;  // File -> Game mode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,9 +92,9 @@ class MainWindow extends JFrame {
 | 
				
			||||||
        // Configure child windows
 | 
					        // Configure child windows
 | 
				
			||||||
        desktop = new JDesktopPane();
 | 
					        desktop = new JDesktopPane();
 | 
				
			||||||
        desktop.setBackground(SystemColor.controlShadow);
 | 
					        desktop.setBackground(SystemColor.controlShadow);
 | 
				
			||||||
        desktop.add(console = new Console(this));
 | 
					        desktop.add(console = new ConsoleWindow(this));
 | 
				
			||||||
        desktop.add(cpu     = new CPU    (this));
 | 
					        desktop.add(cpu     = new CPUWindow    (this));
 | 
				
			||||||
        desktop.add(memory  = new Memory (this));
 | 
					        desktop.add(memory  = new MemoryWindow (this));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Display window
 | 
					        // Display window
 | 
				
			||||||
        refreshDebug();
 | 
					        refreshDebug();
 | 
				
			||||||
| 
						 | 
					@ -207,6 +207,7 @@ class MainWindow extends JFrame {
 | 
				
			||||||
    // Window close, File -> Exit
 | 
					    // Window close, File -> Exit
 | 
				
			||||||
    private void onClose() {
 | 
					    private void onClose() {
 | 
				
			||||||
        app.removeWindow(this);
 | 
					        app.removeWindow(this);
 | 
				
			||||||
 | 
					        cpu.dispose();
 | 
				
			||||||
        dispose();
 | 
					        dispose();
 | 
				
			||||||
        vue.dispose();
 | 
					        vue.dispose();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,7 @@ import javax.swing.*;
 | 
				
			||||||
import util.*;
 | 
					import util.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Memory viewer and hex editor window
 | 
					// Memory viewer and hex editor window
 | 
				
			||||||
class Memory extends ChildWindow {
 | 
					class MemoryWindow extends ChildWindow {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Private fields
 | 
					    // Private fields
 | 
				
			||||||
    private int  address;    // Address of top row
 | 
					    private int  address;    // Address of top row
 | 
				
			||||||
| 
						 | 
					@ -41,7 +41,7 @@ class Memory extends ChildWindow {
 | 
				
			||||||
    ///////////////////////////////////////////////////////////////////////////
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Default constructor
 | 
					    // Default constructor
 | 
				
			||||||
    Memory(MainWindow parent) {
 | 
					    MemoryWindow(MainWindow parent) {
 | 
				
			||||||
        super(parent, "memory.title");
 | 
					        super(parent, "memory.title");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Configure instance fields
 | 
					        // Configure instance fields
 | 
				
			||||||
| 
						 | 
					@ -14,26 +14,22 @@ import vue.*;
 | 
				
			||||||
class Register {
 | 
					class Register {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Instance fields
 | 
					    // Instance fields
 | 
				
			||||||
    boolean    expandable; // The expansion area can be shown
 | 
					    private boolean      expandable; // The expansion area can be shown
 | 
				
			||||||
    boolean    expanded;   // The expanded area is being shown
 | 
					    private boolean      expanded;   // The expanded area is being shown
 | 
				
			||||||
    Font       font;       // Hexadecimal font
 | 
					    private int          index;      // Register index
 | 
				
			||||||
    int        index;      // Register index
 | 
					    private int          mode;       // Display mode for program registers
 | 
				
			||||||
    int        mode;       // Display mode for program registers
 | 
					    private String       name;       // Register name
 | 
				
			||||||
    MainWindow parent;     // Containing window
 | 
					    private RegisterList parent;     // Containing register list
 | 
				
			||||||
    int        type;       // Expansion controls type
 | 
					    private int          type;       // Expansion controls type
 | 
				
			||||||
    int        value;      // Current register value
 | 
					    private int          value;      // Current register value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // UI components
 | 
					    // UI components
 | 
				
			||||||
    private JPanel     expansion;   // Expansion area
 | 
					    JPanel     expansion; // Expansion container
 | 
				
			||||||
    private JLabel     btnExpand;   // Expand button
 | 
					    JLabel     btnExpand; // Expand button
 | 
				
			||||||
    private JLabel     lblLastPC;   // Last PC name
 | 
					    JPanel     indent;    // Expansion area indentation
 | 
				
			||||||
    private JLabel     lblName;     // Register name
 | 
					    JLabel     lblName;   // Register name
 | 
				
			||||||
    private JPanel     list;        // Containing element
 | 
					    JTextField txtValue;  // Register value
 | 
				
			||||||
    private JPanel     spacer;      // Expansion area spacer
 | 
					    ArrayList<JComponent> controls; // Expansion controls
 | 
				
			||||||
    private JTextField txtJumpFrom; // Jump-from value
 | 
					 | 
				
			||||||
    private JTextField txtJumpTo;   // Jump-to value
 | 
					 | 
				
			||||||
    private JTextField txtValue;    // Register value
 | 
					 | 
				
			||||||
    private ArrayList<JComponent> controls; // Expansion controls
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,8 +44,8 @@ class Register {
 | 
				
			||||||
    static final int UNSIGNED = 2;
 | 
					    static final int UNSIGNED = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Types
 | 
					    // Types
 | 
				
			||||||
    static final int PLAIN   = -1;
 | 
					    static final int PLAIN   = -2;
 | 
				
			||||||
    static final int PROGRAM = -2;
 | 
					    static final int PROGRAM = -3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,14 +54,15 @@ class Register {
 | 
				
			||||||
    ///////////////////////////////////////////////////////////////////////////
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Default constructor
 | 
					    // Default constructor
 | 
				
			||||||
    Register(MainWindow parent, JPanel list, String name, int index, int type){
 | 
					    Register(RegisterList parent, String name, int index, int type) {
 | 
				
			||||||
 | 
					        parent.add(index, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Configure instance fields
 | 
					        // Configure instance fields
 | 
				
			||||||
        controls    = new ArrayList<JComponent>();
 | 
					        controls    = new ArrayList<JComponent>();
 | 
				
			||||||
        expandable  = type != PLAIN && index != 0 || index == VUE.PC;
 | 
					        expandable  = type != PLAIN && index != 0;
 | 
				
			||||||
        this.index  = index;
 | 
					        this.index  = index;
 | 
				
			||||||
        this.list   = list;
 | 
					        mode        = HEX;
 | 
				
			||||||
        this.mode   = HEX;
 | 
					        this.name   = name;
 | 
				
			||||||
        this.parent = parent;
 | 
					        this.parent = parent;
 | 
				
			||||||
        this.type   = type;
 | 
					        this.type   = type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,17 +78,17 @@ class Register {
 | 
				
			||||||
        var gbc = new GridBagConstraints();
 | 
					        var gbc = new GridBagConstraints();
 | 
				
			||||||
        gbc.anchor = GridBagConstraints.NORTH;
 | 
					        gbc.anchor = GridBagConstraints.NORTH;
 | 
				
			||||||
        gbc.fill   = GridBagConstraints.HORIZONTAL;
 | 
					        gbc.fill   = GridBagConstraints.HORIZONTAL;
 | 
				
			||||||
        list.add(btnExpand, gbc);
 | 
					        parent.add(gbc, btnExpand);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Name label
 | 
					        // Name label
 | 
				
			||||||
        lblName = new JLabel(name);
 | 
					        lblName = new JLabel(" ");
 | 
				
			||||||
        if (expandable)
 | 
					        if (expandable)
 | 
				
			||||||
            lblName.addMouseListener(expand);
 | 
					            lblName.addMouseListener(expand);
 | 
				
			||||||
        gbc = new GridBagConstraints();
 | 
					        gbc = new GridBagConstraints();
 | 
				
			||||||
        gbc.anchor  = GridBagConstraints.NORTH;
 | 
					        gbc.anchor  = GridBagConstraints.NORTH;
 | 
				
			||||||
        gbc.fill    = GridBagConstraints.HORIZONTAL;
 | 
					        gbc.fill    = GridBagConstraints.HORIZONTAL;
 | 
				
			||||||
        gbc.weightx = 1;
 | 
					        gbc.weightx = 1;
 | 
				
			||||||
        list.add(lblName, gbc);
 | 
					        parent.add(gbc, lblName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Value text box
 | 
					        // Value text box
 | 
				
			||||||
        txtValue = new JTextField();
 | 
					        txtValue = new JTextField();
 | 
				
			||||||
| 
						 | 
					@ -101,7 +98,7 @@ class Register {
 | 
				
			||||||
        gbc = new GridBagConstraints();
 | 
					        gbc = new GridBagConstraints();
 | 
				
			||||||
        gbc.gridwidth = GridBagConstraints.REMAINDER;
 | 
					        gbc.gridwidth = GridBagConstraints.REMAINDER;
 | 
				
			||||||
        gbc.insets    = new Insets(0, 4, 0, 0);
 | 
					        gbc.insets    = new Insets(0, 4, 0, 0);
 | 
				
			||||||
        list.add(txtValue, gbc);
 | 
					        parent.add(gbc, txtValue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Value changed
 | 
					        // Value changed
 | 
				
			||||||
        txtValue.addActionListener(e->{
 | 
					        txtValue.addActionListener(e->{
 | 
				
			||||||
| 
						 | 
					@ -129,14 +126,14 @@ class Register {
 | 
				
			||||||
            default: return;
 | 
					            default: return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Expansion spacer
 | 
					        // Expansion indentation
 | 
				
			||||||
        if (index != VUE.PC) {
 | 
					        if (index != VUE.PC) {
 | 
				
			||||||
            spacer = new JPanel(null);
 | 
					            indent = new JPanel(null);
 | 
				
			||||||
            spacer.setOpaque(false);
 | 
					            indent.setOpaque(false);
 | 
				
			||||||
            spacer.setPreferredSize(new Dimension(0, 0));
 | 
					            indent.setPreferredSize(new Dimension(0, 0));
 | 
				
			||||||
            spacer.setVisible(false);
 | 
					            indent.setVisible(false);
 | 
				
			||||||
            gbc = new GridBagConstraints();
 | 
					            gbc = new GridBagConstraints();
 | 
				
			||||||
            list.add(spacer, gbc);
 | 
					            parent.add(gbc, indent);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Expansion area
 | 
					        // Expansion area
 | 
				
			||||||
| 
						 | 
					@ -149,7 +146,11 @@ class Register {
 | 
				
			||||||
        gbc.gridwidth = GridBagConstraints.REMAINDER;
 | 
					        gbc.gridwidth = GridBagConstraints.REMAINDER;
 | 
				
			||||||
        gbc.insets    = new Insets(0, 4, 0, 0);
 | 
					        gbc.insets    = new Insets(0, 4, 0, 0);
 | 
				
			||||||
        gbc.weightx   = 1;
 | 
					        gbc.weightx   = 1;
 | 
				
			||||||
        list.add(expansion, gbc);
 | 
					        parent.add(gbc, expansion);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Handling for PSW
 | 
				
			||||||
 | 
					        if (index == VUE.PSW && type == VUE.PSW)
 | 
				
			||||||
 | 
					            setExpanded(true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -161,14 +162,14 @@ class Register {
 | 
				
			||||||
    // Expansion controls for CHCW
 | 
					    // Expansion controls for CHCW
 | 
				
			||||||
    private void initCHCW() {
 | 
					    private void initCHCW() {
 | 
				
			||||||
        expansion = new JPanel(new GridBagLayout());
 | 
					        expansion = new JPanel(new GridBagLayout());
 | 
				
			||||||
        addCheckBox("ICE", 1, false); endRow();
 | 
					        addCheckBox("ICE", 1, false, true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Expansion controls for ECR
 | 
					    // Expansion controls for ECR
 | 
				
			||||||
    private void initECR() {
 | 
					    private void initECR() {
 | 
				
			||||||
        expansion = new JPanel(new GridBagLayout());
 | 
					        expansion = new JPanel(new GridBagLayout());
 | 
				
			||||||
        addTextBox("EICC",  0, 16, false, true); endRow();
 | 
					        addTextBox("EICC",  0, 16, false, true);
 | 
				
			||||||
        addTextBox("FECC", 16, 16, false, true); endRow();
 | 
					        addTextBox("FECC", 16, 16, false, true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Expansion controls for program registers
 | 
					    // Expansion controls for program registers
 | 
				
			||||||
| 
						 | 
					@ -189,38 +190,37 @@ class Register {
 | 
				
			||||||
        for (int x = 0; x < 2; x++) {
 | 
					        for (int x = 0; x < 2; x++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Indentation
 | 
					            // Indentation
 | 
				
			||||||
            var spacer = new JPanel(null);
 | 
					            indent = new JPanel(null);
 | 
				
			||||||
            spacer.setOpaque(false);
 | 
					            indent.setOpaque(false);
 | 
				
			||||||
            spacer.setPreferredSize(new Dimension(0, 0));
 | 
					            indent.setPreferredSize(new Dimension(0, 0));
 | 
				
			||||||
            var gbc = new GridBagConstraints();
 | 
					            var gbc = new GridBagConstraints();
 | 
				
			||||||
            gbc.weightx = 1;
 | 
					            gbc.weightx = 1;
 | 
				
			||||||
            expansion.add(spacer, gbc);
 | 
					            expansion.add(indent, gbc);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
            // Name label
 | 
					            // Name label
 | 
				
			||||||
            var label = new JLabel();
 | 
					            var label = new JLabel();
 | 
				
			||||||
            parent.app.localizer.add(label,
 | 
					            parent.parent.parent.app.localizer.add(label,
 | 
				
			||||||
                x == 0 ? "cpu.jump_from" : "cpu.jump_to" );
 | 
					                x == 0 ? "cpu.jump_from" : "cpu.jump_to" );
 | 
				
			||||||
            gbc = new GridBagConstraints();
 | 
					            gbc = new GridBagConstraints();
 | 
				
			||||||
            gbc.anchor = GridBagConstraints.NORTHWEST;
 | 
					            gbc.anchor = GridBagConstraints.NORTHWEST;
 | 
				
			||||||
            expansion.add(label, gbc);
 | 
					            expansion.add(label, gbc);
 | 
				
			||||||
 | 
					            controls.add(label);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
            // Value text box
 | 
					            // Value text box
 | 
				
			||||||
            var txt = new JTextField();
 | 
					            var txt = new JTextField();
 | 
				
			||||||
            txt.addActionListener(e->{
 | 
					            txt.addActionListener(e->{
 | 
				
			||||||
                txt.setText((String) txt.getClientProperty("text"));
 | 
					                txt.setText((String) txt.getClientProperty("text"));
 | 
				
			||||||
                list.requestFocus();
 | 
					                parent.requestFocus();
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					            txt.putClientProperty("index",
 | 
				
			||||||
 | 
					                x == 0 ? VUE.JUMP_FROM : VUE.JUMP_TO);
 | 
				
			||||||
            txt.setBorder(null);
 | 
					            txt.setBorder(null);
 | 
				
			||||||
            txt.setOpaque(false);
 | 
					            txt.setOpaque(false);
 | 
				
			||||||
            gbc = new GridBagConstraints();
 | 
					            gbc = new GridBagConstraints();
 | 
				
			||||||
            gbc.gridwidth = GridBagConstraints.REMAINDER;
 | 
					            gbc.gridwidth = GridBagConstraints.REMAINDER;
 | 
				
			||||||
            gbc.insets    = new Insets(0, 4, 0, 0);
 | 
					            gbc.insets    = new Insets(0, 4, 0, 0);
 | 
				
			||||||
            expansion.add(txt, gbc);
 | 
					            expansion.add(txt, gbc);
 | 
				
			||||||
        
 | 
					            controls.add(txt);
 | 
				
			||||||
            // Initialize the corresponding component field
 | 
					 | 
				
			||||||
            if (x == 0)
 | 
					 | 
				
			||||||
                txtJumpFrom = txt;
 | 
					 | 
				
			||||||
            else txtJumpTo = txt;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -228,40 +228,40 @@ class Register {
 | 
				
			||||||
    // Expansion controls for PSW
 | 
					    // Expansion controls for PSW
 | 
				
			||||||
    private void initPSW() {
 | 
					    private void initPSW() {
 | 
				
			||||||
        expansion = new JPanel(new GridBagLayout());
 | 
					        expansion = new JPanel(new GridBagLayout());
 | 
				
			||||||
        addCheckBox("Z"  ,  0, false);
 | 
					        addCheckBox("Z"  ,  0, false, false);
 | 
				
			||||||
        addCheckBox("FRO",  9, false); endRow();
 | 
					        addCheckBox("FRO",  9, false, true );
 | 
				
			||||||
        addCheckBox("S"  ,  1, false);
 | 
					        addCheckBox("S"  ,  1, false, false);
 | 
				
			||||||
        addCheckBox("FIV",  8, false); endRow();
 | 
					        addCheckBox("FIV",  8, false, true );
 | 
				
			||||||
        addCheckBox("OV" ,  2, false);
 | 
					        addCheckBox("OV" ,  2, false, false);
 | 
				
			||||||
        addCheckBox("FZD",  7, false); endRow();
 | 
					        addCheckBox("FZD",  7, false, true );
 | 
				
			||||||
        addCheckBox("CY" ,  3, false);
 | 
					        addCheckBox("CY" ,  3, false, false);
 | 
				
			||||||
        addCheckBox("FOV",  6, false); endRow();
 | 
					        addCheckBox("FOV",  6, false, true );
 | 
				
			||||||
        addCheckBox("EP" , 14, false);
 | 
					        addCheckBox("EP" , 14, false, false);
 | 
				
			||||||
        addCheckBox("FUD",  5, false); endRow();
 | 
					        addCheckBox("FUD",  5, false, true );
 | 
				
			||||||
        addCheckBox("NP" , 15, false);
 | 
					        addCheckBox("NP" , 15, false, false);
 | 
				
			||||||
        addCheckBox("FPR",  4, false); endRow();
 | 
					        addCheckBox("FPR",  4, false, true );
 | 
				
			||||||
        addCheckBox("AE" , 13, false); endRow();
 | 
					        addCheckBox("AE" , 13, false, true );
 | 
				
			||||||
        addCheckBox("ID" , 12, false);
 | 
					        addCheckBox("ID" , 12, false, false);
 | 
				
			||||||
        addTextBox ("I"  , 16, 4, false, false); endRow();
 | 
					        addTextBox ("I"  , 16, 4, false, false);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Expansion controls for PIR
 | 
					    // Expansion controls for PIR
 | 
				
			||||||
    private void initPIR() {
 | 
					    private void initPIR() {
 | 
				
			||||||
        expansion = new JPanel(new GridBagLayout());
 | 
					        expansion = new JPanel(new GridBagLayout());
 | 
				
			||||||
        addTextBox("PT",  0, 16, true, true); endRow();
 | 
					        addTextBox("PT",  0, 16, true, true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Expansion controls for TKCW
 | 
					    // Expansion controls for TKCW
 | 
				
			||||||
    private void initTKCW() {
 | 
					    private void initTKCW() {
 | 
				
			||||||
        expansion = new JPanel(new GridBagLayout());
 | 
					        expansion = new JPanel(new GridBagLayout());
 | 
				
			||||||
        addCheckBox("OTM", 8, true);
 | 
					        addCheckBox("OTM", 8, true, false);
 | 
				
			||||||
        addCheckBox("FVT", 5, true); endRow();
 | 
					        addCheckBox("FVT", 5, true, true );
 | 
				
			||||||
        addCheckBox("FIT", 7, true);
 | 
					        addCheckBox("FIT", 7, true, false);
 | 
				
			||||||
        addCheckBox("FUT", 4, true); endRow();
 | 
					        addCheckBox("FUT", 4, true, true );
 | 
				
			||||||
        addCheckBox("FZT", 6, true);
 | 
					        addCheckBox("FZT", 6, true, false);
 | 
				
			||||||
        addCheckBox("FPT", 3, true); endRow();
 | 
					        addCheckBox("FPT", 3, true, true );
 | 
				
			||||||
        addCheckBox("RDI", 2, true);
 | 
					        addCheckBox("RDI", 2, true, false);
 | 
				
			||||||
        addTextBox ("RD", 0, 2, true, false); endRow();
 | 
					        addTextBox ("RD", 0, 2, true, false);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -270,11 +270,61 @@ class Register {
 | 
				
			||||||
    //                            Package Methods                            //
 | 
					    //                            Package Methods                            //
 | 
				
			||||||
    ///////////////////////////////////////////////////////////////////////////
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Refresh controls
 | 
					    // Apply configuration settings
 | 
				
			||||||
    void refresh() {
 | 
					    void configure() {
 | 
				
			||||||
 | 
					        String name = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // System register
 | 
				
			||||||
 | 
					        if (type != PROGRAM) {
 | 
				
			||||||
 | 
					            name = this.name;
 | 
				
			||||||
 | 
					            if (!Disassembler.systemCaps)
 | 
				
			||||||
 | 
					                name = name.toLowerCase();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Program register
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            if (Disassembler.programNames)
 | 
				
			||||||
 | 
					                name = this.name;
 | 
				
			||||||
 | 
					            if (name == null)
 | 
				
			||||||
 | 
					                name = "r" + index;
 | 
				
			||||||
 | 
					            if (Disassembler.programCaps)
 | 
				
			||||||
 | 
					                name = name.toUpperCase();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Name label
 | 
				
			||||||
 | 
					        lblName.setText(name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Expand button
 | 
				
			||||||
 | 
					        var size = btnExpand.getPreferredSize();
 | 
				
			||||||
 | 
					        size.width = CPUWindow.regExpandWidth;
 | 
				
			||||||
 | 
					        btnExpand.setPreferredSize(size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Value text box
 | 
					        // Value text box
 | 
				
			||||||
        value = parent.vue.getRegister(index, type != PROGRAM);
 | 
					        var fontSize = CPUWindow.regHexFontSize;
 | 
				
			||||||
 | 
					            size     = new Dimension(8 * fontSize.width + 4, fontSize.height);
 | 
				
			||||||
 | 
					        txtValue.setFont(CPUWindow.regHexFont);
 | 
				
			||||||
 | 
					        txtValue.setPreferredSize(size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Expansion controls
 | 
				
			||||||
 | 
					        for (var ctrl : controls) {
 | 
				
			||||||
 | 
					            if (!(ctrl instanceof JTextField))
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            if (type == VUE.PC || (Boolean) ctrl.getClientProperty("hex"))
 | 
				
			||||||
 | 
					                ((JTextField) ctrl).setFont(CPUWindow.regHexFont);
 | 
				
			||||||
 | 
					            int digits = type == VUE.PC ? 8 :
 | 
				
			||||||
 | 
					                (Integer) ctrl.getClientProperty("digits");
 | 
				
			||||||
 | 
					            size       = ctrl.getPreferredSize();
 | 
				
			||||||
 | 
					            size.width = digits * fontSize.width + 4;
 | 
				
			||||||
 | 
					            ctrl.setPreferredSize(size);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Refresh controls
 | 
				
			||||||
 | 
					    void refresh() {
 | 
				
			||||||
 | 
					        var vue = parent.parent.parent.vue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Value text box
 | 
				
			||||||
 | 
					        value = vue.getRegister(index, type != PROGRAM);
 | 
				
			||||||
        txtValue.setText(
 | 
					        txtValue.setText(
 | 
				
			||||||
            type != PROGRAM || mode == HEX ?
 | 
					            type != PROGRAM || mode == HEX ?
 | 
				
			||||||
                String.format("%08X", value) :
 | 
					                String.format("%08X", value) :
 | 
				
			||||||
| 
						 | 
					@ -283,18 +333,8 @@ class Register {
 | 
				
			||||||
            Float.toString(Float.intBitsToFloat(value))
 | 
					            Float.toString(Float.intBitsToFloat(value))
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // PC expansion controls
 | 
					        // Expansion controls
 | 
				
			||||||
        if (index == VUE.PC) for (int x = 0; x < 2; x++) {
 | 
					        for (var control : controls) {
 | 
				
			||||||
            JTextField txt = x == 0 ? txtJumpFrom : txtJumpTo;
 | 
					 | 
				
			||||||
            int index = x == 0 ? VUE.JUMP_FROM : VUE.JUMP_TO;
 | 
					 | 
				
			||||||
            int value = parent.vue.getRegister(index, true);
 | 
					 | 
				
			||||||
            String text = String.format("%08X", value);
 | 
					 | 
				
			||||||
            txt.putClientProperty("text", text);
 | 
					 | 
				
			||||||
            txt.setText(text);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Other expansion controls
 | 
					 | 
				
			||||||
        else for (var control : controls) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Check box
 | 
					            // Check box
 | 
				
			||||||
            if (control instanceof JCheckBox) {
 | 
					            if (control instanceof JCheckBox) {
 | 
				
			||||||
| 
						 | 
					@ -306,13 +346,32 @@ class Register {
 | 
				
			||||||
            // Text box
 | 
					            // Text box
 | 
				
			||||||
            if (control instanceof JTextField) {
 | 
					            if (control instanceof JTextField) {
 | 
				
			||||||
                var     ctrl   = (JTextField) control;
 | 
					                var     ctrl   = (JTextField) control;
 | 
				
			||||||
 | 
					                int     digits; // Maximum digits that can be displayed
 | 
				
			||||||
 | 
					                boolean hex;    // The value is hexadecimal
 | 
				
			||||||
 | 
					                int     val;    // The value to be displayed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Jump history
 | 
				
			||||||
 | 
					                if (type == VUE.PC) {
 | 
				
			||||||
 | 
					                    digits = 8;
 | 
				
			||||||
 | 
					                    hex    = true;
 | 
				
			||||||
 | 
					                    val    = vue.getRegister((Integer)
 | 
				
			||||||
 | 
					                        ctrl.getClientProperty("index"), true);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // All other values
 | 
				
			||||||
 | 
					                else {
 | 
				
			||||||
                    int bit    = (Integer) ctrl.getClientProperty("bit"  );
 | 
					                    int bit    = (Integer) ctrl.getClientProperty("bit"  );
 | 
				
			||||||
                int     digits = (Integer) ctrl.getClientProperty("digits");
 | 
					                        digits = (Integer) ctrl.getClientProperty("digits");
 | 
				
			||||||
                boolean hex    = (Boolean) ctrl.getClientProperty("hex");
 | 
					                        hex    = (Boolean) ctrl.getClientProperty("hex");
 | 
				
			||||||
                    int width  = (Integer) ctrl.getClientProperty("width");
 | 
					                    int width  = (Integer) ctrl.getClientProperty("width");
 | 
				
			||||||
                int     val    = value >> bit & (1 << width) - 1;
 | 
					                        val = value >> bit & (1 << width) - 1;
 | 
				
			||||||
                ctrl.setText(!hex ? Integer.toString(val) :
 | 
					                }
 | 
				
			||||||
                    String.format("%0" + digits + "X", val));
 | 
					
 | 
				
			||||||
 | 
					                // Update the text
 | 
				
			||||||
 | 
					                String text = !hex ? Integer.toString(val) : String.format(
 | 
				
			||||||
 | 
					                    "%0" + digits + (Disassembler.hexCaps ? "X" : "x"), val);
 | 
				
			||||||
 | 
					                ctrl.putClientProperty("text", text);
 | 
				
			||||||
 | 
					                ctrl.setText(text);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -329,52 +388,16 @@ class Register {
 | 
				
			||||||
        // Update controls
 | 
					        // Update controls
 | 
				
			||||||
        this.expanded = expanded;
 | 
					        this.expanded = expanded;
 | 
				
			||||||
        btnExpand.setText(expanded ? "-" : "+");
 | 
					        btnExpand.setText(expanded ? "-" : "+");
 | 
				
			||||||
        if (index != VUE.PC)
 | 
					        if (type != VUE.PC)
 | 
				
			||||||
            spacer.setVisible(expanded);
 | 
					            indent.setVisible(expanded);
 | 
				
			||||||
        expansion.setVisible(expanded);
 | 
					        expansion.setVisible(expanded);
 | 
				
			||||||
        list.revalidate();
 | 
					        parent.revalidate();
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Specify the width of the expand button
 | 
					 | 
				
			||||||
    void setExpandWidth(int width) {
 | 
					 | 
				
			||||||
        var size = btnExpand.getPreferredSize();
 | 
					 | 
				
			||||||
        size.width = width;
 | 
					 | 
				
			||||||
        btnExpand.setPreferredSize(size);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Specify a new font
 | 
					 | 
				
			||||||
    void setFont(Font font, int fontWidth, int fontHeight) {
 | 
					 | 
				
			||||||
        this.font = font;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Value text box
 | 
					 | 
				
			||||||
        var size = new Dimension(8 * fontWidth + 4, fontHeight);
 | 
					 | 
				
			||||||
        txtValue.setFont(font);
 | 
					 | 
				
			||||||
        txtValue.setPreferredSize(size);
 | 
					 | 
				
			||||||
        if (index == VUE.PC) {
 | 
					 | 
				
			||||||
            txtJumpFrom.setFont(font);
 | 
					 | 
				
			||||||
            txtJumpFrom.setPreferredSize(size);
 | 
					 | 
				
			||||||
            txtJumpTo  .setFont(font);
 | 
					 | 
				
			||||||
            txtJumpTo  .setPreferredSize(size);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Expansion controls
 | 
					 | 
				
			||||||
        for (var ctrl : controls) {
 | 
					 | 
				
			||||||
            if (!(ctrl instanceof JTextField))
 | 
					 | 
				
			||||||
                continue;
 | 
					 | 
				
			||||||
            if ((Boolean) ctrl.getClientProperty("hex"))
 | 
					 | 
				
			||||||
                ((JTextField) ctrl).setFont(font);
 | 
					 | 
				
			||||||
            int digits = (Integer) ctrl.getClientProperty("digits");
 | 
					 | 
				
			||||||
            size       = ctrl.getPreferredSize();
 | 
					 | 
				
			||||||
            size.width = digits * fontWidth + 4;
 | 
					 | 
				
			||||||
            ctrl.setPreferredSize(size);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Change the display mode of a program register
 | 
					    // Change the display mode of a program register
 | 
				
			||||||
    void setMode(int mode) {
 | 
					    void setMode(int mode) {
 | 
				
			||||||
        this.mode = mode;
 | 
					        this.mode = mode;
 | 
				
			||||||
        txtValue.setFont(mode == HEX ? font : null);
 | 
					        txtValue.setFont(mode == HEX ? CPUWindow.regHexFont : null);
 | 
				
			||||||
        refresh();
 | 
					        refresh();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -385,7 +408,8 @@ class Register {
 | 
				
			||||||
    ///////////////////////////////////////////////////////////////////////////
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Add a check box to the expansion area
 | 
					    // Add a check box to the expansion area
 | 
				
			||||||
    private void addCheckBox(String name, int bit, boolean readOnly) {
 | 
					    private void addCheckBox(String name, int bit, boolean readOnly,
 | 
				
			||||||
 | 
					        boolean last) {
 | 
				
			||||||
        int mask = 1 << bit;
 | 
					        int mask = 1 << bit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Configure control
 | 
					        // Configure control
 | 
				
			||||||
| 
						 | 
					@ -406,7 +430,7 @@ class Register {
 | 
				
			||||||
        // Configure expansion area
 | 
					        // Configure expansion area
 | 
				
			||||||
        var gbc = new GridBagConstraints();
 | 
					        var gbc = new GridBagConstraints();
 | 
				
			||||||
        gbc.anchor    = GridBagConstraints.NORTHWEST;
 | 
					        gbc.anchor    = GridBagConstraints.NORTHWEST;
 | 
				
			||||||
        gbc.gridwidth = 2;
 | 
					        gbc.gridwidth = last ? GridBagConstraints.REMAINDER : 2;
 | 
				
			||||||
        gbc.insets    = new Insets(0, 4, 0, 4);
 | 
					        gbc.insets    = new Insets(0, 4, 0, 4);
 | 
				
			||||||
        expansion.add(ctrl, gbc);
 | 
					        expansion.add(ctrl, gbc);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -416,7 +440,7 @@ class Register {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Configure control
 | 
					        // Configure control
 | 
				
			||||||
        var ctrl = new JRadioButton();
 | 
					        var ctrl = new JRadioButton();
 | 
				
			||||||
        parent.app.localizer.add(ctrl, key);
 | 
					        parent.parent.parent.app.localizer.add(ctrl, key);
 | 
				
			||||||
        ctrl.setBorder(null);
 | 
					        ctrl.setBorder(null);
 | 
				
			||||||
        ctrl.setFocusable(false);
 | 
					        ctrl.setFocusable(false);
 | 
				
			||||||
        ctrl.setOpaque(false);
 | 
					        ctrl.setOpaque(false);
 | 
				
			||||||
| 
						 | 
					@ -469,23 +493,16 @@ class Register {
 | 
				
			||||||
        gbc.anchor = GridBagConstraints.NORTHWEST;
 | 
					        gbc.anchor = GridBagConstraints.NORTHWEST;
 | 
				
			||||||
        gbc.insets = new Insets(0, 4, 0, 4);
 | 
					        gbc.insets = new Insets(0, 4, 0, 4);
 | 
				
			||||||
        expansion.add(label, gbc);
 | 
					        expansion.add(label, gbc);
 | 
				
			||||||
        expansion.add(ctrl , gbc);
 | 
					        gbc = new GridBagConstraints();
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Terminate a row of expansion controls
 | 
					 | 
				
			||||||
    private void endRow() {
 | 
					 | 
				
			||||||
        var spacer = new JPanel(null);
 | 
					 | 
				
			||||||
        spacer.setOpaque(false);
 | 
					 | 
				
			||||||
        spacer.setPreferredSize(new Dimension(0, 0));
 | 
					 | 
				
			||||||
        var gbc = new GridBagConstraints();
 | 
					 | 
				
			||||||
        gbc.gridwidth = GridBagConstraints.REMAINDER;
 | 
					        gbc.gridwidth = GridBagConstraints.REMAINDER;
 | 
				
			||||||
        expansion.add(spacer, gbc);
 | 
					        gbc.insets    = new Insets(0, 4, 0, 4);
 | 
				
			||||||
 | 
					        expansion.add(ctrl , gbc);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Update the register value
 | 
					    // Update the register value
 | 
				
			||||||
    private void setValue(int value) {
 | 
					    private void setValue(int value) {
 | 
				
			||||||
        list.requestFocus();
 | 
					        parent.requestFocus();
 | 
				
			||||||
        parent.vue.setRegister(index, type != PROGRAM, value);
 | 
					        parent.parent.parent.vue.setRegister(index, type != PROGRAM, value);
 | 
				
			||||||
        refresh();
 | 
					        refresh();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,201 @@
 | 
				
			||||||
 | 
					package app;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Java imports
 | 
				
			||||||
 | 
					import java.awt.*;
 | 
				
			||||||
 | 
					import java.util.*;
 | 
				
			||||||
 | 
					import javax.swing.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Project imports
 | 
				
			||||||
 | 
					import vue.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// List of CPU registers
 | 
				
			||||||
 | 
					class RegisterList extends JScrollPane {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Package fields
 | 
				
			||||||
 | 
					    CPUWindow parent; // Containing CPU window
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Private fields
 | 
				
			||||||
 | 
					    private boolean shown; // Component has been shown
 | 
				
			||||||
 | 
					    private HashMap<Integer, Register> registers; // Register items
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // UI components
 | 
				
			||||||
 | 
					    private JPanel client; // Client area
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    //                             Constructors                              //
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Default constructor
 | 
				
			||||||
 | 
					    RegisterList(CPUWindow parent, boolean system) {
 | 
				
			||||||
 | 
					        super(VERTICAL_SCROLLBAR_ALWAYS, HORIZONTAL_SCROLLBAR_AS_NEEDED);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Configure instance fields
 | 
				
			||||||
 | 
					        this.parent = parent;
 | 
				
			||||||
 | 
					        registers   = new HashMap<Integer, Register>();
 | 
				
			||||||
 | 
					        shown       = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Configure client area
 | 
				
			||||||
 | 
					        client = new JPanel(new GridBagLayout()) {
 | 
				
			||||||
 | 
					            public Dimension getPreferredSize() {
 | 
				
			||||||
 | 
					                var ret = super.getPreferredSize();
 | 
				
			||||||
 | 
					                if (!shown) ret.height = system ? getInitialHeight() : 0;
 | 
				
			||||||
 | 
					                return ret;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            public void paintComponent(Graphics g) {
 | 
				
			||||||
 | 
					                shown = true;
 | 
				
			||||||
 | 
					                super.paintComponent(g);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        client.setBackground(SystemColor.window);
 | 
				
			||||||
 | 
					        client.setFocusable(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Initialize system registers
 | 
				
			||||||
 | 
					        if (system) {
 | 
				
			||||||
 | 
					            new Register(this, "PC"   , VUE.PC   , VUE.PC        );
 | 
				
			||||||
 | 
					            new Register(this, "PSW"  , VUE.PSW  , VUE.PSW       );
 | 
				
			||||||
 | 
					            new Register(this, "EIPC" , VUE.EIPC , Register.PLAIN);
 | 
				
			||||||
 | 
					            new Register(this, "EIPSW", VUE.EIPSW, VUE.PSW       );
 | 
				
			||||||
 | 
					            new Register(this, "FEPC" , VUE.FEPC , Register.PLAIN);
 | 
				
			||||||
 | 
					            new Register(this, "FEPSW", VUE.FEPSW, VUE.PSW       );
 | 
				
			||||||
 | 
					            new Register(this, "ECR"  , VUE.ECR  , VUE.ECR       );
 | 
				
			||||||
 | 
					            new Register(this, "ADTRE", VUE.ADTRE, Register.PLAIN);
 | 
				
			||||||
 | 
					            new Register(this, "CHCW" , VUE.CHCW , VUE.CHCW      );
 | 
				
			||||||
 | 
					            new Register(this, "PIR"  , VUE.PIR  , VUE.PIR       );
 | 
				
			||||||
 | 
					            new Register(this, "TKCW" , VUE.TKCW , VUE.TKCW      );
 | 
				
			||||||
 | 
					            new Register(this, "29"   ,        29, Register.PLAIN);
 | 
				
			||||||
 | 
					            new Register(this, "30"   ,        30, Register.PLAIN);
 | 
				
			||||||
 | 
					            new Register(this, "31"   ,        31, Register.PLAIN);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Initialize program registers
 | 
				
			||||||
 | 
					        else for (int x = 0; x < 32; x++) {
 | 
				
			||||||
 | 
					            String name = null;
 | 
				
			||||||
 | 
					            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;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            new Register(this, name, x, Register.PROGRAM);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // List terminator
 | 
				
			||||||
 | 
					        var spacer = new JPanel(null);
 | 
				
			||||||
 | 
					        spacer.setOpaque(false);
 | 
				
			||||||
 | 
					        spacer.setPreferredSize(new Dimension(0, 0));
 | 
				
			||||||
 | 
					        var gbc = new GridBagConstraints();
 | 
				
			||||||
 | 
					        gbc.gridheight = GridBagConstraints.REMAINDER;
 | 
				
			||||||
 | 
					        gbc.gridwidth  = GridBagConstraints.REMAINDER;
 | 
				
			||||||
 | 
					        gbc.weighty    = 1;
 | 
				
			||||||
 | 
					        client.add(spacer, gbc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Configure component
 | 
				
			||||||
 | 
					        shown = false;
 | 
				
			||||||
 | 
					        setViewportView(client);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    //                            Public Methods                             //
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Draw the component
 | 
				
			||||||
 | 
					    public void paintComponent(Graphics g) {
 | 
				
			||||||
 | 
					        if (!shown) {
 | 
				
			||||||
 | 
					            shown = true;
 | 
				
			||||||
 | 
					            revalidate();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        super.paintComponent(g);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Transfer focus to the client area
 | 
				
			||||||
 | 
					    public void requestFocus() {
 | 
				
			||||||
 | 
					        client.requestFocus();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Recalculate layout
 | 
				
			||||||
 | 
					    public void revalidate() {
 | 
				
			||||||
 | 
					        if (client != null)
 | 
				
			||||||
 | 
					            client.revalidate();
 | 
				
			||||||
 | 
					        super.revalidate();
 | 
				
			||||||
 | 
					        repaint();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    //                            Package Methods                            //
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Add a register component to the client area
 | 
				
			||||||
 | 
					    void add(GridBagConstraints gbc, JComponent comp) {
 | 
				
			||||||
 | 
					        client.add(comp, gbc);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Associate a register with its index
 | 
				
			||||||
 | 
					    void add(int index, Register register) {
 | 
				
			||||||
 | 
					        registers.put(index, register);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Apply configuration settings
 | 
				
			||||||
 | 
					    void configure() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Configure registers
 | 
				
			||||||
 | 
					        for (var reg : registers.values())
 | 
				
			||||||
 | 
					            reg.configure();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Configure component
 | 
				
			||||||
 | 
					        getVerticalScrollBar().setUnitIncrement(
 | 
				
			||||||
 | 
					            CPUWindow.regHexFontSize.height);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Update the display
 | 
				
			||||||
 | 
					    void refresh() {
 | 
				
			||||||
 | 
					        for (var reg : registers.values())
 | 
				
			||||||
 | 
					            reg.refresh();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					    //                            Private Methods                            //
 | 
				
			||||||
 | 
					    ///////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Determine the initial height upon first show
 | 
				
			||||||
 | 
					    private int getInitialHeight() {
 | 
				
			||||||
 | 
					        int height = 0;
 | 
				
			||||||
 | 
					        var layout = (GridBagLayout) client.getLayout();
 | 
				
			||||||
 | 
					        int ret    = 0;
 | 
				
			||||||
 | 
					        int row    = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Process controls until the target row is found
 | 
				
			||||||
 | 
					        for (var control : client.getComponents()) {
 | 
				
			||||||
 | 
					            var ctrl = (JComponent) control;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Track the tallest control on the row
 | 
				
			||||||
 | 
					            if (ctrl.isVisible())
 | 
				
			||||||
 | 
					                height = Math.max(height, ctrl.getPreferredSize().height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // This is not the last control on the row
 | 
				
			||||||
 | 
					            if (layout.getConstraints(control).gridwidth !=
 | 
				
			||||||
 | 
					                GridBagConstraints.REMAINDER)
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Advance to the next row
 | 
				
			||||||
 | 
					            ret   += height;
 | 
				
			||||||
 | 
					            height = 0;
 | 
				
			||||||
 | 
					            row++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // The target row has been reached
 | 
				
			||||||
 | 
					            if (row == 4)
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -104,7 +104,6 @@ public class Instruction {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Decode by format
 | 
					        // Decode by format
 | 
				
			||||||
        switch (format) {
 | 
					        switch (format) {
 | 
				
			||||||
            case 0: return; // Illegal opcode
 | 
					 | 
				
			||||||
            case 1:
 | 
					            case 1:
 | 
				
			||||||
                reg2 = bits >> 21 & 31;
 | 
					                reg2 = bits >> 21 & 31;
 | 
				
			||||||
                reg1 = bits >> 16 & 31;
 | 
					                reg1 = bits >> 16 & 31;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,9 @@ package vue;
 | 
				
			||||||
// Java emulation core implementation
 | 
					// Java emulation core implementation
 | 
				
			||||||
class JavaVUE extends VUE {
 | 
					class JavaVUE extends VUE {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Instance fields
 | 
				
			||||||
 | 
					    Instruction inst; // Instruction state
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Components
 | 
					    // Components
 | 
				
			||||||
    Bus bus; // Memory bus
 | 
					    Bus bus; // Memory bus
 | 
				
			||||||
    CPU cpu; // Processor
 | 
					    CPU cpu; // Processor
 | 
				
			||||||
| 
						 | 
					@ -26,6 +29,7 @@ class JavaVUE extends VUE {
 | 
				
			||||||
    JavaVUE() {
 | 
					    JavaVUE() {
 | 
				
			||||||
        bus  = new Bus(this);
 | 
					        bus  = new Bus(this);
 | 
				
			||||||
        cpu  = new CPU(this);
 | 
					        cpu  = new CPU(this);
 | 
				
			||||||
 | 
					        inst = new Instruction();
 | 
				
			||||||
        reset();
 | 
					        reset();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue