ref: cff6c35a865e4563695928b12ea9f38c7b3099f4
dir: /5551e.c/
/* 5551 cpu emulator */ #include <stdbool.h> #include <stdio.h> #include "5551.h" typedef struct { bool flags[8]; int regs[8]; }reg_t; bool carry = false; bool add_bit(bool a, bool b) { bool out; out = ((a ^ b) ^ carry); carry = (((a ^ b) & carry) | (a & b)); return out; } int btoi(bool b[], int len) { char arr[10]; int res = 0, i = 0, j = len; while (i <= len) { arr[i] = b[j] ? '1' : '0'; i++; j--; } sscanf(arr, "%d", &res); return res; } int main() { reg_t r; unsigned int memory[MMAX]; memory[MMAX-1] = -1; char string[16]; r.flags[ON] = 1; r.flags[NSIGN] = 0; unsigned int op, a, b, c, ind = 0; bool barr[10]; /* there is no space between op and args since some can have no args */ while(r.flags[ON] && scanf("%u %[^\n]", &op, string)) { sscanf(string, "%u %u %u", &a, &b, &c); switch(op) { case DIE: r.flags[ON] = 0; break; case OUT: /* just in case output is "manfi" */ if(r.flags[NSIGN]) printf("-%u\n", r.regs[a]); else printf("%u\n", r.regs[a]); break; case NOT: r.regs[b] = !a; break; case AND: r.regs[c] = a & b; break; case NOR: r.regs[c] = !(a | b); break; case XOR: r.regs[c] = a ^ b; break; case SUB: b = ~b; carry = 1; case ADD: while (a > 0 && b > 0) { int diga = a % 10; int digb = b % 10; barr[ind] = add_bit(diga, digb); a /= 10; b /= 10; ind++; } barr[ind] = carry; r.regs[c] = btoi(barr,ind); break; break; case SHR: r.regs[c] = a >> b; break; case SHL: r.regs[c] = a << b; break; case PUT: memory[b] = a; case MOV: memory[b] = r.regs[a]; break; case LDM: r.regs[b] = memory[a]; break; case NTH: r.regs[c] = a >> b; break; default: fprintf(stderr, "unknown op\n"); return 1; } /* clear them */ a = 0; b = 0; op = 0; string[0] = '\0'; ind = 0; carry = 0; } return 0; }