diff --git a/src/main/java/de/neemann/digital/core/Model.java b/src/main/java/de/neemann/digital/core/Model.java index dcec6837f..5e4fe09b7 100644 --- a/src/main/java/de/neemann/digital/core/Model.java +++ b/src/main/java/de/neemann/digital/core/Model.java @@ -1,5 +1,6 @@ package de.neemann.digital.core; +import de.neemann.digital.core.memory.ROM; import de.neemann.digital.core.wiring.Break; import de.neemann.digital.core.wiring.Clock; import de.neemann.digital.core.wiring.Reset; @@ -43,6 +44,7 @@ public class Model implements Iterable { private final ArrayList clocks; private final ArrayList breaks; private final ArrayList resets; + private final ArrayList progRoms; private final ArrayList signals; private final ArrayList inputs; @@ -62,6 +64,7 @@ public class Model implements Iterable { this.clocks = new ArrayList<>(); this.breaks = new ArrayList<>(); this.resets = new ArrayList<>(); + this.progRoms = new ArrayList<>(); this.signals = new ArrayList<>(); this.outputs = new ArrayList<>(); this.inputs = new ArrayList<>(); @@ -429,6 +432,15 @@ public class Model implements Iterable { return n; } + + public void addProgRom(ROM rom) { + progRoms.add(rom); + } + + public ArrayList getProgRoms() { + return progRoms; + } + /** * fires a model changed event to all listeners */ diff --git a/src/main/java/de/neemann/digital/core/memory/ROM.java b/src/main/java/de/neemann/digital/core/memory/ROM.java index 9c8a786dc..4653726f5 100644 --- a/src/main/java/de/neemann/digital/core/memory/ROM.java +++ b/src/main/java/de/neemann/digital/core/memory/ROM.java @@ -115,6 +115,9 @@ public class ROM extends Node implements Element { @Override public void init(Model model) throws NodeException { + if (isProgramMemory) { + model.addProgRom(this); + } if (autoLoad) { try { data = new DataField(hexFile); diff --git a/src/main/java/de/neemann/digital/gui/DigitalRemoteInterface.java b/src/main/java/de/neemann/digital/gui/DigitalRemoteInterface.java index f841482ad..000d91acf 100644 --- a/src/main/java/de/neemann/digital/gui/DigitalRemoteInterface.java +++ b/src/main/java/de/neemann/digital/gui/DigitalRemoteInterface.java @@ -21,30 +21,37 @@ public interface DigitalRemoteInterface { /** * Starts the model + * * @throws RemoteException RemoteException */ void start() throws RemoteException; /** * Starts the model in debug mode + * * @throws RemoteException RemoteException */ void debug() throws RemoteException; /** * performs a single step + * + * @return actual position * @throws RemoteException RemoteException */ - void doSingleStep() throws RemoteException; + String doSingleStep() throws RemoteException; /** * runs model to the next BRK instruction + * + * @return actual position * @throws RemoteException RemoteException */ - void runToBreak() throws RemoteException; + String runToBreak() throws RemoteException; /** * stops the model + * * @throws RemoteException RemoteException */ void stop() throws RemoteException; diff --git a/src/main/java/de/neemann/digital/gui/Main.java b/src/main/java/de/neemann/digital/gui/Main.java index 2d459b5a8..711282301 100644 --- a/src/main/java/de/neemann/digital/gui/Main.java +++ b/src/main/java/de/neemann/digital/gui/Main.java @@ -52,6 +52,7 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.lang.reflect.InvocationTargetException; import java.net.URL; import java.util.ArrayList; import java.util.List; @@ -1019,39 +1020,57 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E } @Override - public void doSingleStep() { + public String doSingleStep() throws RemoteException { if (model != null && !realtimeClockRunning) { - SwingUtilities.invokeLater(() -> { - ArrayList cl = model.getClocks(); - if (cl.size() == 1) { - ObservableValue clkVal = cl.get(0).getClockOutput(); - clkVal.setBool(!clkVal.getBool()); - try { - model.doStep(); - if (clkVal.getBool()) { - clkVal.setBool(!clkVal.getBool()); + try { + SwingUtilities.invokeAndWait(() -> { + ArrayList cl = model.getClocks(); + if (cl.size() == 1) { + ObservableValue clkVal = cl.get(0).getClockOutput(); + clkVal.setBool(!clkVal.getBool()); + try { model.doStep(); + if (clkVal.getBool()) { + clkVal.setBool(!clkVal.getBool()); + model.doStep(); + } + circuitComponent.hasChanged(); + } catch (NodeException e) { + showErrorAndStopModel(Lang.get("err_remoteExecution"), e); } - circuitComponent.hasChanged(); - } catch (NodeException e) { - showErrorAndStopModel(Lang.get("err_remoteExecution"), e); } - } - }); + }); + return getProgRomAddr(); + } catch (InterruptedException | InvocationTargetException e) { + throw new RemoteException("error performing a single step "+e.getMessage()); + } } + return null; + } + + private String getProgRomAddr() { + ArrayList roms = model.getProgRoms(); + if (roms.size()==1) + return Long.toHexString(roms.get(0).getRomAddress()); + return null; } @Override - public void runToBreak() { - SwingUtilities.invokeLater(() -> { - if (model != null && model.isFastRunModel() && !realtimeClockRunning) - runToBreakAction.actionPerformed(null); - }); + public String runToBreak() throws RemoteException { + try { + SwingUtilities.invokeAndWait(() -> { + if (model != null && model.isFastRunModel() && !realtimeClockRunning) + runToBreakAction.actionPerformed(null); + }); + return getProgRomAddr(); + } catch (InterruptedException | InvocationTargetException e) { + throw new RemoteException("error performing a run to break "+e.getMessage()); + } } private void setDebug(boolean debug) throws RemoteException { VisualElement rom = getProgramRomFromCircuit(); - rom.getElementAttributes().set(Keys.SHOW_LISTING, debug); + //rom.getElementAttributes().set(Keys.SHOW_LISTING, debug); settings.set(Keys.SHOW_DATA_TABLE, debug); } diff --git a/src/main/java/de/neemann/digital/gui/remote/DigitalHandler.java b/src/main/java/de/neemann/digital/gui/remote/DigitalHandler.java index 2ceea3ce4..5cb3c7675 100644 --- a/src/main/java/de/neemann/digital/gui/remote/DigitalHandler.java +++ b/src/main/java/de/neemann/digital/gui/remote/DigitalHandler.java @@ -31,34 +31,35 @@ public class DigitalHandler implements HandlerInterface { } try { - handle(command.toLowerCase(), args); - return "ok"; + String ret = handle(command.toLowerCase(), args); + if (ret != null) + return "ok:"+ret; + else + return "ok"; } catch (RemoteException e) { return e.getMessage(); } } - private void handle(String command, String args) throws RemoteException { + private String handle(String command, String args) throws RemoteException { switch (command) { case "step": - digitalRemoteInterface.doSingleStep(); - break; + return digitalRemoteInterface.doSingleStep(); case "start": digitalRemoteInterface.start(); - break; + return null; case "debug": digitalRemoteInterface.debug(); - break; + return null; case "run": - digitalRemoteInterface.runToBreak(); - break; + return digitalRemoteInterface.runToBreak(); case "stop": digitalRemoteInterface.stop(); - break; + return null; case "load": File file = new File(args); digitalRemoteInterface.loadRom(file); - break; + return null; default: throw new RemoteException(Lang.get("msg_remoteUnknownCommand", command)); }