simpletron.c (5177B)
1 /* Exercise 7.19 */ 2 3 /* The Simpletron (and LMS) implementation */ 4 5 #include <stdio.h> 6 #include <stdlib.h> 7 8 #define MEMSIZE 100 9 10 /* Input/Output */ 11 #define READ 10 12 #define WRITE 11 13 14 /* Loading/Storing */ 15 #define LOAD 20 16 #define STORE 21 17 18 /* Arithmetical */ 19 #define ADD 30 20 #define SUBTRACT 31 21 #define DIVIDE 32 22 #define MULTIPLY 33 23 24 /* Reference and control */ 25 #define BRANCH 40 26 #define BRANCHNEG 41 27 #define BRANCHZERO 42 28 #define HALT 43 29 30 int checkword(int word, int size); 31 void dump(int acc, int icounter, int mem[]); 32 33 int main(void) 34 { 35 int memory[MEMSIZE] = { 0 }, i, err = 0; 36 37 int operationCode = 0, instructionRegister = 0; 38 int accumulator = 0, operand = 0; 39 40 printf("*** Welcome to the Simpletron! ***\n" 41 "*** Please enter your program one instruction ***\n" 42 "*** (or data word) at a time. I will type the ***\n" 43 "*** location number and a question mark (?). ***\n" 44 "*** You then type the word for that location. ***\n" 45 "*** Type the sentinel -99999 to stop entering ***\n" 46 "*** your program. ***\n"); 47 48 for(i = 0; i < MEMSIZE; i++) { 49 while(1) { 50 printf("%.2d ?? ", i); 51 scanf("%d", &memory[i]); 52 53 if(memory[i] == -99999) { 54 memory[i] = 0; 55 i = MEMSIZE; /* Terminate the for loop */ 56 break; 57 } 58 59 if( checkword(memory[i], MEMSIZE) ) { 60 printf("*** Invalid instruction: %d\n", memory[i]); 61 printf("*** Please retype it or exit.\n"); 62 } 63 else 64 break; 65 66 } /* end while */ 67 } /* end for (i) */ 68 69 printf("*** Program loading completed ***\n" 70 "*** Program execution begins ***\n"); 71 72 for(i = 0; i < MEMSIZE; i++) { 73 instructionRegister = memory[i]; 74 75 operationCode = instructionRegister / 100; 76 operand = instructionRegister % 100; 77 78 /* this is required because after the switch() 79 statement the 'i' counter is incremented of 1. */ 80 if(operationCode >= BRANCH) 81 --operand; 82 83 switch(operationCode) { 84 case READ: 85 printf("Insert a word: "); 86 scanf("%d", &memory[operand]); 87 88 break; 89 case WRITE: 90 printf("\nMemory location: %.2d\nWord: %d\nASCII: %c\n", 91 operand, memory[operand], memory[operand]); 92 break; 93 case LOAD: 94 accumulator = memory[operand]; 95 break; 96 case STORE: 97 memory[operand] = accumulator; 98 break; 99 100 case ADD: 101 accumulator += memory[operand]; 102 103 if(accumulator > +9999 || accumulator -9999) 104 err = 1; 105 106 break; 107 case SUBTRACT: 108 accumulator -= memory[operand]; 109 110 if(accumulator > +9999 || accumulator -9999) 111 err = 1; 112 113 break; 114 case DIVIDE: 115 accumulator /= memory[operand]; 116 117 if( !memory[operand] ) 118 err = 2; 119 120 break; 121 case MULTIPLY: 122 accumulator *= memory[operand]; 123 124 if(accumulator > +9999 || accumulator -9999) 125 err = 1; 126 127 break; 128 129 case BRANCH: 130 i = operand; 131 break; 132 case BRANCHNEG: 133 if(accumulator < 0) 134 i = operand; 135 136 break; 137 case BRANCHZERO: 138 if(!accumulator) 139 i = operand; 140 141 break; 142 143 case HALT: 144 printf("*** Simpletron execution terminated ***\n"); 145 dump(accumulator, i, memory); 146 return 0; 147 148 break; 149 case 0: 150 break; 151 152 default: 153 printf("*** unknown error: %d\n", instructionRegister); 154 exit(-1); 155 } 156 157 /* fatal errors check */ 158 if(err) { 159 switch(err) { 160 case 1: 161 printf("*** Out of the accumulator limit ***\n"); 162 break; 163 case 2: 164 printf("*** Attempt to divide by zero ***\n"); 165 break; 166 } 167 168 printf("*** Simpletron execution abnormally terminated ***\n"); 169 dump(accumulator, i, memory); 170 exit(-1); 171 } 172 173 174 } /* end for (i) */ 175 176 dump(accumulator, i, memory); 177 178 return 0; 179 } /* E0F main */ 180 181 /* Check if a "word" is correct */ 182 int checkword(int word, int size) 183 { 184 if(word < 0 || word > 9999 || word % 100 >= size) { 185 return 1; 186 } 187 188 switch(word / 100) { 189 case READ: 190 case WRITE: 191 case LOAD: 192 case STORE: 193 case ADD: 194 case SUBTRACT: 195 case DIVIDE: 196 case MULTIPLY: 197 case BRANCH: 198 case BRANCHNEG: 199 case BRANCHZERO: 200 case HALT: 201 case 0: 202 break; 203 default: 204 return 1; 205 206 } /* end switch (word) */ 207 208 return 0; 209 210 } /* eof checkword() */ 211 212 /* Show a dump of the current memory state */ 213 void dump(int acc, int icounter, int mem[]) 214 { 215 int i, j; 216 217 printf("\nREGISTERS:\n"); 218 printf("accumulator\t\t%c%.4d\n" 219 "instructionCounter\t%.2d\n" 220 "instructionRegister\t%c%.4d\n" 221 "operationCode\t\t%.2d\n" 222 "operand\t\t\t%.2d\n", 223 acc < 0 ? '-' : '+', acc < 0 ? -acc : acc, 224 icounter, mem[icounter] < 0 ? '-' : '+', 225 mem[icounter] < 0 ? -mem[icounter] : mem[icounter], 226 mem[icounter] / 100, mem[icounter] % 100); 227 228 229 printf("\nMEMORY:\n"); 230 231 /* Print the header */ 232 printf("%3c", ' '); 233 for(i = 0; i < 10; i++) 234 printf("%5d ", i); 235 printf("\n"); 236 237 for(i = 0; i < MEMSIZE; i += 10) { 238 printf("%.2d", i); 239 for(j = i; j < i+10; j++) { 240 printf(" %c%.4d", 241 mem[j] < 0 ? '-' : '+', mem[j] < 0 ? -mem[j] : mem[j]); 242 } 243 printf("\n"); 244 } 245 246 } /* eof dump() */ 247