The ROM from the assembler is now loaded to the model instead of loading it to the circuit.
This commit is contained in:
hneemann 2016-12-17 10:27:11 +01:00
parent 9b2f3b5334
commit 0213a358b0
5 changed files with 105 additions and 67 deletions

View File

@ -11,27 +11,21 @@ import java.io.File;
*/ */
public interface DigitalRemoteInterface { public interface DigitalRemoteInterface {
/**
* Loads the given file to the data rom
*
* @param file the file to load
* @throws RemoteException RemoteException
*/
void loadRom(File file) throws RemoteException;
/** /**
* Starts the model * Starts the model
* *
* @param file the file to load to program rom
* @throws RemoteException RemoteException * @throws RemoteException RemoteException
*/ */
void start() throws RemoteException; void start(File file) throws RemoteException;
/** /**
* Starts the model in debug mode * Starts the model in debug mode
* *
* @param file the file to load to program rom
* @throws RemoteException RemoteException * @throws RemoteException RemoteException
*/ */
void debug() throws RemoteException; void debug(File file) throws RemoteException;
/** /**
* performs a single step * performs a single step

View File

@ -6,10 +6,11 @@ import de.neemann.digital.analyse.TruthTable;
import de.neemann.digital.builder.PinMap; import de.neemann.digital.builder.PinMap;
import de.neemann.digital.builder.PinMapException; import de.neemann.digital.builder.PinMapException;
import de.neemann.digital.core.*; import de.neemann.digital.core.*;
import de.neemann.digital.core.element.*; import de.neemann.digital.core.element.ElementAttributes;
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.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;
@ -695,7 +696,7 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E
@Override @Override
public void enter() { public void enter() {
super.enter(); super.enter();
if (createAndStartModel(false, ModelEvent.MICROSTEP)) if (createAndStartModel(false, ModelEvent.MICROSTEP, null))
circuitComponent.setManualChangeObserver(new MicroStepObserver(model)); circuitComponent.setManualChangeObserver(new MicroStepObserver(model));
} }
}); });
@ -710,7 +711,7 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E
model = null; model = null;
} }
private boolean createAndStartModel(boolean globalRunClock, ModelEvent updateEvent) { private boolean createAndStartModel(boolean globalRunClock, ModelEvent updateEvent, ModelModifier modelModifier) {
try { try {
circuitComponent.removeHighLighted(); circuitComponent.removeHighLighted();
@ -759,6 +760,9 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E
if (settings.get(Keys.SHOW_DATA_GRAPH_MICRO)) if (settings.get(Keys.SHOW_DATA_GRAPH_MICRO))
windowPosManager.register("datasetMicro", new DataSetDialog(this, model, true, ordering, modelSync)).setVisible(true); windowPosManager.register("datasetMicro", new DataSetDialog(this, model, true, ordering, modelSync)).setVisible(true);
if (modelModifier != null)
modelModifier.preInit(model);
model.init(); model.init();
return true; return true;
@ -963,12 +967,12 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E
private class RunModelState extends State { private class RunModelState extends State {
@Override @Override
public void enter() { public void enter() {
enter(true); enter(true, null);
} }
void enter(boolean runRealTime) { void enter(boolean runRealTime, ModelModifier modelModifier) {
super.enter(); super.enter();
if (createAndStartModel(runRealTime, ModelEvent.STEP)) if (createAndStartModel(runRealTime, ModelEvent.STEP, modelModifier))
circuitComponent.setManualChangeObserver(new FullStepObserver(model)); circuitComponent.setManualChangeObserver(new FullStepObserver(model));
} }
} }
@ -977,35 +981,23 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E
// remote interface start // remote interface start
//*********************** //***********************
private VisualElement getProgramRomFromCircuit() throws RemoteException { private static class AddressPicker {
VisualElement rom = null;
ArrayList<VisualElement> el = circuitComponent.getCircuit().getElements(); private long addr;
for (VisualElement e : el) {
if (e.equalsDescription(ROM.DESCRIPTION)) { private void getProgRomAddr(Model model) {
ElementAttributes attr = e.getElementAttributes(); ArrayList<ROM> roms = model.getProgRoms();
if (attr.get(Keys.IS_PROGRAM_MEMORY)) { if (roms.size() == 1)
if (rom != null) addr = roms.get(0).getRomAddress();
throw new RemoteException(Lang.get("msg_moreThenOneRomFound")); else
rom = e; addr = -1;
}
}
} }
if (rom == null)
throw new RemoteException(Lang.get("msg_noRomFound"));
return rom; String getAddrString() {
} if (addr < 0)
return null;
@Override else
public void loadRom(File file) throws RemoteException { return Long.toHexString(addr);
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());
} }
} }
@ -1013,6 +1005,7 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E
public String doSingleStep() throws RemoteException { public String doSingleStep() throws RemoteException {
if (model != null && !realtimeClockRunning) { if (model != null && !realtimeClockRunning) {
try { try {
AddressPicker addressPicker = new AddressPicker();
SwingUtilities.invokeAndWait(() -> { SwingUtilities.invokeAndWait(() -> {
ArrayList<Clock> cl = model.getClocks(); ArrayList<Clock> cl = model.getClocks();
if (cl.size() == 1) { if (cl.size() == 1) {
@ -1025,60 +1018,54 @@ public class Main extends JFrame implements ClosingWindowListener.ConfirmSave, E
model.doStep(); model.doStep();
} }
circuitComponent.hasChanged(); circuitComponent.hasChanged();
addressPicker.getProgRomAddr(model);
} catch (NodeException e) { } catch (NodeException e) {
showErrorAndStopModel(Lang.get("err_remoteExecution"), e); showErrorAndStopModel(Lang.get("err_remoteExecution"), e);
} }
} }
}); });
return getProgRomAddr(); return addressPicker.getAddrString();
} catch (InterruptedException | InvocationTargetException e) { } catch (InterruptedException | InvocationTargetException e) {
throw new RemoteException("error performing a single step "+e.getMessage()); throw new RemoteException("error performing a single step " + e.getMessage());
} }
} }
return null; return null;
} }
private String getProgRomAddr() {
ArrayList<ROM> roms = model.getProgRoms();
if (roms.size()==1)
return Long.toHexString(roms.get(0).getRomAddress());
return null;
}
@Override @Override
public String runToBreak() throws RemoteException { public String runToBreak() throws RemoteException {
try { try {
AddressPicker addressPicker = new AddressPicker();
SwingUtilities.invokeAndWait(() -> { SwingUtilities.invokeAndWait(() -> {
if (model != null && model.isFastRunModel() && !realtimeClockRunning) if (model != null && model.isFastRunModel() && !realtimeClockRunning)
runToBreakAction.actionPerformed(null); runToBreakAction.actionPerformed(null);
addressPicker.getProgRomAddr(model);
}); });
return getProgRomAddr(); return addressPicker.getAddrString();
} catch (InterruptedException | InvocationTargetException e) { } catch (InterruptedException | InvocationTargetException e) {
throw new RemoteException("error performing a run to break "+e.getMessage()); throw new RemoteException("error performing a run to break " + e.getMessage());
} }
} }
private void setDebug(boolean debug) throws RemoteException { private void setDebug(boolean debug) throws RemoteException {
VisualElement rom = getProgramRomFromCircuit();
//rom.getElementAttributes().set(Keys.SHOW_LISTING, debug);
settings.set(Keys.SHOW_DATA_TABLE, debug); settings.set(Keys.SHOW_DATA_TABLE, debug);
} }
@Override @Override
public void debug() throws RemoteException { public void debug(File romHex) throws RemoteException {
setDebug(true); setDebug(true);
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
runModelState.enter(false); runModelState.enter(false, new RomLoader(romHex));
circuitComponent.hasChanged(); circuitComponent.hasChanged();
}); });
} }
@Override @Override
public void start() throws RemoteException { public void start(File romHex) throws RemoteException {
setDebug(false); setDebug(false);
SwingUtilities.invokeLater(() -> { SwingUtilities.invokeLater(() -> {
windowPosManager.closeAll(); windowPosManager.closeAll();
runModelState.enter(true); runModelState.enter(true, new RomLoader(romHex));
circuitComponent.hasChanged(); circuitComponent.hasChanged();
}); });
} }

View File

@ -0,0 +1,18 @@
package de.neemann.digital.gui;
import de.neemann.digital.core.Model;
import de.neemann.digital.core.NodeException;
/**
* Modifier which can be used to modify the model while it is started
* Created by hneemann on 17.12.16.
*/
public interface ModelModifier {
/**
* Called before model.init() is called
*
* @param model the model
* @throws NodeException NodeException
*/
void preInit(Model model) throws NodeException;
}

View File

@ -0,0 +1,43 @@
package de.neemann.digital.gui;
import de.neemann.digital.core.Model;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.core.memory.DataField;
import de.neemann.digital.core.memory.ROM;
import de.neemann.digital.lang.Lang;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
/**
* A Modifier that loads a given rom file to the program memory of the model.
* Created by hneemann on 17.12.16.
*/
public class RomLoader implements ModelModifier {
private final File romHex;
/**
* Creates a new rom modifier
*
* @param romHex the file to load
*/
RomLoader(File romHex) {
this.romHex = romHex;
}
@Override
public void preInit(Model model) throws NodeException {
ArrayList<ROM> roms = model.getProgRoms();
if (roms.isEmpty())
throw new NodeException(Lang.get("msg_noRomFound"));
if (roms.size() > 1)
throw new NodeException(Lang.get("msg_moreThenOneRomFound"));
try {
roms.get(0).setData(new DataField(romHex));
} catch (IOException e) {
throw new NodeException(e.getMessage());
}
}
}

View File

@ -46,20 +46,16 @@ public class DigitalHandler implements HandlerInterface {
case "step": case "step":
return digitalRemoteInterface.doSingleStep(); return digitalRemoteInterface.doSingleStep();
case "start": case "start":
digitalRemoteInterface.start(); digitalRemoteInterface.start(new File(args));
return null; return null;
case "debug": case "debug":
digitalRemoteInterface.debug(); digitalRemoteInterface.debug(new File(args));
return null; return null;
case "run": case "run":
return digitalRemoteInterface.runToBreak(); return digitalRemoteInterface.runToBreak();
case "stop": case "stop":
digitalRemoteInterface.stop(); digitalRemoteInterface.stop();
return null; return null;
case "load":
File file = new File(args);
digitalRemoteInterface.loadRom(file);
return null;
default: default:
throw new RemoteException(Lang.get("msg_remoteUnknownCommand", command)); throw new RemoteException(Lang.get("msg_remoteUnknownCommand", command));
} }