mos-tui 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/OS_CP.c +68 -97
- package/core/mos_tui.py +858 -492
- package/package.json +1 -1
package/core/OS_CP.c
CHANGED
|
@@ -9,7 +9,7 @@ char IR[4]; // IR (Instruction register) of size 4
|
|
|
9
9
|
char R[4]; // R (General Purpose register) of size 4
|
|
10
10
|
int IC; // Instruction Counter
|
|
11
11
|
int C; // Toggle Register
|
|
12
|
-
int SI; // Supervisor
|
|
12
|
+
int SI; // Supervisor Interrupt
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
FILE *fin, *fout;
|
|
@@ -36,7 +36,6 @@ int lenString(char s[]) {
|
|
|
36
36
|
while (s[ans] != '\0') {
|
|
37
37
|
ans++;
|
|
38
38
|
}
|
|
39
|
-
|
|
40
39
|
return ans;
|
|
41
40
|
}
|
|
42
41
|
|
|
@@ -56,14 +55,49 @@ void init() {
|
|
|
56
55
|
SI = 0;
|
|
57
56
|
}
|
|
58
57
|
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
// ── MEMORY DUMP ──────────────────────────────────────────────────────────────
|
|
59
|
+
// Writes memory_dump.txt in the same directory as output.txt.
|
|
60
|
+
// Format per line: ADDR|C0C1C2C3|TYPE
|
|
61
|
+
// TYPE: I=instruction, D=data, E=empty
|
|
62
|
+
void dump_memory() {
|
|
63
|
+
char *dumppath = getenv("MOS_MEMDUMP");
|
|
64
|
+
if (!dumppath) return;
|
|
65
|
+
|
|
66
|
+
FILE *fd = fopen(dumppath, "w");
|
|
67
|
+
if (!fd) return;
|
|
68
|
+
|
|
69
|
+
// Write registers first
|
|
70
|
+
fprintf(fd, "REG|IC=%d|C=%d|SI=%d\n", IC, C, SI);
|
|
71
|
+
fprintf(fd, "REG|IR=%c%c%c%c\n", IR[0],IR[1],IR[2],IR[3]);
|
|
72
|
+
fprintf(fd, "REG|R=%c%c%c%c\n", R[0], R[1], R[2], R[3]);
|
|
73
|
+
|
|
74
|
+
// Write all 100 memory cells
|
|
75
|
+
for (int i = 0; i < 100; i++) {
|
|
76
|
+
char c0=M[i][0], c1=M[i][1], c2=M[i][2], c3=M[i][3];
|
|
77
|
+
// Determine cell type
|
|
78
|
+
char type = 'E'; // empty
|
|
79
|
+
bool all_space = (c0==' ' && c1==' ' && c2==' ' && c3==' ');
|
|
80
|
+
if (!all_space) {
|
|
81
|
+
// Instruction if first two chars look like a known opcode
|
|
82
|
+
if ((c0=='L'&&c1=='R') || (c0=='S'&&c1=='R') ||
|
|
83
|
+
(c0=='C'&&c1=='R') || (c0=='B'&&c1=='T') ||
|
|
84
|
+
(c0=='G'&&c1=='D') || (c0=='P'&&c1=='D') ||
|
|
85
|
+
(c0=='H'&&c1==' ') || (c0=='H'&&c1=='\0')) {
|
|
86
|
+
type = 'I';
|
|
87
|
+
} else {
|
|
88
|
+
type = 'D';
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
fprintf(fd, "%02d|%c%c%c%c|%c\n", i, c0, c1, c2, c3, type);
|
|
92
|
+
}
|
|
93
|
+
fclose(fd);
|
|
94
|
+
}
|
|
61
95
|
|
|
62
|
-
|
|
96
|
+
void LOAD() {
|
|
97
|
+
int m = 0;
|
|
98
|
+
char word[100];
|
|
63
99
|
|
|
64
100
|
while (fgets(word, sizeof(word), fin)) {
|
|
65
|
-
// printf("%s", word);
|
|
66
|
-
|
|
67
101
|
if (cmpString(word, "$AMJ", 4)) {
|
|
68
102
|
printf("%s", "AMJ (initializing the String)\n");
|
|
69
103
|
init();
|
|
@@ -73,17 +107,13 @@ void LOAD() {
|
|
|
73
107
|
printf("%s", "DTA (Starting Execution)\n");
|
|
74
108
|
START_EXECUTION();
|
|
75
109
|
}
|
|
76
|
-
|
|
77
110
|
else if (cmpString(word, "$END", 4)) {
|
|
78
111
|
printf("%s", "END (Instruction Completed)\n");
|
|
79
112
|
continue;
|
|
80
113
|
}
|
|
81
114
|
else {
|
|
82
115
|
int k = 0;
|
|
83
|
-
while (k < lenString(word) && word[k] != '\n')
|
|
84
|
-
{
|
|
85
|
-
|
|
86
|
-
// Validation for memory overflow
|
|
116
|
+
while (k < lenString(word) && word[k] != '\n') {
|
|
87
117
|
if (m >= 100) {
|
|
88
118
|
printf("Memory overflow\n");
|
|
89
119
|
return;
|
|
@@ -97,7 +127,6 @@ void LOAD() {
|
|
|
97
127
|
}
|
|
98
128
|
}
|
|
99
129
|
|
|
100
|
-
// START EXECUTION
|
|
101
130
|
void START_EXECUTION() {
|
|
102
131
|
IC = 0;
|
|
103
132
|
EXECUTE_USER_PROGRAM();
|
|
@@ -105,123 +134,87 @@ void START_EXECUTION() {
|
|
|
105
134
|
|
|
106
135
|
void EXECUTE_USER_PROGRAM() {
|
|
107
136
|
int step = 0;
|
|
108
|
-
while (true)
|
|
109
|
-
{
|
|
110
|
-
// To avoid Infinite loop
|
|
137
|
+
while (true) {
|
|
111
138
|
if (step++ > 1000) {
|
|
112
139
|
printf("Infinite loop detected\n");
|
|
113
140
|
break;
|
|
114
141
|
}
|
|
115
|
-
// Fetch the Instruction
|
|
116
142
|
for (int i = 0; i < 4; i++) {
|
|
117
143
|
IR[i] = M[IC][i];
|
|
118
144
|
}
|
|
119
|
-
|
|
120
145
|
IC++;
|
|
121
|
-
|
|
122
|
-
// Decode and Execute the Instructions
|
|
123
146
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
// LR Instruction (Load Register)
|
|
127
147
|
if (IR[0] == 'L' && IR[1] == 'R') {
|
|
128
148
|
int addr = (IR[2]-'0')*10 + (IR[3]-'0');
|
|
129
149
|
if (!(IR[2] >= '0' && IR[2] <= '9' && IR[3] >= '0' && IR[3] <= '9')) {
|
|
130
|
-
printf("Invalid operand\n");
|
|
131
|
-
break;
|
|
150
|
+
printf("Invalid operand\n"); break;
|
|
132
151
|
}
|
|
133
152
|
if (addr < 0 || addr >= 100) {
|
|
134
|
-
printf("Memory address out of bounds\n");
|
|
135
|
-
break;
|
|
153
|
+
printf("Memory address out of bounds\n"); break;
|
|
136
154
|
}
|
|
137
155
|
for (int i = 0; i < 4; i++) R[i] = M[addr][i];
|
|
138
156
|
}
|
|
139
|
-
|
|
140
|
-
// SR (Store Register)
|
|
141
157
|
else if (IR[0] == 'S' && IR[1] == 'R') {
|
|
142
158
|
int addr = (IR[2]-'0')*10 + (IR[3]-'0');
|
|
143
159
|
if (!(IR[2] >= '0' && IR[2] <= '9' && IR[3] >= '0' && IR[3] <= '9')) {
|
|
144
|
-
printf("Invalid operand\n");
|
|
145
|
-
break;
|
|
160
|
+
printf("Invalid operand\n"); break;
|
|
146
161
|
}
|
|
147
162
|
if (addr < 0 || addr >= 100) {
|
|
148
|
-
printf("Memory address out of bounds\n");
|
|
149
|
-
break;
|
|
163
|
+
printf("Memory address out of bounds\n"); break;
|
|
150
164
|
}
|
|
151
165
|
for (int i = 0; i < 4; i++) M[addr][i] = R[i];
|
|
152
166
|
}
|
|
153
|
-
|
|
154
|
-
// CR (Compare Register)
|
|
155
167
|
else if (IR[0] == 'C' && IR[1] == 'R') {
|
|
156
168
|
int addr = (IR[2]-'0')*10 + (IR[3]-'0');
|
|
157
169
|
if (!(IR[2] >= '0' && IR[2] <= '9' && IR[3] >= '0' && IR[3] <= '9')) {
|
|
158
|
-
printf("Invalid operand\n");
|
|
159
|
-
break;
|
|
170
|
+
printf("Invalid operand\n"); break;
|
|
160
171
|
}
|
|
161
172
|
if (addr < 0 || addr >= 100) {
|
|
162
|
-
printf("Memory address out of bounds\n");
|
|
163
|
-
break;
|
|
173
|
+
printf("Memory address out of bounds\n"); break;
|
|
164
174
|
}
|
|
165
175
|
C = 1;
|
|
166
176
|
for (int i = 0; i < 4; i++) {
|
|
167
|
-
if (R[i] != M[addr][i]) {
|
|
168
|
-
C = 0;
|
|
169
|
-
break;
|
|
170
|
-
}
|
|
177
|
+
if (R[i] != M[addr][i]) { C = 0; break; }
|
|
171
178
|
}
|
|
172
179
|
}
|
|
173
|
-
|
|
174
|
-
// BT (Branch if True)
|
|
175
180
|
else if (IR[0] == 'B' && IR[1] == 'T') {
|
|
176
181
|
int addr = (IR[2]-'0')*10 + (IR[3]-'0');
|
|
177
182
|
if (!(IR[2] >= '0' && IR[2] <= '9' && IR[3] >= '0' && IR[3] <= '9')) {
|
|
178
|
-
printf("Invalid operand\n");
|
|
179
|
-
break;
|
|
183
|
+
printf("Invalid operand\n"); break;
|
|
180
184
|
}
|
|
181
185
|
if (addr < 0 || addr >= 100) {
|
|
182
|
-
printf("Memory address out of bounds\n");
|
|
183
|
-
break;
|
|
186
|
+
printf("Memory address out of bounds\n"); break;
|
|
184
187
|
}
|
|
185
|
-
if (C == 1)
|
|
186
|
-
IC = addr;
|
|
188
|
+
if (C == 1) IC = addr;
|
|
187
189
|
}
|
|
188
|
-
|
|
189
|
-
// GD (Get Data)
|
|
190
190
|
else if (IR[0] == 'G' && IR[1] == 'D') {
|
|
191
|
-
SI = 1;
|
|
192
|
-
MOS();
|
|
191
|
+
SI = 1; MOS();
|
|
193
192
|
}
|
|
194
|
-
|
|
195
|
-
// PD (Put Data)
|
|
196
193
|
else if (IR[0] == 'P' && IR[1] == 'D') {
|
|
197
|
-
SI = 2;
|
|
198
|
-
MOS();
|
|
194
|
+
SI = 2; MOS();
|
|
199
195
|
}
|
|
200
|
-
|
|
201
|
-
// H (Halt)
|
|
202
196
|
else if (IR[0] == 'H') {
|
|
203
|
-
SI = 3;
|
|
204
|
-
|
|
197
|
+
SI = 3; MOS();
|
|
198
|
+
dump_memory(); // dump memory state on HALT
|
|
205
199
|
break;
|
|
206
200
|
}
|
|
207
|
-
|
|
208
201
|
else {
|
|
209
202
|
printf("Invalid instruction: %c%c%c%c\n", IR[0], IR[1], IR[2], IR[3]);
|
|
203
|
+
dump_memory(); // dump even on error so TUI can show state
|
|
210
204
|
break;
|
|
211
205
|
}
|
|
212
206
|
}
|
|
207
|
+
// Always dump if we exited via step limit
|
|
208
|
+
dump_memory();
|
|
213
209
|
}
|
|
214
210
|
|
|
215
211
|
void READ() {
|
|
216
212
|
char word[40];
|
|
217
213
|
int addr = (IR[2]-'0')*10 + (IR[3]-'0');
|
|
218
|
-
|
|
219
|
-
// Reading if Input file is not Empty
|
|
220
214
|
if (fgets(word, sizeof(word), fin) == NULL) {
|
|
221
215
|
printf("No data available for GD\n");
|
|
222
216
|
return;
|
|
223
217
|
}
|
|
224
|
-
|
|
225
218
|
int k = 0;
|
|
226
219
|
for (int i = addr; i < addr + 10 && i < 100; i++) {
|
|
227
220
|
for (int j = 0; j < 4; j++) {
|
|
@@ -235,7 +228,6 @@ void READ() {
|
|
|
235
228
|
|
|
236
229
|
void WRITE() {
|
|
237
230
|
int addr = (IR[2]-'0')*10 + (IR[3]-'0');
|
|
238
|
-
|
|
239
231
|
for (int i = addr; i < addr + 10 && i < 100; i++) {
|
|
240
232
|
for (int j = 0; j < 4; j++) {
|
|
241
233
|
fputc(M[i][j], fout);
|
|
@@ -249,33 +241,23 @@ void TERMINATE() {
|
|
|
249
241
|
}
|
|
250
242
|
|
|
251
243
|
void MOS() {
|
|
252
|
-
if (SI == 1)
|
|
253
|
-
|
|
254
|
-
else if (SI ==
|
|
255
|
-
WRITE();
|
|
256
|
-
else if (SI == 3)
|
|
257
|
-
TERMINATE();
|
|
244
|
+
if (SI == 1) READ();
|
|
245
|
+
else if (SI == 2) WRITE();
|
|
246
|
+
else if (SI == 3) TERMINATE();
|
|
258
247
|
}
|
|
259
248
|
|
|
260
249
|
int main() {
|
|
261
250
|
clock_t start, end;
|
|
262
|
-
|
|
263
251
|
start = clock();
|
|
264
252
|
|
|
265
|
-
char *infile
|
|
253
|
+
char *infile = getenv("MOS_INPUT");
|
|
266
254
|
char *outfile = getenv("MOS_OUTPUT");
|
|
267
255
|
|
|
268
|
-
fin
|
|
256
|
+
fin = fopen(infile ? infile : "input.txt", "r");
|
|
269
257
|
fout = fopen(outfile ? outfile : "output.txt", "w");
|
|
270
258
|
|
|
271
|
-
if (fin == NULL)
|
|
272
|
-
|
|
273
|
-
return 0;
|
|
274
|
-
}
|
|
275
|
-
if (fout == NULL) {
|
|
276
|
-
printf("Output file error\n");
|
|
277
|
-
return 0;
|
|
278
|
-
}
|
|
259
|
+
if (fin == NULL) { printf("Input file not found\n"); return 1; }
|
|
260
|
+
if (fout == NULL) { printf("Output file error\n"); return 1; }
|
|
279
261
|
|
|
280
262
|
LOAD();
|
|
281
263
|
|
|
@@ -287,15 +269,4 @@ int main() {
|
|
|
287
269
|
printf("Execution time: %f seconds\n", time_taken);
|
|
288
270
|
|
|
289
271
|
return 0;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
/*
|
|
294
|
-
// Validations Added
|
|
295
|
-
1. Checking if Input and Output File exists
|
|
296
|
-
2. checking Memery Overflow
|
|
297
|
-
3. Invalid Instruction
|
|
298
|
-
4. Avoid Infinite Loop if Halt Instruction is not available
|
|
299
|
-
5. Added Validation for Correct Operand
|
|
300
|
-
6. Vadidation if input file is Empty
|
|
301
|
-
*/
|
|
272
|
+
}
|