Finished MPROM support. Fixes #10
[Mograsim.git] / plugins / net.mograsim.machine / src / net / mograsim / machine / standard / memory / AbstractModelBitVectorMemory.java
diff --git a/plugins/net.mograsim.machine/src/net/mograsim/machine/standard/memory/AbstractModelBitVectorMemory.java b/plugins/net.mograsim.machine/src/net/mograsim/machine/standard/memory/AbstractModelBitVectorMemory.java
new file mode 100644 (file)
index 0000000..055fb4f
--- /dev/null
@@ -0,0 +1,141 @@
+package net.mograsim.machine.standard.memory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+
+import net.mograsim.logic.model.model.LogicModelModifiable;
+import net.mograsim.logic.model.model.wires.Pin;
+import net.mograsim.logic.model.model.wires.PinUsage;
+import net.mograsim.logic.model.modeladapter.LogicCoreAdapter;
+import net.mograsim.logic.model.serializing.IdentifyParams;
+import net.mograsim.logic.model.snippets.HighLevelStateHandler;
+import net.mograsim.machine.BitVectorMemory;
+import net.mograsim.machine.BitVectorMemoryDefinition;
+import net.mograsim.machine.ModelMemory;
+
+public abstract class AbstractModelBitVectorMemory<M extends BitVectorMemory, D extends BitVectorMemoryDefinition> extends ModelMemory
+{
+       private final Pin addrPin, dataPin, rWPin;
+       private final D definition;
+       private final boolean readonly;
+
+       private CoreBitVectorMemory<M> memory;
+
+       private final List<Consumer<Object>> memoryBindingListeners;
+
+       public AbstractModelBitVectorMemory(LogicModelModifiable model, int width, int height, int aPinX, int dPinX, int rwPinX,
+                       boolean readonly, String centerText, D definition, String name)
+       {
+               super(model, width, height, name, centerText, false);
+               this.definition = definition;
+               this.readonly = readonly;
+
+               addPin(addrPin = new Pin(model, this, "A", definition.getMemoryAddressBits(), PinUsage.INPUT, width, aPinX));
+               addPin(dataPin = new Pin(model, this, "D", definition.getCellWidth(), PinUsage.TRISTATE, width, dPinX));
+               if (readonly)
+                       rWPin = null;
+               else
+                       addPin(rWPin = new Pin(model, this, "RW", 1, PinUsage.INPUT, width, rwPinX));
+
+               memoryBindingListeners = new ArrayList<>();
+
+               setHighLevelStateHandler(new HighLevelStateHandler()
+               {
+                       @Override
+                       public Object get(String stateID)
+                       {
+                               if (stateID.equals("memory_binding"))
+                                       return memory.getMemory();
+                               throw new IllegalArgumentException("No high level state with ID " + stateID);
+                       }
+
+                       @Override
+                       public void set(String stateID, Object newState)
+                       {
+                               if (stateID.equals("memory_binding"))
+                               {
+                                       @SuppressWarnings("unchecked")
+                                       M mem = (M) newState;
+                                       memory.setMemory(mem);
+                                       memoryBindingListeners.forEach(l -> l.accept(newState));
+                               } else
+                                       throw new IllegalArgumentException("No high level state with ID " + stateID);
+                       }
+
+                       @Override
+                       public void addListener(String stateID, Consumer<Object> stateChanged)
+                       {
+                               if (stateID.equals("memory_binding"))
+                                       memoryBindingListeners.add(stateChanged);
+                               else
+                                       throw new IllegalArgumentException("No high level state with ID " + stateID);
+                       }
+
+                       @Override
+                       public void removeListener(String stateID, Consumer<Object> stateChanged)
+                       {
+                               if (stateID.equals("memory_binding"))
+                                       memoryBindingListeners.remove(stateChanged);
+                               else
+                                       throw new IllegalArgumentException("No high level state with ID " + stateID);
+                       }
+
+                       @Override
+                       public String getIDForSerializing(IdentifyParams idParams)
+                       {
+                               return null;
+                       }
+
+                       @Override
+                       public Object getParamsForSerializing(IdentifyParams idParams)
+                       {
+                               return null;
+                       }
+               });
+
+               init();
+       }
+
+       public D getDefinition()
+       {
+               return definition;
+       }
+
+       public Pin getAddressPin()
+       {
+               return addrPin;
+       }
+
+       public Pin getDataPin()
+       {
+               return dataPin;
+       }
+
+       public Pin getReadWritePin()
+       {
+               if (isReadonly())
+                       throw new IllegalArgumentException("This AbstractModelBitVectorMemory has no RW pin; it is readonly");
+               return rWPin;
+       }
+
+       public boolean isReadonly()
+       {
+               return readonly;
+       }
+
+       public void setCoreModelBinding(CoreBitVectorMemory<M> memory)
+       {
+               this.memory = memory;
+       }
+
+       public CoreBitVectorMemory<M> getCoreMemory()
+       {
+               return memory;
+       }
+
+       static
+       {
+               LogicCoreAdapter.addComponentAdapter(new BitVectorMemoryAdapter());
+       }
+}
\ No newline at end of file