ref: 574330802775a8417de895c924bf454807295150
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;
}
}
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(0, program[i].inst, sizeof(Word));
write(0, program[i].mode, sizeof(Word));
write(0, program[i].arg1, sizeof(Word));
write(0, program[i].arg2, sizeof(Word));
}
}
}
int main(int argc, char* argv[])
{
unsigned int inst, a, b, c;
char string[32], op[4];
while(scanf("%s %[^\n;]%*c", op, string) > 0)
{
sscanf(string, "%u %u %u", &a, &b, &c);
if(!strcmp(op, "DIE"))
inst = DIE;
if(!strcmp(op, "OUT"))
inst = OUT;
if(!strcmp(op, "NOT"))
inst = NOT;
if(!strcmp(op, "AND"))
inst = AND;
if(!strcmp(op, "NOR"))
inst = NOR;
if(!strcmp(op, "XOR"))
inst = XOR;
if(!strcmp(op, "SUB"))
inst = SUB;
if(!strcmp(op, "ADD"))
inst = ADD;
if(!strcmp(op, "SHR"))
inst = SHR;
if(!strcmp(op, "SHL"))
inst = SHL;
if(!strcmp(op, "PUT"))
inst = PUT;
if(!strcmp(op, "MOV"))
inst = MOV;
if(!strcmp(op, "LDM"))
inst = LDM;
if(!strcmp(op, "NTH"))
inst = NTH;
switch(inst)
{
/* no args */
case DIE:
printf("%u\n", inst);
break;
/* one arg */
case NOT:
case OUT:
printf("%u %u\n", inst, a);
break;
/* two args */
case PUT:
case MOV:
case LDM:
printf("%u %u %u\n", inst, a, b);
break;
/* three args */
case AND:
case NOR:
case XOR:
case SUB:
case SHL:
case SHR:
case ADD:
case NTH:
printf("%u %u %u %u\n", inst, a, b, c);
break;
/* should this ever happen? */
default:
fprintf(stderr, "unkown instr.\n");
return -1;
}
}
return 0;
}