wm: 5551

ref: 8a9c05b991899089f57ef6480d981b45e7489d57
dir: /5551e.c/

View raw version
/* 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;
}