diff --git a/Makefile b/Makefile
index 3f4a66716..707af8f1d 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@
 
 # What platform to build for by default?
 
-DEFAULT_PLATFORM ?= pc86
+DEFAULT_PLATFORM ?= pc65oo2
 
 # Where should the ACK put its temporary files?
 
@@ -40,7 +40,7 @@ LUA ?= lua
 # Which build system to use; use 'ninja' or 'make' (in lower case). Leave
 # blank to autodetect.
 
-BUILDSYSTEM ?=
+BUILDSYSTEM ?= make
 
 # Build flags for ninja.
 
diff --git a/build.lua b/build.lua
index 418bc7dc0..3698d949b 100644
--- a/build.lua
+++ b/build.lua
@@ -6,27 +6,10 @@ vars.ackcflags = {
 }
 vars.ackldflags = {}
 vars.plats = {
-	"cpm",
-	"linux386",
-	"linux68k",
-	"linuxppc",
-	"linuxmips",
-	"msdos86",
-	"msdos386",
-	"osx386",
-	"osxppc",
-	"pc86",
-	"rpi",
-	"pdpv7",
-	"em22",
+	"pc65oo2",
 }
 vars.plats_with_tests = {
-	"cpm",
-	"linux68k",
-	--"linux386",
-	"linuxppc",
-	--"linuxmips",
-	"pc86",
+	"pc65oo2",
 }
 
 local is_windows = os.getenv("OS") == "Windows_NT"
@@ -41,7 +24,7 @@ installable {
 	map = {
 		"lang/basic/src+pkg",
 		"lang/cem/cemcom.ansi+pkg",
-		"lang/m2/comp+pkg",
+		--"lang/m2/comp+pkg",
 		"lang/pc/comp+pkg",
 		"lang/b/compiler+pkg",
 		"util/ack+pkg",
diff --git a/lib/m65oo2/descr b/lib/m65oo2/descr
new file mode 100644
index 000000000..722fc4390
--- /dev/null
+++ b/lib/m65oo2/descr
@@ -0,0 +1,63 @@
+# $Revision$
+var w=4
+var p=4
+var s=2
+var l=4
+var f=4
+var d=8
+var NAME=m65oo2
+var M=m65oo2
+var LIB=lib/{M}/tail_
+var RT=lib/{M}/head_
+var CPP_F=-D__unix -D__USG
+var ALIGN=-a0:2 -a1:2 -a2:2 -a3:2
+var C_LIB={EM}/{LIB}cc.1s {EM}/{LIB}cc.2g
+var OLD_C_LIB={C_LIB}
+var MACHOPT_F=-m8
+name be
+	from .m.g
+	to .s
+	program {EM}/lib.bin/{M}/ncg
+	args <
+	stdout
+	need .e
+end
+name as
+	from .s.so
+	to .o
+	program {EM}/lib.bin/{M}/as
+	args - -o > <
+	prep cond
+end
+name led
+	from .o.a
+	to .out
+	program {EM}/lib.bin/em_led
+	mapflag -l* LNAME={EM}/{LIB}*
+	mapflag -i SEPID=-b1:0
+	mapflag -fp FLOATS={EM}/{ILIB}fp
+	mapflag -ansi C_LIB={EM}/{LIB}ac
+	args {ALIGN} {SEPID?} (.e:{HEAD}={EM}/{RT}em) \
+		({RTS}:.ocm.bas={EM}/{RT}cc) \
+		({RTS}{ANSI?}:.c={EM}/{RT}cc) \
+		({RTS}{ANSI?}:.cansi={EM}/{RT}ac) \
+		({RTS}:.mod={EM}/{RT}m2) \
+		({RTS}:.p={EM}/{RT}pc) \
+		-o > < \
+		(.p:{TAIL}={EM}/{LIB}pc) \
+		(.bas:{TAIL}={EM}/{LIB}bc) \
+		(.mod:{TAIL}={EM}/{LIB}m2) \
+		(.ocm:{TAIL}={EM}/{LIB}ocm) \
+		(.ocm.bas:{TAIL}={OLD_C_LIB}) \
+		(.c:{TAIL}={C_LIB}) \
+		{FLOATS?} \
+		(.e:{TAIL}={EM}/{LIB}em {EM}/{LIB}mon {EM}/lib/{M}/end_em)
+	linker
+end
+name cv
+	from .out
+	to .cv
+	program {EM}/lib.bin/{M}/cv
+	args < >
+	outfile a.out
+end
diff --git a/mach/m65oo2/Action b/mach/m65oo2/Action
new file mode 100644
index 000000000..14beb6e1c
--- /dev/null
+++ b/mach/m65oo2/Action
@@ -0,0 +1,21 @@
+name "Intel 8086 assembler"
+dir as
+end
+name "Intel 8086 backend"
+dir ncg
+end
+name "Intel 8086 EM library"
+dir libem
+end
+name "Intel 8086 etext,edata,end library"
+dir libend
+end
+name "Intel 8086 floating point library"
+dir libfp
+end
+name "Intel 8086 PC/IX systemcall library"
+dir libsys
+end
+name "Intel 8086 conversion program from ack.out --> PC/IX a.out"
+dir cv
+end
diff --git a/mach/m65oo2/as/build.lua b/mach/m65oo2/as/build.lua
new file mode 100644
index 000000000..788b76863
--- /dev/null
+++ b/mach/m65oo2/as/build.lua
@@ -0,0 +1,12 @@
+bundle {
+	name = "headers",
+	srcs = {
+		"./mach0.c",
+		"./mach1.c",
+		"./mach2.c",
+		"./mach3.c",
+		"./mach4.c",
+		"./mach5.c",
+	}
+}
+
diff --git a/mach/m65oo2/as/mach0.c b/mach/m65oo2/as/mach0.c
new file mode 100644
index 000000000..fc69730c9
--- /dev/null
+++ b/mach/m65oo2/as/mach0.c
@@ -0,0 +1,18 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
+#define RCSID0 "$Id$"
+
+/*
+ * INTEL 8086 options
+ */
+#define	THREE_PASS	/* branch and offset optimization */
+#define	LISTING		/* enable listing facilities */
+#define RELOCATION	/* generate relocation info */
+#define DEBUG 0
+
+#undef ALIGNWORD
+#define ALIGNWORD 2
+#undef ALIGNSECT
+#define ALIGNSECT 2
diff --git a/mach/m65oo2/as/mach1.c b/mach/m65oo2/as/mach1.c
new file mode 100644
index 000000000..b7f0e4cd9
--- /dev/null
+++ b/mach/m65oo2/as/mach1.c
@@ -0,0 +1,63 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
+#define RCSID1 "$Id$"
+
+/*
+ * INTEL 8086 C declarations
+ */
+
+#define	low6(z)		(z & 077)
+#define	fit6(z)		(low6(z) == z)
+#define	low3(z)		(z & 07)
+#define	fit3(z)		(low3(z) == z)
+
+#define FESC	0xD8		/* escape for 8087 processor */
+extern int	mrg_1,mrg_2;
+extern expr_t	exp_1,exp_2;
+#ifndef ASLD
+extern int	rel_1, rel_2;
+#endif
+
+#ifndef extern
+extern char	sr_m[8];
+#else
+char	sr_m[8] = {
+	-1,	-1,	-1,	7,	-1,	6,	4,	5
+};
+#endif
+
+#ifndef extern
+extern char	dr_m[8][8];
+#else
+char	dr_m[8][8] = {
+	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,
+	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,
+	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,
+	-1,	-1,	-1,	-1,	-1,	-1,	0,	1,
+	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,
+	-1,	-1,	-1,	-1,	-1,	-1,	2,	3,
+	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,
+	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1
+};
+#endif
+
+void encode_imm(int opc, int sz, expr_t exp);
+/* 8086 specific routines */
+void ea_1(int param);
+void ea_2(int param);
+void reverse(void);
+void badsyntax(void);
+void regsize(register int sz);
+void indexed(void);
+void branch(register int opc,expr_t exp);
+void pushop(register int opc);
+void addop(register int opc);
+void rolop(register int opc);
+void incop(register int opc);
+void callop(register int opc);
+void xchg(register int opc);
+void test(register int opc);
+void mov(register int opc);
+void imul(int opc);
diff --git a/mach/m65oo2/as/mach2.c b/mach/m65oo2/as/mach2.c
new file mode 100644
index 000000000..fd5c7172e
--- /dev/null
+++ b/mach/m65oo2/as/mach2.c
@@ -0,0 +1,62 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
+#define RCSID2 "$Id$"
+
+/*
+ * INTEL 8086 tokens
+ */
+
+%token <y_word> SIZE
+%token <y_word> REG_acc
+%token <y_word> OP_impl
+%token <y_word> OP_rel
+%token <y_word> OP_imm
+%token <y_word> OP_x_ind
+%token <y_word> OP_ind_y
+%token <y_word> OP_ind
+%token <y_word> OP_acc
+%token <y_word> OP_abs
+%token <y_word> OP_abs_y
+%token <y_word> OP_abs_x
+
+%token <y_word> R16
+%token <y_word> R8
+%token <y_word> RSEG
+%token <y_word> PREFIX
+%token <y_word> NOOP_1
+%token <y_word> NOOP_2
+%token <y_word> JOP
+%token <y_word> PUSHOP
+%token <y_word> IOOP
+%token <y_word> ADDOP
+%token <y_word> ROLOP
+%token <y_word> INCOP
+%token <y_word> NOTOP
+%token <y_word> CALLOP
+%token <y_word> CALFOP
+%token <y_word> LEAOP
+%token <y_word> ARPLOP
+%token <y_word> ESC
+%token <y_word> INT
+%token <y_word> RET
+%token <y_word> XCHG
+%token <y_word> TEST
+%token <y_word> MOV
+
+/* Intel 80268 tokens */
+%token <y_word> IMUL
+%token <y_word> ENTER
+%token <y_word> EXTOP
+%token <y_word> EXTOP1
+
+/* Intel 8087 coprocessor tokens */
+%token <y_word> FNOOP
+%token <y_word> FMEM
+%token <y_word> FST_I
+%token <y_word> FST_ST
+%token <y_word> FST_ST2
+%token <y_word> ST
+
+%type <y_valu> st_i
diff --git a/mach/m65oo2/as/mach3.c b/mach/m65oo2/as/mach3.c
new file mode 100644
index 000000000..c8f8bae0e
--- /dev/null
+++ b/mach/m65oo2/as/mach3.c
@@ -0,0 +1,448 @@
+{0, SIZE,       0x00,   ".b"},
+{0, SIZE,       0x01,   ".w"},
+{0, SIZE,       0x02,   ".d"},
+{0, SIZE,       0x04,   ".ub"},
+{0, SIZE,       0x05,   ".uw"},
+
+{0, REG_acc,    0x00,   "a"},
+
+{0, OP_impl,    0x00,   "brk"},
+{0, OP_x_ind,   0x01,   "ora"},
+{0, OP_impl,    0x08,   "php"},
+{0, OP_imm,     0x09,   "ora"},
+{0, OP_acc,     0x0A,   "asl"},
+{0, OP_abs,     0x0D,   "ora"},
+{0, OP_abs,     0x0E,   "asl"},
+{0, OP_rel,     0x10,   "bpl"},
+{0, OP_ind_y,   0x11,   "ora"},
+{0, OP_impl,    0x18,   "clc"},
+{0, OP_abs_y,   0x19,   "ora"},
+{0, OP_abs_x,   0x1D,   "ora"},
+{0, OP_abs_x,   0x1E,   "asl"},
+{0, OP_abs,     0x20,   "jsr"},
+{0, OP_x_ind,   0x21,   "and"},
+{0, OP_impl,    0x28,   "plp"},
+{0, OP_imm,     0x29,   "and"},
+{0, OP_acc,     0x2A,   "rol"},
+{0, OP_abs,     0x2C,   "bit"},
+{0, OP_abs,     0x2D,   "and"},
+{0, OP_abs,     0x2E,   "rol"},
+{0, OP_rel,     0x30,   "bmi"},
+{0, OP_ind_y,   0x31,   "and"},
+{0, OP_impl,    0x38,   "sec"},
+{0, OP_abs_y,   0x39,   "and"},
+{0, OP_abs_x,   0x3D,   "and"},
+{0, OP_abs_x,   0x3E,   "rol"},
+{0, OP_impl,    0x40,   "rti"},
+{0, OP_x_ind,   0x41,   "eor"},
+{0, OP_impl,    0x48,   "pha"},
+{0, OP_imm,     0x49,   "eor"},
+{0, OP_acc,     0x4A,   "lsr"},
+{0, OP_abs,     0x4C,   "jmp"},
+{0, OP_abs,     0x4D,   "eor"},
+{0, OP_abs,     0x4E,   "lsr"},
+{0, OP_rel,     0x50,   "bvc"},
+{0, OP_ind_y,   0x51,   "eor"},
+{0, OP_impl,    0x58,   "cli"},
+{0, OP_abs_y,   0x59,   "eor"},
+{0, OP_abs_x,   0x5D,   "eor"},
+{0, OP_abs_x,   0x5E,   "lsr"},
+{0, OP_impl,    0x60,   "rts"},
+{0, OP_x_ind,   0x61,   "adc"},
+{0, OP_impl,    0x68,   "pla"},
+{0, OP_imm,     0x69,   "adc"},
+{0, OP_acc,     0x6A,   "ror"},
+{0, OP_ind,     0x6C,   "jmp"},
+{0, OP_abs,     0x6D,   "adc"},
+{0, OP_abs,     0x6E,   "ror"},
+{0, OP_rel,     0x70,   "bvs"},
+{0, OP_ind_y,   0x71,   "adc"},
+{0, OP_impl,    0x78,   "sei"},
+{0, OP_abs_y,   0x79,   "adc"},
+{0, OP_abs_x,   0x7D,   "adc"},
+{0, OP_abs_x,   0x7E,   "ror"},
+{0, OP_x_ind,   0x81,   "sta"},
+{0, OP_impl,    0x88,   "dey"},
+{0, OP_impl,    0x8A,   "txa"},
+{0, OP_abs,     0x8C,   "sty"},
+{0, OP_abs,     0x8D,   "sta"},
+{0, OP_abs,     0x8E,   "stx"},
+{0, OP_rel,     0x90,   "bcc"},
+{0, OP_ind_y,   0x91,   "sta"},
+{0, OP_impl,    0x98,   "tya"},
+{0, OP_abs_y,   0x99,   "sta"},
+{0, OP_impl,    0x9A,   "txs"},
+{0, OP_abs_x,   0x9D,   "sta"},
+{0, OP_imm,     0xA0,   "ldy"},
+{0, OP_x_ind,   0xA1,   "lda"},
+{0, OP_imm,     0xA2,   "ldx"},
+{0, OP_impl,    0xA8,   "tay"},
+{0, OP_imm,     0xA9,   "lda"},
+{0, OP_impl,    0xAA,   "tax"},
+{0, OP_abs,     0xAC,   "ldy"},
+{0, OP_abs,     0xAD,   "lda"},
+{0, OP_abs,     0xAE,   "ldx"},
+{0, OP_rel,     0xB0,   "bcs"},
+{0, OP_ind_y,   0xB1,   "lda"},
+{0, OP_impl,    0xB8,   "clv"},
+{0, OP_abs_y,   0xB9,   "lda"},
+{0, OP_impl,    0xBA,   "tsx"},
+{0, OP_abs_x,   0xBC,   "ldy"},
+{0, OP_abs_x,   0xBD,   "lda"},
+{0, OP_abs_y,   0xBE,   "ldx"},
+{0, OP_imm,     0xC0,   "cpy"},
+{0, OP_x_ind,   0xC1,   "cmp"},
+{0, OP_impl,    0xC8,   "iny"},
+{0, OP_imm,     0xC9,   "cmp"},
+{0, OP_impl,    0xCA,   "dex"},
+{0, OP_abs,     0xCC,   "cpy"},
+{0, OP_abs,     0xCD,   "cmp"},
+{0, OP_abs,     0xCE,   "dec"},
+{0, OP_rel,     0xD0,   "bne"},
+{0, OP_ind_y,   0xD1,   "cmp"},
+{0, OP_impl,    0xD8,   "cld"},
+{0, OP_abs_y,   0xD9,   "cmp"},
+{0, OP_abs_x,   0xDD,   "cmp"},
+{0, OP_abs_x,   0xDE,   "dec"},
+{0, OP_imm,     0xE0,   "cpx"},
+{0, OP_x_ind,   0xE1,   "sbc"},
+{0, OP_impl,    0xE8,   "inx"},
+{0, OP_imm,     0xE9,   "sbc"},
+{0, OP_impl,    0xEA,   "nop"},
+{0, OP_abs,     0xEC,   "cpx"},
+{0, OP_abs,     0xED,   "sbc"},
+{0, OP_abs,     0xEE,   "inc"},
+{0, OP_rel,     0xF0,   "beq"},
+{0, OP_ind_y,   0xF1,   "sbc"},
+{0, OP_impl,    0xF8,   "sed"},
+{0, OP_abs_y,   0xF9,   "sbc"},
+{0, OP_abs_x,   0xFD,   "sbc"},
+{0, OP_abs_x,   0xFE,   "inc"},
+
+{0,	R16,		0,		"ax"},
+{0,	R16,		1,		"cx"},
+{0,	R16,		2,		"dx"},
+{0,	R16,		3,		"bx"},
+{0,	R16,		4,		"sp"},
+{0,	R16,		5,		"bp"},
+{0,	R16,		6,		"si"},
+{0,	R16,		7,		"di"},
+{0,	R8,			0,		"al"},
+{0,	R8,			1,		"cl"},
+{0,	R8,			2,		"dl"},
+{0,	R8,			3,		"bl"},
+{0,	R8,			4,		"ah"},
+{0,	R8,			5,		"ch"},
+{0,	R8,			6,		"dh"},
+{0,	R8,			7,		"bh"},
+{0,	RSEG,		0,		"es"},
+{0,	RSEG,		1,		"cs"},
+{0,	RSEG,		2,		"ss"},
+{0,	RSEG,		3,		"ds"},
+{0,	PREFIX,		046,		"eseg"},
+{0,	PREFIX,		056,		"cseg"},
+{0,	PREFIX,		066,		"sseg"},
+{0,	PREFIX,		076,		"dseg"},
+{0,	PREFIX,		0360,		"lock"},
+{0,	PREFIX,		0363,		"rep"},
+{0,	PREFIX,		0362,		"repne"},
+{0,	PREFIX,		0362,		"repnz"},
+{0,	PREFIX,		0363,		"repe"},
+{0,	PREFIX,		0363,		"repz"},
+{0,	NOOP_1,		047,		"daa"},
+{0,	NOOP_1,		057,		"das"},
+{0,	NOOP_1,		067,		"aaa"},
+{0,	NOOP_1,		077,		"aas"},
+{0,	NOOP_1,		0220,		"nop"},
+{0,	NOOP_1,		0230,		"cbw"},
+{0,	NOOP_1,		0231,		"cwd"},
+{0,	NOOP_1,		0233,		"wait"},
+{0,	NOOP_1,		0234,		"pushf"},
+{0,	NOOP_1,		0235,		"popf"},
+{0,	NOOP_1,		0236,		"sahf"},
+{0,	NOOP_1,		0237,		"lahf"},
+{0,	NOOP_1,		0244,		"movsb"},
+{0,	NOOP_1,		0245,		"movs"},
+{0,	NOOP_1,		0245,		"movsw"},
+{0,	NOOP_1,		0246,		"cmpsb"},
+{0,	NOOP_1,		0247,		"cmps"},
+{0,	NOOP_1,		0247,		"cmpsw"},
+{0,	NOOP_1,		0252,		"stosb"},
+{0,	NOOP_1,		0253,		"stos"},
+{0,	NOOP_1,		0253,		"stosw"},
+{0,	NOOP_1,		0254,		"lodsb"},
+{0,	NOOP_1,		0255,		"lods"},
+{0,	NOOP_1,		0255,		"lodsw"},
+{0,	NOOP_1,		0256,		"scasb"},
+{0,	NOOP_1,		0257,		"scas"},
+{0,	NOOP_1,		0257,		"scasw"},
+{0,	NOOP_1,		0316,		"into"},
+{0,	NOOP_1,		0317,		"iret"},
+{0,	NOOP_1,		0327,		"xlat"},
+{0,	NOOP_1,		0364,		"hlt"},
+{0,	NOOP_1,		0365,		"cmc"},
+{0,	NOOP_1,		0370,		"clc"},
+{0,	NOOP_1,		0371,		"stc"},
+{0,	NOOP_1,		0372,		"cli"},
+{0,	NOOP_1,		0373,		"sti"},
+{0,	NOOP_1,		0374,		"cld"},
+{0,	NOOP_1,		0375,		"std"},
+{0,	NOOP_2,		0324+012<<8,	"aam"},
+{0,	NOOP_2,		0325+012<<8,	"aad"},
+{0,	JOP,		0340,		"loopne"},
+{0,	JOP,		0340,		"loopnz"},
+{0,	JOP,		0341,		"loope"},
+{0,	JOP,		0341,		"loopz"},
+{0,	JOP,		0342,		"loop"},
+{0,	JOP,		0343,		"jcxz"},
+{0,	JOP,		0160,		"jo"},
+{0,	JOP,		0161,		"jno"},
+{0,	JOP,		0162,		"jb"},
+{0,	JOP,		0162,		"jc"},
+{0,	JOP,		0162,		"jnae"},
+{0,	JOP,		0163,		"jae"},
+{0,	JOP,		0163,		"jnb"},
+{0,	JOP,		0163,		"jnc"},
+{0,	JOP,		0164,		"je"},
+{0,	JOP,		0164,		"jz"},
+{0,	JOP,		0165,		"jne"},
+{0,	JOP,		0165,		"jnz"},
+{0,	JOP,		0166,		"jbe"},
+{0,	JOP,		0166,		"jna"},
+{0,	JOP,		0167,		"ja"},
+{0,	JOP,		0167,		"jnbe"},
+{0,	JOP,		0170,		"js"},
+{0,	JOP,		0171,		"jns"},
+{0,	JOP,		0172,		"jp"},
+{0,	JOP,		0172,		"jpe"},
+{0,	JOP,		0173,		"jnp"},
+{0,	JOP,		0173,		"jpo"},
+{0,	JOP,		0174,		"jl"},
+{0,	JOP,		0174,		"jnge"},
+{0,	JOP,		0175,		"jge"},
+{0,	JOP,		0175,		"jnl"},
+{0,	JOP,		0176,		"jle"},
+{0,	JOP,		0176,		"jng"},
+{0,	JOP,		0177,		"jg"},
+{0,	JOP,		0177,		"jnle"},
+{0,	PUSHOP,		0,			"push"},
+{0,	PUSHOP,		1,			"pop"},
+{0,	IOOP,		0344,		"inb"},
+{0,	IOOP,		0345,		"in"},
+{0,	IOOP,		0345,		"inw"},
+{0,	IOOP,		0346,		"outb"},
+{0,	IOOP,		0347,		"out"},
+{0,	IOOP,		0347,		"outw"},
+{0,	ADDOP,		000,		"addb"},
+{0,	ADDOP,		001,		"add"},
+{0,	ADDOP,		010,		"orb"},
+{0,	ADDOP,		011,		"or"},
+{0,	ADDOP,		020,		"adcb"},
+{0,	ADDOP,		021,		"adc"},
+{0,	ADDOP,		030,		"sbbb"},
+{0,	ADDOP,		031,		"sbb"},
+{0,	ADDOP,		040,		"andb"},
+{0,	ADDOP,		041,		"and"},
+{0,	ADDOP,		050,		"subb"},
+{0,	ADDOP,		051,		"sub"},
+{0,	ADDOP,		060,		"xorb"},
+{0,	ADDOP,		061,		"xor"},
+{0,	ADDOP,		070,		"cmpb"},
+{0,	ADDOP,		071,		"cmp"},
+{0,	ROLOP,		000,		"rolb"},
+{0,	ROLOP,		001,		"rol"},
+{0,	ROLOP,		010,		"rorb"},
+{0,	ROLOP,		011,		"ror"},
+{0,	ROLOP,		020,		"rclb"},
+{0,	ROLOP,		021,		"rcl"},
+{0,	ROLOP,		030,		"rcrb"},
+{0,	ROLOP,		031,		"rcr"},
+{0,	ROLOP,		040,		"salb"},
+{0,	ROLOP,		040,		"shlb"},
+{0,	ROLOP,		041,		"sal"},
+{0,	ROLOP,		041,		"shl"},
+{0,	ROLOP,		050,		"shrb"},
+{0,	ROLOP,		051,		"shr"},
+{0,	ROLOP,		070,		"sarb"},
+{0,	ROLOP,		071,		"sar"},
+{0,	INCOP,		000,		"incb"},
+{0,	INCOP,		001,		"inc"},
+{0,	INCOP,		010,		"decb"},
+{0,	INCOP,		011,		"dec"},
+{0,	NOTOP,		020,		"notb"},
+{0,	NOTOP,		021,		"not"},
+{0,	NOTOP,		030,		"negb"},
+{0,	NOTOP,		031,		"neg"},
+{0,	NOTOP,		040,		"mulb"},
+{0,	NOTOP,		041,		"mul"},
+{0,	NOTOP,		050,		"imulb"},
+{0,	IMUL,		051,		"imul"},		/* for 80286 */
+{0,	NOTOP,		060,		"divb"},
+{0,	NOTOP,		061,		"div"},
+{0,	NOTOP,		070,		"idivb"},
+{0,	NOTOP,		071,		"idiv"},
+{0,	CALLOP,		020+(0350<<8),	"call"},
+{0,	CALLOP,		040+(0351<<8),	"jmp"},
+{0,	CALFOP,		030+(0232<<8),	"callf"},
+{0,	CALFOP,		050+(0352<<8),	"jmpf"},
+{0,	LEAOP,		0215,		"lea"},
+{0,	LEAOP,		0304,		"les"},
+{0,	LEAOP,		0305,		"lds"},
+{0,	ESC,		0,		"esc"},
+{0,	INT,		0,		"int"},
+{0,	RET,		0303,		"ret"},
+{0,	RET,		0313,		"retf"},
+{0,	XCHG,		0,		"xchgb"},
+{0,	XCHG,		1,		"xchg"},
+{0,	TEST,		0,		"testb"},
+{0,	TEST,		1,		"test"},
+{0,	MOV,		0,		"movb"},
+{0,	MOV,		1,		"mov"},
+{0,	MOV,		1,		"movw"},
+
+/* Intel 8087 coprocessor keywords */
+
+{0,	ST,		0,			"st"},
+
+{0,	FNOOP,		FESC+1+(0xF0<<8),	"f2xm1"},
+{0,	FNOOP,		FESC+1+(0xE1<<8),	"fabs"},
+{0,	FNOOP,		FESC+1+(0xE0<<8),	"fchs"},
+{0,	FNOOP,		FESC+3+(0xE2<<8),	"fclex"},
+{0,	FNOOP,		FESC+6+(0xD9<<8),	"fcompp"},
+{0,	FNOOP,		FESC+1+(0xF6<<8),	"fdecstp"},
+{0,	FNOOP,		FESC+3+(0xE1<<8),	"fdisi"},
+{0,	FNOOP,		FESC+3+(0xE0<<8),	"feni"},
+{0,	FNOOP,		FESC+1+(0xF7<<8),	"fincstp"},
+{0,	FNOOP,		FESC+3+(0xE3<<8),	"finit"},
+{0,	FNOOP,		FESC+1+(0xE8<<8),	"fld1"},
+{0,	FNOOP,		FESC+1+(0xEA<<8),	"fldl2e"},
+{0,	FNOOP,		FESC+1+(0xE9<<8),	"fldl2t"},
+{0,	FNOOP,		FESC+1+(0xEC<<8),	"fldlg2"},
+{0,	FNOOP,		FESC+1+(0xED<<8),	"fldln2"},
+{0,	FNOOP,		FESC+1+(0xEB<<8),	"fldpi"},
+{0,	FNOOP,		FESC+1+(0xEE<<8),	"fldz"},
+{0,	FNOOP,		FESC+1+(0xD0<<8),	"fnop"},
+{0,	FNOOP,		FESC+1+(0xF3<<8),	"fpatan"},
+{0,	FNOOP,		FESC+1+(0xF8<<8),	"fprem"},
+{0,	FNOOP,		FESC+1+(0xF2<<8),	"fptan"},
+{0,	FNOOP,		FESC+1+(0xFC<<8),	"frndint"},
+{0,	FNOOP,		FESC+1+(0xFD<<8),	"fscale"},
+{0,	FNOOP,		FESC+1+(0xFA<<8),	"fsqrt"},
+{0,	FNOOP,		FESC+7+(0xE0<<8),	"fstswax"}, /* 80287 */
+{0,	FNOOP,		FESC+1+(0xE4<<8),	"ftst"},
+{0,	FNOOP,		FESC+1+(0xE5<<8),	"fxam"},
+{0,	FNOOP,		FESC+1+(0xF4<<8),	"fxtract"},
+{0,	FNOOP,		FESC+1+(0xF1<<8),	"fyl2x"},
+{0,	FNOOP,		FESC+1+(0xF9<<8),	"fyl2pi"},
+
+{0,	FMEM,		FESC+6+(0<<11),		"fiadds"},
+{0,	FMEM,		FESC+2+(0<<11),		"fiaddl"},
+{0,	FMEM,		FESC+0+(0<<11),		"fadds"},
+{0,	FMEM,		FESC+4+(0<<11),		"faddd"},
+{0,	FMEM,		FESC+7+(4<<11),		"fbld"},
+{0,	FMEM,		FESC+7+(6<<11),		"fbstp"},
+{0,	FMEM,		FESC+6+(2<<11),		"ficoms"},
+{0,	FMEM,		FESC+2+(2<<11),		"ficoml"},
+{0,	FMEM,		FESC+0+(2<<11),		"fcoms"},
+{0,	FMEM,		FESC+4+(2<<11),		"fcomd"},
+{0,	FMEM,		FESC+6+(3<<11),		"ficomps"},
+{0,	FMEM,		FESC+2+(3<<11),		"ficompl"},
+{0,	FMEM,		FESC+0+(3<<11),		"fcomps"},
+{0,	FMEM,		FESC+4+(3<<11),		"fcompd"},
+{0,	FMEM,		FESC+6+(6<<11),		"fidivs"},
+{0,	FMEM,		FESC+2+(6<<11),		"fidivl"},
+{0,	FMEM,		FESC+0+(6<<11),		"fdivs"},
+{0,	FMEM,		FESC+4+(6<<11),		"fdivd"},
+{0,	FMEM,		FESC+6+(7<<11),		"fidivrs"},
+{0,	FMEM,		FESC+2+(7<<11),		"fidivrl"},
+{0,	FMEM,		FESC+0+(7<<11),		"fdivrs"},
+{0,	FMEM,		FESC+4+(7<<11),		"fdivrd"},
+{0,	FMEM,		FESC+7+(5<<11),		"fildq"},
+{0,	FMEM,		FESC+7+(0<<11),		"filds"},
+{0,	FMEM,		FESC+3+(0<<11),		"fildl"},
+{0,	FMEM,		FESC+1+(0<<11),		"flds"},
+{0,	FMEM,		FESC+5+(0<<11),		"fldd"},
+{0,	FMEM,		FESC+3+(5<<11),		"fldx"},
+{0,	FMEM,		FESC+1+(5<<11),		"fldcw"},
+{0,	FMEM,		FESC+1+(4<<11),		"fldenv"},
+{0,	FMEM,		FESC+6+(1<<11),		"fimuls"},
+{0,	FMEM,		FESC+2+(1<<11),		"fimull"},
+{0,	FMEM,		FESC+0+(1<<11),		"fmuls"},
+{0,	FMEM,		FESC+4+(1<<11),		"fmuld"},
+{0,	FMEM,		FESC+5+(4<<11),		"frstor"},
+{0,	FMEM,		FESC+5+(6<<11),		"fsave"},
+{0,	FMEM,		FESC+7+(2<<11),		"fists"},
+{0,	FMEM,		FESC+3+(2<<11),		"fistl"},
+{0,	FMEM,		FESC+1+(2<<11),		"fsts"},
+{0,	FMEM,		FESC+5+(2<<11),		"fstd"},
+{0,	FMEM,		FESC+7+(7<<11),		"fistpq"},
+{0,	FMEM,		FESC+7+(3<<11),		"fistps"},
+{0,	FMEM,		FESC+3+(3<<11),		"fistpl"},
+{0,	FMEM,		FESC+1+(3<<11),		"fstps"},
+{0,	FMEM,		FESC+5+(3<<11),		"fstpd"},
+{0,	FMEM,		FESC+3+(7<<11),		"fstpx"},
+{0,	FMEM,		FESC+1+(7<<11),		"fstcw"},
+{0,	FMEM,		FESC+1+(6<<11),		"fstenv"},
+{0,	FMEM,		FESC+5+(7<<11),		"fstsw"},
+{0,	FMEM,		FESC+6+(4<<11),		"fisubs"},
+{0,	FMEM,		FESC+2+(4<<11),		"fisubl"},
+{0,	FMEM,		FESC+0+(4<<11),		"fsubs"},
+{0,	FMEM,		FESC+4+(4<<11),		"fsubd"},
+{0,	FMEM,		FESC+6+(5<<11),		"fisubrs"},
+{0,	FMEM,		FESC+2+(5<<11),		"fisubrl"},
+{0,	FMEM,		FESC+0+(5<<11),		"fsubrs"},
+{0,	FMEM,		FESC+4+(5<<11),		"fsubrd"},
+
+{0,	FST_I,		FESC+1+(0xC0<<8),	"fld"},
+{0,	FST_I,		FESC+5+(0xD0<<8),	"fst"},
+{0,	FST_I,		FESC+5+(0xC8<<8),	"fstp"},
+{0,	FST_I,		FESC+1+(0xC8<<8),	"fxch"},
+{0,	FST_I,		FESC+0+(0xD0<<8),	"fcom"},
+{0,	FST_I,		FESC+0+(0xD8<<8),	"fcomp"},
+{0,	FST_I,		FESC+5+(0xC0<<8),	"ffree"},
+
+{0,	FST_ST,		FESC+0+(0xC0<<8),	"fadd"},
+{0,	FST_ST,		FESC+2+(0xC0<<8),	"faddp"},
+{0,	FST_ST2,	FESC+0+(0xF0<<8),	"fdiv"},
+{0,	FST_ST2,	FESC+2+(0xF0<<8),	"fdivp"},
+{0,	FST_ST2,	FESC+0+(0xF8<<8),	"fdivr"},
+{0,	FST_ST2,	FESC+2+(0xF8<<8),	"fdivrp"},
+{0,	FST_ST,		FESC+0+(0xC8<<8),	"fmul"},
+{0,	FST_ST,		FESC+2+(0xC8<<8),	"fmulp"},
+{0,	FST_ST2,	FESC+0+(0xE0<<8),	"fsub"},
+{0,	FST_ST2,	FESC+2+(0xE0<<8),	"fsubp"},
+{0,	FST_ST2,	FESC+0+(0xE8<<8),	"fsubr"},
+{0,	FST_ST2,	FESC+2+(0xE8<<8),	"fsubrp"},
+
+/* 80286 keywords */
+{0,	NOOP_1,		0140,			"pusha"},
+{0,	NOOP_1,		0141,			"popa"},
+{0,	NOOP_1,		0154,			"insb"},
+{0,	NOOP_1,		0155,			"ins"},
+{0,	NOOP_1,		0155,			"insw"},
+{0,	NOOP_1,		0156,			"outsb"},
+{0,	NOOP_1,		0157,			"outs"},
+{0,	NOOP_1,		0157,			"outsw"},
+
+{0,	ARPLOP,		0143,			"arpl"},
+{0,	ENTER,		0310,			"enter"},
+{0,	NOOP_1,		0311,			"leave"},
+{0,	LEAOP,		0142,			"bound"},
+
+{0,	NOOP_2,		017+06<<8,		"clts"},
+
+{0,	EXTOP,		0002,			"lar"},
+{0,	EXTOP,		0003,			"lsl"},
+
+{0,	EXTOP1,		0021,			"lgdt"},
+{0,	EXTOP1,		0001,			"sgdt"},
+{0,	EXTOP1,		0031,			"lidt"},
+{0,	EXTOP1,		0011,			"sidt"},
+{0,	EXTOP1,		0020,			"lldt"},
+{0,	EXTOP1,		0000,			"sldt"},
+{0,	EXTOP1,		0030,			"ltr"},
+{0,	EXTOP1,		0010,			"str"},
+{0,	EXTOP1,		0061,			"lmsw"},
+{0,	EXTOP1,		0041,			"smsw"},
+{0,	EXTOP1,		0050,			"verw"},
+{0,	EXTOP1,		0040,			"verr"},
diff --git a/mach/m65oo2/as/mach4.c b/mach/m65oo2/as/mach4.c
new file mode 100644
index 000000000..ed1c7b830
--- /dev/null
+++ b/mach/m65oo2/as/mach4.c
@@ -0,0 +1,167 @@
+#define RCSID4 "$Id$"
+
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ *
+ */
+
+operation
+	:	prefix oper
+	;
+prefix	:	/* empty */
+	|	prefix PREFIX
+			{	emit1($2);}
+	;
+oper	:	OP_impl
+			{	emit1($1);}
+	|	OP_acc REG_acc
+			{	emit1($1);}
+	|	OP_imm SIZE '#' expr
+			{	encode_imm($1, $2, $4);}
+	|	JOP expr
+			{	branch($1,$2);}
+	|	PUSHOP ea_1
+			{	pushop($1);}
+	|	IOOP expr
+			{	emit1($1);
+#ifdef RELOCATION
+				newrelo($2.typ, RELO1);
+#endif
+				emit1($2.val);
+			}
+	|	IOOP R16
+			{	if ($2!=2) serror("register error");
+				emit1($1+010);
+			}
+	|	ADDOP ea_ea
+			{	addop($1);}
+	|	ROLOP ea_ea
+			{	rolop($1);}
+	|	INCOP ea_1
+			{	incop($1);}
+	|	IMUL ea_ea
+			{	imul($1);}
+	|	IMUL ea_1
+			{	regsize($1); emit1(0366|($1&1)); ea_1($1&070);}
+	|	NOTOP ea_1
+			{	regsize($1); emit1(0366|($1&1)); ea_1($1&070);}
+	|	CALLOP ea_1
+			{	callop($1&0xFFFF);}
+	|	CALFOP expr ':' expr
+			{	emit1($1>>8);
+#ifdef RELOCATION
+				newrelo($4.typ, RELO2);
+#endif
+				emit2($4.val);
+#ifdef RELOCATION
+				newrelo($2.typ, RELO2);
+#endif
+				emit2($2.val);
+			}
+	|	CALFOP mem
+			{	emit1(0377); ea_2($1&0xFF);}
+	|	ENTER absexp ',' absexp
+			{	fit(fitw($2)); fit(fitb($4));
+				emit1($1); emit2((int)$2); emit1((int)$4);
+			}
+	|	LEAOP R16 ',' mem
+			{	emit1($1); ea_2($2<<3);}
+	|	ARPLOP mem ',' R16
+			{	emit1($1); ea_2($4<<3);}
+	|	EXTOP	R16 ',' ea_2
+			{	emit1(0xF); emit1($1);
+				ea_2($2<<3);
+			}
+	|	EXTOP1	ea_1
+			{	regsize(1); emit1(0xF); emit1($1&07); 
+				ea_1($1&070);
+			}
+	|	ESC absexp ',' mem
+			{	fit(fit6($2));
+				emit1(0330 | $2>>3);
+				ea_2(($2&7)<<3);
+			}
+	|	INT absexp
+			{	if ($2==3)
+					emit1(0314);
+				else {
+					emit1(0315); emit1($2);
+				}
+			}
+	|	RET
+			{	emit1($1);}
+	|	RET expr
+			{	emit1($1-1);
+#ifdef RELOCATION
+				newrelo($2.typ, RELO2);
+#endif
+				emit2($2.val);
+			}
+	|	XCHG ea_ea
+			{	xchg($1);}
+	|	TEST ea_ea
+			{	test($1);}
+	|	MOV ea_ea
+			{	mov($1);}
+/* Intel 8087 coprocessor instructions */
+	|	FNOOP
+			{	emit1($1); emit1($1>>8);}
+	|	FMEM mem
+			{	emit1($1); ea_2(($1>>8)&070);}
+	|	FST_I st_i
+			{	emit1($1); emit1(($1>>8)|$2); }
+	|	FST_I ST
+			{	emit1($1); emit1($1>>8); }
+	|	FST_ST ST ',' st_i
+			{	emit1($1); emit1(($1>>8)|$4); }
+	|	FST_ST2 ST ',' st_i
+			{	emit1($1); emit1(($1>>8)|$4); }
+	|	FST_ST st_i ',' ST
+			{	emit1($1|4); emit1((($1>>8)|$2)); }
+	|	FST_ST2 st_i ',' ST
+			{	emit1($1|4); emit1((($1>>8)|$2)^010); }
+	;
+
+st_i	:	ST '(' absexp ')'
+			{	if (!fit3($3)) {
+					serror("illegal index in FP stack");
+				}
+				$$ = $3;
+			}
+	;
+mem	:	'(' expr ')'
+			{	mrg_2 = 6; exp_2 = $2;
+				RELOMOVE(rel_2, relonami);
+			}
+	|	bases
+			{	exp_2.val = 0; exp_2.typ = S_ABS; indexed();}
+	|	expr bases
+			{	exp_2 = $1; indexed();
+				RELOMOVE(rel_2, relonami);
+			}
+	;
+bases	:	'(' R16 ')'
+			{	mrg_2 = sr_m[$2];}
+	|	'(' R16 ')' '(' R16 ')'
+			{	mrg_2 = dr_m[$2][$5];}
+	;
+ea_2	:	mem
+	|	R8
+			{	mrg_2 = $1 | 0300;}
+	|	R16
+			{	mrg_2 = $1 | 0310;}
+	|	RSEG
+			{	mrg_2 = $1 | 020;}
+	|	expr
+			{	mrg_2 = 040; exp_2 = $1;
+				RELOMOVE(rel_2, relonami);
+			}
+	;
+ea_1	:	ea_2
+			{	mrg_1 = mrg_2; exp_1 = exp_2;
+				RELOMOVE(rel_1, rel_2);
+			}
+	;
+ea_ea	:	ea_1 ',' ea_2
+	;
diff --git a/mach/m65oo2/as/mach5.c b/mach/m65oo2/as/mach5.c
new file mode 100644
index 000000000..8edc74e5c
--- /dev/null
+++ b/mach/m65oo2/as/mach5.c
@@ -0,0 +1,390 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
+#define RCSID5 "$Id$"
+
+/*
+ * INTEL 8086 special routines
+ */
+
+void
+encode_imm(int opc, int sz, expr_t exp)
+{
+	emit1(opc);
+	emit1(sz);
+	switch(sz)
+	{
+		case 4:
+		case 0:
+			emit1(exp.val);
+			break;
+		
+		case 5:
+		case 1:
+			emit2(exp.val);
+			break;
+			
+		default:
+			emit4(exp.val);
+			break;
+	}
+}
+
+void ea_1(int param)
+{
+
+	if ((mrg_1 & 070) || (param & ~070)) {
+		serror("bad operand");
+	}
+	emit1(mrg_1 | param);
+	switch(mrg_1 >> 6) {
+	case 0:
+		if (mrg_1 == 6 || (mrg_1 & 040)) {
+#ifdef RELOCATION
+			RELOMOVE(relonami, rel_1);
+			newrelo(exp_1.typ, RELO2);
+#endif
+			emit2(exp_1.val);
+		}
+		break;
+	case 1:
+#ifdef RELOCATION
+		RELOMOVE(relonami, rel_1);
+		newrelo(exp_1.typ, RELO1);
+#endif
+		emit1(exp_1.val);
+		break;
+	case 2:
+#ifdef RELOCATION
+		RELOMOVE(relonami, rel_1);
+		newrelo(exp_1.typ, RELO2);
+#endif
+		emit2(exp_1.val);
+		break;
+	}
+}
+
+void ea_2(int param) {
+
+	mrg_1 = mrg_2;
+	exp_1 = exp_2;
+	RELOMOVE(rel_1, rel_2);
+	ea_1(param);
+}
+
+void reverse(void)
+{
+	register int m, r;
+    expr_t e;
+
+	m = mrg_1; mrg_1 = mrg_2; mrg_2 = m;
+	e = exp_1; exp_1 = exp_2; exp_2 = e;
+#ifndef ASLD
+	r = rel_1; rel_1 = rel_2; rel_2 = r;
+#endif
+}
+
+void badsyntax(void)
+{
+
+	serror("bad operands");
+}
+
+void regsize(register int sz)
+{
+	register int bit;
+
+	sz <<= 3;
+	bit = 010;
+	sz &= bit;
+	if ((mrg_1 >= 0300 && (mrg_1 & bit) != sz) ||
+	    (mrg_2 >= 0300 && (mrg_2 & bit) != sz))
+		serror("register error");
+	mrg_1 &= ~bit;
+	mrg_2 &= ~bit;
+}
+
+void indexed(void)
+{
+	int sm1, sm2;
+
+	if (mrg_2 & ~7)
+		serror("register error");
+	sm1 = exp_2.typ == S_ABS && fitb((short)(exp_2.val));
+	if (sm1) {
+		sm2 = exp_2.val == 0 && mrg_2 != 6;
+	}
+	else sm2 = 0;
+	if (small(sm1, 1)) {
+		if (small(sm2, 1)) {
+		}
+		else mrg_2 |= 0100;
+	}
+	else {
+		if (small(0, 1)) {}
+		mrg_2 |= 0200;
+	}
+}
+
+void branch(register int opc,expr_t exp)
+{
+	register int sm,dist;
+	int saving = opc == 0353 ? 1 : 3;
+
+	dist = exp.val - (DOTVAL + 2);
+	if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT))
+		dist -= DOTGAIN;
+	sm = dist > 0 ? fitb(dist-saving) : fitb(dist);
+	if ((exp.typ & ~S_DOT) != DOTTYP)
+		sm = 0;
+	if ((opc & 0370) == 0340) {
+		fit(sm);
+		sm = 1;
+	} else {
+		if ((sm = small(sm,saving)) == 0) {
+			if (opc != 0353) {
+				emit1(opc^1);
+				emit1(3);
+				dist -= 2;
+			}
+			opc = 0351;
+			dist--;
+		}
+	}
+	emit1(opc);
+	if (sm == 0) {
+#ifdef RELOCATION
+		newrelo(exp.typ, RELPC | RELO2);
+#endif
+		emit2(dist);
+	} else
+		emit1(dist);
+}
+
+void pushop(register int opc)
+{
+
+	regsize(1);
+	if (mrg_1 & 020) {
+		if ( (mrg_1&3) == 1 && opc==1 ) badsyntax() ;
+		emit1(6 | opc | (mrg_1&3)<<3);
+	} else if (mrg_1 >= 0300) {
+		emit1(0120 | opc<<3 | (mrg_1&7));
+	} else if (opc == 0) {
+		if (mrg_1 & 040) {	/* 070 ??? */
+			if (small(exp_1.typ == S_ABS && fitb((short)exp_1.val),1)) {
+				emit1(0152);
+				emit1((int) exp_1.val);
+			} else {
+				emit1(0150);
+				RELOMOVE(relonami, rel_1);
+#ifdef RELOCATION
+				newrelo(exp_1.typ, RELO2);
+				emit2((int) exp_1.val);
+#endif
+			}
+		} else {
+			emit1(0377); ea_1(6<<3);
+		}
+	} else {
+		emit1(0217); ea_1(0<<3);
+	}
+}
+
+void addop(register int opc)
+{
+	regsize(opc);
+	if (mrg_2 >= 0300) {
+		emit1(opc); ea_1((mrg_2&7)<<3);
+	} else if ((mrg_2 & 040) && mrg_1 == 0300) {
+		emit1(opc | 4);
+#ifdef RELOCATION
+		RELOMOVE(relonami, rel_2);
+		newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
+#endif
+		emitx(exp_2.val, (opc&1)+1);
+	} else if (mrg_2 & 040) {
+		if ((opc&1) == 0) {
+			emit1(0200);
+		} else {
+			int sm = exp_2.typ == S_ABS && fitb((short)exp_2.val) &&
+				opc != 011 && opc != 041 && opc != 061;
+			if (small(sm, 1)) {
+				emit1(0203); opc &= ~1;
+			}
+			else emit1(0201);
+		}
+		ea_1(opc & 070);
+#ifdef RELOCATION
+			RELOMOVE(relonami, rel_2);
+			newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
+#endif
+		emitx(exp_2.val, (opc&1)+1);
+	} else if (mrg_1 >= 0300) {
+		emit1(opc | 2);
+		ea_2((mrg_1&7)<<3);
+	} else
+		badsyntax();
+}
+
+void rolop(register int opc)
+{
+	register int cmrg;
+
+	cmrg = mrg_2;
+	mrg_2 = mrg_1;
+	regsize(opc);
+	if (cmrg == 0301) {
+		emit1(0322 | (opc&1)); ea_1(opc&070);
+	} else if (cmrg & 040) {
+		if (small(exp_2.val == 1, 1)) {
+			emit1(0320 | (opc&1)); ea_1(opc&070);
+		} else {
+			fit(fitb(exp_2.val));
+			emit1(0300|(opc&1)); ea_1(opc&070);
+			emit1((int)exp_2.val);
+		}
+	} else
+		badsyntax();
+}
+
+void incop(register int opc)
+{
+
+	regsize(opc);
+	if ((opc&1) && mrg_1>=0300) {
+		emit1(0100 | (opc&010) | (mrg_1&7));
+	} else {
+		emit1(0376 | (opc&1));
+		ea_1(opc & 010);
+	}
+}
+
+void callop(register int opc)
+{
+	regsize(1);
+	if (mrg_1 & 040) {
+		if (opc == (040+(0351<<8))) {
+			RELOMOVE(relonami, rel_1);
+			branch(0353,exp_1);
+		} else {
+			exp_1.val -= (DOTVAL+3);
+			emit1(opc>>8);
+#ifdef RELOCATION
+			RELOMOVE(relonami, rel_1);
+			newrelo(exp_1.typ, RELPC | RELO2);
+#endif
+			emit2(exp_1.val);
+		}
+	} else {
+		emit1(0377); ea_1(opc&070);
+	}
+}
+
+void xchg(register int opc)
+{
+	regsize(opc);
+	if (mrg_2 == 0300 || mrg_1 < 0300)
+		reverse();
+	if (opc == 1 && mrg_1 == 0300 && mrg_2 >= 0300) {
+		emit1(0220 | (mrg_2&7));
+	} else if (mrg_1 >= 0300) {
+		emit1(0206 | opc); ea_2((mrg_1&7)<<3);
+	} else
+		badsyntax();
+}
+
+void test(register int opc)
+{
+	regsize(opc);
+	if ((mrg_1 & 040) || mrg_2 >= 0300)
+		reverse();
+	if ((mrg_2 & 040) && mrg_1 == 0300) {
+		emit1(0250 | opc);
+#ifdef RELOCATION
+			RELOMOVE(relonami, rel_2);
+			newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
+#endif
+		emitx(exp_2.val, (opc&1)+1);
+	} else if (mrg_2 & 040) {
+		emit1(0366 | opc);
+		ea_1(0<<3);
+#ifdef RELOCATION
+			RELOMOVE(relonami, rel_2);
+			newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
+#endif
+		emitx(exp_2.val, (opc&1)+1);
+	} else if (mrg_1 >= 0300) {
+		emit1(0204 | opc); ea_2((mrg_1&7)<<3);
+	} else
+		badsyntax();
+}
+
+void mov(register int opc)
+{
+	regsize(opc);
+	if (mrg_1 & 020) {
+		emit1(0216); ea_2((mrg_1&3)<<3);
+	} else if (mrg_2 & 020) {
+		emit1(0214); ea_1((mrg_2&3)<<3);
+	} else if (mrg_2 & 040) {
+		if (mrg_1 >= 0300) {
+			emit1(0260 | opc<<3 | (mrg_1&7)); 
+#ifdef RELOCATION
+			RELOMOVE(relonami, rel_2);
+			newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
+#endif
+			emitx(exp_2.val, (opc&1)+1);
+		} else {
+			emit1(0306 | opc); ea_1(0<<3); 
+#ifdef RELOCATION
+			RELOMOVE(relonami, rel_2);
+			newrelo(exp_2.typ, (opc&1)? RELO2 : RELO1);
+#endif
+			emitx(exp_2.val, (opc&1)+1);
+		}
+	} else if (mrg_2 == 0300 && mrg_1 == 6) {
+		emit1(0242 | opc);
+#ifdef RELOCATION
+		RELOMOVE(relonami, rel_1);
+		newrelo(exp_1.typ, RELO2);
+#endif
+		emit2(exp_1.val);
+	} else if (mrg_1 == 0300 && mrg_2 == 6) {
+		emit1(0240 | opc);
+#ifdef RELOCATION
+		RELOMOVE(relonami, rel_2);
+		newrelo(exp_2.typ, RELO2);
+#endif
+		emit2(exp_2.val);
+	} else if (mrg_2 >= 0300) {
+		emit1(0210 | opc); ea_1((mrg_2&7)<<3);
+	} else if (mrg_1 >= 0300) {
+		emit1(0212 | opc); ea_2((mrg_1&7)<<3);
+	} else {
+		badsyntax();
+	}
+}
+
+void imul(int opc)
+{
+	regsize(opc);
+	if (exp_2.typ != S_ABS || ((mrg_2 & 040) == 0)) {
+		serror("bad operand");
+	} else {
+		if (small(exp_2.typ == S_ABS && fitb((short)exp_2.val),1)) {
+			emit1(0153);
+			ea_1((mrg_2&7)<<3);
+			emit1((int)exp_2.val);
+		} else {
+			emit1(0151);
+			ea_1((mrg_2&7)<<3);
+			RELOMOVE(relonami, rel_2);
+#ifdef RELOCATION
+			newrelo(exp_2.typ, RELO2);
+			emit2((int) exp_2.val);
+#endif
+		}
+	}
+}
diff --git a/mach/m65oo2/as/testfp.s b/mach/m65oo2/as/testfp.s
new file mode 100644
index 000000000..5937e497d
--- /dev/null
+++ b/mach/m65oo2/as/testfp.s
@@ -0,0 +1,189 @@
+.sect .text; .sect .rom; .sect .data;
+.sect .data
+.define _m_a_i_n
+blablabla:
+	.space 100
+
+.sect .text
+
+_m_a_i_n:
+	! no operands
+	f2xm1
+	fabs
+	fchs
+	fclex
+	fcompp
+	fdecstp
+	fdisi
+	feni
+	fincstp
+	finit
+	fld1
+	fldl2e
+	fldl2t
+	fldlg2
+	fldln2
+	fldpi
+	fldz
+	fnop
+	fpatan
+	fprem
+	fptan
+	frndint
+	fscale
+	fsqrt
+	ftst
+	fxam
+	fxtract
+	fyl2x
+	fyl2pi
+
+	! memory operand
+	fiadds	(blablabla)
+	fiaddl	(blablabla)
+	fadds	(blablabla)
+	faddd	(blablabla)
+	fbld	(blablabla)
+	fbstp	(blablabla)
+	ficoms	(blablabla)
+	ficoml	(blablabla)
+	fcoms	(blablabla)
+	fcomd	(blablabla)
+	ficomps	(blablabla)
+	ficompl	(blablabla)
+	fcomps	(blablabla)
+	fcompd	(blablabla)
+	fidivs	(blablabla)
+	fidivl	(blablabla)
+	fdivs	(blablabla)
+	fdivd	(blablabla)
+	fidivrs	(blablabla)
+	fidivrl	(blablabla)
+	fdivrs	(blablabla)
+	fdivrd	(blablabla)
+	filds	(blablabla)
+	fildl	(blablabla)
+	flds	(blablabla)
+	fldd	(blablabla)
+	fldx	(blablabla)
+	fldcw	(blablabla)
+	fldenv	(blablabla)
+	fimuls	(blablabla)
+	fimull	(blablabla)
+	fmuls	(blablabla)
+	fmuld	(blablabla)
+	frstor	(blablabla)
+	fsave	(blablabla)
+	fists	(blablabla)
+	fistl	(blablabla)
+	fsts	(blablabla)
+	fstd	(blablabla)
+	fistps	(blablabla)
+	fistpl	(blablabla)
+	fstps	(blablabla)
+	fstpd	(blablabla)
+	fstpx	(blablabla)
+	fstcw	(blablabla)
+	fstenv	(blablabla)
+	fstsw	(blablabla)
+	fisubs	(blablabla)
+	fisubl	(blablabla)
+	fsubs	(blablabla)
+	fsubd	(blablabla)
+	fisubrs	(blablabla)
+	fisubrl	(blablabla)
+	fsubrs	(blablabla)
+	fsubrd	(blablabla)
+
+	! again, memory operand
+	fiadds	8(bp)
+	fiaddl	8(bp)
+	fadds	8(bp)
+	faddd	8(bp)
+	fbld	8(bp)
+	fbstp	8(bp)
+	ficoms	8(bp)
+	ficoml	8(bp)
+	fcoms	8(bp)
+	fcomd	8(bp)
+	ficomps	8(bp)
+	ficompl	8(bp)
+	fcomps	8(bp)
+	fcompd	8(bp)
+	fidivs	8(bp)
+	fidivl	8(bp)
+	fdivs	8(bp)
+	fdivd	8(bp)
+	fidivrs	8(bp)
+	fidivrl	8(bp)
+	fdivrs	8(bp)
+	fdivrd	8(bp)
+	filds	8(bp)
+	fildl	8(bp)
+	flds	8(bp)
+	fldd	8(bp)
+	fldx	8(bp)
+	fldcw	8(bp)
+	fldenv	8(bp)
+	fimuls	8(bp)
+	fimull	8(bp)
+	fmuls	8(bp)
+	fmuld	8(bp)
+	frstor	8(bp)
+	fsave	8(bp)
+	fists	8(bp)
+	fistl	8(bp)
+	fsts	8(bp)
+	fstd	8(bp)
+	fistps	8(bp)
+	fistpl	8(bp)
+	fstps	8(bp)
+	fstpd	8(bp)
+	fstpx	8(bp)
+	fstcw	8(bp)
+	fstenv	8(bp)
+	fstsw	8(bp)
+	fisubs	8(bp)
+	fisubl	8(bp)
+	fsubs	8(bp)
+	fsubd	8(bp)
+	fisubrs	8(bp)
+	fisubrl	8(bp)
+	fsubrs	8(bp)
+	fsubrd	8(bp)
+
+	! one FP stack argument
+	fld	st
+	fst	st
+	fstp	st
+	fxch	st
+	fcom	st
+	fcomp	st
+	ffree	st
+
+	fld	st(4)
+	fst	st(4)
+	fstp	st(4)
+	fxch	st(4)
+	fcom	st(4)
+	fcomp	st(4)
+	ffree	st(4)
+
+	! two FP stack arguments
+	fadd	st(4),st
+	faddp	st(4),st
+	fdiv	st(4),st
+	fdivp	st(4),st
+	fdivr	st(4),st
+	fdivrp	st(4),st
+	fmul	st(4),st
+	fmulp	st(4),st
+	fsub	st(4),st
+	fsubp	st(4),st
+	fsubr	st(4),st
+	fsubrp	st(4),st
+
+	fadd	st,st(4)
+	faddp	st,st(4)
+	fmul	st,st(4)
+	fmulp	st,st(4)
diff --git a/mach/m65oo2/ce/EM_table b/mach/m65oo2/ce/EM_table
new file mode 100644
index 000000000..909d6348d
--- /dev/null
+++ b/mach/m65oo2/ce/EM_table
@@ -0,0 +1,1266 @@
+#define PUSH_POP_OPT	TRUE
+
+/******************************************************************************/
+/*									      */
+/*		Group 1 : load instructions				      */
+/*									      */
+/******************************************************************************/
+
+C_loc		==> 	"mov ax, $1";
+			"push ax".
+
+C_ldc		==>	C_loc( $1>>16);
+			C_loc( $1).
+
+C_lol		==>	"push $1(bp)".
+
+C_loe..		==>	"push ($1+$2)".
+
+C_lil		==> 	"mov bx, $1(bp)";
+			"push (bx)".
+
+C_lof		==>	"pop bx";
+			"push $1(bx)".
+
+C_lal		==> 	"lea ax, $1(bp)";
+			"push ax".
+
+C_lae..		==> 	"mov ax, $1+$2";
+			"push ax".
+
+C_lxl  
+  $1 == 0	==> 	"push bp".
+
+  $1 == 1	==> 	"push 4(bp)".
+
+  default	==> 	"mov cx, $1-1";
+	  	    	"mov bx, 4(bp)";
+		    	"1: mov bx, 4(bx)";
+		    	"loop 1b";
+		    	"push bx".
+
+C_lxa	
+  $1 == 0	==> 	"lea ax, 4(bp)";
+		    	"push ax".
+
+  $1 == 1	==> 	"mov ax, 4(bp)";
+		    	"add ax, 4";
+		    	"push ax".
+
+  default	==> 	"mov cx, $1-1";
+	  	    	"mov bx, 4(bp)";
+		    	"1: mov bx, 4(bx)";
+		    	"loop 1b";
+		    	"add bx, 4";
+		    	"push bx".
+
+C_loi
+  $1 == 1	==> 	"pop bx";
+		    	"xor ax, ax";
+		    	"movb al, (bx)";
+		    	"push ax".
+
+  $1 == 2	==> 	"pop bx";
+		    	"push (bx)".
+	 
+  $1 == 4	==> 	"pop bx";
+		    	"push 2(bx)";
+		    	"push (bx)".
+	  
+  default	==> 	"pop bx";
+		    	"mov cx, $1";
+		    	"call .loi".
+
+C_los
+  $1 == 2	==> 	"pop cx";
+			"pop bx";
+			"call .los".
+
+  default	==> 	arg_error( "C_los", $1).
+
+C_los_narg	==> 	"pop ax";
+			"cmp ax, 2";
+			"jne .unknown";
+			"pop cx";
+			"pop bx";
+			"call .loi".
+
+C_ldl		==> 	"push $1+2(bp)";
+			"push $1(bp)".
+
+C_lde..		==> 	"push ($1+$2+2)";
+			"push ($1+$2)".
+
+C_ldf		==> 	"pop bx";
+			"push $1+2(bx)";
+			"push $1(bx)".
+
+C_lpi		==> 	"mov ax, $1";
+			"push ax".
+
+/******************************************************************************/
+/*									      */
+/*		Group 2 : store instructions				      */
+/*									      */
+/******************************************************************************/
+
+C_stl		==> 	"pop $1(bp)".
+
+C_ste..		==> 	"pop ($1+$2)".
+
+C_sil		==> 	"mov bx, $1(bp)";
+			"pop (bx)".
+
+C_stf		==> 	"pop bx";
+			"pop $1(bx)".
+
+C_sti
+  $1 == 1	==>	"pop bx";
+		   	"pop ax";
+		   	"movb (bx), al".
+
+  $1 == 2	==>	"pop bx";
+		   	"pop (bx)".
+
+  $1 == 4	==>	"pop bx";
+		   	"pop (bx)";
+		   	"pop 2(bx)".
+
+  default	==>	"pop bx";
+		   	"mov cx, $1";
+		   	"call .sti".
+
+C_sts
+  $1 == 2	==> 	"pop cx";
+			"pop bx";
+			"call .sts".
+
+  default	==>	arg_error( "C_sts", $1).
+
+C_sts_narg	==> 	"pop ax";
+			"cmp ax, 2";
+			"jne .unknown";
+			"pop cx";
+			"pop bx";
+			"call .sti".
+
+C_sdl		==> 	"pop $1(bp)";
+			"pop $1+2(bp)".
+
+C_sde..		==> 	"pop ($1+$2)";
+			"pop ($1+$2+2)".
+
+C_sdf		==> 	"pop bx";
+			"pop $1(bx)";
+			"pop $1+2(bx)".
+
+/******************************************************************************/
+/*									      */
+/*		Group 3 : integer arithmetic				      */
+/*									      */
+/******************************************************************************/
+
+C_adi
+  $1 == 2	==> 	"pop ax";
+		    	"pop bx";
+		    	"add ax, bx";
+		    	"push ax".
+
+  $1 == 4	==> 	"pop ax";
+		    	"pop bx";
+		    	"pop cx";
+		    	"pop dx";
+		    	"add ax, cx";
+		    	"adc bx, dx";
+		    	"push bx";
+		    	"push ax".
+
+  default	==> 	"pop ax";
+		    	"mov cx, $1";
+		    	"call .adi";
+		    	"push ax".
+
+C_adi_narg	==> 	"pop cx";
+			"pop ax";
+			"call .adi";
+			"push ax".
+
+C_sbi	
+  $1 == 2	==> 	"pop bx";
+		    	"pop ax";
+		    	"sub ax, bx";
+		    	"push ax".
+
+  $1 == 4	==> 	"pop ax";
+		    	"pop bx";
+		    	"pop cx";
+		    	"pop dx";
+		    	"sub cx, ax";
+		    	"sbb dx, bx";
+		    	"push dx";
+		    	"push cx".
+
+  default	==> 	"pop ax";
+		    	"mov cx, $1";
+		    	"call .sbi";
+		    	"push ax".
+
+C_sbi_narg	==> 	"pop cx";
+			"pop ax";
+			"call .sbi";
+			"push ax".
+
+C_mli
+  $1 == 2	==> 	"pop ax";
+		    	"pop bx";
+		    	"mul bx";
+		    	"push ax".
+
+  $1 == 4	==> 	"pop ax";
+		    	"pop dx";
+		    	"call .mli4";
+		    	"push dx";
+		    	"push ax".
+
+  default	==> 	arg_error( "C_mli", $1).
+
+C_mli_narg	==>	"pop ax";
+			"call .mli".
+
+C_dvi
+  $1 == 2	==> 	"pop bx";
+		    	"pop ax";
+		    	"cwd";
+		    	"idiv bx";
+		    	"push ax".
+
+  $1 == 4	==> 	"call .dvi4";
+		    	"push dx";
+		    	"push ax".
+
+  default	==> 	arg_error( "C_dvi", $1).
+
+C_dvi_narg	==> 	"pop ax";
+			"call .dvi".
+
+C_rmi
+  $1 == 2	==> 	"pop bx";
+		    	"pop ax";
+		    	"cwd";
+		    	"idiv bx";
+		    	"push dx".
+
+  $1 == 4	==> 	"call .rmi4";
+		    	"push dx";
+		    	"push ax".
+
+  default	==> 	arg_error( "C_rmi", $1).
+
+C_rmi_narg	==>	"pop ax";
+			"call .rmi".
+
+C_ngi
+  $1 == 2	==> 	"pop ax";
+		    	"neg ax";
+		    	"push ax".
+
+  $1 == 4	==> 	"pop bx";
+			"pop ax";
+		    	"neg ax";
+		    	"neg bx";
+		    	"sbb ax, 0";
+		    	"push ax";
+		    	"push bx".
+
+  default	==> 	"mov ax, $1";
+		    	"call .ngi".
+
+C_ngi_narg	==> 	"pop ax";
+			"call .ngi".
+
+C_sli
+  $1 == 2	==> 	"pop cx";
+		    	"pop ax";
+		    	"sal ax, cl";
+		    	"push ax".
+
+  default	==>	"mov ax, $1";
+		    	"call .sli".
+
+C_sli_narg	==> 	"pop ax";
+			"call .sli".
+
+C_sri
+  $1 == 2	==> 	"pop cx";
+		    	"pop ax";
+		    	"sar ax, cl";
+		    	"push ax".
+
+  default	==> 	"mov ax, $1";
+		    	"call .sri".
+
+C_sri_narg	==> 	"pop ax";
+			"call .sri".
+
+/******************************************************************************/
+/*									      */
+/*		Group 4 : Unsigned arithmetic 				      */
+/*									      */
+/******************************************************************************/
+
+C_adu		==> 	C_adi( $1).
+
+C_adu_narg	==> 	C_adi_narg().
+
+C_sbu		==> 	C_sbi( $1).
+
+C_sbu_narg	==>	C_sbi_narg().
+
+C_mlu		==>	C_mli( $1).
+
+C_mlu_narg	==>	C_mli_narg().
+
+C_dvu
+  $1 == 2	==> 	"pop bx";
+		    	"pop ax";
+		    	"xor dx, dx";
+		    	"div bx";
+		    	"push ax".
+
+  $1 == 4	==> 	"call .dvu4";
+		    	"push dx";
+		    	"push ax".
+
+  default	==> 	"mov ax, $1";
+		    	"call .dvu".
+
+C_dvu_narg	==> 	"pop ax";
+			"call .dvu".
+
+C_rmu
+  $1 == 2	==> 	"pop bx";
+		    	"pop ax";
+		    	"xor dx, dx";
+		    	"div bx";
+		    	"push dx".
+
+  $1 == 4	==> 	"call .dvu4";
+		    	"push dx";
+		    	"push ax".
+
+  default	==> 	"mov ax, $1";
+		    	"call .rmu".
+
+C_rmu_narg	==> 	"pop ax";
+			"call .rmu".
+
+C_slu		==>	C_sli( $1).
+
+C_slu_narg	==>	C_sli_narg().
+
+C_sru
+  $1 == 2	==> 	"pop cx";
+		    	"pop ax";
+		    	"shr ax, cl";
+		    	"push ax".
+
+  $1 == 4	==> 	"pop cx";
+		    	"pop bx";
+		    	"pop ax";
+		    	"1 : shr ax, 1";
+		    	"rcr bx, 1";
+		    	"loop 1b";
+		    	"push ax";
+		    	"push bx".
+
+  default	==> 	arg_error( "C_sru", $1).
+
+/******************************************************************************/
+/*									      */
+/*		Group 5 : Floating point arithmetic 			      */
+/*									      */
+/******************************************************************************/
+
+C_adf
+  $1 == 4	==>	"call .adf4";
+			"pop bx";
+			"pop bx".
+  $1 == 8	==>	"call .adf8";
+			"add sp,8".
+  default	==>	arg_error("C_adf", $1).
+
+C_sbf
+  $1 == 4	==>	"call .sbf4";
+			"pop bx";
+			"pop bx".
+  $1 == 8	==>	"call .sbf8";
+			"add sp,8".
+  default	==>	arg_error("C_sbf", $1).
+
+C_mlf
+  $1 == 4	==>	"call .mlf4";
+			"pop bx";
+			"pop bx".
+  $1 == 8	==>	"call .mlf8";
+			"add sp,8".
+  default	==>	arg_error("C_mlf", $1).
+
+C_dvf
+  $1 == 4	==>	"call .dvf4";
+			"pop bx";
+			"pop bx".
+  $1 == 8	==>	"call .dvf8";
+			"add sp,8".
+  default	==>	arg_error("C_dvf", $1).
+
+C_ngf
+  $1 == 4	==>	"call .ngf4".
+  $1 == 8	==>	"call .ngf8".
+  default	==>	arg_error("C_ngf", $1).
+
+C_fif
+  $1 == 4	==>	C_lor((arith)1);
+			"call .fif4";
+			"pop bx".
+  $1 == 8	==>	C_lor((arith)1);
+			"call .fif8";
+			"pop bx".
+  default	==>	arg_error("C_fif", $1).
+
+C_fef
+  $1 == 4	==>	"mov ax,sp";
+			"sub ax,2";
+			"push ax";
+			"call .fef4".
+  $1 == 8	==>	"mov ax,sp";
+			"sub ax,2";
+			"push ax";
+			"call .fef8".
+  default	==>	arg_error("C_fef", $1).
+
+/******************************************************************************/
+/*									      */
+/*		Group 6 : Pointer arithmetic 				      */
+/*									      */
+/******************************************************************************/
+
+C_adp
+
+#ifndef PEEPHOLE_OPT
+  $1 == 0	==>	.
+#endif
+
+  $1 == 1	==> 	"pop ax";
+		    	"inc ax";
+		    	"push ax".
+
+  $1 == -1 	==>	"pop ax";
+		    	"dec ax";
+		    	"push ax".
+
+  default	==> 	"pop ax";
+		    	"add ax, $1";
+		    	"push ax".
+
+C_ads
+  $1 == 2	==>	"pop ax";
+			"pop bx";
+			"add ax, bx";
+			"push ax".
+
+  default	==>	arg_error( "C_ads", $1).
+
+C_ads_narg	==> 	"pop ax";
+			"cmp ax, 2";
+			"jne .unknown";
+			"pop ax";
+			"pop bx";
+			"add ax, bx";
+			"push ax".
+
+C_sbs
+  $1 == 2	==>	"pop bx";
+			"pop ax";
+			"sub ax, bx";
+			"push ax".
+
+  default	==>	arg_error( "C_sbs", $1).
+
+C_sbs_narg	==> 	"pop ax";
+			"cmp ax, 2";
+			"jne .unknown";
+			"pop bx";
+			"pop ax";
+			"sub ax, bx";
+			"push ax".
+
+/******************************************************************************/
+/*									      */
+/*		Group 7 : Increment/decrement/zero			      */
+/*									      */
+/******************************************************************************/
+
+C_inc		==> 	"pop ax";
+			"inc ax";
+			"push ax".
+
+C_inl		==> 	"inc $1(bp)".
+
+C_ine..		==> 	"inc ($1+$2)".
+
+C_dec		==> 	"pop ax";
+			"dec ax";
+			"push ax".
+
+C_del		==> 	"dec $1(bp)".
+
+C_dee..		==> 	"dec ($1+$2)".
+
+C_zrl		==> 	"mov $1(bp), 0".
+
+C_zre..		==> 	"mov ($1+$2), 0".
+
+C_zer
+  $1 == 2	==>  	"xor ax, ax";
+			"push ax".
+
+  $1 == 4	==>  	"xor ax, ax";
+			"push ax";
+			"push ax".
+
+  $1 == 6	==>  	"xor ax, ax";
+			"push ax";
+			"push ax";
+			"push ax".
+
+  $1 == 8	==>  	"xor ax, ax";
+			"push ax";
+			"push ax";
+			"push ax";
+			"push ax".
+
+  $1 % 2 == 0	==> 	"mov cx, $1/2";
+			"xor ax, ax";
+		    	"1: push ax";
+		    	"loop 1b".
+
+  default	==>	arg_error( "C_zer", $1).
+
+C_zrf		==>	C_zer($1).
+
+C_zer_narg	==> 	"pop cx";
+			"sar cx, 1";
+			"xor ax, ax";
+			"1: push ax";
+			"loop 1b".
+
+/******************************************************************************/
+/*									      */
+/*		Group 8 : Convert 					      */
+/*									      */
+/******************************************************************************/
+
+C_cii		==> 	"pop cx";
+			"pop dx";
+			"pop ax";
+			"call .cii";
+			"push ax".
+
+C_cui		==>	C_cuu().
+
+C_ciu		==>	C_cuu().
+
+C_cuu		==> 	"pop cx";
+			"pop dx";
+			"pop ax";
+			"call .cuu";
+			"push ax".
+
+C_cif		==>	"call .cif".
+
+C_cuf		==>	"call .cuf".
+
+C_cfi		==>	"call .cfi";
+			"pop bx";
+			"pop cx";
+			"cmp bx,4";
+			"je 1f";
+			"add sp,cx";
+			"push ax";
+			"jmp 2f";
+			"1:add cx,4";
+			"add sp,cx";
+			"2:".
+
+C_cfu		==>	"call .cfu";
+			"pop bx";
+			"pop cx";
+			"cmp bx,4";
+			"je 1f";
+			"add sp,cx";
+			"push ax";
+			"jmp 2f";
+			"1:add cx,4";
+			"add sp,cx";
+			"2:".
+
+C_cff		==>	"pop ax";
+			"pop bx";
+			"cmp ax,bx";
+			"je 1f";
+			"cmp ax,4";
+			"je 2f";
+			"pop cx";
+			"pop bx";
+			"xor ax,ax";
+			"push ax";
+			"push ax";
+			"push bx";
+			"push cx";
+			"call .cff8";
+			"jmp 1f";
+			"2: call .cff4";
+			"pop bx";
+			"pop bx";
+			"1:".
+
+/******************************************************************************/
+/*									      */
+/*		Group 9 : Logical 	 				      */
+/*									      */
+/******************************************************************************/
+
+C_and
+  $1 == 2	==> 	"pop ax";
+	  	    	"pop bx";
+		    	"and ax, bx";
+	  	    	"push ax".
+
+  $1 == 4	==> 	"pop ax";
+	  	    	"pop bx";
+	  	    	"pop cx";
+	  	    	"pop dx";
+		    	"and ax, cx";
+		    	"and bx, dx";
+	  	    	"push bx";
+	  	    	"push ax".
+
+  default	==> 	"mov cx, $1";
+		    	"call .and".
+
+C_and_narg	==> 	"pop cx";
+			"call .and".
+
+C_ior
+  $1 == 2	==> 	"pop ax";
+	  	    	"pop bx";
+		    	"or ax, bx";
+	  	    	"push ax".
+
+  $1 == 4	==> 	"pop ax";
+	  	    	"pop bx";
+	  	    	"pop cx";
+	  	    	"pop dx";
+		    	"or ax, cx";
+		    	"or bx, dx";
+	  	    	"push bx";
+	  	    	"push ax".
+
+  default	==> 	"mov cx, $1";
+		    	"call .ior".
+
+C_ior_narg	==> 	"pop cx";
+			"call .ior".
+
+C_xor
+  $1 == 2	==> 	"pop ax";
+	  	    	"pop bx";
+		    	"xor ax, bx";
+	  	    	"push ax".
+
+  $1 == 4	==> 	"pop ax";
+	  	    	"pop bx";
+	  	    	"pop cx";
+	  	    	"pop dx";
+		    	"xor ax, cx";
+		    	"xor bx, dx";
+	  	    	"push bx";
+	  	    	"push ax".
+
+  default	==> 	"mov cx, $1";
+		    	"call .xor".
+
+C_xor_narg	==> 	"pop cx";
+			"call .xor".
+
+C_com
+  $1 == 2	==> 	"pop ax";
+	  	    	"not ax";
+		    	"push ax".
+
+  $1 == 4	==> 	"pop ax";
+		    	"pop bx";
+	  	    	"not ax";
+	  	    	"not bx";
+		    	"push bx";
+		    	"push ax".
+
+  default	==> 	"mov cx, $1";
+		    	"call .com".
+
+C_com_narg	==> 	"pop cx";
+			"call .com".
+
+C_rol
+  $1 == 2	==> 	"pop cx";
+		    	"pop ax";
+		    	"rol ax, cl";
+		    	"push ax".
+		    
+  default	==> 	"mov cx, $1";
+		    	"call .rol".
+
+C_rol_narg	==>	"pop cx";
+			"call .rol".
+
+C_ror
+  $1 == 2	==> 	"pop cx";
+		    	"pop ax";
+		    	"ror ax, cl";
+		    	"push ax".
+		    
+  default	==> 	"mov cx, $1";
+		    	"call .ror".
+
+C_ror_narg	==> 	"pop cx";
+			"call .ror".
+
+/******************************************************************************/
+/*									      */
+/*		Group 10 : Sets 	 				      */
+/*									      */
+/******************************************************************************/
+
+C_inn
+  $1 == 2	==> 	"pop cx";
+			"pop ax";
+			"shr ax, cl";
+			"and ax, 1";
+			"push ax".
+
+  default	==>	"pop ax";
+			"mov cx, $1";
+			"call .inn";
+			"push ax".
+  
+C_inn_narg	==> 	"pop cx";
+			"pop ax";
+			"call .inn";
+			"push ax".
+
+C_set
+  $1 == 2	==> 	"pop cx";
+			"mov ax, 1";
+			"shl ax, cl";
+			"push ax".
+
+  default	==>	"pop ax";
+			"mov cx, $1";
+			"call .set".
+  
+C_set_narg	==> 	"pop cx";
+			"pop ax";
+			"call .set".
+
+/******************************************************************************/
+/*									      */
+/*		Group 11 : Array 	 				      */
+/*									      */
+/******************************************************************************/
+
+C_lar
+  $1 == 2	==>	"pop bx";
+			"pop ax";
+			"call .lar2".
+
+  default	==>	arg_error( "C_lar", $1).
+
+C_lar_narg	==> 	"call .ilar".
+
+C_sar
+  $1 == 2	==>	"pop bx";
+			"pop ax";
+			"call .sar2".
+
+  default	==>	arg_error( "C_sar", $1).
+
+C_sar_narg	==> 	"call .isar".
+
+C_aar
+  $1 == 2	==>	"pop bx";
+			"pop ax";
+			"pop cx";
+			"sub ax, (bx)";
+			"mul 4(bx)";
+			"add ax, cx";
+			"push ax".
+
+  default	==>	arg_error( "C_aar", $1).
+
+C_aar_narg	==> 	"call .iaar";
+			"push bx".
+
+/******************************************************************************/
+/*									      */
+/*		Group 12 : Compare 	 				      */
+/*									      */
+/******************************************************************************/
+
+C_cmi
+  $1 == 2	==>	/* bug : C_sbi( (arith) 2). */
+			"pop bx";
+			"pop cx";
+			"xor ax, ax";
+			"cmp cx, bx";
+			"je 2f";
+			"jl 1f";
+			"inc ax";
+			"jmp 2f";
+			"1: dec ax";
+			"2: push ax".
+	  
+  $1 == 4	==>	"call .cmi4";
+			"push ax".
+	  
+  default	==> 	arg_error( "C_cmi", $1).
+
+C_cmu
+  $1 == 2	==> 	C_cmp().
+	  
+  $1 == 4	==> 	"call .cmu4";
+		    	"push ax".
+
+  default	==> 	arg_error( "C_cmu", $1).
+
+C_cms
+  $1 == 2	==>	C_sbi( (arith) 2).
+	  
+  $1 == 4	==> 	"pop ax";
+		    	"pop bx";
+		    	"pop cx";
+		    	"pop dx";
+		    	"sub cx, ax";
+		    	"sbb dx, bx";
+		    	"jne 1f";
+		    	"or dx, cx";
+		    	"1: push dx".
+
+  default	==> 	"mov cx, $1";
+		    	"call .cms";
+		    	"push cx".
+
+C_cms_narg	==> 	"pop cx";
+			"call .cms";
+			"push cx".
+
+C_cmp		==> 	"pop bx";
+			"pop cx";
+			"xor ax, ax";
+			"cmp cx, bx";
+			"je 2f";
+			"jb 1f";
+			"inc ax";
+			"jmp 2f";
+			"1: dec ax";
+			"2: push ax".
+
+C_cmf
+  $1 == 4	==>	"call .cmf4";
+			"add sp,8";
+			"push ax".
+  $1 == 8	==>	"call .cmf8";
+			"add sp,16";
+			"push ax".
+  default	==>	arg_error("C_cmf", $1).
+
+C_tlt		==> 	"pop ax";
+			"xor bx, bx";
+			"test ax, ax";
+			"jge 1f";
+			"inc bx";
+			"1: push bx".
+
+C_tle		==> 	"pop ax";
+			"xor bx, bx";
+			"test ax, ax";
+			"jg 1f";
+			"inc bx";
+			"1: push bx".
+
+C_teq		==> 	"pop ax";
+			"xor bx, bx";
+			"test ax, ax";
+			"jne 1f";
+			"inc bx";
+			"1: push bx".
+
+C_tne		==> 	"pop ax";
+			"xor bx, bx";
+			"test ax, ax";
+			"je 1f";
+			"inc bx";
+			"1: push bx".
+
+C_tge		==> 	"pop ax";
+			"xor bx, bx";
+			"test ax, ax";
+			"jl 1f";
+			"inc bx";
+			"1: push bx".
+
+C_tgt		==> 	"pop ax";
+			"xor bx, bx";
+			"test ax, ax";
+			"jle 1f";
+			"inc bx";
+			"1: push bx".
+
+/******************************************************************************/
+/*									      */
+/*		Group 13 : Branch 	 				      */
+/*									      */
+/******************************************************************************/
+
+C_bra		==> 	"jmp $1".
+
+C_blt		==> 	"pop ax";
+			"pop bx";
+			"cmp bx, ax";
+			"jl $1".
+
+C_ble		==> 	"pop ax";
+			"pop bx";
+			"cmp bx, ax";
+			"jle $1".
+
+C_beq		==> 	"pop ax";
+			"pop bx";
+			"cmp bx, ax";
+			"je $1".
+
+C_bne		==> 	"pop ax";
+			"pop bx";
+			"cmp bx, ax";
+			"jne $1".
+
+C_bge		==> 	"pop ax";
+			"pop bx";
+			"cmp bx, ax";
+			"jge $1".
+
+C_bgt		==> 	"pop ax";
+			"pop bx";
+			"cmp bx, ax";
+			"jg $1".
+
+C_zlt		==> 	"pop ax";
+			"test ax, ax";
+			"jl $1".
+
+C_zle		==> 	"pop ax";
+			"test ax, ax";
+			"jle $1".
+
+C_zeq		==> 	"pop ax";
+			"test ax, ax";
+			"je $1".
+
+C_zne		==> 	"pop ax";
+			"test ax, ax";
+			"jne $1".
+
+C_zge		==> 	"pop ax";
+			"test ax, ax";
+			"jge $1".
+
+C_zgt		==> 	"pop ax";
+			"test ax, ax";
+			"jg $1".
+
+/******************************************************************************/
+/*									      */
+/*		Group 14 : Procedure call instructions			      */
+/*									      */
+/******************************************************************************/
+
+C_cai		==> 	"pop bx";
+			"call bx".
+
+C_cal		==> 	"call $1".
+
+C_lfr
+  $1 == 2	==> 	"push ax".
+
+  $1 == 4	==> 	"push dx";
+			"push ax".
+
+  $1 == 6	==> 	"call .lfr6".
+
+  $1 == 8	==> 	"call .lfr8".
+
+  default	==> 	arg_error( "C_lfr", $1).
+
+C_ret
+  $1 == 0	==>	"mov sp, bp";
+			"pop bp";
+			"ret".
+
+  $1 == 2	==> 	"pop ax";
+			"mov sp, bp";
+			"pop bp";
+			"ret".
+
+  $1 == 4	==> 	"pop ax";
+	  	    	"pop dx";
+			"mov sp, bp";
+			"pop bp";
+			"ret".
+
+  $1 == 6	==> 	"call .ret6";
+			"mov sp, bp";
+			"pop bp";
+			"ret".
+
+  $1 == 8	==> 	"call .ret8";
+			"mov sp, bp";
+			"pop bp";
+			"ret".
+
+  default	==> 	arg_error( "C_ret", $1).
+
+/******************************************************************************/
+/*									      */
+/*		Group 15 : Miscellaneous instructions			      */
+/*									      */
+/******************************************************************************/
+
+C_asp
+  $1 == 2	==> 	"pop bx".
+
+  $1 == 4	==> 	"pop bx";
+			"pop bx".
+
+  $1 == -2 	==>	"push ax".
+
+  default	==> 	"add sp, $1".
+
+C_ass
+  $1 == 2	==>	"pop ax";
+			"add sp, ax".
+
+  default	==>	arg_error( "C_ass", $1).
+
+C_ass_narg	==> 	"pop ax";
+			"cmp ax, 2";
+			"jne .unknown";
+			"pop ax";
+			"add sp, ax".
+
+C_blm
+  $1 % 2 == 0	==>	"mov cx, $1/2";
+			"call .blm".
+
+  default	==>	arg_error( "C_blm", $1).
+
+C_bls
+  $1 == 2	==>	"pop cx";
+			"sar cx,1";
+			"call .blm".
+
+  default	==> 	arg_error( "C_bls", $1).
+
+C_bls_narg	==> 	"pop ax";
+			"cmp ax, 2";
+			"jne .unknown";
+			"pop cx";
+			"sar cx, 1";
+			"call .blm".
+
+C_csa
+  $1 == 2	==>	"pop bx";
+			"pop ax";
+			"jmp .csa2".
+
+  default	==>	arg_error( "C_csa", $1).
+
+C_csa_narg	==> 	"pop ax";
+			"cmp ax, 2";
+			"jne .unknown";
+			"pop bx";
+			"pop ax";
+			"jmp .csa2".
+
+C_csb
+  $1 == 2	==>	"pop bx";
+			"pop ax";
+			"jmp .csb2".
+
+  default	==>	arg_error( "C_csb", $1).
+
+C_csb_narg	==> 	"pop ax";
+			"cmp ax, 2";
+			"jne .unknown";
+			"pop bx";
+			"pop ax";
+			"jmp .csb2".
+
+C_dch		==> 	"mov bp, (bp)".
+
+C_dup
+  $1 == 2	==> 	"pop ax";
+		    	"push ax";
+		    	"push ax".
+
+  $1 == 4	==> 	"pop ax";
+		    	"pop bx";
+		    	"push bx";
+		    	"push ax";
+		    	"push bx";
+		    	"push ax".
+
+  default	==> 	"mov cx, $1";
+	  	    	"call .dup".
+
+C_dus
+  $1 == 2	==>	"pop cx";
+			"call .dup".
+
+  default	==>	arg_error( "C_dus", $1).
+
+C_dus_narg	==> 	"pop ax";
+			"cmp ax, 2";
+			"jne .unknown";
+			"pop cx";
+			"call .dup".
+
+C_exg		==> 	"mov cx, $1";
+			"call .exg".
+
+C_exg_narg	==> 	"pop cx";
+			"call .exg".
+
+C_fil..		==> 	"mov (hol0+4), $1+$2".
+
+C_gto..		==> 	"mov bx, $1+$2";
+			"call .gto".
+
+C_lim		==> 	"push (.ignmask)".
+
+C_lin		==> 	"mov (hol0), $1".
+
+C_lni		==> 	"inc (hol0)".
+
+C_lor
+  $1 == 0	==> 	"push bp".
+
+  $1 == 1	==> 	"mov ax, sp";
+		    	"push ax".
+
+  $1 == 2	==> 	"push (.reghp)".
+
+  default	==> 	arg_error( "C_lor", $1).
+
+C_lpb		==> 	"pop ax";
+			"add ax,4";
+			"push ax".
+
+C_mon		==> 	"pop ax";
+			"call .mon".
+
+C_nop		==> 	.
+
+C_rck
+  $1 == 2	==>	"pop bx";
+			"pop ax";
+			"call .rck";
+			"push ax".
+
+  default	==>	arg_error( "C_rck", $1).
+
+C_rck_narg	==> 	"pop ax";
+			"cmp ax, 2";
+			"jne .unknown";
+			"pop bx";
+			"pop ax";
+			"call .rck";
+			"push ax".
+
+
+C_rtt		==>	C_ret( (arith) 0).
+
+C_sig		==> 	"pop ax";
+			"xchg (.trppc), ax";
+			"push ax".
+
+C_sim		==> 	"pop (.ignmask)".
+
+C_str
+  $1 == 0	==> 	"pop bp".
+
+  $1 == 1	==> 	"pop sp".
+
+  $1 == 2	==> 	"pop (.reghp)".
+
+  default	==> 	arg_error( "C_str", $1).
+
+C_trp		==> 	"pop ax";
+			"call .trp".
+
+/******************************************************************************/
+/*									      */
+/*		Storage-routines					      */
+/*									      */
+/******************************************************************************/
+
+
+..icon
+  $2 == 1 	==>	gen1( (ONE_BYTE) atoi( $1)).
+  $2 == 2	==>	gen2( (TWO_BYTES) atoi( $1)).
+  $2 == 4	==>	gen4( (FOUR_BYTES) atol( $1)).
+  default	==> 	arg_error( "..icon", $1).
+
+..ucon
+  $2 == 1 	==>	gen1( (ONE_BYTE) atoi( $1)).
+  $2 == 2	==>	gen2( (TWO_BYTES) atoi( $1)).
+  $2 == 4	==>	gen4( (FOUR_BYTES) atol( $1)).
+  default	==> 	arg_error( "..ucon", $1).
+
+..fcon		==>	con_float($1, $2).
+
+/******************************************************************************/
+/*									      */
+/*		Extra-routines						      */
+/*									      */
+/******************************************************************************/
+
+#ifdef PUSH_POP_OPT
+
+C_df_ilb	==>	clean_push_buf();
+			symbol_definition( $1);
+			set_local_visible( $1).
+#endif
+
+C_jump		==>		"jmp $1".
+
+C_prolog		==>	"push bp";
+				"mov bp, sp".
+
+C_locals
+  $1 == 0		==>	.
+
+  $1 == 2		==>	"push ax".
+
+  $1 == 4		==>	"push ax";
+				"push ax".
+
+  default		==>	"sub sp, $1".
diff --git a/mach/m65oo2/ce/as.c b/mach/m65oo2/ce/as.c
new file mode 100644
index 000000000..6f6d63ada
--- /dev/null
+++ b/mach/m65oo2/ce/as.c
@@ -0,0 +1,312 @@
+#include "arg_type.h"
+#include "as.h"
+
+static struct t_operand dummy = { IS_REG, AX, 0, 0, 0};
+struct t_operand saved_op, *AX_oper = &dummy; 
+
+save_op( op)
+struct t_operand *op;
+{
+	saved_op.type = op->type;
+	saved_op.reg = op->reg;
+	saved_op.expr = op->expr;
+	saved_op.lab = op->lab;
+	saved_op.off = op->off;
+}
+
+#define last( s)	( s + strlen( s) - 1)
+#define LEFT	'('
+#define RIGHT	')'
+#define DOLLAR	'$'
+
+block_assemble( instr, nr, first, Last)
+char **instr;
+int nr, first, Last;
+{
+	int i;
+
+	if ( first) {
+		if( strncmp( instr[0], "pop", 3) == 0) {
+			*instr[0] = 'P';
+			*( instr[0]+1) = 'O';
+			*( instr[0]+2) = 'P';
+		}
+		else
+			@clean_push_buf();
+	}
+	if ( Last && strncmp( instr[nr-1], "push", 4) == 0) {
+			*instr[nr-1] = 'P';
+			*( instr[nr-1]+1) = 'U';
+			*( instr[nr-1]+2) = 'S';
+			*( instr[nr-1]+3) = 'H';
+	}
+
+	for( i=0; i<nr; i++)
+		assemble( instr[i]);
+}
+		
+
+process_label( l)
+char *l;
+{
+}
+
+
+process_mnemonic( m)
+char *m;
+{
+}
+
+
+process_operand( str, op)
+char *str;
+struct t_operand *op;
+
+/*	expr		->	IS_DATA en IS_LABEL
+ *	reg		->	IS_REG en IS_ACCU
+ *	(expr)		->	IS_ADDR
+ *	expr(reg)	->	IS_MEM
+ */
+{
+	char *ptr, *strchr();
+
+	op->type = UNKNOWN;
+	if ( *last( str) == RIGHT) {
+		ptr = strchr( str, LEFT);
+		*last( str) = '\0';
+		*ptr = '\0';
+		if ( is_reg( ptr+1, op)) {
+			op->type = IS_MEM;
+			op->expr = ( *str == '\0' ? "0" : str);
+		}
+		else {
+			set_label( ptr+1, op);
+			op->type = IS_ADDR;
+		}
+	}
+	else
+		if ( is_reg( str, op))
+			op->type = IS_REG;
+		else {
+			if ( contains_label( str))
+				set_label( str, op);
+			else {
+				op->type = IS_DATA;
+				op->expr = str;
+			}
+		}
+}
+
+int is_reg( str, op)
+char *str;
+struct t_operand *op;
+{
+	if ( strlen( str) != 2)
+		return( 0);
+
+	switch ( *(str+1)) {
+	  case 'x' :
+	  case 'l' : switch( *str) {
+		       case 'a' : op->reg = 0;
+				  return( TRUE);
+
+		       case 'c' : op->reg = 1;
+				  return( TRUE);
+
+		       case 'd' : op->reg = 2;
+				  return( TRUE);
+
+		       case 'b' : op->reg = 3;
+				  return( TRUE);
+
+		       default  : return( FALSE);
+		     }
+
+	  case 'h' : switch( *str) {
+		       case 'a' : op->reg = 4;
+				  return( TRUE);
+
+		       case 'c' : op->reg = 5;
+				  return( TRUE);
+
+		       case 'd' : op->reg = 6;
+				  return( TRUE);
+
+		       case 'b' : op->reg = 7;
+				  return( TRUE);
+
+		       default  : return( FALSE);
+		     }
+
+	  case 'p' : switch ( *str) {
+		       case 's' : op->reg = 4;
+				  return( TRUE);
+
+		       case 'b' : op->reg = 5;
+				  return( TRUE);
+
+		       default  : return( FALSE);
+		     }
+
+	  case 'i' : switch ( *str) {
+		       case 's' : op->reg = 6;
+				  return( TRUE);
+
+		       case 'd' : op->reg = 7;
+				  return( TRUE);
+
+		       default  : return( FALSE);
+		     }
+
+	  default  : return( FALSE);
+	}
+}
+
+#include <ctype.h>
+#define	 isletter( c)	( isalpha( c) || c == '_')
+
+int contains_label( str)
+char *str;
+{
+	while( !isletter( *str) && *str != '\0')
+		if ( *str == '$')
+			if ( arg_type( str) == STRING)
+				return( TRUE);
+			else
+				str += 2;
+		else
+			str++;
+
+	return( isletter( *str));
+}
+
+set_label( str, op)
+char *str;
+struct t_operand *op;
+{
+	char *ptr, *strchr(), *sprint();
+	static char buf[256];
+
+	ptr = strchr( str, '+');
+
+	if ( ptr == 0)
+		op->off = "0";
+	else {
+		*ptr = '\0';
+		op->off = ptr + 1;
+	}
+
+	if ( isdigit( *str) && ( *(str+1) == 'b' || *(str+1) == 'f') &&
+	     *(str+2) == '\0') {
+		*(str+1) = '\0';	/* b of f verwijderen! */
+		op->lab = str;
+		op->type = IS_ILB;
+	}
+	else {
+		op->type = IS_LABEL;
+		if ( strchr( str, DOLLAR) != 0)
+			op->lab = str;
+		else 
+			/* nood oplossing */
+			op->lab = sprint( buf, "\"%s\"", str);
+	}
+}
+
+
+/******************************************************************************/
+
+
+
+mod_RM( reg, op)
+int reg;
+struct t_operand *op;
+{
+	if ( REG( op))
+		R233( 0x3, reg, op->reg);
+	else if ( ADDR( op)) {
+		R233( 0x0, reg, 0x6);
+		@reloc2( %$(op->lab), %$(op->off), ABSOLUTE);
+	}
+	else if ( strcmp( op->expr, "0") == 0)
+		switch( op->reg) {
+		  case SI : R233( 0x0, reg, 0x4);
+			    break;
+
+		  case DI : R233( 0x0, reg, 0x5);
+			    break;
+
+		  case BP : R233( 0x1, reg, 0x6);	/* Uitzondering! */
+			    @text1( 0);
+			    break;
+
+		  case BX : R233( 0x0, reg, 0x7);
+			    break;
+
+		  default : fprint( STDERR, "Wrong index register %d\n",
+				    op->reg);
+		}
+	else {
+		@if ( fit_byte( %$(op->expr)))
+			switch( op->reg) {
+		  	  case SI : R233( 0x1, reg, 0x4);
+				    break;
+	
+			  case DI : R233( 0x1, reg, 0x5);
+				    break;
+	
+			  case BP : R233( 0x1, reg, 0x6);
+				    break;
+	
+			  case BX : R233( 0x1, reg, 0x7);
+				    break;
+	
+			  default : fprint( STDERR, "Wrong index register %d\n",
+					    op->reg);
+			}
+			@text1( %$(op->expr));
+		@else
+			switch( op->reg) {
+			  case SI : R233( 0x2, reg, 0x4);
+				    break;
+	
+			  case DI : R233( 0x2, reg, 0x5);
+				    break;
+	
+			  case BP : R233( 0x2, reg, 0x6);
+				    break;
+	
+			  case BX : R233( 0x2, reg, 0x7);
+				    break;
+	
+			  default : fprint( STDERR, "Wrong index register %d\n",
+					    op->reg);
+			}
+			@text2( %$(op->expr));
+		@fi
+	}
+}
+
+mov_REG_EADDR( dst, src)
+struct t_operand *dst, *src;
+{
+	if ( REG(src) && dst->reg == src->reg)
+		; /* Nothing!! result of push/pop optimization */
+	else {
+		@text1( 0x8b);
+		mod_RM( dst->reg, src);
+	}
+}
+
+
+R233( a, b, c)
+int a,b,c;
+{
+	@text1( %d( (a << 6) | ( b << 3) | c));
+}
+
+
+R53( a, b)
+int a,b;
+{
+	@text1( %d( (a << 3) | b));
+}
diff --git a/mach/m65oo2/ce/as.h b/mach/m65oo2/ce/as.h
new file mode 100644
index 000000000..e39e6871c
--- /dev/null
+++ b/mach/m65oo2/ce/as.h
@@ -0,0 +1,40 @@
+#define	UNKNOWN		0
+#define	IS_REG		0x1
+#define	IS_ACCU		0x2
+#define	IS_DATA		0x4
+#define	IS_LABEL	0x8
+#define	IS_MEM		0x10
+#define	IS_ADDR		0x20
+#define	IS_ILB		0x40
+
+#define AX		0
+#define BX		3
+#define CL		1
+#define SP		4
+#define BP		5
+#define SI		6
+#define DI		7
+
+#define REG( op)	( op->type & IS_REG)
+#define ACCU( op)	( op->type & IS_REG  &&  op->reg == AX)
+#define REG_CL( op)	( op->type & IS_REG  &&  op->reg == CL)
+#define DATA( op)	( op->type & IS_DATA)
+#define lABEL( op)	( op->type & IS_LABEL)
+#define ILB( op)	( op->type & IS_ILB)
+#define MEM( op)	( op->type & IS_MEM)
+#define ADDR( op)	( op->type & IS_ADDR)
+#define EADDR( op)	( op->type & ( IS_ADDR | IS_MEM | IS_REG))
+#define CONST1( op)	( op->type & IS_DATA  && strcmp( "1", op->expr) == 0)
+#define MOVS( op)	( op->type & IS_LABEL&&strcmp("\"movs\"", op->lab) == 0)
+#define IMMEDIATE( op)	( op->type & ( IS_DATA | IS_LABEL))
+
+#define TRUE		1
+#define FALSE		0
+
+struct t_operand {
+	unsigned type;
+	int reg;
+	char *expr, *lab, *off;
+       };
+
+extern struct t_operand saved_op, *AX_oper;
diff --git a/mach/m65oo2/ce/as_table b/mach/m65oo2/ce/as_table
new file mode 100644
index 000000000..251422d08
--- /dev/null
+++ b/mach/m65oo2/ce/as_table
@@ -0,0 +1,232 @@
+adc dst:REG, src:EADDR	==>	@text1( 0x13);
+				mod_RM( dst->reg, src).
+
+add dst:REG, src:EADDR	==>	@text1( 0x3);
+				mod_RM( dst->reg, src).
+
+... dst:ACCU, src:DATA	==>	@text1( 0x5);
+				@text2( %$(src->expr)).
+
+... dst:EADDR, src:DATA	==>	@text1( 0x81);
+				mod_RM( 0, dst);
+				@text2( %$(src->expr)).
+
+... dst:ACCU, src:lABEL	==>	@text1( 0x5);
+				@reloc2( %$(src->lab), %$(src->off), !PC_REL).
+
+... dst:EADDR, src:lABEL ==>	@text1( 0x81);
+				mod_RM( 0, dst);
+				@reloc2( %$(src->lab), %$(src->off), !PC_REL).
+
+and dst:REG, src:EADDR	==>	@text1( 0x23);
+				mod_RM( dst->reg, src).
+
+... dst:ACCU, src:DATA	==>	@text1( 0x25);
+				@text2( %$(src->expr)).
+
+call dst:lABEL		==>	@text1( 0xe8);
+				@reloc2( %$(dst->lab), %$(dst->off), PC_REL).
+
+... dst:EADDR		==>	@text1( 0xff);
+				mod_RM( 2, dst).
+
+cmp dst:REG, src:EADDR	==>	@text1( 0x3b);
+				mod_RM( dst->reg, src).
+
+... dst:ACCU, src:DATA	==>	@text1( 0x3d);
+				@text2( %$(src->expr)).
+
+... dst:EADDR, src:DATA	==>	@text1( 0x81);
+				mod_RM(7,dst);
+				@text2( %$(src->expr)).
+
+cwd			==>	@text1( 0x99).
+
+dec dst:REG		==>	R53( 9, dst->reg).
+
+... dst:EADDR		==>	@text1( 0xff);
+				mod_RM( 1, dst).
+
+div divisor:EADDR	==>	@text1( 0xf7);
+				mod_RM( 6, divisor).
+
+idiv divisor:EADDR	==>	@text1( 0xf7);
+				mod_RM( 7, divisor).
+
+inc dst:REG		==>	R53( 8, dst->reg).
+
+... dst:EADDR		==>	@text1( 0xff);
+				mod_RM( 0, dst).
+
+jb dst:ILB		==>	@text1( 0x72);
+				@text1( %dist( dst->lab)).
+
+je dst:ILB		==>	@text1( 0x74);
+				@text1( %dist( dst->lab)).
+
+... dst:lABEL		==>	save_op( dst);
+				assemble( "jne 9f");
+				jmp_instr( &saved_op);
+				assemble( "9:").
+
+jg dst:ILB		==>	@text1( 0x7f);
+				@text1( %dist( dst->lab)).
+
+... dst:lABEL		==>	save_op( dst);
+				assemble( "jle 9f");
+				jmp_instr( &saved_op);
+				assemble( "9:").
+
+jge dst:ILB		==>	@text1( 0x7d);
+				@text1( %dist( dst->lab)).
+
+... dst:lABEL		==>	save_op( dst);
+				assemble( "jl 9f");
+				jmp_instr( &saved_op);
+				assemble( "9:").
+
+jl dst:ILB		==>	@text1( 0x7c);
+				@text1( %dist( dst->lab)).
+
+... dst:lABEL		==>	save_op( dst);
+				assemble( "jge 9f");
+				jmp_instr( &saved_op);
+				assemble( "9:").
+
+jle dst:ILB		==>	@text1( 0x7e);
+				@text1( %dist( dst->lab)).
+
+... dst:lABEL		==>	save_op( dst);
+				assemble( "jg 9f");
+				jmp_instr( &saved_op);
+				assemble( "9:").
+
+jmp dst:ILB		==>	@text1( 0xeb);
+				@text1( %dist( dst->lab)).
+
+... dst:lABEL		==>	@text1( 0xe9);
+				@reloc2( %$(dst->lab), %$(dst->off), PC_REL).
+
+jne dst:ILB		==>	@text1( 0x75);
+				@text1( %dist( dst->lab)).
+
+... dst:lABEL		==>	save_op( dst);
+				assemble( "je 9f");
+				jmp_instr( &saved_op);
+				assemble( "9:").
+
+lea dst:REG, src:EADDR	==>	@text1( 0x8d);
+				mod_RM( dst->reg, src).
+
+loop dst:ILB		==>	@text1( 0xe2);
+				@text1( %dist( dst->lab)).
+
+mov dst:REG, src:EADDR	==>	mov_REG_EADDR( dst, src).
+
+... dst:REG, src:DATA	==>	R53( 0x17, dst->reg);
+				@text2( %$(src->expr)).
+
+... dst:REG, src:lABEL	==>	R53( 0x17, dst->reg);
+				@reloc2( %$(src->lab), %$(src->off), !PC_REL).
+
+... dst:EADDR, src:REG	==>	@text1( 0x89);
+				mod_RM( src->reg, dst).
+
+... dst:EADDR, src:DATA	==>	@text1( 0xc7);
+				mod_RM( 0, dst);
+				@text2( %$(src->expr)).
+
+... dst:EADDR, src:lABEL ==>	@text1( 0xc7);
+				mod_RM( 0, dst);
+				@reloc2( %$(src->lab), %$(src->off), !PC_REL).
+
+movb dst:REG, src:EADDR	==>	@text1( 0x8a);
+				mod_RM( dst->reg, src).
+
+... dst:EADDR, src:REG	==>	@text1( 0x88);
+				mod_RM( src->reg, dst).
+
+mul mplier:EADDR	==>	@text1( 0xf7);
+				mod_RM( 4, mplier).
+
+neg dst:EADDR		==>	@text1( 0xf7);
+				mod_RM( 3, dst).
+
+not dst:EADDR		==>	@text1( 0xf7);
+				mod_RM( 2, dst).
+
+or dst:REG, src:EADDR	==>	@text1( 0x0b);
+				mod_RM( dst->reg, src).
+
+pop dst:REG		==>	R53( 0xb, dst->reg).
+
+... dst:EADDR		==>	@text1( 0x8f);
+				mod_RM( 0, dst).
+
+POP dst			==>	@if ( push_waiting)
+					mov_instr( dst, AX_oper);
+					@assign( push_waiting, FALSE).
+				@else
+					pop_instr( dst).
+				@fi.
+
+push src:REG		==>	R53( 0xa, src->reg).
+
+... src:EADDR		==>	@text1( 0xff);
+				mod_RM( 6, src).
+
+PUSH src		==>	mov_instr( AX_oper, src);
+				@assign( push_waiting, TRUE).
+
+rcr dst:EADDR, src:CONST1 ==>	@text1( 0xd1);
+				mod_RM( 3, dst).
+
+rep ins:MOVS		==>	@text1( 0xf3);
+				@text1( 0xa5).	/* Wie zet direction flag? */
+
+ret			==>	@text1( 0xc3).	/* Altijd NEAR! */
+
+rol dst:EADDR, src:REG_CL ==>	@text1( 0xd3);
+				mod_RM( 0, dst).
+
+ror dst:EADDR, src:REG_CL ==>	@text1( 0xd3);
+				mod_RM( 1, dst).
+
+sal dst:EADDR, src:REG_CL ==>	@text1( 0xd3);
+				mod_RM( 4, dst).
+
+sar dst:EADDR, src:REG_CL ==>	@text1( 0xd3);
+				mod_RM( 7, dst).
+
+... dst:EADDR, src:CONST1 ==>	@text1( 0xd1);
+				mod_RM( 7, dst).
+
+sbb dst:REG, src:EADDR	==>	@text1( 0x1b);
+				mod_RM( dst->reg, src).
+
+... dst:ACCU, src:DATA	==>	@text1( 0x1d);
+				@text2( %$(src->expr)).
+
+shl dst, src		==>	sal_instr( dst, src).
+
+shr dst:EADDR, src:REG_CL ==>	@text1( 0xd3);
+				mod_RM( 5, dst).
+
+... dst:EADDR, src:CONST1 ==>	@text1( 0xd1);
+				mod_RM( 5, dst).
+
+sub dst:REG, src:EADDR	==>	@text1( 0x2b);
+				mod_RM( dst->reg, src).
+
+... dst:EADDR, src:DATA	==>	@text1( 0x81);
+				mod_RM( 5, dst);
+				@text2( %$(src->expr)).
+
+test dst:REG, src:EADDR	==>	@text1( 0x85);
+				mod_RM( dst->reg, src).
+
+xchg dst:EADDR, src:REG	==>	@text1( 0x87);
+				mod_RM( src->reg, dst).
+
+xor dst:REG, src:EADDR	==>	@text1( 0x33);
+				mod_RM( dst->reg, src).
diff --git a/mach/m65oo2/ce/mach.c b/mach/m65oo2/ce/mach.c
new file mode 100644
index 000000000..9ed03698c
--- /dev/null
+++ b/mach/m65oo2/ce/mach.c
@@ -0,0 +1,27 @@
+#define CODE_EXPANDER
+#include <system.h>
+#include "back.h"
+#include "mach.h"
+
+#ifdef DEBUG
+arg_error( s, arg)
+char *s;
+int arg;
+{
+	fprint( STDERR, "arg_error %s %d\n", s, arg);
+}
+#endif
+
+int push_waiting = FALSE;
+
+int fit_byte( val)
+int val;
+{
+	return( val >= -128 && val <= 127);
+}
+
+#define IEEEFLOAT
+#define FL_MSL_AT_LOW_ADDRESS	0
+#define FL_MSW_AT_LOW_ADDRESS	0
+#define FL_MSB_AT_LOW_ADDRESS	0
+#include <con_float>
diff --git a/mach/m65oo2/ce/mach.h b/mach/m65oo2/ce/mach.h
new file mode 100644
index 000000000..5860f682e
--- /dev/null
+++ b/mach/m65oo2/ce/mach.h
@@ -0,0 +1,30 @@
+#define	BSS_INIT	0
+
+#define ONE_BYTE	int
+#define TWO_BYTES	int
+#define FOUR_BYTES	long
+
+
+#define EM_WSIZE	2
+#define EM_PSIZE	2
+#define EM_BSIZE	4
+
+
+#define NAME_FMT	"_%s"
+#define DNAM_FMT	"_%s"
+#define DLB_FMT		"I_%ld"
+#define	ILB_FMT		"I%03d%ld"
+#define HOL_FMT		"hol%d"
+
+#define	GENLAB		'I'
+
+#define TRUE		1
+#define FALSE		0
+
+#define clean_push_buf()       if(push_waiting){text1(0x50);push_waiting=FALSE;}
+#define assign( l, r)          l = r
+extern int push_waiting;
+
+#ifndef DEBUG
+#define arg_error(s,i)
+#endif
diff --git a/mach/m65oo2/ce/proto.make b/mach/m65oo2/ce/proto.make
new file mode 100644
index 000000000..b5a873e32
--- /dev/null
+++ b/mach/m65oo2/ce/proto.make
@@ -0,0 +1,32 @@
+# $Id$
+
+#PARAMS		do not remove this line!
+
+MACH = m65oo2
+OBJ = obj
+SRC_DIR = $(SRC_HOME)/mach/$(MACH)/ce
+
+CEG = $(TARGET_HOME)/lib.bin/ceg/util
+
+all:
+	make -f $(CEG)/make_asobj "OBJ="$(OBJ) "MACH="$(MACH)
+
+install:
+	make -f $(CEG)/make_asobj "OBJ="$(OBJ) "MACH="$(MACH) install
+
+cmp:
+	-make -f $(CEG)/make_asobj "OBJ="$(OBJ) "MACH="$(MACH) cmp
+
+pr:
+	@pr $(SRC_DIR)/proto.make $(SRC_DIR)/EM_table $(SRC_DIR)/mach.h $(SRC_DIR)/mach.c $(SRC_DIR)/as_table $(SRC_DIR)/as.h $(SRC_DIR)/as.c
+
+opr:
+	make pr | opr
+
+# total cleanup
+clean:
+	make -f $(CEG)/make_asobj "OBJ="$(OBJ) clean
+
+# only remove ce, ceg, and back directories
+dclean:
+	make -f $(CEG)/make_asobj "OBJ="$(OBJ) dclean
diff --git a/mach/m65oo2/cv/cv.c b/mach/m65oo2/cv/cv.c
new file mode 100644
index 000000000..7f329ad6e
--- /dev/null
+++ b/mach/m65oo2/cv/cv.c
@@ -0,0 +1,322 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ *
+ */
+
+/*
+ * This program converts ack.out format to PC/IX a.out format.
+ * It uses ~em/modules/lib/libobject.a.
+ */
+
+#include <stdio.h>
+
+/* unsigned char: not portable */
+
+struct exec {
+	char   a_magic[2];
+	char   a_flags;
+	char   a_cpu;
+	char   a_hdrlen;
+	char   a_unused;
+	unsigned short  a_version;
+	long            a_text;
+	long            a_data;
+	long            a_bss;
+	long            a_entry;
+	long            a_misc;
+	long            a_syms;
+};
+
+struct  nlist
+{       char            n_name[8];
+	long            n_value; 
+	char   n_sclass;
+	char   n_numaux;
+	unsigned short  n_type;
+};
+
+#include <out.h>
+
+#ifndef NORCSID
+static char rcs_id[] = "$Id$" ;
+#endif
+
+#define ENTRY 0x0	/* entry point */
+
+/*
+ * Header and section table of new format object file.
+ */
+struct outhead	outhead;
+struct outsect	outsect[S_MAX];
+
+struct exec exec;
+
+char	*output_file;
+int	outputfile_created;
+FILE	*output;
+
+char *program ;
+char *chars;
+char *malloc();
+
+char flag ;
+
+/* Output file definitions and such */
+
+#define TEXTSG	0
+#define ROMSG	1
+#define DATASG	2
+#define BSSSG	3
+#define LSECT	BSSSG+1
+#define NSECT	LSECT+1
+
+long align(a,b)
+        long a,b;
+{
+        a += b - 1;
+        return a - a % b;
+}
+
+int
+follows(pa, pb)
+        register struct outsect *pa, *pb;
+{
+        /* return 1 if pa follows pb */
+
+        return pa->os_base == align(pb->os_base+pb->os_size, pa->os_lign);
+}
+
+main(argc, argv)
+	int	argc;
+	char	*argv[];
+{
+	register struct exec *e = &exec;
+
+	output = stdout;
+	program= argv[0] ;
+	if ( argc>1 && argv[1][0]=='-' ) {
+		flag=argv[1][1] ;
+		argc-- ; argv++ ;
+	}
+	switch (argc) {
+	case 1: rd_fdopen(0);
+		break;
+	case 3:	if ((output = fopen(argv[2], "wb")) == 0) {
+			fatal("Can't write %s.\n", argv[2]);
+		}
+		output_file = argv[2];
+		outputfile_created = 1;
+		/* FALLTHROUGH */
+	case 2:
+		if (! rd_open(argv[1]))
+			fatal("Can't read %s.\n", argv[1]);
+		break;
+	default:fatal("Usage: %s <as object> <dl object>.\n", argv[0]);
+	}
+	rd_ohead(&outhead);
+	if (BADMAGIC(outhead))
+		fatal("Not an ack object file.\n");
+	if (outhead.oh_flags & HF_LINK)
+		fatal("Contains unresolved references.\n");
+	if (outhead.oh_nrelo > 0)
+		fprintf(stderr, "Warning: relocation information present.\n");
+	if ( outhead.oh_nsect!=LSECT && outhead.oh_nsect!=NSECT )
+		fatal("Input file must have %d sections, not %ld\n",
+			NSECT,outhead.oh_nsect) ;
+	rd_sect(outsect, outhead.oh_nsect);
+	/* A few checks */
+	if ( outsect[TEXTSG].os_base != ENTRY)
+		fatal("text must start at %d not at 0x%lx\n", ENTRY,
+			outsect[TEXTSG].os_base) ;
+	if ( outsect[BSSSG].os_flen != 0 )
+		fatal("bss space contains initialized data\n") ;
+	if (! follows(&outsect[BSSSG], &outsect[DATASG]))
+		fatal("bss segment must follow data segment\n") ;
+	if (! follows(&outsect[DATASG], &outsect[ROMSG]))
+		fatal("data segment must follow rom\n") ;
+
+	outsect[ROMSG].os_size = outsect[DATASG].os_base - outsect[ROMSG].os_base;
+	outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
+	e->a_magic[0] = 01;
+	e->a_magic[1] = 03;
+	e->a_cpu = 04;
+	e->a_hdrlen = 32;
+	e->a_data = outsect[BSSSG].os_base - outsect[ROMSG].os_base;
+	e->a_bss = outsect[BSSSG].os_size;
+	e->a_entry = outsect[TEXTSG].os_base;
+	e->a_syms = (long) outhead.oh_nname * sizeof (struct nlist);
+	e->a_misc = 0x10000;
+	if ( outsect[ROMSG].os_base == 0x0 ) {
+		/* Separate I/D */
+		e->a_flags = 0x20;
+		outsect[TEXTSG].os_size = e->a_text =
+			align(outsect[TEXTSG].os_size,16L);
+	} else {
+		e->a_flags = 0x10;
+		outsect[TEXTSG].os_size = e->a_text =
+			outsect[ROMSG].os_base - outsect[TEXTSG].os_base;
+		if (! follows(&outsect[ROMSG], &outsect[TEXTSG]))
+			fatal("rom segment must follow text\n") ;
+	}
+	if ( outhead.oh_nsect==NSECT ) {
+		if (! follows(&outsect[LSECT], &outsect[BSSSG]))
+			fatal("end segment must follow bss\n") ;
+		if ( outsect[LSECT].os_size != 0 )
+			fatal("end segment must be empty\n") ;
+	}
+
+	if (((unsigned) outhead.oh_nchar != outhead.oh_nchar) ||
+	     (outhead.oh_nchar != 0 &&
+	      (chars = malloc((unsigned)outhead.oh_nchar)) == 0)) {
+		fprintf(stderr, "%s: (warning) No name list generated\n", program);
+		e->a_syms = 0;
+	}
+
+	/* Action at last */
+	fwrite((char *) e, 1, 6, output);
+	wr_int2((int) e->a_version);
+	wr_long(e->a_text);
+	wr_long(e->a_data);
+	wr_long(e->a_bss);
+	wr_long(e->a_entry);
+	wr_long(e->a_misc);
+	wr_long(e->a_syms);
+	emits(&outsect[TEXTSG]) ;
+	emits(&outsect[ROMSG]) ;
+	emits(&outsect[DATASG]) ;
+	if (e->a_syms) emit_symtab();
+	fclose(output);
+	if ( outputfile_created ) chmod(argv[2],0755);
+	exit(0);
+}
+
+wr_int2(n)
+	int n;
+{
+	char buf[2];
+
+	buf[0] = n;
+	buf[1] = (n >> 8);
+	fwrite(buf, 1, 2, output);
+}
+
+wr_long(l)
+	long l;
+{
+	char buf[4];
+
+	buf[0] = l;
+	buf[1] = (l >> 8);
+	buf[2] = (l >> 16);
+	buf[3] = (l >> 24);
+	fwrite(buf, 1, 4, output);
+}
+
+/*
+ * Transfer the emitted byted from one file to another.
+ */
+emits(section) struct outsect *section ; {
+	register long	n ;
+	register int	blk;
+	char		buffer[BUFSIZ];
+
+	n= section->os_flen ;
+	rd_outsect(section - outsect);
+	while (n > 0) {
+		blk = n > BUFSIZ ? BUFSIZ : n;
+		rd_emit(buffer, (long) blk);
+		fwrite(buffer, 1, blk, output);
+		n -= blk;
+	}
+	if ((n = section->os_size - section->os_flen) > 0) {
+		for (blk = BUFSIZ - 1; blk >= 0; blk--) {
+			buffer[blk] = 0;
+		}
+		while (n > 0) {
+			blk = n > BUFSIZ ? BUFSIZ : n;
+			fwrite(buffer, 1, blk, output);
+			n -= blk;
+		}
+	}
+}
+
+emit_symtab()
+{
+	struct outname ACK_name;  /* symbol table entry in ACK format */
+	struct nlist IX_name;	  /* symbol table entry in PC/IX format */
+	register unsigned short i;
+
+	long l;
+	long off = OFF_CHAR(outhead);
+	int j;
+	char *p;
+
+	rd_string(chars,outhead.oh_nchar);
+	for (i = 0; i < outhead.oh_nname; i++) {
+		rd_name(&ACK_name, 1);
+		switch(ACK_name.on_type & S_TYP) {
+			case S_UND:
+				IX_name.n_sclass = 0;
+				break;
+			case S_ABS:
+				IX_name.n_sclass = 01;
+				break;
+			case S_MIN + TEXTSG:
+				IX_name.n_sclass = 02; 
+				break;
+			case S_MIN + ROMSG:
+			case S_MIN + DATASG:
+				IX_name.n_sclass = 03;
+				break;
+			case S_MIN + BSSSG:
+			case S_MIN + LSECT:
+				IX_name.n_sclass = 04;
+				break;
+			default:
+				fprintf(stderr,"warning: unknown s_type: %d\n",
+					ACK_name.on_type & S_TYP);
+		}
+		if (ACK_name.on_type & S_EXT) IX_name.n_sclass |= 020;
+		IX_name.n_value = ACK_name.on_valu;
+		if (ACK_name.on_foff == 0) {
+			p = "\0\0";
+		}
+		else {
+			l = ACK_name.on_foff - off;
+			if (l < 0 || l >= outhead.oh_nchar) {
+				fatal("bad on_off: %ld\n",l);
+			}
+			p = &chars[l];
+		}
+		for (j = 0; j < 8; j++) {
+			IX_name.n_name[j] = *p++;
+			if (*p == '\0') break;
+		}
+		for (j++; j < 8; j++) {
+			IX_name.n_name[j] = 0;
+		}
+		fwrite((char *) &IX_name, 1, 8, output);
+		wr_long(IX_name.n_value);
+		fwrite(&(IX_name.n_sclass), 1, 2, output);
+		wr_int2((int) IX_name.n_type);
+	}
+}
+
+/* VARARGS1 */
+fatal(s, a1, a2)
+	char	*s;
+{
+	fprintf(stderr,"%s: ",program) ;
+	fprintf(stderr, s, a1, a2);
+	if (outputfile_created) {
+		fclose(output);
+		unlink(output_file);
+	}
+	exit(1);
+}
+
+rd_fatal()
+{
+	fatal("read error\n");
+}
diff --git a/mach/m65oo2/cv/proto.make b/mach/m65oo2/cv/proto.make
new file mode 100644
index 000000000..d3261743e
--- /dev/null
+++ b/mach/m65oo2/cv/proto.make
@@ -0,0 +1,34 @@
+# $Id$
+
+#PARAMS		do not remove this line!
+
+OBJLIB=$(TARGET_HOME)/modules/lib/libobject.$(LIBSUF)
+
+SRC_DIR = $(SRC_HOME)/mach/m65oo2/cv
+
+all:	cv
+
+cv:	cv.$(SUF)
+	$(CC) $(LDOPTIONS) -o cv cv.$(SUF) $(OBJLIB)
+
+cv.$(SUF):	$(SRC_DIR)/cv.c
+	$(CC) $(COPTIONS) -I$(TARGET_HOME)/h -c $(SRC_DIR)/cv.c
+
+install:	all
+	-mkdir $(TARGET_HOME)/lib.bin/m65oo2
+	cp cv $(TARGET_HOME)/lib.bin/m65oo2/cv
+
+cmp:	all
+	-cmp cv $(TARGET_HOME)/lib.bin/m65oo2/cv
+
+clean:
+	rm -f *.$(SUF) Out cv
+
+lint:
+	$(LINT) $(LINTOPTIONS) -I$(TARGET_HOME)/h $(SRC_DIR)/cv.c $(UTIL_HOME)/modules/lib/$(LINTPREF)object.$(LINTSUF)
+
+pr:
+	@pr $(SRC_DIR)/proto.make $(SRC_DIR)/cv.c
+
+opr:
+	make pr | opr
diff --git a/mach/m65oo2/libem/LIST b/mach/m65oo2/libem/LIST
new file mode 100644
index 000000000..aeb8783d3
--- /dev/null
+++ b/mach/m65oo2/libem/LIST
@@ -0,0 +1,60 @@
+libem_s.a
+adi.s
+and.s
+cii.s
+cms.s
+cmi4.s
+cmu4.s
+com.s
+csa2.s
+csb2.s
+csa4.s
+csb4.s
+cuu.s
+dup.s
+dvi.s
+dvi4.s
+dvu.s
+dvu4.s
+exg.s
+fp8087.s
+gto.s
+iaar.s
+ilar.s
+inn.s
+ior.s
+isar.s
+lar2.s
+loi.s
+mli.s
+mli4.s
+mon.s
+ngi.s
+nop.s
+rck.s
+rmi.s
+rmi4.s
+rmu.s
+rmu4.s
+rol.s
+ror.s
+sar2.s
+sbi.s
+set.s
+sli.s
+sri.s
+sti.s
+strhp.s
+xor.s
+error.s
+unknown.s
+fat.s
+trp.s
+print.s
+ret6.s
+ret8.s
+lfr6.s
+lfr8.s
+retarea.s
+blm.s
+return.s
diff --git a/mach/m65oo2/libem/adi.s b/mach/m65oo2/libem/adi.s
new file mode 100644
index 000000000..b76949ae1
--- /dev/null
+++ b/mach/m65oo2/libem/adi.s
@@ -0,0 +1,28 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define .adi
+
+	! #bytes in cx , top of stack in ax
+	.sect .text
+.adi:
+	pop     bx              ! return address
+	cmp     cx,2
+	jne     1f
+	pop     cx
+	add     ax,cx
+	jmp     bx
+1:
+	cmp     cx,4
+	jne     9f
+	pop     dx
+	pop     cx
+	add     ax,cx
+	pop     cx
+	adc     dx,cx
+	push    dx
+	jmp     bx
+9:
+.extern	EODDZ
+.extern .trp
+	mov     ax,EODDZ
+	push	bx
+	jmp     .trp
diff --git a/mach/m65oo2/libem/and.s b/mach/m65oo2/libem/and.s
new file mode 100644
index 000000000..28fed090e
--- /dev/null
+++ b/mach/m65oo2/libem/and.s
@@ -0,0 +1,20 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define	.and
+
+	! #bytes in cx
+	! save di; it might be a register variable
+
+	.sect .text
+.and:
+	pop	bx		! return address
+	mov	dx,di
+	mov	di,sp
+	add	di,cx
+	sar	cx,1
+1:
+	pop	ax
+	and	ax,(di)
+	stos
+	loop	1b
+	mov	di,dx
+	jmp	bx
diff --git a/mach/m65oo2/libem/blm.s b/mach/m65oo2/libem/blm.s
new file mode 100644
index 000000000..c107e3199
--- /dev/null
+++ b/mach/m65oo2/libem/blm.s
@@ -0,0 +1,15 @@
+.sect .text
+.define .blm
+
+	! cx: count in words
+.blm:
+	mov	bx,sp
+	mov	ax,si
+	mov	dx,di
+	mov	di,2(bx)
+	mov	si,4(bx)
+	rep	movs
+	mov	si,ax
+	mov	di,dx
+	ret	4
+
diff --git a/mach/m65oo2/libem/build.lua b/mach/m65oo2/libem/build.lua
new file mode 100644
index 000000000..db45ca763
--- /dev/null
+++ b/mach/m65oo2/libem/build.lua
@@ -0,0 +1,68 @@
+for _, plat in ipairs(vars.plats) do
+	acklibrary {
+		name = "lib_"..plat,
+		srcs = {
+			"./adi.s",
+			"./and.s",
+			"./blm.s",
+			"./cii.s",
+			"./cmi4.s",
+			"./cms.s",
+			"./cmu4.s",
+			"./com.s",
+			"./csa2.s",
+			"./csa4.s",
+			"./csb2.s",
+			"./csb4.s",
+			"./cuu.s",
+			"./dup.s",
+			"./dvi4.s",
+			"./dvi.s",
+			"./dvu4.s",
+			"./dvu.s",
+			"./error.s",
+			"./exg.s",
+			"./fat.s",
+			"./fp8087.s",
+			"./gto.s",
+			"./iaar.s",
+			"./ilar.s",
+			"./inn.s",
+			"./ior.s",
+			"./isar.s",
+			"./lar2.s",
+			"./lfr6.s",
+			"./lfr8.s",
+			"./loi.s",
+			"./mli4.s",
+			"./mli.s",
+			"./mon.s",
+			"./ngi.s",
+			"./nop.s",
+			"./print.s",
+			"./rck.s",
+			"./ret6.s",
+			"./ret8.s",
+			"./retarea.s",
+			"./return.s",
+			"./rmi4.s",
+			"./rmi.s",
+			"./rmu4.s",
+			"./rmu.s",
+			"./rol.s",
+			"./ror.s",
+			"./sar2.s",
+			"./sbi.s",
+			"./set.s",
+			"./sli.s",
+			"./sri.s",
+			"./sti.s",
+			"./strhp.s",
+			"./trp.s",
+			"./unknown.s",
+			"./xor.s",
+		},
+		vars = { plat = plat },
+	}
+end
+
diff --git a/mach/m65oo2/libem/cii.s b/mach/m65oo2/libem/cii.s
new file mode 100644
index 000000000..2659e48c2
--- /dev/null
+++ b/mach/m65oo2/libem/cii.s
@@ -0,0 +1,38 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define .cii
+
+.sect .text
+.cii:
+	pop     bx              ! return address
+				! pop     cx, dest. size
+				! pop     dx, src. size
+				! ax is first word of source
+	cmp	dx,1
+	jne	2f
+	cbw
+	mov	dx,2
+2:
+	cmp     dx,cx
+	je      8f
+	cmp     dx,2
+	je      1f
+	cmp     dx,4
+	jne     9f
+	cmp     cx,2
+	jne     9f
+	pop     dx
+8:
+	jmp     bx
+1:
+	cmp     cx,4
+	jne     9f
+	cwd
+	push    dx
+	jmp     bx
+9:
+	push    ax              ! push low source
+.extern EILLINS
+.extern .fat
+	mov     ax,EILLINS
+	push    ax
+	jmp     .fat
diff --git a/mach/m65oo2/libem/cmi4.s b/mach/m65oo2/libem/cmi4.s
new file mode 100644
index 000000000..d7e8b2d50
--- /dev/null
+++ b/mach/m65oo2/libem/cmi4.s
@@ -0,0 +1,28 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define .cmi4
+
+.sect .text
+.cmi4:
+	pop     bx              ! return address
+	pop     cx
+	pop     dx
+	pop     ax
+	push	si
+	mov	si,sp
+	xchg	bx,2(si)
+	pop	si
+	cmp     bx,dx
+	jg      1f
+	jl      2f
+	cmp     ax,cx
+	ja      1f
+	je      3f
+2:
+	mov	ax,-1
+	ret
+3:
+	xor	ax,ax
+	ret
+1:
+	mov	ax,1
+	ret
diff --git a/mach/m65oo2/libem/cms.s b/mach/m65oo2/libem/cms.s
new file mode 100644
index 000000000..71ebbbd94
--- /dev/null
+++ b/mach/m65oo2/libem/cms.s
@@ -0,0 +1,23 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define .cms
+
+	! #bytes in cx
+	.sect .text
+.cms:
+	pop     bx              ! return address
+	mov     dx,sp
+	push	si
+	push	di
+	mov     si,dx
+	add     dx,cx
+	mov     di,dx
+	add     dx,cx
+	sar     cx,1
+	repe cmps
+	je      1f
+	inc     cx
+1:
+	pop	di
+	pop	si
+	mov     sp,dx
+	jmp     bx
diff --git a/mach/m65oo2/libem/cmu4.s b/mach/m65oo2/libem/cmu4.s
new file mode 100644
index 000000000..5d78b6122
--- /dev/null
+++ b/mach/m65oo2/libem/cmu4.s
@@ -0,0 +1,28 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define .cmu4
+
+.sect .text
+.cmu4:
+	pop     bx              ! return address
+	pop     cx
+	pop     dx
+	pop     ax
+	push	si
+	mov	si,sp
+	xchg	bx,2(si)
+	pop	si
+	cmp     bx,dx
+	ja      1f
+	jb      2f
+	cmp     ax,cx
+	ja      1f
+	je      3f
+2:
+	mov	ax,-1
+	ret
+3:
+	xor	ax,ax
+	ret
+1:
+	mov	ax,1
+	ret
diff --git a/mach/m65oo2/libem/com.s b/mach/m65oo2/libem/com.s
new file mode 100644
index 000000000..6d6c243bf
--- /dev/null
+++ b/mach/m65oo2/libem/com.s
@@ -0,0 +1,15 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define	.com
+
+	! #bytes in cx
+	.sect .text
+.com:
+	mov	bx,sp
+	add	bx,2
+	sar	cx,1
+1:
+	not	(bx)
+	inc	bx
+	inc	bx
+	loop	1b
+	ret
diff --git a/mach/m65oo2/libem/csa2.s b/mach/m65oo2/libem/csa2.s
new file mode 100644
index 000000000..017b4a86e
--- /dev/null
+++ b/mach/m65oo2/libem/csa2.s
@@ -0,0 +1,27 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define .csa2
+
+.sect .text
+.csa2:
+				! bx, descriptor address
+				! ax, index
+	mov     dx,(bx)         ! default
+	sub     ax,2(bx)
+	cmp     ax,4(bx)
+	ja      1f
+	sal     ax,1
+	add	bx,ax
+	mov     bx,6(bx)
+	test    bx,bx
+	jnz     2f
+1:
+	mov     bx,dx
+	test    bx,bx
+	jnz     2f
+.extern ECASE
+.extern .fat
+	mov     ax,ECASE
+	push    ax
+	jmp     .fat
+2:
+	jmp     bx
diff --git a/mach/m65oo2/libem/csa4.s b/mach/m65oo2/libem/csa4.s
new file mode 100644
index 000000000..43157fcec
--- /dev/null
+++ b/mach/m65oo2/libem/csa4.s
@@ -0,0 +1,30 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define .csa4
+
+.sect .text
+.csa4:
+				! bx, descriptor address
+				! ax, dx: index
+	mov	cx,(bx)         ! default
+	sub     ax,2(bx)
+				! ignore high order word; if non-zero, the
+				! case descriptor would not fit anyway
+	cmp	ax,6(bx)
+	ja	1f
+2:
+	sal     ax,1
+	add	bx,ax
+	mov     bx,10(bx)
+	test    bx,bx
+	jnz     2f
+1:
+	mov	bx,cx
+	test    bx,bx
+	jnz     2f
+.extern ECASE
+.extern .fat
+	mov     ax,ECASE
+	push    ax
+	jmp     .fat
+2:
+	jmp     bx
diff --git a/mach/m65oo2/libem/csb2.s b/mach/m65oo2/libem/csb2.s
new file mode 100644
index 000000000..a2a590341
--- /dev/null
+++ b/mach/m65oo2/libem/csb2.s
@@ -0,0 +1,29 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define .csb2
+
+.sect .text
+.csb2:
+				!bx, descriptor address
+				!ax,  index
+	mov	dx,(bx)
+	mov	cx,2(bx)
+1:
+	add	bx,4
+	dec     cx
+	jl      4f
+	cmp     ax,(bx)
+	jne     1b
+	mov	bx,2(bx)
+2:
+	test    bx,bx
+	jnz     3f
+.extern ECASE
+.extern .fat
+	mov     ax,ECASE
+	push    ax
+	jmp     .fat
+3:
+	jmp     bx
+4:
+	mov	bx,dx
+	jmp	2b
diff --git a/mach/m65oo2/libem/csb4.s b/mach/m65oo2/libem/csb4.s
new file mode 100644
index 000000000..8ac3f0566
--- /dev/null
+++ b/mach/m65oo2/libem/csb4.s
@@ -0,0 +1,33 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define .csb4
+
+.sect .text
+.csb4:
+				!bx: descriptor address
+				!ax, dx:  index
+	push	(bx)		! default
+	mov	cx,2(bx)	! count (ignore high order word, the descriptor
+				! would not fit anyway)
+1:
+	add	bx,6
+	dec     cx
+	jl      4f
+	cmp     ax,(bx)
+	jne     1b
+	cmp	dx,2(bx)
+	jne     1b
+	pop	cx
+	mov	bx,4(bx)
+2:
+	test    bx,bx
+	jnz     3f
+.extern ECASE
+.extern .fat
+	mov     ax,ECASE
+	push    ax
+	jmp     .fat
+3:
+	jmp	bx
+4:
+	pop	bx
+	jmp	2b
diff --git a/mach/m65oo2/libem/cuu.s b/mach/m65oo2/libem/cuu.s
new file mode 100644
index 000000000..4343dfb7e
--- /dev/null
+++ b/mach/m65oo2/libem/cuu.s
@@ -0,0 +1,37 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define .ciu
+.define .cui
+.define .cuu
+
+.sect .text
+.ciu:
+.cui:
+.cuu:
+	pop     bx              ! return address
+				! pop     cx, dest. size
+				! pop     dx, source size
+				! ax is low word of source
+	cmp     dx,cx
+	je      8f
+	cmp     dx,2
+	je      1f
+	cmp     dx,4
+	jne     9f
+	cmp     cx,2
+	jne     9f
+	pop     dx
+8:
+	jmp     bx
+1:
+	cmp     cx,4
+	jne     9f
+	xor     dx,dx
+	push    dx
+	jmp     bx
+9:
+	push    ax              ! to help debugging ?
+.extern EILLINS
+.extern .fat
+	mov     ax,EILLINS
+	push    ax
+	jmp     .fat
diff --git a/mach/m65oo2/libem/dup.s b/mach/m65oo2/libem/dup.s
new file mode 100644
index 000000000..453049399
--- /dev/null
+++ b/mach/m65oo2/libem/dup.s
@@ -0,0 +1,17 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define	.dup
+
+	! #bytes in cx
+	.sect .text
+.dup:
+	pop	bx		! return address
+	mov	ax,si
+	mov	dx,di
+	mov	si,sp
+	sub	sp,cx
+	mov	di,sp
+	sar	cx,1
+	rep movs
+	mov	si,ax
+	mov	di,dx
+	jmp	bx
diff --git a/mach/m65oo2/libem/dvi.s b/mach/m65oo2/libem/dvi.s
new file mode 100644
index 000000000..e09c98d68
--- /dev/null
+++ b/mach/m65oo2/libem/dvi.s
@@ -0,0 +1,39 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define .dvi
+
+        ! #bytes in ax
+	.sect .text
+.dvi:
+        pop     bx              ! return address
+        cmp     ax,2
+        jne     1f
+        pop     ax
+        cwd
+        pop     cx
+        idiv    cx
+        push    ax
+        jmp     bx
+1:
+        cmp     ax,4
+        jne     9f
+        pop     ax
+        pop     dx
+        pop     si
+        pop     di
+        push    bx
+        push    di
+        push    si
+        push    dx
+        push    ax
+.extern .dvi4
+        call   .dvi4
+        pop     bx
+        push    dx
+        push    ax
+        jmp     bx
+9:
+.extern EODDZ
+.extern .trp
+        mov     ax,EODDZ
+        push    bx
+        jmp     .trp
diff --git a/mach/m65oo2/libem/dvi4.s b/mach/m65oo2/libem/dvi4.s
new file mode 100644
index 000000000..396f9e82f
--- /dev/null
+++ b/mach/m65oo2/libem/dvi4.s
@@ -0,0 +1,91 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define .dvi4
+
+yl=6
+yh=8
+xl=10
+xh=12
+
+.sect .text
+.dvi4:
+	push	si
+	push	di
+	mov     si,sp           ! copy of sp
+	mov     bx,yl(si)
+	mov     ax,yh(si)
+	cwd
+	mov     di,dx
+	cmp     dx,ax
+	jne     7f
+	and     dx,dx
+	jge     1f
+	neg     bx
+	je      7f
+1:
+	xor     dx,dx
+	mov     cx,xl(si)
+	mov     ax,xh(si)
+	and     ax,ax
+	jge     2f
+	neg     ax
+	neg     cx
+	sbb     ax,dx
+	not     di
+2:
+	div     bx
+	xchg    ax,cx
+	div     bx              ! cx = high abs(result), ax=low abs(result)
+9:
+	and     di,di
+	jge     1f
+	neg     cx
+	neg     ax
+	sbb     cx,0
+1:
+			! cx is high order result
+			! ax is low order result
+	mov	dx,cx
+	pop	di
+	pop	si
+	ret     8	! result in ax/dx
+
+7:
+	push    dx              ! sign of y
+	mov     di,ax
+	xor     bx,bx
+	and     di,di
+	jge     1f
+	neg     di
+	neg     yl(si)
+	sbb     di,bx
+1:
+	mov     ax,xl(si)
+	mov     dx,xh(si)
+	and     dx,dx
+	jge     1f
+	neg     dx
+	neg     ax
+	sbb     dx,bx
+	not     -2(si)
+1:
+	mov     cx,16
+1:
+	shl     ax,1
+	rcl     dx,1
+	rcl     bx,1
+	cmp     di,bx
+	ja      3f
+	jb      2f
+	cmp     yl(si),dx
+	jbe     2f
+3:
+	loop    1b
+	jmp     1f
+2:
+	sub     dx,yl(si)
+	sbb     bx,di
+	inc     ax
+	loop    1b
+1:
+	pop     di              ! di=sign of result,ax= result
+	jmp     9b
diff --git a/mach/m65oo2/libem/dvu.s b/mach/m65oo2/libem/dvu.s
new file mode 100644
index 000000000..45f73a1d6
--- /dev/null
+++ b/mach/m65oo2/libem/dvu.s
@@ -0,0 +1,39 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define .dvu
+
+	! #bytes in ax
+	.sect .text
+.dvu:
+	pop     bx              ! return address
+	cmp     ax,2
+	jne     1f
+	pop     ax
+	xor     dx,dx
+	pop     cx
+	div     cx
+	push    ax
+	jmp     bx
+1:
+	cmp     ax,4
+	jne     9f
+	pop     ax
+	pop     dx
+	pop     si
+	pop     di
+	push    bx
+	push    di
+	push    si
+	push    dx
+	push    ax
+.extern .dvu4
+	call   .dvu4
+	pop     bx
+	push    dx
+	push    ax
+	jmp     bx
+9:
+.extern EODDZ
+.extern .trp
+	mov     ax,EODDZ
+	push    bx
+	jmp     .trp
diff --git a/mach/m65oo2/libem/dvu4.s b/mach/m65oo2/libem/dvu4.s
new file mode 100644
index 000000000..7d2df82b6
--- /dev/null
+++ b/mach/m65oo2/libem/dvu4.s
@@ -0,0 +1,55 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define .dvu4
+
+yl=6
+yh=8
+xl=10
+xh=12
+
+.sect .text
+.dvu4:
+	push	si
+	push	di
+	mov     si,sp           ! copy of sp
+	mov     bx,yl(si)
+	mov     ax,yh(si)
+	or      ax,ax
+	jne     7f
+	xor     dx,dx
+	mov     cx,xl(si)
+	mov     ax,xh(si)
+	div     bx
+	xchg    ax,cx
+	div     bx
+9:
+			! cx is high order result
+			! ax is low order result
+	mov	dx,cx
+	pop	di
+	pop	si
+	ret     8	! result in ax/dx
+
+7:
+	mov     di,ax
+	xor     bx,bx
+	mov     ax,xl(si)
+	mov     dx,xh(si)
+	mov     cx,16
+1:
+	shl     ax,1
+	rcl     dx,1
+	rcl     bx,1
+	cmp     di,bx
+	ja      3f
+	jb      2f
+	cmp     yl(si),dx
+	jbe     2f
+3:
+	loop    1b
+	jmp     9b
+2:
+	sub     dx,yl(si)
+	sbb     bx,di
+	inc     ax
+	loop    1b
+	jmp     9b
diff --git a/mach/m65oo2/libem/error.s b/mach/m65oo2/libem/error.s
new file mode 100644
index 000000000..49194d65e
--- /dev/null
+++ b/mach/m65oo2/libem/error.s
@@ -0,0 +1,42 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define .error
+.define .Xtrp
+
+	! ax is trap number
+	! all registers must be saved
+	! because return is possible
+	! May only be called with error no's <16
+.sect .text
+.error:
+	push bp
+	push si
+	push di
+	push dx
+	push cx
+	push bx
+	push ax
+	mov  cx,ax
+	mov  bx,1
+	sal  bx,cl
+.extern .ignmask
+.extern .trp
+	test bx,(.ignmask)
+	jne  2f
+	call    .trp
+2:
+	pop  ax
+	pop  bx
+	pop  cx
+	pop  dx
+	pop  di
+	pop  si
+	pop  bp
+	ret
+
+.Xtrp:
+	cmp	ax,16
+	jge	1f
+	call	.error
+	ret
+1:
+	jmp	.trp
diff --git a/mach/m65oo2/libem/exg.s b/mach/m65oo2/libem/exg.s
new file mode 100644
index 000000000..35fa93110
--- /dev/null
+++ b/mach/m65oo2/libem/exg.s
@@ -0,0 +1,22 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define .exg
+
+	! #bytes in cx
+.sect .text
+.exg:
+	push	di
+	mov	di,sp
+	add	di,4
+	mov	bx,di
+	add	bx,cx
+	sar     cx,1
+1:
+	mov	ax,(bx)
+	xchg	ax,(di)
+	mov	(bx),ax
+	add	di,2
+	add	bx,2
+	loop	1b
+2:
+	pop	di
+	ret
diff --git a/mach/m65oo2/libem/fat.s b/mach/m65oo2/libem/fat.s
new file mode 100644
index 000000000..0302552dc
--- /dev/null
+++ b/mach/m65oo2/libem/fat.s
@@ -0,0 +1,10 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .fat
+
+.fat:
+.extern .trp
+.extern .stop
+	call    .trp
+	call    .stop
+	! no return
diff --git a/mach/m65oo2/libem/fp8087.s b/mach/m65oo2/libem/fp8087.s
new file mode 100644
index 000000000..ff4cc551a
--- /dev/null
+++ b/mach/m65oo2/libem/fp8087.s
@@ -0,0 +1,615 @@
+.define .adf4, .adf8, .sbf4, .sbf8, .mlf4, .mlf8, .dvf4, .dvf8
+.define .ngf4, .ngf8, .fif4, .fif8, .fef4, .fef8
+.define .cif4, .cif8, .cuf4, .cuf8, .cfi, .cfu, .cff4, .cff8
+.define .cmf4, .cmf8
+.sect .text; .sect .rom; .sect .data; .sect .bss
+
+!	$Id$
+
+!	Implement interface to floating point package for Intel 8087
+
+	.sect .rom
+one:
+	.data2	1
+two:
+	.data2	2
+bigmin:
+	.data2	0, -32768
+
+	.sect .text
+.adf4:
+	mov	bx,sp
+	wait
+	flds	2(bx)
+	wait
+	fadds	6(bx)
+	wait
+	fstps	6(bx)
+	wait
+	ret
+.adf8:
+	mov	bx,sp
+	wait
+	fldd	2(bx)
+	wait
+	faddd	10(bx)
+	wait
+	fstpd	10(bx)
+	wait
+	ret
+
+.sbf4:
+	mov	bx,sp
+	wait
+	flds	6(bx)
+	wait
+	fsubs	2(bx)
+	wait
+	fstps	6(bx)
+	wait
+	ret
+
+.sbf8:
+	mov	bx,sp
+	wait
+	fldd	10(bx)
+	wait
+	fsubd	2(bx)
+	wait
+	fstpd	10(bx)
+	wait
+	ret
+
+.mlf4:
+	mov	bx,sp
+	wait
+	flds	2(bx)
+	wait
+	fmuls	6(bx)
+	wait
+	fstps	6(bx)
+	wait
+	ret
+.mlf8:
+	mov	bx,sp
+	wait
+	fldd	2(bx)
+	wait
+	fmuld	10(bx)
+	wait
+	fstpd	10(bx)
+	wait
+	ret
+
+.dvf4:
+	mov	bx,sp
+	wait
+	flds	6(bx)
+	wait
+	fdivs	2(bx)
+	wait
+	fstps	6(bx)
+	wait
+	ret
+
+.dvf8:
+	mov	bx,sp
+	wait
+	fldd	10(bx)
+	wait
+	fdivd	2(bx)
+	wait
+	fstpd	10(bx)
+	wait
+	ret
+
+.ngf4:
+	mov	bx,sp
+	wait
+	flds	2(bx)
+	wait
+	fchs
+	wait
+	fstps	2(bx)
+	wait
+	ret
+
+.ngf8:
+	mov	bx,sp
+	wait
+	fldd	2(bx)
+	wait
+	fchs
+	wait
+	fstpd	2(bx)
+	wait
+	ret
+
+.fif4:
+	mov	bx,sp
+	push	bx		! make room for FP status word
+	wait
+	flds	4(bx)
+	wait
+	fmuls	8(bx)		! multiply
+	wait
+	fld	st		! copy result
+	wait
+	ftst			! test sign; handle negative separately
+	wait
+	fstsw	-2(bx)
+	wait
+	mov	ax,-2(bx)
+	sahf			! result of test in condition codes
+	jb	1f
+	frndint			! this one rounds (?)
+	wait
+	fcom	st(1)		! compare with original; if <=, then OK
+	wait
+	fstsw	-2(bx)
+	wait
+	mov	ax,-2(bx)
+	sahf
+	jbe	2f
+	fisubs	(one)		! else subtract 1
+	wait
+	jmp	2f
+1:				! here, negative case
+	frndint			! this one rounds (?)
+	wait
+	fcom	st(1)		! compare with original; if >=, then OK
+	wait
+	fstsw	-2(bx)
+	wait
+	mov	ax,-2(bx)
+	sahf
+	jae	2f
+	fiadds	(one)		! else add 1
+	wait
+2:
+	fsub	st(1),st	! subtract integer part
+	wait
+	mov	bx,2(bx)
+	fstps	(bx)
+	wait
+	fstps	4(bx)
+	wait
+	pop	bx
+	ret
+
+.fif8:
+	mov	bx,sp
+	push	bx		! make room for FP status word
+	wait
+	fldd	4(bx)
+	wait
+	fmuld	12(bx)		! multiply
+	wait
+	fld	st		! and copy result
+	wait
+	ftst			! test sign; handle negative separately
+	wait
+	fstsw	-2(bx)
+	wait
+	mov	ax,-2(bx)
+	sahf			! result of test in condition codes
+	jb	1f
+	frndint			! this one rounds (?)
+	wait
+	fcom	st(1)		! compare with original; if <=, then OK
+	wait
+	fstsw	-2(bx)
+	wait
+	mov	ax,-2(bx)
+	sahf
+	jbe	2f
+	fisubs	(one)		! else subtract 1
+	wait
+	jmp	2f
+1:				! here, negative case
+	frndint			! this one rounds (?)
+	wait
+	fcom	st(1)		! compare with original; if >=, then OK
+	wait
+	fstsw	-2(bx)
+	wait
+	mov	ax,-2(bx)
+	sahf
+	jae	2f
+	fiadds	(one)		! else add 1
+	wait
+2:
+	fsub	st(1),st	! subtract integer part
+	mov	bx,2(bx)
+	fstpd	(bx)
+	wait
+	fstpd	8(bx)
+	wait
+	pop	bx
+	ret
+
+.fef4:
+				! this could be simpler, if only the
+				! fxtract instruction was emulated properly
+	mov	bx,sp
+	mov	ax,6(bx)
+	and	ax,077600
+	je	1f		! zero exponent
+	mov	cx,7
+	shr	ax,cl
+	sub	ax,126
+	mov	cx,ax		! exponent in cx
+	mov	ax,6(bx)
+	and	ax,0100177
+	or	ax,0037400	! load -1 exponent
+	mov	dx,4(bx)
+	mov	bx,2(bx)
+	mov	4(bx),ax
+	mov	2(bx),dx
+	mov	(bx),cx
+	ret
+1:				! we get here on zero exp
+	mov	ax,6(bx)
+	and	ax,0177
+	or	ax,4(bx)
+	jne	1f		! zero result
+	xor	ax,ax
+	mov	bx,2(bx)
+	mov	(bx),ax
+	mov	2(bx),ax
+	mov	4(bx),ax
+	ret
+1:				! otherwise unnormalized number
+	mov	cx,6(bx)
+	and	cx,0100177
+	mov	dx,cx
+	and	cx,0x8000
+	mov	ax,-125
+2:
+	test	dx,0x80
+	jne	1f
+	dec	ax
+	shl	4(bx),1
+	rcl	dx,1
+	or	dx,cx
+	jmp	2b
+1:
+	mov	cx,4(bx)
+	mov	bx,2(bx)
+	mov	(bx),ax
+	mov	2(bx),cx
+	and	dx,0100177
+	or	dx,0037400	! load -1 exponent
+	mov	4(bx),dx
+	ret
+
+.fef8:
+				! this could be simpler, if only the
+				! fxtract instruction was emulated properly
+	mov	bx,sp
+	mov	ax,10(bx)
+	and	ax,077760
+	je	1f		! zero exponent
+	mov	cx,4
+	shr	ax,cl
+	sub	ax,1022
+	mov	cx,ax		! exponent in cx
+	mov	ax,10(bx)
+	and	ax,0100017
+	or	ax,0037740	! load -1 exponent
+	push	8(bx)
+	push	6(bx)
+	push	4(bx)
+	mov	bx,2(bx)
+	pop	2(bx)
+	pop	4(bx)
+	pop	6(bx)
+	mov	8(bx),ax
+	mov	(bx),cx
+	ret
+1:				! we get here on zero exp
+	mov	ax,10(bx)
+	and	ax,017
+	or	ax,8(bx)
+	or	ax,6(bx)
+	or	ax,4(bx)
+	jne	1f		! zero result
+	xor	ax,ax
+	mov	bx,2(bx)
+	mov	(bx),ax
+	mov	2(bx),ax
+	mov	4(bx),ax
+	mov	6(bx),ax
+	mov	8(bx),ax
+	ret
+1:				! otherwise unnormalized number
+	mov	cx,10(bx)
+	and	cx,0100017
+	mov	dx,cx
+	and	cx,0x8000
+	mov	ax,-1021
+2:
+	test	dx,0x10
+	jne	1f
+	dec	ax
+	shl	4(bx),1
+	rcl	6(bx),1
+	rcl	8(bx),1
+	rcl	dx,1
+	or	dx,cx
+	jmp	2b
+1:
+	and	dx,0100017
+	or	dx,0037740	! load -1 exponent
+	mov	cx,8(bx)
+	push	6(bx)
+	push	4(bx)
+	mov	bx,2(bx)
+	mov	(bx),ax
+	mov	8(bx),dx
+	mov	6(bx),cx
+	pop	2(bx)
+	pop	4(bx)
+	ret
+
+.cif4:
+	mov	bx,sp
+	cmp	2(bx),2
+	jne	1f
+	wait
+	filds	4(bx)
+	wait
+	fstps	2(bx)
+	wait
+	ret
+1:
+	wait
+	fildl	4(bx)
+	wait
+	fstps	4(bx)
+	wait
+	ret
+
+.cif8:
+	mov	bx,sp
+	cmp	2(bx),2
+	jne	1f
+	wait
+	filds	4(bx)
+	wait
+	fstpd	2(bx)
+	wait
+	ret
+1:
+	wait
+	fildl	4(bx)
+	wait
+	fstpd	2(bx)
+	wait
+	ret
+
+.cuf4:
+	mov	bx,sp
+	cmp	2(bx),2
+	jne	1f
+	mov	ax,4(bx)
+	mov	2(bx),ax
+	mov	4(bx),0
+	wait
+	fildl	2(bx)
+	wait
+	fstps	2(bx)
+	wait
+	ret
+1:
+	wait
+	fildl	4(bx)
+	wait
+	cmp	6(bx),0
+	jge	1f
+2:
+	wait
+	fisubl	(bigmin)
+	wait
+	fisubl	(bigmin)
+1:
+	wait
+	fstps	4(bx)
+	wait
+	ret
+
+.cuf8:
+	mov	bx,sp
+	cmp	2(bx),2
+	jne	1f
+	mov	6(bx),0
+1:
+	wait
+	fildl	4(bx)
+	wait
+	cmp	6(bx),0
+	jge	1f
+2:
+	wait
+	fisubl	(bigmin)
+	wait
+	fisubl	(bigmin)
+1:
+	wait
+	fstpd	2(bx)
+	wait
+	ret
+
+.cfi:
+	mov	bx,sp
+	push	bx
+	wait
+	fstcw	-2(bx)
+	wait
+	mov	dx,-2(bx)
+	or	-2(bx),0xc00	! truncating mode
+	wait
+	fldcw	-2(bx)
+	pop	ax
+	cmp	4(bx),4
+	jne	2f
+				! loc 4 loc ? cfi
+	wait
+	flds	6(bx)
+	wait
+	fistpl	6(bx)
+	wait
+	cmp	2(bx),2
+	jne	1f
+	mov	ax,6(bx)
+1:
+	mov	4(bx),dx
+	wait
+	fldcw	4(bx)
+	wait
+	ret
+2:
+				! loc 8 loc ? cfi
+	wait
+	fldd	6(bx)
+	wait
+	fistpl	10(bx)
+	wait
+	cmp	2(bx),2
+	jne	1b
+	mov	ax,10(bx)
+	jmp	1b
+
+.cfu:
+	mov	bx,sp
+	push	bx
+	wait
+	fstcw	-2(bx)
+	wait
+	mov	dx,-2(bx)
+	and	-2(bx),0xf3ff
+	or	-2(bx),0x400	! to -infinity
+	wait
+	fldcw	-2(bx)
+	wait
+	pop	ax
+	cmp	4(bx),4
+	jne	2f
+				! loc 4 loc ? cfu
+	flds	6(bx)
+	wait
+	fabs			! ???
+	wait
+	fiaddl	(bigmin)
+	fistpl	6(bx)
+	wait
+	mov	ax,8(bx)
+	sub	ax,(bigmin+2)
+	mov	8(bx),ax
+	cmp	2(bx),2
+	jne	1f
+	mov	ax,6(bx)
+1:
+	mov	4(bx),dx
+	wait
+	fldcw	4(bx)
+	wait
+	ret
+2:
+	wait
+				! loc 8 loc ? cfu
+	fldd	6(bx)
+	wait
+	fabs			! ???
+	wait
+	fiaddl	(bigmin)
+	fistpl	10(bx)
+	wait
+	mov	ax,12(bx)
+	sub	ax,(bigmin+2)
+	mov	12(bx),ax
+	cmp	2(bx),2
+	jne	1b
+	mov	ax,10(bx)
+	jmp	1b
+
+.cff4:
+	mov	bx,sp
+	wait
+	fldd	2(bx)
+	wait
+	fstcw	2(bx)
+	wait
+	mov	dx,2(bx)
+	and	2(bx),0xf3ff	! set to rounding mode
+	wait
+	fldcw	2(bx)
+	wait
+	fstps	6(bx)
+	mov	2(bx),dx
+	wait
+	fldcw	2(bx)
+	wait
+	ret
+
+.cff8:
+	mov	bx,sp
+	wait
+	flds	2(bx)
+	wait
+	fstpd	2(bx)
+	wait
+	ret
+
+.cmf4:
+	mov	bx,sp
+	push	bx		! room for 8087 status word
+	xor	cx,cx
+	wait
+	flds	6(bx)
+	wait
+	flds	2(bx)
+	wait
+	fcompp			! compare and pop operands
+	wait
+	fstsw	-2(bx)
+	wait
+	mov	ax,-2(bx)
+	sahf
+	je	1f
+	jb	2f
+	dec	cx
+	jmp	1f
+2:
+	inc	cx
+1:
+	mov	ax,cx
+	pop	bx
+	ret
+
+
+.cmf8:
+	mov	bx,sp
+	push	bx		! room for 8087 status word
+	xor	cx,cx
+	wait
+	fldd	10(bx)
+	wait
+	fldd	2(bx)
+	wait
+	fcompp			! compare and pop operands
+	wait
+	fstsw	-2(bx)
+	wait
+	mov	ax,-2(bx)
+	sahf
+	je	1f
+	jb	2f
+	dec	cx
+	jmp	1f
+2:
+	inc	cx
+1:
+	mov	ax,cx
+	pop	bx
+	ret
diff --git a/mach/m65oo2/libem/gto.s b/mach/m65oo2/libem/gto.s
new file mode 100644
index 000000000..b7c325b5d
--- /dev/null
+++ b/mach/m65oo2/libem/gto.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .gto
+
+.gto:
+	mov     bp,4(bx)
+	mov     sp,2(bx)
+	jmp     (bx)
diff --git a/mach/m65oo2/libem/iaar.s b/mach/m65oo2/libem/iaar.s
new file mode 100644
index 000000000..940e52981
--- /dev/null
+++ b/mach/m65oo2/libem/iaar.s
@@ -0,0 +1,18 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .iaar
+
+.iaar:
+	pop     cx
+	pop     dx
+	cmp     dx,2
+.extern .unknown
+	jne     .unknown
+	pop     bx      ! descriptor address
+	pop     ax      ! index
+	sub     ax,(bx)
+	mul     4(bx)
+	pop	bx	! base address
+	add     bx,ax
+	push	cx
+	ret
diff --git a/mach/m65oo2/libem/ilar.s b/mach/m65oo2/libem/ilar.s
new file mode 100644
index 000000000..62f319987
--- /dev/null
+++ b/mach/m65oo2/libem/ilar.s
@@ -0,0 +1,15 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .ilar
+
+.ilar:
+	pop     cx
+	pop     dx
+.extern .unknown
+	cmp     dx,2
+	jne     .unknown
+	pop     bx      ! descriptor address
+	pop     ax      ! index
+	push    cx
+.extern .lar2
+	jmp    .lar2
diff --git a/mach/m65oo2/libem/inn.s b/mach/m65oo2/libem/inn.s
new file mode 100644
index 000000000..32a0d0f72
--- /dev/null
+++ b/mach/m65oo2/libem/inn.s
@@ -0,0 +1,32 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .inn
+
+	! #bytes in cx
+	! bit # in ax
+.inn:
+	xor     dx,dx
+	mov     bx,8
+	div     bx
+	mov     bx,sp
+	add	bx,2
+	add     bx,ax
+	cmp     ax,cx
+	jae     1f
+	movb	al,(bx)
+	mov	bx,dx
+	testb   al,bits(bx)
+	jz      1f
+	mov	ax,1
+	jmp	2f
+1:
+	xor	ax,ax
+2:
+	pop	bx
+	add     sp,cx
+	! ax is result
+	jmp     bx
+
+	.sect .data
+bits:
+	.data1 1,2,4,8,16,32,64,128
diff --git a/mach/m65oo2/libem/ior.s b/mach/m65oo2/libem/ior.s
new file mode 100644
index 000000000..246ecca2d
--- /dev/null
+++ b/mach/m65oo2/libem/ior.s
@@ -0,0 +1,18 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define	.ior
+
+	! #bytes in cx
+.ior:
+	pop	bx		! return address
+	mov	dx,di
+	mov	di,sp
+	add	di,cx
+	sar	cx,1
+1:
+	pop	ax
+	or	ax,(di)
+	stos
+	loop	1b
+	mov	di,dx
+	jmp	bx
diff --git a/mach/m65oo2/libem/isar.s b/mach/m65oo2/libem/isar.s
new file mode 100644
index 000000000..0374aa58b
--- /dev/null
+++ b/mach/m65oo2/libem/isar.s
@@ -0,0 +1,15 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .isar
+
+.isar:
+	pop     cx
+	pop     ax
+	cmp     ax,2
+.extern .unknown
+	jne     .unknown
+	pop     bx      ! descriptor address
+	pop     ax      ! index
+	push    cx
+.extern .sar2
+	jmp    .sar2
diff --git a/mach/m65oo2/libem/lar2.s b/mach/m65oo2/libem/lar2.s
new file mode 100644
index 000000000..cf7866058
--- /dev/null
+++ b/mach/m65oo2/libem/lar2.s
@@ -0,0 +1,35 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .lar2
+
+.lar2:
+				! bx, descriptor address
+				! ax, index
+	pop	cx
+	pop	dx		! base address
+	push	cx
+	push	si
+	mov	si,dx
+	sub     ax,(bx)
+	mov     cx,4(bx)
+	imul    cx
+	add     si,ax
+	sar     cx,1
+	jnb     1f
+	xorb    ah,ah
+	lodsb
+	pop	si
+	pop	bx
+	push    ax
+	jmp     bx
+1:
+	pop	dx		! saved si
+	mov	ax,4(bx)
+	pop	bx		! return address
+	sub     sp,ax
+	mov	ax,di		! save di
+	mov     di,sp
+	rep movs
+	mov	di,ax
+	mov	si,dx
+	jmp     bx
diff --git a/mach/m65oo2/libem/lfr6.s b/mach/m65oo2/libem/lfr6.s
new file mode 100644
index 000000000..74588e8de
--- /dev/null
+++ b/mach/m65oo2/libem/lfr6.s
@@ -0,0 +1,10 @@
+.sect .text
+.define .lfr6
+.extern .retarea
+
+.lfr6:
+	pop	bx
+	push	(.retarea+4)
+	push	(.retarea+2)
+	push	(.retarea)
+	jmp	bx
diff --git a/mach/m65oo2/libem/lfr8.s b/mach/m65oo2/libem/lfr8.s
new file mode 100644
index 000000000..3f4f2dcf7
--- /dev/null
+++ b/mach/m65oo2/libem/lfr8.s
@@ -0,0 +1,11 @@
+.sect .text
+.define .lfr8
+.extern .retarea
+
+.lfr8:
+	pop	bx
+	push	(.retarea+6)
+	push	(.retarea+4)
+	push	(.retarea+2)
+	push	(.retarea)
+	jmp	bx
diff --git a/mach/m65oo2/libem/loi.s b/mach/m65oo2/libem/loi.s
new file mode 100644
index 000000000..080fbc70d
--- /dev/null
+++ b/mach/m65oo2/libem/loi.s
@@ -0,0 +1,38 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .loi
+.define .los
+
+	! #bytes in cx
+	! address in bx
+	! save si/di. they might be register variables
+.los:
+	mov	dx,si
+	mov	si,bx
+	pop	bx
+	mov     ax,cx
+	sar     cx,1
+	jnb     1f
+	xorb    ah,ah
+	lodsb
+	mov	si,dx
+	push    ax
+	jmp     bx
+1:
+	sub     sp,ax
+	jmp	1f
+
+.loi:
+	! only called with size > 4
+	mov	dx,si
+	mov	si,bx
+	pop	bx
+	sub	sp,cx
+	sar	cx,1
+1:
+	mov	ax,di
+	mov     di,sp
+	rep movs
+	mov	si,dx
+	mov	di,ax
+	jmp     bx
diff --git a/mach/m65oo2/libem/mli.s b/mach/m65oo2/libem/mli.s
new file mode 100644
index 000000000..eb0b800c3
--- /dev/null
+++ b/mach/m65oo2/libem/mli.s
@@ -0,0 +1,42 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .mli
+
+	! #bytes in ax
+.mli:
+	pop     bx              ! return address
+	cmp     ax,2
+	jne     1f
+	pop     ax
+	pop     cx
+	mul     cx
+	push    ax
+	jmp     bx
+1:
+	cmp     ax,4
+	jne     9f
+	push	bx
+	mov	cx,bx
+	mov	bx,sp
+	mov	ax,2(bx)
+	mov	(bx),ax
+	mov	ax,4(bx)
+	mov	2(bx),ax
+	mov	ax,6(bx)
+	mov	4(bx),ax
+	mov	ax,8(bx)
+	mov	6(bx),ax
+	mov	8(bx),cx
+	pop	ax
+	pop	dx
+	call   .mli4
+	pop	bx
+	push	dx
+	push	ax
+	jmp	bx
+9:
+.extern EODDZ
+.extern .trp
+	mov     ax,EODDZ
+	push    bx
+	jmp     .trp
diff --git a/mach/m65oo2/libem/mli4.s b/mach/m65oo2/libem/mli4.s
new file mode 100644
index 000000000..24a803c6b
--- /dev/null
+++ b/mach/m65oo2/libem/mli4.s
@@ -0,0 +1,26 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .mli4
+
+yl=2
+yh=4
+	! x * y
+	! xl in ax
+	! xh in dx
+
+.mli4:
+	mov	bx,sp
+	push	dx
+	mov	cx,ax
+	mul	yh(bx)           ! xl*yh
+	pop	dx
+	push	ax
+	mov	ax,dx
+	mul	yl(bx)		! xh * yl
+	pop	dx
+	add     dx,ax           ! xh*yl+xl*yh
+	mov     ax,cx
+	mov	cx,dx
+	mul     yl(bx)           ! xl*yl
+	add     dx,cx
+	ret	4
diff --git a/mach/m65oo2/libem/mon.s b/mach/m65oo2/libem/mon.s
new file mode 100644
index 000000000..42cac7ca8
--- /dev/null
+++ b/mach/m65oo2/libem/mon.s
@@ -0,0 +1,7 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .mon
+
+.mon:
+.extern .stop
+	call    .stop
diff --git a/mach/m65oo2/libem/ngi.s b/mach/m65oo2/libem/ngi.s
new file mode 100644
index 000000000..49061e16c
--- /dev/null
+++ b/mach/m65oo2/libem/ngi.s
@@ -0,0 +1,30 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .ngi
+
+	! #bytes in ax
+.ngi:
+	pop     bx              ! return address
+	cmp     ax,2
+	jne     1f
+	pop     cx
+	neg     cx
+	push    cx
+	jmp     bx
+1:
+	cmp     ax,4
+	jne     9f
+	pop     dx
+	pop     ax
+	neg     ax
+	neg     dx
+	sbb     ax,0
+	push    dx
+	push    ax
+	jmp     bx
+9:
+.extern EODDZ
+.extern .trp
+	mov     ax,EODDZ
+	push    bx
+	jmp     .trp
diff --git a/mach/m65oo2/libem/nop.s b/mach/m65oo2/libem/nop.s
new file mode 100644
index 000000000..62e861b55
--- /dev/null
+++ b/mach/m65oo2/libem/nop.s
@@ -0,0 +1,24 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .nop
+.extern printd, printc, hol0
+
+SIO_S           = 0xDA
+SIO_D           = 0xD8
+RXRDY           = 0x02
+
+.nop:
+	mov     ax,(hol0)
+	call    printd
+!       movb    al,' '
+!       call    printc
+!       mov     ax,sp
+!       call    printd
+!1:
+!       inb     SIO_S
+!       andb    al,RXRDY
+!       jz      1b
+!       inb     SIO_D
+!       call    printc
+	movb    al,'\n'
+	jmp     printc
diff --git a/mach/m65oo2/libem/print.s b/mach/m65oo2/libem/print.s
new file mode 100644
index 000000000..00737adb7
--- /dev/null
+++ b/mach/m65oo2/libem/print.s
@@ -0,0 +1,47 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define	printc,printd,prints
+
+	! argument in ax
+	! uses bx
+prints:
+	xchg	ax,bx
+1:
+	movb	al,(bx)
+	inc	bx
+	testb	al,al
+	jz	2f
+	call	printc
+	jmp	1b
+2:
+	ret
+
+	! argument in ax
+	! uses cx and dx
+printd:
+	xor	dx,dx
+	mov	cx,10
+	div	cx
+	test	ax,ax
+	jz	1f
+	push	dx
+	call	printd
+	pop	dx
+1:
+	xchg	ax,dx
+	addb	al,'0'
+
+	! argument in ax
+printc:
+	push	ax
+	mov	bx,sp
+	mov	ax,1
+	push	ax
+	push	bx
+	push	ax
+	call	__write
+	pop	bx
+	pop	bx
+	pop	bx
+	pop	bx
+	ret
diff --git a/mach/m65oo2/libem/rck.s b/mach/m65oo2/libem/rck.s
new file mode 100644
index 000000000..7af17c844
--- /dev/null
+++ b/mach/m65oo2/libem/rck.s
@@ -0,0 +1,20 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .rck
+
+	! descriptor address in bx
+	! value in ax, must be left there
+.rck:
+	cmp     ax,(bx)
+	jl      2f
+	cmp     ax,2(bx)
+	jg      2f
+	ret
+2:
+	push    ax
+.extern ERANGE
+.extern .error
+	mov     ax,ERANGE
+	call    .error
+	pop     ax
+	ret
diff --git a/mach/m65oo2/libem/ret6.s b/mach/m65oo2/libem/ret6.s
new file mode 100644
index 000000000..fe07db423
--- /dev/null
+++ b/mach/m65oo2/libem/ret6.s
@@ -0,0 +1,10 @@
+.sect .text
+.define .ret6
+.extern .retarea
+
+.ret6:
+	pop	bx
+	pop	(.retarea)
+	pop	(.retarea+2)
+	pop	(.retarea+4)
+	jmp	bx
diff --git a/mach/m65oo2/libem/ret8.s b/mach/m65oo2/libem/ret8.s
new file mode 100644
index 000000000..22878f8a1
--- /dev/null
+++ b/mach/m65oo2/libem/ret8.s
@@ -0,0 +1,11 @@
+.sect .text
+.define .ret8
+.extern .retarea
+
+.ret8:
+	pop	bx
+	pop	(.retarea)
+	pop	(.retarea+2)
+	pop	(.retarea+4)
+	pop	(.retarea+6)
+	jmp	bx
diff --git a/mach/m65oo2/libem/retarea.s b/mach/m65oo2/libem/retarea.s
new file mode 100644
index 000000000..52c99aac6
--- /dev/null
+++ b/mach/m65oo2/libem/retarea.s
@@ -0,0 +1,5 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define .retarea
+
+.retarea:
+	.space 8
diff --git a/mach/m65oo2/libem/return.s b/mach/m65oo2/libem/return.s
new file mode 100644
index 000000000..014cd7686
--- /dev/null
+++ b/mach/m65oo2/libem/return.s
@@ -0,0 +1,17 @@
+.define .sdret, .dsret, .sret, .dret, .cret 
+.sect .text
+
+.dsret:
+	pop	di
+.sret:
+	pop	si
+.cret:
+	mov	sp,bp
+	pop	bp
+	ret
+
+.sdret:
+	pop	si
+.dret:
+	pop	di
+	jmp	.cret
diff --git a/mach/m65oo2/libem/rmi.s b/mach/m65oo2/libem/rmi.s
new file mode 100644
index 000000000..43bde9f3e
--- /dev/null
+++ b/mach/m65oo2/libem/rmi.s
@@ -0,0 +1,39 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .rmi
+
+	! #bytes in ax
+.rmi:
+	pop     bx              ! return address
+	cmp     ax,2
+	jne     1f
+	pop     ax
+	cwd
+	pop     cx
+	idiv    cx
+	push    dx
+	jmp     bx
+1:
+	cmp     ax,4
+	jne     9f
+	pop     ax
+	pop     dx
+	pop     si
+	pop     di
+	push    bx
+	push    di
+	push    si
+	push    dx
+	push    ax
+.extern .rmi4
+	call   .rmi4
+	pop     bx
+	push    dx
+	push    ax
+	jmp     bx
+9:
+.extern EODDZ
+.extern .trp
+	mov     ax,EODDZ
+	push    bx
+	jmp     .trp
diff --git a/mach/m65oo2/libem/rmi4.s b/mach/m65oo2/libem/rmi4.s
new file mode 100644
index 000000000..05e3ce67a
--- /dev/null
+++ b/mach/m65oo2/libem/rmi4.s
@@ -0,0 +1,90 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .rmi4
+
+yl=6
+yh=8
+xl=10
+xh=12
+
+.rmi4:
+	push	si
+	push	di
+	mov     si,sp           ! copy of sp
+	mov     bx,yl(si)
+	mov     ax,yh(si)
+	cwd
+	cmp     dx,ax
+	jne     7f
+	and     dx,dx
+	jge     1f
+	neg     bx
+	je      7f
+1:
+	xor     dx,dx
+	mov     cx,xl(si)
+	mov     ax,xh(si)
+	and     ax,ax
+	jge     2f
+	neg     ax
+	neg     cx
+	sbb     ax,dx
+2:
+	div     bx
+	xchg    ax,cx
+	div     bx              ! dx= result(low), 0=result(high)
+	xor     bx,bx
+9:
+	cmp     xh(si),0
+	jge     1f
+	neg     bx
+	neg     dx
+	sbb     bx,0
+1:
+			! bx is high order result
+			! dx is low order result
+	mov	ax,dx
+	mov	dx,bx	! result in ax/dx
+	pop	di
+	pop	si
+	ret     8
+
+7:
+	mov     di,ax
+	xor     bx,bx
+	and     di,di
+	jge     1f
+	neg     di
+	neg     yl(si)
+	sbb     di,bx
+1:
+	mov     ax,xl(si)
+	mov     dx,xh(si)
+	and     dx,dx
+	jge     1f
+	neg     dx
+	neg     ax
+	sbb     dx,bx
+1:
+	mov     cx,16
+1:
+	shl     ax,1
+	rcl     dx,1
+	rcl     bx,1
+	cmp     di,bx
+	ja      3f
+	jb      2f
+	cmp     yl(si),dx
+	jbe     2f
+3:
+	loop    1b
+		! dx=result(low), bx=result(high)
+	jmp     9b
+2:
+	sub     dx,yl(si)
+	sbb     bx,di
+	inc     ax
+	loop    1b
+1:
+		! dx=result(low), bx=result(high)
+	jmp     9b
diff --git a/mach/m65oo2/libem/rmu.s b/mach/m65oo2/libem/rmu.s
new file mode 100644
index 000000000..4ed99722d
--- /dev/null
+++ b/mach/m65oo2/libem/rmu.s
@@ -0,0 +1,39 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .rmu
+
+	! #bytes in ax
+.rmu:
+	pop     bx              ! return address
+	cmp     ax,2
+	jne     1f
+	pop     ax
+	xor     dx,dx
+	pop     cx
+	idiv    cx
+	push    dx
+	jmp     bx
+1:
+	cmp     ax,4
+	jne     9f
+	pop     ax
+	pop     dx
+	pop     si
+	pop     di
+	push    bx
+	push    di
+	push    si
+	push    dx
+	push    ax
+.extern .rmu4
+	call   .rmu4
+	pop     bx
+	push    dx
+	push    ax
+	jmp     bx
+9:
+.extern EODDZ
+.extern .trp
+	mov     ax,EODDZ
+	push    bx
+	jmp     .trp
diff --git a/mach/m65oo2/libem/rmu4.s b/mach/m65oo2/libem/rmu4.s
new file mode 100644
index 000000000..4355d35b9
--- /dev/null
+++ b/mach/m65oo2/libem/rmu4.s
@@ -0,0 +1,62 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .rmu4
+
+yl=6
+yh=8
+xl=10
+xh=12
+
+.rmu4:
+	push	si
+	push	di
+	mov     si,sp           ! copy of sp
+	mov     bx,yl(si)
+	mov     ax,yh(si)
+	or      ax,ax
+	jne     7f
+1:
+	xor     dx,dx
+	mov     cx,xl(si)
+	mov     ax,xh(si)
+2:
+	div     bx
+	xchg    ax,cx
+	div     bx
+	xor     bx,bx
+9:
+			! bx is high order result
+			! dx is low order result
+	mov	ax,dx
+	mov	dx,bx
+	pop	di
+	pop	si
+	ret     8	! result in ax/dx
+
+7:
+	mov     di,ax
+	xor     bx,bx
+	mov     ax,xl(si)
+	mov     dx,xh(si)
+	mov     cx,16
+1:
+	shl     ax,1
+	rcl     dx,1
+	rcl     bx,1
+	cmp     di,bx
+	ja      3f
+	jb      2f
+	cmp     yl(si),dx
+	jbe     2f
+3:
+	loop    1b
+		! dx=result(low), bx=result(high)
+	jmp     9b
+2:
+	sub     dx,yl(si)
+	sbb     bx,di
+	inc     ax
+	loop    1b
+1:
+		! dx=result(low), bx=result(high)
+	jmp     9b
diff --git a/mach/m65oo2/libem/rol.s b/mach/m65oo2/libem/rol.s
new file mode 100644
index 000000000..2b2af4f8c
--- /dev/null
+++ b/mach/m65oo2/libem/rol.s
@@ -0,0 +1,36 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .rol
+
+	! #bytes in ax
+.rol:
+	pop     dx              ! return address
+	cmp     ax,2
+	jne     1f
+	pop     ax
+	pop     cx
+	rol     ax,cl
+	push    ax
+	jmp     dx
+1:
+	cmp     ax,4
+	jne     9f
+	pop     cx
+	jcxz    2f
+	pop     ax
+	pop     bx
+3:
+	sal     ax,1
+	rcl     bx,1
+	adc     ax,0
+	loop    3b
+	push    bx
+	push    ax
+2:
+	jmp     dx
+9:
+.extern EODDZ
+.extern .trp
+	mov     ax,EODDZ
+	push    dx
+	jmp     .trp
diff --git a/mach/m65oo2/libem/ror.s b/mach/m65oo2/libem/ror.s
new file mode 100644
index 000000000..d92069c22
--- /dev/null
+++ b/mach/m65oo2/libem/ror.s
@@ -0,0 +1,37 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .ror
+
+	! #bytes in ax
+.ror:
+	pop     dx              ! return address
+	cmp     ax,2
+	jne     1f
+	pop     ax
+	pop     cx
+	ror     ax,cl
+	push    ax
+	jmp     dx
+1:
+	cmp     ax,4
+	jne     9f
+	pop     cx
+	jcxz    2f
+	neg     cx
+	add     cx,32
+	pop     ax
+	pop     bx
+3:
+	sar     bx,1
+	rcr     ax,1
+	loop    3b
+	push    bx
+	push    ax
+2:
+	jmp     dx
+9:
+.extern EODDZ
+.extern .trp
+	mov     ax,EODDZ
+	push    dx
+	jmp     .trp
diff --git a/mach/m65oo2/libem/sar2.s b/mach/m65oo2/libem/sar2.s
new file mode 100644
index 000000000..0f40f9bd3
--- /dev/null
+++ b/mach/m65oo2/libem/sar2.s
@@ -0,0 +1,33 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .sar2
+
+.sar2:
+				! bx, descriptor address
+				! ax, index
+	pop	cx
+	pop	dx		! base address
+	push	cx
+	xchg	di,dx		! di = base address, dx is saved di
+	sub     ax,(bx)
+	mov     cx,4(bx)
+	push	dx
+	imul    cx
+	pop	dx
+	add     di,ax
+	sar     cx,1
+	jnb     1f
+	pop	bx
+	pop     ax
+	stosb
+	mov	di,dx
+	jmp     bx
+1:
+	pop	bx
+	mov	ax,si
+	mov     si,sp
+	rep movs
+	mov     sp,si
+	mov	si,ax
+	mov	di,dx
+	jmp     bx
diff --git a/mach/m65oo2/libem/sbi.s b/mach/m65oo2/libem/sbi.s
new file mode 100644
index 000000000..f5c81ebe0
--- /dev/null
+++ b/mach/m65oo2/libem/sbi.s
@@ -0,0 +1,30 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .sbi
+
+	! #bytes in cx , top of stack in ax
+.sbi:
+	pop     bx              ! return subress
+	cmp     cx,2
+	jne     1f
+	pop     cx
+	sub     ax,cx
+	neg     ax
+	jmp     bx
+1:
+	cmp     cx,4
+	jne     9f
+	pop     dx
+	pop     cx
+	sub     cx,ax
+	mov     ax,cx
+	pop     cx
+	sbb     cx,dx
+	push    cx
+	jmp     bx
+9:
+.extern EODDZ
+.extern .trp
+	mov     ax,EODDZ
+	push    bx
+	jmp     .trp
diff --git a/mach/m65oo2/libem/set.s b/mach/m65oo2/libem/set.s
new file mode 100644
index 000000000..2a030b8f4
--- /dev/null
+++ b/mach/m65oo2/libem/set.s
@@ -0,0 +1,42 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .set
+
+	! #bytes in cx
+	! bit # in ax
+.set:
+	pop     bx              ! return address
+	xor     dx,dx
+!ifdef create set
+	sub	sp,cx
+	push	bx
+	push	di
+	mov     bx,sp
+	xor	di,di
+	sar	cx,1
+1:
+	mov     4(bx)(di),dx
+	add	di,2
+	loop	1b
+!endif
+	mov     bx,8
+	div     bx
+	cmp     ax,di
+	jae     2f
+	mov	di,dx
+	movb	dl,bits(di)
+	mov     di,sp
+	add     di,ax
+	orb     4(di),dl
+	pop	di
+	ret
+2:
+.extern ESET
+.extern .trp
+	pop	di
+	mov     ax,ESET
+	jmp     .trp
+
+	.sect .data
+bits:
+	.data1   1,2,4,8,16,32,64,128
diff --git a/mach/m65oo2/libem/sli.s b/mach/m65oo2/libem/sli.s
new file mode 100644
index 000000000..4c4f98c2f
--- /dev/null
+++ b/mach/m65oo2/libem/sli.s
@@ -0,0 +1,35 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .sli
+
+	! #bytes in ax
+.sli:
+	pop     dx              ! return address
+	cmp     ax,2
+	jne     1f
+	pop     ax
+	pop     cx
+	sal     ax,cl
+	push    ax
+	jmp     dx
+1:
+	cmp     ax,4
+	jne     9f
+	pop     cx
+	jcxz    2f
+	pop     ax
+	pop     bx
+3:
+	sal     ax,1
+	rcl     bx,1
+	loop    3b
+	push    bx
+	push    ax
+2:
+	jmp     dx
+9:
+.extern EODDZ
+.extern .trp
+	mov     ax,EODDZ
+	push    dx
+	jmp     .trp
diff --git a/mach/m65oo2/libem/sri.s b/mach/m65oo2/libem/sri.s
new file mode 100644
index 000000000..e3e623a94
--- /dev/null
+++ b/mach/m65oo2/libem/sri.s
@@ -0,0 +1,35 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .sri
+
+	! #bytes in ax
+.sri:
+	pop     dx              ! return address
+	cmp     ax,2
+	jne     1f
+	pop     ax
+	pop     cx
+	sar     ax,cl
+	push    ax
+	jmp     dx
+1:
+	cmp     ax,4
+	jne     9f
+	pop     cx
+	jcxz    2f
+	pop     ax
+	pop     bx
+3:
+	sar     bx,1
+	rcr     ax,1
+	loop    3b
+	push    bx
+	push    ax
+2:
+	jmp     dx
+9:
+.extern EODDZ
+.extern .trp
+	mov     ax,EODDZ
+	push    dx
+	jmp     .trp
diff --git a/mach/m65oo2/libem/sti.s b/mach/m65oo2/libem/sti.s
new file mode 100644
index 000000000..7825928e4
--- /dev/null
+++ b/mach/m65oo2/libem/sti.s
@@ -0,0 +1,32 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .sti
+.define .sts
+
+	! #bytes in cx
+	! address in bx
+	! save di/si. they might be register variables
+.sts:
+	mov	dx,di		! save di
+	mov	di,bx
+	pop	bx
+	sar     cx,1
+	jnb     1f
+	pop     ax
+	stosb
+	mov	di,dx
+	jmp     bx
+.sti:
+	! only called with count > 4
+	mov	dx,di
+	mov	di,bx
+	pop	bx
+	sar	cx,1
+1:
+	mov	ax,si
+	mov     si,sp
+	rep movs
+	mov     sp,si
+	mov	di,dx
+	mov	si,ax
+	jmp     bx
diff --git a/mach/m65oo2/libem/strhp.s b/mach/m65oo2/libem/strhp.s
new file mode 100644
index 000000000..5bddb63ea
--- /dev/null
+++ b/mach/m65oo2/libem/strhp.s
@@ -0,0 +1,41 @@
+! $Source$
+! $State$
+! $Revision$
+
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define	.strhp
+.extern .reghp, .limhp, EHEAP, .trp
+
+! Updates the heap pointer:
+!
+! int .strhp(void* newpointer)
+!
+! .reghp is the current heap pointer;
+! .limhp is the current top of memory.
+!
+! If the desired new heap pointer is above the top of memory, then BRK is
+! called to extend the memory.
+
+.strhp:
+	pop	bx
+	pop	ax
+	mov	(.reghp),ax
+	cmp	ax,(.limhp)
+	jb	1f
+	add	ax,02000
+	and	ax,~0777
+	push	bx
+	push	ax
+	call	BRK
+	pop	cx
+	pop	bx
+	cmp	ax,-1
+	je	2f
+1:
+	mov	(.limhp),cx
+	jmp	bx
+2:
+	mov	ax,EHEAP
+	push	bx
+	jmp	.trp
diff --git a/mach/m65oo2/libem/trp.s b/mach/m65oo2/libem/trp.s
new file mode 100644
index 000000000..6d656ef12
--- /dev/null
+++ b/mach/m65oo2/libem/trp.s
@@ -0,0 +1,21 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .trp
+.define .stop
+.extern .trppc
+
+		! ax is trap number
+.trp:
+	xor     bx,bx
+	xchg    bx,(.trppc)
+	test    bx,bx
+	jz      2f
+	push    ax
+	call    bx
+	pop     ax
+	ret
+2:
+	call	.stop
+
+.stop:
+	jmp	EXIT
diff --git a/mach/m65oo2/libem/unknown.s b/mach/m65oo2/libem/unknown.s
new file mode 100644
index 000000000..a436afd48
--- /dev/null
+++ b/mach/m65oo2/libem/unknown.s
@@ -0,0 +1,9 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define .unknown
+.extern EILLINS, .fat
+
+.unknown:
+	mov  ax,EILLINS
+	push ax
+	jmp  .fat
diff --git a/mach/m65oo2/libem/xor.s b/mach/m65oo2/libem/xor.s
new file mode 100644
index 000000000..1167abf48
--- /dev/null
+++ b/mach/m65oo2/libem/xor.s
@@ -0,0 +1,18 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.sect .text
+.define	.xor
+
+	! #bytes in cx
+.xor:
+	pop	bx		! return address
+	mov	dx,di
+	mov	di,sp
+	add	di,cx
+	sar	cx,1
+1:
+	pop	ax
+	xor	ax,(di)
+	stos
+	loop	1b
+	mov	di,dx
+	jmp	bx
diff --git a/mach/m65oo2/libend/LIST b/mach/m65oo2/libend/LIST
new file mode 100644
index 000000000..2efbd3eb2
--- /dev/null
+++ b/mach/m65oo2/libend/LIST
@@ -0,0 +1,5 @@
+end_s.a
+edata.s
+em_end.s
+end.s
+etext.s
diff --git a/mach/m65oo2/libend/build.lua b/mach/m65oo2/libend/build.lua
new file mode 100644
index 000000000..bfbf21cd0
--- /dev/null
+++ b/mach/m65oo2/libend/build.lua
@@ -0,0 +1,13 @@
+for _, plat in ipairs(vars.plats) do
+	acklibrary {
+		name = "lib_"..plat,
+		srcs = {
+			"./edata.s",
+			"./em_end.s",
+			"./end.s",
+			"./etext.s",
+		},
+		vars = { plat = plat },
+	}
+end
+
diff --git a/mach/m65oo2/libend/edata.s b/mach/m65oo2/libend/edata.s
new file mode 100644
index 000000000..a742b6f11
--- /dev/null
+++ b/mach/m65oo2/libend/edata.s
@@ -0,0 +1,7 @@
+.sect .text
+.sect .rom
+.sect .data
+.sect .bss
+.define	_edata
+.sect .data
+_edata:
diff --git a/mach/m65oo2/libend/em_end.s b/mach/m65oo2/libend/em_end.s
new file mode 100644
index 000000000..e95664edd
--- /dev/null
+++ b/mach/m65oo2/libend/em_end.s
@@ -0,0 +1,20 @@
+! $Source$
+! $State$
+! $Revision$
+
+.sect .text
+.sect .rom
+.sect .data
+.sect .bss
+.sect .end ! only for declaration of _end, __end and endbss.
+.define	endtext, endrom, enddata, endbss, __end
+
+	.sect .text
+endtext:
+	.sect .rom
+endrom:
+	.sect .data
+enddata:
+	.sect .end
+__end:
+endbss:
diff --git a/mach/m65oo2/libend/end.s b/mach/m65oo2/libend/end.s
new file mode 100644
index 000000000..93a1e6e00
--- /dev/null
+++ b/mach/m65oo2/libend/end.s
@@ -0,0 +1,7 @@
+.sect .text
+.sect .rom
+.sect .data
+.sect .bss
+.define	_end
+.sect .end ! only for declaration of _end, __end and endbss.
+_end:
diff --git a/mach/m65oo2/libend/etext.s b/mach/m65oo2/libend/etext.s
new file mode 100644
index 000000000..6651ca96e
--- /dev/null
+++ b/mach/m65oo2/libend/etext.s
@@ -0,0 +1,7 @@
+.sect .text
+.sect .rom
+.sect .data
+.sect .bss
+.define	_etext
+.sect .text
+_etext:
diff --git a/mach/m65oo2/libfp/byte_order.h b/mach/m65oo2/libfp/byte_order.h
new file mode 100644
index 000000000..d08b45a5d
--- /dev/null
+++ b/mach/m65oo2/libfp/byte_order.h
@@ -0,0 +1,6 @@
+#define CHAR_UNSIGNED	0
+#define MSB_AT_LOW_ADDRESS	0
+#define MSW_AT_LOW_ADDRESS	0
+#define FL_MSB_AT_LOW_ADDRESS	0
+#define FL_MSW_AT_LOW_ADDRESS	0
+#define FL_MSL_AT_LOW_ADDRESS	0
diff --git a/mach/m65oo2/libsys/LIST b/mach/m65oo2/libsys/LIST
new file mode 100644
index 000000000..7e4d92ffa
--- /dev/null
+++ b/mach/m65oo2/libsys/LIST
@@ -0,0 +1,76 @@
+libmon_s.a
+_alarm.s
+_sbrk.s
+_brk.s
+_close.s
+_creat.s
+_dup.s
+_execl.s
+_execve.s
+_fork.s
+_fstat.s
+_ftime.s
+_getpid.s
+_gtty.s
+_ioctl.s
+_kill.s
+_link.s
+_lseek.s
+_open.s
+_pause.s
+_pipe.s
+_read.s
+_unlink.s
+_wait.s
+_write.s
+exit.s
+_exit.s
+abort.s
+access.s
+chdir.s
+chmod.s
+chown.s
+cleanup.s
+close.s
+creat.s
+dup.s
+execl.s
+execle.s
+execv.s
+execve.s
+time.s
+exece.s
+fork.s
+fstat.s
+getgid.s
+getpid.s
+getuid.s
+gtty.s
+stty.s
+ioctl.s
+kill.s
+link.s
+lseek.s
+mknod.s
+mount.s
+nice.s
+open.s
+pipe.s
+profil.s
+read.s
+sbrk.s
+brk.s
+setgid.s
+setuid.s
+signal.s
+stat.s
+sync.s
+umount.s
+unlink.s
+wait.s
+write.s
+cerror.s
+error.s
+pause.s
+alarm.s
+ftime.s
diff --git a/mach/m65oo2/libsys/_alarm.s b/mach/m65oo2/libsys/_alarm.s
new file mode 100644
index 000000000..5f70bde41
--- /dev/null
+++ b/mach/m65oo2/libsys/_alarm.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __alarm
+.extern __alarm, cerror
+__alarm:	int 0x9b
+	jb 9f
+	ret
+9:
+	jmp cerror
diff --git a/mach/m65oo2/libsys/_brk.s b/mach/m65oo2/libsys/_brk.s
new file mode 100644
index 000000000..00bde7da7
--- /dev/null
+++ b/mach/m65oo2/libsys/_brk.s
@@ -0,0 +1,32 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __brk
+.define xbrk
+__brk:	
+	mov bx,sp
+	mov ax,2(bx)
+	mov cx,sp
+	sub cx,128
+	jbe 1f
+	mov bx,(.limhp)
+	mov (.limhp),ax
+	sub ax,bx
+	jbe 2f
+	call xbrk
+2:
+	xor ax,ax
+	ret
+1:
+	mov ax,0xc
+	jmp cerror
+xbrk:
+	push di
+	mov di,bx
+	mov cx,ax
+	xor ax,ax
+	shr cx,1
+	repz stos
+	jae 3f
+	stosb
+3:
+	pop di
+	ret
diff --git a/mach/m65oo2/libsys/_close.s b/mach/m65oo2/libsys/_close.s
new file mode 100644
index 000000000..c3a9b91cb
--- /dev/null
+++ b/mach/m65oo2/libsys/_close.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __close
+.extern __close, cerror
+__close:	int 0x86
+	jb 9f
+	xor ax,ax
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/_creat.s b/mach/m65oo2/libsys/_creat.s
new file mode 100644
index 000000000..2af32a198
--- /dev/null
+++ b/mach/m65oo2/libsys/_creat.s
@@ -0,0 +1,7 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __creat
+.extern __creat, cerror
+__creat:	int 0x88
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/_dup.s b/mach/m65oo2/libsys/_dup.s
new file mode 100644
index 000000000..8b96e6e93
--- /dev/null
+++ b/mach/m65oo2/libsys/_dup.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+
+.define __dup
+.extern __dup, cerror
+__dup:	int 0xc9
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/_execl.s b/mach/m65oo2/libsys/_execl.s
new file mode 100644
index 000000000..9ae7d4853
--- /dev/null
+++ b/mach/m65oo2/libsys/_execl.s
@@ -0,0 +1,20 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+
+.define __execl
+.extern __execl, _environ, __execve
+__execl:
+	push	si
+	push	di
+	push	bp
+	mov	bp,sp
+	push	(_environ)
+	lea	ax,10(bp)
+	push	ax
+	push	8(bp)
+	call	__execve
+	add	sp,6
+	mov	sp,bp
+	pop	bp
+	pop	di
+	pop	si
+	ret
diff --git a/mach/m65oo2/libsys/_execve.s b/mach/m65oo2/libsys/_execve.s
new file mode 100644
index 000000000..c6a7e03a4
--- /dev/null
+++ b/mach/m65oo2/libsys/_execve.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __execve
+.extern __execve, cerror
+__execve:
+	int 0x8b
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/_exit.s b/mach/m65oo2/libsys/_exit.s
new file mode 100644
index 000000000..0f138b88c
--- /dev/null
+++ b/mach/m65oo2/libsys/_exit.s
@@ -0,0 +1,10 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __exit
+.sect .text
+__exit:
+	mov bx,sp
+	xor ax,ax
+	push ax	! unused memory
+	push 2(bx)
+	push ax	! dummy return address
+	int 0x81
diff --git a/mach/m65oo2/libsys/_fork.s b/mach/m65oo2/libsys/_fork.s
new file mode 100644
index 000000000..a61b18a5e
--- /dev/null
+++ b/mach/m65oo2/libsys/_fork.s
@@ -0,0 +1,11 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __fork
+.extern __fork, cerror
+__fork:	int 0x82
+	jmp 1f
+	jae 2f
+	jmp cerror
+1:
+	xor ax,ax
+2:
+	ret
diff --git a/mach/m65oo2/libsys/_fstat.s b/mach/m65oo2/libsys/_fstat.s
new file mode 100644
index 000000000..869102a67
--- /dev/null
+++ b/mach/m65oo2/libsys/_fstat.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __fstat
+.extern __fstat, cerror
+__fstat:	int 0x9c
+	jb 9f
+	xor ax,ax
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/_ftime.s b/mach/m65oo2/libsys/_ftime.s
new file mode 100644
index 000000000..aa5d5ebf9
--- /dev/null
+++ b/mach/m65oo2/libsys/_ftime.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __ftime
+.extern __ftime, cerror
+__ftime:	int 0xa3
+	jb 9f
+	ret
+9:
+	jmp cerror
diff --git a/mach/m65oo2/libsys/_getpid.s b/mach/m65oo2/libsys/_getpid.s
new file mode 100644
index 000000000..0aaedff51
--- /dev/null
+++ b/mach/m65oo2/libsys/_getpid.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __getpid
+.extern __getpid, cerror
+__getpid:	int 0x94
+	jb 9f
+	ret
+9:
+	jmp cerror
diff --git a/mach/m65oo2/libsys/_gtty.s b/mach/m65oo2/libsys/_gtty.s
new file mode 100644
index 000000000..79c75e43f
--- /dev/null
+++ b/mach/m65oo2/libsys/_gtty.s
@@ -0,0 +1,15 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __gtty
+.extern __gtty, __ioctl
+__gtty:
+	push	bp
+	mov	bp,sp
+push 6(bp)
+mov ax,0x5401
+push ax
+push 4(bp)
+call __ioctl
+add sp,6
+mov sp,bp
+pop bp
+ret
diff --git a/mach/m65oo2/libsys/_ioctl.s b/mach/m65oo2/libsys/_ioctl.s
new file mode 100644
index 000000000..f42533990
--- /dev/null
+++ b/mach/m65oo2/libsys/_ioctl.s
@@ -0,0 +1,7 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __ioctl
+.extern __ioctl, cerror
+__ioctl:	int 0xb6
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/_kill.s b/mach/m65oo2/libsys/_kill.s
new file mode 100644
index 000000000..18f4590d6
--- /dev/null
+++ b/mach/m65oo2/libsys/_kill.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __kill
+.extern __kill, cerror
+__kill:	int 0xa5
+	jb 9f
+	xor ax,ax
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/_link.s b/mach/m65oo2/libsys/_link.s
new file mode 100644
index 000000000..8ecd92d66
--- /dev/null
+++ b/mach/m65oo2/libsys/_link.s
@@ -0,0 +1,7 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __link
+.extern __link, cerror
+__link:	int 0x89
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/_lseek.s b/mach/m65oo2/libsys/_lseek.s
new file mode 100644
index 000000000..ba5e861a8
--- /dev/null
+++ b/mach/m65oo2/libsys/_lseek.s
@@ -0,0 +1,7 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __lseek
+.extern __lseek, cerror
+__lseek:	int 0x93
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/_open.s b/mach/m65oo2/libsys/_open.s
new file mode 100644
index 000000000..e411555c4
--- /dev/null
+++ b/mach/m65oo2/libsys/_open.s
@@ -0,0 +1,7 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __open
+.extern __open, cerror
+__open:	int 0x85
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/_pause.s b/mach/m65oo2/libsys/_pause.s
new file mode 100644
index 000000000..6e980d93d
--- /dev/null
+++ b/mach/m65oo2/libsys/_pause.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __pause
+.extern __pause, cerror
+__pause:	int 0x9d
+	jb 9f
+	ret
+9:
+	jmp cerror
diff --git a/mach/m65oo2/libsys/_pipe.s b/mach/m65oo2/libsys/_pipe.s
new file mode 100644
index 000000000..46433e9ac
--- /dev/null
+++ b/mach/m65oo2/libsys/_pipe.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __pipe
+.extern __pipe, cerror
+__pipe:	int 0xaa
+	jb 9f
+	xor ax,ax
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/_read.s b/mach/m65oo2/libsys/_read.s
new file mode 100644
index 000000000..f79558c95
--- /dev/null
+++ b/mach/m65oo2/libsys/_read.s
@@ -0,0 +1,7 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __read
+.extern __read, cerror
+__read:	int 0x83
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/_sbrk.s b/mach/m65oo2/libsys/_sbrk.s
new file mode 100644
index 000000000..f9b34b0ea
--- /dev/null
+++ b/mach/m65oo2/libsys/_sbrk.s
@@ -0,0 +1,24 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __sbrk
+__sbrk:
+push	bp
+mov	bp,sp
+mov	ax,4(bp)
+mov	bx,(.limhp)
+add	ax,bx
+mov	cx,sp
+sub	cx,128
+sub	cx,ax
+jbe	1f
+mov	(.limhp),ax
+sub	ax,bx
+jbe	2f
+call	xbrk
+2:
+mov	ax,bx
+pop	bp
+ret
+1:
+mov	ax,0xc
+pop	bp
+jmp	cerror
diff --git a/mach/m65oo2/libsys/_unlink.s b/mach/m65oo2/libsys/_unlink.s
new file mode 100644
index 000000000..bc344c065
--- /dev/null
+++ b/mach/m65oo2/libsys/_unlink.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __unlink
+.extern __unlink, cerror
+__unlink:	int 0x8a
+	jb 9f
+	xor ax,ax
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/_wait.s b/mach/m65oo2/libsys/_wait.s
new file mode 100644
index 000000000..e43ea9345
--- /dev/null
+++ b/mach/m65oo2/libsys/_wait.s
@@ -0,0 +1,17 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __wait
+.extern __wait, cerror
+__wait:
+	mov bx,sp
+	mov ax,2	! void info about unused memory
+	! Should be 0 according to /usr/include/sys.s, but
+	! that doesn't work
+	push ax
+	push 2(bx)
+	push ax		! dummy return address
+	int 0x87
+	jb 9f
+	add sp,6
+	ret
+9:	add sp,6
+	jmp cerror
diff --git a/mach/m65oo2/libsys/_write.s b/mach/m65oo2/libsys/_write.s
new file mode 100644
index 000000000..d6f7d0bab
--- /dev/null
+++ b/mach/m65oo2/libsys/_write.s
@@ -0,0 +1,7 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __write
+.extern __write, cerror
+__write:	int 0x84
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/abort.s b/mach/m65oo2/libsys/abort.s
new file mode 100644
index 000000000..bd6d7544f
--- /dev/null
+++ b/mach/m65oo2/libsys/abort.s
@@ -0,0 +1,13 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _abort
+.extern _abort
+_abort:	push	si
+	push	di
+	push	bp
+	mov	bp,sp
+	int	128
+	mov	sp,bp
+	pop	bp
+	pop	di
+	pop	si
+	ret
diff --git a/mach/m65oo2/libsys/access.s b/mach/m65oo2/libsys/access.s
new file mode 100644
index 000000000..f0059aa08
--- /dev/null
+++ b/mach/m65oo2/libsys/access.s
@@ -0,0 +1,9 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _access
+.extern _access, cerror
+_access:	int 0xa1
+	jb 9f
+	xor ax,ax
+	ret
+9:
+	jmp cerror
diff --git a/mach/m65oo2/libsys/alarm.s b/mach/m65oo2/libsys/alarm.s
new file mode 100644
index 000000000..df92e8922
--- /dev/null
+++ b/mach/m65oo2/libsys/alarm.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _alarm
+.extern _alarm, cerror
+_alarm:	int 0x9b
+	jb 9f
+	ret
+9:
+	jmp cerror
diff --git a/mach/m65oo2/libsys/brk.s b/mach/m65oo2/libsys/brk.s
new file mode 100644
index 000000000..0756697a5
--- /dev/null
+++ b/mach/m65oo2/libsys/brk.s
@@ -0,0 +1,4 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _brk
+_brk:	
+	jmp __brk
diff --git a/mach/m65oo2/libsys/build.lua b/mach/m65oo2/libsys/build.lua
new file mode 100644
index 000000000..ca5a13c65
--- /dev/null
+++ b/mach/m65oo2/libsys/build.lua
@@ -0,0 +1,8 @@
+for _, plat in ipairs(vars.plats) do
+	acklibrary {
+		name = "lib_"..plat,
+		srcs = { "./*.s" },
+		vars = { plat = plat },
+	}
+end
+
diff --git a/mach/m65oo2/libsys/cerror.s b/mach/m65oo2/libsys/cerror.s
new file mode 100644
index 000000000..fad3993d7
--- /dev/null
+++ b/mach/m65oo2/libsys/cerror.s
@@ -0,0 +1,9 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define cerror
+.extern cerror
+.extern _errno
+cerror:
+	mov (_errno),ax
+	mov dx,-1
+	mov ax,dx
+	ret
diff --git a/mach/m65oo2/libsys/chdir.s b/mach/m65oo2/libsys/chdir.s
new file mode 100644
index 000000000..c5012f943
--- /dev/null
+++ b/mach/m65oo2/libsys/chdir.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _chdir
+.extern _chdir, cerror
+_chdir:	int 0x8c
+	jb 9f
+	xor ax,ax
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/chmod.s b/mach/m65oo2/libsys/chmod.s
new file mode 100644
index 000000000..298babefd
--- /dev/null
+++ b/mach/m65oo2/libsys/chmod.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _chmod
+.extern _chmod, cerror
+_chmod:	int 0x8f
+	jb 9f
+	xor ax,ax
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/chown.s b/mach/m65oo2/libsys/chown.s
new file mode 100644
index 000000000..dc39ab6a4
--- /dev/null
+++ b/mach/m65oo2/libsys/chown.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _chown
+.extern _chown, cerror
+_chown: int 0x90
+	jb 9f
+	xor ax,ax
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/cleanup.s b/mach/m65oo2/libsys/cleanup.s
new file mode 100644
index 000000000..61db5665f
--- /dev/null
+++ b/mach/m65oo2/libsys/cleanup.s
@@ -0,0 +1,9 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define __cleanup
+.extern __cleanup
+__cleanup:
+	push	bp
+	mov	bp,sp
+mov sp,bp
+pop bp
+ret
diff --git a/mach/m65oo2/libsys/close.s b/mach/m65oo2/libsys/close.s
new file mode 100644
index 000000000..29e7b03d4
--- /dev/null
+++ b/mach/m65oo2/libsys/close.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _close
+.extern _close, cerror
+_close:	int 0x86
+	jb 9f
+	xor ax,ax
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/creat.s b/mach/m65oo2/libsys/creat.s
new file mode 100644
index 000000000..ababb8646
--- /dev/null
+++ b/mach/m65oo2/libsys/creat.s
@@ -0,0 +1,7 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _creat
+.extern _creat, cerror
+_creat:	int 0x88
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/dup.s b/mach/m65oo2/libsys/dup.s
new file mode 100644
index 000000000..d0e6ba092
--- /dev/null
+++ b/mach/m65oo2/libsys/dup.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+
+.define _dup
+.extern _dup, cerror
+_dup:	int 0xc9
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/error.s b/mach/m65oo2/libsys/error.s
new file mode 100644
index 000000000..ec32cc390
--- /dev/null
+++ b/mach/m65oo2/libsys/error.s
@@ -0,0 +1,7 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+.define _errno
+.extern _errno
+
+_errno:
+	.space 2
+.sect .text
diff --git a/mach/m65oo2/libsys/exece.s b/mach/m65oo2/libsys/exece.s
new file mode 100644
index 000000000..c2495ad6a
--- /dev/null
+++ b/mach/m65oo2/libsys/exece.s
@@ -0,0 +1,7 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _exece
+.extern _exece, cerror
+_exece:	int 0xdb
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/execl.s b/mach/m65oo2/libsys/execl.s
new file mode 100644
index 000000000..9f2130f24
--- /dev/null
+++ b/mach/m65oo2/libsys/execl.s
@@ -0,0 +1,20 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+
+.define _execl
+.extern _execl, _environ, _execve
+_execl:
+	push	si
+	push	di
+	push	bp
+	mov	bp,sp
+	push	(_environ)
+	lea	ax,10(bp)
+	push	ax
+	push	8(bp)
+	call	_execve
+	add	sp,6
+	mov	sp,bp
+	pop	bp
+	pop	di
+	pop	si
+	ret
diff --git a/mach/m65oo2/libsys/execle.s b/mach/m65oo2/libsys/execle.s
new file mode 100644
index 000000000..bba540835
--- /dev/null
+++ b/mach/m65oo2/libsys/execle.s
@@ -0,0 +1,24 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _execle
+.extern _execle, _execve
+_execle:
+	push	si
+	push	di
+	push	bp
+	mov	bp,sp
+	lea	si,10(bp)
+1:	mov	di,si
+	add	si,2
+	cmp	(di),0
+	jne	1b
+	push	(si)
+	lea	ax,10(bp)
+	push	ax
+	push	8(bp)
+	call	_execve
+	add	sp,6
+	mov	sp,bp
+	pop	bp
+	pop	di
+	pop	si
+	ret
diff --git a/mach/m65oo2/libsys/execv.s b/mach/m65oo2/libsys/execv.s
new file mode 100644
index 000000000..bbbc2e63f
--- /dev/null
+++ b/mach/m65oo2/libsys/execv.s
@@ -0,0 +1,12 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _execv
+.extern _execv, _environ, cerror
+_execv:
+	mov	bx,sp
+	push	(_environ)
+	push	4(bx)
+	push	2(bx)
+	push	ax
+	int	0xbb
+	add	sp,8
+	jmp	cerror
diff --git a/mach/m65oo2/libsys/execve.s b/mach/m65oo2/libsys/execve.s
new file mode 100644
index 000000000..964b6b9c4
--- /dev/null
+++ b/mach/m65oo2/libsys/execve.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _execve
+.extern _execve, cerror
+_execve:
+	int 0x8b
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/exit.s b/mach/m65oo2/libsys/exit.s
new file mode 100644
index 000000000..28cfca10d
--- /dev/null
+++ b/mach/m65oo2/libsys/exit.s
@@ -0,0 +1,13 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _exit
+.extern _exit, __cleanup, __exit
+_exit:
+	push	bp
+	mov	bp,sp
+call __cleanup
+push 4(bp)
+call __exit
+pop si
+mov sp,bp
+pop bp
+ret
diff --git a/mach/m65oo2/libsys/fork.s b/mach/m65oo2/libsys/fork.s
new file mode 100644
index 000000000..e280f58db
--- /dev/null
+++ b/mach/m65oo2/libsys/fork.s
@@ -0,0 +1,11 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _fork
+.extern _fork, cerror
+_fork:	int 0x82
+	jmp 1f
+	jae 2f
+	jmp cerror
+1:
+	xor ax,ax
+2:
+	ret
diff --git a/mach/m65oo2/libsys/fstat.s b/mach/m65oo2/libsys/fstat.s
new file mode 100644
index 000000000..d7977f9e2
--- /dev/null
+++ b/mach/m65oo2/libsys/fstat.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _fstat
+.extern _fstat, cerror
+_fstat:	int 0x9c
+	jb 9f
+	xor ax,ax
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/ftime.s b/mach/m65oo2/libsys/ftime.s
new file mode 100644
index 000000000..be3604fd3
--- /dev/null
+++ b/mach/m65oo2/libsys/ftime.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _ftime
+.extern _ftime, cerror
+_ftime:	int 0xa3
+	jb 9f
+	ret
+9:
+	jmp cerror
diff --git a/mach/m65oo2/libsys/getgid.s b/mach/m65oo2/libsys/getgid.s
new file mode 100644
index 000000000..dc769aec3
--- /dev/null
+++ b/mach/m65oo2/libsys/getgid.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _getgid
+.extern _getgid, cerror
+_getgid:	int 0xaf
+	jb 9f
+	ret
+9:
+	jmp cerror
diff --git a/mach/m65oo2/libsys/getpid.s b/mach/m65oo2/libsys/getpid.s
new file mode 100644
index 000000000..8300a7af9
--- /dev/null
+++ b/mach/m65oo2/libsys/getpid.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _getpid
+.extern _getpid, cerror
+_getpid:	int 0x94
+	jb 9f
+	ret
+9:
+	jmp cerror
diff --git a/mach/m65oo2/libsys/getuid.s b/mach/m65oo2/libsys/getuid.s
new file mode 100644
index 000000000..ff5d6fa8a
--- /dev/null
+++ b/mach/m65oo2/libsys/getuid.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _getuid
+.extern _getuid, cerror
+_getuid:	int 0x98
+	jb 9f
+	ret
+9:
+	jmp cerror
diff --git a/mach/m65oo2/libsys/gtty.s b/mach/m65oo2/libsys/gtty.s
new file mode 100644
index 000000000..58569489a
--- /dev/null
+++ b/mach/m65oo2/libsys/gtty.s
@@ -0,0 +1,15 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _gtty
+.extern _gtty, _ioctl
+_gtty:
+	push	bp
+	mov	bp,sp
+push 6(bp)
+mov ax,0x5401
+push ax
+push 4(bp)
+call _ioctl
+add sp,6
+mov sp,bp
+pop bp
+ret
diff --git a/mach/m65oo2/libsys/head_em.s b/mach/m65oo2/libsys/head_em.s
new file mode 100644
index 000000000..28d169ab9
--- /dev/null
+++ b/mach/m65oo2/libsys/head_em.s
@@ -0,0 +1,50 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss
+
+.define begtext,begdata,begbss
+.define hol0,.reghp,.limhp,.trppc,.ignmask
+.define ERANGE,ESET,EHEAP,ECASE,EILLINS,EIDIVZ,EODDZ
+.define EXIT, BRK
+.extern _end
+
+ERANGE          = 1
+ESET            = 2
+EIDIVZ          = 6
+EHEAP           = 17
+EILLINS         = 18
+EODDZ           = 19
+ECASE           = 20
+
+.sect .text
+begtext:
+	mov bx,sp
+	mov cx,(bx)
+	add bx,2
+	mov ax,cx
+	inc ax
+	shl ax,1
+	add ax,bx
+	push ax
+	push bx
+	push cx
+	xor bp,bp
+	call    __m_a_i_n
+EXIT:
+	int 0x81     
+BRK:
+	jmp	__brk
+.sect	.data
+begdata:
+hol0:
+	.data2   0,0
+	.data2   0,0
+.reghp:
+	.data2   endbss
+.limhp:
+	.data2   endbss
+.ignmask:
+	.data2   0
+.trppc:
+	.data2   0
+
+	.sect .bss
+begbss:
diff --git a/mach/m65oo2/libsys/ioctl.s b/mach/m65oo2/libsys/ioctl.s
new file mode 100644
index 000000000..b7e24279a
--- /dev/null
+++ b/mach/m65oo2/libsys/ioctl.s
@@ -0,0 +1,7 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _ioctl
+.extern _ioctl, cerror
+_ioctl:	int 0xb6
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/kill.s b/mach/m65oo2/libsys/kill.s
new file mode 100644
index 000000000..3c6ce5267
--- /dev/null
+++ b/mach/m65oo2/libsys/kill.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _kill
+.extern _kill, cerror
+_kill:	int 0xa5
+	jb 9f
+	xor ax,ax
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/link.s b/mach/m65oo2/libsys/link.s
new file mode 100644
index 000000000..0be0cf2e5
--- /dev/null
+++ b/mach/m65oo2/libsys/link.s
@@ -0,0 +1,7 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _link
+.extern _link, cerror
+_link:	int 0x89
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/lseek.s b/mach/m65oo2/libsys/lseek.s
new file mode 100644
index 000000000..a54326b1c
--- /dev/null
+++ b/mach/m65oo2/libsys/lseek.s
@@ -0,0 +1,7 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _lseek
+.extern _lseek, cerror
+_lseek:	int 0x93
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/mknod.s b/mach/m65oo2/libsys/mknod.s
new file mode 100644
index 000000000..0d6aa3db6
--- /dev/null
+++ b/mach/m65oo2/libsys/mknod.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _mknod
+.extern _mknod, cerror
+_mknod:	int 0x8e
+	jb 9f
+	xor ax,ax
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/mount.s b/mach/m65oo2/libsys/mount.s
new file mode 100644
index 000000000..ad3e4b2cf
--- /dev/null
+++ b/mach/m65oo2/libsys/mount.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _mount
+.extern _mount, cerror
+_mount:	int 0x95
+	jb 9f
+	xor ax,ax
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/nice.s b/mach/m65oo2/libsys/nice.s
new file mode 100644
index 000000000..1e8977425
--- /dev/null
+++ b/mach/m65oo2/libsys/nice.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _nice
+.extern _nice, cerror
+_nice:	int 0xa2
+	jb 9f
+	ret
+9:
+	jmp cerror
diff --git a/mach/m65oo2/libsys/open.s b/mach/m65oo2/libsys/open.s
new file mode 100644
index 000000000..2cf6df3c3
--- /dev/null
+++ b/mach/m65oo2/libsys/open.s
@@ -0,0 +1,7 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _open
+.extern _open, cerror
+_open:	int 0x85
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/pause.s b/mach/m65oo2/libsys/pause.s
new file mode 100644
index 000000000..05a6fe701
--- /dev/null
+++ b/mach/m65oo2/libsys/pause.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _pause
+.extern _pause, cerror
+_pause:	int 0x9d
+	jb 9f
+	ret
+9:
+	jmp cerror
diff --git a/mach/m65oo2/libsys/pipe.s b/mach/m65oo2/libsys/pipe.s
new file mode 100644
index 000000000..47865c829
--- /dev/null
+++ b/mach/m65oo2/libsys/pipe.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _pipe
+.extern _pipe, cerror
+_pipe:	int 0xaa
+	jb 9f
+	xor ax,ax
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/profil.s b/mach/m65oo2/libsys/profil.s
new file mode 100644
index 000000000..52e3b7fb9
--- /dev/null
+++ b/mach/m65oo2/libsys/profil.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _profil
+.extern _profil, cerror
+_profil:	int 0xac
+	jb 9f
+	ret
+9:
+	jmp cerror
diff --git a/mach/m65oo2/libsys/read.s b/mach/m65oo2/libsys/read.s
new file mode 100644
index 000000000..a9839bf62
--- /dev/null
+++ b/mach/m65oo2/libsys/read.s
@@ -0,0 +1,7 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _read
+.extern _read, cerror
+_read:	int 0x83
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/sbrk.s b/mach/m65oo2/libsys/sbrk.s
new file mode 100644
index 000000000..3cd593f95
--- /dev/null
+++ b/mach/m65oo2/libsys/sbrk.s
@@ -0,0 +1,4 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _sbrk
+_sbrk:
+	jmp __sbrk
diff --git a/mach/m65oo2/libsys/setgid.s b/mach/m65oo2/libsys/setgid.s
new file mode 100644
index 000000000..52f9b11e2
--- /dev/null
+++ b/mach/m65oo2/libsys/setgid.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _setgid
+.extern _setgid, cerror
+setgid:	int 0xae
+	jb 9f
+	xor ax,ax
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/setuid.s b/mach/m65oo2/libsys/setuid.s
new file mode 100644
index 000000000..e27c0fd14
--- /dev/null
+++ b/mach/m65oo2/libsys/setuid.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _setuid
+.extern _setuid, cerror
+_setuid:	int 0x97
+	jb 9f
+	xor ax,ax
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/signal.s b/mach/m65oo2/libsys/signal.s
new file mode 100644
index 000000000..2577eaeb8
--- /dev/null
+++ b/mach/m65oo2/libsys/signal.s
@@ -0,0 +1,62 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _signal
+.extern _signal, cerror
+NSIG=16
+_signal:	mov	bx,sp
+	mov cx,4(bx)
+	mov bx,2(bx)
+	cmp bx,NSIG
+	jae 1f
+	shl bx,1
+	mov dx,dvect(bx)
+	cmp cx,1
+	jbe 2f
+	mov dvect(bx),cx
+	mov bx,sp
+	mov 4(bx),entry
+	mov bx,dx
+	int 0xb0
+	mov dx,bx
+	mov bx,sp
+	mov 4(bx),cx
+	jb 3f
+	jmp 4f
+2:
+	int 0xb0
+	jb 3f
+	mov dvect(bx),cx
+4:
+	cmp ax,1
+	jbe 5f
+	mov ax,dx
+5:
+	ret
+1:
+	mov ax,22
+3:
+	jmp cerror
+
+entry:
+	push bx
+	push cx
+	push dx
+	push di
+	push si
+	mov bx,sp
+	mov di,10(bx)
+	mov 10(bx),ax
+	push di
+	shl di,1
+	call dvect(di)
+	add sp,2
+	pop si
+	pop di
+	pop dx
+	pop cx
+	pop bx
+	pop ax
+	popf
+	ret
+.sect .bss
+dvect:	.space 2*NSIG
+.sect .text
diff --git a/mach/m65oo2/libsys/stat.s b/mach/m65oo2/libsys/stat.s
new file mode 100644
index 000000000..31153b4a7
--- /dev/null
+++ b/mach/m65oo2/libsys/stat.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _stat
+.extern _stat, cerror
+_stat:	int 0x92
+	jb 9f
+	xor ax,ax
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/stty.s b/mach/m65oo2/libsys/stty.s
new file mode 100644
index 000000000..01efaba6f
--- /dev/null
+++ b/mach/m65oo2/libsys/stty.s
@@ -0,0 +1,15 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _stty
+.extern _stty, _ioctl
+_stty:
+	push	bp
+	mov	bp,sp
+push 6(bp)
+mov ax,0x5402
+push ax
+push 4(bp)
+call _ioctl
+add sp,6
+mov sp,bp
+pop bp
+ret
diff --git a/mach/m65oo2/libsys/sync.s b/mach/m65oo2/libsys/sync.s
new file mode 100644
index 000000000..973cc27a6
--- /dev/null
+++ b/mach/m65oo2/libsys/sync.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _sync
+.extern _sync, cerror
+_sync:	int 0xa4
+	jb 9f
+	ret
+9:
+	jmp cerror
diff --git a/mach/m65oo2/libsys/time.s b/mach/m65oo2/libsys/time.s
new file mode 100644
index 000000000..ec87adb63
--- /dev/null
+++ b/mach/m65oo2/libsys/time.s
@@ -0,0 +1,27 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _time
+.extern _time, _ftime
+_time:
+	push	si
+	push	di
+	push	bp
+	mov	bp,sp
+	sub	sp,10
+	lea	ax,-10(bp)
+	push	ax
+	call	_ftime
+	add	sp,2
+	cmp	8(bp),0
+	je	1f
+	mov	ax,-10(bp)
+	mov	dx,-8(bp)
+	mov	di,8(bp)
+	mov	(di),ax
+	mov	2(di),dx
+1:	mov	ax,-10(bp)
+	mov	dx,-8(bp)
+	mov	sp,bp
+	pop	bp
+	pop	di
+	pop	si
+	ret
diff --git a/mach/m65oo2/libsys/umount.s b/mach/m65oo2/libsys/umount.s
new file mode 100644
index 000000000..bee18150e
--- /dev/null
+++ b/mach/m65oo2/libsys/umount.s
@@ -0,0 +1,9 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _umount
+.extern _umount, cerror
+_umount:	int 0x96
+	jb 9f
+	xor ax,ax
+	ret
+9:
+	jmp cerror
diff --git a/mach/m65oo2/libsys/unlink.s b/mach/m65oo2/libsys/unlink.s
new file mode 100644
index 000000000..6d5459975
--- /dev/null
+++ b/mach/m65oo2/libsys/unlink.s
@@ -0,0 +1,8 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _unlink
+.extern _unlink, cerror
+_unlink:	int 0x8a
+	jb 9f
+	xor ax,ax
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/libsys/wait.s b/mach/m65oo2/libsys/wait.s
new file mode 100644
index 000000000..ae27c3bdc
--- /dev/null
+++ b/mach/m65oo2/libsys/wait.s
@@ -0,0 +1,17 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _wait
+.extern _wait, cerror
+_wait:
+	mov bx,sp
+	mov ax,2	! void info about unused memory
+	! Should be 0 according to /usr/include/sys.s, but
+	! that doesn't work
+	push ax
+	push 2(bx)
+	push ax		! dummy return address
+	int 0x87
+	jb 9f
+	add sp,6
+	ret
+9:	add sp,6
+	jmp cerror
diff --git a/mach/m65oo2/libsys/write.s b/mach/m65oo2/libsys/write.s
new file mode 100644
index 000000000..935d3eeab
--- /dev/null
+++ b/mach/m65oo2/libsys/write.s
@@ -0,0 +1,7 @@
+.sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+.define _write
+.extern _write, cerror
+_write:	int 0x84
+	jb 9f
+	ret
+9: jmp cerror
diff --git a/mach/m65oo2/mach_params b/mach/m65oo2/mach_params
new file mode 100644
index 000000000..e961fbee7
--- /dev/null
+++ b/mach/m65oo2/mach_params
@@ -0,0 +1,5 @@
+MACH=m65oo2
+SUF=o
+ASAR=aal
+RANLIB=:
+MACHFL=-O -DUFS
diff --git a/mach/m65oo2/ncg/build.lua b/mach/m65oo2/ncg/build.lua
new file mode 100644
index 000000000..cc47f9b7b
--- /dev/null
+++ b/mach/m65oo2/ncg/build.lua
@@ -0,0 +1,8 @@
+bundle {
+	name = "headers",
+	srcs = {
+		"./mach.c",
+		"./mach.h"
+	}
+}
+
diff --git a/mach/m65oo2/ncg/mach.c b/mach/m65oo2/ncg/mach.c
new file mode 100644
index 000000000..14e10be12
--- /dev/null
+++ b/mach/m65oo2/ncg/mach.c
@@ -0,0 +1,190 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ *
+ */
+
+#ifndef NORCSID
+static char rcs_m[]= "$Id$" ;
+static char rcs_mh[]= ID_MH ;
+#endif
+
+/*
+ * machine dependent back end routines for the Intel 8086
+ */
+
+void
+con_part(int sz, word w) {
+
+	while (part_size % sz)
+		part_size++;
+	if (part_size == TEM_WSIZE)
+		part_flush();
+	if (sz == 1) {
+		w &= 0xFF;
+		if (part_size)
+			w <<= 8;
+		part_word |= w;
+	} else {
+		assert(sz == 2);
+		part_word = w;
+	}
+	part_size += sz;
+}
+
+void
+con_mult(word sz) {
+
+	if (sz != 4 && sz != 8)
+		fatal("bad icon/ucon size");
+	fprintf(codefile,".data%d\t%s\n", (int)sz, str);
+}
+
+#define CODE_GENERATOR 
+#define IEEEFLOAT 
+#define FL_MSL_AT_LOW_ADDRESS	0
+#define FL_MSW_AT_LOW_ADDRESS	0
+#define FL_MSB_AT_LOW_ADDRESS	0
+#include <con_float>
+
+/*
+
+string holstr(n) word n; {
+
+	sprintf(str,hol_off,n,holno);
+	return(mystrcpy(str));
+}
+*/
+
+#ifdef REGVARS
+full lbytes;
+#endif
+
+void
+prolog(nlocals) full nlocals; {
+
+	fputs("\tpush\tbp\n\tmov\tbp,sp\n", codefile);
+#ifdef REGVARS
+	lbytes = nlocals;
+#else
+	switch (nlocals) {
+	case 4: fputs("\tpush\tax\n", codefile);
+	case 2: fputs("\tpush\tax\n", codefile);
+	case 0: break;
+	default:
+		fprintf(codefile, "\tsub\tsp,%d\n",nlocals); break;
+	}
+#endif
+}
+
+#ifdef REGVARS
+long si_off;
+long di_off;
+int firstreg;
+
+int
+regscore(long off, int size, int typ, int score, int totyp)
+{
+	if (size != 2) return -1;
+	score -= 1;
+	score += score;
+	if (typ == reg_pointer || typ == reg_loop) score += (score >> 2);
+	score -= 2;	/* cost of saving */
+	if (off >= 0) score -= 3;
+	return score;
+}
+
+void
+i_regsave()
+{
+	si_off = -1;
+	di_off = -1;
+	firstreg = 0;
+}
+
+void
+f_regsave()
+{
+	if (si_off != di_off) {
+		if (di_off == -lbytes) lbytes -= 2;
+		if (si_off == -lbytes) lbytes -= 2;
+		if (di_off == -lbytes) lbytes -= 2;
+	}
+	switch (lbytes) {
+	case 4: fputs("\tpush\tax\n", codefile);
+	case 2: fputs("\tpush\tax\n", codefile);
+	case 0: break;
+	default:
+		fprintf(codefile, "\tsub\tsp,%d\n",lbytes); break;
+	}
+	if (firstreg == 1) {
+		fputs("push di\n", codefile);
+		if (si_off != -1) fputs("push si\n", codefile);
+	}
+	else if (firstreg == -1) {
+		fputs("push si\n", codefile);
+		if (di_off != -1) fputs("push di\n", codefile);
+	}
+	if (di_off >= 0)
+		fprintf(codefile, "mov di,%ld(bp)\n", di_off);
+	if (si_off >= 0)
+		fprintf(codefile, "mov si,%ld(bp)\n", si_off);
+}
+
+void
+regsave(const char* regstr, long off, int size)
+{
+	if (strcmp(regstr, "si") == 0) {
+		if (! firstreg) firstreg = -1;
+		si_off = off;
+	}
+	else {
+		if (! firstreg) firstreg = 1;
+		di_off = off;
+	}
+}
+
+void
+regreturn()
+{
+	if (firstreg == 1) {
+		if (si_off != -1) fputs("jmp .sdret\n", codefile);
+		else fputs("jmp .dret\n", codefile);
+	}
+	else if (firstreg == -1) {
+		if (di_off != -1) fputs("jmp .dsret\n", codefile);
+		else fputs("jmp .sret\n", codefile);
+	}
+	else fputs("jmp .cret\n", codefile);
+}
+#endif /* REGVARS */
+
+void
+mes(type) word type ; {
+	int argt ;
+
+	switch ( (int)type ) {
+	case ms_ext :
+		for (;;) {
+			switch ( argt=getarg(
+			    ptyp(sp_cend)|ptyp(sp_pnam)|sym_ptyp) ) {
+			case sp_cend :
+				return ;
+			default:
+				strarg(argt) ;
+				fprintf(codefile, ".define %s\n",argstr) ;
+				break ;
+			}
+		}
+	default :
+		while ( getarg(any_ptyp) != sp_cend ) ;
+		break ;
+	}
+}
+
+char    *segname[] = {
+	".sect .text",        /* SEGTXT */
+	".sect .data",        /* SEGCON */
+	".sect .rom",        /* SEGROM */
+	".sect .bss"          /* SEGBSS */
+};
diff --git a/mach/m65oo2/ncg/mach.h b/mach/m65oo2/ncg/mach.h
new file mode 100644
index 000000000..ab5a0d156
--- /dev/null
+++ b/mach/m65oo2/ncg/mach.h
@@ -0,0 +1,34 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
+#ifndef NORCSID
+#define ID_MH		"$Id$"
+#endif
+
+#define ex_ap(y)        fprintf(codefile,".extern %s\n",y)
+#define in_ap(y)        /* nothing */
+
+#define newilb(x)       fprintf(codefile,"%s:\n",x)
+#define newdlb(x)       fprintf(codefile,"%s:\n",x)
+#define newplb(x)       fprintf(codefile,".align 2\n%s:\n", x)
+#define dlbdlb(x,y)     fprintf(codefile,"%s = %s\n",x,y)
+#define newlbss(l,x)    fprintf(codefile,".comm %s,%u\n",l,x);
+
+#define cst_fmt         "%d"
+#define off_fmt         "%d"
+#define ilb_fmt         "I%x_%d"
+#define dlb_fmt         "I_%d"
+#define hol_fmt         "hol%d"
+
+#define hol_off         "%ld+hol%d"
+
+#define con_cst(x)      fprintf(codefile,".data2\t%ld\n",x)
+#define con_ilb(x)      fprintf(codefile,".data2\t%s\n",x)
+#define con_dlb(x)      fprintf(codefile,".data2\t%s\n",x)
+
+#define modhead         ".sect .text; .sect .rom; .sect .data; .sect .bss\n"
+
+#define fmt_id(fr,to)	sprintf(to, "_%s", fr)
+
+#define BSS_INIT        0
diff --git a/mach/m65oo2/ncg/table b/mach/m65oo2/ncg/table
new file mode 100644
index 000000000..b91f4c8f5
--- /dev/null
+++ b/mach/m65oo2/ncg/table
@@ -0,0 +1,3222 @@
+/*
+ * (c) copyright 1989 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
+
+rscid = "$Id$"
+
+/*
+ * Back end tables for Intel 80386
+ *
+ * Author : Ceriel J.H. Jacobs
+ *
+ * Partly adapted from Intel 8086 table
+ *
+ * wordsize = 4 bytes, pointersize = 4 bytes.
+ *
+ * Register ebp is used as LB, esp is used for SP.
+ * Some global variables are used:
+ * - .reghp	: the heap pointer
+ * - .ignmask	: trap ignore mask
+ * - .trppc	: address of user defined trap handler
+ *
+ */
+
+#define WS 4
+#define PS 4
+
+SL = 8
+SSL = "8"
+
+EM_WSIZE = WS
+EM_PSIZE = PS
+EM_BSIZE = 8
+
+SIZEFACTOR = 5/1
+
+#define REGVARS
+
+#define EXACT exact	/* to improve code but slow down code generator,
+			   define it to nothing
+			*/
+
+/*****************************************************************/
+PROPERTIES
+/*****************************************************************/
+
+REG1			/* general 1 byte register */
+REG2			/* general 2 byte register */
+ACC1			/* 1 byte accumulator */
+ACC2			/* 2 byte accumulator */
+REG			/* allocatable register */
+GENREG			/* register with sub-registers */
+ACC			/* accumulator */
+SHIFT_CREG		/* shift count register */
+BXREG			/* ebx register */
+AREG			/* address register */
+ADDREG			/* allocatable address register */
+CXREG			/* ecx register */
+DXREG			/* edx register */
+IREG			/* index register */
+RREG			/* register variable, or register without subregs */
+
+/*****************************************************************/
+REGISTERS
+/*****************************************************************/
+
+al				    : REG1 , ACC1 .
+ah,bl, bh, ch,dl,dh		    : REG1 .
+cl				    : REG1 , SHIFT_CREG .
+ax = al + ah			    : REG2 , ACC2 .
+bx = bl + bh			    : REG2 .
+cx = cl + ch			    : REG2 .
+dx = dl + dh			    : REG2 .
+eax = al + ah			    : REG, GENREG, IREG, ACC, ADDREG, AREG.
+ebx = bl + bh			    : REG, GENREG, IREG, BXREG, ADDREG, AREG.
+ecx = cl + ch			    : REG, GENREG, IREG, CXREG, SHIFT_CREG, ADDREG , AREG .
+edx = dl + dh			    : REG, GENREG, IREG, DXREG, ADDREG, AREG .
+#ifndef REGVARS
+esi				    : REG, RREG, IREG, AREG, ADDREG .
+edi				    : REG, RREG, IREG, AREG, ADDREG .
+#else
+esi				    : AREG , IREG , RREG regvar(reg_any) .
+edi				    : AREG , IREG , RREG regvar(reg_any) .
+#endif
+ebp				    : AREG , IREG .
+esp				    : AREG .
+
+/*****************************************************************/
+TOKENS
+/*****************************************************************/
+
+ANYCON		= { INT val; }	    4 cost(4,0) val .
+CONSTR		= { ADDR off; }	    4 cost(4,0) off .
+ADDR_EXTERN	= { ADDR off; }	    4 cost(4,0) off .
+EXTERN1		= { ADDR off; }	    4 cost(4,5) "(" off ")" .
+EXTERN2		= { ADDR off; }	    4 cost(4,5) "(" off ")" .
+EXTERN		= { ADDR off; }	    4 cost(4,5) "(" off ")" .
+ADDR_LOCAL	= { INT ind; }	    4 cost(1,0) ind "(ebp)" .
+LOCAL		= { INT ind; INT size; } 4 cost(1,5) ind "(ebp)" .
+LOCAL1		= { INT ind; INT size; } 4 cost(1,5) ind "(ebp)" .
+LOCAL2		= { INT ind; INT size; } 4 cost(1,5) ind "(ebp)" .
+
+Rreg_off	= { AREG reg; ADDR off;} 4 cost(4,0) off "(" reg ")" .
+Xreg_off	= { AREG reg; ADDR off;} 4 cost(4,0) off "(" reg ")" .
+indexed_r_off	= { AREG reg; IREG reg2; INT scale; ADDR off;}
+			4 cost(5,0) off "(" reg ")" "(" reg2 "*" scale ")" .
+indexed_off	= { IREG reg; INT scale; ADDR off;}
+			4 cost(5,0) off "(" reg "*" scale ")" .
+
+indir_r		= { AREG reg;} 4 cost(0,5) "(" reg ")" .
+indir_r1	= { AREG reg;} 4 cost(0,5) "(" reg ")" .
+indir_r2	= { AREG reg;} 4 cost(0,5) "(" reg ")" .
+indir_r_off	= { AREG reg; ADDR off;} 4 cost(4,5) off "(" reg ")" .
+indir_r_off1	= { AREG reg; ADDR off;} 4 cost(4,5) off "(" reg ")" .
+indir_r_off2	= { AREG reg; ADDR off;} 4 cost(4,5) off "(" reg ")" .
+
+indir_indexed_r_off =
+		  { AREG reg; IREG reg2; INT scale; ADDR off;}
+			4 cost(5,5) off "(" reg ")" "(" reg2 "*" scale ")" .
+indir_indexed_r_off1 =
+		  { AREG reg; IREG reg2; INT scale; ADDR off;}
+			4 cost(5,5) off "(" reg ")" "(" reg2 "*" scale ")" .
+indir_indexed_r_off2 =
+		  { AREG reg; IREG reg2; INT scale; ADDR off;}
+			4 cost(5,5) off "(" reg ")" "(" reg2 "*" scale ")" .
+indir_indexed_off =
+		  { IREG reg; INT scale; ADDR off;}
+			4 cost(5,5) off "(" reg "*" scale ")" .
+indir_indexed_off1 =
+		  { IREG reg; INT scale; ADDR off;}
+			4 cost(5,5) off "(" reg "*" scale ")" .
+indir_indexed_off2 =
+		  { IREG reg; INT scale; ADDR off;}
+			4 cost(5,5) off "(" reg "*" scale ")" .
+
+label		= { ADDR off;} 4 off .
+
+/*****************************************************************/
+SETS
+/*****************************************************************/
+
+/* Mode refering to a word in memory */
+memory2		= EXTERN2 + indir_r2 + indir_r_off2 + LOCAL2 +
+		  indir_indexed_r_off2 + indir_indexed_off2 .
+memory1		= EXTERN1 + indir_r1 + indir_r_off1 + LOCAL1 +
+		  indir_indexed_r_off1 + indir_indexed_off1 .
+memory		= EXTERN + indir_r + indir_r_off + LOCAL +
+		  indir_indexed_r_off + indir_indexed_off .
+noacc		= EXTERN + LOCAL + BXREG + CXREG + RREG .
+const		= ANYCON + ADDR_EXTERN + CONSTR .
+register	= REG + ADDREG + RREG + IREG .
+addreg		= ADDREG + RREG .
+anyreg		= register + AREG .
+rm		= anyreg + memory .
+rmorconst	= const + rm .
+regorconst	= const + anyreg .
+dest		= register + memory .
+
+rm1		= REG1 + memory1 .
+rmorconst1	= const + rm1 .
+rm2		= REG2 + memory2 .
+rmorconst2	= const + rm2 .
+regorconst124	= REG1 + REG2 + GENREG + const .
+regorconst24	= REG2 + GENREG + const .
+dest1		= REG1 + memory1 .
+dest2		= REG2 + memory2 .
+
+/* Modes used to indicate tokens to be removed from the fakestack */
+reg_indir	= indir_r1 + indir_r2 + indir_r_off1 + indir_r_off2 + indir_r +
+		  indir_r_off .
+indexed		= indir_indexed_r_off1 + indir_indexed_r_off2 +
+		  indir_indexed_r_off + indir_indexed_off1 +
+		  indir_indexed_off2 + indir_indexed_off .
+indir		= reg_indir + indexed .
+externals	= EXTERN2 + EXTERN1 + EXTERN .
+locals		= LOCAL2 + LOCAL1 + LOCAL .
+mem_nonlocals	= externals + reg_indir .
+all_mems	= mem_nonlocals + locals .
+
+/* Miscellaneous */
+reg_off		= Xreg_off + Rreg_off .
+halfindir	= reg_off + ADDR_LOCAL + indexed_r_off + indexed_off .
+some_off	= halfindir + ADDR_EXTERN + AREG .
+a_word		= rmorconst + halfindir .
+
+/*****************************************************************/
+INSTRUCTIONS
+/*****************************************************************/
+
+cost(2,2)
+adc rm:rw:cc, regorconst:ro.
+adc anyreg:rw:cc, rmorconst:ro.
+#ifdef REGVARS
+add LOCAL:rw:cc, rmorconst:ro.	/* only for register variables; UNSAFE !!! */
+#endif
+add anyreg:rw:cc, rmorconst:ro.
+add rm:rw:cc, regorconst:ro.
+#ifdef REGVARS
+axx "syntax error" LOCAL:rw:cc, rmorconst:ro.	/* only for register variables; UNSAFE !!! */
+#endif
+axx "syntax error" anyreg:rw:cc, rmorconst:ro.
+axx "syntax error" rm:rw:cc, regorconst:ro.
+#ifdef REGVARS
+and LOCAL:rw:cc, rmorconst:ro.	/* only for register variables; UNSAFE !!! */
+#endif
+and rm:rw:cc, regorconst:ro.
+and anyreg:rw:cc, rmorconst:ro.
+cdq kills edx cost(1,3).
+cmp rm:ro, regorconst:ro kills :cc.
+cmp anyreg:ro, rmorconst:ro kills :cc.
+cmpb rm1:rw, const:ro kills :cc.
+cmpw "o16 cmp" rm2:rw, const:ro kills :cc cost(3,2).
+dec anyreg:rw:cc cost(1,2).
+dec rm:rw:cc.
+div rm:ro kills:cc eax edx cost(2,43).
+idiv rm:ro kills:cc eax edx cost(2,43).
+imul rm:rw, anyreg:ro kills:cc cost(3,41).
+imul anyreg:rw, rm:ro kills:cc cost(3,41).
+imul anyreg:wo, rm:ro, const:ro kills :cc cost(2,38).
+inc anyreg:rw:cc cost(1,2).
+inc rm:rw:cc.
+ja label cost(1,4).
+jae label cost(1,4).
+jb label cost(1,4).
+jbe label cost(1,4).
+jcxz label cost(1,4).
+je label cost(1,4).
+jg label cost(1,4).
+jge label cost(1,4).
+jl label cost(1,4).
+jle label cost(1,4).
+jne label cost(1,4).
+jmp label cost(1,4).
+proccall "call" label+rm cost(1,8).
+jxx "syntax error" label cost(1,4).
+setxx "syntax error" REG1:rw cost(2,4).
+seta REG1:rw cost(2,4).
+setb REG1:rw cost(2,4).
+setl REG1:rw cost(2,4).
+setle REG1:rw cost(2,4).
+setg REG1:rw cost(2,4).
+setne REG1:rw cost(2,4).
+lea anyreg:rw, halfindir:ro.
+lea LOCAL:rw, halfindir:ro.	/* only for register variables, UNSAFE!!! */
+leave cost(1,4).
+loop label kills ecx.
+#ifdef REGVARS
+mov LOCAL:wo, rmorconst:ro.	/* only for register variables, UNSAFE!!! */
+#endif
+mov a_word:wo, regorconst:ro.
+mov anyreg:wo, rmorconst:ro.
+movb rm1:wo, regorconst124:ro.
+movb REG1:wo, rm1:ro.
+movw "o16 mov" rm2:wo, regorconst124:ro cost(3,2).
+movw "o16 mov" REG2:wo, rmorconst2:ro cost(3,2).
+movsxb anyreg:wo, REG+rm1:ro.
+movsx anyreg:wo, REG+rm2:ro.
+movzxb anyreg:wo, REG+rm1:ro.
+movzx anyreg:wo, REG+rm2:ro.
+mul rmorconst:ro kills :cc eax edx cost(2,41).
+neg rmorconst:rw:cc.
+negb rm1:rw:cc.
+not rmorconst:rw.
+#ifdef REGVARS
+or LOCAL:rw:cc, rmorconst:ro.	/* only for register variables; UNSAFE !!! */
+#endif
+or rm:rw:cc, regorconst:ro.
+or anyreg:rw:cc, rmorconst:ro.
+orb REG1:rw, REG1:ro.
+pop anyreg:wo cost(1,4).
+pop rm:wo.
+push anyreg:ro cost(1,2).
+push const:ro cost(1,2).
+push rm:ro cost(2,5).
+rcl rm:rw, ANYCON+SHIFT_CREG:ro kills :cc cost(2,10).
+rcr rm:rw, ANYCON+SHIFT_CREG:ro kills :cc cost(2,10).
+ret cost(1,10).
+rol rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
+ror rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
+sal rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
+sar rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
+sbb rm:rw:cc, regorconst:ro.
+sbb anyreg:rw:cc, rmorconst:ro.
+shl rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
+shld rm:rw, anyreg:ro, ANYCON+SHIFT_CREG:ro kills :cc cost(2,3).
+shr rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
+shrd rm:rw, anyreg:ro, ANYCON+SHIFT_CREG:ro kills :cc cost(2,3).
+#ifdef REGVARS
+sub LOCAL:rw:cc, rmorconst:ro.	/* only for register variables; UNSAFE !!! */
+#endif
+sub rm:rw:cc, regorconst:ro.
+sub anyreg:rw:cc, rmorconst+halfindir:ro.
+check "test" rm:ro, regorconst:ro kills :cc.
+check "test" anyreg:ro, rmorconst:ro kills :cc.
+testb "testb" rm1:ro, regorconst124:ro kills :cc.
+testb "testb" REG1:ro, rmorconst1:ro kills :cc.
+testw "o16 test" rm2:ro, regorconst24:ro kills :cc.
+testw "o16 test" REG2:ro, rmorconst2:ro kills :cc.
+testl "test" rm:ro, regorconst:ro kills :cc.
+testl "test" REG:ro, rmorconst:ro kills :cc.
+uxx "syntax error"  rm:rw:cc.
+xchg rm:rw, anyreg:rw.
+xchg anyreg:rw, rm:rw.
+xor rm:rw:cc, regorconst:ro.
+xor anyreg:rw:cc, rmorconst:ro.
+xorb rm1:rw:cc, regorconst124:ro.
+xorb anyreg:rw:cc, rmorconst1:ro.
+xorw "o16 xor" rm2:rw:cc, regorconst124:ro.
+xorw "o16 xor" anyreg:rw:cc, rmorconst2:ro.
+
+killreg "! kill" anyreg:wo cost(0,0).
+killcc "! kill cc" kills:cc cost(0,0).
+
+
+/*****************************************************************/
+MOVES
+/*****************************************************************/
+
+#ifdef REGVARS
+from rmorconst to LOCAL		/* unsafe !!! */
+gen mov %2,%1
+#endif
+
+from rm to register
+gen mov %2,%1
+
+from anyreg to dest
+gen mov %2,%1
+
+from halfindir to register+AREG
+gen lea %2,%1
+
+from halfindir to LOCAL		/* unsafe !!! */
+gen lea %2,%1
+
+from rm1 to REG1
+gen movb %2,%1
+
+from rm2 to REG2
+gen movw %2,%1
+
+from GENREG to rm1
+gen movb %2,%1.1
+
+from GENREG to rm2
+gen movw %2,%1
+
+from REG2 to rm1
+gen movb %2,%1.1
+
+from ANYCON %val==0 to register
+gen xor %2,%2
+
+from ANYCON %val==0 to REG1
+gen xorb %2,%2
+
+from ANYCON %val==0 to REG2
+gen xorw %2,%2
+
+from const to dest
+gen mov %2,%1
+
+from const+REG1 to rm1
+gen movb %2,%1
+
+from const+REG2 to rm2
+gen movw %2,%1
+
+/*****************************************************************/
+TESTS
+/*****************************************************************/
+
+to test anyreg
+gen testl %1,%1
+
+to test memory
+gen cmp %1, {ANYCON,0}
+
+to test REG1
+gen testb %1,%1
+
+to test memory1
+gen cmpb %1, {ANYCON,0}
+
+to test REG2
+gen testw %1,%1
+
+to test memory2
+gen cmpw %1, {ANYCON,0}
+
+
+/*****************************************************************/
+STACKINGRULES
+/*****************************************************************/
+
+from rm to STACK
+  gen push %1
+
+from const to STACK
+  gen push %1
+
+from rm1 to STACK
+  uses REG
+  gen movzxb %a,%1
+      push %a
+
+from rm1 to STACK
+  gen push eax
+      movzxb eax,%1
+      xchg {indir_r,esp},eax
+
+from rm2 to STACK
+  uses REG
+  gen movzx %a,%1
+      push %a
+
+from rm2 to STACK
+  gen push eax
+      movzx eax,%1
+      xchg {indir_r,esp},eax
+
+from Xreg_off to STACK
+  gen add %1.reg,{CONSTR,%1.off}
+      push %1.reg
+
+from ADDR_LOCAL %ind==0 to STACK
+  gen push ebp
+
+from halfindir to STACK
+  uses REG
+  gen move %1,%a
+      push %a
+
+from halfindir to STACK
+  gen push eax
+      lea eax,%1
+      xchg {indir_r,esp},eax
+
+
+/*****************************************************************/
+COERCIONS
+/*****************************************************************/
+
+/***************************
+ * From source to register *
+ ***************************/
+
+from rmorconst
+  uses reusing %1,REG=%1		yields %a
+from rmorconst
+  uses reusing %1,IREG=%1		yields %a
+
+from Xreg_off
+  gen add %1.reg,{CONSTR,%1.off}	yields %1.reg
+
+from halfindir
+  uses reusing %1,ADDREG
+  gen move %1,%a			yields %a
+
+from halfindir
+  uses reusing %1,REG
+  gen move %1,%a			yields %a
+
+from halfindir
+  uses reusing %1,IREG
+  gen move %1,%a			yields %a
+
+/************************
+ * From source to token *
+ ************************/
+
+from ANYCON				yields {ADDR_EXTERN,%1.val}
+
+/****************
+ * From source1 *
+ ****************/
+
+from rm1
+  uses reusing %1,REG1=%1		yields %a
+
+from rm1
+  uses GENREG
+  gen
+      movzxb %a,%1			yields %a
+
+/****************
+ * From source2 *
+ ****************/
+
+from rm2
+  uses reusing %1,REG2=%1		yields %a
+
+from rm2
+  uses GENREG
+  gen
+      movzx %a,%1			yields %a
+
+/************************
+ * From STACK coercions *
+ ************************/
+
+from STACK
+  uses REG
+  gen pop %a				yields %a
+
+
+/*****************************************************************/
+PATTERNS
+/*****************************************************************/
+
+/******************************************************************
+ *  Group 1 : Load Instructions					  *
+ ******************************************************************/
+
+pat loc					yields {ANYCON,$1}
+
+#if 0
+/* wrong because .Xtrp assumes trap < 16 */
+pat ldc					leaving loc 18 trp
+#endif
+
+pat lol					yields {LOCAL,$1,4}
+
+pat stl lol $1==$2
+#ifdef REGVARS
+	&& inreg($1) <= 0
+#endif
+						leaving dup 4 stl $1
+
+pat sdl ldl $1==$2				leaving dup 8 sdl $1
+
+#ifdef REGVARS
+pat lol dup stl $2==4 && inreg($1) <= 0 && inreg($3) > 0
+kills regvar($3)
+gen	move {LOCAL,$1,4}, {LOCAL,$3,4}
+					yields {LOCAL,$3,4}
+#endif
+
+pat loe					yields {EXTERN,$1}
+
+pat ste loe $1==$2				leaving dup 4 ste $1
+
+pat sde lde $1==$2				leaving dup 8 sde $1
+
+#ifdef REGVARS
+pat loe dup stl $2==4 && inreg($3) > 0
+kills regvar($3)
+gen	move {EXTERN,$1}, {LOCAL,$3,4}
+					yields {LOCAL,$3,4}
+#endif
+
+#ifdef REGVARS
+pat lil inreg($1) > 0			yields {indir_r, regvar($1)}
+#endif
+pat lil
+  uses ADDREG={indir_r_off,ebp,$1}	yields {indir_r,%a}
+
+pat lil dup stl $2==4				leaving lil $1 stl $3 lol $3
+
+pat sil lil $1==$2				leaving dup 4 sil $1
+
+pat lof
+  with exact indexed_r_off	yields {indir_indexed_r_off,%1.reg,%1.reg2,
+						%1.scale,%1.off+$1}
+  with exact indexed_off	yields {indir_indexed_off,%1.reg,
+						%1.scale,%1.off+$1}
+  with exact reg_off		yields {indir_r_off,%1.reg,%1.off+$1}
+  with exact ADDR_EXTERN	yields {EXTERN,%1.off+$1}
+  with exact ADDR_LOCAL		yields {LOCAL,%1.ind + $1,4}
+  with addreg			yields {indir_r_off,%1,$1}
+
+pat lal					yields {ADDR_LOCAL,$1}
+
+pat lae					yields {ADDR_EXTERN,$1}
+
+pat lpb						leaving adp SL
+
+pat lxl $1==0				yields {ADDR_LOCAL,0}
+
+pat lxl $1==1				yields {LOCAL,SL,4}
+
+pat lxl $1==2
+  uses ADDREG={indir_r_off,ebp,SSL}	yields {indir_r_off,%a,SSL}
+
+pat lxl $1>2
+  uses ADDREG={indir_r_off,ebp,SSL},
+       CXREG={ANYCON,$1-1}
+  gen 1:
+      mov %a,{indir_r_off,%a,SSL}
+      loop {label,1b}			yields %a
+
+pat lxa $1==0				yields {ADDR_LOCAL,SL}
+
+pat lxa $1==1
+  uses ADDREG={indir_r_off,ebp,SSL}	yields {Xreg_off,%a,SSL}
+
+pat lxa $1==2
+  uses ADDREG={indir_r_off,ebp,SSL}
+  gen move {indir_r_off,%a,SSL},%a	yields {Xreg_off,%a,SSL}
+
+pat lxa $1>2
+  uses ADDREG={indir_r_off,ebp,SSL},
+       CXREG={ANYCON,$1-1}
+  gen 1:
+      mov %a,{indir_r_off,%a,SSL}
+      loop {label,1b}			yields {Xreg_off,%a,SSL}
+
+pat dch						leaving loi 4
+
+pat loi $1==2
+  with addreg			yields {indir_r2,%1}
+  with exact indexed_r_off	yields {indir_indexed_r_off2, %1.reg, %1.reg2,
+						%1.scale, %1.off}
+  with exact indexed_off	yields {indir_indexed_off2, %1.reg,
+						%1.scale, %1.off}
+  with exact reg_off		yields {indir_r_off2,%1.reg,%1.off}
+  with exact ADDR_EXTERN	yields {EXTERN2,%1.off}
+  with exact ADDR_LOCAL		yields {LOCAL2,%1.ind,2}
+
+pat loi $1==1
+  with addreg			yields {indir_r1,%1}
+  with exact indexed_r_off	yields {indir_indexed_r_off1, %1.reg, %1.reg2,
+						%1.scale, %1.off}
+  with exact indexed_off	yields {indir_indexed_off1, %1.reg,
+						%1.scale, %1.off}
+  with exact reg_off		yields {indir_r_off1,%1.reg,%1.off}
+  with exact ADDR_EXTERN	yields {EXTERN1,%1.off}
+  with exact ADDR_LOCAL		yields {LOCAL1,%1.ind,1}
+
+pat loi $1==4
+  with addreg			yields {indir_r,%1}
+  with exact indexed_r_off	yields {indir_indexed_r_off, %1.reg, %1.reg2,
+						%1.scale, %1.off}
+  with exact indexed_off	yields {indir_indexed_off, %1.reg,
+						%1.scale, %1.off}
+  with exact reg_off		yields {indir_r_off,%1.reg,%1.off}
+  with exact ADDR_EXTERN	yields {EXTERN,%1.off}
+  with exact ADDR_LOCAL		yields {LOCAL,%1.ind,4}
+
+pat loi $1==8
+  with addreg			yields {indir_r_off,%1,4}
+				       {indir_r,%1}
+  with exact indexed_r_off	yields {indir_indexed_r_off, %1.reg, %1.reg2,
+						%1.scale, %1.off+4}
+					{indir_indexed_r_off, %1.reg, %1.reg2,
+						%1.scale, %1.off}
+  with exact indexed_off	yields {indir_indexed_off, %1.reg,
+						%1.scale, %1.off+4}
+					{indir_indexed_off, %1.reg,
+						%1.scale, %1.off}
+  with exact reg_off		yields {indir_r_off,%1.reg,%1.off+4}
+				       {indir_r_off,%1.reg,%1.off}
+  with exact ADDR_LOCAL		yields {LOCAL,%1.ind+4,4}
+				       {LOCAL,%1.ind,4}
+  with exact ADDR_EXTERN	yields {EXTERN,%1.off + 4}
+				       {EXTERN,%1.off}
+pat loi
+  with BXREG
+  kills ALL
+  gen mov ecx,{ANYCON,$1}
+      proccall {label,".loi"}
+
+pat los $1==4
+  with CXREG BXREG
+  kills ALL
+  gen proccall {label,".los"}
+
+pat ldl					yields {LOCAL,$1+4,4}
+					       {LOCAL,$1,4}
+
+pat lde					yields {EXTERN,$1+4}
+					       {EXTERN,$1}
+
+pat ldf
+  with exact reg_off			yields {indir_r_off,%1.reg,
+						%1.off + 4 + $1}
+					       {indir_r_off,%1.reg,
+						%1.off + $1}
+  with exact indexed_r_off	yields {indir_indexed_r_off, %1.reg, %1.reg2,
+						%1.scale, %1.off+$1+4}
+					{indir_indexed_r_off, %1.reg, %1.reg2,
+						%1.scale, %1.off+$1}
+  with exact indexed_off	yields {indir_indexed_off, %1.reg,
+						%1.scale, %1.off+$1+4}
+					{indir_indexed_off, %1.reg,
+						%1.scale, %1.off+$1}
+  with addreg				yields {indir_r_off,%1,$1+4}
+					       {indir_r_off,%1,$1}
+  with exact ADDR_EXTERN	yields {EXTERN,%1.off+4+$1}
+				       {EXTERN,%1.off+$1}
+  with exact ADDR_LOCAL		yields {LOCAL,%1.ind + $1 + 4,4}
+				       {LOCAL,%1.ind + $1,4}
+
+pat lpi				yields {ADDR_EXTERN,$1}
+
+/* this code sequence is generated by the C-compiler to tackle
+   char parameters, on the 80386 it reduces to nil */
+
+pat lol lal sti $1==$2 && $3<=4
+
+/*******************************************************************
+ *  Group 2 : Store Instructions				   *
+ *******************************************************************/
+
+#ifdef REGVARS
+pat stl inreg($1)==reg_any
+  with rmorconst
+  kills regvar($1)
+  gen move %1, {LOCAL,$1,4}
+  with exact halfindir
+  kills regvar($1)
+  gen move %1, {LOCAL,$1,4}
+  with exact STACK
+  kills regvar($1)
+  gen pop {LOCAL, $1, 4}
+#endif
+pat stl
+  with regorconst
+  kills indir,locals %ind+%size > $1 && %ind < $1+4
+  gen move %1,{LOCAL,$1,4}
+  with exact STACK
+  kills ALL
+  gen pop {indir_r_off,ebp,$1}
+
+pat ste
+  with regorconst
+  kills mem_nonlocals
+  gen move %1,{EXTERN,$1}
+  with exact STACK
+  kills ALL
+  gen pop {EXTERN,$1}
+
+#ifdef REGVARS
+pat sil inreg($1)==reg_any
+  with regorconst
+  kills all_mems
+  gen move %1,{indir_r,regvar($1)}
+  with exact STACK
+  kills ALL
+  gen pop {indir_r,regvar($1)}
+#endif
+pat sil
+  with regorconst
+  kills all_mems
+  uses ADDREG={indir_r_off,ebp,$1}
+  gen move %1,{indir_r,%a}
+      killreg %a
+  with exact STACK
+  kills ALL
+  uses ADDREG={indir_r_off,ebp,$1}
+  gen pop {indir_r,%a}
+      killreg %a
+
+pat stf
+  with addreg regorconst
+  kills all_mems
+  gen move %2,{indir_r_off,%1,$1}
+  with exact addreg STACK
+  kills ALL
+  gen pop {indir_r_off, %1,$1}
+  with reg_off regorconst
+  kills all_mems
+  gen move %2,{indir_r_off,%1.reg,%1.off+$1}
+  with exact reg_off STACK
+  gen pop {indir_r_off,%1.reg,$1+%1.off}
+  with indexed_r_off regorconst
+  kills all_mems
+  gen move %2,{indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
+  with exact indexed_r_off STACK
+  kills all_mems
+  gen pop {indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
+  with indexed_off regorconst
+  kills all_mems
+  gen move %2,{indir_indexed_off,%1.reg,%1.scale,%1.off+$1}
+  with exact indexed_off STACK
+  kills all_mems
+  gen pop {indir_indexed_off,%1.reg,%1.scale,%1.off+$1}
+  with ADDR_LOCAL regorconst
+  kills indir,locals %ind+%size > %1.ind+$1 && %ind < %1.ind+$1+4
+  gen move %2,{LOCAL,%1.ind+$1,4}
+  with exact ADDR_LOCAL STACK
+  kills indir,locals %ind+%size > %1.ind+$1 && %ind < %1.ind+$1+4
+  gen pop {LOCAL,%1.ind+$1,4}
+  with ADDR_EXTERN regorconst
+  kills mem_nonlocals
+  gen move %2,{EXTERN,%1.off+$1}
+  with exact ADDR_EXTERN STACK
+  kills mem_nonlocals
+  gen pop {EXTERN,%1.off+$1}
+
+pat sti $1==4
+  with addreg regorconst
+  kills all_mems
+  gen move %2,{indir_r,%1}
+  with exact addreg STACK
+  kills all_mems
+  gen pop {indir_r,%1}
+  with reg_off regorconst
+  kills all_mems
+  gen move %2,{indir_r_off,%1.reg,%1.off}
+  with exact reg_off STACK
+  kills all_mems
+  gen pop {indir_r_off,%1.reg,%1.off}
+  with indexed_r_off regorconst
+  kills all_mems
+  gen move %2,{indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off}
+  with exact indexed_r_off STACK
+  kills all_mems
+  gen pop {indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off}
+  with indexed_off regorconst
+  kills all_mems
+  gen move %2,{indir_indexed_off,%1.reg,%1.scale,%1.off}
+  with exact indexed_off STACK
+  kills all_mems
+  gen pop {indir_indexed_off,%1.reg,%1.scale,%1.off}
+  with ADDR_LOCAL regorconst
+  kills indir,locals %ind+%size > %1.ind && %ind < %1.ind+4
+  gen move %2,{LOCAL,%1.ind,4}
+  with exact ADDR_LOCAL STACK
+  kills indir,locals %ind+%size > %1.ind && %ind < %1.ind+4
+  gen pop {LOCAL,%1.ind,4}
+  with ADDR_EXTERN regorconst
+  kills mem_nonlocals
+  gen move %2,{EXTERN,%1.off}
+  with exact ADDR_EXTERN STACK
+  kills mem_nonlocals
+  gen pop {EXTERN,%1.off}
+
+pat sti $1==1
+  with addreg regorconst124
+  kills all_mems
+  gen move %2,{indir_r1,%1}
+  with reg_off regorconst124
+  kills all_mems
+  gen move %2,{indir_r_off1,%1.reg,%1.off}
+  with indexed_r_off regorconst124
+  kills all_mems
+  gen move %2,{indir_indexed_r_off1,%1.reg,%1.reg2,%1.scale,%1.off}
+  with indexed_off regorconst124
+  kills all_mems
+  gen move %2,{indir_indexed_off1,%1.reg,%1.scale,%1.off}
+  with ADDR_EXTERN regorconst124
+  kills mem_nonlocals
+  gen move %2,{EXTERN1,%1.off}
+  with ADDR_LOCAL regorconst124
+  kills indir,locals %ind<%1.ind+1 && %ind+%size>%1.ind
+  gen move %2,{indir_r_off1,ebp,%1.ind}
+
+pat sti $1==2
+  with addreg regorconst24
+  kills all_mems
+  gen move %2,{indir_r2,%1}
+  with reg_off regorconst24
+  kills all_mems
+  gen move %2,{indir_r_off2,%1.reg,%1.off}
+  with indexed_r_off regorconst24
+  kills all_mems
+  gen move %2,{indir_indexed_r_off2,%1.reg,%1.reg2,%1.scale,%1.off}
+  with indexed_off regorconst24
+  kills all_mems
+  gen move %2,{indir_indexed_off2,%1.reg,%1.scale,%1.off}
+  with ADDR_EXTERN regorconst24
+  kills mem_nonlocals
+  gen move %2,{EXTERN2,%1.off}
+  with ADDR_LOCAL regorconst24
+  kills indir,locals %ind<%1.ind+2 && %ind+%size>%1.ind
+  gen move %2,{indir_r_off2,ebp,%1.ind}
+
+pat sti $1==8			leaving sdf 0
+
+pat sti
+  with BXREG
+  kills ALL
+  gen mov ecx,{ANYCON,$1}
+      proccall {label, ".sti"}
+
+/* this sort of construction gives problems in the codegenerator
+   because of the potential very large lookahead
+
+  with addreg
+  kills ALL
+  gen pop (%1)
+      add %1,{ANYCON,2}			yields %1	leaving sti $1-4
+
+*/
+
+pat sts $1==4
+  with CXREG BXREG
+  kills ALL
+  gen proccall {label,".sts"}
+
+pat sdl
+  with regorconst regorconst	yields %2 %1
+					leaving stl $1 stl $1+4
+  with exact STACK			leaving stl $1 stl $1+4
+
+pat sde
+  with regorconst regorconst	yields %2 %1
+					leaving ste $1 ste $1+4
+  with exact STACK			leaving ste $1 ste $1+4
+
+pat sdf
+  with addreg regorconst regorconst
+  kills all_mems
+  gen move %2,{indir_r_off,%1,$1}
+      move %3,{indir_r_off,%1,$1+4}
+  with exact addreg STACK
+  kills all_mems
+  gen pop {indir_r_off,%1,$1}
+      pop {indir_r_off,%1,$1+4}
+  with reg_off regorconst regorconst
+  kills all_mems
+  gen move %2,{indir_r_off,%1.reg,%1.off+$1}
+      move %3,{indir_r_off,%1.reg,%1.off+$1+4}
+  with exact reg_off STACK
+  kills all_mems
+  gen pop {indir_r_off,%1.reg,$1+%1.off}
+      pop {indir_r_off,%1.reg,$1+%1.off+4}
+  with indexed_r_off regorconst regorconst
+  kills all_mems
+  gen move %2,{indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
+      move %3,{indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+4+$1}
+  with exact indexed_r_off STACK
+  kills all_mems
+  gen pop {indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
+      pop {indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+4+$1}
+  with indexed_off regorconst regorconst
+  kills all_mems
+  gen move %2,{indir_indexed_off,%1.reg,%1.scale,%1.off+$1}
+      move %3,{indir_indexed_off,%1.reg,%1.scale,%1.off+4+$1}
+  with exact indexed_off STACK
+  kills all_mems
+  gen pop {indir_indexed_off,%1.reg,%1.scale,%1.off+$1}
+      pop {indir_indexed_off,%1.reg,%1.scale,%1.off+4+$1}
+  with ADDR_LOCAL regorconst regorconst
+  kills indir,locals %ind+%size > $1 && %ind < $1+8
+  gen	move %2,{LOCAL,%1.ind+$1,4}
+	move %3,{LOCAL,%1.ind+$1+4,4}
+  with exact ADDR_LOCAL STACK
+  kills indir,locals %ind+%size > $1 && %ind < $1+8
+  gen	pop {LOCAL,%1.ind+$1,4}
+	pop {LOCAL,%1.ind+$1+4,4}
+  with ADDR_EXTERN regorconst regorconst
+  kills mem_nonlocals
+  gen	move %2,{EXTERN,%1.off+$1}
+	move %3,{EXTERN,%1.off+$1+4}
+  with exact ADDR_EXTERN STACK
+  kills mem_nonlocals
+  gen	pop {EXTERN,%1.off+$1}
+	pop {EXTERN,%1.off+$1+4}
+
+
+/****************************************************************
+ *  Group 3 : Integer Arithmetic.				*
+ *								*
+ *  Implemented (sometimes with the use of subroutines) :	*
+ *  4 byte arithmetic.						*
+ ****************************************************************/
+
+pat adi $1==4
+#ifdef REGVARS
+with exact ANYCON RREG
+				yields {Rreg_off,%2,%1.val}
+with exact RREG ANYCON
+				yields {Rreg_off,%1,%2.val}
+#endif
+with REG rmorconst
+  gen add %1,%2			yields %1
+with rmorconst REG
+  gen add %2,%1			yields %2
+with EXACT rmorconst const
+  uses reusing %1,REG=%1
+  gen add %a,%2			yields %a
+
+pat adi $1==8
+with EXACT REG REG rmorconst rmorconst
+  gen add %1,%3
+      adc %2,%4			yields %2 %1
+with rmorconst rmorconst REG REG
+  gen add %3,%1
+      adc %4,%2			yields %4 %3
+
+/*
+pat adi !defined($1)
+with CXREG ACC
+  kills ALL
+  gen proccall {label,".adi"}	yields eax
+*/
+
+pat sbi $1==4
+with rmorconst REG
+  gen sub %2,%1			yields %2
+with EXACT REG rmorconst
+  gen sub %1,%2
+      neg %1			yields %1
+
+pat sbi $1==8
+with rmorconst rmorconst REG REG
+  gen sub %3,%1
+      sbb %4,%2			yields %4 %3
+
+/*
+pat sbi !defined($1)
+with CXREG ACC
+  kills ALL
+  gen proccall {label,".sbi"}	yields eax
+*/
+
+pat mli $1==4
+with rm REG
+  gen imul %2,%1		yields %2
+with REG rm
+  gen imul %1,%2		yields %1
+with const rm
+  uses reusing %2,REG
+  gen imul %a,%2,%1		yields %a
+with rm const
+  uses reusing %1,REG
+  gen imul %a,%1,%2		yields %a
+
+pat mli $1==8
+with ACC DXREG
+  kills ALL
+  gen proccall {label,".mli8"}	yields edx eax
+
+/*
+pat mli !defined($1)
+with ACC
+  kills ALL
+  gen proccall {label,".mli"}
+*/
+
+pat dvi $1==4
+with noacc ACC
+  uses DXREG
+  gen cdq.
+      idiv %1			yields eax
+
+pat dvi $1==8
+  kills ALL
+  gen proccall {label,".dvi8"}	yields ebx eax
+
+/*
+pat dvi !defined($1)
+with ACC
+  kills ALL
+  gen proccall {label,".dvi"}
+*/
+
+pat rmi $1==4
+with noacc ACC
+  uses DXREG
+  gen cdq.
+      idiv %1			yields edx
+
+pat rmi $1==8
+  kills ALL
+  gen proccall {label,".rmi8"}	yields ecx edx
+
+/*
+pat rmi !defined($1)
+with ACC
+  kills ALL
+  gen proccall {label,".rmi"}
+*/
+
+pat ngi $1==4
+with REG
+  gen neg %1			yields %1
+
+pat ngi $1==8
+with REG REG
+  gen neg %2
+      neg %1
+      sbb %2,{ANYCON,0}		yields %2 %1
+
+/*
+pat ngi !defined($1)
+with ACC
+  kills ALL
+  gen proccall {label,".ngi"}
+*/
+
+pat sli $1==4
+with ANYCON REG
+  gen sal %2,%1			yields %2
+with SHIFT_CREG REG
+  gen sal %2,cl			yields %2
+
+pat sli $1==8
+with SHIFT_CREG REG REG
+  gen testb cl,{ANYCON,32}
+      jne {label,1f}
+      shld %3,%2,cl
+      sal %2,cl
+      jmp {label,2f}
+      1:
+      mov %3,%2
+      sal %3,cl
+      xor %2,%2
+      2:			yields %3 %2
+
+pat loc sli ($1&32)==0 && $2==8
+with REG REG
+  gen shld %2,%1,{ANYCON,$1&31}
+      sal %1,{ANYCON,$1&31}	yields %2 %1
+pat loc sli ($1&63)==32 && $2==8
+with a_word a_word		yields %1 {ANYCON,0}
+pat loc sli ($1&32)!=0 && $2==8
+with REG a_word
+  gen sal %1,{ANYCON,$1&31}	yields %1 {ANYCON,0}
+
+/*
+pat sli !defined($1)
+with ACC
+  kills ALL
+  gen proccall {label,".sli"}
+*/
+
+pat sri $1==4
+with SHIFT_CREG REG
+  gen sar %2,cl			yields %2
+with ANYCON REG
+  gen sar %2,%1			yields %2
+
+pat sri $1==8
+with SHIFT_CREG REG REG
+  gen testb cl,{ANYCON,32}
+      jne {label,1f}
+      shrd %2,%3,cl
+      sar %3,cl
+      jmp {label,2f}
+      1:
+      mov %2,%3
+      sar %2,cl
+      sar %3,{ANYCON,31}
+      2:			yields %3 %2
+
+pat loc sri ($1&32)==0 && $2==8
+with REG REG
+  gen shrd %1,%2,{ANYCON,$1&31}
+      sar %2,{ANYCON,$1&31}	yields %2 %1
+pat loc sri ($1&63)==32
+with a_word ACC
+  gen cdq.			yields edx eax
+pat loc sri ($1&32)!=0 && $2==8
+with a_word ACC
+  gen sar eax,{ANYCON,$1&31}
+      cdq.			yields edx eax
+
+/*
+pat sri !defined($1)
+with ACC
+  kills ALL
+  gen proccall {label,".sri"}
+*/
+
+/*******************************************************************
+ *  Group 4: Unsigned Arithmetic				   *
+ *******************************************************************/
+
+pat adu					leaving adi $1
+pat loc lol adu stl $1==1 && $3==4 && $2==$4	leaving inl $2
+pat loc loe adu ste $1==1 && $3==4 && $2==$4	leaving ine $2
+pat loc lol adu $1==1 && $3==4		leaving lol $2 inc
+pat loc loe adu $1==1 && $3==4		leaving loe $2 inc
+pat loc lil adu $1==1 && $3==4		leaving lil $2 inc
+pat loc lol adu stl $1==0-1 && $3==4 && $2==$4	leaving del $2
+pat loc loe adu ste $1==0-1 && $3==4 && $2==$4	leaving dee $2
+pat loc lol adu $1==0-1 && $3==4		leaving lol $2 dec
+pat loc loe adu $1==0-1 && $3==4		leaving loe $2 dec
+pat loc lil adu $1==0-1 && $3==4		leaving lil $2 dec
+pat sbu					leaving sbi $1
+pat lol loc sbu stl $1==$4 && $2==1 && $3==4	leaving del $1
+pat loe loc sbu ste $1==$4 && $2==1 && $3==4	leaving dee $1
+pat lol loc sbu $2==1 && $3==4		leaving lol $1 dec
+pat loe loc sbu $2==1 && $3==4		leaving loe $1 dec
+pat lil loc sbu $2==1 && $3==4		leaving lil $1 dec
+pat lol loc sbu stl $1==$4 && $2==0-1 && $3==4	leaving inl $1
+pat loe loc sbu ste $1==$4 && $2==0-1 && $3==4	leaving ine $1
+pat lol loc sbu $2==0-1 && $3==4		leaving lol $1 inc
+pat loe loc sbu $2==0-1 && $3==4		leaving loe $1 inc
+pat lil loc sbu $2==0-1 && $3==4		leaving lil $1 inc
+pat mlu					leaving mli $1
+
+pat loe loc loe adu ste $1==$3 && $1==$5 && $4==4
+uses REG = {EXTERN, $1}
+                                yields %a leaving loc $2 loe $3 adu 4 ste $3
+
+pat lol loc lol adu stl $1==$3 && $1==$5 && $4==4
+uses REG = {LOCAL, $1, 4}
+                                yields %a leaving loc $2 lol $3 adu 4 stl $3
+
+pat loe loc loe adi ste $1==$3 && $1==$5 && $4==4
+uses REG = {EXTERN, $1}
+                                yields %a leaving loc $2 loe $3 adi 4 ste $3
+
+pat lol loc lol adi stl $1==$3 && $1==$5 && $4==4
+uses REG = {LOCAL, $1, 4}
+                                yields %a leaving loc $2 lol $3 adi 4 stl $3
+
+pat dvu $1==4
+with noacc ACC
+uses DXREG={ANYCON,0}
+gen div %1			yields eax
+
+pat dvu $1==8
+  kills ALL
+  gen proccall {label,".dvu8"}	yields ebx eax
+
+/*
+pat dvu !defined($1)
+with ACC STACK
+kills ALL
+gen proccall {label,".dvu"}
+*/
+
+pat rmu $1==4
+with noacc ACC
+uses DXREG={ANYCON,0}
+gen div %1			yields edx
+
+pat rmu $1==8
+  kills ALL
+  gen proccall {label,".rmu8"}	yields ecx edx
+
+/*
+pat rmu !defined($1)
+with ACC STACK
+kills ALL
+gen proccall {label,".rmu"}
+*/
+
+pat slu					leaving sli $1
+pat loc slu					leaving loc $1 sli $2
+
+pat sru $1==4
+with SHIFT_CREG REG
+gen shr %2,cl			yields %2
+with ANYCON REG
+gen shr %2,%1			yields %2
+
+pat sru $1==8
+with SHIFT_CREG REG REG
+  gen testb cl,{ANYCON,32}
+      jne {label,1f}
+      shrd %2,%3,cl
+      shr %3,cl
+      jmp {label,2f}
+      1:
+      mov %2,%3
+      shr %2,cl
+      xor %3,%3
+      2:			yields %3 %2
+
+pat loc sru ($1&32)==0 && $2==8
+with REG REG
+  gen shrd %2,%1,{ANYCON,$1&31}
+      shr %1,{ANYCON,$1&31}	yields %2 %1
+pat loc sru ($1&63)==32 && $2==8
+with a_word a_word		yields {ANYCON,0} %2
+pat loc sru ($1&32)!=0 && $2==8
+with a_word REG
+  gen shr %2,{ANYCON,$1&31}	yields {ANYCON,0} %2
+
+/*
+pat sru !defined($1)
+with ACC STACK
+kills ALL
+gen proccall {label,".sru"}
+*/
+
+/*******************************************************************
+ *  Group 5: Floating Point Instructions			   *
+ *******************************************************************/
+
+pat adf $1==4		leaving cal ".adf4" asp 4
+pat adf $1==8		leaving cal ".adf8" asp 8
+pat sbf $1==4		leaving cal ".sbf4" asp 4
+pat sbf $1==8		leaving cal ".sbf8" asp 8
+pat mlf $1==4		leaving cal ".mlf4" asp 4
+pat mlf $1==8		leaving cal ".mlf8" asp 8
+pat dvf $1==4		leaving cal ".dvf4" asp 4
+pat dvf $1==8		leaving cal ".dvf8" asp 8
+pat ngf $1==4		leaving cal ".ngf4"
+pat ngf $1==8		leaving cal ".ngf8"
+pat fif $1==4		leaving lor 1 cal ".fif4" asp 4
+pat fif $1==8		leaving lor 1 cal ".fif8" asp 4
+pat fef $1==4		leaving lor 1 adp 0-4 cal ".fef4"
+pat fef $1==8		leaving lor 1 adp 0-4 cal ".fef8"
+
+/******************************************************************
+ *  Group 6: Pointer Arithmetic					  *
+ ******************************************************************/
+
+pat adp $1==1
+with exact Xreg_off	yields {Xreg_off,%1.reg,%1.off+$1}
+with exact Rreg_off	yields {Rreg_off,%1.reg,%1.off+$1}
+with exact indexed_r_off
+			yields {indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
+with exact indexed_off	yields {indexed_off,%1.reg,%1.scale,%1.off+$1}
+with exact ADDR_EXTERN	yields {ADDR_EXTERN,%1.off+$1}
+with exact ADDR_LOCAL	yields {ADDR_LOCAL,%1.ind+$1}
+with REG
+  gen inc %1		yields %1
+with ADDREG
+  gen killreg %1
+			yields {Xreg_off, %1, $1}
+with exact RREG		yields {Rreg_off, %1, $1}
+
+pat adp $1==0-1
+with exact Xreg_off	yields {Xreg_off,%1.reg,%1.off+$1}
+with exact Rreg_off	yields {Rreg_off,%1.reg,%1.off+$1}
+with exact indexed_r_off
+			yields {indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
+with exact indexed_off	yields {indexed_off,%1.reg,%1.scale,%1.off+$1}
+with exact ADDR_EXTERN	yields {ADDR_EXTERN,%1.off+$1}
+with exact ADDR_LOCAL	yields {ADDR_LOCAL,%1.ind+$1}
+with REG
+  gen dec %1		yields %1
+with ADDREG
+  gen killreg %1
+			yields {Xreg_off, %1, $1}
+with exact RREG		yields {Rreg_off, %1, $1}
+
+pat adp
+with exact Xreg_off	yields {Xreg_off,%1.reg,%1.off+$1}
+with exact Rreg_off	yields {Rreg_off,%1.reg,%1.off+$1}
+with exact indexed_r_off
+			yields {indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
+with exact indexed_off	yields {indexed_off,%1.reg,%1.scale,%1.off+$1}
+with exact ADDR_EXTERN	yields {ADDR_EXTERN,%1.off+$1}
+with exact ADDR_LOCAL	yields {ADDR_LOCAL,%1.ind+$1}
+with ADDREG
+  gen killreg %1
+			yields {Xreg_off,%1,$1}
+with exact RREG		yields {Rreg_off, %1, $1}
+with REG
+  gen add %1,{ANYCON,$1}	yields %1
+
+pat ads stl $1==4			leaving adi 4 stl $2
+pat ads ste $1==4			leaving adi 4 ste $2
+pat ads sil $1==4			leaving adi 4 sil $2
+pat ads lol stf $1==4			leaving adi 4 lol $2 stf $3
+pat ads loe stf $1==4			leaving adi 4 loe $2 stf $3
+
+pat ads $1==4
+with exact ANYCON Rreg_off
+			yields {Rreg_off,%2.reg,%2.off+%1.val}
+with exact ANYCON Xreg_off
+			yields {Xreg_off,%2.reg,%2.off+%1.val}
+with exact ANYCON indexed_r_off
+			yields {indexed_r_off,%2.reg,%2.reg2,
+					%2.scale,%2.off+%1.val}
+with exact ANYCON indexed_off
+			yields {indexed_off,%2.reg,%2.scale,%2.off+%1.val}
+with exact ADDR_EXTERN Rreg_off
+			yields {Rreg_off,%2.reg,%2.off+%1.off}
+with exact ADDR_EXTERN Xreg_off
+			yields {Xreg_off,%2.reg,%2.off+%1.off}
+with exact ADDR_EXTERN indexed_r_off
+			yields {indexed_r_off,%2.reg,%2.reg2,
+					%2.scale,%2.off+%1.off}
+with exact ADDR_EXTERN indexed_off
+			yields {indexed_off,%2.reg,%2.scale,%2.off+%1.off}
+with exact IREG reg_off
+			yields {indexed_r_off,%2.reg,%1,1,%2.off}
+with exact reg_off IREG
+			yields {indexed_r_off,%1.reg,%2,1,%1.off}
+with exact IREG ADDR_LOCAL
+			yields {indexed_r_off,ebp,%1,1,%2.ind}
+with exact ADDR_LOCAL IREG
+			yields {indexed_r_off,ebp,%2,1,%1.ind}
+with rmorconst Xreg_off
+  gen add %2.reg,%1	yields %2
+with Xreg_off rmorconst
+  gen add %1.reg,%2	yields %1
+with exact Xreg_off ANYCON
+			yields {Xreg_off,%1.reg,%1.off+%2.val}
+with exact Rreg_off ANYCON
+			yields {Rreg_off,%1.reg,%1.off+%2.val}
+with exact indexed_r_off ANYCON
+			yields {indexed_r_off,%1.reg,%1.reg2,
+					%1.scale,%1.off+%2.val}
+with exact indexed_off ANYCON
+			yields {indexed_off,%1.reg,%1.scale,%1.off+%2.val}
+with exact Xreg_off ADDR_EXTERN
+			yields {Xreg_off,%1.reg,%1.off+%2.off}
+with exact Rreg_off ADDR_EXTERN
+			yields {Rreg_off,%1.reg,%1.off+%2.off}
+with exact indexed_r_off ADDR_EXTERN
+			yields {indexed_r_off,%1.reg,%1.reg2,
+					%1.scale,%1.off+%2.off}
+with exact indexed_off ADDR_EXTERN
+			yields {indexed_off,%1.reg,%1.scale,%1.off+%2.off}
+with exact Xreg_off reg_off
+  gen add %1.reg,%2.reg
+			yields {Xreg_off,%1.reg,%1.off+%2.off}
+with exact RREG ADDR_EXTERN
+			yields {Rreg_off, %1, %2.off}
+with exact ADDR_EXTERN RREG
+			yields {Rreg_off,%2,%1.off}
+
+with exact rmorconst ADDR_EXTERN
+  uses reusing %1,ADDREG=%1
+			yields {Xreg_off,%a,%2.off}
+with exact ADDR_EXTERN rmorconst
+  uses reusing %2,ADDREG=%2
+			yields {Xreg_off,%a,%1.off}
+with rmorconst ADDREG
+  gen add %2,%1		yields %2
+with ADDREG rmorconst
+  gen add %1,%2		yields %1
+
+pat sbs $1==4
+with exact ANYCON Xreg_off
+			yields {Xreg_off,%2.reg,%2.off+"-"+%1.val}
+with exact ANYCON Rreg_off
+			yields {Rreg_off,%2.reg,%2.off+"-"+%1.val}
+with exact ANYCON indexed_r_off
+			yields {indexed_r_off,%2.reg,%2.reg2,%2.scale,
+					%2.off+"-"+%1.val}
+with exact ANYCON indexed_off
+			yields {indexed_off,%2.reg,%2.scale,%2.off+"-"+%1.val}
+with exact ANYCON ADDR_LOCAL
+			yields {ADDR_LOCAL,%2.ind-%1.val}
+with rm Xreg_off
+  gen sub %2.reg,%1	yields {Xreg_off,%2.reg,%2.off}
+
+/* Should not occur
+with exact reg_off ANYCON
+			yields {reg_off,%1.reg,%1.off-%2.val}
+with ANYCON ADDR_EXTERN
+			yields {ADDR_EXTERN,%2.off+%1.val}
+with exact ANYCON ADDR_LOCAL
+			yields {ADDR_LOCAL,%1.val+%2.ind}
+*/
+
+with rm REG
+  gen sub %2,%1		yields %2
+with const ACC
+  gen sub %2,%1		yields %2
+
+/*******************************************************************
+ *  Group 7 : Increment/Decrement Zero				   *
+ *******************************************************************/
+
+pat inc
+with REG
+gen inc %1			yields %1
+
+#ifdef REGVARS
+pat inl inreg($1)==reg_any
+  kills regvar($1)
+  gen inc {LOCAL,$1,4}
+#endif
+
+pat inl
+kills indir, locals %ind + %size>$1 && %ind<$1+4
+gen inc {LOCAL,$1,4}
+
+pat ine
+kills mem_nonlocals
+gen inc {EXTERN,$1}
+
+pat dec
+with REG
+gen dec %1			yields %1
+
+#ifdef REGVARS
+pat del inreg($1)==reg_any
+  kills regvar($1)
+  gen dec {LOCAL,$1,4}
+#endif
+
+pat del
+kills indir, locals %ind+%size>$1 && %ind<$1+4
+gen dec {LOCAL, $1, 4}
+
+pat dee
+kills mem_nonlocals
+gen dec {EXTERN, $1}
+
+#ifdef REGVARS
+pat zrl inreg($1)==reg_any
+  kills regvar($1)
+  gen move {ANYCON, 0}, {LOCAL,$1,4}
+#endif
+
+pat zrl
+kills indir, locals %ind+%size>$1 && %ind<$1+4
+gen move {ANYCON, 0}, {LOCAL,$1,4}
+
+pat zre
+kills mem_nonlocals
+gen move {ANYCON, 0},  {EXTERN, $1}
+
+pat zrf			leaving zer $1
+
+pat zer $1==4			yields {ANYCON, 0}
+pat zer $1==8			yields {ANYCON, 0} {ANYCON, 0}
+pat zer $1==12			yields {ANYCON, 0} {ANYCON, 0}
+				       {ANYCON, 0}
+pat zer $1==16			yields {ANYCON, 0} {ANYCON, 0}
+				       {ANYCON, 0} {ANYCON, 0}
+
+pat zer defined($1)
+with STACK
+gen move {ANYCON, $1/4}, ecx
+    move {ANYCON, 0}, ebx
+    1:
+    push ebx
+    loop {label,1b}
+
+pat zer !defined($1)
+with CXREG STACK
+gen move {ANYCON, $1/4}, ebx
+    sar ecx,{ANYCON, 1}
+    1:
+    push ebx
+    loop {label,1b}
+
+#ifdef REGVARS
+proc lolrxxxstl example lol adi stl
+with rmorconst
+  kills regvar($1)
+  gen axx* {LOCAL, $1, 4}, %1
+
+proc lilrxxxsil example lil adi sil
+with regorconst
+kills all_mems
+gen axx* {indir_r, regvar($1)}, %1
+
+proc xxxrstl example adi stl
+with rmorconst regorconst-RREG
+  kills regvar($2)
+  gen move %1, {LOCAL, $2, 4}
+      axx* {LOCAL, $2, 4}, %2
+
+pat lol adi stl $1==$3 && $2==4 && inreg($1)==reg_any	call lolrxxxstl("add")
+pat lol adu stl $1==$3 && $2==4 && inreg($1)==reg_any	call lolrxxxstl("add")
+pat lol ads stl $1==$3 && $2==4 && inreg($1)==reg_any	call lolrxxxstl("add")
+pat lol and stl $1==$3 && $2==4 && inreg($1)==reg_any	call lolrxxxstl("and")
+pat lol ior stl $1==$3 && $2==4 && inreg($1)==reg_any	call lolrxxxstl("or")
+pat lol xor stl $1==$3 && $2==4 && inreg($1)==reg_any	call lolrxxxstl("xor")
+
+pat lil adi sil $1==$3 && $2==4 && inreg($1)==reg_any	call lilrxxxsil("add")
+pat lil adu sil $1==$3 && $2==4 && inreg($1)==reg_any	call lilrxxxsil("add")
+pat lil ads sil $1==$3 && $2==4 && inreg($1)==reg_any	call lilrxxxsil("add")
+pat lil and sil $1==$3 && $2==4 && inreg($1)==reg_any	call lilrxxxsil("and")
+pat lil ior sil $1==$3 && $2==4 && inreg($1)==reg_any	call lilrxxxsil("or")
+pat lil xor sil $1==$3 && $2==4 && inreg($1)==reg_any	call lilrxxxsil("xor")
+
+pat adi stl $1==4 && inreg($2)==reg_any	call xxxrstl("add")
+pat adu stl $1==4 && inreg($2)==reg_any	call xxxrstl("add")
+pat ads stl $1==4 && inreg($2)==reg_any	call xxxrstl("add")
+pat and stl $1==4 && inreg($2)==reg_any	call xxxrstl("and")
+pat ior stl $1==4 && inreg($2)==reg_any	call xxxrstl("or")
+pat xor stl $1==4 && inreg($2)==reg_any	call xxxrstl("xor")
+#endif
+
+proc lolxxxstl example lol adi stl
+with regorconst
+kills indir, locals %ind+%size>$1 && %ind<$1+4
+gen axx* {LOCAL, $1, 4}, %1
+
+pat lol adi stl $1==$3 && $2==4		call lolxxxstl("add")
+pat lol adu stl $1==$3 && $2==4		call lolxxxstl("add")
+pat lol ads stl $1==$3 && $2==4		call lolxxxstl("add")
+pat lol and stl $1==$3 && $2==4		call lolxxxstl("and")
+pat lol ior stl $1==$3 && $2==4		call lolxxxstl("or")
+pat lol xor stl $1==$3 && $2==4		call lolxxxstl("xor")
+
+proc lilxxxsil example lil adi sil
+with regorconst
+kills all_mems
+uses ADDREG={LOCAL, $1, 4}
+gen axx* {indir_r, %a}, %1
+    killreg %a
+
+pat lil adi sil $1==$3 && $2==4		call lilxxxsil("add")
+pat lil adu sil $1==$3 && $2==4		call lilxxxsil("add")
+pat lil ads sil $1==$3 && $2==4		call lilxxxsil("add")
+pat lil and sil $1==$3 && $2==4		call lilxxxsil("and")
+pat lil ior sil $1==$3 && $2==4		call lilxxxsil("or")
+pat lil xor sil $1==$3 && $2==4		call lilxxxsil("xor")
+
+#ifdef REGVARS
+proc lilruxxsil example lil ngi sil
+kills all_mems
+gen uxx* {indir_r, regvar($1)}
+
+pat lil ngi sil $1==$3 && $2==4 && inreg($1)==reg_any	call lilruxxsil("neg")
+pat lil com sil $1==$3 && $2==4 && inreg($1)==reg_any	call lilruxxsil("not")
+pat lil dec sil $1==$3 && inreg($1)==reg_any		call lilruxxsil("dec")
+pat lil inc sil $1==$3 && inreg($1)==reg_any		call lilruxxsil("inc")
+pat lil adp sil $1==$3 && inreg($1)==reg_any && $2==1	call lilruxxsil("inc")
+pat lil adp sil $1==$3 && inreg($1)==reg_any && $2==(0-1)
+							call lilruxxsil("dec")
+#endif
+
+proc liluxxsil example lil ngi sil
+kills all_mems
+uses ADDREG={LOCAL, $1, 4}
+gen uxx* {indir_r, %a}
+    killreg %a
+
+pat lil ngi sil $1==$3 && $2==4		call liluxxsil("neg")
+pat lil com sil $1==$3 && $2==4		call liluxxsil("not")
+pat lil dec sil $1==$3			call liluxxsil("dec")
+pat lil inc sil $1==$3			call liluxxsil("inc")
+pat lil adp sil $1==$3 && $2==1		call liluxxsil("inc")
+pat lil adp sil $1==$3 && $2==(0-1)	call liluxxsil("dec")
+
+proc loexxxste example loe adi ste
+with regorconst
+kills mem_nonlocals
+gen axx* {EXTERN, $1}, %1
+
+pat loe adi ste $1==$3 && $2==4		call loexxxste("add")
+pat loe adu ste $1==$3 && $2==4		call loexxxste("add")
+pat loe ads ste $1==$3 && $2==4		call loexxxste("add")
+pat loe and ste $1==$3 && $2==4		call loexxxste("and")
+pat loe ior ste $1==$3 && $2==4		call loexxxste("or")
+pat loe xor ste $1==$3 && $2==4		call loexxxste("xor")
+
+#ifdef REGVARS
+proc lofrxxxsof example lol lof adi lol stf
+with regorconst
+kills all_mems
+gen axx* {indir_r_off, regvar($1), $2}, %1
+
+pat lol lof adi lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
+					call lofrxxxsof("add")
+pat lol lof adu lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
+					call lofrxxxsof("add")
+pat lol lof ads lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
+					call lofrxxxsof("add")
+pat lol lof and lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
+					call lofrxxxsof("and")
+pat lol lof ior lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
+					call lofrxxxsof("or")
+pat lol lof xor lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
+					call lofrxxxsof("xor")
+
+proc lofruxxsof example lol lof inc lol stf
+kills all_mems
+gen uxx* {indir_r_off, regvar($1), $2}
+
+pat lol lof inc lol stf $1==$4 && $2==$5 && inreg($1)==reg_any
+					call lofruxxsof("inc")
+pat lol lof adp lol stf $1==$4 && $2==$5 && inreg($1)==reg_any && $3==1
+					call lofruxxsof("inc")
+pat lol lof dec lol stf $1==$4 && $2==$5 && inreg($1)==reg_any
+					call lofruxxsof("dec")
+pat lol lof adp lol stf $1==$4 && $2==$5 && inreg($1)==reg_any && $3==(0-1)
+					call lofruxxsof("dec")
+pat lol lof ngi lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
+					call lofruxxsof("neg")
+pat lol lof com lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
+					call lofruxxsof("not")
+
+pat lol lof dup adp lol stf $1==$5 && $2==$6 && $3==4 && inreg($1)==reg_any
+kills all_mems
+uses ADDREG={indir_r_off, regvar($1), $2}
+gen add {indir_r_off, regvar($1), $2}, {ANYCON, $4} 	yields %a
+
+#endif
+
+proc lofuxxsof example lol lof inc lol stf
+kills all_mems
+uses ADDREG={LOCAL,$1,4}
+gen uxx* {indir_r_off, %a, $2}
+    killreg %a
+
+pat lol lof ngi lol stf $1==$4 && $2==$5 && $3==4	call lofuxxsof("neg")
+pat lol lof com lol stf $1==$4 && $2==$5 && $3==4	call lofuxxsof("not")
+pat lol lof dec lol stf $1==$4 && $2==$5		call lofuxxsof("dec")
+pat lol lof inc lol stf $1==$4 && $2==$5		call lofuxxsof("inc")
+pat lol lof adp lol stf $1==$4 && $2==$5 && $3==1	call lofuxxsof("inc")
+pat lol lof adp lol stf $1==$4 && $2==$5 && $3==(0-1)	call lofuxxsof("dec")
+
+proc lofxxxsof example lol lof adi lol stf
+with regorconst
+kills all_mems
+uses ADDREG={LOCAL,$1,4}
+gen axx* {indir_r_off, %a, $2}, %1
+    killreg %a
+
+pat lol lof adi lol stf $1==$4 && $2==$5 && $3==4	call lofxxxsof("add")
+pat lol lof adu lol stf $1==$4 && $2==$5 && $3==4	call lofxxxsof("add")
+pat lol lof ads lol stf $1==$4 && $2==$5 && $3==4	call lofxxxsof("add")
+pat lol lof and lol stf $1==$4 && $2==$5 && $3==4	call lofxxxsof("and")
+pat lol lof ior lol stf $1==$4 && $2==$5 && $3==4	call lofxxxsof("or")
+pat lol lof xor lol stf $1==$4 && $2==$5 && $3==4	call lofxxxsof("xor")
+
+pat lol lof dup adp lol stf $1==$5 && $2==$6 && $3==4
+kills all_mems
+uses ADDREG={LOCAL,$1,4},ADDREG
+gen mov %b, {indir_r_off, %a, $2}
+    add {indir_r_off, %a, $2}, {ANYCON, $4}
+    killreg %a				yields %b
+
+proc lefuxxsef example loe lof inc loe stf
+kills all_mems
+uses ADDREG={EXTERN,$1}
+gen uxx* {indir_r_off, %a, $2}
+    killreg %a
+
+pat loe lof ngi loe stf $1==$4 && $2==$5 && $3==4	call lefuxxsef("neg")
+pat loe lof com loe stf $1==$4 && $2==$5 && $3==4	call lefuxxsef("not")
+pat loe lof dec loe stf $1==$4 && $2==$5		call lefuxxsef("dec")
+pat loe lof inc loe stf $1==$4 && $2==$5		call lefuxxsef("inc")
+pat loe lof adp loe stf $1==$4 && $2==$5 && $3==1	call lefuxxsef("inc")
+pat loe lof adp loe stf $1==$4 && $2==$5 && $3==(0-1)	call lefuxxsef("dec")
+
+proc lefxxxsef example loe lof adi loe stf
+with regorconst
+kills all_mems
+uses ADDREG={EXTERN,$1}
+gen axx* {indir_r_off, %a, $2}, %1
+    killreg %a
+
+pat loe lof adi loe stf $1==$4 && $2==$5 && $3==4	call lefxxxsef("add")
+pat loe lof adu loe stf $1==$4 && $2==$5 && $3==4	call lefxxxsef("add")
+pat loe lof ads loe stf $1==$4 && $2==$5 && $3==4	call lefxxxsef("add")
+pat loe lof and loe stf $1==$4 && $2==$5 && $3==4	call lefxxxsef("and")
+pat loe lof ior loe stf $1==$4 && $2==$5 && $3==4	call lefxxxsef("or")
+pat loe lof xor loe stf $1==$4 && $2==$5 && $3==4	call lefxxxsef("xor")
+
+pat loe lof dup adp loe stf $1==$5 && $2==$6 && $3==4
+kills all_mems
+uses ADDREG={EXTERN,$1},ADDREG
+gen mov %b, {indir_r_off, %a, $2}
+    add {indir_r_off, %a, $2}, {ANYCON, $4}
+    killreg %a				yields %b
+
+proc leiuxxsei example loe loi inc loe sti
+kills all_mems
+uses ADDREG={EXTERN,$1}
+gen uxx* {indir_r, %a}
+    killreg %a
+
+pat loe loi ngi loe sti $1==$4 && $2==4 && $5==4 && $3==4
+	call leiuxxsei("neg")
+pat loe loi com loe sti $1==$4 && $2==4 && $5==4 && $3==4
+	call leiuxxsei("not")
+pat loe loi dec loe sti $1==$4 && $2==4 && $5==4
+	call leiuxxsei("dec")
+pat loe loi inc loe sti $1==$4 && $2==4 && $5==4
+	call leiuxxsei("inc")
+pat loe loi adp loe sti $1==$4 && $2==4 && $5==4 && $3==1
+	call leiuxxsei("inc")
+pat loe loi adp loe sti $1==$4 && $2==4 && $5==4 && $3==(0-1)
+	call leiuxxsei("dec")
+
+proc leixxxsei example loe loi adi loe sti
+with regorconst
+kills all_mems
+uses ADDREG={EXTERN,$1}
+gen axx* {indir_r, %a}, %1
+    killreg %a
+
+pat loe loi adi loe sti $1==$4 && $2==4 && $5==4 && $3==4
+	call leixxxsei("add")
+pat loe loi adu loe sti $1==$4 && $2==4 && $5==4 && $3==4
+	call leixxxsei("add")
+pat loe loi ads loe sti $1==$4 && $2==4 && $5==4 && $3==4
+	call leixxxsei("add")
+pat loe loi and loe sti $1==$4 && $2==4 && $5==4 && $3==4
+	call leixxxsei("and")
+pat loe loi ior loe sti $1==$4 && $2==4 && $5==4 && $3==4
+	call leixxxsei("or")
+pat loe loi xor loe sti $1==$4 && $2==4 && $5==4 && $3==4
+	call leixxxsei("xor")
+
+#ifdef REGVARS
+proc lifuxxsif example lil lof inc lil stf
+kills all_mems
+uses ADDREG={indir_r,regvar($1)}
+gen uxx* {indir_r_off, %a, $2}
+    killreg %a
+
+pat lil lof ngi lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
+	call lifuxxsif("neg")
+pat lil lof com lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
+	call lifuxxsif("not")
+pat lil lof dec lil stf $1==$4 && $2==$5 && inreg($1)>0
+	call lifuxxsif("dec")
+pat lil lof inc lil stf $1==$4 && $2==$5 && inreg($1)>0
+	call lifuxxsif("inc")
+
+proc lifxxxsif example lil lof adi lil stf
+with regorconst
+kills all_mems
+uses ADDREG={indir_r,regvar($1)}
+gen axx* {indir_r_off, %a, $2}, %1
+    killreg %a
+
+pat lil lof adi lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
+	call lifxxxsif("add")
+pat lil lof adu lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
+	call lifxxxsif("add")
+pat lil lof ads lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
+	call lifxxxsif("add")
+pat lil lof and lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
+	call lifxxxsif("and")
+pat lil lof ior lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
+	call lifxxxsif("or")
+pat lil lof xor lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
+	call lifxxxsif("xor")
+
+proc liiuxxsii example lil loi inc lil sti
+kills all_mems
+uses ADDREG={indir_r,regvar($1)}
+gen uxx* {indir_r, %a}
+    killreg %a
+
+pat lil loi ngi lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
+	call liiuxxsii("neg")
+pat lil loi com lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
+	call liiuxxsii("not")
+pat lil loi dec lil sti $1==$4 && $2==4 && $5==4 && inreg($1)>0
+	call liiuxxsii("dec")
+pat lil loi inc lil sti $1==$4 && $2==4 && $5==4 && inreg($1)>0
+	call liiuxxsii("inc")
+pat lil loi adp lil sti $1==$4 && $2==4 && $5==4 && inreg($1)>0 && $3==1
+	call liiuxxsii("inc")
+pat lil loi adp lil sti $1==$4 && $2==4 && $5==4 && inreg($1)>0 && $3==(0-1)
+	call liiuxxsii("dec")
+
+proc liixxxsii example lil loi adi lil sti
+with regorconst
+kills all_mems
+uses ADDREG={indir_r,regvar($1)}
+gen axx* {indir_r, %a}, %1
+    killreg %a
+
+pat lil loi adi lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
+	call liixxxsii("add")
+pat lil loi adu lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
+	call liixxxsii("add")
+pat lil loi ads lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
+	call liixxxsii("add")
+pat lil loi and lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
+	call liixxxsii("and")
+pat lil loi ior lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
+	call liixxxsii("or")
+pat lil loi xor lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
+	call liixxxsii("xor")
+
+proc lolcrxxstl example lol loc sbi stl
+  kills regvar($1)
+  gen axx* {LOCAL,$1,4},{ANYCON,$2}
+
+pat lol loc sbi stl $1==$4 && $3==4 && inreg($1)==reg_any
+						call lolcrxxstl("sub")
+pat lol loc sbu stl $1==$4 && $3==4 && inreg($1)==reg_any
+						call lolcrxxstl("sub")
+pat lol loc sli stl $1==$4 && $3==4 && inreg($1)==reg_any
+						call lolcrxxstl("sal")
+pat lol loc slu stl $1==$4 && $3==4 && inreg($1)==reg_any
+						call lolcrxxstl("sal")
+pat lol loc sri stl $1==$4 && $3==4 && inreg($1)==reg_any
+						call lolcrxxstl("sar")
+pat lol loc sru stl $1==$4 && $3==4 && inreg($1)==reg_any
+						call lolcrxxstl("shr")
+#endif
+
+proc lolcxxstl example lol loc sbi stl
+  kills indir, locals %ind+%size>$1 && %ind<$1+4
+  gen axx* {LOCAL,$1,4},{ANYCON,$2}
+
+pat lol loc sbi stl $1==$4 && $3==4		call lolcxxstl("sub")
+pat lol loc sbu stl $1==$4 && $3==4		call lolcxxstl("sub")
+pat lol loc adi stl $1==$4 && $3==4		call lolcxxstl("add")
+pat lol loc adi stl $1==$4 && $3==4		call lolcxxstl("add")
+pat lol loc sli stl $1==$4 && $3==4		call lolcxxstl("sal")
+pat lol loc slu stl $1==$4 && $3==4		call lolcxxstl("sal")
+pat lol loc sri stl $1==$4 && $3==4		call lolcxxstl("sar")
+pat lol loc sru stl $1==$4 && $3==4		call lolcxxstl("shr")
+
+proc loecxxste example loe loc sbi ste
+  kills mem_nonlocals
+  gen axx* {EXTERN,$1},{ANYCON,$2}
+
+pat loe loc sbi ste $1==$4 && $3==4		call loecxxste("sub")
+pat loe loc sbu ste $1==$4 && $3==4		call loecxxste("sub")
+pat loe loc adu ste $1==$4 && $3==4		call loecxxste("add")
+pat loe loc adi ste $1==$4 && $3==4		call loecxxste("add")
+pat loe loc sli ste $1==$4 && $3==4		call loecxxste("sal")
+pat loe loc slu ste $1==$4 && $3==4		call loecxxste("sal")
+pat loe loc sri ste $1==$4 && $3==4		call loecxxste("sar")
+pat loe loc sru ste $1==$4 && $3==4		call loecxxste("shr")
+
+#ifdef REGVARS
+proc lilcxxsil example lil loc sbi sil
+  kills mem_nonlocals
+  gen axx* {indir_r,regvar($1)},{ANYCON,$2}
+
+pat lil loc sbi sil $1==$4 && $3==4 && inreg($1)>0	call lilcxxsil("sub")
+pat lil loc sbu sil $1==$4 && $3==4 && inreg($1)>0	call lilcxxsil("sub")
+pat lil loc adu sil $1==$4 && $3==4 && inreg($1)>0	call lilcxxsil("add")
+pat lil loc adi sil $1==$4 && $3==4 && inreg($1)>0	call lilcxxsil("add")
+pat lil loc sli sil $1==$4 && $3==4 && inreg($1)>0	call lilcxxsil("sal")
+pat lil loc slu sil $1==$4 && $3==4 && inreg($1)>0	call lilcxxsil("sal")
+pat lil loc sri sil $1==$4 && $3==4 && inreg($1)>0	call lilcxxsil("sar")
+pat lil loc sru sil $1==$4 && $3==4 && inreg($1)>0	call lilcxxsil("shr")
+
+pat lol ngi stl $1==$3 && $2==4 && inreg($1)==reg_any
+kills regvar($1)
+gen neg {LOCAL, $1, 4}
+#endif
+
+pat lol ngi stl $1==$3 && $2==4
+kills indir, locals %ind+%size>$1 && %ind<$1+4
+gen neg {LOCAL, $1, 4}
+
+pat lol dup adp stl loi stl $1==$4 && $2==4 && $5<=4
+					leaving lol $1 loi $5 stl $6 lol $1 adp $3 stl $4
+
+#ifdef REGVARS
+pat lol dup adp stl loi loc loc cii $1==$4 && $2==4 && $5==1 && inreg($1) > 0 && $6==1 && $7==4
+uses REG
+gen movsxb %a,{indir_r1, regvar($1)}
+				yields %a
+					leaving lol $1 adp $3 stl $4
+
+pat lol dup adp stl loi $1==$4 && $2==4 && $5==1 && inreg($1) > 0
+uses REG1 = {indir_r1, regvar($1)}
+				yields %a
+					leaving lol $1 adp $3 stl $4
+
+pat lol dup adp stl loi loc loc cii $1==$4 && $2==4 && $5==2 && inreg($1) > 0 && $6==2 && $7==4
+uses REG
+gen movsx %a,{indir_r2, regvar($1)}
+				yields %a
+					leaving lol $1 adp $3 stl $4
+
+pat lol dup adp stl loi $1==$4 && $2==4 && $5==2 && inreg($1) > 0
+uses REG2 = {indir_r2, regvar($1)}
+				yields %a
+					leaving lol $4 adp $3 stl $4
+
+pat lol dup adp stl loi $1==$4 && $2==4 && $5==4 && inreg($1) > 0
+uses REG = {indir_r, regvar($1)}
+				yields %a
+					leaving lol $4 adp $3 stl $4
+pat adp stl inreg($2) > 0		leaving stl $2 lol $2 adp $1 stl $2
+#endif
+
+pat lol dup adp stl $1==$4 && $2==4
+uses ADDREG={LOCAL,$1,4}	yields %a
+					leaving lol $4 adp $3 stl $4
+
+pat lol inl $1==$2
+uses REG={LOCAL,$1,4}		yields %a
+					leaving inl $1
+
+pat lol del $1==$2
+uses REG={LOCAL,$1,4}		yields %a
+					leaving del $1
+
+pat lol adp stl $1==$3 && $2==1		leaving inl $1
+pat lol adp stl $1==$3 && $2==0-1	leaving del $1
+pat lol adp stl $1==$3			leaving loc $2 lol $1 adi 4 stl $3
+
+#ifdef REGVARS
+pat lol com stl $1==$3 && $2==4 && inreg($1)==reg_any
+kills regvar($1)
+gen not {LOCAL,$1,4}
+#endif
+
+pat lol com stl $1==$3 && $2==4
+kills indir, locals %ind+%size>$1 && %ind<$1+4
+gen not {LOCAL, $1, 4}
+
+#ifdef REGVARS
+pat lil dup adp sil $1==$4 && $2==4 && inreg($1)==reg_any
+uses ADDREG={indir_r, regvar($1)}
+				yields %a
+					leaving lil $4 adp $3 sil $4
+
+pat lil dup inc sil $1==$4 && $2==4 && inreg($1)==reg_any
+uses REG={indir_r, regvar($1)}
+				yields %a
+					leaving lil $4 inc sil $4
+
+pat lil dup dec sil $1==$4 && $2==4 && inreg($1)==reg_any
+uses REG={indir_r, regvar($1)}
+				yields %a
+					leaving lil $4 dec sil $4
+#endif
+
+pat lil adp sil $1==$3 && $2==1         leaving lil $1 inc sil $1
+
+pat lil adp sil $1==$3 && $2==0-1       leaving lil $1 dec sil $1
+
+pat lil adp sil $1==$3			leaving loc $2 lil $1 adi 4 sil $3
+
+#ifdef REGVARS
+pat lol lof lol lof adp lol stf
+	$1==$3 && $1==$6 && $2==$4 && $2==$7 && inreg($1)==reg_any
+uses ADDREG={indir_r_off, regvar($1), $2}
+				yields %a
+					leaving lol $1 lof $2 adp $5 lol $6 stf $7
+
+pat lol lof lol lof inc lol stf
+	$1==$3 && $1==$6 && $2==$4 && $2==$7 && inreg($1)==reg_any
+uses REG={indir_r_off, regvar($1), $2}
+				yields %a
+					leaving lol $1 lof $2 inc lol $6 stf $7
+
+pat lol lof lol lof dec lol stf
+	$1==$3 && $1==$6 && $2==$4 && $2==$7 && inreg($1)==reg_any
+uses REG={indir_r_off, regvar($1), $2}
+				yields %a
+					leaving lol $1 lof $2 dec lol $6 stf $7
+
+pat lol lof dup adp lol stf
+        $1==$5 && $2==$6 && $3==4 && inreg($1)==reg_any
+uses REG={indir_r_off, regvar($1), $2}
+                                yields %a
+                                        leaving lol $1 lof $2 adp $4 lol $1 stf
+$2
+
+pat lol lof dup inc lol stf
+        $1==$5 && $2==$6 && $3==4 && inreg($1)==reg_any
+uses REG={indir_r_off, regvar($1), $2}
+                                yields %a
+                                        leaving lol $1 lof $2 inc lol $1 stf $2
+
+pat lol lof dup dec lol stf
+        $1==$5 && $2==$6 && $3==4 && inreg($1)==reg_any
+uses REG={indir_r_off, regvar($1), $2}
+                                yields %a
+                                        leaving lol $1 lof $2 dec lol $1 stf $2
+
+#endif
+
+pat lol lof adp lol stf $1==$4 && $2==$5
+			leaving loc $3 lol $1 lof $2 adi 4 lol $4 stf $5
+
+pat lol lof dup adp lol stf
+        $1==$5 && $2==$6 && $3==4 && $4==1
+kills all_mems
+uses REG={LOCAL,$1,4}, REG
+gen move {indir_r_off, %a, $2},%b
+    inc {indir_r_off, %a, $2}
+                                yields %b
+
+pat loe lof dup adp loe stf
+        $1==$5 && $2==$6 && $3==4 && $4==1
+kills all_mems
+uses REG={EXTERN,$1}, REG
+gen move {indir_r_off, %a, $2},%b
+    inc {indir_r_off, %a, $2}
+                                yields %b
+
+pat loe loi dup adp loe sti
+        $1==$5 && $2==$6 && $3==4 && $2==4 && $4==1
+kills all_mems
+uses REG={EXTERN,$1}, REG
+gen move {indir_r, %a},%b
+    inc {indir_r, %a}
+                                yields %b
+
+pat lol lof dup adp lol stf
+        $1==$5 && $2==$6 && $3==4 && $4==(0-1)
+kills all_mems
+uses REG={LOCAL,$1,4}, REG
+gen move {indir_r_off, %a, $2},%b
+    dec {indir_r_off, %a, $2}
+                                yields %b
+
+pat loe lof dup adp loe stf
+        $1==$5 && $2==$6 && $3==4 && $4==(0-1)
+kills all_mems
+uses REG={EXTERN,$1}, REG
+gen move {indir_r_off, %a, $2},%b
+    dec {indir_r_off, %a, $2}
+                                yields %b
+pat loe loi dup adp loe sti
+        $1==$5 && $2==$6 && $3==4 && $2==4 && $4==(0-1)
+kills all_mems
+uses REG={EXTERN,$1}, REG
+gen move {indir_r, %a},%b
+    dec {indir_r, %a}
+                                yields %b
+
+pat lol lof dup adp lol stf
+        $1==$5 && $2==$6 && $3==4
+kills all_mems
+uses REG={LOCAL,$1,4}, REG
+gen move {indir_r_off, %a, $2},%b
+    add {indir_r_off, %a, $2}, {ANYCON, $4}
+                                yields %b
+
+pat loe lof dup adp loe stf
+        $1==$5 && $2==$6 && $3==4
+kills all_mems
+uses REG={EXTERN,$1}, REG
+gen move {indir_r_off, %a, $2},%b
+    add {indir_r_off, %a, $2}, {ANYCON, $4}
+                                yields %b
+
+pat loe loi dup adp loe sti
+        $1==$5 && $2==$6 && $3==4 && $2==4
+kills all_mems
+uses REG={EXTERN,$1}, REG
+gen move {indir_r, %a},%b
+    add {indir_r, %a}, {ANYCON, $4}
+                                yields %b
+
+
+pat loe ngi ste $1==$3 && $2==4
+kills mem_nonlocals
+gen neg {EXTERN, $1}
+
+pat loe dup adp ste $1==$4 && $2==4
+uses REG={EXTERN,$1}	yields %a
+					leaving loe $1 adp $3 ste $1
+
+pat loe ine $1==$2
+uses REG={EXTERN,$1}	yields %a
+					leaving ine $1
+
+pat loe dee $1==$2
+uses REG={EXTERN,$1}	yields %a
+					leaving dee $1
+
+pat loe adp ste $1==$3 && $2==1		leaving ine $1
+
+pat loe adp ste $1==$3 && $2==0-1	leaving dee $1
+
+pat loe adp ste $1==$3			leaving loc $2 loe $1 adi 4 ste $3
+
+pat loe com ste $1==$3 && $2==4
+kills mem_nonlocals
+gen not {EXTERN, $1}
+
+pat loe lof adp loe stf $1==$4 && $2==$5
+				leaving loc $3 loe $1 lof $2 adi 4 loe $1 stf $2
+
+pat loe loi adp loe sti $1==$4 && $2==$5 && $2==4
+				leaving loc $3 loe $1 loi $2 adi 4 loe $1 sti $2
+
+pat lil lof adp lil stf $1==$4 && $2==$5 && $3==1
+				leaving lil $1 lof $2 inc lil $1 stf $2
+pat lil lof adp lil stf $1==$4 && $2==$5 && $3==0-1
+				leaving lil $1 lof $2 dec lil $1 stf $2
+pat lil lof adp lil stf $1==$4 && $2==$5
+				leaving loc $3 lil $1 lof $2 adi 4 lil $1 stf $2
+pat lil loi adp lil sti $1==$4 && $2==$5 && $2==4 && $3==1
+				leaving lil $1 loi $2 inc lil $1 sti $2
+pat lil loi adp lil sti $1==$4 && $2==$5 && $2==4 && $3==0-1
+				leaving lil $1 loi $2 dec lil $1 sti $2
+pat lil loi adp lil sti $1==$4 && $2==$5 && $2==4
+				leaving loc $3 lil $1 loi $2 adi 4 lil $1 sti $2
+
+/*******************************************************************
+ *  Group 8: Convert Instructions				   *
+ *******************************************************************/
+
+pat cii
+with CXREG DXREG ACC
+kills ALL
+gen proccall {label,".cii"}		yields %3
+
+#if 0
+/* wrong when integer size > 4 */
+pat ciu					leaving cuu
+pat cui					leaving cuu
+
+pat cuu
+#endif
+
+pat loc loc cii zeq $1==1
+with GENREG STACK
+gen test %1.1
+    je {label, $4}
+
+pat loc loc cii zne $1==1
+with GENREG STACK
+gen test %1.1
+    jne {label, $4}
+
+pat loc loc cii loc and zeq $4<256 && $4>=0 && $5==4 && $1==1 && $2==4
+		leaving loc $4 and $5 zeq $6
+pat loc loc cii loc and zne $4<256 && $4>=0 && $5==4 && $1==1 && $2==4
+		leaving loc $4 and $5 zne $6
+pat loc loc cii loc and zeq $4<65536 && $4>=0 && $5==4 && $1==2 && $2==4
+		leaving loc $4 and $5 zeq $6
+pat loc loc cii loc and zne $4<65536 && $4>=0 && $5==4 && $1==2 && $2==4
+		leaving loc $4 and $5 zne $6
+
+pat loc loc cii $1==1 && $2==4
+with ACC
+gen movsxb %1,%1		yields eax
+with exact rm1
+uses reusing %1, GENREG
+gen movsxb %a,%1		yields %a
+
+pat loc loc cii $1==2 && $2==4
+with ACC
+gen  movsx %1,%1		yields eax
+with exact rm2
+uses reusing %1,GENREG
+gen movsx %a,%1			yields %a
+
+pat loc loc cii $1==4 && $2==8
+with ACC
+  gen cdq.			yields edx eax
+
+pat loc loc cii $1<4 && $2==8	leaving loc $1 loc 4 cii loc 4 loc $2 cii
+
+pat loc loc cii $1==8 && $2==4
+with a_word a_word		yields %1
+
+pat loc loc ciu				leaving loc $1 loc $2 cuu
+pat loc loc cui				leaving loc $1 loc $2 cuu
+
+pat loc loc cuu $1==$2
+
+pat loc loc cuu $1==4 && $2==8
+with a_word			yields {ANYCON,0} %1
+
+pat loc loc cuu $1==8 && $2==4
+with a_word a_word		yields %1
+
+pat loc loc cif $1==4 && $2==4		leaving loc 4 cal ".cif4" asp 4
+pat loc loc cif $1==4 && $2==8		leaving loc 4 cal ".cif8"
+pat loc loc cuf $1==4 && $2==4		leaving loc 4 cal ".cuf4" asp 4
+pat loc loc cuf $1==4 && $2==8		leaving loc 4 cal ".cuf8"
+pat loc loc cfi		leaving loc $1 loc $2 cal ".cfi" asp 8+($1-4)
+pat loc loc cfu		leaving loc $1 loc $2 cal ".cfu" asp 8+($1-4)
+pat loc loc cff $1==8 && $2==4	leaving cal ".cff4" asp 4
+pat loc loc cff $1==4 && $2==8
+with REG
+kills ALL
+  gen push {ANYCON,0}
+      push %1			leaving cal ".cff8"
+
+/********************************************************************
+ *  Group 9 : Logical Instructions				    *
+ ********************************************************************/
+
+pat and $1==4
+with REG rmorconst
+  gen and %1,%2				yields %1
+with rmorconst REG
+  gen and %2,%1				yields %2
+
+pat loc and $1==255 && $2==4
+with GENREG				yields %1.1
+
+pat and $1==8
+with EXACT REG REG rmorconst rmorconst
+  gen and %1,%3
+      and %2,%4				yields %2 %1
+with rmorconst rmorconst REG REG
+  gen and %3,%1
+      and %4,%2				yields %4 %3
+
+pat and defined($1)
+kills ALL
+  gen mov ecx,{ANYCON,$1}
+      proccall {label, ".and"}
+
+pat and !defined($1)
+with CXREG
+kills ALL
+  gen proccall {label, ".and"}
+
+pat ior $1==4
+with REG rmorconst
+  gen or %1,%2				yields %1
+with rmorconst REG
+  gen or %2,%1				yields %2
+
+pat ior $1==8
+with EXACT REG REG rmorconst rmorconst
+  gen or %1,%3
+      or %2,%4				yields %2 %1
+with rmorconst rmorconst REG REG
+  gen or %3,%1
+      or %4,%2				yields %4 %3
+
+pat ior defined($1)
+kills ALL
+  gen mov ecx,{ANYCON,$1}
+      proccall {label, ".ior"}
+
+pat ior !defined($1)
+with CXREG
+kills ALL
+  gen proccall {label, ".ior"}
+
+pat xor $1==4
+with REG rmorconst
+  gen xor %1,%2				yields %1
+with rmorconst REG
+  gen xor %2,%1				yields %2
+
+pat xor $1==8
+with EXACT REG REG rmorconst rmorconst
+  gen xor %1,%3
+      xor %2,%4				yields %2 %1
+with rmorconst rmorconst REG REG
+  gen xor %3,%1
+      xor %4,%2				yields %4 %3
+
+pat xor defined($1)
+kills ALL
+  gen mov ecx,{ANYCON,$1}
+      proccall {label, ".xor"}
+
+pat xor !defined($1)
+with CXREG
+kills ALL
+  gen proccall {label, ".xor"}
+
+pat com $1==4
+with REG
+  gen not %1				yields %1
+
+pat com $1==8
+with REG REG
+  gen not %2
+      not %1				yields %2 %1
+
+pat com defined($1)
+kills ALL
+  gen mov ecx,{ANYCON,$1}
+      proccall {label, ".com"}
+
+pat com !defined($1)
+with CXREG
+kills ALL
+  gen proccall {label, ".com"}
+
+pat rol $1==4
+with SHIFT_CREG REG
+  gen rol %2,cl				yields %2
+with ANYCON REG
+  gen rol %2,%1				yields %2
+
+pat rol $1==8
+with SHIFT_CREG REG REG
+  uses REG
+  gen testb cl,{ANYCON,32}
+      je {label,1f}
+      xchg %2,%3
+      1:
+      mov %a,%3
+      shld %3,%2,cl
+      shld %2,%a,cl			yields %3 %2
+
+pat loc rol ($1&32)==0 && $2==8
+with REG REG
+  uses REG
+  gen mov %a,%2
+      shld %2,%1,{ANYCON,$1&31}
+      shld %1,%a,{ANYCON,$1&31}		yields %2 %1
+pat loc rol ($1&63)==32 && $2==8
+  leaving exg 4
+pat loc rol ($1&32)!=0 && $2==8
+  leaving loc (0-$1)&31 ror 8
+
+pat ror $1==4
+with SHIFT_CREG REG
+  gen ror %2,cl				yields %2
+with ANYCON REG
+  gen ror %2,%1				yields %2
+
+pat ror $1==8
+with SHIFT_CREG REG REG
+  uses REG
+  gen testb cl,{ANYCON,32}
+      je {label,1f}
+      xchg %2,%3
+      1:
+      mov %a,%2
+      shrd %2,%3,cl
+      shrd %3,%a,cl			yields %3 %2
+
+pat loc ror ($1&32)==0 && $2==8
+with REG REG
+  uses REG
+  gen mov %a,%1
+      shrd %1,%2,{ANYCON,$1&31}
+      shrd %2,%a,{ANYCON,$1&31}		yields %2 %1
+pat loc ror ($1&63)==32 && $2==8
+  leaving exg 4
+pat loc ror ($1&32)!=0 && $2==8
+  leaving loc (0-$1)&31 rol 8
+
+/*******************************************************************
+ *  Group 10 : Set Instructions					   *
+ *******************************************************************/
+
+pat inn $1==4
+with SHIFT_CREG REG
+gen shr %2,cl
+    and %2,{ANYCON, 1}			yields %2
+with ANYCON REG
+gen shr %2,%1
+    and %2,{ANYCON, 1}			yields %2
+
+pat loc inn $1==0 && $2==4
+with REG
+gen and %1,{ANYCON, 1}			yields %1
+
+pat inn defined($1)
+with ACC
+kills ALL
+gen mov ecx,{ANYCON, $1}
+    proccall {label,".inn"}		yields eax
+
+pat inn !defined($1)
+with CXREG ACC
+kills ALL
+gen proccall {label,".inn"}		yields eax
+
+pat loc inn zeq $2==4
+with rm STACK
+gen check %1,{ANYCON,1<<$1}
+    je {label,$3}
+
+pat loc inn zne $2==4
+with rm STACK
+gen check %1,{ANYCON,1<<$1}
+    jne {label,$3}
+
+pat set $1==4
+with SHIFT_CREG
+uses REG={ANYCON, 1}
+gen shl %a,cl			yields %a
+
+pat set defined($1)
+with ACC
+kills ALL
+gen mov ecx,{ANYCON, $1}
+    proccall {label,".set"}
+
+pat set !defined($1)
+with CXREG ACC
+kills ALL
+gen proccall {label,".set"}
+
+/********************************************************************
+ *  Group 11 : Array Instructions				    *
+ ********************************************************************/
+
+pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)==0
+				leaving ads 4
+
+pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)!=0
+				leaving adp 0-rom($1,1) ads 4
+
+pat lae aar $2==4 && rom($1,3)==2 && rom($1,1)==0
+				leaving loc 1 sli 4 ads 4
+
+pat lae aar $2==4 && rom($1,3)==2 && rom($1,1)!=0
+				leaving adp 0-rom($1,1) loc 1 sli 4 ads 4
+
+pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)==0
+				leaving loc 2 sli 4 ads 4
+
+pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)!=0
+				leaving adp 0-rom($1,1) loc 2 sli 4 ads 4
+
+pat lae aar $2==4 && rom($1,3)==8 && rom($1,1)==0
+				leaving loc 3 sli 4 ads 4
+
+pat lae aar $2==4 && rom($1,3)==8 && rom($1,1)!=0
+				leaving adp 0-rom($1,1) loc 3 sli 4 ads 4
+
+pat lae aar $2==4 && rom($1,1)==0
+  with ADDREG
+  gen imul %1,%1,{ANYCON,rom($1,3)}	yields %1	leaving ads 4
+
+pat lae aar $2==4 && defined(rom($1,1))
+  with ADDREG
+  gen imul %1,%1,{ANYCON,rom($1,3)}	yields %1
+				leaving adp 0-rom($1,1)*rom($1,3) ads 4
+
+/* when followed by an LOI or STI instruction, use indexed mode */
+pat loc sli ads loi ($1==1 || $1==2 || $1==3) && $2==4 && $3==4
+with IREG ADDR_LOCAL		yields {indexed_r_off,ebp,%1,1<<$1,%2.ind}
+					leaving loi $4
+with IREG ADDR_EXTERN		yields {indexed_off,%1,1<<$1,%2.off}
+					leaving loi $4
+with IREG ADDREG		yields {indexed_r_off,%2,%1,1<<$1,0}
+					leaving loi $4
+
+pat loc sli ads sti ($1==1 || $1==2 || $1==3) && $2==4 && $3==4
+with IREG ADDR_LOCAL		yields {indexed_r_off,ebp,%1,1<<$1,%2.ind}
+					leaving sti $4
+with IREG ADDR_EXTERN		yields {indexed_off,%1,1<<$1,%2.off}
+					leaving sti $4
+with IREG ADDREG		yields {indexed_r_off,%2,%1,1<<$1,0}
+					leaving sti $4
+
+pat loc sli ads ($1==1 || $1==2 || $1==3) && $2==4 && $3==4
+with IREG ADDR_LOCAL		yields {indexed_r_off,ebp,%1,1<<$1,%2.ind}
+with IREG ADDR_EXTERN		yields {indexed_off,%1,1<<$1,%2.off}
+with IREG ADDREG		yields {indexed_r_off,%2,%1,1<<$1,0}
+with REG rmorconst
+gen sal %1,{ANYCON,$1}		yields %2 %1	leaving ads 4
+
+pat aar $1==4
+  with AREG REG
+  gen sub %2,{indir_r,%1}
+      imul %2,{indir_r_off,%1,8}		yields %2	leaving ads 4
+  with reg_off REG
+  gen sub %2,{indir_r_off, %1.reg, %1.off}
+      imul %2,{indir_r_off, %1.reg, 8+%1.off}
+					yields %2	leaving ads 4
+  with ADDR_LOCAL REG
+  gen sub %2,{LOCAL,%1.ind,4}
+      imul %2,{LOCAL,8+%1.ind,4}	yields %2	leaving ads 4
+  with ADDR_EXTERN REG
+  gen sub %2,{EXTERN,%1.off}
+      imul %2,{EXTERN,8+%1.off}		yields %2	leaving ads 4
+
+pat lae lar defined(rom($1,3))	leaving lae $1 aar $2 loi rom($1,3)
+
+pat lae sar defined(rom($1,3))	leaving lae $1 aar $2 sti rom($1,3)
+
+pat aar !defined($1)
+  kills ALL
+  gen proccall {label,".iaar"}		yields ebx
+
+pat sar $1==4
+  with BXREG ACC
+  kills ALL
+  gen proccall {label,".sar4"}
+
+pat sar !defined($1)
+  kills ALL
+  gen proccall {label,".isar"}
+
+pat lar $1==4
+  with BXREG ACC
+  kills ALL
+  gen proccall {label,".lar4"}
+
+pat lar !defined($1)
+  kills ALL
+  gen proccall {label,".ilar"}
+
+/*******************************************************************
+ *  Group 12 : Compare Instructions				   *
+ *******************************************************************/
+
+pat cmi $1==4
+with register rmorconst
+  uses REG={ANYCON,0}
+  gen cmp %1,%2
+      je {label,2f}
+      jl {label,1f}
+      inc %a
+      jmp {label,2f}
+      1:
+      dec %a
+      2:			yields %a
+with rmorconst register
+  uses REG={ANYCON,0}
+  gen cmp %2,%1
+      je {label,2f}
+      jg {label,1f}
+      inc %a
+      jmp {label,2f}
+      1:
+      dec %a
+      2:			yields %a
+
+pat cmi $1==8
+with rmorconst rmorconst GENREG GENREG
+  /* Let dx = 0x100 or 0x101 if a < b, 0 if a == b, 1 if a > b.
+     Shift left so 0x100 becomes the sign bit of edx. */
+  /* can't use 5th REG */
+  gen sub %3,%1
+      setne %3.1
+      sbb %4,%2
+      setl %4.2
+      setg %4.1
+      orb %4.1,%3.1
+      shl %4,{ANYCON,23}	yields %4
+
+pat cmu $1==4				 leaving cmp
+
+pat cmu $1==8
+with rmorconst rmorconst GENREG GENREG
+  gen sub %3,%1
+      setne %3.1
+      sbb %4,%2
+      setb %4.2
+      seta %4.1
+      orb %4.1,%3.1
+      shl %4,{ANYCON,23}	yields %4
+
+pat cms $1==4
+with REG rmorconst
+  gen sub %1,%2			yields %1
+with rmorconst REG
+  gen sub %2,%1			yields %2
+
+pat cms $1==8
+with rmorconst rmorconst REG REG
+  gen sub %3,%1
+      sbb %4,%2
+      or %4,%3			yields %4
+with REG REG rmorconst rmorconst
+  gen sub %1,%3
+      sbb %2,%4
+      or %2,%1			yields %2
+
+pat cms defined($1)
+kills ALL
+  gen mov ecx,{ANYCON,$1}
+      proccall {label,".cms"}	yields ecx
+
+pat cms !defined($1)
+with CXREG
+kills ALL
+  gen proccall {label,".cms"}	yields ecx
+
+pat cmf $1==4
+kills ALL
+  gen proccall {label,".cmf4"}	leaving asp 8 lfr 4
+
+pat cmf $1==8
+kills ALL
+  gen proccall {label,".cmf8"}	leaving asp 16 lfr 4
+
+pat cmp
+with register rmorconst
+uses REG = {ANYCON,0}
+  gen cmp %1,%2
+      je  {label,2f}
+      jb  {label,1f}
+      inc %a
+      jmp {label,2f}
+      1: dec %a
+      2:			    yields %a
+with rmorconst register
+uses REG = {ANYCON,0}
+  gen cmp %2,%1
+      je  {label,2f}
+      ja  {label,1f}
+      inc %a
+      jmp {label,2f}
+      1: dec %a
+      2:			    yields %a
+
+proc txx
+with rm
+uses GENREG = {ANYCON,0}
+  gen test %1
+      setxx* %a.1		    yields %a
+
+pat tlt call txx("sets")
+pat teq call txx("sete")
+pat tne call txx("setne")
+pat tge call txx("setns")
+
+/* Explicit test for TLE and TGT. We must make sure that the OC
+   flag is cleared.
+*/
+pat tle
+with rm
+uses GENREG = {ANYCON,0}
+  gen
+      killcc.
+      test %1
+      setle %a.1
+				   yields %a
+
+pat tgt
+with rm
+uses GENREG = {ANYCON,0}
+  gen
+      killcc.
+      test %1
+      setg %a.1
+				   yields %a
+
+proc txxior
+with rm REG
+  gen test %1
+      jxx* {label,1f}
+      or  %2,{ANYCON,1}
+      1:			    yields %2
+
+pat tlt ior $2==4 call txxior("jge")
+pat tle ior $2==4 call txxior("jg")
+pat teq ior $2==4 call txxior("jne")
+pat tne ior $2==4 call txxior("je")
+pat tge ior $2==4 call txxior("jl")
+pat tgt ior $2==4 call txxior("jle")
+
+proc cmixxior
+with regorconst rm REG
+  gen cmp %2,%1
+      jxx* {label,1f}
+      or  %3,{ANYCON,1}
+      1:			    yields %3
+
+pat cmi tlt ior $1==4 && $3==4 call cmixxior("jge")
+pat cmi tle ior $1==4 && $3==4 call cmixxior("jg")
+pat cmi teq ior $1==4 && $3==4 call cmixxior("jne")
+pat cmi tne ior $1==4 && $3==4 call cmixxior("je")
+pat cmi tge ior $1==4 && $3==4 call cmixxior("jl")
+pat cmi tgt ior $1==4 && $3==4 call cmixxior("jle")
+
+proc cmxtxx
+with regorconst rm
+uses REG = {ANYCON,0}
+  gen cmp %2,%1
+      jxx[1] {label,1f}
+      inc %a
+      1:			    yields %a
+with rm regorconst
+uses REG = {ANYCON,0}
+  gen cmp %1,%2
+      jxx[2] {label,1f}
+      inc %a
+      1:			    yields %a
+
+pat cmi tlt $1==4     call cmxtxx("jge","jle")
+pat cmi tle $1==4     call cmxtxx("jg","jl")
+pat cmi teq $1==4     call cmxtxx("jne","jne")
+pat cmi tne $1==4     call cmxtxx("je","je")
+pat cmi tge $1==4     call cmxtxx("jl","jg")
+pat cmi tgt $1==4     call cmxtxx("jle","jge")
+pat cmp tlt	      call cmxtxx("jae","jbe")
+pat cmp tle	      call cmxtxx("ja","jb")
+pat cmp teq	      call cmxtxx("jne","jne")
+pat cmp tne	      call cmxtxx("je","je")
+pat cmp tge	      call cmxtxx("jb","ja")
+pat cmp tgt	      call cmxtxx("jbe","jae")
+pat cms teq $1==4     call cmxtxx("jne","jne")
+pat cms tne $1==4     call cmxtxx("je","je")
+
+proc cmxzxx example cmp zlt
+with regorconst rm STACK
+  gen cmp %2,%1
+      jxx[1] {label,$2}
+with rm regorconst STACK
+  gen cmp %1,%2
+      jxx[2] {label,$2}
+
+pat cmp zlt	    call cmxzxx("jb","ja")
+pat cmp zle	    call cmxzxx("jbe","jae")
+pat cmp zeq	    call cmxzxx("je","je")
+pat cmp zne	    call cmxzxx("jne","jne")
+pat cmp zge	    call cmxzxx("jae","jbe")
+pat cmp zgt	    call cmxzxx("ja","jb")
+pat cms zeq $1==4   call cmxzxx("je","je")
+pat cms zne $1==4   call cmxzxx("jne","jne")
+
+proc cmx8txxn example cmi tgt
+with GENREG REG rmorconst rmorconst
+  /* can't use 5th REG */
+  gen sub %1,%3
+      sbb %2,%4
+      setxx* %2.1
+      movzxb %2,%2.1		yields %2
+proc cmx8txxy example cmi tlt
+with rmorconst rmorconst GENREG REG
+  gen sub %3,%1
+      sbb %4,%2
+      setxx* %4.1
+      movzxb %4,%4.1		yields %4
+
+pat cmi tlt $1==8	call cmx8txxy("setl")
+pat cmi tle $1==8	call cmx8txxn("setge")
+pat cmi tge $1==8	call cmx8txxy("setge")
+pat cmi tgt $1==8	call cmx8txxn("setl")
+pat cmu tlt $1==8	call cmx8txxy("setb")
+pat cmu tle $1==8	call cmx8txxn("setae")
+pat cmu tge $1==8	call cmx8txxy("setae")
+pat cmu tgt $1==8	call cmx8txxn("setb")
+
+proc cmx8zxxn example cmi zgt
+with REG REG rmorconst rmorconst STACK
+  gen sub %1,%3
+      sbb %2,%4
+      jxx* {label,$2}
+proc cmx8zxxy example cmi zlt
+with rmorconst rmorconst REG REG STACK
+  gen sub %3,%1
+      sbb %4,%2
+      jxx* {label,$2}
+
+pat cmi zlt $1==8	call cmx8zxxy("jl")
+pat cmi zle $1==8	call cmx8zxxn("jge")
+pat cmi zge $1==8	call cmx8zxxy("jge")
+pat cmi zgt $1==8	call cmx8zxxn("jl")
+pat cmu zlt $1==8	call cmx8zxxy("jb")
+pat cmu zle $1==8	call cmx8zxxn("jae")
+pat cmu zge $1==8	call cmx8zxxy("jae")
+pat cmu zgt $1==8	call cmx8zxxn("jb")
+
+pat cms zne $1==8
+with regorconst regorconst rm rm STACK
+  gen cmp %3,%1
+      jne {label,$2}
+      cmp %4,%2
+      jne {label,$2}
+with rm rm regorconst regorconst STACK
+kills ALL
+  gen cmp %1,%3
+      jne {label,$2}
+      cmp %2,%4
+      jne {label,$2}
+
+pat cms zeq $1==8
+with regorconst regorconst rm rm STACK
+  gen cmp %3,%1
+      jne {label, 1f}
+      cmp %4,%2
+      je {label,$2}
+      1:
+with rm rm regorconst regorconst STACK
+kills ALL
+  gen cmp %1,%3
+      jne {label,1f}
+      cmp %2,%4
+      je {label,$2}
+      1:
+
+proc andzxx example and zeq
+with regorconst rm STACK
+  gen check %2,%1
+      jxx* {label,$2}
+with exact rm regorconst
+  kills ALL
+  gen check %1,%2
+      jxx* {label,$2}
+
+pat and zeq $1==4 call andzxx("je")
+pat and zne $1==4 call andzxx("jne")
+
+proc locandzxx example loc and zeq
+with rm1 STACK
+  gen testb %1,{ANYCON,$1}
+      jxx* {label,$3}
+with GENREG STACK
+  gen testb %1.1,{ANYCON,$1}
+      jxx* {label,$3}
+with exact RREG
+  kills ALL
+  gen check %1,{ANYCON,$1}
+      jxx* {label,$3}
+
+pat loc and zeq $1<256 && $1>=0 && $2==4 call locandzxx("je")
+pat loc and zne $1<256 && $1>=0 && $2==4 call locandzxx("jne")
+
+proc locbxx example loc beq
+with rm1 STACK
+  gen cmpb %1,{ANYCON,$1}
+      jxx* {label,$2}
+with rm STACK
+  gen cmp %1,{ANYCON,$1}
+      jxx* {label,$2}
+
+pat loc beq $1<256 && $1>=0 call locbxx("je")
+pat loc bne $1<256 && $1>=0 call locbxx("jne")
+
+proc loccmuzxx example loc cmu zeq
+with rm1 STACK
+  gen cmpb %1,{ANYCON,$1}
+      jxx* {label,$3}
+with rm STACK
+  gen cmp %1,{ANYCON,$1}
+      jxx* {label,$3}
+
+pat loc cmu zeq $1<256 && $1>=0 && $2==4 call loccmuzxx("je")
+pat loc cmu zne $1<256 && $1>=0 && $2==4 call loccmuzxx("jne")
+
+/*******************************************************************
+ *  Group 13 : Branch Instructions				   *
+ *******************************************************************/
+
+pat lab topeltsize($1)==4 && !fallthrough($1)
+  with STACK
+  kills ALL
+  gen labeldef $1                 yields eax
+
+pat lab topeltsize($1)==4 && fallthrough($1)
+  with ACC STACK
+  kills ALL
+  gen labeldef $1                 yields eax
+
+pat lab topeltsize($1)!=4
+  with STACK
+  kills ALL
+  gen labeldef $1
+
+pat bra topeltsize($1)==4
+  with ACC STACK
+  gen jmp {label,$1}
+
+pat bra topeltsize($1)!=4
+  with STACK
+  gen jmp {label,$1}
+
+proc bxx example blt
+with regorconst rm STACK
+  gen cmp %2,%1
+      jxx[1] {label,$1}
+with rm regorconst STACK
+  gen cmp %1,%2
+      jxx[2] {label,$1}
+
+pat blt		call bxx("jl","jg")
+pat ble		call bxx("jle","jge")
+pat beq		call bxx("je","je")
+pat bne		call bxx("jne","jne")
+pat bge		call bxx("jge","jle")
+pat bgt		call bxx("jg","jl")
+
+proc zxx example zlt
+with rm STACK
+  gen test %1
+      jxx* {label,$1}
+
+pat zlt		call zxx("js")
+pat zge		call zxx("jns")
+
+/* Explicit test for ZLE and ZGT. We must make sure that the OC
+   flag is cleared.
+*/
+pat zle
+with rm STACK
+  gen 
+      killcc.
+      test %1
+      jle {label,$1}
+
+pat zgt
+with rm STACK
+  gen
+      killcc.
+      test %1
+      jg {label, $1}
+
+pat zne
+with rm+rm1 STACK
+  gen test %1
+      jne {label,$1}
+
+pat zeq
+with rm+rm1 STACK
+  gen test %1
+      je {label,$1}
+
+/*******************************************************************
+ *  Group 14 : Procedure-call Instructions			   *
+ *******************************************************************/
+
+pat cal
+  kills ALL
+  gen proccall {label,$1}
+
+pat cai
+  with rm
+  kills ALL
+  gen proccall %1
+
+#ifdef REGVARS
+pat lfr adi stl $1==4 && $2==4 && inreg($3) > 0
+  kills ALL
+  gen pop {LOCAL,$3,4}
+      add {LOCAL,$3,4}, eax
+#endif
+
+pat lfr $1==4			yields eax
+
+pat lfr $1==8			yields edx eax
+
+pat ret $1==0
+  kills ALL
+  gen
+#ifdef REGVARS
+	return
+#else
+      leave.
+      ret.
+#endif
+
+pat ret $1==4
+  with ACC
+  kills ALL
+  gen
+#ifdef REGVARS
+	return
+#else
+      leave.
+      ret.
+#endif
+
+pat ret $1==8
+  with ACC DXREG
+  kills ALL
+  gen
+#ifdef REGVARS
+	return
+#else
+      leave.
+      ret.
+#endif
+
+/********************************************************************
+ *  Group 15 : Miscellaneous Instructions			    *
+ ********************************************************************/
+
+pat asp $1==4
+with exact a_word
+with STACK
+  uses CXREG /* GENREG may contain lfr area */
+  gen pop %a
+
+pat asp $1==8
+with exact a_word a_word
+with STACK
+  uses CXREG /* GENREG may contain lfr area */
+  gen pop %a
+      pop %a
+
+pat asp $1==0-4
+with STACK					yields ebp
+
+pat asp
+with STACK
+  gen add esp,{ANYCON,$1}
+
+pat ass $1==4
+with rmorconst STACK
+  gen add esp,%1
+
+pat ass !defined($1)
+with rm rmorconst STACK
+  gen cmp %1,{ANYCON,4}
+      jne {label, ".unknown"}
+      add esp,%2
+
+pat blm $1==0					leaving asp 4
+
+pat blm $1>0
+kills ALL
+  gen mov ecx,{ANYCON,$1/4}
+      proccall {label, ".blm"}
+
+pat bls $1==4
+with CXREG
+kills ALL
+  gen sar ecx,{ANYCON,2}
+      proccall {label, ".blm"}
+
+pat bls !defined($1)
+with rm-CXREG CXREG
+kills ALL
+  gen cmp %1,{ANYCON,4}
+      jne {label, ".unknown"}
+      sar ecx,{ANYCON,2}
+      proccall {label, ".blm"}
+
+pat csa $1==4
+with BXREG ACC
+kills ALL
+  gen jmp {label, ".csa4"}
+
+pat csa $1==8
+with BXREG ACC DXREG
+kills ALL
+  gen jmp {label, ".csa8"}
+
+pat csa !defined($1)
+with rm-BXREG-ACC BXREG ACC
+kills ALL
+  gen cmp %1,{ANYCON,4}
+      jne {label, ".unknown"}
+      jmp {label, ".csa4"}
+
+pat csb $1==4
+with BXREG ACC
+kills ALL
+  gen jmp {label, ".csb4"}
+
+pat csb $1==8
+with BXREG ACC DXREG
+kills ALL
+  gen jmp {label, ".csb8"}
+
+pat csb !defined($1)
+with rm-BXREG-ACC BXREG ACC
+  gen cmp %1,{ANYCON,4}
+      jne {label, ".unknown"}
+      jmp {label, ".csb4"}
+
+pat dup $1==4
+with anyreg				yields %1 %1
+with ACC1				yields %1 %1
+
+pat dup $1==8
+with regorconst regorconst		yields %2 %1 %2 %1
+
+pat dup
+kills ALL
+  gen mov ecx,{ANYCON,$1}
+      proccall {label, ".dup"}
+
+pat dus $1==4
+with CXREG
+kills ALL
+  gen proccall {label, ".dup"}
+
+pat dus !defined($1)
+with rm-CXREG CXREG
+kills ALL
+  gen cmp %1,{ANYCON,4}
+      jne {label, ".unknown"}
+      proccall {label, ".dup"}
+
+pat exg $1==4
+with a_word a_word			yields %1 %2
+
+pat exg $1==8
+with a_word a_word a_word a_word	yields %2 %1 %4 %3
+
+pat exg defined($1)
+kills ALL
+  gen mov ecx,{ANYCON,$1}
+      proccall {label, ".exg"}
+
+pat exg
+with CXREG
+  kills ALL
+  gen proccall {label, ".exg"}
+
+pat gto
+kills ALL
+  gen mov ebx,{ADDR_EXTERN,$1}
+      jmp {label, ".gto"}
+
+pat fil
+  gen mov {EXTERN,"hol0+4"},{ADDR_EXTERN,$1}
+
+pat lim
+  uses REG
+  gen mov %a,{EXTERN,".ignmask"}	yields %a
+
+pat lin
+  gen mov {EXTERN,"hol0"},{ANYCON,$1}
+
+pat lni
+  gen inc {EXTERN,"hol0"}
+
+pat lor $1==0				yields ebp
+
+pat lor $1==1
+with STACK
+  uses REG
+  gen mov %a,esp			yields %a
+
+pat lor $1==2
+  uses REG
+  gen mov %a,{EXTERN,".reghp"}		yields %a
+
+pat mon
+with ACC
+kills ALL
+  gen proccall {label, ".mon"}
+
+pat nop
+kills ALL
+#ifdef DEBUG
+  gen proccall {label, ".nop"}
+#endif
+
+pat rck $1==4
+with BXREG ACC
+kills ALL
+  gen proccall {label, ".rck"}		yields eax
+
+pat rck !defined($1)
+with rm-BXREG-ACC BXREG ACC
+kills ALL
+  gen cmp %1,{ANYCON,4}
+      jne {label, ".unknown"}
+      proccall {label, ".rck"}		yields eax
+
+pat rtt						leaving ret 0
+
+pat sig
+with REG
+  gen xchg {EXTERN,".trppc"},%1		yields %1
+
+pat sim
+with regorconst
+  gen mov {EXTERN,".ignmask"},%1
+
+pat str $1==0
+with rmorconst
+  gen mov ebp,%1
+
+pat str $1==1
+with rmorconst STACK
+  gen mov esp,%1
+
+pat str $1==2
+kills ALL
+  gen proccall {label, ".strhp"}
+
+pat trp
+with ACC
+kills ALL
+  gen proccall {label, ".Xtrp"}
diff --git a/plat/pc65oo2/README b/plat/pc65oo2/README
new file mode 100644
index 000000000..dcbe0ba27
--- /dev/null
+++ b/plat/pc65oo2/README
@@ -0,0 +1,40 @@
+# $Source$
+# $State$
+# $Revision$
+
+
+The pc86 platform
+=================
+
+pc86 is an i86-based BSP that produces bootable floppy disk images that can
+be run on most PCs. It is intended to be quick and dirty rather than actually
+useful, although it may come in handy for hardware test purposes, boot
+loaders, and the like.
+
+The code runs in TINY mode, where CS, DS and SS all share the same segment.
+This means that there's not very much memory available. It would be very easy
+to change it to run in SMALL mode, where CS occupies one segment and DS and SS
+another, which would give 64kB for nearly all programs; I just haven't done it.
+
+IEEE floating point is available, but requires an FPU.
+
+This port only implements a very limited set of syscalls --- and most of those
+are stubs required to make the demo apps link. File descriptors 0, 1 and 2
+represent the console. All reads block. There's enough TTY emulation to allow
+\n conversion and local echo (but it can't be turned off).
+
+Console output is echoed to the serial port (without any setup). This is used
+by qemu for running tests.
+
+
+Example command line
+====================
+
+ack -mpc86 -O -o pc86.img examples/paranoia.c
+
+The file pc86.img can then be copied onto a floppy and booted, or run via qemu
+or somesuch emulator.
+
+
+David Given
+dg@cowlark.com
diff --git a/plat/pc65oo2/boot.s b/plat/pc65oo2/boot.s
new file mode 100644
index 000000000..e3f9eb00b
--- /dev/null
+++ b/plat/pc65oo2/boot.s
@@ -0,0 +1,338 @@
+#
+! $Source$
+! $State$
+! $Revision$
+
+! Declare segments (the order is important).
+
+.sect .text
+.sect .rom
+.sect .data
+.sect .bss
+
+.sect .text
+
+! Some definitions.
+
+BOOT_SEGMENT = 0x07C0        ! Where we've been loaded
+
+#define PRINT(N) push ax; push bx; movb ah, 0x0E; movb al, N; mov bx, 0x0007; int 0x10; pop bx; pop ax
+
+begtext:
+	! This code makes up the PC boot sector, and is the first thing on the
+	! floppy disk. The PC will load this sector to 0x07C0:0000 and jump to it
+	! with dl set to our drive, but it won't necessarily do it in a sane way
+	! (some BIOSes jump to 0x0000:7C00 instead). So, we need to fix that.
+
+	jmpf BOOT_SEGMENT : start2
+start2:
+	! Set up the segment descriptors. We're running in tiny mode, so it's just
+	! a matter of copying the contents of cs (already been set up by the jmpf)
+	! into the other registers.
+
+	mov ax, cs
+	mov ds, ax
+	mov ss, ax
+	! Defer setting es until after probing the drive.
+	
+	! Initialise the stack, which will start at the top of our segment and work
+	! down.
+	
+	mov sp, 0 ! the first push will wrap round to 0xFFFF
+	
+	! Some more startup housekeeping.
+	
+	sti
+	cld
+
+	! We're now set up for actual code. Write out our banner. Remember that
+	! at this point dl contains our drive number, which we want to keep.
+
+	mov si, banner_msg
+	call write_string
+
+	! Probe the drive to figure out its geometry.
+	! This might clobber es.
+	
+	push dx
+	mov ax, 0x0800           ! service number
+	int 0x13
+	mov ax, cs               ! restore es
+	mov es, ax
+	pop ax
+	jc cant_boot
+	
+	! At this point:
+	!   al: current drive
+	!   cl: maximum sector number (bottom six bits)
+	!   dh: maximum head number
+	! We don't care about the rest.
+	andb cl, 0x3F
+	
+	! We now need to go through a loop loading each sector in turn.
+	! During this loop, the registers will be set up as follows:
+	!   al: current cylinder
+	!   ah: maximum head
+	!   bx: address
+	!   cl: current sector (one based)
+	!   ch: maximum sector (one based)
+	!   dl: current drive
+	!   dh: current head
+	! Why, yes, they are painstakingly shoehorned in to get all the data
+	! into registers.
+	
+	movb dl, al
+	movb ch, cl
+	movb ah, dh
+	movb al, 0                ! start on cylinder 0
+	mov bx, 0x0200           ! don't overwrite boot sector
+	movb cl, 2                ! start on sector 2 (skip boot sector)
+	movb dh, 0                ! start on head 0
+	
+1:
+	call read_sector
+	
+	! Next memory area.
+	
+	add bx, 0x0200
+	cmp bx, enddata
+	ja finished
+	
+	! Next sector.
+	
+	incb cl
+	cmpb cl, ch
+	jle 1b
+	movb cl, 1               ! back to sector 1 again
+	
+	! Next head.
+	
+	incb dh
+	cmpb dh, ah
+	jle 1b
+	movb dh, 0               ! back to head 1 again
+	
+	! Next cylinder.
+	
+	incb al
+	jmp 1b
+	
+cant_boot:
+	mov si, bootfail_msg
+	call write_string
+	jmp EXIT
+
+	! Reads a sector into memory. The parameters are:
+	!   al: cylinder
+	!   bx: address
+	!   cl: sector
+	!   dl: drive
+	!   dh: head
+	! If an error occurs, it'll automatically try again. And again.
+	! And again...
+	
+read_sector:
+	push ax
+	push bx
+	push cx
+	push dx
+	
+#if 0
+	push dx
+	xorb dh, dh
+	movb dl, cl
+	call write_hex4
+	pop dx
+	PRINT(0x20)
+	push dx
+	movb dl, dh
+	xorb dh, dh
+	call write_hex4
+	pop dx
+	PRINT(0x20)
+	push dx
+	movb dl, al
+	xorb dh, dh
+	call write_hex4
+	pop dx
+#endif
+	
+1:
+	movb ch, al
+	mov ax, 0x0201           ! service 2, read one sector
+	int 0x13
+	jc 2f
+	
+	mov ax, 0x0E2E           ! write out a .
+	mov bx, 0x0007           ! page 0, white
+	int 0x10
+	
+	pop dx
+	pop cx
+	pop bx
+	pop ax
+	ret
+
+	! If a read fail occurs, the spec (such as it is) states that we need
+	! to reset the fd controller and try again.
+2:
+	push ax
+	push bx
+	
+	mov ax, 0x0E21           ! write out a !
+	mov bx, 0x0007           ! page 0, white
+	int 0x10
+	
+	mov ax, 0x0000
+	int 0x13
+	
+	pop bx
+	pop ax
+	jmp 1b
+
+	! Waits for a keystroke (and then discards it).
+	
+pause:
+	push ax
+	xorb ah, ah
+	int 0x16
+	pop ax
+	ret
+	
+	! This utility writes the string pointed to by ds:si out to the console.
+
+write_string:
+	push ax
+	push bx
+1:
+	lodsb
+	andb al, al
+	jz 2f
+	movb ah, 0xE   ! service
+	mov bx, 0x0007 ! page 0, white
+	int 0x10
+	jmp 1b
+2:
+	pop bx
+	pop ax
+	ret
+	
+	! Writes out the contents of dx as hex.
+
+write_hex4:
+	push ax
+	push cx
+	mov cx, 4      ! 4 hex digits
+1:
+	rol	dx, 1       ! rotate so that highest 4 bits are at the bottom
+	rol dx, 1
+	rol dx, 1
+	rol dx, 1
+	mov	ax, 0xE0F	! ah = request, al = mask for nybble
+	andb al, dl
+	addb al, 0x90	! convert al to ascii hex (four instructions)
+	daa
+	adcb al, 0x40
+	daa
+	int	0x10
+	loop 1b
+	pop cx
+	pop ax
+	ret
+
+	! Everything loaded successfully!
+	!
+	! We now need to do some setup and start the program itself.
+		
+finished:
+	mov si, running_msg
+	call write_string
+	
+	! Wipe the bss. (I'm a little suprised that __m_a_i_n doesn't do this.)
+	
+	mov di, begbss
+	mov cx, endbss
+	sub cx, di
+	mov ax, 0
+	rep stosb
+	
+	! Push standard parameters onto the stack and go.
+	
+	mov ax, envp
+	push ax
+	mov ax, argv
+	push ax
+	mov ax, 1
+	push ax
+	call __m_a_i_n
+	! fall through into the exit routine.
+	
+	! Halts, waits for a keypress, and reboots. This also becomes the
+	! application termination routine.
+	
+.define __exit
+.extern __exit
+.define EXIT
+.extern EXIT
+__exit:
+EXIT:
+	mov si, halted_msg
+	call write_string
+	
+1:
+	jmp 1b
+	
+	xor ax, ax
+	int 0x16 ! get key
+	int 0x19 ! reboot
+
+	! Some text messages.
+	
+banner_msg: .asciz 'ACKBOOT\n\r'
+nl_msg = banner_msg + 7 ! cheap trick
+
+bootfail_msg: .asciz 'Unable to boot!\n\r'
+loading_msg: .asciz '\n\rLoading...\n\r'
+halted_msg: .asciz '\n\rHalted.\n\r'
+running_msg: .asciz '\n\rRunning.\n\r'
+ 
+ 	! The argv and env arrays.
+ 
+argv: .data2 exename, 0
+envp: .data2 0
+exename: .asciz 'pc86.img'
+
+	! A degenerate "hard disk partition table" covering this boot
+	! sector (possibly needed if booting from a USB drive).
+
+	.seek 0x1BE
+	.data1 0x80		! boot indicator (0x80 = active)
+	.data1 0x00		! partition start head
+	.data1 0x01		! partition start sector and start track high
+	.data1 0x00		! partition start track low
+	.data1 0x7F		! OS or filesystem indicator
+	.data1 0xFF		! partition end head
+	.data1 0xFF		! partition end sector and end track high
+	.data1 0xFF		! partition end track low
+	.data4 0		! partition start LBA
+	.data4 0xFFFFFFFF	! length of partition in sectors
+
+	! ...and we need this to fool the PC into booting our boot sector.
+
+	.seek 0x1FE
+	.data2 0xAA55
+
+! Define symbols at the beginning of our various segments, so that we can find
+! them. (Except .text, which has already been done.)
+
+.define begtext, begdata, begbss
+.sect .data;       begdata:
+.sect .rom;        begrom:
+.sect .bss;        begbss:
+
+! Some magic data. All EM systems need these.
+
+.define .trppc, .ignmask, _errno
+.comm .trppc, 4
+.comm .ignmask, 4
+.comm _errno, 4
diff --git a/plat/pc65oo2/build-pkg.lua b/plat/pc65oo2/build-pkg.lua
new file mode 100644
index 000000000..0909d21dd
--- /dev/null
+++ b/plat/pc65oo2/build-pkg.lua
@@ -0,0 +1,25 @@
+include("plat/build.lua")
+
+ackfile {
+	name = "boot",
+	srcs = { "./boot.s" },
+	vars = { plat = "pc65oo2" }
+}
+
+build_plat_libs {
+	name = "libs",
+	arch = "m65oo2",
+	plat = "pc65oo2",
+}
+
+installable {
+	name = "pkg",
+	map = {
+		"+tools",
+		"+libs",
+        "./include+pkg",
+		["$(PLATIND)/pc65oo2/boot.o"] = "+boot",
+        ["$(PLATIND)/pc65oo2/libsys.a"] = "./libsys+lib",
+	}
+}
+
diff --git a/plat/pc65oo2/build-tools.lua b/plat/pc65oo2/build-tools.lua
new file mode 100644
index 000000000..53f34e8b3
--- /dev/null
+++ b/plat/pc65oo2/build-tools.lua
@@ -0,0 +1,21 @@
+include("plat/build.lua")
+
+build_as {
+	name = "as",
+	arch = "m65oo2",
+}
+
+build_ncg {
+	name = "ncg",
+	arch = "m65oo2",
+}
+
+return installable {
+	name = "tools",
+	map = {
+		["$(PLATDEP)/pc65oo2/as"] = "+as",
+		["$(PLATDEP)/pc65oo2/ncg"] = "+ncg",
+		["$(PLATIND)/descr/pc65oo2"] = "./descr",
+		"util/opt+pkg",
+	}
+}
diff --git a/plat/pc65oo2/descr b/plat/pc65oo2/descr
new file mode 100644
index 000000000..5bbe0b68b
--- /dev/null
+++ b/plat/pc65oo2/descr
@@ -0,0 +1,80 @@
+# $Source$
+# $State$
+# $Revision$
+
+var w=4
+var wa=4
+var p=4
+var pa=2
+var s=2
+var sa=2
+var l=4
+var la=2
+var f=4
+var fa=2
+var d=8
+var da=2
+var x=8
+var xa=2
+var ARCH=m65oo2
+var PLATFORM=pc65oo2
+var PLATFORMDIR={EM}/share/ack/{PLATFORM}
+var CPP_F=-D__unix
+var ALIGN=-a0:2 -a1:2 -a2:2 -a3:2
+var MACHOPT_F=-m8
+var EGO_PLAT_FLAGS=-M{EM}/share/ack/ego/{ARCH}.descr
+
+# Override the setting in fe so that files compiled for this platform can see
+# the platform-specific headers.
+
+var C_INCLUDES=-I{PLATFORMDIR}/include -I{EM}/share/ack/include/ansi
+
+name be
+	from .m.g
+	to .s
+	program {EM}/lib/ack/{PLATFORM}/ncg
+	args <
+	stdout
+	need .e
+end
+name as
+	from .s.so
+	to .o
+	program {EM}/lib/ack/{PLATFORM}/as
+	args - -o > <
+	prep cond
+end
+name led
+	from .o.a
+	to .out
+	program {EM}/lib/ack/em_led
+	mapflag -l* LNAME={PLATFORMDIR}/lib*
+	mapflag -i SEPID=-b1:0
+	mapflag -fp FLOATS={EM}/{ILIB}fp
+	args {ALIGN} {SEPID?} \
+		({RTS}:.b=-u _i_main) \
+	    (.e:{HEAD}={PLATFORMDIR}/boot.o) \
+		({RTS}:.ocm.bas.b={PLATFORMDIR}/c-ansi.o) \
+		({RTS}:.c={PLATFORMDIR}/c-ansi.o) \
+		({RTS}:.mod={PLATFORMDIR}/modula2.o) \
+		({RTS}:.p={PLATFORMDIR}/pascal.o) \
+		-o > < \
+		(.p:{TAIL}={PLATFORMDIR}/libpascal.a) \
+		(.b:{TAIL}={PLATFORMDIR}/libb.a) \
+		(.bas:{TAIL}={PLATFORMDIR}/libbasic.a) \
+		(.mod:{TAIL}={PLATFORMDIR}/libmodula2.a) \
+		(.ocm:{TAIL}={PLATFORMDIR}/liboccam.a) \
+		(.ocm.bas.mod.b.c.p:{TAIL}={PLATFORMDIR}/libc.a) \
+		{FLOATS?} \
+		(.e:{TAIL}={PLATFORMDIR}/libem.a \
+		           {PLATFORMDIR}/libsys.a \
+		           {PLATFORMDIR}/libend.a)
+	linker
+end
+name cv
+	from .out
+	to .img
+	program {EM}/bin/aslod
+	args < >
+	outfile pc86.img
+end
diff --git a/plat/pc65oo2/emu/README.md b/plat/pc65oo2/emu/README.md
new file mode 100644
index 000000000..7c12ca68b
--- /dev/null
+++ b/plat/pc65oo2/emu/README.md
@@ -0,0 +1,3 @@
+The x86emu directory contains a modified copy of the xorg 8086 emulation
+library from the X server. It's distributable under the MIT/X11 license,
+and so is compatible with the ACK.
diff --git a/plat/pc65oo2/emu/build.lua b/plat/pc65oo2/emu/build.lua
new file mode 100644
index 000000000..b1c06c9e9
--- /dev/null
+++ b/plat/pc65oo2/emu/build.lua
@@ -0,0 +1,27 @@
+clibrary {
+	name = "x86emu",
+	vars = {
+		["+cflags"] = {"-Iplat/pc65oo2/emu/x86emu", "-DDEBUG"}
+	},
+	srcs = {
+		"./x86emu/debug.c",
+		"./x86emu/decode.c",
+		"./x86emu/fpu.c",
+		"./x86emu/ops2.c",
+		"./x86emu/ops.c",
+		"./x86emu/prim_ops.c",
+		"./x86emu/sys.c",
+	}	
+}
+
+cprogram {
+	name = "pc65oo2emu",
+	srcs = {"./main.c"},
+	vars = {
+		["+cflags"] = {"-Iplat/pc65oo2/emu/x86emu", "-DDEBUG"}
+	},
+	deps = {
+		"+x86emu"
+	}
+}
+
diff --git a/plat/pc65oo2/emu/main.c b/plat/pc65oo2/emu/main.c
new file mode 100644
index 000000000..f5131229b
--- /dev/null
+++ b/plat/pc65oo2/emu/main.c
@@ -0,0 +1,146 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "x86emu.h"
+
+static uint8_t ram[1025*1024];
+static int floppy_fd;
+static X86EMU_intrFuncs intr_funcs[256];
+
+void printk(const char* format, ...)
+{
+	va_list ap;
+	va_start(ap, format);
+	vfprintf(stderr, format, ap);
+	va_end(ap);
+}
+
+static void unknown_interrupt_cb(int num)
+{
+	printk("unknown interrupt 0x%02x\n", num);
+	exit(1);
+}
+
+static void ignored_interrupt_cb(int num)
+{
+	M.x86.R_AX = 0;
+}
+
+static void int10_cb(int num)
+{
+	switch (M.x86.R_AH)
+	{
+		case 0x0e: /* print char al */
+			putchar(M.x86.R_AL);
+			fflush(stdout);
+			break;
+
+		default:
+			printk("unknown int10 service 0x%02x\n", M.x86.R_AH);
+			exit(1);
+	}
+}
+
+static void int13_cb(int num)
+{
+	if (M.x86.R_DL != 0)
+	{
+		/* unknown disk */
+		M.x86.R_AX = 1;
+		return;
+	}
+
+	switch (M.x86.R_AH)
+	{
+		case 0x02: /* read sector */
+		{
+			/* On entry:
+			 *   al: number of sectors
+			 *   bx: address
+			 *   ch: track
+			 *   cl: sector
+			 *   dh: head number
+			 *   dl: disk
+			 */
+			uint8_t count = M.x86.R_AL;
+			uint32_t address = (M.x86.R_DS << 4) + M.x86.R_BX;
+			uint8_t sector = M.x86.R_CL;
+			uint8_t track = M.x86.R_CH;
+			uint8_t head = M.x86.R_DH;
+			uint32_t lba = track*18*2 + head*18 + (sector-1);
+			//printf("CHS %d.%d.%d -> lba 0x%x\n", track, head, sector, lba);
+			pread(floppy_fd, &ram[address], count*512, lba*512);
+			M.x86.R_AX = 0;
+			CLEAR_FLAG(F_CF);
+		}
+
+		case 0x08: /* probe disk al */
+			M.x86.R_AX = 0;
+			M.x86.R_CL = 18; /* maximum sector number */
+			M.x86.R_DH = 1; /* maximum head number */
+			/* there's other stuff we should set as well */
+			break;
+
+		default:
+			printk("unknown int13 service 0x%02x\n", M.x86.R_AH);
+			exit(1);
+	}
+}
+
+int main(int argc, const char* argv[])
+{
+	int i;
+
+	if (argc != 2)
+	{
+		printk("syntax: pc86emu <fdimage.img>\n");
+		exit(1);
+	}
+
+	floppy_fd = open(argv[1], O_RDONLY);
+	if (floppy_fd == -1)
+	{
+		printk("could not open disk image: %s\n", strerror(errno));
+		exit(1);
+	}
+
+	/* Initialise the processor. */
+
+	M.mem_base = (uintptr_t) ram;
+    M.mem_size = sizeof(ram);
+
+	/* Load the boot sector at 0x07c0:0000. */
+
+	for (i=0; i<512; i++)
+	{
+		uint8_t b;
+		read(floppy_fd, &b, 1);
+		wrb(0x7c00 + i, b);
+	}
+
+	/* Initialise. */
+
+	for (i=0; i<256; i++)
+		intr_funcs[i] = unknown_interrupt_cb;
+	intr_funcs[0x10] = int10_cb;
+	intr_funcs[0x13] = int13_cb;
+	intr_funcs[0x14] = ignored_interrupt_cb; /* serial port stuff */
+
+	//M.x86.debug = DEBUG_TRACE_F|DEBUG_STEP_F|DEBUG_DECODE_F;
+	M.x86.debug = 0;
+	M.x86.R_CS = 0x07c0;
+	M.x86.R_IP = 0x0000;
+	M.x86.R_DL = 0; /* boot drive */
+	X86EMU_setupIntrFuncs(intr_funcs);
+	X86EMU_exec();
+
+	return 0;
+}
+
diff --git a/plat/pc65oo2/emu/x86emu/COPYING b/plat/pc65oo2/emu/x86emu/COPYING
new file mode 100644
index 000000000..abf13c2e3
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/COPYING
@@ -0,0 +1,1847 @@
+The following is the 'standard copyright' agreed upon by most contributors,
+and is currently the canonical license preferred by the X.Org Foundation.
+This is a slight variant of the common MIT license form published by the
+Open Source Initiative at http://www.opensource.org/licenses/mit-license.php
+
+Copyright holders of new code should use this license statement where
+possible, and insert their name to this list.  Please sort by surname
+for people, and by the full name for other entities (e.g.  Juliusz
+Chroboczek sorts before Intel Corporation sorts before Daniel Stone).
+
+Copyright © 2011 Dave Airlie
+Copyright © 2000-2001 Juliusz Chroboczek
+Copyright © 1998 Egbert Eich
+Copyright © 2006-2007 Intel Corporation
+Copyright © 2006 Nokia Corporation
+Copyright © 2006-2008 Peter Hutterer
+Copyright © 2006 Adam Jackson
+Copyright © 2009-2010 NVIDIA Corporation
+Copyright © 1987, 2003-2006, 2008-2010 Oracle and/or its affiliates.
+Copyright © 1999 Keith Packard
+Copyright © 2007-2009 Red Hat, Inc.
+Copyright © 2005-2008 Daniel Stone
+Copyright © 2006-2009 Simon Thum
+Copyright © 2003-2008, 2013 Geert Uytterhoeven
+Copyright © 2006 Luc Verhaegen
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+
+
+
+The following licenses are 'legacy': usually MIT/X11 licenses with the name
+of the copyright holder(s) in the license statement, but also some BSD-like
+licenses.
+
+
+Copyright (C) 1994-2003 The XFree86 Project, Inc.  All Rights Reserved.
+Copyright (C) Colin Harrison 2005-2008
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the XFree86 Project shall not
+be used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the XFree86 Project.
+
+
+Copyright 1997 by The XFree86 Project, Inc.
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of the XFree86 Project, Inc.
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.  The Xfree86
+Project, Inc. makes no representations about the suitability of this
+software for any purpose.  It is provided "as is" without express or
+implied warranty.
+
+THE XFREE86 PROJECT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID WEXELBLAT BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 1985-1998, 2001  The Open Group
+Copyright 2002 Red Hat Inc., Durham, North Carolina.
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright (c) 1987, 1989-1990, 1992-1995  X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+Copyright © 1999-2000 SuSE, Inc.
+Copyright © 2007 Red Hat, Inc.
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of SuSE not be used in advertising or
+publicity pertaining to distribution of the software without specific,
+written prior permission.  SuSE makes no representations about the
+suitability of this software for any purpose.  It is provided "as is"
+without express or implied warranty.
+
+SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 1987-1991, 1993 by Digital Equipment Corporation, Maynard, Massachusetts.
+Copyright 1991 Massachusetts Institute of Technology, Cambridge, Massachusetts.
+Copyright 1991, 1993 Olivetti Research Limited, Cambridge, England.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+Copyright 1994 Quarterdeck Office Systems.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Digital and
+Quarterdeck not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+DIGITAL AND QUARTERDECK DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT
+OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
+OR PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 1997 Digital Equipment Corporation.
+All rights reserved.
+
+This software is furnished under license and may be used and copied only in
+accordance with the following terms and conditions.  Subject to these
+conditions, you may download, copy, install, use, modify and distribute
+this software in source and/or binary form. No title or ownership is
+transferred hereby.
+
+1) Any source code used, modified or distributed must reproduce and retain
+   this copyright notice and list of conditions as they appear in the
+   source file.
+
+2) No right is granted to use any trade name, trademark, or logo of Digital
+   Equipment Corporation. Neither the "Digital Equipment Corporation"
+   name nor any trademark or logo of Digital Equipment Corporation may be
+   used to endorse or promote products derived from this software without
+   the prior written permission of Digital Equipment Corporation.
+
+3) This software is provided "AS-IS" and any express or implied warranties,
+   including but not limited to, any implied warranties of merchantability,
+   fitness for a particular purpose, or non-infringement are disclaimed.
+   In no event shall DIGITAL be liable for any damages whatsoever, and in
+   particular, DIGITAL shall not be liable for special, indirect,
+   consequential, or incidental damages or damages for lost profits, loss
+   of revenue or loss of use, whether such damages arise in contract,
+   negligence, tort, under statute, in equity, at law or otherwise, even
+   if advised of the possibility of such damage.
+
+
+Copyright (c) 1991, 1996-1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+
+SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice including the dates of first publication and
+either this permission notice or a reference to
+http://oss.sgi.com/projects/FreeB/
+shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+Copyright (c) 1994, 1995  Hewlett-Packard Company
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the Hewlett-Packard
+Company shall not be used in advertising or otherwise to promote the
+sale, use or other dealings in this Software without prior written
+authorization from the Hewlett-Packard Company.
+
+
+Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+
+Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
+Copyright (c) 2003 by the XFree86 Project, Inc.
+Copyright 2004-2005 Red Hat Inc., Raleigh, North Carolina.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation on the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT.  IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+Copyright © 2008 Red Hat, Inc.
+Partly based on code Copyright © 2000 SuSE, Inc.
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without
+fee, provided that the above copyright notice appear in all copies
+and that both that copyright notice and this permission notice
+appear in supporting documentation, and that the name of Red Hat
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.  Red
+Hat makes no representations about the suitability of this software
+for any purpose.  It is provided "as is" without express or implied
+warranty.
+
+Red Hat DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+NO EVENT SHALL Red Hat BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of SuSE not be used in advertising or
+publicity pertaining to distribution of the software without specific,
+written prior permission.  SuSE makes no representations about the
+suitability of this software for any purpose.  It is provided "as is"
+without express or implied warranty.
+
+SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright © 2006  Red Hat, Inc.
+(C) Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sub license,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
+RED HAT, INC, OR PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
+OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+Copyright (c) 1995  X Consortium
+Copyright 2004 Red Hat Inc., Durham, North Carolina.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation on the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT.  IN NO EVENT SHALL RED HAT, THE X CONSORTIUM,
+AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium
+shall not be used in advertising or otherwise to promote the sale,
+use or other dealings in this Software without prior written
+authorization from the X Consortium.
+
+
+Copyright 1998-2000 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, Inc.
+Copyright (c) 2002, 2008, 2009 Apple Computer, Inc.
+Copyright (c) 2003-2004 Torrey T. Lyons.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+(C) Copyright IBM Corporation 2003
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
+VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+(C) Copyright IBM Corporation 2004-2005
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sub license,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
+IBM,
+AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+Copyright (c) 1997  Metro Link Incorporated
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+Except as contained in this notice, the name of the Metro Link shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from Metro Link.
+
+
+Copyright 1995-1998 by Metro Link, Inc.
+Copyright (c) 1997 Matthieu Herrb
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of Metro Link, Inc. not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission.  Metro Link, Inc. makes no
+representations about the suitability of this software for any purpose.
+ It is provided "as is" without express or implied warranty.
+
+METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 1998 by Metro Link Incorporated
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Metro Link
+Incorporated not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.  Metro Link Incorporated makes no representations
+about the suitability of this software for any purpose.  It is
+provided "as is" without express or implied warranty.
+
+METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED BE
+LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+
+Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+CONECTIVA LINUX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+Except as contained in this notice, the name of Conectiva Linux shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from
+Conectiva Linux.
+
+
+Copyright (c) 2001, Andy Ritger  aritger@nvidia.com
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+o Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+o Redistributions in binary form must reproduce the above copyright
+  notice, this list of conditions and the following disclaimer
+  in the documentation and/or other materials provided with the
+  distribution.
+o Neither the name of NVIDIA nor the names of its contributors
+  may be used to endorse or promote products derived from this
+  software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+
+Copyright 1992 Vrije Universiteit, The Netherlands
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted, provided
+that the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of the Vrije Universiteit not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission.  The Vrije Universiteit makes no
+representations about the suitability of this software for any purpose.
+It is provided "as is" without express or implied warranty.
+
+The Vrije Universiteit DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL The Vrije Universiteit BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 1998 by Concurrent Computer Corporation
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Concurrent Computer
+Corporation not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.  Concurrent Computer Corporation makes no representations
+about the suitability of this software for any purpose.  It is
+provided "as is" without express or implied warranty.
+
+CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE
+LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+
+Copyright © 2004 Nokia
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of Nokia not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission. Nokia makes no
+representations about the suitability of this software for any purpose.  It
+is provided "as is" without express or implied warranty.
+
+NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+
+(c)Copyright 1988,1991 Adobe Systems Incorporated.
+All rights reserved.
+
+Permission to use, copy, modify, distribute, and sublicense this software and its
+documentation for any purpose and without fee is hereby granted, provided that
+the above copyright notices appear in all copies and that both those copyright
+notices and this permission notice appear in supporting documentation and that
+the name of Adobe Systems Incorporated not be used in advertising or publicity
+pertaining to distribution of the software without specific, written prior
+permission.  No trademark license to use the Adobe trademarks is hereby
+granted.  If the Adobe trademark "Display PostScript"(tm) is used to describe
+this software, its functionality or for any other purpose, such use shall be
+limited to a statement that this software works in conjunction with the Display
+PostScript system.  Proper trademark attribution to reflect Adobe's ownership
+of the trademark shall be given whenever any such reference to the Display
+PostScript system is made.
+
+ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR ANY
+PURPOSE.  IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.  ADOBE
+DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-
+INFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO EVENT SHALL ADOBE BE LIABLE TO YOU
+OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,NEGLIGENCE, STRICT
+LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.  ADOBE WILL NOT PROVIDE ANY TRAINING OR OTHER
+SUPPORT FOR THE SOFTWARE.
+
+Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems
+Incorporated which may be registered in certain jurisdictions.
+
+
+Copyright 1989 Network Computing Devices, Inc., Mountain View, California.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted, provided
+that the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of N.C.D. not be used in advertising or
+publicity pertaining to distribution of the software without specific,
+written prior permission.  N.C.D. makes no representations about the
+suitability of this software for any purpose.  It is provided "as is"
+without express or implied warranty.
+
+
+Copyright (c) 1987 by the Regents of the University of California
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies.  The University of California
+makes no representations about the suitability of this
+software for any purpose.  It is provided "as is" without
+express or implied warranty.
+
+
+Copyright 1992, 1993 Data General Corporation;
+Copyright 1992, 1993 OMRON Corporation
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that the
+above copyright notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting documentation, and that
+neither the name OMRON or DATA GENERAL be used in advertising or publicity
+pertaining to distribution of the software without specific, written prior
+permission of the party whose name is to be used.  Neither OMRON or
+DATA GENERAL make any representation about the suitability of this software
+for any purpose.  It is provided "as is" without express or implied warranty.
+
+OMRON AND DATA GENERAL EACH DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+IN NO EVENT SHALL OMRON OR DATA GENERAL BE LIABLE FOR ANY SPECIAL, INDIRECT
+OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+OF THIS SOFTWARE.
+
+
+Copyright © 1998-2004, 2006 Keith Packard
+Copyright © 2000-2002 Keith Packard, member of The XFree86 Project, Inc.
+Copyright (c) 2002 Apple Computer, Inc.
+Copyright (c) 2003 Torrey T. Lyons.
+All Rights Reserved.
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of Keith Packard not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission.  Keith Packard makes no
+representations about the suitability of this software for any purpose.  It
+is provided "as is" without express or implied warranty.
+
+KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright © 1999 Keith Packard
+Copyright © 2000 Compaq Computer Corporation
+Copyright © 2002 MontaVista Software Inc.
+Copyright © 2005 OpenedHand Ltd.
+Copyright © 2006 Nokia Corporation
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of the authors and/or copyright holders
+not be used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  The authors and/or
+copyright holders make no representations about the suitability of this
+software for any purpose.  It is provided "as is" without express or
+implied warranty.
+
+THE AUTHORS AND/OR COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE AUTHORS AND/OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation.  Davor Matic makes no representations about
+the suitability of this software for any purpose.  It is provided "as
+is" without express or implied warranty.
+
+
+Copyright (C) 2001-2004 Harold L Hunt II All Rights Reserved.
+Copyright (C) Colin Harrison 2005-2008
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Harold L Hunt II
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+from Harold L Hunt II.
+
+
+Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of Thomas Roell not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission.  Thomas Roell makes no representations
+about the suitability of this software for any purpose.  It is provided
+"as is" without express or implied warranty.
+
+THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+Copyright 1993 by David Wexelblat <dwex@goblin.org>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the names of Thomas Roell and David Wexelblat
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.  Thomas Roell and
+David Wexelblat makes no representations about the suitability of this
+software for any purpose.  It is provided "as is" without express or
+implied warranty.
+
+THOMAS ROELL AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID WEXELBLAT BE LIABLE FOR
+ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 1990,91,92,93 by Thomas Roell, Germany.
+Copyright 1991,92,93    by SGCS (Snitily Graphics Consulting Services), USA.
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and
+that both that copyright notice and this  permission notice appear
+in supporting documentation, and that the name of Thomas Roell nor
+SGCS be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+Thomas Roell nor SGCS makes no representations about the suitability
+of this software for any purpose. It is provided "as is" without
+express or implied warranty.
+
+THOMAS ROELL AND SGCS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL THOMAS ROELL OR SGCS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 1998 by Alan Hourihane, Wigan, England.
+Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales.
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of Alan Hourihane not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission.  Alan Hourihane makes no representations
+about the suitability of this software for any purpose.  It is provided
+"as is" without express or implied warranty.
+
+ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 1995  Kaleb S. KEITHLEY
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL Kaleb S. KEITHLEY BE LIABLE FOR ANY CLAIM, DAMAGES
+OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Kaleb S. KEITHLEY
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+from Kaleb S. KEITHLEY
+
+
+Copyright (c) 1997 Matthieu Herrb
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of Matthieu Herrb not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission.  Matthieu Herrb makes no
+representations about the suitability of this software for any purpose.
+ It is provided "as is" without express or implied warranty.
+
+MATTHIEU HERRB DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL MATTHIEU HERRB BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 2004, Egbert Eich
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+EGBERT EICH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Egbert Eich shall not
+be used in advertising or otherwise to promote the sale, use or other deal-
+ings in this Software without prior written authorization from Egbert Eich.
+
+
+Copyright 1993 by David Wexelblat <dwex@goblin.org>
+Copyright 2005 by Kean Johnston <jkj@sco.com>
+Copyright 1993 by David McCullough <davidm@stallion.oz.au>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of David Wexelblat not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission.  David Wexelblat makes no representations
+about the suitability of this software for any purpose.  It is provided
+"as is" without express or implied warranty.
+
+DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL DAVID WEXELBLAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 1992 by Orest Zborowski <obz@Kodak.com>
+Copyright 1993 by David Wexelblat <dwex@goblin.org>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the names of Orest Zborowski and David Wexelblat
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.  Orest Zborowski
+and David Wexelblat make no representations about the suitability of this
+software for any purpose.  It is provided "as is" without express or
+implied warranty.
+
+OREST ZBOROWSKI AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID WEXELBLAT BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 1992 by Orest Zborowski <obz@Kodak.com>
+Copyright 1993 by David Dawes <dawes@xfree86.org>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the names of Orest Zborowski and David Dawes
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.  Orest Zborowski
+and David Dawes make no representations about the suitability of this
+software for any purpose.  It is provided "as is" without express or
+implied warranty.
+
+OREST ZBOROWSKI AND DAVID DAWES DISCLAIMS ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID DAWES BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 1995-1999 by Frederic Lepied, France. <fred@sugix.frmug.fr.net>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is  hereby granted without fee, provided that
+the  above copyright   notice appear  in   all  copies and  that both  that
+copyright  notice   and   this  permission   notice  appear  in  supporting
+documentation, and that   the  name of  Frederic   Lepied not  be  used  in
+advertising or publicity pertaining to distribution of the software without
+specific,  written      prior  permission.     Frederic  Lepied   makes  no
+representations about the suitability of this software for any purpose.  It
+is provided "as is" without express or implied warranty.
+
+FREDERIC  LEPIED DISCLAIMS ALL   WARRANTIES WITH REGARD  TO  THIS SOFTWARE,
+INCLUDING ALL IMPLIED   WARRANTIES OF MERCHANTABILITY  AND   FITNESS, IN NO
+EVENT  SHALL FREDERIC  LEPIED BE   LIABLE   FOR ANY  SPECIAL, INDIRECT   OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA  OR PROFITS, WHETHER  IN  AN ACTION OF  CONTRACT,  NEGLIGENCE OR OTHER
+TORTIOUS  ACTION, ARISING    OUT OF OR   IN  CONNECTION  WITH THE USE    OR
+PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 1992 by Rich Murphey <Rich@Rice.edu>
+Copyright 1993 by David Wexelblat <dwex@goblin.org>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the names of Rich Murphey and David Wexelblat
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.  Rich Murphey and
+David Wexelblat make no representations about the suitability of this
+software for any purpose.  It is provided "as is" without express or
+implied warranty.
+
+RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL RICH MURPHEY OR DAVID WEXELBLAT BE LIABLE FOR
+ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 1992 by Rich Murphey <Rich@Rice.edu>
+Copyright 1993 by David Dawes <dawes@xfree86.org>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the names of Rich Murphey and David Dawes
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.  Rich Murphey and
+David Dawes make no representations about the suitability of this
+software for any purpose.  It is provided "as is" without express or
+implied warranty.
+
+RICH MURPHEY AND DAVID DAWES DISCLAIM ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL RICH MURPHEY OR DAVID DAWES BE LIABLE FOR
+ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright © 2003-2004 Anders Carlsson
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of Anders Carlsson not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission.  Anders Carlsson makes no
+representations about the suitability of this software for any purpose.  It
+is provided "as is" without express or implied warranty.
+
+ANDERS CARLSSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL ANDERS CARLSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright (C) 2003 Anders Carlsson
+Copyright © 2003-2004 Eric Anholt
+Copyright © 2004 Keith Packard
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of Eric Anholt not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission.  Eric Anholt makes no
+representations about the suitability of this software for any purpose.  It
+is provided "as is" without express or implied warranty.
+
+ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
+WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
+FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright © 2003-2004 Philip Blundell
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of Philip Blundell not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission.  Philip Blundell makes no
+representations about the suitability of this software for any purpose.  It
+is provided "as is" without express or implied warranty.
+
+PHILIP BLUNDELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL PHILIP BLUNDELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+
+
+Copyright (c) 1994-2003 by The XFree86 Project, Inc.
+Copyright 1997 by Metro Link, Inc.
+Copyright 2003 by David H. Dawes.
+Copyright 2003 by X-Oz Technologies.
+Copyright (c) 2004, X.Org Foundation
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the copyright holder(s)
+and author(s) shall not be used in advertising or otherwise to promote
+the sale, use or other dealings in this Software without prior written
+authorization from the copyright holder(s) and author(s).
+
+
+Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+Copyright 1993 by David Wexelblat <dwex@goblin.org>
+Copyright 1999 by David Holland <davidh@iquest.net>
+Copyright © 2000 Compaq Computer Corporation
+Copyright © 2002 Hewlett-Packard Company
+Copyright © 2004, 2005 Red Hat, Inc.
+Copyright © 2004 Nicholas Miell
+Copyright © 2005 Trolltech AS
+Copyright © 2006 Intel Corporation
+Copyright © 2006-2007 Keith Packard
+Copyright © 2008 Red Hat, Inc
+Copyright © 2008 George Sapountzis <gsap7@yahoo.gr>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting documentation, and
+that the name of the copyright holders not be used in advertising or
+publicity pertaining to distribution of the software without specific,
+written prior permission.  The copyright holders make no representations
+about the suitability of this software for any purpose.  It is provided "as
+is" without express or implied warranty.
+
+THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+
+Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+            2005 Lars Knoll & Zack Rusin, Trolltech
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of Keith Packard not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission.  Keith Packard makes no
+representations about the suitability of this software for any purpose.  It
+is provided "as is" without express or implied warranty.
+
+THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+
+Copyright 1987, 1998  The Open Group
+Copyright © 1998-1999, 2001 The XFree86 Project, Inc.
+Copyright © 2000 VA Linux Systems, Inc.
+Copyright (c) 2000, 2001 Nokia Home Communications
+Copyright © 2007, 2008 Red Hat, Inc.
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies of
+the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
+INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
+FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+of the copyright holder.
+
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE
+LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright (c) 2001 Andreas Monitzer.
+Copyright (c) 2001-2004 Greg Parker.
+Copyright (c) 2001-2004 Torrey T. Lyons
+Copyright (c) 2002-2003 Apple Computer, Inc.
+Copyright (c) 2004-2005 Alexander Gottwald
+Copyright (c) 2002-2009 Apple Inc.
+Copyright (c) 2007 Jeremy Huddleston
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name(s) of the above copyright
+holders shall not be used in advertising or otherwise to promote the sale,
+use or other dealings in this Software without prior written authorization.
+
+
+Copyright (C) 1999,2000 by Eric Sunshine <sunshine@sunshineco.com>
+Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+  1. Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+  2. Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+  3. The name of the author may not be used to endorse or promote products
+     derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+Copyright (C) 2005 Bogdan D. bogdand@users.sourceforge.net
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the author shall not be used in
+advertising or otherwise to promote the sale, use or other dealings in this
+Software without prior written authorization from the author.
+
+
+Copyright © 2002 David Dawes
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+Except as contained in this notice, the name of the author(s) shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from
+the author(s).
+
+
+Copyright (C) 1996-1999 SciTech Software, Inc.
+Copyright (C) David Mosberger-Tang
+Copyright (C) 1999 Egbert Eich
+Copyright (C) 2008 Bart Trojanowski, Symbio Technologies, LLC
+
+Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of the authors not be used
+in advertising or publicity pertaining to distribution of the software
+without specific, written prior permission.  The authors makes no
+representations about the suitability of this software for any purpose.
+It is provided "as is" without express or implied warranty.
+
+THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 2005-2006 Luc Verhaegen.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+
+Copyright 1995 by Robin Cutshaw <robin@XFree86.Org>
+Copyright 2000 by Egbert Eich
+Copyright 2002 by David Dawes
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the names of the above listed copyright holder(s)
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.  The above listed
+copyright holder(s) make(s) no representations about the suitability of this
+software for any purpose.  It is provided "as is" without express or
+implied warranty.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM(S) ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE
+LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 1997-2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting documentation, and
+that the name of Marc Aurele La France not be used in advertising or
+publicity pertaining to distribution of the software without specific,
+written prior permission.  Marc Aurele La France makes no representations
+about the suitability of this software for any purpose.  It is provided
+"as-is" without express or implied warranty.
+
+MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO
+EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+OF THIS SOFTWARE.
+
+
+Copyright 1990, 1991 by Thomas Roell, Dinkelscherben, Germany
+Copyright 1992 by David Dawes <dawes@XFree86.org>
+Copyright 1992 by Jim Tsillas <jtsilla@damon.ccs.northeastern.edu>
+Copyright 1992 by Rich Murphey <Rich@Rice.edu>
+Copyright 1992 by Robert Baron <Robert.Baron@ernst.mach.cs.cmu.edu>
+Copyright 1992 by Orest Zborowski <obz@eskimo.com>
+Copyright 1993 by Vrije Universiteit, The Netherlands
+Copyright 1993 by David Wexelblat <dwex@XFree86.org>
+Copyright 1994, 1996 by Holger Veit <Holger.Veit@gmd.de>
+Copyright 1997 by Takis Psarogiannakopoulos <takis@dpmms.cam.ac.uk>
+Copyright 1994-2003 by The XFree86 Project, Inc
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the names of the above listed copyright holders
+not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.  The above listed
+copyright holders make no representations about the suitability of this
+software for any purpose.  It is provided "as is" without express or
+implied warranty.
+
+THE ABOVE LISTED COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDERS BE
+LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright 2001-2005 by J. Kean Johnston <jkj@sco.com>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name J. Kean Johnston not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission.  J. Kean Johnston makes no
+representations about the suitability of this software for any purpose.
+It is provided "as is" without express or implied warranty.
+
+J. KEAN JOHNSTON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL J. KEAN JOHNSTON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+Copyright 1997,1998 by UCHIYAMA Yasushi
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of UCHIYAMA Yasushi not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission.  UCHIYAMA Yasushi makes no representations
+about the suitability of this software for any purpose.  It is provided
+"as is" without express or implied warranty.
+
+UCHIYAMA YASUSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL UCHIYAMA YASUSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright (C) 2000 Keith Packard
+              2004 Eric Anholt
+              2005 Zack Rusin
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of copyright holders not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission. Copyright holders make no
+representations about the suitability of this software for any purpose.  It
+is provided "as is" without express or implied warranty.
+
+THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+
+(C) Copyright IBM Corporation 2002-2007
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
+THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+this permission notice appear in supporting documentation.  This permission
+notice shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+Copyright © 2007 OpenedHand Ltd
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of OpenedHand Ltd not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission. OpenedHand Ltd makes no
+representations about the suitability of this software for any purpose.  It
+is provided "as is" without express or implied warranty.
+
+OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+
+Copyright (c) 1987, 1990, 1993
+     The Regents of the University of California.  All rights reserved.
+
+This code is derived from software contributed to Berkeley by
+Chris Torek.
+
+This code is derived from software contributed to Berkeley by
+Michael Rendell of Memorial University of Newfoundland.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+ 4. Neither the name of the University nor the names of its contributors
+    may be used to endorse or promote products derived from this software
+    without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/plat/pc65oo2/emu/x86emu/Makefile.am b/plat/pc65oo2/emu/x86emu/Makefile.am
new file mode 100644
index 000000000..2a55d6353
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/Makefile.am
@@ -0,0 +1,29 @@
+if INT10_X86EMU
+noinst_LTLIBRARIES = libx86emu.la
+endif
+
+libx86emu_la_SOURCES = debug.c \
+                      decode.c \
+                      fpu.c \
+                      ops2.c \
+                      ops.c \
+                      prim_ops.c \
+                      sys.c \
+                      x86emu.h
+
+AM_CPPFLAGS = 
+
+AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS)
+
+EXTRA_DIST = validate.c \
+             x86emu/debug.h \
+             x86emu/decode.h \
+             x86emu/fpu.h \
+             x86emu/fpu_regs.h \
+             x86emu/ops.h \
+             x86emu/prim_asm.h \
+             x86emu/prim_ops.h \
+	     x86emu/prim_x86_gcc.h \
+             x86emu/regs.h \
+             x86emu/types.h \
+             x86emu/x86emui.h
diff --git a/plat/pc65oo2/emu/x86emu/debug.c b/plat/pc65oo2/emu/x86emu/debug.c
new file mode 100644
index 000000000..576ace55e
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/debug.c
@@ -0,0 +1,487 @@
+/****************************************************************************
+*
+*						Realmode X86 Emulator Library
+*
+*            	Copyright (C) 1996-1999 SciTech Software, Inc.
+* 				     Copyright (C) David Mosberger-Tang
+* 					   Copyright (C) 1999 Egbert Eich
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:		ANSI C
+* Environment:	Any
+* Developer:    Kendall Bennett
+*
+* Description:  This file contains the code to handle debugging of the
+*				emulator.
+*
+****************************************************************************/
+
+#include "x86emu/x86emui.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#ifndef NO_SYS_HEADERS
+#include <stdlib.h>
+#endif
+
+/*----------------------------- Implementation ----------------------------*/
+
+#ifdef DEBUG
+
+static void print_encoded_bytes(u16 s, u16 o);
+static void print_decoded_instruction(void);
+static int parse_line(char *s, int *ps, int *n);
+
+/* should look something like debug's output. */
+void
+X86EMU_trace_regs(void)
+{
+    if (DEBUG_TRACE()) {
+        x86emu_dump_regs();
+    }
+    if (DEBUG_DECODE() && !DEBUG_DECODE_NOPRINT()) {
+        printk("%04x:%04x ", M.x86.saved_cs, M.x86.saved_ip);
+        print_encoded_bytes(M.x86.saved_cs, M.x86.saved_ip);
+        print_decoded_instruction();
+    }
+}
+
+void
+X86EMU_trace_xregs(void)
+{
+    if (DEBUG_TRACE()) {
+        x86emu_dump_xregs();
+    }
+}
+
+void
+x86emu_just_disassemble(void)
+{
+    /*
+     * This routine called if the flag DEBUG_DISASSEMBLE is set kind
+     * of a hack!
+     */
+    printk("%04x:%04x ", M.x86.saved_cs, M.x86.saved_ip);
+    print_encoded_bytes(M.x86.saved_cs, M.x86.saved_ip);
+    print_decoded_instruction();
+}
+
+static void
+disassemble_forward(u16 seg, u16 off, int n)
+{
+    X86EMU_sysEnv tregs;
+    int i;
+    u8 op1;
+
+    /*
+     * hack, hack, hack.  What we do is use the exact machinery set up
+     * for execution, except that now there is an additional state
+     * flag associated with the "execution", and we are using a copy
+     * of the register struct.  All the major opcodes, once fully
+     * decoded, have the following two steps: TRACE_REGS(r,m);
+     * SINGLE_STEP(r,m); which disappear if DEBUG is not defined to
+     * the preprocessor.  The TRACE_REGS macro expands to:
+     *
+     * if (debug&DEBUG_DISASSEMBLE)
+     *     {just_disassemble(); goto EndOfInstruction;}
+     *     if (debug&DEBUG_TRACE) trace_regs(r,m);
+     *
+     * ......  and at the last line of the routine.
+     *
+     * EndOfInstruction: end_instr();
+     *
+     * Up to the point where TRACE_REG is expanded, NO modifications
+     * are done to any register EXCEPT the IP register, for fetch and
+     * decoding purposes.
+     *
+     * This was done for an entirely different reason, but makes a
+     * nice way to get the system to help debug codes.
+     */
+    tregs = M;
+    tregs.x86.R_IP = off;
+    tregs.x86.R_CS = seg;
+
+    /* reset the decoding buffers */
+    tregs.x86.enc_str_pos = 0;
+    tregs.x86.enc_pos = 0;
+
+    /* turn on the "disassemble only, no execute" flag */
+    tregs.x86.debug |= DEBUG_DISASSEMBLE_F;
+
+    /* DUMP NEXT n instructions to screen in straight_line fashion */
+    /*
+     * This looks like the regular instruction fetch stream, except
+     * that when this occurs, each fetched opcode, upon seeing the
+     * DEBUG_DISASSEMBLE flag set, exits immediately after decoding
+     * the instruction.  XXX --- CHECK THAT MEM IS NOT AFFECTED!!!
+     * Note the use of a copy of the register structure...
+     */
+    for (i = 0; i < n; i++) {
+        op1 = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
+        (x86emu_optab[op1]) (op1);
+    }
+    /* end major hack mode. */
+}
+
+void
+x86emu_check_ip_access(void)
+{
+    /* NULL as of now */
+}
+
+void
+x86emu_check_sp_access(void)
+{
+}
+
+void
+x86emu_check_mem_access(u32 dummy)
+{
+    /*  check bounds, etc */
+}
+
+void
+x86emu_check_data_access(uint dummy1, uint dummy2)
+{
+    /*  check bounds, etc */
+}
+
+void
+x86emu_inc_decoded_inst_len(int x)
+{
+    M.x86.enc_pos += x;
+}
+
+void
+x86emu_decode_printf(const char *x, ...)
+{
+    va_list ap;
+    char temp[100];
+
+    va_start(ap, x);
+    vsnprintf(temp, sizeof(temp), x, ap);
+    va_end(ap);
+    sprintf(M.x86.decoded_buf + M.x86.enc_str_pos, "%s", temp);
+    M.x86.enc_str_pos += strlen(temp);
+}
+
+void
+x86emu_end_instr(void)
+{
+    M.x86.enc_str_pos = 0;
+    M.x86.enc_pos = 0;
+}
+
+static void
+print_encoded_bytes(u16 s, u16 o)
+{
+    int i;
+    char buf1[64];
+
+    for (i = 0; i < M.x86.enc_pos; i++) {
+        sprintf(buf1 + 2 * i, "%02x", fetch_data_byte_abs(s, o + i));
+    }
+    printk("%-20s", buf1);
+}
+
+static void
+print_decoded_instruction(void)
+{
+    printk("%s", M.x86.decoded_buf);
+}
+
+void
+x86emu_print_int_vect(u16 iv)
+{
+    u16 seg, off;
+
+    if (iv > 256)
+        return;
+    seg = fetch_data_word_abs(0, iv * 4);
+    off = fetch_data_word_abs(0, iv * 4 + 2);
+    printk("%04x:%04x ", seg, off);
+}
+
+void
+X86EMU_dump_memory(u16 seg, u16 off, u32 amt)
+{
+    u32 start = off & 0xfffffff0;
+    u32 end = (off + 16) & 0xfffffff0;
+    u32 i;
+
+    while (end <= off + amt) {
+        printk("%04x:%04x ", seg, start);
+        for (i = start; i < off; i++)
+            printk("   ");
+        for (; i < end; i++)
+            printk("%02x ", fetch_data_byte_abs(seg, i));
+        printk("\n");
+        start = end;
+        end = start + 16;
+    }
+}
+
+void
+x86emu_single_step(void)
+{
+    char s[1024];
+    int ps[10];
+    int ntok;
+    int cmd;
+    int done;
+    int segment;
+    int offset;
+    static int breakpoint;
+    static int noDecode = 1;
+
+    if (DEBUG_BREAK()) {
+        if (M.x86.saved_ip != breakpoint) {
+            return;
+        }
+        else {
+            M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
+            M.x86.debug |= DEBUG_TRACE_F;
+            M.x86.debug &= ~DEBUG_BREAK_F;
+            print_decoded_instruction();
+            X86EMU_trace_regs();
+        }
+    }
+    done = 0;
+    offset = M.x86.saved_ip;
+    while (!done) {
+        printk("-");
+        (void)fgets(s, 1023, stdin);
+        cmd = parse_line(s, ps, &ntok);
+        switch (cmd) {
+        case 'u':
+            disassemble_forward(M.x86.saved_cs, (u16) offset, 10);
+            break;
+        case 'd':
+            if (ntok == 2) {
+                segment = M.x86.saved_cs;
+                offset = ps[1];
+                X86EMU_dump_memory(segment, (u16) offset, 16);
+                offset += 16;
+            }
+            else if (ntok == 3) {
+                segment = ps[1];
+                offset = ps[2];
+                X86EMU_dump_memory(segment, (u16) offset, 16);
+                offset += 16;
+            }
+            else {
+                segment = M.x86.saved_cs;
+                X86EMU_dump_memory(segment, (u16) offset, 16);
+                offset += 16;
+            }
+            break;
+        case 'c':
+            M.x86.debug ^= DEBUG_TRACECALL_F;
+            break;
+        case 's':
+            M.x86.debug ^= DEBUG_SVC_F | DEBUG_SYS_F | DEBUG_SYSINT_F;
+            break;
+        case 'r':
+            X86EMU_trace_regs();
+            break;
+        case 'x':
+            X86EMU_trace_xregs();
+            break;
+        case 'g':
+            if (ntok == 2) {
+                breakpoint = ps[1];
+                if (noDecode) {
+                    M.x86.debug |= DEBUG_DECODE_NOPRINT_F;
+                }
+                else {
+                    M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
+                }
+                M.x86.debug &= ~DEBUG_TRACE_F;
+                M.x86.debug |= DEBUG_BREAK_F;
+                done = 1;
+            }
+            break;
+        case 'q':
+            M.x86.debug |= DEBUG_EXIT;
+            return;
+        case 'P':
+            noDecode = (noDecode) ? 0 : 1;
+            printk("Toggled decoding to %s\n", (noDecode) ? "FALSE" : "TRUE");
+            break;
+        case 't':
+        case 0:
+            done = 1;
+            break;
+        }
+    }
+}
+
+int
+X86EMU_trace_on(void)
+{
+    return M.x86.debug |= DEBUG_STEP_F | DEBUG_DECODE_F | DEBUG_TRACE_F;
+}
+
+int
+X86EMU_trace_off(void)
+{
+    return M.x86.debug &= ~(DEBUG_STEP_F | DEBUG_DECODE_F | DEBUG_TRACE_F);
+}
+
+static int
+parse_line(char *s, int *ps, int *n)
+{
+    int cmd;
+
+    *n = 0;
+    while (*s == ' ' || *s == '\t')
+        s++;
+    ps[*n] = *s;
+    switch (*s) {
+    case '\n':
+        *n += 1;
+        return 0;
+    default:
+        cmd = *s;
+        *n += 1;
+    }
+
+    while (1) {
+        while (*s != ' ' && *s != '\t' && *s != '\n')
+            s++;
+
+        if (*s == '\n')
+            return cmd;
+
+        while (*s == ' ' || *s == '\t')
+            s++;
+
+        sscanf(s, "%x", &ps[*n]);
+        *n += 1;
+    }
+}
+
+#endif                          /* DEBUG */
+
+void
+x86emu_dump_regs(void)
+{
+    printk("\tAX=%04x  ", M.x86.R_AX);
+    printk("BX=%04x  ", M.x86.R_BX);
+    printk("CX=%04x  ", M.x86.R_CX);
+    printk("DX=%04x  ", M.x86.R_DX);
+    printk("SP=%04x  ", M.x86.R_SP);
+    printk("BP=%04x  ", M.x86.R_BP);
+    printk("SI=%04x  ", M.x86.R_SI);
+    printk("DI=%04x\n", M.x86.R_DI);
+    printk("\tDS=%04x  ", M.x86.R_DS);
+    printk("ES=%04x  ", M.x86.R_ES);
+    printk("SS=%04x  ", M.x86.R_SS);
+    printk("CS=%04x  ", M.x86.R_CS);
+    printk("IP=%04x   ", M.x86.R_IP);
+    if (ACCESS_FLAG(F_OF))
+        printk("OV ");          /* CHECKED... */
+    else
+        printk("NV ");
+    if (ACCESS_FLAG(F_DF))
+        printk("DN ");
+    else
+        printk("UP ");
+    if (ACCESS_FLAG(F_IF))
+        printk("EI ");
+    else
+        printk("DI ");
+    if (ACCESS_FLAG(F_SF))
+        printk("NG ");
+    else
+        printk("PL ");
+    if (ACCESS_FLAG(F_ZF))
+        printk("ZR ");
+    else
+        printk("NZ ");
+    if (ACCESS_FLAG(F_AF))
+        printk("AC ");
+    else
+        printk("NA ");
+    if (ACCESS_FLAG(F_PF))
+        printk("PE ");
+    else
+        printk("PO ");
+    if (ACCESS_FLAG(F_CF))
+        printk("CY ");
+    else
+        printk("NC ");
+    printk("\n");
+}
+
+void
+x86emu_dump_xregs(void)
+{
+    printk("\tEAX=%08x  ", M.x86.R_EAX);
+    printk("EBX=%08x  ", M.x86.R_EBX);
+    printk("ECX=%08x  ", M.x86.R_ECX);
+    printk("EDX=%08x  \n", M.x86.R_EDX);
+    printk("\tESP=%08x  ", M.x86.R_ESP);
+    printk("EBP=%08x  ", M.x86.R_EBP);
+    printk("ESI=%08x  ", M.x86.R_ESI);
+    printk("EDI=%08x\n", M.x86.R_EDI);
+    printk("\tDS=%04x  ", M.x86.R_DS);
+    printk("ES=%04x  ", M.x86.R_ES);
+    printk("SS=%04x  ", M.x86.R_SS);
+    printk("CS=%04x  ", M.x86.R_CS);
+    printk("EIP=%08x\n\t", M.x86.R_EIP);
+    if (ACCESS_FLAG(F_OF))
+        printk("OV ");          /* CHECKED... */
+    else
+        printk("NV ");
+    if (ACCESS_FLAG(F_DF))
+        printk("DN ");
+    else
+        printk("UP ");
+    if (ACCESS_FLAG(F_IF))
+        printk("EI ");
+    else
+        printk("DI ");
+    if (ACCESS_FLAG(F_SF))
+        printk("NG ");
+    else
+        printk("PL ");
+    if (ACCESS_FLAG(F_ZF))
+        printk("ZR ");
+    else
+        printk("NZ ");
+    if (ACCESS_FLAG(F_AF))
+        printk("AC ");
+    else
+        printk("NA ");
+    if (ACCESS_FLAG(F_PF))
+        printk("PE ");
+    else
+        printk("PO ");
+    if (ACCESS_FLAG(F_CF))
+        printk("CY ");
+    else
+        printk("NC ");
+    printk("\n");
+}
diff --git a/plat/pc65oo2/emu/x86emu/decode.c b/plat/pc65oo2/emu/x86emu/decode.c
new file mode 100644
index 000000000..08a07b1bb
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/decode.c
@@ -0,0 +1,1102 @@
+/****************************************************************************
+*
+*						Realmode X86 Emulator Library
+*
+*            	Copyright (C) 1996-1999 SciTech Software, Inc.
+* 				     Copyright (C) David Mosberger-Tang
+* 					   Copyright (C) 1999 Egbert Eich
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:		ANSI C
+* Environment:	Any
+* Developer:    Kendall Bennett
+*
+* Description:  This file includes subroutines which are related to
+*				instruction decoding and accessess of immediate data via IP.  etc.
+*
+****************************************************************************/
+
+#include <stdlib.h>
+
+#if defined(__sun) && defined(CS) /* avoid conflicts with Solaris sys/regset.h */
+# undef CS
+# undef DS
+# undef SS
+# undef ES
+# undef FS
+# undef GS
+#endif
+
+#include "x86emu/x86emui.h"
+
+/*----------------------------- Implementation ----------------------------*/
+
+/****************************************************************************
+REMARKS:
+Handles any pending asychronous interrupts.
+****************************************************************************/
+static void
+x86emu_intr_handle(void)
+{
+    u8 intno;
+
+    if (M.x86.intr & INTR_SYNCH) {
+        intno = M.x86.intno;
+        if (_X86EMU_intrTab[intno]) {
+            (*_X86EMU_intrTab[intno]) (intno);
+        }
+        else {
+            push_word((u16) M.x86.R_FLG);
+            CLEAR_FLAG(F_IF);
+            CLEAR_FLAG(F_TF);
+            push_word(M.x86.R_CS);
+            M.x86.R_CS = mem_access_word(intno * 4 + 2);
+            push_word(M.x86.R_IP);
+            M.x86.R_IP = mem_access_word(intno * 4);
+            M.x86.intr = 0;
+        }
+    }
+}
+
+/****************************************************************************
+PARAMETERS:
+intrnum - Interrupt number to raise
+
+REMARKS:
+Raise the specified interrupt to be handled before the execution of the
+next instruction.
+****************************************************************************/
+void
+x86emu_intr_raise(u8 intrnum)
+{
+    M.x86.intno = intrnum;
+    M.x86.intr |= INTR_SYNCH;
+}
+
+/****************************************************************************
+REMARKS:
+Main execution loop for the emulator. We return from here when the system
+halts, which is normally caused by a stack fault when we return from the
+original real mode call.
+****************************************************************************/
+void
+X86EMU_exec(void)
+{
+    u8 op1;
+
+    M.x86.intr = 0;
+    DB(x86emu_end_instr();
+        )
+
+        for (;;) {
+        DB(if (CHECK_IP_FETCH())
+           x86emu_check_ip_access();)
+            /* If debugging, save the IP and CS values. */
+            SAVE_IP_CS(M.x86.R_CS, M.x86.R_IP);
+        INC_DECODED_INST_LEN(1);
+        if (M.x86.intr) {
+            if (M.x86.intr & INTR_HALTED) {
+                DB(if (M.x86.R_SP != 0) {
+                   printk("halted\n"); X86EMU_trace_regs();}
+                   else {
+                   if (M.x86.debug)
+                   printk("Service completed successfully\n");}
+                )
+                    return;
+            }
+            if (((M.x86.intr & INTR_SYNCH) &&
+                 (M.x86.intno == 0 || M.x86.intno == 2)) ||
+                !ACCESS_FLAG(F_IF)) {
+                x86emu_intr_handle();
+            }
+        }
+        op1 = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
+        (*x86emu_optab[op1]) (op1);
+        if (M.x86.debug & DEBUG_EXIT) {
+            M.x86.debug &= ~DEBUG_EXIT;
+            return;
+        }
+    }
+}
+
+/****************************************************************************
+REMARKS:
+Halts the system by setting the halted system flag.
+****************************************************************************/
+void
+X86EMU_halt_sys(void)
+{
+    M.x86.intr |= INTR_HALTED;
+}
+
+/****************************************************************************
+PARAMETERS:
+mod		- Mod value from decoded byte
+regh	- Reg h value from decoded byte
+regl	- Reg l value from decoded byte
+
+REMARKS:
+Raise the specified interrupt to be handled before the execution of the
+next instruction.
+
+NOTE: Do not inline this function, as (*sys_rdb) is already inline!
+****************************************************************************/
+void
+fetch_decode_modrm(int *mod, int *regh, int *regl)
+{
+    int fetched;
+
+    DB(if (CHECK_IP_FETCH())
+       x86emu_check_ip_access();)
+        fetched = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
+    INC_DECODED_INST_LEN(1);
+    *mod = (fetched >> 6) & 0x03;
+    *regh = (fetched >> 3) & 0x07;
+    *regl = (fetched >> 0) & 0x07;
+}
+
+/****************************************************************************
+RETURNS:
+Immediate byte value read from instruction queue
+
+REMARKS:
+This function returns the immediate byte from the instruction queue, and
+moves the instruction pointer to the next value.
+
+NOTE: Do not inline this function, as (*sys_rdb) is already inline!
+****************************************************************************/
+u8
+fetch_byte_imm(void)
+{
+    u8 fetched;
+
+    DB(if (CHECK_IP_FETCH())
+       x86emu_check_ip_access();)
+        fetched = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
+    INC_DECODED_INST_LEN(1);
+    return fetched;
+}
+
+/****************************************************************************
+RETURNS:
+Immediate word value read from instruction queue
+
+REMARKS:
+This function returns the immediate byte from the instruction queue, and
+moves the instruction pointer to the next value.
+
+NOTE: Do not inline this function, as (*sys_rdw) is already inline!
+****************************************************************************/
+u16
+fetch_word_imm(void)
+{
+    u16 fetched;
+
+    DB(if (CHECK_IP_FETCH())
+       x86emu_check_ip_access();)
+        fetched = (*sys_rdw) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP));
+    M.x86.R_IP += 2;
+    INC_DECODED_INST_LEN(2);
+    return fetched;
+}
+
+/****************************************************************************
+RETURNS:
+Immediate lone value read from instruction queue
+
+REMARKS:
+This function returns the immediate byte from the instruction queue, and
+moves the instruction pointer to the next value.
+
+NOTE: Do not inline this function, as (*sys_rdw) is already inline!
+****************************************************************************/
+u32
+fetch_long_imm(void)
+{
+    u32 fetched;
+
+    DB(if (CHECK_IP_FETCH())
+       x86emu_check_ip_access();)
+        fetched = (*sys_rdl) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP));
+    M.x86.R_IP += 4;
+    INC_DECODED_INST_LEN(4);
+    return fetched;
+}
+
+/****************************************************************************
+RETURNS:
+Value of the default data segment
+
+REMARKS:
+Inline function that returns the default data segment for the current
+instruction.
+
+On the x86 processor, the default segment is not always DS if there is
+no segment override. Address modes such as -3[BP] or 10[BP+SI] all refer to
+addresses relative to SS (ie: on the stack). So, at the minimum, all
+decodings of addressing modes would have to set/clear a bit describing
+whether the access is relative to DS or SS.  That is the function of the
+cpu-state-varible M.x86.mode. There are several potential states:
+
+	repe prefix seen  (handled elsewhere)
+	repne prefix seen  (ditto)
+
+	cs segment override
+	ds segment override
+	es segment override
+	fs segment override
+	gs segment override
+	ss segment override
+
+	ds/ss select (in absense of override)
+
+Each of the above 7 items are handled with a bit in the mode field.
+****************************************************************************/
+_INLINE u32
+get_data_segment(void)
+{
+#define	GET_SEGMENT(segment)
+    switch (M.x86.mode & SYSMODE_SEGMASK) {
+    case 0:                    /* default case: use ds register */
+    case SYSMODE_SEGOVR_DS:
+    case SYSMODE_SEGOVR_DS | SYSMODE_SEG_DS_SS:
+        return M.x86.R_DS;
+    case SYSMODE_SEG_DS_SS:    /* non-overridden, use ss register */
+        return M.x86.R_SS;
+    case SYSMODE_SEGOVR_CS:
+    case SYSMODE_SEGOVR_CS | SYSMODE_SEG_DS_SS:
+        return M.x86.R_CS;
+    case SYSMODE_SEGOVR_ES:
+    case SYSMODE_SEGOVR_ES | SYSMODE_SEG_DS_SS:
+        return M.x86.R_ES;
+    case SYSMODE_SEGOVR_FS:
+    case SYSMODE_SEGOVR_FS | SYSMODE_SEG_DS_SS:
+        return M.x86.R_FS;
+    case SYSMODE_SEGOVR_GS:
+    case SYSMODE_SEGOVR_GS | SYSMODE_SEG_DS_SS:
+        return M.x86.R_GS;
+    case SYSMODE_SEGOVR_SS:
+    case SYSMODE_SEGOVR_SS | SYSMODE_SEG_DS_SS:
+        return M.x86.R_SS;
+    default:
+#ifdef	DEBUG
+        printk("error: should not happen:  multiple overrides.\n");
+#endif
+        HALT_SYS();
+        return 0;
+    }
+}
+
+/****************************************************************************
+PARAMETERS:
+offset	- Offset to load data from
+
+RETURNS:
+Byte value read from the absolute memory location.
+
+NOTE: Do not inline this function as (*sys_rdX) is already inline!
+****************************************************************************/
+u8
+fetch_data_byte(uint offset)
+{
+#ifdef DEBUG
+    if (CHECK_DATA_ACCESS())
+        x86emu_check_data_access((u16) get_data_segment(), offset);
+#endif
+    return (*sys_rdb) ((get_data_segment() << 4) + offset);
+}
+
+/****************************************************************************
+PARAMETERS:
+offset	- Offset to load data from
+
+RETURNS:
+Word value read from the absolute memory location.
+
+NOTE: Do not inline this function as (*sys_rdX) is already inline!
+****************************************************************************/
+u16
+fetch_data_word(uint offset)
+{
+#ifdef DEBUG
+    if (CHECK_DATA_ACCESS())
+        x86emu_check_data_access((u16) get_data_segment(), offset);
+#endif
+    return (*sys_rdw) ((get_data_segment() << 4) + offset);
+}
+
+/****************************************************************************
+PARAMETERS:
+offset	- Offset to load data from
+
+RETURNS:
+Long value read from the absolute memory location.
+
+NOTE: Do not inline this function as (*sys_rdX) is already inline!
+****************************************************************************/
+u32
+fetch_data_long(uint offset)
+{
+#ifdef DEBUG
+    if (CHECK_DATA_ACCESS())
+        x86emu_check_data_access((u16) get_data_segment(), offset);
+#endif
+    return (*sys_rdl) ((get_data_segment() << 4) + offset);
+}
+
+/****************************************************************************
+PARAMETERS:
+segment	- Segment to load data from
+offset	- Offset to load data from
+
+RETURNS:
+Byte value read from the absolute memory location.
+
+NOTE: Do not inline this function as (*sys_rdX) is already inline!
+****************************************************************************/
+u8
+fetch_data_byte_abs(uint segment, uint offset)
+{
+#ifdef DEBUG
+    if (CHECK_DATA_ACCESS())
+        x86emu_check_data_access(segment, offset);
+#endif
+    return (*sys_rdb) (((u32) segment << 4) + offset);
+}
+
+/****************************************************************************
+PARAMETERS:
+segment	- Segment to load data from
+offset	- Offset to load data from
+
+RETURNS:
+Word value read from the absolute memory location.
+
+NOTE: Do not inline this function as (*sys_rdX) is already inline!
+****************************************************************************/
+u16
+fetch_data_word_abs(uint segment, uint offset)
+{
+#ifdef DEBUG
+    if (CHECK_DATA_ACCESS())
+        x86emu_check_data_access(segment, offset);
+#endif
+    return (*sys_rdw) (((u32) segment << 4) + offset);
+}
+
+/****************************************************************************
+PARAMETERS:
+segment	- Segment to load data from
+offset	- Offset to load data from
+
+RETURNS:
+Long value read from the absolute memory location.
+
+NOTE: Do not inline this function as (*sys_rdX) is already inline!
+****************************************************************************/
+u32
+fetch_data_long_abs(uint segment, uint offset)
+{
+#ifdef DEBUG
+    if (CHECK_DATA_ACCESS())
+        x86emu_check_data_access(segment, offset);
+#endif
+    return (*sys_rdl) (((u32) segment << 4) + offset);
+}
+
+/****************************************************************************
+PARAMETERS:
+offset	- Offset to store data at
+val		- Value to store
+
+REMARKS:
+Writes a word value to an segmented memory location. The segment used is
+the current 'default' segment, which may have been overridden.
+
+NOTE: Do not inline this function as (*sys_wrX) is already inline!
+****************************************************************************/
+void
+store_data_byte(uint offset, u8 val)
+{
+#ifdef DEBUG
+    if (CHECK_DATA_ACCESS())
+        x86emu_check_data_access((u16) get_data_segment(), offset);
+#endif
+    (*sys_wrb) ((get_data_segment() << 4) + offset, val);
+}
+
+/****************************************************************************
+PARAMETERS:
+offset	- Offset to store data at
+val		- Value to store
+
+REMARKS:
+Writes a word value to an segmented memory location. The segment used is
+the current 'default' segment, which may have been overridden.
+
+NOTE: Do not inline this function as (*sys_wrX) is already inline!
+****************************************************************************/
+void
+store_data_word(uint offset, u16 val)
+{
+#ifdef DEBUG
+    if (CHECK_DATA_ACCESS())
+        x86emu_check_data_access((u16) get_data_segment(), offset);
+#endif
+    (*sys_wrw) ((get_data_segment() << 4) + offset, val);
+}
+
+/****************************************************************************
+PARAMETERS:
+offset	- Offset to store data at
+val		- Value to store
+
+REMARKS:
+Writes a long value to an segmented memory location. The segment used is
+the current 'default' segment, which may have been overridden.
+
+NOTE: Do not inline this function as (*sys_wrX) is already inline!
+****************************************************************************/
+void
+store_data_long(uint offset, u32 val)
+{
+#ifdef DEBUG
+    if (CHECK_DATA_ACCESS())
+        x86emu_check_data_access((u16) get_data_segment(), offset);
+#endif
+    (*sys_wrl) ((get_data_segment() << 4) + offset, val);
+}
+
+/****************************************************************************
+PARAMETERS:
+segment	- Segment to store data at
+offset	- Offset to store data at
+val		- Value to store
+
+REMARKS:
+Writes a byte value to an absolute memory location.
+
+NOTE: Do not inline this function as (*sys_wrX) is already inline!
+****************************************************************************/
+void
+store_data_byte_abs(uint segment, uint offset, u8 val)
+{
+#ifdef DEBUG
+    if (CHECK_DATA_ACCESS())
+        x86emu_check_data_access(segment, offset);
+#endif
+    (*sys_wrb) (((u32) segment << 4) + offset, val);
+}
+
+/****************************************************************************
+PARAMETERS:
+segment	- Segment to store data at
+offset	- Offset to store data at
+val		- Value to store
+
+REMARKS:
+Writes a word value to an absolute memory location.
+
+NOTE: Do not inline this function as (*sys_wrX) is already inline!
+****************************************************************************/
+void
+store_data_word_abs(uint segment, uint offset, u16 val)
+{
+#ifdef DEBUG
+    if (CHECK_DATA_ACCESS())
+        x86emu_check_data_access(segment, offset);
+#endif
+    (*sys_wrw) (((u32) segment << 4) + offset, val);
+}
+
+/****************************************************************************
+PARAMETERS:
+segment	- Segment to store data at
+offset	- Offset to store data at
+val		- Value to store
+
+REMARKS:
+Writes a long value to an absolute memory location.
+
+NOTE: Do not inline this function as (*sys_wrX) is already inline!
+****************************************************************************/
+void
+store_data_long_abs(uint segment, uint offset, u32 val)
+{
+#ifdef DEBUG
+    if (CHECK_DATA_ACCESS())
+        x86emu_check_data_access(segment, offset);
+#endif
+    (*sys_wrl) (((u32) segment << 4) + offset, val);
+}
+
+/****************************************************************************
+PARAMETERS:
+reg	- Register to decode
+
+RETURNS:
+Pointer to the appropriate register
+
+REMARKS:
+Return a pointer to the register given by the R/RM field of the
+modrm byte, for byte operands. Also enables the decoding of instructions.
+****************************************************************************/
+u8 *
+decode_rm_byte_register(int reg)
+{
+    switch (reg) {
+    case 0:
+        DECODE_PRINTF("AL");
+        return &M.x86.R_AL;
+    case 1:
+        DECODE_PRINTF("CL");
+        return &M.x86.R_CL;
+    case 2:
+        DECODE_PRINTF("DL");
+        return &M.x86.R_DL;
+    case 3:
+        DECODE_PRINTF("BL");
+        return &M.x86.R_BL;
+    case 4:
+        DECODE_PRINTF("AH");
+        return &M.x86.R_AH;
+    case 5:
+        DECODE_PRINTF("CH");
+        return &M.x86.R_CH;
+    case 6:
+        DECODE_PRINTF("DH");
+        return &M.x86.R_DH;
+    case 7:
+        DECODE_PRINTF("BH");
+        return &M.x86.R_BH;
+    }
+    HALT_SYS();
+    return NULL;                /* NOT REACHED OR REACHED ON ERROR */
+}
+
+/****************************************************************************
+PARAMETERS:
+reg	- Register to decode
+
+RETURNS:
+Pointer to the appropriate register
+
+REMARKS:
+Return a pointer to the register given by the R/RM field of the
+modrm byte, for word operands.  Also enables the decoding of instructions.
+****************************************************************************/
+u16 *
+decode_rm_word_register(int reg)
+{
+    switch (reg) {
+    case 0:
+        DECODE_PRINTF("AX");
+        return &M.x86.R_AX;
+    case 1:
+        DECODE_PRINTF("CX");
+        return &M.x86.R_CX;
+    case 2:
+        DECODE_PRINTF("DX");
+        return &M.x86.R_DX;
+    case 3:
+        DECODE_PRINTF("BX");
+        return &M.x86.R_BX;
+    case 4:
+        DECODE_PRINTF("SP");
+        return &M.x86.R_SP;
+    case 5:
+        DECODE_PRINTF("BP");
+        return &M.x86.R_BP;
+    case 6:
+        DECODE_PRINTF("SI");
+        return &M.x86.R_SI;
+    case 7:
+        DECODE_PRINTF("DI");
+        return &M.x86.R_DI;
+    }
+    HALT_SYS();
+    return NULL;                /* NOTREACHED OR REACHED ON ERROR */
+}
+
+/****************************************************************************
+PARAMETERS:
+reg	- Register to decode
+
+RETURNS:
+Pointer to the appropriate register
+
+REMARKS:
+Return a pointer to the register given by the R/RM field of the
+modrm byte, for dword operands.  Also enables the decoding of instructions.
+****************************************************************************/
+u32 *
+decode_rm_long_register(int reg)
+{
+    switch (reg) {
+    case 0:
+        DECODE_PRINTF("EAX");
+        return &M.x86.R_EAX;
+    case 1:
+        DECODE_PRINTF("ECX");
+        return &M.x86.R_ECX;
+    case 2:
+        DECODE_PRINTF("EDX");
+        return &M.x86.R_EDX;
+    case 3:
+        DECODE_PRINTF("EBX");
+        return &M.x86.R_EBX;
+    case 4:
+        DECODE_PRINTF("ESP");
+        return &M.x86.R_ESP;
+    case 5:
+        DECODE_PRINTF("EBP");
+        return &M.x86.R_EBP;
+    case 6:
+        DECODE_PRINTF("ESI");
+        return &M.x86.R_ESI;
+    case 7:
+        DECODE_PRINTF("EDI");
+        return &M.x86.R_EDI;
+    }
+    HALT_SYS();
+    return NULL;                /* NOTREACHED OR REACHED ON ERROR */
+}
+
+/****************************************************************************
+PARAMETERS:
+reg	- Register to decode
+
+RETURNS:
+Pointer to the appropriate register
+
+REMARKS:
+Return a pointer to the register given by the R/RM field of the
+modrm byte, for word operands, modified from above for the weirdo
+special case of segreg operands.  Also enables the decoding of instructions.
+****************************************************************************/
+u16 *
+decode_rm_seg_register(int reg)
+{
+    switch (reg) {
+    case 0:
+        DECODE_PRINTF("ES");
+        return &M.x86.R_ES;
+    case 1:
+        DECODE_PRINTF("CS");
+        return &M.x86.R_CS;
+    case 2:
+        DECODE_PRINTF("SS");
+        return &M.x86.R_SS;
+    case 3:
+        DECODE_PRINTF("DS");
+        return &M.x86.R_DS;
+    case 4:
+        DECODE_PRINTF("FS");
+        return &M.x86.R_FS;
+    case 5:
+        DECODE_PRINTF("GS");
+        return &M.x86.R_GS;
+    case 6:
+    case 7:
+        DECODE_PRINTF("ILLEGAL SEGREG");
+        break;
+    }
+    HALT_SYS();
+    return NULL;                /* NOT REACHED OR REACHED ON ERROR */
+}
+
+/*
+ *
+ * return offset from the SIB Byte
+ */
+u32
+decode_sib_address(int sib, int mod)
+{
+    u32 base = 0, i = 0, scale = 1;
+
+    switch (sib & 0x07) {
+    case 0:
+        DECODE_PRINTF("[EAX]");
+        base = M.x86.R_EAX;
+        break;
+    case 1:
+        DECODE_PRINTF("[ECX]");
+        base = M.x86.R_ECX;
+        break;
+    case 2:
+        DECODE_PRINTF("[EDX]");
+        base = M.x86.R_EDX;
+        break;
+    case 3:
+        DECODE_PRINTF("[EBX]");
+        base = M.x86.R_EBX;
+        break;
+    case 4:
+        DECODE_PRINTF("[ESP]");
+        base = M.x86.R_ESP;
+        M.x86.mode |= SYSMODE_SEG_DS_SS;
+        break;
+    case 5:
+        if (mod == 0) {
+            base = fetch_long_imm();
+            DECODE_PRINTF2("%08x", base);
+        }
+        else {
+            DECODE_PRINTF("[EBP]");
+            base = M.x86.R_ESP;
+            M.x86.mode |= SYSMODE_SEG_DS_SS;
+        }
+        break;
+    case 6:
+        DECODE_PRINTF("[ESI]");
+        base = M.x86.R_ESI;
+        break;
+    case 7:
+        DECODE_PRINTF("[EDI]");
+        base = M.x86.R_EDI;
+        break;
+    }
+    switch ((sib >> 3) & 0x07) {
+    case 0:
+        DECODE_PRINTF("[EAX");
+        i = M.x86.R_EAX;
+        break;
+    case 1:
+        DECODE_PRINTF("[ECX");
+        i = M.x86.R_ECX;
+        break;
+    case 2:
+        DECODE_PRINTF("[EDX");
+        i = M.x86.R_EDX;
+        break;
+    case 3:
+        DECODE_PRINTF("[EBX");
+        i = M.x86.R_EBX;
+        break;
+    case 4:
+        i = 0;
+        break;
+    case 5:
+        DECODE_PRINTF("[EBP");
+        i = M.x86.R_EBP;
+        break;
+    case 6:
+        DECODE_PRINTF("[ESI");
+        i = M.x86.R_ESI;
+        break;
+    case 7:
+        DECODE_PRINTF("[EDI");
+        i = M.x86.R_EDI;
+        break;
+    }
+    scale = 1 << ((sib >> 6) & 0x03);
+    if (((sib >> 3) & 0x07) != 4) {
+        if (scale == 1) {
+            DECODE_PRINTF("]");
+        }
+        else {
+            DECODE_PRINTF2("*%d]", scale);
+        }
+    }
+    return base + (i * scale);
+}
+
+/****************************************************************************
+PARAMETERS:
+rm	- RM value to decode
+
+RETURNS:
+Offset in memory for the address decoding
+
+REMARKS:
+Return the offset given by mod=00 addressing.  Also enables the
+decoding of instructions.
+
+NOTE: 	The code which specifies the corresponding segment (ds vs ss)
+		below in the case of [BP+..].  The assumption here is that at the
+		point that this subroutine is called, the bit corresponding to
+		SYSMODE_SEG_DS_SS will be zero.  After every instruction
+		except the segment override instructions, this bit (as well
+		as any bits indicating segment overrides) will be clear.  So
+		if a SS access is needed, set this bit.  Otherwise, DS access
+		occurs (unless any of the segment override bits are set).
+****************************************************************************/
+u32
+decode_rm00_address(int rm)
+{
+    u32 offset;
+    int sib;
+
+    if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
+        /* 32-bit addressing */
+        switch (rm) {
+        case 0:
+            DECODE_PRINTF("[EAX]");
+            return M.x86.R_EAX;
+        case 1:
+            DECODE_PRINTF("[ECX]");
+            return M.x86.R_ECX;
+        case 2:
+            DECODE_PRINTF("[EDX]");
+            return M.x86.R_EDX;
+        case 3:
+            DECODE_PRINTF("[EBX]");
+            return M.x86.R_EBX;
+        case 4:
+            sib = fetch_byte_imm();
+            return decode_sib_address(sib, 0);
+        case 5:
+            offset = fetch_long_imm();
+            DECODE_PRINTF2("[%08x]", offset);
+            return offset;
+        case 6:
+            DECODE_PRINTF("[ESI]");
+            return M.x86.R_ESI;
+        case 7:
+            DECODE_PRINTF("[EDI]");
+            return M.x86.R_EDI;
+        }
+        HALT_SYS();
+    }
+    else {
+        /* 16-bit addressing */
+        switch (rm) {
+        case 0:
+            DECODE_PRINTF("[BX+SI]");
+            return (M.x86.R_BX + M.x86.R_SI) & 0xffff;
+        case 1:
+            DECODE_PRINTF("[BX+DI]");
+            return (M.x86.R_BX + M.x86.R_DI) & 0xffff;
+        case 2:
+            DECODE_PRINTF("[BP+SI]");
+            M.x86.mode |= SYSMODE_SEG_DS_SS;
+            return (M.x86.R_BP + M.x86.R_SI) & 0xffff;
+        case 3:
+            DECODE_PRINTF("[BP+DI]");
+            M.x86.mode |= SYSMODE_SEG_DS_SS;
+            return (M.x86.R_BP + M.x86.R_DI) & 0xffff;
+        case 4:
+            DECODE_PRINTF("[SI]");
+            return M.x86.R_SI;
+        case 5:
+            DECODE_PRINTF("[DI]");
+            return M.x86.R_DI;
+        case 6:
+            offset = fetch_word_imm();
+            DECODE_PRINTF2("[%04x]", offset);
+            return offset;
+        case 7:
+            DECODE_PRINTF("[BX]");
+            return M.x86.R_BX;
+        }
+        HALT_SYS();
+    }
+    return 0;
+}
+
+/****************************************************************************
+PARAMETERS:
+rm	- RM value to decode
+
+RETURNS:
+Offset in memory for the address decoding
+
+REMARKS:
+Return the offset given by mod=01 addressing.  Also enables the
+decoding of instructions.
+****************************************************************************/
+u32
+decode_rm01_address(int rm)
+{
+    int displacement = 0;
+    int sib;
+
+    /* Fetch disp8 if no SIB byte */
+    if (!((M.x86.mode & SYSMODE_PREFIX_ADDR) && (rm == 4)))
+        displacement = (s8) fetch_byte_imm();
+
+    if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
+        /* 32-bit addressing */
+        switch (rm) {
+        case 0:
+            DECODE_PRINTF2("%d[EAX]", displacement);
+            return M.x86.R_EAX + displacement;
+        case 1:
+            DECODE_PRINTF2("%d[ECX]", displacement);
+            return M.x86.R_ECX + displacement;
+        case 2:
+            DECODE_PRINTF2("%d[EDX]", displacement);
+            return M.x86.R_EDX + displacement;
+        case 3:
+            DECODE_PRINTF2("%d[EBX]", displacement);
+            return M.x86.R_EBX + displacement;
+        case 4:
+            sib = fetch_byte_imm();
+            displacement = (s8) fetch_byte_imm();
+            DECODE_PRINTF2("%d", displacement);
+            return decode_sib_address(sib, 1) + displacement;
+        case 5:
+            DECODE_PRINTF2("%d[EBP]", displacement);
+            return M.x86.R_EBP + displacement;
+        case 6:
+            DECODE_PRINTF2("%d[ESI]", displacement);
+            return M.x86.R_ESI + displacement;
+        case 7:
+            DECODE_PRINTF2("%d[EDI]", displacement);
+            return M.x86.R_EDI + displacement;
+        }
+        HALT_SYS();
+    }
+    else {
+        /* 16-bit addressing */
+        switch (rm) {
+        case 0:
+            DECODE_PRINTF2("%d[BX+SI]", displacement);
+            return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff;
+        case 1:
+            DECODE_PRINTF2("%d[BX+DI]", displacement);
+            return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff;
+        case 2:
+            DECODE_PRINTF2("%d[BP+SI]", displacement);
+            M.x86.mode |= SYSMODE_SEG_DS_SS;
+            return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff;
+        case 3:
+            DECODE_PRINTF2("%d[BP+DI]", displacement);
+            M.x86.mode |= SYSMODE_SEG_DS_SS;
+            return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff;
+        case 4:
+            DECODE_PRINTF2("%d[SI]", displacement);
+            return (M.x86.R_SI + displacement) & 0xffff;
+        case 5:
+            DECODE_PRINTF2("%d[DI]", displacement);
+            return (M.x86.R_DI + displacement) & 0xffff;
+        case 6:
+            DECODE_PRINTF2("%d[BP]", displacement);
+            M.x86.mode |= SYSMODE_SEG_DS_SS;
+            return (M.x86.R_BP + displacement) & 0xffff;
+        case 7:
+            DECODE_PRINTF2("%d[BX]", displacement);
+            return (M.x86.R_BX + displacement) & 0xffff;
+        }
+        HALT_SYS();
+    }
+    return 0;                   /* SHOULD NOT HAPPEN */
+}
+
+/****************************************************************************
+PARAMETERS:
+rm	- RM value to decode
+
+RETURNS:
+Offset in memory for the address decoding
+
+REMARKS:
+Return the offset given by mod=10 addressing.  Also enables the
+decoding of instructions.
+****************************************************************************/
+u32
+decode_rm10_address(int rm)
+{
+    u32 displacement = 0;
+    int sib;
+
+    /* Fetch disp16 if 16-bit addr mode */
+    if (!(M.x86.mode & SYSMODE_PREFIX_ADDR))
+        displacement = (u16) fetch_word_imm();
+    else {
+        /* Fetch disp32 if no SIB byte */
+        if (rm != 4)
+            displacement = (u32) fetch_long_imm();
+    }
+
+    if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
+        /* 32-bit addressing */
+        switch (rm) {
+        case 0:
+            DECODE_PRINTF2("%08x[EAX]", displacement);
+            return M.x86.R_EAX + displacement;
+        case 1:
+            DECODE_PRINTF2("%08x[ECX]", displacement);
+            return M.x86.R_ECX + displacement;
+        case 2:
+            DECODE_PRINTF2("%08x[EDX]", displacement);
+            M.x86.mode |= SYSMODE_SEG_DS_SS;
+            return M.x86.R_EDX + displacement;
+        case 3:
+            DECODE_PRINTF2("%08x[EBX]", displacement);
+            return M.x86.R_EBX + displacement;
+        case 4:
+            sib = fetch_byte_imm();
+            displacement = (u32) fetch_long_imm();
+            DECODE_PRINTF2("%08x", displacement);
+            return decode_sib_address(sib, 2) + displacement;
+            break;
+        case 5:
+            DECODE_PRINTF2("%08x[EBP]", displacement);
+            return M.x86.R_EBP + displacement;
+        case 6:
+            DECODE_PRINTF2("%08x[ESI]", displacement);
+            return M.x86.R_ESI + displacement;
+        case 7:
+            DECODE_PRINTF2("%08x[EDI]", displacement);
+            return M.x86.R_EDI + displacement;
+        }
+        HALT_SYS();
+    }
+    else {
+        /* 16-bit addressing */
+        switch (rm) {
+        case 0:
+            DECODE_PRINTF2("%04x[BX+SI]", displacement);
+            return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff;
+        case 1:
+            DECODE_PRINTF2("%04x[BX+DI]", displacement);
+            return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff;
+        case 2:
+            DECODE_PRINTF2("%04x[BP+SI]", displacement);
+            M.x86.mode |= SYSMODE_SEG_DS_SS;
+            return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff;
+        case 3:
+            DECODE_PRINTF2("%04x[BP+DI]", displacement);
+            M.x86.mode |= SYSMODE_SEG_DS_SS;
+            return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff;
+        case 4:
+            DECODE_PRINTF2("%04x[SI]", displacement);
+            return (M.x86.R_SI + displacement) & 0xffff;
+        case 5:
+            DECODE_PRINTF2("%04x[DI]", displacement);
+            return (M.x86.R_DI + displacement) & 0xffff;
+        case 6:
+            DECODE_PRINTF2("%04x[BP]", displacement);
+            M.x86.mode |= SYSMODE_SEG_DS_SS;
+            return (M.x86.R_BP + displacement) & 0xffff;
+        case 7:
+            DECODE_PRINTF2("%04x[BX]", displacement);
+            return (M.x86.R_BX + displacement) & 0xffff;
+        }
+        HALT_SYS();
+    }
+    return 0;
+    /*NOTREACHED */
+}
diff --git a/plat/pc65oo2/emu/x86emu/fpu.c b/plat/pc65oo2/emu/x86emu/fpu.c
new file mode 100644
index 000000000..0dab05ce3
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/fpu.c
@@ -0,0 +1,976 @@
+/****************************************************************************
+*
+*						Realmode X86 Emulator Library
+*
+*            	Copyright (C) 1996-1999 SciTech Software, Inc.
+* 				     Copyright (C) David Mosberger-Tang
+* 					   Copyright (C) 1999 Egbert Eich
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:		ANSI C
+* Environment:	Any
+* Developer:    Kendall Bennett
+*
+* Description:  This file contains the code to implement the decoding and
+*               emulation of the FPU instructions.
+*
+****************************************************************************/
+
+#include "x86emu/x86emui.h"
+
+/*----------------------------- Implementation ----------------------------*/
+
+/* opcode=0xd8 */
+void
+x86emuOp_esc_coprocess_d8(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("ESC D8\n");
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR_NO_TRACE();
+}
+
+#ifdef DEBUG
+
+static const char *x86emu_fpu_op_d9_tab[] = {
+    "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
+    "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
+
+    "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
+    "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
+
+    "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
+    "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
+};
+
+static const char *x86emu_fpu_op_d9_tab1[] = {
+    "FLD\t", "FLD\t", "FLD\t", "FLD\t",
+    "FLD\t", "FLD\t", "FLD\t", "FLD\t",
+
+    "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
+    "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
+
+    "FNOP", "ESC_D9", "ESC_D9", "ESC_D9",
+    "ESC_D9", "ESC_D9", "ESC_D9", "ESC_D9",
+
+    "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
+    "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
+
+    "FCHS", "FABS", "ESC_D9", "ESC_D9",
+    "FTST", "FXAM", "ESC_D9", "ESC_D9",
+
+    "FLD1", "FLDL2T", "FLDL2E", "FLDPI",
+    "FLDLG2", "FLDLN2", "FLDZ", "ESC_D9",
+
+    "F2XM1", "FYL2X", "FPTAN", "FPATAN",
+    "FXTRACT", "ESC_D9", "FDECSTP", "FINCSTP",
+
+    "FPREM", "FYL2XP1", "FSQRT", "ESC_D9",
+    "FRNDINT", "FSCALE", "ESC_D9", "ESC_D9",
+};
+
+#endif                          /* DEBUG */
+
+/* opcode=0xd9 */
+void
+x86emuOp_esc_coprocess_d9(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset = 0;
+    u8 stkelem = 0;
+
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+#ifdef DEBUG
+    if (mod != 3) {
+        DECODE_PRINTINSTR32(x86emu_fpu_op_d9_tab, mod, rh, rl);
+    }
+    else {
+        DECODE_PRINTF(x86emu_fpu_op_d9_tab1[(rh << 3) + rl]);
+    }
+#endif
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF("\n");
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF("\n");
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF("\n");
+        break;
+    case 3:                    /* register to register */
+        stkelem = (u8) rl;
+        if (rh < 4) {
+            DECODE_PRINTF2("ST(%d)\n", stkelem);
+        }
+        else {
+            DECODE_PRINTF("\n");
+        }
+        break;
+    }
+#ifdef X86EMU_FPU_PRESENT
+    /* execute */
+    switch (mod) {
+    case 3:
+        switch (rh) {
+        case 0:
+            x86emu_fpu_R_fld(X86EMU_FPU_STKTOP, stkelem);
+            break;
+        case 1:
+            x86emu_fpu_R_fxch(X86EMU_FPU_STKTOP, stkelem);
+            break;
+        case 2:
+            switch (rl) {
+            case 0:
+                x86emu_fpu_R_nop();
+                break;
+            default:
+                x86emu_fpu_illegal();
+                break;
+            }
+        case 3:
+            x86emu_fpu_R_fstp(X86EMU_FPU_STKTOP, stkelem);
+            break;
+        case 4:
+            switch (rl) {
+            case 0:
+                x86emu_fpu_R_fchs(X86EMU_FPU_STKTOP);
+                break;
+            case 1:
+                x86emu_fpu_R_fabs(X86EMU_FPU_STKTOP);
+                break;
+            case 4:
+                x86emu_fpu_R_ftst(X86EMU_FPU_STKTOP);
+                break;
+            case 5:
+                x86emu_fpu_R_fxam(X86EMU_FPU_STKTOP);
+                break;
+            default:
+                /* 2,3,6,7 */
+                x86emu_fpu_illegal();
+                break;
+            }
+            break;
+
+        case 5:
+            switch (rl) {
+            case 0:
+                x86emu_fpu_R_fld1(X86EMU_FPU_STKTOP);
+                break;
+            case 1:
+                x86emu_fpu_R_fldl2t(X86EMU_FPU_STKTOP);
+                break;
+            case 2:
+                x86emu_fpu_R_fldl2e(X86EMU_FPU_STKTOP);
+                break;
+            case 3:
+                x86emu_fpu_R_fldpi(X86EMU_FPU_STKTOP);
+                break;
+            case 4:
+                x86emu_fpu_R_fldlg2(X86EMU_FPU_STKTOP);
+                break;
+            case 5:
+                x86emu_fpu_R_fldln2(X86EMU_FPU_STKTOP);
+                break;
+            case 6:
+                x86emu_fpu_R_fldz(X86EMU_FPU_STKTOP);
+                break;
+            default:
+                /* 7 */
+                x86emu_fpu_illegal();
+                break;
+            }
+            break;
+
+        case 6:
+            switch (rl) {
+            case 0:
+                x86emu_fpu_R_f2xm1(X86EMU_FPU_STKTOP);
+                break;
+            case 1:
+                x86emu_fpu_R_fyl2x(X86EMU_FPU_STKTOP);
+                break;
+            case 2:
+                x86emu_fpu_R_fptan(X86EMU_FPU_STKTOP);
+                break;
+            case 3:
+                x86emu_fpu_R_fpatan(X86EMU_FPU_STKTOP);
+                break;
+            case 4:
+                x86emu_fpu_R_fxtract(X86EMU_FPU_STKTOP);
+                break;
+            case 5:
+                x86emu_fpu_illegal();
+                break;
+            case 6:
+                x86emu_fpu_R_decstp();
+                break;
+            case 7:
+                x86emu_fpu_R_incstp();
+                break;
+            }
+            break;
+
+        case 7:
+            switch (rl) {
+            case 0:
+                x86emu_fpu_R_fprem(X86EMU_FPU_STKTOP);
+                break;
+            case 1:
+                x86emu_fpu_R_fyl2xp1(X86EMU_FPU_STKTOP);
+                break;
+            case 2:
+                x86emu_fpu_R_fsqrt(X86EMU_FPU_STKTOP);
+                break;
+            case 3:
+                x86emu_fpu_illegal();
+                break;
+            case 4:
+                x86emu_fpu_R_frndint(X86EMU_FPU_STKTOP);
+                break;
+            case 5:
+                x86emu_fpu_R_fscale(X86EMU_FPU_STKTOP);
+                break;
+            case 6:
+            case 7:
+            default:
+                x86emu_fpu_illegal();
+                break;
+            }
+            break;
+
+        default:
+            switch (rh) {
+            case 0:
+                x86emu_fpu_M_fld(X86EMU_FPU_FLOAT, destoffset);
+                break;
+            case 1:
+                x86emu_fpu_illegal();
+                break;
+            case 2:
+                x86emu_fpu_M_fst(X86EMU_FPU_FLOAT, destoffset);
+                break;
+            case 3:
+                x86emu_fpu_M_fstp(X86EMU_FPU_FLOAT, destoffset);
+                break;
+            case 4:
+                x86emu_fpu_M_fldenv(X86EMU_FPU_WORD, destoffset);
+                break;
+            case 5:
+                x86emu_fpu_M_fldcw(X86EMU_FPU_WORD, destoffset);
+                break;
+            case 6:
+                x86emu_fpu_M_fstenv(X86EMU_FPU_WORD, destoffset);
+                break;
+            case 7:
+                x86emu_fpu_M_fstcw(X86EMU_FPU_WORD, destoffset);
+                break;
+            }
+        }
+    }
+#else
+    (void) destoffset;
+    (void) stkelem;
+#endif                          /* X86EMU_FPU_PRESENT */
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR_NO_TRACE();
+}
+
+#ifdef DEBUG
+
+static const char *x86emu_fpu_op_da_tab[] = {
+    "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
+    "FICOMP\tDWORD PTR ",
+    "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
+    "FIDIVR\tDWORD PTR ",
+
+    "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
+    "FICOMP\tDWORD PTR ",
+    "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
+    "FIDIVR\tDWORD PTR ",
+
+    "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
+    "FICOMP\tDWORD PTR ",
+    "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
+    "FIDIVR\tDWORD PTR ",
+
+    "ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ",
+    "ESC_DA     ", "ESC_DA ", "ESC_DA   ", "ESC_DA ",
+};
+
+#endif                          /* DEBUG */
+
+/* opcode=0xda */
+void
+x86emuOp_esc_coprocess_da(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset = 0;
+    u8 stkelem = 0;
+
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    DECODE_PRINTINSTR32(x86emu_fpu_op_da_tab, mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF("\n");
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF("\n");
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF("\n");
+        break;
+    case 3:                    /* register to register */
+        stkelem = (u8) rl;
+        DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
+        break;
+    }
+#ifdef X86EMU_FPU_PRESENT
+    switch (mod) {
+    case 3:
+        x86emu_fpu_illegal();
+        break;
+    default:
+        switch (rh) {
+        case 0:
+            x86emu_fpu_M_iadd(X86EMU_FPU_SHORT, destoffset);
+            break;
+        case 1:
+            x86emu_fpu_M_imul(X86EMU_FPU_SHORT, destoffset);
+            break;
+        case 2:
+            x86emu_fpu_M_icom(X86EMU_FPU_SHORT, destoffset);
+            break;
+        case 3:
+            x86emu_fpu_M_icomp(X86EMU_FPU_SHORT, destoffset);
+            break;
+        case 4:
+            x86emu_fpu_M_isub(X86EMU_FPU_SHORT, destoffset);
+            break;
+        case 5:
+            x86emu_fpu_M_isubr(X86EMU_FPU_SHORT, destoffset);
+            break;
+        case 6:
+            x86emu_fpu_M_idiv(X86EMU_FPU_SHORT, destoffset);
+            break;
+        case 7:
+            x86emu_fpu_M_idivr(X86EMU_FPU_SHORT, destoffset);
+            break;
+        }
+    }
+#else
+    (void) destoffset;
+    (void) stkelem;
+#endif
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR_NO_TRACE();
+}
+
+#ifdef DEBUG
+
+static const char *x86emu_fpu_op_db_tab[] = {
+    "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
+    "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
+
+    "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
+    "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
+
+    "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
+    "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
+};
+
+#endif                          /* DEBUG */
+
+/* opcode=0xdb */
+void
+x86emuOp_esc_coprocess_db(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset = 0;
+
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+#ifdef DEBUG
+    if (mod != 3) {
+        DECODE_PRINTINSTR32(x86emu_fpu_op_db_tab, mod, rh, rl);
+    }
+    else if (rh == 4) {         /* === 11 10 0 nnn */
+        switch (rl) {
+        case 0:
+            DECODE_PRINTF("FENI\n");
+            break;
+        case 1:
+            DECODE_PRINTF("FDISI\n");
+            break;
+        case 2:
+            DECODE_PRINTF("FCLEX\n");
+            break;
+        case 3:
+            DECODE_PRINTF("FINIT\n");
+            break;
+        }
+    }
+    else {
+        DECODE_PRINTF2("ESC_DB %0x\n", (mod << 6) + (rh << 3) + (rl));
+    }
+#endif                          /* DEBUG */
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        break;
+    case 3:                    /* register to register */
+        break;
+    }
+#ifdef X86EMU_FPU_PRESENT
+    /* execute */
+    switch (mod) {
+    case 3:
+        switch (rh) {
+        case 4:
+            switch (rl) {
+            case 0:
+                x86emu_fpu_R_feni();
+                break;
+            case 1:
+                x86emu_fpu_R_fdisi();
+                break;
+            case 2:
+                x86emu_fpu_R_fclex();
+                break;
+            case 3:
+                x86emu_fpu_R_finit();
+                break;
+            default:
+                x86emu_fpu_illegal();
+                break;
+            }
+            break;
+        default:
+            x86emu_fpu_illegal();
+            break;
+        }
+        break;
+    default:
+        switch (rh) {
+        case 0:
+            x86emu_fpu_M_fild(X86EMU_FPU_SHORT, destoffset);
+            break;
+        case 1:
+            x86emu_fpu_illegal();
+            break;
+        case 2:
+            x86emu_fpu_M_fist(X86EMU_FPU_SHORT, destoffset);
+            break;
+        case 3:
+            x86emu_fpu_M_fistp(X86EMU_FPU_SHORT, destoffset);
+            break;
+        case 4:
+            x86emu_fpu_illegal();
+            break;
+        case 5:
+            x86emu_fpu_M_fld(X86EMU_FPU_LDBL, destoffset);
+            break;
+        case 6:
+            x86emu_fpu_illegal();
+            break;
+        case 7:
+            x86emu_fpu_M_fstp(X86EMU_FPU_LDBL, destoffset);
+            break;
+        }
+    }
+#else
+    (void) destoffset;
+#endif
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR_NO_TRACE();
+}
+
+#ifdef DEBUG
+static const char *x86emu_fpu_op_dc_tab[] = {
+    "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
+    "FCOMP\tQWORD PTR ",
+    "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
+    "FDIVR\tQWORD PTR ",
+
+    "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
+    "FCOMP\tQWORD PTR ",
+    "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
+    "FDIVR\tQWORD PTR ",
+
+    "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
+    "FCOMP\tQWORD PTR ",
+    "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
+    "FDIVR\tQWORD PTR ",
+
+    "FADD\t", "FMUL\t", "FCOM\t", "FCOMP\t",
+    "FSUBR\t", "FSUB\t", "FDIVR\t", "FDIV\t",
+};
+#endif                          /* DEBUG */
+
+/* opcode=0xdc */
+void
+x86emuOp_esc_coprocess_dc(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset = 0;
+    u8 stkelem = 0;
+
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    DECODE_PRINTINSTR32(x86emu_fpu_op_dc_tab, mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF("\n");
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF("\n");
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF("\n");
+        break;
+    case 3:                    /* register to register */
+        stkelem = (u8) rl;
+        DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
+        break;
+    }
+#ifdef X86EMU_FPU_PRESENT
+    /* execute */
+    switch (mod) {
+    case 3:
+        switch (rh) {
+        case 0:
+            x86emu_fpu_R_fadd(stkelem, X86EMU_FPU_STKTOP);
+            break;
+        case 1:
+            x86emu_fpu_R_fmul(stkelem, X86EMU_FPU_STKTOP);
+            break;
+        case 2:
+            x86emu_fpu_R_fcom(stkelem, X86EMU_FPU_STKTOP);
+            break;
+        case 3:
+            x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
+            break;
+        case 4:
+            x86emu_fpu_R_fsubr(stkelem, X86EMU_FPU_STKTOP);
+            break;
+        case 5:
+            x86emu_fpu_R_fsub(stkelem, X86EMU_FPU_STKTOP);
+            break;
+        case 6:
+            x86emu_fpu_R_fdivr(stkelem, X86EMU_FPU_STKTOP);
+            break;
+        case 7:
+            x86emu_fpu_R_fdiv(stkelem, X86EMU_FPU_STKTOP);
+            break;
+        }
+        break;
+    default:
+        switch (rh) {
+        case 0:
+            x86emu_fpu_M_fadd(X86EMU_FPU_DOUBLE, destoffset);
+            break;
+        case 1:
+            x86emu_fpu_M_fmul(X86EMU_FPU_DOUBLE, destoffset);
+            break;
+        case 2:
+            x86emu_fpu_M_fcom(X86EMU_FPU_DOUBLE, destoffset);
+            break;
+        case 3:
+            x86emu_fpu_M_fcomp(X86EMU_FPU_DOUBLE, destoffset);
+            break;
+        case 4:
+            x86emu_fpu_M_fsub(X86EMU_FPU_DOUBLE, destoffset);
+            break;
+        case 5:
+            x86emu_fpu_M_fsubr(X86EMU_FPU_DOUBLE, destoffset);
+            break;
+        case 6:
+            x86emu_fpu_M_fdiv(X86EMU_FPU_DOUBLE, destoffset);
+            break;
+        case 7:
+            x86emu_fpu_M_fdivr(X86EMU_FPU_DOUBLE, destoffset);
+            break;
+        }
+    }
+#else
+    (void) destoffset;
+    (void) stkelem;
+#endif
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR_NO_TRACE();
+}
+
+#ifdef DEBUG
+
+static const char *x86emu_fpu_op_dd_tab[] = {
+    "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
+    "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
+
+    "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
+    "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
+
+    "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
+    "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
+
+    "FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
+    "ESC_DD\t2C,", "ESC_DD\t2D,", "ESC_DD\t2E,", "ESC_DD\t2F,",
+};
+
+#endif                          /* DEBUG */
+
+/* opcode=0xdd */
+void
+x86emuOp_esc_coprocess_dd(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset = 0;
+    u8 stkelem = 0;
+
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    DECODE_PRINTINSTR32(x86emu_fpu_op_dd_tab, mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF("\n");
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF("\n");
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF("\n");
+        break;
+    case 3:                    /* register to register */
+        stkelem = (u8) rl;
+        DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
+        break;
+    }
+#ifdef X86EMU_FPU_PRESENT
+    switch (mod) {
+    case 3:
+        switch (rh) {
+        case 0:
+            x86emu_fpu_R_ffree(stkelem);
+            break;
+        case 1:
+            x86emu_fpu_R_fxch(stkelem);
+            break;
+        case 2:
+            x86emu_fpu_R_fst(stkelem);  /* register version */
+            break;
+        case 3:
+            x86emu_fpu_R_fstp(stkelem); /* register version */
+            break;
+        default:
+            x86emu_fpu_illegal();
+            break;
+        }
+        break;
+    default:
+        switch (rh) {
+        case 0:
+            x86emu_fpu_M_fld(X86EMU_FPU_DOUBLE, destoffset);
+            break;
+        case 1:
+            x86emu_fpu_illegal();
+            break;
+        case 2:
+            x86emu_fpu_M_fst(X86EMU_FPU_DOUBLE, destoffset);
+            break;
+        case 3:
+            x86emu_fpu_M_fstp(X86EMU_FPU_DOUBLE, destoffset);
+            break;
+        case 4:
+            x86emu_fpu_M_frstor(X86EMU_FPU_WORD, destoffset);
+            break;
+        case 5:
+            x86emu_fpu_illegal();
+            break;
+        case 6:
+            x86emu_fpu_M_fsave(X86EMU_FPU_WORD, destoffset);
+            break;
+        case 7:
+            x86emu_fpu_M_fstsw(X86EMU_FPU_WORD, destoffset);
+            break;
+        }
+    }
+#else
+    (void) destoffset;
+    (void) stkelem;
+#endif
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR_NO_TRACE();
+}
+
+#ifdef DEBUG
+
+static const char *x86emu_fpu_op_de_tab[] = {
+    "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
+    "FICOMP\tWORD PTR ",
+    "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
+    "FIDIVR\tWORD PTR ",
+
+    "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
+    "FICOMP\tWORD PTR ",
+    "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
+    "FIDIVR\tWORD PTR ",
+
+    "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
+    "FICOMP\tWORD PTR ",
+    "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
+    "FIDIVR\tWORD PTR ",
+
+    "FADDP\t", "FMULP\t", "FCOMP\t", "FCOMPP\t",
+    "FSUBRP\t", "FSUBP\t", "FDIVRP\t", "FDIVP\t",
+};
+
+#endif                          /* DEBUG */
+
+/* opcode=0xde */
+void
+x86emuOp_esc_coprocess_de(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset = 0;
+    u8 stkelem = 0;
+
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    DECODE_PRINTINSTR32(x86emu_fpu_op_de_tab, mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF("\n");
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF("\n");
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF("\n");
+        break;
+    case 3:                    /* register to register */
+        stkelem = (u8) rl;
+        DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
+        break;
+    }
+#ifdef X86EMU_FPU_PRESENT
+    switch (mod) {
+    case 3:
+        switch (rh) {
+        case 0:
+            x86emu_fpu_R_faddp(stkelem, X86EMU_FPU_STKTOP);
+            break;
+        case 1:
+            x86emu_fpu_R_fmulp(stkelem, X86EMU_FPU_STKTOP);
+            break;
+        case 2:
+            x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
+            break;
+        case 3:
+            if (stkelem == 1)
+                x86emu_fpu_R_fcompp(stkelem, X86EMU_FPU_STKTOP);
+            else
+                x86emu_fpu_illegal();
+            break;
+        case 4:
+            x86emu_fpu_R_fsubrp(stkelem, X86EMU_FPU_STKTOP);
+            break;
+        case 5:
+            x86emu_fpu_R_fsubp(stkelem, X86EMU_FPU_STKTOP);
+            break;
+        case 6:
+            x86emu_fpu_R_fdivrp(stkelem, X86EMU_FPU_STKTOP);
+            break;
+        case 7:
+            x86emu_fpu_R_fdivp(stkelem, X86EMU_FPU_STKTOP);
+            break;
+        }
+        break;
+    default:
+        switch (rh) {
+        case 0:
+            x86emu_fpu_M_fiadd(X86EMU_FPU_WORD, destoffset);
+            break;
+        case 1:
+            x86emu_fpu_M_fimul(X86EMU_FPU_WORD, destoffset);
+            break;
+        case 2:
+            x86emu_fpu_M_ficom(X86EMU_FPU_WORD, destoffset);
+            break;
+        case 3:
+            x86emu_fpu_M_ficomp(X86EMU_FPU_WORD, destoffset);
+            break;
+        case 4:
+            x86emu_fpu_M_fisub(X86EMU_FPU_WORD, destoffset);
+            break;
+        case 5:
+            x86emu_fpu_M_fisubr(X86EMU_FPU_WORD, destoffset);
+            break;
+        case 6:
+            x86emu_fpu_M_fidiv(X86EMU_FPU_WORD, destoffset);
+            break;
+        case 7:
+            x86emu_fpu_M_fidivr(X86EMU_FPU_WORD, destoffset);
+            break;
+        }
+    }
+#else
+    (void) destoffset;
+    (void) stkelem;
+#endif
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR_NO_TRACE();
+}
+
+#ifdef DEBUG
+
+static const char *x86emu_fpu_op_df_tab[] = {
+    /* mod == 00 */
+    "FILD\tWORD PTR ", "ESC_DF\t39\n", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
+    "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
+    "FISTP\tQWORD PTR ",
+
+    /* mod == 01 */
+    "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
+    "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
+    "FISTP\tQWORD PTR ",
+
+    /* mod == 10 */
+    "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
+    "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
+    "FISTP\tQWORD PTR ",
+
+    /* mod == 11 */
+    "FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
+    "ESC_DF\t3C,", "ESC_DF\t3D,", "ESC_DF\t3E,", "ESC_DF\t3F,"
+};
+
+#endif                          /* DEBUG */
+
+/* opcode=0xdf */
+void
+x86emuOp_esc_coprocess_df(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset = 0;
+    u8 stkelem = 0;
+
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    DECODE_PRINTINSTR32(x86emu_fpu_op_df_tab, mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF("\n");
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF("\n");
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF("\n");
+        break;
+    case 3:                    /* register to register */
+        stkelem = (u8) rl;
+        DECODE_PRINTF2("\tST(%d)\n", stkelem);
+        break;
+    }
+#ifdef X86EMU_FPU_PRESENT
+    switch (mod) {
+    case 3:
+        switch (rh) {
+        case 0:
+            x86emu_fpu_R_ffree(stkelem);
+            break;
+        case 1:
+            x86emu_fpu_R_fxch(stkelem);
+            break;
+        case 2:
+            x86emu_fpu_R_fst(stkelem);  /* register version */
+            break;
+        case 3:
+            x86emu_fpu_R_fstp(stkelem); /* register version */
+            break;
+        default:
+            x86emu_fpu_illegal();
+            break;
+        }
+        break;
+    default:
+        switch (rh) {
+        case 0:
+            x86emu_fpu_M_fild(X86EMU_FPU_WORD, destoffset);
+            break;
+        case 1:
+            x86emu_fpu_illegal();
+            break;
+        case 2:
+            x86emu_fpu_M_fist(X86EMU_FPU_WORD, destoffset);
+            break;
+        case 3:
+            x86emu_fpu_M_fistp(X86EMU_FPU_WORD, destoffset);
+            break;
+        case 4:
+            x86emu_fpu_M_fbld(X86EMU_FPU_BSD, destoffset);
+            break;
+        case 5:
+            x86emu_fpu_M_fild(X86EMU_FPU_LONG, destoffset);
+            break;
+        case 6:
+            x86emu_fpu_M_fbstp(X86EMU_FPU_BSD, destoffset);
+            break;
+        case 7:
+            x86emu_fpu_M_fistp(X86EMU_FPU_LONG, destoffset);
+            break;
+        }
+    }
+#else
+    (void) destoffset;
+    (void) stkelem;
+#endif
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR_NO_TRACE();
+}
diff --git a/plat/pc65oo2/emu/x86emu/meson.build b/plat/pc65oo2/emu/x86emu/meson.build
new file mode 100644
index 000000000..4846da99d
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/meson.build
@@ -0,0 +1,15 @@
+srcs_xorg_x86emu = [
+    'debug.c',
+    'decode.c',
+    'fpu.c',
+    'ops2.c',
+    'ops.c',
+    'prim_ops.c',
+    'sys.c',
+]
+
+xorg_x86emu = static_library('x86emu',
+    srcs_xorg_x86emu,
+    include_directories: [inc, xorg_inc],
+    dependencies: common_dep,
+)
diff --git a/plat/pc65oo2/emu/x86emu/ops.c b/plat/pc65oo2/emu/x86emu/ops.c
new file mode 100644
index 000000000..210f8ce64
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/ops.c
@@ -0,0 +1,12399 @@
+/****************************************************************************
+*
+*						Realmode X86 Emulator Library
+*
+*            	Copyright (C) 1996-1999 SciTech Software, Inc.
+* 				     Copyright (C) David Mosberger-Tang
+* 					   Copyright (C) 1999 Egbert Eich
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:		ANSI C
+* Environment:	Any
+* Developer:    Kendall Bennett
+*
+* Description:  This file includes subroutines to implement the decoding
+*               and emulation of all the x86 processor instructions.
+*
+* There are approximately 250 subroutines in here, which correspond
+* to the 256 byte-"opcodes" found on the 8086.  The table which
+* dispatches this is found in the files optab.[ch].
+*
+* Each opcode proc has a comment preceeding it which gives it's table
+* address.  Several opcodes are missing (undefined) in the table.
+*
+* Each proc includes information for decoding (DECODE_PRINTF and
+* DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc
+* functions (START_OF_INSTR, END_OF_INSTR).
+*
+* Many of the procedures are *VERY* similar in coding.  This has
+* allowed for a very large amount of code to be generated in a fairly
+* short amount of time (i.e. cut, paste, and modify).  The result is
+* that much of the code below could have been folded into subroutines
+* for a large reduction in size of this file.  The downside would be
+* that there would be a penalty in execution speed.  The file could
+* also have been *MUCH* larger by inlining certain functions which
+* were called.  This could have resulted even faster execution.  The
+* prime directive I used to decide whether to inline the code or to
+* modularize it, was basically: 1) no unnecessary subroutine calls,
+* 2) no routines more than about 200 lines in size, and 3) modularize
+* any code that I might not get right the first time.  The fetch_*
+* subroutines fall into the latter category.  The The decode_* fall
+* into the second category.  The coding of the "switch(mod){ .... }"
+* in many of the subroutines below falls into the first category.
+* Especially, the coding of {add,and,or,sub,...}_{byte,word}
+* subroutines are an especially glaring case of the third guideline.
+* Since so much of the code is cloned from other modules (compare
+* opcode #00 to opcode #01), making the basic operations subroutine
+* calls is especially important; otherwise mistakes in coding an
+* "add" would represent a nightmare in maintenance.
+*
+****************************************************************************/
+
+#include "x86emu/x86emui.h"
+
+/*----------------------------- Implementation ----------------------------*/
+
+/****************************************************************************
+PARAMETERS:
+op1 - Instruction op code
+
+REMARKS:
+Handles illegal opcodes.
+****************************************************************************/
+static void
+x86emuOp_illegal_op(u8 op1)
+{
+    START_OF_INSTR();
+    if (M.x86.R_SP != 0) {
+        DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
+        TRACE_REGS();
+        DB(printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
+                  M.x86.R_CS, M.x86.R_IP - 1, op1));
+        HALT_SYS();
+    }
+    else {
+        /* If we get here, it means the stack pointer is back to zero
+         * so we are just returning from an emulator service call
+         * so therte is no need to display an error message. We trap
+         * the emulator with an 0xF1 opcode to finish the service
+         * call.
+         */
+        X86EMU_halt_sys();
+    }
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x00
+****************************************************************************/
+static void
+x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+    u8 *destreg, *srcreg;
+    u8 destval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("ADD\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = add_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = add_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = add_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = add_byte(*destreg, *srcreg);
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x01
+****************************************************************************/
+static void
+x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("ADD\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = add_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = add_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = add_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = add_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = add_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = add_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = add_long(*destreg, *srcreg);
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = add_word(*destreg, *srcreg);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x02
+****************************************************************************/
+static void
+x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg, *srcreg;
+    uint srcoffset;
+    u8 srcval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("ADD\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm00_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = add_byte(*destreg, srcval);
+        break;
+    case 1:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm01_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = add_byte(*destreg, srcval);
+        break;
+    case 2:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm10_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = add_byte(*destreg, srcval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = add_byte(*destreg, *srcreg);
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x03
+****************************************************************************/
+static void
+x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("ADD\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = add_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = add_word(*destreg, srcval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = add_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = add_word(*destreg, srcval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = add_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = add_word(*destreg, srcval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = add_long(*destreg, *srcreg);
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = add_word(*destreg, *srcreg);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x04
+****************************************************************************/
+static void
+x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 srcval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("ADD\tAL,");
+    srcval = fetch_byte_imm();
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    M.x86.R_AL = add_byte(M.x86.R_AL, srcval);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x05
+****************************************************************************/
+static void
+x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 srcval;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("ADD\tEAX,");
+        srcval = fetch_long_imm();
+    }
+    else {
+        DECODE_PRINTF("ADD\tAX,");
+        srcval = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EAX = add_long(M.x86.R_EAX, srcval);
+    }
+    else {
+        M.x86.R_AX = add_word(M.x86.R_AX, (u16) srcval);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x06
+****************************************************************************/
+static void
+x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("PUSH\tES\n");
+    TRACE_AND_STEP();
+    push_word(M.x86.R_ES);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x07
+****************************************************************************/
+static void
+x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("POP\tES\n");
+    TRACE_AND_STEP();
+    M.x86.R_ES = pop_word();
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x08
+****************************************************************************/
+static void
+x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg, *srcreg;
+    uint destoffset;
+    u8 destval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("OR\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = or_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = or_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = or_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = or_byte(*destreg, *srcreg);
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x09
+****************************************************************************/
+static void
+x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("OR\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = or_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = or_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = or_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = or_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = or_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = or_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = or_long(*destreg, *srcreg);
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = or_word(*destreg, *srcreg);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0a
+****************************************************************************/
+static void
+x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg, *srcreg;
+    uint srcoffset;
+    u8 srcval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("OR\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm00_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = or_byte(*destreg, srcval);
+        break;
+    case 1:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm01_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = or_byte(*destreg, srcval);
+        break;
+    case 2:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm10_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = or_byte(*destreg, srcval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = or_byte(*destreg, *srcreg);
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0b
+****************************************************************************/
+static void
+x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("OR\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = or_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = or_word(*destreg, srcval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = or_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = or_word(*destreg, srcval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = or_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = or_word(*destreg, srcval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = or_long(*destreg, *srcreg);
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = or_word(*destreg, *srcreg);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0c
+****************************************************************************/
+static void
+x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 srcval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("OR\tAL,");
+    srcval = fetch_byte_imm();
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    M.x86.R_AL = or_byte(M.x86.R_AL, srcval);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0d
+****************************************************************************/
+static void
+x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 srcval;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("OR\tEAX,");
+        srcval = fetch_long_imm();
+    }
+    else {
+        DECODE_PRINTF("OR\tAX,");
+        srcval = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EAX = or_long(M.x86.R_EAX, srcval);
+    }
+    else {
+        M.x86.R_AX = or_word(M.x86.R_AX, (u16) srcval);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0e
+****************************************************************************/
+static void
+x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("PUSH\tCS\n");
+    TRACE_AND_STEP();
+    push_word(M.x86.R_CS);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
+****************************************************************************/
+static void
+x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
+{
+    u8 op2 = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
+
+    INC_DECODED_INST_LEN(1);
+    (*x86emu_optab2[op2]) (op2);
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x10
+****************************************************************************/
+static void
+x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg, *srcreg;
+    uint destoffset;
+    u8 destval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("ADC\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = adc_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = adc_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = adc_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = adc_byte(*destreg, *srcreg);
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x11
+****************************************************************************/
+static void
+x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("ADC\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = adc_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = adc_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = adc_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = adc_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = adc_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = adc_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = adc_long(*destreg, *srcreg);
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = adc_word(*destreg, *srcreg);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x12
+****************************************************************************/
+static void
+x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg, *srcreg;
+    uint srcoffset;
+    u8 srcval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("ADC\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm00_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = adc_byte(*destreg, srcval);
+        break;
+    case 1:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm01_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = adc_byte(*destreg, srcval);
+        break;
+    case 2:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm10_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = adc_byte(*destreg, srcval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = adc_byte(*destreg, *srcreg);
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x13
+****************************************************************************/
+static void
+x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("ADC\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = adc_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = adc_word(*destreg, srcval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = adc_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = adc_word(*destreg, srcval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = adc_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = adc_word(*destreg, srcval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = adc_long(*destreg, *srcreg);
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = adc_word(*destreg, *srcreg);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x14
+****************************************************************************/
+static void
+x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 srcval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("ADC\tAL,");
+    srcval = fetch_byte_imm();
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    M.x86.R_AL = adc_byte(M.x86.R_AL, srcval);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x15
+****************************************************************************/
+static void
+x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 srcval;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("ADC\tEAX,");
+        srcval = fetch_long_imm();
+    }
+    else {
+        DECODE_PRINTF("ADC\tAX,");
+        srcval = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval);
+    }
+    else {
+        M.x86.R_AX = adc_word(M.x86.R_AX, (u16) srcval);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x16
+****************************************************************************/
+static void
+x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("PUSH\tSS\n");
+    TRACE_AND_STEP();
+    push_word(M.x86.R_SS);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x17
+****************************************************************************/
+static void
+x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("POP\tSS\n");
+    TRACE_AND_STEP();
+    M.x86.R_SS = pop_word();
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x18
+****************************************************************************/
+static void
+x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg, *srcreg;
+    uint destoffset;
+    u8 destval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("SBB\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = sbb_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = sbb_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = sbb_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = sbb_byte(*destreg, *srcreg);
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x19
+****************************************************************************/
+static void
+x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("SBB\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = sbb_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = sbb_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = sbb_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = sbb_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = sbb_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = sbb_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sbb_long(*destreg, *srcreg);
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sbb_word(*destreg, *srcreg);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x1a
+****************************************************************************/
+static void
+x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg, *srcreg;
+    uint srcoffset;
+    u8 srcval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("SBB\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm00_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = sbb_byte(*destreg, srcval);
+        break;
+    case 1:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm01_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = sbb_byte(*destreg, srcval);
+        break;
+    case 2:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm10_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = sbb_byte(*destreg, srcval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = sbb_byte(*destreg, *srcreg);
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x1b
+****************************************************************************/
+static void
+x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("SBB\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sbb_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sbb_word(*destreg, srcval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sbb_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sbb_word(*destreg, srcval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sbb_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sbb_word(*destreg, srcval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sbb_long(*destreg, *srcreg);
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sbb_word(*destreg, *srcreg);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x1c
+****************************************************************************/
+static void
+x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 srcval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("SBB\tAL,");
+    srcval = fetch_byte_imm();
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x1d
+****************************************************************************/
+static void
+x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 srcval;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("SBB\tEAX,");
+        srcval = fetch_long_imm();
+    }
+    else {
+        DECODE_PRINTF("SBB\tAX,");
+        srcval = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval);
+    }
+    else {
+        M.x86.R_AX = sbb_word(M.x86.R_AX, (u16) srcval);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x1e
+****************************************************************************/
+static void
+x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("PUSH\tDS\n");
+    TRACE_AND_STEP();
+    push_word(M.x86.R_DS);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x1f
+****************************************************************************/
+static void
+x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("POP\tDS\n");
+    TRACE_AND_STEP();
+    M.x86.R_DS = pop_word();
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x20
+****************************************************************************/
+static void
+x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg, *srcreg;
+    uint destoffset;
+    u8 destval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("AND\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = and_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = and_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = and_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = and_byte(*destreg, *srcreg);
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x21
+****************************************************************************/
+static void
+x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("AND\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = and_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = and_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = and_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = and_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = and_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = and_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = and_long(*destreg, *srcreg);
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = and_word(*destreg, *srcreg);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x22
+****************************************************************************/
+static void
+x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg, *srcreg;
+    uint srcoffset;
+    u8 srcval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("AND\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm00_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = and_byte(*destreg, srcval);
+        break;
+    case 1:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm01_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = and_byte(*destreg, srcval);
+        break;
+    case 2:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm10_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = and_byte(*destreg, srcval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = and_byte(*destreg, *srcreg);
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x23
+****************************************************************************/
+static void
+x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("AND\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = and_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = and_word(*destreg, srcval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = and_long(*destreg, srcval);
+            break;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = and_word(*destreg, srcval);
+            break;
+        }
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = and_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = and_word(*destreg, srcval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = and_long(*destreg, *srcreg);
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = and_word(*destreg, *srcreg);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x24
+****************************************************************************/
+static void
+x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 srcval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("AND\tAL,");
+    srcval = fetch_byte_imm();
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    M.x86.R_AL = and_byte(M.x86.R_AL, srcval);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x25
+****************************************************************************/
+static void
+x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 srcval;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("AND\tEAX,");
+        srcval = fetch_long_imm();
+    }
+    else {
+        DECODE_PRINTF("AND\tAX,");
+        srcval = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EAX = and_long(M.x86.R_EAX, srcval);
+    }
+    else {
+        M.x86.R_AX = and_word(M.x86.R_AX, (u16) srcval);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x26
+****************************************************************************/
+static void
+x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("ES:\n");
+    TRACE_AND_STEP();
+    M.x86.mode |= SYSMODE_SEGOVR_ES;
+    /*
+     * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
+     * opcode subroutines we do not want to do this.
+     */
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x27
+****************************************************************************/
+static void
+x86emuOp_daa(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("DAA\n");
+    TRACE_AND_STEP();
+    M.x86.R_AL = daa_byte(M.x86.R_AL);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x28
+****************************************************************************/
+static void
+x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg, *srcreg;
+    uint destoffset;
+    u8 destval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("SUB\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = sub_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = sub_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = sub_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = sub_byte(*destreg, *srcreg);
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x29
+****************************************************************************/
+static void
+x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("SUB\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = sub_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = sub_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = sub_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = sub_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = sub_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = sub_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sub_long(*destreg, *srcreg);
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sub_word(*destreg, *srcreg);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x2a
+****************************************************************************/
+static void
+x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg, *srcreg;
+    uint srcoffset;
+    u8 srcval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("SUB\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm00_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = sub_byte(*destreg, srcval);
+        break;
+    case 1:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm01_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = sub_byte(*destreg, srcval);
+        break;
+    case 2:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm10_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = sub_byte(*destreg, srcval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = sub_byte(*destreg, *srcreg);
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x2b
+****************************************************************************/
+static void
+x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("SUB\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sub_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sub_word(*destreg, srcval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sub_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sub_word(*destreg, srcval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sub_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sub_word(*destreg, srcval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sub_long(*destreg, *srcreg);
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = sub_word(*destreg, *srcreg);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x2c
+****************************************************************************/
+static void
+x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 srcval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("SUB\tAL,");
+    srcval = fetch_byte_imm();
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    M.x86.R_AL = sub_byte(M.x86.R_AL, srcval);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x2d
+****************************************************************************/
+static void
+x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 srcval;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("SUB\tEAX,");
+        srcval = fetch_long_imm();
+    }
+    else {
+        DECODE_PRINTF("SUB\tAX,");
+        srcval = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval);
+    }
+    else {
+        M.x86.R_AX = sub_word(M.x86.R_AX, (u16) srcval);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x2e
+****************************************************************************/
+static void
+x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("CS:\n");
+    TRACE_AND_STEP();
+    M.x86.mode |= SYSMODE_SEGOVR_CS;
+    /* note no DECODE_CLEAR_SEGOVR here. */
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x2f
+****************************************************************************/
+static void
+x86emuOp_das(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("DAS\n");
+    TRACE_AND_STEP();
+    M.x86.R_AL = das_byte(M.x86.R_AL);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x30
+****************************************************************************/
+static void
+x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg, *srcreg;
+    uint destoffset;
+    u8 destval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("XOR\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = xor_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = xor_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = xor_byte(destval, *srcreg);
+        store_data_byte(destoffset, destval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = xor_byte(*destreg, *srcreg);
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x31
+****************************************************************************/
+static void
+x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("XOR\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = xor_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = xor_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = xor_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = xor_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = xor_long(destval, *srcreg);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = xor_word(destval, *srcreg);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = xor_long(*destreg, *srcreg);
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = xor_word(*destreg, *srcreg);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x32
+****************************************************************************/
+static void
+x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg, *srcreg;
+    uint srcoffset;
+    u8 srcval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("XOR\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm00_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = xor_byte(*destreg, srcval);
+        break;
+    case 1:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm01_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = xor_byte(*destreg, srcval);
+        break;
+    case 2:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm10_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = xor_byte(*destreg, srcval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = xor_byte(*destreg, *srcreg);
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x33
+****************************************************************************/
+static void
+x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("XOR\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = xor_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = xor_word(*destreg, srcval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = xor_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = xor_word(*destreg, srcval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = xor_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = xor_word(*destreg, srcval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = xor_long(*destreg, *srcreg);
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = xor_word(*destreg, *srcreg);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x34
+****************************************************************************/
+static void
+x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 srcval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("XOR\tAL,");
+    srcval = fetch_byte_imm();
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    M.x86.R_AL = xor_byte(M.x86.R_AL, srcval);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x35
+****************************************************************************/
+static void
+x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 srcval;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("XOR\tEAX,");
+        srcval = fetch_long_imm();
+    }
+    else {
+        DECODE_PRINTF("XOR\tAX,");
+        srcval = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval);
+    }
+    else {
+        M.x86.R_AX = xor_word(M.x86.R_AX, (u16) srcval);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x36
+****************************************************************************/
+static void
+x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("SS:\n");
+    TRACE_AND_STEP();
+    M.x86.mode |= SYSMODE_SEGOVR_SS;
+    /* no DECODE_CLEAR_SEGOVR ! */
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x37
+****************************************************************************/
+static void
+x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("AAA\n");
+    TRACE_AND_STEP();
+    M.x86.R_AX = aaa_word(M.x86.R_AX);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x38
+****************************************************************************/
+static void
+x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+    u8 *destreg, *srcreg;
+    u8 destval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("CMP\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        cmp_byte(destval, *srcreg);
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        cmp_byte(destval, *srcreg);
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        cmp_byte(destval, *srcreg);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        cmp_byte(*destreg, *srcreg);
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x39
+****************************************************************************/
+static void
+x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("CMP\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            cmp_long(destval, *srcreg);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            cmp_word(destval, *srcreg);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            cmp_long(destval, *srcreg);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            cmp_word(destval, *srcreg);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            cmp_long(destval, *srcreg);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            cmp_word(destval, *srcreg);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            cmp_long(*destreg, *srcreg);
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            cmp_word(*destreg, *srcreg);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x3a
+****************************************************************************/
+static void
+x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg, *srcreg;
+    uint srcoffset;
+    u8 srcval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("CMP\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm00_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        cmp_byte(*destreg, srcval);
+        break;
+    case 1:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm01_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        cmp_byte(*destreg, srcval);
+        break;
+    case 2:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm10_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        cmp_byte(*destreg, srcval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        cmp_byte(*destreg, *srcreg);
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x3b
+****************************************************************************/
+static void
+x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("CMP\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            cmp_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            cmp_word(*destreg, srcval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            cmp_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            cmp_word(*destreg, srcval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            cmp_long(*destreg, srcval);
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            cmp_word(*destreg, srcval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            cmp_long(*destreg, *srcreg);
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            cmp_word(*destreg, *srcreg);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x3c
+****************************************************************************/
+static void
+x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 srcval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("CMP\tAL,");
+    srcval = fetch_byte_imm();
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    cmp_byte(M.x86.R_AL, srcval);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x3d
+****************************************************************************/
+static void
+x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 srcval;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("CMP\tEAX,");
+        srcval = fetch_long_imm();
+    }
+    else {
+        DECODE_PRINTF("CMP\tAX,");
+        srcval = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        cmp_long(M.x86.R_EAX, srcval);
+    }
+    else {
+        cmp_word(M.x86.R_AX, (u16) srcval);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x3e
+****************************************************************************/
+static void
+x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("DS:\n");
+    TRACE_AND_STEP();
+    M.x86.mode |= SYSMODE_SEGOVR_DS;
+    /* NO DECODE_CLEAR_SEGOVR! */
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x3f
+****************************************************************************/
+static void
+x86emuOp_aas(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("AAS\n");
+    TRACE_AND_STEP();
+    M.x86.R_AX = aas_word(M.x86.R_AX);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x40
+****************************************************************************/
+static void
+x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("INC\tEAX\n");
+    }
+    else {
+        DECODE_PRINTF("INC\tAX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EAX = inc_long(M.x86.R_EAX);
+    }
+    else {
+        M.x86.R_AX = inc_word(M.x86.R_AX);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x41
+****************************************************************************/
+static void
+x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("INC\tECX\n");
+    }
+    else {
+        DECODE_PRINTF("INC\tCX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_ECX = inc_long(M.x86.R_ECX);
+    }
+    else {
+        M.x86.R_CX = inc_word(M.x86.R_CX);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x42
+****************************************************************************/
+static void
+x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("INC\tEDX\n");
+    }
+    else {
+        DECODE_PRINTF("INC\tDX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EDX = inc_long(M.x86.R_EDX);
+    }
+    else {
+        M.x86.R_DX = inc_word(M.x86.R_DX);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x43
+****************************************************************************/
+static void
+x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("INC\tEBX\n");
+    }
+    else {
+        DECODE_PRINTF("INC\tBX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EBX = inc_long(M.x86.R_EBX);
+    }
+    else {
+        M.x86.R_BX = inc_word(M.x86.R_BX);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x44
+****************************************************************************/
+static void
+x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("INC\tESP\n");
+    }
+    else {
+        DECODE_PRINTF("INC\tSP\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_ESP = inc_long(M.x86.R_ESP);
+    }
+    else {
+        M.x86.R_SP = inc_word(M.x86.R_SP);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x45
+****************************************************************************/
+static void
+x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("INC\tEBP\n");
+    }
+    else {
+        DECODE_PRINTF("INC\tBP\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EBP = inc_long(M.x86.R_EBP);
+    }
+    else {
+        M.x86.R_BP = inc_word(M.x86.R_BP);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x46
+****************************************************************************/
+static void
+x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("INC\tESI\n");
+    }
+    else {
+        DECODE_PRINTF("INC\tSI\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_ESI = inc_long(M.x86.R_ESI);
+    }
+    else {
+        M.x86.R_SI = inc_word(M.x86.R_SI);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x47
+****************************************************************************/
+static void
+x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("INC\tEDI\n");
+    }
+    else {
+        DECODE_PRINTF("INC\tDI\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EDI = inc_long(M.x86.R_EDI);
+    }
+    else {
+        M.x86.R_DI = inc_word(M.x86.R_DI);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x48
+****************************************************************************/
+static void
+x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("DEC\tEAX\n");
+    }
+    else {
+        DECODE_PRINTF("DEC\tAX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EAX = dec_long(M.x86.R_EAX);
+    }
+    else {
+        M.x86.R_AX = dec_word(M.x86.R_AX);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x49
+****************************************************************************/
+static void
+x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("DEC\tECX\n");
+    }
+    else {
+        DECODE_PRINTF("DEC\tCX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_ECX = dec_long(M.x86.R_ECX);
+    }
+    else {
+        M.x86.R_CX = dec_word(M.x86.R_CX);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x4a
+****************************************************************************/
+static void
+x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("DEC\tEDX\n");
+    }
+    else {
+        DECODE_PRINTF("DEC\tDX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EDX = dec_long(M.x86.R_EDX);
+    }
+    else {
+        M.x86.R_DX = dec_word(M.x86.R_DX);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x4b
+****************************************************************************/
+static void
+x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("DEC\tEBX\n");
+    }
+    else {
+        DECODE_PRINTF("DEC\tBX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EBX = dec_long(M.x86.R_EBX);
+    }
+    else {
+        M.x86.R_BX = dec_word(M.x86.R_BX);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x4c
+****************************************************************************/
+static void
+x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("DEC\tESP\n");
+    }
+    else {
+        DECODE_PRINTF("DEC\tSP\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_ESP = dec_long(M.x86.R_ESP);
+    }
+    else {
+        M.x86.R_SP = dec_word(M.x86.R_SP);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x4d
+****************************************************************************/
+static void
+x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("DEC\tEBP\n");
+    }
+    else {
+        DECODE_PRINTF("DEC\tBP\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EBP = dec_long(M.x86.R_EBP);
+    }
+    else {
+        M.x86.R_BP = dec_word(M.x86.R_BP);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x4e
+****************************************************************************/
+static void
+x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("DEC\tESI\n");
+    }
+    else {
+        DECODE_PRINTF("DEC\tSI\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_ESI = dec_long(M.x86.R_ESI);
+    }
+    else {
+        M.x86.R_SI = dec_word(M.x86.R_SI);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x4f
+****************************************************************************/
+static void
+x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("DEC\tEDI\n");
+    }
+    else {
+        DECODE_PRINTF("DEC\tDI\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EDI = dec_long(M.x86.R_EDI);
+    }
+    else {
+        M.x86.R_DI = dec_word(M.x86.R_DI);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x50
+****************************************************************************/
+static void
+x86emuOp_push_AX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("PUSH\tEAX\n");
+    }
+    else {
+        DECODE_PRINTF("PUSH\tAX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        push_long(M.x86.R_EAX);
+    }
+    else {
+        push_word(M.x86.R_AX);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x51
+****************************************************************************/
+static void
+x86emuOp_push_CX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("PUSH\tECX\n");
+    }
+    else {
+        DECODE_PRINTF("PUSH\tCX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        push_long(M.x86.R_ECX);
+    }
+    else {
+        push_word(M.x86.R_CX);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x52
+****************************************************************************/
+static void
+x86emuOp_push_DX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("PUSH\tEDX\n");
+    }
+    else {
+        DECODE_PRINTF("PUSH\tDX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        push_long(M.x86.R_EDX);
+    }
+    else {
+        push_word(M.x86.R_DX);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x53
+****************************************************************************/
+static void
+x86emuOp_push_BX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("PUSH\tEBX\n");
+    }
+    else {
+        DECODE_PRINTF("PUSH\tBX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        push_long(M.x86.R_EBX);
+    }
+    else {
+        push_word(M.x86.R_BX);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x54
+****************************************************************************/
+static void
+x86emuOp_push_SP(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("PUSH\tESP\n");
+    }
+    else {
+        DECODE_PRINTF("PUSH\tSP\n");
+    }
+    TRACE_AND_STEP();
+    /* Always push (E)SP, since we are emulating an i386 and above
+     * processor. This is necessary as some BIOS'es use this to check
+     * what type of processor is in the system.
+     */
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        push_long(M.x86.R_ESP);
+    }
+    else {
+        push_word((u16) (M.x86.R_SP));
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x55
+****************************************************************************/
+static void
+x86emuOp_push_BP(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("PUSH\tEBP\n");
+    }
+    else {
+        DECODE_PRINTF("PUSH\tBP\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        push_long(M.x86.R_EBP);
+    }
+    else {
+        push_word(M.x86.R_BP);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x56
+****************************************************************************/
+static void
+x86emuOp_push_SI(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("PUSH\tESI\n");
+    }
+    else {
+        DECODE_PRINTF("PUSH\tSI\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        push_long(M.x86.R_ESI);
+    }
+    else {
+        push_word(M.x86.R_SI);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x57
+****************************************************************************/
+static void
+x86emuOp_push_DI(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("PUSH\tEDI\n");
+    }
+    else {
+        DECODE_PRINTF("PUSH\tDI\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        push_long(M.x86.R_EDI);
+    }
+    else {
+        push_word(M.x86.R_DI);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x58
+****************************************************************************/
+static void
+x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("POP\tEAX\n");
+    }
+    else {
+        DECODE_PRINTF("POP\tAX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EAX = pop_long();
+    }
+    else {
+        M.x86.R_AX = pop_word();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x59
+****************************************************************************/
+static void
+x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("POP\tECX\n");
+    }
+    else {
+        DECODE_PRINTF("POP\tCX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_ECX = pop_long();
+    }
+    else {
+        M.x86.R_CX = pop_word();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x5a
+****************************************************************************/
+static void
+x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("POP\tEDX\n");
+    }
+    else {
+        DECODE_PRINTF("POP\tDX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EDX = pop_long();
+    }
+    else {
+        M.x86.R_DX = pop_word();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x5b
+****************************************************************************/
+static void
+x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("POP\tEBX\n");
+    }
+    else {
+        DECODE_PRINTF("POP\tBX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EBX = pop_long();
+    }
+    else {
+        M.x86.R_BX = pop_word();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x5c
+****************************************************************************/
+static void
+x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("POP\tESP\n");
+    }
+    else {
+        DECODE_PRINTF("POP\tSP\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_ESP = pop_long();
+    }
+    else {
+        M.x86.R_SP = pop_word();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x5d
+****************************************************************************/
+static void
+x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("POP\tEBP\n");
+    }
+    else {
+        DECODE_PRINTF("POP\tBP\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EBP = pop_long();
+    }
+    else {
+        M.x86.R_BP = pop_word();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x5e
+****************************************************************************/
+static void
+x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("POP\tESI\n");
+    }
+    else {
+        DECODE_PRINTF("POP\tSI\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_ESI = pop_long();
+    }
+    else {
+        M.x86.R_SI = pop_word();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x5f
+****************************************************************************/
+static void
+x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("POP\tEDI\n");
+    }
+    else {
+        DECODE_PRINTF("POP\tDI\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EDI = pop_long();
+    }
+    else {
+        M.x86.R_DI = pop_word();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x60
+****************************************************************************/
+static void
+x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("PUSHAD\n");
+    }
+    else {
+        DECODE_PRINTF("PUSHA\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        u32 old_sp = M.x86.R_ESP;
+
+        push_long(M.x86.R_EAX);
+        push_long(M.x86.R_ECX);
+        push_long(M.x86.R_EDX);
+        push_long(M.x86.R_EBX);
+        push_long(old_sp);
+        push_long(M.x86.R_EBP);
+        push_long(M.x86.R_ESI);
+        push_long(M.x86.R_EDI);
+    }
+    else {
+        u16 old_sp = M.x86.R_SP;
+
+        push_word(M.x86.R_AX);
+        push_word(M.x86.R_CX);
+        push_word(M.x86.R_DX);
+        push_word(M.x86.R_BX);
+        push_word(old_sp);
+        push_word(M.x86.R_BP);
+        push_word(M.x86.R_SI);
+        push_word(M.x86.R_DI);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x61
+****************************************************************************/
+static void
+x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("POPAD\n");
+    }
+    else {
+        DECODE_PRINTF("POPA\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EDI = pop_long();
+        M.x86.R_ESI = pop_long();
+        M.x86.R_EBP = pop_long();
+        M.x86.R_ESP += 4;       /* skip ESP */
+        M.x86.R_EBX = pop_long();
+        M.x86.R_EDX = pop_long();
+        M.x86.R_ECX = pop_long();
+        M.x86.R_EAX = pop_long();
+    }
+    else {
+        M.x86.R_DI = pop_word();
+        M.x86.R_SI = pop_word();
+        M.x86.R_BP = pop_word();
+        M.x86.R_SP += 2;        /* skip SP */
+        M.x86.R_BX = pop_word();
+        M.x86.R_DX = pop_word();
+        M.x86.R_CX = pop_word();
+        M.x86.R_AX = pop_word();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/*opcode 0x62   ILLEGAL OP, calls x86emuOp_illegal_op() */
+/*opcode 0x63   ILLEGAL OP, calls x86emuOp_illegal_op() */
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x64
+****************************************************************************/
+static void
+x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("FS:\n");
+    TRACE_AND_STEP();
+    M.x86.mode |= SYSMODE_SEGOVR_FS;
+    /*
+     * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
+     * opcode subroutines we do not want to do this.
+     */
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x65
+****************************************************************************/
+static void
+x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("GS:\n");
+    TRACE_AND_STEP();
+    M.x86.mode |= SYSMODE_SEGOVR_GS;
+    /*
+     * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
+     * opcode subroutines we do not want to do this.
+     */
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x66 - prefix for 32-bit register
+****************************************************************************/
+static void
+x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("DATA:\n");
+    TRACE_AND_STEP();
+    M.x86.mode |= SYSMODE_PREFIX_DATA;
+    /* note no DECODE_CLEAR_SEGOVR here. */
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x67 - prefix for 32-bit address
+****************************************************************************/
+static void
+x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("ADDR:\n");
+    TRACE_AND_STEP();
+    M.x86.mode |= SYSMODE_PREFIX_ADDR;
+    /* note no DECODE_CLEAR_SEGOVR here. */
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x68
+****************************************************************************/
+static void
+x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 imm;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        imm = fetch_long_imm();
+    }
+    else {
+        imm = fetch_word_imm();
+    }
+    DECODE_PRINTF2("PUSH\t%x\n", imm);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        push_long(imm);
+    }
+    else {
+        push_word((u16) imm);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x69
+****************************************************************************/
+static void
+x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("IMUL\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+            u32 res_lo, res_hi;
+            s32 imm;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            imm = fetch_long_imm();
+            DECODE_PRINTF2(",%d\n", (s32) imm);
+            TRACE_AND_STEP();
+            imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
+            if (res_hi != 0) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u32) res_lo;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+            u32 res;
+            s16 imm;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            imm = fetch_word_imm();
+            DECODE_PRINTF2(",%d\n", (s32) imm);
+            TRACE_AND_STEP();
+            res = (s16) srcval *(s16) imm;
+
+            if (res > 0xFFFF) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u16) res;
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+            u32 res_lo, res_hi;
+            s32 imm;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            imm = fetch_long_imm();
+            DECODE_PRINTF2(",%d\n", (s32) imm);
+            TRACE_AND_STEP();
+            imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
+            if (res_hi != 0) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u32) res_lo;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+            u32 res;
+            s16 imm;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            imm = fetch_word_imm();
+            DECODE_PRINTF2(",%d\n", (s32) imm);
+            TRACE_AND_STEP();
+            res = (s16) srcval *(s16) imm;
+
+            if (res > 0xFFFF) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u16) res;
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+            u32 res_lo, res_hi;
+            s32 imm;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            imm = fetch_long_imm();
+            DECODE_PRINTF2(",%d\n", (s32) imm);
+            TRACE_AND_STEP();
+            imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
+            if (res_hi != 0) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u32) res_lo;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+            u32 res;
+            s16 imm;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            imm = fetch_word_imm();
+            DECODE_PRINTF2(",%d\n", (s32) imm);
+            TRACE_AND_STEP();
+            res = (s16) srcval *(s16) imm;
+
+            if (res > 0xFFFF) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u16) res;
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+            u32 res_lo, res_hi;
+            s32 imm;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rl);
+            imm = fetch_long_imm();
+            DECODE_PRINTF2(",%d\n", (s32) imm);
+            TRACE_AND_STEP();
+            imul_long_direct(&res_lo, &res_hi, (s32) * srcreg, (s32) imm);
+            if (res_hi != 0) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u32) res_lo;
+        }
+        else {
+            u16 *destreg, *srcreg;
+            u32 res;
+            s16 imm;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rl);
+            imm = fetch_word_imm();
+            DECODE_PRINTF2(",%d\n", (s32) imm);
+            res = (s16) * srcreg * (s16) imm;
+            if (res > 0xFFFF) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u16) res;
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x6a
+****************************************************************************/
+static void
+x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
+{
+    s16 imm;
+
+    START_OF_INSTR();
+    imm = (s8) fetch_byte_imm();
+    DECODE_PRINTF2("PUSH\t%d\n", imm);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        push_long((s32) imm);
+    }
+    else {
+        push_word(imm);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x6b
+****************************************************************************/
+static void
+x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+    s8 imm;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("IMUL\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+            u32 res_lo, res_hi;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            imm = fetch_byte_imm();
+            DECODE_PRINTF2(",%d\n", (s32) imm);
+            TRACE_AND_STEP();
+            imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
+            if (res_hi != 0) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u32) res_lo;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+            u32 res;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            imm = fetch_byte_imm();
+            DECODE_PRINTF2(",%d\n", (s32) imm);
+            TRACE_AND_STEP();
+            res = (s16) srcval *(s16) imm;
+
+            if (res > 0xFFFF) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u16) res;
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+            u32 res_lo, res_hi;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            imm = fetch_byte_imm();
+            DECODE_PRINTF2(",%d\n", (s32) imm);
+            TRACE_AND_STEP();
+            imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
+            if (res_hi != 0) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u32) res_lo;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+            u32 res;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            imm = fetch_byte_imm();
+            DECODE_PRINTF2(",%d\n", (s32) imm);
+            TRACE_AND_STEP();
+            res = (s16) srcval *(s16) imm;
+
+            if (res > 0xFFFF) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u16) res;
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+            u32 res_lo, res_hi;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            imm = fetch_byte_imm();
+            DECODE_PRINTF2(",%d\n", (s32) imm);
+            TRACE_AND_STEP();
+            imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
+            if (res_hi != 0) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u32) res_lo;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+            u32 res;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            imm = fetch_byte_imm();
+            DECODE_PRINTF2(",%d\n", (s32) imm);
+            TRACE_AND_STEP();
+            res = (s16) srcval *(s16) imm;
+
+            if (res > 0xFFFF) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u16) res;
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+            u32 res_lo, res_hi;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rl);
+            imm = fetch_byte_imm();
+            DECODE_PRINTF2(",%d\n", (s32) imm);
+            TRACE_AND_STEP();
+            imul_long_direct(&res_lo, &res_hi, (s32) * srcreg, (s32) imm);
+            if (res_hi != 0) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u32) res_lo;
+        }
+        else {
+            u16 *destreg, *srcreg;
+            u32 res;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rl);
+            imm = fetch_byte_imm();
+            DECODE_PRINTF2(",%d\n", (s32) imm);
+            res = (s16) * srcreg * (s16) imm;
+            if (res > 0xFFFF) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u16) res;
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x6c
+****************************************************************************/
+static void
+x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("INSB\n");
+    ins(1);
+    TRACE_AND_STEP();
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x6d
+****************************************************************************/
+static void
+x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("INSD\n");
+        ins(4);
+    }
+    else {
+        DECODE_PRINTF("INSW\n");
+        ins(2);
+    }
+    TRACE_AND_STEP();
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x6e
+****************************************************************************/
+static void
+x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("OUTSB\n");
+    outs(1);
+    TRACE_AND_STEP();
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x6f
+****************************************************************************/
+static void
+x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("OUTSD\n");
+        outs(4);
+    }
+    else {
+        DECODE_PRINTF("OUTSW\n");
+        outs(2);
+    }
+    TRACE_AND_STEP();
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x70
+****************************************************************************/
+static void
+x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1))
+{
+    s8 offset;
+    u16 target;
+
+    /* jump to byte offset if overflow flag is set */
+    START_OF_INSTR();
+    DECODE_PRINTF("JO\t");
+    offset = (s8) fetch_byte_imm();
+    target = (u16) (M.x86.R_IP + (s16) offset);
+    DECODE_PRINTF2("%x\n", target);
+    TRACE_AND_STEP();
+    if (ACCESS_FLAG(F_OF))
+        M.x86.R_IP = target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x71
+****************************************************************************/
+static void
+x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1))
+{
+    s8 offset;
+    u16 target;
+
+    /* jump to byte offset if overflow is not set */
+    START_OF_INSTR();
+    DECODE_PRINTF("JNO\t");
+    offset = (s8) fetch_byte_imm();
+    target = (u16) (M.x86.R_IP + (s16) offset);
+    DECODE_PRINTF2("%x\n", target);
+    TRACE_AND_STEP();
+    if (!ACCESS_FLAG(F_OF))
+        M.x86.R_IP = target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x72
+****************************************************************************/
+static void
+x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1))
+{
+    s8 offset;
+    u16 target;
+
+    /* jump to byte offset if carry flag is set. */
+    START_OF_INSTR();
+    DECODE_PRINTF("JB\t");
+    offset = (s8) fetch_byte_imm();
+    target = (u16) (M.x86.R_IP + (s16) offset);
+    DECODE_PRINTF2("%x\n", target);
+    TRACE_AND_STEP();
+    if (ACCESS_FLAG(F_CF))
+        M.x86.R_IP = target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x73
+****************************************************************************/
+static void
+x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1))
+{
+    s8 offset;
+    u16 target;
+
+    /* jump to byte offset if carry flag is clear. */
+    START_OF_INSTR();
+    DECODE_PRINTF("JNB\t");
+    offset = (s8) fetch_byte_imm();
+    target = (u16) (M.x86.R_IP + (s16) offset);
+    DECODE_PRINTF2("%x\n", target);
+    TRACE_AND_STEP();
+    if (!ACCESS_FLAG(F_CF))
+        M.x86.R_IP = target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x74
+****************************************************************************/
+static void
+x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1))
+{
+    s8 offset;
+    u16 target;
+
+    /* jump to byte offset if zero flag is set. */
+    START_OF_INSTR();
+    DECODE_PRINTF("JZ\t");
+    offset = (s8) fetch_byte_imm();
+    target = (u16) (M.x86.R_IP + (s16) offset);
+    DECODE_PRINTF2("%x\n", target);
+    TRACE_AND_STEP();
+    if (ACCESS_FLAG(F_ZF))
+        M.x86.R_IP = target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x75
+****************************************************************************/
+static void
+x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1))
+{
+    s8 offset;
+    u16 target;
+
+    /* jump to byte offset if zero flag is clear. */
+    START_OF_INSTR();
+    DECODE_PRINTF("JNZ\t");
+    offset = (s8) fetch_byte_imm();
+    target = (u16) (M.x86.R_IP + (s16) offset);
+    DECODE_PRINTF2("%x\n", target);
+    TRACE_AND_STEP();
+    if (!ACCESS_FLAG(F_ZF))
+        M.x86.R_IP = target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x76
+****************************************************************************/
+static void
+x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1))
+{
+    s8 offset;
+    u16 target;
+
+    /* jump to byte offset if carry flag is set or if the zero
+       flag is set. */
+    START_OF_INSTR();
+    DECODE_PRINTF("JBE\t");
+    offset = (s8) fetch_byte_imm();
+    target = (u16) (M.x86.R_IP + (s16) offset);
+    DECODE_PRINTF2("%x\n", target);
+    TRACE_AND_STEP();
+    if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))
+        M.x86.R_IP = target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x77
+****************************************************************************/
+static void
+x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1))
+{
+    s8 offset;
+    u16 target;
+
+    /* jump to byte offset if carry flag is clear and if the zero
+       flag is clear */
+    START_OF_INSTR();
+    DECODE_PRINTF("JNBE\t");
+    offset = (s8) fetch_byte_imm();
+    target = (u16) (M.x86.R_IP + (s16) offset);
+    DECODE_PRINTF2("%x\n", target);
+    TRACE_AND_STEP();
+    if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
+        M.x86.R_IP = target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x78
+****************************************************************************/
+static void
+x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1))
+{
+    s8 offset;
+    u16 target;
+
+    /* jump to byte offset if sign flag is set */
+    START_OF_INSTR();
+    DECODE_PRINTF("JS\t");
+    offset = (s8) fetch_byte_imm();
+    target = (u16) (M.x86.R_IP + (s16) offset);
+    DECODE_PRINTF2("%x\n", target);
+    TRACE_AND_STEP();
+    if (ACCESS_FLAG(F_SF))
+        M.x86.R_IP = target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x79
+****************************************************************************/
+static void
+x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1))
+{
+    s8 offset;
+    u16 target;
+
+    /* jump to byte offset if sign flag is clear */
+    START_OF_INSTR();
+    DECODE_PRINTF("JNS\t");
+    offset = (s8) fetch_byte_imm();
+    target = (u16) (M.x86.R_IP + (s16) offset);
+    DECODE_PRINTF2("%x\n", target);
+    TRACE_AND_STEP();
+    if (!ACCESS_FLAG(F_SF))
+        M.x86.R_IP = target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x7a
+****************************************************************************/
+static void
+x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1))
+{
+    s8 offset;
+    u16 target;
+
+    /* jump to byte offset if parity flag is set (even parity) */
+    START_OF_INSTR();
+    DECODE_PRINTF("JP\t");
+    offset = (s8) fetch_byte_imm();
+    target = (u16) (M.x86.R_IP + (s16) offset);
+    DECODE_PRINTF2("%x\n", target);
+    TRACE_AND_STEP();
+    if (ACCESS_FLAG(F_PF))
+        M.x86.R_IP = target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x7b
+****************************************************************************/
+static void
+x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1))
+{
+    s8 offset;
+    u16 target;
+
+    /* jump to byte offset if parity flag is clear (odd parity) */
+    START_OF_INSTR();
+    DECODE_PRINTF("JNP\t");
+    offset = (s8) fetch_byte_imm();
+    target = (u16) (M.x86.R_IP + (s16) offset);
+    DECODE_PRINTF2("%x\n", target);
+    TRACE_AND_STEP();
+    if (!ACCESS_FLAG(F_PF))
+        M.x86.R_IP = target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x7c
+****************************************************************************/
+static void
+x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1))
+{
+    s8 offset;
+    u16 target;
+    int sf, of;
+
+    /* jump to byte offset if sign flag not equal to overflow flag. */
+    START_OF_INSTR();
+    DECODE_PRINTF("JL\t");
+    offset = (s8) fetch_byte_imm();
+    target = (u16) (M.x86.R_IP + (s16) offset);
+    DECODE_PRINTF2("%x\n", target);
+    TRACE_AND_STEP();
+    sf = ACCESS_FLAG(F_SF) != 0;
+    of = ACCESS_FLAG(F_OF) != 0;
+    if (sf ^ of)
+        M.x86.R_IP = target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x7d
+****************************************************************************/
+static void
+x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1))
+{
+    s8 offset;
+    u16 target;
+    int sf, of;
+
+    /* jump to byte offset if sign flag not equal to overflow flag. */
+    START_OF_INSTR();
+    DECODE_PRINTF("JNL\t");
+    offset = (s8) fetch_byte_imm();
+    target = (u16) (M.x86.R_IP + (s16) offset);
+    DECODE_PRINTF2("%x\n", target);
+    TRACE_AND_STEP();
+    sf = ACCESS_FLAG(F_SF) != 0;
+    of = ACCESS_FLAG(F_OF) != 0;
+    /* note: inverse of above, but using == instead of xor. */
+    if (sf == of)
+        M.x86.R_IP = target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x7e
+****************************************************************************/
+static void
+x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1))
+{
+    s8 offset;
+    u16 target;
+    int sf, of;
+
+    /* jump to byte offset if sign flag not equal to overflow flag
+       or the zero flag is set */
+    START_OF_INSTR();
+    DECODE_PRINTF("JLE\t");
+    offset = (s8) fetch_byte_imm();
+    target = (u16) (M.x86.R_IP + (s16) offset);
+    DECODE_PRINTF2("%x\n", target);
+    TRACE_AND_STEP();
+    sf = ACCESS_FLAG(F_SF) != 0;
+    of = ACCESS_FLAG(F_OF) != 0;
+    if ((sf ^ of) || ACCESS_FLAG(F_ZF))
+        M.x86.R_IP = target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x7f
+****************************************************************************/
+static void
+x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1))
+{
+    s8 offset;
+    u16 target;
+    int sf, of;
+
+    /* jump to byte offset if sign flag equal to overflow flag.
+       and the zero flag is clear */
+    START_OF_INSTR();
+    DECODE_PRINTF("JNLE\t");
+    offset = (s8) fetch_byte_imm();
+    target = (u16) (M.x86.R_IP + (s16) offset);
+    DECODE_PRINTF2("%x\n", target);
+    TRACE_AND_STEP();
+    sf = ACCESS_FLAG(F_SF) != 0;
+    of = ACCESS_FLAG(F_OF) != 0;
+    if ((sf == of) && !ACCESS_FLAG(F_ZF))
+        M.x86.R_IP = target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+static u8(*opc80_byte_operation[]) (u8 d, u8 s) = {
+    add_byte,                   /* 00 */
+        or_byte,                /* 01 */
+        adc_byte,               /* 02 */
+        sbb_byte,               /* 03 */
+        and_byte,               /* 04 */
+        sub_byte,               /* 05 */
+        xor_byte,               /* 06 */
+        cmp_byte,               /* 07 */
+};
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x80
+****************************************************************************/
+static void
+x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg;
+    uint destoffset;
+    u8 imm;
+    u8 destval;
+
+    /*
+     * Weirdo special case instruction format.  Part of the opcode
+     * held below in "RH".  Doubly nested case would result, except
+     * that the decoded instruction
+     */
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+#ifdef DEBUG
+    if (DEBUG_DECODE()) {
+        /* XXX DECODE_PRINTF may be changed to something more
+           general, so that it is important to leave the strings
+           in the same format, even though the result is that the
+           above test is done twice. */
+
+        switch (rh) {
+        case 0:
+            DECODE_PRINTF("ADD\t");
+            break;
+        case 1:
+            DECODE_PRINTF("OR\t");
+            break;
+        case 2:
+            DECODE_PRINTF("ADC\t");
+            break;
+        case 3:
+            DECODE_PRINTF("SBB\t");
+            break;
+        case 4:
+            DECODE_PRINTF("AND\t");
+            break;
+        case 5:
+            DECODE_PRINTF("SUB\t");
+            break;
+        case 6:
+            DECODE_PRINTF("XOR\t");
+            break;
+        case 7:
+            DECODE_PRINTF("CMP\t");
+            break;
+        }
+    }
+#endif
+    /* know operation, decode the mod byte to find the addressing
+       mode. */
+    switch (mod) {
+    case 0:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        imm = fetch_byte_imm();
+        DECODE_PRINTF2("%x\n", imm);
+        TRACE_AND_STEP();
+        destval = (*opc80_byte_operation[rh]) (destval, imm);
+        if (rh != 7)
+            store_data_byte(destoffset, destval);
+        break;
+    case 1:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        imm = fetch_byte_imm();
+        DECODE_PRINTF2("%x\n", imm);
+        TRACE_AND_STEP();
+        destval = (*opc80_byte_operation[rh]) (destval, imm);
+        if (rh != 7)
+            store_data_byte(destoffset, destval);
+        break;
+    case 2:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        imm = fetch_byte_imm();
+        DECODE_PRINTF2("%x\n", imm);
+        TRACE_AND_STEP();
+        destval = (*opc80_byte_operation[rh]) (destval, imm);
+        if (rh != 7)
+            store_data_byte(destoffset, destval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF(",");
+        imm = fetch_byte_imm();
+        DECODE_PRINTF2("%x\n", imm);
+        TRACE_AND_STEP();
+        destval = (*opc80_byte_operation[rh]) (*destreg, imm);
+        if (rh != 7)
+            *destreg = destval;
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+static u16(*opc81_word_operation[]) (u16 d, u16 s) = {
+    add_word,                   /*00 */
+        or_word,                /*01 */
+        adc_word,               /*02 */
+        sbb_word,               /*03 */
+        and_word,               /*04 */
+        sub_word,               /*05 */
+        xor_word,               /*06 */
+        cmp_word,               /*07 */
+};
+
+static u32(*opc81_long_operation[]) (u32 d, u32 s) = {
+    add_long,                   /*00 */
+        or_long,                /*01 */
+        adc_long,               /*02 */
+        sbb_long,               /*03 */
+        and_long,               /*04 */
+        sub_long,               /*05 */
+        xor_long,               /*06 */
+        cmp_long,               /*07 */
+};
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x81
+****************************************************************************/
+static void
+x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    /*
+     * Weirdo special case instruction format.  Part of the opcode
+     * held below in "RH".  Doubly nested case would result, except
+     * that the decoded instruction
+     */
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+#ifdef DEBUG
+    if (DEBUG_DECODE()) {
+        /* XXX DECODE_PRINTF may be changed to something more
+           general, so that it is important to leave the strings
+           in the same format, even though the result is that the
+           above test is done twice. */
+
+        switch (rh) {
+        case 0:
+            DECODE_PRINTF("ADD\t");
+            break;
+        case 1:
+            DECODE_PRINTF("OR\t");
+            break;
+        case 2:
+            DECODE_PRINTF("ADC\t");
+            break;
+        case 3:
+            DECODE_PRINTF("SBB\t");
+            break;
+        case 4:
+            DECODE_PRINTF("AND\t");
+            break;
+        case 5:
+            DECODE_PRINTF("SUB\t");
+            break;
+        case 6:
+            DECODE_PRINTF("XOR\t");
+            break;
+        case 7:
+            DECODE_PRINTF("CMP\t");
+            break;
+        }
+    }
+#endif
+    /*
+     * Know operation, decode the mod byte to find the addressing
+     * mode.
+     */
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval, imm;
+
+            DECODE_PRINTF("DWORD PTR ");
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            imm = fetch_long_imm();
+            DECODE_PRINTF2("%x\n", imm);
+            TRACE_AND_STEP();
+            destval = (*opc81_long_operation[rh]) (destval, imm);
+            if (rh != 7)
+                store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval, imm;
+
+            DECODE_PRINTF("WORD PTR ");
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            imm = fetch_word_imm();
+            DECODE_PRINTF2("%x\n", imm);
+            TRACE_AND_STEP();
+            destval = (*opc81_word_operation[rh]) (destval, imm);
+            if (rh != 7)
+                store_data_word(destoffset, destval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval, imm;
+
+            DECODE_PRINTF("DWORD PTR ");
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            imm = fetch_long_imm();
+            DECODE_PRINTF2("%x\n", imm);
+            TRACE_AND_STEP();
+            destval = (*opc81_long_operation[rh]) (destval, imm);
+            if (rh != 7)
+                store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval, imm;
+
+            DECODE_PRINTF("WORD PTR ");
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            imm = fetch_word_imm();
+            DECODE_PRINTF2("%x\n", imm);
+            TRACE_AND_STEP();
+            destval = (*opc81_word_operation[rh]) (destval, imm);
+            if (rh != 7)
+                store_data_word(destoffset, destval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval, imm;
+
+            DECODE_PRINTF("DWORD PTR ");
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            imm = fetch_long_imm();
+            DECODE_PRINTF2("%x\n", imm);
+            TRACE_AND_STEP();
+            destval = (*opc81_long_operation[rh]) (destval, imm);
+            if (rh != 7)
+                store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval, imm;
+
+            DECODE_PRINTF("WORD PTR ");
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            imm = fetch_word_imm();
+            DECODE_PRINTF2("%x\n", imm);
+            TRACE_AND_STEP();
+            destval = (*opc81_word_operation[rh]) (destval, imm);
+            if (rh != 7)
+                store_data_word(destoffset, destval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 destval, imm;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            imm = fetch_long_imm();
+            DECODE_PRINTF2("%x\n", imm);
+            TRACE_AND_STEP();
+            destval = (*opc81_long_operation[rh]) (*destreg, imm);
+            if (rh != 7)
+                *destreg = destval;
+        }
+        else {
+            u16 *destreg;
+            u16 destval, imm;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            imm = fetch_word_imm();
+            DECODE_PRINTF2("%x\n", imm);
+            TRACE_AND_STEP();
+            destval = (*opc81_word_operation[rh]) (*destreg, imm);
+            if (rh != 7)
+                *destreg = destval;
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+static u8(*opc82_byte_operation[]) (u8 s, u8 d) = {
+    add_byte,                   /*00 */
+        or_byte,                /*01 *//*YYY UNUSED ???? */
+        adc_byte,               /*02 */
+        sbb_byte,               /*03 */
+        and_byte,               /*04 *//*YYY UNUSED ???? */
+        sub_byte,               /*05 */
+        xor_byte,               /*06 *//*YYY UNUSED ???? */
+        cmp_byte,               /*07 */
+};
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x82
+****************************************************************************/
+static void
+x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg;
+    uint destoffset;
+    u8 imm;
+    u8 destval;
+
+    /*
+     * Weirdo special case instruction format.  Part of the opcode
+     * held below in "RH".  Doubly nested case would result, except
+     * that the decoded instruction Similar to opcode 81, except that
+     * the immediate byte is sign extended to a word length.
+     */
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+#ifdef DEBUG
+    if (DEBUG_DECODE()) {
+        /* XXX DECODE_PRINTF may be changed to something more
+           general, so that it is important to leave the strings
+           in the same format, even though the result is that the
+           above test is done twice. */
+        switch (rh) {
+        case 0:
+            DECODE_PRINTF("ADD\t");
+            break;
+        case 1:
+            DECODE_PRINTF("OR\t");
+            break;
+        case 2:
+            DECODE_PRINTF("ADC\t");
+            break;
+        case 3:
+            DECODE_PRINTF("SBB\t");
+            break;
+        case 4:
+            DECODE_PRINTF("AND\t");
+            break;
+        case 5:
+            DECODE_PRINTF("SUB\t");
+            break;
+        case 6:
+            DECODE_PRINTF("XOR\t");
+            break;
+        case 7:
+            DECODE_PRINTF("CMP\t");
+            break;
+        }
+    }
+#endif
+    /* know operation, decode the mod byte to find the addressing
+       mode. */
+    switch (mod) {
+    case 0:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm00_address(rl);
+        destval = fetch_data_byte(destoffset);
+        imm = fetch_byte_imm();
+        DECODE_PRINTF2(",%x\n", imm);
+        TRACE_AND_STEP();
+        destval = (*opc82_byte_operation[rh]) (destval, imm);
+        if (rh != 7)
+            store_data_byte(destoffset, destval);
+        break;
+    case 1:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm01_address(rl);
+        destval = fetch_data_byte(destoffset);
+        imm = fetch_byte_imm();
+        DECODE_PRINTF2(",%x\n", imm);
+        TRACE_AND_STEP();
+        destval = (*opc82_byte_operation[rh]) (destval, imm);
+        if (rh != 7)
+            store_data_byte(destoffset, destval);
+        break;
+    case 2:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm10_address(rl);
+        destval = fetch_data_byte(destoffset);
+        imm = fetch_byte_imm();
+        DECODE_PRINTF2(",%x\n", imm);
+        TRACE_AND_STEP();
+        destval = (*opc82_byte_operation[rh]) (destval, imm);
+        if (rh != 7)
+            store_data_byte(destoffset, destval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        imm = fetch_byte_imm();
+        DECODE_PRINTF2(",%x\n", imm);
+        TRACE_AND_STEP();
+        destval = (*opc82_byte_operation[rh]) (*destreg, imm);
+        if (rh != 7)
+            *destreg = destval;
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+static u16(*opc83_word_operation[]) (u16 s, u16 d) = {
+    add_word,                   /*00 */
+        or_word,                /*01 *//*YYY UNUSED ???? */
+        adc_word,               /*02 */
+        sbb_word,               /*03 */
+        and_word,               /*04 *//*YYY UNUSED ???? */
+        sub_word,               /*05 */
+        xor_word,               /*06 *//*YYY UNUSED ???? */
+        cmp_word,               /*07 */
+};
+
+static u32(*opc83_long_operation[]) (u32 s, u32 d) = {
+    add_long,                   /*00 */
+        or_long,                /*01 *//*YYY UNUSED ???? */
+        adc_long,               /*02 */
+        sbb_long,               /*03 */
+        and_long,               /*04 *//*YYY UNUSED ???? */
+        sub_long,               /*05 */
+        xor_long,               /*06 *//*YYY UNUSED ???? */
+        cmp_long,               /*07 */
+};
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x83
+****************************************************************************/
+static void
+x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    /*
+     * Weirdo special case instruction format.  Part of the opcode
+     * held below in "RH".  Doubly nested case would result, except
+     * that the decoded instruction Similar to opcode 81, except that
+     * the immediate byte is sign extended to a word length.
+     */
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+#ifdef DEBUG
+    if (DEBUG_DECODE()) {
+        /* XXX DECODE_PRINTF may be changed to something more
+           general, so that it is important to leave the strings
+           in the same format, even though the result is that the
+           above test is done twice. */
+        switch (rh) {
+        case 0:
+            DECODE_PRINTF("ADD\t");
+            break;
+        case 1:
+            DECODE_PRINTF("OR\t");
+            break;
+        case 2:
+            DECODE_PRINTF("ADC\t");
+            break;
+        case 3:
+            DECODE_PRINTF("SBB\t");
+            break;
+        case 4:
+            DECODE_PRINTF("AND\t");
+            break;
+        case 5:
+            DECODE_PRINTF("SUB\t");
+            break;
+        case 6:
+            DECODE_PRINTF("XOR\t");
+            break;
+        case 7:
+            DECODE_PRINTF("CMP\t");
+            break;
+        }
+    }
+#endif
+    /* know operation, decode the mod byte to find the addressing
+       mode. */
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval, imm;
+
+            DECODE_PRINTF("DWORD PTR ");
+            destoffset = decode_rm00_address(rl);
+            destval = fetch_data_long(destoffset);
+            imm = (s8) fetch_byte_imm();
+            DECODE_PRINTF2(",%x\n", imm);
+            TRACE_AND_STEP();
+            destval = (*opc83_long_operation[rh]) (destval, imm);
+            if (rh != 7)
+                store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval, imm;
+
+            DECODE_PRINTF("WORD PTR ");
+            destoffset = decode_rm00_address(rl);
+            destval = fetch_data_word(destoffset);
+            imm = (s8) fetch_byte_imm();
+            DECODE_PRINTF2(",%x\n", imm);
+            TRACE_AND_STEP();
+            destval = (*opc83_word_operation[rh]) (destval, imm);
+            if (rh != 7)
+                store_data_word(destoffset, destval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval, imm;
+
+            DECODE_PRINTF("DWORD PTR ");
+            destoffset = decode_rm01_address(rl);
+            destval = fetch_data_long(destoffset);
+            imm = (s8) fetch_byte_imm();
+            DECODE_PRINTF2(",%x\n", imm);
+            TRACE_AND_STEP();
+            destval = (*opc83_long_operation[rh]) (destval, imm);
+            if (rh != 7)
+                store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval, imm;
+
+            DECODE_PRINTF("WORD PTR ");
+            destoffset = decode_rm01_address(rl);
+            destval = fetch_data_word(destoffset);
+            imm = (s8) fetch_byte_imm();
+            DECODE_PRINTF2(",%x\n", imm);
+            TRACE_AND_STEP();
+            destval = (*opc83_word_operation[rh]) (destval, imm);
+            if (rh != 7)
+                store_data_word(destoffset, destval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval, imm;
+
+            DECODE_PRINTF("DWORD PTR ");
+            destoffset = decode_rm10_address(rl);
+            destval = fetch_data_long(destoffset);
+            imm = (s8) fetch_byte_imm();
+            DECODE_PRINTF2(",%x\n", imm);
+            TRACE_AND_STEP();
+            destval = (*opc83_long_operation[rh]) (destval, imm);
+            if (rh != 7)
+                store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval, imm;
+
+            DECODE_PRINTF("WORD PTR ");
+            destoffset = decode_rm10_address(rl);
+            destval = fetch_data_word(destoffset);
+            imm = (s8) fetch_byte_imm();
+            DECODE_PRINTF2(",%x\n", imm);
+            TRACE_AND_STEP();
+            destval = (*opc83_word_operation[rh]) (destval, imm);
+            if (rh != 7)
+                store_data_word(destoffset, destval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 destval, imm;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            imm = (s8) fetch_byte_imm();
+            DECODE_PRINTF2(",%x\n", imm);
+            TRACE_AND_STEP();
+            destval = (*opc83_long_operation[rh]) (*destreg, imm);
+            if (rh != 7)
+                *destreg = destval;
+        }
+        else {
+            u16 *destreg;
+            u16 destval, imm;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            imm = (s8) fetch_byte_imm();
+            DECODE_PRINTF2(",%x\n", imm);
+            TRACE_AND_STEP();
+            destval = (*opc83_word_operation[rh]) (*destreg, imm);
+            if (rh != 7)
+                *destreg = destval;
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x84
+****************************************************************************/
+static void
+x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg, *srcreg;
+    uint destoffset;
+    u8 destval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("TEST\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        test_byte(destval, *srcreg);
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        test_byte(destval, *srcreg);
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        test_byte(destval, *srcreg);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        test_byte(*destreg, *srcreg);
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x85
+****************************************************************************/
+static void
+x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("TEST\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            test_long(destval, *srcreg);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            test_word(destval, *srcreg);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            test_long(destval, *srcreg);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            test_word(destval, *srcreg);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            test_long(destval, *srcreg);
+        }
+        else {
+            u16 destval;
+            u16 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            test_word(destval, *srcreg);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            test_long(*destreg, *srcreg);
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            test_word(*destreg, *srcreg);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x86
+****************************************************************************/
+static void
+x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg, *srcreg;
+    uint destoffset;
+    u8 destval;
+    u8 tmp;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("XCHG\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        tmp = *srcreg;
+        *srcreg = destval;
+        destval = tmp;
+        store_data_byte(destoffset, destval);
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        tmp = *srcreg;
+        *srcreg = destval;
+        destval = tmp;
+        store_data_byte(destoffset, destval);
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF(",");
+        destval = fetch_data_byte(destoffset);
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        tmp = *srcreg;
+        *srcreg = destval;
+        destval = tmp;
+        store_data_byte(destoffset, destval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        tmp = *srcreg;
+        *srcreg = *destreg;
+        *destreg = tmp;
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x87
+****************************************************************************/
+static void
+x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("XCHG\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *srcreg;
+            u32 destval, tmp;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            tmp = *srcreg;
+            *srcreg = destval;
+            destval = tmp;
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 *srcreg;
+            u16 destval, tmp;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            tmp = *srcreg;
+            *srcreg = destval;
+            destval = tmp;
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *srcreg;
+            u32 destval, tmp;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            tmp = *srcreg;
+            *srcreg = destval;
+            destval = tmp;
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 *srcreg;
+            u16 destval, tmp;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            tmp = *srcreg;
+            *srcreg = destval;
+            destval = tmp;
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *srcreg;
+            u32 destval, tmp;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_long(destoffset);
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            tmp = *srcreg;
+            *srcreg = destval;
+            destval = tmp;
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 *srcreg;
+            u16 destval, tmp;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            destval = fetch_data_word(destoffset);
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            tmp = *srcreg;
+            *srcreg = destval;
+            destval = tmp;
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+            u32 tmp;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            tmp = *srcreg;
+            *srcreg = *destreg;
+            *destreg = tmp;
+        }
+        else {
+            u16 *destreg, *srcreg;
+            u16 tmp;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            tmp = *srcreg;
+            *srcreg = *destreg;
+            *destreg = tmp;
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x88
+****************************************************************************/
+static void
+x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg, *srcreg;
+    uint destoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOV\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        store_data_byte(destoffset, *srcreg);
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        store_data_byte(destoffset, *srcreg);
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        store_data_byte(destoffset, *srcreg);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = *srcreg;
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x89
+****************************************************************************/
+static void
+x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u32 destoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOV\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            store_data_long(destoffset, *srcreg);
+        }
+        else {
+            u16 *srcreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            store_data_word(destoffset, *srcreg);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            store_data_long(destoffset, *srcreg);
+        }
+        else {
+            u16 *srcreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            store_data_word(destoffset, *srcreg);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            store_data_long(destoffset, *srcreg);
+        }
+        else {
+            u16 *srcreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            store_data_word(destoffset, *srcreg);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = *srcreg;
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = *srcreg;
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x8a
+****************************************************************************/
+static void
+x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg, *srcreg;
+    uint srcoffset;
+    u8 srcval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOV\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm00_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = srcval;
+        break;
+    case 1:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm01_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = srcval;
+        break;
+    case 2:
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm10_address(rl);
+        srcval = fetch_data_byte(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = srcval;
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = *srcreg;
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x8b
+****************************************************************************/
+static void
+x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOV\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = srcval;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = srcval;
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = srcval;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = srcval;
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = srcval;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = srcval;
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = *srcreg;
+        }
+        else {
+            u16 *destreg, *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = *srcreg;
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x8c
+****************************************************************************/
+static void
+x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u16 *destreg, *srcreg;
+    uint destoffset;
+    u16 destval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOV\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF(",");
+        srcreg = decode_rm_seg_register(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = *srcreg;
+        store_data_word(destoffset, destval);
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF(",");
+        srcreg = decode_rm_seg_register(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = *srcreg;
+        store_data_word(destoffset, destval);
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF(",");
+        srcreg = decode_rm_seg_register(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        destval = *srcreg;
+        store_data_word(destoffset, destval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_WORD_REGISTER(rl);
+        DECODE_PRINTF(",");
+        srcreg = decode_rm_seg_register(rh);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = *srcreg;
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x8d
+****************************************************************************/
+static void
+x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("LEA\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
+            u32 *srcreg = DECODE_RM_LONG_REGISTER(rh);
+
+            DECODE_PRINTF(",");
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *srcreg = (u32) destoffset;
+        }
+        else {
+            u16 *srcreg = DECODE_RM_WORD_REGISTER(rh);
+
+            DECODE_PRINTF(",");
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *srcreg = (u16) destoffset;
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
+            u32 *srcreg = DECODE_RM_LONG_REGISTER(rh);
+
+            DECODE_PRINTF(",");
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *srcreg = (u32) destoffset;
+        }
+        else {
+            u16 *srcreg = DECODE_RM_WORD_REGISTER(rh);
+
+            DECODE_PRINTF(",");
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *srcreg = (u16) destoffset;
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
+            u32 *srcreg = DECODE_RM_LONG_REGISTER(rh);
+
+            DECODE_PRINTF(",");
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *srcreg = (u32) destoffset;
+        }
+        else {
+            u16 *srcreg = DECODE_RM_WORD_REGISTER(rh);
+
+            DECODE_PRINTF(",");
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *srcreg = (u16) destoffset;
+        }
+        break;
+    case 3:                    /* register to register */
+        /* undefined.  Do nothing. */
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x8e
+****************************************************************************/
+static void
+x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u16 *destreg, *srcreg;
+    uint srcoffset;
+    u16 srcval;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOV\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destreg = decode_rm_seg_register(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm00_address(rl);
+        srcval = fetch_data_word(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = srcval;
+        break;
+    case 1:
+        destreg = decode_rm_seg_register(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm01_address(rl);
+        srcval = fetch_data_word(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = srcval;
+        break;
+    case 2:
+        destreg = decode_rm_seg_register(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm10_address(rl);
+        srcval = fetch_data_word(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = srcval;
+        break;
+    case 3:                    /* register to register */
+        destreg = decode_rm_seg_register(rh);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_WORD_REGISTER(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = *srcreg;
+        break;
+    }
+    /*
+     * Clean up, and reset all the R_xSP pointers to the correct
+     * locations.  This is about 3x too much overhead (doing all the
+     * segreg ptrs when only one is needed, but this instruction
+     * *cannot* be that common, and this isn't too much work anyway.
+     */
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x8f
+****************************************************************************/
+static void
+x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("POP\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    if (rh != 0) {
+        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
+        HALT_SYS();
+    }
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = pop_long();
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = pop_word();
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = pop_long();
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = pop_word();
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = pop_long();
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            destval = pop_word();
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = pop_long();
+        }
+        else {
+            u16 *destreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = pop_word();
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x90
+****************************************************************************/
+static void
+x86emuOp_nop(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("NOP\n");
+    TRACE_AND_STEP();
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x91
+****************************************************************************/
+static void
+x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1))
+{
+    u32 tmp;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("XCHG\tEAX,ECX\n");
+    }
+    else {
+        DECODE_PRINTF("XCHG\tAX,CX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        tmp = M.x86.R_EAX;
+        M.x86.R_EAX = M.x86.R_ECX;
+        M.x86.R_ECX = tmp;
+    }
+    else {
+        tmp = M.x86.R_AX;
+        M.x86.R_AX = M.x86.R_CX;
+        M.x86.R_CX = (u16) tmp;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x92
+****************************************************************************/
+static void
+x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1))
+{
+    u32 tmp;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("XCHG\tEAX,EDX\n");
+    }
+    else {
+        DECODE_PRINTF("XCHG\tAX,DX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        tmp = M.x86.R_EAX;
+        M.x86.R_EAX = M.x86.R_EDX;
+        M.x86.R_EDX = tmp;
+    }
+    else {
+        tmp = M.x86.R_AX;
+        M.x86.R_AX = M.x86.R_DX;
+        M.x86.R_DX = (u16) tmp;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x93
+****************************************************************************/
+static void
+x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1))
+{
+    u32 tmp;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("XCHG\tEAX,EBX\n");
+    }
+    else {
+        DECODE_PRINTF("XCHG\tAX,BX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        tmp = M.x86.R_EAX;
+        M.x86.R_EAX = M.x86.R_EBX;
+        M.x86.R_EBX = tmp;
+    }
+    else {
+        tmp = M.x86.R_AX;
+        M.x86.R_AX = M.x86.R_BX;
+        M.x86.R_BX = (u16) tmp;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x94
+****************************************************************************/
+static void
+x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1))
+{
+    u32 tmp;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("XCHG\tEAX,ESP\n");
+    }
+    else {
+        DECODE_PRINTF("XCHG\tAX,SP\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        tmp = M.x86.R_EAX;
+        M.x86.R_EAX = M.x86.R_ESP;
+        M.x86.R_ESP = tmp;
+    }
+    else {
+        tmp = M.x86.R_AX;
+        M.x86.R_AX = M.x86.R_SP;
+        M.x86.R_SP = (u16) tmp;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x95
+****************************************************************************/
+static void
+x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1))
+{
+    u32 tmp;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("XCHG\tEAX,EBP\n");
+    }
+    else {
+        DECODE_PRINTF("XCHG\tAX,BP\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        tmp = M.x86.R_EAX;
+        M.x86.R_EAX = M.x86.R_EBP;
+        M.x86.R_EBP = tmp;
+    }
+    else {
+        tmp = M.x86.R_AX;
+        M.x86.R_AX = M.x86.R_BP;
+        M.x86.R_BP = (u16) tmp;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x96
+****************************************************************************/
+static void
+x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1))
+{
+    u32 tmp;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("XCHG\tEAX,ESI\n");
+    }
+    else {
+        DECODE_PRINTF("XCHG\tAX,SI\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        tmp = M.x86.R_EAX;
+        M.x86.R_EAX = M.x86.R_ESI;
+        M.x86.R_ESI = tmp;
+    }
+    else {
+        tmp = M.x86.R_AX;
+        M.x86.R_AX = M.x86.R_SI;
+        M.x86.R_SI = (u16) tmp;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x97
+****************************************************************************/
+static void
+x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1))
+{
+    u32 tmp;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("XCHG\tEAX,EDI\n");
+    }
+    else {
+        DECODE_PRINTF("XCHG\tAX,DI\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        tmp = M.x86.R_EAX;
+        M.x86.R_EAX = M.x86.R_EDI;
+        M.x86.R_EDI = tmp;
+    }
+    else {
+        tmp = M.x86.R_AX;
+        M.x86.R_AX = M.x86.R_DI;
+        M.x86.R_DI = (u16) tmp;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x98
+****************************************************************************/
+static void
+x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("CWDE\n");
+    }
+    else {
+        DECODE_PRINTF("CBW\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        if (M.x86.R_AX & 0x8000) {
+            M.x86.R_EAX |= 0xffff0000;
+        }
+        else {
+            M.x86.R_EAX &= 0x0000ffff;
+        }
+    }
+    else {
+        if (M.x86.R_AL & 0x80) {
+            M.x86.R_AH = 0xff;
+        }
+        else {
+            M.x86.R_AH = 0x0;
+        }
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x99
+****************************************************************************/
+static void
+x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("CDQ\n");
+    }
+    else {
+        DECODE_PRINTF("CWD\n");
+    }
+    DECODE_PRINTF("CWD\n");
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        if (M.x86.R_EAX & 0x80000000) {
+            M.x86.R_EDX = 0xffffffff;
+        }
+        else {
+            M.x86.R_EDX = 0x0;
+        }
+    }
+    else {
+        if (M.x86.R_AX & 0x8000) {
+            M.x86.R_DX = 0xffff;
+        }
+        else {
+            M.x86.R_DX = 0x0;
+        }
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x9a
+****************************************************************************/
+static void
+x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 farseg, faroff;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("CALL\t");
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        faroff = fetch_long_imm();
+        farseg = fetch_word_imm();
+    }
+    else {
+        faroff = fetch_word_imm();
+        farseg = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%04x:", farseg);
+    DECODE_PRINTF2("%04x\n", faroff);
+    CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
+
+    /* XXX
+     *
+     * Hooked interrupt vectors calling into our "BIOS" will cause
+     * problems unless all intersegment stuff is checked for BIOS
+     * access.  Check needed here.  For moment, let it alone.
+     */
+    TRACE_AND_STEP();
+    push_word(M.x86.R_CS);
+    M.x86.R_CS = farseg;
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        push_long(M.x86.R_EIP);
+    }
+    else {
+        push_word(M.x86.R_IP);
+    }
+    M.x86.R_EIP = faroff & 0xffff;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x9b
+****************************************************************************/
+static void
+x86emuOp_wait(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("WAIT");
+    TRACE_AND_STEP();
+    /* NADA.  */
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x9c
+****************************************************************************/
+static void
+x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
+{
+    u32 flags;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("PUSHFD\n");
+    }
+    else {
+        DECODE_PRINTF("PUSHF\n");
+    }
+    TRACE_AND_STEP();
+
+    /* clear out *all* bits not representing flags, and turn on real bits */
+    flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        push_long(flags);
+    }
+    else {
+        push_word((u16) flags);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x9d
+****************************************************************************/
+static void
+x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("POPFD\n");
+    }
+    else {
+        DECODE_PRINTF("POPF\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EFLG = pop_long();
+    }
+    else {
+        M.x86.R_FLG = pop_word();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x9e
+****************************************************************************/
+static void
+x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("SAHF\n");
+    TRACE_AND_STEP();
+    /* clear the lower bits of the flag register */
+    M.x86.R_FLG &= 0xffffff00;
+    /* or in the AH register into the flags register */
+    M.x86.R_FLG |= M.x86.R_AH;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x9f
+****************************************************************************/
+static void
+x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("LAHF\n");
+    TRACE_AND_STEP();
+    M.x86.R_AH = (u8) (M.x86.R_FLG & 0xff);
+    /*undocumented TC++ behavior??? Nope.  It's documented, but
+       you have too look real hard to notice it. */
+    M.x86.R_AH |= 0x2;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xa0
+****************************************************************************/
+static void
+x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u16 offset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOV\tAL,");
+    offset = fetch_word_imm();
+    DECODE_PRINTF2("[%04x]\n", offset);
+    TRACE_AND_STEP();
+    M.x86.R_AL = fetch_data_byte(offset);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xa1
+****************************************************************************/
+static void
+x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u16 offset;
+
+    START_OF_INSTR();
+    offset = fetch_word_imm();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
+    }
+    else {
+        DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EAX = fetch_data_long(offset);
+    }
+    else {
+        M.x86.R_AX = fetch_data_word(offset);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xa2
+****************************************************************************/
+static void
+x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u16 offset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOV\t");
+    offset = fetch_word_imm();
+    DECODE_PRINTF2("[%04x],AL\n", offset);
+    TRACE_AND_STEP();
+    store_data_byte(offset, M.x86.R_AL);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xa3
+****************************************************************************/
+static void
+x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u16 offset;
+
+    START_OF_INSTR();
+    offset = fetch_word_imm();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
+    }
+    else {
+        DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        store_data_long(offset, M.x86.R_EAX);
+    }
+    else {
+        store_data_word(offset, M.x86.R_AX);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xa4
+****************************************************************************/
+static void
+x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
+{
+    u8 val;
+    u32 count;
+    int inc;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOVS\tBYTE\n");
+    if (ACCESS_FLAG(F_DF))      /* down */
+        inc = -1;
+    else
+        inc = 1;
+    TRACE_AND_STEP();
+    count = 1;
+    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
+        /* dont care whether REPE or REPNE */
+        /* move them until CX is ZERO. */
+        count = M.x86.R_CX;
+        M.x86.R_CX = 0;
+        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
+    }
+    while (count--) {
+        val = fetch_data_byte(M.x86.R_SI);
+        store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
+        M.x86.R_SI += inc;
+        M.x86.R_DI += inc;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xa5
+****************************************************************************/
+static void
+x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
+{
+    u32 val;
+    int inc;
+    u32 count;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("MOVS\tDWORD\n");
+        if (ACCESS_FLAG(F_DF))  /* down */
+            inc = -4;
+        else
+            inc = 4;
+    }
+    else {
+        DECODE_PRINTF("MOVS\tWORD\n");
+        if (ACCESS_FLAG(F_DF))  /* down */
+            inc = -2;
+        else
+            inc = 2;
+    }
+    TRACE_AND_STEP();
+    count = 1;
+    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
+        /* dont care whether REPE or REPNE */
+        /* move them until CX is ZERO. */
+        count = M.x86.R_CX;
+        M.x86.R_CX = 0;
+        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
+    }
+    while (count--) {
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            val = fetch_data_long(M.x86.R_SI);
+            store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
+        }
+        else {
+            val = fetch_data_word(M.x86.R_SI);
+            store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16) val);
+        }
+        M.x86.R_SI += inc;
+        M.x86.R_DI += inc;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xa6
+****************************************************************************/
+static void
+x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
+{
+    s8 val1, val2;
+    int inc;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("CMPS\tBYTE\n");
+    TRACE_AND_STEP();
+    if (ACCESS_FLAG(F_DF))      /* down */
+        inc = -1;
+    else
+        inc = 1;
+
+    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
+        /* REPE  */
+        /* move them until CX is ZERO. */
+        while (M.x86.R_CX != 0) {
+            val1 = fetch_data_byte(M.x86.R_SI);
+            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
+            cmp_byte(val1, val2);
+            M.x86.R_CX -= 1;
+            M.x86.R_SI += inc;
+            M.x86.R_DI += inc;
+            if (ACCESS_FLAG(F_ZF) == 0)
+                break;
+        }
+        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
+    }
+    else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
+        /* REPNE  */
+        /* move them until CX is ZERO. */
+        while (M.x86.R_CX != 0) {
+            val1 = fetch_data_byte(M.x86.R_SI);
+            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
+            cmp_byte(val1, val2);
+            M.x86.R_CX -= 1;
+            M.x86.R_SI += inc;
+            M.x86.R_DI += inc;
+            if (ACCESS_FLAG(F_ZF))
+                break;          /* zero flag set means equal */
+        }
+        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
+    }
+    else {
+        val1 = fetch_data_byte(M.x86.R_SI);
+        val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
+        cmp_byte(val1, val2);
+        M.x86.R_SI += inc;
+        M.x86.R_DI += inc;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xa7
+****************************************************************************/
+static void
+x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
+{
+    u32 val1, val2;
+    int inc;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("CMPS\tDWORD\n");
+        if (ACCESS_FLAG(F_DF))  /* down */
+            inc = -4;
+        else
+            inc = 4;
+    }
+    else {
+        DECODE_PRINTF("CMPS\tWORD\n");
+        if (ACCESS_FLAG(F_DF))  /* down */
+            inc = -2;
+        else
+            inc = 2;
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
+        /* REPE  */
+        /* move them until CX is ZERO. */
+        while (M.x86.R_CX != 0) {
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                val1 = fetch_data_long(M.x86.R_SI);
+                val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
+                cmp_long(val1, val2);
+            }
+            else {
+                val1 = fetch_data_word(M.x86.R_SI);
+                val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
+                cmp_word((u16) val1, (u16) val2);
+            }
+            M.x86.R_CX -= 1;
+            M.x86.R_SI += inc;
+            M.x86.R_DI += inc;
+            if (ACCESS_FLAG(F_ZF) == 0)
+                break;
+        }
+        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
+    }
+    else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
+        /* REPNE  */
+        /* move them until CX is ZERO. */
+        while (M.x86.R_CX != 0) {
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                val1 = fetch_data_long(M.x86.R_SI);
+                val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
+                cmp_long(val1, val2);
+            }
+            else {
+                val1 = fetch_data_word(M.x86.R_SI);
+                val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
+                cmp_word((u16) val1, (u16) val2);
+            }
+            M.x86.R_CX -= 1;
+            M.x86.R_SI += inc;
+            M.x86.R_DI += inc;
+            if (ACCESS_FLAG(F_ZF))
+                break;          /* zero flag set means equal */
+        }
+        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
+    }
+    else {
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            val1 = fetch_data_long(M.x86.R_SI);
+            val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
+            cmp_long(val1, val2);
+        }
+        else {
+            val1 = fetch_data_word(M.x86.R_SI);
+            val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
+            cmp_word((u16) val1, (u16) val2);
+        }
+        M.x86.R_SI += inc;
+        M.x86.R_DI += inc;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xa8
+****************************************************************************/
+static void
+x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
+{
+    int imm;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("TEST\tAL,");
+    imm = fetch_byte_imm();
+    DECODE_PRINTF2("%04x\n", imm);
+    TRACE_AND_STEP();
+    test_byte(M.x86.R_AL, (u8) imm);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xa9
+****************************************************************************/
+static void
+x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 srcval;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("TEST\tEAX,");
+        srcval = fetch_long_imm();
+    }
+    else {
+        DECODE_PRINTF("TEST\tAX,");
+        srcval = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        test_long(M.x86.R_EAX, srcval);
+    }
+    else {
+        test_word(M.x86.R_AX, (u16) srcval);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xaa
+****************************************************************************/
+static void
+x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
+{
+    int inc;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("STOS\tBYTE\n");
+    if (ACCESS_FLAG(F_DF))      /* down */
+        inc = -1;
+    else
+        inc = 1;
+    TRACE_AND_STEP();
+    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
+        /* dont care whether REPE or REPNE */
+        /* move them until CX is ZERO. */
+        while (M.x86.R_CX != 0) {
+            store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
+            M.x86.R_CX -= 1;
+            M.x86.R_DI += inc;
+        }
+        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
+    }
+    else {
+        store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
+        M.x86.R_DI += inc;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xab
+****************************************************************************/
+static void
+x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
+{
+    int inc;
+    u32 count;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("STOS\tDWORD\n");
+        if (ACCESS_FLAG(F_DF))  /* down */
+            inc = -4;
+        else
+            inc = 4;
+    }
+    else {
+        DECODE_PRINTF("STOS\tWORD\n");
+        if (ACCESS_FLAG(F_DF))  /* down */
+            inc = -2;
+        else
+            inc = 2;
+    }
+    TRACE_AND_STEP();
+    count = 1;
+    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
+        /* dont care whether REPE or REPNE */
+        /* move them until CX is ZERO. */
+        count = M.x86.R_CX;
+        M.x86.R_CX = 0;
+        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
+    }
+    while (count--) {
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
+        }
+        else {
+            store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
+        }
+        M.x86.R_DI += inc;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xac
+****************************************************************************/
+static void
+x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
+{
+    int inc;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("LODS\tBYTE\n");
+    TRACE_AND_STEP();
+    if (ACCESS_FLAG(F_DF))      /* down */
+        inc = -1;
+    else
+        inc = 1;
+    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
+        /* dont care whether REPE or REPNE */
+        /* move them until CX is ZERO. */
+        while (M.x86.R_CX != 0) {
+            M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
+            M.x86.R_CX -= 1;
+            M.x86.R_SI += inc;
+        }
+        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
+    }
+    else {
+        M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
+        M.x86.R_SI += inc;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xad
+****************************************************************************/
+static void
+x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
+{
+    int inc;
+    u32 count;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("LODS\tDWORD\n");
+        if (ACCESS_FLAG(F_DF))  /* down */
+            inc = -4;
+        else
+            inc = 4;
+    }
+    else {
+        DECODE_PRINTF("LODS\tWORD\n");
+        if (ACCESS_FLAG(F_DF))  /* down */
+            inc = -2;
+        else
+            inc = 2;
+    }
+    TRACE_AND_STEP();
+    count = 1;
+    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
+        /* dont care whether REPE or REPNE */
+        /* move them until CX is ZERO. */
+        count = M.x86.R_CX;
+        M.x86.R_CX = 0;
+        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
+    }
+    while (count--) {
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
+        }
+        else {
+            M.x86.R_AX = fetch_data_word(M.x86.R_SI);
+        }
+        M.x86.R_SI += inc;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xae
+****************************************************************************/
+static void
+x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
+{
+    s8 val2;
+    int inc;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("SCAS\tBYTE\n");
+    TRACE_AND_STEP();
+    if (ACCESS_FLAG(F_DF))      /* down */
+        inc = -1;
+    else
+        inc = 1;
+    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
+        /* REPE  */
+        /* move them until CX is ZERO. */
+        while (M.x86.R_CX != 0) {
+            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
+            cmp_byte(M.x86.R_AL, val2);
+            M.x86.R_CX -= 1;
+            M.x86.R_DI += inc;
+            if (ACCESS_FLAG(F_ZF) == 0)
+                break;
+        }
+        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
+    }
+    else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
+        /* REPNE  */
+        /* move them until CX is ZERO. */
+        while (M.x86.R_CX != 0) {
+            val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
+            cmp_byte(M.x86.R_AL, val2);
+            M.x86.R_CX -= 1;
+            M.x86.R_DI += inc;
+            if (ACCESS_FLAG(F_ZF))
+                break;          /* zero flag set means equal */
+        }
+        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
+    }
+    else {
+        val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
+        cmp_byte(M.x86.R_AL, val2);
+        M.x86.R_DI += inc;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xaf
+****************************************************************************/
+static void
+x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
+{
+    int inc;
+    u32 val;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("SCAS\tDWORD\n");
+        if (ACCESS_FLAG(F_DF))  /* down */
+            inc = -4;
+        else
+            inc = 4;
+    }
+    else {
+        DECODE_PRINTF("SCAS\tWORD\n");
+        if (ACCESS_FLAG(F_DF))  /* down */
+            inc = -2;
+        else
+            inc = 2;
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_REPE) {
+        /* REPE  */
+        /* move them until CX is ZERO. */
+        while (M.x86.R_CX != 0) {
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
+                cmp_long(M.x86.R_EAX, val);
+            }
+            else {
+                val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
+                cmp_word(M.x86.R_AX, (u16) val);
+            }
+            M.x86.R_CX -= 1;
+            M.x86.R_DI += inc;
+            if (ACCESS_FLAG(F_ZF) == 0)
+                break;
+        }
+        M.x86.mode &= ~SYSMODE_PREFIX_REPE;
+    }
+    else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
+        /* REPNE  */
+        /* move them until CX is ZERO. */
+        while (M.x86.R_CX != 0) {
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
+                cmp_long(M.x86.R_EAX, val);
+            }
+            else {
+                val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
+                cmp_word(M.x86.R_AX, (u16) val);
+            }
+            M.x86.R_CX -= 1;
+            M.x86.R_DI += inc;
+            if (ACCESS_FLAG(F_ZF))
+                break;          /* zero flag set means equal */
+        }
+        M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
+    }
+    else {
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
+            cmp_long(M.x86.R_EAX, val);
+        }
+        else {
+            val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
+            cmp_word(M.x86.R_AX, (u16) val);
+        }
+        M.x86.R_DI += inc;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xb0
+****************************************************************************/
+static void
+x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 imm;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOV\tAL,");
+    imm = fetch_byte_imm();
+    DECODE_PRINTF2("%x\n", imm);
+    TRACE_AND_STEP();
+    M.x86.R_AL = imm;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xb1
+****************************************************************************/
+static void
+x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 imm;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOV\tCL,");
+    imm = fetch_byte_imm();
+    DECODE_PRINTF2("%x\n", imm);
+    TRACE_AND_STEP();
+    M.x86.R_CL = imm;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xb2
+****************************************************************************/
+static void
+x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 imm;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOV\tDL,");
+    imm = fetch_byte_imm();
+    DECODE_PRINTF2("%x\n", imm);
+    TRACE_AND_STEP();
+    M.x86.R_DL = imm;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xb3
+****************************************************************************/
+static void
+x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 imm;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOV\tBL,");
+    imm = fetch_byte_imm();
+    DECODE_PRINTF2("%x\n", imm);
+    TRACE_AND_STEP();
+    M.x86.R_BL = imm;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xb4
+****************************************************************************/
+static void
+x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 imm;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOV\tAH,");
+    imm = fetch_byte_imm();
+    DECODE_PRINTF2("%x\n", imm);
+    TRACE_AND_STEP();
+    M.x86.R_AH = imm;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xb5
+****************************************************************************/
+static void
+x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 imm;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOV\tCH,");
+    imm = fetch_byte_imm();
+    DECODE_PRINTF2("%x\n", imm);
+    TRACE_AND_STEP();
+    M.x86.R_CH = imm;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xb6
+****************************************************************************/
+static void
+x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 imm;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOV\tDH,");
+    imm = fetch_byte_imm();
+    DECODE_PRINTF2("%x\n", imm);
+    TRACE_AND_STEP();
+    M.x86.R_DH = imm;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xb7
+****************************************************************************/
+static void
+x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 imm;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOV\tBH,");
+    imm = fetch_byte_imm();
+    DECODE_PRINTF2("%x\n", imm);
+    TRACE_AND_STEP();
+    M.x86.R_BH = imm;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xb8
+****************************************************************************/
+static void
+x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 srcval;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("MOV\tEAX,");
+        srcval = fetch_long_imm();
+    }
+    else {
+        DECODE_PRINTF("MOV\tAX,");
+        srcval = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EAX = srcval;
+    }
+    else {
+        M.x86.R_AX = (u16) srcval;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xb9
+****************************************************************************/
+static void
+x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 srcval;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("MOV\tECX,");
+        srcval = fetch_long_imm();
+    }
+    else {
+        DECODE_PRINTF("MOV\tCX,");
+        srcval = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_ECX = srcval;
+    }
+    else {
+        M.x86.R_CX = (u16) srcval;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xba
+****************************************************************************/
+static void
+x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 srcval;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("MOV\tEDX,");
+        srcval = fetch_long_imm();
+    }
+    else {
+        DECODE_PRINTF("MOV\tDX,");
+        srcval = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EDX = srcval;
+    }
+    else {
+        M.x86.R_DX = (u16) srcval;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xbb
+****************************************************************************/
+static void
+x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 srcval;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("MOV\tEBX,");
+        srcval = fetch_long_imm();
+    }
+    else {
+        DECODE_PRINTF("MOV\tBX,");
+        srcval = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EBX = srcval;
+    }
+    else {
+        M.x86.R_BX = (u16) srcval;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xbc
+****************************************************************************/
+static void
+x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 srcval;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("MOV\tESP,");
+        srcval = fetch_long_imm();
+    }
+    else {
+        DECODE_PRINTF("MOV\tSP,");
+        srcval = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_ESP = srcval;
+    }
+    else {
+        M.x86.R_SP = (u16) srcval;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xbd
+****************************************************************************/
+static void
+x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 srcval;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("MOV\tEBP,");
+        srcval = fetch_long_imm();
+    }
+    else {
+        DECODE_PRINTF("MOV\tBP,");
+        srcval = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EBP = srcval;
+    }
+    else {
+        M.x86.R_BP = (u16) srcval;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xbe
+****************************************************************************/
+static void
+x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 srcval;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("MOV\tESI,");
+        srcval = fetch_long_imm();
+    }
+    else {
+        DECODE_PRINTF("MOV\tSI,");
+        srcval = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_ESI = srcval;
+    }
+    else {
+        M.x86.R_SI = (u16) srcval;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xbf
+****************************************************************************/
+static void
+x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 srcval;
+
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("MOV\tEDI,");
+        srcval = fetch_long_imm();
+    }
+    else {
+        DECODE_PRINTF("MOV\tDI,");
+        srcval = fetch_word_imm();
+    }
+    DECODE_PRINTF2("%x\n", srcval);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EDI = srcval;
+    }
+    else {
+        M.x86.R_DI = (u16) srcval;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/* used by opcodes c0, d0, and d2. */
+static u8(*opcD0_byte_operation[]) (u8 d, u8 s) = {
+    rol_byte, ror_byte, rcl_byte, rcr_byte, shl_byte, shr_byte, shl_byte,       /* sal_byte === shl_byte  by definition */
+sar_byte,};
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xc0
+****************************************************************************/
+static void
+x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg;
+    uint destoffset;
+    u8 destval;
+    u8 amt;
+
+    /*
+     * Yet another weirdo special case instruction format.  Part of
+     * the opcode held below in "RH".  Doubly nested case would
+     * result, except that the decoded instruction
+     */
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+#ifdef DEBUG
+    if (DEBUG_DECODE()) {
+        /* XXX DECODE_PRINTF may be changed to something more
+           general, so that it is important to leave the strings
+           in the same format, even though the result is that the
+           above test is done twice. */
+
+        switch (rh) {
+        case 0:
+            DECODE_PRINTF("ROL\t");
+            break;
+        case 1:
+            DECODE_PRINTF("ROR\t");
+            break;
+        case 2:
+            DECODE_PRINTF("RCL\t");
+            break;
+        case 3:
+            DECODE_PRINTF("RCR\t");
+            break;
+        case 4:
+            DECODE_PRINTF("SHL\t");
+            break;
+        case 5:
+            DECODE_PRINTF("SHR\t");
+            break;
+        case 6:
+            DECODE_PRINTF("SAL\t");
+            break;
+        case 7:
+            DECODE_PRINTF("SAR\t");
+            break;
+        }
+    }
+#endif
+    /* know operation, decode the mod byte to find the addressing
+       mode. */
+    switch (mod) {
+    case 0:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm00_address(rl);
+        amt = fetch_byte_imm();
+        DECODE_PRINTF2(",%x\n", amt);
+        destval = fetch_data_byte(destoffset);
+        TRACE_AND_STEP();
+        destval = (*opcD0_byte_operation[rh]) (destval, amt);
+        store_data_byte(destoffset, destval);
+        break;
+    case 1:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm01_address(rl);
+        amt = fetch_byte_imm();
+        DECODE_PRINTF2(",%x\n", amt);
+        destval = fetch_data_byte(destoffset);
+        TRACE_AND_STEP();
+        destval = (*opcD0_byte_operation[rh]) (destval, amt);
+        store_data_byte(destoffset, destval);
+        break;
+    case 2:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm10_address(rl);
+        amt = fetch_byte_imm();
+        DECODE_PRINTF2(",%x\n", amt);
+        destval = fetch_data_byte(destoffset);
+        TRACE_AND_STEP();
+        destval = (*opcD0_byte_operation[rh]) (destval, amt);
+        store_data_byte(destoffset, destval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        amt = fetch_byte_imm();
+        DECODE_PRINTF2(",%x\n", amt);
+        TRACE_AND_STEP();
+        destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
+        *destreg = destval;
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/* used by opcodes c1, d1, and d3. */
+static u16(*opcD1_word_operation[]) (u16 s, u8 d) = {
+    rol_word, ror_word, rcl_word, rcr_word, shl_word, shr_word, shl_word,       /* sal_byte === shl_byte  by definition */
+sar_word,};
+
+/* used by opcodes c1, d1, and d3. */
+static u32(*opcD1_long_operation[]) (u32 s, u8 d) = {
+    rol_long, ror_long, rcl_long, rcr_long, shl_long, shr_long, shl_long,       /* sal_byte === shl_byte  by definition */
+sar_long,};
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xc1
+****************************************************************************/
+static void
+x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+    u8 amt;
+
+    /*
+     * Yet another weirdo special case instruction format.  Part of
+     * the opcode held below in "RH".  Doubly nested case would
+     * result, except that the decoded instruction
+     */
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+#ifdef DEBUG
+    if (DEBUG_DECODE()) {
+        /* XXX DECODE_PRINTF may be changed to something more
+           general, so that it is important to leave the strings
+           in the same format, even though the result is that the
+           above test is done twice. */
+
+        switch (rh) {
+        case 0:
+            DECODE_PRINTF("ROL\t");
+            break;
+        case 1:
+            DECODE_PRINTF("ROR\t");
+            break;
+        case 2:
+            DECODE_PRINTF("RCL\t");
+            break;
+        case 3:
+            DECODE_PRINTF("RCR\t");
+            break;
+        case 4:
+            DECODE_PRINTF("SHL\t");
+            break;
+        case 5:
+            DECODE_PRINTF("SHR\t");
+            break;
+        case 6:
+            DECODE_PRINTF("SAL\t");
+            break;
+        case 7:
+            DECODE_PRINTF("SAR\t");
+            break;
+        }
+    }
+#endif
+    /* know operation, decode the mod byte to find the addressing
+       mode. */
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+
+            DECODE_PRINTF("DWORD PTR ");
+            destoffset = decode_rm00_address(rl);
+            amt = fetch_byte_imm();
+            DECODE_PRINTF2(",%x\n", amt);
+            destval = fetch_data_long(destoffset);
+            TRACE_AND_STEP();
+            destval = (*opcD1_long_operation[rh]) (destval, amt);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+
+            DECODE_PRINTF("WORD PTR ");
+            destoffset = decode_rm00_address(rl);
+            amt = fetch_byte_imm();
+            DECODE_PRINTF2(",%x\n", amt);
+            destval = fetch_data_word(destoffset);
+            TRACE_AND_STEP();
+            destval = (*opcD1_word_operation[rh]) (destval, amt);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+
+            DECODE_PRINTF("DWORD PTR ");
+            destoffset = decode_rm01_address(rl);
+            amt = fetch_byte_imm();
+            DECODE_PRINTF2(",%x\n", amt);
+            destval = fetch_data_long(destoffset);
+            TRACE_AND_STEP();
+            destval = (*opcD1_long_operation[rh]) (destval, amt);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+
+            DECODE_PRINTF("WORD PTR ");
+            destoffset = decode_rm01_address(rl);
+            amt = fetch_byte_imm();
+            DECODE_PRINTF2(",%x\n", amt);
+            destval = fetch_data_word(destoffset);
+            TRACE_AND_STEP();
+            destval = (*opcD1_word_operation[rh]) (destval, amt);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+
+            DECODE_PRINTF("DWORD PTR ");
+            destoffset = decode_rm10_address(rl);
+            amt = fetch_byte_imm();
+            DECODE_PRINTF2(",%x\n", amt);
+            destval = fetch_data_long(destoffset);
+            TRACE_AND_STEP();
+            destval = (*opcD1_long_operation[rh]) (destval, amt);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+
+            DECODE_PRINTF("WORD PTR ");
+            destoffset = decode_rm10_address(rl);
+            amt = fetch_byte_imm();
+            DECODE_PRINTF2(",%x\n", amt);
+            destval = fetch_data_word(destoffset);
+            TRACE_AND_STEP();
+            destval = (*opcD1_word_operation[rh]) (destval, amt);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            amt = fetch_byte_imm();
+            DECODE_PRINTF2(",%x\n", amt);
+            TRACE_AND_STEP();
+            *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
+        }
+        else {
+            u16 *destreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            amt = fetch_byte_imm();
+            DECODE_PRINTF2(",%x\n", amt);
+            TRACE_AND_STEP();
+            *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xc2
+****************************************************************************/
+static void
+x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u16 imm;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("RET\t");
+    imm = fetch_word_imm();
+    DECODE_PRINTF2("%x\n", imm);
+    RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EIP = pop_long();
+    } else {
+        M.x86.R_IP = pop_word();
+    }
+    M.x86.R_SP += imm;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xc3
+****************************************************************************/
+static void
+x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("RET\n");
+    RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EIP = pop_long();
+    } else {
+        M.x86.R_IP = pop_word();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xc4
+****************************************************************************/
+static void
+x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rh, rl;
+    u16 *dstreg;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("LES\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        dstreg = DECODE_RM_WORD_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm00_address(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *dstreg = fetch_data_word(srcoffset);
+        M.x86.R_ES = fetch_data_word(srcoffset + 2);
+        break;
+    case 1:
+        dstreg = DECODE_RM_WORD_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm01_address(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *dstreg = fetch_data_word(srcoffset);
+        M.x86.R_ES = fetch_data_word(srcoffset + 2);
+        break;
+    case 2:
+        dstreg = DECODE_RM_WORD_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm10_address(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *dstreg = fetch_data_word(srcoffset);
+        M.x86.R_ES = fetch_data_word(srcoffset + 2);
+        break;
+    case 3:                    /* register to register */
+        /* UNDEFINED! */
+        TRACE_AND_STEP();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xc5
+****************************************************************************/
+static void
+x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rh, rl;
+    u16 *dstreg;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("LDS\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        dstreg = DECODE_RM_WORD_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm00_address(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *dstreg = fetch_data_word(srcoffset);
+        M.x86.R_DS = fetch_data_word(srcoffset + 2);
+        break;
+    case 1:
+        dstreg = DECODE_RM_WORD_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm01_address(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *dstreg = fetch_data_word(srcoffset);
+        M.x86.R_DS = fetch_data_word(srcoffset + 2);
+        break;
+    case 2:
+        dstreg = DECODE_RM_WORD_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm10_address(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *dstreg = fetch_data_word(srcoffset);
+        M.x86.R_DS = fetch_data_word(srcoffset + 2);
+        break;
+    case 3:                    /* register to register */
+        /* UNDEFINED! */
+        TRACE_AND_STEP();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xc6
+****************************************************************************/
+static void
+x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg;
+    uint destoffset;
+    u8 imm;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOV\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    if (rh != 0) {
+        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
+        HALT_SYS();
+    }
+    switch (mod) {
+    case 0:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm00_address(rl);
+        imm = fetch_byte_imm();
+        DECODE_PRINTF2(",%2x\n", imm);
+        TRACE_AND_STEP();
+        store_data_byte(destoffset, imm);
+        break;
+    case 1:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm01_address(rl);
+        imm = fetch_byte_imm();
+        DECODE_PRINTF2(",%2x\n", imm);
+        TRACE_AND_STEP();
+        store_data_byte(destoffset, imm);
+        break;
+    case 2:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm10_address(rl);
+        imm = fetch_byte_imm();
+        DECODE_PRINTF2(",%2x\n", imm);
+        TRACE_AND_STEP();
+        store_data_byte(destoffset, imm);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        imm = fetch_byte_imm();
+        DECODE_PRINTF2(",%2x\n", imm);
+        TRACE_AND_STEP();
+        *destreg = imm;
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xc7
+****************************************************************************/
+static void
+x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOV\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    if (rh != 0) {
+        DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
+        HALT_SYS();
+    }
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 imm;
+
+            DECODE_PRINTF("DWORD PTR ");
+            destoffset = decode_rm00_address(rl);
+            imm = fetch_long_imm();
+            DECODE_PRINTF2(",%x\n", imm);
+            TRACE_AND_STEP();
+            store_data_long(destoffset, imm);
+        }
+        else {
+            u16 imm;
+
+            DECODE_PRINTF("WORD PTR ");
+            destoffset = decode_rm00_address(rl);
+            imm = fetch_word_imm();
+            DECODE_PRINTF2(",%x\n", imm);
+            TRACE_AND_STEP();
+            store_data_word(destoffset, imm);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 imm;
+
+            DECODE_PRINTF("DWORD PTR ");
+            destoffset = decode_rm01_address(rl);
+            imm = fetch_long_imm();
+            DECODE_PRINTF2(",%x\n", imm);
+            TRACE_AND_STEP();
+            store_data_long(destoffset, imm);
+        }
+        else {
+            u16 imm;
+
+            DECODE_PRINTF("WORD PTR ");
+            destoffset = decode_rm01_address(rl);
+            imm = fetch_word_imm();
+            DECODE_PRINTF2(",%x\n", imm);
+            TRACE_AND_STEP();
+            store_data_word(destoffset, imm);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 imm;
+
+            DECODE_PRINTF("DWORD PTR ");
+            destoffset = decode_rm10_address(rl);
+            imm = fetch_long_imm();
+            DECODE_PRINTF2(",%x\n", imm);
+            TRACE_AND_STEP();
+            store_data_long(destoffset, imm);
+        }
+        else {
+            u16 imm;
+
+            DECODE_PRINTF("WORD PTR ");
+            destoffset = decode_rm10_address(rl);
+            imm = fetch_word_imm();
+            DECODE_PRINTF2(",%x\n", imm);
+            TRACE_AND_STEP();
+            store_data_word(destoffset, imm);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 imm;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            imm = fetch_long_imm();
+            DECODE_PRINTF2(",%x\n", imm);
+            TRACE_AND_STEP();
+            *destreg = imm;
+        }
+        else {
+            u16 *destreg;
+            u16 imm;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            imm = fetch_word_imm();
+            DECODE_PRINTF2(",%x\n", imm);
+            TRACE_AND_STEP();
+            *destreg = imm;
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xc8
+****************************************************************************/
+static void
+x86emuOp_enter(u8 X86EMU_UNUSED(op1))
+{
+    u16 local, frame_pointer;
+    u8 nesting;
+    int i;
+
+    START_OF_INSTR();
+    local = fetch_word_imm();
+    nesting = fetch_byte_imm();
+    DECODE_PRINTF2("ENTER %x\n", local);
+    DECODE_PRINTF2(",%x\n", nesting);
+    TRACE_AND_STEP();
+    push_word(M.x86.R_BP);
+    frame_pointer = M.x86.R_SP;
+    if (nesting > 0) {
+        for (i = 1; i < nesting; i++) {
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                M.x86.R_BP -= 4;
+                push_long(fetch_data_long_abs(M.x86.R_SS, M.x86.R_BP));
+            } else {
+                M.x86.R_BP -= 2;
+                push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
+            }
+        }
+        push_word(frame_pointer);
+    }
+    M.x86.R_BP = frame_pointer;
+    M.x86.R_SP = (u16) (M.x86.R_SP - local);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xc9
+****************************************************************************/
+static void
+x86emuOp_leave(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("LEAVE\n");
+    TRACE_AND_STEP();
+    M.x86.R_SP = M.x86.R_BP;
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EBP = pop_long();
+    } else {
+        M.x86.R_BP = pop_word();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xca
+****************************************************************************/
+static void
+x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u16 imm;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("RETF\t");
+    imm = fetch_word_imm();
+    DECODE_PRINTF2("%x\n", imm);
+    RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EIP = pop_long();
+        M.x86.R_CS = pop_long() & 0xffff;
+    } else {
+        M.x86.R_IP = pop_word();
+        M.x86.R_CS = pop_word();
+    }
+    M.x86.R_SP += imm;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xcb
+****************************************************************************/
+static void
+x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("RETF\n");
+    RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EIP = pop_long();
+        M.x86.R_CS = pop_long() & 0xffff;
+    } else {
+        M.x86.R_IP = pop_word();
+        M.x86.R_CS = pop_word();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xcc
+****************************************************************************/
+static void
+x86emuOp_int3(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("INT 3\n");
+    TRACE_AND_STEP();
+    if (_X86EMU_intrTab[3]) {
+        (*_X86EMU_intrTab[3]) (3);
+    }
+    else {
+        push_word((u16) M.x86.R_FLG);
+        CLEAR_FLAG(F_IF);
+        CLEAR_FLAG(F_TF);
+        push_word(M.x86.R_CS);
+        M.x86.R_CS = mem_access_word(3 * 4 + 2);
+        push_word(M.x86.R_IP);
+        M.x86.R_IP = mem_access_word(3 * 4);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xcd
+****************************************************************************/
+static void
+x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 intnum;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("INT\t");
+    intnum = fetch_byte_imm();
+    DECODE_PRINTF2("%x\n", intnum);
+    TRACE_AND_STEP();
+    if (_X86EMU_intrTab[intnum]) {
+        (*_X86EMU_intrTab[intnum]) (intnum);
+    }
+    else {
+        push_word((u16) M.x86.R_FLG);
+        CLEAR_FLAG(F_IF);
+        CLEAR_FLAG(F_TF);
+        push_word(M.x86.R_CS);
+        M.x86.R_CS = mem_access_word(intnum * 4 + 2);
+        push_word(M.x86.R_IP);
+        M.x86.R_IP = mem_access_word(intnum * 4);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xce
+****************************************************************************/
+static void
+x86emuOp_into(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("INTO\n");
+    TRACE_AND_STEP();
+    if (ACCESS_FLAG(F_OF)) {
+        if (_X86EMU_intrTab[4]) {
+            (*_X86EMU_intrTab[4]) (4);
+        }
+        else {
+            push_word((u16) M.x86.R_FLG);
+            CLEAR_FLAG(F_IF);
+            CLEAR_FLAG(F_TF);
+            push_word(M.x86.R_CS);
+            M.x86.R_CS = mem_access_word(4 * 4 + 2);
+            push_word(M.x86.R_IP);
+            M.x86.R_IP = mem_access_word(4 * 4);
+        }
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xcf
+****************************************************************************/
+static void
+x86emuOp_iret(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("IRET\n");
+
+    TRACE_AND_STEP();
+
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EIP = pop_long();
+        M.x86.R_CS = pop_long() & 0xffff;
+        M.x86.R_EFLG = (pop_long() & 0x257FD5) | (M.x86.R_EFLG & 0x1A0000);
+    } else {
+        M.x86.R_IP = pop_word();
+        M.x86.R_CS = pop_word();
+        M.x86.R_FLG = pop_word();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xd0
+****************************************************************************/
+static void
+x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg;
+    uint destoffset;
+    u8 destval;
+
+    /*
+     * Yet another weirdo special case instruction format.  Part of
+     * the opcode held below in "RH".  Doubly nested case would
+     * result, except that the decoded instruction
+     */
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+#ifdef DEBUG
+    if (DEBUG_DECODE()) {
+        /* XXX DECODE_PRINTF may be changed to something more
+           general, so that it is important to leave the strings
+           in the same format, even though the result is that the
+           above test is done twice. */
+        switch (rh) {
+        case 0:
+            DECODE_PRINTF("ROL\t");
+            break;
+        case 1:
+            DECODE_PRINTF("ROR\t");
+            break;
+        case 2:
+            DECODE_PRINTF("RCL\t");
+            break;
+        case 3:
+            DECODE_PRINTF("RCR\t");
+            break;
+        case 4:
+            DECODE_PRINTF("SHL\t");
+            break;
+        case 5:
+            DECODE_PRINTF("SHR\t");
+            break;
+        case 6:
+            DECODE_PRINTF("SAL\t");
+            break;
+        case 7:
+            DECODE_PRINTF("SAR\t");
+            break;
+        }
+    }
+#endif
+    /* know operation, decode the mod byte to find the addressing
+       mode. */
+    switch (mod) {
+    case 0:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF(",1\n");
+        destval = fetch_data_byte(destoffset);
+        TRACE_AND_STEP();
+        destval = (*opcD0_byte_operation[rh]) (destval, 1);
+        store_data_byte(destoffset, destval);
+        break;
+    case 1:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF(",1\n");
+        destval = fetch_data_byte(destoffset);
+        TRACE_AND_STEP();
+        destval = (*opcD0_byte_operation[rh]) (destval, 1);
+        store_data_byte(destoffset, destval);
+        break;
+    case 2:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF(",1\n");
+        destval = fetch_data_byte(destoffset);
+        TRACE_AND_STEP();
+        destval = (*opcD0_byte_operation[rh]) (destval, 1);
+        store_data_byte(destoffset, destval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF(",1\n");
+        TRACE_AND_STEP();
+        destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
+        *destreg = destval;
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xd1
+****************************************************************************/
+static void
+x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    /*
+     * Yet another weirdo special case instruction format.  Part of
+     * the opcode held below in "RH".  Doubly nested case would
+     * result, except that the decoded instruction
+     */
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+#ifdef DEBUG
+    if (DEBUG_DECODE()) {
+        /* XXX DECODE_PRINTF may be changed to something more
+           general, so that it is important to leave the strings
+           in the same format, even though the result is that the
+           above test is done twice. */
+        switch (rh) {
+        case 0:
+            DECODE_PRINTF("ROL\t");
+            break;
+        case 1:
+            DECODE_PRINTF("ROR\t");
+            break;
+        case 2:
+            DECODE_PRINTF("RCL\t");
+            break;
+        case 3:
+            DECODE_PRINTF("RCR\t");
+            break;
+        case 4:
+            DECODE_PRINTF("SHL\t");
+            break;
+        case 5:
+            DECODE_PRINTF("SHR\t");
+            break;
+        case 6:
+            DECODE_PRINTF("SAL\t");
+            break;
+        case 7:
+            DECODE_PRINTF("SAR\t");
+            break;
+        }
+    }
+#endif
+    /* know operation, decode the mod byte to find the addressing
+       mode. */
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+
+            DECODE_PRINTF("DWORD PTR ");
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",1\n");
+            destval = fetch_data_long(destoffset);
+            TRACE_AND_STEP();
+            destval = (*opcD1_long_operation[rh]) (destval, 1);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+
+            DECODE_PRINTF("WORD PTR ");
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",1\n");
+            destval = fetch_data_word(destoffset);
+            TRACE_AND_STEP();
+            destval = (*opcD1_word_operation[rh]) (destval, 1);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+
+            DECODE_PRINTF("DWORD PTR ");
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",1\n");
+            destval = fetch_data_long(destoffset);
+            TRACE_AND_STEP();
+            destval = (*opcD1_long_operation[rh]) (destval, 1);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+
+            DECODE_PRINTF("WORD PTR ");
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",1\n");
+            destval = fetch_data_word(destoffset);
+            TRACE_AND_STEP();
+            destval = (*opcD1_word_operation[rh]) (destval, 1);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+
+            DECODE_PRINTF("DWORD PTR ");
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",1\n");
+            destval = fetch_data_long(destoffset);
+            TRACE_AND_STEP();
+            destval = (*opcD1_long_operation[rh]) (destval, 1);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+
+            DECODE_PRINTF("BYTE PTR ");
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",1\n");
+            destval = fetch_data_word(destoffset);
+            TRACE_AND_STEP();
+            destval = (*opcD1_word_operation[rh]) (destval, 1);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *destreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",1\n");
+            TRACE_AND_STEP();
+            destval = (*opcD1_long_operation[rh]) (*destreg, 1);
+            *destreg = destval;
+        }
+        else {
+            u16 destval;
+            u16 *destreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",1\n");
+            TRACE_AND_STEP();
+            destval = (*opcD1_word_operation[rh]) (*destreg, 1);
+            *destreg = destval;
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xd2
+****************************************************************************/
+static void
+x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg;
+    uint destoffset;
+    u8 destval;
+    u8 amt;
+
+    /*
+     * Yet another weirdo special case instruction format.  Part of
+     * the opcode held below in "RH".  Doubly nested case would
+     * result, except that the decoded instruction
+     */
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+#ifdef DEBUG
+    if (DEBUG_DECODE()) {
+        /* XXX DECODE_PRINTF may be changed to something more
+           general, so that it is important to leave the strings
+           in the same format, even though the result is that the
+           above test is done twice. */
+        switch (rh) {
+        case 0:
+            DECODE_PRINTF("ROL\t");
+            break;
+        case 1:
+            DECODE_PRINTF("ROR\t");
+            break;
+        case 2:
+            DECODE_PRINTF("RCL\t");
+            break;
+        case 3:
+            DECODE_PRINTF("RCR\t");
+            break;
+        case 4:
+            DECODE_PRINTF("SHL\t");
+            break;
+        case 5:
+            DECODE_PRINTF("SHR\t");
+            break;
+        case 6:
+            DECODE_PRINTF("SAL\t");
+            break;
+        case 7:
+            DECODE_PRINTF("SAR\t");
+            break;
+        }
+    }
+#endif
+    /* know operation, decode the mod byte to find the addressing
+       mode. */
+    amt = M.x86.R_CL;
+    switch (mod) {
+    case 0:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF(",CL\n");
+        destval = fetch_data_byte(destoffset);
+        TRACE_AND_STEP();
+        destval = (*opcD0_byte_operation[rh]) (destval, amt);
+        store_data_byte(destoffset, destval);
+        break;
+    case 1:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF(",CL\n");
+        destval = fetch_data_byte(destoffset);
+        TRACE_AND_STEP();
+        destval = (*opcD0_byte_operation[rh]) (destval, amt);
+        store_data_byte(destoffset, destval);
+        break;
+    case 2:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF(",CL\n");
+        destval = fetch_data_byte(destoffset);
+        TRACE_AND_STEP();
+        destval = (*opcD0_byte_operation[rh]) (destval, amt);
+        store_data_byte(destoffset, destval);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF(",CL\n");
+        TRACE_AND_STEP();
+        destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
+        *destreg = destval;
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xd3
+****************************************************************************/
+static void
+x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+    u8 amt;
+
+    /*
+     * Yet another weirdo special case instruction format.  Part of
+     * the opcode held below in "RH".  Doubly nested case would
+     * result, except that the decoded instruction
+     */
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+#ifdef DEBUG
+    if (DEBUG_DECODE()) {
+        /* XXX DECODE_PRINTF may be changed to something more
+           general, so that it is important to leave the strings
+           in the same format, even though the result is that the
+           above test is done twice. */
+        switch (rh) {
+        case 0:
+            DECODE_PRINTF("ROL\t");
+            break;
+        case 1:
+            DECODE_PRINTF("ROR\t");
+            break;
+        case 2:
+            DECODE_PRINTF("RCL\t");
+            break;
+        case 3:
+            DECODE_PRINTF("RCR\t");
+            break;
+        case 4:
+            DECODE_PRINTF("SHL\t");
+            break;
+        case 5:
+            DECODE_PRINTF("SHR\t");
+            break;
+        case 6:
+            DECODE_PRINTF("SAL\t");
+            break;
+        case 7:
+            DECODE_PRINTF("SAR\t");
+            break;
+        }
+    }
+#endif
+    /* know operation, decode the mod byte to find the addressing
+       mode. */
+    amt = M.x86.R_CL;
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+
+            DECODE_PRINTF("DWORD PTR ");
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",CL\n");
+            destval = fetch_data_long(destoffset);
+            TRACE_AND_STEP();
+            destval = (*opcD1_long_operation[rh]) (destval, amt);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+
+            DECODE_PRINTF("WORD PTR ");
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",CL\n");
+            destval = fetch_data_word(destoffset);
+            TRACE_AND_STEP();
+            destval = (*opcD1_word_operation[rh]) (destval, amt);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+
+            DECODE_PRINTF("DWORD PTR ");
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",CL\n");
+            destval = fetch_data_long(destoffset);
+            TRACE_AND_STEP();
+            destval = (*opcD1_long_operation[rh]) (destval, amt);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+
+            DECODE_PRINTF("WORD PTR ");
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",CL\n");
+            destval = fetch_data_word(destoffset);
+            TRACE_AND_STEP();
+            destval = (*opcD1_word_operation[rh]) (destval, amt);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+
+            DECODE_PRINTF("DWORD PTR ");
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",CL\n");
+            destval = fetch_data_long(destoffset);
+            TRACE_AND_STEP();
+            destval = (*opcD1_long_operation[rh]) (destval, amt);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+
+            DECODE_PRINTF("WORD PTR ");
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",CL\n");
+            destval = fetch_data_word(destoffset);
+            TRACE_AND_STEP();
+            destval = (*opcD1_word_operation[rh]) (destval, amt);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",CL\n");
+            TRACE_AND_STEP();
+            *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
+        }
+        else {
+            u16 *destreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",CL\n");
+            TRACE_AND_STEP();
+            *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xd4
+****************************************************************************/
+static void
+x86emuOp_aam(u8 X86EMU_UNUSED(op1))
+{
+    u8 a;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("AAM\n");
+    a = fetch_byte_imm();       /* this is a stupid encoding. */
+    if (a != 10) {
+        /* fix: add base decoding
+           aam_word(u8 val, int base a) */
+        DECODE_PRINTF("ERROR DECODING AAM\n");
+        TRACE_REGS();
+        HALT_SYS();
+    }
+    TRACE_AND_STEP();
+    /* note the type change here --- returning AL and AH in AX. */
+    M.x86.R_AX = aam_word(M.x86.R_AL);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xd5
+****************************************************************************/
+static void
+x86emuOp_aad(u8 X86EMU_UNUSED(op1))
+{
+    u8 a;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("AAD\n");
+    a = fetch_byte_imm();
+    if (a != 10) {
+        /* fix: add base decoding
+           aad_word(u16 val, int base a) */
+        DECODE_PRINTF("ERROR DECODING AAM\n");
+        TRACE_REGS();
+        HALT_SYS();
+    }
+    TRACE_AND_STEP();
+    M.x86.R_AX = aad_word(M.x86.R_AX);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/* opcode 0xd6 ILLEGAL OPCODE */
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xd7
+****************************************************************************/
+static void
+x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
+{
+    u16 addr;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("XLAT\n");
+    TRACE_AND_STEP();
+    addr = (u16) (M.x86.R_BX + (u8) M.x86.R_AL);
+    M.x86.R_AL = fetch_data_byte(addr);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/* instuctions  D8 .. DF are in i87_ops.c */
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xe0
+****************************************************************************/
+static void
+x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
+{
+    s16 ip;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("LOOPNE\t");
+    ip = (s8) fetch_byte_imm();
+    ip += (s16) M.x86.R_IP;
+    DECODE_PRINTF2("%04x\n", ip);
+    TRACE_AND_STEP();
+    M.x86.R_CX -= 1;
+    if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF))  /* CX != 0 and !ZF */
+        M.x86.R_IP = ip;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xe1
+****************************************************************************/
+static void
+x86emuOp_loope(u8 X86EMU_UNUSED(op1))
+{
+    s16 ip;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("LOOPE\t");
+    ip = (s8) fetch_byte_imm();
+    ip += (s16) M.x86.R_IP;
+    DECODE_PRINTF2("%04x\n", ip);
+    TRACE_AND_STEP();
+    M.x86.R_CX -= 1;
+    if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF))   /* CX != 0 and ZF */
+        M.x86.R_IP = ip;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xe2
+****************************************************************************/
+static void
+x86emuOp_loop(u8 X86EMU_UNUSED(op1))
+{
+    s16 ip;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("LOOP\t");
+    ip = (s8) fetch_byte_imm();
+    ip += (s16) M.x86.R_IP;
+    DECODE_PRINTF2("%04x\n", ip);
+    TRACE_AND_STEP();
+    M.x86.R_CX -= 1;
+    if (M.x86.R_CX != 0)
+        M.x86.R_IP = ip;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xe3
+****************************************************************************/
+static void
+x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
+{
+    u16 target;
+    s8 offset;
+
+    /* jump to byte offset if overflow flag is set */
+    START_OF_INSTR();
+    DECODE_PRINTF("JCXZ\t");
+    offset = (s8) fetch_byte_imm();
+    target = (u16) (M.x86.R_IP + offset);
+    DECODE_PRINTF2("%x\n", target);
+    TRACE_AND_STEP();
+    if (M.x86.R_CX == 0)
+        M.x86.R_IP = target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xe4
+****************************************************************************/
+static void
+x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 port;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("IN\t");
+    port = (u8) fetch_byte_imm();
+    DECODE_PRINTF2("%x,AL\n", port);
+    TRACE_AND_STEP();
+    M.x86.R_AL = (*sys_inb) (port);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xe5
+****************************************************************************/
+static void
+x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u8 port;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("IN\t");
+    port = (u8) fetch_byte_imm();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF2("EAX,%x\n", port);
+    }
+    else {
+        DECODE_PRINTF2("AX,%x\n", port);
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EAX = (*sys_inl) (port);
+    }
+    else {
+        M.x86.R_AX = (*sys_inw) (port);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xe6
+****************************************************************************/
+static void
+x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
+{
+    u8 port;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("OUT\t");
+    port = (u8) fetch_byte_imm();
+    DECODE_PRINTF2("%x,AL\n", port);
+    TRACE_AND_STEP();
+    (*sys_outb) (port, M.x86.R_AL);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xe7
+****************************************************************************/
+static void
+x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
+{
+    u8 port;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("OUT\t");
+    port = (u8) fetch_byte_imm();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF2("%x,EAX\n", port);
+    }
+    else {
+        DECODE_PRINTF2("%x,AX\n", port);
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        (*sys_outl) (port, M.x86.R_EAX);
+    }
+    else {
+        (*sys_outw) (port, M.x86.R_AX);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xe8
+****************************************************************************/
+static void
+x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
+{
+    s16 ip16 = 0;
+    s32 ip32 = 0;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("CALL\t");
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        ip32 = (s32) fetch_long_imm();
+        ip32 += (s16) M.x86.R_IP;       /* CHECK SIGN */
+        DECODE_PRINTF2("%04x\n", (u16) ip32);
+        CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip32, "");
+    }
+    else {
+        ip16 = (s16) fetch_word_imm();
+        ip16 += (s16) M.x86.R_IP;       /* CHECK SIGN */
+        DECODE_PRINTF2("%04x\n", (u16) ip16);
+        CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip16, "");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        push_long(M.x86.R_EIP);
+        M.x86.R_EIP = ip32 & 0xffff;
+    }
+    else {
+        push_word(M.x86.R_IP);
+        M.x86.R_EIP = ip16;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xe9
+****************************************************************************/
+static void
+x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u32 ip;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("JMP\t");
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        ip = (u32) fetch_long_imm();
+        ip += (u32) M.x86.R_EIP;
+        DECODE_PRINTF2("%08x\n", (u32) ip);
+        TRACE_AND_STEP();
+        M.x86.R_EIP = (u32) ip;
+    }
+    else {
+        ip = (s16) fetch_word_imm();
+        ip += (s16) M.x86.R_IP;
+        DECODE_PRINTF2("%04x\n", (u16) ip);
+        TRACE_AND_STEP();
+        M.x86.R_IP = (u16) ip;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xea
+****************************************************************************/
+static void
+x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u16 cs;
+    u32 ip;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("JMP\tFAR ");
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        ip = fetch_long_imm();
+    }
+    else {
+        ip = fetch_word_imm();
+    }
+    cs = fetch_word_imm();
+    DECODE_PRINTF2("%04x:", cs);
+    DECODE_PRINTF2("%04x\n", ip);
+    TRACE_AND_STEP();
+    M.x86.R_EIP = ip & 0xffff;
+    M.x86.R_CS = cs;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xeb
+****************************************************************************/
+static void
+x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
+{
+    u16 target;
+    s8 offset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("JMP\t");
+    offset = (s8) fetch_byte_imm();
+    target = (u16) (M.x86.R_IP + offset);
+    DECODE_PRINTF2("%x\n", target);
+    TRACE_AND_STEP();
+    M.x86.R_IP = target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xec
+****************************************************************************/
+static void
+x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("IN\tAL,DX\n");
+    TRACE_AND_STEP();
+    M.x86.R_AL = (*sys_inb) (M.x86.R_DX);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xed
+****************************************************************************/
+static void
+x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("IN\tEAX,DX\n");
+    }
+    else {
+        DECODE_PRINTF("IN\tAX,DX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        M.x86.R_EAX = (*sys_inl) (M.x86.R_DX);
+    }
+    else {
+        M.x86.R_AX = (*sys_inw) (M.x86.R_DX);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xee
+****************************************************************************/
+static void
+x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("OUT\tDX,AL\n");
+    TRACE_AND_STEP();
+    (*sys_outb) (M.x86.R_DX, M.x86.R_AL);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xef
+****************************************************************************/
+static void
+x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        DECODE_PRINTF("OUT\tDX,EAX\n");
+    }
+    else {
+        DECODE_PRINTF("OUT\tDX,AX\n");
+    }
+    TRACE_AND_STEP();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+        (*sys_outl) (M.x86.R_DX, M.x86.R_EAX);
+    }
+    else {
+        (*sys_outw) (M.x86.R_DX, M.x86.R_AX);
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xf0
+****************************************************************************/
+static void
+x86emuOp_lock(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("LOCK:\n");
+    TRACE_AND_STEP();
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/*opcode 0xf1 ILLEGAL OPERATION */
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xf2
+****************************************************************************/
+static void
+x86emuOp_repne(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("REPNE\n");
+    TRACE_AND_STEP();
+    M.x86.mode |= SYSMODE_PREFIX_REPNE;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xf3
+****************************************************************************/
+static void
+x86emuOp_repe(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("REPE\n");
+    TRACE_AND_STEP();
+    M.x86.mode |= SYSMODE_PREFIX_REPE;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xf4
+****************************************************************************/
+static void
+x86emuOp_halt(u8 X86EMU_UNUSED(op1))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("HALT\n");
+    TRACE_AND_STEP();
+    HALT_SYS();
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xf5
+****************************************************************************/
+static void
+x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
+{
+    /* complement the carry flag. */
+    START_OF_INSTR();
+    DECODE_PRINTF("CMC\n");
+    TRACE_AND_STEP();
+    TOGGLE_FLAG(F_CF);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xf6
+****************************************************************************/
+static void
+x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    u8 *destreg;
+    uint destoffset;
+    u8 destval, srcval;
+
+    /* long, drawn out code follows.  Double switch for a total
+       of 32 cases.  */
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:                    /* mod=00 */
+        switch (rh) {
+        case 0:                /* test byte imm */
+            DECODE_PRINTF("TEST\tBYTE PTR ");
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            srcval = fetch_byte_imm();
+            DECODE_PRINTF2("%02x\n", srcval);
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            test_byte(destval, srcval);
+            break;
+        case 1:
+            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
+            HALT_SYS();
+            break;
+        case 2:
+            DECODE_PRINTF("NOT\tBYTE PTR ");
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF("\n");
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            destval = not_byte(destval);
+            store_data_byte(destoffset, destval);
+            break;
+        case 3:
+            DECODE_PRINTF("NEG\tBYTE PTR ");
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF("\n");
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            destval = neg_byte(destval);
+            store_data_byte(destoffset, destval);
+            break;
+        case 4:
+            DECODE_PRINTF("MUL\tBYTE PTR ");
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF("\n");
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            mul_byte(destval);
+            break;
+        case 5:
+            DECODE_PRINTF("IMUL\tBYTE PTR ");
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF("\n");
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            imul_byte(destval);
+            break;
+        case 6:
+            DECODE_PRINTF("DIV\tBYTE PTR ");
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF("\n");
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            div_byte(destval);
+            break;
+        case 7:
+            DECODE_PRINTF("IDIV\tBYTE PTR ");
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF("\n");
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            idiv_byte(destval);
+            break;
+        }
+        break;                  /* end mod==00 */
+    case 1:                    /* mod=01 */
+        switch (rh) {
+        case 0:                /* test byte imm */
+            DECODE_PRINTF("TEST\tBYTE PTR ");
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            srcval = fetch_byte_imm();
+            DECODE_PRINTF2("%02x\n", srcval);
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            test_byte(destval, srcval);
+            break;
+        case 1:
+            DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
+            HALT_SYS();
+            break;
+        case 2:
+            DECODE_PRINTF("NOT\tBYTE PTR ");
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF("\n");
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            destval = not_byte(destval);
+            store_data_byte(destoffset, destval);
+            break;
+        case 3:
+            DECODE_PRINTF("NEG\tBYTE PTR ");
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF("\n");
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            destval = neg_byte(destval);
+            store_data_byte(destoffset, destval);
+            break;
+        case 4:
+            DECODE_PRINTF("MUL\tBYTE PTR ");
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF("\n");
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            mul_byte(destval);
+            break;
+        case 5:
+            DECODE_PRINTF("IMUL\tBYTE PTR ");
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF("\n");
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            imul_byte(destval);
+            break;
+        case 6:
+            DECODE_PRINTF("DIV\tBYTE PTR ");
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF("\n");
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            div_byte(destval);
+            break;
+        case 7:
+            DECODE_PRINTF("IDIV\tBYTE PTR ");
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF("\n");
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            idiv_byte(destval);
+            break;
+        }
+        break;                  /* end mod==01 */
+    case 2:                    /* mod=10 */
+        switch (rh) {
+        case 0:                /* test byte imm */
+            DECODE_PRINTF("TEST\tBYTE PTR ");
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            srcval = fetch_byte_imm();
+            DECODE_PRINTF2("%02x\n", srcval);
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            test_byte(destval, srcval);
+            break;
+        case 1:
+            DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
+            HALT_SYS();
+            break;
+        case 2:
+            DECODE_PRINTF("NOT\tBYTE PTR ");
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF("\n");
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            destval = not_byte(destval);
+            store_data_byte(destoffset, destval);
+            break;
+        case 3:
+            DECODE_PRINTF("NEG\tBYTE PTR ");
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF("\n");
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            destval = neg_byte(destval);
+            store_data_byte(destoffset, destval);
+            break;
+        case 4:
+            DECODE_PRINTF("MUL\tBYTE PTR ");
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF("\n");
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            mul_byte(destval);
+            break;
+        case 5:
+            DECODE_PRINTF("IMUL\tBYTE PTR ");
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF("\n");
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            imul_byte(destval);
+            break;
+        case 6:
+            DECODE_PRINTF("DIV\tBYTE PTR ");
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF("\n");
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            div_byte(destval);
+            break;
+        case 7:
+            DECODE_PRINTF("IDIV\tBYTE PTR ");
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF("\n");
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            idiv_byte(destval);
+            break;
+        }
+        break;                  /* end mod==10 */
+    case 3:                    /* mod=11 */
+        switch (rh) {
+        case 0:                /* test byte imm */
+            DECODE_PRINTF("TEST\t");
+            destreg = DECODE_RM_BYTE_REGISTER(rl);
+            DECODE_PRINTF(",");
+            srcval = fetch_byte_imm();
+            DECODE_PRINTF2("%02x\n", srcval);
+            TRACE_AND_STEP();
+            test_byte(*destreg, srcval);
+            break;
+        case 1:
+            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
+            HALT_SYS();
+            break;
+        case 2:
+            DECODE_PRINTF("NOT\t");
+            destreg = DECODE_RM_BYTE_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = not_byte(*destreg);
+            break;
+        case 3:
+            DECODE_PRINTF("NEG\t");
+            destreg = DECODE_RM_BYTE_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = neg_byte(*destreg);
+            break;
+        case 4:
+            DECODE_PRINTF("MUL\t");
+            destreg = DECODE_RM_BYTE_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            mul_byte(*destreg); /*!!!  */
+            break;
+        case 5:
+            DECODE_PRINTF("IMUL\t");
+            destreg = DECODE_RM_BYTE_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            imul_byte(*destreg);
+            break;
+        case 6:
+            DECODE_PRINTF("DIV\t");
+            destreg = DECODE_RM_BYTE_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            div_byte(*destreg);
+            break;
+        case 7:
+            DECODE_PRINTF("IDIV\t");
+            destreg = DECODE_RM_BYTE_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            idiv_byte(*destreg);
+            break;
+        }
+        break;                  /* end mod==11 */
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xf7
+****************************************************************************/
+static void
+x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    /* long, drawn out code follows.  Double switch for a total
+       of 32 cases.  */
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:                    /* mod=00 */
+        switch (rh) {
+        case 0:                /* test word imm */
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval, srcval;
+
+                DECODE_PRINTF("TEST\tDWORD PTR ");
+                destoffset = decode_rm00_address(rl);
+                DECODE_PRINTF(",");
+                srcval = fetch_long_imm();
+                DECODE_PRINTF2("%x\n", srcval);
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                test_long(destval, srcval);
+            }
+            else {
+                u16 destval, srcval;
+
+                DECODE_PRINTF("TEST\tWORD PTR ");
+                destoffset = decode_rm00_address(rl);
+                DECODE_PRINTF(",");
+                srcval = fetch_word_imm();
+                DECODE_PRINTF2("%x\n", srcval);
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                test_word(destval, srcval);
+            }
+            break;
+        case 1:
+            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
+            HALT_SYS();
+            break;
+        case 2:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval;
+
+                DECODE_PRINTF("NOT\tDWORD PTR ");
+                destoffset = decode_rm00_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                destval = not_long(destval);
+                store_data_long(destoffset, destval);
+            }
+            else {
+                u16 destval;
+
+                DECODE_PRINTF("NOT\tWORD PTR ");
+                destoffset = decode_rm00_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                destval = not_word(destval);
+                store_data_word(destoffset, destval);
+            }
+            break;
+        case 3:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval;
+
+                DECODE_PRINTF("NEG\tDWORD PTR ");
+                destoffset = decode_rm00_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                destval = neg_long(destval);
+                store_data_long(destoffset, destval);
+            }
+            else {
+                u16 destval;
+
+                DECODE_PRINTF("NEG\tWORD PTR ");
+                destoffset = decode_rm00_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                destval = neg_word(destval);
+                store_data_word(destoffset, destval);
+            }
+            break;
+        case 4:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval;
+
+                DECODE_PRINTF("MUL\tDWORD PTR ");
+                destoffset = decode_rm00_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                mul_long(destval);
+            }
+            else {
+                u16 destval;
+
+                DECODE_PRINTF("MUL\tWORD PTR ");
+                destoffset = decode_rm00_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                mul_word(destval);
+            }
+            break;
+        case 5:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval;
+
+                DECODE_PRINTF("IMUL\tDWORD PTR ");
+                destoffset = decode_rm00_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                imul_long(destval);
+            }
+            else {
+                u16 destval;
+
+                DECODE_PRINTF("IMUL\tWORD PTR ");
+                destoffset = decode_rm00_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                imul_word(destval);
+            }
+            break;
+        case 6:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval;
+
+                DECODE_PRINTF("DIV\tDWORD PTR ");
+                destoffset = decode_rm00_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                div_long(destval);
+            }
+            else {
+                u16 destval;
+
+                DECODE_PRINTF("DIV\tWORD PTR ");
+                destoffset = decode_rm00_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                div_word(destval);
+            }
+            break;
+        case 7:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval;
+
+                DECODE_PRINTF("IDIV\tDWORD PTR ");
+                destoffset = decode_rm00_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                idiv_long(destval);
+            }
+            else {
+                u16 destval;
+
+                DECODE_PRINTF("IDIV\tWORD PTR ");
+                destoffset = decode_rm00_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                idiv_word(destval);
+            }
+            break;
+        }
+        break;                  /* end mod==00 */
+    case 1:                    /* mod=01 */
+        switch (rh) {
+        case 0:                /* test word imm */
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval, srcval;
+
+                DECODE_PRINTF("TEST\tDWORD PTR ");
+                destoffset = decode_rm01_address(rl);
+                DECODE_PRINTF(",");
+                srcval = fetch_long_imm();
+                DECODE_PRINTF2("%x\n", srcval);
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                test_long(destval, srcval);
+            }
+            else {
+                u16 destval, srcval;
+
+                DECODE_PRINTF("TEST\tWORD PTR ");
+                destoffset = decode_rm01_address(rl);
+                DECODE_PRINTF(",");
+                srcval = fetch_word_imm();
+                DECODE_PRINTF2("%x\n", srcval);
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                test_word(destval, srcval);
+            }
+            break;
+        case 1:
+            DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
+            HALT_SYS();
+            break;
+        case 2:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval;
+
+                DECODE_PRINTF("NOT\tDWORD PTR ");
+                destoffset = decode_rm01_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                destval = not_long(destval);
+                store_data_long(destoffset, destval);
+            }
+            else {
+                u16 destval;
+
+                DECODE_PRINTF("NOT\tWORD PTR ");
+                destoffset = decode_rm01_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                destval = not_word(destval);
+                store_data_word(destoffset, destval);
+            }
+            break;
+        case 3:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval;
+
+                DECODE_PRINTF("NEG\tDWORD PTR ");
+                destoffset = decode_rm01_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                destval = neg_long(destval);
+                store_data_long(destoffset, destval);
+            }
+            else {
+                u16 destval;
+
+                DECODE_PRINTF("NEG\tWORD PTR ");
+                destoffset = decode_rm01_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                destval = neg_word(destval);
+                store_data_word(destoffset, destval);
+            }
+            break;
+        case 4:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval;
+
+                DECODE_PRINTF("MUL\tDWORD PTR ");
+                destoffset = decode_rm01_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                mul_long(destval);
+            }
+            else {
+                u16 destval;
+
+                DECODE_PRINTF("MUL\tWORD PTR ");
+                destoffset = decode_rm01_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                mul_word(destval);
+            }
+            break;
+        case 5:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval;
+
+                DECODE_PRINTF("IMUL\tDWORD PTR ");
+                destoffset = decode_rm01_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                imul_long(destval);
+            }
+            else {
+                u16 destval;
+
+                DECODE_PRINTF("IMUL\tWORD PTR ");
+                destoffset = decode_rm01_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                imul_word(destval);
+            }
+            break;
+        case 6:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval;
+
+                DECODE_PRINTF("DIV\tDWORD PTR ");
+                destoffset = decode_rm01_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                div_long(destval);
+            }
+            else {
+                u16 destval;
+
+                DECODE_PRINTF("DIV\tWORD PTR ");
+                destoffset = decode_rm01_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                div_word(destval);
+            }
+            break;
+        case 7:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval;
+
+                DECODE_PRINTF("IDIV\tDWORD PTR ");
+                destoffset = decode_rm01_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                idiv_long(destval);
+            }
+            else {
+                u16 destval;
+
+                DECODE_PRINTF("IDIV\tWORD PTR ");
+                destoffset = decode_rm01_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                idiv_word(destval);
+            }
+            break;
+        }
+        break;                  /* end mod==01 */
+    case 2:                    /* mod=10 */
+        switch (rh) {
+        case 0:                /* test word imm */
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval, srcval;
+
+                DECODE_PRINTF("TEST\tDWORD PTR ");
+                destoffset = decode_rm10_address(rl);
+                DECODE_PRINTF(",");
+                srcval = fetch_long_imm();
+                DECODE_PRINTF2("%x\n", srcval);
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                test_long(destval, srcval);
+            }
+            else {
+                u16 destval, srcval;
+
+                DECODE_PRINTF("TEST\tWORD PTR ");
+                destoffset = decode_rm10_address(rl);
+                DECODE_PRINTF(",");
+                srcval = fetch_word_imm();
+                DECODE_PRINTF2("%x\n", srcval);
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                test_word(destval, srcval);
+            }
+            break;
+        case 1:
+            DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
+            HALT_SYS();
+            break;
+        case 2:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval;
+
+                DECODE_PRINTF("NOT\tDWORD PTR ");
+                destoffset = decode_rm10_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                destval = not_long(destval);
+                store_data_long(destoffset, destval);
+            }
+            else {
+                u16 destval;
+
+                DECODE_PRINTF("NOT\tWORD PTR ");
+                destoffset = decode_rm10_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                destval = not_word(destval);
+                store_data_word(destoffset, destval);
+            }
+            break;
+        case 3:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval;
+
+                DECODE_PRINTF("NEG\tDWORD PTR ");
+                destoffset = decode_rm10_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                destval = neg_long(destval);
+                store_data_long(destoffset, destval);
+            }
+            else {
+                u16 destval;
+
+                DECODE_PRINTF("NEG\tWORD PTR ");
+                destoffset = decode_rm10_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                destval = neg_word(destval);
+                store_data_word(destoffset, destval);
+            }
+            break;
+        case 4:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval;
+
+                DECODE_PRINTF("MUL\tDWORD PTR ");
+                destoffset = decode_rm10_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                mul_long(destval);
+            }
+            else {
+                u16 destval;
+
+                DECODE_PRINTF("MUL\tWORD PTR ");
+                destoffset = decode_rm10_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                mul_word(destval);
+            }
+            break;
+        case 5:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval;
+
+                DECODE_PRINTF("IMUL\tDWORD PTR ");
+                destoffset = decode_rm10_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                imul_long(destval);
+            }
+            else {
+                u16 destval;
+
+                DECODE_PRINTF("IMUL\tWORD PTR ");
+                destoffset = decode_rm10_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                imul_word(destval);
+            }
+            break;
+        case 6:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval;
+
+                DECODE_PRINTF("DIV\tDWORD PTR ");
+                destoffset = decode_rm10_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                div_long(destval);
+            }
+            else {
+                u16 destval;
+
+                DECODE_PRINTF("DIV\tWORD PTR ");
+                destoffset = decode_rm10_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                div_word(destval);
+            }
+            break;
+        case 7:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval;
+
+                DECODE_PRINTF("IDIV\tDWORD PTR ");
+                destoffset = decode_rm10_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                idiv_long(destval);
+            }
+            else {
+                u16 destval;
+
+                DECODE_PRINTF("IDIV\tWORD PTR ");
+                destoffset = decode_rm10_address(rl);
+                DECODE_PRINTF("\n");
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                idiv_word(destval);
+            }
+            break;
+        }
+        break;                  /* end mod==10 */
+    case 3:                    /* mod=11 */
+        switch (rh) {
+        case 0:                /* test word imm */
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 *destreg;
+                u32 srcval;
+
+                DECODE_PRINTF("TEST\t");
+                destreg = DECODE_RM_LONG_REGISTER(rl);
+                DECODE_PRINTF(",");
+                srcval = fetch_long_imm();
+                DECODE_PRINTF2("%x\n", srcval);
+                TRACE_AND_STEP();
+                test_long(*destreg, srcval);
+            }
+            else {
+                u16 *destreg;
+                u16 srcval;
+
+                DECODE_PRINTF("TEST\t");
+                destreg = DECODE_RM_WORD_REGISTER(rl);
+                DECODE_PRINTF(",");
+                srcval = fetch_word_imm();
+                DECODE_PRINTF2("%x\n", srcval);
+                TRACE_AND_STEP();
+                test_word(*destreg, srcval);
+            }
+            break;
+        case 1:
+            DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
+            HALT_SYS();
+            break;
+        case 2:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 *destreg;
+
+                DECODE_PRINTF("NOT\t");
+                destreg = DECODE_RM_LONG_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                *destreg = not_long(*destreg);
+            }
+            else {
+                u16 *destreg;
+
+                DECODE_PRINTF("NOT\t");
+                destreg = DECODE_RM_WORD_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                *destreg = not_word(*destreg);
+            }
+            break;
+        case 3:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 *destreg;
+
+                DECODE_PRINTF("NEG\t");
+                destreg = DECODE_RM_LONG_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                *destreg = neg_long(*destreg);
+            }
+            else {
+                u16 *destreg;
+
+                DECODE_PRINTF("NEG\t");
+                destreg = DECODE_RM_WORD_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                *destreg = neg_word(*destreg);
+            }
+            break;
+        case 4:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 *destreg;
+
+                DECODE_PRINTF("MUL\t");
+                destreg = DECODE_RM_LONG_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                mul_long(*destreg);     /*!!!  */
+            }
+            else {
+                u16 *destreg;
+
+                DECODE_PRINTF("MUL\t");
+                destreg = DECODE_RM_WORD_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                mul_word(*destreg);     /*!!!  */
+            }
+            break;
+        case 5:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 *destreg;
+
+                DECODE_PRINTF("IMUL\t");
+                destreg = DECODE_RM_LONG_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                imul_long(*destreg);
+            }
+            else {
+                u16 *destreg;
+
+                DECODE_PRINTF("IMUL\t");
+                destreg = DECODE_RM_WORD_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                imul_word(*destreg);
+            }
+            break;
+        case 6:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 *destreg;
+
+                DECODE_PRINTF("DIV\t");
+                destreg = DECODE_RM_LONG_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                div_long(*destreg);
+            }
+            else {
+                u16 *destreg;
+
+                DECODE_PRINTF("DIV\t");
+                destreg = DECODE_RM_WORD_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                div_word(*destreg);
+            }
+            break;
+        case 7:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 *destreg;
+
+                DECODE_PRINTF("IDIV\t");
+                destreg = DECODE_RM_LONG_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                idiv_long(*destreg);
+            }
+            else {
+                u16 *destreg;
+
+                DECODE_PRINTF("IDIV\t");
+                destreg = DECODE_RM_WORD_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                idiv_word(*destreg);
+            }
+            break;
+        }
+        break;                  /* end mod==11 */
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xf8
+****************************************************************************/
+static void
+x86emuOp_clc(u8 X86EMU_UNUSED(op1))
+{
+    /* clear the carry flag. */
+    START_OF_INSTR();
+    DECODE_PRINTF("CLC\n");
+    TRACE_AND_STEP();
+    CLEAR_FLAG(F_CF);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xf9
+****************************************************************************/
+static void
+x86emuOp_stc(u8 X86EMU_UNUSED(op1))
+{
+    /* set the carry flag. */
+    START_OF_INSTR();
+    DECODE_PRINTF("STC\n");
+    TRACE_AND_STEP();
+    SET_FLAG(F_CF);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xfa
+****************************************************************************/
+static void
+x86emuOp_cli(u8 X86EMU_UNUSED(op1))
+{
+    /* clear interrupts. */
+    START_OF_INSTR();
+    DECODE_PRINTF("CLI\n");
+    TRACE_AND_STEP();
+    CLEAR_FLAG(F_IF);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xfb
+****************************************************************************/
+static void
+x86emuOp_sti(u8 X86EMU_UNUSED(op1))
+{
+    /* enable  interrupts. */
+    START_OF_INSTR();
+    DECODE_PRINTF("STI\n");
+    TRACE_AND_STEP();
+    SET_FLAG(F_IF);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xfc
+****************************************************************************/
+static void
+x86emuOp_cld(u8 X86EMU_UNUSED(op1))
+{
+    /* clear interrupts. */
+    START_OF_INSTR();
+    DECODE_PRINTF("CLD\n");
+    TRACE_AND_STEP();
+    CLEAR_FLAG(F_DF);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xfd
+****************************************************************************/
+static void
+x86emuOp_std(u8 X86EMU_UNUSED(op1))
+{
+    /* clear interrupts. */
+    START_OF_INSTR();
+    DECODE_PRINTF("STD\n");
+    TRACE_AND_STEP();
+    SET_FLAG(F_DF);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xfe
+****************************************************************************/
+static void
+x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rh, rl;
+    u8 destval;
+    uint destoffset;
+    u8 *destreg;
+
+    /* Yet another special case instruction. */
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+#ifdef DEBUG
+    if (DEBUG_DECODE()) {
+        /* XXX DECODE_PRINTF may be changed to something more
+           general, so that it is important to leave the strings
+           in the same format, even though the result is that the
+           above test is done twice. */
+
+        switch (rh) {
+        case 0:
+            DECODE_PRINTF("INC\t");
+            break;
+        case 1:
+            DECODE_PRINTF("DEC\t");
+            break;
+        case 2:
+        case 3:
+        case 4:
+        case 5:
+        case 6:
+        case 7:
+            DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
+            HALT_SYS();
+            break;
+        }
+    }
+#endif
+    switch (mod) {
+    case 0:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF("\n");
+        switch (rh) {
+        case 0:                /* inc word ptr ... */
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            destval = inc_byte(destval);
+            store_data_byte(destoffset, destval);
+            break;
+        case 1:                /* dec word ptr ... */
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            destval = dec_byte(destval);
+            store_data_byte(destoffset, destval);
+            break;
+        }
+        break;
+    case 1:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF("\n");
+        switch (rh) {
+        case 0:
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            destval = inc_byte(destval);
+            store_data_byte(destoffset, destval);
+            break;
+        case 1:
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            destval = dec_byte(destval);
+            store_data_byte(destoffset, destval);
+            break;
+        }
+        break;
+    case 2:
+        DECODE_PRINTF("BYTE PTR ");
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF("\n");
+        switch (rh) {
+        case 0:
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            destval = inc_byte(destval);
+            store_data_byte(destoffset, destval);
+            break;
+        case 1:
+            destval = fetch_data_byte(destoffset);
+            TRACE_AND_STEP();
+            destval = dec_byte(destval);
+            store_data_byte(destoffset, destval);
+            break;
+        }
+        break;
+    case 3:
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        DECODE_PRINTF("\n");
+        switch (rh) {
+        case 0:
+            TRACE_AND_STEP();
+            *destreg = inc_byte(*destreg);
+            break;
+        case 1:
+            TRACE_AND_STEP();
+            *destreg = dec_byte(*destreg);
+            break;
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xff
+****************************************************************************/
+static void
+x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
+{
+    int mod, rh, rl;
+    uint destoffset = 0;
+    u16 *destreg;
+    u16 destval, destval2;
+
+    /* Yet another special case instruction. */
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+#ifdef DEBUG
+    if (DEBUG_DECODE()) {
+        /* XXX DECODE_PRINTF may be changed to something more
+           general, so that it is important to leave the strings
+           in the same format, even though the result is that the
+           above test is done twice. */
+
+        switch (rh) {
+        case 0:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                DECODE_PRINTF("INC\tDWORD PTR ");
+            }
+            else {
+                DECODE_PRINTF("INC\tWORD PTR ");
+            }
+            break;
+        case 1:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                DECODE_PRINTF("DEC\tDWORD PTR ");
+            }
+            else {
+                DECODE_PRINTF("DEC\tWORD PTR ");
+            }
+            break;
+        case 2:
+            DECODE_PRINTF("CALL\t");
+            break;
+        case 3:
+            DECODE_PRINTF("CALL\tFAR ");
+            break;
+        case 4:
+            DECODE_PRINTF("JMP\t");
+            break;
+        case 5:
+            DECODE_PRINTF("JMP\tFAR ");
+            break;
+        case 6:
+            DECODE_PRINTF("PUSH\t");
+            break;
+        case 7:
+            DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
+            HALT_SYS();
+            break;
+        }
+    }
+#endif
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        DECODE_PRINTF("\n");
+        switch (rh) {
+        case 0:                /* inc word ptr ... */
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval32;
+
+                destval32 = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                destval32 = inc_long(destval32);
+                store_data_long(destoffset, destval32);
+            }
+            else {
+                u16 destval16;
+
+                destval16 = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                destval16 = inc_word(destval16);
+                store_data_word(destoffset, destval16);
+            }
+            break;
+        case 1:                /* dec word ptr ... */
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval32;
+
+                destval32 = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                destval32 = dec_long(destval32);
+                store_data_long(destoffset, destval32);
+            }
+            else {
+                u16 destval16;
+
+                destval16 = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                destval16 = dec_word(destval16);
+                store_data_word(destoffset, destval16);
+            }
+            break;
+        case 2:                /* call word ptr ... */
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                push_long(M.x86.R_EIP);
+                M.x86.R_EIP = destval;
+            } else {
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                push_word(M.x86.R_IP);
+                M.x86.R_IP = destval;
+            }
+            break;
+        case 3:                /* call far ptr ... */
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                destval = fetch_data_long(destoffset);
+                destval2 = fetch_data_word(destoffset + 4);
+                TRACE_AND_STEP();
+                push_long(M.x86.R_CS);
+                M.x86.R_CS = destval2;
+                push_long(M.x86.R_EIP);
+                M.x86.R_EIP = destval;
+            } else {
+                destval = fetch_data_word(destoffset);
+                destval2 = fetch_data_word(destoffset + 2);
+                TRACE_AND_STEP();
+                push_word(M.x86.R_CS);
+                M.x86.R_CS = destval2;
+                push_word(M.x86.R_IP);
+                M.x86.R_IP = destval;
+            }
+            break;
+        case 4:                /* jmp word ptr ... */
+            destval = fetch_data_word(destoffset);
+            TRACE_AND_STEP();
+            M.x86.R_IP = destval;
+            break;
+        case 5:                /* jmp far ptr ... */
+            destval = fetch_data_word(destoffset);
+            destval2 = fetch_data_word(destoffset + 2);
+            TRACE_AND_STEP();
+            M.x86.R_IP = destval;
+            M.x86.R_CS = destval2;
+            break;
+        case 6:                /*  push word ptr ... */
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval32;
+
+                destval32 = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                push_long(destval32);
+            }
+            else {
+                u16 destval16;
+
+                destval16 = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                push_word(destval16);
+            }
+            break;
+        }
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        DECODE_PRINTF("\n");
+        switch (rh) {
+        case 0:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval32;
+
+                destval32 = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                destval32 = inc_long(destval32);
+                store_data_long(destoffset, destval32);
+            }
+            else {
+                u16 destval16;
+
+                destval16 = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                destval16 = inc_word(destval16);
+                store_data_word(destoffset, destval16);
+            }
+            break;
+        case 1:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval32;
+
+                destval32 = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                destval32 = dec_long(destval32);
+                store_data_long(destoffset, destval32);
+            }
+            else {
+                u16 destval16;
+
+                destval16 = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                destval16 = dec_word(destval16);
+                store_data_word(destoffset, destval16);
+            }
+            break;
+        case 2:                /* call word ptr ... */
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                push_long(M.x86.R_EIP);
+                M.x86.R_EIP = destval;
+            } else {
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                push_word(M.x86.R_IP);
+                M.x86.R_IP = destval;
+            }
+            break;
+        case 3:                /* call far ptr ... */
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                destval = fetch_data_long(destoffset);
+                destval2 = fetch_data_word(destoffset + 4);
+                TRACE_AND_STEP();
+                push_long(M.x86.R_CS);
+                M.x86.R_CS = destval2;
+                push_long(M.x86.R_EIP);
+                M.x86.R_EIP = destval;
+            } else {
+                destval = fetch_data_word(destoffset);
+                destval2 = fetch_data_word(destoffset + 2);
+                TRACE_AND_STEP();
+                push_word(M.x86.R_CS);
+                M.x86.R_CS = destval2;
+                push_word(M.x86.R_IP);
+                M.x86.R_IP = destval;
+            }
+            break;
+        case 4:                /* jmp word ptr ... */
+            destval = fetch_data_word(destoffset);
+            TRACE_AND_STEP();
+            M.x86.R_IP = destval;
+            break;
+        case 5:                /* jmp far ptr ... */
+            destval = fetch_data_word(destoffset);
+            destval2 = fetch_data_word(destoffset + 2);
+            TRACE_AND_STEP();
+            M.x86.R_IP = destval;
+            M.x86.R_CS = destval2;
+            break;
+        case 6:                /*  push word ptr ... */
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval32;
+
+                destval32 = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                push_long(destval32);
+            }
+            else {
+                u16 destval16;
+
+                destval16 = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                push_word(destval16);
+            }
+            break;
+        }
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        DECODE_PRINTF("\n");
+        switch (rh) {
+        case 0:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval32;
+
+                destval32 = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                destval32 = inc_long(destval32);
+                store_data_long(destoffset, destval32);
+            }
+            else {
+                u16 destval16;
+
+                destval16 = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                destval16 = inc_word(destval16);
+                store_data_word(destoffset, destval16);
+            }
+            break;
+        case 1:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval32;
+
+                destval32 = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                destval32 = dec_long(destval32);
+                store_data_long(destoffset, destval32);
+            }
+            else {
+                u16 destval16;
+
+                destval16 = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                destval16 = dec_word(destval16);
+                store_data_word(destoffset, destval16);
+            }
+            break;
+        case 2:                /* call word ptr ... */
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                destval = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                push_long(M.x86.R_EIP);
+                M.x86.R_EIP = destval;
+            } else {
+                destval = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                push_word(M.x86.R_IP);
+                M.x86.R_IP = destval;
+            }
+            break;
+        case 3:                /* call far ptr ... */
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                destval = fetch_data_long(destoffset);
+                destval2 = fetch_data_word(destoffset + 4);
+                TRACE_AND_STEP();
+                push_long(M.x86.R_CS);
+                M.x86.R_CS = destval2;
+                push_long(M.x86.R_EIP);
+                M.x86.R_EIP = destval;
+            } else {
+                destval = fetch_data_word(destoffset);
+                destval2 = fetch_data_word(destoffset + 2);
+                TRACE_AND_STEP();
+                push_word(M.x86.R_CS);
+                M.x86.R_CS = destval2;
+                push_word(M.x86.R_IP);
+                M.x86.R_IP = destval;
+            }
+            break;
+        case 4:                /* jmp word ptr ... */
+            destval = fetch_data_word(destoffset);
+            TRACE_AND_STEP();
+            M.x86.R_IP = destval;
+            break;
+        case 5:                /* jmp far ptr ... */
+            destval = fetch_data_word(destoffset);
+            destval2 = fetch_data_word(destoffset + 2);
+            TRACE_AND_STEP();
+            M.x86.R_IP = destval;
+            M.x86.R_CS = destval2;
+            break;
+        case 6:                /*  push word ptr ... */
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 destval32;
+
+                destval32 = fetch_data_long(destoffset);
+                TRACE_AND_STEP();
+                push_long(destval32);
+            }
+            else {
+                u16 destval16;
+
+                destval16 = fetch_data_word(destoffset);
+                TRACE_AND_STEP();
+                push_word(destval16);
+            }
+            break;
+        }
+        break;
+    case 3:
+        switch (rh) {
+        case 0:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 *destreg32;
+
+                destreg32 = DECODE_RM_LONG_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                *destreg32 = inc_long(*destreg32);
+            }
+            else {
+                u16 *destreg16;
+
+                destreg16 = DECODE_RM_WORD_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                *destreg16 = inc_word(*destreg16);
+            }
+            break;
+        case 1:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 *destreg32;
+
+                destreg32 = DECODE_RM_LONG_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                *destreg32 = dec_long(*destreg32);
+            }
+            else {
+                u16 *destreg16;
+
+                destreg16 = DECODE_RM_WORD_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                *destreg16 = dec_word(*destreg16);
+            }
+            break;
+        case 2:                /* call word ptr ... */
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                destreg = (u16 *)DECODE_RM_LONG_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                push_long(M.x86.R_EIP);
+                M.x86.R_EIP = *destreg;
+            } else {
+                destreg = DECODE_RM_WORD_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                push_word(M.x86.R_IP);
+                M.x86.R_IP = *destreg;
+            }
+            break;
+        case 3:                /* jmp far ptr ... */
+            DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
+            TRACE_AND_STEP();
+            HALT_SYS();
+            break;
+
+        case 4:                /* jmp  ... */
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            M.x86.R_IP = (u16) (*destreg);
+            break;
+        case 5:                /* jmp far ptr ... */
+            DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
+            TRACE_AND_STEP();
+            HALT_SYS();
+            break;
+        case 6:
+            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+                u32 *destreg32;
+
+                destreg32 = DECODE_RM_LONG_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                push_long(*destreg32);
+            }
+            else {
+                u16 *destreg16;
+
+                destreg16 = DECODE_RM_WORD_REGISTER(rl);
+                DECODE_PRINTF("\n");
+                TRACE_AND_STEP();
+                push_word(*destreg16);
+            }
+            break;
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/***************************************************************************
+ * Single byte operation code table:
+ **************************************************************************/
+void (*x86emu_optab[256]) (u8) = {
+/*  0x00 */ x86emuOp_add_byte_RM_R,
+/*  0x01 */ x86emuOp_add_word_RM_R,
+/*  0x02 */ x86emuOp_add_byte_R_RM,
+/*  0x03 */ x86emuOp_add_word_R_RM,
+/*  0x04 */ x86emuOp_add_byte_AL_IMM,
+/*  0x05 */ x86emuOp_add_word_AX_IMM,
+/*  0x06 */ x86emuOp_push_ES,
+/*  0x07 */ x86emuOp_pop_ES,
+/*  0x08 */ x86emuOp_or_byte_RM_R,
+/*  0x09 */ x86emuOp_or_word_RM_R,
+/*  0x0a */ x86emuOp_or_byte_R_RM,
+/*  0x0b */ x86emuOp_or_word_R_RM,
+/*  0x0c */ x86emuOp_or_byte_AL_IMM,
+/*  0x0d */ x86emuOp_or_word_AX_IMM,
+/*  0x0e */ x86emuOp_push_CS,
+/*  0x0f */ x86emuOp_two_byte,
+/*  0x10 */ x86emuOp_adc_byte_RM_R,
+/*  0x11 */ x86emuOp_adc_word_RM_R,
+/*  0x12 */ x86emuOp_adc_byte_R_RM,
+/*  0x13 */ x86emuOp_adc_word_R_RM,
+/*  0x14 */ x86emuOp_adc_byte_AL_IMM,
+/*  0x15 */ x86emuOp_adc_word_AX_IMM,
+/*  0x16 */ x86emuOp_push_SS,
+/*  0x17 */ x86emuOp_pop_SS,
+/*  0x18 */ x86emuOp_sbb_byte_RM_R,
+/*  0x19 */ x86emuOp_sbb_word_RM_R,
+/*  0x1a */ x86emuOp_sbb_byte_R_RM,
+/*  0x1b */ x86emuOp_sbb_word_R_RM,
+/*  0x1c */ x86emuOp_sbb_byte_AL_IMM,
+/*  0x1d */ x86emuOp_sbb_word_AX_IMM,
+/*  0x1e */ x86emuOp_push_DS,
+/*  0x1f */ x86emuOp_pop_DS,
+/*  0x20 */ x86emuOp_and_byte_RM_R,
+/*  0x21 */ x86emuOp_and_word_RM_R,
+/*  0x22 */ x86emuOp_and_byte_R_RM,
+/*  0x23 */ x86emuOp_and_word_R_RM,
+/*  0x24 */ x86emuOp_and_byte_AL_IMM,
+/*  0x25 */ x86emuOp_and_word_AX_IMM,
+/*  0x26 */ x86emuOp_segovr_ES,
+/*  0x27 */ x86emuOp_daa,
+/*  0x28 */ x86emuOp_sub_byte_RM_R,
+/*  0x29 */ x86emuOp_sub_word_RM_R,
+/*  0x2a */ x86emuOp_sub_byte_R_RM,
+/*  0x2b */ x86emuOp_sub_word_R_RM,
+/*  0x2c */ x86emuOp_sub_byte_AL_IMM,
+/*  0x2d */ x86emuOp_sub_word_AX_IMM,
+/*  0x2e */ x86emuOp_segovr_CS,
+/*  0x2f */ x86emuOp_das,
+/*  0x30 */ x86emuOp_xor_byte_RM_R,
+/*  0x31 */ x86emuOp_xor_word_RM_R,
+/*  0x32 */ x86emuOp_xor_byte_R_RM,
+/*  0x33 */ x86emuOp_xor_word_R_RM,
+/*  0x34 */ x86emuOp_xor_byte_AL_IMM,
+/*  0x35 */ x86emuOp_xor_word_AX_IMM,
+/*  0x36 */ x86emuOp_segovr_SS,
+/*  0x37 */ x86emuOp_aaa,
+/*  0x38 */ x86emuOp_cmp_byte_RM_R,
+/*  0x39 */ x86emuOp_cmp_word_RM_R,
+/*  0x3a */ x86emuOp_cmp_byte_R_RM,
+/*  0x3b */ x86emuOp_cmp_word_R_RM,
+/*  0x3c */ x86emuOp_cmp_byte_AL_IMM,
+/*  0x3d */ x86emuOp_cmp_word_AX_IMM,
+/*  0x3e */ x86emuOp_segovr_DS,
+/*  0x3f */ x86emuOp_aas,
+/*  0x40 */ x86emuOp_inc_AX,
+/*  0x41 */ x86emuOp_inc_CX,
+/*  0x42 */ x86emuOp_inc_DX,
+/*  0x43 */ x86emuOp_inc_BX,
+/*  0x44 */ x86emuOp_inc_SP,
+/*  0x45 */ x86emuOp_inc_BP,
+/*  0x46 */ x86emuOp_inc_SI,
+/*  0x47 */ x86emuOp_inc_DI,
+/*  0x48 */ x86emuOp_dec_AX,
+/*  0x49 */ x86emuOp_dec_CX,
+/*  0x4a */ x86emuOp_dec_DX,
+/*  0x4b */ x86emuOp_dec_BX,
+/*  0x4c */ x86emuOp_dec_SP,
+/*  0x4d */ x86emuOp_dec_BP,
+/*  0x4e */ x86emuOp_dec_SI,
+/*  0x4f */ x86emuOp_dec_DI,
+/*  0x50 */ x86emuOp_push_AX,
+/*  0x51 */ x86emuOp_push_CX,
+/*  0x52 */ x86emuOp_push_DX,
+/*  0x53 */ x86emuOp_push_BX,
+/*  0x54 */ x86emuOp_push_SP,
+/*  0x55 */ x86emuOp_push_BP,
+/*  0x56 */ x86emuOp_push_SI,
+/*  0x57 */ x86emuOp_push_DI,
+/*  0x58 */ x86emuOp_pop_AX,
+/*  0x59 */ x86emuOp_pop_CX,
+/*  0x5a */ x86emuOp_pop_DX,
+/*  0x5b */ x86emuOp_pop_BX,
+/*  0x5c */ x86emuOp_pop_SP,
+/*  0x5d */ x86emuOp_pop_BP,
+/*  0x5e */ x86emuOp_pop_SI,
+/*  0x5f */ x86emuOp_pop_DI,
+/*  0x60 */ x86emuOp_push_all,
+/*  0x61 */ x86emuOp_pop_all,
+                                                /*  0x62 */ x86emuOp_illegal_op,
+                                                /* bound */
+                                                /*  0x63 */ x86emuOp_illegal_op,
+                                                /* arpl */
+/*  0x64 */ x86emuOp_segovr_FS,
+/*  0x65 */ x86emuOp_segovr_GS,
+/*  0x66 */ x86emuOp_prefix_data,
+/*  0x67 */ x86emuOp_prefix_addr,
+/*  0x68 */ x86emuOp_push_word_IMM,
+/*  0x69 */ x86emuOp_imul_word_IMM,
+/*  0x6a */ x86emuOp_push_byte_IMM,
+/*  0x6b */ x86emuOp_imul_byte_IMM,
+/*  0x6c */ x86emuOp_ins_byte,
+/*  0x6d */ x86emuOp_ins_word,
+/*  0x6e */ x86emuOp_outs_byte,
+/*  0x6f */ x86emuOp_outs_word,
+/*  0x70 */ x86emuOp_jump_near_O,
+/*  0x71 */ x86emuOp_jump_near_NO,
+/*  0x72 */ x86emuOp_jump_near_B,
+/*  0x73 */ x86emuOp_jump_near_NB,
+/*  0x74 */ x86emuOp_jump_near_Z,
+/*  0x75 */ x86emuOp_jump_near_NZ,
+/*  0x76 */ x86emuOp_jump_near_BE,
+/*  0x77 */ x86emuOp_jump_near_NBE,
+/*  0x78 */ x86emuOp_jump_near_S,
+/*  0x79 */ x86emuOp_jump_near_NS,
+/*  0x7a */ x86emuOp_jump_near_P,
+/*  0x7b */ x86emuOp_jump_near_NP,
+/*  0x7c */ x86emuOp_jump_near_L,
+/*  0x7d */ x86emuOp_jump_near_NL,
+/*  0x7e */ x86emuOp_jump_near_LE,
+/*  0x7f */ x86emuOp_jump_near_NLE,
+/*  0x80 */ x86emuOp_opc80_byte_RM_IMM,
+/*  0x81 */ x86emuOp_opc81_word_RM_IMM,
+/*  0x82 */ x86emuOp_opc82_byte_RM_IMM,
+/*  0x83 */ x86emuOp_opc83_word_RM_IMM,
+/*  0x84 */ x86emuOp_test_byte_RM_R,
+/*  0x85 */ x86emuOp_test_word_RM_R,
+/*  0x86 */ x86emuOp_xchg_byte_RM_R,
+/*  0x87 */ x86emuOp_xchg_word_RM_R,
+/*  0x88 */ x86emuOp_mov_byte_RM_R,
+/*  0x89 */ x86emuOp_mov_word_RM_R,
+/*  0x8a */ x86emuOp_mov_byte_R_RM,
+/*  0x8b */ x86emuOp_mov_word_R_RM,
+/*  0x8c */ x86emuOp_mov_word_RM_SR,
+/*  0x8d */ x86emuOp_lea_word_R_M,
+/*  0x8e */ x86emuOp_mov_word_SR_RM,
+/*  0x8f */ x86emuOp_pop_RM,
+/*  0x90 */ x86emuOp_nop,
+/*  0x91 */ x86emuOp_xchg_word_AX_CX,
+/*  0x92 */ x86emuOp_xchg_word_AX_DX,
+/*  0x93 */ x86emuOp_xchg_word_AX_BX,
+/*  0x94 */ x86emuOp_xchg_word_AX_SP,
+/*  0x95 */ x86emuOp_xchg_word_AX_BP,
+/*  0x96 */ x86emuOp_xchg_word_AX_SI,
+/*  0x97 */ x86emuOp_xchg_word_AX_DI,
+/*  0x98 */ x86emuOp_cbw,
+/*  0x99 */ x86emuOp_cwd,
+/*  0x9a */ x86emuOp_call_far_IMM,
+/*  0x9b */ x86emuOp_wait,
+/*  0x9c */ x86emuOp_pushf_word,
+/*  0x9d */ x86emuOp_popf_word,
+/*  0x9e */ x86emuOp_sahf,
+/*  0x9f */ x86emuOp_lahf,
+/*  0xa0 */ x86emuOp_mov_AL_M_IMM,
+/*  0xa1 */ x86emuOp_mov_AX_M_IMM,
+/*  0xa2 */ x86emuOp_mov_M_AL_IMM,
+/*  0xa3 */ x86emuOp_mov_M_AX_IMM,
+/*  0xa4 */ x86emuOp_movs_byte,
+/*  0xa5 */ x86emuOp_movs_word,
+/*  0xa6 */ x86emuOp_cmps_byte,
+/*  0xa7 */ x86emuOp_cmps_word,
+/*  0xa8 */ x86emuOp_test_AL_IMM,
+/*  0xa9 */ x86emuOp_test_AX_IMM,
+/*  0xaa */ x86emuOp_stos_byte,
+/*  0xab */ x86emuOp_stos_word,
+/*  0xac */ x86emuOp_lods_byte,
+/*  0xad */ x86emuOp_lods_word,
+/*  0xac */ x86emuOp_scas_byte,
+/*  0xad */ x86emuOp_scas_word,
+/*  0xb0 */ x86emuOp_mov_byte_AL_IMM,
+/*  0xb1 */ x86emuOp_mov_byte_CL_IMM,
+/*  0xb2 */ x86emuOp_mov_byte_DL_IMM,
+/*  0xb3 */ x86emuOp_mov_byte_BL_IMM,
+/*  0xb4 */ x86emuOp_mov_byte_AH_IMM,
+/*  0xb5 */ x86emuOp_mov_byte_CH_IMM,
+/*  0xb6 */ x86emuOp_mov_byte_DH_IMM,
+/*  0xb7 */ x86emuOp_mov_byte_BH_IMM,
+/*  0xb8 */ x86emuOp_mov_word_AX_IMM,
+/*  0xb9 */ x86emuOp_mov_word_CX_IMM,
+/*  0xba */ x86emuOp_mov_word_DX_IMM,
+/*  0xbb */ x86emuOp_mov_word_BX_IMM,
+/*  0xbc */ x86emuOp_mov_word_SP_IMM,
+/*  0xbd */ x86emuOp_mov_word_BP_IMM,
+/*  0xbe */ x86emuOp_mov_word_SI_IMM,
+/*  0xbf */ x86emuOp_mov_word_DI_IMM,
+/*  0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
+/*  0xc1 */ x86emuOp_opcC1_word_RM_MEM,
+/*  0xc2 */ x86emuOp_ret_near_IMM,
+/*  0xc3 */ x86emuOp_ret_near,
+/*  0xc4 */ x86emuOp_les_R_IMM,
+/*  0xc5 */ x86emuOp_lds_R_IMM,
+/*  0xc6 */ x86emuOp_mov_byte_RM_IMM,
+/*  0xc7 */ x86emuOp_mov_word_RM_IMM,
+/*  0xc8 */ x86emuOp_enter,
+/*  0xc9 */ x86emuOp_leave,
+/*  0xca */ x86emuOp_ret_far_IMM,
+/*  0xcb */ x86emuOp_ret_far,
+/*  0xcc */ x86emuOp_int3,
+/*  0xcd */ x86emuOp_int_IMM,
+/*  0xce */ x86emuOp_into,
+/*  0xcf */ x86emuOp_iret,
+/*  0xd0 */ x86emuOp_opcD0_byte_RM_1,
+/*  0xd1 */ x86emuOp_opcD1_word_RM_1,
+/*  0xd2 */ x86emuOp_opcD2_byte_RM_CL,
+/*  0xd3 */ x86emuOp_opcD3_word_RM_CL,
+/*  0xd4 */ x86emuOp_aam,
+/*  0xd5 */ x86emuOp_aad,
+                                                /*  0xd6 */ x86emuOp_illegal_op,
+                                                /* Undocumented SETALC instruction */
+/*  0xd7 */ x86emuOp_xlat,
+/*  0xd8 */ x86emuOp_esc_coprocess_d8,
+/*  0xd9 */ x86emuOp_esc_coprocess_d9,
+/*  0xda */ x86emuOp_esc_coprocess_da,
+/*  0xdb */ x86emuOp_esc_coprocess_db,
+/*  0xdc */ x86emuOp_esc_coprocess_dc,
+/*  0xdd */ x86emuOp_esc_coprocess_dd,
+/*  0xde */ x86emuOp_esc_coprocess_de,
+/*  0xdf */ x86emuOp_esc_coprocess_df,
+/*  0xe0 */ x86emuOp_loopne,
+/*  0xe1 */ x86emuOp_loope,
+/*  0xe2 */ x86emuOp_loop,
+/*  0xe3 */ x86emuOp_jcxz,
+/*  0xe4 */ x86emuOp_in_byte_AL_IMM,
+/*  0xe5 */ x86emuOp_in_word_AX_IMM,
+/*  0xe6 */ x86emuOp_out_byte_IMM_AL,
+/*  0xe7 */ x86emuOp_out_word_IMM_AX,
+/*  0xe8 */ x86emuOp_call_near_IMM,
+/*  0xe9 */ x86emuOp_jump_near_IMM,
+/*  0xea */ x86emuOp_jump_far_IMM,
+/*  0xeb */ x86emuOp_jump_byte_IMM,
+/*  0xec */ x86emuOp_in_byte_AL_DX,
+/*  0xed */ x86emuOp_in_word_AX_DX,
+/*  0xee */ x86emuOp_out_byte_DX_AL,
+/*  0xef */ x86emuOp_out_word_DX_AX,
+/*  0xf0 */ x86emuOp_lock,
+/*  0xf1 */ x86emuOp_illegal_op,
+/*  0xf2 */ x86emuOp_repne,
+/*  0xf3 */ x86emuOp_repe,
+/*  0xf4 */ x86emuOp_halt,
+/*  0xf5 */ x86emuOp_cmc,
+/*  0xf6 */ x86emuOp_opcF6_byte_RM,
+/*  0xf7 */ x86emuOp_opcF7_word_RM,
+/*  0xf8 */ x86emuOp_clc,
+/*  0xf9 */ x86emuOp_stc,
+/*  0xfa */ x86emuOp_cli,
+/*  0xfb */ x86emuOp_sti,
+/*  0xfc */ x86emuOp_cld,
+/*  0xfd */ x86emuOp_std,
+/*  0xfe */ x86emuOp_opcFE_byte_RM,
+/*  0xff */ x86emuOp_opcFF_word_RM,
+};
diff --git a/plat/pc65oo2/emu/x86emu/ops.o b/plat/pc65oo2/emu/x86emu/ops.o
new file mode 100644
index 000000000..ebd6e773d
Binary files /dev/null and b/plat/pc65oo2/emu/x86emu/ops.o differ
diff --git a/plat/pc65oo2/emu/x86emu/ops2.c b/plat/pc65oo2/emu/x86emu/ops2.c
new file mode 100644
index 000000000..5ed2bf68d
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/ops2.c
@@ -0,0 +1,3008 @@
+/****************************************************************************
+*
+*						Realmode X86 Emulator Library
+*
+*            	Copyright (C) 1996-1999 SciTech Software, Inc.
+* 				     Copyright (C) David Mosberger-Tang
+* 					   Copyright (C) 1999 Egbert Eich
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:		ANSI C
+* Environment:	Any
+* Developer:    Kendall Bennett
+*
+* Description:  This file includes subroutines to implement the decoding
+*               and emulation of all the x86 extended two-byte processor
+*               instructions.
+*
+****************************************************************************/
+
+#include "x86emu/x86emui.h"
+
+#undef bswap_32
+#define bswap_32(x) (((x & 0xff000000) >> 24) | \
+		     ((x & 0x00ff0000) >> 8) | \
+		     ((x & 0x0000ff00) << 8) | \
+		     ((x & 0x000000ff) << 24))
+
+/*----------------------------- Implementation ----------------------------*/
+
+/****************************************************************************
+PARAMETERS:
+op1 - Instruction op code
+
+REMARKS:
+Handles illegal opcodes.
+****************************************************************************/
+static void
+x86emuOp2_illegal_op(u8 op2)
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
+    TRACE_REGS();
+    printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
+           M.x86.R_CS, M.x86.R_IP - 2, op2);
+    HALT_SYS();
+    END_OF_INSTR();
+}
+
+#define xorl(a,b)   ((a) && !(b)) || (!(a) && (b))
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0x31
+****************************************************************************/
+static void
+x86emuOp2_rdtsc(u8 X86EMU_UNUSED(op2))
+{
+#ifdef __HAS_LONG_LONG__
+    static u64 counter = 0;
+#else
+    static u32 counter = 0;
+#endif
+
+    counter += 0x10000;
+
+    /* read timestamp counter */
+    /*
+     * Note that instead of actually trying to accurately measure this, we just
+     * increase the counter by a fixed amount every time we hit one of these
+     * instructions.  Feel free to come up with a better method.
+     */
+    START_OF_INSTR();
+    DECODE_PRINTF("RDTSC\n");
+    TRACE_AND_STEP();
+#ifdef __HAS_LONG_LONG__
+    M.x86.R_EAX = counter & 0xffffffff;
+    M.x86.R_EDX = counter >> 32;
+#else
+    M.x86.R_EAX = counter;
+    M.x86.R_EDX = 0;
+#endif
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0x80-0x8F
+****************************************************************************/
+static void
+x86emuOp2_long_jump(u8 op2)
+{
+    s32 target;
+    const char *name = NULL;
+    int cond = 0;
+
+    /* conditional jump to word offset. */
+    START_OF_INSTR();
+    switch (op2) {
+    case 0x80:
+        name = "JO\t";
+        cond = ACCESS_FLAG(F_OF);
+        break;
+    case 0x81:
+        name = "JNO\t";
+        cond = !ACCESS_FLAG(F_OF);
+        break;
+    case 0x82:
+        name = "JB\t";
+        cond = ACCESS_FLAG(F_CF);
+        break;
+    case 0x83:
+        name = "JNB\t";
+        cond = !ACCESS_FLAG(F_CF);
+        break;
+    case 0x84:
+        name = "JZ\t";
+        cond = ACCESS_FLAG(F_ZF);
+        break;
+    case 0x85:
+        name = "JNZ\t";
+        cond = !ACCESS_FLAG(F_ZF);
+        break;
+    case 0x86:
+        name = "JBE\t";
+        cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
+        break;
+    case 0x87:
+        name = "JNBE\t";
+        cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
+        break;
+    case 0x88:
+        name = "JS\t";
+        cond = ACCESS_FLAG(F_SF);
+        break;
+    case 0x89:
+        name = "JNS\t";
+        cond = !ACCESS_FLAG(F_SF);
+        break;
+    case 0x8a:
+        name = "JP\t";
+        cond = ACCESS_FLAG(F_PF);
+        break;
+    case 0x8b:
+        name = "JNP\t";
+        cond = !ACCESS_FLAG(F_PF);
+        break;
+    case 0x8c:
+        name = "JL\t";
+        cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
+        break;
+    case 0x8d:
+        name = "JNL\t";
+        cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)));
+        break;
+    case 0x8e:
+        name = "JLE\t";
+        cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
+                ACCESS_FLAG(F_ZF));
+        break;
+    case 0x8f:
+        name = "JNLE\t";
+        cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
+                 ACCESS_FLAG(F_ZF));
+        break;
+    }
+    DECODE_PRINTF(name);
+    (void) name;
+    target = (s16) fetch_word_imm();
+    target += (s16) M.x86.R_IP;
+    DECODE_PRINTF2("%04x\n", target);
+    TRACE_AND_STEP();
+    if (cond)
+        M.x86.R_IP = (u16) target;
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0x90-0x9F
+****************************************************************************/
+static void
+x86emuOp2_set_byte(u8 op2)
+{
+    int mod, rl, rh;
+    uint destoffset;
+    u8 *destreg;
+    const char *name = NULL;
+    int cond = 0;
+
+    START_OF_INSTR();
+    switch (op2) {
+    case 0x90:
+        name = "SETO\t";
+        cond = ACCESS_FLAG(F_OF);
+        break;
+    case 0x91:
+        name = "SETNO\t";
+        cond = !ACCESS_FLAG(F_OF);
+        break;
+    case 0x92:
+        name = "SETB\t";
+        cond = ACCESS_FLAG(F_CF);
+        break;
+    case 0x93:
+        name = "SETNB\t";
+        cond = !ACCESS_FLAG(F_CF);
+        break;
+    case 0x94:
+        name = "SETZ\t";
+        cond = ACCESS_FLAG(F_ZF);
+        break;
+    case 0x95:
+        name = "SETNZ\t";
+        cond = !ACCESS_FLAG(F_ZF);
+        break;
+    case 0x96:
+        name = "SETBE\t";
+        cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
+        break;
+    case 0x97:
+        name = "SETNBE\t";
+        cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
+        break;
+    case 0x98:
+        name = "SETS\t";
+        cond = ACCESS_FLAG(F_SF);
+        break;
+    case 0x99:
+        name = "SETNS\t";
+        cond = !ACCESS_FLAG(F_SF);
+        break;
+    case 0x9a:
+        name = "SETP\t";
+        cond = ACCESS_FLAG(F_PF);
+        break;
+    case 0x9b:
+        name = "SETNP\t";
+        cond = !ACCESS_FLAG(F_PF);
+        break;
+    case 0x9c:
+        name = "SETL\t";
+        cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
+        break;
+    case 0x9d:
+        name = "SETNL\t";
+        cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
+        break;
+    case 0x9e:
+        name = "SETLE\t";
+        cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
+                ACCESS_FLAG(F_ZF));
+        break;
+    case 0x9f:
+        name = "SETNLE\t";
+        cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
+                 ACCESS_FLAG(F_ZF));
+        break;
+    }
+    DECODE_PRINTF(name);
+    (void) name;
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destoffset = decode_rm00_address(rl);
+        TRACE_AND_STEP();
+        store_data_byte(destoffset, cond ? 0x01 : 0x00);
+        break;
+    case 1:
+        destoffset = decode_rm01_address(rl);
+        TRACE_AND_STEP();
+        store_data_byte(destoffset, cond ? 0x01 : 0x00);
+        break;
+    case 2:
+        destoffset = decode_rm10_address(rl);
+        TRACE_AND_STEP();
+        store_data_byte(destoffset, cond ? 0x01 : 0x00);
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_BYTE_REGISTER(rl);
+        TRACE_AND_STEP();
+        *destreg = cond ? 0x01 : 0x00;
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xa0
+****************************************************************************/
+static void
+x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("PUSH\tFS\n");
+    TRACE_AND_STEP();
+    push_word(M.x86.R_FS);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xa1
+****************************************************************************/
+static void
+x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("POP\tFS\n");
+    TRACE_AND_STEP();
+    M.x86.R_FS = pop_word();
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output
+Handles opcode 0x0f,0xa2
+****************************************************************************/
+static void
+x86emuOp2_cpuid(u8 X86EMU_UNUSED(op2))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("CPUID\n");
+    TRACE_AND_STEP();
+    cpuid();
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xa3
+****************************************************************************/
+static void
+x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+    int bit, disp;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("BT\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval;
+            u32 *shiftreg;
+
+            srcoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0x1F;
+            disp = (s16) * shiftreg >> 5;
+            srcval = fetch_data_long(srcoffset + disp);
+            CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
+        }
+        else {
+            u16 srcval;
+            u16 *shiftreg;
+
+            srcoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0xF;
+            disp = (s16) * shiftreg >> 4;
+            srcval = fetch_data_word(srcoffset + disp);
+            CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval;
+            u32 *shiftreg;
+
+            srcoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0x1F;
+            disp = (s16) * shiftreg >> 5;
+            srcval = fetch_data_long(srcoffset + disp);
+            CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
+        }
+        else {
+            u16 srcval;
+            u16 *shiftreg;
+
+            srcoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0xF;
+            disp = (s16) * shiftreg >> 4;
+            srcval = fetch_data_word(srcoffset + disp);
+            CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval;
+            u32 *shiftreg;
+
+            srcoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0x1F;
+            disp = (s16) * shiftreg >> 5;
+            srcval = fetch_data_long(srcoffset + disp);
+            CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
+        }
+        else {
+            u16 srcval;
+            u16 *shiftreg;
+
+            srcoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0xF;
+            disp = (s16) * shiftreg >> 4;
+            srcval = fetch_data_word(srcoffset + disp);
+            CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *srcreg, *shiftreg;
+
+            srcreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0x1F;
+            CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit), F_CF);
+        }
+        else {
+            u16 *srcreg, *shiftreg;
+
+            srcreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0xF;
+            CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit), F_CF);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xa4
+****************************************************************************/
+static void
+x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rl, rh;
+    uint destoffset;
+    u8 shift;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("SHLD\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *shiftreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            DECODE_PRINTF2("%d\n", shift);
+            TRACE_AND_STEP();
+            destval = fetch_data_long(destoffset);
+            destval = shld_long(destval, *shiftreg, shift);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *shiftreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            DECODE_PRINTF2("%d\n", shift);
+            TRACE_AND_STEP();
+            destval = fetch_data_word(destoffset);
+            destval = shld_word(destval, *shiftreg, shift);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *shiftreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            DECODE_PRINTF2("%d\n", shift);
+            TRACE_AND_STEP();
+            destval = fetch_data_long(destoffset);
+            destval = shld_long(destval, *shiftreg, shift);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *shiftreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            DECODE_PRINTF2("%d\n", shift);
+            TRACE_AND_STEP();
+            destval = fetch_data_word(destoffset);
+            destval = shld_word(destval, *shiftreg, shift);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *shiftreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            DECODE_PRINTF2("%d\n", shift);
+            TRACE_AND_STEP();
+            destval = fetch_data_long(destoffset);
+            destval = shld_long(destval, *shiftreg, shift);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *shiftreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            DECODE_PRINTF2("%d\n", shift);
+            TRACE_AND_STEP();
+            destval = fetch_data_word(destoffset);
+            destval = shld_word(destval, *shiftreg, shift);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *shiftreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            DECODE_PRINTF2("%d\n", shift);
+            TRACE_AND_STEP();
+            *destreg = shld_long(*destreg, *shiftreg, shift);
+        }
+        else {
+            u16 *destreg, *shiftreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            DECODE_PRINTF2("%d\n", shift);
+            TRACE_AND_STEP();
+            *destreg = shld_word(*destreg, *shiftreg, shift);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xa5
+****************************************************************************/
+static void
+x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("SHLD\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *shiftreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",CL\n");
+            TRACE_AND_STEP();
+            destval = fetch_data_long(destoffset);
+            destval = shld_long(destval, *shiftreg, M.x86.R_CL);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *shiftreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",CL\n");
+            TRACE_AND_STEP();
+            destval = fetch_data_word(destoffset);
+            destval = shld_word(destval, *shiftreg, M.x86.R_CL);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *shiftreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",CL\n");
+            TRACE_AND_STEP();
+            destval = fetch_data_long(destoffset);
+            destval = shld_long(destval, *shiftreg, M.x86.R_CL);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *shiftreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",CL\n");
+            TRACE_AND_STEP();
+            destval = fetch_data_word(destoffset);
+            destval = shld_word(destval, *shiftreg, M.x86.R_CL);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *shiftreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",CL\n");
+            TRACE_AND_STEP();
+            destval = fetch_data_long(destoffset);
+            destval = shld_long(destval, *shiftreg, M.x86.R_CL);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *shiftreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",CL\n");
+            TRACE_AND_STEP();
+            destval = fetch_data_word(destoffset);
+            destval = shld_word(destval, *shiftreg, M.x86.R_CL);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *shiftreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",CL\n");
+            TRACE_AND_STEP();
+            *destreg = shld_long(*destreg, *shiftreg, M.x86.R_CL);
+        }
+        else {
+            u16 *destreg, *shiftreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",CL\n");
+            TRACE_AND_STEP();
+            *destreg = shld_word(*destreg, *shiftreg, M.x86.R_CL);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xa8
+****************************************************************************/
+static void
+x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("PUSH\tGS\n");
+    TRACE_AND_STEP();
+    push_word(M.x86.R_GS);
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xa9
+****************************************************************************/
+static void
+x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("POP\tGS\n");
+    TRACE_AND_STEP();
+    M.x86.R_GS = pop_word();
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xab
+****************************************************************************/
+static void
+x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+    int bit, disp;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("BTS\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, mask;
+            u32 *shiftreg;
+
+            srcoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0x1F;
+            disp = (s16) * shiftreg >> 5;
+            srcval = fetch_data_long(srcoffset + disp);
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            store_data_long(srcoffset + disp, srcval | mask);
+        }
+        else {
+            u16 srcval, mask;
+            u16 *shiftreg;
+
+            srcoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0xF;
+            disp = (s16) * shiftreg >> 4;
+            srcval = fetch_data_word(srcoffset + disp);
+            mask = (u16) (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            store_data_word(srcoffset + disp, srcval | mask);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, mask;
+            u32 *shiftreg;
+
+            srcoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0x1F;
+            disp = (s16) * shiftreg >> 5;
+            srcval = fetch_data_long(srcoffset + disp);
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            store_data_long(srcoffset + disp, srcval | mask);
+        }
+        else {
+            u16 srcval, mask;
+            u16 *shiftreg;
+
+            srcoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0xF;
+            disp = (s16) * shiftreg >> 4;
+            srcval = fetch_data_word(srcoffset + disp);
+            mask = (u16) (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            store_data_word(srcoffset + disp, srcval | mask);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, mask;
+            u32 *shiftreg;
+
+            srcoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0x1F;
+            disp = (s16) * shiftreg >> 5;
+            srcval = fetch_data_long(srcoffset + disp);
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            store_data_long(srcoffset + disp, srcval | mask);
+        }
+        else {
+            u16 srcval, mask;
+            u16 *shiftreg;
+
+            srcoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0xF;
+            disp = (s16) * shiftreg >> 4;
+            srcval = fetch_data_word(srcoffset + disp);
+            mask = (u16) (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            store_data_word(srcoffset + disp, srcval | mask);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *srcreg, *shiftreg;
+            u32 mask;
+
+            srcreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0x1F;
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
+            *srcreg |= mask;
+        }
+        else {
+            u16 *srcreg, *shiftreg;
+            u16 mask;
+
+            srcreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0xF;
+            mask = (u16) (0x1 << bit);
+            CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
+            *srcreg |= mask;
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xac
+****************************************************************************/
+static void
+x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rl, rh;
+    uint destoffset;
+    u8 shift;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("SHLD\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *shiftreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            DECODE_PRINTF2("%d\n", shift);
+            TRACE_AND_STEP();
+            destval = fetch_data_long(destoffset);
+            destval = shrd_long(destval, *shiftreg, shift);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *shiftreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            DECODE_PRINTF2("%d\n", shift);
+            TRACE_AND_STEP();
+            destval = fetch_data_word(destoffset);
+            destval = shrd_word(destval, *shiftreg, shift);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *shiftreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            DECODE_PRINTF2("%d\n", shift);
+            TRACE_AND_STEP();
+            destval = fetch_data_long(destoffset);
+            destval = shrd_long(destval, *shiftreg, shift);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *shiftreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            DECODE_PRINTF2("%d\n", shift);
+            TRACE_AND_STEP();
+            destval = fetch_data_word(destoffset);
+            destval = shrd_word(destval, *shiftreg, shift);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *shiftreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            DECODE_PRINTF2("%d\n", shift);
+            TRACE_AND_STEP();
+            destval = fetch_data_long(destoffset);
+            destval = shrd_long(destval, *shiftreg, shift);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *shiftreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            DECODE_PRINTF2("%d\n", shift);
+            TRACE_AND_STEP();
+            destval = fetch_data_word(destoffset);
+            destval = shrd_word(destval, *shiftreg, shift);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *shiftreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            DECODE_PRINTF2("%d\n", shift);
+            TRACE_AND_STEP();
+            *destreg = shrd_long(*destreg, *shiftreg, shift);
+        }
+        else {
+            u16 *destreg, *shiftreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            DECODE_PRINTF2("%d\n", shift);
+            TRACE_AND_STEP();
+            *destreg = shrd_word(*destreg, *shiftreg, shift);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xad
+****************************************************************************/
+static void
+x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rl, rh;
+    uint destoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("SHLD\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *shiftreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",CL\n");
+            TRACE_AND_STEP();
+            destval = fetch_data_long(destoffset);
+            destval = shrd_long(destval, *shiftreg, M.x86.R_CL);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *shiftreg;
+
+            destoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",CL\n");
+            TRACE_AND_STEP();
+            destval = fetch_data_word(destoffset);
+            destval = shrd_word(destval, *shiftreg, M.x86.R_CL);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *shiftreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",CL\n");
+            TRACE_AND_STEP();
+            destval = fetch_data_long(destoffset);
+            destval = shrd_long(destval, *shiftreg, M.x86.R_CL);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *shiftreg;
+
+            destoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",CL\n");
+            TRACE_AND_STEP();
+            destval = fetch_data_word(destoffset);
+            destval = shrd_word(destval, *shiftreg, M.x86.R_CL);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 destval;
+            u32 *shiftreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",CL\n");
+            TRACE_AND_STEP();
+            destval = fetch_data_long(destoffset);
+            destval = shrd_long(destval, *shiftreg, M.x86.R_CL);
+            store_data_long(destoffset, destval);
+        }
+        else {
+            u16 destval;
+            u16 *shiftreg;
+
+            destoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",CL\n");
+            TRACE_AND_STEP();
+            destval = fetch_data_word(destoffset);
+            destval = shrd_word(destval, *shiftreg, M.x86.R_CL);
+            store_data_word(destoffset, destval);
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *shiftreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",CL\n");
+            TRACE_AND_STEP();
+            *destreg = shrd_long(*destreg, *shiftreg, M.x86.R_CL);
+        }
+        else {
+            u16 *destreg, *shiftreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",CL\n");
+            TRACE_AND_STEP();
+            *destreg = shrd_word(*destreg, *shiftreg, M.x86.R_CL);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xaf
+****************************************************************************/
+static void
+x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("IMUL\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+            u32 res_lo, res_hi;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            TRACE_AND_STEP();
+            imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval);
+            if (res_hi != 0) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u32) res_lo;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+            u32 res;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            TRACE_AND_STEP();
+            res = (s16) * destreg * (s16) srcval;
+            if (res > 0xFFFF) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u16) res;
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+            u32 res_lo, res_hi;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            TRACE_AND_STEP();
+            imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval);
+            if (res_hi != 0) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u32) res_lo;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+            u32 res;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            TRACE_AND_STEP();
+            res = (s16) * destreg * (s16) srcval;
+            if (res > 0xFFFF) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u16) res;
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+            u32 res_lo, res_hi;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_long(srcoffset);
+            TRACE_AND_STEP();
+            imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval);
+            if (res_hi != 0) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u32) res_lo;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+            u32 res;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_word(srcoffset);
+            TRACE_AND_STEP();
+            res = (s16) * destreg * (s16) srcval;
+            if (res > 0xFFFF) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u16) res;
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg, *srcreg;
+            u32 res_lo, res_hi;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_LONG_REGISTER(rl);
+            TRACE_AND_STEP();
+            imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) * srcreg);
+            if (res_hi != 0) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u32) res_lo;
+        }
+        else {
+            u16 *destreg, *srcreg;
+            u32 res;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_WORD_REGISTER(rl);
+            res = (s16) * destreg * (s16) * srcreg;
+            if (res > 0xFFFF) {
+                SET_FLAG(F_CF);
+                SET_FLAG(F_OF);
+            }
+            else {
+                CLEAR_FLAG(F_CF);
+                CLEAR_FLAG(F_OF);
+            }
+            *destreg = (u16) res;
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xb2
+****************************************************************************/
+static void
+x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rh, rl;
+    u16 *dstreg;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("LSS\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        dstreg = DECODE_RM_WORD_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm00_address(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *dstreg = fetch_data_word(srcoffset);
+        M.x86.R_SS = fetch_data_word(srcoffset + 2);
+        break;
+    case 1:
+        dstreg = DECODE_RM_WORD_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm01_address(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *dstreg = fetch_data_word(srcoffset);
+        M.x86.R_SS = fetch_data_word(srcoffset + 2);
+        break;
+    case 2:
+        dstreg = DECODE_RM_WORD_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm10_address(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *dstreg = fetch_data_word(srcoffset);
+        M.x86.R_SS = fetch_data_word(srcoffset + 2);
+        break;
+    case 3:                    /* register to register */
+        /* UNDEFINED! */
+        TRACE_AND_STEP();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xb3
+****************************************************************************/
+static void
+x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+    int bit, disp;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("BTR\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, mask;
+            u32 *shiftreg;
+
+            srcoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0x1F;
+            disp = (s16) * shiftreg >> 5;
+            srcval = fetch_data_long(srcoffset + disp);
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            store_data_long(srcoffset + disp, srcval & ~mask);
+        }
+        else {
+            u16 srcval, mask;
+            u16 *shiftreg;
+
+            srcoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0xF;
+            disp = (s16) * shiftreg >> 4;
+            srcval = fetch_data_word(srcoffset + disp);
+            mask = (u16) (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            store_data_word(srcoffset + disp, (u16) (srcval & ~mask));
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, mask;
+            u32 *shiftreg;
+
+            srcoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0x1F;
+            disp = (s16) * shiftreg >> 5;
+            srcval = fetch_data_long(srcoffset + disp);
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            store_data_long(srcoffset + disp, srcval & ~mask);
+        }
+        else {
+            u16 srcval, mask;
+            u16 *shiftreg;
+
+            srcoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0xF;
+            disp = (s16) * shiftreg >> 4;
+            srcval = fetch_data_word(srcoffset + disp);
+            mask = (u16) (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            store_data_word(srcoffset + disp, (u16) (srcval & ~mask));
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, mask;
+            u32 *shiftreg;
+
+            srcoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0x1F;
+            disp = (s16) * shiftreg >> 5;
+            srcval = fetch_data_long(srcoffset + disp);
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            store_data_long(srcoffset + disp, srcval & ~mask);
+        }
+        else {
+            u16 srcval, mask;
+            u16 *shiftreg;
+
+            srcoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0xF;
+            disp = (s16) * shiftreg >> 4;
+            srcval = fetch_data_word(srcoffset + disp);
+            mask = (u16) (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            store_data_word(srcoffset + disp, (u16) (srcval & ~mask));
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *srcreg, *shiftreg;
+            u32 mask;
+
+            srcreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0x1F;
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
+            *srcreg &= ~mask;
+        }
+        else {
+            u16 *srcreg, *shiftreg;
+            u16 mask;
+
+            srcreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0xF;
+            mask = (u16) (0x1 << bit);
+            CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
+            *srcreg &= ~mask;
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xb4
+****************************************************************************/
+static void
+x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rh, rl;
+    u16 *dstreg;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("LFS\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        dstreg = DECODE_RM_WORD_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm00_address(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *dstreg = fetch_data_word(srcoffset);
+        M.x86.R_FS = fetch_data_word(srcoffset + 2);
+        break;
+    case 1:
+        dstreg = DECODE_RM_WORD_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm01_address(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *dstreg = fetch_data_word(srcoffset);
+        M.x86.R_FS = fetch_data_word(srcoffset + 2);
+        break;
+    case 2:
+        dstreg = DECODE_RM_WORD_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm10_address(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *dstreg = fetch_data_word(srcoffset);
+        M.x86.R_FS = fetch_data_word(srcoffset + 2);
+        break;
+    case 3:                    /* register to register */
+        /* UNDEFINED! */
+        TRACE_AND_STEP();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xb5
+****************************************************************************/
+static void
+x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rh, rl;
+    u16 *dstreg;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("LGS\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        dstreg = DECODE_RM_WORD_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm00_address(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *dstreg = fetch_data_word(srcoffset);
+        M.x86.R_GS = fetch_data_word(srcoffset + 2);
+        break;
+    case 1:
+        dstreg = DECODE_RM_WORD_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm01_address(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *dstreg = fetch_data_word(srcoffset);
+        M.x86.R_GS = fetch_data_word(srcoffset + 2);
+        break;
+    case 2:
+        dstreg = DECODE_RM_WORD_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm10_address(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *dstreg = fetch_data_word(srcoffset);
+        M.x86.R_GS = fetch_data_word(srcoffset + 2);
+        break;
+    case 3:                    /* register to register */
+        /* UNDEFINED! */
+        TRACE_AND_STEP();
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xb6
+****************************************************************************/
+static void
+x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOVZX\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_byte(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = srcval;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = fetch_data_byte(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = srcval;
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_byte(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = srcval;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = fetch_data_byte(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = srcval;
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_byte(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = srcval;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = fetch_data_byte(srcoffset);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = srcval;
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u8 *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_BYTE_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = *srcreg;
+        }
+        else {
+            u16 *destreg;
+            u8 *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_BYTE_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = *srcreg;
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xb7
+****************************************************************************/
+static void
+x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+    u32 *destreg;
+    u32 srcval;
+    u16 *srcreg;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOVZX\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destreg = DECODE_RM_LONG_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm00_address(rl);
+        srcval = fetch_data_word(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = srcval;
+        break;
+    case 1:
+        destreg = DECODE_RM_LONG_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm01_address(rl);
+        srcval = fetch_data_word(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = srcval;
+        break;
+    case 2:
+        destreg = DECODE_RM_LONG_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm10_address(rl);
+        srcval = fetch_data_word(srcoffset);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = srcval;
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_LONG_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_WORD_REGISTER(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = *srcreg;
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xba
+****************************************************************************/
+static void
+x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+    int bit;
+
+    START_OF_INSTR();
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (rh) {
+    case 4:
+        DECODE_PRINTF("BT\t");
+        break;
+    case 5:
+        DECODE_PRINTF("BTS\t");
+        break;
+    case 6:
+        DECODE_PRINTF("BTR\t");
+        break;
+    case 7:
+        DECODE_PRINTF("BTC\t");
+        break;
+    default:
+        DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
+        TRACE_REGS();
+        printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
+               M.x86.R_CS, M.x86.R_IP - 3, op2, (mod << 6) | (rh << 3) | rl);
+        HALT_SYS();
+    }
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, mask;
+            u8 shift;
+
+            srcoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            TRACE_AND_STEP();
+            bit = shift & 0x1F;
+            srcval = fetch_data_long(srcoffset);
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            switch (rh) {
+            case 5:
+                store_data_long(srcoffset, srcval | mask);
+                break;
+            case 6:
+                store_data_long(srcoffset, srcval & ~mask);
+                break;
+            case 7:
+                store_data_long(srcoffset, srcval ^ mask);
+                break;
+            default:
+                break;
+            }
+        }
+        else {
+            u16 srcval, mask;
+            u8 shift;
+
+            srcoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            TRACE_AND_STEP();
+            bit = shift & 0xF;
+            srcval = fetch_data_word(srcoffset);
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            switch (rh) {
+            case 5:
+                store_data_word(srcoffset, srcval | mask);
+                break;
+            case 6:
+                store_data_word(srcoffset, srcval & ~mask);
+                break;
+            case 7:
+                store_data_word(srcoffset, srcval ^ mask);
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, mask;
+            u8 shift;
+
+            srcoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            TRACE_AND_STEP();
+            bit = shift & 0x1F;
+            srcval = fetch_data_long(srcoffset);
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            switch (rh) {
+            case 5:
+                store_data_long(srcoffset, srcval | mask);
+                break;
+            case 6:
+                store_data_long(srcoffset, srcval & ~mask);
+                break;
+            case 7:
+                store_data_long(srcoffset, srcval ^ mask);
+                break;
+            default:
+                break;
+            }
+        }
+        else {
+            u16 srcval, mask;
+            u8 shift;
+
+            srcoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            TRACE_AND_STEP();
+            bit = shift & 0xF;
+            srcval = fetch_data_word(srcoffset);
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            switch (rh) {
+            case 5:
+                store_data_word(srcoffset, srcval | mask);
+                break;
+            case 6:
+                store_data_word(srcoffset, srcval & ~mask);
+                break;
+            case 7:
+                store_data_word(srcoffset, srcval ^ mask);
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, mask;
+            u8 shift;
+
+            srcoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            TRACE_AND_STEP();
+            bit = shift & 0x1F;
+            srcval = fetch_data_long(srcoffset);
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            switch (rh) {
+            case 5:
+                store_data_long(srcoffset, srcval | mask);
+                break;
+            case 6:
+                store_data_long(srcoffset, srcval & ~mask);
+                break;
+            case 7:
+                store_data_long(srcoffset, srcval ^ mask);
+                break;
+            default:
+                break;
+            }
+        }
+        else {
+            u16 srcval, mask;
+            u8 shift;
+
+            srcoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            TRACE_AND_STEP();
+            bit = shift & 0xF;
+            srcval = fetch_data_word(srcoffset);
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            switch (rh) {
+            case 5:
+                store_data_word(srcoffset, srcval | mask);
+                break;
+            case 6:
+                store_data_word(srcoffset, srcval & ~mask);
+                break;
+            case 7:
+                store_data_word(srcoffset, srcval ^ mask);
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *srcreg;
+            u32 mask;
+            u8 shift;
+
+            srcreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            TRACE_AND_STEP();
+            bit = shift & 0x1F;
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
+            switch (rh) {
+            case 5:
+                *srcreg |= mask;
+                break;
+            case 6:
+                *srcreg &= ~mask;
+                break;
+            case 7:
+                *srcreg ^= mask;
+                break;
+            default:
+                break;
+            }
+        }
+        else {
+            u16 *srcreg;
+            u16 mask;
+            u8 shift;
+
+            srcreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            shift = fetch_byte_imm();
+            TRACE_AND_STEP();
+            bit = shift & 0xF;
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
+            switch (rh) {
+            case 5:
+                *srcreg |= mask;
+                break;
+            case 6:
+                *srcreg &= ~mask;
+                break;
+            case 7:
+                *srcreg ^= mask;
+                break;
+            default:
+                break;
+            }
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xbb
+****************************************************************************/
+static void
+x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+    int bit, disp;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("BTC\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, mask;
+            u32 *shiftreg;
+
+            srcoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0x1F;
+            disp = (s16) * shiftreg >> 5;
+            srcval = fetch_data_long(srcoffset + disp);
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            store_data_long(srcoffset + disp, srcval ^ mask);
+        }
+        else {
+            u16 srcval, mask;
+            u16 *shiftreg;
+
+            srcoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0xF;
+            disp = (s16) * shiftreg >> 4;
+            srcval = fetch_data_word(srcoffset + disp);
+            mask = (u16) (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            store_data_word(srcoffset + disp, (u16) (srcval ^ mask));
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, mask;
+            u32 *shiftreg;
+
+            srcoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0x1F;
+            disp = (s16) * shiftreg >> 5;
+            srcval = fetch_data_long(srcoffset + disp);
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            store_data_long(srcoffset + disp, srcval ^ mask);
+        }
+        else {
+            u16 srcval, mask;
+            u16 *shiftreg;
+
+            srcoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0xF;
+            disp = (s16) * shiftreg >> 4;
+            srcval = fetch_data_word(srcoffset + disp);
+            mask = (u16) (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            store_data_word(srcoffset + disp, (u16) (srcval ^ mask));
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, mask;
+            u32 *shiftreg;
+
+            srcoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0x1F;
+            disp = (s16) * shiftreg >> 5;
+            srcval = fetch_data_long(srcoffset + disp);
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            store_data_long(srcoffset + disp, srcval ^ mask);
+        }
+        else {
+            u16 srcval, mask;
+            u16 *shiftreg;
+
+            srcoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0xF;
+            disp = (s16) * shiftreg >> 4;
+            srcval = fetch_data_word(srcoffset + disp);
+            mask = (u16) (0x1 << bit);
+            CONDITIONAL_SET_FLAG(srcval & mask, F_CF);
+            store_data_word(srcoffset + disp, (u16) (srcval ^ mask));
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *srcreg, *shiftreg;
+            u32 mask;
+
+            srcreg = DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0x1F;
+            mask = (0x1 << bit);
+            CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
+            *srcreg ^= mask;
+        }
+        else {
+            u16 *srcreg, *shiftreg;
+            u16 mask;
+
+            srcreg = DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            shiftreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            bit = *shiftreg & 0xF;
+            mask = (u16) (0x1 << bit);
+            CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF);
+            *srcreg ^= mask;
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xbc
+****************************************************************************/
+static void
+x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("BSF\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, *dstreg;
+
+            srcoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            dstreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            srcval = fetch_data_long(srcoffset);
+            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
+            for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
+                if ((srcval >> *dstreg) & 1)
+                    break;
+        }
+        else {
+            u16 srcval, *dstreg;
+
+            srcoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            dstreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            srcval = fetch_data_word(srcoffset);
+            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
+            for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
+                if ((srcval >> *dstreg) & 1)
+                    break;
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, *dstreg;
+
+            srcoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            dstreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            srcval = fetch_data_long(srcoffset);
+            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
+            for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
+                if ((srcval >> *dstreg) & 1)
+                    break;
+        }
+        else {
+            u16 srcval, *dstreg;
+
+            srcoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            dstreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            srcval = fetch_data_word(srcoffset);
+            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
+            for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
+                if ((srcval >> *dstreg) & 1)
+                    break;
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, *dstreg;
+
+            srcoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            dstreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            srcval = fetch_data_long(srcoffset);
+            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
+            for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
+                if ((srcval >> *dstreg) & 1)
+                    break;
+        }
+        else {
+            u16 srcval, *dstreg;
+
+            srcoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            dstreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            srcval = fetch_data_word(srcoffset);
+            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
+            for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
+                if ((srcval >> *dstreg) & 1)
+                    break;
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, *dstreg;
+
+            srcval = *DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            dstreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
+            for (*dstreg = 0; *dstreg < 32; (*dstreg)++)
+                if ((srcval >> *dstreg) & 1)
+                    break;
+        }
+        else {
+            u16 srcval, *dstreg;
+
+            srcval = *DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            dstreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
+            for (*dstreg = 0; *dstreg < 16; (*dstreg)++)
+                if ((srcval >> *dstreg) & 1)
+                    break;
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xbd
+****************************************************************************/
+static void
+x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("BSR\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, *dstreg;
+
+            srcoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            dstreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            srcval = fetch_data_long(srcoffset);
+            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
+            for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
+                if ((srcval >> *dstreg) & 1)
+                    break;
+        }
+        else {
+            u16 srcval, *dstreg;
+
+            srcoffset = decode_rm00_address(rl);
+            DECODE_PRINTF(",");
+            dstreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            srcval = fetch_data_word(srcoffset);
+            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
+            for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
+                if ((srcval >> *dstreg) & 1)
+                    break;
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, *dstreg;
+
+            srcoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            dstreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            srcval = fetch_data_long(srcoffset);
+            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
+            for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
+                if ((srcval >> *dstreg) & 1)
+                    break;
+        }
+        else {
+            u16 srcval, *dstreg;
+
+            srcoffset = decode_rm01_address(rl);
+            DECODE_PRINTF(",");
+            dstreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            srcval = fetch_data_word(srcoffset);
+            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
+            for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
+                if ((srcval >> *dstreg) & 1)
+                    break;
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, *dstreg;
+
+            srcoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            dstreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            srcval = fetch_data_long(srcoffset);
+            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
+            for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
+                if ((srcval >> *dstreg) & 1)
+                    break;
+        }
+        else {
+            u16 srcval, *dstreg;
+
+            srcoffset = decode_rm10_address(rl);
+            DECODE_PRINTF(",");
+            dstreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            srcval = fetch_data_word(srcoffset);
+            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
+            for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
+                if ((srcval >> *dstreg) & 1)
+                    break;
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 srcval, *dstreg;
+
+            srcval = *DECODE_RM_LONG_REGISTER(rl);
+            DECODE_PRINTF(",");
+            dstreg = DECODE_RM_LONG_REGISTER(rh);
+            TRACE_AND_STEP();
+            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
+            for (*dstreg = 31; *dstreg > 0; (*dstreg)--)
+                if ((srcval >> *dstreg) & 1)
+                    break;
+        }
+        else {
+            u16 srcval, *dstreg;
+
+            srcval = *DECODE_RM_WORD_REGISTER(rl);
+            DECODE_PRINTF(",");
+            dstreg = DECODE_RM_WORD_REGISTER(rh);
+            TRACE_AND_STEP();
+            CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
+            for (*dstreg = 15; *dstreg > 0; (*dstreg)--)
+                if ((srcval >> *dstreg) & 1)
+                    break;
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xbe
+****************************************************************************/
+static void
+x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOVSX\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = (s32) ((s8) fetch_data_byte(srcoffset));
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = srcval;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm00_address(rl);
+            srcval = (s16) ((s8) fetch_data_byte(srcoffset));
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = srcval;
+        }
+        break;
+    case 1:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = (s32) ((s8) fetch_data_byte(srcoffset));
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = srcval;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm01_address(rl);
+            srcval = (s16) ((s8) fetch_data_byte(srcoffset));
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = srcval;
+        }
+        break;
+    case 2:
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u32 srcval;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = (s32) ((s8) fetch_data_byte(srcoffset));
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = srcval;
+        }
+        else {
+            u16 *destreg;
+            u16 srcval;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcoffset = decode_rm10_address(rl);
+            srcval = (s16) ((s8) fetch_data_byte(srcoffset));
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = srcval;
+        }
+        break;
+    case 3:                    /* register to register */
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            u32 *destreg;
+            u8 *srcreg;
+
+            destreg = DECODE_RM_LONG_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_BYTE_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = (s32) ((s8) * srcreg);
+        }
+        else {
+            u16 *destreg;
+            u8 *srcreg;
+
+            destreg = DECODE_RM_WORD_REGISTER(rh);
+            DECODE_PRINTF(",");
+            srcreg = DECODE_RM_BYTE_REGISTER(rl);
+            DECODE_PRINTF("\n");
+            TRACE_AND_STEP();
+            *destreg = (s16) ((s8) * srcreg);
+        }
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xbf
+****************************************************************************/
+static void
+x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
+{
+    int mod, rl, rh;
+    uint srcoffset;
+    u32 *destreg;
+    u32 srcval;
+    u16 *srcreg;
+
+    START_OF_INSTR();
+    DECODE_PRINTF("MOVSX\t");
+    FETCH_DECODE_MODRM(mod, rh, rl);
+    switch (mod) {
+    case 0:
+        destreg = DECODE_RM_LONG_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm00_address(rl);
+        srcval = (s32) ((s16) fetch_data_word(srcoffset));
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = srcval;
+        break;
+    case 1:
+        destreg = DECODE_RM_LONG_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm01_address(rl);
+        srcval = (s32) ((s16) fetch_data_word(srcoffset));
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = srcval;
+        break;
+    case 2:
+        destreg = DECODE_RM_LONG_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcoffset = decode_rm10_address(rl);
+        srcval = (s32) ((s16) fetch_data_word(srcoffset));
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = srcval;
+        break;
+    case 3:                    /* register to register */
+        destreg = DECODE_RM_LONG_REGISTER(rh);
+        DECODE_PRINTF(",");
+        srcreg = DECODE_RM_WORD_REGISTER(rl);
+        DECODE_PRINTF("\n");
+        TRACE_AND_STEP();
+        *destreg = (s32) ((s16) * srcreg);
+        break;
+    }
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/* Handles opcodes 0xc8-0xcf */
+static void
+x86emuOp2_bswap(u8 X86EMU_UNUSED(op2))
+{
+    START_OF_INSTR();
+    DECODE_PRINTF("BSWAP\n");
+    TRACE_AND_STEP();
+
+    switch (op2) {
+    case 0xc8:
+        M.x86.R_EAX = bswap_32(M.x86.R_EAX);
+        break;
+    case 0xc9:
+        M.x86.R_ECX = bswap_32(M.x86.R_ECX);
+        break;
+    case 0xca:
+        M.x86.R_EDX = bswap_32(M.x86.R_EDX);
+        break;
+    case 0xcb:
+        M.x86.R_EBX = bswap_32(M.x86.R_EBX);
+        break;
+    case 0xcc:
+        M.x86.R_ESP = bswap_32(M.x86.R_ESP);
+        break;
+    case 0xcd:
+        M.x86.R_EBP = bswap_32(M.x86.R_EBP);
+        break;
+    case 0xce:
+        M.x86.R_ESI = bswap_32(M.x86.R_ESI);
+        break;
+    case 0xcf:
+        M.x86.R_EDI = bswap_32(M.x86.R_EDI);
+        break;
+    default:
+        /* can't happen */
+        break;
+    }
+
+    DECODE_CLEAR_SEGOVR();
+    END_OF_INSTR();
+}
+
+/***************************************************************************
+ * Double byte operation code table:
+ **************************************************************************/
+void (*x86emu_optab2[256]) (u8) = {
+                                        /*  0x00 */ x86emuOp2_illegal_op,
+                                        /* Group F (ring 0 PM)      */
+                                                /*  0x01 */ x86emuOp2_illegal_op,
+                                                /* Group G (ring 0 PM)      */
+                                                /*  0x02 */ x86emuOp2_illegal_op,
+                                                /* lar (ring 0 PM)          */
+                                                /*  0x03 */ x86emuOp2_illegal_op,
+                                                /* lsl (ring 0 PM)          */
+/*  0x04 */ x86emuOp2_illegal_op,
+                                                /*  0x05 */ x86emuOp2_illegal_op,
+                                                /* loadall (undocumented)   */
+                                                /*  0x06 */ x86emuOp2_illegal_op,
+                                                /* clts (ring 0 PM)         */
+                                                /*  0x07 */ x86emuOp2_illegal_op,
+                                                /* loadall (undocumented)   */
+                                                /*  0x08 */ x86emuOp2_illegal_op,
+                                                /* invd (ring 0 PM)         */
+                                                /*  0x09 */ x86emuOp2_illegal_op,
+                                                /* wbinvd (ring 0 PM)       */
+/*  0x0a */ x86emuOp2_illegal_op,
+/*  0x0b */ x86emuOp2_illegal_op,
+/*  0x0c */ x86emuOp2_illegal_op,
+/*  0x0d */ x86emuOp2_illegal_op,
+/*  0x0e */ x86emuOp2_illegal_op,
+/*  0x0f */ x86emuOp2_illegal_op,
+/*  0x10 */ x86emuOp2_illegal_op,
+/*  0x11 */ x86emuOp2_illegal_op,
+/*  0x12 */ x86emuOp2_illegal_op,
+/*  0x13 */ x86emuOp2_illegal_op,
+/*  0x14 */ x86emuOp2_illegal_op,
+/*  0x15 */ x86emuOp2_illegal_op,
+/*  0x16 */ x86emuOp2_illegal_op,
+/*  0x17 */ x86emuOp2_illegal_op,
+/*  0x18 */ x86emuOp2_illegal_op,
+/*  0x19 */ x86emuOp2_illegal_op,
+/*  0x1a */ x86emuOp2_illegal_op,
+/*  0x1b */ x86emuOp2_illegal_op,
+/*  0x1c */ x86emuOp2_illegal_op,
+/*  0x1d */ x86emuOp2_illegal_op,
+/*  0x1e */ x86emuOp2_illegal_op,
+/*  0x1f */ x86emuOp2_illegal_op,
+                                                /*  0x20 */ x86emuOp2_illegal_op,
+                                                /* mov reg32,creg (ring 0 PM) */
+                                                /*  0x21 */ x86emuOp2_illegal_op,
+                                                /* mov reg32,dreg (ring 0 PM) */
+                                                /*  0x22 */ x86emuOp2_illegal_op,
+                                                /* mov creg,reg32 (ring 0 PM) */
+                                                /*  0x23 */ x86emuOp2_illegal_op,
+                                                /* mov dreg,reg32 (ring 0 PM) */
+                                                /*  0x24 */ x86emuOp2_illegal_op,
+                                                /* mov reg32,treg (ring 0 PM) */
+/*  0x25 */ x86emuOp2_illegal_op,
+                                                /*  0x26 */ x86emuOp2_illegal_op,
+                                                /* mov treg,reg32 (ring 0 PM) */
+/*  0x27 */ x86emuOp2_illegal_op,
+/*  0x28 */ x86emuOp2_illegal_op,
+/*  0x29 */ x86emuOp2_illegal_op,
+/*  0x2a */ x86emuOp2_illegal_op,
+/*  0x2b */ x86emuOp2_illegal_op,
+/*  0x2c */ x86emuOp2_illegal_op,
+/*  0x2d */ x86emuOp2_illegal_op,
+/*  0x2e */ x86emuOp2_illegal_op,
+/*  0x2f */ x86emuOp2_illegal_op,
+/*  0x30 */ x86emuOp2_illegal_op,
+/*  0x31 */ x86emuOp2_rdtsc,
+/*  0x32 */ x86emuOp2_illegal_op,
+/*  0x33 */ x86emuOp2_illegal_op,
+/*  0x34 */ x86emuOp2_illegal_op,
+/*  0x35 */ x86emuOp2_illegal_op,
+/*  0x36 */ x86emuOp2_illegal_op,
+/*  0x37 */ x86emuOp2_illegal_op,
+/*  0x38 */ x86emuOp2_illegal_op,
+/*  0x39 */ x86emuOp2_illegal_op,
+/*  0x3a */ x86emuOp2_illegal_op,
+/*  0x3b */ x86emuOp2_illegal_op,
+/*  0x3c */ x86emuOp2_illegal_op,
+/*  0x3d */ x86emuOp2_illegal_op,
+/*  0x3e */ x86emuOp2_illegal_op,
+/*  0x3f */ x86emuOp2_illegal_op,
+/*  0x40 */ x86emuOp2_illegal_op,
+/*  0x41 */ x86emuOp2_illegal_op,
+/*  0x42 */ x86emuOp2_illegal_op,
+/*  0x43 */ x86emuOp2_illegal_op,
+/*  0x44 */ x86emuOp2_illegal_op,
+/*  0x45 */ x86emuOp2_illegal_op,
+/*  0x46 */ x86emuOp2_illegal_op,
+/*  0x47 */ x86emuOp2_illegal_op,
+/*  0x48 */ x86emuOp2_illegal_op,
+/*  0x49 */ x86emuOp2_illegal_op,
+/*  0x4a */ x86emuOp2_illegal_op,
+/*  0x4b */ x86emuOp2_illegal_op,
+/*  0x4c */ x86emuOp2_illegal_op,
+/*  0x4d */ x86emuOp2_illegal_op,
+/*  0x4e */ x86emuOp2_illegal_op,
+/*  0x4f */ x86emuOp2_illegal_op,
+/*  0x50 */ x86emuOp2_illegal_op,
+/*  0x51 */ x86emuOp2_illegal_op,
+/*  0x52 */ x86emuOp2_illegal_op,
+/*  0x53 */ x86emuOp2_illegal_op,
+/*  0x54 */ x86emuOp2_illegal_op,
+/*  0x55 */ x86emuOp2_illegal_op,
+/*  0x56 */ x86emuOp2_illegal_op,
+/*  0x57 */ x86emuOp2_illegal_op,
+/*  0x58 */ x86emuOp2_illegal_op,
+/*  0x59 */ x86emuOp2_illegal_op,
+/*  0x5a */ x86emuOp2_illegal_op,
+/*  0x5b */ x86emuOp2_illegal_op,
+/*  0x5c */ x86emuOp2_illegal_op,
+/*  0x5d */ x86emuOp2_illegal_op,
+/*  0x5e */ x86emuOp2_illegal_op,
+/*  0x5f */ x86emuOp2_illegal_op,
+/*  0x60 */ x86emuOp2_illegal_op,
+/*  0x61 */ x86emuOp2_illegal_op,
+/*  0x62 */ x86emuOp2_illegal_op,
+/*  0x63 */ x86emuOp2_illegal_op,
+/*  0x64 */ x86emuOp2_illegal_op,
+/*  0x65 */ x86emuOp2_illegal_op,
+/*  0x66 */ x86emuOp2_illegal_op,
+/*  0x67 */ x86emuOp2_illegal_op,
+/*  0x68 */ x86emuOp2_illegal_op,
+/*  0x69 */ x86emuOp2_illegal_op,
+/*  0x6a */ x86emuOp2_illegal_op,
+/*  0x6b */ x86emuOp2_illegal_op,
+/*  0x6c */ x86emuOp2_illegal_op,
+/*  0x6d */ x86emuOp2_illegal_op,
+/*  0x6e */ x86emuOp2_illegal_op,
+/*  0x6f */ x86emuOp2_illegal_op,
+/*  0x70 */ x86emuOp2_illegal_op,
+/*  0x71 */ x86emuOp2_illegal_op,
+/*  0x72 */ x86emuOp2_illegal_op,
+/*  0x73 */ x86emuOp2_illegal_op,
+/*  0x74 */ x86emuOp2_illegal_op,
+/*  0x75 */ x86emuOp2_illegal_op,
+/*  0x76 */ x86emuOp2_illegal_op,
+/*  0x77 */ x86emuOp2_illegal_op,
+/*  0x78 */ x86emuOp2_illegal_op,
+/*  0x79 */ x86emuOp2_illegal_op,
+/*  0x7a */ x86emuOp2_illegal_op,
+/*  0x7b */ x86emuOp2_illegal_op,
+/*  0x7c */ x86emuOp2_illegal_op,
+/*  0x7d */ x86emuOp2_illegal_op,
+/*  0x7e */ x86emuOp2_illegal_op,
+/*  0x7f */ x86emuOp2_illegal_op,
+/*  0x80 */ x86emuOp2_long_jump,
+/*  0x81 */ x86emuOp2_long_jump,
+/*  0x82 */ x86emuOp2_long_jump,
+/*  0x83 */ x86emuOp2_long_jump,
+/*  0x84 */ x86emuOp2_long_jump,
+/*  0x85 */ x86emuOp2_long_jump,
+/*  0x86 */ x86emuOp2_long_jump,
+/*  0x87 */ x86emuOp2_long_jump,
+/*  0x88 */ x86emuOp2_long_jump,
+/*  0x89 */ x86emuOp2_long_jump,
+/*  0x8a */ x86emuOp2_long_jump,
+/*  0x8b */ x86emuOp2_long_jump,
+/*  0x8c */ x86emuOp2_long_jump,
+/*  0x8d */ x86emuOp2_long_jump,
+/*  0x8e */ x86emuOp2_long_jump,
+/*  0x8f */ x86emuOp2_long_jump,
+/*  0x90 */ x86emuOp2_set_byte,
+/*  0x91 */ x86emuOp2_set_byte,
+/*  0x92 */ x86emuOp2_set_byte,
+/*  0x93 */ x86emuOp2_set_byte,
+/*  0x94 */ x86emuOp2_set_byte,
+/*  0x95 */ x86emuOp2_set_byte,
+/*  0x96 */ x86emuOp2_set_byte,
+/*  0x97 */ x86emuOp2_set_byte,
+/*  0x98 */ x86emuOp2_set_byte,
+/*  0x99 */ x86emuOp2_set_byte,
+/*  0x9a */ x86emuOp2_set_byte,
+/*  0x9b */ x86emuOp2_set_byte,
+/*  0x9c */ x86emuOp2_set_byte,
+/*  0x9d */ x86emuOp2_set_byte,
+/*  0x9e */ x86emuOp2_set_byte,
+/*  0x9f */ x86emuOp2_set_byte,
+/*  0xa0 */ x86emuOp2_push_FS,
+/*  0xa1 */ x86emuOp2_pop_FS,
+/*  0xa2 */ x86emuOp2_cpuid,
+/*  0xa3 */ x86emuOp2_bt_R,
+/*  0xa4 */ x86emuOp2_shld_IMM,
+/*  0xa5 */ x86emuOp2_shld_CL,
+/*  0xa6 */ x86emuOp2_illegal_op,
+/*  0xa7 */ x86emuOp2_illegal_op,
+/*  0xa8 */ x86emuOp2_push_GS,
+/*  0xa9 */ x86emuOp2_pop_GS,
+/*  0xaa */ x86emuOp2_illegal_op,
+/*  0xab */ x86emuOp2_bts_R,
+/*  0xac */ x86emuOp2_shrd_IMM,
+/*  0xad */ x86emuOp2_shrd_CL,
+/*  0xae */ x86emuOp2_illegal_op,
+/*  0xaf */ x86emuOp2_imul_R_RM,
+                                                /*  0xb0 */ x86emuOp2_illegal_op,
+                                                /* TODO: cmpxchg */
+                                                /*  0xb1 */ x86emuOp2_illegal_op,
+                                                /* TODO: cmpxchg */
+/*  0xb2 */ x86emuOp2_lss_R_IMM,
+/*  0xb3 */ x86emuOp2_btr_R,
+/*  0xb4 */ x86emuOp2_lfs_R_IMM,
+/*  0xb5 */ x86emuOp2_lgs_R_IMM,
+/*  0xb6 */ x86emuOp2_movzx_byte_R_RM,
+/*  0xb7 */ x86emuOp2_movzx_word_R_RM,
+/*  0xb8 */ x86emuOp2_illegal_op,
+/*  0xb9 */ x86emuOp2_illegal_op,
+/*  0xba */ x86emuOp2_btX_I,
+/*  0xbb */ x86emuOp2_btc_R,
+/*  0xbc */ x86emuOp2_bsf,
+/*  0xbd */ x86emuOp2_bsr,
+/*  0xbe */ x86emuOp2_movsx_byte_R_RM,
+/*  0xbf */ x86emuOp2_movsx_word_R_RM,
+                                                /*  0xc0 */ x86emuOp2_illegal_op,
+                                                /* TODO: xadd */
+                                                /*  0xc1 */ x86emuOp2_illegal_op,
+                                                /* TODO: xadd */
+/*  0xc2 */ x86emuOp2_illegal_op,
+/*  0xc3 */ x86emuOp2_illegal_op,
+/*  0xc4 */ x86emuOp2_illegal_op,
+/*  0xc5 */ x86emuOp2_illegal_op,
+/*  0xc6 */ x86emuOp2_illegal_op,
+/*  0xc7 */ x86emuOp2_illegal_op,
+/*  0xc8 */ x86emuOp2_bswap,
+/*  0xc9 */ x86emuOp2_bswap,
+/*  0xca */ x86emuOp2_bswap,
+/*  0xcb */ x86emuOp2_bswap,
+/*  0xcc */ x86emuOp2_bswap,
+/*  0xcd */ x86emuOp2_bswap,
+/*  0xce */ x86emuOp2_bswap,
+/*  0xcf */ x86emuOp2_bswap,
+/*  0xd0 */ x86emuOp2_illegal_op,
+/*  0xd1 */ x86emuOp2_illegal_op,
+/*  0xd2 */ x86emuOp2_illegal_op,
+/*  0xd3 */ x86emuOp2_illegal_op,
+/*  0xd4 */ x86emuOp2_illegal_op,
+/*  0xd5 */ x86emuOp2_illegal_op,
+/*  0xd6 */ x86emuOp2_illegal_op,
+/*  0xd7 */ x86emuOp2_illegal_op,
+/*  0xd8 */ x86emuOp2_illegal_op,
+/*  0xd9 */ x86emuOp2_illegal_op,
+/*  0xda */ x86emuOp2_illegal_op,
+/*  0xdb */ x86emuOp2_illegal_op,
+/*  0xdc */ x86emuOp2_illegal_op,
+/*  0xdd */ x86emuOp2_illegal_op,
+/*  0xde */ x86emuOp2_illegal_op,
+/*  0xdf */ x86emuOp2_illegal_op,
+/*  0xe0 */ x86emuOp2_illegal_op,
+/*  0xe1 */ x86emuOp2_illegal_op,
+/*  0xe2 */ x86emuOp2_illegal_op,
+/*  0xe3 */ x86emuOp2_illegal_op,
+/*  0xe4 */ x86emuOp2_illegal_op,
+/*  0xe5 */ x86emuOp2_illegal_op,
+/*  0xe6 */ x86emuOp2_illegal_op,
+/*  0xe7 */ x86emuOp2_illegal_op,
+/*  0xe8 */ x86emuOp2_illegal_op,
+/*  0xe9 */ x86emuOp2_illegal_op,
+/*  0xea */ x86emuOp2_illegal_op,
+/*  0xeb */ x86emuOp2_illegal_op,
+/*  0xec */ x86emuOp2_illegal_op,
+/*  0xed */ x86emuOp2_illegal_op,
+/*  0xee */ x86emuOp2_illegal_op,
+/*  0xef */ x86emuOp2_illegal_op,
+/*  0xf0 */ x86emuOp2_illegal_op,
+/*  0xf1 */ x86emuOp2_illegal_op,
+/*  0xf2 */ x86emuOp2_illegal_op,
+/*  0xf3 */ x86emuOp2_illegal_op,
+/*  0xf4 */ x86emuOp2_illegal_op,
+/*  0xf5 */ x86emuOp2_illegal_op,
+/*  0xf6 */ x86emuOp2_illegal_op,
+/*  0xf7 */ x86emuOp2_illegal_op,
+/*  0xf8 */ x86emuOp2_illegal_op,
+/*  0xf9 */ x86emuOp2_illegal_op,
+/*  0xfa */ x86emuOp2_illegal_op,
+/*  0xfb */ x86emuOp2_illegal_op,
+/*  0xfc */ x86emuOp2_illegal_op,
+/*  0xfd */ x86emuOp2_illegal_op,
+/*  0xfe */ x86emuOp2_illegal_op,
+/*  0xff */ x86emuOp2_illegal_op,
+};
diff --git a/plat/pc65oo2/emu/x86emu/prim_ops.c b/plat/pc65oo2/emu/x86emu/prim_ops.c
new file mode 100644
index 000000000..5604c7e81
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/prim_ops.c
@@ -0,0 +1,2859 @@
+/****************************************************************************
+*
+*						Realmode X86 Emulator Library
+*
+*            	Copyright (C) 1996-1999 SciTech Software, Inc.
+* 				     Copyright (C) David Mosberger-Tang
+* 					   Copyright (C) 1999 Egbert Eich
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:		ANSI C
+* Environment:	Any
+* Developer:    Kendall Bennett
+*
+* Description:  This file contains the code to implement the primitive
+*				machine operations used by the emulation code in ops.c
+*
+* Carry Chain Calculation
+*
+* This represents a somewhat expensive calculation which is
+* apparently required to emulate the setting of the OF and AF flag.
+* The latter is not so important, but the former is.  The overflow
+* flag is the XOR of the top two bits of the carry chain for an
+* addition (similar for subtraction).  Since we do not want to
+* simulate the addition in a bitwise manner, we try to calculate the
+* carry chain given the two operands and the result.
+*
+* So, given the following table, which represents the addition of two
+* bits, we can derive a formula for the carry chain.
+*
+* a   b   cin   r     cout
+* 0   0   0     0     0
+* 0   0   1     1     0
+* 0   1   0     1     0
+* 0   1   1     0     1
+* 1   0   0     1     0
+* 1   0   1     0     1
+* 1   1   0     0     1
+* 1   1   1     1     1
+*
+* Construction of table for cout:
+*
+* ab
+* r  \  00   01   11  10
+* |------------------
+* 0  |   0    1    1   1
+* 1  |   0    0    1   0
+*
+* By inspection, one gets:  cc = ab +  r'(a + b)
+*
+* That represents alot of operations, but NO CHOICE....
+*
+* Borrow Chain Calculation.
+*
+* The following table represents the subtraction of two bits, from
+* which we can derive a formula for the borrow chain.
+*
+* a   b   bin   r     bout
+* 0   0   0     0     0
+* 0   0   1     1     1
+* 0   1   0     1     1
+* 0   1   1     0     1
+* 1   0   0     1     0
+* 1   0   1     0     0
+* 1   1   0     0     0
+* 1   1   1     1     1
+*
+* Construction of table for cout:
+*
+* ab
+* r  \  00   01   11  10
+* |------------------
+* 0  |   0    1    0   0
+* 1  |   1    1    1   0
+*
+* By inspection, one gets:  bc = a'b +  r(a' + b)
+*
+****************************************************************************/
+
+#include <stdlib.h>
+
+#define	PRIM_OPS_NO_REDEFINE_ASM
+#include "x86emu/x86emui.h"
+
+#if defined(__GNUC__)
+#if defined (__i386__) || defined(__i386) || defined(__AMD64__) || defined(__amd64__)
+#include "x86emu/prim_x86_gcc.h"
+#endif
+#endif
+
+/*------------------------- Global Variables ------------------------------*/
+
+static u32 x86emu_parity_tab[8] = {
+    0x96696996,
+    0x69969669,
+    0x69969669,
+    0x96696996,
+    0x69969669,
+    0x96696996,
+    0x96696996,
+    0x69969669,
+};
+
+#define PARITY(x)   (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
+#define XOR2(x) 	(((x) ^ ((x)>>1)) & 0x1)
+
+/*----------------------------- Implementation ----------------------------*/
+
+/****************************************************************************
+REMARKS:
+Implements the AAA instruction and side effects.
+****************************************************************************/
+u16
+aaa_word(u16 d)
+{
+    u16 res;
+
+    if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
+        d += 0x6;
+        d += 0x100;
+        SET_FLAG(F_AF);
+        SET_FLAG(F_CF);
+    }
+    else {
+        CLEAR_FLAG(F_CF);
+        CLEAR_FLAG(F_AF);
+    }
+    res = (u16) (d & 0xFF0F);
+    CLEAR_FLAG(F_SF);
+    CONDITIONAL_SET_FLAG(res == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the AAA instruction and side effects.
+****************************************************************************/
+u16
+aas_word(u16 d)
+{
+    u16 res;
+
+    if ((d & 0xf) > 0x9 || ACCESS_FLAG(F_AF)) {
+        d -= 0x6;
+        d -= 0x100;
+        SET_FLAG(F_AF);
+        SET_FLAG(F_CF);
+    }
+    else {
+        CLEAR_FLAG(F_CF);
+        CLEAR_FLAG(F_AF);
+    }
+    res = (u16) (d & 0xFF0F);
+    CLEAR_FLAG(F_SF);
+    CONDITIONAL_SET_FLAG(res == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the AAD instruction and side effects.
+****************************************************************************/
+u16
+aad_word(u16 d)
+{
+    u16 l;
+    u8 hb, lb;
+
+    hb = (u8) ((d >> 8) & 0xff);
+    lb = (u8) ((d & 0xff));
+    l = (u16) ((lb + 10 * hb) & 0xFF);
+
+    CLEAR_FLAG(F_CF);
+    CLEAR_FLAG(F_AF);
+    CLEAR_FLAG(F_OF);
+    CONDITIONAL_SET_FLAG(l & 0x80, F_SF);
+    CONDITIONAL_SET_FLAG(l == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);
+    return l;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the AAM instruction and side effects.
+****************************************************************************/
+u16
+aam_word(u8 d)
+{
+    u16 h, l;
+
+    h = (u16) (d / 10);
+    l = (u16) (d % 10);
+    l |= (u16) (h << 8);
+
+    CLEAR_FLAG(F_CF);
+    CLEAR_FLAG(F_AF);
+    CLEAR_FLAG(F_OF);
+    CONDITIONAL_SET_FLAG(l & 0x80, F_SF);
+    CONDITIONAL_SET_FLAG(l == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(l & 0xff), F_PF);
+    return l;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the ADC instruction and side effects.
+****************************************************************************/
+u8
+adc_byte(u8 d, u8 s)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 cc;
+
+    if (ACCESS_FLAG(F_CF))
+        res = 1 + d + s;
+    else
+        res = d + s;
+
+    CONDITIONAL_SET_FLAG(res & 0x100, F_CF);
+    CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the carry chain  SEE NOTE AT TOP. */
+    cc = (s & d) | ((~res) & (s | d));
+    CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
+    CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
+    return (u8) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the ADC instruction and side effects.
+****************************************************************************/
+u16
+adc_word(u16 d, u16 s)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 cc;
+
+    if (ACCESS_FLAG(F_CF))
+        res = 1 + d + s;
+    else
+        res = d + s;
+
+    CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);
+    CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the carry chain  SEE NOTE AT TOP. */
+    cc = (s & d) | ((~res) & (s | d));
+    CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
+    CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
+    return (u16) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the ADC instruction and side effects.
+****************************************************************************/
+u32
+adc_long(u32 d, u32 s)
+{
+    register u32 lo;            /* all operands in native machine order */
+    register u32 hi;
+    register u32 res;
+    register u32 cc;
+
+    if (ACCESS_FLAG(F_CF)) {
+        lo = 1 + (d & 0xFFFF) + (s & 0xFFFF);
+        res = 1 + d + s;
+    }
+    else {
+        lo = (d & 0xFFFF) + (s & 0xFFFF);
+        res = d + s;
+    }
+    hi = (lo >> 16) + (d >> 16) + (s >> 16);
+
+    CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
+    CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the carry chain  SEE NOTE AT TOP. */
+    cc = (s & d) | ((~res) & (s | d));
+    CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
+    CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the ADD instruction and side effects.
+****************************************************************************/
+u8
+add_byte(u8 d, u8 s)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 cc;
+
+    res = d + s;
+    CONDITIONAL_SET_FLAG(res & 0x100, F_CF);
+    CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the carry chain  SEE NOTE AT TOP. */
+    cc = (s & d) | ((~res) & (s | d));
+    CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
+    CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
+    return (u8) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the ADD instruction and side effects.
+****************************************************************************/
+u16
+add_word(u16 d, u16 s)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 cc;
+
+    res = d + s;
+    CONDITIONAL_SET_FLAG(res & 0x10000, F_CF);
+    CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the carry chain  SEE NOTE AT TOP. */
+    cc = (s & d) | ((~res) & (s | d));
+    CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
+    CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
+    return (u16) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the ADD instruction and side effects.
+****************************************************************************/
+u32
+add_long(u32 d, u32 s)
+{
+    register u32 lo;            /* all operands in native machine order */
+    register u32 hi;
+    register u32 res;
+    register u32 cc;
+
+    lo = (d & 0xFFFF) + (s & 0xFFFF);
+    res = d + s;
+    hi = (lo >> 16) + (d >> 16) + (s >> 16);
+
+    CONDITIONAL_SET_FLAG(hi & 0x10000, F_CF);
+    CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the carry chain  SEE NOTE AT TOP. */
+    cc = (s & d) | ((~res) & (s | d));
+    CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
+    CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
+
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the AND instruction and side effects.
+****************************************************************************/
+u8
+and_byte(u8 d, u8 s)
+{
+    register u8 res;            /* all operands in native machine order */
+
+    res = d & s;
+
+    /* set the flags  */
+    CLEAR_FLAG(F_OF);
+    CLEAR_FLAG(F_CF);
+    CLEAR_FLAG(F_AF);
+    CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
+    CONDITIONAL_SET_FLAG(res == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the AND instruction and side effects.
+****************************************************************************/
+u16
+and_word(u16 d, u16 s)
+{
+    register u16 res;           /* all operands in native machine order */
+
+    res = d & s;
+
+    /* set the flags  */
+    CLEAR_FLAG(F_OF);
+    CLEAR_FLAG(F_CF);
+    CLEAR_FLAG(F_AF);
+    CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
+    CONDITIONAL_SET_FLAG(res == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the AND instruction and side effects.
+****************************************************************************/
+u32
+and_long(u32 d, u32 s)
+{
+    register u32 res;           /* all operands in native machine order */
+
+    res = d & s;
+
+    /* set the flags  */
+    CLEAR_FLAG(F_OF);
+    CLEAR_FLAG(F_CF);
+    CLEAR_FLAG(F_AF);
+    CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
+    CONDITIONAL_SET_FLAG(res == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the CMP instruction and side effects.
+****************************************************************************/
+u8
+cmp_byte(u8 d, u8 s)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 bc;
+
+    res = d - s;
+    CLEAR_FLAG(F_CF);
+    CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
+    CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the borrow chain.  See note at top */
+    bc = (res & (~d | s)) | (~d & s);
+    CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
+    CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
+    CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
+    return d;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the CMP instruction and side effects.
+****************************************************************************/
+u16
+cmp_word(u16 d, u16 s)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 bc;
+
+    res = d - s;
+    CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
+    CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the borrow chain.  See note at top */
+    bc = (res & (~d | s)) | (~d & s);
+    CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
+    CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
+    CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
+    return d;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the CMP instruction and side effects.
+****************************************************************************/
+u32
+cmp_long(u32 d, u32 s)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 bc;
+
+    res = d - s;
+    CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
+    CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the borrow chain.  See note at top */
+    bc = (res & (~d | s)) | (~d & s);
+    CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
+    CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
+    CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
+    return d;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the DAA instruction and side effects.
+****************************************************************************/
+u8
+daa_byte(u8 d)
+{
+    u32 res = d;
+
+    if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
+        res += 6;
+        SET_FLAG(F_AF);
+    }
+    if (res > 0x9F || ACCESS_FLAG(F_CF)) {
+        res += 0x60;
+        SET_FLAG(F_CF);
+    }
+    CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
+    CONDITIONAL_SET_FLAG((res & 0xFF) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+    return (u8) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the DAS instruction and side effects.
+****************************************************************************/
+u8
+das_byte(u8 d)
+{
+    if ((d & 0xf) > 9 || ACCESS_FLAG(F_AF)) {
+        d -= 6;
+        SET_FLAG(F_AF);
+    }
+    if (d > 0x9F || ACCESS_FLAG(F_CF)) {
+        d -= 0x60;
+        SET_FLAG(F_CF);
+    }
+    CONDITIONAL_SET_FLAG(d & 0x80, F_SF);
+    CONDITIONAL_SET_FLAG(d == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(d & 0xff), F_PF);
+    return d;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the DEC instruction and side effects.
+****************************************************************************/
+u8
+dec_byte(u8 d)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 bc;
+
+    res = d - 1;
+    CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
+    CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the borrow chain.  See note at top */
+    /* based on sub_byte, uses s==1.  */
+    bc = (res & (~d | 1)) | (~d & 1);
+    /* carry flag unchanged */
+    CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
+    CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
+    return (u8) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the DEC instruction and side effects.
+****************************************************************************/
+u16
+dec_word(u16 d)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 bc;
+
+    res = d - 1;
+    CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
+    CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the borrow chain.  See note at top */
+    /* based on the sub_byte routine, with s==1 */
+    bc = (res & (~d | 1)) | (~d & 1);
+    /* carry flag unchanged */
+    CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
+    CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
+    return (u16) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the DEC instruction and side effects.
+****************************************************************************/
+u32
+dec_long(u32 d)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 bc;
+
+    res = d - 1;
+
+    CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
+    CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the borrow chain.  See note at top */
+    bc = (res & (~d | 1)) | (~d & 1);
+    /* carry flag unchanged */
+    CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
+    CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the INC instruction and side effects.
+****************************************************************************/
+u8
+inc_byte(u8 d)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 cc;
+
+    res = d + 1;
+    CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the carry chain  SEE NOTE AT TOP. */
+    cc = ((1 & d) | (~res)) & (1 | d);
+    CONDITIONAL_SET_FLAG(XOR2(cc >> 6), F_OF);
+    CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
+    return (u8) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the INC instruction and side effects.
+****************************************************************************/
+u16
+inc_word(u16 d)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 cc;
+
+    res = d + 1;
+    CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the carry chain  SEE NOTE AT TOP. */
+    cc = (1 & d) | ((~res) & (1 | d));
+    CONDITIONAL_SET_FLAG(XOR2(cc >> 14), F_OF);
+    CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
+    return (u16) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the INC instruction and side effects.
+****************************************************************************/
+u32
+inc_long(u32 d)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 cc;
+
+    res = d + 1;
+    CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the carry chain  SEE NOTE AT TOP. */
+    cc = (1 & d) | ((~res) & (1 | d));
+    CONDITIONAL_SET_FLAG(XOR2(cc >> 30), F_OF);
+    CONDITIONAL_SET_FLAG(cc & 0x8, F_AF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the OR instruction and side effects.
+****************************************************************************/
+u8
+or_byte(u8 d, u8 s)
+{
+    register u8 res;            /* all operands in native machine order */
+
+    res = d | s;
+    CLEAR_FLAG(F_OF);
+    CLEAR_FLAG(F_CF);
+    CLEAR_FLAG(F_AF);
+    CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
+    CONDITIONAL_SET_FLAG(res == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the OR instruction and side effects.
+****************************************************************************/
+u16
+or_word(u16 d, u16 s)
+{
+    register u16 res;           /* all operands in native machine order */
+
+    res = d | s;
+    /* set the carry flag to be bit 8 */
+    CLEAR_FLAG(F_OF);
+    CLEAR_FLAG(F_CF);
+    CLEAR_FLAG(F_AF);
+    CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
+    CONDITIONAL_SET_FLAG(res == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the OR instruction and side effects.
+****************************************************************************/
+u32
+or_long(u32 d, u32 s)
+{
+    register u32 res;           /* all operands in native machine order */
+
+    res = d | s;
+
+    /* set the carry flag to be bit 8 */
+    CLEAR_FLAG(F_OF);
+    CLEAR_FLAG(F_CF);
+    CLEAR_FLAG(F_AF);
+    CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
+    CONDITIONAL_SET_FLAG(res == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the OR instruction and side effects.
+****************************************************************************/
+u8
+neg_byte(u8 s)
+{
+    register u8 res;
+    register u8 bc;
+
+    CONDITIONAL_SET_FLAG(s != 0, F_CF);
+    res = (u8) - s;
+    CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
+    CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
+    /* calculate the borrow chain --- modified such that d=0.
+       substitutiing d=0 into     bc= res&(~d|s)|(~d&s);
+       (the one used for sub) and simplifying, since ~d=0xff...,
+       ~d|s == 0xffff..., and res&0xfff... == res.  Similarly
+       ~d&s == s.  So the simplified result is: */
+    bc = res | s;
+    CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
+    CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the OR instruction and side effects.
+****************************************************************************/
+u16
+neg_word(u16 s)
+{
+    register u16 res;
+    register u16 bc;
+
+    CONDITIONAL_SET_FLAG(s != 0, F_CF);
+    res = (u16) - s;
+    CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the borrow chain --- modified such that d=0.
+       substitutiing d=0 into     bc= res&(~d|s)|(~d&s);
+       (the one used for sub) and simplifying, since ~d=0xff...,
+       ~d|s == 0xffff..., and res&0xfff... == res.  Similarly
+       ~d&s == s.  So the simplified result is: */
+    bc = res | s;
+    CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
+    CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the OR instruction and side effects.
+****************************************************************************/
+u32
+neg_long(u32 s)
+{
+    register u32 res;
+    register u32 bc;
+
+    CONDITIONAL_SET_FLAG(s != 0, F_CF);
+    res = (u32) - s;
+    CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the borrow chain --- modified such that d=0.
+       substitutiing d=0 into     bc= res&(~d|s)|(~d&s);
+       (the one used for sub) and simplifying, since ~d=0xff...,
+       ~d|s == 0xffff..., and res&0xfff... == res.  Similarly
+       ~d&s == s.  So the simplified result is: */
+    bc = res | s;
+    CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
+    CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the NOT instruction and side effects.
+****************************************************************************/
+u8
+not_byte(u8 s)
+{
+    return ~s;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the NOT instruction and side effects.
+****************************************************************************/
+u16
+not_word(u16 s)
+{
+    return ~s;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the NOT instruction and side effects.
+****************************************************************************/
+u32
+not_long(u32 s)
+{
+    return ~s;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the RCL instruction and side effects.
+****************************************************************************/
+u8
+rcl_byte(u8 d, u8 s)
+{
+    register unsigned int res, cnt, mask, cf;
+
+    /* s is the rotate distance.  It varies from 0 - 8. */
+    /* have
+
+       CF  B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
+
+       want to rotate through the carry by "s" bits.  We could
+       loop, but that's inefficient.  So the width is 9,
+       and we split into three parts:
+
+       The new carry flag   (was B_n)
+       the stuff in B_n-1 .. B_0
+       the stuff in B_7 .. B_n+1
+
+       The new rotate is done mod 9, and given this,
+       for a rotation of n bits (mod 9) the new carry flag is
+       then located n bits from the MSB.  The low part is
+       then shifted up cnt bits, and the high part is or'd
+       in.  Using CAPS for new values, and lowercase for the
+       original values, this can be expressed as:
+
+       IF n > 0
+       1) CF <-  b_(8-n)
+       2) B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_0
+       3) B_(n-1) <- cf
+       4) B_(n-2) .. B_0 <-  b_7 .. b_(8-(n-1))
+     */
+    res = d;
+    if ((cnt = s % 9) != 0) {
+        /* extract the new CARRY FLAG. */
+        /* CF <-  b_(8-n)             */
+        cf = (d >> (8 - cnt)) & 0x1;
+
+        /* get the low stuff which rotated
+           into the range B_7 .. B_cnt */
+        /* B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_0  */
+        /* note that the right hand side done by the mask */
+        res = (d << cnt) & 0xff;
+
+        /* now the high stuff which rotated around
+           into the positions B_cnt-2 .. B_0 */
+        /* B_(n-2) .. B_0 <-  b_7 .. b_(8-(n-1)) */
+        /* shift it downward, 7-(n-2) = 9-n positions.
+           and mask off the result before or'ing in.
+         */
+        mask = (1 << (cnt - 1)) - 1;
+        res |= (d >> (9 - cnt)) & mask;
+
+        /* if the carry flag was set, or it in.  */
+        if (ACCESS_FLAG(F_CF)) {        /* carry flag is set */
+            /*  B_(n-1) <- cf */
+            res |= 1 << (cnt - 1);
+        }
+        /* set the new carry flag, based on the variable "cf" */
+        CONDITIONAL_SET_FLAG(cf, F_CF);
+        /* OVERFLOW is set *IFF* cnt==1, then it is the
+           xor of CF and the most significant bit.  Blecck. */
+        /* parenthesized this expression since it appears to
+           be causing OF to be misset */
+        CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 6) & 0x2)), F_OF);
+
+    }
+    return (u8) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the RCL instruction and side effects.
+****************************************************************************/
+u16
+rcl_word(u16 d, u8 s)
+{
+    register unsigned int res, cnt, mask, cf;
+
+    res = d;
+    if ((cnt = s % 17) != 0) {
+        cf = (d >> (16 - cnt)) & 0x1;
+        res = (d << cnt) & 0xffff;
+        mask = (1 << (cnt - 1)) - 1;
+        res |= (d >> (17 - cnt)) & mask;
+        if (ACCESS_FLAG(F_CF)) {
+            res |= 1 << (cnt - 1);
+        }
+        CONDITIONAL_SET_FLAG(cf, F_CF);
+        CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 14) & 0x2)), F_OF);
+    }
+    return (u16) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the RCL instruction and side effects.
+****************************************************************************/
+u32
+rcl_long(u32 d, u8 s)
+{
+    register u32 res, cnt, mask, cf;
+
+    res = d;
+    if ((cnt = s % 33) != 0) {
+        cf = (d >> (32 - cnt)) & 0x1;
+        res = (d << cnt) & 0xffffffff;
+        mask = (1 << (cnt - 1)) - 1;
+        res |= (d >> (33 - cnt)) & mask;
+        if (ACCESS_FLAG(F_CF)) {        /* carry flag is set */
+            res |= 1 << (cnt - 1);
+        }
+        CONDITIONAL_SET_FLAG(cf, F_CF);
+        CONDITIONAL_SET_FLAG(cnt == 1 && XOR2(cf + ((res >> 30) & 0x2)), F_OF);
+    }
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the RCR instruction and side effects.
+****************************************************************************/
+u8
+rcr_byte(u8 d, u8 s)
+{
+    u32 res, cnt;
+    u32 mask, cf, ocf = 0;
+
+    /* rotate right through carry */
+    /*
+       s is the rotate distance.  It varies from 0 - 8.
+       d is the byte object rotated.
+
+       have
+
+       CF  B_7 B_6 B_5 B_4 B_3 B_2 B_1 B_0
+
+       The new rotate is done mod 9, and given this,
+       for a rotation of n bits (mod 9) the new carry flag is
+       then located n bits from the LSB.  The low part is
+       then shifted up cnt bits, and the high part is or'd
+       in.  Using CAPS for new values, and lowercase for the
+       original values, this can be expressed as:
+
+       IF n > 0
+       1) CF <-  b_(n-1)
+       2) B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_(n)
+       3) B_(8-n) <- cf
+       4) B_(7) .. B_(8-(n-1)) <-  b_(n-2) .. b_(0)
+     */
+    res = d;
+    if ((cnt = s % 9) != 0) {
+        /* extract the new CARRY FLAG. */
+        /* CF <-  b_(n-1)              */
+        if (cnt == 1) {
+            cf = d & 0x1;
+            /* note hackery here.  Access_flag(..) evaluates to either
+               0 if flag not set
+               non-zero if flag is set.
+               doing access_flag(..) != 0 casts that into either
+               0..1 in any representation of the flags register
+               (i.e. packed bit array or unpacked.)
+             */
+            ocf = ACCESS_FLAG(F_CF) != 0;
+        }
+        else
+            cf = (d >> (cnt - 1)) & 0x1;
+
+        /* B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_n  */
+        /* note that the right hand side done by the mask
+           This is effectively done by shifting the
+           object to the right.  The result must be masked,
+           in case the object came in and was treated
+           as a negative number.  Needed??? */
+
+        mask = (1 << (8 - cnt)) - 1;
+        res = (d >> cnt) & mask;
+
+        /* now the high stuff which rotated around
+           into the positions B_cnt-2 .. B_0 */
+        /* B_(7) .. B_(8-(n-1)) <-  b_(n-2) .. b_(0) */
+        /* shift it downward, 7-(n-2) = 9-n positions.
+           and mask off the result before or'ing in.
+         */
+        res |= (d << (9 - cnt));
+
+        /* if the carry flag was set, or it in.  */
+        if (ACCESS_FLAG(F_CF)) {        /* carry flag is set */
+            /*  B_(8-n) <- cf */
+            res |= 1 << (8 - cnt);
+        }
+        /* set the new carry flag, based on the variable "cf" */
+        CONDITIONAL_SET_FLAG(cf, F_CF);
+        /* OVERFLOW is set *IFF* cnt==1, then it is the
+           xor of CF and the most significant bit.  Blecck. */
+        /* parenthesized... */
+        if (cnt == 1) {
+            CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 6) & 0x2)), F_OF);
+        }
+    }
+    return (u8) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the RCR instruction and side effects.
+****************************************************************************/
+u16
+rcr_word(u16 d, u8 s)
+{
+    u32 res, cnt;
+    u32 mask, cf, ocf = 0;
+
+    /* rotate right through carry */
+    res = d;
+    if ((cnt = s % 17) != 0) {
+        if (cnt == 1) {
+            cf = d & 0x1;
+            ocf = ACCESS_FLAG(F_CF) != 0;
+        }
+        else
+            cf = (d >> (cnt - 1)) & 0x1;
+        mask = (1 << (16 - cnt)) - 1;
+        res = (d >> cnt) & mask;
+        res |= (d << (17 - cnt));
+        if (ACCESS_FLAG(F_CF)) {
+            res |= 1 << (16 - cnt);
+        }
+        CONDITIONAL_SET_FLAG(cf, F_CF);
+        if (cnt == 1) {
+            CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 14) & 0x2)), F_OF);
+        }
+    }
+    return (u16) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the RCR instruction and side effects.
+****************************************************************************/
+u32
+rcr_long(u32 d, u8 s)
+{
+    u32 res, cnt;
+    u32 mask, cf, ocf = 0;
+
+    /* rotate right through carry */
+    res = d;
+    if ((cnt = s % 33) != 0) {
+        if (cnt == 1) {
+            cf = d & 0x1;
+            ocf = ACCESS_FLAG(F_CF) != 0;
+        }
+        else
+            cf = (d >> (cnt - 1)) & 0x1;
+        mask = (1 << (32 - cnt)) - 1;
+        res = (d >> cnt) & mask;
+        if (cnt != 1)
+            res |= (d << (33 - cnt));
+        if (ACCESS_FLAG(F_CF)) {        /* carry flag is set */
+            res |= 1 << (32 - cnt);
+        }
+        CONDITIONAL_SET_FLAG(cf, F_CF);
+        if (cnt == 1) {
+            CONDITIONAL_SET_FLAG(XOR2(ocf + ((d >> 30) & 0x2)), F_OF);
+        }
+    }
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the ROL instruction and side effects.
+****************************************************************************/
+u8
+rol_byte(u8 d, u8 s)
+{
+    register unsigned int res, cnt, mask;
+
+    /* rotate left */
+    /*
+       s is the rotate distance.  It varies from 0 - 8.
+       d is the byte object rotated.
+
+       have
+
+       CF  B_7 ... B_0
+
+       The new rotate is done mod 8.
+       Much simpler than the "rcl" or "rcr" operations.
+
+       IF n > 0
+       1) B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_(0)
+       2) B_(n-1) .. B_(0) <-  b_(7) .. b_(8-n)
+     */
+    res = d;
+    if ((cnt = s % 8) != 0) {
+        /* B_(7) .. B_(n)  <-  b_(8-(n+1)) .. b_(0) */
+        res = (d << cnt);
+
+        /* B_(n-1) .. B_(0) <-  b_(7) .. b_(8-n) */
+        mask = (1 << cnt) - 1;
+        res |= (d >> (8 - cnt)) & mask;
+
+        /* set the new carry flag, Note that it is the low order
+           bit of the result!!!                               */
+        CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
+        /* OVERFLOW is set *IFF* s==1, then it is the
+           xor of CF and the most significant bit.  Blecck. */
+        CONDITIONAL_SET_FLAG(s == 1 &&
+                             XOR2((res & 0x1) + ((res >> 6) & 0x2)), F_OF);
+    }
+    if (s != 0) {
+        /* set the new carry flag, Note that it is the low order
+           bit of the result!!!                               */
+        CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
+    }
+    return (u8) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the ROL instruction and side effects.
+****************************************************************************/
+u16
+rol_word(u16 d, u8 s)
+{
+    register unsigned int res, cnt, mask;
+
+    res = d;
+    if ((cnt = s % 16) != 0) {
+        res = (d << cnt);
+        mask = (1 << cnt) - 1;
+        res |= (d >> (16 - cnt)) & mask;
+        CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
+        CONDITIONAL_SET_FLAG(s == 1 &&
+                             XOR2((res & 0x1) + ((res >> 14) & 0x2)), F_OF);
+    }
+    if (s != 0) {
+        /* set the new carry flag, Note that it is the low order
+           bit of the result!!!                               */
+        CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
+    }
+    return (u16) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the ROL instruction and side effects.
+****************************************************************************/
+u32
+rol_long(u32 d, u8 s)
+{
+    register u32 res, cnt, mask;
+
+    res = d;
+    if ((cnt = s % 32) != 0) {
+        res = (d << cnt);
+        mask = (1 << cnt) - 1;
+        res |= (d >> (32 - cnt)) & mask;
+        CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
+        CONDITIONAL_SET_FLAG(s == 1 &&
+                             XOR2((res & 0x1) + ((res >> 30) & 0x2)), F_OF);
+    }
+    if (s != 0) {
+        /* set the new carry flag, Note that it is the low order
+           bit of the result!!!                               */
+        CONDITIONAL_SET_FLAG(res & 0x1, F_CF);
+    }
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the ROR instruction and side effects.
+****************************************************************************/
+u8
+ror_byte(u8 d, u8 s)
+{
+    register unsigned int res, cnt, mask;
+
+    /* rotate right */
+    /*
+       s is the rotate distance.  It varies from 0 - 8.
+       d is the byte object rotated.
+
+       have
+
+       B_7 ... B_0
+
+       The rotate is done mod 8.
+
+       IF n > 0
+       1) B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_(n)
+       2) B_(7) .. B_(8-n) <-  b_(n-1) .. b_(0)
+     */
+    res = d;
+    if ((cnt = s % 8) != 0) {   /* not a typo, do nada if cnt==0 */
+        /* B_(7) .. B_(8-n) <-  b_(n-1) .. b_(0) */
+        res = (d << (8 - cnt));
+
+        /* B_(8-(n+1)) .. B_(0)  <-  b_(7) .. b_(n) */
+        mask = (1 << (8 - cnt)) - 1;
+        res |= (d >> (cnt)) & mask;
+
+        /* set the new carry flag, Note that it is the low order
+           bit of the result!!!                               */
+        CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
+        /* OVERFLOW is set *IFF* s==1, then it is the
+           xor of the two most significant bits.  Blecck. */
+        CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 6), F_OF);
+    }
+    else if (s != 0) {
+        /* set the new carry flag, Note that it is the low order
+           bit of the result!!!                               */
+        CONDITIONAL_SET_FLAG(res & 0x80, F_CF);
+    }
+    return (u8) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the ROR instruction and side effects.
+****************************************************************************/
+u16
+ror_word(u16 d, u8 s)
+{
+    register unsigned int res, cnt, mask;
+
+    res = d;
+    if ((cnt = s % 16) != 0) {
+        res = (d << (16 - cnt));
+        mask = (1 << (16 - cnt)) - 1;
+        res |= (d >> (cnt)) & mask;
+        CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
+        CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 14), F_OF);
+    }
+    else if (s != 0) {
+        /* set the new carry flag, Note that it is the low order
+           bit of the result!!!                               */
+        CONDITIONAL_SET_FLAG(res & 0x8000, F_CF);
+    }
+    return (u16) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the ROR instruction and side effects.
+****************************************************************************/
+u32
+ror_long(u32 d, u8 s)
+{
+    register u32 res, cnt, mask;
+
+    res = d;
+    if ((cnt = s % 32) != 0) {
+        res = (d << (32 - cnt));
+        mask = (1 << (32 - cnt)) - 1;
+        res |= (d >> (cnt)) & mask;
+        CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
+        CONDITIONAL_SET_FLAG(s == 1 && XOR2(res >> 30), F_OF);
+    }
+    else if (s != 0) {
+        /* set the new carry flag, Note that it is the low order
+           bit of the result!!!                               */
+        CONDITIONAL_SET_FLAG(res & 0x80000000, F_CF);
+    }
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SHL instruction and side effects.
+****************************************************************************/
+u8
+shl_byte(u8 d, u8 s)
+{
+    unsigned int cnt, res, cf;
+
+    if (s < 8) {
+        cnt = s % 8;
+
+        /* last bit shifted out goes into carry flag */
+        if (cnt > 0) {
+            res = d << cnt;
+            cf = d & (1 << (8 - cnt));
+            CONDITIONAL_SET_FLAG(cf, F_CF);
+            CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
+            CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
+            CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+        }
+        else {
+            res = (u8) d;
+        }
+
+        if (cnt == 1) {
+            /* Needs simplification. */
+            CONDITIONAL_SET_FLAG((((res & 0x80) == 0x80) ^
+                                  (ACCESS_FLAG(F_CF) != 0)),
+                                 /* was (M.x86.R_FLG&F_CF)==F_CF)), */
+                                 F_OF);
+        }
+        else {
+            CLEAR_FLAG(F_OF);
+        }
+    }
+    else {
+        res = 0;
+        CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80, F_CF);
+        CLEAR_FLAG(F_OF);
+        CLEAR_FLAG(F_SF);
+        SET_FLAG(F_PF);
+        SET_FLAG(F_ZF);
+    }
+    return (u8) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SHL instruction and side effects.
+****************************************************************************/
+u16
+shl_word(u16 d, u8 s)
+{
+    unsigned int cnt, res, cf;
+
+    if (s < 16) {
+        cnt = s % 16;
+        if (cnt > 0) {
+            res = d << cnt;
+            cf = d & (1 << (16 - cnt));
+            CONDITIONAL_SET_FLAG(cf, F_CF);
+            CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
+            CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
+            CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+        }
+        else {
+            res = (u16) d;
+        }
+
+        if (cnt == 1) {
+            CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
+                                  (ACCESS_FLAG(F_CF) != 0)), F_OF);
+        }
+        else {
+            CLEAR_FLAG(F_OF);
+        }
+    }
+    else {
+        res = 0;
+        CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF);
+        CLEAR_FLAG(F_OF);
+        CLEAR_FLAG(F_SF);
+        SET_FLAG(F_PF);
+        SET_FLAG(F_ZF);
+    }
+    return (u16) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SHL instruction and side effects.
+****************************************************************************/
+u32
+shl_long(u32 d, u8 s)
+{
+    unsigned int cnt, res, cf;
+
+    if (s < 32) {
+        cnt = s % 32;
+        if (cnt > 0) {
+            res = d << cnt;
+            cf = d & (1 << (32 - cnt));
+            CONDITIONAL_SET_FLAG(cf, F_CF);
+            CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
+            CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
+            CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+        }
+        else {
+            res = d;
+        }
+        if (cnt == 1) {
+            CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
+                                  (ACCESS_FLAG(F_CF) != 0)), F_OF);
+        }
+        else {
+            CLEAR_FLAG(F_OF);
+        }
+    }
+    else {
+        res = 0;
+        CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF);
+        CLEAR_FLAG(F_OF);
+        CLEAR_FLAG(F_SF);
+        SET_FLAG(F_PF);
+        SET_FLAG(F_ZF);
+    }
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SHR instruction and side effects.
+****************************************************************************/
+u8
+shr_byte(u8 d, u8 s)
+{
+    unsigned int cnt, res, cf;
+
+    if (s < 8) {
+        cnt = s % 8;
+        if (cnt > 0) {
+            cf = d & (1 << (cnt - 1));
+            res = d >> cnt;
+            CONDITIONAL_SET_FLAG(cf, F_CF);
+            CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
+            CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
+            CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+        }
+        else {
+            res = (u8) d;
+        }
+
+        if (cnt == 1) {
+            CONDITIONAL_SET_FLAG(XOR2(res >> 6), F_OF);
+        }
+        else {
+            CLEAR_FLAG(F_OF);
+        }
+    }
+    else {
+        res = 0;
+        CONDITIONAL_SET_FLAG((d >> (s - 1)) & 0x1, F_CF);
+        CLEAR_FLAG(F_OF);
+        CLEAR_FLAG(F_SF);
+        SET_FLAG(F_PF);
+        SET_FLAG(F_ZF);
+    }
+    return (u8) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SHR instruction and side effects.
+****************************************************************************/
+u16
+shr_word(u16 d, u8 s)
+{
+    unsigned int cnt, res, cf;
+
+    if (s < 16) {
+        cnt = s % 16;
+        if (cnt > 0) {
+            cf = d & (1 << (cnt - 1));
+            res = d >> cnt;
+            CONDITIONAL_SET_FLAG(cf, F_CF);
+            CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
+            CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
+            CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+        }
+        else {
+            res = d;
+        }
+
+        if (cnt == 1) {
+            CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
+        }
+        else {
+            CLEAR_FLAG(F_OF);
+        }
+    }
+    else {
+        res = 0;
+        CLEAR_FLAG(F_CF);
+        CLEAR_FLAG(F_OF);
+        SET_FLAG(F_ZF);
+        CLEAR_FLAG(F_SF);
+        CLEAR_FLAG(F_PF);
+    }
+    return (u16) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SHR instruction and side effects.
+****************************************************************************/
+u32
+shr_long(u32 d, u8 s)
+{
+    unsigned int cnt, res, cf;
+
+    if (s < 32) {
+        cnt = s % 32;
+        if (cnt > 0) {
+            cf = d & (1 << (cnt - 1));
+            res = d >> cnt;
+            CONDITIONAL_SET_FLAG(cf, F_CF);
+            CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
+            CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
+            CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+        }
+        else {
+            res = d;
+        }
+        if (cnt == 1) {
+            CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
+        }
+        else {
+            CLEAR_FLAG(F_OF);
+        }
+    }
+    else {
+        res = 0;
+        CLEAR_FLAG(F_CF);
+        CLEAR_FLAG(F_OF);
+        SET_FLAG(F_ZF);
+        CLEAR_FLAG(F_SF);
+        CLEAR_FLAG(F_PF);
+    }
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SAR instruction and side effects.
+****************************************************************************/
+u8
+sar_byte(u8 d, u8 s)
+{
+    unsigned int cnt, res, cf, mask, sf;
+
+    res = d;
+    sf = d & 0x80;
+    cnt = s % 8;
+    if (cnt > 0 && cnt < 8) {
+        mask = (1 << (8 - cnt)) - 1;
+        cf = d & (1 << (cnt - 1));
+        res = (d >> cnt) & mask;
+        CONDITIONAL_SET_FLAG(cf, F_CF);
+        if (sf) {
+            res |= ~mask;
+        }
+        CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
+        CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+        CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
+    }
+    else if (cnt >= 8) {
+        if (sf) {
+            res = 0xff;
+            SET_FLAG(F_CF);
+            CLEAR_FLAG(F_ZF);
+            SET_FLAG(F_SF);
+            SET_FLAG(F_PF);
+        }
+        else {
+            res = 0;
+            CLEAR_FLAG(F_CF);
+            SET_FLAG(F_ZF);
+            CLEAR_FLAG(F_SF);
+            CLEAR_FLAG(F_PF);
+        }
+    }
+    return (u8) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SAR instruction and side effects.
+****************************************************************************/
+u16
+sar_word(u16 d, u8 s)
+{
+    unsigned int cnt, res, cf, mask, sf;
+
+    sf = d & 0x8000;
+    cnt = s % 16;
+    res = d;
+    if (cnt > 0 && cnt < 16) {
+        mask = (1 << (16 - cnt)) - 1;
+        cf = d & (1 << (cnt - 1));
+        res = (d >> cnt) & mask;
+        CONDITIONAL_SET_FLAG(cf, F_CF);
+        if (sf) {
+            res |= ~mask;
+        }
+        CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
+        CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
+        CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+    }
+    else if (cnt >= 16) {
+        if (sf) {
+            res = 0xffff;
+            SET_FLAG(F_CF);
+            CLEAR_FLAG(F_ZF);
+            SET_FLAG(F_SF);
+            SET_FLAG(F_PF);
+        }
+        else {
+            res = 0;
+            CLEAR_FLAG(F_CF);
+            SET_FLAG(F_ZF);
+            CLEAR_FLAG(F_SF);
+            CLEAR_FLAG(F_PF);
+        }
+    }
+    return (u16) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SAR instruction and side effects.
+****************************************************************************/
+u32
+sar_long(u32 d, u8 s)
+{
+    u32 cnt, res, cf, mask, sf;
+
+    sf = d & 0x80000000;
+    cnt = s % 32;
+    res = d;
+    if (cnt > 0 && cnt < 32) {
+        mask = (1 << (32 - cnt)) - 1;
+        cf = d & (1 << (cnt - 1));
+        res = (d >> cnt) & mask;
+        CONDITIONAL_SET_FLAG(cf, F_CF);
+        if (sf) {
+            res |= ~mask;
+        }
+        CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
+        CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
+        CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+    }
+    else if (cnt >= 32) {
+        if (sf) {
+            res = 0xffffffff;
+            SET_FLAG(F_CF);
+            CLEAR_FLAG(F_ZF);
+            SET_FLAG(F_SF);
+            SET_FLAG(F_PF);
+        }
+        else {
+            res = 0;
+            CLEAR_FLAG(F_CF);
+            SET_FLAG(F_ZF);
+            CLEAR_FLAG(F_SF);
+            CLEAR_FLAG(F_PF);
+        }
+    }
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SHLD instruction and side effects.
+****************************************************************************/
+u16
+shld_word(u16 d, u16 fill, u8 s)
+{
+    unsigned int cnt, res, cf;
+
+    if (s < 16) {
+        cnt = s % 16;
+        if (cnt > 0) {
+            res = (d << cnt) | (fill >> (16 - cnt));
+            cf = d & (1 << (16 - cnt));
+            CONDITIONAL_SET_FLAG(cf, F_CF);
+            CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
+            CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
+            CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+        }
+        else {
+            res = d;
+        }
+        if (cnt == 1) {
+            CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
+                                  (ACCESS_FLAG(F_CF) != 0)), F_OF);
+        }
+        else {
+            CLEAR_FLAG(F_OF);
+        }
+    }
+    else {
+        res = 0;
+        CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x8000, F_CF);
+        CLEAR_FLAG(F_OF);
+        CLEAR_FLAG(F_SF);
+        SET_FLAG(F_PF);
+        SET_FLAG(F_ZF);
+    }
+    return (u16) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SHLD instruction and side effects.
+****************************************************************************/
+u32
+shld_long(u32 d, u32 fill, u8 s)
+{
+    unsigned int cnt, res, cf;
+
+    if (s < 32) {
+        cnt = s % 32;
+        if (cnt > 0) {
+            res = (d << cnt) | (fill >> (32 - cnt));
+            cf = d & (1 << (32 - cnt));
+            CONDITIONAL_SET_FLAG(cf, F_CF);
+            CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
+            CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
+            CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+        }
+        else {
+            res = d;
+        }
+        if (cnt == 1) {
+            CONDITIONAL_SET_FLAG((((res & 0x80000000) == 0x80000000) ^
+                                  (ACCESS_FLAG(F_CF) != 0)), F_OF);
+        }
+        else {
+            CLEAR_FLAG(F_OF);
+        }
+    }
+    else {
+        res = 0;
+        CONDITIONAL_SET_FLAG((d << (s - 1)) & 0x80000000, F_CF);
+        CLEAR_FLAG(F_OF);
+        CLEAR_FLAG(F_SF);
+        SET_FLAG(F_PF);
+        SET_FLAG(F_ZF);
+    }
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SHRD instruction and side effects.
+****************************************************************************/
+u16
+shrd_word(u16 d, u16 fill, u8 s)
+{
+    unsigned int cnt, res, cf;
+
+    if (s < 16) {
+        cnt = s % 16;
+        if (cnt > 0) {
+            cf = d & (1 << (cnt - 1));
+            res = (d >> cnt) | (fill << (16 - cnt));
+            CONDITIONAL_SET_FLAG(cf, F_CF);
+            CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
+            CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
+            CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+        }
+        else {
+            res = d;
+        }
+
+        if (cnt == 1) {
+            CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
+        }
+        else {
+            CLEAR_FLAG(F_OF);
+        }
+    }
+    else {
+        res = 0;
+        CLEAR_FLAG(F_CF);
+        CLEAR_FLAG(F_OF);
+        SET_FLAG(F_ZF);
+        CLEAR_FLAG(F_SF);
+        CLEAR_FLAG(F_PF);
+    }
+    return (u16) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SHRD instruction and side effects.
+****************************************************************************/
+u32
+shrd_long(u32 d, u32 fill, u8 s)
+{
+    unsigned int cnt, res, cf;
+
+    if (s < 32) {
+        cnt = s % 32;
+        if (cnt > 0) {
+            cf = d & (1 << (cnt - 1));
+            res = (d >> cnt) | (fill << (32 - cnt));
+            CONDITIONAL_SET_FLAG(cf, F_CF);
+            CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
+            CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
+            CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+        }
+        else {
+            res = d;
+        }
+        if (cnt == 1) {
+            CONDITIONAL_SET_FLAG(XOR2(res >> 30), F_OF);
+        }
+        else {
+            CLEAR_FLAG(F_OF);
+        }
+    }
+    else {
+        res = 0;
+        CLEAR_FLAG(F_CF);
+        CLEAR_FLAG(F_OF);
+        SET_FLAG(F_ZF);
+        CLEAR_FLAG(F_SF);
+        CLEAR_FLAG(F_PF);
+    }
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SBB instruction and side effects.
+****************************************************************************/
+u8
+sbb_byte(u8 d, u8 s)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 bc;
+
+    if (ACCESS_FLAG(F_CF))
+        res = d - s - 1;
+    else
+        res = d - s;
+    CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
+    CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the borrow chain.  See note at top */
+    bc = (res & (~d | s)) | (~d & s);
+    CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
+    CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
+    CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
+    return (u8) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SBB instruction and side effects.
+****************************************************************************/
+u16
+sbb_word(u16 d, u16 s)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 bc;
+
+    if (ACCESS_FLAG(F_CF))
+        res = d - s - 1;
+    else
+        res = d - s;
+    CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
+    CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the borrow chain.  See note at top */
+    bc = (res & (~d | s)) | (~d & s);
+    CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
+    CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
+    CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
+    return (u16) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SBB instruction and side effects.
+****************************************************************************/
+u32
+sbb_long(u32 d, u32 s)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 bc;
+
+    if (ACCESS_FLAG(F_CF))
+        res = d - s - 1;
+    else
+        res = d - s;
+    CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
+    CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the borrow chain.  See note at top */
+    bc = (res & (~d | s)) | (~d & s);
+    CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
+    CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
+    CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SUB instruction and side effects.
+****************************************************************************/
+u8
+sub_byte(u8 d, u8 s)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 bc;
+
+    res = d - s;
+    CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
+    CONDITIONAL_SET_FLAG((res & 0xff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the borrow chain.  See note at top */
+    bc = (res & (~d | s)) | (~d & s);
+    CONDITIONAL_SET_FLAG(bc & 0x80, F_CF);
+    CONDITIONAL_SET_FLAG(XOR2(bc >> 6), F_OF);
+    CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
+    return (u8) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SUB instruction and side effects.
+****************************************************************************/
+u16
+sub_word(u16 d, u16 s)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 bc;
+
+    res = d - s;
+    CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
+    CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the borrow chain.  See note at top */
+    bc = (res & (~d | s)) | (~d & s);
+    CONDITIONAL_SET_FLAG(bc & 0x8000, F_CF);
+    CONDITIONAL_SET_FLAG(XOR2(bc >> 14), F_OF);
+    CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
+    return (u16) res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the SUB instruction and side effects.
+****************************************************************************/
+u32
+sub_long(u32 d, u32 s)
+{
+    register u32 res;           /* all operands in native machine order */
+    register u32 bc;
+
+    res = d - s;
+    CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
+    CONDITIONAL_SET_FLAG((res & 0xffffffff) == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+
+    /* calculate the borrow chain.  See note at top */
+    bc = (res & (~d | s)) | (~d & s);
+    CONDITIONAL_SET_FLAG(bc & 0x80000000, F_CF);
+    CONDITIONAL_SET_FLAG(XOR2(bc >> 30), F_OF);
+    CONDITIONAL_SET_FLAG(bc & 0x8, F_AF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the TEST instruction and side effects.
+****************************************************************************/
+void
+test_byte(u8 d, u8 s)
+{
+    register u32 res;           /* all operands in native machine order */
+
+    res = d & s;
+
+    CLEAR_FLAG(F_OF);
+    CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
+    CONDITIONAL_SET_FLAG(res == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+    /* AF == dont care */
+    CLEAR_FLAG(F_CF);
+}
+
+/****************************************************************************
+REMARKS:
+Implements the TEST instruction and side effects.
+****************************************************************************/
+void
+test_word(u16 d, u16 s)
+{
+    register u32 res;           /* all operands in native machine order */
+
+    res = d & s;
+
+    CLEAR_FLAG(F_OF);
+    CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
+    CONDITIONAL_SET_FLAG(res == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+    /* AF == dont care */
+    CLEAR_FLAG(F_CF);
+}
+
+/****************************************************************************
+REMARKS:
+Implements the TEST instruction and side effects.
+****************************************************************************/
+void
+test_long(u32 d, u32 s)
+{
+    register u32 res;           /* all operands in native machine order */
+
+    res = d & s;
+
+    CLEAR_FLAG(F_OF);
+    CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
+    CONDITIONAL_SET_FLAG(res == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+    /* AF == dont care */
+    CLEAR_FLAG(F_CF);
+}
+
+/****************************************************************************
+REMARKS:
+Implements the XOR instruction and side effects.
+****************************************************************************/
+u8
+xor_byte(u8 d, u8 s)
+{
+    register u8 res;            /* all operands in native machine order */
+
+    res = d ^ s;
+    CLEAR_FLAG(F_OF);
+    CONDITIONAL_SET_FLAG(res & 0x80, F_SF);
+    CONDITIONAL_SET_FLAG(res == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res), F_PF);
+    CLEAR_FLAG(F_CF);
+    CLEAR_FLAG(F_AF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the XOR instruction and side effects.
+****************************************************************************/
+u16
+xor_word(u16 d, u16 s)
+{
+    register u16 res;           /* all operands in native machine order */
+
+    res = d ^ s;
+    CLEAR_FLAG(F_OF);
+    CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
+    CONDITIONAL_SET_FLAG(res == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+    CLEAR_FLAG(F_CF);
+    CLEAR_FLAG(F_AF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the XOR instruction and side effects.
+****************************************************************************/
+u32
+xor_long(u32 d, u32 s)
+{
+    register u32 res;           /* all operands in native machine order */
+
+    res = d ^ s;
+    CLEAR_FLAG(F_OF);
+    CONDITIONAL_SET_FLAG(res & 0x80000000, F_SF);
+    CONDITIONAL_SET_FLAG(res == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
+    CLEAR_FLAG(F_CF);
+    CLEAR_FLAG(F_AF);
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the IMUL instruction and side effects.
+****************************************************************************/
+void
+imul_byte(u8 s)
+{
+    s16 res = (s16) ((s8) M.x86.R_AL * (s8) s);
+
+    M.x86.R_AX = res;
+    if (((M.x86.R_AL & 0x80) == 0 && M.x86.R_AH == 0x00) ||
+        ((M.x86.R_AL & 0x80) != 0 && M.x86.R_AH == 0xFF)) {
+        CLEAR_FLAG(F_CF);
+        CLEAR_FLAG(F_OF);
+    }
+    else {
+        SET_FLAG(F_CF);
+        SET_FLAG(F_OF);
+    }
+}
+
+/****************************************************************************
+REMARKS:
+Implements the IMUL instruction and side effects.
+****************************************************************************/
+void
+imul_word(u16 s)
+{
+    s32 res = (s16) M.x86.R_AX * (s16) s;
+
+    M.x86.R_AX = (u16) res;
+    M.x86.R_DX = (u16) (res >> 16);
+    if (((M.x86.R_AX & 0x8000) == 0 && M.x86.R_DX == 0x00) ||
+        ((M.x86.R_AX & 0x8000) != 0 && M.x86.R_DX == 0xFF)) {
+        CLEAR_FLAG(F_CF);
+        CLEAR_FLAG(F_OF);
+    }
+    else {
+        SET_FLAG(F_CF);
+        SET_FLAG(F_OF);
+    }
+}
+
+/****************************************************************************
+REMARKS:
+Implements the IMUL instruction and side effects.
+****************************************************************************/
+void
+imul_long_direct(u32 * res_lo, u32 * res_hi, u32 d, u32 s)
+{
+#ifdef	__HAS_LONG_LONG__
+    s64 res = (s64) (s32) d * (s32) s;
+
+    *res_lo = (u32) res;
+    *res_hi = (u32) (res >> 32);
+#else
+    u32 d_lo, d_hi, d_sign;
+    u32 s_lo, s_hi, s_sign;
+    u32 rlo_lo, rlo_hi, rhi_lo;
+
+    if ((d_sign = d & 0x80000000) != 0)
+        d = -d;
+    d_lo = d & 0xFFFF;
+    d_hi = d >> 16;
+    if ((s_sign = s & 0x80000000) != 0)
+        s = -s;
+    s_lo = s & 0xFFFF;
+    s_hi = s >> 16;
+    rlo_lo = d_lo * s_lo;
+    rlo_hi = (d_hi * s_lo + d_lo * s_hi) + (rlo_lo >> 16);
+    rhi_lo = d_hi * s_hi + (rlo_hi >> 16);
+    *res_lo = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
+    *res_hi = rhi_lo;
+    if (d_sign != s_sign) {
+        d = ~*res_lo;
+        s = (((d & 0xFFFF) + 1) >> 16) + (d >> 16);
+        *res_lo = ~*res_lo + 1;
+        *res_hi = ~*res_hi + (s >> 16);
+    }
+#endif
+}
+
+/****************************************************************************
+REMARKS:
+Implements the IMUL instruction and side effects.
+****************************************************************************/
+void
+imul_long(u32 s)
+{
+    imul_long_direct(&M.x86.R_EAX, &M.x86.R_EDX, M.x86.R_EAX, s);
+    if (((M.x86.R_EAX & 0x80000000) == 0 && M.x86.R_EDX == 0x00) ||
+        ((M.x86.R_EAX & 0x80000000) != 0 && M.x86.R_EDX == 0xFF)) {
+        CLEAR_FLAG(F_CF);
+        CLEAR_FLAG(F_OF);
+    }
+    else {
+        SET_FLAG(F_CF);
+        SET_FLAG(F_OF);
+    }
+}
+
+/****************************************************************************
+REMARKS:
+Implements the MUL instruction and side effects.
+****************************************************************************/
+void
+mul_byte(u8 s)
+{
+    u16 res = (u16) (M.x86.R_AL * s);
+
+    M.x86.R_AX = res;
+    if (M.x86.R_AH == 0) {
+        CLEAR_FLAG(F_CF);
+        CLEAR_FLAG(F_OF);
+    }
+    else {
+        SET_FLAG(F_CF);
+        SET_FLAG(F_OF);
+    }
+}
+
+/****************************************************************************
+REMARKS:
+Implements the MUL instruction and side effects.
+****************************************************************************/
+void
+mul_word(u16 s)
+{
+    u32 res = M.x86.R_AX * s;
+
+    M.x86.R_AX = (u16) res;
+    M.x86.R_DX = (u16) (res >> 16);
+    if (M.x86.R_DX == 0) {
+        CLEAR_FLAG(F_CF);
+        CLEAR_FLAG(F_OF);
+    }
+    else {
+        SET_FLAG(F_CF);
+        SET_FLAG(F_OF);
+    }
+}
+
+/****************************************************************************
+REMARKS:
+Implements the MUL instruction and side effects.
+****************************************************************************/
+void
+mul_long(u32 s)
+{
+#ifdef	__HAS_LONG_LONG__
+    u64 res = (u64) M.x86.R_EAX * s;
+
+    M.x86.R_EAX = (u32) res;
+    M.x86.R_EDX = (u32) (res >> 32);
+#else
+    u32 a, a_lo, a_hi;
+    u32 s_lo, s_hi;
+    u32 rlo_lo, rlo_hi, rhi_lo;
+
+    a = M.x86.R_EAX;
+    a_lo = a & 0xFFFF;
+    a_hi = a >> 16;
+    s_lo = s & 0xFFFF;
+    s_hi = s >> 16;
+    rlo_lo = a_lo * s_lo;
+    rlo_hi = (a_hi * s_lo + a_lo * s_hi) + (rlo_lo >> 16);
+    rhi_lo = a_hi * s_hi + (rlo_hi >> 16);
+    M.x86.R_EAX = (rlo_hi << 16) | (rlo_lo & 0xFFFF);
+    M.x86.R_EDX = rhi_lo;
+#endif
+
+    if (M.x86.R_EDX == 0) {
+        CLEAR_FLAG(F_CF);
+        CLEAR_FLAG(F_OF);
+    }
+    else {
+        SET_FLAG(F_CF);
+        SET_FLAG(F_OF);
+    }
+}
+
+/****************************************************************************
+REMARKS:
+Implements the IDIV instruction and side effects.
+****************************************************************************/
+void
+idiv_byte(u8 s)
+{
+    s32 dvd, div, mod;
+
+    dvd = (s16) M.x86.R_AX;
+    if (s == 0) {
+        x86emu_intr_raise(0);
+        return;
+    }
+    div = dvd / (s8) s;
+    mod = dvd % (s8) s;
+    if (abs(div) > 0x7f) {
+        x86emu_intr_raise(0);
+        return;
+    }
+    M.x86.R_AL = (s8) div;
+    M.x86.R_AH = (s8) mod;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the IDIV instruction and side effects.
+****************************************************************************/
+void
+idiv_word(u16 s)
+{
+    s32 dvd, div, mod;
+
+    dvd = (((s32) M.x86.R_DX) << 16) | M.x86.R_AX;
+    if (s == 0) {
+        x86emu_intr_raise(0);
+        return;
+    }
+    div = dvd / (s16) s;
+    mod = dvd % (s16) s;
+    if (abs(div) > 0x7fff) {
+        x86emu_intr_raise(0);
+        return;
+    }
+    CLEAR_FLAG(F_CF);
+    CLEAR_FLAG(F_SF);
+    CONDITIONAL_SET_FLAG(div == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
+
+    M.x86.R_AX = (u16) div;
+    M.x86.R_DX = (u16) mod;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the IDIV instruction and side effects.
+****************************************************************************/
+void
+idiv_long(u32 s)
+{
+#ifdef	__HAS_LONG_LONG__
+    s64 dvd, div, mod;
+
+    dvd = (((s64) M.x86.R_EDX) << 32) | M.x86.R_EAX;
+    if (s == 0) {
+        x86emu_intr_raise(0);
+        return;
+    }
+    div = dvd / (s32) s;
+    mod = dvd % (s32) s;
+    if (abs(div) > 0x7fffffff) {
+        x86emu_intr_raise(0);
+        return;
+    }
+#else
+    s32 div = 0, mod;
+    s32 h_dvd = M.x86.R_EDX;
+    u32 l_dvd = M.x86.R_EAX;
+    u32 abs_s = s & 0x7FFFFFFF;
+    u32 abs_h_dvd = h_dvd & 0x7FFFFFFF;
+    u32 h_s = abs_s >> 1;
+    u32 l_s = abs_s << 31;
+    int counter = 31;
+    int carry;
+
+    if (s == 0) {
+        x86emu_intr_raise(0);
+        return;
+    }
+    do {
+        div <<= 1;
+        carry = (l_dvd >= l_s) ? 0 : 1;
+
+        if (abs_h_dvd < (h_s + carry)) {
+            h_s >>= 1;
+            l_s = abs_s << (--counter);
+            continue;
+        }
+        else {
+            abs_h_dvd -= (h_s + carry);
+            l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
+                : (l_dvd - l_s);
+            h_s >>= 1;
+            l_s = abs_s << (--counter);
+            div |= 1;
+            continue;
+        }
+
+    } while (counter > -1);
+    /* overflow */
+    if (abs_h_dvd || (l_dvd > abs_s)) {
+        x86emu_intr_raise(0);
+        return;
+    }
+    /* sign */
+    div |= ((h_dvd & 0x10000000) ^ (s & 0x10000000));
+    mod = l_dvd;
+
+#endif
+    CLEAR_FLAG(F_CF);
+    CLEAR_FLAG(F_AF);
+    CLEAR_FLAG(F_SF);
+    SET_FLAG(F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
+
+    M.x86.R_EAX = (u32) div;
+    M.x86.R_EDX = (u32) mod;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the DIV instruction and side effects.
+****************************************************************************/
+void
+div_byte(u8 s)
+{
+    u32 dvd, div, mod;
+
+    dvd = M.x86.R_AX;
+    if (s == 0) {
+        x86emu_intr_raise(0);
+        return;
+    }
+    div = dvd / (u8) s;
+    mod = dvd % (u8) s;
+    if (abs(div) > 0xff) {
+        x86emu_intr_raise(0);
+        return;
+    }
+    M.x86.R_AL = (u8) div;
+    M.x86.R_AH = (u8) mod;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the DIV instruction and side effects.
+****************************************************************************/
+void
+div_word(u16 s)
+{
+    u32 dvd, div, mod;
+
+    dvd = (((u32) M.x86.R_DX) << 16) | M.x86.R_AX;
+    if (s == 0) {
+        x86emu_intr_raise(0);
+        return;
+    }
+    div = dvd / (u16) s;
+    mod = dvd % (u16) s;
+    if (abs(div) > 0xffff) {
+        x86emu_intr_raise(0);
+        return;
+    }
+    CLEAR_FLAG(F_CF);
+    CLEAR_FLAG(F_SF);
+    CONDITIONAL_SET_FLAG(div == 0, F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
+
+    M.x86.R_AX = (u16) div;
+    M.x86.R_DX = (u16) mod;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the DIV instruction and side effects.
+****************************************************************************/
+void
+div_long(u32 s)
+{
+#ifdef	__HAS_LONG_LONG__
+    u64 dvd, div, mod;
+
+    dvd = (((u64) M.x86.R_EDX) << 32) | M.x86.R_EAX;
+    if (s == 0) {
+        x86emu_intr_raise(0);
+        return;
+    }
+    div = dvd / (u32) s;
+    mod = dvd % (u32) s;
+    if (abs(div) > 0xffffffff) {
+        x86emu_intr_raise(0);
+        return;
+    }
+#else
+    s32 div = 0, mod;
+    s32 h_dvd = M.x86.R_EDX;
+    u32 l_dvd = M.x86.R_EAX;
+
+    u32 h_s = s;
+    u32 l_s = 0;
+    int counter = 32;
+    int carry;
+
+    if (s == 0) {
+        x86emu_intr_raise(0);
+        return;
+    }
+    do {
+        div <<= 1;
+        carry = (l_dvd >= l_s) ? 0 : 1;
+
+        if (h_dvd < (h_s + carry)) {
+            h_s >>= 1;
+            l_s = s << (--counter);
+            continue;
+        }
+        else {
+            h_dvd -= (h_s + carry);
+            l_dvd = carry ? ((0xFFFFFFFF - l_s) + l_dvd + 1)
+                : (l_dvd - l_s);
+            h_s >>= 1;
+            l_s = s << (--counter);
+            div |= 1;
+            continue;
+        }
+
+    } while (counter > -1);
+    /* overflow */
+    if (h_dvd || (l_dvd > s)) {
+        x86emu_intr_raise(0);
+        return;
+    }
+    mod = l_dvd;
+#endif
+    CLEAR_FLAG(F_CF);
+    CLEAR_FLAG(F_AF);
+    CLEAR_FLAG(F_SF);
+    SET_FLAG(F_ZF);
+    CONDITIONAL_SET_FLAG(PARITY(mod & 0xff), F_PF);
+
+    M.x86.R_EAX = (u32) div;
+    M.x86.R_EDX = (u32) mod;
+}
+
+/****************************************************************************
+REMARKS:
+Implements the IN string instruction and side effects.
+****************************************************************************/
+void
+ins(int size)
+{
+    int inc = size;
+
+    if (ACCESS_FLAG(F_DF)) {
+        inc = -size;
+    }
+    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
+        /* dont care whether REPE or REPNE */
+        /* in until CX is ZERO. */
+        u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
+                     M.x86.R_ECX : M.x86.R_CX);
+        switch (size) {
+        case 1:
+            while (count--) {
+                store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,
+                                    (*sys_inb) (M.x86.R_DX));
+                M.x86.R_DI += inc;
+            }
+            break;
+
+        case 2:
+            while (count--) {
+                store_data_word_abs(M.x86.R_ES, M.x86.R_DI,
+                                    (*sys_inw) (M.x86.R_DX));
+                M.x86.R_DI += inc;
+            }
+            break;
+        case 4:
+            while (count--) {
+                store_data_long_abs(M.x86.R_ES, M.x86.R_DI,
+                                    (*sys_inl) (M.x86.R_DX));
+                M.x86.R_DI += inc;
+                break;
+            }
+        }
+        M.x86.R_CX = 0;
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            M.x86.R_ECX = 0;
+        }
+        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
+    }
+    else {
+        switch (size) {
+        case 1:
+            store_data_byte_abs(M.x86.R_ES, M.x86.R_DI,
+                                (*sys_inb) (M.x86.R_DX));
+            break;
+        case 2:
+            store_data_word_abs(M.x86.R_ES, M.x86.R_DI,
+                                (*sys_inw) (M.x86.R_DX));
+            break;
+        case 4:
+            store_data_long_abs(M.x86.R_ES, M.x86.R_DI,
+                                (*sys_inl) (M.x86.R_DX));
+            break;
+        }
+        M.x86.R_DI += inc;
+    }
+}
+
+/****************************************************************************
+REMARKS:
+Implements the OUT string instruction and side effects.
+****************************************************************************/
+void
+outs(int size)
+{
+    int inc = size;
+
+    if (ACCESS_FLAG(F_DF)) {
+        inc = -size;
+    }
+    if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
+        /* dont care whether REPE or REPNE */
+        /* out until CX is ZERO. */
+        u32 count = ((M.x86.mode & SYSMODE_PREFIX_DATA) ?
+                     M.x86.R_ECX : M.x86.R_CX);
+        switch (size) {
+        case 1:
+            while (count--) {
+                (*sys_outb) (M.x86.R_DX,
+                             fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
+                M.x86.R_SI += inc;
+            }
+            break;
+
+        case 2:
+            while (count--) {
+                (*sys_outw) (M.x86.R_DX,
+                             fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
+                M.x86.R_SI += inc;
+            }
+            break;
+        case 4:
+            while (count--) {
+                (*sys_outl) (M.x86.R_DX,
+                             fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
+                M.x86.R_SI += inc;
+                break;
+            }
+        }
+        M.x86.R_CX = 0;
+        if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+            M.x86.R_ECX = 0;
+        }
+        M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
+    }
+    else {
+        switch (size) {
+        case 1:
+            (*sys_outb) (M.x86.R_DX,
+                         fetch_data_byte_abs(M.x86.R_ES, M.x86.R_SI));
+            break;
+        case 2:
+            (*sys_outw) (M.x86.R_DX,
+                         fetch_data_word_abs(M.x86.R_ES, M.x86.R_SI));
+            break;
+        case 4:
+            (*sys_outl) (M.x86.R_DX,
+                         fetch_data_long_abs(M.x86.R_ES, M.x86.R_SI));
+            break;
+        }
+        M.x86.R_SI += inc;
+    }
+}
+
+/****************************************************************************
+PARAMETERS:
+addr	- Address to fetch word from
+
+REMARKS:
+Fetches a word from emulator memory using an absolute address.
+****************************************************************************/
+u16
+mem_access_word(int addr)
+{
+    DB(if (CHECK_MEM_ACCESS())
+       x86emu_check_mem_access(addr);)
+        return (*sys_rdw) (addr);
+}
+
+/****************************************************************************
+REMARKS:
+Pushes a word onto the stack.
+
+NOTE: Do not inline this, as (*sys_wrX) is already inline!
+****************************************************************************/
+void
+push_word(u16 w)
+{
+    DB(if (CHECK_SP_ACCESS())
+       x86emu_check_sp_access();)
+        M.x86.R_SP -= 2;
+    (*sys_wrw) (((u32) M.x86.R_SS << 4) + M.x86.R_SP, w);
+}
+
+/****************************************************************************
+REMARKS:
+Pushes a long onto the stack.
+
+NOTE: Do not inline this, as (*sys_wrX) is already inline!
+****************************************************************************/
+void
+push_long(u32 w)
+{
+    DB(if (CHECK_SP_ACCESS())
+       x86emu_check_sp_access();)
+        M.x86.R_SP -= 4;
+    (*sys_wrl) (((u32) M.x86.R_SS << 4) + M.x86.R_SP, w);
+}
+
+/****************************************************************************
+REMARKS:
+Pops a word from the stack.
+
+NOTE: Do not inline this, as (*sys_rdX) is already inline!
+****************************************************************************/
+u16
+pop_word(void)
+{
+    register u16 res;
+
+    DB(if (CHECK_SP_ACCESS())
+       x86emu_check_sp_access();)
+        res = (*sys_rdw) (((u32) M.x86.R_SS << 4) + M.x86.R_SP);
+    M.x86.R_SP += 2;
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+Pops a long from the stack.
+
+NOTE: Do not inline this, as (*sys_rdX) is already inline!
+****************************************************************************/
+u32
+pop_long(void)
+{
+    register u32 res;
+
+    DB(if (CHECK_SP_ACCESS())
+       x86emu_check_sp_access();)
+        res = (*sys_rdl) (((u32) M.x86.R_SS << 4) + M.x86.R_SP);
+    M.x86.R_SP += 4;
+    return res;
+}
+
+/****************************************************************************
+REMARKS:
+CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output
+****************************************************************************/
+void
+cpuid(void)
+{
+    u32 feature = M.x86.R_EAX;
+
+#ifdef X86EMU_HAS_HW_CPUID
+    /* If the platform allows it, we will base our values on the real
+     * results from the CPUID instruction.  We limit support to the
+     * first two features, and the results of those are sanitized.
+     */
+    if (feature <= 1)
+        hw_cpuid(&M.x86.R_EAX, &M.x86.R_EBX, &M.x86.R_ECX, &M.x86.R_EDX);
+#endif
+
+    switch (feature) {
+    case 0:
+        /* Regardless if we have real data from the hardware, the emulator
+         * will only support upto feature 1, which we set in register EAX.
+         * Registers EBX:EDX:ECX contain a string identifying the CPU.
+         */
+        M.x86.R_EAX = 1;
+#ifndef X86EMU_HAS_HW_CPUID
+        /* EBX:EDX:ECX = "GenuineIntel" */
+        M.x86.R_EBX = 0x756e6547;
+        M.x86.R_EDX = 0x49656e69;
+        M.x86.R_ECX = 0x6c65746e;
+#endif
+        break;
+    case 1:
+#ifndef X86EMU_HAS_HW_CPUID
+        /* If we don't have x86 compatible hardware, we return values from an
+         * Intel 486dx4; which was one of the first processors to have CPUID.
+         */
+        M.x86.R_EAX = 0x00000480;
+        M.x86.R_EBX = 0x00000000;
+        M.x86.R_ECX = 0x00000000;
+        M.x86.R_EDX = 0x00000002;       /* VME */
+#else
+        /* In the case that we have hardware CPUID instruction, we make sure
+         * that the features reported are limited to TSC and VME.
+         */
+        M.x86.R_EDX &= 0x00000012;
+#endif
+        break;
+    default:
+        /* Finally, we don't support any additional features.  Most CPUs
+         * return all zeros when queried for invalid or unsupported feature
+         * numbers.
+         */
+        M.x86.R_EAX = 0;
+        M.x86.R_EBX = 0;
+        M.x86.R_ECX = 0;
+        M.x86.R_EDX = 0;
+        break;
+    }
+}
diff --git a/plat/pc65oo2/emu/x86emu/sys.c b/plat/pc65oo2/emu/x86emu/sys.c
new file mode 100644
index 000000000..ccce540e7
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/sys.c
@@ -0,0 +1,550 @@
+/****************************************************************************
+*
+*						Realmode X86 Emulator Library
+*
+*            	Copyright (C) 1996-1999 SciTech Software, Inc.
+* 				     Copyright (C) David Mosberger-Tang
+* 					   Copyright (C) 1999 Egbert Eich
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:		ANSI C
+* Environment:	Any
+* Developer:    Kendall Bennett
+*
+* Description:  This file includes subroutines which are related to
+*				programmed I/O and memory access. Included in this module
+*				are default functions with limited usefulness. For real
+*				uses these functions will most likely be overriden by the
+*				user library.
+*
+****************************************************************************/
+
+#include "x86emu.h"
+#include "x86emu/x86emui.h"
+#include "x86emu/regs.h"
+#include "x86emu/debug.h"
+#include "x86emu/prim_ops.h"
+#ifndef NO_SYS_HEADERS
+#include <string.h>
+#endif
+
+#ifdef __GNUC__
+
+/* Define some packed structures to use with unaligned accesses */
+
+struct __una_u64 {
+    u64 x __attribute__ ((packed));
+};
+struct __una_u32 {
+    u32 x __attribute__ ((packed));
+};
+struct __una_u16 {
+    u16 x __attribute__ ((packed));
+};
+
+/* Elemental unaligned loads */
+
+static __inline__ u64
+ldq_u(u64 * p)
+{
+    const struct __una_u64 *ptr = (const struct __una_u64 *) p;
+
+    return ptr->x;
+}
+
+static __inline__ u32
+ldl_u(u32 * p)
+{
+    const struct __una_u32 *ptr = (const struct __una_u32 *) p;
+
+    return ptr->x;
+}
+
+static __inline__ u16
+ldw_u(u16 * p)
+{
+    const struct __una_u16 *ptr = (const struct __una_u16 *) p;
+
+    return ptr->x;
+}
+
+/* Elemental unaligned stores */
+
+static __inline__ void
+stq_u(u64 val, u64 * p)
+{
+    struct __una_u64 *ptr = (struct __una_u64 *) p;
+
+    ptr->x = val;
+}
+
+static __inline__ void
+stl_u(u32 val, u32 * p)
+{
+    struct __una_u32 *ptr = (struct __una_u32 *) p;
+
+    ptr->x = val;
+}
+
+static __inline__ void
+stw_u(u16 val, u16 * p)
+{
+    struct __una_u16 *ptr = (struct __una_u16 *) p;
+
+    ptr->x = val;
+}
+#else                           /* !__GNUC__ */
+
+static __inline__ u64
+ldq_u(u64 * p)
+{
+    u64 ret;
+
+    memmove(&ret, p, sizeof(*p));
+    return ret;
+}
+
+static __inline__ u32
+ldl_u(u32 * p)
+{
+    u32 ret;
+
+    memmove(&ret, p, sizeof(*p));
+    return ret;
+}
+
+static __inline__ u16
+ldw_u(u16 * p)
+{
+    u16 ret;
+
+    memmove(&ret, p, sizeof(*p));
+    return ret;
+}
+
+static __inline__ void
+stq_u(u64 val, u64 * p)
+{
+    u64 tmp = val;
+
+    memmove(p, &tmp, sizeof(*p));
+}
+
+static __inline__ void
+stl_u(u32 val, u32 * p)
+{
+    u32 tmp = val;
+
+    memmove(p, &tmp, sizeof(*p));
+}
+
+static __inline__ void
+stw_u(u16 val, u16 * p)
+{
+    u16 tmp = val;
+
+    memmove(p, &tmp, sizeof(*p));
+}
+
+#endif                          /* __GNUC__ */
+/*------------------------- Global Variables ------------------------------*/
+
+X86EMU_sysEnv _X86EMU_env;      /* Global emulator machine state */
+X86EMU_intrFuncs _X86EMU_intrTab[256];
+
+/*----------------------------- Implementation ----------------------------*/
+
+/****************************************************************************
+PARAMETERS:
+addr	- Emulator memory address to read
+
+RETURNS:
+Byte value read from emulator memory.
+
+REMARKS:
+Reads a byte value from the emulator memory.
+****************************************************************************/
+u8 X86API
+rdb(u32 addr)
+{
+    u8 val;
+
+    if (addr > M.mem_size - 1) {
+        DB(printk("mem_read: address %#" PRIx32 " out of range!\n", addr);
+            )
+            HALT_SYS();
+    }
+    val = *(u8 *) (M.mem_base + addr);
+    DB(if (DEBUG_MEM_TRACE())
+       printk("%#08x 1 -> %#x\n", addr, val);)
+        return val;
+}
+
+/****************************************************************************
+PARAMETERS:
+addr	- Emulator memory address to read
+
+RETURNS:
+Word value read from emulator memory.
+
+REMARKS:
+Reads a word value from the emulator memory.
+****************************************************************************/
+u16 X86API
+rdw(u32 addr)
+{
+    u16 val = 0;
+
+    if (addr > M.mem_size - 2) {
+        DB(printk("mem_read: address %#" PRIx32 " out of range!\n", addr);
+            )
+            HALT_SYS();
+    }
+#ifdef __BIG_ENDIAN__
+    if (addr & 0x1) {
+        val = (*(u8 *) (M.mem_base + addr) |
+               (*(u8 *) (M.mem_base + addr + 1) << 8));
+    }
+    else
+#endif
+        val = ldw_u((u16 *) (M.mem_base + addr));
+    DB(if (DEBUG_MEM_TRACE())
+       printk("%#08x 2 -> %#x\n", addr, val);)
+        return val;
+}
+
+/****************************************************************************
+PARAMETERS:
+addr	- Emulator memory address to read
+
+RETURNS:
+Long value read from emulator memory.
+REMARKS:
+Reads a long value from the emulator memory.
+****************************************************************************/
+u32 X86API
+rdl(u32 addr)
+{
+    u32 val = 0;
+
+    if (addr > M.mem_size - 4) {
+        DB(printk("mem_read: address %#" PRIx32 " out of range!\n", addr);
+            )
+            HALT_SYS();
+    }
+#ifdef __BIG_ENDIAN__
+    if (addr & 0x3) {
+        val = (*(u8 *) (M.mem_base + addr + 0) |
+               (*(u8 *) (M.mem_base + addr + 1) << 8) |
+               (*(u8 *) (M.mem_base + addr + 2) << 16) |
+               (*(u8 *) (M.mem_base + addr + 3) << 24));
+    }
+    else
+#endif
+        val = ldl_u((u32 *) (M.mem_base + addr));
+    DB(if (DEBUG_MEM_TRACE())
+       printk("%#08x 4 -> %#x\n", addr, val);)
+        return val;
+}
+
+/****************************************************************************
+PARAMETERS:
+addr	- Emulator memory address to read
+val		- Value to store
+
+REMARKS:
+Writes a byte value to emulator memory.
+****************************************************************************/
+void X86API
+wrb(u32 addr, u8 val)
+{
+    DB(if (DEBUG_MEM_TRACE())
+       printk("%#08x 1 <- %#x\n", addr, val);)
+        if (addr > M.mem_size - 1) {
+            DB(printk("mem_write: address %#" PRIx32 " out of range!\n",addr);
+                )
+                HALT_SYS();
+        }
+    *(u8 *) (M.mem_base + addr) = val;
+}
+
+/****************************************************************************
+PARAMETERS:
+addr	- Emulator memory address to read
+val		- Value to store
+
+REMARKS:
+Writes a word value to emulator memory.
+****************************************************************************/
+void X86API
+wrw(u32 addr, u16 val)
+{
+    DB(if (DEBUG_MEM_TRACE())
+       printk("%#08x 2 <- %#x\n", addr, val);)
+        if (addr > M.mem_size - 2) {
+            DB(printk("mem_write: address %#" PRIx32 " out of range!\n",addr);
+                )
+                HALT_SYS();
+        }
+#ifdef __BIG_ENDIAN__
+    if (addr & 0x1) {
+        *(u8 *) (M.mem_base + addr + 0) = (val >> 0) & 0xff;
+        *(u8 *) (M.mem_base + addr + 1) = (val >> 8) & 0xff;
+    }
+    else
+#endif
+        stw_u(val, (u16 *) (M.mem_base + addr));
+}
+
+/****************************************************************************
+PARAMETERS:
+addr	- Emulator memory address to read
+val		- Value to store
+
+REMARKS:
+Writes a long value to emulator memory.
+****************************************************************************/
+void X86API
+wrl(u32 addr, u32 val)
+{
+    DB(if (DEBUG_MEM_TRACE())
+       printk("%#08x 4 <- %#x\n", addr, val);)
+        if (addr > M.mem_size - 4) {
+            DB(printk("mem_write: address %#" PRIx32 " out of range!\n",addr);
+                )
+                HALT_SYS();
+        }
+#ifdef __BIG_ENDIAN__
+    if (addr & 0x1) {
+        *(u8 *) (M.mem_base + addr + 0) = (val >> 0) & 0xff;
+        *(u8 *) (M.mem_base + addr + 1) = (val >> 8) & 0xff;
+        *(u8 *) (M.mem_base + addr + 2) = (val >> 16) & 0xff;
+        *(u8 *) (M.mem_base + addr + 3) = (val >> 24) & 0xff;
+    }
+    else
+#endif
+        stl_u(val, (u32 *) (M.mem_base + addr));
+}
+
+/****************************************************************************
+PARAMETERS:
+addr	- PIO address to read
+RETURN:
+0
+REMARKS:
+Default PIO byte read function. Doesn't perform real inb.
+****************************************************************************/
+static u8 X86API
+p_inb(X86EMU_pioAddr addr)
+{
+    DB(if (DEBUG_IO_TRACE())
+       printk("inb %#04x \n", addr);)
+        return 0;
+}
+
+/****************************************************************************
+PARAMETERS:
+addr	- PIO address to read
+RETURN:
+0
+REMARKS:
+Default PIO word read function. Doesn't perform real inw.
+****************************************************************************/
+static u16 X86API
+p_inw(X86EMU_pioAddr addr)
+{
+    DB(if (DEBUG_IO_TRACE())
+       printk("inw %#04x \n", addr);)
+        return 0;
+}
+
+/****************************************************************************
+PARAMETERS:
+addr	- PIO address to read
+RETURN:
+0
+REMARKS:
+Default PIO long read function. Doesn't perform real inl.
+****************************************************************************/
+static u32 X86API
+p_inl(X86EMU_pioAddr addr)
+{
+    DB(if (DEBUG_IO_TRACE())
+       printk("inl %#04x \n", addr);)
+        return 0;
+}
+
+/****************************************************************************
+PARAMETERS:
+addr	- PIO address to write
+val     - Value to store
+REMARKS:
+Default PIO byte write function. Doesn't perform real outb.
+****************************************************************************/
+static void X86API
+p_outb(X86EMU_pioAddr addr, u8 val)
+{
+    DB(if (DEBUG_IO_TRACE())
+       printk("outb %#02x -> %#04x \n", val, addr);)
+        return;
+}
+
+/****************************************************************************
+PARAMETERS:
+addr	- PIO address to write
+val     - Value to store
+REMARKS:
+Default PIO word write function. Doesn't perform real outw.
+****************************************************************************/
+static void X86API
+p_outw(X86EMU_pioAddr addr, u16 val)
+{
+    DB(if (DEBUG_IO_TRACE())
+       printk("outw %#04x -> %#04x \n", val, addr);)
+        return;
+}
+
+/****************************************************************************
+PARAMETERS:
+addr	- PIO address to write
+val     - Value to store
+REMARKS:
+Default PIO ;ong write function. Doesn't perform real outl.
+****************************************************************************/
+static void X86API
+p_outl(X86EMU_pioAddr addr, u32 val)
+{
+    DB(if (DEBUG_IO_TRACE())
+       printk("outl %#08x -> %#04x \n", val, addr);)
+        return;
+}
+
+/*------------------------- Global Variables ------------------------------*/
+
+u8(X86APIP sys_rdb) (u32 addr) = rdb;
+u16(X86APIP sys_rdw) (u32 addr) = rdw;
+u32(X86APIP sys_rdl) (u32 addr) = rdl;
+void (X86APIP sys_wrb) (u32 addr, u8 val) = wrb;
+void (X86APIP sys_wrw) (u32 addr, u16 val) = wrw;
+void (X86APIP sys_wrl) (u32 addr, u32 val) = wrl;
+
+u8(X86APIP sys_inb) (X86EMU_pioAddr addr) = p_inb;
+u16(X86APIP sys_inw) (X86EMU_pioAddr addr) = p_inw;
+u32(X86APIP sys_inl) (X86EMU_pioAddr addr) = p_inl;
+void (X86APIP sys_outb) (X86EMU_pioAddr addr, u8 val) = p_outb;
+void (X86APIP sys_outw) (X86EMU_pioAddr addr, u16 val) = p_outw;
+void (X86APIP sys_outl) (X86EMU_pioAddr addr, u32 val) = p_outl;
+
+/*----------------------------- Setup -------------------------------------*/
+
+/****************************************************************************
+PARAMETERS:
+funcs	- New memory function pointers to make active
+
+REMARKS:
+This function is used to set the pointers to functions which access
+memory space, allowing the user application to override these functions
+and hook them out as necessary for their application.
+****************************************************************************/
+void
+X86EMU_setupMemFuncs(X86EMU_memFuncs * funcs)
+{
+    sys_rdb = funcs->rdb;
+    sys_rdw = funcs->rdw;
+    sys_rdl = funcs->rdl;
+    sys_wrb = funcs->wrb;
+    sys_wrw = funcs->wrw;
+    sys_wrl = funcs->wrl;
+}
+
+/****************************************************************************
+PARAMETERS:
+funcs	- New programmed I/O function pointers to make active
+
+REMARKS:
+This function is used to set the pointers to functions which access
+I/O space, allowing the user application to override these functions
+and hook them out as necessary for their application.
+****************************************************************************/
+void
+X86EMU_setupPioFuncs(X86EMU_pioFuncs * funcs)
+{
+    sys_inb = funcs->inb;
+    sys_inw = funcs->inw;
+    sys_inl = funcs->inl;
+    sys_outb = funcs->outb;
+    sys_outw = funcs->outw;
+    sys_outl = funcs->outl;
+}
+
+/****************************************************************************
+PARAMETERS:
+funcs	- New interrupt vector table to make active
+
+REMARKS:
+This function is used to set the pointers to functions which handle
+interrupt processing in the emulator, allowing the user application to
+hook interrupts as necessary for their application. Any interrupts that
+are not hooked by the user application, and reflected and handled internally
+in the emulator via the interrupt vector table. This allows the application
+to get control when the code being emulated executes specific software
+interrupts.
+****************************************************************************/
+void
+X86EMU_setupIntrFuncs(X86EMU_intrFuncs funcs[])
+{
+    int i;
+
+    for (i = 0; i < 256; i++)
+        _X86EMU_intrTab[i] = NULL;
+    if (funcs) {
+        for (i = 0; i < 256; i++)
+            _X86EMU_intrTab[i] = funcs[i];
+    }
+}
+
+/****************************************************************************
+PARAMETERS:
+int	- New software interrupt to prepare for
+
+REMARKS:
+This function is used to set up the emulator state to exceute a software
+interrupt. This can be used by the user application code to allow an
+interrupt to be hooked, examined and then reflected back to the emulator
+so that the code in the emulator will continue processing the software
+interrupt as per normal. This essentially allows system code to actively
+hook and handle certain software interrupts as necessary.
+****************************************************************************/
+void
+X86EMU_prepareForInt(int num)
+{
+    push_word((u16) M.x86.R_FLG);
+    CLEAR_FLAG(F_IF);
+    CLEAR_FLAG(F_TF);
+    push_word(M.x86.R_CS);
+    M.x86.R_CS = mem_access_word(num * 4 + 2);
+    push_word(M.x86.R_IP);
+    M.x86.R_IP = mem_access_word(num * 4);
+    M.x86.intr = 0;
+}
diff --git a/plat/pc65oo2/emu/x86emu/x86emu.h b/plat/pc65oo2/emu/x86emu/x86emu.h
new file mode 100644
index 000000000..501dd913c
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/x86emu.h
@@ -0,0 +1,197 @@
+/****************************************************************************
+*
+*						Realmode X86 Emulator Library
+*
+*            	Copyright (C) 1996-1999 SciTech Software, Inc.
+* 				     Copyright (C) David Mosberger-Tang
+* 					   Copyright (C) 1999 Egbert Eich
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:		ANSI C
+* Environment:	Any
+* Developer:    Kendall Bennett
+*
+* Description:  Header file for public specific functions.
+*               Any application linking against us should only
+*               include this header
+*
+****************************************************************************/
+
+#ifndef __X86EMU_X86EMU_H
+#define __X86EMU_X86EMU_H
+
+#ifdef SCITECH
+#include "scitech.h"
+#define	X86API	_ASMAPI
+#define	X86APIP	_ASMAPIP
+typedef int X86EMU_pioAddr;
+#else
+#include "x86emu/types.h"
+#define	X86API
+#define	X86APIP	*
+#endif
+#include "x86emu/regs.h"
+
+/*---------------------- Macros and type definitions ----------------------*/
+
+#ifdef PACK
+#pragma	PACK                    /* Don't pack structs with function pointers! */
+#endif
+
+/****************************************************************************
+REMARKS:
+Data structure containing ponters to programmed I/O functions used by the
+emulator. This is used so that the user program can hook all programmed
+I/O for the emulator to handled as necessary by the user program. By
+default the emulator contains simple functions that do not do access the
+hardware in any way. To allow the emualtor access the hardware, you will
+need to override the programmed I/O functions using the X86EMU_setupPioFuncs
+function.
+
+HEADER:
+x86emu.h
+
+MEMBERS:
+inb		- Function to read a byte from an I/O port
+inw		- Function to read a word from an I/O port
+inl     - Function to read a dword from an I/O port
+outb	- Function to write a byte to an I/O port
+outw    - Function to write a word to an I/O port
+outl    - Function to write a dword to an I/O port
+****************************************************************************/
+typedef struct {
+    u8(X86APIP inb) (X86EMU_pioAddr addr);
+    u16(X86APIP inw) (X86EMU_pioAddr addr);
+    u32(X86APIP inl) (X86EMU_pioAddr addr);
+    void (X86APIP outb) (X86EMU_pioAddr addr, u8 val);
+    void (X86APIP outw) (X86EMU_pioAddr addr, u16 val);
+    void (X86APIP outl) (X86EMU_pioAddr addr, u32 val);
+} X86EMU_pioFuncs;
+
+/****************************************************************************
+REMARKS:
+Data structure containing ponters to memory access functions used by the
+emulator. This is used so that the user program can hook all memory
+access functions as necessary for the emulator. By default the emulator
+contains simple functions that only access the internal memory of the
+emulator. If you need specialised functions to handle access to different
+types of memory (ie: hardware framebuffer accesses and BIOS memory access
+etc), you will need to override this using the X86EMU_setupMemFuncs
+function.
+
+HEADER:
+x86emu.h
+
+MEMBERS:
+rdb		- Function to read a byte from an address
+rdw		- Function to read a word from an address
+rdl     - Function to read a dword from an address
+wrb		- Function to write a byte to an address
+wrw    	- Function to write a word to an address
+wrl    	- Function to write a dword to an address
+****************************************************************************/
+typedef struct {
+    u8(X86APIP rdb) (u32 addr);
+    u16(X86APIP rdw) (u32 addr);
+    u32(X86APIP rdl) (u32 addr);
+    void (X86APIP wrb) (u32 addr, u8 val);
+    void (X86APIP wrw) (u32 addr, u16 val);
+    void (X86APIP wrl) (u32 addr, u32 val);
+} X86EMU_memFuncs;
+
+/****************************************************************************
+  Here are the default memory read and write
+  function in case they are needed as fallbacks.
+***************************************************************************/
+extern u8 X86API rdb(u32 addr);
+extern u16 X86API rdw(u32 addr);
+extern u32 X86API rdl(u32 addr);
+extern void X86API wrb(u32 addr, u8 val);
+extern void X86API wrw(u32 addr, u16 val);
+extern void X86API wrl(u32 addr, u32 val);
+
+#ifdef END_PACK
+#pragma	END_PACK
+#endif
+
+/*--------------------- type definitions -----------------------------------*/
+
+typedef void (X86APIP X86EMU_intrFuncs) (int num);
+extern X86EMU_intrFuncs _X86EMU_intrTab[256];
+
+/*-------------------------- Function Prototypes --------------------------*/
+
+#ifdef  __cplusplus
+extern "C" {                    /* Use "C" linkage when in C++ mode */
+#endif
+
+    void X86EMU_setupMemFuncs(X86EMU_memFuncs * funcs);
+    void X86EMU_setupPioFuncs(X86EMU_pioFuncs * funcs);
+    void X86EMU_setupIntrFuncs(X86EMU_intrFuncs funcs[]);
+    void X86EMU_prepareForInt(int num);
+
+/* decode.c */
+
+    void X86EMU_exec(void);
+    void X86EMU_halt_sys(void);
+
+#ifdef	DEBUG
+#define	HALT_SYS()	\
+	printk("halt_sys: file %s, line %d\n", __FILE__, __LINE__), \
+	X86EMU_halt_sys()
+#else
+#define	HALT_SYS()	X86EMU_halt_sys()
+#endif
+
+/* Debug options */
+
+#define DEBUG_DECODE_F          0x000001        /* print decoded instruction  */
+#define DEBUG_TRACE_F           0x000002        /* dump regs before/after execution */
+#define DEBUG_STEP_F            0x000004
+#define DEBUG_DISASSEMBLE_F     0x000008
+#define DEBUG_BREAK_F           0x000010
+#define DEBUG_SVC_F             0x000020
+#define DEBUG_SAVE_IP_CS_F      0x000040
+#define DEBUG_FS_F              0x000080
+#define DEBUG_PROC_F            0x000100
+#define DEBUG_SYSINT_F          0x000200        /* bios system interrupts. */
+#define DEBUG_TRACECALL_F       0x000400
+#define DEBUG_INSTRUMENT_F      0x000800
+#define DEBUG_MEM_TRACE_F       0x001000
+#define DEBUG_IO_TRACE_F        0x002000
+#define DEBUG_TRACECALL_REGS_F  0x004000
+#define DEBUG_DECODE_NOPRINT_F  0x008000
+#define DEBUG_EXIT              0x010000
+#define DEBUG_SYS_F             (DEBUG_SVC_F|DEBUG_FS_F|DEBUG_PROC_F)
+
+    void X86EMU_trace_regs(void);
+    void X86EMU_trace_xregs(void);
+    void X86EMU_dump_memory(u16 seg, u16 off, u32 amt);
+    int X86EMU_trace_on(void);
+    int X86EMU_trace_off(void);
+
+#ifdef  __cplusplus
+}                               /* End of "C" linkage for C++           */
+#endif
+#endif                          /* __X86EMU_X86EMU_H */
diff --git a/plat/pc65oo2/emu/x86emu/x86emu/debug.h b/plat/pc65oo2/emu/x86emu/x86emu/debug.h
new file mode 100644
index 000000000..1158c2c90
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/x86emu/debug.h
@@ -0,0 +1,208 @@
+/****************************************************************************
+*
+*						Realmode X86 Emulator Library
+*
+*            	Copyright (C) 1996-1999 SciTech Software, Inc.
+* 				     Copyright (C) David Mosberger-Tang
+* 					   Copyright (C) 1999 Egbert Eich
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:		ANSI C
+* Environment:	Any
+* Developer:    Kendall Bennett
+*
+* Description:  Header file for debug definitions.
+*
+****************************************************************************/
+
+#ifndef __X86EMU_DEBUG_H
+#define __X86EMU_DEBUG_H
+
+/*---------------------- Macros and type definitions ----------------------*/
+
+/* checks to be enabled for "runtime" */
+
+#define CHECK_IP_FETCH_F                0x1
+#define CHECK_SP_ACCESS_F               0x2
+#define CHECK_MEM_ACCESS_F              0x4     /*using regular linear pointer */
+#define CHECK_DATA_ACCESS_F             0x8     /*using segment:offset */
+
+#ifdef DEBUG
+#define CHECK_IP_FETCH()              	(M.x86.check & CHECK_IP_FETCH_F)
+#define CHECK_SP_ACCESS()             	(M.x86.check & CHECK_SP_ACCESS_F)
+#define CHECK_MEM_ACCESS()            	(M.x86.check & CHECK_MEM_ACCESS_F)
+#define CHECK_DATA_ACCESS()           	(M.x86.check & CHECK_DATA_ACCESS_F)
+#else
+#define CHECK_IP_FETCH()
+#define CHECK_SP_ACCESS()
+#define CHECK_MEM_ACCESS()
+#define CHECK_DATA_ACCESS()
+#endif
+
+#ifdef DEBUG
+#define DEBUG_INSTRUMENT()    	(M.x86.debug & DEBUG_INSTRUMENT_F)
+#define DEBUG_DECODE()        	(M.x86.debug & DEBUG_DECODE_F)
+#define DEBUG_TRACE()         	(M.x86.debug & DEBUG_TRACE_F)
+#define DEBUG_STEP()          	(M.x86.debug & DEBUG_STEP_F)
+#define DEBUG_DISASSEMBLE()   	(M.x86.debug & DEBUG_DISASSEMBLE_F)
+#define DEBUG_BREAK()         	(M.x86.debug & DEBUG_BREAK_F)
+#define DEBUG_SVC()           	(M.x86.debug & DEBUG_SVC_F)
+#define DEBUG_SAVE_IP_CS()     (M.x86.debug & DEBUG_SAVE_IP_CS_F)
+
+#define DEBUG_FS()            	(M.x86.debug & DEBUG_FS_F)
+#define DEBUG_PROC()          	(M.x86.debug & DEBUG_PROC_F)
+#define DEBUG_SYSINT()        	(M.x86.debug & DEBUG_SYSINT_F)
+#define DEBUG_TRACECALL()     	(M.x86.debug & DEBUG_TRACECALL_F)
+#define DEBUG_TRACECALLREGS() 	(M.x86.debug & DEBUG_TRACECALL_REGS_F)
+#define DEBUG_SYS()           	(M.x86.debug & DEBUG_SYS_F)
+#define DEBUG_MEM_TRACE()     	(M.x86.debug & DEBUG_MEM_TRACE_F)
+#define DEBUG_IO_TRACE()      	(M.x86.debug & DEBUG_IO_TRACE_F)
+#define DEBUG_DECODE_NOPRINT() (M.x86.debug & DEBUG_DECODE_NOPRINT_F)
+#else
+#define DEBUG_INSTRUMENT()    	0
+#define DEBUG_DECODE()        	0
+#define DEBUG_TRACE()         	0
+#define DEBUG_STEP()          	0
+#define DEBUG_DISASSEMBLE()   	0
+#define DEBUG_BREAK()         	0
+#define DEBUG_SVC()           	0
+#define DEBUG_SAVE_IP_CS()     0
+#define DEBUG_FS()            	0
+#define DEBUG_PROC()          	0
+#define DEBUG_SYSINT()        	0
+#define DEBUG_TRACECALL()     	0
+#define DEBUG_TRACECALLREGS() 	0
+#define DEBUG_SYS()           	0
+#define DEBUG_MEM_TRACE()     	0
+#define DEBUG_IO_TRACE()      	0
+#define DEBUG_DECODE_NOPRINT() 0
+#endif
+
+#ifdef DEBUG
+
+#define DECODE_PRINTF(x)     	if (DEBUG_DECODE()) \
+									x86emu_decode_printf("%s",x)
+#define DECODE_PRINTF2(x,y)  	if (DEBUG_DECODE()) \
+									x86emu_decode_printf(x,y)
+
+/*
+ * The following allow us to look at the bytes of an instruction.  The
+ * first INCR_INSTRN_LEN, is called everytime bytes are consumed in
+ * the decoding process.  The SAVE_IP_CS is called initially when the
+ * major opcode of the instruction is accessed.
+ */
+#define INC_DECODED_INST_LEN(x)                    	\
+	if (DEBUG_DECODE())  	                       	\
+		x86emu_inc_decoded_inst_len(x)
+
+#define SAVE_IP_CS(x,y)                               			\
+	if (DEBUG_DECODE() | DEBUG_TRACECALL() | DEBUG_BREAK() \
+              | DEBUG_IO_TRACE() | DEBUG_SAVE_IP_CS()) { \
+		M.x86.saved_cs = x;                          			\
+		M.x86.saved_ip = y;                          			\
+	}
+#else
+#define INC_DECODED_INST_LEN(x)
+#define DECODE_PRINTF(x)
+#define DECODE_PRINTF2(x,y)
+#define SAVE_IP_CS(x,y)
+#endif
+
+#ifdef DEBUG
+#define TRACE_REGS()                                   		\
+	if (DEBUG_DISASSEMBLE()) {                         		\
+		x86emu_just_disassemble();                        	\
+		goto EndOfTheInstructionProcedure;             		\
+	}                                                   	\
+	if (DEBUG_TRACE() || DEBUG_DECODE()) X86EMU_trace_regs()
+#else
+#define TRACE_REGS()
+#endif
+
+#ifdef DEBUG
+#define SINGLE_STEP()		if (DEBUG_STEP()) x86emu_single_step()
+#else
+#define SINGLE_STEP()
+#endif
+
+#define TRACE_AND_STEP()	\
+	TRACE_REGS();			\
+	SINGLE_STEP()
+
+#ifdef DEBUG
+#define START_OF_INSTR()
+#define END_OF_INSTR()		EndOfTheInstructionProcedure: x86emu_end_instr();
+#define END_OF_INSTR_NO_TRACE()	x86emu_end_instr();
+#else
+#define START_OF_INSTR()
+#define END_OF_INSTR()
+#define END_OF_INSTR_NO_TRACE()
+#endif
+
+#ifdef DEBUG
+#define  CALL_TRACE(u,v,w,x,s)                                 \
+	if (DEBUG_TRACECALLREGS())									\
+		x86emu_dump_regs();                                     \
+	if (DEBUG_TRACECALL())                                     	\
+		printk("%04x:%04x: CALL %s%04x:%04x\n", u , v, s, w, x);
+#define RETURN_TRACE(n,u,v)                                    \
+	if (DEBUG_TRACECALLREGS())									\
+		x86emu_dump_regs();                                     \
+	if (DEBUG_TRACECALL())                                     	\
+		printk("%04x:%04x: %s\n",u,v,n);
+#else
+#define CALL_TRACE(u,v,w,x,s)
+#define RETURN_TRACE(n,u,v)
+#endif
+
+#ifdef DEBUG
+#define	DB(x)	x
+#else
+#define	DB(x)
+#endif
+
+/*-------------------------- Function Prototypes --------------------------*/
+
+#ifdef  __cplusplus
+extern "C" {                    /* Use "C" linkage when in C++ mode */
+#endif
+
+    extern void x86emu_inc_decoded_inst_len(int x);
+    extern void x86emu_decode_printf(const char *x, ...);
+    extern void x86emu_just_disassemble(void);
+    extern void x86emu_single_step(void);
+    extern void x86emu_end_instr(void);
+    extern void x86emu_dump_regs(void);
+    extern void x86emu_dump_xregs(void);
+    extern void x86emu_print_int_vect(u16 iv);
+    extern void x86emu_instrument_instruction(void);
+    extern void x86emu_check_ip_access(void);
+    extern void x86emu_check_sp_access(void);
+    extern void x86emu_check_mem_access(u32 p);
+    extern void x86emu_check_data_access(uint s, uint o);
+
+#ifdef  __cplusplus
+}                               /* End of "C" linkage for C++           */
+#endif
+#endif                          /* __X86EMU_DEBUG_H */
diff --git a/plat/pc65oo2/emu/x86emu/x86emu/decode.h b/plat/pc65oo2/emu/x86emu/x86emu/decode.h
new file mode 100644
index 000000000..49a1f7b54
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/x86emu/decode.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+*
+*						Realmode X86 Emulator Library
+*
+*            	Copyright (C) 1996-1999 SciTech Software, Inc.
+* 				     Copyright (C) David Mosberger-Tang
+* 					   Copyright (C) 1999 Egbert Eich
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:		ANSI C
+* Environment:	Any
+* Developer:    Kendall Bennett
+*
+* Description:  Header file for instruction decoding logic.
+*
+****************************************************************************/
+
+#ifndef __X86EMU_DECODE_H
+#define __X86EMU_DECODE_H
+
+/*---------------------- Macros and type definitions ----------------------*/
+
+/* Instruction Decoding Stuff */
+
+#define FETCH_DECODE_MODRM(mod,rh,rl) 	fetch_decode_modrm(&mod,&rh,&rl)
+#define DECODE_RM_BYTE_REGISTER(r)    	decode_rm_byte_register(r)
+#define DECODE_RM_WORD_REGISTER(r)    	decode_rm_word_register(r)
+#define DECODE_RM_LONG_REGISTER(r)    	decode_rm_long_register(r)
+#define DECODE_CLEAR_SEGOVR()         	M.x86.mode &= ~SYSMODE_CLRMASK
+
+/*-------------------------- Function Prototypes --------------------------*/
+
+#ifdef  __cplusplus
+extern "C" {                    /* Use "C" linkage when in C++ mode */
+#endif
+
+    void x86emu_intr_raise(u8 type);
+    void fetch_decode_modrm(int *mod, int *regh, int *regl);
+    u8 fetch_byte_imm(void);
+    u16 fetch_word_imm(void);
+    u32 fetch_long_imm(void);
+    u8 fetch_data_byte(uint offset);
+    u8 fetch_data_byte_abs(uint segment, uint offset);
+    u16 fetch_data_word(uint offset);
+    u16 fetch_data_word_abs(uint segment, uint offset);
+    u32 fetch_data_long(uint offset);
+    u32 fetch_data_long_abs(uint segment, uint offset);
+    void store_data_byte(uint offset, u8 val);
+    void store_data_byte_abs(uint segment, uint offset, u8 val);
+    void store_data_word(uint offset, u16 val);
+    void store_data_word_abs(uint segment, uint offset, u16 val);
+    void store_data_long(uint offset, u32 val);
+    void store_data_long_abs(uint segment, uint offset, u32 val);
+    u8 *decode_rm_byte_register(int reg);
+    u16 *decode_rm_word_register(int reg);
+    u32 *decode_rm_long_register(int reg);
+    u16 *decode_rm_seg_register(int reg);
+    u32 decode_rm00_address(int rm);
+    u32 decode_rm01_address(int rm);
+    u32 decode_rm10_address(int rm);
+    u32 decode_sib_address(int sib, int mod);
+
+#ifdef  __cplusplus
+}                               /* End of "C" linkage for C++           */
+#endif
+#endif                          /* __X86EMU_DECODE_H */
diff --git a/plat/pc65oo2/emu/x86emu/x86emu/fpu.h b/plat/pc65oo2/emu/x86emu/x86emu/fpu.h
new file mode 100644
index 000000000..1c114987f
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/x86emu/fpu.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+*
+*						Realmode X86 Emulator Library
+*
+*            	Copyright (C) 1996-1999 SciTech Software, Inc.
+* 				     Copyright (C) David Mosberger-Tang
+* 					   Copyright (C) 1999 Egbert Eich
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:		ANSI C
+* Environment:	Any
+* Developer:    Kendall Bennett
+*
+* Description:  Header file for FPU instruction decoding.
+*
+****************************************************************************/
+
+#ifndef __X86EMU_FPU_H
+#define __X86EMU_FPU_H
+
+#ifdef  __cplusplus
+extern "C" {                    /* Use "C" linkage when in C++ mode */
+#endif
+
+/* these have to be defined, whether 8087 support compiled in or not. */
+
+    extern void x86emuOp_esc_coprocess_d8(u8 op1);
+    extern void x86emuOp_esc_coprocess_d9(u8 op1);
+    extern void x86emuOp_esc_coprocess_da(u8 op1);
+    extern void x86emuOp_esc_coprocess_db(u8 op1);
+    extern void x86emuOp_esc_coprocess_dc(u8 op1);
+    extern void x86emuOp_esc_coprocess_dd(u8 op1);
+    extern void x86emuOp_esc_coprocess_de(u8 op1);
+    extern void x86emuOp_esc_coprocess_df(u8 op1);
+
+#ifdef  __cplusplus
+}                               /* End of "C" linkage for C++           */
+#endif
+#endif                          /* __X86EMU_FPU_H */
diff --git a/plat/pc65oo2/emu/x86emu/x86emu/fpu_regs.h b/plat/pc65oo2/emu/x86emu/x86emu/fpu_regs.h
new file mode 100644
index 000000000..5a780e69c
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/x86emu/fpu_regs.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+*
+*						Realmode X86 Emulator Library
+*
+*            	Copyright (C) 1996-1999 SciTech Software, Inc.
+* 				     Copyright (C) David Mosberger-Tang
+* 					   Copyright (C) 1999 Egbert Eich
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:		ANSI C
+* Environment:	Any
+* Developer:    Kendall Bennett
+*
+* Description:  Header file for FPU register definitions.
+*
+****************************************************************************/
+
+#ifndef __X86EMU_FPU_REGS_H
+#define __X86EMU_FPU_REGS_H
+
+#ifdef X86_FPU_SUPPORT
+
+#ifdef PACK
+#pragma PACK
+#endif
+
+/* Basic 8087 register can hold any of the following values: */
+
+union x86_fpu_reg_u {
+    s8 tenbytes[10];
+    double dval;
+    float fval;
+    s16 sval;
+    s32 lval;
+};
+
+struct x86_fpu_reg {
+    union x86_fpu_reg_u reg;
+    char tag;
+};
+
+/*
+ * Since we are not going to worry about the problems of aliasing
+ * registers, every time a register is modified, its result type is
+ * set in the tag fields for that register.  If some operation
+ * attempts to access the type in a way inconsistent with its current
+ * storage format, then we flag the operation.  If common, we'll
+ * attempt the conversion.
+ */
+
+#define  X86_FPU_VALID          0x80
+#define  X86_FPU_REGTYP(r)      ((r) & 0x7F)
+
+#define  X86_FPU_WORD           0x0
+#define  X86_FPU_SHORT          0x1
+#define  X86_FPU_LONG           0x2
+#define  X86_FPU_FLOAT          0x3
+#define  X86_FPU_DOUBLE         0x4
+#define  X86_FPU_LDBL           0x5
+#define  X86_FPU_BSD            0x6
+
+#define  X86_FPU_STKTOP  0
+
+struct x86_fpu_registers {
+    struct x86_fpu_reg x86_fpu_stack[8];
+    int x86_fpu_flags;
+    int x86_fpu_config;         /* rounding modes, etc. */
+    short x86_fpu_tos, x86_fpu_bos;
+};
+
+#ifdef END_PACK
+#pragma END_PACK
+#endif
+
+/*
+ * There are two versions of the following macro.
+ *
+ * One version is for opcode D9, for which there are more than 32
+ * instructions encoded in the second byte of the opcode.
+ *
+ * The other version, deals with all the other 7 i87 opcodes, for
+ * which there are only 32 strings needed to describe the
+ * instructions.
+ */
+
+#endif                          /* X86_FPU_SUPPORT */
+
+#ifdef DEBUG
+#define DECODE_PRINTINSTR32(t,mod,rh,rl)     	\
+	DECODE_PRINTF(t[(mod<<3)+(rh)]);
+#define DECODE_PRINTINSTR256(t,mod,rh,rl)    	\
+	DECODE_PRINTF(t[(mod<<6)+(rh<<3)+(rl)]);
+#else
+#define DECODE_PRINTINSTR32(t,mod,rh,rl)
+#define DECODE_PRINTINSTR256(t,mod,rh,rl)
+#endif
+
+#endif                          /* __X86EMU_FPU_REGS_H */
diff --git a/plat/pc65oo2/emu/x86emu/x86emu/ops.h b/plat/pc65oo2/emu/x86emu/x86emu/ops.h
new file mode 100644
index 000000000..1bc07a4e1
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/x86emu/ops.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+*
+*						Realmode X86 Emulator Library
+*
+*            	Copyright (C) 1996-1999 SciTech Software, Inc.
+* 				     Copyright (C) David Mosberger-Tang
+* 					   Copyright (C) 1999 Egbert Eich
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:		ANSI C
+* Environment:	Any
+* Developer:    Kendall Bennett
+*
+* Description:  Header file for operand decoding functions.
+*
+****************************************************************************/
+
+#ifndef __X86EMU_OPS_H
+#define __X86EMU_OPS_H
+
+extern void (*x86emu_optab[0x100]) (u8 op1);
+extern void (*x86emu_optab2[0x100]) (u8 op2);
+
+#endif                          /* __X86EMU_OPS_H */
diff --git a/plat/pc65oo2/emu/x86emu/x86emu/prim_asm.h b/plat/pc65oo2/emu/x86emu/x86emu/prim_asm.h
new file mode 100644
index 000000000..aca132bf1
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/x86emu/prim_asm.h
@@ -0,0 +1,1053 @@
+/****************************************************************************
+*
+*						Realmode X86 Emulator Library
+*
+*            	Copyright (C) 1996-1999 SciTech Software, Inc.
+* 				     Copyright (C) David Mosberger-Tang
+* 					   Copyright (C) 1999 Egbert Eich
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:		Watcom C++ 10.6 or later
+* Environment:	Any
+* Developer:    Kendall Bennett
+*
+* Description:  Inline assembler versions of the primitive operand
+*				functions for faster performance. At the moment this is
+*				x86 inline assembler, but these functions could be replaced
+*				with native inline assembler for each supported processor
+*				platform.
+*
+****************************************************************************/
+
+#ifndef	__X86EMU_PRIM_ASM_H
+#define	__X86EMU_PRIM_ASM_H
+
+#ifdef	__WATCOMC__
+
+#ifndef	VALIDATE
+#define	__HAVE_INLINE_ASSEMBLER__
+#endif
+
+u32 get_flags_asm(void);
+
+#pragma aux get_flags_asm =			\
+	"pushf"                         \
+	"pop	eax"                  	\
+	value [eax]                     \
+	modify exact [eax];
+
+u16 aaa_word_asm(u32 * flags, u16 d);
+
+#pragma aux aaa_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"aaa"                  			\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] 				\
+	value [ax]                      \
+	modify exact [ax];
+
+u16 aas_word_asm(u32 * flags, u16 d);
+
+#pragma aux aas_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"aas"                  			\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] 				\
+	value [ax]                      \
+	modify exact [ax];
+
+u16 aad_word_asm(u32 * flags, u16 d);
+
+#pragma aux aad_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"aad"                  			\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] 				\
+	value [ax]                      \
+	modify exact [ax];
+
+u16 aam_word_asm(u32 * flags, u8 d);
+
+#pragma aux aam_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"aam"                  			\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al] 				\
+	value [ax]                      \
+	modify exact [ax];
+
+u8 adc_byte_asm(u32 * flags, u8 d, u8 s);
+
+#pragma aux adc_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"adc	al,bl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al] [bl]            \
+	value [al]                      \
+	modify exact [al bl];
+
+u16 adc_word_asm(u32 * flags, u16 d, u16 s);
+
+#pragma aux adc_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"adc	ax,bx"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] [bx]            \
+	value [ax]                      \
+	modify exact [ax bx];
+
+u32 adc_long_asm(u32 * flags, u32 d, u32 s);
+
+#pragma aux adc_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"adc	eax,ebx"                \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax] [ebx]          \
+	value [eax]                     \
+	modify exact [eax ebx];
+
+u8 add_byte_asm(u32 * flags, u8 d, u8 s);
+
+#pragma aux add_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"add	al,bl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al] [bl]            \
+	value [al]                      \
+	modify exact [al bl];
+
+u16 add_word_asm(u32 * flags, u16 d, u16 s);
+
+#pragma aux add_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"add	ax,bx"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] [bx]            \
+	value [ax]                      \
+	modify exact [ax bx];
+
+u32 add_long_asm(u32 * flags, u32 d, u32 s);
+
+#pragma aux add_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"add	eax,ebx"                \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax] [ebx]          \
+	value [eax]                     \
+	modify exact [eax ebx];
+
+u8 and_byte_asm(u32 * flags, u8 d, u8 s);
+
+#pragma aux and_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"and	al,bl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al] [bl]            \
+	value [al]                      \
+	modify exact [al bl];
+
+u16 and_word_asm(u32 * flags, u16 d, u16 s);
+
+#pragma aux and_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"and	ax,bx"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] [bx]            \
+	value [ax]                      \
+	modify exact [ax bx];
+
+u32 and_long_asm(u32 * flags, u32 d, u32 s);
+
+#pragma aux and_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"and	eax,ebx"                \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax] [ebx]          \
+	value [eax]                     \
+	modify exact [eax ebx];
+
+u8 cmp_byte_asm(u32 * flags, u8 d, u8 s);
+
+#pragma aux cmp_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"cmp	al,bl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al] [bl]            \
+	value [al]                      \
+	modify exact [al bl];
+
+u16 cmp_word_asm(u32 * flags, u16 d, u16 s);
+
+#pragma aux cmp_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"cmp	ax,bx"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] [bx]            \
+	value [ax]                      \
+	modify exact [ax bx];
+
+u32 cmp_long_asm(u32 * flags, u32 d, u32 s);
+
+#pragma aux cmp_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"cmp	eax,ebx"                \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax] [ebx]          \
+	value [eax]                     \
+	modify exact [eax ebx];
+
+u8 daa_byte_asm(u32 * flags, u8 d);
+
+#pragma aux daa_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"daa"                  			\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al]            		\
+	value [al]                      \
+	modify exact [al];
+
+u8 das_byte_asm(u32 * flags, u8 d);
+
+#pragma aux das_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"das"                  			\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al]            		\
+	value [al]                      \
+	modify exact [al];
+
+u8 dec_byte_asm(u32 * flags, u8 d);
+
+#pragma aux dec_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"dec	al"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al]            		\
+	value [al]                      \
+	modify exact [al];
+
+u16 dec_word_asm(u32 * flags, u16 d);
+
+#pragma aux dec_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"dec	ax"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax]            		\
+	value [ax]                      \
+	modify exact [ax];
+
+u32 dec_long_asm(u32 * flags, u32 d);
+
+#pragma aux dec_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"dec	eax"                	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax]          		\
+	value [eax]                     \
+	modify exact [eax];
+
+u8 inc_byte_asm(u32 * flags, u8 d);
+
+#pragma aux inc_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"inc	al"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al]            		\
+	value [al]                      \
+	modify exact [al];
+
+u16 inc_word_asm(u32 * flags, u16 d);
+
+#pragma aux inc_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"inc	ax"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax]            		\
+	value [ax]                      \
+	modify exact [ax];
+
+u32 inc_long_asm(u32 * flags, u32 d);
+
+#pragma aux inc_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"inc	eax"                	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax]          		\
+	value [eax]                     \
+	modify exact [eax];
+
+u8 or_byte_asm(u32 * flags, u8 d, u8 s);
+
+#pragma aux or_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"or	al,bl"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al] [bl]            \
+	value [al]                      \
+	modify exact [al bl];
+
+u16 or_word_asm(u32 * flags, u16 d, u16 s);
+
+#pragma aux or_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"or	ax,bx"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] [bx]            \
+	value [ax]                      \
+	modify exact [ax bx];
+
+u32 or_long_asm(u32 * flags, u32 d, u32 s);
+
+#pragma aux or_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"or	eax,ebx"                	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax] [ebx]          \
+	value [eax]                     \
+	modify exact [eax ebx];
+
+u8 neg_byte_asm(u32 * flags, u8 d);
+
+#pragma aux neg_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"neg	al"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al]            		\
+	value [al]                      \
+	modify exact [al];
+
+u16 neg_word_asm(u32 * flags, u16 d);
+
+#pragma aux neg_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"neg	ax"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax]            		\
+	value [ax]                      \
+	modify exact [ax];
+
+u32 neg_long_asm(u32 * flags, u32 d);
+
+#pragma aux neg_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"neg	eax"                	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax]          		\
+	value [eax]                     \
+	modify exact [eax];
+
+u8 not_byte_asm(u32 * flags, u8 d);
+
+#pragma aux not_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"not	al"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al]            		\
+	value [al]                      \
+	modify exact [al];
+
+u16 not_word_asm(u32 * flags, u16 d);
+
+#pragma aux not_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"not	ax"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax]            		\
+	value [ax]                      \
+	modify exact [ax];
+
+u32 not_long_asm(u32 * flags, u32 d);
+
+#pragma aux not_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"not	eax"                	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax]          		\
+	value [eax]                     \
+	modify exact [eax];
+
+u8 rcl_byte_asm(u32 * flags, u8 d, u8 s);
+
+#pragma aux rcl_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"rcl	al,cl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al] [cl]            \
+	value [al]                      \
+	modify exact [al cl];
+
+u16 rcl_word_asm(u32 * flags, u16 d, u8 s);
+
+#pragma aux rcl_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"rcl	ax,cl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] [cl]            \
+	value [ax]                      \
+	modify exact [ax cl];
+
+u32 rcl_long_asm(u32 * flags, u32 d, u8 s);
+
+#pragma aux rcl_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"rcl	eax,cl"                	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax] [cl]          	\
+	value [eax]                     \
+	modify exact [eax cl];
+
+u8 rcr_byte_asm(u32 * flags, u8 d, u8 s);
+
+#pragma aux rcr_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"rcr	al,cl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al] [cl]            \
+	value [al]                      \
+	modify exact [al cl];
+
+u16 rcr_word_asm(u32 * flags, u16 d, u8 s);
+
+#pragma aux rcr_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"rcr	ax,cl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] [cl]            \
+	value [ax]                      \
+	modify exact [ax cl];
+
+u32 rcr_long_asm(u32 * flags, u32 d, u8 s);
+
+#pragma aux rcr_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"rcr	eax,cl"                	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax] [cl]          	\
+	value [eax]                     \
+	modify exact [eax cl];
+
+u8 rol_byte_asm(u32 * flags, u8 d, u8 s);
+
+#pragma aux rol_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"rol	al,cl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al] [cl]            \
+	value [al]                      \
+	modify exact [al cl];
+
+u16 rol_word_asm(u32 * flags, u16 d, u8 s);
+
+#pragma aux rol_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"rol	ax,cl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] [cl]            \
+	value [ax]                      \
+	modify exact [ax cl];
+
+u32 rol_long_asm(u32 * flags, u32 d, u8 s);
+
+#pragma aux rol_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"rol	eax,cl"                	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax] [cl]          	\
+	value [eax]                     \
+	modify exact [eax cl];
+
+u8 ror_byte_asm(u32 * flags, u8 d, u8 s);
+
+#pragma aux ror_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"ror	al,cl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al] [cl]            \
+	value [al]                      \
+	modify exact [al cl];
+
+u16 ror_word_asm(u32 * flags, u16 d, u8 s);
+
+#pragma aux ror_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"ror	ax,cl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] [cl]            \
+	value [ax]                      \
+	modify exact [ax cl];
+
+u32 ror_long_asm(u32 * flags, u32 d, u8 s);
+
+#pragma aux ror_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"ror	eax,cl"                	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax] [cl]          	\
+	value [eax]                     \
+	modify exact [eax cl];
+
+u8 shl_byte_asm(u32 * flags, u8 d, u8 s);
+
+#pragma aux shl_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"shl	al,cl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al] [cl]            \
+	value [al]                      \
+	modify exact [al cl];
+
+u16 shl_word_asm(u32 * flags, u16 d, u8 s);
+
+#pragma aux shl_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"shl	ax,cl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] [cl]            \
+	value [ax]                      \
+	modify exact [ax cl];
+
+u32 shl_long_asm(u32 * flags, u32 d, u8 s);
+
+#pragma aux shl_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"shl	eax,cl"                	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax] [cl]          	\
+	value [eax]                     \
+	modify exact [eax cl];
+
+u8 shr_byte_asm(u32 * flags, u8 d, u8 s);
+
+#pragma aux shr_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"shr	al,cl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al] [cl]            \
+	value [al]                      \
+	modify exact [al cl];
+
+u16 shr_word_asm(u32 * flags, u16 d, u8 s);
+
+#pragma aux shr_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"shr	ax,cl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] [cl]            \
+	value [ax]                      \
+	modify exact [ax cl];
+
+u32 shr_long_asm(u32 * flags, u32 d, u8 s);
+
+#pragma aux shr_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"shr	eax,cl"                	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax] [cl]          	\
+	value [eax]                     \
+	modify exact [eax cl];
+
+u8 sar_byte_asm(u32 * flags, u8 d, u8 s);
+
+#pragma aux sar_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"sar	al,cl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al] [cl]            \
+	value [al]                      \
+	modify exact [al cl];
+
+u16 sar_word_asm(u32 * flags, u16 d, u8 s);
+
+#pragma aux sar_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"sar	ax,cl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] [cl]            \
+	value [ax]                      \
+	modify exact [ax cl];
+
+u32 sar_long_asm(u32 * flags, u32 d, u8 s);
+
+#pragma aux sar_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"sar	eax,cl"                	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax] [cl]          	\
+	value [eax]                     \
+	modify exact [eax cl];
+
+u16 shld_word_asm(u32 * flags, u16 d, u16 fill, u8 s);
+
+#pragma aux shld_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"shld	ax,dx,cl"               \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] [dx] [cl]       \
+	value [ax]                      \
+	modify exact [ax dx cl];
+
+u32 shld_long_asm(u32 * flags, u32 d, u32 fill, u8 s);
+
+#pragma aux shld_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"shld	eax,edx,cl"             \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax] [edx] [cl]     \
+	value [eax]                     \
+	modify exact [eax edx cl];
+
+u16 shrd_word_asm(u32 * flags, u16 d, u16 fill, u8 s);
+
+#pragma aux shrd_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"shrd	ax,dx,cl"               \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] [dx] [cl]       \
+	value [ax]                      \
+	modify exact [ax dx cl];
+
+u32 shrd_long_asm(u32 * flags, u32 d, u32 fill, u8 s);
+
+#pragma aux shrd_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"shrd	eax,edx,cl"             \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax] [edx] [cl]     \
+	value [eax]                     \
+	modify exact [eax edx cl];
+
+u8 sbb_byte_asm(u32 * flags, u8 d, u8 s);
+
+#pragma aux sbb_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"sbb	al,bl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al] [bl]            \
+	value [al]                      \
+	modify exact [al bl];
+
+u16 sbb_word_asm(u32 * flags, u16 d, u16 s);
+
+#pragma aux sbb_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"sbb	ax,bx"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] [bx]            \
+	value [ax]                      \
+	modify exact [ax bx];
+
+u32 sbb_long_asm(u32 * flags, u32 d, u32 s);
+
+#pragma aux sbb_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"sbb	eax,ebx"                \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax] [ebx]          \
+	value [eax]                     \
+	modify exact [eax ebx];
+
+u8 sub_byte_asm(u32 * flags, u8 d, u8 s);
+
+#pragma aux sub_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"sub	al,bl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al] [bl]            \
+	value [al]                      \
+	modify exact [al bl];
+
+u16 sub_word_asm(u32 * flags, u16 d, u16 s);
+
+#pragma aux sub_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"sub	ax,bx"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] [bx]            \
+	value [ax]                      \
+	modify exact [ax bx];
+
+u32 sub_long_asm(u32 * flags, u32 d, u32 s);
+
+#pragma aux sub_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"sub	eax,ebx"                \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax] [ebx]          \
+	value [eax]                     \
+	modify exact [eax ebx];
+
+void test_byte_asm(u32 * flags, u8 d, u8 s);
+
+#pragma aux test_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"test	al,bl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al] [bl]            \
+	modify exact [al bl];
+
+void test_word_asm(u32 * flags, u16 d, u16 s);
+
+#pragma aux test_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"test	ax,bx"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] [bx]            \
+	modify exact [ax bx];
+
+void test_long_asm(u32 * flags, u32 d, u32 s);
+
+#pragma aux test_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"test	eax,ebx"                \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax] [ebx]          \
+	modify exact [eax ebx];
+
+u8 xor_byte_asm(u32 * flags, u8 d, u8 s);
+
+#pragma aux xor_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"xor	al,bl"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [al] [bl]            \
+	value [al]                      \
+	modify exact [al bl];
+
+u16 xor_word_asm(u32 * flags, u16 d, u16 s);
+
+#pragma aux xor_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"xor	ax,bx"                  \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [ax] [bx]            \
+	value [ax]                      \
+	modify exact [ax bx];
+
+u32 xor_long_asm(u32 * flags, u32 d, u32 s);
+
+#pragma aux xor_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"xor	eax,ebx"                \
+	"pushf"                         \
+	"pop	[edi]"            		\
+	parm [edi] [eax] [ebx]          \
+	value [eax]                     \
+	modify exact [eax ebx];
+
+void imul_byte_asm(u32 * flags, u16 * ax, u8 d, u8 s);
+
+#pragma aux imul_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"imul	bl"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	"mov	[esi],ax"				\
+	parm [edi] [esi] [al] [bl]      \
+	modify exact [esi ax bl];
+
+void imul_word_asm(u32 * flags, u16 * ax, u16 * dx, u16 d, u16 s);
+
+#pragma aux imul_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"imul	bx"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	"mov	[esi],ax"				\
+	"mov	[ecx],dx"				\
+	parm [edi] [esi] [ecx] [ax] [bx]\
+	modify exact [esi edi ax bx dx];
+
+void imul_long_asm(u32 * flags, u32 * eax, u32 * edx, u32 d, u32 s);
+
+#pragma aux imul_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"imul	ebx"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	"mov	[esi],eax"				\
+	"mov	[ecx],edx"				\
+	parm [edi] [esi] [ecx] [eax] [ebx] \
+	modify exact [esi edi eax ebx edx];
+
+void mul_byte_asm(u32 * flags, u16 * ax, u8 d, u8 s);
+
+#pragma aux mul_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"mul	bl"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	"mov	[esi],ax"				\
+	parm [edi] [esi] [al] [bl]      \
+	modify exact [esi ax bl];
+
+void mul_word_asm(u32 * flags, u16 * ax, u16 * dx, u16 d, u16 s);
+
+#pragma aux mul_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"mul	bx"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	"mov	[esi],ax"				\
+	"mov	[ecx],dx"				\
+	parm [edi] [esi] [ecx] [ax] [bx]\
+	modify exact [esi edi ax bx dx];
+
+void mul_long_asm(u32 * flags, u32 * eax, u32 * edx, u32 d, u32 s);
+
+#pragma aux mul_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"mul	ebx"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	"mov	[esi],eax"				\
+	"mov	[ecx],edx"				\
+	parm [edi] [esi] [ecx] [eax] [ebx] \
+	modify exact [esi edi eax ebx edx];
+
+void idiv_byte_asm(u32 * flags, u8 * al, u8 * ah, u16 d, u8 s);
+
+#pragma aux idiv_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"idiv	bl"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	"mov	[esi],al"				\
+	"mov	[ecx],ah"				\
+	parm [edi] [esi] [ecx] [ax] [bl]\
+	modify exact [esi edi ax bl];
+
+void idiv_word_asm(u32 * flags, u16 * ax, u16 * dx, u16 dlo, u16 dhi, u16 s);
+
+#pragma aux idiv_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"idiv	bx"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	"mov	[esi],ax"				\
+	"mov	[ecx],dx"				\
+	parm [edi] [esi] [ecx] [ax] [dx] [bx]\
+	modify exact [esi edi ax dx bx];
+
+void idiv_long_asm(u32 * flags, u32 * eax, u32 * edx, u32 dlo, u32 dhi, u32 s);
+
+#pragma aux idiv_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"idiv	ebx"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	"mov	[esi],eax"				\
+	"mov	[ecx],edx"				\
+	parm [edi] [esi] [ecx] [eax] [edx] [ebx]\
+	modify exact [esi edi eax edx ebx];
+
+void div_byte_asm(u32 * flags, u8 * al, u8 * ah, u16 d, u8 s);
+
+#pragma aux div_byte_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"div	bl"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	"mov	[esi],al"				\
+	"mov	[ecx],ah"				\
+	parm [edi] [esi] [ecx] [ax] [bl]\
+	modify exact [esi edi ax bl];
+
+void div_word_asm(u32 * flags, u16 * ax, u16 * dx, u16 dlo, u16 dhi, u16 s);
+
+#pragma aux div_word_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"div	bx"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	"mov	[esi],ax"				\
+	"mov	[ecx],dx"				\
+	parm [edi] [esi] [ecx] [ax] [dx] [bx]\
+	modify exact [esi edi ax dx bx];
+
+void div_long_asm(u32 * flags, u32 * eax, u32 * edx, u32 dlo, u32 dhi, u32 s);
+
+#pragma aux div_long_asm =			\
+	"push	[edi]"            		\
+	"popf"                         	\
+	"div	ebx"                  	\
+	"pushf"                         \
+	"pop	[edi]"            		\
+	"mov	[esi],eax"				\
+	"mov	[ecx],edx"				\
+	parm [edi] [esi] [ecx] [eax] [edx] [ebx]\
+	modify exact [esi edi eax edx ebx];
+
+#endif
+
+#endif                          /* __X86EMU_PRIM_ASM_H */
diff --git a/plat/pc65oo2/emu/x86emu/x86emu/prim_ops.h b/plat/pc65oo2/emu/x86emu/x86emu/prim_ops.h
new file mode 100644
index 000000000..0f0e78d71
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/x86emu/prim_ops.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+*
+*						Realmode X86 Emulator Library
+*
+*            	Copyright (C) 1996-1999 SciTech Software, Inc.
+* 				     Copyright (C) David Mosberger-Tang
+* 					   Copyright (C) 1999 Egbert Eich
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:		ANSI C
+* Environment:	Any
+* Developer:    Kendall Bennett
+*
+* Description:  Header file for primitive operation functions.
+*
+****************************************************************************/
+
+#ifndef __X86EMU_PRIM_OPS_H
+#define __X86EMU_PRIM_OPS_H
+
+#ifdef  __cplusplus
+extern "C" {                    /* Use "C" linkage when in C++ mode */
+#endif
+
+    u16 aaa_word(u16 d);
+    u16 aas_word(u16 d);
+    u16 aad_word(u16 d);
+    u16 aam_word(u8 d);
+    u8 adc_byte(u8 d, u8 s);
+    u16 adc_word(u16 d, u16 s);
+    u32 adc_long(u32 d, u32 s);
+    u8 add_byte(u8 d, u8 s);
+    u16 add_word(u16 d, u16 s);
+    u32 add_long(u32 d, u32 s);
+    u8 and_byte(u8 d, u8 s);
+    u16 and_word(u16 d, u16 s);
+    u32 and_long(u32 d, u32 s);
+    u8 cmp_byte(u8 d, u8 s);
+    u16 cmp_word(u16 d, u16 s);
+    u32 cmp_long(u32 d, u32 s);
+    u8 daa_byte(u8 d);
+    u8 das_byte(u8 d);
+    u8 dec_byte(u8 d);
+    u16 dec_word(u16 d);
+    u32 dec_long(u32 d);
+    u8 inc_byte(u8 d);
+    u16 inc_word(u16 d);
+    u32 inc_long(u32 d);
+    u8 or_byte(u8 d, u8 s);
+    u16 or_word(u16 d, u16 s);
+    u32 or_long(u32 d, u32 s);
+    u8 neg_byte(u8 s);
+    u16 neg_word(u16 s);
+    u32 neg_long(u32 s);
+    u8 not_byte(u8 s);
+    u16 not_word(u16 s);
+    u32 not_long(u32 s);
+    u8 rcl_byte(u8 d, u8 s);
+    u16 rcl_word(u16 d, u8 s);
+    u32 rcl_long(u32 d, u8 s);
+    u8 rcr_byte(u8 d, u8 s);
+    u16 rcr_word(u16 d, u8 s);
+    u32 rcr_long(u32 d, u8 s);
+    u8 rol_byte(u8 d, u8 s);
+    u16 rol_word(u16 d, u8 s);
+    u32 rol_long(u32 d, u8 s);
+    u8 ror_byte(u8 d, u8 s);
+    u16 ror_word(u16 d, u8 s);
+    u32 ror_long(u32 d, u8 s);
+    u8 shl_byte(u8 d, u8 s);
+    u16 shl_word(u16 d, u8 s);
+    u32 shl_long(u32 d, u8 s);
+    u8 shr_byte(u8 d, u8 s);
+    u16 shr_word(u16 d, u8 s);
+    u32 shr_long(u32 d, u8 s);
+    u8 sar_byte(u8 d, u8 s);
+    u16 sar_word(u16 d, u8 s);
+    u32 sar_long(u32 d, u8 s);
+    u16 shld_word(u16 d, u16 fill, u8 s);
+    u32 shld_long(u32 d, u32 fill, u8 s);
+    u16 shrd_word(u16 d, u16 fill, u8 s);
+    u32 shrd_long(u32 d, u32 fill, u8 s);
+    u8 sbb_byte(u8 d, u8 s);
+    u16 sbb_word(u16 d, u16 s);
+    u32 sbb_long(u32 d, u32 s);
+    u8 sub_byte(u8 d, u8 s);
+    u16 sub_word(u16 d, u16 s);
+    u32 sub_long(u32 d, u32 s);
+    void test_byte(u8 d, u8 s);
+    void test_word(u16 d, u16 s);
+    void test_long(u32 d, u32 s);
+    u8 xor_byte(u8 d, u8 s);
+    u16 xor_word(u16 d, u16 s);
+    u32 xor_long(u32 d, u32 s);
+    void imul_byte(u8 s);
+    void imul_word(u16 s);
+    void imul_long(u32 s);
+    void imul_long_direct(u32 * res_lo, u32 * res_hi, u32 d, u32 s);
+    void mul_byte(u8 s);
+    void mul_word(u16 s);
+    void mul_long(u32 s);
+    void idiv_byte(u8 s);
+    void idiv_word(u16 s);
+    void idiv_long(u32 s);
+    void div_byte(u8 s);
+    void div_word(u16 s);
+    void div_long(u32 s);
+    void ins(int size);
+    void outs(int size);
+    u16 mem_access_word(int addr);
+    void push_word(u16 w);
+    void push_long(u32 w);
+    u16 pop_word(void);
+    u32 pop_long(void);
+    void cpuid(void);
+
+#ifdef  __cplusplus
+}                               /* End of "C" linkage for C++           */
+#endif
+#endif                          /* __X86EMU_PRIM_OPS_H */
diff --git a/plat/pc65oo2/emu/x86emu/x86emu/prim_x86_gcc.h b/plat/pc65oo2/emu/x86emu/x86emu/prim_x86_gcc.h
new file mode 100644
index 000000000..646ec9def
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/x86emu/prim_x86_gcc.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+*
+* Inline helpers for x86emu
+*
+* Copyright (C) 2008 Bart Trojanowski, Symbio Technologies, LLC
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:     GNU C
+* Environment:  GCC on i386 or x86-64
+* Developer:    Bart Trojanowski
+*
+* Description:  This file defines a few x86 macros that can be used by the
+*               emulator to execute native instructions.
+*
+*               For PIC vs non-PIC code refer to:
+*               http://sam.zoy.org/blog/2007-04-13-shlib-with-non-pic-code-have-inline-assembly-and-pic-mix-well
+*
+****************************************************************************/
+#ifndef __X86EMU_PRIM_X86_GCC_H
+#define __X86EMU_PRIM_X86_GCC_H
+
+#include "x86emu/types.h"
+
+#if !defined(__GNUC__) || !(defined (__i386__) || defined(__i386) || defined(__AMD64__) || defined(__amd64__))
+#error This file is intended to be used by gcc on i386 or x86-64 system
+#endif
+
+#if defined(__PIC__) && defined(__i386__)
+
+#define X86EMU_HAS_HW_CPUID 1
+static inline void
+hw_cpuid(u32 * a, u32 * b, u32 * c, u32 * d)
+{
+    __asm__ __volatile__("pushl %%ebx      \n\t"
+                         "cpuid            \n\t"
+                         "movl %%ebx, %1   \n\t"
+                         "popl %%ebx       \n\t":"=a"(*a), "=r"(*b),
+                         "=c"(*c), "=d"(*d)
+                         :"a"(*a), "c"(*c)
+                         :"cc");
+}
+
+#else                           /* ! (__PIC__ && __i386__) */
+
+#define x86EMU_HAS_HW_CPUID 1
+static inline void
+hw_cpuid(u32 * a, u32 * b, u32 * c, u32 * d)
+{
+    __asm__ __volatile__("cpuid":"=a"(*a), "=b"(*b), "=c"(*c), "=d"(*d)
+                         :"a"(*a), "c"(*c)
+                         :"cc");
+}
+
+#endif                          /* __PIC__ && __i386__ */
+
+#endif                          /* __X86EMU_PRIM_X86_GCC_H */
diff --git a/plat/pc65oo2/emu/x86emu/x86emu/regs.h b/plat/pc65oo2/emu/x86emu/x86emu/regs.h
new file mode 100644
index 000000000..057f38cb7
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/x86emu/regs.h
@@ -0,0 +1,337 @@
+/****************************************************************************
+*
+*						Realmode X86 Emulator Library
+*
+*            	Copyright (C) 1996-1999 SciTech Software, Inc.
+* 				     Copyright (C) David Mosberger-Tang
+* 					   Copyright (C) 1999 Egbert Eich
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:		ANSI C
+* Environment:	Any
+* Developer:    Kendall Bennett
+*
+* Description:  Header file for x86 register definitions.
+*
+****************************************************************************/
+
+#ifndef __X86EMU_REGS_H
+#define __X86EMU_REGS_H
+
+/*---------------------- Macros and type definitions ----------------------*/
+
+#ifdef PACK
+#pragma PACK
+#endif
+
+/*
+ * General EAX, EBX, ECX, EDX type registers.  Note that for
+ * portability, and speed, the issue of byte swapping is not addressed
+ * in the registers.  All registers are stored in the default format
+ * available on the host machine.  The only critical issue is that the
+ * registers should line up EXACTLY in the same manner as they do in
+ * the 386.  That is:
+ *
+ * EAX & 0xff  === AL
+ * EAX & 0xffff == AX
+ *
+ * etc.  The result is that alot of the calculations can then be
+ * done using the native instruction set fully.
+ */
+
+#ifdef	__BIG_ENDIAN__
+
+typedef struct {
+    u32 e_reg;
+} I32_reg_t;
+
+typedef struct {
+    u16 filler0, x_reg;
+} I16_reg_t;
+
+typedef struct {
+    u8 filler0, filler1, h_reg, l_reg;
+} I8_reg_t;
+
+#else                           /* !__BIG_ENDIAN__ */
+
+typedef struct {
+    u32 e_reg;
+} I32_reg_t;
+
+typedef struct {
+    u16 x_reg;
+} I16_reg_t;
+
+typedef struct {
+    u8 l_reg, h_reg;
+} I8_reg_t;
+
+#endif                          /* BIG_ENDIAN */
+
+typedef union {
+    I32_reg_t I32_reg;
+    I16_reg_t I16_reg;
+    I8_reg_t I8_reg;
+} i386_general_register;
+
+struct i386_general_regs {
+    i386_general_register A, B, C, D;
+};
+
+typedef struct i386_general_regs Gen_reg_t;
+
+struct i386_special_regs {
+    i386_general_register SP, BP, SI, DI, IP;
+    u32 FLAGS;
+};
+
+/*
+ * Segment registers here represent the 16 bit quantities
+ * CS, DS, ES, SS.
+ */
+
+#if defined(__sun) && defined(CS) /* avoid conflicts with Solaris sys/regset.h */
+# undef CS
+# undef DS
+# undef SS
+# undef ES
+# undef FS
+# undef GS
+#endif
+
+struct i386_segment_regs {
+    u16 CS, DS, SS, ES, FS, GS;
+};
+
+/* 8 bit registers */
+#define R_AH  gen.A.I8_reg.h_reg
+#define R_AL  gen.A.I8_reg.l_reg
+#define R_BH  gen.B.I8_reg.h_reg
+#define R_BL  gen.B.I8_reg.l_reg
+#define R_CH  gen.C.I8_reg.h_reg
+#define R_CL  gen.C.I8_reg.l_reg
+#define R_DH  gen.D.I8_reg.h_reg
+#define R_DL  gen.D.I8_reg.l_reg
+
+/* 16 bit registers */
+#define R_AX  gen.A.I16_reg.x_reg
+#define R_BX  gen.B.I16_reg.x_reg
+#define R_CX  gen.C.I16_reg.x_reg
+#define R_DX  gen.D.I16_reg.x_reg
+
+/* 32 bit extended registers */
+#define R_EAX  gen.A.I32_reg.e_reg
+#define R_EBX  gen.B.I32_reg.e_reg
+#define R_ECX  gen.C.I32_reg.e_reg
+#define R_EDX  gen.D.I32_reg.e_reg
+
+/* special registers */
+#define R_SP  spc.SP.I16_reg.x_reg
+#define R_BP  spc.BP.I16_reg.x_reg
+#define R_SI  spc.SI.I16_reg.x_reg
+#define R_DI  spc.DI.I16_reg.x_reg
+#define R_IP  spc.IP.I16_reg.x_reg
+#define R_FLG spc.FLAGS
+
+/* special registers */
+#define R_ESP  spc.SP.I32_reg.e_reg
+#define R_EBP  spc.BP.I32_reg.e_reg
+#define R_ESI  spc.SI.I32_reg.e_reg
+#define R_EDI  spc.DI.I32_reg.e_reg
+#define R_EIP  spc.IP.I32_reg.e_reg
+#define R_EFLG spc.FLAGS
+
+/* segment registers */
+#define R_CS  seg.CS
+#define R_DS  seg.DS
+#define R_SS  seg.SS
+#define R_ES  seg.ES
+#define R_FS  seg.FS
+#define R_GS  seg.GS
+
+/* flag conditions   */
+#define FB_CF 0x0001            /* CARRY flag  */
+#define FB_PF 0x0004            /* PARITY flag */
+#define FB_AF 0x0010            /* AUX  flag   */
+#define FB_ZF 0x0040            /* ZERO flag   */
+#define FB_SF 0x0080            /* SIGN flag   */
+#define FB_TF 0x0100            /* TRAP flag   */
+#define FB_IF 0x0200            /* INTERRUPT ENABLE flag */
+#define FB_DF 0x0400            /* DIR flag    */
+#define FB_OF 0x0800            /* OVERFLOW flag */
+
+/* 80286 and above always have bit#1 set */
+#define F_ALWAYS_ON  (0x0002)   /* flag bits always on */
+
+/*
+ * Define a mask for only those flag bits we will ever pass back
+ * (via PUSHF)
+ */
+#define F_MSK (FB_CF|FB_PF|FB_AF|FB_ZF|FB_SF|FB_TF|FB_IF|FB_DF|FB_OF)
+
+/* following bits masked in to a 16bit quantity */
+
+#define F_CF 0x0001             /* CARRY flag  */
+#define F_PF 0x0004             /* PARITY flag */
+#define F_AF 0x0010             /* AUX  flag   */
+#define F_ZF 0x0040             /* ZERO flag   */
+#define F_SF 0x0080             /* SIGN flag   */
+#define F_TF 0x0100             /* TRAP flag   */
+#define F_IF 0x0200             /* INTERRUPT ENABLE flag */
+#define F_DF 0x0400             /* DIR flag    */
+#define F_OF 0x0800             /* OVERFLOW flag */
+
+#define TOGGLE_FLAG(flag)     	(M.x86.R_FLG ^= (flag))
+#define SET_FLAG(flag)        	(M.x86.R_FLG |= (flag))
+#define CLEAR_FLAG(flag)      	(M.x86.R_FLG &= ~(flag))
+#define ACCESS_FLAG(flag)     	(M.x86.R_FLG & (flag))
+#define CLEARALL_FLAG(m)    	(M.x86.R_FLG = 0)
+
+#define CONDITIONAL_SET_FLAG(COND,FLAG) \
+  if (COND) SET_FLAG(FLAG); else CLEAR_FLAG(FLAG)
+
+#define F_PF_CALC 0x010000      /* PARITY flag has been calced    */
+#define F_ZF_CALC 0x020000      /* ZERO flag has been calced      */
+#define F_SF_CALC 0x040000      /* SIGN flag has been calced      */
+
+#define F_ALL_CALC      0xff0000        /* All have been calced   */
+
+/*
+ * Emulator machine state.
+ * Segment usage control.
+ */
+#define SYSMODE_SEG_DS_SS       0x00000001
+#define SYSMODE_SEGOVR_CS       0x00000002
+#define SYSMODE_SEGOVR_DS       0x00000004
+#define SYSMODE_SEGOVR_ES       0x00000008
+#define SYSMODE_SEGOVR_FS       0x00000010
+#define SYSMODE_SEGOVR_GS       0x00000020
+#define SYSMODE_SEGOVR_SS       0x00000040
+#define SYSMODE_PREFIX_REPE     0x00000080
+#define SYSMODE_PREFIX_REPNE    0x00000100
+#define SYSMODE_PREFIX_DATA     0x00000200
+#define SYSMODE_PREFIX_ADDR     0x00000400
+#define SYSMODE_INTR_PENDING    0x10000000
+#define SYSMODE_EXTRN_INTR      0x20000000
+#define SYSMODE_HALTED          0x40000000
+
+#define SYSMODE_SEGMASK (SYSMODE_SEG_DS_SS      | \
+						 SYSMODE_SEGOVR_CS      | \
+						 SYSMODE_SEGOVR_DS      | \
+						 SYSMODE_SEGOVR_ES      | \
+						 SYSMODE_SEGOVR_FS      | \
+						 SYSMODE_SEGOVR_GS      | \
+						 SYSMODE_SEGOVR_SS)
+#define SYSMODE_CLRMASK (SYSMODE_SEG_DS_SS      | \
+						 SYSMODE_SEGOVR_CS      | \
+						 SYSMODE_SEGOVR_DS      | \
+						 SYSMODE_SEGOVR_ES      | \
+						 SYSMODE_SEGOVR_FS      | \
+						 SYSMODE_SEGOVR_GS      | \
+						 SYSMODE_SEGOVR_SS      | \
+						 SYSMODE_PREFIX_DATA    | \
+						 SYSMODE_PREFIX_ADDR)
+
+#define  INTR_SYNCH           0x1
+#define  INTR_ASYNCH          0x2
+#define  INTR_HALTED          0x4
+
+typedef struct {
+    struct i386_general_regs gen;
+    struct i386_special_regs spc;
+    struct i386_segment_regs seg;
+    /*
+     * MODE contains information on:
+     *  REPE prefix             2 bits  repe,repne
+     *  SEGMENT overrides       5 bits  normal,DS,SS,CS,ES
+     *  Delayed flag set        3 bits  (zero, signed, parity)
+     *  reserved                6 bits
+     *  interrupt #             8 bits  instruction raised interrupt
+     *  BIOS video segregs      4 bits
+     *  Interrupt Pending       1 bits
+     *  Extern interrupt        1 bits
+     *  Halted                  1 bits
+     */
+    u32 mode;
+    volatile int intr;          /* mask of pending interrupts */
+    int debug;
+#ifdef DEBUG
+    int check;
+    u16 saved_ip;
+    u16 saved_cs;
+    int enc_pos;
+    int enc_str_pos;
+    char decode_buf[32];        /* encoded byte stream  */
+    char decoded_buf[256];      /* disassembled strings */
+#endif
+    u8 intno;
+    u8 __pad[3];
+} X86EMU_regs;
+
+/****************************************************************************
+REMARKS:
+Structure maintaining the emulator machine state.
+
+MEMBERS:
+mem_base		- Base real mode memory for the emulator
+mem_size		- Size of the real mode memory block for the emulator
+private			- private data pointer
+x86			- X86 registers
+****************************************************************************/
+typedef struct {
+    unsigned long mem_base;
+    unsigned long mem_size;
+    void *private;
+    X86EMU_regs x86;
+} X86EMU_sysEnv;
+
+#ifdef END_PACK
+#pragma END_PACK
+#endif
+
+/*----------------------------- Global Variables --------------------------*/
+
+#ifdef  __cplusplus
+extern "C" {                    /* Use "C" linkage when in C++ mode */
+#endif
+
+/* Global emulator machine state.
+ *
+ * We keep it global to avoid pointer dereferences in the code for speed.
+ */
+
+    extern X86EMU_sysEnv _X86EMU_env;
+#define   M             _X86EMU_env
+
+/*-------------------------- Function Prototypes --------------------------*/
+
+/* Function to log information at runtime */
+
+    void printk(const char *fmt, ...);
+
+#ifdef  __cplusplus
+}                               /* End of "C" linkage for C++           */
+#endif
+#endif                          /* __X86EMU_REGS_H */
diff --git a/plat/pc65oo2/emu/x86emu/x86emu/types.h b/plat/pc65oo2/emu/x86emu/x86emu/types.h
new file mode 100644
index 000000000..0559bc089
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/x86emu/types.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+*
+*						Realmode X86 Emulator Library
+*
+*            	Copyright (C) 1996-1999 SciTech Software, Inc.
+* 				     Copyright (C) David Mosberger-Tang
+* 					   Copyright (C) 1999 Egbert Eich
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:		ANSI C
+* Environment:	Any
+* Developer:    Kendall Bennett
+*
+* Description:  Header file for x86 emulator type definitions.
+*
+****************************************************************************/
+
+#ifndef __X86EMU_TYPES_H
+#define __X86EMU_TYPES_H
+
+#ifndef NO_SYS_HEADERS
+#include <sys/types.h>
+#endif
+
+/*
+ * The following kludge is an attempt to work around typedef conflicts with
+ * <sys/types.h>.
+ */
+#define u8   x86emuu8
+#define u16  x86emuu16
+#define u32  x86emuu32
+#define u64  x86emuu64
+#define s8   x86emus8
+#define s16  x86emus16
+#define s32  x86emus32
+#define s64  x86emus64
+#define uint x86emuuint
+#define sint x86emusint
+
+/*---------------------- Macros and type definitions ----------------------*/
+
+#include <stdint.h>
+#include <inttypes.h>
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+typedef int8_t s8;
+typedef int16_t s16;
+typedef int32_t s32;
+typedef int64_t s64;
+
+typedef unsigned int uint;
+typedef int sint;
+
+typedef u16 X86EMU_pioAddr;
+
+#endif                          /* __X86EMU_TYPES_H */
diff --git a/plat/pc65oo2/emu/x86emu/x86emu/x86emui.h b/plat/pc65oo2/emu/x86emu/x86emu/x86emui.h
new file mode 100644
index 000000000..01bd92a6f
--- /dev/null
+++ b/plat/pc65oo2/emu/x86emu/x86emu/x86emui.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+*
+*						Realmode X86 Emulator Library
+*
+*            	Copyright (C) 1996-1999 SciTech Software, Inc.
+* 				     Copyright (C) David Mosberger-Tang
+* 					   Copyright (C) 1999 Egbert Eich
+*
+*  ========================================================================
+*
+*  Permission to use, copy, modify, distribute, and sell this software and
+*  its documentation for any purpose is hereby granted without fee,
+*  provided that the above copyright notice appear in all copies and that
+*  both that copyright notice and this permission notice appear in
+*  supporting documentation, and that the name of the authors not be used
+*  in advertising or publicity pertaining to distribution of the software
+*  without specific, written prior permission.  The authors makes no
+*  representations about the suitability of this software for any purpose.
+*  It is provided "as is" without express or implied warranty.
+*
+*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+*  PERFORMANCE OF THIS SOFTWARE.
+*
+*  ========================================================================
+*
+* Language:		ANSI C
+* Environment:	Any
+* Developer:    Kendall Bennett
+*
+* Description:  Header file for system specific functions. These functions
+*				are always compiled and linked in the OS depedent libraries,
+*				and never in a binary portable driver.
+*
+****************************************************************************/
+
+#ifndef __X86EMU_X86EMUI_H
+#define __X86EMU_X86EMUI_H
+
+/* If we are compiling in C++ mode, we can compile some functions as
+ * inline to increase performance (however the code size increases quite
+ * dramatically in this case).
+ */
+
+#if defined(__cplusplus)
+#define	_INLINE	inline
+#else
+#define	_INLINE static
+#endif
+
+/* Get rid of unused parameters in C++ compilation mode */
+
+#ifdef __cplusplus
+#define	X86EMU_UNUSED(v)
+#else
+#define	X86EMU_UNUSED(v)	v
+#endif
+
+#include "x86emu.h"
+#include "x86emu/regs.h"
+#include "x86emu/debug.h"
+#include "x86emu/decode.h"
+#include "x86emu/ops.h"
+#include "x86emu/prim_ops.h"
+#include "x86emu/fpu.h"
+#include "x86emu/fpu_regs.h"
+
+#ifndef NO_SYS_HEADERS
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+/* avoid conflicts with Solaris sys/regset.h */
+# if defined(__sun) && defined(CS)
+#  undef CS
+#  undef DS
+#  undef SS
+#  undef ES
+#  undef FS
+#  undef GS
+# endif
+#endif /* NO_SYS_HEADERS */
+
+/*--------------------------- Inline Functions ----------------------------*/
+
+#ifdef  __cplusplus
+extern "C" {                    /* Use "C" linkage when in C++ mode */
+#endif
+
+    extern u8(X86APIP sys_rdb) (u32 addr);
+    extern u16(X86APIP sys_rdw) (u32 addr);
+    extern u32(X86APIP sys_rdl) (u32 addr);
+    extern void (X86APIP sys_wrb) (u32 addr, u8 val);
+    extern void (X86APIP sys_wrw) (u32 addr, u16 val);
+    extern void (X86APIP sys_wrl) (u32 addr, u32 val);
+
+    extern u8(X86APIP sys_inb) (X86EMU_pioAddr addr);
+    extern u16(X86APIP sys_inw) (X86EMU_pioAddr addr);
+    extern u32(X86APIP sys_inl) (X86EMU_pioAddr addr);
+    extern void (X86APIP sys_outb) (X86EMU_pioAddr addr, u8 val);
+    extern void (X86APIP sys_outw) (X86EMU_pioAddr addr, u16 val);
+    extern void (X86APIP sys_outl) (X86EMU_pioAddr addr, u32 val);
+
+#ifdef  __cplusplus
+}                               /* End of "C" linkage for C++           */
+#endif
+#endif                          /* __X86EMU_X86EMUI_H */
diff --git a/plat/pc65oo2/include/ack/plat.h b/plat/pc65oo2/include/ack/plat.h
new file mode 100644
index 000000000..e8c2251a0
--- /dev/null
+++ b/plat/pc65oo2/include/ack/plat.h
@@ -0,0 +1,11 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#ifndef _ACK_PLAT_H
+#define _ACK_PLAT_H
+
+#define ACKCONF_WANT_EMULATED_TIME 0
+
+#endif
diff --git a/plat/pc65oo2/include/build.lua b/plat/pc65oo2/include/build.lua
new file mode 100644
index 000000000..390576c5a
--- /dev/null
+++ b/plat/pc65oo2/include/build.lua
@@ -0,0 +1,24 @@
+include("plat/build.lua")
+
+headermap = {}
+packagemap = {}
+
+local function addheader(h)
+	headermap[h] = "./"..h
+	packagemap["$(PLATIND)/pc65oo2/include/"..h] = "./"..h
+end
+
+addheader("ack/plat.h")
+addheader("sys/types.h")
+
+acklibrary {
+	name = "headers",
+	hdrs = headermap
+}
+
+installable {
+	name = "pkg",
+	map = packagemap
+}
+
+
diff --git a/plat/pc65oo2/include/sys/types.h b/plat/pc65oo2/include/sys/types.h
new file mode 100644
index 000000000..6a0c3d3db
--- /dev/null
+++ b/plat/pc65oo2/include/sys/types.h
@@ -0,0 +1,9 @@
+#ifndef _SYS_TYPES_H
+#define _SYS_TYPES_H
+
+typedef int pid_t;
+typedef int mode_t;
+typedef long time_t;
+typedef long suseconds_t;
+
+#endif
diff --git a/plat/pc65oo2/libsys/_hol0.s b/plat/pc65oo2/libsys/_hol0.s
new file mode 100644
index 000000000..f01566fe8
--- /dev/null
+++ b/plat/pc65oo2/libsys/_hol0.s
@@ -0,0 +1,19 @@
+#
+! $Source$
+! $State$
+! $Revision$
+
+! Declare segments (the order is important).
+
+.sect .text
+.sect .rom
+.sect .data
+.sect .bss
+
+.sect .bss
+
+! This data block is used to store information about the current line number
+! and file.
+
+.define hol0
+.comm hol0, 8
diff --git a/plat/pc65oo2/libsys/_sys_rawread.s b/plat/pc65oo2/libsys/_sys_rawread.s
new file mode 100644
index 000000000..480727b55
--- /dev/null
+++ b/plat/pc65oo2/libsys/_sys_rawread.s
@@ -0,0 +1,23 @@
+#
+! $Source$
+! $State$
+! $Revision$
+
+! Declare segments (the order is important).
+
+.sect .text
+.sect .rom
+.sect .data
+.sect .bss
+
+.sect .text
+
+! Reads a single byte.
+
+.define __sys_rawread
+__sys_rawread:
+	xorb ah, ah
+	int 0x16
+	xorb ah, ah
+	ret
+	
\ No newline at end of file
diff --git a/plat/pc65oo2/libsys/_sys_rawwrite.s b/plat/pc65oo2/libsys/_sys_rawwrite.s
new file mode 100644
index 000000000..ae477c6d2
--- /dev/null
+++ b/plat/pc65oo2/libsys/_sys_rawwrite.s
@@ -0,0 +1,38 @@
+#
+! $Source$
+! $State$
+! $Revision$
+
+! Declare segments (the order is important).
+
+.sect .text
+.sect .rom
+.sect .data
+.sect .bss
+
+.sect .text
+
+! Writes a single byte to the console.
+
+.define __sys_rawwrite
+.extern __sys_rawwrite
+
+__sys_rawwrite:
+	push bp
+	mov bp, sp
+
+	! Write to the BIOS console.
+
+	movb al, 4(bp)
+	movb ah, 0x0E
+	mov bx, 0x0007
+	int 0x10
+
+	! Also write to the serial port (used by the test suite).
+
+	movb ah, 0x01
+	xor dx, dx
+	int 0x14
+
+	jmp .cret
+	
\ No newline at end of file
diff --git a/plat/pc65oo2/libsys/brk.c b/plat/pc65oo2/libsys/brk.c
new file mode 100644
index 000000000..293703234
--- /dev/null
+++ b/plat/pc65oo2/libsys/brk.c
@@ -0,0 +1,59 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+#define	OUT_OF_MEMORY (void*)(-1)	/* sbrk returns this on failure */
+#define STACK_BUFFER 128 /* number of bytes to leave for stack */
+
+extern char _end[1];
+static char* current = _end;
+
+int brk(void* newend)
+{
+	/* This variable is used to figure out the current stack pointer,
+	 * by taking its address. */
+	char dummy;
+	char* p = newend;
+	
+	if ((p > (&dummy - STACK_BUFFER)) ||
+	    (p < _end))	
+	{
+		errno = ENOMEM;
+		return -1;
+	}
+		
+	current = p;
+	return 0;
+}
+
+void* sbrk(int increment)
+{
+	char* old;
+	char* new;
+
+	if (increment == 0)
+		return current;
+		
+	old = current;
+
+	new = old + increment;
+
+	if ((increment > 0) && (new <= old))
+		goto out_of_memory;
+	else if ((increment < 0) && (new >= old))
+		goto out_of_memory;
+
+	if (brk(new) < 0)
+		goto out_of_memory;
+		
+	return old;
+
+out_of_memory:
+	errno = ENOMEM;
+	return OUT_OF_MEMORY;
+}
diff --git a/plat/pc65oo2/libsys/build.lua b/plat/pc65oo2/libsys/build.lua
new file mode 100644
index 000000000..3071f793a
--- /dev/null
+++ b/plat/pc65oo2/libsys/build.lua
@@ -0,0 +1,29 @@
+acklibrary {
+    name = "lib",
+    srcs = {
+		"./brk.c",
+		"./close.c",
+		"./creat.c",
+		"./errno.s",
+		"./getpid.c",
+		"./_hol0.s",
+		"./isatty.c",
+		"./kill.c",
+		"./lseek.c",
+		"./open.c",
+		"./read.c",
+		"./signal.c",
+		"./_sys_rawread.s",
+		"./_sys_rawwrite.s",
+		"./time.c",
+		"./write.c",
+    },
+	deps = {
+		"lang/cem/libcc.ansi/headers+headers",
+		"plat/pc65oo2/include+headers",
+	},
+    vars = {
+        plat = "pc65oo2"
+    }
+}
+
diff --git a/plat/pc65oo2/libsys/close.c b/plat/pc65oo2/libsys/close.c
new file mode 100644
index 000000000..1c570029b
--- /dev/null
+++ b/plat/pc65oo2/libsys/close.c
@@ -0,0 +1,14 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+int close(int fd)
+{
+	errno = EBADF;
+	return -1;
+}
diff --git a/plat/pc65oo2/libsys/creat.c b/plat/pc65oo2/libsys/creat.c
new file mode 100644
index 000000000..34ace747c
--- /dev/null
+++ b/plat/pc65oo2/libsys/creat.c
@@ -0,0 +1,15 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include "libsys.h"
+
+int open(const char* path, int access, ...)
+{
+	errno = EACCES;
+	return -1;
+}
diff --git a/plat/pc65oo2/libsys/errno.s b/plat/pc65oo2/libsys/errno.s
new file mode 100644
index 000000000..9858d2640
--- /dev/null
+++ b/plat/pc65oo2/libsys/errno.s
@@ -0,0 +1,28 @@
+#
+! $Source$
+! $State$
+! $Revision$
+
+! Declare segments (the order is important).
+
+.sect .text
+.sect .rom
+.sect .data
+.sect .bss
+
+#define D(e) .define e; e
+
+.sect .data
+
+! Define various ACK error numbers. Note that these are *not* ANSI C
+! errnos, and are used for different purposes.
+
+D(ERANGE)         = 1
+D(ESET)           = 2
+D(EIDIVZ)         = 6
+D(EHEAP)          = 17
+D(EILLINS)        = 18
+D(EODDZ)          = 19
+D(ECASE)          = 20
+D(EBADMON)        = 25
+
diff --git a/plat/pc65oo2/libsys/getpid.c b/plat/pc65oo2/libsys/getpid.c
new file mode 100644
index 000000000..5e6eb003e
--- /dev/null
+++ b/plat/pc65oo2/libsys/getpid.c
@@ -0,0 +1,13 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+pid_t getpid(void)
+{
+	return 0;
+}
diff --git a/plat/pc65oo2/libsys/isatty.c b/plat/pc65oo2/libsys/isatty.c
new file mode 100644
index 000000000..ad01e343f
--- /dev/null
+++ b/plat/pc65oo2/libsys/isatty.c
@@ -0,0 +1,13 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+int isatty(int fd)
+{
+	return 1;
+}
diff --git a/plat/pc65oo2/libsys/kill.c b/plat/pc65oo2/libsys/kill.c
new file mode 100644
index 000000000..4a179c47c
--- /dev/null
+++ b/plat/pc65oo2/libsys/kill.c
@@ -0,0 +1,14 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+int kill(pid_t pid, int sig)
+{
+	errno = EINVAL;
+	return -1;
+}
diff --git a/plat/pc65oo2/libsys/libsys.h b/plat/pc65oo2/libsys/libsys.h
new file mode 100644
index 000000000..fee2fc76d
--- /dev/null
+++ b/plat/pc65oo2/libsys/libsys.h
@@ -0,0 +1,16 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#ifndef LIBSYS_H
+#define LIBSYS_H
+
+extern void _sys_rawwrite(unsigned char b);
+extern unsigned char _sys_rawread(void);
+
+extern void _sys_write_tty(char c);
+
+/* extern int _sys_ttyflags; */
+
+#endif
diff --git a/plat/pc65oo2/libsys/lseek.c b/plat/pc65oo2/libsys/lseek.c
new file mode 100644
index 000000000..ecbc4b520
--- /dev/null
+++ b/plat/pc65oo2/libsys/lseek.c
@@ -0,0 +1,14 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+off_t lseek(int fd, off_t offset, int whence)
+{
+	errno = EINVAL;
+	return -1;
+}
diff --git a/plat/pc65oo2/libsys/open.c b/plat/pc65oo2/libsys/open.c
new file mode 100644
index 000000000..8f18317c5
--- /dev/null
+++ b/plat/pc65oo2/libsys/open.c
@@ -0,0 +1,14 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include "libsys.h"
+
+int creat(const char* path, int mode)
+{
+	return open(path, O_CREAT|O_WRONLY|O_TRUNC, mode);
+}
diff --git a/plat/pc65oo2/libsys/read.c b/plat/pc65oo2/libsys/read.c
new file mode 100644
index 000000000..c888660a4
--- /dev/null
+++ b/plat/pc65oo2/libsys/read.c
@@ -0,0 +1,43 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include "libsys.h"
+
+ssize_t read(int fd, void* buffer, size_t count)
+{
+	char i;
+	
+	/* We're only allowed to read from fd 0, 1 or 2. */
+	
+	if ((fd < 0) || (fd > 2))
+	{
+		errno = EBADF;
+		return -1;
+	}
+	
+	/* Empty buffer? */
+	
+	if (count == 0)
+		return 0;
+	
+	/* Read one byte. */
+	
+	i = _sys_rawread();
+#if 0
+	if ((i == '\r') && !(_sys_ttyflags & RAW)) 
+		i = '\n';
+	if (_sys_ttyflags & ECHO)
+		_sys_write_tty(i);
+#endif
+	if (i == '\r') 
+		i = '\n';
+	_sys_write_tty(i);
+	
+	*(char*)buffer = i;
+	return 1;
+}
diff --git a/plat/pc65oo2/libsys/signal.c b/plat/pc65oo2/libsys/signal.c
new file mode 100644
index 000000000..a87b9ced2
--- /dev/null
+++ b/plat/pc65oo2/libsys/signal.c
@@ -0,0 +1,15 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include "libsys.h"
+
+sighandler_t signal(int signum, sighandler_t handler)
+{
+	return SIG_DFL;
+}
diff --git a/plat/pc65oo2/libsys/time.c b/plat/pc65oo2/libsys/time.c
new file mode 100644
index 000000000..5ef17b841
--- /dev/null
+++ b/plat/pc65oo2/libsys/time.c
@@ -0,0 +1,17 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#include "libsys.h"
+
+time_t time(time_t* t)
+{
+	if (t)
+		*t = 0;
+	return 0;
+}
diff --git a/plat/pc65oo2/libsys/write.c b/plat/pc65oo2/libsys/write.c
new file mode 100644
index 000000000..064e5f487
--- /dev/null
+++ b/plat/pc65oo2/libsys/write.c
@@ -0,0 +1,48 @@
+/* $Source$
+ * $State$
+ * $Revision$
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include "libsys.h"
+
+void _sys_write_tty(char c)
+{
+	_sys_rawwrite(c);
+#if 0
+	if ((c == '\n') && !(_sys_ttyflags & RAW))
+		_sys_rawwrite('\r');
+#endif
+	if (c == '\n')
+		_sys_rawwrite('\r');
+}
+
+ssize_t write(int fd, void* buffer, size_t count)
+{
+	int i;
+	char* p = buffer;
+	
+	/* We're only allowed to write to fd 0, 1 or 2. */
+	
+	if ((fd < 0) || (fd > 2))
+	{
+		errno = EBADF;
+		return -1;
+	}
+	
+	/* Write all data. */
+	
+	i = 0;
+	while (i < count)
+	{
+		_sys_write_tty(*p++);
+			
+		i++;
+	}
+	
+	/* No failures. */
+	
+	return count;
+}
diff --git a/plat/pc65oo2/tests/build.lua b/plat/pc65oo2/tests/build.lua
new file mode 100644
index 000000000..1e6aa3a7a
--- /dev/null
+++ b/plat/pc65oo2/tests/build.lua
@@ -0,0 +1,11 @@
+include("tests/plat/build.lua")
+
+plat_testsuite {
+    name = "tests",
+    plat = "pc65oo2",
+    method = "plat/pc65oo2/emu+pc86emu",
+    skipsets = {
+        "floats", -- FPU instructions not supported by emulator
+        "long-long",
+    },
+}
diff --git a/util/ego/descr/build.lua b/util/ego/descr/build.lua
index e9a008cc5..56aae82f6 100644
--- a/util/ego/descr/build.lua
+++ b/util/ego/descr/build.lua
@@ -23,6 +23,7 @@ build_descr("i386")
 build_descr("i86")
 build_descr("m68020")
 build_descr("powerpc")
+build_descr("m65oo2")
 
 installable {
 	name = "pkg",
diff --git a/util/ego/descr/m65oo2.descr b/util/ego/descr/m65oo2.descr
new file mode 100644
index 000000000..d5a2014bf
--- /dev/null
+++ b/util/ego/descr/m65oo2.descr
@@ -0,0 +1,101 @@
+wordsize: 4
+pointersize: 4
+%%RA
+general registers: 2
+address registers: 0
+floating point registers: 0
+use general as pointer: yes
+
+register score parameters:
+        local variable:
+                (2 cases)
+                pointer,general
+                        (1 size)
+                        default ->      (8,4)
+                general,general
+                        (1 size)
+                        default ->      (4,2)
+        address of local variable:
+                (2 cases)
+                pointer,general
+                        (1 size)
+                        default ->      (0,0)
+                general,general
+                        (1 size)
+                        default ->      (2,2)
+        constant:
+                (1 sizes)
+                default ->      (2,2)
+        double constant:
+                (1 size)
+                default ->      (-1,-1)
+        address of global variable:
+                (1 size)
+                default ->      (4,2)
+        address of procedure:
+                (1 size)
+                default ->      (2,2)
+
+opening cost parameters:
+        local variable:
+                (2 cases)
+                pointer
+                        (1 size)
+                        default ->      (9,4)
+                general
+                        (1 size)
+                        default ->      (9,4)
+        address of local variable:
+                (2 cases)
+                pointer
+                        (1 size)
+                        default ->      (10,6)
+                general
+                        (1 size)
+                        general ->      (10,6)
+        constant:
+                (1 size)
+                default ->      (4,4)
+        double constant:
+                (1 size)
+                default ->      (1000,1000)
+        address of global variable:
+                (1 size)
+                default ->      (4,4)
+        address of procedure:
+                (1 size)
+                default ->      (4,4)
+
+register save costs:
+        (4 cases)
+        0 -> (0,0)
+        1 -> (18,2)
+        2 -> (36,4)
+        0 -> (0,0)
+
+%%UD
+access costs of global variables:
+	(1 size)
+	default ->	(4,2)
+access costs of local variables:
+	(1 size)
+	default ->	(4,2)
+%%SR
+overflow harmful?:  no
+array bound harmful?:  no
+reduce sli if shift count larger than:  0
+%%CS
+#include "em_mnem.h"
+first time then space:
+addressing modes: op_adp op_lof op_ldf op_loi op_dch op_lpb -1
+                  op_adp op_lof op_ldf op_loi op_dch op_lpb -1
+cheap operations: op_cii op_cui op_ciu op_cuu -1
+                  op_cii op_cui op_ciu op_cuu -1
+lexical tresholds: 1 1
+indirection limit: 8
+convert remainder to division?: no no
+do not eliminate sli if index on shiftcounts:   -1
+                                                -1
+forbidden operators: -1 -1
+%%SP
+global stack pollution allowed?: no