Mercurial > hg-old > index.cgi
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); +}