training

Code I wrote during training
git clone git://git.bitsmanent.org/training
Log | Files | Refs | README

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