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