summaryrefslogtreecommitdiff
path: root/as
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>2002-07-27 09:23:57 +0200
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:16:11 +0200
commita7aba15e8efffb1c5d3097656f1a93955a64f01f (patch)
tree4bb9d6d1d1528bc5647670d510aca6cc5fb300a8 /as
downloaddev86-a7aba15e8efffb1c5d3097656f1a93955a64f01f.tar.gz
Import origs.tar.gzorigs
Diffstat (limited to 'as')
-rw-r--r--as/6809/const.h501
-rw-r--r--as/Makefile27
-rw-r--r--as/TODO1
-rw-r--r--as/address.h30
-rw-r--r--as/as.c296
-rw-r--r--as/asm/calljmp.asm70
-rw-r--r--as/asm/ea.asm109
-rw-r--r--as/asm/each.asm145
-rw-r--r--as/asm/easlow.as1219
-rw-r--r--as/asm/f.asm114
-rw-r--r--as/asm/fadd.asm271
-rw-r--r--as/asm/farcall.asm10
-rw-r--r--as/asm/group1.asm31
-rw-r--r--as/asm/group6.asm24
-rw-r--r--as/asm/group7.asm34
-rw-r--r--as/asm/imul.asm33
-rw-r--r--as/asm/incdec.asm83
-rw-r--r--as/asm/inher.asm127
-rw-r--r--as/asm/inout.asm25
-rw-r--r--as/asm/movspec.asm246
-rw-r--r--as/asm/pushpop.asm86
-rw-r--r--as/asm/seg.asm6
-rw-r--r--as/asm/shdouble.asm34
-rw-r--r--as/asm/shift.asm119
-rw-r--r--as/asm/summary.as385
-rw-r--r--as/asm/xchg.asm103
-rw-r--r--as/assemble.c309
-rw-r--r--as/bin/calljmp.binbin0 -> 146 bytes
-rw-r--r--as/bin/ea.binbin0 -> 441 bytes
-rw-r--r--as/bin/each.binbin0 -> 657 bytes
-rw-r--r--as/bin/f.binbin0 -> 181 bytes
-rw-r--r--as/bin/fadd.binbin0 -> 605 bytes
-rw-r--r--as/bin/farcall.binbin0 -> 41 bytes
-rw-r--r--as/bin/group1.binbin0 -> 115 bytes
-rw-r--r--as/bin/group6.binbin0 -> 38 bytes
-rw-r--r--as/bin/group7.binbin0 -> 53 bytes
-rw-r--r--as/bin/imul.binbin0 -> 119 bytes
-rw-r--r--as/bin/incdec.binbin0 -> 116 bytes
-rw-r--r--as/bin/inher.binbin0 -> 129 bytes
-rw-r--r--as/bin/inout.binbin0 -> 54 bytes
-rw-r--r--as/bin/movspec.binbin0 -> 682 bytes
-rw-r--r--as/bin/pushpop.binbin0 -> 128 bytes
-rw-r--r--as/bin/seg.binbin0 -> 16 bytes
-rw-r--r--as/bin/shdouble.binbin0 -> 61 bytes
-rw-r--r--as/bin/shift.binbin0 -> 276 bytes
-rw-r--r--as/bin/xchg.binbin0 -> 234 bytes
-rw-r--r--as/byteord.h18
-rwxr-xr-xas/chk9
-rw-r--r--as/const.h409
-rw-r--r--as/error.c106
-rw-r--r--as/express.c382
-rw-r--r--as/file.h12
-rw-r--r--as/flag.h5
-rw-r--r--as/genbin.c220
-rw-r--r--as/genlist.c463
-rw-r--r--as/genobj.c682
-rw-r--r--as/gensym.c212
-rw-r--r--as/globvar.h93
-rw-r--r--as/macro.c175
-rw-r--r--as/macro.h10
-rw-r--r--as/mops.c2835
-rw-r--r--as/obj1/calljmp.objbin0 -> 200 bytes
-rw-r--r--as/obj1/ea.objbin0 -> 472 bytes
-rw-r--r--as/obj1/each.objbin0 -> 715 bytes
-rw-r--r--as/obj1/f.objbin0 -> 207 bytes
-rw-r--r--as/obj1/fadd.objbin0 -> 1069 bytes
-rw-r--r--as/obj1/farcall.objbin0 -> 71 bytes
-rw-r--r--as/obj1/group1.objbin0 -> 145 bytes
-rw-r--r--as/obj1/group6.objbin0 -> 67 bytes
-rw-r--r--as/obj1/group7.objbin0 -> 82 bytes
-rw-r--r--as/obj1/imul.objbin0 -> 147 bytes
-rw-r--r--as/obj1/incdec.objbin0 -> 146 bytes
-rw-r--r--as/obj1/inher.objbin0 -> 158 bytes
-rw-r--r--as/obj1/inout.objbin0 -> 82 bytes
-rw-r--r--as/obj1/movspec.objbin0 -> 722 bytes
-rw-r--r--as/obj1/pushpop.objbin0 -> 159 bytes
-rw-r--r--as/obj1/seg.objbin0 -> 42 bytes
-rw-r--r--as/obj1/shdouble.objbin0 -> 106 bytes
-rw-r--r--as/obj1/shift.objbin0 -> 308 bytes
-rw-r--r--as/obj1/xchg.objbin0 -> 264 bytes
-rw-r--r--as/opcode.h157
-rw-r--r--as/pops.c1048
-rw-r--r--as/proto.h218
-rw-r--r--as/readsrc.c341
-rw-r--r--as/scan.c247
-rw-r--r--as/scan.h12
-rw-r--r--as/source.h4
-rw-r--r--as/table.c945
-rw-r--r--as/todo14
-rw-r--r--as/type.h167
90 files changed, 13222 insertions, 0 deletions
diff --git a/as/6809/const.h b/as/6809/const.h
new file mode 100644
index 0000000..abd9469
--- /dev/null
+++ b/as/6809/const.h
@@ -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/as/Makefile b/as/Makefile
new file mode 100644
index 0000000..d7468a9
--- /dev/null
+++ b/as/Makefile
@@ -0,0 +1,27 @@
+CFLAGS =-O
+LDFLAGS =
+
+OBJS =as.o assemble.o error.o express.o \
+ genbin.o genlist.o genobj.o gensym.o \
+ macro.o mops.o pops.o readsrc.o \
+ scan.o table.o typeconv.o
+
+as: $(OBJS)
+ $(CC) $(LDFLAGS) $(OBJS) -o as
+ chmem =182000 as
+
+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
+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/as/TODO b/as/TODO
new file mode 100644
index 0000000..b8166c8
--- /dev/null
+++ b/as/TODO
@@ -0,0 +1 @@
+6809/const.h is out of date.
diff --git a/as/address.h b/as/address.h
new file mode 100644
index 0000000..26fcf33
--- /dev/null
+++ b/as/address.h
@@ -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/as/as.c b/as/as.c
new file mode 100644
index 0000000..666fd79
--- /dev/null
+++ b/as/as.c
@@ -0,0 +1,296 @@
+/* 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 "const.h"
+#include "type.h"
+#include "byteord.h"
+#include "macro.h"
+#undef EXTERN
+#define EXTERN
+#include "file.h"
+#include "flag.h"
+#include "globvar.h"
+
+#ifdef STDC_HEADERS_MISSING
+void exit P((int status));
+void *malloc P((unsigned size));
+char *strcpy P((char *s1, const char *s2));
+unsigned strlen P((const char *s));
+#else
+#undef NULL
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#ifdef POSIX_HEADERS_MISSING
+int close P((int fd));
+int creat P((const char *path, int mode));
+int write P((int fd, const void *buf, unsigned nbytes));
+#else
+#undef NULL
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#endif
+
+PUBLIC char hexdigit[] = "0123456789ABCDEF"; /* XXX - ld uses lower case */
+
+PRIVATE struct block_s hid_blockstak[MAXBLOCK]; /* block stack */
+PRIVATE struct lc_s hid_lctab[NLOC]; /* location counter table */
+PRIVATE struct if_s hid_ifstak[MAXBLOCK]; /* if stack */
+PRIVATE struct schain_s hid_mcpar[MACPSIZ]; /* MACRO params */
+PRIVATE struct macro_s hid_macstak[MAXBLOCK]; /* macro stack */
+PRIVATE struct sym_s *hid_spt[SPTSIZ]; /* hash table */
+
+FORWARD void initp1 P((void));
+FORWARD int my_creat P((char *name, char *message));
+FORWARD void process_args P((int argc, char **argv));
+FORWARD void summary P((fd_t fd));
+FORWARD void summ_number P((unsigned num));
+FORWARD void usage P((void));
+
+#define USERMEM (sizeof(int) <= 2 ? (unsigned) 0xAC00 : (unsigned) 0x28000L)
+
+PUBLIC int main(argc, argv)
+int argc;
+char **argv;
+{
+ heapptr = malloc(USERMEM);
+ heapend = heapptr + USERMEM;
+ if (heapptr == 0)
+ as_abort("cannot allocate memory");
+#ifdef SOS_EDOS
+ heapend = stackreg() - STAKSIZ;
+#endif
+ initp1();
+ initp1p2();
+ inst_keywords();
+ initbin();
+ initobj();
+ initsource(); /* only nec to init for unsupported mem file */
+ typeconv_init(BIG_ENDIAN, LONG_BIG_ENDIAN);
+ warn.global = TRUE; /* constant */
+ process_args(argc, argv);
+ initscan();
+
+ assemble(); /* doesn't return, maybe use setjmp */
+
+ /* NOTREACHED */
+ return 0;
+}
+
+PUBLIC void as_abort(message)
+char *message;
+{
+ write(STDOUT, "as: ", 4);
+ write(STDOUT, message, strlen(message));
+ write(STDOUT, "\n", 1);
+ exit(1);
+}
+
+PUBLIC void finishup()
+{
+ 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();
+ exit(toterr != 0 ? 1 : 0); /* should close output files and check */
+}
+
+/* initialise constant nonzero values */
+
+PRIVATE void initp1()
+{
+#ifdef I80386
+ 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 */
+
+PUBLIC void initp1p2()
+{
+ register struct lc_s *lcp;
+
+ 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)
+ /* init of lcdata/lc (many times) in loop to save space */
+ {
+ lcp->data = lcdata = RELBIT; /* lc relocatable until 1st ORG */
+ lcp->lc = lc = 0;
+ }
+}
+
+PRIVATE int my_creat(name, message)
+char *name;
+char *message;
+{
+ int fd;
+
+ if ((fd = creat(name, CREAT_PERMS)) < 0 || fd > 255)
+ as_abort(message);
+ return fd;
+}
+
+PRIVATE void process_args(argc, argv)
+int argc;
+char **argv;
+{
+ char *arg;
+ bool_t isnextarg;
+ char *nextarg;
+
+ if (argc <= 1)
+ usage();
+ do
+ {
+ arg = *++argv;
+ if (arg[0] == '-')
+ {
+ 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])
+ {
+#ifdef I80386
+ case '0':
+ idefsize = defsize = 0x2;
+ break;
+ case '3':
+ idefsize = defsize = 0x4;
+ break;
+ case 'a':
+ asld_compatible = TRUE;
+ break;
+#endif
+ case 'b':
+ if (!isnextarg || binfil != 0)
+ usage();
+ binfil = my_creat(nextarg, "error creating binary file");
+ binaryg = TRUE;
+ --argc;
+ ++argv;
+ break;
+ case 'g':
+ globals_only_in_obj = TRUE;
+ break;
+#ifdef I80386
+ case 'j':
+ jumps_long = TRUE;
+ 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(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 'u':
+ inidata = IMPBIT | SEGM;
+ break;
+ case 'w':
+ warn.semaphore = -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");
+ infil = open_input(strcpy(filnamptr, arg));
+ infiln = infil0 = 1;
+ }
+ }
+ while (--argc != 1);
+ inidata = (~binaryg & inidata) | (RELBIT | UNDBIT);
+} /* IMPBIT from inidata unless binaryg */
+
+PRIVATE void summary(fd)
+int fd;
+{
+ innum = fd;
+ writenl();
+ summ_number(toterr);
+ writesn(" errors");
+ summ_number(totwarn);
+ writesn(" warnings");
+}
+
+PRIVATE void summ_number(num)
+unsigned num;
+{
+ /* format number like line numbers, build it at free spot heapptr */
+ *build_number(num, LINUM_LEN, heapptr) = 0;
+ writes(heapptr);
+}
+
+PRIVATE void usage()
+{
+ as_abort(
+#ifdef I80386
+"usage: as [-03agjuw] [-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/as/asm/calljmp.asm b/as/asm/calljmp.asm
new file mode 100644
index 0000000..36a6ea4
--- /dev/null
+++ b/as/asm/calljmp.asm
@@ -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/as/asm/ea.asm b/as/asm/ea.asm
new file mode 100644
index 0000000..8717a73
--- /dev/null
+++ b/as/asm/ea.asm
@@ -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/as/asm/each.asm b/as/asm/each.asm
new file mode 100644
index 0000000..2145489
--- /dev/null
+++ b/as/asm/each.asm
@@ -0,0 +1,145 @@
+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
+repe
+repz
+repne
+repnz
+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/as/asm/easlow.as b/as/asm/easlow.as
new file mode 100644
index 0000000..75d71e2
--- /dev/null
+++ b/as/asm/easlow.as
@@ -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/as/asm/f.asm b/as/asm/f.asm
new file mode 100644
index 0000000..c067bf9
--- /dev/null
+++ b/as/asm/f.asm
@@ -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/as/asm/fadd.asm b/as/asm/fadd.asm
new file mode 100644
index 0000000..d18f002
--- /dev/null
+++ b/as/asm/fadd.asm
@@ -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/as/asm/farcall.asm b/as/asm/farcall.asm
new file mode 100644
index 0000000..6a779d9
--- /dev/null
+++ b/as/asm/farcall.asm
@@ -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/as/asm/group1.asm b/as/asm/group1.asm
new file mode 100644
index 0000000..fe2fb45
--- /dev/null
+++ b/as/asm/group1.asm
@@ -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/as/asm/group6.asm b/as/asm/group6.asm
new file mode 100644
index 0000000..f742672
--- /dev/null
+++ b/as/asm/group6.asm
@@ -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/as/asm/group7.asm b/as/asm/group7.asm
new file mode 100644
index 0000000..0df497c
--- /dev/null
+++ b/as/asm/group7.asm
@@ -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/as/asm/imul.asm b/as/asm/imul.asm
new file mode 100644
index 0000000..e2772c2
--- /dev/null
+++ b/as/asm/imul.asm
@@ -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/as/asm/incdec.asm b/as/asm/incdec.asm
new file mode 100644
index 0000000..573861c
--- /dev/null
+++ b/as/asm/incdec.asm
@@ -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/as/asm/inher.asm b/as/asm/inher.asm
new file mode 100644
index 0000000..f1343fa
--- /dev/null
+++ b/as/asm/inher.asm
@@ -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/as/asm/inout.asm b/as/asm/inout.asm
new file mode 100644
index 0000000..3f0a3f2
--- /dev/null
+++ b/as/asm/inout.asm
@@ -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/as/asm/movspec.asm b/as/asm/movspec.asm
new file mode 100644
index 0000000..a4f9c15
--- /dev/null
+++ b/as/asm/movspec.asm
@@ -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/as/asm/pushpop.asm b/as/asm/pushpop.asm
new file mode 100644
index 0000000..b45117a
--- /dev/null
+++ b/as/asm/pushpop.asm
@@ -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/as/asm/seg.asm b/as/asm/seg.asm
new file mode 100644
index 0000000..0394615
--- /dev/null
+++ b/as/asm/seg.asm
@@ -0,0 +1,6 @@
+ SEG CS
+ SEG DS
+ SEG ES
+ SEG FS
+ SEG GS
+ SEG SS
diff --git a/as/asm/shdouble.asm b/as/asm/shdouble.asm
new file mode 100644
index 0000000..1080ece
--- /dev/null
+++ b/as/asm/shdouble.asm
@@ -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/as/asm/shift.asm b/as/asm/shift.asm
new file mode 100644
index 0000000..35cc23f
--- /dev/null
+++ b/as/asm/shift.asm
@@ -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/as/asm/summary.as b/as/asm/summary.as
new file mode 100644
index 0000000..cd62e37
--- /dev/null
+++ b/as/asm/summary.as
@@ -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/as/asm/xchg.asm b/as/asm/xchg.asm
new file mode 100644
index 0000000..f05157f
--- /dev/null
+++ b/as/asm/xchg.asm
@@ -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/as/assemble.c b/as/assemble.c
new file mode 100644
index 0000000..c438ce6
--- /dev/null
+++ b/as/assemble.c
@@ -0,0 +1,309 @@
+/* assemble.c - main loop for assembler */
+
+#include "const.h"
+#include "type.h"
+#include "address.h"
+#include "globvar.h"
+#include "opcode.h"
+#include "scan.h"
+
+PRIVATE bool_t nocolonlabel; /* set for labels not followed by ':' */
+PRIVATE void (*routine) P((void));
+PRIVATE 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,
+ pfqb,
+ 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 */
+};
+
+FORWARD void asline P((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.
+*/
+
+PUBLIC void assemble()
+{
+ while (TRUE)
+ {
+ asline();
+ if (label != NULL) /* must be confirmed if still set */
+ { /* it is nulled by EQU, COMM and SET */
+#ifndef MC6809
+#define NEEDENDLABEL ILLAB
+ if (nocolonlabel)
+ error(NEEDENDLABEL);
+#endif
+ 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 = NULL; /* reset for next line */
+ }
+ skipline();
+ listline();
+ genbin();
+ genobj();
+ binmbuf = lc += lcjump
+#ifdef I80386
+ + immcount
+#endif
+ ;
+ }
+}
+
+PRIVATE void asline()
+{
+ 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;
+ readline();
+ getsym();
+ if (sym != IDENT) /* expect label, mnemonic or macro */
+ return; /* anything else is a comment */
+ symptr = gsymptr;
+ if (!ifflag)
+ /* not assembling, just test for IF/ELSE/ELSEIF/ENDIF */
+ {
+ if (symptr == NULL || !(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 */
+ {
+ if ((nocolonlabel = (*lineptr - ':')) == 0) /* exported label? */
+ {
+ sym = COLON;
+ ++lineptr;
+ }
+ if (symptr->type & (LABIT | VARBIT))
+ {
+ if (symptr->type & REDBIT)
+ labelerror(RELAB);
+ label = symptr;
+ }
+ else if (checksegrel(symptr))
+ {
+ symptr->type &= ~COMMBIT; /* ignore COMM, PCOMM gives warning */
+#ifdef MC6809
+#if 0
+ if (sym == COLON)
+ symptr->type |= EXPBIT;
+#endif
+#endif
+ symptr->data = (symptr->data & FORBIT) | lcdata;
+ /* remember if forward referenced */
+ 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;
+ routine = rout_table[symptr->value_reg_or_op.op.routine];
+ getsym();
+ (*routine)();
+ if (sym != EOLSYM)
+ error(JUNK_AFTER_OPERANDS);
+#ifdef I80386
+ if (aprefix != 0)
+ ++mcount;
+ if (oprefix != 0)
+ ++mcount;
+ if (sprefix != 0)
+ ++mcount;
+#endif
+}
diff --git a/as/bin/calljmp.bin b/as/bin/calljmp.bin
new file mode 100644
index 0000000..90c022f
--- /dev/null
+++ b/as/bin/calljmp.bin
Binary files differ
diff --git a/as/bin/ea.bin b/as/bin/ea.bin
new file mode 100644
index 0000000..5edc0b0
--- /dev/null
+++ b/as/bin/ea.bin
Binary files differ
diff --git a/as/bin/each.bin b/as/bin/each.bin
new file mode 100644
index 0000000..211155f
--- /dev/null
+++ b/as/bin/each.bin
Binary files differ
diff --git a/as/bin/f.bin b/as/bin/f.bin
new file mode 100644
index 0000000..ce695a0
--- /dev/null
+++ b/as/bin/f.bin
Binary files differ
diff --git a/as/bin/fadd.bin b/as/bin/fadd.bin
new file mode 100644
index 0000000..9afa6fc
--- /dev/null
+++ b/as/bin/fadd.bin
Binary files differ
diff --git a/as/bin/farcall.bin b/as/bin/farcall.bin
new file mode 100644
index 0000000..797a87c
--- /dev/null
+++ b/as/bin/farcall.bin
Binary files differ
diff --git a/as/bin/group1.bin b/as/bin/group1.bin
new file mode 100644
index 0000000..64a01bf
--- /dev/null
+++ b/as/bin/group1.bin
Binary files differ
diff --git a/as/bin/group6.bin b/as/bin/group6.bin
new file mode 100644
index 0000000..22ff663
--- /dev/null
+++ b/as/bin/group6.bin
Binary files differ
diff --git a/as/bin/group7.bin b/as/bin/group7.bin
new file mode 100644
index 0000000..9570eee
--- /dev/null
+++ b/as/bin/group7.bin
Binary files differ
diff --git a/as/bin/imul.bin b/as/bin/imul.bin
new file mode 100644
index 0000000..2b8ea16
--- /dev/null
+++ b/as/bin/imul.bin
Binary files differ
diff --git a/as/bin/incdec.bin b/as/bin/incdec.bin
new file mode 100644
index 0000000..676e5fa
--- /dev/null
+++ b/as/bin/incdec.bin
Binary files differ
diff --git a/as/bin/inher.bin b/as/bin/inher.bin
new file mode 100644
index 0000000..b37b3eb
--- /dev/null
+++ b/as/bin/inher.bin
Binary files differ
diff --git a/as/bin/inout.bin b/as/bin/inout.bin
new file mode 100644
index 0000000..a215490
--- /dev/null
+++ b/as/bin/inout.bin
Binary files differ
diff --git a/as/bin/movspec.bin b/as/bin/movspec.bin
new file mode 100644
index 0000000..6a5ef0a
--- /dev/null
+++ b/as/bin/movspec.bin
Binary files differ
diff --git a/as/bin/pushpop.bin b/as/bin/pushpop.bin
new file mode 100644
index 0000000..f95d6b5
--- /dev/null
+++ b/as/bin/pushpop.bin
Binary files differ
diff --git a/as/bin/seg.bin b/as/bin/seg.bin
new file mode 100644
index 0000000..43445a6
--- /dev/null
+++ b/as/bin/seg.bin
Binary files differ
diff --git a/as/bin/shdouble.bin b/as/bin/shdouble.bin
new file mode 100644
index 0000000..91bda37
--- /dev/null
+++ b/as/bin/shdouble.bin
Binary files differ
diff --git a/as/bin/shift.bin b/as/bin/shift.bin
new file mode 100644
index 0000000..1e31fac
--- /dev/null
+++ b/as/bin/shift.bin
Binary files differ
diff --git a/as/bin/xchg.bin b/as/bin/xchg.bin
new file mode 100644
index 0000000..6455b67
--- /dev/null
+++ b/as/bin/xchg.bin
Binary files differ
diff --git a/as/byteord.h b/as/byteord.h
new file mode 100644
index 0000000..a0d14e1
--- /dev/null
+++ b/as/byteord.h
@@ -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 BIG_ENDIAN 0
+# define LONG_BIG_ENDIAN 0 /* except longs are back to front for Xenix */
+#endif
+
+#ifdef I80386
+# define BIG_ENDIAN 0
+# define LONG_BIG_ENDIAN 0
+#endif
+
+#ifdef MC6809
+# define 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/as/chk b/as/chk
new file mode 100755
index 0000000..89c73de
--- /dev/null
+++ b/as/chk
@@ -0,0 +1,9 @@
+for i in `ls asm/*.asm`
+do
+ j=`basename $i .asm`
+ ./as asm/$j.asm -b $j.bin -o $j.obj > /dev/null
+ cmp $j.bin bin/$j.bin
+ cmp $j.obj obj1/$j.obj
+ rm $j.bin $j.obj
+done
+
diff --git a/as/const.h b/as/const.h
new file mode 100644
index 0000000..78523e5
--- /dev/null
+++ b/as/const.h
@@ -0,0 +1,409 @@
+#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 */
+
+#define I80386 /* generate 80386 code */
+#undef 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
+
+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
+};
+
+enum
+{
+/* Error codes. */
+
+/* Syntax errors. */
+ COMEXP,
+ DELEXP,
+ FACEXP,
+ IREGEXP,
+ LABEXP,
+ LPEXP,
+ OPEXP,
+ RBEXP,
+ REGEXP,
+ RPEXP,
+ SPEXP,
+
+/* Expression errors. */
+ ABSREQ,
+ NONIMPREQ,
+ RELBAD,
+
+/* Label errors. */
+ ILLAB,
+ MACUID,
+ MISLAB,
+ MNUID,
+ REGUID,
+ RELAB,
+ UNBLAB,
+ UNLAB,
+ VARLAB,
+
+/* Addressing errors. */
+ ABOUNDS,
+ DBOUNDS,
+ ILLMOD,
+ ILLREG,
+
+/* Control structure errors. */
+ ELSEBAD,
+#define ELSEIFBAD ELSEBAD
+ ENDBBAD,
+#define ENDIFBAD ELSEBAD
+ EOFBLOCK,
+ EOFIF,
+ EOFLC,
+ EOFMAC,
+ FAILERR,
+
+/* Overflow errors. */
+ BLOCKOV,
+ BWRAP,
+ COUNTOV,
+ COUNTUN,
+ GETOV,
+ IFOV,
+
+ LINLONG,
+ MACOV,
+ OBJSYMOV,
+ OWRITE,
+ PAROV,
+ SYMOV,
+ SYMOUTOV,
+
+/* I/O errors. */
+ OBJOUT,
+
+/* Miscellaneous errors. */
+ AL_AX_EAX_EXP,
+ CTLINS,
+ FURTHER,
+ ILL_IMM_MODE,
+ ILL_IND_TO_IND,
+ ILL_IND,
+ ILL_IND_PTR,
+ ILL_SCALE,
+ ILL_SECTION,
+ ILL_SEG_REG,
+ ILL_SOURCE_EA,
+ ILL_SIZE,
+ IMM_REQ,
+ INDEX_REG_EXP,
+ IND_REQ,
+ MISMATCHED_SIZE,
+ NOIMPORT,
+ REENTER,
+ REL_REQ,
+ REPEATED_DISPL,
+ SEGREL,
+ SEG_REG_REQ,
+ SIZE_UNK,
+ UNKNOWN_ESCAPE_SEQUENCE,
+
+ FP_REG_REQ,
+ FP_REG_NOT_ALLOWED,
+ ILL_FP_REG,
+ ILL_FP_REG_PAIR,
+ JUNK_AFTER_OPERANDS,
+
+ ALREADY,
+
+/* Warnings. */
+#define MINWARN SHORTB
+ SHORTB
+};
+
+/* 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
diff --git a/as/error.c b/as/error.c
new file mode 100644
index 0000000..6cb4da7
--- /dev/null
+++ b/as/error.c
@@ -0,0 +1,106 @@
+/* error.c - error routines for assembler */
+
+#include "const.h"
+#include "type.h"
+
+#ifdef STDC_HEADERS_MISSING
+char *strcpy P((char *s1, const char *s2));
+#else
+#undef NULL
+#include <string.h>
+#endif
+
+PRIVATE char *errormessage[] =
+{
+ "comma expected",
+ "delimiter expected",
+ "factor expected",
+ "index register expected",
+ "label expected",
+ "left parentheses expected",
+ "opcode expected",
+ "right bracket expected",
+ "register expected",
+ "right parentheses expected",
+ "space expected",
+ "absolute expression required",
+ "non-imported expression required",
+ "relocation impossible",
+ "illegal label",
+ "MACRO used as identifier",
+ "missing label",
+ "opcode used as identifier",
+ "register used as identifier",
+ "redefined label",
+ "unbound label",
+ "undefined label",
+ "variable used as label",
+ "address out of bounds",
+ "data out of bounds",
+ "illegal address mode",
+ "illegal register",
+ "no matching IF",
+ "no matching BLOCK",
+ "end of file in BLOCK",
+ "end of file in IF",
+ "location counter was undefined at end",
+ "end of file in MACRO",
+ "user-generated error",
+ "BLOCK stack overflow",
+ "binary file wrap-around",
+ "counter overflow",
+ "counter underflow",
+ "GET stack overflow",
+ "IF stack overflow",
+ "line too long",
+ "MACRO stack overflow",
+ "object symbol table overflow",
+ "program overwrite",
+ "parameter table overflow",
+ "symbol table overflow",
+ "output symbol table overflow",
+ "error writing object file",
+ "al, ax or eax expected",
+ "control character in string",
+ "futher errors suppressed",
+ "illegal immediate mode",
+ "illegal indirect to indirect",
+ "illegal indirection",
+ "illegal indirection from previous 'ptr'",
+ "illegal scale",
+ "illegal section",
+ "illegal segment register",
+ "illegal source effective address",
+ "illegal size",
+ "immediate expression expected",
+ "index register expected",
+ "indirect expression required",
+ "mismatched size",
+ "no imports with binary file output",
+ "multiple ENTER pseudo-ops",
+ "relative expression required",
+ "repeated displacement",
+ "segment or relocatability redefined",
+ "segment register required",
+ "size unknown",
+ "unknown escape sequence",
+ "FP register required",
+ "FP register not allowed",
+ "illegal FP register",
+ "illegal FP register pair",
+ "junk after operands",
+ "already defined",
+ "short branch would do",
+ "unknown error",
+};
+
+/* build null-terminated error message for given error at given spot */
+
+PUBLIC char *build_error_message(errnum, buf)
+error_pt errnum;
+char *buf;
+{
+ if (errnum >= sizeof errormessage / sizeof errormessage[0])
+ errnum = sizeof errormessage / sizeof errormessage[0] - 1;
+ return strcpy(buf, errormessage[errnum]);
+}
diff --git a/as/express.c b/as/express.c
new file mode 100644
index 0000000..54dff2f
--- /dev/null
+++ b/as/express.c
@@ -0,0 +1,382 @@
+/* express.c - expression handler for assembler */
+
+#include "const.h"
+#include "type.h"
+#include "address.h"
+#include "globvar.h"
+#include "scan.h"
+#include "source.h"
+
+FORWARD void experror P((error_pt errnum));
+FORWARD void expundefined P((void));
+FORWARD void simple2 P((void));
+FORWARD void simple P((void));
+FORWARD void term P((void));
+FORWARD void factor2 P((void));
+
+PUBLIC void absexpres()
+{
+ expres();
+ chkabs();
+}
+
+/* check lastexp.data is abs */
+
+PUBLIC void chkabs()
+{
+ if (lastexp.data & RELBIT)
+ {
+ if (pass != 0)
+ error(ABSREQ);
+ expundefined();
+ }
+}
+
+PRIVATE void experror(errnum)
+error_pt errnum;
+{
+ error(errnum);
+ expundefined();
+}
+
+PRIVATE void expundefined()
+{
+ lastexp.data = FORBIT | UNDBIT;
+}
+
+PUBLIC void nonimpexpres()
+{
+ expres();
+ if (lastexp.data & IMPBIT)
+ experror(NONIMPREQ);
+}
+
+/* generate relocation error if pass 2, make lastexp.data forward&undefined */
+
+PUBLIC void showrelbad()
+{
+ if (pass != 0)
+ error(RELBAD);
+ expundefined();
+}
+
+PUBLIC void symabsexpres()
+{
+ getsym();
+ absexpres();
+}
+
+PUBLIC void symexpres()
+{
+ 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.
+*/
+
+PUBLIC void expres()
+{
+ 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 */
+
+PRIVATE void simple2()
+{
+ 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).
+*/
+
+PRIVATE void simple()
+{
+ 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 >>. */
+
+PRIVATE void term()
+{
+ 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 */
+
+PRIVATE void factor2()
+{
+ 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.
+*/
+
+PUBLIC void factor()
+{
+ 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)))
+ {
+ symptr->data |= FORBIT;
+ lastexp.sym = symptr;
+ }
+ if (pass == 0)
+ {
+ lastexp.data = symptr->data &
+ (FORBIT | 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;
+ }
+ case LBRACKET:
+ if (!asld_compatible)
+ break; /* error, LPAREN is the grouping symbol */
+ getsym();
+ expres();
+ if (sym != RBRACKET)
+ error(RBEXP);
+ else
+ getsym();
+ return;
+ case LPAREN:
+ if (asld_compatible)
+ break; /* error, LBRACKET is the grouping symbol */
+ getsym();
+ expres();
+ if (sym != RPAREN)
+ error(RPEXP);
+ else
+ getsym();
+ return;
+ case NOTOP:
+ 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 != 0)
+ experror(UNBLAB);
+ getsym();
+ return;
+ }
+ experror(FACEXP);
+}
+
+/*
+ string compare for IFC/ELSEIFC
+ expects (<string1>,<string2>)
+ returns logical value in lastexp
+*/
+
+PUBLIC void scompare()
+{
+ /* 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;
+ }
+ while (*string1++ == *string2++)
+ ;
+ if (string2[-1] == ')')
+ {
+ if (string1[-1] == ',')
+ lastexp.offset = TRUE; /* else leave FALSE */
+ }
+ else /* FALSE, keep reading to verify syntax */
+ for (; *string2 != ')'; ++string2)
+ if (*string2 == 0 || *string2 == ',')
+ {
+ symname = string2;
+ experror(RPEXP);
+ }
+ }
+}
diff --git a/as/file.h b/as/file.h
new file mode 100644
index 0000000..1272d47
--- /dev/null
+++ b/as/file.h
@@ -0,0 +1,12 @@
+/* file.h - global variables involving files for assembler */
+
+EXTERN fd_t binfil; /* binary output file (0 = memory) */
+EXTERN char *filnamptr; /* file name pointer */
+EXTERN fd_t infil0; /* initial input file */
+EXTERN fd_t infil; /* current input file (stacked, 0 = memory) */
+EXTERN unsigned char infiln; /* innum when file was opened */
+EXTERN unsigned char innum; /* counter for calls to open */
+EXTERN fd_t lstfil; /* list output file (0 = standard) */
+EXTERN fd_t objfil; /* object output file */
+EXTERN fd_t symfil; /* symbol table output file */
+EXTERN char *truefilename; /* in case actual source name is a tmpname */
diff --git a/as/flag.h b/as/flag.h
new file mode 100644
index 0000000..791dcc1
--- /dev/null
+++ b/as/flag.h
@@ -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 warn; /* warnings on/off */
diff --git a/as/genbin.c b/as/genbin.c
new file mode 100644
index 0000000..ce16405
--- /dev/null
+++ b/as/genbin.c
@@ -0,0 +1,220 @@
+/* genbin.c - binary code generation routines for assembler */
+
+#include "const.h"
+#include "type.h"
+#include "address.h"
+#include "file.h"
+#include "globvar.h"
+
+PRIVATE char *asmbeg; /* beginning of assembler code */
+ /* for overwrite check */
+ /* bss-init to zero = NULL and not changed */
+PRIVATE offset_t binfbuf; /* binary code buffer for file (counter) */
+PRIVATE offset_t binmax; /* maximum value of binmbuf for pass 1 */
+PRIVATE offset_t binmin; /* minimum value of binmbuf for pass 1 */
+
+FORWARD void putbinoffset P((offset_t offset, count_t size));
+
+/* write header to binary file */
+
+PUBLIC void binheader()
+{
+ if ((innum = binfil) != 0x0)
+ {
+ 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
+ }
+}
+
+/* write trailer to binary file */
+
+PUBLIC void bintrailer()
+{
+ if ((innum = binfil) != 0x0)
+ {
+ 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
+ }
+}
+
+/* generate binary code for current line */
+
+PUBLIC void genbin()
+{
+ 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 */
+
+PUBLIC void initbin()
+{
+ binmin = -1; /* greater than anything */
+}
+
+/* write char to binary file or directly to memory */
+
+PUBLIC void putbin(ch)
+opcode_pt ch;
+{
+ if (binfil != 0x0)
+ {
+ if (!binaryc) /* pass 1, just record limits */
+ {
+ if (binmbuf < binmin)
+ binmin = binmbuf;
+ if (++binmbuf > binmax)
+ binmax = binmbuf;
+ }
+ else
+ {
+ if (binfbuf > binmbuf)
+ error(BWRAP); /* file buffer ahead of memory buffer */
+ else
+ {
+ innum = binfil;
+ while (binfbuf < binmbuf)
+ {
+ writec(0x0);/* pad with nulls if file buffer behind */
+ ++binfbuf;
+ }
+ writec(ch);
+ binmbuf = ++binfbuf;
+ }
+ }
+ }
+ else if (binaryc && !(lcdata & UNDBIT))
+ /* memory output, and enabled */
+ {
+ register char *bufptr;
+
+ if ((bufptr = (char *) binmbuf) >= asmbeg && bufptr < heapptr)
+ error(OWRITE);
+ else
+ *bufptr = ch;
+ ++binmbuf;
+ }
+}
+
+/* write sized offset to binary file or directly to memory */
+
+PRIVATE void putbinoffset(offset, size)
+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/as/genlist.c b/as/genlist.c
new file mode 100644
index 0000000..e179fcf
--- /dev/null
+++ b/as/genlist.c
@@ -0,0 +1,463 @@
+/* genlist.c - generate listing and error reports for assembler */
+
+#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"
+
+#ifdef STDC_HEADERS_MISSING
+void *memset P((void *s, int c, unsigned n));
+unsigned strlen P((const char *s));
+#else
+#undef NULL
+#include <string.h>
+#endif
+
+#ifdef POSIX_HEADERS_MISSING
+int write P((int fd, const void *buf, unsigned nbytes));
+#else
+#undef NULL
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
+#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 */
+{
+ unsigned char errnum;
+ 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;
+};
+
+PRIVATE struct error_s errbuf[MAXERR]; /* error buffer */
+PRIVATE unsigned char errcount; /* # errors in line */
+PRIVATE bool_t erroverflow; /* set if too many errors on line */
+
+FORWARD char *build_1hex_number P((opcode_pt num, char *where));
+FORWARD void list1 P((fd_t fd));
+FORWARD void listcode P((void));
+FORWARD void listerrors P((void));
+FORWARD void paderrorline P((unsigned nspaces));
+
+/* format 1 byte number as 2 hex digits, return ptr to end */
+
+PRIVATE char *build_1hex_number(num, where)
+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 */
+
+PUBLIC char *build_2hex_number(num, where)
+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 */
+
+PUBLIC char *build_number(num, width, where)
+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) */
+
+PUBLIC void error(errnum)
+error_pt errnum;
+{
+ register struct error_s *errptr;
+ register struct error_s *errptrlow;
+ unsigned char position;
+
+ if ((unsigned) errnum < MINWARN || warn.current)
+ {
+ if (errcount >= MAXERR)
+ erroverflow = TRUE;
+ else
+ {
+ position = symname - linebuf;
+ for (errptr = errbuf + errcount;
+ errptr > errbuf && errptr->position > position;
+ errptr = errptrlow)
+ {
+ errptrlow = errptr - 1;
+ errptr->errnum = errptrlow->errnum;
+ errptr->position = errptrlow->position;
+ }
+ errptr->errnum = errnum;
+ errptr->position = position;
+ ++errcount;
+ if ((unsigned)errnum >= MINWARN)
+ ++totwarn;
+ else
+ ++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 */
+
+PUBLIC void listline()
+{
+ if (!listpre)
+ {
+ if (errcount || list.current && (!macflag || mcount != 0) ||
+ macflag && maclist.current)
+ list1(lstfil);
+ if (errcount)
+ {
+ if (lstfil != STDOUT)
+ list1(STDOUT);
+ errcount = 0;
+ erroverflow = FALSE;
+ }
+ }
+}
+
+/* list 1 line unconditionally */
+
+PRIVATE void list1(fd)
+fd_t fd;
+{
+ innum = fd;
+ listcode();
+ write(innum, linebuf, (unsigned) (lineptr - linebuf));
+ writenl();
+ if (errcount != 0)
+ listerrors();
+ listpre = TRUE;
+}
+
+/* list object code for 1 line */
+
+PRIVATE void listcode()
+{
+ unsigned char count;
+ struct code_listing_s *listptr;
+ unsigned numlength;
+ char *numptr;
+
+ listptr = (struct code_listing_s *) heapptr;
+ 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 */
+
+PRIVATE void listerrors()
+{
+ 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;
+
+ paderrorline(CODE_LIST_LENGTH - LINUM_LEN);
+ 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
+ {
+ while (column < errptr->position)
+ {
+ ++column;
+ if (*linep++ == '\t') /* next tab (standard tabs only) */
+ errcolw = (errcolw + 8) & 0xf8;
+ else
+ ++errcolw;
+ while (errcolw > errcol)
+ {
+ writec(' ');
+ ++errcol;
+ }
+ }
+ if (errcolw < errcol) /* position under error on new line */
+ {
+ writenl();
+ paderrorline((unsigned) errcolw - LINUM_LEN);
+ }
+ writec('^');
+ writes(errmsg = build_error_message(errptr->errnum, heapptr));
+ errcol += strlen(errmsg);
+ ++errptr;
+ }
+ while (--remaining != 0);
+ writenl();
+ if (erroverflow)
+ {
+ paderrorline(CODE_LIST_LENGTH - LINUM_LEN);
+ writesn(build_error_message(FURTHER, heapptr));
+ }
+}
+
+/* pad out error line to begin under 1st char of source listing */
+
+PRIVATE void paderrorline(nspaces)
+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 */
+
+PUBLIC void writec(ch)
+char ch;
+{
+ write(innum, &ch, 1);
+}
+
+/* write newline */
+
+PUBLIC void writenl()
+{
+ writes(SOS_EOLSTR);
+}
+
+/* write 1 offset_t, order to suit target */
+
+PUBLIC void writeoff(offset)
+offset_t offset;
+{
+ char buf[sizeof offset];
+
+#if SIZEOF_OFFSET_T > 2
+ u4c4(buf, offset);
+#else
+ u2c2(buf, offset);
+#endif
+ write(innum, buf, sizeof buf);
+}
+
+/* write string */
+
+PUBLIC void writes(s)
+char *s;
+{
+ write(innum, s, strlen(s));
+}
+
+/* write string followed by newline */
+
+PUBLIC void writesn(s)
+char *s;
+{
+ writes(s);
+ writenl();
+}
+
+/* write 1 word, order to suit target */
+
+PUBLIC void writew(word)
+unsigned word;
+{
+ char buf[2];
+
+ u2c2(buf, (u16_T) word);
+ write(innum, buf, sizeof buf);
+}
diff --git a/as/genobj.c b/as/genobj.c
new file mode 100644
index 0000000..80b03ce
--- /dev/null
+++ b/as/genobj.c
@@ -0,0 +1,682 @@
+/* genobj.c - object code generation routines for assembler */
+
+#include "const.h"
+#include "type.h"
+#include "address.h"
+#include "file.h"
+#include "globvar.h"
+
+#ifdef STDC_HEADERS_MISSING
+char *strcpy P((char *s1, const char *s2));
+char *strrchr P((const char *s, int c));
+unsigned strlen P((const char *s));
+#else
+#undef NULL
+#include <string.h>
+#endif
+
+#ifdef POSIX_HEADERS_MISSING
+int write P((int fd, const void *buf, unsigned nbytes));
+#else
+#undef NULL
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
+#define OBJBUFSIZE 512 /* size of object code output buffer */
+#define isge2byteoffset(offset) ((offset) >= 0x100)
+#define isge4byteoffset(offset) ((offset) >= 0x10000L)
+
+PRIVATE char hid_absbuf[OBJ_MAX_ABS_LEN]; /* absolute object code buf */
+PRIVATE char *absbuf; /* start */
+PRIVATE char *absbufend; /* last location + 1 */
+PRIVATE char *absbufptr; /* current location */
+PRIVATE struct sym_s **arrext; /* array of external symbol ptrs */
+PRIVATE char hid_objbuf[OBJBUFSIZE]; /* object code buffer */
+PRIVATE unsigned numext; /* number of external symbols */
+PRIVATE char *objbuf; /* start */
+PRIVATE char *objbufend; /* last location + 1 */
+PRIVATE char *objbufptr; /* current location */
+PRIVATE unsigned char relsize; /* current relocation size, 0 init */
+ /* local to genobjadr, but here */
+ /* because of static re-init bug */
+PRIVATE offset_t rmbcount; /* accumulator for repeated RMB's */
+
+FORWARD void flushabs P((void));
+FORWARD void flushrmb P((void));
+FORWARD void genobjadr P((struct address_s *adrptr, int size));
+FORWARD void putobj1 P((opcode_pt ch));
+FORWARD void putobj4 P((u32_T offset));
+FORWARD void putobjoffset P((offset_t offset, count_t size));
+FORWARD void putobjword P((unsigned word));
+FORWARD void writeobj P((char *buf, unsigned count));
+
+/* accumulate RMB requests into 1 (so + and - requests cancel) */
+
+PUBLIC void accumulate_rmb(offset)
+offset_t offset;
+{
+ if (objectc)
+ {
+ flushabs();
+ rmbcount += offset;
+ }
+}
+
+/* flush absolute object code buffer to object code buffer if necessary */
+
+PRIVATE void flushabs()
+{
+ 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 */
+
+PUBLIC void flushobj()
+{
+ 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 */
+
+PRIVATE void flushrmb()
+{
+ 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
+*/
+
+PUBLIC void genobj()
+{
+ 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 */
+
+PRIVATE void genobjadr(adrptr, size)
+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 */
+
+PUBLIC void initobj()
+{
+ 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
+*/
+
+PUBLIC void objheader()
+{
+ 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;
+
+ 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 == NULL)
+ truefilename = filnamptr;
+ nameptr = strrchr(truefilename, DIRCHAR);
+ strcpy(module_name, nameptr != NULL ? nameptr + 1 : truefilename);
+ if ((nameptr = strrchr(module_name, '.')) != NULL)
+ *nameptr = 0;
+ strsiz = strlen(module_name) + 1;
+ align(heapptr);
+ for (hashptr = spt, arrext = copyptr = (struct sym_s **) heapptr;
+ hashptr < spt_top;)
+ if ((symptr = *hashptr++) != NULL)
+ do
+ {
+ if ((symptr->type & EXPBIT || symptr->data & IMPBIT) ||
+ !globals_only_in_obj && symptr->name[0] != '.' &&
+ !(symptr->type & (MNREGBIT | MACBIT | VARBIT)))
+ {
+ if (copyptr >= (struct sym_s **) heapend)
+ {
+ heapptr = (char *) copyptr;
+ fatalerror(OBJSYMOV);
+ }
+ *copyptr++ = symptr;
+ strsiz += symptr->length + 1;
+#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) != NULL);
+ heapptr = (char *) (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;
+ }
+
+ /* strings */
+
+ writeobj(module_name, strlen(module_name));
+ putobj1(0);
+ for (copyptr = arrext; copyptr < copytop;)
+ {
+ symptr = *copyptr++;
+ writeobj(symptr->name, symptr->length);
+ putobj1(0);
+ }
+ putobj1(OBJ_SET_SEG | 0); /* default segment 0, |0010|SEGM| */
+}
+
+/* write trailer to object file */
+
+PUBLIC void objtrailer()
+{
+ if (objectc)
+ {
+ putobj(0); /* end of object file */
+ flushobj();
+ }
+}
+
+/* write char to absolute object code buffer, flush if necessary */
+
+PUBLIC void putabs(ch)
+opcode_pt ch;
+{
+ if (objectc)
+ {
+ if (rmbcount != 0)
+ flushrmb();
+ if (absbufptr >= absbufend)
+ flushabs();
+ *absbufptr++ = ch;
+ }
+}
+
+/* write char to object code buffer, flush if necessary */
+
+PUBLIC void putobj(ch)
+opcode_pt ch;
+{
+ if (objectc)
+ {
+ flushabs();
+ flushrmb();
+ putobj1(ch);
+ }
+}
+
+/* write char to object code buffer assuming nothing in absolute & rmb bufs */
+
+PRIVATE void putobj1(ch)
+opcode_pt ch;
+{
+ if (objbufptr >= objbufend)
+ flushobj();
+ *objbufptr++ = ch;
+}
+
+/* write 32 bit offset to object code buffer assuming ... */
+
+PRIVATE void putobj4(offset)
+u32_T offset;
+{
+ char buf[sizeof offset];
+
+ u4c4(buf, offset);
+ writeobj(buf, sizeof buf);
+}
+
+/* write sized offset to object code buffer assuming ... */
+
+PRIVATE void putobjoffset(offset, size)
+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 ... */
+
+PRIVATE void putobjword(word)
+unsigned word;
+{
+ char buf[sizeof word];
+
+ u2c2(buf, word);
+ putobj1(buf[0]);
+ putobj1(buf[1]);
+}
+
+/* write several bytes to object code buffer assuming ... */
+
+PRIVATE void writeobj(buf, count)
+char *buf;
+unsigned count;
+{
+ do
+ putobj1(*buf++);
+ while (--count);
+}
diff --git a/as/gensym.c b/as/gensym.c
new file mode 100644
index 0000000..bc773db
--- /dev/null
+++ b/as/gensym.c
@@ -0,0 +1,212 @@
+/* gensym.c - generate symbol table for assembler */
+
+#include "const.h"
+#include "type.h"
+#include "flag.h"
+#include "file.h"
+#include "globvar.h"
+
+#ifdef STDC_HEADERS_MISSING
+void *memset P((void *s, int c, unsigned n));
+int strcmp P((const char *s1, const char *s2));
+#else
+#undef NULL
+#include <string.h>
+#endif
+
+#ifdef POSIX_HEADERS_MISSING
+int write P((int fd, const void *buf, unsigned nbytes));
+#else
+#undef NULL
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
+FORWARD int printsym P((register struct sym_s *symptr, unsigned column));
+FORWARD void sort P((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 */
+
+PUBLIC void gensym()
+{
+ 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 */
+ unsigned label_stringptr; /* offset of label str from start of file */
+ register struct sym_s *symptr;
+ struct sym_s **symlptr; /* start of symbol output list */
+
+ 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 */
+
+ align(heapptr);
+ for (hashptr = spt, symlptr = copyptr = (struct sym_s **) heapptr;
+ hashptr < spt_top;)
+ if ((symptr = *hashptr++) != NULL)
+ do
+ if (!(symptr->type & (MACBIT | MNREGBIT | VARBIT)))
+ {
+ if (copyptr >= (struct sym_s **) heapend)
+ {
+ heapptr = (char *) copyptr;
+ error(SYMOUTOV); /* avoid recursive fatalerror */
+ listline(); /* the main job is OK if here */
+ goto sort_symbols;
+ }
+ *copyptr++ = symptr;
+ ++label_count;
+ labels_length += symptr->length + 3; /* 3 for type, value */
+ }
+ while ((symptr = symptr->next) != NULL);
+
+sort_symbols:
+ sort(symlptr, copyptr, TRUE); /* sort on name */
+ heapptr = (char *) (copytop = copyptr);
+ if (list.global)
+ {
+ innum = lstfil;
+ writenl();
+ writesn("Symbols:");
+ for (copyptr = symlptr, column = 0; copyptr < copytop;)
+ column = printsym(*copyptr++, column);
+ if (column != 0)
+ writenl();
+ }
+ if ((innum = symfil) != 0)
+ {
+ 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(innum, 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 */
+ }
+ }
+}
+
+/* print symbol nicely formatted for given column */
+
+PRIVATE int printsym(symptr, column)
+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 *) heapptr;
+ 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 + 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 */
+
+PRIVATE void sort(array, top, nameflag)
+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/as/globvar.h b/as/globvar.h
new file mode 100644
index 0000000..f2896fb
--- /dev/null
+++ b/as/globvar.h
@@ -0,0 +1,93 @@
+/* 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 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 */
+
+/* bookeeping for current line */
+
+EXTERN char *linebuf; /* buffer */
+
+/* for symbol table routines */
+
+EXTERN char *heapend; /* end of free space for symbol list */
+EXTERN char *heapptr; /* next free space in symbol list */
+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 */
+#define mcount (((unsigned char *) &lcjump)[LOW_BYTE])
+ /* low byte of lcjump */
+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 */
+
+#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 */
+
+#endif
+
+/* miscellaneous */
+
+extern char hexdigit[];
diff --git a/as/macro.c b/as/macro.c
new file mode 100644
index 0000000..9363947
--- /dev/null
+++ b/as/macro.c
@@ -0,0 +1,175 @@
+/* macro.c - expand macros for assembler */
+
+#include "const.h"
+#include "type.h"
+#include "globvar.h"
+#include "scan.h"
+#undef EXTERN
+#define EXTERN
+#include "macro.h"
+
+#ifdef STDC_HEADERS_MISSING
+int strncmp P((const char *s1, const char *s2, unsigned n));
+#else
+#undef NULL
+#include <string.h>
+#endif
+
+/*
+ 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.
+*/
+
+PUBLIC void entermac(symptr)
+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 = NULL;
+ *(stringptr = build_number(++macnum, 3, param1->string)) = 0;
+ macpar = (struct schain_s *) (stringptr + 1);
+ /* TODO: alignment */
+ getsym();
+ if (sym != LPAREN)
+ return; /* no other params */
+ 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 == ')')
+ {
+ if (stringptr >= (char *) macptop)
+ {
+ symname = reglineptr;
+ error(PAROV); /* no room for null */
+ return;
+ }
+ *stringptr = 0;
+ param1->next = macpar; /* ptr from previous */
+ (param1 = macpar)->next = NULL;
+ /* 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 */
+
+PUBLIC void pmacro()
+{
+ bool_t saving;
+ bool_t savingc;
+ struct sym_s *symptr;
+
+ saving = /* prepare for bad macro */
+ savingc = FALSE; /* normally don't save comments */
+ macload = TRUE; /* show loading */
+ if (label != NULL)
+ 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 == 0 || 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 = (unsigned) heapptr;
+ /* beginning of store for macro */
+ /* value s.b. (char *) */
+ 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)
+ break;
+ }
+ else if (sym != MACROARG)
+ {
+ if (!savingc)
+ continue; /* don't save comment */
+ }
+ if (!saving)
+ continue;
+ {
+ register char *reglineptr;
+ register char *regheapptr;
+
+ reglineptr = linebuf;
+ regheapptr = heapptr;
+ do
+ {
+ if (regheapptr >= heapend)
+ {
+ heapptr = regheapptr;
+ fatalerror(SYMOV); /* won't fit */
+ }
+ }
+ while ((*regheapptr++ = *reglineptr++) != EOLCHAR);
+ heapptr = regheapptr;
+ }
+ }
+ macload = FALSE;
+ if (saving)
+ {
+ *heapptr++ = ETB;
+ symptr->data = 0;
+ }
+}
diff --git a/as/macro.h b/as/macro.h
new file mode 100644
index 0000000..c37bd00
--- /dev/null
+++ b/as/macro.h
@@ -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/as/mops.c b/as/mops.c
new file mode 100644
index 0000000..209f0c8
--- /dev/null
+++ b/as/mops.c
@@ -0,0 +1,2835 @@
+/* mops.c - handle pseudo-ops */
+
+#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
+
+FORWARD void mshort2 P((void));
+FORWARD reg_pt regchk P((void));
+FORWARD void reldata 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
+
+PRIVATE 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 */
+};
+
+PRIVATE 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) */
+};
+
+PRIVATE 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 */
+};
+
+PRIVATE 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 */
+};
+
+PRIVATE 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 */
+};
+
+PRIVATE opcode_t rmfunny[] =
+{
+ 0x06, /* BP */
+ 0x07, /* BX */
+ 0x05, /* DI */
+ 0x04, /* SI */
+};
+
+PRIVATE opcode_t segoverride[] =
+{
+ 0x2E, /* CS */
+ 0x3E, /* DS */
+ 0x26, /* ES */
+ 0x64, /* FS */
+ 0x65, /* GS */
+ 0x36, /* SS */
+};
+
+PRIVATE 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 */
+};
+
+PRIVATE unsigned char calljmp_kludge;
+PRIVATE opcode_t direction;
+PRIVATE bool_t fpreg_allowed;
+PRIVATE 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
+*/
+
+PRIVATE struct ea_s source;
+PRIVATE struct ea_s source2;
+PRIVATE struct ea_s target;
+
+FORWARD void Eb P((struct ea_s *eap));
+FORWARD void Ew P((struct ea_s *eap));
+FORWARD void Ev P((struct ea_s *eap));
+FORWARD void Ex P((struct ea_s *eap));
+FORWARD void Gd P((struct ea_s *eap));
+FORWARD void Gw P((struct ea_s *eap));
+FORWARD void Gv P((struct ea_s *eap));
+FORWARD void Gx P((struct ea_s *eap));
+FORWARD void buildea P((struct ea_s *eap));
+FORWARD void buildfloat P((void));
+FORWARD void buildfreg P((void));
+FORWARD void buildimm P((struct ea_s *eap, bool_pt signflag));
+FORWARD void buildregular P((void));
+FORWARD void buildsegword P((struct ea_s *eap));
+FORWARD void buildunary P((opcode_pt opc));
+FORWARD opsize_pt displsize P((struct ea_s *eap));
+FORWARD reg_pt fpregchk P((void));
+FORWARD bool_pt getaccumreg P((struct ea_s *eap));
+FORWARD void getbinary P((void));
+FORWARD bool_pt getdxreg P((struct ea_s *eap));
+FORWARD void getea P((struct ea_s *eap));
+FORWARD void getimmed P((struct ea_s *eap, count_t immed_count));
+FORWARD void getindirect P((struct ea_s *eap));
+FORWARD void getshift P((struct ea_s *eap));
+FORWARD reg_pt indregchk P((reg_pt matchreg));
+FORWARD void kgerror P((error_pt errnum));
+FORWARD void lbranch P((int backamount));
+FORWARD void notbytesize P((struct ea_s *eap));
+FORWARD void notimmed P((struct ea_s *eap));
+FORWARD void notindirect P((struct ea_s *eap));
+FORWARD void notsegorspecreg P((struct ea_s *eap));
+FORWARD void yesimmed P((struct ea_s *eap));
+FORWARD void yes_samesize P((void));
+
+PRIVATE 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);
+ }
+}
+
+PRIVATE 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);
+ }
+}
+
+PRIVATE void Ev(eap)
+register struct ea_s *eap;
+{
+ Ex(eap);
+ notbytesize(eap);
+}
+
+PRIVATE void Ex(eap)
+register struct ea_s *eap;
+{
+ getea(eap);
+ notimmed(eap);
+ notsegorspecreg(eap);
+}
+
+PRIVATE void Gd(eap)
+register struct ea_s *eap;
+{
+ Gx(eap);
+ if (eap->size != 0x4)
+ kgerror(ILL_SIZE);
+}
+
+PRIVATE void Gw(eap)
+register struct ea_s *eap;
+{
+ Gx(eap);
+ if (eap->size != 0x2)
+ kgerror(ILL_SIZE);
+}
+
+PRIVATE void Gv(eap)
+register struct ea_s *eap;
+{
+ Gx(eap);
+ notbytesize(eap);
+}
+
+PRIVATE void Gx(eap)
+register struct ea_s *eap;
+{
+ Ex(eap);
+ notindirect(eap);
+}
+
+PRIVATE 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];
+ }
+ }
+ 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;
+ }
+ }
+}
+
+PRIVATE void buildfloat()
+{
+ if (mcount != 0x0)
+ {
+ buildea(&source);
+ oprefix = 0x0;
+ postb |= (opcode & 0x07) << REG_SHIFT;
+ opcode = ESCAPE_OPCODE_BASE | ((opcode & 0x70) >> 0x4);
+ }
+}
+
+PRIVATE void buildfreg()
+{
+ mcount += 0x2;
+ oprefix = 0x0;
+ postb = REG_MOD | ((opcode & 0x07) << REG_SHIFT) | (target.base - ST0REG);
+ opcode = ESCAPE_OPCODE_BASE | ((opcode & 0x70) >> 0x4);
+}
+
+PRIVATE 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();
+ }
+ }
+}
+
+PRIVATE void buildregular()
+{
+ if (mcount != 0x0)
+ {
+ buildea(&target);
+ postb |= regbits[source.base];
+ }
+}
+
+/* Check size and build segword. */
+
+PRIVATE 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];
+}
+
+PRIVATE void buildunary(opc)
+opcode_pt opc;
+{
+ if (mcount != 0x0)
+ {
+ buildea(&target);
+ postb |= opcode;
+ opcode = opc;
+ }
+}
+
+PRIVATE 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;
+}
+
+PRIVATE reg_pt fpregchk()
+{
+ 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;
+}
+
+PRIVATE 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.
+*/
+
+PRIVATE void getbinary()
+{
+ ++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);
+}
+
+PRIVATE 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
+*/
+
+PRIVATE 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 (!(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;
+ 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)
+ {
+ /* 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();
+ }
+ else if (!leading_immed && idefsize <= 0x2)
+ eap->indcount = 0x1; /* compatibility kludge */
+ if (!leading_displ)
+ eap->displ = lastexp;
+}
+
+PRIVATE 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);
+ }
+}
+
+PRIVATE void getindirect(eap)
+register struct ea_s *eap;
+{
+ getea(eap);
+ if (eap->indcount == 0x0)
+ kgerror(IND_REQ);
+}
+
+PRIVATE 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.
+*/
+
+PRIVATE 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;
+}
+
+PRIVATE void kgerror(errnum)
+error_pt errnum;
+{
+ error(errnum);
+ sprefix = oprefix = aprefix = mcount = 0x0;
+}
+
+PRIVATE void lbranch(backamount)
+int backamount;
+{
+ mcount += defsize + 0x1;
+ if (pass2)
+ {
+ reldata();
+ if (!(lastexp.data & (RELBIT | UNDBIT)))
+ {
+ lastexp.offset = lastexp.offset - lc - lcjump;
+ if (backamount != 0x0 && !(lastexp.data & IMPBIT) &&
+ lastexp.offset + backamount < 0x80 + backamount)
+ error(SHORTB); /* -0x8? to 0x7F, warning */
+ }
+ }
+}
+
+/* BCC (long branches emulated by short branch over & long jump) */
+
+PUBLIC void mbcc()
+{
+ getea(&target);
+ if (target.indcount >= 0x2 || target.base != NOREG)
+ kgerror(REL_REQ);
+ else
+ {
+ if (defsize != 0x2)
+ {
+ 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 */
+
+PUBLIC void mbswap()
+{
+ ++mcount;
+ Gd(&target);
+ opcode |= rm[target.base];
+}
+
+/* BR, CALL, J, JMP */
+
+PUBLIC void mcall()
+{
+ opcode_pt far;
+ bool_t indirect;
+ register struct sym_s *symptr;
+
+ far = 0x0;
+ if (sym == IDENT && (symptr = gsymptr)->type & MNREGBIT &&
+ symptr->data & SIZEBIT &&
+ symptr->value_reg_or_op.op.routine == FAROP)
+ {
+ far = 0x8;
+ getsym();
+ }
+ indirect = FALSE;
+ if (asld_compatible && idefsize <= 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)
+ {
+ 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)) &&
+ defsize == 0x2 &&
+ (offset_t) (lastexp.offset + 0x8000L) >= 0x18000L)
+ datatoobig();
+ mcount += defsize;
+ 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;
+ opcode = 0xFF;
+ }
+ }
+ else if (opcode == JMP_SHORT_OPCODE)
+ {
+ if (jumps_long)
+ {
+ 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 */
+
+PUBLIC void mcalli()
+{
+ 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
+ {
+ getcomma();
+ getea(&source);
+ yesimmed(&source);
+ if (mcount != 0x0)
+ {
+ lastexp = target.displ;
+ if (!(lastexp.data & (FORBIT | RELBIT | UNDBIT)) &&
+ defsize == 0x2 &&
+ (offset_t) (lastexp.offset + 0x8000L) >= 0x18000L)
+ datatoobig();
+ mcount += defsize;
+ source.size = 0x2;
+ buildimm(&source, FALSE);
+ }
+ }
+}
+
+/* DIV, IDIV, MUL */
+
+PUBLIC void mdivmul()
+{
+ if (getaccumreg(&source))
+ {
+ ++mcount;
+ getcomma();
+ Ex(&target);
+ yes_samesize();
+ buildunary(0xF6 | regsegword[source.base]);
+ }
+ else
+ mnegnot();
+}
+
+/* ENTER */
+
+PUBLIC void menter()
+{
+ ++mcount;
+ getimmed(&target, 0x2);
+ getcomma();
+ getimmed(&source, 0x1);
+ if (mcount != 0x0)
+ {
+ mcount += 2;
+ lastexp = target.displ; /* getimmed(&source) wiped it out */
+ }
+}
+
+/* arpl r/m16,r16 (Intel manual opcode chart wrongly says EwRw) */
+
+PUBLIC void mEwGw()
+{
+ ++mcount;
+ Ew(&target);
+ getcomma();
+ Gw(&source);
+ oprefix = 0x0;
+ buildregular();
+}
+
+/* [cmpxchg xadd] [r/m8,r8 r/m16,r16, r/m32,r32] */
+
+PUBLIC void mExGx()
+{
+ ++mcount;
+ Ex(&target);
+ getcomma();
+ Gx(&source);
+ yes_samesize();
+ opcode |= segword;
+ buildregular();
+}
+
+PUBLIC void mf_inher()
+{
+ 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 */
+
+PUBLIC void mf_m()
+{
+ ++mcount;
+ getindirect(&source);
+ if (source.size != 0x0)
+ kgerror(ILL_SIZE);
+ buildfloat();
+}
+
+/* [fldcw fnstcw] mem2i */
+
+PUBLIC void mf_m2()
+{
+ ++mcount;
+ getindirect(&source);
+ if (source.size != 0x0 && source.size != 0x2)
+ kgerror(ILL_SIZE);
+ buildfloat();
+}
+
+/* fnstsw [mem2i ax] */
+
+PUBLIC void mf_m2_ax()
+{
+ 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] */
+
+PUBLIC void mf_m2_m4()
+{
+ ++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] */
+
+PUBLIC void mf_m2_m4_m8()
+{
+ ++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)] */
+
+PUBLIC void mf_m4_m8_optst()
+{
+ 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] */
+
+PUBLIC void mf_m4_m8_stst()
+{
+ 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)] */
+
+PUBLIC void mf_m4_m8_st()
+{
+ 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)] */
+
+PUBLIC void mf_m4_m8_m10_st()
+{
+ 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 */
+
+PUBLIC void mf_m10()
+{
+ ++mcount;
+ getindirect(&source);
+ if (source.size != 0xA)
+ kgerror(ILL_SIZE);
+ buildfloat();
+}
+
+/* ffree st(i) */
+
+PUBLIC void mf_st()
+{
+ target.base = fpregchk();
+ if (target.base == NOREG)
+ kgerror(FP_REG_REQ);
+ buildfreg();
+}
+
+/* [fucom fucomp fxch] optional-st(i) */
+
+PUBLIC void mf_optst()
+{
+ if (sym == EOLSYM)
+ {
+ target.base = ST1REG;
+ buildfreg();
+ }
+ else
+ mf_st();
+}
+
+/* [faddp fdivp fdivrp fmulp fsubp fsubrp] st(i),st */
+
+PUBLIC void mf_stst()
+{
+ 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();
+}
+
+PUBLIC void mf_w_inher()
+{
+ sprefix = WAIT_OPCODE;
+ mf_inher();
+}
+
+/* [fsave fstenv] mem */
+
+PUBLIC void mf_w_m()
+{
+ sprefix = WAIT_OPCODE;
+ mf_m();
+}
+
+/* fstcw mem2i */
+
+PUBLIC void mf_w_m2()
+{
+ sprefix = WAIT_OPCODE;
+ mf_m2();
+}
+
+/* fstsw [mem2i ax] */
+
+PUBLIC void mf_w_m2_ax()
+{
+ sprefix = WAIT_OPCODE;
+ mf_m2_ax();
+}
+
+/* ADC, ADD, AND, CMP, OR, SBB, SUB, XOR */
+
+PUBLIC void mgroup1()
+{
+ 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 */
+
+PUBLIC void mgroup2()
+{
+ ++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)
+ {
+ opcode -= 0x10;
+ source.size = 0x1;
+ buildimm(&source, FALSE);
+ }
+ }
+}
+
+/* LLDT, LTR, SLDT, STR, VERR, VERW */
+
+PUBLIC void mgroup6()
+{
+ ++mcount;
+ Ew(&target);
+ oprefix = 0x0;
+ buildunary(0x0);
+}
+
+/* INVLPG, LGDT, LIDT, LMSW, SGDT, SIDT, SMSW */
+
+PUBLIC void mgroup7()
+{
+ ++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 */
+
+PUBLIC void mgroup8()
+{
+ ++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*) */
+
+PUBLIC void mGvEv()
+{
+ ++mcount;
+ Gv(&source);
+ getcomma();
+ Ev(&target);
+ yes_samesize();
+ buildregular();
+}
+
+/* bound [r16,m16&16 r32,m32&32] */
+
+PUBLIC void mGvMa()
+{
+ ++mcount;
+ Gv(&source);
+ getcomma();
+ getindirect(&target);
+ yes_samesize();
+ buildregular();
+}
+
+/* LDS, LES, LFS, LGS, LSS */
+
+PUBLIC void mGvMp()
+{
+ ++mcount;
+ Gv(&source);
+ getcomma();
+ getindirect(&target);
+ if (target.size != 0x0 && target.size != 0x2 + source.size)
+ error(MISMATCHED_SIZE);
+ buildregular();
+}
+
+/* IMUL */
+
+PUBLIC void mimul()
+{
+ ++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))
+ {
+ 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 */
+
+PUBLIC void min()
+{
+ ++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 */
+
+PUBLIC void mincdec()
+{
+ ++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 */
+
+PUBLIC void minher16()
+{
+ minher();
+ if (defsize != 0x2)
+ oprefix = 0x66;
+}
+
+/* CWDE, CDQ, CMPSD, INSD, IRETD, LODSD, POPAD, POPFD, PUSHAD, PUSHFD */
+/* MOVSD, OUTSD, SCASD, STOSD */
+
+PUBLIC void minher32()
+{
+ minher();
+ if (defsize != 0x4)
+ oprefix = 0x66;
+}
+
+/* AAD, AAM */
+
+PUBLIC void minhera()
+{
+ ++mcount;
+ if (sym == EOLSYM)
+ {
+ target.displ.offset = 0xA;
+ target.size = 0x1;
+ buildimm(&target, FALSE);
+ }
+ else
+ getimmed(&target, 0x1);
+}
+
+/* INT */
+
+PUBLIC void mint()
+{
+ ++mcount;
+ getimmed(&target, 0x1);
+ if (!(immadr.data & (FORBIT | RELBIT | UNDBIT)) &&
+ (opcode_t) immadr.offset == 0x3)
+ {
+ immcount = 0x0;
+ opcode = 0xCC;
+ }
+}
+
+/* JCC */
+
+PUBLIC void mjcc()
+{
+ if (jumps_long && opcode < 0x80) /* above 0x80 means loop - not long */
+ mbcc();
+ else
+ mshort();
+}
+
+/* JCXZ, JECXZ */
+
+PUBLIC void mjcxz()
+{
+ 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 */
+
+PUBLIC void mlea()
+{
+ Gv(&source); /* back to front */
+ getcomma();
+ ++mcount;
+ getindirect(&target);
+ yes_samesize();
+ buildregular();
+}
+
+/* MOV */
+
+PUBLIC void mmov()
+{
+ 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;
+ }
+ 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))
+ {
+ page = PAGE1_OPCODE;
+ ++mcount;
+ opcode = 0x0;
+ }
+ opcode |= direction | segword;
+ buildregular();
+ }
+ }
+}
+
+/* MOVSX, MOVZX */
+
+PUBLIC void mmovx()
+{
+ ++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 */
+
+PUBLIC void mnegnot()
+{
+ ++mcount;
+ Ex(&target);
+ buildsegword(&target);
+ buildunary(0xF6 | segword);
+}
+
+/* OUT */
+
+PUBLIC void mout()
+{
+ ++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 */
+
+PUBLIC void mpushpop()
+{
+ 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
+ {
+ opcode = 0x68;
+ if (oldopcode == POP_OPCODE)
+ ++opcode;
+ buildimm(&target, TRUE);
+ }
+ }
+ else
+ {
+ buildea(&target);
+ if (oldopcode == PUSH_OPCODE)
+ postb |= 0x6 << REG_SHIFT;
+ }
+ }
+}
+
+/* RET, RETF */
+
+PUBLIC void mret()
+{
+ ++mcount;
+ if (sym != EOLSYM)
+ {
+ --opcode;
+ getimmed(&target, 0x2);
+ }
+}
+
+/* SEG CS/DS/ES/FS/GS/SS */
+
+PUBLIC void mseg()
+{
+ reg_pt reg;
+
+ if (regsegword[reg = regchk()] != SEGMOV)
+ error(SEG_REG_REQ);
+ else
+ {
+ getsym();
+ ++mcount;
+ opcode = (segoverride - CSREG)[reg];
+ }
+}
+
+/* SETCC */
+
+PUBLIC void msetcc()
+{
+ ++mcount;
+ Eb(&target);
+ if (mcount != 0x0)
+ buildea(&target);
+}
+
+/* SHLD, SHRD */
+
+PUBLIC void mshdouble()
+{
+ ++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.
+*/
+
+PUBLIC void mtest()
+{
+ 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.
+*/
+
+PUBLIC void mxchg()
+{
+ 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();
+}
+
+PRIVATE void notbytesize(eap)
+register struct ea_s *eap;
+{
+ if (eap->size == 0x1)
+ kgerror(ILL_SIZE);
+}
+
+PRIVATE void notimmed(eap)
+register struct ea_s *eap;
+{
+ if (eap->indcount == 0x0 && eap->base == NOREG)
+ kgerror(ILL_IMM_MODE);
+}
+
+PRIVATE void notindirect(eap)
+register struct ea_s *eap;
+{
+ if (eap->indcount != 0x0)
+ kgerror(ILL_IND);
+}
+
+PRIVATE void notsegorspecreg(eap)
+register struct ea_s *eap;
+{
+ if (regsegword[eap->base] >= SEGMOV)
+ kgerror(ILLREG);
+}
+
+PRIVATE 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);
+}
+
+PRIVATE void yes_samesize()
+{
+ 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 */
+
+PRIVATE 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 */
+};
+
+PRIVATE 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 */
+};
+
+PRIVATE 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 */
+};
+
+PRIVATE 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 */
+};
+
+FORWARD void checkpostinc P((void));
+FORWARD void doaltind P((void));
+FORWARD void do1altind P((void));
+FORWARD void fixupind P((void));
+FORWARD void getindexnopost P((void));
+FORWARD void inderror P((error_pt errnum));
+FORWARD reg_pt indreg P((reg_pt maxindex));
+FORWARD void predec1 P((void));
+FORWARD void sustack P((reg_pt stackreg));
+
+PRIVATE void checkpostinc()
+{
+ 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 */
+
+PRIVATE void doaltind()
+{
+ mcount += 0x2;
+ if (sym == LBRACKET)
+ {
+ postb = INDIRECTBIT;
+ getsym();
+ do1altind();
+ if (sym != RBRACKET)
+ error(RBEXP);
+ }
+ else
+ do1altind();
+}
+
+PRIVATE void do1altind()
+{
+ 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 */
+ error(SHORTB);
+ }
+ }
+}
+
+PRIVATE void fixupind()
+{
+ if ((opcode & 0x30) == 0x0) /* change all but LEA opcodes */
+ {
+ if (opcode < 0x80)
+ opcode |= 0x60;
+ else
+ opcode |= 0x20;
+ }
+}
+
+PRIVATE void getindexnopost()
+{
+ getsym();
+ if (indreg(MAXINDREG) != NOREG)
+ fixupind();
+}
+
+PRIVATE void inderror(errnum)
+error_pt errnum;
+{
+ error(errnum);
+ 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 */
+
+PRIVATE reg_pt indreg(maxindex)
+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 */
+
+PUBLIC void mall()
+{
+ if (sym == IMMEDIATE)
+ mimmed();
+ else
+ malter();
+}
+
+/* alterable mode ops */
+
+PUBLIC void malter()
+{
+ postb = 0x0; /* not yet indexed or indirect */
+ doaltind();
+}
+
+/* indexed mode ops */
+
+PUBLIC void mindex()
+{
+ postb = INDEXBIT; /* indexed but not yet indirect */
+ doaltind();
+}
+
+/* immediate ops */
+
+PUBLIC void mimmed()
+{
+ 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 */
+
+PUBLIC void mlong()
+{
+ mcount += 0x3; /* may be 0x0 or 0x1 here */
+ expres();
+ if (pass2)
+ {
+ reldata();
+ if (!(lastexp.data & (RELBIT | UNDBIT)))
+ {
+ lastexp.offset = lastexp.offset - lc - lcjump;
+ if (!(lastexp.data & IMPBIT) &&
+ lastexp.offset + 0x81 < 0x101)
+ error(SHORTB); /* -0x81 to 0x7F, warning */
+ }
+ }
+}
+
+/* PSHS and PULS */
+
+PUBLIC void msstak()
+{
+ sustack(SREG);
+}
+
+/* TFR and EXG */
+
+PUBLIC void mswap()
+{
+ 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 */
+
+PUBLIC void mustak()
+{
+ sustack(UREG);
+}
+
+PRIVATE void predec1()
+{
+ if (postb & INDIRECTBIT)
+ inderror(ILLMOD); /* single-dec indirect illegal */
+ else
+ {
+ postb |= 0x82;
+ getindexnopost();
+ }
+}
+
+/* common routine for PSHS/PULS/PSHU/PULU */
+
+PRIVATE 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 */
+
+PUBLIC void getcomma()
+{
+ 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 */
+
+PUBLIC void minher()
+{
+ ++mcount;
+}
+
+/* short branches */
+
+PUBLIC void mshort()
+{
+ nonimpexpres();
+ mshort2();
+}
+
+PRIVATE void mshort2()
+{
+ 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 */
+
+PRIVATE reg_pt regchk()
+{
+ register struct sym_s *symptr;
+
+ if (sym == IDENT)
+ {
+ if ((symptr = gsymptr)->type & MNREGBIT)
+ {
+ if (symptr->data & REGBIT)
+ {
+#ifdef I80386
+ if (symptr->value_reg_or_op.reg == ST0REG && !fpreg_allowed)
+ error(FP_REG_NOT_ALLOWED);
+#endif
+ return symptr->value_reg_or_op.reg;
+ }
+ }
+ else if (!(symptr->type & (LABIT | MACBIT | VARBIT)))
+ symptr->data |= FORBIT; /* show seen in advance */
+ }
+ return NOREG;
+}
+
+/* convert lastexp.data for PC relative */
+
+PRIVATE void reldata()
+{
+ 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);
+}
diff --git a/as/obj1/calljmp.obj b/as/obj1/calljmp.obj
new file mode 100644
index 0000000..522d6f7
--- /dev/null
+++ b/as/obj1/calljmp.obj
Binary files differ
diff --git a/as/obj1/ea.obj b/as/obj1/ea.obj
new file mode 100644
index 0000000..6b53beb
--- /dev/null
+++ b/as/obj1/ea.obj
Binary files differ
diff --git a/as/obj1/each.obj b/as/obj1/each.obj
new file mode 100644
index 0000000..5426253
--- /dev/null
+++ b/as/obj1/each.obj
Binary files differ
diff --git a/as/obj1/f.obj b/as/obj1/f.obj
new file mode 100644
index 0000000..4dbe2d9
--- /dev/null
+++ b/as/obj1/f.obj
Binary files differ
diff --git a/as/obj1/fadd.obj b/as/obj1/fadd.obj
new file mode 100644
index 0000000..28b3dd4
--- /dev/null
+++ b/as/obj1/fadd.obj
Binary files differ
diff --git a/as/obj1/farcall.obj b/as/obj1/farcall.obj
new file mode 100644
index 0000000..259703c
--- /dev/null
+++ b/as/obj1/farcall.obj
Binary files differ
diff --git a/as/obj1/group1.obj b/as/obj1/group1.obj
new file mode 100644
index 0000000..26d4a8c
--- /dev/null
+++ b/as/obj1/group1.obj
Binary files differ
diff --git a/as/obj1/group6.obj b/as/obj1/group6.obj
new file mode 100644
index 0000000..27e81ae
--- /dev/null
+++ b/as/obj1/group6.obj
Binary files differ
diff --git a/as/obj1/group7.obj b/as/obj1/group7.obj
new file mode 100644
index 0000000..37af051
--- /dev/null
+++ b/as/obj1/group7.obj
Binary files differ
diff --git a/as/obj1/imul.obj b/as/obj1/imul.obj
new file mode 100644
index 0000000..34ef370
--- /dev/null
+++ b/as/obj1/imul.obj
Binary files differ
diff --git a/as/obj1/incdec.obj b/as/obj1/incdec.obj
new file mode 100644
index 0000000..03f583a
--- /dev/null
+++ b/as/obj1/incdec.obj
Binary files differ
diff --git a/as/obj1/inher.obj b/as/obj1/inher.obj
new file mode 100644
index 0000000..aaea0b9
--- /dev/null
+++ b/as/obj1/inher.obj
Binary files differ
diff --git a/as/obj1/inout.obj b/as/obj1/inout.obj
new file mode 100644
index 0000000..58aa820
--- /dev/null
+++ b/as/obj1/inout.obj
Binary files differ
diff --git a/as/obj1/movspec.obj b/as/obj1/movspec.obj
new file mode 100644
index 0000000..15eab78
--- /dev/null
+++ b/as/obj1/movspec.obj
Binary files differ
diff --git a/as/obj1/pushpop.obj b/as/obj1/pushpop.obj
new file mode 100644
index 0000000..2ff789e
--- /dev/null
+++ b/as/obj1/pushpop.obj
Binary files differ
diff --git a/as/obj1/seg.obj b/as/obj1/seg.obj
new file mode 100644
index 0000000..2ba948c
--- /dev/null
+++ b/as/obj1/seg.obj
Binary files differ
diff --git a/as/obj1/shdouble.obj b/as/obj1/shdouble.obj
new file mode 100644
index 0000000..ab75750
--- /dev/null
+++ b/as/obj1/shdouble.obj
Binary files differ
diff --git a/as/obj1/shift.obj b/as/obj1/shift.obj
new file mode 100644
index 0000000..520be81
--- /dev/null
+++ b/as/obj1/shift.obj
Binary files differ
diff --git a/as/obj1/xchg.obj b/as/obj1/xchg.obj
new file mode 100644
index 0000000..c39b703
--- /dev/null
+++ b/as/obj1/xchg.obj
Binary files differ
diff --git a/as/opcode.h b/as/opcode.h
new file mode 100644
index 0000000..385c096
--- /dev/null
+++ b/as/opcode.h
@@ -0,0 +1,157 @@
+/* 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,
+ FQBOP,
+ 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/as/pops.c b/as/pops.c
new file mode 100644
index 0000000..aca4841
--- /dev/null
+++ b/as/pops.c
@@ -0,0 +1,1048 @@
+/* pops.c - handle pseudo-ops for assembler */
+
+#include "const.h"
+#include "type.h"
+#include "address.h"
+#include "flag.h"
+#include "globvar.h"
+#include "opcode.h"
+#include "scan.h"
+
+PRIVATE bool_t elseflag; /* set if ELSE/ELSEIF are enabled */
+ /* depends on zero = FALSE init */
+PRIVATE bool_t lcommflag;
+
+FORWARD void bumpsem P((struct flags_s *flagptr));
+FORWARD void constdata P((unsigned size));
+FORWARD void docomm P((void));
+FORWARD void doelseif P((pfv func));
+FORWARD void doequset P((int labits));
+FORWARD void doentexp P((int entbits, int impbits));
+FORWARD void dofcc P((void));
+FORWARD void doif P((pfv func));
+FORWARD struct sym_s *needlabel P((void));
+FORWARD void showredefinedlabel P((void));
+FORWARD void setloc P((unsigned seg));
+
+PRIVATE void bumpsem(flagptr)
+register struct flags_s *flagptr;
+{
+ int newcount;
+
+ if (flagptr->global &&pass != 0)
+ {
+ /* bump semaphore count by an expression (default 1), */
+ /* then set currentflag iff semaphore count is plus */
+ if (sym == EOLSYM)
+ lastexp.offset = 1;
+ 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 */
+
+PUBLIC 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) */
+
+PUBLIC void checkdatabounds()
+{
+ if (!(lastexp.data & UNDBIT) &&
+ (offset_t) (lastexp.offset + 0x80) >= 0x180)
+ datatoobig();
+}
+
+/* allocate constant data (zero except for size 1), default zero for size 1 */
+
+PRIVATE void constdata(size)
+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);
+ }
+}
+
+PUBLIC void datatoobig()
+{
+ error(DBOUNDS);
+}
+
+/* common routine for COMM/.COMM */
+
+PRIVATE void docomm()
+{
+ 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 */
+ labptr->data = (lcdata & SEGM) | (FORBIT | IMPBIT | RELBIT);
+ showlabel();
+ }
+ }
+ lcommflag = FALSE;
+}
+
+/* common routine for ELSEIF/ELSEIFC */
+
+PRIVATE void doelseif(func)
+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;
+ }
+ }
+ }
+}
+
+/* common routine for EQU/SET */
+
+PRIVATE void doequset(labits)
+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))
+ /* 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();
+}
+
+/* common routine for ENTRY/EXPORT */
+
+PRIVATE void doentexp(entbits, impbits)
+unsigned char entbits;
+unsigned char impbits;
+{
+ struct sym_s *symptr;
+
+ while (TRUE)
+ {
+ if ((symptr = needlabel()) != NULL)
+ {
+ if (symptr->type & COMMBIT)
+ error(ALREADY);
+ else if (impbits != 0)
+ {
+ if (pass != 0)
+ ;
+ else if (symptr->type & (EXPBIT | LABIT))
+ symptr->type |= EXPBIT;
+ else
+ {
+ symptr->type |= REDBIT;
+ if (!(symptr->data & IMPBIT))
+ symptr->data |= IMPBIT | SEGM;
+ }
+ }
+ else
+ {
+ if (pass != 0)
+ {
+ 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 */
+
+PRIVATE void dofcc()
+{
+ 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 */
+
+PRIVATE void doif(func)
+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 */
+ }
+ }
+ }
+}
+
+PUBLIC void fatalerror(errnum)
+error_pt errnum;
+{
+ error(errnum);
+ skipline();
+ listline();
+ finishup();
+}
+
+/* swap position with label position, do error, put back posn */
+/* also clear label ptr */
+
+PUBLIC void labelerror(errnum)
+error_pt errnum;
+{
+ 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(errnum);
+ gsymptr = oldgsymptr;
+ lineptr = oldlineptr;
+ sym = oldsym;
+ symname = oldsymname;
+ label = NULL;
+}
+
+PRIVATE struct sym_s *needlabel()
+{
+ register struct sym_s *symptr;
+
+ if (sym != IDENT ||
+ (symptr = gsymptr)->type & (MACBIT | MNREGBIT | VARBIT))
+ {
+ error(LABEXP);
+ return NULL;
+ }
+ return symptr;
+}
+
+/* .ALIGN pseudo-op */
+
+PUBLIC void palign()
+{
+ 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 */
+
+PUBLIC void pasciz()
+{
+ dofcc();
+ databuf.fcbuf[mcount++] = 0;
+ fcflag = TRUE;
+ popflags = POPLO | POPLC;
+}
+
+/* .BLKW pseudo-op */
+
+PUBLIC void pblkw()
+{
+ constdata(2);
+}
+
+/* BLOCK pseudo-op */
+
+PUBLIC void pblock()
+{
+ 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 */
+
+PUBLIC void pbss()
+{
+ setloc(BSSLOC);
+}
+
+/* COMM pseudo-op */
+
+PUBLIC void pcomm()
+{
+ if (label == NULL)
+ labelerror(MISLAB);
+ else if (label->type & VARBIT)
+ labelerror(VARLAB); /* variable cannot be COMM'd */
+ else
+ docomm();
+}
+
+/* .COMM pseudo-op */
+
+PUBLIC void pcomm1()
+{
+ unsigned oldseg;
+
+ if (label != NULL)
+ labelerror(ILLAB);
+ oldseg = lcdata & SEGM;
+ setloc(BSSLOC);
+ if ((label = needlabel()) != NULL && checksegrel(label))
+ {
+ /* Like import. */
+ if (label->type & (EXPBIT | LABIT))
+ error(ALREADY);
+ else
+ label->data = lcdata | (FORBIT | IMPBIT | RELBIT);
+ getsym();
+ getcomma();
+ if (label->type & (EXPBIT | LABIT))
+ absexpres(); /* just to check it */
+ else
+ docomm();
+ }
+ setloc(oldseg);
+}
+
+/* .DATA pseudo-op */
+
+PUBLIC void pdata()
+{
+ setloc(DATALOC);
+}
+
+/* ELSE pseudo-op */
+
+PUBLIC void pelse()
+{
+ if (iflevel == 0)
+ error(ELSEBAD);
+ else
+ {
+ ifflag = FALSE; /* assume ELSE disabled */
+ if (elseflag)
+ {
+ ifflag = TRUE; /* ELSE enabled */
+ elseflag = FALSE;
+ }
+ }
+}
+
+/* ELSEIF pseudo-op */
+
+PUBLIC void pelseif()
+{
+ doelseif(absexpres);
+}
+
+/* ELSEIFC pseudo-op */
+
+PUBLIC void pelsifc()
+{
+ doelseif(scompare);
+}
+
+/* ENDB pseudo-op */
+
+PUBLIC void pendb()
+{
+ if (label != NULL)
+ 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 */
+
+PUBLIC void pendif()
+{
+ if (iflevel == 0)
+ error(ENDIFBAD);
+ else
+ {
+ ifflag = ifstak->ifflag;
+ elseflag = ifstak->elseflag;
+ ++ifstak;
+ --iflevel;
+ }
+}
+
+/* ENTER pseudo-op */
+
+PUBLIC void penter()
+{
+ if (!(pedata & UNDBIT))
+ error(REENTER);
+ else
+ {
+ if (!((pedata = (pedata & ~UNDBIT) | lcdata) & UNDBIT))
+ {
+ progent = lc;
+ popflags = POPLC;
+ }
+ }
+}
+
+/* ENTRY pseudo-op */
+
+PUBLIC void pentry()
+{
+ doentexp(ENTBIT, 0);
+}
+
+/* EQU pseudo-op */
+
+PUBLIC void pequ()
+{
+ register struct sym_s *labptr;
+
+ if ((labptr = label) == NULL)
+ 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 */
+
+PUBLIC void peven()
+{
+ popflags = POPLONG | POPHI | POPLO | POPLC;
+ accumulate_rmb(lcjump = lastexp.data = lc & 1);
+}
+
+/* EXPORT pseudo-op */
+
+PUBLIC void pexport()
+{
+ doentexp(0, 0);
+}
+
+/* FAIL pseudo-op */
+
+PUBLIC void pfail()
+{
+ error(FAILERR);
+}
+
+/* FCB pseudo-op */
+
+PUBLIC void pfcb()
+{
+ 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 */
+
+PUBLIC void pfcc()
+{
+ dofcc();
+ if (mcount != 0)
+ {
+ fcflag = TRUE;
+ popflags = POPLO | POPLC;
+ }
+}
+
+/* FDB pseudo-op */
+
+PUBLIC void pfdb()
+{
+ 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 */
+
+PUBLIC void pfqb()
+{
+ 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 */
+
+PUBLIC void pglobl()
+{
+ if (binaryg)
+ error(NOIMPORT);
+ doentexp(0, IMPBIT);
+}
+
+/* IDENT pseudo-op (not complete) */
+
+PUBLIC void pident()
+{
+ if (sym != IDENT)
+ error(LABEXP);
+ else
+ getsym_nolookup(); /* should save ident string */
+}
+
+/* IF pseudo-op */
+
+PUBLIC void pif()
+{
+ doif(absexpres);
+}
+
+/* IFC pseudo-op */
+
+PUBLIC void pifc()
+{
+ doif(scompare);
+}
+
+/* IMPORT pseudo-op */
+
+PUBLIC void pimport()
+{
+ struct sym_s *symptr;
+
+ if (binaryg)
+ error(NOIMPORT);
+ while (TRUE)
+ {
+ if ((symptr = needlabel()) != NULL && checksegrel(symptr))
+ {
+ if (symptr->type & (COMMBIT | EXPBIT | LABIT))
+ /* IMPORT is null if label (to be) declared */
+ error(ALREADY);
+ else
+ /* get current segment from lcdata, no need to mask rest */
+ symptr->data = lcdata | (FORBIT | IMPBIT | RELBIT);
+ }
+ getsym();
+ if (sym != COMMA)
+ break;
+ getsym();
+ }
+}
+
+/* LCOMM pseudo-op */
+
+PUBLIC void plcomm()
+{
+ lcommflag = TRUE;
+ pcomm();
+}
+
+/* .LCOMM pseudo-op */
+
+PUBLIC void plcomm1()
+{
+ lcommflag = TRUE;
+ pcomm1();
+}
+
+/* .LIST pseudo-op */
+
+PUBLIC void plist()
+{
+ bumpsem(&list);
+}
+
+/* LOC pseudo-op */
+
+PUBLIC void ploc()
+{
+ if (label != NULL)
+ labelerror(ILLAB);
+ absexpres();
+ if (!(lastexp.data & UNDBIT))
+ {
+ if (lastexp.offset >= NLOC)
+ datatoobig();
+ else
+ setloc((unsigned) lastexp.offset);
+ }
+}
+
+/* .MACLIST pseudo-op */
+
+PUBLIC void pmaclist()
+{
+ bumpsem(&maclist);
+}
+
+/* .MAP pseudo-op */
+
+PUBLIC void pmap()
+{
+ absexpres();
+ if (!(lastexp.data & UNDBIT))
+ {
+ mapnum = lastexp.offset;
+ popflags = POPLO;
+ if (lastexp.offset >= 0x100)
+ datatoobig();
+ }
+}
+
+/* ORG pseudo-op */
+
+PUBLIC void porg()
+{
+ if (label != NULL)
+ labelerror(ILLAB);
+ absexpres();
+ if (!((lcdata = lastexp.data) & UNDBIT))
+ {
+ accumulate_rmb(lastexp.offset - lc);
+ binmbuf = lc = lastexp.offset;
+ popflags = POPLC;
+ }
+}
+
+/* RMB pseudo-op */
+
+PUBLIC void prmb()
+{
+ constdata(1);
+}
+
+/* .SECT pseudo-op */
+
+PUBLIC void psect()
+{
+ if (label != NULL)
+ 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 */
+
+PUBLIC void pset()
+{
+ register struct sym_s *labptr;
+
+ if ((labptr = label) == NULL)
+ labelerror(MISLAB);
+ else if (labptr->type & COMMBIT)
+ labelerror(RELAB); /* common cannot be SET'd */
+ else
+ doequset(labptr->type & LABIT ? 0 : VARBIT);
+}
+
+/* SETDP pseudo-op */
+
+PUBLIC void psetdp()
+{
+ absexpres();
+ if (!(lastexp.data & UNDBIT))
+ {
+ dirpag = lastexp.offset;
+ popflags = POPLO;
+ if (lastexp.offset >= 0x100)
+ datatoobig();
+ }
+}
+
+/* .TEXT pseudo-op */
+
+PUBLIC void ptext()
+{
+ setloc(TEXTLOC);
+}
+
+/* .WARN pseudo-op */
+
+PUBLIC void pwarn()
+{
+ bumpsem(&warn);
+}
+
+#ifdef I80386
+
+/* USE16 pseudo-op */
+
+PUBLIC void puse16()
+{
+ defsize = 2;
+}
+
+/* USE16 pseudo-op */
+
+PUBLIC void puse32()
+{
+ defsize = 4;
+}
+
+#endif
+
+/* show redefined label and error, and set REDBIT */
+
+PRIVATE void showredefinedlabel()
+{
+ register struct sym_s *labptr;
+
+ labptr = label; /* showlabel() will kill label prematurely */
+ showlabel();
+ if (!(labptr->type & REDBIT))
+ {
+ labptr->type |= REDBIT;
+ labelerror(RELAB);
+ }
+}
+
+PUBLIC void showlabel()
+{
+ register struct sym_s *labptr;
+
+ labptr = label;
+ lastexp.data = labptr->data;
+ lastexp.offset = labptr->value_reg_or_op.value;
+ popflags = POPLONG | POPHI | POPLO;
+ label = NULL; /* show handled by COMM, EQU or SET */
+}
+
+/* set location segment */
+
+PRIVATE void setloc(seg)
+unsigned seg;
+{
+ if (pass != 0 && 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/as/proto.h b/as/proto.h
new file mode 100644
index 0000000..e348413
--- /dev/null
+++ b/as/proto.h
@@ -0,0 +1,218 @@
+/* extern functions */
+
+#if __STDC__
+#define P(x) x
+#else
+#define P(x) ()
+#endif
+
+/* as.c */
+int main P((int argc, char **argv));
+void as_abort P((char *message));
+void finishup P((void));
+void initp1p2 P((void));
+
+/* assemble.c */
+void assemble P((void));
+
+/* error.c */
+char *build_error_message P((error_pt errnum, char *buf));
+
+/* express.c */
+void absexpres P((void));
+void chkabs P((void));
+void nonimpexpres P((void));
+void showrelbad P((void));
+void symabsexpres P((void));
+void symexpres P((void));
+void expres P((void));
+void factor P((void));
+void scompare P((void));
+
+/* genbin.c */
+void binheader P((void));
+void bintrailer P((void));
+void genbin P((void));
+void initbin P((void));
+void putbin P((int ch));
+
+/* genlist.c */
+char *build_2hex_number P((unsigned num, char *where));
+char *build_number P((unsigned num, unsigned width, char *where));
+void error P((error_pt errnum));
+void listline P((void));
+void writec P((int ch));
+void writenl P((void));
+void writeoff P((offset_t offset));
+void writes P((char *s));
+void writesn P((char *s));
+void writew P((unsigned word));
+
+/* genobj.c */
+void accumulate_rmb P((offset_t offset));
+void flushobj P((void));
+void genobj P((void));
+void initobj P((void));
+void objheader P((void));
+void objtrailer P((void));
+void putabs P((opcode_pt ch));
+void putobj P((opcode_pt ch));
+
+/* gensym.c */
+void gensym P((void));
+
+/* macro.c */
+void entermac P((struct sym_s *symptr));
+void pmacro P((void));
+
+/* mops.c */
+#ifdef I80386
+void mbcc P((void));
+void mbswap P((void));
+void mcall P((void));
+void mcalli P((void));
+void mdivmul P((void));
+void menter P((void));
+void mEwGw P((void));
+void mExGx P((void));
+void mf_inher P((void));
+void mf_m P((void));
+void mf_m2 P((void));
+void mf_m2_ax P((void));
+void mf_m2_m4 P((void));
+void mf_m2_m4_m8 P((void));
+void mf_m4_m8_optst P((void));
+void mf_m4_m8_st P((void));
+void mf_m4_m8_stst P((void));
+void mf_m4_m8_m10_st P((void));
+void mf_m10 P((void));
+void mf_optst P((void));
+void mf_st P((void));
+void mf_stst P((void));
+void mf_w_inher P((void));
+void mf_w_m P((void));
+void mf_w_m2 P((void));
+void mf_w_m2_ax P((void));
+void mgroup1 P((void));
+void mgroup2 P((void));
+void mgroup6 P((void));
+void mgroup7 P((void));
+void mgroup8 P((void));
+void mGvEv P((void));
+void mGvMa P((void));
+void mGvMp P((void));
+void mimul P((void));
+void min P((void));
+void mincdec P((void));
+void minher P((void));
+void minher16 P((void));
+void minher32 P((void));
+void minhera P((void));
+void mint P((void));
+void mjcc P((void));
+void mjcxz P((void));
+void mlea P((void));
+void mmov P((void));
+void mmovx P((void));
+void mnegnot P((void));
+void mout P((void));
+void mpushpop P((void));
+void mret P((void));
+void mseg P((void));
+void msetcc P((void));
+void mshdouble P((void));
+void mtest P((void));
+void mxchg P((void));
+#endif /* I80386 */
+
+#ifdef MC6809
+void mall P((void));
+void malter P((void));
+void mimmed P((void));
+void mindex P((void));
+void minher P((void));
+void mlong P((void));
+void msstak P((void));
+void mswap P((void));
+void mustak P((void));
+#endif /* MC6809 */
+
+void getcomma P((void));
+void mshort P((void));
+
+/* pops.c */
+bool_pt checksegrel P((struct sym_s *symptr));
+void checkdatabounds P((void));
+void datatoobig P((void));
+void fatalerror P((error_pt errnum));
+void labelerror P((error_pt errnum));
+void palign P((void));
+void pasciz P((void));
+void pblkw P((void));
+void pblock P((void));
+void pbss P((void));
+void pcomm P((void));
+void pcomm1 P((void));
+void pdata P((void));
+void pelse P((void));
+void pelseif P((void));
+void pelsifc P((void));
+void pendb P((void));
+void pendif P((void));
+void penter P((void));
+void pentry P((void));
+void pequ P((void));
+void peven P((void));
+void pexport P((void));
+void pfail P((void));
+void pfcb P((void));
+void pfcc P((void));
+void pfdb P((void));
+void pfqb P((void));
+void pglobl P((void));
+void pident P((void));
+void pif P((void));
+void pifc P((void));
+void pimport P((void));
+void plcomm P((void));
+void plcomm1 P((void));
+void plist P((void));
+void ploc P((void));
+void pmaclist P((void));
+void pmap P((void));
+void porg P((void));
+void prmb P((void));
+void psect P((void));
+void pset P((void));
+void psetdp P((void));
+void ptext P((void));
+void puse16 P((void));
+void puse32 P((void));
+void pwarn P((void));
+void showlabel P((void));
+
+/* readsrc.c */
+void initsource P((void));
+fd_t open_input P((char *name));
+void pget P((void));
+void pproceof P((void));
+void readline P((void));
+void skipline P((void));
+
+/* scan.c */
+void context_hexconst P((void));
+void getsym P((void));
+void getsym_nolookup P((void));
+void initscan P((void));
+
+/* table.c */
+void inst_keywords P((void));
+struct sym_s *lookup P((void));
+void statistics P((void));
+
+/* type.c */
+void u2c2 P((char *buf, u16_pt offset));
+void u4c4 P((char *buf, u32_T offset));
+void u2cn P((char *buf, u16_pt offset, unsigned count));
+void u4cn P((char *buf, u32_T offset, unsigned count));
+bool_pt typeconv_init P((bool_pt big_endian, bool_pt long_big_endian));
diff --git a/as/readsrc.c b/as/readsrc.c
new file mode 100644
index 0000000..39bd063
--- /dev/null
+++ b/as/readsrc.c
@@ -0,0 +1,341 @@
+#define MAXLINE 256 /* when this is made bigger, fix pfcc not
+ * to store the string length in a byte-
+ * sized variable */
+
+/* readsrc.c - read source files for assembler */
+
+#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"
+
+#ifdef POSIX_HEADERS_MISSING
+#define O_RDONLY 0
+typedef long off_t;
+int close P((int fd));
+off_t lseek P((int fd, off_t offset, int whence));
+int open P((const char *path, int oflag, ...));
+int read P((int fd, void *buf, unsigned nbytes));
+#else
+#undef NULL
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#endif
+
+struct fcbstruct /* file control block structure */
+{
+ fd_t fd; /* file descriptor */
+ char *lineptr; /* current spot in line */
+ char *buf; /* start of buffer (after partial line) */
+ char *first; /* start of partial line before buf */
+ char *limit; /* end of used part of input buffer */
+ int blocksize; /* chars from last read and partial line flag */
+ struct fbufstruct *includer;/* buffer of file which included current one */
+};
+
+struct fbufstruct /* file buffer structure */
+{
+ struct fcbstruct fcb; /* status after opening an include sub-file */
+ char fpartline[MAXLINE + 1];/* buffer for partial line */
+ char fbuf[INBUFSIZE + 1]; /* buffer to read into */
+ char fname[1]; /* file name (variable length), 1 for null */
+};
+
+struct get_s /* to record included files */
+{
+ fd_t fd;
+ unsigned line;
+ off_t position;
+};
+
+PRIVATE char hid_filnambuf[FILNAMLEN + 1]; /* buffer for file name */
+
+PRIVATE struct get_s hid_getstak[MAXGET]; /* GET stack */
+PRIVATE struct get_s *getstak; /* ptr */
+
+PRIVATE struct fcbstruct input; /* current input file control block */
+ /* input.lineptr is not kept up to date */
+ /* input.fd depends on zero init */
+PRIVATE struct fbufstruct xyz;
+PRIVATE struct fbufstruct *inputbuf; /* current input file buffer */
+ /* its fcb only to date in includes */
+
+PRIVATE char hid_linebuf[LINLEN]; /* line buffer */
+PRIVATE char *maclinebuf;
+PRIVATE char *maclineptr;
+
+FORWARD void clearsource P((void));
+FORWARD void line_too_long P((void));
+
+PRIVATE void clearsource()
+{
+ input.includer = inputbuf;
+ inputbuf = &xyz;
+ input.first = input.limit = input.buf = inputbuf->fbuf;
+ *(lineptr = linebuf = input.first - 1) = EOLCHAR;
+ input.blocksize = 0;
+}
+
+PRIVATE void line_too_long()
+{
+ symname = linebuf + (LINLEN - 1); /* spot for the error */
+ error(LINLONG); /* so error is shown in column LINLEN - 1 */
+}
+
+/* initialise private variables */
+
+PUBLIC void initsource()
+{
+ filnamptr = hid_filnambuf;
+ getstak = hid_getstak + MAXGET;
+ clearsource(); /* sentinel to invoke blank skipping */
+}
+
+PUBLIC fd_t open_input(name)
+char *name;
+{
+ fd_t fd;
+
+ if ((unsigned) (fd = open(name, O_RDONLY)) > 255)
+ as_abort("error opening input file");
+ 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
+*/
+
+PUBLIC void pget()
+{
+#if OLD
+ if (infiln >= MAXGET)
+ error(GETOV);
+ else
+ {
+ skipline();
+ listline();
+ if (infiln != 0)
+ {
+ --getstak;
+ getstak->fd = infil;
+ getstak->line = linum;
+ getstak->position = lseek(infil, 0L, 1) - (inbufend - inbufptr);
+ ++infiln;
+ linum = 0;
+ infil = open_input(lineptr - 1);
+ }
+ }
+#else
+ as_abort("get/include pseudo-op not implemented");
+#endif
+}
+
+/* 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 */
+
+PUBLIC void pproceof()
+{
+ if (infiln != 0)
+ close(infil);
+ if (lineptr == linebuf)
+ list.current = FALSE; /* don't list line after last unless error */
+ 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 (lcdata & UNDBIT)
+ error(EOFLC);
+ lcptr->data = lcdata;
+ lcptr->lc = lc;
+ }
+ /* macros must be closed before end of all files */
+ if (macload)
+ error(EOFMAC);
+ listline(); /* last line or line after last if error */
+ if (infiln != infil0)
+ {
+ infil = getstak->fd;
+ linum = getstak->line;
+ if (--infiln != 0)
+ lseek(infil, getstak->position, 0);
+ ++getstak;
+ }
+ else if (!pass)
+ {
+ pass = TRUE;
+ objheader(); /* while pass 1 data all valid */
+ binmbuf = 0; /* reset zero variables */
+ maclevel = iflevel = blocklevel =
+ totwarn = toterr = linum = macnum = 0;
+ initp1p2(); /* reset other varaiables */
+ binaryc = binaryg;
+#ifdef I80386
+ defsize = idefsize;
+#endif
+ list.current = list.global;
+ maclist.current = maclist.global;
+
+ warn.current = TRUE;
+ if (warn.semaphore < 0)
+ warn.current = FALSE;
+ if (infiln != 0)
+ infil = open_input(filnamptr);
+ binheader();
+ }
+ 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.
+*/
+
+PUBLIC void readline()
+{
+ 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 char 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) == NULL)
+ break;
+ if (parameters != NULL)
+ {
+ 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;
+ *reglineptr = EOLCHAR;
+ return;
+ }
+ }
+ if (macflag)
+ {
+ linebuf = maclinebuf;
+ lineptr = maclineptr;
+ macflag = FALSE;
+ }
+again:
+ ++linum;
+ ++lineptr; /* if eof, this is input.limit + 1 */
+ if (input.blocksize != 0) /* and this routine just resets eof */
+ {
+ if (lineptr < input.limit) /* move back partial line */
+ {
+ register char *col;
+
+ col = input.buf;
+ while ((*--col = *--input.limit) != EOLCHAR)
+ ;
+ input.first = col + 1;
+ ++input.limit;
+ input.blocksize = 0;
+ }
+ else /* may be non-terminated line, don't stop */
+ lineptr = input.limit;
+ }
+ if (lineptr == input.limit)
+ {
+ lineptr = input.first;
+ input.blocksize = read(infil, input.buf, INBUFSIZE);
+ if (input.blocksize < 0)
+ as_abort("error reading input");
+ if (input.blocksize == 0)
+ {
+ clearsource();
+ pproceof();
+ if (macload)
+ {
+ symname = lineptr;
+ return; /* macro not allowed across eof */
+ }
+ goto again;
+ }
+ input.first = input.buf;
+ *(input.limit = input.buf + input.blocksize) = EOLCHAR;
+ }
+ linebuf = lineptr;
+ if (lineptr >= input.limit)
+ *(lineptr = input.limit = input.buf) = EOLCHAR;
+}
+
+PUBLIC void skipline()
+{
+ register char *reglineptr;
+
+ reglineptr = lineptr - 1;
+ while (*reglineptr != EOLCHAR)
+ ++reglineptr;
+ lineptr = reglineptr;
+}
diff --git a/as/scan.c b/as/scan.c
new file mode 100644
index 0000000..56c6bf3
--- /dev/null
+++ b/as/scan.c
@@ -0,0 +1,247 @@
+/* scan.c - lexical analyser for assembler */
+
+#include "const.h"
+#include "type.h"
+#include "globvar.h"
+#undef EXTERN
+#define EXTERN
+#include "scan.h"
+
+PRIVATE int numbase; /* base for number */
+
+PRIVATE char symofchar[256] = /* table to convert chars to their symbols */
+{
+ WHITESPACE, 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
+};
+
+FORWARD void intconst P((void));
+
+PUBLIC void context_hexconst()
+{
+ numbase = 16;
+ intconst();
+}
+
+PUBLIC void getsym()
+{
+ 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;
+}
+
+PUBLIC void getsym_nolookup()
+{
+ bool_t old_ifflag;
+
+ old_ifflag = ifflag;
+ ifflag = FALSE;
+ getsym();
+ ifflag = old_ifflag;
+}
+
+PRIVATE void intconst()
+{
+ 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;
+}
+
+PUBLIC void initscan()
+{
+ if (asld_compatible)
+ {
+ lindirect = LPAREN;
+ rindexp = RPEXP;
+ rindirect = RPAREN;
+ }
+ else
+ {
+ lindirect = LBRACKET;
+ rindexp = RBEXP;
+ rindirect = RBRACKET;
+ }
+}
diff --git a/as/scan.h b/as/scan.h
new file mode 100644
index 0000000..22def98
--- /dev/null
+++ b/as/scan.h
@@ -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 int 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/as/source.h b/as/source.h
new file mode 100644
index 0000000..0181e54
--- /dev/null
+++ b/as/source.h
@@ -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/as/table.c b/as/table.c
new file mode 100644
index 0000000..66d9332
--- /dev/null
+++ b/as/table.c
@@ -0,0 +1,945 @@
+/* table.c - keyword tables and symbol table lookup for assembler */
+
+#include "const.h"
+#include "type.h"
+#include "globvar.h"
+#include "opcode.h"
+#include "scan.h"
+
+#ifdef STDC_HEADERS_MISSING
+int memcmp P((const void *s1, const void *s2, unsigned n));
+#else
+#undef NULL
+#include <string.h>
+#endif
+
+#define hconv(ch) ((unsigned char) (ch) - 0x41) /* better form for hashing */
+
+#ifdef DEBUG
+unsigned nhash;
+unsigned nlookup;
+unsigned nsym;
+unsigned nx[30];
+FORWARD void printchain P((void));
+#endif
+
+/* --- start of keywords --- */
+
+/* registers */
+/* the register code (internal to assembler) is given in 1 byte */
+/* the "opcode" field is not used */
+
+PUBLIC 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 */
+
+PUBLIC 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,
+ 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) */
+
+PUBLIC 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,
+ 6, '.', 'D', 'A', 'T', 'A', '4', FQBOP, 0,
+ 2, 'D', 'B', FCBOP, 0,
+ 2, 'D', 'D', FQBOP, 0,
+ 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,
+ 5, '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,
+ 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,
+ 5, '.', 'L', 'O', 'N', 'G', FQBOP, 0,
+ 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,
+ 5, 'U', 'S', 'E', '1', '6', USE16OP, 0,
+ 5, 'U', 'S', 'E', '3', '2', USE32OP, 0,
+ 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 */
+};
+
+PUBLIC 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,
+ 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,
+ 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 */
+};
+
+PUBLIC 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
+PUBLIC 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 --- */
+
+FORWARD void install P((register char *keyptr, int data));
+
+PUBLIC 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
+}
+
+PRIVATE void install(keyptr, data)
+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 (NULL if not found and not installed)
+ * unless symbol table overflows, when routine aborts.
+ */
+
+PUBLIC struct sym_s *lookup()
+{
+ struct sym_s **hashptr;
+ register char *nameptr;
+ register struct sym_s *symptr;
+ register unsigned hashval;
+ register unsigned length;
+#ifdef DEBUG
+ 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(nameptr[-(length / 2)]) * MULTIPLIER,
+ hashval ^= hconv(nameptr[-2]) << 2,
+ hashval ^= hconv(nameptr[-1]);
+ nameptr = symname;
+ if ((symptr = *(hashptr = spt +
+ (hashval ^ (hconv(nameptr[0]) << 1)) % SPTSIZ))
+ != NULL)
+ {
+ do
+ {
+#ifdef DEBUG
+ 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) != NULL);
+
+ /* Calculate last non-NULL 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 != NULL);
+ }
+ if (!ifflag)
+ return NULL;
+ align(heapptr);
+ if (heapptr >= heapend)
+ fatalerror(SYMOV);
+#ifdef DEBUG
+ ++nsym;
+ if (hashptr >= spt && hashptr < spt + SPTSIZ)
+ ++nhash;
+#endif
+ *hashptr = symptr = (struct sym_s *) heapptr;
+ symptr->type = 0;
+ symptr->data = inidata;
+ symptr->length = length;
+ symptr->value_reg_or_op.value = (unsigned) (symptr->next = NULL);
+ heapptr = symptr->name;
+ do
+ *heapptr++ = *nameptr++;
+ while (--length != 0);
+ *heapptr++ = 0;
+ return symptr;
+}
+
+#ifdef DEBUG
+
+static void printchain(hashval)
+unsigned hashval;
+{
+ register struct sym_s *symptr;
+
+ printf("%04x ", hashval);
+ for (symptr = spt[hashval]; symptr != NULL; symptr = symptr->next)
+ printf("%s ", symptr->name);
+ printf("\n");
+}
+
+#endif
+
+PUBLIC void statistics()
+{
+#ifdef DEBUG
+ 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", w;
+#endif
+}
diff --git a/as/todo b/as/todo
new file mode 100644
index 0000000..e85cb6c
--- /dev/null
+++ b/as/todo
@@ -0,0 +1,14 @@
+Check why `chk' fails.
+
+Update 6809/const.h.
+
+Produce bsd symbol tables.
+
+Accept gas format.
+
+Decide how to choose between 8-bit and 32-bit branches. 16-bit branches in
+32-bit mode are unusable because top 16 bits of PC are messed up.
+
+Limit insns to specified processor (warn for 386 insns on 8086).
+
+Buffer for printing of listing.
diff --git a/as/type.h b/as/type.h
new file mode 100644
index 0000000..978c7d8
--- /dev/null
+++ b/as/type.h
@@ -0,0 +1,167 @@
+/* type.h - types for assembler */
+
+/* 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 error_pt;
+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 (NULL 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"