# HG changeset patch # User lost # Date 1224651076 0 # Node ID 05d4115b48604b1a591e5e1d7e42ed57f76343f8 # Parent 287a6905a63c9d22f482e894d10921ef070778bf Started work on new expression evaluator system and major code re-work for next release diff -r 287a6905a63c -r 05d4115b4860 src/Makefile.am --- a/src/Makefile.am Sat Oct 04 03:20:36 2008 +0000 +++ b/src/Makefile.am Wed Oct 22 04:51:16 2008 +0000 @@ -1,3 +1,3 @@ bin_PROGRAMS = lwasm -lwasm_SOURCES = index.c instab.c macro.c pragma.c insn_gen.c list.c main.c pseudo.c insn_misc.c lwasm.c output.c symtab.c -EXTRA_DIST = instab.h lwasm.h +lwasm_SOURCES = main.c expr.c pass1.c pass2.c +EXTRA_DIST = instab.h lwasm.h expr.h diff -r 287a6905a63c -r 05d4115b4860 src/expr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/expr.c Wed Oct 22 04:51:16 2008 +0000 @@ -0,0 +1,25 @@ +/* +expr.c +Copyright © 2008 William Astle + +This file is part of LWASM. + +LWASM is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +/* +This file contains implementations associated with the expression evaluator +used by LWASM. + +*/ diff -r 287a6905a63c -r 05d4115b4860 src/expr.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/expr.h Wed Oct 22 04:51:16 2008 +0000 @@ -0,0 +1,75 @@ +/* +expr.h +Copyright © 2008 William Astle + +This file is part of LWASM. + +LWASM is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +/* +This file contains definitions associated with the expression evaluator used +by LWASM. + +The core of the entire expression handler is the opaque type LWVAL, pointers +to which are passed around to keep track of values. A value may be a simple +integer or it could be a more complex expression linked by operators or it +could be a polynomial expression. Simple integers are merely a degenerate +case of polynomials. + +The package understands the following operations: + +addition +subtraction +multiplication +division +modulus +parentheses +unary negation +unary "positive" +bitwise and +bitwise or +bitwise not (1's complement) +bitwise exclusive or + +Infix operators can be expressed as LWVAL LWVAL. Thus, the order of +operations is only relevant when initially parsing the expression. The order +of evaluation is determined by what appears on either side of the as +an LWVAL may be an expression. +*/ + +typedef union lwval LWVAL; + +struct lwval_int +{ + int lwval_type; // type of value + int lwval_int_value; // integer value +}; + +union lwval +{ + struct lwval_int lwval_type_int; // integer type +}; + +enum lwval_types +{ + LWVAL_TYPE_INT +}; + +#ifndef __expr_h_seen__ +#define __expr_h_seen__ + + + +#endif //__expr_h_seen__ diff -r 287a6905a63c -r 05d4115b4860 src/instab.h --- a/src/instab.h Sat Oct 04 03:20:36 2008 +0000 +++ b/src/instab.h Wed Oct 22 04:51:16 2008 +0000 @@ -21,53 +21,12 @@ Contains definitions for the instruction table */ -#include "lwasm.h" - -#ifndef __instab_h_seen__ -#define __instab_h_seen__ - -#define INSTYPE_INH 0 /* inherent addressing */ -#define INSTYPE_GEN 1 /* general addressing modes */ -#define INSTYPE_GEN8 2 /* general addressing, 8 bit immed */ -#define INSTYPE_GENNOIMM 3 /* no immediate addressing */ -#define INSTYPE_RTOR 4 /* register to register */ -#define INSTYPE_RLIST 5 /* register list */ -#define INSTYPE_REL8 6 /* relative addressing */ -#define INSTYPE_REL16 7 /* 16 bit relative addressing */ -#define INSTYPE_INDEX 8 /* indexed mode only */ -#define INSTYPE_IMM8 9 /* immediate only 8 bit (andcc, cwai) */ -#define INSTYPE_LOGICMEM 10 /* aim/oim/eim/tim */ -#define INSTYPE_BITBIT 11 /* bit to bit ops */ -#define INSTYPE_TFM 12 /* TFM ops */ -#define INSTYPE_GEN32 13 /* general addressing, 32 bit immed */ -#define INSTYPE_PSEUDO 14 /* special handling, pseudo op */ - -#define SPECIAL_EQU 1 /* equ */ -#define SPECIAL_ORG 2 /* org */ -#define SPECIAL_SETDP 3 -#define SPECIAL_FCB 4 -#define SPECIAL_FDB 5 -#define SPECIAL_FQB 6 -#define SPECIAL_FCC 7 -#define SPECIAL_FCS 8 -#define SPECIAL_FCN 9 -#define SPECIAL_RMB 10 -#define SPECIAL_ALIGN 11 -#define SPECIAL_END 12 -#define SPECIAL_INCLUDE 13 -#define SPECIAL_ENDM 14 -#define SPECIAL_ENDC 15 -#define SPECIAL_MACRO 16 -#define SPECIAL_COND 17 -#define SPECIAL_ELSE 18 - typedef struct { char *opcode; /* the mneumonic */ int ops[4]; /* opcode values for up to four addr modes */ - int instype; /* type of instruction (see above) */ - int specialnum; /* type of special instruction */ - void (*opfn)(asmstate_t *as, sourceline_t *cl, char **optr); + void (*p1fn)(asmstate_t *as, sourceline_t *cl, char **optr); + void (*p2fn)(asmstate_t *as, sourceline_t *cl, char **optr); } instab_t; #ifndef __instab_c_seen__ diff -r 287a6905a63c -r 05d4115b4860 src/lwasm.c --- a/src/lwasm.c Sat Oct 04 03:20:36 2008 +0000 +++ b/src/lwasm.c Wed Oct 22 04:51:16 2008 +0000 @@ -423,75 +423,6 @@ } } -void lwasm_read_file(asmstate_t *as, char *fname) -{ - FILE *f; - int cline = 0; - sourceline_t *cl; - size_t bufflen; - char *buff = NULL; - int retval; - - as -> passnum = 1; - - f = fopen(fname, "r"); - if (!f) - { - fprintf(stderr, "Cannot open input file %s: %s\n", fname, strerror(errno)); - return; - } - - while (!feof(f)) - { - retval = getline(&buff, &bufflen, f); - debug(" read line (%s:%d): %s\n", fname, cline, buff); - if (retval < 0) - { - if (feof(f)) - break; - fprintf(stderr, "Error reading '%s': %s\n", fname, strerror(errno)); - exit(1); - } - if (strchr(buff, '\n')) - *strchr(buff, '\n') = '\0'; - if (strchr(buff, '\r')) - *strchr(buff, '\r') = '\0'; - cl = calloc(sizeof(sourceline_t), 1); - if (!cl) - { - perror("Malloc"); - exit(1); - } - - cl -> lineno = cline++; - cl -> sourcefile = fname; - cl -> opcode = -1; - cl -> addrmode = -1; - cl -> addr = as -> addr; - cl -> dpval = as -> dpval; - cl -> prev = as -> source_tail; - if (as -> source_tail) - as -> source_tail -> next = cl; - as -> source_tail = cl; - if (as -> source_head == NULL) - as -> source_head = cl; - cl -> line = strdup(buff); - - resolve_insn(as, cl); - - if (cl -> opcode >= 0 && instab[cl -> opcode].instype == INSTYPE_PSEUDO && instab[cl -> opcode].specialnum == SPECIAL_END) - break; - - *buff = '\0'; - - } - if (buff) - free(buff); - - fclose(f); - - return; -} /* below this point is the expression evaluation package diff -r 287a6905a63c -r 05d4115b4860 src/lwasm.h --- a/src/lwasm.h Sat Oct 04 03:20:36 2008 +0000 +++ b/src/lwasm.h Wed Oct 22 04:51:16 2008 +0000 @@ -24,211 +24,33 @@ #ifndef __lwasm_h_seen__ #define __lwasm_h_seen__ -#define MAX_OP_LEN 32 -#define SYMCHAR_START "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" -#define SYMCHAR "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$." - -#define MACROCHAR_START "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" -#define MACROCHAR "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" - - -#define OPER_INH 0 -#define OPER_RTOR 1 -#define OPER_RLIST 2 -#define OPER_TFM 3 -#define OPER_IMM8 4 -#define OPER_IMM16 5 -#define OPER_IMM32 6 -#define OPER_DIR 7 -#define OPER_EXT 8 -#define OPER_INDEX 9 // indexed with no offset -#define OPER_DIREXT 10 // used as a placeholder when direct/extended unknown -#define OPER_BITBIT 11 // bit to bit direct page opers -#define OPER_REL8 12 -#define OPER_REL16 13 -#define OPER_INDEX5 14 // 5 bit offset indexed -#define OPER_INDEX8 15 // 8 bit offset indexed -#define OPER_INDEX16 16 // 16 bit offset indexed -#define OPER_INDEXV 17 // unknown size offset indexed -#define OPER_EXTIND 18 // extended indirect -#define OPER_LOGICD 19 // logic on mem, direct mode -#define OPER_LOGICE 20 // logic on mem, extended mode -#define OPER_LOGICEI 21 // logic on mem, extended indir mode -#define OPER_LOGICI 22 // logic on mem, indexed no offset -#define OPER_LOGICI5 23 // logic on mem, 5 bit indexed offset -#define OPER_LOGICI8 24 // logic on mem, 8 bit indexed offset -#define OPER_LOGICI16 25 // logic on mem, 16 bit indexed offset -#define OPER_LOGICIV 26 // logic on mem, unknown size offset - #define OUTPUT_DECB 0 // DECB multirecord format #define OUTPUT_RAW 1 // raw sequence of bytes #define OUTPUT_RAWREL 2 // raw but with ORG as a relative offset - -enum -{ - ERR_NONE, // no error - ERR_BADOP, // bad opcode - ERR_BADSYM, // illegal symbol - ERR_DUPSYM, // duplicate symbol definition - ERR_NOSYM, // symbol required but not present - ERR_FORWARD, // forward references not permitted here - ERR_OVERFLOW, // byte overflow - ERR_PHASE, // phasing error - ERR_BADOPER, // bad operand - ERR_SYM, // symbol present where not permitted - ERR_UNDEF, // undefined symbol - ERR_OVERFLOW3, // bit number out of range - ERR_BADEXPR, // invalid expression - ERR_BADREG, // invalid register - ERR_BADFN, // bad file name - ERR_ENDM, // end macro without macro - ERR_MACRO, // redefined macro - ERR_NESTNAME, // nested namespace - ERR_BADCOND, // bad condition - ERR_USER, // user error - ERR_PRAGMA, // bad pragma - - ERR_MAXERR // last error in the list -}; - -typedef struct sourceline_s sourceline_t; - -// structure to keep track of errors -typedef struct errortab_s errortab_t; -struct errortab_s { - int errnum; - sourceline_t *line; - errortab_t *next; -}; - -typedef struct macroline_s macroline_t; -struct macroline_s -{ - char *linetext; - macroline_t *next; -}; - -typedef struct macrotab_s macrotab_t; -struct macrotab_s -{ - char *name; // name of the macro - macroline_t *linehead; // start of the macro lines - macroline_t *linetail; // last line of macro - macrotab_t *next; -}; - - -// structure to keep track of each line of the source -// this also keeps various bits of state about a line -struct sourceline_s { - char *sourcefile; // name of the source file - int lineno; // line number in the source file - char *symstr; // symbol on this line (if any) - int opcode; // index to instab for this line - int opbytes; // actual bytes of opcode - int postbyte; // post byte for the instruction - int numcodebytes; // how many code bytes for this line - unsigned char *codebytes; // actual code for this line - int codesize; // size of codebytes -// if minaddr and maxaddr are the same, we know exactly which address -// we are at so there can be no possible phase error with symbols defined -// here; these are *code* addresses - int len; // length of this insn - int in_macro; // set if it's a macro expansion line - int code_symloc; - int addrmode; // addressing mode of this insn - int addr; // the lowest possible address of this line - int dpval; // dp value at this point in the code - int hassym; // is there a symbol on this line - int addrset; // is this insn a point where the address is *set* (org) - int isequ; // does this insn set a symbol address (equ)? - int isset; // is the address setting from a "set"? - int issetdp; // this insn sets DP - int symaddr; // address for the symbol (if we're setting one) - // also used for "setdp" - int undef; // set if the symbol is undefined - int p1f16; // if we forced 16 bit on pass 1 so we can force it on pass 2 - int nocode; // if set, there is no code to output (rmb) - int notinsn; // if this is not a regular insn (used for formatting output) - char *line; // the text of the line - char *opcstr; // opcode string - char *operstr; // operand string - char *remainder; // remainder string (whole line if no opcode/operand - errortab_t *errors; // errors on this line - sourceline_t *next; // next line - sourceline_t *prev; // previous line - macrotab_t *macro; // pointer to macro table entry if this is a macro - int skipped; // set if the line was skipped - char *user_error; // user error message - int macrodef; // set if it's a macro definition line -}; - -// structure to keep the symbol table -typedef struct symtab_s symtab_t; -struct symtab_s { - char *symbol; // symbol name - sourceline_t *line; // pointer to the line where symbol is defined - int addr; // address of symbol (-1 for unknown) - int flags; // flags for symbol - symtab_t *next; // next symbol -}; - +#define OUTPUT_OBJ 3 // proprietary object file format // keep track of current assembler state typedef struct { - int dpval; // current dp value (setdp) - int addr; // current address - symtab_t *symbol_table; - sourceline_t *source_head; - sourceline_t *source_tail; - int errorcount; // error count - int passnum; // which pass are we on? - const char *infile; // input file - const char *outfile;// output file - const char *listfile; // output listing file - int debug; // debug mode - int outformat; // output format type: 0 = decb, 1 = raw - int execaddr; // execution address for the program (END ....) - macrotab_t *macros; // pointer to macros - int inmacro; // are we in a macro? - char *cur_namespace; // current namespace prefix - int skipcond; // are we skipping a condition? - int skipcount; // number of endc we need before we stop skipping - int skipmacro; // are we skipping a macro definition? - int noelse; // skipped an else? - int pragmas; // what pragmas are in effect? + int dpval; // current dp value (setdp) + int addr; // current address + int errorcount; // error count + int passnum; // which pass are we on? + const char *infile; // input file + const char *outfile; // output file + const char *listfile; // output listing file + int debug; // debug mode + int outformat; // output format type + int execaddr; // execution address for the program (END ....) + int pragmas; // what pragmas are in effect? } asmstate_t; #define PRAGMA_NOINDEX0TONONE 1 - -#ifndef __lwasm_c_seen__ -extern int eval_expr(asmstate_t *as, sourceline_t *cl, char **optr, int *val); -extern void register_error(asmstate_t *as, sourceline_t *cl, int errcode); -extern int lookupreg3(const char *rlist, char **str); -extern int lookupreg(const char *reglist, char **str); -extern void lwasm_read_file(asmstate_t *as, char *fname); -extern void addcodebyte(asmstate_t *as, sourceline_t *cl, int cb); -#endif - -#define SYMFLAG_NONE 0 -#define SYMFLAG_SET 1 - #ifndef __symtab_c_seen__ -#include -extern void register_symbol(asmstate_t *as, sourceline_t *cl, char *symstr, int val, int flags); -extern int lookup_symbol(asmstate_t *as, char *symstr); -extern void list_symbols(asmstate_t *as, FILE *f); +//extern void register_symbol(asmstate_t *as, sourceline_t *cl, char *symstr, int val, int flags); +//extern int lookup_symbol(asmstate_t *as, char *symstr); +//extern void list_symbols(asmstate_t *as, FILE *f); #endif -#ifndef __index_c_seen__ -extern int parse_index_expr(asmstate_t *as, sourceline_t *cl, char **optr, int *postbyte, int *opmode, int *v1); -#endif - -#define emit(cb) do { addcodebyte(as, cl, (cb)); } while (0) -#define emitop(cb) do { if ((cb) > 0xff) addcodebyte(as, cl, (cb)>>8); addcodebyte(as, cl, (cb) & 0xff); } while (0) -#define errorp1(e) do { if (as -> passnum == 1) register_error(as, cl, (e)); } while (0) -#define errorp2(e) do { if (as -> passnum == 2) register_error(as, cl, (e)); } while (0) - #endif //__lwasm_h_seen__ diff -r 287a6905a63c -r 05d4115b4860 src/main.c --- a/src/main.c Sat Oct 04 03:20:36 2008 +0000 +++ b/src/main.c Wed Oct 22 04:51:16 2008 +0000 @@ -22,7 +22,9 @@ */ +#ifdef HAVE_CONFIG_H #include "config.h" +#endif #include #include @@ -32,10 +34,8 @@ #include "lwasm.h" // external declarations -extern void resolve_phasing(asmstate_t *as); -extern void generate_code(asmstate_t *as); -extern void list_code(asmstate_t *as); -extern void write_code(asmstate_t *as); +extern void lwasm_pass1(asmstate_t *as); +extern void lwasm_pass2(asmstate_t *as); // command line option handling @@ -78,7 +78,11 @@ // raw binary output as -> outformat = OUTPUT_RAW; break; - + + case 0x100: + // proprietary object format + as -> outformat = OUTPUT_OBJ; + case ARGP_KEY_END: // done; sanity check if (!as -> outfile) @@ -112,6 +116,8 @@ "Generate raw binary format output"}, { "rawrel", 0, 0, 0, "Generate raw binary respecing ORG statements as offsets from the start of the file"}, + { "obj", 0, 0, 0, + "Generate proprietary object file format for later linking" }, { 0 } }; @@ -133,23 +139,21 @@ argp_parse(&argp, argc, argv, 0, 0, &asmstate); if (!asmstate.listfile) asmstate.listfile = "-"; - -// printf("Assembling %s to %s; list to %s\n", asmstate.infile, asmstate.outfile, asmstate.listfile); /* pass 1 - collect the symbols and assign addresses where possible */ /* pass 1 also resolves included files, etc. */ /* that means files are read exactly once unless included multiple times */ - lwasm_read_file(&asmstate, (char *)(asmstate.infile)); + lwasm_pass1(&asmstate); // pass 2: actually generate the code; if any phasing errors appear // at this stage, we have a bug - generate_code(&asmstate); + lwasm_pass2(&asmstate); // now make a pretty listing - list_code(&asmstate); +// lwasm_list(&asmstate); // now write the code out to the output file - write_code(&asmstate); +// lwasm_output(&asmstate); if (asmstate.errorcount > 0) exit(1); diff -r 287a6905a63c -r 05d4115b4860 src/pass1.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pass1.c Wed Oct 22 04:51:16 2008 +0000 @@ -0,0 +1,50 @@ +/* +pass1.c +Copyright © 2008 William Astle + +This file is part of LWASM. + +LWASM is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + + +Handles first pass of assembly + +First pass involves the following: + +1. read all lines from the main source file, following all "include" + directives as appropriate +2. parse each line into a symbol, operation code, and operand as appropriate +3. each operand is evaluated for syntax and futher for value if there are + multiple addressing sizes available; any undefined or not fully resolved + value will default to the largest addressing size available (16 bit) +4. addresses are assigned to every symbol defined in the assembly +5. macros are defined and expanded at this pass + + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "lwasm.h" + +void lwasm_pass1(asmstate_t *as) +{ +} diff -r 287a6905a63c -r 05d4115b4860 src/pass2.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pass2.c Wed Oct 22 04:51:16 2008 +0000 @@ -0,0 +1,38 @@ +/* +pass2.c +Copyright © 2008 William Astle + +This file is part of LWASM. + +LWASM is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . + + +Handles second pass of assembly + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "lwasm.h" + +void lwasm_pass2(asmstate_t *as) +{ +}