net.mograsim.logic.model.examples
Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: org.eclipse.osgi,
- net.mograsim.machine;bundle-version="0.1.0";visibility:=reexport
+ net.mograsim.machine;bundle-version="0.1.0";visibility:=reexport,
+ net.mograsim.logic.core
Automatic-Module-Name: net.mograsim.logic.model.am2900
Bundle-Vendor: Mograsim Team
Bundle-Activator: net.mograsim.logic.model.am2900.Am2900Loader
import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator;
import net.mograsim.machine.Machine;
import net.mograsim.machine.MachineDefinition;
+import net.mograsim.machine.MainMemory;
import net.mograsim.machine.Register;
+import net.mograsim.machine.mi.MicroInstructionMemory;
+import net.mograsim.machine.mi.StandardMicroInstructionMemory;
+import net.mograsim.machine.standard.memory.WordAddressableMemory;
public class Am2900Machine implements Machine
{
private ViewModelModifiable viewModel;
private Timeline timeline;
private Clock clock;
+ private MainMemory mainMemory;
+ private MicroInstructionMemory instMemory;
public Am2900Machine(Am2900MachineDefinition am2900MachineDefinition)
{
params.gateProcessTime = 50;
params.wireTravelTime = 10;
timeline = ViewLogicModelAdapter.convert(viewModel, params);
+
+ mainMemory = new WordAddressableMemory(am2900MachineDefinition.getMainMemoryDefinition());
+ instMemory = new StandardMicroInstructionMemory(am2900MachineDefinition.getMicroInstructionMemoryDefinition());
}
@Override
}
+ @Override
+ public MainMemory getMainMemory()
+ {
+ return mainMemory;
+ }
+
+ @Override
+ public MicroInstructionMemory getMicroInstructionMemory()
+ {
+ return instMemory;
+ }
+
}
import net.mograsim.machine.MachineDefinition;
import net.mograsim.machine.MainMemoryDefinition;
import net.mograsim.machine.Register;
+import net.mograsim.machine.mi.MicroInstructionMemoryDefinition;
public class Am2900MachineDefinition implements MachineDefinition
{
private MainMemoryDefinition memoryDefinition = new Am2900MainMemoryDefinition();
+ private MicroInstructionMemoryDefinition microInstMemoryDefinition = new Am2900MicroInstructionMemoryDefinition();
@Override
public Machine createNew()
return memoryDefinition;
}
+ @Override
+ public MicroInstructionMemoryDefinition getMicroInstructionMemoryDefinition()
+ {
+ return microInstMemoryDefinition;
+ }
}
--- /dev/null
+package net.mograsim.logic.model.am2900.machine;
+
+import net.mograsim.logic.core.types.Bit;
+import net.mograsim.logic.core.types.BitVector;
+import net.mograsim.machine.mi.MicroInstructionDefinition;
+import net.mograsim.machine.mi.parameters.BooleanClassification;
+import net.mograsim.machine.mi.parameters.IntegerClassification;
+import net.mograsim.machine.mi.parameters.MnemonicFamily;
+import net.mograsim.machine.mi.parameters.MnemonicFamily.MnemonicPair;
+import net.mograsim.machine.mi.parameters.ParameterClassification;
+
+public class Am2900MicroInstructionDefinition implements MicroInstructionDefinition
+{
+ private final static MnemonicFamily am2910Instructions = new MnemonicFamily(new MnemonicPair("X", BitVector.of(Bit.ZERO, 4))/* TODO */);
+ private final static MnemonicFamily am2904StatusInstructions = new MnemonicFamily(
+ new MnemonicPair("X", BitVector.of(Bit.ZERO, 4))/* TODO */);
+ private final static MnemonicFamily am2904ShiftInstructions = new MnemonicFamily(
+ new MnemonicPair("X", BitVector.of(Bit.ZERO, 4))/* TODO */);
+ private final static MnemonicFamily am2904CarryInstructions = new MnemonicFamily(
+ new MnemonicPair("X", BitVector.of(Bit.ZERO, 4))/* TODO */);
+ private final static MnemonicFamily am2901DestInstructions = new MnemonicFamily(
+ new MnemonicPair("X", BitVector.of(Bit.ZERO, 4))/* TODO */);
+ private final static MnemonicFamily am2901FuncInstructions = new MnemonicFamily(
+ new MnemonicPair("X", BitVector.of(Bit.ZERO, 4))/* TODO */);
+ private final static MnemonicFamily am2901SrcInstructions = new MnemonicFamily(
+ new MnemonicPair("X", BitVector.of(Bit.ZERO, 4))/* TODO */);
+ private final static MnemonicFamily interruptInstructions = new MnemonicFamily(
+ new MnemonicPair("X", BitVector.of(Bit.ZERO, 4))/* TODO */);
+ private final static BooleanClassification hL = new BooleanClassification("H", "L");
+ private final static BooleanClassification registerSelect = new BooleanClassification("MR", "IR");
+ private final static IntegerClassification register = new IntegerClassification(4);
+
+ private final static ParameterClassification[] classes = { new BooleanClassification("R", "W"), hL, new BooleanClassification("H", "E"),
+ new BooleanClassification("H", "I"), new BooleanClassification("H", "E"), hL, new IntegerClassification(11), am2910Instructions,
+ new BooleanClassification("PS", "C"), am2904StatusInstructions, hL, hL, am2904ShiftInstructions, am2904CarryInstructions,
+ new BooleanClassification("H", "DB"), new BooleanClassification("H", "AB"), registerSelect, register, registerSelect, register,
+ am2901DestInstructions, am2901FuncInstructions, am2901SrcInstructions, new IntegerClassification(16),
+ new BooleanClassification("D", "K"), interruptInstructions, new BooleanClassification("Dis", "IE") };
+
+ @Override
+ public ParameterClassification[] getParameterClassifications()
+ {
+ return classes;
+ }
+
+ @Override
+ public ParameterClassification getParameterClassification(int index)
+ {
+ return classes[index];
+ }
+
+}
--- /dev/null
+package net.mograsim.logic.model.am2900.machine;
+
+import net.mograsim.machine.mi.MicroInstructionDefinition;
+import net.mograsim.machine.mi.MicroInstructionMemoryDefinition;
+
+public class Am2900MicroInstructionMemoryDefinition implements MicroInstructionMemoryDefinition
+{
+
+ @Override
+ public int getMemoryAddressBits()
+ {
+ return 12;
+ }
+
+ @Override
+ public long getMinimalAddress()
+ {
+ return 0;
+ }
+
+ @Override
+ public long getMaximalAddress()
+ {
+ return 4096;
+ }
+
+ @Override
+ public MicroInstructionDefinition getMicroInstructionDefinition()
+ {
+ return new Am2900MicroInstructionDefinition();
+ }
+}
import net.mograsim.logic.core.timeline.Timeline;
import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.model.model.ViewModel;
+import net.mograsim.machine.mi.MicroInstructionMemory;
public interface Machine {
MachineDefinition getDefinition();
void setRegister(Register r, BitVector value);
Timeline getTimeline();
+
+ MainMemory getMainMemory();
+
+ MicroInstructionMemory getMicroInstructionMemory();
+
}
import java.util.Set;
+import net.mograsim.machine.mi.MicroInstructionMemoryDefinition;
+
public interface MachineDefinition {
/**
* @author Christian Femers
*/
MainMemoryDefinition getMainMemoryDefinition();
+
+ /**
+ * Returns the definition of the machines instruction memory.
+ *
+ * @return the {@link InstructionMemoryDefinition} that defines the instruction memory.
+ */
+ MicroInstructionMemoryDefinition getMicroInstructionMemoryDefinition();
+
}
public default long size()
{
MemoryDefinition def = getDefinition();
- return Long.max(0, def.getMaximalAddress() - def.getMinimalAddress());
+ return Long.max(0, def.getMaximalAddress() - def.getMinimalAddress() + 1);
}
/**
package net.mograsim.machine.mi;
+import java.math.BigInteger;
+
+import net.mograsim.machine.mi.parameters.IntegerClassification;
+import net.mograsim.machine.mi.parameters.IntegerImmediate;
import net.mograsim.machine.mi.parameters.MicroInstructionParameter;
+import net.mograsim.machine.mi.parameters.MnemonicFamily;
import net.mograsim.machine.mi.parameters.ParameterClassification;
+import net.mograsim.machine.mi.parameters.MicroInstructionParameter.ParameterType;
public interface MicroInstructionDefinition
{
return getParameterClassifications().length;
}
+ public default MicroInstruction createDefaultInstruction()
+ {
+ int size = size();
+ MicroInstructionParameter[] params = new MicroInstructionParameter[size];
+ ParameterClassification[] classes = getParameterClassifications();
+ for(int i = 0; i < size; i++)
+ {
+ MicroInstructionParameter newParam;
+ ParameterClassification classification = classes[i];
+ ParameterType type = classification.getExpectedType();
+ switch(type)
+ {
+ case BOOLEAN_IMMEDIATE:
+ case MNEMONIC:
+ newParam = ((MnemonicFamily) classification).get(0);
+ break;
+ case INTEGER_IMMEDIATE:
+ newParam = new IntegerImmediate(BigInteger.valueOf(0), ((IntegerClassification) classification).getExpectedBits());
+ break;
+ default:
+ throw new IllegalStateException("Unknown ParameterType " + type);
+ }
+ params[i] = newParam;
+ }
+ return new StandardMicroInstruction(params);
+ }
+
public static MicroInstructionDefinition create(ParameterClassification... classes)
{
return new StandardMicroInstructionDefinition(classes);
package net.mograsim.machine.mi;
import net.mograsim.machine.Memory;
-import net.mograsim.machine.MemoryDefinition;
public interface MicroInstructionMemory extends Memory<MicroInstruction>
{
- public static MicroInstructionMemory create(MemoryDefinition def)
- {
- return new StandardMicroInstructionMemory(def);
- }
+ public MicroInstructionMemoryDefinition getDefinition();
}
--- /dev/null
+package net.mograsim.machine.mi;
+
+import net.mograsim.machine.MemoryDefinition;
+
+public interface MicroInstructionMemoryDefinition extends MemoryDefinition
+{
+ MicroInstructionDefinition getMicroInstructionDefinition();
+}
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-import net.mograsim.logic.core.types.BitVector;
import net.mograsim.machine.MemoryDefinition;
-import net.mograsim.machine.mi.parameters.BooleanClassification;
-import net.mograsim.machine.mi.parameters.IntegerClassification;
-import net.mograsim.machine.mi.parameters.IntegerImmediate;
import net.mograsim.machine.mi.parameters.MicroInstructionParameter;
-import net.mograsim.machine.mi.parameters.MnemonicFamily;
-import net.mograsim.machine.mi.parameters.MnemonicFamily.MnemonicPair;
import net.mograsim.machine.mi.parameters.ParameterClassification;
public class MicroInstructionMemoryParser
{
- public static MicroInstructionMemory parseMemory(MicroInstructionDefinition definition, String input) throws IOException
+ public static void parseMemory(final MicroInstructionMemory memory, String inputPath) throws IOException
{
- try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(input))))
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(inputPath))))
{
- return parseMemory(definition, reader);
+ parseMemory(memory, reader);
}
}
- public static MicroInstructionMemory parseMemory(MicroInstructionDefinition definition, BufferedReader input)
+ public static void parseMemory(final MicroInstructionMemory memory, BufferedReader input)
{
- List<MicroInstruction> instructions = new ArrayList<>();
+ MicroInstructionMemoryDefinition def = memory.getDefinition();
+ MicroInstructionDefinition miDef = def.getMicroInstructionDefinition();
+
+ long minAddr = def.getMinimalAddress();
+ long maxAddr = def.getMaximalAddress();
+
+ String line;
+ long i = minAddr;
try
{
- String line;
- while (input.ready() && !"".equals((line = input.readLine())))
- instructions.add(parse(definition, line));
+ for (; i <= maxAddr && input.ready() && !"".equals((line = input.readLine())); i++)
+ memory.setCell(i, parse(miDef, line));
} catch (IOException e)
{
e.printStackTrace();
}
-
- int maxAddress = instructions.size() - 1;
- MicroInstructionMemory memory = MicroInstructionMemory
- .create(MemoryDefinition.create((int) Math.ceil(Math.log(maxAddress)), 0, maxAddress));
- int i = 0;
- for (MicroInstruction inst : instructions)
- memory.setCell(i++, inst);
- return memory;
+
+ for(; i <= maxAddr; i++)
+ memory.setCell(i, miDef.createDefaultInstruction());
}
-
+
public static MicroInstruction parse(MicroInstructionDefinition definition, String toParse)
{
int size = definition.size();
}
}
- public static void write(MicroInstructionMemory memory, String output) throws IOException
+ public static void write(MicroInstructionMemory memory, String outputPath) throws IOException
{
- try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(output)))
+ try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(outputPath)))
{
write(memory, writer);
}
import java.util.HashSet;
-import net.mograsim.machine.MemoryDefinition;
import net.mograsim.machine.MemoryObserver;
import net.mograsim.machine.standard.memory.MemoryException;
-class StandardMicroInstructionMemory implements MicroInstructionMemory
+public class StandardMicroInstructionMemory implements MicroInstructionMemory
{
private MicroInstruction[] data;
- private MemoryDefinition definition;
+ private MicroInstructionMemoryDefinition definition;
private HashSet<MemoryObserver> observers = new HashSet<>();
- StandardMicroInstructionMemory(MemoryDefinition definition)
+ public StandardMicroInstructionMemory(MicroInstructionMemoryDefinition definition)
{
if(definition.size() > Integer.MAX_VALUE)
throw new MemoryException("Size of MicroInstructionMemory must be an int, not a long");
@Override
public MicroInstruction getCell(long address)
{
- return data[translate(address)];
+ int translatedAddress = translate(address);
+ MicroInstruction actual = data[translatedAddress];
+ if(actual == null)
+ actual = data[translatedAddress] = definition.getMicroInstructionDefinition().createDefaultInstruction();
+ return actual;
}
@Override
}
@Override
- public MemoryDefinition getDefinition()
+ public MicroInstructionMemoryDefinition getDefinition()
{
return definition;
}
--- /dev/null
+package net.mograsim.plugin;
+
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+
+import net.mograsim.logic.model.am2900.machine.Am2900Machine;
+import net.mograsim.logic.model.am2900.machine.Am2900MachineDefinition;
+import net.mograsim.machine.Machine;
+import net.mograsim.machine.MachineRegistry;
+
+public class MachineContext
+{
+ private Machine machine;
+ private Set<ContextObserver> observers;
+ private static MachineContext instance;
+
+ private MachineContext()
+ {
+ observers = new HashSet<>();
+ }
+
+ public static MachineContext getInstance()
+ {
+ if (instance == null)
+ {
+ instance = new MachineContext();
+ instance.setMachine(new Am2900Machine((Am2900MachineDefinition) MachineRegistry.getinstalledMachines().get("Am2900")));
+ }
+ return instance;
+ }
+
+ public Machine getMachine()
+ {
+ return machine;
+ }
+
+ public void setMachine(Machine machine)
+ {
+ this.machine = machine;
+ notifyObservers(machine);
+ }
+
+ public void registerObserver(ContextObserver ob)
+ {
+ observers.add(ob);
+ ob.setMachine(Optional.ofNullable(machine));
+ }
+
+ public void deregisterObserver(ContextObserver ob)
+ {
+ observers.remove(ob);
+ }
+
+ private void notifyObservers(Machine machine)
+ {
+ observers.forEach(ob -> ob.setMachine(Optional.ofNullable(machine)));
+ }
+
+ @FunctionalInterface
+ public static interface ContextObserver
+ {
+ void setMachine(Optional<Machine> machine);
+ }
+}
package net.mograsim.plugin.tables.memory;
import java.math.BigInteger;
+import java.util.Optional;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.ViewPart;
+import net.mograsim.machine.Machine;
import net.mograsim.machine.MainMemory;
import net.mograsim.machine.MainMemoryDefinition;
import net.mograsim.machine.standard.memory.WordAddressableMemory;
+import net.mograsim.plugin.MachineContext;
+import net.mograsim.plugin.MachineContext.ContextObserver;
import net.mograsim.plugin.asm.AsmNumberUtil;
import net.mograsim.plugin.tables.DisplaySettings;
import net.mograsim.plugin.tables.NumberColumnLabelProvider;
import net.mograsim.plugin.tables.RadixSelector;
-public class MemoryView extends ViewPart
+public class MemoryView extends ViewPart implements ContextObserver
{
private TableViewer viewer;
private MemoryTableContentProvider provider;
private DisplaySettings displaySettings;
private String addressFormat;
- @SuppressWarnings("unused")
@Override
public void createPartControl(Composite parent)
{
GridLayout layout = new GridLayout(6, false);
parent.setLayout(layout);
+
+ createHeader(parent);
+ createViewer(parent);
+
+ displaySettings.addObserver(() -> viewer.refresh());
+
+ setupContextBinding();
+ }
+
+ @SuppressWarnings("unused")
+ private void createHeader(Composite parent)
+ {
Label fromLabel = new Label(parent, SWT.NONE);
fromLabel.setText("Address: ");
Text fromText = new Text(parent, SWT.BORDER | SWT.SEARCH);
}
});
new RadixSelector(parent, displaySettings);
- createViewer(parent);
-
- displaySettings.addObserver(() -> viewer.refresh());
}
private void createViewer(Composite parent)
table.setLinesVisible(true);
viewer.setUseHashlookup(true);
viewer.setContentProvider(provider);
- setMemoryBinding(new WordAddressableMemory(MainMemoryDefinition.create(8, 8, 8L, Long.MAX_VALUE)));
+ bindMainMemory(new WordAddressableMemory(MainMemoryDefinition.create(8, 8, 8L, Long.MAX_VALUE)));
getSite().setSelectionProvider(viewer);
GridData gd = new GridData();
viewer.getControl().setFocus();
}
- public void setMemoryBinding(MainMemory m)
+ private void bindMainMemory(MainMemory m)
{
int hexAddressLength = Long.toUnsignedString(m.getDefinition().getMaximalAddress(), 16).length();
addressFormat = "0x%0" + hexAddressLength + "X";
viewer.setInput(m);
}
+
+ private void setupContextBinding()
+ {
+ MachineContext.getInstance().registerObserver(this);
+ }
+
+ @Override
+ public void setMachine(Optional<Machine> machine)
+ {
+ if (machine.isPresent())
+ bindMainMemory(machine.get().getMainMemory());
+ }
}
import java.io.File;
import java.io.IOException;
+import java.util.Optional;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.part.ViewPart;
+import net.mograsim.machine.Machine;
import net.mograsim.machine.mi.MicroInstructionDefinition;
import net.mograsim.machine.mi.MicroInstructionMemory;
import net.mograsim.machine.mi.MicroInstructionMemoryParseException;
import net.mograsim.machine.mi.MicroInstructionMemoryParser;
import net.mograsim.machine.mi.parameters.ParameterClassification;
+import net.mograsim.plugin.MachineContext;
+import net.mograsim.plugin.MachineContext.ContextObserver;
import net.mograsim.plugin.asm.AsmNumberUtil.NumberType;
import net.mograsim.plugin.tables.DisplaySettings;
import net.mograsim.plugin.tables.RadixSelector;
import net.mograsim.plugin.util.DropDownMenu;
import net.mograsim.plugin.util.DropDownMenu.DropDownEntry;
-public class InstructionView extends ViewPart
+public class InstructionView extends ViewPart implements ContextObserver
{
private String saveLoc = null;
private TableViewer viewer;
viewer.getTable().setLayoutData(viewerData);
displaySettings.addObserver(() -> viewer.refresh());
+ MachineContext.getInstance().registerObserver(this);
}
@SuppressWarnings("unused")
saveLoc = d.getFilterPath() + File.separator + filename;
}
- public void bindMicroprogramMemory(MicroInstructionMemory memory)
+ public void bindMicroInstructionMemory(MicroInstructionMemory memory)
{
+ deleteColumns();
this.memory = memory;
viewer.setInput(memory);
+ this.miDef = memory.getDefinition().getMicroInstructionDefinition();
+ createColumns();
}
- public void bindMicroInstructionDef(MicroInstructionDefinition miDef)
+ private void deleteColumns()
{
- this.miDef = miDef;
- createColumns();
+ for (TableViewerColumn col : columns)
+ col.getColumn().dispose();
}
private void createColumns()
{
- for (TableViewerColumn col : columns)
- col.getColumn().dispose();
int size = miDef.size();
int bit = 0;
columns = new TableViewerColumn[size];
}
try
{
- MicroInstructionMemory newMemory = MicroInstructionMemoryParser.parseMemory(miDef, file);
- bindMicroprogramMemory(newMemory);
+ MicroInstructionMemoryParser.parseMemory(memory, file);
+ viewer.refresh();
saveLoc = file;
}
catch (IOException | MicroInstructionMemoryParseException e)
{
viewer.getControl().setFocus();
}
+
+ @Override
+ public void setMachine(Optional<Machine> machine)
+ {
+ if (machine.isPresent())
+ {
+ Machine actualMachine = machine.get();
+ bindMicroInstructionMemory(actualMachine.getMicroInstructionMemory());
+ }
+ }
}