Fixed two problems causing memory updates to get "missed" by observers
[Mograsim.git] / net.mograsim.machine / src / net / mograsim / machine / mi / MicroInstructionDefinition.java
1 package net.mograsim.machine.mi;
2
3 import java.math.BigInteger;
4 import java.util.Arrays;
5 import java.util.Optional;
6
7 import net.mograsim.logic.core.types.Bit;
8 import net.mograsim.machine.mi.parameters.IntegerClassification;
9 import net.mograsim.machine.mi.parameters.IntegerImmediate;
10 import net.mograsim.machine.mi.parameters.MicroInstructionParameter;
11 import net.mograsim.machine.mi.parameters.MicroInstructionParameter.ParameterType;
12 import net.mograsim.machine.mi.parameters.MnemonicFamily;
13 import net.mograsim.machine.mi.parameters.ParameterClassification;
14
15 public interface MicroInstructionDefinition
16 {
17         /**
18          * @return The {@link ParameterClassification}s of which a MicroInstruction is composed.
19          */
20         public ParameterClassification[] getParameterClassifications();
21
22         /**
23          * @throws IndexOutOfBoundsException
24          */
25         public ParameterClassification getParameterClassification(int index);
26
27         /**
28          * @return The amount of {@link MicroInstructionParameter}s in a {@link MicroInstruction} that follows this definition.
29          */
30         public default int size()
31         {
32                 return getParameterClassifications().length;
33         }
34
35         /**
36          * @return The amount of {@link Bit}s in a {@link MicroInstruction} that follows this definition.
37          */
38         public default int sizeInBits()
39         {
40                 return Arrays.stream(getParameterClassifications()).mapToInt(e -> e.getExpectedBits()).reduce(0, (a, b) -> a + b);
41         }
42
43         public default MicroInstruction createDefaultInstruction(Runnable updateCallback)
44         {
45                 int size = size();
46                 MicroInstructionParameter[] params = new MicroInstructionParameter[size];
47                 ParameterClassification[] classes = getParameterClassifications();
48                 for (int i = 0; i < size; i++)
49                 {
50                         MicroInstructionParameter newParam;
51                         ParameterClassification classification = classes[i];
52                         ParameterType type = classification.getExpectedType();
53                         switch (type)
54                         {
55                         case BOOLEAN_IMMEDIATE:
56                         case MNEMONIC:
57                                 newParam = ((MnemonicFamily) classification).get(0);
58                                 break;
59                         case INTEGER_IMMEDIATE:
60                                 newParam = new IntegerImmediate(BigInteger.valueOf(0), ((IntegerClassification) classification).getExpectedBits());
61                                 break;
62                         default:
63                                 throw new IllegalStateException("Unknown ParameterType " + type);
64                         }
65                         params[i] = newParam;
66                 }
67                 return new StandardMicroInstruction(updateCallback, params);
68         }
69
70         public Optional<String> getParameterDescription(int index);
71 }