Merge branch 'development' of https://gitlab.lrz.de/lrr-tum/students/eragp-misim...
authorFabian Stemmler <stemmler@in.tum.de>
Sat, 31 Aug 2019 14:52:37 +0000 (16:52 +0200)
committerFabian Stemmler <stemmler@in.tum.de>
Sat, 31 Aug 2019 14:52:37 +0000 (16:52 +0200)
41 files changed:
net.mograsim.machine/src/net/mograsim/machine/DefaultMainMemoryDefinition.java [deleted file]
net.mograsim.machine/src/net/mograsim/machine/GenericMemory.java [new file with mode: 0644]
net.mograsim.machine/src/net/mograsim/machine/MainMemory.java
net.mograsim.machine/src/net/mograsim/machine/MainMemoryDefinition.java
net.mograsim.machine/src/net/mograsim/machine/Memory.java
net.mograsim.machine/src/net/mograsim/machine/MemoryDefinition.java [new file with mode: 0644]
net.mograsim.machine/src/net/mograsim/machine/MicroInstruction.java [deleted file]
net.mograsim.machine/src/net/mograsim/machine/MicroInstructionDefinition.java [deleted file]
net.mograsim.machine/src/net/mograsim/machine/MicroprogramMemory.java [deleted file]
net.mograsim.machine/src/net/mograsim/machine/StandardMainMemoryDefinition.java [new file with mode: 0644]
net.mograsim.machine/src/net/mograsim/machine/StandardMemoryDefinition.java [new file with mode: 0644]
net.mograsim.machine/src/net/mograsim/machine/mi/MicroInstruction.java [new file with mode: 0644]
net.mograsim.machine/src/net/mograsim/machine/mi/MicroInstructionDefinition.java [new file with mode: 0644]
net.mograsim.machine/src/net/mograsim/machine/mi/MicroprogramMemory.java [new file with mode: 0644]
net.mograsim.machine/src/net/mograsim/machine/mi/MicroprogramMemoryParser.java [new file with mode: 0644]
net.mograsim.machine/src/net/mograsim/machine/mi/StandardMicroInstruction.java [new file with mode: 0644]
net.mograsim.machine/src/net/mograsim/machine/mi/StandardMicroInstructionDefinition.java [new file with mode: 0644]
net.mograsim.machine/src/net/mograsim/machine/mi/StandardMicroprogramMemory.java [new file with mode: 0644]
net.mograsim.machine/src/net/mograsim/machine/mi/parameters/BooleanClassification.java
net.mograsim.machine/src/net/mograsim/machine/mi/parameters/IntegerClassification.java
net.mograsim.machine/src/net/mograsim/machine/mi/parameters/MnemonicFamily.java
net.mograsim.machine/src/net/mograsim/machine/mi/parameters/ParameterClassification.java
net.mograsim.machine/src/net/mograsim/machine/mi/parameters/UnknownMnemonicException.java [new file with mode: 0644]
net.mograsim.machine/src/net/mograsim/machine/standard/memory/GUIMemoryWA.java
net.mograsim.machine/src/net/mograsim/machine/standard/memory/WordAddressableMemory.java
net.mograsim.machine/test/net/mograsim/machine/standard/memory/WordAddressableMemoryTest.java
net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryCellEditingSupport.java [deleted file]
net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryTableContentProvider.java [deleted file]
net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryTableRow.java [deleted file]
net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryView.java [deleted file]
net.mograsim.plugin.core/src/net/mograsim/plugin/memory/NumberCellEditorValidator.java [deleted file]
net.mograsim.plugin.core/src/net/mograsim/plugin/memory/NumberVerifyListener.java [deleted file]
net.mograsim.plugin.core/src/net/mograsim/plugin/tables/NumberCellEditingSupport.java [new file with mode: 0644]
net.mograsim.plugin.core/src/net/mograsim/plugin/tables/NumberCellEditorValidator.java [new file with mode: 0644]
net.mograsim.plugin.core/src/net/mograsim/plugin/tables/NumberColumnLabelProvider.java [new file with mode: 0644]
net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/DisplaySettings.java [new file with mode: 0644]
net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryCellEditingSupport.java [new file with mode: 0644]
net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryTableContentProvider.java [new file with mode: 0644]
net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryTableRow.java [new file with mode: 0644]
net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryView.java [new file with mode: 0644]
net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/NumberVerifyListener.java [new file with mode: 0644]

diff --git a/net.mograsim.machine/src/net/mograsim/machine/DefaultMainMemoryDefinition.java b/net.mograsim.machine/src/net/mograsim/machine/DefaultMainMemoryDefinition.java
deleted file mode 100644 (file)
index 2431b65..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-package net.mograsim.machine;
-
-public class DefaultMainMemoryDefinition implements MainMemoryDefinition {
-       private final int memoryAddressBits, cellWidth;
-       private final long minimalAddress, maximalAddress;
-       
-       public DefaultMainMemoryDefinition(int memoryAddressBits, int cellWidth, long minimalAddress, long maximalAddress)
-       {
-               super();
-               this.memoryAddressBits = memoryAddressBits;
-               this.cellWidth = cellWidth;
-               this.minimalAddress = minimalAddress;
-               this.maximalAddress = maximalAddress;
-       }
-
-       public DefaultMainMemoryDefinition(MainMemoryDefinition definition)
-       {
-               this(definition.getMemoryAddressBits(), definition.getCellWidth(), definition.getMinimalAddress(), definition.getMaximalAddress());
-       }
-
-       @Override
-       public int getMemoryAddressBits()
-       {
-               return memoryAddressBits;
-       }
-
-       @Override
-       public int getCellWidth()
-       {
-               return cellWidth;
-       }
-
-       @Override
-       public long getMinimalAddress()
-       {
-               return minimalAddress;
-       }
-
-       @Override
-       public long getMaximalAddress()
-       {
-               return maximalAddress;
-       }
-       
-}
diff --git a/net.mograsim.machine/src/net/mograsim/machine/GenericMemory.java b/net.mograsim.machine/src/net/mograsim/machine/GenericMemory.java
new file mode 100644 (file)
index 0000000..f01f9df
--- /dev/null
@@ -0,0 +1,119 @@
+package net.mograsim.machine;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+public abstract class GenericMemory<T> implements Memory<T>
+{
+       private final long minimalAddress, maximalAddress;
+       private final MemoryDefinition definition;
+       private final int pageSize = 64;
+       private Set<MemoryObserver> observers = new HashSet<>();
+
+       private HashMap<Long, Page> pages;
+
+       public GenericMemory(MemoryDefinition definition)
+       {
+               super();
+               this.definition = definition;
+               this.minimalAddress = definition.getMinimalAddress();
+               this.maximalAddress = definition.getMaximalAddress();
+               this.pages = new HashMap<>();
+       }
+       
+       private void inBoundsCheck(long address)
+       {
+               if (address < minimalAddress || address > maximalAddress)
+                       throw new IndexOutOfBoundsException(String.format("Memory address out of bounds! Minimum: %d Maximum: %d Actual: %d",
+                                       minimalAddress, maximalAddress, address));
+       }
+
+       private long page(long address)
+       {
+               return address / pageSize;
+       }
+       
+       private int offset(long address)
+       {
+               return (int) (address % pageSize);
+       }
+       
+       @Override
+       public void setCell(long address, T data)
+       {
+               inBoundsCheck(address);
+               long page = page(address);
+               int offset = offset(address);
+               Page p = pages.get(Long.valueOf(page));
+               if (p == null)
+                       pages.put(page, p = new Page());
+               p.setCell(offset, data);
+               notifyObservers(address);
+       }
+
+       @Override
+       public T getCell(long address)
+       {
+               inBoundsCheck(address);
+               long page = page(address);
+               int offset = offset(address);
+               Page p = pages.get(Long.valueOf(page));
+               if (p == null)
+                       return null;
+               return p.getCell(offset);
+       }
+
+       private class Page
+       {
+               private Object[] memory;
+
+               public Page()
+               {
+                       memory = new Object[pageSize];
+               }
+
+               public T getCell(int index)
+               {
+                       @SuppressWarnings("unchecked")
+                       T data = (T) memory[index];
+                       return data;
+               }
+
+               public void setCell(int index, T data)
+               {
+                       memory[index] = data;
+               }
+
+               @Override
+               public String toString()
+               {
+                       return Arrays.deepToString(memory);
+               }
+       }
+
+       @Override
+       public void registerObserver(MemoryObserver ob)
+       {
+               observers.add(ob);
+       }
+
+       @Override
+       public void deregisterObserver(MemoryObserver ob)
+       {
+               observers.remove(ob);
+       }
+
+       @Override
+       public void notifyObservers(long address)
+       {
+               observers.forEach(ob -> ob.update(address));
+       }
+       
+       @Override
+       public MemoryDefinition getDefinition()
+       {
+               return definition;
+       }
+}
index dcd3ee2..94140b7 100644 (file)
@@ -4,13 +4,11 @@ import java.math.BigInteger;
 
 import net.mograsim.logic.core.types.BitVector;
 
-public interface MainMemory extends Memory<BitVector> {
-       
+public interface MainMemory extends Memory<BitVector>
+{
        public BigInteger getCellAsBigInteger(long address);
+
        public void setCellAsBigInteger(long address, BigInteger word);
+
        public MainMemoryDefinition getDefinition();
-       public default long size()
-       {
-               return getDefinition().size();
-       }
 }
index f01d119..4f69673 100644 (file)
@@ -7,17 +7,8 @@ package net.mograsim.machine;
  * @author Christian Femers
  *
  */
-public interface MainMemoryDefinition {
-
-       /**
-        * The number of bits that the main memory uses to address cells. Note that this
-        * does not need to equal {@link MachineDefinition#getAddressBits()}.
-        * 
-        * @return the number of bits used to address a memory cell
-        * @author Christian Femers
-        */
-       int getMemoryAddressBits();
-
+public interface MainMemoryDefinition extends MemoryDefinition
+{
        /**
         * The width in bits of an addressable memory cell/unit. This is often 8 (= one
         * byte). The actual cells/lines of the memory may be a lot larger.
@@ -26,30 +17,9 @@ public interface MainMemoryDefinition {
         * @author Christian Femers
         */
        int getCellWidth();
-
-       /**
-        * The minimal address possible to address/use. This is usually 0.
-        * 
-        * @return the minimal possible address.
-        * @author Christian Femers
-        */
-       long getMinimalAddress();
-
-       /**
-        * The maximal address possible to address/use.
-        * 
-        * @return the maximal possible address as <b>unsigned long</b>
-        * @author Christian Femers
-        */
-       long getMaximalAddress();
        
-       /**
-        * The size of the MainMemory as the amount of addressable memory cells.
-        * 
-        * @return the amount of addressable memory cells
-        */
-       default long size()
+       public static MainMemoryDefinition create(int memoryAddressBits, int cellWidth, long minimalAddress, long maximalAddress)
        {
-               return getMaximalAddress() - getMinimalAddress();
+               return new StandardMainMemoryDefinition(memoryAddressBits, cellWidth, minimalAddress, maximalAddress);
        }
 }
index e421e47..58798c3 100644 (file)
@@ -16,7 +16,11 @@ public interface Memory<T>
         */
        public void setCell(long address, T data);
        
-       public long size();
+       public default long size()
+       {
+               MemoryDefinition def = getDefinition();
+               return Long.max(0, def.getMaximalAddress() - def.getMinimalAddress());
+       }
        
        /**
         * Registers an observer to be notified when a memory cell is modified
@@ -26,4 +30,6 @@ public interface Memory<T>
        public void deregisterObserver(MemoryObserver ob);
        
        public void notifyObservers(long address);
+       
+       public MemoryDefinition getDefinition();
 }
diff --git a/net.mograsim.machine/src/net/mograsim/machine/MemoryDefinition.java b/net.mograsim.machine/src/net/mograsim/machine/MemoryDefinition.java
new file mode 100644 (file)
index 0000000..5f42d10
--- /dev/null
@@ -0,0 +1,44 @@
+package net.mograsim.machine;
+
+public interface MemoryDefinition {
+
+       /**
+        * The number of bits that the main memory uses to address cells. Note that this
+        * does not need to equal {@link MachineDefinition#getAddressBits()}.
+        * 
+        * @return the number of bits used to address a memory cell
+        * @author Christian Femers
+        */
+       int getMemoryAddressBits();
+
+       /**
+        * The minimal address possible to address/use. This is usually 0.
+        * 
+        * @return the minimal possible address.
+        * @author Christian Femers
+        */
+       long getMinimalAddress();
+
+       /**
+        * The maximal address possible to address/use.
+        * 
+        * @return the maximal possible address as <b>unsigned long</b>
+        * @author Christian Femers
+        */
+       long getMaximalAddress();
+       
+       /**
+        * The size of the MainMemory as the amount of addressable memory cells.
+        * 
+        * @return the amount of addressable memory cells
+        */
+       default long size()
+       {
+               return getMaximalAddress() - getMinimalAddress();
+       }
+       
+       public static MemoryDefinition create(int memoryAddressBits, long minimalAddress, long maximalAddress)
+       {
+               return new StandardMemoryDefinition(memoryAddressBits, minimalAddress, maximalAddress);
+       }
+}
diff --git a/net.mograsim.machine/src/net/mograsim/machine/MicroInstruction.java b/net.mograsim.machine/src/net/mograsim/machine/MicroInstruction.java
deleted file mode 100644 (file)
index 9f16320..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-package net.mograsim.machine;
-
-import net.mograsim.machine.mi.parameters.MicroInstructionParameter;
-import net.mograsim.machine.mi.parameters.Mnemonic;
-
-public interface MicroInstruction {
-       
-       public MicroInstructionParameter getParameter(int index);
-       
-       /**
-        * @return The amount of {@link Mnemonic}s, the instruction is composed of
-        */
-       public int getSize();
-}
diff --git a/net.mograsim.machine/src/net/mograsim/machine/MicroInstructionDefinition.java b/net.mograsim.machine/src/net/mograsim/machine/MicroInstructionDefinition.java
deleted file mode 100644 (file)
index 63134a0..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-package net.mograsim.machine;
-
-import net.mograsim.machine.mi.parameters.MicroInstructionParameter;
-import net.mograsim.machine.mi.parameters.ParameterClassification;
-
-public interface MicroInstructionDefinition
-{
-       /**
-        * @return The {@link ParameterClassification}s of which a MicroInstruction is composed.
-        */
-       public ParameterClassification[] getParameterClassifications();
-       
-       /**
-        * @return The amount of {@link MicroInstructionParameter}s in a {@link MicroInstruction} that follows this definition.
-        */
-       public default int size()
-       {
-               return getParameterClassifications().length;
-       }
-       
-}
diff --git a/net.mograsim.machine/src/net/mograsim/machine/MicroprogramMemory.java b/net.mograsim.machine/src/net/mograsim/machine/MicroprogramMemory.java
deleted file mode 100644 (file)
index 333f8a6..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-package net.mograsim.machine;
-
-public interface MicroprogramMemory extends Memory<MicroInstruction>
-{
-}
diff --git a/net.mograsim.machine/src/net/mograsim/machine/StandardMainMemoryDefinition.java b/net.mograsim.machine/src/net/mograsim/machine/StandardMainMemoryDefinition.java
new file mode 100644 (file)
index 0000000..1e3bd50
--- /dev/null
@@ -0,0 +1,17 @@
+package net.mograsim.machine;
+
+class StandardMainMemoryDefinition extends StandardMemoryDefinition implements MainMemoryDefinition {
+       private final int cellWidth;
+       
+       StandardMainMemoryDefinition(int memoryAddressBits, int cellWidth, long minimalAddress, long maximalAddress)
+       {
+               super(memoryAddressBits, minimalAddress, maximalAddress);
+               this.cellWidth = cellWidth;
+       }
+
+       @Override
+       public int getCellWidth()
+       {
+               return cellWidth;
+       }
+}
diff --git a/net.mograsim.machine/src/net/mograsim/machine/StandardMemoryDefinition.java b/net.mograsim.machine/src/net/mograsim/machine/StandardMemoryDefinition.java
new file mode 100644 (file)
index 0000000..7ba5fb8
--- /dev/null
@@ -0,0 +1,42 @@
+package net.mograsim.machine;
+
+class StandardMemoryDefinition implements MemoryDefinition {
+       private final int memoryAddressBits;
+       private final long minimalAddress, maximalAddress;
+       
+       StandardMemoryDefinition(int memoryAddressBits, long minimalAddress, long maximalAddress)
+       {
+               super();
+               this.memoryAddressBits = memoryAddressBits;
+               this.minimalAddress = minimalAddress;
+               this.maximalAddress = maximalAddress;
+       }
+
+       public StandardMemoryDefinition(MainMemoryDefinition definition)
+       {
+               this(definition.getMemoryAddressBits(), definition.getMinimalAddress(), definition.getMaximalAddress());
+       }
+
+       @Override
+       public int getMemoryAddressBits()
+       {
+               return memoryAddressBits;
+       }
+
+       @Override
+       public long getMinimalAddress()
+       {
+               return minimalAddress;
+       }
+
+       @Override
+       public long getMaximalAddress()
+       {
+               return maximalAddress;
+       }
+       
+       public static MemoryDefinition create(int memoryAddressBits, long minimalAddress, long maximalAddress)
+       {
+               return new StandardMemoryDefinition(memoryAddressBits, minimalAddress, maximalAddress);
+       }
+}
diff --git a/net.mograsim.machine/src/net/mograsim/machine/mi/MicroInstruction.java b/net.mograsim.machine/src/net/mograsim/machine/mi/MicroInstruction.java
new file mode 100644 (file)
index 0000000..07a15d2
--- /dev/null
@@ -0,0 +1,20 @@
+package net.mograsim.machine.mi;
+
+import net.mograsim.machine.mi.parameters.MicroInstructionParameter;
+import net.mograsim.machine.mi.parameters.Mnemonic;
+
+public interface MicroInstruction {
+       
+       public MicroInstructionParameter getParameter(int index);
+       public void setParameter(int index, MicroInstructionParameter param);
+       
+       /**
+        * @return The amount of {@link Mnemonic}s, the instruction is composed of
+        */
+       public int getSize();
+       
+       public static MicroInstruction create(MicroInstructionParameter... parameters)
+       {
+               return new StandardMicroInstruction(parameters);
+       }
+}
diff --git a/net.mograsim.machine/src/net/mograsim/machine/mi/MicroInstructionDefinition.java b/net.mograsim.machine/src/net/mograsim/machine/mi/MicroInstructionDefinition.java
new file mode 100644 (file)
index 0000000..b940e65
--- /dev/null
@@ -0,0 +1,31 @@
+package net.mograsim.machine.mi;
+
+import net.mograsim.machine.mi.parameters.MicroInstructionParameter;
+import net.mograsim.machine.mi.parameters.ParameterClassification;
+
+public interface MicroInstructionDefinition
+{
+       /**
+        * @return The {@link ParameterClassification}s of which a MicroInstruction is composed.
+        */
+       public ParameterClassification[] getParameterClassifications();
+       
+       /**
+        * @throws IndexOutOfBoundsException
+        */
+       public ParameterClassification getParameterClassification(int index);
+       
+       
+       /**
+        * @return The amount of {@link MicroInstructionParameter}s in a {@link MicroInstruction} that follows this definition.
+        */
+       public default int size()
+       {
+               return getParameterClassifications().length;
+       }
+       
+       public static MicroInstructionDefinition create(ParameterClassification... classes)
+       {
+               return new StandardMicroInstructionDefinition(classes);
+       }
+}
\ No newline at end of file
diff --git a/net.mograsim.machine/src/net/mograsim/machine/mi/MicroprogramMemory.java b/net.mograsim.machine/src/net/mograsim/machine/mi/MicroprogramMemory.java
new file mode 100644 (file)
index 0000000..e31ce77
--- /dev/null
@@ -0,0 +1,12 @@
+package net.mograsim.machine.mi;
+
+import net.mograsim.machine.Memory;
+import net.mograsim.machine.MemoryDefinition;
+
+public interface MicroprogramMemory extends Memory<MicroInstruction>
+{
+       public static MicroprogramMemory create(MemoryDefinition def)
+       {
+               return new StandardMicroprogramMemory(def);
+       }
+}
diff --git a/net.mograsim.machine/src/net/mograsim/machine/mi/MicroprogramMemoryParser.java b/net.mograsim.machine/src/net/mograsim/machine/mi/MicroprogramMemoryParser.java
new file mode 100644 (file)
index 0000000..065ba15
--- /dev/null
@@ -0,0 +1,94 @@
+package net.mograsim.machine.mi;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.math.BigInteger;
+
+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.BooleanImmediate;
+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 MicroprogramMemoryParser
+{
+       public static void parse(MicroprogramMemory memory, long startAddress, MicroInstructionDefinition definition, String input) throws IOException
+       {
+               try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(input))))
+               {
+                       parse(memory, startAddress, definition, reader);
+               }
+       }
+
+       public static void parse(MicroprogramMemory memory, long startAddress, MicroInstructionDefinition definition,
+                       BufferedReader input)
+       {
+               MemoryDefinition def = memory.getDefinition();
+               long minAddress = Long.max(startAddress, def.getMinimalAddress()), maxAddress = def.getMaximalAddress();
+               try
+               {
+                       String line;
+                       for (long i = minAddress; i < maxAddress && input.ready() && !"".equals((line = input.readLine())); i++)
+                               memory.setCell(i, parse(definition, line));
+               } catch (IOException e)
+               {
+                       e.printStackTrace();
+               }
+       }
+
+       public static MicroInstruction parse(MicroInstructionDefinition definition, String toParse)
+       {
+               int size = definition.size();
+               String[] strings = toParse.split(",");
+               if (size != strings.length)
+                       throw new IllegalArgumentException(
+                                       "String does not match definition! The number of parameters does not match.");
+               MicroInstructionParameter[] params = new MicroInstructionParameter[size];
+               ParameterClassification[] classes = definition.getParameterClassifications();
+               for (int i = 0; i < size; i++)
+               {
+                       params[i] = classes[i].parse(strings[i]);
+               }
+               return new StandardMicroInstruction(params);
+       }
+       
+       public static void write(MicroprogramMemory memory, long startAddress, long endAddress, String output) throws IOException
+       {
+               try(OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(output)))
+               {
+                       write(memory, startAddress, endAddress, writer);
+               }
+       }
+       
+       public static void write(MicroprogramMemory memory, long startAddress, long endAddress, OutputStreamWriter output) throws IOException
+       {
+               MemoryDefinition def = memory.getDefinition();
+               long min = Long.max(def.getMinimalAddress(), startAddress), max = Long.min(def.getMaximalAddress(), endAddress) + 1;
+               for(long i = min; i < max; i++)
+               {
+                       output.write(toCSV(memory.getCell(i)) + "\n");
+               }
+       }
+       
+       private static String toCSV(MicroInstruction inst)
+       {
+               int max = inst.getSize() - 1;
+               StringBuilder sb = new StringBuilder();
+               for(int i = 0; i < max; i++)
+               {
+                       sb.append(inst.getParameter(i).toString());
+                       sb.append(",");
+               }
+               sb.append(inst.getParameter(max).toString());
+               return sb.toString();
+       }
+}
diff --git a/net.mograsim.machine/src/net/mograsim/machine/mi/StandardMicroInstruction.java b/net.mograsim.machine/src/net/mograsim/machine/mi/StandardMicroInstruction.java
new file mode 100644 (file)
index 0000000..e40350d
--- /dev/null
@@ -0,0 +1,38 @@
+package net.mograsim.machine.mi;
+
+import net.mograsim.machine.mi.parameters.MicroInstructionParameter;
+
+class StandardMicroInstruction implements MicroInstruction
+{
+       private MicroInstructionParameter[] parameters;
+
+       StandardMicroInstruction(MicroInstructionParameter... parameters)
+       {
+               this.parameters = parameters;
+       }
+       
+       /**
+        * @throws IndexOutOfBoundsException
+        */
+       @Override
+       public MicroInstructionParameter getParameter(int index)
+       {
+               return parameters[index];
+       }
+
+       @Override
+       public int getSize()
+       {
+               return parameters.length;
+       }
+
+       /**
+        * @throws IndexOutOfBoundsException
+        */
+       @Override
+       public void setParameter(int index, MicroInstructionParameter param)
+       {
+               parameters[index] = param;
+       }
+
+}
diff --git a/net.mograsim.machine/src/net/mograsim/machine/mi/StandardMicroInstructionDefinition.java b/net.mograsim.machine/src/net/mograsim/machine/mi/StandardMicroInstructionDefinition.java
new file mode 100644 (file)
index 0000000..2def5e1
--- /dev/null
@@ -0,0 +1,26 @@
+package net.mograsim.machine.mi;
+
+import net.mograsim.machine.mi.parameters.ParameterClassification;
+
+class StandardMicroInstructionDefinition implements MicroInstructionDefinition
+{
+       private ParameterClassification[] classes;
+       
+       public StandardMicroInstructionDefinition(ParameterClassification... classes)
+       {
+               this.classes = classes;
+       }
+
+       @Override
+       public ParameterClassification[] getParameterClassifications()
+       {
+               return classes.clone();
+       }
+
+       @Override
+       public ParameterClassification getParameterClassification(int index)
+       {
+               return classes[index];
+       }
+
+}
diff --git a/net.mograsim.machine/src/net/mograsim/machine/mi/StandardMicroprogramMemory.java b/net.mograsim.machine/src/net/mograsim/machine/mi/StandardMicroprogramMemory.java
new file mode 100644 (file)
index 0000000..a253f22
--- /dev/null
@@ -0,0 +1,64 @@
+package net.mograsim.machine.mi;
+
+import java.util.HashSet;
+
+import net.mograsim.machine.MemoryDefinition;
+import net.mograsim.machine.MemoryObserver;
+import net.mograsim.machine.standard.memory.MemoryException;
+
+class StandardMicroprogramMemory implements MicroprogramMemory
+{
+       private MicroInstruction[] data;
+       private MemoryDefinition definition;
+       private HashSet<MemoryObserver> observers;
+       
+       StandardMicroprogramMemory(MemoryDefinition definition)
+       {
+               if(definition.size() > Integer.MAX_VALUE)
+                       throw new MemoryException("Size of MicroprogramMemory must be an int, not a long");
+               this.definition = definition;
+               data = new MicroInstruction[(int) definition.size()];
+       }
+       
+       private int translate(long address)
+       {
+               return (int) (address - definition.getMinimalAddress());
+       }
+       
+       @Override
+       public MicroInstruction getCell(long address)
+       {
+               return data[translate(address)];
+       }
+
+       @Override
+       public void setCell(long address, MicroInstruction data)
+       {
+               this.data[translate(address)] = data;
+       }
+
+       @Override
+       public void registerObserver(MemoryObserver ob)
+       {
+               observers.add(ob);
+       }
+
+       @Override
+       public void deregisterObserver(MemoryObserver ob)
+       {
+               observers.remove(ob);
+       }
+
+       @Override
+       public void notifyObservers(long address)
+       {
+               observers.forEach(ob -> ob.update(address));
+       }
+
+       @Override
+       public MemoryDefinition getDefinition()
+       {
+               return definition;
+       }
+
+}
index abe552f..1689cff 100644 (file)
@@ -15,4 +15,10 @@ public class BooleanClassification implements ParameterClassification
        {
                return 1;
        }
+       
+       @Override
+       public BooleanImmediate parse(String toParse)
+       {
+               return new BooleanImmediate("H".equals(toParse));
+       }
 }
index d5ba964..b28a436 100644 (file)
@@ -1,5 +1,7 @@
 package net.mograsim.machine.mi.parameters;
 
+import java.math.BigInteger;
+
 import net.mograsim.machine.mi.parameters.MicroInstructionParameter.ParameterType;
 
 public class IntegerClassification implements ParameterClassification
@@ -22,4 +24,10 @@ public class IntegerClassification implements ParameterClassification
        {
                return bits;
        }
+       
+       @Override
+       public IntegerImmediate parse(String toParse)
+       {
+               return new IntegerImmediate(new BigInteger(toParse), bits);
+       }
 }
index b9c1373..a513b60 100644 (file)
@@ -104,8 +104,6 @@ public class MnemonicFamily implements ParameterClassification
                return stringValues.clone();
        }
        
-       
-       
        @Override
        public int hashCode()
        {
@@ -120,8 +118,15 @@ public class MnemonicFamily implements ParameterClassification
        {
                return this == obj;
        }
-
-
+       
+       @Override
+       public Mnemonic parse(String toParse)
+       {
+               Mnemonic parsed = get(toParse);
+               if(parsed == null)
+                       throw new UnknownMnemonicException(toParse);
+               return parsed;
+       }
 
        public static class MnemonicPair
        {
index 3b3f1a2..3373401 100644 (file)
@@ -22,4 +22,6 @@ public interface ParameterClassification
         * @return The number of bits of the parameters in this classification.
         */
        public int getExpectedBits();
+       
+       public MicroInstructionParameter parse(String toParse);
 }
diff --git a/net.mograsim.machine/src/net/mograsim/machine/mi/parameters/UnknownMnemonicException.java b/net.mograsim.machine/src/net/mograsim/machine/mi/parameters/UnknownMnemonicException.java
new file mode 100644 (file)
index 0000000..9b23236
--- /dev/null
@@ -0,0 +1,26 @@
+package net.mograsim.machine.mi.parameters;
+
+import net.mograsim.machine.MachineException;
+
+public class UnknownMnemonicException extends MachineException
+{
+       /**
+        * 
+        */
+       private static final long serialVersionUID = 701558899889830975L;
+
+       public UnknownMnemonicException()
+       {
+               super();
+       }
+       
+       public UnknownMnemonicException(String message)
+       {
+               super(message);
+       }
+       
+       public UnknownMnemonicException(Throwable cause)
+       {
+               super(cause);
+       }
+}
index 1632c8e..079c7e5 100644 (file)
@@ -2,8 +2,8 @@ package net.mograsim.machine.standard.memory;
 
 import org.eclipse.swt.graphics.Color;
 
-import com.google.gson.Gson;
 import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
 
 import net.haspamelodica.swt.helper.gcs.GeneralGC;
 import net.haspamelodica.swt.helper.swtobjectwrappers.Font;
@@ -16,7 +16,6 @@ import net.mograsim.logic.model.model.wires.Pin;
 import net.mograsim.logic.model.modeladapter.ViewLogicModelAdapter;
 import net.mograsim.logic.model.serializing.IdentifierGetter;
 import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator;
-import net.mograsim.machine.DefaultMainMemoryDefinition;
 import net.mograsim.machine.MainMemoryDefinition;
 import net.mograsim.machine.standard.memory.WordAddressableMemoryComponent;
 import net.mograsim.preferences.Preferences;
@@ -27,6 +26,8 @@ public class GUIMemoryWA extends GUIComponent
        private final Pin addrPin, dataPin, rWPin;
        private WordAddressableMemoryComponent memory;
        private final static int width = 100, height = 300;
+       
+       private final static String addrKey = "addrBits", cellWidthKey = "cellWidth", minAddrKey = "minAddr", maxAddrKey = "maxAddr";
 
        public GUIMemoryWA(ViewModelModifiable model, MainMemoryDefinition definition, String name)
        {
@@ -91,7 +92,12 @@ public class GUIMemoryWA extends GUIComponent
        @Override
        public JsonElement getParamsForSerializing(IdentifierGetter idGetter)
        {
-               return new Gson().toJsonTree(new DefaultMainMemoryDefinition(definition));
+               JsonObject o = new JsonObject();
+               o.addProperty(addrKey, definition.getMemoryAddressBits());
+               o.addProperty(cellWidthKey, definition.getCellWidth());
+               o.addProperty(maxAddrKey, definition.getMaximalAddress());
+               o.addProperty(minAddrKey, definition.getMinimalAddress());
+               return o;
        }
 
        static
@@ -99,7 +105,12 @@ public class GUIMemoryWA extends GUIComponent
                ViewLogicModelAdapter.addComponentAdapter(new WordAddressableMemoryAdapter());
                IndirectGUIComponentCreator.setComponentSupplier(GUIAndGate.class.getCanonicalName(), (m, p, n) ->
                {
-                       return new GUIMemoryWA(m, new Gson().fromJson(p, DefaultMainMemoryDefinition.class), n);
+                       JsonObject o = (JsonObject) p;
+                       int addressBits = o.get(addrKey).getAsInt();
+                       int cellWidth = o.get(cellWidthKey).getAsInt();
+                       long maxAddr = o.get(maxAddrKey).getAsLong();
+                       long minAddr = o.get(minAddrKey).getAsLong();
+                       return new GUIMemoryWA(m, MainMemoryDefinition.create(addressBits, cellWidth, minAddr, maxAddr), n);
                });
        }
 }
index 516b01f..3dddc2e 100644 (file)
 package net.mograsim.machine.standard.memory;
 
 import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
 
 import net.mograsim.logic.core.types.Bit;
 import net.mograsim.logic.core.types.BitVector;
+import net.mograsim.machine.GenericMemory;
 import net.mograsim.machine.MainMemory;
 import net.mograsim.machine.MainMemoryDefinition;
-import net.mograsim.machine.MemoryObserver;
 
-public class WordAddressableMemory implements MainMemory
+public class WordAddressableMemory extends GenericMemory<BitVector> implements MainMemory
 {
        private final int cellWidth;
-       private final long minimalAddress, maximalAddress;
        private final MainMemoryDefinition definition;
-       private final int pageSize = 64;
-       private Set<MemoryObserver> observers = new HashSet<>();
-
-       private HashMap<Long, Page> pages;
 
        public WordAddressableMemory(MainMemoryDefinition definition)
        {
-               super();
+               super(definition);
                this.cellWidth = definition.getCellWidth();
-               this.minimalAddress = definition.getMinimalAddress();
-               this.maximalAddress = definition.getMaximalAddress();
                this.definition = definition;
-               this.pages = new HashMap<>();
-       }
-       
-       private void inBoundsCheck(long address)
-       {
-               if (address < minimalAddress || address > maximalAddress)
-                       throw new IndexOutOfBoundsException(String.format("Memory address out of bounds! Minimum: %d Maximum: %d Actual: %d",
-                                       minimalAddress, maximalAddress, address));
-       }
-
-       private long page(long address)
-       {
-               return address / pageSize;
-       }
-       
-       private int offset(long address)
-       {
-               return (int) (address % pageSize);
-       }
-       
-       @Override
-       public void setCell(long address, BitVector b)
-       {
-               inBoundsCheck(address);
-               long page = page(address);
-               int offset = offset(address);
-               Page p = pages.get(Long.valueOf(page));
-               if (p == null)
-                       pages.put(page, p = new Page());
-               p.setCell(offset, b);
-               notifyObservers(address);
        }
 
        @Override
        public BitVector getCell(long address)
        {
-               inBoundsCheck(address);
-               long page = page(address);
-               int offset = offset(address);
-               Page p = pages.get(Long.valueOf(page));
-               if (p == null)
-                       return BitVector.of(Bit.ZERO, cellWidth);
-               return p.getCell(offset);
+               BitVector data = super.getCell(address);
+               return data == null ? BitVector.of(Bit.ZERO, cellWidth) : data;
        }
        
        @Override
        public BigInteger getCellAsBigInteger(long address)
        {
-               inBoundsCheck(address);
-               long page = page(address);
-               int offset = offset(address);
-               Page p = pages.get(Long.valueOf(page));
-               if (p == null)
-                       return BigInteger.valueOf(0L);
-               return p.getCellAsBigInteger(offset);
+               BitVector data = getCell(address);
+               return data == null ? BigInteger.valueOf(0) : data.getUnsignedValue();
        }
 
        @Override
-       public void setCellAsBigInteger(long address, BigInteger word)
-       {
-               inBoundsCheck(address);
-               long page = page(address);
-               int offset = offset(address);
-               Page p = pages.get(Long.valueOf(page));
-               if (p == null)
-                       pages.put(page, p = new Page());
-               p.setCellAsBigInteger(offset, word);
-               notifyObservers(address);
-       }
-
-       private class Page
+       public void setCellAsBigInteger(long address, BigInteger data)
        {
-               private BitVector[] memory;
-
-               public Page()
-               {
-                       memory = new BitVector[pageSize];
-               }
-
-               public BitVector getCell(int index)
-               {
-                       BitVector b = memory[index];
-                       if (b == null)
-                               return BitVector.of(Bit.ZERO, cellWidth);
-                       return memory[index];
-               }
-
-               public void setCell(int index, BitVector bits)
-               {
-                       if (bits.length() != cellWidth)
-                               throw new IllegalArgumentException(String.format(
-                                               "BitVector to be saved in memory cell has unexpected width. Expected: %d Actual: %d", cellWidth, bits.length()));
-                       memory[index] = bits;
-               }
-
-               public void setCellAsBigInteger(int index, BigInteger bits)
-               {
-                       setCell(index, BitVector.from(bits, cellWidth));
-               }
-               
-               public BigInteger getCellAsBigInteger(int index)
-               {
-                       try {
-                               return getCell(index).getUnsignedValue();
-                       }
-                       catch(NumberFormatException e)
-                       {
-                               throw new MemoryException(e);
-                       }
-               }
-
-               @Override
-               public String toString()
-               {
-                       return Arrays.deepToString(memory);
-               }
+               setCell(address, BitVector.from(data, cellWidth));
        }
 
        @Override
@@ -152,22 +45,4 @@ public class WordAddressableMemory implements MainMemory
        {
                return definition;
        }
-
-       @Override
-       public void registerObserver(MemoryObserver ob)
-       {
-               observers.add(ob);
-       }
-
-       @Override
-       public void deregisterObserver(MemoryObserver ob)
-       {
-               observers.remove(ob);
-       }
-
-       @Override
-       public void notifyObservers(long address)
-       {
-               observers.forEach(ob -> ob.update(address));
-       }
 }
index 1fb59d0..5f50dbc 100644 (file)
@@ -12,7 +12,7 @@ import net.mograsim.logic.core.types.Bit;
 import net.mograsim.logic.core.types.BitVector;
 import net.mograsim.logic.core.wires.Wire;
 import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-import net.mograsim.machine.DefaultMainMemoryDefinition;
+import net.mograsim.machine.MainMemoryDefinition;
 
 class WordAddressableMemoryTest {
        
@@ -28,7 +28,8 @@ class WordAddressableMemoryTest {
                ReadWriteEnd dataI = data.createReadWriteEnd();
                ReadWriteEnd addressI = address.createReadWriteEnd();
 
-               WordAddressableMemoryComponent memory = new WordAddressableMemoryComponent(t, 4, new DefaultMainMemoryDefinition(64, 16, 4096L, Long.MAX_VALUE), data.createReadWriteEnd(),
+               @SuppressWarnings("unused")
+               WordAddressableMemoryComponent memory = new WordAddressableMemoryComponent(t, 4, MainMemoryDefinition.create(64, 16, 4096L, Long.MAX_VALUE), data.createReadWriteEnd(),
                                rW.createReadOnlyEnd(), address.createReadOnlyEnd());
 
                Random r = new Random();
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryCellEditingSupport.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryCellEditingSupport.java
deleted file mode 100644 (file)
index 10498f6..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-package net.mograsim.plugin.memory;
-
-import java.math.BigInteger;
-
-import org.eclipse.jface.viewers.CellEditor;
-import org.eclipse.jface.viewers.EditingSupport;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.TextCellEditor;
-
-import net.mograsim.plugin.asm.AsmNumberUtil;
-import net.mograsim.plugin.memory.MemoryView.DisplaySettings;
-
-public class MemoryCellEditingSupport extends EditingSupport
-{
-       private final TableViewer viewer;
-       private final CellEditor editor;
-       private final DisplaySettings displaySettings;
-
-       public MemoryCellEditingSupport(TableViewer viewer, DisplaySettings displaySettings)
-       {
-               super(viewer);
-               this.viewer = viewer;
-               this.displaySettings = displaySettings;
-               editor = new TextCellEditor(viewer.getTable());
-               editor.setValidator(new NumberCellEditorValidator());
-       }
-
-       @Override
-       protected boolean canEdit(Object element)
-       {
-               return true;
-       }
-
-       @Override
-       protected CellEditor getCellEditor(Object element)
-       {
-               return editor;
-       }
-
-       @Override
-       protected Object getValue(Object element)
-       {
-               MemoryTableRow row = (MemoryTableRow) element;
-               return AsmNumberUtil.toString(row.getMemory().getCellAsBigInteger(row.address), displaySettings.getDataNumberType());
-       }
-
-       @Override
-       protected void setValue(Object element, Object userInput)
-       {
-               MemoryTableRow row = (MemoryTableRow) element;
-               try
-               {
-                       row.getMemory().setCellAsBigInteger(row.address, AsmNumberUtil.valueOf((String) userInput));
-               }
-               catch (@SuppressWarnings("unused") NumberFormatException e)
-               {
-                       row.getMemory().setCellAsBigInteger(row.address, BigInteger.valueOf(0));
-               }
-               viewer.update(element, null);
-       }
-}
\ No newline at end of file
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryTableContentProvider.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryTableContentProvider.java
deleted file mode 100644 (file)
index 9f2a9e1..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-package net.mograsim.plugin.memory;
-
-import org.eclipse.jface.viewers.ILazyContentProvider;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.widgets.Display;
-
-import net.mograsim.machine.MainMemory;
-import net.mograsim.machine.MemoryObserver;
-
-public class MemoryTableContentProvider implements ILazyContentProvider, MemoryObserver
-{
-       private long lower;
-       private TableViewer viewer;
-       private final static int limit = 10_000;
-       private int amount = 0;
-       private MainMemory memory;
-
-       public void setLowerBound(long lower)
-       {
-               if (memory != null)
-                       this.lower = Long.min(memory.getDefinition().getMaximalAddress(), Long.max(memory.getDefinition().getMinimalAddress(), lower));
-               else
-                       this.lower = lower;
-               updateItemCount();
-       }
-
-       public void updateItemCount()
-       {
-               if (memory != null)
-               {
-                       long size = memory.getDefinition().getMaximalAddress() - lower;
-                       viewer.setItemCount(size > amount ? amount : (int) size);
-               } else
-                       viewer.setItemCount(0);
-       }
-
-       public long getLowerBound()
-       {
-               return lower;
-       }
-
-       public void setAmount(int amount)
-       {
-               this.amount = Integer.min(amount, limit);
-               updateItemCount();
-       }
-
-       public int getAmount()
-       {
-               return amount;
-       }
-
-       @Override
-       public void updateElement(int index)
-       {
-               long address = lower + index;
-               if (address <= memory.getDefinition().getMaximalAddress())
-                       viewer.replace(new MemoryTableRow(address, memory), index);
-       }
-
-       @Override
-       public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
-       {
-               this.viewer = (TableViewer) viewer;
-               this.memory = (MainMemory) newInput;
-               if (oldInput != null)
-                       ((MainMemory) oldInput).deregisterObserver(this);
-               if (memory != null)
-                       memory.registerObserver(this);
-               setLowerBound(0L);
-       }
-
-       @Override
-       public void update(long address)
-       {
-               Display.getDefault().asyncExec(() -> updateElement((int) (address - lower)));
-       }
-}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryTableRow.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryTableRow.java
deleted file mode 100644 (file)
index fa5b626..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-package net.mograsim.plugin.memory;
-
-import net.mograsim.machine.MainMemory;
-
-public class MemoryTableRow
-{
-       public final long address;
-       private final MainMemory memory;
-
-       public MemoryTableRow(long address, MainMemory memory)
-       {
-               this.address = address;
-               this.memory = memory;
-       }
-
-       public MainMemory getMemory()
-       {
-               return memory;
-       }
-}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryView.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/MemoryView.java
deleted file mode 100644 (file)
index 5254745..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-package net.mograsim.plugin.memory;
-
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.events.VerifyListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.part.ViewPart;
-
-import net.mograsim.machine.DefaultMainMemoryDefinition;
-import net.mograsim.machine.MainMemory;
-import net.mograsim.machine.standard.memory.WordAddressableMemory;
-import net.mograsim.plugin.asm.AsmNumberUtil;
-import net.mograsim.plugin.asm.AsmNumberUtil.NumberType;
-
-public class MemoryView extends ViewPart
-{
-       private TableViewer viewer;
-       private MemoryTableContentProvider provider;
-       private DisplaySettings displaySettings;
-       private String addressFormat;
-
-       @Override
-       public void createPartControl(Composite parent)
-       {
-               provider = new MemoryTableContentProvider();
-               displaySettings = new DisplaySettings();
-               displaySettings.setDataNumberType(NumberType.HEXADECIMAL);
-
-               GridLayout layout = new GridLayout(6, false);
-               parent.setLayout(layout);
-               Label fromLabel = new Label(parent, SWT.NONE);
-               fromLabel.setText("Address: ");
-               Text fromText = new Text(parent, SWT.BORDER | SWT.SEARCH);
-               fromText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL));
-               VerifyListener vl = new NumberVerifyListener();
-               fromText.addVerifyListener(vl);
-               fromText.setText("0");
-               fromText.addModifyListener(e ->
-               {
-                       try
-                       {
-                               provider.setLowerBound(AsmNumberUtil.valueOf(fromText.getText()).longValue());
-                               viewer.refresh();
-                       }
-                       catch (@SuppressWarnings("unused") NumberFormatException ex)
-                       {
-                               // Nothing to do here
-                       }
-               });
-
-               Label amountLabel = new Label(parent, SWT.NONE);
-               amountLabel.setText("Number of cells: ");
-               Text amountText = new Text(parent, SWT.BORDER | SWT.SEARCH);
-               amountText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL));
-               amountText.addVerifyListener(vl);
-               amountText.setText("0");
-               amountText.addModifyListener(e ->
-               {
-                       try
-                       {
-                               provider.setAmount(AsmNumberUtil.valueOf(amountText.getText()).intValue());
-                               viewer.refresh();
-                       }
-                       catch (@SuppressWarnings("unused") NumberFormatException ex)
-                       {
-                               // Nothing to do here
-                       }
-               });
-
-               setupRadixSelector(parent);
-
-               createViewer(parent);
-       }
-
-       private void setupRadixSelector(Composite parent)
-       {
-               Label radixLabel = new Label(parent, SWT.NONE);
-               radixLabel.setText("Radix: ");
-               Combo selectRadix = new Combo(parent, SWT.READ_ONLY);
-
-               String entries[] = new String[] { "Binary", "Octal", "Decimal", "Hexadecimal" };
-               NumberType corTypes[] = new NumberType[] { NumberType.BINARY, NumberType.OCTAL, NumberType.DECIMAL, NumberType.HEXADECIMAL };
-               selectRadix.setItems(entries);
-               selectRadix.addSelectionListener(new SelectionListener()
-               {
-                       @Override
-                       public void widgetSelected(SelectionEvent e)
-                       {
-                               int index = selectRadix.getSelectionIndex();
-                               if (index == -1)
-                                       displaySettings.setDataNumberType(NumberType.HEXADECIMAL);
-                               else
-                               {
-                                       displaySettings.setDataNumberType(corTypes[index]);
-                               }
-                               viewer.refresh();
-                       }
-
-                       @Override
-                       public void widgetDefaultSelected(SelectionEvent e)
-                       {
-                               widgetSelected(e);
-                       }
-               });
-       }
-
-       private void createViewer(Composite parent)
-       {
-               viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER | SWT.VIRTUAL);
-               createColumns();
-               Table table = viewer.getTable();
-               table.setHeaderVisible(true);
-               table.setLinesVisible(true);
-               viewer.setUseHashlookup(true);
-               viewer.setContentProvider(provider);
-               setMemoryBinding(new WordAddressableMemory(new DefaultMainMemoryDefinition(8, 8, 8L, Long.MAX_VALUE)));
-               getSite().setSelectionProvider(viewer);
-
-               GridData gd = new GridData();
-               gd.verticalAlignment = GridData.FILL;
-               gd.horizontalSpan = 6;
-               gd.grabExcessHorizontalSpace = true;
-               gd.grabExcessVerticalSpace = true;
-               gd.horizontalAlignment = GridData.FILL;
-               viewer.getControl().setLayoutData(gd);
-       }
-
-       private void createColumns()
-       {
-               String[] titles = { "Address", "Data" };
-               int[] bounds = { 100, 100 };
-
-               TableViewerColumn col = createTableViewerColumn(titles[0], bounds[0]);
-               col.setLabelProvider(new ColumnLabelProvider()
-               {
-                       @Override
-                       public String getText(Object element)
-                       {
-                               MemoryTableRow row = (MemoryTableRow) element;
-                               return String.format(addressFormat, row.address);// TODO: make the string length dependent on memory address length
-                       }
-               });
-
-               col = createTableViewerColumn(titles[1], bounds[1]);
-               col.setLabelProvider(new ColumnLabelProvider()
-               {
-                       @Override
-                       public String getText(Object element)
-                       {
-                               MemoryTableRow row = (MemoryTableRow) element;
-                               return AsmNumberUtil.toString(row.getMemory().getCellAsBigInteger(row.address), displaySettings.getDataNumberType());
-                       }
-               });
-               col.setEditingSupport(new MemoryCellEditingSupport(viewer, displaySettings));
-       }
-
-       private TableViewerColumn createTableViewerColumn(String title, int bound)
-       {
-               TableViewerColumn viewerColumn = new TableViewerColumn(viewer, SWT.NONE);
-               TableColumn column = viewerColumn.getColumn();
-               column.setText(title);
-               column.setWidth(bound);
-               column.setResizable(true);
-               column.setMoveable(false);
-               return viewerColumn;
-       }
-
-       @Override
-       public void setFocus()
-       {
-               viewer.getControl().setFocus();
-       }
-
-       public void setMemoryBinding(MainMemory m)
-       {
-               int hexAddressLength = Long.toUnsignedString(m.getDefinition().getMaximalAddress(), 16).length();
-               addressFormat = "0x%0" + hexAddressLength + "X";
-               viewer.setInput(m);
-       }
-
-       public static class DisplaySettings
-       {
-               private AsmNumberUtil.NumberType dataNumberType;
-
-               public AsmNumberUtil.NumberType getDataNumberType()
-               {
-                       return dataNumberType;
-               }
-
-               public void setDataNumberType(AsmNumberUtil.NumberType dataNumberType)
-               {
-                       this.dataNumberType = dataNumberType;
-               }
-       }
-}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/NumberCellEditorValidator.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/NumberCellEditorValidator.java
deleted file mode 100644 (file)
index 236eaa0..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-package net.mograsim.plugin.memory;
-
-import org.eclipse.jface.viewers.ICellEditorValidator;
-
-import net.mograsim.plugin.asm.AsmNumberUtil;
-
-public class NumberCellEditorValidator implements ICellEditorValidator
-{
-
-       @Override
-       public String isValid(Object value)
-       {
-               return AsmNumberUtil.NumberType.NONE.equals(AsmNumberUtil.getType((String) value)) ? (String) value + "is not a valid number"
-                               : null;
-       }
-
-}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/NumberVerifyListener.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/memory/NumberVerifyListener.java
deleted file mode 100644 (file)
index 4e5d11c..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package net.mograsim.plugin.memory;
-
-import org.eclipse.swt.events.VerifyEvent;
-import org.eclipse.swt.events.VerifyListener;
-import org.eclipse.swt.widgets.Text;
-
-import net.mograsim.plugin.asm.AsmNumberUtil;
-import net.mograsim.plugin.asm.AsmNumberUtil.NumberType;
-
-public class NumberVerifyListener implements VerifyListener
-{
-
-       @Override
-       public void verifyText(VerifyEvent e)
-       {
-               String text = computeModifiedText(e);
-               e.doit = !NumberType.NONE.equals(AsmNumberUtil.prefixOfType(text));
-       }
-
-       private static String computeModifiedText(VerifyEvent e)
-       {
-               String modifiedText = ((Text) e.getSource()).getText();
-               modifiedText = modifiedText.substring(0, e.start).concat(e.text).concat(modifiedText.substring(e.end));
-               return modifiedText;
-       }
-}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/NumberCellEditingSupport.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/NumberCellEditingSupport.java
new file mode 100644 (file)
index 0000000..7bba426
--- /dev/null
@@ -0,0 +1,63 @@
+package net.mograsim.plugin.tables;
+
+import java.math.BigInteger;
+
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.EditingSupport;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TextCellEditor;
+
+import net.mograsim.plugin.asm.AsmNumberUtil;
+import net.mograsim.plugin.tables.memory.DisplaySettings;
+
+public abstract class NumberCellEditingSupport extends EditingSupport
+{
+       private final TableViewer viewer;
+       private final CellEditor editor;
+       private final DisplaySettings displaySettings;
+
+       public NumberCellEditingSupport(TableViewer viewer, DisplaySettings displaySettings)
+       {
+               super(viewer);
+               this.viewer = viewer;
+               this.displaySettings = displaySettings;
+               editor = new TextCellEditor(viewer.getTable());
+               editor.setValidator(new NumberCellEditorValidator());
+       }
+
+       @Override
+       final protected boolean canEdit(Object element)
+       {
+               return true;
+       }
+
+       @Override
+       final protected CellEditor getCellEditor(Object element)
+       {
+               return editor;
+       }
+
+       @Override
+       final protected Object getValue(Object element)
+       {
+               return AsmNumberUtil.toString(getAsBigInteger(element), displaySettings.getDataNumberType());
+       }
+
+       @Override
+       final protected void setValue(Object element, Object userInput)
+       {
+               try
+               {
+                       setAsBigInteger(element, AsmNumberUtil.valueOf((String) userInput));
+               }
+               catch (@SuppressWarnings("unused") NumberFormatException e)
+               {
+                       setAsBigInteger(element, BigInteger.valueOf(0));
+               }
+               viewer.update(element, null);
+       }
+
+       protected abstract void setAsBigInteger(Object element, BigInteger value);
+
+       protected abstract BigInteger getAsBigInteger(Object element);
+}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/NumberCellEditorValidator.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/NumberCellEditorValidator.java
new file mode 100644 (file)
index 0000000..e0b445d
--- /dev/null
@@ -0,0 +1,17 @@
+package net.mograsim.plugin.tables;
+
+import org.eclipse.jface.viewers.ICellEditorValidator;
+
+import net.mograsim.plugin.asm.AsmNumberUtil;
+
+public class NumberCellEditorValidator implements ICellEditorValidator
+{
+
+       @Override
+       public String isValid(Object value)
+       {
+               return AsmNumberUtil.NumberType.NONE.equals(AsmNumberUtil.getType((String) value)) ? (String) value + "is not a valid number"
+                               : null;
+       }
+
+}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/NumberColumnLabelProvider.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/NumberColumnLabelProvider.java
new file mode 100644 (file)
index 0000000..35f032a
--- /dev/null
@@ -0,0 +1,26 @@
+package net.mograsim.plugin.tables;
+
+import java.math.BigInteger;
+
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+
+import net.mograsim.plugin.asm.AsmNumberUtil;
+import net.mograsim.plugin.tables.memory.DisplaySettings;
+
+public abstract class NumberColumnLabelProvider extends ColumnLabelProvider
+{
+       private DisplaySettings displaySettings;
+
+       public NumberColumnLabelProvider(DisplaySettings displaySettings)
+       {
+               this.displaySettings = displaySettings;
+       }
+
+       @Override
+       public String getText(Object element)
+       {
+               return AsmNumberUtil.toString(getAsBigInteger(element), displaySettings.getDataNumberType());
+       }
+
+       public abstract BigInteger getAsBigInteger(Object element);
+}
\ No newline at end of file
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/DisplaySettings.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/DisplaySettings.java
new file mode 100644 (file)
index 0000000..8816a52
--- /dev/null
@@ -0,0 +1,23 @@
+package net.mograsim.plugin.tables.memory;
+
+import net.mograsim.plugin.asm.AsmNumberUtil.NumberType;
+
+public class DisplaySettings
+{
+       private NumberType dataNumberType;
+
+       public DisplaySettings(NumberType dataNumberType)
+       {
+               this.dataNumberType = dataNumberType;
+       }
+
+       public NumberType getDataNumberType()
+       {
+               return dataNumberType;
+       }
+
+       public void setDataNumberType(NumberType dataNumberType)
+       {
+               this.dataNumberType = dataNumberType;
+       }
+}
\ No newline at end of file
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryCellEditingSupport.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryCellEditingSupport.java
new file mode 100644 (file)
index 0000000..94f1821
--- /dev/null
@@ -0,0 +1,29 @@
+package net.mograsim.plugin.tables.memory;
+
+import java.math.BigInteger;
+
+import org.eclipse.jface.viewers.TableViewer;
+
+import net.mograsim.plugin.tables.NumberCellEditingSupport;
+
+public class MemoryCellEditingSupport extends NumberCellEditingSupport
+{
+       public MemoryCellEditingSupport(TableViewer viewer, DisplaySettings displaySettings)
+       {
+               super(viewer, displaySettings);
+       }
+
+       @Override
+       protected void setAsBigInteger(Object element, BigInteger value)
+       {
+               MemoryTableRow row = (MemoryTableRow) element;
+               row.getMemory().setCellAsBigInteger(row.address, value);
+       }
+
+       @Override
+       protected BigInteger getAsBigInteger(Object element)
+       {
+               MemoryTableRow row = (MemoryTableRow) element;
+               return row.getMemory().getCellAsBigInteger(row.address);
+       }
+}
\ No newline at end of file
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryTableContentProvider.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryTableContentProvider.java
new file mode 100644 (file)
index 0000000..aaecc75
--- /dev/null
@@ -0,0 +1,79 @@
+package net.mograsim.plugin.tables.memory;
+
+import org.eclipse.jface.viewers.ILazyContentProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.widgets.Display;
+
+import net.mograsim.machine.MainMemory;
+import net.mograsim.machine.MemoryObserver;
+
+public class MemoryTableContentProvider implements ILazyContentProvider, MemoryObserver
+{
+       private long lower;
+       private TableViewer viewer;
+       private final static int limit = 10_000;
+       private int amount = 0;
+       private MainMemory memory;
+
+       public void setLowerBound(long lower)
+       {
+               if (memory != null)
+                       this.lower = Long.min(memory.getDefinition().getMaximalAddress(), Long.max(memory.getDefinition().getMinimalAddress(), lower));
+               else
+                       this.lower = lower;
+               updateItemCount();
+       }
+
+       public void updateItemCount()
+       {
+               if (memory != null)
+               {
+                       long size = memory.getDefinition().getMaximalAddress() - lower;
+                       viewer.setItemCount(size > amount ? amount : (int) size);
+               } else
+                       viewer.setItemCount(0);
+       }
+
+       public long getLowerBound()
+       {
+               return lower;
+       }
+
+       public void setAmount(int amount)
+       {
+               this.amount = Integer.min(amount, limit);
+               updateItemCount();
+       }
+
+       public int getAmount()
+       {
+               return amount;
+       }
+
+       @Override
+       public void updateElement(int index)
+       {
+               long address = lower + index;
+               if (address <= memory.getDefinition().getMaximalAddress())
+                       viewer.replace(new MemoryTableRow(address, memory), index);
+       }
+
+       @Override
+       public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
+       {
+               this.viewer = (TableViewer) viewer;
+               this.memory = (MainMemory) newInput;
+               if (oldInput != null)
+                       ((MainMemory) oldInput).deregisterObserver(this);
+               if (memory != null)
+                       memory.registerObserver(this);
+               setLowerBound(0L);
+       }
+
+       @Override
+       public void update(long address)
+       {
+               Display.getDefault().asyncExec(() -> updateElement((int) (address - lower)));
+       }
+}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryTableRow.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryTableRow.java
new file mode 100644 (file)
index 0000000..6f1c353
--- /dev/null
@@ -0,0 +1,20 @@
+package net.mograsim.plugin.tables.memory;
+
+import net.mograsim.machine.MainMemory;
+
+public class MemoryTableRow
+{
+       public final long address;
+       private final MainMemory memory;
+
+       public MemoryTableRow(long address, MainMemory memory)
+       {
+               this.address = address;
+               this.memory = memory;
+       }
+
+       public MainMemory getMemory()
+       {
+               return memory;
+       }
+}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryView.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/MemoryView.java
new file mode 100644 (file)
index 0000000..98983a6
--- /dev/null
@@ -0,0 +1,194 @@
+package net.mograsim.plugin.tables.memory;
+
+import java.math.BigInteger;
+
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.part.ViewPart;
+
+import net.mograsim.machine.MainMemory;
+import net.mograsim.machine.MainMemoryDefinition;
+import net.mograsim.machine.standard.memory.WordAddressableMemory;
+import net.mograsim.plugin.asm.AsmNumberUtil;
+import net.mograsim.plugin.asm.AsmNumberUtil.NumberType;
+import net.mograsim.plugin.tables.NumberColumnLabelProvider;
+
+public class MemoryView extends ViewPart
+{
+       private TableViewer viewer;
+       private MemoryTableContentProvider provider;
+       private DisplaySettings displaySettings;
+       private String addressFormat;
+
+       @Override
+       public void createPartControl(Composite parent)
+       {
+               provider = new MemoryTableContentProvider();
+               displaySettings = new DisplaySettings(NumberType.HEXADECIMAL);
+
+               GridLayout layout = new GridLayout(6, false);
+               parent.setLayout(layout);
+               Label fromLabel = new Label(parent, SWT.NONE);
+               fromLabel.setText("Address: ");
+               Text fromText = new Text(parent, SWT.BORDER | SWT.SEARCH);
+               fromText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL));
+               VerifyListener vl = new NumberVerifyListener();
+               fromText.addVerifyListener(vl);
+               fromText.setText("0");
+               fromText.addModifyListener(e ->
+               {
+                       try
+                       {
+                               provider.setLowerBound(AsmNumberUtil.valueOf(fromText.getText()).longValue());
+                               viewer.refresh();
+                       }
+                       catch (@SuppressWarnings("unused") NumberFormatException ex)
+                       {
+                               // Nothing to do here
+                       }
+               });
+
+               Label amountLabel = new Label(parent, SWT.NONE);
+               amountLabel.setText("Number of cells: ");
+               Text amountText = new Text(parent, SWT.BORDER | SWT.SEARCH);
+               amountText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL));
+               amountText.addVerifyListener(vl);
+               amountText.setText("0");
+               amountText.addModifyListener(e ->
+               {
+                       try
+                       {
+                               provider.setAmount(AsmNumberUtil.valueOf(amountText.getText()).intValue());
+                               viewer.refresh();
+                       }
+                       catch (@SuppressWarnings("unused") NumberFormatException ex)
+                       {
+                               // Nothing to do here
+                       }
+               });
+
+               setupRadixSelector(parent);
+
+               createViewer(parent);
+       }
+
+       private void setupRadixSelector(Composite parent)
+       {
+               Label radixLabel = new Label(parent, SWT.NONE);
+               radixLabel.setText("Radix: ");
+               Combo selectRadix = new Combo(parent, SWT.READ_ONLY);
+
+               String entries[] = new String[] { "Binary", "Octal", "Decimal", "Hexadecimal" };
+               NumberType corTypes[] = new NumberType[] { NumberType.BINARY, NumberType.OCTAL, NumberType.DECIMAL, NumberType.HEXADECIMAL };
+               selectRadix.setItems(entries);
+               selectRadix.addSelectionListener(new SelectionListener()
+               {
+                       @Override
+                       public void widgetSelected(SelectionEvent e)
+                       {
+                               int index = selectRadix.getSelectionIndex();
+                               if (index == -1)
+                                       displaySettings.setDataNumberType(NumberType.HEXADECIMAL);
+                               else
+                               {
+                                       displaySettings.setDataNumberType(corTypes[index]);
+                               }
+                               viewer.refresh();
+                       }
+
+                       @Override
+                       public void widgetDefaultSelected(SelectionEvent e)
+                       {
+                               widgetSelected(e);
+                       }
+               });
+       }
+
+       private void createViewer(Composite parent)
+       {
+               viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER | SWT.VIRTUAL);
+               createColumns();
+               Table table = viewer.getTable();
+               table.setHeaderVisible(true);
+               table.setLinesVisible(true);
+               viewer.setUseHashlookup(true);
+               viewer.setContentProvider(provider);
+               setMemoryBinding(new WordAddressableMemory(MainMemoryDefinition.create(8, 8, 8L, Long.MAX_VALUE)));
+               getSite().setSelectionProvider(viewer);
+
+               GridData gd = new GridData();
+               gd.verticalAlignment = GridData.FILL;
+               gd.horizontalSpan = 6;
+               gd.grabExcessHorizontalSpace = true;
+               gd.grabExcessVerticalSpace = true;
+               gd.horizontalAlignment = GridData.FILL;
+               viewer.getControl().setLayoutData(gd);
+       }
+
+       private void createColumns()
+       {
+               String[] titles = { "Address", "Data" };
+               int[] bounds = { 100, 100 };
+
+               TableViewerColumn col = createTableViewerColumn(titles[0], bounds[0]);
+               col.setLabelProvider(new ColumnLabelProvider()
+               {
+                       @Override
+                       public String getText(Object element)
+                       {
+                               MemoryTableRow row = (MemoryTableRow) element;
+                               return String.format(addressFormat, row.address);
+                       }
+               });
+
+               col = createTableViewerColumn(titles[1], bounds[1]);
+               col.setLabelProvider(new NumberColumnLabelProvider(displaySettings)
+               {
+                       @Override
+                       public BigInteger getAsBigInteger(Object element)
+                       {
+                               MemoryTableRow row = (MemoryTableRow) element;
+                               return row.getMemory().getCellAsBigInteger(row.address);
+                       }
+
+               });
+               col.setEditingSupport(new MemoryCellEditingSupport(viewer, displaySettings));
+       }
+
+       private TableViewerColumn createTableViewerColumn(String title, int bound)
+       {
+               TableViewerColumn viewerColumn = new TableViewerColumn(viewer, SWT.NONE);
+               TableColumn column = viewerColumn.getColumn();
+               column.setText(title);
+               column.setWidth(bound);
+               column.setResizable(true);
+               column.setMoveable(false);
+               return viewerColumn;
+       }
+
+       @Override
+       public void setFocus()
+       {
+               viewer.getControl().setFocus();
+       }
+
+       public void setMemoryBinding(MainMemory m)
+       {
+               int hexAddressLength = Long.toUnsignedString(m.getDefinition().getMaximalAddress(), 16).length();
+               addressFormat = "0x%0" + hexAddressLength + "X";
+               viewer.setInput(m);
+       }
+}
diff --git a/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/NumberVerifyListener.java b/net.mograsim.plugin.core/src/net/mograsim/plugin/tables/memory/NumberVerifyListener.java
new file mode 100644 (file)
index 0000000..54d7176
--- /dev/null
@@ -0,0 +1,26 @@
+package net.mograsim.plugin.tables.memory;
+
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.widgets.Text;
+
+import net.mograsim.plugin.asm.AsmNumberUtil;
+import net.mograsim.plugin.asm.AsmNumberUtil.NumberType;
+
+public class NumberVerifyListener implements VerifyListener
+{
+
+       @Override
+       public void verifyText(VerifyEvent e)
+       {
+               String text = computeModifiedText(e);
+               e.doit = !NumberType.NONE.equals(AsmNumberUtil.prefixOfType(text));
+       }
+
+       private static String computeModifiedText(VerifyEvent e)
+       {
+               String modifiedText = ((Text) e.getSource()).getText();
+               modifiedText = modifiedText.substring(0, e.start).concat(e.text).concat(modifiedText.substring(e.end));
+               return modifiedText;
+       }
+}