-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathComputer.cpp
296 lines (256 loc) · 12.5 KB
/
Computer.cpp
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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
#include <iostream>
#include <string.h>
#include "Computer.h"
#define DEBUGMODE 1
using namespace std;
Computer::Computer() {
menu();
delete CPU1;
delete Memory1;
}
void::Computer::run() {
CPU1->CPU_RELOAD(); /// Reset the values in the CPU like the PC and halt signal
/// Unnecessary due to CPU being deleted, however kept here in case of random values assigned to it
cout << "========INITIAL MEMORY========" << endl;
Memory1->printmem(); /// Print the memory blocks out at the beginning
cout << "==============================" << endl;
while(CPU1->get_PC() < Memory1->get_size()){ /// Keep executing cycle until all the memory cells have been read
if(!CPU1->Halt){ /// Check if the halt signal has been given
cout << "============================CYCLE" << CPU1->get_PC() << "============================" << endl;
cout << "=======> 0: fetching..." << endl;
fetch();
cout << "=======> 1: executing..." << endl;
execute();
cout << "=======> 2: finished..." << endl;
cout << "=============================================================" << endl;
}
else break;
}
cout << "Program Complete!" << endl;
cout << "========FINAL MEMORY========" << endl;
Memory1->printmem(); /// Print the memory blocks out at the end
cout << "==============================" << endl;
return;
}
void::Computer::fetch() {
addressbus = CPU1->update_address_bus(CPU1->get_PC()); /// Generic update address function used to initial upload the PC
#if DEBUGMODE == 1
cout << "0.1: Addressbus: " << addressbus << endl;
#endif
Memory1->read(instructionbus,addressbus);
#if DEBUGMODE == 1
cout << "0.2: Instructionbus: " << instructionbus << endl;
#endif
CPU1->update(CPU1->READ,addressbus,instructionbus);
#if DEBUGMODE == 1
cout << "0.3: MODE: ";
if(CPU1->mode == CPU1->READ){
cout<< "READ" << endl;
}
else cout << "WRITE" << endl;
cout << "0.4: MAR: " << CPU1->get_MAR() << endl;
cout << "0.5: MDR: " << CPU1->get_MDR() << endl;
#endif
CPU1->IR_load();
#if DEBUGMODE == 1
cout << "0.6: IR: " << CPU1->get_IR() << endl;
#endif
return;
}
void::Computer::execute() {
CPU1->IR_decode();
#if DEBUGMODE == 1
cout << "DECODING" << endl;
cout << "1.1: IR: " << CPU1->get_IR() << endl;
cout << "1.2: Opcode: " << CPU1->get_opcode() << endl;
cout << "1.3: Operand: " << CPU1->get_operand1() << endl;
cout << "1.4: Operand Cast: ";
if (!strcmp(CPU1->get_opcode(),"NOP")) {cout << "is not available with No Operation" << endl;}
else cout << CPU1->get_operand1_cast() << endl;
cout << "1.5: This data " << (CPU1->yesOP ? "is " : "is not ") << "operable" << endl;
cout << "1.6: There " << (CPU1->feedback ? "is " : "is no ") << "feedback" << endl;
#endif
if (CPU1->yesOP){ /// If instruction is not NOP or VAR
if (!CPU1->feedback){ /// Does the instruction require feedback?
if (!strcmp(CPU1->get_opcode(),"STO")) { /// This one is for store
CPU1->CPU_execute(); /// Execute store
#if DEBUGMODE == 1
cout << "STORING" << endl;
cout << "1.7: Feedback Instruction: " << CPU1->get_feedback_instruction() << endl;
#endif
CPU1->update(CPU1->WRITE, CPU1->get_operand1_cast(),CPU1->get_feedback_instruction()); /// Update the MAR and MDR
strcpy(instructionbus,CPU1->update_instructionbus(CPU1->get_MDR())); /// Copy MDR to instructionbus, strcpy for char array
addressbus = CPU1->update_address_bus(CPU1->get_MAR()); /// Copy MAR to addressbus, assign int values
#if DEBUGMODE == 1
cout << "1.8: Writing " << instructionbus << " to address " << addressbus << endl;
#endif
Memory1->write(instructionbus,addressbus); /// Write the instruction to memory location at address
#if DEBUGMODE == 1
cout << "1.9: Memory " << addressbus << " is now " << Memory1->get_block(addressbus) << endl;
#endif
return;
}
else if (!strcmp(CPU1->get_opcode(), "JMP")) { /// This one is for jump
CPU1->CPU_execute();
#if DEBUGMODE == 1
cout << "JUMPING" << endl;
cout << "1.7: Jumping to address " << CPU1->get_PC() << endl;
#endif
return;
}
return;
}
else if (CPU1->feedback){ /// If instruction needs feedback, this is the routine
addressbus = CPU1->update_address_bus(CPU1->get_operand1_cast()); /// Get the address to feedback from
Memory1->read(instructionbus,addressbus); /// Read the data at feedback address
CPU1->update(CPU1->READ,addressbus,instructionbus); /// update the MAR and MDR
#if DEBUGMODE == 1
cout << "GETTING VARIABLE FOR OPERATION: " << CPU1->get_opcode() << endl;
cout << "1.7: Feedback Data in MDR: " << CPU1->get_MDR() << endl;
#endif
CPU1->MDR_decode(); /// Decode the values in the MDR
if (!strcmp(CPU1->get_MDR_opcode(),"VAR")) { /// Check the feedback is a variable
if (!strcmp(CPU1->get_opcode(), "MOV") || !strcmp(CPU1->get_opcode(), "CPY")){ /// In the special case that it's MOV or CPY
addressbus = CPU1->update_address_bus(CPU1->get_operand2_cast());
strcpy(instructionbus,CPU1->update_instructionbus(CPU1->get_MDR()));
#if DEBUGMODE == 1
cout << "1.8: Writing " << instructionbus << " to address " << addressbus << endl;
#endif
Memory1->write(instructionbus,addressbus); /// Write the instruction to memory location at address
#if DEBUGMODE == 1
cout << "1.9: Memory " << addressbus << " is now " << Memory1->get_block(addressbus) << endl;
#endif
if (!strcmp(CPU1->get_opcode(), "MOV")){
addressbus = CPU1->update_address_bus(CPU1->get_operand1_cast());
strcpy(instructionbus,"NOP##"); /// Delete old memory location if MOV
Memory1->write(instructionbus,addressbus);
}
}
else {
CPU1->CPU_execute(CPU1->get_MDR_operand()); /// If not MOV or CPY, then continue with other operations
#if DEBUGMODE == 1
cout << "1.8: ALU Contents: " << CPU1->get_feedback_instruction() << endl;
CPU1->print_ALU();
#endif
CPU1->clearXY(); /// Clear ALU X and Y;
}
return;
}
else cout << "error, feedback address is not a variable!" << endl;
}
}
return;
}
void::Computer::menu() {
int choice;
int example;
while(!shutdown) {
cout << "========MENU========" << endl;
cout << "1: Run Examples" << endl;
cout << "2: Input Memory" << endl;
cout << "3: Shutdown" << endl;
cin >> choice;
if (choice == 1) {
cout << "========EXAMPLES========" << endl;
cout << "1: ADD" << endl; /// See the constructor in Memory.cpp for more information
cout << "2: SUBTRACT" << endl;
cout << "3: JUMP" << endl;
cout << "4: MODULO" << endl;
cout << "5: MULTIPLY" << endl;
cout << "6: DIVIDE" << endl;
cout << "7: INFINITE JUMP" << endl;
cout << "8: COPY" << endl;
cout << "9: MOVE" << endl;
cout << "10: USER DEFINED" << endl;
cin >> example;
switch (example) {
case 1:
CPU1 = new CPU;
Memory1 = new Memory(Memory1->ADD); /// You can see that it creates a pointer to a new memory loaded with an example
run();
delete Memory1;
delete CPU1;
break;
case 2:
CPU1 = new CPU;
Memory1 = new Memory(Memory1->SUB);
run();
delete Memory1;
delete CPU1;
break;
case 3:
CPU1 = new CPU;
Memory1 = new Memory(Memory1->JMP);
run();
delete Memory1;
delete CPU1;
break;
case 4:
CPU1 = new CPU;
Memory1 = new Memory(Memory1->MOD);
run();
delete Memory1;
delete CPU1;
break;
case 5:
CPU1 = new CPU;
Memory1 = new Memory(Memory1->MUL);
run();
delete Memory1;
delete CPU1;
break;
case 6:
CPU1 = new CPU;
Memory1 = new Memory(Memory1->DIV);
run();
delete Memory1;
delete CPU1;
break;
case 7:
CPU1 = new CPU;
Memory1 = new Memory(Memory1->INFJMP);
run();
delete Memory1;
delete CPU1;
break;
case 8:
CPU1 = new CPU;
Memory1 = new Memory(Memory1->CPY);
run();
delete Memory1;
delete CPU1;
break;
case 9:
CPU1 = new CPU;
Memory1 = new Memory(Memory1->MOV);
run();
delete Memory1;
delete CPU1;
break;
case 10:
CPU1 = new CPU;
run();
delete Memory1;
delete CPU1;
break;
default:
cout << "You did not enter a valid option" << endl;
break;
}
}
else if (choice == 2){
Memory1 = new Memory(Memory1->USR);
Memory1->mem_input();
cout << "Now try to run User Defined in examples" << endl;
}
else if (choice == 3){
shutdown = true;
cout << "Shutdown Selected..." << endl;
}
}
cout << "Shutting down..." << endl;
return;
}
//
// Created by Peter Chai on 03/04/2017.
//