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