--- makefile.~1~	2006-07-07 14:50:52.000000000 -0400
+++ makefile	2008-05-01 10:43:20.000000000 -0400
@@ -83,7 +83,8 @@
 	${PDP11D}pdp11_ry.c ${PDP11D}pdp11_pt.c ${PDP11D}pdp11_hk.c \
 	${PDP11D}pdp11_xq.c ${PDP11D}pdp11_xu.c ${PDP11D}pdp11_vh.c \
 	${PDP11D}pdp11_rh.c ${PDP11D}pdp11_tu.c ${PDP11D}pdp11_cpumod.c \
-	${PDP11D}pdp11_cr.c ${PDP11D}pdp11_rf.c ${PDP11D}pdp11_dl.c
+	${PDP11D}pdp11_cr.c ${PDP11D}pdp11_rf.c ${PDP11D}pdp11_dl.c \
+	${PDP11D}pdp11_ke.c
 PDP11_OPT = -DVM_PDP11 -I ${PDP11D} ${NETWORK_OPT}
 
 
--- PDP11/pdp11_defs.h.~1~	2006-07-06 11:33:30.000000000 -0400
+++ PDP11/pdp11_defs.h	2008-05-01 11:12:57.000000000 -0400
@@ -561,6 +561,8 @@
 #define IOLN_RX         004
 #define IOBA_RY         (IOPAGEBASE + 017170)           /* RY11 */
 #define IOLN_RY         004
+#define IOBA_KE         (IOPAGEBASE + 017300)           /* KE11 */
+#define IOLN_KE         020
 #define IOBA_TC         (IOPAGEBASE + 017340)           /* TC11 */
 #define IOLN_TC         012
 #define IOBA_RK         (IOPAGEBASE + 017400)           /* RK11 */
--- PDP11/pdp11_ke.c.~0~	1969-12-31 19:00:00.000000000 -0500
+++ PDP11/pdp11_ke.c	2008-05-04 15:08:14.000000000 -0400
@@ -0,0 +1,296 @@
+/* pdp11_ke.c: 
+
+   Copyright (c) 1993-2005, Robert M Supnik
+
+   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
+   ROBERT M SUPNIK 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 Robert M Supnik shall not be
+   used in advertising or otherwise to promote the sale, use or other dealings
+   in this Software without prior written authorization from Robert M Supnik.
+
+   Some of this code is lifted directly from Tim Shoppa's KE11A code in apout,
+   Brad Parker <brad@heeltoe.com> 5/2008
+
+   01-May-08    JBP     cloned from pdp11_pt.c
+*/
+
+#include "pdp11_defs.h"
+//#define PT_DIS          0
+extern int32 int_req[IPL_HLVL];
+
+static int32 AC;
+static int32 MQ;
+static int32 SC;
+static int32 SR;
+
+DEVICE ke_dev;
+t_stat ke_rd (int32 *data, int32 PA, int32 access);
+t_stat ke_wr (int32 data, int32 PA, int32 access);
+t_stat ke_svc (UNIT *uptr);
+t_stat ke_reset (DEVICE *dptr);
+t_stat ke_attach (UNIT *uptr, char *ptr);
+t_stat ke_detach (UNIT *uptr);
+
+
+DIB ke_dib = { IOBA_KE, IOLN_KE, &ke_rd, &ke_wr, 0 };
+
+UNIT ke_unit = {
+	UDATA (&ke_svc, UNIT_DISABLE, 0)
+    };
+
+REG ke_reg[] = {
+      { ORDATA (KE_AC, AC, 16) },
+      { ORDATA (KE_MQ, MQ, 16) },
+      { ORDATA (KE_SC, SC, 16) },
+      { ORDATA (KE_SR, SR, 16) },
+    { NULL }
+    };
+
+MTAB ke_mod[] = {
+    { MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
+      NULL, &show_addr, NULL },
+    { MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
+      NULL, &show_vec, NULL },
+    { 0 }
+    };
+
+DEVICE ke_dev = {
+    "KE", &ke_unit, ke_reg, ke_mod,
+    1, 10, 31, 1, DEV_RDX, 8,
+    NULL, NULL, &ke_reset,
+    NULL, &ke_attach, &ke_detach,
+    &ke_dib, DEV_DISABLE | /*PT_DIS |*/ DEV_UBUS | DEV_QBUS
+    };
+
+/* KE11A I/O address offsets 0177300 - 0177316 */
+
+#define KE_DIV	000/* Divide */
+#define KE_AC	002/* Accumulator */
+#define KE_MQ	004/* MQ */
+#define KE_MUL	006/* Multiply */
+#define KE_SC	010/* Step counter */
+#define KE_SR	011/* Status register */
+#define KE_NOR	012/* Normalize */
+#define KE_LSH	014/* Logical shift */
+#define KE_ASH	016/* Arithmetic shift */
+
+/* Stolen from Tim Shoppa's KE11A in apout */
+void set_SR(void)
+{
+SR = SR & 0301;/* clear the result bits we can set here */
+if (((MQ & 0100000) == 0) && (AC == 0)) SR = SR | 002;
+if (((MQ & 0100000) == 0100000) && (AC == 0177777)) SR = SR | 002;
+
+if ((AC == 0) && (MQ == 0)) SR = SR | 0004;
+if (MQ == 0) SR = SR | 0010;
+if (AC == 0) SR = SR | 0020;
+if (AC == 0177777) SR = SR | 0040;
+}
+
+t_stat ke_rd (int32 *data, int32 PA, int32 access)
+{
+switch (PA & 077) {                               /* decode PA<5:0> */
+
+    case KE_AC:
+        *data = AC;
+        return SCPE_OK;
+    case KE_MQ:
+        *data = MQ;
+        return SCPE_OK;
+    case KE_NOR:
+        *data = SC;
+        return SCPE_OK;
+    case KE_SC:
+        set_SR();
+        *data = (SR << 8) | SC;
+        return SCPE_OK;
+    case KE_SR:
+        set_SR();
+        *data = (SR << 8);
+        return SCPE_OK;
+
+    case KE_DIV:
+    case KE_MUL:
+    case KE_LSH:
+    case KE_ASH:
+        *data = 0;
+        return SCPE_OK;
+        }
+
+return SCPE_NXM;                                        /* can't get here */
+}
+
+t_stat ke_wr (int32 data, int32 PA, int32 access)
+{
+  int32 divisor, quotient, remainder;
+  int32 dividend, product;
+  int32 oldMQ;
+
+switch (PA & 077) {                               /* decode PA<5:0> */
+
+    case KE_DIV:
+      SC = 0;
+      dividend = (AC << 16) | MQ;
+      divisor = data;
+      if (divisor >> 15) divisor = divisor | ~077777;
+      quotient = dividend / divisor;
+      MQ = quotient & 0177777;
+      remainder = dividend % divisor;
+      AC = remainder & 0177777;
+      SR = SR & 076;
+      if ((quotient > 32767) || (quotient < -32768)) {	/* did we overflow? */
+	if (dividend < 0) SR = SR | 0100;
+	else SR = SR | 0200;
+      } else {
+	if (quotient < 0) SR = SR | 0300;
+      }
+      return SCPE_OK;
+
+    case KE_AC:
+      AC = data;
+      if ((access == WRITEB) & (data >> 7))
+	AC = AC | 0177400;
+      return SCPE_OK;
+
+    case KE_AC + 1:
+      printf("write to AC+1; data=%o", data);
+      AC = (AC & 0377) | (data << 8);
+      return SCPE_OK;
+
+    case KE_MQ:
+      MQ = data;
+      if ((access == WRITEB) & (data >> 7)) MQ = MQ | 0177400;
+      if (MQ >> 15) AC = 0177777;
+      else AC = 0;
+      return SCPE_OK;
+
+    case KE_MQ + 1:
+      printf("write to MQ+1; data=%o", data);
+      MQ = (MQ & 0377) | (data << 8);
+      if (MQ >> 15) AC = 0177777;
+      else AC = 0;
+      return SCPE_OK;
+
+    case KE_MUL:
+      SC = 0;
+      if (data >> 15) data = data | ~077777;
+      if (MQ >> 15) MQ = MQ | ~077777;
+      product = MQ * data;
+      MQ = product & 0177777;
+      AC = (product >> 16) & 0177777;
+      SR = SR & 076;
+      if (AC >> 15) SR = SR | 0300;	/* set sign bit if necessary */
+      return SCPE_OK;
+
+    case KE_SC:
+      if (access == WRITEB) return SCPE_OK;/* byte writes are no-ops */
+      SR = (data >> 8) & 0177777;
+      SC = data & 0000077;
+      return SCPE_OK;
+
+    case KE_SR:
+      return SCPE_OK;			/* this is a No-op */
+
+    case KE_NOR:			/* Normalize */
+      MQ = (AC << 16) | MQ;		/* 32-bit number to normalize in MQ */
+      for (SC = 0; SC < 31; SC++) {
+	if (MQ == (0140000 << 16))
+	  break;
+	if ((((MQ >> 30) & 3) == 1) || (((MQ >> 30) & 3) == 2))
+	  break;
+	MQ = MQ << 1;
+      }
+      printf("SC = %o\r\n", SC);
+      AC = (MQ >> 16) & 0177777;
+      MQ = MQ & 0177777;
+      return SCPE_OK;
+
+    case KE_LSH:			/* Logical shift */
+       MQ=(AC<<16)|MQ; 			/* Form a temporary 32-bit entity */
+       oldMQ=MQ & 0x80000000;		/* Save the sign bit for later */
+       SR=SR&0176; 			/* Clear overflow & carry bits */
+       data=data & 077;			/* Convert data from 6-bit */
+       if (data>31) {		
+	 data=64-data;			/* Shift in a -ve direction */
+         SR=SR|((MQ>>(data-1))&1);	/* Get the bit that went off the end */
+         MQ=MQ>>data; 			/* and do the right shift */
+       } else {				/* Else left shift */
+	 if ((MQ<<(data-1))&0x80000000) SR|=1; /* Get the bit off the end */
+	 MQ=MQ<<data;			/* and do the left shift */
+       }
+       oldMQ= oldMQ ^ MQ;		/* Any difference in sign bit? */
+       if (oldMQ & 0x80000000) SR|=0200;/* Yes, set the overflow bit */
+       AC=(MQ>>16)&0177777;		/* Save result in AC and MQ */
+       MQ=MQ&0177777;
+       set_SR();
+       return SCPE_OK;
+
+    case KE_ASH:			/* Arithmetic shift */
+       MQ=(AC<<16)|MQ; 			/* Form a temporary 32-bit entity */
+       oldMQ=MQ & 0x80000000;		/* Save the sign bit for later */
+       SR=SR&0176; 			/* Clear overflow & carry bits */
+       data=data & 077;			/* Convert data from 6-bit */
+       if (data>31) {		
+	 data=64-data;			/* Shift in a -ve direction */
+	 divisor=1 << data;		/* Work out the dividing factor */
+         SR=SR|((MQ>>(data-1))&1);	/* Get the bit that went off the end */
+         MQ=MQ/divisor; 		/* and do the right shift */
+       } else {				/* Else left shift */
+	 product=1 << data;		/* Work out the multiplying factor */
+	 if ((MQ<<(data-1))&0x80000000) SR|=1; /* Get the bit off the end */
+	 MQ=MQ*product;			/* and do the left shift */
+       }
+       oldMQ= oldMQ ^ MQ;		/* Any difference in sign bit? */
+       if (oldMQ & 0x80000000) SR|=0200;/* Yes, set the overflow bit */
+       AC=(MQ>>16)&0177777;		/* Save result in AC and MQ */
+       MQ=MQ&0177777;
+       set_SR();
+       return SCPE_OK;
+
+    }                                               /* end switch PA */
+
+return SCPE_NXM;                                        /* can't get here */
+}
+
+/* service */
+
+t_stat ke_svc (UNIT *uptr)
+{
+return SCPE_OK;
+}
+
+/* support routines */
+
+t_stat ke_reset (DEVICE *dptr)
+{
+ke_unit.buf = 0;
+sim_cancel (&ke_unit);                                 /* deactivate unit */
+return SCPE_OK;
+}
+
+t_stat ke_attach (UNIT *uptr, char *cptr)
+{
+t_stat reason;
+reason = attach_unit (uptr, cptr);
+return reason;
+}
+
+t_stat ke_detach (UNIT *uptr)
+{
+return detach_unit (uptr);
+}
--- PDP11/pdp11_sys.c.~1~	2006-07-14 15:20:48.000000000 -0400
+++ PDP11/pdp11_sys.c	2008-05-01 10:46:23.000000000 -0400
@@ -76,6 +76,7 @@
 extern DEVICE rk_dev;
 extern DEVICE rl_dev;
 extern DEVICE hk_dev;
+extern DEVICE ke_dev;
 extern DEVICE rx_dev;
 extern DEVICE ry_dev;
 extern DEVICE mba_dev[];
@@ -129,6 +130,7 @@
     &rk_dev,
     &rl_dev,
     &hk_dev,
+    &ke_dev,
     &rx_dev,
     &ry_dev,
     &rp_dev,
