/* file: the.c * * Code for the simulated toy machine (STM), * a simulated architecture supporting variable-length partitions. * * The original STM CODE is from Professor Ernie Davis with permission. ***************************************************/ #include "the.h" /* hack -- used in trap_exec */ int min(a,b){ if (a= 0) && (reladd < limit)) return(reladd+base); else { error = 1; printf("Error: Address out of bounds\n"); return(0); } } /*************************************************** * Display STM instruction for level-2 debugging ***************************************************/ void show_inst(op, ra, ad, rb, rc, rd) int op, ra, ad, rb, rc, rd; { printf("Process %i %s instruction 0x%X : %3s", procindex, procname, regs[0], codes[op]); switch(op) { case 0: case 1: case 13: printf(" R%i Address 0x%X", ra, ad); break; case 12: printf(" Address 0x%X", ad); break; case 2: case 3: case 4: printf(" R%i R%i", ra, rb); break; case 5: case 6: case 7: case 11: printf(" R%i R%i R%i", ra, rb, rc); break; case 8: printf(" R%i R%i R%i R%i", ra, rb, rc, rd); break; case 9: case 10: case 14: printf(" R%i ", ra); break; } printf("\n"); } /*************************************************** * Decompose an STM instruction into its components ***************************************************/ void get_inst(inst, pop, pra, pad, prb, prc, prd) int inst, *pop, *pra, *pad, *prb, *prc, *prd; { *pop = inst % 16; inst = inst / 16; *pra = inst % 16; inst = inst / 16; *pad = inst % RAMSIZE; *prb = inst % 16; inst = inst / 16; *prc = inst % 16; inst = inst / 16; *prd = inst % 16; if (debug == 2) show_inst(*pop, *pra, *pad, *prb, *prc, *prd); } /*************************************************** /* Execute an STM instruction. * This is what does the actual work of carrying out the STM code ***************************************************/ int exec_inst(op, ra, ad, rb, rc, rd) int op, ra, ad, rb, rc, rd; { int regrep = 0; /* Flag for repeated registers */ int trap = 0; switch (op) { case 0: regs[ra] = mem[phys_address(ad)]; break; case 1: mem[phys_address(ad)] = regs[ra]; break; case 2: regs[ra] = regs[rb]; break; case 3: regs[ra] = mem[phys_address(regs[rb])]; break; case 4: mem[phys_address(regs[ra])] = regs[rb]; break; case 5: regs[rc] = regs[ra] + regs[rb]; break; case 6: regs[rc] = regs[ra] - regs[rb]; break; case 7: regs[rc] = regs[ra] * regs[rb]; break; case 8: if (regs[rb] == 0) { printf("Arithmetic error: Divide by zero\n"); error = 1; } else { regs[rc] = regs[ra] / regs[rb]; regs[rd] = regs[ra] % regs[rb]; } break; case 9: regs[ra]++; break; case 10: regs[ra]--; break; case 11: regs[rc] = (regs[ra] > regs[rb]); break; case 12: regs[0] = ad; break; case 13: if (regs[ra] == 0) regs[0] = ad; break; case 14: regs[0] = regs[ra]; break; case 15: trap = 1; break; } return(trap); } /*************************************************** * Execute a trap ***************************************************/ void exec_trap() { int iread, i, n; char buffer[MAXBUF]; // input buffer if (debug) printf("Process %s, index %i, ", procname, procindex); switch(regs[15]) { case 0: // TERMINATE terminate=1; if (debug) printf(" TRP 0 -- Terminate\n"); break; case 1: // READ INPUT if (regs[12] == 0){ // READ INTEGER if (debug) printf(" TRP 1 -- Read int: "); iread = scanf("%i",®s[14]); if (iread ==1) { // input is integer regs[13]=0; if (debug) printf("%d\n", regs[14]); } else { // input is non-integer regs[13]=-1; error=1; if (debug) printf("input error\n"); } } else if (regs[12]>0){ // READ STRING if (debug) printf(" TRP 1 -- Read string: "); iread = scanf("%i", &buffer); // no check for buffer overflow! if (iread ==1) { n=strlen(buffer); for (i=0; i< min(regs[12],n); i++) mem[phys_address(regs[14]+i)] = buffer[i]; mem[phys_address(regs[14]+1+min(regs[12],n))] = 0; if (debug) printf("%s\n", mem[phys_address(regs[14])]); } else { regs[13]=-2; error=1; if (debug) printf("input error\n"); } } break; case 2: // WRITE OUTPUT if (regs[12] <= 0){ // WRITE INTEGER if (debug) printf(" TRP 2 -- Write int: "); printf("%i", regs[14]); if (regs[12]==0) printf("\n"); // add newline if regs[12]=0 if (regs[12]==-1) ; // add nothing if regs[12]=-1 if (regs[12]==-2) printf(" "); // add space if regs[12]=-2 if (regs[12]==-3) printf(","); // add comma if regs[12]=-3 regs[13]=0; } else if ((regs[12]>0)&(regs[12]= limit) error=1; else { trap = exec_inst(opcode, rega, ad, regb, regc, regd); /*execute*/ if (trap) exec_trap(); /* handle trap */ } } }