~grimmware/lc3

16ebec4996c10de807c1ffcf68b1da532a13f2d0 — glenda 1 year, 2 months ago f317250
Parser appears to be complete, label mappings work!
2 files changed, 74 insertions(+), 14 deletions(-)

M asm.c
M tests/test.asm
M asm.c => asm.c +68 -14
@@ 24,9 24,13 @@ struct Symbol {
};

Symbol symtab[MAXSYMBOL];

// FIXME: Make these dynamic;
Inst *mem[MEMORY];
Inst *unmapped[MEMORY];

int debug = 0;
int unmappedcount = 0;
int symcount = 0;
int memc = 0;
int lineno = 1;


@@ 218,7 222,11 @@ validate(Inst *in)
		case OP_LEA:
		case OP_ST:
		case OP_STI:
			in->p_arg[1] = hexnparse(9, in->arg[1]);
			if(in->arg[1][0] == 'x'){
				in->p_arg[1] = hexnparse(9, in->arg[1]);
			} else {
				unmapped[unmappedcount++] = in;
			}
			break;
		}
	}


@@ 226,14 234,23 @@ validate(Inst *in)
	if(arity >= 1){
		switch(in->op){
		case OP_BR:
			in->p_arg[0] = hexnparse(9, in->arg[0]);
			if(in->arg[0][0] == 'x'){
				in->p_arg[0] = hexnparse(9, in->arg[0]);
			} else {
				unmapped[unmappedcount++] = in;
			}
			break;
		case OP_JSR:
			// FIXME Make sure mode is set by the parser!
			if(in->mode)
				in->p_arg[0] = hexnparse(11, in->arg[0]);
			else
			if(in->mode){ // JSR
				if(in->arg[0][0] == 'x'){
					in->p_arg[0] = hexnparse(11, in->arg[0]);
				} else {
					unmapped[unmappedcount++] = in;
				}
			} else { // JSRR
				goto Reg;
			}
			break;
		case OP_TRAP:
			in->p_arg[0] = hexnparse(8, in->arg[0]);


@@ 257,7 274,6 @@ parseline(char *l)
	int pos = 0;
	int c = 0;
	char *t = nil;
	int op = -1;
	Inst *inst;
	while(l[0] && pos < MAXARGS){
		if(l[0] == ';' || l[0] == '\n') return 0; // a comment


@@ 289,29 305,46 @@ parseline(char *l)
				// FIXME: replace with hexenparse
				// re-use c
				c = (int) strtol(t, 0, 16);
				pc = origin = c;
				pc = orig = c;
				if(pc != c) { // not a valid u16int
					fprint(2, ".ORIG argument too large\n");
					exits("Orig too big");
				}
				if(debug)
					print("updated origin to %x\n", origin);
					print("updated origin to %x\n", orig);
				return 0;
			} else if(strcmp(t,"NOP") == 0) {
				op = OP_BR;
				inst = newinst(op);
				inst = newinst(OP_BR);
				inst->arg[0] = "x0";
				inst->argc++;
				goto validate;
				return 1;
			} else if(strcmp(t,"RET") == 0) {
				op = OP_JMP;
				inst = newinst(op);
				inst = newinst(OP_JMP);
				inst->arg[0] = "R7";
				inst->argc++;
				goto validate;
			} else if(strcmp(t, "JSR") == 0) {
				inst = newinst(OP_JSR);
				inst->mode++;
				pos++;
			} else if(strcmp(t, "JSRR") == 0) {
				inst = newinst(OP_JSR);
				pos++;
			} else if(strcmp(t, "BRn") == 0) {
				inst = newinst(OP_BR);
				inst->mode = FL_NEG;
				pos++;
			} else if(strcmp(t, "BRz") == 0) {
				inst = newinst(OP_BR);
				inst->mode = FL_ZRO;
				pos++;
			} else if(strcmp(t, "BRp") == 0) {
				inst = newinst(OP_BR);
				inst->mode = FL_POS;
				pos++;
			} else {
				op = matchopcode(t);
				int op = matchopcode(t);
				pos++;
				if(op == -1)
					syntaxerr(smprint("Invalid instruction `%s`", t));


@@ 326,7 359,7 @@ parseline(char *l)
			validate(inst);
			pc++;
			if(debug){
				print("%d:OPCODE:%s", lineno, opcode[op]);
				print("%d:OPCODE:%s", lineno, opcode[inst->op]);
				for(int i = 0; i<inst->argc; i++)
					print("\tARG:%s", inst->arg[i]);
				print("\n");


@@ 349,6 382,24 @@ parse(FILE *fh)
}

void
maplabels(void)
{
	for(int i = 0; i<unmappedcount; i++){
		int last = unmapped[i]->argc - 1;
		int found = 0;
		for(int j = 0; j<symcount; j++){
			if(!strcmp(symtab[j].label, unmapped[i]->arg[last])){
				unmapped[i]->p_arg[last] = symtab[j].addr;
				found++;
				break;
			}
		}
		if(!found)
			syntaxerr(smprint("Label %s does not exist!", unmapped[i]->arg[last]));
	}
}

void
main(int argc, char* argv[])
{
	FILE *in, *out;


@@ 374,6 425,9 @@ main(int argc, char* argv[])
				symtab[i].addr
			);
		}
	}
	maplabels();
	if(debug){
		for(int i = 0; i < memc; i++){
			print("%04x: %x %d", orig + i, mem[i]->op, mem[i]->mode); 
			for(int j = 0; j<mem[i]->argc; j++)

M tests/test.asm => tests/test.asm +6 -0
@@ 8,7 8,13 @@ JUNK	NOP
	ADD	R0,R0,R0
	AND	R0,R0,R0
	BR	x0000
	JSR	JUNK
	BRz	MAIN
	BRp	MAIN
	BRn	MAIN
GARB	RET
	.END
	ADD	R0,R0.x111111
	RTI	stuff	;syntax error
	JSR	NOPE