https://github.com/jakub-gonet/Emulated-CPUhttps://github.com/jakub-gonet/Emulated-CPU
package cpu.instruction;
import cpu.ADDR_TYPE;
import cpu.instruction.converter.ValueToAddressingMode;
import cpu.instruction.converter.ValueToOPCode;
import cpu.memory.Memory;
public class InstructionRunner {
public static void run(Instruction instruction) {
if (instruction != null) {
Integer arg2Value = (instruction.getArg2() != null) ? instruction.getArg2()
.getValue() : null;
Integer arg1Value = (instruction.getArg1() != null) ? instruction.getArg1()
.getValue() : null;
Integer address = (instruction.getArg1() != null) ? instruction.getArg1()
.getAddress() : null;
Integer value = instruction.getMnemonic()
.getOpcode()
.apply(arg1Value,
arg2Value);
if (instruction.getArgumentCount() > 0) instruction.getArg1()
.getMemory()
.write(address, value);
} else throw new
IllegalArgumentException("ERROR: Instruction can't be null.");
}
public static Instruction fetchInstruction(int address) {
try {
int opCodeAndAddresses = readFromMemory(address);
InstructionMnemonic mnemonic = new InstructionMnemonic(
ValueToOPCode.getOPCode(opCodeAndAddresses)
);
InstructionArgument[] arguments = createArguments(mnemonic.getRequiredArgs(), address, opCodeAndAddresses);
return new Instruction(mnemonic, arguments[0], arguments[1]);
} catch (IndexOutOfBoundsException e) {
System.out.println("ERROR: OP code not recognized.");
} catch (NullPointerException e) {
System.out.println("ERROR: Bad format of instruction.");
}
return null;
}
private static InstructionArgument[] createArguments(int argumentCount, int address, int argumentsCode) {
InstructionArgument arg2 = null;
InstructionArgument arg1 = null;
switch (argumentCount) {
case 2:
int arg2Code = readFromMemory(address + 2);
ADDR_TYPE secondAddressType = getAddressType(2, argumentsCode);
arg2 = new InstructionArgument(arg2Code, secondAddressType);
case 1:
int arg1Code = readFromMemory(address + 1);
ADDR_TYPE firstAddressType = getAddressType(1, argumentsCode);
arg1 = new InstructionArgument(arg1Code, firstAddressType);
}
return new InstructionArgument[] {arg1, arg2};
}
private static ADDR_TYPE getAddressType(int argumentNumber, int operatorAndAddressingModeCode) {
if (argumentNumber == 1) return ValueToAddressingMode.getFirstArgAddressingMode(operatorAndAddressingModeCode);
if (argumentNumber == 2) return ValueToAddressingMode.getSecondArgAddressingMode(operatorAndAddressingModeCode);
throw new IllegalArgumentException("ERROR: OP code argument does not exist.");
}
private static int readFromMemory(int address) {
return Memory.getInstance()
.read(address);
}
}