Improved debugging of processors. Now its more intuitive.

Also updating of listings and value tables are disabled in fast run mode.
This commit is contained in:
hneemann 2016-08-20 13:10:09 +02:00
parent c3cf27f427
commit b3b778c79a
13 changed files with 156 additions and 39 deletions

View File

@ -144,6 +144,10 @@
<visualElement> <visualElement>
<elementName>ROM</elementName> <elementName>ROM</elementName>
<elementAttributes> <elementAttributes>
<entry>
<string>isProgramMemory</string>
<boolean>true</boolean>
</entry>
<entry> <entry>
<string>Bits</string> <string>Bits</string>
<int>16</int> <int>16</int>

View File

@ -231,6 +231,7 @@ public class Model implements Iterable<Node> {
int count = aBreak.getCycles() * 2; int count = aBreak.getCycles() * 2;
boolean lastIn = brVal.getBool(); boolean lastIn = brVal.getBool();
fireEvent(ModelEvent.FASTRUN);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
clkVal.setBool(!clkVal.getBool()); clkVal.setBool(!clkVal.getBool());
doStep(); doStep();

View File

@ -24,6 +24,11 @@ public enum ModelEvent {
*/ */
STEP, STEP,
/**
* Fast run is started.
*/
FASTRUN,
/** /**
* A break is detected. * A break is detected.
*/ */

View File

@ -157,6 +157,12 @@ public final class Keys {
public static final Key<Boolean> SHOW_LISTING public static final Key<Boolean> SHOW_LISTING
= new Key<>("showList", false); = new Key<>("showList", false);
/**
* flag to set a ROM as programm memory
*/
public static final Key<Boolean> IS_PROGRAM_MEMORY
= new Key<>("isProgramMemory", false);
/** /**
* flag to enable the ROMs auto load function * flag to enable the ROMs auto load function
*/ */

View File

@ -34,6 +34,7 @@ public class ROM extends Node implements Element {
.addAttribute(Keys.ADDR_BITS) .addAttribute(Keys.ADDR_BITS)
.addAttribute(Keys.LABEL) .addAttribute(Keys.LABEL)
.addAttribute(Keys.DATA) .addAttribute(Keys.DATA)
.addAttribute(Keys.IS_PROGRAM_MEMORY)
.addAttribute(Keys.AUTO_RELOAD_ROM) .addAttribute(Keys.AUTO_RELOAD_ROM)
.addAttribute(Keys.SHOW_LISTING); .addAttribute(Keys.SHOW_LISTING);

View File

@ -1,5 +1,7 @@
package de.neemann.digital.gui; package de.neemann.digital.gui;
import de.neemann.digital.gui.remote.RemoteException;
import java.io.File; import java.io.File;
/** /**
@ -13,28 +15,37 @@ public interface DigitalRemoteInterface {
* Loads the given file to the data rom * Loads the given file to the data rom
* *
* @param file the file to load * @param file the file to load
* @return true if loading was successful * @throws RemoteException RemoteException
*/ */
boolean loadRom(File file); void loadRom(File file) throws RemoteException;
/** /**
* Starts the model * Starts the model
* @return true if start was successful * @throws RemoteException RemoteException
*/ */
boolean start(); void start() throws RemoteException;
/**
* Starts the model in debug mode
* @throws RemoteException RemoteException
*/
void debug() throws RemoteException;
/** /**
* performs a single step * performs a single step
* @throws RemoteException RemoteException
*/ */
void doSingleStep(); void doSingleStep() throws RemoteException;
/** /**
* runs model to the next BRK instruction * runs model to the next BRK instruction
* @throws RemoteException RemoteException
*/ */
void runToBreak(); void runToBreak() throws RemoteException;
/** /**
* stops the model * stops the model
* @throws RemoteException RemoteException
*/ */
void stop(); void stop() throws RemoteException;
} }

View File

@ -11,6 +11,7 @@ import de.neemann.digital.core.element.Key;
import de.neemann.digital.core.element.Keys; import de.neemann.digital.core.element.Keys;
import de.neemann.digital.core.io.In; import de.neemann.digital.core.io.In;
import de.neemann.digital.core.io.Out; import de.neemann.digital.core.io.Out;
import de.neemann.digital.core.memory.DataField;
import de.neemann.digital.core.memory.ROM; import de.neemann.digital.core.memory.ROM;
import de.neemann.digital.core.wiring.Clock; import de.neemann.digital.core.wiring.Clock;
import de.neemann.digital.draw.elements.Circuit; import de.neemann.digital.draw.elements.Circuit;
@ -31,6 +32,7 @@ import de.neemann.digital.gui.components.test.DataException;
import de.neemann.digital.gui.components.test.TestCaseElement; import de.neemann.digital.gui.components.test.TestCaseElement;
import de.neemann.digital.gui.components.test.TestResultDialog; import de.neemann.digital.gui.components.test.TestResultDialog;
import de.neemann.digital.gui.remote.DigitalHandler; import de.neemann.digital.gui.remote.DigitalHandler;
import de.neemann.digital.gui.remote.RemoteException;
import de.neemann.digital.gui.remote.RemoteSever; import de.neemann.digital.gui.remote.RemoteSever;
import de.neemann.digital.gui.state.State; import de.neemann.digital.gui.state.State;
import de.neemann.digital.gui.state.StateManager; import de.neemann.digital.gui.state.StateManager;
@ -729,7 +731,7 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E
for (ROM rom : model.findNode(ROM.class)) for (ROM rom : model.findNode(ROM.class))
if (rom.showListing()) if (rom.showListing())
try { try {
windowPosManager.register("rom" + (i++), new ROMListingDialog(this, rom)).setVisible(true); windowPosManager.register("rom" + (i++), new ROMListingDialog(this, rom, model, modelSync)).setVisible(true);
} catch (IOException e) { } catch (IOException e) {
new ErrorMessage(Lang.get("msg_errorReadingListing_N0", rom.getHexFile().toString())).addCause(e).show(this); new ErrorMessage(Lang.get("msg_errorReadingListing_N0", rom.getHexFile().toString())).addCause(e).show(this);
} }
@ -944,20 +946,36 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E
// remote interface start // remote interface start
//********************** //**********************
@Override public VisualElement getProgramRomFromCircuit() throws RemoteException {
public boolean loadRom(File file) { VisualElement rom = null;
boolean found = false;
ArrayList<VisualElement> el = circuitComponent.getCircuit().getElements(); ArrayList<VisualElement> el = circuitComponent.getCircuit().getElements();
for (VisualElement e : el) { for (VisualElement e : el) {
if (e.equalsDescription(ROM.DESCRIPTION)) { if (e.equalsDescription(ROM.DESCRIPTION)) {
ElementAttributes attr = e.getElementAttributes(); ElementAttributes attr = e.getElementAttributes();
if (attr.get(Keys.AUTO_RELOAD_ROM)) { if (attr.get(Keys.IS_PROGRAM_MEMORY)) {
attr.setFile(ROM.LAST_DATA_FILE_KEY, file); if (rom != null)
found = true; throw new RemoteException(Lang.get("msg_moreThenOneRomFound"));
rom = e;
} }
} }
} }
return found; if (rom == null)
throw new RemoteException(Lang.get("msg_noRomFound"));
return rom;
}
@Override
public void loadRom(File file) throws RemoteException {
VisualElement rom = getProgramRomFromCircuit();
ElementAttributes attr = rom.getElementAttributes();
try {
DataField df = new DataField(file);
attr.set(Keys.DATA, df);
attr.setFile(ROM.LAST_DATA_FILE_KEY, file); // needed in debug mode to load listing!
} catch (IOException e) {
throw new RemoteException(e.getMessage());
}
} }
@Override @Override
@ -987,11 +1005,23 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E
runToBreakAction.actionPerformed(null); runToBreakAction.actionPerformed(null);
} }
private void setDebug(boolean debug) throws RemoteException {
VisualElement rom = getProgramRomFromCircuit();
rom.getElementAttributes().set(Keys.SHOW_LISTING, debug);
}
@Override @Override
public boolean start() { public void debug() throws RemoteException {
setDebug(true);
runModelState.enter(false); runModelState.enter(false);
circuitComponent.hasChanged(); circuitComponent.hasChanged();
return true; }
@Override
public void start() throws RemoteException {
setDebug(false);
runModelState.enter(true);
circuitComponent.hasChanged();
} }
@Override @Override

View File

@ -24,6 +24,7 @@ public class ProbeDialog extends JDialog implements ModelStateObserver {
private final ModelEvent type; private final ModelEvent type;
private final SignalTableModel tableModel; private final SignalTableModel tableModel;
private boolean tableUpdateEnable = true;
/** /**
* Creates a new instance * Creates a new instance
@ -73,7 +74,18 @@ public class ProbeDialog extends JDialog implements ModelStateObserver {
@Override @Override
public void handleEvent(ModelEvent event) { public void handleEvent(ModelEvent event) {
if (event == type || event == ModelEvent.MANUALCHANGE) { if (event == type || event == ModelEvent.MANUALCHANGE) {
SwingUtilities.invokeLater(tableModel::fireChanged); if (tableUpdateEnable)
SwingUtilities.invokeLater(tableModel::fireChanged);
}
switch (event) {
case FASTRUN:
tableUpdateEnable = false;
break;
case BREAK:
case STOPPED:
tableUpdateEnable = true;
SwingUtilities.invokeLater(tableModel::fireChanged);
break;
} }
} }

View File

@ -1,7 +1,11 @@
package de.neemann.digital.gui.components.listing; package de.neemann.digital.gui.components.listing;
import de.neemann.digital.core.Model;
import de.neemann.digital.core.ModelEvent;
import de.neemann.digital.core.ModelStateObserver;
import de.neemann.digital.core.Observer; import de.neemann.digital.core.Observer;
import de.neemann.digital.core.memory.ROM; import de.neemann.digital.core.memory.ROM;
import de.neemann.digital.gui.sync.Sync;
import de.neemann.digital.lang.Lang; import de.neemann.digital.lang.Lang;
import javax.swing.*; import javax.swing.*;
@ -17,27 +21,27 @@ import java.io.IOException;
* *
* @author hneemann * @author hneemann
*/ */
public class ROMListingDialog extends JDialog implements Observer { public class ROMListingDialog extends JDialog implements Observer, ModelStateObserver {
private final ROM rom; private final ROM rom;
private final Listing listing; private final Listing listing;
private final JList<String> list; private final JList<String> list;
private int lastAddr = -1; private int lastAddr = -1;
private boolean updateViewEnable = true;
/** /**
* Creates a new instance * Creates a new instance
* *
* @param parent the parent frame * @param parent the parent frame
* @param rom the rom element * @param rom the rom element
* @param model the model
* @throws IOException IOException * @throws IOException IOException
*/ */
public ROMListingDialog(JFrame parent, ROM rom) throws IOException { public ROMListingDialog(JFrame parent, ROM rom, Model model, Sync modelSync) throws IOException {
super(parent, Lang.get("win_listing"), false); super(parent, Lang.get("win_listing"), false);
setDefaultCloseOperation(DISPOSE_ON_CLOSE); setDefaultCloseOperation(DISPOSE_ON_CLOSE);
this.rom = rom;
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setAlwaysOnTop(true); setAlwaysOnTop(true);
this.rom = rom;
File filename = rom.getHexFile(); File filename = rom.getHexFile();
String name = filename.getName(); String name = filename.getName();
@ -55,12 +59,18 @@ public class ROMListingDialog extends JDialog implements Observer {
addWindowListener(new WindowAdapter() { addWindowListener(new WindowAdapter() {
@Override @Override
public void windowOpened(WindowEvent e) { public void windowOpened(WindowEvent e) {
rom.addObserver(ROMListingDialog.this); modelSync.access(() -> {
rom.addObserver(ROMListingDialog.this);
model.addObserver(ROMListingDialog.this);
});
} }
@Override @Override
public void windowClosed(WindowEvent e) { public void windowClosed(WindowEvent e) {
rom.removeObserver(ROMListingDialog.this); modelSync.access(() -> {
rom.removeObserver(ROMListingDialog.this);
model.removeObserver(ROMListingDialog.this);
});
} }
}); });
@ -76,6 +86,13 @@ public class ROMListingDialog extends JDialog implements Observer {
public void hasChanged() { public void hasChanged() {
int addr = (int) rom.getRomAddress(); int addr = (int) rom.getRomAddress();
if (addr != lastAddr) { if (addr != lastAddr) {
updateView(addr);
lastAddr = addr;
}
}
private void updateView(int addr) {
if (updateViewEnable) {
Integer line = listing.getLine(addr); Integer line = listing.getLine(addr);
if (line != null) { if (line != null) {
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
@ -83,8 +100,20 @@ public class ROMListingDialog extends JDialog implements Observer {
list.setSelectedIndex(line); list.setSelectedIndex(line);
}); });
} }
lastAddr = addr;
} }
} }
@Override
public void handleEvent(ModelEvent event) {
switch (event) {
case FASTRUN:
updateViewEnable = false;
break;
case BREAK:
case STOPPED:
updateViewEnable = true;
updateView(lastAddr);
break;
}
}
} }

View File

@ -30,17 +30,24 @@ public class DigitalHandler implements HandlerInterface {
args = request.substring(p + 1); args = request.substring(p + 1);
} }
return handle(command.toLowerCase(), args); try {
handle(command.toLowerCase(), args);
return "ok";
} catch (RemoteException e) {
return e.getMessage();
}
} }
private String handle(String command, String args) { private void handle(String command, String args) throws RemoteException {
switch (command) { switch (command) {
case "step": case "step":
digitalRemoteInterface.doSingleStep(); digitalRemoteInterface.doSingleStep();
break; break;
case "start": case "start":
if (!digitalRemoteInterface.start()) digitalRemoteInterface.start();
return Lang.get("msg_errorCreatingModel"); break;
case "debug":
digitalRemoteInterface.debug();
break; break;
case "run": case "run":
digitalRemoteInterface.runToBreak(); digitalRemoteInterface.runToBreak();
@ -50,15 +57,10 @@ public class DigitalHandler implements HandlerInterface {
break; break;
case "load": case "load":
File file = new File(args); File file = new File(args);
if (file.exists()) { digitalRemoteInterface.loadRom(file);
if (!digitalRemoteInterface.loadRom(file))
return Lang.get("msg_noRomFound");
} else
return Lang.get("msg_errorFileNotFound", args);
break; break;
default: default:
return Lang.get("msg_remoteUnknownCommand", command); throw new RemoteException(Lang.get("msg_remoteUnknownCommand", command));
} }
return "ok";
} }
} }

View File

@ -0,0 +1,10 @@
package de.neemann.digital.gui.remote;
/**
* Created by hneemann on 20.08.16.
*/
public class RemoteException extends Exception {
public RemoteException(String message) {
super(message);
}
}

View File

@ -238,6 +238,8 @@ Zur Analyse können Sie die Schaltung im Gatterschrittmodus ausführen.</string>
<string name="key_Testdata">Testdaten</string> <string name="key_Testdata">Testdaten</string>
<string name="key_graphicWidth">Breite in Pixel</string> <string name="key_graphicWidth">Breite in Pixel</string>
<string name="key_graphicHeight">Höhe in Pixel</string> <string name="key_graphicHeight">Höhe in Pixel</string>
<string name="key_isProgramMemory">Programmspeicher</string>
<string name="key_isProgramMemory_tt">Zeichnet dieses ROM als Programmspeicher aus. Es kann damit von einer externen IDE beschrieben werden.</string>
<string name="lib_Logic">Logisch</string> <string name="lib_Logic">Logisch</string>
<string name="lib_arithmetic">Arithmetik</string> <string name="lib_arithmetic">Arithmetik</string>
<string name="lib_flipFlops">FlipFlops</string> <string name="lib_flipFlops">FlipFlops</string>
@ -384,7 +386,8 @@ Die Icons stammen aus dem Tango Desktop Project.</string>
<string name="msg_pinMap_outputs">Ausgänge</string> <string name="msg_pinMap_outputs">Ausgänge</string>
<string name="msg_pinMap_pin_N_is_N">Pin {0}: {1}</string> <string name="msg_pinMap_pin_N_is_N">Pin {0}: {1}</string>
<string name="msg_restartNeeded">Die Änderung erfordert einen Neustart!</string> <string name="msg_restartNeeded">Die Änderung erfordert einen Neustart!</string>
<string name="msg_noRomFound">Kein ROM im Model gefunden! Im ROM muss Automatisches Laden eingeschaltet sein!</string> <string name="msg_noRomFound">Kein ROM im Model gefunden! Ein ROM muss als Programmspeicher gewählt werden!</string>
<string name="msg_moreThenOneRomFound">Mehr als einen Programmspeicher gefunden. Es darf nur einen Programmspeicher geben.</string>
<string name="msg_enterAnExpression">Geben Sie einen Ausdruck ein:</string> <string name="msg_enterAnExpression">Geben Sie einen Ausdruck ein:</string>
<string name="msg_runningTestError">Fehler bei der Ausführung der Tests:</string> <string name="msg_runningTestError">Fehler bei der Ausführung der Tests:</string>
<string name="msg_testResult">Testergebnis</string> <string name="msg_testResult">Testergebnis</string>

View File

@ -238,6 +238,8 @@ To analyse you can run the circuit in single gate step mode.</string>
<string name="key_Testdata">Testdata</string> <string name="key_Testdata">Testdata</string>
<string name="key_graphicWidth">Width in pixels</string> <string name="key_graphicWidth">Width in pixels</string>
<string name="key_graphicHeight">Height in pixels</string> <string name="key_graphicHeight">Height in pixels</string>
<string name="key_isProgramMemory">Program Memory</string>
<string name="key_isProgramMemory_tt">Makes this ROM to program memory. So it can be accessed by an external IDE.</string>
<string name="lib_Logic">Logic</string> <string name="lib_Logic">Logic</string>
<string name="lib_arithmetic">Arithmetic</string> <string name="lib_arithmetic">Arithmetic</string>
<string name="lib_flipFlops">FlipFlops</string> <string name="lib_flipFlops">FlipFlops</string>
@ -383,7 +385,8 @@ The icons are taken from the Tango Desktop Project.</string>
<string name="msg_pinMap_outputs">Onputs</string> <string name="msg_pinMap_outputs">Onputs</string>
<string name="msg_pinMap_pin_N_is_N">Pin {0}: {1}</string> <string name="msg_pinMap_pin_N_is_N">Pin {0}: {1}</string>
<string name="msg_restartNeeded">Change needs a restart to take effect!</string> <string name="msg_restartNeeded">Change needs a restart to take effect!</string>
<string name="msg_noRomFound">No ROM found! ROM needs to be set to auto reload mode.</string> <string name="msg_noRomFound">No ROM found! ROM needs to be set to be program memory.</string>
<string name="msg_moreThenOneRomFound">More then one ROM found! Only one ROM must be set to be program memory.</string>
<string name="msg_errorFileNotFound">Could not find file: {0}</string> <string name="msg_errorFileNotFound">Could not find file: {0}</string>
<string name="msg_remoteUnknownCommand">Command {0} unknown!</string> <string name="msg_remoteUnknownCommand">Command {0} unknown!</string>
<string name="msg_enterAnExpression">Enter an expression:</string> <string name="msg_enterAnExpression">Enter an expression:</string>