Fixed X/U/Z handling in GUIAm2904RegCTInstrDecode/ShiftInstrDecode
[Mograsim.git] / net.mograsim.logic.model.am2900 / src / net / mograsim / logic / model / am2900 / components / am2904 / GUIAm2904ShiftInstrDecode.java
1 package net.mograsim.logic.model.am2900.components.am2904;
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.Z;
7 import static net.mograsim.logic.core.types.Bit.ZERO;
8
9 import java.util.Map;
10
11 import net.mograsim.logic.core.types.Bit;
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 GUIAm2904ShiftInstrDecode extends SimpleRectangularHardcodedGUIComponent
21 {
22         public GUIAm2904ShiftInstrDecode(ViewModelModifiable model, String name)
23         {
24                 super(model, name, "Shift \ninstruction\ndecode");
25                 setSize(60, 70);
26                 addPin(new Pin(this, "I", 5, 0, 35), Usage.INPUT, Position.RIGHT);
27                 // SIO0 MUX:
28                 // 000: 0
29                 // 001: 1
30                 // 01x: SIOn
31                 // 10x: QIOn
32                 // 11x: MC
33                 addPin(new Pin(this, "SIO0_MUX", 3, 60, 5), Usage.OUTPUT, Position.LEFT);
34                 // SIOn MUX:
35                 // 000: 0
36                 // 001: 1
37                 // 010: SIO0
38                 // 011: QIO0
39                 // 100: MC
40                 // 101: MN
41                 // 110: IC
42                 // 111: IN xor IVOR
43                 addPin(new Pin(this, "SIOn_MUX", 3, 60, 15), Usage.OUTPUT, Position.LEFT);
44                 // QIO0 MUX:
45                 // 000: 0
46                 // 001: 1
47                 // 01x: SIOn
48                 // 10x: QIOn
49                 // 11x: MC
50                 addPin(new Pin(this, "QIO0_MUX", 3, 60, 25), Usage.OUTPUT, Position.LEFT);
51                 // QIOn MUX:
52                 // 000: 0
53                 // 001: 1
54                 // 01x: SIO0
55                 // 10x: QIO0
56                 // 11x: MN
57                 addPin(new Pin(this, "QIOn_MUX", 3, 60, 35), Usage.OUTPUT, Position.LEFT);
58                 addPin(new Pin(this, "LSHIFT", 1, 60, 45), Usage.OUTPUT, Position.LEFT);
59                 // 00: SIO0
60                 // 01: QIO0
61                 // 1x: SIOn
62                 addPin(new Pin(this, "MC_MUX", 2, 60, 55), Usage.OUTPUT, Position.LEFT);
63                 addPin(new Pin(this, "MC_EN", 1, 60, 65), Usage.OUTPUT, Position.LEFT);
64         }
65
66         @Override
67         protected Object recalculate(Object lastState, Map<String, ReadEnd> readEnds, Map<String, ReadWriteEnd> readWriteEnds)
68         {
69                 Bit[] IBits = readEnds.get("I").getValues().getBits();
70                 readWriteEnds.get("LSHIFT").feedSignals(IBits[0]);
71                 // TODO move the following loop to BitVector.
72                 int IAsInt = 0;
73                 for (int i = 0; i < 5; i++)
74                         switch (IBits[4 - i])
75                         {
76                         case ONE:
77                                 IAsInt |= 1 << i;
78                                 break;
79                         case U:
80                                 readWriteEnds.get("SIO0_MUX").feedSignals(U, U, U);
81                                 readWriteEnds.get("SIOn_MUX").feedSignals(U, U, U);
82                                 readWriteEnds.get("QIO0_MUX").feedSignals(U, U, U);
83                                 readWriteEnds.get("QIOn_MUX").feedSignals(U, U, U);
84                                 readWriteEnds.get("MC_MUX").feedSignals(U, U);
85                                 readWriteEnds.get("MC_EN").feedSignals(U);
86                                 return null;
87                         case X:
88                         case Z:
89                                 readWriteEnds.get("SIO0_MUX").feedSignals(X, X, X);
90                                 readWriteEnds.get("SIOn_MUX").feedSignals(X, X, X);
91                                 readWriteEnds.get("QIO0_MUX").feedSignals(X, X, X);
92                                 readWriteEnds.get("QIOn_MUX").feedSignals(X, X, X);
93                                 readWriteEnds.get("MC_MUX").feedSignals(X, X);
94                                 readWriteEnds.get("MC_EN").feedSignals(X);
95                                 return null;
96                         case ZERO:
97                                 break;
98                         default:
99                                 throw new IllegalArgumentException("Unknown enum constant: " + IBits[i]);
100                         }
101                 if (IAsInt < 16)
102                 {
103                         readWriteEnds.get("SIO0_MUX").feedSignals(Z, Z, Z);
104                         readWriteEnds.get("QIO0_MUX").feedSignals(Z, Z, Z);
105                         switch (IAsInt)
106                         {
107                         case 0:
108                         case 2:
109                         case 6:
110                         case 7:
111                                 readWriteEnds.get("SIOn_MUX").feedSignals(ZERO, ZERO, ZERO);
112                                 break;
113                         case 1:
114                         case 3:
115                                 readWriteEnds.get("SIOn_MUX").feedSignals(ZERO, ZERO, ONE);
116                                 break;
117                         case 4:
118                         case 9:
119                         case 12:
120                                 readWriteEnds.get("SIOn_MUX").feedSignals(ONE, ZERO, ZERO);
121                                 break;
122                         case 5:
123                                 readWriteEnds.get("SIOn_MUX").feedSignals(ONE, ZERO, ONE);
124                                 break;
125                         case 8:
126                         case 10:
127                                 readWriteEnds.get("SIOn_MUX").feedSignals(ZERO, ONE, ZERO);
128                                 break;
129                         case 11:
130                                 readWriteEnds.get("SIOn_MUX").feedSignals(ONE, ONE, ZERO);
131                                 break;
132                         case 13:
133                         case 15:
134                                 readWriteEnds.get("SIOn_MUX").feedSignals(ZERO, ONE, ONE);
135                                 break;
136                         case 14:
137                                 readWriteEnds.get("SIOn_MUX").feedSignals(ONE, ONE, ONE);
138                                 break;
139                         default:
140                                 throw new IllegalStateException("can't happen");
141                         }
142                         switch (IAsInt)
143                         {
144                         case 0:
145                                 readWriteEnds.get("QIOn_MUX").feedSignals(ZERO, ZERO, ZERO);
146                                 break;
147                         case 1:
148                                 readWriteEnds.get("QIOn_MUX").feedSignals(ZERO, ZERO, ONE);
149                                 break;
150                         case 2:
151                                 readWriteEnds.get("QIOn_MUX").feedSignals(ONE, ONE, Z);
152                                 break;
153                         case 3:
154                         case 4:
155                         case 5:
156                         case 6:
157                         case 7:
158                         case 11:
159                         case 12:
160                         case 13:
161                         case 14:
162                         case 15:
163                                 readWriteEnds.get("QIOn_MUX").feedSignals(ZERO, ONE, Z);
164                                 break;
165                         case 8:
166                         case 9:
167                         case 10:
168                                 readWriteEnds.get("QIOn_MUX").feedSignals(ONE, ZERO, Z);
169                                 break;
170                         default:
171                                 throw new IllegalStateException("can't happen");
172                         }
173                 } else
174                 {
175                         readWriteEnds.get("SIOn_MUX").feedSignals(Z, Z, Z);
176                         readWriteEnds.get("QIOn_MUX").feedSignals(Z, Z, Z);
177                         switch (IAsInt)
178                         {
179                         case 16:
180                         case 18:
181                                 readWriteEnds.get("SIO0_MUX").feedSignals(ZERO, ZERO, ZERO);
182                                 break;
183                         case 17:
184                         case 19:
185                                 readWriteEnds.get("SIO0_MUX").feedSignals(ZERO, ZERO, ONE);
186                                 break;
187                         case 20:
188                         case 21:
189                         case 22:
190                         case 23:
191                         case 28:
192                         case 29:
193                         case 30:
194                         case 31:
195                                 readWriteEnds.get("SIO0_MUX").feedSignals(ONE, ZERO, Z);
196                                 break;
197                         case 24:
198                         case 26:
199                                 readWriteEnds.get("SIO0_MUX").feedSignals(ONE, ONE, Z);
200                                 break;
201                         case 25:
202                         case 27:
203                                 readWriteEnds.get("SIO0_MUX").feedSignals(ZERO, ONE, Z);
204                                 break;
205                         default:
206                                 throw new IllegalStateException("can't happen");
207                         }
208                         switch (IAsInt)
209                         {
210                         case 16:
211                         case 18:
212                         case 20:
213                         case 22:
214                         case 27:
215                                 readWriteEnds.get("QIO0_MUX").feedSignals(ZERO, ZERO, ZERO);
216                                 break;
217                         case 17:
218                         case 19:
219                         case 21:
220                         case 23:
221                                 readWriteEnds.get("QIO0_MUX").feedSignals(ZERO, ZERO, ONE);
222                                 break;
223                         case 24:
224                         case 25:
225                         case 26:
226                                 readWriteEnds.get("SIO0_MUX").feedSignals(ONE, ZERO, Z);
227                                 break;
228                         case 28:
229                         case 30:
230                                 readWriteEnds.get("SIO0_MUX").feedSignals(ONE, ONE, Z);
231                                 break;
232                         case 29:
233                         case 31:
234                                 readWriteEnds.get("QIO0_MUX").feedSignals(ZERO, ONE, Z);
235                                 break;
236                         default:
237                                 throw new IllegalStateException("can't happen");
238                         }
239                 }
240                 // MC
241                 switch (IAsInt)
242                 {
243                 case 0:
244                 case 1:
245                 case 3:
246                 case 4:
247                 case 5:
248                 case 6:
249                 case 10:
250                 case 11:
251                 case 14:
252                 case 15:
253                 case 18:
254                 case 19:
255                 case 22:
256                 case 23:
257                 case 26:
258                 case 27:
259                 case 30:
260                 case 31:
261                         readWriteEnds.get("MC_EN").feedSignals(ZERO);
262                         readWriteEnds.get("MC_MUX").feedSignals(Z, Z);
263                         break;
264                 case 2:
265                 case 8:
266                 case 9:
267                         readWriteEnds.get("MC_EN").feedSignals(ONE);
268                         readWriteEnds.get("MC_MUX").feedSignals(ZERO, ZERO);
269                         break;
270                 case 7:
271                 case 12:
272                 case 13:
273                         readWriteEnds.get("MC_EN").feedSignals(ONE);
274                         readWriteEnds.get("MC_MUX").feedSignals(ZERO, ONE);
275                         break;
276                 case 16:
277                 case 17:
278                 case 20:
279                 case 21:
280                 case 24:
281                 case 25:
282                 case 28:
283                 case 29:
284                         readWriteEnds.get("MC_EN").feedSignals(ONE);
285                         readWriteEnds.get("MC_MUX").feedSignals(ONE, Z);
286                         break;
287                 default:
288                         throw new IllegalStateException("can't happen");
289                 }
290                 return null;
291         }
292
293         static
294         {
295                 IndirectGUIComponentCreator.setComponentSupplier(GUIAm2904ShiftInstrDecode.class.getCanonicalName(),
296                                 (m, p, n) -> new GUIAm2904ShiftInstrDecode(m, n));
297         }
298 }