mos-tui 1.0.1 → 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 +72 -97
- package/core/mos.sh +16 -17
- package/core/mos_tui.py +887 -466
- package/output.txt +0 -0
- package/package.json +1 -1
package/core/OS_CP.c
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#include<stdio.h>
|
|
2
2
|
#include <stdbool.h>
|
|
3
3
|
#include<time.h>
|
|
4
|
+
#include <stdlib.h>
|
|
4
5
|
|
|
5
6
|
// Declaring the required Memory and Registers
|
|
6
7
|
char M[100][4]; // main storage of size 100 x 4
|
|
@@ -8,7 +9,7 @@ char IR[4]; // IR (Instruction register) of size 4
|
|
|
8
9
|
char R[4]; // R (General Purpose register) of size 4
|
|
9
10
|
int IC; // Instruction Counter
|
|
10
11
|
int C; // Toggle Register
|
|
11
|
-
int SI; // Supervisor
|
|
12
|
+
int SI; // Supervisor Interrupt
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
FILE *fin, *fout;
|
|
@@ -35,7 +36,6 @@ int lenString(char s[]) {
|
|
|
35
36
|
while (s[ans] != '\0') {
|
|
36
37
|
ans++;
|
|
37
38
|
}
|
|
38
|
-
|
|
39
39
|
return ans;
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -55,14 +55,49 @@ void init() {
|
|
|
55
55
|
SI = 0;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
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
|
+
}
|
|
60
95
|
|
|
61
|
-
|
|
96
|
+
void LOAD() {
|
|
97
|
+
int m = 0;
|
|
98
|
+
char word[100];
|
|
62
99
|
|
|
63
100
|
while (fgets(word, sizeof(word), fin)) {
|
|
64
|
-
// printf("%s", word);
|
|
65
|
-
|
|
66
101
|
if (cmpString(word, "$AMJ", 4)) {
|
|
67
102
|
printf("%s", "AMJ (initializing the String)\n");
|
|
68
103
|
init();
|
|
@@ -72,17 +107,13 @@ void LOAD() {
|
|
|
72
107
|
printf("%s", "DTA (Starting Execution)\n");
|
|
73
108
|
START_EXECUTION();
|
|
74
109
|
}
|
|
75
|
-
|
|
76
110
|
else if (cmpString(word, "$END", 4)) {
|
|
77
111
|
printf("%s", "END (Instruction Completed)\n");
|
|
78
112
|
continue;
|
|
79
113
|
}
|
|
80
114
|
else {
|
|
81
115
|
int k = 0;
|
|
82
|
-
while (k < lenString(word) && word[k] != '\n')
|
|
83
|
-
{
|
|
84
|
-
|
|
85
|
-
// Validation for memory overflow
|
|
116
|
+
while (k < lenString(word) && word[k] != '\n') {
|
|
86
117
|
if (m >= 100) {
|
|
87
118
|
printf("Memory overflow\n");
|
|
88
119
|
return;
|
|
@@ -96,7 +127,6 @@ void LOAD() {
|
|
|
96
127
|
}
|
|
97
128
|
}
|
|
98
129
|
|
|
99
|
-
// START EXECUTION
|
|
100
130
|
void START_EXECUTION() {
|
|
101
131
|
IC = 0;
|
|
102
132
|
EXECUTE_USER_PROGRAM();
|
|
@@ -104,123 +134,87 @@ void START_EXECUTION() {
|
|
|
104
134
|
|
|
105
135
|
void EXECUTE_USER_PROGRAM() {
|
|
106
136
|
int step = 0;
|
|
107
|
-
while (true)
|
|
108
|
-
{
|
|
109
|
-
// To avoid Infinite loop
|
|
137
|
+
while (true) {
|
|
110
138
|
if (step++ > 1000) {
|
|
111
139
|
printf("Infinite loop detected\n");
|
|
112
140
|
break;
|
|
113
141
|
}
|
|
114
|
-
// Fetch the Instruction
|
|
115
142
|
for (int i = 0; i < 4; i++) {
|
|
116
143
|
IR[i] = M[IC][i];
|
|
117
144
|
}
|
|
118
|
-
|
|
119
145
|
IC++;
|
|
120
|
-
|
|
121
|
-
// Decode and Execute the Instructions
|
|
122
|
-
|
|
123
146
|
|
|
124
|
-
|
|
125
|
-
// LR Instruction (Load Register)
|
|
126
147
|
if (IR[0] == 'L' && IR[1] == 'R') {
|
|
127
148
|
int addr = (IR[2]-'0')*10 + (IR[3]-'0');
|
|
128
149
|
if (!(IR[2] >= '0' && IR[2] <= '9' && IR[3] >= '0' && IR[3] <= '9')) {
|
|
129
|
-
printf("Invalid operand\n");
|
|
130
|
-
break;
|
|
150
|
+
printf("Invalid operand\n"); break;
|
|
131
151
|
}
|
|
132
152
|
if (addr < 0 || addr >= 100) {
|
|
133
|
-
printf("Memory address out of bounds\n");
|
|
134
|
-
break;
|
|
153
|
+
printf("Memory address out of bounds\n"); break;
|
|
135
154
|
}
|
|
136
155
|
for (int i = 0; i < 4; i++) R[i] = M[addr][i];
|
|
137
156
|
}
|
|
138
|
-
|
|
139
|
-
// SR (Store Register)
|
|
140
157
|
else if (IR[0] == 'S' && IR[1] == 'R') {
|
|
141
158
|
int addr = (IR[2]-'0')*10 + (IR[3]-'0');
|
|
142
159
|
if (!(IR[2] >= '0' && IR[2] <= '9' && IR[3] >= '0' && IR[3] <= '9')) {
|
|
143
|
-
printf("Invalid operand\n");
|
|
144
|
-
break;
|
|
160
|
+
printf("Invalid operand\n"); break;
|
|
145
161
|
}
|
|
146
162
|
if (addr < 0 || addr >= 100) {
|
|
147
|
-
printf("Memory address out of bounds\n");
|
|
148
|
-
break;
|
|
163
|
+
printf("Memory address out of bounds\n"); break;
|
|
149
164
|
}
|
|
150
165
|
for (int i = 0; i < 4; i++) M[addr][i] = R[i];
|
|
151
166
|
}
|
|
152
|
-
|
|
153
|
-
// CR (Compare Register)
|
|
154
167
|
else if (IR[0] == 'C' && IR[1] == 'R') {
|
|
155
168
|
int addr = (IR[2]-'0')*10 + (IR[3]-'0');
|
|
156
169
|
if (!(IR[2] >= '0' && IR[2] <= '9' && IR[3] >= '0' && IR[3] <= '9')) {
|
|
157
|
-
printf("Invalid operand\n");
|
|
158
|
-
break;
|
|
170
|
+
printf("Invalid operand\n"); break;
|
|
159
171
|
}
|
|
160
172
|
if (addr < 0 || addr >= 100) {
|
|
161
|
-
printf("Memory address out of bounds\n");
|
|
162
|
-
break;
|
|
173
|
+
printf("Memory address out of bounds\n"); break;
|
|
163
174
|
}
|
|
164
175
|
C = 1;
|
|
165
176
|
for (int i = 0; i < 4; i++) {
|
|
166
|
-
if (R[i] != M[addr][i]) {
|
|
167
|
-
C = 0;
|
|
168
|
-
break;
|
|
169
|
-
}
|
|
177
|
+
if (R[i] != M[addr][i]) { C = 0; break; }
|
|
170
178
|
}
|
|
171
179
|
}
|
|
172
|
-
|
|
173
|
-
// BT (Branch if True)
|
|
174
180
|
else if (IR[0] == 'B' && IR[1] == 'T') {
|
|
175
181
|
int addr = (IR[2]-'0')*10 + (IR[3]-'0');
|
|
176
182
|
if (!(IR[2] >= '0' && IR[2] <= '9' && IR[3] >= '0' && IR[3] <= '9')) {
|
|
177
|
-
printf("Invalid operand\n");
|
|
178
|
-
break;
|
|
183
|
+
printf("Invalid operand\n"); break;
|
|
179
184
|
}
|
|
180
185
|
if (addr < 0 || addr >= 100) {
|
|
181
|
-
printf("Memory address out of bounds\n");
|
|
182
|
-
break;
|
|
186
|
+
printf("Memory address out of bounds\n"); break;
|
|
183
187
|
}
|
|
184
|
-
if (C == 1)
|
|
185
|
-
IC = addr;
|
|
188
|
+
if (C == 1) IC = addr;
|
|
186
189
|
}
|
|
187
|
-
|
|
188
|
-
// GD (Get Data)
|
|
189
190
|
else if (IR[0] == 'G' && IR[1] == 'D') {
|
|
190
|
-
SI = 1;
|
|
191
|
-
MOS();
|
|
191
|
+
SI = 1; MOS();
|
|
192
192
|
}
|
|
193
|
-
|
|
194
|
-
// PD (Put Data)
|
|
195
193
|
else if (IR[0] == 'P' && IR[1] == 'D') {
|
|
196
|
-
SI = 2;
|
|
197
|
-
MOS();
|
|
194
|
+
SI = 2; MOS();
|
|
198
195
|
}
|
|
199
|
-
|
|
200
|
-
// H (Halt)
|
|
201
196
|
else if (IR[0] == 'H') {
|
|
202
|
-
SI = 3;
|
|
203
|
-
|
|
197
|
+
SI = 3; MOS();
|
|
198
|
+
dump_memory(); // dump memory state on HALT
|
|
204
199
|
break;
|
|
205
200
|
}
|
|
206
|
-
|
|
207
201
|
else {
|
|
208
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
|
|
209
204
|
break;
|
|
210
205
|
}
|
|
211
206
|
}
|
|
207
|
+
// Always dump if we exited via step limit
|
|
208
|
+
dump_memory();
|
|
212
209
|
}
|
|
213
210
|
|
|
214
211
|
void READ() {
|
|
215
212
|
char word[40];
|
|
216
213
|
int addr = (IR[2]-'0')*10 + (IR[3]-'0');
|
|
217
|
-
|
|
218
|
-
// Reading if Input file is not Empty
|
|
219
214
|
if (fgets(word, sizeof(word), fin) == NULL) {
|
|
220
215
|
printf("No data available for GD\n");
|
|
221
216
|
return;
|
|
222
217
|
}
|
|
223
|
-
|
|
224
218
|
int k = 0;
|
|
225
219
|
for (int i = addr; i < addr + 10 && i < 100; i++) {
|
|
226
220
|
for (int j = 0; j < 4; j++) {
|
|
@@ -234,7 +228,6 @@ void READ() {
|
|
|
234
228
|
|
|
235
229
|
void WRITE() {
|
|
236
230
|
int addr = (IR[2]-'0')*10 + (IR[3]-'0');
|
|
237
|
-
|
|
238
231
|
for (int i = addr; i < addr + 10 && i < 100; i++) {
|
|
239
232
|
for (int j = 0; j < 4; j++) {
|
|
240
233
|
fputc(M[i][j], fout);
|
|
@@ -248,30 +241,23 @@ void TERMINATE() {
|
|
|
248
241
|
}
|
|
249
242
|
|
|
250
243
|
void MOS() {
|
|
251
|
-
if (SI == 1)
|
|
252
|
-
|
|
253
|
-
else if (SI ==
|
|
254
|
-
WRITE();
|
|
255
|
-
else if (SI == 3)
|
|
256
|
-
TERMINATE();
|
|
244
|
+
if (SI == 1) READ();
|
|
245
|
+
else if (SI == 2) WRITE();
|
|
246
|
+
else if (SI == 3) TERMINATE();
|
|
257
247
|
}
|
|
258
248
|
|
|
259
249
|
int main() {
|
|
260
250
|
clock_t start, end;
|
|
261
|
-
|
|
262
251
|
start = clock();
|
|
263
252
|
|
|
264
|
-
|
|
265
|
-
|
|
253
|
+
char *infile = getenv("MOS_INPUT");
|
|
254
|
+
char *outfile = getenv("MOS_OUTPUT");
|
|
266
255
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
271
|
-
if (fout == NULL) {
|
|
272
|
-
printf("Output file error\n");
|
|
273
|
-
return 0;
|
|
274
|
-
}
|
|
256
|
+
fin = fopen(infile ? infile : "input.txt", "r");
|
|
257
|
+
fout = fopen(outfile ? outfile : "output.txt", "w");
|
|
258
|
+
|
|
259
|
+
if (fin == NULL) { printf("Input file not found\n"); return 1; }
|
|
260
|
+
if (fout == NULL) { printf("Output file error\n"); return 1; }
|
|
275
261
|
|
|
276
262
|
LOAD();
|
|
277
263
|
|
|
@@ -283,15 +269,4 @@ int main() {
|
|
|
283
269
|
printf("Execution time: %f seconds\n", time_taken);
|
|
284
270
|
|
|
285
271
|
return 0;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
/*
|
|
290
|
-
// Validations Added
|
|
291
|
-
1. Checking if Input and Output File exists
|
|
292
|
-
2. checking Memery Overflow
|
|
293
|
-
3. Invalid Instruction
|
|
294
|
-
4. Avoid Infinite Loop if Halt Instruction is not available
|
|
295
|
-
5. Added Validation for Correct Operand
|
|
296
|
-
6. Vadidation if input file is Empty
|
|
297
|
-
*/
|
|
272
|
+
}
|
package/core/mos.sh
CHANGED
|
@@ -1,44 +1,43 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
+
# ─────────────────────────────────────────────────────────────
|
|
3
|
+
# MOS Terminal UI Launcher
|
|
4
|
+
# Usage: ./mos.sh
|
|
5
|
+
# Run from the same directory as OS_CP.c
|
|
6
|
+
# ─────────────────────────────────────────────────────────────
|
|
2
7
|
set -e
|
|
3
8
|
|
|
4
9
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
10
|
TUI="$SCRIPT_DIR/mos_tui.py"
|
|
6
|
-
|
|
11
|
+
PROJECT_DIR="$(pwd)" # where the user IS standing — must have OS_CP.c
|
|
7
12
|
|
|
8
13
|
# Check Python 3
|
|
9
14
|
if ! command -v python3 &>/dev/null; then
|
|
10
|
-
echo "python3 not found. Install
|
|
15
|
+
echo "python3 not found. Install: sudo apt install python3"
|
|
11
16
|
exit 1
|
|
12
17
|
fi
|
|
13
18
|
|
|
14
19
|
# Check gcc
|
|
15
20
|
if ! command -v gcc &>/dev/null; then
|
|
16
|
-
echo "gcc not found. Install
|
|
21
|
+
echo "gcc not found. Install: sudo apt install gcc"
|
|
17
22
|
exit 1
|
|
18
23
|
fi
|
|
19
24
|
|
|
20
|
-
#
|
|
21
|
-
if [ -f "OS_CP.c" ]; then
|
|
22
|
-
|
|
23
|
-
echo "
|
|
24
|
-
else
|
|
25
|
-
OS_FILE="$DEFAULT_OS"
|
|
26
|
-
echo "📦 Using bundled OS_CP.c"
|
|
25
|
+
# Warn if OS_CP.c is missing
|
|
26
|
+
if [ ! -f "$PROJECT_DIR/OS_CP.c" ]; then
|
|
27
|
+
echo "WARNING: OS_CP.c not found in: $PROJECT_DIR"
|
|
28
|
+
echo " cd into the folder that contains OS_CP.c, then run mos.sh again."
|
|
27
29
|
fi
|
|
28
30
|
|
|
29
|
-
# Export so Python can use it
|
|
30
|
-
export MOS_OS_FILE="$OS_FILE"
|
|
31
|
-
|
|
32
|
-
# Ensure the TUI script exists
|
|
33
31
|
if [ ! -f "$TUI" ]; then
|
|
34
32
|
echo "mos_tui.py not found at: $TUI"
|
|
35
33
|
exit 1
|
|
36
34
|
fi
|
|
37
35
|
|
|
38
|
-
# Terminal setup
|
|
39
36
|
export TERM="${TERM:-xterm-256color}"
|
|
40
37
|
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
# cd into the project dir so Python's os.getcwd() == where OS_CP.c is
|
|
39
|
+
cd "$PROJECT_DIR"
|
|
43
40
|
|
|
41
|
+
echo "Starting MOS Terminal UI..."
|
|
42
|
+
sleep 0.2
|
|
44
43
|
python3 "$TUI"
|