From 9f5a5233eac2dc2392c09bbf558706623ebf4d89 Mon Sep 17 00:00:00 2001 From: Guy Perfect Date: Wed, 23 Dec 2020 12:26:02 -0600 Subject: [PATCH] Precursor to VIP introduction --- expressions.html | 61 +++-- locale/en-US.txt | 55 +++-- src/core/cpu.c | 4 +- src/desktop/app/App.java | 42 +++- src/desktop/app/BreakpointsWindow.java | 11 +- src/desktop/app/CPUWindow.java | 124 +--------- src/desktop/app/CharactersWindow.java | 317 +++++++++++++++++++++++++ src/desktop/app/DisassemblerPane.java | 52 ++-- src/desktop/app/MainWindow.java | 117 ++++++++- src/desktop/app/MemoryWindow.java | 57 ++--- src/desktop/app/Register.java | 36 ++- src/desktop/app/RegisterList.java | 6 +- src/desktop/util/Util.java | 12 +- src/desktop/vue/Breakpoint.java | 2 +- src/desktop/vue/CPU.java | 4 +- src/desktop/vue/Instruction.java | 16 +- src/desktop/vue/JavaVue.java | 10 - src/desktop/vue/NativeVue.c | 46 ---- src/desktop/vue/NativeVue.java | 12 - 19 files changed, 636 insertions(+), 348 deletions(-) create mode 100644 src/desktop/app/CharactersWindow.java diff --git a/expressions.html b/expressions.html index a9f4b1f..47e09f5 100644 --- a/expressions.html +++ b/expressions.html @@ -135,7 +135,7 @@ border-width: 0 1px 1px 0; } - .bordered tr > :first-child { + .bordered tr > :first-child, .op1 { padding: 1px 12px 1px 12px; text-align: center; } @@ -245,12 +245,12 @@

Floats, like words, are represented as sequences of character digits. They - are differentiated from words by the presence of a dot . + are distinguished from words by the presence of a dot . character somewhere within the sequence. Only one dot may be present in a float literal, and dots cannot be used in hexadecimal literals. If the given value cannot be represented in the float data type, a parsing error occurs. - Float values in the expression evaluator are subjected to the same - restrictions as on the Virtual Boy's CPU: if the result of any float + Float values in the expression evaluator are subjected to the following + restrictions: if the value of any float literal or the result of any float operation is NaN, an infinity, a denormal number or negative zero, it will be changed to positive zero.

@@ -259,7 +259,7 @@ slightly different. When used in a numeric operation, a boolean will use the value 0 if false or the value 1 if true. Boolean literals are specified with the named values true and - false within the expression. In a boolean operation, any result + false within the expression. In a boolean operation, any value that is zero is considered false, and any non-zero value is considered true.

@@ -298,13 +298,13 @@ disp Displacement offset for jumps and memory accesses. - + format Current instruction's encoding format. @@ -354,7 +354,7 @@ value - Value read by the current memory access. + Value read or to be written by the current memory access. vector @@ -434,15 +434,14 @@

Operators may apply to one (unary) or two (binary) values. All unary operators appear to the left of the value they modify (or another unary - operator). Binary operators appear between the values they modify. Each - operator considers the types of its operands in order to produce a new value - of the appropriate type. + operator). Binary operators appear between the values they modify.

- If the operands of a binary operator have different types, one of the values - will be converted to the other type before performing the operation. The - conversion depends on the "greater" of the two types, in the following order - (higher is "greater"): + Each operator considers the types of its operands in order to produce a new + value of the appropriate type. If the operands of a binary operator have + different types, one of the values will be converted to the other type before + performing the operation. The conversion selects the "greater" of the two + types, in the following order (higher is "greater"):

@@ -452,7 +451,7 @@
Float

For example, if an operation contains both a signed word and a float, the - signed word value is first converted to float. + signed word value is converted to float before performing the operation.

Operators have assigned precedence that specifies the order of operations. @@ -467,12 +466,14 @@

The following operators may be used in expressions. Groups listed higher have higher precedence and happen before groups listed lower. Operators within - groups have the same precedence and are processed in the order they appear in - the expression from left to right. + groups have the same precedence and are processed according to the order in + which they appear in the expression: right-to-left for unary operators, + left-to-right for binary operators.

- + + @@ -562,7 +563,8 @@ - + + @@ -589,17 +591,17 @@ - + - + - + @@ -634,17 +636,17 @@ - + - + - + @@ -691,6 +693,13 @@
~Unary~ Not Bitwise Cannot be used with a float value.
The binary value is not modified.
/Binary/ Divide Zero divisor yields zero as result.
<< Shift LeftCannot be used with a float value.Cannot be used with float values.
>> Shift Right ArithmeticCannot be used with a float value.Cannot be used with float values.
>>> Shift Right LogicalCannot be used with a float value.Cannot be used with float values.
>
& And BitwiseCannot be used with a float value.Cannot be used with float values.
^ Exclusive Or BitwiseCannot be used with a float value.Cannot be used with float values.
| Or BitwiseCannot be used with a float value.Cannot be used with float values.
&&Performs a halfword read of the specified signedness.
+

+ Reads are subjected to the alginment restrictions of the Virtual Boy's CPU: + the lowest bit of the address is ignored for halfword reads, and the lowest + two bits of the address are ignored for word reads. +

+ +

 

diff --git a/locale/en-US.txt b/locale/en-US.txt index b23ec23..dc27c95 100644 --- a/locale/en-US.txt +++ b/locale/en-US.txt @@ -68,11 +68,33 @@ breakpoints { } +# Characters window +characters { + address Address + grid Grid + index Index + mirror Mirror + Palette Palette + scale Scale + title Characters + wide Wide +} + # Console window console { title Console } +# Emulation core +core { + java Java + linux-x86 Linux (32-bit) + linux-x86_64 Linux (64-bit) + native Native + windows-x86 Windows (32-bit) + windows-x86_64 Windows (64-bit) +} + # CPU window cpu { float Float @@ -84,21 +106,6 @@ cpu { unsigned Unsigned } -# Memory window -memory { - title Memory -} - -# Emulation core -core { - java Java - linux-x86 Linux (32-bit) - linux-x86_64 Linux (64-bit) - native Native - windows-x86 Windows (32-bit) - windows-x86_64 Windows (64-bit) -} - # File dialog dialog { ext_isx ISX modules (*.isx) @@ -108,3 +115,21 @@ dialog { load_rom_error Unable to load the selected ROM file. load_rom_notvb The selected file does not appear to be a Virtual Boy ROM. } + +# Memory window +memory { + title Memory +} + +# Palettes +palette { + Generic Generic + gplt0 BG 0 + gplt1 BG 1 + gplt2 BG 2 + gplt3 BG 3 + jplt0 OBJ 0 + jplt1 OBJ 1 + jplt2 OBJ 2 + jplt3 OBJ 3 +} diff --git a/src/core/cpu.c b/src/core/cpu.c index 8601f1c..071a327 100644 --- a/src/core/cpu.c +++ b/src/core/cpu.c @@ -1164,7 +1164,7 @@ static vbool cpuFetch(Vue *vue) { /* First unit */ if (vue->cpu.fetch == 0) { vue->cpu.inst.bits = vue->cpu.access.value << 16; - if (cpuSize(vue->cpu.access.value >> 10 & 0x3F) == 4) { + if (cpuSize(vue->cpu.access.value >> 10) == 4) { vue->cpu.fetch = 1; return VUE_FALSE; } @@ -1172,7 +1172,7 @@ static vbool cpuFetch(Vue *vue) { /* Second unit */ else { - vue->cpu.inst.bits |= vue->cpu.access.value & 0xFFFF; + vue->cpu.inst.bits |= vue->cpu.access.value; vue->cpu.fetch = -1; } diff --git a/src/desktop/app/App.java b/src/desktop/app/App.java index 61f5c4f..a7530db 100644 --- a/src/desktop/app/App.java +++ b/src/desktop/app/App.java @@ -1,7 +1,9 @@ package app; // Java imports +import java.awt.*; import java.util.*; +import javax.swing.*; // Project imports import util.*; @@ -16,7 +18,28 @@ public class App { private ArrayList windows; // Application windows // Configuration fields - Localizer localizer; // UI localization manager + Util.Font fntDialog; // Dialog font + Util.Font fntMono; // Monospaced font + int hexDigitWidth; // Width in pixels of one hex digit + Localizer localizer; // UI localization manager + int[][] rgbBase; // Base anaglyph filter colors + + + + /////////////////////////////////////////////////////////////////////////// + // Constants // + /////////////////////////////////////////////////////////////////////////// + + // Anaglyph presets + static final int[] RED = { 0xFF, 0x00, 0x00 }; + static final int[] CYAN = { 0x00, 0xC6, 0xF0 }; + static final int[] GREEN = { 0x00, 0xB4, 0x00 }; + static final int[] MAGENTA = { 0xC8, 0x00, 0xFF }; + + // Eyes + static final int LEFT = 0; + static final int RIGHT = 1; + static final int CHR = 2; @@ -27,10 +50,17 @@ public class App { // Default constructor public App(boolean useNative) { - // Instance fields + // Configure instance fields localizer = new Localizer(); windows = new ArrayList(); + // Configure config fields + fntDialog = new Util.Font(new JLabel().getFont()); + fntMono = new Util.Font(new Font(Util.fontFamily(new String[] + { "Consolas", Font.MONOSPACED } ), Font.PLAIN, 14)); + hexDigitWidth = hexDigitWidth(); + rgbBase = new int[][] { GREEN, MAGENTA, RED }; + // Additional processing setUseNative(useNative); initLocales(); @@ -83,6 +113,14 @@ public class App { // Private Methods // /////////////////////////////////////////////////////////////////////////// + // Calculate the maximum hexadecimal digit width + private int hexDigitWidth() { + int width = 0; + for (var digit : "0123456789ABCDEFabcdef".toCharArray()) + width = Math.max(width, fntMono.metrics.charWidth(digit)); + return width; + } + // Load and parse all locale translations private void initLocales() { diff --git a/src/desktop/app/BreakpointsWindow.java b/src/desktop/app/BreakpointsWindow.java index 92abfe7..9aa4953 100644 --- a/src/desktop/app/BreakpointsWindow.java +++ b/src/desktop/app/BreakpointsWindow.java @@ -14,7 +14,6 @@ import vue.*; class BreakpointsWindow extends ChildWindow { // Private fields - private Font font; // Display font private ArrayList items; // List items private int selectedIndex; // Selected list item @@ -133,7 +132,7 @@ class BreakpointsWindow extends ChildWindow { else if (breakpoint.any() && breakpoint.evaluate(inst, acc)) lblStatus.setText("\u2605"); // Star else lblStatus.setText(" "); - int lineHeight = lblStatus.getPreferredSize().height; + int lineHeight = parent.app.fntDialog.metrics.getHeight(); lblStatus.setPreferredSize(new Dimension(lineHeight, lineHeight)); } @@ -158,8 +157,6 @@ class BreakpointsWindow extends ChildWindow { super(parent, "breakpoints.title"); // Configure instance fields - font = new Font(Util.fontFamily(new String[] - { "Consolas", Font.MONOSPACED } ), Font.PLAIN, 14); items = new ArrayList(); selectedIndex = -1; @@ -183,7 +180,7 @@ class BreakpointsWindow extends ChildWindow { lstBreakpoints.addMouseListener(Util.onMouse(e->onMouseDown(e), null)); var scr = new JScrollPane(lstBreakpoints); client.add(scr, BorderLayout.CENTER); - spacer = new JPanel(null); + spacer = new JPanel(); spacer.setOpaque(false); lstBreakpoints.add(spacer, SPACER); @@ -223,7 +220,7 @@ class BreakpointsWindow extends ChildWindow { gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridwidth = GridBagConstraints.REMAINDER; props.add(buttons, gbc); - var fill = new JPanel(null); + var fill = new JPanel(); fill.setOpaque(false); fill.addMouseListener(Util.onMouse(e->onDebug(e), null)); gbc = new GridBagConstraints(); @@ -602,7 +599,7 @@ class BreakpointsWindow extends ChildWindow { var txt = new JTextField(); txt.setEnabled(false); if (mono) - txt.setFont(font); + txt.setFont(parent.app.fntMono); txt.addActionListener(e->client.requestFocus()); txt.addFocusListener (Util.onFocus(null, e->handler.run())); var gbc = new GridBagConstraints(); diff --git a/src/desktop/app/CPUWindow.java b/src/desktop/app/CPUWindow.java index 698ad5a..c93cd1e 100644 --- a/src/desktop/app/CPUWindow.java +++ b/src/desktop/app/CPUWindow.java @@ -13,7 +13,7 @@ import vue.*; // CPU window class CPUWindow extends ChildWindow { - // Package fields + // Instance fields MainWindow parent; // Containing window // UI components @@ -23,70 +23,6 @@ class CPUWindow extends ChildWindow { - /////////////////////////////////////////////////////////////////////////// - // Global Settings // - /////////////////////////////////////////////////////////////////////////// - - static Font dasmFont; // Disassembler font - static int dasmFontHeight; // Disassembler font line height - static int regExpandWidth; // Width of register list expand button - static Font regHexFont; // Register list hex font - static Dimension regHexFontSize; // Max dimensions - static HashSet instances; // Spawned instances - - // Static initializer - static { - setDefaults(); - instances = new HashSet(); - } - - - - /////////////////////////////////////////////////////////////////////////// - // 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) + 4; - - // Disassembler font - setDasmFont(new Font(Util.fontFamily(new String[] - { "Consolas", Font.MONOSPACED } ), Font.PLAIN, 14)); - } - - // Specify a font to use as the disassembler font - static void setDasmFont(Font font) { - dasmFont = font; - var label = new JLabel("!"); - label.setFont(font); - dasmFontHeight = label.getPreferredSize().height; - } - - // Specify a font to use as the register list hex font - static void setRegHexFont(Font font) { - regHexFont = font; - regHexFontSize = measureHex(font); - } - - - /////////////////////////////////////////////////////////////////////////// // Constructors // /////////////////////////////////////////////////////////////////////////// @@ -94,7 +30,6 @@ class CPUWindow extends ChildWindow { // Default constructor CPUWindow(MainWindow parent) { super(parent, "cpu.title"); - instances.add(this); // Configure instance fields this.parent = parent; @@ -117,34 +52,15 @@ class CPUWindow extends ChildWindow { var client = getContentPane(); 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() { - panDasm .configure(); - lstProgram.configure(); - lstSystem .configure(); - } - // Update the display void refresh(boolean seekToPC) { panDasm .refresh(seekToPC); @@ -152,42 +68,4 @@ class CPUWindow extends ChildWindow { lstProgram.refresh(); } - - - /////////////////////////////////////////////////////////////////////////// - // Event Handlers // - /////////////////////////////////////////////////////////////////////////// - - // Client resize - private void onResize() { - //refreshDasm(); - } - - - - /////////////////////////////////////////////////////////////////////////// - // Private Methods // - /////////////////////////////////////////////////////////////////////////// - - // Determine the maximum 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); - } - - - } diff --git a/src/desktop/app/CharactersWindow.java b/src/desktop/app/CharactersWindow.java new file mode 100644 index 0000000..bf3b823 --- /dev/null +++ b/src/desktop/app/CharactersWindow.java @@ -0,0 +1,317 @@ +package app; + +// Java imports +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import javax.swing.*; + +// Project imports +import util.*; + +// VIP characters window +class CharactersWindow extends ChildWindow { + + // Instance fields + private int color; // Selected color index + + // UI components + private JPanel client; // Client area + private JPanel panCharacters; // Characters panel + private JPanel panPalette; // Palette panel + private JPanel panPattern; // Pattern panel + private JScrollPane scrControls; // Controls panel + + + + /////////////////////////////////////////////////////////////////////////// + // Constructors // + /////////////////////////////////////////////////////////////////////////// + + // Default constructor + CharactersWindow(MainWindow parent) { + super(parent, "characters.title"); + + // Configure instance fields + color = 0; + + // Configure client area + client = new JPanel(new BorderLayout()); + client.setBackground(SystemColor.control); + client.setFocusable(true); + client.setPreferredSize(new Dimension(480, 360)); + client.addComponentListener(Util.onResize(e->onResize())); + + // Configure controls panel + var ctrls = new JPanel(new GridBagLayout()); + ctrls.setBackground(SystemColor.control); + ctrls.addMouseListener( + Util.onMouse(e->client.requestFocus(), null)); + scrControls = new JScrollPane(ctrls, + JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, + JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrControls.setBorder(null); + scrControls.getVerticalScrollBar().setUnitIncrement(20); + client.add(scrControls, BorderLayout.WEST); + + label(ctrls, "characters.index", true); + spinner(ctrls, 0, 2047, 0, true); + label(ctrls, "characters.address", false); + textBox(ctrls); + label(ctrls, "characters.mirror", false); + textBox(ctrls); + + // Pattern panel + var panPattern = new JPanel(); + panPattern.setBackground(Color.black); + panPattern.setPreferredSize(new Dimension(96, 96)); + var gbc = new GridBagConstraints(); + gbc.anchor = GridBagConstraints.CENTER; + gbc.gridwidth = GridBagConstraints.REMAINDER; + gbc.insets = new Insets(4, 2, 2, 2); + ctrls.add(panPattern, gbc); + + // Palette panel + panPalette = new JPanel() { + public void paintComponent(Graphics g) { + super.paintComponent(g); + onPaintPalette((Graphics2D) g, getWidth(), getHeight()); + } + }; + panPalette.setOpaque(false); + panPalette.setPreferredSize(new Dimension(0, 20 + 6)); + panPalette.addMouseListener( + Util.onMouse(e->onMouseDownPalette(e), null)); + gbc = new GridBagConstraints(); + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.gridwidth = GridBagConstraints.REMAINDER; + gbc.insets = new Insets(0, 2, 4, 2); + ctrls.add(panPalette, gbc); + + // Fill the extra space above the view controls + var spacer = new JPanel(); + spacer.setOpaque(false); + gbc = new GridBagConstraints(); + gbc.gridwidth = GridBagConstraints.REMAINDER; + gbc.weighty = 1; + ctrls.add(spacer, gbc); + + label(ctrls, "characters.grid", false); + checkBox(ctrls).setSelected(true); + label(ctrls, "characters.wide", false); + spinner(ctrls, 0, 2048, 0, false); + label(ctrls, "characters.palette", false); + select(ctrls, new String[] { "palette.generic", + "palette.gplt0", "palette.gplt1", "palette.gplt2", "palette.gplt3", + "palette.jplt0", "palette.jplt1", "palette.jplt2", "palette.jplt3" + }); + label(ctrls, "characters.scale", false); + slider(ctrls, 1, 10, 1); + + // Terminate the list of controls + spacer = new JPanel(); + spacer.setOpaque(false); + spacer.setPreferredSize(new Dimension(0, 0)); + gbc = new GridBagConstraints(); + gbc.gridheight = GridBagConstraints.REMAINDER; + gbc.gridwidth = GridBagConstraints.REMAINDER; + ctrls.add(spacer, gbc); + + // Configure characters panel + panCharacters = new JPanel() { + public void paintComponent(Graphics g) { + super.paintComponent(g); + onPaintCharacters((Graphics2D) g, getWidth(), getHeight()); + } + }; + panCharacters.setBackground(SystemColor.control); + panCharacters.addMouseListener( + Util.onMouse(e->client.requestFocus(), null)); + var scr = new JScrollPane(panCharacters); + client.add(scr, BorderLayout.CENTER); + + // Configure component + setContentPane(client); + pack(); + } + + + + /////////////////////////////////////////////////////////////////////////// + // Package Methods // + /////////////////////////////////////////////////////////////////////////// + + // Update the display + void refresh() { + repaint(); + } + + + + /////////////////////////////////////////////////////////////////////////// + // Event Handlers // + /////////////////////////////////////////////////////////////////////////// + + // Palette mouse button press + private void onMouseDownPalette(MouseEvent e) { + + // Common processing + client.requestFocus(); + + // Only consider left clicks + if (e.getButton() != MouseEvent.BUTTON1) + return; + + // Working variables + int height = panPalette.getHeight(); + int width = panPalette.getWidth(); + int size = Math.max(1, Math.min((width - 18) / 4, height - 6)); + int left = (width - size * 4 - 18) / 2; + int top = (height - size - 6) / 2; + int x = e.getX() - left - 3; + int y = e.getY() - top - 3; + + // The click was not on top of a color + if ( + x < 0 || x >= (size + 4) * 4 || + x % (size + 4) >= size || + y < 0 || y >= size + ) return; + + // Select the clicked color + color = x / (size + 4); + panPalette.repaint(); + } + + // Characters paint + private void onPaintCharacters(Graphics2D g, int width, int height) { + g.setColor(new Color(0x001830)); + g.fillRect(0, 0, 256, 512); + } + + // Palette paint + private void onPaintPalette(Graphics2D g, int width, int height) { + int size = Math.max(1, Math.min((width - 18) / 4, height - 6)); + int left = (width - size * 4 - 18) / 2; + int top = (height - size - 6) / 2; + + // Draw the color picker + for (int x = 0; x < 4; x++, left += size + 4) { + + // The current color is selected + if (x == color) { + g.setColor(SystemColor.textHighlight); + g.fillRect(left , top , size + 6, size + 6); + g.setColor(SystemColor.control); + g.fillRect(left + 2, top + 2, size + 2, size + 2); + } + + // Draw the color area + g.setColor(Color.black); + g.fillRect(left + 3, top + 3, size , size ); + } + + } + + // Window resize + private void onResize() { + var viewport = scrControls.getViewport(); + int inner = viewport.getView().getPreferredSize().width; + int outer = viewport.getExtentSize().width; + + // The controls container does not need to be resized + if (inner == outer) + return; + + // Size the controls container to match the inner component + scrControls.setPreferredSize(new Dimension( + scrControls.getPreferredSize().width + inner - outer, 0)); + scrControls.revalidate(); + scrControls.repaint(); + } + + + + /////////////////////////////////////////////////////////////////////////// + // Private Methods // + /////////////////////////////////////////////////////////////////////////// + + // Add a check box to the controls panel + private JCheckBox checkBox(JPanel panel) { + var chk = new JCheckBox(); + chk.setBorder(null); + chk.setFocusable(false); + var gbc = new GridBagConstraints(); + gbc.anchor = GridBagConstraints.WEST; + gbc.gridwidth = GridBagConstraints.REMAINDER; + gbc.insets = new Insets(0, 0, 2, 2); + panel.add(chk, gbc); + return chk; + } + + // Add a label to the controls panel + private void label(JPanel panel, String key, boolean top) { + var lbl = new JLabel(); + parent.app.localizer.add(lbl, key); + var gbc = new GridBagConstraints(); + gbc.anchor = GridBagConstraints.WEST; + gbc.insets = new Insets(top ? 2 : 0, 2, 2, 2); + panel.add(lbl, gbc); + } + + // Add a combo box to the controls panel + private JComboBox select(JPanel panel, String[] options) { + var cmb = new JComboBox(); + parent.app.localizer.add(cmb, options); + cmb.setSelectedIndex(0); + var gbc = new GridBagConstraints(); + gbc.fill = GridBagConstraints.BOTH; + gbc.gridwidth = GridBagConstraints.REMAINDER; + gbc.insets = new Insets(0, 0, 1, 2); + panel.add(cmb, gbc); + return cmb; + } + + // Add a slider to the controls panel + private JSlider slider(JPanel panel, int min, int max, int value) { + var sld = new JSlider(min, max, value); + sld.setFocusable(false); + sld.setPreferredSize(new Dimension(0, sld.getPreferredSize().height)); + var gbc = new GridBagConstraints(); + gbc.fill = GridBagConstraints.BOTH; + gbc.gridwidth = GridBagConstraints.REMAINDER; + gbc.insets = new Insets(0, 0, 1, 2); + panel.add(sld, gbc); + return sld; + } + + // Add a spinner to the controls panel + private JSpinner spinner(JPanel panel, int min, int max, int value, + boolean top) { + var spn = new JSpinner(new SpinnerNumberModel(value, min, max, 1)); + spn.setEditor(new JSpinner.NumberEditor(spn, "#")); + var gbc = new GridBagConstraints(); + gbc.fill = GridBagConstraints.BOTH; + gbc.gridwidth = GridBagConstraints.REMAINDER; + gbc.insets = new Insets(top ? 2 : 0, 0, 2, 2); + gbc.weightx = 1; + panel.add(spn, gbc); + return spn; + } + + // Add a text box to the controls panel + private JTextField textBox(JPanel panel) { + var txt = new JTextField(); + txt.setFont(parent.app.fntMono); + var size = txt.getPreferredSize(); + txt.setPreferredSize(new Dimension( + parent.app.hexDigitWidth * 8 + 2 + size.width, size.height)); + var gbc = new GridBagConstraints(); + gbc.fill = GridBagConstraints.BOTH; + gbc.gridwidth = GridBagConstraints.REMAINDER; + gbc.insets = new Insets(0, 0, 2, 2); + panel.add(txt, gbc); + return txt; + } + +} diff --git a/src/desktop/app/DisassemblerPane.java b/src/desktop/app/DisassemblerPane.java index 7757606..1700f59 100644 --- a/src/desktop/app/DisassemblerPane.java +++ b/src/desktop/app/DisassemblerPane.java @@ -21,8 +21,8 @@ class DisassemblerPane extends JScrollPane { private int[] widths; // Column widths // UI components - private JPanel client; // Client area - private ArrayList rows; // Disassembler output + private JPanel client; // Client area + private ArrayList rows; // Disassembler output @@ -53,23 +53,22 @@ class DisassemblerPane extends JScrollPane { widths = new int[5]; // Configure client area - client = new JPanel(null) { + client = new JPanel() { public void paintComponent(Graphics g) { super.paintComponent(g); onPaint((Graphics2D) g, getWidth(), getHeight()); } }; + client.setBackground(SystemColor.window); + client.setFocusable(true); client.addFocusListener( Util.onFocus(e->client.repaint(), e->client.repaint())); client.addKeyListener(Util.onKey(e->onKeyDown(e), null)); client.addMouseListener(Util.onMouse(e->client.requestFocus(), null)); client.addMouseWheelListener(e->onMouseWheel(e)); - client.setBackground(SystemColor.window); - client.setFocusable(true); // Configure component setViewportView(client); - configure(); } @@ -78,17 +77,14 @@ class DisassemblerPane extends JScrollPane { // Package Methods // /////////////////////////////////////////////////////////////////////////// - // Apply configuration settings - void configure() { - client.repaint(); - } - // Update the display void refresh(boolean seekToPC) { + if (seekToPC) { + int pc = parent.parent.vue.getRegister(Vue.PC, true); + if (!isVisible(pc)) + seek(pc, tall(false) / 3); + } client.repaint(); - int pc = parent.parent.vue.getRegister(Vue.PC, true); - if (!isVisible(pc)) - seek(pc, tall(false) / 3); } @@ -176,10 +172,11 @@ class DisassemblerPane extends JScrollPane { } // Configure working variables - int address = this.address; - int count = tall(true); - var data = new byte[count * 4]; - int offset = 0; + int address = this.address; + int count = tall(true); + var data = new byte[count * 4]; + int lineHeight = parent.parent.app.fntMono.metrics.getHeight(); + int offset = 0; // Disassemble from the current address vue.readBytes(address, data, 0, data.length); @@ -202,8 +199,8 @@ class DisassemblerPane extends JScrollPane { } g.setColor(bg); g.fillRect( - 0, y * CPUWindow.dasmFontHeight, - width, CPUWindow.dasmFontHeight + 0, y * lineHeight, + width, lineHeight ); } @@ -220,7 +217,7 @@ class DisassemblerPane extends JScrollPane { // Configure all rows for (int y = 0; y < rows.size(); y++) { var row = rows.get(y); - int top = y * CPUWindow.dasmFontHeight; + int top = y * lineHeight; // Configure all labels for (int z = 0, x = 0; z < 5; z++) { @@ -235,17 +232,17 @@ class DisassemblerPane extends JScrollPane { // Configure the label label.setLocation(x, top); label.setSize(label.getPreferredSize()); - x += widths[z] + CPUWindow.dasmFontHeight; + x += widths[z] + lineHeight; } } // Update the client's size var size = client.getPreferredSize(); - width = -CPUWindow.dasmFontHeight + 1; + width = -lineHeight + 1; for (int x = 0; x < 5; x++) if (widths[x] != 0 && (x != 2 || showBytes)) - width += CPUWindow.dasmFontHeight + widths[x]; + width += lineHeight + widths[x]; if (width == size.width) return; client.setPreferredSize(new Dimension(width, 0)); @@ -268,7 +265,7 @@ class DisassemblerPane extends JScrollPane { for (int x = 0; x < 5; x++) { var label = row.labels[x] = new JLabel(); if (x != 4) - label.setFont(CPUWindow.dasmFont); + label.setFont(parent.parent.app.fntMono); client.add(label); } @@ -380,9 +377,10 @@ class DisassemblerPane extends JScrollPane { // Determine how many rows of output are visible private int tall(boolean partial) { + int lineHeight = parent.parent.app.fntMono.metrics.getHeight(); return Math.max(1, (client.getHeight() + - (partial ? CPUWindow.dasmFontHeight - 1 : 0) - ) / CPUWindow.dasmFontHeight); + (partial ? lineHeight - 1 : 0) + ) / lineHeight); } // Update a row with its text and measure the column widths diff --git a/src/desktop/app/MainWindow.java b/src/desktop/app/MainWindow.java index dd133b8..c2bb0f7 100644 --- a/src/desktop/app/MainWindow.java +++ b/src/desktop/app/MainWindow.java @@ -15,9 +15,11 @@ import vue.*; class MainWindow extends JFrame { // Instance fields - App app; // Containing application - Breakpoint brkStep; // Single step internal breakpoint - Vue vue; // Emulation core context + App app; // Containing application + Breakpoint brkStep; // Single step internal breakpoint + int[][][] palettes; // Raster palettes + byte[] vram; // Snapshot of VIP memory + Vue vue; // Emulation core context // Private fields private boolean debugMode; // Window is in debug mode @@ -28,23 +30,40 @@ class MainWindow extends JFrame { private File romFile; // Currently loaded ROM file // UI components - private BreakpointsWindow breakpoints; // Breakpoints window - private JPanel client; // Common client container - private ConsoleWindow console; // Console window - private CPUWindow cpu; // CPU window - private JDesktopPane desktop; // Container for child windows - private MemoryWindow memory; // Memory window - private JMenu mnuDebug; // Debug menu - private JPanel video; // Video output + private JPanel client; // Common client container + private JDesktopPane desktop; // Container for child windows + private JMenu mnuDebug; // Debug menu + private JPanel video; // Video output private JMenuItem mnuFileDebugMode; // File -> Debug mode private JMenuItem mnuFileGameMode; // File -> Game mode + // Child windows + private BreakpointsWindow breakpoints; + private CharactersWindow characters; + private ConsoleWindow console; + private CPUWindow cpu; + private MemoryWindow memory; + /////////////////////////////////////////////////////////////////////////// // Constants // /////////////////////////////////////////////////////////////////////////// + // Palette indexes + static final int GENERIC = 0; + static final int GPLT0 = 1; + static final int GPLT1 = 2; + static final int GPLT2 = 3; + static final int GPLT3 = 4; + static final int JPLT0 = 5; + static final int JPLT1 = 6; + static final int JPLT2 = 7; + static final int JPLT3 = 8; + static final int LEFT = 0; + static final int RIGHT = 1; + static final int RED = 2; + // Application icon private static final BufferedImage APPICON; @@ -55,6 +74,17 @@ class MainWindow extends JFrame { + /////////////////////////////////////////////////////////////////////////// + // Static Methods // + /////////////////////////////////////////////////////////////////////////// + + // Calculate the address of a character by index + static int chrAddress(int index) { + return index >> 9 << 15 | (index & 511) << 4; + } + + + /////////////////////////////////////////////////////////////////////////// // Constructors // /////////////////////////////////////////////////////////////////////////// @@ -65,13 +95,16 @@ class MainWindow extends JFrame { // Configure instance fields this.app = app; + palettes = new int[9][3][4]; pwd = Util.PWD; + vram = new byte[0x40000]; vue = Vue.create(app.getUseNative()); System.out.println("Native: " + (vue.isNative() ? Vue.getNativeID() : "No")); +//vue.write(0x00078000, Vue.S32, -1); // Configure video pane - video = new JPanel(null) { + video = new JPanel() { public void paintComponent(Graphics g) { super.paintComponent(g); onPaintVideo((Graphics2D) g, getWidth(), getHeight()); @@ -96,6 +129,7 @@ class MainWindow extends JFrame { desktop = new JDesktopPane(); desktop.setBackground(SystemColor.controlShadow); desktop.add(breakpoints = new BreakpointsWindow(this)); + desktop.add(characters = new CharactersWindow (this)); desktop.add(console = new ConsoleWindow (this)); desktop.add(cpu = new CPUWindow (this)); desktop.add(memory = new MemoryWindow (this)); @@ -160,8 +194,8 @@ class MainWindow extends JFrame { mnuDebug.add(mnuDebugBackgrounds); var mnuDebugCharacters = new JMenuItem(); - mnuDebugCharacters.setEnabled(false); loc.add(mnuDebugCharacters, "app.debug.characters"); + mnuDebugCharacters.addActionListener(e->characters.setVisible(true)); mnuDebug.add(mnuDebugCharacters); var mnuDebugFrameBuffers = new JMenuItem(); @@ -226,7 +260,12 @@ class MainWindow extends JFrame { // Refresh all debug views void refreshDebug(boolean seekToPC) { + + vue.readBytes(0x00000000, vram, 0, vram.length); + refreshPalettes(); + breakpoints.refresh(); + characters .refresh(); cpu .refresh(seekToPC); memory .refresh(); } @@ -364,6 +403,58 @@ class MainWindow extends JFrame { // Private Methods // /////////////////////////////////////////////////////////////////////////// + // Update the palette composites + private void refreshPalettes() { + + // Process brightness levels + int[] brt = { 0, + vue.read(0x0005F824, Vue.U8), + vue.read(0x0005F826, Vue.U8), + vue.read(0x0005F828, Vue.U8) + }; + brt[3] += brt[0] + brt[1]; + for (int x = 1; x < 4; x++) + brt[x] = (Math.min(127, brt[x]) * 510 + 127) / 254 << 1; + + // Process all palettes + var pal = new int[4]; + for (int x = 0; x < 9; x++) { + + // Generic palette + if (x == GENERIC) { + pal[1] = 0x55 << 1; + pal[2] = 0xAA << 1; + pal[3] = 0xFF << 1; + } + + // Palette from emulation state + else { + int bits = vue.read(0x0005F860 + (x - 1 << 1), Vue.U8); + pal[1] = brt[bits >> 2 & 3]; + pal[2] = brt[bits >> 4 & 3]; + pal[3] = brt[bits >> 6 ]; + } + + // Process colors + for (int y = 0; y < 3; y++) { + var base = app.rgbBase[y]; + var dest = palettes[x][y]; + for (int z = 1; z < 4; z++) { + dest[z] = 0xFF000000; + for (int w = 0, bits = 16; w < 3; w++, bits -= 8) + dest[z] |= (pal[z] * base[w] + 255) / 510 << bits; + } + } + + } + + } + + // Separate the RGB components of a color + private static int[] split(int rgb) { + return new int[] { rgb >> 16 & 0xFF, rgb >> 8 & 0xFF, rgb & 0xFF }; + } + // Update the window title private void updateTitle() { app.localizer.add(this, diff --git a/src/desktop/app/MemoryWindow.java b/src/desktop/app/MemoryWindow.java index 8f52a63..c8bf413 100644 --- a/src/desktop/app/MemoryWindow.java +++ b/src/desktop/app/MemoryWindow.java @@ -13,10 +13,7 @@ import util.*; class MemoryWindow extends ChildWindow { // Private fields - private int address; // Address of top row - private Font font; // Display font - private int fontHeight; // Font line height - private int fontWidth; // Font maximum character width + private int address; // Address of top row // UI components private JPanel client; // Client area @@ -46,8 +43,6 @@ class MemoryWindow extends ChildWindow { // Configure instance fields address = 0x00000000; - font = new Font(Util.fontFamily(new String[] - { "Consolas", Font.MONOSPACED } ), Font.PLAIN, 14); rows = new ArrayList(); // Configure client area @@ -64,7 +59,6 @@ class MemoryWindow extends ChildWindow { content.setBorder(new JScrollPane().getBorder()); content.add(client, BorderLayout.CENTER); setContentPane(content); - setFont2(font); pack(); } @@ -82,9 +76,10 @@ class MemoryWindow extends ChildWindow { return; // Configure working variables - int height = client.getHeight(); - int count = (height + fontHeight - 1) / fontHeight; - var data = new byte[count * 16]; + int height = client.getHeight(); + int lineHeight = parent.app.fntMono.metrics.getHeight(); + int count = (height + lineHeight - 1) / lineHeight; + var data = new byte[count * 16]; // Retrieve all visible bytes from the emulation context parent.vue.readBytes(address, data, 0, data.length); @@ -95,7 +90,7 @@ class MemoryWindow extends ChildWindow { if (x < rows.size()) row = rows.get(x); // Retrieve row from collection else row = createRow(); // Produce a new row - update(row, x * fontHeight, address + x * 16, data, x * 16); + update(row, x * lineHeight, address + x * 16, data, x * 16); setVisible(row, true); } @@ -108,30 +103,6 @@ class MemoryWindow extends ChildWindow { client.repaint(); } - // 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 rows - for (var row : rows) { - row.address.setFont(font); - for (var label : row.bytes) - label.setFont(font); - } - - onResize(); - } - /////////////////////////////////////////////////////////////////////////// @@ -202,7 +173,8 @@ class MemoryWindow extends ChildWindow { // Add a new row of output private Row createRow() { - var row = new Row(); + var font = parent.app.fntMono; + var row = new Row(); // Address label row.address = new JLabel(); @@ -250,22 +222,25 @@ class MemoryWindow extends ChildWindow { // Determine how many rows of output are visible private int tall(boolean partial) { - return (client.getHeight() + (partial?fontHeight-1:0)) / fontHeight; + int lineHeight = parent.app.fntMono.metrics.getHeight(); + return (client.getHeight() + (partial?lineHeight-1:0)) / lineHeight; } // Update the text of a row private void update(Row row, int y, int address, byte[] data, int offset) { + int hexDigitWidth = parent.app.hexDigitWidth; + int lineHeight = parent.app.fntMono.metrics.getHeight(); // Update address - row.address.setBounds(0, y, 8 * fontWidth, fontHeight); + row.address.setBounds(0, y, 8 * hexDigitWidth, lineHeight); row.address.setText(String.format("%08X", address)); // Update bytes - for (int z = 0, x = 10 * fontWidth; z < 16; z++) { + for (int z = 0, x = 10 * hexDigitWidth; z < 16; z++) { var label = row.bytes[z]; - label.setBounds(x, y, 2 * fontWidth, fontHeight); + label.setBounds(x, y, 2 * hexDigitWidth, lineHeight); label.setText(String.format("%02X", data[offset++] & 0xFF)); - x += fontWidth * (z == 7 ? 4 : 3); + x += hexDigitWidth * (z == 7 ? 4 : 3); } } diff --git a/src/desktop/app/Register.java b/src/desktop/app/Register.java index 3d7f3c8..092e390 100644 --- a/src/desktop/app/Register.java +++ b/src/desktop/app/Register.java @@ -47,6 +47,10 @@ class Register { static final int PLAIN = -2; static final int PROGRAM = -3; + // Expand button labels + static final String COLLAPSE = "-"; + static final String EXPAND = "+"; + /////////////////////////////////////////////////////////////////////////// @@ -71,7 +75,7 @@ class Register { if (e.getButton() == 1) setExpanded(!expanded); }, null); // Expand button - btnExpand = new JLabel(expandable ? "+" : " "); + btnExpand = new JLabel(expandable ? EXPAND : ""); btnExpand.setHorizontalAlignment(SwingConstants.CENTER); if (expandable) btnExpand.addMouseListener(expand); @@ -124,12 +128,12 @@ class Register { case Vue.PIR : initPIR (); break; case Vue.PSW : initPSW (); break; case Vue.TKCW: initTKCW (); break; - default: return; + default: configure(); return; } // Expansion indentation if (index != Vue.PC) { - indent = new JPanel(null); + indent = new JPanel(); indent.setOpaque(false); indent.setPreferredSize(new Dimension(0, 0)); indent.setVisible(false); @@ -152,6 +156,9 @@ class Register { // Handling for PSW if (index == Vue.PSW && type == Vue.PSW) setExpanded(true); + + // Apply application settings + configure(); } @@ -191,7 +198,7 @@ class Register { for (int x = 0; x < 2; x++) { // Indentation - indent = new JPanel(null); + indent = new JPanel(); indent.setOpaque(false); indent.setPreferredSize(new Dimension(0, 0)); var gbc = new GridBagConstraints(); @@ -295,26 +302,29 @@ class Register { lblName.setText(name); // Expand button - var size = btnExpand.getPreferredSize(); - size.width = CPUWindow.regExpandWidth; + var size = btnExpand.getPreferredSize(); + var metrics = parent.parent.parent.app.fntDialog.metrics; + size.width = 4 + Math.max( + metrics.stringWidth(EXPAND), metrics.stringWidth(COLLAPSE)); btnExpand.setPreferredSize(size); // Value text box - var fontSize = CPUWindow.regHexFontSize; - size = new Dimension(8 * fontSize.width + 4, fontSize.height); - txtValue.setFont(CPUWindow.regHexFont); - txtValue.setPreferredSize(size); + var fntMono = parent.parent.parent.app.fntMono; + int hexDigitWidth = parent.parent.parent.app.hexDigitWidth; + txtValue.setFont(fntMono); + txtValue.setPreferredSize(new Dimension( + hexDigitWidth * 8 + 4, fntMono.metrics.getHeight())); // Expansion controls for (var ctrl : controls) { if (!(ctrl instanceof JTextField)) continue; if (type == Vue.PC || (Boolean) ctrl.getClientProperty("hex")) - ((JTextField) ctrl).setFont(CPUWindow.regHexFont); + ((JTextField) ctrl).setFont(fntMono); int digits = type == Vue.PC ? 8 : (Integer) ctrl.getClientProperty("digits"); size = ctrl.getPreferredSize(); - size.width = digits * fontSize.width + 4; + size.width = digits * hexDigitWidth + 4; ctrl.setPreferredSize(size); } } @@ -397,7 +407,7 @@ class Register { // Change the display mode of a program register void setMode(int mode) { this.mode = mode; - txtValue.setFont(mode == HEX ? CPUWindow.regHexFont : null); + txtValue.setFont(mode!=HEX ? null : parent.parent.parent.app.fntMono); refresh(); } diff --git a/src/desktop/app/RegisterList.java b/src/desktop/app/RegisterList.java index 27a77a0..6d71e6a 100644 --- a/src/desktop/app/RegisterList.java +++ b/src/desktop/app/RegisterList.java @@ -85,7 +85,7 @@ class RegisterList extends JScrollPane { } // List terminator - var spacer = new JPanel(null); + var spacer = new JPanel(); spacer.setOpaque(false); spacer.setPreferredSize(new Dimension(0, 0)); var gbc = new GridBagConstraints(); @@ -144,7 +144,7 @@ class RegisterList extends JScrollPane { } // Apply configuration settings - void configure() { + void configure2() { // Configure registers for (var reg : registers.values()) @@ -152,7 +152,7 @@ class RegisterList extends JScrollPane { // Configure component getVerticalScrollBar().setUnitIncrement( - CPUWindow.regHexFontSize.height); + parent.parent.app.fntMono.metrics.getHeight()); } // Update the display diff --git a/src/desktop/util/Util.java b/src/desktop/util/Util.java index cbf5aad..d8a5143 100644 --- a/src/desktop/util/Util.java +++ b/src/desktop/util/Util.java @@ -24,7 +24,7 @@ public final class Util { /////////////////////////////////////////////////////////////////////////// - // Types // + // Classes // /////////////////////////////////////////////////////////////////////////// // Event listener interfaces @@ -43,6 +43,16 @@ public final class Util { BOM(byte[] m, Charset s) { mark = m; set = s; } } + // Font metrics wrapper + public static class Font extends java.awt.Font { + public final FontMetrics metrics; + public Font(java.awt.Font font) { + super(font); + metrics = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB) + .getGraphics().getFontMetrics(this); + } + } + /////////////////////////////////////////////////////////////////////////// diff --git a/src/desktop/vue/Breakpoint.java b/src/desktop/vue/Breakpoint.java index fc7b700..59dca91 100644 --- a/src/desktop/vue/Breakpoint.java +++ b/src/desktop/vue/Breakpoint.java @@ -1537,7 +1537,7 @@ public class Breakpoint { case CODE : sym = vue.getExceptionCode(); break; case COND : sym = inst.cond ; break; case DISP : sym = inst.disp ; break; - case FETCH : sym = vue.getFetch (); break; + case FETCH : sym = acc.fetch ; break; case FORMAT : sym = inst.format ; break; case ID : sym = inst.id ; break; case OPCODE : sym = inst.opcode ; break; diff --git a/src/desktop/vue/CPU.java b/src/desktop/vue/CPU.java index 8965190..d422edc 100644 --- a/src/desktop/vue/CPU.java +++ b/src/desktop/vue/CPU.java @@ -443,8 +443,8 @@ class CPU { // First unit if (fetch == 0) { - inst.bits = access.value & 0xFFFF; - if (Instruction.size(access.value >> 10 & 0x3F) == 4) { + inst.bits = access.value; + if (Instruction.size(access.value >> 10) == 4) { fetch = 1; return false; } diff --git a/src/desktop/vue/Instruction.java b/src/desktop/vue/Instruction.java index 16be026..bdfbaab 100644 --- a/src/desktop/vue/Instruction.java +++ b/src/desktop/vue/Instruction.java @@ -114,6 +114,7 @@ public class Instruction { boolean read = false; var ret = new Access(); ret.address = vue.getRegister(reg1, false) + disp; + ret.fetch = vue.getFetch(); ret.type = Vue.S32; // Configure descriptor by ID @@ -139,10 +140,17 @@ public class Instruction { if (read) ret.value = vue.read(ret.address, ret.type); - // Select the value to write to the bus - else ret.value = vue.getRegister(id == Vue.CAXI && - vue.getRegister(reg2, false) == vue.read(ret.address, Vue.S32) ? - 30 : reg2, false); + // Write a register to the bus + else if (id != Vue.CAXI) + vue.getRegister(reg2, false); + + // CAXI processing + else { + int value = vue.read(ret.address, Vue.S32); + int compare = vue.getRegister(reg2, false); + int exchange = vue.getRegister( 30, false); + ret.value = value == compare ? value : exchange; + } return ret; } diff --git a/src/desktop/vue/JavaVue.java b/src/desktop/vue/JavaVue.java index ab2fefc..978c312 100644 --- a/src/desktop/vue/JavaVue.java +++ b/src/desktop/vue/JavaVue.java @@ -76,11 +76,6 @@ class JavaVue extends Vue { return maxCycles; } - // Retrieve a snapshot of the current state's memory access - public Access getAccess() { - return cpu.access; - } - // Retrieve the most recent applicaiton break code public int getBreakCode() { return breakCode; @@ -91,11 +86,6 @@ class JavaVue extends Vue { return cpu.exception; } - // Retrieve a snapshot of the current state's instruction - public Instruction getInstruction() { - return cpu.inst; - } - // Retrieve a register value public int getRegister(int index, boolean system) { diff --git a/src/desktop/vue/NativeVue.c b/src/desktop/vue/NativeVue.c index d0a4a04..d0a078f 100644 --- a/src/desktop/vue/NativeVue.c +++ b/src/desktop/vue/NativeVue.c @@ -141,22 +141,6 @@ JNIEXPORT jint JNICALL Java_vue_NativeVue_emulate return vueEmulate(&core->vue, maxCycles); } -// Retrieve a snapshot of the current state's memory access -JNIEXPORT jobject JNICALL Java_vue_NativeVue_getAccess - (JNIEnv *env, jobject vue, jlong handle, jobject acc) { - Core *core = *(Core **)&handle; - jclass cls = (*env)->GetObjectClass(env, acc); - (*env)->SetIntField(env, acc, (*env)->GetFieldID(env, cls, "address", "I"), - core->vue.cpu.access.address); - (*env)->SetIntField(env, acc, (*env)->GetFieldID(env, cls, "fetch", "I"), - core->vue.cpu.fetch); - (*env)->SetIntField(env, acc, (*env)->GetFieldID(env, cls, "type", "I"), - core->vue.cpu.access.type); - (*env)->SetIntField(env, acc, (*env)->GetFieldID(env, cls, "value", "I"), - core->vue.cpu.access.value); - return acc; -} - // Retrieve the most recent exception code JNIEXPORT jint JNICALL Java_vue_NativeVue_getBreakCode (JNIEnv *env, jobject vue, jlong handle) { @@ -171,36 +155,6 @@ JNIEXPORT jint JNICALL Java_vue_NativeVue_getExceptionCode return vueGetExceptionCode(&core->vue); } -// Retrieve a snapshot of the current state's instruction -JNIEXPORT jobject JNICALL Java_vue_NativeVue_getInstruction - (JNIEnv *env, jobject vue, jlong handle, jobject inst) { - Core *core = *(Core **)&handle; - jclass cls = (*env)->GetObjectClass(env, inst); - (*env)->SetIntField(env, inst, (*env)->GetFieldID(env, cls, "bits", "I"), - core->vue.cpu.inst.bits); - (*env)->SetIntField(env, inst, (*env)->GetFieldID(env, cls, "cond", "I"), - core->vue.cpu.inst.cond); - (*env)->SetIntField(env, inst, (*env)->GetFieldID(env, cls, "disp", "I"), - core->vue.cpu.inst.disp); - (*env)->SetIntField(env, inst, (*env)->GetFieldID(env, cls, "format", "I"), - core->vue.cpu.inst.format); - (*env)->SetIntField(env, inst, (*env)->GetFieldID(env, cls, "id", "I"), - core->vue.cpu.inst.id); - (*env)->SetIntField(env, inst, (*env)->GetFieldID(env, cls, "imm", "I"), - core->vue.cpu.inst.imm); - (*env)->SetIntField(env, inst, (*env)->GetFieldID(env, cls, "opcode", "I"), - core->vue.cpu.inst.opcode); - (*env)->SetIntField(env, inst, (*env)->GetFieldID(env, cls, "reg1", "I"), - core->vue.cpu.inst.reg1); - (*env)->SetIntField(env, inst, (*env)->GetFieldID(env, cls, "reg2", "I"), - core->vue.cpu.inst.reg2); - (*env)->SetIntField(env, inst, (*env)->GetFieldID(env, cls, "size", "I"), - core->vue.cpu.inst.size); - (*env)->SetIntField(env, inst, (*env)->GetFieldID(env,cls,"subopcode","I"), - core->vue.cpu.inst.subopcode); - return inst; -} - // Retrieve a register value JNIEXPORT jint JNICALL Java_vue_NativeVue_getRegister (JNIEnv *env, jobject vue, jlong handle, jint index, jboolean system) { diff --git a/src/desktop/vue/NativeVue.java b/src/desktop/vue/NativeVue.java index 3982969..40fd85b 100644 --- a/src/desktop/vue/NativeVue.java +++ b/src/desktop/vue/NativeVue.java @@ -42,12 +42,6 @@ class NativeVue extends Vue { public int emulate(int maxCycles) { return emulate(handle, maxCycles); } - // Retrieve a snapshot of the current state's memory access - private native Access getAccess(long handle, Access access); - public Access getAccess() { - return getAccess(handle, new Access()); - } - // Retrieve the most recent application break code private native int getBreakCode(long handle); public int getBreakCode() { return getBreakCode(handle); } @@ -58,12 +52,6 @@ class NativeVue extends Vue { return getExceptionCode(handle); } - // Retrieve a snapshot of the current state's instruction - private native Instruction getInstruction(long handle, Instruction inst); - public Instruction getInstruction() { - return getInstruction(handle, new Instruction()); - } - // Retrieve a register value private native int getRegister(long handle, int index, boolean system); public int getRegister(int index, boolean system)