Made Am2910 components usable in Editor
[Mograsim.git] / net.mograsim.logic.model.am2900 / src / net / mograsim / logic / model / am2900 / components / am2910 / GUIAm2910SP.java
1 package net.mograsim.logic.model.am2900.components.am2910;
2
3 import static net.mograsim.logic.core.types.Bit.ONE;
4 import static net.mograsim.logic.core.types.Bit.U;
5 import static net.mograsim.logic.core.types.Bit.X;
6 import static net.mograsim.logic.core.types.Bit.ZERO;
7
8 import java.util.Map;
9
10 import net.mograsim.logic.core.types.Bit;
11 import net.mograsim.logic.core.types.BitVector;
12 import net.mograsim.logic.core.wires.Wire.ReadEnd;
13 import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
14 import net.mograsim.logic.model.model.ViewModelModifiable;
15 import net.mograsim.logic.model.model.components.atomic.SimpleRectangularHardcodedGUIComponent;
16 import net.mograsim.logic.model.model.wires.Pin;
17 import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator;
18 import net.mograsim.logic.model.snippets.symbolrenderers.PinNamesSymbolRenderer.PinNamesParams.Position;
19
20 public class GUIAm2910SP extends SimpleRectangularHardcodedGUIComponent
21 {
22         public GUIAm2910SP(ViewModelModifiable model, String name)
23         {
24                 super(model, name, "Stack\npointer");
25                 setSize(40, 30);
26                 addPin(new Pin(this, "STKI0", 1, 0, 5), Usage.INPUT, Position.RIGHT);
27                 addPin(new Pin(this, "STKI1", 1, 0, 15), Usage.INPUT, Position.RIGHT);
28                 addPin(new Pin(this, "C", 1, 0, 25), Usage.INPUT, Position.RIGHT);
29                 addPin(new Pin(this, "A", 3, 10, 30), Usage.OUTPUT, Position.TOP);
30                 addPin(new Pin(this, "B", 3, 30, 30), Usage.OUTPUT, Position.TOP);
31                 addPin(new Pin(this, "_FULL", 1, 40, 15), Usage.OUTPUT, Position.LEFT);
32         }
33
34         @Override
35         protected Object recalculate(Object lastState, Map<String, ReadEnd> readEnds, Map<String, ReadWriteEnd> readWriteEnds)
36         {
37                 BitAndInt SPC = (BitAndInt) lastState;
38                 if (SPC == null)
39                 {
40                         SPC = new BitAndInt();
41                         SPC.bit = U;
42                         SPC.i = -2;
43                 }
44                 int SP = SPC.i;
45
46                 Bit STKI0Val = readEnds.get("STKI0").getValue();
47                 Bit STKI1Val = readEnds.get("STKI1").getValue();
48                 Bit CVal = readEnds.get("C").getValue();
49                 if (SPC.bit == ZERO && CVal == ONE)
50                         if (STKI0Val == U && STKI1Val == U)
51                                 SP = -2;
52                         else if (!STKI0Val.isBinary() || !STKI1Val.isBinary())
53                                 SP = -1;
54                         else if (STKI0Val == ONE && STKI1Val == ZERO)
55                         {
56                                 // PUSH
57                                 if (SP >= 0)
58                                         SP = SP == 5 ? 5 : SP + 1;
59                         } else if (STKI0Val == ZERO && STKI1Val == ONE)
60                                 // CLEAR
61                                 SP = 0;
62                         else if (STKI0Val == ONE && STKI1Val == ONE)
63                                 // POP
64                                 SP = SP <= 0 ? SP : SP - 1;
65                 readWriteEnds.get("A").feedSignals(getAsBitVector(SP == 0 ? 7 : SP - 1));
66                 readWriteEnds.get("B").feedSignals(getAsBitVector(SP == 5 ? 4 : SP));
67                 readWriteEnds.get("_FULL").feedSignals(SP == -2 ? U : SP == -1 ? X : SP == 5 ? ZERO : ONE);
68
69                 SPC.i = SP;
70                 SPC.bit = CVal;
71                 return SPC;
72         }
73
74         private static class BitAndInt
75         {
76                 Bit bit;
77                 int i;
78         }
79
80         /**
81          * -1 means X, -2 means U
82          */
83         private static BitVector getAsBitVector(int i)
84         {
85                 if (i == -1)
86                         return BitVector.of(X, 3);
87                 if (i == -2)
88                         return BitVector.of(U, 3);
89                 // TODO maybe this is the wrong way around
90                 return BitVector.of((i & 0b100) > 0 ? ONE : ZERO, (i & 0b10) > 0 ? ONE : ZERO, (i & 0b1) > 0 ? ONE : ZERO);
91         }
92
93         static
94         {
95                 IndirectGUIComponentCreator.setComponentSupplier(GUIAm2910SP.class.getCanonicalName(), (m, p, n) -> new GUIAm2910SP(m, n));
96         }
97 }