diff src/pseudo.c @ 0:57495da01900

Initial checking of LWASM
author lost
date Fri, 03 Oct 2008 02:44:20 +0000
parents
children 34568fab6058
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pseudo.c	Fri Oct 03 02:44:20 2008 +0000
@@ -0,0 +1,569 @@
+/*
+ * pseudo.c
+ *
+ * pseudo operations
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include "lwasm.h"
+#include "instab.h"
+
+#include <stdio.h>
+
+void pseudo_org(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int v1, rval;
+	
+	if (cl -> hassym)
+	{
+		register_error(as, cl, ERR_SYM);
+		cl -> hassym = 0;
+	}
+	rval = eval_expr(as, cl, optr, &v1);
+	cl -> addr = v1;
+	cl -> addrset = 1;
+	as -> addr = v1;
+}
+
+void pseudo_include(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int v1;
+
+	if (as -> passnum != 1)
+		return;
+	while (**optr && isspace(**optr))
+		(*optr)++;
+	if (!**optr)
+	{
+		register_error(as, cl, ERR_BADFN);
+		return;
+	}
+	for (v1 = 0; *((*optr)+v1) && !isspace(*((*optr)+v1)); v1++)
+		;
+	{
+		char *fn = malloc(v1 + 1);
+		strncpy(fn, *optr, v1);
+		fn[v1] = '\0';
+		lwasm_read_file(as, fn);
+	}
+}
+
+
+void pseudo_rmb(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int rval, v1;
+	
+	rval = eval_expr(as, cl, optr, &v1);
+	if (rval < 0)
+	{
+		errorp1(ERR_FORWARD);
+		return;
+	}
+	if (v1 < 0)
+	{
+		errorp1(ERR_BADOPER);
+		return;
+	}
+	cl -> len = v1;
+	cl -> nocode = 1;
+}
+
+void pseudo_rmd(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int rval, v1;
+	
+	rval = eval_expr(as, cl, optr, &v1);
+	if (rval < 0)
+	{
+		errorp1(ERR_FORWARD);
+		return;
+	}
+	if (v1 < 0)
+	{
+		errorp1(ERR_BADOPER);
+		return;
+	}
+	cl -> len = v1 * 2;
+	cl -> nocode = 1;
+}
+
+void pseudo_rmq(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int rval, v1;
+	
+	rval = eval_expr(as, cl, optr, &v1);
+	if (rval < 0)
+	{
+		errorp1(ERR_FORWARD);
+		return;
+	}
+	if (v1 < 0)
+	{
+		errorp1(ERR_BADOPER);
+		return;
+	}
+	cl -> len = v1 * 4;
+	cl -> nocode = 1;
+}
+
+void pseudo_zmb(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int rval, v1;
+	
+	rval = eval_expr(as, cl, optr, &v1);
+	if (rval < 0)
+	{
+		errorp1(ERR_FORWARD);
+		return;
+	}
+	if (v1 < 0)
+	{
+		errorp1(ERR_BADOPER);
+		return;
+	}
+	while (v1--)
+		emit(0);
+}
+
+void pseudo_zmd(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int rval, v1;
+	
+	rval = eval_expr(as, cl, optr, &v1);
+	if (rval < 0)
+	{
+		errorp1(ERR_FORWARD);
+		return;
+	}
+	if (v1 < 0)
+	{
+		errorp1(ERR_BADOPER);
+		return;
+	}
+	while (v1--)
+	{
+		emit(0);
+		emit(0);
+	}
+}
+
+void pseudo_zmq(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int rval, v1;
+	
+	rval = eval_expr(as, cl, optr, &v1);
+	if (rval < 0)
+	{
+		errorp1(ERR_FORWARD);
+		return;
+	}
+	if (v1 < 0)
+	{
+		errorp1(ERR_BADOPER);
+		return;
+	}
+	while (v1--)
+	{
+		emit(0);
+		emit(0);
+		emit(0);
+		emit(0);
+	}
+}
+
+void pseudo_end(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int rval, v1;
+	
+	while (**optr && isspace(**optr))
+		;
+	if (**optr && **optr != '*' && **optr != ';')
+	{
+		rval = eval_expr(as, cl, optr, &v1);
+		if (rval < 0)
+		{
+			errorp1(ERR_FORWARD);
+			return;
+		}
+	}
+	else
+	{
+		v1 = 0;
+	}
+	if (as -> passnum == 2)
+		as -> execaddr = v1;
+}				
+
+void pseudo_align(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int rval, v1;
+	int cn;
+
+	rval = eval_expr(as, cl, optr, &v1);
+	if (rval < 0)
+	{
+		errorp1(ERR_FORWARD);
+		return;
+	}
+	cn = cl -> addr % v1;
+	if (cn)
+	cn = v1 - cn; 
+
+	while (cn)
+	{
+		emit(0);
+		cn--;
+	}
+}
+
+void pseudo_equ(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int rval, v1;
+	
+	if (cl -> hassym == 0)
+	{
+		errorp1(ERR_NOSYM);
+		return;
+	}
+	rval = eval_expr(as, cl, optr, &v1);
+	// eval_expr returns -1 if there was a forward ref
+	// or -2 if the expr was invalid
+	if (rval == -2)
+	{
+		// carp
+		errorp1(ERR_FORWARD);
+	}
+	if (rval < 0)
+	{
+		// remove symbol ref
+		cl -> hassym = 0;
+		// mark as a "comment" so it isn't processed next time
+		cl -> opcode = -1;
+		return;
+	}
+	cl -> code_symloc = v1;
+	cl -> isequ = 1;
+	cl -> symaddr = v1 & 0xFFFF;
+}
+
+void pseudo_set(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int rval, v1;
+	
+	if (cl -> hassym == 0)
+	{
+		errorp1(ERR_NOSYM);
+		return;
+	}
+	rval = eval_expr(as, cl, optr, &v1);
+	// eval_expr returns -1 if there was a forward ref
+	// or -2 if the expr was invalid
+	if (rval == -2)
+	{
+		// carp
+		errorp1(ERR_FORWARD);
+	}
+	if (rval < 0)
+	{
+		// remove symbol ref
+		cl -> hassym = 0;
+		// mark as a "comment" so it isn't processed next time
+		cl -> opcode = -1;
+		return;
+	}
+	cl -> code_symloc = v1;
+	cl -> isset = 1;
+	cl -> isequ = 1;
+	cl -> symaddr = v1 & 0xFFFF;
+}
+
+void pseudo_setdp(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int rval, v1;
+
+	if (cl -> hassym)
+	{
+		register_error(as, cl, ERR_SYM);
+		cl -> hassym = 0;
+		return;
+	}
+	else
+	{
+		rval = eval_expr(as, cl, optr, &v1);
+		if (rval == -1)
+		{
+			errorp1(ERR_FORWARD);
+		}
+		if (rval < 0)
+		{
+			cl -> opcode = -1;
+			return;
+		}
+	}
+	// setdp needs to resolve properly on pass 2
+	if (v1 > 0xff || v1 < 0)
+	{
+		errorp1(ERR_OVERFLOW);
+	}	
+	as -> dpval = v1 & 0xff;
+	cl -> dpval = v1 & 0xff;
+	cl -> issetdp = 1;
+	cl -> numcodebytes = 0;
+//printf("%s\n", "SETDP2");
+}
+
+void pseudo_fcc(asmstate_t *as, sourceline_t *cl, char **optr)
+{		
+	int cn = 0;
+	int delim = 0;
+				
+	delim = *(*optr)++;
+	if (!delim)
+	{
+		errorp1(ERR_BADOPER);
+	}
+	else
+	{
+		while (**optr && **optr != delim)
+		{
+			emit(**optr);
+			(*optr)++;
+			cn += 1;
+		}
+	}
+	cl -> len = cn;
+}
+		
+void pseudo_fcs(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int cn = 0;
+	int delim = 0;
+				
+	delim = *(*optr)++;
+	if (!delim)
+	{
+		errorp1(ERR_BADOPER);
+	}
+	else
+	{
+		while (**optr && **optr != delim)
+		{
+			if (!*((*optr) + 1) || *((*optr) + 1) == delim)
+				emit((**optr) | 0x80);
+			else
+				emit(**optr);
+			(*optr)++;
+			cn += 1;
+		}
+	}
+	cl -> len = cn;
+}
+
+void pseudo_fcn(asmstate_t *as, sourceline_t *cl, char **optr)
+{		
+	int cn = 0;
+	int delim = 0;
+				
+	delim = *(*optr)++;
+	if (!delim)
+	{
+		errorp1(ERR_BADOPER);
+	}
+	else
+	{
+		while (**optr && **optr != delim)
+		{
+			emit(**optr);
+			(*optr)++;
+			cn += 1;
+		}
+	}
+	emit(0);
+	cl -> len = cn + 1;
+}
+		
+void pseudo_fcb(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int rval, v1;
+	
+fcb_again:
+	rval = eval_expr(as, cl, optr, &v1);
+	if (v1 < -127 || v1 > 0xff)
+		errorp2(ERR_OVERFLOW);
+	emit(v1 & 0xff);
+	if (**optr == ',')
+	{
+		(*optr)++;
+		goto fcb_again;
+	}
+}
+
+void pseudo_fdb(asmstate_t *as, sourceline_t *cl, char **optr)
+{			
+	int rval, v1;
+	
+fdb_again:
+	rval = eval_expr(as, cl, optr, &v1);
+	emit((v1 >> 8) & 0xff);
+	emit(v1 & 0xff);
+	if (**optr == ',')
+	{
+		(*optr)++;
+		goto fdb_again;
+	}
+}
+
+void pseudo_fqb(asmstate_t *as, sourceline_t *cl, char **optr)
+{	
+	int rval, v1;
+
+fqb_again:
+	rval = eval_expr(as, cl, optr, &v1);
+	emit((v1 >> 24) & 0xff);
+	emit((v1 >> 16) & 0xff);
+	emit((v1 >> 8) & 0xff);
+	emit(v1 & 0xff);
+	if (**optr == ',')
+	{
+		(*optr)++;
+		goto fqb_again;
+	}
+}
+
+// don't need to do anything if we are executing one of these
+void pseudo_endc(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	return;
+}
+
+// if "else" executes, we must be going into an "ignore" state
+void pseudo_else(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	as -> skipcond = 1;
+	as -> skipcount = 1;
+}
+
+void pseudo_ifne(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int v1;
+	int rval;
+//	printf("ifne %s\n", *optr);
+	rval = eval_expr(as, cl, optr, &v1);
+	if (rval < 0)
+	{
+		errorp1(ERR_BADCOND);
+	}
+	else
+	{
+//	printf("Condition value: %d\n", v1);
+		if (!v1)
+		{
+//		printf("condition no match\n");
+			as -> skipcond = 1;
+			as -> skipcount = 1;
+		}
+	}
+}
+void pseudo_ifeq(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int v1;
+	int rval;
+	
+	rval = eval_expr(as, cl, optr, &v1);
+	if (rval < 0)
+	{
+		errorp1(ERR_BADCOND);
+	}
+	else
+	{
+		if (v1)
+		{
+			as -> skipcond = 1;
+			as -> skipcount = 1;
+		}
+	}
+}
+void pseudo_iflt(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int v1;
+	int rval;
+	
+	rval = eval_expr(as, cl, optr, &v1);
+	if (rval < 0)
+	{
+		errorp1(ERR_BADCOND);
+	}
+	else
+	{
+		if (v1 >= 0)
+		{
+			as -> skipcond = 1;
+			as -> skipcount = 1;
+		}
+	}
+}
+void pseudo_ifle(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int v1;
+	int rval;
+	
+	rval = eval_expr(as, cl, optr, &v1);
+	if (rval < 0)
+	{
+		errorp1(ERR_BADCOND);
+	}
+	else
+	{
+		if (v1 > 0)
+		{
+			as -> skipcond = 1;
+			as -> skipcount = 1;
+		}
+	}
+}
+void pseudo_ifgt(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int v1;
+	int rval;
+	
+	rval = eval_expr(as, cl, optr, &v1);
+	if (rval < 0)
+	{
+		errorp1(ERR_BADCOND);
+	}
+	else
+	{
+		if (v1 <= 0)
+		{
+			as -> skipcond = 1;
+			as -> skipcount = 1;
+		}
+	}
+}
+void pseudo_ifge(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	int v1;
+	int rval;
+	
+	rval = eval_expr(as, cl, optr, &v1);
+	if (rval < 0)
+	{
+		errorp1(ERR_BADCOND);
+	}
+	else
+	{
+		if (v1 < 0)
+		{
+			as -> skipcond = 1;
+			as -> skipcount = 1;
+		}
+	}
+}
+
+void pseudo_error(asmstate_t *as, sourceline_t *cl, char **optr)
+{
+	cl -> user_error = strdup(*optr);
+	errorp1(ERR_USER);
+}