7
7
8
8
/**
9
9
* 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.
12
14
*/
13
15
public class LdA extends Instruction {
14
16
@@ -18,37 +20,64 @@ public LdA(int operand) {
18
20
19
21
@ Override
20
22
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 );
23
30
24
31
// 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 );
26
33
}
27
34
28
35
@ Override
29
36
protected String internalPrettyPrint (Memory mem , Registry reg , int memIdx ) {
37
+
30
38
if (memIdx >= mem .size ()) {
31
- return "(" + Instruction .INVALID_REG_CHAR + ")" ;
39
+ return Instruction .INVALID_REG_CHAR ;
32
40
}
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
+
34
46
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 ));
37
49
}
38
50
39
51
@ Override
40
52
public int [] getAffectedMemoryCells (Memory mem , Registry reg , int memIdx ) {
41
53
if (memIdx >= mem .size ()) {
42
54
return new int [] {memIdx };
43
55
}
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 };
46
62
}
47
63
48
64
@ Override
49
65
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 };
52
81
}
53
82
return new int [0 ];
54
83
}
0 commit comments