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 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 Interept
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
- void LOAD() {
59
- int m = 0; // It Points location at which instructions are stored
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
- char word[100]; // Stores each instruction which is to be executed
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
- MOS();
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
- READ();
253
- else if (SI == 2)
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
- fin = fopen("input.txt", "r");
265
- fout = fopen("output.txt", "w");
253
+ char *infile = getenv("MOS_INPUT");
254
+ char *outfile = getenv("MOS_OUTPUT");
266
255
 
267
- if (fin == NULL) {
268
- printf("Input file not found\n");
269
- return 0;
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
- DEFAULT_OS="$SCRIPT_DIR/OS_CP.c"
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 it with: sudo apt install python3"
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 it with: sudo apt install gcc"
21
+ echo "gcc not found. Install: sudo apt install gcc"
17
22
  exit 1
18
23
  fi
19
24
 
20
- # Decide which OS_CP.c to use
21
- if [ -f "OS_CP.c" ]; then
22
- OS_FILE="$(pwd)/OS_CP.c"
23
- echo "📄 Using OS_CP.c from current directory"
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
- echo "🚀 Starting MOS Terminal UI..."
42
- sleep 0.3
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"