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>
<elementName>ROM</elementName>
<elementAttributes>
<entry>
<string>isProgramMemory</string>
<boolean>true</boolean>
</entry>
<entry>
<string>Bits</string>
<int>16</int>

View File

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

View File

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

View File

@ -157,6 +157,12 @@ public final class Keys {
public static final Key<Boolean> SHOW_LISTING
= 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
*/

View File

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

View File

@ -1,5 +1,7 @@
package de.neemann.digital.gui;
import de.neemann.digital.gui.remote.RemoteException;
import java.io.File;
/**
@ -13,28 +15,37 @@ public interface DigitalRemoteInterface {
* Loads the given file to the data rom
*
* @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
* @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
* @throws RemoteException RemoteException
*/
void doSingleStep();
void doSingleStep() throws RemoteException;
/**
* runs model to the next BRK instruction
* @throws RemoteException RemoteException
*/
void runToBreak();
void runToBreak() throws RemoteException;
/**
* 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.io.In;
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.wiring.Clock;
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.TestResultDialog;
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.state.State;
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))
if (rom.showListing())
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) {
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
//**********************
@Override
public boolean loadRom(File file) {
boolean found = false;
public VisualElement getProgramRomFromCircuit() throws RemoteException {
VisualElement rom = null;
ArrayList<VisualElement> el = circuitComponent.getCircuit().getElements();
for (VisualElement e : el) {
if (e.equalsDescription(ROM.DESCRIPTION)) {
ElementAttributes attr = e.getElementAttributes();
if (attr.get(Keys.AUTO_RELOAD_ROM)) {
attr.setFile(ROM.LAST_DATA_FILE_KEY, file);
found = true;
if (attr.get(Keys.IS_PROGRAM_MEMORY)) {
if (rom != null)
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
@ -987,11 +1005,23 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E
runToBreakAction.actionPerformed(null);
}
private void setDebug(boolean debug) throws RemoteException {
VisualElement rom = getProgramRomFromCircuit();
rom.getElementAttributes().set(Keys.SHOW_LISTING, debug);
}
@Override
public boolean start() {
public void debug() throws RemoteException {
setDebug(true);
runModelState.enter(false);
circuitComponent.hasChanged();
return true;
}
@Override
public void start() throws RemoteException {
setDebug(false);
runModelState.enter(true);
circuitComponent.hasChanged();
}
@Override

View File

@ -24,6 +24,7 @@ public class ProbeDialog extends JDialog implements ModelStateObserver {
private final ModelEvent type;
private final SignalTableModel tableModel;
private boolean tableUpdateEnable = true;
/**
* Creates a new instance
@ -73,7 +74,18 @@ public class ProbeDialog extends JDialog implements ModelStateObserver {
@Override
public void handleEvent(ModelEvent event) {
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;
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.memory.ROM;
import de.neemann.digital.gui.sync.Sync;
import de.neemann.digital.lang.Lang;
import javax.swing.*;
@ -17,27 +21,27 @@ import java.io.IOException;
*
* @author hneemann
*/
public class ROMListingDialog extends JDialog implements Observer {
public class ROMListingDialog extends JDialog implements Observer, ModelStateObserver {
private final ROM rom;
private final Listing listing;
private final JList<String> list;
private int lastAddr = -1;
private boolean updateViewEnable = true;
/**
* Creates a new instance
*
* @param parent the parent frame
* @param rom the rom element
* @param model the model
* @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);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
this.rom = rom;
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setAlwaysOnTop(true);
this.rom = rom;
File filename = rom.getHexFile();
String name = filename.getName();
@ -55,12 +59,18 @@ public class ROMListingDialog extends JDialog implements Observer {
addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent e) {
rom.addObserver(ROMListingDialog.this);
modelSync.access(() -> {
rom.addObserver(ROMListingDialog.this);
model.addObserver(ROMListingDialog.this);
});
}
@Override
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() {
int addr = (int) rom.getRomAddress();
if (addr != lastAddr) {
updateView(addr);
lastAddr = addr;
}
}
private void updateView(int addr) {
if (updateViewEnable) {
Integer line = listing.getLine(addr);
if (line != null) {
SwingUtilities.invokeLater(() -> {
@ -83,8 +100,20 @@ public class ROMListingDialog extends JDialog implements Observer {
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);
}
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) {
case "step":
digitalRemoteInterface.doSingleStep();
break;
case "start":
if (!digitalRemoteInterface.start())
return Lang.get("msg_errorCreatingModel");
digitalRemoteInterface.start();
break;
case "debug":
digitalRemoteInterface.debug();
break;
case "run":
digitalRemoteInterface.runToBreak();
@ -50,15 +57,10 @@ public class DigitalHandler implements HandlerInterface {
break;
case "load":
File file = new File(args);
if (file.exists()) {
if (!digitalRemoteInterface.loadRom(file))
return Lang.get("msg_noRomFound");
} else
return Lang.get("msg_errorFileNotFound", args);
digitalRemoteInterface.loadRom(file);
break;
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_graphicWidth">Breite 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_arithmetic">Arithmetik</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_pin_N_is_N">Pin {0}: {1}</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_runningTestError">Fehler bei der Ausführung der Tests:</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_graphicWidth">Width 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_arithmetic">Arithmetic</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_pin_N_is_N">Pin {0}: {1}</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_remoteUnknownCommand">Command {0} unknown!</string>
<string name="msg_enterAnExpression">Enter an expression:</string>