ref: 7fa4a7f3243cfcd2e4c839df66c10147459fb99d
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 add_bit(bool a, bool b, bool *carry)
{
bool out, temp = carry;
out = ((a ^ b) ^ temp);
carry = (((a ^ b) & temp) | (a & b));
return out;
}
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;
/* 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);
case XOR:
r.regs[c] = a ^ b;
break;
case SUB:
b = ~b;
r.regs[CARRY] = 1;
case ADD:
r.regs[c] = add_bit(a, b, &r.flags[CARRY]);
break;
case SHR:
r.regs[c] = r.regs[a] >> b;
break;
case SHL:
r.regs[c] = r.regs[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, "unkown op\n");
return 1;
}
/* clear them */
a = 0;
b = 0;
op = 0;
string[0] = '\0';
}
return 0;
}