wm: 5552

ref: 00a90ab613d802127bc3108eb160711153aafbfa
dir: /5552a.c/

View raw version
#include "port.h"
#include "5552.h"

char*
readin(char *in, int len)
{
	memset(in, 1, len);
	for(int i = 0 ; i < len || in+i ; i++)
		read(1, in+i, 1);

	return in;
}

void
asmtobin(char *in)
{
	int tmp = 0, len;
	char *buf;

	len = strlen(in);
	for(int i = 0 ; i < len && in[i] ; i++)
	{
		if(in[i] == '\t')
			continue;
		else if(in[i] == '\n' || in[i] == '\0')
		{
			buf[tmp++] = '\0';
			tmp = 0;
			tobin(buf);
		}
		buf[tmp++] = in[i];
	}
}

void
tobin(char *line)
{
	int *inst, *arg1, *arg2;

	match(line, inst, arg1, arg2);
}

int
matchinst(char *s)
{
	int inst = -1;

	if(!strcmp(s, "DRD"))
		inst = DRD;
	if(!strcmp(s, "DWR"))
		inst = DWR;

	if(!strcmp(s, "NOT"))
		inst = NOT;
	if(!strcmp(s, "AND"))
		inst = AND;
	if(!strcmp(s, "NOR"))
		inst = NOR;
	if(!strcmp(s, "XOR"))
		inst = XOR;

	if(!strcmp(s, "ADD"))
		inst = ADD;
	if(!strcmp(s, "SUB"))
		inst = SUB;

	if(!strcmp(s, "INC"))
		inst = INC;
	if(!strcmp(s, "DEC"))
		inst = DEC;

	if(!strcmp(s, "MUL"))
		inst = MUL;
	if(!strcmp(s, "DIV"))
		inst = DIV;

	if(!strcmp(s, "SHR"))
		inst = SHR;
	if(!strcmp(s, "SHL"))
		inst = SHL;

	if(!strcmp(s, "JMP"))
		inst = JMP;

	if(inst == -1)
		sysfatal("No instruction found for %s", s);

	return inst;
}

void
addlabel(char *name)
{
	for(int i = 0 ; i < lc ; i++)
	{
		if(!strcmp(labels[i].name, name))
			sysfatal("duplicate label %s\t
			"prev pc: %x\t"
			"curr pc: %x", name, labels[i].pc, pc);
	}
	
	labels[lc].name = name;
	labels[lc].pc = pc;

	lc++;
}

void
matchline(char *line)
{
	int len, spaces[2], scount = 0;

	len = strlen(line);
	for(int i = 0 ; i < len ; i++)
	{
		if(line[i] == ' ')
		{
			if(scount < 2)
				spaces[scount++] = i;
			else
			{
				fprint(2, "Too many spaces in the line:\n"
				"\t%s\n\t", line);
				for(int j = 0 ; j < i ; j++)
					fprint(2, " ");

				fprint(2, "^\n");
				sysfatal("Too many spaces.");
			}
			
		}
		else if(line[i] == ':' && line[i+1] == '\n' && scount == 0)
		{
			addlabel(line);
			return;
		}
	}

	for(int i = 0 ; i < scount ; i++)
		line[spaces[i]] = '\0';

	program[pc].inst = matchinst(line);
	if(scount == 1)
		program[pc].arg1 = atoi(line+spaces[0]);
	else if(scount == 2)
		program[pc].arg2 = atoi(line+spaces[1]);
	pc++
}

void
lint(void)
{
	int res, totalres[2] = {0, 0};

	for(int i = 0 ; i < pc ; i++)
	{
		res = lintop(program[i]);
		if(res & WARN)
			totalres[WARN]++;
		if(res & ERR)
			totalres[ERR]++;
	}
	if(totalres[WARN] || totalres[ERR])
		fprint(2, "%d warnnings and %d errors detected\n",
		totalres[WARN], totalres[ERR]);
}

int
lintop(int linenumber)
{
	Op op = program[linenumber];
	for(int i ; i < sizeof(instructions) / sizeof(Inst) ; i++)
	{
		if(op.inst == instructions[i].inst)
			return instructions[i].lint(op.mode, op.arg1, op.arg2);
	}
}

void
asm(int flags)
{
	asm2bin(input);
	if(flags & SFLAG)
	{
		for(int i = 0 ; i < pc ; i++)
		{
			write(outfd, program[i].inst, sizeof(Word));
			write(outfd, program[i].mode, sizeof(Word));
			write(outfd, program[i].arg1, sizeof(Word));
			write(outfd, program[i].arg2, sizeof(Word));
		}
	}
}