77
88/**
99 * Load Address instruction. Similar to Load, but after reading the next memory value, the value is
10- * interpreted as a memory address, and the value at that address is loaded into the destination
11- * register. The destination register is specified by the operand.
10+ * split into two 4-bit values, each indexing a register. The leading 4 bits determine the source
11+ * register and the trailing 4 bits determine the destination register. The value in the source
12+ * register is interpreted as a memory address, and the value at that memory address is stored in
13+ * the destination register. The operand is not used.
1214 */
1315public class LdA extends Instruction {
1416
@@ -18,37 +20,64 @@ public LdA(int operand) {
1820
1921 @ Override
2022 protected void internalExecute (Memory mem , Registry reg , ProgramCounter pc , IO io ) {
21- // Read the next memory value, and interpret as a memory address.
22- int address = mem .getValueAt (pc .next ());
23+ // Read the next memory value, and split into two 4-bit parts.
24+ int addresses = mem .getValueAt (pc .next ());
25+ int src = (addresses >> 4 ) & 0xF ;
26+ int dst = addresses & 0xF ;
27+
28+ int srcAddress = reg .getValueAt (src );
29+ int value = mem .getValueAt (srcAddress );
2330
2431 // Read the value at the memory address, and store in the destination register.
25- reg .setValueAt (operand , mem . getValueAt ( address ) );
32+ reg .setValueAt (dst , value );
2633 }
2734
2835 @ Override
2936 protected String internalPrettyPrint (Memory mem , Registry reg , int memIdx ) {
37+
3038 if (memIdx >= mem .size ()) {
31- return "(" + Instruction .INVALID_REG_CHAR + ")" ;
39+ return Instruction .INVALID_REG_CHAR ;
3240 }
33- int address = mem .getValueAt (memIdx + 1 );
41+ // Read the next memory value, and split into two 4-bit parts.
42+ int addresses = mem .getValueAt (memIdx + 1 );
43+ int src = (addresses >> 4 ) & 0xF ;
44+ int dst = addresses & 0xF ;
45+
3446 return String .format (
35- // e.g. LDA (m[12] -> R0)
36- "(m[%s] %s %s)" , address , Instruction .RIGHT_ARROW_CHAR , Registry .idxToName (operand ));
47+ "(*%s %s %s)" ,
48+ Registry . idxToName ( src ), Instruction .RIGHT_ARROW_CHAR , Registry .idxToName (dst ));
3749 }
3850
3951 @ Override
4052 public int [] getAffectedMemoryCells (Memory mem , Registry reg , int memIdx ) {
4153 if (memIdx >= mem .size ()) {
4254 return new int [] {memIdx };
4355 }
44- int address = mem .getValueAt (memIdx + 1 );
45- return new int [] {memIdx , memIdx + 1 , address };
56+ int addresses = mem .getValueAt (memIdx + 1 );
57+ int src = (addresses >> 4 ) & 0xF ;
58+
59+ int srcAddress = reg .getValueAt (src );
60+
61+ return new int [] {memIdx , memIdx + 1 , srcAddress };
4662 }
4763
4864 @ Override
4965 public int [] getAffectedRegisters (Memory mem , Registry reg , int memIdx ) {
50- if (operand >= 0 && operand < Registry .NUM_REGISTERS ) {
51- return new int [] {operand };
66+ if (memIdx >= mem .size ()) {
67+ return new int [] {memIdx };
68+ }
69+ int addresses = mem .getValueAt (memIdx + 1 );
70+ int src = (addresses >> 4 ) & 0xF ;
71+ int dst = addresses & 0xF ;
72+
73+ if (src >= 0 && src < Registry .NUM_REGISTERS && dst >= 0 && dst < Registry .NUM_REGISTERS ) {
74+ return new int [] {src , dst };
75+ }
76+ if (src >= 0 && src < Registry .NUM_REGISTERS ) {
77+ return new int [] {src };
78+ }
79+ if (dst >= 0 && dst < Registry .NUM_REGISTERS ) {
80+ return new int [] {dst };
5281 }
5382 return new int [0 ];
5483 }
0 commit comments