Added MnemonicFamilyBuilder and set most Mnemonics to 'X' by default
authorFabian Stemmler <stemmler@in.tum.de>
Thu, 26 Sep 2019 13:03:34 +0000 (15:03 +0200)
committerFabian Stemmler <stemmler@in.tum.de>
Thu, 26 Sep 2019 13:04:48 +0000 (15:04 +0200)
plugins/net.mograsim.logic.model.am2900/src/net/mograsim/logic/model/am2900/machine/Am2900MicroInstructionDefinition.java
plugins/net.mograsim.machine/src/net/mograsim/machine/mi/parameters/BooleanClassification.java
plugins/net.mograsim.machine/src/net/mograsim/machine/mi/parameters/IntegerImmediate.java
plugins/net.mograsim.machine/src/net/mograsim/machine/mi/parameters/MicroInstructionParameter.java
plugins/net.mograsim.machine/src/net/mograsim/machine/mi/parameters/Mnemonic.java
plugins/net.mograsim.machine/src/net/mograsim/machine/mi/parameters/MnemonicFamily.java

index 1a7b8f6..b67e93d 100644 (file)
@@ -1,15 +1,12 @@
 package net.mograsim.logic.model.am2900.machine;
 
-import java.util.Arrays;
 import java.util.Optional;
 
-import net.mograsim.logic.core.types.Bit;
-import net.mograsim.logic.core.types.BitVector;
 import net.mograsim.machine.mi.MicroInstructionDefinition;
 import net.mograsim.machine.mi.parameters.BooleanClassification;
 import net.mograsim.machine.mi.parameters.IntegerClassification;
 import net.mograsim.machine.mi.parameters.MnemonicFamily;
-import net.mograsim.machine.mi.parameters.MnemonicFamily.MnemonicPair;
+import net.mograsim.machine.mi.parameters.MnemonicFamily.MnemonicFamilyBuilder;
 import net.mograsim.machine.mi.parameters.ParameterClassification;
 
 public class Am2900MicroInstructionDefinition implements MicroInstructionDefinition
@@ -18,21 +15,26 @@ public class Am2900MicroInstructionDefinition implements MicroInstructionDefinit
 
        private static final BooleanClassification interruptEnable = new BooleanClassification(false, "IE", "Dis");
        // not implemented, because not documented.
-       private static final MnemonicFamily interruptInstructions = new MnemonicFamily("X", new MnemonicPair("X", BitVector.of(Bit.ZERO, 4)));
-       private static final BooleanClassification kmux = new BooleanClassification(false, "D", "K");
-       private static final MnemonicFamily am2901SrcInstructions = new MnemonicFamily("AB", "AQ", "AB", "ZQ", "ZB", "ZA", "DA", "DQ", "DZ");
-       private static final MnemonicFamily am2901FuncInstructions = new MnemonicFamily("ADD", "ADD", "SUBR", "SUBS", "OR", "AND", "NOTRS",
-                       "EXOR", "EXNOR");
-       private static final MnemonicFamily am2901DestInstructions = new MnemonicFamily("NOP", "QREG", "NOP", "RAMA", "RAMF", "RAMQD", "RAMD",
-                       "RAMQU", "RAMU");
+       private static final MnemonicFamily interruptInstructions = new MnemonicFamilyBuilder(4).addX().setXDefault().build();
+       private static final BooleanClassification kmux = new BooleanClassification("D", "K");
+       private static final MnemonicFamily am2901SrcInstructions = new MnemonicFamilyBuilder(3).addX().setXDefault()
+                       .add("AQ", "AB", "ZQ", "ZB", "ZA", "DA", "DQ", "DZ").build();
+       private static final MnemonicFamily am2901FuncInstructions = new MnemonicFamilyBuilder(3).addX().setXDefault()
+                       .add("ADD", "SUBR", "SUBS", "OR", "AND", "NOTRS", "EXOR", "EXNOR").build();
+       private static final MnemonicFamily am2901DestInstructions = new MnemonicFamilyBuilder(3).addX().setXDefault()
+                       .add("QREG", "NOP", "RAMA", "RAMF", "RAMQD", "RAMD", "RAMQU", "RAMU").build();
        private static final IntegerClassification register = new IntegerClassification(0, 4);
-       private static final BooleanClassification registerSelect = new BooleanClassification(false, "MR", "IR");
+       private static final BooleanClassification registerSelect = new BooleanClassification("MR", "IR");
        private static final BooleanClassification abus = new BooleanClassification(true, "H", "AB");
        private static final BooleanClassification dbus = new BooleanClassification(true, "H", "DB");
-       private static final MnemonicFamily am2904CarryInstructions = new MnemonicFamily("CI0", "CI0", "CI1", "CIX", "CIC");
-       private static final MnemonicFamily am2904ShiftInstructions = new MnemonicFamily("RSL / LSLCO", "RSL / LSLCO", "RSH / LSHCO",
-                       "RSCONI / LSL", "RSDH / LSH", "RSDC / LSDLCO", "RSDN / LSDHCO", "RSDL / LSDL", "RSDCO / LSDH", "RSRCO / LSCRO",
-                       "RSRCIO / LSCRIO", "RSR / LSR", "RSDIC / LSLICI", "RSDRCI / LSDCIO", "RSDRCO / LSDRCO", "RSDXOR / LSDCI", "RSDR / LDSR");
+       private static final MnemonicFamily am2904CarryInstructions = new MnemonicFamilyBuilder(2).addX().setXDefault()
+                       .add("CI0", "CI1", "CIX", "CIC").build();
+       private static final MnemonicFamily am2904ShiftInstructions = new MnemonicFamilyBuilder(4).addX().setXDefault()
+                       .add("RSL", "RSH", "RSCONI", "RSDH", "RSDC", "RSDN", "RSDL", "RSDCO", "RSRCO", "RSRCIO", "RSR", "RSDIC", "RSDRCI", "RSDRCO",
+                                       "RSDXOR", "RSDR")
+                       .add("LSLCO", "LSHCO", "LSL", "LSH", "LSDLCO", "LSDHCO", "LSDL", "LSDH", "LSCRO", "LSCRIO", "LSR", "LSLICI", "LSDCIO", "LSDRCO",
+                                       "LSDCI", "LDSR")
+                       .build();
 //     private static final MnemonicFamily am2904StatusInstructions = new MnemonicFamily(
 //                     new String[] { "MI_Zero", "MI_NotZero", "MI_UGTEQ", "MI_ULT", "MI_UGT", "MI_ULTEQ", "MI_SGTEQ", "MI_SLT", "MI_SGT", "MI_SLTEQ",
 //                                     "MA_Zero", "MA_NotZero", "MA_UGTEQ", "MA_ULT", "MA_UGT", "MA_ULTEQ", "MA_SGTEQ", "MA_SLT", "MA_SGT", "MA_SLTEQ" },
@@ -40,24 +42,27 @@ public class Am2900MicroInstructionDefinition implements MicroInstructionDefinit
 //                                     0b10_0101, 0b10_0100, 0b10_1101, 0b10_1100, 0b10_1110, 0b10_1111, 0b10_0010, 0b10_0011, 0b10_0000, 0b10_0001 },
 //                     6);
        // TODO: Maybe "X" and "notX" are swapped.
-       private static final MnemonicFamily am2904StatusInstructions = new MnemonicFamily("Load_Load_I_Z", "LoadM_LoadY_µ_NxorOVRorZ",
-                       "Set_Set_µ_NxnorOVRornotZ", "Swap_Swap_µ_NxorOVR", "Reset_Reset_µ_NxnorOVR", "Load_LoadForShiftThroughOvr_µ_Z",
-                       "Load_Invert_µ_notZ", "LoadOvrRetain_Load_µ_OVR", "LoadOvrRetain_Load_µ_notOVR", "ResetZ_LoadCarryInvert_µ_CorZ",
-                       "SetZ_LoadCarryInvert_µ_notCandnotZ", "ResetC_Load_µ_C", "SetC_Load_µ_notC", "ResetN_Load_µ_notCorZ", "SetN_Load_µ_CandnotZ",
-                       "ResetOvr_Load_IM_NxorN", "SetOvr_Load_IM_NxnorN", "Load_Load_µ_NxorOVRorZ", "Load_Load_µ_NxnorOVRornotZ",
-                       "Load_Load_µ_NxorOVR", "Load_Load_µ_NxnorOVR", "Load_Load_µ_Z", "Load_Load_µ_notZ", "Load_Load_µ_OVR", "Load_Load_µ_notOVR",
-                       "LoadCarryInvert_LoadCarryInvert_µ_CorZ", "LoadCarryInvert_LoadCarryInvert_µ_notCandnotZ", "Load_Load_µ_C", "Load_Load_µ_notC",
-                       "Load_Load_µ_notCorZ", "Load_Load_µ_CandnotZ", "Load_Load_µ_N", "Load_Load_µ_notN", "Load_Load_M_NxorOVRorZ",
-                       "Load_Load_M_NxnorOVRornotZ", "Load_Load_M_NxorOVR", "Load_Load_M_NxnorOVR", "Load_Load_M_Z", "Load_Load_M_notZ",
-                       "Load_Load_M_OVR", "Load_Load_M_notOVR", "LoadCarryInvert_LoadCarryInvert_M_CorZ",
-                       "LoadCarryInvert_LoadCarryInvert_M_notCandnotZ", "Load_Load_M_C", "Load_Load_M_notC", "Load_Load_M_notCorZ",
-                       "Load_Load_M_CandnotZ", "Load_Load_M_N", "Load_Load_M_notN", "Load_Load_I_NxorOVRorZ", "Load_Load_I_NxnorOVRornotZ",
-                       "Load_Load_I_NxorOVR", "Load_Load_I_NxnorOVR", "Load_Load_I_Z", "Load_Load_I_notZ", "Load_Load_I_OVR", "Load_Load_I_notOVR",
-                       "LoadCarryInvert_LoadCarryInvert_I_notCorZ", "LoadCarryInvert_LoadCarryInvert_I_CandnotZ", "Load_Load_I_C", "Load_Load_I_notC",
-                       "Load_Load_I_notCorZ", "Load_Load_I_CandnotZ", "Load_Load_I_N", "Load_Load_I_notN");
+       private static final MnemonicFamily am2904StatusInstructions = new MnemonicFamilyBuilder(6).addX().setXDefault()
+                       .add("LoadM_LoadY_µ_NxorOVRorZ", "Set_Set_µ_NxnorOVRornotZ", "Swap_Swap_µ_NxorOVR", "Reset_Reset_µ_NxnorOVR",
+                                       "Load_LoadForShiftThroughOvr_µ_Z", "Load_Invert_µ_notZ", "LoadOvrRetain_Load_µ_OVR", "LoadOvrRetain_Load_µ_notOVR",
+                                       "ResetZ_LoadCarryInvert_µ_CorZ", "SetZ_LoadCarryInvert_µ_notCandnotZ", "ResetC_Load_µ_C", "SetC_Load_µ_notC",
+                                       "ResetN_Load_µ_notCorZ", "SetN_Load_µ_CandnotZ", "ResetOvr_Load_IM_NxorN", "SetOvr_Load_IM_NxnorN",
+                                       "Load_Load_µ_NxorOVRorZ", "Load_Load_µ_NxnorOVRornotZ", "Load_Load_µ_NxorOVR", "Load_Load_µ_NxnorOVR", "Load_Load_µ_Z",
+                                       "Load_Load_µ_notZ", "Load_Load_µ_OVR", "Load_Load_µ_notOVR", "LoadCarryInvert_LoadCarryInvert_µ_CorZ",
+                                       "LoadCarryInvert_LoadCarryInvert_µ_notCandnotZ", "Load_Load_µ_C", "Load_Load_µ_notC", "Load_Load_µ_notCorZ",
+                                       "Load_Load_µ_CandnotZ", "Load_Load_µ_N", "Load_Load_µ_notN", "Load_Load_M_NxorOVRorZ", "Load_Load_M_NxnorOVRornotZ",
+                                       "Load_Load_M_NxorOVR", "Load_Load_M_NxnorOVR", "Load_Load_M_Z", "Load_Load_M_notZ", "Load_Load_M_OVR",
+                                       "Load_Load_M_notOVR", "LoadCarryInvert_LoadCarryInvert_M_CorZ", "LoadCarryInvert_LoadCarryInvert_M_notCandnotZ",
+                                       "Load_Load_M_C", "Load_Load_M_notC", "Load_Load_M_notCorZ", "Load_Load_M_CandnotZ", "Load_Load_M_N", "Load_Load_M_notN",
+                                       "Load_Load_I_NxorOVRorZ", "Load_Load_I_NxnorOVRornotZ", "Load_Load_I_NxorOVR", "Load_Load_I_NxnorOVR", "Load_Load_I_Z",
+                                       "Load_Load_I_notZ", "Load_Load_I_OVR", "Load_Load_I_notOVR", "LoadCarryInvert_LoadCarryInvert_I_notCorZ",
+                                       "LoadCarryInvert_LoadCarryInvert_I_CandnotZ", "Load_Load_I_C", "Load_Load_I_notC", "Load_Load_I_notCorZ",
+                                       "Load_Load_I_CandnotZ", "Load_Load_I_N", "Load_Load_I_notN")
+                       .build();
        private static final BooleanClassification ccen = new BooleanClassification(true, "PS", "C");
-       private static final MnemonicFamily am2910Instructions = new MnemonicFamily("CONT", "JZ", "CJS", "JMAP", "CJP", "PUSH", "JSRP", "CJV",
-                       "JRP", "RFCT", "RPCT", "CRTN", "CJPP", "LDCT", "LOOP", "CONT", "TWB");
+       private static final MnemonicFamily am2910Instructions = new MnemonicFamilyBuilder(4).addX().setXDefault()
+                       .add("JZ", "CJS", "JMAP", "CJP", "PUSH", "JSRP", "CJV", "JRP", "RFCT", "RPCT", "CRTN", "CJPP", "LDCT", "LOOP", "CONT", "TWB")
+                       .build();
 
        private static final IntegerClassification constant_12bit = new IntegerClassification(0, 12);
        private static final IntegerClassification constant_16bit = new IntegerClassification(0, 16);
@@ -99,19 +104,6 @@ public class Am2900MicroInstructionDefinition implements MicroInstructionDefinit
                return Optional.of(paramDesc[index]);
        }
 
-       public static void main(String[] args)
-       {
-               String s = "new BooleanClassification(\"R\", \"W\"), hL, new BooleanClassification(\"H\", \"E\"),\r\n"
-                               + "                     new BooleanClassification(\"H\", \"I\"), new BooleanClassification(\"H\", \"E\"), hL, new IntegerClassification(12), am2910Instructions,\r\n"
-                               + "                     new BooleanClassification(\"PS\", \"C\"), am2904StatusInstructions, hL, hL, am2904ShiftInstructions, am2904CarryInstructions,\r\n"
-                               + "                     new BooleanClassification(\"H\", \"DB\"), new BooleanClassification(\"H\", \"AB\"), registerSelect, register, registerSelect, register,\r\n"
-                               + "                     am2901DestInstructions, am2901FuncInstructions, am2901SrcInstructions, new IntegerClassification(16),\r\n"
-                               + "                     new BooleanClassification(\"D\", \"K\"), interruptInstructions, new BooleanClassification(\"Dis\", \"IE\")";
-               s = s.replaceAll("[\r\n\t]", "");
-               System.out.print(Arrays.stream(s.split(", new")).reduce((a, b) -> b + ", new" + a));
-//             System.out.println(Arrays.stream(paramDesc).reduce("", (a, b) -> String.format("\"%s\", %s", b, a)));
-       }
-
        private Am2900MicroInstructionDefinition()
        {
        }
index 73acc66..ed53ece 100644 (file)
@@ -15,6 +15,14 @@ public class BooleanClassification extends MnemonicFamily
                this.falseName = falseName;
        }
 
+       public BooleanClassification(String trueName, String falseName)
+       {
+               super("X", new MnemonicPair("X", BitVector.SINGLE_0), new MnemonicPair(trueName, BitVector.SINGLE_1),
+                               new MnemonicPair(falseName, BitVector.SINGLE_0));
+               this.trueName = trueName;
+               this.falseName = falseName;
+       }
+
        public Mnemonic get(boolean value)
        {
                return get(value ? trueName : falseName);
index 419602c..0194766 100644 (file)
@@ -71,4 +71,10 @@ public final class IntegerImmediate implements MicroInstructionParameter
        {
                return getValueAsBigInteger().toString();
        }
+
+       @Override
+       public boolean isDefault()
+       {
+               return value.getSignedValueLong() == 0;
+       }
 }
index 2f135d2..aaa3051 100644 (file)
@@ -8,6 +8,8 @@ public interface MicroInstructionParameter
 
        public ParameterType getType();
 
+       public boolean isDefault();
+
        public static enum ParameterType
        {
                INTEGER_IMMEDIATE, BOOLEAN_IMMEDIATE, MNEMONIC
index 5ea2be0..f7c5043 100644 (file)
@@ -61,4 +61,10 @@ public final class Mnemonic implements MicroInstructionParameter
        {
                return text;
        }
+
+       @Override
+       public boolean isDefault()
+       {
+               return equals(owner.getDefault());
+       }
 }
index 14bffbb..445485b 100644 (file)
@@ -1,9 +1,12 @@
 package net.mograsim.machine.mi.parameters;
 
 import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
+import net.mograsim.logic.core.types.Bit;
 import net.mograsim.logic.core.types.BitVector;
 import net.mograsim.machine.mi.parameters.MicroInstructionParameter.ParameterType;
 
@@ -15,98 +18,7 @@ public class MnemonicFamily implements ParameterClassification
        private Map<String, Mnemonic> byText;
        private int vectorLength;
 
-       public MnemonicFamily(String defaultValueName, String... names)
-       {
-               this(false, defaultValueName, (int) Math.round(Math.ceil(Math.log(names.length) / Math.log(2))), names);
-       }
-
-       public MnemonicFamily(boolean reverse, String defaultValueName, String... names)
-       {
-               this(reverse, defaultValueName, (int) Math.round(Math.ceil(Math.log(names.length) / Math.log(2))), names);
-       }
-
-       public MnemonicFamily(String defaultValueName, int bits, String... names)
-       {
-               this(false, defaultValueName, bits, names);
-       }
-
-       public MnemonicFamily(boolean reverse, String defaultValueName, int bits, String... names)
-       {
-               this.values = new Mnemonic[names.length];
-               this.stringValues = new String[names.length];
-               BitVector[] values = new BitVector[names.length];
-               for (int i = 0; i < names.length; i++)
-               {
-                       values[i] = BitVector.from(i, bits);
-               }
-
-               setup(names, values, reverse);
-
-               int defaultValueIndex = -1;
-               for (int i = 0; i < names.length; i++)
-                       if (names[i].equals(defaultValueName))
-                       {
-                               defaultValueIndex = i;
-                               break;
-                       }
-               this.defaultValue = this.values[defaultValueIndex];
-       }
-
-       public MnemonicFamily(String defaultValueName, String[] names, long[] values, int bits)
-       {
-               this(false, defaultValueName, names, values, bits);
-       }
-
-       public MnemonicFamily(boolean reverse, String defaultValueName, String[] names, long[] values, int bits)
-       {
-               if (names.length != values.length)
-                       throw new IllegalArgumentException();
-               this.values = new Mnemonic[values.length];
-               this.stringValues = new String[values.length];
-               BitVector[] vectors = new BitVector[values.length];
-
-               for (int i = 0; i < vectors.length; i++)
-               {
-                       vectors[i] = BitVector.from(values[i], bits);
-               }
-
-               setup(names, vectors, reverse);
-
-               int defaultValueIndex = -1;
-               for (int i = 0; i < names.length; i++)
-                       if (names[i].equals(defaultValueName))
-                       {
-                               defaultValueIndex = i;
-                               break;
-                       }
-               this.defaultValue = this.values[defaultValueIndex];
-       }
-
-       public MnemonicFamily(String defaultValueName, String[] names, BitVector[] values)
-       {
-               this(false, defaultValueName, names, values);
-       }
-
-       public MnemonicFamily(boolean reverse, String defaultValueName, String[] names, BitVector[] values)
-       {
-               if (names.length != values.length)
-                       throw new IllegalArgumentException();
-               this.values = new Mnemonic[values.length];
-               this.stringValues = new String[values.length];
-
-               setup(names, values, reverse);
-
-               int defaultValueIndex = -1;
-               for (int i = 0; i < names.length; i++)
-                       if (names[i].equals(defaultValueName))
-                       {
-                               defaultValueIndex = i;
-                               break;
-                       }
-               this.defaultValue = this.values[defaultValueIndex];
-       }
-
-       public MnemonicFamily(String defaultValueName, MnemonicPair... values)
+       MnemonicFamily(String defaultValueName, MnemonicPair... values)
        {
                this.values = new Mnemonic[values.length];
                this.stringValues = new String[values.length];
@@ -123,14 +35,6 @@ public class MnemonicFamily implements ParameterClassification
                this.defaultValue = this.values[defaultValueIndex];
        }
 
-       private void setup(String[] names, BitVector[] values, boolean reverse)
-       {
-               MnemonicPair[] mnemonics = new MnemonicPair[values.length];
-               for (int i = 0; i < values.length; i++)
-                       mnemonics[i] = new MnemonicPair(names[i], reverse ? values[i].reverse() : values[i]);
-               setup(mnemonics);
-       }
-
        private void setup(MnemonicPair[] values)
        {
                for (int i = 0; i < values.length; i++)
@@ -258,4 +162,121 @@ public class MnemonicFamily implements ParameterClassification
                        this.value = value;
                }
        }
+
+       public static class MnemonicFamilyBuilder
+       {
+               private final List<MnemonicPair> pairs;
+               private final int bits;
+               private String defaultValue;
+
+               public MnemonicFamilyBuilder(int bits)
+               {
+                       this.pairs = new LinkedList<>();
+                       this.bits = bits;
+               }
+
+               public MnemonicFamilyBuilder addX()
+               {
+                       pairs.add(new MnemonicPair("X", BitVector.of(Bit.ZERO, bits)));
+                       return this;
+               }
+
+               public MnemonicFamilyBuilder add(MnemonicPair... pairs)
+               {
+                       this.pairs.addAll(List.of(pairs));
+                       return this;
+               }
+
+               /**
+                * Adds a name with its corresponding value to the {@link MnemonicFamily}
+                * 
+                * @return this {@link MnemonicFamilyBuilder}
+                */
+               public MnemonicFamilyBuilder add(String name, BitVector value)
+               {
+                       add(new MnemonicPair(name, value));
+                       return this;
+               }
+
+               /**
+                * Adds names with their corresponding values to the {@link MnemonicFamily}
+                * 
+                * @param names  The names to be added to the {@link MnemonicFamily}
+                * @param values The values as {@link BitVector}s
+                * @return this {@link MnemonicFamilyBuilder}
+                */
+               public MnemonicFamilyBuilder add(String name, long value)
+               {
+                       add(new MnemonicPair(name, BitVector.from(value, bits)));
+                       return this;
+               }
+
+               /**
+                * Adds names with their corresponding values to the {@link MnemonicFamily}
+                * 
+                * @param names  The names to be added to the {@link MnemonicFamily}
+                * @param values The values as {@link BitVector}s
+                * @return this {@link MnemonicFamilyBuilder}
+                */
+               public MnemonicFamilyBuilder add(String names[], BitVector[] values)
+               {
+                       if (names.length != values.length)
+                               throw new IllegalArgumentException("Cannot add Mnemonics! Amount of names does not match amount of values!");
+                       for (int i = 0; i < names.length; i++)
+                               add(new MnemonicPair(names[i], values[i]));
+                       return this;
+               }
+
+               /**
+                * Adds names with their corresponding values (converted to a BitVector) to the {@link MnemonicFamily}
+                * 
+                * @param names  The names to be added to the {@link MnemonicFamily}
+                * @param values The values to be converted to {@link BitVector}s with a given amount of {@link MnemonicFamilyBuilder#bits}
+                * @return this {@link MnemonicFamilyBuilder}
+                */
+               public MnemonicFamilyBuilder add(String names[], long values[])
+               {
+                       if (names.length != values.length)
+                               throw new IllegalArgumentException("Cannot add Mnemonics! Amount of names does not match amount of values!");
+                       for (int i = 0; i < names.length; i++)
+                               add(new MnemonicPair(names[i], BitVector.from(values[i], bits)));
+                       return this;
+               }
+
+               /**
+                * Adds names to the {@link MnemonicFamily}; The corresponding {@link BitVector} value to a name is the value of its index
+                * 
+                * @param names The names to be added to the {@link MnemonicFamily}
+                * @return this {@link MnemonicFamilyBuilder}
+                */
+               public MnemonicFamilyBuilder add(String... names)
+               {
+                       for (int i = 0; i < names.length; i++)
+                               add(names[i], i);
+                       return this;
+               }
+
+               /**
+                * Sets the name of the default {@link Mnemonic} of this {@link MnemonicFamily}
+                */
+               public MnemonicFamilyBuilder setDefault(String defaultValue)
+               {
+                       this.defaultValue = defaultValue;
+                       return this;
+               }
+
+               /**
+                * Sets the name of the default {@link Mnemonic} of this {@link MnemonicFamily} to "X"
+                */
+               public MnemonicFamilyBuilder setXDefault()
+               {
+                       this.defaultValue = "X";
+                       return this;
+               }
+
+               public MnemonicFamily build()
+               {
+                       return new MnemonicFamily(defaultValue, pairs.toArray(new MnemonicPair[pairs.size()]));
+               }
+       }
 }