Fleshed out Memory and Microprogramming interfaces
authorFabian Stemmler <stemmler@in.tum.de>
Sat, 31 Aug 2019 14:47:18 +0000 (16:47 +0200)
committerFabian Stemmler <stemmler@in.tum.de>
Sat, 31 Aug 2019 14:47:18 +0000 (16:47 +0200)
26 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

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();