changeset 0:9a224bd9b45f

os9 emulation
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 02 Jul 2018 02:12:31 +0900
parents
children 3c736a81b886
files Makefile a09.c engine.c io.c makerom.c mon2.asm monitor.asm os9/Makefile os9/crc.c os9/makerom.c os9/os9.h os9/os9disass.c os9/os9mod.c os9crc.c v09.c v09.h v09s.c v09st.c
diffstat 18 files changed, 14393 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile	Mon Jul 02 02:12:31 2018 +0900
@@ -0,0 +1,87 @@
+#
+# Makefile Sim6809
+#
+# created 1994 by L.C. Benschop
+# 2013-10-28 - Jens Diemer: add "clean" section
+# 2014-06-25 - J.E. Klasek
+#
+# copyleft (c) 1994-2014 by the sbc09 team, see AUTHORS for more details.
+# license: GNU General Public License version 2, see LICENSE for more details.
+#
+
+# CFLAGS=-O3 -fomit-frame-pointer -DTERM_CONTROL
+CFLAGS=-g  -DTERM_CONTROL
+
+V09FLAGS= -DUSE_TERMIOS #-DBIG_ENDIAN
+
+
+SIM_BIN=v09s v09st 
+
+APPS=mon2.s
+
+# will be installed to ".."
+BIN=a09 v09 $(SIM_BIN) v09.rom
+
+TARGETS=$(BIN) $(APPS)
+
+OTHER=monitor.s makerom
+
+all: $(TARGETS)
+
+# ------------------------------------
+
+a09: a09.c os9crc.c
+
+v09: v09.o engine.o io.o os9disass.o
+	$(CC) -o v09 $(CFLAGS) v09.o engine.o io.o os9disass.o
+
+v09.o: v09.c v09.h
+	$(CC) -c $(CFLAGS) $(V09FLAGS) v09.c
+
+os9disass.o : os9/os9disass.c
+	$(CC) -c -DNO_MAIN -Wno-format-security $(CFLAGS) $(V09FLAGS) $< -o os9disass.o
+
+engine.o: engine.c v09.h
+	$(CC) -c $(CFLAGS) $(V09FLAGS) engine.c
+
+io.o: io.c v09.h
+	$(CC) -c $(CFLAGS) $(V09FLAGS) io.c
+
+v09.rom: makerom monitor.s 
+	./makerom <monitor.s
+
+monitor.s: monitor.asm
+	./a09 -s monitor.s -l monitor.lst monitor.asm
+
+mon2.s: mon2.asm
+	./a09 -s mon2.s -l mon2.lst mon2.asm
+
+makerom: makerom.c
+	$(CC) -o makerom makerom.c
+
+# ------------------------------------
+
+v09s: v09s.c
+
+v09st: v09s.c
+	$(CC) $(CFLAGS) -DTRACE -o $@ $<
+
+# ------------------------------------
+
+install:
+	-for bin in $(BIN); do \
+	  [ -r $$bin ] && cp -p $$bin .. && echo "installing ../$$bin ..." ;\
+	done ;\
+	exit 0
+
+# ------------------------------------
+
+cleanall: clean
+	rm -f $(TARGETS) $(OTHER)
+	(cd ..; rm -f $(BIN) )
+
+clean:
+	rm -f core *.BAK *.o *.lst
+
+# ------------------------------------
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/a09.c	Mon Jul 02 02:12:31 2018 +0900
@@ -0,0 +1,1544 @@
+/* A09, 6809 Assembler.
+
+   created 1993,1994 by L.C. Benschop.
+   copyleft (c) 1994-2014 by the sbc09 team, see AUTHORS for more details.
+   license: GNU General Public License version 2, see LICENSE for more details.
+   THERE IS NO WARRANTY ON THIS PROGRAM. 
+
+   Generates binary image file from the lowest to
+   the highest address with actually assembled data.
+
+   Machine dependencies:
+                  char is 8 bits.
+                  short is 16 bits.
+                  integer arithmetic is twos complement.
+
+   syntax a09 [-o filename] [-l filename] sourcefile.
+
+   Options
+   -o filename name of the output file (default name minus a09 suffix)
+   -s filename name of the s-record output file (default its a binary file)
+   -l filename list file name (default no listing)
+   -d enable debugging
+
+   recognized pseudoops:
+    extern public
+    macro endm if else endif
+    org equ set setdp
+    fcb fcw fdb fcc rmb
+    end include title
+
+   Not all of these are actually IMPLEMENTED!!!!!! 
+
+   Revisions:
+        1993-11-03 v0.1 
+                Initial version.
+        1994/03/21 v0.2
+                Fixed PC relative addressing bug
+                Added SET, SETDP, INCLUDE. IF/ELSE/ENDIF
+                No macros yet, and no separate linkable modules.
+        2012-06-04 j at klasek at
+                New: debugging parameter/option.
+                Fixed additional possible issue PC relative addressing.
+                Compatibility: Octal number prefix "&".
+        2014-07-15 j at klasek at
+                Fixed usage message.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#define NLABELS 2048
+#define MAXIDLEN 16
+#define MAXLISTBYTES 8
+#define FNLEN 30
+#define LINELEN 128
+
+static int debug=0;
+
+struct oprecord{char * name;
+                unsigned char cat;
+                unsigned short code;};
+
+/* Instruction categories:
+   0 one byte oprcodes   NOP
+   1 two byte opcodes    SWI2
+   2 opcodes w. imm byte ANDCC
+   3 LEAX etc.
+   4 short branches. BGE
+   5 long branches 2byte opc LBGE
+   6 long branches 1byte opc LBRA
+   7 accumulator instr.      ADDA
+   8 double reg instr 1byte opc LDX
+   9 double reg instr 2 byte opc LDY
+   10 single address instrs NEG
+   11 TFR, EXG
+   12 push,pull
+   13 pseudoops
+*/
+
+struct oprecord optable[]={
+  {"ABX",0,0x3a},{"ADCA",7,0x89},{"ADCB",7,0xc9},
+  {"ADDA",7,0x8b},{"ADDB",7,0xcb},{"ADDD",8,0xc3},
+  {"ANDA",7,0X84},{"ANDB",7,0xc4},{"ANDCC",2,0x1c},
+  {"ASL",10,0x08},{"ASLA",0,0x48},{"ASLB",0,0x58},
+  {"ASR",10,0x07},{"ASRA",0,0x47},{"ASRB",0,0x57},
+  {"BCC",4,0x24},{"BCS",4,0x25},{"BEQ",4,0x27},
+  {"BGE",4,0x2c},{"BGT",4,0x2e},{"BHI",4,0x22},
+  {"BHS",4,0x24},{"BITA",7,0x85},{"BITB",7,0xc5},
+  {"BLE",4,0x2f},{"BLO",4,0x25},{"BLS",4,0x23},
+  {"BLT",4,0x2d},{"BMI",4,0x2b},{"BNE",4,0x26},
+  {"BPL",4,0x2a},{"BRA",4,0x20},{"BRN",4,0x21},
+  {"BSR",4,0x8d},
+  {"BVC",4,0x28},{"BVS",4,0x29},
+  {"CLC",1,0x1cfe},{"CLF",1,0x1cbf},{"CLI",1,0x1cef},
+  {"CLIF",1,0x1caf},
+  {"CLR",10,0x0f},{"CLRA",0,0x4f},{"CLRB",0,0x5f},
+  {"CLV",1,0x1cfd},
+  {"CMPA",7,0x81},{"CMPB",7,0xc1},{"CMPD",9,0x1083},
+  {"CMPS",9,0x118c},{"CMPU",9,0x1183},{"CMPX",8,0x8c},
+  {"CMPY",9,0x108c},
+  {"COM",10,0x03},{"COMA",0,0x43},{"COMB",0,0x53},
+  {"CWAI",2,0x3c},{"DAA",0,0x19},
+  {"DEC",10,0x0a},{"DECA",0,0x4a},{"DECB",0,0x5a},
+  {"DES",1,0x327f},{"DEU",1,0x335f},{"DEX",1,0x301f},
+  {"DEY",1,0x313f},
+  {"ELSE",13,1},
+  {"EMOD",13,25},
+  {"END",13,2},
+  {"ENDC",13,3},
+  {"ENDIF",13,3},
+  {"ENDM",13,4},
+  {"EORA",7,0x88},{"EORB",7,0xc8},
+  {"EQU",13,5},{"EXG",11,0x1e},{"EXTERN",13,6},
+  {"FCB",13,7},{"FCC",13,8},
+  {"FCS",13,23},
+  {"FCW",13,9},
+  {"FDB",13,9},
+  {"IF",13,10},
+  {"IFEQ",13,29},
+  {"IFGT",13,30},
+  {"IFNE",13,28},
+  {"IFP1",13,21},
+  {"INC",10,0x0c},{"INCA",0,0x4c},{"INCB",0,0x5c},
+  {"INCLUDE",13,16},
+  {"INS",1,0x3261},{"INU",1,0x3341},{"INX",1,0x3001},
+  {"INY",1,0x3121},{"JMP",10,0x0e},{"JSR",8,0x8d},
+  {"LBCC",5,0x1024},{"LBCS",5,0x1025},{"LBEQ",5,0x1027},
+  {"LBGE",5,0x102c},{"LBGT",5,0x102e},{"LBHI",5,0x1022},
+  {"LBHS",5,0x1024},
+  {"LBLE",5,0x102f},{"LBLO",5,0x1025},{"LBLS",5,0x1023},
+  {"LBLT",5,0x102d},{"LBMI",5,0x102b},{"LBNE",5,0x1026},
+  {"LBPL",5,0x102a},{"LBRA",6,0x16},{"LBRN",5,0x1021},
+  {"LBSR",6,0x17},
+  {"LBVC",5,0x1028},{"LBVS",5,0x1029},
+  {"LDA",7,0x86},{"LDB",7,0xc6},{"LDD",8,0xcc},
+  {"LDS",9,0x10ce},{"LDU",8,0xce},{"LDX",8,0x8e},
+  {"LDY",9,0x108e},{"LEAS",3,0x32},
+  {"LEAU",3,0x33},{"LEAX",3,0x30},{"LEAY",3,0x31},
+  {"LSL",10,0x08},{"LSLA",0,0x48},{"LSLB",0,0x58},
+  {"LSR",10,0x04},{"LSRA",0,0x44},{"LSRB",0,0x54},
+  {"MACRO",13,11},
+  {"MOD",13,24},
+  {"MUL",0,0x3d},
+  {"NAM",13,26},
+  {"NEG",10,0x00},{"NEGA",0,0x40},{"NEGB",0,0x50},
+  {"NOP",0,0x12},
+  {"OPT",13,19},
+  {"ORA",7,0x8a},{"ORB",7,0xca},{"ORCC",2,0x1a},
+  {"ORG",13,12},
+  {"OS9",13,32},
+  {"PAG",13,20}, {"PAGE",13,20},
+  {"PSHS",12,0x34},{"PSHU",12,0x36},{"PUBLIC",13,13},
+  {"PULS",12,0x35},{"PULU",12,0x37},{"RMB",13,0},
+  {"ROL",10,0x09},{"ROLA",0,0x49},{"ROLB",0,0x59},
+  {"ROR",10,0x06},{"RORA",0,0x46},{"RORB",0,0x56},
+  {"RTI",0,0x3b},{"RTS",0,0x39},
+  {"SBCA",7,0x82},{"SBCB",7,0xc2},
+  {"SEC",1,0x1a01},{"SEF",1,0x1a40},{"SEI",1,0x1a10},
+  {"SEIF",1,0x1a50},{"SET",13,15},
+  {"SETDP",13,14},{"SEV",1,0x1a02},{"SEX",0,0x1d},
+  {"STA",7,0x87},{"STB",7,0xc7},{"STD",8,0xcd},
+  {"STS",9,0x10cf},{"STU",8,0xcf},{"STX",8,0x8f},
+  {"STY",9,0x108f},
+  {"SUBA",7,0x80},{"SUBB",7,0xc0},{"SUBD",8,0x83},
+  {"SWI",0,0x3f},{"SWI2",1,0x103f},{"SWI3",1,0x113f},
+  {"SYNC",0,0x13},{"TFR",11,0x1f},
+  {"TITLE",13,18},
+  {"TST",10,0x0d},{"TSTA",0,0x4d},{"TSTB",0,0x5d},
+  {"TTL",13,18},
+  {"USE",13,27},
+};
+
+struct symrecord{char name[MAXIDLEN+1];
+                 char cat;
+                 unsigned short value;
+                };
+
+int symcounter=0;
+
+/* Symbol categories.
+   0 Constant value (from equ).
+   1 Variable value (from set)
+   2 Address within program module (label).
+   3 Variable containing address.
+   4 Adress in other program module (extern)
+   5 Variable containing external address.
+   6 Unresolved address.
+   7 Variable containing unresolved address.
+   8 Public label.
+   9 Macro definition.
+  10 Public label (yet undefined).
+  11 parameter name.
+  12 local label.
+  13 empty.
+*/
+
+struct symrecord symtable[NLABELS];
+
+void processfile(char *name);
+
+struct oprecord * findop(char * nm)
+/* Find operation (mnemonic) in table using binary search */
+{
+ int lo,hi,i,s;
+ lo=0;hi=sizeof(optable)/sizeof(optable[0])-1;
+ do {
+  i=(lo+hi)/2;
+  s=strcmp(optable[i].name,nm);
+  if(s<0) lo=i+1;
+  else if(s>0) hi=i-1;
+  else break;
+ } while(hi>=lo);
+ if (s) return NULL;
+ return optable+i;
+}
+
+struct symrecord * findsym(char * nm)
+/* finds symbol table record; inserts if not found
+   uses binary search, maintains sorted table */
+{
+ int lo,hi,i,j,s;
+ lo=0;hi=symcounter-1;
+ s=1;i=0;
+ while (hi>=lo) {
+  i=(lo+hi)/2;
+  s=strcmp(symtable[i].name,nm);
+  if(s<0) lo=i+1;
+  else if(s>0) hi=i-1;
+  else break;
+ }
+ if(s) {
+  i=(s<0?i+1:i);
+  if(symcounter==NLABELS) {
+   fprintf(stderr,"Sorry, no storage for symbols!!!");
+   exit(4);
+  }
+  for(j=symcounter;j>i;j--) symtable[j]=symtable[j-1];
+  symcounter++;
+  strcpy(symtable[i].name,nm);
+  symtable[i].cat=13;
+ }
+ return symtable+i;
+}
+
+FILE *listfile,*objfile;
+char *listname,*objname,*srcname,*curname;
+int lineno;
+
+void
+outsymtable()
+{
+ int i,j=0;
+ fprintf(listfile,"\nSYMBOL TABLE");
+ for(i=0;i<symcounter;i++)
+ if(symtable[i].cat!=13) {
+  if(j%4==0)fprintf(listfile,"\n");
+  fprintf(listfile,"%10s %02d %04x",symtable[i].name,symtable[i].cat,
+                       symtable[i].value);
+  j++;
+ }
+ fprintf(listfile,"\n");
+}
+
+struct regrecord{char *name;unsigned char tfr,psh;};
+struct regrecord regtable[]=
+                 {{"D",0x00,0x06},{"X",0x01,0x10},{"Y",0x02,0x20},
+                  {"U",0x03,0x40},{"S",0x04,0x40},{"PC",0x05,0x80},
+                  {"A",0x08,0x02},{"B",0x09,0x04},{"CC",0x0a,0x01},
+                  {"CCR",0x0a,0x01},{"DP",0x0b,0x08},{"DPR",0x0b,0x08}};
+
+struct regrecord * findreg(char *nm)
+{
+ int i;
+ for(i=0;i<12;i++) {
+  if(strcmp(regtable[i].name,nm)==0) return regtable+i;
+ }
+ return 0;
+}
+
+
+char pass;             /* Assembler pass=1 or 2 */
+char listing;          /* flag to indicate listing */
+char relocatable;      /* flag to indicate relocatable object. */
+char terminate;        /* flag to indicate termination. */
+char generating;       /* flag to indicate that we generate code */
+unsigned short loccounter,oldlc;  /* Location counter */
+
+char inpline[128];     /* Current input line (not expanded)*/
+char srcline[128];     /* Current source line */
+char * srcptr;         /* Pointer to line being parsed */
+
+char unknown;          /* flag to indicate value unknown */
+char certain;          /* flag to indicate value is certain at pass 1*/
+int error;             /* flags indicating errors in current line. */
+int errors;            /* number of errors */
+char exprcat;          /* category of expression being parsed, eg.
+                          label or constant, this is important when
+                          generating relocatable object code. */
+
+
+char namebuf[MAXIDLEN+1];
+
+void
+err(int er) {
+    error |= er ;
+}
+
+void
+scanname()
+{
+ int i=0;
+ char c;
+ while(1) {
+   c=*srcptr++;
+   if(c>='a'&&c<='z')c-=32;
+   if(c!='.'&&c!='$'&&(c<'0'||c>'9')&&(c<'A'||c>'Z'))break;
+   if(i<MAXIDLEN)namebuf[i++]=c;
+ }
+ namebuf[i]=0;
+ srcptr--;
+}
+
+void
+skipspace()
+{
+ char c;
+ do {
+  c=*srcptr++;
+ } while(c==' '||c=='\t');
+ srcptr--;
+}
+
+short scanexpr(int);
+
+short scandecimal()
+{
+ char c;
+ short t=0;
+ c=*srcptr++;
+ while(isdigit(c)) {
+  t=t*10+c-'0';
+  c=*srcptr++;
+ }
+ srcptr--;
+ return t;
+}
+
+short scanhex()
+{
+ short t=0,i=0;
+ srcptr++;
+ scanname();
+ while(namebuf[i]>='0'&&namebuf[i]<='F') {
+  t=t*16+namebuf[i]-'0';
+  if(namebuf[i]>'9')t-=7;
+  i++;
+ }
+ if(i==0)error|=1;
+ return t;
+}
+
+short scanchar()
+{
+ short t;
+ srcptr++;
+ t=*srcptr;
+ if(t)srcptr++;
+ if (*srcptr=='\'')srcptr++;
+ return t;
+}
+
+short scanbin()
+{
+ char c;
+ short t=0;
+ srcptr++;
+ c=*srcptr++;
+ while(c=='0'||c=='1') {
+  t=t*2+c-'0';
+  c=*srcptr++;
+ }
+ srcptr--;
+ return t;
+}
+
+short scanoct()
+{
+ char c;
+ short t=0;
+ srcptr++;
+ c=*srcptr++;
+ while(c>='0'&&c<='7') {
+  t=t*8+c-'0';
+  c=*srcptr++;
+ }
+ srcptr--;
+ return t;
+}
+
+
+short scanlabel()
+{
+ struct symrecord * p;
+ scanname();
+ p=findsym(namebuf);
+ if(p->cat==13) {
+   p->cat=6;
+   p->value=0;
+ }
+ if(p->cat==9||p->cat==11)error|=1;
+ exprcat=p->cat&14;
+ if(exprcat==6||exprcat==10)unknown=1;
+ if(((exprcat==2||exprcat==8)
+     && (unsigned short)(p->value)>(unsigned short)loccounter)||
+     exprcat==4)
+   certain=0;
+ if(exprcat==8||exprcat==6||exprcat==10)exprcat=2;
+ return p->value;
+}
+
+/* expression categories...
+   all zeros is ordinary constant.
+   bit 1 indicates address within module.
+   bit 2 indicates external address.
+   bit 4 indicates this can't be relocated if it's an address.
+   bit 5 indicates address (if any) is negative.
+*/
+
+
+
+short scanfactor()
+{
+ char c;
+ short t;
+ skipspace();
+ c=*srcptr;
+ if(isalpha(c))return scanlabel();
+ else if(isdigit(c))return scandecimal();
+ else switch(c) {
+  case '.' :
+  case '*' : srcptr++;exprcat|=2;return loccounter;
+  case '$' : return scanhex();
+  case '%' : return scanbin();
+  case '&' : /* compatibility */
+  case '@' : return scanoct();
+  case '\'' : return scanchar();
+  case '(' : srcptr++;t=scanexpr(0);skipspace();
+             if(*srcptr==')')srcptr++;else error|=1;
+             return t;
+  case '-' : srcptr++;exprcat^=32;return -scanfactor();
+  case '+' : srcptr++;return scanfactor();
+  case '!' : srcptr++;exprcat|=16;return !scanfactor();
+  case '^' : 
+  case '~' : srcptr++;exprcat|=16;return ~scanfactor();
+ }
+ error|=1;
+ return 0;
+}
+
+#define EXITEVAL {srcptr--;return t;}
+
+#define RESOLVECAT if((oldcat&15)==0)oldcat=0;\
+           if((exprcat&15)==0)exprcat=0;\
+           if((exprcat==2&&oldcat==34)||(exprcat==34&&oldcat==2)) {\
+             exprcat=0;\
+             oldcat=0;}\
+           exprcat|=oldcat;\
+/* resolve such cases as constant added to address or difference between
+   two addresses in same module */
+
+
+short scanexpr(int level) /* This is what you call _recursive_ descent!!!*/
+{
+ short t,u;
+ char oldcat,c;
+ exprcat=0;
+ if(level==10)return scanfactor();
+ t=scanexpr(level+1);
+ while(1) {
+  skipspace();
+  c=*srcptr++;
+  switch(c) {
+  case '*':oldcat=exprcat;
+           t*=scanexpr(10);
+           exprcat|=oldcat|16;
+           break;
+  case '/':oldcat=exprcat;
+           u=scanexpr(10);
+           if(u)t/=u;else error|=1;
+           exprcat|=oldcat|16;
+           break;
+  case '%':oldcat=exprcat;
+           u=scanexpr(10);
+           if(u)t%=u;else error|=1;
+           exprcat|=oldcat|16;
+           break;
+  case '+':if(level==9)EXITEVAL
+           oldcat=exprcat;
+           t+=scanexpr(9);
+           RESOLVECAT
+           break;
+  case '-':if(level==9)EXITEVAL
+           oldcat=exprcat;
+           t-=scanexpr(9);
+           exprcat^=32;
+           RESOLVECAT
+           break;
+  case '<':if(*(srcptr)=='<') {
+            if(level>=8)EXITEVAL
+            srcptr++;
+            oldcat=exprcat;
+            t<<=scanexpr(8);
+            exprcat|=oldcat|16;
+            break;
+           } else if(*(srcptr)=='=') {
+            if(level>=7)EXITEVAL
+            srcptr++;
+            oldcat=exprcat;
+            t=t<=scanexpr(7);
+            exprcat|=oldcat|16;
+            break;
+           } else {
+            if(level>=7)EXITEVAL
+            oldcat=exprcat;
+            t=t<scanexpr(7);
+            exprcat|=oldcat|16;
+            break;
+           }
+  case '>':if(*(srcptr)=='>') {
+            if(level>=8)EXITEVAL
+            srcptr++;
+            oldcat=exprcat;
+            t>>=scanexpr(8);
+            exprcat|=oldcat|16;
+            break;
+           } else if(*(srcptr)=='=') {
+            if(level>=7)EXITEVAL
+            srcptr++;
+            oldcat=exprcat;
+            t=t>=scanexpr(7);
+            exprcat|=oldcat|16;
+            break;
+           } else {
+            if(level>=7)EXITEVAL
+            oldcat=exprcat;
+            t=t>scanexpr(7);
+            exprcat|=oldcat|16;
+            break;
+           }
+  case '!':if(level>=6||*srcptr!='=')EXITEVAL
+           srcptr++;
+           oldcat=exprcat;
+           t=t!=scanexpr(6);
+           exprcat|=oldcat|16;
+           break;
+  case '=':if(level>=6)EXITEVAL
+           if(*srcptr=='=')srcptr++;
+           oldcat=exprcat;
+           t=t==scanexpr(6);
+           exprcat|=oldcat|16;
+           break;
+  case '&':if(level>=5)EXITEVAL
+           oldcat=exprcat;
+           t&=scanexpr(5);
+           exprcat|=oldcat|16;
+           break;
+  case '^':if(level>=4)EXITEVAL
+           oldcat=exprcat;
+           t^=scanexpr(4);
+           exprcat|=oldcat|16;
+           break;
+  case '|':if(level>=3)EXITEVAL
+           oldcat=exprcat;
+           t|=scanexpr(3);
+           exprcat|=oldcat|16;
+  default: EXITEVAL
+  }
+ }
+}
+
+char mode; /* addressing mode 0=immediate,1=direct,2=extended,3=postbyte
+               4=pcrelative(with postbyte) 5=indirect 6=pcrel&indirect*/
+char opsize; /*desired operand size 0=dunno,1=5,2=8,3=16*/
+short operand;
+unsigned char postbyte;
+
+int dpsetting;
+
+
+int scanindexreg()
+{
+ char c;
+ c=*srcptr;
+ if(islower(c))c-=32;
+ if (debug) fprintf(stderr,"DEBUG: scanindexreg: indexreg=%d, mode=%d, opsize=%d, error=%d, postbyte=%02X\n",c,mode,opsize,error,postbyte);
+ switch(c) {
+  case 'X':return 1;
+  case 'Y':postbyte|=0x20;return 1;
+  case 'U':postbyte|=0x40;return 1;
+  case 'S':postbyte|=0x60;return 1;
+  default: return 0;
+ }
+}
+
+void
+set3()
+{
+ if(mode<3)mode=3;
+}
+
+void
+scanspecial()
+{
+ set3();
+ skipspace();
+ if(*srcptr=='-') {
+  srcptr++;
+  if(*srcptr=='-') {
+   srcptr++;
+   postbyte=0x83;
+  } else postbyte=0x82;
+  if(!scanindexreg())error|=2;else srcptr++;
+ } else {
+  postbyte=0x80;
+  if(!scanindexreg())error|=2;else srcptr++;
+  if(*srcptr=='+') {
+   srcptr++;
+   if(*srcptr=='+') {
+    srcptr++;
+    postbyte+=1;
+   }
+  } else postbyte+=4;
+ }
+}
+
+void
+scanindexed()
+{
+ set3();
+ postbyte=0;
+ if(scanindexreg()) {
+   srcptr++;
+   if(opsize==0) { 
+                if(unknown||!certain)opsize=3;
+                else if(operand>=-16&&operand<16&&mode==3)opsize=1;
+                else if(operand>=-128&&operand<128)opsize=2;
+                else opsize=3;
+         }
+   switch(opsize) {
+   case 1:postbyte+=(operand&31);opsize=0;break;
+   case 2:postbyte+=0x88;break;
+   case 3:postbyte+=0x89;break;
+   }
+ } else { /*pc relative*/
+  if(toupper(*srcptr)!='P')error|=2;
+  else {
+    srcptr++;
+    if(toupper(*srcptr)!='C')error|=2;
+    else {
+     srcptr++;
+     if(toupper(*srcptr)=='R')srcptr++;
+    }
+  }
+  mode++;postbyte+=0x8c;
+  if(opsize==1)opsize=2;
+ }
+}
+
+#define RESTORE {srcptr=oldsrcptr;c=*srcptr;goto dodefault;}
+
+void
+scanoperands()
+{
+ char c,d,*oldsrcptr;
+ unknown=0;
+ opsize=0;
+ certain=1;
+ skipspace();
+ c=*srcptr;
+ mode=0;
+ if(c=='[') {
+  srcptr++;
+  c=*srcptr;
+  mode=5;
+ }
+ if (debug) fprintf(stderr,"DEBUG: scanoperands: c=%c (%02X)\n",c,c);
+ switch(c) {
+ case 'D': case 'd':
+  oldsrcptr=srcptr;
+  srcptr++;
+  skipspace();
+  if(*srcptr!=',')RESTORE else {
+     postbyte=0x8b;
+     srcptr++;
+     if(!scanindexreg())RESTORE else {srcptr++;set3();}
+  }
+  break;
+ case 'A': case 'a':
+  oldsrcptr=srcptr;
+  srcptr++;
+  skipspace();
+  if(*srcptr!=',')RESTORE else {
+     postbyte=0x86;
+     srcptr++;
+     if(!scanindexreg())RESTORE else {srcptr++;set3();}
+  }
+  break;
+ case 'B': case 'b':
+  oldsrcptr=srcptr;
+  srcptr++;
+  skipspace();
+  if(*srcptr!=',')RESTORE else {
+     postbyte=0x85;
+     srcptr++;
+     if (debug) fprintf(stderr,"DEBUG: scanoperands: breg preindex: c=%c (%02X)\n",*srcptr,*srcptr);
+     if(!scanindexreg())RESTORE else {srcptr++;set3();}
+     if (debug) fprintf(stderr,"DEBUG: scanoperands: breg: postindex c=%c (%02X)\n",*srcptr,*srcptr);
+  }
+  break;
+ case ',':
+  srcptr++;
+  scanspecial();
+  break;
+ case '#':
+  if(mode==5)error|=2;else mode=0;
+  srcptr++;
+  operand=scanexpr(0);
+  break;
+ case '<':
+  srcptr++;
+  if(*srcptr=='<') {
+   srcptr++;
+   opsize=1;
+  } else opsize=2;
+  goto dodefault;
+ case '>':
+  srcptr++;
+  opsize=3;
+ default: dodefault:
+  operand=scanexpr(0);
+  skipspace();
+  if(*srcptr==',') {
+   srcptr++;
+   scanindexed();
+  } else {
+   if(opsize==0) {
+    if(unknown||!certain||dpsetting==-1||
+         (unsigned short)(operand-dpsetting*256)>=256)
+    opsize=3; else opsize=2;
+   }
+   if(opsize==1)opsize=2;
+   if(mode==5){
+    postbyte=0x8f;
+    opsize=3;
+   } else mode=opsize-1;
+  }
+ }
+ if (debug) fprintf(stderr,"DEBUG: scanoperands: mode=%d, error=%d, postbyte=%02X\n",mode,error,postbyte);
+ if(mode>=5) {
+  skipspace();
+  postbyte|=0x10;
+  if(*srcptr!=']')error|=2;else srcptr++;
+ }
+ if(pass==2&&unknown)error|=4;
+}
+
+unsigned char codebuf[128];
+int codeptr; /* byte offset within instruction */
+int suppress; /* 0=no suppress 1=until ENDIF 2=until ELSE 3=until ENDM */
+int ifcount;  /* count of nested IFs within suppressed text */
+
+unsigned char outmode; /* 0 is binary, 1 is s-records */
+
+unsigned short hexaddr;
+int hexcount;
+unsigned char hexbuffer[16];
+unsigned int chksum;
+
+extern int os9crc(unsigned char c, int crcp);
+int crc;
+
+void
+reset_crc() 
+{
+  crc = -1;
+}
+
+
+void
+flushhex()
+{
+ int i;
+ if(hexcount){
+  fprintf(objfile,"S1%02X%04X",(hexcount+3)&0xff,hexaddr&0xffff);
+  for(i=0;i<hexcount;i++)fprintf(objfile,"%02X",hexbuffer[i]);
+  chksum+=(hexaddr&0xff)+((hexaddr>>8)&0xff)+hexcount+3;
+  fprintf(objfile,"%02X\n",0xff-(chksum&0xff));
+  hexaddr+=hexcount;
+  hexcount=0;
+  chksum=0;
+ }
+}
+
+void
+outhex(unsigned char x) 
+{
+ if(hexcount==16)flushhex();
+ hexbuffer[hexcount++]=x;
+ chksum+=x;
+}
+
+void
+outbuffer()
+{
+ int i;
+ for(i=0;i<codeptr;i++) {
+   crc = os9crc(codebuf[i],crc);   
+   if(!outmode)fputc(codebuf[i],objfile);else outhex(codebuf[i]);
+ }
+}
+
+char *errormsg[]={"Error in expression",
+                "Illegal addressing mode",
+                "Undefined label",
+                "Multiple definitions of label",
+                "Relative branch out of range",
+                "Missing label",
+                "","","","","","","","","",
+                "Illegal mnemonic"
+               };
+
+void
+report()
+{
+ int i;
+ fprintf(stderr,"File %s, line %d:%s\n",curname,lineno,srcline);
+ for(i=0;i<16;i++) {
+  if(error&1) {
+   fprintf(stderr,"%s\n",errormsg[i]);
+   if(pass==2&&listing)fprintf(listfile,"**** %s\n",errormsg[i]);
+  }
+  error>>=1;
+ }
+ errors++;
+}
+
+void
+outlist()
+{
+ int i;
+ fprintf(listfile,"%04X: ",oldlc);
+ for(i=0;i<codeptr&&i<MAXLISTBYTES;i++)
+  fprintf(listfile,"%02X",codebuf[i]);
+ for(;i<=MAXLISTBYTES;i++)
+  fprintf(listfile,"  ");
+ fprintf(listfile,"%s\n",srcline);
+ while(i<codeptr) {
+   fprintf(listfile,"%04X: ",oldlc + i);
+   for(int j=0;i<codeptr&&j<MAXLISTBYTES;j++) {
+    fprintf(listfile,"%02X",codebuf[i]); i++; 
+   }
+   fprintf(listfile,"\n"); 
+ }
+}
+
+void
+setlabel(struct symrecord * lp)
+{
+ if(lp) {
+  if(lp->cat!=13&&lp->cat!=6) {
+   if(lp->cat!=2||lp->value!=loccounter)
+    error|=8;
+  } else {
+   lp->cat=2;
+   lp->value=loccounter;
+  }
+ }
+}
+
+void
+putbyte(unsigned char b)
+{
+ codebuf[codeptr++]=b;
+}
+
+void
+putword(unsigned short w)
+{
+ codebuf[codeptr++]=w>>8;
+ codebuf[codeptr++]=w&0x0ff;
+}
+
+void
+doaddress() /* assemble the right addressing bytes for an instruction */
+{
+ int offs;
+ switch(mode) {
+ case 0: if(opsize==2)putbyte(operand);else putword(operand);break;
+ case 1: putbyte(operand);break;
+ case 2: putword(operand);break;
+ case 3: case 5: putbyte(postbyte);
+    switch(opsize) {
+     case 2: putbyte(operand);break;
+     case 3: putword(operand);
+    }
+    break;
+ case 4: case 6: offs=(unsigned short)operand-loccounter-codeptr-2;
+                if(offs<-128||offs>=128||opsize==3||unknown||!certain) {
+                 if((!unknown)&&opsize==2&&(offs<-128||offs>=128) )
+                   error|=16;
+                 offs--;
+                 opsize=3;
+                 postbyte++;
+                }
+                putbyte(postbyte);
+                if (debug) fprintf(stderr,"DEBUG: doaddress: mode=%d, opsize=%d, error=%d, postbyte=%02X, operand=%04X offs=%d\n",mode,opsize,error,postbyte,operand,offs);
+                if(opsize==3)putword(offs);
+                else putbyte(offs);
+ }
+}
+
+void
+onebyte(int co)
+{
+ putbyte(co);
+}
+
+void
+twobyte(int co)
+{
+ putword(co);
+}
+
+void
+oneimm(int co)
+{
+ scanoperands();
+ if(mode>=3)error|=2;
+ putbyte(co);
+ putbyte(operand);
+}
+
+void
+lea(int co)
+{
+ putbyte(co);
+ scanoperands();
+ if(mode==0) error|=2;
+ if(mode<3) {
+   opsize=3;
+   postbyte=0x8f;
+   mode=3;
+ }
+ if (debug) fprintf(stderr,"DEBUG: lea: mode=%d, opsize=%d, error=%d, postbyte=%02X, *src=%c\n",mode,opsize,error,postbyte,*srcptr);
+ doaddress();
+}
+
+void
+sbranch(int co)
+{
+ int offs;
+ scanoperands();
+ if(mode!=1&&mode!=2)error|=2;
+ offs=(unsigned short)operand-loccounter-2;
+ if(!unknown&&(offs<-128||offs>=128))error|=16;
+ if(pass==2&&unknown)error|=4;
+ putbyte(co);
+ putbyte(offs);
+}
+
+void
+lbra(int co)
+{
+ scanoperands();
+ if(mode!=1&&mode!=2)error|=2;
+ putbyte(co);
+ putword(operand-loccounter-3);
+}
+
+void
+lbranch(int co)
+{
+ scanoperands();
+ if(mode!=1&&mode!=2)error|=2;
+ putword(co);
+ putword(operand-loccounter-4);
+}
+
+void
+arith(int co)
+{
+ scanoperands();
+ switch(mode) {
+ case 0:opsize=2;putbyte(co);break;
+ case 1:putbyte(co+0x010);break;
+ case 2:putbyte(co+0x030);break;
+ default:putbyte(co+0x020);
+ }
+ doaddress();
+}
+
+void
+darith(int co)
+{
+ scanoperands();
+ switch(mode) {
+ case 0:opsize=3;putbyte(co);break;
+ case 1:putbyte(co+0x010);break;
+ case 2:putbyte(co+0x030);break;
+ default:putbyte(co+0x020);
+ }
+ doaddress();
+}
+
+void
+d2arith(int co)
+{
+ scanoperands();
+ switch(mode) {
+ case 0:opsize=3;putword(co);break;
+ case 1:putword(co+0x010);break;
+ case 2:putword(co+0x030);break;
+ default:putword(co+0x020);
+ }
+ doaddress();
+}
+
+void
+oneaddr(int co)
+{
+ scanoperands();
+ switch(mode) {
+ case 0: error|=2;break;
+ case 1: putbyte(co);break;
+ case 2: putbyte(co+0x70);break;
+ default: putbyte(co+0x60);break;
+ }
+ doaddress();
+}
+
+void
+tfrexg(int co)
+{
+ struct regrecord * p;
+ putbyte(co);
+ skipspace();
+ scanname();
+ if((p=findreg(namebuf))==0)error|=2;
+ else postbyte=(p->tfr)<<4;
+ skipspace();
+ if(*srcptr==',')srcptr++;else error|=2;
+ skipspace();
+ scanname();
+ if((p=findreg(namebuf))==0)error|=2;
+ else postbyte|=p->tfr;
+ putbyte(postbyte);
+}
+
+void
+pshpul(int co)
+{
+ struct regrecord *p;
+ putbyte(co);
+ postbyte=0;
+ do {
+  if(*srcptr==',')srcptr++;
+  skipspace();
+  scanname();
+  if((p=findreg(namebuf))==0)error|=2;
+  else postbyte|=p->psh;
+  skipspace();
+ }while (*srcptr==',');
+ putbyte(postbyte);
+}
+
+void
+skipComma()
+{
+ while(*srcptr && *srcptr!='\n' && *srcptr!=',')srcptr++;
+ if (*srcptr==',') {
+   srcptr++;
+ } else {
+   error|=1;  
+ }
+}
+
+int modStart;
+
+void os9begin()
+{
+ generating=1;
+ modStart = loccounter;
+ reset_crc();
+ putword(0x87cd);
+ putword(scanexpr(0)-loccounter);  // module size
+ skipComma();
+ putword(scanexpr(0)-loccounter);  // offset to module name
+ skipComma();
+ putbyte(scanexpr(0));             // type / language
+ skipComma();
+ putbyte(scanexpr(0));             // attribute
+ int parity=0;
+ for(int i=0; i< 8; i++) parity^=codebuf[i];
+ putbyte(parity^0xff);              // header parity
+ skipspace();
+ while (*srcptr==',') {             // there are some more
+   srcptr++;
+   putword(scanexpr(0));   
+   skipspace();
+ }
+}
+
+void os9end()
+{
+ crc = crc ^ 0xffffff;
+
+ putbyte((crc>>16)&0xff);
+ putbyte((crc>>8)&0xff);
+ putbyte(crc&0xff);
+}
+
+
+void
+pseudoop(int co,struct symrecord * lp)
+{
+ int i;
+ char c;
+ char *fname;
+ int locsave;
+
+ switch(co) {
+ case 0:/* RMB */
+        setlabel(lp);
+        operand=scanexpr(0);
+        if(unknown)error|=4;
+        loccounter+=operand;
+        if(generating&&pass==2) {
+           if(!outmode)for(i=0;i<operand;i++)fputc(0,objfile);
+           else flushhex();  
+        }   
+        hexaddr=loccounter;
+        break;
+ case 5:/* EQU */
+        operand=scanexpr(0);
+        if(!lp)error|=32;
+        else {
+         if(lp->cat==13||lp->cat==6||
+            (lp->value==(unsigned short)operand&&pass==2)) {
+          if(exprcat==2)lp->cat=2;
+          else lp->cat=0;
+          lp->value=operand;
+         } else error|=8;
+        }
+        break;
+ case 7:/* FCB */
+        setlabel(lp);
+        generating=1;
+        do {
+        if(*srcptr==',')srcptr++;
+        skipspace();
+        if(*srcptr=='\"') {
+         srcptr++;
+         while(*srcptr!='\"'&&*srcptr)
+          putbyte(*srcptr++);
+         if(*srcptr=='\"')srcptr++;
+        } else {
+          putbyte(scanexpr(0));
+          if(unknown&&pass==2)error|=4;
+        }
+        skipspace();
+        } while(*srcptr==',');
+        break;
+ case 8:/* FCC */
+        setlabel(lp);
+        skipspace();
+        c=*srcptr++;
+        while(*srcptr!=c&&*srcptr)
+         putbyte(*srcptr++);
+        if(*srcptr==c)srcptr++;
+        break;
+ case 9:/* FDB */
+        setlabel(lp);
+        generating=1;
+        do {
+         if(*srcptr==',')srcptr++;
+         skipspace();
+         putword(scanexpr(0));
+         if(unknown&&pass==2)error|=4;
+         skipspace();
+        } while(*srcptr==',');
+        break;
+ case 23 :/* FCS */
+        setlabel(lp);
+        generating=1;
+        skipspace();
+        int sep = *srcptr;
+        if(sep=='\"' || sep=='/') {
+         srcptr++;
+         while(*srcptr!=sep&&*srcptr)
+          putbyte(*srcptr++);
+         if(*srcptr==sep)srcptr++; 
+         codebuf[codeptr-1] |= 0x80;  // os9 string termination
+        }
+        break;
+ case 1: /* ELSE */
+        suppress=1;
+        break;
+ case 21: /* IFP1 */
+        if(pass==2)suppress=2;
+        break;                
+ case 29: /* IFGT */
+        operand=scanexpr(0);
+        if(unknown)error|=4;
+        if(operand>0)suppress=2;
+        break;                
+ case 31: /* IFLT */
+        operand=scanexpr(0);
+        if(unknown)error|=4;
+        if(operand<0)suppress=2;
+        break;                
+ case 28: /* IFNE */
+        operand=scanexpr(0);
+        if(unknown)error|=4;
+        if(operand==0)suppress=2;
+        break;                
+ case 30: /* IFEQ */
+ case 10: /* IF */
+        operand=scanexpr(0);
+        if(unknown)error|=4;
+        if(!operand)suppress=2;
+        break;                
+ case 12: /* ORG */
+         operand=scanexpr(0);
+         if(unknown)error|=4;
+         if(generating&&pass==2) {
+           for(i=0;i<(unsigned short)operand-loccounter;i++)
+                if(!outmode)fputc(0,objfile);else flushhex();
+         }             
+         loccounter=operand;
+         hexaddr=loccounter;
+         break;
+  case 14: /* SETDP */
+         operand=scanexpr(0);
+         if(unknown)error|=4;
+         if(!(operand&255))operand=(unsigned short)operand>>8;
+         if((unsigned)operand>255)operand=-1;
+         dpsetting=operand;              
+         break;
+  case 15: /* SET */
+        operand=scanexpr(0);
+        if(!lp)error|=32;
+        else {
+         if(lp->cat&1||lp->cat==6) {
+          if(exprcat==2)lp->cat=3;
+          else lp->cat=1;
+          lp->value=operand;
+         } else error|=8;
+        }
+        break;
+   case 2: /* END */
+        terminate=1;
+        break;     
+   case 27: /* USE */     
+        locsave = loccounter ;
+   case 16: /* INCLUDE */     
+        skipspace();
+        if(*srcptr=='"')srcptr++;
+        i = 0;
+        for(i=0; !(srcptr[i]==0||srcptr[i]=='"'); i++);
+        int len = i;
+        fname = calloc(1,len);
+        for(i=0;i<len;i++) {
+          if(*srcptr==0||*srcptr=='"')break;
+          fname[i]=*srcptr++;
+        }
+        fname[i]=0;
+        processfile(fname);
+        codeptr=0;
+        srcline[0]=0;
+        if (co==27) loccounter = locsave;
+        break; 
+   case 24: /* MOD */     
+        loccounter = 0;
+        setlabel(lp);
+        os9begin();
+        break; 
+   case 25: /* EMOD */     
+        os9end();
+        break; 
+   case 32: /* OS9 */     
+        setlabel(lp);
+      putword(0x103f); // SWI2
+        putbyte(scanexpr(0));
+        break; 
+   case 18: /* TTL */     
+        break;
+   case 19: /* OPT */     
+   case 26: /* NAM */     
+   case 20: /* PAG */     
+   case 3:  /* ENDIF/ENDC */     
+        break; 
+ }
+}
+
+
+void
+processline()
+{
+ struct symrecord * lp;
+ struct oprecord * op;
+ int co;
+ char c;
+ srcptr=srcline;
+ oldlc=loccounter;
+ error=0;
+ unknown=0;certain=1;
+ lp=0;
+ codeptr=0;
+ if(isalnum(*srcptr)) {
+  scanname();lp=findsym(namebuf);
+  if(*srcptr==':') srcptr++;
+ }
+ skipspace();
+ if(isalnum(*srcptr)) {
+  scanname();
+  op=findop(namebuf);
+  if(op) {
+   if(op->cat!=13){
+     setlabel(lp);
+     generating=1;
+   }
+   co=op->code;
+   switch(op->cat) {
+   case 0:onebyte(co);break;
+   case 1:twobyte(co);break;
+   case 2:oneimm(co);break;
+   case 3:lea(co);break;
+   case 4:sbranch(co);break;
+   case 5:lbranch(co);break;
+   case 6:lbra(co);break;
+   case 7:arith(co);break;
+   case 8:darith(co);break;
+   case 9:d2arith(co);break;
+   case 10:oneaddr(co);break;
+   case 11:tfrexg(co);break;
+   case 12:pshpul(co);break;
+   case 13:pseudoop(co,lp);
+   }
+   c=*srcptr;
+   if (debug) fprintf(stderr,"DEBUG: processline: mode=%d, opsize=%d, error=%d, postbyte=%02X c=%c\n",mode,opsize,error,postbyte,c);
+   if(c!=' '&&*(srcptr-1)!=' '&&c!=0&&c!=';')error|=2;
+  }
+  else error|=0x8000;
+ }else setlabel(lp);
+ if(pass==2) {
+  outbuffer();
+  if(listing)outlist();
+ }
+ if(error)report();
+ loccounter+=codeptr;
+}
+
+void
+suppressline()
+{
+ struct oprecord * op;
+ srcptr=srcline;
+ oldlc=loccounter;
+ codeptr=0;
+ if(isalnum(*srcptr)) {
+  scanname();
+  if(*srcptr==':')srcptr++;
+ }
+ skipspace();
+ scanname();op=findop(namebuf);
+ if(op && op->cat==13) {
+  if(op->code==10||op->code==13||op->code==29||op->code==28||op->code==21||op->code==30) ifcount++;
+  else if(op->code==3) {
+   if(ifcount>0)ifcount--;else if(suppress==1|suppress==2)suppress=0;
+  } else if(op->code==1) {
+   if(ifcount==0 && suppress==2)suppress=0;
+  }
+ }  
+ if(pass==2&&listing)outlist();
+}
+
+void
+usage(char*nm)
+{
+  fprintf(stderr,"Usage: %s [-o objname] [-l listname] [-s srecord-file] srcname\n",nm);
+  exit(2);
+}
+
+char *
+strconcat(char *s,int spos,char *d)
+{
+  int slen = strlen(s);
+  int dlen = strlen(d);
+  if ( spos == 0) spos = slen;
+  char *out = calloc(1,spos+dlen+1);
+  int i = 0;
+  for(; i< spos; i++ ) out[i] = s[i];
+  for(; i< spos+dlen+1; i++ ) out[i] = *d++;
+  return out;
+} 
+
+
+void
+getoptions(int c,char*v[])
+{
+ int i=0;
+ if(c==1)usage(v[0]);
+ if(strcmp(v[1],"-d")==0) {
+   debug=1;
+   i++;
+ }
+ if(strcmp(v[1],"-o")==0) {
+   if(c<4)usage(v[0]);
+   objname = v[2];
+   i+=2;
+ }
+ if(strcmp(v[i+1],"-s")==0) {
+   if(c<4+i)usage(v[0]);
+   objname=v[i+2];
+   outmode=1;
+   i+=2;
+ }
+ if(strcmp(v[i+1],"-l")==0) {
+   if(c<4+i)usage(v[0]);
+   listname=v[2+i];
+   i+=2;
+ }
+ srcname=v[1+i];
+ if(objname==0) {
+   for(i=0;srcname[i]!='.' && srcname[i]!=0 ;i++) ;
+   objname = strconcat(srcname,i,".b");
+ }
+ listing=(listname!=0);
+}
+
+void
+expandline()
+{
+ int i=0,j=0,k,j1;
+ for(i=0;i<128&&j<128;i++)
+ {
+  if(inpline[i]=='\n') {
+    srcline[j]=0;break;
+  }
+  if(inpline[i]=='\t') {
+    j1=j;
+    for(k=0;k<8-j1%8 && j<128;k++)srcline[j++]=' ';
+  }else srcline[j++]=inpline[i];
+ }
+ srcline[127]=0;
+}
+
+
+void
+processfile(char *name)
+{
+ char *oldname;
+ int oldno;
+ FILE *srcfile;
+ oldname=curname;
+ curname=name;
+ oldno=lineno;
+ lineno=0;
+ if((srcfile=fopen(name,"r"))==0) {
+   int i = strlen(oldname);
+   while(i>0 && oldname[i]!='/') i--;
+   if (i>0) {
+       char *next = strconcat(oldname,i+1,name);
+       if((srcfile=fopen(next,"r"))==0) {
+          fprintf(stderr,"Cannot open source file %s\n",next);
+          exit(4);
+       }
+       curname = next;
+   } else {
+     fprintf(stderr,"Cannot open source file %s\n",name);
+     exit(4);
+   }
+ }
+ while(!terminate&&fgets(inpline,128,srcfile)) {
+   expandline();
+   lineno++;
+   srcptr=srcline;
+   if(suppress)suppressline(); else processline();
+ }
+ fclose(srcfile);
+ if(suppress) {
+   fprintf(stderr,"improperly nested IF statements in %s",curname);
+   errors++;
+   suppress=0;
+ }
+ lineno=oldno;
+ curname=oldname;
+}
+
+int
+main(int argc,char *argv[])
+{
+ char c;
+ getoptions(argc,argv);
+ pass=1;
+ errors=0;
+ generating=0;
+ terminate=0;
+ processfile(srcname);
+ if(errors) {
+  fprintf(stderr,"%d Pass 1 Errors, Continue?",errors);
+  c=getchar();
+  if(c=='n'||c=='N') exit(3);
+ }
+ pass=2;
+ loccounter=0;
+ errors=0;
+ generating=0;
+ terminate=0;
+ if(listing&&((listfile=fopen(listname,"w"))==0)) {
+  fprintf(stderr,"Cannot open list file");
+  exit(4);
+ }
+ if((objfile=fopen(objname,outmode?"w":"wb"))==0) {
+  fprintf(stderr,"Cannot write object file\n");
+  exit(4);
+ }
+ processfile(srcname);
+ fprintf(stderr,"%d Pass 2 errors.\n",errors);
+ if(listing) {
+  fprintf(listfile,"%d Pass 2 errors.\n",errors);
+  outsymtable();
+  fclose(listfile);
+ }
+ if(outmode){
+  flushhex();
+  fprintf(objfile,"S9030000FC\n");
+ } 
+ fclose(objfile);
+ return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/engine.c	Mon Jul 02 02:12:31 2018 +0900
@@ -0,0 +1,1170 @@
+/* 6809 Simulator V09.
+
+   created 1994,1995 by L.C. Benschop.
+   copyleft (c) 1994-2014 by the sbc09 team, see AUTHORS for more details.
+   license: GNU General Public License version 2, see LICENSE for more details.
+
+   This program simulates a 6809 processor.
+
+   System dependencies: short must be 16 bits.
+                        char  must be 8 bits.
+                        long must be more than 16 bits.
+                        arrays up to 65536 bytes must be supported.
+                        machine must be twos complement.
+   Most Unix machines will work. For MSODS you need long pointers
+   and you may have to malloc() the mem array of 65536 bytes.
+
+   Special instructions:
+   SWI2 writes char to stdout from register B.
+   SWI3 reads char from stdout to register B, sets carry at EOF.
+               (or when no key available when using term control).
+   SWI retains its normal function.
+   CWAI and SYNC stop simulator.
+   Note: special instructions are gone for now.
+
+   ACIA emulation at port $E000
+
+   Note: BIG_ENDIAN option is no longer needed.
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+
+#define engine
+#include "v09.h"
+
+#define USLEEP 1000
+Byte aca,acb;
+Byte *breg=&aca,*areg=&acb;
+static int tracetrick=0;
+extern int romstart;
+
+#define GETWORD(a) (mem[a]<<8|mem[(a)+1])
+#define SETBYTE(a,n) {if(!(a>=romstart))mem[a]=n;}
+#define SETWORD(a,n) if(!(a>=romstart)){mem[a]=(n)>>8;mem[(a)+1]=n;}
+/* Two bytes of a word are fetched separately because of
+   the possible wrap-around at address $ffff and alignment
+*/
+
+#define IMMBYTE(b) b=mem[ipcreg++];
+#define IMMWORD(w) {w=GETWORD(ipcreg);ipcreg+=2;}
+
+#define PUSHBYTE(b) {--isreg;SETBYTE(isreg,b)}
+#define PUSHWORD(w) {isreg-=2;SETWORD(isreg,w)}
+#define PULLBYTE(b) b=mem[isreg++];
+#define PULLWORD(w) {w=GETWORD(isreg);isreg+=2;}
+#define PSHUBYTE(b) {--iureg;SETBYTE(iureg,b)}
+#define PSHUWORD(w) {iureg-=2;SETWORD(iureg,w)}
+#define PULUBYTE(b) b=mem[iureg++];
+#define PULUWORD(w) {w=GETWORD(iureg);iureg+=2;}
+
+#define SIGNED(b) ((Word)(b&0x80?b|0xff00:b))
+
+#define GETDREG ((iareg<<8)|ibreg)
+#define SETDREG(n) {iareg=(n)>>8;ibreg=(n);}
+
+/* Macros for addressing modes (postbytes have their own code) */
+#define DIRECT {IMMBYTE(eaddr) eaddr|=(idpreg<<8);}
+#define IMM8 {eaddr=ipcreg++;}
+#define IMM16 {eaddr=ipcreg;ipcreg+=2;}
+#define EXTENDED {IMMWORD(eaddr)}
+
+/* macros to set status flags */
+#define SEC iccreg|=0x01;
+#define CLC iccreg&=0xfe;
+#define SEZ iccreg|=0x04;
+#define CLZ iccreg&=0xfb;
+#define SEN iccreg|=0x08;
+#define CLN iccreg&=0xf7;
+#define SEV iccreg|=0x02;
+#define CLV iccreg&=0xfd;
+#define SEH iccreg|=0x20;
+#define CLH iccreg&=0xdf;
+
+/* set N and Z flags depending on 8 or 16 bit result */
+#define SETNZ8(b) {if(b)CLZ else SEZ if(b&0x80)SEN else CLN}
+#define SETNZ16(b) {if(b)CLZ else SEZ if(b&0x8000)SEN else CLN}
+
+#define SETSTATUS(a,b,res) if((a^b^res)&0x10) SEH else CLH \
+                           if((a^b^res^(res>>1))&0x80)SEV else CLV \
+                           if(res&0x100)SEC else CLC SETNZ8((Byte)res)
+
+#define SETSTATUSD(a,b,res) {if(res&0x10000) SEC else CLC \
+                            if(((res>>1)^a^b^res)&0x8000) SEV else CLV \
+                            SETNZ16((Word)res)}
+
+/* Macros for branch instructions */
+#define BRANCH(f) if(!iflag){IMMBYTE(tb) if(f)ipcreg+=SIGNED(tb);}\
+                     else{IMMWORD(tw) if(f)ipcreg+=tw;}
+#define NXORV  ((iccreg&0x08)^((iccreg&0x02)<<2))
+
+/* MAcros for setting/getting registers in TFR/EXG instructions */
+#define GETREG(val,reg) switch(reg) {\
+                         case 0: val=GETDREG;break;\
+                         case 1: val=ixreg;break;\
+                         case 2: val=iyreg;break;\
+                    	 case 3: val=iureg;break;\
+                    	 case 4: val=isreg;break;\
+                    	 case 5: val=ipcreg;break;\
+                    	 case 8: val=iareg;break;\
+                    	 case 9: val=ibreg;break;\
+                    	 case 10: val=iccreg;break;\
+                    	 case 11: val=idpreg;break;}
+
+#define SETREG(val,reg) switch(reg) {\
+			 case 0: SETDREG(val) break;\
+			 case 1: ixreg=val;break;\
+			 case 2: iyreg=val;break;\
+			 case 3: iureg=val;break;\
+			 case 4: isreg=val;break;\
+			 case 5: ipcreg=val;break;\
+			 case 8: iareg=val;break;\
+			 case 9: ibreg=val;break;\
+			 case 10: iccreg=val;break;\
+			 case 11: idpreg=val;break;}
+
+/* Macros for load and store of accumulators. Can be modified to check
+   for port addresses */
+#define LOADAC(reg) if((eaddr&0xff00)!=IOPAGE)reg=mem[eaddr];else\
+           reg=do_input(eaddr&0xff);
+#define STOREAC(reg) if((eaddr&0xff00)!=IOPAGE)SETBYTE(eaddr,reg)else\
+	   do_output(eaddr&0xff,reg);
+
+#define LOADREGS ixreg=xreg;iyreg=yreg;\
+ iureg=ureg;isreg=sreg;\
+ ipcreg=pcreg;\
+ iareg=*areg;ibreg=*breg;\
+ idpreg=dpreg;iccreg=ccreg;
+
+#define SAVEREGS xreg=ixreg;yreg=iyreg;\
+ ureg=iureg;sreg=isreg;\
+ pcreg=ipcreg;\
+ *areg=iareg;*breg=ibreg;\
+ dpreg=idpreg;ccreg=iccreg;
+
+
+unsigned char haspostbyte[] = {
+  /*0*/      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  /*1*/      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  /*2*/      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  /*3*/      1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
+  /*4*/      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  /*5*/      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  /*6*/      1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  /*7*/      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  /*8*/      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  /*9*/      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  /*A*/      1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  /*B*/      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  /*C*/      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  /*D*/      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  /*E*/      1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  /*F*/      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+            };
+
+void interpr(void)
+{
+ Word ixreg,iyreg,iureg,isreg,ipcreg;
+ Byte idpreg,iccreg,iareg,ibreg;
+ /* Make local variables for the registers. On a real processor (non-Intel)
+    these could be implemented as fast registers. */
+ Word eaddr; /* effective address */
+ Byte ireg; /* instruction register */
+ Byte iflag; /* flag to indicate $10 or $11 prebyte */
+ Byte tb;Word tw;
+ LOADREGS
+ for(;;){
+  if(attention) {
+   if(tracing && ipcreg>=tracelo && ipcreg<=tracehi)
+              {SAVEREGS do_trace(tracefile); }
+   if(escape){ SAVEREGS do_escape(); LOADREGS }
+   if(irq) {
+    if(irq==1&&!(iccreg&0x10)) { /* standard IRQ */
+			 PUSHWORD(ipcreg)
+			 PUSHWORD(iureg)
+                   	 PUSHWORD(iyreg)
+   			 PUSHWORD(ixreg)
+   			 PUSHBYTE(idpreg)
+   			 PUSHBYTE(ibreg)
+   			 PUSHBYTE(iareg)
+   			 PUSHBYTE(iccreg)
+   			 iccreg|=0x90;
+     			 ipcreg=GETWORD(0xfff8);
+    }
+    if(irq==2&&!(iccreg&0x40)) { /* Fast IRQ */
+			 PUSHWORD(ipcreg)
+   			 PUSHBYTE(iccreg)
+   			 iccreg&=0x7f;
+    			 iccreg|=0x50;
+    			 ipcreg=GETWORD(0xfff6);
+    }
+    if(!tracing)attention=0;
+    irq=0;
+   }
+  }
+  iflag=0;
+ flaginstr:  /* $10 and $11 instructions return here */
+  ireg=mem[ipcreg++];
+  if(haspostbyte[ireg]) {
+   Byte postbyte=mem[ipcreg++];
+   switch(postbyte) {
+    case 0x00: eaddr=ixreg;break;
+    case 0x01: eaddr=ixreg+1;break;
+    case 0x02: eaddr=ixreg+2;break;
+    case 0x03: eaddr=ixreg+3;break;
+    case 0x04: eaddr=ixreg+4;break;
+    case 0x05: eaddr=ixreg+5;break;
+    case 0x06: eaddr=ixreg+6;break;
+    case 0x07: eaddr=ixreg+7;break;
+    case 0x08: eaddr=ixreg+8;break;
+    case 0x09: eaddr=ixreg+9;break;
+    case 0x0A: eaddr=ixreg+10;break;
+    case 0x0B: eaddr=ixreg+11;break;
+    case 0x0C: eaddr=ixreg+12;break;
+    case 0x0D: eaddr=ixreg+13;break;
+    case 0x0E: eaddr=ixreg+14;break;
+    case 0x0F: eaddr=ixreg+15;break;
+    case 0x10: eaddr=ixreg-16;break;
+    case 0x11: eaddr=ixreg-15;break;
+    case 0x12: eaddr=ixreg-14;break;
+    case 0x13: eaddr=ixreg-13;break;
+    case 0x14: eaddr=ixreg-12;break;
+    case 0x15: eaddr=ixreg-11;break;
+    case 0x16: eaddr=ixreg-10;break;
+    case 0x17: eaddr=ixreg-9;break;
+    case 0x18: eaddr=ixreg-8;break;
+    case 0x19: eaddr=ixreg-7;break;
+    case 0x1A: eaddr=ixreg-6;break;
+    case 0x1B: eaddr=ixreg-5;break;
+    case 0x1C: eaddr=ixreg-4;break;
+    case 0x1D: eaddr=ixreg-3;break;
+    case 0x1E: eaddr=ixreg-2;break;
+    case 0x1F: eaddr=ixreg-1;break;
+    case 0x20: eaddr=iyreg;break;
+    case 0x21: eaddr=iyreg+1;break;
+    case 0x22: eaddr=iyreg+2;break;
+    case 0x23: eaddr=iyreg+3;break;
+    case 0x24: eaddr=iyreg+4;break;
+    case 0x25: eaddr=iyreg+5;break;
+    case 0x26: eaddr=iyreg+6;break;
+    case 0x27: eaddr=iyreg+7;break;
+    case 0x28: eaddr=iyreg+8;break;
+    case 0x29: eaddr=iyreg+9;break;
+    case 0x2A: eaddr=iyreg+10;break;
+    case 0x2B: eaddr=iyreg+11;break;
+    case 0x2C: eaddr=iyreg+12;break;
+    case 0x2D: eaddr=iyreg+13;break;
+    case 0x2E: eaddr=iyreg+14;break;
+    case 0x2F: eaddr=iyreg+15;break;
+    case 0x30: eaddr=iyreg-16;break;
+    case 0x31: eaddr=iyreg-15;break;
+    case 0x32: eaddr=iyreg-14;break;
+    case 0x33: eaddr=iyreg-13;break;
+    case 0x34: eaddr=iyreg-12;break;
+    case 0x35: eaddr=iyreg-11;break;
+    case 0x36: eaddr=iyreg-10;break;
+    case 0x37: eaddr=iyreg-9;break;
+    case 0x38: eaddr=iyreg-8;break;
+    case 0x39: eaddr=iyreg-7;break;
+    case 0x3A: eaddr=iyreg-6;break;
+    case 0x3B: eaddr=iyreg-5;break;
+    case 0x3C: eaddr=iyreg-4;break;
+    case 0x3D: eaddr=iyreg-3;break;
+    case 0x3E: eaddr=iyreg-2;break;
+    case 0x3F: eaddr=iyreg-1;break;
+    case 0x40: eaddr=iureg;break;
+    case 0x41: eaddr=iureg+1;break;
+    case 0x42: eaddr=iureg+2;break;
+    case 0x43: eaddr=iureg+3;break;
+    case 0x44: eaddr=iureg+4;break;
+    case 0x45: eaddr=iureg+5;break;
+    case 0x46: eaddr=iureg+6;break;
+    case 0x47: eaddr=iureg+7;break;
+    case 0x48: eaddr=iureg+8;break;
+    case 0x49: eaddr=iureg+9;break;
+    case 0x4A: eaddr=iureg+10;break;
+    case 0x4B: eaddr=iureg+11;break;
+    case 0x4C: eaddr=iureg+12;break;
+    case 0x4D: eaddr=iureg+13;break;
+    case 0x4E: eaddr=iureg+14;break;
+    case 0x4F: eaddr=iureg+15;break;
+    case 0x50: eaddr=iureg-16;break;
+    case 0x51: eaddr=iureg-15;break;
+    case 0x52: eaddr=iureg-14;break;
+    case 0x53: eaddr=iureg-13;break;
+    case 0x54: eaddr=iureg-12;break;
+    case 0x55: eaddr=iureg-11;break;
+    case 0x56: eaddr=iureg-10;break;
+    case 0x57: eaddr=iureg-9;break;
+    case 0x58: eaddr=iureg-8;break;
+    case 0x59: eaddr=iureg-7;break;
+    case 0x5A: eaddr=iureg-6;break;
+    case 0x5B: eaddr=iureg-5;break;
+    case 0x5C: eaddr=iureg-4;break;
+    case 0x5D: eaddr=iureg-3;break;
+    case 0x5E: eaddr=iureg-2;break;
+    case 0x5F: eaddr=iureg-1;break;
+    case 0x60: eaddr=isreg;break;
+    case 0x61: eaddr=isreg+1;break;
+    case 0x62: eaddr=isreg+2;break;
+    case 0x63: eaddr=isreg+3;break;
+    case 0x64: eaddr=isreg+4;break;
+    case 0x65: eaddr=isreg+5;break;
+    case 0x66: eaddr=isreg+6;break;
+    case 0x67: eaddr=isreg+7;break;
+    case 0x68: eaddr=isreg+8;break;
+    case 0x69: eaddr=isreg+9;break;
+    case 0x6A: eaddr=isreg+10;break;
+    case 0x6B: eaddr=isreg+11;break;
+    case 0x6C: eaddr=isreg+12;break;
+    case 0x6D: eaddr=isreg+13;break;
+    case 0x6E: eaddr=isreg+14;break;
+    case 0x6F: eaddr=isreg+15;break;
+    case 0x70: eaddr=isreg-16;break;
+    case 0x71: eaddr=isreg-15;break;
+    case 0x72: eaddr=isreg-14;break;
+    case 0x73: eaddr=isreg-13;break;
+    case 0x74: eaddr=isreg-12;break;
+    case 0x75: eaddr=isreg-11;break;
+    case 0x76: eaddr=isreg-10;break;
+    case 0x77: eaddr=isreg-9;break;
+    case 0x78: eaddr=isreg-8;break;
+    case 0x79: eaddr=isreg-7;break;
+    case 0x7A: eaddr=isreg-6;break;
+    case 0x7B: eaddr=isreg-5;break;
+    case 0x7C: eaddr=isreg-4;break;
+    case 0x7D: eaddr=isreg-3;break;
+    case 0x7E: eaddr=isreg-2;break;
+    case 0x7F: eaddr=isreg-1;break;
+    case 0x80: eaddr=ixreg;ixreg++;break;
+    case 0x81: eaddr=ixreg;ixreg+=2;break;
+    case 0x82: ixreg--;eaddr=ixreg;break;
+    case 0x83: ixreg-=2;eaddr=ixreg;break;
+    case 0x84: eaddr=ixreg;break;
+    case 0x85: eaddr=ixreg+SIGNED(ibreg);break;
+    case 0x86: eaddr=ixreg+SIGNED(iareg);break;
+    case 0x87: eaddr=0;break; /*ILELGAL*/
+    case 0x88: IMMBYTE(eaddr);eaddr=ixreg+SIGNED(eaddr);break;
+    case 0x89: IMMWORD(eaddr);eaddr+=ixreg;break;
+    case 0x8A: eaddr=0;break; /*ILLEGAL*/
+    case 0x8B: eaddr=ixreg+GETDREG;break;
+    case 0x8C: IMMBYTE(eaddr);eaddr=ipcreg+SIGNED(eaddr);break;
+    case 0x8D: IMMWORD(eaddr);eaddr+=ipcreg;break;
+    case 0x8E: eaddr=0;break; /*ILLEGAL*/
+    case 0x8F: IMMWORD(eaddr);break;
+    case 0x90: eaddr=ixreg;ixreg++;eaddr=GETWORD(eaddr);break;
+    case 0x91: eaddr=ixreg;ixreg+=2;eaddr=GETWORD(eaddr);break;
+    case 0x92: ixreg--;eaddr=ixreg;eaddr=GETWORD(eaddr);break;
+    case 0x93: ixreg-=2;eaddr=ixreg;eaddr=GETWORD(eaddr);break;
+    case 0x94: eaddr=ixreg;eaddr=GETWORD(eaddr);break;
+    case 0x95: eaddr=ixreg+SIGNED(ibreg);eaddr=GETWORD(eaddr);break;
+    case 0x96: eaddr=ixreg+SIGNED(iareg);eaddr=GETWORD(eaddr);break;
+    case 0x97: eaddr=0;break; /*ILELGAL*/
+    case 0x98: IMMBYTE(eaddr);eaddr=ixreg+SIGNED(eaddr);
+               eaddr=GETWORD(eaddr);break;
+    case 0x99: IMMWORD(eaddr);eaddr+=ixreg;eaddr=GETWORD(eaddr);break;
+    case 0x9A: eaddr=0;break; /*ILLEGAL*/
+    case 0x9B: eaddr=ixreg+GETDREG;eaddr=GETWORD(eaddr);break;
+    case 0x9C: IMMBYTE(eaddr);eaddr=ipcreg+SIGNED(eaddr);
+               eaddr=GETWORD(eaddr);break;
+    case 0x9D: IMMWORD(eaddr);eaddr+=ipcreg;eaddr=GETWORD(eaddr);break;
+    case 0x9E: eaddr=0;break; /*ILLEGAL*/
+    case 0x9F: IMMWORD(eaddr);eaddr=GETWORD(eaddr);break;
+    case 0xA0: eaddr=iyreg;iyreg++;break;
+    case 0xA1: eaddr=iyreg;iyreg+=2;break;
+    case 0xA2: iyreg--;eaddr=iyreg;break;
+    case 0xA3: iyreg-=2;eaddr=iyreg;break;
+    case 0xA4: eaddr=iyreg;break;
+    case 0xA5: eaddr=iyreg+SIGNED(ibreg);break;
+    case 0xA6: eaddr=iyreg+SIGNED(iareg);break;
+    case 0xA7: eaddr=0;break; /*ILELGAL*/
+    case 0xA8: IMMBYTE(eaddr);eaddr=iyreg+SIGNED(eaddr);break;
+    case 0xA9: IMMWORD(eaddr);eaddr+=iyreg;break;
+    case 0xAA: eaddr=0;break; /*ILLEGAL*/
+    case 0xAB: eaddr=iyreg+GETDREG;break;
+    case 0xAC: IMMBYTE(eaddr);eaddr=ipcreg+SIGNED(eaddr);break;
+    case 0xAD: IMMWORD(eaddr);eaddr+=ipcreg;break;
+    case 0xAE: eaddr=0;break; /*ILLEGAL*/
+    case 0xAF: IMMWORD(eaddr);break;
+    case 0xB0: eaddr=iyreg;iyreg++;eaddr=GETWORD(eaddr);break;
+    case 0xB1: eaddr=iyreg;iyreg+=2;eaddr=GETWORD(eaddr);break;
+    case 0xB2: iyreg--;eaddr=iyreg;eaddr=GETWORD(eaddr);break;
+    case 0xB3: iyreg-=2;eaddr=iyreg;eaddr=GETWORD(eaddr);break;
+    case 0xB4: eaddr=iyreg;eaddr=GETWORD(eaddr);break;
+    case 0xB5: eaddr=iyreg+SIGNED(ibreg);eaddr=GETWORD(eaddr);break;
+    case 0xB6: eaddr=iyreg+SIGNED(iareg);eaddr=GETWORD(eaddr);break;
+    case 0xB7: eaddr=0;break; /*ILELGAL*/
+    case 0xB8: IMMBYTE(eaddr);eaddr=iyreg+SIGNED(eaddr);
+               eaddr=GETWORD(eaddr);break;
+    case 0xB9: IMMWORD(eaddr);eaddr+=iyreg;eaddr=GETWORD(eaddr);break;
+    case 0xBA: eaddr=0;break; /*ILLEGAL*/
+    case 0xBB: eaddr=iyreg+GETDREG;eaddr=GETWORD(eaddr);break;
+    case 0xBC: IMMBYTE(eaddr);eaddr=ipcreg+SIGNED(eaddr);
+               eaddr=GETWORD(eaddr);break;
+    case 0xBD: IMMWORD(eaddr);eaddr+=ipcreg;eaddr=GETWORD(eaddr);break;
+    case 0xBE: eaddr=0;break; /*ILLEGAL*/
+    case 0xBF: IMMWORD(eaddr);eaddr=GETWORD(eaddr);break;
+    case 0xC0: eaddr=iureg;iureg++;break;
+    case 0xC1: eaddr=iureg;iureg+=2;break;
+    case 0xC2: iureg--;eaddr=iureg;break;
+    case 0xC3: iureg-=2;eaddr=iureg;break;
+    case 0xC4: eaddr=iureg;break;
+    case 0xC5: eaddr=iureg+SIGNED(ibreg);break;
+    case 0xC6: eaddr=iureg+SIGNED(iareg);break;
+    case 0xC7: eaddr=0;break; /*ILELGAL*/
+    case 0xC8: IMMBYTE(eaddr);eaddr=iureg+SIGNED(eaddr);break;
+    case 0xC9: IMMWORD(eaddr);eaddr+=iureg;break;
+    case 0xCA: eaddr=0;break; /*ILLEGAL*/
+    case 0xCB: eaddr=iureg+GETDREG;break;
+    case 0xCC: IMMBYTE(eaddr);eaddr=ipcreg+SIGNED(eaddr);break;
+    case 0xCD: IMMWORD(eaddr);eaddr+=ipcreg;break;
+    case 0xCE: eaddr=0;break; /*ILLEGAL*/
+    case 0xCF: IMMWORD(eaddr);break;
+    case 0xD0: eaddr=iureg;iureg++;eaddr=GETWORD(eaddr);break;
+    case 0xD1: eaddr=iureg;iureg+=2;eaddr=GETWORD(eaddr);break;
+    case 0xD2: iureg--;eaddr=iureg;eaddr=GETWORD(eaddr);break;
+    case 0xD3: iureg-=2;eaddr=iureg;eaddr=GETWORD(eaddr);break;
+    case 0xD4: eaddr=iureg;eaddr=GETWORD(eaddr);break;
+    case 0xD5: eaddr=iureg+SIGNED(ibreg);eaddr=GETWORD(eaddr);break;
+    case 0xD6: eaddr=iureg+SIGNED(iareg);eaddr=GETWORD(eaddr);break;
+    case 0xD7: eaddr=0;break; /*ILELGAL*/
+    case 0xD8: IMMBYTE(eaddr);eaddr=iureg+SIGNED(eaddr);
+               eaddr=GETWORD(eaddr);break;
+    case 0xD9: IMMWORD(eaddr);eaddr+=iureg;eaddr=GETWORD(eaddr);break;
+    case 0xDA: eaddr=0;break; /*ILLEGAL*/
+    case 0xDB: eaddr=iureg+GETDREG;eaddr=GETWORD(eaddr);break;
+    case 0xDC: IMMBYTE(eaddr);eaddr=ipcreg+SIGNED(eaddr);
+               eaddr=GETWORD(eaddr);break;
+    case 0xDD: IMMWORD(eaddr);eaddr+=ipcreg;eaddr=GETWORD(eaddr);break;
+    case 0xDE: eaddr=0;break; /*ILLEGAL*/
+    case 0xDF: IMMWORD(eaddr);eaddr=GETWORD(eaddr);break;
+    case 0xE0: eaddr=isreg;isreg++;break;
+    case 0xE1: eaddr=isreg;isreg+=2;break;
+    case 0xE2: isreg--;eaddr=isreg;break;
+    case 0xE3: isreg-=2;eaddr=isreg;break;
+    case 0xE4: eaddr=isreg;break;
+    case 0xE5: eaddr=isreg+SIGNED(ibreg);break;
+    case 0xE6: eaddr=isreg+SIGNED(iareg);break;
+    case 0xE7: eaddr=0;break; /*ILELGAL*/
+    case 0xE8: IMMBYTE(eaddr);eaddr=isreg+SIGNED(eaddr);break;
+    case 0xE9: IMMWORD(eaddr);eaddr+=isreg;break;
+    case 0xEA: eaddr=0;break; /*ILLEGAL*/
+    case 0xEB: eaddr=isreg+GETDREG;break;
+    case 0xEC: IMMBYTE(eaddr);eaddr=ipcreg+SIGNED(eaddr);break;
+    case 0xED: IMMWORD(eaddr);eaddr+=ipcreg;break;
+    case 0xEE: eaddr=0;break; /*ILLEGAL*/
+    case 0xEF: IMMWORD(eaddr);break;
+    case 0xF0: eaddr=isreg;isreg++;eaddr=GETWORD(eaddr);break;
+    case 0xF1: eaddr=isreg;isreg+=2;eaddr=GETWORD(eaddr);break;
+    case 0xF2: isreg--;eaddr=isreg;eaddr=GETWORD(eaddr);break;
+    case 0xF3: isreg-=2;eaddr=isreg;eaddr=GETWORD(eaddr);break;
+    case 0xF4: eaddr=isreg;eaddr=GETWORD(eaddr);break;
+    case 0xF5: eaddr=isreg+SIGNED(ibreg);eaddr=GETWORD(eaddr);break;
+    case 0xF6: eaddr=isreg+SIGNED(iareg);eaddr=GETWORD(eaddr);break;
+    case 0xF7: eaddr=0;break; /*ILELGAL*/
+    case 0xF8: IMMBYTE(eaddr);eaddr=isreg+SIGNED(eaddr);
+               eaddr=GETWORD(eaddr);break;
+    case 0xF9: IMMWORD(eaddr);eaddr+=isreg;eaddr=GETWORD(eaddr);break;
+    case 0xFA: eaddr=0;break; /*ILLEGAL*/
+    case 0xFB: eaddr=isreg+GETDREG;eaddr=GETWORD(eaddr);break;
+    case 0xFC: IMMBYTE(eaddr);eaddr=ipcreg+SIGNED(eaddr);
+               eaddr=GETWORD(eaddr);break;
+    case 0xFD: IMMWORD(eaddr);eaddr+=ipcreg;eaddr=GETWORD(eaddr);break;
+    case 0xFE: eaddr=0;break; /*ILLEGAL*/
+    case 0xFF: IMMWORD(eaddr);eaddr=GETWORD(eaddr);break;
+   }
+  }
+  switch(ireg) {
+   case 0x00: /*NEG direct*/ DIRECT tw=-mem[eaddr];SETSTATUS(0,mem[eaddr],tw)
+                             SETBYTE(eaddr,tw)break;
+   case 0x01: break;/*ILLEGAL*/
+   case 0x02: break;/*ILLEGAL*/
+   case 0x03: /*COM direct*/ DIRECT  tb=~mem[eaddr];SETNZ8(tb);SEC CLV
+                             SETBYTE(eaddr,tb)break;
+   case 0x04: /*LSR direct*/ DIRECT tb=mem[eaddr];if(tb&0x01)SEC else CLC
+                             if(tb&0x10)SEH else CLH tb>>=1;SETNZ8(tb)
+                             SETBYTE(eaddr,tb)break;
+   case 0x05: break;/* ILLEGAL*/
+   case 0x06: /*ROR direct*/ DIRECT tb=(iccreg&0x01)<<7;
+                             if(mem[eaddr]&0x01)SEC else CLC
+                             tw=(mem[eaddr]>>1)+tb;SETNZ8(tw)
+                             SETBYTE(eaddr,tw)
+                       	     break;
+   case 0x07: /*ASR direct*/ DIRECT tb=mem[eaddr];if(tb&0x01)SEC else CLC
+                             if(tb&0x10)SEH else CLH tb>>=1;
+                             if(tb&0x40)tb|=0x80;SETBYTE(eaddr,tb)SETNZ8(tb)
+                             break;
+   case 0x08: /*ASL direct*/ DIRECT tw=mem[eaddr]<<1;
+                             SETSTATUS(mem[eaddr],mem[eaddr],tw)
+                             SETBYTE(eaddr,tw)break;
+   case 0x09: /*ROL direct*/ DIRECT tb=mem[eaddr];tw=iccreg&0x01;
+                             if(tb&0x80)SEC else CLC
+                             if((tb&0x80)^((tb<<1)&0x80))SEV else CLV
+                             tb=(tb<<1)+tw;SETNZ8(tb) SETBYTE(eaddr,tb)break;
+   case 0x0A: /*DEC direct*/ DIRECT tb=mem[eaddr]-1;if(tb==0x7F)SEV else CLV
+   			     SETNZ8(tb) SETBYTE(eaddr,tb)break;
+   case 0x0B: break; /*ILLEGAL*/
+   case 0x0C: /*INC direct*/ DIRECT tb=mem[eaddr]+1;if(tb==0x80)SEV else CLV
+   			     SETNZ8(tb) SETBYTE(eaddr,tb)break;
+   case 0x0D: /*TST direct*/ DIRECT tb=mem[eaddr];SETNZ8(tb) break;
+   case 0x0E: /*JMP direct*/ DIRECT ipcreg=eaddr;break;
+   case 0x0F: /*CLR direct*/ DIRECT SETBYTE(eaddr,0);CLN CLV SEZ CLC break;
+   case 0x10: /* flag10 */ iflag=1;goto flaginstr;
+   case 0x11: /* flag11 */ iflag=2;goto flaginstr;
+   case 0x12: /* NOP */ break;
+   case 0x13: /* SYNC */ 
+                         do  usleep(USLEEP); /* Wait for IRQ */
+                         while(!irq && !attention);
+		         if(iccreg&0x40)tracetrick=1;
+		         break;
+   case 0x14: break; /*ILLEGAL*/
+   case 0x15: break; /*ILLEGAL*/
+   case 0x16: /*LBRA*/ IMMWORD(eaddr) ipcreg+=eaddr;break;
+   case 0x17: /*LBSR*/ IMMWORD(eaddr) PUSHWORD(ipcreg) ipcreg+=eaddr;break;
+   case 0x18: break; /*ILLEGAL*/
+   case 0x19: /* DAA*/ 	tw=iareg;
+			if(iccreg&0x20)tw+=6;
+			if((tw&0x0f)>9)tw+=6;
+ 			if(iccreg&0x01)tw+=0x60;
+ 			if((tw&0xf0)>0x90)tw+=0x60;
+ 			if(tw&0x100)SEC
+ 			iareg=tw;break;
+   case 0x1A: /* ORCC*/ IMMBYTE(tb) iccreg|=tb;break;
+   case 0x1B: break; /*ILLEGAL*/
+   case 0x1C: /* ANDCC*/ IMMBYTE(tb) iccreg&=tb;break;
+   case 0x1D: /* SEX */ tw=SIGNED(ibreg); SETNZ16(tw) SETDREG(tw) break;
+   case 0x1E: /* EXG */ IMMBYTE(tb) {Word t2;GETREG(tw,tb>>4) GETREG(t2,tb&15)
+                        SETREG(t2,tb>>4) SETREG(tw,tb&15) } break;
+   case 0x1F: /* TFR */ IMMBYTE(tb) GETREG(tw,tb>>4) SETREG(tw,tb&15) break;
+   case 0x20: /* (L)BRA*/  BRANCH(1) break;
+   case 0x21: /* (L)BRN*/  BRANCH(0) break;
+   case 0x22: /* (L)BHI*/  BRANCH(!(iccreg&0x05)) break;
+   case 0x23: /* (L)BLS*/  BRANCH(iccreg&0x05) break;
+   case 0x24: /* (L)BCC*/  BRANCH(!(iccreg&0x01)) break;
+   case 0x25: /* (L)BCS*/  BRANCH(iccreg&0x01) break;
+   case 0x26: /* (L)BNE*/  BRANCH(!(iccreg&0x04)) break;
+   case 0x27: /* (L)BEQ*/  BRANCH(iccreg&0x04) break;
+   case 0x28: /* (L)BVC*/  BRANCH(!(iccreg&0x02)) break;
+   case 0x29: /* (L)BVS*/  BRANCH(iccreg&0x02) break;
+   case 0x2A: /* (L)BPL*/  BRANCH(!(iccreg&0x08)) break;
+   case 0x2B: /* (L)BMI*/  BRANCH(iccreg&0x08) break;
+   case 0x2C: /* (L)BGE*/  BRANCH(!NXORV) break;
+   case 0x2D: /* (L)BLT*/  BRANCH(NXORV) break;
+   case 0x2E: /* (L)BGT*/  BRANCH(!(NXORV||iccreg&0x04)) break;
+   case 0x2F: /* (L)BLE*/  BRANCH(NXORV||iccreg&0x04) break;
+   case 0x30: /* LEAX*/ ixreg=eaddr; if(ixreg) CLZ else SEZ break;
+   case 0x31: /* LEAY*/ iyreg=eaddr; if(iyreg) CLZ else SEZ break;
+   case 0x32: /* LEAS*/ isreg=eaddr;break;
+   case 0x33: /* LEAU*/ iureg=eaddr;break;
+   case 0x34: /* PSHS*/ IMMBYTE(tb)
+   		if(tb&0x80)PUSHWORD(ipcreg)
+	        if(tb&0x40)PUSHWORD(iureg)
+		if(tb&0x20)PUSHWORD(iyreg)
+	        if(tb&0x10)PUSHWORD(ixreg)
+                if(tb&0x08)PUSHBYTE(idpreg)
+                if(tb&0x04)PUSHBYTE(ibreg)
+                if(tb&0x02)PUSHBYTE(iareg)
+                if(tb&0x01)PUSHBYTE(iccreg) break;
+   case 0x35: /* PULS*/ IMMBYTE(tb)
+	        if(tb&0x01)PULLBYTE(iccreg)
+   		if(tb&0x02)PULLBYTE(iareg)
+     		if(tb&0x04)PULLBYTE(ibreg)
+   		if(tb&0x08)PULLBYTE(idpreg)
+     		if(tb&0x10)PULLWORD(ixreg)
+ 		if(tb&0x20)PULLWORD(iyreg)
+ 		if(tb&0x40)PULLWORD(iureg)
+ 		if(tb&0x80)PULLWORD(ipcreg)
+ 		if(tracetrick&&tb==0xff) { /* Arrange fake FIRQ after next insn
+ 		for hardware tracing */
+		  tracetrick=0;
+		  irq=2;
+		  attention=1;
+		  goto flaginstr;
+ 		}
+ 		break;
+   case 0x36: /* PSHU*/ IMMBYTE(tb)
+   		if(tb&0x80)PSHUWORD(ipcreg)
+	        if(tb&0x40)PSHUWORD(isreg)
+		if(tb&0x20)PSHUWORD(iyreg)
+	        if(tb&0x10)PSHUWORD(ixreg)
+                if(tb&0x08)PSHUBYTE(idpreg)
+                if(tb&0x04)PSHUBYTE(ibreg)
+                if(tb&0x02)PSHUBYTE(iareg)
+                if(tb&0x01)PSHUBYTE(iccreg) break;
+   case 0x37: /* PULU*/ IMMBYTE(tb)
+	        if(tb&0x01)PULUBYTE(iccreg)
+   		if(tb&0x02)PULUBYTE(iareg)
+     		if(tb&0x04)PULUBYTE(ibreg)
+   		if(tb&0x08)PULUBYTE(idpreg)
+     		if(tb&0x10)PULUWORD(ixreg)
+ 		if(tb&0x20)PULUWORD(iyreg)
+ 		if(tb&0x40)PULUWORD(isreg)
+ 		if(tb&0x80)PULUWORD(ipcreg) break;
+   case 0x39: /* RTS*/ PULLWORD(ipcreg) break;
+   case 0x3A: /* ABX*/ ixreg+=ibreg; break;
+   case 0x3B: /* RTI*/  tb=iccreg&0x80;
+			PULLBYTE(iccreg)
+			if(tb)
+ 			{
+  			 PULLBYTE(iareg)
+  			 PULLBYTE(ibreg)
+  			 PULLBYTE(idpreg)
+  			 PULLWORD(ixreg)
+	  		 PULLWORD(iyreg)
+  			 PULLWORD(iureg)
+ 			}
+			PULLWORD(ipcreg) break;
+   case 0x3C: /* CWAI*/ IMMBYTE(tb)
+   			 PUSHWORD(ipcreg)
+   			 PUSHWORD(iureg)
+                   	 PUSHWORD(iyreg)
+   			 PUSHWORD(ixreg)
+   			 PUSHBYTE(idpreg)
+   			 PUSHBYTE(ibreg)
+   			 PUSHBYTE(iareg)
+   			 PUSHBYTE(iccreg)
+   			 iccreg&=tb;
+                         iccreg|=0x80;
+                      do     usleep(USLEEP); /* Wait for IRQ */
+                      while(!attention && !((irq==1&&!(iccreg&0x10))||(irq==2&&!(iccreg&0x040))));
+                         if(irq==1)ipcreg=GETWORD(0xfff8);
+                         	else ipcreg=GETWORD(0xfff6);
+                         irq=0;
+                         if(!tracing)attention=0;
+   			 break;
+   case 0x3D: /* MUL*/ tw=iareg*ibreg; if(tw)CLZ else SEZ
+                       if(tw&0x80) SEC else CLC SETDREG(tw) break;
+   case 0x3E: break; /*ILLEGAL*/
+   case 0x3F: /* SWI (SWI2 SWI3)*/ {
+			 PUSHWORD(ipcreg)
+			 PUSHWORD(iureg)
+                   	 PUSHWORD(iyreg)
+   			 PUSHWORD(ixreg)
+   			 PUSHBYTE(idpreg)
+   			 PUSHBYTE(ibreg)
+   			 PUSHBYTE(iareg)
+   			 PUSHBYTE(iccreg)
+   			 iccreg|=0x80;
+   			 if(!iflag)iccreg|=0x50;
+   			 switch(iflag) {
+                          case 0:ipcreg=GETWORD(0xfffa);break;
+                          case 1:ipcreg=GETWORD(0xfff4);break;
+                          case 2:ipcreg=GETWORD(0xfff2);break;
+                         }
+		      }break;
+   case 0x40: /*NEGA*/  tw=-iareg;SETSTATUS(0,iareg,tw)
+                             iareg=tw;break;
+   case 0x41: break;/*ILLEGAL*/
+   case 0x42: break;/*ILLEGAL*/
+   case 0x43: /*COMA*/   tb=~iareg;SETNZ8(tb);SEC CLV
+                             iareg=tb;break;
+   case 0x44: /*LSRA*/  tb=iareg;if(tb&0x01)SEC else CLC
+                             if(tb&0x10)SEH else CLH tb>>=1;SETNZ8(tb)
+                             iareg=tb;break;
+   case 0x45: break;/* ILLEGAL*/
+   case 0x46: /*RORA*/  tb=(iccreg&0x01)<<7;
+                             if(iareg&0x01)SEC else CLC
+                             iareg=(iareg>>1)+tb;SETNZ8(iareg)
+                       	     break;
+   case 0x47: /*ASRA*/  tb=iareg;if(tb&0x01)SEC else CLC
+                             if(tb&0x10)SEH else CLH tb>>=1;
+                             if(tb&0x40)tb|=0x80;iareg=tb;SETNZ8(tb)
+                             break;
+   case 0x48: /*ASLA*/  tw=iareg<<1;
+                             SETSTATUS(iareg,iareg,tw)
+                             iareg=tw;break;
+   case 0x49: /*ROLA*/  tb=iareg;tw=iccreg&0x01;
+                             if(tb&0x80)SEC else CLC
+                             if((tb&0x80)^((tb<<1)&0x80))SEV else CLV
+                             tb=(tb<<1)+tw;SETNZ8(tb) iareg=tb;break;
+   case 0x4A: /*DECA*/  tb=iareg-1;if(tb==0x7F)SEV else CLV
+   			     SETNZ8(tb) iareg=tb;break;
+   case 0x4B: break; /*ILLEGAL*/
+   case 0x4C: /*INCA*/  tb=iareg+1;if(tb==0x80)SEV else CLV
+   			     SETNZ8(tb) iareg=tb;break;
+   case 0x4D: /*TSTA*/  SETNZ8(iareg) break;
+   case 0x4E: break; /*ILLEGAL*/
+   case 0x4F: /*CLRA*/  iareg=0;CLN CLV SEZ CLC break;
+   case 0x50: /*NEGB*/  tw=-ibreg;SETSTATUS(0,ibreg,tw)
+                             ibreg=tw;break;
+   case 0x51: break;/*ILLEGAL*/
+   case 0x52: break;/*ILLEGAL*/
+   case 0x53: /*COMB*/   tb=~ibreg;SETNZ8(tb);SEC CLV
+                             ibreg=tb;break;
+   case 0x54: /*LSRB*/  tb=ibreg;if(tb&0x01)SEC else CLC
+                             if(tb&0x10)SEH else CLH tb>>=1;SETNZ8(tb)
+                             ibreg=tb;break;
+   case 0x55: break;/* ILLEGAL*/
+   case 0x56: /*RORB*/  tb=(iccreg&0x01)<<7;
+                             if(ibreg&0x01)SEC else CLC
+                             ibreg=(ibreg>>1)+tb;SETNZ8(ibreg)
+                       	     break;
+   case 0x57: /*ASRB*/  tb=ibreg;if(tb&0x01)SEC else CLC
+                             if(tb&0x10)SEH else CLH tb>>=1;
+                             if(tb&0x40)tb|=0x80;ibreg=tb;SETNZ8(tb)
+                             break;
+   case 0x58: /*ASLB*/  tw=ibreg<<1;
+                             SETSTATUS(ibreg,ibreg,tw)
+                             ibreg=tw;break;
+   case 0x59: /*ROLB*/  tb=ibreg;tw=iccreg&0x01;
+                             if(tb&0x80)SEC else CLC
+                             if((tb&0x80)^((tb<<1)&0x80))SEV else CLV
+                             tb=(tb<<1)+tw;SETNZ8(tb) ibreg=tb;break;
+   case 0x5A: /*DECB*/  tb=ibreg-1;if(tb==0x7F)SEV else CLV
+   			     SETNZ8(tb) ibreg=tb;break;
+   case 0x5B: break; /*ILLEGAL*/
+   case 0x5C: /*INCB*/  tb=ibreg+1;if(tb==0x80)SEV else CLV
+   			     SETNZ8(tb) ibreg=tb;break;
+   case 0x5D: /*TSTB*/  SETNZ8(ibreg) break;
+   case 0x5E: break; /*ILLEGAL*/
+   case 0x5F: /*CLRB*/  ibreg=0;CLN CLV SEZ CLC break;
+   case 0x60: /*NEG indexed*/  tw=-mem[eaddr];SETSTATUS(0,mem[eaddr],tw)
+                             SETBYTE(eaddr,tw)break;
+   case 0x61: break;/*ILLEGAL*/
+   case 0x62: break;/*ILLEGAL*/
+   case 0x63: /*COM indexed*/   tb=~mem[eaddr];SETNZ8(tb);SEC CLV
+                             SETBYTE(eaddr,tb)break;
+   case 0x64: /*LSR indexed*/  tb=mem[eaddr];if(tb&0x01)SEC else CLC
+                             if(tb&0x10)SEH else CLH tb>>=1;SETNZ8(tb)
+                             SETBYTE(eaddr,tb)break;
+   case 0x65: break;/* ILLEGAL*/
+   case 0x66: /*ROR indexed*/  tb=(iccreg&0x01)<<7;
+                             if(mem[eaddr]&0x01)SEC else CLC
+                             tw=(mem[eaddr]>>1)+tb;SETNZ8(tw)
+                             SETBYTE(eaddr,tw)
+                       	     break;
+   case 0x67: /*ASR indexed*/  tb=mem[eaddr];if(tb&0x01)SEC else CLC
+                             if(tb&0x10)SEH else CLH tb>>=1;
+                             if(tb&0x40)tb|=0x80;SETBYTE(eaddr,tb)SETNZ8(tb)
+                             break;
+   case 0x68: /*ASL indexed*/  tw=mem[eaddr]<<1;
+                             SETSTATUS(mem[eaddr],mem[eaddr],tw)
+                             SETBYTE(eaddr,tw)break;
+   case 0x69: /*ROL indexed*/  tb=mem[eaddr];tw=iccreg&0x01;
+                             if(tb&0x80)SEC else CLC
+                             if((tb&0x80)^((tb<<1)&0x80))SEV else CLV
+                             tb=(tb<<1)+tw;SETNZ8(tb) SETBYTE(eaddr,tb)break;
+   case 0x6A: /*DEC indexed*/  tb=mem[eaddr]-1;if(tb==0x7F)SEV else CLV
+   			     SETNZ8(tb) SETBYTE(eaddr,tb)break;
+   case 0x6B: break; /*ILLEGAL*/
+   case 0x6C: /*INC indexed*/  tb=mem[eaddr]+1;if(tb==0x80)SEV else CLV
+   			     SETNZ8(tb) SETBYTE(eaddr,tb)break;
+   case 0x6D: /*TST indexed*/  tb=mem[eaddr];SETNZ8(tb) break;
+   case 0x6E: /*JMP indexed*/  ipcreg=eaddr;break;
+   case 0x6F: /*CLR indexed*/  SETBYTE(eaddr,0)CLN CLV SEZ CLC break;
+   case 0x70: /*NEG ext*/ EXTENDED tw=-mem[eaddr];SETSTATUS(0,mem[eaddr],tw)
+                             SETBYTE(eaddr,tw)break;
+   case 0x71: break;/*ILLEGAL*/
+   case 0x72: break;/*ILLEGAL*/
+   case 0x73: /*COM ext*/ EXTENDED  tb=~mem[eaddr];SETNZ8(tb);SEC CLV
+                            SETBYTE(eaddr,tb)break;
+   case 0x74: /*LSR ext*/ EXTENDED tb=mem[eaddr];if(tb&0x01)SEC else CLC
+                             if(tb&0x10)SEH else CLH tb>>=1;SETNZ8(tb)
+                             SETBYTE(eaddr,tb)break;
+   case 0x75: break;/* ILLEGAL*/
+   case 0x76: /*ROR ext*/ EXTENDED tb=(iccreg&0x01)<<7;
+                             if(mem[eaddr]&0x01)SEC else CLC
+                             tw=(mem[eaddr]>>1)+tb;SETNZ8(tw)
+                             SETBYTE(eaddr,tw)
+                       	     break;
+   case 0x77: /*ASR ext*/ EXTENDED tb=mem[eaddr];if(tb&0x01)SEC else CLC
+                             if(tb&0x10)SEH else CLH tb>>=1;
+                             if(tb&0x40)tb|=0x80;SETBYTE(eaddr,tb)SETNZ8(tb)
+                             break;
+   case 0x78: /*ASL ext*/ EXTENDED tw=mem[eaddr]<<1;
+                             SETSTATUS(mem[eaddr],mem[eaddr],tw)
+                             SETBYTE(eaddr,tw)break;
+   case 0x79: /*ROL ext*/ EXTENDED tb=mem[eaddr];tw=iccreg&0x01;
+                             if(tb&0x80)SEC else CLC
+                             if((tb&0x80)^((tb<<1)&0x80))SEV else CLV
+                             tb=(tb<<1)+tw;SETNZ8(tb) SETBYTE(eaddr,tb)break;
+   case 0x7A: /*DEC ext*/ EXTENDED tb=mem[eaddr]-1;if(tb==0x7F)SEV else CLV
+   			     SETNZ8(tb) SETBYTE(eaddr,tb)break;
+   case 0x7B: break; /*ILLEGAL*/
+   case 0x7C: /*INC ext*/ EXTENDED tb=mem[eaddr]+1;if(tb==0x80)SEV else CLV
+   			     SETNZ8(tb) SETBYTE(eaddr,tb)break;
+   case 0x7D: /*TST ext*/ EXTENDED tb=mem[eaddr];SETNZ8(tb) break;
+   case 0x7E: /*JMP ext*/ EXTENDED ipcreg=eaddr;break;
+   case 0x7F: /*CLR ext*/ EXTENDED SETBYTE(eaddr,0)CLN CLV SEZ CLC break;
+   case 0x80: /*SUBA immediate*/ IMM8 tw=iareg-mem[eaddr];
+                                 SETSTATUS(iareg,mem[eaddr],tw)
+                                 iareg=tw;break;
+   case 0x81: /*CMPA immediate*/ IMM8 tw=iareg-mem[eaddr];
+   				 SETSTATUS(iareg,mem[eaddr],tw) break;
+   case 0x82: /*SBCA immediate*/ IMM8 tw=iareg-mem[eaddr]-(iccreg&0x01);
+   				 SETSTATUS(iareg,mem[eaddr],tw)
+   				 iareg=tw;break;
+   case 0x83: /*SUBD (CMPD CMPU) immediate*/ IMM16
+                                 {unsigned long res,dreg,breg;
+                                 if(iflag==2)dreg=iureg;else dreg=GETDREG;
+                                 breg=GETWORD(eaddr);
+                                 res=dreg-breg;
+                                 SETSTATUSD(dreg,breg,res)
+                                 if(iflag==0) SETDREG(res)
+                                 }break;
+   case 0x84: /*ANDA immediate*/ IMM8 iareg=iareg&mem[eaddr];SETNZ8(iareg)
+   				 CLV break;
+   case 0x85: /*BITA immediate*/ IMM8 tb=iareg&mem[eaddr];SETNZ8(tb)
+   				 CLV break;
+   case 0x86: /*LDA immediate*/ IMM8 LOADAC(iareg) CLV SETNZ8(iareg)
+                                 break;
+   case 0x87: /*STA immediate (for the sake of orthogonality) */ IMM8
+                                 SETNZ8(iareg) CLV STOREAC(iareg) break;
+   case 0x88: /*EORA immediate*/ IMM8 iareg=iareg^mem[eaddr];SETNZ8(iareg)
+   				 CLV break;
+   case 0x89: /*ADCA immediate*/ IMM8 tw=iareg+mem[eaddr]+(iccreg&0x01);
+                                 SETSTATUS(iareg,mem[eaddr],tw)
+                                 iareg=tw;break;
+   case 0x8A: /*ORA immediate*/  IMM8 iareg=iareg|mem[eaddr];SETNZ8(iareg)
+   				 CLV break;
+   case 0x8B: /*ADDA immediate*/ IMM8 tw=iareg+mem[eaddr];
+   				 SETSTATUS(iareg,mem[eaddr],tw)
+   				 iareg=tw;break;
+   case 0x8C: /*CMPX (CMPY CMPS) immediate */ IMM16
+                                 {unsigned long dreg,breg,res;
+   				 if(iflag==0)dreg=ixreg;else if(iflag==1)
+   				 dreg=iyreg;else dreg=isreg;breg=GETWORD(eaddr);
+   				 res=dreg-breg;
+   				 SETSTATUSD(dreg,breg,res)
+   				 }break;
+   case 0x8D: /*BSR */   IMMBYTE(tb) PUSHWORD(ipcreg) ipcreg+=SIGNED(tb);
+                         break;
+   case 0x8E: /* LDX (LDY) immediate */ IMM16 tw=GETWORD(eaddr);
+                                  CLV SETNZ16(tw) if(!iflag)ixreg=tw; else
+                                  iyreg=tw;break;
+   case 0x8F:  /* STX (STY) immediate (orthogonality) */ IMM16
+                                  if(!iflag) tw=ixreg; else tw=iyreg;
+                                  CLV SETNZ16(tw) SETWORD(eaddr,tw) break;
+   case 0x90: /*SUBA direct*/ DIRECT tw=iareg-mem[eaddr];
+                                 SETSTATUS(iareg,mem[eaddr],tw)
+                                 iareg=tw;break;
+   case 0x91: /*CMPA direct*/ DIRECT tw=iareg-mem[eaddr];
+   				 SETSTATUS(iareg,mem[eaddr],tw) break;
+   case 0x92: /*SBCA direct*/ DIRECT tw=iareg-mem[eaddr]-(iccreg&0x01);
+   				 SETSTATUS(iareg,mem[eaddr],tw)
+   				 iareg=tw;break;
+   case 0x93: /*SUBD (CMPD CMPU) direct*/ DIRECT
+                                 {unsigned long res,dreg,breg;
+                                 if(iflag==2)dreg=iureg;else dreg=GETDREG;
+                                 breg=GETWORD(eaddr);
+                                 res=dreg-breg;
+                                 SETSTATUSD(dreg,breg,res)
+                                 if(iflag==0) SETDREG(res)
+                                 }break;
+   case 0x94: /*ANDA direct*/ DIRECT iareg=iareg&mem[eaddr];SETNZ8(iareg)
+   				 CLV break;
+   case 0x95: /*BITA direct*/ DIRECT tb=iareg&mem[eaddr];SETNZ8(tb)
+   				 CLV break;
+   case 0x96: /*LDA direct*/ DIRECT LOADAC(iareg) CLV SETNZ8(iareg)
+                                 break;
+   case 0x97: /*STA direct */ DIRECT
+                                 SETNZ8(iareg) CLV STOREAC(iareg) break;
+   case 0x98: /*EORA direct*/ DIRECT iareg=iareg^mem[eaddr];SETNZ8(iareg)
+   				 CLV break;
+   case 0x99: /*ADCA direct*/ DIRECT tw=iareg+mem[eaddr]+(iccreg&0x01);
+                                 SETSTATUS(iareg,mem[eaddr],tw)
+                                 iareg=tw;break;
+   case 0x9A: /*ORA direct*/  DIRECT iareg=iareg|mem[eaddr];SETNZ8(iareg)
+   				 CLV break;
+   case 0x9B: /*ADDA direct*/ DIRECT tw=iareg+mem[eaddr];
+   				 SETSTATUS(iareg,mem[eaddr],tw)
+   				 iareg=tw;break;
+   case 0x9C: /*CMPX (CMPY CMPS) direct */ DIRECT
+                                 {unsigned long dreg,breg,res;
+   				 if(iflag==0)dreg=ixreg;else if(iflag==1)
+   				 dreg=iyreg;else dreg=isreg;breg=GETWORD(eaddr);
+   				 res=dreg-breg;
+   				 SETSTATUSD(dreg,breg,res)
+   				 }break;
+   case 0x9D: /*JSR direct */  DIRECT  PUSHWORD(ipcreg) ipcreg=eaddr;
+                         break;
+   case 0x9E: /* LDX (LDY) direct */ DIRECT tw=GETWORD(eaddr);
+                                  CLV SETNZ16(tw) if(!iflag)ixreg=tw; else
+                                  iyreg=tw;break;
+   case 0x9F:  /* STX (STY) direct */ DIRECT
+                                  if(!iflag) tw=ixreg; else tw=iyreg;
+                                  CLV SETNZ16(tw) SETWORD(eaddr,tw) break;
+   case 0xA0: /*SUBA indexed*/  tw=iareg-mem[eaddr];
+                                 SETSTATUS(iareg,mem[eaddr],tw)
+                                 iareg=tw;break;
+   case 0xA1: /*CMPA indexed*/  tw=iareg-mem[eaddr];
+   				 SETSTATUS(iareg,mem[eaddr],tw) break;
+   case 0xA2: /*SBCA indexed*/  tw=iareg-mem[eaddr]-(iccreg&0x01);
+   				 SETSTATUS(iareg,mem[eaddr],tw)
+   				 iareg=tw;break;
+   case 0xA3: /*SUBD (CMPD CMPU) indexed*/
+                                 {unsigned long res,dreg,breg;
+                                 if(iflag==2)dreg=iureg;else dreg=GETDREG;
+                                 breg=GETWORD(eaddr);
+                                 res=dreg-breg;
+                                 SETSTATUSD(dreg,breg,res)
+                                 if(iflag==0) SETDREG(res)
+                                 }break;
+   case 0xA4: /*ANDA indexed*/  iareg=iareg&mem[eaddr];SETNZ8(iareg)
+   				 CLV break;
+   case 0xA5: /*BITA indexed*/  tb=iareg&mem[eaddr];SETNZ8(tb)
+   				 CLV break;
+   case 0xA6: /*LDA indexed*/  LOADAC(iareg) CLV SETNZ8(iareg)
+                                 break;
+   case 0xA7: /*STA indexed */
+                                 SETNZ8(iareg) CLV STOREAC(iareg) break;
+   case 0xA8: /*EORA indexed*/  iareg=iareg^mem[eaddr];SETNZ8(iareg)
+   				 CLV break;
+   case 0xA9: /*ADCA indexed*/  tw=iareg+mem[eaddr]+(iccreg&0x01);
+                                 SETSTATUS(iareg,mem[eaddr],tw)
+                                 iareg=tw;break;
+   case 0xAA: /*ORA indexed*/   iareg=iareg|mem[eaddr];SETNZ8(iareg)
+   				 CLV break;
+   case 0xAB: /*ADDA indexed*/  tw=iareg+mem[eaddr];
+   				 SETSTATUS(iareg,mem[eaddr],tw)
+   				 iareg=tw;break;
+   case 0xAC: /*CMPX (CMPY CMPS) indexed */
+                                 {unsigned long dreg,breg,res;
+   				 if(iflag==0)dreg=ixreg;else if(iflag==1)
+   				 dreg=iyreg;else dreg=isreg;breg=GETWORD(eaddr);
+   				 res=dreg-breg;
+   				 SETSTATUSD(dreg,breg,res)
+   				 }break;
+   case 0xAD: /*JSR indexed */    PUSHWORD(ipcreg) ipcreg=eaddr;
+                         break;
+   case 0xAE: /* LDX (LDY) indexed */  tw=GETWORD(eaddr);
+                                  CLV SETNZ16(tw) if(!iflag)ixreg=tw; else
+                                  iyreg=tw;break;
+   case 0xAF:  /* STX (STY) indexed */
+                                  if(!iflag) tw=ixreg; else tw=iyreg;
+                                  CLV SETNZ16(tw) SETWORD(eaddr,tw) break;
+   case 0xB0: /*SUBA ext*/ EXTENDED tw=iareg-mem[eaddr];
+                                 SETSTATUS(iareg,mem[eaddr],tw)
+                                 iareg=tw;break;
+   case 0xB1: /*CMPA ext*/ EXTENDED tw=iareg-mem[eaddr];
+   				 SETSTATUS(iareg,mem[eaddr],tw) break;
+   case 0xB2: /*SBCA ext*/ EXTENDED tw=iareg-mem[eaddr]-(iccreg&0x01);
+   				 SETSTATUS(iareg,mem[eaddr],tw)
+   				 iareg=tw;break;
+   case 0xB3: /*SUBD (CMPD CMPU) ext*/ EXTENDED
+                                 {unsigned long res,dreg,breg;
+                                 if(iflag==2)dreg=iureg;else dreg=GETDREG;
+                                 breg=GETWORD(eaddr);
+                                 res=dreg-breg;
+                                 SETSTATUSD(dreg,breg,res)
+                                 if(iflag==0) SETDREG(res)
+                                 }break;
+   case 0xB4: /*ANDA ext*/ EXTENDED iareg=iareg&mem[eaddr];SETNZ8(iareg)
+   				 CLV break;
+   case 0xB5: /*BITA ext*/ EXTENDED tb=iareg&mem[eaddr];SETNZ8(tb)
+   				 CLV break;
+   case 0xB6: /*LDA ext*/ EXTENDED LOADAC(iareg) CLV SETNZ8(iareg)
+                                 break;
+   case 0xB7: /*STA ext */ EXTENDED
+                                 SETNZ8(iareg) CLV STOREAC(iareg) break;
+   case 0xB8: /*EORA ext*/ EXTENDED iareg=iareg^mem[eaddr];SETNZ8(iareg)
+   				 CLV break;
+   case 0xB9: /*ADCA ext*/ EXTENDED tw=iareg+mem[eaddr]+(iccreg&0x01);
+                                 SETSTATUS(iareg,mem[eaddr],tw)
+                                 iareg=tw;break;
+   case 0xBA: /*ORA ext*/  EXTENDED iareg=iareg|mem[eaddr];SETNZ8(iareg)
+   				 CLV break;
+   case 0xBB: /*ADDA ext*/ EXTENDED tw=iareg+mem[eaddr];
+   				 SETSTATUS(iareg,mem[eaddr],tw)
+   				 iareg=tw;break;
+   case 0xBC: /*CMPX (CMPY CMPS) ext */ EXTENDED
+                                 {unsigned long dreg,breg,res;
+   				 if(iflag==0)dreg=ixreg;else if(iflag==1)
+   				 dreg=iyreg;else dreg=isreg;breg=GETWORD(eaddr);
+   				 res=dreg-breg;
+   				 SETSTATUSD(dreg,breg,res)
+   				 }break;
+   case 0xBD: /*JSR ext */  EXTENDED  PUSHWORD(ipcreg) ipcreg=eaddr;
+                         break;
+   case 0xBE: /* LDX (LDY) ext */ EXTENDED tw=GETWORD(eaddr);
+                                  CLV SETNZ16(tw) if(!iflag)ixreg=tw; else
+                                  iyreg=tw;break;
+   case 0xBF:  /* STX (STY) ext */ EXTENDED
+                                  if(!iflag) tw=ixreg; else tw=iyreg;
+                                  CLV SETNZ16(tw) SETWORD(eaddr,tw) break;
+   case 0xC0: /*SUBB immediate*/ IMM8 tw=ibreg-mem[eaddr];
+                                 SETSTATUS(ibreg,mem[eaddr],tw)
+                                 ibreg=tw;break;
+   case 0xC1: /*CMPB immediate*/ IMM8 tw=ibreg-mem[eaddr];
+   				 SETSTATUS(ibreg,mem[eaddr],tw) break;
+   case 0xC2: /*SBCB immediate*/ IMM8 tw=ibreg-mem[eaddr]-(iccreg&0x01);
+   				 SETSTATUS(ibreg,mem[eaddr],tw)
+   				 ibreg=tw;break;
+   case 0xC3: /*ADDD immediate*/ IMM16
+                                 {unsigned long res,dreg,breg;
+                                 dreg=GETDREG;
+                                 breg=GETWORD(eaddr);
+                                 res=dreg+breg;
+                                 SETSTATUSD(dreg,breg,res)
+                                 SETDREG(res)
+                                 }break;
+   case 0xC4: /*ANDB immediate*/ IMM8 ibreg=ibreg&mem[eaddr];SETNZ8(ibreg)
+   				 CLV break;
+   case 0xC5: /*BITB immediate*/ IMM8 tb=ibreg&mem[eaddr];SETNZ8(tb)
+   				 CLV break;
+   case 0xC6: /*LDB immediate*/ IMM8 LOADAC(ibreg) CLV SETNZ8(ibreg)
+                                 break;
+   case 0xC7: /*STB immediate (for the sake of orthogonality) */ IMM8
+                                 SETNZ8(ibreg) CLV STOREAC(ibreg) break;
+   case 0xC8: /*EORB immediate*/ IMM8 ibreg=ibreg^mem[eaddr];SETNZ8(ibreg)
+   				 CLV break;
+   case 0xC9: /*ADCB immediate*/ IMM8 tw=ibreg+mem[eaddr]+(iccreg&0x01);
+                                 SETSTATUS(ibreg,mem[eaddr],tw)
+                                 ibreg=tw;break;
+   case 0xCA: /*ORB immediate*/  IMM8 ibreg=ibreg|mem[eaddr];SETNZ8(ibreg)
+   				 CLV break;
+   case 0xCB: /*ADDB immediate*/ IMM8 tw=ibreg+mem[eaddr];
+   				 SETSTATUS(ibreg,mem[eaddr],tw)
+   				 ibreg=tw;break;
+   case 0xCC: /*LDD immediate */ IMM16 tw=GETWORD(eaddr);SETNZ16(tw)
+   			         CLV SETDREG(tw) break;
+   case 0xCD: /*STD immediate (orthogonality) */ IMM16
+   				 tw=GETDREG; SETNZ16(tw) CLV
+   				 SETWORD(eaddr,tw) break;
+   case 0xCE: /* LDU (LDS) immediate */ IMM16 tw=GETWORD(eaddr);
+                                  CLV SETNZ16(tw) if(!iflag)iureg=tw; else
+                                  isreg=tw;break;
+   case 0xCF:  /* STU (STS) immediate (orthogonality) */ IMM16
+                                  if(!iflag) tw=iureg; else tw=isreg;
+                                  CLV SETNZ16(tw) SETWORD(eaddr,tw) break;
+   case 0xD0: /*SUBB direct*/ DIRECT tw=ibreg-mem[eaddr];
+                                 SETSTATUS(ibreg,mem[eaddr],tw)
+                                 ibreg=tw;break;
+   case 0xD1: /*CMPB direct*/ DIRECT tw=ibreg-mem[eaddr];
+   				 SETSTATUS(ibreg,mem[eaddr],tw) break;
+   case 0xD2: /*SBCB direct*/ DIRECT tw=ibreg-mem[eaddr]-(iccreg&0x01);
+   				 SETSTATUS(ibreg,mem[eaddr],tw)
+   				 ibreg=tw;break;
+   case 0xD3: /*ADDD direct*/ DIRECT
+                                 {unsigned long res,dreg,breg;
+                                 dreg=GETDREG;
+                                 breg=GETWORD(eaddr);
+                                 res=dreg+breg;
+                                 SETSTATUSD(dreg,breg,res)
+                                 SETDREG(res)
+                                 }break;
+   case 0xD4: /*ANDB direct*/ DIRECT ibreg=ibreg&mem[eaddr];SETNZ8(ibreg)
+   				 CLV break;
+   case 0xD5: /*BITB direct*/ DIRECT tb=ibreg&mem[eaddr];SETNZ8(tb)
+   				 CLV break;
+   case 0xD6: /*LDB direct*/ DIRECT LOADAC(ibreg) CLV SETNZ8(ibreg)
+                                 break;
+   case 0xD7: /*STB direct  */ DIRECT
+                                 SETNZ8(ibreg) CLV STOREAC(ibreg) break;
+   case 0xD8: /*EORB direct*/ DIRECT ibreg=ibreg^mem[eaddr];SETNZ8(ibreg)
+   				 CLV break;
+   case 0xD9: /*ADCB direct*/ DIRECT tw=ibreg+mem[eaddr]+(iccreg&0x01);
+                                 SETSTATUS(ibreg,mem[eaddr],tw)
+                                 ibreg=tw;break;
+   case 0xDA: /*ORB direct*/  DIRECT ibreg=ibreg|mem[eaddr];SETNZ8(ibreg)
+   				 CLV break;
+   case 0xDB: /*ADDB direct*/ DIRECT tw=ibreg+mem[eaddr];
+   				 SETSTATUS(ibreg,mem[eaddr],tw)
+   				 ibreg=tw;break;
+   case 0xDC: /*LDD direct */ DIRECT tw=GETWORD(eaddr);SETNZ16(tw)
+   			         CLV SETDREG(tw) break;
+   case 0xDD: /*STD direct  */ DIRECT
+   				 tw=GETDREG; SETNZ16(tw) CLV
+   				 SETWORD(eaddr,tw) break;
+   case 0xDE: /* LDU (LDS) direct */ DIRECT tw=GETWORD(eaddr);
+                                  CLV SETNZ16(tw) if(!iflag)iureg=tw; else
+                                  isreg=tw;break;
+   case 0xDF:  /* STU (STS) direct  */ DIRECT
+                                  if(!iflag) tw=iureg; else tw=isreg;
+                                  CLV SETNZ16(tw) SETWORD(eaddr,tw) break;
+   case 0xE0: /*SUBB indexed*/  tw=ibreg-mem[eaddr];
+                                 SETSTATUS(ibreg,mem[eaddr],tw)
+                                 ibreg=tw;break;
+   case 0xE1: /*CMPB indexed*/  tw=ibreg-mem[eaddr];
+   				 SETSTATUS(ibreg,mem[eaddr],tw) break;
+   case 0xE2: /*SBCB indexed*/  tw=ibreg-mem[eaddr]-(iccreg&0x01);
+   				 SETSTATUS(ibreg,mem[eaddr],tw)
+   				 ibreg=tw;break;
+   case 0xE3: /*ADDD indexed*/
+                                 {unsigned long res,dreg,breg;
+                                 dreg=GETDREG;
+                                 breg=GETWORD(eaddr);
+                                 res=dreg+breg;
+                                 SETSTATUSD(dreg,breg,res)
+                                 SETDREG(res)
+                                 }break;
+   case 0xE4: /*ANDB indexed*/  ibreg=ibreg&mem[eaddr];SETNZ8(ibreg)
+   				 CLV break;
+   case 0xE5: /*BITB indexed*/  tb=ibreg&mem[eaddr];SETNZ8(tb)
+   				 CLV break;
+   case 0xE6: /*LDB indexed*/  LOADAC(ibreg) CLV SETNZ8(ibreg)
+                                 break;
+   case 0xE7: /*STB indexed  */
+                                 SETNZ8(ibreg) CLV STOREAC(ibreg) break;
+   case 0xE8: /*EORB indexed*/  ibreg=ibreg^mem[eaddr];SETNZ8(ibreg)
+   				 CLV break;
+   case 0xE9: /*ADCB indexed*/  tw=ibreg+mem[eaddr]+(iccreg&0x01);
+                                 SETSTATUS(ibreg,mem[eaddr],tw)
+                                 ibreg=tw;break;
+   case 0xEA: /*ORB indexed*/   ibreg=ibreg|mem[eaddr];SETNZ8(ibreg)
+   				 CLV break;
+   case 0xEB: /*ADDB indexed*/  tw=ibreg+mem[eaddr];
+   				 SETSTATUS(ibreg,mem[eaddr],tw)
+   				 ibreg=tw;break;
+   case 0xEC: /*LDD indexed */  tw=GETWORD(eaddr);SETNZ16(tw)
+   			         CLV SETDREG(tw) break;
+   case 0xED: /*STD indexed  */
+   				 tw=GETDREG; SETNZ16(tw) CLV
+   				 SETWORD(eaddr,tw) break;
+   case 0xEE: /* LDU (LDS) indexed */  tw=GETWORD(eaddr);
+                                  CLV SETNZ16(tw) if(!iflag)iureg=tw; else
+                                  isreg=tw;break;
+   case 0xEF:  /* STU (STS) indexed  */
+                                  if(!iflag) tw=iureg; else tw=isreg;
+                                  CLV SETNZ16(tw) SETWORD(eaddr,tw) break;
+   case 0xF0: /*SUBB ext*/ EXTENDED tw=ibreg-mem[eaddr];
+                                 SETSTATUS(ibreg,mem[eaddr],tw)
+                                 ibreg=tw;break;
+   case 0xF1: /*CMPB ext*/ EXTENDED tw=ibreg-mem[eaddr];
+   				 SETSTATUS(ibreg,mem[eaddr],tw) break;
+   case 0xF2: /*SBCB ext*/ EXTENDED tw=ibreg-mem[eaddr]-(iccreg&0x01);
+   				 SETSTATUS(ibreg,mem[eaddr],tw)
+   				 ibreg=tw;break;
+   case 0xF3: /*ADDD ext*/ EXTENDED
+                                 {unsigned long res,dreg,breg;
+                                 dreg=GETDREG;
+                                 breg=GETWORD(eaddr);
+                                 res=dreg+breg;
+                                 SETSTATUSD(dreg,breg,res)
+                                 SETDREG(res)
+                                 }break;
+   case 0xF4: /*ANDB ext*/ EXTENDED ibreg=ibreg&mem[eaddr];SETNZ8(ibreg)
+   				 CLV break;
+   case 0xF5: /*BITB ext*/ EXTENDED tb=ibreg&mem[eaddr];SETNZ8(tb)
+   				 CLV break;
+   case 0xF6: /*LDB ext*/ EXTENDED LOADAC(ibreg) CLV SETNZ8(ibreg)
+                                 break;
+   case 0xF7: /*STB ext  */ EXTENDED
+                                 SETNZ8(ibreg) CLV STOREAC(ibreg) break;
+   case 0xF8: /*EORB ext*/ EXTENDED ibreg=ibreg^mem[eaddr];SETNZ8(ibreg)
+   				 CLV break;
+   case 0xF9: /*ADCB ext*/ EXTENDED tw=ibreg+mem[eaddr]+(iccreg&0x01);
+                                 SETSTATUS(ibreg,mem[eaddr],tw)
+                                 ibreg=tw;break;
+   case 0xFA: /*ORB ext*/  EXTENDED ibreg=ibreg|mem[eaddr];SETNZ8(ibreg)
+   				 CLV break;
+   case 0xFB: /*ADDB ext*/ EXTENDED tw=ibreg+mem[eaddr];
+   				 SETSTATUS(ibreg,mem[eaddr],tw)
+   				 ibreg=tw;break;
+   case 0xFC: /*LDD ext */ EXTENDED tw=GETWORD(eaddr);SETNZ16(tw)
+   			         CLV SETDREG(tw) break;
+   case 0xFD: /*STD ext  */ EXTENDED
+   				 tw=GETDREG; SETNZ16(tw) CLV
+   				 SETWORD(eaddr,tw) break;
+   case 0xFE: /* LDU (LDS) ext */ EXTENDED tw=GETWORD(eaddr);
+                                  CLV SETNZ16(tw) if(!iflag)iureg=tw; else
+                                  isreg=tw;break;
+   case 0xFF:  /* STU (STS) ext  */ EXTENDED
+                                  if(!iflag) tw=iureg; else tw=isreg;
+                                  CLV SETNZ16(tw) SETWORD(eaddr,tw) break;
+
+
+  }
+ }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/io.c	Mon Jul 02 02:12:31 2018 +0900
@@ -0,0 +1,479 @@
+/* 6809 Simulator V09.
+
+   created 1993,1994 by L.C. Benschop.
+   copyleft (c) 1994-2014 by the sbc09 team, see AUTHORS for more details.
+   license: GNU General Public License version 2, see LICENSE for more details.
+
+   This program simulates a 6809 processor.
+
+   System dependencies: short must be 16 bits.
+   char  must be 8 bits.
+   long must be more than 16 bits.
+   arrays up to 65536 bytes must be supported.
+   machine must be twos complement.
+   Most Unix machines will work. For MSODS you need long pointers
+   and you may have to malloc() the mem array of 65536 bytes.
+
+   Define BIG_ENDIAN if you have a big-endian machine (680x0 etc)
+
+   Special instructions:
+   SWI2 writes char to stdout from register B.
+   SWI3 reads char from stdout to register B, sets carry at EOF.
+   (or when no key available when using term control).
+   SWI retains its normal function.
+   CWAI and SYNC stop simulator.
+
+*/
+
+#include<stdio.h>
+#include<stdlib.h>
+#include<ctype.h>
+#include<signal.h>
+#include<sys/time.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+
+#ifdef USE_TERMIOS
+#include <termios.h>
+#endif
+
+#define engine extern
+#include "v09.h"
+
+int tflags;
+int timer = 1;
+struct termios termsetting;
+
+int xmstat; /* 0= no XMODEM transfer, 1=send, 2=receiver */
+unsigned char xmbuf[132];
+int xidx;
+int acknak;
+int rcvdnak;
+int blocknum;
+
+FILE *logfile;
+FILE *infile;
+FILE *xfile;
+
+extern void hexadump( unsigned char *b, int l, int loc, int w);
+extern void disasm(int,int);
+
+
+int char_input(void) {
+        int c, w, sum;
+        if (!xmstat) {
+                if (infile) {
+                        c = getc(infile);
+                        if (c == EOF) {
+                                fclose(infile);
+                                infile = 0;
+                                return char_input();
+                        }
+                        if (c == '\n')
+                                c = '\r';
+                        return c;
+                } else
+                        return getchar();
+        } else if (xmstat == 1) {
+                if (xidx) {
+                        c = xmbuf[xidx++];
+                        if (xidx == 132) {
+                                xidx = 0;
+                                rcvdnak = EOF;
+                                acknak = 6;
+                        }
+                } else {
+                        if ((acknak == 21 && rcvdnak == 21) || (acknak == 6 && rcvdnak == 6)) {
+                                rcvdnak = 0;
+                                memset(xmbuf, 0, 132);
+                                w = fread(xmbuf + 3, 1, 128, xfile);
+                                if (w) {
+                                        printf("Block %3d transmitted, ", blocknum);
+                                        xmbuf[0] = 1;
+                                        xmbuf[1] = blocknum;
+                                        xmbuf[2] = 255 - blocknum;
+                                        blocknum = (blocknum + 1) & 255;
+                                        sum = 0;
+                                        for (w = 3; w < 131; w++)
+                                                sum = (sum + xmbuf[w]) & 255;
+                                        xmbuf[131] = sum;
+                                        acknak = 6;
+                                        c = 1;
+                                        xidx = 1;
+                                } else {
+                                        printf("EOT transmitted, ");
+                                        acknak = 4;
+                                        c = 4;
+                                }
+                        } else if (rcvdnak == 21) {
+                                rcvdnak = 0;
+                                printf("Block %3d retransmitted, ", xmbuf[1]);
+                                c = xmbuf[xidx++]; /*retransmit the same block */
+                        } else
+                                c = EOF;
+                }
+                return c;
+        } else {
+                if (acknak == 4) {
+                        c = 6;
+                        acknak = 0;
+                        fclose(xfile);
+                        xfile = 0;
+                        xmstat = 0;
+                } else if (acknak) {
+                        c = acknak;
+                        acknak = 0;
+                } else
+                        c = EOF;
+                if (c == 6)
+                        printf("ACK\n");
+                if (c == 21)
+                        printf("NAK\n");
+                return c;
+        }
+}
+
+int do_input( a) {
+        static int c, f = EOF;
+        if (a == 0) {
+                if (f == EOF)
+                        f = char_input();
+                if (f != EOF)
+                        c = f;
+                return 2 + (f != EOF);
+        } else if (a == 1) { /*data port*/
+                if (f == EOF)
+                        f = char_input();
+                if (f != EOF) {
+                        c = f;
+                        f = EOF;
+                }
+                return c;
+        }
+        return 0;
+}
+
+void do_output(int a, int c) {
+        int i, sum;
+        if (a == 1) { /* ACIA data port,ignore address */
+                if (!xmstat) {
+                        if (logfile && c != 127 && (c >= ' ' || c == '\n'))
+                                putc(c, logfile);
+                        putchar(c);
+                        fflush(stdout);
+                } else if (xmstat == 1) {
+                        rcvdnak = c;
+                        if (c == 6 && acknak == 4) {
+                                fclose(xfile);
+                                xfile = 0;
+                                xmstat = 0;
+                        }
+                        if (c == 6)
+                                printf("ACK\n");
+                        if (c == 21)
+                                printf("NAK\n");
+                        if (c == 24) {
+                                printf("CAN\n");
+                                fclose(xfile);
+                                xmstat = 0;
+                                xfile = 0;
+                        }
+                } else {
+                        if (xidx == 0 && c == 4) {
+                                acknak = 4;
+                                printf("EOT received, ");
+                        }
+                        xmbuf[xidx++] = c;
+                        if (xidx == 132) {
+                                sum = 0;
+                                for (i = 3; i < 131; i++)
+                                        sum = (sum + xmbuf[i]) & 255;
+                                if (xmbuf[0] == 1 && xmbuf[1] == 255 - xmbuf[2]
+                                                && sum == xmbuf[131])
+                                        acknak = 6;
+                                else
+                                        acknak = 21;
+                                printf("Block %3d received, ", xmbuf[1]);
+                                if (blocknum == xmbuf[1]) {
+                                        blocknum = (blocknum + 1) & 255;
+                                        fwrite(xmbuf + 3, 1, 128, xfile);
+                                }
+                                xidx = 0;
+                        }
+                }
+        }
+}
+
+void restore_term(void) {
+        tcsetattr(0, TCSAFLUSH, &termsetting);
+        fcntl(0, F_SETFL, tflags);
+        signal(SIGALRM, SIG_IGN);
+}
+
+void do_exit(void) {
+        restore_term();
+        exit(0);
+}
+
+typedef struct bp {
+  int address;
+  int count;
+  struct bp *next;
+} BP, *BPTR;
+
+BPTR breakpoint = 0;
+int bpskip = 0;
+int trskip = 0;
+int stkskip = 0;
+
+int getarg(char *buf, char** next) {
+        return strtol(buf,(char**)next,0);
+}
+
+void printhelp(void)
+{
+  printf( 
+     "  s [count]  one step trace\n"
+     "  n          step over\n"
+     "  f          finish this call (until stack pop)\n"
+     "  b [adr]    set break point\n"
+     "  l          break point list\n"
+     "  d [n]      delte break point list\n"
+     "  c  [count] continue;\n"
+     "  x  [adr]   dump\n"
+     "  xi [adr]   disassemble\n"
+     "  L  file    start log to file\n"
+     "  S  file    set input file\n"
+     "  X  exit\n"
+     "  q  exit\n"
+     "  U  file    upload from srecord file \n"
+     "  D  file    download to srecord file \n"
+     "  R  do reset\n"
+     "  h,?  print this\n"
+    );
+}
+
+void do_escape(void) {
+        char s[80];
+        int adr,skip;
+        if (bpskip) { // skip unbreak instruction
+            bpskip--;
+            for(BPTR b = breakpoint; b ; b=b->next) {
+                if (pcreg==b->address) {
+                    if (b->count) b->count--;
+                    if (b->count==0) {
+                        goto restart0;
+                    }
+                }
+            }
+            return;
+        }
+        if (stkskip) { // skip until return
+           if (sreg < stkskip ) return;
+        }
+restart0:
+        stkskip = 0;
+        restore_term();
+        do_trace(stdout);
+        if (trskip>1) { // show trace and step
+            trskip--;
+            set_term(escchar);
+            return; 
+        }
+restart:
+        printf("v09>");
+        fgets(s, 80, stdin);
+        if (s[0])
+                s[strlen(s) - 1] = 0;
+        switch (s[0]) {
+        case 's':   // one step trace
+                trskip = 1;
+                if (s[1]) {
+                   trskip = getarg(s+1,0);
+                }
+                bpskip = 0;
+                attention = escape = 1;
+                break;
+        case 'n':   // step over
+                stkskip = sreg;
+                attention = escape = 1;
+                break;
+        case 'f':   // finish this call (until stack pop)
+                stkskip = sreg + 2;
+                attention = escape = 1;
+                break;
+        case 'b':   // set break point
+                {
+                  BPTR bp = calloc(1,sizeof(BP));
+                  bp->next = breakpoint;
+                  breakpoint = bp;
+                  bp->count = 1;
+                  if (s[1]) {
+                     char *next;
+                     bp->address = getarg(s+1,&next);
+                     if (next[0]) {
+                         bp->count = getarg(next,&next);
+                     }
+                  } else {
+                     bp->address = pcreg;
+                  }
+                }
+                bpskip = -1;
+                goto restart;
+        case 'l':   // break point list
+                for(BPTR bp = breakpoint; bp ; bp = bp->next) {
+                    printf("%x %i\n", bp->address, bp->count);
+                }
+                goto restart;
+        case 'd':   // delte break point list
+                if (s[1]) {
+                   int trskip = getarg(s+1,0);
+                   BPTR *prev = &breakpoint;
+                   for(BPTR bp = breakpoint; bp ; bp = bp->next) {
+                       if (trskip-- == 0) {
+                          if (bp) {
+                              *prev = bp->next;
+                          }
+                          break;
+                       }
+                       prev = &bp->next;
+                   }
+                }
+                goto restart;
+        case 'c':   // continue;
+                bpskip = -1;
+                attention = escape = 1;
+                if (s[1]) {
+                   bpskip = getarg(s+1,0);
+                }
+                break;
+        case 'x':   // dump
+                skip = 1;
+                if (s[1]=='i') skip=2;
+                if (s[skip]) {
+                   char *next;
+                   int adr = getarg(s+skip,&next);
+                   int len = 32;
+                   if (next[0]) {
+                      len =  getarg(next,&next);
+                   }
+                   if (skip==2) {
+                        disasm(adr,adr+len);
+                   } else {
+                     for(int i=0; len > 0 ; i+=16, len-=16) {
+                        hexadump(mem+adr+i,len>16?16:len,adr+i,16);
+                     }
+                   }
+                } else 
+                   disasm(pcreg,pcreg+32);
+                goto restart;
+        case 'L':
+                if (logfile)
+                        fclose(logfile);
+                logfile = 0;
+                if (s[1]) {
+                        logfile = fopen(s + 1, "w");
+                }
+                break;
+        case 'S':
+                if (infile)
+                        fclose(infile);
+                infile = 0;
+                if (s[1]) {
+                        infile = fopen(s + 1, "r");
+                }
+                break;
+        case 'h':
+        case '?':
+                printhelp();
+                goto restart;
+        case 'X':
+        case 'q':
+                if (!xmstat)
+                        do_exit();
+                else {
+                        xmstat = 0;
+                        fclose(xfile);
+                        xfile = 0;
+                }
+                break;
+        case 'U':
+                if (xfile)
+                        fclose(xfile);
+                xfile = 0;
+                if (s[1]) {
+                        xfile = fopen(s + 1, "rb");
+                }
+                if (xfile)
+                        xmstat = 1;
+                else
+                        xmstat = 0;
+                xidx = 0;
+                acknak = 21;
+                rcvdnak = EOF;
+                blocknum = 1;
+                break;
+        case 'D':
+                if (xfile)
+                        fclose(xfile);
+                xfile = 0;
+                if (s[1]) {
+                        xfile = fopen(s + 1, "wb");
+                }
+                if (xfile)
+                        xmstat = 2;
+                else
+                        xmstat = 0;
+                xidx = 0;
+                acknak = 21;
+                blocknum = 1;
+                break;
+        case 'R':
+                pcreg = (mem[0xfffe] << 8) + mem[0xffff];
+                break;
+        }
+        if (tracing||breakpoint||trskip||bpskip||stkskip) { attention = escape = 1; }
+        else attention = 0;
+        set_term(escchar);
+}
+
+void timehandler(int sig) {
+        attention = 1;
+        irq = 2;
+        signal(SIGALRM, timehandler);
+}
+
+void handler(int sig) {
+        escape = 1;
+        attention = 1;
+        bpskip = 0;
+        stkskip = 0;
+}
+
+void set_term(char c) {
+        struct termios newterm;
+        struct itimerval timercontrol;
+        signal(SIGQUIT, SIG_IGN);
+        signal(SIGTSTP, SIG_IGN);
+        signal(SIGINT, handler);
+        signal(SIGUSR1, handler);
+        tcgetattr(0, &termsetting);
+        newterm = termsetting;
+        newterm.c_iflag = newterm.c_iflag & ~INLCR & ~ICRNL;
+        newterm.c_lflag = newterm.c_lflag & ~ECHO & ~ICANON;
+        newterm.c_cc[VTIME] = 0;
+        newterm.c_cc[VMIN] = 1;
+        newterm.c_cc[VINTR] = escchar;
+        tcsetattr(0, TCSAFLUSH, &newterm);
+        tflags = fcntl(0, F_GETFL, 0);
+        fcntl(0, F_SETFL, tflags | O_NDELAY); /* Make input from stdin non-blocking */
+        signal(SIGALRM, timehandler);
+        timercontrol.it_interval.tv_sec = 0;
+        timercontrol.it_interval.tv_usec = 20000;
+        timercontrol.it_value.tv_sec = 0;
+        timercontrol.it_value.tv_usec = 20000;
+        if (timer)
+            setitimer(ITIMER_REAL, &timercontrol, NULL);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/makerom.c	Mon Jul 02 02:12:31 2018 +0900
@@ -0,0 +1,78 @@
+/* makerom.c 
+   Read standard input as S-records and build ROM image file v09.rom
+   ROM starts at 0x8000 and is 32K.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+static int sum,charindex;
+unsigned char mem[0x8000];
+char linebuf[130];
+
+void
+hexerr()
+{
+ fprintf(stderr,"Illegal character in hex number\n");
+ exit(1);
+}
+
+int gethex()
+{
+ int c;
+ c=linebuf[charindex++];
+ if(c<'0')hexerr();
+ if(c>'9') { if(c<'A')hexerr();else c-=7; }
+ c-='0';
+ return c;
+}
+
+int getbyte() 
+{
+ int b;
+ b=gethex();
+ b=b*16+gethex();
+ sum=(sum+b)&0xff;
+ return b;
+}
+
+int
+main()
+{
+ FILE *romfile;
+ unsigned int i,length,addr;
+ for(i=0;i<0x8000;i++)mem[i]=0xff; /*set unused locations to FF */
+ for(;;) {
+  if(fgets(linebuf,128,stdin)==NULL)break;
+  if(strlen(linebuf))linebuf[strlen(linebuf)]=0;
+  if(linebuf[0]=='S'&&linebuf[1]=='1') {
+   sum=0;charindex=2;
+   length=getbyte();
+   if(length<3) {
+    fprintf(stderr,"Illegal length in data record\n");
+    exit(1);
+   }
+   addr=getbyte();
+   addr=(addr<<8)+getbyte();
+   if((long)addr+length-3>0x10000||addr<0x8000) {
+    fprintf(stderr,"Address 0x%x out of range\n",addr);
+    exit(1);
+   }
+   for(i=0;i!=length-3;i++)mem[addr-0x8000+i]=getbyte();
+   getbyte();
+   if(sum!=0xff) {
+    fprintf(stderr,"Checksum error\n");
+    exit(1);
+   }  
+  }
+ }
+ romfile=fopen("v09.rom","wb");
+ if(!romfile) {
+  fprintf(stderr,"Cannot create file v09.rom\n");
+  exit(1);
+ }
+ fwrite(mem,0x8000,1,romfile);
+ fclose(romfile);
+ exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mon2.asm	Mon Jul 02 02:12:31 2018 +0900
@@ -0,0 +1,3080 @@
+	;Buggy machine language monitor and rudimentary O.S. version 1.0
+
+* Memory map of SBC
+* $0-$40 Zero page variables reserved by monitor and O.S.
+* $40-$FF Zero page portion for user programs.
+* $100-$17F Xmodem buffer 0, terminal input buffer,
+* $180-$1FF Xmodem buffer 1, terminal output buffer.
+* $200-$27F Terminal input line.
+* $280-$2FF Variables reserved by monitor and O.S.
+* $300-$400 System stack.
+* $400-$7FFF RAM for user programs and data.
+* $8000-$DFFF PROM for user programs.
+* $E000-$E1FF I/O addresses.
+* $E200-$E3FF Reserved.
+* $E400-$FFFF Monitor ROM
+
+* Reserved Zero page addresses
+		org $0000
+* First the I/O routine vectors.
+getchar		rmb 3		;Jump to getchar routine.
+putchar		rmb 3		;Jump to putchar routine.
+getline		rmb 3		;Jump to getline routine.
+putline		rmb 3		;Jump to putline routine.
+putcr		rmb 3		;Jump to putcr routine.
+getpoll         rmb 3           ;Jump to getpoll routine.
+xopenin		rmb 3		;Jump to xopenin routine.
+xopenout	rmb 3		;Jump to xopenout routine.
+xabortin	rmb 3           ;Jump to xabortin routine.
+xclosein	rmb 3		;Jump to xclosein routine.
+xcloseout	rmb 3		;Jump to xcloseout routine.
+delay		rmb 3		;Jump to delay routine.
+
+*Next the system variables in the zero page.
+temp		rmb 2            ;hex scanning/disasm
+temp2		rmb 2            ;Hex scanning/disasm
+temp3 		rmb 2            ;Used in Srecords, H command
+timer		rmb 3            ;3 byte timer, incremented every 20ms
+xpacknum	rmb 1            ;Packet number for XMODEM block,
+xsum		rmb 1		 ;XMODEM checksum
+lastok		rmb 1            ;flag to indicate last block was OK
+xcount		rmb 1		 ;Count of characters in buffer.
+xmode 		rmb 1		 ;XMODEM mode, 0 none, 1 out, 2 in.
+disflg		rmb 1
+
+* I/O buffers.
+buflen		equ 128		;Length of input line buffer.
+		org $100
+buf0		rmb 128		;Xmodem buffer 0, serial input buffer.
+buf1		rmb 128		;Xmodem buffer 1, serial output buffer.
+linebuf		rmb buflen	;Input line buffer.
+
+
+* Interrupt vectors (start at $280)
+* All interrupts except RESET are vectored through jumps.
+* FIRQ is timer interrupt, IRQ is ACIA interrupt.
+swi3vec		rmb 3
+swi2vec		rmb 3
+firqvec		rmb 3
+irqvec		rmb 3
+swivec 		rmb 3
+nmivec		rmb 3
+xerrvec		rmb 3           ;Error handler for XMODEM error.
+exprvec		rmb 3		;Expression evaluator in assembler.
+asmerrvec	rmb 3		;Error handler for assembler errors.
+pseudovec	rmb 3		;Vector for asm pseudo instructions.
+
+* Next the non zero page system variables.
+oldpc		rmb 2		;Saved pc value for J command.
+addr		rmb 2		;Address parameter.
+length		rmb 2		;Length parameter.
+
+brkpoints 	equ 8		;Number of settable breakpoints. 
+bpaddr		rmb brkpoints*3 ;Address and byte for each break point.
+stepbp		rmb 3		;Address of P command break point.
+
+sorg		rmb 2		;Origin address of S record entry.
+soffs		rmb 2		;Offset load adrr-addr in record
+
+oldgetc		rmb 2		;Old getchar address.
+oldputc		rmb 2		;Old putchar address.
+oldputcr	rmb 2		;Old putcr address.
+lastterm	rmb 1		;Last terminating character.
+filler		rmb 1		;Filler at end of XMODEM file.
+xmcr		rmb 1		;end-of-line characters for XMODEM send.
+savesp		rmb 2		;Save sp to restore it on error.
+nxtadd		rmb 2
+
+* Following variables are used by assembler/disassembler.
+prebyte		rmb 1
+opc1		rmb 1
+opcode 		rmb 1
+postbyte	rmb 1
+amode		rmb 1
+operand		rmb 2		
+mnembuf		rmb 5		;Buffer to store capitalized mnemonic.
+opsize		rmb 1		;SIze (in bytes) of extra oeprand (0--2)
+uncert		rmb 1		;Flag to indicate that op is unknown.
+dpsetting	rmb 2
+
+endvars		equ *
+
+ramstart	equ $400	;first free RAM address.
+
+ramtop  	equ $8000       ;top of RAM.
+
+* I/O port addresses
+aciactl		equ $e000	;Control port of ACIA
+aciasta		equ $e000	;Status port of ACIA
+aciadat		equ $e001	;Data port of ACIA
+
+* ASCII control characters.
+SOH		equ 1
+EOT		equ 4
+ACK		equ 6
+BS		equ 8
+TAB		equ 9
+LF		equ 10
+CR		equ 13
+NAK		equ 21
+CAN		equ 24
+DEL		equ 127
+
+CASEMASK	equ $DF		;Mask to make lowercase into uppercase.
+
+* Monitor ROM starts here.
+		org $E400
+
+reset		orcc #$FF	;Disable interrupts.
+		clra		
+		tfr a,dp	;Set direct page register to 0.
+		clr disflg
+		lds #ramstart
+		ldx #intvectbl
+		ldu #swi3vec
+		ldb #osvectbl-intvectbl
+		bsr blockmove   ;Initialize interrupt vectors from ROM.
+		ldx #osvectbl
+		ldu #0
+		ldb #endvecs-osvectbl
+		bsr blockmove	;Initialize I/O vectors from ROM.
+		bsr initacia	;Initialize serial port.
+		andcc #$0	;Enable interrupts
+* Put the 'saved' registers of the program being monitored on top of the
+* stack. There are 12 bytes on the stack for cc,b,a,dp,x,y,u and pc
+* pc is initialized to $400, the rest to zero.
+		ldx #0          
+		tfr x,y
+		ldu #ramstart
+		pshs x,u
+		pshs x,y
+		pshs x,y  
+		ldx #oldpc
+		ldb #endvars-oldpc
+clvar		clr ,x+
+		decb
+		bne clvar	;Clear the variable area.	
+		ldd #$1A03	
+		std filler	;Set XMODEM filler and end-of-line.
+		ldx #welcome
+		jsr outcount
+		jsr putcr	;Print a welcome message.      
+		jmp cmdline
+* Block move routine, from X to U length B. Modifies them all and A. 
+blockmove	lda ,x+
+		sta ,u+
+		decb
+		bne blockmove
+		rts
+
+* Initialize serial communications port, buffers, interrupts.
+initacia	ldb #$03
+		stb aciactl
+		ldb #%00110101
+		rts
+
+* O.S. routine to read a character into B register.
+osgetc		ldb aciasta
+		bitb #$01
+		beq osgetc
+		ldb aciadat
+		rts
+
+;O.S. rotuine to check if there is a character ready to be read.
+osgetpoll       ldb aciasta
+		bitb #$01
+		bne poltrue
+		clrb
+		rts
+poltrue		ldb #$ff
+		rts
+
+* O.S. routine to write the character in the B register.
+osputc		pshs a
+putcloop	lda aciasta
+		bita #$02
+		beq putcloop
+		stb aciadat
+		puls a
+		rts
+
+* O.S. routine to read a line into memory at address X, at most B chars
+* long, return actual length in B. Permit backspace editing.
+osgetl		pshs a,x
+		stb temp
+		clra
+osgetl1		jsr getchar
+		andb #$7F      		
+		cmpb #BS
+		beq backsp
+		cmpb #DEL
+		bne osgetl2       
+backsp		tsta                  ;Recognize BS and DEL as backspace key.
+		beq osgetl1	      ;ignore if line already zero length.
+		ldb #BS
+		jsr putchar
+		ldb #' '
+		jsr putchar
+		ldb #BS		      ;Send BS,space,BS. This erases last
+		jsr putchar           ;character on most terminals.
+		leax -1,x	      ;Decrement address.
+		deca
+		bra osgetl1
+osgetl2		cmpb #CR
+		beq newline
+		cmpb #LF
+		bne osgetl3           ;CR or LF character ends line.
+		ldb lastterm
+		cmpb #CR
+		beq osgetl1	      ;Ignore LF if it comes after CR
+		ldb #LF		      
+newline         stb lastterm
+		jsr putcr             
+		tfr a,b               ;Move length to B
+		puls a,x              ;restore registers.
+		rts                   ;<--- Here is the exit point.
+osgetl3         cmpb #TAB
+		beq dotab		
+		cmpb #' '
+		blo osgetl1	      ;Ignore control characters.
+		cmpa temp
+		beq osgetl1	      ;Ignore char if line full.
+		jsr putchar           ;Echo the character.
+		stb ,x+               ;Store it in memory.
+		inca
+		bra osgetl1
+dotab		ldb #' '
+		cmpa temp
+		beq osgetl1
+		jsr putchar
+		stb ,x+
+		inca
+		bita #7		       ;Insert spaces until length mod 8=0
+		bne dotab
+		bra osgetl1 
+
+* O.S. routine to write a line starting at address X, B chars long.
+osputl		pshs a,b,x
+		tfr b,a
+		tsta
+		beq osputl1
+osputl2		ldb ,x+
+		jsr putchar
+		deca
+		bne osputl2
+osputl1		puls a,b,x
+		rts
+
+* O.S. routine to terminate a line.
+oscr		pshs b
+		ldb #CR
+		jsr putchar
+		ldb #LF
+		jsr putchar     ;Send the CR and LF characters.
+		puls b
+		rts
+
+* Output a counted string at addr X
+outcount	pshs x,b
+		ldb ,x+
+		jsr putline
+		puls x,b
+		rts
+
+timerirq	inc timer+2
+		bne endirq
+		inc timer+1
+		bne endirq
+		inc timer
+		rti
+aciairq		nop
+endirq		rti
+
+* Wait D times 20ms.
+osdly		addd timer+1
+dlyloop		cmpd timer+1
+		bne dlyloop
+		rts		
+
+* This table will be copied to the interrupt vector area in RAM.
+intvectbl	jmp endirq
+		jmp endirq
+		jmp timerirq
+		jmp aciairq
+		jmp unlaunch
+		jmp endirq
+		jmp xerrhand
+		jmp expr
+		jmp asmerrvec
+		jmp pseudo
+* And this one to the I/O vector table.
+osvectbl	jmp osgetc
+		jmp osputc
+		jmp osgetl
+		jmp osputl
+		jmp oscr		
+		jmp osgetpoll
+		jmp xopin
+		jmp xopout
+		jmp xabtin
+		jmp xclsin
+		jmp xclsout
+		jmp osdly
+endvecs 	equ *		
+		
+* The J command returns here.
+stakregs        pshs x		     ;Stack something where the pc comes
+		pshs ccr,b,a,dp,x,y,u ;Stack the normal registers.
+		ldx oldpc	
+		stx 10,s	     ;Stack the old pc value.
+		bra unlaunch1
+* The G and P commands return here through a breakpoint.
+* Registers are already stacked.
+unlaunch	ldd 10,s
+		subd #1
+		std 10,s	     ;Decrement pc before breakpoint
+unlaunch1	andcc #$0	     ;reenable the interrupts.
+		jsr disarm	     ;Disarm the breakpoints.
+		jsr dispregs 	     
+cmdline		jsr xcloseout
+		sts savesp
+		ldb #'.'
+		jsr putchar
+		ldx #linebuf
+		ldb #buflen
+                jsr getline
+		tstb
+		beq cmdline          ;Ignore line if it is empty
+		abx
+		clr ,x		     ;Make location after line zero.
+		ldx #linebuf
+		ldb ,x+
+		andb #CASEMASK	     ;Make 1st char uppercase.
+		subb #'A'            
+		bcs unk
+		cmpb #26
+		bcc unk		     ;Unknown cmd if it is not a letter.
+		ldx #cmdtab
+		aslb		      ;Index into command table.
+		jmp [b,x]
+
+cmdtab 		fdb asm,break,calc,dump
+		fdb enter,find,go,help
+		fdb inp,jump,unk,unk
+		fdb move,unk,unk,prog
+		fdb unk,regs,srec,trace
+		fdb unasm,unk,unk,xmodem
+		fdb unk,unk
+
+* Unknown command handling routine.
+unk		jsr xabortin
+		ldx #unknown
+		jsr outcount
+		jsr putcr
+		jmp cmdline
+
+help		ldx #mhelp   	;Print a help message.
+help1		ldb ,x+
+		beq endhlp
+		lbsr osputc
+		bra help1		
+endhlp		jmp cmdline
+mhelp		fcb	CR,LF
+		fcc	'Commands list'
+		fcb	CR,LF
+
+		fcc	'-------------'
+		fcb	CR,LF
+
+	        fcc 	'Asm    '
+		fcc	'{Aaddr}'
+		fcb	CR,LF
+
+		fcc	'Unasm  '
+		fcc	'{U or Uaddr or Uaddr,length}'
+		fcb	CR,LF
+
+		fcc	'Dump   '
+		fcc	'{D or D<addr> or D<addr>,<length>}'
+		fcb	CR,LF
+
+		fcc	'Enter  '
+		fcc	'{E or E<addr> or E<addr> <bytes> or E<addr>string}'
+		fcb	CR,LF
+
+		fcc	'Break  '
+		fcc	'{B or B<addr>. B displays, B<addr> sets or clears breakpoint}'
+		fcb	CR,LF
+
+		fcc	'Find   '
+		fcb	"{Faddr bytes or Faddr",34,"ascii",34,"}"
+		fcb	CR,LF
+
+		fcc	'Go     '
+		fcc	'{G or G<addr>}'
+		fcb	CR,LF
+
+		fcc	'Calc   '
+		fcc	'{Chexnum{+|-hexnum}}'
+		fcb	CR,LF
+
+		fcc	'Inp    '
+		fcc	'{Iaddr}'
+		fcb	CR,LF
+
+		fcc	'Jump   '
+		fcc	'{J<addr>}'
+		fcb	CR,LF
+
+		fcc	'Move   '
+		fcc	'{M<addr1>,<addr2>,<lenght>}'
+		fcb	CR,LF
+
+		fcc	'Prog   '
+		fcc	'{P}'
+		fcb	CR,LF
+
+		fcc	'Regs   '
+		fcc	'{R or R<letter><hex>}'
+		fcb	CR,LF
+
+		fcc	'Srec   '
+		fcc	'{SO<addr> or SS<addr>,<len> or S1<bytes> or S9<bytes>}'
+		fcb	CR,LF
+
+		fcc	'Trace  '
+		fcc	'{T}'
+		fcb	CR,LF
+
+		fcc	'Xmodem '
+		fcc	'{XSaddr,len XLaddr,len XX XOcrlf,filler, XSSaddr,len}'
+		fcb	CR,LF
+
+		fcc	'Help   '
+		fcc	'{H}'
+		fcb	CR,LF,0
+
+
+
+* Here are some useful messages.
+welcome		fcb unknown-welcome-1
+		fcc "Welcome to BUGGY version 1.0"
+unknown		fcb brkmsg-unknown-1
+		fcc "Unknown command"
+brkmsg		fcb clrmsg-brkmsg-1
+		fcc "Breakpoint set"
+clrmsg		fcb fullmsg-clrmsg-1
+		fcc "Breakpoint cleared"
+fullmsg		fcb smsg-fullmsg-1
+		fcc "Breakpoints full"
+smsg		fcb lastrec-smsg-1
+		fcc "Error in S record"
+lastrec		fcb xsmsg-lastrec-1
+		fcc "S9030000FC"
+xsmsg		fcb xrmsg-xsmsg-1
+		fcc "Start XMODEM Send"
+xrmsg		fcb xamsg-xrmsg-1
+		fcc "Start XMODEM Receive"
+xamsg		fcb invmmsg-xamsg-1
+		fcc "XMODEM transfer aborted"
+invmmsg		fcb exprmsg-invmmsg-1
+		fcc "Invalid mnemonic"
+exprmsg		fcb modemsg-exprmsg-1
+		fcc "Expression error"
+modemsg		fcb brmsg-modemsg-1
+		fcc "Addressing mode error"		
+brmsg		fcb endmsg-brmsg-1
+		fcc "Branch too long"
+endmsg		equ *
+
+* Output hex digit contained in A
+hexdigit 	adda #$90
+		daa
+		adca #$40
+		daa		;It's the standard conversion trick ascii
+		tfr a,b		;to hex without branching.
+		jsr putchar
+		rts
+
+* Output contents of A as two hex digits 
+outbyte		pshs a		
+		lsra
+		lsra
+		lsra
+		lsra
+		bsr hexdigit
+		puls a
+		anda #$0f
+		bra hexdigit
+
+* Output contents of d as four hex digits 
+outd		pshs b   
+		bsr outbyte
+		puls a
+		bsr outbyte
+		rts
+
+* Skip X past spaces, B is first non-space character.
+skipspace	ldb ,x+
+		cmpb #' '
+		beq skipspace
+		rts
+
+* Convert ascii hex digit in B register to binary Z flag set if no hex digit. 
+convb		subb #'0'
+		blo convexit
+		cmpb #9
+		bls cb2
+		andb #CASEMASK ;Make uppercase.
+		subb #7		;If higher than digit 9 it must be a letter.
+		cmpb #9
+		bls convexit
+		cmpb #15
+		bhi convexit
+cb2		andcc #$FB      ;clear zero	
+		rts
+convexit	orcc #$04
+		rts
+
+scanexit  	ldd temp
+		leax -1,x
+		tst temp2
+		rts		<-- exit point of scanhex
+
+* Scan for hexadecimal number at address X return in D, Z flag is set it no
+* number found.
+scanhex		clr temp    
+		clr temp+1
+		clr temp2
+		bsr skipspace
+scloop		jsr convb
+		beq scanexit
+		pshs b
+		ldd temp
+		aslb
+		rola
+		aslb
+		rola
+		aslb
+		rola
+		aslb
+		rola
+		addb ,s+
+		std temp
+		inc temp2
+		ldb ,x+
+		bra scloop
+
+scan2parms	std length
+		bsr scanhex
+		beq sp2
+		std addr
+		bsr skipspace
+		cmpb #','
+		bne sp2
+		bsr scanhex
+		beq sp2
+		std length				
+sp2 		rts
+
+* Scan two hexdigits at in and convert to byte into A, Z flag if error.
+scanbyte	bsr skipspace
+		bsr convb
+		beq sb1
+		tfr b,a
+		ldb ,x+
+		bsr convb
+		beq sb1
+		asla
+		asla
+		asla
+		asla
+		stb temp
+		adda temp
+		andcc #$fb	;Clear zero flag
+sb1		rts
+
+
+* This is the code for the D command, hex/ascii dump of memory
+* Syntax: D or D<addr> or D<addr>,<length>	
+dump	    	ldx #linebuf+1
+		ldd #$40	
+	        jsr scan2parms ;Scan address and length, default length=64
+		ldy addr
+dh1		lda #16
+		sta temp+1	
+		tfr y,d
+		jsr outd
+		ldb #' '
+		jsr putchar
+dh2		lda ,y+		;display row of 16 mem locations as hex
+		jsr outbyte
+		ldb #' '
+		lda temp+1
+		cmpa #9
+		bne dh6
+		ldb #'-'	;Do a - after the eighth byte.
+dh6		jsr putchar
+		dec temp+1
+		bne dh2
+		leay -16,y	;And now for the ascii dump.
+		lda #16
+dh3		ldb ,y+
+		cmpb #' '
+		bhs dh4
+		ldb #'.'            
+dh4		cmpb #DEL
+		blo dh5
+		ldb #'.'	;Convert all nonprintables to .
+dh5		jsr putchar
+		deca
+		bne dh3
+		jsr putcr
+		ldd length
+		subd #16
+		std length
+		bhi dh1
+		sty addr
+		jmp cmdline
+
+* This is the code for the E command, enter hex bytes or ascii string.
+* Syntax E or E<addr> or E<addr> <bytes> or E<addr>"string"
+enter		ldx #linebuf+1
+		jsr scanhex
+		beq ent1
+		std addr
+ent1		bsr entline
+		lbne cmdline	;No bytes, then enter interactively.		
+ent2		ldb #'E'
+		jsr putchar
+		ldd addr 
+		jsr outd
+		ldb #' '
+		jsr putchar	;Display Eaddr + space
+		lda [addr]
+		jsr outbyte
+		ldb #' '
+		jsr putchar
+                ldx #linebuf
+		ldb #buflen
+		jsr getline     ;Get the line.
+		tstb
+		beq skipbyte
+		abx
+		clr ,x
+		ldx #linebuf
+		bsr entline
+		bne ent2
+		jmp cmdline 
+skipbyte	ldd addr
+		addd #1
+		std addr
+		bra ent2
+
+* Enter a line of hex bytes or ascci string at address X, Z if empty.
+entline		jsr skipspace
+		tstb
+		beq entexit
+		cmpb #'.'
+		beq entexit
+		cmpb #'"'
+		beq entasc 
+		leax -1,x
+		ldy addr
+entl2		jsr scanbyte  ;Enter hex digits.
+		beq entdone
+		sta ,y+
+		bra entl2
+entasc		ldy addr
+entl3		lda ,x+
+		tsta
+		beq entdone
+		cmpa #'"'
+		beq entdone
+		sta ,y+
+		bra entl3
+entdone		sty addr
+		andcc #$fb
+		rts
+entexit		orcc #$04
+		rts
+
+*This is the code for the I command, display the contents of an address
+* Syntax: Iaddr
+inp		ldx #linebuf+1
+		jsr scanhex
+		tfr d,x
+		lda ,x		;Read the byte from memory.
+		jsr outbyte	;Display itin hex.
+		jsr putcr
+		jmp cmdline		 
+
+*This is the code for the H command, display result of simple hex expression
+*Syntax Hhexnum{+|-hexnum}
+calc		ldx #linebuf+1
+		jsr scanhex
+		std temp3
+hexloop		jsr skipspace
+		cmpb #'+'
+		bne hex1
+		jsr scanhex
+		addd temp3
+		std temp3
+		bra hexloop
+hex1		cmpb #'-'
+		bne hexend
+		jsr scanhex
+		comb
+		coma
+		addd #1
+		addd temp3
+		std temp3
+		bra hexloop
+hexend		ldd temp3
+		jsr outd
+		jsr putcr
+		jmp cmdline		
+
+* This is the code for the G command, jump to the program
+* Syntax G or G<addr>
+go		ldx #linebuf+1
+		jsr scanhex
+		beq launch		
+		std 10,s	;Store parameter in pc location.
+launch		jsr arm         ;Arm the breakpoints.  
+		puls ccr,b,a,dp,x,y,u,pc
+
+* This is the code for the J command, run a subroutine.
+* Syntax J<addr>
+jump		ldx #linebuf+1
+		ldd 10,s	        
+		std oldpc	;Save old pc
+		jsr scanhex
+		std 10,s	;Store parameter in PC location
+		tfr s,x
+		leas -2,s
+		tfr s,u
+		ldb #12		;Move the saved register set 2 addresses
+		jsr blockmove   ;down on the stack.
+		ldd #stakregs
+		std 12,s	;Prepare subroutine return address.
+		bra launch	;Jump to the routine.
+
+
+* This is the code for the P command, run instruction followed by breakpoint
+* Syntax P
+prog		ldy 10,s	;Get program counter value.
+		jsr disdecode	;Find out location past current insn.
+		sty stepbp
+		bra launch
+
+* This is the code for the T command, single step trace an instruction.
+* Syntax T
+trace		jsr traceone
+		jsr dispregs
+		jmp cmdline
+
+traceone	orcc #$50	;Disable the interrupts.
+		ldd ,s++	
+		std oldpc	;Remove saved pc from stack.
+		ldd #traceret
+		std firqvec+1   ;Adjust timer IRQ vector.
+		sync		;Synchronize on the next timer interrupt.
+				;1 cycle
+		ldx #4441	;3 cycles
+traceloop	leax -1,x       ;6 cycles\x4441= 39969 cycles.
+		bne traceloop	;3 cycles/
+		nop		;2 cycles.
+		nop		;2 cycles.
+		nop		;2 cycles.
+		brn traceret	;3 cycles.
+		puls x,y,u,a,b,dp,cc,pc ;17 cycles, total=39999 20ms @ 2MHz
+					;Pull all registers and execute.
+					;Is timed such that next timer IRQ
+					;occurs right after it.
+traceret	puls cc
+		pshs x,y,u,a,b,dp,cc;Store full register set instead of cc.
+		ldd #timerirq
+		std firqvec+1	;Restore timer IRQ vector.
+		jmp [oldpc]
+				
+
+* Display the contents of 8 bit register, name in B, contents in A
+disp8		jsr putchar
+		ldb #'='
+		jsr putchar
+		jsr outbyte
+		ldb #' '
+		jsr putchar
+		rts
+
+* Display the contents of 16 bit register, name in B, contents in Y
+disp16		jsr putchar
+		ldb #'='
+		jsr putchar
+		tfr y,d
+		jsr outd
+		ldb #' '
+		jsr putchar
+		rts
+
+* Display the contents of the registers and disassemble instruction at
+* PC location.
+dispregs	ldb #'X'
+		ldy 6,s		;Note that there's one return address on
+		bsr disp16	;stack so saved register offsets are 
+		ldb #'Y'	;inremented by 2.
+		ldy 8,s
+		bsr disp16
+		ldb #'U'
+		ldy 10,s
+		bsr disp16
+		ldb #'S'
+		tfr s,y
+		leay 14,y	;S of the running program is 12 higher,
+				;because regs are not stacked when running.
+		bsr disp16
+		ldb #'A'
+		lda 3,s
+		bsr disp8
+		ldb #'B'
+		lda 4,s
+		bsr disp8
+		ldb #'D'
+		lda 5,s
+		bsr disp8
+		ldb #'C'
+		lda 2,s
+		bsr disp8
+		jsr putcr
+		ldb #'P'
+		ldy 12,s
+		bsr disp16
+		jsr disdecode
+		jsr disdisp       ;Disassemble instruction at PC
+		jsr putcr
+		rts
+
+
+* This is the code for the R command, display or alter the registers.
+* Syntax R or R<letter><hex>	
+regs		ldx #linebuf+1
+		jsr skipspace
+		tstb
+		bne setreg		
+		bsr dispregs	;Display regs ifnothing follows.
+		jmp cmdline
+setreg		ldy #regtab	
+		clra
+		andb #CASEMASK	;Make letter uppercase.
+sr1		tst ,y
+		lbeq unk	;At end of register tab, unknown reg
+		cmpb ,y+
+		beq sr2		;Found the register?
+		inca
+		bra sr1		
+sr2		pshs a
+		jsr scanhex	;Convert the hex argument.
+		pshs d
+		lda 2,s		;Get register number.
+		cmpa #4
+		bcc sr3		
+		ldb 1,s		;It's 8 bit. 		
+		leas 3,s	;Remove temp stuff from stack.
+		stb a,s		;Store it in the reg on stack.
+		jmp cmdline
+sr3		cmpa #8
+		bcc sr4		
+		puls x		;It's 16 bit.
+		leas 1,s
+		lsla
+		suba #4		;Convert reg no to stack offset.
+		stx a,s
+		jmp cmdline
+sr4		puls u		;It's the stack pointer.
+		leas 1,s
+		leau -12,u      
+		tfr s,x
+		tfr u,s		;Set new stack pointer.
+		ldb #12
+		jsr blockmove	;Move register set to new stack location.
+		jmp cmdline				
+		
+regtab 		FCC "CABDXYUPS "
+
+* Disarm the breakpoints, this is replace the SWI instructions with the
+* original byte.
+disarm		ldx #bpaddr
+		lda #brkpoints+1
+disarm1		ldu ,x++        
+		ldb ,x+		;Get address in u, byte in b
+		cmpu #0
+		beq disarm2
+		stb ,u
+disarm2		deca
+		bne disarm1
+		ldu #0
+		stu -3,x	;Clear the step breakpoint.
+		rts
+
+* Arm the breakponts, this is replace the byte at the breakpoint address
+* with an SWI instruction.
+arm		ldx #bpaddr+brkpoints*3
+		lda #brkpoints+1  ;Arm them in reverse order of disarming.
+arm1		ldu ,x       ;Get address in u.
+		beq arm2
+		ldb ,u
+		stb 2,x
+		cmpu 12,s      ;Compare to program counter location
+		beq arm2
+		ldb #$3F
+		stb ,u	       ;Store SWI instruction if not equal.
+arm2		leax -3,x
+		deca
+		bne arm1		
+		rts
+
+* This is the code for the break command, set, clear display breakpoints.
+* Syntax B or B<addr>. B displays, B<addr> sets or clears breakpoint.
+break		lda #brkpoints
+		sta temp2+1     ;Store number of breakpoints to visit.
+		ldx #linebuf+1
+		jsr scanhex
+		beq dispbp	;No number then display breakpoints
+		ldx #bpaddr
+		ldu #0
+		tfr u,y
+bp1		cmpd ,x
+		beq clearit	;Found the breakpoint, so clear it,
+		cmpu ,x		;Is location zero
+		bne bp2
+		tfr x,y		;Set free address to y
+bp2		leax 3,x
+		dec temp2+1
+		bne bp1
+		cmpy #0		;Address not found in list of breakpoints
+		beq bpfull	;Was free address found.
+		std ,y		;If so, store breakpoint there.
+		ldx #brkmsg	
+bpexit		jsr outcount
+		jsr putcr
+		jmp cmdline
+clearit		clra
+		clrb
+		std ,x
+		ldx #clrmsg
+		bra bpexit
+bpfull		ldx #fullmsg
+		bra bpexit		
+
+dispbp 		ldx #bpaddr
+dbp1		ldd ,x
+		beq dbp2
+		jsr outd
+		ldb #' '
+		jsr putchar
+dbp2		leax 3,x
+		dec temp2+1
+		bne dbp1
+		jsr putcr
+		jmp cmdline
+
+* Scan hex byte into a and add it to check sum in temp2+1
+addchk		jsr scanbyte
+		lbeq srecerr
+		tfr a,b
+		addb temp2+1
+		stb temp2+1
+		rts
+
+* This tis the code for the S command, the Motorola S records entry.
+* Syntax SO<addr> or SS<addr>,<len> or S1<bytes> or S9<bytes>
+srec		ldx #linebuf+1
+		ldb ,x+
+		andb #CASEMASK
+		cmpb #'O'
+		beq setsorg
+		cmpb #'S'
+		beq sendrec
+		ldb -1,x
+		clr temp3
+		cmpb #'1'
+		beq readrec
+		cmpb #'9'
+		bne srecerr
+		inc temp3		
+readrec		clr temp2+1	;clear checksum.
+		bsr addchk
+		suba #2		;discount the address bytes from the count.
+		sta temp3+1	;Read length byte.
+		bsr addchk
+		pshs a
+		bsr addchk
+		puls b
+		exg a,b		;Read address into d.
+		ldu sorg
+		beq rr1		
+		ldu soffs
+		bne rr1
+		pshs d		;Sorg is nonzero and soffs is zero, now
+		subd sorg	;set soffs
+		std soffs
+		puls d
+rr1		subd soffs	;Subtract the address offset.
+		tfr d,y
+rr2		bsr addchk	
+		dec temp3+1
+		beq endrec
+		sta ,y+
+		bra rr2
+endrec		inc temp2+1	;Check checksum.
+		bne srecerr
+		tst temp3
+		lbeq cmdline	;Was it no S9 record?
+		cmpy #0
+		beq endrec1 
+		sty 10,s	;Store address into program counter.
+endrec1		clra
+		clrb
+		std sorg	;Reset sorg, next S loads will be normal.
+		std soffs
+		jmp cmdline	
+srecerr		jsr xabortin
+		ldx #smsg	;Error in srecord, display message.
+		jsr outcount
+		jsr putcr
+		jmp cmdline
+setsorg		jsr scanhex	;Set S record origin.
+		std sorg
+		clra 
+		clrb
+		std soffs
+		jmp cmdline
+* Send a memory region as S-records.
+sendrec		ldd #$100	;Scan address and length parameter.
+		jsr scan2parms				
+		ldd sorg
+		beq ss1
+		ldd addr
+		subd sorg
+		std soffs	;Compute offset for origin.
+ss1		ldd length	
+		beq endss	;All bytes sent?
+		cmpd #16
+		blo ss2         
+		ldb #16		;If more than 16 left, then send 16.
+ss2		stb temp
+		negb
+		ldu length
+		leau b,u
+		stu length	;Discount line length from length.
+		ldb #'S'
+		jsr putchar
+		ldb #'1'
+		jsr putchar
+		clr temp+1	;Clear check sum
+		ldb temp
+		addb #3
+		bsr checkout	;Output byte b as hex and add to check sum.
+		ldd addr
+		tfr d,y
+		subd soffs
+		exg a,b
+		bsr checkout
+		exg a,b
+		bsr checkout	;Output address (add into check sum)
+ss3		ldb ,y+
+		bsr checkout
+		dec temp
+		bne ss3
+		sty addr
+		ldb temp+1
+		comb
+		bsr checkout	;Output checksum byte.
+		jsr putcr
+		bra ss1
+endss		ldx #lastrec
+		jsr outcount
+		jsr putcr
+		jmp cmdline
+* Output byte in register B and add it into check sum at temp+1
+checkout	pshs a
+		tfr b,a
+		addb temp+1
+		stb temp+1
+		jsr outbyte
+		puls a
+		rts
+
+* This is the code for the M command, move memory region.
+* Syntax: Maddr1,addr2,length
+move		ldx #linebuf+1
+		jsr scanhex
+		lbeq unk
+		std temp3
+		jsr skipspace
+		cmpb #','
+		lbne unk
+		jsr scanhex
+		lbeq unk
+		tfr d,u
+		jsr skipspace
+		cmpb #','
+		lbne unk
+		jsr scanhex
+		lbeq unk
+		tfr d,y		;Read the argument separated by commas
+		ldx temp3	;src addr to x, dest addr to u, length to y
+			        ;Don't tolerate syntax deviations.
+mvloop		lda ,x+
+		sta ,u+
+		leay -1,y
+		bne mvloop	;Perform the block move.
+		jmp cmdline
+		
+
+* This is the code for the F command, find byte/ascii string in memory.
+* Syntax: Faddr bytes or Faddr "ascii"
+find		ldx #linebuf+1
+		jsr scanhex
+		tfr d,y		;Scan the start address.
+		jsr skipspace
+		cmpb #'"'
+		bne findhex
+		ldu #linebuf	;Quote found, so scan for quoted string.
+		clra
+fstrloop	ldb ,x+
+		beq startsrch	;End of line without final quote.
+		cmpb #'"'
+		beq startsrch   ;End quote found
+		stb ,u+
+		inca
+		bra fstrloop		 		
+findhex		ldu #linebuf	;Convert string of hex bytes.
+		leax -1,x	;String will be stored at start of line
+		clra		;buffer and may overwrite part of the
+fhexloop	pshs a		;already converted string.
+		jsr scanbyte
+		tfr a,b
+		puls a
+		beq startsrch	
+		stb ,u+
+		inca
+		bra fhexloop				
+startsrch	tsta		;Start searching, start addr in Y, 
+		                ;string starts at linebuf, length A
+		lbeq cmdline	;Quit with zero length string.
+		clr temp3
+		sta temp3+1
+srchloop	tfr y,x
+		lda temp3+1
+		cmpx #$e100
+		bcc srch1
+		leax a,x
+		cmpx #$e000	;Stop at I/O addresses.
+		lbcc cmdline
+srch1		tfr y,x
+		ldu #linebuf
+srch2		ldb ,x+
+		cmpb ,u+
+		bne srch3       ;Not equal, try next address.
+		deca 
+		bne srch2
+		tfr y,d
+		jsr outd	;String found
+		jsr putcr
+		inc temp3
+		lda temp3
+		cmpa #$10
+		lbeq cmdline	;If 10 matches found, just stop.
+srch3		leay 1,y
+		bra srchloop
+
+* Send the contents of the xmodem buffer and get it acknowledged, zero flag
+* is set if transfer aborted.
+xsendbuf	ldb #SOH		
+		jsr osputc	;Send SOH
+		ldb xpacknum
+		jsr osputc	;Send block number.
+		comb
+		jsr osputc      ;and its complement.
+		clr xsum
+		lda #128
+		ldx #buf0
+xsloop		ldb ,x
+	        addb xsum
+		stb xsum	
+		ldb ,x+
+		jsr osputc
+		deca
+		bne xsloop      ;Send the buffer contents.
+		ldb xsum
+		jsr osputc	;Send the check sum
+waitack		jsr osgetc
+		cmpb #CAN
+		beq xsabt	;^X for abort.
+		cmpb #NAK        
+		beq xsendbuf	;Send again if NAK
+		cmpb #ACK
+		bne waitack
+		inc xpacknum
+xsok		andcc #$fb	;Clear zero flag after ACK		
+xsabt		rts
+		
+* Start an XMODEM send session.
+xsendinit	ldb #1
+		stb xpacknum	;Initialize block number.
+waitnak		jsr osgetc
+		cmpb #CAN
+		beq xsabt      ;If ^X exit with zero flag.
+		cmpb #NAK
+		beq xsok        
+		bra waitnak    ;Wait until NAK received.
+
+* Send ETX and wait for ack.
+xsendeot	ldb #EOT
+		jsr osputc
+waitack2	jsr osgetc
+		cmpb #CAN
+		beq xsabt
+		cmpb #NAK
+		beq xsendeot
+		cmpb #ACK
+		beq xsok
+		bra waitack2
+
+* Read character into B with a timeout of A seconds,  Carry set if timeout.
+gettimeout	asla
+		ldb #50
+		mul
+		tfr b,a
+		adda timer+2
+gt1		jsr osgetpoll
+		tstb
+		bne gtexit
+		cmpa timer+2
+		bne gt1		
+		orcc #$1
+		rts
+gtexit		jsr osgetc
+		andcc #$fe
+		rts
+
+* Wait until line becomes quiet.
+purge		lda #3
+		jsr gettimeout
+		bcc purge
+		rts
+
+* Receive an XMODEM block and wait till it is OK, Z set if etx.				
+xrcvbuf		lda #3
+		tst lastok				
+		beq sendnak
+		ldb #ACK
+		jsr osputc	;Send an ack.
+		lda #5         
+		bra startblock
+sendnak		ldb #NAK
+		jsr osputc	;Send a NAK
+startblock	clr lastok
+		bsr gettimeout   
+		lda #3
+		bcs sendnak	;Keep sending NAKs when timed out.
+		cmpb #EOT		
+		beq xrcveot	;End of file reached, acknowledge EOT.
+		cmpb #SOH
+		bne purgeit	;Not, SOH, bad block.
+		lda #1
+		bsr gettimeout	
+		bcs purgeit				
+		cmpb xpacknum	;Is it the right block?
+		beq xr1
+		incb
+		cmpb xpacknum   ;Was it the previous block.
+		bne purgeit	
+		inc lastok
+xr1		stb xsum
+		lda #1
+		bsr gettimeout
+		bcs purgeit
+		comb
+		cmpb xsum       ;Is the complement of the block number OK
+		bne purgeit		
+		ldx #buf0
+		clr xsum
+xrloop		lda #1
+		bsr gettimeout  
+		bcs purgeit
+		stb ,x+
+		addb xsum
+		stb xsum
+		cmpx #buf0+128
+		bne xrloop       ;Get the data bytes.		
+		lda #1
+		bsr gettimeout
+		bcs purgeit
+		cmpb xsum
+		bne purgeit	;Check the check sum.
+		tst lastok
+		bne xrcvbuf	;Block was the previous block, get next one
+		inc lastok
+		inc xpacknum
+		andcc #$fb
+		rts
+purgeit		jsr purge
+		bra sendnak		
+xrcveot		lda #3		;EOT was received.
+		ldb #ACK
+ackloop		jsr osputc
+		deca
+		bne ackloop     ;Send 3 acks in a row.
+		rts
+
+
+savevecs	ldx getchar+1
+		stx oldgetc
+		ldx putchar+1
+		stx oldputc
+		ldx putcr+1
+		stx oldputcr
+		clr lastterm
+		rts
+
+rstvecs		ldx oldgetc
+		stx getchar+1
+		ldx oldputc
+		stx putchar+1
+		ldx oldputcr
+		stx putcr+1
+		clr lastterm
+		rts	
+
+* O.S. routine to open input through XMODEM transfer.
+xopin		pshs x,a,b
+		ldx #xsmsg
+		jsr outcount
+		jsr putcr	;Display message to start XMODEM send.
+		bsr savevecs
+		ldx #noop
+		stx putchar+1	;Disable character output.
+		ldx #xgetc
+		stx getchar+1	;
+		clr lastok
+		clr xcount
+		lda #1
+		sta xpacknum
+		inca
+		sta xmode	;set xmode to 2.
+		puls x,a,b,pc
+
+* O.S. routine to open output through XMODEM transfer.
+xopout		pshs x,a,b
+		bsr savevecs
+		ldx #xrmsg
+		jsr outcount	;Display message to start XMODEM receive
+		jsr putcr
+		ldx #xputc
+		stx putchar+1
+		ldx #xputcr
+		stx putcr+1
+		jsr xsendinit
+		lbeq xerror
+		clr xcount
+		lda #1
+		sta xmode
+		puls x,a,b,pc
+		
+
+* O.S. routine to abort input through XMODEM transfer.
+xabtin		lda xmode
+		cmpa #2
+		bne xclsend
+		jsr purge
+		ldb #CAN
+		lda #8
+xabtloop	jsr osputc
+		deca
+		bne xabtloop	;Send 8 CAN characters to kill transfer.
+		bsr rstvecs
+		clr xmode
+		ldx #xamsg
+		jsr outcount
+		jsr putcr	;Send diagnostic message.
+		rts		
+
+* O.S. routine to close output through XMODEM transfer.
+xclsout		lda xmode 
+		cmpa #1
+		bne xclsend
+		tst xcount
+		beq xclsdone
+		lda #128
+		suba xcount
+xclsloop	ldb filler
+		bsr xputc   
+		deca
+		bne xclsloop	;Transfer filler chars to force block out.
+xclsdone	jsr xsendeot	;Send EOT
+		lbeq xerror
+		jsr rstvecs
+		clr xmode						
+xclsend		rts	
+
+* O.S. routine to close input through XMODEM, by gobbling up the remaining
+* bytes.
+xclsin		ldb xmode
+		cmpb #2
+		bne xclsend
+		jsr putchar
+		bra xclsin
+
+* putchar routine for XMODEM 
+xputc		pshs x,a,b
+		lda xcount
+		inc xcount
+		ldx #buf0
+		stb a,x		;Store character in XMODEM buffer.
+		cmpa #127
+		bne xputc1	;is buffer full?
+		clr xcount
+		pshs y,u
+		jsr xsendbuf	
+		lbeq xerror
+		puls y,u
+xputc1		puls x,a,b,pc			
+
+* putcr routine for XMODEM
+xputcr		pshs b
+		ldb xmcr
+		bitb #2
+		beq xputcr1
+		ldb #CR
+		bsr xputc
+xputcr1		ldb xmcr
+		bitb #1
+		beq xputcr2
+		ldb #LF
+		bsr xputc		
+xputcr2		puls b
+		rts
+
+* getchar routine for XMODEM
+xgetc		pshs x,a
+		tst xcount	;No characters left?
+		bne xgetc1
+		pshs y,u
+		jsr xrcvbuf	;Receive new block.
+		puls y,u
+		beq xgetcterm	;End of input?		
+		lda #128
+		sta xcount
+xgetc1		lda xcount
+		nega
+		ldx #buf0+128
+		ldb a,x		;Get character from buffer
+		dec xcount
+		puls x,a,pc		
+xgetcterm	jsr rstvecs
+		clr xmode
+		ldb filler
+		puls x,a,pc
+		
+xerror		jsr rstvecs	;Restore I/O vectors
+		clr xmode
+		ldx #xamsg
+		jsr outcount
+		jsr putcr
+		jmp xerrvec
+	
+xerrhand	lds savesp
+		jmp cmdline
+
+* This is the code for the X command, various XMODEM related commands.
+* Syntax: XSaddr,len XLaddr,len XX XOcrlf,filler, XSSaddr,len
+xmodem		ldx #linebuf+1
+		lda ,x+
+		anda #CASEMASK	;Convert to uppercase.
+		cmpa #'X'
+		beq xeq	
+		cmpa #'L'
+		beq xload
+		cmpa #'O'
+		beq xopts
+		cmpa #'S'
+		lbne unk
+		lda ,x
+		anda #CASEMASK
+		cmpa #'S'
+		beq xss
+		ldd #$100            ;XSaddr,len command.
+		jsr scan2parms       ;Send binary through XMODEM
+		jsr xopenout
+		ldu addr
+		ldy length
+xsbinloop	ldb ,u+
+		jsr putchar		
+		leay -1,y
+		bne xsbinloop 	     ;Send all the bytes through XMODEM.
+		jmp cmdline
+xss		leax 1,x	     ;XSSaddr,len command.
+		jsr xopenout	     ;Send Srecords through XMODEM
+		jmp sendrec		
+xload		jsr scanhex	     ;XLaddr command
+		tfr d,y		     ;Load binary through XMODEM
+		jsr xopenin
+xlodloop	jsr getchar
+		tst xmode	     ;File ended? then done
+		lbeq cmdline					
+		stb ,y+
+		bra xlodloop
+xeq		jsr xopenin	     ;XX command
+		jmp cmdline	     ;Execute commands received from XMODEM
+xopts		ldd #$1a
+		jsr scan2parms
+		lda addr+1
+		sta xmcr
+		lda length+1
+		sta filler
+		jmp cmdline
+	
+* mnemonics table, ordered alphabetically.
+* 5 bytes name, 1 byte category, 2 bytes opcode, 8 bytes total.
+mnemtab         fcc "ABX  "
+                fcb 0
+                fdb $3a
+                fcc "ADCA "
+                fcb 7
+                fdb $89
+                fcc "ADCB "
+                fcb 7
+                fdb $c9
+                fcc "ADDA "
+                fcb 7
+		fdb $8b
+                fcc "ADDB "
+                fcb 7
+                fdb $cb 
+                fcc "ADDD "
+		fcb 8
+		fdb $c3
+                fcc "ANDA "
+                fcb 7
+                fdb $84
+                fcc "ANDB "
+                fcb 7
+                fdb $c4
+                fcc "ANDCC"
+ 		fcb 2
+		fdb $1c
+                fcc "ASL  "
+		fcb 10
+		fdb $08
+                fcc "ASLA "
+		fcb 0
+		fdb $48
+		fcc "ASLB "
+		fcb 0
+		fdb $58
+                fcc "ASR  "
+                fcb 10
+                fdb $07
+                fcc "ASRA "
+		fcb 0
+		fdb $47
+                fcc "ASRB "
+		fcb 0
+		fdb $57
+                fcc "BCC  "
+		fcb 4
+		fdb $24
+                fcc "BCS  "
+		fcb 4 
+		fdb $25
+                fcc "BEQ  "
+		fcb 4
+		fdb $27
+                fcc "BGE  "
+		fcb 4
+		fdb $2c
+                fcc "BGT  "
+		fcb 4
+		fdb $2e
+                fcc "BHI  "
+		fcb 4
+		fdb $22
+                fcc "BHS  "
+		fcb 4
+		fdb $24
+                fcc "BITA "
+		fcb 7
+		fdb $85
+                fcc "BITB "
+		fcb 7
+		fdb $c5
+                fcc "BLE  "
+		fcb 4
+		fdb $2f
+                fcc "BLO  "
+		fcb 4
+		fdb $25
+                fcc "BLS  "
+		fcb 4
+		fdb $23
+                fcc "BLT  "
+		fcb 4
+		fdb $2d
+                fcc "BMI  "
+		fcb 4
+		fdb $2b
+                fcc "BNE  "
+		fcb 4
+		fdb $26
+                fcc "BPL  "
+		fcb 4
+		fdb $2a
+                fcc "BRA  "
+		fcb 4
+		fdb $20 
+                fcc "BRN  "
+		fcb 4
+		fdb $21
+mnembsr         fcc "BSR  "
+		fcb 4
+		fdb $8d
+                fcc "BVC  "
+		fcb 4
+		fdb $28
+                fcc "BVS  "
+		fcb 4
+		fdb $29
+                fcc "CLR  "
+		fcb 10
+		fdb $0f
+                fcc "CLRA "
+		fcb 0
+		fdb $4f
+                fcc "CLRB "
+		fcb 0
+		fdb $5f
+                fcc "CMPA "
+		fcb 7
+		fdb $81
+                fcc "CMPB "
+		fcb 7
+		fdb $c1
+                fcc "CMPD "
+		fcb 9
+		fdb $1083
+                fcc "CMPS "
+		fcb 9
+		fdb $118c
+                fcc "CMPU "
+		fcb 9
+		fdb $1183
+                fcc "CMPX "
+		fcb 8
+		fdb $8c
+                fcc "CMPY "
+		fcb 9
+		fdb $108c
+                fcc "COM  "
+		fcb 10
+		fdb $03
+                fcc "COMA "
+		fcb 0
+		fdb $43
+                fcc "COMB "
+		fcb 0
+		fdb $53
+                fcc "CWAI "
+		fcb 2
+		fdb $3c
+                fcc "DAA  "
+		fcb 0
+		fdb $19
+                fcc "DEC  "
+		fcb 10
+		fdb $0a
+                fcc "DECA "
+		fcb 0
+		fdb $4a
+                fcc "DECB "
+		fcb 0
+		fdb $5a
+                fcc "EORA "
+		fcb 7
+		fdb $88
+                fcc "EORB "
+		fcb 7
+		fdb $c8
+                fcc "EQU  "
+		fcb 13
+		fdb 0
+                fcc "EXG  "
+		fcb 11
+		fdb $1e
+mnemfcb         fcc "FCB  "
+		fcb 13
+		fdb 1
+                fcc "FCC  "
+		fcb 13
+		fdb 2
+                fcc "FDB  "
+		fcb 13
+		fdb 3
+                fcc "INC  "
+		fcb 10
+		fdb $0c
+                fcc "INCA "
+		fcb 0
+		fdb $4c
+                fcc "INCB "
+		fcb 0
+		fdb $5c
+                fcc "JMP  "
+		fcb 10
+		fdb $0e
+mnemjsr         fcc "JSR  "
+		fcb 8
+		fdb $8d
+                fcc "LBCC "
+		fcb 5
+		fdb $1024
+                fcc "LBCS "
+		fcb 5
+		fdb $1025
+                fcc "LBEQ "
+		fcb 5
+		fdb $1027
+                fcc "LBGE "
+		fcb 5
+		fdb $102c
+                fcc "LBGT "
+		fcb 5
+		fdb $102e
+                fcc "LBHI "
+		fcb 5
+		fdb $1022
+                fcc "LBHS "
+		fcb 5
+		fdb $1024
+                fcc "LBLE "
+		fcb 5
+		fdb $102f
+                fcc "LBLO "
+		fcb 5
+		fdb $1025
+                fcc "LBLS "
+		fcb 5
+		fdb $1023
+                fcc "LBLT "
+		fcb 5
+		fdb $102d
+                fcc "LBMI "
+		fcb 5
+		fdb $102b
+                fcc "LBNE "
+		fcb 5
+		fdb $1026
+                fcc "LBPL "
+		fcb 5
+		fdb $102a
+                fcc "LBRA "
+		fcb 6
+		fdb $16
+                fcc "LBRN "
+		fcb 5
+		fdb $1021
+                fcc "LBSR "
+		fcb 6
+		fdb $17
+                fcc "LBVC "
+		fcb 5
+		fdb $1028
+                fcc "LBVS "
+		fcb 5
+		fdb $1029
+                fcc "LDA  "
+		fcb 7
+		fdb $86
+                fcc "LDB  "
+		fcb 7
+		fdb $c6
+                fcc "LDD  "
+		fcb 8
+		fdb $cc
+                fcc "LDS  "
+		fcb 9
+		fdb $10ce
+                fcc "LDU  "
+		fcb 8
+		fdb $ce
+                fcc "LDX  "
+		fcb 8
+		fdb $8e
+                fcc "LDY  "
+		fcb 9
+		fdb $108e
+                fcc "LEAS "
+		fcb 3
+		fdb $32
+                fcc "LEAU "
+		fcb 3
+		fdb $33
+                fcc "LEAX "
+		fcb 3
+		fdb $30
+                fcc "LEAY "
+		fcb 3
+		fdb $31
+                fcc "LSL  "
+		fcb 10
+		fdb $08
+                fcc "LSLA "
+		fcb 0
+		fdb $48
+                fcc "LSLB "
+		fcb 0
+		fdb $58
+                fcc "LSR  "
+		fcb 10
+		fdb $04
+                fcc "LSRA "
+		fcb 0
+		fdb $44
+                fcc "LSRB "
+		fcb 0
+		fdb $54
+                fcc "MUL  "
+		fcb 0
+		fdb $3d
+                fcc "NEG  "
+		fcb 10
+		fdb $00
+                fcc "NEGA "
+		fcb 0
+		fdb $40
+                fcc "NEGB "
+		fcb 0
+		fdb $50
+                fcc "NOP  "
+		fcb 0
+		fdb $12
+                fcc "ORA  "
+		fcb 7
+		fdb $8a
+                fcc "ORB  "
+		fcb 7
+		fdb $ca
+                fcc "ORCC "
+		fcb 2
+		fdb $1a
+                fcc "ORG  "
+		fcb 13
+		fdb 4
+                fcc "PSHS "
+		fcb 12
+		fdb $34
+                fcc "PSHU "
+		fcb 12
+		fdb $36
+                fcc "PULS "
+		fcb 12
+		fdb $35
+                fcc "PULU "
+		fcb 12
+		fdb $37
+                fcc "RMB  "
+		fcb 13
+		fdb 5
+                fcc "ROL  "
+		fcb 10
+		fdb $09
+                fcc "ROLA "
+		fcb 0
+		fdb $49
+                fcc "ROLB "
+		fcb 0
+		fdb $59
+                fcc "ROR  "
+		fcb 10
+		fdb $06
+                fcc "RORA "
+		fcb 0
+		fdb $46
+                fcc "RORB "
+		fcb 0
+		fdb $56
+                fcc "RTI  "
+		fcb 0
+		fdb $3b
+                fcc "RTS  "
+		fcb 0
+		fdb $39
+                fcc "SBCA "
+		fcb 7
+		fdb $82
+                fcc "SBCB "
+		fcb 7
+		fdb $c2
+                fcc "SET  "
+		fcb 13
+		fdb 6
+                fcc "SETDP"
+		fcb 13
+		fdb 7
+                fcc "SEX  "
+		fcb 0
+		fdb $1d
+                fcc "STA  "
+		fcb 7
+		fdb $87
+                fcc "STB  "
+		fcb 7
+		fdb $c7
+                fcc "STD  "
+		fcb 8
+		fdb $cd
+                fcc "STS  "
+		fcb 9
+		fdb $10cf
+                fcc "STU  "
+		fcb 8
+		fdb $cf
+                fcc "STX  "
+		fcb 8
+		fdb $8f
+                fcc "STY  "
+		fcb 9
+		fdb $108f
+                fcc "SUBA "
+		fcb 7
+		fdb $80
+                fcc "SUBB "
+		fcb 7
+		fdb $c0 
+                fcc "SUBD "
+		fcb 8
+		fdb $83
+                fcc "SWI  "
+		fcb 0
+		fdb $3f
+                fcb "SWI2 "
+		fcb 1
+		fdb $103f
+                fcb "SWI3 "
+		fcb 1
+		fdb $113f
+                fcc "SYNC "
+		fcb 0
+		fdb $13
+                fcc "TFR  "
+		fcb 11
+		fdb $1f
+                fcc "TST  "
+		fcb 10
+		fdb $0d
+                fcc "TSTA "
+		fcb 0
+		fdb $4d
+                fcc "TSTB "
+		fcb 0
+		fdb $5d
+
+mnemsize	equ (*-mnemtab)/8
+
+* Register table for PUSH/PULL and TFR/EXG instructions.
+* 3 bytes for name, 1 for tfr/exg, 1 for push/pull, 5 total 
+asmregtab     	fcc "X  "
+		fcb $01,$10
+		fcc "Y  "
+		fcb $02,$20
+aregu           fcc "U  "
+		fcb $03,$40
+aregs		fcc "S  "
+		fcb $04,$40
+		fcc "PC "
+		fcb $05,$80
+                fcc "A  "
+		fcb $08,$02
+		fcc "B  "
+		fcb $09,$04
+		fcc "D  "
+		fcb $00,$06
+		fcc "CC "
+		fcb $0a,$01
+		fcc "CCR"
+		fcb $0a,$01
+		fcc "DP "
+		fcb $0b,$08
+		fcc "DPR"
+		fcb $0b,$08
+reginval	fcc "?  "
+
+ixregs		fcc "XYUS"
+
+* opcode offsets to basic opcode, depends on first nibble. 
+opcoffs		fcb 0,0,0,0,0,0,-$60,-$70
+		fcb 0,-$10,-$20,-$30,0,-$10,-$20,-$30
+* mode depending on first nibble of opcode.
+modetab		fcb 3,0,0,0,0,0,5,4,1,3,5,4,1,3,5,4
+* mode depending on category code stored in mnemtab
+modetab2	fcb 0,0,1,5,6,7,7,1,2,2,0,8,9
+* modes in this context: 0 no operands, 1 8-bit immediate, 2 16 bit imm,
+* 3, 8-bit address, 4 16 bit address, 5 indexed with postbyte, 6 short
+* relative, 7 long relative, 8 pushpul, 9 tftetx
+
+* Decode instruction pointed to by Y for disassembly (and to find out
+* how long it is). On return, U points to appropriate mnemonic table entry,
+* Y points past instruction. 
+* It's rather clumsy code, but we do want to reuse the same table
+* as used with assembling.
+disdecode	clr prebyte
+		clr amode
+		lda ,y+
+		cmpa #$10
+		beq ddec1
+		cmpa #$11
+		bne ddec2
+ddec1		sta prebyte         ;Store $10 or $11 prebyte.
+		lda ,y+             ;Get new opcode.
+ddec2		sta opcode
+		lsra
+		lsra
+		lsra
+		lsra		    ;Get high nibble.
+		ldx #modetab
+		ldb a,x
+		stb amode
+		ldx #opcoffs
+		lda a,x
+		adda opcode         ;Add opcode offset to opcode. 		
+ddec4		sta opc1            ;Store the 'basis' opcode.
+		ldu #mnemtab
+		ldx #mnemsize
+ddecloop	ldb #13
+		cmpb 5,u            ;Compare category code with 13
+		beq ddec3	    ;13=pseudo op, no valid opcode
+		ldd prebyte
+		cmpd 6,u
+		beq ddecfound	    ;Opcode&prebyte agree, operation found.
+ddec3		leau 8,u            ;point to next mnemonic
+		leax -1,x
+		bne ddecloop        
+		ldu #mnemfcb        ;mnemonic not found, use FCB byte.
+		lda #3
+		sta amode	    ;Store mode 3, 8 bit address.
+		lda opcode
+		tst prebyte
+		beq ddec5
+		lda prebyte 	    ;if it was the combination prebyte
+		clr prebyte         ;and opcode that was not found,
+         	leay -1,y 	    ;FCB just the prebyte
+ddec5	        sta operand+1       ;The byte must be stored as operand.	
+		rts
+ddecfound       cmpu #mnembsr
+		bne ddec6
+		lda #$8d	    ;Is it really the BSR opcode?
+		cmpa opcode
+		beq ddec6
+		ldu #mnemjsr        ;We mistakenly found BSR instead of JSR
+ddec6           lda amode
+		anda #$FE
+		bne ddec7
+		lda 5,u             ;nibble-dependent mode was 0 or 1,
+		ldx #modetab2       ;use category dependent mode instead.
+		lda a,x
+		sta amode
+ddec7           lda amode
+		asla
+		ldx #disdectab
+		jmp [a,x]           ;jump dependent on definitive mode.
+disdectab	fdb noop,opdec1,opdec2,opdec1,opdec2,opdecidx
+		fdb opdec1,opdec2,opdecpb,opdecpb
+disdectab1	fdb noop,noop,noop,noop,noop,noop,noop,noop
+		fdb opdec1,opdec2,noop,noop,opdec1,opdec2,noop,opdec2
+opdec1		ldb ,y+
+		sex
+od1a		std operand
+noop		rts 
+opdec2		ldd ,y++
+		bra od1a
+opdecpb		ldb ,y+
+odpa		stb postbyte
+		rts
+opdecidx	ldb ,y+
+		bpl odpa	;postbytes <$80 have no extra operands.
+		stb postbyte    
+		andb #$0f
+		aslb
+		ldx #disdectab1
+		jmp [b,x]
+
+* Display disassembled instruction after the invocation of disdecode.
+* U points to mnemonic table entry.
+disdisp		tfr u,x
+		ldb #5
+		jsr putline      ;Display the mnemonic.
+		ldb #' '
+		jsr putchar
+		lda amode
+		asla
+		ldx #disdisptab
+		jmp [a,x]        ;Perform action dependent on mode.
+disdisptab	fdb noop,disim8,disim16,disadr8,disadr16
+		fdb disidx,disrel8,disrel16,distfr,dispush
+disim8		bsr puthash
+		bra disadr8
+disim16		bsr puthash
+disadr16	bsr putdol
+		ldd operand
+		jmp outd
+disadr8		bsr putdol
+		lda operand+1
+		jmp outbyte
+disrel8		bsr putdol
+		ldb operand+1
+		sex
+dr8a		sty temp
+		addd temp
+		jmp outd
+disrel16	bsr putdol
+		ldd operand
+		bra dr8a
+		
+puthash		ldb #'#'
+		jmp putchar
+putdol		ldb #'$'
+		jmp putchar						    
+putcomma	ldb #','
+		jmp putchar
+putspace	ldb #' '
+		jmp putchar
+
+dispush		ldb #12
+		ldx #asmregtab	;Walk through the register table.
+		clr temp
+regloop		lda postbyte
+		anda 4,x                
+		beq dispush1	;Is bit corresponding to reg set in postbyte
+		cmpx #aregu
+		bne dispush3
+		sta temp+1
+		lda opcode
+		anda #2
+		bne dispush1    ;no u register in pshu pulu.
+		lda temp+1		
+dispush3	cmpx #aregs
+		bne dispush4
+		sta temp+1
+		lda opcode
+		anda #2
+		beq dispush1   ;no s register in pshs puls.
+		lda temp+1
+dispush4	coma
+		anda postbyte   ;remove the bits from postbyte.
+		sta postbyte
+		pshs b          
+		tst temp
+		beq dispush2
+		bsr putcomma	;print comma after first register.
+dispush2	bsr disregname
+		inc temp
+		puls b
+dispush1	leax 5,x
+		decb
+		bne regloop		
+		rts
+
+distfr 		lda postbyte
+		lsra
+		lsra
+		lsra
+		lsra
+		bsr distfrsub
+		bsr putcomma
+		lda postbyte
+		anda #$0f
+distfrsub	ldb #12
+		ldx #asmregtab
+distfrloop	cmpa 3,x
+		beq distfrend
+		leax 5,x
+		decb
+		bne distfrloop
+distfrend	bsr disregname
+		rts
+
+disregname	lda #3
+		tfr x,u
+drnloop		ldb ,u+
+		cmpb #' '
+		beq drnend
+		jsr putchar
+		deca
+		bne drnloop
+drnend		rts
+
+disidxreg	lda postbyte
+		lsra
+		lsra
+		lsra
+		lsra
+		lsra
+		anda #3
+		ldx #ixregs
+		ldb a,x
+		jmp putchar
+
+disidx		clr temp
+		lda postbyte
+		bmi disidx1
+		anda #$1f
+		bita #$10
+		bne negoffs
+		jsr outdecbyte
+		bra discomma
+negoffs		ldb #'-'
+		jsr putchar
+		ora #$f0
+		nega
+		jsr outdecbyte
+discomma	jsr putcomma         ;Display ,Xreg and terminating ]
+disindex	bsr disidxreg
+disindir	tst temp             ;Display ] if indirect.
+		beq disidxend      
+		ldb #']'       
+		jsr putchar
+disidxend	rts
+disidx1		bita #$10			
+		beq disidx2
+		ldb #'['
+		jsr putchar
+		inc temp
+disidx2		lda postbyte
+		anda #$0f
+		asla
+		ldx #disidxtab
+		jmp [a,x]	     ;Jump to routine for indexed mode
+disadec2	lda #2
+		bra disadeca
+disadec1 	lda #1		
+disadeca	jsr putcomma
+disadloop	ldb #'-'
+		jsr putchar
+		deca
+		bne disadloop
+		bra disindex
+disainc2	lda #2
+		bra disainca
+disainc1	lda #1
+disainca	sta temp+1
+		jsr putcomma
+		jsr disidxreg		
+		lda temp+1
+disailoop	ldb #'+'
+		jsr putchar
+		deca
+		bne disailoop
+		jmp disindir
+disax		ldb #'A'
+		jsr putchar
+		jmp discomma
+disbx		ldb #'B'
+		jsr putchar
+		jmp discomma
+disdx		ldb #'D'
+		jsr putchar
+		jmp discomma
+disinval	ldb #'?'
+		jsr putchar
+		jmp disindir
+disnx		lda operand+1
+		bmi disnxneg
+disnx1		jsr putdol
+		jsr outbyte
+		jmp discomma
+disnxneg	ldb #'-'
+		jsr putchar
+		nega
+		bra disnx1
+disnnx		jsr putdol
+		ldd operand
+		jsr outd
+		jmp discomma
+disnpc		jsr putdol
+		ldb operand+1
+		sex
+disnpca		sty temp2
+		addd temp2
+		jsr outd
+		ldx #commapc
+		ldb #4
+		jsr putline
+		jmp disindir
+disnnpc		jsr putdol
+		ldd operand
+		bra disnpca
+disdirect	jsr putdol
+		ldd operand
+		jsr outd		
+		jmp disindir
+
+commapc		fcc ",PCR"
+
+disidxtab	fdb disainc1,disainc2,disadec1,disadec2
+		fdb discomma,disbx,disax,disinval
+		fdb disnx,disnnx,disinval,disdx
+		fdb disnpc,disnnpc,disinval,disdirect		
+
+* Display byte A in decimal (0<=A<20)
+outdecbyte	cmpa #10
+		blo odb1
+		suba #10
+		ldb #'1'
+		jsr putchar
+odb1		adda #'0'
+		tfr a,b
+		jmp putchar
+		
+* This is the code for the U command, unassemble instructions in memory.
+* Syntax: U or Uaddr or Uaddr,length
+unasm		bsr disasm		
+		jmp cmdline
+disasm		ldx #linebuf+1
+		ldd #20
+		jsr scan2parms  ;Scan address,length parameters.
+dis1		ldd addr
+		addd length
+		std length
+		ldy addr
+unasmloop	tfr y,d
+		jsr outd        ;Display instruction address
+		jsr putspace
+		pshs y
+		jsr disdecode
+		puls x
+		sty temp
+		clr temp2
+unadishex	lda ,x+
+		jsr outbyte
+		inc temp2
+		inc temp2
+		cmpx temp
+		bne unadishex  ;Display instruction bytes as hex.
+unadisspc	ldb #' '
+		jsr putchar
+		inc temp2
+		lda #11
+		cmpa temp2     ;Fill out with spaces to width 11.
+		bne unadisspc
+		bne unadishex
+		jsr disdisp    ;Display disassembled instruction.
+		tst disflg
+		bne skipcr		
+		jsr putcr
+skipcr		cmpy length
+		bls unasmloop
+		sty addr
+		rts
+
+* Simple 'expression evaluator' for assembler.
+expr		ldb ,x
+		cmpb #'-'
+		bne pos
+		clrb
+		leax 1,x
+pos		pshs b
+		bsr scanfact
+		beq exprend1
+		tst ,s+
+		bne exprend 	;Was the minus sign there.
+		coma
+		comb
+		addd #1
+		andcc #$fb	;Clear Z flag for valid result.
+exprend		rts		
+exprend1	puls b
+		rts
+
+scanfact	ldb ,x+
+		cmpb #'$'
+		lbeq scanhex   ;Hex number if starting with dollar.
+		cmpb #'''
+		bne scandec    ;char if starting with ' else decimal
+		ldb ,x+
+		lda ,x
+		cmpa #'''
+		bne scanchar2
+		leax 1,x       ;Increment past final quote if it's there.
+scanchar2	clra
+		andcc #$fb     ;Clear zero flag.
+		rts
+scandec		cmpb #'0'
+		blo noexpr
+		cmpb #'9'
+		bhi noexpr
+		clr temp
+		clr temp+1
+scandloop	subb #'0'
+		bcs sdexit				
+		cmpb #10
+		bcc sdexit
+		pshs b
+		ldd temp
+		aslb
+		rola
+		pshs d
+		aslb
+		rola
+		aslb
+		rola
+		addd ,s++     ;Multiply number by 10.
+		addb ,s+
+		adca #0	      ;Add digit to 10.
+		std temp	
+		ldb ,x+	      ;Get next character.
+		bra scandloop
+sdexit		ldd temp
+		leax -1,x
+		andcc #$fb	
+		rts			
+noexpr		orcc #$04
+		rts	
+
+* Assemble the instruction pointed to by X.
+* Fisrt stage: copy mnemonic to mnemonic buffer.
+asminstr 	lda #5
+		ldu #mnembuf
+mncploop	ldb ,x+		
+		beq mncpexit
+		cmpb #' '
+		beq mncpexit	;Mnemonic ends at first space or null
+		andb #CASEMASK
+		cmpb #'A'
+		blo nolet
+		cmpb #'Z'
+		bls mnemcp1	;Capitalize letters, but only letters.
+nolet		ldb -1,x
+mnemcp1		stb ,u+		;Copy to mnemonic buffer.
+		deca
+		bne mncploop
+mncpexit	tsta
+		beq mncpdone
+		ldb #' '
+mnfilloop	stb ,u+
+		deca
+		bne mnfilloop	;Fill the rest of mnem buffer with spaces.
+* Second stage: look mnemonic up using binary search.
+mncpdone	stx temp3
+		clr temp	;Low index=0
+		lda #mnemsize
+		sta temp+1      ;High index=mnemsize.
+bsrchloop	ldb temp+1
+		cmpb #$ff
+		beq invmnem	;lower limit -1?
+		cmpb temp
+		blo invmnem     ;hi index lower than low index?
+		clra
+		addb temp	;Add indexes.
+		adca #0 	
+		lsra
+		rorb		;Divide by 2 to get average
+		stb temp2
+		aslb
+		rola
+		aslb		
+		rola		
+		aslb
+		rola		;Multiply by 8 to get offset.
+		ldu #mnemtab
+		leau d,u	;Add offset to table base
+		tfr u,y
+		lda #5
+		ldx #mnembuf
+bscmploop	ldb ,x+
+		cmpb ,y+
+		bne bscmpexit	;Characters don't match?
+		deca
+		bne bscmploop
+		jmp mnemfound	;We found the mnemonic.
+bscmpexit	ldb temp2
+		bcc bscmplower
+		decb
+		stb temp+1	;mnembuf<table, adjust high limit.
+		bra bsrchloop
+bscmplower	incb
+		stb temp	;mnembuf>table, adjust low limit.
+		bra bsrchloop
+invmnem		ldx #invmmsg	
+		jmp asmerrvec
+* Stage 3: Perform routine depending on category code.
+mnemfound	clr uncert
+		ldy addr
+		lda 5,u
+		asla
+		ldx #asmtab
+		jsr [a,x]
+		sty addr
+		rts
+asmtab		fdb onebyte,twobyte,immbyte,lea
+		fdb sbranch,lbranch,lbra,acc8
+		fdb dreg1,dreg2,oneaddr,tfrexg
+		fdb pushpul,pseudovec
+
+putbyte		stb ,y+
+		rts
+putword		std ,y++
+		rts
+
+onebyte		ldb 7,u		;Cat 0, one byte opcode w/o operands RTS
+		bra putbyte
+twobyte		ldd 6,u		;Cat 1, two byte opcode w/o operands SWI2
+		bra putword
+immbyte		ldb 7,u		;Cat 2, opcode w/ immdiate operand ANDCC
+		bsr putbyte
+		jsr scanops
+		ldb amode
+		cmpb #1
+		lbne moderr
+		ldb operand+1
+		bra putbyte
+lea		ldb 7,u		;Cat 3, LEA
+		bsr putbyte
+		jsr scanops
+		lda amode
+		cmpa #1
+		lbeq moderr	;No immediate w/ lea
+		cmpa #3
+		lbhs doaddr	
+		jsr set3
+		lda #$8f
+		sta postbyte
+		lda #2
+		sta opsize	;Use 8F nn nn for direct mode.	
+		jmp doaddr
+sbranch		ldb 7,u		;Cat 4, short branch instructions
+		bsr putbyte
+		jsr startop
+		leax -1,x
+		jsr exprvec
+		lbeq exprerr
+		jmp shortrel
+lbranch		ldd 6,u		;Cat 5, long brach w/ two byte opcode
+		bsr putword
+lbra1		jsr startop
+		leax -1,x
+		jsr exprvec
+		lbeq exprerr
+		jmp longrel		
+lbra		ldb 7,u		;Cat 6, long branch w/ one byte opcode.
+		jsr putbyte
+		bra lbra1
+acc8		lda #1		;Cat 7, 8-bit two operand instructions ADDA
+		sta opsize
+		jsr scanops
+		jsr adjopc
+		jsr putbyte
+		jmp doaddr
+dreg1		lda #2		;Cat 8, 16-bit 2operand insns 1byte opc LDX
+		sta opsize
+		jsr scanops
+		jsr adjopc
+		jsr putbyte
+		jmp doaddr
+dreg2		lda #2		;Cat 9, 16-bit 2operand insns 2byte opc LDY
+		sta opsize
+		jsr scanops
+		jsr adjopc
+		lda 6,u
+		jsr putword
+		jmp doaddr
+oneaddr		jsr scanops	;Cat 10, one-operand insns NEG..CLR
+		ldb 7,u
+		lda amode
+		cmpa #1
+		lbeq moderr	;No immediate mode
+		cmpa #3
+		bhs oaind	;indexed etc
+		lda opsize
+		deca
+		beq oadir
+		addb #$10	;Add $70 for extended direct.
+oaind		addb #$60	;And $60 for indexed etc.
+oadir		jsr putbyte	;And nothing for direct8.
+		jmp doaddr
+tfrexg		jsr startop	;Cat 11, TFR and EXG
+		leax -1,x
+		ldb 7,u
+		jsr putbyte
+		jsr findreg
+		ldb ,u
+		aslb 
+		aslb
+		aslb
+		aslb
+		stb postbyte
+		ldb ,x+
+		cmpb #','
+		lbne moderr
+		jsr findreg
+		ldb ,u
+		orb postbyte
+		jmp putbyte		
+pushpul		jsr startop	;Cat 12, PSH and PUL
+		leax -1,x
+		ldb 7,u
+		jsr putbyte
+		clr postbyte
+pploop		jsr findreg
+		ldb 1,u
+		orb postbyte
+		stb postbyte
+		ldb ,x+
+		cmpb #','
+		beq pploop
+		leax -1,x
+		ldb postbyte
+		jmp putbyte		
+pseudo		ldb 7,u		;Cat 13, pseudo oeprations
+		aslb
+		ldx #pseudotab
+		jmp [b,x]
+pseudotab	fdb pseudoend,dofcb,dofcc,dofdb
+		fdb doorg,dormb,pseudoend,pseudoend
+dofcb		jsr startop
+		leax -1,x
+fcbloop		jsr exprvec
+		lbeq exprerr
+		jsr putbyte
+		ldb ,x+
+		cmpb #','
+		beq fcbloop
+pseudoend	rts
+dofcc		jsr startop
+		tfr b,a ;Save delimiter.
+fccloop		ldb ,x+	
+		beq pseudoend
+		pshs a
+		cmpb ,s+
+		beq pseudoend
+		jsr putbyte
+		bra fccloop	
+dofdb		jsr startop
+		leax -1,x
+fdbloop		jsr exprvec
+		lbeq exprerr
+		jsr putword
+		ldb ,x+
+		cmpb #','
+		beq fdbloop
+		rts
+doorg		jsr startop
+		leax -1,x
+		jsr exprvec
+		lbeq exprerr
+		tfr d,y
+		rts
+dormb		jsr startop
+		leax -1,x
+		jsr exprvec
+		lbeq exprerr
+		leay d,y
+		rts
+
+
+* Adjust opcdoe depending on mode (in $80-$FF range)
+adjopc		ldb 7,u
+		lda amode
+		cmpa #2
+		beq adjdir	;Is it direct?
+		cmpa #3
+		bhs adjind	;Indexed etc?
+		rts		;Not, then immediate, no adjust.
+adjind		addb #$20	;Add $20 to opcode for indexed etc modes.
+		rts
+adjdir		addb #$10	;Add $10 to opcode for direct8
+		lda opsize
+		deca
+		bne adjind	;If opsize=2, add another $20 for extended16	
+		rts
+
+* Start scanning of operands.
+startop		ldx temp3
+		clr amode
+		jmp skipspace
+
+* amode settings in assembler: 1=immediate, 2=direct/extended, 3=indexed
+* etc. 4=pc relative, 5=indirect, 6=pcrelative and indirect.
+
+* This subroutine scans the assembler operands.
+scanops		bsr startop
+		cmpb #'['
+		bne noindir
+		lda #5		;operand starts with [, then indirect.
+		sta amode	
+		ldb ,x+
+noindir		cmpb #'#'
+		lbeq doimm
+		cmpb #','
+		lbeq dospecial
+		andb #CASEMASK    ;Convert to uppercase.
+		lda #$86
+		cmpb #'A'
+		beq scanacidx
+		lda #$85
+		cmpb #'B'
+		beq scanacidx
+		lda #$8B
+		cmpb #'D'
+		bne scanlab
+scanacidx	ldb ,x+		;Could it be A,X B,X or D,X
+		cmpb #','
+		bne nocomma
+		sta postbyte
+		clr opsize
+		jsr set3
+		jsr scanixreg
+		bra scanend
+nocomma		leax -1,x		
+scanlab		leax -1,x	;Point to the start of the operand
+		jsr exprvec
+		lbeq exprerr    
+		std operand
+		tst uncert
+		bne opsz2	;Go for extended if operand unknown.
+		subd dpsetting  
+		tsta		;Can we use 8-bit operand?
+		bne opsz2
+		inca		
+		bra opsz1
+opsz2		lda #2
+opsz1		sta opsize	;Set opsize depending on magnitude of op.
+		lda amode
+		cmpa #5
+		bne opsz3	;Or was it indirect.
+		lda #2		;Then we have postbyte and opsize=2
+		sta opsize
+		lda #$8F
+		sta postbyte	
+		bra opsz4
+opsz3		lda #2
+		sta amode	;Assume direct or absolute addressing 
+opsz4		ldb ,x+		
+		cmpb #','
+		lbeq doindex	;If followed by, then indexed.
+scanend		lda amode
+		cmpa #5
+		blo scanend2	;Was it an indirect mode?
+		lda postbyte
+		ora #$10	;Set indirect bit.
+		sta postbyte
+		ldb ,x+		
+		cmpb #']'	;Check for the other ]
+		lbeq moderr
+scanend2	rts
+doimm		jsr exprvec	;Immediate addressing.	
+		lbeq exprerr
+		std operand
+		lda amode
+		cmpa #5
+		lbeq moderr	;Inirect mode w/ imm is illegal.
+		lda #$01
+		sta amode
+		rts
+dospecial	jsr set3
+		clr opsize
+		clra
+adecloop	ldb ,x+
+		cmpb #'-'
+		bne adecend
+		inca		;Count the - signs for autodecrement.
+		bra adecloop
+adecend		leax -1,x
+		cmpa #2				
+		lbhi moderr
+		tsta
+		bne autodec
+		clr postbyte
+		jsr scanixreg
+		clra
+aincloop	ldb ,x+
+		cmpb #'+'
+		bne aincend
+		inca
+		bra aincloop	;Count the + signs for autoincrement.			
+aincend		leax -1,x
+		cmpa #2
+		lbhi moderr
+		tsta
+		bne autoinc
+		lda #$84
+		ora postbyte
+		sta postbyte
+		bra scanend
+autoinc		adda #$7f
+		ora postbyte
+		sta postbyte		
+		bra scanend
+autodec		adda #$81
+		sta postbyte
+		jsr scanixreg
+		lbra scanend
+doindex		clr postbyte
+		jsr set3
+		ldb ,x+
+		andb #CASEMASK	;Convert to uppercase.
+		cmpb #'P'
+		lbeq dopcrel	;Check for PC relative.
+		leax -1,x
+		clr opsize
+		bsr scanixreg
+		ldd operand
+		tst uncert
+		bne longindex	;Go for long index if operand unknown.
+		cmpd #-16
+		blt shortindex
+		cmpd #15
+		bgt shortindex
+		lda amode
+		cmpa #5		
+		beq shortind1	;Indirect may not be 5-bit index	
+				;It's a five-bit index.
+		andb #$1f
+		orb postbyte
+		stb postbyte
+		lbra scanend
+shortindex	cmpd #-128
+		blt longindex
+		cmpd #127
+		bgt longindex
+shortind1	inc opsize
+		ldb #$88
+		orb postbyte
+		stb postbyte
+		lbra scanend
+longindex	lda #$2
+		sta opsize
+		ldb #$89
+		orb postbyte
+		stb postbyte
+		lbra scanend
+dopcrel		ldb ,x+
+		andb #CASEMASK	;Convert to uppercase
+		cmpb #'C'
+		blo pcrelend
+		cmpb #'R'
+		bhi pcrelend
+		bra dopcrel	;Scan past the ,PCR 
+pcrelend	leax -1,x
+		ldb #$8C
+		orb postbyte	;Set postbyte
+		stb postbyte	
+		inc amode	;Set addr mode to PCR
+		lbra scanend
+
+* Scan for one of the 4 index registers and adjust postbyte. 
+scanixreg	ldb ,x+
+		andb #CASEMASK	;Convert to uppercase.
+		pshs x
+		ldx #ixregs
+		clra
+scidxloop	cmpb ,x+
+		beq ixfound
+		adda #$20
+		bpl scidxloop
+		jmp moderr	;Index register not found where expected.
+ixfound		ora postbyte
+		sta postbyte	;Set index reg bits in postbyte.
+		puls x
+		rts		
+				
+* This routine sets amode to 3, if it was less.
+set3		lda amode
+		cmpa #3
+		bhs set3a
+		lda #3
+		sta amode
+set3a		rts
+
+* This subroutine lays down the address.
+doaddr		lda amode
+		cmpa #3
+		blo doa1
+		ldb postbyte
+		jsr putbyte
+		lda amode 
+		anda #1
+		beq doapcrel	;pc rel modes.
+doa1		lda opsize
+		tsta
+		beq set3a
+		deca
+		beq doa2
+		ldd operand
+		jmp putword
+doa2		ldb operand+1
+		jmp putbyte		
+doapcrel	sty addr
+		ldd operand
+		subd addr
+		subd #1
+		tst uncert
+		bne pcrlong
+		cmpd #-128
+		blt pcrlong
+		cmpd #-127
+		bgt pcrlong
+		lda #1
+		sta opsize
+		jmp putbyte
+pcrlong		subd #1
+		leay -1,y
+		inc postbyte
+		pshs d
+		ldb postbyte
+		jsr putbyte
+		lda #2
+		sta opsize
+		puls d
+		jmp putword
+
+* This routine checks and lays down short relative address.
+shortrel	sty addr
+		subd addr
+		subd #1
+		cmpd #-128
+		blt brerr
+		cmpd #127
+		bgt brerr
+		jsr putbyte
+		lda #4
+		sta amode
+		lda #1
+		sta opsize
+		rts
+* This routine lays down long relative address.
+longrel		sty addr
+		subd addr
+		subd #2
+		jsr putword
+		lda #4
+		sta amode
+		lda #2
+		sta opsize
+		rts
+
+brerr		ldx #brmsg
+		jmp asmerrvec 
+exprerr		ldx #exprmsg
+		jmp asmerrvec
+moderr		ldx #modemsg
+		jmp asmerrvec
+asmerr		pshs x
+		jsr xabortin
+		puls x
+		jsr outcount
+		jsr putcr
+		lds savesp
+		jmp cmdline
+
+* Find register for TFR and PSH instruction
+findreg		ldb #12
+		pshs y,b
+		ldu #asmregtab
+findregloop	tfr x,y
+		lda #3
+frcmps		ldb ,u
+		cmpb #' '
+		bne frcmps1
+		ldb ,y
+		cmpb #'A'
+		blt frfound
+frcmps1		ldb ,y+
+		andb #CASEMASK
+		cmpb ,u+
+		bne frnextreg
+		deca
+		bne frcmps
+		inca
+		bra frfound
+frnextreg	inca
+		leau a,u
+		dec ,s
+		bne findregloop
+		lbra moderr
+frfound		leau a,u
+		tfr y,x
+		puls y,b
+		rts
+
+* This is the code for the A command, assemble instructions.
+* Syntax: Aaddr
+asm             ldx #linebuf+1
+		jsr scanhex
+		std addr
+		inc disflg	
+
+
+asmloop		ldy #0
+		sty length
+		ldd addr
+		pshs d
+		jsr dis1        ;display unassembled line
+		ldd addr
+		std nxtadd
+
+		puls d
+		std addr
+
+*		ldd addr
+*		jsr outd
+
+		ldb #TAB
+		jsr putchar     ;Print TAB
+		ldx #linebuf
+		ldb #128
+		jsr getline     ;Get new line
+		tstb    
+		beq next
+
+***		beq asmend      ;Exit on empty line.
+		abx 
+		clr ,x          ;Make line zero terminated.
+		ldx #linebuf
+		lda ,x
+		cmpa #'.'
+		beq asmend
+		jsr asminstr
+		bra asmloop
+
+next		ldd nxtadd
+		std addr
+		bra asmloop
+
+asmend		clr disflg
+		jmp cmdline			
+
+
+* Jump table for monitor routines that are usable by other programs.
+		org $ffc0
+		jmp outbyte
+		jmp outd
+		jmp scanbyte
+		jmp scanhex
+		jmp scanfact
+		jmp asminstr
+		
+								
+* Interrupt vector addresses at top of ROM. Most are vectored through jumps
+* in RAM.
+		org $fff2
+		fdb swi3vec
+		fdb swi2vec
+		fdb firqvec
+		fdb irqvec
+		fdb swivec
+		fdb nmivec
+		fdb reset
+
+		end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/monitor.asm	Mon Jul 02 02:12:31 2018 +0900
@@ -0,0 +1,2905 @@
+	;Buggy machine language monitor and rudimentary O.S. version 1.0
+
+* Memory map of SBC
+* $0-$40 Zero page variables reserved by monitor and O.S.
+* $40-$FF Zero page portion for user programs.
+* $100-$17F Xmodem buffer 0, terminal input buffer,
+* $180-$1FF Xmodem buffer 1, terminal output buffer.
+* $200-$27F Terminal input line.
+* $280-$2FF Variables reserved by monitor and O.S.
+* $300-$400 System stack.
+* $400-$7FFF RAM for user programs and data.
+* $8000-$DFFF PROM for user programs.
+* $E000-$E1FF I/O addresses.
+* $E200-$E3FF Reserved.
+* $E400-$FFFF Monitor ROM
+
+* Reserved Zero page addresses
+		org $0000
+		setdp 0
+* First the I/O routine vectors.
+getchar		rmb 3		;Jump to getchar routine.
+putchar		rmb 3		;Jump to putchar routine.
+getline		rmb 3		;Jump to getline routine.
+putline		rmb 3		;Jump to putline routine.
+putcr		rmb 3		;Jump to putcr routine.
+getpoll         rmb 3           ;Jump to getpoll routine.
+xopenin		rmb 3		;Jump to xopenin routine.
+xopenout	rmb 3		;Jump to xopenout routine.
+xabortin	rmb 3           ;Jump to xabortin routine.
+xclosein	rmb 3		;Jump to xclosein routine.
+xcloseout	rmb 3		;Jump to xcloseout routine.
+delay		rmb 3		;Jump to delay routine.
+
+*Next the system variables in the zero page.
+temp		rmb 2            ;hex scanning/disasm
+temp2		rmb 2            ;Hex scanning/disasm
+temp3 		rmb 2            ;Used in Srecords, H command
+timer		rmb 3            ;3 byte timer, incremented every 20ms
+xpacknum	rmb 1            ;Packet number for XMODEM block,
+xsum		rmb 1		 ;XMODEM checksum
+lastok		rmb 1            ;flag to indicate last block was OK
+xcount		rmb 1		 ;Count of characters in buffer.
+xmode 		rmb 1		 ;XMODEM mode, 0 none, 1 out, 2 in.
+
+* I/O buffers.
+buflen		equ 128		;Length of input line buffer.
+		org $100
+buf0		rmb 128		;Xmodem buffer 0, serial input buffer.
+buf1		rmb 128		;Xmodem buffer 1, serial output buffer.
+linebuf		rmb buflen	;Input line buffer.
+
+
+* Interrupt vectors (start at $280)
+* All interrupts except RESET are vectored through jumps.
+* FIRQ is timer interrupt, IRQ is ACIA interrupt.
+swi3vec		rmb 3
+swi2vec		rmb 3
+firqvec		rmb 3
+irqvec		rmb 3
+swivec 		rmb 3
+nmivec		rmb 3
+xerrvec		rmb 3           ;Error handler for XMODEM error.
+exprvec		rmb 3		;Expression evaluator in assembler.
+asmerrvec	rmb 3		;Error handler for assembler errors.
+
+* Next the non zero page system variables.
+oldpc		rmb 2		;Saved pc value for J command.
+addr		rmb 2		;Address parameter.
+length		rmb 2		;Length parameter.
+
+brkpoints 	equ 4		;Number of settable breakpoints. 
+bpaddr		rmb brkpoints*3 ;Address and byte for each break point.
+stepbp		rmb 3		;Address of P command break point.
+
+sorg		rmb 2		;Origin address of S record entry.
+soffs		rmb 2		;Offset load adrr-addr in record
+
+oldgetc		rmb 2		;Old getchar address.
+oldputc		rmb 2		;Old putchar address.
+oldputcr	rmb 2		;Old putcr address.
+lastterm	rmb 1		;Last terminating character.
+filler		rmb 1		;Filler at end of XMODEM file.
+xmcr		rmb 1		;end-of-line characters for XMODEM send.
+savesp		rmb 2		;Save sp to restore it on error.
+
+* Following variables are used by assembler/disassembler.
+prebyte		rmb 1
+opc1		rmb 1
+opcode 		rmb 1
+postbyte	rmb 1
+amode		rmb 1
+operand		rmb 2		
+mnembuf		rmb 5		;Buffer to store capitalized mnemonic.
+opsize		rmb 1		;SIze (in bytes) of extra oeprand (0--2)
+uncert		rmb 1		;Flag to indicate that op is unknown.
+dpsetting	rmb 2
+
+endvars		equ *
+
+ramstart	equ $400	;first free RAM address.
+
+ramtop  	equ $8000       ;top of RAM.
+
+* I/O port addresses
+aciactl		equ $e000	;Control port of ACIA
+aciasta		equ $e000	;Status port of ACIA
+aciadat		equ $e001	;Data port of ACIA
+
+* ASCII control characters.
+SOH		equ 1
+EOT		equ 4
+ACK		equ 6
+BS		equ 8
+TAB		equ 9
+LF		equ 10
+CR		equ 13
+NAK		equ 21
+CAN		equ 24
+DEL		equ 127
+
+CASEMASK	equ $DF		;Mask to make lowercase into uppercase.
+
+* Monitor ROM starts here.
+		org $E400
+
+reset		orcc #$FF	;Disable interrupts.
+		clra		
+		tfr a,dp	;Set direct page register to 0.
+		lds #ramstart
+		ldx #intvectbl
+		ldu #swi3vec
+		ldb #osvectbl-intvectbl
+		bsr blockmove   ;Initialize interrupt vectors from ROM.
+		ldx #osvectbl
+		ldu #0
+		ldb #endvecs-osvectbl
+		bsr blockmove	;Initialize I/O vectors from ROM.
+		bsr initacia	;Initialize serial port.
+		andcc #$0	;Enable interrupts
+* Put the 'saved' registers of the program being monitored on top of the
+* stack. There are 12 bytes on the stack for cc,b,a,dp,x,y,u and pc
+* pc is initialized to $400, the rest to zero.
+		ldx #0          
+		tfr x,y
+		ldu #ramstart
+		pshs x,u
+		pshs x,y
+		pshs x,y  
+		ldx #oldpc
+		ldb #endvars-oldpc
+clvar		clr ,x+
+		decb
+		bne clvar	;Clear the variable area.	
+		ldd #$1A03	
+		std filler	;Set XMODEM filler and end-of-line.
+		ldx #welcome
+		jsr outcount
+		jsr putcr	;Print a welcome message.      
+		jmp cmdline
+* Block move routine, from X to U length B. Modifies them all and A. 
+blockmove	lda ,x+
+		sta ,u+
+		decb
+		bne blockmove
+		rts
+
+* Initialize serial communications port, buffers, interrupts.
+initacia	ldb #$03
+		stb aciactl
+		ldb #%00110101
+		rts
+
+* O.S. routine to read a character into B register.
+osgetc		ldb aciasta
+		bitb #$01
+		beq osgetc
+		ldb aciadat
+		rts
+
+;O.S. rotuine to check if there is a character ready to be read.
+osgetpoll       ldb aciasta
+		bitb #$01
+		bne poltrue
+		clrb
+		rts
+poltrue		ldb #$ff
+		rts
+
+* O.S. routine to write the character in the B register.
+osputc		pshs a
+putcloop	lda aciasta
+		bita #$02
+		beq putcloop
+		stb aciadat
+		puls a
+		rts
+
+* O.S. routine to read a line into memory at address X, at most B chars
+* long, return actual length in B. Permit backspace editing.
+osgetl		pshs a,x
+		stb temp
+		clra
+osgetl1		jsr getchar
+		andb #$7F      		
+		cmpb #BS
+		beq backsp
+		cmpb #DEL
+		bne osgetl2       
+backsp		tsta                  ;Recognize BS and DEL as backspace key.
+		beq osgetl1	      ;ignore if line already zero length.
+		ldb #BS
+		jsr putchar
+		ldb #' '
+		jsr putchar
+		ldb #BS		      ;Send BS,space,BS. This erases last
+		jsr putchar           ;character on most terminals.
+		leax -1,x	      ;Decrement address.
+		deca
+		bra osgetl1
+osgetl2		cmpb #CR
+		beq newline
+		cmpb #LF
+		bne osgetl3           ;CR or LF character ends line.
+		ldb lastterm
+		cmpb #CR
+		beq osgetl1	      ;Ignore LF if it comes after CR
+		ldb #LF		      
+newline         stb lastterm
+		jsr putcr             
+		tfr a,b               ;Move length to B
+		puls a,x              ;restore registers.
+		rts                   ;<--- Here is the exit point.
+osgetl3         cmpb #TAB
+		beq dotab		
+		cmpb #' '
+		blo osgetl1	      ;Ignore control characters.
+		cmpa temp
+		beq osgetl1	      ;Ignore char if line full.
+		jsr putchar           ;Echo the character.
+		stb ,x+               ;Store it in memory.
+		inca
+		bra osgetl1
+dotab		ldb #' '
+		cmpa temp
+		beq osgetl1
+		jsr putchar
+		stb ,x+
+		inca
+		bita #7		       ;Insert spaces until length mod 8=0
+		bne dotab
+		bra osgetl1 
+
+* O.S. routine to write a line starting at address X, B chars long.
+osputl		pshs a,b,x
+		tfr b,a
+		tsta
+		beq osputl1
+osputl2		ldb ,x+
+		jsr putchar
+		deca
+		bne osputl2
+osputl1		puls a,b,x
+		rts
+
+* O.S. routine to terminate a line.
+oscr		pshs b
+		ldb #CR
+		jsr putchar
+		ldb #LF
+		jsr putchar     ;Send the CR and LF characters.
+		puls b
+		rts
+
+* Output a counted string at addr X
+outcount	pshs x,b
+		ldb ,x+
+		jsr putline
+		puls x,b
+		rts
+
+timerirq	inc timer+2
+		bne endirq
+		inc timer+1
+		bne endirq
+		inc timer
+		rti
+aciairq		nop
+endirq		rti
+
+* Wait D times 20ms.
+osdly		addd timer+1
+dlyloop		cmpd timer+1
+		bne dlyloop
+		rts		
+
+* This table will be copied to the interrupt vector area in RAM.
+intvectbl	jmp endirq
+		jmp endirq
+		jmp timerirq
+		jmp aciairq
+		jmp unlaunch
+		jmp endirq
+		jmp xerrhand
+		jmp expr
+		jmp asmerrvec
+* And this one to the I/O vector table.
+osvectbl	jmp osgetc
+		jmp osputc
+		jmp osgetl
+		jmp osputl
+		jmp oscr		
+		jmp osgetpoll
+		jmp xopin
+		jmp xopout
+		jmp xabtin
+		jmp xclsin
+		jmp xclsout
+		jmp osdly
+endvecs 	equ *		
+		
+* The J command returns here.
+stakregs        pshs x		     ;Stack something where the pc comes
+		pshs cc,b,a,dp,x,y,u ;Stack the normal registers.
+		ldx oldpc	
+		stx 10,s	     ;Stack the old pc value.
+		bra unlaunch1
+* The G and P commands return here through a breakpoint.
+* Registers are already stacked.
+unlaunch	ldd 10,s
+		subd #1
+		std 10,s	     ;Decrement pc before breakpoint
+unlaunch1	andcc #$0	     ;reenable the interrupts.
+		jsr disarm	     ;Disarm the breakpoints.
+		jsr dispregs 	     
+cmdline		jsr xcloseout
+		sts savesp
+		ldx #linebuf
+		ldb #buflen
+                jsr getline
+		tstb
+		beq cmdline          ;Ignore line if it is empty
+		abx
+		clr ,x		     ;Make location after line zero.
+		ldx #linebuf
+		ldb ,x+
+		andb #CASEMASK	     ;Make 1st char uppercase.
+		subb #'A'            
+		bcs unk
+		cmpb #26
+		bcc unk		     ;Unknown cmd if it is not a letter.
+		ldx #cmdtab
+		aslb		      ;Index into command table.
+		jmp [b,x]
+
+cmdtab 		fdb asm,break,unk,dump
+		fdb enter,find,go,hex
+		fdb inp,jump,unk,unk
+		fdb move,unk,unk,prog
+		fdb unk,regs,srec,trace
+		fdb unasm,unk,unk,xmodem
+		fdb unk,unk
+
+* Unknown command handling routine.
+unk		jsr xabortin
+		ldx #unknown
+		jsr outcount
+		jsr putcr
+		jmp cmdline
+
+
+
+* Here are some useful messages.
+welcome		fcb unknown-welcome-1
+		fcc "Welcome to BUGGY version 1.0"
+unknown		fcb brkmsg-unknown-1
+		fcc "Unknown command"
+brkmsg		fcb clrmsg-brkmsg-1
+		fcc "Breakpoint set"
+clrmsg		fcb fullmsg-clrmsg-1
+		fcc "Breakpoint cleared"
+fullmsg		fcb smsg-fullmsg-1
+		fcc "Breakpoints full"
+smsg		fcb lastrec-smsg-1
+		fcc "Error in S record"
+lastrec		fcb xsmsg-lastrec-1
+		fcc "S9030000FC"
+xsmsg		fcb xrmsg-xsmsg-1
+		fcc "Start XMODEM Send"
+xrmsg		fcb xamsg-xrmsg-1
+		fcc "Start XMODEM Receive"
+xamsg		fcb invmmsg-xamsg-1
+		fcc "XMODEM transfer aborted"
+invmmsg		fcb exprmsg-invmmsg-1
+		fcc "Invalid mnemonic"
+exprmsg		fcb modemsg-exprmsg-1
+		fcc "Expression error"
+modemsg		fcb brmsg-modemsg-1
+		fcc "Addressing mode error"		
+brmsg		fcb endmsg-brmsg-1
+		fcc "Branch too long"
+endmsg		equ *
+
+* Output hex digit contained in A
+hexdigit 	adda #$90
+		daa
+		adca #$40
+		daa		;It's the standard conversion trick ascii
+		tfr a,b		;to hex without branching.
+		jsr putchar
+		rts
+
+* Output contents of A as two hex digits 
+outbyte		pshs a		
+		lsra
+		lsra
+		lsra
+		lsra
+		bsr hexdigit
+		puls a
+		anda #$0f
+		bra hexdigit
+
+* Output contents of d as four hex digits 
+outd		pshs b   
+		bsr outbyte
+		puls a
+		bsr outbyte
+		rts
+
+* Skip X past spaces, B is first non-space character.
+skipspace	ldb ,x+
+		cmpb #' '
+		beq skipspace
+		rts
+
+* Convert ascii hex digit in B register to binary Z flag set if no hex digit. 
+convb		subb #'0'
+		blo convexit
+		cmpb #9
+		bls cb2
+		andb #CASEMASK ;Make uppercase.
+		subb #7		;If higher than digit 9 it must be a letter.
+		cmpb #9
+		bls convexit
+		cmpb #15
+		bhi convexit
+cb2		andcc #$FB      ;clear zero	
+		rts
+convexit	orcc #$04
+		rts
+
+scanexit  	ldd temp
+		leax -1,x
+		tst temp2
+		rts		;<-- exit point of scanhex 
+
+* Scan for hexadecimal number at address X return in D, Z flag is set it no
+* number found.
+scanhex		clr temp    
+		clr temp+1
+		clr temp2
+		bsr skipspace
+scloop		jsr convb
+		beq scanexit
+		pshs b
+		ldd temp
+		aslb
+		rola
+		aslb
+		rola
+		aslb
+		rola
+		aslb
+		rola
+		addb ,s+
+		std temp
+		inc temp2
+		ldb ,x+
+		bra scloop
+
+scan2parms	std length
+		bsr scanhex
+		beq sp2
+		std addr
+		bsr skipspace
+		cmpb #','
+		bne sp2
+		bsr scanhex
+		beq sp2
+		std length				
+sp2 		rts
+
+* Scan two hexdigits at in and convert to byte into A, Z flag if error.
+scanbyte	bsr skipspace
+		bsr convb
+		beq sb1
+		tfr b,a
+		ldb ,x+
+		bsr convb
+		beq sb1
+		asla
+		asla
+		asla
+		asla
+		stb temp
+		adda temp
+		andcc #$fb	;Clear zero flag
+sb1		rts
+
+
+* This is the code for the D command, hex/ascii dump of memory
+* Syntax: D or D<addr> or D<addr>,<length>	
+dump	    	ldx #linebuf+1
+		ldd #$40	
+	        jsr scan2parms ;Scan address and length, default length=64
+		ldy addr
+dh1		lda #16
+		sta temp+1	
+		tfr y,d
+		jsr outd
+		ldb #' '
+		jsr putchar
+dh2		lda ,y+		;display row of 16 mem locations as hex
+		jsr outbyte
+		ldb #' '
+		lda temp+1
+		cmpa #9
+		bne dh6
+		ldb #'-'	;Do a - after the eighth byte.
+dh6		jsr putchar
+		dec temp+1
+		bne dh2
+		leay -16,y	;And now for the ascii dump.
+		lda #16
+dh3		ldb ,y+
+		cmpb #' '
+		bhs dh4
+		ldb #'.'            
+dh4		cmpb #DEL
+		blo dh5
+		ldb #'.'	;Convert all nonprintables to .
+dh5		jsr putchar
+		deca
+		bne dh3
+		jsr putcr
+		ldd length
+		subd #16
+		std length
+		bhi dh1
+		sty addr
+		jmp cmdline
+
+* This is the code for the E command, enter hex bytes or ascii string.
+* Syntax E or E<addr> or E<addr> <bytes> or E<addr>"string"
+enter		ldx #linebuf+1
+		jsr scanhex
+		beq ent1
+		std addr
+ent1		bsr entline
+		lbne cmdline	;No bytes, then enter interactively.		
+ent2		ldb #'E'
+		jsr putchar
+		ldd addr 
+		jsr outd
+		ldb #' '
+		jsr putchar	;Display Eaddr + space
+                ldx #linebuf
+		ldb #buflen
+		jsr getline     ;Get the line.
+		abx
+		clr ,x
+		ldx #linebuf
+		bsr entline
+		bne ent2
+		jmp cmdline 
+
+* Enter a line of hex bytes or ascci string at address X, Z if empty.
+entline		jsr skipspace
+		tstb
+		beq entexit
+		cmpb #'"'
+		beq entasc 
+		leax -1,x
+		ldy addr
+entl2		jsr scanbyte  ;Enter hex digits.
+		beq entdone
+		sta ,y+
+		bra entl2
+entasc		ldy addr
+entl3		lda ,x+
+		tsta
+		beq entdone
+		cmpa #'"'
+		beq entdone
+		sta ,y+
+		bra entl3
+entdone		sty addr
+		andcc #$fb
+		rts
+entexit		orcc #$04
+		rts
+
+*This is the code for the I command, display the contents of an address
+* Syntax: Iaddr
+inp		ldx #linebuf+1
+		jsr scanhex
+		tfr d,x
+		lda ,x		;Read the byte from memory.
+		jsr outbyte	;Display itin hex.
+		jsr putcr
+		jmp cmdline		 
+
+*This is the code for the H command, display result of simple hex expression
+*Syntax Hhexnum{+|-hexnum}
+hex		ldx #linebuf+1
+		jsr scanhex
+		std temp3
+hexloop		jsr skipspace
+		cmpb #'+'
+		bne hex1
+		jsr scanhex
+		addd temp3
+		std temp3
+		bra hexloop
+hex1		cmpb #'-'
+		bne hexend
+		jsr scanhex
+		comb
+		coma
+		addd #1
+		addd temp3
+		std temp3
+		bra hexloop
+hexend		ldd temp3
+		jsr outd
+		jsr putcr
+		jmp cmdline		
+
+* This is the code for the G command, jump to the program
+* Syntax G or G<addr>
+go		ldx #linebuf+1
+		jsr scanhex
+		beq launch		
+		std 10,s	;Store parameter in pc location.
+launch		jsr arm         ;Arm the breakpoints.  
+		puls cc,b,a,dp,x,y,u,pc
+
+* This is the code for the J command, run a subroutine.
+* Syntax J<addr>
+jump		ldx #linebuf+1
+		ldd 10,s	        
+		std oldpc	;Save old pc
+		jsr scanhex
+		std 10,s	;Store parameter in PC location
+		tfr s,x
+		leas -2,s
+		tfr s,u
+		ldb #12		;Move the saved register set 2 addresses
+		jsr blockmove   ;down on the stack.
+		ldd #stakregs
+		std 12,s	;Prepare subroutine return address.
+		bra launch	;Jump to the routine.
+
+
+* This is the code for the P command, run instruction followed by breakpoint
+* Syntax P
+prog		ldy 10,s	;Get program counter value.
+		jsr disdecode	;Find out location past current insn.
+		sty stepbp
+		bra launch
+
+* This is the code for the T command, single step trace an instruction.
+* Syntax T
+trace		jsr traceone
+		jsr dispregs
+		jmp cmdline
+
+traceone	orcc #$50	;Disable the interrupts.
+		ldd ,s++	
+		std oldpc	;Remove saved pc from stack.
+		ldd #traceret
+		std firqvec+1   ;Adjust timer IRQ vector.
+		sync		;Synchronize on the next timer interrupt.
+				;1 cycle
+		ldx #4441	;3 cycles
+traceloop	leax -1,x       ;6 cycles\x4441= 39969 cycles.
+		bne traceloop	;3 cycles/
+		nop		;2 cycles.
+		nop		;2 cycles.
+		nop		;2 cycles.
+		brn traceret	;3 cycles.
+		puls x,y,u,a,b,dp,cc,pc ;17 cycles, total=39999 20ms @ 2MHz
+					;Pull all registers and execute.
+					;Is timed such that next timer IRQ
+					;occurs right after it.
+traceret	puls cc
+		pshs x,y,u,a,b,dp,cc;Store full register set instead of cc.
+		ldd #timerirq
+		std firqvec+1	;Restore timer IRQ vector.
+		jmp [oldpc]
+				
+
+* Display the contents of 8 bit register, name in B, contents in A
+disp8		jsr putchar
+		ldb #'='
+		jsr putchar
+		jsr outbyte
+		ldb #' '
+		jsr putchar
+		rts
+
+* Display the contents of 16 bit register, name in B, contents in Y
+disp16		jsr putchar
+		ldb #'='
+		jsr putchar
+		tfr y,d
+		jsr outd
+		ldb #' '
+		jsr putchar
+		rts
+
+* Display the contents of the registers and disassemble instruction at
+* PC location.
+dispregs	ldb #'X'
+		ldy 6,s		;Note that there's one return address on
+		bsr disp16	;stack so saved register offsets are 
+		ldb #'Y'	;inremented by 2.
+		ldy 8,s
+		bsr disp16
+		ldb #'U'
+		ldy 10,s
+		bsr disp16
+		ldb #'S'
+		tfr s,y
+		leay 14,y	;S of the running program is 12 higher,
+				;because regs are not stacked when running.
+		bsr disp16
+		ldb #'A'
+		lda 3,s
+		bsr disp8
+		ldb #'B'
+		lda 4,s
+		bsr disp8
+		ldb #'D'
+		lda 5,s
+		bsr disp8
+		ldb #'C'
+		lda 2,s
+		bsr disp8
+		jsr putcr
+		ldb #'P'
+		ldy 12,s
+		bsr disp16
+		jsr disdecode
+		jsr disdisp       ;Disassemble instruction at PC
+		jsr putcr
+		rts
+
+
+* This is the code for the R command, display or alter the registers.
+* Syntax R or R<letter><hex>	
+regs		ldx #linebuf+1
+		jsr skipspace
+		tstb
+		bne setreg		
+		bsr dispregs	;Display regs ifnothing follows.
+		jmp cmdline
+setreg		ldy #regtab	
+		clra
+		andb #CASEMASK	;Make letter uppercase.
+sr1		tst ,y
+		lbeq unk	;At end of register tab, unknown reg
+		cmpb ,y+
+		beq sr2		;Found the register?
+		inca
+		bra sr1		
+sr2		pshs a
+		jsr scanhex	;Convert the hex argument.
+		pshs d
+		lda 2,s		;Get register number.
+		cmpa #4
+		bcc sr3		
+		ldb 1,s		;It's 8 bit. 		
+		leas 3,s	;Remove temp stuff from stack.
+		stb a,s		;Store it in the reg on stack.
+		jmp cmdline
+sr3		cmpa #8
+		bcc sr4		
+		puls x		;It's 16 bit.
+		leas 1,s
+		lsla
+		suba #4		;Convert reg no to stack offset.
+		stx a,s
+		jmp cmdline
+sr4		puls u		;It's the stack pointer.
+		leas 1,s
+		leau -12,u      
+		tfr s,x
+		tfr u,s		;Set new stack pointer.
+		ldb #12
+		jsr blockmove	;Move register set to new stack location.
+		jmp cmdline				
+		
+regtab 		FCC "CABDXYUPS "
+
+* Disarm the breakpoints, this is replace the SWI instructions with the
+* original byte.
+disarm		ldx #bpaddr
+		lda #brkpoints+1
+disarm1		ldu ,x++        
+		ldb ,x+		;Get address in u, byte in b
+		cmpu #0
+		beq disarm2
+		stb ,u
+disarm2		deca
+		bne disarm1
+		ldu #0
+		stu -3,x	;Clear the step breakpoint.
+		rts
+
+* Arm the breakponts, this is replace the byte at the breakpoint address
+* with an SWI instruction.
+arm		ldx #bpaddr+brkpoints*3
+		lda #brkpoints+1  ;Arm them in reverse order of disarming.
+arm1		ldu ,x       ;Get address in u.
+		beq arm2
+		ldb ,u
+		stb 2,x
+		cmpu 12,s      ;Compare to program counter location
+		beq arm2
+		ldb #$3F
+		stb ,u	       ;Store SWI instruction if not equal.
+arm2		leax -3,x
+		deca
+		bne arm1		
+		rts
+
+* This is the code for the break command, set, clear display breakpoints.
+* Syntax B or B<addr>. B displays, B<addr> sets or clears breakpoint.
+break		lda #brkpoints
+		sta temp2+1     ;Store number of breakpoints to visit.
+		ldx #linebuf+1
+		jsr scanhex
+		beq dispbp	;No number then display breakpoints
+		ldx #bpaddr
+		ldu #0
+		tfr u,y
+bp1		cmpd ,x
+		beq clearit	;Found the breakpoint, so clear it,
+		cmpu ,x		;Is location zero
+		bne bp2
+		tfr x,y		;Set free address to y
+bp2		leax 3,x
+		dec temp2+1
+		bne bp1
+		cmpy #0		;Address not found in list of breakpoints
+		beq bpfull	;Was free address found.
+		std ,y		;If so, store breakpoint there.
+		ldx #brkmsg	
+bpexit		jsr outcount
+		jsr putcr
+		jmp cmdline
+clearit		clra
+		clrb
+		std ,x
+		ldx #clrmsg
+		bra bpexit
+bpfull		ldx #fullmsg
+		bra bpexit		
+
+dispbp 		ldx #bpaddr
+dbp1		ldd ,x
+		beq dbp2
+		jsr outd
+		ldb #' '
+		jsr putchar
+dbp2		leax 3,x
+		dec temp2+1
+		bne dbp1
+		jsr putcr
+		jmp cmdline
+
+* Scan hex byte into a and add it to check sum in temp2+1
+addchk		jsr scanbyte
+		lbeq srecerr
+		tfr a,b
+		addb temp2+1
+		stb temp2+1
+		rts
+
+* This tis the code for the S command, the Motorola S records entry.
+* Syntax SO<addr> or SS<addr>,<len> or S1<bytes> or S9<bytes>
+srec		ldx #linebuf+1
+		ldb ,x+
+		andb #CASEMASK
+		cmpb #'O'
+		beq setsorg
+		cmpb #'S'
+		beq sendrec
+		ldb -1,x
+		clr temp3
+		cmpb #'1'
+		beq readrec
+		cmpb #'9'
+		bne srecerr
+		inc temp3		
+readrec		clr temp2+1	;clear checksum.
+		bsr addchk
+		suba #2		;discount the address bytes from the count.
+		sta temp3+1	;Read length byte.
+		bsr addchk
+		pshs a
+		bsr addchk
+		puls b
+		exg a,b		;Read address into d.
+		ldu sorg
+		beq rr1		
+		ldu soffs
+		bne rr1
+		pshs d		;Sorg is nonzero and soffs is zero, now
+		subd sorg	;set soffs
+		std soffs
+		puls d
+rr1		subd soffs	;Subtract the address offset.
+		tfr d,y
+rr2		bsr addchk	
+		dec temp3+1
+		beq endrec
+		sta ,y+
+		bra rr2
+endrec		inc temp2+1	;Check checksum.
+		bne srecerr
+		tst temp3
+		lbeq cmdline	;Was it no S9 record?
+		cmpy #0
+		beq endrec1 
+		sty 10,s	;Store address into program counter.
+endrec1		clra
+		clrb
+		std sorg	;Reset sorg, next S loads will be normal.
+		std soffs
+		jmp cmdline	
+srecerr		jsr xabortin
+		ldx #smsg	;Error in srecord, display message.
+		jsr outcount
+		jsr putcr
+		jmp cmdline
+setsorg		jsr scanhex	;Set S record origin.
+		std sorg
+		clra 
+		clrb
+		std soffs
+		jmp cmdline
+* Send a memory region as S-records.
+sendrec		ldd #$100	;Scan address and length parameter.
+		jsr scan2parms				
+		ldd sorg
+		beq ss1
+		ldd addr
+		subd sorg
+		std soffs	;Compute offset for origin.
+ss1		ldd length	
+		beq endss	;All bytes sent?
+		cmpd #16
+		blo ss2         
+		ldb #16		;If more than 16 left, then send 16.
+ss2		stb temp
+		negb
+		ldu length
+		leau b,u
+		stu length	;Discount line length from length.
+		ldb #'S'
+		jsr putchar
+		ldb #'1'
+		jsr putchar
+		clr temp+1	;Clear check sum
+		ldb temp
+		addb #3
+		bsr checkout	;Output byte b as hex and add to check sum.
+		ldd addr
+		tfr d,y
+		subd soffs
+		exg a,b
+		bsr checkout
+		exg a,b
+		bsr checkout	;Output address (add into check sum)
+ss3		ldb ,y+
+		bsr checkout
+		dec temp
+		bne ss3
+		sty addr
+		ldb temp+1
+		comb
+		bsr checkout	;Output checksum byte.
+		jsr putcr
+		bra ss1
+endss		ldx #lastrec
+		jsr outcount
+		jsr putcr
+		jmp cmdline
+* Output byte in register B and add it into check sum at temp+1
+checkout	pshs a
+		tfr b,a
+		addb temp+1
+		stb temp+1
+		jsr outbyte
+		puls a
+		rts
+
+* This is the code for the M command, move memory region.
+* Syntax: Maddr1,addr2,length
+move		ldx #linebuf+1
+		jsr scanhex
+		lbeq unk
+		std temp3
+		jsr skipspace
+		cmpb #','
+		lbne unk
+		jsr scanhex
+		lbeq unk
+		tfr d,u
+		jsr skipspace
+		cmpb #','
+		lbne unk
+		jsr scanhex
+		lbeq unk
+		tfr d,y		;Read the argument separated by commas
+		ldx temp3	;src addr to x, dest addr to u, length to y
+			        ;Don't tolerate syntax deviations.
+mvloop		lda ,x+
+		sta ,u+
+		leay -1,y
+		bne mvloop	;Perform the block move.
+		jmp cmdline
+		
+
+* This is the code for the F command, find byte/ascii string in memory.
+* Syntax: Faddr bytes or Faddr "ascii"
+find		ldx #linebuf+1
+		jsr scanhex
+		tfr d,y		;Scan the start address.
+		jsr skipspace
+		cmpb #'"'
+		bne findhex
+		ldu #linebuf	;Quote found, so scan for quoted string.
+		clra
+fstrloop	ldb ,x+
+		beq startsrch	;End of line without final quote.
+		cmpb #'"'
+		beq startsrch   ;End quote found
+		stb ,u+
+		inca
+		bra fstrloop		 		
+findhex		ldu #linebuf	;Convert string of hex bytes.
+		leax -1,x	;String will be stored at start of line
+		clra		;buffer and may overwrite part of the
+fhexloop	pshs a		;already converted string.
+		jsr scanbyte
+		tfr a,b
+		puls a
+		beq startsrch	
+		stb ,u+
+		inca
+		bra fhexloop				
+startsrch	tsta		;Start searching, start addr in Y, 
+		                ;string starts at linebuf, length A
+		lbeq cmdline	;Quit with zero length string.
+		clr temp3
+		sta temp3+1
+srchloop	tfr y,x
+		lda temp3+1
+		cmpx #$e100
+		bcc srch1
+		leax a,x
+		cmpx #$e000	;Stop at I/O addresses.
+		lbcc cmdline
+srch1		tfr y,x
+		ldu #linebuf
+srch2		ldb ,x+
+		cmpb ,u+
+		bne srch3       ;Not equal, try next address.
+		deca 
+		bne srch2
+		tfr y,d
+		jsr outd	;String found
+		jsr putcr
+		inc temp3
+		lda temp3
+		cmpa #$10
+		lbeq cmdline	;If 10 matches found, just stop.
+srch3		leay 1,y
+		bra srchloop
+
+* Send the contents of the xmodem buffer and get it acknowledged, zero flag
+* is set if transfer aborted.
+xsendbuf	ldb #SOH		
+		jsr osputc	;Send SOH
+		ldb xpacknum
+		jsr osputc	;Send block number.
+		comb
+		jsr osputc      ;and its complement.
+		clr xsum
+		lda #128
+		ldx #buf0
+xsloop		ldb ,x
+	        addb xsum
+		stb xsum	
+		ldb ,x+
+		jsr osputc
+		deca
+		bne xsloop      ;Send the buffer contents.
+		ldb xsum
+		jsr osputc	;Send the check sum
+waitack		jsr osgetc
+		cmpb #CAN
+		beq xsabt	;^X for abort.
+		cmpb #NAK        
+		beq xsendbuf	;Send again if NAK
+		cmpb #ACK
+		bne waitack
+		inc xpacknum
+xsok		andcc #$fb	;Clear zero flag after ACK		
+xsabt		rts
+		
+* Start an XMODEM send session.
+xsendinit	ldb #1
+		stb xpacknum	;Initialize block number.
+waitnak		jsr osgetc
+		cmpb #CAN
+		beq xsabt      ;If ^X exit with zero flag.
+		cmpb #NAK
+		beq xsok        
+		bra waitnak    ;Wait until NAK received.
+
+* Send ETX and wait for ack.
+xsendeot	ldb #EOT
+		jsr osputc
+waitack2	jsr osgetc
+		cmpb #CAN
+		beq xsabt
+		cmpb #NAK
+		beq xsendeot
+		cmpb #ACK
+		beq xsok
+		bra waitack2
+
+* Read character into B with a timeout of A seconds,  Carry set if timeout.
+gettimeout	asla
+		ldb #50
+		mul
+		tfr b,a
+		adda timer+2
+gt1		jsr osgetpoll
+		tstb
+		bne gtexit
+		cmpa timer+2
+		bne gt1		
+		orcc #$1
+		rts
+gtexit		jsr osgetc
+		andcc #$fe
+		rts
+
+* Wait until line becomes quiet.
+purge		lda #3
+		jsr gettimeout
+		bcc purge
+		rts
+
+* Receive an XMODEM block and wait till it is OK, Z set if etx.				
+xrcvbuf		lda #3
+		tst lastok				
+		beq sendnak
+		ldb #ACK
+		jsr osputc	;Send an ack.
+		lda #5         
+		bra startblock
+sendnak		ldb #NAK
+		jsr osputc	;Send a NAK
+startblock	clr lastok
+		bsr gettimeout   
+		lda #3
+		bcs sendnak	;Keep sending NAKs when timed out.
+		cmpb #EOT		
+		beq xrcveot	;End of file reached, acknowledge EOT.
+		cmpb #SOH
+		bne purgeit	;Not, SOH, bad block.
+		lda #1
+		bsr gettimeout	
+		bcs purgeit				
+		cmpb xpacknum	;Is it the right block?
+		beq xr1
+		incb
+		cmpb xpacknum   ;Was it the previous block.
+		bne purgeit	
+		inc lastok
+xr1		stb xsum
+		lda #1
+		bsr gettimeout
+		bcs purgeit
+		comb
+		cmpb xsum       ;Is the complement of the block number OK
+		bne purgeit		
+		ldx #buf0
+		clr xsum
+xrloop		lda #1
+		bsr gettimeout  
+		bcs purgeit
+		stb ,x+
+		addb xsum
+		stb xsum
+		cmpx #buf0+128
+		bne xrloop       ;Get the data bytes.		
+		lda #1
+		bsr gettimeout
+		bcs purgeit
+		cmpb xsum
+		bne purgeit	;Check the check sum.
+		tst lastok
+		bne xrcvbuf	;Block was the previous block, get next one
+		inc lastok
+		inc xpacknum
+		andcc #$fb
+		rts
+purgeit		jsr purge
+		bra sendnak		
+xrcveot		lda #3		;EOT was received.
+		ldb #ACK
+ackloop		jsr osputc
+		deca
+		bne ackloop     ;Send 3 acks in a row.
+		rts
+
+
+savevecs	ldx getchar+1
+		stx oldgetc
+		ldx putchar+1
+		stx oldputc
+		ldx putcr+1
+		stx oldputcr
+		clr lastterm
+		rts
+
+rstvecs		ldx oldgetc
+		stx getchar+1
+		ldx oldputc
+		stx putchar+1
+		ldx oldputcr
+		stx putcr+1
+		clr lastterm
+		rts	
+
+* O.S. routine to open input through XMODEM transfer.
+xopin		pshs x,a,b
+		ldx #xsmsg
+		jsr outcount
+		jsr putcr	;Display message to start XMODEM send.
+		bsr savevecs
+		ldx #noop
+		stx putchar+1	;Disable character output.
+		ldx #xgetc
+		stx getchar+1	;
+		clr lastok
+		clr xcount
+		lda #1
+		sta xpacknum
+		inca
+		sta xmode	;set xmode to 2.
+		puls x,a,b,pc
+
+* O.S. routine to open output through XMODEM transfer.
+xopout		pshs x,a,b
+		bsr savevecs
+		ldx #xrmsg
+		jsr outcount	;Display message to start XMODEM receive
+		jsr putcr
+		ldx #xputc
+		stx putchar+1
+		ldx #xputcr
+		stx putcr+1
+		jsr xsendinit
+		lbeq xerror
+		clr xcount
+		lda #1
+		sta xmode
+		puls x,a,b,pc
+		
+
+* O.S. routine to abort input through XMODEM transfer.
+xabtin		lda xmode
+		cmpa #2
+		bne xclsend
+		jsr purge
+		ldb #CAN
+		lda #8
+xabtloop	jsr osputc
+		deca
+		bne xabtloop	;Send 8 CAN characters to kill transfer.
+		bsr rstvecs
+		clr xmode
+		ldx #xamsg
+		jsr outcount
+		jsr putcr	;Send diagnostic message.
+		rts		
+
+* O.S. routine to close output through XMODEM transfer.
+xclsout		lda xmode 
+		cmpa #1
+		bne xclsend
+		tst xcount
+		beq xclsdone
+		lda #128
+		suba xcount
+xclsloop	ldb filler
+		bsr xputc   
+		deca
+		bne xclsloop	;Transfer filler chars to force block out.
+xclsdone	jsr xsendeot	;Send EOT
+		lbeq xerror
+		jsr rstvecs
+		clr xmode						
+xclsend		rts	
+
+* O.S. routine to close input through XMODEM, by gobbling up the remaining
+* bytes.
+xclsin		ldb xmode
+		cmpb #2
+		bne xclsend
+		jsr putchar
+		bra xclsin
+
+* putchar routine for XMODEM 
+xputc		pshs x,a,b
+		lda xcount
+		inc xcount
+		ldx #buf0
+		stb a,x		;Store character in XMODEM buffer.
+		cmpa #127
+		bne xputc1	;is buffer full?
+		clr xcount
+		pshs y,u
+		jsr xsendbuf	
+		lbeq xerror
+		puls y,u
+xputc1		puls x,a,b,pc			
+
+* putcr routine for XMODEM
+xputcr		pshs b
+		ldb xmcr
+		bitb #2
+		beq xputcr1
+		ldb #CR
+		bsr xputc
+xputcr1		ldb xmcr
+		bitb #1
+		beq xputcr2
+		ldb #LF
+		bsr xputc		
+xputcr2		puls b
+		rts
+
+* getchar routine for XMODEM
+xgetc		pshs x,a
+		tst xcount	;No characters left?
+		bne xgetc1
+		pshs y,u
+		jsr xrcvbuf	;Receive new block.
+		puls y,u
+		beq xgetcterm	;End of input?		
+		lda #128
+		sta xcount
+xgetc1		lda xcount
+		nega
+		ldx #buf0+128
+		ldb a,x		;Get character from buffer
+		dec xcount
+		puls x,a,pc		
+xgetcterm	jsr rstvecs
+		clr xmode
+		ldb filler
+		puls x,a,pc
+		
+xerror		jsr rstvecs	;Restore I/O vectors
+		clr xmode
+		ldx #xamsg
+		jsr outcount
+		jsr putcr
+		jmp xerrvec
+	
+xerrhand	lds savesp
+		jmp cmdline
+
+* This is the code for the X command, various XMODEM related commands.
+* Syntax: XSaddr,len XLaddr,len XX XOcrlf,filler, XSSaddr,len
+xmodem		ldx #linebuf+1
+		lda ,x+
+		anda #CASEMASK	;Convert to uppercase.
+		cmpa #'X'
+		beq xeq	
+		cmpa #'L'
+		beq xload
+		cmpa #'O'
+		beq xopts
+		cmpa #'S'
+		lbne unk
+		lda ,x
+		anda #CASEMASK
+		cmpa #'S'
+		beq xss
+		ldd #$100            ;XSaddr,len command.
+		jsr scan2parms       ;Send binary through XMODEM
+		jsr xopenout
+		ldu addr
+		ldy length
+xsbinloop	ldb ,u+
+		jsr putchar		
+		leay -1,y
+		bne xsbinloop 	     ;Send all the bytes through XMODEM.
+		jmp cmdline
+xss		leax 1,x	     ;XSSaddr,len command.
+		jsr xopenout	     ;Send Srecords through XMODEM
+		jmp sendrec		
+xload		jsr scanhex	     ;XLaddr command
+		tfr d,y		     ;Load binary through XMODEM
+		jsr xopenin
+xlodloop	jsr getchar
+		tst xmode	     ;File ended? then done
+		lbeq cmdline					
+		stb ,y+
+		bra xlodloop
+xeq		jsr xopenin	     ;XX command
+		jmp cmdline	     ;Execute commands received from XMODEM
+xopts		ldd #$1a
+		jsr scan2parms
+		lda addr+1
+		sta xmcr
+		lda length+1
+		sta filler
+		jmp cmdline
+	
+* mnemonics table, ordered alphabetically.
+* 5 bytes name, 1 byte category, 2 bytes opcode, 8 bytes total.
+mnemtab         fcc "ABX  "
+                fcb 0
+                fdb $3a
+                fcc "ADCA "
+                fcb 7
+                fdb $89
+                fcc "ADCB "
+                fcb 7
+                fdb $c9
+                fcc "ADDA "
+                fcb 7
+		fdb $8b
+                fcc "ADDB "
+                fcb 7
+                fdb $cb 
+                fcc "ADDD "
+		fcb 8
+		fdb $c3
+                fcc "ANDA "
+                fcb 7
+                fdb $84
+                fcc "ANDB "
+                fcb 7
+                fdb $c4
+                fcc "ANDCC"
+ 		fcb 2
+		fdb $1c
+                fcc "ASL  "
+		fcb 10
+		fdb $08
+                fcc "ASLA "
+		fcb 0
+		fdb $48
+		fcc "ASLB "
+		fcb 0
+		fdb $58
+                fcc "ASR  "
+                fcb 10
+                fdb $07
+                fcc "ASRA "
+		fcb 0
+		fdb $47
+                fcc "ASRB "
+		fcb 0
+		fdb $57
+                fcc "BCC  "
+		fcb 4
+		fdb $24
+                fcc "BCS  "
+		fcb 4 
+		fdb $25
+                fcc "BEQ  "
+		fcb 4
+		fdb $27
+                fcc "BGE  "
+		fcb 4
+		fdb $2c
+                fcc "BGT  "
+		fcb 4
+		fdb $2e
+                fcc "BHI  "
+		fcb 4
+		fdb $22
+                fcc "BHS  "
+		fcb 4
+		fdb $24
+                fcc "BITA "
+		fcb 7
+		fdb $85
+                fcc "BITB "
+		fcb 7
+		fdb $c5
+                fcc "BLE  "
+		fcb 4
+		fdb $2f
+                fcc "BLO  "
+		fcb 4
+		fdb $25
+                fcc "BLS  "
+		fcb 4
+		fdb $23
+                fcc "BLT  "
+		fcb 4
+		fdb $2d
+                fcc "BMI  "
+		fcb 4
+		fdb $2b
+                fcc "BNE  "
+		fcb 4
+		fdb $26
+                fcc "BPL  "
+		fcb 4
+		fdb $2a
+                fcc "BRA  "
+		fcb 4
+		fdb $20 
+                fcc "BRN  "
+		fcb 4
+		fdb $21
+mnembsr         fcc "BSR  "
+		fcb 4
+		fdb $8d
+                fcc "BVC  "
+		fcb 4
+		fdb $28
+                fcc "BVS  "
+		fcb 4
+		fdb $29
+                fcc "CLR  "
+		fcb 10
+		fdb $0f
+                fcc "CLRA "
+		fcb 0
+		fdb $4f
+                fcc "CLRB "
+		fcb 0
+		fdb $5f
+                fcc "CMPA "
+		fcb 7
+		fdb $81
+                fcc "CMPB "
+		fcb 7
+		fdb $c1
+                fcc "CMPD "
+		fcb 9
+		fdb $1083
+                fcc "CMPS "
+		fcb 9
+		fdb $118c
+                fcc "CMPU "
+		fcb 9
+		fdb $1183
+                fcc "CMPX "
+		fcb 8
+		fdb $8c
+                fcc "CMPY "
+		fcb 9
+		fdb $108c
+                fcc "COM  "
+		fcb 10
+		fdb $03
+                fcc "COMA "
+		fcb 0
+		fdb $43
+                fcc "COMB "
+		fcb 0
+		fdb $53
+                fcc "CWAI "
+		fcb 2
+		fdb $3c
+                fcc "DAA  "
+		fcb 0
+		fdb $19
+                fcc "DEC  "
+		fcb 10
+		fdb $0a
+                fcc "DECA "
+		fcb 0
+		fdb $4a
+                fcc "DECB "
+		fcb 0
+		fdb $5a
+                fcc "EORA "
+		fcb 7
+		fdb $88
+                fcc "EORB "
+		fcb 7
+		fdb $c8
+                fcc "EQU  "
+		fcb 13
+		fdb 5
+                fcc "EXG  "
+		fcb 11
+		fdb $1e
+mnemfcb         fcc "FCB  "
+		fcb 13
+		fdb 7
+                fcc "FCC  "
+		fcb 13
+		fdb 8
+                fcc "FDB  "
+		fcb 13
+		fdb 9
+                fcc "INC  "
+		fcb 10
+		fdb $0c
+                fcc "INCA "
+		fcb 0
+		fdb $4c
+                fcc "INCB "
+		fcb 0
+		fdb $5c
+                fcc "JMP  "
+		fcb 10
+		fdb $0e
+mnemjsr         fcc "JSR  "
+		fcb 8
+		fdb $8d
+                fcc "LBCC "
+		fcb 5
+		fdb $1024
+                fcc "LBCS "
+		fcb 5
+		fdb $1025
+                fcc "LBEQ "
+		fcb 5
+		fdb $1027
+                fcc "LBGE "
+		fcb 5
+		fdb $102c
+                fcc "LBGT "
+		fcb 5
+		fdb $102e
+                fcc "LBHI "
+		fcb 5
+		fdb $1022
+                fcc "LBHS "
+		fcb 5
+		fdb $1024
+                fcc "LBLE "
+		fcb 5
+		fdb $102f
+                fcc "LBLO "
+		fcb 5
+		fdb $1025
+                fcc "LBLS "
+		fcb 5
+		fdb $1023
+                fcc "LBLT "
+		fcb 5
+		fdb $102d
+                fcc "LBMI "
+		fcb 5
+		fdb $102b
+                fcc "LBNE "
+		fcb 5
+		fdb $1026
+                fcc "LBPL "
+		fcb 5
+		fdb $102a
+                fcc "LBRA "
+		fcb 6
+		fdb $16
+                fcc "LBRN "
+		fcb 5
+		fdb $1021
+                fcc "LBSR "
+		fcb 6
+		fdb $17
+                fcc "LBVC "
+		fcb 5
+		fdb $1028
+                fcc "LBVS "
+		fcb 5
+		fdb $1029
+                fcc "LDA  "
+		fcb 7
+		fdb $86
+                fcc "LDB  "
+		fcb 7
+		fdb $c6
+                fcc "LDD  "
+		fcb 8
+		fdb $cc
+                fcc "LDS  "
+		fcb 9
+		fdb $10ce
+                fcc "LDU  "
+		fcb 8
+		fdb $ce
+                fcc "LDX  "
+		fcb 8
+		fdb $8e
+                fcc "LDY  "
+		fcb 9
+		fdb $108e
+                fcc "LEAS "
+		fcb 3
+		fdb $32
+                fcc "LEAU "
+		fcb 3
+		fdb $33
+                fcc "LEAX "
+		fcb 3
+		fdb $30
+                fcc "LEAY "
+		fcb 3
+		fdb $31
+                fcc "LSL  "
+		fcb 10
+		fdb $08
+                fcc "LSLA "
+		fcb 0
+		fdb $48
+                fcc "LSLB "
+		fcb 0
+		fdb $58
+                fcc "LSR  "
+		fcb 10
+		fdb $04
+                fcc "LSRA "
+		fcb 0
+		fdb $44
+                fcc "LSRB "
+		fcb 0
+		fdb $54
+                fcc "MUL  "
+		fcb 0
+		fdb $3d
+                fcc "NEG  "
+		fcb 10
+		fdb $00
+                fcc "NEGA "
+		fcb 0
+		fdb $40
+                fcc "NEGB "
+		fcb 0
+		fdb $50
+                fcc "NOP  "
+		fcb 0
+		fdb $12
+                fcc "ORA  "
+		fcb 7
+		fdb $8a
+                fcc "ORB  "
+		fcb 7
+		fdb $ca
+                fcc "ORCC "
+		fcb 2
+		fdb $1a
+                fcc "ORG  "
+		fcb 13
+		fdb 12
+                fcc "PSHS "
+		fcb 12
+		fdb $34
+                fcc "PSHU "
+		fcb 12
+		fdb $36
+                fcc "PULS "
+		fcb 12
+		fdb $35
+                fcc "PULU "
+		fcb 12
+		fdb $37
+                fcc "RMB  "
+		fcb 13
+		fdb 0
+                fcc "ROL  "
+		fcb 10
+		fdb $09
+                fcc "ROLA "
+		fcb 0
+		fdb $49
+                fcc "ROLB "
+		fcb 0
+		fdb $59
+                fcc "ROR  "
+		fcb 10
+		fdb $06
+                fcc "RORA "
+		fcb 0
+		fdb $46
+                fcc "RORB "
+		fcb 0
+		fdb $56
+                fcc "RTI  "
+		fcb 0
+		fdb $3b
+                fcc "RTS  "
+		fcb 0
+		fdb $39
+                fcc "SBCA "
+		fcb 7
+		fdb $82
+                fcc "SBCB "
+		fcb 7
+		fdb $c2
+                fcc "SET  "
+		fcb 13
+		fdb 15
+                fcc "SETDP"
+		fcb 13
+		fdb 14
+                fcc "SEX  "
+		fcb 0
+		fdb $1d
+                fcc "STA  "
+		fcb 7
+		fdb $87
+                fcc "STB  "
+		fcb 7
+		fdb $c7
+                fcc "STD  "
+		fcb 8
+		fdb $cd
+                fcc "STS  "
+		fcb 9
+		fdb $10cf
+                fcc "STU  "
+		fcb 8
+		fdb $cf
+                fcc "STX  "
+		fcb 8
+		fdb $8f
+                fcc "STY  "
+		fcb 9
+		fdb $108f
+                fcc "SUBA "
+		fcb 7
+		fdb $80
+                fcc "SUBB "
+		fcb 7
+		fdb $c0 
+                fcc "SUBD "
+		fcb 8
+		fdb $83
+                fcc "SWI  "
+		fcb 0
+		fdb $3f
+                fcb "SWI2 "
+		fcb 1
+		fdb $103f
+                fcb "SWI3 "
+		fcb 1
+		fdb $113f
+                fcc "SYNC "
+		fcb 0
+		fdb $13
+                fcc "TFR  "
+		fcb 11
+		fdb $1f
+                fcc "TST  "
+		fcb 10
+		fdb $0d
+                fcc "TSTA "
+		fcb 0
+		fdb $4d
+                fcc "TSTB "
+		fcb 0
+		fdb $5d
+
+mnemsize	equ (*-mnemtab)/8
+
+* Register table for PUSH/PULL and TFR/EXG instructions.
+* 3 bytes for name, 1 for tfr/exg, 1 for push/pull, 5 total 
+asmregtab     	fcc "X  "
+		fcb $01,$10
+		fcc "Y  "
+		fcb $02,$20
+aregu           fcc "U  "
+		fcb $03,$40
+aregs		fcc "S  "
+		fcb $04,$40
+		fcc "PC "
+		fcb $05,$80
+                fcc "A  "
+		fcb $08,$02
+		fcc "B  "
+		fcb $09,$04
+		fcc "D  "
+		fcb $00,$06
+		fcc "CC "
+		fcb $0a,$01
+		fcc "CCR"
+		fcb $0a,$01
+		fcc "DP "
+		fcb $0b,$08
+		fcc "DPR"
+		fcb $0b,$08
+reginval	fcc "?  "
+
+ixregs		fcc "XYUS"
+
+* opcode offsets to basic opcode, depends on first nibble. 
+opcoffs		fcb 0,0,0,0,0,0,-$60,-$70
+		fcb 0,-$10,-$20,-$30,0,-$10,-$20,-$30
+* mode depending on first nibble of opcode.
+modetab		fcb 3,0,0,0,0,0,5,4,1,3,5,4,1,3,5,4
+* mode depending on category code stored in mnemtab
+modetab2	fcb 0,0,1,5,6,7,7,1,2,2,0,8,9
+* modes in this context: 0 no operands, 1 8-bit immediate, 2 16 bit imm,
+* 3, 8-bit address, 4 16 bit address, 5 indexed with postbyte, 6 short
+* relative, 7 long relative, 8 pushpul, 9 tftetx
+
+* Decode instruction pointed to by Y for disassembly (and to find out
+* how long it is). On return, U points to appropriate mnemonic table entry,
+* Y points past instruction. 
+* It's rather clumsy code, but we do want to reuse the same table
+* as used with assembling.
+disdecode	clr prebyte
+		clr amode
+		lda ,y+
+		cmpa #$10
+		beq ddec1
+		cmpa #$11
+		bne ddec2
+ddec1		sta prebyte         ;Store $10 or $11 prebyte.
+		lda ,y+             ;Get new opcode.
+ddec2		sta opcode
+		lsra
+		lsra
+		lsra
+		lsra		    ;Get high nibble.
+		ldx #modetab
+		ldb a,x
+		stb amode
+		ldx #opcoffs
+		lda a,x
+		adda opcode         ;Add opcode offset to opcode. 		
+ddec4		sta opc1            ;Store the 'basis' opcode.
+		ldu #mnemtab
+		ldx #mnemsize
+ddecloop	ldb #13
+		cmpb 5,u            ;Compare category code with 13
+		beq ddec3	    ;13=pseudo op, no valid opcode
+		ldd prebyte
+		cmpd 6,u
+		beq ddecfound	    ;Opcode&prebyte agree, operation found.
+ddec3		leau 8,u            ;point to next mnemonic
+		leax -1,x
+		bne ddecloop        
+		ldu #mnemfcb        ;mnemonic not found, use FCB byte.
+		lda #3
+		sta amode	    ;Store mode 3, 8 bit address.
+		lda opcode
+		tst prebyte
+		beq ddec5
+		lda prebyte 	    ;if it was the combination prebyte
+		clr prebyte         ;and opcode that was not found,
+         	leay -1,y 	    ;FCB just the prebyte
+ddec5	        sta operand+1       ;The byte must be stored as operand.	
+		rts
+ddecfound       cmpu #mnembsr
+		bne ddec6
+		lda #$8d	    ;Is it really the BSR opcode?
+		cmpa opcode
+		beq ddec6
+		ldu #mnemjsr        ;We mistakenly found BSR instead of JSR
+ddec6           lda amode
+		anda #$FE
+		bne ddec7
+		lda 5,u             ;nibble-dependent mode was 0 or 1,
+		ldx #modetab2       ;use category dependent mode instead.
+		lda a,x
+		sta amode
+ddec7           lda amode
+		asla
+		ldx #disdectab
+		jmp [a,x]           ;jump dependent on definitive mode.
+disdectab	fdb noop,opdec1,opdec2,opdec1,opdec2,opdecidx
+		fdb opdec1,opdec2,opdecpb,opdecpb
+disdectab1	fdb noop,noop,noop,noop,noop,noop,noop,noop
+		fdb opdec1,opdec2,noop,noop,opdec1,opdec2,noop,opdec2
+opdec1		ldb ,y+
+		sex
+od1a		std operand
+noop		rts 
+opdec2		ldd ,y++
+		bra od1a
+opdecpb		ldb ,y+
+odpa		stb postbyte
+		rts
+opdecidx	ldb ,y+
+		bpl odpa	;postbytes <$80 have no extra operands.
+		stb postbyte    
+		andb #$0f
+		aslb
+		ldx #disdectab1
+		jmp [b,x]
+
+* Display disassembled instruction after the invocation of disdecode.
+* U points to mnemonic table entry.
+disdisp		tfr u,x
+		ldb #5
+		jsr putline      ;Display the mnemonic.
+		ldb #' '
+		jsr putchar
+		lda amode
+		asla
+		ldx #disdisptab
+		jmp [a,x]        ;Perform action dependent on mode.
+disdisptab	fdb noop,disim8,disim16,disadr8,disadr16
+		fdb disidx,disrel8,disrel16,distfr,dispush
+disim8		bsr puthash
+		bra disadr8
+disim16		bsr puthash
+disadr16	bsr putdol
+		ldd operand
+		jmp outd
+disadr8		bsr putdol
+		lda operand+1
+		jmp outbyte
+disrel8		bsr putdol
+		ldb operand+1
+		sex
+dr8a		sty temp
+		addd temp
+		jmp outd
+disrel16	bsr putdol
+		ldd operand
+		bra dr8a
+		
+puthash		ldb #'#'
+		jmp putchar
+putdol		ldb #'$'
+		jmp putchar						    
+putcomma	ldb #','
+		jmp putchar
+putspace	ldb #' '
+		jmp putchar
+
+dispush		ldb #12
+		ldx #asmregtab	;Walk through the register table.
+		clr temp
+regloop		lda postbyte
+		anda 4,x                
+		beq dispush1	;Is bit corresponding to reg set in postbyte
+		cmpx #aregu
+		bne dispush3
+		sta temp+1
+		lda opcode
+		anda #2
+		bne dispush1    ;no u register in pshu pulu.
+		lda temp+1		
+dispush3	cmpx #aregs
+		bne dispush4
+		sta temp+1
+		lda opcode
+		anda #2
+		beq dispush1   ;no s register in pshs puls.
+		lda temp+1
+dispush4	coma
+		anda postbyte   ;remove the bits from postbyte.
+		sta postbyte
+		pshs b          
+		tst temp
+		beq dispush2
+		bsr putcomma	;print comma after first register.
+dispush2	bsr disregname
+		inc temp
+		puls b
+dispush1	leax 5,x
+		decb
+		bne regloop		
+		rts
+
+distfr 		lda postbyte
+		lsra
+		lsra
+		lsra
+		lsra
+		bsr distfrsub
+		bsr putcomma
+		lda postbyte
+		anda #$0f
+distfrsub	ldb #12
+		ldx #asmregtab
+distfrloop	cmpa 3,x
+		beq distfrend
+		leax 5,x
+		decb
+		bne distfrloop
+distfrend	bsr disregname
+		rts
+
+disregname	lda #3
+		tfr x,u
+drnloop		ldb ,u+
+		cmpb #' '
+		beq drnend
+		jsr putchar
+		deca
+		bne drnloop
+drnend		rts
+
+disidxreg	lda postbyte
+		lsra
+		lsra
+		lsra
+		lsra
+		lsra
+		anda #3
+		ldx #ixregs
+		ldb a,x
+		jmp putchar
+
+disidx		clr temp
+		lda postbyte
+		bmi disidx1
+		anda #$1f
+		bita #$10
+		bne negoffs
+		jsr outdecbyte
+		bra discomma
+negoffs		ldb #'-'
+		jsr putchar
+		ora #$f0
+		nega
+		jsr outdecbyte
+discomma	jsr putcomma         ;Display ,Xreg and terminating ]
+disindex	bsr disidxreg
+disindir	tst temp             ;Display ] if indirect.
+		beq disidxend      
+		ldb #']'       
+		jsr putchar
+disidxend	rts
+disidx1		bita #$10			
+		beq disidx2
+		ldb #'['
+		jsr putchar
+		inc temp
+disidx2		lda postbyte
+		anda #$0f
+		asla
+		ldx #disidxtab
+		jmp [a,x]	     ;Jump to routine for indexed mode
+disadec2	lda #2
+		bra disadeca
+disadec1 	lda #1		
+disadeca	jsr putcomma
+disadloop	ldb #'-'
+		jsr putchar
+		deca
+		bne disadloop
+		bra disindex
+disainc2	lda #2
+		bra disainca
+disainc1	lda #1
+disainca	sta temp+1
+		jsr putcomma
+		jsr disidxreg		
+		lda temp+1
+disailoop	ldb #'+'
+		jsr putchar
+		deca
+		bne disailoop
+		jmp disindir
+disax		ldb #'A'
+		jsr putchar
+		jmp discomma
+disbx		ldb #'B'
+		jsr putchar
+		jmp discomma
+disdx		ldb #'D'
+		jsr putchar
+		jmp discomma
+disinval	ldb #'?'
+		jsr putchar
+		jmp disindir
+disnx		lda operand+1
+		bmi disnxneg
+disnx1		jsr putdol
+		jsr outbyte
+		jmp discomma
+disnxneg	ldb #'-'
+		jsr putchar
+		nega
+		bra disnx1
+disnnx		jsr putdol
+		ldd operand
+		jsr outd
+		jmp discomma
+disnpc		jsr putdol
+		ldb operand+1
+		sex
+disnpca		sty temp2
+		addd temp2
+		jsr outd
+		ldx #commapc
+		ldb #4
+		jsr putline
+		jmp disindir
+disnnpc		jsr putdol
+		ldd operand
+		bra disnpca
+disdirect	jsr putdol
+		ldd operand
+		jsr outd		
+		jmp disindir
+
+commapc		fcc ",PCR"
+
+disidxtab	fdb disainc1,disainc2,disadec1,disadec2
+		fdb discomma,disbx,disax,disinval
+		fdb disnx,disnnx,disinval,disdx
+		fdb disnpc,disnnpc,disinval,disdirect		
+
+* Display byte A in decimal (0<=A<20)
+outdecbyte	cmpa #10
+		blo odb1
+		suba #10
+		ldb #'1'
+		jsr putchar
+odb1		adda #'0'
+		tfr a,b
+		jmp putchar
+		
+* This is the code for the U command, unassemble instructions in memory.
+* Syntax: U or Uaddr or Uaddr,length
+unasm		ldx #linebuf+1
+		ldd #20
+		jsr scan2parms  ;Scan address,length parameters.
+		ldd addr
+		addd length
+		std length
+		ldy addr
+unasmloop	tfr y,d
+		jsr outd        ;Display instruction address
+		jsr putspace
+		pshs y
+		jsr disdecode
+		puls x
+		sty temp
+		clr temp2
+unadishex	lda ,x+
+		jsr outbyte
+		inc temp2
+		inc temp2
+		cmpx temp
+		bne unadishex  ;Display instruction bytes as hex.
+unadisspc	ldb #' '
+		jsr putchar
+		inc temp2
+		lda #11
+		cmpa temp2     ;Fill out with spaces to width 11.
+		bne unadisspc
+		bne unadishex
+		jsr disdisp    ;Display disassembled instruction.
+		jsr putcr
+		cmpy length
+		bls unasmloop
+		sty addr
+		jmp cmdline
+
+* Simple 'expression evaluator' for assembler.
+expr		ldb ,x
+		cmpb #'-'
+		bne pos
+		clrb
+		leax 1,x
+pos		pshs b
+		bsr scanfact
+		beq exprend1
+		tst ,s+
+		bne exprend 	;Was the minus sign there.
+		coma
+		comb
+		addd #1
+		andcc #$fb	;Clear Z flag for valid result.
+exprend		rts		
+exprend1	puls b
+		rts
+
+scanfact	ldb ,x+
+		cmpb #'$'
+		lbeq scanhex   ;Hex number if starting with dollar.
+		cmpb #'''
+		bne scandec    ;char if starting with ' else decimal
+		ldb ,x+
+		lda ,x
+		cmpa #'''
+		bne scanchar2
+		leax 1,x       ;Increment past final quote if it's there.
+scanchar2	clra
+		andcc #$fb     ;Clear zero flag.
+		rts
+scandec		cmpb #'0'
+		blo noexpr
+		cmpb #'9'
+		bhi noexpr
+		clr temp
+		clr temp+1
+scandloop	subb #'0'
+		bcs sdexit				
+		cmpb #10
+		bcc sdexit
+		pshs b
+		ldd temp
+		aslb
+		rola
+		pshs d
+		aslb
+		rola
+		aslb
+		rola
+		addd ,s++     ;Multiply number by 10.
+		addb ,s+
+		adca #0	      ;Add digit to 10.
+		std temp	
+		ldb ,x+	      ;Get next character.
+		bra scandloop
+sdexit		ldd temp
+		leax -1,x
+		andcc #$fb	
+		rts			
+noexpr		orcc #$04
+		rts	
+
+* Assemble the instruction pointed to by X.
+* Fisrt stage: copy mnemonic to mnemonic buffer.
+asminstr 	lda #5
+		ldu #mnembuf
+mncploop	ldb ,x+		
+		beq mncpexit
+		cmpb #' '
+		beq mncpexit	;Mnemonic ends at first space or null
+		andb #CASEMASK
+		cmpb #'A'
+		blo nolet
+		cmpb #'Z'
+		bls mnemcp1	;Capitalize letters, but only letters.
+nolet		ldb -1,x
+mnemcp1		stb ,u+		;Copy to mnemonic buffer.
+		deca
+		bne mncploop
+mncpexit	tsta
+		beq mncpdone
+		ldb #' '
+mnfilloop	stb ,u+
+		deca
+		bne mnfilloop	;Fill the rest of mnem buffer with spaces.
+* Second stage: look mnemonic up using binary search.
+mncpdone	stx temp3
+		clr temp	;Low index=0
+		lda #mnemsize
+		sta temp+1      ;High index=mnemsize.
+bsrchloop	ldb temp+1
+		cmpb #$ff
+		beq invmnem	;lower limit -1?
+		cmpb temp
+		blo invmnem     ;hi index lower than low index?
+		clra
+		addb temp	;Add indexes.
+		adca #0 	
+		lsra
+		rorb		;Divide by 2 to get average
+		stb temp2
+		aslb
+		rola
+		aslb		
+		rola		
+		aslb
+		rola		;Multiply by 8 to get offset.
+		ldu #mnemtab
+		leau d,u	;Add offset to table base
+		tfr u,y
+		lda #5
+		ldx #mnembuf
+bscmploop	ldb ,x+
+		cmpb ,y+
+		bne bscmpexit	;Characters don't match?
+		deca
+		bne bscmploop
+		jmp mnemfound	;We found the mnemonic.
+bscmpexit	ldb temp2
+		bcc bscmplower
+		decb
+		stb temp+1	;mnembuf<table, adjust high limit.
+		bra bsrchloop
+bscmplower	incb
+		stb temp	;mnembuf>table, adjust low limit.
+		bra bsrchloop
+invmnem		ldx #invmmsg	
+		jmp asmerrvec
+* Stage 3: Perform routine depending on category code.
+mnemfound	clr uncert
+		ldy addr
+		lda 5,u
+		asla
+		ldx #asmtab
+		jsr [a,x]
+		sty addr
+		rts
+asmtab		fdb onebyte,twobyte,immbyte,lea
+		fdb sbranch,lbranch,lbra,acc8
+		fdb dreg1,dreg2,oneaddr,tfrexg
+		fdb pushpul,pseudo
+
+putbyte		stb ,y+
+		rts
+putword		std ,y++
+		rts
+
+onebyte		ldb 7,u		;Cat 0, one byte opcode w/o operands RTS
+		bra putbyte
+twobyte		ldd 6,u		;Cat 1, two byte opcode w/o operands SWI2
+		bra putword
+immbyte		ldb 7,u		;Cat 2, opcode w/ immdiate operand ANDCC
+		bsr putbyte
+		jsr scanops
+		ldb amode
+		cmpb #1
+		lbne moderr
+		ldb operand+1
+		bra putbyte
+lea		ldb 7,u		;Cat 3, LEA
+		bsr putbyte
+		jsr scanops
+		lda amode
+		cmpa #1
+		lbeq moderr	;No immediate w/ lea
+		cmpa #3
+		lbhs doaddr	
+		jsr set3
+		lda #$8f
+		sta postbyte
+		lda #2
+		sta opsize	;Use 8F nn nn for direct mode.	
+		jmp doaddr
+sbranch		ldb 7,u		;Cat 4, short branch instructions
+		bsr putbyte
+		jsr startop
+		leax -1,x
+		jsr exprvec
+		lbeq exprerr
+		jmp shortrel
+lbranch		ldd 6,u		;Cat 5, long brach w/ two byte opcode
+		bsr putword
+lbra1		jsr startop
+		leax -1,x
+		jsr exprvec
+		lbeq exprerr
+		jmp longrel		
+lbra		ldb 7,u		;Cat 6, long branch w/ one byte opcode.
+		jsr putbyte
+		bra lbra1
+acc8		lda #1		;Cat 7, 8-bit two operand instructions ADDA
+		sta opsize
+		jsr scanops
+		jsr adjopc
+		jsr putbyte
+		jmp doaddr
+dreg1		lda #2		;Cat 8, 16-bit 2operand insns 1byte opc LDX
+		sta opsize
+		jsr scanops
+		jsr adjopc
+		jsr putbyte
+		jmp doaddr
+dreg2		lda #2		;Cat 9, 16-bit 2operand insns 2byte opc LDY
+		sta opsize
+		jsr scanops
+		jsr adjopc
+		lda 6,u
+		jsr putword
+		jmp doaddr
+oneaddr		jsr scanops	;Cat 10, one-operand insns NEG..CLR
+		ldb 7,u
+		lda amode
+		cmpa #1
+		lbeq moderr	;No immediate mode
+		cmpa #3
+		bhs oaind	;indexed etc
+		lda opsize
+		deca
+		beq oadir
+		addb #$10	;Add $70 for extended direct.
+oaind		addb #$60	;And $60 for indexed etc.
+oadir		jsr putbyte	;And nothing for direct8.
+		jmp doaddr
+tfrexg		jsr startop	;Cat 11, TFR and EXG
+		leax -1,x
+		ldb 7,u
+		jsr putbyte
+		jsr findreg
+		ldb ,u
+		aslb 
+		aslb
+		aslb
+		aslb
+		stb postbyte
+		ldb ,x+
+		cmpb #','
+		lbne moderr
+		jsr findreg
+		ldb ,u
+		orb postbyte
+		jmp putbyte		
+pushpul		jsr startop	;Cat 12, PSH and PUL
+		leax -1,x
+		ldb 7,u
+		jsr putbyte
+		clr postbyte
+pploop		jsr findreg
+		ldb 1,u
+		orb postbyte
+		stb postbyte
+		ldb ,x+
+		cmpb #','
+		beq pploop
+		leax -1,x
+		ldb postbyte
+		jmp putbyte		
+pseudo				;Cat 13, pseudo oeprations
+		rts
+
+* Adjust opcdoe depending on mode (in $80-$FF range)
+adjopc		ldb 7,u
+		lda amode
+		cmpa #2
+		beq adjdir	;Is it direct?
+		cmpa #3
+		bhs adjind	;Indexed etc?
+		rts		;Not, then immediate, no adjust.
+adjind		addb #$20	;Add $20 to opcode for indexed etc modes.
+		rts
+adjdir		addb #$10	;Add $10 to opcode for direct8
+		lda opsize
+		deca
+		bne adjind	;If opsize=2, add another $20 for extended16	
+		rts
+
+* Start scanning of operands.
+startop		ldx temp3
+		clr amode
+		jmp skipspace
+
+* amode settings in assembler: 1=immediate, 2=direct/extended, 3=indexed
+* etc. 4=pc relative, 5=indirect, 6=pcrelative and indirect.
+
+* This subroutine scans the assembler operands.
+scanops		bsr startop
+		cmpb #'['
+		bne noindir
+		lda #5		;operand starts with [, then indirect.
+		sta amode	
+		ldb ,x+
+noindir		cmpb #'#'
+		lbeq doimm
+		cmpb #','
+		lbeq dospecial
+		andb #CASEMASK    ;Convert to uppercase.
+		lda #$86
+		cmpb #'A'
+		beq scanacidx
+		lda #$85
+		cmpb #'B'
+		beq scanacidx
+		lda #$8B
+		cmpb #'D'
+		bne scanlab
+scanacidx	ldb ,x+		;Could it be A,X B,X or D,X
+		cmpb #','
+		bne nocomma
+		sta postbyte
+		clr opsize
+		jsr set3
+		jsr scanixreg
+		bra scanend
+nocomma		leax -1,x		
+scanlab		leax -1,x	;Point to the start of the operand
+		jsr exprvec
+		lbeq exprerr    
+		std operand
+		tst uncert
+		bne opsz2	;Go for extended if operand unknown.
+		subd dpsetting  
+		tsta		;Can we use 8-bit operand?
+		bne opsz2
+		inca		
+		bra opsz1
+opsz2		lda #2
+opsz1		sta opsize	;Set opsize depending on magnitude of op.
+		lda amode
+		cmpa #5
+		bne opsz3	;Or was it indirect.
+		lda #2		;Then we have postbyte and opsize=2
+		sta opsize
+		lda #$8F
+		sta postbyte	
+		bra opsz4
+opsz3		lda #2
+		sta amode	;Assume direct or absolute addressing 
+opsz4		ldb ,x+		
+		cmpb #','
+		lbeq doindex	;If followed by, then indexed.
+scanend		lda amode
+		cmpa #5
+		blo scanend2	;Was it an indirect mode?
+		lda postbyte
+		ora #$10	;Set indirect bit.
+		sta postbyte
+		ldb ,x+		
+		cmpb #']'	;Check for the other ]
+		lbeq moderr
+scanend2	rts
+doimm		jsr exprvec	;Immediate addressing.	
+		lbeq exprerr
+		std operand
+		lda amode
+		cmpa #5
+		lbeq moderr	;Inirect mode w/ imm is illegal.
+		lda #$01
+		sta amode
+		rts
+dospecial	jsr set3
+		clr opsize
+		clra
+adecloop	ldb ,x+
+		cmpb #'-'
+		bne adecend
+		inca		;Count the - signs for autodecrement.
+		bra adecloop
+adecend		leax -1,x
+		cmpa #2				
+		lbhi moderr
+		tsta
+		bne autodec
+		clr postbyte
+		jsr scanixreg
+		clra
+aincloop	ldb ,x+
+		cmpb #'+'
+		bne aincend
+		inca
+		bra aincloop	;Count the + signs for autoincrement.			
+aincend		leax -1,x
+		cmpa #2
+		lbhi moderr
+		tsta
+		bne autoinc
+		lda #$84
+		ora postbyte
+		sta postbyte
+		bra scanend
+autoinc		adda #$7f
+		ora postbyte
+		sta postbyte		
+		bra scanend
+autodec		adda #$81
+		sta postbyte
+		jsr scanixreg
+		lbra scanend
+doindex		clr postbyte
+		jsr set3
+		ldb ,x+
+		andb #CASEMASK	;Convert to uppercase.
+		cmpb #'P'
+		lbeq dopcrel	;Check for PC relative.
+		leax -1,x
+		clr opsize
+		bsr scanixreg
+		ldd operand
+		tst uncert
+		bne longindex	;Go for long index if operand unknown.
+		cmpd #-16
+		blt shortindex
+		cmpd #15
+		bgt shortindex
+		lda amode
+		cmpa #5		
+		beq shortind1	;Indirect may not be 5-bit index	
+				;It's a five-bit index.
+		andb #$1f
+		orb postbyte
+		stb postbyte
+		lbra scanend
+shortindex	cmpd #-128
+		blt longindex
+		cmpd #127
+		bgt longindex
+shortind1	inc opsize
+		ldb #$88
+		orb postbyte
+		stb postbyte
+		lbra scanend
+longindex	lda #$2
+		sta opsize
+		ldb #$89
+		orb postbyte
+		stb postbyte
+		lbra scanend
+dopcrel		ldb ,x+
+		andb #CASEMASK	;Convert to uppercase
+		cmpb #'C'
+		blo pcrelend
+		cmpb #'R'
+		bhi pcrelend
+		bra dopcrel	;Scan past the ,PCR 
+pcrelend	leax -1,x
+		ldb #$8C
+		orb postbyte	;Set postbyte
+		stb postbyte	
+		inc amode	;Set addr mode to PCR
+		lbra scanend
+
+* Scan for one of the 4 index registers and adjust postbyte. 
+scanixreg	ldb ,x+
+		andb #CASEMASK	;Convert to uppercase.
+		pshs x
+		ldx #ixregs
+		clra
+scidxloop	cmpb ,x+
+		beq ixfound
+		adda #$20
+		bpl scidxloop
+		jmp moderr	;Index register not found where expected.
+ixfound		ora postbyte
+		sta postbyte	;Set index reg bits in postbyte.
+		puls x
+		rts		
+				
+* This routine sets amode to 3, if it was less.
+set3		lda amode
+		cmpa #3
+		bhs set3a
+		lda #3
+		sta amode
+set3a		rts
+
+* This subroutine lays down the address.
+doaddr		lda amode
+		cmpa #3
+		blo doa1
+		ldb postbyte
+		jsr putbyte
+		lda amode 
+		anda #1
+		beq doapcrel	;pc rel modes.
+doa1		lda opsize
+		tsta
+		beq set3a
+		deca
+		beq doa2
+		ldd operand
+		jmp putword
+doa2		ldb operand+1
+		jmp putbyte		
+doapcrel	sty addr
+		ldd operand
+		subd addr
+		subd #1
+		tst uncert
+		bne pcrlong
+		cmpd #-128
+		blt pcrlong
+		cmpd #-127
+		bgt pcrlong
+		lda #1
+		sta opsize
+		jmp putbyte
+pcrlong		subd #1
+		leay -1,y
+		inc postbyte
+		pshs d
+		ldb postbyte
+		jsr putbyte
+		lda #2
+		sta opsize
+		puls d
+		jmp putword
+
+* This routine checks and lays down short relative address.
+shortrel	sty addr
+		subd addr
+		subd #1
+		cmpd #-128
+		blt brerr
+		cmpd #127
+		bgt brerr
+		jsr putbyte
+		lda #4
+		sta amode
+		lda #1
+		sta opsize
+		rts
+* This routine lays down long relative address.
+longrel		sty addr
+		subd addr
+		subd #2
+		jsr putword
+		lda #4
+		sta amode
+		lda #2
+		sta opsize
+		rts
+
+brerr		ldx #brmsg
+		jmp asmerrvec 
+exprerr		ldx #exprmsg
+		jmp asmerrvec
+moderr		ldx #modemsg
+		jmp asmerrvec
+asmerr		pshs x
+		jsr xabortin
+		puls x
+		jsr outcount
+		jsr putcr
+		lds savesp
+		jmp cmdline
+
+* Find register for TFR and PSH instruction
+findreg		ldb #12
+		pshs y,b
+		ldu #asmregtab
+findregloop	tfr x,y
+		lda #3
+frcmps		ldb ,u
+		cmpb #' '
+		bne frcmps1
+		ldb ,y
+		cmpb #'A'
+		blt frfound
+frcmps1		ldb ,y+
+		andb #CASEMASK
+		cmpb ,u+
+		bne frnextreg
+		deca
+		bne frcmps
+		inca
+		bra frfound
+frnextreg	inca
+		leau a,u
+		dec ,s
+		bne findregloop
+		lbra moderr
+frfound		leau a,u
+		tfr y,x
+		puls y,b
+		rts
+
+* This is the code for the A command, assemble instructions.
+* Syntax: Aaddr
+asm		ldx #linebuf+1
+		jsr scanhex
+		std addr
+asmloop		ldd addr
+		jsr outd
+		ldb #' '
+		jsr putchar	;Print address and space.
+		ldx #linebuf
+		ldb #128
+		jsr getline	;Get new line
+		tstb	
+		lbeq cmdline    ;Exit on empty line.
+		abx 
+		clr ,x		;Make line zero terminated.
+		ldx #linebuf
+		jsr asminstr
+		bra asmloop
+			
+* Jump table for monitor routines that are usable by other programs.
+		org $ffc0
+		jmp outbyte
+		jmp outd
+		jmp scanbyte
+		jmp scanhex
+		jmp scanfact
+		jmp asminstr
+		
+								
+* Interrupt vector addresses at top of ROM. Most are vectored through jumps
+* in RAM.
+		org $fff2
+		fdb swi3vec
+		fdb swi2vec
+		fdb firqvec
+		fdb irqvec
+		fdb swivec
+		fdb nmivec
+		fdb reset
+
+		end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/Makefile	Mon Jul 02 02:12:31 2018 +0900
@@ -0,0 +1,20 @@
+all: os9mod makerom os9disass os9.rom
+
+CC=clang
+CFLAGS = -g
+
+os9mod : crc.c os9.h os9mod.c os9.h
+	$(CC) $(CFLAGS) -o os9mod crc.c  os9mod.c
+
+makerom : makerom.c
+	$(CC) $(CFLAGS) -o makerom  makerom.c
+
+os9disass : os9disass.c
+	$(CC) $(CFLAGS) -Wno-format-security -o os9disass  os9disass.c
+
+os9.rom : makerom modules/init.b modules/pty.b
+	./makerom os9.rom modules/Shell modules/init.b modules/mdir modules/SysGo modules/IOMan modules/SCF modules/pty-dd.b modules/pty.b modules/OS9p2 modules/OS9
+
+os9b.rom : makerom modules/init.b modules/pty.b
+	./makerom os9b.rom modules/Basic09 modules/Shell modules/init.b modules/mdir modules/SysGo modules/IOMan modules/SCF modules/pty-dd.b modules/pty.b modules/OS9p2 modules/OS9
+   
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/crc.c	Mon Jul 02 02:12:31 2018 +0900
@@ -0,0 +1,49 @@
+#include <stdio.h>
+
+#include "os9.h"
+
+int os9_crc(OS9_MODULE_t *mod)
+{
+  int i;
+  u_char crc[3] = {0xff, 0xff, 0xff};
+  u_char *ptr = (u_char *) mod;
+  u_char a;
+
+  for (i = 0; i < INT(mod->size); i++)
+    {
+      a = *(ptr++);
+
+      a ^= crc[0];
+      crc[0] = crc[1];
+      crc[1] = crc[2];
+      crc[1] ^= (a >> 7);
+      crc[2] = (a << 1);
+      crc[1] ^= (a >> 2);
+      crc[2] ^= (a << 6);
+      a ^= (a << 1);
+      a ^= (a << 2);
+      a ^= (a << 4);
+      if (a & 0x80) {
+	crc[0] ^= 0x80;
+	crc[2] ^= 0x21;
+      }
+    }
+  if ((crc[0] == OS9_CRC0) &&
+      (crc[1] == OS9_CRC1) &&
+      (crc[2] == OS9_CRC2))
+    return 1;
+
+  return 0;
+}
+
+int os9_header(OS9_MODULE_t *mod)
+{
+  u_char tmp = 0x00;
+  u_char *ptr = (u_char *) mod;
+  int i;
+  
+  for (i = 0; i < OS9_HEADER_SIZE; i++)
+    tmp ^= *(ptr++);
+  
+  return tmp;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/makerom.c	Mon Jul 02 02:12:31 2018 +0900
@@ -0,0 +1,141 @@
+/* makerom.c 
+   build ROM image file os9.rom from module list
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <sys/stat.h>
+
+#define IOBASE 0xe000
+#define IOSIZE 0x800
+
+typedef struct os9module {
+   int size;
+   int location;
+   int ioflag;
+   unsigned char *mod;
+   char *name;
+   struct os9module *next;
+} *MPTR ; 
+
+struct os9module *
+readOS9module(char *filename) 
+{
+  FILE *fp = fopen(filename,"rb");
+  if (fp==0) {
+    fprintf(stderr,"cannot read %s\n",filename);
+    exit(1);
+  }
+  struct stat st;
+  fstat(fileno(fp),&st);
+  int size = st.st_size;
+  struct os9module *m = malloc(size + sizeof(struct os9module));
+  m->size = size;
+  m->next = 0;
+  m->ioflag = 0;
+  m->mod = (unsigned char*)m + sizeof(struct os9module);
+  fread(m->mod , size, 1, fp);
+  m->name = (char*) (m->mod + (m->mod[4]*256 + m->mod[5]) );
+  fclose(fp);
+  return m;
+}
+
+void
+fputword(unsigned short x, FILE *fp)
+{
+   fputc((x>>8)&0xff,fp);
+   fputc(x&0xff,fp);
+}
+
+void printOs9Str(char *p)
+{
+   while((*p & 0x80)==0) {
+      putchar(*p);
+      p++;
+   }
+   putchar(*p & 0x7f);
+}
+
+int findLocation(MPTR m, int loc) {
+   if (m==0) return loc;
+   int top = findLocation(m->next, loc) - m->size;
+   if (m->next==0) top = 0xf800;  // OS9p1
+   if (!(( top+m->size < IOBASE )  || ( IOBASE+IOSIZE < top)) ) {
+      top = IOBASE-m->size-1;
+      m->ioflag = 1;
+      // printf("*");
+   }
+   m->location = top;
+   // printf("mod ");
+   // printOs9Str(m->name);
+   // printf(" \t: 0x%x - 0x%x\n",top, top + m->size);
+   return top;
+}
+
+int
+main(int ac, char *av[])
+{
+ int vectable = 0;
+ struct os9module *m = 0, root ;
+ root.size = 0;
+ root.mod = 0;
+ m = &root;
+
+ for(int i = 2 ; i<ac ; i++ ) {
+    struct os9module *cur;
+    cur = readOS9module(av[i]);
+    m->next = cur;
+    m = cur;
+ }
+
+ FILE *romfile;
+ unsigned pos;
+
+ romfile=fopen(av[1],"wb");
+ if(!romfile) {
+  fprintf(stderr,"Cannot create file %s\n",av[1]);
+  exit(1);
+ }
+
+ 
+ int start = findLocation(root.next,0);
+ start = start&0xf800;
+ printf("\n\n");
+
+ pos = start;
+ for(struct os9module *cur = root.next; cur ; cur = cur->next ) {
+    if ( cur->size && (cur->name[0]=='O' && cur->name[1]=='S' && cur->name[2]== -71)) {
+       for(; pos < 0xf800 ; pos++) {
+          fputc(0xff,romfile);
+       }
+    }
+    printf("mod ");
+    printOs9Str(cur->name);
+    fwrite(cur->mod, cur->size, 1, romfile);
+    printf(" \t: 0x%x - 0x%x\n",pos, pos + cur->size);
+    // printf(" \t: 0x%x - 0x%x : 0x%lx \n",pos, pos + cur->size, ftell(romfile)+start);
+    pos = pos+cur->size;
+    if (cur->ioflag) {
+       for(; pos < IOBASE + IOSIZE; pos++) {
+          fputc(0xff,romfile);
+       }
+       printf("*");
+    } 
+ }
+ printf("os9 end %x\n",pos);
+ vectable  = 0x10000 - 2*7;
+ for( ; pos<vectable; pos++) fputc(0xff,romfile);
+ printf("vectbl %x\n",pos);
+ fputword(0xF82d,romfile);
+ fputword(0xF831,romfile);
+ fputword(0xF835,romfile);
+ fputword(0xF839,romfile);
+ fputword(0xF83d,romfile);
+ fputword(0xF841,romfile);
+ fputword(0xF876,romfile);
+ 
+ printf("boot rom from 0x%lx\n",0x10000-ftell(romfile)); 
+ fclose(romfile);
+ return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/os9.h	Mon Jul 02 02:12:31 2018 +0900
@@ -0,0 +1,94 @@
+typedef unsigned char u_char;
+
+typedef struct os9_module_t {
+  u_char id[2];
+  u_char size[2];
+  u_char name[2];
+  u_char tyla;
+  u_char atrv;
+  u_char parity;
+  union {
+    u_char data[1];		/* plain modules */
+    struct {
+      u_char exec[2];
+      u_char data[1];
+    } system;
+    struct {
+      u_char exec[2];
+      u_char mem[2];
+      u_char data[1];
+    } program;
+    struct {
+      u_char exec[2];
+      u_char mem[2];
+      u_char mode[1];
+      u_char data[1];
+    } driver;
+    struct {
+      u_char exec[2];
+      u_char data[1];
+    } file_mgr;
+    struct {
+      u_char fmgr[2];
+      u_char driver[2];
+      u_char mode;
+      u_char port[3];
+      u_char opt;
+      u_char dtype;
+      u_char data[1];
+    } descriptor;
+  } data;
+} OS9_MODULE_t;
+
+#define OS9_HEADER_SIZE 9
+
+#define TYPE_MASK 0xF0
+typedef enum os9_type_t {
+  NULL_TYPE = 0,
+  Prgrm, 
+  Sbtrn, 
+  Multi, 
+  Data,  
+  SSbtrn,
+  TYPE_6,
+  TYPE_7,
+  TYPE_8,
+  TYPE_9,
+  TYPE_A,
+  TYPE_B,
+  Systm, 
+  FlMgr,
+  Drivr,
+  Devic  
+} OS9_TYPE_t;
+
+#define LANG_MASK 0x0F
+typedef enum os9_lang_t {
+  NULL_LANG = 0,
+  Objct,
+  ICode,
+  PCode,
+  CCode,
+  CblCode,
+  FrtnCode,
+  Obj6309,
+} OS9_LANG_t;
+
+#define ATTR_MASK 0xF0
+typedef enum os9_attr_t {
+  ReEnt   = 0x80,
+  Modprot = 0x40,
+} OS9_attr_t;
+
+#define REVS_MASK 0x0F
+
+#define OS9_ID0 0x87
+#define OS9_ID1 0xcd
+
+#define OS9_CRC0 0x80
+#define OS9_CRC1 0x0F
+#define OS9_CRC2 0xE3
+
+#define INT(foo) (foo[0] * 256 + foo[1])
+int os9_crc(OS9_MODULE_t *mod);
+int os9_header(OS9_MODULE_t *mod);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/os9disass.c	Mon Jul 02 02:12:31 2018 +0900
@@ -0,0 +1,1549 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+
+/*************************************************************************** 
+  Originally posted to comp.sys.m6809 by Didier Derny (didier@aida.remcomp.fr)
+
+  Minor hacks by Alan DeKok
+
+ Fixed: D_Indexed addressing used prog[2] and prog[3] when it meant
+        prog[pc+2] and prog[pc+3]:  Would produce flawed disassemblies!
+
+        changed addresses in D_Indexed to be all hex.
+	added 2 instances of 'extrabyte' in D_Indexed: would not skip them..
+        Added PC offsets to D_Indexed ,PCR formats
+	added SWI2 print out as OS9
+
+  To do:
+
+ handle command-line options properly...
+
+ Fix handling of illegal opcodes so it doesn't skip a byte
+   i.e. $87 is a skip 2
+
+ Move defines to another file
+
+ Add 6309 support
+   also add 6309 native-mode support, and listing of clock cycles for opcodes.
+
+ Add OS-9 support
+
+ add proper label-disassembly.  i.e. 2-pass.
+
+****************************************************************************/
+
+// extern int errno;
+// extern char *sys_errlist[];
+
+static unsigned char prog0[65536];
+unsigned char *prog = prog0;
+
+FILE *fp;
+
+typedef struct {
+	char *name;
+	int  clock;
+	int  bytes;
+	int  (*display)();
+	int  (*execute)();
+} Opcode;
+
+typedef struct {
+  int address;
+  int length;
+  int width;
+} String;
+
+int    D_Illegal(Opcode *, int, int, char *);
+int    D_Direct(Opcode *, int, int, char *);
+int    D_Page10(Opcode *, int, int, char *);
+int    D_Page11(Opcode *, int, int, char *);
+int    D_Immediat(Opcode *, int, int, char *);
+int    D_ImmediatL(Opcode *, int, int, char *);
+int    D_Inherent(Opcode *, int, int, char *);
+int    D_Indexed(Opcode *, int, int, char *);
+int    D_Extended(Opcode *, int, int, char *);
+int    D_Relative(Opcode *, int, int, char *);
+int    D_RelativeL(Opcode *, int, int, char *);
+int    D_Register0(Opcode *, int, int, char *);
+int    D_Register1(Opcode *, int, int, char *);
+int    D_Register2(Opcode *, int, int, char *);
+int    D_Page10(Opcode *, int, int, char *);
+int    D_Page11(Opcode *, int, int, char *);
+int    D_OS9(Opcode *, int, int, char *);
+char  *IndexRegister(int);
+
+String stringtable[] = {
+	{ 0xc321, 16,  16 },
+	{ 0xc395, 258, 16 },
+	{ 0xeb15,  50, 16 },
+	{ 0xee6f, 128, 16 },
+	{ 0xfdf4, 492, 16 },
+	{ 0xfff0, 16,   2 },
+};
+
+int adoffset = 0;
+int laststring = 6;
+
+Opcode optable[] = {
+  { "NEG  ",  6,  2, D_Direct,    NULL },	 /* 0x00 */
+  { "?????",  0,  1, D_Illegal,   NULL },	 /* 0x01 */
+  { "?????",  0,  1,	D_Illegal,   NULL },	 /* 0x02 */
+  { "COM  ",  6,  2,	D_Direct,    NULL },	 /* 0x03 */
+  { "LSR  ",  6,  2,	D_Direct,    NULL },	 /* 0x04 */
+  { "?????",  0,  1,	D_Illegal,   NULL },	 /* 0x05 */
+  { "ROR  ",  6,  2,	D_Direct,    NULL },	 /* 0x06 */
+  { "ASR  ",  6,  2,	D_Direct,    NULL },	 /* 0x07 */
+  { "LSL  ",  6,  2,	D_Direct,    NULL },	 /* 0x08 */
+  { "ROR  ",  6,  2,	D_Direct,    NULL },	 /* 0x09 */
+  { "DEC  ",  6,  2,	D_Direct,    NULL },	 /* 0x0a */
+  { "?????",  0,  1,	D_Illegal,   NULL },	 /* 0x0b */
+  { "INC  ",  6,  2,	D_Direct,    NULL },	 /* 0x0c */
+  { "TST  ",  6,  2,	D_Direct,    NULL },	 /* 0x0d */
+  { "JMP  ",  3,  2,	D_Direct,    NULL },	 /* 0x0e */
+  { "CLR  ",  6,  2,	D_Direct,    NULL },     /* 0x0f */
+
+  { "",       0,  1, D_Page10,    NULL },	 /* 0x10 */
+  { "",       0,  1, D_Page11,    NULL },	 /* 0x11 */
+  { "NOP  ",  2,  1, D_Inherent,  NULL },	 /* 0x12 */
+  { "SYNC ",  4,  1, D_Inherent,  NULL },       /* 0x13 */
+  { "?????",  0,  1, D_Illegal,   NULL },	 /* 0x14 */
+  { "?????",  0,  1, D_Illegal,   NULL },  /* 0x15 */
+  { "LBRA ",  5,  3, D_RelativeL, NULL },	 /* 0x16 */
+  { "LBSR ",  9,  3, D_RelativeL, NULL },	 /* 0x17 */
+  { "?????",  0,  1, D_Illegal,   NULL },	 /* 0x18 */
+  { "DAA  ",  2,  1, D_Inherent,  NULL },	 /* 0x19 */
+  { "ORCC ",  3,  2, D_Immediat,  NULL },	 /* 0x1a */
+  { "?????",  0,  1, D_Illegal,   NULL },	 /* 0x1b */
+  { "ANDCC",  3,  2, D_Immediat,  NULL },  /* 0x1c */
+  { "SEX  ",  2,  1, D_Inherent,  NULL },	 /* 0x1d */
+  { "EXG  ",  8,  2, D_Register0, NULL },	 /* 0x1e */
+  { "TFR  ",  6,  2,   D_Register0, NULL },	 /* 0x1f */
+
+  { "BRA  ",  3,  2,   D_Relative,  NULL },	 /* 0x20 */
+  { "BRN  ",  3,  2,   D_Relative,  NULL },	 /* 0x21 */
+  { "BHI  ",  3,  2,   D_Relative,  NULL },	 /* 0x22 */
+  { "BLS  ",  3,  2,   D_Relative,  NULL },	 /* 0x23 */
+  { "BCC  ",  3,  2,   D_Relative,  NULL },	 /* 0x24 */
+  { "BCS  ",  3,  2,   D_Relative,  NULL },	 /* 0x25 */
+  { "BNE  ",  3,  2,   D_Relative,  NULL },	 /* 0x26 */
+  { "BEQ  ",  3,  2,   D_Relative,  NULL },	 /* 0x27 */
+  { "BVC  ",  3,  2,   D_Relative,  NULL },	 /* 0x28 */
+  { "BVS  ",  3,  2,   D_Relative,  NULL },	 /* 0x29 */
+  { "BPL  ",  3,  2,   D_Relative,  NULL },	 /* 0x2a */
+  { "BMI  ",  3,  2,   D_Relative,  NULL },	 /* 0x2b */
+  { "BGE  ",  3,  2,   D_Relative,  NULL },	 /* 0x2c */
+  { "BLT  ",  3,  2,   D_Relative,  NULL },	 /* 0x2d */
+  { "BGT  ",  3,  2,   D_Relative,  NULL },	 /* 0x2e */
+  { "BLE  ",  3,  2,   D_Relative,  NULL },	 /* 0x2f */
+
+  { "LEAX ",  4,  2,   D_Indexed,   NULL },  /* 0x30 */
+  { "LEAY ",  4,  2,   D_Indexed,   NULL },  /* 0x31 */
+  { "LEAS ",  4,  2,   D_Indexed,   NULL },  /* 0x32 */
+  { "LEAU ",  4,  2,   D_Indexed,   NULL },  /* 0x33 */
+  { "PSHS ",  5,  2,   D_Register1, NULL },  /* 0x34 */
+  { "PULS ",  5,  2,   D_Register1, NULL },  /* 0x35 */
+  { "PSHU ",  5,  2,   D_Register2, NULL },  /* 0x36 */
+  { "PULU ",  5,  2,   D_Register2, NULL },  /* 0x37 */
+  { "?????",  0,  1,   D_Illegal,   NULL },  /* 0x38 */
+  { "RTS  ",  5,  1,   D_Inherent,  NULL },  /* 0x39 */
+  { "ABX  ",  3,  1,   D_Inherent,  NULL },  /* 0x3a */
+  { "RTI  ",  6,  1,   D_Inherent,  NULL },  /* 0x3b */
+  { "CWAI ",  20, 2,   D_Inherent,  NULL },  /* 0x3c */
+  { "MUL  ",  11, 1,   D_Inherent,  NULL },  /* 0x3d */
+  { "?????",  0,  1,   D_Illegal,   NULL },  /* 0x3e */
+  { "SWI  ",  19, 1,   D_Inherent,  NULL },  /* 0x3f */
+
+  { "NEGA ",   2,  1,   D_Inherent,  NULL },	 /* 0x40 */
+  {  "?????",  0, 1,   D_Illegal,   NULL },	 /* 0x41 */
+  {  "?????",  0, 1,   D_Illegal,   NULL },	 /* 0x42 */
+  {  "COMA ",  2, 1,   D_Inherent,  NULL },	 /* 0x43 */
+  {  "LSRA ",  2, 1,   D_Inherent,  NULL },	 /* 0x44 */
+  {  "?????",  0, 1,   D_Illegal,   NULL },	 /* 0x45 */
+  {  "RORA ",  2, 1,   D_Inherent,  NULL },	 /* 0x46 */
+  {  "ASRA ",  2, 1,   D_Inherent,  NULL },	 /* 0x47 */
+  {  "LSLA ",  2, 1,   D_Inherent,  NULL },	 /* 0x48 */
+  {  "ROLA ",  2, 1,   D_Inherent,  NULL },	 /* 0x49 */
+  {  "DECA ",  2, 1,   D_Inherent,  NULL },	 /* 0x4a */
+  {  "?????",  0, 1,   D_Illegal,   NULL },	 /* 0x4b */
+  {  "INCA ",  2, 1,   D_Inherent,  NULL },	 /* 0x4c */
+  {  "TSTA ",  2, 1,   D_Inherent,  NULL },  /* 0x4d */
+  {  "?????",  0, 1,   D_Illegal,   NULL },	 /* 0x4e */
+  {  "CLRA ",  2, 1,   D_Inherent,  NULL },	 /* 0x4f */
+
+  {  "NEGB ",  2, 1,   D_Inherent,  NULL },	 /* 0x50 */
+  { "?????",   0, 1,   D_Illegal,   NULL },	 /* 0x51 */
+  { "?????",   0, 1,   D_Illegal,   NULL },	 /* 0x52 */
+  { "COMB ",   2, 1,   D_Inherent,  NULL },	 /* 0x53 */
+  { "LSRB ",   2, 1,   D_Inherent,  NULL },	 /* 0x54 */
+  { "?????",   0, 1,   D_Illegal,   NULL },	 /* 0x55 */
+  { "RORB ",   2, 1,   D_Inherent,  NULL },	 /* 0x56 */
+  { "ASRB ",   2, 1,   D_Inherent,  NULL },	 /* 0x57 */
+  { "LSLB ",   2, 1,   D_Inherent,  NULL },	 /* 0x58 */
+  { "ROLB ",   2, 1,   D_Inherent,  NULL },	 /* 0x59 */
+  { "DECB ",   2, 1,   D_Inherent,  NULL },	 /* 0x5a */
+  { "?????",   0, 1,   D_Illegal,   NULL },	 /* 0x5b */
+  { "INCB ",   2, 1,   D_Inherent,  NULL },	 /* 0x5c */
+  { "TSTB ",   2, 1,   D_Inherent,  NULL },	 /* 0x5d */
+  { "?????",   0, 1,   D_Illegal,   NULL },	 /* 0x5e */
+  { "CLRB ",   2, 1,   D_Inherent,  NULL },	 /* 0x5f */
+
+  { "NEG  ",   6, 2,   D_Indexed,   NULL },	 /* 0x60 */
+  { "?????",   0, 2,   D_Illegal,   NULL },	 /* 0x61 */
+  { "?????",   0, 2,   D_Illegal,   NULL },	 /* 0x62 */
+  { "COM  ",   6, 2,   D_Indexed,   NULL },	 /* 0x63 */
+  { "LSR  ",   6, 2,   D_Indexed,   NULL },	 /* 0x64 */
+  { "?????",   0, 2,   D_Indexed,   NULL },	 /* 0x65 */
+  { "ROR  ",   6, 2,   D_Indexed,   NULL },	 /* 0x66 */
+  { "ASR  ",   6, 2,   D_Indexed,   NULL },	 /* 0x67 */
+  { "LSL  ",   6, 2,   D_Indexed,   NULL },	 /* 0x68 */
+  { "ROL  ",   6, 2,   D_Indexed,   NULL },	 /* 0x69 */
+  { "DEC  ",   6, 2,   D_Indexed,   NULL },	 /* 0x6a */
+  { "?????",   0, 2,   D_Illegal,   NULL },	 /* 0x6b */
+  { "INC  ",   6, 2,   D_Indexed,   NULL },	 /* 0x6c */
+  { "TST  ",   6, 2,   D_Indexed,   NULL },	 /* 0x6d */
+  { "JMP  ",   3, 2,   D_Indexed,   NULL },	 /* 0x6e */
+  { "CLR  ",   6, 2,   D_Indexed,   NULL },	 /* 0x6f */
+
+  { "NEG  ",   7, 3,   D_Extended,  NULL },      /* 0x70 */
+  { "?????",   0, 1,   D_Illegal,   NULL },      /* 0x71 */
+  { "?????",   0, 1,   D_Illegal,   NULL },	 /* 0x72 */
+  { "COM  ",   7, 3,   D_Extended,  NULL },	 /* 0x73 */
+  { "LSR  ",   7, 3,   D_Extended,  NULL },	 /* 0x74 */
+  { "?????",   0, 1,   D_Illegal,   NULL },	 /* 0x75 */
+  { "ROR  ",   7, 3,   D_Extended,  NULL },	 /* 0x76 */
+  { "ASR  ",   7, 3,   D_Extended,  NULL },	 /* 0x77 */
+  { "LSL  ",   7, 3,   D_Extended,  NULL },	 /* 0x78 */
+  { "ROL  ",   7, 3,   D_Extended,  NULL },	 /* 0x79 */
+  { "DEC  ",   7, 3,   D_Extended,  NULL },	 /* 0x7a */
+  { "?????",   0, 1,   D_Illegal,   NULL },	 /* 0x7b */
+  { "INC  ",   7, 3,   D_Extended,  NULL },	 /* 0x7c */
+  { "TST  ",   7, 3,   D_Extended,  NULL },	 /* 0x7d */
+  { "JMP  ",   4, 3,   D_Extended,  NULL },	 /* 0x7e */
+  { "CLR  ",   7, 3,   D_Extended,  NULL },	 /* 0x7f */
+
+  { "SUBA ",  2,  2,   D_Immediat,  NULL },	/* 0x80 */
+  { "CMPA ",  2,  2,   D_Immediat,  NULL },	/* 0x81 */
+  { "SBCA ",  2,  2,   D_Immediat,  NULL },	/* 0x82 */
+  { "SUBD ",  4,  3,   D_ImmediatL, NULL },	/* 0x83 */
+  { "ANDA ",  2,  2,   D_Immediat,  NULL },	/* 0x84 */
+  { "BITA ",  2,  2,   D_Immediat,  NULL },	/* 0x85 */
+  { "LDA  ",  2,  2,   D_Immediat,  NULL },	/* 0x86 */
+  { "?????",  0,  2,   D_Illegal,   NULL },	/* 0x87 */
+  { "EORA ",  2,  2,   D_Immediat,  NULL },	/* 0x88 */
+  { "ADCA ",  2,  2,   D_Immediat,  NULL },	/* 0x89 */
+  { "ORA  ",  2,  2,   D_Immediat,  NULL },	/* 0x8a */
+  { "ADDA ",  2,  2,   D_Immediat,  NULL },	/* 0x8b */
+  { "CMPX ",  4,  3,   D_ImmediatL, NULL },	/* 0x8c */
+  { "BSR  ",  7,  2,   D_Relative,  NULL },	/* 0x8d */
+  { "LDX  ",  3,  3,   D_ImmediatL, NULL },	/* 0x8e */
+  { "?????",  0,  2,   D_Illegal,   NULL },	/* 0x8f */
+
+  { "SUBA ",  4,  2,   D_Direct,    NULL },	/* 0x90 */
+  { "CMPA ",  4,  2,   D_Direct,    NULL },	/* 0x91 */
+  { "SBCA ",  4,  2,   D_Direct,    NULL },	/* 0x92 */
+  { "SUBD ",  6,  2,   D_Direct,    NULL },	/* 0x93 */
+  { "ANDA ",  4,  2,   D_Direct,    NULL },	/* 0x94 */
+  { "BITA ",  4,  2,   D_Direct,    NULL },	/* 0x95 */
+  { "LDA  ",  4,  2,   D_Direct,    NULL },	/* 0x96 */
+  { "STA  ",  4,  2,   D_Direct,    NULL },	/* 0x97 */
+  { "EORA ",  4,  2,   D_Direct,    NULL },	/* 0x98 */
+  { "ADCA ",  4,  2,   D_Direct,    NULL },	/* 0x99 */
+  { "ORA  ",  4,  2,   D_Direct,    NULL },	/* 0x9a */
+  { "ADDA ",  4,  2,   D_Direct,    NULL },	/* 0x9b */
+  { "CMPX ",  6,  2,   D_Direct,    NULL },	/* 0x9c */
+  { "JSR  ",  7,  2,   D_Direct,    NULL },	/* 0x9d */
+  { "LDX  ",  5,  2,   D_Direct,    NULL },	/* 0x9e */
+  { "STX  ",  5,  2,   D_Direct,    NULL },	/* 0x9f */
+
+  { "SUBA ",  4,  2,   D_Indexed,   NULL },	/* 0xa0 */
+  { "CMPA ",  4,  2,   D_Indexed,   NULL },	/* 0xa1 */
+  { "SBCA ",  4,  2,   D_Indexed,   NULL },	/* 0xa2 */
+  { "SUBD ",  6,  2,   D_Indexed,   NULL },	/* 0xa3 */
+  { "ANDA ",  4,  2,   D_Indexed,   NULL },	/* 0xa4 */
+  { "BITA ",  4,  2,   D_Indexed,   NULL },	/* 0xa5 */
+  { "LDA  ",  4,  2,   D_Indexed,   NULL },	/* 0xa6 */
+  { "STA  ",  4,  2,   D_Indexed,   NULL },	/* 0xa7 */
+  { "EORA ",  4,  2,   D_Indexed,   NULL },	/* 0xa8 */
+  { "ADCA ",  4,  2,   D_Indexed,   NULL },	/* 0xa9 */
+  { "ORA  ",  4,  2,   D_Indexed,   NULL },	/* 0xaa */
+  { "ADDA ",  4,  2,   D_Indexed,   NULL },	/* 0xab */
+  { "CMPX ",  6,  2,   D_Indexed,   NULL },	/* 0xac */
+  { "JSR  ",  7,  2,   D_Indexed,   NULL },	/* 0xad */
+  { "LDX  ",  5,  2,   D_Indexed,   NULL },	/* 0xae */
+  { "STX  ",  5,  2,   D_Indexed,   NULL },	/* 0xaf */
+
+  { "SUBA ",  5,  3,   D_Extended,  NULL },	/* 0xb0 */
+  { "CMPA ",  5,  3,   D_Extended,  NULL },	/* 0xb1 */
+  { "SBCA ",  5,  3,   D_Extended,  NULL },	/* 0xb2 */
+  { "SUBD ",  7,  3,   D_Extended,  NULL },	/* 0xb3 */
+  { "ANDA ",  5,  3,   D_Extended,  NULL },	/* 0xb4 */
+  { "BITA ",  5,  3,   D_Extended,  NULL },	/* 0xb5 */
+  { "LDA  ",  5,  3,   D_Extended,  NULL },	/* 0xb6 */
+  { "STA  ",  5,  3,   D_Extended,  NULL },	/* 0xb7 */
+  { "EORA ",  5,  3,   D_Extended,  NULL },	/* 0xb8 */
+  { "ADCA ",  5,  3,   D_Extended,  NULL },	/* 0xb9 */
+  { "ORA  ",  5,  3,   D_Extended,  NULL },	/* 0xba */
+  { "ADDA ",  5,  3,   D_Extended,  NULL },	/* 0xbb */
+  { "CMPX ",  7,  3,   D_Extended,  NULL },	/* 0xbc */
+  { "JSR  ",  8,  3,   D_Extended,  NULL },	/* 0xbd */
+  { "LDX  ",  6,  3,   D_Extended,  NULL },	/* 0xbe */
+  { "STX  ",  6,  3,   D_Extended,  NULL },	/* 0xbf */
+
+  { "SUBB ",  2,  2,   D_Immediat,  NULL },	/* 0xc0 */
+  { "CMPB ",  2,  2,   D_Immediat,  NULL },	/* 0xc1 */
+  { "SBCB ",  2,  2,   D_Immediat,  NULL },	/* 0xc2 */
+  { "ADDD ",  4,  3,   D_ImmediatL, NULL },	/* 0xc3 */
+  { "ANDB ",  2,  2,   D_Immediat,  NULL },	/* 0xc4 */
+  { "BITB ",  2,  2,   D_Immediat,  NULL },	/* 0xc5 */
+  { "LDB  ",  2,  2,   D_Immediat,  NULL },	/* 0xc6 */
+  { "?????",  0,  1,   D_Illegal,   NULL },	/* 0xc7 */
+  { "EORB ",  2,  2,   D_Immediat,  NULL },	/* 0xc8 */
+  { "ADCB ",  2,  2,   D_Immediat,  NULL },	/* 0xc9 */
+  { "ORB  ",  2,  2,   D_Immediat,  NULL },	/* 0xca */
+  { "ADDB ",  2,  2,   D_Immediat,  NULL },	/* 0xcb */
+  { "LDD  ",  3,  3,   D_ImmediatL, NULL },	/* 0xcc */
+  { "?????",  0,  1,   D_Illegal,   NULL },	/* 0xcd */
+  { "LDU  ",  3,  3,   D_ImmediatL, NULL },	/* 0xce */
+  { "?????",  0,  1,   D_Illegal,   NULL },	/* 0xcf */
+
+  { "SUBB ",  4,  2,   D_Direct,    NULL },	/* 0xd0 */
+  { "CMPB ",  4,  2,   D_Direct,    NULL },	/* 0xd1 */
+  { "SBCB ",  4,  2,   D_Direct,    NULL },	/* 0xd2 */
+  { "ADDD ",  6,  2,   D_Direct,    NULL },	/* 0xd3 */
+  { "ANDB ",  4,  2,   D_Direct,    NULL },	/* 0xd4 */
+  { "BITB ",  4,  2,   D_Direct,    NULL },	/* 0xd5 */
+  { "LDB  ",  4,  2,   D_Direct,    NULL },	/* 0xd6 */
+  { "STB  ",  4,  2,   D_Direct,    NULL },	/* 0xd7 */
+  { "EORB ",  4,  2,   D_Direct,    NULL },	/* 0xd8 */
+  { "ADCB ",  4,  2,   D_Direct,    NULL },	/* 0xd9 */
+  { "ORB  ",  4,  2,   D_Direct,    NULL },	/* 0xda */
+  { "ADDB ",  4,  2,   D_Direct,    NULL },	/* 0xdb */
+  { "LDD  ",  5,  2,   D_Direct,    NULL },	/* 0xdc */
+  { "STD  ",  5,  2,   D_Direct,    NULL },	/* 0xdd */
+  { "LDU  ",  5,  2,   D_Direct,    NULL },	/* 0xde */
+  { "STU  ",  5,  2,   D_Direct,    NULL },	/* 0xdf */
+
+  { "SUBB ",  4,  2,   D_Indexed,   NULL },	   /* 0xe0 */
+  { "CMPB ",  4,  2,   D_Indexed,   NULL },	   /* 0xe1 */
+  { "SBCB ",  4,  2,   D_Indexed,   NULL },	   /* 0xe2 */
+  { "ADDD ",  6,  2,   D_Indexed,   NULL },  	   /* 0xe3 */
+  { "ANDB ",  4,  2,   D_Indexed,   NULL },	   /* 0xe4 */
+  { "BITB ",  4,  2,   D_Indexed,   NULL },	   /* 0xe5 */
+  { "LDB  ",  4,  2,   D_Indexed,   NULL },	   /* 0xe6 */
+  { "STB  ",  4,  2,   D_Indexed,   NULL },	   /* 0xe7 */
+  { "EORB ",  4,  2,   D_Indexed,   NULL },	   /* 0xe8 */
+  { "ADCB ",  4,  2,   D_Indexed,   NULL },	   /* 0xe9 */
+  { "ORB  ",  4,  2,   D_Indexed,   NULL },	   /* 0xea */
+  { "ADDB ",  4,  2,   D_Indexed,   NULL },	   /* 0xeb */
+  { "LDD  ",  5,  2,   D_Indexed,   NULL },	   /* 0xec */
+  { "STD  ",  5,  2,   D_Indexed,   NULL },	   /* 0xed */
+  { "LDU  ",  5,  2,   D_Indexed,   NULL },	   /* 0xee */
+  { "STU  ",  5,  2,   D_Indexed,   NULL },	   /* 0xef */
+
+  { "SUBB ",  5,  3,   D_Extended,  NULL },	   /* 0xf0 */
+  { "CMPB ",  5,  3,   D_Extended,  NULL },	   /* 0xf1 */
+  { "SBCB ",  5,  3,   D_Extended,  NULL },	   /* 0xf2 */
+  { "ADDD ",  7,  3,   D_Extended,  NULL },	   /* 0xf3 */
+  { "ANDB ",  5,  3,   D_Extended,  NULL },	   /* 0xf4 */
+  { "BITB ",  5,  3,   D_Extended,  NULL },	   /* 0xf5 */
+  { "LDB  ",  5,  3,   D_Extended,  NULL },	   /* 0xf6 */
+  { "STB  ",  5,  3,   D_Extended,  NULL },	   /* 0xf7 */
+  { "EORB ",  5,  3,   D_Extended,  NULL },	   /* 0xf8 */
+  { "ADCB ",  5,  3,   D_Extended,  NULL },	   /* 0xf9 */
+  { "ORB  ",  5,  3,   D_Extended,  NULL },	   /* 0xfa */
+  { "ADDB ",  5,  3,   D_Extended,  NULL },	   /* 0xfb */
+  { "LDD  ",  6,  3,   D_Extended,  NULL },	   /* 0xfc */
+  { "STD  ",  6,  3,   D_Extended,  NULL },	   /* 0xfd */
+  { "LDU  ",  6,  3,   D_Extended,  NULL },	   /* 0xfe */
+  { "STU  ",  6,  3,   D_Extended,  NULL },   	   /* 0xff */
+};
+
+Opcode optable10[] = {
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x00 */
+  { "?????",  0,  1,   D_Illegal,   NULL },	   /* 0x01 */
+  { "?????",  0,  1,   D_Illegal,   NULL },	   /* 0x02 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x03 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x04 */
+  { "?????",  0,  1,   D_Illegal,   NULL },	   /* 0x05 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x06 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x07 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x08 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x09 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x0a */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x0b */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x0c */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x0d */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x0e */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x0f */
+
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x10 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x11 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x12 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x13 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x14 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x15 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x16 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x17 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x18 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x19 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x1a */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x1b */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x1c */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x1d */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x1e */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x1f */
+
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x20 */
+  { "LBRN ",  5,  4,   D_RelativeL, NULL },        /* 0x21 */
+  { "LBHI ",  5,  4,   D_RelativeL, NULL },        /* 0x22 */
+  { "LBLS ",  5,  4,   D_RelativeL, NULL },        /* 0x23 */
+  { "LBCC ",  5,  4,   D_RelativeL, NULL },        /* 0x24 */
+  { "LBCS ",  5,  4,   D_RelativeL, NULL },        /* 0x25 */
+  { "LBNE ",  5,  4,   D_RelativeL, NULL },        /* 0x26 */
+  { "LBEQ ",  5,  4,   D_RelativeL, NULL },        /* 0x27 */
+  { "LBVC ",  5,  4,   D_RelativeL, NULL },        /* 0x28 */
+  { "LBVS ",  5,  4,   D_RelativeL, NULL },        /* 0x29 */
+  { "LBPL ",  5,  4,   D_RelativeL, NULL },        /* 0x2a */
+  { "LBMI ",  5,  4,   D_RelativeL, NULL },        /* 0x2b */
+  { "LBGE ",  5,  4,   D_RelativeL, NULL },        /* 0x2c */
+  { "LBLT ",  5,  4,   D_RelativeL, NULL },        /* 0x2d */
+  { "LBGT ",  5,  4,   D_RelativeL, NULL },        /* 0x2e */
+  { "LBLE ",  5,  4,   D_RelativeL, NULL },        /* 0x2f */
+
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x30 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x31 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x32 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x33 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x34 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x35 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x36 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x37 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x38 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x39 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x3a */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x3b */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x3c */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x3d */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x3e */
+/* Fake SWI2 as an OS9 F$xxx system call */
+  { "OS9  ",  20, 3,   D_OS9,  NULL },        /* 0x3f */
+
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x40 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x41 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x42 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x43 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x44 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x45 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x46 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x47 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x48 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x49 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x4a */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x4b */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x4c */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x4d */
+  { "?????",  0,  1,   D_Illegal,   NULL },	   /* 0x4e */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x4f */
+
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x50 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x51 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x52 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x53 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x54 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x55 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x56 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x57 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x58 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x59 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x5a */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x5b */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x5c */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x5d */
+  { "?????",  0,  1,   D_Illegal,   NULL },	   /* 0x5e */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x5f */
+
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x60 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x61 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x62 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x63 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x64 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x65 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x66 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x67 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x68 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x69 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x6a */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x6b */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x6c */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x6d */
+  { "?????",  0,  1,   D_Illegal,   NULL },	   /* 0x6e */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x6f */
+
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x70 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x71 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x72 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x73 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x74 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x75 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x76 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x77 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x78 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x79 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x7a */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x7b */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x7c */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x7d */
+  { "?????",  0,  1,   D_Illegal,   NULL },	   /* 0x7e */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x7f */
+
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x80 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x81 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x82 */
+  { "CMPD ",  5,  4,   D_ImmediatL, NULL },        /* 0x83 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x84 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x85 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x86 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x87 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x88 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x89 */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x8a */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x8b */
+  { "CMPY ",  5,  4,   D_ImmediatL, NULL },        /* 0x8c */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x8d */
+  { "LDY  ",  4,  4,   D_ImmediatL, NULL },	   /* 0x8e */
+  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x8f */
+
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x90 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x91 */
+ 	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x92 */
+             { "CMPD ",  7,  3,   D_Direct,    NULL },        /* 0x93 */
+			  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x94 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x95 */
+			  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x96 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x97 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x98 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x99 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x9a */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x9b */
+             { "CMPY ",  7,  3,   D_Direct,    NULL },        /* 0x9c */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x9d */
+				 { "LDY  ",  6,  3,   D_Direct,    NULL },	 /* 0x9e */
+             { "STY  ",  6,  3,   D_Direct,    NULL },        /* 0x9f */
+
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xa0 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xa1 */
+ 	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xa2 */
+             { "CMPD ",  7,  3,   D_Indexed,   NULL },        /* 0xa3 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xa4 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xa5 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xa6 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xa7 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xa8 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xa9 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xaa */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xab */
+             { "CMPY ",  7,  3,   D_Indexed,   NULL },        /* 0xac */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xad */
+             { "LDY  ",  6,  3,   D_Indexed,   NULL },	 /* 0xae */
+				 { "STY  ",  6,  3,   D_Indexed,   NULL },        /* 0xaf */
+
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xb0 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xb1 */
+ 	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xb2 */
+             { "CMPD ",  8,  4,   D_Extended,  NULL },        /* 0xb3 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xb4 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xb5 */
+			  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xb6 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xb7 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xb8 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xb9 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xba */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xbb */
+             { "CMPY ",  8,  4,   D_Extended,  NULL },        /* 0xbc */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xbd */
+             { "LDY  ",  7,  4,   D_Extended,  NULL },	 /* 0xbe */
+             { "STY  ",  7,  4,   D_Extended,  NULL },        /* 0xbf */
+
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc0 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc1 */
+ 	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc2 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc3 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc4 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc5 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc6 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc7 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc8 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc9 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xca */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xcb */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xcc */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xcd */
+             { "LDS  ",  4,  4,   D_ImmediatL, NULL },	 /* 0xce */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xcf */
+
+		  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd0 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd1 */
+ 	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd2 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd3 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd4 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd5 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd6 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd7 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd8 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd9 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xda */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xdb */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xdc */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xdd */
+             { "LDS  ",  6,  3,   D_Direct,    NULL },	 /* 0xde */
+             { "STS  ",  6,  3,   D_Direct,    NULL },        /* 0xdf */
+
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe0 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe1 */
+ 	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe2 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe3 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe4 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe5 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe6 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe7 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe8 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe9 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xea */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xeb */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xec */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xed */
+             { "LDS  ",  6,  3,   D_Indexed,   NULL },	 /* 0xee */
+             { "STS  ",  6,  3,   D_Indexed,   NULL },        /* 0xef */
+
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf0 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf1 */
+		  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf2 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf3 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf4 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf5 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf6 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf7 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf8 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf9 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xfa */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xfb */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xfc */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xfd */
+             { "LDS  ",  7,  4,   D_Extended,  NULL },	 /* 0xfe */
+             { "STS  ",  7,  4,   D_Extended,  NULL },        /* 0xff */
+
+};
+
+
+Opcode optable11[] = {
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x00 */
+             { "?????",  0,  1, 	D_Illegal,   NULL },	 /* 0x01 */
+             { "?????",  0,  1,	D_Illegal,   NULL },	 /* 0x02 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x03 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x04 */
+             { "?????",  0,  1,	D_Illegal,   NULL },	 /* 0x05 */
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x06 */
+		  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x07 */
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x08 */
+		  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x09 */
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x0a */
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x0b */
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x0c */
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x0d */
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x0e */
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x0f */
+
+		  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x10 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x11 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x12 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x13 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x14 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x15 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x16 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x17 */
+		  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x18 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x19 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x1a */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x1b */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x1c */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x1d */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x1e */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x1f */
+		     
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x20 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x21 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x22 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x23 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x24 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x25 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x26 */
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x27 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x28 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x29 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x2a */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x2b */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x2c */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x2d */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x2e */
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x2f */
+
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x30 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x31 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x32 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x33 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x34 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x35 */
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x36 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x37 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x38 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x39 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x3a */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x3b */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x3c */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x3d */
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x3e */
+             { "SWI3 ",  20, 2,   D_Inherent,  NULL },        /* 0x3f */
+
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x40 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x41 */
+ 	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x42 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x43 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x44 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x45 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x46 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x47 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x48 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x49 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x4a */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x4b */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x4c */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x4d */
+             { "?????",  0,  1,   D_Illegal,   NULL },	 /* 0x4e */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x4f */
+
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x50 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x51 */
+ 	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x52 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x53 */
+			  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x54 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x55 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x56 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x57 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x58 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x59 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x5a */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x5b */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x5c */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x5d */
+				 { "?????",  0,  1,   D_Illegal,   NULL },	 /* 0x5e */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x5f */
+
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x60 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x61 */
+ 	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x62 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x63 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x64 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x65 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x66 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x67 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x68 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x69 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x6a */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x6b */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x6c */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x6d */
+             { "?????",  0,  1,   D_Illegal,   NULL },	 /* 0x6e */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x6f */
+
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x70 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x71 */
+ 	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x72 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x73 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x74 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x75 */
+			  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x76 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x77 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x78 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x79 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x7a */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x7b */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x7c */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x7d */
+				 { "?????",  0,  1,   D_Illegal,   NULL },	 /* 0x7e */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x7f */
+
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x80 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x81 */
+ 	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x82 */
+             { "CMPU ",  5,  4,   D_ImmediatL, NULL },        /* 0x83 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x84 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x85 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x86 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x87 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x88 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x89 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x8a */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x8b */
+             { "CMPS ",  5,  4,   D_ImmediatL, NULL },        /* 0x8c */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x8d */
+             { "?????",  0,  1,   D_Illegal,   NULL },	 /* 0x8e */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x8f */
+
+		  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x90 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x91 */
+ 	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x92 */
+             { "CMPU ",  7,  3,   D_Direct,    NULL },        /* 0x93 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x94 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x95 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x96 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x97 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x98 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x99 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x9a */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x9b */
+             { "CMPS ",  7,  3,   D_Direct,    NULL },        /* 0x9c */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x9d */
+             { "?????",  0,  1,   D_Illegal,   NULL },	 /* 0x9e */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0x9f */
+
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xa0 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xa1 */
+ 	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xa2 */
+             { "CMPU ",  7,  3,   D_Indexed,   NULL },        /* 0xa3 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xa4 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xa5 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xa6 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xa7 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xa8 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xa9 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xaa */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xab */
+             { "CMPS ",  7,  3,   D_Indexed,   NULL },        /* 0xac */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xad */
+             { "?????",  0,  1,   D_Illegal,   NULL },	 /* 0xae */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xaf */
+
+		  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xb0 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xb1 */
+		  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xb2 */
+             { "CMPU ",  8,  4,   D_Extended,  NULL },        /* 0xb3 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xb4 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xb5 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xb6 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xb7 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xb8 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xb9 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xba */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xbb */
+             { "CMPS ",  8,  4,   D_Extended,  NULL },        /* 0xbc */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xbd */
+             { "?????",  0,  1,   D_Illegal,   NULL },	 /* 0xbe */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xbf */
+
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc0 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc1 */
+ 	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc2 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc3 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc4 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc5 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc6 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc7 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc8 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xc9 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xca */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xcb */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xcc */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xcd */
+             { "?????",  0,  1,   D_Illegal,   NULL },	 /* 0xce */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xcf */
+
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd0 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd1 */
+		  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd2 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd3 */
+			  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd4 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd5 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd6 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd7 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd8 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xd9 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xda */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xdb */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xdc */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xdd */
+             { "?????",  0,  1,   D_Illegal,   NULL },	 /* 0xde */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xdf */
+
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe0 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe1 */
+ 	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe2 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe3 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe4 */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe5 */
+   	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe6 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe7 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe8 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xe9 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xea */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xeb */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xec */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xed */
+             { "?????",  0,  1,   D_Illegal,   NULL },	 /* 0xee */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xef */
+
+	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf0 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf1 */
+ 	     { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf2 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf3 */
+			  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf4 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf5 */
+			  { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf6 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf7 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf8 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xf9 */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xfa */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xfb */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xfc */
+             { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xfd */
+				 { "?????",  0,  1,   D_Illegal,   NULL },	 /* 0xfe */
+				 { "?????",  0,  1,   D_Illegal,   NULL },        /* 0xff */
+};
+
+int iotable[32] = {
+	0x0000,
+	0x0001,
+	0x0002,
+	0x0003,
+	0x0008,
+	0x0009,
+	0x000a,
+	0x000b,
+	0x000c,
+	0x000d,
+	0x000e,
+	0x0010,
+	0x0011,
+	0x0012,
+	0x0013,
+	0x0014,
+	0x8000,
+	0x8001,
+	0x8002,
+	0x8003,
+	0x8004,
+	0x8005,
+	0x8006,
+	0x8007,
+	0x8008,
+	0x8009,
+	0x800a,
+	0x800b,
+	0x800c,
+	0x800d,
+	0x800e,
+	0x800f,
+};
+
+char *iocomment[32] = {
+	"Data direction register port 1",
+	"Data direction register port 2",
+	"I/O register port 1",
+	"I/O register port 2",
+	"Timer control and status",
+	"Counter high byte",
+	"Counter low byte",
+	"Output compare high byte",
+	"Output compare low byte",
+	"Input capture high byte",
+	"Input capture low byte",
+	"Serial rate and mode register",
+	"Serial control and status register",
+	"Serial receiver data register",
+	"Serial transmit data register",
+	"Ram control register",
+	"Modem port 0",
+	"Modem port 1",
+	"Modem port 2",
+	"Modem port 3",
+	"Modem port 4",
+	"Modem port 5",
+	"Modem port 6",
+	"Modem port 7",
+	"Modem port 8",
+	"Modem port 9",
+	"Modem port 10",
+	"Modem port 11",
+	"Modem port 12",
+	"Modem port 13",
+	"Modem port 14",
+	"Modem port 15",
+};
+
+char *Inter_Register[16]={"D","X","Y","U","S","PC","??","??","A","B","CC","DP","??","??","??","??"};
+
+char *Indexed_Register[4]={"X","Y","U","S"};
+
+int  lastio = 32;
+
+#pragma argsused
+int D_Illegal(op, code, pc, suffix)
+Opcode *op;
+int code;
+int pc;
+char *suffix;
+{
+  fprintf(fp,"%0.2X          %s%s", code, suffix, op->name);
+  return op->bytes;
+}
+
+#pragma argsused
+int D_Direct(op, code, pc, suffix)
+Opcode *op;
+int code;
+int pc;
+char *suffix;
+{
+  int offset;
+
+  offset = prog[pc+1];
+  fprintf(fp,"%0.2X %0.2X       %s%s       $%0.2X",
+	code, offset, suffix, op->name, offset);
+  return op->bytes;
+}
+
+#pragma argsused
+int D_Page10(op, code, pc, suffix)
+Opcode *op;
+int code;
+int pc;
+char *suffix;
+{
+  fprintf(fp,"10 ");
+  code = prog[pc+1];
+  return (*optable10[code].display)(&optable10[code], code, pc+1, "");
+}
+
+#pragma argsused
+int D_Page11(op, code, pc, suffix)
+Opcode *op;
+int code;
+int pc;
+char *suffix;
+{
+  fprintf(fp,"11 ");
+  code = prog[pc+1];
+  return (*optable11[code].display)(&optable11[code], code, pc+1, "");
+}
+
+#pragma argsused
+int D_Immediat(op, code, pc, suffix)
+Opcode *op;
+int code;
+int pc;
+char *suffix;
+{
+  int offset;
+
+  offset = prog[pc+1];
+  fprintf(fp,"%0.2X %0.2X       %s%s       #$%0.2X",
+	code, offset, suffix, op->name, offset);
+  return op->bytes;
+}
+
+#pragma argsused
+int D_ImmediatL(op, code, pc, suffix)
+Opcode *op;
+int code;
+int pc;
+char *suffix;
+{
+  int offset;
+
+  offset = prog[pc+1] * 256 + prog[pc+2];
+  fprintf(fp,"%0.2X %0.2X %0.2X    %s%s       #$%0.4X",
+	code, prog[pc+1], prog[pc+2], suffix, op->name, offset);
+  return op->bytes;
+}
+
+#pragma argsused
+int D_Inherent(op, code, pc, suffix)
+Opcode *op;
+int code;
+int pc;
+char *suffix;
+{
+  fprintf(fp,"%0.2X          %s%s", code, suffix, op->name);
+  return op->bytes;
+}
+
+#pragma argsused
+int D_OS9(op, code, pc, suffix)
+Opcode *op;
+int code;
+int pc;
+char *suffix;
+{
+  int offset;
+
+  offset = prog[pc+2];
+
+  fprintf(fp,"%0.2X %0.2X       %s%s       $%0.2X",
+	code, offset, suffix, op->name, prog[pc+2]);
+  return op->bytes;
+}
+
+#pragma argsused
+char *IndexRegister(postbyte)
+int postbyte;
+{
+  return Indexed_Register[ (postbyte>>5) & 0x03];
+}
+
+#pragma argsused
+int D_Indexed(op, code, pc, suffix)
+Opcode *op;
+int code;
+int pc;
+char *suffix;
+{
+  int postbyte;
+  char *s;
+  int extrabytes;
+  int disp;
+  int address;
+  int offset;
+
+  extrabytes = 0;
+  postbyte = prog[pc+1];
+  if ((postbyte & 0x80) == 0x00) {
+	 disp = postbyte & 0x1f;
+	 if ((postbyte & 0x10) == 0x10) {
+		s = "-";
+		disp=0x20-disp;
+	      }
+	 else
+		s = "+";
+	 fprintf(fp,"%0.2X %0.2X       %s%s       %s$%0.2X,%s",
+			code, postbyte, suffix, op->name, s,disp,IndexRegister(postbyte));
+  } else {
+	 switch(postbyte & 0x1f) {
+	 case 0x00 :
+		fprintf(fp,"%0.2X %0.2X       %s%s       ,%s+",
+				  code, postbyte, suffix, op->name, IndexRegister(postbyte));
+		break;
+	 case 0x01 :
+		fprintf(fp,"%0.2X %0.2X       %s%s       ,%s++",
+				  code, postbyte, suffix, op->name, IndexRegister(postbyte));
+		break;
+	 case 0x02 :
+		fprintf(fp,"%0.2X %0.2X       %s%s       ,-%s",
+				  code, postbyte, suffix, op->name, IndexRegister(postbyte));
+		break;
+	 case 0x03 :
+		fprintf(fp,"%0.2X %0.2X       %s%s       ,--%s",
+				  code, postbyte, suffix, op->name, IndexRegister(postbyte));
+		break;
+	 case 0x04 :
+		fprintf(fp,"%0.2X %0.2X       %s%s       ,%s",
+				  code, postbyte, suffix, op->name, IndexRegister(postbyte));
+		break;
+	 case 0x05 :
+		fprintf(fp,"%0.2X %0.2X       %s%s       B,%s",
+				  code, postbyte, suffix, op->name, IndexRegister(postbyte));
+		break;
+	 case 0x06 :
+		fprintf(fp,"%0.2X %0.2X       %s%s       A,%s",
+				  code, postbyte, suffix, op->name, IndexRegister(postbyte));
+		break;
+	 case 0x07 :
+		break;
+	 case 0x08 :
+		offset = prog[pc+2];
+		if (offset < 128)
+		  s = "+";
+		else {
+		  s = "-";
+		  offset=0x0100-offset;
+		}
+		fprintf(fp,"%0.2X %0.2X %0.2X    %s%s       %s$%0.2X,%s",
+			code, postbyte, prog[pc+2], suffix, op->name, s, offset,
+		IndexRegister(postbyte));
+		extrabytes=1;
+		break;
+	 case 0x09 :
+		offset = prog[pc+2] * 256 + prog[pc+3];
+		if (offset < 32768)
+			s = "+";
+		else {
+		  s = "-";
+		  offset=0xffff-offset+1;
+		}
+		fprintf(fp,"%0.2X %0.2X %0.2X %0.2X %s%s       %s$%0.4X,%s",
+			code, postbyte, prog[pc+2], prog[pc+3], suffix, op->name, s, offset,
+		IndexRegister(postbyte));
+		extrabytes=2;
+		break;
+	 case 0x0a :
+		break;
+	 case 0x0b :
+		fprintf(fp,"%0.2X %0.2X       %s%s       D,%s",
+				  code, postbyte, suffix, op->name, IndexRegister(postbyte));
+		break;
+	 case 0x0c :
+		offset = (prog[pc+2]+pc+3) & 0xFFFF;
+		s = "<";
+		fprintf(fp,"%0.2X %0.2X %0.2X    %s%s       %s$%0.2X,PCR",
+				  code, postbyte, prog[pc+2], suffix, op->name, s, pc+3+offset+adoffset);
+		extrabytes = 1;
+		break;
+	 case 0x0d :
+		offset = (prog[pc+2] * 256 + prog[pc+3]+pc+4) & 0xFFFF;
+		s = ">";
+		fprintf(fp,"%0.2X %0.2X %0.2X %0.2X %s%s       %s$%0.4X,PCR",
+				  code, postbyte, prog[pc+2], prog[pc+3], suffix, op->name, s, offset+pc+4+adoffset);
+		extrabytes = 2;
+		break;
+	 case 0x0e :
+		break;
+	 case 0x0f :
+		fprintf(fp,"%0.2X %0.2X       %s?????",
+				  code, postbyte, suffix);
+		break;
+	 case 0x10 :
+		fprintf(fp,"%0.2X %0.2X       %s?????",
+				  code, postbyte, suffix);
+		break;
+	 case 0x11 :
+		fprintf(fp,"%0.2X %0.2X       %s%s       [,%s++]",
+				  code, postbyte, suffix, op->name, IndexRegister(postbyte));
+		break;
+	 case 0x12 :
+		fprintf(fp,"%0.2X %0.2X       %s?????",
+				  code, postbyte, suffix);
+		break;
+	 case 0x13 :
+		fprintf(fp,"%0.2X %0.2X       %s%s       [,--%s]",
+				  code, postbyte, suffix, op->name, IndexRegister(postbyte));
+		break;
+	 case 0x14 :
+		fprintf(fp,"%0.2X %0.2X       %s%s       [,%s]",
+				  code, postbyte, suffix, op->name, IndexRegister(postbyte));
+		break;
+	 case 0x15 :
+		fprintf(fp,"%0.2X %0.2X       %s%s       [B,%s]",
+				  code, postbyte, suffix, op->name, IndexRegister(postbyte));
+		break;
+	 case 0x16 :
+		fprintf(fp,"%0.2X %0.2X       %s%s       [A,%s]",
+				  code, postbyte, suffix, op->name, IndexRegister(postbyte));
+		break;
+	 case 0x17 :
+		break;
+	 case 0x18 :
+		offset = prog[pc+2];
+		if (offset < 128)
+		  s = "+";
+		else {
+		  s = "-";
+		  offset=0x0100-offset;
+		}
+		fprintf(fp,"%0.2X %0.2X %0.2X    %s%s       [%s$%0.2X,%s]",
+			code, postbyte, prog[pc+2], suffix, op->name, s, offset,
+		IndexRegister(postbyte));
+		break;
+	 case 0x19 :
+		offset = prog[pc+2] * 256 + prog[pc+3];
+		if (offset < 32768)
+		  s = "+";
+		else {
+		  s = "-";
+		  offset=0xffff-offset+1;
+		}
+		fprintf(fp,"%0.2X %0.2X %0.2X %0.2X %s%s       %s$%0.4X,%s",
+			code, postbyte, prog[pc+2], prog[pc+3], suffix, op->name, s, offset,
+		IndexRegister(postbyte));
+		break;
+	 case 0x1a :
+		break;
+	 case 0x1b :
+		fprintf(fp,"%0.2X %0.2X       %s%s       [D,%s]",
+				  code, postbyte, suffix, op->name, IndexRegister(postbyte));
+		break;
+	 case 0x1c :
+		offset = (prog[pc+2]+pc+3) & 0xFFFF;
+		s = "<";
+		fprintf(fp,"%0.2X %0.2X %0.2X    %s%s       [%s$%0.2X,PCR]",
+				  code, postbyte, prog[pc+2], suffix, op->name, s, offset);
+		extrabytes = 1;
+		break;
+	 case 0x1d :
+		offset = (prog[pc+2] * 256 + prog[pc+3]+pc+4) & 0xFFFF;
+		s = ">";
+		fprintf(fp,"%0.2X %0.2X %0.2X %0.2X %s%s       [%s$%0.4X,PCR]",
+				  code, postbyte, prog[pc+2], prog[pc+3], suffix, op->name, s, offset);
+		extrabytes = 2;
+		break;
+	 case 0x1e :
+		break;
+	 case 0x1f :
+		address = prog[pc+2] * 256 + prog[pc+3];
+		extrabytes = 2;
+		fprintf(fp,"%0.2X %0.2X %0.2X %0.2X %s%s       [$%4X]",
+				  code, postbyte, prog[pc+2], prog[pc+3], suffix, op->name, address);
+		break;
+	 }
+  }
+  return op->bytes + extrabytes;
+}
+
+#pragma argsused
+int D_Extended(op, code, pc, suffix)
+Opcode *op;
+int code;
+int pc;
+char *suffix;
+{
+  int offset;
+
+  offset = prog[pc+1] * 256 + prog[pc+2];
+  fprintf(fp,"%0.2X %0.2X %0.2X    %s%s       $%0.4X",
+	code, prog[pc+1], prog[pc+2], suffix, op->name, offset);
+  return op->bytes;
+}
+
+#pragma argsused
+int D_Relative(op, code, pc, suffix)
+Opcode *op;
+int code;
+int pc;
+char *suffix;
+{
+  int offset;
+  int disp;
+
+  offset = prog[pc+1];
+  if (offset < 127 )
+	 disp   = pc + 2 + offset;
+  else
+	 disp   = pc + 2 - (256 - offset);
+  fprintf(fp,"%0.2X %0.2X       %s%s       $%0.4X",
+	code, offset, suffix, op->name, disp);
+  return op->bytes;
+}
+
+#pragma argsused
+int D_RelativeL(op, code, pc, suffix)
+Opcode *op;
+int code;
+int pc;
+char *suffix;
+{
+  int offset;
+  int disp;
+
+  offset = prog[pc+1] * 256 + prog[pc+2];
+  if (offset < 32767 )
+	 disp   = pc + 3 + offset + adoffset;
+  else
+	 disp   = pc + 3 - (65536 - offset) + adoffset;
+  fprintf(fp,"%0.2X %0.2X %0.2X    %s%s       $%0.4X",
+	code, prog[pc+1], prog[pc+2], suffix, op->name, disp);
+  return op->bytes;
+}
+
+#pragma argsused
+int D_Register0(op, code, pc, suffix)
+Opcode *op;
+int code;
+int pc;
+char *suffix;
+{
+  int postbyte;
+
+  postbyte = prog[pc+1];
+
+  fprintf(fp,"%0.2X %0.2X       %s%s       %s,%s",
+	code, postbyte, suffix, op->name, Inter_Register[postbyte>>4], Inter_Register[postbyte & 0x0F]);
+
+
+  return op->bytes;
+}
+
+#pragma argsused
+int D_Register1(op, code, pc, suffix)
+Opcode *op;
+int code;
+int pc;
+char *suffix;
+{
+  int postbyte;
+  int i;
+  int flag=0;
+  static char *s_stack[8]={"PC","U","Y","X","DP","B","A","CC"};
+  static int bits[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
+
+  postbyte = prog[pc+1];	
+
+  fprintf(fp,"%0.2X %0.2X       %s%s       ", 
+  	code, postbyte, suffix, op->name);   	
+
+  for(i=0;i<8;i++) {
+    if ((postbyte & bits[i]) !=0) {
+      if (flag !=0) {
+	fprintf(fp,",");
+      } else {
+	flag=1;
+      }
+      fprintf(fp,s_stack[i]);
+    }
+  }
+  return op->bytes;
+}
+
+#pragma argsused
+int D_Register2(op, code, pc, suffix)
+Opcode *op;
+int code;
+int pc;
+char *suffix;
+{
+  int postbyte;
+  int i;
+  int flag=0;
+  static char *u_stack[8]={"PC","S","Y","X","DP","B","A","CC"};
+  static int bits[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
+
+  postbyte = prog[pc+1];	
+  fprintf(fp,"%0.2X %0.2X       %s%s       ", 
+  	code, postbyte, suffix, op->name);   	
+
+  for(i=0;i<8;i++) {
+    if ((postbyte & bits[i]) !=0) {
+      if (flag !=0) {
+	fprintf(fp,",");
+      } else {
+	flag=1;
+      }
+      fprintf(fp,u_stack[i]);
+    }
+  }
+  return op->bytes;
+}
+
+
+void hexadump(b, l, loc, w)
+unsigned char *b;
+int l;
+int loc;
+int w;
+{
+  int i;
+  int j;
+  int end;
+  // char b[4096];
+
+  // memset(b, '\0', 4096);
+  // memcpy(b, s, l);
+  //fprintf(fp,"\n");
+  end = ((l%w)>0)?(l/w)+1:(l/w);
+  for (j=0;j<end;j++) {
+    fprintf(fp,"%04X: ", loc+j*w+adoffset);
+    for (i=0;i<w;i++) {
+		fprintf(fp,"%02X ", b[j*w+i]);
+    }
+    fprintf(fp,"|");
+    for (i=0;i<w;i++) {
+      if ((b[j*w+i] >= 0x20) && (b[j*w+i] < 0x7f)) {
+	fprintf(fp,"%c", b[j*w+i]);
+      } else {
+	fprintf(fp,".");
+      }
+    }
+    fprintf(fp,"|\n");
+  }
+  //fprintf(fp,"\n");
+}
+
+char *comment(arg)
+int arg;
+{
+  int i;
+
+  for (i=0;i<lastio;i++) {
+    if (arg == iotable[i]) {
+      return iocomment[i];
+    }
+  }
+  return "";
+}
+
+void disasm(start, end)
+int start;
+int end;
+{
+  int pc;	
+  int code;
+  int currstring;
+
+  currstring = 0;
+  for (pc=start; pc <= end;) {
+    code = prog[pc];
+    fprintf(fp,"%0.4X: ", pc + adoffset);
+    if (currstring < laststring) {
+      if (pc == stringtable[currstring].address) {
+	  hexadump(&prog[pc], stringtable[currstring].length, pc,
+	           stringtable[currstring].width);
+	pc += stringtable[currstring].length;
+	currstring++;
+	continue;
+      }
+    }
+    pc += (*optable[code].display)(&optable[code], code, pc, "   ");
+    fprintf(fp,"\n");
+  }
+}
+
+#ifndef NO_MAIN
+
+int main(int argc, char **argv )
+{
+  int fd;
+  int start,end;
+  int size;
+
+  if ( argc > 2 && *argv[1] == '-') {
+     if (argv[1][1]=='o') {
+        adoffset=strtol(argv[2],(char**)0,0);
+        argc-=2;
+        argv += 2;
+     }
+  }
+  if ( argc != 4 ) {
+    fprintf(stderr, "usage: disasm [-o offset] <file> <start> <end>\n");
+    fprintf(stderr, "       where start and end are in hex.\n");
+    exit(1);
+  }
+
+  sscanf(argv[2],"%x",&start); start -= adoffset;
+  sscanf(argv[3],"%x",&end); end -= adoffset;
+
+  fp = stdout;
+
+  fd = open(argv[1], O_RDONLY, S_IREAD|S_IWRITE);
+  size = read(fd, &prog[0x0000], 0xffff);
+
+  if (end > size) end=size;
+
+  disasm(start, end);
+  close(fd);
+  return 0;
+}
+
+#endif // NO_MAIN
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9/os9mod.c	Mon Jul 02 02:12:31 2018 +0900
@@ -0,0 +1,187 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "os9.h"
+
+
+u_char *os9_string(u_char *string);
+void ident(OS9_MODULE_t *mod);
+void usage(void);
+long pos;
+
+static char *types[16] = {
+    "???", "Prog", "Subr", "Multi", "Data", "USR 5", "USR 6", "USR 7", 
+    "USR 8", "USR 9", "USR A", "USR B", "System", "File Manager",
+    "Device Driver", "Device Descriptor"
+};
+  
+static char *langs[16] = {
+  "Data", "6809 Obj", "Basic09 I-Code", "Pascal P-Code", "C I-Code",
+  "Cobol I-Code", "Fortran I-Code", "6309 Obj", "???", "???", "???",
+  "???", "???", "???", "???", "???"
+};
+
+int offset = 0;
+
+int main(int argc, char **argv)
+{
+  char *filename = NULL;
+  FILE *fp;
+  u_char buffer[65536];		/* OS9 Module can't be larger than this */
+  OS9_MODULE_t *mod = (OS9_MODULE_t *) buffer;
+  int i=0, j;
+  int flag = 0;
+
+  argv++;			/* skip my name */
+
+  if (argc == 1)
+    usage();
+
+  while ((argc >= 2) && (*argv[0] == '-')) {
+    if (*(argv[0] + 1) == 's') {
+      argc--;
+      flag = 1;
+    } else if (*(argv[0] + 1) == 'o') {
+      argc--; argc--;
+      argv++;
+      offset = strtol(argv[0],(char**)0,0);
+    } else
+      usage();
+    argv++;
+  }
+    
+
+  while (argc-- > 1) {
+    if (*argv==0) return 0;
+    filename = *(argv++);
+    
+    if ((fp = fopen(filename,"rb")) == NULL) {
+      fprintf(stderr, "Error opening file %s: %s\n",
+	      filename, strerror(errno));
+      return 1;
+    }
+    
+    while (!feof(fp)) {
+
+      if (flag) {
+          int c;
+          while( !feof(fp) && (c = fgetc(fp)) != 0x87 );
+          ungetc(c, fp);
+      }
+
+      pos = ftell(fp);
+      if (fread(buffer, OS9_HEADER_SIZE, 1, fp) != 1) {
+	if (feof(fp))
+	  break;
+	else {
+	  fprintf(stderr, "Error reading file %s: %s\n",
+		  filename, strerror(errno));
+	  return 1;
+	}
+      }
+      
+      if ((mod->id[0] != OS9_ID0) && (mod->id[1] != OS9_ID1)) {
+	fprintf(stderr,"Not OS9 module, skipping.\n");
+	return 1;
+      }
+      
+      if ((i = os9_header(mod))!=0xff) {
+	fprintf(stderr, "Bad header parity.  Expected 0xFF, got 0x%02X\n", i);
+	return 1;
+      }
+      
+      i = INT(mod->size) - OS9_HEADER_SIZE;
+      if ((j = fread(buffer + OS9_HEADER_SIZE, 1, i, fp)) != i) {
+	fprintf(stderr,"Module short.  Expected 0x%04X, got 0x%04X\n",
+		i + OS9_HEADER_SIZE, j + OS9_HEADER_SIZE);
+	return 1;
+      }
+      ident(mod);
+    }
+    fclose(fp);
+  }
+  return 0;
+    
+}
+
+void ident(OS9_MODULE_t *mod)
+{
+  int i, j;
+  u_char *name, *ptr, tmp, *buffer = (u_char *) mod;
+
+  i = INT(mod->name);
+  j = INT(mod->size);
+  name = os9_string(&buffer[i]);
+  printf("Offset : 0x%04lx\n", pos + offset);
+  printf("Header for : %s\n", name);
+  printf("Module size: $%X  #%d\n", j, j);
+  ptr = &buffer[j - 3];
+  printf("Module CRC : $%02X%02X%02X (%s)\n", ptr[0], ptr[1], ptr[2],
+	   os9_crc(mod) ? "Good" : "Bad" );
+  printf("Hdr parity : $%02X\n", mod->parity);
+
+  switch ((mod->tyla & TYPE_MASK) >> 4)
+    {
+
+    case Drivr:
+    case Prgrm:
+      i = INT(mod->data.program.exec);
+      printf("Exec. off  : $%04X  #%d\n", i, i);
+      i = INT(mod->data.program.mem);
+      printf("Data size  : $%04X  #%d\n", i, i);
+      break;
+      
+    case Devic:
+      printf("File Mgr   : %s\n",
+	     os9_string(&buffer[INT(mod->data.descriptor.fmgr)]));
+      printf("Driver     : %s\n",
+	     os9_string(&buffer[INT(mod->data.descriptor.driver)]));
+      break;
+      
+    case NULL_TYPE:
+    case TYPE_6:
+    case TYPE_7:
+    case TYPE_8:
+    case TYPE_9:
+    case TYPE_A:
+    case TYPE_B:
+    case Systm:
+      break;
+    }
+  
+
+
+
+  tmp = buffer[i + strlen((const char *)name)];
+  printf("Edition    : $%02X  #%d\n", tmp, tmp);
+  printf("Ty/La At/Rv: $%02X $%02x\n", mod->tyla, mod->atrv);
+  printf("%s mod, ", types[(mod->tyla & TYPE_MASK) >> 4]);
+  printf("%s, ", langs[mod->tyla & LANG_MASK]);
+  printf("%s, %s\n", (mod->atrv & ReEnt) ? "re-ent" : "non-share",
+	 (mod->atrv & Modprot) ? "R/W" : "R/O" );
+  printf("\n");
+}
+
+u_char *os9_string(u_char *string)
+{
+  static u_char cleaned[80];	/* strings shouldn't be longer than this */
+  u_char *ptr = cleaned;
+  int i = 0;
+
+  while (((*(ptr++) = *(string++)) < 0x7f) &&
+	 (i++ < sizeof(cleaned) - 1))
+    ;
+
+  *(ptr - 1) &= 0x7f;
+  *ptr = '\0';
+  return cleaned;
+}
+void usage(void)
+{
+  printf("Usage: os9mod [-s] [-o offset] file [ file ... ]\n");
+  printf("Performs an OS-9: 6809 'ident' on the specified files.\n");
+  printf("  -s : skip to valid module\n");
+  printf("  -o : offset \n\n");
+  exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/os9crc.c	Mon Jul 02 02:12:31 2018 +0900
@@ -0,0 +1,52 @@
+/*
+ * Generate OS9 CRC value
+ *
+ * This is a direct replacement for the Microware/Ultra-C
+ * library function crc()
+ *    by Steve Rance
+ *    https://groups.google.com/forum/#!topic/comp.os.os9/jJONahOrBX8
+ */
+
+static long crctable[256] = {
+0x000000, 0x800063, 0x8000a5, 0x0000c6, 0x800129, 0x00014a, 0x00018c, 0x8001ef,
+0x800231, 0x000252, 0x000294, 0x8002f7, 0x000318, 0x80037b, 0x8003bd, 0x0003de,
+0x800401, 0x000462, 0x0004a4, 0x8004c7, 0x000528, 0x80054b, 0x80058d, 0x0005ee,
+0x000630, 0x800653, 0x800695, 0x0006f6, 0x800719, 0x00077a, 0x0007bc, 0x8007df,
+0x800861, 0x000802, 0x0008c4, 0x8008a7, 0x000948, 0x80092b, 0x8009ed, 0x00098e,
+0x000a50, 0x800a33, 0x800af5, 0x000a96, 0x800b79, 0x000b1a, 0x000bdc, 0x800bbf,
+0x000c60, 0x800c03, 0x800cc5, 0x000ca6, 0x800d49, 0x000d2a, 0x000dec, 0x800d8f,
+0x800e51, 0x000e32, 0x000ef4, 0x800e97, 0x000f78, 0x800f1b, 0x800fdd, 0x000fbe,
+0x8010a1, 0x0010c2, 0x001004, 0x801067, 0x001188, 0x8011eb, 0x80112d, 0x00114e,
+0x001290, 0x8012f3, 0x801235, 0x001256, 0x8013b9, 0x0013da, 0x00131c, 0x80137f,
+0x0014a0, 0x8014c3, 0x801405, 0x001466, 0x801589, 0x0015ea, 0x00152c, 0x80154f,
+0x801691, 0x0016f2, 0x001634, 0x801657, 0x0017b8, 0x8017db, 0x80171d, 0x00177e,
+0x0018c0, 0x8018a3, 0x801865, 0x001806, 0x8019e9, 0x00198a, 0x00194c, 0x80192f,
+0x801af1, 0x001a92, 0x001a54, 0x801a37, 0x001bd8, 0x801bbb, 0x801b7d, 0x001b1e,
+0x801cc1, 0x001ca2, 0x001c64, 0x801c07, 0x001de8, 0x801d8b, 0x801d4d, 0x001d2e,
+0x001ef0, 0x801e93, 0x801e55, 0x001e36, 0x801fd9, 0x001fba, 0x001f7c, 0x801f1f,
+0x802121, 0x002142, 0x002184, 0x8021e7, 0x002008, 0x80206b, 0x8020ad, 0x0020ce,
+0x002310, 0x802373, 0x8023b5, 0x0023d6, 0x802239, 0x00225a, 0x00229c, 0x8022ff,
+0x002520, 0x802543, 0x802585, 0x0025e6, 0x802409, 0x00246a, 0x0024ac, 0x8024cf,
+0x802711, 0x002772, 0x0027b4, 0x8027d7, 0x002638, 0x80265b, 0x80269d, 0x0026fe,
+0x002940, 0x802923, 0x8029e5, 0x002986, 0x802869, 0x00280a, 0x0028cc, 0x8028af,
+0x802b71, 0x002b12, 0x002bd4, 0x802bb7, 0x002a58, 0x802a3b, 0x802afd, 0x002a9e,
+0x802d41, 0x002d22, 0x002de4, 0x802d87, 0x002c68, 0x802c0b, 0x802ccd, 0x002cae,
+0x002f70, 0x802f13, 0x802fd5, 0x002fb6, 0x802e59, 0x002e3a, 0x002efc, 0x802e9f,
+0x003180, 0x8031e3, 0x803125, 0x003146, 0x8030a9, 0x0030ca, 0x00300c, 0x80306f,
+0x8033b1, 0x0033d2, 0x003314, 0x803377, 0x003298, 0x8032fb, 0x80323d, 0x00325e,
+0x803581, 0x0035e2, 0x003524, 0x803547, 0x0034a8, 0x8034cb, 0x80340d, 0x00346e,
+0x0037b0, 0x8037d3, 0x803715, 0x003776, 0x803699, 0x0036fa, 0x00363c, 0x80365f,
+0x8039e1, 0x003982, 0x003944, 0x803927, 0x0038c8, 0x8038ab, 0x80386d, 0x00380e,
+0x003bd0, 0x803bb3, 0x803b75, 0x003b16, 0x803af9, 0x003a9a, 0x003a5c, 0x803a3f,
+0x003de0, 0x803d83, 0x803d45, 0x003d26, 0x803cc9, 0x003caa, 0x003c6c, 0x803c0f,
+0x803fd1, 0x003fb2, 0x003f74, 0x803f17, 0x003ef8, 0x803e9b, 0x803e5d, 0x003e3e
+};
+
+#define UPDCRC(crc,i) (crctable[((crc) >> 16 ^ (i)) & 0xff] ^ (crc) << 8)
+
+int os9crc(unsigned char c, int crcp)
+{
+ return UPDCRC(crcp, c);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/v09.c	Mon Jul 02 02:12:31 2018 +0900
@@ -0,0 +1,146 @@
+/* 6809 Simulator V09.
+
+   Copyright 1994, L.C. Benschop, Eidnhoven The Netherlands.
+   This version of the program is distributed under the terms and conditions
+   of the GNU General Public License version 2. See the file COPYING.
+   THERE IS NO WARRANTY ON THIS PROGRAM!!!
+   
+   This program simulates a 6809 processor.
+   
+   System dependencies: short must be 16 bits.
+                        char  must be 8 bits.
+                        long must be more than 16 bits.
+                        arrays up to 65536 bytes must be supported.
+                        machine must be twos complement.
+   Most Unix machines will work. For MSODS you need long pointers
+   and you may have to malloc() the mem array of 65536 bytes.
+                 
+   Define BIG_ENDIAN if you have a big-endian machine (680x0 etc)              
+   
+   Special instructions:                     
+   SWI2 writes char to stdout from register B.
+   SWI3 reads char from stdout to register B, sets carry at EOF.
+               (or when no key available when using term control).
+   SWI retains its normal function. 
+   CWAI and SYNC stop simulator.
+   
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <sys/stat.h>
+
+#define engine extern
+
+#include "v09.h"
+
+FILE *tracefile;
+
+extern FILE *fp;
+extern char *prog;
+extern void disasm(int,int);
+
+void do_trace(FILE *tracefile)
+{
+ Word pc=pcreg;
+ Byte ir;
+ // fprintf(tracefile,"pc=%04x ",pc);
+ // ir=mem[pc++];
+ // fprintf(tracefile,"i=%02x ",ir); if((ir&0xfe)==0x10) fprintf(tracefile,"%02x ",mem[pc]);else 
+ // fprintf(tracefile,"   ");
+ fprintf(tracefile,"x=%04x y=%04x u=%04x s=%04x a=%02x b=%02x cc=%02x pc=",
+                   xreg,yreg,ureg,sreg,*areg,*breg,ccreg);
+ fp = tracefile;
+ prog = (char*)mem;
+ disasm(pc,pc);
+} 
+
+char *romfile = "v09.rom";
+int romstart = 0x8000;
+
+long
+filesize(FILE *image)
+{
+    struct stat buf;
+    fstat(fileno(image),&buf);
+    return buf.st_size;
+}
+
+
+void 
+read_image()
+{
+ FILE *image;
+ if((image=fopen(romfile,"rb"))==NULL) 
+  if((image=fopen("../v09.rom","rb"))==NULL) 
+   if((image=fopen("..\\v09.rom","rb"))==NULL) {
+    perror("v09, image file");
+    exit(2);
+ }
+ long len = filesize(image);
+ fread(mem+romstart,len,1,image);
+ fclose(image);
+}
+
+void usage(void)
+{
+ fprintf(stderr,"Usage: v09 [-l romstart] [-rom rom-image] [-t tracefile [-tl addr] [-nt]"
+                "[-th addr] ]\n[-e escchar] \n");
+ exit(1); 
+}
+
+
+#define CHECKARG if(i==argc)usage();else i++;
+
+int
+main(int argc,char *argv[])
+{
+ Word loadaddr=0x100;
+ char *imagename=0;
+ int i;
+ int setterm = 1;
+ escchar='\x1d'; 
+ tracelo=0;tracehi=0xffff;
+ for(i=1;i<argc;i++) {
+    if (strcmp(argv[i],"-t")==0) {
+     i++;
+     if((tracefile=fopen(argv[i],"w"))==NULL) {
+         perror("v09, tracefile");
+         exit(2);
+     }
+     tracing=1;attention=1;    
+   } else if (strcmp(argv[i],"-rom")==0) {
+     i++;
+     romfile = argv[i];
+   } else if (strcmp(argv[i],"-tl")==0) {
+     i++;
+     tracelo=strtol(argv[i],(char**)0,0);
+   } else if (strcmp(argv[i],"-th")==0) {
+     i++;
+     tracehi=strtol(argv[i],(char**)0,0);
+   } else if (strcmp(argv[i],"-e")==0) {
+     i++;
+     escchar=strtol(argv[i],(char**)0,0);
+   } else if (strcmp(argv[i],"-l")==0) {
+     i++;
+     romstart=strtol(argv[i],(char**)0,0);
+   } else if (strcmp(argv[i],"-nt")==0) {
+     attention = escape = 1;
+     timer = 0;
+   } else usage();
+ }   
+ #ifdef MSDOS
+ if((mem=farmalloc(65535))==0) { 
+   fprintf(stderr,"Not enough memory\n");
+   exit(2);
+ } 
+ #endif
+ read_image(); 
+ if (setterm) set_term(escchar);
+ pcreg=(mem[0xfffe]<<8)+mem[0xffff]; 
+ interpr();
+ return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/v09.h	Mon Jul 02 02:12:31 2018 +0900
@@ -0,0 +1,44 @@
+/* v09.h
+   This file is part of the 6809 simulator v09
+
+   created 1994 by L.C. Benschop.
+   copyleft (c) 1994-2014 by the sbc09 team, see AUTHORS for more details.
+   license: GNU General Public License version 2, see LICENSE for more details.
+
+*/
+
+typedef unsigned char Byte;
+typedef unsigned short Word;
+
+/* 6809 registers */
+engine Byte ccreg,dpreg;
+engine Word xreg,yreg,ureg,sreg,ureg,pcreg;
+
+engine Byte d_reg[2];
+extern Word *dreg;
+extern Byte *breg,*areg;
+
+/* 6809 memory space */
+#ifdef MSDOS
+ engine Byte * mem;
+#else
+ engine Byte mem[65536];
+#endif
+
+engine volatile int tracing,attention,escape,irq;
+engine Word tracehi,tracelo;
+engine char escchar;
+engine int timer;
+engine FILE *tracefile;
+
+#define IOPAGE 0xe000
+
+void interpr(void);
+void do_exit(void);
+int do_input(int);
+void set_term(char);
+void do_trace(FILE *);
+void do_output(int,int);
+void do_escape(void);
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/v09s.c	Mon Jul 02 02:12:31 2018 +0900
@@ -0,0 +1,1683 @@
+/* 6809 Simulator V09,
+
+   created 1994 by L.C. Benschop.
+   copyleft (c) 1994-2014 by the sbc09 team, see AUTHORS for more details.
+   license: GNU General Public License version 2, see LICENSE for more details.
+
+   This program simulates a 6809 processor.
+
+   System dependencies: short must be 16 bits.
+                        char  must be 8 bits.
+                        long must be more than 16 bits.
+                        arrays up to 65536 bytes must be supported.
+                        machine must be twos complement.
+   Most Unix machines will work. For MSODS you need long pointers
+   and you may have to malloc() the mem array of 65536 bytes.
+
+   Define CPU_BIG_ENDIAN with != 0 if you have a big-endian machine (680x0 etc)
+   Usually UNIX systems get this automatically from BIG_ENDIAN and BYTE_ORDER
+   definitions ...
+
+   Define TRACE if you want an instruction trace on stderr.
+   Define TERM_CONTROL if you want nonblocking non-echoing key input.
+   * THIS IS DIRTY !!! *
+
+   Special instructions:
+   SWI2 writes char to stdout from register B.
+   SWI3 reads char from stdout to register B, sets carry at EOF.
+               (or when no key available when using term control).
+   SWI retains its normal function.
+   CWAI and SYNC stop simulator.
+
+   The program reads a binary image file at $100 and runs it from there.
+   The file name must be given on the command line.
+
+   Revisions:
+        2012-06-05 johann AT klasek at
+                Fixed: com with C "NOT" operator ... 0^(value) did not work!
+        2012-06-06
+                Fixed: changes from 1994 release (flag handling)
+                        reestablished.
+        2012-07-15 JK
+                New: option parsing, new option -d (dump memory on exit)
+        2013-10-07 JK
+                New: print ccreg with flag name in lower/upper case depending on flag state.
+        2013-10-20 JK
+                New: Show instruction disassembling in trace mode.
+        2014-07-01 JK
+                Fixed: disassembling output: cmpd
+        2014-07-11 JK
+                Fixed: undocumented tfr/exg register combinations.
+                        http://www.6809.org.uk/dragon/illegal-opcodes.shtml
+        2016-10-06 JK
+                Fixed: wrong cmpu cycles
+*/
+
+#include <stdio.h>
+#ifdef TERM_CONTROL
+#include <fcntl.h>
+int tflags;
+#endif
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <string.h>
+#include <ctype.h>
+
+void finish();
+
+static int fdump=0;
+
+
+/* Default: no big endian ... */
+#ifndef CPU_BIG_ENDIAN
+/* check if environment provides some information about this ... */
+# if defined(BIG_ENDIAN) && defined(BYTE_ORDER)
+#  if BIG_ENDIAN == BYTE_ORDER
+#   define CPU_BIG_ENDIAN 1
+#  else
+#   define CPU_BIG_ENDIAN 0
+#  endif
+# endif
+#endif
+
+
+typedef unsigned char Byte;
+typedef unsigned short Word;
+
+/* 6809 registers */
+Byte ccreg,dpreg;
+Word xreg,yreg,ureg,sreg,ureg,pcreg;
+
+Byte fillreg = 0xff;
+Word wfillreg = 0xffff;
+
+Word pcreg_prev;
+
+Byte d_reg[2];
+Word *dreg=(Word *)d_reg;
+
+
+/* This is a dirty aliasing trick, but fast! */
+#if CPU_BIG_ENDIAN
+ Byte *areg=d_reg;
+ Byte *breg=d_reg+1;
+#else
+ Byte *breg=d_reg;
+ Byte *areg=d_reg+1;
+#endif
+
+
+/* 6809 memory space */
+static Byte mem[65536];
+
+#define GETWORD(a) (mem[a]<<8|mem[(a)+1])
+#define SETWORD(a,n) {mem[a]=(n)>>8;mem[(a)+1]=n;}
+/* Two bytes of a word are fetched separately because of
+   the possible wrap-around at address $ffff and alignment
+*/
+
+
+int iflag; /* flag to indicate prebyte $10 or $11 */
+Byte ireg; /* Instruction register */
+
+#define IMMBYTE(b) b=mem[pcreg++];
+#define IMMWORD(w) {w=GETWORD(pcreg);pcreg+=2;}
+
+/* sreg */
+#define PUSHBYTE(b) mem[--sreg]=b;
+#define PUSHWORD(w) {sreg-=2;SETWORD(sreg,w)}
+#define PULLBYTE(b) b=mem[sreg++];
+#define PULLWORD(w) {w=GETWORD(sreg);sreg+=2;}
+
+/* ureg */
+#define PUSHUBYTE(b) mem[--ureg]=b;
+#define PUSHUWORD(w) {ureg-=2;SETWORD(ureg,w)}
+#define PULLUBYTE(b) b=mem[ureg++];
+#define PULLUWORD(w) {w=GETWORD(ureg);ureg+=2;}
+
+#define SIGNED(b) ((Word)(b&0x80?b|0xff00:b))
+
+Word *ixregs[]={&xreg,&yreg,&ureg,&sreg};
+
+static int idx;
+
+/* disassembled instruction buffer */
+static char dinst[6];
+
+/* disassembled operand buffer */
+static char dops[32];
+
+/* disassembled instruction len (optional, on demand) */
+static int da_len;
+
+/* instruction cycles */
+static int cycles;
+unsigned long cycles_sum;
+
+void da_inst(char *inst, char *reg, int cyclecount) {
+        *dinst = 0;
+        *dops = 0;
+        if (inst != NULL) strcat(dinst, inst);
+        if (reg != NULL) strcat(dinst, reg);
+        cycles += cyclecount;
+}
+
+void da_inst_cat(char *inst, int cyclecount) {
+        if (inst != NULL) strcat(dinst, inst);
+        cycles += cyclecount;
+}
+
+void da_ops(char *part1, char* part2, int cyclecount) {
+        if (part1 != NULL) strcat(dops, part1);
+        if (part2 != NULL) strcat(dops, part2);
+        cycles += cyclecount;
+}
+
+void da_reg(Byte b)
+{
+  char *reg[] = { "d", "x", "y", "u", "s", "pc", "?", "?",
+                  "a", "b", "cc", "dp", "?", "?", "?", "?" };
+  da_ops( reg[(b>>4) & 0xf], ",", 0);
+  da_ops( reg[b & 0xf], NULL, 0);
+}
+
+/* Now follow the posbyte addressing modes. */
+
+Word illaddr() /* illegal addressing mode, defaults to zero */
+{
+ return 0;
+}
+
+static char *dixreg[] = { "x", "y", "u", "s" };
+
+Word ainc()
+{
+ da_ops(",",dixreg[idx],2);
+ da_ops("+",NULL,0);
+ return (*ixregs[idx])++;
+}
+
+Word ainc2()
+{
+ Word temp;
+ da_ops(",",dixreg[idx],3);
+ da_ops("++",NULL,0);
+ temp=(*ixregs[idx]);
+ (*ixregs[idx])+=2;
+ return(temp);
+}
+
+Word adec()
+{
+ da_ops(",-",dixreg[idx],2);
+ return --(*ixregs[idx]);
+}
+
+Word adec2()
+{
+ Word temp;
+ da_ops(",--",dixreg[idx],3);
+ (*ixregs[idx])-=2;
+ temp=(*ixregs[idx]);
+ return(temp);
+}
+
+Word plus0()
+{
+ da_ops(",",dixreg[idx],0);
+ return(*ixregs[idx]);
+}
+
+Word plusa()
+{
+ da_ops("a,",dixreg[idx],1);
+ return(*ixregs[idx])+SIGNED(*areg);
+}
+
+Word plusb()
+{
+ da_ops("b,",dixreg[idx],1);
+ return(*ixregs[idx])+SIGNED(*breg);
+}
+
+Word plusn()
+{
+ Byte b;
+ char off[6];
+ IMMBYTE(b)
+ /* negative offsets alway decimal, otherwise hex */
+ if (b & 0x80) sprintf(off,"%d,", -(b ^ 0xff)-1);
+ else sprintf(off,"$%02x,",b);
+ da_ops(off,dixreg[idx],1);
+ return(*ixregs[idx])+SIGNED(b);
+}
+
+Word plusnn()
+{
+ Word w;
+ IMMWORD(w)
+ char off[6];
+ sprintf(off,"$%04x,",w);
+ da_ops(off,dixreg[idx],4);
+ return(*ixregs[idx])+w;
+}
+
+Word plusd()
+{
+ da_ops("d,",dixreg[idx],4);
+ return(*ixregs[idx])+*dreg;
+}
+
+
+Word npcr()
+{
+ Byte b;
+ char off[11];
+
+ IMMBYTE(b)
+ sprintf(off,"$%04x,pcr",(pcreg+SIGNED(b))&0xffff);
+ da_ops(off,NULL,1);
+ return pcreg+SIGNED(b);
+}
+
+Word nnpcr()
+{
+ Word w;
+ char off[11];
+
+ IMMWORD(w)
+ sprintf(off,"$%04x,pcr",(pcreg+w)&0xffff);
+ da_ops(off,NULL,5);
+ return pcreg+w;
+}
+
+Word direct()
+{
+ Word(w);
+ char off[6];
+
+ IMMWORD(w)
+ sprintf(off,"$%04x",w);
+ da_ops(off,NULL,3);
+ return w;
+}
+
+Word zeropage()
+{
+ Byte b;
+ char off[6];
+
+ IMMBYTE(b)
+ sprintf(off,"$%02x", b);
+ da_ops(off,NULL,2);
+ return dpreg<<8|b;
+}
+
+
+Word immediate()
+{
+ char off[6];
+
+ sprintf(off,"#$%02x", mem[pcreg]);
+ da_ops(off,NULL,0);
+ return pcreg++;
+}
+
+Word immediate2()
+{
+ Word temp;
+ char off[7];
+
+ temp=pcreg;
+ sprintf(off,"#$%04x", (mem[pcreg]<<8)+mem[(pcreg+1)&0xffff]);
+ da_ops(off,NULL,0);
+ pcreg+=2;
+ return temp;
+}
+
+Word (*pbtable[])()={ ainc, ainc2, adec, adec2,
+                      plus0, plusb, plusa, illaddr,
+                      plusn, plusnn, illaddr, plusd,
+                      npcr, nnpcr, illaddr, direct, };
+
+Word postbyte()
+{
+ Byte pb;
+ Word temp;
+ char off[6];
+
+ IMMBYTE(pb)
+ idx=((pb & 0x60) >> 5);
+ if(pb & 0x80) {
+  if( pb & 0x10)
+        da_ops("[",NULL,3);
+  temp=(*pbtable[pb & 0x0f])();
+  if( pb & 0x10) {
+        temp=GETWORD(temp);
+        da_ops("]",NULL,0);
+  }
+  return temp;
+ } else {
+  temp=pb & 0x1f;
+  if(temp & 0x10) temp|=0xfff0; /* sign extend */
+  sprintf(off,"%d,",(temp & 0x10) ? -(temp ^ 0xffff)-1 : temp);
+  da_ops(off,dixreg[idx],1);
+  return (*ixregs[idx])+temp;
+ }
+}
+
+Byte * eaddr0() /* effective address for NEG..JMP as byte pointer */
+{
+ switch( (ireg & 0x70) >> 4)
+ {
+  case 0: return mem+zeropage();
+  default:
+  case 1:case 2:case 3: return 0; /*canthappen*/
+
+  case 4: da_inst_cat("a",-2); return areg;
+  case 5: da_inst_cat("b",-2); return breg;
+  case 6: da_inst_cat(NULL,2); return mem+postbyte();
+  case 7: return mem+direct();
+ }
+ 
+}
+
+Word eaddr8()  /* effective address for 8-bits ops. */
+{
+ switch( (ireg & 0x30) >> 4)
+ {
+  default:
+  case 0: return immediate();
+  case 1: return zeropage();
+  case 2: da_inst_cat(NULL,2); return postbyte();
+  case 3: return direct();
+ }
+}
+
+Word eaddr16() /* effective address for 16-bits ops. */
+{
+ switch( (ireg & 0x30) >> 4)
+ {
+  default:
+  case 0: da_inst_cat(NULL,-1); return immediate2();
+  case 1: da_inst_cat(NULL,-1); return zeropage();
+  case 2: da_inst_cat(NULL,1); return postbyte();
+  case 3: da_inst_cat(NULL,-1); return direct();
+ }
+}
+
+void
+ill() /* illegal opcode==noop */
+{
+}
+
+/* macros to set status flags */
+#define SEC ccreg|=0x01;
+#define CLC ccreg&=0xfe;
+#define SEZ ccreg|=0x04;
+#define CLZ ccreg&=0xfb;
+#define SEN ccreg|=0x08;
+#define CLN ccreg&=0xf7;
+#define SEV ccreg|=0x02;
+#define CLV ccreg&=0xfd;
+#define SEH ccreg|=0x20;
+#define CLH ccreg&=0xdf;
+
+/* set N and Z flags depending on 8 or 16 bit result */
+#define SETNZ8(b) {if(b)CLZ else SEZ if(b&0x80)SEN else CLN}
+#define SETNZ16(b) {if(b)CLZ else SEZ if(b&0x8000)SEN else CLN}
+
+#define SETSTATUS(a,b,res) if((a^b^res)&0x10) SEH else CLH \
+                           if((a^b^res^(res>>1))&0x80)SEV else CLV \
+                           if(res&0x100)SEC else CLC SETNZ8((Byte)res)
+
+void
+add()
+{
+ Word aop,bop,res;
+ Byte* aaop;
+ da_inst("add",(ireg&0x40)?"b":"a",2);
+ aaop=(ireg&0x40)?breg:areg;
+ aop=*aaop;
+ bop=mem[eaddr8()];
+ res=aop+bop;
+ SETSTATUS(aop,bop,res)
+ *aaop=res;
+}
+
+void
+sbc()
+{
+ Word aop,bop,res;
+ Byte* aaop;
+ da_inst("sbc",(ireg&0x40)?"b":"a",2);
+ aaop=(ireg&0x40)?breg:areg;
+ aop=*aaop;
+ bop=mem[eaddr8()];
+ res=aop-bop-(ccreg&0x01);
+ SETSTATUS(aop,bop,res)
+ *aaop=res;
+}
+
+void
+sub()
+{
+ Word aop,bop,res;
+ Byte* aaop;
+ da_inst("sub",(ireg&0x40)?"b":"a",2);
+ aaop=(ireg&0x40)?breg:areg;
+ aop=*aaop;
+ bop=mem[eaddr8()];
+ res=aop-bop;
+ SETSTATUS(aop,bop,res)
+ *aaop=res;
+}
+
+void
+adc()
+{
+ Word aop,bop,res;
+ Byte* aaop;
+ da_inst("adc",(ireg&0x40)?"b":"a",2);
+ aaop=(ireg&0x40)?breg:areg;
+ aop=*aaop;
+ bop=mem[eaddr8()];
+ res=aop+bop+(ccreg&0x01);
+ SETSTATUS(aop,bop,res)
+ *aaop=res;
+}
+
+void
+cmp()
+{
+ Word aop,bop,res;
+ Byte* aaop;
+ da_inst("cmp",(ireg&0x40)?"b":"a",2);
+ aaop=(ireg&0x40)?breg:areg;
+ aop=*aaop;
+ bop=mem[eaddr8()];
+ res=aop-bop;
+ SETSTATUS(aop,bop,res)
+}
+
+void
+and()
+{
+ Byte aop,bop,res;
+ Byte* aaop;
+ da_inst("and",(ireg&0x40)?"b":"a",2);
+ aaop=(ireg&0x40)?breg:areg;
+ aop=*aaop;
+ bop=mem[eaddr8()];
+ res=aop&bop;
+ SETNZ8(res)
+ CLV
+ *aaop=res;
+}
+
+void
+or()
+{
+ Byte aop,bop,res;
+ Byte* aaop;
+ da_inst("or",(ireg&0x40)?"b":"a",2);
+ aaop=(ireg&0x40)?breg:areg;
+ aop=*aaop;
+ bop=mem[eaddr8()];
+ res=aop|bop;
+ SETNZ8(res)
+ CLV
+ *aaop=res;
+}
+
+void
+eor()
+{
+ Byte aop,bop,res;
+ Byte* aaop;
+ da_inst("eor",(ireg&0x40)?"b":"a",2);
+ aaop=(ireg&0x40)?breg:areg;
+ aop=*aaop;
+ bop=mem[eaddr8()];
+ res=aop^bop;
+ SETNZ8(res)
+ CLV
+ *aaop=res;
+}
+
+void
+bit()
+{
+ Byte aop,bop,res;
+ Byte* aaop;
+ da_inst("bit",(ireg&0x40)?"b":"a",2);
+ aaop=(ireg&0x40)?breg:areg;
+ aop=*aaop;
+ bop=mem[eaddr8()];
+ res=aop&bop;
+ SETNZ8(res)
+ CLV
+}
+
+void
+ld()
+{
+ Byte res;
+ Byte* aaop;
+ da_inst("ld",(ireg&0x40)?"b":"a",2);
+ aaop=(ireg&0x40)?breg:areg;
+ res=mem[eaddr8()];
+ SETNZ8(res)
+ CLV
+ *aaop=res;
+}
+
+void
+st()
+{
+ Byte res;
+ Byte* aaop;
+ da_inst("st",(ireg&0x40)?"b":"a",2);
+ aaop=(ireg&0x40)?breg:areg;
+ res=*aaop;
+ mem[eaddr8()]=res;
+ SETNZ8(res)
+ CLV
+}
+
+void
+jsr()
+{
+ Word w;
+
+ da_inst("jsr",NULL,5);
+ da_len=-pcreg;
+ w=eaddr8();
+ da_len += pcreg +1;
+ PUSHWORD(pcreg)
+ pcreg=w;
+}
+
+void
+bsr()
+{
+ Byte b;
+ char off[6];
+ 
+ IMMBYTE(b)
+ da_inst("bsr",NULL,7);
+ da_len = 2;
+ PUSHWORD(pcreg)
+ pcreg+=SIGNED(b);
+ sprintf(off,"$%04x", pcreg&0xffff);
+ da_ops(off,NULL,0);
+}
+
+void
+neg()
+{
+ Byte *ea;
+ Word a,r;
+
+ a=0;
+ da_inst("neg",NULL,4);
+ ea=eaddr0();
+ a=*ea;
+ r=-a;
+ SETSTATUS(0,a,r)
+ *ea=r;
+}
+
+void
+com()
+{
+ Byte *ea;
+ Byte r;
+
+ da_inst("com",NULL,4);
+ ea=eaddr0();
+/*
+ fprintf(stderr,"DEBUG: com before r=%02X *ea=%02X\n", r, *ea);
+*/
+ r= ~*ea;
+/*
+ fprintf(stderr,"DEBUG: com after r=%02X *ea=%02X\n", r, *ea);
+*/
+ SETNZ8(r)
+ SEC CLV
+ *ea=r;
+}
+
+void
+lsr()
+{
+ Byte *ea;
+ Byte r;
+
+ da_inst("lsr",NULL,4);
+ ea=eaddr0();
+ r=*ea;
+ if(r&0x01)SEC else CLC
+ if(r&0x10)SEH else CLH
+ r>>=1;
+ SETNZ8(r)
+ *ea=r;
+}
+
+void
+ror()
+{
+ Byte *ea;
+ Byte r,c;
+
+ c=(ccreg&0x01)<<7;
+ da_inst("ror",NULL,4);
+ ea=eaddr0();
+ r=*ea;
+ if(r&0x01)SEC else CLC
+ r=(r>>1)+c;
+ SETNZ8(r)
+ *ea=r;
+}
+
+void
+asr()
+{
+ Byte *ea;
+ Byte r;
+
+ da_inst("asr",NULL,4);
+ ea=eaddr0();
+ r=*ea;
+ if(r&0x01)SEC else CLC
+ if(r&0x10)SEH else CLH
+ r>>=1;
+ if(r&0x40)r|=0x80;
+ SETNZ8(r)
+ *ea=r;
+}
+
+void
+asl()
+{
+ Byte *ea;
+ Word a,r;
+
+ da_inst("asl",NULL,4);
+ ea=eaddr0();
+ a=*ea;
+ r=a<<1;
+ SETSTATUS(a,a,r)
+ *ea=r;
+}
+
+void
+rol()
+{
+ Byte *ea;
+ Byte r,c;
+
+ c=(ccreg&0x01);
+ da_inst("rol",NULL,4);
+ ea=eaddr0();
+ r=*ea;
+ if(r&0x80)SEC else CLC
+ if((r&0x80)^((r<<1)&0x80))SEV else CLV
+ r=(r<<1)+c;
+ SETNZ8(r)
+ *ea=r;
+}
+
+void
+inc()
+{
+ Byte *ea;
+ Byte r;
+
+ da_inst("inc",NULL,4);
+ ea=eaddr0();
+ r=*ea;
+ r++;
+ if(r==0x80)SEV else CLV
+ SETNZ8(r)
+ *ea=r;
+}
+
+void
+dec()
+{
+ Byte *ea;
+ Byte r;
+
+ da_inst("dec",NULL,4);
+ ea=eaddr0();
+ r=*ea;
+ r--;
+ if(r==0x7f)SEV else CLV
+ SETNZ8(r)
+ *ea=r;
+}
+
+void
+tst()
+{
+ Byte r;
+ Byte *ea;
+
+ da_inst("tst",NULL,4);
+ ea=eaddr0();
+ r=*ea;
+ SETNZ8(r)
+ CLV
+}
+
+void
+jmp()
+{
+ Byte *ea;
+
+ da_len = -pcreg;
+ da_inst("jmp",NULL,1);
+ ea=eaddr0();
+ da_len += pcreg + 1;
+ pcreg=ea-mem;
+}
+
+void
+clr()
+{
+ Byte *ea;
+
+ da_inst("clr",NULL,4);
+ ea=eaddr0();
+ *ea=0;CLN CLV SEZ CLC
+}
+
+extern void (*instrtable[])();
+
+void
+flag0()
+{
+ if(iflag) /* in case flag already set by previous flag instr don't recurse */
+ {
+  pcreg--;
+  return;
+ }
+ iflag=1;
+ ireg=mem[pcreg++];
+ da_inst(NULL,NULL,1);
+ (*instrtable[ireg])();
+ iflag=0;
+}
+
+void
+flag1()
+{
+ if(iflag) /* in case flag already set by previous flag instr don't recurse */
+ {
+  pcreg--;
+  return;
+ }
+ iflag=2;
+ ireg=mem[pcreg++];
+ da_inst(NULL,NULL,1);
+ (*instrtable[ireg])();
+ iflag=0;
+}
+
+void
+nop()
+{
+ da_inst("nop",NULL,2);
+}
+
+void
+sync_inst()
+{
+ finish();
+}
+
+void
+cwai()
+{
+ sync_inst();
+}
+
+void
+lbra()
+{
+ Word w;
+ char off[6];
+
+ IMMWORD(w)
+ pcreg+=w;
+ da_len = 3;
+ da_inst("lbra",NULL,5);
+ sprintf(off,"$%04x", pcreg&0xffff);
+ da_ops(off,NULL,0);
+}
+
+void
+lbsr()
+{
+ Word w;
+ char off[6];
+
+ da_len = 3;
+ da_inst("lbsr",NULL,9);
+ IMMWORD(w)
+ PUSHWORD(pcreg)
+ pcreg+=w;
+ sprintf(off,"$%04x", pcreg&0xffff);
+ da_ops(off,NULL,0);
+}
+
+void
+daa()
+{
+ Word a;
+ da_inst("daa",NULL,2);
+ a=*areg;
+ if(ccreg&0x20)a+=6;
+ if((a&0x0f)>9)a+=6;
+ if(ccreg&0x01)a+=0x60;
+ if((a&0xf0)>0x90)a+=0x60;
+ if(a&0x100)SEC
+ *areg=a;
+}
+
+void
+orcc()
+{
+ Byte b;
+ char off[7];
+ IMMBYTE(b)
+ sprintf(off,"#$%02x", b);
+ da_inst("orcc",NULL,3);
+ da_ops(off,NULL,0);
+ ccreg|=b;
+}
+
+void
+andcc()
+{
+ Byte b;
+ char off[6];
+ IMMBYTE(b)
+ sprintf(off,"#$%02x", b);
+ da_inst("andcc",NULL,3);
+ da_ops(off,NULL,0);
+
+ ccreg&=b;
+}
+
+void
+mul()
+{
+ Word w;
+ w=*areg * *breg;
+ da_inst("mul",NULL,11);
+ if(w)CLZ else SEZ
+ if(w&0x80) SEC else CLC
+ *dreg=w;
+}
+
+void
+sex()
+{
+ Word w;
+ da_inst("sex",NULL,2);
+ w=SIGNED(*breg);
+ SETNZ16(w)
+ *dreg=w;
+}
+
+void
+abx()
+{
+ da_inst("abx",NULL,3);
+ xreg += *breg;
+}
+
+void
+rts()
+{
+ da_inst("rts",NULL,5);
+ da_len = 1;
+ PULLWORD(pcreg)
+}
+
+void
+rti()
+{
+ Byte x;
+ x=ccreg&0x80;
+ da_inst("rti",NULL,(x?15:6));
+ da_len = 1;
+ PULLBYTE(ccreg)
+ if(x)
+ {
+  PULLBYTE(*areg)
+  PULLBYTE(*breg)
+  PULLBYTE(dpreg)
+  PULLWORD(xreg)
+  PULLWORD(yreg)
+  PULLWORD(ureg)
+ }
+ PULLWORD(pcreg)
+}
+
+void
+swi()
+{
+ int w;
+ da_inst("swi",(iflag==1)?"2":(iflag==2)?"3":"",5);
+ switch(iflag)
+ {
+  case 0:
+   PUSHWORD(pcreg)
+   PUSHWORD(ureg)
+   PUSHWORD(yreg)
+   PUSHWORD(xreg)
+   PUSHBYTE(dpreg)
+   PUSHBYTE(*breg)
+   PUSHBYTE(*areg)
+   PUSHBYTE(ccreg)
+   ccreg|=0xd0;
+   pcreg=GETWORD(0xfffa);
+   break;
+  case 1:
+   putchar(*breg);
+   fflush(stdout);
+   break;
+  case 2:
+   w=getchar();
+   if(w==EOF)SEC else CLC
+   *breg=w;
+ }
+}
+
+
+Word *wordregs[]={(Word*)d_reg,&xreg,&yreg,&ureg,&sreg,&pcreg,&wfillreg,&wfillreg};
+
+#if CPU_BIG_ENDIAN
+Byte *byteregs[]={d_reg,d_reg+1,&ccreg,&dpreg,&fillreg,&fillreg,&fillreg,&fillreg};
+#else
+Byte *byteregs[]={d_reg+1,d_reg,&ccreg,&dpreg,&fillreg,&fillreg,&fillreg,&fillreg};
+#endif
+
+void
+tfr()
+{
+ Byte b;
+ da_inst("tfr",NULL,7);
+ IMMBYTE(b)
+ da_reg(b);
+ Word v;
+ // source in higher nibble (highest bit set means 8 bit reg.)
+ if(b&0x80) {
+  v=*byteregs[(b&0x70)>>4] | (b&0x08 ? 0 : 0xff00);
+ } else {
+  v=*wordregs[(b&0x70)>>4];
+ }
+ // dest in lower nibble (highest bit set means 8 bit reg.)
+ if(b&0x8) {
+  *byteregs[b&0x07]=v&0xff;
+  fillreg=0xff;  // keep fillvalue
+ } else {
+  *wordregs[b&0x07]=v;
+  wfillreg = 0xffff;  // keep fillvalue
+ }
+}
+
+void
+exg()
+{
+ Byte b;
+ Word f;
+ Word t;
+ da_inst("exg",NULL,8);
+ IMMBYTE(b)
+ da_reg(b);
+ if(b&0x80) {
+  f=*byteregs[(b&0x70)>>4] | 0xff00;
+ } else {
+  f=*wordregs[(b>>4)&0x07];
+ }
+ if(b&0x8) {
+  t=*byteregs[b&0x07] | 0xff00;
+ } else {
+  t=*wordregs[b&0x07];
+ }
+ if(b&0x80) {
+  *byteregs[(b&0x70)>>4] = t;
+  fillreg=0xff;  // keep fillvalue
+ } else {
+  *wordregs[(b>>4)&0x07] = t;
+  wfillreg = 0xffff;  // keep fillvalue
+ }
+ if(b&0x8) {
+  *byteregs[b&0x07] = f;
+  fillreg=0xff;  // keep fillvalue
+ } else {
+  *wordregs[b&0x07] = f;
+  wfillreg = 0xffff;  // keep fillvalue
+ }
+}
+
+void
+br(int f)
+{
+ Byte b;
+ Word w;
+ char off[7];
+ Word dest;
+
+ if(!iflag) {
+  IMMBYTE(b)
+  dest = pcreg+SIGNED(b);
+  if(f) pcreg+=SIGNED(b);
+  da_len = 2;
+ } else {
+  IMMWORD(w)
+  dest = pcreg+w;
+  if(f) pcreg+=w;
+  da_len = 3;
+ }
+ sprintf(off,"$%04x", dest&0xffff);
+ da_ops(off,NULL,0);
+}
+
+#define NXORV  ((ccreg&0x08)^(ccreg&0x02))
+
+void
+bra()
+{
+ da_inst(iflag?"l":"","bra",iflag?5:3);
+ br(1);
+}
+
+void
+brn()
+{
+ da_inst(iflag?"l":"","brn",iflag?5:3);
+ br(0);
+}
+
+void
+bhi()
+{
+ da_inst(iflag?"l":"","bhi",iflag?5:3);
+ br(!(ccreg&0x05));
+}
+
+void
+bls()
+{
+ da_inst(iflag?"l":"","bls",iflag?5:3);
+ br(ccreg&0x05);
+}
+
+void
+bcc()
+{
+ da_inst(iflag?"l":"","bcc",iflag?5:3);
+ br(!(ccreg&0x01));
+}
+
+void
+bcs()
+{
+ da_inst(iflag?"l":"","bcs",iflag?5:3);
+ br(ccreg&0x01);
+}
+
+void
+bne()
+{
+ da_inst(iflag?"l":"","bne",iflag?5:3);
+ br(!(ccreg&0x04));
+}
+
+void
+beq()
+{
+ da_inst(iflag?"l":"","beq",iflag?5:3);
+ br(ccreg&0x04);
+}
+
+void
+bvc()
+{
+ da_inst(iflag?"l":"","bvc",iflag?5:3);
+ br(!(ccreg&0x02));
+}
+
+void
+bvs()
+{
+ da_inst(iflag?"l":"","bvs",iflag?5:3);
+ br(ccreg&0x02);
+}
+
+void
+bpl()
+{
+ da_inst(iflag?"l":"","bpl",iflag?5:3);
+ br(!(ccreg&0x08));
+}
+
+void
+bmi()
+{
+ da_inst(iflag?"l":"","bmi",iflag?5:3);
+ br(ccreg&0x08);
+}
+
+void
+bge()
+{
+ da_inst(iflag?"l":"","bge",iflag?5:3);
+ br(!NXORV);
+}
+
+void
+blt()
+{
+ da_inst(iflag?"l":"","blt",iflag?5:3);
+ br(NXORV);
+}
+
+void
+bgt()
+{
+ da_inst(iflag?"l":"","bgt",iflag?5:3);
+ br(!(NXORV||ccreg&0x04));
+}
+
+void
+ble()
+{
+ da_inst(iflag?"l":"","ble",iflag?5:3);
+ br(NXORV||ccreg&0x04);
+}
+
+void
+leax()
+{
+ Word w;
+ da_inst("leax",NULL,4);
+ w=postbyte();
+ if(w) CLZ else SEZ
+ xreg=w;
+}
+
+void
+leay()
+{
+ Word w;
+ da_inst("leay",NULL,4);
+ w=postbyte();
+ if(w) CLZ else SEZ
+ yreg=w;
+}
+
+void
+leau()
+{
+ da_inst("leau",NULL,4);
+ ureg=postbyte();
+}
+
+void
+leas()
+{
+ da_inst("leas",NULL,4);
+ sreg=postbyte();
+}
+
+
+int bit_count(Byte b)
+{
+  Byte mask=0x80;
+  int count=0;
+  int i;
+  char *reg[] = { "pc", "u", "y", "x", "dp", "b", "a", "cc" };
+
+  for(i=0; i<=7; i++) {
+        if (b & mask) {
+                count++;
+                da_ops(count > 1 ? ",":"", reg[i],1+(i<4?1:0));
+        }
+        mask >>= 1;
+  }
+  return count;
+}
+
+
+void
+pshs()
+{
+ Byte b;
+ IMMBYTE(b)
+ da_inst("pshs",NULL,5);
+ bit_count(b);
+ if(b&0x80)PUSHWORD(pcreg)
+ if(b&0x40)PUSHWORD(ureg)
+ if(b&0x20)PUSHWORD(yreg)
+ if(b&0x10)PUSHWORD(xreg)
+ if(b&0x08)PUSHBYTE(dpreg)
+ if(b&0x04)PUSHBYTE(*breg)
+ if(b&0x02)PUSHBYTE(*areg)
+ if(b&0x01)PUSHBYTE(ccreg)
+}
+
+void
+puls()
+{
+ Byte b;
+ IMMBYTE(b)
+ da_inst("puls",NULL,5);
+ da_len = 2;
+ bit_count(b);
+ if(b&0x01)PULLBYTE(ccreg)
+ if(b&0x02)PULLBYTE(*areg)
+ if(b&0x04)PULLBYTE(*breg)
+ if(b&0x08)PULLBYTE(dpreg)
+ if(b&0x10)PULLWORD(xreg)
+ if(b&0x20)PULLWORD(yreg)
+ if(b&0x40)PULLWORD(ureg)
+ if(b&0x80)PULLWORD(pcreg)
+}
+
+void
+pshu()
+{
+ Byte b;
+ IMMBYTE(b)
+ da_inst("pshu",NULL,5);
+ bit_count(b);
+ if(b&0x80)PUSHUWORD(pcreg)
+ if(b&0x40)PUSHUWORD(ureg)
+ if(b&0x20)PUSHUWORD(yreg)
+ if(b&0x10)PUSHUWORD(xreg)
+ if(b&0x08)PUSHUBYTE(dpreg)
+ if(b&0x04)PUSHUBYTE(*breg)
+ if(b&0x02)PUSHUBYTE(*areg)
+ if(b&0x01)PUSHUBYTE(ccreg)
+}
+
+void
+pulu()
+{
+ Byte b;
+ IMMBYTE(b)
+ da_inst("pulu",NULL,5);
+ da_len = 2;
+ bit_count(b);
+ if(b&0x01)PULLUBYTE(ccreg)
+ if(b&0x02)PULLUBYTE(*areg)
+ if(b&0x04)PULLUBYTE(*breg)
+ if(b&0x08)PULLUBYTE(dpreg)
+ if(b&0x10)PULLUWORD(xreg)
+ if(b&0x20)PULLUWORD(yreg)
+ if(b&0x40)PULLUWORD(ureg)
+ if(b&0x80)PULLUWORD(pcreg)
+}
+
+#define SETSTATUSD(a,b,res) {if(res&0x10000) SEC else CLC \
+                            if(((res>>1)^a^b^res)&0x8000) SEV else CLV \
+                            SETNZ16((Word)res)}
+
+void
+addd()
+{
+ unsigned long aop,bop,res;
+ Word ea;
+ da_inst("addd",NULL,5);
+ aop=*dreg & 0xffff;
+ ea=eaddr16();
+ bop=GETWORD(ea);
+ res=aop+bop;
+ SETSTATUSD(aop,bop,res)
+ *dreg=res;
+}
+
+void
+subd()
+{
+ unsigned long aop,bop,res;
+ Word ea;
+ aop=*dreg & 0xffff;
+ switch(iflag) {
+  case 0:
+        da_inst("subd",NULL,5);
+        break;
+  case 1:
+        da_inst("cmpd",NULL,5);
+        aop=*dreg & 0xffff;
+        break;
+  case 2:
+        da_inst("cmpu",NULL,5);
+        aop=ureg;
+ }
+ ea=eaddr16();
+ bop=GETWORD(ea);
+ res=aop-bop;
+ SETSTATUSD(aop,bop,res)
+ if(iflag==0) *dreg=res; /* subd result */
+}
+
+void
+cmpx()
+{
+ unsigned long aop,bop,res;
+ Word ea;
+ switch(iflag) {
+  case 0:
+        da_inst("cmpx",NULL,5);
+        aop=xreg;
+        break;
+  case 1:
+        da_inst("cmpy",NULL,5);
+        aop=yreg;
+        break;
+  case 2:
+        da_inst("cmps",NULL,5);
+        aop=sreg;
+ }
+ ea=eaddr16();
+ bop=GETWORD(ea);
+ res=aop-bop;
+ SETSTATUSD(aop,bop,res)
+}
+
+void
+ldd()
+{
+ Word ea,w;
+ da_inst("ldd",NULL,4);
+ ea=eaddr16();
+ w=GETWORD(ea);
+ SETNZ16(w)
+ *dreg=w;
+}
+
+void
+ldx()
+{
+ Word ea,w;
+ if (iflag) da_inst("ldy",NULL,4);
+ else da_inst("ldx",NULL,4);
+ ea=eaddr16();
+ w=GETWORD(ea);
+ SETNZ16(w)
+ if (iflag==0) xreg=w; else yreg=w;
+}
+
+void
+ldu()
+{
+ Word ea,w;
+ if (iflag) da_inst("lds",NULL,4);
+ else da_inst("ldu",NULL,4);
+ ea=eaddr16();
+ w=GETWORD(ea);
+ SETNZ16(w)
+ if (iflag==0) ureg=w; else sreg=w;
+}
+
+void
+std()
+{
+ Word ea,w;
+ da_inst("std",NULL,4);
+ ea=eaddr16();
+ w=*dreg;
+ SETNZ16(w)
+ SETWORD(ea,w)
+}
+
+void
+stx()
+{
+ Word ea,w;
+ if (iflag) da_inst("sty",NULL,4);
+ else da_inst("stx",NULL,4);
+ ea=eaddr16();
+ if (iflag==0) w=xreg; else w=yreg;
+ SETNZ16(w)
+ SETWORD(ea,w)
+}
+
+void
+stu()
+{
+ Word ea,w;
+ if (iflag) da_inst("sts",NULL,4);
+ else da_inst("stu",NULL,4);
+ ea=eaddr16();
+ if (iflag==0) w=ureg; else w=sreg;
+ SETNZ16(w)
+ SETWORD(ea,w)
+}
+
+void (*instrtable[])() = {
+ neg , ill , ill , com , lsr , ill , ror , asr ,
+ asl , rol , dec , ill , inc , tst , jmp , clr ,
+ flag0 , flag1 , nop , sync_inst , ill , ill , lbra , lbsr ,
+ ill , daa , orcc , ill , andcc , sex , exg , tfr ,
+ bra , brn , bhi , bls , bcc , bcs , bne , beq ,
+ bvc , bvs , bpl , bmi , bge , blt , bgt , ble ,
+ leax , leay , leas , leau , pshs , puls , pshu , pulu ,
+ ill , rts , abx , rti , cwai , mul , ill , swi ,
+ neg , ill , ill , com , lsr , ill , ror , asr ,
+ asl , rol , dec , ill , inc , tst , ill , clr ,
+ neg , ill , ill , com , lsr , ill , ror , asr ,
+ asl , rol , dec , ill , inc , tst , ill , clr ,
+ neg , ill , ill , com , lsr , ill , ror , asr ,
+ asl , rol , dec , ill , inc , tst , jmp , clr ,
+ neg , ill , ill , com , lsr , ill , ror , asr ,
+ asl , rol , dec , ill , inc , tst , jmp , clr ,
+sub , cmp , sbc , subd , and , bit , ld , st ,
+eor , adc ,  or , add , cmpx , bsr , ldx , stx ,
+sub , cmp , sbc , subd , and , bit , ld , st ,
+eor , adc ,  or , add , cmpx , jsr , ldx , stx ,
+sub , cmp , sbc , subd , and , bit , ld , st ,
+eor , adc ,  or , add , cmpx , jsr , ldx , stx ,
+sub , cmp , sbc , subd , and , bit , ld , st ,
+eor , adc ,  or , add , cmpx , jsr , ldx , stx ,
+sub , cmp , sbc , addd , and , bit , ld , st ,
+eor , adc ,  or , add , ldd , std , ldu , stu ,
+sub , cmp , sbc , addd , and , bit , ld , st ,
+eor , adc ,  or , add , ldd , std , ldu , stu ,
+sub , cmp , sbc , addd , and , bit , ld , st ,
+eor , adc ,  or , add , ldd , std , ldu , stu ,
+sub , cmp , sbc , addd , and , bit , ld , st ,
+eor , adc ,  or , add , ldd , std , ldu , stu ,
+};
+
+void
+read_image(char* name)
+{
+ FILE *image;
+ if((image=fopen(name,"rb"))!=NULL) {
+  fread(mem+0x100,0xff00,1,image);
+  fclose(image);
+ }
+}
+
+void
+dump()
+{
+ FILE *image;
+ if((image=fopen("dump.v09","wb"))!=NULL) {
+  fwrite(mem,0x10000,1,image);
+  fclose(image);
+ }
+}
+
+/* E F H I N Z V C */
+
+char *to_bin(Byte b)
+{
+        static char binstr[9];
+        Byte bm;
+        char *ccbit="EFHINZVC";
+        int i;
+
+        for(bm=0x80, i=0; bm>0; bm >>=1, i++)
+                binstr[i] = (b & bm) ? toupper(ccbit[i]) : tolower(ccbit[i]);
+        binstr[8] = 0;
+        return binstr;
+}
+
+
+void cr() {
+   #ifdef TERM_CONTROL
+   fprintf(stderr,"%s","\r\n");         /* CR+LF because raw terminal ... */
+   #else
+   fprintf(stderr,"%s","\n");
+   #endif
+}
+
+#ifdef TRACE
+
+/* max. bytes of instruction code per trace line */
+#define I_MAX 4
+
+void trace()
+{
+   int ilen;
+   int i;
+
+  if (
+   1 || (                                       /* no trace filtering ... */
+   !(ureg > 0x09c0 && ureg < 0x09f3) && (       /* CMOVE ausblenden! */
+    pcreg_prev == 0x01de || /* DOLST */
+    pcreg_prev == 0x037a || /* FDOVAR */
+  /*
+    ureg >= 0x0300 && ureg < 0x03f0 ||
+    ureg >=0x1900 ||
+    ureg > 0x118b && ureg < 0x11b2 ||
+    pcreg_prev >= 0x01de && pcreg_prev < 0x0300 ||
+    xreg >=0x8000 ||
+    pcreg_prev >= 0x01de && pcreg_prev < 0x0300 ||
+   */
+    0
+    ))
+   )
+  {
+   fprintf(stderr,"%04x ",pcreg_prev);
+   if (da_len) ilen = da_len;
+   else {
+        ilen = pcreg-pcreg_prev; if (ilen < 0) ilen= -ilen;
+   }
+   for(i=0; i < I_MAX; i++) {
+        if (i < ilen) fprintf(stderr,"%02x",mem[(pcreg_prev+i)&0xffff]);
+        else fprintf(stderr,"  ");
+   }
+   fprintf(stderr," %-5s %-17s [%02d] ", dinst, dops, cycles);
+   //if((ireg&0xfe)==0x10)
+   // fprintf(stderr,"%02x ",mem[pcreg]);else fprintf(stderr,"   ");
+   fprintf(stderr,"x=%04x y=%04x u=%04x s=%04x a=%02x b=%02x cc=%s",
+                   xreg,yreg,ureg,sreg,*areg,*breg,to_bin(ccreg));
+   fprintf(stderr,", s: %04x %04x, r: %04x",
+        mem[sreg]<<8|mem[sreg+1],
+        mem[sreg+2]<<8|mem[sreg+3],
+        mem[yreg]<<8|mem[yreg+1]
+   );
+   cr();
+  }
+  da_len = 0;
+}
+
+#endif
+
+
+static char optstring[]="d";
+
+int
+main(int argc,char *argv[])
+{
+ char c;
+ int a;
+
+ /* initialize memory with pseudo random data ... */
+ srandom(time(NULL));
+ for(a=0x0100; a<0x10000;a++) {
+        mem[(Word)a] = (Byte) (random() & 0xff);
+ }
+
+ while( (c=getopt(argc, argv, optstring)) >=0 ) {
+        switch(c) {
+          case 'd':
+                fdump = 1;
+                break;
+          default:
+                fprintf(stderr,"ERROR: Unknown option\n");
+                exit(2);
+        }
+ }
+
+ if (optind < argc) {
+   read_image(argv[optind]);
+ }
+ else {
+        fprintf(stderr,"ERROR: Missing image name\n");
+        exit(2);
+ }
+
+ pcreg=0x100;
+ sreg=0;
+ dpreg=0;
+ iflag=0;
+ /* raw disables SIGINT, brkint reenables it ...
+  */
+#if defined(TERM_CONTROL) && ! defined(TRACE)
+  /* raw, but still allow key signaling, especial if ^C is desired
+     - if not, remove brkint and isig!
+   */
+  system("stty -echo nl raw brkint isig");
+  tflags=fcntl(0,F_GETFL,0);
+  fcntl(0,F_SETFL,tflags|O_NDELAY);
+#endif
+
+#ifdef TRACE
+ da_len = 0;
+#endif
+ cycles_sum = 0;
+ pcreg_prev = pcreg;
+
+ for(;;){
+
+  ireg=mem[pcreg++];
+  cycles=0;
+  (*instrtable[ireg])();                /* process instruction */
+  cycles_sum += cycles;
+
+#ifdef TRACE
+  trace();
+#endif
+
+ pcreg_prev = pcreg;
+
+ } /* for */
+ return 0;
+}
+
+
+
+void finish()
+{
+ cr();
+ fprintf(stderr,"Cycles: %lu", cycles_sum);
+ cr();
+#if defined(TERM_CONTROL) && ! defined(TRACE)
+ system("stty -raw -nl echo brkint");
+ fcntl(0,F_SETFL,tflags&~O_NDELAY);
+#endif
+ if (fdump) dump();
+ exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/v09st.c	Mon Jul 02 02:12:31 2018 +0900
@@ -0,0 +1,1085 @@
+/* 6809 Simulator V09,
+   By L.C. Benschop, Eidnhoven The Netherlands.
+   This program is in the public domain.
+   
+   *** TURBO C VERSION ****   
+ 
+   This program simulates a 6809 processor.
+
+   System dependencies: short must be 16 bits.
+                        char  must be 8 bits.
+                        long must be more than 16 bits.
+                        arrays up to 65536 bytes must be supported.
+                        machine must be twos complement.
+   Most Unix machines will work. For MSODS you need long pointers
+   and you may have to malloc() the mem array of 65536 bytes.
+
+   Define BIG_ENDIAN if you have a big-endian machine (680x0 etc)
+
+   Define TRACE if you want an instruction trace on stderr.
+   Define TERM_CONTROL for raw, nonblocking IO.    
+
+   Special instructions:
+   SWI2 writes char to stdout from register B.
+   SWI3 reads char from stdout to register B, sets carry at EOF.
+               (or when no key available when using TERM Control).
+   SWI retains its normal function.
+   CWAI and SYNC stop simulator.
+
+   The program reads a binary image file at $100 and runs it from there.
+   The file name must be given on the command line.
+*/
+
+#include <stdio.h>
+#include <alloc.h>
+#ifdef TERM_CONTROL
+#include <conio.h>
+#endif
+
+typedef unsigned char Byte;
+typedef unsigned short Word;
+
+/* 6809 registers */
+Byte ccreg,dpreg;
+Word xreg,yreg,ureg,sreg,ureg,pcreg;
+
+Byte d_reg[2];
+Word *dreg=(Word *)d_reg;
+#ifdef BIG_ENDIAN /* This is a dirty aliasing trick, but fast! */
+ Byte *areg=d_reg;
+ Byte *breg=d_reg+1;
+#else
+ Byte *breg=d_reg;
+ Byte *areg=d_reg+1;
+#endif
+
+/* 6809 memory space */
+Byte *mem;
+
+#define GETWORD(a) (mem[a]<<8|mem[(a)+1])
+#define SETWORD(a,n) {mem[a]=(n)>>8;mem[(a)+1]=n;}
+/* Two bytes of a word are fetched separately because of
+   the possible wrap-around at address $ffff and alignment
+*/   
+
+
+int iflag; /* flag to indicate prebyte $10 or $11 */
+Byte ireg; /* Instruction register */
+
+#define IMMBYTE(b) b=mem[pcreg++];
+#define IMMWORD(w) {w=GETWORD(pcreg);pcreg+=2;}
+
+#define PUSHBYTE(b) mem[--sreg]=b;
+#define PUSHWORD(w) {sreg-=2;SETWORD(sreg,w)}
+#define PULLBYTE(b) b=mem[sreg++];
+#define PULLWORD(w) {w=GETWORD(sreg);sreg+=2;}
+
+#define SIGNED(b) ((Word)(b&0x80?b|0xff00:b))
+
+Word *ixregs[]={&xreg,&yreg,&ureg,&sreg};
+
+int index;
+
+/* Now follow the posbyte addressing modes. */
+
+Word illaddr() /* illegal addressing mode, defaults to zero */
+{
+ return 0;
+}
+
+Word ainc()
+{
+ return (*ixregs[index])++;
+}
+
+Word ainc2()
+{
+ Word temp;
+ temp=(*ixregs[index]);
+ (*ixregs[index])+=2;
+ return(temp);
+}
+
+Word adec()
+{
+ return --(*ixregs[index]);
+}
+
+Word adec2()
+{
+ Word temp;
+ (*ixregs[index])-=2;
+ temp=(*ixregs[index]);
+ return(temp);
+}
+
+Word plus0()
+{
+ return(*ixregs[index]);
+}
+
+Word plusa()
+{
+ return(*ixregs[index])+SIGNED(*areg);
+}
+
+Word plusb()
+{
+ return(*ixregs[index])+SIGNED(*breg);
+}
+
+Word plusn()
+{
+ Byte b;
+ IMMBYTE(b)
+ return(*ixregs[index])+SIGNED(b);
+}
+
+Word plusnn()
+{
+ Word w;
+ IMMWORD(w)
+ return(*ixregs[index])+w;
+}
+ 
+Word plusd()
+{
+ return(*ixregs[index])+*dreg;
+}
+
+
+Word npcr()
+{
+ Byte b;
+ IMMBYTE(b)
+ return pcreg+SIGNED(b);
+}
+
+Word nnpcr()
+{
+ Word w;
+ IMMWORD(w)
+ return pcreg+w;
+}            
+
+Word direct()
+{
+ Word(w);
+ IMMWORD(w)
+ return w;
+}
+
+Word zeropage()
+{ 
+ Byte b;
+ IMMBYTE(b)
+ return dpreg<<8|b;
+}
+
+
+Word immediate()
+{
+ return pcreg++;
+}
+
+Word immediate2()
+{
+ Word temp;
+ temp=pcreg;
+ pcreg+=2;
+ return temp;
+}
+
+Word (*pbtable[])()={ ainc, ainc2, adec, adec2, 
+                      plus0, plusb, plusa, illaddr,
+                      plusn, plusnn, illaddr, plusd,
+                      npcr, nnpcr, illaddr, direct, };
+
+Word postbyte() 
+{
+ Byte pb;
+ Word temp;
+ IMMBYTE(pb)
+ index=(pb & 0x60) >> 5;
+ if(pb & 0x80) {
+  temp=(*pbtable[pb & 0x0f])();
+  if( pb & 0x10) temp=GETWORD(temp);
+  return temp;
+ } else {
+  temp=pb & 0x1f;
+  if(temp & 0x10) temp|=0xfff0;
+  return (*ixregs[index])+temp;
+ }
+}
+
+Byte * eaddr0() /* effective address for NEG..JMP as byte poitner */
+{
+ switch( (ireg & 0x70) >> 4)
+ {
+  case 0: return mem+zeropage();
+  case 1:case 2:case 3: return 0; /*canthappen*/
+  case 4: return areg;
+  case 5: return breg;
+  case 6: return mem+postbyte();
+  case 7: return mem+direct(); 
+ }
+} 
+
+Word eaddr8()  /* effective address for 8-bits ops. */
+{
+ switch( (ireg & 0x30) >> 4)
+ {
+  case 0: return immediate();
+  case 1: return zeropage();
+  case 2: return postbyte();
+  case 3: return direct();
+ }
+}
+
+Word eaddr16() /* effective address for 16-bits ops. */
+{
+ switch( (ireg & 0x30) >> 4)
+ {
+  case 0: return immediate2();
+  case 1: return zeropage();
+  case 2: return postbyte();
+  case 3: return direct();
+ }
+}
+  
+ill() /* illegal opcode==noop */ 
+{
+}
+
+/* macros to set status flags */
+#define SEC ccreg|=0x01;
+#define CLC ccreg&=0xfe;
+#define SEZ ccreg|=0x04;
+#define CLZ ccreg&=0xfb;
+#define SEN ccreg|=0x08;
+#define CLN ccreg&=0xf7;
+#define SEV ccreg|=0x02;
+#define CLV ccreg&=0xfd;
+#define SEH ccreg|=0x20;
+#define CLH ccreg&=0xdf;
+
+/* set N and Z flags depending on 8 or 16 bit result */
+#define SETNZ8(b) {if(b)CLZ else SEZ if(b&0x80)SEN else CLN}
+#define SETNZ16(b) {if(b)CLZ else SEZ if(b&0x8000)SEN else CLN}
+
+#define SETSTATUS(a,b,res) if((a^b^res)&0x10) SEH else CLH \
+                           if((a^b^res^(res>>1))&0x80)SEV else CLV \
+                           if(res&0x100)SEC else CLC SETNZ8((Byte)res) 
+                           
+add()
+{
+ Word aop,bop,res;
+ Byte* aaop;
+ aaop=(ireg&0x40)?breg:areg;
+ aop=*aaop;
+ bop=mem[eaddr8()];                           
+ res=aop+bop;
+ SETSTATUS(aop,bop,res)
+ *aaop=res;
+} 
+
+sbc()
+{
+ Word aop,bop,res;
+ Byte* aaop;
+ aaop=(ireg&0x40)?breg:areg;
+ aop=*aaop;
+ bop=mem[eaddr8()];                           
+ res=aop-bop-(ccreg&0x01);
+ SETSTATUS(aop,bop,res)
+ *aaop=res;
+} 
+
+sub()
+{
+ Word aop,bop,res;
+ Byte* aaop;
+ aaop=(ireg&0x40)?breg:areg;
+ aop=*aaop;
+ bop=mem[eaddr8()];                           
+ res=aop-bop;
+ SETSTATUS(aop,bop,res)
+ *aaop=res;
+} 
+
+adc()
+{
+ Word aop,bop,res;
+ Byte* aaop;
+ aaop=(ireg&0x40)?breg:areg;
+ aop=*aaop;
+ bop=mem[eaddr8()];
+ res=aop+bop+(ccreg&0x01);
+ SETSTATUS(aop,bop,res)
+ *aaop=res;
+} 
+
+cmp()
+{
+ Word aop,bop,res;
+ Byte* aaop;
+ aaop=(ireg&0x40)?breg:areg;
+ aop=*aaop;
+ bop=mem[eaddr8()];                           
+ res=aop-bop;
+ SETSTATUS(aop,bop,res)
+} 
+
+and()
+{
+ Byte aop,bop,res;
+ Byte* aaop;
+ aaop=(ireg&0x40)?breg:areg;
+ aop=*aaop;
+ bop=mem[eaddr8()];                           
+ res=aop&bop;
+ SETNZ8(res)
+ CLV
+ *aaop=res;
+} 
+
+or()
+{
+ Byte aop,bop,res;
+ Byte* aaop;
+ aaop=(ireg&0x40)?breg:areg;
+ aop=*aaop;
+ bop=mem[eaddr8()];                           
+ res=aop|bop;
+ SETNZ8(res)
+ CLV
+ *aaop=res;
+} 
+
+eor()
+{
+ Byte aop,bop,res;
+ Byte* aaop;
+ aaop=(ireg&0x40)?breg:areg;
+ aop=*aaop;
+ bop=mem[eaddr8()];                           
+ res=aop^bop;
+ SETNZ8(res)
+ CLV
+ *aaop=res;
+} 
+
+bit()
+{
+ Byte aop,bop,res;
+ Byte* aaop;
+ aaop=(ireg&0x40)?breg:areg;
+ aop=*aaop;
+ bop=mem[eaddr8()];                           
+ res=aop&bop;
+ SETNZ8(res)
+ CLV
+} 
+
+ld()
+{
+ Byte res;
+ Byte* aaop;
+ aaop=(ireg&0x40)?breg:areg;
+ res=mem[eaddr8()];                           
+ SETNZ8(res)
+ CLV
+ *aaop=res;
+}
+
+st()
+{
+ Byte res;
+ Byte* aaop;
+ aaop=(ireg&0x40)?breg:areg;
+ res=*aaop;
+ mem[eaddr8()]=res;                           
+ SETNZ8(res)
+ CLV
+} 
+
+jsr()
+{
+ Word w;
+ w=eaddr8();
+ PUSHWORD(pcreg)
+ pcreg=w;
+}
+
+bsr()
+{
+ Byte b;
+ IMMBYTE(b)
+ PUSHWORD(pcreg)
+ pcreg+=SIGNED(b); 
+}
+
+neg()
+{
+ Byte *ea;
+ Word a,r;
+ a=0;
+ ea=eaddr0();
+ a=*ea;
+ r=-a;
+ SETSTATUS(0,a,r)
+ *ea=r;
+}
+
+com()
+{
+ Byte *ea;
+ Byte r;
+ ea=eaddr0();
+ r=0^*ea;
+ SETNZ8(r)
+ SEC CLV
+ *ea=r;
+}
+
+lsr()
+{
+ Byte *ea;
+ Byte r;
+ ea=eaddr0();
+ r=*ea;
+ if(r&0x01)SEC else CLC
+ r>>=1;
+ SETNZ8(r)
+ *ea=r;
+}
+
+ror()
+{
+ Byte *ea;
+ Byte r,c;
+ c=(ccreg&0x01)<<7;
+ ea=eaddr0();
+ r=*ea;
+ if(r&0x01)SEC else CLC
+ r=(r>>1)+c;
+ SETNZ8(r)
+ *ea=r;
+}
+
+asr()
+{
+ Byte *ea;
+ Byte r;
+ ea=eaddr0();
+ r=*ea;
+ if(r&0x01)SEC else CLC
+ r>>=1;
+ if(r&0x40)r|=0x80;
+ SETNZ8(r)
+ *ea=r;
+}
+
+asl()
+{
+ Byte *ea;
+ Word a,r;
+ ea=eaddr0();
+ a=*ea;
+ r=a<<1;
+ SETSTATUS(a,a,r) 
+ *ea=r;
+}
+
+rol()
+{
+ Byte *ea;
+ Byte r,c;
+ c=(ccreg&0x01);
+ ea=eaddr0();
+ r=*ea;
+ if(r&0x80)SEC else CLC 
+ r=(r<<1)+c; 
+ SETNZ8(r)
+ *ea=r;
+}
+
+inc()
+{
+ Byte *ea;
+ Byte r;
+ ea=eaddr0();
+ r=*ea;
+ r++;
+ if(r==0x80)SEV else CLV
+ SETNZ8(r)
+ *ea=r;
+}
+
+dec()
+{
+ Byte *ea;
+ Byte r;
+ ea=eaddr0();
+ r=*ea;
+ r--;
+ if(r==0x7f)SEV else CLV
+ SETNZ8(r)
+ *ea=r;
+}
+
+tst()
+{
+ Byte r;
+ r=*eaddr0();
+ SETNZ8(r)
+ CLV
+}
+
+jmp()
+{
+ Byte *ea;
+ ea=eaddr0();
+ pcreg=ea-mem;
+}
+
+clr()
+{
+ Byte *ea;
+ ea=eaddr0();
+ *ea=0;CLN CLV SEZ CLC
+}
+
+extern (*instrtable[])();
+
+flag0()
+{
+ if(iflag) /* in case flag already set by previous flag instr don't recurse */
+ {
+  pcreg--;
+  return; 
+ }
+ iflag=1;
+ ireg=mem[pcreg++];
+ (*instrtable[ireg])();
+ iflag=0;
+}
+
+flag1()
+{
+ if(iflag) /* in case flag already set by previous flag instr don't recurse */
+ {
+  pcreg--;
+  return; 
+ }
+ iflag=2;
+ ireg=mem[pcreg++];
+ (*instrtable[ireg])();
+ iflag=0;
+}
+
+nop()
+{
+}
+
+sync()
+{
+ exit(0);
+}
+
+cwai()
+{
+ sync();
+}
+
+lbra()
+{
+ Word w;
+ IMMWORD(w)
+ pcreg+=w;
+}
+
+lbsr()
+{
+ Word w;
+ IMMWORD(w)
+ PUSHWORD(pcreg)
+ pcreg+=w;
+}
+
+daa()
+{
+ Word a;
+ a=*areg;
+ if(ccreg&0x20)a+=6;
+ if((a&0x0f)>9)a+=6;
+ if(ccreg&0x01)a+=0x60;
+ if((a&0xf0)>0x90)a+=0x60;
+ if(a&0x100)SEC else CLC
+ *areg=a;
+}
+
+orcc()
+{
+ Byte b; 
+ IMMBYTE(b)
+ ccreg|=b;
+}
+
+andcc()
+{
+ Byte b; 
+ IMMBYTE(b)
+ ccreg&=b;
+}
+
+mul()
+{
+ Word w;
+ w=*areg * *breg;
+ if(w)CLZ else SEZ
+ if(w&0xff00) SEC else CLC
+ *dreg=w;
+}
+
+sex()
+{
+ Word w;
+ w=SIGNED(*breg);
+ SETNZ16(w)
+ *dreg=w;
+}
+
+abx()
+{
+ xreg += *breg;
+}
+
+rts()
+{
+ PULLWORD(pcreg)
+}
+
+rti()
+{
+ Byte x;
+ x=ccreg&0x80;
+ PULLBYTE(ccreg)
+ if(x)
+ {
+  PULLBYTE(*areg)
+  PULLBYTE(*breg)
+  PULLBYTE(dpreg)
+  PULLWORD(xreg)
+  PULLWORD(yreg)
+  PULLWORD(ureg)
+ } 
+ PULLWORD(pcreg)
+}
+
+swi()
+{
+ int w;
+ switch(iflag)
+ {
+  case 0: 
+   PUSHWORD(pcreg)
+   PUSHWORD(ureg)
+   PUSHWORD(yreg)
+   PUSHWORD(xreg)
+   PUSHBYTE(dpreg)
+   PUSHBYTE(*breg)
+   PUSHBYTE(*areg)
+   PUSHBYTE(ccreg)
+   ccreg|=0xd0;
+   pcreg=GETWORD(0xfffa);
+   break;
+  case 1:
+   putchar(*breg);
+   fflush(stdout);
+   break;
+  case 2:
+#ifndef TERM_CONTROL  
+   w=getchar();
+   if(w==EOF)SEC else CLC
+#else
+   if(kbhit()) {
+     w=getch();
+     CLC
+   } else {
+     w=255;
+     SEC
+   }
+#endif   
+   *breg=w;
+ }
+}
+    
+Word *wordregs[]={(Word*)d_reg,&xreg,&yreg,&ureg,&sreg,&pcreg,&sreg,&pcreg};
+#ifdef BIG_ENDIAN
+Byte *byteregs[]={d_reg,d_reg+1,&ccreg,&dpreg};
+#else
+Byte *byteregs[]={d_reg+1,d_reg,&ccreg,&dpreg};
+#endif
+
+tfr()
+{
+ Byte b;
+ IMMBYTE(b)
+ if(b&0x80) { 
+  *byteregs[b&0x03]=*byteregs[(b&0x30)>>4];
+ } else {
+  *wordregs[b&0x07]=*wordregs[(b&0x70)>>4];
+ }
+}
+
+exg()
+{
+ Byte b;
+ Word w;
+ IMMBYTE(b)
+ if(b&0x80) {
+  w=*byteregs[b&0x03]; 
+  *byteregs[b&0x03]=*byteregs[(b&0x30)>>4];
+  *byteregs[(b&0x30)>>4]=w;
+ } else {
+  w=*wordregs[b&0x07];
+  *wordregs[b&0x07]=*wordregs[(b&0x70)>>4];
+  *wordregs[(b&0x70)>>4]=w;
+ } 
+}
+
+br(int f)
+{
+ Byte b;
+ Word w;
+ if(!iflag) {
+  IMMBYTE(b)
+  if(f) pcreg+=SIGNED(b);
+ } else {
+  IMMWORD(w)
+  if(f) pcreg+=w;
+ }
+}   
+
+#define NXORV  ((ccreg&0x08)^(ccreg&0x02))
+
+bra()
+{ 
+ br(1);
+}
+
+brn()
+{
+ br(0);
+}
+
+bhi()
+{
+ br(!(ccreg&0x05));
+}
+
+bls()
+{
+ br(ccreg&0x05);
+}
+
+bcc()
+{
+ br(!(ccreg&0x01));
+}
+
+bcs()
+{
+ br(ccreg&0x01);
+}
+
+bne()
+{
+ br(!(ccreg&0x04));
+}
+
+beq()
+{
+ br(ccreg&0x04);
+}
+
+bvc()
+{
+ br(!(ccreg&0x02));
+}
+
+bvs()
+{
+ br(ccreg&0x02);
+}
+
+bpl()
+{
+ br(!(ccreg&0x08));
+}
+
+bmi()
+{
+ br(ccreg&0x08);
+}
+
+bge()
+{
+ br(!NXORV);
+}
+
+blt()
+{
+ br(NXORV);
+} 
+
+bgt()
+{
+ br(!(NXORV||ccreg&0x04));
+}
+
+ble()
+{
+ br(NXORV||ccreg&0x04);
+}   
+
+leax()
+{
+ Word w;
+ w=postbyte();
+ if(w) CLZ else SEZ
+ xreg=w;
+}
+
+leay()
+{
+ Word w;
+ w=postbyte();
+ if(w) CLZ else SEZ
+ yreg=w;
+}
+
+leau()
+{
+ ureg=postbyte();
+}
+
+leas()
+{
+ sreg=postbyte();
+}
+
+#define SWAPUS {temp=sreg;sreg=ureg;ureg=temp;}
+
+pshs()
+{
+ Byte b;
+ IMMBYTE(b)
+ if(b&0x80)PUSHWORD(pcreg)
+ if(b&0x40)PUSHWORD(ureg)
+ if(b&0x20)PUSHWORD(yreg)
+ if(b&0x10)PUSHWORD(xreg)
+ if(b&0x08)PUSHBYTE(dpreg)
+ if(b&0x04)PUSHBYTE(*breg)
+ if(b&0x02)PUSHBYTE(*areg)
+ if(b&0x01)PUSHBYTE(ccreg)
+}
+
+puls()
+{
+ Byte b;
+ IMMBYTE(b)
+ if(b&0x01)PULLBYTE(ccreg)
+ if(b&0x02)PULLBYTE(*areg)
+ if(b&0x04)PULLBYTE(*breg)
+ if(b&0x08)PULLBYTE(dpreg)
+ if(b&0x10)PULLWORD(xreg)
+ if(b&0x20)PULLWORD(yreg)
+ if(b&0x40)PULLWORD(ureg)
+ if(b&0x80)PULLWORD(pcreg)
+}
+
+pshu()
+{
+ Word temp;
+ SWAPUS
+ pshs();
+ SWAPUS
+}
+
+pulu()
+{
+ Word temp;
+ SWAPUS
+ puls();
+ SWAPUS
+}
+
+#define SETSTATUSD(a,b,res) {if((res&0x10000l)!=0) SEC else CLC \
+                            if((((res>>1)^a^b^res)&0x8000l)!=0) SEV else CLV \
+                            SETNZ16((Word)res)}
+
+addd()
+{
+ unsigned long aop,bop,res;
+ Word ea;
+ aop=*dreg&0xffff;
+ ea=eaddr16();
+ bop=GETWORD(ea)&0xffff;
+ res=aop+bop;
+ SETSTATUSD(aop,bop,res)
+ *dreg=res;
+}
+
+subd()
+{
+ unsigned long aop,bop,res;
+ Word ea;
+ if(iflag==2)aop=ureg; else aop=*dreg;
+ aop&=0xffff;
+ ea=eaddr16();
+ bop=GETWORD(ea)&0xffff;
+ res=aop-bop;
+ SETSTATUSD(aop,bop,res)
+ if(iflag==0) *dreg=res; 
+}
+
+cmpx()
+{
+ unsigned long aop,bop,res;
+ Word ea;
+ switch(iflag) {
+  case 0: aop=xreg;break;
+  case 1: aop=yreg;break;
+  case 2: aop=sreg;
+ }
+ aop&=0xffff;
+ ea=eaddr16();
+ bop=GETWORD(ea)&0xffff;
+ res=aop-bop;
+ SETSTATUSD(aop,bop,res)
+}
+
+ldd()
+{
+ Word ea,w;
+ ea=eaddr16();
+ w=GETWORD(ea);
+ SETNZ16(w)
+ *dreg=w;
+}
+
+ldx()
+{
+ Word ea,w;
+ ea=eaddr16();
+ w=GETWORD(ea);
+ SETNZ16(w)
+ if (iflag==0) xreg=w; else yreg=w;
+}
+
+ldu()
+{
+ Word ea,w;
+ ea=eaddr16();
+ w=GETWORD(ea);
+ SETNZ16(w)
+ if (iflag==0) ureg=w; else sreg=w;
+}
+
+std()
+{
+ Word ea,w;
+ ea=eaddr16();
+ w=*dreg;
+ SETNZ16(w)
+ SETWORD(ea,w)
+}
+
+stx()
+{
+ Word ea,w;
+ ea=eaddr16();
+ if (iflag==0) w=xreg; else w=yreg;
+ SETNZ16(w)
+ SETWORD(ea,w)
+}
+
+stu()
+{
+ Word ea,w;
+ ea=eaddr16();
+ if (iflag==0) w=ureg; else w=sreg;
+ SETNZ16(w)
+ SETWORD(ea,w)
+}
+
+int (*instrtable[])() = {
+ neg , ill , ill , com , lsr , ill , ror , asr ,
+ asl , rol , dec , ill , inc , tst , jmp , clr ,
+ flag0 , flag1 , nop , sync , ill , ill , lbra , lbsr ,
+ ill , daa , orcc , ill , andcc , sex , exg , tfr ,
+ bra , brn , bhi , bls , bcc , bcs , bne , beq ,
+ bvc , bvs , bpl , bmi , bge , blt , bgt , ble ,
+ leax , leay , leas , leau , pshs , puls , pshu , pulu ,
+ ill , rts , abx , rti , cwai , mul , ill , swi ,
+ neg , ill , ill , com , lsr , ill , ror , asr ,
+ asl , rol , dec , ill , inc , tst , ill , clr ,
+ neg , ill , ill , com , lsr , ill , ror , asr ,
+ asl , rol , dec , ill , inc , tst , ill , clr ,
+ neg , ill , ill , com , lsr , ill , ror , asr ,
+ asl , rol , dec , ill , inc , tst , jmp , clr ,
+ neg , ill , ill , com , lsr , ill , ror , asr ,
+ asl , rol , dec , ill , inc , tst , jmp , clr ,
+sub , cmp , sbc , subd , and , bit , ld , st ,
+eor , adc ,  or , add , cmpx , bsr , ldx , stx ,
+sub , cmp , sbc , subd , and , bit , ld , st ,
+eor , adc ,  or , add , cmpx , jsr , ldx , stx ,
+sub , cmp , sbc , subd , and , bit , ld , st ,
+eor , adc ,  or , add , cmpx , jsr , ldx , stx ,
+sub , cmp , sbc , subd , and , bit , ld , st ,
+eor , adc ,  or , add , cmpx , jsr , ldx , stx ,
+sub , cmp , sbc , addd , and , bit , ld , st ,
+eor , adc ,  or , add , ldd , std , ldu , stu ,
+sub , cmp , sbc , addd , and , bit , ld , st ,
+eor , adc ,  or , add , ldd , std , ldu , stu ,
+sub , cmp , sbc , addd , and , bit , ld , st ,
+eor , adc ,  or , add , ldd , std , ldu , stu ,
+sub , cmp , sbc , addd , and , bit , ld , st ,
+eor , adc ,  or , add , ldd , std , ldu , stu ,
+};
+
+read_image(char* name)
+{
+ FILE *image;
+ if((image=fopen(name,"rb"))!=NULL) {
+  fread(mem+0x100,0xff00,1,image);
+  fclose(image);
+ }
+}
+
+main(int argc,char *argv[])
+{
+ mem=farmalloc(65536);
+ read_image(argv[1]);
+ pcreg=0x100;
+ sreg=0;
+ dpreg=0;
+ iflag=0;
+ for(;;){
+  #ifdef TRACE
+   fprintf(stderr,"pc=%04x ",pcreg);
+  #endif
+  ireg=mem[pcreg++];
+  #ifdef TRACE
+   fprintf(stderr,"i=%02x ",ireg);
+   if((ireg&0xfe)==0x10)
+    fprintf(stderr,"%02x ",mem[pcreg]);else fprintf(stderr,"   ");
+     fprintf(stderr,"x=%04x y=%04x u=%04x s=%04x a=%02x b=%02x cc=%02x\n",
+                   xreg,yreg,ureg,sreg,*areg,*breg,ccreg);
+  #endif
+  (*instrtable[ireg])();
+ }
+}
+