changeset 408:2a94b2e64621

Started creation of lwdisasm
author lost@l-w.ca
date Mon, 02 Aug 2010 13:24:07 -0600
parents b2e007c28b8f
children cba03436c720
files .hgignore ChangeLog Makefile.am configure.ac lwdisasm/Makefile.am lwdisasm/instab.c lwdisasm/instab6309.c lwdisasm/lwdisasm.h lwdisasm/main.c
diffstat 9 files changed, 2126 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Fri Jul 23 19:53:43 2010 -0600
+++ b/.hgignore	Mon Aug 02 13:24:07 2010 -0600
@@ -6,6 +6,7 @@
 lwlink/lwobjdump
 lwar/lwar
 lwlib/liblw.a
+lwdisasm/lwdisasm
 link-warning.h
 
 syntax: regexp
--- a/ChangeLog	Fri Jul 23 19:53:43 2010 -0600
+++ b/ChangeLog	Mon Aug 02 13:24:07 2010 -0600
@@ -16,3 +16,4 @@
 Version 3.0
 
 [*] Completely new architecture for lwasm
+[+] Added LWDISASM, a disassembler
--- a/Makefile.am	Fri Jul 23 19:53:43 2010 -0600
+++ b/Makefile.am	Mon Aug 02 13:24:07 2010 -0600
@@ -1,4 +1,4 @@
 ACLOCAL_AMFLAGS = -I m4
-SUBDIRS = lib lwlib lwasm lwlink lwar
-DIST_SUBDIRS = lib lwlib lwasm lwlink lwar doc
+SUBDIRS = lib lwlib lwasm lwlink lwar lwdisasm
+DIST_SUBDIRS = lib lwlib lwasm lwlink lwar lwdisasm doc
 EXTRA_DIST = m4/gnulib-cache.m4
--- a/configure.ac	Fri Jul 23 19:53:43 2010 -0600
+++ b/configure.ac	Mon Aug 02 13:24:07 2010 -0600
@@ -12,6 +12,7 @@
 	lwasm/Makefile
 	lwlink/Makefile
 	lwar/Makefile
+	lwdisasm/Makefile
 	doc/Makefile
 ])
 AC_OUTPUT
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwdisasm/Makefile.am	Mon Aug 02 13:24:07 2010 -0600
@@ -0,0 +1,5 @@
+AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib -I$(top_builddir)/lwlib -I$(top_srcdir)/lwlib
+bin_PROGRAMS = lwdisasm
+lwdisasm_SOURCES = main.c instab.c instab6309.c
+lwdisasm_LDADD = -L$(top_builddir)/lib -L$(top_srcdir)/lib -L$(top_builddir)/lwlib -L$(top_srcdir)/lwlib -lgnu -llw
+EXTRA_DIST =  lwdisasm.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwdisasm/instab.c	Mon Aug 02 13:24:07 2010 -0600
@@ -0,0 +1,901 @@
+/*
+instab.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 <stdlib.h>
+
+#include "lwdisasm.h"
+
+/* 6809 instruction table */
+
+/* base page */
+instab_t page0_6809[] =
+{
+	{ "neg",	ADDR_DIR },
+	{ NULL },
+	{ NULL },
+	{ "com",	ADDR_DIR },
+	{ "lsr",	ADDR_DIR },
+	{ NULL },
+	{ "ror",	ADDR_DIR },
+	{ "asr",	ADDR_DIR },
+	{ "lsl",	ADDR_DIR },
+	{ "rol",	ADDR_DIR },
+	{ "dec",	ADDR_DIR },
+	{ NULL },
+	{ "inc",	ADDR_DIR },
+	{ "tst",	ADDR_DIR },
+	{ "jmp",	ADDR_DIR },
+	{ "clr",	ADDR_DIR },
+	
+	/* $10 */
+	{ "",		ADDR_PAGE1 },
+	{ "",		ADDR_PAGE2 },
+	{ "nop",	ADDR_INH },
+	{ "sync",	ADDR_INH },
+	{ NULL },
+	{ NULL },
+	{ "lbra",	ADDR_REL16 },
+	{ "lbsr",	ADDR_REL16 },
+	{ NULL },
+	{ "daa",	ADDR_INH },
+	{ "orcc",	ADDR_IMM8 },
+	{ NULL },
+	{ "andcc",	ADDR_IMM8 },
+	{ "sex",	ADDR_INH },
+	{ "exg",	ADDR_RTOR },
+	{ "tfr",	ADDR_RTOR },
+	
+	/* $20 */
+	{ "bra",	ADDR_REL8 },
+	{ "brn",	ADDR_REL8 },
+	{ "bhi",	ADDR_REL8 },
+	{ "bls",	ADDR_REL8 },
+	{ "bcc",	ADDR_REL8 },
+	{ "bcs",	ADDR_REL8 },
+	{ "bne",	ADDR_REL8 },
+	{ "beq",	ADDR_REL8 },
+	{ "bvc",	ADDR_REL8 },
+	{ "bvs",	ADDR_REL8 },
+	{ "bpl",	ADDR_REL8 },
+	{ "bmi",	ADDR_REL8 },
+	{ "bge",	ADDR_REL8 },
+	{ "blt",	ADDR_REL8 },
+	{ "bgt",	ADDR_REL8 },
+	{ "ble",	ADDR_REL8 },
+	
+	/* $30 */
+	{ "leax",	ADDR_IND },
+	{ "leay",	ADDR_IND },
+	{ "leas",	ADDR_IND },
+	{ "leau",	ADDR_IND },
+	{ "pshs",	ADDR_PSHPUL },
+	{ "puls",	ADDR_PSHPUL },
+	{ "pshu",	ADDR_PSHPUL },
+	{ "pulu",	ADDR_PSHPUL },
+	{ NULL },
+	{ "rts",	ADDR_INH },
+	{ "abx",	ADDR_INH },
+	{ "rti",	ADDR_INH },
+	{ "cwai",	ADDR_IMM8 },
+	{ "mul",	ADDR_INH },
+	{ NULL },
+	{ "swi",	ADDR_INH },
+
+	/* $40 */
+	{ "nega",	ADDR_INH },
+	{ NULL },
+	{ NULL },
+	{ "coma",	ADDR_INH },
+	{ "lsra",	ADDR_INH },
+	{ NULL },
+	{ "rora",	ADDR_INH },
+	{ "asra",	ADDR_INH },
+	{ "lsla",	ADDR_INH },
+	{ "rola",	ADDR_INH },
+	{ "deca",	ADDR_INH },
+	{ NULL },
+	{ "inca",	ADDR_INH },
+	{ "tsta",	ADDR_INH },
+	{ NULL },
+	{ "clra",	ADDR_INH },
+
+	/* $50 */
+	{ "negb",	ADDR_INH },
+	{ NULL },
+	{ NULL },
+	{ "comb",	ADDR_INH },
+	{ "lsrb",	ADDR_INH },
+	{ NULL },
+	{ "rorb",	ADDR_INH },
+	{ "asrb",	ADDR_INH },
+	{ "lslb",	ADDR_INH },
+	{ "rolb",	ADDR_INH },
+	{ "decb",	ADDR_INH },
+	{ NULL },
+	{ "incb",	ADDR_INH },
+	{ "tstb",	ADDR_INH },
+	{ NULL },
+	{ "clrb",	ADDR_INH },
+	
+	/* $60 */
+	{ "neg",	ADDR_IND },
+	{ NULL },
+	{ NULL },
+	{ "com",	ADDR_IND },
+	{ "lsr",	ADDR_IND },
+	{ NULL },
+	{ "ror",	ADDR_IND },
+	{ "asr",	ADDR_IND },
+	{ "lsl",	ADDR_IND },
+	{ "rol",	ADDR_IND },
+	{ "dec",	ADDR_IND },
+	{ NULL },
+	{ "inc",	ADDR_IND },
+	{ "tst",	ADDR_IND },
+	{ "jmp",	ADDR_IND },
+	{ "clr",	ADDR_IND },
+	
+	/* $70 */
+	{ "neg",	ADDR_EXT },
+	{ NULL },
+	{ NULL },
+	{ "com",	ADDR_EXT },
+	{ "lsr",	ADDR_EXT },
+	{ NULL },
+	{ "ror",	ADDR_EXT },
+	{ "asr",	ADDR_EXT },
+	{ "lsl",	ADDR_EXT },
+	{ "rol",	ADDR_EXT },
+	{ "dec",	ADDR_EXT },
+	{ NULL },
+	{ "inc",	ADDR_EXT },
+	{ "tst",	ADDR_EXT },
+	{ "jmp",	ADDR_EXT },
+	{ "clr",	ADDR_EXT },
+	
+	/* $80 */
+	{ "suba",	ADDR_IMM8 },
+	{ "cmpa",	ADDR_IMM8 },
+	{ "sbca",	ADDR_IMM8 },
+	{ "subd",	ADDR_IMM16 },
+	{ "anda",	ADDR_IMM8 },
+	{ "bita",	ADDR_IMM8 },
+	{ "lda",	ADDR_IMM8 },
+	{ NULL },
+	{ "eora",	ADDR_IMM8 },
+	{ "adca",	ADDR_IMM8 },
+	{ "ora",	ADDR_IMM8 },
+	{ "adda",	ADDR_IMM8 },
+	{ "cmpx",	ADDR_IMM16 },
+	{ "bsr",	ADDR_REL8 },
+	{ "ldx",	ADDR_IMM16 },
+	{ NULL },
+	
+	/* $90 */
+	{ "suba",	ADDR_DIR },
+	{ "cmpa",	ADDR_DIR },
+	{ "sbca",	ADDR_DIR },
+	{ "subd",	ADDR_DIR },
+	{ "anda",	ADDR_DIR },
+	{ "bita",	ADDR_DIR },
+	{ "lda",	ADDR_DIR },
+	{ "sta",	ADDR_DIR },
+	{ "eora",	ADDR_DIR },
+	{ "adca",	ADDR_DIR },
+	{ "ora",	ADDR_DIR },
+	{ "adda",	ADDR_DIR },
+	{ "cmpx",	ADDR_DIR },
+	{ "jsr",	ADDR_DIR },
+	{ "ldx",	ADDR_DIR },
+	{ "stx",	ADDR_DIR },
+	
+	/* $A0 */
+	{ "suba",	ADDR_IND },
+	{ "cmpa",	ADDR_IND },
+	{ "sbca",	ADDR_IND },
+	{ "subd",	ADDR_IND },
+	{ "anda",	ADDR_IND },
+	{ "bita",	ADDR_IND },
+	{ "lda",	ADDR_IND },
+	{ "sta",	ADDR_IND },
+	{ "eora",	ADDR_IND },
+	{ "adca",	ADDR_IND },
+	{ "ora",	ADDR_IND },
+	{ "adda",	ADDR_IND },
+	{ "cmpx",	ADDR_IND },
+	{ "jsr",	ADDR_IND },
+	{ "ldx",	ADDR_IND },
+	{ "stx",	ADDR_IND },
+	
+	/* $B0 */
+	{ "suba",	ADDR_EXT },
+	{ "cmpa",	ADDR_EXT },
+	{ "sbca",	ADDR_EXT },
+	{ "subd",	ADDR_EXT },
+	{ "anda",	ADDR_EXT },
+	{ "bita",	ADDR_EXT },
+	{ "lda",	ADDR_EXT },
+	{ "sta",	ADDR_EXT },
+	{ "eora",	ADDR_EXT },
+	{ "adca",	ADDR_EXT },
+	{ "ora",	ADDR_EXT },
+	{ "adda",	ADDR_EXT },
+	{ "cmpx",	ADDR_EXT },
+	{ "jsr",	ADDR_EXT },
+	{ "ldx",	ADDR_EXT },
+	{ "stx",	ADDR_EXT },
+
+	/* $C0 */
+	{ "subb",	ADDR_IMM8 },
+	{ "cmpb",	ADDR_IMM8 },
+	{ "sbcb",	ADDR_IMM8 },
+	{ "addd",	ADDR_IMM16 },
+	{ "andb",	ADDR_IMM8 },
+	{ "bitb",	ADDR_IMM8 },
+	{ "ldb",	ADDR_IMM8 },
+	{ NULL },
+	{ "eorb",	ADDR_IMM8 },
+	{ "adcb",	ADDR_IMM8 },
+	{ "orb",	ADDR_IMM8 },
+	{ "addb",	ADDR_IMM8 },
+	{ "ldd",	ADDR_IMM16 },
+	{ NULL },
+	{ "ldu",	ADDR_IMM16 },
+	{ NULL },
+	
+	/* $D0 */
+	{ "subb",	ADDR_DIR },
+	{ "cmpb",	ADDR_DIR },
+	{ "sbcb",	ADDR_DIR },
+	{ "addd",	ADDR_DIR },
+	{ "andb",	ADDR_DIR },
+	{ "bitb",	ADDR_DIR },
+	{ "ldb",	ADDR_DIR },
+	{ "stb",	ADDR_DIR },
+	{ "eorb",	ADDR_DIR },
+	{ "adcb",	ADDR_DIR },
+	{ "orb",	ADDR_DIR },
+	{ "addb",	ADDR_DIR },
+	{ "ldd",	ADDR_DIR },
+	{ "std",	ADDR_DIR },
+	{ "ldu",	ADDR_DIR },
+	{ "stu",	ADDR_DIR },
+	
+	/* $E0 */
+	{ "subb",	ADDR_IND },
+	{ "cmpb",	ADDR_IND },
+	{ "sbcb",	ADDR_IND },
+	{ "addd",	ADDR_IND },
+	{ "andb",	ADDR_IND },
+	{ "bitb",	ADDR_IND },
+	{ "ldb",	ADDR_IND },
+	{ "stb",	ADDR_IND },
+	{ "eorb",	ADDR_IND },
+	{ "adcb",	ADDR_IND },
+	{ "orb",	ADDR_IND },
+	{ "addb",	ADDR_IND },
+	{ "ldd",	ADDR_IND },
+	{ "std",	ADDR_IND },
+	{ "ldu",	ADDR_IND },
+	{ "stu",	ADDR_IND },
+	
+	/* $F0 */
+	{ "subb",	ADDR_EXT },
+	{ "cmpb",	ADDR_EXT },
+	{ "sbcb",	ADDR_EXT },
+	{ "addd",	ADDR_EXT },
+	{ "andb",	ADDR_EXT },
+	{ "bitb",	ADDR_EXT },
+	{ "ldb",	ADDR_EXT },
+	{ "stb",	ADDR_EXT },
+	{ "eorb",	ADDR_EXT },
+	{ "adcb",	ADDR_EXT },
+	{ "orb",	ADDR_EXT },
+	{ "addb",	ADDR_EXT },
+	{ "ldd",	ADDR_EXT },
+	{ "std",	ADDR_EXT },
+	{ "ldu",	ADDR_EXT },
+	{ "stu",	ADDR_EXT }
+};
+
+/* $10 prefix */
+instab_t page1_6809[] =
+{
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $10 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $20 */
+	{ NULL },
+	{ "lbrn",	ADDR_REL16 },
+	{ "lbhi",	ADDR_REL16 },
+	{ "lbls",	ADDR_REL16 },
+	{ "lbcc",	ADDR_REL16 },
+	{ "lbcs",	ADDR_REL16 },
+	{ "lbne",	ADDR_REL16 },
+	{ "lbeq",	ADDR_REL16 },
+	{ "lbvc",	ADDR_REL16 },
+	{ "lbvs",	ADDR_REL16 },
+	{ "lbpl",	ADDR_REL16 },
+	{ "lbmi",	ADDR_REL16 },
+	{ "lbge",	ADDR_REL16 },
+	{ "lblt",	ADDR_REL16 },
+	{ "lbgt",	ADDR_REL16 },
+	{ "lble",	ADDR_REL16 },
+	
+	/* $30 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "swi2",	ADDR_INH },
+
+	/* $40 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $50 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $60 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $70 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $80 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "cmpd",	ADDR_IMM16 },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "cmpy",	ADDR_IMM16 },
+	{ NULL },
+	{ "ldy",	ADDR_IMM16 },
+	{ NULL },
+
+	/* $90 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "cmpd",	ADDR_DIR },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "cmpy",	ADDR_DIR },
+	{ NULL },
+	{ "ldy",	ADDR_DIR },
+	{ "sty",	ADDR_DIR },
+
+	/* $A0 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "cmpd",	ADDR_IND },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "cmpy",	ADDR_IND },
+	{ NULL },
+	{ "ldy",	ADDR_IND },
+	{ "sty",	ADDR_IND },
+
+	/* $B0 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "cmpd",	ADDR_EXT },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "cmpy",	ADDR_EXT },
+	{ NULL },
+	{ "ldy",	ADDR_EXT },
+	{ "sty",	ADDR_EXT },
+
+	/* $C0 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "lds",	ADDR_IMM16 },
+	{ NULL },
+
+	/* $D0 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "lds",	ADDR_DIR },
+	{ "sts",	ADDR_DIR },
+
+	/* $E0 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "lds",	ADDR_IND },
+	{ "sts",	ADDR_IND },
+
+	/* $F0 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "lds",	ADDR_EXT },
+	{ "sts",	ADDR_EXT }
+};
+
+/* $11 prefix */
+instab_t page2_6809[] =
+{
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $10 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $20 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	
+	/* $30 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "swi3",	ADDR_INH },
+
+	/* $40 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $50 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $60 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $70 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $80 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "cmpu",	ADDR_IMM16 },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "cmps",	ADDR_IMM16 },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $90 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "cmpu",	ADDR_DIR },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "cmps",	ADDR_DIR },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $A0 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "cmpu",	ADDR_IND },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "cmps",	ADDR_IND },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $B0 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "cmpu",	ADDR_EXT },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "cmps",	ADDR_EXT },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $C0 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $D0 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $E0 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $F0 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwdisasm/instab6309.c	Mon Aug 02 13:24:07 2010 -0600
@@ -0,0 +1,901 @@
+/*
+instab6309.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 <stdlib.h>
+
+#include "lwdisasm.h"
+
+/* 6309 instruction table */
+
+/* base page */
+instab_t page0_6309[] =
+{
+	{ "neg",	ADDR_DIR },
+	{ "oim",	ADDR_IMM8DIR },
+	{ "aim",	ADDR_IMM8DIR },
+	{ "com",	ADDR_DIR },
+	{ "lsr",	ADDR_DIR },
+	{ "eim",	ADDR_IMM8DIR },
+	{ "ror",	ADDR_DIR },
+	{ "asr",	ADDR_DIR },
+	{ "lsl",	ADDR_DIR },
+	{ "rol",	ADDR_DIR },
+	{ "dec",	ADDR_DIR },
+	{ "tim",	ADDR_IMM8DIR },
+	{ "inc",	ADDR_DIR },
+	{ "tst",	ADDR_DIR },
+	{ "jmp",	ADDR_DIR },
+	{ "clr",	ADDR_DIR },
+	
+	/* $10 */
+	{ "",		ADDR_PAGE1 },
+	{ "",		ADDR_PAGE2 },
+	{ "nop",	ADDR_INH },
+	{ "sync",	ADDR_INH },
+	{ "sexw",	ADDR_INH },
+	{ NULL },
+	{ "lbra",	ADDR_REL16 },
+	{ "lbsr",	ADDR_REL16 },
+	{ NULL },
+	{ "daa",	ADDR_INH },
+	{ "orcc",	ADDR_IMM8 },
+	{ NULL },
+	{ "andcc",	ADDR_IMM8 },
+	{ "sex",	ADDR_INH },
+	{ "exg",	ADDR_RTOR },
+	{ "tfr",	ADDR_RTOR },
+	
+	/* $20 */
+	{ "bra",	ADDR_REL8 },
+	{ "brn",	ADDR_REL8 },
+	{ "bhi",	ADDR_REL8 },
+	{ "bls",	ADDR_REL8 },
+	{ "bcc",	ADDR_REL8 },
+	{ "bcs",	ADDR_REL8 },
+	{ "bne",	ADDR_REL8 },
+	{ "beq",	ADDR_REL8 },
+	{ "bvc",	ADDR_REL8 },
+	{ "bvs",	ADDR_REL8 },
+	{ "bpl",	ADDR_REL8 },
+	{ "bmi",	ADDR_REL8 },
+	{ "bge",	ADDR_REL8 },
+	{ "blt",	ADDR_REL8 },
+	{ "bgt",	ADDR_REL8 },
+	{ "ble",	ADDR_REL8 },
+	
+	/* $30 */
+	{ "leax",	ADDR_IND },
+	{ "leay",	ADDR_IND },
+	{ "leas",	ADDR_IND },
+	{ "leau",	ADDR_IND },
+	{ "pshs",	ADDR_PSHPUL },
+	{ "puls",	ADDR_PSHPUL },
+	{ "pshu",	ADDR_PSHPUL },
+	{ "pulu",	ADDR_PSHPUL },
+	{ NULL },
+	{ "rts",	ADDR_INH },
+	{ "abx",	ADDR_INH },
+	{ "rti",	ADDR_INH },
+	{ "cwai",	ADDR_IMM8 },
+	{ "mul",	ADDR_INH },
+	{ NULL },
+	{ "swi",	ADDR_INH },
+
+	/* $40 */
+	{ "nega",	ADDR_INH },
+	{ NULL },
+	{ NULL },
+	{ "coma",	ADDR_INH },
+	{ "lsra",	ADDR_INH },
+	{ NULL },
+	{ "rora",	ADDR_INH },
+	{ "asra",	ADDR_INH },
+	{ "lsla",	ADDR_INH },
+	{ "rola",	ADDR_INH },
+	{ "deca",	ADDR_INH },
+	{ NULL },
+	{ "inca",	ADDR_INH },
+	{ "tsta",	ADDR_INH },
+	{ NULL },
+	{ "clra",	ADDR_INH },
+
+	/* $50 */
+	{ "negb",	ADDR_INH },
+	{ NULL },
+	{ NULL },
+	{ "comb",	ADDR_INH },
+	{ "lsrb",	ADDR_INH },
+	{ NULL },
+	{ "rorb",	ADDR_INH },
+	{ "asrb",	ADDR_INH },
+	{ "lslb",	ADDR_INH },
+	{ "rolb",	ADDR_INH },
+	{ "decb",	ADDR_INH },
+	{ NULL },
+	{ "incb",	ADDR_INH },
+	{ "tstb",	ADDR_INH },
+	{ NULL },
+	{ "clrb",	ADDR_INH },
+	
+	/* $60 */
+	{ "neg",	ADDR_IND },
+	{ "oim",	ADDR_IMM8IND },
+	{ "aim",	ADDR_IMM8IND },
+	{ "com",	ADDR_IND },
+	{ "lsr",	ADDR_IND },
+	{ "eim",	ADDR_IMM8IND },
+	{ "ror",	ADDR_IND },
+	{ "asr",	ADDR_IND },
+	{ "lsl",	ADDR_IND },
+	{ "rol",	ADDR_IND },
+	{ "dec",	ADDR_IND },
+	{ "tim",	ADDR_IMM8IND },
+	{ "inc",	ADDR_IND },
+	{ "tst",	ADDR_IND },
+	{ "jmp",	ADDR_IND },
+	{ "clr",	ADDR_IND },
+	
+	/* $70 */
+	{ "neg",	ADDR_EXT },
+	{ "oim",	ADDR_IMM8EXT },
+	{ "aim",	ADDR_IMM8EXT },
+	{ "com",	ADDR_EXT },
+	{ "lsr",	ADDR_EXT },
+	{ "eim",	ADDR_IMM8EXT },
+	{ "ror",	ADDR_EXT },
+	{ "asr",	ADDR_EXT },
+	{ "lsl",	ADDR_EXT },
+	{ "rol",	ADDR_EXT },
+	{ "dec",	ADDR_EXT },
+	{ "tim",	ADDR_IMM8EXT },
+	{ "inc",	ADDR_EXT },
+	{ "tst",	ADDR_EXT },
+	{ "jmp",	ADDR_EXT },
+	{ "clr",	ADDR_EXT },
+	
+	/* $80 */
+	{ "suba",	ADDR_IMM8 },
+	{ "cmpa",	ADDR_IMM8 },
+	{ "sbca",	ADDR_IMM8 },
+	{ "subd",	ADDR_IMM16 },
+	{ "anda",	ADDR_IMM8 },
+	{ "bita",	ADDR_IMM8 },
+	{ "lda",	ADDR_IMM8 },
+	{ NULL },
+	{ "eora",	ADDR_IMM8 },
+	{ "adca",	ADDR_IMM8 },
+	{ "ora",	ADDR_IMM8 },
+	{ "adda",	ADDR_IMM8 },
+	{ "cmpx",	ADDR_IMM16 },
+	{ "bsr",	ADDR_REL8 },
+	{ "ldx",	ADDR_IMM16 },
+	{ NULL },
+	
+	/* $90 */
+	{ "suba",	ADDR_DIR },
+	{ "cmpa",	ADDR_DIR },
+	{ "sbca",	ADDR_DIR },
+	{ "subd",	ADDR_DIR },
+	{ "anda",	ADDR_DIR },
+	{ "bita",	ADDR_DIR },
+	{ "lda",	ADDR_DIR },
+	{ "sta",	ADDR_DIR },
+	{ "eora",	ADDR_DIR },
+	{ "adca",	ADDR_DIR },
+	{ "ora",	ADDR_DIR },
+	{ "adda",	ADDR_DIR },
+	{ "cmpx",	ADDR_DIR },
+	{ "jsr",	ADDR_DIR },
+	{ "ldx",	ADDR_DIR },
+	{ "stx",	ADDR_DIR },
+	
+	/* $A0 */
+	{ "suba",	ADDR_IND },
+	{ "cmpa",	ADDR_IND },
+	{ "sbca",	ADDR_IND },
+	{ "subd",	ADDR_IND },
+	{ "anda",	ADDR_IND },
+	{ "bita",	ADDR_IND },
+	{ "lda",	ADDR_IND },
+	{ "sta",	ADDR_IND },
+	{ "eora",	ADDR_IND },
+	{ "adca",	ADDR_IND },
+	{ "ora",	ADDR_IND },
+	{ "adda",	ADDR_IND },
+	{ "cmpx",	ADDR_IND },
+	{ "jsr",	ADDR_IND },
+	{ "ldx",	ADDR_IND },
+	{ "stx",	ADDR_IND },
+	
+	/* $B0 */
+	{ "suba",	ADDR_EXT },
+	{ "cmpa",	ADDR_EXT },
+	{ "sbca",	ADDR_EXT },
+	{ "subd",	ADDR_EXT },
+	{ "anda",	ADDR_EXT },
+	{ "bita",	ADDR_EXT },
+	{ "lda",	ADDR_EXT },
+	{ "sta",	ADDR_EXT },
+	{ "eora",	ADDR_EXT },
+	{ "adca",	ADDR_EXT },
+	{ "ora",	ADDR_EXT },
+	{ "adda",	ADDR_EXT },
+	{ "cmpx",	ADDR_EXT },
+	{ "jsr",	ADDR_EXT },
+	{ "ldx",	ADDR_EXT },
+	{ "stx",	ADDR_EXT },
+
+	/* $C0 */
+	{ "subb",	ADDR_IMM8 },
+	{ "cmpb",	ADDR_IMM8 },
+	{ "sbcb",	ADDR_IMM8 },
+	{ "addd",	ADDR_IMM16 },
+	{ "andb",	ADDR_IMM8 },
+	{ "bitb",	ADDR_IMM8 },
+	{ "ldb",	ADDR_IMM8 },
+	{ NULL },
+	{ "eorb",	ADDR_IMM8 },
+	{ "adcb",	ADDR_IMM8 },
+	{ "orb",	ADDR_IMM8 },
+	{ "addb",	ADDR_IMM8 },
+	{ "ldd",	ADDR_IMM16 },
+	{ "ldq",	ADDR_IMM32 },
+	{ "ldu",	ADDR_IMM16 },
+	{ NULL },
+	
+	/* $D0 */
+	{ "subb",	ADDR_DIR },
+	{ "cmpb",	ADDR_DIR },
+	{ "sbcb",	ADDR_DIR },
+	{ "addd",	ADDR_DIR },
+	{ "andb",	ADDR_DIR },
+	{ "bitb",	ADDR_DIR },
+	{ "ldb",	ADDR_DIR },
+	{ "stb",	ADDR_DIR },
+	{ "eorb",	ADDR_DIR },
+	{ "adcb",	ADDR_DIR },
+	{ "orb",	ADDR_DIR },
+	{ "addb",	ADDR_DIR },
+	{ "ldd",	ADDR_DIR },
+	{ "std",	ADDR_DIR },
+	{ "ldu",	ADDR_DIR },
+	{ "stu",	ADDR_DIR },
+	
+	/* $E0 */
+	{ "subb",	ADDR_IND },
+	{ "cmpb",	ADDR_IND },
+	{ "sbcb",	ADDR_IND },
+	{ "addd",	ADDR_IND },
+	{ "andb",	ADDR_IND },
+	{ "bitb",	ADDR_IND },
+	{ "ldb",	ADDR_IND },
+	{ "stb",	ADDR_IND },
+	{ "eorb",	ADDR_IND },
+	{ "adcb",	ADDR_IND },
+	{ "orb",	ADDR_IND },
+	{ "addb",	ADDR_IND },
+	{ "ldd",	ADDR_IND },
+	{ "std",	ADDR_IND },
+	{ "ldu",	ADDR_IND },
+	{ "stu",	ADDR_IND },
+	
+	/* $F0 */
+	{ "subb",	ADDR_EXT },
+	{ "cmpb",	ADDR_EXT },
+	{ "sbcb",	ADDR_EXT },
+	{ "addd",	ADDR_EXT },
+	{ "andb",	ADDR_EXT },
+	{ "bitb",	ADDR_EXT },
+	{ "ldb",	ADDR_EXT },
+	{ "stb",	ADDR_EXT },
+	{ "eorb",	ADDR_EXT },
+	{ "adcb",	ADDR_EXT },
+	{ "orb",	ADDR_EXT },
+	{ "addb",	ADDR_EXT },
+	{ "ldd",	ADDR_EXT },
+	{ "std",	ADDR_EXT },
+	{ "ldu",	ADDR_EXT },
+	{ "stu",	ADDR_EXT }
+};
+
+/* $10 prefix */
+instab_t page1_6309[] =
+{
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $10 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $20 */
+	{ NULL },
+	{ "lbrn",	ADDR_REL16 },
+	{ "lbhi",	ADDR_REL16 },
+	{ "lbls",	ADDR_REL16 },
+	{ "lbcc",	ADDR_REL16 },
+	{ "lbcs",	ADDR_REL16 },
+	{ "lbne",	ADDR_REL16 },
+	{ "lbeq",	ADDR_REL16 },
+	{ "lbvc",	ADDR_REL16 },
+	{ "lbvs",	ADDR_REL16 },
+	{ "lbpl",	ADDR_REL16 },
+	{ "lbmi",	ADDR_REL16 },
+	{ "lbge",	ADDR_REL16 },
+	{ "lblt",	ADDR_REL16 },
+	{ "lbgt",	ADDR_REL16 },
+	{ "lble",	ADDR_REL16 },
+	
+	/* $30 */
+	{ "addr",	ADDR_RTOR },
+	{ "adcr",	ADDR_RTOR },
+	{ "subr",	ADDR_RTOR },
+	{ "sbcr",	ADDR_RTOR },
+	{ "andr",	ADDR_RTOR },
+	{ "orr",	ADDR_RTOR },
+	{ "eorr",	ADDR_RTOR },
+	{ "cmpr",	ADDR_RTOR },
+	{ "pshsw",	ADDR_INH },
+	{ "pulsw",	ADDR_INH },
+	{ "pshuw",	ADDR_INH },
+	{ "puluw",	ADDR_INH },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "swi2",	ADDR_INH },
+
+	/* $40 */
+	{ "negd",	ADDR_INH },
+	{ NULL },
+	{ NULL },
+	{ "comd",	ADDR_INH },
+	{ "lsrd",	ADDR_INH },
+	{ NULL },
+	{ "rord",	ADDR_INH },
+	{ "asrd",	ADDR_INH },
+	{ "lsld",	ADDR_INH },
+	{ "rold",	ADDR_INH },
+	{ "decd",	ADDR_INH },
+	{ NULL },
+	{ "incd",	ADDR_INH },
+	{ "tstd",	ADDR_INH },
+	{ NULL },
+	{ "clrd",	ADDR_INH },
+
+	/* $50 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "comw",	ADDR_INH },
+	{ "lsrw",	ADDR_INH },
+	{ NULL },
+	{ "rorw",	ADDR_INH },
+	{ NULL },
+	{ NULL },
+	{ "rolw",	ADDR_INH },
+	{ "decw",	ADDR_INH },
+	{ NULL },
+	{ "incw",	ADDR_INH },
+	{ "tstw",	ADDR_INH },
+	{ NULL },
+	{ "clrw",	ADDR_INH },
+
+	/* $60 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $70 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $80 */
+	{ "subw",	ADDR_IMM16 },
+	{ "cmpw",	ADDR_IMM16 },
+	{ "sbcd",	ADDR_IMM16 },
+	{ "cmpd",	ADDR_IMM16 },
+	{ "andd",	ADDR_IMM16 },
+	{ "bitd",	ADDR_IMM16 },
+	{ "ldw",	ADDR_IMM16 },
+	{ NULL },
+	{ "eord",	ADDR_IMM16 },
+	{ "adcd",	ADDR_IMM16 },
+	{ "ord",	ADDR_IMM16 },
+	{ "addw",	ADDR_IMM16 },
+	{ "cmpy",	ADDR_IMM16 },
+	{ NULL },
+	{ "ldy",	ADDR_IMM16 },
+	{ NULL },
+
+	/* $90 */
+	{ "subw",	ADDR_DIR },
+	{ "cmpw",	ADDR_DIR },
+	{ "sbcd",	ADDR_DIR },
+	{ "cmpd",	ADDR_DIR },
+	{ "andd",	ADDR_DIR },
+	{ "bitd",	ADDR_DIR },
+	{ "ldw",	ADDR_DIR },
+	{ "stw",	ADDR_DIR },
+	{ "eord",	ADDR_DIR },
+	{ "adcd",	ADDR_DIR },
+	{ "ord",	ADDR_DIR },
+	{ "addw",	ADDR_DIR },
+	{ "cmpy",	ADDR_DIR },
+	{ NULL },
+	{ "ldy",	ADDR_DIR },
+	{ "sty",	ADDR_DIR },
+
+	/* $A0 */
+	{ "subw",	ADDR_IND },
+	{ "cmpw",	ADDR_IND },
+	{ "sbcd",	ADDR_IND },
+	{ "cmpd",	ADDR_IND },
+	{ "andd",	ADDR_IND },
+	{ "bitd",	ADDR_IND },
+	{ "ldw",	ADDR_IND },
+	{ "stw",	ADDR_IND },
+	{ "eord",	ADDR_IND },
+	{ "adcd",	ADDR_IND },
+	{ "ord",	ADDR_IND },
+	{ "addw",	ADDR_IND },
+	{ "cmpy",	ADDR_IND },
+	{ NULL },
+	{ "ldy",	ADDR_IND },
+	{ "sty",	ADDR_IND },
+
+	/* $B0 */
+	{ "subw",	ADDR_EXT },
+	{ "cmpw",	ADDR_EXT },
+	{ "adcd",	ADDR_EXT },
+	{ "cmpd",	ADDR_EXT },
+	{ "andd",	ADDR_EXT },
+	{ "bitd",	ADDR_EXT },
+	{ "ldw",	ADDR_EXT },
+	{ "stw",	ADDR_EXT },
+	{ "eord",	ADDR_EXT },
+	{ "adcd",	ADDR_EXT },
+	{ "ord",	ADDR_EXT },
+	{ "addw",	ADDR_EXT },
+	{ "cmpy",	ADDR_EXT },
+	{ NULL },
+	{ "ldy",	ADDR_EXT },
+	{ "sty",	ADDR_EXT },
+
+	/* $C0 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "lds",	ADDR_IMM16 },
+	{ NULL },
+
+	/* $D0 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "ldq",	ADDR_DIR },
+	{ "stq",	ADDR_DIR },
+	{ "lds",	ADDR_DIR },
+	{ "sts",	ADDR_DIR },
+
+	/* $E0 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "ldq",	ADDR_IND },
+	{ "stq",	ADDR_IND },
+	{ "lds",	ADDR_IND },
+	{ "sts",	ADDR_IND },
+
+	/* $F0 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "ldq",	ADDR_EXT },
+	{ "stq",	ADDR_EXT },
+	{ "lds",	ADDR_EXT },
+	{ "sts",	ADDR_EXT }
+};
+
+/* $11 prefix */
+instab_t page2_6309[] =
+{
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $10 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $20 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	
+	/* $30 */
+	{ "band",	ADDR_BITBIT },
+	{ "biand",	ADDR_BITBIT },
+	{ "bor",	ADDR_BITBIT },
+	{ "bior",	ADDR_BITBIT },
+	{ "beor",	ADDR_BITBIT },
+	{ "bieor",	ADDR_BITBIT },
+	{ "ldbt",	ADDR_BITBIT },
+	{ "stbt",	ADDR_BITBIT },
+	{ "tfm",	ADDR_TFMPP },
+	{ "tfm",	ADDR_TFMMM },
+	{ "tfm",	ADDR_TFMPC },
+	{ "tfm",	ADDR_TFMCP },
+	{ "bitmd",	ADDR_IMM8 },
+	{ "ldmd",	ADDR_IMM8 },
+	{ NULL },
+	{ "swi3",	ADDR_INH },
+
+	/* $40 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "come",	ADDR_INH },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "dece",	ADDR_INH },
+	{ NULL },
+	{ "ince",	ADDR_INH },
+	{ "tste",	ADDR_INH },
+	{ NULL },
+	{ "clre",	ADDR_INH },
+
+	/* $50 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "comf",	ADDR_INH },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "incf",	ADDR_INH },
+	{ NULL },
+	{ "decf",	ADDR_INH },
+	{ "tstf",	ADDR_INH },
+	{ NULL },
+	{ "clrf",	ADDR_INH },
+
+	/* $60 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $70 */
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $80 */
+	{ "sube",	ADDR_IMM8 },
+	{ "cmpe",	ADDR_IMM8 },
+	{ NULL },
+	{ "cmpu",	ADDR_IMM16 },
+	{ NULL },
+	{ NULL },
+	{ "lde",	ADDR_IMM8 },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "adde",	ADDR_IMM8 },
+	{ "cmps",	ADDR_IMM16 },
+	{ "divd",	ADDR_IMM8 },
+	{ "divq",	ADDR_IMM16 },
+	{ "muld",	ADDR_IMM16 },
+
+	/* $90 */
+	{ "sube",	ADDR_DIR },
+	{ "cmpe",	ADDR_DIR },
+	{ NULL },
+	{ "cmpu",	ADDR_DIR },
+	{ NULL },
+	{ NULL },
+	{ "lde",	ADDR_DIR },
+	{ "ste",	ADDR_DIR },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "adde",	ADDR_DIR },
+	{ "cmps",	ADDR_DIR },
+	{ "divd",	ADDR_DIR },
+	{ "divq",	ADDR_DIR },
+	{ "muld",	ADDR_DIR },
+
+	/* $A0 */
+	{ "sube",	ADDR_IND },
+	{ "cmpe",	ADDR_IND },
+	{ NULL },
+	{ "cmpu",	ADDR_IND },
+	{ NULL },
+	{ NULL },
+	{ "lde",	ADDR_IND },
+	{ "ste",	ADDR_IND },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "adde",	ADDR_IND },
+	{ "cmps",	ADDR_IND },
+	{ "divd",	ADDR_IND },
+	{ "divq",	ADDR_IND },
+	{ "muld",	ADDR_IND },
+
+	/* $B0 */
+	{ "sube",	ADDR_EXT },
+	{ "cmpe",	ADDR_EXT },
+	{ NULL },
+	{ "cmpu",	ADDR_EXT },
+	{ NULL },
+	{ NULL },
+	{ "lde",	ADDR_EXT },
+	{ "ste",	ADDR_EXT },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "adde",	ADDR_EXT },
+	{ "cmps",	ADDR_EXT },
+	{ "divd",	ADDR_EXT },
+	{ "divq",	ADDR_EXT },
+	{ "muld",	ADDR_EXT },
+
+	/* $C0 */
+	{ "subf",	ADDR_IMM8 },
+	{ "cmpf",	ADDR_IMM8 },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "ldf",	ADDR_IMM8 },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "addf",	ADDR_IMM8 },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $D0 */
+	{ "subf",	ADDR_DIR },
+	{ "cmpf",	ADDR_DIR },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "ldf",	ADDR_DIR },
+	{ "stf",	ADDR_DIR },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "addf",	ADDR_DIR },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $E0 */
+	{ "subf",	ADDR_IND },
+	{ "cmpf",	ADDR_IND },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "ldf",	ADDR_IND },
+	{ "stf",	ADDR_IND },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "addf",	ADDR_IND },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+
+	/* $F0 */
+	{ "subf",	ADDR_EXT },
+	{ "cmpf",	ADDR_EXT },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "ldf",	ADDR_EXT },
+	{ "stf",	ADDR_EXT },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ "addf",	ADDR_EXT },
+	{ NULL },
+	{ NULL },
+	{ NULL },
+	{ NULL }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwdisasm/lwdisasm.h	Mon Aug 02 13:24:07 2010 -0600
@@ -0,0 +1,95 @@
+/*
+lwdisasm.h
+
+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/>.
+*/
+
+#ifndef ____lwdisasm_h_seen____
+#define ____lwdisasm_h_seen____
+
+#include <stdint.h>
+
+enum
+{
+	INPUT_RAW = 0,
+	INPUT_DECB,
+	INPUT_OBJ,
+	INPUT_OS9
+};
+
+enum
+{
+	TARGET_6809 = 0,
+	TARGET_6309
+};
+
+enum
+{
+	ADDR_DIR = 0,
+	ADDR_EXT,
+	ADDR_IND,
+	ADDR_IMM8,
+	ADDR_IMM16,
+	ADDR_IMM32,
+	ADDR_INH,
+	ADDR_RTOR,
+	ADDR_PSHPUL,
+	ADDR_IMM8DIR,
+	ADDR_IMM8IND,
+	ADDR_IMM8EXT,
+	ADDR_BITBIT,
+	ADDR_REL8,
+	ADDR_REL16,
+	ADDR_PAGE1,
+	ADDR_PAGE2,
+	ADDR_TFMPP,
+	ADDR_TFMMM,
+	ADDR_TFMPC,
+	ADDR_TFMCP
+};
+
+typedef struct disasmstate_s
+{
+	int input_type;
+	int debug_level;
+	char *output_file;
+	char *input_file;
+	int target;
+	uint8_t *filedata;	// the file data
+	long filelen;		// length of the file data
+	int base;			// base address (raw)
+	int entry;			// entry address
+} disasmstate_t;
+
+
+
+typedef struct instab_s
+{
+	char *op;			// mneumonic
+	int addrmode;		// addressing mode
+} instab_t;
+
+extern instab_t page0_6809[];
+extern instab_t page1_6809[];
+extern instab_t page2_6809[];
+
+extern instab_t page0_6309[];
+extern instab_t page1_6309[];
+extern instab_t page2_6309[];
+
+#endif // ____lwdisasm_h_seen____
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwdisasm/main.c	Mon Aug 02 13:24:07 2010 -0600
@@ -0,0 +1,219 @@
+/*
+main.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 <argp.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <lw_alloc.h>
+#include <lw_string.h>
+
+#include "lwdisasm.h"
+
+/* command line option handling */
+const char *argp_program_version = "lwdisasmasm from " PACKAGE_STRING;
+const char *argp_program_bug_address = PACKAGE_BUGREPORT;
+char *program_name;
+
+static struct argp_option options[] =
+{
+	{ "output",		'o',	"FILE",		0,						"Output to FILE"},
+	{ "debug",		'd',	"LEVEL",	OPTION_ARG_OPTIONAL,	"Set debug mode"},
+	{ "format",		'f',	"TYPE",		0,						"Select input format: decb, raw, obj, os9"},
+	{ "decb",		'b',	0,			0,						"Read DECB .bin format input, equivalent of --format=decb"},
+	{ "raw",		'r',	0,			0,						"Read raw binary format input, equivalent of --format=raw"},
+	{ "obj",		0x100,	0,			0,						"Read proprietary object file format, equivalent of --format=obj" },
+	{ "6809",		'9',	0,			0,						"Set disassembler to 6809 only mode" },
+	{ "6309",		'3',	0,			0,						"Set disassembler to 6309 mode (default)" },
+	{ "data",		0x101,	"RANGE",	0,						"Set an address range as data" },
+	{ "code",		0x102,	"RANGE",	0,						"Set an address range as code" },
+	{ "entry",		0x103,	"ADDR",		0,						"Start disassembling at ADDR" },
+	{ "base",		0x104,	"ADDR",		0,						"Set the base address of a raw file" },
+	{ 0 }
+};
+
+
+static error_t parse_opts(int key, char *arg, struct argp_state *state)
+{
+	disasmstate_t *as = state -> input;
+	int rangelow, rangehigh;
+	char *e;
+	
+	switch (key)
+	{
+	
+	case 0x101: // data range
+		rangelow = strtol(arg, &e, 0);
+		if (*e != ':')
+		{
+			fprintf(stderr, "Invalid range: %s\n", arg);
+			exit(1);
+		}
+		rangehigh = strtol(e + 1, NULL, 0);
+		if (rangelow < 0 || rangehigh < 0 || rangehigh < rangelow)
+		{
+			fprintf(stderr, "Invalid range: %s\n", arg);
+			exit(1);
+		}
+		// register the range as data
+		break;
+		
+	case 0x102: // code range
+		rangelow = strtol(arg, &e, 0);
+		if (*e != ':')
+		{
+			fprintf(stderr, "Invalid range: %s\n", arg);
+			exit(1);
+		}
+		rangehigh = strtol(e + 1, NULL, 0);
+		if (rangelow < 0 || rangehigh < 0 || rangehigh < rangelow)
+		{
+			fprintf(stderr, "Invalid range: %s\n", arg);
+			exit(1);
+		}
+		// register the range as code
+		break;
+	
+	case 0x103: // entry
+		as -> entry = strtol(arg, NULL, 0);
+		break;
+		
+	case 0x104: // base
+		as -> base = strtol(arg, NULL, 0);
+		break;
+		
+	case 'o':
+		if (as -> output_file)
+			lw_free(as -> output_file);
+		as -> output_file = lw_strdup(arg);
+		break;
+
+	case 'd':
+		if (!arg)
+			as -> debug_level = 50;
+		else
+			as -> debug_level = atoi(arg);
+		break;
+
+	case 'b':
+		as -> input_type = INPUT_DECB;
+		break;
+
+	case 'r':
+		as -> input_type = INPUT_RAW;
+		break;
+
+	case 0x100:
+		as -> input_type = INPUT_OBJ;
+		break;
+
+	case 'f':
+		if (!strcasecmp(arg, "decb"))
+			as -> input_type = INPUT_DECB;
+		else if (!strcasecmp(arg, "raw"))
+			as -> input_type = INPUT_RAW;
+		else if (!strcasecmp(arg, "obj"))
+			as -> input_type = INPUT_OBJ;
+		else if (!strcasecmp(arg, "os9"))
+			as -> input_type = INPUT_OS9;
+		else
+		{
+			fprintf(stderr, "Invalid input format: %s\n", arg);
+			exit(1);
+		}
+		break;
+		
+	case '9':
+		as -> target = TARGET_6809;
+		break;
+
+	case '3':
+		as -> target = TARGET_6309;
+		break;
+
+	case ARGP_KEY_END:
+		break;
+	
+	case ARGP_KEY_ARG:
+		if (as -> input_file)
+		{
+			fprintf(stderr, "Only one input file allowed\n");
+			exit(1);
+		}
+		as -> input_file = lw_strdup(arg);
+		break;
+		
+	default:
+		return ARGP_ERR_UNKNOWN;
+	}
+	return 0;
+}
+
+static struct argp argp =
+{
+	options,
+	parse_opts,
+	"<input file>",
+	"LWDISASM, a HD6309 and MC6809 disassembler"
+};
+
+/*
+main function; parse command line, set up disassembler state, and run the 
+disassembler on the first file
+*/
+
+int main(int argc, char **argv)
+{
+	disasmstate_t as = { 0 };
+	FILE *fp;
+	
+	/* assembler state */
+	program_name = argv[0];
+
+	/* parse command line arguments */	
+	argp_parse(&argp, argc, argv, 0, 0, &as);
+
+	if (as.input_file == NULL)
+	{
+		fprintf(stderr, "No input files specified.\n");
+		exit(1);
+	}
+	
+	fp = fopen(as.input_file, "rb");
+	if (!fp)
+	{
+		perror("Cannot open input file");
+		exit(1);
+	}
+
+	fseek(fp, 0, SEEK_END);
+	as.filelen = ftell(fp);
+	rewind(fp);
+	
+	as.filedata = lw_alloc(as.filelen);
+	0 == fread(as.filedata, as.filelen, 1, fp);
+
+	fclose(fp);
+
+	exit(0);
+}