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;
}