changeset 337:04c80c51b16a

Checkpoint development
author lost
date Fri, 12 Mar 2010 06:01:38 +0000
parents 401587ab6a09
children e7885b3ee266
files lwasm/Makefile.am lwasm/instab.c lwasm/instab.h lwasm/lwasm.c lwasm/lwasm.h lwasm/main.c lwasm/pass1.c lwlib/lw_expr.c lwlib/lw_expr.h
diffstat 9 files changed, 871 insertions(+), 97 deletions(-) [+]
line wrap: on
line diff
--- a/lwasm/Makefile.am	Fri Mar 05 02:34:16 2010 +0000
+++ b/lwasm/Makefile.am	Fri Mar 12 06:01:38 2010 +0000
@@ -1,5 +1,5 @@
 AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib -I$(top_builddir)/lwlib -I$(top_srcdir)/lwlib
 bin_PROGRAMS = lwasm
-lwasm_SOURCES = main.c pragma.c input.c pass1.c
+lwasm_SOURCES = main.c pragma.c input.c pass1.c lwasm.c
 lwasm_LDADD = -L$(top_builddir)/lib -L$(top_srcdir)/lib -L$(top_builddir)/lwlib -L$(top_srcdir)/lwlib -lgnu -llw
 EXTRA_DIST =  lwasm.h input.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwasm/instab.c	Fri Mar 12 06:01:38 2010 +0000
@@ -0,0 +1,523 @@
+/*
+instab.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 <http://www.gnu.org/licenses/>.
+
+
+Contains the instruction table for assembling code
+*/
+#include <config.h>
+
+#include <stdlib.h>
+#define __instab_c_seen__
+#include "instab.h"
+
+extern PARSEFUNC(insn_parse_inh);
+extern RESOLVEFUNC(insn_resolve_inh);
+extern PARSEFUNC(insn_parse_gen8);
+extern RESOLVEFUNC(insn_resolve_gen8);
+extern PARSEFUNC(insn_parse_gen16);
+extern RESOLVEFUNC(insn_resolve_gen16);
+extern PARSEFUNC(insn_parse_gen32);
+extern RESOLVEFUNC(insn_resolve_gen32);
+extern PARSEFUNC(insn_parse_gen0);
+extern RESOLVEFUNC(insn_resolve_gen0);
+extern PARSEFUNC(insn_parse_rtor);
+extern RESOLVEFUNC(insn_resolve_rtor);
+extern PARSEFUNC(insn_parse_imm8);
+extern RESOLVEFUNC(insn_resolve_imm8);
+extern PARSEFUNC(insn_parse_rel8);
+extern RESOLVEFUNC(insn_resolve_rel8);
+extern PARSEFUNC(insn_parse_rel16);
+extern RESOLVEFUNC(insn_resolve_rel16);
+extern PARSEFUNC(insn_parse_rlist);
+extern RESOLVEFUNC(insn_resolve_rlist);
+extern PARSEFUNC(insn_parse_bitbit);
+extern RESOLVEFUNC(insn_resolve_bitbit);
+extern PARSEFUNC(insn_parse_logicmem);
+extern RESOLVEFUNC(insn_resolve_logicmem);
+extern PARSEFUNC(insn_parse_tfm);
+extern RESOLVEFUNC(insn_resolve_tfm);
+extern PARSEFUNC(insn_parse_tfmrtor);
+extern RESOLVEFUNC(insn_resolve_tfmrtor);
+extern PARSEFUNC(insn_parse_indexed);
+extern RESOLVEFUNC(insn_resolve_indexed);
+
+extern PARSEFUNC(pseudo_parse_org);
+extern RESOLVEFUNC(pseudo_resolve_org);
+extern PARSEFUNC(pseudo_parse_equ);
+extern RESOLVEFUNC(pseudo_resolve_equ);
+extern PARSEFUNC(pseudo_parse_rmb);
+extern RESOLVEFUNC(pseudo_resolve_rmb);
+extern PARSEFUNC(pseudo_parse_rmd);
+extern RESOLVEFUNC(pseudo_resolve_rmd);
+extern PARSEFUNC(pseudo_parse_rmq);
+extern RESOLVEFUNC(pseudo_resolve_rmq);
+extern PARSEFUNC(pseudo_parse_zmb);
+extern RESOLVEFUNC(pseudo_resolve_zmb);
+extern PARSEFUNC(pseudo_parse_zmd);
+extern RESOLVEFUNC(pseudo_resolve_zmd);
+extern PARSEFUNC(pseudo_parse_zmq);
+extern RESOLVEFUNC(pseudo_resolve_zmq);
+extern PARSEFUNC(pseudo_parse_include);
+extern RESOLVEFUNC(pseudo_resolve_include);
+extern PARSEFUNC(pseudo_parse_end);
+extern RESOLVEFUNC(pseudo_resolve_end);
+extern PARSEFUNC(pseudo_parse_align);
+extern RESOLVEFUNC(pseudo_resolve_align);
+extern PARSEFUNC(pseudo_parse_error);
+extern RESOLVEFUNC(pseudo_resolve_error);
+extern PARSEFUNC(pseudo_parse_fcc);
+extern RESOLVEFUNC(pseudo_resolve_fcc);
+extern PARSEFUNC(pseudo_parse_fcs);
+extern RESOLVEFUNC(pseudo_resolve_fcs);
+extern PARSEFUNC(pseudo_parse_fcn);
+extern RESOLVEFUNC(pseudo_resolve_fcn);
+extern PARSEFUNC(pseudo_parse_fcb);
+extern RESOLVEFUNC(pseudo_resolve_fcb);
+extern PARSEFUNC(pseudo_parse_fdb);
+extern RESOLVEFUNC(pseudo_resolve_fdb);
+extern PARSEFUNC(pseudo_parse_fqb);
+extern RESOLVEFUNC(pseudo_resolve_fqb);
+extern PARSEFUNC(pseudo_parse_ifne);
+extern RESOLVEFUNC(pseudo_resolve_ifne);
+extern PARSEFUNC(pseudo_parse_ifeq);
+extern RESOLVEFUNC(pseudo_resolve_ifeq);
+extern PARSEFUNC(pseudo_parse_ifgt);
+extern RESOLVEFUNC(pseudo_resolve_ifgt);
+extern PARSEFUNC(pseudo_parse_ifge);
+extern RESOLVEFUNC(pseudo_resolve_ifge);
+extern PARSEFUNC(pseudo_parse_iflt);
+extern RESOLVEFUNC(pseudo_resolve_iflt);
+extern PARSEFUNC(pseudo_parse_ifle);
+extern RESOLVEFUNC(pseudo_resolve_ifle);
+extern PARSEFUNC(pseudo_parse_ifp1);
+extern RESOLVEFUNC(pseudo_resolve_ifp1);
+extern PARSEFUNC(pseudo_parse_ifp2);
+extern RESOLVEFUNC(pseudo_resolve_ifp2);
+extern PARSEFUNC(pseudo_parse_else);
+extern RESOLVEFUNC(pseudo_resolve_else);
+extern PARSEFUNC(pseudo_parse_endc);
+extern RESOLVEFUNC(pseudo_resolve_endc);
+extern PARSEFUNC(pseudo_parse_macro);
+extern RESOLVEFUNC(pseudo_resolve_macro);
+extern PARSEFUNC(pseudo_parse_endm);
+extern RESOLVEFUNC(pseudo_resolve_endm);
+extern PARSEFUNC(pseudo_parse_setdp);
+extern RESOLVEFUNC(pseudo_resolve_setdp);
+extern PARSEFUNC(pseudo_parse_set);
+extern RESOLVEFUNC(pseudo_resolve_set);
+extern PARSEFUNC(pseudo_parse_section);
+extern RESOLVEFUNC(pseudo_resolve_section);
+extern PARSEFUNC(pseudo_parse_endsection);
+extern RESOLVEFUNC(pseudo_resolve_endsection);
+extern PARSEFUNC(pseudo_parse_pragma);
+extern RESOLVEFUNC(pseudo_resolve_pragma);
+extern PARSEFUNC(pseudo_parse_starpragma);
+extern RESOLVEFUNC(pseudo_resolve_starpragma);
+extern PARSEFUNC(pseudo_parse_extern);
+extern RESOLVEFUNC(pseudo_resolve_extern);
+extern PARSEFUNC(pseudo_parse_export);
+extern RESOLVEFUNC(pseudo_resolve_export);
+extern PARSEFUNC(pseudo_parse_ifdef);
+extern RESOLVEFUNC(pseudo_resolve_ifdef);
+extern PARSEFUNC(pseudo_parse_ifndef);
+extern RESOLVEFUNC(pseudo_resolve_ifndef);
+extern PARSEFUNC(pseudo_parse_noop);
+extern RESOLVEFUNC(pseudo_resolve_noop);
+extern PARSEFUNC(pseudo_parse_includebin);
+extern RESOLVEFUNC(pseudo_resolve_includebin);
+
+extern PARSEFUNC(pseudo_parse_os9);
+extern RESOLVEFUNC(pseudo_resolve_os9);
+extern PARSEFUNC(pseudo_parse_mod);
+extern RESOLVEFUNC(pseudo_resolve_mod);
+extern PARSEFUNC(pseudo_parse_emod);
+extern RESOLVEFUNC(pseudo_resolve_emod);
+
+instab_t instab[] =
+{
+	{ "abx",		{	0x3a,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "adca",		{	0x99,	0xa9,	0xb9,	0x89},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "adcb",		{	0xd9,	0xe9,	0xf9,	0xc9},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "adcd",		{	0x1099,	0x10a9,	0x10b9,	0x1089},insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_is6309},
+	{ "adcr",		{	0x1031,	-1,		-1,		-1	},	insn_parse_rtor,		insn_resolve_rtor,				lwasm_insn_is6309},
+	{ "adda",		{	0x9b,	0xab,	0xbb,	0x8b},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "addb",		{	0xdb,	0xeb,	0xfb,	0xcb},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "addd",		{	0xd3,	0xe3,	0xf3,	0xc3},	insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_normal},
+	{ "adde",		{	0x119b,	0x11ab,	0x11bb,	0x118b},insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_is6309},
+	{ "addf",		{	0x11db,	0x11eb,	0x11fb,	0x11cb},insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_is6309},
+	{ "addr",		{	0x1030,	-1,		-1,		-1	},	insn_parse_rtor,		insn_resolve_rtor,				lwasm_insn_is6309},
+	{ "addw",		{	0x109b,	0x10ab,	0x10bb,	0x108b},insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_is6309},
+	{ "aim",		{	0x02,	0x62,	0x72,	-1	},	insn_parse_logicmem,	insn_resolve_logicmem,			lwasm_insn_is6309},
+	{ "anda",		{	0x94,	0xa4,	0xb4,	0x84},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "andb",		{	0xd4,	0xe4,	0xf4,	0xc4},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "andcc",		{	0x1c,	-1,		-1,		0x1c},	insn_parse_imm8,		insn_resolve_imm8,				lwasm_insn_normal},
+	{ "andd",		{	0x1094,	0x10a4,	0x10b4,	0x1084},insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_is6309},
+	{ "andr",		{	0x1034,	-1,		-1,		-1	},	insn_parse_rtor,		insn_resolve_rtor,				lwasm_insn_is6309},
+	{ "asl",		{	0x08,	0x68,	0x78,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "asla",		{	0x48,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "aslb",		{	0x58,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "asld",		{	0x1048,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "asr",		{	0x07,	0x67,	0x77,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "asra",		{	0x47,	-1,		-1,		-1	}, 	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "asrb",		{	0x57,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "asrd",		{	0x1047,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+
+	{ "band",		{	0x1130,	-1,		-1,		-1	},	insn_parse_bitbit,		insn_resolve_bitbit,			lwasm_insn_is6309},
+	{ "bcc",		{	0x24,	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+	{ "bcs",		{	0x25,	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+	{ "beor",		{	0x1134,	-1,		-1,		-1	},	insn_parse_bitbit,		insn_resolve_bitbit,			lwasm_insn_is6309},
+	{ "beq",		{	0x27,	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+	{ "bge",		{	0x2c,	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+	{ "bgt",		{	0x2e,	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+	{ "bhi",		{	0x22,	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+	{ "bhs",		{	0x24,	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+	{ "biand",		{	0x1131,	-1,		-1,		-1	},	insn_parse_bitbit,		insn_resolve_bitbit,			lwasm_insn_is6309},
+	{ "bieor",		{	0x1135,	-1,		-1,		-1	},	insn_parse_bitbit,		insn_resolve_bitbit,			lwasm_insn_is6309},
+	{ "bior",		{	0x1133, -1,		-1,		-1	},	insn_parse_bitbit,		insn_resolve_bitbit,			lwasm_insn_is6309},
+	{ "bita",		{	0x95,	0xa5,	0xb5,	0x85},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "bitb",		{	0xd5,	0xe5,	0xf5,	0xc5},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "bitd",		{	0x1095,	0x10a5,	0x10b5,	0x1085},insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_is6309},
+	{ "bitmd",		{	0x113c, -1,		-1,		0x113c},insn_parse_imm8,		insn_resolve_imm8,				lwasm_insn_is6309},
+	{ "ble",		{	0x2f,	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+	{ "blo",		{	0x25,	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+	{ "bls",		{	0x23,	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+	{ "blt",		{	0x2d,	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+	{ "bmi",		{	0x2b,	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+	{ "bne",		{	0x26, 	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+	{ "bor",		{	0x1132,	-1,		-1,		-1	},	insn_parse_bitbit,		insn_resolve_bitbit,			lwasm_insn_is6309},
+	{ "bpl",		{	0x2a,	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+	{ "bra",		{	0x20,	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+	{ "brn",		{	0x21,	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+	{ "bsr",		{	0x8d,	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+	{ "bvc",		{	0x28,	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+	{ "bvs",		{	0x29,	-1,		-1,		-1	},	insn_parse_rel8,		insn_resolve_rel8,				lwasm_insn_normal},
+
+	{ "clr",		{	0x0f,	0x6f,	0x7f,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "clra",		{	0x4f,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "clrb",		{	0x5f,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "clrd",		{	0x104f,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "clre",		{	0x114f,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "clrf",		{	0x115f,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "clrw",		{	0x105f,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "cmpa",		{	0x91,	0xa1,	0xb1,	0x81},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "cmpb",		{	0xd1,	0xe1,	0xf1,	0xc1},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "cmpd",		{	0x1093,	0x10a3,	0x10b3,	0x1083},insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_normal},
+	{ "cmpe",		{	0x1191,	0x11a1,	0x11b1,	0x1181},insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_is6309},
+	{ "cmpf",		{	0x11d1,	0x11e1,	0x11f1,	0x11c1},insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_is6309},
+	{ "cmpr",		{	0x1037,	-1,		-1,		-1	},	insn_parse_rtor,		insn_resolve_rtor,				lwasm_insn_is6309},
+	{ "cmps",		{	0x119c,	0x11ac,	0x11bc,	0x118c},insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_normal},
+	{ "cmpu",		{	0x1193,	0x11a3,	0x11b3,	0x1183},insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_normal},
+	{ "cmpw",		{	0x1091,	0x10a1,	0x10b1,	0x1081},insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_is6309},
+	{ "cmpx",		{	0x9c,	0xac,	0xbc,	0x8c}, 	insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_normal},
+	{ "cmpy",		{	0x109c,	0x10ac,	0x10bc,	0x108c},insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_normal},
+	{ "com",		{	0x03,	0x63,	0x73,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "coma",		{	0x43,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "comb",		{	0x53,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "comd",		{	0x1043,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "come",		{	0x1143,	-1, 	-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "comf", 		{	0x1153, -1,		-1,		-1	}, 	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "comw",		{	0x1053,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "cwai",		{	0x3c, 	-1,		-1,		-1	},	insn_parse_imm8,		insn_resolve_imm8,				lwasm_insn_normal},
+	
+	{ "daa",		{	0x19,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "dec",		{	0x0a,	0x6a,	0x7a,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "deca",		{	0x4a,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "decb",		{	0x5a,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "decd",		{	0x104a,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "dece",		{	0x114a,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "decf",		{	0x115a,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "decw",		{	0x105a,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "divd",		{	0x118d,	0x119d,	0x11ad,	0x11bd},insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_is6309},
+	{ "divq",		{	0x118e,	0x119e,	0x11ae,	0x11be},insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_is6309},
+
+	{ "eim",		{	0x05,	0x65,	0x75,	-1	},	insn_parse_logicmem,	insn_resolve_logicmem,			lwasm_insn_is6309},
+	{ "eora",		{	0x98,	0xa8,	0xb8,	0x88},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "eorb",		{	0xd8,	0xe9,	0xf9,	0xc8},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "eord",		{	0x1098,	0x10a8,	0x10b8,	0x1088},insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_is6309},
+	{ "eorr",		{	0x1036,	-1,		-1,		-1	},	insn_parse_rtor,		insn_resolve_rtor,				lwasm_insn_is6309},
+	{ "exg",		{	0x1e,	-1,		-1,		-1	},	insn_parse_rtor,		insn_resolve_rtor,				lwasm_insn_normal},
+
+	{ "inc",		{	0x0c,	0x6c,	0x7c,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "inca",		{	0x4c,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "incb",		{	0x5c,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "incd",		{	0x104c,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "ince",		{	0x114c,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "incf",		{	0x115c,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "incw",		{	0x105c,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	
+	{ "jmp",		{	0x0e,	0x6e,	0x7e,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "jsr",		{	0x9d,	0xad,	0xbd,	-1	}, 	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	
+	{ "lbcc",		{	0x1024,	-1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lbcs",		{	0x1025,	-1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lbeq",		{	0x1027,	-1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lbge",		{	0x102c,	-1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lbgt",		{	0x102e,	-1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lbhi",		{	0x1022,	-1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lbhs",		{	0x1024,	-1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lble",		{	0x102f,	-1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lblo",		{	0x1025,	-1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lbls",		{	0x1023,	-1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lblt",		{	0x102d, -1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lbmi",		{	0x102b,	-1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lbne",		{	0x1026,	-1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lbpl",		{	0x102a,	-1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lbra",		{	0x16,	-1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lbrn",		{	0x1021,	-1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lbsr",		{	0x17,	-1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lbvc",		{	0x1028,	-1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lbvs",		{	0x1029,	-1,		-1,		-1	},	insn_parse_rel16,		insn_resolve_rel16,				lwasm_insn_normal},
+	{ "lda",		{	0x96,	0xa6,	0xb6,	0x86},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "ldb",		{	0xd6,	0xe6,	0xf6,	0xc6},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "ldbt",		{	0x1136,	-1,		-1,		-1	},	insn_parse_bitbit,		insn_resolve_bitbit,			lwasm_insn_is6309},
+	{ "ldd",		{	0xdc,	0xec,	0xfc,	0xcc},	insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_normal},
+	{ "lde",		{	0x1196,	0x11a6,	0x11b6,	0x1186},insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_is6309},
+	{ "ldf",		{	0x11d6,	0x11e6,	0x11f6,	0x11c6},insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_is6309},
+	{ "ldq",		{	0x10dc,	0x10ec,	0x10fc,	0xcd},	insn_parse_gen32,		insn_resolve_gen32,				lwasm_insn_is6309},
+	{ "lds",		{	0x10de,	0x10ee,	0x10fe,	0x10ce},insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_normal},
+	{ "ldu",		{ 	0xde,	0xee,	0xfe,	0xce},	insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_normal},
+	{ "ldw",		{	0x1096,	0x10a6,	0x10b6,	0x1086},insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_is6309},
+	{ "ldx",		{	0x9e,	0xae,	0xbe,	0x8e},	insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_normal},
+	{ "ldy",		{	0x109e,	0x10ae,	0x10be,	0x108e},insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_normal},
+	{ "ldmd",		{	0x113d, -1,		-1,		0x113d},insn_parse_imm8,		insn_resolve_imm8,				lwasm_insn_is6309},
+	{ "leas",		{	0x32,	-1,		-1,		-1	},	insn_parse_indexed,		insn_resolve_indexed,			lwasm_insn_normal},
+	{ "leau",		{	0x33,	-1,		-1,		-1	},	insn_parse_indexed,		insn_resolve_indexed,			lwasm_insn_normal},
+	{ "leax",		{	0x30,	-1,		-1,		-1	},	insn_parse_indexed,		insn_resolve_indexed,			lwasm_insn_normal},
+	{ "leay",		{	0x31,	-1,		-1,		-1	},	insn_parse_indexed,		insn_resolve_indexed,			lwasm_insn_normal},
+	{ "lsl",		{	0x08,	0x68,	0x78,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "lsla",		{	0x48,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "lslb",		{	0x58,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "lsld",		{	0x1048,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "lsr",		{	0x04,	0x64,	0x74,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "lsra",		{	0x44,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "lsrb",		{	0x54,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "lsrd",		{	0x1044,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "lsrw",		{	0x1054,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+
+	{ "mul",		{	0x3d,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "muld",		{	0x118f,	0x119f,	0x11af,	0x11bf},insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_is6309},
+	
+	{ "neg",		{	0x00,	0x60,	0x70,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "nega",		{	0x40,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "negb",		{	0x50,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "negd",		{	0x1040,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "nop",		{	0x12,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	
+	{ "oim",		{	0x01,	0x61,	0x71,	-1	},	insn_parse_logicmem,	insn_resolve_logicmem,			lwasm_insn_is6309},
+	{ "ora",		{	0x9a,	0xaa,	0xba,	0x8a},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "orb",		{	0xda,	0xea,	0xfa,	0xca},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "orcc",		{	0x1a,	-1,		-1,	0x1a	},	insn_parse_imm8,		insn_resolve_imm8,				lwasm_insn_normal},
+	{ "ord",		{	0x109a,	0x10aa,	0x10ba,	0x108a},insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_is6309},
+	{ "orr",		{	0x1035,	-1,		-1,		-1	},	insn_parse_rtor,		insn_resolve_rtor,				lwasm_insn_is6309},
+	
+	{ "pshs",		{	0x34,	-1,		-1,		-1	},	insn_parse_rlist,		insn_resolve_rlist,				lwasm_insn_normal},
+	{ "pshsw",		{	0x1038,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "pshu",		{	0x36,	-1,		-1,		-1	},	insn_parse_rlist,		insn_resolve_rlist,				lwasm_insn_normal},
+	{ "pshuw",		{	0x103a,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "puls",		{	0x35,	-1,		-1,		-1	},	insn_parse_rlist,		insn_resolve_rlist,				lwasm_insn_normal},
+	{ "pulsw",		{	0x1039,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "pulu",		{	0x37,	-1,		-1,		-1	},	insn_parse_rlist,		insn_resolve_rlist,				lwasm_insn_normal},
+	{ "puluw",		{	0x103b,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	
+	{ "rol",		{	0x09,	0x69,	0x79,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "rola",		{	0x49,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "rolb",		{	0x59,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "rold",		{	0x1049,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "rolw",		{	0x1059,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "ror",		{	0x06,	0x66,	0x76,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "rora",		{	0x46,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "rorb",		{	0x56,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "rord",		{	0x1046,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "rorw",		{	0x1056,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "rti",		{	0x3b,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "rts",		{	0x39,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	
+	{ "sbca",		{	0x92,	0xa2,	0xb2,	0x82},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "sbcb",		{	0xd2,	0xe2,	0xf2,	0xc2},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "sbcd",		{	0x1092,	0x10a2,	0x10b2,	0x1082},insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_is6309},
+	{ "sbcr",		{	0x1033,	-1,		-1,		-1	},	insn_parse_rtor,		insn_resolve_rtor,				lwasm_insn_is6309},
+	{ "sex",		{	0x1d,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "sexw",		{	0x14,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "sta",		{	0x97,	0xa7,	0xb7,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "stb",		{	0xd7,	0xe7,	0xf7,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "stbt",		{	0x1137,	-1,		-1,		-1	},	insn_parse_bitbit,		insn_resolve_bitbit,			lwasm_insn_is6309},
+	{ "std",		{	0xdd,	0xed,	0xfd,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "ste",		{	0x1197,	0x11a7,	0x11b7,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_is6309},
+	{ "stf",		{	0x11d7,	0x11e7,	0x11f7,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_is6309},
+	{ "stq",		{	0x10dd,	0x10ed,	0x10fd,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_is6309},
+	{ "sts",		{	0x10df,	0x10ef,	0x10ff,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "stu",		{	0xdf,	0xef,	0xff,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "stw",		{	0x1097,	0x10a7,	0x10b7,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_is6309},
+	{ "stx",		{	0x9f,	0xaf,	0xbf,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "sty",		{	0x109f,	0x10af,	0x10bf,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "suba",		{	0x90,	0xa0,	0xb0,	0x80},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "subb",		{	0xd0,	0xe0,	0xf0,	0xc0},	insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_normal},
+	{ "subd",		{	0x93,	0xa3,	0xb3,	0x83},	insn_parse_gen16,		insn_resolve_gen16,				lwasm_insn_normal},
+	{ "sube",		{	0x1190,	0x11a0,	0x11b0,	0x1180},insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_is6309},
+	{ "subf",		{	0x11d0,	0x11e0,	0x11f0,	0x11c0},insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_is6309},
+	{ "subr",		{	0x1032,	-1,		-1,		-1	},	insn_parse_rtor,		insn_resolve_rtor,				lwasm_insn_is6309},
+	{ "subw",		{	0x1090,	0x10a0,	0x1090,	0x1080},insn_parse_gen8,		insn_resolve_gen8,				lwasm_insn_is6309},
+	{ "swi",		{	0x3f,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "swi2",		{	0x103f,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "swi3",		{	0x113f,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "sync",		{	0x13,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	
+	// note: 			r+,r+	r-,r-	r+,r	r,r+
+	{ "tfm",		{	0x1138,	0x1139,	0x113a,	0x113b },insn_parse_tfm,		insn_resolve_tfm,				lwasm_insn_is6309},
+
+	// compatibility opcodes for tfm in other assemblers
+	{ "copy",		{	0x1138, -1, 	-1, 	-1},	insn_parse_tfmrtor,		insn_resolve_tfmrtor,			lwasm_insn_is6309},
+	{ "copy+",		{	0x1138, -1, 	-1, 	-1},	insn_parse_tfmrtor,		insn_resolve_tfmrtor,			lwasm_insn_is6309},
+	{ "tfrp",		{	0x1138, -1, 	-1, 	-1},	insn_parse_tfmrtor,		insn_resolve_tfmrtor,			lwasm_insn_is6309},
+	
+	{ "copy-",		{	0x1139, -1, 	-1, 	-1},	insn_parse_tfmrtor,		insn_resolve_tfmrtor,			lwasm_insn_is6309},
+	{ "tfrm",		{	0x1139, -1, 	-1, 	-1},	insn_parse_tfmrtor,		insn_resolve_tfmrtor,			lwasm_insn_is6309},
+	
+	{ "imp",		{	0x113a, -1, 	-1, 	-1},	insn_parse_tfmrtor,		insn_resolve_tfmrtor,			lwasm_insn_is6309},
+	{ "implode",	{	0x113a, -1, 	-1, 	-1},	insn_parse_tfmrtor,		insn_resolve_tfmrtor,			lwasm_insn_is6309},
+	{ "tfrs",		{	0x113a, -1, 	-1, 	-1},	insn_parse_tfmrtor,		insn_resolve_tfmrtor,			lwasm_insn_is6309},
+	
+	{ "exp",		{	0x113b, -1, 	-1, 	-1},	insn_parse_tfmrtor,		insn_resolve_tfmrtor,			lwasm_insn_is6309},
+	{ "expand",		{	0x113b, -1, 	-1, 	-1},	insn_parse_tfmrtor,		insn_resolve_tfmrtor,			lwasm_insn_is6309},
+	{ "tfrr",		{	0x113b, -1, 	-1, 	-1},	insn_parse_tfmrtor,		insn_resolve_tfmrtor,			lwasm_insn_is6309},
+
+	{ "tfr",		{	0x1f,	-1,		-1,		-1	},	insn_parse_rtor,		insn_resolve_rtor,				lwasm_insn_normal},
+	{ "tim",		{	0x0b,	0x6b,	0x7b,	-1	},	insn_parse_logicmem,	insn_resolve_logicmem,			lwasm_insn_is6309},
+	{ "tst",		{	0x0d,	0x6d,	0x7d,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				lwasm_insn_normal},
+	{ "tsta",		{	0x4d,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "tstb",		{	0x5d,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal},
+	{ "tstd",		{	0x104d,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "tste",		{	0x114d,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "tstf",		{	0x115d,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+	{ "tstw",		{	0x105d,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_is6309},
+
+	{ "org",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_org,		pseudo_resolve_org,				lwasm_insn_normal},
+
+	{ "equ",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_equ,		pseudo_resolve_equ,				lwasm_insn_setsym},
+	{ "=",			{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_equ,		pseudo_resolve_equ,				lwasm_insn_setsym},
+	{ "extern",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_extern,	pseudo_resolve_extern,			lwasm_insn_setsym},
+	{ "external",	{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_extern,	pseudo_resolve_extern,			lwasm_insn_setsym},
+	{ "import",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_extern,	pseudo_resolve_extern,			lwasm_insn_setsym},
+	{ "export",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_export,	pseudo_resolve_export,			lwasm_insn_setsym},
+
+
+	{ "rmb", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_rmb,		pseudo_resolve_rmb,				lwasm_insn_normal},
+	{ "rmd", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_rmd,		pseudo_resolve_rmd,				lwasm_insn_normal},
+	{ "rmq", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_rmq,		pseudo_resolve_rmq,				lwasm_insn_normal},
+
+	{ "zmb", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_zmb,		pseudo_resolve_zmb,				lwasm_insn_normal},
+	{ "zmd", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_zmd,		pseudo_resolve_zmd,				lwasm_insn_normal},
+	{ "zmq", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_zmq,		pseudo_resolve_zmq,				lwasm_insn_normal},
+
+	{ "fcc",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_fcc,		pseudo_resolve_fcc,				lwasm_insn_normal},
+	{ "fcn",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_fcn,		pseudo_resolve_fcn,				lwasm_insn_normal},
+	{ "fcs",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_fcs,		pseudo_resolve_fcs,				lwasm_insn_normal},
+
+	{ "fcb",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_fcb,		pseudo_resolve_fcb,				lwasm_insn_normal},
+	{ "fdb",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_fdb,		pseudo_resolve_fdb,				lwasm_insn_normal},
+	{ "fqb",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_fqb,		pseudo_resolve_fqb,				lwasm_insn_normal},
+	
+	{ "end", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_end,		pseudo_resolve_end,				lwasm_insn_normal},
+
+	{ "includebin", {	-1, 	-1, 	-1, 	-1},	pseudo_parse_includebin,pseudo_resolve_includebin,		lwasm_insn_normal},
+	{ "include",	{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_include,	pseudo_resolve_include,			lwasm_insn_normal},
+	{ "use",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_include,	pseudo_resolve_include,			lwasm_insn_normal},
+	
+	{ "align", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_align,		pseudo_resolve_align,			lwasm_insn_normal},
+
+	{ "error",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_error,		pseudo_resolve_error,			lwasm_insn_normal},
+
+	// these are *dangerous*
+	{ "ifp1",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_ifp1,		pseudo_resolve_ifp1,			lwasm_insn_cond},
+	{ "ifp2",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_ifp2,		pseudo_resolve_ifp2,			lwasm_insn_cond},
+
+	{ "ifeq",		{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_ifeq,		pseudo_resolve_ifeq,			lwasm_insn_cond},
+	{ "ifne",		{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_ifne,		pseudo_resolve_ifne,			lwasm_insn_cond},
+	{ "if",			{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_ifne,		pseudo_resolve_ifne,			lwasm_insn_cond},
+	{ "ifgt",		{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_ifgt,		pseudo_resolve_ifgt,			lwasm_insn_cond},
+	{ "ifge",		{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_ifge,		pseudo_resolve_ifge,			lwasm_insn_cond},
+	{ "iflt",		{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_iflt,		pseudo_resolve_iflt,			lwasm_insn_cond},
+	{ "ifle",		{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_ifle,		pseudo_resolve_ifle,			lwasm_insn_cond},
+	{ "endc",		{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_endc,		pseudo_resolve_endc,			lwasm_insn_cond},
+	{ "else",		{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_else,		pseudo_resolve_else,			lwasm_insn_cond},
+	{ "ifdef",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_ifdef,		pseudo_resolve_ifdef,			lwasm_insn_cond},
+	{ "ifndef",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_ifndef,	pseudo_resolve_ifndef,			lwasm_insn_cond},
+
+	{ "macro",		{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_macro,		pseudo_resolve_macro,			lwasm_insn_cond | lwasm_insn_setsym},
+	{ "endm",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_endm,		pseudo_resolve_endm,			lwasm_insn_cond | lwasm_insn_setsym | lwasm_insn_endm},
+
+	{ "setdp", 		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_setdp,		pseudo_resolve_setdp,			lwasm_insn_normal},
+	{ "set",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_set,		pseudo_resolve_set,				lwasm_insn_setsym},
+
+	{ "section",	{	-1, 	-1, 	-1, 	-1},	pseudo_parse_section,	pseudo_resolve_section,			lwasm_insn_normal},
+	{ "sect",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_section,	pseudo_resolve_section,			lwasm_insn_normal},
+	{ "ends",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_endsection,pseudo_resolve_endsection,		lwasm_insn_normal},
+	{ "endsect",	{	-1, 	-1, 	-1, 	-1},	pseudo_parse_endsection,pseudo_resolve_endsection,		lwasm_insn_normal},
+	{ "endsection",	{	-1,		-1, 	-1, 	-1},	pseudo_parse_endsection,pseudo_resolve_endsection,		lwasm_insn_normal},
+	
+	{ "pragma",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_pragma,	pseudo_resolve_pragma,			lwasm_insn_normal},
+	{ "*pragma",	{	-1, 	-1, 	-1, 	-1},	pseudo_parse_starpragma,pseudo_resolve_starpragma,		lwasm_insn_normal},
+	
+	// for os9 target
+	{ "os9",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_os9,		pseudo_resolve_os9,				lwasm_insn_normal},
+	{ "mod",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_mod,		pseudo_resolve_mod,				lwasm_insn_normal},
+	{ "emod",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_emod,		pseudo_resolve_emod,			lwasm_insn_normal},
+
+	/* for compatibility with gcc6809 output... */
+	{ ".area",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_section,	pseudo_resolve_section,			lwasm_insn_normal},
+	{ ".globl",		{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_export,	pseudo_resolve_export,			lwasm_insn_normal},
+	{ ".module",	{	-1, 	-1, 	-1, 	-1},	pseudo_parse_noop,		pseudo_resolve_noop,			lwasm_insn_normal},
+	
+	{ ".4byte",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_fqb,		pseudo_resolve_fqb,				lwasm_insn_normal},
+	{ ".quad",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_fqb,		pseudo_resolve_fqb,				lwasm_insn_normal},
+	
+	{ ".word",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_fdb,		pseudo_resolve_fdb,				lwasm_insn_normal},
+	{ ".dw",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_fdb,		pseudo_resolve_fdb,				lwasm_insn_normal},
+
+	{ ".byte",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_fcb,		pseudo_resolve_fcb,				lwasm_insn_normal},
+	{ ".db",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_fcb,		pseudo_resolve_fcb,				lwasm_insn_normal},
+
+	{ ".ascii",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_fcc,		pseudo_resolve_fcc,				lwasm_insn_normal},
+	{ ".str",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_fcc,		pseudo_resolve_fcc,				lwasm_insn_normal},
+	
+	{ ".ascis",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_fcs,		pseudo_resolve_fcs,				lwasm_insn_normal},
+	{ ".strs",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_fcs,		pseudo_resolve_fcs,				lwasm_insn_normal},
+	
+	{ ".asciz",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_fcn,		pseudo_resolve_fcn,				lwasm_insn_normal},
+	{ ".strz",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_fcn,		pseudo_resolve_fcn,				lwasm_insn_normal},
+	
+	{ ".blkb",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_rmb,		pseudo_resolve_rmb,				lwasm_insn_normal},
+	{ ".ds",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_rmb,		pseudo_resolve_rmb,				lwasm_insn_normal},
+	{ ".rs",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_rmb,		pseudo_resolve_rmb,				lwasm_insn_normal},
+
+// needs to handle C escapes maybe?
+//	{ ".ascii",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_ascii,		pseudo_resolve_ascii,			lwasm_insn_normal},
+
+	// for compatibility
+	{ ".end", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_end,		pseudo_resolve_end,				lwasm_insn_normal},
+	
+	// extra ops that are ignored because they are generally only for
+	// pretty printing the listing
+	{ "nam",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_noop,		pseudo_resolve_noop,			lwasm_insn_normal},
+	{ "pag",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_noop,		pseudo_resolve_noop,			lwasm_insn_normal},
+	{ "ttl",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_noop,		pseudo_resolve_noop,			lwasm_insn_normal},
+
+	/* flag end of table */	
+	{ NULL,			{	-1, 	-1, 	-1, 	-1 },	insn_parse_inh,			insn_resolve_inh,				lwasm_insn_normal}
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwasm/instab.h	Fri Mar 12 06:01:38 2010 +0000
@@ -0,0 +1,55 @@
+/*
+instab.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 <http://www.gnu.org/licenses/>.
+
+
+Contains definitions for the instruction table
+*/
+
+#ifndef __instab_h_seen__
+#define __instab_h_seen__
+
+#include "lwasm.h"
+
+typedef struct
+{
+	char *opcode;				/* the mneumonic */
+	int ops[4];					/* opcode values for up to four addr modes */
+	void (*parse)(asmstate_t *as, line_t *l, char **optr);	/* parse operand for insn */
+	void (*resolve)(asmstate_t *as, line_t *l);				/* resolve instruction to code */
+	int flags;					/* flag for this instruction */
+} instab_t;
+
+enum
+{
+	lwasm_insn_normal = 0,
+	lwasm_insn_cond = 1,		/* conditional instruction */
+	lwasm_insn_endm = 2,		/* end of macro */
+	lwasm_insn_setsym = 4,		/* insn sets symbol address */
+	lwasm_insn_is6309 = 8		/* insn is 6309 only */
+};
+
+
+#define PARSEFUNC(fn)	void (fn)(asmstate_t *as, line_t *l, char **p)
+#define RESOLVEFUNC(fn)	void (fn)(asmstate_t *as, line_t *l)
+
+#ifndef __instab_c_seen__
+extern instab_t instab[];
+#endif //__instab_c_seen__
+
+#endif //__instab_h_seen__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwasm/lwasm.c	Fri Mar 12 06:01:38 2010 +0000
@@ -0,0 +1,49 @@
+/*
+lwasm.c
+
+Copyright © 2010 William Astle
+
+This file is part of LWTOOLS.
+
+LWTOOLS 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <config.h>
+
+#include <lw_expr.h>
+
+#include "lwasm.h"
+
+#define NULL 0;
+
+lw_expr_t lwasm_evaluate_var(char *var)
+{
+	return NULL;
+}
+
+lw_expr_t lwasm_evaluate_special(int t, void *ptr)
+{
+	switch (t)
+	{
+	case lwasm_expr_linelen:
+		{
+			line_t *cl = ptr;
+			if (cl -> len == -1)
+				return NULL;
+			return lw_expr_build(lw_expr_type_int, cl -> len);
+		}
+		break;
+	}
+	return NULL;
+}
--- a/lwasm/lwasm.h	Fri Mar 05 02:34:16 2010 +0000
+++ b/lwasm/lwasm.h	Fri Mar 12 06:01:38 2010 +0000
@@ -22,9 +22,15 @@
 #ifndef ___lwasm_h_seen___
 #define ___lwasm_h_seen___
 
+#include <lw_expr.h>
 #include <lw_stringlist.h>
 #include <lw_stack.h>
 
+enum
+{
+	lwasm_expr_linelen = 1
+};
+
 enum lwasm_output_e
 {
 	OUTPUT_DECB = 0,	// DECB multirecord format
@@ -57,6 +63,16 @@
 	PRAGMA_IMPORTUNDEFEXPORT = 0x0010	// imports symbol if undefined upon export
 };
 
+typedef struct line_s line_t;
+struct line_s
+{
+	lw_expr_t addr;						// assembly address of the line
+	int len;							// the "size" this line occupies (address space wise) (-1 if unknown)
+	int insn;							// number of insn in insn table
+	line_t *prev;
+	line_t *next;
+};
+
 typedef struct
 {
 	int output_format;					// output format
@@ -65,6 +81,9 @@
 	int flags;							// assembly flags
 	int pragmas;						// pragmas currently in effect
 
+	line_t *line_head;					// start of lines list
+	line_t *line_tail;					// tail of lines list
+
 	char *list_file;					// name of file to list to
 	char *output_file;					// output file name	
 	lw_stringlist_t input_files;		// files to assemble
--- a/lwasm/main.c	Fri Mar 05 02:34:16 2010 +0000
+++ b/lwasm/main.c	Fri Mar 12 06:01:38 2010 +0000
@@ -165,6 +165,8 @@
 assembler on the first file
 */
 extern void do_pass1(asmstate_t *as);
+extern void lwasm_evaluate_special(int t, void *ptr);
+extern void lwasm_evaluate_var(char *var);
 
 int main(int argc, char **argv)
 {
@@ -172,6 +174,9 @@
 	asmstate_t asmstate = { 0 };
 	program_name = argv[0];
 
+	lw_expr_set_special_handler(lwasm_evaluate_special);
+	lw_expr_set_var_handler(lwasm_evaluate_var);
+
 	/* initialize assembler state */
 	asmstate.include_list = lw_stringlist_create();
 	asmstate.input_files = lw_stringlist_create();
@@ -186,34 +191,6 @@
 
 	input_init(&asmstate);
 
-//	do_pass1(&asmstate);
-{
-	lw_expr_t te;
-	
-	te = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus,
-			lw_expr_build_noref(lw_expr_type_oper, lw_expr_oper_plus,
-				lw_expr_build_noref(lw_expr_type_oper, lw_expr_oper_times,
-					lw_expr_build_noref(lw_expr_type_int, 2),
-					lw_expr_build_noref(lw_expr_type_var, "tvar")
-				),
-				lw_expr_build_noref(lw_expr_type_oper, lw_expr_oper_times,
-					lw_expr_build_noref(lw_expr_type_var, "tvar"),
-					lw_expr_build_noref(lw_expr_type_int, 3)
-				)
-			),
-			lw_expr_build_noref(lw_expr_type_oper, lw_expr_oper_times,
-				lw_expr_build_noref(lw_expr_type_int, 16),
-				lw_expr_build_noref(lw_expr_type_var, "avar")
-			)
-		);
-	
-	lw_expr_print(te);
-	printf("\n");
-	
-	lw_expr_simplify(te);
-	lw_expr_print(te);
-	printf("\n");
-}
-
+	do_pass1(&asmstate);
 	exit(0);
 }
--- a/lwasm/pass1.c	Fri Mar 05 02:34:16 2010 +0000
+++ b/lwasm/pass1.c	Fri Mar 12 06:01:38 2010 +0000
@@ -28,16 +28,46 @@
 #include "lwasm.h"
 #include "input.h"
 
+/*
+pass 1: parse the lines
+*/
 void do_pass1(asmstate_t *as)
 {
 	char *line;
-	
+	line_t *cl;
+
 	for (;;)
 	{
 		line = input_readline(as);
 		if (!line)
 			break;
 		printf("%s\n", line);
+		
+		cl = lw_alloc(sizeof(line_t));
+		cl -> next = NULL;
+		cl -> prev = as -> line_tail;
+		cl -> len = -1;
+		cl -> insn = -1;
+		if (!as -> line_tail)
+		{
+			as -> line_head = cl;
+			cl -> addr = lw_expr_build(lw_expr_type_int, 0);
+		}
+		else
+		{
+			lw_expr_t te;
+			as -> line_tail -> next = cl;
+			te = lw_expr_build(lw_expr_type_special, lwasm_expr_linelen, cl -> prev);
+			cl -> addr = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, cl -> prev -> addr, te);
+			lw_expr_destroy(te);
+			lw_expr_simplify(cl -> addr);
+		}
+		as -> line_tail = cl;
+
+		lw_expr_print(cl -> addr);
+		printf("\n");
+		// now parse the line
+		
 		lw_free(line);
 	}
 }
--- a/lwlib/lw_expr.c	Fri Mar 05 02:34:16 2010 +0000
+++ b/lwlib/lw_expr.c	Fri Mar 12 06:01:38 2010 +0000
@@ -31,44 +31,58 @@
 #include "lw_error.h"
 #include "lw_string.h"
 
+static lw_expr_t (*evaluate_special)(int t, void *ptr) = NULL;
+static lw_expr_t (*evaluate_var)(char *var) = NULL;
+
+void lw_expr_set_special_handler(lw_expr_t (*fn)(int t, void *ptr))
+{
+	evaluate_special = fn;
+}
+
+void lw_expr_set_var_handler(lw_expr_t (*fn)(char *var))
+{
+	evaluate_var = fn;
+}
+
 lw_expr_t lw_expr_create(void)
 {
 	lw_expr_t r;
 	
 	r = lw_alloc(sizeof(struct lw_expr_priv));
-	r -> refcount = 1;
 	r -> operands = NULL;
 
 	return r;
 }
 
-/* useful for constant expression construction */
-/* lw_expr_deref(lw_expr_create(...)) */
-/* use of this function on an expression that is not already referenced by the caller */
-lw_expr_t lw_expr_deref(lw_expr_t r)
-{
-	r -> refcount--;
-	return r;
-}
-
 void lw_expr_destroy(lw_expr_t E)
 {
-	E -> refcount--;
-	if (E -> refcount <= 0)
-	{
-		struct lw_expr_opers *o;
-		for (o = E -> operands; o; o = o -> next)
-			lw_expr_destroy(o -> p);
-		if (E -> type == lw_expr_type_var)
-			lw_free(E -> value2);
-		lw_free(E);
-	}
+	struct lw_expr_opers *o;
+	for (o = E -> operands; o; o = o -> next)
+		lw_expr_destroy(o -> p);
+	if (E -> type == lw_expr_type_var)
+		lw_free(E -> value2);
+	lw_free(E);
 }
 
+/* actually duplicates the entire expression */
+void lw_expr_add_operand(lw_expr_t E, lw_expr_t O);
 lw_expr_t lw_expr_copy(lw_expr_t E)
 {
-	E -> refcount++;
-	return E;
+	lw_expr_t r, t;
+	struct lw_expr_opers *o;
+	
+	r = lw_alloc(sizeof(struct lw_expr_priv));
+	*r = *E;
+	r -> operands = NULL;
+	
+	if (E -> type == lw_expr_type_var)
+		r -> value2 = lw_strdup(E -> value2);
+	for (o = E -> operands; o; o = o -> next)
+	{
+		lw_expr_add_operand(r, lw_expr_copy(o -> p));
+	}
+	
+	return r;
 }
 
 void lw_expr_add_operand(lw_expr_t E, lw_expr_t O)
@@ -87,27 +101,6 @@
 		E -> operands = o;
 }
 
-/* actually duplicates the entire expression */
-lw_expr_t lw_expr_deepcopy(lw_expr_t E)
-{
-	lw_expr_t r, t;
-	struct lw_expr_opers *o;
-	
-	r = lw_alloc(sizeof(struct lw_expr_priv));
-	*r = *E;
-	r -> refcount = 1;
-	r -> operands = NULL;
-	
-	if (E -> type == lw_expr_type_var)
-		r -> value2 = lw_strdup(E -> value2);
-	for (o = E -> operands; o; o = o -> next)
-	{
-		lw_expr_add_operand(r, lw_expr_deref(lw_expr_deepcopy(o -> p)));
-	}
-	
-	return r;
-}
-
 lw_expr_t lw_expr_build_aux(int exprtype, va_list args)
 {
 	lw_expr_t r;
@@ -136,6 +129,7 @@
 		t = va_arg(args, int);
 		p = va_arg(args, char *);
 		r -> type = lw_expr_type_special;
+		r -> value = t;
 		r -> value2 = p;
 		break;
 
@@ -171,18 +165,6 @@
 	return r;
 }
 
-lw_expr_t lw_expr_build_noref(int exprtype, ...)
-{
-	va_list args;
-	lw_expr_t r;
-	
-	va_start(args, exprtype);
-	r = lw_expr_build_aux(exprtype, args);
-	r -> refcount--;
-	va_end(args);
-	return r;
-}
-
 void lw_expr_print(lw_expr_t E)
 {
 	struct lw_expr_opers *o;
@@ -375,12 +357,155 @@
 {
 	struct lw_expr_opers *o;
 
+again:
+	// try to resolve non-constant terms to constants here
+	if (E -> type == lw_expr_type_special && evaluate_special)
+	{
+		lw_expr_t te;
+		
+		te = evaluate_special(E -> value, E -> value2);
+		if (te)
+		{
+			for (o = E -> operands; o; o = o -> next)
+				lw_expr_destroy(o -> p);
+			if (E -> type == lw_expr_type_var)
+				lw_free(E -> value2);
+			*E = *te;
+			E -> operands = NULL;
+	
+			if (te -> type == lw_expr_type_var)
+				E -> value2 = lw_strdup(te -> value2);
+			for (o = te -> operands; o; o = o -> next)
+			{
+				lw_expr_add_operand(E, lw_expr_copy(o -> p));
+			}
+			lw_expr_destroy(te);
+			goto again;
+		}
+		return;
+	}
+
+	if (E -> type == lw_expr_type_var && evaluate_var)
+	{
+		lw_expr_t te;
+		
+		te = evaluate_var(E -> value2);
+		if (te)
+		{
+			for (o = E -> operands; o; o = o -> next)
+				lw_expr_destroy(o -> p);
+			if (E -> type == lw_expr_type_var)
+				lw_free(E -> value2);
+			*E = *te;
+			E -> operands = NULL;
+	
+			if (te -> type == lw_expr_type_var)
+				E -> value2 = lw_strdup(te -> value2);
+			for (o = te -> operands; o; o = o -> next)
+			{
+				lw_expr_add_operand(E, lw_expr_copy(o -> p));
+			}
+			lw_expr_destroy(te);
+			goto again;
+		}
+		return;
+	}
+
+	// non-operators have no simplification to do!
+	if (E -> type != lw_expr_type_oper)
+		return;
+
 	// sort "constants" to the start of each operand list for + and *
 	lw_expr_simplify_sortconstfirst(E);
 	
-	// non-operators have no simplification to do!
-	if (E -> type != lw_expr_type_oper)
+	// simplify operands
+	for (o = E -> operands; o; o = o -> next)
+		lw_expr_simplify(o -> p);
+
+	for (o = E -> operands; o; o = o -> next)
+	{
+		if (o -> p -> type != lw_expr_type_int)
+			break;
+	}
+
+	if (!o)
+	{
+		// we can do the operation here!
+		int tr = -42424242;
+		
+		switch (E -> value)
+		{
+		case lw_expr_oper_neg:
+			tr = -(E -> operands -> p -> value);
+			break;
+
+		case lw_expr_oper_com:
+			tr = ~(E -> operands -> p -> value);
+			break;
+		
+		case lw_expr_oper_plus:
+			tr = E -> operands -> p -> value;
+			for (o = E -> operands -> next; o; o = o -> next)
+				tr += o -> p -> value;
+			break;
+
+		case lw_expr_oper_minus:
+			tr = E -> operands -> p -> value;
+			for (o = E -> operands -> next; o; o = o -> next)
+				tr -= o -> p -> value;
+			break;
+
+		case lw_expr_oper_times:
+			tr = E -> operands -> p -> value;
+			for (o = E -> operands -> next; o; o = o -> next)
+				tr *= o -> p -> value;
+			break;
+
+		case lw_expr_oper_divide:
+			tr = E -> operands -> p -> value / E -> operands -> next -> p -> value;
+			break;
+		
+		case lw_expr_oper_mod:
+			tr = E -> operands -> p -> value % E -> operands -> next -> p -> value;
+			break;
+		
+		case lw_expr_oper_intdiv:
+			tr = E -> operands -> p -> value / E -> operands -> next -> p -> value;
+			break;
+
+		case lw_expr_oper_bwand:
+			tr = E -> operands -> p -> value & E -> operands -> next -> p -> value;
+			break;
+
+		case lw_expr_oper_bwor:
+			tr = E -> operands -> p -> value | E -> operands -> next -> p -> value;
+			break;
+
+		case lw_expr_oper_bwxor:
+			tr = E -> operands -> p -> value ^ E -> operands -> next -> p -> value;
+			break;
+
+		case lw_expr_oper_and:
+			tr = E -> operands -> p -> value && E -> operands -> next -> p -> value;
+			break;
+
+		case lw_expr_oper_or:
+			tr = E -> operands -> p -> value || E -> operands -> next -> p -> value;
+			break;
+		
+		}
+		
+		while (E -> operands)
+		{
+			o = E -> operands;
+			E -> operands = o -> next;
+			lw_expr_destroy(o -> p);
+			lw_free(o);
+		}
+		E -> type = lw_expr_type_int;
+		E -> value = tr;
 		return;
+	}
 
 	if (E -> value == lw_expr_oper_times)
 	{
@@ -438,9 +563,6 @@
 	}
 
 
-	for (o = E -> operands; o; o = o -> next)
-		lw_expr_simplify(o -> p);
-
 	if (E -> value == lw_expr_oper_plus)
 	{
 		int c = 0, t = 0;
@@ -461,7 +583,7 @@
 				o = E -> operands;
 				if (o -> p -> type != lw_expr_type_int || o -> p -> value != 0)
 				{
-					r = lw_expr_deepcopy(o -> p);
+					r = lw_expr_copy(o -> p);
 				}
 				E -> operands = o -> next;
 				lw_expr_destroy(o -> p);
--- a/lwlib/lw_expr.h	Fri Mar 05 02:34:16 2010 +0000
+++ b/lwlib/lw_expr.h	Fri Mar 12 06:01:38 2010 +0000
@@ -63,7 +63,6 @@
 	int type;							// type of term
 	int value;							// integer value
 	void *value2;						// misc pointer value
-	int refcount;						// reference count
 	struct lw_expr_opers *operands;		// ptr to list of operands (for operators)
 };
 
@@ -73,16 +72,16 @@
 typedef void * lw_expr_t;
 
 extern lw_expr_t lwexpr_create(void);
-extern void lwexpr_destroy(lw_expr_t E);
-extern lw_expr_t lw_expr_deref(lw_expr_t r);
+extern void lw_expr_destroy(lw_expr_t E);
 extern lw_expr_t lw_expr_copy(lw_expr_t E);
 extern void lw_expr_add_operand(lw_expr_t E, lw_expr_t O);
-extern lw_expr_t lw_expr_deepcopy(lw_expr_t E);
 extern lw_expr_t lw_expr_build(int exprtype, ...);
 extern void lw_expr_print(lw_expr_t E);
 extern int lw_expr_compare(lw_expr_t E1, lw_expr_t E2);
 extern void lw_expr_simplify(lw_expr_t E);
-extern lw_expr_t lw_expr_build_noref(int exprtype, ...);
+
+extern void lw_expr_set_special_handler(lw_expr_t (*fn)(int t, void *ptr));
+extern void lw_expr_set_var_handler(lw_expr_t (*fn)(char *var));
 
 #endif /* def ___lw_expr_c_seen___ */