# HG changeset patch
# User lost@l-w.ca
# Date 1280794024 21600
# Node ID cba03436c7207445e48fdc38f9189a671e53f1df
# Parent 2a94b2e64621278c36f445a50a30a381ca08f056
Checkpoint disassembler
diff -r 2a94b2e64621 -r cba03436c720 lwdisasm/Makefile.am
--- a/lwdisasm/Makefile.am Mon Aug 02 13:24:07 2010 -0600
+++ b/lwdisasm/Makefile.am Mon Aug 02 18:07:04 2010 -0600
@@ -1,5 +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_SOURCES = main.c instab.c instab6309.c range.c do_raw.c insn.c misc.c symbol.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
diff -r 2a94b2e64621 -r cba03436c720 lwdisasm/do_raw.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lwdisasm/do_raw.c Mon Aug 02 18:07:04 2010 -0600
@@ -0,0 +1,74 @@
+/*
+do_raw.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 .
+*/
+
+#include
+
+#include
+#include
+
+#include "lwdisasm.h"
+
+void do_disasm_raw(disasmstate_t *as)
+{
+ linedata_t *l;
+ symbol_t *s;
+ char bytebuf[11];
+ int i;
+
+ // initialize disassembly
+ as -> curoff = as -> entry;
+ as -> crange = lookup_range(as, as -> curoff);
+
+
+ while (l = disasm_insn(as))
+ {
+ if (!as -> ltail)
+ as -> lhead = l;
+ else
+ as -> ltail -> next = l;
+ l -> prev = as -> ltail;
+ as -> ltail = l;
+
+ if (l -> target != -1)
+ {
+ s = register_symbol(as, l -> target, l -> sectionref, NULL);
+ l -> symbol = s;
+ }
+ }
+
+ attach_symbols(as);
+
+ for (l = as -> lhead; l; l = l -> next)
+ {
+ if (l -> target != -1)
+ redisasm_insn(as, l);
+ }
+
+ for (l = as -> lhead; l; l = l -> next)
+ {
+ bytebuf[0] = 0;
+ for (i = 0; i < l -> length; i++)
+ {
+ sprintf(bytebuf, "%s%02X", bytebuf, l -> bytes[i]);
+ }
+ printf("%04X %-10s %-15s %s\n", l -> address, bytebuf, l -> isref ? l -> symbol -> symbol : "", l -> disasm);
+ }
+}
diff -r 2a94b2e64621 -r cba03436c720 lwdisasm/insn.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lwdisasm/insn.c Mon Aug 02 18:07:04 2010 -0600
@@ -0,0 +1,568 @@
+/*
+insn.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 .
+*/
+
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include "lwdisasm.h"
+
+/*
+this function creates a linedata_t with the disassembly of the
+current location; returns NULL if the current disassembly point
+is not a valid instruction or we are at the end of the input
+*/
+
+#define fb(d) do { int ____t; ____t = fetch_byte(as); if (____t < 0) return NULL; bytes[len++] = ____t; (d) = ____t; } while (0)
+#define fb2(d) do { int ____t; ____t = fetch_byte(as); if (____t < 0) return "?"; bytes[(*len)++] = ____t; (d) = ____t; } while (0)
+
+char *encode_target(disasmstate_t *as, int addr, int section)
+{
+ symbol_t *s;
+ static char buffer[256];
+
+ s = find_symbol(as, addr, section);
+ if (!s)
+ {
+ sprintf(buffer, "$%04X", addr);
+ return buffer;
+ }
+ else
+ {
+ return s -> symbol;
+ }
+}
+
+char *decode_indexed(disasmstate_t *as, char *bytes, int *len, int *target, int section)
+{
+ int pb, b1, b2;
+ int rn;
+ static char *rs[] = { "x", "y", "u", "s", "pcr" };
+ static char str[40];
+ char *i1 = "", *i2 = "";
+ char *tstr;
+ *target = -1;
+
+ fb2(pb);
+
+ rn = (pb >> 5) & 3;
+
+ if (pb < 0x80)
+ {
+ // 5 bit
+ b1 = pb & 15;
+ if (pb & 16)
+ b1 = b1 - 16;
+
+ sprintf(str, "%d,%s", b1, rs[rn]);
+ return str;
+ }
+ if ((pb & 0x1F) == 0x1F)
+ {
+ // extended indirect
+ fb2(b1);
+ fb2(b2);
+ sprintf(str, "[$%04X]", (b1 << 8) | b2);
+ return str;
+ }
+
+ if (pb & 0x10)
+ {
+ i1 = "[";
+ i2 = "]";
+ }
+
+ switch (pb & 0x0F)
+ {
+ case 0: // ,r+
+ if (*i1 == '[')
+ {
+ break;
+ }
+ sprintf(str, "%s,%s+%s", i1, rs[rn], i2);
+ return str;
+
+ case 1: // ,r++
+ sprintf(str, "%s,%s++%s", i1, rs[rn], i2);
+ return str;
+
+ case 2: // ,-r
+ if (*i1 == '[')
+ {
+ break;
+ }
+ sprintf(str, "%s,-%s%s", i1, rs[rn], i2);
+ return str;
+
+ case 3: // ,--r
+ sprintf(str, "%s,--%s%s", i1, rs[rn], i2);
+ return str;
+
+ case 4: // ,r
+ sprintf(str, "%s,%s%s", i1, rs[rn], i2);
+ return str;
+
+ case 5: // B,r
+ sprintf(str, "%sb,%s%s", i1, rs[rn], i2);
+ return str;
+
+ case 6: // A,r
+ sprintf(str, "%sa,%s%s", i1, rs[rn], i2);
+ return str;
+
+ case 8: // 8 bit,r
+ fb2(b1);
+ if (b1 > 128)
+ b1 -= 256;
+ sprintf(str, "%s<$%02X,%s%s", i1, b1, rs[rn], i2);
+ return str;
+
+ case 9: // 16 bit,r
+ fb2(b1);
+ fb2(b2);
+ b1 = (b1 << 8) | b2;
+ if (b2 > 32768)
+ b2 -= 65536;
+ sprintf(str, "%s>$%04X,%s%s", i1, b1, rs[rn], i2);
+ return str;
+
+ case 11: // D,r
+ sprintf(str, "%sd,%s%s", i1, rs[rn], i2);
+ return str;
+
+ case 12: // 8 bit,PCR
+ fb2(b1);
+ if (b1 > 127)
+ b1 -= 256;
+ b1 += as -> curoff;
+ b1 &= 0xFFFF;
+ sprintf(str, "%s<%s,pcr%s", i1, encode_target(as, b1, section), i2);
+ *target = b1;
+ return str;
+
+ case 13: // 16 bit,PCR
+ fb2(b1);
+ fb2(b2);
+ b1 = (b1 << 8) | b2;
+ b1 += as -> curoff;
+ b1 &= 0xFFFF;
+ sprintf(str, "%s>%s,pcr%s", i1, encode_target(as, b1, section), i2);
+ *target = b1;
+ return str;
+ }
+
+ // if we got here, we have an illegal 6809
+ if (as -> target == TARGET_6809)
+ {
+ sprintf(str, "?");
+ return str;
+ }
+
+ // now sort out 6309 operations
+ pb &= 0x1F;
+
+ switch (pb)
+ {
+ case 0x07:
+ case 0x17:
+ // E,r
+ sprintf(str, "%se,%s%s", i1, rs[rn], i2);
+ return str;
+
+ case 0x0A:
+ case 0x1A:
+ // F,r
+ sprintf(str, "%sf,%s%s", i1, rs[rn], i2);
+ return str;
+
+ case 0x0E:
+ case 0x1E:
+ // W,r
+ sprintf(str, "%sw,%s%s", i1, rs[rn], i2);
+ return str;
+
+ case 0x0F:
+ case 0x10:
+ // W indexing
+ switch (rn)
+ {
+ case 0: // ,W
+ sprintf(str, "%s,w%s", i1, i2);
+ return str;
+
+ case 1: // 16 bit,W
+ fb2(b1);
+ fb2(b2);
+ b1 = (b1 << 8) | b2;
+ if (b1 > 32768)
+ b1 -= 65536;
+ sprintf(str, "%s>$%04X,w%s", i1, b1, i2);
+ return str;
+
+ case 2: // ,W++
+ sprintf(str, "%s,w++%s", i1, i2);
+ return str;
+
+ case 3: // ,--W
+ sprintf(str, "%s,--w%s", i1, i2);
+ return str;
+ }
+ }
+
+ sprintf(str, "?");
+ return str;
+}
+
+char *decode_operand(disasmstate_t *as, int addrmode, uint8_t *bytes, int *len, int *target, int section)
+{
+ int b1, b2, b3, b4;
+ static char insnbuffer[256];
+ char *t;
+ static char *rlist3[] = { "D", "X", "Y", "U", "S", "PC", "W", "V", "A", "B", "CC", "DP", "0", "0", "E", "F" };
+ static char *rlist8[] = { "D", "X", "Y", "U", "S", "PC", "?", "?", "A", "B", "CC", "DP", "?", "?", "?", "?" };
+ char **rlist = (as -> target == TARGET_6809) ? rlist8 : rlist3;
+
+ switch (addrmode)
+ {
+ case ADDR_IMM8:
+ fb2(b1);
+ sprintf(insnbuffer, "#$%02X", b1);
+ break;
+
+ case ADDR_IMM16:
+ fb2(b1);
+ fb2(b2);
+ sprintf(insnbuffer, "#$%04X", (b1 << 8) | b2);
+ break;
+
+ case ADDR_IMM32:
+ fb2(b1);
+ fb2(b2);
+ fb2(b3);
+ fb2(b4);
+ sprintf(insnbuffer, "#$%08X", (b1 << 24) | (b2 << 16) | (b3 << 8) | b4);
+ break;
+
+ case ADDR_DIR:
+ fb2(b1);
+ sprintf(insnbuffer, "<%s", encode_target(as, (as -> dpval << 8) | b1, section));
+ *target = as -> dpval * 256 + b1;
+ break;
+
+ case ADDR_EXT:
+ fb2(b1);
+ fb2(b2);
+ sprintf(insnbuffer, ">%s", encode_target(as, (b1 << 8) | b2, section));
+ *target = (b1 << 8) | b2;
+ break;
+
+ case ADDR_INH:
+ *insnbuffer = 0;
+ break;
+
+ case ADDR_IMM8DIR:
+ fb2(b1);
+ fb2(b2);
+ sprintf(insnbuffer, "#$%02X;<%s", b1, encode_target(as, (as -> dpval << 8) | b2, section));
+ *target = (as -> dpval << 8) | b2;
+ break;
+
+ case ADDR_IMM8EXT:
+ fb2(b1);
+ fb2(b2);
+ fb2(b3);
+ sprintf(insnbuffer, "#$%02X;>%s", b1, encode_target(as, (b2 << 8) | b3, section));
+ *target = (b2 << 8) | b3;
+ break;
+
+ case ADDR_IMM8IND:
+ fb2(b1);
+ t = decode_indexed(as, bytes, len, target, section);
+ sprintf(insnbuffer, "#$%02X;%s", b1, t);
+ break;
+
+ case ADDR_IND:
+ t = decode_indexed(as, bytes, len, target, section);
+ sprintf(insnbuffer, "%s", t);
+ break;
+
+ case ADDR_RTOR:
+ fb2(b1);
+ b2 = b1 & 0x0F;
+ b1 = b1 >> 4;
+ sprintf(insnbuffer, "%s,%s", rlist[b1], rlist[b2]);
+ break;
+
+ case ADDR_BITBIT:
+ fb2(b1);
+ fb2(b2);
+ sprintf(insnbuffer, "%s,%d,%d;<%s",
+ (b1 >> 6 == 0) ? "CC" : ((b1 >> 6 == 1) ? "A" : ((b1 >> 6 == 2) ? "B" : "?")),
+ (b1 >> 3) & 7, b1 & 7, encode_target(as, (as -> dpval << 8) | b2, section));
+ *target = (as -> dpval << 8) | b2;
+ break;
+
+ case ADDR_PSHPULS:
+ insnbuffer[0] = 0;
+ fb2(b1);
+ if (b1 & 0x01)
+ {
+ strcat(insnbuffer, ",cc");
+ }
+ if (b1 & 0x02)
+ {
+ strcat(insnbuffer, ",a");
+ }
+ if (b1 & 0x04)
+ {
+ strcat(insnbuffer, ",b");
+ }
+ if (b1 & 0x08)
+ {
+ strcat(insnbuffer, ",dp");
+ }
+ if (b1 & 0x10)
+ {
+ strcat(insnbuffer, "x");
+ }
+ if (b1 & 0x20)
+ {
+ strcat(insnbuffer, "y");
+ }
+ if (b1 & 0x40)
+ {
+ strcat(insnbuffer, "u");
+ }
+ if (b1 & 0x80)
+ {
+ strcat(insnbuffer, "pc");
+ }
+ return insnbuffer + 1;
+ break;
+
+ case ADDR_PSHPULU:
+ insnbuffer[0] = 0;
+ fb2(b1);
+ if (b1 & 0x01)
+ {
+ strcat(insnbuffer, ",cc");
+ }
+ if (b1 & 0x02)
+ {
+ strcat(insnbuffer, ",a");
+ }
+ if (b1 & 0x04)
+ {
+ strcat(insnbuffer, ",b");
+ }
+ if (b1 & 0x08)
+ {
+ strcat(insnbuffer, ",dp");
+ }
+ if (b1 & 0x10)
+ {
+ strcat(insnbuffer, "x");
+ }
+ if (b1 & 0x20)
+ {
+ strcat(insnbuffer, "y");
+ }
+ if (b1 & 0x40)
+ {
+ strcat(insnbuffer, "s");
+ }
+ if (b1 & 0x80)
+ {
+ strcat(insnbuffer, "pc");
+ }
+ return insnbuffer + 1;
+
+ case ADDR_REL8:
+ fb2(b1);
+ if (b1 > 127)
+ b1 -= 256;
+ b1 += as -> curoff;
+ b1 &= 0xFFFF;
+ sprintf(insnbuffer, "%s", encode_target(as, b1, section));
+ *target = b1;
+ break;
+
+ case ADDR_REL16:
+ fb2(b1);
+ if (b1 > 32767)
+ b1 -= 65536;
+ b1 += as -> curoff;
+ b1 &= 0xFFFF;
+ sprintf(insnbuffer, "%s", encode_target(as, b1, section));
+ *target = b2;
+ break;
+
+ case ADDR_TFMPP:
+ fb2(b1);
+ b2 = b1 & 0x0F;
+ b1 >>= 4;
+ sprintf(insnbuffer, "%s+,%s+", rlist[b1], rlist[b2]);
+ break;
+
+ case ADDR_TFMMM:
+ fb2(b1);
+ b2 = b1 & 0x0F;
+ b1 >>= 4;
+ sprintf(insnbuffer, "%s-,%s-", rlist[b1], rlist[b2]);
+ break;
+
+ case ADDR_TFMPC:
+ fb2(b1);
+ b2 = b1 & 0x0F;
+ b1 >>= 4;
+ sprintf(insnbuffer, "%s+,%s", rlist[b1], rlist[b2]);
+ break;
+
+ case ADDR_TFMCP:
+ fb2(b1);
+ b2 = b1 & 0x0F;
+ b1 >>= 4;
+ sprintf(insnbuffer, "%s,%s+", rlist[b1], rlist[b2]);
+ break;
+
+ default:
+ sprintf(insnbuffer, "????");
+ break;
+ }
+
+ return insnbuffer;
+}
+
+linedata_t *disasm_insn(disasmstate_t *as)
+{
+ int curbyte;
+ int b1;
+ linedata_t *l;
+ char *opcode;
+ int addrmode;
+ char insnbuffer[256];
+ char *t;
+ int addr;
+ int len = 0;
+ int8_t bytes[10];
+ int target = -1;
+
+ addr = as -> curoff;
+
+ fb(curbyte);
+ if (curbyte < 0)
+ return NULL;
+
+ opcode = as->page0[curbyte].op;
+ addrmode = as->page0[curbyte].addrmode;
+
+ if (addrmode == ADDR_PAGE1)
+ {
+ fb(b1);
+ if (b1 < 0)
+ return NULL;
+ opcode = as->page1[b1].op;
+ addrmode = as->page1[b1].addrmode;
+ curbyte = (curbyte << 8) | b1;
+ }
+ else if (addrmode == ADDR_PAGE2)
+ {
+ fb(b1);
+ if (b1 < 0)
+ return NULL;
+ opcode = as->page2[b1].op;
+ addrmode = as->page2[b1].addrmode;
+ curbyte = (curbyte << 8) | b1;
+ }
+
+ if (opcode == NULL)
+ return NULL;
+
+ t = decode_operand(as, addrmode, bytes, &len, &target, 0);
+
+ if (!t)
+ return NULL;
+
+ // now create the line structure
+ l = lw_alloc(sizeof(linedata_t));
+ l -> next = NULL;
+ l -> prev = NULL;
+ l -> address = addr;
+ l -> type = type_code;
+ l -> length = len;
+ l -> bytes = lw_alloc(len);
+ memmove(l -> bytes, bytes, len);
+ l -> isref = 0;
+ l -> symbol = NULL;
+ l -> sectionref = 0;
+ sprintf(insnbuffer, "%s %s", opcode, t);
+ l -> disasm = lw_strdup(insnbuffer);
+ l -> target = target;
+ return l;
+}
+
+void redisasm_insn(disasmstate_t *as, linedata_t *l)
+{
+ char *opcode;
+ int addrmode;
+ int len = 0;
+ char bytes[15];
+ int target = -1;
+ char *t;
+ char insnbuf[256];
+ int ta;
+ int ts;
+
+ // short circuit if no target in this one
+ if (l -> target == -1)
+ return;
+
+ opcode = as -> page0[l -> bytes[0]].op;
+ addrmode = as -> page0[l -> bytes[0]].addrmode;
+
+ ta = as -> curoff;
+ as -> curoff = l -> address + 1;
+
+ if (addrmode == ADDR_PAGE1)
+ {
+ opcode = as -> page1[l -> bytes[1]].op;
+ addrmode = as -> page1[l -> bytes[1]].addrmode;
+ as -> curoff++;
+ }
+ else if (addrmode == ADDR_PAGE2)
+ {
+ opcode = as -> page2[l -> bytes[1]].op;
+ addrmode = as -> page2[l -> bytes[1]].addrmode;
+ as -> curoff++;
+ }
+
+ t = decode_operand(as, addrmode, bytes, &len, &target, l -> sectionref);
+
+ // now create the line structure
+ lw_free(l -> disasm);
+ sprintf(insnbuf, "%s %s", opcode, t);
+ l -> disasm = lw_strdup(insnbuf);
+}
diff -r 2a94b2e64621 -r cba03436c720 lwdisasm/instab.c
--- a/lwdisasm/instab.c Mon Aug 02 13:24:07 2010 -0600
+++ b/lwdisasm/instab.c Mon Aug 02 18:07:04 2010 -0600
@@ -88,10 +88,10 @@
{ "leay", ADDR_IND },
{ "leas", ADDR_IND },
{ "leau", ADDR_IND },
- { "pshs", ADDR_PSHPUL },
- { "puls", ADDR_PSHPUL },
- { "pshu", ADDR_PSHPUL },
- { "pulu", ADDR_PSHPUL },
+ { "pshs", ADDR_PSHPULS },
+ { "puls", ADDR_PSHPULS },
+ { "pshu", ADDR_PSHPULU },
+ { "pulu", ADDR_PSHPULU },
{ NULL },
{ "rts", ADDR_INH },
{ "abx", ADDR_INH },
diff -r 2a94b2e64621 -r cba03436c720 lwdisasm/instab6309.c
--- a/lwdisasm/instab6309.c Mon Aug 02 13:24:07 2010 -0600
+++ b/lwdisasm/instab6309.c Mon Aug 02 18:07:04 2010 -0600
@@ -88,10 +88,10 @@
{ "leay", ADDR_IND },
{ "leas", ADDR_IND },
{ "leau", ADDR_IND },
- { "pshs", ADDR_PSHPUL },
- { "puls", ADDR_PSHPUL },
- { "pshu", ADDR_PSHPUL },
- { "pulu", ADDR_PSHPUL },
+ { "pshs", ADDR_PSHPULS },
+ { "puls", ADDR_PSHPULS },
+ { "pshu", ADDR_PSHPULU },
+ { "pulu", ADDR_PSHPULU },
{ NULL },
{ "rts", ADDR_INH },
{ "abx", ADDR_INH },
diff -r 2a94b2e64621 -r cba03436c720 lwdisasm/lwdisasm.h
--- a/lwdisasm/lwdisasm.h Mon Aug 02 13:24:07 2010 -0600
+++ b/lwdisasm/lwdisasm.h Mon Aug 02 18:07:04 2010 -0600
@@ -48,7 +48,8 @@
ADDR_IMM32,
ADDR_INH,
ADDR_RTOR,
- ADDR_PSHPUL,
+ ADDR_PSHPULS,
+ ADDR_PSHPULU,
ADDR_IMM8DIR,
ADDR_IMM8IND,
ADDR_IMM8EXT,
@@ -63,6 +64,47 @@
ADDR_TFMCP
};
+
+typedef struct rangedata_s rangedata_t;
+struct rangedata_s
+{
+ int min;
+ int max;
+ int type;
+ rangedata_t *next;
+ rangedata_t *prev;
+};
+
+typedef struct symbol_s symbol_t;
+struct symbol_s
+{
+ int address;
+ int section;
+ char *symbol;
+ symbol_t *next;
+};
+
+typedef struct linedata_s linedata_t;
+struct linedata_s
+{
+ int address;
+ int sectionref;
+ int length;
+ int type;
+ int target;
+ char *disasm;
+ uint8_t *bytes;
+ int isref;
+ symbol_t *symbol;
+ linedata_t *next;
+ linedata_t *prev;
+};
+typedef struct instab_s
+{
+ char *op; // mneumonic
+ int addrmode; // addressing mode
+} instab_t;
+
typedef struct disasmstate_s
{
int input_type;
@@ -74,16 +116,24 @@
long filelen; // length of the file data
int base; // base address (raw)
int entry; // entry address
+ int dpval; // DP value
+ linedata_t *lhead; // start of lines table
+ linedata_t *ltail; // end of lines table
+ rangedata_t *rhead; // start of range table
+ rangedata_t *rtail; // end of range table
+
+ instab_t *page0; // instruction table 0
+ instab_t *page1; // instruction table 1
+ instab_t *page2; // instruction table 2
+
+ int curoff; // current disassembly point
+ rangedata_t *crange; // current range
+
+ symbol_t *symbols; // symbol tables
} 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[];
@@ -92,4 +142,18 @@
extern instab_t page1_6309[];
extern instab_t page2_6309[];
+enum
+{
+ type_code = 0,
+ type_data = 1
+};
+
+extern void register_range(disasmstate_t *as, int min, int max, int type);
+extern rangedata_t *lookup_range(disasmstate_t *as, int addr);
+extern int fetch_byte(disasmstate_t *as);
+extern linedata_t *disasm_insn(disasmstate_t *as);
+extern symbol_t *register_symbol(disasmstate_t *as, int addr, int section, char *symbol);
+extern void attach_symbols(disasmstate_t *as);
+extern void redisasm_insn(disasmstate_t *as, linedata_t *l);
+extern symbol_t *find_symbol(disasmstate_t *as, int addr, int section);
#endif // ____lwdisasm_h_seen____
diff -r 2a94b2e64621 -r cba03436c720 lwdisasm/main.c
--- a/lwdisasm/main.c Mon Aug 02 13:24:07 2010 -0600
+++ b/lwdisasm/main.c Mon Aug 02 18:07:04 2010 -0600
@@ -76,6 +76,7 @@
exit(1);
}
// register the range as data
+ register_range(as, rangelow, rangehigh, type_data);
break;
case 0x102: // code range
@@ -92,6 +93,7 @@
exit(1);
}
// register the range as code
+ register_range(as, rangelow, rangehigh, type_code);
break;
case 0x103: // entry
@@ -182,6 +184,8 @@
disassembler on the first file
*/
+void do_disasm_raw(disasmstate_t *as);
+
int main(int argc, char **argv)
{
disasmstate_t as = { 0 };
@@ -215,5 +219,38 @@
fclose(fp);
+ switch (as.target)
+ {
+ case TARGET_6309:
+ as.page0 = page0_6309;
+ as.page1 = page1_6309;
+ as.page2 = page2_6309;
+ break;
+
+ case TARGET_6809:
+ as.page0 = page0_6809;
+ as.page1 = page1_6809;
+ as.page2 = page2_6809;
+ break;
+
+ default:
+ as.page0 = page0_6809;
+ as.page1 = page1_6809;
+ as.page2 = page2_6809;
+ break;
+
+ }
+
+ switch (as.input_type)
+ {
+ case INPUT_RAW:
+ do_disasm_raw(&as);
+ break;
+
+ default:
+ fprintf(stderr, "Input type is not currently implemented\n");
+ exit(1);
+ }
+
exit(0);
}
diff -r 2a94b2e64621 -r cba03436c720 lwdisasm/misc.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lwdisasm/misc.c Mon Aug 02 18:07:04 2010 -0600
@@ -0,0 +1,36 @@
+/*
+misc.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 .
+*/
+
+#include
+
+#include
+
+#include "lwdisasm.h"
+
+/* add support for misc fetchers here */
+/* return -1 if no more input */
+int fetch_byte(disasmstate_t *as)
+{
+ if (as -> curoff == as -> filelen)
+ return -1;
+
+ return as -> filedata[as -> curoff++];
+}
diff -r 2a94b2e64621 -r cba03436c720 lwdisasm/range.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lwdisasm/range.c Mon Aug 02 18:07:04 2010 -0600
@@ -0,0 +1,124 @@
+/*
+range.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 .
+*/
+
+#include
+
+#include
+
+#include
+
+#include "lwdisasm.h"
+
+void register_range(disasmstate_t *as, int min, int max, int type)
+{
+ rangedata_t *nr;
+ rangedata_t *r;
+
+ // first remove any complete subsets of the new range
+subsetagain:
+ for (r = as -> rhead; r; r = r -> next)
+ {
+ // if we haven't run into an existing range yet, short circuit
+ if (r -> min >= min && r -> max <= max)
+ {
+ if (r -> prev)
+ r -> prev -> next = r -> next;
+ else
+ as -> rhead = r -> next;
+ if (r -> next)
+ r -> next -> prev = r -> prev;
+ else
+ as -> rtail = r -> prev;
+ goto subsetagain;
+ }
+ }
+
+ // now shorten any subset that overlaps below or overlaps above
+ for (r = as -> rhead; r; r = r -> next)
+ {
+ // are we a subset of this range?
+ if (r -> min <= min && r -> max >= max)
+ {
+ // proper subset; split
+ nr = lw_alloc(sizeof(rangedata_t));
+ *nr = *r;
+ r -> next = nr;
+ nr -> prev = r;
+ r -> max = min - 1;
+ nr -> min = max + 1;
+ break;
+ }
+ // overlap above us
+ if (r -> max > max && r -> min < max)
+ {
+ r -> min = max + 1;
+ }
+ // overlap on the bottom
+ if (r -> min < min && r -> max > min)
+ {
+ r -> max = min - 1;
+ }
+ }
+
+ // now add new range
+ for (r = as -> rhead; r; r = r -> next)
+ {
+ if (r -> min < max)
+ {
+ break;
+ }
+ }
+
+ nr = lw_alloc(sizeof(rangedata_t));
+ nr -> min = min;
+ nr -> max = max;
+ nr -> type = type;
+
+ if (r)
+ {
+ if (r -> prev)
+ r -> prev -> next = nr;
+ else
+ as -> rhead = nr;
+ nr -> prev = r -> prev;
+ nr -> next = r;
+ r -> prev = nr;
+ }
+ else
+ {
+ nr -> next = NULL;
+ nr -> prev = as -> rtail;
+ as -> rtail -> next = nr;
+ as -> rtail = nr;
+ }
+}
+
+rangedata_t *lookup_range(disasmstate_t *as, int addr)
+{
+ rangedata_t *r;
+
+ for (r = as -> rhead; r; r = r -> next)
+ {
+ if (r -> min <= addr && r -> max >= addr)
+ return r;
+ }
+ return NULL;
+}
diff -r 2a94b2e64621 -r cba03436c720 lwdisasm/symbol.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lwdisasm/symbol.c Mon Aug 02 18:07:04 2010 -0600
@@ -0,0 +1,93 @@
+/*
+symbol.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 .
+*/
+
+#include
+
+#include
+
+#include
+#include
+
+#include "lwdisasm.h"
+
+symbol_t *find_symbol(disasmstate_t *as, int addr, int section)
+{
+ symbol_t *s;
+
+ for (s = as -> symbols; s; s = s -> next)
+ {
+ if (s -> address == addr && s -> section == section)
+ return s;
+ }
+ return NULL;
+}
+
+symbol_t *register_symbol(disasmstate_t *as, int addr, int section, char *symbol)
+{
+ char symbuf[200];
+ symbol_t *s;
+
+ for (s = as -> symbols; s; s = s -> next)
+ {
+ if (s -> address == addr && s -> section == section)
+ return s;
+ }
+
+ if (!symbol)
+ {
+ if (section)
+ {
+ sprintf(symbuf, "L%d_%04X", section, addr);
+ }
+ else
+ {
+ sprintf(symbuf, "L%04X", addr);
+ }
+ symbol = symbuf;
+ }
+
+ s = lw_alloc(sizeof(symbol_t));
+ s -> symbol = lw_strdup(symbol);
+ s -> address = addr;
+ s -> section = section;
+ s -> next = as -> symbols;
+ as -> symbols = s;
+ return s;
+}
+
+void attach_symbols(disasmstate_t *as)
+{
+ symbol_t *s;
+ linedata_t *l;
+
+ for (s = as -> symbols; s; s = s -> next)
+ {
+ for (l = as -> lhead; l; l = l -> next)
+ {
+ if (l -> isref == 0 && l -> address == s -> address && l -> sectionref == s -> section)
+ {
+ l -> symbol = s;
+ l -> isref = 1;
+ break;
+ }
+ }
+ }
+}