Author SHA1 Message Date
Chris Cureau fcc57d9be4 update Makefiles and configuration for latest cc65 2016-01-12 08:14:38 -06:00
Seth Morabito 88eba2cdcb Merge branch '1.2.branch' 2016-01-08 20:53:54 -08:00
Seth Morabito 0e49b197b3 Update README for 1.2.1 2016-01-08 20:52:02 -08:00
Seth Morabito b59fa63b63 Merge branch '1.2.branch' 2016-01-08 20:41:25 -08:00
Seth Morabito eff98118d5 Fix a few straggling Java 8-isms. 2016-01-08 20:40:23 -08:00
Seth Morabito c599df1cfb Set version to 1.3.0-SNAPSHOT 2016-01-08 19:14:00 -08:00
Seth Morabito 66c52c8826 Revert Java 1.8 changes. Buildable with Java 1.7
There are still active users on Java 1.7, so building with Java 8
was a no-no. This change reverts the recent migration to Java 8,
allowing JDK 1.7 to compile the code.

This means, at least for the time being, no more Lambda expressions
(Boooooooooooooooo!!)
2016-01-08 19:11:42 -08:00
Seth Morabito f3a5dd93ad Release 1.2.0 2016-01-03 11:01:20 -08:00
Seth Morabito 4044458baa Fix typo 2016-01-03 10:59:11 -08:00
Seth Morabito 9ab94b3050 Prep for 1.2 2016-01-03 10:56:16 -08:00
Seth Morabito 9a504adc58 Added roadmap to README 2016-01-03 10:49:41 -08:00
Seth Morabito 57cbff42e7 Merge branch '1.1.branch' 2016-01-02 19:06:23 -08:00
Seth Morabito 0ca30291cb Merge branch '1.1.branch' 2016-01-02 09:51:20 -08:00
Seth Morabito 95f85b71b1 Enter key can add breakpoints 2016-01-02 09:50:38 -08:00
Seth Morabito 7a9f9bfd55 Update images for 1.1.0 2016-01-01 09:49:39 -08:00
Seth Morabito 1e04a52d1b Prep for 1.2 2016-01-01 09:44:43 -08:00
21 changed files with 257 additions and 166 deletions

No files matched your search

+20 -6
View File
@@ -1,9 +1,9 @@
SYMON - A 6502 System Simulator SYMON - A 6502 System Simulator
=============================== ===============================
**Version:** 1.1.1 **Version:** 1.2.1
**Last Updated:** 2 January, 2016 **Last Updated:** 8 January, 2016
See the file COPYING for license. See the file COPYING for license.
@@ -188,7 +188,7 @@ Maven will build Symon, run unit tests, and produce a jar file in the
Symon is meant to be invoked directly from the jar file. To run with Symon is meant to be invoked directly from the jar file. To run with
Java 1.8 or greater, just type: Java 1.8 or greater, just type:
$ java -jar symon-1.1.1.jar $ java -jar symon-1.2.0.jar
When Symon is running, you should be presented with a simple graphical When Symon is running, you should be presented with a simple graphical
interface. interface.
@@ -235,6 +235,12 @@ running.
## 5.0 Revision History ## 5.0 Revision History
- **1.2.1:** 8 January, 2016 - Remove dependency on Java 8. Now
supports compiling and running under Java 1.7.
- **1.2.0:** 3 January, 2016 - Add symbolic disassembly to breakpoints
window.
- **1.1.1:** 2 January, 2016 - Minor enhancement: Allows breakpoints - **1.1.1:** 2 January, 2016 - Minor enhancement: Allows breakpoints
to be added with the Enter key. to be added with the Enter key.
@@ -286,7 +292,15 @@ running.
- **0.1:** 20 January, 2010 - **0.1:** 20 January, 2010
## 6.0 To Do ## 6.0 Roadmap
- **1.2:** Better breakpoint support. Symbolic debugging of breakpoints.
- **2.0:** Complete rewrite of the UI in JavaFX instead of Swing. Complete
assembler and disassembler built in. Ability to attach source code for
symbolic debugging.
## 7.0 To Do
- Feedback (in the form of dialogs, status bar, etc). - Feedback (in the form of dialogs, status bar, etc).
@@ -310,7 +324,7 @@ running.
- Symbolic debugging. - Symbolic debugging.
## 7.0 Copyright and Acknowledgements ## 8.0 Copyright and Acknowledgements
**Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>** **Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>**
@@ -330,7 +344,7 @@ This project would not have been possible without the following resources:
- [Neil Parker's "The 6502/65C02/65C816 Instruction Set Decoded"] (http://www.llx.com/~nparker/a2/opcodes.html), - [Neil Parker's "The 6502/65C02/65C816 Instruction Set Decoded"] (http://www.llx.com/~nparker/a2/opcodes.html),
for information about how instructions are coded for information about how instructions are coded
## 8.0 Licensing ## 9.0 Licensing
Symon is free software. It is distributed under the MIT License. Symon is free software. It is distributed under the MIT License.
Please see the file 'COPYING' for full details of the license. Please see the file 'COPYING' for full details of the license.
+3 -3
View File
@@ -4,7 +4,7 @@
<groupId>com.loomcom.symon</groupId> <groupId>com.loomcom.symon</groupId>
<artifactId>symon</artifactId> <artifactId>symon</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>1.1.1</version> <version>1.3.0-SNAPSHOT</version>
<name>symon</name> <name>symon</name>
<url>http://www.loomcom.com/symon</url> <url>http://www.loomcom.com/symon</url>
<properties> <properties>
@@ -91,8 +91,8 @@
<version>3.1</version> <version>3.1</version>
<configuration> <configuration>
<compilerArgument>-Xlint:unchecked</compilerArgument> <compilerArgument>-Xlint:unchecked</compilerArgument>
<source>1.8</source> <source>1.7</source>
<target>1.8</target> <target>1.7</target>
</configuration> </configuration>
</plugin> </plugin>
+1 -1
View File
@@ -7,7 +7,7 @@ echo_irq: echo_irq.o
$(LD) -C symon.config -vm -m echo_irq.map -o echo_irq.rom echo_irq.o $(LD) -C symon.config -vm -m echo_irq.map -o echo_irq.rom echo_irq.o
echo_irq.o: echo_irq.o:
$(CA) --listing -o echo_irq.o echo_irq.asm $(CA) --listing echo_irq.lst -o echo_irq.o echo_irq.asm
clean: clean:
rm -f *.o *.rom *.map *.lst rm -f *.o *.rom *.map *.lst
+2 -2
View File
@@ -1,5 +1,5 @@
MEMORY { MEMORY {
RAM1: start = $0000, size = $8000; RAM1: start = $0000, size = $8000 - __STACKSIZE__;
ROM1: start = $C000, size = $3FFA, fill = yes; ROM1: start = $C000, size = $3FFA, fill = yes;
ROMV: start = $FFFA, size = $6, file = %O, fill = yes; ROMV: start = $FFFA, size = $6, file = %O, fill = yes;
} }
@@ -11,6 +11,6 @@ VECTORS: load = ROMV, type = ro;
} }
SYMBOLS { SYMBOLS {
__STACKSIZE__ = $0300; __STACKSIZE__: type = weak, value = $0300;
} }
+1 -1
View File
@@ -7,7 +7,7 @@ ehbasic: ehbasic.o
$(LD) -C symon.config -vm -m ehbasic.map -o ehbasic.rom ehbasic.o $(LD) -C symon.config -vm -m ehbasic.map -o ehbasic.rom ehbasic.o
ehbasic.o: ehbasic.o:
$(CA) --listing -o ehbasic.o min_mon.asm $(CA) --listing ehbasic.lst -o ehbasic.o min_mon.asm
clean: clean:
rm -f *.o *.rom *.map *.lst rm -f *.o *.rom *.map *.lst
+2 -2
View File
@@ -1,5 +1,5 @@
MEMORY { MEMORY {
RAM1: start = $0000, size = $8000; RAM1: start = $0000, size = $8000 - __STACKSIZE__;
ROM1: start = $C000, size = $3F00, fill = yes; ROM1: start = $C000, size = $3F00, fill = yes;
MONITOR: start = $FF00, size = $FA, fill = yes; MONITOR: start = $FF00, size = $FA, fill = yes;
ROMV: start = $FFFA, size = $6, file = %O, fill = yes; ROMV: start = $FFFA, size = $6, file = %O, fill = yes;
@@ -13,6 +13,6 @@ VECTORS: load = ROMV, type = ro;
} }
SYMBOLS { SYMBOLS {
__STACKSIZE__ = $0300; __STACKSIZE__: type = weak, value = $0300;
} }
+1 -1
View File
@@ -7,7 +7,7 @@ ehbasic: ehbasic.o
$(LD) -C symon.config -vm -m ehbasic.map -o ehbasic.rom ehbasic.o $(LD) -C symon.config -vm -m ehbasic.map -o ehbasic.rom ehbasic.o
ehbasic.o: ehbasic.o:
$(CA) --listing -o ehbasic.o min_mon.asm $(CA) --listing ehbasic.lst -o ehbasic.o min_mon.asm
clean: clean:
rm -f *.o *.rom *.map *.lst rm -f *.o *.rom *.map *.lst
+2 -2
View File
@@ -1,5 +1,5 @@
MEMORY { MEMORY {
RAM1: start = $0000, size = $8000; RAM1: start = $0000, size = $8000 - __STACKSIZE__;
ROM1: start = $C000, size = $3C00, fill = yes; ROM1: start = $C000, size = $3C00, fill = yes;
MONITOR: start = $FC00, size = $3FA, fill = yes; MONITOR: start = $FC00, size = $3FA, fill = yes;
ROMV: start = $FFFA, size = $6, file = %O, fill = yes; ROMV: start = $FFFA, size = $6, file = %O, fill = yes;
@@ -13,6 +13,6 @@ VECTORS: load = ROMV, type = ro;
} }
SYMBOLS { SYMBOLS {
__STACKSIZE__ = $0300; __STACKSIZE__: type = weak, value = $0300;
} }
Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 35 KiB

+4 -3
View File
@@ -34,7 +34,6 @@ import java.util.Map;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.stream.Collectors;
/** /**
* The Bus ties the whole thing together, man. * The Bus ties the whole thing together, man.
@@ -222,9 +221,11 @@ public class Bus {
List<Integer> priorities = new ArrayList<>(deviceMap.keySet()); List<Integer> priorities = new ArrayList<>(deviceMap.keySet());
Collections.sort(priorities); Collections.sort(priorities);
for(int priority : priorities) { for (int priority : priorities) {
SortedSet<Device> deviceSet = deviceMap.get(priority); SortedSet<Device> deviceSet = deviceMap.get(priority);
devices.addAll(deviceSet.stream().collect(Collectors.toList())); for (Device device : deviceSet) {
devices.add(device);
}
} }
return devices; return devices;
+10 -7
View File
@@ -86,13 +86,16 @@ public class Main {
final Simulator simulator = new Simulator(machineClass); final Simulator simulator = new Simulator(machineClass);
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(new Runnable() {
try { @Override
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); public void run() {
// Create the main UI window try {
simulator.createAndShowUi(); UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) { // Create the main UI window
e.printStackTrace(); simulator.createAndShowUi();
} catch (Exception e) {
e.printStackTrace();
}
} }
}); });
+81 -49
View File
@@ -185,13 +185,16 @@ public class Simulator {
JButton hardResetButton = new JButton("Hard Reset"); JButton hardResetButton = new JButton("Hard Reset");
stepCountBox = new JComboBox<>(STEPS); stepCountBox = new JComboBox<>(STEPS);
stepCountBox.addActionListener(actionEvent -> { stepCountBox.addActionListener(new ActionListener() {
try { @Override
JComboBox cb = (JComboBox) actionEvent.getSource(); public void actionPerformed(ActionEvent actionEvent) {
stepsPerClick = Integer.parseInt((String) cb.getSelectedItem()); try {
} catch (NumberFormatException ex) { JComboBox cb = (JComboBox) actionEvent.getSource();
stepsPerClick = 1; stepsPerClick = Integer.parseInt((String) cb.getSelectedItem());
stepCountBox.setSelectedIndex(0); } catch (NumberFormatException ex) {
stepsPerClick = 1;
stepCountBox.setSelectedIndex(0);
}
} }
}); });
@@ -211,24 +214,38 @@ public class Simulator {
// Bottom - buttons. // Bottom - buttons.
mainWindow.getContentPane().add(buttonContainer, BorderLayout.PAGE_END); mainWindow.getContentPane().add(buttonContainer, BorderLayout.PAGE_END);
runStopButton.addActionListener(actionEvent -> { runStopButton.addActionListener(new ActionListener() {
if (runLoop != null && runLoop.isRunning()) { @Override
handleStop(); public void actionPerformed(ActionEvent actionEvent) {
} else { if (runLoop != null && runLoop.isRunning()) {
handleStart(); Simulator.this.handleStop();
} else {
Simulator.this.handleStart();
}
} }
}); });
stepButton.addActionListener(actionEvent -> handleStep(stepsPerClick)); stepButton.addActionListener(new ActionListener() {
@Override
softResetButton.addActionListener(actionEvent -> { public void actionPerformed(ActionEvent actionEvent) {
// If this was a CTRL-click, do a hard reset. Simulator.this.handleStep(stepsPerClick);
handleReset(false); }
}); });
hardResetButton.addActionListener(actionEvent -> { softResetButton.addActionListener(new ActionListener() {
// If this was a CTRL-click, do a hard reset. @Override
handleReset(true); public void actionPerformed(ActionEvent actionEvent) {
// If this was a CTRL-click, do a hard reset.
Simulator.this.handleReset(false);
}
});
hardResetButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
// If this was a CTRL-click, do a hard reset.
Simulator.this.handleReset(true);
}
}); });
mainWindow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); mainWindow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
@@ -400,13 +417,16 @@ public class Simulator {
logger.debug("Starting main run loop."); logger.debug("Starting main run loop.");
isRunning = true; isRunning = true;
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(new Runnable() {
// Don't allow step while the simulator is running @Override
stepButton.setEnabled(false); public void run() {
stepCountBox.setEnabled(false); // Don't allow step while the simulator is running
menuBar.simulatorDidStart(); stepButton.setEnabled(false);
// Toggle the state of the run button stepCountBox.setEnabled(false);
runStopButton.setText("Stop"); menuBar.simulatorDidStart();
// Toggle the state of the run button
runStopButton.setText("Stop");
}
}); });
try { try {
@@ -417,17 +437,20 @@ public class Simulator {
logger.error("Exception in main simulator run thread. Exiting run.", ex); logger.error("Exception in main simulator run thread. Exiting run.", ex);
} }
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(new Runnable() {
statusPane.updateState(); @Override
memoryWindow.updateState(); public void run() {
runStopButton.setText("Run"); statusPane.updateState();
stepButton.setEnabled(true); memoryWindow.updateState();
stepCountBox.setEnabled(true); runStopButton.setText("Run");
if (traceLog.isVisible()) { stepButton.setEnabled(true);
traceLog.refresh(); stepCountBox.setEnabled(true);
if (traceLog.isVisible()) {
traceLog.refresh();
}
menuBar.simulatorDidStop();
traceLog.simulatorDidStop();
} }
menuBar.simulatorDidStop();
traceLog.simulatorDidStop();
}); });
isRunning = false; isRunning = false;
@@ -480,9 +503,12 @@ public class Simulator {
// Now load the program at the starting address. // Now load the program at the starting address.
loadProgram(program, preferences.getProgramStartAddress()); loadProgram(program, preferences.getProgramStartAddress());
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(new Runnable() {
console.reset(); @Override
breakpoints.refresh(); public void run() {
console.reset();
breakpoints.refresh();
}
}); });
// TODO: "Don't Show Again" checkbox // TODO: "Don't Show Again" checkbox
@@ -623,9 +649,12 @@ public class Simulator {
} }
public void actionPerformed(ActionEvent actionEvent) { public void actionPerformed(ActionEvent actionEvent) {
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(new Runnable() {
console.setFont(new Font("Monospaced", Font.PLAIN, size)); @Override
mainWindow.pack(); public void run() {
console.setFont(new Font("Monospaced", Font.PLAIN, size));
mainWindow.pack();
}
}); });
} }
} }
@@ -889,12 +918,15 @@ public class Simulator {
private void updateVisibleState() { private void updateVisibleState() {
// Immediately update the UI. // Immediately update the UI.
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(new Runnable() {
// Now update the state @Override
statusPane.updateState(); public void run() {
memoryWindow.updateState(); // Now update the state
if (traceLog.shouldUpdate()) { statusPane.updateState();
traceLog.refresh(); memoryWindow.updateState();
if (traceLog.shouldUpdate()) {
traceLog.refresh();
}
} }
}); });
} }
@@ -115,7 +115,9 @@ public abstract class Device implements Comparable<Device> {
} }
public void notifyListeners() { public void notifyListeners() {
deviceChangeListeners.forEach(DeviceChangeListener::deviceStateChanged); for (DeviceChangeListener listener : deviceChangeListeners) {
listener.deviceStateChanged();
}
} }
/** /**
@@ -27,7 +27,6 @@ package com.loomcom.symon.devices;
import com.loomcom.symon.exceptions.MemoryAccessException; import com.loomcom.symon.exceptions.MemoryAccessException;
import com.loomcom.symon.exceptions.MemoryRangeException; import com.loomcom.symon.exceptions.MemoryRangeException;
import jdk.nashorn.internal.ir.annotations.Ignore;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@@ -30,7 +30,10 @@ import org.slf4j.LoggerFactory;
import javax.swing.*; import javax.swing.*;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*; import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
/** /**
@@ -62,21 +65,24 @@ public class BreakpointsWindow extends JFrame {
breakpointsPanel.setLayout(new BorderLayout()); breakpointsPanel.setLayout(new BorderLayout());
breakpointsPanel.setBorder(new EmptyBorder(10, 10, 10, 10)); breakpointsPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
JButton addButton = new JButton("Add"); final JButton addButton = new JButton("Add");
JButton removeButton = new JButton("Del"); final JButton removeButton = new JButton("Del");
removeButton.setEnabled(false); removeButton.setEnabled(false);
JTextField addTextField = new JTextField(4); final JTextField addTextField = new JTextField(4);
JTable breakpointsTable = new JTable(breakpoints); final JTable breakpointsTable = new JTable(breakpoints);
breakpointsTable.setShowGrid(true); breakpointsTable.setShowGrid(true);
breakpointsTable.setGridColor(Color.LIGHT_GRAY); breakpointsTable.setGridColor(Color.LIGHT_GRAY);
breakpointsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); breakpointsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
breakpointsTable.getSelectionModel().addListSelectionListener(e -> { breakpointsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
if (e.getFirstIndex() > -1) { @Override
removeButton.setEnabled(true); public void valueChanged(ListSelectionEvent e) {
} else { if (e.getFirstIndex() > -1) {
removeButton.setEnabled(false); removeButton.setEnabled(true);
} else {
removeButton.setEnabled(false);
}
} }
}); });
@@ -86,37 +92,45 @@ public class BreakpointsWindow extends JFrame {
breakpointsPanel.add(scrollPane, BorderLayout.CENTER); breakpointsPanel.add(scrollPane, BorderLayout.CENTER);
ActionListener addBreakpointListener = e -> { ActionListener addBreakpointListener = new ActionListener() {
int value = -1; @Override
public void actionPerformed(ActionEvent e) {
int value;
String newBreakpoint = addTextField.getText(); String newBreakpoint = addTextField.getText();
if (newBreakpoint == null || newBreakpoint.isEmpty()) { if (newBreakpoint == null || newBreakpoint.isEmpty()) {
return; return;
}
try {
value = (Integer.parseInt(addTextField.getText(), 16) & 0xffff);
} catch (NumberFormatException ex) {
logger.warn("Can't parse page number {}", newBreakpoint);
return;
}
if (value < 0) {
return;
}
breakpoints.addBreakpoint(value);
logger.debug("Added breakpoint ${}", Utils.wordToHex(value));
addTextField.setText(EMPTY_STRING);
} }
try {
value = (Integer.parseInt(addTextField.getText(), 16) & 0xffff);
} catch (NumberFormatException ex) {
logger.warn("Can't parse page number {}", newBreakpoint);
return;
}
if (value < 0) {
return;
}
breakpoints.addBreakpoint(value);
logger.debug("Added breakpoint ${}", Utils.wordToHex(value));
addTextField.setText(EMPTY_STRING);
}; };
addButton.addActionListener(addBreakpointListener); addButton.addActionListener(addBreakpointListener);
addTextField.addActionListener(addBreakpointListener); addTextField.addActionListener(addBreakpointListener);
removeButton.addActionListener(e -> breakpoints.removeBreakpointAtIndex(breakpointsTable.getSelectedRow())); removeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
breakpoints.removeBreakpointAtIndex(breakpointsTable.getSelectedRow());
}
});
controlPanel.add(addTextField); controlPanel.add(addTextField);
controlPanel.add(addButton); controlPanel.add(addButton);
@@ -97,19 +97,25 @@ public class PreferencesDialog extends Observable implements Preferences {
JButton applyButton = new JButton("Apply"); JButton applyButton = new JButton("Apply");
JButton cancelButton = new JButton("Cancel"); JButton cancelButton = new JButton("Cancel");
cancelButton.addActionListener(actionEvent -> { cancelButton.addActionListener(new ActionListener() {
updateUi(); @Override
dialog.setVisible(false); public void actionPerformed(ActionEvent actionEvent) {
PreferencesDialog.this.updateUi();
dialog.setVisible(false);
}
}); });
applyButton.addActionListener(actionEvent -> { applyButton.addActionListener(new ActionListener() {
haltOnBreak = haltOnBreakCheckBox.isSelected(); @Override
programLoadAddress = hexToInt(programLoadAddressField.getText()); public void actionPerformed(ActionEvent actionEvent) {
updateUi(); haltOnBreak = haltOnBreakCheckBox.isSelected();
// TODO: Actually check to see if values have changed, don't assume. programLoadAddress = PreferencesDialog.this.hexToInt(programLoadAddressField.getText());
setChanged(); PreferencesDialog.this.updateUi();
PreferencesDialog.this.notifyObservers(); // TODO: Actually check to see if values have changed, don't assume.
dialog.setVisible(false); PreferencesDialog.this.setChanged();
PreferencesDialog.this.notifyObservers();
dialog.setVisible(false);
}
}); });
buttonsContainer.add(applyButton); buttonsContainer.add(applyButton);
@@ -31,6 +31,8 @@ import javax.swing.*;
import javax.swing.border.Border; import javax.swing.border.Border;
import javax.swing.border.EtchedBorder; import javax.swing.border.EtchedBorder;
import java.awt.*; import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/** /**
* UI component that displays the current state of the simulated CPU. * UI component that displays the current state of the simulated CPU.
@@ -162,59 +164,74 @@ public class StatusPanel extends JPanel {
yField = makeTextField(SMALL_TEXT_FIELD_SIZE, true); yField = makeTextField(SMALL_TEXT_FIELD_SIZE, true);
// Make fields editable // Make fields editable
pcField.addActionListener(e -> { pcField.addActionListener(new ActionListener() {
try { @Override
int newVal = getHexVal(pcField) & 0xffff; public void actionPerformed(ActionEvent e) {
machine.getCpu().setProgramCounter(newVal); try {
} catch (Exception ex) { int newVal = StatusPanel.this.getHexVal(pcField) & 0xffff;
// Swallow exception machine.getCpu().setProgramCounter(newVal);
} } catch (Exception ex) {
// Swallow exception
}
updateState(); StatusPanel.this.updateState();
}
}); });
spField.addActionListener(e -> { spField.addActionListener(new ActionListener() {
try { @Override
int newVal = getHexVal(spField) & 0xff; public void actionPerformed(ActionEvent e) {
machine.getCpu().setStackPointer(newVal); try {
} catch (Exception ex) { int newVal = StatusPanel.this.getHexVal(spField) & 0xff;
// Swallow exception machine.getCpu().setStackPointer(newVal);
} } catch (Exception ex) {
// Swallow exception
}
updateState(); StatusPanel.this.updateState();
}
}); });
aField.addActionListener(e -> { aField.addActionListener(new ActionListener() {
try { @Override
int newVal = getHexVal(aField) & 0xff; public void actionPerformed(ActionEvent e) {
machine.getCpu().setAccumulator(newVal); try {
} catch (Exception ex) { int newVal = StatusPanel.this.getHexVal(aField) & 0xff;
// Swallow exception machine.getCpu().setAccumulator(newVal);
} } catch (Exception ex) {
// Swallow exception
}
updateState(); StatusPanel.this.updateState();
}
}); });
xField.addActionListener(e -> { xField.addActionListener(new ActionListener() {
try { @Override
int newVal = getHexVal(xField) & 0xff; public void actionPerformed(ActionEvent e) {
machine.getCpu().setXRegister(newVal); try {
} catch (Exception ex) { int newVal = StatusPanel.this.getHexVal(xField) & 0xff;
// Swallow exception machine.getCpu().setXRegister(newVal);
} } catch (Exception ex) {
// Swallow exception
}
updateState(); StatusPanel.this.updateState();
}
}); });
yField.addActionListener(e -> { yField.addActionListener(new ActionListener() {
try { @Override
int newVal = getHexVal(yField) & 0xff; public void actionPerformed(ActionEvent e) {
machine.getCpu().setYRegister(newVal); try {
} catch (Exception ex) { int newVal = StatusPanel.this.getHexVal(yField) & 0xff;
// Swallow exception machine.getCpu().setYRegister(newVal);
} } catch (Exception ex) {
// Swallow exception
}
updateState(); StatusPanel.this.updateState();
}
}); });
constraints.anchor = GridBagConstraints.LINE_START; constraints.anchor = GridBagConstraints.LINE_START;
@@ -122,10 +122,13 @@ public class VideoWindow extends JFrame implements DeviceChangeListener {
*/ */
private class CursorBlinker implements Runnable { private class CursorBlinker implements Runnable {
public void run() { public void run() {
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(new Runnable() {
if (cursorBlinkRate > 0) { @Override
hideCursor = !hideCursor; public void run() {
repaint(); if (cursorBlinkRate > 0) {
hideCursor = !hideCursor;
VideoWindow.this.repaint();
}
} }
}); });
} }