diff --git a/Server/src/main/java/net/simon987/server/assembly/Assembler.java b/Server/src/main/java/net/simon987/server/assembly/Assembler.java index 1e31834..53156cf 100755 --- a/Server/src/main/java/net/simon987/server/assembly/Assembler.java +++ b/Server/src/main/java/net/simon987/server/assembly/Assembler.java @@ -544,7 +544,6 @@ public class Assembler { if (instructionSet.get(mnemonic) == null) { throw new InvalidMnemonicException(mnemonic, currentLine); - } //Check operands and encode instruction diff --git a/Server/src/main/java/net/simon987/server/assembly/DefaultInstructionSet.java b/Server/src/main/java/net/simon987/server/assembly/DefaultInstructionSet.java index 723865c..1c64d82 100755 --- a/Server/src/main/java/net/simon987/server/assembly/DefaultInstructionSet.java +++ b/Server/src/main/java/net/simon987/server/assembly/DefaultInstructionSet.java @@ -1,7 +1,6 @@ package net.simon987.server.assembly; import net.simon987.server.assembly.instruction.*; -import net.simon987.server.logging.LogManager; import java.util.HashMap; import java.util.Map; @@ -51,9 +50,11 @@ public class DefaultInstructionSet implements InstructionSet { add(new SarInstruction()); add(new IncInstruction()); add(new DecInstruction()); + add(new SetccInstruction()); // aliases add(new SalInstruction()); + add(new SetzInstruction()); } /** @@ -107,7 +108,7 @@ public class DefaultInstructionSet implements InstructionSet { public void add(Instruction instruction) { Instruction aliasedInstruction = instructionMap.get(instruction.getOpCode()); if (aliasedInstruction != null) { - aliasesMap.put(instruction.getMnemonic(), aliasedInstruction); + aliasesMap.put(instruction.getMnemonic(), instruction); } else { instructionMap.put(instruction.getOpCode(), instruction); } diff --git a/Server/src/main/java/net/simon987/server/assembly/Instruction.java b/Server/src/main/java/net/simon987/server/assembly/Instruction.java index eb393c5..8a521cd 100755 --- a/Server/src/main/java/net/simon987/server/assembly/Instruction.java +++ b/Server/src/main/java/net/simon987/server/assembly/Instruction.java @@ -1,6 +1,6 @@ package net.simon987.server.assembly; - +import net.simon987.server.assembly.exception.AssemblyException; import net.simon987.server.assembly.exception.IllegalOperandException; import java.io.ByteArrayOutputStream; @@ -102,7 +102,7 @@ public abstract class Instruction { * @param o2 Source operand * @return true if valid */ - private static boolean operandsValid(Operand o1, Operand o2) throws IllegalOperandException { + public boolean operandsValid(Operand o1, Operand o2) { return o1.getType() != OperandType.IMMEDIATE16; } @@ -112,7 +112,7 @@ public abstract class Instruction { * @param o1 source operand * @return true if the specified operand can be used with this instruction */ - private static boolean operandValid(Operand o1) { + public boolean operandValid(Operand o1) { return true; } @@ -124,7 +124,7 @@ public abstract class Instruction { return false; } - String getMnemonic() { + public String getMnemonic() { return mnemonic; } @@ -133,7 +133,7 @@ public abstract class Instruction { * * @param out encoded bytes will be written here */ - public void encode(ByteArrayOutputStream out, int currentLine) throws IllegalOperandException { + public void encode(ByteArrayOutputStream out, int currentLine) throws AssemblyException { if (!noOperandsValid()) { throw new IllegalOperandException("This instruction must have operand(s)!", currentLine); @@ -148,7 +148,7 @@ public abstract class Instruction { } public void encode(ByteArrayOutputStream out, Operand o1, Operand o2, int currentLine) - throws IllegalOperandException { + throws AssemblyException { MachineCode code = new MachineCode(); code.writeOpcode(opCode); @@ -183,7 +183,7 @@ public abstract class Instruction { } public void encode(ByteArrayOutputStream out, Operand o1, int currentLine) - throws IllegalOperandException { + throws AssemblyException { MachineCode code = new MachineCode(); code.writeOpcode(opCode); @@ -208,7 +208,7 @@ public abstract class Instruction { } } - int getOpCode() { + public int getOpCode() { return opCode; } } diff --git a/Server/src/main/java/net/simon987/server/assembly/MachineCode.java b/Server/src/main/java/net/simon987/server/assembly/MachineCode.java index 9197107..d90edb6 100755 --- a/Server/src/main/java/net/simon987/server/assembly/MachineCode.java +++ b/Server/src/main/java/net/simon987/server/assembly/MachineCode.java @@ -10,7 +10,7 @@ import java.util.ArrayList; * Represents an encoded instruction. this class is used to easily * write to an 16bit value. */ -class MachineCode { +public class MachineCode { /** * Value of the initial 2-byte instruction @@ -27,7 +27,7 @@ class MachineCode { * * @param opCode signed 6-bit integer (value 0-63) */ - void writeOpcode(int opCode) { + public void writeOpcode(int opCode) { if (opCode < 0 || opCode > 63) { LogManager.LOGGER.severe("Couldn't write the opCode for instruction :" + opCode); @@ -44,7 +44,7 @@ class MachineCode { * * @param src signed 5-bit integer (value 0-31) */ - void writeSourceOperand(int src) { + public void writeSourceOperand(int src) { if (src < 0 || src > 31) { LogManager.LOGGER.severe("Couldn't write the scr operand for instruction :" + src); @@ -62,7 +62,7 @@ class MachineCode { * * @param dst signed 5-bit integer (value 0-31) */ - void writeDestinationOperand(int dst) { + public void writeDestinationOperand(int dst) { if (dst < 0 || dst > 31) { LogManager.LOGGER.severe("Couldn't write the dst operand for instruction :" + dst); } else { @@ -73,14 +73,14 @@ class MachineCode { } } - void appendWord(char word) { + public void appendWord(char word) { additionalWords.add(word); } /** * Get the bytes of the code */ - byte[] bytes() { + public byte[] bytes() { ByteArrayOutputStream out = new ByteArrayOutputStream(); diff --git a/Server/src/main/java/net/simon987/server/assembly/Operand.java b/Server/src/main/java/net/simon987/server/assembly/Operand.java index b236365..b2ad770 100755 --- a/Server/src/main/java/net/simon987/server/assembly/Operand.java +++ b/Server/src/main/java/net/simon987/server/assembly/Operand.java @@ -10,9 +10,9 @@ import java.util.HashMap; */ public class Operand { - static final int IMMEDIATE_VALUE = 0b11111; //1 1111 + public static final int IMMEDIATE_VALUE = 0b11111; //1 1111 - static final int IMMEDIATE_VALUE_MEM = 0b11110; //1 1110 + public static final int IMMEDIATE_VALUE_MEM = 0b11110; //1 1110 /** * The actual text of the operand (e.g. "[AX]") @@ -36,6 +36,16 @@ public class Operand { */ private int data = 0; + public Operand(OperandType type, int value) { + this.type = type; + this.value = value; + } + + public Operand(OperandType type, int value, int data) { + this(type, value); + this.data = data; + } + /** * Create an Operand from text. It assumes that the numerical values that can't be * parsed are labels that are not defined yet. @@ -252,7 +262,7 @@ public class Operand { } } - OperandType getType() { + public OperandType getType() { return type; } @@ -260,7 +270,7 @@ public class Operand { return value; } - int getData() { + public int getData() { return data; } } diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SalInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SalInstruction.java index f24ab94..8d3a405 100644 --- a/Server/src/main/java/net/simon987/server/assembly/instruction/SalInstruction.java +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SalInstruction.java @@ -1,13 +1,11 @@ package net.simon987.server.assembly.instruction; -import net.simon987.server.assembly.Instruction; - /** * Alias of SHL instruction */ -public class SalInstruction extends Instruction { +public class SalInstruction extends ShlInstruction { public SalInstruction() { - super("sal", ShlInstruction.OPCODE); + super("sal"); } } diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetaInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetaInstruction.java new file mode 100644 index 0000000..1df5af0 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetaInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetaInstruction extends SetccInstruction { + + public SetaInstruction() { + super("seta"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetaeInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetaeInstruction.java new file mode 100644 index 0000000..3bf4a3e --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetaeInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetaeInstruction extends SetccInstruction { + + public SetaeInstruction() { + super("setae"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetbInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetbInstruction.java new file mode 100644 index 0000000..7cbaae3 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetbInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetbInstruction extends SetccInstruction { + + public SetbInstruction() { + super("setb"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetbeInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetbeInstruction.java new file mode 100644 index 0000000..d3cb95f --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetbeInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetbeInstruction extends SetccInstruction { + + public SetbeInstruction() { + super("setbe"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetcInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetcInstruction.java new file mode 100644 index 0000000..844e348 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetcInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetcInstruction extends SetccInstruction { + + public SetcInstruction() { + super("setc"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetccInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetccInstruction.java new file mode 100644 index 0000000..14af27e --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetccInstruction.java @@ -0,0 +1,341 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Instruction; +import net.simon987.server.assembly.Status; +import net.simon987.server.assembly.Target; +import net.simon987.server.assembly.Operand; +import net.simon987.server.assembly.OperandType; +import net.simon987.server.assembly.MachineCode; + +import net.simon987.server.assembly.exception.AssemblyException; +import net.simon987.server.assembly.exception.IllegalOperandException; +import net.simon987.server.assembly.exception.InvalidMnemonicException; + +import java.io.ByteArrayOutputStream; + +import java.util.Map; +import java.util.HashMap; + +/** + * Implementation of the SETcc family of instructions + * http://www.ousob.com/ng/iapx86/ng22d84.php + */ +public class SetccInstruction extends Instruction { + + public static final int OPCODE = 50; + + public static final int SETA = 0x01; + public static final int SETAE = 0x02; + public static final int SETBE = 0x03; + public static final int SETB = 0x04; + public static final int SETE = 0x05; + public static final int SETNE = 0x06; + public static final int SETG = 0x07; + public static final int SETGE = 0x08; + public static final int SETLE = 0x09; + public static final int SETL = 0x0A; + public static final int SETO = 0x0B; + public static final int SETNO = 0x0C; + public static final int SETS = 0x0D; + public static final int SETNS = 0x0E; + + /** + * Map of mnemonics, stored in mnemonic : family op code + * This map includes aliases + */ + private static final Map mnemonicFamilyOpCodeMap = new HashMap<>(26); + + static { + mnemonicFamilyOpCodeMap.put("seta", (char) SETA); + mnemonicFamilyOpCodeMap.put("setnbe", (char) SETA); + mnemonicFamilyOpCodeMap.put("setae", (char) SETAE); + mnemonicFamilyOpCodeMap.put("setnb", (char) SETAE); + mnemonicFamilyOpCodeMap.put("setnc", (char) SETAE); + mnemonicFamilyOpCodeMap.put("setbe", (char) SETBE); + mnemonicFamilyOpCodeMap.put("setna", (char) SETBE); + mnemonicFamilyOpCodeMap.put("setb", (char) SETB); + mnemonicFamilyOpCodeMap.put("setc", (char) SETB); + mnemonicFamilyOpCodeMap.put("setnae", (char) SETB); + mnemonicFamilyOpCodeMap.put("sete", (char) SETE); + mnemonicFamilyOpCodeMap.put("setz", (char) SETE); + mnemonicFamilyOpCodeMap.put("setne", (char) SETNE); + mnemonicFamilyOpCodeMap.put("setnz", (char) SETNE); + mnemonicFamilyOpCodeMap.put("setg", (char) SETG); + mnemonicFamilyOpCodeMap.put("setnle", (char) SETG); + mnemonicFamilyOpCodeMap.put("setge", (char) SETGE); + mnemonicFamilyOpCodeMap.put("setnl", (char) SETGE); + mnemonicFamilyOpCodeMap.put("setle", (char) SETLE); + mnemonicFamilyOpCodeMap.put("setng", (char) SETLE); + mnemonicFamilyOpCodeMap.put("setl", (char) SETL); + mnemonicFamilyOpCodeMap.put("setnge", (char) SETL); + mnemonicFamilyOpCodeMap.put("seto", (char) SETO); + mnemonicFamilyOpCodeMap.put("setno", (char) SETNO); + mnemonicFamilyOpCodeMap.put("sets", (char) SETS); + mnemonicFamilyOpCodeMap.put("setns", (char) SETNS); + } + + public SetccInstruction() { + super("setcc", OPCODE); + } + + public SetccInstruction(String alias) { + super(alias, OPCODE); + } + + /** + * The SET instructions set the 16-bit destination to 1 if the + * specified condition is true, otherwise destination is set to 0. + *

+ * FamilyOpcode Instruction SET to 1 if ... else to 0 Flags + * 0x01 SETA, SETNBE Above, Not Below or Equal CF=0 AND ZF=0 + * 0x02 SETAE,SETNB,SETNC Above or Equal, Not Below, No Carry CF=0 + * 0x03 SETBE, SETNA Below or Equal, Not Above CF=1 OR ZF=1 + * 0x04 SETB, SETC,SETNAE Below, Carry, Not Above or Equal CF=1 + * 0x05 SETE, SETZ Equal, Zero ZF=1 + * 0x06 SETNE, SETNZ Not Equal, Not Zero ZF=0 + * 0x07 SETG, SETNLE Greater, Not Less or Equal SF=OF AND ZF=0 + * 0x08 SETGE, SETNL Greater or Equal, Not Less SF=OF + * 0x09 SETLE, SETNG Less or Equal, Not Greater SF<>OF OR ZF=1 + * 0x0A SETL, SETNGE Less, Not Greater or Equal SF<>OF + * 0x0B SETO Overflow OF=1 + * 0x0C SETNO No Overflow OF=0 + * 0x0D SETS Sign (negative) SF=1 + * 0x0E SETNS No Sign (positive) SF=0 + */ + private static Status setcc(Target dst, int dstIndex, int familyOpCode, Status status) { + switch (familyOpCode) { + case SETA: + return seta(dst, dstIndex, status); + case SETAE: + return setae(dst, dstIndex, status); + case SETBE: + return setbe(dst, dstIndex, status); + case SETB: + return setb(dst, dstIndex, status); + case SETE: + return sete(dst, dstIndex, status); + case SETNE: + return setne(dst, dstIndex, status); + case SETG: + return setg(dst, dstIndex, status); + case SETGE: + return setge(dst, dstIndex, status); + case SETLE: + return setle(dst, dstIndex, status); + case SETL: + return setl(dst, dstIndex, status); + case SETO: + return seto(dst, dstIndex, status); + case SETNO: + return setno(dst, dstIndex, status); + case SETS: + return sets(dst, dstIndex, status); + case SETNS: + return setns(dst, dstIndex, status); + default: + return status; + } + } + + /** + * Target can be a memory location or register adressable by dst[dstIndex] + * FamilyOpcode is the value encoded in the source operand as immidiate value + * it will be used to determince what specfic SETcc operation should be execute + */ + @Override + public Status execute(Target dst, int dstIndex, int familyOpCode, Status status) { + return setcc(dst, dstIndex, familyOpCode, status); + } + + /** + * This instruction can never be encoded with 2 operands since one word is reserved for its family op code encoding + */ + @Override + public boolean operandsValid(Operand o1, Operand o2) { + return false; + } + + @Override + public boolean operandValid(Operand o1) { + return o1.getType() != OperandType.IMMEDIATE16; + } + + /** + * Encodes the instruction. Writes the result in the outputStream. + * Needs one operand of OperandType.REGISTER or OperandType.MEMORY_REG16 + * + * @param out encoded bytes will be written here + */ + @Override + public void encode(ByteArrayOutputStream out, Operand o1, int currentLine) throws AssemblyException { + String mnemonic = getMnemonic().toLowerCase(); + Character familyOpCode = mnemonicFamilyOpCodeMap.get(mnemonic); + + // This will catch the off case that someone uses the mnemonic 'setcc' + // as far as the assembler knows this is a valid instruction, but we know it isn't + if (familyOpCode == null) { + throw new InvalidMnemonicException(getMnemonic(), currentLine); + } + + if (!operandValid(o1)) { + throw new IllegalOperandException("Illegal operand combination: " + o1.getType() + " (none)", currentLine); + } + + MachineCode code = new MachineCode(); + code.writeOpcode(getOpCode()); + + code.writeSourceOperand(Operand.IMMEDIATE_VALUE); + code.appendWord(familyOpCode); + + if (o1.getType() == OperandType.REGISTER16 || o1.getType() == OperandType.MEMORY_REG16) { + code.writeDestinationOperand(o1.getValue()); + } else { + code.writeDestinationOperand(o1.getValue()); + code.appendWord((char) o1.getData()); + } + + for (byte b : code.bytes()) { + out.write(b); + } + } + + /** + * SETA, SETNBE Above, Not Below or Equal CF=0 AND ZF=0 + */ + private static Status seta(Target dst, int dstIndex, Status status) { + boolean condition = !status.isCarryFlag() && !status.isZeroFlag(); + int value = condition ? 1 : 0; + dst.set(dstIndex, value); + return status; + } + + /** + * SETAE,SETNB,SETNC Above or Equal, Not Below, No Carry CF=0 + */ + private static Status setae(Target dst, int dstIndex, Status status) { + boolean condition = !status.isCarryFlag(); + int value = condition ? 1 : 0; + dst.set(dstIndex, value); + return status; + } + + /** + * SETBE, SETNA Below or Equal, Not Above CF=1 OR ZF=1 + */ + private static Status setbe(Target dst, int dstIndex, Status status) { + boolean condition = status.isCarryFlag() || status.isZeroFlag(); + int value = condition ? 1 : 0; + dst.set(dstIndex, value); + return status; + } + + /** + * SETB, SETC,SETNAE Below, Carry, Not Above or Equal CF=1 + */ + private static Status setb(Target dst, int dstIndex, Status status) { + boolean condition = status.isCarryFlag(); + int value = condition ? 1 : 0; + dst.set(dstIndex, value); + return status; + } + + /** + * SETE, SETZ Equal, Zero ZF=1 + */ + private static Status sete(Target dst, int dstIndex, Status status) { + boolean condition = status.isZeroFlag(); + int value = condition ? 1 : 0; + dst.set(dstIndex, value); + return status; + } + + /** + * SETNE, SETNZ Not Equal, Not Zero ZF=0 + */ + private static Status setne(Target dst, int dstIndex, Status status) { + boolean condition = !status.isZeroFlag(); + int value = condition ? 1 : 0; + dst.set(dstIndex, value); + return status; + } + + /** + * SETG, SETNLE Greater, Not Less or Equal SF=OF AND ZF=0 + */ + private static Status setg(Target dst, int dstIndex, Status status) { + boolean condition = (status.isSignFlag() == status.isOverflowFlag()) && !status.isZeroFlag(); + int value = condition ? 1 : 0; + dst.set(dstIndex, value); + return status; + } + + /** + * SETGE, SETNL Greater or Equal, Not Less SF=OF + */ + private static Status setge(Target dst, int dstIndex, Status status) { + boolean condition = status.isSignFlag() == status.isOverflowFlag(); + int value = condition ? 1 : 0; + dst.set(dstIndex, value); + return status; + } + + /** + * SETLE, SETNG Less or Equal, Not Greater SF<>OF OR ZF=1 + */ + private static Status setle(Target dst, int dstIndex, Status status) { + boolean condition = (status.isSignFlag() != status.isOverflowFlag()) || status.isZeroFlag(); + int value = condition ? 1 : 0; + dst.set(dstIndex, value); + return status; + } + + /** + * SETL, SETNGE Less, Not Greater or Equal SF<>OF + */ + private static Status setl(Target dst, int dstIndex, Status status) { + boolean condition = status.isSignFlag() != status.isOverflowFlag(); + int value = condition ? 1 : 0; + dst.set(dstIndex, value); + return status; + } + + /** + * SETO Overflow OF=1 + */ + private static Status seto(Target dst, int dstIndex, Status status) { + boolean condition = status.isOverflowFlag(); + int value = condition ? 1 : 0; + dst.set(dstIndex, value); + return status; + } + + /** + * SETNO No Overflow OF=0 + */ + private static Status setno(Target dst, int dstIndex, Status status) { + boolean condition = !status.isOverflowFlag(); + int value = condition ? 1 : 0; + dst.set(dstIndex, value); + return status; + } + + /** + * SETS Sign (negative) SF=1 + */ + private static Status sets(Target dst, int dstIndex, Status status) { + boolean condition = status.isSignFlag(); + int value = condition ? 1 : 0; + dst.set(dstIndex, value); + return status; + } + + /** + * SETNS No Sign (positive) SF=0 + */ + private static Status setns(Target dst, int dstIndex, Status status) { + boolean condition = !status.isSignFlag(); + int value = condition ? 1 : 0; + dst.set(dstIndex, value); + return status; + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SeteInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SeteInstruction.java new file mode 100644 index 0000000..ea02ad8 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SeteInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SeteInstruction extends SetccInstruction { + + public SeteInstruction() { + super("sete"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetgInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetgInstruction.java new file mode 100644 index 0000000..39deb1d --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetgInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetgInstruction extends SetccInstruction { + + public SetgInstruction() { + super("setg"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetgeInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetgeInstruction.java new file mode 100644 index 0000000..463cb7e --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetgeInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetgeInstruction extends SetccInstruction { + + public SetgeInstruction() { + super("setge"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetlInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetlInstruction.java new file mode 100644 index 0000000..164c73d --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetlInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetlInstruction extends SetccInstruction { + + public SetlInstruction() { + super("setl"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetleInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetleInstruction.java new file mode 100644 index 0000000..d88ec0c --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetleInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetleInstruction extends SetccInstruction { + + public SetleInstruction() { + super("setle"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetnaInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetnaInstruction.java new file mode 100644 index 0000000..1107308 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetnaInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetnaInstruction extends SetccInstruction { + + public SetnaInstruction() { + super("setna"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetnaeInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetnaeInstruction.java new file mode 100644 index 0000000..14c39e9 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetnaeInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetnaeInstruction extends SetccInstruction { + + public SetnaeInstruction() { + super("setnae"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetnbInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetnbInstruction.java new file mode 100644 index 0000000..0fe4d80 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetnbInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetnbInstruction extends SetccInstruction { + + public SetnbInstruction() { + super("setnb"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetnbeInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetnbeInstruction.java new file mode 100644 index 0000000..9e7ba90 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetnbeInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetnbeInstruction extends SetccInstruction { + + public SetnbeInstruction() { + super("setnbe"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetncInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetncInstruction.java new file mode 100644 index 0000000..bc127b3 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetncInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetncInstruction extends SetccInstruction { + + public SetncInstruction() { + super("setnc"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetneInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetneInstruction.java new file mode 100644 index 0000000..5800e43 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetneInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetneInstruction extends SetccInstruction { + + public SetneInstruction() { + super("setne"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetngInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetngInstruction.java new file mode 100644 index 0000000..0f5cb8c --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetngInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetngInstruction extends SetccInstruction { + + public SetngInstruction() { + super("setng"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetngeInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetngeInstruction.java new file mode 100644 index 0000000..a305e78 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetngeInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetngeInstruction extends SetccInstruction { + + public SetngeInstruction() { + super("setnge"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetnlInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetnlInstruction.java new file mode 100644 index 0000000..5857c78 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetnlInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetnlInstruction extends SetccInstruction { + + public SetnlInstruction() { + super("setnl"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetnleInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetnleInstruction.java new file mode 100644 index 0000000..e7211a7 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetnleInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetnleInstruction extends SetccInstruction { + + public SetnleInstruction() { + super("setnle"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetnoInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetnoInstruction.java new file mode 100644 index 0000000..3517e4a --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetnoInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetnoInstruction extends SetccInstruction { + + public SetnoInstruction() { + super("setno"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetnsInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetnsInstruction.java new file mode 100644 index 0000000..4097552 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetnsInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetnsInstruction extends SetccInstruction { + + public SetnsInstruction() { + super("setns"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetnzInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetnzInstruction.java new file mode 100644 index 0000000..8099b74 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetnzInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetnzInstruction extends SetccInstruction { + + public SetnzInstruction() { + super("setnz"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetoInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetoInstruction.java new file mode 100644 index 0000000..8f5b477 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetoInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetoInstruction extends SetccInstruction { + + public SetoInstruction() { + super("seto"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetsInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetsInstruction.java new file mode 100644 index 0000000..5b370da --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetsInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetsInstruction extends SetccInstruction { + + public SetsInstruction() { + super("sets"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/SetzInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/SetzInstruction.java new file mode 100644 index 0000000..bca3a53 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/SetzInstruction.java @@ -0,0 +1,11 @@ +package net.simon987.server.assembly.instruction; + +/** + * alias of SetccInstruction + */ +public class SetzInstruction extends SetccInstruction { + + public SetzInstruction() { + super("setz"); + } +} diff --git a/Server/src/main/java/net/simon987/server/assembly/instruction/ShlInstruction.java b/Server/src/main/java/net/simon987/server/assembly/instruction/ShlInstruction.java index 58b356f..2f473f8 100644 --- a/Server/src/main/java/net/simon987/server/assembly/instruction/ShlInstruction.java +++ b/Server/src/main/java/net/simon987/server/assembly/instruction/ShlInstruction.java @@ -13,6 +13,10 @@ public class ShlInstruction extends Instruction { super("shl", OPCODE); } + public ShlInstruction(String alias) { + super(alias, OPCODE); + } + @Override public Status execute(Target dst, int dstIndex, Target src, int srcIndex, Status status) { diff --git a/Server/src/main/resources/static/js/ace/mode-mar.js b/Server/src/main/resources/static/js/ace/mode-mar.js index c663f2b..287ebfb 100644 --- a/Server/src/main/resources/static/js/ace/mode-mar.js +++ b/Server/src/main/resources/static/js/ace/mode-mar.js @@ -52,7 +52,7 @@ define("ace/mode/mar_rules", ["require", "exports", "module", "ace/lib/oop", "ac }, { token: 'keyword.operator.assembly', - regex: '\\b(?:call|ret|jmp|jnz|jg|jl|jge|jle|hwi|jz|js|jns|jc|jnc|jo|jno|ja|jna)\\b', + regex: '\\b(?:call|ret|jmp|jnz|jg|jl|jge|jle|hwi|jz|js|jns|jc|jnc|jo|jno|ja|jna|seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|setnae|sete|setz|setne|setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|setno|sets|setns)\\b', caseInsensitive: true }, { diff --git a/Server/src/main/resources/static/js/editor.js b/Server/src/main/resources/static/js/editor.js index 7d98023..d4f6d13 100644 --- a/Server/src/main/resources/static/js/editor.js +++ b/Server/src/main/resources/static/js/editor.js @@ -275,6 +275,7 @@ function parseInstruction(line, result, currentLine) { if (!parseDWInstruction(line, result, currentLine)) { if (new RegExp('\\b(?:mov|add|sub|and|or|test|cmp|shl|shr|mul|push|pop|div|xor|hwi|hwq|nop|neg|' + + 'seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|setnae|sete|setz|setne|setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|setno|sets|setns|' + 'call|ret|jmp|jnz|jg|jl|jge|jle|int|jz|js|jns|brk|not|jc|jnc|ror|rol|sal|sar|jo|jno|inc|dec|rcl|xchg|rcr|pushf|popf|ja|jna)\\b').test(mnemonic.toLowerCase())) { @@ -333,7 +334,7 @@ function parseInstruction(line, result, currentLine) { strO1 = line.substring(line.indexOf(mnemonic) + mnemonic.length).trim(); //Validate operand number - if (!new RegExp('\\b(?:push|mul|pop|div|neg|call|jnz|jg|jl|jge|jle|hwi|hwq|jz|js|jns|ret|jmp|not|jc|jnc|jo|jno|inc|dec|ja|jna)\\b').test(mnemonic.toLowerCase())) { + if (!new RegExp('\\b(?:push|mul|pop|div|neg|call|jnz|jg|jl|jge|jle|hwi|hwq|jz|js|jns|ret|jmp|not|jc|jnc|jo|jno|inc|dec|ja|jna|seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|setnae|sete|setz|setne|setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|setno|sets|setns)\\b').test(mnemonic.toLowerCase())) { result.annotations.push({ row: currentLine, column: 0, @@ -353,6 +354,16 @@ function parseInstruction(line, result, currentLine) { }); } + if (new RegExp('\\b(?:seta|setnbe|setae|setnb|setnc|setbe|setna|setb|setc|setnae|sete|setz|setne|setnz|setg|setnle|setge|setnl|setle|setng|setl|setnge|seto|setno|sets|setns)\\b').test(mnemonic.toLowerCase())) { + if (getOperandType(strO1, result) === OPERAND_IMM) { + result.annotations.push({ + row: currentLine, + column: 0, + text: "Invalid operand type: " + strO1, + type: "error" + }); + } + } } else { //No operand diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetaInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetaInstructionTest.java new file mode 100644 index 0000000..a4825e0 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetaInstructionTest.java @@ -0,0 +1,54 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetaInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETA; + + public SetaInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetaInstruction(); + } + + /** + * SETA, SETNBE Above, Not Below or Equal CF=0 AND ZF=0 + */ + @Test + public void execution() { + status.setCarryFlag(false); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setCarryFlag(true); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + status.setCarryFlag(false); + status.setZeroFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + status.setCarryFlag(true); + status.setZeroFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetaeInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetaeInstructionTest.java new file mode 100644 index 0000000..10d70c3 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetaeInstructionTest.java @@ -0,0 +1,42 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetaeInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETAE; + + public SetaeInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetaeInstruction(); + } + + /** + * SETAE,SETNB,SETNC Above or Equal, Not Below, No Carry CF=0 + */ + @Test + public void execution() { + status.setCarryFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setCarryFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetbInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetbInstructionTest.java new file mode 100644 index 0000000..c0f464b --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetbInstructionTest.java @@ -0,0 +1,42 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetbInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETB; + + public SetbInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetbInstruction(); + } + + /** + * SETB, SETC,SETNAE Below, Carry, Not Above or Equal CF=1 + */ + @Test + public void execution() { + status.setCarryFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setCarryFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetbeInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetbeInstructionTest.java new file mode 100644 index 0000000..c23d5d8 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetbeInstructionTest.java @@ -0,0 +1,54 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetbeInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETBE; + + public SetbeInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetbeInstruction(); + } + + /** + * SETBE, SETNA Below or Equal, Not Above CF=1 OR ZF=1 + */ + @Test + public void execution() { + status.setCarryFlag(false); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + status.setCarryFlag(true); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setCarryFlag(false); + status.setZeroFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setCarryFlag(true); + status.setZeroFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetcInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetcInstructionTest.java new file mode 100644 index 0000000..2777442 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetcInstructionTest.java @@ -0,0 +1,42 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetcInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETB; + + public SetcInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetcInstruction(); + } + + /** + * SETB, SETC,SETNAE Below, Carry, Not Above or Equal CF=1 + */ + @Test + public void execution() { + status.setCarryFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setCarryFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetccInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetccInstructionTest.java new file mode 100644 index 0000000..8d6e524 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetccInstructionTest.java @@ -0,0 +1,70 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Operand; +import net.simon987.server.assembly.OperandType; + +import net.simon987.server.assembly.exception.*; + +import org.junit.Test; + +import static org.junit.Assert.*; + +import java.io.ByteArrayOutputStream; + +public class SetccInstructionTest { + /** + * Since SETCC is not an actual valid mnemonic, encoding the SetccInstruction class should throw an exception + */ + @Test + public void throwsInvalidMnemonicException() { + SetccInstruction instruction = new SetccInstruction(); + + boolean hasThrown = false; + try { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + Operand operand = new Operand(OperandType.MEMORY_REG16, 1); + instruction.encode(stream, operand, 0); + } catch (AssemblyException exception) { + if (exception instanceof InvalidMnemonicException) { + hasThrown = true; + } + } + assertTrue(hasThrown); + } + + @Test + public void throwsIllegalOperandException() { + SetccInstruction instruction = new SetccInstruction(); + + boolean hasThrownForZeroOperands = false; + boolean oneOperandImmediatIsInvalid = false; + boolean hasThrownForTwoOperands = false; + + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + + try { + instruction.encode(stream, 0); + } catch (AssemblyException exception) { + if (exception instanceof IllegalOperandException) { + hasThrownForZeroOperands = true; + } + } + + try { + Operand o1 = new Operand(OperandType.MEMORY_REG16, 1); + Operand o2= new Operand(OperandType.MEMORY_REG16, 1); + instruction.encode(stream, o1, o2, 0); + } catch (AssemblyException exception) { + if (exception instanceof IllegalOperandException) { + hasThrownForTwoOperands = true; + } + } + + Operand invalidOperand = new Operand(OperandType.IMMEDIATE16, 0); + oneOperandImmediatIsInvalid = !instruction.operandValid(invalidOperand); + + assertTrue(hasThrownForZeroOperands); + assertTrue(hasThrownForTwoOperands); + assertTrue(oneOperandImmediatIsInvalid); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SeteInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SeteInstructionTest.java new file mode 100644 index 0000000..cd5ec55 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SeteInstructionTest.java @@ -0,0 +1,42 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SeteInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETE; + + public SeteInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SeteInstruction(); + } + + /** + * SETE, SETZ Equal, Zero ZF=1 + */ + @Test + public void execution() { + status.setZeroFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetgInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetgInstructionTest.java new file mode 100644 index 0000000..2bd7e58 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetgInstructionTest.java @@ -0,0 +1,64 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetgInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETG; + + public SetgInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetgInstruction(); + } + + /** + * SETG, SETNLE Greater, Not Less or Equal SF=OF AND ZF=0 + */ + @Test + public void execution() { + status.setSignFlag(false); + status.setOverflowFlag(false); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setSignFlag(true); + status.setOverflowFlag(true); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setSignFlag(false); + status.setOverflowFlag(false); + status.setZeroFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + status.setSignFlag(true); + status.setOverflowFlag(false); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + status.setSignFlag(false); + status.setOverflowFlag(true); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetgeInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetgeInstructionTest.java new file mode 100644 index 0000000..f667877 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetgeInstructionTest.java @@ -0,0 +1,54 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetgeInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETGE; + + public SetgeInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetgeInstruction(); + } + + /** + * SETGE, SETNL Greater or Equal, Not Less SF=OF + */ + @Test + public void execution() { + status.setSignFlag(true); + status.setOverflowFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setSignFlag(true); + status.setOverflowFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + status.setSignFlag(false); + status.setOverflowFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + status.setSignFlag(false); + status.setOverflowFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetlInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetlInstructionTest.java new file mode 100644 index 0000000..5f47b68 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetlInstructionTest.java @@ -0,0 +1,54 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetlInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETL; + + public SetlInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetlInstruction(); + } + + /** + * SETL, SETNGE Less, Not Greater or Equal SF<>OF + */ + @Test + public void execution() { + status.setSignFlag(true); + status.setOverflowFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setSignFlag(false); + status.setOverflowFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setSignFlag(false); + status.setOverflowFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + status.setSignFlag(true); + status.setOverflowFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetleInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetleInstructionTest.java new file mode 100644 index 0000000..2e37ea9 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetleInstructionTest.java @@ -0,0 +1,62 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetleInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETLE; + + public SetleInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetleInstruction(); + } + + /** + * SETL, SETNGE Less, Not Greater or Equal SF<>OF + */ + @Test + public void execution() { + status.setSignFlag(true); + status.setOverflowFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setSignFlag(false); + status.setOverflowFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setSignFlag(false); + status.setOverflowFlag(false); + status.setZeroFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setSignFlag(false); + status.setOverflowFlag(false); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + status.setSignFlag(true); + status.setOverflowFlag(true); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetnaInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetnaInstructionTest.java new file mode 100644 index 0000000..49e9400 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetnaInstructionTest.java @@ -0,0 +1,54 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetnaInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETBE; + + public SetnaInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetnaInstruction(); + } + + /** + * SETBE, SETNA Below or Equal, Not Above CF=1 OR ZF=1 + */ + @Test + public void execution() { + status.setCarryFlag(false); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + status.setCarryFlag(true); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setCarryFlag(false); + status.setZeroFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setCarryFlag(true); + status.setZeroFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetnaeInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetnaeInstructionTest.java new file mode 100644 index 0000000..c9ee249 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetnaeInstructionTest.java @@ -0,0 +1,42 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetnaeInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETB; + + public SetnaeInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetnaeInstruction(); + } + + /** + * SETB, SETC,SETNAE Below, Carry, Not Above or Equal CF=1 + */ + @Test + public void execution() { + status.setCarryFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setCarryFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetnbInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetnbInstructionTest.java new file mode 100644 index 0000000..2be4102 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetnbInstructionTest.java @@ -0,0 +1,42 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetnbInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETAE; + + public SetnbInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetnbInstruction(); + } + + /** + * SETAE,SETNB,SETNC Above or Equal, Not Below, No Carry CF=0 + */ + @Test + public void execution() { + status.setCarryFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setCarryFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetnbeInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetnbeInstructionTest.java new file mode 100644 index 0000000..a501ee4 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetnbeInstructionTest.java @@ -0,0 +1,54 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetnbeInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETA; + + public SetnbeInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetnbeInstruction(); + } + + /** + * SETA, SETNBE Above, Not Below or Equal CF=0 AND ZF=0 + */ + @Test + public void execution() { + status.setCarryFlag(false); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setCarryFlag(true); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + status.setCarryFlag(false); + status.setZeroFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + status.setCarryFlag(true); + status.setZeroFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetncInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetncInstructionTest.java new file mode 100644 index 0000000..84d0998 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetncInstructionTest.java @@ -0,0 +1,42 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetncInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETAE; + + public SetncInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetncInstruction(); + } + + /** + * SETAE,SETNB,SETNC Above or Equal, Not Below, No Carry CF=0 + */ + @Test + public void execution() { + status.setCarryFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setCarryFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetneInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetneInstructionTest.java new file mode 100644 index 0000000..4a21ab0 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetneInstructionTest.java @@ -0,0 +1,42 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetneInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETNE; + + public SetneInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetneInstruction(); + } + + /** + * SETNE, SETNZ Not Equal, Not Zero ZF=0 + */ + @Test + public void execution() { + status.setZeroFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetngInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetngInstructionTest.java new file mode 100644 index 0000000..8738be1 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetngInstructionTest.java @@ -0,0 +1,63 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetngInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETLE; + + public SetngInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetngInstruction(); + } + + /** + * SETLE, SETNG Less or Equal, Not Greater SF<>OF OR ZF=1 + */ + @Test + public void execution() { + status.setSignFlag(true); + status.setOverflowFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setSignFlag(false); + status.setOverflowFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setSignFlag(false); + status.setOverflowFlag(false); + status.setZeroFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setSignFlag(false); + status.setOverflowFlag(false); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + + status.setSignFlag(true); + status.setOverflowFlag(true); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetngeInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetngeInstructionTest.java new file mode 100644 index 0000000..9a9853e --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetngeInstructionTest.java @@ -0,0 +1,54 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetngeInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETL; + + public SetngeInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetngeInstruction(); + } + + /** + * SETL, SETNGE Less, Not Greater or Equal SF<>OF + */ + @Test + public void execution() { + status.setSignFlag(true); + status.setOverflowFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setSignFlag(false); + status.setOverflowFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setSignFlag(false); + status.setOverflowFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + status.setSignFlag(true); + status.setOverflowFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetnlInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetnlInstructionTest.java new file mode 100644 index 0000000..9431a0f --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetnlInstructionTest.java @@ -0,0 +1,54 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetnlInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETGE; + + public SetnlInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetnlInstruction(); + } + + /** + * SETGE, SETNL Greater or Equal, Not Less SF=OF + */ + @Test + public void execution() { + status.setSignFlag(true); + status.setOverflowFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setSignFlag(true); + status.setOverflowFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + status.setSignFlag(false); + status.setOverflowFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + status.setSignFlag(false); + status.setOverflowFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetnleInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetnleInstructionTest.java new file mode 100644 index 0000000..fd0c8ba --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetnleInstructionTest.java @@ -0,0 +1,64 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetnleInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETG; + + public SetnleInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetnleInstruction(); + } + + /** + * SETG, SETNLE Greater, Not Less or Equal SF=OF AND ZF=0 + */ + @Test + public void execution() { + status.setSignFlag(false); + status.setOverflowFlag(false); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setSignFlag(true); + status.setOverflowFlag(true); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setSignFlag(false); + status.setOverflowFlag(false); + status.setZeroFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + status.setSignFlag(true); + status.setOverflowFlag(false); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + + status.setSignFlag(false); + status.setOverflowFlag(true); + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetnoInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetnoInstructionTest.java new file mode 100644 index 0000000..beae781 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetnoInstructionTest.java @@ -0,0 +1,42 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetnoInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETNO; + + public SetnoInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetnoInstruction(); + } + + /** + * SETNO No Overflow OF=0 + */ + @Test + public void execution() { + status.setOverflowFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setOverflowFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetnsInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetnsInstructionTest.java new file mode 100644 index 0000000..6b256b5 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetnsInstructionTest.java @@ -0,0 +1,42 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetnsInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETNS; + + public SetnsInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetnsInstruction(); + } + + /** + * SETS No Sign SF=0 + */ + @Test + public void execution() { + status.setSignFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setSignFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetnzInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetnzInstructionTest.java new file mode 100644 index 0000000..e69de29 diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetoInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetoInstructionTest.java new file mode 100644 index 0000000..eee4911 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetoInstructionTest.java @@ -0,0 +1,42 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetoInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETO; + + public SetoInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetoInstruction(); + } + + /** + * SETO Overflow OF=1 + */ + @Test + public void execution() { + status.setOverflowFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setOverflowFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetsInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetsInstructionTest.java new file mode 100644 index 0000000..ca9be24 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetsInstructionTest.java @@ -0,0 +1,42 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetsInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETS; + + public SetsInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetsInstruction(); + } + + /** + * SETS Sign SF=1 + */ + @Test + public void execution() { + status.setSignFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setSignFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +} diff --git a/Server/src/test/java/net/simon987/server/assembly/instruction/SetzInstructionTest.java b/Server/src/test/java/net/simon987/server/assembly/instruction/SetzInstructionTest.java new file mode 100644 index 0000000..5ea4475 --- /dev/null +++ b/Server/src/test/java/net/simon987/server/assembly/instruction/SetzInstructionTest.java @@ -0,0 +1,42 @@ +package net.simon987.server.assembly.instruction; + +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.RegisterSet; +import net.simon987.server.assembly.Status; + +import org.junit.Test; + +import static org.junit.Assert.*; + + +public class SetzInstructionTest { + private RegisterSet registers; + private Status status; + private SetccInstruction instruction; + private int SETCCOPCODE = SetccInstruction.SETE; + + public SetzInstructionTest() { + registers = new RegisterSet(); + registers.put(1, new Register("R")); + registers.clear(); + + status = new Status(); + status.clear(); + + instruction = new SetzInstruction(); + } + + /** + * SETE, SETZ Equal, Zero ZF=1 + */ + @Test + public void execution() { + status.setZeroFlag(true); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 1); + + status.setZeroFlag(false); + instruction.execute(registers, 1, SETCCOPCODE, status); + assertEquals(registers.get(1), 0); + } +}