ref: 3128b86e38f6375c886cae173dc9deff3e4c0d3f
dir: /5552a.c/
#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;
}
else if(line[i] == ';')
break;
}
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));
}
}
}