as09: 6809 assembler for native asm work
authorAlan Cox <alan@linux.intel.com>
Mon, 8 Jun 2015 21:03:48 +0000 (22:03 +0100)
committerAlan Cox <alan@linux.intel.com>
Mon, 8 Jun 2015 21:03:48 +0000 (22:03 +0100)
Right now this won't *quite* fit on the Dragon32, but I think it would with
a tiny bit of tidying up and if 6809 is fixed to not suck in stdio always
(or has a stdio free link option as Z80 has for now)

97 files changed:
Applications/as09/6809/const.h [new file with mode: 0644]
Applications/as09/Makefile [new file with mode: 0644]
Applications/as09/address.h [new file with mode: 0644]
Applications/as09/align.h [new file with mode: 0644]
Applications/as09/alloc.c [new file with mode: 0644]
Applications/as09/as.c [new file with mode: 0644]
Applications/as09/as86_encap.sh [new file with mode: 0644]
Applications/as09/as86_to_data [new file with mode: 0644]
Applications/as09/asm/calljmp.asm [new file with mode: 0644]
Applications/as09/asm/ea.asm [new file with mode: 0644]
Applications/as09/asm/each.asm [new file with mode: 0644]
Applications/as09/asm/easlow.as [new file with mode: 0644]
Applications/as09/asm/f.asm [new file with mode: 0644]
Applications/as09/asm/fadd.asm [new file with mode: 0644]
Applications/as09/asm/farcall.asm [new file with mode: 0644]
Applications/as09/asm/group1.asm [new file with mode: 0644]
Applications/as09/asm/group6.asm [new file with mode: 0644]
Applications/as09/asm/group7.asm [new file with mode: 0644]
Applications/as09/asm/imul.asm [new file with mode: 0644]
Applications/as09/asm/incdec.asm [new file with mode: 0644]
Applications/as09/asm/inher.asm [new file with mode: 0644]
Applications/as09/asm/inout.asm [new file with mode: 0644]
Applications/as09/asm/movspec.asm [new file with mode: 0644]
Applications/as09/asm/pushpop.asm [new file with mode: 0644]
Applications/as09/asm/seg.asm [new file with mode: 0644]
Applications/as09/asm/shdouble.asm [new file with mode: 0644]
Applications/as09/asm/shift.asm [new file with mode: 0644]
Applications/as09/asm/summary.as [new file with mode: 0644]
Applications/as09/asm/xchg.asm [new file with mode: 0644]
Applications/as09/assemble.c [new file with mode: 0644]
Applications/as09/bin/calljmp.bin [new file with mode: 0644]
Applications/as09/bin/ea.bin [new file with mode: 0644]
Applications/as09/bin/each.bin [new file with mode: 0644]
Applications/as09/bin/f.bin [new file with mode: 0644]
Applications/as09/bin/fadd.bin [new file with mode: 0644]
Applications/as09/bin/farcall.bin [new file with mode: 0644]
Applications/as09/bin/group1.bin [new file with mode: 0644]
Applications/as09/bin/group6.bin [new file with mode: 0644]
Applications/as09/bin/group7.bin [new file with mode: 0644]
Applications/as09/bin/imul.bin [new file with mode: 0644]
Applications/as09/bin/incdec.bin [new file with mode: 0644]
Applications/as09/bin/inher.bin [new file with mode: 0644]
Applications/as09/bin/inout.bin [new file with mode: 0644]
Applications/as09/bin/movspec.bin [new file with mode: 0644]
Applications/as09/bin/pushpop.bin [new file with mode: 0644]
Applications/as09/bin/seg.bin [new file with mode: 0644]
Applications/as09/bin/shdouble.bin [new file with mode: 0644]
Applications/as09/bin/shift.bin [new file with mode: 0644]
Applications/as09/bin/xchg.bin [new file with mode: 0644]
Applications/as09/byteord.h [new file with mode: 0644]
Applications/as09/chk [new file with mode: 0755]
Applications/as09/const.h [new file with mode: 0644]
Applications/as09/errors.c [new file with mode: 0644]
Applications/as09/errors.h [new file with mode: 0644]
Applications/as09/express.c [new file with mode: 0644]
Applications/as09/file.h [new file with mode: 0644]
Applications/as09/flag.h [new file with mode: 0644]
Applications/as09/genbin.c [new file with mode: 0644]
Applications/as09/genlist.c [new file with mode: 0644]
Applications/as09/genobj.c [new file with mode: 0644]
Applications/as09/gensym.c [new file with mode: 0644]
Applications/as09/globvar.h [new file with mode: 0644]
Applications/as09/keywords.c [new file with mode: 0644]
Applications/as09/macro.c [new file with mode: 0644]
Applications/as09/macro.h [new file with mode: 0644]
Applications/as09/mops.c [new file with mode: 0644]
Applications/as09/obj1/calljmp.obj [new file with mode: 0644]
Applications/as09/obj1/ea.obj [new file with mode: 0644]
Applications/as09/obj1/each.obj [new file with mode: 0644]
Applications/as09/obj1/f.obj [new file with mode: 0644]
Applications/as09/obj1/fadd.obj [new file with mode: 0644]
Applications/as09/obj1/farcall.obj [new file with mode: 0644]
Applications/as09/obj1/group1.obj [new file with mode: 0644]
Applications/as09/obj1/group6.obj [new file with mode: 0644]
Applications/as09/obj1/group7.obj [new file with mode: 0644]
Applications/as09/obj1/imul.obj [new file with mode: 0644]
Applications/as09/obj1/incdec.obj [new file with mode: 0644]
Applications/as09/obj1/inher.obj [new file with mode: 0644]
Applications/as09/obj1/inout.obj [new file with mode: 0644]
Applications/as09/obj1/movspec.obj [new file with mode: 0644]
Applications/as09/obj1/pushpop.obj [new file with mode: 0644]
Applications/as09/obj1/seg.obj [new file with mode: 0644]
Applications/as09/obj1/shdouble.obj [new file with mode: 0644]
Applications/as09/obj1/shift.obj [new file with mode: 0644]
Applications/as09/obj1/xchg.obj [new file with mode: 0644]
Applications/as09/opcode.h [new file with mode: 0644]
Applications/as09/pops.c [new file with mode: 0644]
Applications/as09/proto.h [new file with mode: 0644]
Applications/as09/readsrc.c [new file with mode: 0644]
Applications/as09/scan.c [new file with mode: 0644]
Applications/as09/scan.h [new file with mode: 0644]
Applications/as09/source.h [new file with mode: 0644]
Applications/as09/syshead.h [new file with mode: 0644]
Applications/as09/table.c [new file with mode: 0644]
Applications/as09/type.h [new file with mode: 0644]
Applications/as09/typeconv.c [new file with mode: 0644]
Applications/as09/version.h [new file with mode: 0644]

diff --git a/Applications/as09/6809/const.h b/Applications/as09/6809/const.h
new file mode 100644 (file)
index 0000000..abd9469
--- /dev/null
@@ -0,0 +1,501 @@
+#define align(x)               /* ((x) = ((int) (x) + (4-1)) & ~(4-1)) */
+#define LOW_BYTE 0             /* must be changed for big-endian */
+
+/* const.h - constants for assembler */
+
+/* major switches */
+
+#undef  I80386                 /* generate 80386 code */
+#define MC6809                 /* generate 6809 code */
+#define MNSIZE                 /* allow byte size in mnemonic, e.g. "movb" */
+#undef  SOS_EDOS               /* source OS is EDOS */
+
+/* defaults */
+
+#define DIRCHAR '/'            /* character separating filename from dir */
+#define INBUFSIZE 8192
+#define SOS_EOLSTR "\012"
+
+/* defaults modified by switches */
+
+#ifdef SOS_EDOS
+# undef INBUFSIZE
+# define INBUFSIZE 512
+# undef SOS_EOLSTR
+# define SOS_EOLSTR "\015\012"
+# define STAKSIZ 256           /* table grows up to stack less this */
+#endif
+
+/* booleans */
+
+#define FALSE 0
+#define TRUE 1
+
+/* ASCII constants */
+
+#define ETB  23
+
+/* C tricks */
+
+#define EXTERN extern
+#define FORWARD static
+#define PRIVATE static
+#define PUBLIC
+#define NULL 0
+
+/* O/S constants */
+
+#define CREAT_PERMS 0666
+#define EOF (-1)
+#define STDIN 0
+#define STDOUT 1
+
+/* register codes (internal to assembler) */
+
+#ifdef I80386
+
+/* index regs must be first */
+
+#define BPREG 0
+#define BXREG 1
+#define DIREG 2
+#define SIREG 3
+#define MAX16BITINDREG 3
+
+#define EAXREG 4
+#define EBPREG 5
+#define EBXREG 6
+#define ECXREG 7
+#define EDIREG 8
+#define EDXREG 9
+#define ESIREG 10
+#define ESPREG 11
+#define MAXINDREG 11
+
+#define AXREG 12
+#define CXREG 13
+#define DXREG 14
+#define SPREG 15
+
+#define AHREG 16
+#define ALREG 17
+#define BHREG 18
+#define BLREG 19
+#define CHREG 20
+#define CLREG 21
+#define DHREG 22
+#define DLREG 23
+
+#define CSREG 24
+#define DSREG 25
+#define ESREG 26
+#define FSREG 27
+#define GSREG 28
+#define SSREG 29
+
+#define CR0REG 30
+#define CR2REG 31
+#define CR3REG 32
+#define DR0REG 33
+#define DR1REG 34
+#define DR2REG 35
+#define DR3REG 36
+#define DR6REG 37
+#define DR7REG 38
+#define TR6REG 39
+#define TR7REG 40
+
+#define NOREG 41
+
+#endif                         /* I80386 */
+
+#ifdef MC6809
+
+/* index regs must be first, then PC, then other regs */
+
+#define AREG  5
+#define BREG  6
+#define CCREG 7
+#define DPREG 8
+#define DREG  9
+#define MAXINDREG 3
+#define NOREG 10
+#define PCREG 4
+#define SREG  0
+#define UREG  1
+#define XREG  2
+#define YREG  3
+
+#endif
+
+#ifdef I80386
+
+/* type and size keywords */
+
+#define BYTEOP     0
+#define DWORDOP    1
+#define FWORDOP    2
+#define FAROP      3
+#define PTROP      4
+#define PWORDOP    5
+#define QWORDOP    6
+#define TBYTEOP    7
+#define WORDOP     8
+#endif
+
+/* special chars */
+
+#define EOL            0
+#define MACROCHAR      '?'
+
+/* symbol codes */
+
+/* the first 2 must be from chars in identifiers */
+#define IDENT          0
+#define INTCONST       1
+
+/* the next few are best for other possibly-multi-char tokens */
+#define ADDOP          2       /* also ++ */
+#define BINCONST       3
+#define CHARCONST      4
+#define GREATERTHAN    5       /* also >> and context-sensitive */
+#define HEXCONST       6
+#define LESSTHAN       7       /* also << and context-sensitive */
+#define SUBOP          8       /* also -- */
+#define WHITESPACE     9
+
+#define ANDOP          10
+#define COMMA          11
+#define EOLSYM         12
+#define EQOP           13
+#define IMMEDIATE      14
+#define INDIRECT       15
+#define LBRACKET       16
+#define LPAREN         17
+#define MACROARG       18
+#define NOTOP          19
+#define OROP           20
+#define OTHERSYM       21
+#define POSTINCOP      22
+#define PREDECOP       23
+#define RBRACKET       24
+#define RPAREN         25
+#define SLASH          26      /* context-sensitive */
+#define SLOP           27
+#define SROP           28
+#define STAR           29      /* context-sensitive */
+#define STRINGCONST    30
+#define COLON          31
+
+/* these are from assembler errors module */
+
+/* syntax errors */
+
+#define COMEXP 0
+#define DELEXP 1
+#define FACEXP 2
+#define IREGEXP 3
+#define LABEXP 4
+#define LPEXP 5
+#define OPEXP 6
+#define RBEXP 7
+#define REGEXP 8
+#define RPEXP 9
+#define SPEXP 10
+
+/* expression errors */
+
+#define ABSREQ 11
+#define NONIMPREQ 12
+#define RELBAD 13
+
+/* label errors */
+
+#define ILLAB 14
+#define MACUID 15
+#define MISLAB 16
+#define MNUID 17
+#define REGUID 18
+#define RELAB 19
+#define UNBLAB 20
+#define UNLAB 21
+#define VARLAB 22
+
+/* addressing errors */
+
+#define ABOUNDS 23
+#define DBOUNDS 24
+#define ILLMOD 25
+#define ILLREG 26
+
+/* control structure errors */
+
+#define ELSEBAD 27
+#define ELSEIFBAD 27
+#define ENDBBAD 28
+#define ENDIFBAD 27
+#define EOFBLOCK 29
+#define EOFIF 30
+
+#define EOFLC 31
+#define EOFMAC 32
+#define FAILERR 33
+
+/* overflow errors */
+
+#define BLOCKOV 34
+#define BWRAP 35
+#define COUNTOV 36
+#define COUNTUN 37
+#define GETOV 38
+#define IFOV 39
+
+#define LINLONG 40
+#define MACOV 41
+#define OBJSYMOV 42
+#define OWRITE 43
+#define PAROV 44
+#define SYMOV 45
+#define SYMOUTOV 46
+
+/* i/o errors */
+
+#define OBJOUT 47
+
+/* miscellaneous errors */
+
+#define CTLINS 48
+#define FURTHER 49
+#define NOIMPORT 50
+#define NOTIMPLEMENTED 51
+#define REENTER 52
+#define SEGREL 53
+
+/* warnings */
+
+#define MINWARN 54
+#define ALREADY 54
+#define SHORTB 55
+
+/* symbol table entry */
+
+                               /* type entry contains following flags */
+#define ENTBIT   (1<<0)                /* entry point (=OBJ_N_MASK) */
+#define COMMBIT  (1<<1)                /* common */
+#define LABIT    (1<<2)                /* label (a PC location or defined by EQU) */
+#define MNREGBIT (1<<3)                /* mnemonic for op or pseudo-op, or register */
+#define MACBIT   (1<<4)                /* macro */
+#define REDBIT   (1<<5)                /* redefined */
+#define VARBIT   (1<<6)                /* variable (i.e. something defined by SET) */
+#define EXPBIT   (1<<7)                /* exported (= OBJ_E_MASK) */
+
+                               /* data entry contains following flags, valid */
+                               /* for expressions as well as syms */
+#define PAGE1    (1<<0)                /* page 1 machine op = MNREGBIT \ PAGE1 */
+#define PAGE2    (1<<1)                /* page 2 machine op = MNREGBIT \ PAGE2 */
+#define REGBIT   (1<<2)                /* register = MNREGBIT \ REGBIT */
+#define SIZEBIT  (1<<3)                /* sizing mnemonic = MNREGBIT \ SIZEBIT */
+#define SEGM     15            /* 1st 4 bits reused for segment if !MNREGBIT */
+#define RELBIT   (1<<4)                /* relative (= OBJ_A_MASK) */
+#define FORBIT   (1<<5)                /* forward referenced */
+#define IMPBIT   (1<<6)                /* imported (= OBJ_I_MASK) */
+#define UNDBIT   (1<<7)                /* undefined */
+
+/* pseudo-op routine numbers */
+/* conditionals are first, this is used to test if op is a conditional */
+
+#define ELSEOP      0
+#define ELSEIFOP    1
+#define ELSEIFCOP   2
+#define ENDIFOP     3
+#define IFOP        4
+#define IFCOP       5
+#define MAXCOND     6          /* limit of conditionals */
+
+#define BLOCKOP     6
+#define COMMOP      7
+#define ENDOP       8
+#define ENDBOP      9
+#define ENTEROP    10
+#define ENTRYOP    11
+#define EQUOP      12
+#define EXPORTOP   13
+#define FAILOP     14
+#define FCBOP      15
+#define FCCOP      16
+#define FDBOP      17
+#define GETOP      18
+#define IDENTOP    19
+#define IMPORTOP   20
+#define _LISTOP    21
+#define LOCOP      22
+#define _MACLISTOP 23
+#define MACROOP    24
+#define _MAPOP     25
+#define ORGOP      26
+#define RMBOP      27
+#define SETOP      28
+#define SETDPOP    29
+#define _WARNOP    30
+
+#ifdef I80386
+
+/* further pseudo-ops */
+
+#define BSSOP      31
+#define COMMOP1    32
+#define DATAOP     33
+#define TEXTOP     34
+#define USE16OP    35
+#define USE32OP    36
+
+/* machine-op routine numbers */
+
+#define ARPL       37
+#define BCC        38
+#define BOUND      39
+#define CALL       40
+#define DIVMUL     41
+#define ENTER      42
+#define GROUP1     43
+#define GROUP2     44
+#define GROUP6     45
+#define GROUP7     46
+#define GROUP8     47
+#define GvEv       48
+#define IMUL       49
+#define IN         50
+#define INCDEC     51
+#define INHER      52
+#define INHER16    53
+#define INHER32    54
+#define INHER_A    55
+#define INT        56
+#define JCC        57
+#define JCXZ       58
+#define LEA        59
+#define LOAD_FULL_POINTER 60
+#define MOV        61
+#define MOVX       62
+#define NEGNOT     63
+#define OUT        64
+#define PUSHPOP    65
+#define RET        66
+#define RETF       67
+#define SEG        68
+#define SETCC      69
+#define SH_DOUBLE  70
+#define TEST       71
+#define XCHG       72
+
+/* further pseudo-ops */
+
+#define BLKWOP     73
+#define EVENOP     74
+#define FQBOP      75
+#define ALIGNOP    76
+
+/* further machine-ops */
+
+#define CALLI      77
+
+/* yet further pseudo-ops */
+
+#define LCOMMOP    78
+#define LCOMMOP1   79
+
+#endif                         /* I80386 */
+
+#ifdef MC6809
+
+/* machine-op routine numbers */
+
+#define ALL        31          /* all address modes allowed, like LDA */
+#define ALTER      32          /* all but immediate, like STA */
+#define IMMED      33          /* immediate only (ANDCC, ORCC) */
+#define INDEXD     34          /* indexed (LEA's) */
+#define INHER      35          /* inherent, like CLC or CLRA */
+#define LONG       36          /* long branches */
+#define SHORT      37          /* short branches */
+#define SSTAK      38          /* S-stack (PSHS, PULS) */
+#define SWAP       39          /* TFR, EXG */
+#define USTAK      40          /* U-stack (PSHU,PULU) */
+
+/* yet further pseudo-ops */
+
+#define LCOMMOP    41
+
+#endif
+
+/* object code format (Introl) */
+
+#define OBJ_SEGSZ_TWO  0x02    /* size 2 code for segment size descriptor */
+
+#define OBJ_MAX_ABS_LEN  64    /* max length of chunk of absolute code */
+
+#define OBJ_ABS        0x40    /* absolute code command */
+#define OBJ_OFFSET_REL 0x80    /* offset relocation command */
+#define OBJ_SET_SEG    0x20    /* set segment command */
+#define OBJ_SKIP_1     0x11    /* skip with 1 byte count */
+#define OBJ_SKIP_2     0x12    /* skip with 2 byte count */
+#define OBJ_SKIP_4     0x13    /* skip with 4 byte count */
+#define OBJ_SYMBOL_REL 0xC0    /* symbol relocation command */
+
+#define OBJ_A_MASK     0x10    /* absolute bit(symbols) */
+#if OBJ_A_MASK - RELBIT                /* must match internal format (~byte 1 -> 0) */
+oops - RELBIT misplaced
+#endif
+#define OBJ_E_MASK     0x80    /* exported bit (symbols) */
+#if OBJ_E_MASK - EXPBIT                /* must match internal format (byte 0 -> 0) */
+oops - EXPBIT misplaced
+#endif
+#define OBJ_I_MASK     0x40    /* imported bit (symbols) */
+#if OBJ_I_MASK - IMPBIT                /* must match internal format (byte 1 -> 0) */
+oops - IMPBIT misplaced
+#endif
+#define OBJ_N_MASK     0x01    /* entry bit (symbols) */
+#if OBJ_N_MASK - ENTBIT                /* must match internal format (byte 0 -> 1) */
+oops - ENTBIT misplaced
+#endif
+#define OBJ_SA_MASK    0x20    /* size allocation bit (symbols) */
+#define OBJ_SZ_ONE     0x40    /* size one code for symbol value */
+#define OBJ_SZ_TWO     0x80    /* size two code for symbol value */
+#define OBJ_SZ_FOUR    0xC0    /* size four code for symbol value */
+
+#define OBJ_R_MASK     0x20    /* PC-rel bit (off & sym reloc commands) */
+#define OBJ_SEGM_MASK  0x0F    /* segment mask (symbols, off reloc command) */
+
+#define OBJ_OF_MASK    0x03    /* offset size code for symbol reloc */
+#define OBJ_S_MASK     0x04    /* symbol number size code for symbol reloc */
+
+#define SYMLIS_NAMELEN 26
+#define SYMLIS_LEN (sizeof (struct sym_listing_s))
+
+#define FILNAMLEN 64           /* max length of a file name */
+#define LINLEN 256             /* max length of input line */
+#define LINUM_LEN 5            /* length of formatted line number */
+
+#define SPTSIZ 1024            /* number of symbol ptrs */
+                               /* pseudo-op flags */
+#define POPHI 1                        /* set to print hi byte of adr */
+#define POPLO 2                        /* to print lo byte of ADR */
+#define POPLC 4                        /* to print LC */
+#define POPLONG 8              /* to print high word of ADR */
+#define MAXBLOCK 8             /* max nesting level of BLOCK stack */
+#define MAXGET 8               /* max nesting level of GET stack */
+#define MAXIF 8                        /* max nesting level of IF stack */
+#define MACPSIZ (128/sizeof (struct schain_s))
+                               /* size of macro param buffer */
+#define MAXMAC 8               /* max nesting level of macro stack */
+#define NLOC 16                        /* number of location counters */
+#ifdef I80386
+#define NO_SIB 0340            /* illegal sib (3 with 4) to mean no sib */
+#endif
+
+/* special segments */
+
+#define BSSLOC 3
+#define DATALOC 3
+#define DPLOC 2
+#define STRLOC 1
+#define TEXTLOC 0
diff --git a/Applications/as09/Makefile b/Applications/as09/Makefile
new file mode 100644 (file)
index 0000000..6505036
--- /dev/null
@@ -0,0 +1,49 @@
+PLATFORM = 6809
+CC = m6809-unknown-gcc
+# These are wrappers for lwasm and lwar
+ASM = m6809-unknown-as
+AR = m6809-unknown-ar
+LINKER = lwlink
+CFLAGS =  -I../../Library/include -I../../Library/include/6502 -Wall -pedantic -fno-strict-aliasing
+COPT = -Os
+LINKER_OPT = --format=raw -L../../Library/libs -lc6809
+LIBGCCDIR = $(dir $(shell $(CC) -print-libgcc-file-name))
+LINKER_OPT += -L$(LIBGCCDIR) -lgcc -m as09.map
+LINKER_OPT += --script=../util/$(TARGET).link
+ASM_OPT = -o
+CRT0 = ../../Library/libs/crt0_6809.o
+
+OBJS           =as.o assemble.o errors.o express.o \
+                genbin.o genlist.o genobj.o gensym.o \
+                keywords.o macro.o mops.o pops.o readsrc.o \
+                scan.o table.o typeconv.o alloc.o
+
+all: as09
+
+as09: $(OBJS)
+       $(LINKER) -o $@ $(LINKER_OPT) $(CRT0) $(OBJS)
+
+clean realclean clobber:
+       rm -f *.o as09 *~
+
+.c.o:
+       $(CC) $(CFLAGS) $(COPT) -c $<
+
+$(OBJS): const.h errors.h
+
+as.o: const.h type.h byteord.h macro.h file.h flag.h globvar.h
+assemble.o: const.h type.h address.h globvar.h opcode.h scan.h
+error.o: const.h type.h
+express.o: const.h type.h address.h globvar.h scan.h source.h
+genbin.o: const.h type.h address.h file.h globvar.h
+genlist.o: const.h type.h address.h flag.h file.h globvar.h macro.h scan.h \
+          source.h
+genobj.o: const.h type.h address.h file.h globvar.h
+gensym.o: const.h type.h flag.h file.h globvar.h
+keywords.o: const.h type.h globvar.h opcode.h
+macro.o: const.h type.h globvar.h scan.h macro.h
+mops.o: const.h type.h globvar.h opcode.h scan.h address.h
+pops.o: const.h type.h address.h flag.h globvar.h opcode.h scan.h
+readsrc.o: const.h type.h flag.h file.h globvar.h macro.h scan.h source.h
+scan.o: const.h type.h globvar.h scan.h 
+table.o: const.h type.h globvar.h opcode.h scan.h
diff --git a/Applications/as09/address.h b/Applications/as09/address.h
new file mode 100644 (file)
index 0000000..26fcf33
--- /dev/null
@@ -0,0 +1,30 @@
+/* address.h - global variables involving addresses for assembler */
+
+EXTERN struct address_s lastexp;/* last expression parsed */
+
+EXTERN union
+{
+    char fcbuf[LINLEN - 6];    /* buffer for fcb and fcc data */
+                               /* data is absolute in 1 char pieces */
+                               /* limited by FCC\t"" etc on line */
+    struct address_s fdbuf[(LINLEN - 4) / 2];
+                               /* buffer for fdb data */
+                               /* data can be of any 2-byte adr type */
+                               /* limited by FDB\t and commas on line */
+#if SIZEOF_OFFSET_T > 2
+    struct address_s fqbuf[(LINLEN - 4) / 4];
+                               /* buffer for fqb data */
+                               /* data can be of any 4-byte adr type */
+                               /* limited by FQB\t and commas on line */
+#endif
+}
+    databuf;
+
+EXTERN bool_t fcflag;
+EXTERN bool_t fdflag;
+#if SIZEOF_OFFSET_T > 2
+EXTERN bool_t fqflag;
+#endif
+
+EXTERN struct address_s immadr;
+EXTERN smallcount_t immcount;
diff --git a/Applications/as09/align.h b/Applications/as09/align.h
new file mode 100644 (file)
index 0000000..52b1e89
--- /dev/null
@@ -0,0 +1,23 @@
+/* align.h - memory alignment requirements for linker */
+
+/* Copyright (C) 1994 Bruce Evans */
+
+#ifndef S_ALIGNMENT
+# define align(x)
+#else
+
+#if defined(__STDC__) && defined(_POSIX_SOURCE)
+# define align(x) ((x)=(void *)        \
+                  (((ssize_t)(x) + (S_ALIGNMENT-1)) & ~(S_ALIGNMENT-1)))
+#else
+# define align(x) ((x)=(void *)        \
+                  ((char *)(x) + ((S_ALIGNMENT-(char)(x)) & (S_ALIGNMENT-1))))
+#endif
+#endif
+
+
+
+
+
+
+
diff --git a/Applications/as09/alloc.c b/Applications/as09/alloc.c
new file mode 100644 (file)
index 0000000..2ca84f3
--- /dev/null
@@ -0,0 +1,94 @@
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "align.h"
+
+static char NOMEMEORY[] = "Cannot allocate sufficient memory";
+
+#ifdef USE_FIXED_HEAP
+static char *heapend;          /* end of free space for symbol list */
+static char *heapptr;          /* next free space in symbol list */
+#endif
+
+#ifndef USE_FIXED_HEAP
+static char tempbuf[2048];
+#endif
+
+void init_heap(void)
+{
+#ifdef USE_FIXED_HEAP
+#ifndef USERMEM
+#define USERMEM 0xAC00U
+#endif
+
+#if defined(__AS386_16__) || defined(__m6809__)
+    int stk;
+    heapptr = sbrk(0);
+    heapend = ((char*)&stk) - STAKSIZ - 16;
+    brk(heapend);
+    if(sbrk(0) != heapend)
+       as_abort(NOMEMEORY);
+#else
+#ifdef SOS_EDOS
+    heapend = stackreg() - STAKSIZ;
+#else
+    heapptr = malloc(USERMEM);
+    heapend = heapptr + USERMEM;
+    if (heapptr == 0)
+       as_abort(NOMEMEORY);
+#endif
+#endif
+#endif
+}
+
+void *temp_buf(void)
+{
+#ifdef USE_FIXED_HEAP
+    return heapptr;
+#else
+    return tempbuf;
+#endif
+}
+
+void *asalloc(unsigned int size)
+{
+    void * rv;
+#ifdef USE_FIXED_HEAP
+    align(heapptr);
+    if (heapptr+size < heapend)
+    {
+        rv = heapptr;
+        heapptr += size;
+    }
+    else
+       rv = 0;
+#else
+    rv = malloc(size);
+#endif
+    if (rv == 0 && size) as_abort(NOMEMEORY);
+    return rv;
+}
+
+
+void *asrealloc(void *oldptr, unsigned int size)
+{
+    void * rv;
+#ifdef USE_FIXED_HEAP
+    if (oldptr == 0) return asalloc(size);
+
+    if ((char*)oldptr+size < heapend)
+    {
+        heapptr = (char*)oldptr + size;
+        rv = oldptr;
+    }
+    else
+        rv = 0;
+#else
+    rv = realloc(oldptr, size);
+#endif
+
+    if (rv == 0) as_abort(NOMEMEORY);
+    return rv;
+}
+
diff --git a/Applications/as09/as.c b/Applications/as09/as.c
new file mode 100644 (file)
index 0000000..70ca16e
--- /dev/null
@@ -0,0 +1,337 @@
+/* as.c - assembler */
+
+/*
+  usage: as source [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] [-guw]
+  in any order (but no repeated file options)
+*/
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "byteord.h"
+#include "macro.h"
+#undef EXTERN
+#define EXTERN
+#include "file.h"
+#include "flag.h"
+#include "globvar.h"
+#include "version.h"
+
+char hexdigit[] = "0123456789ABCDEF";  /* XXX - ld uses lower case */
+
+static struct block_s hid_blockstak[MAXBLOCK]; /* block stack */
+static struct lc_s hid_lctab[NLOC];    /* location counter table */
+static struct if_s hid_ifstak[MAXBLOCK];       /* if stack */
+static struct schain_s hid_mcpar[MACPSIZ];     /* MACRO params */
+static struct macro_s hid_macstak[MAXBLOCK];   /* macro stack */
+static struct sym_s *hid_spt[SPTSIZ];  /* hash table */
+
+static char * binfilename = 0;
+static char * objfilename = 0;
+static int keep_bad_output = 0;
+
+static void initp1 P((void));
+static int my_creat P((char *name, char *message));
+static void process_args P((int argc, char **argv));
+static void summary P((fd_t fd));
+static void summ_number P((unsigned num));
+static void usage P((void));
+
+int main(int argc, char *argv[])
+{
+    init_heap();
+    initp1();
+    initp1p2();
+    inst_keywords();
+    initbin();
+    initobj();
+    initsource();
+    typeconv_init(INT_BIG_ENDIAN, LONG_BIG_ENDIAN);
+    as_warn.global = TRUE;             /* constant */
+    as_warn.semaphore = -1;
+    last_pass=1;
+    process_args(argc, argv);
+    initscan();
+    line_zero();
+
+    assemble();                        /* doesn't return, maybe use setjmp */
+
+    /* NOTREACHED */
+    return 0;
+}
+
+void as_abort(char *message)
+{
+    write(STDOUT, "as: ", 4);
+    write(STDOUT, message, strlen(message));
+    write(STDOUT, "\n", 1);
+    exit(1);
+}
+
+void finishup(void)
+{
+    bintrailer();
+    objtrailer();
+    if (list.global ||symgen)
+       gensym();               /* output to lstfil and/or symfil */
+    if (list.global ||toterr != 0 || totwarn != 0)
+       summary(lstfil);
+    if (lstfil != STDOUT && (toterr != 0 || totwarn != 0))
+       summary(STDOUT);
+    statistics();
+
+    /* If an output binary is in error remove it */
+    close(binfil); binfil=0;
+    close(objfil); objfil=0;
+    if (toterr != 0 && !keep_bad_output) 
+    {
+       if(binfilename) unlink(binfilename);
+       if(objfilename) unlink(objfilename);
+    }
+
+    exit(toterr != 0 ? 1 : 0); /* should close output files and check */
+}
+
+/* initialise constant nonzero values */
+
+static void initp1(void)
+{
+#ifdef I80386
+    idefsize = defsize = 2;    /* I think this is probably safer (RDB) */
+#endif
+#if 0
+    idefsize = defsize = sizeof (char *) > 2 ? 4 : 2;
+#endif
+    lctabtop = lctab + NLOC;
+    lstfil = STDOUT;
+    mapnum = 15;               /* default map number for symbol table */
+    spt_top = (spt = hid_spt) + SPTSIZ;
+}
+
+/* initialise nonzero values which start same each pass */
+
+void initp1p2(void)
+{
+    register struct lc_s *lcp;
+
+    dirty_pass = 0;
+    ifflag = TRUE;
+    pedata = UNDBIT;           /* program entry point not defined */
+    blockstak = hid_blockstak + MAXBLOCK;
+    ifstak = hid_ifstak + MAXIF;
+    macstak = hid_macstak + MAXMAC;
+    macptop = (macpar = hid_mcpar) + MACPSIZ;
+    lctabtop = (lcptr = lctab = hid_lctab) + NLOC;
+    for (lcp = lctab; lcp < lctabtop; ++lcp)
+    {
+       lcp->data = lcdata = RELBIT;    /* lc relocatable until 1st ORG */
+       lcp->lc = lc = 0;
+    }
+}
+
+void line_zero(void)
+{
+   if( textseg >= 0 )
+      ptext();
+}
+
+static int my_creat(char *name, char *message)
+{
+    int fd;
+
+#ifdef O_BINARY
+    if ((fd = open(name, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, CREAT_PERMS)) < 0 || fd > 255)
+#else
+    if ((fd = creat(name, CREAT_PERMS)) < 0 || fd > 255)
+#endif
+       as_abort(message);
+    return fd;
+}
+
+static void process_args(int argc, char *argv[])
+{
+    char *arg;
+    bool_t isnextarg;
+    char *nextarg = 0;
+    int opened_file = 0;
+    int flag_state;
+
+#ifdef I80386
+    setcpu(0xF);
+#endif
+    textseg = -1;
+
+    if (argc <= 1)
+       usage();
+    do
+    {
+       arg = *++argv;
+       if (arg[0] == '-' && arg[1] != '\0')
+       {
+           flag_state = 1;
+           if (arg[2] == '-' && arg[3] == 0 )
+              flag_state = 0;
+           else
+           if (arg[2] != 0)
+               usage();        /* no multiple options */
+           isnextarg = FALSE;
+           if (argc > 2)
+           {
+               nextarg = argv[1];
+               if (nextarg[0] != 0 && nextarg[0] != '-')
+                   isnextarg = TRUE;
+           }
+           switch (arg[1])
+           {
+           case 'v':
+              outfd = STDOUT;
+              writes("as86 version: ");
+#ifdef VERSION
+              writesn(VERSION);
+#else
+              writesn("Unknown!");
+#endif
+              exit(1);
+#ifdef I80386
+           case '0': case '1': case '2':
+               idefsize = defsize = 0x2;
+               setcpu(arg[1]-'0');
+               break;
+           case '3':
+               idefsize = defsize = 0x4;
+               setcpu(0xF);
+               break;
+           case 'a':
+               asld_compatible = flag_state;
+               break;
+#endif
+           case 'b':
+               if (!isnextarg || binfil != 0)
+                   usage();
+               binfil = my_creat(binfilename=nextarg, "error creating binary file");
+               binaryg = TRUE;
+               --argc;
+               ++argv;
+               break;
+           case 'g':
+               globals_only_in_obj = flag_state;
+               break;
+#ifdef I80386
+           case 'j':
+               jumps_long = flag_state;
+               break;
+           case 'O':
+               if( flag_state ) last_pass = 2;
+               else             last_pass = 1;
+               break;
+#endif
+           case 'l':
+               list.global = TRUE;
+               goto get_any_list_file;
+           case 'm':
+               maclist.global = TRUE;
+       get_any_list_file:
+               if (isnextarg)
+               {
+                   if (lstfil != STDOUT)
+                       usage();
+                   lstfil = my_creat(nextarg, "error creating list file");
+                   --argc;
+                   ++argv;
+               }
+               break;
+           case 'n':
+               if (!isnextarg)
+                   usage();
+               truefilename = nextarg;
+               --argc;
+               ++argv;
+               break;
+           case 'o':
+               if (!isnextarg || objfil != 0)
+                   usage();
+               objectg = TRUE;
+               objfil = my_creat(objfilename=nextarg, "error creating object file");
+               --argc;
+               ++argv;
+               break;
+           case 's':
+               if (!isnextarg || symfil != 0)
+                   usage();
+               symgen = TRUE;
+               symfil = my_creat(nextarg, "error creating symbol file");
+               --argc;
+               ++argv;
+               break;
+           case 't':
+               if (!isnextarg || binfil != 0)
+                   usage();
+               textseg = atoi(nextarg); if(textseg>0) textseg+=BSSLOC;
+               --argc;
+               ++argv;
+               break;
+           case 'u':
+               if( flag_state ) inidata = IMPBIT | SEGM;
+               else             inidata = 0;
+               break;
+           case 'w':
+               if( flag_state ) as_warn.semaphore = -1;
+               else             as_warn.semaphore = 0;
+               break;
+           case 'k':
+               keep_bad_output = 1;
+               break;
+           default:
+               usage();        /* bad option */
+           }
+       }
+       else if (infil != 0)
+           usage();            /* no multiple sources */
+       else
+       {
+           if (strlen(arg) > FILNAMLEN)
+               as_abort("source file name too long");
+           infiln = infil0 = 1;
+           infil = open_input(strcpy(filnamptr, arg));
+           opened_file = 1;
+       }
+    }
+    while (--argc != 1);
+    if( !opened_file )
+    {
+       infiln = infil0 = 1;
+       infil = open_input(strcpy(filnamptr, "-"));
+    }
+#ifdef I80386
+    origcpuid = cpuid;
+#endif
+    inidata = (~binaryg & inidata) | (RELBIT | UNDBIT);
+}                              /* IMPBIT from inidata unless binaryg */
+
+static void summary(int fd)
+{
+    outfd = fd;
+    writenl();
+    summ_number(toterr);
+    writesn(" errors");
+    summ_number(totwarn);
+    writesn(" warnings");
+}
+
+static void summ_number(unsigned num)
+{
+    /* format number like line numbers */
+    char buf[16];
+    *build_number(num, LINUM_LEN, buf) = 0;
+    writes(buf);
+}
+
+static void usage(void)
+{
+    as_abort(
+#ifdef I80386
+"usage: as [-03agjuwO] [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] src");
+#else
+    "usage: as [-guw] [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] src");
+#endif
+}
diff --git a/Applications/as09/as86_encap.sh b/Applications/as09/as86_encap.sh
new file mode 100644 (file)
index 0000000..cba2b3c
--- /dev/null
@@ -0,0 +1,124 @@
+#!/bin/sh -
+#
+# This file is simply an example of what can be done using the new binary
+# and symbol table output functions. As shown it can be used to produce
+# a C file containing the encapsulated binary of the assembly, plus any
+# public symbols in the source are accessable to the C program.
+#
+# Use it in a makefile:
+#
+# .s.v:
+#      as86_encap $*.s $*.v $*_ $(AS86FLAGS)
+#
+
+[ $# -lt 2 ] && {
+   echo "Usage: `basename $0` infile outfile prefix [as86 opts]" 1>&2
+   exit 1
+}
+
+trap "rm -f _$$.* ; exit 99" 1 2 3 15 
+
+LIBDIR='%%LIBDIR%%'    # Set by make install
+BINDIR='%%BINDIR%%'    # Set by make install
+
+# If the one set by install fails then try a couple of others.
+[ -x "$LIBDIR/as86" ] || LIBDIR="`dirname $0`"
+[ -x "$LIBDIR/as86" ] || LIBDIR="$BINDIR"
+[ -x "$LIBDIR/as86" ] || LIBDIR="`dirname $0`/../lib"
+[ -x "$LIBDIR/as86" ] || LIBDIR=/usr/bin
+
+IFILE="$1"
+OFILE="$2"
+PREFIX="`basename $IFILE .s`_"
+
+shift ; shift
+if [ $# -ge 1 ]
+then case "$1" in 
+     -* ) ;; 
+     [A-Za-z_]* ) PREFIX="$1"
+                  shift
+                 ;;
+     esac
+fi
+RV=0
+
+$LIBDIR/as86 "$@" "$IFILE" -b _$$.bin -s _$$.sym || RV=$?
+
+echo '#ifndef __ASSEMBLY__'     > _$$.0
+echo                           >> _$$.0
+echo '#else'                    > _$$.3
+echo                           >> _$$.3
+echo '#endif'                   > _$$.5
+
+[ "$RV" = 0 ] && {
+  (
+    sort _$$.sym
+    echo %%%%
+    od -v -t uC _$$.bin
+  ) | \
+  awk -v prefix=$PREFIX -v ofile=_$$ ' BEGIN{
+       sname = prefix "start";
+       sn_file= ofile ".1";
+       bn_file= ofile ".2";
+       as_file= ofile ".4";
+    }
+    /^%%%%$/ { flg++; 
+       if( flg == 1 )
+       {
+         if( !started )
+         {
+            printf "#define %s 0\n", sname > sn_file;
+            printf "%s = 0\n", sname > as_file;
+         }
+
+         printf "static char %sdata[] = {\n", prefix >bn_file;
+          bincount=0;
+       }
+       next;
+    }
+    flg==0 {
+       if(NF == 0) next;
+       if( substr($2,1,4) == "0000" ) $2=substr($2,5);
+       if( $1 == "+" && $4 == "$start" )
+       {
+          printf "#define %s 0x%s\n", sname, $2 > sn_file;
+          printf "%s = $%s\n", sname, $2 > as_file;
+         started = 1;
+       }
+       else if( substr($3, 1, 1) == "E" && $4 != "start" && $4 != "size" && $4 != "data" )
+       {
+          printf "#define %s%s 0x%s\n", prefix, $4, $2 > sn_file;
+          printf "%s%s = $%s\n", prefix, $4, $2 > as_file;
+       }
+       next;
+    }
+    flg==1 {
+        if(NF == 0) next;
+       printf "   " > bn_file;
+       for(i=2;i<=NF;i++) {
+          if( $i >= 32 && $i < 127 && $i != 39 && $i != 92 )
+             printf("\047%c\047,", $i) > bn_file;
+          else
+             printf("%3d,", $i) > bn_file;
+          bincount++;
+       }
+       printf "\n" > bn_file;
+    }
+    END {
+       printf "};\n\n" > bn_file;
+       printf "#define %ssize %d\n\n", prefix, bincount > sn_file;
+       printf "%ssize = $%04x\n\n", prefix, bincount > as_file;
+    }
+  '
+  RV=$?
+}
+
+[ "$RV" = 0 ] && {
+   if [ "X$OFILE" = "X-" ]
+   then cat _$$.[0-9]
+   else cat _$$.[0-9] > "$OFILE" || RV=$?
+   fi
+}
+
+rm -f _$$.*
+exit $RV
diff --git a/Applications/as09/as86_to_data b/Applications/as09/as86_to_data
new file mode 100644 (file)
index 0000000..d53e500
--- /dev/null
@@ -0,0 +1,94 @@
+#!/bin/sh -
+#
+# This file is simply an example of what can be done using the new binary
+# and symbol table output functions. It produces a byte array with the
+# symbols in the object as array references within it.
+#
+# The output is a Linux OMAGIC binary created by ld86 -N, this means the
+# object can be linked directly to C-functions created by the same GCC that
+# compiled ld86.
+#
+# Use it in a makefile:
+#
+# .s86.o:
+#      as86_to_data $*.s86 $*.o $(AS86FLAGS)
+#
+
+[ $# -lt 2 ] && {
+   echo "Usage: `basename $0` infile outfile [as86 opts]" 1>&2
+   exit 1
+}
+
+trap "rm -f _$$.* ; exit 99" 1 2 3 15 
+
+LIBDIR='%%LIBDIR%%'    # Set by make install
+[ -d "$LIBDIR" ] || LIBDIR='%%BINDIR%%'
+[ -d "$LIBDIR" ] || LIBDIR=/usr/bin
+
+IFILE="$1"
+OFILE="$2"
+
+shift ; shift
+RV=0
+
+$LIBDIR/as86 "$@" "$IFILE" -b _$$.bin -s _$$.sym || RV=$?
+
+[ "$RV" = 0 ] && {
+  (
+    cat _$$.sym
+    echo %%%%
+    od -v -t uC _$$.bin
+    echo %%%%
+  ) | \
+  awk > _$$.v ' BEGIN{
+       startaddr="";
+       printf ".text\n.data\n";
+    }
+    /^%%%%$/ { flg++; 
+       next;
+    }
+    flg==0 {
+       if(NF == 0) next;
+       if( substr($2,1,4) == "0000" ) $2=substr($2,5);
+       if( $1 == "+" && $4 == "$start" )
+       {
+         if( $2 != "0000" ) startaddr=" - $" $2;
+       }
+       else if( substr($3, 1, 1) == "E" && $4 != "start" && $4 != "size" && $4 != "data" )
+       {
+          printf "export _%s\n", $4
+          printf "_%s = * + $%s%s\n\n", $4, $2, startaddr;
+       }
+       next;
+    }
+    flg==1 {
+        if(NF <= 1) next;
+       printf "  .byte ";
+       for(i=2;i<NF;i++) printf("%3d,", $i);
+                         printf("%3d", $NF);
+       printf "\n";
+    }
+  '
+  RV=$?
+}
+
+[ "$RV" = 0 ] || { rm -f _$$.* ; exit $RV ; }
+
+# If you want to see the assembler.
+# cp _$$.v `basename $2 .o`.asm
+
+$LIBDIR/as86 -o _$$.o86 _$$.v || RV=$?
+
+[ "$RV" = 0 ] || { rm -f _$$.* ; exit $RV ; }
+
+$LIBDIR/ld86 -r -N _$$.o86 -o _$$.o || RV=$?
+
+[ "$RV" = 0 ] || { rm -f _$$.* ; exit $RV ; }
+
+if [ "X$OFILE" = "X-" ]
+then cat _$$.o
+else mv -f _$$.o "$OFILE" || RV=$?
+fi
+
+rm -f _$$.*
+exit $RV
diff --git a/Applications/as09/asm/calljmp.asm b/Applications/as09/asm/calljmp.asm
new file mode 100644 (file)
index 0000000..36a6ea4
--- /dev/null
@@ -0,0 +1,70 @@
+       CALL    0x10:0x20       ; not implemented
+       CALL    AL;             ; illeg
+       CALL    DS              ; illeg
+
+       CALL    REL16
+
+       CALL    AX
+       CALL    BX
+       CALL    CX
+       CALL    DX
+       CALL    SP
+       CALL    BP
+       CALL    SI
+       CALL    DI
+
+       CALL    BYTE [BX]       ; illeg
+       CALL    [BX]
+       CALL    WORD [BX]
+
+       USE32
+       CALL    REL32
+
+       USE16
+       CALL    EAX
+       CALL    EBX
+       CALL    ECX
+       CALL    EDX
+       CALL    ESP
+       CALL    EBP
+       CALL    ESI
+       CALL    EDI
+
+       CALL    DWORD [BX]
+
+       JMP     0x10:0x20       ; not implemented
+       JMP     AL;             ; illeg
+       JMP     DS              ; illeg
+
+       JMP     REL16
+
+       JMP     AX
+       JMP     BX
+       JMP     CX
+       JMP     DX
+       JMP     SP
+       JMP     BP
+       JMP     SI
+       JMP     DI
+
+       JMP     BYTE [BX]       ; illeg
+       JMP     [BX]
+       JMP     WORD [BX]
+
+       USE32
+       JMP     REL32
+
+       USE16
+       JMP     EAX
+       JMP     EBX
+       JMP     ECX
+       JMP     EDX
+       JMP     ESP
+       JMP     EBP
+       JMP     ESI
+       JMP     EDI
+
+       JMP     DWORD [BX]
+
+REL16:
+REL32:
diff --git a/Applications/as09/asm/ea.asm b/Applications/as09/asm/ea.asm
new file mode 100644 (file)
index 0000000..8717a73
--- /dev/null
@@ -0,0 +1,109 @@
+       MOV     AX,[BX+SI]
+       MOV     AX,[BX+DI]
+       MOV     AX,[BP+SI]
+       MOV     AX,[BP+DI]
+       MOV     AX,[SI]
+       MOV     AX,[DI]
+       MOV     AX,[0x1234]
+       MOV     AX,[BX]
+
+       MOV     AX,[BX+SI+0x12]
+       MOV     AX,[BX+DI+0x12]
+       MOV     AX,[BP+SI+0x12]
+       MOV     AX,[BP+DI+0x12]
+       MOV     AX,[SI+0x12]
+       MOV     AX,[DI+0x12]
+       MOV     AX,[BP+0x12]
+       MOV     AX,[BX+0x12]
+
+       MOV     AX,[BX+SI+0x1234]
+       MOV     AX,[BX+DI+0x1234]
+       MOV     AX,[BP+SI+0x1234]
+       MOV     AX,[BP+DI+0x1234]
+       MOV     AX,[SI+0x1234]
+       MOV     AX,[DI+0x1234]
+       MOV     AX,[BP+0x1234]
+       MOV     AX,[BX+0x1234]
+
+       MOV     AL,AL
+       MOV     AL,AH
+       MOV     AL,BL
+       MOV     AL,BH
+       MOV     AL,CL
+       MOV     AL,CH
+       MOV     AL,DL
+       MOV     AL,DH
+
+       MOV     AX,AX
+       MOV     AX,CX
+       MOV     AX,DX
+       MOV     AX,BX
+       MOV     AX,SP
+       MOV     AX,BP
+       MOV     AX,SI
+       MOV     AX,DI
+
+       MOV     AX,[EAX]
+       MOV     AX,[ECX]
+       MOV     AX,[EDX]
+       MOV     AX,[EBX]
+
+       MOV     AX,[0x12345678]
+       MOV     AX,[ESI]
+       MOV     AX,[EDI]
+
+       MOV     AX,[EAX+0x12]
+       MOV     AX,[ECX+0x12]
+       MOV     AX,[EDX+0x12]
+       MOV     AX,[EBX+0x12]
+
+       MOV     AX,[EBP+0x12]
+       MOV     AX,[ESI+0x12]
+       MOV     AX,[EDI+0x12]
+
+       MOV     AX,[EAX+0x12345678]
+       MOV     AX,[ECX+0x12345678]
+       MOV     AX,[EDX+0x12345678]
+       MOV     AX,[EBX+0x12345678]
+
+       MOV     AX,[EBP+0x12345678]
+       MOV     AX,[ESI+0x12345678]
+       MOV     AX,[EDI+0x12345678]
+
+       MOV     EAX,EAX
+       MOV     EAX,ECX
+       MOV     EAX,EDX
+       MOV     EAX,EBX
+       MOV     EAX,ESP
+       MOV     EAX,EBP
+       MOV     EAX,ESI
+       MOV     EAX,EDI
+
+       MOV     AX,[EAX+ESI*2]
+       MOV     AX,[ECX+ESI*2]
+       MOV     AX,[EDX+ESI*2]
+       MOV     AX,[EBX+ESI*2]
+       MOV     AX,[ESP+ESI*2]
+       MOV     AX,[ESI*2+0x12345678]
+       MOV     AX,[ESI+ESI*2]
+       MOV     AX,[EDI+ESI*2]
+
+       MOV     AX,[EAX+ESI*2+0x12]
+       MOV     AX,[ECX+ESI*2+0x12]
+       MOV     AX,[EDX+ESI*2+0x12]
+       MOV     AX,[EBX+ESI*2+0x12]
+       MOV     AX,[ESP+ESI*2+0x12]
+       MOV     AX,[ESP+0x12]
+       MOV     AX,[EBP+ESI*2+0x12]
+       MOV     AX,[ESI+ESI*2+0x12]
+       MOV     AX,[EDI+ESI*2+0x12]
+
+       MOV     AX,[EAX+ESI*2+0x12345678]
+       MOV     AX,[ECX+ESI*2+0x12345678]
+       MOV     AX,[EDX+ESI*2+0x12345678]
+       MOV     AX,[EBX+ESI*2+0x12345678]
+       MOV     AX,[ESP+ESI*2+0x12345678]
+       MOV     AX,[ESP+0x12345678]
+       MOV     AX,[EBP+ESI*2+0x12345678]
+       MOV     AX,[ESI+ESI*2+0x12345678]
+       MOV     AX,[EDI+ESI*2+0x12345678]
diff --git a/Applications/as09/asm/each.asm b/Applications/as09/asm/each.asm
new file mode 100644 (file)
index 0000000..ceb5e32
--- /dev/null
@@ -0,0 +1,211 @@
+aaa
+aad
+aam
+aas
+adc    bx,[esi*4]
+add    bx,[esi*4]
+and    bx,[esi*4]
+arpl   [esi*4],bx
+bound  bx,[esi*4]
+bsf    bx,[esi*4]
+bsr    bx,[esi*4]
+bswap  ebx
+bt     [esi*4],bx
+btc    [esi*4],bx
+btr    [esi*4],bx
+bts    [esi*4],bx
+call   [esi*4]
+cbw
+cwde
+clc
+cld
+cli
+clts
+cmc
+cmp    bx,[esi*4]
+cmpsb
+cmpsw
+cmpsd
+cmpxchg        [esi*4],bx
+cwd
+cdq
+daa
+das
+dec    [esi*4]
+div    [esi*4]
+enter  0x200,3
+hlt
+idiv   [esi*4]
+imul   [esi*4]
+in     al,0x20
+inc    [esi*4]
+insb
+insw
+insd
+int    0x20
+into
+invd
+invlpg [esi*4]
+iret
+iretd
+jnz    many
+many:
+jmp    [esi*4]
+lahf
+lar    bx,[esi*4]
+lea    bx,[esi*4]
+leave
+lgdt   [esi*4]
+lidt   [esi*4]
+lds    bx,[esi*4]
+les    bx,[esi*4]
+lfs    bx,[esi*4]
+lgs    bx,[esi*4]
+lss    bx,[esi*4]
+lldt   [esi*4]
+lmsw   [esi*4]
+lock
+lodsb
+lodsw
+lodsd
+loop   alot
+alot:
+lsl    bx,[esi*4]
+ltr    [esi*4]
+mov    ax,[esi*4]
+mov    bx,[esi*4]
+mov    cr0,eax
+movsb
+movsw
+movsd
+movsx  bx,byte [esi*4]
+movzx  bx,byte [esi*4]
+mul    [esi*4]
+neg    [esi*4]
+nop
+not    [esi*4]
+or     bx,[esi*4]
+out    0x20,al
+outsb
+outsw
+outsd
+pop    [esi*4]
+popa
+popad
+popf
+popfd
+push   [esi*4]
+pusha
+pushad
+pushf
+pushfd
+rcl    [esi*4],1
+rcr    [esi*4],1
+rol    [esi*4],1
+ror    [esi*4],1
+rep
+ins
+rep
+lock
+outs
+rep
+movs
+rep
+cmps
+rep
+dseg
+stos
+rep
+scas
+repe
+seg ss
+ins
+repe
+outs
+repe
+lock
+seg ss
+movs
+repe
+cmps
+repe
+stos
+repe
+seg ss
+seg cs
+fseg
+scas
+repz
+lock
+lock
+ins
+repz
+outs
+repz
+movs
+repz
+cmps
+repz
+stos
+repz
+scas
+repne
+scas
+repne
+cmps
+repnz
+scas
+repnz
+cmps
+repnz
+lock
+cmps
+repnz
+seg ss
+cmps
+repnz
+cseg
+cmps
+repnz
+seg ss
+lock
+cmps
+repnz
+lock
+cseg
+cmps
+ret
+retf
+sahf
+sal    [esi*4],1
+sar    [esi*4],1
+shl    [esi*4],1
+shr    [esi*4],1
+sbb    bx,[esi*4]
+scasb
+scasw
+scasd
+setnz  byte [esi*4]
+sgdt   [esi*4]
+sidt   [esi*4]
+shld   [esi*4],bx,1
+shrd   [esi*4],bx,1
+sldt   [esi*4]
+smsw   [esi*4]
+stc
+std
+sti
+stosb
+stosw
+stosd
+str    [esi*4]
+sub    bx,[esi*4]
+test   bx,[esi*4]
+verr   [esi*4]
+verw   [esi*4]
+wait
+wbinvd
+xadd   [esi*4],bx
+xchg   bx,[esi*4]
+xlat
+xor    bx,[esi*4]
diff --git a/Applications/as09/asm/easlow.as b/Applications/as09/asm/easlow.as
new file mode 100644 (file)
index 0000000..75d71e2
--- /dev/null
@@ -0,0 +1,1219 @@
+       MOV     AL,[0]
+       MOV     AH,[1]
+       MOV     BL,[-1]         ; illeg
+       MOV     BH,[127]
+       MOV     CL,[-128]       ; illeg
+       MOV     CH,[128]
+       MOV     DL,[-129]       ; illeg
+       MOV     DH,[32767]
+       MOV     AL,[-32768]     ; illeg
+       MOV     AH,[32768]
+       MOV     BL,[-32769]     ; illeg
+       MOV     BH,[$7FFFFFFF]  ; illeg
+       MOV     CL,[$80000000]  ; illeg
+
+       MOV     AL,AL
+       MOV     AL,AH
+       MOV     AL,BL
+       MOV     AL,BH
+       MOV     AL,CL
+       MOV     AL,CH
+       MOV     AL,DL
+       MOV     AL,DH
+
+       MOV     AL,AX           ; illeg
+       MOV     AL,BX           ; illeg
+       MOV     AL,CX           ; illeg
+       MOV     AL,DX           ; illeg
+       MOV     AL,BP           ; illeg
+       MOV     AL,DI           ; illeg
+       MOV     AL,SI           ; illeg
+       MOV     AL,SP           ; illeg
+
+       MOV     AH,AL
+       MOV     AH,AH
+       MOV     AH,BL
+       MOV     AH,BH
+       MOV     AH,CL
+       MOV     AH,CH
+       MOV     AH,DL
+       MOV     AH,DH
+
+       MOV     AH,AX           ; illeg
+       MOV     AH,BX           ; illeg
+       MOV     AH,CX           ; illeg
+       MOV     AH,DX           ; illeg
+       MOV     AH,BP           ; illeg
+       MOV     AH,DI           ; illeg
+       MOV     AH,SI           ; illeg
+       MOV     AH,SP           ; illeg
+
+       MOV     BL,AL
+       MOV     BL,AH
+       MOV     BL,BL
+       MOV     BL,BH
+       MOV     BL,CL
+       MOV     BL,CH
+       MOV     BL,DL
+       MOV     BL,DH
+
+       MOV     BL,AX           ; illeg
+       MOV     BL,BX           ; illeg
+       MOV     BL,CX           ; illeg
+       MOV     BL,DX           ; illeg
+       MOV     BL,BP           ; illeg
+       MOV     BL,DI           ; illeg
+       MOV     BL,SI           ; illeg
+       MOV     BL,SP           ; illeg
+
+       MOV     BH,AL
+       MOV     BH,AH
+       MOV     BH,BL
+       MOV     BH,BH
+       MOV     BH,CL
+       MOV     BH,CH
+       MOV     BH,DL
+       MOV     BH,DH
+
+       MOV     BH,AX           ; illeg
+       MOV     BH,BX           ; illeg
+       MOV     BH,CX           ; illeg
+       MOV     BH,DX           ; illeg
+       MOV     BH,BP           ; illeg
+       MOV     BH,DI           ; illeg
+       MOV     BH,SI           ; illeg
+       MOV     BH,SP           ; illeg
+
+       MOV     CL,AL
+       MOV     CL,AH
+       MOV     CL,BL
+       MOV     CL,BH
+       MOV     CL,CL
+       MOV     CL,CH
+       MOV     CL,DL
+       MOV     CL,DH
+
+       MOV     CL,AX           ; illeg
+       MOV     CL,BX           ; illeg
+       MOV     CL,CX           ; illeg
+       MOV     CL,DX           ; illeg
+       MOV     CL,BP           ; illeg
+       MOV     CL,DI           ; illeg
+       MOV     CL,SI           ; illeg
+       MOV     CL,SP           ; illeg
+
+       MOV     CH,AL
+       MOV     CH,AH
+       MOV     CH,BL
+       MOV     CH,BH
+       MOV     CH,CL
+       MOV     CH,CH
+       MOV     CH,DL
+       MOV     CH,DH
+
+       MOV     CH,AX           ; illeg
+       MOV     CH,BX           ; illeg
+       MOV     CH,CX           ; illeg
+       MOV     CH,DX           ; illeg
+       MOV     CH,BP           ; illeg
+       MOV     CH,DI           ; illeg
+       MOV     CH,SI           ; illeg
+       MOV     CH,SP           ; illeg
+
+       MOV     DL,AL
+       MOV     DL,AH
+       MOV     DL,BL
+       MOV     DL,BH
+       MOV     DL,CL
+       MOV     DL,CH
+       MOV     DL,DL
+       MOV     DL,DH
+
+       MOV     DL,AX           ; illeg
+       MOV     DL,BX           ; illeg
+       MOV     DL,CX           ; illeg
+       MOV     DL,DX           ; illeg
+       MOV     DL,BP           ; illeg
+       MOV     DL,DI           ; illeg
+       MOV     DL,SI           ; illeg
+       MOV     DL,SP           ; illeg
+
+       MOV     DH,AL
+       MOV     DH,AH
+       MOV     DH,BL
+       MOV     DH,BH
+       MOV     DH,CL
+       MOV     DH,CH
+       MOV     DH,DL
+       MOV     DH,DH
+
+       MOV     DH,AX           ; illeg
+       MOV     DH,BX           ; illeg
+       MOV     DH,CX           ; illeg
+       MOV     DH,DX           ; illeg
+       MOV     DH,BP           ; illeg
+       MOV     DH,DI           ; illeg
+       MOV     DH,SI           ; illeg
+       MOV     DH,SP           ; illeg
+
+       MOV     AL,[AL]         ; illeg
+       MOV     AH,[AH]         ; illeg
+       MOV     BL,[BL]         ; illeg
+       MOV     BH,[BH]         ; illeg
+       MOV     CL,[CL]         ; illeg
+       MOV     CH,[CH]         ; illeg
+       MOV     DL,[DL]         ; illeg
+       MOV     DH,[DH]         ; illeg
+
+       MOV     AL,[AX]         ; illeg
+       MOV     AH,[BX]
+       MOV     BL,[CX]         ; illeg
+       MOV     BH,[DX]         ; illeg
+       MOV     CL,[BP]
+       MOV     CH,[DI]
+       MOV     DL,[SI]
+       MOV     DH,[SP]         ; illeg
+
+       MOV     AL,[AX+1]       ; illeg
+       MOV     AH,[BX+1]
+       MOV     BL,[CX+1]       ; illeg
+       MOV     BH,[DX+1]       ; illeg
+       MOV     CL,[BP+1]
+       MOV     CH,[DI+1]
+       MOV     DL,[SI+1]
+       MOV     DH,[SP+1]       ; illeg
+
+       MOV     AL,[AX-1]       ; illeg
+       MOV     AH,[BX-1]
+       MOV     BL,[CX-1]       ; illeg
+       MOV     BH,[DX-1]       ; illeg
+       MOV     CL,[BP-1]
+       MOV     CH,[DI-1]
+       MOV     DL,[SI-1]
+       MOV     DH,[SP-1]       ; illeg
+
+       MOV     AL,[AX+127]     ; illeg
+       MOV     AH,[BX+127]
+       MOV     BL,[CX+127]     ; illeg
+       MOV     BH,[DX+127]     ; illeg
+       MOV     CL,[BP+127]
+       MOV     CH,[DI+127]
+       MOV     DL,[SI+127]
+       MOV     DH,[SP+127]     ; illeg
+
+       MOV     AL,[AX-128]     ; illeg
+       MOV     AH,[BX-128]
+       MOV     BL,[CX-128]     ; illeg
+       MOV     BH,[DX-128]     ; illeg
+       MOV     CL,[BP-128]
+       MOV     CH,[DI-128]
+       MOV     DL,[SI-128]
+       MOV     DH,[SP-128]     ; illeg
+
+       MOV     AL,[AX+128]     ; illeg
+       MOV     AH,[BX+128]
+       MOV     BL,[CX+128]     ; illeg
+       MOV     BH,[DX+128]     ; illeg
+       MOV     CL,[BP+128]
+       MOV     CH,[DI+128]
+       MOV     DL,[SI+128]
+       MOV     DH,[SP+128]     ; illeg
+
+       MOV     AL,[AX-129]     ; illeg
+       MOV     AH,[BX-129]
+       MOV     BL,[CX-129]     ; illeg
+       MOV     BH,[DX-129]     ; illeg
+       MOV     CL,[BP-129]
+       MOV     CH,[DI-129]
+       MOV     DL,[SI-129]
+       MOV     DH,[SP-129]     ; illeg
+
+       MOV     AL,[AX+32767]   ; illeg
+       MOV     AH,[BX+32767]
+       MOV     BL,[CX+32767]   ; illeg
+       MOV     BH,[DX+32767]   ; illeg
+       MOV     CL,[BP+32767]
+       MOV     CH,[DI+32767]
+       MOV     DL,[SI+32767]
+       MOV     DH,[SP+32767]   ; illeg
+
+       MOV     AL,[AX-32768]   ; illeg
+       MOV     AH,[BX-32768]
+       MOV     BL,[CX-32768]   ; illeg
+       MOV     BH,[DX-32768]   ; illeg
+       MOV     CL,[BP-32768]
+       MOV     CH,[DI-32768]
+       MOV     DL,[SI-32768]
+       MOV     DH,[SP-32768]   ; illeg
+
+       MOV     AL,[AX+32768]   ; illeg
+       MOV     AH,[BX+32768]
+       MOV     BL,[CX+32768]   ; illeg
+       MOV     BH,[DX+32768]   ; illeg
+       MOV     CL,[BP+32768]
+       MOV     CH,[DI+32768]
+       MOV     DL,[SI+32768]
+       MOV     DH,[SP+32768]   ; illeg
+
+       MOV     AL,[AX-32769]   ; illeg
+       MOV     AH,[BX-32769]
+       MOV     BL,[CX-32769]   ; illeg
+       MOV     BH,[DX-32769]   ; illeg
+       MOV     CL,[BP-32769]
+       MOV     CH,[DI-32769]
+       MOV     DL,[SI-32769]
+       MOV     DH,[SP-32769]   ; illeg
+
+       MOV     AL,[AX+$7FFFFFFF]       ; illeg
+       MOV     AH,[BX+$7FFFFFFF]       ; illeg (bounds)
+       MOV     BL,[CX+$7FFFFFFF]       ; illeg
+       MOV     BH,[DX+$7FFFFFFF]       ; illeg
+       MOV     CL,[BP+$7FFFFFFF]       ; illeg (bounds)
+       MOV     CH,[DI+$7FFFFFFF]       ; illeg (bounds)
+       MOV     DL,[SI+$7FFFFFFF]       ; illeg (bounds)
+       MOV     DH,[SP+$7FFFFFFF]       ; illeg
+
+       MOV     AL,[AX-$80000000]       ; illeg
+       MOV     AH,[BX-$80000000]       ; illeg (bounds)
+       MOV     BL,[CX-$80000000]       ; illeg
+       MOV     BH,[DX-$80000000]       ; illeg
+       MOV     CL,[BP-$80000000]       ; illeg (bounds)
+       MOV     CH,[DI-$80000000]       ; illeg (bounds)
+       MOV     DL,[SI-$80000000]       ; illeg (bounds)
+       MOV     DH,[SP-$80000000]       ; illeg
+
+       MOV     AL,[AX+AX]      ; illeg
+       MOV     AH,[AX+BX]      ; illeg
+       MOV     BL,[AX+CX]      ; illeg
+       MOV     BH,[AX+DX]      ; illeg
+       MOV     CL,[AX+BP]      ; illeg
+       MOV     CH,[AX+DI]      ; illeg
+       MOV     DL,[AX+SI]      ; illeg
+       MOV     DH,[AX+SP]      ; illeg
+
+       MOV     AL,[BX+AX]      ; illeg
+       MOV     AH,[BX+BX]      ; illeg
+       MOV     BL,[BX+CX]      ; illeg
+       MOV     BH,[BX+DX]      ; illeg
+       MOV     CL,[BX+BP]      ; illeg
+       MOV     CH,[BX+DI]
+       MOV     DL,[BX+SI]
+       MOV     DH,[BX+SP]      ; illeg
+
+       MOV     AL,[CX+AX]      ; illeg
+       MOV     AH,[CX+BX]      ; illeg
+       MOV     BL,[CX+CX]      ; illeg
+       MOV     BH,[CX+DX]      ; illeg
+       MOV     CL,[CX+BP]      ; illeg
+       MOV     CH,[CX+DI]      ; illeg
+       MOV     DL,[CX+SI]      ; illeg
+       MOV     DH,[CX+SP]      ; illeg
+
+       MOV     AL,[DX+AX]      ; illeg
+       MOV     AH,[DX+BX]      ; illeg
+       MOV     BL,[DX+CX]      ; illeg
+       MOV     BH,[DX+DX]      ; illeg
+       MOV     CL,[DX+BP]      ; illeg
+       MOV     CH,[DX+DI]      ; illeg
+       MOV     DL,[DX+SI]      ; illeg
+       MOV     DH,[DX+SP]      ; illeg
+
+       MOV     AL,[BP+AX]      ; illeg
+       MOV     AH,[BP+BX]      ; illeg
+       MOV     BL,[BP+CX]      ; illeg
+       MOV     BH,[BP+DX]      ; illeg
+       MOV     CL,[BP+BP]      ; illeg
+       MOV     CH,[BP+DI]
+       MOV     DL,[BP+SI]
+       MOV     DH,[BP+SP]      ; illeg
+
+       MOV     AL,[DI+AX]      ; illeg
+       MOV     AH,[DI+BX]
+       MOV     BL,[DI+CX]      ; illeg
+       MOV     BH,[DI+DX]      ; illeg
+       MOV     CL,[DI+BP]
+       MOV     CH,[DI+DI]      ; illeg
+       MOV     DL,[DI+SI]      ; illeg
+       MOV     DH,[DI+SP]      ; illeg
+
+       MOV     AL,[SI+AX]      ; illeg
+       MOV     AH,[SI+BX]
+       MOV     BL,[SI+CX]      ; illeg
+       MOV     BH,[SI+DX]      ; illeg
+       MOV     CL,[SI+BP]
+       MOV     CH,[SI+DI]      ; illeg
+       MOV     DL,[SI+SI]      ; illeg
+       MOV     DH,[SI+SP]      ; illeg
+
+       MOV     AL,[SP+AX]      ; illeg
+       MOV     AH,[SP+BX]      ; illeg
+       MOV     BL,[SP+CX]      ; illeg
+       MOV     BH,[SP+DX]      ; illeg
+       MOV     CL,[SP+BP]      ; illeg
+       MOV     CH,[SP+DI]      ; illeg
+       MOV     DL,[SP+SI]      ; illeg
+       MOV     DH,[SP+SP]      ; illeg
+
+       MOV     AL,[AX+AX+1]    ; illeg
+       MOV     AH,[AX+BX+1]    ; illeg
+       MOV     BL,[AX+CX+1]    ; illeg
+       MOV     BH,[AX+DX+1]    ; illeg
+       MOV     CL,[AX+BP+1]    ; illeg
+       MOV     CH,[AX+DI+1]    ; illeg
+       MOV     DL,[AX+SI+1]    ; illeg
+       MOV     DH,[AX+SP+1]    ; illeg
+
+       MOV     AL,[BX+AX+1]    ; illeg
+       MOV     AH,[BX+BX+1]    ; illeg
+       MOV     BL,[BX+CX+1]    ; illeg
+       MOV     BH,[BX+DX+1]    ; illeg
+       MOV     CL,[BX+BP+1]    ; illeg
+       MOV     CH,[BX+DI+1]
+       MOV     DL,[BX+SI+1]
+       MOV     DH,[BX+SP+1]    ; illeg
+
+       MOV     AL,[CX+AX+1]    ; illeg
+       MOV     AH,[CX+BX+1]    ; illeg
+       MOV     BL,[CX+CX+1]    ; illeg
+       MOV     BH,[CX+DX+1]    ; illeg
+       MOV     CL,[CX+BP+1]    ; illeg
+       MOV     CH,[CX+DI+1]    ; illeg
+       MOV     DL,[CX+SI+1]    ; illeg
+       MOV     DH,[CX+SP+1]    ; illeg
+
+       MOV     AL,[DX+AX+1]    ; illeg
+       MOV     AH,[DX+BX+1]    ; illeg
+       MOV     BL,[DX+CX+1]    ; illeg
+       MOV     BH,[DX+DX+1]    ; illeg
+       MOV     CL,[DX+BP+1]    ; illeg
+       MOV     CH,[DX+DI+1]    ; illeg
+       MOV     DL,[DX+SI+1]    ; illeg
+       MOV     DH,[DX+SP+1]    ; illeg
+
+       MOV     AL,[BP+AX+1]    ; illeg
+       MOV     AH,[BP+BX+1]    ; illeg
+       MOV     BL,[BP+CX+1]    ; illeg
+       MOV     BH,[BP+DX+1]    ; illeg
+       MOV     CL,[BP+BP+1]    ; illeg
+       MOV     CH,[BP+DI+1]
+       MOV     DL,[BP+SI+1]
+       MOV     DH,[BP+SP+1]    ; illeg
+
+       MOV     AL,[DI+AX+1]    ; illeg
+       MOV     AH,[DI+BX+1]
+       MOV     BL,[DI+CX+1]    ; illeg
+       MOV     BH,[DI+DX+1]    ; illeg
+       MOV     CL,[DI+BP+1]
+       MOV     CH,[DI+DI+1]    ; illeg
+       MOV     DL,[DI+SI+1]    ; illeg
+       MOV     DH,[DI+SP+1]    ; illeg
+
+       MOV     AL,[SI+AX+1]    ; illeg
+       MOV     AH,[SI+BX+1]
+       MOV     BL,[SI+CX+1]    ; illeg
+       MOV     BH,[SI+DX+1]    ; illeg
+       MOV     CL,[SI+BP+1]
+       MOV     CH,[SI+DI+1]    ; illeg
+       MOV     DL,[SI+SI+1]    ; illeg
+       MOV     DH,[SI+SP+1]    ; illeg
+
+       MOV     AL,[SP+AX+1]    ; illeg
+       MOV     AH,[SP+BX+1]    ; illeg
+       MOV     BL,[SP+CX+1]    ; illeg
+       MOV     BH,[SP+DX+1]    ; illeg
+       MOV     CL,[SP+BP+1]    ; illeg
+       MOV     CH,[SP+DI+1]    ; illeg
+       MOV     DL,[SP+SI+1]    ; illeg
+       MOV     DH,[SP+SP+1]    ; illeg
+
+       MOV     AL,[AX+AX-1]    ; illeg
+       MOV     AH,[AX+BX-1]    ; illeg
+       MOV     BL,[AX+CX-1]    ; illeg
+       MOV     BH,[AX+DX-1]    ; illeg
+       MOV     CL,[AX+BP-1]    ; illeg
+       MOV     CH,[AX+DI-1]    ; illeg
+       MOV     DL,[AX+SI-1]    ; illeg
+       MOV     DH,[AX+SP-1]    ; illeg
+
+       MOV     AL,[BX+AX-1]    ; illeg
+       MOV     AH,[BX+BX-1]    ; illeg
+       MOV     BL,[BX+CX-1]    ; illeg
+       MOV     BH,[BX+DX-1]    ; illeg
+       MOV     CL,[BX+BP-1]    ; illeg
+       MOV     CH,[BX+DI-1]
+       MOV     DL,[BX+SI-1]
+       MOV     DH,[BX+SP-1]    ; illeg
+
+       MOV     AL,[CX+AX-1]    ; illeg
+       MOV     AH,[CX+BX-1]    ; illeg
+       MOV     BL,[CX+CX-1]    ; illeg
+       MOV     BH,[CX+DX-1]    ; illeg
+       MOV     CL,[CX+BP-1]    ; illeg
+       MOV     CH,[CX+DI-1]    ; illeg
+       MOV     DL,[CX+SI-1]    ; illeg
+       MOV     DH,[CX+SP-1]    ; illeg
+
+       MOV     AL,[DX+AX-1]    ; illeg
+       MOV     AH,[DX+BX-1]    ; illeg
+       MOV     BL,[DX+CX-1]    ; illeg
+       MOV     BH,[DX+DX-1]    ; illeg
+       MOV     CL,[DX+BP-1]    ; illeg
+       MOV     CH,[DX+DI-1]    ; illeg
+       MOV     DL,[DX+SI-1]    ; illeg
+       MOV     DH,[DX+SP-1]    ; illeg
+
+       MOV     AL,[BP+AX-1]    ; illeg
+       MOV     AH,[BP+BX-1]    ; illeg
+       MOV     BL,[BP+CX-1]    ; illeg
+       MOV     BH,[BP+DX-1]    ; illeg
+       MOV     CL,[BP+BP-1]    ; illeg
+       MOV     CH,[BP+DI-1]
+       MOV     DL,[BP+SI-1]
+       MOV     DH,[BP+SP-1]    ; illeg
+
+       MOV     AL,[DI+AX-1]    ; illeg
+       MOV     AH,[DI+BX-1]
+       MOV     BL,[DI+CX-1]    ; illeg
+       MOV     BH,[DI+DX-1]    ; illeg
+       MOV     CL,[DI+BP-1]
+       MOV     CH,[DI+DI-1]    ; illeg
+       MOV     DL,[DI+SI-1]    ; illeg
+       MOV     DH,[DI+SP-1]    ; illeg
+
+       MOV     AL,[SI+AX-1]    ; illeg
+       MOV     AH,[SI+BX-1]
+       MOV     BL,[SI+CX-1]    ; illeg
+       MOV     BH,[SI+DX-1]    ; illeg
+       MOV     CL,[SI+BP-1]
+       MOV     CH,[SI+DI-1]    ; illeg
+       MOV     DL,[SI+SI-1]    ; illeg
+       MOV     DH,[SI+SP-1]    ; illeg
+
+       MOV     AL,[SP+AX-1]    ; illeg
+       MOV     AH,[SP+BX-1]    ; illeg
+       MOV     BL,[SP+CX-1]    ; illeg
+       MOV     BH,[SP+DX-1]    ; illeg
+       MOV     CL,[SP+BP-1]    ; illeg
+       MOV     CH,[SP+DI-1]    ; illeg
+       MOV     DL,[SP+SI-1]    ; illeg
+       MOV     DH,[SP+SP-1]    ; illeg
+
+       MOV     AL,[AX+AX+127]  ; illeg
+       MOV     AH,[AX+BX+127]  ; illeg
+       MOV     BL,[AX+CX+127]  ; illeg
+       MOV     BH,[AX+DX+127]  ; illeg
+       MOV     CL,[AX+BP+127]  ; illeg
+       MOV     CH,[AX+DI+127]  ; illeg
+       MOV     DL,[AX+SI+127]  ; illeg
+       MOV     DH,[AX+SP+127]  ; illeg
+
+       MOV     AL,[BX+AX+127]  ; illeg
+       MOV     AH,[BX+BX+127]  ; illeg
+       MOV     BL,[BX+CX+127]  ; illeg
+       MOV     BH,[BX+DX+127]  ; illeg
+       MOV     CL,[BX+BP+127]  ; illeg
+       MOV     CH,[BX+DI+127]
+       MOV     DL,[BX+SI+127]
+       MOV     DH,[BX+SP+127]  ; illeg
+
+       MOV     AL,[CX+AX+127]  ; illeg
+       MOV     AH,[CX+BX+127]  ; illeg
+       MOV     BL,[CX+CX+127]  ; illeg
+       MOV     BH,[CX+DX+127]  ; illeg
+       MOV     CL,[CX+BP+127]  ; illeg
+       MOV     CH,[CX+DI+127]  ; illeg
+       MOV     DL,[CX+SI+127]  ; illeg
+       MOV     DH,[CX+SP+127]  ; illeg
+
+       MOV     AL,[DX+AX+127]  ; illeg
+       MOV     AH,[DX+BX+127]  ; illeg
+       MOV     BL,[DX+CX+127]  ; illeg
+       MOV     BH,[DX+DX+127]  ; illeg
+       MOV     CL,[DX+BP+127]  ; illeg
+       MOV     CH,[DX+DI+127]  ; illeg
+       MOV     DL,[DX+SI+127]  ; illeg
+       MOV     DH,[DX+SP+127]  ; illeg
+
+       MOV     AL,[BP+AX+127]  ; illeg
+       MOV     AH,[BP+BX+127]  ; illeg
+       MOV     BL,[BP+CX+127]  ; illeg
+       MOV     BH,[BP+DX+127]  ; illeg
+       MOV     CL,[BP+BP+127]  ; illeg
+       MOV     CH,[BP+DI+127]
+       MOV     DL,[BP+SI+127]
+       MOV     DH,[BP+SP+127]  ; illeg
+
+       MOV     AL,[DI+AX+127]  ; illeg
+       MOV     AH,[DI+BX+127]
+       MOV     BL,[DI+CX+127]  ; illeg
+       MOV     BH,[DI+DX+127]  ; illeg
+       MOV     CL,[DI+BP+127]
+       MOV     CH,[DI+DI+127]  ; illeg
+       MOV     DL,[DI+SI+127]  ; illeg
+       MOV     DH,[DI+SP+127]  ; illeg
+
+       MOV     AL,[SI+AX+127]  ; illeg
+       MOV     AH,[SI+BX+127]
+       MOV     BL,[SI+CX+127]  ; illeg
+       MOV     BH,[SI+DX+127]  ; illeg
+       MOV     CL,[SI+BP+127]
+       MOV     CH,[SI+DI+127]  ; illeg
+       MOV     DL,[SI+SI+127]  ; illeg
+       MOV     DH,[SI+SP+127]  ; illeg
+
+       MOV     AL,[SP+AX+127]  ; illeg
+       MOV     AH,[SP+BX+127]  ; illeg
+       MOV     BL,[SP+CX+127]  ; illeg
+       MOV     BH,[SP+DX+127]  ; illeg
+       MOV     CL,[SP+BP+127]  ; illeg
+       MOV     CH,[SP+DI+127]  ; illeg
+       MOV     DL,[SP+SI+127]  ; illeg
+       MOV     DH,[SP+SP+127]  ; illeg
+
+       MOV     AL,[AX+AX-128]  ; illeg
+       MOV     AH,[AX+BX-128]  ; illeg
+       MOV     BL,[AX+CX-128]  ; illeg
+       MOV     BH,[AX+DX-128]  ; illeg
+       MOV     CL,[AX+BP-128]  ; illeg
+       MOV     CH,[AX+DI-128]  ; illeg
+       MOV     DL,[AX+SI-128]  ; illeg
+       MOV     DH,[AX+SP-128]  ; illeg
+
+       MOV     AL,[BX+AX-128]  ; illeg
+       MOV     AH,[BX+BX-128]  ; illeg
+       MOV     BL,[BX+CX-128]  ; illeg
+       MOV     BH,[BX+DX-128]  ; illeg
+       MOV     CL,[BX+BP-128]  ; illeg
+       MOV     CH,[BX+DI-128]
+       MOV     DL,[BX+SI-128]
+       MOV     DH,[BX+SP-128]  ; illeg
+
+       MOV     AL,[CX+AX-128]  ; illeg
+       MOV     AH,[CX+BX-128]  ; illeg
+       MOV     BL,[CX+CX-128]  ; illeg
+       MOV     BH,[CX+DX-128]  ; illeg
+       MOV     CL,[CX+BP-128]  ; illeg
+       MOV     CH,[CX+DI-128]  ; illeg
+       MOV     DL,[CX+SI-128]  ; illeg
+       MOV     DH,[CX+SP-128]  ; illeg
+
+       MOV     AL,[DX+AX-128]  ; illeg
+       MOV     AH,[DX+BX-128]  ; illeg
+       MOV     BL,[DX+CX-128]  ; illeg
+       MOV     BH,[DX+DX-128]  ; illeg
+       MOV     CL,[DX+BP-128]  ; illeg
+       MOV     CH,[DX+DI-128]  ; illeg
+       MOV     DL,[DX+SI-128]  ; illeg
+       MOV     DH,[DX+SP-128]  ; illeg
+
+       MOV     AL,[BP+AX-128]  ; illeg
+       MOV     AH,[BP+BX-128]  ; illeg
+       MOV     BL,[BP+CX-128]  ; illeg
+       MOV     BH,[BP+DX-128]  ; illeg
+       MOV     CL,[BP+BP-128]  ; illeg
+       MOV     CH,[BP+DI-128]
+       MOV     DL,[BP+SI-128]
+       MOV     DH,[BP+SP-128]  ; illeg
+
+       MOV     AL,[DI+AX-128]  ; illeg
+       MOV     AH,[DI+BX-128]
+       MOV     BL,[DI+CX-128]  ; illeg
+       MOV     BH,[DI+DX-128]  ; illeg
+       MOV     CL,[DI+BP-128]
+       MOV     CH,[DI+DI-128]  ; illeg
+       MOV     DL,[DI+SI-128]  ; illeg
+       MOV     DH,[DI+SP-128]  ; illeg
+
+       MOV     AL,[SI+AX-128]  ; illeg
+       MOV     AH,[SI+BX-128]
+       MOV     BL,[SI+CX-128]  ; illeg
+       MOV     BH,[SI+DX-128]  ; illeg
+       MOV     CL,[SI+BP-128]
+       MOV     CH,[SI+DI-128]  ; illeg
+       MOV     DL,[SI+SI-128]  ; illeg
+       MOV     DH,[SI+SP-128]  ; illeg
+
+       MOV     AL,[SP+AX-128]  ; illeg
+       MOV     AH,[SP+BX-128]  ; illeg
+       MOV     BL,[SP+CX-128]  ; illeg
+       MOV     BH,[SP+DX-128]  ; illeg
+       MOV     CL,[SP+BP-128]  ; illeg
+       MOV     CH,[SP+DI-128]  ; illeg
+       MOV     DL,[SP+SI-128]  ; illeg
+       MOV     DH,[SP+SP-128]  ; illeg
+
+       MOV     AL,[AX+AX+128]  ; illeg
+       MOV     AH,[AX+BX+128]  ; illeg
+       MOV     BL,[AX+CX+128]  ; illeg
+       MOV     BH,[AX+DX+128]  ; illeg
+       MOV     CL,[AX+BP+128]  ; illeg
+       MOV     CH,[AX+DI+128]  ; illeg
+       MOV     DL,[AX+SI+128]  ; illeg
+       MOV     DH,[AX+SP+128]  ; illeg
+
+       MOV     AL,[BX+AX+128]  ; illeg
+       MOV     AH,[BX+BX+128]  ; illeg
+       MOV     BL,[BX+CX+128]  ; illeg
+       MOV     BH,[BX+DX+128]  ; illeg
+       MOV     CL,[BX+BP+128]  ; illeg
+       MOV     CH,[BX+DI+128]
+       MOV     DL,[BX+SI+128]
+       MOV     DH,[BX+SP+128]  ; illeg
+
+       MOV     AL,[CX+AX+128]  ; illeg
+       MOV     AH,[CX+BX+128]  ; illeg
+       MOV     BL,[CX+CX+128]  ; illeg
+       MOV     BH,[CX+DX+128]  ; illeg
+       MOV     CL,[CX+BP+128]  ; illeg
+       MOV     CH,[CX+DI+128]  ; illeg
+       MOV     DL,[CX+SI+128]  ; illeg
+       MOV     DH,[CX+SP+128]  ; illeg
+
+       MOV     AL,[DX+AX+128]  ; illeg
+       MOV     AH,[DX+BX+128]  ; illeg
+       MOV     BL,[DX+CX+128]  ; illeg
+       MOV     BH,[DX+DX+128]  ; illeg
+       MOV     CL,[DX+BP+128]  ; illeg
+       MOV     CH,[DX+DI+128]  ; illeg
+       MOV     DL,[DX+SI+128]  ; illeg
+       MOV     DH,[DX+SP+128]  ; illeg
+
+       MOV     AL,[BP+AX+128]  ; illeg
+       MOV     AH,[BP+BX+128]  ; illeg
+       MOV     BL,[BP+CX+128]  ; illeg
+       MOV     BH,[BP+DX+128]  ; illeg
+       MOV     CL,[BP+BP+128]  ; illeg
+       MOV     CH,[BP+DI+128]
+       MOV     DL,[BP+SI+128]
+       MOV     DH,[BP+SP+128]  ; illeg
+
+       MOV     AL,[DI+AX+128]  ; illeg
+       MOV     AH,[DI+BX+128]
+       MOV     BL,[DI+CX+128]  ; illeg
+       MOV     BH,[DI+DX+128]  ; illeg
+       MOV     CL,[DI+BP+128]
+       MOV     CH,[DI+DI+128]  ; illeg
+       MOV     DL,[DI+SI+128]  ; illeg
+       MOV     DH,[DI+SP+128]  ; illeg
+
+       MOV     AL,[SI+AX+128]  ; illeg
+       MOV     AH,[SI+BX+128]
+       MOV     BL,[SI+CX+128]  ; illeg
+       MOV     BH,[SI+DX+128]  ; illeg
+       MOV     CL,[SI+BP+128]
+       MOV     CH,[SI+DI+128]  ; illeg
+       MOV     DL,[SI+SI+128]  ; illeg
+       MOV     DH,[SI+SP+128]  ; illeg
+
+       MOV     AL,[SP+AX+128]  ; illeg
+       MOV     AH,[SP+BX+128]  ; illeg
+       MOV     BL,[SP+CX+128]  ; illeg
+       MOV     BH,[SP+DX+128]  ; illeg
+       MOV     CL,[SP+BP+128]  ; illeg
+       MOV     CH,[SP+DI+128]  ; illeg
+       MOV     DL,[SP+SI+128]  ; illeg
+       MOV     DH,[SP+SP+128]  ; illeg
+
+       MOV     AL,[AX+AX-129]  ; illeg
+       MOV     AH,[AX+BX-129]  ; illeg
+       MOV     BL,[AX+CX-129]  ; illeg
+       MOV     BH,[AX+DX-129]  ; illeg
+       MOV     CL,[AX+BP-129]  ; illeg
+       MOV     CH,[AX+DI-129]  ; illeg
+       MOV     DL,[AX+SI-129]  ; illeg
+       MOV     DH,[AX+SP-129]  ; illeg
+
+       MOV     AL,[BX+AX-129]  ; illeg
+       MOV     AH,[BX+BX-129]  ; illeg
+       MOV     BL,[BX+CX-129]  ; illeg
+       MOV     BH,[BX+DX-129]  ; illeg
+       MOV     CL,[BX+BP-129]  ; illeg
+       MOV     CH,[BX+DI-129]
+       MOV     DL,[BX+SI-129]
+       MOV     DH,[BX+SP-129]  ; illeg
+
+       MOV     AL,[CX+AX-129]  ; illeg
+       MOV     AH,[CX+BX-129]  ; illeg
+       MOV     BL,[CX+CX-129]  ; illeg
+       MOV     BH,[CX+DX-129]  ; illeg
+       MOV     CL,[CX+BP-129]  ; illeg
+       MOV     CH,[CX+DI-129]  ; illeg
+       MOV     DL,[CX+SI-129]  ; illeg
+       MOV     DH,[CX+SP-129]  ; illeg
+
+       MOV     AL,[DX+AX-129]  ; illeg
+       MOV     AH,[DX+BX-129]  ; illeg
+       MOV     BL,[DX+CX-129]  ; illeg
+       MOV     BH,[DX+DX-129]  ; illeg
+       MOV     CL,[DX+BP-129]  ; illeg
+       MOV     CH,[DX+DI-129]  ; illeg
+       MOV     DL,[DX+SI-129]  ; illeg
+       MOV     DH,[DX+SP-129]  ; illeg
+
+       MOV     AL,[BP+AX-129]  ; illeg
+       MOV     AH,[BP+BX-129]  ; illeg
+       MOV     BL,[BP+CX-129]  ; illeg
+       MOV     BH,[BP+DX-129]  ; illeg
+       MOV     CL,[BP+BP-129]  ; illeg
+       MOV     CH,[BP+DI-129]
+       MOV     DL,[BP+SI-129]
+       MOV     DH,[BP+SP-129]  ; illeg
+
+       MOV     AL,[DI+AX-129]  ; illeg
+       MOV     AH,[DI+BX-129]
+       MOV     BL,[DI+CX-129]  ; illeg
+       MOV     BH,[DI+DX-129]  ; illeg
+       MOV     CL,[DI+BP-129]
+       MOV     CH,[DI+DI-129]  ; illeg
+       MOV     DL,[DI+SI-129]  ; illeg
+       MOV     DH,[DI+SP-129]  ; illeg
+
+       MOV     AL,[SI+AX-129]  ; illeg
+       MOV     AH,[SI+BX-129]
+       MOV     BL,[SI+CX-129]  ; illeg
+       MOV     BH,[SI+DX-129]  ; illeg
+       MOV     CL,[SI+BP-129]
+       MOV     CH,[SI+DI-129]  ; illeg
+       MOV     DL,[SI+SI-129]  ; illeg
+       MOV     DH,[SI+SP-129]  ; illeg
+
+       MOV     AL,[SP+AX-129]  ; illeg
+       MOV     AH,[SP+BX-129]  ; illeg
+       MOV     BL,[SP+CX-129]  ; illeg
+       MOV     BH,[SP+DX-129]  ; illeg
+       MOV     CL,[SP+BP-129]  ; illeg
+       MOV     CH,[SP+DI-129]  ; illeg
+       MOV     DL,[SP+SI-129]  ; illeg
+       MOV     DH,[SP+SP-129]  ; illeg
+
+       MOV     AL,[AX+AX+32767]        ; illeg
+       MOV     AH,[AX+BX+32767]        ; illeg
+       MOV     BL,[AX+CX+32767]        ; illeg
+       MOV     BH,[AX+DX+32767]        ; illeg
+       MOV     CL,[AX+BP+32767]        ; illeg
+       MOV     CH,[AX+DI+32767]        ; illeg
+       MOV     DL,[AX+SI+32767]        ; illeg
+       MOV     DH,[AX+SP+32767]        ; illeg
+
+       MOV     AL,[BX+AX+32767]        ; illeg
+       MOV     AH,[BX+BX+32767]        ; illeg
+       MOV     BL,[BX+CX+32767]        ; illeg
+       MOV     BH,[BX+DX+32767]        ; illeg
+       MOV     CL,[BX+BP+32767]        ; illeg
+       MOV     CH,[BX+DI+32767]
+       MOV     DL,[BX+SI+32767]
+       MOV     DH,[BX+SP+32767]        ; illeg
+
+       MOV     AL,[CX+AX+32767]        ; illeg
+       MOV     AH,[CX+BX+32767]        ; illeg
+       MOV     BL,[CX+CX+32767]        ; illeg
+       MOV     BH,[CX+DX+32767]        ; illeg
+       MOV     CL,[CX+BP+32767]        ; illeg
+       MOV     CH,[CX+DI+32767]        ; illeg
+       MOV     DL,[CX+SI+32767]        ; illeg
+       MOV     DH,[CX+SP+32767]        ; illeg
+
+       MOV     AL,[DX+AX+32767]        ; illeg
+       MOV     AH,[DX+BX+32767]        ; illeg
+       MOV     BL,[DX+CX+32767]        ; illeg
+       MOV     BH,[DX+DX+32767]        ; illeg
+       MOV     CL,[DX+BP+32767]        ; illeg
+       MOV     CH,[DX+DI+32767]        ; illeg
+       MOV     DL,[DX+SI+32767]        ; illeg
+       MOV     DH,[DX+SP+32767]        ; illeg
+
+       MOV     AL,[BP+AX+32767]        ; illeg
+       MOV     AH,[BP+BX+32767]        ; illeg
+       MOV     BL,[BP+CX+32767]        ; illeg
+       MOV     BH,[BP+DX+32767]        ; illeg
+       MOV     CL,[BP+BP+32767]        ; illeg
+       MOV     CH,[BP+DI+32767]
+       MOV     DL,[BP+SI+32767]
+       MOV     DH,[BP+SP+32767]        ; illeg
+
+       MOV     AL,[DI+AX+32767]        ; illeg
+       MOV     AH,[DI+BX+32767]
+       MOV     BL,[DI+CX+32767]        ; illeg
+       MOV     BH,[DI+DX+32767]        ; illeg
+       MOV     CL,[DI+BP+32767]
+       MOV     CH,[DI+DI+32767]        ; illeg
+       MOV     DL,[DI+SI+32767]        ; illeg
+       MOV     DH,[DI+SP+32767]        ; illeg
+
+       MOV     AL,[SI+AX+32767]        ; illeg
+       MOV     AH,[SI+BX+32767]
+       MOV     BL,[SI+CX+32767]        ; illeg
+       MOV     BH,[SI+DX+32767]        ; illeg
+       MOV     CL,[SI+BP+32767]
+       MOV     CH,[SI+DI+32767]        ; illeg
+       MOV     DL,[SI+SI+32767]        ; illeg
+       MOV     DH,[SI+SP+32767]        ; illeg
+
+       MOV     AL,[SP+AX+32767]        ; illeg
+       MOV     AH,[SP+BX+32767]        ; illeg
+       MOV     BL,[SP+CX+32767]        ; illeg
+       MOV     BH,[SP+DX+32767]        ; illeg
+       MOV     CL,[SP+BP+32767]        ; illeg
+       MOV     CH,[SP+DI+32767]        ; illeg
+       MOV     DL,[SP+SI+32767]        ; illeg
+       MOV     DH,[SP+SP+32767]        ; illeg
+
+       MOV     AL,[AX+AX-32768]        ; illeg
+       MOV     AH,[AX+BX-32768]        ; illeg
+       MOV     BL,[AX+CX-32768]        ; illeg
+       MOV     BH,[AX+DX-32768]        ; illeg
+       MOV     CL,[AX+BP-32768]        ; illeg
+       MOV     CH,[AX+DI-32768]        ; illeg
+       MOV     DL,[AX+SI-32768]        ; illeg
+       MOV     DH,[AX+SP-32768]        ; illeg
+
+       MOV     AL,[BX+AX-32768]        ; illeg
+       MOV     AH,[BX+BX-32768]        ; illeg
+       MOV     BL,[BX+CX-32768]        ; illeg
+       MOV     BH,[BX+DX-32768]        ; illeg
+       MOV     CL,[BX+BP-32768]        ; illeg
+       MOV     CH,[BX+DI-32768]
+       MOV     DL,[BX+SI-32768]
+       MOV     DH,[BX+SP-32768]        ; illeg
+
+       MOV     AL,[CX+AX-32768]        ; illeg
+       MOV     AH,[CX+BX-32768]        ; illeg
+       MOV     BL,[CX+CX-32768]        ; illeg
+       MOV     BH,[CX+DX-32768]        ; illeg
+       MOV     CL,[CX+BP-32768]        ; illeg
+       MOV     CH,[CX+DI-32768]        ; illeg
+       MOV     DL,[CX+SI-32768]        ; illeg
+       MOV     DH,[CX+SP-32768]        ; illeg
+
+       MOV     AL,[DX+AX-32768]        ; illeg
+       MOV     AH,[DX+BX-32768]        ; illeg
+       MOV     BL,[DX+CX-32768]        ; illeg
+       MOV     BH,[DX+DX-32768]        ; illeg
+       MOV     CL,[DX+BP-32768]        ; illeg
+       MOV     CH,[DX+DI-32768]        ; illeg
+       MOV     DL,[DX+SI-32768]        ; illeg
+       MOV     DH,[DX+SP-32768]        ; illeg
+
+       MOV     AL,[BP+AX-32768]        ; illeg
+       MOV     AH,[BP+BX-32768]        ; illeg
+       MOV     BL,[BP+CX-32768]        ; illeg
+       MOV     BH,[BP+DX-32768]        ; illeg
+       MOV     CL,[BP+BP-32768]        ; illeg
+       MOV     CH,[BP+DI-32768]
+       MOV     DL,[BP+SI-32768]
+       MOV     DH,[BP+SP-32768]        ; illeg
+
+       MOV     AL,[DI+AX-32768]        ; illeg
+       MOV     AH,[DI+BX-32768]
+       MOV     BL,[DI+CX-32768]        ; illeg
+       MOV     BH,[DI+DX-32768]        ; illeg
+       MOV     CL,[DI+BP-32768]
+       MOV     CH,[DI+DI-32768]        ; illeg
+       MOV     DL,[DI+SI-32768]        ; illeg
+       MOV     DH,[DI+SP-32768]        ; illeg
+
+       MOV     AL,[SI+AX-32768]        ; illeg
+       MOV     AH,[SI+BX-32768]
+       MOV     BL,[SI+CX-32768]        ; illeg
+       MOV     BH,[SI+DX-32768]        ; illeg
+       MOV     CL,[SI+BP-32768]
+       MOV     CH,[SI+DI-32768]        ; illeg
+       MOV     DL,[SI+SI-32768]        ; illeg
+       MOV     DH,[SI+SP-32768]        ; illeg
+
+       MOV     AL,[SP+AX-32768]        ; illeg
+       MOV     AH,[SP+BX-32768]        ; illeg
+       MOV     BL,[SP+CX-32768]        ; illeg
+       MOV     BH,[SP+DX-32768]        ; illeg
+       MOV     CL,[SP+BP-32768]        ; illeg
+       MOV     CH,[SP+DI-32768]        ; illeg
+       MOV     DL,[SP+SI-32768]        ; illeg
+       MOV     DH,[SP+SP-32768]        ; illeg
+
+       MOV     AL,[AX+AX+32768]        ; illeg
+       MOV     AH,[AX+BX+32768]        ; illeg
+       MOV     BL,[AX+CX+32768]        ; illeg
+       MOV     BH,[AX+DX+32768]        ; illeg
+       MOV     CL,[AX+BP+32768]        ; illeg
+       MOV     CH,[AX+DI+32768]        ; illeg
+       MOV     DL,[AX+SI+32768]        ; illeg
+       MOV     DH,[AX+SP+32768]        ; illeg
+
+       MOV     AL,[BX+AX+32768]        ; illeg
+       MOV     AH,[BX+BX+32768]        ; illeg
+       MOV     BL,[BX+CX+32768]        ; illeg
+       MOV     BH,[BX+DX+32768]        ; illeg
+       MOV     CL,[BX+BP+32768]        ; illeg
+       MOV     CH,[BX+DI+32768]
+       MOV     DL,[BX+SI+32768]
+       MOV     DH,[BX+SP+32768]        ; illeg
+
+       MOV     AL,[CX+AX+32768]        ; illeg
+       MOV     AH,[CX+BX+32768]        ; illeg
+       MOV     BL,[CX+CX+32768]        ; illeg
+       MOV     BH,[CX+DX+32768]        ; illeg
+       MOV     CL,[CX+BP+32768]        ; illeg
+       MOV     CH,[CX+DI+32768]        ; illeg
+       MOV     DL,[CX+SI+32768]        ; illeg
+       MOV     DH,[CX+SP+32768]        ; illeg
+
+       MOV     AL,[DX+AX+32768]        ; illeg
+       MOV     AH,[DX+BX+32768]        ; illeg
+       MOV     BL,[DX+CX+32768]        ; illeg
+       MOV     BH,[DX+DX+32768]        ; illeg
+       MOV     CL,[DX+BP+32768]        ; illeg
+       MOV     CH,[DX+DI+32768]        ; illeg
+       MOV     DL,[DX+SI+32768]        ; illeg
+       MOV     DH,[DX+SP+32768]        ; illeg
+
+       MOV     AL,[BP+AX+32768]        ; illeg
+       MOV     AH,[BP+BX+32768]        ; illeg
+       MOV     BL,[BP+CX+32768]        ; illeg
+       MOV     BH,[BP+DX+32768]        ; illeg
+       MOV     CL,[BP+BP+32768]        ; illeg
+       MOV     CH,[BP+DI+32768]
+       MOV     DL,[BP+SI+32768]
+       MOV     DH,[BP+SP+32768]        ; illeg
+
+       MOV     AL,[DI+AX+32768]        ; illeg
+       MOV     AH,[DI+BX+32768]
+       MOV     BL,[DI+CX+32768]        ; illeg
+       MOV     BH,[DI+DX+32768]        ; illeg
+       MOV     CL,[DI+BP+32768]
+       MOV     CH,[DI+DI+32768]        ; illeg
+       MOV     DL,[DI+SI+32768]        ; illeg
+       MOV     DH,[DI+SP+32768]        ; illeg
+
+       MOV     AL,[SI+AX+32768]        ; illeg
+       MOV     AH,[SI+BX+32768]
+       MOV     BL,[SI+CX+32768]        ; illeg
+       MOV     BH,[SI+DX+32768]        ; illeg
+       MOV     CL,[SI+BP+32768]
+       MOV     CH,[SI+DI+32768]        ; illeg
+       MOV     DL,[SI+SI+32768]        ; illeg
+       MOV     DH,[SI+SP+32768]        ; illeg
+
+       MOV     AL,[SP+AX+32768]        ; illeg
+       MOV     AH,[SP+BX+32768]        ; illeg
+       MOV     BL,[SP+CX+32768]        ; illeg
+       MOV     BH,[SP+DX+32768]        ; illeg
+       MOV     CL,[SP+BP+32768]        ; illeg
+       MOV     CH,[SP+DI+32768]        ; illeg
+       MOV     DL,[SP+SI+32768]        ; illeg
+       MOV     DH,[SP+SP+32768]        ; illeg
+
+       MOV     AL,[AX+AX-32769]        ; illeg
+       MOV     AH,[AX+BX-32769]        ; illeg
+       MOV     BL,[AX+CX-32769]        ; illeg
+       MOV     BH,[AX+DX-32769]        ; illeg
+       MOV     CL,[AX+BP-32769]        ; illeg
+       MOV     CH,[AX+DI-32769]        ; illeg
+       MOV     DL,[AX+SI-32769]        ; illeg
+       MOV     DH,[AX+SP-32769]        ; illeg
+
+       MOV     AL,[BX+AX-32769]        ; illeg
+       MOV     AH,[BX+BX-32769]        ; illeg
+       MOV     BL,[BX+CX-32769]        ; illeg
+       MOV     BH,[BX+DX-32769]        ; illeg
+       MOV     CL,[BX+BP-32769]        ; illeg
+       MOV     CH,[BX+DI-32769]
+       MOV     DL,[BX+SI-32769]
+       MOV     DH,[BX+SP-32769]        ; illeg
+
+       MOV     AL,[CX+AX-32769]        ; illeg
+       MOV     AH,[CX+BX-32769]        ; illeg
+       MOV     BL,[CX+CX-32769]        ; illeg
+       MOV     BH,[CX+DX-32769]        ; illeg
+       MOV     CL,[CX+BP-32769]        ; illeg
+       MOV     CH,[CX+DI-32769]        ; illeg
+       MOV     DL,[CX+SI-32769]        ; illeg
+       MOV     DH,[CX+SP-32769]        ; illeg
+
+       MOV     AL,[DX+AX-32769]        ; illeg
+       MOV     AH,[DX+BX-32769]        ; illeg
+       MOV     BL,[DX+CX-32769]        ; illeg
+       MOV     BH,[DX+DX-32769]        ; illeg
+       MOV     CL,[DX+BP-32769]        ; illeg
+       MOV     CH,[DX+DI-32769]        ; illeg
+       MOV     DL,[DX+SI-32769]        ; illeg
+       MOV     DH,[DX+SP-32769]        ; illeg
+
+       MOV     AL,[BP+AX-32769]        ; illeg
+       MOV     AH,[BP+BX-32769]        ; illeg
+       MOV     BL,[BP+CX-32769]        ; illeg
+       MOV     BH,[BP+DX-32769]        ; illeg
+       MOV     CL,[BP+BP-32769]        ; illeg
+       MOV     CH,[BP+DI-32769]
+       MOV     DL,[BP+SI-32769]
+       MOV     DH,[BP+SP-32769]        ; illeg
+
+       MOV     AL,[DI+AX-32769]        ; illeg
+       MOV     AH,[DI+BX-32769]
+       MOV     BL,[DI+CX-32769]        ; illeg
+       MOV     BH,[DI+DX-32769]        ; illeg
+       MOV     CL,[DI+BP-32769]
+       MOV     CH,[DI+DI-32769]        ; illeg
+       MOV     DL,[DI+SI-32769]        ; illeg
+       MOV     DH,[DI+SP-32769]        ; illeg
+
+       MOV     AL,[SI+AX-32769]        ; illeg
+       MOV     AH,[SI+BX-32769]
+       MOV     BL,[SI+CX-32769]        ; illeg
+       MOV     BH,[SI+DX-32769]        ; illeg
+       MOV     CL,[SI+BP-32769]
+       MOV     CH,[SI+DI-32769]        ; illeg
+       MOV     DL,[SI+SI-32769]        ; illeg
+       MOV     DH,[SI+SP-32769]        ; illeg
+
+       MOV     AL,[SP+AX-32769]        ; illeg
+       MOV     AH,[SP+BX-32769]        ; illeg
+       MOV     BL,[SP+CX-32769]        ; illeg
+       MOV     BH,[SP+DX-32769]        ; illeg
+       MOV     CL,[SP+BP-32769]        ; illeg
+       MOV     CH,[SP+DI-32769]        ; illeg
+       MOV     DL,[SP+SI-32769]        ; illeg
+       MOV     DH,[SP+SP-32769]        ; illeg
+
+       MOV     AL,[AX+AX+$7FFFFFFF]    ; illeg
+       MOV     AH,[AX+BX+$7FFFFFFF]    ; illeg
+       MOV     BL,[AX+CX+$7FFFFFFF]    ; illeg
+       MOV     BH,[AX+DX+$7FFFFFFF]    ; illeg
+       MOV     CL,[AX+BP+$7FFFFFFF]    ; illeg
+       MOV     CH,[AX+DI+$7FFFFFFF]    ; illeg
+       MOV     DL,[AX+SI+$7FFFFFFF]    ; illeg
+       MOV     DH,[AX+SP+$7FFFFFFF]    ; illeg
+
+       MOV     AL,[BX+AX+$7FFFFFFF]    ; illeg
+       MOV     AH,[BX+BX+$7FFFFFFF]    ; illeg
+       MOV     BL,[BX+CX+$7FFFFFFF]    ; illeg
+       MOV     BH,[BX+DX+$7FFFFFFF]    ; illeg
+       MOV     CL,[BX+BP+$7FFFFFFF]    ; illeg
+       MOV     CH,[BX+DI+$7FFFFFFF]    ; illeg (bounds)
+       MOV     DL,[BX+SI+$7FFFFFFF]    ; illeg (bounds)
+       MOV     DH,[BX+SP+$7FFFFFFF]    ; illeg
+
+       MOV     AL,[CX+AX+$7FFFFFFF]    ; illeg
+       MOV     AH,[CX+BX+$7FFFFFFF]    ; illeg
+       MOV     BL,[CX+CX+$7FFFFFFF]    ; illeg
+       MOV     BH,[CX+DX+$7FFFFFFF]    ; illeg
+       MOV     CL,[CX+BP+$7FFFFFFF]    ; illeg
+       MOV     CH,[CX+DI+$7FFFFFFF]    ; illeg
+       MOV     DL,[CX+SI+$7FFFFFFF]    ; illeg
+       MOV     DH,[CX+SP+$7FFFFFFF]    ; illeg
+
+       MOV     AL,[DX+AX+$7FFFFFFF]    ; illeg
+       MOV     AH,[DX+BX+$7FFFFFFF]    ; illeg
+       MOV     BL,[DX+CX+$7FFFFFFF]    ; illeg
+       MOV     BH,[DX+DX+$7FFFFFFF]    ; illeg
+       MOV     CL,[DX+BP+$7FFFFFFF]    ; illeg
+       MOV     CH,[DX+DI+$7FFFFFFF]    ; illeg
+       MOV     DL,[DX+SI+$7FFFFFFF]    ; illeg
+       MOV     DH,[DX+SP+$7FFFFFFF]    ; illeg
+
+       MOV     AL,[BP+AX+$7FFFFFFF]    ; illeg
+       MOV     AH,[BP+BX+$7FFFFFFF]    ; illeg
+       MOV     BL,[BP+CX+$7FFFFFFF]    ; illeg
+       MOV     BH,[BP+DX+$7FFFFFFF]    ; illeg
+       MOV     CL,[BP+BP+$7FFFFFFF]    ; illeg
+       MOV     CH,[BP+DI+$7FFFFFFF]    ; illeg (bounds)
+       MOV     DL,[BP+SI+$7FFFFFFF]    ; illeg (bounds)
+       MOV     DH,[BP+SP+$7FFFFFFF]    ; illeg
+
+       MOV     AL,[DI+AX+$7FFFFFFF]    ; illeg
+       MOV     AH,[DI+BX+$7FFFFFFF]    ; illeg (bounds)
+       MOV     BL,[DI+CX+$7FFFFFFF]    ; illeg
+       MOV     BH,[DI+DX+$7FFFFFFF]    ; illeg
+       MOV     CL,[DI+BP+$7FFFFFFF]    ; illeg (bounds)
+       MOV     CH,[DI+DI+$7FFFFFFF]    ; illeg
+       MOV     DL,[DI+SI+$7FFFFFFF]    ; illeg
+       MOV     DH,[DI+SP+$7FFFFFFF]    ; illeg
+
+       MOV     AL,[SI+AX+$7FFFFFFF]    ; illeg
+       MOV     AH,[SI+BX+$7FFFFFFF]    ; illeg (bounds)
+       MOV     BL,[SI+CX+$7FFFFFFF]    ; illeg
+       MOV     BH,[SI+DX+$7FFFFFFF]    ; illeg
+       MOV     CL,[SI+BP+$7FFFFFFF]    ; illeg (bounds)
+       MOV     CH,[SI+DI+$7FFFFFFF]    ; illeg
+       MOV     DL,[SI+SI+$7FFFFFFF]    ; illeg
+       MOV     DH,[SI+SP+$7FFFFFFF]    ; illeg
+
+       MOV     AL,[SP+AX+$7FFFFFFF]    ; illeg
+       MOV     AH,[SP+BX+$7FFFFFFF]    ; illeg
+       MOV     BL,[SP+CX+$7FFFFFFF]    ; illeg
+       MOV     BH,[SP+DX+$7FFFFFFF]    ; illeg
+       MOV     CL,[SP+BP+$7FFFFFFF]    ; illeg
+       MOV     CH,[SP+DI+$7FFFFFFF]    ; illeg
+       MOV     DL,[SP+SI+$7FFFFFFF]    ; illeg
+       MOV     DH,[SP+SP+$7FFFFFFF]    ; illeg
+
+       MOV     AL,[AX+AX-$80000000]    ; illeg
+       MOV     AH,[AX+BX-$80000000]    ; illeg
+       MOV     BL,[AX+CX-$80000000]    ; illeg
+       MOV     BH,[AX+DX-$80000000]    ; illeg
+       MOV     CL,[AX+BP-$80000000]    ; illeg
+       MOV     CH,[AX+DI-$80000000]    ; illeg
+       MOV     DL,[AX+SI-$80000000]    ; illeg
+       MOV     DH,[AX+SP-$80000000]    ; illeg
+
+       MOV     AL,[BX+AX-$80000000]    ; illeg
+       MOV     AH,[BX+BX-$80000000]    ; illeg
+       MOV     BL,[BX+CX-$80000000]    ; illeg
+       MOV     BH,[BX+DX-$80000000]    ; illeg
+       MOV     CL,[BX+BP-$80000000]    ; illeg
+       MOV     CH,[BX+DI-$80000000]    ; illeg (bounds)
+       MOV     DL,[BX+SI-$80000000]    ; illeg (bounds)
+       MOV     DH,[BX+SP-$80000000]    ; illeg
+
+       MOV     AL,[CX+AX-$80000000]    ; illeg
+       MOV     AH,[CX+BX-$80000000]    ; illeg
+       MOV     BL,[CX+CX-$80000000]    ; illeg
+       MOV     BH,[CX+DX-$80000000]    ; illeg
+       MOV     CL,[CX+BP-$80000000]    ; illeg
+       MOV     CH,[CX+DI-$80000000]    ; illeg
+       MOV     DL,[CX+SI-$80000000]    ; illeg
+       MOV     DH,[CX+SP-$80000000]    ; illeg
+
+       MOV     AL,[DX+AX-$80000000]    ; illeg
+       MOV     AH,[DX+BX-$80000000]    ; illeg
+       MOV     BL,[DX+CX-$80000000]    ; illeg
+       MOV     BH,[DX+DX-$80000000]    ; illeg
+       MOV     CL,[DX+BP-$80000000]    ; illeg
+       MOV     CH,[DX+DI-$80000000]    ; illeg
+       MOV     DL,[DX+SI-$80000000]    ; illeg
+       MOV     DH,[DX+SP-$80000000]    ; illeg
+
+       MOV     AL,[BP+AX-$80000000]    ; illeg
+       MOV     AH,[BP+BX-$80000000]    ; illeg
+       MOV     BL,[BP+CX-$80000000]    ; illeg
+       MOV     BH,[BP+DX-$80000000]    ; illeg
+       MOV     CL,[BP+BP-$80000000]    ; illeg
+       MOV     CH,[BP+DI-$80000000]    ; illeg (bounds)
+       MOV     DL,[BP+SI-$80000000]    ; illeg (bounds)
+       MOV     DH,[BP+SP-$80000000]    ; illeg
+
+       MOV     AL,[DI+AX-$80000000]    ; illeg
+       MOV     AH,[DI+BX-$80000000]    ; illeg (bounds)
+       MOV     BL,[DI+CX-$80000000]    ; illeg
+       MOV     BH,[DI+DX-$80000000]    ; illeg
+       MOV     CL,[DI+BP-$80000000]    ; illeg (bounds)
+       MOV     CH,[DI+DI-$80000000]    ; illeg
+       MOV     DL,[DI+SI-$80000000]    ; illeg
+       MOV     DH,[DI+SP-$80000000]    ; illeg
+
+       MOV     AL,[SI+AX-$80000000]    ; illeg
+       MOV     AH,[SI+BX-$80000000]    ; illeg (bounds)
+       MOV     BL,[SI+CX-$80000000]    ; illeg
+       MOV     BH,[SI+DX-$80000000]    ; illeg
+       MOV     CL,[SI+BP-$80000000]    ; illeg (bounds)
+       MOV     CH,[SI+DI-$80000000]    ; illeg
+       MOV     DL,[SI+SI-$80000000]    ; illeg
+       MOV     DH,[SI+SP-$80000000]    ; illeg
+
+       MOV     AL,[SP+AX-$80000000]    ; illeg
+       MOV     AH,[SP+BX-$80000000]    ; illeg
+       MOV     BL,[SP+CX-$80000000]    ; illeg
+       MOV     BH,[SP+DX-$80000000]    ; illeg
+       MOV     CL,[SP+BP-$80000000]    ; illeg
+       MOV     CH,[SP+DI-$80000000]    ; illeg
+       MOV     DL,[SP+SI-$80000000]    ; illeg
+       MOV     DH,[SP+SP-$80000000]    ; illeg
diff --git a/Applications/as09/asm/f.asm b/Applications/as09/asm/f.asm
new file mode 100644 (file)
index 0000000..c067bf9
--- /dev/null
@@ -0,0 +1,114 @@
+; [fadd fdiv fdivr fmul fsub fsubr] [mem4r mem8r st,st(i) st(i),st]
+       fadd    qword [ebx]
+       fadd    dword [ebx]
+       fadd    st,st(1)
+       fadd    st(1),st
+       fdiv    qword [ebx]
+       fdiv    dword [ebx]
+       fdiv    st,st(1)        ; special swapping for this
+
+; [faddp fdivp fdivrp fmulp fsubp fsubrp] st(i),st
+       faddp   st(1),st
+
+; [fbld fbstp] mem10r
+       fbld    tbyte [ebx]
+       fbstp   tbyte [ebx]
+
+; [fcom fcomp] [mem4r mem8r optional-st(i)]
+       fcom    dword [ebx]
+       fcom    qword [ebx]
+       fcom
+       fcom    st(1)
+
+; ffree st(i)
+       ffree   st(1)
+
+; [fucom fucomp fxch] optional-st(i)
+       fucom
+       fucom   st(1)
+
+; [fiadd ficom ficomp fidiv fidivr fimul fist fisub fisubr] [mem2i mem4i]
+       fiadd   word [ebx]
+       fiadd   dword [ebx]
+
+; [fild fistp] [mem2i mem4i mem8i]
+       fild    word [ebx]
+       fild    dword [ebx]
+       fild    qword [ebx]
+
+; [fld fstp] [mem4r mem8r mem10r st(i)]
+       fld     dword [ebx]
+       fld     qword [ebx]
+       fld     tbyte [ebx]
+       fld     st(1)
+
+; [fldcw fnstcw] mem2i
+       fldcw   word [ebx]
+       fnstcw  word [ebx]
+
+; [fldenv fnsave fnstenv frstor] mem
+       fldenv  [ebx]
+       fnsave  [ebx]
+       fnstenv [ebx]
+       frstor  [ebx]
+
+; fnstsw [mem2i ax]
+       fnstsw  word [ebx]
+       fnstsw  ax
+
+; fst [mem4r mem8r st(i)]
+       fst     dword [ebx]
+       fst     qword [ebx]
+       fst     st(1)
+
+; fstcw mem2i (wait)
+       fstcw   word [ebx]
+
+; fstsw [mem2i ax] (wait)
+       fstsw   word [ebx]
+       fstsw   ax
+
+; [fsave fstenv] mem (wait)
+       fsave   [ebx]
+       fstenv  [ebx]
+
+; [fxxx] (no operands)
+       fnop    ; D9D0
+       fchs    ; D9E0
+       fabs    ; D9E1
+       ftst    ; D9E4
+       fxam    ; D9E5
+       fld1    ; D9E8
+       fldl2t  ; D9E9
+       fldl2e  ; D9EA
+       fldpi   ; D9EB
+       fldlg2  ; D9EC
+       fldln2  ; D9ED
+       fldz    ; D9EE
+       f2xm1   ; D9F0
+       fyl2x   ; D9F1
+       fptan   ; D9F2
+       fpatan  ; D9F3
+       fxtract ; D9F4
+       fprem1  ; D9F5
+       fdecstp ; D9F6
+       fincstp ; D9F7
+       fprem   ; D9F8
+       fyl2xp1 ; D9F9
+       fsqrt   ; D9FA
+       fsincos ; D9FB
+       frndint ; D9FC
+       fscale  ; D9FD
+       fsin    ; D9FE
+       fcos    ; D9FF
+       fucompp ; DAE9
+       feni    ; 9BDBE0
+       fneni   ; DBE0
+       fdisi   ; 9BDBE1
+       fndisi  ; DBE1
+       fclex   ; 9BDBE2
+       fnclex  ; DBE2
+       finit   ; 9BDBE3
+       fninit  ; DBE3
+       fsetpm  ; DBE4
+       fcompp  ; DED9
diff --git a/Applications/as09/asm/fadd.asm b/Applications/as09/asm/fadd.asm
new file mode 100644 (file)
index 0000000..d18f002
--- /dev/null
@@ -0,0 +1,271 @@
+_fadd:
+       PUSH    BP
+       MOV     BP,SP
+       MOV     EAX,DWORD PTR [BP+4]
+       MOV     EDX,DWORD PTR [BP+8]
+       MOV     EBX,DWORD PTR [BP+12]
+       MOV     ECX,DWORD PTR [BP+16]
+       CALL    faddfxfy
+       MOV     DWORD PTR _facc,EAX
+       MOV     DWORD PTR _facc+4,EDX
+       POP     BP
+       RET
+
+fsubfxfy:
+       XOR     ECX,#$80000000  ; complement sign bit, fall into add routine
+faddfxfy:
+       PUSH    EBP
+       PUSH    EDI
+       PUSH    ESI
+       MOV     EDI,ECX         ; free CL for shifts
+       MOV     ESI,EDX         ; this mainly for consistent naming
+       AND     ESI,#$7FFFFFFF  ; discard sign so comparison is simple
+       AND     EDI,#$7FFFFFFF
+
+       CMP     ESI,EDI
+       JA      XBIG
+       JB      SWAP
+       CMP     EAX,EBX
+       JAE     XBIG
+SWAP:
+       XCHG    EDX,ECX
+       XCHG    ESI,EDI
+       XCHG    EAX,EBX
+XBIG:
+       AND     ESI,#$000FFFFF  ; discard exponent
+       AND     EDI,#$000FFFFF
+       OR      ESI,#$00100000  ; normalize
+       OR      EDI,#$00100000
+
+       SHR     ECX,32-(1+11)
+       SHR     EDX,32-(1+11)   
+       MOV     EBP,ECX         ; prepare to compare signs (want high bits 0)
+       SUB     CX,DX           ; get difference of signs in CX
+       NEG     CX              ; D holds sign and exponent of both throughout
+       CMP     CX,#(64-11)+2
+       JAE     TO_DONE1        ; x dominates y
+       XOR     BP,DX
+       AND     BP,#$0800       ; see if signs are same
+       JNZ     TO_SUBTRACT     ; else roundoff reg EBP is 0
+
+       CMP     CL,#32
+       JAE     TO_ADD_BIGSHIFT
+       SHRD    EBP,EBX,CL
+       SHRD    EBX,EDI,CL
+       SHR     EDI,CL
+       ADD     EAX,EBX
+       ADC     ESI,EDI
+       SUB     EBX,EBX
+
+; result DX(1+11):SI:AX:BP:BX but needs normalization
+
+NORMALIZE:
+       MOV     CX,DX
+       AND     CX,#$07FF
+       TEST    ESI,#$00200000
+       JZ      NORMALIZE2
+       BR      LOVERFLOW
+
+TO_DONE1:
+       JMP     DONE1
+
+TO_SUBTRACT:
+       BR      SUBTRACT
+
+TO_ADD_BIGSHIFT:
+       BR      ADD_BIGSHIFT
+
+TO_NORMLITTLE:
+       BR      NORMLITTLE
+
+; result DX(1):CX(11):SI:AX:BP:BX
+
+NORMALIZE2:
+       SHRD    EDI,ESI,32-11
+                               ; top 11 bits of ESI known 0 and BSR is slooow
+       BSR     EDI,EDI         ; index of leading 1 bit in EDI is 11..31 in DI
+       JZ      TO_NORMLITTLE   ; ESI is zero (flag wrong in Intel Manual)
+       SUB     DI,#31
+       NEG     DI
+       PUSH    CX              ; gr
+       MOV     CX,DI           ; rr
+       SHLD    ESI,EAX,CL
+       SHLD    EAX,EBP,CL
+       SHLD    EBP,EBX,CL
+       SHL     EBX,CL
+       POP     CX              ; rr
+       SUB     CX,DI
+       JC      UNDERFLOW       
+
+ROUND:
+       CMP     EBP,#$80000000  ; test roundoff register
+       JA      ROUNDUP
+       JB      DONE            ; no rounding
+       TEST    EBX,EBX
+       JNZ     ROUNDUP
+       TEST    AL,#1           ; ambiguous case, round to even
+       JZ      DONE            ; even, no rounding
+ROUNDUP:
+       ADD     EAX,#1
+       ADC     ESI,#0
+       SUB     EBP,EBP
+       SUB     EBX,EBX
+       TEST    ESI,#$00200000
+       JNZ     LOVERFLOW       ; rounding may cause overflow!
+
+DONE:
+       AND     DX,#$0800       ; extract sign of largest and result
+       OR      DX,CX           ; include exponent with sign
+DONE1:
+       SHL     EDX,32-(1+11)
+       AND     ESI,#$000FFFFF  ; discard normalization bit
+       OR      EDX,ESI 
+       POP     ESI
+       POP     EDI
+       POP     EBP
+       RET
+
+UNDERFLOW:                             ; should have error message here
+ANSWER0:
+       SUB     EDX,EDX
+       MOV     EAX,EDX
+       POP     ESI
+       POP     EDI
+       POP     EBP
+       RET
+
+LOVERFLOW:                     ; carry bit must be right-shifted back in
+       SHR     ESI,1
+       RCR     EAX,1
+       RCR     EBP,1
+       RCR     EBX,1
+       INC     CX
+       CMP     CX,#$0800
+       JNZ     ROUND
+
+OVERFLOW:                      ; should have error message here
+       MOV     EDX,#$FFE00000  ; + infinity
+       SUB     EAX,EAX
+       POP     ESI
+       POP     EDI
+       POP     EBP
+       RET
+
+ADD_BIGSHIFT:
+       SUB     CL,#32
+       SHRD    EBP,EBX,CL
+       SHRD    EBX,EDI,CL
+       SHR     EDI,CL
+       ADD     EAX,EDI
+       ADC     ESI,#0
+       XCHG    EBP,EBX
+       BR      NORMALIZE
+
+NORMLITTLE:
+       SHLD    ESI,EAX,32-(1+11)
+       SHLD    EAX,EBP,32-(1+11)
+       SHLD    EBP,EBX,32-(1+11)
+       SHL     EBX,20
+       SUB     CL,#32-(1+11)
+       JC      UNDERFLOW
+       BR      NORMALIZE2
+
+SUBTRACT:
+       SUB     EBP,EBP         ; set up roundoff register
+       CMP     CL,#32
+       JAE     SUBTRACT_BIGSHIFT
+       SHRD    EBP,EBX,CL
+       SHRD    EBX,EDI,CL
+       SHR     EDI,CL
+       NEG     EBP
+       SBB     EAX,EBX
+       SBB     ESI,EDI
+       SUB     EBX,EBX
+       MOV     CX,DX
+       AND     CX,#$07FF
+       BR      NORMALIZE2
+
+SUBTRACT_BIGSHIFT:
+       SUB     CL,#32
+       SHRD    EBP,EBX,CL
+       SHRD    EBX,EDI,CL
+       SHR     EDI,CL
+       NEG     EBX
+       NEG     EBP
+       SBB     EBX,#0
+       SBB     EAX,EDI
+       SBB     ESI,#0
+       XCHG    EBP,EBX
+       MOV     CX,DX
+       AND     CX,#$07FF
+       BR      NORMALIZE2
+
+TO_ANSWER0:
+       BR      ANSWER0
+
+TO_OVERFLOW:
+       JMP     TO_OVERFLOW
+
+TO_UNDERFLOW:
+       BR      UNDERFLOW
+
+fmulfxfy:
+       PUSH    EBP
+       PUSH    EDI
+       PUSH    ESI
+       MOV     ESI,EDX         ; free DX for multiplications
+       MOV     EDI,ECX         ; this mainly for consistent naming
+       SHR     EDX,32-(1+11)
+       SHR     ECX,32-(1+11)   
+       MOV     BP,DX
+       XOR     BP,CX
+       AND     BP,#$0800       ; extract sign
+       AND     DX,#$07FF       ; exp(x)
+       JZ      TO_ANSWER0
+       AND     CX,#$07FF       ; exp(y)
+       JZ      TO_ANSWER0
+       ADD     CX,DX
+       SUB     CX,#$0400
+       JB      TO_UNDERFLOW
+       CMP     CX,#$07FF
+       JA      TO_OVERFLOW     ; probably not quite right
+
+       AND     ESI,#$000FFFFF  ; discard sign and exponent
+       AND     EDI,#$000FFFFF
+       OR      ESI,#$00100000  ; normalize
+       OR      EDI,#$00100000
+
+; exponent is in CX, sign in BP, operands in ESI:EAX and EDI:EBX, DX is free
+; product to go in ESI:EAX:EBP:EBX
+; terminology: x * y = (x32:x0) * (y32:y0) = x32y32 + x32y0 + x0y32 +x0y0
+
+       PUSH    CX
+       PUSH    BP
+       MOV     ECX,EAX
+       MUL     EBX             ; x0y0
+       MOV     EBP,EDX         ; x0y0.high in EBP
+       XCHG    EBX,EAX         ; x0y0.low in EBX (final), y0 in EAX
+       MUL     ESI             ; x32y0
+       PUSH    EAX             ; x32y0.low on stack
+       PUSH    EDX             ; x32y0.high on stack
+       MOV     EAX,ESI
+       MUL     EDI             ; x32y32
+       MOV     ESI,EDX         ; x32y32.high in ESI (final except carries)
+       XCHG    ECX,EAX         ; x32y32.low in ECX, x0 in EAX
+       MUL     EDI             ; x0y32
+
+       ADD     EBP,EAX         ; x0y0.high + x0y32.low
+       POP     EAX             ; x32y0.high
+       ADC     EAX,EDX         ; x32y0.high + x0y32.high
+       ADC     ESI,#0
+       POP     EDX             ; x32y0.low
+       ADD     EBP,EDX         ; (x0y0.high + x0y32.low) + x32y0.low
+       ADC     EAX,ECX         ; (x32y0.high + x0y32.high) + x32y32.low
+       ADC     ESI,#0
+       POP     DX              ; sign
+       POP     CX              ; exponent
+       ADD     CX,#13          ; temp fixup
+       BR      NORMALIZE2
+
+_facc:
+       .word   0,0
diff --git a/Applications/as09/asm/farcall.asm b/Applications/as09/asm/farcall.asm
new file mode 100644 (file)
index 0000000..6a779d9
--- /dev/null
@@ -0,0 +1,10 @@
+call 1:2
+call far [1]
+use32
+call far [1]
+
+use16
+jmp 1:2
+jmp far [1]
+use32
+jmp far [1]
diff --git a/Applications/as09/asm/group1.asm b/Applications/as09/asm/group1.asm
new file mode 100644 (file)
index 0000000..fe2fb45
--- /dev/null
@@ -0,0 +1,31 @@
+       ADD     AL,#3
+       ADD     AX,#$1234
+       ADD     EAX,#$12345678
+       ADD     BL,#3
+       ADD     BX,#$1234
+       ADD     EBX,#$12345678
+       ADD     BYTE [BX],#3
+       ADD     BYTE 3[BX],#4
+       ADD     BYTE [BX+SI],#4
+       ADD     WORD [BX],#$1234
+       ADD     DWORD [BX],#$12345678
+       ADD     BYTE [BX],#3
+       ADD     WORD [BX],#-3
+       ADD     DWORD [BX],#-3
+       ADD     CL,BL
+       ADD     CX,BX
+       ADD     ECX,EBX
+       ADD     [BX],CL
+       ADD     [BX],CX
+       ADD     [BX],ECX
+       ADD     CL,[BX]
+       ADD     CX,[BX]
+       ADD     ECX,[BX]
+
+       ADC     CL,BL
+       AND     CL,BL
+       CMP     CL,BL
+       OR      CL,BL
+       SUB     CL,BL
+       SBB     CL,BL
+       XOR     CL,BL
diff --git a/Applications/as09/asm/group6.asm b/Applications/as09/asm/group6.asm
new file mode 100644 (file)
index 0000000..f742672
--- /dev/null
@@ -0,0 +1,24 @@
+; group6.asm
+; 0F 00 /nnn
+
+;      LLDT    r/m16           nnn = 010
+;      LTR     r/m16           nnn = 011
+;      SLDT    r/m16           nnn = 000
+;      STR     r/m16           nnn = 001
+;      VERR    r/m16           nnn = 100
+;      VERW    r/m16           nnn = 101
+
+       LLDT    AL              ; illeg size
+       LLDT    EAX             ; illeg size
+       LLDT    WORD $1234      ; immed not allowed
+       LLDT    DS              ; segreg not allowed
+
+       LLDT    AX
+       LLDT    [BX]
+       LLDT    [EAX]
+
+       LTR     BX
+       SLDT    [BP]
+       STR     [EBX]
+       VERR    CX
+       VERW    [SI]
diff --git a/Applications/as09/asm/group7.asm b/Applications/as09/asm/group7.asm
new file mode 100644 (file)
index 0000000..0df497c
--- /dev/null
@@ -0,0 +1,34 @@
+; group7.asm
+; 0F 01 /nnn
+
+;      INVLPG  m               nnn = 111
+;      LGDT    m16&32          nnn = 010
+;      LIDT    m16&32          nnn = 011
+;      LMSW    r/m16           nnn = 110
+;      SGDT    m               nnn = 000
+;      SIDT    m               nnn = 001
+;      SMSW    r/m16           nnn = 100
+
+       LGDT    EAX             ; register not allowed
+       LGDT    #$1234          ; immed not allowed
+       LGDT    WORD PTR [BX]   ; illegal size
+
+       LGDT    [BX]
+       LGDT    PWORD PTR [BX]
+       LGDT    FWORD PTR [BX]
+       LGDT    [EAX]
+
+       INVLPG  [EDI]
+       SGDT    [BP]
+       SIDT    [EBX]
+
+       LMSW    AL              ; illeg size
+       LMSW    EAX             ; illeg size
+       LMSW    #$1234          ; immed not allowed
+       LMSW    DS              ; segreg not allowed
+
+       LMSW    AX
+       LMSW    [BX]
+       LMSW    [EAX]
+
+       SMSW    BX
diff --git a/Applications/as09/asm/imul.asm b/Applications/as09/asm/imul.asm
new file mode 100644 (file)
index 0000000..e2772c2
--- /dev/null
@@ -0,0 +1,33 @@
+       use32
+
+       imul    bl
+       imul    byte ptr [esi]
+       imul    bx
+       imul    word ptr [esi]
+       imul    ebx
+       imul    dword ptr [esi]
+
+       imul    ax,bx
+       imul    ax,[esi]
+       imul    eax,ebx
+       imul    eax,[esi]
+
+       imul    ax,bx,22
+       imul    ax,[esi],22
+       imul    eax,ebx,22
+       imul    eax,[esi],22
+
+       imul    ax,[22]
+       imul    eax,[22]
+       imul    ax,#22
+       imul    eax,#22
+
+       imul    ax,bx,300
+       imul    ax,[esi],300
+       imul    eax,ebx,300000
+       imul    eax,[esi],300000
+
+       imul    ax,[300]
+       imul    eax,[300000]
+       imul    ax,#300
+       imul    eax,#300000
diff --git a/Applications/as09/asm/incdec.asm b/Applications/as09/asm/incdec.asm
new file mode 100644 (file)
index 0000000..573861c
--- /dev/null
@@ -0,0 +1,83 @@
+       INC     AL
+       INC     AH
+       INC     BL
+       INC     BH
+       INC     CL
+       INC     CH
+       INC     DL
+       INC     DH
+       INC     #1              ; illeg
+       INC     BYTE #1         ; illeg
+       INC     [BX]            ; illeg
+       INC     BYTE [BX]
+
+       INC     AX
+       INC     BX
+       INC     CX
+       INC     DX
+       INC     SP
+       INC     BP
+       INC     SI
+       INC     DI
+       INC     CS              ; illeg
+       INC     DS              ; illeg
+       INC     ES              ; illeg
+       INC     FS              ; illeg
+       INC     GS              ; illeg
+       INC     #$1234          ; illeg
+       INC     WORD #$1234     ; illeg
+       INC     WORD [BX]
+
+       INC     EAX
+       INC     EBX
+       INC     ECX
+       INC     EDX
+       INC     ESP
+       INC     EBP
+       INC     ESI
+       INC     EDI
+       INC     #$12345678      ; illeg
+       INC     DWORD #$12345678        ; illeg
+       INC     DWORD [BX]
+
+       DEC     AL
+       DEC     AH
+       DEC     BL
+       DEC     BH
+       DEC     CL
+       DEC     CH
+       DEC     DL
+       DEC     DH
+       DEC     #1              ; illeg
+       DEC     BYTE #1         ; illeg
+       DEC     [BX]            ; illeg
+       DEC     BYTE [BX]
+
+       DEC     AX
+       DEC     BX
+       DEC     CX
+       DEC     DX
+       DEC     SP
+       DEC     BP
+       DEC     SI
+       DEC     DI
+       DEC     CS              ; illeg
+       DEC     DS              ; illeg
+       DEC     ES              ; illeg
+       DEC     FS              ; illeg
+       DEC     GS              ; illeg
+       DEC     #$1234          ; illeg
+       DEC     WORD #$1234     ; illeg
+       DEC     WORD [BX]
+
+       DEC     EAX
+       DEC     EBX
+       DEC     ECX
+       DEC     EDX
+       DEC     ESP
+       DEC     EBP
+       DEC     ESI
+       DEC     EDI
+       DEC     #$12345678      ; illeg
+       DEC     DWORD #$12345678        ; illeg
+       DEC     DWORD [BX]
diff --git a/Applications/as09/asm/inher.asm b/Applications/as09/asm/inher.asm
new file mode 100644 (file)
index 0000000..f1343fa
--- /dev/null
@@ -0,0 +1,127 @@
+; INHER.ASM
+
+; INHER opcodes
+
+       AAA
+       AAS
+
+       CLC
+       CLD
+       CLI
+       CLTS
+       CMC
+       CMPSB
+
+       DAA
+       DAS
+
+       HLT
+
+       INTO
+       INSB
+
+       LAHF
+       LEAVE
+       LOCK
+       LODSB
+
+       MOVSB
+
+       NOP
+
+       OUTSB
+
+       REP
+       REPE
+       REPNE
+
+       SAHF
+       SCASB
+       STC
+       STD
+       STI
+       STOSB
+
+       WAIT
+
+; INHER16 and INHER32 opcodes
+
+       USE16
+
+       CBW
+       CWD
+       CWDE
+       CDQ
+       CMPSW
+       CMPSD
+
+       INSW
+       INSD
+       IRET
+       IRETD
+
+       LODSW
+       LODSD
+
+       MOVSW
+       MOVSD
+
+       OUTSW
+       OUTSD
+
+       POPA
+       POPAD
+       POPF
+       POPFD
+       PUSHA
+       PUSHAD
+       PUSHF
+       PUSHFD
+
+       SCASW
+       SCASD
+       STOSW
+       STOSW
+
+       XLAT
+       XLATB
+
+       USE32
+
+       CBW
+       CWD
+       CWDE
+       CDQ
+       CMPSW
+       CMPSD
+
+       INSW
+       INSD
+       IRET
+       IRETD
+
+       LODSW
+       LODSD
+
+       MOVSW
+       MOVSD
+
+       OUTSW
+       OUTSD
+
+       POPA
+       POPAD
+       POPF
+       POPFD
+       PUSHA
+       PUSHAD
+       PUSHF
+       PUSHFD
+
+       SCASW
+       SCASD
+       STOSW
+       STOSW
+
+       XLAT
+       XLATB
diff --git a/Applications/as09/asm/inout.asm b/Applications/as09/asm/inout.asm
new file mode 100644 (file)
index 0000000..3f0a3f2
--- /dev/null
@@ -0,0 +1,25 @@
+       IN      EAX,DX          ; plain IN is no longer allowed
+       INB
+       IN      AL,DX
+       INW
+       IN      AX,DX
+       IN      EAX,DX
+       IN      AL,$20
+       IN      AL,$101
+       IN      AX,$20
+       IN      AX,$101
+       IN      EAX,$20
+       IN      EAX,$101
+
+       OUTB    DX,EAX          ; plain OUT is no longer allowed
+       OUTB
+       OUT     DX,AL
+       OUTW
+       OUT     DX,AX
+       OUT     DX,EAX
+       OUT     $20,AL
+       OUT     $101,AL
+       OUT     $20,AX
+       OUT     #101,AX
+       OUT     $20,EAX
+       OUT     $101,EAX
diff --git a/Applications/as09/asm/movspec.asm b/Applications/as09/asm/movspec.asm
new file mode 100644 (file)
index 0000000..a4f9c15
--- /dev/null
@@ -0,0 +1,246 @@
+mov eax,cr0
+mov eax,cr2
+mov eax,cr3
+mov eax,dr0
+mov eax,dr1
+mov eax,dr2
+mov eax,dr3
+mov eax,dr6
+mov eax,dr7
+mov eax,tr3
+mov eax,tr4
+mov eax,tr5
+mov eax,tr6
+mov eax,tr7
+
+mov cr0,eax
+mov cr2,eax
+mov cr3,eax
+mov dr0,eax
+mov dr1,eax
+mov dr2,eax
+mov dr3,eax
+mov dr6,eax
+mov dr7,eax
+mov tr3,eax
+mov tr4,eax
+mov tr5,eax
+mov tr6,eax
+mov tr7,eax
+
+
+mov ebx,cr0
+mov ebx,cr2
+mov ebx,cr3
+mov ebx,dr0
+mov ebx,dr1
+mov ebx,dr2
+mov ebx,dr3
+mov ebx,dr6
+mov ebx,dr7
+mov ebx,tr3
+mov ebx,tr4
+mov ebx,tr5
+mov ebx,tr6
+mov ebx,tr7
+
+mov cr0,ebx
+mov cr2,ebx
+mov cr3,ebx
+mov dr0,ebx
+mov dr1,ebx
+mov dr2,ebx
+mov dr3,ebx
+mov dr6,ebx
+mov dr7,ebx
+mov tr3,ebx
+mov tr4,ebx
+mov tr5,ebx
+mov tr6,ebx
+mov tr7,ebx
+
+
+mov ecx,cr0
+mov ecx,cr2
+mov ecx,cr3
+mov ecx,dr0
+mov ecx,dr1
+mov ecx,dr2
+mov ecx,dr3
+mov ecx,dr6
+mov ecx,dr7
+mov ecx,tr3
+mov ecx,tr4
+mov ecx,tr5
+mov ecx,tr6
+mov ecx,tr7
+
+mov cr0,ecx
+mov cr2,ecx
+mov cr3,ecx
+mov dr0,ecx
+mov dr1,ecx
+mov dr2,ecx
+mov dr3,ecx
+mov dr6,ecx
+mov dr7,ecx
+mov tr3,ecx
+mov tr4,ecx
+mov tr5,ecx
+mov tr6,ecx
+mov tr7,ecx
+
+
+mov edx,cr0
+mov edx,cr2
+mov edx,cr3
+mov edx,dr0
+mov edx,dr1
+mov edx,dr2
+mov edx,dr3
+mov edx,dr6
+mov edx,dr7
+mov edx,tr3
+mov edx,tr4
+mov edx,tr5
+mov edx,tr6
+mov edx,tr7
+
+mov cr0,edx
+mov cr2,edx
+mov cr3,edx
+mov dr0,edx
+mov dr1,edx
+mov dr2,edx
+mov dr3,edx
+mov dr6,edx
+mov dr7,edx
+mov tr3,edx
+mov tr4,edx
+mov tr5,edx
+mov tr6,edx
+mov tr7,edx
+
+
+mov esi,cr0
+mov esi,cr2
+mov esi,cr3
+mov esi,dr0
+mov esi,dr1
+mov esi,dr2
+mov esi,dr3
+mov esi,dr6
+mov esi,dr7
+mov esi,tr3
+mov esi,tr4
+mov esi,tr5
+mov esi,tr6
+mov esi,tr7
+
+mov cr0,esi
+mov cr2,esi
+mov cr3,esi
+mov dr0,esi
+mov dr1,esi
+mov dr2,esi
+mov dr3,esi
+mov dr6,esi
+mov dr7,esi
+mov tr3,esi
+mov tr4,esi
+mov tr5,esi
+mov tr6,esi
+mov tr7,esi
+
+
+mov edi,cr0
+mov edi,cr2
+mov edi,cr3
+mov edi,dr0
+mov edi,dr1
+mov edi,dr2
+mov edi,dr3
+mov edi,dr6
+mov edi,dr7
+mov edi,tr3
+mov edi,tr4
+mov edi,tr5
+mov edi,tr6
+mov edi,tr7
+
+mov cr0,edi
+mov cr2,edi
+mov cr3,edi
+mov dr0,edi
+mov dr1,edi
+mov dr2,edi
+mov dr3,edi
+mov dr6,edi
+mov dr7,edi
+mov tr3,edi
+mov tr4,edi
+mov tr5,edi
+mov tr6,edi
+mov tr7,edi
+
+
+mov esp,cr0
+mov esp,cr2
+mov esp,cr3
+mov esp,dr0
+mov esp,dr1
+mov esp,dr2
+mov esp,dr3
+mov esp,dr6
+mov esp,dr7
+mov esp,tr3
+mov esp,tr4
+mov esp,tr5
+mov esp,tr6
+mov esp,tr7
+
+mov cr0,esp
+mov cr2,esp
+mov cr3,esp
+mov dr0,esp
+mov dr1,esp
+mov dr2,esp
+mov dr3,esp
+mov dr6,esp
+mov dr7,esp
+mov tr3,esp
+mov tr4,esp
+mov tr5,esp
+mov tr6,esp
+mov tr7,esp
+
+
+mov ebp,cr0
+mov ebp,cr2
+mov ebp,cr3
+mov ebp,dr0
+mov ebp,dr1
+mov ebp,dr2
+mov ebp,dr3
+mov ebp,dr6
+mov ebp,dr7
+mov ebp,tr3
+mov ebp,tr4
+mov ebp,tr5
+mov ebp,tr6
+mov ebp,tr7
+
+mov cr0,ebp
+mov cr2,ebp
+mov cr3,ebp
+mov dr0,ebp
+mov dr1,ebp
+mov dr2,ebp
+mov dr3,ebp
+mov dr6,ebp
+mov dr7,ebp
+mov tr3,ebp
+mov tr4,ebp
+mov tr5,ebp
+mov tr6,ebp
+mov tr7,ebp
diff --git a/Applications/as09/asm/pushpop.asm b/Applications/as09/asm/pushpop.asm
new file mode 100644 (file)
index 0000000..b45117a
--- /dev/null
@@ -0,0 +1,86 @@
+       PUSH    AL              ; illeg
+       PUSH    AH              ; illeg
+       PUSH    BL              ; illeg
+       PUSH    BH              ; illeg
+       PUSH    CL              ; illeg
+       PUSH    CH              ; illeg
+       PUSH    DL              ; illeg
+       PUSH    DH              ; illeg
+       PUSH    #1              ; illeg
+       PUSH    BYTE #1         ; illeg
+       PUSH    [BX]            ; illeg
+       PUSH    BYTE [BX]       ; illeg
+       PUSH    WORD #-1        ; right way to push a signed byte value
+
+       PUSH    AX
+       PUSH    BX
+       PUSH    CX
+       PUSH    DX
+       PUSH    SP
+       PUSH    BP
+       PUSH    SI
+       PUSH    DI
+       PUSH    CS
+       PUSH    DS
+       PUSH    ES
+       PUSH    FS
+       PUSH    GS
+       PUSH    SS
+       PUSH    #$1234          ; illeg
+       PUSH    WORD #$1234
+       PUSH    WORD [BX]
+
+       PUSH    EAX
+       PUSH    EBX
+       PUSH    ECX
+       PUSH    EDX
+       PUSH    ESP
+       PUSH    EBP
+       PUSH    ESI
+       PUSH    EDI
+       PUSH    #$12345678      ; illeg
+       PUSH    DWORD #$12345678
+       PUSH    DWORD [BX]
+
+       POP     AL              ; illeg
+       POP     AH              ; illeg
+       POP     BL              ; illeg
+       POP     BH              ; illeg
+       POP     CL              ; illeg
+       POP     CH              ; illeg
+       POP     DL              ; illeg
+       POP     DH              ; illeg
+       POP     #1              ; illeg
+       POP     BYTE #1         ; illeg
+       POP     [BX]            ; illeg
+       POP     BYTE [BX]       ; illeg
+
+       POP     AX
+       POP     BX
+       POP     CX
+       POP     DX
+       POP     SP
+       POP     BP
+       POP     SI
+       POP     DI
+       POP     CS              ; illeg
+       POP     DS
+       POP     ES
+       POP     FS
+       POP     GS
+       POP     SS
+       POP     #$1234          ; illeg
+       POP     WORD #$1234     ; illeg
+       POP     WORD [BX]
+
+       POP     EAX
+       POP     EBX
+       POP     ECX
+       POP     EDX
+       POP     ESP
+       POP     EBP
+       POP     ESI
+       POP     EDI
+       POP     #$12345678      ; illeg
+       POP     DWORD #$12345678        ; illeg
+       POP     DWORD [BX]
diff --git a/Applications/as09/asm/seg.asm b/Applications/as09/asm/seg.asm
new file mode 100644 (file)
index 0000000..0394615
--- /dev/null
@@ -0,0 +1,6 @@
+       SEG     CS
+       SEG     DS
+       SEG     ES
+       SEG     FS
+       SEG     GS
+       SEG     SS
diff --git a/Applications/as09/asm/shdouble.asm b/Applications/as09/asm/shdouble.asm
new file mode 100644 (file)
index 0000000..1080ece
--- /dev/null
@@ -0,0 +1,34 @@
+; SHDOUBLE.ASM
+
+ILLEGALS       EQU     1
+
+; 0F A4                SHLD    r/m16,r16,imm8          3/7
+; 0F A4                SHLD    r/m32,r32,imm8          3/7
+; 0F A5                SHLD    r/m16,r16,CL            3/7
+; 0F A5                SHLD    r/m32,r32,CL            3/7
+
+; 0F AC                SHRD    r/m16,r16,imm8          3/7
+; 0F AC                SHRD    r/m32,r32,imm8          3/7
+; 0F AD                SHRD    r/m16,r16,CL            3/7
+; 0F AD                SHRD    r/m32,r32,CL            3/7
+
+IF     ILLEGALS
+       SHLD    AL,BL,8         ; byte size
+       SHLD    AX,8,8          ; immediate source
+       SHLD    AX,DS,8         ; segment register
+       SHLD    AX,[BX],8       ; non-register source
+       SHLD    AX,BX,256       ; shift count too big
+       SHLD    AL,BL,8         ; byte size
+ENDIF
+
+       SHLD    BX,CX,3
+       SHLD    EDX,ESI,1
+       SHLD    CX,BX,CL
+       SHLD    ESI,EDX,1
+       SHLD    [BX],CX,3
+       SHLD    [BX],ECX,1
+       SHLD    [SI],BX,CL
+       SHLD    [SI],EBX,CL
+
+       SHRD    BX,CX,3
+       SHRD    CX,BX,CL
diff --git a/Applications/as09/asm/shift.asm b/Applications/as09/asm/shift.asm
new file mode 100644 (file)
index 0000000..35cc23f
--- /dev/null
@@ -0,0 +1,119 @@
+       RCL     AL,CL
+       RCL     AH,CL
+       RCL     BL,CL
+       RCL     BH,CL
+       RCL     CL,CL
+       RCL     CH,CL
+       RCL     DL,CL
+       RCL     DH,CL
+       RCL     #1,CL           ; illeg
+       RCL     [BX],CL         ; illeg
+       RCL     BYTE [BX],CL
+
+       RCL     AX,CL
+       RCL     BX,CL
+       RCL     CX,CL
+       RCL     DX,CL
+       RCL     SP,CL
+       RCL     BP,CL
+       RCL     SI,CL
+       RCL     DI,CL
+       RCL     CS,CL           ; illeg
+       RCL     DS,CL           ; illeg
+       RCL     ES,CL           ; illeg
+       RCL     FS,CL           ; illeg
+       RCL     GS,CL           ; illeg
+       RCL     WORD [BX],CL
+
+       RCL     EAX,CL
+       RCL     EBX,CL
+       RCL     ECX,CL
+       RCL     EDX,CL
+       RCL     ESP,CL
+       RCL     EBP,CL
+       RCL     ESI,CL
+       RCL     EDI,CL
+       RCL     DWORD [BX],CL
+
+       RCL     AL,1
+       RCL     AH,1
+       RCL     BL,1
+       RCL     BH,1
+       RCL     CL,1
+       RCL     CH,1
+       RCL     DL,1
+       RCL     DH,1
+       RCL     #1,1            ; illeg
+       RCL     [BX],1          ; illeg
+       RCL     BYTE [BX],1
+
+       RCL     AX,1
+       RCL     BX,1
+       RCL     CX,1
+       RCL     DX,1
+       RCL     SP,1
+       RCL     BP,1
+       RCL     SI,1
+       RCL     DI,1
+       RCL     CS,1            ; illeg
+       RCL     DS,1            ; illeg
+       RCL     ES,1            ; illeg
+       RCL     FS,1            ; illeg
+       RCL     GS,1            ; illeg
+       RCL     WORD [BX],1
+
+       RCL     EAX,1
+       RCL     EBX,1
+       RCL     ECX,1
+       RCL     EDX,1
+       RCL     ESP,1
+       RCL     EBP,1
+       RCL     ESI,1
+       RCL     EDI,1
+       RCL     DWORD [BX],1
+
+       RCL     AL,15
+       RCL     AH,15
+       RCL     BL,15
+       RCL     BH,15
+       RCL     CL,15
+       RCL     CH,15
+       RCL     DL,15
+       RCL     DH,15
+       RCL     #1,15           ; illeg
+       RCL     [BX],15         ; illeg
+       RCL     BYTE [BX],15
+       RCL     AL,$1000
+
+       RCL     AX,15
+       RCL     BX,15
+       RCL     CX,15
+       RCL     DX,15
+       RCL     SP,15
+       RCL     BP,15
+       RCL     SI,15
+       RCL     DI,15
+       RCL     CS,15           ; illeg
+       RCL     DS,15           ; illeg
+       RCL     ES,15           ; illeg
+       RCL     FS,15           ; illeg
+       RCL     GS,15           ; illeg
+       RCL     WORD [BX],15
+
+       RCL     EAX,15
+       RCL     EBX,15
+       RCL     ECX,15
+       RCL     EDX,15
+       RCL     ESP,15
+       RCL     EBP,15
+       RCL     ESI,15
+       RCL     EDI,15
+       RCL     DWORD [BX],15
+
+       RCR     AX,7
+       ROL     AX,7
+       ROR     AX,7
+       SAL     AX,7
+       SAR     AX,7
+       SHL     AX,7
+       SHR     AX,7
diff --git a/Applications/as09/asm/summary.as b/Applications/as09/asm/summary.as
new file mode 100644 (file)
index 0000000..cd62e37
--- /dev/null
@@ -0,0 +1,385 @@
+general:
+               ; AL,imm8
+               ; AX,imm16
+               ; EAX,imm32
+               ; r/m8,imm8
+               ; r/m16,imm16
+               ; r/m32.imm32
+               ; r/m16,signed imm8
+               ; r/m32,signed imm8
+               ; r/m8,r8
+               ; r/m16,r16
+               ; r/m32,r32
+               ; r8,r/m8
+               ; r16,r/m16
+               ; r32,r/m32
+
+shiftcount:
+               ; 1
+               ; CL
+               ; imm8
+unary alterable:
+               ; r/m8
+               ; r/m16
+               ; r/m32
+
+       AAA
+       AAD     ; [unsupported base]
+       AAM     ; [unsupported base]
+       AAS
+       ADC     ; general
+       ADD     ; general
+       AND     ; general
+       ARPL    ; r/m16,r16
+       BOUND   ; r16,m16&16
+       BOUND   ; r32,m32&32
+       BSF     ; r16,r/m16
+       BSF     ; r32,r/m32
+       BSR     ; r16,r/m16
+       BSR     ; r32,r/m32
+       BSWAP   ; r32
+       BT      ; r/m16,r16
+       BT      ; r/m32,r32
+       BT      ; r/m16,imm8
+       BT      ; r/m32,imm8
+       BTC     ; r/m16,r16
+       BTC     ; r/m32,r32
+       BTC     ; r/m16,imm8
+       BTC     ; r/m32,imm8
+       BTR     ; r/m16,r16
+       BTR     ; r/m32,r32
+       BTR     ; r/m16,imm8
+       BTR     ; r/m32,imm8
+       BTS     ; r/m16,r16
+       BTS     ; r/m32,r32
+       BTS     ; r/m16,imm8
+       BTS     ; r/m32,imm8
+       CALL    ; rel16
+       CALL    ; r/m16
+       CALL    ; ptr16:16
+       CALL    ; m16:16
+       CALL    ; rel32
+       CALL    ; r/m32
+       CALL    ; ptr16:32
+       CALL    ; m16:32
+       CBW
+       CDQ
+       CLC
+       CLD
+       CLI
+       CLTS
+       CMC
+       CMP     ; general
+       CMPS    ; [segreg:]m8,m8
+       CMPS    ; [segreg:]m16,m16
+       CMPS    ; [segreg:]m32,m32
+       CMPSB
+       CMPSW
+       CMPSD
+       CMPXCHG ; r/m8,r8
+       CMPXCHG ; r/m16,r16
+       CMPXCHG ; r/m32,r32
+       CWD
+       CWDE
+       DAA
+       DAS
+       DEC     ; unary alterable
+       DEC     ; r16
+       DEC     ; r32
+       DIV     ; AL,r/m8
+       DIV     ; AX,r/m16
+       DIV     ; EAX,r/m32
+       ENTER   ; imm16,imm8
+       HLT
+       IDIV    ; AL,r/m8
+       IDIV    ; AX,r/m16
+       IDIV    ; EAX,r/m32
+       IMUL    ; r/m8
+       IMUL    ; r/m16
+       IMUL    ; r/m32
+       IMUL    ; r16,r/m16
+       IMUL    ; r32,r/m32
+       IMUL    ; r16,r/m16,imm8
+       IMUL    ; r32,r/m32,imm8
+       IMUL    ; r16,imm8
+       IMUL    ; r32,imm8
+       IMUL    ; r16,r/m16,imm16
+       IMUL    ; r32,r/m32,imm32
+       IMUL    ; r16,imm16
+       IMUL    ; r32,imm32
+       IN      ; AL,imm8
+       IN      ; AX,imm8
+       IN      ; EAX,imm8
+       IN      ; AL,DX
+       IN      ; AX,DX
+       IN      ; EAX,DX
+       INC     ; unary alterable
+       INC     ; r16
+       INC     ; r32
+       INSB
+       INSW
+       INSD
+       INT     ; imm8
+       INTO
+       INVD
+       INVLPG  ; m
+       IRET
+       IRETD
+       JCC     ; rel8
+       JCC     ; rel16/32
+       JA
+       JAE
+       JB
+       JBE
+       JC
+       JCXZ
+       JECXZ
+       JE
+       JG
+       JGE
+       JL
+       JLE
+       JNA
+       JNAE
+       JNB
+       JNBE
+       JNC
+       JNE
+       JNG
+       JNGE
+       JNL
+       JNLE
+       JNO
+       JNP
+       JNS
+       JNZ
+       JO
+       JP
+       JPE
+       JPO
+       JS
+       JZ
+       JMP     ; rel8
+       JMP     ; rel16
+       JMP     ; r/m16
+       JMP     ; ptr16:16
+       JMP     ; m16:16
+       JMP     ; rel32
+       JMP     ; r/m32
+       JMP     ; ptr16:32
+       JMP     ; m16:32
+       LAHF
+       LAR     ; r16,r/m16
+       LAR     ; r32,r/m32
+       LEA     ; r16,m
+       LEA     ; r32,m
+       LEAVE
+       LGDT    ; m16&32
+       LIDT    ; m16&32
+       LDS     ; r16,m16:16
+       LDS     ; r32,m16:32
+       LES     ; r16,m16:16
+       LES     ; r32,m16:32
+       LFS     ; r16,m16:16
+       LFS     ; r32,m16:32
+       LGS     ; r16,m16:16
+       LGS     ; r32,m16:32
+       LSS     ; r16,m16:16
+       LSS     ; r32,m16:32
+       LLDT    ; r/m16
+       LMSW    ; r/m16
+       LOCK
+       LODS    ; [segreg:]m8
+       LODS    ; [segreg:]m16
+       LODS    ; [segreg:]m32
+       LODSB
+       LODSW
+       LODSD
+       LOOP    ; rel8
+       LOOPE   ; rel8
+       LOOPZ   ; rel8
+       LOOPNE  ; rel8
+       LOOPNZ  ; rel8
+       LSL     ; r16,r/m16
+       LSL     ; r32,r/m32
+       LTR     ; r/m16
+       MOV     ; r/m8,r8
+       MOV     ; r/m16,r16
+       MOV     ; r/m32,r32
+       MOV     ; r8,r/m8
+       MOV     ; r16,r/m16
+       MOV     ; r32,r/m32
+       MOV     ; r/m16,Sreg
+       MOV     ; Sreg,r/m16
+       MOV     ; AL,moffs8
+       MOV     ; AX,moffs16
+       MOV     ; EAX,moffs32
+       MOV     ; moffs8,AL
+       MOV     ; moffs16,AX
+       MOV     ; moffs32,EAX
+       MOV     ; r8,imm8
+       MOV     ; r16,imm16
+       MOV     ; r32,imm32
+       MOV     ; r32,CR0/CR2/CR3
+       MOV     ; r/m8,imm8
+       MOV     ; r/m16,imm16
+       MOV     ; r/m32,imm32
+       MOV     ; r32,CR0/CR2/CR3
+       MOV     ; CR0/CR2/CR3,r32
+       MOV     ; r32,DR0/DR1/DR2/DR3/DR6/DR7
+       MOV     ; DR0/DR1/DR2/DR3/DR6/DR7,r32
+       MOV     ; r32,TR6/TR7
+       MOV     ; TR6/TR7,r32
+       MOVS    ; [segreg:]m8,m8
+       MOVS    ; [segreg:]m16,m16
+       MOVS    ; [segreg:]m32,m32
+       MOVSB
+       MOVSW
+       MOVSD
+       MOVSX   ; r16,r/m8
+       MOVSX   ; r32,r/m8
+       MOVSX   ; r32,r/m16
+       MOVZX   ; r16,r/m8
+       MOVZX   ; r32,r/m8
+       MOVZX   ; r32,r/m16
+       MUL     ; AL,r/m8
+       MUL     ; AX,r/m16
+       MUL     ; EAX,r/m32
+       NEG     ; unary alterable
+       NOP
+       NOT     ; unary alterable
+       OR      ; general
+       OUT     ; imm8,AL
+       OUT     ; imm8,AX
+       OUT     ; imm8,EAX
+       OUT     ; DX,AL
+       OUT     ; DX,AX
+       OUT     ; DX,EAX
+       OUTS    ; [segreg:]m8
+       OUTS    ; [segreg:]m16
+       OUTS    ; [segreg:]m32
+       OUTSB
+       OUTSW
+       OUTSD
+       POP     ; m16
+       POP     ; m32
+       POP     ; r16
+       POP     ; r32
+       POP     ; DS
+       POP     ; ES
+       POP     ; FS
+       POP     ; GS
+       POP     ; SS
+       POPA
+       POPAD
+       POPF
+       POPFD
+       PUSH    ; m16
+       PUSH    ; m32
+       PUSH    ; r16
+       PUSH    ; r32
+       PUSH    ; imm8
+       PUSH    ; imm16
+       PUSH    ; imm32
+       PUSH    ; CS
+       PUSH    ; DS
+       PUSH    ; ES
+       PUSH    ; FS
+       PUSH    ; GS
+       PUSH    ; SS
+       PUSHA
+       PUSHAD
+       PUSHF
+       PUSHFD
+       RCL     ; shiftcount
+       RCR     ; shiftcount
+       ROL     ; shiftcount
+       ROR     ; shiftcount
+       REP     ; INS/MOVS/OUTS/STOS
+       REPE    ; CMPS/SCAS
+       REPNE   ; CMPS/SCAS
+       RET
+       RET     ; imm16
+       SAHF
+       SAL     ; shiftcount
+       SAR     ; shiftcount
+       SHL     ; shiftcount
+       SHR     ; shiftcount
+       SBB     ; general
+       SCASB
+       SCASW
+       SCASD
+       SETA    ; r/m8
+       SETAE   ; r/m8
+       SETB    ; r/m8
+       SETBE   ; r/m8
+       SETC    ; r/m8
+       SETE    ; r/m8
+       SETG    ; r/m8
+       SETGE   ; r/m8
+       SETL    ; r/m8
+       SETLE   ; r/m8
+       SETNA   ; r/m8
+       SETNAE  ; r/m8
+       SETNB   ; r/m8
+       SETNBE  ; r/m8
+       SETNC   ; r/m8
+       SETNE   ; r/m8
+       SETNG   ; r/m8
+       SETNGE  ; r/m8
+       SETNL   ; r/m8
+       SETNLE  ; r/m8
+       SETNO   ; r/m8
+       SETNP   ; r/m8
+       SETNS   ; r/m8
+       SETNZ   ; r/m8
+       SETO    ; r/m8
+       SETP    ; r/m8
+       SETPE   ; r/m8
+       SETPO   ; r/m8
+       SETS    ; r/m8
+       SETZ    ; r/m8
+       SGDT    ; m
+       SHLD    ; r/m16,r16,imm8
+       SHLD    ; r/m32,r32,imm8
+       SHLD    ; r/m16,r16,CL
+       SHLD    ; r/m32,r32,CL
+       SHRD    ; r/m16,r16,imm8
+       SHRD    ; r/m32,r32,imm8
+       SHRD    ; r/m16,r16,CL
+       SHRD    ; r/m32,r32,CL
+       SIDT    ; m
+       SLDT    ; r/m16
+       SMSW    ; r/m16
+       STC
+       STD
+       STI
+       STOSB
+       STOSW
+       STOSD
+       STR     ; r/m16
+       SUB     ; general
+       TEST    ; AL,imm8
+       TEST    ; AX,imm16
+       TEST    ; EAX,imm32
+       TEST    ; r/m8,imm8
+       TEST    ; r/m16,imm16
+       TEST    ; r/m32,imm32
+       TEST    ; r/m8,r8
+       TEST    ; r/m16,r16
+       TEST    ; r/m32/r32
+       VERR    ; r/m16
+       VERW    ; r/m16
+       WAIT
+       WBINVD
+       XADD    ; r/m8,r8
+       XADD    ; r/m16,r16
+       XADD    ; r/m32,r32
+       XCHG    ; AX,r16
+       XCHG    ; EAX,r32
+       XCHG    ; r/m8,r8
+       XCHG    ; r/m16,r16
+       XCHG    ; r/m32,r32
+       XLAT    ; [segreg:]m8
+       XLATB
+       XOR     ; general
diff --git a/Applications/as09/asm/xchg.asm b/Applications/as09/asm/xchg.asm
new file mode 100644 (file)
index 0000000..f05157f
--- /dev/null
@@ -0,0 +1,103 @@
+       XCHG    AX,BL           ; illeg
+       XCHG    AX,BYTE [BX]    ; illeg
+       XCHG    AX,DS           ; illeg
+       XCHG    AX,#1           ; illeg
+
+       XCHG    AX,AX
+       XCHG    AX,BX
+       XCHG    AX,CX
+       XCHG    AX,DX
+       XCHG    AX,SP
+       XCHG    AX,BP
+       XCHG    AX,SI
+       XCHG    AX,DI
+
+       XCHG    AX,AX
+       XCHG    BX,AX
+       XCHG    CX,AX
+       XCHG    DX,AX
+       XCHG    SP,AX
+       XCHG    BP,AX
+       XCHG    SI,AX
+       XCHG    DI,AX
+
+       XCHG    EAX,EAX
+       XCHG    EAX,EBX
+       XCHG    EAX,ECX
+       XCHG    EAX,EDX
+       XCHG    EAX,ESP
+       XCHG    EAX,EBP
+       XCHG    EAX,ESI
+       XCHG    EAX,EDI
+
+       XCHG    EAX,EAX
+       XCHG    EBX,EAX
+       XCHG    ECX,EAX
+       XCHG    EDX,EAX
+       XCHG    ESP,EAX
+       XCHG    EBP,EAX
+       XCHG    ESI,EAX
+       XCHG    EDI,EAX
+
+       XCHG    AL,AL
+       XCHG    AL,AH
+       XCHG    AL,BL
+       XCHG    AL,BH
+       XCHG    BL,CL
+       XCHG    BL,CH
+       XCHG    BL,DL
+       XCHG    BL,DH
+
+       XCHG    [BX],AL
+       XCHG    [BX],AH
+       XCHG    [BX],BL
+       XCHG    [BX],BH
+       XCHG    [BX],CL
+       XCHG    [BX],CH
+       XCHG    [BX],DL
+       XCHG    [BX],DH
+
+       XCHG    AL,[BX]
+       XCHG    AH,[BX]
+       XCHG    BL,[BX]
+       XCHG    BH,[BX]
+       XCHG    CL,[BX]
+       XCHG    CH,[BX]
+       XCHG    DL,[BX]
+       XCHG    DH,[BX]
+
+       XCHG    [BX],AX
+       XCHG    [BX],BX
+       XCHG    [BX],CX
+       XCHG    [BX],DX
+       XCHG    [BX],SP
+       XCHG    [BX],BP
+       XCHG    [BX],SI
+       XCHG    [BX],DI
+
+       XCHG    AX,[BX]
+       XCHG    BX,[BX]
+       XCHG    CX,[BX]
+       XCHG    DX,[BX]
+       XCHG    SP,[BX]
+       XCHG    BP,[BX]
+       XCHG    SI,[BX]
+       XCHG    DI,[BX]
+
+       XCHG    [BX],EAX
+       XCHG    [BX],EBX
+       XCHG    [BX],ECX
+       XCHG    [BX],EDX
+       XCHG    [BX],ESP
+       XCHG    [BX],EBP
+       XCHG    [BX],ESI
+       XCHG    [BX],EDI
+
+       XCHG    AX,[EBX]
+       XCHG    BX,[EBX]
+       XCHG    CX,[EBX]
+       XCHG    DX,[EBX]
+       XCHG    SP,[EBX]
+       XCHG    BP,[EBX]
+       XCHG    SI,[EBX]
+       XCHG    DI,[EBX]
diff --git a/Applications/as09/assemble.c b/Applications/as09/assemble.c
new file mode 100644 (file)
index 0000000..12cf6c9
--- /dev/null
@@ -0,0 +1,364 @@
+/* assemble.c - main loop for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "address.h"
+#include "globvar.h"
+#include "opcode.h"
+#include "scan.h"
+
+static bool_t nocolonlabel;    /* set for labels not followed by ':' */
+static void (*routine) P((void));
+#ifdef I80386
+static opcode_t rep = 0;       /* which rep/repne prefix was seen */
+#endif
+static pfv rout_table[] =
+{
+    pelse,
+    pelseif,
+    pelsifc,
+    pendif,
+    pif,
+    pifc,
+
+    /* start of non-conditionals */
+    palign,
+    pasciz,
+    pblkw,
+    pblock,
+    pbss,
+    pcomm,
+    pcomm1,
+    pdata,
+    pendb,
+    penter,
+    pentry,
+    pequ,
+    peven,
+    pexport,
+    pfail,
+    pfcb,
+    pfcc,
+    pfdb,
+#if SIZEOF_OFFSET_T > 2
+    pfqb,
+#endif
+    pget,
+    pglobl,
+    pident,
+    pimport,
+    plcomm,
+    plcomm1,
+    plist,
+    ploc,
+    pmaclist,
+    pmacro,
+    pmap,
+    porg,
+    pproceof,
+    prmb,
+    psect,
+    pset,
+    psetdp,
+    ptext,
+#ifdef I80386
+    puse16,
+    puse32,
+#endif
+    pwarn,
+    /* end of pseudo-ops */
+
+#ifdef I80386
+    mbcc,
+    mbswap,
+    mcall,
+    mcalli,
+    mdivmul,
+    menter,
+    mEwGw,
+    mExGx,
+    mf_inher,
+    mf_m,
+    mf_m2,
+    mf_m2_ax,
+    mf_m2_m4,
+    mf_m2_m4_m8,
+    mf_m4_m8_optst,
+    mf_m4_m8_st,
+    mf_m4_m8_stst,
+    mf_m4_m8_m10_st,
+    mf_m10,
+    mf_optst,
+    mf_st,
+    mf_stst,
+    mf_w_inher,
+    mf_w_m,
+    mf_w_m2,
+    mf_w_m2_ax,
+    mgroup1,
+    mgroup2,
+    mgroup6,
+    mgroup7,
+    mgroup8,
+    mGvEv,
+    mGvMa,
+    mGvMp,
+    mimul,
+    min,
+    mincdec,
+    minher,
+    minher16,
+    minher32,
+    minhera,
+    mint,
+    mjcc,
+    mjcxz,
+    mlea,
+    mmov,
+    mmovx,
+    mnegnot,
+    mout,
+    mpushpop,
+    mret,
+    mseg,
+    msetcc,
+    mshdouble,
+    mtest,
+    mxchg,
+#endif /* I80386 */
+
+#ifdef MC6809
+    mall,                      /* all address modes allowed, like LDA */
+    malter,                    /* all but immediate, like STA */
+    mimmed,                    /* immediate only (ANDCC, ORCC) */
+    mindex,                    /* indexed (LEA's) */
+    minher,                    /* inherent, like CLC or CLRA */
+    mlong,                     /* long branches */
+    mshort,                    /* short branches */
+    msstak,                    /* S-stack      (PSHS, PULS) */
+    mswap,                     /* TFR, EXG */
+    mustak,                    /* U-stack      (PSHU,PULU) */
+#endif /* MC6809 */
+};
+
+static void asline(void);
+
+/*
+  This uses registers as follows: A is for work and is not preserved by
+  the subroutines.B holds the last symbol code, X usually points to data
+  about the last symbol, U usually holds the value of last expression
+  or symbol, and Y points to the current char. The value in Y is needed
+  by READCH and GETSYM.  EXPRES needs B and Y, and returns a value in U.
+  If the expression starts with an identifier, X must point to its string.
+  LOOKUP needs a string pointer in X and length in A. It returns a table
+  pointer in X (unless not assembling and not found), symbol type in A
+  and overflow in CC.
+*/
+
+void assemble(void)
+{
+    while (TRUE)
+    {
+       asline();
+       if (label != NUL_PTR)   /* must be confirmed if still set */
+       {                       /* it is nulled by EQU, COMM and SET */
+#ifndef MC6809
+#define NEEDENDLABEL ILLAB
+           if (nocolonlabel)
+               error(NEEDENDLABEL);
+#endif
+           if(pass && label->value_reg_or_op.value != oldlabel)
+           {
+              dirty_pass = TRUE;
+              if( pass == last_pass )
+                 error(UNSTABLE_LABEL);
+            }
+
+           label->type |= LABIT;       /* confirm, perhaps redundant */
+           if (label->type & REDBIT)
+           {
+               /* REDBIT meant 'GLOBLBIT' while LABIT was not set. */
+               label->type |= EXPBIT;
+               label->type &= ~REDBIT;
+           }
+           if ((mcount | popflags) == 0)
+               /* unaccompanied label, display adr like EQU and SET */
+               showlabel();
+           label = NUL_PTR;    /* reset for next line */
+       }
+        skipline();
+       listline();
+       genbin();
+       genobj();
+       binmbuf = lc += lcjump
+#ifdef I80386
+           + immcount
+#endif
+           ;
+    }
+}
+
+static void asline(void)
+{
+    register struct sym_s *symptr;
+
+    postb = popflags = pcrflag =
+#ifdef I80386
+       sprefix = oprefix = aprefix =
+#endif
+       immcount = lastexp.data = lcjump = 0;
+#ifdef I80386
+    sib = NO_SIB;
+#endif
+#if SIZEOF_OFFSET_T > 2
+    fqflag =
+#endif
+       fdflag = fcflag = FALSE;
+    cpuwarn();
+    readline();
+    getsym();
+    if (sym != IDENT)          /* expect label, mnemonic or macro */
+    {  
+       /* Warn if not a comment marker or a hash (for /lib/cpp) */
+       if( sym != EOLSYM && sym != IMMEDIATE )
+          list_force = TRUE;
+       return;                 /* anything else is a comment */
+    }
+    symptr = gsymptr;
+    if (!ifflag)
+       /* not assembling, just test for IF/ELSE/ELSEIF/ENDIF */
+    {
+       if (symptr == NUL_PTR || !(symptr->type & MNREGBIT) ||
+           symptr->data & REGBIT ||
+           symptr->value_reg_or_op.op.routine >= MIN_NONCOND)
+           return;
+    }
+    else if (!(symptr->type & (MACBIT | MNREGBIT)))
+       /* not macro, op, pseudo-op or register, expect label */
+    {
+       oldlabel = symptr->value_reg_or_op.value;
+
+       if ((nocolonlabel = (*lineptr - ':')) == 0)     /* exported label? */
+       {
+           sym = COLON;
+           ++lineptr;
+       }
+       if (symptr->type & (LABIT | VARBIT))
+       {
+           if (symptr->type & REDBIT)
+               labelerror(RELAB);
+           label = symptr;
+
+           if (pass && !(symptr->type & VARBIT) /*&& last_pass>1*/)
+           {
+              label->data = (label->data & FORBIT) | lcdata;
+              label->value_reg_or_op.value = lc;
+           }
+       }
+       else if (checksegrel(symptr))
+       {
+           symptr->type &= ~COMMBIT;   /* ignore COMM, PCOMM gives warning */
+#ifdef MC6809
+#if 0
+           if (sym == COLON)
+               symptr->type |= EXPBIT;
+#endif
+#endif
+                               /* remember if forward referenced */
+           symptr->data = (symptr->data & FORBIT) | lcdata;
+           symptr->value_reg_or_op.value = lc;
+                               /* unless changed by EQU,COMM or SET */
+           label = symptr;
+       }
+
+       getsym();
+       if (sym != IDENT)
+       {
+           if (sym == EQOP)
+           {
+               getsym();
+               pequ();
+           }
+           return;             /* anything but ident is comment */
+       }
+       symptr = gsymptr;
+    }
+    if (symptr->type & MACBIT)
+    {
+       entermac(symptr);
+       return;
+    }
+    if (!(symptr->type & MNREGBIT))
+    {
+       error(OPEXP);
+       return;
+    }
+    if (symptr->data & REGBIT)
+    {
+       error(REGUID);
+       return;
+    }
+    mnsize = 0;
+    if ((page = (symptr->data & (PAGE1 | PAGE2))) != 0)
+    {
+#ifdef MNSIZE
+       if (page == (PAGE1 | PAGE2))
+       {
+           mnsize = 1;
+           page = 0;
+       }
+       else
+#endif
+       {
+#ifdef PAGE2_OPCODE
+           if (page == PAGE2)
+               page = PAGE2_OPCODE;
+           else
+#endif
+               page = PAGE1_OPCODE;
+           mcount = 1;
+       }
+    }
+    opcode = symptr->value_reg_or_op.op.opcode;
+#ifdef I80386
+    needcpu((page==0 && ((opcode&0xF0) == 0x60||(opcode&0xF6)==0xC0))?1:0);
+#endif
+    routine = rout_table[symptr->value_reg_or_op.op.routine];
+    getsym();
+    (*routine)();
+#ifdef I80386
+    /* We handle "rep[ne]" refix as separate instruction; check if its use is valid */
+    if (opcode == 0xF2 || opcode == 0xF3) {    /* REP */
+        rep = opcode;
+    /* Not another prefix */
+    } else if (opcode != 0x2E &&    /* CSEG */
+        opcode != 0x3E &&           /* DSEG */
+        opcode != 0x26 &&           /* ESEG */
+        opcode != 0x64 &&           /* FSEG */
+        opcode != 0x65 &&           /* GSEG */
+        opcode != 0x36 &&           /* SSEG */
+        opcode != 0xF0) {           /* LOCK */
+        if (rep == 0xF2 && (opcode&0xF6) != 0xA6)       /* REPNE CMPS/SCAS */
+            error (REPNE_STRING);
+        if (rep == 0xF3 && !((opcode&0xFC) == 0x6C ||   /* REP INS/OUTS */
+            (opcode&0xFC) == 0xA4 ||                    /* REP MOVS/CMPS */
+            (opcode&0xFC) == 0xAC ||                    /* REP SCAS/LODS */
+            (opcode&0xFE) == 0xAA))                     /* REP STOS */
+            error (REP_STRING);
+        rep = 0;
+    }
+#endif
+    if (sym != EOLSYM)
+       error(JUNK_AFTER_OPERANDS);
+#ifdef I80386
+    needcpu(page==PAGE1_OPCODE?2:0);
+
+    if (aprefix != 0)
+       ++mcount;
+    if (oprefix != 0)
+       ++mcount;
+    if (sprefix != 0)
+       ++mcount;
+#endif
+}
diff --git a/Applications/as09/bin/calljmp.bin b/Applications/as09/bin/calljmp.bin
new file mode 100644 (file)
index 0000000..90c022f
Binary files /dev/null and b/Applications/as09/bin/calljmp.bin differ
diff --git a/Applications/as09/bin/ea.bin b/Applications/as09/bin/ea.bin
new file mode 100644 (file)
index 0000000..5edc0b0
Binary files /dev/null and b/Applications/as09/bin/ea.bin differ
diff --git a/Applications/as09/bin/each.bin b/Applications/as09/bin/each.bin
new file mode 100644 (file)
index 0000000..211155f
Binary files /dev/null and b/Applications/as09/bin/each.bin differ
diff --git a/Applications/as09/bin/f.bin b/Applications/as09/bin/f.bin
new file mode 100644 (file)
index 0000000..ce695a0
Binary files /dev/null and b/Applications/as09/bin/f.bin differ
diff --git a/Applications/as09/bin/fadd.bin b/Applications/as09/bin/fadd.bin
new file mode 100644 (file)
index 0000000..9afa6fc
Binary files /dev/null and b/Applications/as09/bin/fadd.bin differ
diff --git a/Applications/as09/bin/farcall.bin b/Applications/as09/bin/farcall.bin
new file mode 100644 (file)
index 0000000..797a87c
Binary files /dev/null and b/Applications/as09/bin/farcall.bin differ
diff --git a/Applications/as09/bin/group1.bin b/Applications/as09/bin/group1.bin
new file mode 100644 (file)
index 0000000..64a01bf
Binary files /dev/null and b/Applications/as09/bin/group1.bin differ
diff --git a/Applications/as09/bin/group6.bin b/Applications/as09/bin/group6.bin
new file mode 100644 (file)
index 0000000..22ff663
Binary files /dev/null and b/Applications/as09/bin/group6.bin differ
diff --git a/Applications/as09/bin/group7.bin b/Applications/as09/bin/group7.bin
new file mode 100644 (file)
index 0000000..9570eee
Binary files /dev/null and b/Applications/as09/bin/group7.bin differ
diff --git a/Applications/as09/bin/imul.bin b/Applications/as09/bin/imul.bin
new file mode 100644 (file)
index 0000000..2b8ea16
Binary files /dev/null and b/Applications/as09/bin/imul.bin differ
diff --git a/Applications/as09/bin/incdec.bin b/Applications/as09/bin/incdec.bin
new file mode 100644 (file)
index 0000000..676e5fa
Binary files /dev/null and b/Applications/as09/bin/incdec.bin differ
diff --git a/Applications/as09/bin/inher.bin b/Applications/as09/bin/inher.bin
new file mode 100644 (file)
index 0000000..b37b3eb
Binary files /dev/null and b/Applications/as09/bin/inher.bin differ
diff --git a/Applications/as09/bin/inout.bin b/Applications/as09/bin/inout.bin
new file mode 100644 (file)
index 0000000..a215490
Binary files /dev/null and b/Applications/as09/bin/inout.bin differ
diff --git a/Applications/as09/bin/movspec.bin b/Applications/as09/bin/movspec.bin
new file mode 100644 (file)
index 0000000..6a5ef0a
Binary files /dev/null and b/Applications/as09/bin/movspec.bin differ
diff --git a/Applications/as09/bin/pushpop.bin b/Applications/as09/bin/pushpop.bin
new file mode 100644 (file)
index 0000000..f95d6b5
Binary files /dev/null and b/Applications/as09/bin/pushpop.bin differ
diff --git a/Applications/as09/bin/seg.bin b/Applications/as09/bin/seg.bin
new file mode 100644 (file)
index 0000000..43445a6
Binary files /dev/null and b/Applications/as09/bin/seg.bin differ
diff --git a/Applications/as09/bin/shdouble.bin b/Applications/as09/bin/shdouble.bin
new file mode 100644 (file)
index 0000000..91bda37
Binary files /dev/null and b/Applications/as09/bin/shdouble.bin differ
diff --git a/Applications/as09/bin/shift.bin b/Applications/as09/bin/shift.bin
new file mode 100644 (file)
index 0000000..1e31fac
Binary files /dev/null and b/Applications/as09/bin/shift.bin differ
diff --git a/Applications/as09/bin/xchg.bin b/Applications/as09/bin/xchg.bin
new file mode 100644 (file)
index 0000000..6455b67
Binary files /dev/null and b/Applications/as09/bin/xchg.bin differ
diff --git a/Applications/as09/byteord.h b/Applications/as09/byteord.h
new file mode 100644 (file)
index 0000000..baf02d0
--- /dev/null
@@ -0,0 +1,18 @@
+/* byteord.h - byte order dependencies for C compiler, assembler, linker */
+
+/* These are for the targets of everything and for linker source too. */
+
+#ifdef I8086
+# define INT_BIG_ENDIAN 0
+# define LONG_BIG_ENDIAN 0     /* except longs are back to front for Xenix */
+#endif
+
+#ifdef I80386
+# define INT_BIG_ENDIAN 0
+# define LONG_BIG_ENDIAN 0
+#endif
+
+#ifdef MC6809
+# define INT_BIG_ENDIAN 1      /* byte order in words is high-low */
+# define LONG_BIG_ENDIAN 1     /* byte order in longs is high-low */
+#endif
diff --git a/Applications/as09/chk b/Applications/as09/chk
new file mode 100755 (executable)
index 0000000..44f316a
--- /dev/null
@@ -0,0 +1,19 @@
+
+compile()
+{
+   # /lib/elksemu ./as86 -3 -k "$@"
+   ./as86 -3 -k "$@"
+}
+
+for i in `ls asm/*.asm`
+do
+       j=`basename $i .asm`
+       compile asm/$j.asm -b $j.bin -o $j.obj > /dev/null
+       cmp $j.obj obj1/$j.obj
+
+       # compile asm/$j.asm -b $j.bin > /dev/null
+       # cmp $j.bin bin/$j.bin
+
+       rm -f $j.bin $j.obj $j.asm
+done
+
diff --git a/Applications/as09/const.h b/Applications/as09/const.h
new file mode 100644 (file)
index 0000000..881e511
--- /dev/null
@@ -0,0 +1,315 @@
+
+/* Speed and space hacks for BCC */
+#ifdef __AS386_16__
+#define LOW_BYTE       0       /* must be changed for big-endian */
+#else
+
+#define S_ALIGNMENT    sizeof(long)
+#endif
+
+/* const.h - constants for assembler */
+
+/* major switches */
+
+#define MC6809                 /* generate 6809 code */
+#ifndef MC6809
+#define I80386                 /* generate 80386 code */
+#endif
+#define MNSIZE                 /* allow byte size in mnemonic, e.g. "movb" */
+#undef SOS_EDOS                        /* source OS is EDOS */
+
+/* defaults */
+
+#define DIRCHAR                '/'     /* character separating filename from dir */
+#define INBUFSIZE      8192
+#define SOS_EOLSTR     "\012"
+
+/* defaults modified by switches */
+
+#ifdef SOS_EDOS
+# undef INBUFSIZE
+# define INBUFSIZE     512
+# undef SOS_EOLSTR
+# define SOS_EOLSTR    "\015\012"
+# define STAKSIZ       256     /* table grows up to stack less this */
+#endif
+
+#ifdef __AS386_16__
+# undef INBUFSIZE
+# define INBUFSIZE     512
+# define STAKSIZ       512     /* table grows up to stack less this */
+#endif
+
+/* booleans */
+
+#define FALSE          0
+#define TRUE           1
+
+/* ASCII constants */
+
+#define ETB            23
+
+/* C tricks */
+
+#define EXTERN         extern
+#define NUL_PTR                ((void*)0)
+
+/* O/S constants */
+
+#define CREAT_PERMS    0666
+#define EOF            (-1)
+#define STDIN          0
+#define STDOUT         1
+
+enum
+{
+/* Register codes (internal to assembler). */
+#ifdef I80386
+
+/* Index regs must be first. */
+    BPREG,
+    BXREG,
+    DIREG,
+    SIREG,
+#define MAX16BITINDREG SIREG
+
+    EAXREG,
+    EBPREG,
+    EBXREG,
+    ECXREG,
+    EDIREG,
+    EDXREG,
+    ESIREG,
+    ESPREG,
+#define MAXINDREG      ESPREG
+
+    AXREG,
+    CXREG,
+    DXREG,
+    SPREG,
+
+    AHREG,
+    ALREG,
+    BHREG,
+    BLREG,
+    CHREG,
+    CLREG,
+    DHREG,
+    DLREG,
+
+    CSREG,
+    DSREG,
+    ESREG,
+    FSREG,
+    GSREG,
+    SSREG,
+
+    CR0REG,
+    CR2REG,
+    CR3REG,
+    DR0REG,
+    DR1REG,
+    DR2REG,
+    DR3REG,
+    DR6REG,
+    DR7REG,
+    TR3REG,
+    TR4REG,
+    TR5REG,
+    TR6REG,
+    TR7REG,
+
+    ST0REG,
+    ST1REG,
+    ST2REG,
+    ST3REG,
+    ST4REG,
+    ST5REG,
+    ST6REG,
+    ST7REG,
+#endif /* I80386 */
+
+#ifdef MC6809
+
+/* Index regs must be first, then PC. */
+    SREG,
+    UREG,
+    XREG,
+    YREG,
+#define MAXINDREG      YREG
+
+    PCREG,
+    AREG,
+    BREG,
+    CCREG,
+    DPREG,
+    DREG,
+#endif /* MC6809 */
+
+    NOREG
+};
+
+#ifdef I80386
+enum
+{
+/* Type and size keywords. */
+    BYTEOP,
+    DWORDOP,
+    FWORDOP,
+    FAROP,
+    PTROP,
+    PWORDOP,
+    QWORDOP,
+    TBYTEOP,
+    WORDOP
+};
+#endif /* I80386 */
+
+/* special chars */
+
+#define EOL            0
+#define MACROCHAR      '?'
+
+enum
+{
+/* Symbol codes. */
+
+/* The first 2 must be from chars in identifiers. */
+    IDENT,
+    INTCONST,
+
+/* The next few are best for other possibly-multi-char tokens. */
+    ADDOP,                     /* also ++ */
+    BINCONST,
+    CHARCONST,
+    GREATERTHAN,               /* also >> and context-sensitive */
+    HEXCONST,
+    LESSTHAN,                  /* also << and context-sensitive */
+    SUBOP,                     /* also -- */
+    WHITESPACE,
+
+    ANDOP,
+    COMMA,
+    EOLSYM,
+    EQOP,
+    IMMEDIATE,
+    INDIRECT,
+    LBRACKET,
+    LPAREN,
+    MACROARG,
+    NOTOP,
+    OROP,
+    OTHERSYM,
+    POSTINCOP,
+    PREDECOP,
+    RBRACKET,
+    RPAREN,
+    SLASH,                     /* context-sensitive */
+    SLOP,
+    SROP,
+    STAR,                      /* context-sensitive */
+    STRINGCONST,
+    COLON
+};
+
+/* symbol table entry */
+
+                               /* type entry contains following flags */
+#define ENTBIT         (1<<0)  /* entry point (= OBJ_N_MASK) */
+#define COMMBIT                (1<<1)  /* common */
+#define LABIT          (1<<2)  /* label (a PC location or defined by EQU) */
+#define MNREGBIT       (1<<3)  /* mnemonic for op or pseudo-op, or register */
+#define MACBIT         (1<<4)  /* macro */
+#define REDBIT         (1<<5)  /* redefined (if with LABIT or VARBIT), to do
+                                * with SA_MASK (if with COMMBIT), otherwise
+                                * means globl */
+#define VARBIT         (1<<6)  /* variable (i.e. something defined by SET) */
+#define EXPBIT         (1<<7)  /* exported (= OBJ_E_MASK) */
+
+                               /* data entry contains following flags, valid */
+                               /* for expressions as well as syms */
+#define PAGE1          (1<<0)  /* page 1 machine op = MNREGBIT | PAGE1 */
+#define PAGE2          (1<<1)  /* page 2 machine op = MNREGBIT | PAGE2 */
+#define REGBIT         (1<<2)  /* register = MNREGBIT | REGBIT */
+#define SIZEBIT                (1<<3)  /* sizing mnemonic = MNREGBIT | SIZEBIT */
+#define SEGM           0x0F    /* 1st 4 bits reused for segment if !MNREGBIT */
+#define RELBIT         (1<<4)  /* relative (= OBJ_A_MASK) */
+#define FORBIT         (1<<5)  /* forward referenced */
+#define IMPBIT         (1<<6)  /* imported (= OBJ_I_MASK) */
+#define UNDBIT         (1<<7)  /* undefined */
+
+/* object code format (Introl) */
+
+#define OBJ_SEGSZ_TWO  0x02    /* size 2 code for segment size descriptor */
+
+#define OBJ_MAX_ABS_LEN        64      /* max length of chunk of absolute code */
+
+#define OBJ_ABS                0x40    /* absolute code command */
+#define OBJ_OFFSET_REL 0x80    /* offset relocation command */
+#define OBJ_SET_SEG    0x20    /* set segment command */
+#define OBJ_SKIP_1     0x11    /* skip with 1 byte count */
+#define OBJ_SKIP_2     0x12    /* skip with 2 byte count */
+#define OBJ_SKIP_4     0x13    /* skip with 4 byte count */
+#define OBJ_SYMBOL_REL 0xC0    /* symbol relocation command */
+
+#define OBJ_A_MASK     0x10    /* absolute bit(symbols) */
+#if OBJ_A_MASK - RELBIT                /* must match internal format (~byte 1 -> 0) */
+oops - RELBIT misplaced
+#endif
+#define OBJ_E_MASK     0x80    /* exported bit (symbols) */
+#if OBJ_E_MASK - EXPBIT                /* must match internal format (byte 0 -> 0) */
+oops - EXPBIT misplaced
+#endif
+#define OBJ_I_MASK     0x40    /* imported bit (symbols) */
+#if OBJ_I_MASK - IMPBIT                /* must match internal format (byte 1 -> 0) */
+oops - IMPBIT misplaced
+#endif
+#define OBJ_N_MASK     0x01    /* entry bit (symbols) */
+#if OBJ_N_MASK - ENTBIT                /* must match internal format (byte 0 -> 1) */
+oops - ENTBIT misplaced
+#endif
+#define OBJ_SA_MASK    0x20    /* size allocation bit (symbols) */
+#define OBJ_SZ_ONE     0x40    /* size one code for symbol value */
+#define OBJ_SZ_TWO     0x80    /* size two code for symbol value */
+#define OBJ_SZ_FOUR    0xC0    /* size four code for symbol value */
+
+#define OBJ_R_MASK     0x20    /* PC-rel bit (off & sym reloc commands) */
+#define OBJ_SEGM_MASK  0x0F    /* segment mask (symbols, off reloc command) */
+
+#define OBJ_OF_MASK    0x03    /* offset size code for symbol reloc */
+#define OBJ_S_MASK     0x04    /* symbol number size code for symbol reloc */
+
+#define SYMLIS_NAMELEN 26
+#define SYMLIS_LEN     (sizeof (struct sym_listing_s))
+
+#define FILNAMLEN      64      /* max length of a file name */
+#define LINLEN         256     /* max length of input line */
+#define LINUM_LEN      5       /* length of formatted line number */
+
+#define SPTSIZ         1024    /* number of symbol ptrs */
+                               /* pseudo-op flags */
+#define POPHI          1       /* set to print hi byte of adr */
+#define POPLO          2       /* to print lo byte of ADR */
+#define POPLC          4       /* to print LC */
+#define POPLONG                8       /* to print high word of ADR */
+#define MAXBLOCK       8       /* max nesting level of BLOCK stack */
+#define MAXGET         8       /* max nesting level of GET stack */
+#define MAXIF          8       /* max nesting level of IF stack */
+#define MACPSIZ                (128 / sizeof (struct schain_s))
+                               /* size of macro param buffer */
+#define MAXMAC         8       /* max nesting level of macro stack */
+#define NLOC           16      /* number of location counters */
+#ifdef I80386
+#define NO_SIB         0340    /* illegal sib (3 with 4) to mean no sib */
+#endif
+
+/* special segments */
+
+#define BSSLOC         3
+#define DATALOC                3
+#define DPLOC          2
+#define STRLOC         1
+#define TEXTLOC                0
+
+#include "errors.h"
+
diff --git a/Applications/as09/errors.c b/Applications/as09/errors.c
new file mode 100644 (file)
index 0000000..1c68950
--- /dev/null
@@ -0,0 +1,111 @@
+
+#include "syshead.h"
+#include "const.h"
+#include "errors.h"
+
+/* Error codes. */
+
+/* Syntax errors. */
+char COMEXP[] =          "comma expected";
+char DELEXP[] =          "delimiter expected";
+char FACEXP[] =          "factor expected";
+char IREGEXP[] =         "index register expected";
+char LABEXP[] =          "label expected";
+char LPEXP[] =           "left parentheses expected";
+char OPEXP[] =           "opcode expected";
+char RBEXP[] =           "right bracket expected";
+char REGEXP[] =          "register expected";
+char RPEXP[] =           "right parentheses expected";
+char SPEXP[] =           "space expected";
+
+/* Expression errors. */
+char ABSREQ[] =          "absolute expression required";
+char NONIMPREQ[] =       "non-imported expression required";
+char RELBAD[] =          "relocation impossible";
+
+/* Label errors. */
+char ILLAB[] =           "illegal label";
+char MACUID[] =          "MACRO used as identifier";
+char MISLAB[] =          "missing label";
+char MNUID[] =           "opcode used as identifier";
+char REGUID[] =          "register used as identifier";
+char RELAB[] =           "redefined label";
+char UNBLAB[] =          "unbound label";
+char UNLAB[] =           "undefined label";
+char VARLAB[] =          "variable used as label";
+
+/* Addressing errors. */
+char ABOUNDS[] =         "address out of bounds";
+char DBOUNDS[] =         "data out of bounds";
+char ILLMOD[] =          "illegal address mode";
+char ILLREG[] =          "illegal register";
+
+/* Control structure errors. */
+char ELSEBAD[] =         "no matching IF";
+char ENDBBAD[] =         "no matching BLOCK";
+char EOFBLOCK[] =        "end of file in BLOCK";
+char EOFIF[] =           "end of file in IF";
+char EOFLC[] =           "location counter was undefined at end";
+char EOFMAC[] =          "end of file in MACRO";
+char FAILERR[] =         "user-generated error";
+
+/* Overflow errors. */
+char BLOCKOV[] =         "BLOCK stack overflow";
+char BWRAP[] =           "binary file wrap-around";
+char COUNTOV[] =         "counter overflow";
+char COUNTUN[] =         "counter underflow";
+char GETOV[] =           "GET stack overflow";
+char IFOV[] =            "IF stack overflow";
+
+char LINLONG[] =         "line too long";
+char MACOV[] =           "MACRO stack overflow";
+char OBJSYMOV[] =        "object symbol table overflow";
+char OWRITE[] =          "program overwrite";
+char PAROV[] =           "parameter table overflow";
+char SYMOV[] =           "symbol table overflow";
+char SYMOUTOV[] =        "output symbol table overflow";
+
+/* I/O errors. */
+char OBJOUT[] =          "error writing object file";
+
+/* Miscellaneous errors. */
+char AL_AX_EAX_EXP[] =   "al ax or eax expected";
+char CTLINS[] =          "control character in string";
+char FURTHER[] =         "futher errors suppressed";
+char ILL_IMM_MODE[] =    "illegal immediate mode";
+char ILL_IND_TO_IND[] =  "illegal indirect to indirect";
+char ILL_IND[] =         "illegal indirection";
+char ILL_IND_PTR[] =     "illegal indirection from previous 'ptr'";
+char ILL_SCALE[] =       "illegal scale";
+char ILL_SECTION[] =     "illegal section";
+char ILL_SEG_REG[] =     "illegal segment register";
+char ILL_SOURCE_EA[] =   "illegal source effective address";
+char ILL_SIZE[] =        "illegal size";
+char IMM_REQ[] =         "immediate expression expected";
+char INDEX_REG_EXP[] =   "index register expected";
+char IND_REQ[] =         "indirect expression required";
+char MISMATCHED_SIZE[] =  "mismatched size";
+char NOIMPORT[] =        "no imports with binary file output";
+char REENTER[] =         "multiple ENTER pseudo-ops";
+char REL_REQ[] =         "relative expression required";
+char REPEATED_DISPL[] =  "repeated displacement";
+char SEGREL[] =          "segment or relocatability redefined";
+char SEG_REG_REQ[] =     "segment register required";
+char SIZE_UNK[] =        "size unknown";
+char UNKNOWN_ESCAPE_SEQUENCE[] =  "unknown escape sequence";
+
+char FP_REG_REQ[] =      "FP register required";
+char FP_REG_NOT_ALLOWED[] =  "FP register not allowed";
+char ILL_FP_REG[] =      "illegal FP register";
+char ILL_FP_REG_PAIR[] =  "illegal FP register pair";
+char JUNK_AFTER_OPERANDS[] =  "junk after operands";
+
+char ALREADY[] =         "already defined";
+char UNSTABLE_LABEL[] =  "label moved in last pass add -O?";
+
+char REPNE_STRING[] =    "CMPS or SCAS expected";
+char REP_STRING[] =      "string instruction expected";
+
+/* Warnings. */
+char CPUCLASH[] =        "instruction illegal for current cpu";
+char SHORTB[] =          "short branch would do";
diff --git a/Applications/as09/errors.h b/Applications/as09/errors.h
new file mode 100644 (file)
index 0000000..451ac41
--- /dev/null
@@ -0,0 +1,113 @@
+
+#ifndef _H_ERRORS
+#define _H_ERRORS
+/* Error codes. */
+
+/* Syntax errors. */
+EXTERN char COMEXP[];           /* "comma expected" */
+EXTERN char DELEXP[];           /* "delimiter expected" */
+EXTERN char FACEXP[];           /* "factor expected" */
+EXTERN char IREGEXP[];          /* "index register expected" */
+EXTERN char LABEXP[];           /* "label expected" */
+EXTERN char LPEXP[];            /* "left parentheses expected" */
+EXTERN char OPEXP[];            /* "opcode expected" */
+EXTERN char RBEXP[];            /* "right bracket expected" */
+EXTERN char REGEXP[];           /* "register expected" */
+EXTERN char RPEXP[];            /* "right parentheses expected" */
+EXTERN char SPEXP[];            /* "space expected" */
+
+/* Expression errors. */
+EXTERN char ABSREQ[];           /* "absolute expression required" */
+EXTERN char NONIMPREQ[];        /* "non-imported expression required" */
+EXTERN char RELBAD[];           /* "relocation impossible" */
+
+/* Label errors. */
+EXTERN char ILLAB[];            /* "illegal label" */
+EXTERN char MACUID[];           /* "MACRO used as identifier" */
+EXTERN char MISLAB[];           /* "missing label" */
+EXTERN char MNUID[];            /* "opcode used as identifier" */
+EXTERN char REGUID[];           /* "register used as identifier" */
+EXTERN char RELAB[];            /* "redefined label" */
+EXTERN char UNBLAB[];           /* "unbound label" */
+EXTERN char UNLAB[];            /* "undefined label" */
+EXTERN char VARLAB[];           /* "variable used as label" */
+
+/* Addressing errors. */
+EXTERN char ABOUNDS[];          /* "address out of bounds" */
+EXTERN char DBOUNDS[];          /* "data out of bounds" */
+EXTERN char ILLMOD[];           /* "illegal address mode" */
+EXTERN char ILLREG[];           /* "illegal register" */
+
+/* Control structure errors. */
+EXTERN char ELSEBAD[];          /* "no matching IF" */
+#define ELSEIFBAD       ELSEBAD
+EXTERN char ENDBBAD[];          /* "no matching BLOCK" */
+#define ENDIFBAD        ELSEBAD
+EXTERN char EOFBLOCK[];         /* "end of file in BLOCK" */
+EXTERN char EOFIF[];            /* "end of file in IF" */
+EXTERN char EOFLC[];            /* "location counter was undefined at end" */
+EXTERN char EOFMAC[];           /* "end of file in MACRO" */
+EXTERN char FAILERR[];          /* "user-generated error" */
+
+/* Overflow errors. */
+EXTERN char BLOCKOV[];          /* "BLOCK stack overflow" */
+EXTERN char BWRAP[];            /* "binary file wrap-around" */
+EXTERN char COUNTOV[];          /* "counter overflow" */
+EXTERN char COUNTUN[];          /* "counter underflow" */
+EXTERN char GETOV[];            /* "GET stack overflow" */
+EXTERN char IFOV[];             /* "IF stack overflow" */
+
+EXTERN char LINLONG[];          /* "line too long" */
+EXTERN char MACOV[];            /* "MACRO stack overflow" */
+EXTERN char OBJSYMOV[];         /* "object symbol table overflow" */
+EXTERN char OWRITE[];           /* "program overwrite" */
+EXTERN char PAROV[];            /* "parameter table overflow" */
+EXTERN char SYMOV[];            /* "symbol table overflow" */
+EXTERN char SYMOUTOV[];         /* "output symbol table overflow" */
+
+/* I/O errors. */
+EXTERN char OBJOUT[];           /* "error writing object file" */
+
+/* Miscellaneous errors. */
+EXTERN char AL_AX_EAX_EXP[];    /* "al ax or eax expected" */
+EXTERN char CTLINS[];           /* "control character in string" */
+EXTERN char FURTHER[];          /* "futher errors suppressed" */
+EXTERN char ILL_IMM_MODE[];     /* "illegal immediate mode" */
+EXTERN char ILL_IND_TO_IND[];   /* "illegal indirect to indirect" */
+EXTERN char ILL_IND[];          /* "illegal indirection" */
+EXTERN char ILL_IND_PTR[];      /* "illegal indirection from previous 'ptr'" */
+EXTERN char ILL_SCALE[];        /* "illegal scale" */
+EXTERN char ILL_SECTION[];      /* "illegal section" */
+EXTERN char ILL_SEG_REG[];      /* "illegal segment register" */
+EXTERN char ILL_SOURCE_EA[];    /* "illegal source effective address" */
+EXTERN char ILL_SIZE[];         /* "illegal size" */
+EXTERN char IMM_REQ[];          /* "immediate expression expected" */
+EXTERN char INDEX_REG_EXP[];    /* "index register expected" */
+EXTERN char IND_REQ[];          /* "indirect expression required" */
+EXTERN char MISMATCHED_SIZE[];  /* "mismatched size" */
+EXTERN char NOIMPORT[];         /* "no imports with binary file output" */
+EXTERN char REENTER[];          /* "multiple ENTER pseudo-ops" */
+EXTERN char REL_REQ[];          /* "relative expression required" */
+EXTERN char REPEATED_DISPL[];   /* "repeated displacement" */
+EXTERN char SEGREL[];           /* "segment or relocatability redefined" */
+EXTERN char SEG_REG_REQ[];      /* "segment register required" */
+EXTERN char SIZE_UNK[];         /* "size unknown" */
+EXTERN char UNKNOWN_ESCAPE_SEQUENCE[]; /* "unknown escape sequence" */
+
+EXTERN char FP_REG_REQ[];       /* "FP register required" */
+EXTERN char FP_REG_NOT_ALLOWED[]; /* "FP register not allowed" */
+EXTERN char ILL_FP_REG[];       /* "illegal FP register" */
+EXTERN char ILL_FP_REG_PAIR[];  /* "illegal FP register pair" */
+EXTERN char JUNK_AFTER_OPERANDS[]; /* "junk after operands" */
+
+EXTERN char ALREADY[];          /* "already defined" */
+EXTERN char UNSTABLE_LABEL[];   /* "label moved in last pass add -O?" */
+
+EXTERN char REPNE_STRING[];     /* "CMPS or SCAS expected" */
+EXTERN char REP_STRING[];       /* "string instruction expected" */
+
+/* Warnings. */
+EXTERN char CPUCLASH[];         /* "instruction illegal for current cpu" */
+EXTERN char SHORTB[];           /* "short branch would do" */
+
+#endif
diff --git a/Applications/as09/express.c b/Applications/as09/express.c
new file mode 100644 (file)
index 0000000..a43a919
--- /dev/null
@@ -0,0 +1,410 @@
+/* express.c - expression handler for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "address.h"
+#include "globvar.h"
+#include "scan.h"
+#include "source.h"
+
+static void experror P((char * err_str));
+static void expundefined P((void));
+static void simple2 P((void));
+static void simple P((void));
+static void term P((void));
+static void factor2 P((void));
+
+void absexpres(void)
+{
+    expres();
+    chkabs();
+}
+
+/* check lastexp.data is abs */
+
+void chkabs(void)
+{
+    if (lastexp.data & RELBIT)
+    {
+       if (pass == last_pass)
+           error(ABSREQ);
+       expundefined();
+    }
+}
+
+void experror(char *err_str)
+{
+    error(err_str);
+    expundefined();
+}
+
+void expundefined(void)
+{
+    if( last_pass == 1 )
+       lastexp.data = FORBIT | UNDBIT;
+    else
+       lastexp.data = UNDBIT;
+}
+
+void nonimpexpres(void)
+{
+    expres();
+    if (lastexp.data & IMPBIT)
+       experror(NONIMPREQ);
+}
+
+/* generate relocation error if pass 2, make lastexp.data forward&undefined */
+
+void showrelbad(void)
+{
+    if (pass == last_pass)
+       error(RELBAD);
+    expundefined();
+}
+
+void symabsexpres(void)
+{
+    getsym();
+    absexpres();
+}
+
+void symexpres(void)
+{
+    getsym();
+    expres();
+}
+
+/*
+  expres() parses expression = simple expression [op simple expression],
+  where op is =, < or >.
+  Parameters: sym, number in number, identifier from symname to lineptr - 1.
+  Returns value in lastexp.
+*/
+
+void expres(void)
+{
+    offset_t leftoffset;
+
+    simple();
+    leftoffset = lastexp.offset;
+    if (sym == EQOP)
+    {
+       simple2();
+       if (leftoffset == lastexp.offset)
+           lastexp.offset = -1;
+       else
+           lastexp.offset = 0;
+    }
+    else if (sym == LESSTHAN)
+    {
+       /* context-sensitive, LESSTHAN really means less than here */
+       simple2();
+       if (leftoffset < lastexp.offset)
+           lastexp.offset = -1;
+       else
+           lastexp.offset = 0;
+    }
+    else if (sym == GREATERTHAN)
+    {
+       /* context-sensitive, GREATERTHAN really means greater than here */
+       simple2();
+       if (leftoffset > lastexp.offset)
+           lastexp.offset = -1;
+       else
+           lastexp.offset = 0;
+    }
+}
+
+/* get symbol and 2nd simple expression, check both rel or both abs */
+
+void simple2(void)
+{
+    unsigned char leftdata;
+
+    leftdata = lastexp.data;
+    getsym();
+    simple();
+    if ((leftdata | lastexp.data) & IMPBIT ||
+       (leftdata ^ lastexp.data) & (RELBIT | SEGM))
+       showrelbad();
+    else
+       lastexp.data = (leftdata & lastexp.data) & ~(RELBIT | SEGM);
+}
+
+/*
+  simple() parses simple expression = [+-] term {op term},
+  where op is +, -, or \ (OR).
+*/
+
+void simple(void)
+{
+    offset_t leftoffset;
+    unsigned char leftdata;
+
+    if (sym == ADDOP || sym == SUBOP)
+       lastexp.data = lastexp.offset = 0;
+    else
+       term();
+    while (TRUE)
+    {
+       leftoffset = lastexp.offset;
+       leftdata = lastexp.data;
+       if (sym == ADDOP)
+       {
+           getsym();
+           term();
+           if (leftdata & lastexp.data & RELBIT)
+               showrelbad();   /* rel + rel no good */
+           else
+               lastexp.data |= leftdata;
+           lastexp.offset += leftoffset;
+       }
+       else if (sym == SUBOP)
+       {
+           getsym();
+           term();
+           /* check not abs - rel or rel - rel with mismatch */
+           if (lastexp.data & RELBIT &&
+               (!(leftdata & RELBIT) ||
+                (leftdata | lastexp.data) & IMPBIT ||
+                (leftdata ^ lastexp.data) & (RELBIT | SEGM)))
+               showrelbad();
+           else
+               lastexp.data = ((leftdata | lastexp.data) & ~(RELBIT | SEGM))
+                            | ((leftdata ^ lastexp.data) &  (RELBIT | SEGM));
+           lastexp.offset = leftoffset - lastexp.offset;
+       }
+       else if (sym == OROP)
+       {
+           getsym();
+           term();
+           lastexp.data |= leftdata;
+           chkabs();           /* both must be absolute */
+           lastexp.offset |= leftoffset;
+       }
+       else
+           return;
+    }
+}
+
+/* term() parses term = factor {op factor}, where op is *, /, &, <<, or >>. */
+
+void term(void)
+{
+    offset_t leftoffset;
+
+    factor();
+    while (TRUE)
+    {
+       leftoffset = lastexp.offset;
+       if (sym == STAR)
+       {
+           /* context-sensitive, STAR means multiplication here */
+           factor2();
+           lastexp.offset *= leftoffset;
+       }
+       else if (sym == SLASH)
+       {
+           /* context-sensitive, SLASH means division here */
+           factor2();
+           lastexp.offset = leftoffset / lastexp.offset;
+       }
+       else if (sym == ANDOP)
+       {
+           factor2();
+           lastexp.offset &= leftoffset;
+       }
+       else if (sym == SLOP)
+       {
+           factor2();
+           lastexp.offset = leftoffset << lastexp.offset;
+       }
+       else if (sym == SROP)
+       {
+           factor2();
+           lastexp.offset = leftoffset >> lastexp.offset;
+       }
+       else
+           return;
+    }
+}
+
+/* get symbol and 2nd or later factor, check both abs */
+
+void factor2(void)
+{
+    unsigned char leftdata;
+
+    leftdata = lastexp.data;
+    getsym();
+    factor();
+    lastexp.data |= leftdata;
+    chkabs();
+}
+
+/*
+  factor() parses factor = number | identifier | * | (expression) | ! factor,
+  ! is complementation. Returns value in lastexp.offset, possible flags
+  IMPBIT, FORBIT, RELBIT and UNDBIT in lastexp.data, and segment in SEGM
+  part of lastexp.data, and lastexp.sym at imported symbol if IMPBIT.
+  If the factor is an identifier, LOOKUP is used to get its value
+  (so the ident is installed in the symbol table if necessary, with
+  default flags inidata). If the identifier is not a label,
+  (could be imported, or later in the program), its FORBIT is set.
+  The expression FORBIT, IMPBIT, RELBIT, UNDBIT and SEGM are then
+  taken from the identifier.
+*/
+
+void factor(void)
+{
+    switch (sym)
+    {
+    case SLASH:
+       /* context-sensitive, SLASH means a hex number here */
+       context_hexconst();
+    case INTCONST:
+       lastexp.data = 0;       /* absolute & not forward or undefined */
+       lastexp.offset = number;
+       getsym();
+       return;
+    case IDENT:
+       {
+           register struct sym_s *symptr;
+
+           symptr = gsymptr;
+           if (symptr->type & (MNREGBIT | MACBIT))
+               experror(symptr->type & MACBIT ? MACUID :
+                        symptr->data & REGBIT ? REGUID : MNUID);
+           else
+           {
+               if (!(symptr->type & (LABIT | VARBIT)))
+               {
+                    if( last_pass == 1 )
+                       symptr->data |= FORBIT;
+                   lastexp.sym = symptr;
+               }
+               if (pass != last_pass)
+               {
+                    if( last_pass == 1 )
+                       lastexp.data = symptr->data &
+                           (FORBIT | RELBIT | UNDBIT | SEGM);
+                   else
+                       lastexp.data = symptr->data &
+                           (RELBIT | UNDBIT | SEGM);
+                               /* possible flags for pass 1 */
+                   lastexp.offset = symptr->value_reg_or_op.value;
+               }
+               else
+               {
+                   if ((lastexp.data = symptr->data) & IMPBIT)
+                       lastexp.offset = 0;     /* value != 0 for commons */
+                                               /* OK even if UNDBIT */
+                   else
+                   {
+                       lastexp.offset = symptr->value_reg_or_op.value;
+                       if (lastexp.data & UNDBIT)
+                           experror(UNBLAB);
+                   }
+               }
+           }
+           getsym();
+           return;
+       }
+#ifndef MC6809
+    case LBRACKET:
+       if (!asld_compatible)
+           break;              /* error, LPAREN is the grouping symbol */
+       getsym();
+       expres();
+       if (sym != RBRACKET)
+           error(RBEXP);
+       else
+           getsym();
+       return;
+#endif
+    case LPAREN:
+#ifndef MC6809
+       if (asld_compatible)
+           break;              /* error, LBRACKET is the grouping symbol */
+#endif
+       getsym();
+       expres();
+       if (sym != RPAREN)
+           error(RPEXP);
+       else
+           getsym();
+       return;
+    case NOTOP:
+       getsym();
+       factor();
+       chkabs();
+       lastexp.offset = ~lastexp.offset;
+       return;
+    case ADDOP:
+       getsym();
+       factor();
+       return;
+    case SUBOP:
+       getsym();
+       factor();
+       chkabs();
+       lastexp.offset = -lastexp.offset;
+       return;
+    case STAR:
+       /* context-sensitive, STAR means location counter here */
+       lastexp.offset = lc;
+       if ((lastexp.data = lcdata) & UNDBIT && pass == last_pass)
+           experror(UNBLAB);
+       getsym();
+       return;
+    }
+    experror(FACEXP);
+}
+
+/*
+  string compare for IFC/ELSEIFC
+  expects (<string1>,<string2>)
+  returns logical value in lastexp
+*/
+
+void scompare(void)
+{
+    /* prepare flags for OK, lastexp.offset for error */
+    lastexp.data = lastexp.offset = 0;
+    if (sym != LPAREN)
+       experror(LPEXP);
+    else
+    {
+       register char *string1;
+       register char *string2;
+
+       for (string2 = string1 = lineptr; *string2 != ','; ++string2)
+           if (*string2 == 0 || *string2 == ')')
+           {
+               symname = string2;
+               experror(COMEXP);
+               return;
+           }
+       string2++;
+       while (*string1++ == *string2++)
+           ;
+       if (string2[-1] == ')')
+       {
+           if (string1[-1] == ',')
+               lastexp.offset = TRUE;  /* else leave FALSE */
+           lineptr = string2;
+       }
+       else                    /* FALSE, keep reading to verify syntax */
+       {
+           for (; *string2 != ')'; ++string2)
+               if (*string2 == 0 || *string2 == ',')
+               {
+                   symname = string2;
+                   experror(RPEXP);
+               }
+           lineptr = ++string2;
+       }
+       getsym();
+    }
+}
diff --git a/Applications/as09/file.h b/Applications/as09/file.h
new file mode 100644 (file)
index 0000000..11dea71
--- /dev/null
@@ -0,0 +1,17 @@
+/* file.h - global variables involving files for assembler */
+
+EXTERN char *filnamptr;                /* file name pointer */
+EXTERN char *truefilename;     /* in case actual source name is a tmpname */
+
+EXTERN fd_t infil;             /* current input file (stacked, 0 = memory) */
+
+/* Output fds */
+EXTERN unsigned char outfd;    /* output fd for writer fns */
+EXTERN fd_t binfil;            /* binary output file (0 = memory) */
+EXTERN fd_t lstfil;            /* list output file (0 = standard) */
+EXTERN fd_t objfil;            /* object output file */
+EXTERN fd_t symfil;            /* symbol table output file */
+
+/* readsrc internals */
+EXTERN unsigned infil0;                /* Number of first input area */
+EXTERN unsigned infiln;                /* Number of current input area */
diff --git a/Applications/as09/flag.h b/Applications/as09/flag.h
new file mode 100644 (file)
index 0000000..d9124e0
--- /dev/null
@@ -0,0 +1,5 @@
+/* flag.h - global structured-flag variables for assembler */
+
+EXTERN struct flags_s list;    /* listing on/off */
+EXTERN struct flags_s maclist; /* list macros on/off */
+EXTERN struct flags_s as_warn; /* warnings on/off */
diff --git a/Applications/as09/genbin.c b/Applications/as09/genbin.c
new file mode 100644 (file)
index 0000000..a6228e9
--- /dev/null
@@ -0,0 +1,272 @@
+/* genbin.c - binary code generation routines for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "address.h"
+#include "file.h"
+#include "globvar.h"
+
+#ifdef USE_FIXED_HEAP
+static char *asmbeg;           /* beginning of assembler code */
+                               /* for overwrite check */
+                               /* bss-init to zero = NULL and not changed */
+#endif
+
+/* Sneaky stuff, the start of a binary file can be _negative_ for the I80386
+   assembler. The -ve addresses are ones over 2GB (or "org -32") */
+#ifdef I80386
+static soffset_t binfbuf;      /* binary code buffer for file (counter) */
+static soffset_t binmax;       /* maximum value of binmbuf for pass 1 */
+static soffset_t binmin;       /* minimum value of binmbuf for pass 1 */
+#define PT soffset_t
+#else
+static offset_t binfbuf;       /* binary code buffer for file (counter) */
+static offset_t binmax;        /* maximum value of binmbuf for pass 1 */
+static offset_t binmin;        /* minimum value of binmbuf for pass 1 */
+#define PT offset_t
+#endif
+
+static void putbinoffset P((offset_t offset, count_t size));
+
+/* write header to binary file */
+
+void binheader(void)
+{
+#ifdef BINSYM
+    if ((outfd = binfil) != 0x0 && binmbuf_set && binmax >= binmin)
+    {
+       writec(0x0);            /* binary header byte */
+#ifdef LONG_BINHEADER
+       writeoff(binmax - binmin);      /* program length */
+       writeoff(binfbuf = binmin);     /* program start */
+#else
+       writew((unsigned) (binmax - binmin));   /* program length */
+       writew((unsigned) (binfbuf = binmin));  /* program start */
+#endif
+    }
+#else
+    if ( ( outfd = symfil ) && binmbuf_set && binmax >= binmin)
+    {
+        int sft;
+        writec('+'); writec(' ');
+       for(sft=SIZEOF_OFFSET_T*8-4; sft >= 0; sft-=4)
+           writec(hexdigit[(binmin>>sft) & 0xF]);
+       writesn(" ----- $start");
+
+        writec('+'); writec(' ');
+       for(sft=SIZEOF_OFFSET_T*8-4; sft >= 0; sft-=4)
+           writec(hexdigit[(binmax>>sft) & 0xF]);
+       writesn(" ----- $end");
+
+       binfbuf = binmin;       /* program start */
+    }
+#endif
+}
+
+/* write trailer to binary file */
+
+void bintrailer()
+{
+#ifdef BINSYM
+    if ((outfd = binfil) != 0x0 && (pedata & UNDBIT) != UNDBIT && binmbuf_set)
+    {
+       writec(0xFF);           /* binary trailer byte */
+       writew(0x0);            /* further trailer bytes */
+#ifdef LONG_BINHEADER
+       writeoff(pedata & UNDBIT ? binmin : progent);   /* entry point */
+#else
+       writew(pedata & UNDBIT ? (unsigned) binmin : (unsigned) progent);
+#endif
+    }
+#endif
+}
+
+/* generate binary code for current line */
+
+void genbin(void)
+{
+    struct address_s *adrptr;
+    char *bufptr;
+    unsigned char remaining;
+
+    if (binaryg && mcount != 0x0)
+    {
+       if (popflags)
+       {
+           if (fcflag)
+           {
+               bufptr = databuf.fcbuf;
+               remaining = mcount;
+               do
+                   putbin(*bufptr++);
+               while (--remaining != 0x0);
+           }
+           if (fdflag)
+           {
+               adrptr = databuf.fdbuf;
+               remaining = mcount;
+               do
+               {
+                   putbinoffset(adrptr->offset, 0x2);
+                   ++adrptr;
+               }
+               while ((remaining -= 0x2) != 0x0);
+           }
+#if SIZEOF_OFFSET_T > 0x2
+           if (fqflag)
+           {
+               adrptr = databuf.fqbuf;
+               remaining = mcount;
+               do
+               {
+                   putbinoffset(adrptr->offset, 0x4);
+                   ++adrptr;
+               }
+               while ((remaining -= 0x4) != 0x0);
+           }
+#endif
+       }
+       else
+       {
+           remaining = mcount - 0x1;   /* count opcode immediately */
+#ifdef I80386
+           if (aprefix != 0x0)
+           {
+               putbin(aprefix);
+               --remaining;
+           }
+           if (oprefix != 0x0)
+           {
+               putbin(oprefix);
+               --remaining;
+           }
+           if (sprefix != 0x0)
+           {
+               putbin(sprefix);
+               --remaining;
+           }
+#endif
+           if (page != 0x0)
+           {
+               putbin(page);
+               --remaining;
+           }
+           putbin(opcode);
+           if (remaining != 0x0)
+           {
+               if (postb != 0x0)
+               {
+                   putbin(postb);
+                   --remaining;
+               }
+#ifdef I80386
+               if (sib != NO_SIB)
+               {
+                   putbin(sib);
+                   --remaining;
+               }
+#endif
+               if (remaining != 0x0)
+                   putbinoffset(lastexp.offset, remaining);
+           }
+#ifdef I80386
+           if (immcount != 0x0)
+               putbinoffset(immadr.offset, immcount);
+#endif
+       }
+       /* else no code for this instruction, or already generated */
+    }
+}
+
+/* initialise private variables */
+
+void initbin(void)
+{
+#ifdef I80386
+    binmin = ((offset_t)-1 >>1);       /* greater than anything */
+#else
+    binmin = -1;               /* greater than anything */
+#endif
+}
+
+/* write char to binary file or directly to memory */
+
+void putbin(opcode_pt ch)
+{
+    if (binfil != 0x0)
+    {
+       if (!binaryc)           /* pass 1, just record limits */
+       {
+           if ((PT)binmbuf < binmin)
+               binmin = binmbuf;
+           binmbuf++;
+           if ((PT)binmbuf > binmax)
+               binmax = binmbuf;
+       }
+       else
+       {
+#if 0
+           if (binfbuf > (PT)binmbuf)
+           {
+               error(BWRAP);   /* file buffer ahead of memory buffer */
+           }
+           else
+#endif
+           {
+#ifdef MSDOS
+static PT zapptr = 0;
+#endif
+               outfd = binfil;
+#ifdef MSDOS
+               while (binfbuf < (PT)binmbuf && binfbuf >= zapptr+binmin)
+               {
+                   writec(0);
+                   ++binfbuf;
+                   ++zapptr;
+               }
+#endif
+               if( binfbuf != (PT)binmbuf)
+                   if( lseek(binfil, (long)((PT)binmbuf-binfbuf), 1) < 0 )
+                       error(BWRAP);
+               binfbuf = binmbuf;
+               writec(ch);
+               binmbuf = ++binfbuf;
+           }
+       }
+    }
+#ifdef USE_FIXED_HEAP
+    else if (binaryc && !(lcdata & UNDBIT))
+       /* memory output, and enabled */
+    {
+       register char *bufptr;
+
+       if ((bufptr = (char *) binmbuf) >= asmbeg && bufptr < temp_buf())
+           error(OWRITE);
+       else
+           *bufptr = ch;
+       ++binmbuf;
+    }
+#endif
+}
+
+/* write sized offset to binary file or directly to memory */
+
+static void putbinoffset(offset_t offset, count_t size)
+{
+    char buf[sizeof offset];
+
+#if SIZEOF_OFFSET_T > 0x2
+    u4cn(buf, offset, size);
+#else
+    u2cn(buf, offset, size);
+#endif
+    putbin(buf[0]);
+    if (size > 0x1)
+       putbin(buf[1]);
+    if (size > 0x2)
+    {
+       putbin(buf[2]);
+       putbin(buf[3]);
+    }
+}
diff --git a/Applications/as09/genlist.c b/Applications/as09/genlist.c
new file mode 100644 (file)
index 0000000..82c13dd
--- /dev/null
@@ -0,0 +1,468 @@
+/* genlist.c - generate listing and error reports for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "address.h"
+#include "flag.h"
+#include "file.h"
+#include "globvar.h"
+#include "macro.h"
+#include "scan.h"
+#include "source.h"
+
+#define CODE_LIST_LENGTH (sizeof (struct code_listing_s) - 1)
+                               /* length of formatted code listing */
+#define MAXERR 6               /* maximum errors listed per line */
+
+struct error_s                 /* to record error info */
+{
+    char * err_str;
+    unsigned char position;
+};
+
+/* code listing format */
+
+struct code_listing_s
+{
+    union linum_macro_u
+    {
+       char linum[LINUM_LEN];
+       struct
+       {
+           char pad[1];
+           char mark[1];
+           char level[1];
+       }
+        macro;
+    }
+     linum_or_macro;
+    char padlinum[1];
+    char lc[4];
+    char padlc[1];
+#ifdef I80386
+    char lprefix[2];
+    char aprefix[2];
+    char oprefix[2];
+    char sprefix[2];
+#endif
+    char page[2];
+    char opcode[2];
+    char postb[2];
+#ifdef I80386
+    char sib[2];
+#endif
+    char padopcode[1];
+#if SIZEOF_OFFSET_T > 2
+    char displ4[2];
+    char displ3[2];
+#endif
+    char displ2[2];
+    char displ1[2];
+    char reldispl[1];
+    char paddispl[1];
+#ifdef I80386
+    char imm4[2];
+    char imm3[2];
+    char imm2[2];
+    char imm1[2];
+    char relimm[1];
+    char padimm[1];
+#endif
+    char nullterm;
+};
+
+static struct error_s errbuf[MAXERR];  /* error buffer */
+static unsigned char errcount; /* # errors in line */
+static bool_t erroverflow;     /* set if too many errors on line */
+
+static char *build_1hex_number(opcode_pt num, char *where);
+static void list1(fd_t fd);
+static void listcode(void);
+static void listerrors(void);
+static void paderrorline(unsigned nspaces);
+
+/* format 1 byte number as 2 hex digits, return ptr to end */
+
+static char *build_1hex_number(opcode_pt num, register char *where)
+{
+    where[0] = hexdigit[((unsigned) num % 256) / 16];
+    where[1] = hexdigit[(unsigned) num % 16];
+    return where + 2;
+}
+
+/* format 2 byte number as 4 hex digits, return ptr to end */
+
+char *build_2hex_number(unsigned num, char *where)
+{
+    return build_1hex_number((opcode_pt) num,
+                            build_1hex_number((opcode_pt) (num / 256), where));
+}
+
+/* format 2 byte number as decimal with given width (pad with leading '0's) */
+/* return ptr to end */
+
+char *build_number(unsigned num, unsigned width, register char *where)
+{
+    static unsigned powers_of_10[] = {1, 10, 100, 1000, 10000,};
+    unsigned char digit;
+    unsigned char power;
+    register unsigned power_of_10;
+
+    power = 5;                 /* actually 1 more than power */
+    do
+    {
+       for (digit = '0', power_of_10 = (powers_of_10 - 1)[power];
+            num >= power_of_10; num -= power_of_10)
+           ++digit;
+       if (power <= width)
+           *where++ = digit;
+    }
+    while (--power != 0);
+    return where;
+}
+
+/* record number and position of error (or error buffer overflow) */
+
+void warning(char * err_str)
+{
+    if (!as_warn.current) return;
+    ++totwarn;
+    --toterr;
+    error(err_str);
+}
+
+void error(char *err_str)
+{
+    register struct error_s *errptr;
+    register struct error_s *errptrlow;
+    unsigned char position;
+
+    if (errcount >= MAXERR)
+       erroverflow = TRUE;
+    else
+    {
+       position = symname - linebuf;
+       for (errptr = errbuf + errcount;
+            errptr > errbuf && errptr->position > position;
+            errptr = errptrlow)
+       {
+           errptrlow = errptr - 1;
+           errptr->err_str = errptrlow->err_str;
+           errptr->position = errptrlow->position;
+       }
+       errptr->err_str = err_str;
+       errptr->position = position;
+       ++errcount;
+       ++toterr;
+    }
+}
+
+/* list 1 line to list file if any errors or flags permit */
+/* list line to console as well if any errors and list file is not console */
+
+void listline(void)
+{
+    if (!listpre && lineptr != 0)
+    {
+       if (errcount || (list.current && (!macflag || mcount != 0)) ||
+           (macflag && maclist.current) || list_force )
+           list1(lstfil);
+       if (errcount)
+       {
+           if (lstfil != STDOUT)
+               list1(STDOUT);
+           errcount = 0;
+           erroverflow = FALSE;
+       }
+    }
+}
+
+/* list 1 line unconditionally */
+
+static void list1(fd_t fd)
+{
+    outfd = fd;
+    listcode();
+    write(outfd, linebuf, (unsigned) (lineptr - linebuf));
+    writenl();
+    if (errcount != 0)
+       listerrors();
+    listpre = TRUE;
+    list_force=FALSE;
+}
+
+/* list object code for 1 line */
+
+static void listcode(void)
+{
+    unsigned char count;
+    struct code_listing_s *listptr;
+    unsigned numlength;
+    char *numptr;
+
+    listptr = (struct code_listing_s *) temp_buf();
+    memset((char *) listptr, ' ', sizeof *listptr);
+    listptr->nullterm = 0;
+    if (macflag)
+    {
+       listptr->linum_or_macro.macro.mark[0] = '+';
+       listptr->linum_or_macro.macro.level[0] = maclevel + ('a' - 1);
+    }
+    else
+    {
+       numlength = LINUM_LEN;
+       numptr = listptr->linum_or_macro.linum;
+       if (infiln != infil0)
+       {
+           *numptr++ = infiln - infil0 + ('a' - 1);
+           numlength = LINUM_LEN - 1;
+       }
+       build_number(linum, numlength, numptr);
+    }
+    if ((count = mcount) != 0 || popflags & POPLC)
+       build_2hex_number((u16_T) lc, listptr->lc);
+    if (popflags & POPLO)
+    {
+#if SIZEOF_OFFSET_T > 2
+       if (popflags & POPLONG)
+           build_2hex_number((u16_T) (lastexp.offset / (offset_t) 0x10000L),
+                             listptr->displ4);
+#endif
+       if (popflags & POPHI)
+           build_2hex_number((u16_T) lastexp.offset, listptr->displ2);
+       else
+           build_1hex_number((opcode_pt) /* XXX */(u16_T) lastexp.offset, listptr->displ1);
+       if (lastexp.data & RELBIT)
+           listptr->reldispl[0] = '>';
+    }
+    else if (count != 0)
+    {
+#ifdef I80386
+       if (aprefix != 0)
+       {
+           --count;
+           build_1hex_number(aprefix, listptr->aprefix);
+       }
+       if (oprefix != 0)
+       {
+           --count;
+           build_1hex_number(oprefix, listptr->oprefix);
+       }
+       if (sprefix != 0)
+       {
+           --count;
+           build_1hex_number(sprefix, listptr->sprefix);
+       }
+#endif
+       if (page != 0)
+       {
+           build_1hex_number(page, listptr->page);
+           --count;
+       }
+       build_1hex_number(opcode, listptr->opcode);
+       --count;
+       if (postb != 0)
+       {
+           --count;
+           build_1hex_number(postb,
+#ifdef MC6809
+                             count == 0 ? listptr->displ1 :
+#endif
+                             listptr->postb);
+       }
+#ifdef I80386
+       if (sib != NO_SIB)
+       {
+           --count;
+           build_1hex_number(sib, listptr->sib);
+       }
+#endif
+       if (count > 0)
+       {
+           build_1hex_number((opcode_pt) lastexp.offset, listptr->displ1);
+           if (lastexp.data & RELBIT)
+               listptr->reldispl[0] = '>';
+       }
+       if (count > 1)
+           build_1hex_number((opcode_pt) (lastexp.offset >> 0x8),
+                             listptr->displ2);
+#if SIZEOF_OFFSET_T > 2
+       if (count > 2)
+       {
+           build_1hex_number((opcode_pt) (lastexp.offset >> 0x10),
+                             listptr->displ3);
+           build_1hex_number((opcode_pt) (lastexp.offset >> 0x18),
+                             listptr->displ4);
+       }
+#endif
+#ifdef I80386
+       if (immcount > 0)
+       {
+           build_1hex_number((opcode_pt) immadr.offset, listptr->imm1);
+           if (immadr.data & RELBIT)
+               listptr->relimm[0] = '>';
+       }
+       if (immcount > 1)
+           build_1hex_number((opcode_pt) (immadr.offset >> 0x8),
+                             listptr->imm2);
+       if (immcount > 2)
+       {
+           build_1hex_number((opcode_pt) (immadr.offset >> 0x10),
+                             listptr->imm3);
+           build_1hex_number((opcode_pt) (immadr.offset >> 0x18),
+                             listptr->imm4);
+       }
+#endif
+    }
+    writes((char *) listptr);
+}
+
+/* list errors, assuming some */
+
+static void listerrors(void)
+{
+    unsigned char column;
+    unsigned char errcol;      /* column # in error line */
+    unsigned char errcolw;     /* working column in error line */
+    char *errmsg;
+    struct error_s *errptr;
+    char *linep;
+    unsigned char remaining;
+
+#ifdef I80386
+    paderrorline(1);
+#else
+    paderrorline(CODE_LIST_LENGTH - LINUM_LEN);
+#endif
+    remaining = errcount;
+    column = 0;                        /* column to match with error column */
+    errcolw = errcol = CODE_LIST_LENGTH; /* working & col number on err line */
+    errptr = errbuf;
+    linep = linebuf;
+    do
+    {
+#ifdef I80386
+        if(errcol != CODE_LIST_LENGTH)
+       {
+           writenl(); paderrorline(1);
+       }
+       writes(errmsg = errptr->err_str);
+       errcol = strlen(errmsg)+LINUM_LEN+1;
+       column = 0; linep = linebuf;
+        errcolw = CODE_LIST_LENGTH;
+       while (errcolw > errcol)
+       {
+           writec('.');
+           ++errcol;
+       }
+#endif
+       while (errptr && errptr->position < 132 && column < errptr->position)
+       {
+           ++column;
+           if (*linep++ == '\t')       /* next tab (standard tabs only) */
+               errcolw = (errcolw + 8) & 0xf8;
+           else
+               ++errcolw;
+           while (errcolw > errcol)
+           {
+#ifdef I80386
+               writec('.');
+#else
+               writec(' ');
+#endif
+               ++errcol;
+           }
+       }
+#ifdef I80386
+       writec('^'); ++errcol;
+#else
+       if (errcolw < errcol)   /* position under error on new line */
+       {
+           writenl();
+           paderrorline((unsigned) errcolw - LINUM_LEN);
+       }
+       writec('^');
+       writes(errmsg = errptr->err_str);
+       errcol += strlen(errmsg);
+#endif
+       ++errptr;
+    }
+    while (--remaining != 0);
+    writenl();
+    if (erroverflow)
+    {
+#ifdef I80386
+       paderrorline(1);
+#else
+       paderrorline(CODE_LIST_LENGTH - LINUM_LEN);
+#endif
+       writesn(FURTHER);
+    }
+}
+
+/* pad out error line to begin under 1st char of source listing */
+
+static void paderrorline(unsigned nspaces)
+{
+    int nstars = LINUM_LEN;
+
+    while (nstars-- != 0)
+       writec('*');            /* stars under line number */
+    while (nspaces-- != 0)
+       writec(' ');            /* spaces out to error position */
+}
+
+/* write 1 character */
+
+void writec(char ch)
+{
+    write(outfd, &ch, 1);
+}
+
+/* write newline */
+
+void writenl(void)
+{
+    writes(SOS_EOLSTR);
+}
+
+/* write 1 offset_t, order to suit target */
+
+void writeoff(offset)
+offset_t offset;
+{
+    char buf[sizeof offset];
+
+#if SIZEOF_OFFSET_T > 2
+    u4c4(buf, offset);
+#else
+    u2c2(buf, offset);
+#endif
+    write(outfd, buf, sizeof buf);
+}
+
+/* write string */
+
+void writes(const char *s)
+{
+    write(outfd, s, strlen(s));
+}
+
+/* write string followed by newline */
+
+void writesn(const char *s)
+{
+    writes(s);
+    writenl();
+}
+
+/* write 1 word, order to suit target */
+
+void writew(unsigned word)
+{
+    char buf[2];
+
+    u2c2(buf, (u16_T) word);
+    write(outfd, buf, sizeof buf);
+}
diff --git a/Applications/as09/genobj.c b/Applications/as09/genobj.c
new file mode 100644 (file)
index 0000000..b4ba994
--- /dev/null
@@ -0,0 +1,672 @@
+/* genobj.c - object code generation routines for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "address.h"
+#include "file.h"
+#include "globvar.h"
+
+#define OBJBUFSIZE 512         /* size of object code output buffer */
+#define isge2byteoffset(offset) ((offset) >= 0x100)
+#define isge4byteoffset(offset) ((offset) >= 0x10000L)
+
+static char hid_absbuf[OBJ_MAX_ABS_LEN];       /* absolute object code buf */
+static char *absbuf;           /* start */
+static char *absbufend;        /* last location + 1 */
+static char *absbufptr;        /* current location */
+static struct sym_s **arrext;  /* array of external symbol ptrs */
+static char hid_objbuf[OBJBUFSIZE];    /* object code buffer */
+static unsigned numext;        /* number of external symbols */
+static char *objbuf;           /* start */
+static char *objbufend;        /* last location + 1 */
+static char *objbufptr;        /* current location */
+static unsigned char relsize;  /* current relocation size, 0 init */
+                               /* local to genobjadr, but here */
+                               /* because of static re-init bug */
+static offset_t rmbcount;      /* accumulator for repeated RMB's */
+
+static void flushabs(void);
+static void flushrmb(void);
+static void genobjadr(struct address_s *adrptr, smallcount_t size);
+static void putobj1(opcode_pt ch);
+static void putobj4(u32_T offset);
+static void putobjoffset(offset_t offset, count_t size);
+static void putobjword(unsigned word);
+static void writeobj(char *buf, unsigned count);
+
+/* accumulate RMB requests into 1 (so + and - requests cancel) */
+
+void accumulate_rmb(offset_t offset)
+{
+    if (objectc)
+    {
+       flushabs();
+       rmbcount += offset;
+    }
+}
+
+/* flush absolute object code buffer to object code buffer if necessary */
+
+static void flushabs(void)
+{
+    if (absbufptr > absbuf)
+    {
+       putobj1((absbufptr - absbuf) | OBJ_ABS);
+       {
+           register char *bufptr;
+
+           bufptr = absbuf;
+           do
+               putobj1(*bufptr);
+           while (++bufptr < absbufptr);
+           absbufptr = absbuf;
+       }
+    }
+}
+
+/* flush object code buffer if necessary */
+
+void flushobj(void)
+{
+    int ntowrite;
+
+    if ((ntowrite = objbufptr - objbuf) > 0)
+    {
+       if (write(objfil, objbuf, (unsigned) ntowrite) != ntowrite)
+       {
+           error(OBJOUT);
+           listline();
+           finishup();
+       }
+       objbufptr = objbuf;
+    }
+}
+
+/* flush RMB count if necessary */
+
+static void flushrmb(void)
+{
+    count_t size;
+
+    if (rmbcount != 0)
+    {
+#if SIZEOF_OFFSET_T > 2
+       if (isge4byteoffset(rmbcount))
+       {
+           putobj1(OBJ_SKIP_4);
+           size = 4;
+       }
+       else
+#endif
+       if (isge2byteoffset(rmbcount))
+       {
+           putobj1(OBJ_SKIP_2);
+           size = 2;
+       }
+       else
+       {
+           putobj1(OBJ_SKIP_1);
+           size = 1;
+       }
+       putobjoffset(rmbcount, size);
+       rmbcount = 0;
+    }
+}
+
+/* generate object code for current line */
+
+/*
+  any address parameter is (regrettably) in lastexp
+  any immediate parameter is (corectly) in immadr
+*/
+
+void genobj(void)
+{
+    struct address_s *adrptr;
+    char *bufptr;
+    unsigned char remaining;
+
+    if (objectc && mcount != 0)
+    {
+       if (popflags)
+       {
+           if (fcflag)
+           {
+               bufptr = databuf.fcbuf;
+               remaining = mcount;
+               do
+                   putabs(*bufptr++);
+               while (--remaining != 0);
+           }
+           if (fdflag)
+           {
+               adrptr = databuf.fdbuf;
+               remaining = mcount;
+               do
+                   genobjadr(adrptr++, 2);
+               while ((remaining -= 2) != 0);
+           }
+#if SIZEOF_OFFSET_T > 2
+           if (fqflag)
+           {
+               adrptr = databuf.fqbuf;
+               remaining = mcount;
+               do
+                   genobjadr(adrptr++, 4);
+               while ((remaining -= 4) != 0);
+           }
+#endif
+       }
+       else
+       {
+           remaining = mcount - 1;     /* count opcode immediately */
+#ifdef I80386
+           if (aprefix != 0)
+           {
+               putabs(aprefix);
+               --remaining;
+           }
+           if (oprefix != 0)
+           {
+               putabs(oprefix);
+               --remaining;
+           }
+           if (sprefix != 0)
+           {
+               putabs(sprefix);
+               --remaining;
+           }
+#endif
+           if (page != 0)
+           {
+               putabs(page);
+               --remaining;
+           }
+           putabs(opcode);
+           if (remaining != 0)
+           {
+               if (postb != 0)
+               {
+                   putabs(postb);
+                   --remaining;
+               }
+#ifdef I80386
+               if (sib != NO_SIB)
+               {
+                   putabs(sib);
+                   --remaining;
+               }
+#endif
+               if (remaining != 0)
+                   genobjadr(&lastexp, remaining);
+           }
+       }
+#ifdef I80386
+       if (immcount != 0)
+           genobjadr(&immadr, immcount);
+#endif
+    }
+}
+
+/* generate object code for current address */
+
+static void genobjadr(struct address_s *adrptr, smallcount_t size)
+{
+    unsigned char byte;
+    unsigned symnum;
+
+    if (!(adrptr->data & RELBIT))
+    {
+       /* absolute address */
+
+       char buf[sizeof(offset_t)];
+
+#if SIZEOF_OFFSET_T > 2
+       u4cn(buf, adrptr->offset, size);
+#else
+       u2cn(buf, adrptr->offset, size);
+#endif
+       putabs(buf[0]);
+       if (size > 1)
+           putabs(buf[1]);
+       if (size > 2)
+       {
+           putabs(buf[2]);
+           putabs(buf[3]);
+       }
+    }
+    else
+    {
+       /* relocatable address */
+       if (size != relsize)
+           /* set reloc size index |00|0000xx| */
+           putobj((relsize = size) == 4 ? 0x03 : relsize);
+       if (!(adrptr->data & IMPBIT))
+       {
+           /* offset relocation (known offset) */
+           putobj((adrptr->data & SEGM) | OBJ_OFFSET_REL | pcrflag);
+           putobjoffset(adrptr->offset, size);
+       }
+       else
+       {
+           /* symbol relocation (imported symbol + offset) */
+           {
+               register struct sym_s **copyptr;
+
+               for (copyptr = arrext, symnum = 0;
+                    symnum < numext && *copyptr++ != adrptr->sym; ++symnum)
+                   ;
+           }
+           byte = OBJ_SYMBOL_REL;
+           if (isge2byteoffset(symnum))
+               byte = OBJ_SYMBOL_REL | OBJ_S_MASK;
+#if SIZEOF_OFFSET_T > 2
+           if (isge4byteoffset(adrptr->offset))
+           {
+               byte |= 0x03;   /* 4 byte offset */
+               size = 4;
+           }
+           else
+#endif
+           if (isge2byteoffset(adrptr->offset))
+           {
+               byte |= 0x02;   /* 2 byte offset */
+               size = 2;
+           }
+           else if (adrptr->offset != 0)
+           {
+               byte |= 0x01;   /* 1 byte offset */
+               size = 1;
+           }
+           else
+               size = 0;
+           putobj(byte | pcrflag);
+           if (isge2byteoffset(symnum))
+               putobjword(symnum);
+           else
+               putobj1((opcode_pt) symnum);
+           if (adrptr->offset != 0)
+               putobjoffset(adrptr->offset, size);
+       }
+    }
+}
+
+/* initialise private variables */
+
+void initobj(void)
+{
+    absbufend = (absbufptr = absbuf = hid_absbuf) + sizeof hid_absbuf;
+    objbufend = (objbufptr = objbuf = hid_objbuf) + sizeof hid_objbuf;
+}
+
+/*
+  write header to object file
+  also build array of imported/exported symbols
+*/
+
+void objheader(void)
+{
+    static char module_header[] =
+    {
+#ifdef I80386
+       0xA3, 0x86,
+       1, 0,
+       (char) (0xA3 + 0x86 + 1 + 0),
+#endif
+#ifdef MC6809
+       'S', '1',               /* 2 byte magic number */
+       0, 1,                   /* 2 byte number of modules in file */
+       'S' + '1' + 0 + 1,      /* 1 byte checksum */
+#endif
+    };
+    static char seg_max_sizes[] =
+    {
+       0x55,                   /* all segments have maximum size 2^16 */
+       0x55,                   /* this is encoded by 0b01 4 times per byte */
+       0x55,                   /* other codes are 0b00 = max size 2^8 */
+       0x55,                   /* 0b10 = max size 2^24, 0b11 = max 2^32 */
+    };
+    unsigned char byte;
+    register struct sym_s **copyptr;
+    struct sym_s **copytop;
+    struct sym_s **hashptr;
+    struct lc_s *lcp;
+    char module_name[FILNAMLEN + 1];
+    char *nameptr;
+    unsigned offset;
+    unsigned segsizebytes;
+    unsigned size;
+    unsigned char sizebits;
+    unsigned strsiz;           /* size of object string table */
+    unsigned symosiz;          /* size of object symbol table */
+    register struct sym_s *symptr;
+    u32_T textlength;
+    int symcount = 0;
+
+    if ((objectc = objectg) == 0)
+       return;
+    writeobj(module_header, sizeof module_header);
+
+    /* calculate number of imported/exported symbols */
+    /* and lengths of symbol and string tables */
+    /* build array of imported/exported symbols */
+
+    symosiz = 0;
+    if (truefilename == NUL_PTR)
+       truefilename = filnamptr;
+    nameptr = strrchr(truefilename, DIRCHAR);
+    strcpy(module_name, nameptr != NUL_PTR ? nameptr + 1 : truefilename);
+    if ((nameptr = strrchr(module_name, '.')) != NUL_PTR)
+       *nameptr = 0;
+    strsiz = strlen(module_name) + 1;
+    
+    for (hashptr = spt; hashptr < spt_top;)
+       if ((symptr = *hashptr++) != NUL_PTR)
+           do
+           {
+               if ((symptr->type & EXPBIT || symptr->data & IMPBIT) ||
+                   (!globals_only_in_obj && symptr->name[0] != '.' &&
+                   !(symptr->type & (MNREGBIT | MACBIT | VARBIT))))
+               {
+                   symcount ++;
+               }
+           }
+           while ((symptr = symptr->next) != NUL_PTR);
+    arrext = copyptr = asalloc( sizeof(struct sym_s *) * symcount);
+
+    for (hashptr = spt; hashptr < spt_top;)
+       if ((symptr = *hashptr++) != NUL_PTR)
+           do
+           {
+               if ((symptr->type & EXPBIT || symptr->data & IMPBIT) ||
+                   (!globals_only_in_obj && symptr->name[0] != '.' &&
+                   !(symptr->type & (MNREGBIT | MACBIT | VARBIT))))
+               {
+                   *copyptr++ = symptr;
+                   strsiz += symptr->length + 1;
+                   if (textseg>=0 && (symptr->data & SEGM) == textseg)
+                      strsiz+=2;
+#if SIZEOF_OFFSET_T > 2
+                   if (isge4byteoffset(symptr->value_reg_or_op.value))
+                       size = 4 + 4;
+                       /* 4 is size of offset into string table and flags */
+                       /* 2nd 4 is for 4 byte offset */
+                   else
+#endif
+                   if (isge2byteoffset(symptr->value_reg_or_op.value))
+                       size = 4 + 2;
+                   else if (symptr->value_reg_or_op.value != 0)
+                       size = 4 + 1;
+                   else
+                       size = 4;
+                   symosiz += size;
+                   ++numext;
+               }
+           }
+           while ((symptr = symptr->next) != NUL_PTR);
+    copytop = copyptr;
+
+    /* calculate length of text, and number of seg size bytes in header */
+
+    textlength = segsizebytes = 0;
+    lcp = lctab;
+    do
+       if (lcp->lc != 0)
+       {
+           textlength += lcp->lc;      /* assuming text starts at 0 */
+#if SIZEOF_OFFSET_T > 2
+           if (isge4byteoffset(lcp->lc))
+               segsizebytes += 4;
+           else
+#endif
+               segsizebytes += 2;      /* use 2 byte size if possible */
+       }
+    while (++lcp < lctabtop);
+
+/*
+  offset to text = length of header since only 1 module
+  header consists of:
+  module header                        sizeof module_header
+  offset to start of text      4
+  length of text               4
+  length of string area                2
+  class                                1
+  revision                     1
+  seg max sizes                        sizeof seg_max_sizes
+  seg size descriptors         4
+  seg sizes                    segsizebytes
+  symbol count                 2
+  symbol offsets and types     symosiz
+  strings                      strsiz
+*/
+
+    /* offset to start of text */
+
+    putobj4((u32_T) (sizeof module_header + 4 + 4 + 2 + 1 + 1 +
+                    sizeof seg_max_sizes + 4 + segsizebytes + 2 +
+                    symosiz) + strsiz);
+
+    /* length of text */
+
+    putobj4((u32_T) textlength);
+
+    /* length of string area */
+
+    putobjword(strsiz);
+
+    /* class and revision */
+
+    putobj1(0);
+    putobj1(0);
+
+    /* segment max sizes (constant) */
+
+    writeobj(seg_max_sizes, sizeof seg_max_sizes);
+
+    /* segment size descriptors */
+    /* produce only 0 and 2 byte sizes */
+
+    lcp = lctabtop;
+    byte = 0;
+    sizebits = OBJ_SEGSZ_TWO << 6;
+    do
+    {
+       --lcp;
+       if (lcp->lc != 0)
+       {
+           byte |= sizebits;
+#if SIZEOF_OFFSET_T > 2
+           if (isge4byteoffset(lcp->lc))
+               byte |= sizebits >> 1;  /* XXX - convert size 2 to size 4 */
+#endif
+       }
+       if ((sizebits >>= 2) == 0)
+       {
+           putobj1(byte);
+           byte = 0;
+           sizebits = OBJ_SEGSZ_TWO << 6;
+       }
+    }
+    while (lcp > lctab);
+
+    /* segment sizes */
+
+    do                         /* lcp starts at lctab */
+       if (lcp->lc != 0)
+       {
+#if SIZEOF_OFFSET_T > 2
+           if (isge4byteoffset(lcp->lc))
+               putobj4(lcp->lc);
+           else
+#endif
+               putobjword((unsigned) lcp->lc);
+       }
+    while (++lcp < lctabtop);
+
+    /* symbol count */
+
+    putobjword(numext);
+
+    /* symbol offsets and types */
+
+    offset = strlen(module_name) + 1;  /* 1st symbol begins after name */
+    for (copyptr = arrext; copyptr < copytop;)
+    {
+       putobjword(offset);
+       symptr = *copyptr++;
+       byte = symptr->type & OBJ_N_MASK;
+#if SIZEOF_OFFSET_T > 2
+       if (isge4byteoffset(symptr->value_reg_or_op.value))
+       {
+           byte |= OBJ_SZ_FOUR;
+           size = 4;
+       }
+       else
+#endif
+       if (isge2byteoffset(symptr->value_reg_or_op.value))
+       {
+           byte |= OBJ_SZ_TWO;
+           size = 2;
+       }
+       else if (symptr->value_reg_or_op.value != 0)
+       {
+           byte |= OBJ_SZ_ONE;
+           size = 1;
+       }
+       else
+           size = 0;
+       if ((symptr->type & (COMMBIT | REDBIT)) == (COMMBIT | REDBIT))
+       {
+           byte |= OBJ_SA_MASK;
+           symptr->data &= ~OBJ_I_MASK;
+       }
+       putobjword((unsigned)
+                  (byte << 0x8) |
+                  (symptr->type & OBJ_E_MASK) |        /* |E|0000000| */
+              ((symptr->data & (OBJ_I_MASK | OBJ_A_MASK | OBJ_SEGM_MASK)) ^
+       /* |0|I|0|A|SEGM| */
+               RELBIT));       /* RELBIT by negative logic */
+       if ((symptr->type & (COMMBIT | REDBIT)) == (COMMBIT | REDBIT))
+           symptr->data |= OBJ_I_MASK;
+       if (size != 0)
+           putobjoffset(symptr->value_reg_or_op.value, size);
+       offset += symptr->length + 1;
+       if (textseg>=0 && (symptr->data & SEGM) == textseg)
+          offset+=2;
+    }
+
+    /* strings */
+
+    writeobj(module_name, strlen(module_name));
+    putobj1(0);
+    for (copyptr = arrext; copyptr < copytop;)
+    {
+       symptr = *copyptr++;
+       writeobj(symptr->name, symptr->length);
+       if (textseg>=0 && (symptr->data & SEGM) == textseg)
+       {
+          putobj1('.');
+          putobj1(hexdigit[textseg]);
+       }
+       putobj1(0);
+    }
+    putobj1(OBJ_SET_SEG | 0);  /* default segment 0, |0010|SEGM| */
+}
+
+/* write trailer to object file */
+
+void objtrailer(void)
+{
+    if (objectc)
+    {
+       putobj(0);              /* end of object file */
+       flushobj();
+    }
+}
+
+/* write char to absolute object code buffer, flush if necessary */
+
+void putabs(opcode_pt ch)
+{
+    if (objectc)
+    {
+       if (rmbcount != 0)
+           flushrmb();
+       if (absbufptr >= absbufend)
+           flushabs();
+       *absbufptr++ = ch;
+    }
+}
+
+/* write char to object code buffer, flush if necessary */
+
+void putobj(opcode_pt ch)
+{
+    if (objectc)
+    {
+       flushabs();
+       flushrmb();
+       putobj1(ch);
+    }
+}
+
+/* write char to object code buffer assuming nothing in absolute & rmb bufs */
+
+static void putobj1(opcode_pt ch)
+{
+    if (objbufptr >= objbufend)
+       flushobj();
+    *objbufptr++ = ch;
+}
+
+/* write 32 bit offset to object code buffer assuming ... */
+
+static void putobj4(u32_T offset)
+{
+    char buf[sizeof offset];
+
+    u4c4(buf, offset);
+    writeobj(buf, 4);
+}
+
+/* write sized offset to object code buffer assuming ... */
+
+static void putobjoffset(offset_t offset, count_t size)
+{
+    char buf[sizeof offset];
+
+#if SIZEOF_OFFSET_T > 2
+    u4cn(buf, offset, size);
+#else
+    u2cn(buf, offset, size);
+#endif
+    putobj1(buf[0]);
+    if (size > 1)
+       putobj1(buf[1]);
+    if (size > 2)
+    {
+       putobj1(buf[2]);
+       putobj1(buf[3]);
+    }
+}
+
+/* write word to object code buffer assuming ... */
+
+static void putobjword(unsigned word)
+{
+    char buf[sizeof word];
+
+    u2c2(buf, word);
+    putobj1(buf[0]);
+    putobj1(buf[1]);
+}
+
+/* write several bytes to object code buffer assuming ... */
+
+static void writeobj(char *buf, unsigned count)
+{
+    do
+       putobj1(*buf++);
+    while (--count);
+}
diff --git a/Applications/as09/gensym.c b/Applications/as09/gensym.c
new file mode 100644 (file)
index 0000000..fc20b00
--- /dev/null
@@ -0,0 +1,223 @@
+/* gensym.c - generate symbol table for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "flag.h"
+#include "file.h"
+#include "globvar.h"
+
+static int printsym(register struct sym_s *symptr, unsigned column);
+static void sort(struct sym_s **array, struct sym_s **top,
+                    bool_pt nameflag);
+
+/* sort labels in symbol table on name and value */
+/* if listing, write human-readable table to list file */
+/* if symbol file, write machine-readable tables to it */
+/* pointers become relative to start of file */
+
+void gensym(void)
+{
+    unsigned column;
+    struct sym_s **copyptr;
+    struct sym_s **copytop;
+    register struct sym_s **hashptr;
+    unsigned label_count;      /* number of labels */
+    unsigned labels_length;    /* length of all label strings */
+    struct sym_s **symlptr;    /* start of symbol output list */
+    register struct sym_s *symptr;
+#ifdef BINSYM
+    unsigned label_stringptr;  /* offset of label str from start of file */
+#endif
+    int symcount = 0;
+
+    labels_length = label_count = 0;
+
+    /* make copy of all relavant symbol ptrs on heap */
+    /* original ptrs can now be modified, but need to be an array for sort */
+
+    for (hashptr = spt; hashptr < spt_top;)
+       if ((symptr = *hashptr++) != NUL_PTR)
+           do
+               if (!(symptr->type & (MACBIT | MNREGBIT | VARBIT)))
+                  symcount++;
+           while ((symptr = symptr->next) != NUL_PTR);
+    symlptr = copyptr = asalloc( sizeof(struct sym_s *) * symcount);
+
+    for (hashptr = spt; hashptr < spt_top;)
+       if ((symptr = *hashptr++) != NUL_PTR)
+           do
+               if (!(symptr->type & (MACBIT | MNREGBIT | VARBIT)))
+               {
+                   *copyptr++ = symptr;
+                   ++label_count;
+                   labels_length += symptr->length + 3; /* 3 for type, value */
+               }
+           while ((symptr = symptr->next) != NUL_PTR);
+
+    sort(symlptr, copyptr, TRUE);      /* sort on name */
+    copytop = copyptr;
+    if (list.global)
+    {
+       outfd = lstfil;
+       writenl();
+       writesn("Symbols:");
+       for (copyptr = symlptr, column = 0; copyptr < copytop;)
+           column = printsym(*copyptr++, column);
+       if (column != 0)
+           writenl();
+    }
+    if ((outfd = symfil) != 0)
+    {
+#ifndef BINSYM
+       for (copyptr = symlptr; copyptr < copytop;)
+       /* for (copyptr = spt; copyptr < spt_top;) */
+       {
+           int sft;
+           if((symptr = *copyptr++) == NUL_PTR ) continue;
+           if( globals_only_in_obj &&
+              !(symptr->type & EXPBIT)) continue;
+
+            writec(hexdigit[symptr->data & SEGM]);
+           writec(' ');
+
+           for(sft=SIZEOF_OFFSET_T*8-4; sft >= 0; sft-=4)
+               writec(hexdigit[(symptr->value_reg_or_op.value>>sft) & 0xF]);
+
+           writec(' ');
+            writec(symptr->type & EXPBIT ? 'E' : '-');
+            writec(symptr->type & ENTBIT ? 'N' : '-');
+            writec(symptr->data & IMPBIT ? 'I' : '-');
+            writec(symptr->data & RELBIT ? 'R' : 'A');
+            writec(symptr->type & COMMBIT ? 'C' : '-');
+
+           writec(' ');
+           write(outfd, symptr->name, (unsigned) (symptr->length));
+
+           /* printsym(*copyptr++, 0); */
+           writenl();
+        }
+#else
+       writew(mapnum);
+       label_count *= 2;       /* now length of ptr table (2 bytes per ptr) */
+       label_stringptr = label_count + 6;
+                               /* offset to current string in symbol file */
+                               /* 6 is length of header */
+       labels_length += label_stringptr;
+       /* offset to ptr table sorted on value */
+       writew(labels_length + label_count);
+       /* total length of symbol file */
+       writew(label_count);
+       for (copyptr = symlptr; copyptr < copytop;)
+       {
+           symptr = *copyptr++;
+           writew((unsigned)
+                  (symptr->next = (struct sym_s *) label_stringptr));
+                               /* reuse "next" to record string position */
+           label_stringptr += symptr->length + 3;
+       }
+       for (copyptr = symlptr; copyptr < copytop;)
+       {
+           symptr = *copyptr++;
+           writew((unsigned) symptr->value_reg_or_op.value);
+           writec(symptr->type);
+           write(outfd, symptr->name, (unsigned) (symptr->length - 1));
+           writec(symptr->name[symptr->length - 1] | 0x80);
+       }
+       sort(symlptr, copyptr, FALSE);
+       /* sort on value */
+       for (copyptr = symlptr; copyptr < copytop;)
+       {
+           symptr = *copyptr++;
+           writew((unsigned) symptr->next);    /* now has string position */
+       }
+#endif
+    }
+}
+
+/* print symbol nicely formatted for given column */
+
+static int printsym(register struct sym_s *symptr, unsigned column)
+{
+    unsigned char length;
+    register struct sym_listing_s *listptr;
+    char *outname;
+    char *symname;
+
+    listptr = (struct sym_listing_s *) temp_buf();
+    memset((char *) listptr, ' ', SYMLIS_LEN);
+    listptr->nullterm = 0;
+    if ((length = symptr->length) > SYMLIS_NAMELEN)
+    {
+       outname = listptr->name;
+       outname[length = SYMLIS_NAMELEN] = '+';
+    }
+    else
+       outname = listptr->name; /*(listptr->name + SYMLIS_NAMELEN) - length;*/
+    symname = symptr->name;
+    do
+       *outname++ = *symname++;
+    while (--length != 0);
+    listptr->ar[0] = symptr->data & RELBIT ? 'R' : 'A';
+    listptr->segm[0] = hexdigit[symptr->data & SEGM];
+    if (symptr->type & COMMBIT)
+       listptr->cein[0] = 'C';
+    else if (symptr->type & ENTBIT)
+       listptr->cein[0] = 'N';
+    else if (symptr->type & EXPBIT)
+       listptr->cein[0] = 'E';
+    else if (symptr->data & IMPBIT)
+       listptr->cein[0] = 'I';
+#if SIZEOF_OFFSET_T > 2
+    build_2hex_number((unsigned) (symptr->value_reg_or_op.value >> 16),
+                     listptr->value);
+#endif
+    build_2hex_number((unsigned) symptr->value_reg_or_op.value,
+                     listptr->value);
+    writes((char *) listptr);
+    if ((column += SYMLIS_LEN) > (80 - SYMLIS_LEN))
+    {
+       writenl();
+       column = 0;
+    }
+    return column;
+}
+
+/* shell sort symbols */
+
+static void sort(struct sym_s **array, struct sym_s **top, bool_pt nameflag)
+{
+    int gap;
+    int i;
+    int j;
+    register struct sym_s **left;
+    register struct sym_s **right;
+    int size;
+    struct sym_s *swap;
+
+    size = top - array;
+    /* choose gaps according to Knuth V3 p95 */
+    for (gap = 1, i = 4; (j = 3 * i + 1) < size; gap = i, i = j)
+       ;
+    do
+    {
+       for (j = gap; j < size; ++j)
+           for (i = j - gap; i >= 0; i -= gap)
+           {
+               left = &array[i];
+               right = &array[i + gap];
+               if ((bool_t) nameflag)
+               {
+                   if (strcmp((*left)->name, (*right)->name) <= 0)
+                       break;
+               }
+               else if ((unsigned) (*left)->value_reg_or_op.value <=
+                        (*right)->value_reg_or_op.value)
+                   break;
+               swap = *left;
+               *left = *right;
+               *right = swap;
+           }
+    }
+    while ((gap /= 3) != 0);
+}
diff --git a/Applications/as09/globvar.h b/Applications/as09/globvar.h
new file mode 100644 (file)
index 0000000..edd9419
--- /dev/null
@@ -0,0 +1,124 @@
+/* globvar.h - global variables for assembler */
+
+/* global control and bookkeeping */
+
+EXTERN bool_t binaryc;         /* current binary code flag */
+EXTERN bool_t binaryg;         /* global binary code flag */
+EXTERN offset_t binmbuf;       /* offset in binary code buffer for memory */
+EXTERN bool_t binmbuf_set;     /* set to 1 when binmbuf set by org */
+
+EXTERN unsigned char dirpag;   /* direct page */
+
+EXTERN bool_t globals_only_in_obj;     /* global symbols only in object file */
+
+EXTERN bool_t jumps_long;      /* make all jumps long */
+
+EXTERN unsigned char mapnum;   /* global map number */
+
+EXTERN bool_t objectc;         /* current object code flag */
+EXTERN bool_t objectg;         /* global object code flag */
+
+EXTERN bool_t pass;            /* pass, FALSE means 0, TRUE means 1 */
+
+EXTERN offset_t progent;       /* program entry point */
+
+EXTERN bool_t symgen;          /* generate symbol table flag */
+
+EXTERN unsigned toterr;                /* total errors */
+EXTERN unsigned totwarn;       /* total warnings */
+
+EXTERN bool_t list_force;      /* Force line to be listed - no error */
+
+/* bookeeping for current line */
+
+EXTERN char *linebuf;          /* buffer */
+
+/* for symbol table routines */
+
+EXTERN unsigned char inidata;  /* init sym entry data governed by "u" flag */
+EXTERN struct sym_s **spt;     /* symbol pointer table */
+EXTERN struct sym_s **spt_top; /* top of symbol ptr table */
+
+/* for translator */
+
+EXTERN struct sym_s *label;    /* non-null if valid label starts line */
+EXTERN unsigned char pedata;   /* shows how PROGENT bound, flags like LCDATA*/
+EXTERN unsigned char popflags; /* pseudo-op flags */
+
+/* for BLOCK stack */
+
+EXTERN struct block_s *blockstak;      /* stack ptr */
+EXTERN unsigned char blocklevel;       /* nesting level */
+
+/* for IF stack */
+
+EXTERN struct if_s *ifstak;    /* stack ptr */
+EXTERN unsigned char iflevel;  /* nesting level */
+EXTERN bool_t ifflag;          /* set if assembling */
+
+/* location counters for various segments */
+
+EXTERN offset_t lc;            /* location counter */
+EXTERN unsigned char lcdata;   /* shows how lc is bound */
+                               /* FORBIT is set if lc is forward referenced */
+                               /* RELBIT is is if lc is relocat. (not ASEG) */
+EXTERN offset_t lcjump;        /* lc jump between lines */
+
+EXTERN offset_t oldlabel;      /* Used for checking for moving labels */
+#ifdef LOW_BYTE
+#define mcount (((unsigned char *) &lcjump)[LOW_BYTE])
+                               /* low byte of lcjump */
+#else
+#define mcount lcjump          /* I think this is just a speed hack */
+#endif
+EXTERN struct lc_s *lcptr;     /* top of current spot in lctab */
+EXTERN struct lc_s *lctab;     /* start of lctab */
+EXTERN struct lc_s *lctabtop;  /* top of lctab */
+
+/* for code generator */
+
+EXTERN opsize_t mnsize;                /* 1 if forced byte operand size, else 0 */
+EXTERN opcode_t page;
+EXTERN opcode_t opcode;
+EXTERN opcode_t postb;         /* postbyte, 0 if none */
+EXTERN unsigned char pcrflag;  /* OBJ_RMASK set if addressing is PC-relative */
+EXTERN int last_pass;          /* Pass number of last pass */
+EXTERN int dirty_pass;         /* Set if this pass had a label movement */
+
+EXTERN int textseg;            /* Text segment id */
+
+#ifdef I80386
+
+EXTERN opcode_t aprefix;       /* address size prefix or 0 */
+EXTERN bool_t asld_compatible; /* asld compatibility flag */
+EXTERN opsize_t defsize;       /* current default size */
+EXTERN opsize_t idefsize;      /* initial default size */
+EXTERN opcode_t oprefix;       /* operand size prefix or 0 */
+EXTERN opcode_t sprefix;       /* segment prefix or 0 */
+EXTERN opcode_t sib;           /* scale-index-base byte */
+
+EXTERN int cpuid;              /* Assembler instruction limit flag */
+EXTERN int origcpuid;          /* Assembler instruction limit flag */
+
+#endif
+
+/* miscellaneous */
+
+extern char hexdigit[];
+
+/* cpuid functions */
+#ifdef I80386
+#ifndef __AS386_16__
+#define iscpu(x) (cpuid>=(x))
+#define needcpu(x) do{ if(cpuid<(x)) {warning(CPUCLASH); cpuid|=0x10;} }while(0)
+#define setcpu(x) (cpuid=(x))
+#define cpuwarn() (cpuid&=0xF)
+#endif
+#endif
+
+#ifndef setcpu
+#define needcpu(x)
+#define setcpu(x)
+#define cpuwarn()
+#endif
+
diff --git a/Applications/as09/keywords.c b/Applications/as09/keywords.c
new file mode 100644 (file)
index 0000000..c61ea9d
--- /dev/null
@@ -0,0 +1,746 @@
+/* keywords.c - keyword tables for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "globvar.h"
+#include "opcode.h"
+
+/* --- start of keywords --- */
+
+/* registers */
+/* the register code (internal to assembler) is given in 1 byte */
+/* the "opcode" field is not used */
+
+char regs[] =
+{
+#ifdef I80386
+    2, 'B', 'P', BPREG, 0,
+    2, 'B', 'X', BXREG, 0,
+    2, 'D', 'I', DIREG, 0,
+    2, 'S', 'I', SIREG, 0,
+
+    3, 'E', 'A', 'X', EAXREG, 0,
+    3, 'E', 'B', 'P', EBPREG, 0,
+    3, 'E', 'B', 'X', EBXREG, 0,
+    3, 'E', 'C', 'X', ECXREG, 0,
+    3, 'E', 'D', 'I', EDIREG, 0,
+    3, 'E', 'D', 'X', EDXREG, 0,
+    3, 'E', 'S', 'I', ESIREG, 0,
+    3, 'E', 'S', 'P', ESPREG, 0,
+
+    2, 'A', 'X', AXREG, 0,
+    2, 'C', 'X', CXREG, 0,
+    2, 'D', 'X', DXREG, 0,
+    2, 'S', 'P', SPREG, 0,
+
+    2, 'A', 'H', AHREG, 0,
+    2, 'A', 'L', ALREG, 0,
+    2, 'B', 'H', BHREG, 0,
+    2, 'B', 'L', BLREG, 0,
+    2, 'C', 'H', CHREG, 0,
+    2, 'C', 'L', CLREG, 0,
+    2, 'D', 'H', DHREG, 0,
+    2, 'D', 'L', DLREG, 0,
+
+    2, 'C', 'S', CSREG, 0,
+    2, 'D', 'S', DSREG, 0,
+    2, 'E', 'S', ESREG, 0,
+    2, 'F', 'S', FSREG, 0,
+    2, 'G', 'S', GSREG, 0,
+    2, 'S', 'S', SSREG, 0,
+
+    3, 'C', 'R', '0', CR0REG, 0,
+    3, 'C', 'R', '2', CR2REG, 0,
+    3, 'C', 'R', '3', CR3REG, 0,
+    3, 'D', 'R', '0', DR0REG, 0,
+    3, 'D', 'R', '1', DR1REG, 0,
+    3, 'D', 'R', '2', DR2REG, 0,
+    3, 'D', 'R', '3', DR3REG, 0,
+    3, 'D', 'R', '6', DR6REG, 0,
+    3, 'D', 'R', '7', DR7REG, 0,
+    3, 'T', 'R', '3', TR3REG, 0,
+    3, 'T', 'R', '4', TR4REG, 0,
+    3, 'T', 'R', '5', TR5REG, 0,
+    3, 'T', 'R', '6', TR6REG, 0,
+    3, 'T', 'R', '7', TR7REG, 0,
+
+    2, 'S', 'T', ST0REG, 0,
+#endif /* I80386 */
+
+#ifdef MC6809
+    1, 'A', AREG, 0,
+    1, 'B', BREG, 0,
+    2, 'C', 'C', CCREG, 0,
+    1, 'D', DREG, 0,
+    2, 'D', 'P', DPREG, 0,
+    2, 'P', 'C', PCREG, 0,
+    3, 'P', 'C', 'R', PCREG, 0,
+    1, 'S', SREG, 0,
+    1, 'U', UREG, 0,
+    1, 'X', XREG, 0,
+    1, 'Y', YREG, 0,
+#endif
+    0                          /* end of register list */
+};
+
+#ifdef I80386
+
+/* type sizes */
+/* the "opcode" field gives the type size */
+
+char typesizes[] =
+{
+    4, 'B', 'Y', 'T', 'E', BYTEOP, 1,
+    5, 'D', 'W', 'O', 'R', 'D', DWORDOP, 4,
+    5, 'F', 'W', 'O', 'R', 'D', FWORDOP, 6,
+    3, 'F', 'A', 'R', FAROP, 0,
+    4, 'N', 'E', 'A', 'R', WORDOP, 2,
+    3, 'P', 'T', 'R', PTROP, 0,
+    5, 'P', 'W', 'O', 'R', 'D', PWORDOP, 6,
+    5, 'Q', 'W', 'O', 'R', 'D', QWORDOP, 8,
+    5, 'T', 'B', 'Y', 'T', 'E', TBYTEOP, 10,
+    4, 'W', 'O', 'R', 'D', WORDOP, 2,
+    0                          /* end of typesize list */
+};
+
+#endif
+
+/* ops */
+/* the routine number is given in 1 byte */
+/* the opcode is given in 1 byte (it is not used for pseudo-ops) */
+
+char ops[] =
+{
+    /* pseudo-ops. The "opcode" field is unused and padded with a null byte */
+    /* conditionals - must be first */
+    4, 'E', 'L', 'S', 'E', ELSEOP, 0,
+    6, 'E', 'L', 'S', 'E', 'I', 'F', ELSEIFOP, 0,
+    7, 'E', 'L', 'S', 'E', 'I', 'F', 'C', ELSEIFCOP, 0,
+    5, 'E', 'N', 'D', 'I', 'F', ENDIFOP, 0,
+    2, 'I', 'F', IFOP, 0,
+    3, 'I', 'F', 'C', IFCOP, 0,
+
+    /* unconditionals */
+    6, '.', 'A', 'L', 'I', 'G', 'N', ALIGNOP, 0,
+    6, '.', 'A', 'S', 'C', 'I', 'I', FCCOP, 0,
+    6, '.', 'A', 'S', 'C', 'I', 'Z', ASCIZOP, 0,
+    5, '.', 'B', 'L', 'K', 'B', RMBOP, 0,
+    5, '.', 'B', 'L', 'K', 'W', BLKWOP, 0,
+    5, 'B', 'L', 'O', 'C', 'K', BLOCKOP, 0,
+    4, '.', 'B', 'S', 'S', BSSOP, 0,
+    5, '.', 'B', 'Y', 'T', 'E', FCBOP, 0,
+    4, 'C', 'O', 'M', 'M', COMMOP, 0,
+    5, '.', 'C', 'O', 'M', 'M', COMMOP1, 0,
+    5, '.', 'D', 'A', 'T', 'A', DATAOP, 0,
+    6, '.', 'D', 'A', 'T', 'A', '1', FCBOP, 0,
+    6, '.', 'D', 'A', 'T', 'A', '2', FDBOP, 0,
+#if SIZEOF_OFFSET_T > 2
+    6, '.', 'D', 'A', 'T', 'A', '4', FQBOP, 0,
+#endif
+    2, 'D', 'B', FCBOP, 0,
+#if SIZEOF_OFFSET_T > 2
+    2, 'D', 'D', FQBOP, 0,
+#endif
+    7, '.', 'D', 'E', 'F', 'I', 'N', 'E', EXPORTOP, 0,
+    2, 'D', 'W', FDBOP, 0,
+    3, 'E', 'N', 'D', PROCEOFOP, 0,
+    4, 'E', 'N', 'D', 'B', ENDBOP, 0,
+    6, '.', 'E', 'N', 'T', 'E', 'R', ENTEROP, 0,
+    5, 'E', 'N', 'T', 'R', 'Y', ENTRYOP, 0,
+    3, 'E', 'Q', 'U', EQUOP, 0,
+    5, '.', 'E', 'V', 'E', 'N', EVENOP, 0,
+    6, 'E', 'X', 'P', 'O', 'R', 'T', EXPORTOP, 0,
+    6, 'E', 'X', 'T', 'E', 'R', 'N', IMPORTOP, 0,
+    7, '.', 'E', 'X', 'T', 'E', 'R', 'N', IMPORTOP, 0,
+    5, 'E', 'X', 'T', 'R', 'N', IMPORTOP, 0,
+    4, 'F', 'A', 'I', 'L', FAILOP, 0,
+    5, '.', 'F', 'A', 'I', 'L', FAILOP, 0,
+    3, 'F', 'C', 'B', FCBOP, 0,
+    3, 'F', 'C', 'C', FCCOP, 0,
+    3, 'F', 'D', 'B', FDBOP, 0,
+    3, 'G', 'E', 'T', GETOP, 0,
+    7, '.', 'G', 'L', 'O', 'B', 'A', 'L', GLOBLOP, 0,
+    6, '.', 'G', 'L', 'O', 'B', 'L', GLOBLOP, 0,
+    5, 'I', 'D', 'E', 'N', 'T', IDENTOP, 0,
+    6, 'I', 'M', 'P', 'O', 'R', 'T', IMPORTOP, 0,
+    7, 'I', 'N', 'C', 'L', 'U', 'D', 'E', GETOP, 0,
+    5, 'L', 'C', 'O', 'M', 'M', LCOMMOP, 0,
+    6, '.', 'L', 'C', 'O', 'M', 'M', LCOMMOP1, 0,
+    5, '.', 'L', 'I', 'S', 'T', LISTOP, 0,
+    3, 'L', 'O', 'C', LOCOP, 0,
+#if SIZEOF_OFFSET_T > 2
+    5, '.', 'L', 'O', 'N', 'G', FQBOP, 0,
+#endif
+    8, '.', 'M', 'A', 'C', 'L', 'I', 'S', 'T', MACLISTOP, 0,
+    5, 'M', 'A', 'C', 'R', 'O', MACROOP, 0,
+    4, '.', 'M', 'A', 'P', MAPOP, 0,
+    3, 'O', 'R', 'G', ORGOP, 0,
+    4, '.', 'O', 'R', 'G', ORGOP, 0,
+    6, 'P', 'U', 'B', 'L', 'I', 'C', EXPORTOP, 0,
+    3, 'R', 'M', 'B', RMBOP, 0,
+    4, '.', 'R', 'O', 'M', DATAOP, 0,
+    5, '.', 'S', 'E', 'C', 'T', SECTOP, 0,
+    3, 'S', 'E', 'T', SETOP, 0,
+    5, 'S', 'E', 'T', 'D', 'P', SETDPOP, 0,
+    6, '.', 'S', 'H', 'O', 'R', 'T', FDBOP, 0,
+    6, '.', 'S', 'P', 'A', 'C', 'E', RMBOP, 0,
+    5, '.', 'T', 'E', 'X', 'T', TEXTOP, 0,
+#ifndef MC6809
+    5, 'U', 'S', 'E', '1', '6', USE16OP, 0,
+    5, 'U', 'S', 'E', '3', '2', USE32OP, 0,
+#endif
+    5, '.', 'W', 'A', 'R', 'N', WARNOP, 0,
+    5, '.', 'W', 'O', 'R', 'D', FDBOP, 0,
+    6, '.', 'Z', 'E', 'R', 'O', 'W', BLKWOP, 0,
+
+    /* hardware ops. The opcode field is now used */
+#ifdef I80386
+    3, 'A', 'A', 'A', INHER, 0x37,
+    3, 'A', 'A', 'D', INHER_A, 0xD5,
+    3, 'A', 'A', 'M', INHER_A, 0xD4,
+    3, 'A', 'A', 'S', INHER, 0x3F,
+    3, 'A', 'D', 'C', GROUP1, 0x10,
+    3, 'A', 'D', 'D', GROUP1, 0x00,
+    3, 'A', 'N', 'D', GROUP1, 0x20,
+    4, 'A', 'R', 'P', 'L', EwGw, 0x63,
+    3, 'B', 'C', 'C', BCC, 0x73,
+    3, 'B', 'C', 'S', BCC, 0x72,
+    3, 'B', 'E', 'Q', BCC, 0x74,
+    3, 'B', 'G', 'E', BCC, 0x7D,
+    3, 'B', 'G', 'T', BCC, 0x7F,
+    3, 'B', 'H', 'I', BCC, 0x77,
+    4, 'B', 'H', 'I', 'S', BCC, 0x73,
+    3, 'B', 'L', 'E', BCC, 0x7E,
+    3, 'B', 'L', 'O', BCC, 0x72,
+    4, 'B', 'L', 'O', 'S', BCC, 0x76,
+    3, 'B', 'L', 'T', BCC, 0x7C,
+    3, 'B', 'M', 'I', BCC, 0x78,
+    3, 'B', 'N', 'E', BCC, 0x75,
+    5, 'B', 'O', 'U', 'N', 'D', GvMa, 0x62,
+    3, 'B', 'P', 'C', BCC, 0x7B,
+    3, 'B', 'P', 'L', BCC, 0x79,
+    3, 'B', 'P', 'S', BCC, 0x7A,
+    2, 'B', 'R', CALL, JMP_OPCODE,
+    3, 'B', 'V', 'C', BCC, 0x71,
+    3, 'B', 'V', 'S', BCC, 0x70,
+    4, 'C', 'A', 'L', 'L', CALL, JSR_OPCODE,
+    5, 'C', 'A', 'L', 'L', 'F', CALLI, 0x9A,
+    5, 'C', 'A', 'L', 'L', 'I', CALLI, 0x9A,
+    3, 'C', 'B', 'W', INHER16, 0x98,
+    3, 'C', 'L', 'C', INHER, 0xF8,
+    3, 'C', 'L', 'D', INHER, 0xFC,
+    3, 'C', 'L', 'I', INHER, 0xFA,
+    3, 'C', 'M', 'C', INHER, 0xF5,
+    3, 'C', 'M', 'P', GROUP1, CMP_OPCODE_BASE,
+    4, 'C', 'M', 'P', 'S', INHER, CMPSW_OPCODE,
+    5, 'C', 'M', 'P', 'S', 'B', INHER, CMPSB_OPCODE,
+    5, 'C', 'M', 'P', 'S', 'D', INHER32, CMPSW_OPCODE,
+    5, 'C', 'M', 'P', 'S', 'W', INHER16, CMPSW_OPCODE,
+    4, 'C', 'M', 'P', 'W', INHER16, CMPSW_OPCODE,
+    4, 'C', 'S', 'E', 'G', INHER, 0x2E,
+    3, 'C', 'W', 'D', INHER16, 0x99,
+    4, 'C', 'W', 'D', 'E', INHER32, 0x98,
+    3, 'C', 'D', 'Q', INHER32, 0x99,
+    3, 'D', 'A', 'A', INHER, 0x27,
+    3, 'D', 'A', 'S', INHER, 0x2F,
+    4, 'D', 'S', 'E', 'G', INHER, 0x3E,
+    3, 'D', 'E', 'C', INCDEC, 0x08,
+    3, 'D', 'I', 'V', DIVMUL, 0x30,
+    5, 'E', 'N', 'T', 'E', 'R', ENTER, 0xC8,
+    4, 'E', 'S', 'E', 'G', INHER, 0x26,
+    4, 'F', 'S', 'E', 'G', INHER, 0x64,
+    4, 'G', 'S', 'E', 'G', INHER, 0x65,
+    3, 'H', 'L', 'T', INHER, 0xF4,
+    4, 'I', 'D', 'I', 'V', DIVMUL, 0x38,
+    4, 'I', 'M', 'U', 'L', IMUL, 0x28,
+    2, 'I', 'N', IN, 0xEC,
+    3, 'I', 'N', 'C', INCDEC, 0x00,
+    3, 'I', 'N', 'S', INHER, 0x6D,
+    4, 'I', 'N', 'S', 'B', INHER, 0x6C,
+    4, 'I', 'N', 'S', 'D', INHER32, 0x6D,
+    4, 'I', 'N', 'S', 'W', INHER16, 0x6D,
+    3, 'I', 'N', 'T', INT, 0xCD,
+    4, 'I', 'N', 'T', 'O', INHER, 0xCE,
+    3, 'I', 'N', 'W', IN, 0xED,
+    4, 'I', 'R', 'E', 'T', INHER16, 0xCF,
+    5, 'I', 'R', 'E', 'T', 'D', INHER32, 0xCF,
+    1, 'J', CALL, JMP_SHORT_OPCODE,
+    2, 'J', 'A', JCC, 0x77,
+    3, 'J', 'A', 'E', JCC, 0x73,
+    2, 'J', 'B', JCC, 0x72,
+    3, 'J', 'B', 'E', JCC, 0x76,
+    2, 'J', 'C', JCC, 0x72,
+    4, 'J', 'C', 'X', 'E', JCXZ, 0x2,
+    4, 'J', 'C', 'X', 'Z', JCXZ, 0x2,
+    5, 'J', 'E', 'C', 'X', 'E', JCXZ, 0x4,
+    5, 'J', 'E', 'C', 'X', 'Z', JCXZ, 0x4,
+    2, 'J', 'E', JCC, 0x74,
+    2, 'J', 'G', JCC, 0x7F,
+    3, 'J', 'G', 'E', JCC, 0x7D,
+    2, 'J', 'L', JCC, 0x7C,
+    3, 'J', 'L', 'E', JCC, 0x7E,
+    3, 'J', 'M', 'P', CALL, JMP_SHORT_OPCODE,
+    4, 'J', 'M', 'P', 'F', CALLI, 0xEA,
+    4, 'J', 'M', 'P', 'I', CALLI, 0xEA,
+    3, 'J', 'N', 'A', JCC, 0x76,
+    4, 'J', 'N', 'A', 'E', JCC, 0x72,
+    3, 'J', 'N', 'B', JCC, 0x73,
+    4, 'J', 'N', 'B', 'E', JCC, 0x77,
+    3, 'J', 'N', 'C', JCC, 0x73,
+    3, 'J', 'N', 'E', JCC, 0x75,
+    3, 'J', 'N', 'G', JCC, 0x7E,
+    4, 'J', 'N', 'G', 'E', JCC, 0x7C,
+    3, 'J', 'N', 'L', JCC, 0x7D,
+    4, 'J', 'N', 'L', 'E', JCC, 0x7F,
+    3, 'J', 'N', 'O', JCC, 0x71,
+    3, 'J', 'N', 'P', JCC, 0x7B,
+    3, 'J', 'N', 'S', JCC, 0x79,
+    3, 'J', 'N', 'Z', JCC, 0x75,
+    2, 'J', 'O', JCC, 0x70,
+    2, 'J', 'P', JCC, 0x7A,
+    3, 'J', 'P', 'E', JCC, 0x7A,
+    3, 'J', 'P', 'O', JCC, 0x7B,
+    2, 'J', 'S', JCC, 0x78,
+    2, 'J', 'Z', JCC, 0x74,
+    4, 'L', 'A', 'H', 'F', INHER, 0x9F,
+    3, 'L', 'D', 'S', GvMp, 0xC5,
+    3, 'L', 'E', 'A', LEA, 0x8D,
+    5, 'L', 'E', 'A', 'V', 'E', INHER, 0xC9,
+    3, 'L', 'E', 'S', GvMp, 0xC4,
+    4, 'L', 'O', 'C', 'K', INHER, 0xF0,
+    4, 'L', 'O', 'D', 'B', INHER, 0xAC,
+    4, 'L', 'O', 'D', 'S', INHER, 0xAD,
+    5, 'L', 'O', 'D', 'S', 'B', INHER, 0xAC,
+    5, 'L', 'O', 'D', 'S', 'D', INHER32, 0xAD,
+    5, 'L', 'O', 'D', 'S', 'W', INHER16, 0xAD,
+    4, 'L', 'O', 'D', 'W', INHER16, 0xAD,
+    4, 'L', 'O', 'O', 'P', JCC, 0xE2,
+    5, 'L', 'O', 'O', 'P', 'E', JCC, 0xE1,
+    6, 'L', 'O', 'O', 'P', 'N', 'E', JCC, 0xE0,
+    6, 'L', 'O', 'O', 'P', 'N', 'Z', JCC, 0xE0,
+    5, 'L', 'O', 'O', 'P', 'Z', JCC, 0xE1,
+    3, 'M', 'O', 'V', MOV, 0x88,
+    4, 'M', 'O', 'V', 'S', INHER, MOVSW_OPCODE,
+    5, 'M', 'O', 'V', 'S', 'B', INHER, MOVSB_OPCODE,
+    5, 'M', 'O', 'V', 'S', 'D', INHER32, MOVSW_OPCODE,
+    5, 'M', 'O', 'V', 'S', 'W', INHER16, MOVSW_OPCODE,
+    4, 'M', 'O', 'V', 'W', INHER16, MOVSW_OPCODE,
+    3, 'M', 'U', 'L', DIVMUL, 0x20,
+    3, 'N', 'E', 'G', NEGNOT, 0x18,
+    3, 'N', 'O', 'P', INHER, 0x90,
+    3, 'N', 'O', 'T', NEGNOT, 0x10,
+    2, 'O', 'R', GROUP1, 0x08,
+    3, 'O', 'U', 'T', OUT, 0xEE,
+    4, 'O', 'U', 'T', 'S', INHER, 0x6F,
+    5, 'O', 'U', 'T', 'S', 'B', INHER, 0x6E,
+    5, 'O', 'U', 'T', 'S', 'D', INHER32, 0x6F,
+    5, 'O', 'U', 'T', 'S', 'W', INHER16, 0x6F,
+    4, 'O', 'U', 'T', 'W', OUT, 0xEF,
+    3, 'P', 'O', 'P', PUSHPOP, POP_OPCODE,
+    4, 'P', 'O', 'P', 'A', INHER16, 0x61,
+    5, 'P', 'O', 'P', 'A', 'D', INHER32, 0x61,
+    4, 'P', 'O', 'P', 'F', INHER16, 0x9D,
+    5, 'P', 'O', 'P', 'F', 'D', INHER32, 0x9D,
+    4, 'P', 'U', 'S', 'H', PUSHPOP, PUSH_OPCODE,
+    5, 'P', 'U', 'S', 'H', 'A', INHER16, 0x60,
+    6, 'P', 'U', 'S', 'H', 'A', 'D', INHER32, 0x60,
+    5, 'P', 'U', 'S', 'H', 'F', INHER16, 0x9C,
+    6, 'P', 'U', 'S', 'H', 'F', 'D', INHER32, 0x9C,
+    3, 'R', 'C', 'L', GROUP2, 0x10,
+    3, 'R', 'C', 'R', GROUP2, 0x18,
+    3, 'R', 'O', 'L', GROUP2, 0x00,
+    3, 'R', 'O', 'R', GROUP2, 0x08,
+    3, 'R', 'E', 'P', INHER, 0xF3,
+    4, 'R', 'E', 'P', 'E', INHER, 0xF3,
+    5, 'R', 'E', 'P', 'N', 'E', INHER, 0xF2,
+    5, 'R', 'E', 'P', 'N', 'Z', INHER, 0xF2,
+    4, 'R', 'E', 'P', 'Z', INHER, 0xF3,
+    3, 'R', 'E', 'T', RET, 0xC3,
+    4, 'R', 'E', 'T', 'F', RET, 0xCB,
+    4, 'R', 'E', 'T', 'I', RET, 0xCB,
+    4, 'S', 'A', 'H', 'F', INHER, 0x9E,
+    3, 'S', 'A', 'L', GROUP2, 0x20,
+    3, 'S', 'A', 'R', GROUP2, 0x38,
+    3, 'S', 'B', 'B', GROUP1, 0x18,
+    4, 'S', 'C', 'A', 'B', INHER, 0xAE,
+    4, 'S', 'C', 'A', 'S', INHER, 0xAF,
+    5, 'S', 'C', 'A', 'S', 'B', INHER, 0xAE,
+    5, 'S', 'C', 'A', 'S', 'D', INHER32, 0xAF,
+    5, 'S', 'C', 'A', 'S', 'W', INHER16, 0xAF,
+    4, 'S', 'C', 'A', 'W', INHER16, 0xAF,
+    3, 'S', 'E', 'G', SEG, 0x06,
+    3, 'S', 'H', 'L', GROUP2, 0x20,
+    3, 'S', 'H', 'R', GROUP2, 0x28,
+    4, 'S', 'S', 'E', 'G', INHER, 0x36,
+    3, 'S', 'T', 'C', INHER, 0xF9,
+    3, 'S', 'T', 'D', INHER, 0xFD,
+    3, 'S', 'T', 'I', INHER, 0xFB,
+    4, 'S', 'T', 'O', 'B', INHER, 0xAA,
+    4, 'S', 'T', 'O', 'S', INHER, 0xAB,
+    5, 'S', 'T', 'O', 'S', 'B', INHER, 0xAA,
+    5, 'S', 'T', 'O', 'S', 'D', INHER32, 0xAB,
+    5, 'S', 'T', 'O', 'S', 'W', INHER16, 0xAB,
+    4, 'S', 'T', 'O', 'W', INHER16, 0xAB,
+    3, 'S', 'U', 'B', GROUP1, 0x28,
+    4, 'T', 'E', 'S', 'T', TEST, 0x84,
+    4, 'W', 'A', 'I', 'T', INHER, WAIT_OPCODE,
+    4, 'X', 'C', 'H', 'G', XCHG, 0x86,
+    4, 'X', 'L', 'A', 'T', INHER, 0xD7,
+    5, 'X', 'L', 'A', 'T', 'B', INHER, 0xD7,
+    3, 'X', 'O', 'R', GROUP1, 0x30,
+
+    /* floating point */
+    5, 'F', '2', 'X', 'M', '1', F_INHER, 0x70,
+    4, 'F', 'A', 'B', 'S', F_INHER, 0x61,
+    4, 'F', 'A', 'D', 'D', F_M4_M8_STST, 0x00,
+    5, 'F', 'A', 'D', 'D', 'P', F_STST, 0x60,
+    4, 'F', 'B', 'L', 'D', F_M10, 0x74,
+    5, 'F', 'B', 'S', 'T', 'P', F_M10, 0x76,
+    4, 'F', 'C', 'H', 'S', F_INHER, 0x60,
+    5, 'F', 'C', 'L', 'E', 'X', F_W_INHER, 0xE2,
+    4, 'F', 'C', 'O', 'M', F_M4_M8_OPTST, 0x02,
+    5, 'F', 'C', 'O', 'M', 'P', F_M4_M8_OPTST, 0x03,
+    6, 'F', 'C', 'O', 'M', 'P', 'P', F_INHER, 0x19,
+    4, 'F', 'C', 'O', 'S', F_INHER, 0x7F,
+    7, 'F', 'D', 'E', 'C', 'S', 'T', 'P', F_INHER, 0x76,
+    5, 'F', 'D', 'I', 'S', 'I', F_W_INHER, 0xE1,
+    4, 'F', 'D', 'I', 'V', F_M4_M8_STST, 0x06,
+    5, 'F', 'D', 'I', 'V', 'P', F_STST, 0x67,
+    5, 'F', 'D', 'I', 'V', 'R', F_M4_M8_STST, 0x07,
+    6, 'F', 'D', 'I', 'V', 'R', 'P', F_STST, 0x66,
+    4, 'F', 'E', 'N', 'I', F_W_INHER, 0xE0,
+    5, 'F', 'F', 'R', 'E', 'E', F_ST, 0x50,
+    5, 'F', 'I', 'A', 'D', 'D', F_M2_M4, 0x20,
+    5, 'F', 'I', 'C', 'O', 'M', F_M2_M4, 0x22,
+    6, 'F', 'I', 'C', 'O', 'M', 'P', F_M2_M4, 0x23,
+    5, 'F', 'I', 'D', 'I', 'V', F_M2_M4, 0x26,
+    6, 'F', 'I', 'D', 'I', 'V', 'R', F_M2_M4, 0x27,
+    4, 'F', 'I', 'L', 'D', F_M2_M4_M8, 0x30,
+    5, 'F', 'I', 'M', 'U', 'L', F_M2_M4, 0x21,
+    7, 'F', 'I', 'N', 'C', 'S', 'T', 'P', F_INHER, 0x77,
+    5, 'F', 'I', 'N', 'I', 'T', F_W_INHER, 0xE3,
+    4, 'F', 'I', 'S', 'T', F_M2_M4, 0x32,
+    5, 'F', 'I', 'S', 'T', 'P', F_M2_M4_M8, 0x33,
+    5, 'F', 'I', 'S', 'U', 'B', F_M2_M4, 0x24,
+    6, 'F', 'I', 'S', 'U', 'B', 'R', F_M2_M4, 0x25,
+    3, 'F', 'L', 'D', F_M4_M8_M10_ST, 0x10,
+    4, 'F', 'L', 'D', '1', F_INHER, 0x68,
+    6, 'F', 'L', 'D', 'L', '2', 'E', F_INHER, 0x6A,
+    6, 'F', 'L', 'D', 'L', '2', 'T', F_INHER, 0x69,
+    5, 'F', 'L', 'D', 'C', 'W', F_M2, 0x15,
+    6, 'F', 'L', 'D', 'E', 'N', 'V', F_M, 0x14,
+    6, 'F', 'L', 'D', 'L', 'G', '2', F_INHER, 0x6C,
+    6, 'F', 'L', 'D', 'L', 'N', '2', F_INHER, 0x6D,
+    5, 'F', 'L', 'D', 'P', 'I', F_INHER, 0x6B,
+    4, 'F', 'L', 'D', 'Z', F_INHER, 0x6E,
+    4, 'F', 'M', 'U', 'L', F_M4_M8_STST, 0x01,
+    5, 'F', 'M', 'U', 'L', 'P', F_STST, 0x61,
+    6, 'F', 'N', 'C', 'L', 'E', 'X', F_INHER, 0xE2,
+    6, 'F', 'N', 'D', 'I', 'S', 'I', F_INHER, 0xE1,
+    5, 'F', 'N', 'E', 'N', 'I', F_INHER, 0xE0,
+    6, 'F', 'N', 'I', 'N', 'I', 'T', F_INHER, 0xE3,
+    4, 'F', 'N', 'O', 'P', F_INHER, 0x50,
+    6, 'F', 'N', 'S', 'A', 'V', 'E', F_M, 0x56,
+    6, 'F', 'N', 'S', 'T', 'C', 'W', F_M2, 0x17,
+    7, 'F', 'N', 'S', 'T', 'E', 'N', 'V', F_M, 0x16,
+    6, 'F', 'N', 'S', 'T', 'S', 'W', F_M2_AX, 0x57,
+    6, 'F', 'P', 'A', 'T', 'A', 'N', F_INHER, 0x73,
+    5, 'F', 'P', 'R', 'E', 'M', F_INHER, 0x78,
+    6, 'F', 'P', 'R', 'E', 'M', '1', F_INHER, 0x75,
+    5, 'F', 'P', 'T', 'A', 'N', F_INHER, 0x72,
+    7, 'F', 'R', 'N', 'D', 'I', 'N', 'T', F_INHER, 0x7C,
+    6, 'F', 'R', 'S', 'T', 'O', 'R', F_M, 0x54,
+    5, 'F', 'S', 'A', 'V', 'E', F_W_M, 0x56,
+    6, 'F', 'S', 'C', 'A', 'L', 'E', F_INHER, 0x7D,
+    6, 'F', 'S', 'E', 'T', 'P', 'M', F_INHER, 0xE4,
+    4, 'F', 'S', 'I', 'N', F_INHER, 0x7E,
+    7, 'F', 'S', 'I', 'N', 'C', 'O', 'S', F_INHER, 0x7B,
+    5, 'F', 'S', 'Q', 'R', 'T', F_INHER, 0x7A,
+    3, 'F', 'S', 'T', F_M4_M8_ST, FST_ENCODED,
+    5, 'F', 'S', 'T', 'C', 'W', F_W_M2, 0x17,
+    6, 'F', 'S', 'T', 'E', 'N', 'V', F_W_M, 0x16,
+    4, 'F', 'S', 'T', 'P', F_M4_M8_M10_ST, FSTP_ENCODED,
+    5, 'F', 'S', 'T', 'S', 'W', F_W_M2_AX, 0x57,
+    4, 'F', 'S', 'U', 'B', F_M4_M8_STST, 0x04,
+    5, 'F', 'S', 'U', 'B', 'P', F_STST, 0x65,
+    5, 'F', 'S', 'U', 'B', 'R', F_M4_M8_STST, 0x05,
+    6, 'F', 'S', 'U', 'B', 'R', 'P', F_STST, 0x64,
+    4, 'F', 'T', 'S', 'T', F_INHER, 0x64,
+    5, 'F', 'U', 'C', 'O', 'M', F_OPTST, 0x54,
+    6, 'F', 'U', 'C', 'O', 'M', 'P', F_OPTST, 0x55,
+    7, 'F', 'U', 'C', 'O', 'M', 'P', 'P', F_INHER, 0xA9,
+    5, 'F', 'W', 'A', 'I', 'T', INHER, WAIT_OPCODE,
+    4, 'F', 'X', 'A', 'M', F_INHER, 0x65,
+    4, 'F', 'X', 'C', 'H', F_OPTST, 0x11,
+    7, 'F', 'X', 'T', 'R', 'A', 'C', 'T', F_INHER, 0x74,
+    5, 'F', 'Y', 'L', '2', 'X', F_INHER, 0x71,
+    7, 'F', 'Y', 'L', '2', 'X', 'P', '1', F_INHER, 0x79,
+#endif /* I80386 */
+
+#ifdef MC6809
+    3, 'A', 'B', 'X', INHER, 0x3A,
+    4, 'A', 'D', 'C', 'A', ALL, 0x89,
+    4, 'A', 'D', 'C', 'B', ALL, 0xC9,
+    4, 'A', 'D', 'D', 'A', ALL, 0x8B,
+    4, 'A', 'D', 'D', 'B', ALL, 0xCB,
+    4, 'A', 'D', 'D', 'D', ALL, 0xC3,
+    4, 'A', 'N', 'D', 'A', ALL, 0x84,
+    4, 'A', 'N', 'D', 'B', ALL, 0xC4,
+    5, 'A', 'N', 'D', 'C', 'C', IMMED, 0x1C,
+    3, 'A', 'S', 'L', ALTER, 0x08,
+    4, 'A', 'S', 'L', 'A', INHER, 0x48,
+    4, 'A', 'S', 'L', 'B', INHER, 0x58,
+    3, 'A', 'S', 'R', ALTER, 0x07,
+    4, 'A', 'S', 'R', 'A', INHER, 0x47,
+    4, 'A', 'S', 'R', 'B', INHER, 0x57,
+    3, 'B', 'C', 'C', SHORT, 0x24,
+    3, 'B', 'C', 'S', SHORT, 0x25,
+    3, 'B', 'E', 'Q', SHORT, 0x27,
+    3, 'B', 'G', 'E', SHORT, 0x2C,
+    3, 'B', 'G', 'T', SHORT, 0x2E,
+    3, 'B', 'H', 'I', SHORT, 0x22,
+    3, 'B', 'H', 'S', SHORT, 0x24,
+    4, 'B', 'I', 'T', 'A', ALL, 0X85,
+    4, 'B', 'I', 'T', 'B', ALL, 0XC5,
+    3, 'B', 'L', 'E', SHORT, 0x2F,
+    3, 'B', 'L', 'O', SHORT, 0x25,
+    3, 'B', 'L', 'S', SHORT, 0x23,
+    3, 'B', 'L', 'T', SHORT, 0x2D,
+    3, 'B', 'M', 'I', SHORT, 0x2B,
+    3, 'B', 'N', 'E', SHORT, 0x26,
+    3, 'B', 'P', 'L', SHORT, 0x2A,
+    3, 'B', 'R', 'A', SHORT, 0x20,
+    4, 'L', 'B', 'R', 'A', LONG, 0x16,
+    3, 'B', 'R', 'N', SHORT, 0x21,
+    3, 'B', 'S', 'R', SHORT, 0x8D,
+    4, 'L', 'B', 'S', 'R', LONG, 0x17,
+    3, 'B', 'V', 'C', SHORT, 0x28,
+    3, 'B', 'V', 'S', SHORT, 0x29,
+    3, 'C', 'L', 'R', ALTER, 0x0F,
+    4, 'C', 'L', 'R', 'A', INHER, 0x4F,
+    4, 'C', 'L', 'R', 'B', INHER, 0x5F,
+    4, 'C', 'M', 'P', 'A', ALL, 0x81,
+    4, 'C', 'M', 'P', 'B', ALL, 0xC1,
+    4, 'C', 'M', 'P', 'X', ALL, 0x8C,
+    3, 'C', 'O', 'M', ALTER, 0x03,
+    4, 'C', 'O', 'M', 'A', INHER, 0x43,
+    4, 'C', 'O', 'M', 'B', INHER, 0x53,
+    4, 'C', 'W', 'A', 'I', IMMED, 0x3C,
+    3, 'D', 'A', 'A', INHER, 0x19,
+    3, 'D', 'E', 'C', ALTER, 0x0A,
+    4, 'D', 'E', 'C', 'A', INHER, 0x4A,
+    4, 'D', 'E', 'C', 'B', INHER, 0x5A,
+    4, 'E', 'O', 'R', 'A', ALL, 0x88,
+    4, 'E', 'O', 'R', 'B', ALL, 0xC8,
+    3, 'E', 'X', 'G', SWAP, 0x1E,
+    3, 'I', 'N', 'C', ALTER, 0x0C,
+    4, 'I', 'N', 'C', 'A', INHER, 0x4C,
+    4, 'I', 'N', 'C', 'B', INHER, 0x5C,
+    3, 'J', 'M', 'P', ALTER, 0x0E,
+    3, 'J', 'S', 'R', ALTER, 0x8D,
+    3, 'L', 'D', 'A', ALL, 0x86,
+    3, 'L', 'D', 'B', ALL, 0xC6,
+    3, 'L', 'D', 'D', ALL, 0xCC,
+    3, 'L', 'D', 'U', ALL, 0xCE,
+    3, 'L', 'D', 'X', ALL, 0x8E,
+    4, 'L', 'E', 'A', 'S', INDEXD, 0x32,
+    4, 'L', 'E', 'A', 'U', INDEXD, 0x33,
+    4, 'L', 'E', 'A', 'X', INDEXD, 0x30,
+    4, 'L', 'E', 'A', 'Y', INDEXD, 0x31,
+    3, 'L', 'S', 'L', ALTER, 0x08,
+    4, 'L', 'S', 'L', 'A', INHER, 0x48,
+    4, 'L', 'S', 'L', 'B', INHER, 0x58,
+    3, 'L', 'S', 'R', ALTER, 0x04,
+    4, 'L', 'S', 'R', 'A', INHER, 0x44,
+    4, 'L', 'S', 'R', 'B', INHER, 0x54,
+    3, 'M', 'U', 'L', INHER, 0x3D,
+    3, 'N', 'E', 'G', ALTER, 0x00,
+    4, 'N', 'E', 'G', 'A', INHER, 0x40,
+    4, 'N', 'E', 'G', 'B', INHER, 0x50,
+    3, 'N', 'O', 'P', INHER, 0x12,
+    3, 'O', 'R', 'A', ALL, 0x8A,
+    3, 'O', 'R', 'B', ALL, 0xCA,
+    4, 'O', 'R', 'C', 'C', IMMED, 0x1A,
+    4, 'P', 'S', 'H', 'S', SSTAK, 0x34,
+    4, 'P', 'S', 'H', 'U', USTAK, 0x36,
+    4, 'P', 'U', 'L', 'S', SSTAK, 0x35,
+    4, 'P', 'U', 'L', 'U', USTAK, 0x37,
+    3, 'R', 'O', 'L', ALTER, 0x09,
+    4, 'R', 'O', 'L', 'A', INHER, 0x49,
+    4, 'R', 'O', 'L', 'B', INHER, 0x59,
+    3, 'R', 'O', 'R', ALTER, 0x06,
+    4, 'R', 'O', 'R', 'A', INHER, 0x46,
+    4, 'R', 'O', 'R', 'B', INHER, 0x56,
+    3, 'R', 'T', 'I', INHER, 0x3B,
+    3, 'R', 'T', 'S', INHER, 0x39,
+    4, 'S', 'B', 'C', 'A', ALL, 0x82,
+    4, 'S', 'B', 'C', 'B', ALL, 0xC2,
+    3, 'S', 'E', 'X', INHER, 0x1D,
+    3, 'S', 'T', 'A', ALTER, 0x87,
+    3, 'S', 'T', 'B', ALTER, 0xC7,
+    3, 'S', 'T', 'D', ALTER, 0xCD,
+    3, 'S', 'T', 'U', ALTER, 0xCF,
+    3, 'S', 'T', 'X', ALTER, 0x8F,
+    4, 'S', 'U', 'B', 'A', ALL, 0x80,
+    4, 'S', 'U', 'B', 'B', ALL, 0xC0,
+    4, 'S', 'U', 'B', 'D', ALL, 0x83,
+    3, 'S', 'W', 'I', INHER, 0x3F,
+    4, 'S', 'Y', 'N', 'C', INHER, 0x13,
+    3, 'T', 'F', 'R', SWAP, 0x1F,
+    3, 'T', 'S', 'T', ALTER, 0x0D,
+    4, 'T', 'S', 'T', 'A', INHER, 0x4D,
+    4, 'T', 'S', 'T', 'B', INHER, 0x5D,
+#endif /* MC6809 */
+    0                          /* end of ops */
+};
+
+char page1ops[] =
+{
+#ifdef I80386
+    3, 'B', 'S', 'F', GvEv, 0xBC,
+    3, 'B', 'S', 'R', GvEv, 0xBD,
+    5, 'B', 'S', 'W', 'A', 'P', BSWAP, 0xC8,
+    2, 'B', 'T', GROUP8, 0x20,
+    3, 'B', 'T', 'C', GROUP8, 0x38,
+    3, 'B', 'T', 'R', GROUP8, 0x30,
+    3, 'B', 'T', 'S', GROUP8, 0x28,
+    4, 'C', 'L', 'T', 'S', INHER, 0x06,
+    7, 'C', 'M', 'P', 'X', 'C', 'H', 'G', ExGx, 0xA6,
+    4, 'I', 'N', 'V', 'D', INHER, 0x08,
+    6, 'I', 'N', 'V', 'L', 'P', 'G', GROUP7, 0x38,
+    3, 'L', 'A', 'R', GvEv, 0x02,
+    3, 'L', 'F', 'S', GvMp, 0xB4,
+    4, 'L', 'G', 'D', 'T', GROUP7, 0x10,
+    3, 'L', 'G', 'S', GvMp, 0xB5,
+    4, 'L', 'I', 'D', 'T', GROUP7, 0x18,
+    4, 'L', 'L', 'D', 'T', GROUP6, 0x10,
+    4, 'L', 'M', 'S', 'W', GROUP7, 0x30,
+    3, 'L', 'S', 'L', GvEv, 0x03,
+    3, 'L', 'S', 'S', GvMp, 0xB2,
+    3, 'L', 'T', 'R', GROUP6, 0x18,
+    5, 'M', 'O', 'V', 'S', 'X', MOVX, 0xBE,
+    5, 'M', 'O', 'V', 'Z', 'X', MOVX, 0xB6,
+    5, 'R', 'D', 'M', 'S', 'R', INHER, 0x32,
+    4, 'S', 'E', 'T', 'A', SETCC, 0x97,
+    5, 'S', 'E', 'T', 'A', 'E', SETCC, 0x93,
+    4, 'S', 'E', 'T', 'B', SETCC, 0x92,
+    5, 'S', 'E', 'T', 'B', 'E', SETCC, 0x96,
+    4, 'S', 'E', 'T', 'C', SETCC, 0x92,
+    4, 'S', 'E', 'T', 'E', SETCC, 0x94,
+    4, 'S', 'E', 'T', 'G', SETCC, 0x9F,
+    5, 'S', 'E', 'T', 'G', 'E', SETCC, 0x9D,
+    4, 'S', 'E', 'T', 'L', SETCC, 0x9C,
+    5, 'S', 'E', 'T', 'L', 'E', SETCC, 0x9E,
+    5, 'S', 'E', 'T', 'N', 'A', SETCC, 0x96,
+    6, 'S', 'E', 'T', 'N', 'A', 'E', SETCC, 0x92,
+    5, 'S', 'E', 'T', 'N', 'B', SETCC, 0x93,
+    6, 'S', 'E', 'T', 'N', 'B', 'E', SETCC, 0x97,
+    5, 'S', 'E', 'T', 'N', 'C', SETCC, 0x93,
+    5, 'S', 'E', 'T', 'N', 'E', SETCC, 0x95,
+    5, 'S', 'E', 'T', 'N', 'G', SETCC, 0x9E,
+    6, 'S', 'E', 'T', 'N', 'G', 'E', SETCC, 0x9C,
+    5, 'S', 'E', 'T', 'N', 'L', SETCC, 0x9D,
+    6, 'S', 'E', 'T', 'N', 'L', 'E', SETCC, 0x9F,
+    5, 'S', 'E', 'T', 'N', 'O', SETCC, 0x91,
+    5, 'S', 'E', 'T', 'N', 'P', SETCC, 0x9B,
+    5, 'S', 'E', 'T', 'N', 'S', SETCC, 0x99,
+    5, 'S', 'E', 'T', 'N', 'Z', SETCC, 0x95,
+    4, 'S', 'E', 'T', 'O', SETCC, 0x90,
+    4, 'S', 'E', 'T', 'P', SETCC, 0x9A,
+    5, 'S', 'E', 'T', 'P', 'E', SETCC, 0x9A,
+    5, 'S', 'E', 'T', 'P', 'O', SETCC, 0x9B,
+    4, 'S', 'E', 'T', 'S', SETCC, 0x98,
+    4, 'S', 'E', 'T', 'Z', SETCC, 0x94,
+    4, 'S', 'G', 'D', 'T', GROUP7, 0x00,
+    4, 'S', 'I', 'D', 'T', GROUP7, 0x08,
+    4, 'S', 'H', 'L', 'D', SH_DOUBLE, 0xA4,
+    4, 'S', 'H', 'R', 'D', SH_DOUBLE, 0xAC,
+    4, 'S', 'L', 'D', 'T', GROUP6, 0x00,
+    4, 'S', 'M', 'S', 'W', GROUP7, 0x20,
+    3, 'S', 'T', 'R', GROUP6, 0x08,
+    4, 'V', 'E', 'R', 'R', GROUP6, 0x20,
+    4, 'V', 'E', 'R', 'W', GROUP6, 0x28,
+    6, 'W', 'B', 'I', 'N', 'V', 'D', INHER, 0x09,
+    5, 'W', 'R', 'M', 'S', 'R', INHER, 0x30,
+    4, 'X', 'A', 'D', 'D', ExGx, 0xC0,
+#endif /* I80386 */
+
+#ifdef MC6809
+    4, 'L', 'B', 'C', 'C', LONG, 0x24,
+    4, 'L', 'B', 'C', 'S', LONG, 0x25,
+    4, 'L', 'B', 'E', 'Q', LONG, 0x27,
+    4, 'L', 'B', 'G', 'E', LONG, 0x2C,
+    4, 'L', 'B', 'G', 'T', LONG, 0x2E,
+    4, 'L', 'B', 'H', 'I', LONG, 0x22,
+    4, 'L', 'B', 'H', 'S', LONG, 0x24,
+    4, 'L', 'B', 'L', 'E', LONG, 0x2F,
+    4, 'L', 'B', 'L', 'O', LONG, 0x25,
+    4, 'L', 'B', 'L', 'S', LONG, 0x23,
+    4, 'L', 'B', 'L', 'T', LONG, 0x2D,
+    4, 'L', 'B', 'M', 'I', LONG, 0x2B,
+    4, 'L', 'B', 'N', 'E', LONG, 0x26,
+    4, 'L', 'B', 'P', 'L', LONG, 0x2A,
+    4, 'L', 'B', 'R', 'N', LONG, 0x21,
+    4, 'L', 'B', 'V', 'C', LONG, 0x28,
+    4, 'L', 'B', 'V', 'S', LONG, 0x29,
+    4, 'C', 'M', 'P', 'D', ALL, 0x83,
+    4, 'C', 'M', 'P', 'Y', ALL, 0x8C,
+    3, 'L', 'D', 'S', ALL, 0xCE,
+    3, 'L', 'D', 'Y', ALL, 0x8E,
+    3, 'S', 'T', 'S', ALTER, 0xCF,
+    3, 'S', 'T', 'Y', ALTER, 0x8F,
+    4, 'S', 'W', 'I', '2', INHER, 0x3F,
+#endif /* MC6809 */
+    0                          /* end of page 1 ops */
+};
+
+char page2ops[] =
+{
+#ifdef MC6809
+    4, 'C', 'M', 'P', 'S', ALL, 0x8C,
+    4, 'C', 'M', 'P', 'U', ALL, 0x83,
+    4, 'S', 'W', 'I', '3', INHER, 0x3F,
+#endif
+    0                          /* end of page 2 ops */
+};
+
+#ifdef I80386
+# ifdef MNSIZE
+char bytesizeops[] =
+{
+    4, 'A', 'D', 'C', 'B', GROUP1, 0x10,
+    4, 'A', 'D', 'D', 'B', GROUP1, 0x00,
+    4, 'A', 'N', 'D', 'B', GROUP1, 0x20,
+    4, 'C', 'M', 'P', 'B', GROUP1, CMP_OPCODE_BASE,
+    4, 'D', 'E', 'C', 'B', INCDEC, 0x08,
+    4, 'D', 'I', 'V', 'B', DIVMUL, 0x30,
+    5, 'I', 'D', 'I', 'V', 'B', DIVMUL, 0x38,
+    5, 'I', 'M', 'U', 'L', 'B', IMUL, 0x28,
+    3, 'I', 'N', 'B', IN, 0xEC,
+    4, 'I', 'N', 'C', 'B', INCDEC, 0x00,
+    4, 'M', 'O', 'V', 'B', MOV, 0x88,
+    4, 'M', 'U', 'L', 'B', DIVMUL, 0x20,
+    4, 'N', 'E', 'G', 'B', NEGNOT, 0x18,
+    4, 'N', 'O', 'T', 'B', NEGNOT, 0x10,
+    3, 'O', 'R', 'B', GROUP1, 0x08,
+    4, 'O', 'U', 'T', 'B', OUT, 0xEE,
+    4, 'R', 'C', 'L', 'B', GROUP2, 0x10,
+    4, 'R', 'C', 'R', 'B', GROUP2, 0x18,
+    4, 'R', 'O', 'L', 'B', GROUP2, 0x00,
+    4, 'R', 'O', 'R', 'B', GROUP2, 0x08,
+    4, 'S', 'A', 'L', 'B', GROUP2, 0x20,
+    4, 'S', 'A', 'R', 'B', GROUP2, 0x38,
+    4, 'S', 'H', 'L', 'B', GROUP2, 0x20,
+    4, 'S', 'H', 'R', 'B', GROUP2, 0x28,
+    4, 'S', 'B', 'B', 'B', GROUP1, 0x18,
+    4, 'S', 'U', 'B', 'B', GROUP1, 0x28,
+    5, 'T', 'E', 'S', 'T', 'B', TEST, 0x84,
+    5, 'X', 'C', 'H', 'G', 'B', XCHG, 0x86,
+    4, 'X', 'O', 'R', 'B', GROUP1, 0x30,
+    0                          /* end of byte size ops */
+};
+# endif /* MNSIZE */
+#endif /* I80386 */
+
+/* --- end of keywords --- */
diff --git a/Applications/as09/macro.c b/Applications/as09/macro.c
new file mode 100644 (file)
index 0000000..036bdc9
--- /dev/null
@@ -0,0 +1,174 @@
+/* macro.c - expand macros for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "globvar.h"
+#include "scan.h"
+#undef EXTERN
+#define EXTERN
+#include "macro.h"
+
+/*
+  Enter macro: stack macro and get its parameters.
+  Parameters form a linked list of null-terminated strings of form
+  next:string. The first string is the macro number in 4 bytes.
+*/
+
+void entermac(struct sym_s *symptr)
+{
+    if (maclevel >= MAXMAC)
+       error(MACOV);
+    else if (macpar + 2 > macptop)
+       error(PAROV);           /* no room for 0th param */
+                               /* (2 structs to fit it!) */
+    else
+    {
+       char ch;
+       struct schain_s *param1;
+       register char *reglineptr;
+       register char *stringptr;
+
+       ++maclevel;
+       (--macstak)->text = (char *) symptr->value_reg_or_op.value;
+       macstak->parameters = param1 = macpar;
+       param1->next = NUL_PTR;
+       *(stringptr = build_number(++macnum, 3, param1->string)) = 0;
+       macpar = (struct schain_s *) (stringptr + 1);
+                               /* TODO: alignment */
+       getsym();
+       if (sym == EOLSYM)
+           return;             /* no other params */
+       if (sym != LPAREN)
+           reglineptr = symname;
+       else
+           reglineptr = lineptr;
+       stringptr = macpar->string;
+       while (TRUE)
+       {
+           if (stringptr >= (char *) macptop)
+           {
+               symname = reglineptr;
+               error(PAROV);
+               return;
+           }
+           ch = *reglineptr++;
+           if (ch == '\\')
+               /* escaped means no special meaning for slash, comma, paren */
+               ch = *reglineptr++;
+           else if (ch == ',' || ch == ')' || ch == '!' || ch == ';' 
+                 || ch == '\n' || ch == 0)
+           {
+               if (stringptr >= (char *) macptop)
+               {
+                   symname = reglineptr;
+                   error(PAROV);       /* no room for null */
+                   return;
+               }
+               *stringptr = 0;
+               param1->next = macpar;  /* ptr from previous */
+               (param1 = macpar)->next = NUL_PTR;
+                                       /* this goes nowhere */
+               macpar = (struct schain_s *) (stringptr + 1);
+                                       /* but is finished OK - TODO align */
+               stringptr = macpar->string;
+               if (ch != ',')
+                   return;
+               continue;
+           }
+           if ((*stringptr++ = ch) == 0)
+           {
+               symname = reglineptr;
+               error(RPEXP);
+               return;
+           }
+       }
+    }
+}
+
+/* MACRO pseudo-op */
+
+void pmacro(void)
+{
+    bool_t saving;
+    bool_t savingc;
+    struct sym_s *symptr=0;
+    int    maclen = 8;
+    int    macoff = 0;
+    char * macbuf = asalloc(8);
+
+    saving =                   /* prepare for bad macro */
+       savingc = FALSE;        /* normally don't save comments */
+    macload = TRUE;            /* show loading */
+    if (label != NUL_PTR)
+       error(ILLAB);
+    else if (sym != IDENT)
+       error(LABEXP);
+    else
+    {
+       symptr = gsymptr;
+       if (symptr->type & MNREGBIT)
+           error(LABEXP);
+       else if (symptr->type & LABIT || symptr->data & FORBIT)
+           error(RELAB);
+       else if (pass != last_pass || symptr->type & REDBIT)
+                               /* copy on pass 0, also pass 1 if redefined */
+       {
+           saving = TRUE;
+           if (symptr->type & MACBIT)
+               symptr->type |= REDBIT;
+           else
+               symptr->type |= MACBIT;
+           symptr->data = UNDBIT;      /* undefined till end */
+           symptr->value_reg_or_op.value = (offset_t) macbuf;
+           getsym_nolookup();          /* test for "C" */
+           if (sym == IDENT && lineptr == symname + 1 && *symname == 'C')
+               savingc = TRUE;
+       }
+    }
+    while (TRUE)
+    {
+       skipline();
+       listline();
+       readline();
+       if (!macload)
+           break;              /* macload cleared to show eof */
+       getsym_nolookup();
+       if (sym == IDENT)
+       {
+           if (lineptr == symname + 4 &&
+               ( strncmp(symname, "MEND", 4) == 0 || strncmp(symname, "mend", 4) == 0) )
+            {
+                getsym();
+               break;
+            }
+       }
+       else if (sym != MACROARG)
+       {
+           if (!savingc)
+               continue;       /* don't save comment */
+       }
+       if (!saving)
+           continue;
+       {
+           char * p = strchr(linebuf, EOLCHAR);
+           int len = (p-linebuf+1);
+
+           if ( macoff + len > maclen-4 )
+           {
+               maclen = maclen * 2 + len;
+               macbuf = asrealloc(macbuf, maclen);
+           }
+           memcpy(macbuf+macoff, linebuf, len);
+           macoff += len;
+
+       }
+    }
+    macload = FALSE;
+    if (saving)
+    {
+       macbuf[macoff] = ETB;
+        symptr->value_reg_or_op.value = (offset_t) macbuf;
+       symptr->data = 0;
+    }
+}
diff --git a/Applications/as09/macro.h b/Applications/as09/macro.h
new file mode 100644 (file)
index 0000000..c37bd00
--- /dev/null
@@ -0,0 +1,10 @@
+/* macro.h - global variables for macro expansion for assembler */
+
+EXTERN bool_t macflag;         /* inside macro flag */
+EXTERN bool_t macload;         /* loading macro flag */
+EXTERN unsigned macnum;                /* macro call counter */
+
+EXTERN unsigned char maclevel; /* nesting level */
+EXTERN struct schain_s *macpar;        /* parameter save buffer */
+EXTERN struct schain_s *macptop;       /* top of param buffer (+1) */
+EXTERN struct macro_s *macstak;        /* stack ptr */
diff --git a/Applications/as09/mops.c b/Applications/as09/mops.c
new file mode 100644 (file)
index 0000000..73c3a4f
--- /dev/null
@@ -0,0 +1,2945 @@
+/* mops.c - handle pseudo-ops */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "globvar.h"
+#include "opcode.h"
+#include "scan.h"
+#undef EXTERN
+#define EXTERN
+#include "address.h"
+
+#define is8bitadr(offset) ((offset_t) offset < 0x100)
+#define is8bitsignedoffset(offset) ((offset_t) (offset) + 0x80 < 0x100)
+#define pass2 (pass==last_pass)
+
+static void mshort2 P((void));
+static reg_pt regchk P((void));
+static void reldata P((void));
+static void segadj P((void));
+
+#ifdef I80386
+
+#define iswordadr(offset) ((offset_t) (offset) < 0x10000L)
+#define iswordoffset(offset) ((offset_t) (offset) + 0x8000L < 0x10000L)
+#define iswordorswordoffset(offset) ((offset_t) (offset) + 0xFFFFL < 0x1FFFEL)
+
+#define BYTE_SEGWORD        0x00
+#define isspecreg(r) ((r) >= CR0REG && (r) <= TR7REG)
+
+#define BASE_MASK   0x07
+#define BASE_SHIFT     0
+#define INDEX_MASK  0x38
+#define INDEX_SHIFT    3
+#define MOD_MASK    0xC0
+# define REG_MOD    0xC0
+# define MEM0_MOD   0x00
+# define MEM1_MOD   0x40
+# define MEM2_MOD   0x80
+#define REG_MASK    0x38
+#define REG_SHIFT      3
+#define RM_MASK     0x07
+#define RM_SHIFT       0
+# define D16_RM     0x06
+# define D32_RM     0x05
+# define SIB_NOBASE 0x05
+# define SIB_RM     0x04
+#define SREG_MASK   0x38
+#define SREG_SHIFT     3
+#define SS_MASK     0xC0
+#define SS_SHIFT       6
+
+#define SEGMOV      0x04
+#define SIGNBIT     0x02
+#define TOREGBIT    0x02
+#define WORDBIT     0x01
+
+static opcode_t baseind16[] =
+{
+    0x00,                      /* BP + BP, illegal */
+    0x00,                      /* BX + BP, illegal */
+    0x03,                      /* DI + BP */
+    0x02,                      /* SI + BP */
+    0x00,                      /* BP + BX, illegal */
+    0x00,                      /* BX + BX, illegal */
+    0x01,                      /* DI + BX */
+    0x00,                      /* SI + BX */
+    0x03,                      /* BP + DI */
+    0x01,                      /* BX + DI */
+    0x00,                      /* DI + DI, illegal */
+    0x00,                      /* SI + DI, illegal */
+    0x02,                      /* BP + SI */
+    0x00,                      /* BX + SI */
+    0x00,                      /* DI + SI, illegal */
+    0x00,                      /* SI + SI, illegal */
+};
+
+static opcode_t regbits[] =
+{
+    0x05 << REG_SHIFT,         /* BP */
+    0x03 << REG_SHIFT,         /* BX */
+    0x07 << REG_SHIFT,         /* DI */
+    0x06 << REG_SHIFT,         /* SI */
+
+    0x00 << REG_SHIFT,         /* EAX */
+    0x05 << REG_SHIFT,         /* EBP */
+    0x03 << REG_SHIFT,         /* EBX */
+    0x01 << REG_SHIFT,         /* ECX */
+    0x07 << REG_SHIFT,         /* EDI */
+    0x02 << REG_SHIFT,         /* EDX */
+    0x06 << REG_SHIFT,         /* ESI */
+    0x04 << REG_SHIFT,         /* ESP */
+
+    0x00 << REG_SHIFT,         /* AX */
+    0x01 << REG_SHIFT,         /* CX */
+    0x02 << REG_SHIFT,         /* DX */
+    0x04 << REG_SHIFT,         /* SP */
+
+    0x04 << REG_SHIFT,         /* AH */
+    0x00 << REG_SHIFT,         /* AL */
+    0x07 << REG_SHIFT,         /* BH */
+    0x03 << REG_SHIFT,         /* BL */
+    0x05 << REG_SHIFT,         /* CH */
+    0x01 << REG_SHIFT,         /* CL */
+    0x06 << REG_SHIFT,         /* DH */
+    0x02 << REG_SHIFT,         /* DL */
+
+    0x01 << REG_SHIFT,         /* CS */
+    0x03 << REG_SHIFT,         /* DS */
+    0x00 << REG_SHIFT,         /* ES */
+    0x04 << REG_SHIFT,         /* FS */
+    0x05 << REG_SHIFT,         /* GS */
+    0x02 << REG_SHIFT,         /* SS */
+
+    0x00 << REG_SHIFT,         /* CR0 */
+    0x02 << REG_SHIFT,         /* CR2 */
+    0x03 << REG_SHIFT,         /* CR3 */
+
+    0x00 << REG_SHIFT,         /* DR0 */
+    0x01 << REG_SHIFT,         /* DR1 */
+    0x02 << REG_SHIFT,         /* DR2 */
+    0x03 << REG_SHIFT,         /* DR3 */
+    0x06 << REG_SHIFT,         /* DR6 */
+    0x07 << REG_SHIFT,         /* DR7 */
+
+    0x03 << REG_SHIFT,         /* TR3 */
+    0x04 << REG_SHIFT,         /* TR4 */
+    0x05 << REG_SHIFT,         /* TR5 */
+    0x06 << REG_SHIFT,         /* TR6 */
+    0x07 << REG_SHIFT,         /* TR7 */
+
+    0x00 << REG_SHIFT,         /* ST(0) */
+    0x01 << REG_SHIFT,         /* ST(1) */
+    0x02 << REG_SHIFT,         /* ST(2) */
+    0x03 << REG_SHIFT,         /* ST(3) */
+    0x04 << REG_SHIFT,         /* ST(4) */
+    0x05 << REG_SHIFT,         /* ST(5) */
+    0x06 << REG_SHIFT,         /* ST(6) */
+    0x07 << REG_SHIFT,         /* ST(7) */
+};
+
+static opsize_t regsize[] =
+{
+    2,                         /* BP */
+    2,                         /* BX */
+    2,                         /* DI */
+    2,                         /* SI */
+
+    4,                         /* EAX */
+    4,                         /* EBP */
+    4,                         /* EBX */
+    4,                         /* ECX */
+    4,                         /* EDI */
+    4,                         /* EDX */
+    4,                         /* ESI */
+    4,                         /* ESP */
+
+    2,                         /* AX */
+    2,                         /* CX */
+    2,                         /* DX */
+    2,                         /* SP */
+
+    1,                         /* AH */
+    1,                         /* AL */
+    1,                         /* BH */
+    1,                         /* BL */
+    1,                         /* CH */
+    1,                         /* CL */
+    1,                         /* DH */
+    1,                         /* DL */
+
+    2,                         /* CS */
+    2,                         /* DS */
+    2,                         /* ES */
+    2,                         /* FS */
+    2,                         /* GS */
+    2,                         /* SS */
+
+    4,                         /* CR0 */
+    4,                         /* CR2 */
+    4,                         /* CR3 */
+
+    4,                         /* DR0 */
+    4,                         /* DR1 */
+    4,                         /* DR2 */
+    4,                         /* DR3 */
+    4,                         /* DR6 */
+    4,                         /* DR7 */
+
+    4,                         /* TR3 */
+    4,                         /* TR4 */
+    4,                         /* TR5 */
+    4,                         /* TR6 */
+    4,                         /* TR7 */
+
+    10,                                /* ST(0) */
+    10,                                /* ST(1) */
+    10,                                /* ST(2) */
+    10,                                /* ST(3) */
+    10,                                /* ST(4) */
+    10,                                /* ST(5) */
+    10,                                /* ST(6) */
+    10,                                /* ST(7) */
+
+    0,                         /* NOREG */
+};
+
+static opcode_t regsegword[] =
+{
+    WORDBIT,                   /* BP */
+    WORDBIT,                   /* BX */
+    WORDBIT,                   /* DI */
+    WORDBIT,                   /* SI */
+
+    WORDBIT,                   /* EAX */
+    WORDBIT,                   /* EBP */
+    WORDBIT,                   /* EBX */
+    WORDBIT,                   /* ECX */
+    WORDBIT,                   /* EDI */
+    WORDBIT,                   /* EDX */
+    WORDBIT,                   /* ESI */
+    WORDBIT,                   /* ESP */
+
+    WORDBIT,                   /* AX */
+    WORDBIT,                   /* CX */
+    WORDBIT,                   /* DX */
+    WORDBIT,                   /* SP */
+
+    BYTE_SEGWORD,              /* AH */
+    BYTE_SEGWORD,              /* AL */
+    BYTE_SEGWORD,              /* BH */
+    BYTE_SEGWORD,              /* BL */
+    BYTE_SEGWORD,              /* CH */
+    BYTE_SEGWORD,              /* CL */
+    BYTE_SEGWORD,              /* DH */
+    BYTE_SEGWORD,              /* DL */
+
+    SEGMOV,                    /* CS */
+    SEGMOV,                    /* DS */
+    SEGMOV,                    /* ES */
+    SEGMOV,                    /* FS */
+    SEGMOV,                    /* GS */
+    SEGMOV,                    /* SS */
+
+    0x20,                      /* CR0 */
+    0x20,                      /* CR2 */
+    0x20,                      /* CR3 */
+
+    0x21,                      /* DR0 */
+    0x21,                      /* DR1 */
+    0x21,                      /* DR2 */
+    0x21,                      /* DR3 */
+    0x21,                      /* DR6 */
+    0x21,                      /* DR7 */
+
+    0x24,                      /* TR3 */
+    0x24,                      /* TR4 */
+    0x24,                      /* TR5 */
+    0x24,                      /* TR6 */
+    0x24,                      /* TR7 */
+
+    0x00,                      /* ST(0) */
+    0x00,                      /* ST(1) */
+    0x00,                      /* ST(2) */
+    0x00,                      /* ST(3) */
+    0x00,                      /* ST(4) */
+    0x00,                      /* ST(5) */
+    0x00,                      /* ST(6) */
+    0x00,                      /* ST(7) */
+
+    0x00,                      /* NOREG */
+};
+
+static opcode_t rm[] =
+{
+    0x05,                      /* BP */
+    0x03,                      /* BX */
+    0x07,                      /* DI */
+    0x06,                      /* SI */
+
+    0x00,                      /* EAX */
+    0x05,                      /* EBP */
+    0x03,                      /* EBX */
+    0x01,                      /* ECX */
+    0x07,                      /* EDI */
+    0x02,                      /* EDX */
+    0x06,                      /* ESI */
+    0x04,                      /* ESP */
+
+    0x00,                      /* AX */
+    0x01,                      /* CX */
+    0x02,                      /* DX */
+    0x04,                      /* SP */
+
+    0x04,                      /* AH */
+    0x00,                      /* AL */
+    0x07,                      /* BH */
+    0x03,                      /* BL */
+    0x05,                      /* CH */
+    0x01,                      /* CL */
+    0x06,                      /* DH */
+    0x02,                      /* DL */
+
+    0x01,                      /* CS */
+    0x03,                      /* DS */
+    0x00,                      /* ES */
+    0x04,                      /* FS */
+    0x05,                      /* GS */
+    0x02,                      /* SS */
+
+    0x00,                      /* CR0 */
+    0x00,                      /* CR2 */
+    0x00,                      /* CR3 */
+
+    0x00,                      /* DR0 */
+    0x00,                      /* DR1 */
+    0x00,                      /* DR2 */
+    0x00,                      /* DR3 */
+    0x00,                      /* DR6 */
+    0x00,                      /* DR7 */
+
+    0x00,                      /* TR3 */
+    0x00,                      /* TR4 */
+    0x00,                      /* TR5 */
+    0x00,                      /* TR6 */
+    0x00,                      /* TR7 */
+
+    0x00,                      /* ST(0) */
+    0x00,                      /* ST(1) */
+    0x00,                      /* ST(2) */
+    0x00,                      /* ST(3) */
+    0x00,                      /* ST(4) */
+    0x00,                      /* ST(5) */
+    0x00,                      /* ST(6) */
+    0x00,                      /* ST(7) */
+
+    0x04,                      /* null index reg for sib only */
+};
+
+static opcode_t rmfunny[] =
+{
+    0x06,                      /* BP */
+    0x07,                      /* BX */
+    0x05,                      /* DI */
+    0x04,                      /* SI */
+};
+
+static opcode_t segoverride[] =
+{
+    0x2E,                      /* CS */
+    0x3E,                      /* DS */
+    0x26,                      /* ES */
+    0x64,                      /* FS */
+    0x65,                      /* GS */
+    0x36,                      /* SS */
+};
+
+static opcode_t ss[] =         /* scale to ss bits */
+{
+    0x00,                      /* x0, illegal */
+    0x00 << SS_SHIFT,          /* x1 */
+    0x01 << SS_SHIFT,          /* x2 */
+    0x00,                      /* x3, illegal */
+    0x02 << SS_SHIFT,          /* x4 */
+    0x00,                      /* x5, illegal */
+    0x00,                      /* x6, illegal */
+    0x00,                      /* x7, illegal */
+    0x03 << SS_SHIFT,          /* x8 */
+};
+
+static unsigned char calljmp_kludge;
+static opcode_t direction;
+static bool_t fpreg_allowed;
+static opcode_t segword;
+/*
+  Values of segword:
+    BYTE_SEGWORD for byte ea's.
+    SEGMOV for segment registers
+    opcode for special registers
+    WORDBIT for other word and dword ea's
+*/
+
+static struct ea_s source;
+static struct ea_s source2;
+static struct ea_s target;
+
+static void Eb(struct ea_s *eap);
+static void Ew(struct ea_s *eap);
+static void Ev(struct ea_s *eap);
+static void Ex(struct ea_s *eap);
+static void Gd(struct ea_s *eap);
+static void Gw(struct ea_s *eap);
+static void Gv(struct ea_s *eap);
+static void Gx(struct ea_s *eap);
+static void buildea(struct ea_s *eap);
+static void buildfloat(void);
+static void buildfreg(void);
+static void buildimm(struct ea_s *eap, bool_pt signflag);
+static void buildregular(void);
+static void buildsegword(struct ea_s *eap);
+static void buildunary(opcode_pt opc);
+static opsize_pt displsize(struct ea_s *eap);
+static reg_pt fpregchk(void);
+static bool_pt getaccumreg(struct ea_s *eap);
+static void getbinary(void);
+static bool_pt getdxreg(struct ea_s *eap);
+static void getea(struct ea_s *eap);
+static void getimmed(struct ea_s *eap, count_t immed_count);
+static void getindirect(struct ea_s *eap);
+static void getshift(struct ea_s *eap);
+static reg_pt indregchk(reg_pt matchreg);
+static void kgerror(char * err_str);
+static void lbranch(int backamount);
+static void notbytesize(struct ea_s *eap);
+static void notimmed(struct ea_s *eap);
+static void notindirect(struct ea_s *eap);
+static void notsegorspecreg(struct ea_s *eap);
+static void yesimmed(struct ea_s *eap);
+static void yes_samesize(void);
+
+static void Eb(eap)
+register struct ea_s *eap;
+{
+    Ex(eap);
+    if (eap->size != 0x1)
+    {
+#ifndef NODEFAULTSIZE
+       if (eap->size == 0x0)
+           eap->size = 0x1;
+       else
+#endif
+           kgerror(ILL_SIZE);
+    }
+}
+
+static void Ew(eap)
+register struct ea_s *eap;
+{
+    Ex(eap);
+    if (eap->size != 0x2)
+    {
+#ifndef NODEFAULTSIZE
+       if (eap->size == 0x0)
+           eap->size = 0x2;
+       else
+#endif
+           kgerror(ILL_SIZE);
+    }
+}
+
+static void Ev(eap)
+register struct ea_s *eap;
+{
+    Ex(eap);
+    notbytesize(eap);
+}
+
+static void Ex(eap)
+register struct ea_s *eap;
+{
+    getea(eap);
+    notimmed(eap);
+    notsegorspecreg(eap);
+}
+
+static void Gd(eap)
+register struct ea_s *eap;
+{
+    Gx(eap);
+    if (eap->size != 0x4)
+       kgerror(ILL_SIZE);
+}
+
+static void Gw(eap)
+register struct ea_s *eap;
+{
+    Gx(eap);
+    if (eap->size != 0x2)
+       kgerror(ILL_SIZE);
+}
+
+static void Gv(eap)
+register struct ea_s *eap;
+{
+    Gx(eap);
+    notbytesize(eap);
+}
+
+static void Gx(eap)
+register struct ea_s *eap;
+{
+    Ex(eap);
+    notindirect(eap);
+}
+
+static void buildea(eap)
+register struct ea_s *eap;
+{
+    opsize_t asize;
+
+    ++mcount;
+    lastexp = eap->displ;
+    if (eap->indcount == 0x0)
+       postb = REG_MOD | rm[eap->base];
+    else
+    {
+       if (eap->base == NOREG)
+       {
+           if (eap->index == NOREG)
+           {
+               if ((asize = displsize(eap)) > 0x2)
+                   postb = D32_RM;
+               else
+                   postb = D16_RM;
+           }
+           else
+           {
+               asize = 0x4;
+               postb = SIB_NOBASE;     /* for sib later */
+           }
+       }
+       else
+       {
+           if (eap->base > MAX16BITINDREG)
+           {
+               asize = 0x4;
+               postb = rm[eap->base];
+           }
+           else
+           {
+               asize = 0x2;
+               if (!(lastexp.data & UNDBIT) &&
+                   !iswordorswordoffset(lastexp.offset))
+                   error(ABOUNDS);
+               if (eap->index == NOREG)
+                   postb = rmfunny[eap->base];
+               else if (eap->base <= MAX16BITINDREG)
+                   postb = baseind16[eap->base + 0x4 * eap->index];
+           }
+       }
+       needcpu(asize==4?3:0);
+       if (asize != defsize)
+           aprefix = 0x67;
+       if (eap->base == NOREG)
+           mcount += asize;
+       else if (lastexp.data & (FORBIT | RELBIT | UNDBIT) ||
+                !is8bitsignedoffset(lastexp.offset))
+       {
+           postb |= MEM2_MOD;
+           mcount += asize;
+       }
+       else if (lastexp.offset != 0x0 ||
+                (eap->base == BPREG && eap->index == NOREG) ||
+                eap->base == EBPREG)
+       {
+           postb |= MEM1_MOD;
+           ++mcount;
+       }
+       if (asize > 0x2 && (eap->base == ESPREG || eap->index != NOREG))
+       {
+           sib = ss[eap->scale] |
+               (rm[eap->index] << INDEX_SHIFT) |
+               (postb & RM_MASK);
+           postb = (postb & MOD_MASK) | SIB_RM;
+           ++mcount;
+       }
+    }
+}
+
+static void buildfloat(void)
+{
+    if (mcount != 0x0)
+    {
+       buildea(&source);
+       oprefix = 0x0;
+       postb |= (opcode & 0x07) << REG_SHIFT;
+       opcode = ESCAPE_OPCODE_BASE | ((opcode & 0x70) >> 0x4);
+    }
+}
+
+static void buildfreg(void)
+{
+    mcount += 0x2;
+    oprefix = 0x0;
+    postb = REG_MOD | ((opcode & 0x07) << REG_SHIFT) | (target.base - ST0REG);
+    opcode = ESCAPE_OPCODE_BASE | ((opcode & 0x70) >> 0x4);
+}
+
+static void buildimm(eap, signflag)
+register struct ea_s *eap;
+bool_pt signflag;
+{
+    immadr = eap->displ;
+    immcount = eap->size;
+    if (!(immadr.data & (FORBIT | RELBIT | UNDBIT)))
+    {
+       if (immcount == 0x1)
+       {
+           if ((offset_t) (immadr.offset + 0x80) >= 0x180)
+               datatoobig();
+       }
+       else if (signflag && is8bitsignedoffset(immadr.offset))
+       {
+           opcode |= SIGNBIT;
+           immcount = 0x1;
+       }
+       else if (immcount == 0x2)
+       {
+           if ((offset_t) (immadr.offset + 0x8000L) >= 0x18000L)
+               datatoobig();
+       }
+    }
+}
+
+static void buildregular(void)
+{
+    if (mcount != 0x0)
+    {
+       buildea(&target);
+       postb |= regbits[source.base];
+    }
+}
+
+/* Check size and build segword. */
+
+static void buildsegword(eap)
+register struct ea_s *eap;
+{
+    if (eap->size == 0x0)
+#ifdef NODEFAULTSIZE
+       kgerror(SIZE_UNK);
+#else
+       eap->size = defsize;
+#endif
+    if (eap->indcount != 0x0 || eap->base == NOREG)
+    {
+       segword = WORDBIT;
+       if (eap->size == 0x1)
+           segword = BYTE_SEGWORD;
+    }
+    else
+       segword = regsegword[eap->base];
+}
+
+static void buildunary(opc)
+opcode_pt opc;
+{
+    if (mcount != 0x0)
+    {
+       buildea(&target);
+       postb |= opcode;
+       opcode = opc;
+    }
+}
+
+static opsize_pt displsize(eap)
+register struct ea_s *eap;
+{
+    opsize_t asize;
+
+    asize = defsize;
+    if (!(eap->displ.data & UNDBIT))
+    {
+       if (asize > 0x2)
+       {
+           if (!(eap->displ.data & (FORBIT | RELBIT)) &&
+               iswordadr(eap->displ.offset))
+               asize = 0x2;
+       }
+       else if (!iswordorswordoffset(eap->displ.offset))
+                               /* should really use iswordadr() */
+                               /* but compiler generates signed offsets */
+       {
+           if (!(eap->displ.data & (FORBIT | RELBIT)))
+               asize = 0x4;
+           else if (pass2)
+               error(ABOUNDS);
+       }
+    }
+    return asize;
+}
+
+static reg_pt fpregchk(void)
+{
+    reg_pt fpreg;
+
+    fpreg_allowed = TRUE;
+    fpreg = regchk();
+    fpreg_allowed = FALSE;
+    if (fpreg != ST0REG)
+       return NOREG;
+    getsym();
+    if (sym == LPAREN)
+    {
+       getsym();
+       if (sym != INTCONST || (unsigned) number >= 0x8)
+           error(ILL_FP_REG);
+       else
+       {
+           fpreg += number;
+           getsym();
+           if (sym != RPAREN)
+               error(RPEXP);
+           else
+               getsym();
+       }
+    }
+    return fpreg;
+}
+
+static bool_pt getaccumreg(eap)
+register struct ea_s *eap;
+{
+    if ((eap->base = regchk()) != AXREG && eap->base != ALREG
+       && eap->base != EAXREG)
+       return FALSE;
+    getsym();
+    if ((eap->size = regsize[eap->base]) > 0x1 && eap->size != defsize)
+       oprefix = 0x66;
+    return TRUE;
+}
+
+/*
+  Get binary ea's in target & source (flipped if direction is set).
+  Put size in source if not already.
+  Initialise direction, segword, bump mcount.
+*/
+
+static void getbinary(void)
+{
+    ++mcount;
+    getea(&target);
+    if (target.indcount == 0x0 && target.base == NOREG)
+    {
+       error(ILL_IMM_MODE);
+       target.base = AXREG;
+       target.size = defsize;
+    }
+    getcomma();
+    getea(&source);
+    if (source.size == 0x0)
+       source.size = target.size;
+    else if (target.size != 0x0 && target.size != source.size)
+    {
+       kgerror(MISMATCHED_SIZE);
+       return;
+    }
+    if (source.indcount == 0x0 && regsegword[target.base] < SEGMOV)
+       direction = 0x0;
+    else if (target.indcount == 0x0 && regsegword[source.base] < SEGMOV)
+    {
+       struct ea_s swap;
+
+       direction = TOREGBIT;
+       swap = source;
+       source = target;
+       target = swap;
+    }
+    else if (target.indcount != 0x0)
+    {
+       kgerror(ILL_IND_TO_IND);
+       return;
+    }
+    else
+    {
+       kgerror(ILL_SEG_REG);
+       return;
+    }
+    buildsegword(&source);
+}
+
+static bool_pt getdxreg(eap)
+register struct ea_s *eap;
+{
+    if ((eap->base = regchk()) != DXREG)
+       return FALSE;
+    getsym();
+    return TRUE;
+}
+
+/* parse effective address */
+
+/*
+  Syntax is restrictive in that displacements must be in the right spots
+  and will not be added up.
+
+  optional size-type prefix, which is
+    BYTE
+    BYTE PTR
+    WORD
+    WORD PTR
+    DWORD
+    DWORD PTR
+    PTR
+  reg
+  segreg
+  [scaled index]
+  where scaled index =
+    indreg
+    indreg*scale
+    indreg+indreg
+    indreg+indreg*scale
+  [scaled index+displ]
+  [scaled index-displ]
+  optional-immediate-prefix displ[scaled index]
+  [displ]
+  optional-imediate-prefix displ
+  (scaled index)                                   -- anachronism
+  optional-imediate-prefix displ(scaled index)     -- anachronism
+*/
+
+static void getea(eap)
+register struct ea_s *eap;
+{
+    bool_t leading_displ;
+    bool_t leading_immed;
+    register struct sym_s *symptr;
+
+    leading_immed = leading_displ = lastexp.data = eap->indcount
+                 = lastexp.offset = 0x0;
+    eap->index = eap->base = NOREG;
+    eap->scale = 0x1;
+    eap->size = mnsize;                /* 0x1 for byte ops, else 0x0 */
+
+    if (sym == IDENT)
+    {
+       if ((symptr = gsymptr)->type & MNREGBIT)
+       {
+           if (symptr->data & SIZEBIT)
+           {
+               getsym();
+               if (symptr->value_reg_or_op.op.opcode == 0x0)
+                   eap->indcount = 0x2 - calljmp_kludge;
+               else
+               {
+                   if (eap->size != 0x0)
+                   {
+                       if (eap->size != symptr->value_reg_or_op.op.opcode)
+                           error(MISMATCHED_SIZE);
+                   }
+                   else
+                       eap->size = symptr->value_reg_or_op.op.opcode;
+                   if (eap->size > 0x1 && eap->size != defsize)
+                       oprefix = 0x66;
+                   if (sym == IDENT &&
+                       (symptr = gsymptr)->type & MNREGBIT &&
+                       symptr->data & SIZEBIT &&
+                       symptr->value_reg_or_op.op.routine == PTROP)
+                   {
+                       getsym();
+                       eap->indcount = 0x2 - calljmp_kludge;
+                   }
+               }
+           }
+       }
+       if( last_pass == 1 )
+           if (!(symptr->type & (LABIT | MACBIT | MNREGBIT | VARBIT)))
+               symptr->data |= FORBIT; /* show seen in advance */
+    }
+    if ((eap->base = regchk()) != NOREG)
+    {
+       getsym();
+       if (eap->indcount != 0x0)
+       {
+           error(ILL_IND_PTR);
+           eap->indcount = 0x0;
+       }
+       if (eap->size != 0x0 && eap->size != regsize[eap->base])
+           error(MISMATCHED_SIZE);
+       if ((eap->size = regsize[eap->base]) > 0x1 && eap->size != defsize)
+           oprefix = 0x66;
+       eap->displ = lastexp;
+        needcpu(eap->size==4?3:0);
+       return;
+    }
+    if (sym != lindirect)
+    {
+       if (sym == IMMEDIATE || sym == STAR)
+       {
+           /* context-sensitive, STAR means signed immediate here */
+           leading_immed = TRUE;
+           getsym();
+       }
+       leading_displ = TRUE;
+       expres();
+       eap->displ = lastexp;
+    }
+    if (sym == lindirect)
+    {
+       getsym();
+       eap->indcount = 0x2 - calljmp_kludge;
+       if ((eap->base = indregchk((reg_pt) NOREG)) != NOREG)
+       {
+           if (eap->indcount == 0x0 && leading_displ)
+               error(IND_REQ);
+           getsym();
+           if (sym == ADDOP)
+           {
+               getsym();
+               if ((eap->index = indregchk(eap->base)) != NOREG)
+                   getsym();
+               else
+               {
+                   if (eap->indcount == 0x0)
+                       error(IND_REQ);
+                   if (leading_displ)
+                       error(REPEATED_DISPL);
+                   expres();   /* this eats ADDOP, SUBOP, MULOP */
+               }
+           }
+           if (sym == STAR)
+           {
+                needcpu(3);
+               /* context-sensitive, STAR means scaled here*/
+               if (eap->index == NOREG && eap->base == ESPREG)
+               {
+                   error(INDEX_REG_EXP);
+                   eap->base = EAXREG;
+               }
+               getsym();
+               factor();
+               chkabs();
+               if (!(lastexp.data & UNDBIT) && lastexp.offset != 0x1)
+               {
+                   if (eap->base <= MAX16BITINDREG ||
+                       (lastexp.offset != 0x2 && lastexp.offset != 0x4 &&
+                       lastexp.offset != 0x8))
+                       error(ILL_SCALE);
+                   else
+                   {
+                       eap->scale = lastexp.offset;
+                       if (eap->index == NOREG)
+                       {
+                           eap->index = eap->base;
+                           eap->base = NOREG;
+                       }
+                   }
+               }
+               lastexp.data = lastexp.offset = 0x0;
+           }
+           if ((sym == ADDOP || sym == SUBOP))
+           {
+               if (eap->indcount == 0x0)
+                   error(IND_REQ);
+               if (leading_displ)
+                   error(REPEATED_DISPL);
+               expres();
+           }
+       }
+       else
+       {
+           if (leading_displ)
+               error(REPEATED_DISPL);
+           expres();
+       }
+       if (sym != rindirect)
+           error(rindexp);
+       else
+           getsym();
+    }
+    /* RDB */
+    else if (!leading_immed && defsize <= 0x2)
+       eap->indcount = 0x1;    /* compatibility kludge */
+    if (!leading_displ)
+       eap->displ = lastexp;
+
+    needcpu(eap->size==4?3:0);
+}
+
+static void getimmed(eap, immed_count)
+struct ea_s *eap; 
+count_t immed_count;
+{
+    getea(eap);
+    yesimmed(eap);
+    if (mcount != 0x0)
+    {
+       eap->size = immed_count;
+       buildimm(eap, FALSE);
+    }
+}
+
+static void getindirect(eap)
+register struct ea_s *eap;
+{
+    getea(eap);
+    if (eap->indcount == 0x0)
+       kgerror(IND_REQ);
+}
+
+static void getshift(eap)
+register struct ea_s *eap;
+{
+    getcomma();
+    getea(eap);
+    if (eap->base != CLREG)
+       yesimmed(eap);
+}
+
+/*
+  Check if current symbol is a compatible index register.
+  Generate error if it is a reg but not a compatible index.
+  Return register number (adjusted if necessary to a legal index) or NOREG.
+*/
+
+static reg_pt indregchk(matchreg)
+reg_pt matchreg;
+{
+    reg_pt reg;
+
+    if ((reg = regchk()) != NOREG)
+    {
+       switch (matchreg)
+       {
+       case BPREG:
+       case BXREG:
+           if (reg != DIREG && reg != SIREG)
+           {
+               reg = SIREG;
+               error(INDEX_REG_EXP);
+           }
+           break;
+       case DIREG:
+       case SIREG:
+           if (reg != BPREG && reg != BXREG)
+           {
+               reg = BXREG;
+               error(INDEX_REG_EXP);
+           }
+           break;
+       case NOREG:
+           break;
+       default:
+           if (reg <= MAX16BITINDREG || reg == ESPREG)
+           {
+               reg = EAXREG;
+               error(INDEX_REG_EXP);
+           }
+           break;
+       }
+       if (reg > MAXINDREG && calljmp_kludge == 0x0)
+       {
+           if (matchreg != NOREG)
+               reg = EAXREG;
+           else
+               reg = BXREG;
+           error(INDEX_REG_EXP);
+       }
+    }
+    return reg;
+}
+
+static void kgerror(err_str)
+char * err_str;
+{
+    error(err_str);
+    sprefix = oprefix = aprefix = mcount = 0x0;
+}
+
+static void lbranch(backamount)
+int backamount;
+{
+    mcount += defsize + 0x1;
+    segadj();
+    if (pass2)
+    {
+       reldata();
+       if (!(lastexp.data & (RELBIT | UNDBIT)))
+       {
+           lastexp.offset = lastexp.offset - lc - lcjump;
+           if ( last_pass<2 && backamount != 0x0 && 
+               !(lastexp.data & IMPBIT) &&
+               lastexp.offset + backamount < 0x80 + backamount)
+               warning(SHORTB);        /* -0x8? to 0x7F, warning */
+       }
+    }
+}
+
+/* BCC (long branches emulated by short branch over & long jump) */
+
+void mbcc(void)
+{
+    getea(&target);
+    if (target.indcount >= 0x2 || target.base != NOREG)
+       kgerror(REL_REQ);
+    else
+    {
+#ifdef iscpu
+       if (iscpu(3))
+#else
+       if (defsize != 0x2)
+#endif
+       {
+           page = PAGE1_OPCODE;
+           ++mcount;
+           opcode += 0x10;
+           lbranch(0x84);
+       }
+       else
+       {
+           aprefix = opcode ^ 0x1;     /* kludged storage for short branch
+                                          over */
+           oprefix = defsize + 0x1;
+           mcount += 0x2;
+           opcode = JMP_OPCODE;
+           lbranch(0x83);
+           mcount -= 0x2;
+       }
+    }
+}
+
+/* bswap r32 */
+
+void mbswap(void)
+{
+    needcpu(4);
+    ++mcount;
+    Gd(&target);
+    opcode |= rm[target.base];
+}
+
+/* BR, CALL, J, JMP */
+
+void mcall(void)
+{
+    opcode_pt far_diff;
+    bool_t indirect;
+    register struct sym_s *symptr;
+
+    far_diff = 0x0;
+    if (sym == IDENT && (symptr = gsymptr)->type & MNREGBIT &&
+       symptr->data & SIZEBIT )
+    {
+        if(symptr->value_reg_or_op.op.routine == FAROP)
+        {
+           far_diff = 0x8;
+           getsym();
+        }
+        if(symptr->value_reg_or_op.op.routine == WORDOP &&
+          opcode == JMP_SHORT_OPCODE)
+        {
+          opcode = JMP_OPCODE;
+          getsym();
+       }
+    }
+    indirect = FALSE;
+
+    if (asld_compatible && defsize <= 0x2)
+    {
+       calljmp_kludge = 0x2;
+       if (sym == INDIRECT)
+       {
+           calljmp_kludge = 0x0;
+           indirect = TRUE;
+           getsym();
+       }
+    }
+    getea(&target);
+    if (indirect && target.indcount == 0x1)
+       target.indcount = 0x2;
+    calljmp_kludge = 0x0;
+    if (sym == COLON)
+    {
+        int tsize = target.size?target.size:defsize;
+       if (opcode == JMP_SHORT_OPCODE)
+           opcode = JMP_OPCODE;
+       ++mcount;
+       yesimmed(&target);
+       getsym();
+       getea(&source);
+       yesimmed(&source);
+       if (mcount != 0x0)
+       {
+           if (opcode == JMP_OPCODE)
+               opcode = 0xEA;
+           else
+               opcode = 0x9A;
+           lastexp = source.displ;
+           if (!(lastexp.data & (FORBIT | RELBIT | UNDBIT)) &&
+               tsize == 0x2 &&
+               (offset_t) (lastexp.offset + 0x8000L) >= 0x18000L)
+               datatoobig();
+           mcount += tsize;
+           target.size = 0x2;
+           buildimm(&target, FALSE);
+       }
+    }
+    else if (target.indcount >= 0x2 || target.base != NOREG)
+    {
+       ++mcount;
+       notsegorspecreg(&target);
+       if (target.indcount == 0)
+           notbytesize(&target);
+       if (mcount != 0x0)
+       {
+           if (opcode == JMP_SHORT_OPCODE)
+               opcode = JMP_OPCODE;
+           buildea(&target);
+           if (opcode == JMP_OPCODE)
+               opcode = 0x20;
+           else
+               opcode = 0x10;
+           postb |= opcode + far_diff;
+           opcode = 0xFF;
+       }
+    }
+    else if (opcode == JMP_SHORT_OPCODE)
+    {
+       if (jumps_long &&
+           ((pass!=0 && !is8bitsignedoffset(lastexp.offset - lc - 2)) ||
+            (last_pass==1)))
+       {
+           opcode = JMP_OPCODE;
+           lbranch(0x83);
+       }
+       else
+       {
+           lastexp = target.displ;
+           if (lastexp.data & IMPBIT)
+           {
+               error(NONIMPREQ);
+               lastexp.data = FORBIT | UNDBIT;
+           }
+           mshort2();
+       }
+    }
+    else
+       lbranch(opcode == JMP_OPCODE ? 0x83 : 0x0);
+}
+
+/* CALLI, JMPI */
+
+void mcalli(void)
+{
+    bool_t indirect;
+
+    ++mcount;
+    indirect = FALSE;
+    if (sym == INDIRECT)
+    {
+       getsym();
+       indirect = TRUE;
+    }
+    getea(&target);
+    if (target.indcount >= 0x2 || target.base != NOREG)
+       indirect = TRUE;
+    if (indirect)
+    {
+       buildea(&target);
+       if (opcode == 0xEA)
+           opcode = 0x28;
+       else
+           opcode = 0x18;
+       postb |= opcode;
+       opcode = 0xFF;
+    }
+    else
+    {
+        int tsize = target.size?target.size:defsize;
+       getcomma();
+       getea(&source);
+       yesimmed(&source);
+       if (mcount != 0x0)
+       {
+           lastexp = target.displ;
+           if (!(lastexp.data & (FORBIT | RELBIT | UNDBIT)) &&
+               tsize == 0x2 &&
+               (offset_t) (lastexp.offset + 0x8000L) >= 0x18000L)
+            {
+               tsize=4;
+               if( tsize != defsize ) oprefix = 0x66;
+               /* datatoobig(); */
+           }
+           needcpu(tsize==4?3:0);
+           mcount += tsize;
+           source.size = 0x2;
+           buildimm(&source, FALSE);
+       }
+    }
+}
+
+/* DIV, IDIV, MUL */
+
+void mdivmul(void)
+{
+    if (getaccumreg(&source))
+    {
+       ++mcount;
+       getcomma();
+       Ex(&target);
+       yes_samesize();
+       buildunary(0xF6 | regsegword[source.base]);
+    }
+    else
+       mnegnot();
+}
+
+/* ENTER */
+
+void menter(void)
+{
+    ++mcount;
+    getimmed(&target, 0x2);
+    getcomma();
+    getimmed(&source, 0x1);
+    if (mcount != 0x0)
+    {
+       mcount += 2;
+       lastexp = target.displ; /* getimmed(&source) wiped it out */
+    }
+    needcpu(1);
+}
+
+/* arpl r/m16,r16 (Intel manual opcode chart wrongly says EwRw) */
+
+void mEwGw(void)
+{
+    ++mcount;
+    Ew(&target);
+    getcomma();
+    Gw(&source);
+    oprefix = 0x0;
+    buildregular();
+}
+
+/* [cmpxchg xadd] [r/m8,r8 r/m16,r16, r/m32,r32] */
+
+void mExGx(void)
+{
+    ++mcount;
+    Ex(&target);
+    getcomma();
+    Gx(&source);
+    yes_samesize();
+    opcode |= segword;
+    buildregular();
+}
+
+void mf_inher(void)
+{
+    mcount += 0x2;
+    postb = REG_MOD | (opcode & ~REG_MOD);
+    opcode = ESCAPE_OPCODE_BASE | (opcode >> 0x6);
+    if (opcode == ESCAPE_OPCODE_BASE)
+       opcode = ESCAPE_OPCODE_BASE | 0x6;      /* fix up encoding of fcompp */
+}
+
+/* [fldenv fnsave fnstenv frstor] mem */
+
+void mf_m(void)
+{
+    ++mcount;
+    getindirect(&source);
+    if (source.size != 0x0)
+       kgerror(ILL_SIZE);
+    buildfloat();
+}
+
+/* [fldcw fnstcw] mem2i */
+
+void mf_m2(void)
+{
+    ++mcount;
+    getindirect(&source);
+    if (source.size != 0x0 && source.size != 0x2)
+       kgerror(ILL_SIZE);
+    buildfloat();
+}
+
+/* fnstsw [mem2i ax] */
+
+void mf_m2_ax(void)
+{
+    if (getaccumreg(&target))
+    {
+       if (target.base != AXREG)
+           kgerror(ILLREG);
+       else
+       {
+           opcode = 0x74;
+           target.base = ST0REG;       /* fake, really ax */
+           buildfreg();
+       }
+    }
+    else
+       mf_m2();
+}
+
+/* [fiadd ficom ficomp fidiv fidivr fimul fist fisub fisubr] [mem2i mem4i] */
+
+void mf_m2_m4(void)
+{
+    ++mcount;
+    getindirect(&source);
+    if (source.size == 0x0)
+       kgerror(SIZE_UNK);
+    else if (source.size == 0x2)
+       opcode |= 0x40;
+    else if (source.size != 0x4)
+       kgerror(ILL_SIZE);
+    buildfloat();
+}
+
+/* [fild fistp] [mem2i mem4i mem8i] */
+
+void mf_m2_m4_m8(void)
+{
+    ++mcount;
+    getindirect(&source);
+    if (source.size == 0x0)
+       kgerror(SIZE_UNK);
+    else if (source.size == 0x2)
+       opcode |= 0x40;
+    else if (source.size == 0x8)
+       opcode |= 0x45;         /* low bits 0 -> 5 and 3 -> 7 */
+    else if (source.size != 0x4)
+       kgerror(ILL_SIZE);
+    buildfloat();
+}
+
+/* [fcom fcomp] [mem4r mem8r optional-st(i)] */
+
+void mf_m4_m8_optst(void)
+{
+    if (sym == EOLSYM)
+    {
+       target.base = ST1REG;
+       buildfreg();
+    }
+    else
+       mf_m4_m8_st();
+}
+
+/* [fadd fdiv fdivr fmul fsub fsubr] [mem4r mem8r st,st(i) st(i),st] */
+
+void mf_m4_m8_stst(void)
+{
+    target.base = fpregchk();
+    if (target.base != NOREG)
+    {
+       getcomma();
+       source.base = fpregchk();
+       if (source.base == NOREG)
+       {
+           error(FP_REG_REQ);
+           source.base = ST0REG;
+       }
+       if (target.base == ST0REG)
+           target.base = source.base;
+       else
+       {
+           if (source.base != ST0REG)
+               error(ILL_FP_REG_PAIR);
+           opcode |= 0x40;
+           if ((opcode & 0x07) >= 0x4)
+               opcode ^= 0x01; /* weird swap of fdiv/fdivr, fsub/fsubr */
+       }
+       buildfreg();
+    }
+    else
+    {
+       ++mcount;
+       getindirect(&source);
+       if (source.size == 0x0)
+           kgerror(SIZE_UNK);
+       else if (source.size == 0x8)
+           opcode |= 0x40;
+       else if (source.size != 0x4)
+           kgerror(ILL_SIZE);
+       buildfloat();
+    }
+}
+
+/* fst [mem4r mem8r st(i)] */
+
+void mf_m4_m8_st(void)
+{
+    target.base = fpregchk();
+    if (target.base != NOREG)
+    {
+       if (opcode == FST_ENCODED)
+           opcode |= 0x40;
+       buildfreg();
+    }
+    else
+    {
+       ++mcount;
+       getindirect(&source);
+       if (source.size == 0x0)
+           kgerror(SIZE_UNK);
+       else if (source.size == 0x8)
+           opcode |= 0x40;
+       else if (source.size != 0x4)
+           kgerror(ILL_SIZE);
+       buildfloat();
+    }
+}
+
+/* [fld fstp] [mem4r mem8r mem10r st(i)] */
+
+void mf_m4_m8_m10_st(void)
+{
+    target.base = fpregchk();
+    if (target.base != NOREG)
+    {
+       if (opcode == FSTP_ENCODED)
+           opcode |= 0x40;
+       buildfreg();
+    }
+    else
+    {
+       ++mcount;
+       getindirect(&source);
+       if (source.size == 0x0)
+           kgerror(SIZE_UNK);
+       else if (source.size == 0x8)
+           opcode |= 0x40;
+       else if (source.size == 0xA)
+           opcode |= 0x25;     /* low bits 0 -> 5 and 3 -> 7 */
+       else if (source.size != 0x4)
+           kgerror(ILL_SIZE);
+       buildfloat();
+    }
+}
+
+/* [fbld fbstp] mem10r */
+
+void mf_m10(void)
+{
+    ++mcount;
+    getindirect(&source);
+    if (source.size != 0xA)
+       kgerror(ILL_SIZE);
+    buildfloat();
+}
+
+/* ffree st(i) */
+
+void mf_st(void)
+{
+    target.base = fpregchk();
+    if (target.base == NOREG)
+       kgerror(FP_REG_REQ);
+    buildfreg();
+}
+
+/* [fucom fucomp fxch] optional-st(i) */
+
+void mf_optst(void)
+{
+    if (sym == EOLSYM)
+    {
+       target.base = ST1REG;
+       buildfreg();
+    }
+    else
+       mf_st();
+}
+
+/* [faddp fdivp fdivrp fmulp fsubp fsubrp] st(i),st */
+
+void mf_stst(void)
+{
+    target.base = fpregchk();
+    if (target.base == NOREG)
+    {
+       kgerror(FP_REG_REQ);
+       return;
+    }
+    getcomma();
+    source.base = fpregchk();
+    if (source.base == NOREG)
+    {
+       kgerror(FP_REG_REQ);
+       return;
+    }
+    if (source.base != ST0REG)
+    {
+       kgerror(ILL_FP_REG);
+       return;
+    }
+    buildfreg();
+}
+
+void mf_w_inher(void)
+{
+    sprefix = WAIT_OPCODE;
+    mf_inher();
+}
+
+/* [fsave fstenv] mem */
+
+void mf_w_m(void)
+{
+    sprefix = WAIT_OPCODE;
+    mf_m();
+}
+
+/* fstcw mem2i */
+
+void mf_w_m2(void)
+{
+    sprefix = WAIT_OPCODE;
+    mf_m2();
+}
+
+/* fstsw [mem2i ax] */
+
+void mf_w_m2_ax(void)
+{
+    sprefix = WAIT_OPCODE;
+    mf_m2_ax();
+}
+
+/* ADC, ADD, AND, CMP, OR, SBB, SUB, XOR */
+
+void mgroup1(void)
+{
+    getbinary();
+    notsegorspecreg(&source);
+    if (mcount != 0x0)
+    {
+       if (source.base == NOREG)
+       {
+           if (target.indcount == 0x0 && (target.base == ALREG ||
+                                          target.base == AXREG ||
+                                         (target.base == EAXREG &&
+                         (source.displ.data & (FORBIT | RELBIT | UNDBIT) ||
+                          !is8bitsignedoffset(source.displ.offset)))))
+           {
+               opcode |= 0x04 | segword;
+               buildimm(&source, FALSE);
+           }
+           else
+           {
+               buildunary(0x80 | segword);
+               buildimm(&source, TRUE);
+           }
+       }
+       else
+       {
+           opcode |= direction | segword;
+           buildregular();
+       }
+    }
+}
+
+/* RCL, RCR, ROL, ROR, SAL, SAR, SHL, SHR */
+
+void mgroup2(void)
+{
+    ++mcount;
+    Ex(&target);
+    buildsegword(&target);
+    getshift(&source);
+    if (mcount != 0x0)
+    {
+       buildunary(0xD0 | segword);
+       if (source.base == CLREG)
+           opcode |= 0x2;
+       else if (source.displ.offset != 0x1)
+       {
+           needcpu(1);
+           opcode -= 0x10;
+           source.size = 0x1;
+           buildimm(&source, FALSE);
+       }
+    }
+}
+
+/* LLDT, LTR, SLDT, STR, VERR, VERW */
+
+void mgroup6(void)
+{
+    needcpu(2);
+    ++mcount;
+    Ew(&target);
+    oprefix = 0x0;
+    buildunary(0x0);
+}
+
+/* INVLPG, LGDT, LIDT, LMSW, SGDT, SIDT, SMSW */
+
+void mgroup7(void)
+{
+    needcpu(2);        /* I think INVLPG is actually 386 */
+    ++mcount;
+    if (opcode == 0x20 || opcode == 0x30)
+    {
+       Ew(&target);
+       oprefix = 0x0;
+    }
+    else
+    {
+       getindirect(&target);
+       oprefix = 0x0;
+       if (target.size != 0x0 && target.size != 0x6)
+           error(MISMATCHED_SIZE);     /* XXX - size 6 wrong for INVLPG? */
+    }
+    buildunary(0x1);
+}
+
+/* BT, BTR, BTS, BTC */
+
+void mgroup8(void)
+{
+    needcpu(3);
+    ++mcount;
+    Ev(&target);
+    getcomma();
+    /* Gv or Ib */
+    getea(&source);
+    notindirect(&source);
+    notsegorspecreg(&source);
+    if (mcount != 0x0)
+    {
+       if (source.base == NOREG)
+       {
+           buildunary(0xBA);
+           source.size = 0x1;
+           buildimm(&source, TRUE);
+       }
+       else
+       {
+           yes_samesize();
+           opcode += 0x83;
+           buildregular();
+       }
+    }
+}
+
+/* BSF, BSR, LAR, LSL (Intel manual opcode chart wrongly says GvEw for L*) */
+
+void mGvEv(void)
+{
+    needcpu(2);
+    ++mcount;
+    Gv(&source);
+    getcomma();
+    Ev(&target);
+    yes_samesize();
+    buildregular();
+}
+
+/* bound [r16,m16&16 r32,m32&32] */
+
+void mGvMa(void)
+{
+    ++mcount;
+    Gv(&source);
+    getcomma();
+    getindirect(&target);
+    yes_samesize();
+    buildregular();
+}
+
+/* LDS, LES, LFS, LGS, LSS */
+
+void mGvMp(void)
+{
+    ++mcount;
+    Gv(&source);
+    getcomma();
+    getindirect(&target);
+    if (target.size != 0x0 && target.size != 0x2 + source.size)
+       error(MISMATCHED_SIZE);
+    buildregular();
+}
+
+/* IMUL */
+
+void mimul(void)
+{
+    ++mcount;
+    Ex(&target);
+    if (sym != COMMA)
+    {
+       buildsegword(&target);
+       buildunary(0xF6 | segword);
+       return;
+    }
+    getcomma();
+    notindirect(&target);
+    source = target;           /* direction is swapped */
+    getea(&target);
+    notsegorspecreg(&target);
+    yes_samesize();
+    if (sym != COMMA && (target.indcount != 0x0 || target.base != NOREG))
+    {
+        needcpu(3);
+       page = PAGE1_OPCODE;
+       ++mcount;
+       opcode = 0xAF;
+       buildregular();
+    }
+    else
+    {
+       if (sym == COMMA)
+       {
+           getsym();
+           getea(&source2);
+           yesimmed(&source2);
+       }
+       else
+       {
+           source2 = target;
+           target = source;
+       }
+       source2.size = target.size;
+       if (is8bitsignedoffset(source2.displ.offset))
+       {
+           source2.size = 0x1;
+           opcode = 0x6B;
+       }
+       else
+       {
+           source2.size = target.size;
+           opcode = 0x69;
+       }
+       buildregular();
+       if (mcount != 0x0)
+           buildimm(&source2, FALSE);
+    }
+}
+
+/* IN */
+
+void min(void)
+{
+    ++mcount;
+    if (opcode & WORDBIT)      /* inw; ind not supported */
+       mnsize = 0x2;
+    if (sym == EOLSYM && mnsize != 0x0)
+           target.size = mnsize;
+    else
+    {
+       if (getaccumreg(&target))
+       {
+           if (mnsize != 0x0 && regsize[target.base] != mnsize)
+               error(MISMATCHED_SIZE);
+           getcomma();
+       }
+       else
+           target.size = regsize[target.base = mnsize < 0x2 ? ALREG : AXREG];
+       opcode |= regsegword[target.base];
+       if (!getdxreg(&source))
+       {
+           getimmed(&source, 0x1);
+           opcode -= 0x8;
+       }
+    }
+    if (target.size > 0x1 && target.size != defsize)
+       oprefix = 0x66;
+}
+
+/* DEC, INC */
+
+void mincdec(void)
+{
+    ++mcount;
+    Ex(&target);
+    buildsegword(&target);
+    if (target.indcount == 0x0 && segword == WORDBIT)
+       opcode |= 0x40 | rm[target.base];
+    else
+       buildunary(0xFE | segword);
+}
+
+/* CBW, CWD, CMPSW, INSW, IRET, LODSW, POPA, POPF, PUSHA, PUSHF */
+/* MOVSW, OUTSW, SCASW, STOSW */
+
+void minher16(void)
+{
+    minher();
+    if (defsize != 0x2)
+       oprefix = 0x66;
+}
+
+/* CWDE, CDQ, CMPSD, INSD, IRETD, LODSD, POPAD, POPFD, PUSHAD, PUSHFD */
+/* MOVSD, OUTSD, SCASD, STOSD */
+
+void minher32(void)
+{
+    minher();
+    if (defsize != 0x4)
+       oprefix = 0x66;
+    needcpu(3);
+}
+
+/* AAD, AAM */
+
+void minhera(void)
+{
+    ++mcount;
+    if (sym == EOLSYM)
+    {
+       target.displ.offset = 0xA;
+       target.size = 0x1;
+       buildimm(&target, FALSE);
+    }
+    else
+       getimmed(&target, 0x1);
+}
+
+/* INT */
+
+void mint(void)
+{
+    ++mcount;
+    getimmed(&target, 0x1);
+    if (!(immadr.data & (FORBIT | RELBIT | UNDBIT)) &&
+       (opcode_t) immadr.offset == 0x3)
+    {
+       immcount = 0x0;
+       opcode = 0xCC;
+    }
+}
+
+/* JCC */
+
+void mjcc(void)
+{
+    /* First look for j* near */
+    if (sym == IDENT && 
+        gsymptr->type & MNREGBIT &&
+       gsymptr->data & SIZEBIT &&
+        gsymptr->value_reg_or_op.op.routine == WORDOP &&
+       opcode < 0x80)
+    {
+        getsym();
+        getea(&target);
+        if (target.indcount >= 0x2 || target.base != NOREG)
+          kgerror(REL_REQ);
+        else
+        {
+            needcpu(3);
+           page = PAGE1_OPCODE;
+           ++mcount;
+           opcode += 0x10;
+           lbranch(0x84);
+        }
+    }
+    else if (!jumps_long || opcode > 0x80) /* above 0x80 means loop, not long */
+       mshort();
+    else  /* mbcc */
+    {
+        getea(&target);
+       lastexp = target.displ;
+
+       if ( (pass!=0 && !is8bitsignedoffset(lastexp.offset - lc - 2)) ||
+             last_pass==1)
+       {
+           if (target.indcount >= 0x2 || target.base != NOREG)
+              kgerror(REL_REQ);
+
+           aprefix = opcode ^ 0x1;     /* kludged storage for short branch
+                                          over */
+           oprefix = defsize + 0x1;
+           mcount += 0x2;
+           opcode = JMP_OPCODE;
+           lbranch(0x83);
+           mcount -= 0x2;
+       }
+       else
+       {
+          /* 8 bit */
+           if (lastexp.data & IMPBIT)
+           {
+               error(NONIMPREQ);
+               lastexp.data = FORBIT | UNDBIT;
+           }
+           mshort2();
+       }
+    }
+}
+
+/* JCXZ, JECXZ */
+
+void mjcxz(void)
+{
+    if (opcode != defsize)
+    {
+       aprefix = 0x67;
+       ++mcount;               /* quick fix - mshort() needs to know */
+    }
+    opcode = 0xE3;
+    mshort();
+    if (aprefix != 0x0)
+       --mcount;               /* quick fix - main routine bumps it again */
+}
+
+/* LEA */
+
+void mlea(void)
+{
+    Gv(&source);               /* back to front */
+    getcomma();
+    ++mcount;
+    getindirect(&target);
+    yes_samesize();
+    buildregular();
+}
+
+/* MOV */
+
+void mmov(void)
+{
+    getbinary();
+    if (segword >= SEGMOV)
+    {
+       oprefix = 0x0;
+       notimmed(&target);      /* target is actually the source */
+       if (segword > SEGMOV)   /* special reg */
+           notindirect(&target);
+    }
+    if (mcount != 0x0)
+    {
+       if (target.base == NOREG && target.index == NOREG &&
+           (source.base == ALREG || source.base == AXREG ||
+            source.base == EAXREG))
+       {
+           opcode = 0xA0 | (direction ^ TOREGBIT) | segword;
+           lastexp = target.displ;
+           if ((source.size = displsize(&target)) != defsize)
+               aprefix = 0x67;
+           mcount += source.size;
+           needcpu(source.size==4?3:0);
+       }
+       else if (source.base == NOREG)
+       {
+           if (target.indcount == 0x0)
+               opcode = 0xB0 | (segword << 0x3) | rm[target.base];
+           else
+           {
+               buildea(&target);
+               opcode = 0xC6 | segword;
+           }
+           buildimm(&source, FALSE);
+       }
+       else
+       {
+           if (isspecreg(source.base))
+           {
+               needcpu(3);
+               page = PAGE1_OPCODE;
+               ++mcount;
+               opcode = 0x0;
+           }
+           opcode |= direction | segword;
+           buildregular();
+       }
+    }
+}
+
+/* MOVSX, MOVZX */
+
+void mmovx(void)
+{
+    ++mcount;
+    Gv(&source);
+    getcomma();
+    Ex(&target);
+    if (target.size == 0x0)
+       kgerror(SIZE_UNK);
+    if (target.size > 0x2)
+       kgerror(ILL_SIZE);
+    oprefix = 0x0;
+    if (source.size != defsize)
+       oprefix = 0x66;
+    buildsegword(&target);
+    opcode |= segword;
+    buildregular();
+}
+
+/* NEG, NOT */
+
+void mnegnot(void)
+{
+    ++mcount;
+    Ex(&target);
+    buildsegword(&target);
+    buildunary(0xF6 | segword);
+}
+
+/* OUT */
+
+void mout(void)
+{
+    ++mcount;
+    if (opcode & WORDBIT)      /* outw; outd not supported */
+       mnsize = 0x2;
+    if (sym == EOLSYM && mnsize != 0x0)
+           source.size = mnsize;
+    else
+    {
+       if (!getdxreg(&target))
+       {
+           getimmed(&target, 0x1);
+           opcode -= 0x8;
+       }
+       if (sym == COMMA)
+       {
+           getsym();
+           if (!getaccumreg(&source))
+               kgerror(AL_AX_EAX_EXP);
+           else if (mnsize != 0x0 && regsize[source.base] != mnsize)
+               error(MISMATCHED_SIZE);
+       }
+       else
+           source.size = regsize[source.base = mnsize < 0x2 ? ALREG : AXREG];
+       opcode |= regsegword[source.base];
+    }
+    if (source.size > 0x1 && source.size != defsize)
+       oprefix = 0x66;
+}
+
+/* POP, PUSH */
+
+void mpushpop(void)
+{
+    opcode_t oldopcode;
+
+    ++mcount;
+    getea(&target);
+    buildsegword(&target);
+    notbytesize(&target);
+    if ((oldopcode = opcode) == POP_OPCODE)
+    {
+       notimmed(&target);
+       if (target.base == CSREG)
+           kgerror(ILL_SEG_REG);
+    }
+    if (mcount != 0x0)
+    {
+       if (target.indcount == 0x0)
+       {
+           if (segword == SEGMOV)
+           {
+               switch (target.base)
+               {
+               case CSREG:
+                   opcode = 0x0E;
+                   break;
+               case DSREG:
+                   opcode = 0x1E;
+                   break;
+               case ESREG:
+                   opcode = 0x06;
+                   break;
+               case SSREG:
+                   opcode = 0x16;
+                   break;
+               case FSREG:
+                   opcode = 0xA0;
+                   page = PAGE1_OPCODE;
+                   ++mcount;
+                   break;
+               case GSREG:
+                   opcode = 0xA8;
+                   page = PAGE1_OPCODE;
+                   ++mcount;
+                   break;
+               }
+               if (oldopcode == POP_OPCODE)
+                   ++opcode;
+           }
+           else if (target.base != NOREG)
+           {
+               opcode = 0x50 | rm[target.base];
+               if (oldopcode == POP_OPCODE)
+                   opcode |= 0x8;
+           }
+           else
+           {
+               needcpu(1); /* On 8086 PUSH does not allow immediate */
+               opcode = 0x68;
+               if (oldopcode == POP_OPCODE)
+                   ++opcode;
+               buildimm(&target, TRUE);
+           }
+       }
+       else
+       {
+           buildea(&target);
+           if (oldopcode == PUSH_OPCODE)
+               postb |= 0x6 << REG_SHIFT;
+       }
+    }
+}
+
+/* RET, RETF */
+
+void mret(void)
+{
+    ++mcount;
+    if (sym != EOLSYM)
+    {
+       --opcode;
+       getimmed(&target, 0x2);
+    }
+}
+
+/* SEG CS/DS/ES/FS/GS/SS */
+
+void mseg(void)
+{
+    reg_pt reg;
+
+    if (regsegword[reg = regchk()] != SEGMOV)
+       error(SEG_REG_REQ);
+    else
+    {
+       getsym();
+       ++mcount;
+       opcode = (segoverride - CSREG)[reg];
+    }
+}
+
+/* SETCC */
+
+void msetcc(void)
+{
+    ++mcount;
+    Eb(&target);
+    if (mcount != 0x0)
+       buildea(&target);
+}
+
+/* SHLD, SHRD */
+
+void mshdouble(void)
+{
+    needcpu(3);
+    ++mcount;
+    Ev(&target);
+    getcomma();
+    Gv(&source);
+    yes_samesize();
+    buildregular();
+    getshift(&source2);
+    lastexp = target.displ;    /* getshift() wiped it out */
+    if (mcount != 0x0)
+    {
+       if (source2.base == CLREG)
+           opcode |= 0x1;
+       else
+       {
+           source2.size = 0x1;
+           buildimm(&source2, FALSE);
+       }
+    }
+}
+
+/*
+  TEST
+  Similar to the regular group1 operators.
+  It does not allow the sign extended immediate byte forms
+  and does not use the relevant direction bit.
+*/
+
+void mtest(void)
+{
+    getbinary();
+    notsegorspecreg(&source);
+    if (source.base == NOREG)
+    {
+       if (mcount != 0x0)
+       {
+           if (target.indcount == 0x0
+               && (target.base == ALREG || target.base == AXREG
+                   || target.base == EAXREG))
+               opcode = 0xA8 | segword;
+           else
+           {
+               buildea(&target);
+               opcode = 0xF6 | segword;
+           }
+       }
+       buildimm(&source, FALSE);
+    }
+    else
+    {
+       opcode |= segword;
+       buildregular();
+    }
+}
+
+/*
+  XCHG
+  Similar to the regular group1 operators.
+  It does not allow any of the immediate forms
+  and does not use the irrelevant direction bit.
+*/
+
+void mxchg(void)
+{
+    getbinary();
+    notimmed(&source);
+    notsegorspecreg(&source);
+    if (target.indcount == 0x0)
+    {
+       if (target.base == AXREG || target.base == EAXREG)
+       {
+           opcode = 0x90 + rm[source.base];
+           return;
+       }
+       if (source.base == AXREG || source.base == EAXREG)
+       {
+           opcode = 0x90 + rm[target.base];
+           return;
+       }
+    }
+    opcode |= segword;
+    buildregular();
+}
+
+static void notbytesize(eap)
+register struct ea_s *eap;
+{
+    if (eap->size == 0x1)
+       kgerror(ILL_SIZE);
+}
+
+static void notimmed(eap)
+register struct ea_s *eap;
+{
+    if (eap->indcount == 0x0 && eap->base == NOREG)
+       kgerror(ILL_IMM_MODE);
+}
+
+static void notindirect(eap)
+register struct ea_s *eap;
+{
+    if (eap->indcount != 0x0)
+       kgerror(ILL_IND);
+}
+
+static void notsegorspecreg(eap)
+register struct ea_s *eap;
+{
+    if (regsegword[eap->base] >= SEGMOV)
+       kgerror(ILLREG);
+}
+
+static void yesimmed(eap)
+register struct ea_s *eap;
+{
+    if (eap->indcount == 0x1)
+       eap->indcount = 0x0;
+    if (eap->indcount != 0x0 || eap->base != NOREG)
+       kgerror(IMM_REQ);
+}
+
+static void yes_samesize(void)
+{
+    if (target.size == 0x0)
+       target.size = source.size;
+    else if (source.size != 0x0 && target.size != source.size)
+       kgerror(MISMATCHED_SIZE);
+}
+
+#endif /* I80386 */
+
+#ifdef MC6809
+
+/* 6809 opcode constants */
+
+/* bits for indexed addressing */
+
+#define INDIRECTBIT 0x10
+#define INDEXBIT    0x80       /* except 5 bit offset */
+#define PCRELBIT    0x04       /* PC relative (in certain cases) */
+#define RRBITS      0x60       /* register select bits */
+
+static opcode_t rrindex[] =    /* register and index bits for indexed adr */
+{
+    0x60 | INDEXBIT,           /* S */
+    0x40 | INDEXBIT,           /* U */
+    0x00 | INDEXBIT,           /* X */
+    0x20 | INDEXBIT,           /* Y */
+    PCRELBIT | INDEXBIT,       /* PC */
+};
+
+static opcode_t pushpull[] =   /* push/pull codes  */
+{
+    0x40,                      /* S */
+    0x40,                      /* U */
+    0x10,                      /* X */
+    0x20,                      /* Y */
+    0x80,                      /* PC */
+    0x02,                      /* A */
+    0x04,                      /* B */
+    0x01,                      /* CC */
+    0x08,                      /* DP */
+    0x06,                      /* D */
+};
+
+static opcode_t tfrexg1[] =    /* transfer/exchange codes for source reg */
+{
+    0x40,                      /* S */
+    0x30,                      /* U */
+    0x10,                      /* X */
+    0x20,                      /* Y */
+    0x50,                      /* PC */
+    0x80,                      /* A */
+    0x90,                      /* B */
+    0xA0,                      /* CC */
+    0xB0,                      /* DP */
+    0x00,                      /* D */
+};
+
+static opcode_t tfrexg2[] =    /* transfer/exchange codes for target reg */
+{
+    0x04,                      /* S */
+    0x03,                      /* U */
+    0x01,                      /* X */
+    0x02,                      /* Y */
+    0x05,                      /* PC */
+    0x08,                      /* A */
+    0x09,                      /* B */
+    0x0A,                      /* CC */
+    0x0B,                      /* DP */
+    0x00,                      /* D */
+};
+
+static void checkpostinc(void);
+static void doaltind(void);
+static void do1altind(void);
+static void fixupind(void);
+static void getindexnopost(void);
+static void inderror(char * err_str);
+static reg_pt indreg(reg_pt maxindex);
+static void predec1(void);
+static void sustack(reg_pt stackreg);
+
+void checkpostinc(void)
+{
+    if (sym == ADDOP)
+    {
+       if (postb & INDIRECTBIT)
+           inderror(ILLMOD);   /* single-inc indirect illegal */
+       else
+       {
+           lastexp.offset &= 0xFF00;   /* for printing if postbyte is 0: ,X+ */
+           getsym();
+       }
+    }
+    else if (sym == POSTINCOP)
+    {
+       postb |= 0x1;
+       getsym();
+    }
+    else
+       postb |= 0x4;
+    fixupind();
+}
+
+/* common code for all-mode ops, alterable-mode ops, indexed ops */
+
+void doaltind(void)
+{
+    mcount += 0x2;
+    if (sym == LBRACKET)
+    {
+       postb = INDIRECTBIT;
+       getsym();
+       do1altind();
+       if (sym != RBRACKET)
+           error(RBEXP);
+    }
+    else
+       do1altind();
+}
+
+void do1altind(void)
+{
+    bool_t byteflag;           /* set if direct or short indexed adr forced */
+    char *oldlineptr;
+    char *oldsymname;
+    reg_pt reg;
+    bool_t wordflag;           /* set if extended or long indexed adr forced*/
+
+    if ((reg = regchk()) != NOREG)
+    {
+       switch (reg)
+       {
+       case AREG:
+           postb |= 0x86;
+           break;
+       case BREG:
+           postb |= 0x85;
+           break;
+       case DREG:
+           postb |= 0x8B;
+           break;
+       default:
+           if (indreg(MAXINDREG) != NOREG)
+               checkpostinc();
+           return;
+       }
+       getsym();
+       if (sym != COMMA)
+           inderror(COMEXP);
+       else
+           getindexnopost();
+       return;
+    }
+    else if (sym == SUBOP)     /* could be -R or - in expression */
+    {
+       oldlineptr = lineptr;   /* save state */
+       oldsymname = symname;
+       getsym();
+       reg = regchk();
+       lineptr = oldlineptr;
+       symname = oldsymname;
+       if (reg != NOREG)
+       {
+           predec1();          /* it's -R */
+           return;
+       }
+       sym = SUBOP;
+    }
+    else if (sym == COMMA)
+    {
+       postb |= INDEXBIT;
+       getsym();
+       if (sym == SUBOP)
+       {
+           predec1();
+           return;
+       }
+       else if (sym != PREDECOP)
+       {
+           if (indreg(MAXINDREG) != NOREG)
+               checkpostinc();
+           return;
+       }
+    }
+    if (sym == PREDECOP)
+    {
+       postb |= 0x83;
+       getindexnopost();
+       return;
+    }
+
+    /* should have expression */
+
+    wordflag = byteflag = FALSE;
+    if (sym == LESSTHAN)
+    {
+       /* context-sensitive, LESSTHAN means byte-sized here */
+       byteflag = TRUE;
+       getsym();
+    }
+    else if (sym == GREATERTHAN)
+    {
+       /* context-sensitive, GREATERTHAN means word-sized here */
+       wordflag = TRUE;
+       getsym();
+    }
+    expres();
+    if (sym == COMMA)
+    {                          /* offset from register */
+       getsym();
+       if ((reg = indreg(PCREG)) == NOREG)
+           return;
+       postb |= 0x8;           /* default 8 bit offset */
+       if (reg == PCREG)
+       {
+           reldata();
+           if (!(lastexp.data & (RELBIT | UNDBIT)))
+           {
+               lastexp.offset = lastexp.offset - lc;
+               if (page != 0x0)
+                   lastexp.offset -= 0x4;      /* extra for instruction */
+               else
+                   lastexp.offset -= 0x3;      /* 3 byte instruction
+                                                  assuming 8 bit offset */
+           }
+       }
+       if (byteflag)
+       {
+           if (!(lastexp.data & (RELBIT | UNDBIT)) &&
+               !is8bitsignedoffset(lastexp.offset))
+               error(ABOUNDS); /* forced short form is impossible */
+           ++mcount;
+       }
+       else if (wordflag || lastexp.data & (FORBIT | RELBIT | UNDBIT) ||
+                !is8bitsignedoffset(lastexp.offset))
+       {                       /* 16 bit offset */
+           if (postb & PCRELBIT && !(lastexp.data & RELBIT))
+               --lastexp.offset;       /* instruction 1 longer than already
+                                          allowed */
+           postb |= 0x1;
+           mcount += 0x2;
+       }
+       else if (!(postb & PCRELBIT) &&
+                (offset_t) (lastexp.offset + 0x10) < 0x20 &&
+                !(postb & INDIRECTBIT && lastexp.offset != 0x0))
+       {                       /* 5 bit offset */
+           postb &= RRBITS | INDIRECTBIT;
+           if (lastexp.offset == 0x0)
+               postb |= 0x84;  /* index with zero offset */
+           else
+               postb |= (lastexp.offset & 0x1F);
+       }
+       else                    /* 8 bit offset */
+           ++mcount;
+       fixupind();
+    }
+    else if (postb & INDIRECTBIT)
+    {                          /* extended indirect */
+       postb = 0x9F;
+       mcount += 0x2;
+       fixupind();
+    }
+    else if (postb & INDEXBIT)
+       inderror(ILLMOD);       /* e.g. LEAX     $10 */
+    else
+    {
+       if (byteflag || (!wordflag && !(lastexp.data & (FORBIT | RELBIT)) &&
+           (lastexp.offset >> 0x8) == dirpag))
+       {                       /* direct addressing */
+           if (opcode >= 0x80)
+               opcode |= 0x10;
+       }
+       else                    /* extended addressing */
+       {
+           if (opcode < 0x80)
+               opcode |= 0x70;
+           else
+               opcode |= 0x30;
+           ++mcount;
+           if (pass2 && (opcode == JSR_OPCODE || opcode == JMP_OPCODE) &&
+               !(lastexp.data & IMPBIT) &&
+               lastexp.offset + (0x81 - 0x3) < 0x101)
+                               /* JSR or JMP could be done with BSR or BRA */
+               warning(SHORTB);
+       }
+    }
+}
+
+void fixupind(void)
+{
+    if ((opcode & 0x30) == 0x0)        /* change all but LEA opcodes */
+    {
+       if (opcode < 0x80)
+           opcode |= 0x60;
+       else
+           opcode |= 0x20;
+    }
+}
+
+void getindexnopost(void)
+{
+    getsym();
+    if (indreg(MAXINDREG) != NOREG)
+       fixupind();
+}
+
+void inderror(char *err_str)
+{
+    error(err_str);
+    if (postb & INDIRECTBIT)
+       sym = RBRACKET;         /* fake right bracket to kill further errors */
+    fixupind();
+}
+
+/* check current symbol is an index register (possibly excepting PC) */
+/* if so, modify postbyte RR and INDEXBIT for it, get next sym, return TRUE */
+/* otherwise generate error, return FALSE */
+
+reg_pt indreg(reg_pt maxindex)
+{
+    reg_pt reg;
+
+    if ((reg = regchk()) == NOREG)
+       inderror(IREGEXP);
+    else if (reg > maxindex)
+    {
+       inderror(ILLREG);
+       reg = NOREG;
+    }
+    else
+    {
+       postb |= rrindex[reg];
+       getsym();
+    }
+    return reg;
+}
+
+/* all-mode ops */
+
+void mall(void)
+{
+    if (sym == IMMEDIATE)
+       mimmed();
+    else
+       malter();
+}
+
+/* alterable mode ops */
+
+void malter(void)
+{
+    postb = 0x0;               /* not yet indexed or indirect */
+    doaltind();
+}
+
+/* indexed mode ops */
+
+void mindex(void)
+{
+    postb = INDEXBIT;          /* indexed but not yet indirect */
+    doaltind();
+}
+
+/* immediate ops */
+
+void mimmed(void)
+{
+    opcode_t nybble;
+
+    mcount += 0x2;
+    if (sym != IMMEDIATE)
+       error(ILLMOD);
+    else
+    {
+       if (opcode >= 0x80 && ((nybble = opcode & 0xF) == 0x3 ||
+                              nybble == 0xC || nybble >= 0xE))
+           ++mcount;           /* magic for long immediate */
+       symexpres();
+       if (pass2 && mcount <= 0x2)
+       {
+           chkabs();
+           checkdatabounds();
+       }
+    }
+}
+
+/* long branches */
+
+void mlong(void)
+{
+    mcount += 0x3;             /* may be 0x0 or 0x1 here */
+    expres();
+    segadj();
+    if (pass2)
+    {
+       reldata();
+       if (!(lastexp.data & (RELBIT | UNDBIT)))
+       {
+           lastexp.offset = lastexp.offset - lc - lcjump;
+           if ( last_pass<2 && !(lastexp.data & IMPBIT) &&
+               lastexp.offset + 0x81 < 0x101)
+               warning(SHORTB);        /* -0x81 to 0x7F, warning */
+       }
+    }
+}
+
+/* PSHS and PULS */
+
+void msstak(void)
+{
+    sustack(SREG);
+}
+
+/* TFR and EXG */
+
+void mswap(void)
+{
+    reg_pt reg;
+
+    mcount = 0x2;
+    if ((reg = regchk()) == NOREG)
+       error(REGEXP);
+    else
+    {
+       postb = tfrexg1[reg];
+       getsym();
+       if (sym != COMMA)
+           error(COMEXP);
+       else
+       {
+           getsym();
+           if ((reg = regchk()) == NOREG)
+               error(REGEXP);
+           else if ((postb |= tfrexg2[reg])
+                    & 0x88 && (postb & 0x88) != 0x88)
+               error(ILLREG);  /* registers not of same size */
+       }
+    }
+}
+
+/* PSHU and PULU */
+
+void mustak(void)
+{
+    sustack(UREG);
+}
+
+void predec1(void)
+{
+    if (postb & INDIRECTBIT)
+       inderror(ILLMOD);       /* single-dec indirect illegal */
+    else
+    {
+       postb |= 0x82;
+       getindexnopost();
+    }
+}
+
+/* common routine for PSHS/PULS/PSHU/PULU */
+
+void sustack(stackreg)
+reg_pt stackreg;
+{
+    reg_pt reg;
+
+    mcount = 0x2;
+    while ((reg = regchk()) != NOREG)
+    {
+       if (reg == stackreg)
+       {
+           error(ILLREG);      /* cannot stack self */
+           break;
+       }
+       postb |= pushpull[reg];
+       getsym();
+       if (sym != COMMA)
+           break;
+       getsym();
+    }
+}
+
+#endif /* MC6809 */
+
+/* routines common to all processors */
+
+void getcomma(void)
+{
+    if (sym != COMMA)
+       error(COMEXP);
+    else
+       getsym();
+}
+
+/* inherent ops */
+
+/* for I80386 */
+/* AAA, AAS, CLC, CLD, CLI, CLTS, CMC, CMPSB, DAA, DAS, HLT, INTO, INSB, */
+/* INVD, */
+/* LAHF, LEAVE, LOCK, LODSB, MOVSB, NOP, OUTSB, REP, REPE, REPNE, REPNZ, */
+/* REPZ, SAHF, SCASB, STC, STD, STI, STOSB, WAIT, WBINVD */
+
+void minher(void)
+{
+    ++mcount;
+}
+
+/* short branches */
+
+void mshort(void)
+{
+    nonimpexpres();
+    mshort2();
+}
+
+void mshort2(void)
+{
+    mcount += 0x2;
+    if (pass2)
+    {
+       reldata();
+       if (lastexp.data & RELBIT)
+           showrelbad();
+       else if (!(lastexp.data & UNDBIT))
+       {
+           lastexp.offset = lastexp.offset - lc - mcount;
+           if (!is8bitsignedoffset(lastexp.offset))
+               error(ABOUNDS);
+       }
+    }
+}
+
+/* check if current symbol is a register, return register number or NOREG */
+
+reg_pt regchk(void)
+{
+    register struct sym_s *symptr;
+
+    if (sym == IDENT)
+    {
+       if ((symptr = gsymptr)->type & MNREGBIT)
+       {
+           if (symptr->data & REGBIT)
+           {
+               int regno = symptr->value_reg_or_op.reg;
+#ifdef I80386
+               if (regno == ST0REG && !fpreg_allowed)
+                   error(FP_REG_NOT_ALLOWED);
+
+               /* Check cpu */
+                needcpu((regno==FSREG||regno==GSREG)?3:0);
+                needcpu((regno>=EAXREG && regno<=ESPREG)?3:0);
+                needcpu((regno>=CR0REG && regno<=TR7REG)?3:0);
+#endif
+               return regno;
+           }
+       }
+       else
+           if( last_pass == 1 )
+               if (!(symptr->type & (LABIT | MACBIT | VARBIT)))
+                   symptr->data |= FORBIT;     /* show seen in advance */
+    }
+    return NOREG;
+}
+
+/* convert lastexp.data for PC relative */
+
+void reldata(void)
+{
+    if ((lastexp.data ^ lcdata) & (IMPBIT | RELBIT | SEGM))
+    {
+       if ((lastexp.data ^ lcdata) & RELBIT)
+           showrelbad();       /* rel - abs is weird, abs - rel is bad */
+       else
+       {
+           pcrflag = OBJ_R_MASK;
+           lastexp.data = (lcdata & ~SEGM) | lastexp.data | RELBIT;
+                               /* segment is that of lastexp.data */
+       }
+    }
+    else                       /* same file, segment and relocation */
+       lastexp.data = (lastexp.data | lcdata) & ~(RELBIT | SEGM);
+}
+
+void segadj(void)
+{
+    if ((lastexp.data & UNDBIT) && textseg >= 0 )
+    {
+        lastexp.sym->data &= ~SEGM;
+        lastexp.sym->data |= (lcdata & SEGM);
+    }
+}
diff --git a/Applications/as09/obj1/calljmp.obj b/Applications/as09/obj1/calljmp.obj
new file mode 100644 (file)
index 0000000..522d6f7
Binary files /dev/null and b/Applications/as09/obj1/calljmp.obj differ
diff --git a/Applications/as09/obj1/ea.obj b/Applications/as09/obj1/ea.obj
new file mode 100644 (file)
index 0000000..6b53beb
Binary files /dev/null and b/Applications/as09/obj1/ea.obj differ
diff --git a/Applications/as09/obj1/each.obj b/Applications/as09/obj1/each.obj
new file mode 100644 (file)
index 0000000..5426253
Binary files /dev/null and b/Applications/as09/obj1/each.obj differ
diff --git a/Applications/as09/obj1/f.obj b/Applications/as09/obj1/f.obj
new file mode 100644 (file)
index 0000000..4dbe2d9
Binary files /dev/null and b/Applications/as09/obj1/f.obj differ
diff --git a/Applications/as09/obj1/fadd.obj b/Applications/as09/obj1/fadd.obj
new file mode 100644 (file)
index 0000000..28b3dd4
Binary files /dev/null and b/Applications/as09/obj1/fadd.obj differ
diff --git a/Applications/as09/obj1/farcall.obj b/Applications/as09/obj1/farcall.obj
new file mode 100644 (file)
index 0000000..259703c
Binary files /dev/null and b/Applications/as09/obj1/farcall.obj differ
diff --git a/Applications/as09/obj1/group1.obj b/Applications/as09/obj1/group1.obj
new file mode 100644 (file)
index 0000000..26d4a8c
Binary files /dev/null and b/Applications/as09/obj1/group1.obj differ
diff --git a/Applications/as09/obj1/group6.obj b/Applications/as09/obj1/group6.obj
new file mode 100644 (file)
index 0000000..27e81ae
Binary files /dev/null and b/Applications/as09/obj1/group6.obj differ
diff --git a/Applications/as09/obj1/group7.obj b/Applications/as09/obj1/group7.obj
new file mode 100644 (file)
index 0000000..37af051
Binary files /dev/null and b/Applications/as09/obj1/group7.obj differ
diff --git a/Applications/as09/obj1/imul.obj b/Applications/as09/obj1/imul.obj
new file mode 100644 (file)
index 0000000..34ef370
Binary files /dev/null and b/Applications/as09/obj1/imul.obj differ
diff --git a/Applications/as09/obj1/incdec.obj b/Applications/as09/obj1/incdec.obj
new file mode 100644 (file)
index 0000000..03f583a
Binary files /dev/null and b/Applications/as09/obj1/incdec.obj differ
diff --git a/Applications/as09/obj1/inher.obj b/Applications/as09/obj1/inher.obj
new file mode 100644 (file)
index 0000000..aaea0b9
Binary files /dev/null and b/Applications/as09/obj1/inher.obj differ
diff --git a/Applications/as09/obj1/inout.obj b/Applications/as09/obj1/inout.obj
new file mode 100644 (file)
index 0000000..58aa820
Binary files /dev/null and b/Applications/as09/obj1/inout.obj differ
diff --git a/Applications/as09/obj1/movspec.obj b/Applications/as09/obj1/movspec.obj
new file mode 100644 (file)
index 0000000..15eab78
Binary files /dev/null and b/Applications/as09/obj1/movspec.obj differ
diff --git a/Applications/as09/obj1/pushpop.obj b/Applications/as09/obj1/pushpop.obj
new file mode 100644 (file)
index 0000000..2ff789e
Binary files /dev/null and b/Applications/as09/obj1/pushpop.obj differ
diff --git a/Applications/as09/obj1/seg.obj b/Applications/as09/obj1/seg.obj
new file mode 100644 (file)
index 0000000..2ba948c
Binary files /dev/null and b/Applications/as09/obj1/seg.obj differ
diff --git a/Applications/as09/obj1/shdouble.obj b/Applications/as09/obj1/shdouble.obj
new file mode 100644 (file)
index 0000000..ab75750
Binary files /dev/null and b/Applications/as09/obj1/shdouble.obj differ
diff --git a/Applications/as09/obj1/shift.obj b/Applications/as09/obj1/shift.obj
new file mode 100644 (file)
index 0000000..520be81
Binary files /dev/null and b/Applications/as09/obj1/shift.obj differ
diff --git a/Applications/as09/obj1/xchg.obj b/Applications/as09/obj1/xchg.obj
new file mode 100644 (file)
index 0000000..c39b703
Binary files /dev/null and b/Applications/as09/obj1/xchg.obj differ
diff --git a/Applications/as09/opcode.h b/Applications/as09/opcode.h
new file mode 100644 (file)
index 0000000..1d91dc2
--- /dev/null
@@ -0,0 +1,159 @@
+/* opcode.h - routine numbers and special opcodes for assembler */
+
+enum
+{
+/* Pseudo-op routine numbers.
+ * Conditionals are first - this is used to test if op is a conditional.
+ */
+    ELSEOP,
+    ELSEIFOP,
+    ELSEIFCOP,
+    ENDIFOP,
+    IFOP,
+    IFCOP,
+
+#define MIN_NONCOND    ALIGNOP
+    ALIGNOP,
+    ASCIZOP,
+    BLKWOP,
+    BLOCKOP,
+    BSSOP,
+    COMMOP,
+    COMMOP1,
+    DATAOP,
+    ENDBOP,
+    ENTEROP,
+    ENTRYOP,
+    EQUOP,
+    EVENOP,
+    EXPORTOP,
+    FAILOP,
+    FCBOP,
+    FCCOP,
+    FDBOP,
+#if SIZEOF_OFFSET_T > 2
+    FQBOP,
+#endif
+    GETOP,
+    GLOBLOP,
+    IDENTOP,
+    IMPORTOP,
+    LCOMMOP,
+    LCOMMOP1,
+    LISTOP,
+    LOCOP,
+    MACLISTOP,
+    MACROOP,
+    MAPOP,
+    ORGOP,
+    PROCEOFOP,
+    RMBOP,
+    SECTOP,
+    SETOP,
+    SETDPOP,
+    TEXTOP,
+#ifdef I80386
+    USE16OP,
+    USE32OP,
+#endif
+    WARNOP,
+
+/* Machine-op routine numbers. */
+#ifdef I80386
+    BCC,
+    BSWAP,
+    CALL,
+    CALLI,
+    DIVMUL,
+    ENTER,
+    EwGw,
+    ExGx,
+    F_INHER,
+    F_M,
+    F_M2,
+    F_M2_AX,
+    F_M2_M4,
+    F_M2_M4_M8,
+    F_M4_M8_OPTST,
+    F_M4_M8_ST,
+    F_M4_M8_STST,
+    F_M4_M8_M10_ST,
+    F_M10,
+    F_OPTST,
+    F_ST,
+    F_STST,
+    F_W_INHER,
+    F_W_M,
+    F_W_M2,
+    F_W_M2_AX,
+    GROUP1,
+    GROUP2,
+    GROUP6,
+    GROUP7,
+    GROUP8,
+    GvEv,
+    GvMa,
+    GvMp,
+    IMUL,
+    IN,
+    INCDEC,
+    INHER,
+    INHER16,
+    INHER32,
+    INHER_A,
+    INT,
+    JCC,
+    JCXZ,
+    LEA,
+    MOV,
+    MOVX,
+    NEGNOT,
+    OUT,
+    PUSHPOP,
+    RET,
+    SEG,
+    SETCC,
+    SH_DOUBLE,
+    TEST,
+    XCHG
+#endif /* I80386 */
+
+#ifdef MC6809
+    ALL,                       /* all address modes allowed, like LDA */
+    ALTER,                     /* all but immediate, like STA */
+    IMMED,                     /* immediate only (ANDCC, ORCC) */
+    INDEXD,                    /* indexed (LEA's) */
+    INHER,                     /* inherent, like CLC or CLRA */
+    LONG,                      /* long branches */
+    SHORT,                     /* short branches */
+    SSTAK,                     /* S-stack (PSHS, PULS) */
+    SWAP,                      /* TFR, EXG */
+    USTAK                      /* U-stack (PSHU,PULU) */
+#endif /* MC6809 */
+};
+
+/* Special opcodes. */
+#ifdef I80386
+# define CMP_OPCODE_BASE       0x38
+# define CMPSB_OPCODE          0xA6
+# define CMPSW_OPCODE          0xA7
+# define ESCAPE_OPCODE_BASE    0xD8
+# define FST_ENCODED           0x12
+# define FSTP_ENCODED          0x13
+# define JMP_OPCODE            0xE9
+# define JMP_SHORT_OPCODE      0xEB
+# define JSR_OPCODE            0xE8
+# define MOVSB_OPCODE          0xA4
+# define MOVSW_OPCODE          0xA5
+# define PAGE1_OPCODE          0x0F
+# define POP_OPCODE            0x8F
+# define PUSH_OPCODE           0xFF
+# define WAIT_OPCODE           0x9B
+#endif
+
+#ifdef MC6809
+# define JMP_OPCODE            0x7E
+# define JSR_OPCODE            0xBD
+# define PAGE1_OPCODE          0x10
+# define PAGE2_OPCODE          0x11
+#endif
diff --git a/Applications/as09/pops.c b/Applications/as09/pops.c
new file mode 100644 (file)
index 0000000..f367335
--- /dev/null
@@ -0,0 +1,1105 @@
+/* pops.c - handle pseudo-ops for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "address.h"
+#include "flag.h"
+#include "globvar.h"
+#include "opcode.h"
+#include "scan.h"
+
+static bool_t elseflag;        /* set if ELSE/ELSEIF are enabled */
+                               /* depends on zero = FALSE init */
+static bool_t lcommflag;
+
+static void bumpsem P((struct flags_s *flagptr, int defval));
+static void constdata P((unsigned size));
+static void docomm P((void));
+static void doelseif P((pfv func));
+static void doequset P((unsigned char labits));
+static void doentexp P((unsigned char entbits, unsigned char impbits));
+static void dofcc P((void));
+static void doif P((pfv func));
+static struct sym_s *needlabel P((void));
+static void showredefinedlabel P((void));
+static void setloc P((unsigned seg));
+
+static void bumpsem(flagptr, defval)
+register struct flags_s *flagptr;
+int defval;
+{
+    int newcount;
+
+    if (flagptr->global && pass == last_pass)
+    {
+       /* bump semaphore count by an expression (default 1), */
+       /* then set currentflag iff semaphore count is plus */
+       if (sym == EOLSYM)
+           lastexp.offset = defval;
+       else
+       {
+           absexpres();
+           if (lastexp.data & UNDBIT)
+               return;
+       }
+       newcount = (int) lastexp.offset;
+#ifdef I80386                  /* really sizeof (offset_t) != sizeof (int) */
+       if (newcount != lastexp.offset)
+           datatoobig();
+#endif
+       newcount += flagptr->semaphore;
+       if ((int) lastexp.offset >= 0)
+       {
+           if (newcount < flagptr->semaphore)
+           {
+               error(COUNTOV);
+               newcount = 0x7fff;
+           }
+       }
+       else if (newcount >= flagptr->semaphore)
+       {
+           error(COUNTUN);
+           newcount = -0x8000;
+       }
+       flagptr->semaphore = newcount;
+       flagptr->current = newcount >= 0;
+    }
+}
+
+/* check symbol is either undefined */
+/* or has the same segment & relocatability as lc */
+
+bool_pt checksegrel(symptr)
+register struct sym_s *symptr;
+{
+    if ((symptr->type & LABIT ||
+       (symptr->data & IMPBIT && !(symptr->data & UNDBIT))) &&
+       ((symptr->data ^ lcdata) & (RELBIT | SEGM)))
+    {
+       error(SEGREL);
+       return FALSE;
+    }
+    return TRUE;
+}
+
+/* check address fits in 1 byte (possibly with sign truncated) */
+
+void checkdatabounds(void)
+{
+    if (!(lastexp.data & UNDBIT) &&
+       (offset_t) (lastexp.offset + 0x80) >= 0x180)
+       datatoobig();
+}
+
+/* allocate constant data (zero except for size 1), default zero for size 1 */
+
+static void constdata(unsigned size)
+{
+    offset_t remaining;
+
+    absexpres();
+    if (!((lcdata |= lastexp.data) & UNDBIT))
+    {
+       lcjump = lastexp.offset * size;
+       popflags = POPLONG | POPHI | POPLO | POPLC;
+       if (size == 1 && sym == COMMA)
+       {
+           symabsexpres();
+           checkdatabounds();
+           for (remaining = lcjump; remaining != 0; --remaining)
+           {
+               putbin((opcode_pt) lastexp.offset);     /* fill byte */
+               putabs((opcode_pt) lastexp.offset);
+           }
+           lastexp.offset = lcjump;
+       }
+       else
+           accumulate_rmb(lastexp.offset * size);
+    }
+}
+
+void datatoobig(void)
+{
+    error(DBOUNDS);
+}
+
+/* common routine for COMM/.COMM */
+
+static void docomm(void)
+{
+    register struct sym_s *labptr;
+
+    absexpres();               /* if undefined, value 0 and size unchanged */
+    labptr = label;
+    if (checksegrel(labptr))
+    {
+       if (labptr->type & (EXPBIT | LABIT))
+           labelerror(ALREADY);
+       else
+       {
+           if (!(labptr->type & COMMBIT) ||
+               lastexp.offset > labptr->value_reg_or_op.value)
+               labptr->value_reg_or_op.value = lastexp.offset;
+           labptr->type |= COMMBIT;
+           if (lcommflag)
+               labptr->type |= REDBIT; /* kludge - COMMBIT | REDBIT => SA */
+           if( last_pass == 1 )
+              labptr->data = (lcdata & SEGM) | (FORBIT | IMPBIT | RELBIT);
+           else
+              labptr->data = (lcdata & SEGM) | (IMPBIT | RELBIT);
+           showlabel();
+       }
+    }
+    lcommflag = FALSE;
+}
+
+/* common routine for ELSEIF/ELSEIFC */
+
+static void doelseif(pfv func)
+{
+    if (iflevel == 0)
+       error(ELSEIFBAD);
+    else
+    {
+       ifflag = FALSE;
+       if (elseflag)
+       {
+           (*func) ();
+           if (!(lastexp.data & UNDBIT) && lastexp.offset != 0)
+               /* expression valid and TRUE, enable assembling */
+           {
+               ifflag = TRUE;
+               elseflag = FALSE;
+           }
+       }
+       else
+       {
+           /* Skip to EOL */
+           while (sym != EOLSYM)
+               getsym();
+       }
+    }
+}
+
+/* common routine for EQU/SET */
+
+static void doequset(unsigned char labits)
+{
+    register struct sym_s *labptr;
+    unsigned char olddata;
+    unsigned char oldtype;
+
+    labptr = label;
+    /* set up new label flags in case labe isl used in expression */
+    labptr->type = (oldtype = labptr->type) | labits;
+    labptr->data = (olddata = labptr->data) & ~IMPBIT;
+    /* non-imported now */
+    nonimpexpres();
+    lastexp.data |= olddata & FORBIT;  /* take all but FORBIT from
+                                          expression */
+    if (oldtype & LABIT && !(olddata & UNDBIT) && !pass)
+       /* this is a previously defined label */
+
+       /*
+          redefinition only allowed if same relocatability, segment and
+          value
+       */
+    {
+       if ((olddata ^ lastexp.data) & (RELBIT | UNDBIT) ||
+           labptr->value_reg_or_op.value != lastexp.offset)
+       {
+           showredefinedlabel();
+           return;
+       }
+    }
+    labptr->data = lastexp.data;
+    labptr->value_reg_or_op.value = lastexp.offset;
+    showlabel();
+
+    if(pass && !(labits & VARBIT) && labptr->value_reg_or_op.value != oldlabel)
+    {
+       dirty_pass = TRUE;
+       if( pass == last_pass )
+           error(UNSTABLE_LABEL);
+    }
+}
+
+/* common routine for ENTRY/EXPORT */
+
+static void doentexp(unsigned char entbits, unsigned char impbits)
+{
+    struct sym_s *symptr;
+
+    while (TRUE)
+    {
+       if ((symptr = needlabel()) != NUL_PTR)
+       {
+           if (symptr->type & COMMBIT)
+               error(ALREADY);
+           else if (impbits != 0)
+           {
+               if (pass == last_pass)
+                   ;
+               else if (symptr->type & (EXPBIT | LABIT))
+                   symptr->type |= EXPBIT;
+               else
+               {
+                   symptr->type |= REDBIT;
+                   if (!(symptr->data & IMPBIT))
+                       symptr->data |= IMPBIT | SEGM;
+               }
+           }
+           else
+           {
+               if (pass == last_pass)
+               {
+                   if (!(symptr->type & LABIT))
+                       error(UNLAB);
+               }
+               else
+               {
+                   symptr->type |= entbits | EXPBIT;
+                   symptr->data &= ~IMPBIT;
+               }
+           }
+       }
+       getsym();
+       if (sym != COMMA)
+           break;
+       getsym();
+    }
+}
+
+/* common routine for FCC (== .ASCII) and .ASCIZ */
+
+static void dofcc(void)
+{
+    register char *bufptr;
+    char byte;
+    char delimiter;
+    register char *reglineptr;
+
+    bufptr = databuf.fcbuf;
+    reglineptr = symname;
+    if ((delimiter = *reglineptr) != EOLCHAR)
+       ++reglineptr;
+    while (TRUE)
+    {
+       if ((byte = *reglineptr) == EOLCHAR)
+       {
+           symname = reglineptr;
+           error(DELEXP);
+           break;
+       }
+       if (byte == delimiter)
+       {
+           if ((byte = *++reglineptr) != delimiter)
+               break;
+       }
+       else if (byte == '\\')
+       {
+           switch (byte = *++reglineptr)
+           {
+           case '"':
+           case '\'':
+           case '\\':
+           case '?':
+               break;
+           case '0':
+           case '1':
+           case '2':
+           case '3':
+           case '4':
+           case '5':
+           case '6':
+           case '7':
+               byte -= '0';
+               if (*(reglineptr + 1) >= '0' && *(reglineptr + 1) < '8')
+               {
+                   byte = 8 * byte + *++reglineptr - '0';
+                   if (*(reglineptr + 1) >= '0' && *(reglineptr + 1) < '8')
+                       byte = 8 * byte + *++reglineptr - '0';
+               }
+               break;
+           case 'a':
+               byte = 7;
+               break;
+           case 'b':
+               byte = 8;
+               break;
+           case 'f':
+               byte = 12;
+               break;
+           case 'n':
+               byte = 10;
+               break;
+           case 'r':
+               byte = 13;
+               break;
+           case 't':
+               byte = 9;
+               break;
+           case 'v':
+               byte = 11;
+               break;
+           case 'x':
+               byte = '0';
+               while (TRUE)
+               {
+                   ++reglineptr;
+                   if (*reglineptr >= '0' && *reglineptr <= '9')
+                       byte = 16 * byte + *reglineptr - '0';
+                   else if (*reglineptr >= 'F' && *reglineptr <= 'F')
+                       byte = 16 * byte + *reglineptr - 'A';
+                   else if (*reglineptr >= 'a' && *reglineptr <= 'f')
+                       byte = 16 * byte + *reglineptr - 'F';
+                   else
+                       break;
+               }
+               --reglineptr;
+               break;
+           default:
+               symname = reglineptr;
+               error(UNKNOWN_ESCAPE_SEQUENCE);
+               break;
+           }
+       }
+       else if (byte < ' ' && byte >= 0)
+       {
+           symname = reglineptr;
+           error(CTLINS);
+           byte = ' ';
+       }
+       ++reglineptr;
+       *bufptr++ = byte;
+    }
+    lineptr = reglineptr;
+    getsym();
+    lastexp.offset = databuf.fcbuf[0]; /* show only 1st char (if any) */
+    mcount = bufptr - databuf.fcbuf;
+    /* won't overflow, line length limits it */
+    /* XXX - but now line length is unlimited */
+}
+
+/* common routine for IF/IFC */
+
+static void doif(pfv func)
+{
+    if (iflevel >= MAXIF)
+       error(IFOV);
+    else
+    {
+       ++iflevel;
+       --ifstak;
+       ifstak->elseflag = elseflag;
+       elseflag = FALSE;       /* prepare */
+       if ((ifstak->ifflag = ifflag) != FALSE)
+           /* else not assembling before, so not now & no ELSE's */
+       {
+           (*func) ();
+           if (!(lastexp.data & UNDBIT) && lastexp.offset == 0)
+               /* else expression invalid or FALSE, don't change flags */
+           {
+               ifflag = FALSE; /* not assembling */
+               elseflag = TRUE;/* but ELSE will change that */
+           }
+       }
+       else
+       {
+           /* Skip to EOL */
+           while (sym != EOLSYM)
+               getsym();
+       }
+    }
+}
+
+void fatalerror(char *err_str)
+{
+    error(err_str);
+    skipline();
+    listline();
+    finishup();
+}
+
+/* swap position with label position, do error, put back posn */
+/* also clear label ptr */
+
+void labelerror(char *err_str)
+{
+    struct sym_s *oldgsymptr;
+    char *oldlineptr;
+    unsigned char oldsym;
+    char *oldsymname;
+
+    oldgsymptr = gsymptr;
+    oldlineptr = lineptr;
+    oldsym = sym;
+    oldsymname = symname;
+    lineptr = linebuf;
+    getsym();                  /* 1st symbol is label or symbol after
+                                * missing one */
+    error(err_str);
+    gsymptr = oldgsymptr;
+    lineptr = oldlineptr;
+    sym = oldsym;
+    symname = oldsymname;
+    label = NUL_PTR;
+}
+
+static struct sym_s *needlabel(void)
+{
+    register struct sym_s *symptr;
+
+    if (sym != IDENT ||
+       (symptr = gsymptr)->type & (MACBIT | MNREGBIT | VARBIT))
+    {
+       error(LABEXP);
+       return NUL_PTR;
+    }
+    return symptr;
+}
+
+/* .ALIGN pseudo-op */
+
+void palign(void)
+{
+    absexpres();
+    if (!((lcdata |= lastexp.data) & UNDBIT))
+    {
+       popflags = POPLONG | POPHI | POPLO | POPLC;
+       if (lastexp.offset != 0 &&
+           (lcjump = lc % lastexp.offset) != 0)
+           accumulate_rmb(lcjump = lastexp.offset - lcjump);
+    }
+}
+
+/* .ASCIZ pseudo-op */
+
+void pasciz(void)
+{
+    dofcc();
+    databuf.fcbuf[mcount++] = 0;
+    fcflag = TRUE;
+    popflags = POPLO | POPLC;
+}
+
+/* .BLKW pseudo-op */
+
+void pblkw(void)
+{
+    constdata(2);
+}
+
+/* BLOCK pseudo-op */
+
+void pblock(void)
+{
+    if (blocklevel >= MAXBLOCK)
+       error(BLOCKOV);
+    else
+    {
+       register struct block_s *blockp;
+
+       ++blocklevel;
+       blockp = blockstak;
+       blockstak = --blockp;
+       blockp->data = lcdata;
+       blockp->dp = dirpag;
+       blockp->lc = lc;
+       porg();                 /* same as ORG apart from stacking */
+    }
+}
+
+/* .BSS pseudo-op */
+
+void pbss(void)
+{
+    setloc(BSSLOC);
+}
+
+/* COMM pseudo-op */
+
+void pcomm(void)
+{
+    if (label == NUL_PTR)
+       labelerror(MISLAB);
+    else if (label->type & VARBIT)
+       labelerror(VARLAB);     /* variable cannot be COMM'd */
+    else
+       docomm();
+}
+
+/* .COMM pseudo-op */
+
+void pcomm1(void)
+{
+    static unsigned oldseg;
+
+    if (label != NUL_PTR)
+       labelerror(ILLAB);
+    oldseg = lcdata & SEGM;
+    setloc(BSSLOC);
+    if ((label = needlabel()) != NUL_PTR && checksegrel(label))
+    {
+       /* Like import. */
+       if (label->type & (EXPBIT | LABIT))
+           error(ALREADY);
+       else if( last_pass == 1 )
+           label->data = lcdata | (FORBIT | IMPBIT | RELBIT);
+       else
+           label->data = lcdata | (IMPBIT | RELBIT);
+       getsym();
+       getcomma();
+       if (label->type & (EXPBIT | LABIT))
+           absexpres();        /* just to check it */
+       else
+           docomm();
+    }
+    setloc(oldseg);
+}
+
+/* .DATA pseudo-op */
+
+void pdata(void)
+{
+    setloc(DATALOC);
+}
+
+/* ELSE pseudo-op */
+
+void pelse(void)
+{
+    if (iflevel == 0)
+       error(ELSEBAD);
+    else
+    {
+       ifflag = FALSE;         /* assume ELSE disabled */
+       if (elseflag)
+       {
+           ifflag = TRUE;      /* ELSE enabled */
+           elseflag = FALSE;
+       }
+    }
+}
+
+/* ELSEIF pseudo-op */
+
+void pelseif(void)
+{
+    doelseif(absexpres);
+}
+
+/* ELSEIFC pseudo-op */
+
+void pelsifc(void)
+{
+    doelseif(scompare);
+}
+
+/* ENDB pseudo-op */
+
+void pendb(void)
+{
+    if (label != NUL_PTR)
+       labelerror(ILLAB);
+    if (blocklevel == 0)
+       error(ENDBBAD);
+    else
+    {
+       register struct block_s *blockp;
+
+       blockp = blockstak;
+       lcdata = blockp->data;
+       dirpag = blockp->dp;
+       accumulate_rmb(blockp->lc - lc);
+       lc = blockp->lc;
+       --blocklevel;
+       blockstak = blockp + 1;
+    }
+}
+
+/* ENDIF pseudo-op */
+
+void pendif(void)
+{
+    if (iflevel == 0)
+       error(ENDIFBAD);
+    else
+    {
+       ifflag = ifstak->ifflag;
+       elseflag = ifstak->elseflag;
+       ++ifstak;
+       --iflevel;
+    }
+}
+
+/* ENTER pseudo-op */
+
+void penter(void)
+{
+    if (!(pedata & UNDBIT))
+       error(REENTER);
+    else
+    {
+       if (!((pedata = (pedata & ~UNDBIT) | lcdata) & UNDBIT))
+       {
+           progent = lc;
+           popflags = POPLC;
+       }
+    }
+}
+
+/* ENTRY pseudo-op */
+
+void pentry(void)
+{
+    doentexp(ENTBIT, 0);
+}
+
+/* EQU pseudo-op */
+
+void pequ(void)
+{
+    register struct sym_s *labptr;
+
+    if ((labptr = label) == NUL_PTR)
+       labelerror(MISLAB);
+    else if (labptr->type & COMMBIT)
+       showredefinedlabel();   /* common cannot be EQU'd */
+    else if (labptr->type & VARBIT)
+       labelerror(VARLAB);     /* variable cannot be EQU'd */
+    else
+       doequset(LABIT);
+}
+
+/* .EVEN pseudo-op */
+
+void peven(void)
+{
+    popflags = POPLONG | POPHI | POPLO | POPLC;
+    accumulate_rmb(lcjump = lastexp.data = lc & 1);
+}
+
+/* EXPORT pseudo-op */
+
+void pexport(void)
+{
+    doentexp(0, 0);
+}
+
+/* FAIL pseudo-op */
+
+void pfail(void)
+{
+    if(pass==last_pass) error(FAILERR);
+}
+
+/* FCB pseudo-op */
+
+void pfcb(void)
+{
+    char *bufptr;
+    offset_t firstbyte;
+
+    bufptr = databuf.fcbuf;
+    absexpres();
+    firstbyte = lastexp.offset;
+    while (TRUE)
+    {
+       checkdatabounds();
+       *bufptr++ = lastexp.offset;
+       ++mcount;               /* won't overflow, line length limits it */
+       if (sym != COMMA)
+           break;
+       symabsexpres();
+    }
+    lastexp.offset = firstbyte;
+    popflags = POPLO | POPLC;
+    fcflag = TRUE;
+}
+
+/* FCC pseudo-op */
+
+void pfcc(void)
+{
+    dofcc();
+    if (mcount != 0)
+    {
+       fcflag = TRUE;
+       popflags = POPLO | POPLC;
+    }
+}
+
+/* FDB pseudo-op */
+
+void pfdb(void)
+{
+    struct address_s *adrptr;
+    unsigned firstdata;
+    offset_t firstword;
+
+    adrptr = databuf.fdbuf;
+    expres();
+    firstword = lastexp.offset;
+    firstdata = lastexp.data;
+    while (TRUE)
+    {
+       *adrptr++ = lastexp;
+       mcount += 2;            /* won't overflow, line length limits it */
+       if (sym != COMMA)
+           break;
+       symexpres();
+    }
+    lastexp.offset = firstword;
+    lastexp.data = firstdata;
+    popflags = POPHI | POPLO | POPLC;
+    fdflag = TRUE;
+}
+
+#if SIZEOF_OFFSET_T > 2
+
+/* FQB pseudo-op */
+
+void pfqb(void)
+{
+    struct address_s *adrptr;
+    offset_t firstdata;
+    offset_t firstword;
+
+    adrptr = databuf.fqbuf;
+    expres();
+    firstword = lastexp.offset;
+    firstdata = lastexp.data;
+    while (TRUE)
+    {
+       *adrptr++ = lastexp;
+       mcount += 4;            /* won't overflow, line length limits it */
+       if (sym != COMMA)
+           break;
+       symexpres();
+    }
+    lastexp.offset = firstword;
+    lastexp.data = firstdata;
+    popflags = POPLONG | POPHI | POPLO | POPLC;
+    fqflag = TRUE;
+}
+
+#endif /* SIZEOF_OFFSET_T > 2 */
+
+/* .GLOBL pseudo-op */
+
+void pglobl(void)
+{
+    if (binaryg)
+       error(NOIMPORT);
+    doentexp(0, IMPBIT);
+}
+
+/* IDENT pseudo-op (not complete) */
+
+void pident(void)
+{
+    if (sym != IDENT)
+       error(LABEXP);
+    else
+       getsym_nolookup();      /* should save ident string */
+}
+
+/* IF pseudo-op */
+
+void pif(void)
+{
+    doif(absexpres);
+}
+
+/* IFC pseudo-op */
+
+void pifc(void)
+{
+    doif(scompare);
+}
+
+/* IMPORT pseudo-op */
+
+void pimport(void)
+{
+    struct sym_s *symptr;
+
+    if (binaryg)
+       error(NOIMPORT);
+    while (TRUE)
+    {
+       if ((symptr = needlabel()) != NUL_PTR && checksegrel(symptr))
+       {
+           if (symptr->type & (COMMBIT | EXPBIT | LABIT))
+               /* IMPORT is null if label (to be) declared */
+               error(ALREADY);
+           else if( last_pass == 1 )
+               /* get current segment from lcdata, no need to mask rest */
+               symptr->data = lcdata | (FORBIT | IMPBIT | RELBIT);
+           else
+               symptr->data = lcdata | (IMPBIT | RELBIT);
+       }
+       getsym();
+       if (sym != COMMA)
+           break;
+       getsym();
+    }
+}
+
+/* LCOMM pseudo-op */
+
+void plcomm(void)
+{
+    lcommflag = TRUE;
+    pcomm();
+}
+
+/* .LCOMM pseudo-op */
+
+void plcomm1(void)
+{
+    lcommflag = TRUE;
+    pcomm1();
+}
+
+/* .LIST pseudo-op */
+
+void plist(void)
+{
+    bumpsem(&list, 1);
+}
+
+/* .NOLIST pseudo-op */
+
+void pnolist(void)
+{
+    bumpsem(&list, -1);
+}
+
+/* LOC pseudo-op */
+
+void ploc(void)
+{
+    if (label != NUL_PTR)
+       labelerror(ILLAB);
+    absexpres();
+    if (!(lastexp.data & UNDBIT))
+    {
+       if (lastexp.offset >= NLOC)
+           datatoobig();
+       else
+           setloc((unsigned) lastexp.offset);
+    }
+}
+
+/* .MACLIST pseudo-op */
+
+void pmaclist(void)
+{
+    bumpsem(&maclist, 1);
+}
+
+/* .MAP pseudo-op */
+
+void pmap(void)
+{
+    absexpres();
+    if (!(lastexp.data & UNDBIT))
+    {
+       mapnum = lastexp.offset;
+       popflags = POPLO;
+       if (lastexp.offset >= 0x100)
+           datatoobig();
+    }
+}
+
+/* ORG pseudo-op */
+
+void porg(void)
+{
+    if (label != NUL_PTR)
+       labelerror(ILLAB);
+    absexpres();
+    if (!((lcdata = lastexp.data) & UNDBIT))
+    {
+       accumulate_rmb(lastexp.offset - lc);
+       binmbuf = lc = lastexp.offset;
+       binmbuf_set = 1;
+       popflags = POPLC;
+    }
+}
+
+/* RMB pseudo-op */
+
+void prmb(void)
+{
+    constdata(1);
+}
+
+/* .SECT pseudo-op */
+
+void psect(void)
+{
+    if (label != NUL_PTR)
+       labelerror(ILLAB);
+    while (sym == IDENT)
+    {
+       if (!(gsymptr->type & MNREGBIT))
+           error(ILL_SECTION);
+       else switch (gsymptr->value_reg_or_op.op.routine)
+       {
+       case BSSOP:
+           pbss();
+           break;
+       case DATAOP:
+           pdata();
+           break;
+       case TEXTOP:
+           ptext();
+           break;
+       default:
+           error(ILL_SECTION);
+           break;
+       }
+       getsym();
+       if (sym == COMMA)
+           getsym();
+    }
+}
+
+/* SET pseudo-op */
+
+void pset(void)
+{
+    register struct sym_s *labptr;
+
+    if ((labptr = label) == NUL_PTR)
+       labelerror(MISLAB);
+    else if (labptr->type & COMMBIT)
+       labelerror(RELAB);      /* common cannot be SET'd */
+    else
+       doequset(labptr->type & LABIT ? 0 : VARBIT);
+}
+
+/* SETDP pseudo-op */
+
+void psetdp(void)
+{
+    absexpres();
+    if (!(lastexp.data & UNDBIT))
+    {
+       dirpag = lastexp.offset;
+       popflags = POPLO;
+       if (lastexp.offset >= 0x100)
+           datatoobig();
+    }
+}
+
+/* .TEXT pseudo-op */
+
+void ptext(void)
+{
+    if( textseg <= 0 )
+       setloc(TEXTLOC);
+    else
+       setloc(textseg);
+}
+
+/* .WARN pseudo-op */
+
+void pwarn(void)
+{
+    bumpsem(&as_warn, -1);
+}
+
+#ifdef I80386
+
+/* USE16 pseudo-op */
+
+void puse16(void)
+{
+    defsize = 2;
+#ifdef iscpu
+    if( sym != EOLSYM )
+    {
+       absexpres();
+       if (lastexp.data & UNDBIT)
+           return;
+        if( lastexp.offset > 8000 )
+          setcpu((int) lastexp.offset / 100 % 10);
+        else if( lastexp.offset > 15 )
+          setcpu((int) lastexp.offset / 100);
+       else
+          setcpu((int) lastexp.offset);
+    }
+#endif
+}
+
+/* USE16 pseudo-op */
+
+void puse32(void)
+{
+    defsize = 4;
+#ifdef iscpu
+    if(!iscpu(3)) setcpu(3);
+    if( sym != EOLSYM )
+    {
+       absexpres();
+       if (lastexp.data & UNDBIT)
+           return;
+        if( lastexp.offset > 15 )
+          setcpu((int) lastexp.offset / 100);
+       else
+          setcpu((int) lastexp.offset);
+    }
+#endif
+}
+
+#endif
+
+/* show redefined label and error, and set REDBIT */
+
+static void showredefinedlabel(void)
+{
+    register struct sym_s *labptr;
+
+    labptr = label;            /* showlabel() will kill label prematurely */
+    showlabel();
+    if (!(labptr->type & REDBIT))
+    {
+       labptr->type |= REDBIT;
+       labelerror(RELAB);
+    }
+}
+
+void showlabel(void)
+{
+    register struct sym_s *labptr;
+
+    labptr = label;
+    lastexp.data = labptr->data;
+    lastexp.offset = labptr->value_reg_or_op.value;
+    popflags = POPLONG | POPHI | POPLO;
+    label = NUL_PTR;           /* show handled by COMM, EQU or SET */
+}
+
+/* set location segment */
+
+static void setloc(unsigned seg)
+{
+    if (pass == last_pass && seg != (lcdata & SEGM))
+       putobj((opcode_pt) (seg | OBJ_SET_SEG));
+    {
+       register struct lc_s *lcp;
+
+       lcp = lcptr;
+       lcp->data = lcdata;
+       lcp->lc = lc;
+       lcptr = lcp = lctab + (unsigned char) seg;
+       lcdata = (lcp->data & ~SEGM) | (unsigned char) seg;
+       binmbuf = lc = lcp->lc;
+       popflags = POPLC;
+    }
+}
diff --git a/Applications/as09/proto.h b/Applications/as09/proto.h
new file mode 100644 (file)
index 0000000..3878633
--- /dev/null
@@ -0,0 +1,233 @@
+/* extern functions */
+
+/* as.c */
+int main(int argc, char **argv);
+void as_abort(char *message);
+void finishup(void);
+void initp1p2(void);
+void line_zero(void);
+
+/* assemble.c */
+void assemble(void);
+
+/* express.c */
+void absexpres(void);
+void chkabs(void);
+void nonimpexpres(void);
+void showrelbad(void);
+void symabsexpres(void);
+void symexpres(void);
+void expres(void);
+void factor(void);
+void scompare(void);
+
+/* genbin.c */
+void binheader(void);
+void bintrailer(void);
+void genbin(void);
+void initbin(void);
+void putbin(int ch);
+
+/* genlist.c */
+char *build_2hex_number(unsigned num, char *where);
+char *build_number(unsigned num, unsigned width, char *where);
+void warning(char * errorstr);
+void error(char * errorstr);
+void listline(void);
+void writec(char ch);
+void writenl(void);
+void writeoff(offset_t offset);
+void writes(const char *s);
+void writesn(const char *s);
+void writew(unsigned word);
+
+/* genobj.c */
+void accumulate_rmb(offset_t offset);
+void flushobj(void);
+void genobj(void);
+void initobj(void);
+void objheader(void);
+void objtrailer(void);
+void putabs(opcode_pt ch);
+void putobj(opcode_pt ch);
+
+/* gensym.c */
+void gensym(void);
+
+/* macro.c */
+void entermac(struct sym_s *symptr);
+void pmacro(void);
+
+/* mops.c */
+#ifdef I80386
+void mbcc(void);
+void mbswap(void);
+void mcall(void);
+void mcalli(void);
+void mdivmul(void);
+void menter(void);
+void mEwGw(void);
+void mExGx(void);
+void mf_inher(void);
+void mf_m(void);
+void mf_m2(void);
+void mf_m2_ax(void);
+void mf_m2_m4(void);
+void mf_m2_m4_m8(void);
+void mf_m4_m8_optst(void);
+void mf_m4_m8_st(void);
+void mf_m4_m8_stst(void);
+void mf_m4_m8_m10_st(void);
+void mf_m10(void);
+void mf_optst(void);
+void mf_st(void);
+void mf_stst(void);
+void mf_w_inher(void);
+void mf_w_m(void);
+void mf_w_m2(void);
+void mf_w_m2_ax(void);
+void mgroup1(void);
+void mgroup2(void);
+void mgroup6(void);
+void mgroup7(void);
+void mgroup8(void);
+void mGvEv(void);
+void mGvMa(void);
+void mGvMp(void);
+void mimul(void);
+void min(void);
+void mincdec(void);
+void minher(void);
+void minher16(void);
+void minher32(void);
+void minhera(void);
+void mint(void);
+void mjcc(void);
+void mjcxz(void);
+void mlea(void);
+void mmov(void);
+void mmovx(void);
+void mnegnot(void);
+void mout(void);
+void mpushpop(void);
+void mret(void);
+void mseg(void);
+void msetcc(void);
+void mshdouble(void);
+void mtest(void);
+void mxchg(void);
+#endif                         /* I80386 */
+
+#ifdef MC6809
+void mall(void);
+void malter(void);
+void mimmed(void);
+void mindex(void);
+void minher(void);
+void mlong(void);
+void msstak(void);
+void mswap(void);
+void mustak(void);
+#endif                         /* MC6809 */
+
+void getcomma(void);
+void mshort(void);
+
+/* pops.c */
+bool_pt checksegrel(struct sym_s *symptr);
+void checkdatabounds(void);
+void datatoobig(void);
+void fatalerror(char * errorstr);
+void labelerror(char * errorstr);
+void palign(void);
+void pasciz(void);
+void pblkw(void);
+void pblock(void);
+void pbss(void);
+void pcomm(void);
+void pcomm1(void);
+void pdata(void);
+void pelse(void);
+void pelseif(void);
+void pelsifc(void);
+void pendb(void);
+void pendif(void);
+void penter(void);
+void pentry(void);
+void pequ(void);
+void peven(void);
+void pexport(void);
+void pfail(void);
+void pfcb(void);
+void pfcc(void);
+void pfdb(void);
+#if SIZEOF_OFFSET_T > 2
+void pfqb(void);
+#endif
+void pglobl(void);
+void pident(void);
+void pif(void);
+void pifc(void);
+void pimport(void);
+void plcomm(void);
+void plcomm1(void);
+void plist(void);
+void pnolist(void);
+void ploc(void);
+void pmaclist(void);
+void pmap(void);
+void porg(void);
+void prmb(void);
+void psect(void);
+void pset(void);
+void psetdp(void);
+void ptext(void);
+void puse16(void);
+void puse32(void);
+void pwarn(void);
+void showlabel(void);
+
+/* readsrc.c */
+void initsource(void);
+fd_t open_input(char *name);
+void pget(void);
+void pproceof(void);
+void readline(void);
+void skipline(void);
+
+/* scan.c */
+void context_hexconst(void);
+void getsym(void);
+void getsym_nolookup(void);
+void initscan(void);
+
+/* table.c */
+void inst_keywords(void);
+struct sym_s *lookup(void);
+void statistics(void);
+
+/* type.c */
+#if defined(__m6809__) && defined(MC6809)
+#define NATIVE_ENDIAN
+extern inline u2_pt c2u2(char *buf) { return *((u2_pt *)buf); }
+extern inline u4_t c4u4(char *buf) { return *((u4_t *)buf); }
+extern inline void u2c2(char *buf, u2_t offset) { *((unsigned short *)buf) = offset;}
+extern inline void u4c4(char *buf, u4_t offset) { *((unsigned long *)buf) = offset;}
+#else
+u2_pt c2u2(char *buf);
+u4_t c4u4(char *buf);
+void u2c2(char *buf, u2_t offset);
+void u4c4(char *buf, u32_T offset);
+#endif
+u2_pt cnu2(char *buf, unsigned count);
+u4_t cnu4(char *buf, unsigned count);
+void u2cn(char *buf, u16_pt offset, unsigned count);
+void u4cn(char *buf, u32_T offset, unsigned count);
+bool_pt typeconv_init(bool_pt big_endian, bool_pt long_big_endian);
+
+/* alloc.c */
+void * asalloc(unsigned int size);
+void * asrealloc(void * oldptr, unsigned int size);
+void * temp_buf(void);
+void init_heap(void);
+
diff --git a/Applications/as09/readsrc.c b/Applications/as09/readsrc.c
new file mode 100644 (file)
index 0000000..79b53e4
--- /dev/null
@@ -0,0 +1,494 @@
+/* readsrc.c - read source files for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "flag.h"
+#include "file.h"
+#include "globvar.h"
+#include "macro.h"
+#include "scan.h"
+#undef EXTERN
+#define EXTERN
+#include "source.h"
+
+/*
+ * Ok, lots of hack & slash here.
+ * 1) Added BIG buffer to load entire _primary_ file into memory.
+ * 2) This means the primary file can be standard input.
+ * 3) Fixed so 'get/include' processing now works.
+ * 4) Altered for a 'normal' style buffer otherwise (MINIBUF)
+ * 5) Have the option of completely unbuffered if you need the last Kb.
+ *
+ * RDB.
+ */
+
+#if !defined(__AS386_16__) && !defined(__m6809__)
+#ifndef BIGBUFFER
+#define BIGBUFFER      1       /* For most machines we have the memory */
+#endif
+#endif
+
+#if !defined(__m6809__)
+#ifndef MINIBUF
+#define MINIBUF                1       /* Add in a reasonable buffer */
+#endif
+#endif
+
+struct get_s                   /* to record included files */
+{
+    fd_t fd;
+    unsigned line;
+    off_t position;
+};
+
+static char hid_filnambuf[FILNAMLEN + 1];      /* buffer for file name */
+
+static struct get_s hid_getstak[MAXGET];       /* GET stack */
+static struct get_s *getstak;  /* ptr */
+
+#if BIGBUFFER == 1
+static char *mem_start = 0, *mem_end;
+#endif
+
+static char hid_linebuf[LINLEN];       /* line buffer */
+static char *eol_ptr;
+
+static char *maclinebuf;
+static char *maclineptr;
+
+#if MINIBUF == 1
+static void inp_seek(int fd, long posn);
+static long inp_tell(int fd);
+static int inp_line(int fd, char * buf, int size);
+#endif
+
+static void clearsource(void);
+static void line_too_long(void);
+
+static void clearsource(void)
+{
+}
+
+static void line_too_long(void)
+{
+    symname = linebuf + (LINLEN - 1);  /* spot for the error */
+    error(LINLONG);            /* so error is shown in column LINLEN - 1 */
+}
+
+/* initialise private variables */
+
+void initsource(void)
+{
+    filnamptr = hid_filnambuf;
+    getstak = hid_getstak;
+    clearsource();             /* sentinel to invoke blank skipping */
+}
+
+fd_t open_input(char *name)
+{
+    fd_t fd;
+#if BIGBUFFER == 1
+    off_t filelength = -1;
+
+    if( mem_start == 0 && strcmp(name, "-") == 0 )
+       fd = 0;
+    else
+#endif
+#ifdef O_BINARY
+    if ((unsigned) (fd = open(name, O_RDONLY|O_BINARY)) > 255)
+       as_abort("error opening input file");
+#else
+    if ((unsigned) (fd = open(name, O_RDONLY)) > 255)
+       as_abort("error opening input file");
+#endif
+
+#if BIGBUFFER == 1
+    if( mem_start == 0 )
+    {
+       size_t memsize = 0;
+       int cc;
+
+       if(fd)
+       {
+          struct stat st;
+          if( fstat(fd, &st) >= 0 )
+             filelength = st.st_size;
+          if( filelength > (((unsigned)-1)>>1)-3 )
+          {
+             mem_end = mem_start = "\n\n";
+             goto cant_do_this;
+          }
+       }
+
+       if (filelength > 0) {
+          if( (mem_start = malloc(filelength+4)) == 0 )
+          {
+             mem_end = mem_start = "\n\n";
+             goto cant_do_this;
+          }
+          memsize = filelength;
+
+          filelength = read(fd, mem_start, filelength);
+       } else
+          filelength = 0;
+
+       for(;;)
+       {
+           if( filelength >= memsize )
+           {
+               if (memsize > 16000)
+                   mem_start = asrealloc(mem_start, (memsize+=16384)+4);
+               else
+                   mem_start = asrealloc(mem_start, (memsize+=memsize+32)+4);
+           }
+           cc = read(fd, mem_start+filelength,
+                         (size_t)(memsize-filelength));
+           if( cc <= 0 ) break;
+           filelength+=cc;
+       }
+
+       *(mem_end=mem_start+filelength) = '\n';
+       mem_end[1] = '\0';
+
+       infiln = infil0 = 0;    /* Assemble from memory */
+       if(fd) close(fd);
+       fd = -1;
+    }
+cant_do_this:
+#endif
+
+    clearsource();
+    return fd;
+}
+
+/*
+  handle GET pseudo_op
+  stack state of current file, open new file and reset global state vars
+  file must be seekable for the buffer discard/restore method to work
+*/
+
+void pget(void)
+{
+    if (infiln >= MAXGET)
+       error(GETOV);
+    else
+    {
+       char save;
+
+       skipline();
+       listline();
+
+       getstak->fd = infil;
+       getstak->line = linum;
+       if (infiln != 0)
+#if MINIBUF == 1
+           getstak->position = inp_tell(infil);
+#else
+           getstak->position = lseek(infil, 0L, 1);
+#endif
+       else
+           getstak->position = (off_t)eol_ptr;
+       ++getstak;
+       ++infiln;
+       linum = 0;
+
+       for(lineptr=symname; *lineptr != EOLCHAR; lineptr++)
+          if( *lineptr <= ' ' ) break;
+       save = *lineptr; *lineptr = '\0';
+       infil = open_input(symname);
+       *lineptr = save;
+       getsym();
+    }
+}
+
+/* process end of file */
+/* close file, unstack old file if current one is included */
+/* otherwise switch pass 0 to pass 1 or exit on pass 2 */
+/* end of file may be from phyical end of file or an END statement */
+
+void pproceof(void)
+{
+    if (infiln != 0)
+       close(infil);
+    if (infiln == infil0)
+       /* all conditionals must be closed before end of main file (not GETs) */
+    {
+       if (blocklevel != 0)
+           error(EOFBLOCK);
+       if (iflevel != 0)
+           error(EOFIF);
+       if (pass && (lcdata & UNDBIT))
+           error(EOFLC);
+       lcptr->data = lcdata;
+       lcptr->lc = lc;
+    }
+    /* macros must be closed before end of all files */
+    if (macload)
+       error(EOFMAC);
+    if (linebuf != lineptr)
+        listline();            /* last line or line after last if error */
+    if (infiln != infil0)
+    {
+       --getstak;
+       infil = getstak->fd;
+       linum = getstak->line;
+       if (--infiln == 0)
+           eol_ptr = (void*)getstak->position;
+       else
+#if MINIBUF == 1
+           inp_seek(infil, getstak->position);
+#else
+           lseek(infil, getstak->position, 0);
+#endif
+    }
+    else if (pass!=last_pass)
+    {
+       pass++;
+       if( last_pass>1 && last_pass<30 && dirty_pass && pass==last_pass )
+          last_pass++;
+
+       if( pass==last_pass )
+          objheader();         /* while pass 1 data all valid */
+       binmbuf = 0;            /* reset zero variables */
+       maclevel = iflevel = blocklevel =
+           totwarn = toterr = linum = macnum = 0;
+       initp1p2();             /* reset other varaiables */
+       if(pass==last_pass)
+          binaryc = binaryg;
+#ifdef I80386
+       defsize = idefsize;
+       cpuid = origcpuid;
+#endif
+       if(pass==last_pass)
+       {
+          list.current = list.global;
+          maclist.current = maclist.global;
+          as_warn.current = TRUE;
+          if (as_warn.semaphore < 0)
+              as_warn.current = FALSE;
+       }
+
+       if (infiln != 0)
+           infil = open_input(filnamptr);
+        else
+           eol_ptr=0;
+
+       if(pass==last_pass)
+          binheader();
+
+       line_zero();
+    }
+    else
+       finishup();
+}
+
+/*
+  read 1 line of source.
+  Source line ends with '\n', line returned is null terminated without '\n'.
+  Control characters other than blank, tab and newline are discarded.
+  Long lines (length > LINLEN) are truncated, and an error is generated.
+  On EOF, calls pproceof(), and gets next line unless loading a macro.
+  This is where macro lines are recursively expanded.
+*/
+
+void readline(void)
+{
+    int cc = 0;
+
+    listpre = FALSE;           /* not listed yet */
+    if (maclevel != 0)
+    {
+      register char *bufptr;   /* hold *bufptr in a reg char variable */
+      register char *reglineptr;       /* if possible (not done here) */
+      char *oldbufptr;
+      struct schain_s *parameters;
+      char paramnum;
+      unsigned int remaining;  /* space remaining in line + 2 */
+                               /* value 0 not used except for temp predec */
+                               /* value 1 means error already gen */
+                               /* values 1 and 2 mean no space */
+
+      for (; maclevel != 0;
+            macpar = macstak->parameters, ++macstak, --maclevel)
+       if (*(bufptr = macstak->text) != ETB)
+ /* nonempty macro, process it and return without continuing the for loop */
+       {
+           if (!macflag)
+           {
+               maclinebuf = linebuf;
+               maclineptr = lineptr;
+               macflag = TRUE;
+           }
+           remaining = LINLEN + 2;
+           lineptr = linebuf = reglineptr = hid_linebuf;
+           while (*bufptr++ != EOLCHAR)
+           {
+               if (bufptr[-1] == MACROCHAR && *bufptr >= '0' && *bufptr <= '9')
+               {
+                   parameters = macstak->parameters;
+                   for (paramnum = *bufptr++; paramnum-- != '0';)
+                       if ((parameters = parameters->next) == NUL_PTR)
+                           break;
+                   if (parameters != NUL_PTR)
+                   {
+                       for (oldbufptr = bufptr, bufptr = parameters->string;
+                            *bufptr++ != 0;)
+                       {
+                           if (--remaining <= 1)
+                           {
+                               if (remaining != 0)
+                                   line_too_long();
+                               remaining = 1;
+                               break;  /* forget rest, param on 1 line */
+                           }
+                           *reglineptr++ = bufptr[-1];
+                       }
+                       bufptr = oldbufptr;
+                   }
+               }
+               else
+               {
+                   if (--remaining <= 1)
+                   {
+                       if (remaining != 0)
+                           line_too_long();
+                       remaining = 1;
+                   }
+                   else
+                       *reglineptr++ = bufptr[-1];
+               }
+           }
+           macstak->text = bufptr;
+#if 0
+            *reglineptr = 0;
+            printf("MLINE:%s.\n", lineptr);
+#endif
+           *reglineptr = EOLCHAR;
+           return;
+       }
+    }
+    if (macflag)
+    {
+       linebuf = maclinebuf;
+       lineptr = maclineptr;
+       macflag = FALSE;
+    }
+    /* End of macro expansion processing */
+
+again: /* On EOF for main or included files */
+    ++linum;
+
+#if BIGBUFFER == 1
+    if( infiln == 0 )
+    {
+       if( eol_ptr == 0 ) eol_ptr = mem_start-1;
+       else *eol_ptr = '\n';
+       linebuf = lineptr = eol_ptr + 1;
+       cc = (mem_end - linebuf);
+
+       /* memchr not strchr 'cause some implementations of strchr are like:
+         memchr(x,y,strlen(x)); this is _BAD_ with BIGBUFFER
+       */
+       if((eol_ptr = memchr(linebuf, '\n', cc)) == 0 && cc > 0)
+          cc = -1;
+    }
+    else
+#endif
+    {
+       lineptr = linebuf = hid_linebuf;
+       *(hid_linebuf+sizeof(hid_linebuf)-2) = '\0';    /* Term */
+
+#if MINIBUF == 1
+       cc = inp_line(infil, linebuf, sizeof(hid_linebuf)-2);
+       if( cc >= 0 )
+          eol_ptr = linebuf+cc-1;
+#else
+       cc = read(infil, linebuf, sizeof(hid_linebuf)-2);
+       if( cc > 0 )
+       {
+          eol_ptr = memchr(linebuf, '\n', cc);
+         if( eol_ptr == 0 )
+            eol_ptr = hid_linebuf+sizeof(hid_linebuf)-2;
+         else
+            lseek(infil, (long)(eol_ptr+1-hid_linebuf)-cc, 1);
+       }
+#endif
+    }
+
+    if( cc <= 0 )
+    {
+        if( cc < 0 ) as_abort("error reading input");
+
+        clearsource();
+        pproceof();
+       listpre = FALSE;
+        if (macload)
+        {
+           symname = lineptr;
+           return;             /* macro not allowed across eof */
+        }
+        goto again;
+    }
+
+#if 0
+    *eol_ptr = 0;
+    printf("LINE:%s.\n", lineptr);
+#endif
+    *eol_ptr = EOLCHAR;
+}
+
+void skipline(void)
+{
+    if(macflag)
+        lineptr = strchr(hid_linebuf, EOLCHAR);
+    else
+        lineptr = eol_ptr;
+}
+
+#if MINIBUF == 1
+static char input_buf[1024];           /* input buffer */
+static int  in_start=0, in_end=0;
+static long ftpos = 0;
+static int  lastfd = -1;
+
+static int inp_line(int fd, char *buf, int size)
+{
+   int offt = 0;
+   if( fd!=lastfd ) inp_seek(-1, 0L);
+   for(;;)
+   {
+      if(in_start >= in_end)
+      {
+        lastfd = -1;
+         ftpos = lseek(fd, 0L, 1);
+        in_start = 0;
+         in_end = read(fd, input_buf, sizeof(input_buf));
+        if( in_end <=0 ) return in_end;
+        lastfd = fd;
+      }
+      if( (buf[offt++] = input_buf[in_start++]) == '\n' || offt >= size )
+         break;
+   }
+   return offt;
+}
+
+static long inp_tell(int fd)
+{
+   if( fd != lastfd )
+      return lseek(fd, 0L, 1);
+   else
+      return ftpos + in_start;
+}
+
+static void inp_seek(int fd, long posn)
+{
+   if( lastfd != -1 )
+      lseek(lastfd, ftpos+in_start, 0);
+   lastfd = -1;
+   in_end = 0;
+   if( fd >= 0 )
+      lseek(fd, posn, 0);
+}
+
+#endif
diff --git a/Applications/as09/scan.c b/Applications/as09/scan.c
new file mode 100644 (file)
index 0000000..0115677
--- /dev/null
@@ -0,0 +1,252 @@
+/* scan.c - lexical analyser for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "globvar.h"
+#undef EXTERN
+#define EXTERN
+#include "scan.h"
+
+static int numbase;            /* base for number */
+
+static char symofchar[256] =   /* table to convert chars to their symbols */
+{
+    EOLSYM, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, EOLSYM, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+
+    WHITESPACE, EOLSYM, STRINGCONST, IMMEDIATE,        /*  !"# */
+    HEXCONST, BINCONST, ANDOP, CHARCONST,      /* $%&' */
+    LPAREN, RPAREN, STAR, ADDOP,               /* ()*+ */
+    COMMA, SUBOP, IDENT, SLASH,                        /* ,-./ */
+
+    INTCONST, INTCONST, INTCONST, INTCONST,    /* 0123 */
+    INTCONST, INTCONST, INTCONST, INTCONST,    /* 4567 */
+    INTCONST, INTCONST, COLON, EOLSYM,         /* 89:; */
+    LESSTHAN, EQOP, GREATERTHAN, MACROARG,     /* <=>? */
+
+    INDIRECT, IDENT, IDENT, IDENT,             /* @ABC */
+    IDENT, IDENT, IDENT, IDENT,                        /* DEFG */
+    IDENT, IDENT, IDENT, IDENT,                        /* HIJK */
+    IDENT, IDENT, IDENT, IDENT,                        /* LMNO */
+    IDENT, IDENT, IDENT, IDENT,                        /* PQRS */
+    IDENT, IDENT, IDENT, IDENT,                        /* TUVW */
+    IDENT, IDENT, IDENT, LBRACKET,             /* XYZ[ */
+    OTHERSYM, RBRACKET, OTHERSYM, IDENT,       /* \]^_ */
+
+    OTHERSYM, IDENT, IDENT, IDENT,             /* `abc */
+    IDENT, IDENT, IDENT, IDENT,                        /* defg */
+    IDENT, IDENT, IDENT, IDENT,                        /* hijk */
+    IDENT, IDENT, IDENT, IDENT,                        /* lmno */
+    IDENT, IDENT, IDENT, IDENT,                        /* pqrs */
+    IDENT, IDENT, IDENT, IDENT,                        /* tuvw */
+    IDENT, IDENT, IDENT, OTHERSYM,             /* xyz{ */
+    OROP, OTHERSYM, NOTOP, OTHERSYM,           /* |}~  */
+
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+    WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE
+};
+
+static void intconst P((void));
+
+void context_hexconst(void)
+{
+    numbase = 16;
+    intconst();
+}
+
+void getsym(void)
+{
+    register char *reglineptr;
+
+    reglineptr = lineptr;
+advance:
+    symname = reglineptr;
+    switch (sym = symofchar[(unsigned char) *reglineptr++])
+    {
+    case WHITESPACE:
+       goto advance;
+    case ADDOP:
+       if (*reglineptr == '+')
+       {
+           sym = POSTINCOP;
+           ++reglineptr;
+       }
+       break;
+    case BINCONST:
+       numbase = 2;
+       lineptr = reglineptr;
+       intconst();
+       return;
+    case CHARCONST:
+       if ((number = *reglineptr) < ' ')
+           number = ' ';
+       if (*reglineptr != EOL)
+           ++reglineptr;
+       sym = INTCONST;
+       break;
+    case GREATERTHAN:          /* context-sensitive */
+       if (*reglineptr == '>')
+       {
+           sym = SROP;
+           ++reglineptr;
+       }
+       break;
+    case HEXCONST:
+       numbase = 16;
+       lineptr = reglineptr;
+       intconst();
+       return;
+    case IDENT:
+       /* walk to end of identifier - magic INTCONST is max of INT, IDENT */
+       while (symofchar[(unsigned char) *reglineptr] <= INTCONST)
+           ++reglineptr;
+       lineptr = reglineptr;
+       gsymptr = lookup();
+       return;
+    case INTCONST:
+       if (*(reglineptr - 1) == '0')
+       {
+           if (*reglineptr != 'x' && *reglineptr != 'X')
+               numbase = 8;
+           else
+           {
+               numbase = 16;
+               ++reglineptr;
+           }
+       }
+       else
+       {
+           --reglineptr;
+           numbase = 10;
+       }
+       lineptr = reglineptr;
+       intconst();
+       return;
+    case LESSTHAN:             /* context-sensitive */
+       if (*reglineptr == '<')
+       {
+           sym = SLOP;
+           ++reglineptr;
+       }
+       break;
+    case SUBOP:
+       if (*reglineptr == '-')
+       {
+           sym = PREDECOP;
+           ++reglineptr;
+       }
+       break;
+    }
+    lineptr = reglineptr;
+    return;
+}
+
+void getsym_nolookup(void)
+{
+    bool_t old_ifflag;
+
+    old_ifflag = ifflag;
+    ifflag = FALSE;
+    getsym();
+    ifflag = old_ifflag;
+}
+
+static void intconst(void)
+{
+    register char *reglineptr;
+
+    number = 0;
+    reglineptr = lineptr;
+    for (; *reglineptr >= '0'; ++reglineptr)
+    {
+       if (*reglineptr > '9')
+       {
+           if (numbase != 16)
+               break;
+           if (*reglineptr >= 'a' && *reglineptr <= 'f')
+           {
+               if (number != 0)
+                   number = numbase * number + (*reglineptr - 'a' + 10);
+               else
+                   number = *reglineptr - 'a' + 10;
+           }
+           else if (*reglineptr >= 'A' && *reglineptr <= 'F')
+           {
+               if (number != 0)
+                   number = numbase * number + (*reglineptr - 'A' + 10);
+               else
+                   number = *reglineptr - 'A' + 10;
+           }
+           else
+               break;
+       }
+       else if (number != 0)
+           number = numbase * number + (*reglineptr - '0');
+       else
+           number = *reglineptr - '0';
+    }
+    if (*reglineptr == 'L' || *reglineptr == 'l')
+       ++reglineptr;
+    sym = INTCONST;
+    lineptr = reglineptr;
+}
+
+void initscan(void)
+{
+#ifndef MC6809
+    if (asld_compatible)
+    {
+       lindirect = LPAREN;
+       rindexp = RPEXP;
+       rindirect = RPAREN;
+    }
+    else
+    {
+#endif
+       lindirect = LBRACKET;
+       rindexp = RBEXP;
+       rindirect = RBRACKET;
+#ifndef MC6809
+    }
+#endif
+}
diff --git a/Applications/as09/scan.h b/Applications/as09/scan.h
new file mode 100644 (file)
index 0000000..baffefb
--- /dev/null
@@ -0,0 +1,12 @@
+/* scan.h - global variables for scanner for assembler */
+
+#define EOLCHAR '\n'
+
+EXTERN struct sym_s *gsymptr;  /* global symbol ptr */
+EXTERN char lindirect;         /* left symbol for indirect addressing */
+EXTERN char *lineptr;          /* current line position */
+EXTERN offset_t number;        /* constant number */
+EXTERN char * rindexp;         /* error code for missing rindirect */
+EXTERN char rindirect;         /* right symbol for indirect addressing */
+EXTERN char sym;               /* current symbol */
+EXTERN char *symname;          /* current symbol name */
diff --git a/Applications/as09/source.h b/Applications/as09/source.h
new file mode 100644 (file)
index 0000000..0181e54
--- /dev/null
@@ -0,0 +1,4 @@
+/* source.h - global variables for source handlers for assembler */
+
+EXTERN unsigned linum;         /* line # */
+EXTERN bool_t listpre;         /* flag to show line has already been listed */
diff --git a/Applications/as09/syshead.h b/Applications/as09/syshead.h
new file mode 100644 (file)
index 0000000..82d2cc9
--- /dev/null
@@ -0,0 +1,62 @@
+
+#ifndef POSIX_HEADERS_MISSING
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#endif
+
+#ifndef STDC_HEADERS_MISSING
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#endif
+
+#ifdef MSDOS
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <io.h>
+#undef min
+#undef POSIX_HEADERS_MISSING
+#define VERSION "MSDOS Compile"
+#endif
+
+#if __STDC__ && !defined(__minix)
+#define P(x) x
+#else
+#define P(x) ()
+#endif
+
+#ifdef STDC_HEADERS_MISSING
+char *strcpy P((char *s1, const char *s2));
+char *strrchr P((const char *s, int c));
+int memcmp P((const void *s1, const void *s2, unsigned n));
+int strcmp P((const char *s1, const char *s2));
+int strncmp P((const char *s1, const char *s2, unsigned n));
+unsigned strlen P((const char *s));
+void *malloc P((unsigned size));
+void *memset P((void *s, int c, unsigned n));
+void exit P((int status));
+#endif
+
+#ifdef POSIX_HEADERS_MISSING
+int close P((int fd));
+int creat P((const char *path, int mode));
+int open P((const char *path, int oflag, ...));
+int read P((int fd, void *buf, unsigned nbytes));
+int write P((int fd, const void *buf, unsigned nbytes));
+typedef long off_t;
+off_t lseek P((int fd, off_t offset, int whence));
+#define BIGBUFFER      0       /* Can't use a big buffer ... sorry */
+#endif
+
+#ifndef O_RDONLY
+#define O_RDONLY       0
+#endif
+#ifndef O_WRONLY
+#define O_WRONLY       1
+#endif
+#ifndef O_RDWR
+#define O_RDWR         2
+#endif
diff --git a/Applications/as09/table.c b/Applications/as09/table.c
new file mode 100644 (file)
index 0000000..fa135d8
--- /dev/null
@@ -0,0 +1,216 @@
+/* table.c - keyword tables and symbol table lookup for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "globvar.h"
+#include "opcode.h"
+#include "scan.h"
+
+#define hconv(ch) ((unsigned char) (ch) - 0x41)        /* better form for hashing */
+
+#ifdef I80386
+# ifdef MNSIZE
+EXTERN char bytesizeops[];
+# endif
+#endif
+EXTERN char ops[];
+EXTERN char page1ops[];
+EXTERN char page2ops[];
+EXTERN char regs[];
+#ifdef I80386
+EXTERN char typesizes[];
+#endif
+
+#ifdef DEBUG_HASH
+unsigned nhash;
+unsigned nlookup;
+unsigned nsym;
+unsigned nx[30];
+static void printchain P((void));
+#endif
+
+static void install P((register char *keyptr, unsigned char data));
+
+void inst_keywords()
+{
+    install(regs, REGBIT);
+#ifdef I80386
+    install(typesizes, SIZEBIT);
+#endif
+    install(ops, 0);
+    install(page1ops, PAGE1);
+    install(page2ops, PAGE2);
+#ifdef I80386
+# ifdef MNSIZE
+    install(bytesizeops, PAGE1 | PAGE2);
+# endif
+#endif
+}
+
+static void install(register char *keyptr, unsigned char data)
+{
+    char lowcasebuf[20];
+    unsigned namelength;
+    char *nameptr;
+    char *namend;
+    register struct sym_s *symptr;
+
+    while (*keyptr != 0)
+    {
+       namelength = *keyptr++;
+       lineptr = (symname = keyptr) + namelength;
+       for (nameptr = lowcasebuf, namend = lowcasebuf + namelength;
+            nameptr < namend;)
+       {
+           if (*keyptr < 'A' || *keyptr > 'Z')
+               *nameptr++ = *keyptr++;
+           else
+               *nameptr++ = *keyptr++ + ('a' - 'A');
+       }
+       symptr = lookup();
+       symptr->type = MNREGBIT;
+       symptr->data = data;
+       symptr->value_reg_or_op.op.routine = *keyptr;
+       symptr->value_reg_or_op.op.opcode = keyptr[1];
+       lineptr = (symname = lowcasebuf) + namelength;
+       symptr = lookup();
+       symptr->type = MNREGBIT;
+       symptr->data = data;
+       symptr->value_reg_or_op.op.routine = *keyptr;
+       symptr->value_reg_or_op.op.opcode = keyptr[1];
+       keyptr += 2;
+    }
+}
+
+/* Lookup() searches symbol table for the string from symname to lineptr - 1.
+ * If string is not found and ifflag is TRUE, string is added to table, with
+ *     type = 0
+ *     data = inidata (RELBIT | UNDBIT, possibly with IMPBIT | SEGM)
+ * Returns pointer to symbol entry (NUL_PTR if not found and not installed)
+ * unless symbol table overflows, when routine aborts.
+ */
+
+struct sym_s *lookup(void)
+{
+    struct sym_s **hashptr;
+    register char *nameptr;
+    register struct sym_s *symptr;
+    register unsigned hashval;
+    register unsigned length;
+#ifdef DEBUG_HASH
+    int tries;
+
+    ++nlookup;
+    tries = 0;
+#endif
+
+    /* Hash function is a weighted xor of 1 to 4 chars in the string.
+     * This works seems to work better than looking at all the chars.
+     * It is important that the function be fast.
+     * The string comparision function should also be fast and it helps
+     * if it is optimized for mostly identical comparisions.
+     * The multiplication by MULTIPLIER should compile as a shift.
+     */
+
+#define MULTIPLIER (SPTSIZ / (1 << USEFUL_BITS_IN_ASCII))
+#define USEFUL_BITS_IN_ASCII 6
+
+    nameptr = lineptr;
+    length = nameptr - symname;
+    if (length <= 3)
+    {
+       if (length <= 2)
+           hashval  = hconv(nameptr[-1]) * MULTIPLIER;
+       else
+           hashval  = hconv(nameptr[-2]) * MULTIPLIER,
+           hashval ^= hconv(nameptr[-1]);
+    }
+    else
+       hashval  = hconv(symname[length-(length / 2)]) * MULTIPLIER,
+       hashval ^= hconv(nameptr[-2]) << 2,
+       hashval ^= hconv(nameptr[-1]);
+    nameptr = symname;
+    if ((symptr = *(hashptr = spt +
+                             (hashval ^ (hconv(nameptr[0]) << 1)) % SPTSIZ))
+       != NUL_PTR)
+    {
+       do
+       {
+#ifdef DEBUG_HASH
+           if (tries != 0)
+               --nx[tries];
+           ++tries;
+           if (tries < sizeof nx / sizeof nx[0])
+               ++nx[tries];
+           if (tries >= 5)
+               printchain(hashptr - spt);
+#endif
+           if ((unsigned char) length != symptr->length)
+               continue;
+           if (memcmp(symptr->name, nameptr, length) == 0)
+               return symptr;
+       }
+       while ((symptr = symptr->next) != NUL_PTR);
+
+       /* Calculate last non-NUL_PTR hash ptr.
+        * This is faster than keeping hashptr up to date in previous loop
+        * since most lookups are successful and hash ptr is not needed.
+        */
+       do
+       {
+           symptr = *hashptr;
+           hashptr = &symptr->next;
+       }
+       while (symptr->next != NUL_PTR);
+    }
+    if (!ifflag)
+       return NUL_PTR;
+#ifdef DEBUG_HASH
+    ++nsym;
+    if (hashptr >= spt && hashptr < spt + SPTSIZ)
+       ++nhash;
+#endif
+    *hashptr = symptr = asalloc(sizeof(struct sym_s) + length);
+    symptr->type = 0;
+    symptr->data = inidata;
+    symptr->length = length;
+    symptr->value_reg_or_op.value = (offset_t) (symptr->next = NUL_PTR);
+    memcpy(symptr->name, nameptr, length);
+    symptr->name[length] = 0;
+    return symptr;
+}
+
+#ifdef DEBUG_HASH
+
+static void printchain(unsigned hashval)
+{
+    register struct sym_s *symptr;
+
+    printf("%04x ", hashval);
+    for (symptr = spt[hashval]; symptr != NUL_PTR; symptr = symptr->next)
+       printf("%s ", symptr->name);
+    printf("\n");
+}
+
+#endif
+
+void statistics(void)
+{
+#ifdef DEBUG_HASH
+    int i;
+    int weight;
+
+    for (i = 0; i < SPTSIZ; ++i)
+       printchain(i);
+    printf("nhash = %d, nsym = %d, nlookup = %d nx =\n", nhash, nsym, nlookup);
+    weight = 0;
+    for (i = 0; i < 30; ++i) 
+    {
+       printf("%5d", nx[i]);
+       weight += nx[i] * i;
+    }
+    printf("\n");
+    printf("weight = %d%d\n", weight);
+#endif
+}
diff --git a/Applications/as09/type.h b/Applications/as09/type.h
new file mode 100644 (file)
index 0000000..171790e
--- /dev/null
@@ -0,0 +1,171 @@
+/* type.h - types for assembler */
+
+typedef unsigned short u2_t;
+typedef unsigned u2_pt;
+typedef unsigned long u4_t;
+typedef unsigned long u4_pt;
+
+/* redefine foo_t's because their use has become non-portable */
+
+#define bool_t bool_T
+#define count_t count_T
+#define fd_t fd_T
+#define indcount_t indcount_T
+#define offset_t offset_T
+#define opcode_t opcode_T
+#define opsize_t opsize_T
+#define scale_t scale_T
+#define sem_t sem_T
+#define smallcount_t smallcount_T
+#define soffset_t soffset_T
+
+typedef unsigned char bool_t;
+typedef int bool_pt;
+typedef unsigned count_t;
+typedef int fd_t;
+typedef unsigned char indcount_t;
+#ifdef I80386
+typedef unsigned long offset_t;
+typedef long soffset_t;
+# define SIZEOF_OFFSET_T 4     /* non-portable */
+#endif
+#ifdef MC6809
+typedef unsigned offset_t;
+typedef int soffset_t;
+# define SIZEOF_OFFSET_T 2     /* but sizeof (offset_t) often breaks cpp */
+#endif
+typedef int opcode_pt;
+typedef unsigned char opcode_t;
+typedef int opsize_pt;
+typedef unsigned char opsize_t;
+typedef unsigned reg_pt;
+typedef unsigned char scale_t;
+typedef unsigned char smallcount_t;
+typedef /* signed */ char sem_t;
+typedef unsigned u16_pt;
+typedef unsigned short u16_T;
+typedef unsigned long u32_T;
+
+/* symbol table entry */
+
+struct sym_s
+{
+    struct sym_s *next;                /* next symbol in hash chain (NUL_PTR if none) */
+                               /* zero offset because it is accessed most */
+    unsigned char type;
+    unsigned char data;                /* flags valid for expressions as well as syms*/
+    union
+    {
+       offset_t value;         /* value, if sym is a label */
+       unsigned char reg;      /* register code, if sym is a register */
+       struct
+       {
+           unsigned char routine;      /* routine number */
+           opcode_t opcode;    /* opcode, if sym is a hardware op */
+       }
+           op;                 /* if sym is pseudo-op or hardware op */
+    }
+        value_reg_or_op;
+    unsigned char length;      /* length of symbol string */
+    char name[1];              /* string of variable length */
+};
+
+/* address */
+
+struct address_s
+{
+    offset_t offset;
+    unsigned char data;
+    struct sym_s *sym;
+};
+
+#ifdef I80386
+
+/* effective address */
+
+struct ea_s
+{
+    indcount_t indcount;
+    opsize_t size;
+    reg_pt base;
+    reg_pt index;
+    scale_t scale;
+    struct address_s displ;
+};
+
+#endif
+
+/* flags */
+
+struct flags_s
+{
+    bool_t global;
+    bool_t current;
+    int semaphore;
+};
+
+/* location counter */
+
+struct lc_s
+{
+    unsigned char data;
+    offset_t lc;
+};
+
+/* string chain */
+
+struct schain_s
+{
+    struct schain_s *next;
+    char string[2];            /* variable length */
+};
+
+/* block stack */
+
+struct block_s
+{
+    unsigned char data;
+    unsigned char dp;
+    offset_t lc;
+};
+
+/* if stack */
+
+struct if_s
+{
+    bool_t ifflag;
+    bool_t elseflag;
+};
+
+/* macro stack */
+
+struct macro_s
+{
+    char *text;
+    struct schain_s *parameters;
+};
+
+/* symbol listing format */
+
+struct sym_listing_s
+{
+    char name[SYMLIS_NAMELEN];
+    char zname[2];
+    char segm[1];
+    char pad1[1];
+    char value[4];
+    char pad2[1];
+    char ar[1];
+    char pad3[1];
+    char cein[1];
+    char pad4[1];
+    char nullterm;
+};
+
+#if __STDC__
+typedef void (*pfv)(void);
+#else
+typedef void (*pfv)();
+#endif
+
+#include "proto.h"
diff --git a/Applications/as09/typeconv.c b/Applications/as09/typeconv.c
new file mode 100644 (file)
index 0000000..2af5aff
--- /dev/null
@@ -0,0 +1,181 @@
+
+/*
+ * Type conversion routines, these have been rewritten for portability.
+ *
+ * The only requirement is now that the u2_t and u4_t must be big enough.
+ */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "globvar.h"
+
+#if defined(__m6809__) && defined(MC6809)
+#define NATIVE_ENDIAN
+#endif
+
+void xxerr P((char *));
+void xxerr(x) char * x; { write(2, x, strlen(x)); }
+
+#ifdef __AS386_16__
+static int no_swap   = 1;
+#endif
+
+static int long_off[4] = {0,1,2,3};
+static int int_off[2] = {0,1};
+
+bool_pt typeconv_init(bool_pt big_endian, bool_pt long_big_endian)
+{
+   int i;
+#ifdef __AS386_16__
+   no_swap = (!big_endian && !long_big_endian);
+#endif
+
+   for(i=0; i<4; i++) long_off[i] = i;
+   for(i=0; i<2; i++) int_off[i] = i;
+
+   if( long_big_endian )
+   {
+      i = long_off[0]; long_off[0] = long_off[2]; long_off[2] = i;
+      i = long_off[1]; long_off[1] = long_off[3]; long_off[3] = i;
+   }
+   if( big_endian )
+   {
+      i = long_off[2]; long_off[2] = long_off[3]; long_off[3] = i;
+      i = long_off[0]; long_off[0] = long_off[1]; long_off[1] = i;
+
+      i = int_off[0]; int_off[0] = int_off[1]; int_off[1] = i;
+   }
+   return 1;
+}
+
+void u2c2(char *buf, u2_t offset)
+{
+#ifdef __AS386_16__
+   if( no_swap )
+   {
+      *((unsigned short*)buf) = offset;        /* UNALIGNED ACCESS! */
+      return;
+   }
+#endif
+   buf[int_off[0]] = offset;
+   buf[int_off[1]] = (offset>>8);
+}
+
+void u4c4(char *buf, u4_t offset)
+{
+   int i;
+#ifdef __AS386_16__
+   if( no_swap )
+   {
+      *((unsigned long*)buf) = offset; /* UNALIGNED ACCESS! */
+      return;
+   }
+#endif
+   for(i=0; i<4; i++)
+   {
+      buf[long_off[i]] = offset;
+      offset >>= 8;
+   }
+}
+
+void u4cn(char *buf, u4_t offset, unsigned count)
+{
+    switch(count)
+    {
+    case 1:
+       buf[0] = (char) offset;
+       return;
+    case 2:
+       u2c2(buf, (u2_pt) offset);
+       return;
+    case 4:
+       u4c4(buf, (u4_t) offset);
+       return;
+    default:
+        xxerr("WARNING: typeconv.c(u4cn) illegal count\n");
+       return;
+    }
+}
+
+void u2cn(char *buf, u2_pt offset, unsigned count)
+{
+    switch(count)
+    {
+    case 1:
+       buf[0] = (char) offset;
+       return;
+    case 2:
+       u2c2(buf, (u2_pt) offset);
+       return;
+    case 4:
+       u4c4(buf, (u4_t) offset);
+       return;
+    default:
+        xxerr("WARNING: typeconv.c(u2cn) illegal count\n");
+       return;
+    }
+}
+
+u2_pt c2u2(char *buf)
+{
+    u2_pt res;
+#ifdef __AS386_16__
+   if( no_swap ) return *((u2_pt *)buf);       /* UNALIGNED ACCESS! */
+#endif
+
+    res  =   ((unsigned char *)buf) [int_off[0]]
+         + ((((unsigned char *)buf) [int_off[1]]) << 8);
+    return res;
+}
+
+u4_t c4u4(char *buf)
+{
+    u4_t res;
+    int i;
+#ifdef __AS386_16__
+   if( no_swap ) return *((u4_t *)buf);                /* UNALIGNED ACCESS! */
+#endif
+    res = 0;
+    for(i=3; i>=0; i--)
+    {
+        res = (res<<8) + ((unsigned char *)buf) [long_off[i]];
+    }
+    return res;
+}
+
+u4_t cnu4(char *buf, unsigned count)
+{
+    switch (count)
+    {
+    case 0:
+       return 0;
+    case 1:
+       return buf[0] & 0xFF;
+    case 2:
+       return c2u2(buf);
+    case 4:
+       return c4u4(buf);
+    default:
+        xxerr("WARNING: typeconv.c(cnu4) illegal count\n");
+       return 0;
+    }
+}
+
+u2_pt cnu2(char *buf, unsigned count)
+{
+    switch (count)
+    {
+    case 0:
+       return 0;
+    case 1:
+       return buf[0] & 0xFF;
+    case 2:
+       return c2u2(buf);
+    case 4:
+       return (u2_pt) c4u4(buf);
+    default:
+        xxerr("WARNING: typeconv.c(cnu2) illegal count\n");
+       return 0;
+    }
+}
diff --git a/Applications/as09/version.h b/Applications/as09/version.h
new file mode 100644 (file)
index 0000000..0af81ac
--- /dev/null
@@ -0,0 +1 @@
+#define VERSION "0.16.21"