#include /* short is 16-bit two's complement integer */ short int R[8], mem[256]; /* unsigned char is integer between 0 and 255 */ unsigned char pc = 0X10; /* print contents of all registers */ void dumpreg() { int i; printf("\npc: %04X\n", pc); printf("regs:\t"); for (i = 0; i < 8; i++) { printf("%04hX ", R[i]); if (i % 8 == 7) printf("\n\t"); } } /* print contents of all memory and registers */ void dump() { int i, j, t; dumpreg(); for (i = 0; i < 32; i++) { for (j = 0, t = 0; j < 8; j++) t += mem[8*i+j]; // if next 8 memory addresses if (t == 0) continue; // are all 0, don't print printf("\n%02hX: ", 8*i); for (j = 0; j < 8; j++) printf("%04hX ", mem[8*i+j]); } printf("\n\n\n"); } void main(void) { short int i, inst; int op, addr, r0, r1, r2, c; for (i = 0; i < 256; i++) // initialize memory to 0 mem[i] = 0; /* read in mem location and instruction */ /* hX in scanf refers to short integer in hexadecimal */ while (scanf("%2hX: %4hX", &i, &inst) != EOF) { mem[i] = inst; // put instruction in memory while ((c = getchar()) != EOF) // allow comments in TOY code if (c == '\n') break; // (by ignoring rest of line) } dump(); // print memory and registers do { inst = mem[pc++]; // get next instruction op = (inst >> 12) & 15; // get opcode (bits 12-15) r0 = (inst >> 8) & 7; // get r0 (bits 8-10) r1 = (inst >> 4) & 7; // get r1 (bits 4- 6) r2 = (inst >> 0) & 7; // get r2 (bits 0- 2) addr = (inst >> 0) & 255; // get addr (bits 0- 7) if ((inst >> 11) & 1) // if bit 11 is on then addr = (R[r1] + R[r2]) & 255; // do indexed addressing switch (op) { case 0: break; case 1: R[r0] = R[r1] + R[r2]; break; case 2: R[r0] = R[r1] - R[r2]; break; case 3: R[r0] = R[r1] * R[r2]; break; case 4: printf("%04X\n", R[r0]); break; case 5: pc = addr; break; case 6: if (R[r0] > 0) pc = addr; break; case 7: if (--R[r0]) pc = addr; break; case 8: R[r0] = pc; pc = addr; break; case 9: R[r0] = mem[addr]; break; case 10: mem[addr] = R[r0]; break; case 11: R[r0] = addr; break; case 12: R[r0] = R[r1] ^ R[r2]; break; case 13: R[r0] = R[r1] & R[r2]; break; case 14: R[r0] = R[r0] >> addr; break; case 15: R[r0] = R[r0] << addr; break; } } while (op != 0); dump(); }