diff -urN dosemu-0.60.4.2-clean/Makefile dosemu/Makefile
--- dosemu-0.60.4.2-clean/Makefile	Wed Sep 13 02:06:52 1995
+++ dosemu/Makefile	Sat Sep 16 18:40:38 1995
@@ -18,7 +18,7 @@
 # NOTE: Do NOT start dosemu (compiled with REQUIRES_EMUMODULE),
 #       if you have not loaded emumodule.o !
 #
-# REQUIRES_EMUMODULE= -DREQUIRES_EMUMODULE
+REQUIRES_EMUMODULE= -DREQUIRES_EMUMODULE
 
 ifdef REQUIRES_EMUMODULE
   export REQUIRES_EMUMODULE
@@ -31,6 +31,13 @@
     ifdef USE_VM86_STACKVERIFY
       export USE_VM86_STACKVERIFY
     endif
+# uncomment this, if you want the dosdebugger (mhpdbg)
+    USE_MHPDBG= -DUSE_MHPDBG
+    ifdef USE_MHPDBG
+      DEBUGGER= debugger
+      export DEBUGGER
+      export USE_MHPDBG
+    endif
   endif
 endif
 
@@ -193,7 +200,7 @@
 endif
 
 LIBSUBDIRS=video dosemu pic dpmi mfs init serial keyboard mouse dma sound \
-	$(NET) $(IPX) drivers
+	$(DEBUGGER) $(NET) $(IPX) drivers
 
 SUBDIRS= include boot \
 	$(CLIENTSSUB) kernel
@@ -262,6 +269,9 @@
 CFLAGS+=$(X86_EMULATOR_FLAGS)
 ifdef REQUIRES_EMUMODULE
    CFLAGS+=$(REQUIRES_EMUMODULE) $(USE_VM86PLUS) $(USE_VM86_STACKVERIFY)
+   ifdef USE_MHPDBG
+      CFLAGS+=$(USE_MHPDBG)
+   endif
 endif
 
 # set for DPMI want windows
@@ -520,6 +530,9 @@
 		(cd $$i && echo $$i && $(MAKE) install) || exit; \
 	done
 	@install -c -o root -m 04755 dos /usr/bin
+ifdef  USE_MHPDBG
+	@install -c -o root -m 0755 dosdebug /usr/bin
+endif
 ifndef ELF
 	@install -m 0644 $(LIBDOSEMU) /usr/lib
 	@(cd /usr/lib; ln -sf $(LIBDOSEMU) libdosemu)
diff -urN dosemu-0.60.4.2-clean/data.c dosemu/data.c
--- dosemu-0.60.4.2-clean/data.c	Sun Apr  9 00:29:37 1995
+++ dosemu/data.c	Sat Sep 16 18:34:40 1995
@@ -21,3 +21,4 @@
 #include "shared.h"
 #include "pic.h"
 #include "disks.h"
+#include "mhpdbg.h"
diff -urN dosemu-0.60.4.2-clean/debugger/Makefile dosemu/debugger/Makefile
--- dosemu-0.60.4.2-clean/debugger/Makefile	Thu Jan  1 01:00:00 1970
+++ dosemu/debugger/Makefile	Sat Sep 16 18:34:40 1995
@@ -0,0 +1,26 @@
+# This is the Makefile for the debugger-subdirectory of DOSEMU.
+# Please send comments and bug-reports to Max Parke <mhp@light.lightlink.com>
+# Please read the code in this directory for more information.
+
+SUBDIR=debugger
+
+#The C files, include files and dependancies here.
+CFILES = mhpdbg.c mhpdbgc.c dis8086.c dosdebug.c
+DEPENDS =  mhpdbg.d mhpdbgc.d dis8086.d dosdebug.d
+HFILES =
+
+# Insert all source- and header-files here.
+ALL = $(CFILES) $(HFILES) README.debugger
+
+# All object-files are included here.
+OBJS =  mhpdbg.o mhpdbgc.o dis8086.o
+
+all: lib ../dosdebug
+
+../dosdebug: dosdebug.c
+	$(CC) -O2 -I../include dosdebug.c -o ../dosdebug
+
+
+install:
+
+include ../Makefile.common
diff -urN dosemu-0.60.4.2-clean/debugger/README.dosdebug dosemu/debugger/README.dosdebug
--- dosemu-0.60.4.2-clean/debugger/README.dosdebug	Thu Jan  1 01:00:00 1970
+++ dosemu/debugger/README.dosdebug	Sat Sep 16 18:34:40 1995
@@ -0,0 +1,138 @@
+README file for DOSEMU debugger  v0.2	9/16/95
+send comments to Max Parke     <mhp@light.lightlink.com>
+       and    to Hans Lermen   <lermen@elserv.ffm.fgan.de>
+================================================================
+
+This is a second preliminary release of the DOSEMU debugger, with the
+following features:
+* interactive
+* display/disassembly/modify of registers and memory(0-1Mb)
+* breakpoints (int3-style, and breakpoint on INT xx)
+* symbolic debugging via microsoft linker .MAP file support
+* read-only access to DOSEMU kernel via memory dump and disassembly
+* uses /usr/src/dosemu/dosemu.map for above
+* access is via the 'dosdebug' client from another virtual console.
+  So, you have a "debug window" and the DOS window/keyboard, etc. are
+  undisturbed.	VM86 execution can be started, stopped, etc.
+* If dosemu 'hangs' you can use the 'kill' command from dosbugger to
+  recover.
+* code base is on DOSEMU 0.60.3
+
+================================================================
+Changes were added to these modules in the source tree:
+./emu.c
+./dosemu/sigsegv.c
+./dosemu/dosio.c
+./emumod/vm86.c
+./include/vm86plus.h
+All changes are #ifdef'ed with USE_MHPDBG
+
+New modules:
+./debugger/mhpdbg.c
+./debugger/mhpdbgc.c
+./debugger/dis8086.c
+./include/mhpdbg.h
+
+New executable:
+./dosdebug.c
+
+================================================================
+INSTALLATION:
+
+In order to use DOSEMU debugger you must also use EMUMODULE.
+In the main Makefile uncomment:
+
+  REQUIRES_EMUMODULE= -DREQUIRES_EMUMODULE
+  USE_VM86PLUS= -DUSE_VM86PLUS
+  USE_MHPDBG= -DUSE_MHPDBG
+
+and then do a 'make realclean' and recompile dosemu.
+
+  
+================================================================
+USAGE
+To run, start up DOSEMU.  Then switch to another virtual console
+(or remote login) and do:
+
+  dosdebug
+
+If there are more then one dosemu process running, you will need
+to pass the pid to dosdebug, e.g:
+
+  dosdebug 2134
+  
+NOTE: You must be the owner of the running dosemu to 'debug-login'.
+
+You should get connected and a banner message.
+If you type 'q', only the terminal client will terminate,
+if you type 'kill', both dosemu and the terminal client will be
+terminated.
+
+================================================================
+COMMANDS (see mhpdbgc.c for code and cmd table)
+
+(all numeric args in hex)
+
+?                 Print a help page
+q		  Quit the debug session
+kill              Kill the dosemu process
+r		  list regs
+e ADDR HEXSTR     modify memory (0-1Mb)
+d ADDR SIZE	  dump memory (no limit)
+u ADDR SIZE	  unassemble memory (no limit)
+g		  go (if stopped)
+stop		  stop (if running)
+mode 0|1	  set mode (0=SEG16, 1=LIN32) for u and d commands
+t		  single step (not fully debugged!!!)
+r32		  dump regs in 32 bit format
+bp addr 	  set int3 style breakpoint
+bpint xx	  set breakpoint on INT xx
+bcint xx	  clr breakpoint on INT xx
+bl		  list active breakpoints
+(rmapfile)	  (internal command to read /usr/src/dosemu/dosemu.map
+		  at startup time)
+rusermap org fn   read microsoft linker format .MAP file "fn"
+		  code origin = "org".
+		  for example if your code is at 1234:0, org would
+		  be 12340.
+Addresses may be specified as:
+1) a linear address.  Allows 'd' and 'u' commands to look at both
+   DOSEMU kernel and DOS box memory (0-1Mb).
+2) a seg:off address (0-1Mb)
+3) a symbolic address.	usermap is searched first, then dosemu map.
+4) an asterisk(*): CS:IP
+5) a dollar sign($): SS:SP
+
+================================================================
+PERFORMANCE
+
+If you have dosemu compiled with the debugger support, but the
+debugger is not active and/or the process is not stopped, you
+will not see any great performance penalty.
+
+
+================================================================
+WISH LIST
+
+Main wish is to add support for hardware debug registers (if someone
+would point me in the direction, what syscalls to use, etc.)
+Then you could breakpoint on memory reads/writes, etc!
+
+================================================================
+BUGS
+
+There must be some.
+
+Known bugs:
+
+ - Single stepping doesn't work correctly on call's. May be the
+   trap-flag is lost.
+ - popf sometime clears the trap-flag, so single stepping
+   results in a 'go' command.
+ - When stopped for a long period, the BIOS-timer will be updated to
+   fast and may result in stack overflow. We need to also stop the timer
+   for dosemu.
+ - When not stopped, setting break points doesn't work properly.
+   So, as a work aoround: Ownly set breakpoints while in stop.
+
+================================================================
diff -urN dosemu-0.60.4.2-clean/debugger/dis8086.c dosemu/debugger/dis8086.c
--- dosemu-0.60.4.2-clean/debugger/dis8086.c	Thu Jan  1 01:00:00 1970
+++ dosemu/debugger/dis8086.c	Sat Sep 16 18:34:40 1995
@@ -0,0 +1,1492 @@
+/* 80x86 disassembler for real mode and 16 bit segments.
+ * 32 bit address and data prefixes are partially supported; there
+ * may be some missing cases.
+ *
+ * Copyright 1993 by John F. Carr (jfc@athena.mit.edu)
+ *
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#ifdef __GNUC__
+#define INLINE inline
+#else
+#define INLINE
+#endif
+
+#define IBUFS 100
+#define makeaddr(x,y) ((((unsigned long)x) << 4) + (unsigned long)y)
+static unsigned char* linebuf;
+static unsigned char * nameptr;
+static unsigned int  * refaddr;
+
+static const char *conditions[16] =
+{
+  "o", "no", "b", "ae", "e", "ne", "be", "a",
+  "s", "ns", "p", "np", "le", "g", "le", "g"
+};
+
+static const char *cr[] =
+{
+  "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7"
+};
+
+static const char *dr[] =
+{
+  "dr0", "dr1", "dr2", "dr3", "dr4", "dr5", "dr6", "dr7"
+};
+
+static const char *tr[] =
+{
+  "tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7"
+};
+
+static const char *freg[8] =
+{
+  "st(0)", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)"
+};
+
+static const char *farith[8] =
+{
+  "fadd", "fmul", "fcom", "fcomp", "fsub", "fsubr", "fdiv", "fdivr"
+};
+
+static const char *d9[8] =
+{
+  "flds", "fxch", "fsts", "fstps", "ftst/fxam", "fldc", "fmisc1", "fmisc2"
+};
+
+static const char *f00[8] =
+{
+  "sldt", "str", "lldt", "ltr", "verr", "verw", "???", "???"
+};
+
+static const char *f01[8] =
+{
+  "sgdt", "sidt", "lgdt", "lidt", "smsw", "???", "lmsw", "???"
+};
+
+static const char *shift[8] =
+{
+  "rol", "ror", "rcl", "rcr", "shl", "shr", "sal", "sar"
+};
+
+static const char *f7_code[8] =
+{
+  "test", "???", "not", "neg", "mul", "imul", "div", "idiv"
+};
+
+static const char *ff_code[8] =
+{
+  "inc", "dec", "call", "call far", "jmp", "jmp far", "push", "???"
+};
+
+static const char *arith[8] =
+{
+  "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp"
+};
+
+static const char *reg8[8] =
+{
+  "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"
+};
+
+static const char *reg16[8] =
+{
+  "ax", "cx", "dx", "bx", "sp", "bp", "si", "di"
+};
+
+static const char *reg32[8] =
+{
+  "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
+};
+
+static const char *sreg[8] =
+{
+  "es", "cs", "ss", "ds", "fs", "gs", "??", "??"
+};
+
+static const char *memref[8] =
+{
+  "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
+};
+
+static const char *fop[8] =
+{
+  "0", "1", "2", "3", "4", "5", "6", "7"
+};
+
+/* bit set: instruction takes explicit float register operand */
+static unsigned char freg_op[8] =
+{
+  0xff, 0x03, 0xd3, 0x00, 0xf0, 0x35, 0xf0, 0x00
+};
+
+#if defined(i386) || defined(vax)
+/* Little-endian machines which allow unaligned addresses.  */
+#define IMMED16(code) *(unsigned short *)(code)
+#define IMMED32(code) *(unsigned int *)(code)
+#define IMMED32I(code) *(int *)(code)
+#else
+/* Big-endian or strict alignment.  */
+#define IMMED16(code) code[0] | (code[1] << 8)
+#define IMMED32(code) code[0] | (code[1] << 8) | (code[2] << 16) | (code[3] << 24)
+#define IMMED32I(code) code[0] | (code[1] << 8) | (code[2] << 16) | (code[3] << 24)
+#endif
+
+#undef index
+
+static unsigned char * putaddr(unsigned int i1)
+{
+   *refaddr = i1;
+   return (unsigned char *) 0;
+}
+
+static void d86_printf(const char *fmt,...)
+{
+  va_list args;
+  char frmtbuf[100];
+
+  va_start(args, fmt);
+  vsprintf(frmtbuf, fmt, args);
+  va_end(args);
+
+  strcat (linebuf, frmtbuf);
+}
+
+static INLINE unsigned short immed16 (register const unsigned char * code)
+{
+   nameptr = putaddr(IMMED16(code));
+   return(IMMED16(code));
+}
+
+static INLINE unsigned int   immed32 (register const unsigned char * code)
+{
+   nameptr = putaddr(IMMED32(code));
+   return(IMMED32(code));
+}
+
+static INLINE	       int   immed32i (register const unsigned char * code)
+{
+   nameptr = putaddr(IMMED32(code));
+   return(IMMED32I(code));
+}
+
+static INLINE unsigned int   resolva (unsigned int addr)
+{
+   nameptr = putaddr(addr);
+   return(addr);
+}
+
+static INLINE const unsigned char *mod_rm(FILE *out, const unsigned char *code,
+					  const char *seg, const char **regs,
+					  int addr32)
+{
+  unsigned char rm = *code++;
+
+  if (addr32)
+    {
+      char index[5];
+      const char *scale;
+      const char *base;
+
+      if ((rm >> 6) == 3)
+	{
+	  d86_printf(regs[rm & 7]);
+	  return code;
+	}
+      if ((rm & 7) == 4)
+	{
+	  unsigned char sib = *code++;
+
+	  base = reg32[sib & 7];
+
+	  if (((sib >> 3) & 7) == 4)
+	    {
+	      index[0] = 0;
+	      scale = "";
+	    }
+	  else
+	    {
+	      index[0] = '+';
+	      index[1] = reg32[(sib >> 3) & 7][0];
+	      index[2] = reg32[(sib >> 3) & 7][1];
+	      index[3] = reg32[(sib >> 3) & 7][2];
+	      index[4] = 0;
+
+	      switch(sib >> 6)
+		{
+		case 0:
+		  scale = "";
+		  break;
+		case 1:
+		  scale = "*2";
+		  break;
+		case 2:
+		  scale = "*4";
+		  break;
+		case 3:
+		  scale = "*8";
+		  break;
+		}
+	    }
+	}
+      else
+	{
+	  base = reg32[rm & 7];
+	  index[0] = 0;
+	  scale = "";
+	}
+
+      switch(rm >> 6)
+	{
+	case 2:
+	  d86_printf("%s[%s%s%s%+d]", seg, reg32[rm & 7],
+		  index, scale, immed32(code));
+	  return code + 4;
+
+	case 1:
+	  d86_printf("%s[%s%s%s%+d]", seg, reg32[rm & 7], index, scale,
+		  (signed char)code[0]);
+	  return code + 1;
+
+	case 0:
+	  if ((rm & 7) == 5)
+	    {
+	      d86_printf("%s[%08x%s%s]", seg, immed32(code),
+		      index, scale);
+	      return code + 4;
+	    }
+	  d86_printf("%s[%s%s%s]", seg, reg32[rm & 7], index, scale);
+	  return code;
+	}
+    }
+  else
+    {
+      switch(rm >> 6)
+	{
+	case 3:
+	  d86_printf(regs[rm & 7]);
+	  return code;
+
+	case 2:
+	  d86_printf("%s[%s%+d]", seg, memref[rm & 7], (short)immed16(code));
+	  return code + 2;
+
+	case 1:
+	  d86_printf("%s[%s%+d]", seg, memref[rm & 7], (signed char)code[0]);
+	  return code + 1;
+
+	case 0:
+	  if ((rm & 7) == 6)
+	    {
+	      d86_printf("%s[%04x]", seg, code[0] + (code[1] << 8));
+	      return code + 2;
+	    }
+	  d86_printf("%s[%s]", seg, memref[rm & 7]);
+	  return code;
+	}
+    }
+}
+
+static const unsigned char *mod_reg_rm(FILE *out, const unsigned char *code,
+				   const char *seg, const char **sregs,
+				   const char **regs, int addr32)
+{
+  d86_printf(sregs[(*code >> 3) & 7]);
+  d86_printf(",");
+  return mod_rm(out, code, seg, regs, addr32);
+}
+
+static const unsigned char *mod_reg_rm_r(FILE *out, const unsigned char *code,
+				     const char *seg, const char **sregs,
+				     const char **regs, int addr32)
+{
+  unsigned char rm = *code;
+
+  code = mod_rm(out, code, seg, regs, addr32);
+  d86_printf(",");
+  d86_printf(sregs[(rm >> 3) & 7]);
+  return code;
+}
+
+int  dis_8086(unsigned int org,
+	      register const unsigned char *code,
+	      unsigned char *outbuf,
+	      int def_size,
+	      unsigned int * refseg,
+	      unsigned int * refoff)
+{
+  const unsigned char *code0 = code;
+  FILE *out = 0;
+  const char *seg = "";
+  int data32 = def_size;
+  int addr32 = def_size;
+  int prefix = 0;
+  int i;
+
+  linebuf = outbuf;
+  memset(linebuf, 0x00, IBUFS);
+
+  refaddr = refoff;
+  *refaddr = 0;
+
+  for(i=0;i<16;i++)
+    {
+      unsigned char opcode;
+      register const char **wreg = data32 ? reg32 : reg16;
+      opcode = *code++;
+      switch(opcode)
+	{
+	case 0x00:
+	case 0x08:
+	case 0x10:
+	case 0x18:
+	case 0x20:
+	case 0x28:
+	case 0x30:
+	case 0x38:
+	  d86_printf(arith[(opcode >> 3) & 7]);
+	  d86_printf(" ");
+	  code = mod_reg_rm_r(out, code, seg, reg8, reg8, addr32);
+	  break;
+
+	case 0x01:
+	case 0x09:
+	case 0x11:
+	case 0x19:
+	case 0x21:
+	case 0x29:
+	case 0x31:
+	case 0x39:
+	  d86_printf(arith[(opcode >> 3) & 7]);
+	  d86_printf(" ");
+	  code = mod_reg_rm_r(out, code, seg, wreg, wreg, addr32);
+	  break;
+
+	case 0x02:
+	case 0x0a:
+	case 0x12:
+	case 0x1a:
+	case 0x22:
+	case 0x2a:
+	case 0x32:
+	case 0x3a:
+	  d86_printf(arith[(opcode >> 3) & 7]);
+	  d86_printf(" ");
+	  code = mod_reg_rm(out, code, seg, reg8, reg8, addr32);
+	  break;
+
+	case 0x03:
+	case 0x0b:
+	case 0x13:
+	case 0x1b:
+	case 0x23:
+	case 0x2b:
+	case 0x33:
+	case 0x3b:
+	  d86_printf(arith[(opcode >> 3) & 7]);
+	  d86_printf(" ");
+	  code = mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	  break;
+
+	case 0x04:
+	case 0x0c:
+	case 0x14:
+	case 0x1c:
+	case 0x24:
+	case 0x2c:
+	case 0x34:
+	case 0x3c:
+	  d86_printf("%s al,%d", arith[opcode >> 3],
+		  (signed char)*code++);
+	  break;
+
+	case 0x05:
+	case 0x0d:
+	case 0x15:
+	case 0x1d:
+	case 0x25:
+	case 0x2d:
+	case 0x35:
+	case 0x3d:
+	  if (data32)
+	    {
+	      d86_printf("%s eax,0x%x", arith[opcode >> 3], immed32(code));
+	      code += 4;
+	    }
+	  else
+	    {
+	      d86_printf("%s ax,0x%hx", arith[opcode >> 3], immed16(code));
+	      code += 2;
+	    }
+	  break;
+
+	case 0x06:
+	  d86_printf("push es");
+	  break;
+
+	case 0x07:
+	  d86_printf("pop es");
+	  break;
+
+	case 0x0e:
+	  d86_printf("push cs");
+	  break;
+
+	case 0x0f:
+	  opcode = *code++;
+	  switch (opcode)
+	    {
+	    case 0x00:
+	      d86_printf(f00[(*code >> 3) & 7]);
+	      d86_printf(" ");
+	      code = mod_rm(out, code, seg, wreg, addr32);
+	      break;
+	    case 0x01:
+	      d86_printf(f01[(*code >> 3) & 7]);
+	      d86_printf(" ");
+	      code = mod_rm(out, code, seg, wreg, addr32);
+	      break;
+	    case 0x02:
+	      d86_printf("lar ");
+	      code = mod_rm(out, code, seg, wreg, addr32);
+	      break;
+	    case 0x03:
+	      d86_printf("lsl ");
+	      code = mod_rm(out, code, seg, wreg, addr32);
+	      break;
+	    case 0x06:
+	      d86_printf("clts");
+	      break;
+	    case 0x08:
+	      d86_printf("invd");
+	      break;
+	    case 0x09:
+	      d86_printf("wbinvd");
+	      break;
+	    case 0x10:
+	      d86_printf("invlpg ");
+	      code = mod_rm(out, code, seg, wreg, addr32);
+	      break;
+	    case 0x20:
+	      d86_printf("mov ");
+	      code = mod_reg_rm_r(out, code, seg, cr, reg32, addr32);
+	      break;
+	    case 0x21:
+	      d86_printf("mov ");
+	      code = mod_reg_rm_r(out, code, seg, dr, reg32, addr32);
+	      break;
+	    case 0x22:
+	      d86_printf("mov ");
+	      code = mod_reg_rm(out, code, seg, cr, reg32, addr32);
+	      break;
+	    case 0x23:
+	      d86_printf("mov ");
+	      code = mod_reg_rm(out, code, seg, dr, reg32, addr32);
+	      break;
+	    case 0x24:
+	      d86_printf("mov ");
+	      code = mod_reg_rm_r(out, code, seg, tr, reg32, addr32);
+	      break;
+	    case 0x26:
+	      d86_printf("mov ");
+	      code = mod_reg_rm(out, code, seg, tr, reg32, addr32);
+	      break;
+	    case 0x80:
+	    case 0x81:
+	    case 0x82:
+	    case 0x83:
+	    case 0x84:
+	    case 0x85:
+	    case 0x86:
+	    case 0x87:
+	    case 0x88:
+	    case 0x89:
+	    case 0x8a:
+	    case 0x8b:
+	    case 0x8c:
+	    case 0x8d:
+	    case 0x8e:
+	    case 0x8f:
+	      if (addr32) {
+		d86_printf("j%s %08x", conditions[opcode & 15],
+			resolva((code-code0)+org + 4 + IMMED32I(code)));
+		code += 4;
+	      } else {
+		d86_printf("j%s %04hx", conditions[opcode & 15],
+			(code-code0)+org + 2 + (short)(code[0] + (code[1] << 8)));
+		code += 2;
+	      }
+	      break;
+	    case 0x90:
+	    case 0x91:
+	    case 0x92:
+	    case 0x93:
+	    case 0x94:
+	    case 0x95:
+	    case 0x96:
+	    case 0x97:
+	    case 0x98:
+	    case 0x99:
+	    case 0x9a:
+	    case 0x9b:
+	    case 0x9c:
+	    case 0x9d:
+	    case 0x9e:
+	    case 0x9f:
+	      d86_printf("set%s ", conditions[opcode & 15]);
+	      code = mod_rm(out, code, seg, reg8, addr32);
+	      break;
+
+	    case 0xa0:
+	      d86_printf("push fs");
+	      break;
+
+	    case 0xa1:
+	      d86_printf("pop fs");
+	      break;
+
+	    case 0xa3:
+	      d86_printf("bt ");
+	      code = mod_reg_rm_r(out, code, seg, wreg, wreg, addr32);
+	      break;
+
+	    case 0xa4:
+	      d86_printf("shld ");
+	      mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	      d86_printf(",%d", *code++);
+	      break;
+
+	    case 0xa5:
+	      d86_printf("shrd ");
+	      mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	      d86_printf(",%d", *code++);
+	      break;
+
+	    case 0xa8:
+	      d86_printf("push gs");
+	      break;
+
+	    case 0xa9:
+	      d86_printf("pop gs");
+	      break;
+
+	    case 0xab:
+	      d86_printf("bts ");
+	      code = mod_reg_rm_r(out, code, seg, wreg, wreg, addr32);
+	      break;
+
+	    case 0xac:
+	      d86_printf("shld ");
+	      mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	      d86_printf(",cl");
+	      break;
+
+	    case 0xad:
+	      d86_printf("shrd ");
+	      mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	      d86_printf(",cl");
+	      break;
+
+	    case 0xb2:
+	      d86_printf("lss ");
+	      code = mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	      break;
+
+	    case 0xb3:
+	      d86_printf("btr ");
+	      code = mod_reg_rm_r(out, code, seg, wreg, wreg, addr32);
+	      break;
+
+	    case 0xb4:
+	      d86_printf("lfs ");
+	      code = mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	      break;
+
+	    case 0xb5:
+	      d86_printf("lgs ");
+	      code = mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	      break;
+
+	    case 0xba:
+	      d86_printf("bt? ");
+	      code = mod_rm(out, code, seg, wreg, addr32);
+	      d86_printf(",%d", *code++);
+	      break;
+
+	    case 0xbb:
+	      d86_printf("btc ");
+	      code = mod_reg_rm_r(out, code, seg, wreg, wreg, addr32);
+	      break;
+
+	    case 0xbc:
+	      d86_printf("bsf ");
+	      code = mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	      break;
+
+	    case 0xbd:
+	      d86_printf("bsr ");
+	      code = mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	      break;
+
+	    case 0xc8:
+	    case 0xc9:
+	    case 0xca:
+	    case 0xcb:
+	    case 0xcc:
+	    case 0xcd:
+	    case 0xce:
+	    case 0xcf:
+	      d86_printf("bswap %s", reg32[opcode & 7]);
+	      break;
+
+	    default:
+	      d86_printf("ESC 0f %02x", opcode);
+	      break;
+	    }
+	  break;
+
+	case 0x16:
+	  d86_printf("push ss");
+	  break;
+
+	case 0x17:
+	  d86_printf("pop ss");
+	  break;
+
+	case 0x1e:
+	  d86_printf("push ds");
+	  break;
+
+	case 0x1f:
+	  d86_printf("pop ds");
+	  break;
+
+	case 0x26:
+	  seg = "es:";
+	  prefix = 1;
+	  continue;
+
+	case 0x27:
+	  d86_printf("daa");
+	  break;
+
+	case 0x2e:
+	  seg = "cs:";
+	  prefix = 1;
+	  continue;
+
+	case 0x2f:
+	  d86_printf("das");
+	  break;
+
+	case 0x36:
+	  seg = "ss:";
+	  prefix = 1;
+	  continue;
+
+	case 0x37:
+	  d86_printf("aaa");
+	  break;
+
+	case 0x3e:
+	  seg = "ds:";
+	  prefix = 1;
+	  continue;
+
+	case 0x3f:
+	  d86_printf("aas");
+	  break;
+
+	case 0x40:
+	case 0x41:
+	case 0x42:
+	case 0x43:
+	case 0x44:
+	case 0x45:
+	case 0x46:
+	case 0x47:
+	  d86_printf("inc %s", wreg[opcode & 7]);
+	  break;
+
+	case 0x48:
+	case 0x49:
+	case 0x4a:
+	case 0x4b:
+	case 0x4c:
+	case 0x4d:
+	case 0x4e:
+	case 0x4f:
+	  d86_printf("dec %s", wreg[opcode & 7]);
+	  break;
+
+	case 0x50:
+	case 0x51:
+	case 0x52:
+	case 0x53:
+	case 0x54:
+	case 0x55:
+	case 0x56:
+	case 0x57:
+	  d86_printf("push %s", wreg[opcode & 7]);
+	  break;
+
+	case 0x58:
+	case 0x59:
+	case 0x5a:
+	case 0x5b:
+	case 0x5c:
+	case 0x5d:
+	case 0x5e:
+	case 0x5f:
+	  d86_printf("pop %s", wreg[opcode & 7]);
+	  break;
+
+	case 0x60:
+	  d86_printf("pusha");
+	  break;
+
+	case 0x61:
+	  d86_printf("popa");
+	  break;
+
+	case 0x62:
+	  d86_printf("bound ");
+	  code = mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	  break;
+
+	case 0x63:
+	  d86_printf("arpl ");
+	  code = mod_reg_rm_r(out, code, seg, wreg, wreg, addr32);
+	  break;
+
+	case 0x64:
+	  seg = "fs:";
+	  prefix = 1;
+	  continue;
+
+	case 0x65:
+	  seg = "gs:";
+	  prefix = 1;
+	  continue;
+
+	case 0x66:
+	  data32 = !data32;
+	  prefix = 1;
+	  continue;
+
+	case 0x67:
+	  addr32 = !addr32;
+	  prefix = 1;
+	  continue;
+
+	case 0x68:
+	  if (data32)
+	    {
+	      d86_printf("push %d", immed32(code));
+	      code += 4;
+	    }
+	  else
+	    {
+	      d86_printf("push %d", immed16(code));
+	      code += 2;
+	    }
+	  break;
+
+	case 0x69:
+	  d86_printf("imul ");
+	  code = mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	  if (data32)
+	    {
+	      d86_printf(",%d", immed32(code));
+	      code += 4;
+	    }
+	  else
+	    {
+	      d86_printf(",%hd", immed16(code));
+	      code += 2;
+	    }
+	  break;
+
+	case 0x6a:
+	  d86_printf("push %d", (signed char)*code++);
+	  break;
+
+	case 0x6b:
+	  d86_printf("imul ");
+	  code = mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	  d86_printf(",%d", (signed char)*code++);
+	  break;
+
+	case 0x6c:
+	  d86_printf("insb es:[%s]", addr32 ? "edi" : "di");
+	  break;
+
+	case 0x6d:
+	  d86_printf("ins%c es:[%s]", data32 ? 'd' : 'w',
+		  addr32 ? "edi" : "di");
+	  break;
+
+	case 0x6e:
+	  d86_printf("outsb dx,%s[%s]", seg, addr32 ? "esi" : "si");
+	  break;
+
+	case 0x6f:
+	  d86_printf("outs%c dx,%s[%s]", data32 ? 'd' : 'w',
+		  seg, addr32 ? "esi" : "si");
+	  break;
+
+	case 0x70:
+	case 0x71:
+	case 0x72:
+	case 0x73:
+	case 0x74:
+	case 0x75:
+	case 0x76:
+	case 0x77:
+	case 0x78:
+	case 0x79:
+	case 0x7a:
+	case 0x7b:
+	case 0x7c:
+	case 0x7d:
+	case 0x7e:
+	case 0x7f:
+	  d86_printf("j%s %08x", conditions[opcode & 15],
+		  resolva((code-code0)+org + (signed char)*code + 1));
+	  code++;
+	  break;
+
+	case 0x80:
+	case 0x82:
+	  d86_printf(arith[(*code >> 3) & 7]);
+	  d86_printf(" ");
+	  code = mod_rm(out, code, seg, reg8, addr32);
+	  d86_printf(",%d", (signed char)*code++);
+	  break;
+
+	case 0x81:
+	  d86_printf(arith[(*code >> 3) & 7]);
+	  d86_printf(" ");
+	  code = mod_rm(out, code, seg, wreg, addr32);
+	  if (data32)
+	    {
+	      d86_printf(",0x%x", immed32(code));
+	      code += 4;
+	    }
+	  else
+	    {
+	      d86_printf(",0x%hx", immed16(code));
+	      code += 2;
+	    }
+	  break;
+
+	case 0x83:
+	  d86_printf(arith[(*code >> 3) & 7]);
+	  d86_printf(" ");
+	  code = mod_rm(out, code, seg, wreg, addr32);
+	  d86_printf(",%d", (signed char)*code++);
+	  break;
+
+	case 0x84:
+	  d86_printf("test ");
+	  code = mod_reg_rm(out, code, seg, reg8, reg8, addr32);
+	  break;
+
+	case 0x85:
+	  d86_printf("test ");
+	  code = mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	  break;
+
+	case 0x86:
+	  d86_printf("xchg ");
+	  code = mod_reg_rm(out, code, seg, reg8, reg8, addr32);
+	  break;
+
+	case 0x87:
+	  d86_printf("xchg ");
+	  code = mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	  break;
+
+	case 0x88:
+	  d86_printf("mov ");
+	  code = mod_reg_rm_r(out, code, seg, reg8, reg8, addr32);
+	  break;
+
+	case 0x89:
+	  d86_printf("mov ");
+	  code = mod_reg_rm_r(out, code, seg, wreg, wreg, addr32);
+	  break;
+
+	case 0x8a:
+	  d86_printf("mov ");
+	  code = mod_reg_rm(out, code, seg, reg8, reg8, addr32);
+	  break;
+
+	case 0x8b:
+	  d86_printf("mov ");
+	  code = mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	  break;
+
+	case 0x8c:
+	  d86_printf("mov ");
+	  code = mod_reg_rm_r(out, code, seg, sreg, reg16, addr32);
+	  break;
+
+	case 0x8d:
+	  d86_printf("lea ");
+	  code = mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	  break;
+
+	case 0x8e:
+	  d86_printf("mov ");
+	  code = mod_reg_rm(out, code, seg, sreg, reg16, addr32);
+	  break;
+
+	case 0x8f:
+	  d86_printf("pop ");
+	  code = mod_rm(out, code, seg, wreg, addr32);
+	  break;
+
+	case 0x90:
+	  d86_printf("nop");
+	  break;
+
+	case 0x91:
+	case 0x92:
+	case 0x93:
+	case 0x94:
+	case 0x95:
+	case 0x96:
+	case 0x97:
+	  d86_printf("xchg ax,%s", wreg[opcode & 7]);
+	  break;
+
+	case 0x98:
+	  d86_printf("cbw");
+	  break;
+
+	case 0x99:
+	  d86_printf("cwd");
+	  break;
+
+	case 0x9a:
+	  d86_printf("call %04hx:%04hx", immed16(code+2),
+		  immed16(code));
+	  resolva( makeaddr( immed16(code+2), immed16(code)));
+	  code += 4;
+	  break;
+
+	case 0x9b:
+	  d86_printf("wait");
+	  break;
+
+	case 0x9c:
+	  d86_printf("pushf");
+	  break;
+
+	case 0x9d:
+	  d86_printf("popf");
+	  break;
+
+	case 0x9e:
+	  d86_printf("sahf");
+	  break;
+
+	case 0x9f:
+	  d86_printf("lahf");
+	  break;
+
+	case 0xa0:
+	  if (addr32) {
+	    d86_printf("mov al,%s[%08x]", seg, immed32(code));
+	    code += 4;
+	  } else {
+	    d86_printf("mov al,%s[%04hx]", seg, immed16(code));
+	    code += 2;
+	  }
+	  break;
+
+	case 0xa1:
+	  if (addr32) {
+	    d86_printf("mov ax,%s[%08x]", seg, immed32(code));
+	    code += 4;
+	  } else {
+	    d86_printf("mov ax,%s[%04hx]", seg, immed16(code));
+	    code += 2;
+	  }
+	  break;
+
+	case 0xa2:
+	  if (addr32) {
+	    d86_printf("mov %s[%08x],al", seg, immed32(code));
+	    code += 4;
+	  } else {
+	    d86_printf("mov %s[%04hx],al", seg, immed16(code));
+	    code += 2;
+	  }
+	  break;
+
+	case 0xa3:
+	  if (addr32) {
+	    d86_printf("mov %s[%08x],ax", seg, immed32(code));
+	    code += 4;
+	  } else {
+	    d86_printf("mov %s[%04hx],ax", seg, immed16(code));
+	    code += 2;
+	  }
+	  break;
+
+	case 0xa4:
+	  d86_printf("movsb es:[%s],%s[%s]", addr32 ? "edi" : "di",
+		  seg, addr32 ? "esi" : "si");
+	  break;
+
+	case 0xa5:
+	  d86_printf("movs%c es:[%s],%s[%s]", data32 ? 'd' : 'w',
+		  addr32 ? "edi" : "di", seg, addr32 ? "esi" : "si");
+	  break;
+
+	case 0xa6:
+	  d86_printf("cmpsb");
+	  break;
+
+	case 0xa7:
+	  if (data32)
+	    d86_printf("cmpsd");
+	  else
+	    d86_printf("cmpsw");
+	  break;
+
+	case 0xa8:
+	  d86_printf("test al,%d", *code++);
+	  break;
+
+	case 0xa9:
+	  if (data32)
+	    {
+	      d86_printf("test eax,0x%x", immed32(code));
+	      code += 4;
+	    }
+	  else
+	    {
+	      d86_printf("test ax,0x%hx", immed16(code));
+	      code += 2;
+	    }
+	  break;
+
+	case 0xaa:
+	  d86_printf("stosb es:[%s]", addr32 ? "edi" : "di");
+	  break;
+
+	case 0xab:
+	  d86_printf("stos%c es:[%s]", data32 ? 'd' : 'w',
+		  addr32 ? "edi" : "di");
+	  break;
+
+	case 0xac:
+	  d86_printf("lodsb %s[si]", seg);
+	  break;
+
+	case 0xad:
+	  d86_printf("lods%c %s[%s]", data32 ? 'd' : 'c', seg,
+		  addr32 ? "esi" : "si");
+	  break;
+
+	case 0xae:
+	  d86_printf("scasb");
+	  break;
+
+	case 0xaf:
+	  if (data32)
+	    d86_printf("scasd");
+	  else
+	    d86_printf("scasw");
+	  break;
+
+	case 0xb0:
+	case 0xb1:
+	case 0xb2:
+	case 0xb3:
+	case 0xb4:
+	case 0xb5:
+	case 0xb6:
+	case 0xb7:
+	  d86_printf("mov %s,0x%x", reg8[opcode & 7], *code++);
+	  break;
+
+	case 0xb8:
+	case 0xb9:
+	case 0xba:
+	case 0xbb:
+	case 0xbc:
+	case 0xbd:
+	case 0xbe:
+	case 0xbf:
+	  if (data32)
+	    {
+	      d86_printf("mov %s,0x%x", wreg[opcode & 7], immed32(code));
+	      code += 4;
+	    }
+	  else
+	    {
+	      d86_printf("mov %s,0x%hx", wreg[opcode & 7], immed16(code));
+	      code += 2;
+	    }
+	  break;
+
+	case 0xc0:
+	  d86_printf(shift[(*code >> 3) & 7]);
+	  d86_printf(" ");
+	  code = mod_rm(out, code, seg, reg8, addr32);
+	  d86_printf(",%d", 31 & *code++);
+	  break;
+
+	case 0xc1:
+	  d86_printf(shift[(*code >> 3) & 7]);
+	  d86_printf(" ");
+	  code = mod_rm(out, code, seg, wreg, addr32);
+	  d86_printf(",%d", 31 & *code++);
+	  break;
+
+	case 0xc2:
+	  d86_printf("ret %d", *code++);
+	  break;
+
+	case 0xc3:
+	  d86_printf("ret");
+	  break;
+
+	case 0xc4:
+	  d86_printf("les ");
+	  code = mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	  break;
+
+	case 0xc5:
+	  d86_printf("lds ");
+	  code = mod_reg_rm(out, code, seg, wreg, wreg, addr32);
+	  break;
+
+	case 0xc6:
+	  d86_printf("mov ");
+	  code = mod_rm(out, code, seg, reg8, addr32);
+	  d86_printf(",%d", (signed char)*code++);
+	  break;
+
+	case 0xc7:
+	  d86_printf("mov ");
+	  code = mod_rm(out, code, seg, wreg, addr32);
+	  if (data32)
+	    {
+	      d86_printf(",0x%x", immed32(code));
+	      code += 4;
+	    }
+	  else
+	    {
+	      d86_printf(",%d", immed16(code));
+	      code += 2;
+	    }
+	  break;
+
+	case 0xc8:
+	  d86_printf("enter");
+	  break;
+
+	case 0xc9:
+	  d86_printf("leave");
+	  break;
+
+	case 0xca:
+	  d86_printf("retf %d", immed16(code));
+	  code += 2;
+	  break;
+
+	case 0xcb:
+	  d86_printf("retf");
+	  break;
+
+	case 0xcc:
+	  d86_printf("int 3");
+	  break;
+
+	case 0xcd:
+	  d86_printf("int %02x", *code++);
+	  break;
+
+	case 0xce:
+	  d86_printf("into");
+	  break;
+
+	case 0xcf:
+	  d86_printf("iret");
+	  break;
+
+	case 0xd0:
+	  d86_printf(shift[(*code >> 3) & 7]);
+	  d86_printf(" ");
+	  code = mod_rm(out, code, seg, reg8, addr32);
+	  d86_printf(",1");
+	  break;
+
+	case 0xd1:
+	  d86_printf(shift[(*code >> 3) & 7]);
+	  d86_printf(" ");
+	  code = mod_rm(out, code, seg, wreg, addr32);
+	  d86_printf(",1");
+	  break;
+
+	case 0xd2:
+	  d86_printf(shift[(*code >> 3) & 7]);
+	  d86_printf(" ");
+	  code = mod_rm(out, code, seg, reg8, addr32);
+	  d86_printf(",cl");
+	  break;
+
+	case 0xd3:
+	  d86_printf(shift[(*code >> 3) & 7]);
+	  d86_printf(" ");
+	  code = mod_rm(out, code, seg, wreg, addr32);
+	  d86_printf(",cl");
+	  break;
+
+	case 0xd4:
+	  d86_printf("aam %d", *code++);
+	  break;
+
+	case 0xd5:
+	  d86_printf("aad %d", *code++);
+	  break;
+
+	case 0xd7:
+	  d86_printf("xlatb");
+	  break;
+
+	case 0xd8:
+	  d86_printf(farith[(*code >> 3) & 7]);
+	  d86_printf("s ");
+	  code = mod_rm(out, code, seg, freg, addr32);
+	  break;
+	case 0xda:
+	  d86_printf(farith[(*code >> 3) & 7]);
+	  d86_printf("w ");
+	  code = mod_rm(out, code, seg, freg, addr32);
+	  break;
+	case 0xdc:
+	  d86_printf(farith[(*code >> 3) & 7]);
+	  d86_printf("l ");
+	  code = mod_rm(out, code, seg, freg, addr32);
+	  break;
+	case 0xde:
+	  d86_printf(farith[(*code >> 3) & 7]);
+	  d86_printf("i ");
+	  code = mod_rm(out, code, seg, freg, addr32);
+	  break;
+	case 0xd9:
+	case 0xdb:
+	case 0xdd:
+	case 0xdf:
+	  d86_printf("esc %d,%d ", opcode & 7, ((*code >> 3) & 7));
+	  if (freg_op[opcode & 7] & 1 << ((*code >> 3) & 7))
+	    code = mod_rm(out, code, seg, freg, addr32);
+	  else
+	    code = mod_rm(out, code, seg, fop, addr32);
+	  break;
+
+	case 0xe0:
+	  d86_printf("loopne %08x", (code-code0)+org + (signed char)*code + 1);
+	  code++;
+	  break;
+
+	case 0xe1:
+	  d86_printf("loope %08x", (code-code0)+org + (signed char)*code + 1);
+	  code++;
+	  break;
+
+	case 0xe2:
+	  d86_printf("loop %08x", (code-code0)+org + (signed char)*code + 1);
+	  code++;
+	  break;
+
+	case 0xe3:
+	  d86_printf("jcxz %08x", (code-code0)+org + (signed char)*code + 1);
+	  code++;
+	  break;
+
+	case 0xe4:
+	  d86_printf("in al,0x%hx", *code++);
+	  break;
+
+	case 0xe5:
+	  d86_printf("in ax,0x%hx", *code++);
+	  break;
+
+	case 0xe6:
+	  d86_printf("out 0x%hx,al", *code++);
+	  break;
+
+	case 0xe7:
+	  d86_printf("out 0x%hx,ax", *code++);
+	  break;
+
+	case 0xe8:
+	  if (addr32) {
+	    d86_printf("call %08x",
+		    resolva((code-code0)+org + 4 + IMMED32I(code)));
+	    code += 4;
+	  } else {
+	    d86_printf("call %04hx",
+		    resolva((code-code0)+org + 2 + code[0] + (code[1] << 8)));
+	    code += 2;
+	  }
+	  break;
+
+	case 0xe9:
+	  if (addr32) {
+	    d86_printf("jmp %08x",
+		    resolva((code-code0)+org + 4 + IMMED32I(code)));
+	    code += 4;
+	  } else {
+	    d86_printf("jmp %04hx",
+		    (unsigned short)((code-code0)+org + 2 + code[0] + (code[1] << 8)));
+	    code += 2;
+	  }
+	  break;
+
+	case 0xea:
+	  if (addr32) {
+	    d86_printf("jmp %04hx:%08x", immed16(code+4),
+		    immed32i(code));
+	    code += 6;
+	  } else {
+	    d86_printf("jmp %04hx:%04hx", immed16(code+2),
+		    immed16(code));
+	    resolva( makeaddr( immed16(code+2), immed16(code)));
+	    code += 4;
+	  }
+	  break;
+
+	case 0xeb:
+	  d86_printf("jmp %08x", resolva((code-code0)+org + (signed char)*code + 1));
+	  code++;
+	  break;
+
+	case 0xec:
+	  d86_printf("in al,dx");
+	  break;
+
+	case 0xed:
+	  d86_printf("in ax,dx");
+	  break;
+
+	case 0xee:
+	  d86_printf("out dx,al");
+	  break;
+
+	case 0xef:
+	  d86_printf("out dx,ax");
+	  break;
+
+	case 0xf0:
+	  d86_printf("lock ");
+	  prefix = 1;
+	  break;
+
+	case 0xf2:
+	  d86_printf("rep ");
+	  prefix = 1;
+	  continue;
+
+	case 0xf3:
+	  d86_printf("repe ");
+	  prefix = 1;
+	  continue;
+
+	case 0xf4:
+	  d86_printf("hlt");
+	  break;
+
+	case 0xf5:
+	  d86_printf("cmc");
+	  break;
+
+	case 0xf6:
+	  opcode = *code;
+	  d86_printf(f7_code[(*code >> 3) & 7]);
+	  d86_printf(" ");
+	  code = mod_rm(out, code, seg, reg8, addr32);
+	  if (((opcode >> 3) & 7) == 0)
+	    d86_printf(",%d", *code++);
+	  break;
+
+	case 0xf7:
+	  opcode = *code;
+	  d86_printf(f7_code[(*code >> 3) & 7]);
+	  d86_printf(" ");
+	  code = mod_rm(out, code, seg, wreg, addr32);
+	  if (((opcode >> 3) & 7) == 0)
+	    {
+	      if (data32)
+		{
+		  d86_printf(",%d", immed32(code));
+		  code += 4;
+		}
+	      else
+		{
+		  d86_printf(",%d", immed16(code));
+		  code += 2;
+		}
+	    }
+	  break;
+
+	case 0xf8:
+	  d86_printf("clc");
+	  break;
+
+	case 0xf9:
+	  d86_printf("stc");
+	  break;
+
+	case 0xfa:
+	  d86_printf("cli");
+	  break;
+
+	case 0xfb:
+	  d86_printf("sti");
+	  break;
+
+	case 0xfc:
+	  d86_printf("cld");
+	  break;
+
+	case 0xfd:
+	  d86_printf("std");
+	  break;
+
+	case 0xfe:
+	  d86_printf(ff_code[(*code >> 3) & 7]);
+	  d86_printf(" ");
+	  code = mod_rm(out, code, seg, reg8, addr32);
+	  break;
+
+	case 0xff:
+	  d86_printf(ff_code[(*code >> 3) & 7]);
+	  d86_printf(" ");
+	  code = mod_rm(out, code, seg, wreg, addr32);
+	  break;
+
+	default:
+	  d86_printf("%x", opcode);
+	  break;
+	}
+      seg = "";
+      data32 = def_size;
+      addr32 = def_size;
+      prefix = 0;
+      break;
+    }	/* end of while() */
+    return ( (int) (code-code0) );
+}   /* end of dis_8086 */
+
diff -urN dosemu-0.60.4.2-clean/debugger/dosdebug.c dosemu/debugger/dosdebug.c
--- dosemu-0.60.4.2-clean/debugger/dosdebug.c	Thu Jan  1 01:00:00 1970
+++ dosemu/debugger/dosdebug.c	Sat Sep 16 18:34:40 1995
@@ -0,0 +1,177 @@
+/*
+ * DOSEMU debugger,  1995 Max Parke <mhp@light.lightlink.com>
+ *
+ * This is file dosdebug.c
+ *
+ * Terminal client for DOSEMU debugger v0.2
+ * by Hans Lermen <lermen@elserv.ffm.fgan.de>
+ * It uses /var/run/dosemu.dbgXX.PID for connections.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <string.h>
+
+#include "shared.h"
+#define MHP_BUFFERSIZE 8192
+
+fd_set readfds;
+struct timeval timeout;
+
+static  char pipename_in[128], pipename_out[128];
+int fdout, fdin;
+
+#define FOREVER ((((unsigned long)-1L) >> 1) / CLOCKS_PER_SEC)
+
+
+int find_dosemu_pid()
+{
+  DIR *dir;
+  struct dirent *p;
+  char dn[]=TMPFILE;
+  char *id;
+  int i,j,pid;
+
+  j=i=strlen(dn);
+  while (dn[i--] != '/');  /* remove 'dosemu.' */
+  i++;
+  dn[i++]=0;
+  id=dn+i;
+  j-=i;
+  
+  dir = opendir(dn);
+  if (!dir) {
+    fprintf(stderr, "can't open directory %s\n",dn);
+    exit(1);
+  }
+  i=0;
+  while (p = readdir(dir)) {
+    if (!strncmp(id,p->d_name,j) && (p->d_name[j] != 'd')) {
+      if (i++ ==1) {
+        fprintf(stderr,
+          "Multiple dosemu processes running or stalled files in %s\n"
+          "restart dosdebug with one of the following pids as first arg:\n"
+          "%d", dn, pid
+        );
+      }
+      pid=strtol(p->d_name+j,0,0);
+      if (i >1) fprintf(stderr, " %d", pid);
+    }
+  }
+  closedir(dir);
+  if (i > 1) {
+    fprintf(stderr, "\n");
+    exit(1);
+  }
+  if (!i) {
+    fprintf(stderr, "No dosemu process running, giving up.\n");
+    exit(1);
+  }
+
+  return pid;
+}
+
+int check_pid(int pid)
+{
+  int fd;
+  char buf[32], name[128];
+  
+  memset(buf, 0, sizeof(buf));
+  sprintf(name, "/proc/%d/stat", pid);
+  if ((fd = open(name, O_RDONLY)) ==-1) return 0;
+  if (read(fd, buf, sizeof(buf)-1) <=0) {
+    close(fd);
+    return 0;
+  }
+  close(fd);
+  return strstr(buf,"dos") ? 1 : 0;
+}
+
+
+
+void handle_console_input(void)
+{
+  char buf[MHP_BUFFERSIZE];
+  static char sbuf[MHP_BUFFERSIZE]="\n";
+  static sn=1;
+  int n;
+  
+  n=read(0, buf, sizeof(buf));
+  if (n>0) {
+    if (n==1 && buf[0]=='\n') write(fdout, sbuf, sn);
+    else {
+      write(fdout, buf, n);
+      memcpy(sbuf, buf, n);
+      sn=n;
+      if (buf[0] == 'q') exit(1);
+    }
+  }
+}
+
+
+void handle_dbg_input(void)
+{
+  char buf[MHP_BUFFERSIZE];
+  int n;
+  do {
+    n=read(fdin, buf, sizeof(buf));
+  } while (n == EAGAIN);
+  if (n >0) {
+    if (buf[0] != 1) write(1, buf, n);
+    else exit(0);
+  }
+}
+
+
+int main (int argc, char **argv)
+{
+  int numfds,n,flags,dospid;
+  
+  FD_ZERO(&readfds);
+
+  if (!argv[1]) dospid=find_dosemu_pid();  
+  else dospid=strtol(argv[1], 0, 0);
+
+  if (!check_pid(dospid)) {
+    fprintf(stderr, "no dosemu running on pid %d\n", dospid);
+    exit(1);
+  }
+
+  sprintf(pipename_in, "%sdbgin.%d", TMPFILE, dospid);
+  sprintf(pipename_out, "%sdbgout.%d", TMPFILE, dospid);
+
+  /* NOTE: need to open read/write else O_NONBLOCK would fail to open */
+  if ((fdout = open(pipename_in, O_RDWR | O_NONBLOCK)) == -1) {
+    perror("can't open output fifo");
+    exit(1);
+  }
+  if ((fdin = open(pipename_out, O_RDONLY | O_NONBLOCK)) == -1) {
+    close(fdout);
+    perror("can't open input fifo");
+    exit(1);
+  }
+
+  write(fdout,"\n",1);
+  do {
+    FD_SET(fdin, &readfds);
+    FD_SET(0, &readfds);   /* stdin */
+    timeout.tv_sec=FOREVER;
+    timeout.tv_usec=0;
+    numfds=select( fdin+1 /* max number of fds to scan */,
+                   &readfds,
+                   NULL /*no writefds*/,
+                   NULL /*no exceptfds*/, &timeout);
+    if (numfds > 0) {
+      if (FD_ISSET(0, &readfds)) handle_console_input();
+      if (FD_ISSET(fdin, &readfds)) handle_dbg_input();
+    }
+  } while (1);
+  return 0;
+}
diff -urN dosemu-0.60.4.2-clean/debugger/mhpdbg.c dosemu/debugger/mhpdbg.c
--- dosemu-0.60.4.2-clean/debugger/mhpdbg.c	Thu Jan  1 01:00:00 1970
+++ dosemu/debugger/mhpdbg.c	Sat Sep 16 18:34:40 1995
@@ -0,0 +1,274 @@
+/*
+ * DOSEMU debugger,  1995 Max Parke <mhp@light.lightlink.com>
+ *
+ * This is file mhpdbg.c
+ *
+ * changes:
+ *
+ *   16Sep95 Hans Lermen <lermen@elserv.ffm.fgan.de>
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#if 0
+#include <sys/socket.h>
+#include <netinet/in.h>
+#endif
+#include <asm/bitops.h>
+
+#include "cpu.h"
+#include "emu.h"
+#include "shared.h"
+
+#define MHP_PRIVATE
+#include "mhpdbg.h"
+
+extern void handle_signals(void);
+
+#if 0
+/* NOTE: the below is already defined with #include "emu.h"
+ *       Must NOT redefine it, else USE_VM86PLUS won't work !!!
+ */
+extern struct vm86_struct vm86s;
+#endif
+
+static void mhp_poll(void);
+static void mhp_puts(char*);
+void mhp_putc(char);
+
+static char mhp_banner[] = {
+  "\nDOSEMU Debugger V0.2 connected\n"
+  "- type ? to get help on commands -\n"
+};
+struct mhpdbgc mhpdbgc;
+
+/********/
+/* CODE */
+/********/
+
+static void mhp_puts(char* s)
+
+{
+   for (;;){
+	   if (*s == 0x00)
+		   break;
+	   mhp_putc (*s++);
+   }
+}
+
+void mhp_putc(char c1)
+
+{
+
+#if 0
+   if (c1 == '\n') {
+      mhpdbg.sendbuf[mhpdbg.sendptr] = '\r';
+      if (mhpdbg.sendptr < SRSIZE-1)
+	 mhpdbg.sendptr++;
+   }
+#endif
+   mhpdbg.sendbuf[mhpdbg.sendptr] = c1;
+   if (mhpdbg.sendptr < SRSIZE-1)
+      mhpdbg.sendptr++;
+
+}
+
+void mhp_send(void)
+{
+   if ((mhpdbg.sendptr) && (mhpdbg.fdout == -1)) {
+      mhpdbg.sendptr = 0;
+      return;
+   }
+   if ((mhpdbg.sendptr) && (mhpdbg.fdout != -1)) {
+      write (mhpdbg.fdout, mhpdbg.sendbuf, mhpdbg.sendptr);
+      mhpdbg.sendptr = 0;
+   }
+}
+
+static  char pipename_in[128], pipename_out[128];
+
+void mhp_close(void)
+{
+   if (mhpdbg.fdin == -1) return;
+   if (mhpdbg.active) {
+     mhp_putc(1); /* tell debugger terminal to also quit */
+     mhp_send();
+   }
+   unlink(pipename_in);
+   unlink(pipename_out);   
+   mhpdbg.fdin = mhpdbg.fdout = -1;
+   mhpdbg.active = 0;
+}
+
+static void mhp_init(void)
+{
+  mhpdbg.fdin = mhpdbg.fdout = -1;
+  mhpdbg.active = 0;
+  mhpdbg.sendptr = 0;
+  
+  vm86s.vm86plus.mhpdbg_active = 0;
+  memset(&vm86s.vm86plus.mhpdbg_intxxtab, 0, sizeof(vm86s.vm86plus.mhpdbg_intxxtab));
+
+  sprintf(pipename_in, "%sdbgin.%d", TMPFILE, getpid());
+  if (!mkfifo(pipename_in, S_IFIFO | 0600)) {
+    sprintf(pipename_out, "%sdbgout.%d", TMPFILE, getpid());
+    if (!mkfifo(pipename_out, S_IFIFO | 0600)) {
+      if ((mhpdbg.fdin = open(pipename_in, O_RDONLY | O_NONBLOCK)) != -1) {
+        /* NOTE: need to open read/write else O_NONBLOCK would fail to open */
+        if ((mhpdbg.fdout = open(pipename_out, O_RDWR | O_NONBLOCK)) != -1) {
+          add_to_io_select(mhpdbg.fdin,0);
+        }
+        else {
+          close(mhpdbg.fdin);
+          mhpdbg.fdin = -1;
+        }
+      }
+    }
+  }
+  if (mhpdbg.fdin == -1) {
+    unlink(pipename_in);
+    unlink(pipename_out);
+  }
+  else {
+    uid_t owner=getuid();
+    fchown(mhpdbg.fdin,owner,-1);
+    fchown(mhpdbg.fdout,owner,-1);
+  }
+}
+
+void mhp_input()
+{
+  if (mhpdbg.fdin == -1) return;
+  mhpdbg.nbytes = read(mhpdbg.fdin, mhpdbg.recvbuf, SRSIZE);
+  if (mhpdbg.nbytes == -1) return;
+  if (!mhpdbg.active) {
+    mhpdbg.active = 1; /* 1 = new session */
+  }
+}
+
+static void mhp_poll(void)
+{
+   int clen;
+   int nbytes;
+   int rc;
+   int i;
+
+   if (!mhpdbg.active) {
+     mhpdbg.nbytes = 0;
+     return;
+   }
+
+   if (mhpdbg.active == 1) {
+      /* new session has started */
+      mhpdbg.active++;
+      
+      mhp_printf ("%s", mhp_banner);
+      mhp_cmd("rmapfile");
+      mhp_cmd("r");
+      mhp_send();
+   }
+
+   if (mhpdbgc.stopped) {
+      mhp_cmd("r");
+      mhp_send();
+   }
+
+   for (;;) {
+      handle_signals();
+      /* NOTE: if there is input on mhpdbg.fdin, as result of handle_signals
+       *       io_select() is called and this then calls mhp_input.
+       *       ( all clear ? )
+       */
+      if (mhpdbg.nbytes <= 0) {
+	 if (mhpdbgc.stopped) continue;
+	 else break;
+      }
+      if ((mhpdbg.recvbuf[0] == 'q') && (mhpdbg.recvbuf[1] <= ' ')) {
+	 mhpdbg.active = 0;
+	 mhpdbg.sendptr = 0;
+         mhpdbg.nbytes = 0;
+         return;
+      }
+      mhpdbg.recvbuf[mhpdbg.nbytes] = 0x00;
+      mhp_cmd(mhpdbg.recvbuf);
+      mhp_send();
+      mhpdbg.nbytes = 0;
+   }
+}
+
+unsigned int mhp_debug(unsigned int code, unsigned int parm1, unsigned int parm2)
+{
+  int rtncd = 0;
+#if 0
+  return rtncd;
+#endif
+  mhpdbgc.currcode = code;
+  mhp_bpclr();
+  switch (DBG_TYPE(mhpdbgc.currcode)) {
+  case DBG_INIT:
+	  mhp_init();
+	  break;
+  case DBG_INTx:
+	  if (!mhpdbg.active)
+	     break;
+	  if (test_bit(DBG_ARG(mhpdbgc.currcode), vm86s.vm86plus.mhpdbg_intxxtab)) {
+		  mhpdbgc.stopped = 1;
+		  mhp_poll();
+	  }
+	  break;
+  case DBG_TRAP:
+	  if (!mhpdbg.active)
+	     break;
+	  if (DBG_ARG(mhpdbgc.currcode) == 1) { /* single step */
+		  if (mhpdbgc.trapcmd) {
+			  mhpdbgc.trapcmd = 0;
+			  rtncd = 1;
+			  mhpdbgc.stopped = 1;
+			  mhp_poll();
+		  }
+	  }
+	  if (DBG_ARG(mhpdbgc.currcode) == 3) { /* int3 (0xCC) */
+		  if (mhp_bpchk( (unsigned char *)((LWORD(cs) << 4) + LWORD(eip) - 1))) {
+			  LWORD(eip) --;
+			  mhpdbgc.trapcmd = 0;
+			  rtncd = 1;
+			  mhpdbgc.stopped = 1;
+			  mhp_poll();
+		  }
+	  }
+	  break;
+  case DBG_POLL:
+	  mhp_poll();
+	  break;
+  case DBG_GPF:
+	  if (!mhpdbg.active)
+	     break;
+	  mhpdbgc.stopped = 1;
+	  mhp_poll();
+	  break;
+  default:
+	  break;
+  }
+  if (mhpdbg.active) mhp_bpset();
+  return rtncd;
+}
+
+void mhp_printf(const char *fmt,...)
+{
+  va_list args;
+  char frmtbuf[SRSIZE];
+
+  va_start(args, fmt);
+  vsprintf(frmtbuf, fmt, args);
+  va_end(args);
+
+  mhp_puts(frmtbuf);
+}
diff -urN dosemu-0.60.4.2-clean/debugger/mhpdbgc.c dosemu/debugger/mhpdbgc.c
--- dosemu-0.60.4.2-clean/debugger/mhpdbgc.c	Thu Jan  1 01:00:00 1970
+++ dosemu/debugger/mhpdbgc.c	Sat Sep 16 18:34:41 1995
@@ -0,0 +1,899 @@
+/*
+ * DOSEMU debugger,  1995 Max Parke <mhp@light.lightlink.com>
+ *
+ * This is file mhpdbgc.c
+ *
+ * changes:
+ *
+ *   16Sep95 Hans Lermen <lermen@elserv.ffm.fgan.de>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <asm/bitops.h>
+#include "cpu.h"
+#include "emu.h"
+
+#define MHP_PRIVATE
+#include "mhpdbg.h"
+
+#define makeaddr(x,y) ((((unsigned long)x) << 4) + (unsigned long)y)
+
+/* externs */
+extern struct mhpdbgc mhpdbgc;
+
+#if 0
+/* NOTE: the below is already defined with #include "emu.h"
+ *       Must NOT redefine it, else USE_VM86PLUS won't work !!!
+ */
+extern struct vm86_struct vm86s;
+#endif
+
+extern int  dis_8086(unsigned int, const unsigned char *,
+		     unsigned char *, int, unsigned int *, unsigned int *);
+
+/* prototypes */
+static void* mhp_getadr(unsigned char *, unsigned int *, unsigned int *);
+static int mhp_parse(char*, char *[]);
+static void mhp_regs  (int, char *[]);
+static void mhp_dis   (int, char *[]);
+static void mhp_disasm	(int, char *[]);
+static void mhp_go	(int, char *[]);
+static void mhp_stop	(int, char *[]);
+static void mhp_trace	(int, char *[]);
+static void mhp_regs32	(int, char *[]);
+static void mhp_bp	(int, char *[]);
+static void mhp_bc	(int, char *[]);
+static void mhp_bl	(int, char *[]);
+static void mhp_bpint	(int, char *[]);
+static void mhp_bcint	(int, char *[]);
+static void mhp_rmapfile(int, char *[]);
+static void mhp_mode	(int, char *[]);
+static void mhp_rusermap(int, char *[]);
+static void mhp_kill    (int, char *[]);
+static void mhp_help    (int, char *[]);
+static void mhp_enter	(int, char *[]);
+static unsigned int lookup(unsigned char *, unsigned int *, unsigned int *);
+
+/* static data */
+static unsigned int linmode = 0;
+static unsigned int codeorg = 0;
+
+static unsigned int lastd = 0;
+static unsigned int lastdseg = 0;
+static unsigned int lastdoff = 0;
+
+static unsigned int lastu = 0;
+static unsigned int lastuseg = 0;
+static unsigned int lastuoff = 0;
+
+static struct symbol_entry symbol_table[MAXSYM];
+static unsigned int last_symbol = 0;
+static unsigned int addrmax;
+
+static struct symbl2_entry symbl2_table[MAXSYM];
+static unsigned int last_symbol2 = 0;
+static unsigned int symbl2_org = 0;
+static unsigned int symbl2_end = 0;
+
+/* constants */
+static const struct cmd_db cmdtab[] = {
+   "r", 	    mhp_regs,
+   "e", 	    mhp_enter,
+   "d", 	    mhp_dis,
+   "u", 	    mhp_disasm,
+   "g", 	    mhp_go,
+   "stop",	    mhp_stop,
+   "mode",	    mhp_mode,
+   "t", 	    mhp_trace,
+   "r32",	    mhp_regs32,
+   "bp",	    mhp_bp,
+   "bc",	    mhp_bc,
+   "bl",	    mhp_bl,
+   "bpint",	    mhp_bpint,
+   "bcint",	    mhp_bcint,
+   "rmapfile",	    mhp_rmapfile,
+   "rusermap",	    mhp_rusermap,
+   "kill",	    mhp_kill,
+   "?",		    mhp_help,
+   "",		    NULL
+};
+
+static const char help_page[]=
+  "q                 Quit the debug session\n"
+  "kill              Kill the dosemu process\n"
+  "r                 list regs\n"
+  "e ADDR HEXSTR     modify memory (0-1Mb)\n"
+  "d ADDR SIZE       dump memory (no limit)\n"
+  "u ADDR SIZE       unassemble memory (no limit)\n"
+  "g                 go (if stopped)\n"
+  "stop              stop (if running)\n"
+  "mode 0|1          set mode (0=SEG16, 1=LIN32) for u and d commands\n"
+  "t                 single step (not fully debugged!!!)\n"
+  "r32               dump regs in 32 bit format\n"
+  "bp addr           set int3 style breakpoint\n"
+  "bpint xx          set breakpoint on INT xx\n"
+  "bcint xx          clr breakpoint on INT xx\n"
+  "bl                list active breakpoints\n"
+  "rusermap org fn   read microsoft linker format .MAP file 'fn'\n"
+  "                  code origin = 'org'.\n";
+
+/********/
+/* CODE */
+/********/
+
+static unsigned char * getname(unsigned int addr)
+{
+   int i;
+   if ((addr < 0x100000) || (addr > addrmax))
+      return(NULL);
+   for (i=0; i < last_symbol; i++) {
+      if (symbol_table[i].addr == addr)
+	 return(symbol_table[i].name);
+   }
+   return(NULL);
+}
+
+static unsigned char * getname2(unsigned int seg, unsigned int off)
+{
+   int i;
+   for (i=0; i < last_symbol2; i++) {
+      if ((symbl2_table[i].seg == seg) &&
+	  (symbl2_table[i].off == off))
+	 return(symbl2_table[i].name);
+   }
+   return(NULL);
+}
+
+static unsigned char * getname2u(unsigned int addr)
+{
+   int i;
+   for (i=0; i < last_symbol2; i++) {
+      if (addr == makeaddr(symbl2_table[i].seg, symbl2_table[i].off))
+	 return(symbl2_table[i].name);
+   }
+   return(NULL);
+}
+
+static unsigned int    getaddr(unsigned char * n1)
+{
+   int i;
+   if (strlen(n1) == 0)
+      return 0;
+   for (i=0; i < last_symbol; i++) {
+      if (strcmp(symbol_table[i].name, n1) == 0)
+	 return(symbol_table[i].addr);
+   }
+   return 0;
+}
+
+static unsigned int lookup(unsigned char * n1, unsigned int *s1, unsigned int * o1)
+{
+   int i;
+   if (!strlen(n1))
+      return 0;
+   for (i=0; i < last_symbol2; i++) {
+      if (!strcmp(symbl2_table[i].name, n1)) {
+	 *s1=symbl2_table[i].seg;
+	 *o1=symbl2_table[i].off;
+	 return makeaddr(*s1,*o1);
+      }
+   }
+   return 0;
+}
+
+static void mhp_rusermap(int argc, char *argv[])
+{
+  FILE * ifp;
+  unsigned char bytebuf[IBUFS];
+  unsigned long a1;
+  unsigned long org;
+  unsigned int	seg;
+  unsigned int	off;
+
+  char * srchfor = "  Address         Publics by Value";
+
+  if (argc < 3) {
+     mhp_printf("syntax: rusermap <org> <file>\n");
+     return;
+  }
+
+  sscanf(argv[1], "%x", &org);
+  symbl2_org = org;
+
+  ifp = fopen(argv[2], "r");
+  if (!ifp) {
+     mhp_printf("unable to open map file %s\n", argv[2]);
+     return;
+  }
+  mhp_printf("reading map file %s\n", argv[2]);
+  last_symbol2 = 0;
+  for(;;) {
+     if(!fgets(bytebuf, 100, ifp)) {
+	mhp_printf("error: could not find following in %s:\n%s\n",
+		   argv[2], srchfor);
+	return;
+     }
+     if (!strlen(bytebuf))
+	continue;
+     if (!memcmp(bytebuf, srchfor, strlen(srchfor)))
+	break;
+  }
+  for(;;) {
+     if(!fgets(bytebuf, 100, ifp))
+	break;
+     if(bytebuf[5] != ':')
+	continue;
+     if(bytebuf[12] != ' ')
+	continue;
+     bytebuf[5] = ' ';
+     sscanf(&bytebuf[1], "%x %x", &seg, &off);
+     symbl2_table[last_symbol2].seg  = seg + (symbl2_org >> 4);
+     symbl2_table[last_symbol2].off  = off;
+     symbl2_table[last_symbol2].type = ' ';
+     sscanf(&bytebuf[17], "%s", &symbl2_table[last_symbol2].name);
+     last_symbol2++;
+  }
+  fclose(ifp);
+/*symbl2_end = symbl2_table[last_symbol2-1].addr;*/
+  mhp_printf("%d symbol(s) processed\n", last_symbol2);
+  mhp_printf("highest address %04x:%04x(%s)\n",
+	     symbl2_table[last_symbol2-1].seg,
+	     symbl2_table[last_symbol2-1].off,
+	     symbl2_table[last_symbol2-1].name);
+
+}
+
+static void mhp_rmapfile(int argc, char *argv[])
+{
+  FILE * ifp;
+  unsigned char bytebuf[IBUFS];
+  unsigned long a1;
+
+  ifp = fopen("/usr/src/dosemu/dosemu.map", "r");
+  if (!ifp) {
+     mhp_printf("unable to open map file\n");
+     return;
+  }
+  mhp_printf("Reading map file\n");
+  last_symbol = 0;
+  for(;;) {
+     if(!fgets(bytebuf, 100, ifp))
+	break;
+     if (!strlen(bytebuf))
+	continue;
+     sscanf(&bytebuf[0], "%x", &a1);
+     if (a1 < 0x20000000)
+	continue;
+     if (a1 > 0x28000000)
+	break;
+     symbol_table[last_symbol].addr = a1;
+     symbol_table[last_symbol].type = bytebuf[9];
+     sscanf(&bytebuf[11], "%s", &symbol_table[last_symbol].name);
+     last_symbol++;
+  }
+  fclose(ifp);
+  addrmax = symbol_table[last_symbol-1].addr;
+  mhp_printf("%d symbol(s) processed\n", last_symbol);
+  mhp_printf("highest address %08x(%s)\n", addrmax, getname(addrmax));
+}
+static unsigned long mhp_getreg(unsigned char * regn)
+{
+   if (!memcmp(regn, "AX", 2)) {
+      return LWORD(eax);
+   }
+   if (!memcmp(regn, "BX", 2)) {
+      return LWORD(ebx);
+   }
+   if (!memcmp(regn, "CX", 2)) {
+      return LWORD(ecx);
+   }
+   if (!memcmp(regn, "DX", 2)) {
+      return LWORD(edx);
+   }
+   if (!memcmp(regn, "SI", 2)) {
+      return LWORD(esi);
+   }
+   if (!memcmp(regn, "DI", 2)) {
+      return LWORD(edi);
+   }
+   if (!memcmp(regn, "BP", 2)) {
+      return LWORD(ebp);
+   }
+   if (!memcmp(regn, "SP", 2)) {
+      return LWORD(esp);
+   }
+   if (!memcmp(regn, "CS", 2)) {
+      return LWORD(cs);
+   }
+   if (!memcmp(regn, "DS", 2)) {
+      return LWORD(ds);
+   }
+   if (!memcmp(regn, "ES", 2)) {
+      return LWORD(es);
+   }
+   if (!memcmp(regn, "FS", 2)) {
+      return LWORD(fs);
+   }
+   if (!memcmp(regn, "GS", 2)) {
+      return LWORD(gs);
+   }
+   if (!memcmp(regn, "SS", 2)) {
+      return LWORD(ss);
+   }
+   if (!memcmp(regn, "FL", 2)) {
+      return LWORD(eflags);
+   }
+   return -1;
+}
+
+static void mhp_setreg(unsigned char * regn, unsigned long val)
+{
+   if (!memcmp(regn, "AX", 2)) {
+      LWORD(eax) = (val & 0xFFFF);
+   }
+   if (!memcmp(regn, "BX", 2)) {
+      LWORD(ebx) = (val & 0xFFFF);
+   }
+   if (!memcmp(regn, "CX", 2)) {
+      LWORD(ecx) = (val & 0xFFFF);
+   }
+   if (!memcmp(regn, "DX", 2)) {
+      LWORD(edx) = (val & 0xFFFF);
+   }
+   if (!memcmp(regn, "SI", 2)) {
+      LWORD(esi) = (val & 0xFFFF);
+   }
+   if (!memcmp(regn, "DI", 2)) {
+      LWORD(edi) = (val & 0xFFFF);
+   }
+   if (!memcmp(regn, "BP", 2)) {
+      LWORD(ebp) = (val & 0xFFFF);
+   }
+   if (!memcmp(regn, "SP", 2)) {
+      LWORD(esp) = (val & 0xFFFF);
+   }
+   if (!memcmp(regn, "CS", 2)) {
+      LWORD(cs) = (val & 0xFFFF);
+   }
+   if (!memcmp(regn, "DS", 2)) {
+      LWORD(ds) = (val & 0xFFFF);
+   }
+   if (!memcmp(regn, "ES", 2)) {
+      LWORD(es) = (val & 0xFFFF);
+   }
+   if (!memcmp(regn, "FS", 2)) {
+      LWORD(fs) = (val & 0xFFFF);
+   }
+   if (!memcmp(regn, "GS", 2)) {
+      LWORD(gs) = (val & 0xFFFF);
+   }
+   if (!memcmp(regn, "SS", 2)) {
+      LWORD(ss) = (val & 0xFFFF);
+   }
+   if (!memcmp(regn, "FL", 2)) {
+      WRITE_FLAGS(val & 0xFFFF);
+   }
+}
+
+static void mhp_go(int argc, char * argv[])
+{
+   if (!mhpdbgc.stopped) {
+      mhp_printf("already in running state\n");
+   } else {
+      WRITE_FLAGS(READ_FLAGS() & ~TF);
+      mhpdbgc.stopped = 0;
+   }
+}
+
+static void mhp_stop(int argc, char * argv[])
+{
+   if (mhpdbgc.stopped) {
+      mhp_printf("already in stopped state\n");
+   } else {
+      mhpdbgc.stopped = 1;
+      mhp_cmd("r");
+   }
+}
+
+static void mhp_trace(int argc, char * argv[])
+{
+   if (!mhpdbgc.stopped) {
+      mhp_printf("must be in stopped state\n");
+   } else {
+      WRITE_FLAGS(READ_FLAGS() | TF);
+      mhpdbgc.trapcmd = 1;
+      mhpdbgc.stopped = 0;
+   }
+}
+
+static void mhp_dis(int argc, char * argv[])
+{
+   unsigned int nbytes;
+   unsigned long org;
+   unsigned long seekval;
+   int i,i2;
+   unsigned char * buf = 0;
+   unsigned int seg;
+   unsigned int off;
+
+   if (argc > 1)
+      seekval = (unsigned long)mhp_getadr(argv[1], &seg, &off);
+   else
+      seekval = lastd;
+   buf = (unsigned char *) seekval;
+
+   if (argc > 2)
+      sscanf(argv[2], "%x", &nbytes);
+   else
+      nbytes = 16;
+
+   if ((nbytes == 0) || (nbytes > 256))
+      nbytes = 16;
+
+#if 0
+   mhp_printf( "seekval %08lX nbytes:%d\n", seekval, nbytes);
+#else
+   mhp_printf( "\n");
+#endif
+   for (i=0; i<nbytes; i++) {
+      if ((i&0x0f) == 0x00) {
+	 if (seg|off)
+	    mhp_printf("%04x:%04x ", seg, off+i);
+	 else
+	    mhp_printf( "%08lX ", (unsigned long)seekval+i);
+      }
+      mhp_printf( "%02X ", buf[i]);
+      if ((i&0x0f) == 0x0f) {
+	 mhp_printf( " ");
+	 for (i2=i-15;i2<=i;i2++){
+	    if ((buf[i2]&0x7F) >= 0x20) {
+	       mhp_printf( "%c", buf[i2]&0x7f);
+	    } else {
+	       mhp_printf( "%c", '.');
+	    }
+	 }
+	 mhp_printf( "\n");
+      }
+   }
+   lastd = seekval + i;
+}
+
+static void mhp_mode(int argc, char * argv[])
+{
+   if (argc < 2) {
+      mhp_printf ("current mode: %s\n", linmode?"lin32":"seg16");
+      return;
+   }
+   if (argv[1][0] == '0')
+      linmode = 0;
+   if (argv[1][0] == '1')
+      linmode = 1;
+   mhp_printf ("current mode: %s\n", linmode?"lin32":"seg16");
+   return;
+}
+
+static void mhp_disasm(int argc, char * argv[])
+{
+   int rc;
+   unsigned int nbytes;
+   unsigned long org;
+   unsigned long seekval;
+   int def_size;
+   unsigned int bytesdone;
+   int i,i2;
+   unsigned char * buf = 0;
+   unsigned char bytebuf[IBUFS];
+   unsigned char frmtbuf[IBUFS];
+   unsigned int seg;
+   unsigned int off;
+   unsigned int refseg;
+   unsigned int ref;
+
+   if (argc > 1) {
+      seekval = (unsigned long)mhp_getadr(argv[1], &seg, &off);
+      lastu = seekval;
+      lastuseg = seg;
+      lastuoff = off;
+   } else {
+      if (linmode) {
+	 seekval = lastu;
+      } else {
+	 seekval = makeaddr(lastuseg, lastuoff);
+	 seg = lastuseg;
+	 off = lastuoff;
+      }
+   }
+
+   if (argc > 2) {
+      if ((argv[2][0] == 'l') || (argv[2][0] == 'L'))
+	 sscanf(&argv[2][1], "%x", &nbytes);
+      else
+	 sscanf(argv[2], "%x", &nbytes);
+   } else {
+      nbytes = 32;
+   }
+
+   if ((nbytes == 0) || (nbytes > 256))
+      nbytes = 32;
+
+#if 0
+   mhp_printf( "seekval %08lX nbytes:%d\n", seekval, nbytes);
+#else
+   mhp_printf( "\n");
+#endif
+   if (seekval < 0x100000)
+	   def_size = 0;
+   else
+	   def_size = 1;
+   rc=0;
+   buf = (unsigned char *) seekval;
+   org = codeorg ? codeorg : seekval;
+
+   for (bytesdone = 0; bytesdone < nbytes; bytesdone += rc) {
+       if (linmode) {
+	  if (getname(org+bytesdone))
+	     mhp_printf ("%s:\n", getname(org+bytesdone));
+       } else {
+	  if (getname2(seg,off+bytesdone))
+	     mhp_printf ("%s:\n", getname2(seg,off));
+       }
+       rc = dis_8086(org+bytesdone, buf+bytesdone, frmtbuf, def_size, &refseg, &ref);
+       for (i=0;i<rc;i++) {
+	   sprintf(&bytebuf[i*2], "%02X", *(buf+bytesdone+i) );
+	   bytebuf[(i*2)+2] = 0x00;
+       }
+       if (!linmode) {
+	  mhp_printf( "%04x:%04x %-16s %s", seg, off+bytesdone, bytebuf, frmtbuf);
+	  if ((ref) && (getname2u(ref)))
+	     mhp_printf ("(%s)", getname2u(ref));
+       } else {
+	  mhp_printf( "%08x: %-16s %s", org+bytesdone, bytebuf, frmtbuf);
+	  if ((ref) && (getname(ref)))
+	     mhp_printf ("(%s)", getname(ref));
+       }
+       mhp_printf( "\n");
+   }
+   lastuoff += bytesdone;
+   lastu    += bytesdone;
+}
+static void mhp_enter(int argc, char * argv[])
+{
+   int i1;
+   unsigned char * zapaddr;
+   unsigned int seg;
+   unsigned int off;
+   unsigned char * inputptr;
+   unsigned char   c;
+   unsigned char   workchrs[4];
+
+   if (argc < 3)
+      return;
+
+   zapaddr = (unsigned char*)mhp_getadr(argv[1], &seg, &off);
+   if (0x100000 < (unsigned long)zapaddr) {
+      mhp_printf("Address invalid\n");
+      return;
+   }
+   inputptr = argv[2];
+   for (i1 = 0; ; i1++) {
+      workchrs[0] = *inputptr++;
+      if (!workchrs[0])
+	 break;
+      workchrs[1] = *inputptr++;
+      workchrs[2] = 0x00;
+      sscanf(workchrs, "%02x", &c);
+      zapaddr[i1] = c;
+      if (!workchrs[1])
+	 break;
+   }
+}
+static void* mhp_getadr(unsigned char * a1, unsigned int * s1, unsigned int *o1)
+{
+   unsigned char * srchp;
+   unsigned int seg1;
+   unsigned int off1;
+   unsigned long ul1;
+
+   if(*a1 == '*') {
+      *s1 = LWORD(cs);
+      *o1 = LWORD(eip);
+      return (void*) makeaddr(LWORD(cs), LWORD(eip));
+   }
+   if(*a1 == '$') {
+      *s1 = LWORD(ss);
+      *o1 = LWORD(esp);
+      return (void*) makeaddr(LWORD(ss), LWORD(esp));
+   }
+   if (ul1 = lookup(a1, s1, o1)) {
+      return (void*)ul1;
+   }
+   if (ul1 = getaddr(a1)) {
+      *s1 = 0;
+      *o1 = 0;
+      return (void*)ul1;
+   }
+   if (!(srchp = (unsigned char *)strchr(a1, ':'))) {
+      sscanf(a1, "%lx", &ul1);
+      *s1 = 0;
+      *o1 = 0;
+      return (void*)ul1;
+   }
+   if ( (seg1 = mhp_getreg(a1)) == -1) {
+	   *srchp = ' ';
+	   sscanf(a1, "%x", &seg1);
+	   *srchp = ':';
+   }
+   if ( (off1 = mhp_getreg(srchp+1)) == -1) {
+	   sscanf(srchp+1, "%x", &off1);
+   }
+   *s1 = seg1;
+   *o1 = off1;
+   return (void*)makeaddr(seg1,off1);
+}
+
+static void mhp_bp(int argc, char * argv[])
+{
+   unsigned long seekval;
+   unsigned long org;
+   int i1;
+   unsigned int seg;
+   unsigned int off;
+
+   if (argc < 2) {
+      mhp_printf("location argument required\n");
+      return;
+   }
+   seekval = (unsigned long)mhp_getadr(argv[1], &seg, &off);
+   for (i1=0; i1 < MAXBP; i1++) {
+      if (mhpdbgc.brktab[i1].brkaddr == (unsigned char *)seekval) {
+	 mhp_printf( "Duplicate breakpoint, nothing done\n");
+	 return;
+      }
+   }
+   for (i1=0; i1 < MAXBP; i1++) {
+      if (!mhpdbgc.brktab[i1].brkaddr) {
+	 mhpdbgc.brktab[i1].brkaddr = (unsigned char *)seekval;
+	 return;
+      }
+   }
+   mhp_printf( "Breakpoint table full, nothing done\n");
+   return;
+}
+
+static void mhp_bl(int argc, char * argv[])
+{
+   int i1;
+
+   mhp_printf( "Breakpoints:\n");
+   for (i1=0; i1 < MAXBP; i1++) {
+      if (mhpdbgc.brktab[i1].brkaddr) {
+	 mhp_printf( "%d: %08lx\n", i1, mhpdbgc.brktab[i1].brkaddr);
+      }
+   }
+   mhp_printf( "Interrupts: ");
+   for (i1=0; i1 < 256; i1++) {
+      if (test_bit(i1, vm86s.vm86plus.mhpdbg_intxxtab)) {
+	 mhp_printf( "%02x ", i1);
+      }
+   }
+   mhp_printf( "\n");
+   return;
+}
+
+static void mhp_bc(int argc, char * argv[])
+{
+   int i1;
+
+   sscanf(argv[1], "%d", &i1);
+   if (!mhpdbgc.brktab[i1].brkaddr) {
+	 mhp_printf( "No breakpoint %d, nothing done\n", i1);
+	 return;
+   }
+   mhpdbgc.brktab[i1].brkaddr = 0;
+   return;
+}
+
+static void mhp_bpint(int argc, char * argv[])
+{
+   int i1;
+
+   sscanf(argv[1], "%x", &i1);
+   if (test_bit(i1, vm86s.vm86plus.mhpdbg_intxxtab)) {                       
+	 mhp_printf( "Duplicate BPINT %02x, nothing done\n", i1);
+	 return;
+   }
+   set_bit(i1, vm86s.vm86plus.mhpdbg_intxxtab);                      
+   return;
+}
+
+static void mhp_bcint(int argc, char * argv[])
+{
+   int i1;
+
+   sscanf(argv[1], "%x", &i1);
+   if (!test_bit(i1, vm86s.vm86plus.mhpdbg_intxxtab)) {                       
+	 mhp_printf( "No BPINT %02x, nothing done\n", i1);
+	 return;
+   }
+   clear_bit(i1, vm86s.vm86plus.mhpdbg_intxxtab);
+   return;
+}
+
+static int mhp_parse(char *s, char* argvx[])
+{
+   int mode = 0;
+   int argcx = 0;
+
+   for ( ; *s; s++) {
+      if (!mode) {
+	 if (*s > ' ') {
+	    mode = 1;
+	    argvx[argcx++] = s;
+	    if (argcx >= MAXARG)
+	       break;
+	 }
+      } else {
+	 if (*s <= ' ') {
+	    mode = 0;
+	    *s = 0x00;
+	 }
+      }
+   }
+   return(argcx);
+}
+
+static void mhp_regs(int argc, char * argv[])
+{
+  unsigned long newval;
+  if (argc == 3) {
+     if (!mhpdbgc.stopped) {
+	mhp_printf("Must be in stopped state\n");
+	return;
+     }
+     sscanf(argv[2], "%lx", &newval);
+     if (islower(argv[1][0]))
+	argv[1][0] = toupper(argv[1][0]);
+     if (islower(argv[1][1]))
+	argv[1][1] = toupper(argv[1][1]);
+     mhp_setreg(argv[1], newval);
+     if (newval == mhp_getreg(argv[1]))
+	mhp_printf("reg %s changed to %04x\n", argv[1], mhp_getreg(argv[1]) );
+     return;
+  }
+  if (DBG_TYPE(mhpdbgc.currcode) == DBG_INTx)
+     mhp_printf( "INT 0x%02X, ", DBG_ARG(mhpdbgc.currcode));
+  if (DBG_TYPE(mhpdbgc.currcode) == DBG_TRAP)
+     mhp_printf( "Trap %d, ", DBG_ARG(mhpdbgc.currcode));
+  if (DBG_TYPE(mhpdbgc.currcode) == DBG_GPF)
+     mhp_printf( "General Protection Fault, ");
+
+  mhp_printf( "system state: %s\n", mhpdbgc.stopped ? "stopped" : "running");
+
+  mhp_printf("AX=%04x  BX=%04x  CX=%04x  DX=%04x",
+	      LWORD(eax), LWORD(ebx), LWORD(ecx), LWORD(edx));
+
+  mhp_printf("  SI=%04x  DI=%04x  SP=%04x  BP=%04x",
+	      LWORD(esi), LWORD(edi), LWORD(esp), LWORD(ebp));
+
+  mhp_printf("\nDS=%04x  ES=%04x  FS=%04x  GS=%04x  FL=%04x",
+	      LWORD(ds), LWORD(es), LWORD(fs), LWORD(gs), LWORD(eflags));
+
+  mhp_printf("\nCS:IP=%04x:%04x       SS:SP=%04x:%04x\n",
+	      LWORD(cs), LWORD(eip), LWORD(ss), LWORD(esp));
+
+  mhp_cmd("u * 1");
+
+}
+
+static void mhp_regs32(int argc, char * argv[])
+{
+  if (DBG_TYPE(mhpdbgc.currcode) == DBG_INTx)
+     mhp_printf( "\nInterrupt 0x%02X", DBG_ARG(mhpdbgc.currcode));
+  if (DBG_TYPE(mhpdbgc.currcode) == DBG_TRAP)
+     mhp_printf( "\nTrap 0x%02X", DBG_ARG(mhpdbgc.currcode));
+  if (DBG_TYPE(mhpdbgc.currcode) == DBG_GPF)
+     mhp_printf( "\nGeneral Protection Fault");
+
+  mhp_printf("\nEAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx VFLAGS(h): %08lx",
+	      REG(eax), REG(ebx), REG(ecx), REG(edx), (unsigned long)vflags);
+
+  mhp_printf("\nESI: %08lx EDI: %08lx EBP: %08lx",
+	      REG(esi), REG(edi), REG(ebp));
+
+  mhp_printf(" DS: %04x ES: %04x FS: %04x GS: %04x\n",
+	      LWORD(ds), LWORD(es), LWORD(fs), LWORD(gs));
+
+  mhp_printf(" CS: %04x IP: %04x SS: %04x SP: %04x\n",
+	      LWORD(cs), LWORD(eip), LWORD(ss), LWORD(esp));
+}
+
+static void mhp_kill(int argc, char * argv[])
+{
+  extern void mhp_send(void), mhp_close(void), mhp_putc(char c1);
+  mhp_cmd("r");
+  mhp_printf("\ndosemu killed via debug terminal\n");
+  mhp_send();
+#if 0
+  mhp_putc(1); /* tell debugger terminal to also quit */
+  mhp_send();
+#endif
+  mhp_close();
+  leavedos(1);
+}
+
+static void mhp_help(int argc, char * argv[])
+{
+  mhp_printf("%s\n",help_page);
+}
+
+void mhp_bpset(void)
+{
+   int i1;
+
+   for (i1=0; i1 < MAXBP; i1++) {
+      if (mhpdbgc.brktab[i1].brkaddr) {
+	 mhpdbgc.brktab[i1].opcode = *mhpdbgc.brktab[i1].brkaddr;
+	 *mhpdbgc.brktab[i1].brkaddr = 0xCC;
+      }
+   }
+   return;
+}
+
+void mhp_bpclr(void)
+{
+   int i1;
+
+   for (i1=0; i1 < MAXBP; i1++) {
+      if (mhpdbgc.brktab[i1].brkaddr) {
+	 if( (*mhpdbgc.brktab[i1].brkaddr) != 0xCC) {
+	    mhpdbgc.brktab[i1].brkaddr = 0;
+	    continue;
+	 }
+	 *mhpdbgc.brktab[i1].brkaddr = mhpdbgc.brktab[i1].opcode;
+      }
+   }
+   return;
+}
+
+int mhp_bpchk(unsigned char * a1)
+{
+   int i1;
+
+   for (i1=0; i1 < MAXBP; i1++) {
+      if (mhpdbgc.brktab[i1].brkaddr == a1)
+	 return 1;
+   }
+   return 0;
+}
+
+void mhp_cmd(const char * cmd)
+{
+   int argc1;
+   char * argv1[MAXARG];
+   char tmpcmd[250];
+   void (*cmdproc)(int, char *[]);
+   const struct cmd_db * cmdp;
+
+   strcpy(tmpcmd, cmd);
+   argc1 = mhp_parse(tmpcmd, argv1);
+   if (argc1 < 1)
+      return;
+   for (cmdp = cmdtab, cmdproc = NULL; cmdp->cmdproc; cmdp++) {
+      if (!memcmp(cmdp->cmdname, argv1[0], strlen(argv1[0])+1)) {
+	 cmdproc = cmdp->cmdproc;
+	 break;
+      }
+   }
+   if (!cmdproc) {
+      mhp_printf("Command %s not found\n", argv1[0]);
+      return;
+   }
+   (*cmdproc)(argc1, argv1);
+}
diff -urN dosemu-0.60.4.2-clean/dosemu/dosio.c dosemu/dosemu/dosio.c
--- dosemu-0.60.4.2-clean/dosemu/dosio.c	Sat Aug  5 00:32:52 1995
+++ dosemu/dosemu/dosio.c	Sat Sep 16 18:34:41 1995
@@ -274,6 +274,9 @@
 #include "dosio.h"
 #include "mouse.h"
 #include "int.h"
+#ifdef USE_MHPDBG
+  #include "mhpdbg.h"
+#endif
 
 #include "pic.h"
 #include "bitops.h"
@@ -494,7 +497,9 @@
       if (FD_ISSET(kbd_fd, &fds)) {
 	getKeys();
       }
-
+#ifdef USE_MHPDBG
+      if (mhpdbg.fdin != -1) if (FD_ISSET(mhpdbg.fdin, &fds)) mhp_input();
+#endif
       /* XXX */
 #if 0
       fflush(stdout);
diff -urN dosemu-0.60.4.2-clean/dosemu/sigsegv.c dosemu/dosemu/sigsegv.c
--- dosemu-0.60.4.2-clean/dosemu/sigsegv.c	Wed Sep 13 02:06:52 1995
+++ dosemu/dosemu/sigsegv.c	Sat Sep 16 18:34:41 1995
@@ -130,6 +130,9 @@
  *
  */
 
+#ifdef USE_MHPDBG
+#include "mhpdbg.h"
+#endif
 
 static char rcsid[]="$Id: sigsegv.c,v 2.20 1995/04/08 22:30:40 root Exp $";
 
@@ -931,8 +934,11 @@
     if (is_rep) fprintf(stderr, "Nope REP F3,CSP = 0x%04x\n", csp[0]);
     /* er, why don't we advance eip here, and
 	 why does it work??  */
-    error("general protection at %p: %x\n", lina,*lina);
     REG(eip) = org_eip;
+#ifdef USE_MHPDBG
+    mhp_debug(DBG_GPF, 0, 0);
+#endif
+    error("general protection at %p: %x\n", lina,*lina);
     show_regs(__FILE__, __LINE__);
     show_ints(0, 0x33);
     error("ERROR: SIGSEGV, protected insn...exiting!\n");
diff -urN dosemu-0.60.4.2-clean/emu.c dosemu/emu.c
--- dosemu-0.60.4.2-clean/emu.c	Wed Sep 13 02:06:52 1995
+++ dosemu/emu.c	Sat Sep 16 18:34:41 1995
@@ -421,6 +421,10 @@
 #include "config.h"
 #include "memory.h"
 
+#ifdef USE_MHPDBG
+#include "mhpdbg.h"
+#endif
+
 #ifdef REQUIRES_EMUMODULE
   /* Please folks, don't remove this, it's required for emusys.h (within emu.h) */
   #define __EMUSYS_parent
@@ -561,8 +565,17 @@
 	pic_iret();
 	break;
     case VM86_INTx:
+#ifdef USE_MHPDBG
+	mhp_debug(DBG_INTx + (VM86_ARG(retval) << 8), 0, 0);
+#endif
 	do_int(VM86_ARG(retval));
 	break;
+#ifdef USE_MHPDBG
+    case VM86_TRAP:
+	if(!mhp_debug(DBG_TRAP + (VM86_ARG(retval) << 8), 0, 0))
+	   do_int(VM86_ARG(retval));
+	break;
+#endif
 #ifdef USE_VM86PLUS
     case VM86_PICRETURN:
         I_printf("Return for FORCE_PIC\n");
@@ -577,7 +590,9 @@
 	}
 
     handle_signals();
-
+#ifdef USE_MHPDBG  
+    if (mhpdbg.active) mhp_debug(DBG_POLL, 0, 0);
+#endif
     /*
      * This is here because ioctl() is non-reentrant, and signal handlers
      * may have to use ioctl().  This results in a possible (probable)
@@ -771,7 +786,7 @@
 	while (sg->fd)
 	    close((sg++)->fd);
 #endif
-	fprintf(stderr, "Closing all IRQ you opened!\n");
+	g_printf("Closing all IRQ you opened!\n");
     }
 #endif
 }
@@ -866,6 +881,10 @@
 
     fflush(stdout);
 
+#ifdef USE_MHPDBG  
+    mhp_debug(DBG_INIT, 0, 0);
+#endif
+
     while (!fatalerr) {
 	++pic_vm86_count;
 	run_vm86();
@@ -1006,6 +1025,10 @@
 
     g_printf("calling shared memory exit\n");
     shared_memory_exit();
+#ifdef USE_MHPDBG
+    g_printf("closing debugger pipes\n");
+    mhp_close();
+#endif
     if (config.detach) {
 	restore_vt(config.detach);
 	disallocate_vt();
diff -urN dosemu-0.60.4.2-clean/emumod/Makefile dosemu/emumod/Makefile
--- dosemu-0.60.4.2-clean/emumod/Makefile	Wed Sep 13 02:48:16 1995
+++ dosemu/emumod/Makefile	Sat Sep 16 18:34:41 1995
@@ -58,7 +58,7 @@
 	ld -r -o emumodule.o $(OBJS)
 
 vm86.o:  vm86.c emumod.h ${KVFILE}
-	$(CC) ${KCFLAGS} -D_LOADABLE_VM86_  -c vm86.c -o vm86.o
+	$(CC) ${KCFLAGS} -D_LOADABLE_VM86_ $(USE_MHPDBG)  -c vm86.c -o vm86.o
 
 signal.o:  signal.c emumod.h ${KVFILE}
 	$(CC) ${KCFLAGS} -D_LOADABLE_VM86_  -c signal.c -o signal.o
diff -urN dosemu-0.60.4.2-clean/emumod/vm86.c dosemu/emumod/vm86.c
--- dosemu-0.60.4.2-clean/emumod/vm86.c	Wed Sep 13 02:48:14 1995
+++ dosemu/emumod/vm86.c	Sat Sep 16 18:34:41 1995
@@ -27,6 +27,10 @@
 #endif
 #include <asm/io.h>
 
+#if defined(_LOADABLE_VM86_) && defined(USE_MHPDBG)
+#include "mhpdbg.h"
+#endif
+
 /*
  * Known problems:
  *
@@ -609,11 +613,22 @@
 #endif
 #endif
 	/* int xx */
-	case 0xcd:
+	case 0xcd: {
+	        int intno=popb(csp, ip);
 		IP(regs) += 2;
-		do_int(regs, popb(csp, ip), ssp, sp);
+#if defined(_LOADABLE_VM86_) && defined(USE_MHPDBG)
+		if (is_vm86plus) {
+		  struct vm86plus_info_struct vmpi;
+		  *(((long *)&vmpi.dosemuver)+1) = get_fs_long(((long *)&vmp->vm86plus.dosemuver)+1);
+		  if (vmpi.mhpdbg_active) {
+		    if ( (1 << (intno &7)) & get_fs_byte((char *)&vmp->vm86plus.mhpdbg_intxxtab[intno >> 3]) )
+		         return_to_32bit(regs, VM86_INTx + (intno << 8));
+		  }
+		}
+#endif
+		do_int(regs, intno, ssp, sp);
 		return;
-
+	}
 	/* iret */
 	case 0xcf:
 		STACKVERIFY(+6)
@@ -685,6 +700,9 @@
           extern int vm86_trap_count[8];
           vm86_trap_count[trapno & 7]++;
         }
+#endif
+#if defined(_LOADABLE_VM86_) && defined(USE_MHPDBG)
+	if ( (trapno==3) || (trapno==1) ) return_to_32bit(regs, VM86_TRAP + (trapno << 8));
 #endif
 	do_int(regs, trapno, (unsigned char *) (regs->ss << 4), SP(regs));
 	return;
diff -urN dosemu-0.60.4.2-clean/include/Makefile dosemu/include/Makefile
--- dosemu-0.60.4.2-clean/include/Makefile	Wed Sep 13 02:48:07 1995
+++ dosemu/include/Makefile	Sat Sep 16 18:42:17 1995
@@ -8,7 +8,7 @@
 	serial.h slang.h syscallmgr.h termio.h timers.h video.h xms.h \
 	macros86.h vc.h extern.h int.h shared.h pktdrvr.h dos2linux.h \
 	ldt.h pic.h bitops.h vm86plus.h gcursor.h kernel_space.h \
-	sound.h dma.h
+	sound.h dma.h mhpdbg.h
 
 OBJS =
 
diff -urN dosemu-0.60.4.2-clean/include/mhpdbg.h dosemu/include/mhpdbg.h
--- dosemu-0.60.4.2-clean/include/mhpdbg.h	Thu Jan  1 01:00:00 1970
+++ dosemu/include/mhpdbg.h	Sat Sep 16 18:34:41 1995
@@ -0,0 +1,96 @@
+/*
+ * DOSEMU debugger,  1995 Max Parke <mhp@light.lightlink.com>
+ *
+ * This is file mhpdbg.h
+ *
+ * changes:
+ *
+ *   16Sep95 Hans Lermen <lermen@elserv.ffm.fgan.de>
+ */
+
+#ifndef MHPDBG_H
+#define MHPDBG_H
+
+#include "extern.h"
+
+#if 0  /* now defined in include/vm86plus */
+#define VM86_TRAP 4	  /* (vm86 return) TRAP */
+#endif
+
+#define DBG_INIT 0
+#define DBG_INTx 1
+#define DBG_TRAP 2
+#define DBG_POLL 3
+#define DBG_GPF  4
+
+unsigned int mhp_debug(unsigned int, unsigned int, unsigned int);
+void mhp_send(void);
+void mhp_input();
+void mhp_close();
+ 
+#define MHP_BUFFERSIZE 8192
+struct mhpdbg
+{
+   unsigned char sendbuf[MHP_BUFFERSIZE];
+   unsigned char recvbuf[MHP_BUFFERSIZE];
+   int sendptr;
+   int nbytes;
+   int active;
+
+   int fdin,fdout;
+};
+
+EXTERN struct mhpdbg mhpdbg;
+
+
+#ifdef MHP_PRIVATE
+
+#define DBG_TYPE(val)	       ((val) & 0xff)
+#define DBG_ARG(val)	       ((val) >> 8)
+#define SRSIZE MHP_BUFFERSIZE
+#define MYPORT 3456
+#define IBUFS 100
+#define MAXARG 16
+#define MAXBP 64
+#define MAXSYM 3500
+
+void mhp_printf(const char *,...);
+void mhp_cmd(const char *);
+void mhp_bpset(void);
+void mhp_bpclr(void);
+int  mhp_bpchk(unsigned char *);
+
+struct brkentry {
+   unsigned char * brkaddr;
+   unsigned char opcode;
+};
+
+struct cmd_db {
+   char cmdname[12];
+   void (*cmdproc)(int, char *[]);
+};
+
+struct mhpdbgc
+{
+   int stopped;
+   int currcode;
+   int trapcmd;
+   char intxxtab[256];
+   struct brkentry brktab[MAXBP];
+};
+
+struct symbol_entry {
+   unsigned int  addr;
+   unsigned char type;
+   unsigned char name[49];
+};
+
+struct symbl2_entry {
+   unsigned short seg;
+   unsigned short off;
+   unsigned char type;
+   unsigned char name[49];
+};
+#endif	 /* MHP_PRIVATE */
+
+#endif	 /* MHPDBG_H */
diff -urN dosemu-0.60.4.2-clean/include/vm86plus.h dosemu/include/vm86plus.h
--- dosemu-0.60.4.2-clean/include/vm86plus.h	Wed Sep 13 02:48:07 1995
+++ dosemu/include/vm86plus.h	Sat Sep 16 18:34:41 1995
@@ -9,6 +9,8 @@
 	long vm86plus_magic;
 	long dosemuver;      /* format 53058 = 0.53.58 or 1002003 = 1.2.3 */
         unsigned long force_return_for_pic:1;
+        unsigned long mhpdbg_active:1; /* for debugger */
+        unsigned char mhpdbg_intxxtab[32];   /* for debugger */
 };
 
 struct vm86plus_struct {
@@ -32,7 +34,9 @@
  */
 #define VM86_PICRETURN  4     /* return due to pending PIC request */
 #define VM86_STACKVERIFY 5    /* return due to failed stack verify_area */
-
+#ifdef USE_MHPDBG
+#define VM86_TRAP	6     /* return due to DOS-debugger request */
+#endif
 /*
  * This is how vm86() should be called, if using vm86plus
  *
