# 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)
+{
+}