-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSmpProcessor.java
More file actions
211 lines (187 loc) · 6.34 KB
/
Copy pathSmpProcessor.java
File metadata and controls
211 lines (187 loc) · 6.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
import java.util.Scanner;
/**
* Simpletron processor
*
* @author Maverick G. Fabroa
* @date September 29, 2022
* @based on the code written by sir Dennis Durano
*/
public class SmpProcessor {
// Program counter
private int pc;
// Instruction register
private String ir;
// The memory
private SmpMemory memory;
// Operation code
private String opcode;
// Operand
private int operand;
// Accumulator
private String accumulator;
/**
* Initialize memory with the default size
*/
public SmpProcessor() {
this.memory = new SmpMemory();
}
/**
* Store the data with the specified address to the memory
*
* @param data The data to store
* @param address The address to store
*/
public void store(String data, int address) {
// Store the data to the memory
this.memory.setItem(data, address);
}
/**
* Dump the processor status
*/
public void dump() {
System.out.println("\nProgram counter : " + this.pc);
System.out.println("Instruction Register : " + this.ir);
System.out.println("Accumulator : " + this.accumulator);
System.out.println("Opcode : " + this.opcode);
System.out.println("Operand : " + this.operand);
}
/**
* Execute the program with start address
*/
public void execute() {
// For each instruction
for (pc = 0; pc < this.memory.getSize() - 1; pc++) {
// Dump the memory
this.memory.dump();
// Fetch the instruction
fetch(pc);
// Dump the processor status
dump();
// Decode the instruction
decode();
}
}
/**
* Step-by-step execution
*/
public void step() {
// For each instruction
for (pc = 0; pc < this.memory.getSize() - 1; pc++) {
// Dump the memory
this.memory.dump();
// Fetch the instruction
fetch(pc);
// Dump the processor status
dump();
// Decode the instruction
decode();
// Wait for user input
System.out.print("\n\nPress enter key to continue...");
new Scanner(System.in).nextLine();
}
}
/**
* Fetch the instruction from the memory
*
* @param address
*/
public void fetch(int address) {
// Set the instruction register with the data from the memory
this.ir = this.memory.getItem(address);
// Set opcode and operand on set instruction register
if (this.ir != null && this.ir.length() == 4) {
this.opcode = this.ir.substring(0, 2);
this.operand = Integer.parseInt(this.ir.substring(2, 4));
}
}
/**
* Decode the instruction
*/
public void decode() {
String data = "";
int result = 0;
// If no opcode
if (opcode == null) {
// Don't proceed to decoding
return;
}
// Check the opcode
switch (opcode) {
// READ
case "10":
// Get user input
System.out.print("Enter value: ");
data = new Scanner(System.in).nextLine();
// Store the data to the memory
this.memory.setItem(data, this.operand);
break;
// WRITE
case "11":
// Print the data from the memory
System.out.printf("\nData from Memory Address (%d) : %s\n\n", this.operand, this.memory.getItem(this.operand));
break;
// LOAD
case "20":
// Load the data from the memory to the accumulator
this.accumulator = this.memory.getItem(this.operand);
break;
// STORE
case "21":
// Store the data from the accumulator to the memory
this.memory.setItem(this.accumulator, this.operand);
break;
// ADD
case "30":
// Add the data from the memory to the accumulator
result = Integer.parseInt(this.accumulator) + Integer.parseInt(this.memory.getItem(this.operand));
this.accumulator = String.valueOf(result);
break;
// SUBTRACT
case "31":
// Subtract the data from the memory to the accumulator
result = Integer.parseInt(this.accumulator) - Integer.parseInt(this.memory.getItem(this.operand));
this.accumulator = String.valueOf(result);
break;
/**
* If you notice, all branches have - 1 to the program counter,
* since in the next instruction, the program counter will be
* incremented by 1 by the for loop.
*
* For example, if the operand is 0 and the program counter is 0,
* the next counter will be 1, the first instruction will be skipped,
* and this is the problem. We want to jump to the address 0
*
* To fix this, we subtract 1 from the operand. So, if the operand is 0,
* next instruction's program counter will be 0.
*
* The same applies to the other branches.
*/
// BRANCH
case "40":
// Set the program counter to the operand
this.pc = this.operand - 1;
break;
// BRANCHNEG
case "41":
// Check if the accumulator is negative
if (Integer.parseInt(this.accumulator) < 0) {
// Set the program counter to the operand
this.pc = this.operand - 1;
}
break;
// BRANCHZERO
case "42":
// Check if the accumulator is zero
if (Integer.parseInt(this.accumulator) == 0) {
// Set the program counter to the operand
this.pc = this.operand - 1;
}
break;
// HALT
case "43":
System.out.println("\nProgram terminated.");
System.exit(0);
break;
}
}
}