--- /dev/null
+#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
--- /dev/null
+PLATFORM = 6809
+CC = m6809-unknown-gcc
+# These are wrappers for lwasm and lwar
+ASM = m6809-unknown-as
+AR = m6809-unknown-ar
+LINKER = lwlink
+CFLAGS = -I../../Library/include -I../../Library/include/6502 -Wall -pedantic -fno-strict-aliasing
+COPT = -Os
+LINKER_OPT = --format=raw -L../../Library/libs -lc6809
+LIBGCCDIR = $(dir $(shell $(CC) -print-libgcc-file-name))
+LINKER_OPT += -L$(LIBGCCDIR) -lgcc -m as09.map
+LINKER_OPT += --script=../util/$(TARGET).link
+ASM_OPT = -o
+CRT0 = ../../Library/libs/crt0_6809.o
+
+OBJS =as.o assemble.o errors.o express.o \
+ genbin.o genlist.o genobj.o gensym.o \
+ keywords.o macro.o mops.o pops.o readsrc.o \
+ scan.o table.o typeconv.o alloc.o
+
+all: as09
+
+as09: $(OBJS)
+ $(LINKER) -o $@ $(LINKER_OPT) $(CRT0) $(OBJS)
+
+clean realclean clobber:
+ rm -f *.o as09 *~
+
+.c.o:
+ $(CC) $(CFLAGS) $(COPT) -c $<
+
+$(OBJS): const.h errors.h
+
+as.o: const.h type.h byteord.h macro.h file.h flag.h globvar.h
+assemble.o: const.h type.h address.h globvar.h opcode.h scan.h
+error.o: const.h type.h
+express.o: const.h type.h address.h globvar.h scan.h source.h
+genbin.o: const.h type.h address.h file.h globvar.h
+genlist.o: const.h type.h address.h flag.h file.h globvar.h macro.h scan.h \
+ source.h
+genobj.o: const.h type.h address.h file.h globvar.h
+gensym.o: const.h type.h flag.h file.h globvar.h
+keywords.o: const.h type.h globvar.h opcode.h
+macro.o: const.h type.h globvar.h scan.h macro.h
+mops.o: const.h type.h globvar.h opcode.h scan.h address.h
+pops.o: const.h type.h address.h flag.h globvar.h opcode.h scan.h
+readsrc.o: const.h type.h flag.h file.h globvar.h macro.h scan.h source.h
+scan.o: const.h type.h globvar.h scan.h
+table.o: const.h type.h globvar.h opcode.h scan.h
--- /dev/null
+/* 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;
--- /dev/null
+/* align.h - memory alignment requirements for linker */
+
+/* Copyright (C) 1994 Bruce Evans */
+
+#ifndef S_ALIGNMENT
+# define align(x)
+#else
+
+#if defined(__STDC__) && defined(_POSIX_SOURCE)
+# define align(x) ((x)=(void *) \
+ (((ssize_t)(x) + (S_ALIGNMENT-1)) & ~(S_ALIGNMENT-1)))
+#else
+# define align(x) ((x)=(void *) \
+ ((char *)(x) + ((S_ALIGNMENT-(char)(x)) & (S_ALIGNMENT-1))))
+#endif
+#endif
+
+
+
+
+
+
+
--- /dev/null
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "align.h"
+
+static char NOMEMEORY[] = "Cannot allocate sufficient memory";
+
+#ifdef USE_FIXED_HEAP
+static char *heapend; /* end of free space for symbol list */
+static char *heapptr; /* next free space in symbol list */
+#endif
+
+#ifndef USE_FIXED_HEAP
+static char tempbuf[2048];
+#endif
+
+void init_heap(void)
+{
+#ifdef USE_FIXED_HEAP
+#ifndef USERMEM
+#define USERMEM 0xAC00U
+#endif
+
+#if defined(__AS386_16__) || defined(__m6809__)
+ int stk;
+ heapptr = sbrk(0);
+ heapend = ((char*)&stk) - STAKSIZ - 16;
+ brk(heapend);
+ if(sbrk(0) != heapend)
+ as_abort(NOMEMEORY);
+#else
+#ifdef SOS_EDOS
+ heapend = stackreg() - STAKSIZ;
+#else
+ heapptr = malloc(USERMEM);
+ heapend = heapptr + USERMEM;
+ if (heapptr == 0)
+ as_abort(NOMEMEORY);
+#endif
+#endif
+#endif
+}
+
+void *temp_buf(void)
+{
+#ifdef USE_FIXED_HEAP
+ return heapptr;
+#else
+ return tempbuf;
+#endif
+}
+
+void *asalloc(unsigned int size)
+{
+ void * rv;
+#ifdef USE_FIXED_HEAP
+ align(heapptr);
+ if (heapptr+size < heapend)
+ {
+ rv = heapptr;
+ heapptr += size;
+ }
+ else
+ rv = 0;
+#else
+ rv = malloc(size);
+#endif
+ if (rv == 0 && size) as_abort(NOMEMEORY);
+ return rv;
+}
+
+
+void *asrealloc(void *oldptr, unsigned int size)
+{
+ void * rv;
+#ifdef USE_FIXED_HEAP
+ if (oldptr == 0) return asalloc(size);
+
+ if ((char*)oldptr+size < heapend)
+ {
+ heapptr = (char*)oldptr + size;
+ rv = oldptr;
+ }
+ else
+ rv = 0;
+#else
+ rv = realloc(oldptr, size);
+#endif
+
+ if (rv == 0) as_abort(NOMEMEORY);
+ return rv;
+}
+
--- /dev/null
+/* as.c - assembler */
+
+/*
+ usage: as source [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] [-guw]
+ in any order (but no repeated file options)
+*/
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "byteord.h"
+#include "macro.h"
+#undef EXTERN
+#define EXTERN
+#include "file.h"
+#include "flag.h"
+#include "globvar.h"
+#include "version.h"
+
+char hexdigit[] = "0123456789ABCDEF"; /* XXX - ld uses lower case */
+
+static struct block_s hid_blockstak[MAXBLOCK]; /* block stack */
+static struct lc_s hid_lctab[NLOC]; /* location counter table */
+static struct if_s hid_ifstak[MAXBLOCK]; /* if stack */
+static struct schain_s hid_mcpar[MACPSIZ]; /* MACRO params */
+static struct macro_s hid_macstak[MAXBLOCK]; /* macro stack */
+static struct sym_s *hid_spt[SPTSIZ]; /* hash table */
+
+static char * binfilename = 0;
+static char * objfilename = 0;
+static int keep_bad_output = 0;
+
+static void initp1 P((void));
+static int my_creat P((char *name, char *message));
+static void process_args P((int argc, char **argv));
+static void summary P((fd_t fd));
+static void summ_number P((unsigned num));
+static void usage P((void));
+
+int main(int argc, char *argv[])
+{
+ init_heap();
+ initp1();
+ initp1p2();
+ inst_keywords();
+ initbin();
+ initobj();
+ initsource();
+ typeconv_init(INT_BIG_ENDIAN, LONG_BIG_ENDIAN);
+ as_warn.global = TRUE; /* constant */
+ as_warn.semaphore = -1;
+ last_pass=1;
+ process_args(argc, argv);
+ initscan();
+ line_zero();
+
+ assemble(); /* doesn't return, maybe use setjmp */
+
+ /* NOTREACHED */
+ return 0;
+}
+
+void as_abort(char *message)
+{
+ write(STDOUT, "as: ", 4);
+ write(STDOUT, message, strlen(message));
+ write(STDOUT, "\n", 1);
+ exit(1);
+}
+
+void finishup(void)
+{
+ bintrailer();
+ objtrailer();
+ if (list.global ||symgen)
+ gensym(); /* output to lstfil and/or symfil */
+ if (list.global ||toterr != 0 || totwarn != 0)
+ summary(lstfil);
+ if (lstfil != STDOUT && (toterr != 0 || totwarn != 0))
+ summary(STDOUT);
+ statistics();
+
+ /* If an output binary is in error remove it */
+ close(binfil); binfil=0;
+ close(objfil); objfil=0;
+ if (toterr != 0 && !keep_bad_output)
+ {
+ if(binfilename) unlink(binfilename);
+ if(objfilename) unlink(objfilename);
+ }
+
+ exit(toterr != 0 ? 1 : 0); /* should close output files and check */
+}
+
+/* initialise constant nonzero values */
+
+static void initp1(void)
+{
+#ifdef I80386
+ idefsize = defsize = 2; /* I think this is probably safer (RDB) */
+#endif
+#if 0
+ idefsize = defsize = sizeof (char *) > 2 ? 4 : 2;
+#endif
+ lctabtop = lctab + NLOC;
+ lstfil = STDOUT;
+ mapnum = 15; /* default map number for symbol table */
+ spt_top = (spt = hid_spt) + SPTSIZ;
+}
+
+/* initialise nonzero values which start same each pass */
+
+void initp1p2(void)
+{
+ register struct lc_s *lcp;
+
+ dirty_pass = 0;
+ ifflag = TRUE;
+ pedata = UNDBIT; /* program entry point not defined */
+ blockstak = hid_blockstak + MAXBLOCK;
+ ifstak = hid_ifstak + MAXIF;
+ macstak = hid_macstak + MAXMAC;
+ macptop = (macpar = hid_mcpar) + MACPSIZ;
+ lctabtop = (lcptr = lctab = hid_lctab) + NLOC;
+ for (lcp = lctab; lcp < lctabtop; ++lcp)
+ {
+ lcp->data = lcdata = RELBIT; /* lc relocatable until 1st ORG */
+ lcp->lc = lc = 0;
+ }
+}
+
+void line_zero(void)
+{
+ if( textseg >= 0 )
+ ptext();
+}
+
+static int my_creat(char *name, char *message)
+{
+ int fd;
+
+#ifdef O_BINARY
+ if ((fd = open(name, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, CREAT_PERMS)) < 0 || fd > 255)
+#else
+ if ((fd = creat(name, CREAT_PERMS)) < 0 || fd > 255)
+#endif
+ as_abort(message);
+ return fd;
+}
+
+static void process_args(int argc, char *argv[])
+{
+ char *arg;
+ bool_t isnextarg;
+ char *nextarg = 0;
+ int opened_file = 0;
+ int flag_state;
+
+#ifdef I80386
+ setcpu(0xF);
+#endif
+ textseg = -1;
+
+ if (argc <= 1)
+ usage();
+ do
+ {
+ arg = *++argv;
+ if (arg[0] == '-' && arg[1] != '\0')
+ {
+ flag_state = 1;
+ if (arg[2] == '-' && arg[3] == 0 )
+ flag_state = 0;
+ else
+ if (arg[2] != 0)
+ usage(); /* no multiple options */
+ isnextarg = FALSE;
+ if (argc > 2)
+ {
+ nextarg = argv[1];
+ if (nextarg[0] != 0 && nextarg[0] != '-')
+ isnextarg = TRUE;
+ }
+ switch (arg[1])
+ {
+ case 'v':
+ outfd = STDOUT;
+ writes("as86 version: ");
+#ifdef VERSION
+ writesn(VERSION);
+#else
+ writesn("Unknown!");
+#endif
+ exit(1);
+#ifdef I80386
+ case '0': case '1': case '2':
+ idefsize = defsize = 0x2;
+ setcpu(arg[1]-'0');
+ break;
+ case '3':
+ idefsize = defsize = 0x4;
+ setcpu(0xF);
+ break;
+ case 'a':
+ asld_compatible = flag_state;
+ break;
+#endif
+ case 'b':
+ if (!isnextarg || binfil != 0)
+ usage();
+ binfil = my_creat(binfilename=nextarg, "error creating binary file");
+ binaryg = TRUE;
+ --argc;
+ ++argv;
+ break;
+ case 'g':
+ globals_only_in_obj = flag_state;
+ break;
+#ifdef I80386
+ case 'j':
+ jumps_long = flag_state;
+ break;
+ case 'O':
+ if( flag_state ) last_pass = 2;
+ else last_pass = 1;
+ break;
+#endif
+ case 'l':
+ list.global = TRUE;
+ goto get_any_list_file;
+ case 'm':
+ maclist.global = TRUE;
+ get_any_list_file:
+ if (isnextarg)
+ {
+ if (lstfil != STDOUT)
+ usage();
+ lstfil = my_creat(nextarg, "error creating list file");
+ --argc;
+ ++argv;
+ }
+ break;
+ case 'n':
+ if (!isnextarg)
+ usage();
+ truefilename = nextarg;
+ --argc;
+ ++argv;
+ break;
+ case 'o':
+ if (!isnextarg || objfil != 0)
+ usage();
+ objectg = TRUE;
+ objfil = my_creat(objfilename=nextarg, "error creating object file");
+ --argc;
+ ++argv;
+ break;
+ case 's':
+ if (!isnextarg || symfil != 0)
+ usage();
+ symgen = TRUE;
+ symfil = my_creat(nextarg, "error creating symbol file");
+ --argc;
+ ++argv;
+ break;
+ case 't':
+ if (!isnextarg || binfil != 0)
+ usage();
+ textseg = atoi(nextarg); if(textseg>0) textseg+=BSSLOC;
+ --argc;
+ ++argv;
+ break;
+ case 'u':
+ if( flag_state ) inidata = IMPBIT | SEGM;
+ else inidata = 0;
+ break;
+ case 'w':
+ if( flag_state ) as_warn.semaphore = -1;
+ else as_warn.semaphore = 0;
+ break;
+ case 'k':
+ keep_bad_output = 1;
+ break;
+ default:
+ usage(); /* bad option */
+ }
+ }
+ else if (infil != 0)
+ usage(); /* no multiple sources */
+ else
+ {
+ if (strlen(arg) > FILNAMLEN)
+ as_abort("source file name too long");
+ infiln = infil0 = 1;
+ infil = open_input(strcpy(filnamptr, arg));
+ opened_file = 1;
+ }
+ }
+ while (--argc != 1);
+ if( !opened_file )
+ {
+ infiln = infil0 = 1;
+ infil = open_input(strcpy(filnamptr, "-"));
+ }
+#ifdef I80386
+ origcpuid = cpuid;
+#endif
+ inidata = (~binaryg & inidata) | (RELBIT | UNDBIT);
+} /* IMPBIT from inidata unless binaryg */
+
+static void summary(int fd)
+{
+ outfd = fd;
+ writenl();
+ summ_number(toterr);
+ writesn(" errors");
+ summ_number(totwarn);
+ writesn(" warnings");
+}
+
+static void summ_number(unsigned num)
+{
+ /* format number like line numbers */
+ char buf[16];
+ *build_number(num, LINUM_LEN, buf) = 0;
+ writes(buf);
+}
+
+static void usage(void)
+{
+ as_abort(
+#ifdef I80386
+"usage: as [-03agjuwO] [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] src");
+#else
+ "usage: as [-guw] [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] src");
+#endif
+}
--- /dev/null
+#!/bin/sh -
+#
+# This file is simply an example of what can be done using the new binary
+# and symbol table output functions. As shown it can be used to produce
+# a C file containing the encapsulated binary of the assembly, plus any
+# public symbols in the source are accessable to the C program.
+#
+# Use it in a makefile:
+#
+# .s.v:
+# as86_encap $*.s $*.v $*_ $(AS86FLAGS)
+#
+
+[ $# -lt 2 ] && {
+ echo "Usage: `basename $0` infile outfile prefix [as86 opts]" 1>&2
+ exit 1
+}
+
+trap "rm -f _$$.* ; exit 99" 1 2 3 15
+
+LIBDIR='%%LIBDIR%%' # Set by make install
+BINDIR='%%BINDIR%%' # Set by make install
+
+# If the one set by install fails then try a couple of others.
+[ -x "$LIBDIR/as86" ] || LIBDIR="`dirname $0`"
+[ -x "$LIBDIR/as86" ] || LIBDIR="$BINDIR"
+[ -x "$LIBDIR/as86" ] || LIBDIR="`dirname $0`/../lib"
+[ -x "$LIBDIR/as86" ] || LIBDIR=/usr/bin
+
+IFILE="$1"
+OFILE="$2"
+PREFIX="`basename $IFILE .s`_"
+
+shift ; shift
+if [ $# -ge 1 ]
+then case "$1" in
+ -* ) ;;
+ [A-Za-z_]* ) PREFIX="$1"
+ shift
+ ;;
+ esac
+fi
+RV=0
+
+$LIBDIR/as86 "$@" "$IFILE" -b _$$.bin -s _$$.sym || RV=$?
+
+echo '#ifndef __ASSEMBLY__' > _$$.0
+echo >> _$$.0
+echo '#else' > _$$.3
+echo >> _$$.3
+echo '#endif' > _$$.5
+
+[ "$RV" = 0 ] && {
+ (
+ sort _$$.sym
+ echo %%%%
+ od -v -t uC _$$.bin
+ ) | \
+ awk -v prefix=$PREFIX -v ofile=_$$ ' BEGIN{
+ sname = prefix "start";
+ sn_file= ofile ".1";
+ bn_file= ofile ".2";
+ as_file= ofile ".4";
+ }
+ /^%%%%$/ { flg++;
+ if( flg == 1 )
+ {
+ if( !started )
+ {
+ printf "#define %s 0\n", sname > sn_file;
+ printf "%s = 0\n", sname > as_file;
+ }
+
+ printf "static char %sdata[] = {\n", prefix >bn_file;
+ bincount=0;
+ }
+ next;
+ }
+ flg==0 {
+ if(NF == 0) next;
+ if( substr($2,1,4) == "0000" ) $2=substr($2,5);
+ if( $1 == "+" && $4 == "$start" )
+ {
+ printf "#define %s 0x%s\n", sname, $2 > sn_file;
+ printf "%s = $%s\n", sname, $2 > as_file;
+ started = 1;
+ }
+ else if( substr($3, 1, 1) == "E" && $4 != "start" && $4 != "size" && $4 != "data" )
+ {
+ printf "#define %s%s 0x%s\n", prefix, $4, $2 > sn_file;
+ printf "%s%s = $%s\n", prefix, $4, $2 > as_file;
+ }
+ next;
+ }
+ flg==1 {
+ if(NF == 0) next;
+ printf " " > bn_file;
+ for(i=2;i<=NF;i++) {
+ if( $i >= 32 && $i < 127 && $i != 39 && $i != 92 )
+ printf("\047%c\047,", $i) > bn_file;
+ else
+ printf("%3d,", $i) > bn_file;
+ bincount++;
+ }
+ printf "\n" > bn_file;
+ }
+ END {
+ printf "};\n\n" > bn_file;
+ printf "#define %ssize %d\n\n", prefix, bincount > sn_file;
+ printf "%ssize = $%04x\n\n", prefix, bincount > as_file;
+ }
+ '
+ RV=$?
+}
+
+[ "$RV" = 0 ] && {
+ if [ "X$OFILE" = "X-" ]
+ then cat _$$.[0-9]
+ else cat _$$.[0-9] > "$OFILE" || RV=$?
+ fi
+}
+
+rm -f _$$.*
+exit $RV
--- /dev/null
+#!/bin/sh -
+#
+# This file is simply an example of what can be done using the new binary
+# and symbol table output functions. It produces a byte array with the
+# symbols in the object as array references within it.
+#
+# The output is a Linux OMAGIC binary created by ld86 -N, this means the
+# object can be linked directly to C-functions created by the same GCC that
+# compiled ld86.
+#
+# Use it in a makefile:
+#
+# .s86.o:
+# as86_to_data $*.s86 $*.o $(AS86FLAGS)
+#
+
+[ $# -lt 2 ] && {
+ echo "Usage: `basename $0` infile outfile [as86 opts]" 1>&2
+ exit 1
+}
+
+trap "rm -f _$$.* ; exit 99" 1 2 3 15
+
+LIBDIR='%%LIBDIR%%' # Set by make install
+[ -d "$LIBDIR" ] || LIBDIR='%%BINDIR%%'
+[ -d "$LIBDIR" ] || LIBDIR=/usr/bin
+
+IFILE="$1"
+OFILE="$2"
+
+shift ; shift
+RV=0
+
+$LIBDIR/as86 "$@" "$IFILE" -b _$$.bin -s _$$.sym || RV=$?
+
+[ "$RV" = 0 ] && {
+ (
+ cat _$$.sym
+ echo %%%%
+ od -v -t uC _$$.bin
+ echo %%%%
+ ) | \
+ awk > _$$.v ' BEGIN{
+ startaddr="";
+ printf ".text\n.data\n";
+ }
+ /^%%%%$/ { flg++;
+ next;
+ }
+ flg==0 {
+ if(NF == 0) next;
+ if( substr($2,1,4) == "0000" ) $2=substr($2,5);
+ if( $1 == "+" && $4 == "$start" )
+ {
+ if( $2 != "0000" ) startaddr=" - $" $2;
+ }
+ else if( substr($3, 1, 1) == "E" && $4 != "start" && $4 != "size" && $4 != "data" )
+ {
+ printf "export _%s\n", $4
+ printf "_%s = * + $%s%s\n\n", $4, $2, startaddr;
+ }
+ next;
+ }
+ flg==1 {
+ if(NF <= 1) next;
+ printf " .byte ";
+ for(i=2;i<NF;i++) printf("%3d,", $i);
+ printf("%3d", $NF);
+ printf "\n";
+ }
+ '
+ RV=$?
+}
+
+[ "$RV" = 0 ] || { rm -f _$$.* ; exit $RV ; }
+
+# If you want to see the assembler.
+# cp _$$.v `basename $2 .o`.asm
+
+$LIBDIR/as86 -o _$$.o86 _$$.v || RV=$?
+
+[ "$RV" = 0 ] || { rm -f _$$.* ; exit $RV ; }
+
+$LIBDIR/ld86 -r -N _$$.o86 -o _$$.o || RV=$?
+
+[ "$RV" = 0 ] || { rm -f _$$.* ; exit $RV ; }
+
+if [ "X$OFILE" = "X-" ]
+then cat _$$.o
+else mv -f _$$.o "$OFILE" || RV=$?
+fi
+
+rm -f _$$.*
+exit $RV
--- /dev/null
+ 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:
--- /dev/null
+ 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]
--- /dev/null
+aaa
+aad
+aam
+aas
+adc bx,[esi*4]
+add bx,[esi*4]
+and bx,[esi*4]
+arpl [esi*4],bx
+bound bx,[esi*4]
+bsf bx,[esi*4]
+bsr bx,[esi*4]
+bswap ebx
+bt [esi*4],bx
+btc [esi*4],bx
+btr [esi*4],bx
+bts [esi*4],bx
+call [esi*4]
+cbw
+cwde
+clc
+cld
+cli
+clts
+cmc
+cmp bx,[esi*4]
+cmpsb
+cmpsw
+cmpsd
+cmpxchg [esi*4],bx
+cwd
+cdq
+daa
+das
+dec [esi*4]
+div [esi*4]
+enter 0x200,3
+hlt
+idiv [esi*4]
+imul [esi*4]
+in al,0x20
+inc [esi*4]
+insb
+insw
+insd
+int 0x20
+into
+invd
+invlpg [esi*4]
+iret
+iretd
+jnz many
+many:
+jmp [esi*4]
+lahf
+lar bx,[esi*4]
+lea bx,[esi*4]
+leave
+lgdt [esi*4]
+lidt [esi*4]
+lds bx,[esi*4]
+les bx,[esi*4]
+lfs bx,[esi*4]
+lgs bx,[esi*4]
+lss bx,[esi*4]
+lldt [esi*4]
+lmsw [esi*4]
+lock
+lodsb
+lodsw
+lodsd
+loop alot
+alot:
+lsl bx,[esi*4]
+ltr [esi*4]
+mov ax,[esi*4]
+mov bx,[esi*4]
+mov cr0,eax
+movsb
+movsw
+movsd
+movsx bx,byte [esi*4]
+movzx bx,byte [esi*4]
+mul [esi*4]
+neg [esi*4]
+nop
+not [esi*4]
+or bx,[esi*4]
+out 0x20,al
+outsb
+outsw
+outsd
+pop [esi*4]
+popa
+popad
+popf
+popfd
+push [esi*4]
+pusha
+pushad
+pushf
+pushfd
+rcl [esi*4],1
+rcr [esi*4],1
+rol [esi*4],1
+ror [esi*4],1
+rep
+ins
+rep
+lock
+outs
+rep
+movs
+rep
+cmps
+rep
+dseg
+stos
+rep
+scas
+repe
+seg ss
+ins
+repe
+outs
+repe
+lock
+seg ss
+movs
+repe
+cmps
+repe
+stos
+repe
+seg ss
+seg cs
+fseg
+scas
+repz
+lock
+lock
+ins
+repz
+outs
+repz
+movs
+repz
+cmps
+repz
+stos
+repz
+scas
+repne
+scas
+repne
+cmps
+repnz
+scas
+repnz
+cmps
+repnz
+lock
+cmps
+repnz
+seg ss
+cmps
+repnz
+cseg
+cmps
+repnz
+seg ss
+lock
+cmps
+repnz
+lock
+cseg
+cmps
+ret
+retf
+sahf
+sal [esi*4],1
+sar [esi*4],1
+shl [esi*4],1
+shr [esi*4],1
+sbb bx,[esi*4]
+scasb
+scasw
+scasd
+setnz byte [esi*4]
+sgdt [esi*4]
+sidt [esi*4]
+shld [esi*4],bx,1
+shrd [esi*4],bx,1
+sldt [esi*4]
+smsw [esi*4]
+stc
+std
+sti
+stosb
+stosw
+stosd
+str [esi*4]
+sub bx,[esi*4]
+test bx,[esi*4]
+verr [esi*4]
+verw [esi*4]
+wait
+wbinvd
+xadd [esi*4],bx
+xchg bx,[esi*4]
+xlat
+xor bx,[esi*4]
--- /dev/null
+ 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
--- /dev/null
+; [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
--- /dev/null
+_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
--- /dev/null
+call 1:2
+call far [1]
+use32
+call far [1]
+
+use16
+jmp 1:2
+jmp far [1]
+use32
+jmp far [1]
--- /dev/null
+ 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
--- /dev/null
+; 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]
--- /dev/null
+; 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
--- /dev/null
+ 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
--- /dev/null
+ 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]
--- /dev/null
+; 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
--- /dev/null
+ 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
--- /dev/null
+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
--- /dev/null
+ 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]
--- /dev/null
+ SEG CS
+ SEG DS
+ SEG ES
+ SEG FS
+ SEG GS
+ SEG SS
--- /dev/null
+; 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
--- /dev/null
+ 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
--- /dev/null
+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
--- /dev/null
+ 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]
--- /dev/null
+/* assemble.c - main loop for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "address.h"
+#include "globvar.h"
+#include "opcode.h"
+#include "scan.h"
+
+static bool_t nocolonlabel; /* set for labels not followed by ':' */
+static void (*routine) P((void));
+#ifdef I80386
+static opcode_t rep = 0; /* which rep/repne prefix was seen */
+#endif
+static pfv rout_table[] =
+{
+ pelse,
+ pelseif,
+ pelsifc,
+ pendif,
+ pif,
+ pifc,
+
+ /* start of non-conditionals */
+ palign,
+ pasciz,
+ pblkw,
+ pblock,
+ pbss,
+ pcomm,
+ pcomm1,
+ pdata,
+ pendb,
+ penter,
+ pentry,
+ pequ,
+ peven,
+ pexport,
+ pfail,
+ pfcb,
+ pfcc,
+ pfdb,
+#if SIZEOF_OFFSET_T > 2
+ pfqb,
+#endif
+ pget,
+ pglobl,
+ pident,
+ pimport,
+ plcomm,
+ plcomm1,
+ plist,
+ ploc,
+ pmaclist,
+ pmacro,
+ pmap,
+ porg,
+ pproceof,
+ prmb,
+ psect,
+ pset,
+ psetdp,
+ ptext,
+#ifdef I80386
+ puse16,
+ puse32,
+#endif
+ pwarn,
+ /* end of pseudo-ops */
+
+#ifdef I80386
+ mbcc,
+ mbswap,
+ mcall,
+ mcalli,
+ mdivmul,
+ menter,
+ mEwGw,
+ mExGx,
+ mf_inher,
+ mf_m,
+ mf_m2,
+ mf_m2_ax,
+ mf_m2_m4,
+ mf_m2_m4_m8,
+ mf_m4_m8_optst,
+ mf_m4_m8_st,
+ mf_m4_m8_stst,
+ mf_m4_m8_m10_st,
+ mf_m10,
+ mf_optst,
+ mf_st,
+ mf_stst,
+ mf_w_inher,
+ mf_w_m,
+ mf_w_m2,
+ mf_w_m2_ax,
+ mgroup1,
+ mgroup2,
+ mgroup6,
+ mgroup7,
+ mgroup8,
+ mGvEv,
+ mGvMa,
+ mGvMp,
+ mimul,
+ min,
+ mincdec,
+ minher,
+ minher16,
+ minher32,
+ minhera,
+ mint,
+ mjcc,
+ mjcxz,
+ mlea,
+ mmov,
+ mmovx,
+ mnegnot,
+ mout,
+ mpushpop,
+ mret,
+ mseg,
+ msetcc,
+ mshdouble,
+ mtest,
+ mxchg,
+#endif /* I80386 */
+
+#ifdef MC6809
+ mall, /* all address modes allowed, like LDA */
+ malter, /* all but immediate, like STA */
+ mimmed, /* immediate only (ANDCC, ORCC) */
+ mindex, /* indexed (LEA's) */
+ minher, /* inherent, like CLC or CLRA */
+ mlong, /* long branches */
+ mshort, /* short branches */
+ msstak, /* S-stack (PSHS, PULS) */
+ mswap, /* TFR, EXG */
+ mustak, /* U-stack (PSHU,PULU) */
+#endif /* MC6809 */
+};
+
+static void asline(void);
+
+/*
+ This uses registers as follows: A is for work and is not preserved by
+ the subroutines.B holds the last symbol code, X usually points to data
+ about the last symbol, U usually holds the value of last expression
+ or symbol, and Y points to the current char. The value in Y is needed
+ by READCH and GETSYM. EXPRES needs B and Y, and returns a value in U.
+ If the expression starts with an identifier, X must point to its string.
+ LOOKUP needs a string pointer in X and length in A. It returns a table
+ pointer in X (unless not assembling and not found), symbol type in A
+ and overflow in CC.
+*/
+
+void assemble(void)
+{
+ while (TRUE)
+ {
+ asline();
+ if (label != NUL_PTR) /* must be confirmed if still set */
+ { /* it is nulled by EQU, COMM and SET */
+#ifndef MC6809
+#define NEEDENDLABEL ILLAB
+ if (nocolonlabel)
+ error(NEEDENDLABEL);
+#endif
+ if(pass && label->value_reg_or_op.value != oldlabel)
+ {
+ dirty_pass = TRUE;
+ if( pass == last_pass )
+ error(UNSTABLE_LABEL);
+ }
+
+ label->type |= LABIT; /* confirm, perhaps redundant */
+ if (label->type & REDBIT)
+ {
+ /* REDBIT meant 'GLOBLBIT' while LABIT was not set. */
+ label->type |= EXPBIT;
+ label->type &= ~REDBIT;
+ }
+ if ((mcount | popflags) == 0)
+ /* unaccompanied label, display adr like EQU and SET */
+ showlabel();
+ label = NUL_PTR; /* reset for next line */
+ }
+ skipline();
+ listline();
+ genbin();
+ genobj();
+ binmbuf = lc += lcjump
+#ifdef I80386
+ + immcount
+#endif
+ ;
+ }
+}
+
+static void asline(void)
+{
+ register struct sym_s *symptr;
+
+ postb = popflags = pcrflag =
+#ifdef I80386
+ sprefix = oprefix = aprefix =
+#endif
+ immcount = lastexp.data = lcjump = 0;
+#ifdef I80386
+ sib = NO_SIB;
+#endif
+#if SIZEOF_OFFSET_T > 2
+ fqflag =
+#endif
+ fdflag = fcflag = FALSE;
+ cpuwarn();
+ readline();
+ getsym();
+ if (sym != IDENT) /* expect label, mnemonic or macro */
+ {
+ /* Warn if not a comment marker or a hash (for /lib/cpp) */
+ if( sym != EOLSYM && sym != IMMEDIATE )
+ list_force = TRUE;
+ return; /* anything else is a comment */
+ }
+ symptr = gsymptr;
+ if (!ifflag)
+ /* not assembling, just test for IF/ELSE/ELSEIF/ENDIF */
+ {
+ if (symptr == NUL_PTR || !(symptr->type & MNREGBIT) ||
+ symptr->data & REGBIT ||
+ symptr->value_reg_or_op.op.routine >= MIN_NONCOND)
+ return;
+ }
+ else if (!(symptr->type & (MACBIT | MNREGBIT)))
+ /* not macro, op, pseudo-op or register, expect label */
+ {
+ oldlabel = symptr->value_reg_or_op.value;
+
+ if ((nocolonlabel = (*lineptr - ':')) == 0) /* exported label? */
+ {
+ sym = COLON;
+ ++lineptr;
+ }
+ if (symptr->type & (LABIT | VARBIT))
+ {
+ if (symptr->type & REDBIT)
+ labelerror(RELAB);
+ label = symptr;
+
+ if (pass && !(symptr->type & VARBIT) /*&& last_pass>1*/)
+ {
+ label->data = (label->data & FORBIT) | lcdata;
+ label->value_reg_or_op.value = lc;
+ }
+ }
+ else if (checksegrel(symptr))
+ {
+ symptr->type &= ~COMMBIT; /* ignore COMM, PCOMM gives warning */
+#ifdef MC6809
+#if 0
+ if (sym == COLON)
+ symptr->type |= EXPBIT;
+#endif
+#endif
+ /* remember if forward referenced */
+ symptr->data = (symptr->data & FORBIT) | lcdata;
+ symptr->value_reg_or_op.value = lc;
+ /* unless changed by EQU,COMM or SET */
+ label = symptr;
+ }
+
+ getsym();
+ if (sym != IDENT)
+ {
+ if (sym == EQOP)
+ {
+ getsym();
+ pequ();
+ }
+ return; /* anything but ident is comment */
+ }
+ symptr = gsymptr;
+ }
+ if (symptr->type & MACBIT)
+ {
+ entermac(symptr);
+ return;
+ }
+ if (!(symptr->type & MNREGBIT))
+ {
+ error(OPEXP);
+ return;
+ }
+ if (symptr->data & REGBIT)
+ {
+ error(REGUID);
+ return;
+ }
+ mnsize = 0;
+ if ((page = (symptr->data & (PAGE1 | PAGE2))) != 0)
+ {
+#ifdef MNSIZE
+ if (page == (PAGE1 | PAGE2))
+ {
+ mnsize = 1;
+ page = 0;
+ }
+ else
+#endif
+ {
+#ifdef PAGE2_OPCODE
+ if (page == PAGE2)
+ page = PAGE2_OPCODE;
+ else
+#endif
+ page = PAGE1_OPCODE;
+ mcount = 1;
+ }
+ }
+ opcode = symptr->value_reg_or_op.op.opcode;
+#ifdef I80386
+ needcpu((page==0 && ((opcode&0xF0) == 0x60||(opcode&0xF6)==0xC0))?1:0);
+#endif
+ routine = rout_table[symptr->value_reg_or_op.op.routine];
+ getsym();
+ (*routine)();
+#ifdef I80386
+ /* We handle "rep[ne]" refix as separate instruction; check if its use is valid */
+ if (opcode == 0xF2 || opcode == 0xF3) { /* REP */
+ rep = opcode;
+ /* Not another prefix */
+ } else if (opcode != 0x2E && /* CSEG */
+ opcode != 0x3E && /* DSEG */
+ opcode != 0x26 && /* ESEG */
+ opcode != 0x64 && /* FSEG */
+ opcode != 0x65 && /* GSEG */
+ opcode != 0x36 && /* SSEG */
+ opcode != 0xF0) { /* LOCK */
+ if (rep == 0xF2 && (opcode&0xF6) != 0xA6) /* REPNE CMPS/SCAS */
+ error (REPNE_STRING);
+ if (rep == 0xF3 && !((opcode&0xFC) == 0x6C || /* REP INS/OUTS */
+ (opcode&0xFC) == 0xA4 || /* REP MOVS/CMPS */
+ (opcode&0xFC) == 0xAC || /* REP SCAS/LODS */
+ (opcode&0xFE) == 0xAA)) /* REP STOS */
+ error (REP_STRING);
+ rep = 0;
+ }
+#endif
+ if (sym != EOLSYM)
+ error(JUNK_AFTER_OPERANDS);
+#ifdef I80386
+ needcpu(page==PAGE1_OPCODE?2:0);
+
+ if (aprefix != 0)
+ ++mcount;
+ if (oprefix != 0)
+ ++mcount;
+ if (sprefix != 0)
+ ++mcount;
+#endif
+}
--- /dev/null
+/* byteord.h - byte order dependencies for C compiler, assembler, linker */
+
+/* These are for the targets of everything and for linker source too. */
+
+#ifdef I8086
+# define INT_BIG_ENDIAN 0
+# define LONG_BIG_ENDIAN 0 /* except longs are back to front for Xenix */
+#endif
+
+#ifdef I80386
+# define INT_BIG_ENDIAN 0
+# define LONG_BIG_ENDIAN 0
+#endif
+
+#ifdef MC6809
+# define INT_BIG_ENDIAN 1 /* byte order in words is high-low */
+# define LONG_BIG_ENDIAN 1 /* byte order in longs is high-low */
+#endif
--- /dev/null
+
+compile()
+{
+ # /lib/elksemu ./as86 -3 -k "$@"
+ ./as86 -3 -k "$@"
+}
+
+for i in `ls asm/*.asm`
+do
+ j=`basename $i .asm`
+ compile asm/$j.asm -b $j.bin -o $j.obj > /dev/null
+ cmp $j.obj obj1/$j.obj
+
+ # compile asm/$j.asm -b $j.bin > /dev/null
+ # cmp $j.bin bin/$j.bin
+
+ rm -f $j.bin $j.obj $j.asm
+done
+
--- /dev/null
+
+/* Speed and space hacks for BCC */
+#ifdef __AS386_16__
+#define LOW_BYTE 0 /* must be changed for big-endian */
+#else
+
+#define S_ALIGNMENT sizeof(long)
+#endif
+
+/* const.h - constants for assembler */
+
+/* major switches */
+
+#define MC6809 /* generate 6809 code */
+#ifndef MC6809
+#define I80386 /* generate 80386 code */
+#endif
+#define MNSIZE /* allow byte size in mnemonic, e.g. "movb" */
+#undef SOS_EDOS /* source OS is EDOS */
+
+/* defaults */
+
+#define DIRCHAR '/' /* character separating filename from dir */
+#define INBUFSIZE 8192
+#define SOS_EOLSTR "\012"
+
+/* defaults modified by switches */
+
+#ifdef SOS_EDOS
+# undef INBUFSIZE
+# define INBUFSIZE 512
+# undef SOS_EOLSTR
+# define SOS_EOLSTR "\015\012"
+# define STAKSIZ 256 /* table grows up to stack less this */
+#endif
+
+#ifdef __AS386_16__
+# undef INBUFSIZE
+# define INBUFSIZE 512
+# define STAKSIZ 512 /* table grows up to stack less this */
+#endif
+
+/* booleans */
+
+#define FALSE 0
+#define TRUE 1
+
+/* ASCII constants */
+
+#define ETB 23
+
+/* C tricks */
+
+#define EXTERN extern
+#define NUL_PTR ((void*)0)
+
+/* O/S constants */
+
+#define CREAT_PERMS 0666
+#define EOF (-1)
+#define STDIN 0
+#define STDOUT 1
+
+enum
+{
+/* Register codes (internal to assembler). */
+#ifdef I80386
+
+/* Index regs must be first. */
+ BPREG,
+ BXREG,
+ DIREG,
+ SIREG,
+#define MAX16BITINDREG SIREG
+
+ EAXREG,
+ EBPREG,
+ EBXREG,
+ ECXREG,
+ EDIREG,
+ EDXREG,
+ ESIREG,
+ ESPREG,
+#define MAXINDREG ESPREG
+
+ AXREG,
+ CXREG,
+ DXREG,
+ SPREG,
+
+ AHREG,
+ ALREG,
+ BHREG,
+ BLREG,
+ CHREG,
+ CLREG,
+ DHREG,
+ DLREG,
+
+ CSREG,
+ DSREG,
+ ESREG,
+ FSREG,
+ GSREG,
+ SSREG,
+
+ CR0REG,
+ CR2REG,
+ CR3REG,
+ DR0REG,
+ DR1REG,
+ DR2REG,
+ DR3REG,
+ DR6REG,
+ DR7REG,
+ TR3REG,
+ TR4REG,
+ TR5REG,
+ TR6REG,
+ TR7REG,
+
+ ST0REG,
+ ST1REG,
+ ST2REG,
+ ST3REG,
+ ST4REG,
+ ST5REG,
+ ST6REG,
+ ST7REG,
+#endif /* I80386 */
+
+#ifdef MC6809
+
+/* Index regs must be first, then PC. */
+ SREG,
+ UREG,
+ XREG,
+ YREG,
+#define MAXINDREG YREG
+
+ PCREG,
+ AREG,
+ BREG,
+ CCREG,
+ DPREG,
+ DREG,
+#endif /* MC6809 */
+
+ NOREG
+};
+
+#ifdef I80386
+enum
+{
+/* Type and size keywords. */
+ BYTEOP,
+ DWORDOP,
+ FWORDOP,
+ FAROP,
+ PTROP,
+ PWORDOP,
+ QWORDOP,
+ TBYTEOP,
+ WORDOP
+};
+#endif /* I80386 */
+
+/* special chars */
+
+#define EOL 0
+#define MACROCHAR '?'
+
+enum
+{
+/* Symbol codes. */
+
+/* The first 2 must be from chars in identifiers. */
+ IDENT,
+ INTCONST,
+
+/* The next few are best for other possibly-multi-char tokens. */
+ ADDOP, /* also ++ */
+ BINCONST,
+ CHARCONST,
+ GREATERTHAN, /* also >> and context-sensitive */
+ HEXCONST,
+ LESSTHAN, /* also << and context-sensitive */
+ SUBOP, /* also -- */
+ WHITESPACE,
+
+ ANDOP,
+ COMMA,
+ EOLSYM,
+ EQOP,
+ IMMEDIATE,
+ INDIRECT,
+ LBRACKET,
+ LPAREN,
+ MACROARG,
+ NOTOP,
+ OROP,
+ OTHERSYM,
+ POSTINCOP,
+ PREDECOP,
+ RBRACKET,
+ RPAREN,
+ SLASH, /* context-sensitive */
+ SLOP,
+ SROP,
+ STAR, /* context-sensitive */
+ STRINGCONST,
+ COLON
+};
+
+/* symbol table entry */
+
+ /* type entry contains following flags */
+#define ENTBIT (1<<0) /* entry point (= OBJ_N_MASK) */
+#define COMMBIT (1<<1) /* common */
+#define LABIT (1<<2) /* label (a PC location or defined by EQU) */
+#define MNREGBIT (1<<3) /* mnemonic for op or pseudo-op, or register */
+#define MACBIT (1<<4) /* macro */
+#define REDBIT (1<<5) /* redefined (if with LABIT or VARBIT), to do
+ * with SA_MASK (if with COMMBIT), otherwise
+ * means globl */
+#define VARBIT (1<<6) /* variable (i.e. something defined by SET) */
+#define EXPBIT (1<<7) /* exported (= OBJ_E_MASK) */
+
+ /* data entry contains following flags, valid */
+ /* for expressions as well as syms */
+#define PAGE1 (1<<0) /* page 1 machine op = MNREGBIT | PAGE1 */
+#define PAGE2 (1<<1) /* page 2 machine op = MNREGBIT | PAGE2 */
+#define REGBIT (1<<2) /* register = MNREGBIT | REGBIT */
+#define SIZEBIT (1<<3) /* sizing mnemonic = MNREGBIT | SIZEBIT */
+#define SEGM 0x0F /* 1st 4 bits reused for segment if !MNREGBIT */
+#define RELBIT (1<<4) /* relative (= OBJ_A_MASK) */
+#define FORBIT (1<<5) /* forward referenced */
+#define IMPBIT (1<<6) /* imported (= OBJ_I_MASK) */
+#define UNDBIT (1<<7) /* undefined */
+
+/* object code format (Introl) */
+
+#define OBJ_SEGSZ_TWO 0x02 /* size 2 code for segment size descriptor */
+
+#define OBJ_MAX_ABS_LEN 64 /* max length of chunk of absolute code */
+
+#define OBJ_ABS 0x40 /* absolute code command */
+#define OBJ_OFFSET_REL 0x80 /* offset relocation command */
+#define OBJ_SET_SEG 0x20 /* set segment command */
+#define OBJ_SKIP_1 0x11 /* skip with 1 byte count */
+#define OBJ_SKIP_2 0x12 /* skip with 2 byte count */
+#define OBJ_SKIP_4 0x13 /* skip with 4 byte count */
+#define OBJ_SYMBOL_REL 0xC0 /* symbol relocation command */
+
+#define OBJ_A_MASK 0x10 /* absolute bit(symbols) */
+#if OBJ_A_MASK - RELBIT /* must match internal format (~byte 1 -> 0) */
+oops - RELBIT misplaced
+#endif
+#define OBJ_E_MASK 0x80 /* exported bit (symbols) */
+#if OBJ_E_MASK - EXPBIT /* must match internal format (byte 0 -> 0) */
+oops - EXPBIT misplaced
+#endif
+#define OBJ_I_MASK 0x40 /* imported bit (symbols) */
+#if OBJ_I_MASK - IMPBIT /* must match internal format (byte 1 -> 0) */
+oops - IMPBIT misplaced
+#endif
+#define OBJ_N_MASK 0x01 /* entry bit (symbols) */
+#if OBJ_N_MASK - ENTBIT /* must match internal format (byte 0 -> 1) */
+oops - ENTBIT misplaced
+#endif
+#define OBJ_SA_MASK 0x20 /* size allocation bit (symbols) */
+#define OBJ_SZ_ONE 0x40 /* size one code for symbol value */
+#define OBJ_SZ_TWO 0x80 /* size two code for symbol value */
+#define OBJ_SZ_FOUR 0xC0 /* size four code for symbol value */
+
+#define OBJ_R_MASK 0x20 /* PC-rel bit (off & sym reloc commands) */
+#define OBJ_SEGM_MASK 0x0F /* segment mask (symbols, off reloc command) */
+
+#define OBJ_OF_MASK 0x03 /* offset size code for symbol reloc */
+#define OBJ_S_MASK 0x04 /* symbol number size code for symbol reloc */
+
+#define SYMLIS_NAMELEN 26
+#define SYMLIS_LEN (sizeof (struct sym_listing_s))
+
+#define FILNAMLEN 64 /* max length of a file name */
+#define LINLEN 256 /* max length of input line */
+#define LINUM_LEN 5 /* length of formatted line number */
+
+#define SPTSIZ 1024 /* number of symbol ptrs */
+ /* pseudo-op flags */
+#define POPHI 1 /* set to print hi byte of adr */
+#define POPLO 2 /* to print lo byte of ADR */
+#define POPLC 4 /* to print LC */
+#define POPLONG 8 /* to print high word of ADR */
+#define MAXBLOCK 8 /* max nesting level of BLOCK stack */
+#define MAXGET 8 /* max nesting level of GET stack */
+#define MAXIF 8 /* max nesting level of IF stack */
+#define MACPSIZ (128 / sizeof (struct schain_s))
+ /* size of macro param buffer */
+#define MAXMAC 8 /* max nesting level of macro stack */
+#define NLOC 16 /* number of location counters */
+#ifdef I80386
+#define NO_SIB 0340 /* illegal sib (3 with 4) to mean no sib */
+#endif
+
+/* special segments */
+
+#define BSSLOC 3
+#define DATALOC 3
+#define DPLOC 2
+#define STRLOC 1
+#define TEXTLOC 0
+
+#include "errors.h"
+
--- /dev/null
+
+#include "syshead.h"
+#include "const.h"
+#include "errors.h"
+
+/* Error codes. */
+
+/* Syntax errors. */
+char COMEXP[] = "comma expected";
+char DELEXP[] = "delimiter expected";
+char FACEXP[] = "factor expected";
+char IREGEXP[] = "index register expected";
+char LABEXP[] = "label expected";
+char LPEXP[] = "left parentheses expected";
+char OPEXP[] = "opcode expected";
+char RBEXP[] = "right bracket expected";
+char REGEXP[] = "register expected";
+char RPEXP[] = "right parentheses expected";
+char SPEXP[] = "space expected";
+
+/* Expression errors. */
+char ABSREQ[] = "absolute expression required";
+char NONIMPREQ[] = "non-imported expression required";
+char RELBAD[] = "relocation impossible";
+
+/* Label errors. */
+char ILLAB[] = "illegal label";
+char MACUID[] = "MACRO used as identifier";
+char MISLAB[] = "missing label";
+char MNUID[] = "opcode used as identifier";
+char REGUID[] = "register used as identifier";
+char RELAB[] = "redefined label";
+char UNBLAB[] = "unbound label";
+char UNLAB[] = "undefined label";
+char VARLAB[] = "variable used as label";
+
+/* Addressing errors. */
+char ABOUNDS[] = "address out of bounds";
+char DBOUNDS[] = "data out of bounds";
+char ILLMOD[] = "illegal address mode";
+char ILLREG[] = "illegal register";
+
+/* Control structure errors. */
+char ELSEBAD[] = "no matching IF";
+char ENDBBAD[] = "no matching BLOCK";
+char EOFBLOCK[] = "end of file in BLOCK";
+char EOFIF[] = "end of file in IF";
+char EOFLC[] = "location counter was undefined at end";
+char EOFMAC[] = "end of file in MACRO";
+char FAILERR[] = "user-generated error";
+
+/* Overflow errors. */
+char BLOCKOV[] = "BLOCK stack overflow";
+char BWRAP[] = "binary file wrap-around";
+char COUNTOV[] = "counter overflow";
+char COUNTUN[] = "counter underflow";
+char GETOV[] = "GET stack overflow";
+char IFOV[] = "IF stack overflow";
+
+char LINLONG[] = "line too long";
+char MACOV[] = "MACRO stack overflow";
+char OBJSYMOV[] = "object symbol table overflow";
+char OWRITE[] = "program overwrite";
+char PAROV[] = "parameter table overflow";
+char SYMOV[] = "symbol table overflow";
+char SYMOUTOV[] = "output symbol table overflow";
+
+/* I/O errors. */
+char OBJOUT[] = "error writing object file";
+
+/* Miscellaneous errors. */
+char AL_AX_EAX_EXP[] = "al ax or eax expected";
+char CTLINS[] = "control character in string";
+char FURTHER[] = "futher errors suppressed";
+char ILL_IMM_MODE[] = "illegal immediate mode";
+char ILL_IND_TO_IND[] = "illegal indirect to indirect";
+char ILL_IND[] = "illegal indirection";
+char ILL_IND_PTR[] = "illegal indirection from previous 'ptr'";
+char ILL_SCALE[] = "illegal scale";
+char ILL_SECTION[] = "illegal section";
+char ILL_SEG_REG[] = "illegal segment register";
+char ILL_SOURCE_EA[] = "illegal source effective address";
+char ILL_SIZE[] = "illegal size";
+char IMM_REQ[] = "immediate expression expected";
+char INDEX_REG_EXP[] = "index register expected";
+char IND_REQ[] = "indirect expression required";
+char MISMATCHED_SIZE[] = "mismatched size";
+char NOIMPORT[] = "no imports with binary file output";
+char REENTER[] = "multiple ENTER pseudo-ops";
+char REL_REQ[] = "relative expression required";
+char REPEATED_DISPL[] = "repeated displacement";
+char SEGREL[] = "segment or relocatability redefined";
+char SEG_REG_REQ[] = "segment register required";
+char SIZE_UNK[] = "size unknown";
+char UNKNOWN_ESCAPE_SEQUENCE[] = "unknown escape sequence";
+
+char FP_REG_REQ[] = "FP register required";
+char FP_REG_NOT_ALLOWED[] = "FP register not allowed";
+char ILL_FP_REG[] = "illegal FP register";
+char ILL_FP_REG_PAIR[] = "illegal FP register pair";
+char JUNK_AFTER_OPERANDS[] = "junk after operands";
+
+char ALREADY[] = "already defined";
+char UNSTABLE_LABEL[] = "label moved in last pass add -O?";
+
+char REPNE_STRING[] = "CMPS or SCAS expected";
+char REP_STRING[] = "string instruction expected";
+
+/* Warnings. */
+char CPUCLASH[] = "instruction illegal for current cpu";
+char SHORTB[] = "short branch would do";
--- /dev/null
+
+#ifndef _H_ERRORS
+#define _H_ERRORS
+/* Error codes. */
+
+/* Syntax errors. */
+EXTERN char COMEXP[]; /* "comma expected" */
+EXTERN char DELEXP[]; /* "delimiter expected" */
+EXTERN char FACEXP[]; /* "factor expected" */
+EXTERN char IREGEXP[]; /* "index register expected" */
+EXTERN char LABEXP[]; /* "label expected" */
+EXTERN char LPEXP[]; /* "left parentheses expected" */
+EXTERN char OPEXP[]; /* "opcode expected" */
+EXTERN char RBEXP[]; /* "right bracket expected" */
+EXTERN char REGEXP[]; /* "register expected" */
+EXTERN char RPEXP[]; /* "right parentheses expected" */
+EXTERN char SPEXP[]; /* "space expected" */
+
+/* Expression errors. */
+EXTERN char ABSREQ[]; /* "absolute expression required" */
+EXTERN char NONIMPREQ[]; /* "non-imported expression required" */
+EXTERN char RELBAD[]; /* "relocation impossible" */
+
+/* Label errors. */
+EXTERN char ILLAB[]; /* "illegal label" */
+EXTERN char MACUID[]; /* "MACRO used as identifier" */
+EXTERN char MISLAB[]; /* "missing label" */
+EXTERN char MNUID[]; /* "opcode used as identifier" */
+EXTERN char REGUID[]; /* "register used as identifier" */
+EXTERN char RELAB[]; /* "redefined label" */
+EXTERN char UNBLAB[]; /* "unbound label" */
+EXTERN char UNLAB[]; /* "undefined label" */
+EXTERN char VARLAB[]; /* "variable used as label" */
+
+/* Addressing errors. */
+EXTERN char ABOUNDS[]; /* "address out of bounds" */
+EXTERN char DBOUNDS[]; /* "data out of bounds" */
+EXTERN char ILLMOD[]; /* "illegal address mode" */
+EXTERN char ILLREG[]; /* "illegal register" */
+
+/* Control structure errors. */
+EXTERN char ELSEBAD[]; /* "no matching IF" */
+#define ELSEIFBAD ELSEBAD
+EXTERN char ENDBBAD[]; /* "no matching BLOCK" */
+#define ENDIFBAD ELSEBAD
+EXTERN char EOFBLOCK[]; /* "end of file in BLOCK" */
+EXTERN char EOFIF[]; /* "end of file in IF" */
+EXTERN char EOFLC[]; /* "location counter was undefined at end" */
+EXTERN char EOFMAC[]; /* "end of file in MACRO" */
+EXTERN char FAILERR[]; /* "user-generated error" */
+
+/* Overflow errors. */
+EXTERN char BLOCKOV[]; /* "BLOCK stack overflow" */
+EXTERN char BWRAP[]; /* "binary file wrap-around" */
+EXTERN char COUNTOV[]; /* "counter overflow" */
+EXTERN char COUNTUN[]; /* "counter underflow" */
+EXTERN char GETOV[]; /* "GET stack overflow" */
+EXTERN char IFOV[]; /* "IF stack overflow" */
+
+EXTERN char LINLONG[]; /* "line too long" */
+EXTERN char MACOV[]; /* "MACRO stack overflow" */
+EXTERN char OBJSYMOV[]; /* "object symbol table overflow" */
+EXTERN char OWRITE[]; /* "program overwrite" */
+EXTERN char PAROV[]; /* "parameter table overflow" */
+EXTERN char SYMOV[]; /* "symbol table overflow" */
+EXTERN char SYMOUTOV[]; /* "output symbol table overflow" */
+
+/* I/O errors. */
+EXTERN char OBJOUT[]; /* "error writing object file" */
+
+/* Miscellaneous errors. */
+EXTERN char AL_AX_EAX_EXP[]; /* "al ax or eax expected" */
+EXTERN char CTLINS[]; /* "control character in string" */
+EXTERN char FURTHER[]; /* "futher errors suppressed" */
+EXTERN char ILL_IMM_MODE[]; /* "illegal immediate mode" */
+EXTERN char ILL_IND_TO_IND[]; /* "illegal indirect to indirect" */
+EXTERN char ILL_IND[]; /* "illegal indirection" */
+EXTERN char ILL_IND_PTR[]; /* "illegal indirection from previous 'ptr'" */
+EXTERN char ILL_SCALE[]; /* "illegal scale" */
+EXTERN char ILL_SECTION[]; /* "illegal section" */
+EXTERN char ILL_SEG_REG[]; /* "illegal segment register" */
+EXTERN char ILL_SOURCE_EA[]; /* "illegal source effective address" */
+EXTERN char ILL_SIZE[]; /* "illegal size" */
+EXTERN char IMM_REQ[]; /* "immediate expression expected" */
+EXTERN char INDEX_REG_EXP[]; /* "index register expected" */
+EXTERN char IND_REQ[]; /* "indirect expression required" */
+EXTERN char MISMATCHED_SIZE[]; /* "mismatched size" */
+EXTERN char NOIMPORT[]; /* "no imports with binary file output" */
+EXTERN char REENTER[]; /* "multiple ENTER pseudo-ops" */
+EXTERN char REL_REQ[]; /* "relative expression required" */
+EXTERN char REPEATED_DISPL[]; /* "repeated displacement" */
+EXTERN char SEGREL[]; /* "segment or relocatability redefined" */
+EXTERN char SEG_REG_REQ[]; /* "segment register required" */
+EXTERN char SIZE_UNK[]; /* "size unknown" */
+EXTERN char UNKNOWN_ESCAPE_SEQUENCE[]; /* "unknown escape sequence" */
+
+EXTERN char FP_REG_REQ[]; /* "FP register required" */
+EXTERN char FP_REG_NOT_ALLOWED[]; /* "FP register not allowed" */
+EXTERN char ILL_FP_REG[]; /* "illegal FP register" */
+EXTERN char ILL_FP_REG_PAIR[]; /* "illegal FP register pair" */
+EXTERN char JUNK_AFTER_OPERANDS[]; /* "junk after operands" */
+
+EXTERN char ALREADY[]; /* "already defined" */
+EXTERN char UNSTABLE_LABEL[]; /* "label moved in last pass add -O?" */
+
+EXTERN char REPNE_STRING[]; /* "CMPS or SCAS expected" */
+EXTERN char REP_STRING[]; /* "string instruction expected" */
+
+/* Warnings. */
+EXTERN char CPUCLASH[]; /* "instruction illegal for current cpu" */
+EXTERN char SHORTB[]; /* "short branch would do" */
+
+#endif
--- /dev/null
+/* express.c - expression handler for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "address.h"
+#include "globvar.h"
+#include "scan.h"
+#include "source.h"
+
+static void experror P((char * err_str));
+static void expundefined P((void));
+static void simple2 P((void));
+static void simple P((void));
+static void term P((void));
+static void factor2 P((void));
+
+void absexpres(void)
+{
+ expres();
+ chkabs();
+}
+
+/* check lastexp.data is abs */
+
+void chkabs(void)
+{
+ if (lastexp.data & RELBIT)
+ {
+ if (pass == last_pass)
+ error(ABSREQ);
+ expundefined();
+ }
+}
+
+void experror(char *err_str)
+{
+ error(err_str);
+ expundefined();
+}
+
+void expundefined(void)
+{
+ if( last_pass == 1 )
+ lastexp.data = FORBIT | UNDBIT;
+ else
+ lastexp.data = UNDBIT;
+}
+
+void nonimpexpres(void)
+{
+ expres();
+ if (lastexp.data & IMPBIT)
+ experror(NONIMPREQ);
+}
+
+/* generate relocation error if pass 2, make lastexp.data forward&undefined */
+
+void showrelbad(void)
+{
+ if (pass == last_pass)
+ error(RELBAD);
+ expundefined();
+}
+
+void symabsexpres(void)
+{
+ getsym();
+ absexpres();
+}
+
+void symexpres(void)
+{
+ getsym();
+ expres();
+}
+
+/*
+ expres() parses expression = simple expression [op simple expression],
+ where op is =, < or >.
+ Parameters: sym, number in number, identifier from symname to lineptr - 1.
+ Returns value in lastexp.
+*/
+
+void expres(void)
+{
+ offset_t leftoffset;
+
+ simple();
+ leftoffset = lastexp.offset;
+ if (sym == EQOP)
+ {
+ simple2();
+ if (leftoffset == lastexp.offset)
+ lastexp.offset = -1;
+ else
+ lastexp.offset = 0;
+ }
+ else if (sym == LESSTHAN)
+ {
+ /* context-sensitive, LESSTHAN really means less than here */
+ simple2();
+ if (leftoffset < lastexp.offset)
+ lastexp.offset = -1;
+ else
+ lastexp.offset = 0;
+ }
+ else if (sym == GREATERTHAN)
+ {
+ /* context-sensitive, GREATERTHAN really means greater than here */
+ simple2();
+ if (leftoffset > lastexp.offset)
+ lastexp.offset = -1;
+ else
+ lastexp.offset = 0;
+ }
+}
+
+/* get symbol and 2nd simple expression, check both rel or both abs */
+
+void simple2(void)
+{
+ unsigned char leftdata;
+
+ leftdata = lastexp.data;
+ getsym();
+ simple();
+ if ((leftdata | lastexp.data) & IMPBIT ||
+ (leftdata ^ lastexp.data) & (RELBIT | SEGM))
+ showrelbad();
+ else
+ lastexp.data = (leftdata & lastexp.data) & ~(RELBIT | SEGM);
+}
+
+/*
+ simple() parses simple expression = [+-] term {op term},
+ where op is +, -, or \ (OR).
+*/
+
+void simple(void)
+{
+ offset_t leftoffset;
+ unsigned char leftdata;
+
+ if (sym == ADDOP || sym == SUBOP)
+ lastexp.data = lastexp.offset = 0;
+ else
+ term();
+ while (TRUE)
+ {
+ leftoffset = lastexp.offset;
+ leftdata = lastexp.data;
+ if (sym == ADDOP)
+ {
+ getsym();
+ term();
+ if (leftdata & lastexp.data & RELBIT)
+ showrelbad(); /* rel + rel no good */
+ else
+ lastexp.data |= leftdata;
+ lastexp.offset += leftoffset;
+ }
+ else if (sym == SUBOP)
+ {
+ getsym();
+ term();
+ /* check not abs - rel or rel - rel with mismatch */
+ if (lastexp.data & RELBIT &&
+ (!(leftdata & RELBIT) ||
+ (leftdata | lastexp.data) & IMPBIT ||
+ (leftdata ^ lastexp.data) & (RELBIT | SEGM)))
+ showrelbad();
+ else
+ lastexp.data = ((leftdata | lastexp.data) & ~(RELBIT | SEGM))
+ | ((leftdata ^ lastexp.data) & (RELBIT | SEGM));
+ lastexp.offset = leftoffset - lastexp.offset;
+ }
+ else if (sym == OROP)
+ {
+ getsym();
+ term();
+ lastexp.data |= leftdata;
+ chkabs(); /* both must be absolute */
+ lastexp.offset |= leftoffset;
+ }
+ else
+ return;
+ }
+}
+
+/* term() parses term = factor {op factor}, where op is *, /, &, <<, or >>. */
+
+void term(void)
+{
+ offset_t leftoffset;
+
+ factor();
+ while (TRUE)
+ {
+ leftoffset = lastexp.offset;
+ if (sym == STAR)
+ {
+ /* context-sensitive, STAR means multiplication here */
+ factor2();
+ lastexp.offset *= leftoffset;
+ }
+ else if (sym == SLASH)
+ {
+ /* context-sensitive, SLASH means division here */
+ factor2();
+ lastexp.offset = leftoffset / lastexp.offset;
+ }
+ else if (sym == ANDOP)
+ {
+ factor2();
+ lastexp.offset &= leftoffset;
+ }
+ else if (sym == SLOP)
+ {
+ factor2();
+ lastexp.offset = leftoffset << lastexp.offset;
+ }
+ else if (sym == SROP)
+ {
+ factor2();
+ lastexp.offset = leftoffset >> lastexp.offset;
+ }
+ else
+ return;
+ }
+}
+
+/* get symbol and 2nd or later factor, check both abs */
+
+void factor2(void)
+{
+ unsigned char leftdata;
+
+ leftdata = lastexp.data;
+ getsym();
+ factor();
+ lastexp.data |= leftdata;
+ chkabs();
+}
+
+/*
+ factor() parses factor = number | identifier | * | (expression) | ! factor,
+ ! is complementation. Returns value in lastexp.offset, possible flags
+ IMPBIT, FORBIT, RELBIT and UNDBIT in lastexp.data, and segment in SEGM
+ part of lastexp.data, and lastexp.sym at imported symbol if IMPBIT.
+ If the factor is an identifier, LOOKUP is used to get its value
+ (so the ident is installed in the symbol table if necessary, with
+ default flags inidata). If the identifier is not a label,
+ (could be imported, or later in the program), its FORBIT is set.
+ The expression FORBIT, IMPBIT, RELBIT, UNDBIT and SEGM are then
+ taken from the identifier.
+*/
+
+void factor(void)
+{
+ switch (sym)
+ {
+ case SLASH:
+ /* context-sensitive, SLASH means a hex number here */
+ context_hexconst();
+ case INTCONST:
+ lastexp.data = 0; /* absolute & not forward or undefined */
+ lastexp.offset = number;
+ getsym();
+ return;
+ case IDENT:
+ {
+ register struct sym_s *symptr;
+
+ symptr = gsymptr;
+ if (symptr->type & (MNREGBIT | MACBIT))
+ experror(symptr->type & MACBIT ? MACUID :
+ symptr->data & REGBIT ? REGUID : MNUID);
+ else
+ {
+ if (!(symptr->type & (LABIT | VARBIT)))
+ {
+ if( last_pass == 1 )
+ symptr->data |= FORBIT;
+ lastexp.sym = symptr;
+ }
+ if (pass != last_pass)
+ {
+ if( last_pass == 1 )
+ lastexp.data = symptr->data &
+ (FORBIT | RELBIT | UNDBIT | SEGM);
+ else
+ lastexp.data = symptr->data &
+ (RELBIT | UNDBIT | SEGM);
+ /* possible flags for pass 1 */
+ lastexp.offset = symptr->value_reg_or_op.value;
+ }
+ else
+ {
+ if ((lastexp.data = symptr->data) & IMPBIT)
+ lastexp.offset = 0; /* value != 0 for commons */
+ /* OK even if UNDBIT */
+ else
+ {
+ lastexp.offset = symptr->value_reg_or_op.value;
+ if (lastexp.data & UNDBIT)
+ experror(UNBLAB);
+ }
+ }
+ }
+ getsym();
+ return;
+ }
+#ifndef MC6809
+ case LBRACKET:
+ if (!asld_compatible)
+ break; /* error, LPAREN is the grouping symbol */
+ getsym();
+ expres();
+ if (sym != RBRACKET)
+ error(RBEXP);
+ else
+ getsym();
+ return;
+#endif
+ case LPAREN:
+#ifndef MC6809
+ if (asld_compatible)
+ break; /* error, LBRACKET is the grouping symbol */
+#endif
+ getsym();
+ expres();
+ if (sym != RPAREN)
+ error(RPEXP);
+ else
+ getsym();
+ return;
+ case NOTOP:
+ getsym();
+ factor();
+ chkabs();
+ lastexp.offset = ~lastexp.offset;
+ return;
+ case ADDOP:
+ getsym();
+ factor();
+ return;
+ case SUBOP:
+ getsym();
+ factor();
+ chkabs();
+ lastexp.offset = -lastexp.offset;
+ return;
+ case STAR:
+ /* context-sensitive, STAR means location counter here */
+ lastexp.offset = lc;
+ if ((lastexp.data = lcdata) & UNDBIT && pass == last_pass)
+ experror(UNBLAB);
+ getsym();
+ return;
+ }
+ experror(FACEXP);
+}
+
+/*
+ string compare for IFC/ELSEIFC
+ expects (<string1>,<string2>)
+ returns logical value in lastexp
+*/
+
+void scompare(void)
+{
+ /* prepare flags for OK, lastexp.offset for error */
+ lastexp.data = lastexp.offset = 0;
+ if (sym != LPAREN)
+ experror(LPEXP);
+ else
+ {
+ register char *string1;
+ register char *string2;
+
+ for (string2 = string1 = lineptr; *string2 != ','; ++string2)
+ if (*string2 == 0 || *string2 == ')')
+ {
+ symname = string2;
+ experror(COMEXP);
+ return;
+ }
+ string2++;
+ while (*string1++ == *string2++)
+ ;
+ if (string2[-1] == ')')
+ {
+ if (string1[-1] == ',')
+ lastexp.offset = TRUE; /* else leave FALSE */
+ lineptr = string2;
+ }
+ else /* FALSE, keep reading to verify syntax */
+ {
+ for (; *string2 != ')'; ++string2)
+ if (*string2 == 0 || *string2 == ',')
+ {
+ symname = string2;
+ experror(RPEXP);
+ }
+ lineptr = ++string2;
+ }
+ getsym();
+ }
+}
--- /dev/null
+/* file.h - global variables involving files for assembler */
+
+EXTERN char *filnamptr; /* file name pointer */
+EXTERN char *truefilename; /* in case actual source name is a tmpname */
+
+EXTERN fd_t infil; /* current input file (stacked, 0 = memory) */
+
+/* Output fds */
+EXTERN unsigned char outfd; /* output fd for writer fns */
+EXTERN fd_t binfil; /* binary output file (0 = memory) */
+EXTERN fd_t lstfil; /* list output file (0 = standard) */
+EXTERN fd_t objfil; /* object output file */
+EXTERN fd_t symfil; /* symbol table output file */
+
+/* readsrc internals */
+EXTERN unsigned infil0; /* Number of first input area */
+EXTERN unsigned infiln; /* Number of current input area */
--- /dev/null
+/* flag.h - global structured-flag variables for assembler */
+
+EXTERN struct flags_s list; /* listing on/off */
+EXTERN struct flags_s maclist; /* list macros on/off */
+EXTERN struct flags_s as_warn; /* warnings on/off */
--- /dev/null
+/* genbin.c - binary code generation routines for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "address.h"
+#include "file.h"
+#include "globvar.h"
+
+#ifdef USE_FIXED_HEAP
+static char *asmbeg; /* beginning of assembler code */
+ /* for overwrite check */
+ /* bss-init to zero = NULL and not changed */
+#endif
+
+/* Sneaky stuff, the start of a binary file can be _negative_ for the I80386
+ assembler. The -ve addresses are ones over 2GB (or "org -32") */
+#ifdef I80386
+static soffset_t binfbuf; /* binary code buffer for file (counter) */
+static soffset_t binmax; /* maximum value of binmbuf for pass 1 */
+static soffset_t binmin; /* minimum value of binmbuf for pass 1 */
+#define PT soffset_t
+#else
+static offset_t binfbuf; /* binary code buffer for file (counter) */
+static offset_t binmax; /* maximum value of binmbuf for pass 1 */
+static offset_t binmin; /* minimum value of binmbuf for pass 1 */
+#define PT offset_t
+#endif
+
+static void putbinoffset P((offset_t offset, count_t size));
+
+/* write header to binary file */
+
+void binheader(void)
+{
+#ifdef BINSYM
+ if ((outfd = binfil) != 0x0 && binmbuf_set && binmax >= binmin)
+ {
+ writec(0x0); /* binary header byte */
+#ifdef LONG_BINHEADER
+ writeoff(binmax - binmin); /* program length */
+ writeoff(binfbuf = binmin); /* program start */
+#else
+ writew((unsigned) (binmax - binmin)); /* program length */
+ writew((unsigned) (binfbuf = binmin)); /* program start */
+#endif
+ }
+#else
+ if ( ( outfd = symfil ) && binmbuf_set && binmax >= binmin)
+ {
+ int sft;
+ writec('+'); writec(' ');
+ for(sft=SIZEOF_OFFSET_T*8-4; sft >= 0; sft-=4)
+ writec(hexdigit[(binmin>>sft) & 0xF]);
+ writesn(" ----- $start");
+
+ writec('+'); writec(' ');
+ for(sft=SIZEOF_OFFSET_T*8-4; sft >= 0; sft-=4)
+ writec(hexdigit[(binmax>>sft) & 0xF]);
+ writesn(" ----- $end");
+
+ binfbuf = binmin; /* program start */
+ }
+#endif
+}
+
+/* write trailer to binary file */
+
+void bintrailer()
+{
+#ifdef BINSYM
+ if ((outfd = binfil) != 0x0 && (pedata & UNDBIT) != UNDBIT && binmbuf_set)
+ {
+ writec(0xFF); /* binary trailer byte */
+ writew(0x0); /* further trailer bytes */
+#ifdef LONG_BINHEADER
+ writeoff(pedata & UNDBIT ? binmin : progent); /* entry point */
+#else
+ writew(pedata & UNDBIT ? (unsigned) binmin : (unsigned) progent);
+#endif
+ }
+#endif
+}
+
+/* generate binary code for current line */
+
+void genbin(void)
+{
+ struct address_s *adrptr;
+ char *bufptr;
+ unsigned char remaining;
+
+ if (binaryg && mcount != 0x0)
+ {
+ if (popflags)
+ {
+ if (fcflag)
+ {
+ bufptr = databuf.fcbuf;
+ remaining = mcount;
+ do
+ putbin(*bufptr++);
+ while (--remaining != 0x0);
+ }
+ if (fdflag)
+ {
+ adrptr = databuf.fdbuf;
+ remaining = mcount;
+ do
+ {
+ putbinoffset(adrptr->offset, 0x2);
+ ++adrptr;
+ }
+ while ((remaining -= 0x2) != 0x0);
+ }
+#if SIZEOF_OFFSET_T > 0x2
+ if (fqflag)
+ {
+ adrptr = databuf.fqbuf;
+ remaining = mcount;
+ do
+ {
+ putbinoffset(adrptr->offset, 0x4);
+ ++adrptr;
+ }
+ while ((remaining -= 0x4) != 0x0);
+ }
+#endif
+ }
+ else
+ {
+ remaining = mcount - 0x1; /* count opcode immediately */
+#ifdef I80386
+ if (aprefix != 0x0)
+ {
+ putbin(aprefix);
+ --remaining;
+ }
+ if (oprefix != 0x0)
+ {
+ putbin(oprefix);
+ --remaining;
+ }
+ if (sprefix != 0x0)
+ {
+ putbin(sprefix);
+ --remaining;
+ }
+#endif
+ if (page != 0x0)
+ {
+ putbin(page);
+ --remaining;
+ }
+ putbin(opcode);
+ if (remaining != 0x0)
+ {
+ if (postb != 0x0)
+ {
+ putbin(postb);
+ --remaining;
+ }
+#ifdef I80386
+ if (sib != NO_SIB)
+ {
+ putbin(sib);
+ --remaining;
+ }
+#endif
+ if (remaining != 0x0)
+ putbinoffset(lastexp.offset, remaining);
+ }
+#ifdef I80386
+ if (immcount != 0x0)
+ putbinoffset(immadr.offset, immcount);
+#endif
+ }
+ /* else no code for this instruction, or already generated */
+ }
+}
+
+/* initialise private variables */
+
+void initbin(void)
+{
+#ifdef I80386
+ binmin = ((offset_t)-1 >>1); /* greater than anything */
+#else
+ binmin = -1; /* greater than anything */
+#endif
+}
+
+/* write char to binary file or directly to memory */
+
+void putbin(opcode_pt ch)
+{
+ if (binfil != 0x0)
+ {
+ if (!binaryc) /* pass 1, just record limits */
+ {
+ if ((PT)binmbuf < binmin)
+ binmin = binmbuf;
+ binmbuf++;
+ if ((PT)binmbuf > binmax)
+ binmax = binmbuf;
+ }
+ else
+ {
+#if 0
+ if (binfbuf > (PT)binmbuf)
+ {
+ error(BWRAP); /* file buffer ahead of memory buffer */
+ }
+ else
+#endif
+ {
+#ifdef MSDOS
+static PT zapptr = 0;
+#endif
+ outfd = binfil;
+#ifdef MSDOS
+ while (binfbuf < (PT)binmbuf && binfbuf >= zapptr+binmin)
+ {
+ writec(0);
+ ++binfbuf;
+ ++zapptr;
+ }
+#endif
+ if( binfbuf != (PT)binmbuf)
+ if( lseek(binfil, (long)((PT)binmbuf-binfbuf), 1) < 0 )
+ error(BWRAP);
+ binfbuf = binmbuf;
+ writec(ch);
+ binmbuf = ++binfbuf;
+ }
+ }
+ }
+#ifdef USE_FIXED_HEAP
+ else if (binaryc && !(lcdata & UNDBIT))
+ /* memory output, and enabled */
+ {
+ register char *bufptr;
+
+ if ((bufptr = (char *) binmbuf) >= asmbeg && bufptr < temp_buf())
+ error(OWRITE);
+ else
+ *bufptr = ch;
+ ++binmbuf;
+ }
+#endif
+}
+
+/* write sized offset to binary file or directly to memory */
+
+static void putbinoffset(offset_t offset, count_t size)
+{
+ char buf[sizeof offset];
+
+#if SIZEOF_OFFSET_T > 0x2
+ u4cn(buf, offset, size);
+#else
+ u2cn(buf, offset, size);
+#endif
+ putbin(buf[0]);
+ if (size > 0x1)
+ putbin(buf[1]);
+ if (size > 0x2)
+ {
+ putbin(buf[2]);
+ putbin(buf[3]);
+ }
+}
--- /dev/null
+/* genlist.c - generate listing and error reports for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "address.h"
+#include "flag.h"
+#include "file.h"
+#include "globvar.h"
+#include "macro.h"
+#include "scan.h"
+#include "source.h"
+
+#define CODE_LIST_LENGTH (sizeof (struct code_listing_s) - 1)
+ /* length of formatted code listing */
+#define MAXERR 6 /* maximum errors listed per line */
+
+struct error_s /* to record error info */
+{
+ char * err_str;
+ unsigned char position;
+};
+
+/* code listing format */
+
+struct code_listing_s
+{
+ union linum_macro_u
+ {
+ char linum[LINUM_LEN];
+ struct
+ {
+ char pad[1];
+ char mark[1];
+ char level[1];
+ }
+ macro;
+ }
+ linum_or_macro;
+ char padlinum[1];
+ char lc[4];
+ char padlc[1];
+#ifdef I80386
+ char lprefix[2];
+ char aprefix[2];
+ char oprefix[2];
+ char sprefix[2];
+#endif
+ char page[2];
+ char opcode[2];
+ char postb[2];
+#ifdef I80386
+ char sib[2];
+#endif
+ char padopcode[1];
+#if SIZEOF_OFFSET_T > 2
+ char displ4[2];
+ char displ3[2];
+#endif
+ char displ2[2];
+ char displ1[2];
+ char reldispl[1];
+ char paddispl[1];
+#ifdef I80386
+ char imm4[2];
+ char imm3[2];
+ char imm2[2];
+ char imm1[2];
+ char relimm[1];
+ char padimm[1];
+#endif
+ char nullterm;
+};
+
+static struct error_s errbuf[MAXERR]; /* error buffer */
+static unsigned char errcount; /* # errors in line */
+static bool_t erroverflow; /* set if too many errors on line */
+
+static char *build_1hex_number(opcode_pt num, char *where);
+static void list1(fd_t fd);
+static void listcode(void);
+static void listerrors(void);
+static void paderrorline(unsigned nspaces);
+
+/* format 1 byte number as 2 hex digits, return ptr to end */
+
+static char *build_1hex_number(opcode_pt num, register char *where)
+{
+ where[0] = hexdigit[((unsigned) num % 256) / 16];
+ where[1] = hexdigit[(unsigned) num % 16];
+ return where + 2;
+}
+
+/* format 2 byte number as 4 hex digits, return ptr to end */
+
+char *build_2hex_number(unsigned num, char *where)
+{
+ return build_1hex_number((opcode_pt) num,
+ build_1hex_number((opcode_pt) (num / 256), where));
+}
+
+/* format 2 byte number as decimal with given width (pad with leading '0's) */
+/* return ptr to end */
+
+char *build_number(unsigned num, unsigned width, register char *where)
+{
+ static unsigned powers_of_10[] = {1, 10, 100, 1000, 10000,};
+ unsigned char digit;
+ unsigned char power;
+ register unsigned power_of_10;
+
+ power = 5; /* actually 1 more than power */
+ do
+ {
+ for (digit = '0', power_of_10 = (powers_of_10 - 1)[power];
+ num >= power_of_10; num -= power_of_10)
+ ++digit;
+ if (power <= width)
+ *where++ = digit;
+ }
+ while (--power != 0);
+ return where;
+}
+
+/* record number and position of error (or error buffer overflow) */
+
+void warning(char * err_str)
+{
+ if (!as_warn.current) return;
+ ++totwarn;
+ --toterr;
+ error(err_str);
+}
+
+void error(char *err_str)
+{
+ register struct error_s *errptr;
+ register struct error_s *errptrlow;
+ unsigned char position;
+
+ if (errcount >= MAXERR)
+ erroverflow = TRUE;
+ else
+ {
+ position = symname - linebuf;
+ for (errptr = errbuf + errcount;
+ errptr > errbuf && errptr->position > position;
+ errptr = errptrlow)
+ {
+ errptrlow = errptr - 1;
+ errptr->err_str = errptrlow->err_str;
+ errptr->position = errptrlow->position;
+ }
+ errptr->err_str = err_str;
+ errptr->position = position;
+ ++errcount;
+ ++toterr;
+ }
+}
+
+/* list 1 line to list file if any errors or flags permit */
+/* list line to console as well if any errors and list file is not console */
+
+void listline(void)
+{
+ if (!listpre && lineptr != 0)
+ {
+ if (errcount || (list.current && (!macflag || mcount != 0)) ||
+ (macflag && maclist.current) || list_force )
+ list1(lstfil);
+ if (errcount)
+ {
+ if (lstfil != STDOUT)
+ list1(STDOUT);
+ errcount = 0;
+ erroverflow = FALSE;
+ }
+ }
+}
+
+/* list 1 line unconditionally */
+
+static void list1(fd_t fd)
+{
+ outfd = fd;
+ listcode();
+ write(outfd, linebuf, (unsigned) (lineptr - linebuf));
+ writenl();
+ if (errcount != 0)
+ listerrors();
+ listpre = TRUE;
+ list_force=FALSE;
+}
+
+/* list object code for 1 line */
+
+static void listcode(void)
+{
+ unsigned char count;
+ struct code_listing_s *listptr;
+ unsigned numlength;
+ char *numptr;
+
+ listptr = (struct code_listing_s *) temp_buf();
+ memset((char *) listptr, ' ', sizeof *listptr);
+ listptr->nullterm = 0;
+ if (macflag)
+ {
+ listptr->linum_or_macro.macro.mark[0] = '+';
+ listptr->linum_or_macro.macro.level[0] = maclevel + ('a' - 1);
+ }
+ else
+ {
+ numlength = LINUM_LEN;
+ numptr = listptr->linum_or_macro.linum;
+ if (infiln != infil0)
+ {
+ *numptr++ = infiln - infil0 + ('a' - 1);
+ numlength = LINUM_LEN - 1;
+ }
+ build_number(linum, numlength, numptr);
+ }
+ if ((count = mcount) != 0 || popflags & POPLC)
+ build_2hex_number((u16_T) lc, listptr->lc);
+ if (popflags & POPLO)
+ {
+#if SIZEOF_OFFSET_T > 2
+ if (popflags & POPLONG)
+ build_2hex_number((u16_T) (lastexp.offset / (offset_t) 0x10000L),
+ listptr->displ4);
+#endif
+ if (popflags & POPHI)
+ build_2hex_number((u16_T) lastexp.offset, listptr->displ2);
+ else
+ build_1hex_number((opcode_pt) /* XXX */(u16_T) lastexp.offset, listptr->displ1);
+ if (lastexp.data & RELBIT)
+ listptr->reldispl[0] = '>';
+ }
+ else if (count != 0)
+ {
+#ifdef I80386
+ if (aprefix != 0)
+ {
+ --count;
+ build_1hex_number(aprefix, listptr->aprefix);
+ }
+ if (oprefix != 0)
+ {
+ --count;
+ build_1hex_number(oprefix, listptr->oprefix);
+ }
+ if (sprefix != 0)
+ {
+ --count;
+ build_1hex_number(sprefix, listptr->sprefix);
+ }
+#endif
+ if (page != 0)
+ {
+ build_1hex_number(page, listptr->page);
+ --count;
+ }
+ build_1hex_number(opcode, listptr->opcode);
+ --count;
+ if (postb != 0)
+ {
+ --count;
+ build_1hex_number(postb,
+#ifdef MC6809
+ count == 0 ? listptr->displ1 :
+#endif
+ listptr->postb);
+ }
+#ifdef I80386
+ if (sib != NO_SIB)
+ {
+ --count;
+ build_1hex_number(sib, listptr->sib);
+ }
+#endif
+ if (count > 0)
+ {
+ build_1hex_number((opcode_pt) lastexp.offset, listptr->displ1);
+ if (lastexp.data & RELBIT)
+ listptr->reldispl[0] = '>';
+ }
+ if (count > 1)
+ build_1hex_number((opcode_pt) (lastexp.offset >> 0x8),
+ listptr->displ2);
+#if SIZEOF_OFFSET_T > 2
+ if (count > 2)
+ {
+ build_1hex_number((opcode_pt) (lastexp.offset >> 0x10),
+ listptr->displ3);
+ build_1hex_number((opcode_pt) (lastexp.offset >> 0x18),
+ listptr->displ4);
+ }
+#endif
+#ifdef I80386
+ if (immcount > 0)
+ {
+ build_1hex_number((opcode_pt) immadr.offset, listptr->imm1);
+ if (immadr.data & RELBIT)
+ listptr->relimm[0] = '>';
+ }
+ if (immcount > 1)
+ build_1hex_number((opcode_pt) (immadr.offset >> 0x8),
+ listptr->imm2);
+ if (immcount > 2)
+ {
+ build_1hex_number((opcode_pt) (immadr.offset >> 0x10),
+ listptr->imm3);
+ build_1hex_number((opcode_pt) (immadr.offset >> 0x18),
+ listptr->imm4);
+ }
+#endif
+ }
+ writes((char *) listptr);
+}
+
+/* list errors, assuming some */
+
+static void listerrors(void)
+{
+ unsigned char column;
+ unsigned char errcol; /* column # in error line */
+ unsigned char errcolw; /* working column in error line */
+ char *errmsg;
+ struct error_s *errptr;
+ char *linep;
+ unsigned char remaining;
+
+#ifdef I80386
+ paderrorline(1);
+#else
+ paderrorline(CODE_LIST_LENGTH - LINUM_LEN);
+#endif
+ remaining = errcount;
+ column = 0; /* column to match with error column */
+ errcolw = errcol = CODE_LIST_LENGTH; /* working & col number on err line */
+ errptr = errbuf;
+ linep = linebuf;
+ do
+ {
+#ifdef I80386
+ if(errcol != CODE_LIST_LENGTH)
+ {
+ writenl(); paderrorline(1);
+ }
+ writes(errmsg = errptr->err_str);
+ errcol = strlen(errmsg)+LINUM_LEN+1;
+ column = 0; linep = linebuf;
+ errcolw = CODE_LIST_LENGTH;
+ while (errcolw > errcol)
+ {
+ writec('.');
+ ++errcol;
+ }
+#endif
+ while (errptr && errptr->position < 132 && column < errptr->position)
+ {
+ ++column;
+ if (*linep++ == '\t') /* next tab (standard tabs only) */
+ errcolw = (errcolw + 8) & 0xf8;
+ else
+ ++errcolw;
+ while (errcolw > errcol)
+ {
+#ifdef I80386
+ writec('.');
+#else
+ writec(' ');
+#endif
+ ++errcol;
+ }
+ }
+#ifdef I80386
+ writec('^'); ++errcol;
+#else
+ if (errcolw < errcol) /* position under error on new line */
+ {
+ writenl();
+ paderrorline((unsigned) errcolw - LINUM_LEN);
+ }
+ writec('^');
+ writes(errmsg = errptr->err_str);
+ errcol += strlen(errmsg);
+#endif
+ ++errptr;
+ }
+ while (--remaining != 0);
+ writenl();
+ if (erroverflow)
+ {
+#ifdef I80386
+ paderrorline(1);
+#else
+ paderrorline(CODE_LIST_LENGTH - LINUM_LEN);
+#endif
+ writesn(FURTHER);
+ }
+}
+
+/* pad out error line to begin under 1st char of source listing */
+
+static void paderrorline(unsigned nspaces)
+{
+ int nstars = LINUM_LEN;
+
+ while (nstars-- != 0)
+ writec('*'); /* stars under line number */
+ while (nspaces-- != 0)
+ writec(' '); /* spaces out to error position */
+}
+
+/* write 1 character */
+
+void writec(char ch)
+{
+ write(outfd, &ch, 1);
+}
+
+/* write newline */
+
+void writenl(void)
+{
+ writes(SOS_EOLSTR);
+}
+
+/* write 1 offset_t, order to suit target */
+
+void writeoff(offset)
+offset_t offset;
+{
+ char buf[sizeof offset];
+
+#if SIZEOF_OFFSET_T > 2
+ u4c4(buf, offset);
+#else
+ u2c2(buf, offset);
+#endif
+ write(outfd, buf, sizeof buf);
+}
+
+/* write string */
+
+void writes(const char *s)
+{
+ write(outfd, s, strlen(s));
+}
+
+/* write string followed by newline */
+
+void writesn(const char *s)
+{
+ writes(s);
+ writenl();
+}
+
+/* write 1 word, order to suit target */
+
+void writew(unsigned word)
+{
+ char buf[2];
+
+ u2c2(buf, (u16_T) word);
+ write(outfd, buf, sizeof buf);
+}
--- /dev/null
+/* genobj.c - object code generation routines for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "address.h"
+#include "file.h"
+#include "globvar.h"
+
+#define OBJBUFSIZE 512 /* size of object code output buffer */
+#define isge2byteoffset(offset) ((offset) >= 0x100)
+#define isge4byteoffset(offset) ((offset) >= 0x10000L)
+
+static char hid_absbuf[OBJ_MAX_ABS_LEN]; /* absolute object code buf */
+static char *absbuf; /* start */
+static char *absbufend; /* last location + 1 */
+static char *absbufptr; /* current location */
+static struct sym_s **arrext; /* array of external symbol ptrs */
+static char hid_objbuf[OBJBUFSIZE]; /* object code buffer */
+static unsigned numext; /* number of external symbols */
+static char *objbuf; /* start */
+static char *objbufend; /* last location + 1 */
+static char *objbufptr; /* current location */
+static unsigned char relsize; /* current relocation size, 0 init */
+ /* local to genobjadr, but here */
+ /* because of static re-init bug */
+static offset_t rmbcount; /* accumulator for repeated RMB's */
+
+static void flushabs(void);
+static void flushrmb(void);
+static void genobjadr(struct address_s *adrptr, smallcount_t size);
+static void putobj1(opcode_pt ch);
+static void putobj4(u32_T offset);
+static void putobjoffset(offset_t offset, count_t size);
+static void putobjword(unsigned word);
+static void writeobj(char *buf, unsigned count);
+
+/* accumulate RMB requests into 1 (so + and - requests cancel) */
+
+void accumulate_rmb(offset_t offset)
+{
+ if (objectc)
+ {
+ flushabs();
+ rmbcount += offset;
+ }
+}
+
+/* flush absolute object code buffer to object code buffer if necessary */
+
+static void flushabs(void)
+{
+ if (absbufptr > absbuf)
+ {
+ putobj1((absbufptr - absbuf) | OBJ_ABS);
+ {
+ register char *bufptr;
+
+ bufptr = absbuf;
+ do
+ putobj1(*bufptr);
+ while (++bufptr < absbufptr);
+ absbufptr = absbuf;
+ }
+ }
+}
+
+/* flush object code buffer if necessary */
+
+void flushobj(void)
+{
+ int ntowrite;
+
+ if ((ntowrite = objbufptr - objbuf) > 0)
+ {
+ if (write(objfil, objbuf, (unsigned) ntowrite) != ntowrite)
+ {
+ error(OBJOUT);
+ listline();
+ finishup();
+ }
+ objbufptr = objbuf;
+ }
+}
+
+/* flush RMB count if necessary */
+
+static void flushrmb(void)
+{
+ count_t size;
+
+ if (rmbcount != 0)
+ {
+#if SIZEOF_OFFSET_T > 2
+ if (isge4byteoffset(rmbcount))
+ {
+ putobj1(OBJ_SKIP_4);
+ size = 4;
+ }
+ else
+#endif
+ if (isge2byteoffset(rmbcount))
+ {
+ putobj1(OBJ_SKIP_2);
+ size = 2;
+ }
+ else
+ {
+ putobj1(OBJ_SKIP_1);
+ size = 1;
+ }
+ putobjoffset(rmbcount, size);
+ rmbcount = 0;
+ }
+}
+
+/* generate object code for current line */
+
+/*
+ any address parameter is (regrettably) in lastexp
+ any immediate parameter is (corectly) in immadr
+*/
+
+void genobj(void)
+{
+ struct address_s *adrptr;
+ char *bufptr;
+ unsigned char remaining;
+
+ if (objectc && mcount != 0)
+ {
+ if (popflags)
+ {
+ if (fcflag)
+ {
+ bufptr = databuf.fcbuf;
+ remaining = mcount;
+ do
+ putabs(*bufptr++);
+ while (--remaining != 0);
+ }
+ if (fdflag)
+ {
+ adrptr = databuf.fdbuf;
+ remaining = mcount;
+ do
+ genobjadr(adrptr++, 2);
+ while ((remaining -= 2) != 0);
+ }
+#if SIZEOF_OFFSET_T > 2
+ if (fqflag)
+ {
+ adrptr = databuf.fqbuf;
+ remaining = mcount;
+ do
+ genobjadr(adrptr++, 4);
+ while ((remaining -= 4) != 0);
+ }
+#endif
+ }
+ else
+ {
+ remaining = mcount - 1; /* count opcode immediately */
+#ifdef I80386
+ if (aprefix != 0)
+ {
+ putabs(aprefix);
+ --remaining;
+ }
+ if (oprefix != 0)
+ {
+ putabs(oprefix);
+ --remaining;
+ }
+ if (sprefix != 0)
+ {
+ putabs(sprefix);
+ --remaining;
+ }
+#endif
+ if (page != 0)
+ {
+ putabs(page);
+ --remaining;
+ }
+ putabs(opcode);
+ if (remaining != 0)
+ {
+ if (postb != 0)
+ {
+ putabs(postb);
+ --remaining;
+ }
+#ifdef I80386
+ if (sib != NO_SIB)
+ {
+ putabs(sib);
+ --remaining;
+ }
+#endif
+ if (remaining != 0)
+ genobjadr(&lastexp, remaining);
+ }
+ }
+#ifdef I80386
+ if (immcount != 0)
+ genobjadr(&immadr, immcount);
+#endif
+ }
+}
+
+/* generate object code for current address */
+
+static void genobjadr(struct address_s *adrptr, smallcount_t size)
+{
+ unsigned char byte;
+ unsigned symnum;
+
+ if (!(adrptr->data & RELBIT))
+ {
+ /* absolute address */
+
+ char buf[sizeof(offset_t)];
+
+#if SIZEOF_OFFSET_T > 2
+ u4cn(buf, adrptr->offset, size);
+#else
+ u2cn(buf, adrptr->offset, size);
+#endif
+ putabs(buf[0]);
+ if (size > 1)
+ putabs(buf[1]);
+ if (size > 2)
+ {
+ putabs(buf[2]);
+ putabs(buf[3]);
+ }
+ }
+ else
+ {
+ /* relocatable address */
+ if (size != relsize)
+ /* set reloc size index |00|0000xx| */
+ putobj((relsize = size) == 4 ? 0x03 : relsize);
+ if (!(adrptr->data & IMPBIT))
+ {
+ /* offset relocation (known offset) */
+ putobj((adrptr->data & SEGM) | OBJ_OFFSET_REL | pcrflag);
+ putobjoffset(adrptr->offset, size);
+ }
+ else
+ {
+ /* symbol relocation (imported symbol + offset) */
+ {
+ register struct sym_s **copyptr;
+
+ for (copyptr = arrext, symnum = 0;
+ symnum < numext && *copyptr++ != adrptr->sym; ++symnum)
+ ;
+ }
+ byte = OBJ_SYMBOL_REL;
+ if (isge2byteoffset(symnum))
+ byte = OBJ_SYMBOL_REL | OBJ_S_MASK;
+#if SIZEOF_OFFSET_T > 2
+ if (isge4byteoffset(adrptr->offset))
+ {
+ byte |= 0x03; /* 4 byte offset */
+ size = 4;
+ }
+ else
+#endif
+ if (isge2byteoffset(adrptr->offset))
+ {
+ byte |= 0x02; /* 2 byte offset */
+ size = 2;
+ }
+ else if (adrptr->offset != 0)
+ {
+ byte |= 0x01; /* 1 byte offset */
+ size = 1;
+ }
+ else
+ size = 0;
+ putobj(byte | pcrflag);
+ if (isge2byteoffset(symnum))
+ putobjword(symnum);
+ else
+ putobj1((opcode_pt) symnum);
+ if (adrptr->offset != 0)
+ putobjoffset(adrptr->offset, size);
+ }
+ }
+}
+
+/* initialise private variables */
+
+void initobj(void)
+{
+ absbufend = (absbufptr = absbuf = hid_absbuf) + sizeof hid_absbuf;
+ objbufend = (objbufptr = objbuf = hid_objbuf) + sizeof hid_objbuf;
+}
+
+/*
+ write header to object file
+ also build array of imported/exported symbols
+*/
+
+void objheader(void)
+{
+ static char module_header[] =
+ {
+#ifdef I80386
+ 0xA3, 0x86,
+ 1, 0,
+ (char) (0xA3 + 0x86 + 1 + 0),
+#endif
+#ifdef MC6809
+ 'S', '1', /* 2 byte magic number */
+ 0, 1, /* 2 byte number of modules in file */
+ 'S' + '1' + 0 + 1, /* 1 byte checksum */
+#endif
+ };
+ static char seg_max_sizes[] =
+ {
+ 0x55, /* all segments have maximum size 2^16 */
+ 0x55, /* this is encoded by 0b01 4 times per byte */
+ 0x55, /* other codes are 0b00 = max size 2^8 */
+ 0x55, /* 0b10 = max size 2^24, 0b11 = max 2^32 */
+ };
+ unsigned char byte;
+ register struct sym_s **copyptr;
+ struct sym_s **copytop;
+ struct sym_s **hashptr;
+ struct lc_s *lcp;
+ char module_name[FILNAMLEN + 1];
+ char *nameptr;
+ unsigned offset;
+ unsigned segsizebytes;
+ unsigned size;
+ unsigned char sizebits;
+ unsigned strsiz; /* size of object string table */
+ unsigned symosiz; /* size of object symbol table */
+ register struct sym_s *symptr;
+ u32_T textlength;
+ int symcount = 0;
+
+ if ((objectc = objectg) == 0)
+ return;
+ writeobj(module_header, sizeof module_header);
+
+ /* calculate number of imported/exported symbols */
+ /* and lengths of symbol and string tables */
+ /* build array of imported/exported symbols */
+
+ symosiz = 0;
+ if (truefilename == NUL_PTR)
+ truefilename = filnamptr;
+ nameptr = strrchr(truefilename, DIRCHAR);
+ strcpy(module_name, nameptr != NUL_PTR ? nameptr + 1 : truefilename);
+ if ((nameptr = strrchr(module_name, '.')) != NUL_PTR)
+ *nameptr = 0;
+ strsiz = strlen(module_name) + 1;
+
+ for (hashptr = spt; hashptr < spt_top;)
+ if ((symptr = *hashptr++) != NUL_PTR)
+ do
+ {
+ if ((symptr->type & EXPBIT || symptr->data & IMPBIT) ||
+ (!globals_only_in_obj && symptr->name[0] != '.' &&
+ !(symptr->type & (MNREGBIT | MACBIT | VARBIT))))
+ {
+ symcount ++;
+ }
+ }
+ while ((symptr = symptr->next) != NUL_PTR);
+ arrext = copyptr = asalloc( sizeof(struct sym_s *) * symcount);
+
+ for (hashptr = spt; hashptr < spt_top;)
+ if ((symptr = *hashptr++) != NUL_PTR)
+ do
+ {
+ if ((symptr->type & EXPBIT || symptr->data & IMPBIT) ||
+ (!globals_only_in_obj && symptr->name[0] != '.' &&
+ !(symptr->type & (MNREGBIT | MACBIT | VARBIT))))
+ {
+ *copyptr++ = symptr;
+ strsiz += symptr->length + 1;
+ if (textseg>=0 && (symptr->data & SEGM) == textseg)
+ strsiz+=2;
+#if SIZEOF_OFFSET_T > 2
+ if (isge4byteoffset(symptr->value_reg_or_op.value))
+ size = 4 + 4;
+ /* 4 is size of offset into string table and flags */
+ /* 2nd 4 is for 4 byte offset */
+ else
+#endif
+ if (isge2byteoffset(symptr->value_reg_or_op.value))
+ size = 4 + 2;
+ else if (symptr->value_reg_or_op.value != 0)
+ size = 4 + 1;
+ else
+ size = 4;
+ symosiz += size;
+ ++numext;
+ }
+ }
+ while ((symptr = symptr->next) != NUL_PTR);
+ copytop = copyptr;
+
+ /* calculate length of text, and number of seg size bytes in header */
+
+ textlength = segsizebytes = 0;
+ lcp = lctab;
+ do
+ if (lcp->lc != 0)
+ {
+ textlength += lcp->lc; /* assuming text starts at 0 */
+#if SIZEOF_OFFSET_T > 2
+ if (isge4byteoffset(lcp->lc))
+ segsizebytes += 4;
+ else
+#endif
+ segsizebytes += 2; /* use 2 byte size if possible */
+ }
+ while (++lcp < lctabtop);
+
+/*
+ offset to text = length of header since only 1 module
+ header consists of:
+ module header sizeof module_header
+ offset to start of text 4
+ length of text 4
+ length of string area 2
+ class 1
+ revision 1
+ seg max sizes sizeof seg_max_sizes
+ seg size descriptors 4
+ seg sizes segsizebytes
+ symbol count 2
+ symbol offsets and types symosiz
+ strings strsiz
+*/
+
+ /* offset to start of text */
+
+ putobj4((u32_T) (sizeof module_header + 4 + 4 + 2 + 1 + 1 +
+ sizeof seg_max_sizes + 4 + segsizebytes + 2 +
+ symosiz) + strsiz);
+
+ /* length of text */
+
+ putobj4((u32_T) textlength);
+
+ /* length of string area */
+
+ putobjword(strsiz);
+
+ /* class and revision */
+
+ putobj1(0);
+ putobj1(0);
+
+ /* segment max sizes (constant) */
+
+ writeobj(seg_max_sizes, sizeof seg_max_sizes);
+
+ /* segment size descriptors */
+ /* produce only 0 and 2 byte sizes */
+
+ lcp = lctabtop;
+ byte = 0;
+ sizebits = OBJ_SEGSZ_TWO << 6;
+ do
+ {
+ --lcp;
+ if (lcp->lc != 0)
+ {
+ byte |= sizebits;
+#if SIZEOF_OFFSET_T > 2
+ if (isge4byteoffset(lcp->lc))
+ byte |= sizebits >> 1; /* XXX - convert size 2 to size 4 */
+#endif
+ }
+ if ((sizebits >>= 2) == 0)
+ {
+ putobj1(byte);
+ byte = 0;
+ sizebits = OBJ_SEGSZ_TWO << 6;
+ }
+ }
+ while (lcp > lctab);
+
+ /* segment sizes */
+
+ do /* lcp starts at lctab */
+ if (lcp->lc != 0)
+ {
+#if SIZEOF_OFFSET_T > 2
+ if (isge4byteoffset(lcp->lc))
+ putobj4(lcp->lc);
+ else
+#endif
+ putobjword((unsigned) lcp->lc);
+ }
+ while (++lcp < lctabtop);
+
+ /* symbol count */
+
+ putobjword(numext);
+
+ /* symbol offsets and types */
+
+ offset = strlen(module_name) + 1; /* 1st symbol begins after name */
+ for (copyptr = arrext; copyptr < copytop;)
+ {
+ putobjword(offset);
+ symptr = *copyptr++;
+ byte = symptr->type & OBJ_N_MASK;
+#if SIZEOF_OFFSET_T > 2
+ if (isge4byteoffset(symptr->value_reg_or_op.value))
+ {
+ byte |= OBJ_SZ_FOUR;
+ size = 4;
+ }
+ else
+#endif
+ if (isge2byteoffset(symptr->value_reg_or_op.value))
+ {
+ byte |= OBJ_SZ_TWO;
+ size = 2;
+ }
+ else if (symptr->value_reg_or_op.value != 0)
+ {
+ byte |= OBJ_SZ_ONE;
+ size = 1;
+ }
+ else
+ size = 0;
+ if ((symptr->type & (COMMBIT | REDBIT)) == (COMMBIT | REDBIT))
+ {
+ byte |= OBJ_SA_MASK;
+ symptr->data &= ~OBJ_I_MASK;
+ }
+ putobjword((unsigned)
+ (byte << 0x8) |
+ (symptr->type & OBJ_E_MASK) | /* |E|0000000| */
+ ((symptr->data & (OBJ_I_MASK | OBJ_A_MASK | OBJ_SEGM_MASK)) ^
+ /* |0|I|0|A|SEGM| */
+ RELBIT)); /* RELBIT by negative logic */
+ if ((symptr->type & (COMMBIT | REDBIT)) == (COMMBIT | REDBIT))
+ symptr->data |= OBJ_I_MASK;
+ if (size != 0)
+ putobjoffset(symptr->value_reg_or_op.value, size);
+ offset += symptr->length + 1;
+ if (textseg>=0 && (symptr->data & SEGM) == textseg)
+ offset+=2;
+ }
+
+ /* strings */
+
+ writeobj(module_name, strlen(module_name));
+ putobj1(0);
+ for (copyptr = arrext; copyptr < copytop;)
+ {
+ symptr = *copyptr++;
+ writeobj(symptr->name, symptr->length);
+ if (textseg>=0 && (symptr->data & SEGM) == textseg)
+ {
+ putobj1('.');
+ putobj1(hexdigit[textseg]);
+ }
+ putobj1(0);
+ }
+ putobj1(OBJ_SET_SEG | 0); /* default segment 0, |0010|SEGM| */
+}
+
+/* write trailer to object file */
+
+void objtrailer(void)
+{
+ if (objectc)
+ {
+ putobj(0); /* end of object file */
+ flushobj();
+ }
+}
+
+/* write char to absolute object code buffer, flush if necessary */
+
+void putabs(opcode_pt ch)
+{
+ if (objectc)
+ {
+ if (rmbcount != 0)
+ flushrmb();
+ if (absbufptr >= absbufend)
+ flushabs();
+ *absbufptr++ = ch;
+ }
+}
+
+/* write char to object code buffer, flush if necessary */
+
+void putobj(opcode_pt ch)
+{
+ if (objectc)
+ {
+ flushabs();
+ flushrmb();
+ putobj1(ch);
+ }
+}
+
+/* write char to object code buffer assuming nothing in absolute & rmb bufs */
+
+static void putobj1(opcode_pt ch)
+{
+ if (objbufptr >= objbufend)
+ flushobj();
+ *objbufptr++ = ch;
+}
+
+/* write 32 bit offset to object code buffer assuming ... */
+
+static void putobj4(u32_T offset)
+{
+ char buf[sizeof offset];
+
+ u4c4(buf, offset);
+ writeobj(buf, 4);
+}
+
+/* write sized offset to object code buffer assuming ... */
+
+static void putobjoffset(offset_t offset, count_t size)
+{
+ char buf[sizeof offset];
+
+#if SIZEOF_OFFSET_T > 2
+ u4cn(buf, offset, size);
+#else
+ u2cn(buf, offset, size);
+#endif
+ putobj1(buf[0]);
+ if (size > 1)
+ putobj1(buf[1]);
+ if (size > 2)
+ {
+ putobj1(buf[2]);
+ putobj1(buf[3]);
+ }
+}
+
+/* write word to object code buffer assuming ... */
+
+static void putobjword(unsigned word)
+{
+ char buf[sizeof word];
+
+ u2c2(buf, word);
+ putobj1(buf[0]);
+ putobj1(buf[1]);
+}
+
+/* write several bytes to object code buffer assuming ... */
+
+static void writeobj(char *buf, unsigned count)
+{
+ do
+ putobj1(*buf++);
+ while (--count);
+}
--- /dev/null
+/* gensym.c - generate symbol table for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "flag.h"
+#include "file.h"
+#include "globvar.h"
+
+static int printsym(register struct sym_s *symptr, unsigned column);
+static void sort(struct sym_s **array, struct sym_s **top,
+ bool_pt nameflag);
+
+/* sort labels in symbol table on name and value */
+/* if listing, write human-readable table to list file */
+/* if symbol file, write machine-readable tables to it */
+/* pointers become relative to start of file */
+
+void gensym(void)
+{
+ unsigned column;
+ struct sym_s **copyptr;
+ struct sym_s **copytop;
+ register struct sym_s **hashptr;
+ unsigned label_count; /* number of labels */
+ unsigned labels_length; /* length of all label strings */
+ struct sym_s **symlptr; /* start of symbol output list */
+ register struct sym_s *symptr;
+#ifdef BINSYM
+ unsigned label_stringptr; /* offset of label str from start of file */
+#endif
+ int symcount = 0;
+
+ labels_length = label_count = 0;
+
+ /* make copy of all relavant symbol ptrs on heap */
+ /* original ptrs can now be modified, but need to be an array for sort */
+
+ for (hashptr = spt; hashptr < spt_top;)
+ if ((symptr = *hashptr++) != NUL_PTR)
+ do
+ if (!(symptr->type & (MACBIT | MNREGBIT | VARBIT)))
+ symcount++;
+ while ((symptr = symptr->next) != NUL_PTR);
+ symlptr = copyptr = asalloc( sizeof(struct sym_s *) * symcount);
+
+ for (hashptr = spt; hashptr < spt_top;)
+ if ((symptr = *hashptr++) != NUL_PTR)
+ do
+ if (!(symptr->type & (MACBIT | MNREGBIT | VARBIT)))
+ {
+ *copyptr++ = symptr;
+ ++label_count;
+ labels_length += symptr->length + 3; /* 3 for type, value */
+ }
+ while ((symptr = symptr->next) != NUL_PTR);
+
+ sort(symlptr, copyptr, TRUE); /* sort on name */
+ copytop = copyptr;
+ if (list.global)
+ {
+ outfd = lstfil;
+ writenl();
+ writesn("Symbols:");
+ for (copyptr = symlptr, column = 0; copyptr < copytop;)
+ column = printsym(*copyptr++, column);
+ if (column != 0)
+ writenl();
+ }
+ if ((outfd = symfil) != 0)
+ {
+#ifndef BINSYM
+ for (copyptr = symlptr; copyptr < copytop;)
+ /* for (copyptr = spt; copyptr < spt_top;) */
+ {
+ int sft;
+ if((symptr = *copyptr++) == NUL_PTR ) continue;
+ if( globals_only_in_obj &&
+ !(symptr->type & EXPBIT)) continue;
+
+ writec(hexdigit[symptr->data & SEGM]);
+ writec(' ');
+
+ for(sft=SIZEOF_OFFSET_T*8-4; sft >= 0; sft-=4)
+ writec(hexdigit[(symptr->value_reg_or_op.value>>sft) & 0xF]);
+
+ writec(' ');
+ writec(symptr->type & EXPBIT ? 'E' : '-');
+ writec(symptr->type & ENTBIT ? 'N' : '-');
+ writec(symptr->data & IMPBIT ? 'I' : '-');
+ writec(symptr->data & RELBIT ? 'R' : 'A');
+ writec(symptr->type & COMMBIT ? 'C' : '-');
+
+ writec(' ');
+ write(outfd, symptr->name, (unsigned) (symptr->length));
+
+ /* printsym(*copyptr++, 0); */
+ writenl();
+ }
+#else
+ writew(mapnum);
+ label_count *= 2; /* now length of ptr table (2 bytes per ptr) */
+ label_stringptr = label_count + 6;
+ /* offset to current string in symbol file */
+ /* 6 is length of header */
+ labels_length += label_stringptr;
+ /* offset to ptr table sorted on value */
+ writew(labels_length + label_count);
+ /* total length of symbol file */
+ writew(label_count);
+ for (copyptr = symlptr; copyptr < copytop;)
+ {
+ symptr = *copyptr++;
+ writew((unsigned)
+ (symptr->next = (struct sym_s *) label_stringptr));
+ /* reuse "next" to record string position */
+ label_stringptr += symptr->length + 3;
+ }
+ for (copyptr = symlptr; copyptr < copytop;)
+ {
+ symptr = *copyptr++;
+ writew((unsigned) symptr->value_reg_or_op.value);
+ writec(symptr->type);
+ write(outfd, symptr->name, (unsigned) (symptr->length - 1));
+ writec(symptr->name[symptr->length - 1] | 0x80);
+ }
+ sort(symlptr, copyptr, FALSE);
+ /* sort on value */
+ for (copyptr = symlptr; copyptr < copytop;)
+ {
+ symptr = *copyptr++;
+ writew((unsigned) symptr->next); /* now has string position */
+ }
+#endif
+ }
+}
+
+/* print symbol nicely formatted for given column */
+
+static int printsym(register struct sym_s *symptr, unsigned column)
+{
+ unsigned char length;
+ register struct sym_listing_s *listptr;
+ char *outname;
+ char *symname;
+
+ listptr = (struct sym_listing_s *) temp_buf();
+ memset((char *) listptr, ' ', SYMLIS_LEN);
+ listptr->nullterm = 0;
+ if ((length = symptr->length) > SYMLIS_NAMELEN)
+ {
+ outname = listptr->name;
+ outname[length = SYMLIS_NAMELEN] = '+';
+ }
+ else
+ outname = listptr->name; /*(listptr->name + SYMLIS_NAMELEN) - length;*/
+ symname = symptr->name;
+ do
+ *outname++ = *symname++;
+ while (--length != 0);
+ listptr->ar[0] = symptr->data & RELBIT ? 'R' : 'A';
+ listptr->segm[0] = hexdigit[symptr->data & SEGM];
+ if (symptr->type & COMMBIT)
+ listptr->cein[0] = 'C';
+ else if (symptr->type & ENTBIT)
+ listptr->cein[0] = 'N';
+ else if (symptr->type & EXPBIT)
+ listptr->cein[0] = 'E';
+ else if (symptr->data & IMPBIT)
+ listptr->cein[0] = 'I';
+#if SIZEOF_OFFSET_T > 2
+ build_2hex_number((unsigned) (symptr->value_reg_or_op.value >> 16),
+ listptr->value);
+#endif
+ build_2hex_number((unsigned) symptr->value_reg_or_op.value,
+ listptr->value);
+ writes((char *) listptr);
+ if ((column += SYMLIS_LEN) > (80 - SYMLIS_LEN))
+ {
+ writenl();
+ column = 0;
+ }
+ return column;
+}
+
+/* shell sort symbols */
+
+static void sort(struct sym_s **array, struct sym_s **top, bool_pt nameflag)
+{
+ int gap;
+ int i;
+ int j;
+ register struct sym_s **left;
+ register struct sym_s **right;
+ int size;
+ struct sym_s *swap;
+
+ size = top - array;
+ /* choose gaps according to Knuth V3 p95 */
+ for (gap = 1, i = 4; (j = 3 * i + 1) < size; gap = i, i = j)
+ ;
+ do
+ {
+ for (j = gap; j < size; ++j)
+ for (i = j - gap; i >= 0; i -= gap)
+ {
+ left = &array[i];
+ right = &array[i + gap];
+ if ((bool_t) nameflag)
+ {
+ if (strcmp((*left)->name, (*right)->name) <= 0)
+ break;
+ }
+ else if ((unsigned) (*left)->value_reg_or_op.value <=
+ (*right)->value_reg_or_op.value)
+ break;
+ swap = *left;
+ *left = *right;
+ *right = swap;
+ }
+ }
+ while ((gap /= 3) != 0);
+}
--- /dev/null
+/* globvar.h - global variables for assembler */
+
+/* global control and bookkeeping */
+
+EXTERN bool_t binaryc; /* current binary code flag */
+EXTERN bool_t binaryg; /* global binary code flag */
+EXTERN offset_t binmbuf; /* offset in binary code buffer for memory */
+EXTERN bool_t binmbuf_set; /* set to 1 when binmbuf set by org */
+
+EXTERN unsigned char dirpag; /* direct page */
+
+EXTERN bool_t globals_only_in_obj; /* global symbols only in object file */
+
+EXTERN bool_t jumps_long; /* make all jumps long */
+
+EXTERN unsigned char mapnum; /* global map number */
+
+EXTERN bool_t objectc; /* current object code flag */
+EXTERN bool_t objectg; /* global object code flag */
+
+EXTERN bool_t pass; /* pass, FALSE means 0, TRUE means 1 */
+
+EXTERN offset_t progent; /* program entry point */
+
+EXTERN bool_t symgen; /* generate symbol table flag */
+
+EXTERN unsigned toterr; /* total errors */
+EXTERN unsigned totwarn; /* total warnings */
+
+EXTERN bool_t list_force; /* Force line to be listed - no error */
+
+/* bookeeping for current line */
+
+EXTERN char *linebuf; /* buffer */
+
+/* for symbol table routines */
+
+EXTERN unsigned char inidata; /* init sym entry data governed by "u" flag */
+EXTERN struct sym_s **spt; /* symbol pointer table */
+EXTERN struct sym_s **spt_top; /* top of symbol ptr table */
+
+/* for translator */
+
+EXTERN struct sym_s *label; /* non-null if valid label starts line */
+EXTERN unsigned char pedata; /* shows how PROGENT bound, flags like LCDATA*/
+EXTERN unsigned char popflags; /* pseudo-op flags */
+
+/* for BLOCK stack */
+
+EXTERN struct block_s *blockstak; /* stack ptr */
+EXTERN unsigned char blocklevel; /* nesting level */
+
+/* for IF stack */
+
+EXTERN struct if_s *ifstak; /* stack ptr */
+EXTERN unsigned char iflevel; /* nesting level */
+EXTERN bool_t ifflag; /* set if assembling */
+
+/* location counters for various segments */
+
+EXTERN offset_t lc; /* location counter */
+EXTERN unsigned char lcdata; /* shows how lc is bound */
+ /* FORBIT is set if lc is forward referenced */
+ /* RELBIT is is if lc is relocat. (not ASEG) */
+EXTERN offset_t lcjump; /* lc jump between lines */
+
+EXTERN offset_t oldlabel; /* Used for checking for moving labels */
+#ifdef LOW_BYTE
+#define mcount (((unsigned char *) &lcjump)[LOW_BYTE])
+ /* low byte of lcjump */
+#else
+#define mcount lcjump /* I think this is just a speed hack */
+#endif
+EXTERN struct lc_s *lcptr; /* top of current spot in lctab */
+EXTERN struct lc_s *lctab; /* start of lctab */
+EXTERN struct lc_s *lctabtop; /* top of lctab */
+
+/* for code generator */
+
+EXTERN opsize_t mnsize; /* 1 if forced byte operand size, else 0 */
+EXTERN opcode_t page;
+EXTERN opcode_t opcode;
+EXTERN opcode_t postb; /* postbyte, 0 if none */
+EXTERN unsigned char pcrflag; /* OBJ_RMASK set if addressing is PC-relative */
+EXTERN int last_pass; /* Pass number of last pass */
+EXTERN int dirty_pass; /* Set if this pass had a label movement */
+
+EXTERN int textseg; /* Text segment id */
+
+#ifdef I80386
+
+EXTERN opcode_t aprefix; /* address size prefix or 0 */
+EXTERN bool_t asld_compatible; /* asld compatibility flag */
+EXTERN opsize_t defsize; /* current default size */
+EXTERN opsize_t idefsize; /* initial default size */
+EXTERN opcode_t oprefix; /* operand size prefix or 0 */
+EXTERN opcode_t sprefix; /* segment prefix or 0 */
+EXTERN opcode_t sib; /* scale-index-base byte */
+
+EXTERN int cpuid; /* Assembler instruction limit flag */
+EXTERN int origcpuid; /* Assembler instruction limit flag */
+
+#endif
+
+/* miscellaneous */
+
+extern char hexdigit[];
+
+/* cpuid functions */
+#ifdef I80386
+#ifndef __AS386_16__
+#define iscpu(x) (cpuid>=(x))
+#define needcpu(x) do{ if(cpuid<(x)) {warning(CPUCLASH); cpuid|=0x10;} }while(0)
+#define setcpu(x) (cpuid=(x))
+#define cpuwarn() (cpuid&=0xF)
+#endif
+#endif
+
+#ifndef setcpu
+#define needcpu(x)
+#define setcpu(x)
+#define cpuwarn()
+#endif
+
--- /dev/null
+/* keywords.c - keyword tables for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "globvar.h"
+#include "opcode.h"
+
+/* --- start of keywords --- */
+
+/* registers */
+/* the register code (internal to assembler) is given in 1 byte */
+/* the "opcode" field is not used */
+
+char regs[] =
+{
+#ifdef I80386
+ 2, 'B', 'P', BPREG, 0,
+ 2, 'B', 'X', BXREG, 0,
+ 2, 'D', 'I', DIREG, 0,
+ 2, 'S', 'I', SIREG, 0,
+
+ 3, 'E', 'A', 'X', EAXREG, 0,
+ 3, 'E', 'B', 'P', EBPREG, 0,
+ 3, 'E', 'B', 'X', EBXREG, 0,
+ 3, 'E', 'C', 'X', ECXREG, 0,
+ 3, 'E', 'D', 'I', EDIREG, 0,
+ 3, 'E', 'D', 'X', EDXREG, 0,
+ 3, 'E', 'S', 'I', ESIREG, 0,
+ 3, 'E', 'S', 'P', ESPREG, 0,
+
+ 2, 'A', 'X', AXREG, 0,
+ 2, 'C', 'X', CXREG, 0,
+ 2, 'D', 'X', DXREG, 0,
+ 2, 'S', 'P', SPREG, 0,
+
+ 2, 'A', 'H', AHREG, 0,
+ 2, 'A', 'L', ALREG, 0,
+ 2, 'B', 'H', BHREG, 0,
+ 2, 'B', 'L', BLREG, 0,
+ 2, 'C', 'H', CHREG, 0,
+ 2, 'C', 'L', CLREG, 0,
+ 2, 'D', 'H', DHREG, 0,
+ 2, 'D', 'L', DLREG, 0,
+
+ 2, 'C', 'S', CSREG, 0,
+ 2, 'D', 'S', DSREG, 0,
+ 2, 'E', 'S', ESREG, 0,
+ 2, 'F', 'S', FSREG, 0,
+ 2, 'G', 'S', GSREG, 0,
+ 2, 'S', 'S', SSREG, 0,
+
+ 3, 'C', 'R', '0', CR0REG, 0,
+ 3, 'C', 'R', '2', CR2REG, 0,
+ 3, 'C', 'R', '3', CR3REG, 0,
+ 3, 'D', 'R', '0', DR0REG, 0,
+ 3, 'D', 'R', '1', DR1REG, 0,
+ 3, 'D', 'R', '2', DR2REG, 0,
+ 3, 'D', 'R', '3', DR3REG, 0,
+ 3, 'D', 'R', '6', DR6REG, 0,
+ 3, 'D', 'R', '7', DR7REG, 0,
+ 3, 'T', 'R', '3', TR3REG, 0,
+ 3, 'T', 'R', '4', TR4REG, 0,
+ 3, 'T', 'R', '5', TR5REG, 0,
+ 3, 'T', 'R', '6', TR6REG, 0,
+ 3, 'T', 'R', '7', TR7REG, 0,
+
+ 2, 'S', 'T', ST0REG, 0,
+#endif /* I80386 */
+
+#ifdef MC6809
+ 1, 'A', AREG, 0,
+ 1, 'B', BREG, 0,
+ 2, 'C', 'C', CCREG, 0,
+ 1, 'D', DREG, 0,
+ 2, 'D', 'P', DPREG, 0,
+ 2, 'P', 'C', PCREG, 0,
+ 3, 'P', 'C', 'R', PCREG, 0,
+ 1, 'S', SREG, 0,
+ 1, 'U', UREG, 0,
+ 1, 'X', XREG, 0,
+ 1, 'Y', YREG, 0,
+#endif
+ 0 /* end of register list */
+};
+
+#ifdef I80386
+
+/* type sizes */
+/* the "opcode" field gives the type size */
+
+char typesizes[] =
+{
+ 4, 'B', 'Y', 'T', 'E', BYTEOP, 1,
+ 5, 'D', 'W', 'O', 'R', 'D', DWORDOP, 4,
+ 5, 'F', 'W', 'O', 'R', 'D', FWORDOP, 6,
+ 3, 'F', 'A', 'R', FAROP, 0,
+ 4, 'N', 'E', 'A', 'R', WORDOP, 2,
+ 3, 'P', 'T', 'R', PTROP, 0,
+ 5, 'P', 'W', 'O', 'R', 'D', PWORDOP, 6,
+ 5, 'Q', 'W', 'O', 'R', 'D', QWORDOP, 8,
+ 5, 'T', 'B', 'Y', 'T', 'E', TBYTEOP, 10,
+ 4, 'W', 'O', 'R', 'D', WORDOP, 2,
+ 0 /* end of typesize list */
+};
+
+#endif
+
+/* ops */
+/* the routine number is given in 1 byte */
+/* the opcode is given in 1 byte (it is not used for pseudo-ops) */
+
+char ops[] =
+{
+ /* pseudo-ops. The "opcode" field is unused and padded with a null byte */
+ /* conditionals - must be first */
+ 4, 'E', 'L', 'S', 'E', ELSEOP, 0,
+ 6, 'E', 'L', 'S', 'E', 'I', 'F', ELSEIFOP, 0,
+ 7, 'E', 'L', 'S', 'E', 'I', 'F', 'C', ELSEIFCOP, 0,
+ 5, 'E', 'N', 'D', 'I', 'F', ENDIFOP, 0,
+ 2, 'I', 'F', IFOP, 0,
+ 3, 'I', 'F', 'C', IFCOP, 0,
+
+ /* unconditionals */
+ 6, '.', 'A', 'L', 'I', 'G', 'N', ALIGNOP, 0,
+ 6, '.', 'A', 'S', 'C', 'I', 'I', FCCOP, 0,
+ 6, '.', 'A', 'S', 'C', 'I', 'Z', ASCIZOP, 0,
+ 5, '.', 'B', 'L', 'K', 'B', RMBOP, 0,
+ 5, '.', 'B', 'L', 'K', 'W', BLKWOP, 0,
+ 5, 'B', 'L', 'O', 'C', 'K', BLOCKOP, 0,
+ 4, '.', 'B', 'S', 'S', BSSOP, 0,
+ 5, '.', 'B', 'Y', 'T', 'E', FCBOP, 0,
+ 4, 'C', 'O', 'M', 'M', COMMOP, 0,
+ 5, '.', 'C', 'O', 'M', 'M', COMMOP1, 0,
+ 5, '.', 'D', 'A', 'T', 'A', DATAOP, 0,
+ 6, '.', 'D', 'A', 'T', 'A', '1', FCBOP, 0,
+ 6, '.', 'D', 'A', 'T', 'A', '2', FDBOP, 0,
+#if SIZEOF_OFFSET_T > 2
+ 6, '.', 'D', 'A', 'T', 'A', '4', FQBOP, 0,
+#endif
+ 2, 'D', 'B', FCBOP, 0,
+#if SIZEOF_OFFSET_T > 2
+ 2, 'D', 'D', FQBOP, 0,
+#endif
+ 7, '.', 'D', 'E', 'F', 'I', 'N', 'E', EXPORTOP, 0,
+ 2, 'D', 'W', FDBOP, 0,
+ 3, 'E', 'N', 'D', PROCEOFOP, 0,
+ 4, 'E', 'N', 'D', 'B', ENDBOP, 0,
+ 6, '.', 'E', 'N', 'T', 'E', 'R', ENTEROP, 0,
+ 5, 'E', 'N', 'T', 'R', 'Y', ENTRYOP, 0,
+ 3, 'E', 'Q', 'U', EQUOP, 0,
+ 5, '.', 'E', 'V', 'E', 'N', EVENOP, 0,
+ 6, 'E', 'X', 'P', 'O', 'R', 'T', EXPORTOP, 0,
+ 6, 'E', 'X', 'T', 'E', 'R', 'N', IMPORTOP, 0,
+ 7, '.', 'E', 'X', 'T', 'E', 'R', 'N', IMPORTOP, 0,
+ 5, 'E', 'X', 'T', 'R', 'N', IMPORTOP, 0,
+ 4, 'F', 'A', 'I', 'L', FAILOP, 0,
+ 5, '.', 'F', 'A', 'I', 'L', FAILOP, 0,
+ 3, 'F', 'C', 'B', FCBOP, 0,
+ 3, 'F', 'C', 'C', FCCOP, 0,
+ 3, 'F', 'D', 'B', FDBOP, 0,
+ 3, 'G', 'E', 'T', GETOP, 0,
+ 7, '.', 'G', 'L', 'O', 'B', 'A', 'L', GLOBLOP, 0,
+ 6, '.', 'G', 'L', 'O', 'B', 'L', GLOBLOP, 0,
+ 5, 'I', 'D', 'E', 'N', 'T', IDENTOP, 0,
+ 6, 'I', 'M', 'P', 'O', 'R', 'T', IMPORTOP, 0,
+ 7, 'I', 'N', 'C', 'L', 'U', 'D', 'E', GETOP, 0,
+ 5, 'L', 'C', 'O', 'M', 'M', LCOMMOP, 0,
+ 6, '.', 'L', 'C', 'O', 'M', 'M', LCOMMOP1, 0,
+ 5, '.', 'L', 'I', 'S', 'T', LISTOP, 0,
+ 3, 'L', 'O', 'C', LOCOP, 0,
+#if SIZEOF_OFFSET_T > 2
+ 5, '.', 'L', 'O', 'N', 'G', FQBOP, 0,
+#endif
+ 8, '.', 'M', 'A', 'C', 'L', 'I', 'S', 'T', MACLISTOP, 0,
+ 5, 'M', 'A', 'C', 'R', 'O', MACROOP, 0,
+ 4, '.', 'M', 'A', 'P', MAPOP, 0,
+ 3, 'O', 'R', 'G', ORGOP, 0,
+ 4, '.', 'O', 'R', 'G', ORGOP, 0,
+ 6, 'P', 'U', 'B', 'L', 'I', 'C', EXPORTOP, 0,
+ 3, 'R', 'M', 'B', RMBOP, 0,
+ 4, '.', 'R', 'O', 'M', DATAOP, 0,
+ 5, '.', 'S', 'E', 'C', 'T', SECTOP, 0,
+ 3, 'S', 'E', 'T', SETOP, 0,
+ 5, 'S', 'E', 'T', 'D', 'P', SETDPOP, 0,
+ 6, '.', 'S', 'H', 'O', 'R', 'T', FDBOP, 0,
+ 6, '.', 'S', 'P', 'A', 'C', 'E', RMBOP, 0,
+ 5, '.', 'T', 'E', 'X', 'T', TEXTOP, 0,
+#ifndef MC6809
+ 5, 'U', 'S', 'E', '1', '6', USE16OP, 0,
+ 5, 'U', 'S', 'E', '3', '2', USE32OP, 0,
+#endif
+ 5, '.', 'W', 'A', 'R', 'N', WARNOP, 0,
+ 5, '.', 'W', 'O', 'R', 'D', FDBOP, 0,
+ 6, '.', 'Z', 'E', 'R', 'O', 'W', BLKWOP, 0,
+
+ /* hardware ops. The opcode field is now used */
+#ifdef I80386
+ 3, 'A', 'A', 'A', INHER, 0x37,
+ 3, 'A', 'A', 'D', INHER_A, 0xD5,
+ 3, 'A', 'A', 'M', INHER_A, 0xD4,
+ 3, 'A', 'A', 'S', INHER, 0x3F,
+ 3, 'A', 'D', 'C', GROUP1, 0x10,
+ 3, 'A', 'D', 'D', GROUP1, 0x00,
+ 3, 'A', 'N', 'D', GROUP1, 0x20,
+ 4, 'A', 'R', 'P', 'L', EwGw, 0x63,
+ 3, 'B', 'C', 'C', BCC, 0x73,
+ 3, 'B', 'C', 'S', BCC, 0x72,
+ 3, 'B', 'E', 'Q', BCC, 0x74,
+ 3, 'B', 'G', 'E', BCC, 0x7D,
+ 3, 'B', 'G', 'T', BCC, 0x7F,
+ 3, 'B', 'H', 'I', BCC, 0x77,
+ 4, 'B', 'H', 'I', 'S', BCC, 0x73,
+ 3, 'B', 'L', 'E', BCC, 0x7E,
+ 3, 'B', 'L', 'O', BCC, 0x72,
+ 4, 'B', 'L', 'O', 'S', BCC, 0x76,
+ 3, 'B', 'L', 'T', BCC, 0x7C,
+ 3, 'B', 'M', 'I', BCC, 0x78,
+ 3, 'B', 'N', 'E', BCC, 0x75,
+ 5, 'B', 'O', 'U', 'N', 'D', GvMa, 0x62,
+ 3, 'B', 'P', 'C', BCC, 0x7B,
+ 3, 'B', 'P', 'L', BCC, 0x79,
+ 3, 'B', 'P', 'S', BCC, 0x7A,
+ 2, 'B', 'R', CALL, JMP_OPCODE,
+ 3, 'B', 'V', 'C', BCC, 0x71,
+ 3, 'B', 'V', 'S', BCC, 0x70,
+ 4, 'C', 'A', 'L', 'L', CALL, JSR_OPCODE,
+ 5, 'C', 'A', 'L', 'L', 'F', CALLI, 0x9A,
+ 5, 'C', 'A', 'L', 'L', 'I', CALLI, 0x9A,
+ 3, 'C', 'B', 'W', INHER16, 0x98,
+ 3, 'C', 'L', 'C', INHER, 0xF8,
+ 3, 'C', 'L', 'D', INHER, 0xFC,
+ 3, 'C', 'L', 'I', INHER, 0xFA,
+ 3, 'C', 'M', 'C', INHER, 0xF5,
+ 3, 'C', 'M', 'P', GROUP1, CMP_OPCODE_BASE,
+ 4, 'C', 'M', 'P', 'S', INHER, CMPSW_OPCODE,
+ 5, 'C', 'M', 'P', 'S', 'B', INHER, CMPSB_OPCODE,
+ 5, 'C', 'M', 'P', 'S', 'D', INHER32, CMPSW_OPCODE,
+ 5, 'C', 'M', 'P', 'S', 'W', INHER16, CMPSW_OPCODE,
+ 4, 'C', 'M', 'P', 'W', INHER16, CMPSW_OPCODE,
+ 4, 'C', 'S', 'E', 'G', INHER, 0x2E,
+ 3, 'C', 'W', 'D', INHER16, 0x99,
+ 4, 'C', 'W', 'D', 'E', INHER32, 0x98,
+ 3, 'C', 'D', 'Q', INHER32, 0x99,
+ 3, 'D', 'A', 'A', INHER, 0x27,
+ 3, 'D', 'A', 'S', INHER, 0x2F,
+ 4, 'D', 'S', 'E', 'G', INHER, 0x3E,
+ 3, 'D', 'E', 'C', INCDEC, 0x08,
+ 3, 'D', 'I', 'V', DIVMUL, 0x30,
+ 5, 'E', 'N', 'T', 'E', 'R', ENTER, 0xC8,
+ 4, 'E', 'S', 'E', 'G', INHER, 0x26,
+ 4, 'F', 'S', 'E', 'G', INHER, 0x64,
+ 4, 'G', 'S', 'E', 'G', INHER, 0x65,
+ 3, 'H', 'L', 'T', INHER, 0xF4,
+ 4, 'I', 'D', 'I', 'V', DIVMUL, 0x38,
+ 4, 'I', 'M', 'U', 'L', IMUL, 0x28,
+ 2, 'I', 'N', IN, 0xEC,
+ 3, 'I', 'N', 'C', INCDEC, 0x00,
+ 3, 'I', 'N', 'S', INHER, 0x6D,
+ 4, 'I', 'N', 'S', 'B', INHER, 0x6C,
+ 4, 'I', 'N', 'S', 'D', INHER32, 0x6D,
+ 4, 'I', 'N', 'S', 'W', INHER16, 0x6D,
+ 3, 'I', 'N', 'T', INT, 0xCD,
+ 4, 'I', 'N', 'T', 'O', INHER, 0xCE,
+ 3, 'I', 'N', 'W', IN, 0xED,
+ 4, 'I', 'R', 'E', 'T', INHER16, 0xCF,
+ 5, 'I', 'R', 'E', 'T', 'D', INHER32, 0xCF,
+ 1, 'J', CALL, JMP_SHORT_OPCODE,
+ 2, 'J', 'A', JCC, 0x77,
+ 3, 'J', 'A', 'E', JCC, 0x73,
+ 2, 'J', 'B', JCC, 0x72,
+ 3, 'J', 'B', 'E', JCC, 0x76,
+ 2, 'J', 'C', JCC, 0x72,
+ 4, 'J', 'C', 'X', 'E', JCXZ, 0x2,
+ 4, 'J', 'C', 'X', 'Z', JCXZ, 0x2,
+ 5, 'J', 'E', 'C', 'X', 'E', JCXZ, 0x4,
+ 5, 'J', 'E', 'C', 'X', 'Z', JCXZ, 0x4,
+ 2, 'J', 'E', JCC, 0x74,
+ 2, 'J', 'G', JCC, 0x7F,
+ 3, 'J', 'G', 'E', JCC, 0x7D,
+ 2, 'J', 'L', JCC, 0x7C,
+ 3, 'J', 'L', 'E', JCC, 0x7E,
+ 3, 'J', 'M', 'P', CALL, JMP_SHORT_OPCODE,
+ 4, 'J', 'M', 'P', 'F', CALLI, 0xEA,
+ 4, 'J', 'M', 'P', 'I', CALLI, 0xEA,
+ 3, 'J', 'N', 'A', JCC, 0x76,
+ 4, 'J', 'N', 'A', 'E', JCC, 0x72,
+ 3, 'J', 'N', 'B', JCC, 0x73,
+ 4, 'J', 'N', 'B', 'E', JCC, 0x77,
+ 3, 'J', 'N', 'C', JCC, 0x73,
+ 3, 'J', 'N', 'E', JCC, 0x75,
+ 3, 'J', 'N', 'G', JCC, 0x7E,
+ 4, 'J', 'N', 'G', 'E', JCC, 0x7C,
+ 3, 'J', 'N', 'L', JCC, 0x7D,
+ 4, 'J', 'N', 'L', 'E', JCC, 0x7F,
+ 3, 'J', 'N', 'O', JCC, 0x71,
+ 3, 'J', 'N', 'P', JCC, 0x7B,
+ 3, 'J', 'N', 'S', JCC, 0x79,
+ 3, 'J', 'N', 'Z', JCC, 0x75,
+ 2, 'J', 'O', JCC, 0x70,
+ 2, 'J', 'P', JCC, 0x7A,
+ 3, 'J', 'P', 'E', JCC, 0x7A,
+ 3, 'J', 'P', 'O', JCC, 0x7B,
+ 2, 'J', 'S', JCC, 0x78,
+ 2, 'J', 'Z', JCC, 0x74,
+ 4, 'L', 'A', 'H', 'F', INHER, 0x9F,
+ 3, 'L', 'D', 'S', GvMp, 0xC5,
+ 3, 'L', 'E', 'A', LEA, 0x8D,
+ 5, 'L', 'E', 'A', 'V', 'E', INHER, 0xC9,
+ 3, 'L', 'E', 'S', GvMp, 0xC4,
+ 4, 'L', 'O', 'C', 'K', INHER, 0xF0,
+ 4, 'L', 'O', 'D', 'B', INHER, 0xAC,
+ 4, 'L', 'O', 'D', 'S', INHER, 0xAD,
+ 5, 'L', 'O', 'D', 'S', 'B', INHER, 0xAC,
+ 5, 'L', 'O', 'D', 'S', 'D', INHER32, 0xAD,
+ 5, 'L', 'O', 'D', 'S', 'W', INHER16, 0xAD,
+ 4, 'L', 'O', 'D', 'W', INHER16, 0xAD,
+ 4, 'L', 'O', 'O', 'P', JCC, 0xE2,
+ 5, 'L', 'O', 'O', 'P', 'E', JCC, 0xE1,
+ 6, 'L', 'O', 'O', 'P', 'N', 'E', JCC, 0xE0,
+ 6, 'L', 'O', 'O', 'P', 'N', 'Z', JCC, 0xE0,
+ 5, 'L', 'O', 'O', 'P', 'Z', JCC, 0xE1,
+ 3, 'M', 'O', 'V', MOV, 0x88,
+ 4, 'M', 'O', 'V', 'S', INHER, MOVSW_OPCODE,
+ 5, 'M', 'O', 'V', 'S', 'B', INHER, MOVSB_OPCODE,
+ 5, 'M', 'O', 'V', 'S', 'D', INHER32, MOVSW_OPCODE,
+ 5, 'M', 'O', 'V', 'S', 'W', INHER16, MOVSW_OPCODE,
+ 4, 'M', 'O', 'V', 'W', INHER16, MOVSW_OPCODE,
+ 3, 'M', 'U', 'L', DIVMUL, 0x20,
+ 3, 'N', 'E', 'G', NEGNOT, 0x18,
+ 3, 'N', 'O', 'P', INHER, 0x90,
+ 3, 'N', 'O', 'T', NEGNOT, 0x10,
+ 2, 'O', 'R', GROUP1, 0x08,
+ 3, 'O', 'U', 'T', OUT, 0xEE,
+ 4, 'O', 'U', 'T', 'S', INHER, 0x6F,
+ 5, 'O', 'U', 'T', 'S', 'B', INHER, 0x6E,
+ 5, 'O', 'U', 'T', 'S', 'D', INHER32, 0x6F,
+ 5, 'O', 'U', 'T', 'S', 'W', INHER16, 0x6F,
+ 4, 'O', 'U', 'T', 'W', OUT, 0xEF,
+ 3, 'P', 'O', 'P', PUSHPOP, POP_OPCODE,
+ 4, 'P', 'O', 'P', 'A', INHER16, 0x61,
+ 5, 'P', 'O', 'P', 'A', 'D', INHER32, 0x61,
+ 4, 'P', 'O', 'P', 'F', INHER16, 0x9D,
+ 5, 'P', 'O', 'P', 'F', 'D', INHER32, 0x9D,
+ 4, 'P', 'U', 'S', 'H', PUSHPOP, PUSH_OPCODE,
+ 5, 'P', 'U', 'S', 'H', 'A', INHER16, 0x60,
+ 6, 'P', 'U', 'S', 'H', 'A', 'D', INHER32, 0x60,
+ 5, 'P', 'U', 'S', 'H', 'F', INHER16, 0x9C,
+ 6, 'P', 'U', 'S', 'H', 'F', 'D', INHER32, 0x9C,
+ 3, 'R', 'C', 'L', GROUP2, 0x10,
+ 3, 'R', 'C', 'R', GROUP2, 0x18,
+ 3, 'R', 'O', 'L', GROUP2, 0x00,
+ 3, 'R', 'O', 'R', GROUP2, 0x08,
+ 3, 'R', 'E', 'P', INHER, 0xF3,
+ 4, 'R', 'E', 'P', 'E', INHER, 0xF3,
+ 5, 'R', 'E', 'P', 'N', 'E', INHER, 0xF2,
+ 5, 'R', 'E', 'P', 'N', 'Z', INHER, 0xF2,
+ 4, 'R', 'E', 'P', 'Z', INHER, 0xF3,
+ 3, 'R', 'E', 'T', RET, 0xC3,
+ 4, 'R', 'E', 'T', 'F', RET, 0xCB,
+ 4, 'R', 'E', 'T', 'I', RET, 0xCB,
+ 4, 'S', 'A', 'H', 'F', INHER, 0x9E,
+ 3, 'S', 'A', 'L', GROUP2, 0x20,
+ 3, 'S', 'A', 'R', GROUP2, 0x38,
+ 3, 'S', 'B', 'B', GROUP1, 0x18,
+ 4, 'S', 'C', 'A', 'B', INHER, 0xAE,
+ 4, 'S', 'C', 'A', 'S', INHER, 0xAF,
+ 5, 'S', 'C', 'A', 'S', 'B', INHER, 0xAE,
+ 5, 'S', 'C', 'A', 'S', 'D', INHER32, 0xAF,
+ 5, 'S', 'C', 'A', 'S', 'W', INHER16, 0xAF,
+ 4, 'S', 'C', 'A', 'W', INHER16, 0xAF,
+ 3, 'S', 'E', 'G', SEG, 0x06,
+ 3, 'S', 'H', 'L', GROUP2, 0x20,
+ 3, 'S', 'H', 'R', GROUP2, 0x28,
+ 4, 'S', 'S', 'E', 'G', INHER, 0x36,
+ 3, 'S', 'T', 'C', INHER, 0xF9,
+ 3, 'S', 'T', 'D', INHER, 0xFD,
+ 3, 'S', 'T', 'I', INHER, 0xFB,
+ 4, 'S', 'T', 'O', 'B', INHER, 0xAA,
+ 4, 'S', 'T', 'O', 'S', INHER, 0xAB,
+ 5, 'S', 'T', 'O', 'S', 'B', INHER, 0xAA,
+ 5, 'S', 'T', 'O', 'S', 'D', INHER32, 0xAB,
+ 5, 'S', 'T', 'O', 'S', 'W', INHER16, 0xAB,
+ 4, 'S', 'T', 'O', 'W', INHER16, 0xAB,
+ 3, 'S', 'U', 'B', GROUP1, 0x28,
+ 4, 'T', 'E', 'S', 'T', TEST, 0x84,
+ 4, 'W', 'A', 'I', 'T', INHER, WAIT_OPCODE,
+ 4, 'X', 'C', 'H', 'G', XCHG, 0x86,
+ 4, 'X', 'L', 'A', 'T', INHER, 0xD7,
+ 5, 'X', 'L', 'A', 'T', 'B', INHER, 0xD7,
+ 3, 'X', 'O', 'R', GROUP1, 0x30,
+
+ /* floating point */
+ 5, 'F', '2', 'X', 'M', '1', F_INHER, 0x70,
+ 4, 'F', 'A', 'B', 'S', F_INHER, 0x61,
+ 4, 'F', 'A', 'D', 'D', F_M4_M8_STST, 0x00,
+ 5, 'F', 'A', 'D', 'D', 'P', F_STST, 0x60,
+ 4, 'F', 'B', 'L', 'D', F_M10, 0x74,
+ 5, 'F', 'B', 'S', 'T', 'P', F_M10, 0x76,
+ 4, 'F', 'C', 'H', 'S', F_INHER, 0x60,
+ 5, 'F', 'C', 'L', 'E', 'X', F_W_INHER, 0xE2,
+ 4, 'F', 'C', 'O', 'M', F_M4_M8_OPTST, 0x02,
+ 5, 'F', 'C', 'O', 'M', 'P', F_M4_M8_OPTST, 0x03,
+ 6, 'F', 'C', 'O', 'M', 'P', 'P', F_INHER, 0x19,
+ 4, 'F', 'C', 'O', 'S', F_INHER, 0x7F,
+ 7, 'F', 'D', 'E', 'C', 'S', 'T', 'P', F_INHER, 0x76,
+ 5, 'F', 'D', 'I', 'S', 'I', F_W_INHER, 0xE1,
+ 4, 'F', 'D', 'I', 'V', F_M4_M8_STST, 0x06,
+ 5, 'F', 'D', 'I', 'V', 'P', F_STST, 0x67,
+ 5, 'F', 'D', 'I', 'V', 'R', F_M4_M8_STST, 0x07,
+ 6, 'F', 'D', 'I', 'V', 'R', 'P', F_STST, 0x66,
+ 4, 'F', 'E', 'N', 'I', F_W_INHER, 0xE0,
+ 5, 'F', 'F', 'R', 'E', 'E', F_ST, 0x50,
+ 5, 'F', 'I', 'A', 'D', 'D', F_M2_M4, 0x20,
+ 5, 'F', 'I', 'C', 'O', 'M', F_M2_M4, 0x22,
+ 6, 'F', 'I', 'C', 'O', 'M', 'P', F_M2_M4, 0x23,
+ 5, 'F', 'I', 'D', 'I', 'V', F_M2_M4, 0x26,
+ 6, 'F', 'I', 'D', 'I', 'V', 'R', F_M2_M4, 0x27,
+ 4, 'F', 'I', 'L', 'D', F_M2_M4_M8, 0x30,
+ 5, 'F', 'I', 'M', 'U', 'L', F_M2_M4, 0x21,
+ 7, 'F', 'I', 'N', 'C', 'S', 'T', 'P', F_INHER, 0x77,
+ 5, 'F', 'I', 'N', 'I', 'T', F_W_INHER, 0xE3,
+ 4, 'F', 'I', 'S', 'T', F_M2_M4, 0x32,
+ 5, 'F', 'I', 'S', 'T', 'P', F_M2_M4_M8, 0x33,
+ 5, 'F', 'I', 'S', 'U', 'B', F_M2_M4, 0x24,
+ 6, 'F', 'I', 'S', 'U', 'B', 'R', F_M2_M4, 0x25,
+ 3, 'F', 'L', 'D', F_M4_M8_M10_ST, 0x10,
+ 4, 'F', 'L', 'D', '1', F_INHER, 0x68,
+ 6, 'F', 'L', 'D', 'L', '2', 'E', F_INHER, 0x6A,
+ 6, 'F', 'L', 'D', 'L', '2', 'T', F_INHER, 0x69,
+ 5, 'F', 'L', 'D', 'C', 'W', F_M2, 0x15,
+ 6, 'F', 'L', 'D', 'E', 'N', 'V', F_M, 0x14,
+ 6, 'F', 'L', 'D', 'L', 'G', '2', F_INHER, 0x6C,
+ 6, 'F', 'L', 'D', 'L', 'N', '2', F_INHER, 0x6D,
+ 5, 'F', 'L', 'D', 'P', 'I', F_INHER, 0x6B,
+ 4, 'F', 'L', 'D', 'Z', F_INHER, 0x6E,
+ 4, 'F', 'M', 'U', 'L', F_M4_M8_STST, 0x01,
+ 5, 'F', 'M', 'U', 'L', 'P', F_STST, 0x61,
+ 6, 'F', 'N', 'C', 'L', 'E', 'X', F_INHER, 0xE2,
+ 6, 'F', 'N', 'D', 'I', 'S', 'I', F_INHER, 0xE1,
+ 5, 'F', 'N', 'E', 'N', 'I', F_INHER, 0xE0,
+ 6, 'F', 'N', 'I', 'N', 'I', 'T', F_INHER, 0xE3,
+ 4, 'F', 'N', 'O', 'P', F_INHER, 0x50,
+ 6, 'F', 'N', 'S', 'A', 'V', 'E', F_M, 0x56,
+ 6, 'F', 'N', 'S', 'T', 'C', 'W', F_M2, 0x17,
+ 7, 'F', 'N', 'S', 'T', 'E', 'N', 'V', F_M, 0x16,
+ 6, 'F', 'N', 'S', 'T', 'S', 'W', F_M2_AX, 0x57,
+ 6, 'F', 'P', 'A', 'T', 'A', 'N', F_INHER, 0x73,
+ 5, 'F', 'P', 'R', 'E', 'M', F_INHER, 0x78,
+ 6, 'F', 'P', 'R', 'E', 'M', '1', F_INHER, 0x75,
+ 5, 'F', 'P', 'T', 'A', 'N', F_INHER, 0x72,
+ 7, 'F', 'R', 'N', 'D', 'I', 'N', 'T', F_INHER, 0x7C,
+ 6, 'F', 'R', 'S', 'T', 'O', 'R', F_M, 0x54,
+ 5, 'F', 'S', 'A', 'V', 'E', F_W_M, 0x56,
+ 6, 'F', 'S', 'C', 'A', 'L', 'E', F_INHER, 0x7D,
+ 6, 'F', 'S', 'E', 'T', 'P', 'M', F_INHER, 0xE4,
+ 4, 'F', 'S', 'I', 'N', F_INHER, 0x7E,
+ 7, 'F', 'S', 'I', 'N', 'C', 'O', 'S', F_INHER, 0x7B,
+ 5, 'F', 'S', 'Q', 'R', 'T', F_INHER, 0x7A,
+ 3, 'F', 'S', 'T', F_M4_M8_ST, FST_ENCODED,
+ 5, 'F', 'S', 'T', 'C', 'W', F_W_M2, 0x17,
+ 6, 'F', 'S', 'T', 'E', 'N', 'V', F_W_M, 0x16,
+ 4, 'F', 'S', 'T', 'P', F_M4_M8_M10_ST, FSTP_ENCODED,
+ 5, 'F', 'S', 'T', 'S', 'W', F_W_M2_AX, 0x57,
+ 4, 'F', 'S', 'U', 'B', F_M4_M8_STST, 0x04,
+ 5, 'F', 'S', 'U', 'B', 'P', F_STST, 0x65,
+ 5, 'F', 'S', 'U', 'B', 'R', F_M4_M8_STST, 0x05,
+ 6, 'F', 'S', 'U', 'B', 'R', 'P', F_STST, 0x64,
+ 4, 'F', 'T', 'S', 'T', F_INHER, 0x64,
+ 5, 'F', 'U', 'C', 'O', 'M', F_OPTST, 0x54,
+ 6, 'F', 'U', 'C', 'O', 'M', 'P', F_OPTST, 0x55,
+ 7, 'F', 'U', 'C', 'O', 'M', 'P', 'P', F_INHER, 0xA9,
+ 5, 'F', 'W', 'A', 'I', 'T', INHER, WAIT_OPCODE,
+ 4, 'F', 'X', 'A', 'M', F_INHER, 0x65,
+ 4, 'F', 'X', 'C', 'H', F_OPTST, 0x11,
+ 7, 'F', 'X', 'T', 'R', 'A', 'C', 'T', F_INHER, 0x74,
+ 5, 'F', 'Y', 'L', '2', 'X', F_INHER, 0x71,
+ 7, 'F', 'Y', 'L', '2', 'X', 'P', '1', F_INHER, 0x79,
+#endif /* I80386 */
+
+#ifdef MC6809
+ 3, 'A', 'B', 'X', INHER, 0x3A,
+ 4, 'A', 'D', 'C', 'A', ALL, 0x89,
+ 4, 'A', 'D', 'C', 'B', ALL, 0xC9,
+ 4, 'A', 'D', 'D', 'A', ALL, 0x8B,
+ 4, 'A', 'D', 'D', 'B', ALL, 0xCB,
+ 4, 'A', 'D', 'D', 'D', ALL, 0xC3,
+ 4, 'A', 'N', 'D', 'A', ALL, 0x84,
+ 4, 'A', 'N', 'D', 'B', ALL, 0xC4,
+ 5, 'A', 'N', 'D', 'C', 'C', IMMED, 0x1C,
+ 3, 'A', 'S', 'L', ALTER, 0x08,
+ 4, 'A', 'S', 'L', 'A', INHER, 0x48,
+ 4, 'A', 'S', 'L', 'B', INHER, 0x58,
+ 3, 'A', 'S', 'R', ALTER, 0x07,
+ 4, 'A', 'S', 'R', 'A', INHER, 0x47,
+ 4, 'A', 'S', 'R', 'B', INHER, 0x57,
+ 3, 'B', 'C', 'C', SHORT, 0x24,
+ 3, 'B', 'C', 'S', SHORT, 0x25,
+ 3, 'B', 'E', 'Q', SHORT, 0x27,
+ 3, 'B', 'G', 'E', SHORT, 0x2C,
+ 3, 'B', 'G', 'T', SHORT, 0x2E,
+ 3, 'B', 'H', 'I', SHORT, 0x22,
+ 3, 'B', 'H', 'S', SHORT, 0x24,
+ 4, 'B', 'I', 'T', 'A', ALL, 0X85,
+ 4, 'B', 'I', 'T', 'B', ALL, 0XC5,
+ 3, 'B', 'L', 'E', SHORT, 0x2F,
+ 3, 'B', 'L', 'O', SHORT, 0x25,
+ 3, 'B', 'L', 'S', SHORT, 0x23,
+ 3, 'B', 'L', 'T', SHORT, 0x2D,
+ 3, 'B', 'M', 'I', SHORT, 0x2B,
+ 3, 'B', 'N', 'E', SHORT, 0x26,
+ 3, 'B', 'P', 'L', SHORT, 0x2A,
+ 3, 'B', 'R', 'A', SHORT, 0x20,
+ 4, 'L', 'B', 'R', 'A', LONG, 0x16,
+ 3, 'B', 'R', 'N', SHORT, 0x21,
+ 3, 'B', 'S', 'R', SHORT, 0x8D,
+ 4, 'L', 'B', 'S', 'R', LONG, 0x17,
+ 3, 'B', 'V', 'C', SHORT, 0x28,
+ 3, 'B', 'V', 'S', SHORT, 0x29,
+ 3, 'C', 'L', 'R', ALTER, 0x0F,
+ 4, 'C', 'L', 'R', 'A', INHER, 0x4F,
+ 4, 'C', 'L', 'R', 'B', INHER, 0x5F,
+ 4, 'C', 'M', 'P', 'A', ALL, 0x81,
+ 4, 'C', 'M', 'P', 'B', ALL, 0xC1,
+ 4, 'C', 'M', 'P', 'X', ALL, 0x8C,
+ 3, 'C', 'O', 'M', ALTER, 0x03,
+ 4, 'C', 'O', 'M', 'A', INHER, 0x43,
+ 4, 'C', 'O', 'M', 'B', INHER, 0x53,
+ 4, 'C', 'W', 'A', 'I', IMMED, 0x3C,
+ 3, 'D', 'A', 'A', INHER, 0x19,
+ 3, 'D', 'E', 'C', ALTER, 0x0A,
+ 4, 'D', 'E', 'C', 'A', INHER, 0x4A,
+ 4, 'D', 'E', 'C', 'B', INHER, 0x5A,
+ 4, 'E', 'O', 'R', 'A', ALL, 0x88,
+ 4, 'E', 'O', 'R', 'B', ALL, 0xC8,
+ 3, 'E', 'X', 'G', SWAP, 0x1E,
+ 3, 'I', 'N', 'C', ALTER, 0x0C,
+ 4, 'I', 'N', 'C', 'A', INHER, 0x4C,
+ 4, 'I', 'N', 'C', 'B', INHER, 0x5C,
+ 3, 'J', 'M', 'P', ALTER, 0x0E,
+ 3, 'J', 'S', 'R', ALTER, 0x8D,
+ 3, 'L', 'D', 'A', ALL, 0x86,
+ 3, 'L', 'D', 'B', ALL, 0xC6,
+ 3, 'L', 'D', 'D', ALL, 0xCC,
+ 3, 'L', 'D', 'U', ALL, 0xCE,
+ 3, 'L', 'D', 'X', ALL, 0x8E,
+ 4, 'L', 'E', 'A', 'S', INDEXD, 0x32,
+ 4, 'L', 'E', 'A', 'U', INDEXD, 0x33,
+ 4, 'L', 'E', 'A', 'X', INDEXD, 0x30,
+ 4, 'L', 'E', 'A', 'Y', INDEXD, 0x31,
+ 3, 'L', 'S', 'L', ALTER, 0x08,
+ 4, 'L', 'S', 'L', 'A', INHER, 0x48,
+ 4, 'L', 'S', 'L', 'B', INHER, 0x58,
+ 3, 'L', 'S', 'R', ALTER, 0x04,
+ 4, 'L', 'S', 'R', 'A', INHER, 0x44,
+ 4, 'L', 'S', 'R', 'B', INHER, 0x54,
+ 3, 'M', 'U', 'L', INHER, 0x3D,
+ 3, 'N', 'E', 'G', ALTER, 0x00,
+ 4, 'N', 'E', 'G', 'A', INHER, 0x40,
+ 4, 'N', 'E', 'G', 'B', INHER, 0x50,
+ 3, 'N', 'O', 'P', INHER, 0x12,
+ 3, 'O', 'R', 'A', ALL, 0x8A,
+ 3, 'O', 'R', 'B', ALL, 0xCA,
+ 4, 'O', 'R', 'C', 'C', IMMED, 0x1A,
+ 4, 'P', 'S', 'H', 'S', SSTAK, 0x34,
+ 4, 'P', 'S', 'H', 'U', USTAK, 0x36,
+ 4, 'P', 'U', 'L', 'S', SSTAK, 0x35,
+ 4, 'P', 'U', 'L', 'U', USTAK, 0x37,
+ 3, 'R', 'O', 'L', ALTER, 0x09,
+ 4, 'R', 'O', 'L', 'A', INHER, 0x49,
+ 4, 'R', 'O', 'L', 'B', INHER, 0x59,
+ 3, 'R', 'O', 'R', ALTER, 0x06,
+ 4, 'R', 'O', 'R', 'A', INHER, 0x46,
+ 4, 'R', 'O', 'R', 'B', INHER, 0x56,
+ 3, 'R', 'T', 'I', INHER, 0x3B,
+ 3, 'R', 'T', 'S', INHER, 0x39,
+ 4, 'S', 'B', 'C', 'A', ALL, 0x82,
+ 4, 'S', 'B', 'C', 'B', ALL, 0xC2,
+ 3, 'S', 'E', 'X', INHER, 0x1D,
+ 3, 'S', 'T', 'A', ALTER, 0x87,
+ 3, 'S', 'T', 'B', ALTER, 0xC7,
+ 3, 'S', 'T', 'D', ALTER, 0xCD,
+ 3, 'S', 'T', 'U', ALTER, 0xCF,
+ 3, 'S', 'T', 'X', ALTER, 0x8F,
+ 4, 'S', 'U', 'B', 'A', ALL, 0x80,
+ 4, 'S', 'U', 'B', 'B', ALL, 0xC0,
+ 4, 'S', 'U', 'B', 'D', ALL, 0x83,
+ 3, 'S', 'W', 'I', INHER, 0x3F,
+ 4, 'S', 'Y', 'N', 'C', INHER, 0x13,
+ 3, 'T', 'F', 'R', SWAP, 0x1F,
+ 3, 'T', 'S', 'T', ALTER, 0x0D,
+ 4, 'T', 'S', 'T', 'A', INHER, 0x4D,
+ 4, 'T', 'S', 'T', 'B', INHER, 0x5D,
+#endif /* MC6809 */
+ 0 /* end of ops */
+};
+
+char page1ops[] =
+{
+#ifdef I80386
+ 3, 'B', 'S', 'F', GvEv, 0xBC,
+ 3, 'B', 'S', 'R', GvEv, 0xBD,
+ 5, 'B', 'S', 'W', 'A', 'P', BSWAP, 0xC8,
+ 2, 'B', 'T', GROUP8, 0x20,
+ 3, 'B', 'T', 'C', GROUP8, 0x38,
+ 3, 'B', 'T', 'R', GROUP8, 0x30,
+ 3, 'B', 'T', 'S', GROUP8, 0x28,
+ 4, 'C', 'L', 'T', 'S', INHER, 0x06,
+ 7, 'C', 'M', 'P', 'X', 'C', 'H', 'G', ExGx, 0xA6,
+ 4, 'I', 'N', 'V', 'D', INHER, 0x08,
+ 6, 'I', 'N', 'V', 'L', 'P', 'G', GROUP7, 0x38,
+ 3, 'L', 'A', 'R', GvEv, 0x02,
+ 3, 'L', 'F', 'S', GvMp, 0xB4,
+ 4, 'L', 'G', 'D', 'T', GROUP7, 0x10,
+ 3, 'L', 'G', 'S', GvMp, 0xB5,
+ 4, 'L', 'I', 'D', 'T', GROUP7, 0x18,
+ 4, 'L', 'L', 'D', 'T', GROUP6, 0x10,
+ 4, 'L', 'M', 'S', 'W', GROUP7, 0x30,
+ 3, 'L', 'S', 'L', GvEv, 0x03,
+ 3, 'L', 'S', 'S', GvMp, 0xB2,
+ 3, 'L', 'T', 'R', GROUP6, 0x18,
+ 5, 'M', 'O', 'V', 'S', 'X', MOVX, 0xBE,
+ 5, 'M', 'O', 'V', 'Z', 'X', MOVX, 0xB6,
+ 5, 'R', 'D', 'M', 'S', 'R', INHER, 0x32,
+ 4, 'S', 'E', 'T', 'A', SETCC, 0x97,
+ 5, 'S', 'E', 'T', 'A', 'E', SETCC, 0x93,
+ 4, 'S', 'E', 'T', 'B', SETCC, 0x92,
+ 5, 'S', 'E', 'T', 'B', 'E', SETCC, 0x96,
+ 4, 'S', 'E', 'T', 'C', SETCC, 0x92,
+ 4, 'S', 'E', 'T', 'E', SETCC, 0x94,
+ 4, 'S', 'E', 'T', 'G', SETCC, 0x9F,
+ 5, 'S', 'E', 'T', 'G', 'E', SETCC, 0x9D,
+ 4, 'S', 'E', 'T', 'L', SETCC, 0x9C,
+ 5, 'S', 'E', 'T', 'L', 'E', SETCC, 0x9E,
+ 5, 'S', 'E', 'T', 'N', 'A', SETCC, 0x96,
+ 6, 'S', 'E', 'T', 'N', 'A', 'E', SETCC, 0x92,
+ 5, 'S', 'E', 'T', 'N', 'B', SETCC, 0x93,
+ 6, 'S', 'E', 'T', 'N', 'B', 'E', SETCC, 0x97,
+ 5, 'S', 'E', 'T', 'N', 'C', SETCC, 0x93,
+ 5, 'S', 'E', 'T', 'N', 'E', SETCC, 0x95,
+ 5, 'S', 'E', 'T', 'N', 'G', SETCC, 0x9E,
+ 6, 'S', 'E', 'T', 'N', 'G', 'E', SETCC, 0x9C,
+ 5, 'S', 'E', 'T', 'N', 'L', SETCC, 0x9D,
+ 6, 'S', 'E', 'T', 'N', 'L', 'E', SETCC, 0x9F,
+ 5, 'S', 'E', 'T', 'N', 'O', SETCC, 0x91,
+ 5, 'S', 'E', 'T', 'N', 'P', SETCC, 0x9B,
+ 5, 'S', 'E', 'T', 'N', 'S', SETCC, 0x99,
+ 5, 'S', 'E', 'T', 'N', 'Z', SETCC, 0x95,
+ 4, 'S', 'E', 'T', 'O', SETCC, 0x90,
+ 4, 'S', 'E', 'T', 'P', SETCC, 0x9A,
+ 5, 'S', 'E', 'T', 'P', 'E', SETCC, 0x9A,
+ 5, 'S', 'E', 'T', 'P', 'O', SETCC, 0x9B,
+ 4, 'S', 'E', 'T', 'S', SETCC, 0x98,
+ 4, 'S', 'E', 'T', 'Z', SETCC, 0x94,
+ 4, 'S', 'G', 'D', 'T', GROUP7, 0x00,
+ 4, 'S', 'I', 'D', 'T', GROUP7, 0x08,
+ 4, 'S', 'H', 'L', 'D', SH_DOUBLE, 0xA4,
+ 4, 'S', 'H', 'R', 'D', SH_DOUBLE, 0xAC,
+ 4, 'S', 'L', 'D', 'T', GROUP6, 0x00,
+ 4, 'S', 'M', 'S', 'W', GROUP7, 0x20,
+ 3, 'S', 'T', 'R', GROUP6, 0x08,
+ 4, 'V', 'E', 'R', 'R', GROUP6, 0x20,
+ 4, 'V', 'E', 'R', 'W', GROUP6, 0x28,
+ 6, 'W', 'B', 'I', 'N', 'V', 'D', INHER, 0x09,
+ 5, 'W', 'R', 'M', 'S', 'R', INHER, 0x30,
+ 4, 'X', 'A', 'D', 'D', ExGx, 0xC0,
+#endif /* I80386 */
+
+#ifdef MC6809
+ 4, 'L', 'B', 'C', 'C', LONG, 0x24,
+ 4, 'L', 'B', 'C', 'S', LONG, 0x25,
+ 4, 'L', 'B', 'E', 'Q', LONG, 0x27,
+ 4, 'L', 'B', 'G', 'E', LONG, 0x2C,
+ 4, 'L', 'B', 'G', 'T', LONG, 0x2E,
+ 4, 'L', 'B', 'H', 'I', LONG, 0x22,
+ 4, 'L', 'B', 'H', 'S', LONG, 0x24,
+ 4, 'L', 'B', 'L', 'E', LONG, 0x2F,
+ 4, 'L', 'B', 'L', 'O', LONG, 0x25,
+ 4, 'L', 'B', 'L', 'S', LONG, 0x23,
+ 4, 'L', 'B', 'L', 'T', LONG, 0x2D,
+ 4, 'L', 'B', 'M', 'I', LONG, 0x2B,
+ 4, 'L', 'B', 'N', 'E', LONG, 0x26,
+ 4, 'L', 'B', 'P', 'L', LONG, 0x2A,
+ 4, 'L', 'B', 'R', 'N', LONG, 0x21,
+ 4, 'L', 'B', 'V', 'C', LONG, 0x28,
+ 4, 'L', 'B', 'V', 'S', LONG, 0x29,
+ 4, 'C', 'M', 'P', 'D', ALL, 0x83,
+ 4, 'C', 'M', 'P', 'Y', ALL, 0x8C,
+ 3, 'L', 'D', 'S', ALL, 0xCE,
+ 3, 'L', 'D', 'Y', ALL, 0x8E,
+ 3, 'S', 'T', 'S', ALTER, 0xCF,
+ 3, 'S', 'T', 'Y', ALTER, 0x8F,
+ 4, 'S', 'W', 'I', '2', INHER, 0x3F,
+#endif /* MC6809 */
+ 0 /* end of page 1 ops */
+};
+
+char page2ops[] =
+{
+#ifdef MC6809
+ 4, 'C', 'M', 'P', 'S', ALL, 0x8C,
+ 4, 'C', 'M', 'P', 'U', ALL, 0x83,
+ 4, 'S', 'W', 'I', '3', INHER, 0x3F,
+#endif
+ 0 /* end of page 2 ops */
+};
+
+#ifdef I80386
+# ifdef MNSIZE
+char bytesizeops[] =
+{
+ 4, 'A', 'D', 'C', 'B', GROUP1, 0x10,
+ 4, 'A', 'D', 'D', 'B', GROUP1, 0x00,
+ 4, 'A', 'N', 'D', 'B', GROUP1, 0x20,
+ 4, 'C', 'M', 'P', 'B', GROUP1, CMP_OPCODE_BASE,
+ 4, 'D', 'E', 'C', 'B', INCDEC, 0x08,
+ 4, 'D', 'I', 'V', 'B', DIVMUL, 0x30,
+ 5, 'I', 'D', 'I', 'V', 'B', DIVMUL, 0x38,
+ 5, 'I', 'M', 'U', 'L', 'B', IMUL, 0x28,
+ 3, 'I', 'N', 'B', IN, 0xEC,
+ 4, 'I', 'N', 'C', 'B', INCDEC, 0x00,
+ 4, 'M', 'O', 'V', 'B', MOV, 0x88,
+ 4, 'M', 'U', 'L', 'B', DIVMUL, 0x20,
+ 4, 'N', 'E', 'G', 'B', NEGNOT, 0x18,
+ 4, 'N', 'O', 'T', 'B', NEGNOT, 0x10,
+ 3, 'O', 'R', 'B', GROUP1, 0x08,
+ 4, 'O', 'U', 'T', 'B', OUT, 0xEE,
+ 4, 'R', 'C', 'L', 'B', GROUP2, 0x10,
+ 4, 'R', 'C', 'R', 'B', GROUP2, 0x18,
+ 4, 'R', 'O', 'L', 'B', GROUP2, 0x00,
+ 4, 'R', 'O', 'R', 'B', GROUP2, 0x08,
+ 4, 'S', 'A', 'L', 'B', GROUP2, 0x20,
+ 4, 'S', 'A', 'R', 'B', GROUP2, 0x38,
+ 4, 'S', 'H', 'L', 'B', GROUP2, 0x20,
+ 4, 'S', 'H', 'R', 'B', GROUP2, 0x28,
+ 4, 'S', 'B', 'B', 'B', GROUP1, 0x18,
+ 4, 'S', 'U', 'B', 'B', GROUP1, 0x28,
+ 5, 'T', 'E', 'S', 'T', 'B', TEST, 0x84,
+ 5, 'X', 'C', 'H', 'G', 'B', XCHG, 0x86,
+ 4, 'X', 'O', 'R', 'B', GROUP1, 0x30,
+ 0 /* end of byte size ops */
+};
+# endif /* MNSIZE */
+#endif /* I80386 */
+
+/* --- end of keywords --- */
--- /dev/null
+/* macro.c - expand macros for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "globvar.h"
+#include "scan.h"
+#undef EXTERN
+#define EXTERN
+#include "macro.h"
+
+/*
+ Enter macro: stack macro and get its parameters.
+ Parameters form a linked list of null-terminated strings of form
+ next:string. The first string is the macro number in 4 bytes.
+*/
+
+void entermac(struct sym_s *symptr)
+{
+ if (maclevel >= MAXMAC)
+ error(MACOV);
+ else if (macpar + 2 > macptop)
+ error(PAROV); /* no room for 0th param */
+ /* (2 structs to fit it!) */
+ else
+ {
+ char ch;
+ struct schain_s *param1;
+ register char *reglineptr;
+ register char *stringptr;
+
+ ++maclevel;
+ (--macstak)->text = (char *) symptr->value_reg_or_op.value;
+ macstak->parameters = param1 = macpar;
+ param1->next = NUL_PTR;
+ *(stringptr = build_number(++macnum, 3, param1->string)) = 0;
+ macpar = (struct schain_s *) (stringptr + 1);
+ /* TODO: alignment */
+ getsym();
+ if (sym == EOLSYM)
+ return; /* no other params */
+ if (sym != LPAREN)
+ reglineptr = symname;
+ else
+ reglineptr = lineptr;
+ stringptr = macpar->string;
+ while (TRUE)
+ {
+ if (stringptr >= (char *) macptop)
+ {
+ symname = reglineptr;
+ error(PAROV);
+ return;
+ }
+ ch = *reglineptr++;
+ if (ch == '\\')
+ /* escaped means no special meaning for slash, comma, paren */
+ ch = *reglineptr++;
+ else if (ch == ',' || ch == ')' || ch == '!' || ch == ';'
+ || ch == '\n' || ch == 0)
+ {
+ if (stringptr >= (char *) macptop)
+ {
+ symname = reglineptr;
+ error(PAROV); /* no room for null */
+ return;
+ }
+ *stringptr = 0;
+ param1->next = macpar; /* ptr from previous */
+ (param1 = macpar)->next = NUL_PTR;
+ /* this goes nowhere */
+ macpar = (struct schain_s *) (stringptr + 1);
+ /* but is finished OK - TODO align */
+ stringptr = macpar->string;
+ if (ch != ',')
+ return;
+ continue;
+ }
+ if ((*stringptr++ = ch) == 0)
+ {
+ symname = reglineptr;
+ error(RPEXP);
+ return;
+ }
+ }
+ }
+}
+
+/* MACRO pseudo-op */
+
+void pmacro(void)
+{
+ bool_t saving;
+ bool_t savingc;
+ struct sym_s *symptr=0;
+ int maclen = 8;
+ int macoff = 0;
+ char * macbuf = asalloc(8);
+
+ saving = /* prepare for bad macro */
+ savingc = FALSE; /* normally don't save comments */
+ macload = TRUE; /* show loading */
+ if (label != NUL_PTR)
+ error(ILLAB);
+ else if (sym != IDENT)
+ error(LABEXP);
+ else
+ {
+ symptr = gsymptr;
+ if (symptr->type & MNREGBIT)
+ error(LABEXP);
+ else if (symptr->type & LABIT || symptr->data & FORBIT)
+ error(RELAB);
+ else if (pass != last_pass || symptr->type & REDBIT)
+ /* copy on pass 0, also pass 1 if redefined */
+ {
+ saving = TRUE;
+ if (symptr->type & MACBIT)
+ symptr->type |= REDBIT;
+ else
+ symptr->type |= MACBIT;
+ symptr->data = UNDBIT; /* undefined till end */
+ symptr->value_reg_or_op.value = (offset_t) macbuf;
+ getsym_nolookup(); /* test for "C" */
+ if (sym == IDENT && lineptr == symname + 1 && *symname == 'C')
+ savingc = TRUE;
+ }
+ }
+ while (TRUE)
+ {
+ skipline();
+ listline();
+ readline();
+ if (!macload)
+ break; /* macload cleared to show eof */
+ getsym_nolookup();
+ if (sym == IDENT)
+ {
+ if (lineptr == symname + 4 &&
+ ( strncmp(symname, "MEND", 4) == 0 || strncmp(symname, "mend", 4) == 0) )
+ {
+ getsym();
+ break;
+ }
+ }
+ else if (sym != MACROARG)
+ {
+ if (!savingc)
+ continue; /* don't save comment */
+ }
+ if (!saving)
+ continue;
+ {
+ char * p = strchr(linebuf, EOLCHAR);
+ int len = (p-linebuf+1);
+
+ if ( macoff + len > maclen-4 )
+ {
+ maclen = maclen * 2 + len;
+ macbuf = asrealloc(macbuf, maclen);
+ }
+ memcpy(macbuf+macoff, linebuf, len);
+ macoff += len;
+
+ }
+ }
+ macload = FALSE;
+ if (saving)
+ {
+ macbuf[macoff] = ETB;
+ symptr->value_reg_or_op.value = (offset_t) macbuf;
+ symptr->data = 0;
+ }
+}
--- /dev/null
+/* 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 */
--- /dev/null
+/* mops.c - handle pseudo-ops */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "globvar.h"
+#include "opcode.h"
+#include "scan.h"
+#undef EXTERN
+#define EXTERN
+#include "address.h"
+
+#define is8bitadr(offset) ((offset_t) offset < 0x100)
+#define is8bitsignedoffset(offset) ((offset_t) (offset) + 0x80 < 0x100)
+#define pass2 (pass==last_pass)
+
+static void mshort2 P((void));
+static reg_pt regchk P((void));
+static void reldata P((void));
+static void segadj P((void));
+
+#ifdef I80386
+
+#define iswordadr(offset) ((offset_t) (offset) < 0x10000L)
+#define iswordoffset(offset) ((offset_t) (offset) + 0x8000L < 0x10000L)
+#define iswordorswordoffset(offset) ((offset_t) (offset) + 0xFFFFL < 0x1FFFEL)
+
+#define BYTE_SEGWORD 0x00
+#define isspecreg(r) ((r) >= CR0REG && (r) <= TR7REG)
+
+#define BASE_MASK 0x07
+#define BASE_SHIFT 0
+#define INDEX_MASK 0x38
+#define INDEX_SHIFT 3
+#define MOD_MASK 0xC0
+# define REG_MOD 0xC0
+# define MEM0_MOD 0x00
+# define MEM1_MOD 0x40
+# define MEM2_MOD 0x80
+#define REG_MASK 0x38
+#define REG_SHIFT 3
+#define RM_MASK 0x07
+#define RM_SHIFT 0
+# define D16_RM 0x06
+# define D32_RM 0x05
+# define SIB_NOBASE 0x05
+# define SIB_RM 0x04
+#define SREG_MASK 0x38
+#define SREG_SHIFT 3
+#define SS_MASK 0xC0
+#define SS_SHIFT 6
+
+#define SEGMOV 0x04
+#define SIGNBIT 0x02
+#define TOREGBIT 0x02
+#define WORDBIT 0x01
+
+static opcode_t baseind16[] =
+{
+ 0x00, /* BP + BP, illegal */
+ 0x00, /* BX + BP, illegal */
+ 0x03, /* DI + BP */
+ 0x02, /* SI + BP */
+ 0x00, /* BP + BX, illegal */
+ 0x00, /* BX + BX, illegal */
+ 0x01, /* DI + BX */
+ 0x00, /* SI + BX */
+ 0x03, /* BP + DI */
+ 0x01, /* BX + DI */
+ 0x00, /* DI + DI, illegal */
+ 0x00, /* SI + DI, illegal */
+ 0x02, /* BP + SI */
+ 0x00, /* BX + SI */
+ 0x00, /* DI + SI, illegal */
+ 0x00, /* SI + SI, illegal */
+};
+
+static opcode_t regbits[] =
+{
+ 0x05 << REG_SHIFT, /* BP */
+ 0x03 << REG_SHIFT, /* BX */
+ 0x07 << REG_SHIFT, /* DI */
+ 0x06 << REG_SHIFT, /* SI */
+
+ 0x00 << REG_SHIFT, /* EAX */
+ 0x05 << REG_SHIFT, /* EBP */
+ 0x03 << REG_SHIFT, /* EBX */
+ 0x01 << REG_SHIFT, /* ECX */
+ 0x07 << REG_SHIFT, /* EDI */
+ 0x02 << REG_SHIFT, /* EDX */
+ 0x06 << REG_SHIFT, /* ESI */
+ 0x04 << REG_SHIFT, /* ESP */
+
+ 0x00 << REG_SHIFT, /* AX */
+ 0x01 << REG_SHIFT, /* CX */
+ 0x02 << REG_SHIFT, /* DX */
+ 0x04 << REG_SHIFT, /* SP */
+
+ 0x04 << REG_SHIFT, /* AH */
+ 0x00 << REG_SHIFT, /* AL */
+ 0x07 << REG_SHIFT, /* BH */
+ 0x03 << REG_SHIFT, /* BL */
+ 0x05 << REG_SHIFT, /* CH */
+ 0x01 << REG_SHIFT, /* CL */
+ 0x06 << REG_SHIFT, /* DH */
+ 0x02 << REG_SHIFT, /* DL */
+
+ 0x01 << REG_SHIFT, /* CS */
+ 0x03 << REG_SHIFT, /* DS */
+ 0x00 << REG_SHIFT, /* ES */
+ 0x04 << REG_SHIFT, /* FS */
+ 0x05 << REG_SHIFT, /* GS */
+ 0x02 << REG_SHIFT, /* SS */
+
+ 0x00 << REG_SHIFT, /* CR0 */
+ 0x02 << REG_SHIFT, /* CR2 */
+ 0x03 << REG_SHIFT, /* CR3 */
+
+ 0x00 << REG_SHIFT, /* DR0 */
+ 0x01 << REG_SHIFT, /* DR1 */
+ 0x02 << REG_SHIFT, /* DR2 */
+ 0x03 << REG_SHIFT, /* DR3 */
+ 0x06 << REG_SHIFT, /* DR6 */
+ 0x07 << REG_SHIFT, /* DR7 */
+
+ 0x03 << REG_SHIFT, /* TR3 */
+ 0x04 << REG_SHIFT, /* TR4 */
+ 0x05 << REG_SHIFT, /* TR5 */
+ 0x06 << REG_SHIFT, /* TR6 */
+ 0x07 << REG_SHIFT, /* TR7 */
+
+ 0x00 << REG_SHIFT, /* ST(0) */
+ 0x01 << REG_SHIFT, /* ST(1) */
+ 0x02 << REG_SHIFT, /* ST(2) */
+ 0x03 << REG_SHIFT, /* ST(3) */
+ 0x04 << REG_SHIFT, /* ST(4) */
+ 0x05 << REG_SHIFT, /* ST(5) */
+ 0x06 << REG_SHIFT, /* ST(6) */
+ 0x07 << REG_SHIFT, /* ST(7) */
+};
+
+static opsize_t regsize[] =
+{
+ 2, /* BP */
+ 2, /* BX */
+ 2, /* DI */
+ 2, /* SI */
+
+ 4, /* EAX */
+ 4, /* EBP */
+ 4, /* EBX */
+ 4, /* ECX */
+ 4, /* EDI */
+ 4, /* EDX */
+ 4, /* ESI */
+ 4, /* ESP */
+
+ 2, /* AX */
+ 2, /* CX */
+ 2, /* DX */
+ 2, /* SP */
+
+ 1, /* AH */
+ 1, /* AL */
+ 1, /* BH */
+ 1, /* BL */
+ 1, /* CH */
+ 1, /* CL */
+ 1, /* DH */
+ 1, /* DL */
+
+ 2, /* CS */
+ 2, /* DS */
+ 2, /* ES */
+ 2, /* FS */
+ 2, /* GS */
+ 2, /* SS */
+
+ 4, /* CR0 */
+ 4, /* CR2 */
+ 4, /* CR3 */
+
+ 4, /* DR0 */
+ 4, /* DR1 */
+ 4, /* DR2 */
+ 4, /* DR3 */
+ 4, /* DR6 */
+ 4, /* DR7 */
+
+ 4, /* TR3 */
+ 4, /* TR4 */
+ 4, /* TR5 */
+ 4, /* TR6 */
+ 4, /* TR7 */
+
+ 10, /* ST(0) */
+ 10, /* ST(1) */
+ 10, /* ST(2) */
+ 10, /* ST(3) */
+ 10, /* ST(4) */
+ 10, /* ST(5) */
+ 10, /* ST(6) */
+ 10, /* ST(7) */
+
+ 0, /* NOREG */
+};
+
+static opcode_t regsegword[] =
+{
+ WORDBIT, /* BP */
+ WORDBIT, /* BX */
+ WORDBIT, /* DI */
+ WORDBIT, /* SI */
+
+ WORDBIT, /* EAX */
+ WORDBIT, /* EBP */
+ WORDBIT, /* EBX */
+ WORDBIT, /* ECX */
+ WORDBIT, /* EDI */
+ WORDBIT, /* EDX */
+ WORDBIT, /* ESI */
+ WORDBIT, /* ESP */
+
+ WORDBIT, /* AX */
+ WORDBIT, /* CX */
+ WORDBIT, /* DX */
+ WORDBIT, /* SP */
+
+ BYTE_SEGWORD, /* AH */
+ BYTE_SEGWORD, /* AL */
+ BYTE_SEGWORD, /* BH */
+ BYTE_SEGWORD, /* BL */
+ BYTE_SEGWORD, /* CH */
+ BYTE_SEGWORD, /* CL */
+ BYTE_SEGWORD, /* DH */
+ BYTE_SEGWORD, /* DL */
+
+ SEGMOV, /* CS */
+ SEGMOV, /* DS */
+ SEGMOV, /* ES */
+ SEGMOV, /* FS */
+ SEGMOV, /* GS */
+ SEGMOV, /* SS */
+
+ 0x20, /* CR0 */
+ 0x20, /* CR2 */
+ 0x20, /* CR3 */
+
+ 0x21, /* DR0 */
+ 0x21, /* DR1 */
+ 0x21, /* DR2 */
+ 0x21, /* DR3 */
+ 0x21, /* DR6 */
+ 0x21, /* DR7 */
+
+ 0x24, /* TR3 */
+ 0x24, /* TR4 */
+ 0x24, /* TR5 */
+ 0x24, /* TR6 */
+ 0x24, /* TR7 */
+
+ 0x00, /* ST(0) */
+ 0x00, /* ST(1) */
+ 0x00, /* ST(2) */
+ 0x00, /* ST(3) */
+ 0x00, /* ST(4) */
+ 0x00, /* ST(5) */
+ 0x00, /* ST(6) */
+ 0x00, /* ST(7) */
+
+ 0x00, /* NOREG */
+};
+
+static opcode_t rm[] =
+{
+ 0x05, /* BP */
+ 0x03, /* BX */
+ 0x07, /* DI */
+ 0x06, /* SI */
+
+ 0x00, /* EAX */
+ 0x05, /* EBP */
+ 0x03, /* EBX */
+ 0x01, /* ECX */
+ 0x07, /* EDI */
+ 0x02, /* EDX */
+ 0x06, /* ESI */
+ 0x04, /* ESP */
+
+ 0x00, /* AX */
+ 0x01, /* CX */
+ 0x02, /* DX */
+ 0x04, /* SP */
+
+ 0x04, /* AH */
+ 0x00, /* AL */
+ 0x07, /* BH */
+ 0x03, /* BL */
+ 0x05, /* CH */
+ 0x01, /* CL */
+ 0x06, /* DH */
+ 0x02, /* DL */
+
+ 0x01, /* CS */
+ 0x03, /* DS */
+ 0x00, /* ES */
+ 0x04, /* FS */
+ 0x05, /* GS */
+ 0x02, /* SS */
+
+ 0x00, /* CR0 */
+ 0x00, /* CR2 */
+ 0x00, /* CR3 */
+
+ 0x00, /* DR0 */
+ 0x00, /* DR1 */
+ 0x00, /* DR2 */
+ 0x00, /* DR3 */
+ 0x00, /* DR6 */
+ 0x00, /* DR7 */
+
+ 0x00, /* TR3 */
+ 0x00, /* TR4 */
+ 0x00, /* TR5 */
+ 0x00, /* TR6 */
+ 0x00, /* TR7 */
+
+ 0x00, /* ST(0) */
+ 0x00, /* ST(1) */
+ 0x00, /* ST(2) */
+ 0x00, /* ST(3) */
+ 0x00, /* ST(4) */
+ 0x00, /* ST(5) */
+ 0x00, /* ST(6) */
+ 0x00, /* ST(7) */
+
+ 0x04, /* null index reg for sib only */
+};
+
+static opcode_t rmfunny[] =
+{
+ 0x06, /* BP */
+ 0x07, /* BX */
+ 0x05, /* DI */
+ 0x04, /* SI */
+};
+
+static opcode_t segoverride[] =
+{
+ 0x2E, /* CS */
+ 0x3E, /* DS */
+ 0x26, /* ES */
+ 0x64, /* FS */
+ 0x65, /* GS */
+ 0x36, /* SS */
+};
+
+static opcode_t ss[] = /* scale to ss bits */
+{
+ 0x00, /* x0, illegal */
+ 0x00 << SS_SHIFT, /* x1 */
+ 0x01 << SS_SHIFT, /* x2 */
+ 0x00, /* x3, illegal */
+ 0x02 << SS_SHIFT, /* x4 */
+ 0x00, /* x5, illegal */
+ 0x00, /* x6, illegal */
+ 0x00, /* x7, illegal */
+ 0x03 << SS_SHIFT, /* x8 */
+};
+
+static unsigned char calljmp_kludge;
+static opcode_t direction;
+static bool_t fpreg_allowed;
+static opcode_t segword;
+/*
+ Values of segword:
+ BYTE_SEGWORD for byte ea's.
+ SEGMOV for segment registers
+ opcode for special registers
+ WORDBIT for other word and dword ea's
+*/
+
+static struct ea_s source;
+static struct ea_s source2;
+static struct ea_s target;
+
+static void Eb(struct ea_s *eap);
+static void Ew(struct ea_s *eap);
+static void Ev(struct ea_s *eap);
+static void Ex(struct ea_s *eap);
+static void Gd(struct ea_s *eap);
+static void Gw(struct ea_s *eap);
+static void Gv(struct ea_s *eap);
+static void Gx(struct ea_s *eap);
+static void buildea(struct ea_s *eap);
+static void buildfloat(void);
+static void buildfreg(void);
+static void buildimm(struct ea_s *eap, bool_pt signflag);
+static void buildregular(void);
+static void buildsegword(struct ea_s *eap);
+static void buildunary(opcode_pt opc);
+static opsize_pt displsize(struct ea_s *eap);
+static reg_pt fpregchk(void);
+static bool_pt getaccumreg(struct ea_s *eap);
+static void getbinary(void);
+static bool_pt getdxreg(struct ea_s *eap);
+static void getea(struct ea_s *eap);
+static void getimmed(struct ea_s *eap, count_t immed_count);
+static void getindirect(struct ea_s *eap);
+static void getshift(struct ea_s *eap);
+static reg_pt indregchk(reg_pt matchreg);
+static void kgerror(char * err_str);
+static void lbranch(int backamount);
+static void notbytesize(struct ea_s *eap);
+static void notimmed(struct ea_s *eap);
+static void notindirect(struct ea_s *eap);
+static void notsegorspecreg(struct ea_s *eap);
+static void yesimmed(struct ea_s *eap);
+static void yes_samesize(void);
+
+static void Eb(eap)
+register struct ea_s *eap;
+{
+ Ex(eap);
+ if (eap->size != 0x1)
+ {
+#ifndef NODEFAULTSIZE
+ if (eap->size == 0x0)
+ eap->size = 0x1;
+ else
+#endif
+ kgerror(ILL_SIZE);
+ }
+}
+
+static void Ew(eap)
+register struct ea_s *eap;
+{
+ Ex(eap);
+ if (eap->size != 0x2)
+ {
+#ifndef NODEFAULTSIZE
+ if (eap->size == 0x0)
+ eap->size = 0x2;
+ else
+#endif
+ kgerror(ILL_SIZE);
+ }
+}
+
+static void Ev(eap)
+register struct ea_s *eap;
+{
+ Ex(eap);
+ notbytesize(eap);
+}
+
+static void Ex(eap)
+register struct ea_s *eap;
+{
+ getea(eap);
+ notimmed(eap);
+ notsegorspecreg(eap);
+}
+
+static void Gd(eap)
+register struct ea_s *eap;
+{
+ Gx(eap);
+ if (eap->size != 0x4)
+ kgerror(ILL_SIZE);
+}
+
+static void Gw(eap)
+register struct ea_s *eap;
+{
+ Gx(eap);
+ if (eap->size != 0x2)
+ kgerror(ILL_SIZE);
+}
+
+static void Gv(eap)
+register struct ea_s *eap;
+{
+ Gx(eap);
+ notbytesize(eap);
+}
+
+static void Gx(eap)
+register struct ea_s *eap;
+{
+ Ex(eap);
+ notindirect(eap);
+}
+
+static void buildea(eap)
+register struct ea_s *eap;
+{
+ opsize_t asize;
+
+ ++mcount;
+ lastexp = eap->displ;
+ if (eap->indcount == 0x0)
+ postb = REG_MOD | rm[eap->base];
+ else
+ {
+ if (eap->base == NOREG)
+ {
+ if (eap->index == NOREG)
+ {
+ if ((asize = displsize(eap)) > 0x2)
+ postb = D32_RM;
+ else
+ postb = D16_RM;
+ }
+ else
+ {
+ asize = 0x4;
+ postb = SIB_NOBASE; /* for sib later */
+ }
+ }
+ else
+ {
+ if (eap->base > MAX16BITINDREG)
+ {
+ asize = 0x4;
+ postb = rm[eap->base];
+ }
+ else
+ {
+ asize = 0x2;
+ if (!(lastexp.data & UNDBIT) &&
+ !iswordorswordoffset(lastexp.offset))
+ error(ABOUNDS);
+ if (eap->index == NOREG)
+ postb = rmfunny[eap->base];
+ else if (eap->base <= MAX16BITINDREG)
+ postb = baseind16[eap->base + 0x4 * eap->index];
+ }
+ }
+ needcpu(asize==4?3:0);
+ if (asize != defsize)
+ aprefix = 0x67;
+ if (eap->base == NOREG)
+ mcount += asize;
+ else if (lastexp.data & (FORBIT | RELBIT | UNDBIT) ||
+ !is8bitsignedoffset(lastexp.offset))
+ {
+ postb |= MEM2_MOD;
+ mcount += asize;
+ }
+ else if (lastexp.offset != 0x0 ||
+ (eap->base == BPREG && eap->index == NOREG) ||
+ eap->base == EBPREG)
+ {
+ postb |= MEM1_MOD;
+ ++mcount;
+ }
+ if (asize > 0x2 && (eap->base == ESPREG || eap->index != NOREG))
+ {
+ sib = ss[eap->scale] |
+ (rm[eap->index] << INDEX_SHIFT) |
+ (postb & RM_MASK);
+ postb = (postb & MOD_MASK) | SIB_RM;
+ ++mcount;
+ }
+ }
+}
+
+static void buildfloat(void)
+{
+ if (mcount != 0x0)
+ {
+ buildea(&source);
+ oprefix = 0x0;
+ postb |= (opcode & 0x07) << REG_SHIFT;
+ opcode = ESCAPE_OPCODE_BASE | ((opcode & 0x70) >> 0x4);
+ }
+}
+
+static void buildfreg(void)
+{
+ mcount += 0x2;
+ oprefix = 0x0;
+ postb = REG_MOD | ((opcode & 0x07) << REG_SHIFT) | (target.base - ST0REG);
+ opcode = ESCAPE_OPCODE_BASE | ((opcode & 0x70) >> 0x4);
+}
+
+static void buildimm(eap, signflag)
+register struct ea_s *eap;
+bool_pt signflag;
+{
+ immadr = eap->displ;
+ immcount = eap->size;
+ if (!(immadr.data & (FORBIT | RELBIT | UNDBIT)))
+ {
+ if (immcount == 0x1)
+ {
+ if ((offset_t) (immadr.offset + 0x80) >= 0x180)
+ datatoobig();
+ }
+ else if (signflag && is8bitsignedoffset(immadr.offset))
+ {
+ opcode |= SIGNBIT;
+ immcount = 0x1;
+ }
+ else if (immcount == 0x2)
+ {
+ if ((offset_t) (immadr.offset + 0x8000L) >= 0x18000L)
+ datatoobig();
+ }
+ }
+}
+
+static void buildregular(void)
+{
+ if (mcount != 0x0)
+ {
+ buildea(&target);
+ postb |= regbits[source.base];
+ }
+}
+
+/* Check size and build segword. */
+
+static void buildsegword(eap)
+register struct ea_s *eap;
+{
+ if (eap->size == 0x0)
+#ifdef NODEFAULTSIZE
+ kgerror(SIZE_UNK);
+#else
+ eap->size = defsize;
+#endif
+ if (eap->indcount != 0x0 || eap->base == NOREG)
+ {
+ segword = WORDBIT;
+ if (eap->size == 0x1)
+ segword = BYTE_SEGWORD;
+ }
+ else
+ segword = regsegword[eap->base];
+}
+
+static void buildunary(opc)
+opcode_pt opc;
+{
+ if (mcount != 0x0)
+ {
+ buildea(&target);
+ postb |= opcode;
+ opcode = opc;
+ }
+}
+
+static opsize_pt displsize(eap)
+register struct ea_s *eap;
+{
+ opsize_t asize;
+
+ asize = defsize;
+ if (!(eap->displ.data & UNDBIT))
+ {
+ if (asize > 0x2)
+ {
+ if (!(eap->displ.data & (FORBIT | RELBIT)) &&
+ iswordadr(eap->displ.offset))
+ asize = 0x2;
+ }
+ else if (!iswordorswordoffset(eap->displ.offset))
+ /* should really use iswordadr() */
+ /* but compiler generates signed offsets */
+ {
+ if (!(eap->displ.data & (FORBIT | RELBIT)))
+ asize = 0x4;
+ else if (pass2)
+ error(ABOUNDS);
+ }
+ }
+ return asize;
+}
+
+static reg_pt fpregchk(void)
+{
+ reg_pt fpreg;
+
+ fpreg_allowed = TRUE;
+ fpreg = regchk();
+ fpreg_allowed = FALSE;
+ if (fpreg != ST0REG)
+ return NOREG;
+ getsym();
+ if (sym == LPAREN)
+ {
+ getsym();
+ if (sym != INTCONST || (unsigned) number >= 0x8)
+ error(ILL_FP_REG);
+ else
+ {
+ fpreg += number;
+ getsym();
+ if (sym != RPAREN)
+ error(RPEXP);
+ else
+ getsym();
+ }
+ }
+ return fpreg;
+}
+
+static bool_pt getaccumreg(eap)
+register struct ea_s *eap;
+{
+ if ((eap->base = regchk()) != AXREG && eap->base != ALREG
+ && eap->base != EAXREG)
+ return FALSE;
+ getsym();
+ if ((eap->size = regsize[eap->base]) > 0x1 && eap->size != defsize)
+ oprefix = 0x66;
+ return TRUE;
+}
+
+/*
+ Get binary ea's in target & source (flipped if direction is set).
+ Put size in source if not already.
+ Initialise direction, segword, bump mcount.
+*/
+
+static void getbinary(void)
+{
+ ++mcount;
+ getea(&target);
+ if (target.indcount == 0x0 && target.base == NOREG)
+ {
+ error(ILL_IMM_MODE);
+ target.base = AXREG;
+ target.size = defsize;
+ }
+ getcomma();
+ getea(&source);
+ if (source.size == 0x0)
+ source.size = target.size;
+ else if (target.size != 0x0 && target.size != source.size)
+ {
+ kgerror(MISMATCHED_SIZE);
+ return;
+ }
+ if (source.indcount == 0x0 && regsegword[target.base] < SEGMOV)
+ direction = 0x0;
+ else if (target.indcount == 0x0 && regsegword[source.base] < SEGMOV)
+ {
+ struct ea_s swap;
+
+ direction = TOREGBIT;
+ swap = source;
+ source = target;
+ target = swap;
+ }
+ else if (target.indcount != 0x0)
+ {
+ kgerror(ILL_IND_TO_IND);
+ return;
+ }
+ else
+ {
+ kgerror(ILL_SEG_REG);
+ return;
+ }
+ buildsegword(&source);
+}
+
+static bool_pt getdxreg(eap)
+register struct ea_s *eap;
+{
+ if ((eap->base = regchk()) != DXREG)
+ return FALSE;
+ getsym();
+ return TRUE;
+}
+
+/* parse effective address */
+
+/*
+ Syntax is restrictive in that displacements must be in the right spots
+ and will not be added up.
+
+ optional size-type prefix, which is
+ BYTE
+ BYTE PTR
+ WORD
+ WORD PTR
+ DWORD
+ DWORD PTR
+ PTR
+ reg
+ segreg
+ [scaled index]
+ where scaled index =
+ indreg
+ indreg*scale
+ indreg+indreg
+ indreg+indreg*scale
+ [scaled index+displ]
+ [scaled index-displ]
+ optional-immediate-prefix displ[scaled index]
+ [displ]
+ optional-imediate-prefix displ
+ (scaled index) -- anachronism
+ optional-imediate-prefix displ(scaled index) -- anachronism
+*/
+
+static void getea(eap)
+register struct ea_s *eap;
+{
+ bool_t leading_displ;
+ bool_t leading_immed;
+ register struct sym_s *symptr;
+
+ leading_immed = leading_displ = lastexp.data = eap->indcount
+ = lastexp.offset = 0x0;
+ eap->index = eap->base = NOREG;
+ eap->scale = 0x1;
+ eap->size = mnsize; /* 0x1 for byte ops, else 0x0 */
+
+ if (sym == IDENT)
+ {
+ if ((symptr = gsymptr)->type & MNREGBIT)
+ {
+ if (symptr->data & SIZEBIT)
+ {
+ getsym();
+ if (symptr->value_reg_or_op.op.opcode == 0x0)
+ eap->indcount = 0x2 - calljmp_kludge;
+ else
+ {
+ if (eap->size != 0x0)
+ {
+ if (eap->size != symptr->value_reg_or_op.op.opcode)
+ error(MISMATCHED_SIZE);
+ }
+ else
+ eap->size = symptr->value_reg_or_op.op.opcode;
+ if (eap->size > 0x1 && eap->size != defsize)
+ oprefix = 0x66;
+ if (sym == IDENT &&
+ (symptr = gsymptr)->type & MNREGBIT &&
+ symptr->data & SIZEBIT &&
+ symptr->value_reg_or_op.op.routine == PTROP)
+ {
+ getsym();
+ eap->indcount = 0x2 - calljmp_kludge;
+ }
+ }
+ }
+ }
+ if( last_pass == 1 )
+ if (!(symptr->type & (LABIT | MACBIT | MNREGBIT | VARBIT)))
+ symptr->data |= FORBIT; /* show seen in advance */
+ }
+ if ((eap->base = regchk()) != NOREG)
+ {
+ getsym();
+ if (eap->indcount != 0x0)
+ {
+ error(ILL_IND_PTR);
+ eap->indcount = 0x0;
+ }
+ if (eap->size != 0x0 && eap->size != regsize[eap->base])
+ error(MISMATCHED_SIZE);
+ if ((eap->size = regsize[eap->base]) > 0x1 && eap->size != defsize)
+ oprefix = 0x66;
+ eap->displ = lastexp;
+ needcpu(eap->size==4?3:0);
+ return;
+ }
+ if (sym != lindirect)
+ {
+ if (sym == IMMEDIATE || sym == STAR)
+ {
+ /* context-sensitive, STAR means signed immediate here */
+ leading_immed = TRUE;
+ getsym();
+ }
+ leading_displ = TRUE;
+ expres();
+ eap->displ = lastexp;
+ }
+ if (sym == lindirect)
+ {
+ getsym();
+ eap->indcount = 0x2 - calljmp_kludge;
+ if ((eap->base = indregchk((reg_pt) NOREG)) != NOREG)
+ {
+ if (eap->indcount == 0x0 && leading_displ)
+ error(IND_REQ);
+ getsym();
+ if (sym == ADDOP)
+ {
+ getsym();
+ if ((eap->index = indregchk(eap->base)) != NOREG)
+ getsym();
+ else
+ {
+ if (eap->indcount == 0x0)
+ error(IND_REQ);
+ if (leading_displ)
+ error(REPEATED_DISPL);
+ expres(); /* this eats ADDOP, SUBOP, MULOP */
+ }
+ }
+ if (sym == STAR)
+ {
+ needcpu(3);
+ /* context-sensitive, STAR means scaled here*/
+ if (eap->index == NOREG && eap->base == ESPREG)
+ {
+ error(INDEX_REG_EXP);
+ eap->base = EAXREG;
+ }
+ getsym();
+ factor();
+ chkabs();
+ if (!(lastexp.data & UNDBIT) && lastexp.offset != 0x1)
+ {
+ if (eap->base <= MAX16BITINDREG ||
+ (lastexp.offset != 0x2 && lastexp.offset != 0x4 &&
+ lastexp.offset != 0x8))
+ error(ILL_SCALE);
+ else
+ {
+ eap->scale = lastexp.offset;
+ if (eap->index == NOREG)
+ {
+ eap->index = eap->base;
+ eap->base = NOREG;
+ }
+ }
+ }
+ lastexp.data = lastexp.offset = 0x0;
+ }
+ if ((sym == ADDOP || sym == SUBOP))
+ {
+ if (eap->indcount == 0x0)
+ error(IND_REQ);
+ if (leading_displ)
+ error(REPEATED_DISPL);
+ expres();
+ }
+ }
+ else
+ {
+ if (leading_displ)
+ error(REPEATED_DISPL);
+ expres();
+ }
+ if (sym != rindirect)
+ error(rindexp);
+ else
+ getsym();
+ }
+ /* RDB */
+ else if (!leading_immed && defsize <= 0x2)
+ eap->indcount = 0x1; /* compatibility kludge */
+ if (!leading_displ)
+ eap->displ = lastexp;
+
+ needcpu(eap->size==4?3:0);
+}
+
+static void getimmed(eap, immed_count)
+struct ea_s *eap;
+count_t immed_count;
+{
+ getea(eap);
+ yesimmed(eap);
+ if (mcount != 0x0)
+ {
+ eap->size = immed_count;
+ buildimm(eap, FALSE);
+ }
+}
+
+static void getindirect(eap)
+register struct ea_s *eap;
+{
+ getea(eap);
+ if (eap->indcount == 0x0)
+ kgerror(IND_REQ);
+}
+
+static void getshift(eap)
+register struct ea_s *eap;
+{
+ getcomma();
+ getea(eap);
+ if (eap->base != CLREG)
+ yesimmed(eap);
+}
+
+/*
+ Check if current symbol is a compatible index register.
+ Generate error if it is a reg but not a compatible index.
+ Return register number (adjusted if necessary to a legal index) or NOREG.
+*/
+
+static reg_pt indregchk(matchreg)
+reg_pt matchreg;
+{
+ reg_pt reg;
+
+ if ((reg = regchk()) != NOREG)
+ {
+ switch (matchreg)
+ {
+ case BPREG:
+ case BXREG:
+ if (reg != DIREG && reg != SIREG)
+ {
+ reg = SIREG;
+ error(INDEX_REG_EXP);
+ }
+ break;
+ case DIREG:
+ case SIREG:
+ if (reg != BPREG && reg != BXREG)
+ {
+ reg = BXREG;
+ error(INDEX_REG_EXP);
+ }
+ break;
+ case NOREG:
+ break;
+ default:
+ if (reg <= MAX16BITINDREG || reg == ESPREG)
+ {
+ reg = EAXREG;
+ error(INDEX_REG_EXP);
+ }
+ break;
+ }
+ if (reg > MAXINDREG && calljmp_kludge == 0x0)
+ {
+ if (matchreg != NOREG)
+ reg = EAXREG;
+ else
+ reg = BXREG;
+ error(INDEX_REG_EXP);
+ }
+ }
+ return reg;
+}
+
+static void kgerror(err_str)
+char * err_str;
+{
+ error(err_str);
+ sprefix = oprefix = aprefix = mcount = 0x0;
+}
+
+static void lbranch(backamount)
+int backamount;
+{
+ mcount += defsize + 0x1;
+ segadj();
+ if (pass2)
+ {
+ reldata();
+ if (!(lastexp.data & (RELBIT | UNDBIT)))
+ {
+ lastexp.offset = lastexp.offset - lc - lcjump;
+ if ( last_pass<2 && backamount != 0x0 &&
+ !(lastexp.data & IMPBIT) &&
+ lastexp.offset + backamount < 0x80 + backamount)
+ warning(SHORTB); /* -0x8? to 0x7F, warning */
+ }
+ }
+}
+
+/* BCC (long branches emulated by short branch over & long jump) */
+
+void mbcc(void)
+{
+ getea(&target);
+ if (target.indcount >= 0x2 || target.base != NOREG)
+ kgerror(REL_REQ);
+ else
+ {
+#ifdef iscpu
+ if (iscpu(3))
+#else
+ if (defsize != 0x2)
+#endif
+ {
+ page = PAGE1_OPCODE;
+ ++mcount;
+ opcode += 0x10;
+ lbranch(0x84);
+ }
+ else
+ {
+ aprefix = opcode ^ 0x1; /* kludged storage for short branch
+ over */
+ oprefix = defsize + 0x1;
+ mcount += 0x2;
+ opcode = JMP_OPCODE;
+ lbranch(0x83);
+ mcount -= 0x2;
+ }
+ }
+}
+
+/* bswap r32 */
+
+void mbswap(void)
+{
+ needcpu(4);
+ ++mcount;
+ Gd(&target);
+ opcode |= rm[target.base];
+}
+
+/* BR, CALL, J, JMP */
+
+void mcall(void)
+{
+ opcode_pt far_diff;
+ bool_t indirect;
+ register struct sym_s *symptr;
+
+ far_diff = 0x0;
+ if (sym == IDENT && (symptr = gsymptr)->type & MNREGBIT &&
+ symptr->data & SIZEBIT )
+ {
+ if(symptr->value_reg_or_op.op.routine == FAROP)
+ {
+ far_diff = 0x8;
+ getsym();
+ }
+ if(symptr->value_reg_or_op.op.routine == WORDOP &&
+ opcode == JMP_SHORT_OPCODE)
+ {
+ opcode = JMP_OPCODE;
+ getsym();
+ }
+ }
+ indirect = FALSE;
+
+ if (asld_compatible && defsize <= 0x2)
+ {
+ calljmp_kludge = 0x2;
+ if (sym == INDIRECT)
+ {
+ calljmp_kludge = 0x0;
+ indirect = TRUE;
+ getsym();
+ }
+ }
+ getea(&target);
+ if (indirect && target.indcount == 0x1)
+ target.indcount = 0x2;
+ calljmp_kludge = 0x0;
+ if (sym == COLON)
+ {
+ int tsize = target.size?target.size:defsize;
+ if (opcode == JMP_SHORT_OPCODE)
+ opcode = JMP_OPCODE;
+ ++mcount;
+ yesimmed(&target);
+ getsym();
+ getea(&source);
+ yesimmed(&source);
+ if (mcount != 0x0)
+ {
+ if (opcode == JMP_OPCODE)
+ opcode = 0xEA;
+ else
+ opcode = 0x9A;
+ lastexp = source.displ;
+ if (!(lastexp.data & (FORBIT | RELBIT | UNDBIT)) &&
+ tsize == 0x2 &&
+ (offset_t) (lastexp.offset + 0x8000L) >= 0x18000L)
+ datatoobig();
+ mcount += tsize;
+ target.size = 0x2;
+ buildimm(&target, FALSE);
+ }
+ }
+ else if (target.indcount >= 0x2 || target.base != NOREG)
+ {
+ ++mcount;
+ notsegorspecreg(&target);
+ if (target.indcount == 0)
+ notbytesize(&target);
+ if (mcount != 0x0)
+ {
+ if (opcode == JMP_SHORT_OPCODE)
+ opcode = JMP_OPCODE;
+ buildea(&target);
+ if (opcode == JMP_OPCODE)
+ opcode = 0x20;
+ else
+ opcode = 0x10;
+ postb |= opcode + far_diff;
+ opcode = 0xFF;
+ }
+ }
+ else if (opcode == JMP_SHORT_OPCODE)
+ {
+ if (jumps_long &&
+ ((pass!=0 && !is8bitsignedoffset(lastexp.offset - lc - 2)) ||
+ (last_pass==1)))
+ {
+ opcode = JMP_OPCODE;
+ lbranch(0x83);
+ }
+ else
+ {
+ lastexp = target.displ;
+ if (lastexp.data & IMPBIT)
+ {
+ error(NONIMPREQ);
+ lastexp.data = FORBIT | UNDBIT;
+ }
+ mshort2();
+ }
+ }
+ else
+ lbranch(opcode == JMP_OPCODE ? 0x83 : 0x0);
+}
+
+/* CALLI, JMPI */
+
+void mcalli(void)
+{
+ bool_t indirect;
+
+ ++mcount;
+ indirect = FALSE;
+ if (sym == INDIRECT)
+ {
+ getsym();
+ indirect = TRUE;
+ }
+ getea(&target);
+ if (target.indcount >= 0x2 || target.base != NOREG)
+ indirect = TRUE;
+ if (indirect)
+ {
+ buildea(&target);
+ if (opcode == 0xEA)
+ opcode = 0x28;
+ else
+ opcode = 0x18;
+ postb |= opcode;
+ opcode = 0xFF;
+ }
+ else
+ {
+ int tsize = target.size?target.size:defsize;
+ getcomma();
+ getea(&source);
+ yesimmed(&source);
+ if (mcount != 0x0)
+ {
+ lastexp = target.displ;
+ if (!(lastexp.data & (FORBIT | RELBIT | UNDBIT)) &&
+ tsize == 0x2 &&
+ (offset_t) (lastexp.offset + 0x8000L) >= 0x18000L)
+ {
+ tsize=4;
+ if( tsize != defsize ) oprefix = 0x66;
+ /* datatoobig(); */
+ }
+ needcpu(tsize==4?3:0);
+ mcount += tsize;
+ source.size = 0x2;
+ buildimm(&source, FALSE);
+ }
+ }
+}
+
+/* DIV, IDIV, MUL */
+
+void mdivmul(void)
+{
+ if (getaccumreg(&source))
+ {
+ ++mcount;
+ getcomma();
+ Ex(&target);
+ yes_samesize();
+ buildunary(0xF6 | regsegword[source.base]);
+ }
+ else
+ mnegnot();
+}
+
+/* ENTER */
+
+void menter(void)
+{
+ ++mcount;
+ getimmed(&target, 0x2);
+ getcomma();
+ getimmed(&source, 0x1);
+ if (mcount != 0x0)
+ {
+ mcount += 2;
+ lastexp = target.displ; /* getimmed(&source) wiped it out */
+ }
+ needcpu(1);
+}
+
+/* arpl r/m16,r16 (Intel manual opcode chart wrongly says EwRw) */
+
+void mEwGw(void)
+{
+ ++mcount;
+ Ew(&target);
+ getcomma();
+ Gw(&source);
+ oprefix = 0x0;
+ buildregular();
+}
+
+/* [cmpxchg xadd] [r/m8,r8 r/m16,r16, r/m32,r32] */
+
+void mExGx(void)
+{
+ ++mcount;
+ Ex(&target);
+ getcomma();
+ Gx(&source);
+ yes_samesize();
+ opcode |= segword;
+ buildregular();
+}
+
+void mf_inher(void)
+{
+ mcount += 0x2;
+ postb = REG_MOD | (opcode & ~REG_MOD);
+ opcode = ESCAPE_OPCODE_BASE | (opcode >> 0x6);
+ if (opcode == ESCAPE_OPCODE_BASE)
+ opcode = ESCAPE_OPCODE_BASE | 0x6; /* fix up encoding of fcompp */
+}
+
+/* [fldenv fnsave fnstenv frstor] mem */
+
+void mf_m(void)
+{
+ ++mcount;
+ getindirect(&source);
+ if (source.size != 0x0)
+ kgerror(ILL_SIZE);
+ buildfloat();
+}
+
+/* [fldcw fnstcw] mem2i */
+
+void mf_m2(void)
+{
+ ++mcount;
+ getindirect(&source);
+ if (source.size != 0x0 && source.size != 0x2)
+ kgerror(ILL_SIZE);
+ buildfloat();
+}
+
+/* fnstsw [mem2i ax] */
+
+void mf_m2_ax(void)
+{
+ if (getaccumreg(&target))
+ {
+ if (target.base != AXREG)
+ kgerror(ILLREG);
+ else
+ {
+ opcode = 0x74;
+ target.base = ST0REG; /* fake, really ax */
+ buildfreg();
+ }
+ }
+ else
+ mf_m2();
+}
+
+/* [fiadd ficom ficomp fidiv fidivr fimul fist fisub fisubr] [mem2i mem4i] */
+
+void mf_m2_m4(void)
+{
+ ++mcount;
+ getindirect(&source);
+ if (source.size == 0x0)
+ kgerror(SIZE_UNK);
+ else if (source.size == 0x2)
+ opcode |= 0x40;
+ else if (source.size != 0x4)
+ kgerror(ILL_SIZE);
+ buildfloat();
+}
+
+/* [fild fistp] [mem2i mem4i mem8i] */
+
+void mf_m2_m4_m8(void)
+{
+ ++mcount;
+ getindirect(&source);
+ if (source.size == 0x0)
+ kgerror(SIZE_UNK);
+ else if (source.size == 0x2)
+ opcode |= 0x40;
+ else if (source.size == 0x8)
+ opcode |= 0x45; /* low bits 0 -> 5 and 3 -> 7 */
+ else if (source.size != 0x4)
+ kgerror(ILL_SIZE);
+ buildfloat();
+}
+
+/* [fcom fcomp] [mem4r mem8r optional-st(i)] */
+
+void mf_m4_m8_optst(void)
+{
+ if (sym == EOLSYM)
+ {
+ target.base = ST1REG;
+ buildfreg();
+ }
+ else
+ mf_m4_m8_st();
+}
+
+/* [fadd fdiv fdivr fmul fsub fsubr] [mem4r mem8r st,st(i) st(i),st] */
+
+void mf_m4_m8_stst(void)
+{
+ target.base = fpregchk();
+ if (target.base != NOREG)
+ {
+ getcomma();
+ source.base = fpregchk();
+ if (source.base == NOREG)
+ {
+ error(FP_REG_REQ);
+ source.base = ST0REG;
+ }
+ if (target.base == ST0REG)
+ target.base = source.base;
+ else
+ {
+ if (source.base != ST0REG)
+ error(ILL_FP_REG_PAIR);
+ opcode |= 0x40;
+ if ((opcode & 0x07) >= 0x4)
+ opcode ^= 0x01; /* weird swap of fdiv/fdivr, fsub/fsubr */
+ }
+ buildfreg();
+ }
+ else
+ {
+ ++mcount;
+ getindirect(&source);
+ if (source.size == 0x0)
+ kgerror(SIZE_UNK);
+ else if (source.size == 0x8)
+ opcode |= 0x40;
+ else if (source.size != 0x4)
+ kgerror(ILL_SIZE);
+ buildfloat();
+ }
+}
+
+/* fst [mem4r mem8r st(i)] */
+
+void mf_m4_m8_st(void)
+{
+ target.base = fpregchk();
+ if (target.base != NOREG)
+ {
+ if (opcode == FST_ENCODED)
+ opcode |= 0x40;
+ buildfreg();
+ }
+ else
+ {
+ ++mcount;
+ getindirect(&source);
+ if (source.size == 0x0)
+ kgerror(SIZE_UNK);
+ else if (source.size == 0x8)
+ opcode |= 0x40;
+ else if (source.size != 0x4)
+ kgerror(ILL_SIZE);
+ buildfloat();
+ }
+}
+
+/* [fld fstp] [mem4r mem8r mem10r st(i)] */
+
+void mf_m4_m8_m10_st(void)
+{
+ target.base = fpregchk();
+ if (target.base != NOREG)
+ {
+ if (opcode == FSTP_ENCODED)
+ opcode |= 0x40;
+ buildfreg();
+ }
+ else
+ {
+ ++mcount;
+ getindirect(&source);
+ if (source.size == 0x0)
+ kgerror(SIZE_UNK);
+ else if (source.size == 0x8)
+ opcode |= 0x40;
+ else if (source.size == 0xA)
+ opcode |= 0x25; /* low bits 0 -> 5 and 3 -> 7 */
+ else if (source.size != 0x4)
+ kgerror(ILL_SIZE);
+ buildfloat();
+ }
+}
+
+/* [fbld fbstp] mem10r */
+
+void mf_m10(void)
+{
+ ++mcount;
+ getindirect(&source);
+ if (source.size != 0xA)
+ kgerror(ILL_SIZE);
+ buildfloat();
+}
+
+/* ffree st(i) */
+
+void mf_st(void)
+{
+ target.base = fpregchk();
+ if (target.base == NOREG)
+ kgerror(FP_REG_REQ);
+ buildfreg();
+}
+
+/* [fucom fucomp fxch] optional-st(i) */
+
+void mf_optst(void)
+{
+ if (sym == EOLSYM)
+ {
+ target.base = ST1REG;
+ buildfreg();
+ }
+ else
+ mf_st();
+}
+
+/* [faddp fdivp fdivrp fmulp fsubp fsubrp] st(i),st */
+
+void mf_stst(void)
+{
+ target.base = fpregchk();
+ if (target.base == NOREG)
+ {
+ kgerror(FP_REG_REQ);
+ return;
+ }
+ getcomma();
+ source.base = fpregchk();
+ if (source.base == NOREG)
+ {
+ kgerror(FP_REG_REQ);
+ return;
+ }
+ if (source.base != ST0REG)
+ {
+ kgerror(ILL_FP_REG);
+ return;
+ }
+ buildfreg();
+}
+
+void mf_w_inher(void)
+{
+ sprefix = WAIT_OPCODE;
+ mf_inher();
+}
+
+/* [fsave fstenv] mem */
+
+void mf_w_m(void)
+{
+ sprefix = WAIT_OPCODE;
+ mf_m();
+}
+
+/* fstcw mem2i */
+
+void mf_w_m2(void)
+{
+ sprefix = WAIT_OPCODE;
+ mf_m2();
+}
+
+/* fstsw [mem2i ax] */
+
+void mf_w_m2_ax(void)
+{
+ sprefix = WAIT_OPCODE;
+ mf_m2_ax();
+}
+
+/* ADC, ADD, AND, CMP, OR, SBB, SUB, XOR */
+
+void mgroup1(void)
+{
+ getbinary();
+ notsegorspecreg(&source);
+ if (mcount != 0x0)
+ {
+ if (source.base == NOREG)
+ {
+ if (target.indcount == 0x0 && (target.base == ALREG ||
+ target.base == AXREG ||
+ (target.base == EAXREG &&
+ (source.displ.data & (FORBIT | RELBIT | UNDBIT) ||
+ !is8bitsignedoffset(source.displ.offset)))))
+ {
+ opcode |= 0x04 | segword;
+ buildimm(&source, FALSE);
+ }
+ else
+ {
+ buildunary(0x80 | segword);
+ buildimm(&source, TRUE);
+ }
+ }
+ else
+ {
+ opcode |= direction | segword;
+ buildregular();
+ }
+ }
+}
+
+/* RCL, RCR, ROL, ROR, SAL, SAR, SHL, SHR */
+
+void mgroup2(void)
+{
+ ++mcount;
+ Ex(&target);
+ buildsegword(&target);
+ getshift(&source);
+ if (mcount != 0x0)
+ {
+ buildunary(0xD0 | segword);
+ if (source.base == CLREG)
+ opcode |= 0x2;
+ else if (source.displ.offset != 0x1)
+ {
+ needcpu(1);
+ opcode -= 0x10;
+ source.size = 0x1;
+ buildimm(&source, FALSE);
+ }
+ }
+}
+
+/* LLDT, LTR, SLDT, STR, VERR, VERW */
+
+void mgroup6(void)
+{
+ needcpu(2);
+ ++mcount;
+ Ew(&target);
+ oprefix = 0x0;
+ buildunary(0x0);
+}
+
+/* INVLPG, LGDT, LIDT, LMSW, SGDT, SIDT, SMSW */
+
+void mgroup7(void)
+{
+ needcpu(2); /* I think INVLPG is actually 386 */
+ ++mcount;
+ if (opcode == 0x20 || opcode == 0x30)
+ {
+ Ew(&target);
+ oprefix = 0x0;
+ }
+ else
+ {
+ getindirect(&target);
+ oprefix = 0x0;
+ if (target.size != 0x0 && target.size != 0x6)
+ error(MISMATCHED_SIZE); /* XXX - size 6 wrong for INVLPG? */
+ }
+ buildunary(0x1);
+}
+
+/* BT, BTR, BTS, BTC */
+
+void mgroup8(void)
+{
+ needcpu(3);
+ ++mcount;
+ Ev(&target);
+ getcomma();
+ /* Gv or Ib */
+ getea(&source);
+ notindirect(&source);
+ notsegorspecreg(&source);
+ if (mcount != 0x0)
+ {
+ if (source.base == NOREG)
+ {
+ buildunary(0xBA);
+ source.size = 0x1;
+ buildimm(&source, TRUE);
+ }
+ else
+ {
+ yes_samesize();
+ opcode += 0x83;
+ buildregular();
+ }
+ }
+}
+
+/* BSF, BSR, LAR, LSL (Intel manual opcode chart wrongly says GvEw for L*) */
+
+void mGvEv(void)
+{
+ needcpu(2);
+ ++mcount;
+ Gv(&source);
+ getcomma();
+ Ev(&target);
+ yes_samesize();
+ buildregular();
+}
+
+/* bound [r16,m16&16 r32,m32&32] */
+
+void mGvMa(void)
+{
+ ++mcount;
+ Gv(&source);
+ getcomma();
+ getindirect(&target);
+ yes_samesize();
+ buildregular();
+}
+
+/* LDS, LES, LFS, LGS, LSS */
+
+void mGvMp(void)
+{
+ ++mcount;
+ Gv(&source);
+ getcomma();
+ getindirect(&target);
+ if (target.size != 0x0 && target.size != 0x2 + source.size)
+ error(MISMATCHED_SIZE);
+ buildregular();
+}
+
+/* IMUL */
+
+void mimul(void)
+{
+ ++mcount;
+ Ex(&target);
+ if (sym != COMMA)
+ {
+ buildsegword(&target);
+ buildunary(0xF6 | segword);
+ return;
+ }
+ getcomma();
+ notindirect(&target);
+ source = target; /* direction is swapped */
+ getea(&target);
+ notsegorspecreg(&target);
+ yes_samesize();
+ if (sym != COMMA && (target.indcount != 0x0 || target.base != NOREG))
+ {
+ needcpu(3);
+ page = PAGE1_OPCODE;
+ ++mcount;
+ opcode = 0xAF;
+ buildregular();
+ }
+ else
+ {
+ if (sym == COMMA)
+ {
+ getsym();
+ getea(&source2);
+ yesimmed(&source2);
+ }
+ else
+ {
+ source2 = target;
+ target = source;
+ }
+ source2.size = target.size;
+ if (is8bitsignedoffset(source2.displ.offset))
+ {
+ source2.size = 0x1;
+ opcode = 0x6B;
+ }
+ else
+ {
+ source2.size = target.size;
+ opcode = 0x69;
+ }
+ buildregular();
+ if (mcount != 0x0)
+ buildimm(&source2, FALSE);
+ }
+}
+
+/* IN */
+
+void min(void)
+{
+ ++mcount;
+ if (opcode & WORDBIT) /* inw; ind not supported */
+ mnsize = 0x2;
+ if (sym == EOLSYM && mnsize != 0x0)
+ target.size = mnsize;
+ else
+ {
+ if (getaccumreg(&target))
+ {
+ if (mnsize != 0x0 && regsize[target.base] != mnsize)
+ error(MISMATCHED_SIZE);
+ getcomma();
+ }
+ else
+ target.size = regsize[target.base = mnsize < 0x2 ? ALREG : AXREG];
+ opcode |= regsegword[target.base];
+ if (!getdxreg(&source))
+ {
+ getimmed(&source, 0x1);
+ opcode -= 0x8;
+ }
+ }
+ if (target.size > 0x1 && target.size != defsize)
+ oprefix = 0x66;
+}
+
+/* DEC, INC */
+
+void mincdec(void)
+{
+ ++mcount;
+ Ex(&target);
+ buildsegword(&target);
+ if (target.indcount == 0x0 && segword == WORDBIT)
+ opcode |= 0x40 | rm[target.base];
+ else
+ buildunary(0xFE | segword);
+}
+
+/* CBW, CWD, CMPSW, INSW, IRET, LODSW, POPA, POPF, PUSHA, PUSHF */
+/* MOVSW, OUTSW, SCASW, STOSW */
+
+void minher16(void)
+{
+ minher();
+ if (defsize != 0x2)
+ oprefix = 0x66;
+}
+
+/* CWDE, CDQ, CMPSD, INSD, IRETD, LODSD, POPAD, POPFD, PUSHAD, PUSHFD */
+/* MOVSD, OUTSD, SCASD, STOSD */
+
+void minher32(void)
+{
+ minher();
+ if (defsize != 0x4)
+ oprefix = 0x66;
+ needcpu(3);
+}
+
+/* AAD, AAM */
+
+void minhera(void)
+{
+ ++mcount;
+ if (sym == EOLSYM)
+ {
+ target.displ.offset = 0xA;
+ target.size = 0x1;
+ buildimm(&target, FALSE);
+ }
+ else
+ getimmed(&target, 0x1);
+}
+
+/* INT */
+
+void mint(void)
+{
+ ++mcount;
+ getimmed(&target, 0x1);
+ if (!(immadr.data & (FORBIT | RELBIT | UNDBIT)) &&
+ (opcode_t) immadr.offset == 0x3)
+ {
+ immcount = 0x0;
+ opcode = 0xCC;
+ }
+}
+
+/* JCC */
+
+void mjcc(void)
+{
+ /* First look for j* near */
+ if (sym == IDENT &&
+ gsymptr->type & MNREGBIT &&
+ gsymptr->data & SIZEBIT &&
+ gsymptr->value_reg_or_op.op.routine == WORDOP &&
+ opcode < 0x80)
+ {
+ getsym();
+ getea(&target);
+ if (target.indcount >= 0x2 || target.base != NOREG)
+ kgerror(REL_REQ);
+ else
+ {
+ needcpu(3);
+ page = PAGE1_OPCODE;
+ ++mcount;
+ opcode += 0x10;
+ lbranch(0x84);
+ }
+ }
+ else if (!jumps_long || opcode > 0x80) /* above 0x80 means loop, not long */
+ mshort();
+ else /* mbcc */
+ {
+ getea(&target);
+ lastexp = target.displ;
+
+ if ( (pass!=0 && !is8bitsignedoffset(lastexp.offset - lc - 2)) ||
+ last_pass==1)
+ {
+ if (target.indcount >= 0x2 || target.base != NOREG)
+ kgerror(REL_REQ);
+
+ aprefix = opcode ^ 0x1; /* kludged storage for short branch
+ over */
+ oprefix = defsize + 0x1;
+ mcount += 0x2;
+ opcode = JMP_OPCODE;
+ lbranch(0x83);
+ mcount -= 0x2;
+ }
+ else
+ {
+ /* 8 bit */
+ if (lastexp.data & IMPBIT)
+ {
+ error(NONIMPREQ);
+ lastexp.data = FORBIT | UNDBIT;
+ }
+ mshort2();
+ }
+ }
+}
+
+/* JCXZ, JECXZ */
+
+void mjcxz(void)
+{
+ if (opcode != defsize)
+ {
+ aprefix = 0x67;
+ ++mcount; /* quick fix - mshort() needs to know */
+ }
+ opcode = 0xE3;
+ mshort();
+ if (aprefix != 0x0)
+ --mcount; /* quick fix - main routine bumps it again */
+}
+
+/* LEA */
+
+void mlea(void)
+{
+ Gv(&source); /* back to front */
+ getcomma();
+ ++mcount;
+ getindirect(&target);
+ yes_samesize();
+ buildregular();
+}
+
+/* MOV */
+
+void mmov(void)
+{
+ getbinary();
+ if (segword >= SEGMOV)
+ {
+ oprefix = 0x0;
+ notimmed(&target); /* target is actually the source */
+ if (segword > SEGMOV) /* special reg */
+ notindirect(&target);
+ }
+ if (mcount != 0x0)
+ {
+ if (target.base == NOREG && target.index == NOREG &&
+ (source.base == ALREG || source.base == AXREG ||
+ source.base == EAXREG))
+ {
+ opcode = 0xA0 | (direction ^ TOREGBIT) | segword;
+ lastexp = target.displ;
+ if ((source.size = displsize(&target)) != defsize)
+ aprefix = 0x67;
+ mcount += source.size;
+ needcpu(source.size==4?3:0);
+ }
+ else if (source.base == NOREG)
+ {
+ if (target.indcount == 0x0)
+ opcode = 0xB0 | (segword << 0x3) | rm[target.base];
+ else
+ {
+ buildea(&target);
+ opcode = 0xC6 | segword;
+ }
+ buildimm(&source, FALSE);
+ }
+ else
+ {
+ if (isspecreg(source.base))
+ {
+ needcpu(3);
+ page = PAGE1_OPCODE;
+ ++mcount;
+ opcode = 0x0;
+ }
+ opcode |= direction | segword;
+ buildregular();
+ }
+ }
+}
+
+/* MOVSX, MOVZX */
+
+void mmovx(void)
+{
+ ++mcount;
+ Gv(&source);
+ getcomma();
+ Ex(&target);
+ if (target.size == 0x0)
+ kgerror(SIZE_UNK);
+ if (target.size > 0x2)
+ kgerror(ILL_SIZE);
+ oprefix = 0x0;
+ if (source.size != defsize)
+ oprefix = 0x66;
+ buildsegword(&target);
+ opcode |= segword;
+ buildregular();
+}
+
+/* NEG, NOT */
+
+void mnegnot(void)
+{
+ ++mcount;
+ Ex(&target);
+ buildsegword(&target);
+ buildunary(0xF6 | segword);
+}
+
+/* OUT */
+
+void mout(void)
+{
+ ++mcount;
+ if (opcode & WORDBIT) /* outw; outd not supported */
+ mnsize = 0x2;
+ if (sym == EOLSYM && mnsize != 0x0)
+ source.size = mnsize;
+ else
+ {
+ if (!getdxreg(&target))
+ {
+ getimmed(&target, 0x1);
+ opcode -= 0x8;
+ }
+ if (sym == COMMA)
+ {
+ getsym();
+ if (!getaccumreg(&source))
+ kgerror(AL_AX_EAX_EXP);
+ else if (mnsize != 0x0 && regsize[source.base] != mnsize)
+ error(MISMATCHED_SIZE);
+ }
+ else
+ source.size = regsize[source.base = mnsize < 0x2 ? ALREG : AXREG];
+ opcode |= regsegword[source.base];
+ }
+ if (source.size > 0x1 && source.size != defsize)
+ oprefix = 0x66;
+}
+
+/* POP, PUSH */
+
+void mpushpop(void)
+{
+ opcode_t oldopcode;
+
+ ++mcount;
+ getea(&target);
+ buildsegword(&target);
+ notbytesize(&target);
+ if ((oldopcode = opcode) == POP_OPCODE)
+ {
+ notimmed(&target);
+ if (target.base == CSREG)
+ kgerror(ILL_SEG_REG);
+ }
+ if (mcount != 0x0)
+ {
+ if (target.indcount == 0x0)
+ {
+ if (segword == SEGMOV)
+ {
+ switch (target.base)
+ {
+ case CSREG:
+ opcode = 0x0E;
+ break;
+ case DSREG:
+ opcode = 0x1E;
+ break;
+ case ESREG:
+ opcode = 0x06;
+ break;
+ case SSREG:
+ opcode = 0x16;
+ break;
+ case FSREG:
+ opcode = 0xA0;
+ page = PAGE1_OPCODE;
+ ++mcount;
+ break;
+ case GSREG:
+ opcode = 0xA8;
+ page = PAGE1_OPCODE;
+ ++mcount;
+ break;
+ }
+ if (oldopcode == POP_OPCODE)
+ ++opcode;
+ }
+ else if (target.base != NOREG)
+ {
+ opcode = 0x50 | rm[target.base];
+ if (oldopcode == POP_OPCODE)
+ opcode |= 0x8;
+ }
+ else
+ {
+ needcpu(1); /* On 8086 PUSH does not allow immediate */
+ opcode = 0x68;
+ if (oldopcode == POP_OPCODE)
+ ++opcode;
+ buildimm(&target, TRUE);
+ }
+ }
+ else
+ {
+ buildea(&target);
+ if (oldopcode == PUSH_OPCODE)
+ postb |= 0x6 << REG_SHIFT;
+ }
+ }
+}
+
+/* RET, RETF */
+
+void mret(void)
+{
+ ++mcount;
+ if (sym != EOLSYM)
+ {
+ --opcode;
+ getimmed(&target, 0x2);
+ }
+}
+
+/* SEG CS/DS/ES/FS/GS/SS */
+
+void mseg(void)
+{
+ reg_pt reg;
+
+ if (regsegword[reg = regchk()] != SEGMOV)
+ error(SEG_REG_REQ);
+ else
+ {
+ getsym();
+ ++mcount;
+ opcode = (segoverride - CSREG)[reg];
+ }
+}
+
+/* SETCC */
+
+void msetcc(void)
+{
+ ++mcount;
+ Eb(&target);
+ if (mcount != 0x0)
+ buildea(&target);
+}
+
+/* SHLD, SHRD */
+
+void mshdouble(void)
+{
+ needcpu(3);
+ ++mcount;
+ Ev(&target);
+ getcomma();
+ Gv(&source);
+ yes_samesize();
+ buildregular();
+ getshift(&source2);
+ lastexp = target.displ; /* getshift() wiped it out */
+ if (mcount != 0x0)
+ {
+ if (source2.base == CLREG)
+ opcode |= 0x1;
+ else
+ {
+ source2.size = 0x1;
+ buildimm(&source2, FALSE);
+ }
+ }
+}
+
+/*
+ TEST
+ Similar to the regular group1 operators.
+ It does not allow the sign extended immediate byte forms
+ and does not use the relevant direction bit.
+*/
+
+void mtest(void)
+{
+ getbinary();
+ notsegorspecreg(&source);
+ if (source.base == NOREG)
+ {
+ if (mcount != 0x0)
+ {
+ if (target.indcount == 0x0
+ && (target.base == ALREG || target.base == AXREG
+ || target.base == EAXREG))
+ opcode = 0xA8 | segword;
+ else
+ {
+ buildea(&target);
+ opcode = 0xF6 | segword;
+ }
+ }
+ buildimm(&source, FALSE);
+ }
+ else
+ {
+ opcode |= segword;
+ buildregular();
+ }
+}
+
+/*
+ XCHG
+ Similar to the regular group1 operators.
+ It does not allow any of the immediate forms
+ and does not use the irrelevant direction bit.
+*/
+
+void mxchg(void)
+{
+ getbinary();
+ notimmed(&source);
+ notsegorspecreg(&source);
+ if (target.indcount == 0x0)
+ {
+ if (target.base == AXREG || target.base == EAXREG)
+ {
+ opcode = 0x90 + rm[source.base];
+ return;
+ }
+ if (source.base == AXREG || source.base == EAXREG)
+ {
+ opcode = 0x90 + rm[target.base];
+ return;
+ }
+ }
+ opcode |= segword;
+ buildregular();
+}
+
+static void notbytesize(eap)
+register struct ea_s *eap;
+{
+ if (eap->size == 0x1)
+ kgerror(ILL_SIZE);
+}
+
+static void notimmed(eap)
+register struct ea_s *eap;
+{
+ if (eap->indcount == 0x0 && eap->base == NOREG)
+ kgerror(ILL_IMM_MODE);
+}
+
+static void notindirect(eap)
+register struct ea_s *eap;
+{
+ if (eap->indcount != 0x0)
+ kgerror(ILL_IND);
+}
+
+static void notsegorspecreg(eap)
+register struct ea_s *eap;
+{
+ if (regsegword[eap->base] >= SEGMOV)
+ kgerror(ILLREG);
+}
+
+static void yesimmed(eap)
+register struct ea_s *eap;
+{
+ if (eap->indcount == 0x1)
+ eap->indcount = 0x0;
+ if (eap->indcount != 0x0 || eap->base != NOREG)
+ kgerror(IMM_REQ);
+}
+
+static void yes_samesize(void)
+{
+ if (target.size == 0x0)
+ target.size = source.size;
+ else if (source.size != 0x0 && target.size != source.size)
+ kgerror(MISMATCHED_SIZE);
+}
+
+#endif /* I80386 */
+
+#ifdef MC6809
+
+/* 6809 opcode constants */
+
+/* bits for indexed addressing */
+
+#define INDIRECTBIT 0x10
+#define INDEXBIT 0x80 /* except 5 bit offset */
+#define PCRELBIT 0x04 /* PC relative (in certain cases) */
+#define RRBITS 0x60 /* register select bits */
+
+static opcode_t rrindex[] = /* register and index bits for indexed adr */
+{
+ 0x60 | INDEXBIT, /* S */
+ 0x40 | INDEXBIT, /* U */
+ 0x00 | INDEXBIT, /* X */
+ 0x20 | INDEXBIT, /* Y */
+ PCRELBIT | INDEXBIT, /* PC */
+};
+
+static opcode_t pushpull[] = /* push/pull codes */
+{
+ 0x40, /* S */
+ 0x40, /* U */
+ 0x10, /* X */
+ 0x20, /* Y */
+ 0x80, /* PC */
+ 0x02, /* A */
+ 0x04, /* B */
+ 0x01, /* CC */
+ 0x08, /* DP */
+ 0x06, /* D */
+};
+
+static opcode_t tfrexg1[] = /* transfer/exchange codes for source reg */
+{
+ 0x40, /* S */
+ 0x30, /* U */
+ 0x10, /* X */
+ 0x20, /* Y */
+ 0x50, /* PC */
+ 0x80, /* A */
+ 0x90, /* B */
+ 0xA0, /* CC */
+ 0xB0, /* DP */
+ 0x00, /* D */
+};
+
+static opcode_t tfrexg2[] = /* transfer/exchange codes for target reg */
+{
+ 0x04, /* S */
+ 0x03, /* U */
+ 0x01, /* X */
+ 0x02, /* Y */
+ 0x05, /* PC */
+ 0x08, /* A */
+ 0x09, /* B */
+ 0x0A, /* CC */
+ 0x0B, /* DP */
+ 0x00, /* D */
+};
+
+static void checkpostinc(void);
+static void doaltind(void);
+static void do1altind(void);
+static void fixupind(void);
+static void getindexnopost(void);
+static void inderror(char * err_str);
+static reg_pt indreg(reg_pt maxindex);
+static void predec1(void);
+static void sustack(reg_pt stackreg);
+
+void checkpostinc(void)
+{
+ if (sym == ADDOP)
+ {
+ if (postb & INDIRECTBIT)
+ inderror(ILLMOD); /* single-inc indirect illegal */
+ else
+ {
+ lastexp.offset &= 0xFF00; /* for printing if postbyte is 0: ,X+ */
+ getsym();
+ }
+ }
+ else if (sym == POSTINCOP)
+ {
+ postb |= 0x1;
+ getsym();
+ }
+ else
+ postb |= 0x4;
+ fixupind();
+}
+
+/* common code for all-mode ops, alterable-mode ops, indexed ops */
+
+void doaltind(void)
+{
+ mcount += 0x2;
+ if (sym == LBRACKET)
+ {
+ postb = INDIRECTBIT;
+ getsym();
+ do1altind();
+ if (sym != RBRACKET)
+ error(RBEXP);
+ }
+ else
+ do1altind();
+}
+
+void do1altind(void)
+{
+ bool_t byteflag; /* set if direct or short indexed adr forced */
+ char *oldlineptr;
+ char *oldsymname;
+ reg_pt reg;
+ bool_t wordflag; /* set if extended or long indexed adr forced*/
+
+ if ((reg = regchk()) != NOREG)
+ {
+ switch (reg)
+ {
+ case AREG:
+ postb |= 0x86;
+ break;
+ case BREG:
+ postb |= 0x85;
+ break;
+ case DREG:
+ postb |= 0x8B;
+ break;
+ default:
+ if (indreg(MAXINDREG) != NOREG)
+ checkpostinc();
+ return;
+ }
+ getsym();
+ if (sym != COMMA)
+ inderror(COMEXP);
+ else
+ getindexnopost();
+ return;
+ }
+ else if (sym == SUBOP) /* could be -R or - in expression */
+ {
+ oldlineptr = lineptr; /* save state */
+ oldsymname = symname;
+ getsym();
+ reg = regchk();
+ lineptr = oldlineptr;
+ symname = oldsymname;
+ if (reg != NOREG)
+ {
+ predec1(); /* it's -R */
+ return;
+ }
+ sym = SUBOP;
+ }
+ else if (sym == COMMA)
+ {
+ postb |= INDEXBIT;
+ getsym();
+ if (sym == SUBOP)
+ {
+ predec1();
+ return;
+ }
+ else if (sym != PREDECOP)
+ {
+ if (indreg(MAXINDREG) != NOREG)
+ checkpostinc();
+ return;
+ }
+ }
+ if (sym == PREDECOP)
+ {
+ postb |= 0x83;
+ getindexnopost();
+ return;
+ }
+
+ /* should have expression */
+
+ wordflag = byteflag = FALSE;
+ if (sym == LESSTHAN)
+ {
+ /* context-sensitive, LESSTHAN means byte-sized here */
+ byteflag = TRUE;
+ getsym();
+ }
+ else if (sym == GREATERTHAN)
+ {
+ /* context-sensitive, GREATERTHAN means word-sized here */
+ wordflag = TRUE;
+ getsym();
+ }
+ expres();
+ if (sym == COMMA)
+ { /* offset from register */
+ getsym();
+ if ((reg = indreg(PCREG)) == NOREG)
+ return;
+ postb |= 0x8; /* default 8 bit offset */
+ if (reg == PCREG)
+ {
+ reldata();
+ if (!(lastexp.data & (RELBIT | UNDBIT)))
+ {
+ lastexp.offset = lastexp.offset - lc;
+ if (page != 0x0)
+ lastexp.offset -= 0x4; /* extra for instruction */
+ else
+ lastexp.offset -= 0x3; /* 3 byte instruction
+ assuming 8 bit offset */
+ }
+ }
+ if (byteflag)
+ {
+ if (!(lastexp.data & (RELBIT | UNDBIT)) &&
+ !is8bitsignedoffset(lastexp.offset))
+ error(ABOUNDS); /* forced short form is impossible */
+ ++mcount;
+ }
+ else if (wordflag || lastexp.data & (FORBIT | RELBIT | UNDBIT) ||
+ !is8bitsignedoffset(lastexp.offset))
+ { /* 16 bit offset */
+ if (postb & PCRELBIT && !(lastexp.data & RELBIT))
+ --lastexp.offset; /* instruction 1 longer than already
+ allowed */
+ postb |= 0x1;
+ mcount += 0x2;
+ }
+ else if (!(postb & PCRELBIT) &&
+ (offset_t) (lastexp.offset + 0x10) < 0x20 &&
+ !(postb & INDIRECTBIT && lastexp.offset != 0x0))
+ { /* 5 bit offset */
+ postb &= RRBITS | INDIRECTBIT;
+ if (lastexp.offset == 0x0)
+ postb |= 0x84; /* index with zero offset */
+ else
+ postb |= (lastexp.offset & 0x1F);
+ }
+ else /* 8 bit offset */
+ ++mcount;
+ fixupind();
+ }
+ else if (postb & INDIRECTBIT)
+ { /* extended indirect */
+ postb = 0x9F;
+ mcount += 0x2;
+ fixupind();
+ }
+ else if (postb & INDEXBIT)
+ inderror(ILLMOD); /* e.g. LEAX $10 */
+ else
+ {
+ if (byteflag || (!wordflag && !(lastexp.data & (FORBIT | RELBIT)) &&
+ (lastexp.offset >> 0x8) == dirpag))
+ { /* direct addressing */
+ if (opcode >= 0x80)
+ opcode |= 0x10;
+ }
+ else /* extended addressing */
+ {
+ if (opcode < 0x80)
+ opcode |= 0x70;
+ else
+ opcode |= 0x30;
+ ++mcount;
+ if (pass2 && (opcode == JSR_OPCODE || opcode == JMP_OPCODE) &&
+ !(lastexp.data & IMPBIT) &&
+ lastexp.offset + (0x81 - 0x3) < 0x101)
+ /* JSR or JMP could be done with BSR or BRA */
+ warning(SHORTB);
+ }
+ }
+}
+
+void fixupind(void)
+{
+ if ((opcode & 0x30) == 0x0) /* change all but LEA opcodes */
+ {
+ if (opcode < 0x80)
+ opcode |= 0x60;
+ else
+ opcode |= 0x20;
+ }
+}
+
+void getindexnopost(void)
+{
+ getsym();
+ if (indreg(MAXINDREG) != NOREG)
+ fixupind();
+}
+
+void inderror(char *err_str)
+{
+ error(err_str);
+ if (postb & INDIRECTBIT)
+ sym = RBRACKET; /* fake right bracket to kill further errors */
+ fixupind();
+}
+
+/* check current symbol is an index register (possibly excepting PC) */
+/* if so, modify postbyte RR and INDEXBIT for it, get next sym, return TRUE */
+/* otherwise generate error, return FALSE */
+
+reg_pt indreg(reg_pt maxindex)
+{
+ reg_pt reg;
+
+ if ((reg = regchk()) == NOREG)
+ inderror(IREGEXP);
+ else if (reg > maxindex)
+ {
+ inderror(ILLREG);
+ reg = NOREG;
+ }
+ else
+ {
+ postb |= rrindex[reg];
+ getsym();
+ }
+ return reg;
+}
+
+/* all-mode ops */
+
+void mall(void)
+{
+ if (sym == IMMEDIATE)
+ mimmed();
+ else
+ malter();
+}
+
+/* alterable mode ops */
+
+void malter(void)
+{
+ postb = 0x0; /* not yet indexed or indirect */
+ doaltind();
+}
+
+/* indexed mode ops */
+
+void mindex(void)
+{
+ postb = INDEXBIT; /* indexed but not yet indirect */
+ doaltind();
+}
+
+/* immediate ops */
+
+void mimmed(void)
+{
+ opcode_t nybble;
+
+ mcount += 0x2;
+ if (sym != IMMEDIATE)
+ error(ILLMOD);
+ else
+ {
+ if (opcode >= 0x80 && ((nybble = opcode & 0xF) == 0x3 ||
+ nybble == 0xC || nybble >= 0xE))
+ ++mcount; /* magic for long immediate */
+ symexpres();
+ if (pass2 && mcount <= 0x2)
+ {
+ chkabs();
+ checkdatabounds();
+ }
+ }
+}
+
+/* long branches */
+
+void mlong(void)
+{
+ mcount += 0x3; /* may be 0x0 or 0x1 here */
+ expres();
+ segadj();
+ if (pass2)
+ {
+ reldata();
+ if (!(lastexp.data & (RELBIT | UNDBIT)))
+ {
+ lastexp.offset = lastexp.offset - lc - lcjump;
+ if ( last_pass<2 && !(lastexp.data & IMPBIT) &&
+ lastexp.offset + 0x81 < 0x101)
+ warning(SHORTB); /* -0x81 to 0x7F, warning */
+ }
+ }
+}
+
+/* PSHS and PULS */
+
+void msstak(void)
+{
+ sustack(SREG);
+}
+
+/* TFR and EXG */
+
+void mswap(void)
+{
+ reg_pt reg;
+
+ mcount = 0x2;
+ if ((reg = regchk()) == NOREG)
+ error(REGEXP);
+ else
+ {
+ postb = tfrexg1[reg];
+ getsym();
+ if (sym != COMMA)
+ error(COMEXP);
+ else
+ {
+ getsym();
+ if ((reg = regchk()) == NOREG)
+ error(REGEXP);
+ else if ((postb |= tfrexg2[reg])
+ & 0x88 && (postb & 0x88) != 0x88)
+ error(ILLREG); /* registers not of same size */
+ }
+ }
+}
+
+/* PSHU and PULU */
+
+void mustak(void)
+{
+ sustack(UREG);
+}
+
+void predec1(void)
+{
+ if (postb & INDIRECTBIT)
+ inderror(ILLMOD); /* single-dec indirect illegal */
+ else
+ {
+ postb |= 0x82;
+ getindexnopost();
+ }
+}
+
+/* common routine for PSHS/PULS/PSHU/PULU */
+
+void sustack(stackreg)
+reg_pt stackreg;
+{
+ reg_pt reg;
+
+ mcount = 0x2;
+ while ((reg = regchk()) != NOREG)
+ {
+ if (reg == stackreg)
+ {
+ error(ILLREG); /* cannot stack self */
+ break;
+ }
+ postb |= pushpull[reg];
+ getsym();
+ if (sym != COMMA)
+ break;
+ getsym();
+ }
+}
+
+#endif /* MC6809 */
+
+/* routines common to all processors */
+
+void getcomma(void)
+{
+ if (sym != COMMA)
+ error(COMEXP);
+ else
+ getsym();
+}
+
+/* inherent ops */
+
+/* for I80386 */
+/* AAA, AAS, CLC, CLD, CLI, CLTS, CMC, CMPSB, DAA, DAS, HLT, INTO, INSB, */
+/* INVD, */
+/* LAHF, LEAVE, LOCK, LODSB, MOVSB, NOP, OUTSB, REP, REPE, REPNE, REPNZ, */
+/* REPZ, SAHF, SCASB, STC, STD, STI, STOSB, WAIT, WBINVD */
+
+void minher(void)
+{
+ ++mcount;
+}
+
+/* short branches */
+
+void mshort(void)
+{
+ nonimpexpres();
+ mshort2();
+}
+
+void mshort2(void)
+{
+ mcount += 0x2;
+ if (pass2)
+ {
+ reldata();
+ if (lastexp.data & RELBIT)
+ showrelbad();
+ else if (!(lastexp.data & UNDBIT))
+ {
+ lastexp.offset = lastexp.offset - lc - mcount;
+ if (!is8bitsignedoffset(lastexp.offset))
+ error(ABOUNDS);
+ }
+ }
+}
+
+/* check if current symbol is a register, return register number or NOREG */
+
+reg_pt regchk(void)
+{
+ register struct sym_s *symptr;
+
+ if (sym == IDENT)
+ {
+ if ((symptr = gsymptr)->type & MNREGBIT)
+ {
+ if (symptr->data & REGBIT)
+ {
+ int regno = symptr->value_reg_or_op.reg;
+#ifdef I80386
+ if (regno == ST0REG && !fpreg_allowed)
+ error(FP_REG_NOT_ALLOWED);
+
+ /* Check cpu */
+ needcpu((regno==FSREG||regno==GSREG)?3:0);
+ needcpu((regno>=EAXREG && regno<=ESPREG)?3:0);
+ needcpu((regno>=CR0REG && regno<=TR7REG)?3:0);
+#endif
+ return regno;
+ }
+ }
+ else
+ if( last_pass == 1 )
+ if (!(symptr->type & (LABIT | MACBIT | VARBIT)))
+ symptr->data |= FORBIT; /* show seen in advance */
+ }
+ return NOREG;
+}
+
+/* convert lastexp.data for PC relative */
+
+void reldata(void)
+{
+ if ((lastexp.data ^ lcdata) & (IMPBIT | RELBIT | SEGM))
+ {
+ if ((lastexp.data ^ lcdata) & RELBIT)
+ showrelbad(); /* rel - abs is weird, abs - rel is bad */
+ else
+ {
+ pcrflag = OBJ_R_MASK;
+ lastexp.data = (lcdata & ~SEGM) | lastexp.data | RELBIT;
+ /* segment is that of lastexp.data */
+ }
+ }
+ else /* same file, segment and relocation */
+ lastexp.data = (lastexp.data | lcdata) & ~(RELBIT | SEGM);
+}
+
+void segadj(void)
+{
+ if ((lastexp.data & UNDBIT) && textseg >= 0 )
+ {
+ lastexp.sym->data &= ~SEGM;
+ lastexp.sym->data |= (lcdata & SEGM);
+ }
+}
--- /dev/null
+/* opcode.h - routine numbers and special opcodes for assembler */
+
+enum
+{
+/* Pseudo-op routine numbers.
+ * Conditionals are first - this is used to test if op is a conditional.
+ */
+ ELSEOP,
+ ELSEIFOP,
+ ELSEIFCOP,
+ ENDIFOP,
+ IFOP,
+ IFCOP,
+
+#define MIN_NONCOND ALIGNOP
+ ALIGNOP,
+ ASCIZOP,
+ BLKWOP,
+ BLOCKOP,
+ BSSOP,
+ COMMOP,
+ COMMOP1,
+ DATAOP,
+ ENDBOP,
+ ENTEROP,
+ ENTRYOP,
+ EQUOP,
+ EVENOP,
+ EXPORTOP,
+ FAILOP,
+ FCBOP,
+ FCCOP,
+ FDBOP,
+#if SIZEOF_OFFSET_T > 2
+ FQBOP,
+#endif
+ GETOP,
+ GLOBLOP,
+ IDENTOP,
+ IMPORTOP,
+ LCOMMOP,
+ LCOMMOP1,
+ LISTOP,
+ LOCOP,
+ MACLISTOP,
+ MACROOP,
+ MAPOP,
+ ORGOP,
+ PROCEOFOP,
+ RMBOP,
+ SECTOP,
+ SETOP,
+ SETDPOP,
+ TEXTOP,
+#ifdef I80386
+ USE16OP,
+ USE32OP,
+#endif
+ WARNOP,
+
+/* Machine-op routine numbers. */
+#ifdef I80386
+ BCC,
+ BSWAP,
+ CALL,
+ CALLI,
+ DIVMUL,
+ ENTER,
+ EwGw,
+ ExGx,
+ F_INHER,
+ F_M,
+ F_M2,
+ F_M2_AX,
+ F_M2_M4,
+ F_M2_M4_M8,
+ F_M4_M8_OPTST,
+ F_M4_M8_ST,
+ F_M4_M8_STST,
+ F_M4_M8_M10_ST,
+ F_M10,
+ F_OPTST,
+ F_ST,
+ F_STST,
+ F_W_INHER,
+ F_W_M,
+ F_W_M2,
+ F_W_M2_AX,
+ GROUP1,
+ GROUP2,
+ GROUP6,
+ GROUP7,
+ GROUP8,
+ GvEv,
+ GvMa,
+ GvMp,
+ IMUL,
+ IN,
+ INCDEC,
+ INHER,
+ INHER16,
+ INHER32,
+ INHER_A,
+ INT,
+ JCC,
+ JCXZ,
+ LEA,
+ MOV,
+ MOVX,
+ NEGNOT,
+ OUT,
+ PUSHPOP,
+ RET,
+ SEG,
+ SETCC,
+ SH_DOUBLE,
+ TEST,
+ XCHG
+#endif /* I80386 */
+
+#ifdef MC6809
+ ALL, /* all address modes allowed, like LDA */
+ ALTER, /* all but immediate, like STA */
+ IMMED, /* immediate only (ANDCC, ORCC) */
+ INDEXD, /* indexed (LEA's) */
+ INHER, /* inherent, like CLC or CLRA */
+ LONG, /* long branches */
+ SHORT, /* short branches */
+ SSTAK, /* S-stack (PSHS, PULS) */
+ SWAP, /* TFR, EXG */
+ USTAK /* U-stack (PSHU,PULU) */
+#endif /* MC6809 */
+};
+
+/* Special opcodes. */
+#ifdef I80386
+# define CMP_OPCODE_BASE 0x38
+# define CMPSB_OPCODE 0xA6
+# define CMPSW_OPCODE 0xA7
+# define ESCAPE_OPCODE_BASE 0xD8
+# define FST_ENCODED 0x12
+# define FSTP_ENCODED 0x13
+# define JMP_OPCODE 0xE9
+# define JMP_SHORT_OPCODE 0xEB
+# define JSR_OPCODE 0xE8
+# define MOVSB_OPCODE 0xA4
+# define MOVSW_OPCODE 0xA5
+# define PAGE1_OPCODE 0x0F
+# define POP_OPCODE 0x8F
+# define PUSH_OPCODE 0xFF
+# define WAIT_OPCODE 0x9B
+#endif
+
+#ifdef MC6809
+# define JMP_OPCODE 0x7E
+# define JSR_OPCODE 0xBD
+# define PAGE1_OPCODE 0x10
+# define PAGE2_OPCODE 0x11
+#endif
--- /dev/null
+/* pops.c - handle pseudo-ops for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "address.h"
+#include "flag.h"
+#include "globvar.h"
+#include "opcode.h"
+#include "scan.h"
+
+static bool_t elseflag; /* set if ELSE/ELSEIF are enabled */
+ /* depends on zero = FALSE init */
+static bool_t lcommflag;
+
+static void bumpsem P((struct flags_s *flagptr, int defval));
+static void constdata P((unsigned size));
+static void docomm P((void));
+static void doelseif P((pfv func));
+static void doequset P((unsigned char labits));
+static void doentexp P((unsigned char entbits, unsigned char impbits));
+static void dofcc P((void));
+static void doif P((pfv func));
+static struct sym_s *needlabel P((void));
+static void showredefinedlabel P((void));
+static void setloc P((unsigned seg));
+
+static void bumpsem(flagptr, defval)
+register struct flags_s *flagptr;
+int defval;
+{
+ int newcount;
+
+ if (flagptr->global && pass == last_pass)
+ {
+ /* bump semaphore count by an expression (default 1), */
+ /* then set currentflag iff semaphore count is plus */
+ if (sym == EOLSYM)
+ lastexp.offset = defval;
+ else
+ {
+ absexpres();
+ if (lastexp.data & UNDBIT)
+ return;
+ }
+ newcount = (int) lastexp.offset;
+#ifdef I80386 /* really sizeof (offset_t) != sizeof (int) */
+ if (newcount != lastexp.offset)
+ datatoobig();
+#endif
+ newcount += flagptr->semaphore;
+ if ((int) lastexp.offset >= 0)
+ {
+ if (newcount < flagptr->semaphore)
+ {
+ error(COUNTOV);
+ newcount = 0x7fff;
+ }
+ }
+ else if (newcount >= flagptr->semaphore)
+ {
+ error(COUNTUN);
+ newcount = -0x8000;
+ }
+ flagptr->semaphore = newcount;
+ flagptr->current = newcount >= 0;
+ }
+}
+
+/* check symbol is either undefined */
+/* or has the same segment & relocatability as lc */
+
+bool_pt checksegrel(symptr)
+register struct sym_s *symptr;
+{
+ if ((symptr->type & LABIT ||
+ (symptr->data & IMPBIT && !(symptr->data & UNDBIT))) &&
+ ((symptr->data ^ lcdata) & (RELBIT | SEGM)))
+ {
+ error(SEGREL);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* check address fits in 1 byte (possibly with sign truncated) */
+
+void checkdatabounds(void)
+{
+ if (!(lastexp.data & UNDBIT) &&
+ (offset_t) (lastexp.offset + 0x80) >= 0x180)
+ datatoobig();
+}
+
+/* allocate constant data (zero except for size 1), default zero for size 1 */
+
+static void constdata(unsigned size)
+{
+ offset_t remaining;
+
+ absexpres();
+ if (!((lcdata |= lastexp.data) & UNDBIT))
+ {
+ lcjump = lastexp.offset * size;
+ popflags = POPLONG | POPHI | POPLO | POPLC;
+ if (size == 1 && sym == COMMA)
+ {
+ symabsexpres();
+ checkdatabounds();
+ for (remaining = lcjump; remaining != 0; --remaining)
+ {
+ putbin((opcode_pt) lastexp.offset); /* fill byte */
+ putabs((opcode_pt) lastexp.offset);
+ }
+ lastexp.offset = lcjump;
+ }
+ else
+ accumulate_rmb(lastexp.offset * size);
+ }
+}
+
+void datatoobig(void)
+{
+ error(DBOUNDS);
+}
+
+/* common routine for COMM/.COMM */
+
+static void docomm(void)
+{
+ register struct sym_s *labptr;
+
+ absexpres(); /* if undefined, value 0 and size unchanged */
+ labptr = label;
+ if (checksegrel(labptr))
+ {
+ if (labptr->type & (EXPBIT | LABIT))
+ labelerror(ALREADY);
+ else
+ {
+ if (!(labptr->type & COMMBIT) ||
+ lastexp.offset > labptr->value_reg_or_op.value)
+ labptr->value_reg_or_op.value = lastexp.offset;
+ labptr->type |= COMMBIT;
+ if (lcommflag)
+ labptr->type |= REDBIT; /* kludge - COMMBIT | REDBIT => SA */
+ if( last_pass == 1 )
+ labptr->data = (lcdata & SEGM) | (FORBIT | IMPBIT | RELBIT);
+ else
+ labptr->data = (lcdata & SEGM) | (IMPBIT | RELBIT);
+ showlabel();
+ }
+ }
+ lcommflag = FALSE;
+}
+
+/* common routine for ELSEIF/ELSEIFC */
+
+static void doelseif(pfv func)
+{
+ if (iflevel == 0)
+ error(ELSEIFBAD);
+ else
+ {
+ ifflag = FALSE;
+ if (elseflag)
+ {
+ (*func) ();
+ if (!(lastexp.data & UNDBIT) && lastexp.offset != 0)
+ /* expression valid and TRUE, enable assembling */
+ {
+ ifflag = TRUE;
+ elseflag = FALSE;
+ }
+ }
+ else
+ {
+ /* Skip to EOL */
+ while (sym != EOLSYM)
+ getsym();
+ }
+ }
+}
+
+/* common routine for EQU/SET */
+
+static void doequset(unsigned char labits)
+{
+ register struct sym_s *labptr;
+ unsigned char olddata;
+ unsigned char oldtype;
+
+ labptr = label;
+ /* set up new label flags in case labe isl used in expression */
+ labptr->type = (oldtype = labptr->type) | labits;
+ labptr->data = (olddata = labptr->data) & ~IMPBIT;
+ /* non-imported now */
+ nonimpexpres();
+ lastexp.data |= olddata & FORBIT; /* take all but FORBIT from
+ expression */
+ if (oldtype & LABIT && !(olddata & UNDBIT) && !pass)
+ /* this is a previously defined label */
+
+ /*
+ redefinition only allowed if same relocatability, segment and
+ value
+ */
+ {
+ if ((olddata ^ lastexp.data) & (RELBIT | UNDBIT) ||
+ labptr->value_reg_or_op.value != lastexp.offset)
+ {
+ showredefinedlabel();
+ return;
+ }
+ }
+ labptr->data = lastexp.data;
+ labptr->value_reg_or_op.value = lastexp.offset;
+ showlabel();
+
+ if(pass && !(labits & VARBIT) && labptr->value_reg_or_op.value != oldlabel)
+ {
+ dirty_pass = TRUE;
+ if( pass == last_pass )
+ error(UNSTABLE_LABEL);
+ }
+}
+
+/* common routine for ENTRY/EXPORT */
+
+static void doentexp(unsigned char entbits, unsigned char impbits)
+{
+ struct sym_s *symptr;
+
+ while (TRUE)
+ {
+ if ((symptr = needlabel()) != NUL_PTR)
+ {
+ if (symptr->type & COMMBIT)
+ error(ALREADY);
+ else if (impbits != 0)
+ {
+ if (pass == last_pass)
+ ;
+ else if (symptr->type & (EXPBIT | LABIT))
+ symptr->type |= EXPBIT;
+ else
+ {
+ symptr->type |= REDBIT;
+ if (!(symptr->data & IMPBIT))
+ symptr->data |= IMPBIT | SEGM;
+ }
+ }
+ else
+ {
+ if (pass == last_pass)
+ {
+ if (!(symptr->type & LABIT))
+ error(UNLAB);
+ }
+ else
+ {
+ symptr->type |= entbits | EXPBIT;
+ symptr->data &= ~IMPBIT;
+ }
+ }
+ }
+ getsym();
+ if (sym != COMMA)
+ break;
+ getsym();
+ }
+}
+
+/* common routine for FCC (== .ASCII) and .ASCIZ */
+
+static void dofcc(void)
+{
+ register char *bufptr;
+ char byte;
+ char delimiter;
+ register char *reglineptr;
+
+ bufptr = databuf.fcbuf;
+ reglineptr = symname;
+ if ((delimiter = *reglineptr) != EOLCHAR)
+ ++reglineptr;
+ while (TRUE)
+ {
+ if ((byte = *reglineptr) == EOLCHAR)
+ {
+ symname = reglineptr;
+ error(DELEXP);
+ break;
+ }
+ if (byte == delimiter)
+ {
+ if ((byte = *++reglineptr) != delimiter)
+ break;
+ }
+ else if (byte == '\\')
+ {
+ switch (byte = *++reglineptr)
+ {
+ case '"':
+ case '\'':
+ case '\\':
+ case '?':
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ byte -= '0';
+ if (*(reglineptr + 1) >= '0' && *(reglineptr + 1) < '8')
+ {
+ byte = 8 * byte + *++reglineptr - '0';
+ if (*(reglineptr + 1) >= '0' && *(reglineptr + 1) < '8')
+ byte = 8 * byte + *++reglineptr - '0';
+ }
+ break;
+ case 'a':
+ byte = 7;
+ break;
+ case 'b':
+ byte = 8;
+ break;
+ case 'f':
+ byte = 12;
+ break;
+ case 'n':
+ byte = 10;
+ break;
+ case 'r':
+ byte = 13;
+ break;
+ case 't':
+ byte = 9;
+ break;
+ case 'v':
+ byte = 11;
+ break;
+ case 'x':
+ byte = '0';
+ while (TRUE)
+ {
+ ++reglineptr;
+ if (*reglineptr >= '0' && *reglineptr <= '9')
+ byte = 16 * byte + *reglineptr - '0';
+ else if (*reglineptr >= 'F' && *reglineptr <= 'F')
+ byte = 16 * byte + *reglineptr - 'A';
+ else if (*reglineptr >= 'a' && *reglineptr <= 'f')
+ byte = 16 * byte + *reglineptr - 'F';
+ else
+ break;
+ }
+ --reglineptr;
+ break;
+ default:
+ symname = reglineptr;
+ error(UNKNOWN_ESCAPE_SEQUENCE);
+ break;
+ }
+ }
+ else if (byte < ' ' && byte >= 0)
+ {
+ symname = reglineptr;
+ error(CTLINS);
+ byte = ' ';
+ }
+ ++reglineptr;
+ *bufptr++ = byte;
+ }
+ lineptr = reglineptr;
+ getsym();
+ lastexp.offset = databuf.fcbuf[0]; /* show only 1st char (if any) */
+ mcount = bufptr - databuf.fcbuf;
+ /* won't overflow, line length limits it */
+ /* XXX - but now line length is unlimited */
+}
+
+/* common routine for IF/IFC */
+
+static void doif(pfv func)
+{
+ if (iflevel >= MAXIF)
+ error(IFOV);
+ else
+ {
+ ++iflevel;
+ --ifstak;
+ ifstak->elseflag = elseflag;
+ elseflag = FALSE; /* prepare */
+ if ((ifstak->ifflag = ifflag) != FALSE)
+ /* else not assembling before, so not now & no ELSE's */
+ {
+ (*func) ();
+ if (!(lastexp.data & UNDBIT) && lastexp.offset == 0)
+ /* else expression invalid or FALSE, don't change flags */
+ {
+ ifflag = FALSE; /* not assembling */
+ elseflag = TRUE;/* but ELSE will change that */
+ }
+ }
+ else
+ {
+ /* Skip to EOL */
+ while (sym != EOLSYM)
+ getsym();
+ }
+ }
+}
+
+void fatalerror(char *err_str)
+{
+ error(err_str);
+ skipline();
+ listline();
+ finishup();
+}
+
+/* swap position with label position, do error, put back posn */
+/* also clear label ptr */
+
+void labelerror(char *err_str)
+{
+ struct sym_s *oldgsymptr;
+ char *oldlineptr;
+ unsigned char oldsym;
+ char *oldsymname;
+
+ oldgsymptr = gsymptr;
+ oldlineptr = lineptr;
+ oldsym = sym;
+ oldsymname = symname;
+ lineptr = linebuf;
+ getsym(); /* 1st symbol is label or symbol after
+ * missing one */
+ error(err_str);
+ gsymptr = oldgsymptr;
+ lineptr = oldlineptr;
+ sym = oldsym;
+ symname = oldsymname;
+ label = NUL_PTR;
+}
+
+static struct sym_s *needlabel(void)
+{
+ register struct sym_s *symptr;
+
+ if (sym != IDENT ||
+ (symptr = gsymptr)->type & (MACBIT | MNREGBIT | VARBIT))
+ {
+ error(LABEXP);
+ return NUL_PTR;
+ }
+ return symptr;
+}
+
+/* .ALIGN pseudo-op */
+
+void palign(void)
+{
+ absexpres();
+ if (!((lcdata |= lastexp.data) & UNDBIT))
+ {
+ popflags = POPLONG | POPHI | POPLO | POPLC;
+ if (lastexp.offset != 0 &&
+ (lcjump = lc % lastexp.offset) != 0)
+ accumulate_rmb(lcjump = lastexp.offset - lcjump);
+ }
+}
+
+/* .ASCIZ pseudo-op */
+
+void pasciz(void)
+{
+ dofcc();
+ databuf.fcbuf[mcount++] = 0;
+ fcflag = TRUE;
+ popflags = POPLO | POPLC;
+}
+
+/* .BLKW pseudo-op */
+
+void pblkw(void)
+{
+ constdata(2);
+}
+
+/* BLOCK pseudo-op */
+
+void pblock(void)
+{
+ if (blocklevel >= MAXBLOCK)
+ error(BLOCKOV);
+ else
+ {
+ register struct block_s *blockp;
+
+ ++blocklevel;
+ blockp = blockstak;
+ blockstak = --blockp;
+ blockp->data = lcdata;
+ blockp->dp = dirpag;
+ blockp->lc = lc;
+ porg(); /* same as ORG apart from stacking */
+ }
+}
+
+/* .BSS pseudo-op */
+
+void pbss(void)
+{
+ setloc(BSSLOC);
+}
+
+/* COMM pseudo-op */
+
+void pcomm(void)
+{
+ if (label == NUL_PTR)
+ labelerror(MISLAB);
+ else if (label->type & VARBIT)
+ labelerror(VARLAB); /* variable cannot be COMM'd */
+ else
+ docomm();
+}
+
+/* .COMM pseudo-op */
+
+void pcomm1(void)
+{
+ static unsigned oldseg;
+
+ if (label != NUL_PTR)
+ labelerror(ILLAB);
+ oldseg = lcdata & SEGM;
+ setloc(BSSLOC);
+ if ((label = needlabel()) != NUL_PTR && checksegrel(label))
+ {
+ /* Like import. */
+ if (label->type & (EXPBIT | LABIT))
+ error(ALREADY);
+ else if( last_pass == 1 )
+ label->data = lcdata | (FORBIT | IMPBIT | RELBIT);
+ else
+ label->data = lcdata | (IMPBIT | RELBIT);
+ getsym();
+ getcomma();
+ if (label->type & (EXPBIT | LABIT))
+ absexpres(); /* just to check it */
+ else
+ docomm();
+ }
+ setloc(oldseg);
+}
+
+/* .DATA pseudo-op */
+
+void pdata(void)
+{
+ setloc(DATALOC);
+}
+
+/* ELSE pseudo-op */
+
+void pelse(void)
+{
+ if (iflevel == 0)
+ error(ELSEBAD);
+ else
+ {
+ ifflag = FALSE; /* assume ELSE disabled */
+ if (elseflag)
+ {
+ ifflag = TRUE; /* ELSE enabled */
+ elseflag = FALSE;
+ }
+ }
+}
+
+/* ELSEIF pseudo-op */
+
+void pelseif(void)
+{
+ doelseif(absexpres);
+}
+
+/* ELSEIFC pseudo-op */
+
+void pelsifc(void)
+{
+ doelseif(scompare);
+}
+
+/* ENDB pseudo-op */
+
+void pendb(void)
+{
+ if (label != NUL_PTR)
+ labelerror(ILLAB);
+ if (blocklevel == 0)
+ error(ENDBBAD);
+ else
+ {
+ register struct block_s *blockp;
+
+ blockp = blockstak;
+ lcdata = blockp->data;
+ dirpag = blockp->dp;
+ accumulate_rmb(blockp->lc - lc);
+ lc = blockp->lc;
+ --blocklevel;
+ blockstak = blockp + 1;
+ }
+}
+
+/* ENDIF pseudo-op */
+
+void pendif(void)
+{
+ if (iflevel == 0)
+ error(ENDIFBAD);
+ else
+ {
+ ifflag = ifstak->ifflag;
+ elseflag = ifstak->elseflag;
+ ++ifstak;
+ --iflevel;
+ }
+}
+
+/* ENTER pseudo-op */
+
+void penter(void)
+{
+ if (!(pedata & UNDBIT))
+ error(REENTER);
+ else
+ {
+ if (!((pedata = (pedata & ~UNDBIT) | lcdata) & UNDBIT))
+ {
+ progent = lc;
+ popflags = POPLC;
+ }
+ }
+}
+
+/* ENTRY pseudo-op */
+
+void pentry(void)
+{
+ doentexp(ENTBIT, 0);
+}
+
+/* EQU pseudo-op */
+
+void pequ(void)
+{
+ register struct sym_s *labptr;
+
+ if ((labptr = label) == NUL_PTR)
+ labelerror(MISLAB);
+ else if (labptr->type & COMMBIT)
+ showredefinedlabel(); /* common cannot be EQU'd */
+ else if (labptr->type & VARBIT)
+ labelerror(VARLAB); /* variable cannot be EQU'd */
+ else
+ doequset(LABIT);
+}
+
+/* .EVEN pseudo-op */
+
+void peven(void)
+{
+ popflags = POPLONG | POPHI | POPLO | POPLC;
+ accumulate_rmb(lcjump = lastexp.data = lc & 1);
+}
+
+/* EXPORT pseudo-op */
+
+void pexport(void)
+{
+ doentexp(0, 0);
+}
+
+/* FAIL pseudo-op */
+
+void pfail(void)
+{
+ if(pass==last_pass) error(FAILERR);
+}
+
+/* FCB pseudo-op */
+
+void pfcb(void)
+{
+ char *bufptr;
+ offset_t firstbyte;
+
+ bufptr = databuf.fcbuf;
+ absexpres();
+ firstbyte = lastexp.offset;
+ while (TRUE)
+ {
+ checkdatabounds();
+ *bufptr++ = lastexp.offset;
+ ++mcount; /* won't overflow, line length limits it */
+ if (sym != COMMA)
+ break;
+ symabsexpres();
+ }
+ lastexp.offset = firstbyte;
+ popflags = POPLO | POPLC;
+ fcflag = TRUE;
+}
+
+/* FCC pseudo-op */
+
+void pfcc(void)
+{
+ dofcc();
+ if (mcount != 0)
+ {
+ fcflag = TRUE;
+ popflags = POPLO | POPLC;
+ }
+}
+
+/* FDB pseudo-op */
+
+void pfdb(void)
+{
+ struct address_s *adrptr;
+ unsigned firstdata;
+ offset_t firstword;
+
+ adrptr = databuf.fdbuf;
+ expres();
+ firstword = lastexp.offset;
+ firstdata = lastexp.data;
+ while (TRUE)
+ {
+ *adrptr++ = lastexp;
+ mcount += 2; /* won't overflow, line length limits it */
+ if (sym != COMMA)
+ break;
+ symexpres();
+ }
+ lastexp.offset = firstword;
+ lastexp.data = firstdata;
+ popflags = POPHI | POPLO | POPLC;
+ fdflag = TRUE;
+}
+
+#if SIZEOF_OFFSET_T > 2
+
+/* FQB pseudo-op */
+
+void pfqb(void)
+{
+ struct address_s *adrptr;
+ offset_t firstdata;
+ offset_t firstword;
+
+ adrptr = databuf.fqbuf;
+ expres();
+ firstword = lastexp.offset;
+ firstdata = lastexp.data;
+ while (TRUE)
+ {
+ *adrptr++ = lastexp;
+ mcount += 4; /* won't overflow, line length limits it */
+ if (sym != COMMA)
+ break;
+ symexpres();
+ }
+ lastexp.offset = firstword;
+ lastexp.data = firstdata;
+ popflags = POPLONG | POPHI | POPLO | POPLC;
+ fqflag = TRUE;
+}
+
+#endif /* SIZEOF_OFFSET_T > 2 */
+
+/* .GLOBL pseudo-op */
+
+void pglobl(void)
+{
+ if (binaryg)
+ error(NOIMPORT);
+ doentexp(0, IMPBIT);
+}
+
+/* IDENT pseudo-op (not complete) */
+
+void pident(void)
+{
+ if (sym != IDENT)
+ error(LABEXP);
+ else
+ getsym_nolookup(); /* should save ident string */
+}
+
+/* IF pseudo-op */
+
+void pif(void)
+{
+ doif(absexpres);
+}
+
+/* IFC pseudo-op */
+
+void pifc(void)
+{
+ doif(scompare);
+}
+
+/* IMPORT pseudo-op */
+
+void pimport(void)
+{
+ struct sym_s *symptr;
+
+ if (binaryg)
+ error(NOIMPORT);
+ while (TRUE)
+ {
+ if ((symptr = needlabel()) != NUL_PTR && checksegrel(symptr))
+ {
+ if (symptr->type & (COMMBIT | EXPBIT | LABIT))
+ /* IMPORT is null if label (to be) declared */
+ error(ALREADY);
+ else if( last_pass == 1 )
+ /* get current segment from lcdata, no need to mask rest */
+ symptr->data = lcdata | (FORBIT | IMPBIT | RELBIT);
+ else
+ symptr->data = lcdata | (IMPBIT | RELBIT);
+ }
+ getsym();
+ if (sym != COMMA)
+ break;
+ getsym();
+ }
+}
+
+/* LCOMM pseudo-op */
+
+void plcomm(void)
+{
+ lcommflag = TRUE;
+ pcomm();
+}
+
+/* .LCOMM pseudo-op */
+
+void plcomm1(void)
+{
+ lcommflag = TRUE;
+ pcomm1();
+}
+
+/* .LIST pseudo-op */
+
+void plist(void)
+{
+ bumpsem(&list, 1);
+}
+
+/* .NOLIST pseudo-op */
+
+void pnolist(void)
+{
+ bumpsem(&list, -1);
+}
+
+/* LOC pseudo-op */
+
+void ploc(void)
+{
+ if (label != NUL_PTR)
+ labelerror(ILLAB);
+ absexpres();
+ if (!(lastexp.data & UNDBIT))
+ {
+ if (lastexp.offset >= NLOC)
+ datatoobig();
+ else
+ setloc((unsigned) lastexp.offset);
+ }
+}
+
+/* .MACLIST pseudo-op */
+
+void pmaclist(void)
+{
+ bumpsem(&maclist, 1);
+}
+
+/* .MAP pseudo-op */
+
+void pmap(void)
+{
+ absexpres();
+ if (!(lastexp.data & UNDBIT))
+ {
+ mapnum = lastexp.offset;
+ popflags = POPLO;
+ if (lastexp.offset >= 0x100)
+ datatoobig();
+ }
+}
+
+/* ORG pseudo-op */
+
+void porg(void)
+{
+ if (label != NUL_PTR)
+ labelerror(ILLAB);
+ absexpres();
+ if (!((lcdata = lastexp.data) & UNDBIT))
+ {
+ accumulate_rmb(lastexp.offset - lc);
+ binmbuf = lc = lastexp.offset;
+ binmbuf_set = 1;
+ popflags = POPLC;
+ }
+}
+
+/* RMB pseudo-op */
+
+void prmb(void)
+{
+ constdata(1);
+}
+
+/* .SECT pseudo-op */
+
+void psect(void)
+{
+ if (label != NUL_PTR)
+ labelerror(ILLAB);
+ while (sym == IDENT)
+ {
+ if (!(gsymptr->type & MNREGBIT))
+ error(ILL_SECTION);
+ else switch (gsymptr->value_reg_or_op.op.routine)
+ {
+ case BSSOP:
+ pbss();
+ break;
+ case DATAOP:
+ pdata();
+ break;
+ case TEXTOP:
+ ptext();
+ break;
+ default:
+ error(ILL_SECTION);
+ break;
+ }
+ getsym();
+ if (sym == COMMA)
+ getsym();
+ }
+}
+
+/* SET pseudo-op */
+
+void pset(void)
+{
+ register struct sym_s *labptr;
+
+ if ((labptr = label) == NUL_PTR)
+ labelerror(MISLAB);
+ else if (labptr->type & COMMBIT)
+ labelerror(RELAB); /* common cannot be SET'd */
+ else
+ doequset(labptr->type & LABIT ? 0 : VARBIT);
+}
+
+/* SETDP pseudo-op */
+
+void psetdp(void)
+{
+ absexpres();
+ if (!(lastexp.data & UNDBIT))
+ {
+ dirpag = lastexp.offset;
+ popflags = POPLO;
+ if (lastexp.offset >= 0x100)
+ datatoobig();
+ }
+}
+
+/* .TEXT pseudo-op */
+
+void ptext(void)
+{
+ if( textseg <= 0 )
+ setloc(TEXTLOC);
+ else
+ setloc(textseg);
+}
+
+/* .WARN pseudo-op */
+
+void pwarn(void)
+{
+ bumpsem(&as_warn, -1);
+}
+
+#ifdef I80386
+
+/* USE16 pseudo-op */
+
+void puse16(void)
+{
+ defsize = 2;
+#ifdef iscpu
+ if( sym != EOLSYM )
+ {
+ absexpres();
+ if (lastexp.data & UNDBIT)
+ return;
+ if( lastexp.offset > 8000 )
+ setcpu((int) lastexp.offset / 100 % 10);
+ else if( lastexp.offset > 15 )
+ setcpu((int) lastexp.offset / 100);
+ else
+ setcpu((int) lastexp.offset);
+ }
+#endif
+}
+
+/* USE16 pseudo-op */
+
+void puse32(void)
+{
+ defsize = 4;
+#ifdef iscpu
+ if(!iscpu(3)) setcpu(3);
+ if( sym != EOLSYM )
+ {
+ absexpres();
+ if (lastexp.data & UNDBIT)
+ return;
+ if( lastexp.offset > 15 )
+ setcpu((int) lastexp.offset / 100);
+ else
+ setcpu((int) lastexp.offset);
+ }
+#endif
+}
+
+#endif
+
+/* show redefined label and error, and set REDBIT */
+
+static void showredefinedlabel(void)
+{
+ register struct sym_s *labptr;
+
+ labptr = label; /* showlabel() will kill label prematurely */
+ showlabel();
+ if (!(labptr->type & REDBIT))
+ {
+ labptr->type |= REDBIT;
+ labelerror(RELAB);
+ }
+}
+
+void showlabel(void)
+{
+ register struct sym_s *labptr;
+
+ labptr = label;
+ lastexp.data = labptr->data;
+ lastexp.offset = labptr->value_reg_or_op.value;
+ popflags = POPLONG | POPHI | POPLO;
+ label = NUL_PTR; /* show handled by COMM, EQU or SET */
+}
+
+/* set location segment */
+
+static void setloc(unsigned seg)
+{
+ if (pass == last_pass && seg != (lcdata & SEGM))
+ putobj((opcode_pt) (seg | OBJ_SET_SEG));
+ {
+ register struct lc_s *lcp;
+
+ lcp = lcptr;
+ lcp->data = lcdata;
+ lcp->lc = lc;
+ lcptr = lcp = lctab + (unsigned char) seg;
+ lcdata = (lcp->data & ~SEGM) | (unsigned char) seg;
+ binmbuf = lc = lcp->lc;
+ popflags = POPLC;
+ }
+}
--- /dev/null
+/* extern functions */
+
+/* as.c */
+int main(int argc, char **argv);
+void as_abort(char *message);
+void finishup(void);
+void initp1p2(void);
+void line_zero(void);
+
+/* assemble.c */
+void assemble(void);
+
+/* express.c */
+void absexpres(void);
+void chkabs(void);
+void nonimpexpres(void);
+void showrelbad(void);
+void symabsexpres(void);
+void symexpres(void);
+void expres(void);
+void factor(void);
+void scompare(void);
+
+/* genbin.c */
+void binheader(void);
+void bintrailer(void);
+void genbin(void);
+void initbin(void);
+void putbin(int ch);
+
+/* genlist.c */
+char *build_2hex_number(unsigned num, char *where);
+char *build_number(unsigned num, unsigned width, char *where);
+void warning(char * errorstr);
+void error(char * errorstr);
+void listline(void);
+void writec(char ch);
+void writenl(void);
+void writeoff(offset_t offset);
+void writes(const char *s);
+void writesn(const char *s);
+void writew(unsigned word);
+
+/* genobj.c */
+void accumulate_rmb(offset_t offset);
+void flushobj(void);
+void genobj(void);
+void initobj(void);
+void objheader(void);
+void objtrailer(void);
+void putabs(opcode_pt ch);
+void putobj(opcode_pt ch);
+
+/* gensym.c */
+void gensym(void);
+
+/* macro.c */
+void entermac(struct sym_s *symptr);
+void pmacro(void);
+
+/* mops.c */
+#ifdef I80386
+void mbcc(void);
+void mbswap(void);
+void mcall(void);
+void mcalli(void);
+void mdivmul(void);
+void menter(void);
+void mEwGw(void);
+void mExGx(void);
+void mf_inher(void);
+void mf_m(void);
+void mf_m2(void);
+void mf_m2_ax(void);
+void mf_m2_m4(void);
+void mf_m2_m4_m8(void);
+void mf_m4_m8_optst(void);
+void mf_m4_m8_st(void);
+void mf_m4_m8_stst(void);
+void mf_m4_m8_m10_st(void);
+void mf_m10(void);
+void mf_optst(void);
+void mf_st(void);
+void mf_stst(void);
+void mf_w_inher(void);
+void mf_w_m(void);
+void mf_w_m2(void);
+void mf_w_m2_ax(void);
+void mgroup1(void);
+void mgroup2(void);
+void mgroup6(void);
+void mgroup7(void);
+void mgroup8(void);
+void mGvEv(void);
+void mGvMa(void);
+void mGvMp(void);
+void mimul(void);
+void min(void);
+void mincdec(void);
+void minher(void);
+void minher16(void);
+void minher32(void);
+void minhera(void);
+void mint(void);
+void mjcc(void);
+void mjcxz(void);
+void mlea(void);
+void mmov(void);
+void mmovx(void);
+void mnegnot(void);
+void mout(void);
+void mpushpop(void);
+void mret(void);
+void mseg(void);
+void msetcc(void);
+void mshdouble(void);
+void mtest(void);
+void mxchg(void);
+#endif /* I80386 */
+
+#ifdef MC6809
+void mall(void);
+void malter(void);
+void mimmed(void);
+void mindex(void);
+void minher(void);
+void mlong(void);
+void msstak(void);
+void mswap(void);
+void mustak(void);
+#endif /* MC6809 */
+
+void getcomma(void);
+void mshort(void);
+
+/* pops.c */
+bool_pt checksegrel(struct sym_s *symptr);
+void checkdatabounds(void);
+void datatoobig(void);
+void fatalerror(char * errorstr);
+void labelerror(char * errorstr);
+void palign(void);
+void pasciz(void);
+void pblkw(void);
+void pblock(void);
+void pbss(void);
+void pcomm(void);
+void pcomm1(void);
+void pdata(void);
+void pelse(void);
+void pelseif(void);
+void pelsifc(void);
+void pendb(void);
+void pendif(void);
+void penter(void);
+void pentry(void);
+void pequ(void);
+void peven(void);
+void pexport(void);
+void pfail(void);
+void pfcb(void);
+void pfcc(void);
+void pfdb(void);
+#if SIZEOF_OFFSET_T > 2
+void pfqb(void);
+#endif
+void pglobl(void);
+void pident(void);
+void pif(void);
+void pifc(void);
+void pimport(void);
+void plcomm(void);
+void plcomm1(void);
+void plist(void);
+void pnolist(void);
+void ploc(void);
+void pmaclist(void);
+void pmap(void);
+void porg(void);
+void prmb(void);
+void psect(void);
+void pset(void);
+void psetdp(void);
+void ptext(void);
+void puse16(void);
+void puse32(void);
+void pwarn(void);
+void showlabel(void);
+
+/* readsrc.c */
+void initsource(void);
+fd_t open_input(char *name);
+void pget(void);
+void pproceof(void);
+void readline(void);
+void skipline(void);
+
+/* scan.c */
+void context_hexconst(void);
+void getsym(void);
+void getsym_nolookup(void);
+void initscan(void);
+
+/* table.c */
+void inst_keywords(void);
+struct sym_s *lookup(void);
+void statistics(void);
+
+/* type.c */
+#if defined(__m6809__) && defined(MC6809)
+#define NATIVE_ENDIAN
+extern inline u2_pt c2u2(char *buf) { return *((u2_pt *)buf); }
+extern inline u4_t c4u4(char *buf) { return *((u4_t *)buf); }
+extern inline void u2c2(char *buf, u2_t offset) { *((unsigned short *)buf) = offset;}
+extern inline void u4c4(char *buf, u4_t offset) { *((unsigned long *)buf) = offset;}
+#else
+u2_pt c2u2(char *buf);
+u4_t c4u4(char *buf);
+void u2c2(char *buf, u2_t offset);
+void u4c4(char *buf, u32_T offset);
+#endif
+u2_pt cnu2(char *buf, unsigned count);
+u4_t cnu4(char *buf, unsigned count);
+void u2cn(char *buf, u16_pt offset, unsigned count);
+void u4cn(char *buf, u32_T offset, unsigned count);
+bool_pt typeconv_init(bool_pt big_endian, bool_pt long_big_endian);
+
+/* alloc.c */
+void * asalloc(unsigned int size);
+void * asrealloc(void * oldptr, unsigned int size);
+void * temp_buf(void);
+void init_heap(void);
+
--- /dev/null
+/* readsrc.c - read source files for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "flag.h"
+#include "file.h"
+#include "globvar.h"
+#include "macro.h"
+#include "scan.h"
+#undef EXTERN
+#define EXTERN
+#include "source.h"
+
+/*
+ * Ok, lots of hack & slash here.
+ * 1) Added BIG buffer to load entire _primary_ file into memory.
+ * 2) This means the primary file can be standard input.
+ * 3) Fixed so 'get/include' processing now works.
+ * 4) Altered for a 'normal' style buffer otherwise (MINIBUF)
+ * 5) Have the option of completely unbuffered if you need the last Kb.
+ *
+ * RDB.
+ */
+
+#if !defined(__AS386_16__) && !defined(__m6809__)
+#ifndef BIGBUFFER
+#define BIGBUFFER 1 /* For most machines we have the memory */
+#endif
+#endif
+
+#if !defined(__m6809__)
+#ifndef MINIBUF
+#define MINIBUF 1 /* Add in a reasonable buffer */
+#endif
+#endif
+
+struct get_s /* to record included files */
+{
+ fd_t fd;
+ unsigned line;
+ off_t position;
+};
+
+static char hid_filnambuf[FILNAMLEN + 1]; /* buffer for file name */
+
+static struct get_s hid_getstak[MAXGET]; /* GET stack */
+static struct get_s *getstak; /* ptr */
+
+#if BIGBUFFER == 1
+static char *mem_start = 0, *mem_end;
+#endif
+
+static char hid_linebuf[LINLEN]; /* line buffer */
+static char *eol_ptr;
+
+static char *maclinebuf;
+static char *maclineptr;
+
+#if MINIBUF == 1
+static void inp_seek(int fd, long posn);
+static long inp_tell(int fd);
+static int inp_line(int fd, char * buf, int size);
+#endif
+
+static void clearsource(void);
+static void line_too_long(void);
+
+static void clearsource(void)
+{
+}
+
+static void line_too_long(void)
+{
+ symname = linebuf + (LINLEN - 1); /* spot for the error */
+ error(LINLONG); /* so error is shown in column LINLEN - 1 */
+}
+
+/* initialise private variables */
+
+void initsource(void)
+{
+ filnamptr = hid_filnambuf;
+ getstak = hid_getstak;
+ clearsource(); /* sentinel to invoke blank skipping */
+}
+
+fd_t open_input(char *name)
+{
+ fd_t fd;
+#if BIGBUFFER == 1
+ off_t filelength = -1;
+
+ if( mem_start == 0 && strcmp(name, "-") == 0 )
+ fd = 0;
+ else
+#endif
+#ifdef O_BINARY
+ if ((unsigned) (fd = open(name, O_RDONLY|O_BINARY)) > 255)
+ as_abort("error opening input file");
+#else
+ if ((unsigned) (fd = open(name, O_RDONLY)) > 255)
+ as_abort("error opening input file");
+#endif
+
+#if BIGBUFFER == 1
+ if( mem_start == 0 )
+ {
+ size_t memsize = 0;
+ int cc;
+
+ if(fd)
+ {
+ struct stat st;
+ if( fstat(fd, &st) >= 0 )
+ filelength = st.st_size;
+ if( filelength > (((unsigned)-1)>>1)-3 )
+ {
+ mem_end = mem_start = "\n\n";
+ goto cant_do_this;
+ }
+ }
+
+ if (filelength > 0) {
+ if( (mem_start = malloc(filelength+4)) == 0 )
+ {
+ mem_end = mem_start = "\n\n";
+ goto cant_do_this;
+ }
+ memsize = filelength;
+
+ filelength = read(fd, mem_start, filelength);
+ } else
+ filelength = 0;
+
+ for(;;)
+ {
+ if( filelength >= memsize )
+ {
+ if (memsize > 16000)
+ mem_start = asrealloc(mem_start, (memsize+=16384)+4);
+ else
+ mem_start = asrealloc(mem_start, (memsize+=memsize+32)+4);
+ }
+ cc = read(fd, mem_start+filelength,
+ (size_t)(memsize-filelength));
+ if( cc <= 0 ) break;
+ filelength+=cc;
+ }
+
+ *(mem_end=mem_start+filelength) = '\n';
+ mem_end[1] = '\0';
+
+ infiln = infil0 = 0; /* Assemble from memory */
+ if(fd) close(fd);
+ fd = -1;
+ }
+cant_do_this:
+#endif
+
+ clearsource();
+ return fd;
+}
+
+/*
+ handle GET pseudo_op
+ stack state of current file, open new file and reset global state vars
+ file must be seekable for the buffer discard/restore method to work
+*/
+
+void pget(void)
+{
+ if (infiln >= MAXGET)
+ error(GETOV);
+ else
+ {
+ char save;
+
+ skipline();
+ listline();
+
+ getstak->fd = infil;
+ getstak->line = linum;
+ if (infiln != 0)
+#if MINIBUF == 1
+ getstak->position = inp_tell(infil);
+#else
+ getstak->position = lseek(infil, 0L, 1);
+#endif
+ else
+ getstak->position = (off_t)eol_ptr;
+ ++getstak;
+ ++infiln;
+ linum = 0;
+
+ for(lineptr=symname; *lineptr != EOLCHAR; lineptr++)
+ if( *lineptr <= ' ' ) break;
+ save = *lineptr; *lineptr = '\0';
+ infil = open_input(symname);
+ *lineptr = save;
+ getsym();
+ }
+}
+
+/* process end of file */
+/* close file, unstack old file if current one is included */
+/* otherwise switch pass 0 to pass 1 or exit on pass 2 */
+/* end of file may be from phyical end of file or an END statement */
+
+void pproceof(void)
+{
+ if (infiln != 0)
+ close(infil);
+ if (infiln == infil0)
+ /* all conditionals must be closed before end of main file (not GETs) */
+ {
+ if (blocklevel != 0)
+ error(EOFBLOCK);
+ if (iflevel != 0)
+ error(EOFIF);
+ if (pass && (lcdata & UNDBIT))
+ error(EOFLC);
+ lcptr->data = lcdata;
+ lcptr->lc = lc;
+ }
+ /* macros must be closed before end of all files */
+ if (macload)
+ error(EOFMAC);
+ if (linebuf != lineptr)
+ listline(); /* last line or line after last if error */
+ if (infiln != infil0)
+ {
+ --getstak;
+ infil = getstak->fd;
+ linum = getstak->line;
+ if (--infiln == 0)
+ eol_ptr = (void*)getstak->position;
+ else
+#if MINIBUF == 1
+ inp_seek(infil, getstak->position);
+#else
+ lseek(infil, getstak->position, 0);
+#endif
+ }
+ else if (pass!=last_pass)
+ {
+ pass++;
+ if( last_pass>1 && last_pass<30 && dirty_pass && pass==last_pass )
+ last_pass++;
+
+ if( pass==last_pass )
+ objheader(); /* while pass 1 data all valid */
+ binmbuf = 0; /* reset zero variables */
+ maclevel = iflevel = blocklevel =
+ totwarn = toterr = linum = macnum = 0;
+ initp1p2(); /* reset other varaiables */
+ if(pass==last_pass)
+ binaryc = binaryg;
+#ifdef I80386
+ defsize = idefsize;
+ cpuid = origcpuid;
+#endif
+ if(pass==last_pass)
+ {
+ list.current = list.global;
+ maclist.current = maclist.global;
+ as_warn.current = TRUE;
+ if (as_warn.semaphore < 0)
+ as_warn.current = FALSE;
+ }
+
+ if (infiln != 0)
+ infil = open_input(filnamptr);
+ else
+ eol_ptr=0;
+
+ if(pass==last_pass)
+ binheader();
+
+ line_zero();
+ }
+ else
+ finishup();
+}
+
+/*
+ read 1 line of source.
+ Source line ends with '\n', line returned is null terminated without '\n'.
+ Control characters other than blank, tab and newline are discarded.
+ Long lines (length > LINLEN) are truncated, and an error is generated.
+ On EOF, calls pproceof(), and gets next line unless loading a macro.
+ This is where macro lines are recursively expanded.
+*/
+
+void readline(void)
+{
+ int cc = 0;
+
+ listpre = FALSE; /* not listed yet */
+ if (maclevel != 0)
+ {
+ register char *bufptr; /* hold *bufptr in a reg char variable */
+ register char *reglineptr; /* if possible (not done here) */
+ char *oldbufptr;
+ struct schain_s *parameters;
+ char paramnum;
+ unsigned int remaining; /* space remaining in line + 2 */
+ /* value 0 not used except for temp predec */
+ /* value 1 means error already gen */
+ /* values 1 and 2 mean no space */
+
+ for (; maclevel != 0;
+ macpar = macstak->parameters, ++macstak, --maclevel)
+ if (*(bufptr = macstak->text) != ETB)
+ /* nonempty macro, process it and return without continuing the for loop */
+ {
+ if (!macflag)
+ {
+ maclinebuf = linebuf;
+ maclineptr = lineptr;
+ macflag = TRUE;
+ }
+ remaining = LINLEN + 2;
+ lineptr = linebuf = reglineptr = hid_linebuf;
+ while (*bufptr++ != EOLCHAR)
+ {
+ if (bufptr[-1] == MACROCHAR && *bufptr >= '0' && *bufptr <= '9')
+ {
+ parameters = macstak->parameters;
+ for (paramnum = *bufptr++; paramnum-- != '0';)
+ if ((parameters = parameters->next) == NUL_PTR)
+ break;
+ if (parameters != NUL_PTR)
+ {
+ for (oldbufptr = bufptr, bufptr = parameters->string;
+ *bufptr++ != 0;)
+ {
+ if (--remaining <= 1)
+ {
+ if (remaining != 0)
+ line_too_long();
+ remaining = 1;
+ break; /* forget rest, param on 1 line */
+ }
+ *reglineptr++ = bufptr[-1];
+ }
+ bufptr = oldbufptr;
+ }
+ }
+ else
+ {
+ if (--remaining <= 1)
+ {
+ if (remaining != 0)
+ line_too_long();
+ remaining = 1;
+ }
+ else
+ *reglineptr++ = bufptr[-1];
+ }
+ }
+ macstak->text = bufptr;
+#if 0
+ *reglineptr = 0;
+ printf("MLINE:%s.\n", lineptr);
+#endif
+ *reglineptr = EOLCHAR;
+ return;
+ }
+ }
+ if (macflag)
+ {
+ linebuf = maclinebuf;
+ lineptr = maclineptr;
+ macflag = FALSE;
+ }
+ /* End of macro expansion processing */
+
+again: /* On EOF for main or included files */
+ ++linum;
+
+#if BIGBUFFER == 1
+ if( infiln == 0 )
+ {
+ if( eol_ptr == 0 ) eol_ptr = mem_start-1;
+ else *eol_ptr = '\n';
+ linebuf = lineptr = eol_ptr + 1;
+ cc = (mem_end - linebuf);
+
+ /* memchr not strchr 'cause some implementations of strchr are like:
+ memchr(x,y,strlen(x)); this is _BAD_ with BIGBUFFER
+ */
+ if((eol_ptr = memchr(linebuf, '\n', cc)) == 0 && cc > 0)
+ cc = -1;
+ }
+ else
+#endif
+ {
+ lineptr = linebuf = hid_linebuf;
+ *(hid_linebuf+sizeof(hid_linebuf)-2) = '\0'; /* Term */
+
+#if MINIBUF == 1
+ cc = inp_line(infil, linebuf, sizeof(hid_linebuf)-2);
+ if( cc >= 0 )
+ eol_ptr = linebuf+cc-1;
+#else
+ cc = read(infil, linebuf, sizeof(hid_linebuf)-2);
+ if( cc > 0 )
+ {
+ eol_ptr = memchr(linebuf, '\n', cc);
+ if( eol_ptr == 0 )
+ eol_ptr = hid_linebuf+sizeof(hid_linebuf)-2;
+ else
+ lseek(infil, (long)(eol_ptr+1-hid_linebuf)-cc, 1);
+ }
+#endif
+ }
+
+ if( cc <= 0 )
+ {
+ if( cc < 0 ) as_abort("error reading input");
+
+ clearsource();
+ pproceof();
+ listpre = FALSE;
+ if (macload)
+ {
+ symname = lineptr;
+ return; /* macro not allowed across eof */
+ }
+ goto again;
+ }
+
+#if 0
+ *eol_ptr = 0;
+ printf("LINE:%s.\n", lineptr);
+#endif
+ *eol_ptr = EOLCHAR;
+}
+
+void skipline(void)
+{
+ if(macflag)
+ lineptr = strchr(hid_linebuf, EOLCHAR);
+ else
+ lineptr = eol_ptr;
+}
+
+#if MINIBUF == 1
+static char input_buf[1024]; /* input buffer */
+static int in_start=0, in_end=0;
+static long ftpos = 0;
+static int lastfd = -1;
+
+static int inp_line(int fd, char *buf, int size)
+{
+ int offt = 0;
+ if( fd!=lastfd ) inp_seek(-1, 0L);
+ for(;;)
+ {
+ if(in_start >= in_end)
+ {
+ lastfd = -1;
+ ftpos = lseek(fd, 0L, 1);
+ in_start = 0;
+ in_end = read(fd, input_buf, sizeof(input_buf));
+ if( in_end <=0 ) return in_end;
+ lastfd = fd;
+ }
+ if( (buf[offt++] = input_buf[in_start++]) == '\n' || offt >= size )
+ break;
+ }
+ return offt;
+}
+
+static long inp_tell(int fd)
+{
+ if( fd != lastfd )
+ return lseek(fd, 0L, 1);
+ else
+ return ftpos + in_start;
+}
+
+static void inp_seek(int fd, long posn)
+{
+ if( lastfd != -1 )
+ lseek(lastfd, ftpos+in_start, 0);
+ lastfd = -1;
+ in_end = 0;
+ if( fd >= 0 )
+ lseek(fd, posn, 0);
+}
+
+#endif
--- /dev/null
+/* scan.c - lexical analyser for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "globvar.h"
+#undef EXTERN
+#define EXTERN
+#include "scan.h"
+
+static int numbase; /* base for number */
+
+static char symofchar[256] = /* table to convert chars to their symbols */
+{
+ EOLSYM, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, EOLSYM, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+
+ WHITESPACE, EOLSYM, STRINGCONST, IMMEDIATE, /* !"# */
+ HEXCONST, BINCONST, ANDOP, CHARCONST, /* $%&' */
+ LPAREN, RPAREN, STAR, ADDOP, /* ()*+ */
+ COMMA, SUBOP, IDENT, SLASH, /* ,-./ */
+
+ INTCONST, INTCONST, INTCONST, INTCONST, /* 0123 */
+ INTCONST, INTCONST, INTCONST, INTCONST, /* 4567 */
+ INTCONST, INTCONST, COLON, EOLSYM, /* 89:; */
+ LESSTHAN, EQOP, GREATERTHAN, MACROARG, /* <=>? */
+
+ INDIRECT, IDENT, IDENT, IDENT, /* @ABC */
+ IDENT, IDENT, IDENT, IDENT, /* DEFG */
+ IDENT, IDENT, IDENT, IDENT, /* HIJK */
+ IDENT, IDENT, IDENT, IDENT, /* LMNO */
+ IDENT, IDENT, IDENT, IDENT, /* PQRS */
+ IDENT, IDENT, IDENT, IDENT, /* TUVW */
+ IDENT, IDENT, IDENT, LBRACKET, /* XYZ[ */
+ OTHERSYM, RBRACKET, OTHERSYM, IDENT, /* \]^_ */
+
+ OTHERSYM, IDENT, IDENT, IDENT, /* `abc */
+ IDENT, IDENT, IDENT, IDENT, /* defg */
+ IDENT, IDENT, IDENT, IDENT, /* hijk */
+ IDENT, IDENT, IDENT, IDENT, /* lmno */
+ IDENT, IDENT, IDENT, IDENT, /* pqrs */
+ IDENT, IDENT, IDENT, IDENT, /* tuvw */
+ IDENT, IDENT, IDENT, OTHERSYM, /* xyz{ */
+ OROP, OTHERSYM, NOTOP, OTHERSYM, /* |}~ */
+
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE,
+ WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE
+};
+
+static void intconst P((void));
+
+void context_hexconst(void)
+{
+ numbase = 16;
+ intconst();
+}
+
+void getsym(void)
+{
+ register char *reglineptr;
+
+ reglineptr = lineptr;
+advance:
+ symname = reglineptr;
+ switch (sym = symofchar[(unsigned char) *reglineptr++])
+ {
+ case WHITESPACE:
+ goto advance;
+ case ADDOP:
+ if (*reglineptr == '+')
+ {
+ sym = POSTINCOP;
+ ++reglineptr;
+ }
+ break;
+ case BINCONST:
+ numbase = 2;
+ lineptr = reglineptr;
+ intconst();
+ return;
+ case CHARCONST:
+ if ((number = *reglineptr) < ' ')
+ number = ' ';
+ if (*reglineptr != EOL)
+ ++reglineptr;
+ sym = INTCONST;
+ break;
+ case GREATERTHAN: /* context-sensitive */
+ if (*reglineptr == '>')
+ {
+ sym = SROP;
+ ++reglineptr;
+ }
+ break;
+ case HEXCONST:
+ numbase = 16;
+ lineptr = reglineptr;
+ intconst();
+ return;
+ case IDENT:
+ /* walk to end of identifier - magic INTCONST is max of INT, IDENT */
+ while (symofchar[(unsigned char) *reglineptr] <= INTCONST)
+ ++reglineptr;
+ lineptr = reglineptr;
+ gsymptr = lookup();
+ return;
+ case INTCONST:
+ if (*(reglineptr - 1) == '0')
+ {
+ if (*reglineptr != 'x' && *reglineptr != 'X')
+ numbase = 8;
+ else
+ {
+ numbase = 16;
+ ++reglineptr;
+ }
+ }
+ else
+ {
+ --reglineptr;
+ numbase = 10;
+ }
+ lineptr = reglineptr;
+ intconst();
+ return;
+ case LESSTHAN: /* context-sensitive */
+ if (*reglineptr == '<')
+ {
+ sym = SLOP;
+ ++reglineptr;
+ }
+ break;
+ case SUBOP:
+ if (*reglineptr == '-')
+ {
+ sym = PREDECOP;
+ ++reglineptr;
+ }
+ break;
+ }
+ lineptr = reglineptr;
+ return;
+}
+
+void getsym_nolookup(void)
+{
+ bool_t old_ifflag;
+
+ old_ifflag = ifflag;
+ ifflag = FALSE;
+ getsym();
+ ifflag = old_ifflag;
+}
+
+static void intconst(void)
+{
+ register char *reglineptr;
+
+ number = 0;
+ reglineptr = lineptr;
+ for (; *reglineptr >= '0'; ++reglineptr)
+ {
+ if (*reglineptr > '9')
+ {
+ if (numbase != 16)
+ break;
+ if (*reglineptr >= 'a' && *reglineptr <= 'f')
+ {
+ if (number != 0)
+ number = numbase * number + (*reglineptr - 'a' + 10);
+ else
+ number = *reglineptr - 'a' + 10;
+ }
+ else if (*reglineptr >= 'A' && *reglineptr <= 'F')
+ {
+ if (number != 0)
+ number = numbase * number + (*reglineptr - 'A' + 10);
+ else
+ number = *reglineptr - 'A' + 10;
+ }
+ else
+ break;
+ }
+ else if (number != 0)
+ number = numbase * number + (*reglineptr - '0');
+ else
+ number = *reglineptr - '0';
+ }
+ if (*reglineptr == 'L' || *reglineptr == 'l')
+ ++reglineptr;
+ sym = INTCONST;
+ lineptr = reglineptr;
+}
+
+void initscan(void)
+{
+#ifndef MC6809
+ if (asld_compatible)
+ {
+ lindirect = LPAREN;
+ rindexp = RPEXP;
+ rindirect = RPAREN;
+ }
+ else
+ {
+#endif
+ lindirect = LBRACKET;
+ rindexp = RBEXP;
+ rindirect = RBRACKET;
+#ifndef MC6809
+ }
+#endif
+}
--- /dev/null
+/* scan.h - global variables for scanner for assembler */
+
+#define EOLCHAR '\n'
+
+EXTERN struct sym_s *gsymptr; /* global symbol ptr */
+EXTERN char lindirect; /* left symbol for indirect addressing */
+EXTERN char *lineptr; /* current line position */
+EXTERN offset_t number; /* constant number */
+EXTERN char * rindexp; /* error code for missing rindirect */
+EXTERN char rindirect; /* right symbol for indirect addressing */
+EXTERN char sym; /* current symbol */
+EXTERN char *symname; /* current symbol name */
--- /dev/null
+/* 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 */
--- /dev/null
+
+#ifndef POSIX_HEADERS_MISSING
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#endif
+
+#ifndef STDC_HEADERS_MISSING
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#endif
+
+#ifdef MSDOS
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <io.h>
+#undef min
+#undef POSIX_HEADERS_MISSING
+#define VERSION "MSDOS Compile"
+#endif
+
+#if __STDC__ && !defined(__minix)
+#define P(x) x
+#else
+#define P(x) ()
+#endif
+
+#ifdef STDC_HEADERS_MISSING
+char *strcpy P((char *s1, const char *s2));
+char *strrchr P((const char *s, int c));
+int memcmp P((const void *s1, const void *s2, unsigned n));
+int strcmp P((const char *s1, const char *s2));
+int strncmp P((const char *s1, const char *s2, unsigned n));
+unsigned strlen P((const char *s));
+void *malloc P((unsigned size));
+void *memset P((void *s, int c, unsigned n));
+void exit P((int status));
+#endif
+
+#ifdef POSIX_HEADERS_MISSING
+int close P((int fd));
+int creat P((const char *path, int mode));
+int open P((const char *path, int oflag, ...));
+int read P((int fd, void *buf, unsigned nbytes));
+int write P((int fd, const void *buf, unsigned nbytes));
+typedef long off_t;
+off_t lseek P((int fd, off_t offset, int whence));
+#define BIGBUFFER 0 /* Can't use a big buffer ... sorry */
+#endif
+
+#ifndef O_RDONLY
+#define O_RDONLY 0
+#endif
+#ifndef O_WRONLY
+#define O_WRONLY 1
+#endif
+#ifndef O_RDWR
+#define O_RDWR 2
+#endif
--- /dev/null
+/* table.c - keyword tables and symbol table lookup for assembler */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "globvar.h"
+#include "opcode.h"
+#include "scan.h"
+
+#define hconv(ch) ((unsigned char) (ch) - 0x41) /* better form for hashing */
+
+#ifdef I80386
+# ifdef MNSIZE
+EXTERN char bytesizeops[];
+# endif
+#endif
+EXTERN char ops[];
+EXTERN char page1ops[];
+EXTERN char page2ops[];
+EXTERN char regs[];
+#ifdef I80386
+EXTERN char typesizes[];
+#endif
+
+#ifdef DEBUG_HASH
+unsigned nhash;
+unsigned nlookup;
+unsigned nsym;
+unsigned nx[30];
+static void printchain P((void));
+#endif
+
+static void install P((register char *keyptr, unsigned char data));
+
+void inst_keywords()
+{
+ install(regs, REGBIT);
+#ifdef I80386
+ install(typesizes, SIZEBIT);
+#endif
+ install(ops, 0);
+ install(page1ops, PAGE1);
+ install(page2ops, PAGE2);
+#ifdef I80386
+# ifdef MNSIZE
+ install(bytesizeops, PAGE1 | PAGE2);
+# endif
+#endif
+}
+
+static void install(register char *keyptr, unsigned char data)
+{
+ char lowcasebuf[20];
+ unsigned namelength;
+ char *nameptr;
+ char *namend;
+ register struct sym_s *symptr;
+
+ while (*keyptr != 0)
+ {
+ namelength = *keyptr++;
+ lineptr = (symname = keyptr) + namelength;
+ for (nameptr = lowcasebuf, namend = lowcasebuf + namelength;
+ nameptr < namend;)
+ {
+ if (*keyptr < 'A' || *keyptr > 'Z')
+ *nameptr++ = *keyptr++;
+ else
+ *nameptr++ = *keyptr++ + ('a' - 'A');
+ }
+ symptr = lookup();
+ symptr->type = MNREGBIT;
+ symptr->data = data;
+ symptr->value_reg_or_op.op.routine = *keyptr;
+ symptr->value_reg_or_op.op.opcode = keyptr[1];
+ lineptr = (symname = lowcasebuf) + namelength;
+ symptr = lookup();
+ symptr->type = MNREGBIT;
+ symptr->data = data;
+ symptr->value_reg_or_op.op.routine = *keyptr;
+ symptr->value_reg_or_op.op.opcode = keyptr[1];
+ keyptr += 2;
+ }
+}
+
+/* Lookup() searches symbol table for the string from symname to lineptr - 1.
+ * If string is not found and ifflag is TRUE, string is added to table, with
+ * type = 0
+ * data = inidata (RELBIT | UNDBIT, possibly with IMPBIT | SEGM)
+ * Returns pointer to symbol entry (NUL_PTR if not found and not installed)
+ * unless symbol table overflows, when routine aborts.
+ */
+
+struct sym_s *lookup(void)
+{
+ struct sym_s **hashptr;
+ register char *nameptr;
+ register struct sym_s *symptr;
+ register unsigned hashval;
+ register unsigned length;
+#ifdef DEBUG_HASH
+ int tries;
+
+ ++nlookup;
+ tries = 0;
+#endif
+
+ /* Hash function is a weighted xor of 1 to 4 chars in the string.
+ * This works seems to work better than looking at all the chars.
+ * It is important that the function be fast.
+ * The string comparision function should also be fast and it helps
+ * if it is optimized for mostly identical comparisions.
+ * The multiplication by MULTIPLIER should compile as a shift.
+ */
+
+#define MULTIPLIER (SPTSIZ / (1 << USEFUL_BITS_IN_ASCII))
+#define USEFUL_BITS_IN_ASCII 6
+
+ nameptr = lineptr;
+ length = nameptr - symname;
+ if (length <= 3)
+ {
+ if (length <= 2)
+ hashval = hconv(nameptr[-1]) * MULTIPLIER;
+ else
+ hashval = hconv(nameptr[-2]) * MULTIPLIER,
+ hashval ^= hconv(nameptr[-1]);
+ }
+ else
+ hashval = hconv(symname[length-(length / 2)]) * MULTIPLIER,
+ hashval ^= hconv(nameptr[-2]) << 2,
+ hashval ^= hconv(nameptr[-1]);
+ nameptr = symname;
+ if ((symptr = *(hashptr = spt +
+ (hashval ^ (hconv(nameptr[0]) << 1)) % SPTSIZ))
+ != NUL_PTR)
+ {
+ do
+ {
+#ifdef DEBUG_HASH
+ if (tries != 0)
+ --nx[tries];
+ ++tries;
+ if (tries < sizeof nx / sizeof nx[0])
+ ++nx[tries];
+ if (tries >= 5)
+ printchain(hashptr - spt);
+#endif
+ if ((unsigned char) length != symptr->length)
+ continue;
+ if (memcmp(symptr->name, nameptr, length) == 0)
+ return symptr;
+ }
+ while ((symptr = symptr->next) != NUL_PTR);
+
+ /* Calculate last non-NUL_PTR hash ptr.
+ * This is faster than keeping hashptr up to date in previous loop
+ * since most lookups are successful and hash ptr is not needed.
+ */
+ do
+ {
+ symptr = *hashptr;
+ hashptr = &symptr->next;
+ }
+ while (symptr->next != NUL_PTR);
+ }
+ if (!ifflag)
+ return NUL_PTR;
+#ifdef DEBUG_HASH
+ ++nsym;
+ if (hashptr >= spt && hashptr < spt + SPTSIZ)
+ ++nhash;
+#endif
+ *hashptr = symptr = asalloc(sizeof(struct sym_s) + length);
+ symptr->type = 0;
+ symptr->data = inidata;
+ symptr->length = length;
+ symptr->value_reg_or_op.value = (offset_t) (symptr->next = NUL_PTR);
+ memcpy(symptr->name, nameptr, length);
+ symptr->name[length] = 0;
+ return symptr;
+}
+
+#ifdef DEBUG_HASH
+
+static void printchain(unsigned hashval)
+{
+ register struct sym_s *symptr;
+
+ printf("%04x ", hashval);
+ for (symptr = spt[hashval]; symptr != NUL_PTR; symptr = symptr->next)
+ printf("%s ", symptr->name);
+ printf("\n");
+}
+
+#endif
+
+void statistics(void)
+{
+#ifdef DEBUG_HASH
+ int i;
+ int weight;
+
+ for (i = 0; i < SPTSIZ; ++i)
+ printchain(i);
+ printf("nhash = %d, nsym = %d, nlookup = %d nx =\n", nhash, nsym, nlookup);
+ weight = 0;
+ for (i = 0; i < 30; ++i)
+ {
+ printf("%5d", nx[i]);
+ weight += nx[i] * i;
+ }
+ printf("\n");
+ printf("weight = %d%d\n", weight);
+#endif
+}
--- /dev/null
+/* type.h - types for assembler */
+
+typedef unsigned short u2_t;
+typedef unsigned u2_pt;
+typedef unsigned long u4_t;
+typedef unsigned long u4_pt;
+
+/* redefine foo_t's because their use has become non-portable */
+
+#define bool_t bool_T
+#define count_t count_T
+#define fd_t fd_T
+#define indcount_t indcount_T
+#define offset_t offset_T
+#define opcode_t opcode_T
+#define opsize_t opsize_T
+#define scale_t scale_T
+#define sem_t sem_T
+#define smallcount_t smallcount_T
+#define soffset_t soffset_T
+
+typedef unsigned char bool_t;
+typedef int bool_pt;
+typedef unsigned count_t;
+typedef int fd_t;
+typedef unsigned char indcount_t;
+#ifdef I80386
+typedef unsigned long offset_t;
+typedef long soffset_t;
+# define SIZEOF_OFFSET_T 4 /* non-portable */
+#endif
+#ifdef MC6809
+typedef unsigned offset_t;
+typedef int soffset_t;
+# define SIZEOF_OFFSET_T 2 /* but sizeof (offset_t) often breaks cpp */
+#endif
+typedef int opcode_pt;
+typedef unsigned char opcode_t;
+typedef int opsize_pt;
+typedef unsigned char opsize_t;
+typedef unsigned reg_pt;
+typedef unsigned char scale_t;
+typedef unsigned char smallcount_t;
+typedef /* signed */ char sem_t;
+typedef unsigned u16_pt;
+typedef unsigned short u16_T;
+typedef unsigned long u32_T;
+
+/* symbol table entry */
+
+struct sym_s
+{
+ struct sym_s *next; /* next symbol in hash chain (NUL_PTR if none) */
+ /* zero offset because it is accessed most */
+ unsigned char type;
+ unsigned char data; /* flags valid for expressions as well as syms*/
+ union
+ {
+ offset_t value; /* value, if sym is a label */
+ unsigned char reg; /* register code, if sym is a register */
+ struct
+ {
+ unsigned char routine; /* routine number */
+ opcode_t opcode; /* opcode, if sym is a hardware op */
+ }
+ op; /* if sym is pseudo-op or hardware op */
+ }
+ value_reg_or_op;
+ unsigned char length; /* length of symbol string */
+ char name[1]; /* string of variable length */
+};
+
+/* address */
+
+struct address_s
+{
+ offset_t offset;
+ unsigned char data;
+ struct sym_s *sym;
+};
+
+#ifdef I80386
+
+/* effective address */
+
+struct ea_s
+{
+ indcount_t indcount;
+ opsize_t size;
+ reg_pt base;
+ reg_pt index;
+ scale_t scale;
+ struct address_s displ;
+};
+
+#endif
+
+/* flags */
+
+struct flags_s
+{
+ bool_t global;
+ bool_t current;
+ int semaphore;
+};
+
+/* location counter */
+
+struct lc_s
+{
+ unsigned char data;
+ offset_t lc;
+};
+
+/* string chain */
+
+struct schain_s
+{
+ struct schain_s *next;
+ char string[2]; /* variable length */
+};
+
+/* block stack */
+
+struct block_s
+{
+ unsigned char data;
+ unsigned char dp;
+ offset_t lc;
+};
+
+/* if stack */
+
+struct if_s
+{
+ bool_t ifflag;
+ bool_t elseflag;
+};
+
+/* macro stack */
+
+struct macro_s
+{
+ char *text;
+ struct schain_s *parameters;
+};
+
+/* symbol listing format */
+
+struct sym_listing_s
+{
+ char name[SYMLIS_NAMELEN];
+ char zname[2];
+ char segm[1];
+ char pad1[1];
+ char value[4];
+ char pad2[1];
+ char ar[1];
+ char pad3[1];
+ char cein[1];
+ char pad4[1];
+ char nullterm;
+};
+
+#if __STDC__
+typedef void (*pfv)(void);
+#else
+typedef void (*pfv)();
+#endif
+
+#include "proto.h"
--- /dev/null
+
+/*
+ * Type conversion routines, these have been rewritten for portability.
+ *
+ * The only requirement is now that the u2_t and u4_t must be big enough.
+ */
+
+#include "syshead.h"
+#include "const.h"
+#include "type.h"
+#include "globvar.h"
+
+#if defined(__m6809__) && defined(MC6809)
+#define NATIVE_ENDIAN
+#endif
+
+void xxerr P((char *));
+void xxerr(x) char * x; { write(2, x, strlen(x)); }
+
+#ifdef __AS386_16__
+static int no_swap = 1;
+#endif
+
+static int long_off[4] = {0,1,2,3};
+static int int_off[2] = {0,1};
+
+bool_pt typeconv_init(bool_pt big_endian, bool_pt long_big_endian)
+{
+ int i;
+#ifdef __AS386_16__
+ no_swap = (!big_endian && !long_big_endian);
+#endif
+
+ for(i=0; i<4; i++) long_off[i] = i;
+ for(i=0; i<2; i++) int_off[i] = i;
+
+ if( long_big_endian )
+ {
+ i = long_off[0]; long_off[0] = long_off[2]; long_off[2] = i;
+ i = long_off[1]; long_off[1] = long_off[3]; long_off[3] = i;
+ }
+ if( big_endian )
+ {
+ i = long_off[2]; long_off[2] = long_off[3]; long_off[3] = i;
+ i = long_off[0]; long_off[0] = long_off[1]; long_off[1] = i;
+
+ i = int_off[0]; int_off[0] = int_off[1]; int_off[1] = i;
+ }
+ return 1;
+}
+
+void u2c2(char *buf, u2_t offset)
+{
+#ifdef __AS386_16__
+ if( no_swap )
+ {
+ *((unsigned short*)buf) = offset; /* UNALIGNED ACCESS! */
+ return;
+ }
+#endif
+ buf[int_off[0]] = offset;
+ buf[int_off[1]] = (offset>>8);
+}
+
+void u4c4(char *buf, u4_t offset)
+{
+ int i;
+#ifdef __AS386_16__
+ if( no_swap )
+ {
+ *((unsigned long*)buf) = offset; /* UNALIGNED ACCESS! */
+ return;
+ }
+#endif
+ for(i=0; i<4; i++)
+ {
+ buf[long_off[i]] = offset;
+ offset >>= 8;
+ }
+}
+
+void u4cn(char *buf, u4_t offset, unsigned count)
+{
+ switch(count)
+ {
+ case 1:
+ buf[0] = (char) offset;
+ return;
+ case 2:
+ u2c2(buf, (u2_pt) offset);
+ return;
+ case 4:
+ u4c4(buf, (u4_t) offset);
+ return;
+ default:
+ xxerr("WARNING: typeconv.c(u4cn) illegal count\n");
+ return;
+ }
+}
+
+void u2cn(char *buf, u2_pt offset, unsigned count)
+{
+ switch(count)
+ {
+ case 1:
+ buf[0] = (char) offset;
+ return;
+ case 2:
+ u2c2(buf, (u2_pt) offset);
+ return;
+ case 4:
+ u4c4(buf, (u4_t) offset);
+ return;
+ default:
+ xxerr("WARNING: typeconv.c(u2cn) illegal count\n");
+ return;
+ }
+}
+
+u2_pt c2u2(char *buf)
+{
+ u2_pt res;
+#ifdef __AS386_16__
+ if( no_swap ) return *((u2_pt *)buf); /* UNALIGNED ACCESS! */
+#endif
+
+ res = ((unsigned char *)buf) [int_off[0]]
+ + ((((unsigned char *)buf) [int_off[1]]) << 8);
+ return res;
+}
+
+u4_t c4u4(char *buf)
+{
+ u4_t res;
+ int i;
+#ifdef __AS386_16__
+ if( no_swap ) return *((u4_t *)buf); /* UNALIGNED ACCESS! */
+#endif
+ res = 0;
+ for(i=3; i>=0; i--)
+ {
+ res = (res<<8) + ((unsigned char *)buf) [long_off[i]];
+ }
+ return res;
+}
+
+u4_t cnu4(char *buf, unsigned count)
+{
+ switch (count)
+ {
+ case 0:
+ return 0;
+ case 1:
+ return buf[0] & 0xFF;
+ case 2:
+ return c2u2(buf);
+ case 4:
+ return c4u4(buf);
+ default:
+ xxerr("WARNING: typeconv.c(cnu4) illegal count\n");
+ return 0;
+ }
+}
+
+u2_pt cnu2(char *buf, unsigned count)
+{
+ switch (count)
+ {
+ case 0:
+ return 0;
+ case 1:
+ return buf[0] & 0xFF;
+ case 2:
+ return c2u2(buf);
+ case 4:
+ return (u2_pt) c4u4(buf);
+ default:
+ xxerr("WARNING: typeconv.c(cnu2) illegal count\n");
+ return 0;
+ }
+}
--- /dev/null
+#define VERSION "0.16.21"