diff --git a/src/main/java/instruction/LdA.java b/src/main/java/instruction/LdA.java index 3ea7293..215bf1a 100644 --- a/src/main/java/instruction/LdA.java +++ b/src/main/java/instruction/LdA.java @@ -7,8 +7,10 @@ /** * Load Address instruction. Similar to Load, but after reading the next memory value, the value is - * interpreted as a memory address, and the value at that address is loaded into the destination - * register. The destination register is specified by the operand. + * split into two 4-bit values, each indexing a register. The leading 4 bits determine the source + * register and the trailing 4 bits determine the destination register. The value in the source + * register is interpreted as a memory address, and the value at that memory address is stored in + * the destination register. The operand is not used. */ public class LdA extends Instruction { @@ -18,22 +20,32 @@ public LdA(int operand) { @Override protected void internalExecute(Memory mem, Registry reg, ProgramCounter pc, IO io) { - // Read the next memory value, and interpret as a memory address. - int address = mem.getValueAt(pc.next()); + // Read the next memory value, and split into two 4-bit parts. + int addresses = mem.getValueAt(pc.next()); + int src = (addresses >> 4) & 0xF; + int dst = addresses & 0xF; + + int srcAddress = reg.getValueAt(src); + int value = mem.getValueAt(srcAddress); // Read the value at the memory address, and store in the destination register. - reg.setValueAt(operand, mem.getValueAt(address)); + reg.setValueAt(dst, value); } @Override protected String internalPrettyPrint(Memory mem, Registry reg, int memIdx) { + if (memIdx >= mem.size()) { - return "(" + Instruction.INVALID_REG_CHAR + ")"; + return Instruction.INVALID_REG_CHAR; } - int address = mem.getValueAt(memIdx + 1); + // Read the next memory value, and split into two 4-bit parts. + int addresses = mem.getValueAt(memIdx + 1); + int src = (addresses >> 4) & 0xF; + int dst = addresses & 0xF; + return String.format( - // e.g. LDA (m[12] -> R0) - "(m[%s] %s %s)", address, Instruction.RIGHT_ARROW_CHAR, Registry.idxToName(operand)); + "(*%s %s %s)", + Registry.idxToName(src), Instruction.RIGHT_ARROW_CHAR, Registry.idxToName(dst)); } @Override @@ -41,14 +53,31 @@ public int[] getAffectedMemoryCells(Memory mem, Registry reg, int memIdx) { if (memIdx >= mem.size()) { return new int[] {memIdx}; } - int address = mem.getValueAt(memIdx + 1); - return new int[] {memIdx, memIdx + 1, address}; + int addresses = mem.getValueAt(memIdx + 1); + int src = (addresses >> 4) & 0xF; + + int srcAddress = reg.getValueAt(src); + + return new int[] {memIdx, memIdx + 1, srcAddress}; } @Override public int[] getAffectedRegisters(Memory mem, Registry reg, int memIdx) { - if (operand >= 0 && operand < Registry.NUM_REGISTERS) { - return new int[] {operand}; + if (memIdx >= mem.size()) { + return new int[] {memIdx}; + } + int addresses = mem.getValueAt(memIdx + 1); + int src = (addresses >> 4) & 0xF; + int dst = addresses & 0xF; + + if (src >= 0 && src < Registry.NUM_REGISTERS && dst >= 0 && dst < Registry.NUM_REGISTERS) { + return new int[] {src, dst}; + } + if (src >= 0 && src < Registry.NUM_REGISTERS) { + return new int[] {src}; + } + if (dst >= 0 && dst < Registry.NUM_REGISTERS) { + return new int[] {dst}; } return new int[0]; } diff --git a/src/main/java/view/InstructionTable.java b/src/main/java/view/InstructionTable.java index e1346b7..e89667a 100644 --- a/src/main/java/view/InstructionTable.java +++ b/src/main/java/view/InstructionTable.java @@ -208,9 +208,11 @@ private void initUIContent() { InstructionFactory.INST_NAME_LDA, InstructionFactory.INST_LDA, String.format( - "Load Address: Reads the next memory value and interprets it as a memory" - + " address. Then, reads the addressed value and loads it into a register. The" - + " 4-bit operand is the destination register index (0-%d).", + "Load Address: Loads a memory value from a dynamic address into a register." + + " The next memory value is split into two 4-bit indices, indicating the" + + " indecies (0-%d) of the source and destination register. The source register" + + " is interpreted as a memory address, from which the wanted value is read." + + " Operand has no purpose and is ignored.", (Registry.NUM_REGISTERS - 1)), pc); appendToTable(