diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h
index 0f54b110915f..7f23b8ea087d 100644
--- a/sys/amd64/include/cpufunc.h
+++ b/sys/amd64/include/cpufunc.h
@@ -30,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id: cpufunc.h,v 1.53 1996/07/23 07:45:19 asami Exp $
+ *	$Id: cpufunc.h,v 1.54 1996/08/01 20:29:28 wollman Exp $
  */
 
 /*
@@ -262,54 +262,6 @@ outw(u_int port, u_short data)
 	__asm __volatile("outw %0,%%dx" : : "a" (data), "d" (port));
 }
 
-#ifdef PC98
-#include <machine/spl.h>
-
-static inline u_char
-epson_inb(u_int port)
-{
-	u_char	data;
-
-	outb(0x43f, 0x42);
-	data = inb(port);
-	outb(0x43f, 0x40);
-	return (data);
-}
-
-static inline void
-epson_outb(u_int port, u_char data)
-{
-	outb(0x43f, 0x42);
-	outb(port,data);
-	outb(0x43f, 0x40);
-}
-
-static inline void
-epson_insw(u_int port, void *addr, size_t cnt)
-{
-	int	s;
-
-	s = splbio();
-	outb(0x43f, 0x42);
-	disable_intr();
-	insw((u_int)port, (void *)addr, (size_t)cnt);
-	outb(0x43f, 0x40);
-	splx(s);
-}
-
-static inline void
-epson_outsw(u_int port, void *addr, size_t cnt)
-{
-	int	s;
-
-	s = splbio();
-	outb(0x43f, 0x42);
-	disable_intr();
-	outsw((u_int)port, (void *)addr, (size_t)cnt);
-	outb(0x43f, 0x40);
-	splx(s);
-}
-#endif /* PC98 */
 
 static __inline void
 pmap_update(void)
diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98
index fb7d0d40a537..1d02c572541a 100644
--- a/sys/conf/files.pc98
+++ b/sys/conf/files.pc98
@@ -1,8 +1,9 @@
 # This file tells config what files go into building a kernel,
 # files marked standard are always included.
 #
-# modified for PC-9801 after:
-#	$Id: files.pc98,v 1.5 1996/09/04 09:52:08 asami Exp $
+# modified for PC-9801
+#
+#	$Id: files.i386,v 1.140 1996/09/11 19:53:30 phk Exp $
 #
 aic7xxx_asm			optional	ahc	device-driver	   \
 	dependency 	"$S/dev/aic7xxx/aic7xxx_asm.c"			   \
@@ -60,7 +61,7 @@ i386/i386/support.s		standard
 i386/i386/swtch.s		standard
 i386/i386/sys_machdep.c		standard
 pc98/i386/trap.c		standard
-pc98/i386/userconfig.c		standard
+pc98/i386/userconfig.c		optional	userconfig
 pc98/i386/vm_machdep.c		standard
 i386/ibcs2/ibcs2_fcntl.c	optional 	ibcs2
 i386/ibcs2/ibcs2_stat.c		optional 	ibcs2
diff --git a/sys/conf/options.pc98 b/sys/conf/options.pc98
index ebe3f3bf52ca..98c7223e0518 100644
--- a/sys/conf/options.pc98
+++ b/sys/conf/options.pc98
@@ -1,4 +1,4 @@
-#	$Id: options.pc98,v 1.2 1996/07/23 07:45:51 asami Exp $
+#	$Id: options.pc98,v 1.3 1996/09/10 09:37:14 asami Exp $
 BOUNCEPAGES		opt_bounce.h
 USER_LDT
 MATH_EMULATE		opt_math_emulate.h
@@ -9,7 +9,6 @@ COMPAT_LINUX		opt_dontuse.h
 
 SHOW_BUSYBUFS		opt_machdep.h
 PANIC_REBOOT_WAIT_TIME	opt_machdep.h
-LARGEMEM		opt_machdep.h
 MAXMEM			opt_machdep.h
 PERFMON			opt_perfmon.h
 AUTO_EOI_1		opt_auto_eoi.h
@@ -28,7 +27,13 @@ CLK_CALIBRATION_LOOP	  opt_clock.h
 CLK_USE_I8254_CALIBRATION opt_clock.h
 CLK_USE_I586_CALIBRATION  opt_clock.h
 
-SC_KEYBOARD_PROBE_WORKS	opt_syscons.h
+SC_KBD_PROBE_WORKS	opt_syscons.h
+MAXCONS			opt_syscons.h
+SLOW_VGA		opt_syscons.h
+XT_KEYBOARD		opt_syscons.h
 
 ATAPI			opt_atapi.h
 ATAPI_STATIC		opt_atapi.h
+
+USERCONFIG		opt_userconfig.h
+VISUAL_USERCONFIG	opt_userconfig.h
diff --git a/sys/dev/ic/ns16550.h b/sys/dev/ic/ns16550.h
index ff59757a5f73..dae85bcaf583 100644
--- a/sys/dev/ic/ns16550.h
+++ b/sys/dev/ic/ns16550.h
@@ -31,13 +31,25 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)ns16550.h	7.1 (Berkeley) 5/9/91
- *	$Id$
+ *	$Id: ns16550.h,v 1.2 1993/10/16 13:48:52 rgrimes Exp $
  */
 
 /*
  * NS16550 UART registers
  */
-
+#ifdef PC98
+#define	com_data	0x000	/* data register (R/W) */
+#define	com_dlbl	0x000	/* divisor latch low (W) */
+#define	com_dlbh	0x100	/* divisor latch high (W) */
+#define	com_ier		0x100	/* interrupt enable (W) */
+#define	com_iir		0x200	/* interrupt identification (R) */
+#define	com_fifo	0x200	/* FIFO control (W) */
+#define	com_lctl	0x300	/* line control register (R/W) */
+#define	com_cfcr	0x300	/* line control register (R/W) */
+#define	com_mcr		0x400	/* modem control register (R/W) */
+#define	com_lsr		0x500	/* line status register (R/W) */
+#define	com_msr		0x600	/* modem status register (R/W) */
+#else /* IBM-PC */
 #define	com_data	0	/* data register (R/W) */
 #define	com_dlbl	0	/* divisor latch low (W) */
 #define	com_dlbh	1	/* divisor latch high (W) */
@@ -49,3 +61,4 @@
 #define	com_mcr		4	/* modem control register (R/W) */
 #define	com_lsr		5	/* line status register (R/W) */
 #define	com_msr		6	/* modem status register (R/W) */
+#endif /* PC98 */
diff --git a/sys/i386/include/apm_bios.h b/sys/i386/include/apm_bios.h
index 3abdbd5cbf2f..8e2cbf64a443 100644
--- a/sys/i386/include/apm_bios.h
+++ b/sys/i386/include/apm_bios.h
@@ -12,7 +12,7 @@
  *
  * Aug, 1994	Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
  *
- *	$Id: apm_bios.h,v 1.9 1996/03/13 00:41:45 nate Exp $
+ *	$Id: apm_bios.h,v 1.10 1996/04/23 16:02:53 nate Exp $
  */
 
 #ifndef _MACHINE_APM_BIOS_H_
@@ -21,8 +21,13 @@
 #ifdef KERNEL
 
 /* BIOS id */
+#ifdef PC98
+#define APM_BIOS		0x9a
+#define SYSTEM_BIOS		0x1f
+#else
 #define APM_BIOS		0x53
 #define SYSTEM_BIOS		0x15
+#endif
 
 /* APM flags */
 #define APM_16BIT_SUPPORT	0x01
diff --git a/sys/i386/include/cpufunc.h b/sys/i386/include/cpufunc.h
index 0f54b110915f..7f23b8ea087d 100644
--- a/sys/i386/include/cpufunc.h
+++ b/sys/i386/include/cpufunc.h
@@ -30,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id: cpufunc.h,v 1.53 1996/07/23 07:45:19 asami Exp $
+ *	$Id: cpufunc.h,v 1.54 1996/08/01 20:29:28 wollman Exp $
  */
 
 /*
@@ -262,54 +262,6 @@ outw(u_int port, u_short data)
 	__asm __volatile("outw %0,%%dx" : : "a" (data), "d" (port));
 }
 
-#ifdef PC98
-#include <machine/spl.h>
-
-static inline u_char
-epson_inb(u_int port)
-{
-	u_char	data;
-
-	outb(0x43f, 0x42);
-	data = inb(port);
-	outb(0x43f, 0x40);
-	return (data);
-}
-
-static inline void
-epson_outb(u_int port, u_char data)
-{
-	outb(0x43f, 0x42);
-	outb(port,data);
-	outb(0x43f, 0x40);
-}
-
-static inline void
-epson_insw(u_int port, void *addr, size_t cnt)
-{
-	int	s;
-
-	s = splbio();
-	outb(0x43f, 0x42);
-	disable_intr();
-	insw((u_int)port, (void *)addr, (size_t)cnt);
-	outb(0x43f, 0x40);
-	splx(s);
-}
-
-static inline void
-epson_outsw(u_int port, void *addr, size_t cnt)
-{
-	int	s;
-
-	s = splbio();
-	outb(0x43f, 0x42);
-	disable_intr();
-	outsw((u_int)port, (void *)addr, (size_t)cnt);
-	outb(0x43f, 0x40);
-	splx(s);
-}
-#endif /* PC98 */
 
 static __inline void
 pmap_update(void)
diff --git a/sys/pc98/pc98/ic/i8251.h b/sys/i386/isa/ic/i8251.h
similarity index 100%
rename from sys/pc98/pc98/ic/i8251.h
rename to sys/i386/isa/ic/i8251.h
diff --git a/sys/i386/isa/ic/ns16550.h b/sys/i386/isa/ic/ns16550.h
index ff59757a5f73..dae85bcaf583 100644
--- a/sys/i386/isa/ic/ns16550.h
+++ b/sys/i386/isa/ic/ns16550.h
@@ -31,13 +31,25 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)ns16550.h	7.1 (Berkeley) 5/9/91
- *	$Id$
+ *	$Id: ns16550.h,v 1.2 1993/10/16 13:48:52 rgrimes Exp $
  */
 
 /*
  * NS16550 UART registers
  */
-
+#ifdef PC98
+#define	com_data	0x000	/* data register (R/W) */
+#define	com_dlbl	0x000	/* divisor latch low (W) */
+#define	com_dlbh	0x100	/* divisor latch high (W) */
+#define	com_ier		0x100	/* interrupt enable (W) */
+#define	com_iir		0x200	/* interrupt identification (R) */
+#define	com_fifo	0x200	/* FIFO control (W) */
+#define	com_lctl	0x300	/* line control register (R/W) */
+#define	com_cfcr	0x300	/* line control register (R/W) */
+#define	com_mcr		0x400	/* modem control register (R/W) */
+#define	com_lsr		0x500	/* line status register (R/W) */
+#define	com_msr		0x600	/* modem status register (R/W) */
+#else /* IBM-PC */
 #define	com_data	0	/* data register (R/W) */
 #define	com_dlbl	0	/* divisor latch low (W) */
 #define	com_dlbh	1	/* divisor latch high (W) */
@@ -49,3 +61,4 @@
 #define	com_mcr		4	/* modem control register (R/W) */
 #define	com_lsr		5	/* line status register (R/W) */
 #define	com_msr		6	/* modem status register (R/W) */
+#endif /* PC98 */
diff --git a/sys/pc98/pc98/ic/wd33c93.h b/sys/i386/isa/ic/wd33c93.h
similarity index 100%
rename from sys/pc98/pc98/ic/wd33c93.h
rename to sys/i386/isa/ic/wd33c93.h
diff --git a/sys/isa/ic/ns16550.h b/sys/isa/ic/ns16550.h
index ff59757a5f73..dae85bcaf583 100644
--- a/sys/isa/ic/ns16550.h
+++ b/sys/isa/ic/ns16550.h
@@ -31,13 +31,25 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)ns16550.h	7.1 (Berkeley) 5/9/91
- *	$Id$
+ *	$Id: ns16550.h,v 1.2 1993/10/16 13:48:52 rgrimes Exp $
  */
 
 /*
  * NS16550 UART registers
  */
-
+#ifdef PC98
+#define	com_data	0x000	/* data register (R/W) */
+#define	com_dlbl	0x000	/* divisor latch low (W) */
+#define	com_dlbh	0x100	/* divisor latch high (W) */
+#define	com_ier		0x100	/* interrupt enable (W) */
+#define	com_iir		0x200	/* interrupt identification (R) */
+#define	com_fifo	0x200	/* FIFO control (W) */
+#define	com_lctl	0x300	/* line control register (R/W) */
+#define	com_cfcr	0x300	/* line control register (R/W) */
+#define	com_mcr		0x400	/* modem control register (R/W) */
+#define	com_lsr		0x500	/* line status register (R/W) */
+#define	com_msr		0x600	/* modem status register (R/W) */
+#else /* IBM-PC */
 #define	com_data	0	/* data register (R/W) */
 #define	com_dlbl	0	/* divisor latch low (W) */
 #define	com_dlbh	1	/* divisor latch high (W) */
@@ -49,3 +61,4 @@
 #define	com_mcr		4	/* modem control register (R/W) */
 #define	com_lsr		5	/* line status register (R/W) */
 #define	com_msr		6	/* modem status register (R/W) */
+#endif /* PC98 */
diff --git a/sys/pc98/boot/Makefile b/sys/pc98/boot/Makefile
index c1899cc5eae3..db077c7c8f70 100644
--- a/sys/pc98/boot/Makefile
+++ b/sys/pc98/boot/Makefile
@@ -1,5 +1,5 @@
-#	$Id: Makefile,v 1.25 1995/04/15 08:24:33 phk Exp $
-
-SUBDIR=	biosboot netboot
+#	$Id: Makefile,v 1.26 1996/09/11 19:22:21 phk Exp $
+  
+SUBDIR=	biosboot kzipboot netboot rawboot
 
 .include <bsd.subdir.mk>
diff --git a/sys/pc98/boot/biosboot/Makefile b/sys/pc98/boot/biosboot/Makefile
index 5c8f17a739a6..dbc0a49be7eb 100644
--- a/sys/pc98/boot/biosboot/Makefile
+++ b/sys/pc98/boot/biosboot/Makefile
@@ -1,4 +1,4 @@
-#	$Id: Makefile,v 1.1.1.1 1996/06/14 10:04:37 asami Exp $
+#	$Id: Makefile,v 1.2 1996/07/23 07:45:33 asami Exp $
 #
 
 PROG=	boot
@@ -77,7 +77,9 @@ boot2:		boot.nohdr
 	dd if=boot.nohdr of=boot2 bs=512 skip=1
 	@dd if=boot2 skip=14 of=sizetest 2> /dev/null
 	@if [ -s sizetest ] ; then \
-		echo "*** Boot2 is too BIG ***" ; exit 2 ; \
+		echo "boot2 is too big" >&2 ; \
+		rm boot2 ; \
+		exit 2 ; \
 	fi
 
 all:		boot1 boot2
diff --git a/sys/pc98/boot/biosboot/boot.c b/sys/pc98/boot/biosboot/boot.c
index 924ca549d270..e7ba59d09609 100644
--- a/sys/pc98/boot/biosboot/boot.c
+++ b/sys/pc98/boot/biosboot/boot.c
@@ -24,7 +24,7 @@
  * the rights to redistribute these changes.
  *
  *	from: Mach, [92/04/03  16:51:14  rvb]
- *	$Id: boot.c,v 1.2 1996/07/23 07:45:35 asami Exp $
+ *	$Id: boot.c,v 1.3 1996/08/31 15:06:21 asami Exp $
  */
 
 
@@ -65,7 +65,6 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 char *dflt_name;
 #endif
 char namebuf[NAMEBUF_LEN];
-struct exec head;
 struct bootinfo bootinfo;
 int loadflags;
 
@@ -191,6 +190,7 @@ loadstart:
 static void
 loadprog(void)
 {
+	struct exec head;
 	long int startaddr;
 	long int addr;	/* physical address.. not directly useable */
 	long int bootdev;
@@ -357,6 +357,7 @@ nextarg:
 					*howto ^= RB_SERIAL;
 					if (*howto & RB_SERIAL)
 						init_serial();
+					continue;
 				}
 				if (c == 'g')
 					*howto |= RB_GDB;
diff --git a/sys/pc98/boot/biosboot/boot.h b/sys/pc98/boot/biosboot/boot.h
index a9cdb48224f1..305955ec3e99 100644
--- a/sys/pc98/boot/biosboot/boot.h
+++ b/sys/pc98/boot/biosboot/boot.h
@@ -24,7 +24,7 @@
  * the rights to redistribute these changes.
  *
  *	from: Mach, Revision 2.2  92/04/04  11:35:03  rpd
- *	$Id: boot.h,v 1.11 1995/06/25 14:02:52 joerg Exp $
+ *	$Id: boot.h,v 1.1.1.1 1996/06/14 10:04:37 asami Exp $
  */
 
 #include <sys/types.h>
@@ -69,8 +69,8 @@ void boot2(void);
 
 /* disk.c */
 int devopen(void);
-void devread(void);
-void Bread(int dosdev, int sector);
+void devread(char *iodest, int sector, int cnt);
+char * Bread(int dosdev, int sector);
 int badsect(int dosdev, int sector);
 
 /* io.c */
diff --git a/sys/pc98/boot/biosboot/disk.c b/sys/pc98/boot/biosboot/disk.c
index 4520fccb6a56..348757edc841 100644
--- a/sys/pc98/boot/biosboot/disk.c
+++ b/sys/pc98/boot/biosboot/disk.c
@@ -24,7 +24,7 @@
  * the rights to redistribute these changes.
  *
  *	from: Mach, Revision 2.2  92/04/04  11:35:49  rpd
- *	$Id: disk.c,v 1.1.1.1 1996/06/14 10:04:37 asami Exp $
+ *	$Id: disk.c,v 1.2 1996/07/23 07:45:36 asami Exp $
  */
 
 /*
@@ -63,15 +63,12 @@ int bsize;
 
 int spt, spc;
 
-char *iodest;
 struct fs *fs;
 struct inode inode;
-int dosdev, unit, slice, part, maj, boff, poff, bnum, cnt;
+int dosdev, unit, slice, part, maj, boff, poff;
 
 /*#define EMBEDDED_DISKLABEL 1*/
 
-#define I_ADDR		((void *) 0)	/* XXX where all reads go */
-
 /* Read ahead buffer large enough for one track on a 1440K floppy.  For
  * reading from floppies, the bootstrap has to be loaded on a 64K boundary
  * to ensure that this buffer doesn't cross a 64K DMA boundary.
@@ -88,14 +85,13 @@ devopen(void)
 {
 	struct dos_partition *dptr;
 	struct disklabel *dl;
-	int dosdev = inode.i_dev;
+	char *p;
 	int i, sector = 0, di;
-#if 0   /* Save space, already have hard error for cyl > 1023 in Bread */
-	u_long bend;
-#endif
 
 	di = get_diskinfo(dosdev);
 	spc = (spt = SPT(di)) * HEADS(di);
+
+#ifndef RAWBOOT
 	if ((dosdev & 0xf0) == 0x90)
 	{
 		boff = 0;
@@ -107,7 +103,7 @@ devopen(void)
 		dl = &disklabel;
 #else	EMBEDDED_DISKLABEL
 #ifdef PC98
-		Bread(dosdev, 1);
+		p = Bread(dosdev, 1);
 		dptr = (struct dos_partition *)0;
 		slice = WHOLE_DISK_SLICE;
 		for (i = 0; i < NDOSPART; i++, dptr++)
@@ -120,8 +116,8 @@ devopen(void)
 		dl=((struct disklabel *)0);
 		disklabel = *dl;	/* structure copy (maybe useful later)*/
 #else
-		Bread(dosdev, 0);
-		dptr = (struct dos_partition *)(((char *)0)+DOSPARTOFF);
+		p = Bread(dosdev, 0);
+		dptr = (struct dos_partition *)(p+DOSPARTOFF);
 		slice = WHOLE_DISK_SLICE;
 		for (i = 0; i < NDOSPART; i++, dptr++)
 			if (dptr->dp_typ == DOSPTYP_386BSD) {
@@ -129,8 +125,8 @@ devopen(void)
 				sector = dptr->dp_start;
 				break;
 			}
-		Bread(dosdev, sector + LABELSECTOR);
-		dl=((struct disklabel *)0);
+		p = Bread(dosdev, sector + LABELSECTOR);
+		dl=((struct disklabel *)p);
 		disklabel = *dl;	/* structure copy (maybe useful later)*/
 #endif /* PC98 */
 #endif	EMBEDDED_DISKLABEL
@@ -156,11 +152,6 @@ devopen(void)
 #ifndef PC98
 		/* This is a good idea for all disks */
 		bsize = dl->d_partitions[part].p_size;
-#if 0   /* Save space, already have hard error for cyl > 1023 in Bread */
-		bend = boff + bsize - 1 ;
-		if (bend / spc >= 1024) {
-			printf("boot partition end >= cyl 1024, BIOS can't load kernel stored beyond this limit\n");
-#endif
 #endif
 
 #ifdef DO_BAD144
@@ -193,8 +184,8 @@ devopen(void)
 		    do_bad144 = 0;
 		    do {
 			/* XXX: what if the "DOS sector" < 512 bytes ??? */
-			Bread(dosdev, dkbbnum + i);
-			dkbptr = (struct dkbad *) 0;
+			p = Bread(dosdev, dkbbnum + i);
+			dkbptr = (struct dkbad *) p;
 /* XXX why is this not in <sys/dkbad.h> ??? */
 #define DKBAD_MAGIC 0x4321
 			if (dkbptr->bt_mbz == 0 &&
@@ -210,24 +201,31 @@ devopen(void)
 		    else
 		      printf("Using bad sector table at %d\n", dkbbnum+i);
 		}
-#endif DO_BAD144
+#endif /* DO_BAD144 */
 	}
+#endif /* RAWBOOT */
 	return 0;
 }
 
+
+/*
+ * Be aware that cnt is rounded up to N*BPS
+ */
 void
-devread(void)
+devread(char *iodest, int sector, int cnt)
 {
-	int offset, sector = bnum;
-	int dosdev = inode.i_dev;
+	int offset;
+	char *p;
+
 	for (offset = 0; offset < cnt; offset += BPS)
 	{
-		Bread(dosdev, badsect(dosdev, sector++));
-		bcopy(0, iodest+offset, BPS);
+		p = Bread(dosdev, badsect(dosdev, sector++));
+		bcopy(p, iodest+offset, BPS);
 	}
 }
 
-void
+
+char *
 Bread(int dosdev, int sector)
 {
 	if (dosdev != ra_dev || sector < ra_first || sector >= ra_end)
@@ -260,14 +258,14 @@ Bread(int dosdev, int sector)
 		ra_first = sector;
 		ra_end = sector + nsec;
 	}
-	bcopy(ra_buf + (sector - ra_first) * BPS, I_ADDR, BPS);
+	return (ra_buf + (sector - ra_first) * BPS);
 }
 
 int
 badsect(int dosdev, int sector)
 {
+#if defined(DO_BAD144) && !defined(RAWBOOT)
 	int i;
-#ifdef DO_BAD144
 	if (do_bad144) {
 		u_short cyl;
 		u_short head;
@@ -316,7 +314,7 @@ badsect(int dosdev, int sector)
 		newsec -= dl->d_nsectors + i + 1;
 		return newsec;
 	}
-#endif DO_BAD144
   no_remap:
+#endif 
 	return sector;
 }
diff --git a/sys/pc98/boot/biosboot/io.c b/sys/pc98/boot/biosboot/io.c
index 7f09b2406aaa..d127580a0dc9 100644
--- a/sys/pc98/boot/biosboot/io.c
+++ b/sys/pc98/boot/biosboot/io.c
@@ -31,7 +31,7 @@
 #include <machine/cpufunc.h>
 #include <sys/reboot.h>
 #ifdef PC98
-#include "../../pc98/pc98_bios.h"
+#include "../../pc98/pc98.h"
 #endif
 
 
diff --git a/sys/pc98/boot/biosboot/sys.c b/sys/pc98/boot/biosboot/sys.c
index 795b2c21043d..90c8def0f7e1 100644
--- a/sys/pc98/boot/biosboot/sys.c
+++ b/sys/pc98/boot/biosboot/sys.c
@@ -5,7 +5,7 @@
  *
  * Permission to use, copy, modify and distribute this software and its
  * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
+e* notice and this permission notice appear in all copies of the
  * software, derivative works or modified versions, and any portions
  * thereof, and that both notices appear in supporting documentation.
  *
@@ -24,7 +24,7 @@
  * the rights to redistribute these changes.
  *
  *	from: Mach, Revision 2.2  92/04/04  11:36:34  rpd
- *	$Id: sys.c,v 1.1.1.1 1996/06/14 10:04:37 asami Exp $
+ *	$Id: sys.c,v 1.2 1996/08/31 15:06:24 asami Exp $
  */
 
 /*
@@ -51,6 +51,10 @@ char buf[BUFSIZE], fsbuf[BUFSIZE], iobuf[BUFSIZE];
 char mapbuf[MAPBUFSIZE];
 int mapblock;
 
+#ifdef RAWBOOT
+#define STARTBYTE	8192	/* Where on the media the kernel starts */
+#endif
+
 void
 xread(char *addr, int size)
 {
@@ -65,6 +69,7 @@ xread(char *addr, int size)
 	}
 }
 
+#ifndef RAWBOOT
 void
 read(char *buffer, int count)
 {
@@ -76,43 +81,67 @@ read(char *buffer, int count)
 		logno = lblkno(fs, poff);
 		cnt2 = size = blksize(fs, &inode, logno);
 		bnum2 = fsbtodb(fs, block_map(logno)) + boff;
-		cnt = cnt2;
-		bnum = bnum2;
-		if (	(!off)  && (size <= count))
-		{
-			iodest = buffer;
-			devread();
-		}
-		else
-		{
-			iodest = iobuf;
+		if (	(!off)  && (size <= count)) {
+			devread(buffer, bnum2, cnt2);
+		} else {
 			size -= off;
 			if (size > count)
 				size = count;
-			devread();
-			bcopy(iodest+off,buffer,size);
+			devread(iobuf, bnum2, cnt2);
+			bcopy(iobuf+off, buffer, size);
 		}
 		buffer += size;
 		count -= size;
 		poff += size;
 	}
 }
+#else
+void
+read(char *buffer, int count)
+{
+	int cnt, bnum, off, size;
 
+	off = STARTBYTE + poff;
+	poff += count;
+
+	/* Read any unaligned bit at the front */
+	cnt = off & 511;
+	if (cnt) {
+		size = 512-cnt;
+		if (count < size)
+			size = count;
+		devread(iobuf, off >> 9, 512);
+		bcopy(iobuf+cnt, buffer, size);
+		count -= size;
+		off += size;
+		buffer += size;
+	}
+	size = count & (~511);
+	if (size && (off & (~511))) {
+		devread(buffer, off >> 9, size);
+		off += size;
+		count -= size;
+		buffer += size;
+	}
+	if (count) {
+		devread(iobuf, off >> 9, 512);
+		bcopy(iobuf, buffer, count);
+	}
+}
+
+#endif
 int
 find(char *path)
 {
 	char *rest, ch;
 	int block, off, loc, ino = ROOTINO;
 	struct direct *dp;
-	int list_only = 0;
+	char list_only;
 
-	if (strcmp("?", path) == 0)
-		list_only = 1;
-loop:	iodest = iobuf;
-	cnt = fs->fs_bsize;
-	bnum = fsbtodb(fs,ino_to_fsba(fs,ino)) + boff;
-	devread();
-	bcopy((void *)&((struct dinode *)iodest)[ino % fs->fs_inopb],
+	list_only = (path[0] == '?' && path[1] == '\0');
+loop:
+	devread(iobuf, fsbtodb(fs, ino_to_fsba(fs, ino)) + boff, fs->fs_bsize);
+	bcopy((void *)&((struct dinode *)iobuf)[ino % fs->fs_inopb],
 	      (void *)&inode.i_din,
 	      sizeof (struct dinode));
 	if (!*path)
@@ -127,7 +156,7 @@ loop:	iodest = iobuf;
 	do {
 		if (loc >= inode.i_size) {
 			if (list_only) {
-				printf("\n");
+				putchar('\n');
 				return -1;
 			} else {
 				return 0;
@@ -135,12 +164,10 @@ loop:	iodest = iobuf;
 		}
 		if (!(off = blkoff(fs, loc))) {
 			block = lblkno(fs, loc);
-			cnt = blksize(fs, &inode, block);
-			bnum = fsbtodb(fs, block_map(block)) + boff;
-			iodest = iobuf;
-			devread();
+			devread(iobuf, fsbtodb(fs, block_map(block)) + boff,
+				blksize(fs, &inode, block));
 		}
-		dp = (struct direct *)(iodest + off);
+		dp = (struct direct *)(iobuf + off);
 		loc += dp->d_reclen;
 		if (dp->d_ino && list_only)
 			printf("%s ", dp->d_name);
@@ -154,12 +181,11 @@ loop:	iodest = iobuf;
 int
 block_map(int file_block)
 {
+	int bnum;
 	if (file_block < NDADDR)
 		return(inode.i_db[file_block]);
 	if ((bnum=fsbtodb(fs, inode.i_ib[0])+boff) != mapblock) {
-		iodest = mapbuf;
-		cnt = fs->fs_bsize;
-		devread();
+		devread(mapbuf, bnum, fs->fs_bsize);
 		mapblock = bnum;
 	}
 	return (((int *)mapbuf)[(file_block - NDADDR) % NINDIR(fs)]);
@@ -192,11 +218,11 @@ openrd(void)
 		 * Look for a BIOS drive number (a leading digit followed
 		 * by a colon).
 		 */
+		biosdrivedigit = '\0';
 		if (*(name + 1) == ':' && *name >= '0' && *name <= '9') {
 			biosdrivedigit = *name;
 			name += 2;
-		} else
-			biosdrivedigit = '\0';
+		}
 
 		if (cp++ != name)
 		{
@@ -232,9 +258,8 @@ openrd(void)
 		if (!*cp)
 			return 1;
 	}
-	if (biosdrivedigit != '\0')
-		biosdrive = biosdrivedigit - '0';
-	else {
+	biosdrive = biosdrivedigit - '0';
+	if (biosdrivedigit == '\0') {
 		biosdrive = unit;
 #if BOOT_HD_BIAS > 0
 		/* XXX */
@@ -269,7 +294,6 @@ openrd(void)
 	}
 	printf("dosdev = %x, biosdrive = %d, unit = %d, maj = %d\n",
 		dosdev, biosdrive, unit, maj);
-	inode.i_dev = dosdev;
 
 	/***********************************************\
 	* Now we know the disk unit and part,		*
@@ -278,20 +302,21 @@ openrd(void)
 	if (devopen())
 		return 1;
 
+#ifndef RAWBOOT
 	/***********************************************\
 	* Load Filesystem info (mount the device)	*
 	\***********************************************/
-	iodest = (char *)(fs = (struct fs *)fsbuf);
-	cnt = SBSIZE;
-	bnum = SBLOCK + boff;
-	devread();
+	devread((char *)(fs = (struct fs *)fsbuf), SBLOCK + boff, SBSIZE);
 	/***********************************************\
 	* Find the actual FILE on the mounted device	*
 	\***********************************************/
 	ret = find(cp);
-	if (ret <= 0)
-		return (ret == 0) ? 1 : -1;
+	if (ret == 0)
+		return 1;
+	if (ret < 0)
+		return -1;
 	poff = 0;
 	name = cp;
+#endif /* RAWBOOT */
 	return 0;
 }
diff --git a/sys/pc98/boot/rawboot/Makefile b/sys/pc98/boot/rawboot/Makefile
new file mode 100644
index 000000000000..4f12ed4e4037
--- /dev/null
+++ b/sys/pc98/boot/rawboot/Makefile
@@ -0,0 +1,84 @@
+#	$Id: Makefile,v 1.1 1996/09/11 19:25:11 phk Exp $
+#
+
+PROG=	boot
+
+# Order is very important on the SRCS line for this prog
+SRCS=	start.S table.c boot2.S boot.c asm.S bios.S serial.S
+SRCS+=  probe_keyboard.c io.c disk.c sys.c
+
+.PATH:	${.CURDIR}/../biosboot
+
+BINDIR=		/usr/mdec
+BINMODE=	444
+CFLAGS=         -O2 \
+		-DPC98 \
+		-DRAWBOOT \
+		-I${.CURDIR}/../biosboot \
+		-DBOOTWAIT=${BOOTWAIT} -DTIMEOUT=${TIMEOUT}
+CFLAGS+=	-DCOMCONSOLE=0x30 -DCOMCONSOLE_CLK=16 -DCOMCONSOLE_MODE=0x0c
+CFLAGS+=	-DBOOTSEG=${BOOTSEG} -DBOOTSTACK=${BOOTSTACK}
+
+# Probe the keyboard and use the serial console if the keyboard isn't found.
+#CFLAGS+=	-DPROBE_KEYBOARD
+
+# Force use of the serial console (after probing the keyboard if
+# PROBE_KEYBOARD is defined).
+#CFLAGS+=	-DFORCE_COMCONSOLE
+
+# Enable code to take the default boot string from a fixed location on the
+# disk.  See nextboot(8) and README.386BSD for more info.
+#CFLAGS+=	-DNAMEBLOCK
+#CFLAGS+=	-DNAMEBLOCK_WRITEBACK
+
+# Bias the conversion from the BIOS drive number to the FreeBSD unit number
+# for hard disks.  This may be useful for people booting in a mixed IDE/SCSI
+# environment (set BOOT_HD_BIAS to the number of IDE drives).
+#CFLAGS+=	-DBOOT_HD_BIAS=1
+#
+# Details: this only applies if BOOT_HD_BIAS > 0.  If the BIOS drive number
+# for the boot drive is >= BOOT_HD_BIAS, then the boot drive is assumed to
+# be SCSI and have unit number (BIOS_drive_number - BOOT_HD_BIAS).  E.g.,
+# BOOT_HD_BIAS=1 makes BIOS drive 1 correspond to 1:sd(0,a) instead of
+# 1:wd(1,a).  If `sd' is given explicitly, then the drive is assumed to be
+# SCSI and have BIOS drive number (sd_unit_number + BOOT_HD_BIAS).  E.g.,
+# BOOT_HD_BIAS=1 makes sd(0,a) correspond to 1:sd(0,a) instead of 0:sd(0,a).
+
+CLEANFILES+=	boot.nohdr boot.strip rawboot sizetest
+DPADD=		${LIBC}
+LDFLAGS+=	-N -T 0 -nostdlib
+LDADD=		-lc
+NOSHARED=	YES
+NOMAN=
+STRIP=
+
+# tunable timeout parameter, waiting for keypress, calibrated in ms
+BOOTWAIT?=	5000
+# tunable timeout during string input, calibrated in ms
+#TIMEOUT?=	30000
+
+# Location that boot2 is loaded at
+BOOTSEG=	0x9000
+
+# Offset in BOOTSEG for the top of the stack, keep this 16 byte aligned
+BOOTSTACK=	0xFFF0
+
+boot.strip:	boot
+	cp -p boot boot.strip
+	strip boot.strip
+	size boot.strip
+
+boot.nohdr:	boot.strip
+	dd if=boot.strip of=boot.nohdr ibs=32 skip=1 obs=1024b
+	ls -l boot.nohdr
+
+rawboot:	boot.nohdr
+	dd if=boot.nohdr of=rawboot bs=8k count=1 conv=sync
+
+all:		rawboot 
+
+install:
+	${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE}\
+		rawboot ${DESTDIR}${BINDIR}/rawboot
+
+.include <bsd.prog.mk>
diff --git a/sys/pc98/boot/rawboot/README b/sys/pc98/boot/rawboot/README
new file mode 100644
index 000000000000..4cf51f0c60ad
--- /dev/null
+++ b/sys/pc98/boot/rawboot/README
@@ -0,0 +1,17 @@
+RAWboot readme.
+
+This is a dumber version of the code in biosboot.
+
+The intended usage is:
+
+	cat /usr/mdec/rawboot /sys/compile/FOO/kernel | fdwrite
+
+This makes it a lot easier to make a bootable floppy, and saves space
+on the floppy to boot.
+
+Of course the name you enter for the kernel isn't used...  Then again
+if you know how to make two kernels fit a floppy and have a use for
+it, you don't need this bootblock.
+
+Poul-Henning Kamp
+phk@FreeBSD.org
diff --git a/sys/pc98/cbus/cbus.h b/sys/pc98/cbus/cbus.h
index 79614792fc6e..edc90330f1fa 100644
--- a/sys/pc98/cbus/cbus.h
+++ b/sys/pc98/cbus/cbus.h
@@ -34,7 +34,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)isa.h	5.7 (Berkeley) 5/9/91
- *	$Id: pc98.h,v 1.2 1996/09/03 10:23:48 asami Exp $
+ *	$Id: pc98.h,v 1.3 1996/09/10 09:38:21 asami Exp $
  */
 
 #ifndef _PC98_PC98_PC98_H_
@@ -213,6 +213,53 @@ extern unsigned char	pc98_system_parameter[]; /* in locore.c */
 #define epson_system_type	(pc98_system_parameter[OFS_epson_system_type])
 
 # define PC98_TYPE_CHECK(x)	((pc98_machine_type & (x)) == (x))
+
+#include <machine/spl.h>
+
+static inline u_char
+epson_inb(u_int port)
+{
+	u_char	data;
+
+	outb(0x43f, 0x42);
+	data = inb(port);
+	outb(0x43f, 0x40);
+	return (data);
+}
+
+static inline void
+epson_outb(u_int port, u_char data)
+{
+	outb(0x43f, 0x42);
+	outb(port,data);
+	outb(0x43f, 0x40);
+}
+
+static inline void
+epson_insw(u_int port, void *addr, size_t cnt)
+{
+	int	s;
+
+	s = splbio();
+	outb(0x43f, 0x42);
+	disable_intr();
+	insw((u_int)port, (void *)addr, (size_t)cnt);
+	outb(0x43f, 0x40);
+	splx(s);
+}
+
+static inline void
+epson_outsw(u_int port, void *addr, size_t cnt)
+{
+	int	s;
+
+	s = splbio();
+	outb(0x43f, 0x42);
+	disable_intr();
+	outsw((u_int)port, (void *)addr, (size_t)cnt);
+	outb(0x43f, 0x40);
+	splx(s);
+}
 #endif /* KERNEL */
 
 /*
diff --git a/sys/pc98/cbus/sio.c b/sys/pc98/cbus/sio.c
index c14452401862..aacf54c0617e 100644
--- a/sys/pc98/cbus/sio.c
+++ b/sys/pc98/cbus/sio.c
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)com.c	7.5 (Berkeley) 5/16/91
- *	$Id: sio.c,v 1.5 1996/09/07 02:14:23 asami Exp $
+ *	$Id: sio.c,v 1.6 1996/09/10 09:38:34 asami Exp $
  */
 
 #include "opt_comconsole.h"
@@ -141,18 +141,17 @@
 #include <i386/isa/icu.h>
 #include <i386/isa/isa_device.h>
 #include <pc98/pc98/sioreg.h>
-#include <pc98/pc98/ic/i8251.h>
-#include <pc98/pc98/ic/ns16550.h>
+#include <i386/isa/ic/i8251.h>
 #else
 #include <i386/isa/isa.h>
 #include <i386/isa/isa_device.h>
 #include <i386/isa/sioreg.h>
+#endif
 
 #ifdef COM_ESP
 #include <i386/isa/ic/esp.h>
 #endif
 #include <i386/isa/ic/ns16550.h>
-#endif
 
 #include "crd.h"
 #if NCRD > 0
diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC
index 5fedd9c9a9c9..d8d30249b3cf 100644
--- a/sys/pc98/conf/GENERIC
+++ b/sys/pc98/conf/GENERIC
@@ -11,7 +11,7 @@
 # device lines is present in the ./LINT configuration file. If you are 
 # in doubt as to the purpose or necessity of a line, check first in LINT.
 #
-#	$Id: GENERIC98,v 1.3 1996/08/31 15:06:28 asami Exp $
+#	$Id: GENERIC98,v 1.4 1996/09/07 02:13:23 asami Exp $
 
 # GENERIC98 -- Generic PC98 machine with WD/SBIC55 disks
 
@@ -38,6 +38,8 @@ options		SYSVSEM
 options		SYSVMSG
 options		UCONSOLE		#Allow users to grab the console
 options		FAILSAFE		#Be conservative
+options		USERCONFIG		#boot -c editor
+options		VISUAL_USERCONFIG	#visual boot -c editor
 options		"MAXCONS=4"		#4 virtual consoles
 options		BOUNCE_BUFFERS		#include support for DMA bounce buffers
 options		EPSON_BOUNCEDMA		#use bounce buufer for 15-16M
diff --git a/sys/pc98/conf/GENERIC98 b/sys/pc98/conf/GENERIC98
index 5fedd9c9a9c9..d8d30249b3cf 100644
--- a/sys/pc98/conf/GENERIC98
+++ b/sys/pc98/conf/GENERIC98
@@ -11,7 +11,7 @@
 # device lines is present in the ./LINT configuration file. If you are 
 # in doubt as to the purpose or necessity of a line, check first in LINT.
 #
-#	$Id: GENERIC98,v 1.3 1996/08/31 15:06:28 asami Exp $
+#	$Id: GENERIC98,v 1.4 1996/09/07 02:13:23 asami Exp $
 
 # GENERIC98 -- Generic PC98 machine with WD/SBIC55 disks
 
@@ -38,6 +38,8 @@ options		SYSVSEM
 options		SYSVMSG
 options		UCONSOLE		#Allow users to grab the console
 options		FAILSAFE		#Be conservative
+options		USERCONFIG		#boot -c editor
+options		VISUAL_USERCONFIG	#visual boot -c editor
 options		"MAXCONS=4"		#4 virtual consoles
 options		BOUNCE_BUFFERS		#include support for DMA bounce buffers
 options		EPSON_BOUNCEDMA		#use bounce buufer for 15-16M
diff --git a/sys/pc98/conf/files.pc98 b/sys/pc98/conf/files.pc98
index fb7d0d40a537..1d02c572541a 100644
--- a/sys/pc98/conf/files.pc98
+++ b/sys/pc98/conf/files.pc98
@@ -1,8 +1,9 @@
 # This file tells config what files go into building a kernel,
 # files marked standard are always included.
 #
-# modified for PC-9801 after:
-#	$Id: files.pc98,v 1.5 1996/09/04 09:52:08 asami Exp $
+# modified for PC-9801
+#
+#	$Id: files.i386,v 1.140 1996/09/11 19:53:30 phk Exp $
 #
 aic7xxx_asm			optional	ahc	device-driver	   \
 	dependency 	"$S/dev/aic7xxx/aic7xxx_asm.c"			   \
@@ -60,7 +61,7 @@ i386/i386/support.s		standard
 i386/i386/swtch.s		standard
 i386/i386/sys_machdep.c		standard
 pc98/i386/trap.c		standard
-pc98/i386/userconfig.c		standard
+pc98/i386/userconfig.c		optional	userconfig
 pc98/i386/vm_machdep.c		standard
 i386/ibcs2/ibcs2_fcntl.c	optional 	ibcs2
 i386/ibcs2/ibcs2_stat.c		optional 	ibcs2
diff --git a/sys/pc98/conf/options.pc98 b/sys/pc98/conf/options.pc98
index ebe3f3bf52ca..98c7223e0518 100644
--- a/sys/pc98/conf/options.pc98
+++ b/sys/pc98/conf/options.pc98
@@ -1,4 +1,4 @@
-#	$Id: options.pc98,v 1.2 1996/07/23 07:45:51 asami Exp $
+#	$Id: options.pc98,v 1.3 1996/09/10 09:37:14 asami Exp $
 BOUNCEPAGES		opt_bounce.h
 USER_LDT
 MATH_EMULATE		opt_math_emulate.h
@@ -9,7 +9,6 @@ COMPAT_LINUX		opt_dontuse.h
 
 SHOW_BUSYBUFS		opt_machdep.h
 PANIC_REBOOT_WAIT_TIME	opt_machdep.h
-LARGEMEM		opt_machdep.h
 MAXMEM			opt_machdep.h
 PERFMON			opt_perfmon.h
 AUTO_EOI_1		opt_auto_eoi.h
@@ -28,7 +27,13 @@ CLK_CALIBRATION_LOOP	  opt_clock.h
 CLK_USE_I8254_CALIBRATION opt_clock.h
 CLK_USE_I586_CALIBRATION  opt_clock.h
 
-SC_KEYBOARD_PROBE_WORKS	opt_syscons.h
+SC_KBD_PROBE_WORKS	opt_syscons.h
+MAXCONS			opt_syscons.h
+SLOW_VGA		opt_syscons.h
+XT_KEYBOARD		opt_syscons.h
 
 ATAPI			opt_atapi.h
 ATAPI_STATIC		opt_atapi.h
+
+USERCONFIG		opt_userconfig.h
+VISUAL_USERCONFIG	opt_userconfig.h
diff --git a/sys/pc98/i386/machdep.c b/sys/pc98/i386/machdep.c
index bf21b7bb0b1d..d1b723df405b 100644
--- a/sys/pc98/i386/machdep.c
+++ b/sys/pc98/i386/machdep.c
@@ -35,7 +35,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)machdep.c	7.4 (Berkeley) 6/3/91
- *	$Id: machdep.c,v 1.6 1996/09/07 02:13:32 asami Exp $
+ *	$Id: machdep.c,v 1.7 1996/09/10 09:37:35 asami Exp $
  */
 
 #include "npx.h"
@@ -44,6 +44,7 @@
 #include "opt_bounce.h"
 #include "opt_machdep.h"
 #include "opt_perfmon.h"
+#include "opt_userconfig.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -387,8 +388,12 @@ again:
 		callout[i-1].c_next = &callout[i];
 
         if (boothowto & RB_CONFIG) {
+#ifdef USERCONFIG
 		userconfig();
 		cninit();	/* the preferred console may have changed */
+#else
+		printf("Sorry! no userconfig in this kernel\n");
+#endif 
 	}
 
 #ifdef BOUNCE_BUFFERS
@@ -1169,19 +1174,6 @@ init386(first)
 	}
 #endif
 
-	/*
-	 * Some 386 machines might give us a bogus number for extended
-	 *	mem. If this happens, stop now.
-	 */
-#ifndef PC98
-#ifndef LARGEMEM
-	if (biosextmem > 65536) {
-		panic("extended memory beyond limit of 64MB");
-		/* NOTREACHED */
-	}
-#endif
-#endif
-
 	pagesinbase = biosbasemem * 1024 / PAGE_SIZE;
 	pagesinext = biosextmem * 1024 / PAGE_SIZE;
 
diff --git a/sys/pc98/i386/pmap.c b/sys/pc98/i386/pmap.c
index 557f584082ec..ca72bb1ecac4 100644
--- a/sys/pc98/i386/pmap.c
+++ b/sys/pc98/i386/pmap.c
@@ -39,7 +39,7 @@
  * SUCH DAMAGE.
  *
  *	from:	@(#)pmap.c	7.7 (Berkeley)	5/12/91
- *	$Id: pmap.c,v 1.1.1.1 1996/06/14 10:04:41 asami Exp $
+ *	$Id: pmap.c,v 1.2 1996/07/23 07:45:56 asami Exp $
  */
 
 /*
@@ -99,6 +99,14 @@
 #define PMAP_DIAGNOSTIC
 #endif
 
+#if !defined(PMAP_DIAGNOSTIC)
+#define PMAP_INLINE __inline
+#else
+#define PMAP_INLINE
+#endif
+
+#define PTPHINT
+
 static void	init_pv_entries __P((int));
 
 /*
@@ -150,7 +158,7 @@ extern int cpu;
  * Data for the pv entry allocation mechanism
  */
 static int pv_freelistcnt;
-static pv_entry_t pv_freelist;
+TAILQ_HEAD (,pv_entry) pv_freelist;
 static vm_offset_t pvva;
 static int npvvapg;
 
@@ -159,7 +167,6 @@ static int npvvapg;
  */
 pt_entry_t *CMAP1;
 static pt_entry_t *CMAP2, *ptmmap;
-static pv_entry_t *pv_table;
 caddr_t CADDR1, ptvmmap;
 static caddr_t CADDR2;
 static pt_entry_t *msgbufmap;
@@ -169,7 +176,7 @@ pt_entry_t *PMAP1;
 unsigned *PADDR1;
 
 static void	free_pv_entry __P((pv_entry_t pv));
-static __inline unsigned * get_ptbase __P((pmap_t pmap));
+static unsigned * get_ptbase __P((pmap_t pmap));
 static pv_entry_t get_pv_entry __P((void));
 static void	i386_protection_init __P((void));
 static void	pmap_alloc_pv_entry __P((void));
@@ -177,24 +184,28 @@ static void	pmap_changebit __P((vm_offset_t pa, int bit, boolean_t setem));
 
 static int	pmap_is_managed __P((vm_offset_t pa));
 static void	pmap_remove_all __P((vm_offset_t pa));
-static void	pmap_enter_quick __P((pmap_t pmap, vm_offset_t va,
-				      vm_offset_t pa));
+static vm_page_t pmap_enter_quick __P((pmap_t pmap, vm_offset_t va,
+				      vm_offset_t pa, vm_page_t mpte));
 static int pmap_remove_pte __P((struct pmap *pmap, unsigned *ptq,
 					vm_offset_t sva));
 static void pmap_remove_page __P((struct pmap *pmap, vm_offset_t va));
-static __inline int pmap_remove_entry __P((struct pmap *pmap, pv_entry_t *pv,
+static int pmap_remove_entry __P((struct pmap *pmap, pv_table_t *pv,
 					vm_offset_t va));
 static boolean_t pmap_testbit __P((vm_offset_t pa, int bit));
-static __inline void pmap_insert_entry __P((pmap_t pmap, vm_offset_t va,
+static void pmap_insert_entry __P((pmap_t pmap, vm_offset_t va,
 		vm_page_t mpte, vm_offset_t pa));
 
-static __inline vm_page_t pmap_allocpte __P((pmap_t pmap, vm_offset_t va));
+static vm_page_t pmap_allocpte __P((pmap_t pmap, vm_offset_t va));
 
-static __inline int pmap_release_free_page __P((pmap_t pmap, vm_page_t p));
-static vm_page_t _pmap_allocpte __P((pmap_t pmap, int ptepindex));
+static int pmap_release_free_page __P((pmap_t pmap, vm_page_t p));
+static vm_page_t _pmap_allocpte __P((pmap_t pmap, unsigned ptepindex));
+static unsigned * pmap_pte_quick __P((pmap_t pmap, vm_offset_t va));
+static vm_page_t pmap_page_alloc __P((vm_object_t object, vm_pindex_t pindex));
+static PMAP_INLINE void pmap_lock __P((pmap_t pmap));
+static PMAP_INLINE void pmap_unlock __P((pmap_t pmap));
+static void pmap_lock2 __P((pmap_t pmap1, pmap_t pmap2));
 
-#define VATRACK 4
-#define PDSTACKMAX 16
+#define PDSTACKMAX 6
 static vm_offset_t pdstack[PDSTACKMAX];
 static int pdstackptr;
 
@@ -244,6 +255,7 @@ pmap_bootstrap(firstaddr, loadaddr)
 	kernel_pmap->pm_pdir = (pd_entry_t *) (KERNBASE + IdlePTD);
 
 	kernel_pmap->pm_count = 1;
+	TAILQ_INIT(&kernel_pmap->pm_pvlist);
 	nkpt = NKPT;
 
 	/*
@@ -310,10 +322,19 @@ pmap_init(phys_start, phys_end)
 	 * Allocate memory for random pmap data structures.  Includes the
 	 * pv_head_table.
 	 */
-	s = (vm_size_t) (sizeof(struct pv_entry *) * npg);
+	s = (vm_size_t) (sizeof(pv_table_t) * npg);
 	s = round_page(s);
+
 	addr = (vm_offset_t) kmem_alloc(kernel_map, s);
-	pv_table = (pv_entry_t *) addr;
+	pv_table = (pv_table_t *) addr;
+	for(i=0;i<npg;i++) {
+		vm_offset_t pa;
+		TAILQ_INIT(&pv_table[i].pv_list);
+		pv_table[i].pv_list_count = 0;
+		pa = vm_first_phys + i * PAGE_SIZE;
+		pv_table[i].pv_vm_page = PHYS_TO_VM_PAGE(pa);
+	}
+	TAILQ_INIT(&pv_freelist);
 
 	/*
 	 * init the pv free list
@@ -376,7 +397,7 @@ pmap_nw_modified(pt_entry_t ptea) {
  * this routine defines the region(s) of memory that should
  * not be tested for the modified bit.
  */
-static __inline int
+static PMAP_INLINE int
 pmap_track_modified( vm_offset_t va) {
 	if ((va < clean_sva) || (va >= clean_eva)) 
 		return 1;
@@ -388,7 +409,7 @@ pmap_track_modified( vm_offset_t va) {
  * The below are finer grained pmap_update routines.  These eliminate
  * the gratuitious tlb flushes on non-i386 architectures.
  */
-static __inline void
+static PMAP_INLINE void
 pmap_update_1pg( vm_offset_t va) {
 #if defined(I386_CPU) || defined(CYRIX_486DLC)
 	/* CYRIX Bug? */
@@ -399,7 +420,7 @@ pmap_update_1pg( vm_offset_t va) {
 		__asm __volatile(".byte 0xf,0x1,0x38": :"a" (va));
 }
 
-static __inline void
+static PMAP_INLINE void
 pmap_update_2pg( vm_offset_t va1, vm_offset_t va2) {
 #if defined(I386_CPU) || defined(CYRIX_486DLC)
 	/* CYRIX Bug? */
@@ -413,7 +434,59 @@ pmap_update_2pg( vm_offset_t va1, vm_offset_t va2) {
 	}
 }
 
-static __pure unsigned *
+
+static PMAP_INLINE void
+pmap_lock(pmap)
+pmap_t pmap;
+{
+	int s;
+	if (pmap == kernel_pmap)
+		return;
+	s = splhigh();
+	while (pmap->pm_flags & PM_FLAG_LOCKED) {
+		pmap->pm_flags |= PM_FLAG_WANTED;
+		tsleep(pmap, PVM - 1, "pmaplk", 0);
+	}
+	splx(s);
+}
+
+static PMAP_INLINE void
+pmap_unlock(pmap)
+pmap_t pmap;
+{
+	int s;
+	if (pmap == kernel_pmap)
+		return;
+	s = splhigh();
+	pmap->pm_flags &= ~PM_FLAG_LOCKED;
+	if (pmap->pm_flags & PM_FLAG_WANTED) {
+		pmap->pm_flags &= ~PM_FLAG_WANTED;
+		wakeup(pmap);
+	}
+}
+
+static void
+pmap_lock2(pmap1, pmap2)
+pmap_t pmap1, pmap2;
+{
+	int s;
+	if (pmap1 == kernel_pmap || pmap2 == kernel_pmap)
+		return;
+	s = splhigh();
+	while ((pmap1->pm_flags | pmap2->pm_flags) & PM_FLAG_LOCKED) {
+		while (pmap1->pm_flags & PM_FLAG_LOCKED) {
+			pmap1->pm_flags |= PM_FLAG_WANTED;
+			tsleep(pmap1, PVM - 1, "pmapl1", 0);
+		}
+		while (pmap2->pm_flags & PM_FLAG_LOCKED) {
+			pmap2->pm_flags |= PM_FLAG_WANTED;
+			tsleep(pmap2, PVM - 1, "pmapl2", 0);
+		}
+	}
+	splx(s);
+}
+
+static unsigned *
 get_ptbase(pmap)
 	pmap_t pmap;
 {
@@ -438,7 +511,7 @@ get_ptbase(pmap)
  *		with the given map/virtual_address pair.
  */
 
-__inline unsigned * __pure
+PMAP_INLINE unsigned *
 pmap_pte(pmap, va)
 	register pmap_t pmap;
 	vm_offset_t va;
@@ -452,27 +525,34 @@ pmap_pte(pmap, va)
 /*
  * Super fast pmap_pte routine best used when scanning
  * the pv lists.  This eliminates many coarse-grained
- * pmap_update calls.
+ * pmap_update calls.  Note that many of the pv list
+ * scans are across different pmaps.  It is very wasteful
+ * to do an entire pmap_update for checking a single mapping.
  */
-__inline unsigned * __pure
+
+unsigned * 
 pmap_pte_quick(pmap, va)
 	register pmap_t pmap;
 	vm_offset_t va;
 {
-	unsigned pde;
+	unsigned pde, newpf;
 	if (pde = (unsigned) pmap->pm_pdir[va >> PDRSHIFT]) {
 		unsigned frame = (unsigned) pmap->pm_pdir[PTDPTDI] & PG_FRAME;
+		unsigned index = i386_btop(va);
 		/* are we current address space or kernel? */
-		if (pmap == kernel_pmap || frame == (((unsigned) PTDpde) & PG_FRAME)) {
-			return (unsigned *) PTmap + i386_btop(va);
+		if ((pmap == kernel_pmap) ||
+			(frame == (((unsigned) PTDpde) & PG_FRAME))) {
+			return (unsigned *) PTmap + index;
 		}
-		* (int *) PMAP1 = (pde & PG_FRAME) | PG_V | PG_RW;
-		pmap_update_1pg((vm_offset_t) PADDR1);
-		return PADDR1 + ((unsigned) i386_btop(va) & (NPTEPG - 1));
+		newpf = pde & PG_FRAME;
+		if ( ((* (unsigned *) PMAP1) & PG_FRAME) != newpf) {
+			* (unsigned *) PMAP1 = newpf | PG_RW | PG_V;
+			pmap_update_1pg((vm_offset_t) PADDR1);
+		}
+		return PADDR1 + ((unsigned) index & (NPTEPG - 1));
 	}
 	return (0);
 }
-	
 
 /*
  *	Routine:	pmap_extract
@@ -480,16 +560,21 @@ pmap_pte_quick(pmap, va)
  *		Extract the physical page address associated
  *		with the given map/virtual_address pair.
  */
-vm_offset_t __pure
+vm_offset_t 
 pmap_extract(pmap, va)
 	register pmap_t pmap;
 	vm_offset_t va;
 {
+	vm_offset_t rtval;
+	pmap_lock(pmap);
 	if (pmap && *pmap_pde(pmap, va)) {
 		unsigned *pte;
 		pte = get_ptbase(pmap) + i386_btop(va);
-		return ((*pte & PG_FRAME) | (va & PAGE_MASK));
+		rtval = ((*pte & PG_FRAME) | (va & PAGE_MASK));
+		pmap_unlock(pmap);
+		return rtval;
 	}
+	pmap_unlock(pmap);
 	return 0;
 
 }
@@ -497,7 +582,7 @@ pmap_extract(pmap, va)
 /*
  * determine if a page is managed (memory vs. device)
  */
-static __inline __pure int
+static PMAP_INLINE int
 pmap_is_managed(pa)
 	vm_offset_t pa;
 {
@@ -513,6 +598,7 @@ pmap_is_managed(pa)
 	return 0;
 }
 
+
 /***************************************************
  * Low level mapping routines.....
  ***************************************************/
@@ -545,6 +631,7 @@ pmap_qenter(va, m, count)
 			pmap_update_1pg(tva);
 	}
 }
+
 /*
  * this routine jerks page mappings from the
  * kernel -- it is meant only for temporary mappings.
@@ -570,7 +657,7 @@ pmap_qremove(va, count)
  * note that in order for the mapping to take effect -- you
  * should do a pmap_update after doing the pmap_kenter...
  */
-__inline void 
+PMAP_INLINE void 
 pmap_kenter(va, pa)
 	vm_offset_t va;
 	register vm_offset_t pa;
@@ -589,7 +676,7 @@ pmap_kenter(va, pa)
 /*
  * remove a page from the kernel pagetables
  */
-__inline void
+PMAP_INLINE void
 pmap_kremove(va)
 	vm_offset_t va;
 {
@@ -600,6 +687,40 @@ pmap_kremove(va)
 	pmap_update_1pg(va);
 }
 
+static vm_page_t
+pmap_page_alloc(object, pindex)
+	vm_object_t object;
+	vm_pindex_t pindex;
+{
+	vm_page_t m;
+	m = vm_page_alloc(object, pindex, VM_ALLOC_ZERO);
+	if (m == NULL) {
+		VM_WAIT;
+	}
+	return m;
+}
+
+vm_page_t
+pmap_page_lookup(object, pindex)
+	vm_object_t object;
+	vm_pindex_t pindex;
+{
+	vm_page_t m;
+retry:
+	m = vm_page_lookup(object, pindex);
+	if (m) {
+		if (m->flags & PG_BUSY) {
+			m->flags |= PG_WANTED;
+			tsleep(m, PVM, "pplookp", 0);
+			goto retry;
+		}
+	}
+
+	return m;
+}
+		
+
+
 
 /***************************************************
  * Page table page management routines.....
@@ -609,9 +730,19 @@ pmap_kremove(va)
  * This routine unholds page table pages, and if the hold count
  * drops to zero, then it decrements the wire count.
  */
-static __inline int
+static int
 pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m) {
+	int s;
+
 	vm_page_unhold(m);
+
+	s = splvm();
+	while (m->flags & PG_BUSY) {
+		m->flags |= PG_WANTED;
+		tsleep(m, PVM, "pmuwpt", 0);
+	}
+	splx(s);
+
 	if (m->hold_count == 0) {
 		vm_offset_t pteva;
 		/*
@@ -619,17 +750,32 @@ pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m) {
 		 */
 		pmap->pm_pdir[m->pindex] = 0;
 		--pmap->pm_stats.resident_count;
-		/*
-		 * Do a pmap_update to make the invalidated mapping
-		 * take effect immediately.
-		 */
-		pteva = UPT_MIN_ADDRESS + i386_ptob(m->pindex);
-		pmap_update_1pg(pteva);
+		if ((((unsigned)pmap->pm_pdir[PTDPTDI]) & PG_FRAME) ==
+			(((unsigned) PTDpde) & PG_FRAME)) {
+			/*
+			 * Do a pmap_update to make the invalidated mapping
+			 * take effect immediately.
+			 */
+			pteva = UPT_MIN_ADDRESS + i386_ptob(m->pindex);
+			pmap_update_1pg(pteva);
+		}
+
+#if defined(PTPHINT)
+		if (pmap->pm_ptphint == m)
+			pmap->pm_ptphint = NULL;
+#endif
+
 		/*
 		 * If the page is finally unwired, simply free it.
 		 */
 		--m->wire_count;
 		if (m->wire_count == 0) {
+
+			if (m->flags & PG_WANTED) {
+				m->flags &= ~PG_WANTED;
+				wakeup(m);
+			}
+
 			vm_page_free_zero(m);
 			--cnt.v_wire_count;
 		}
@@ -648,31 +794,25 @@ pmap_unuse_pt(pmap, va, mpte)
 	vm_offset_t va;
 	vm_page_t mpte;
 {
+	unsigned ptepindex;
 	if (va >= UPT_MIN_ADDRESS)
 		return 0;
 
 	if (mpte == NULL) {
-		vm_offset_t ptepa;
-		ptepa = ((vm_offset_t) *pmap_pde(pmap, va));
-#if defined(PMAP_DIAGNOSTIC)
-		if (!ptepa)
-			panic("pmap_unuse_pt: pagetable page missing, va: 0x%x", va);
+		ptepindex = (va >> PDRSHIFT);
+#if defined(PTPHINT)
+		if (pmap->pm_ptphint &&
+			(pmap->pm_ptphint->pindex == ptepindex)) {
+			mpte = pmap->pm_ptphint;
+		} else {
+			mpte = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
+			pmap->pm_ptphint = mpte;
+		}
+#else
+		mpte = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
 #endif
-		if (!ptepa)
-			return 0;
-		mpte = PHYS_TO_VM_PAGE(ptepa);
 	}
 
-#if defined(PMAP_DIAGNOSTIC)
-	if (mpte->pindex != (va >> PDRSHIFT))
-		panic("pmap_unuse_pt: pindex(0x%x) != va(0x%x)",
-			mpte->pindex, (va >> PDRSHIFT));
-
-	if (mpte->hold_count == 0) {
-		panic("pmap_unuse_pt: hold count < 0, va: 0x%x", va);
-	}
-#endif
-
 	return pmap_unwire_pte_hold(pmap, mpte);
 }
 
@@ -707,12 +847,13 @@ pmap_pinit(pmap)
 	 * allocate the page directory page
 	 */
 retry:
-	ptdpg = vm_page_alloc( pmap->pm_pteobj, PTDPTDI, VM_ALLOC_ZERO);
-	if (ptdpg == NULL) {
-		VM_WAIT;
+	ptdpg = pmap_page_alloc( pmap->pm_pteobj, PTDPTDI);
+	if (ptdpg == NULL) 
 		goto retry;
-	}
-	vm_page_wire(ptdpg);
+
+	ptdpg->wire_count = 1;
+	++cnt.v_wire_count;
+
 	ptdpg->flags &= ~(PG_MAPPED|PG_BUSY);	/* not mapped normally */
 	ptdpg->valid = VM_PAGE_BITS_ALL;
 
@@ -727,7 +868,10 @@ retry:
 	*(unsigned *) (pmap->pm_pdir + PTDPTDI) =
 		VM_PAGE_TO_PHYS(ptdpg) | PG_V | PG_RW;
 
+	pmap->pm_flags = 0;
 	pmap->pm_count = 1;
+	pmap->pm_ptphint = NULL;
+	TAILQ_INIT(&pmap->pm_pvlist);
 }
 
 static int
@@ -750,6 +894,11 @@ pmap_release_free_page(pmap, p)
 		return 0;
 	}
 
+	if (p->flags & PG_WANTED) {
+		p->flags &= ~PG_WANTED;
+		wakeup(p);
+	}
+
 	/*
 	 * Remove the page table page from the processes address space.
 	 */
@@ -757,31 +906,7 @@ pmap_release_free_page(pmap, p)
 	--pmap->pm_stats.resident_count;
 
 	if (p->hold_count)  {
-		int *kvap;
-		int i;
-#if defined(PMAP_DIAGNOSTIC)
 		panic("pmap_release: freeing held page table page");
-#else
-		printf("pmap_release: freeing held page table page:\n");
-#endif
-		kvap = (int *)vm_pager_map_page(p);
-		for(i=0;i<NPTEPG;i++) {
-			if (kvap[i]) {
-				printf("pte: 0x%x, index: %d\n", kvap[i],i);
-			}
-		}
-		vm_pager_unmap_page((vm_offset_t)kvap);
-
-		/*
-		 * HACK ALERT!!!
-		 * If this failure happens, we must clear the page, because
-		 * there is likely a mapping still valid.  This condition
-		 * is an error, but at least this zero operation will mitigate
-		 * some Sig-11's or crashes, because this page is thought
-		 * to be zero.  This is a robustness fix, and not meant to
-		 * be a long term work-around.
-		 */
-		pmap_zero_page(VM_PAGE_TO_PHYS(p));
 	}
 	/*
 	 * Page directory pages need to have the kernel
@@ -793,6 +918,12 @@ pmap_release_free_page(pmap, p)
 		pmap_kremove((vm_offset_t) pmap->pm_pdir);
 	}
 
+#if defined(PTPHINT)
+	if (pmap->pm_ptphint &&
+		(pmap->pm_ptphint->pindex == p->pindex))
+		pmap->pm_ptphint = NULL;
+#endif
+
 	vm_page_free_zero(p);
 	splx(s);
 	return 1;
@@ -805,10 +936,11 @@ pmap_release_free_page(pmap, p)
 static vm_page_t
 _pmap_allocpte(pmap, ptepindex)
 	pmap_t	pmap;
-	int ptepindex;
+	unsigned ptepindex;
 {
 	vm_offset_t pteva, ptepa;
 	vm_page_t m;
+	int needszero = 0;
 
 	/*
 	 * Find or fabricate a new pagetable page
@@ -816,13 +948,11 @@ _pmap_allocpte(pmap, ptepindex)
 retry:
 	m = vm_page_lookup(pmap->pm_pteobj, ptepindex);
 	if (m == NULL) {
-		m = vm_page_alloc(pmap->pm_pteobj, ptepindex, VM_ALLOC_ZERO);
-		if (m == NULL) {
-			VM_WAIT;
+		m = pmap_page_alloc(pmap->pm_pteobj, ptepindex);
+		if (m == NULL)
 			goto retry;
-		}
 		if ((m->flags & PG_ZERO) == 0)
-			pmap_zero_page(VM_PAGE_TO_PHYS(m));
+			needszero = 1;
 		m->flags &= ~(PG_ZERO|PG_BUSY);
 		m->valid = VM_PAGE_BITS_ALL;
 	} else {
@@ -833,22 +963,16 @@ retry:
 		}
 	}
 
-	/*
-	 * mark the object writeable
-	 */
-	pmap->pm_pteobj->flags |= OBJ_WRITEABLE;
-
 	if (m->queue != PQ_NONE) {
 		int s = splvm();
 		vm_page_unqueue(m);
 		splx(s);
 	}
 
-	if (m->hold_count == 0) {
-		if (m->wire_count == 0)
-			++cnt.v_wire_count;
-		++m->wire_count;
-	}
+	if (m->wire_count == 0)
+		++cnt.v_wire_count;
+	++m->wire_count;
+
 	/*
 	 * Increment the hold count for the page table page
 	 * (denoting a new mapping.)
@@ -865,19 +989,39 @@ retry:
 	ptepa = VM_PAGE_TO_PHYS(m);
 	pmap->pm_pdir[ptepindex] = (pd_entry_t) (ptepa | PG_U | PG_RW | PG_V);
 
-	pteva = UPT_MIN_ADDRESS + i386_ptob(ptepindex);
-	pmap_update_1pg(pteva);
+#if defined(PTPHINT)
+	/*
+	 * Set the page table hint
+	 */
+	pmap->pm_ptphint = m;
+#endif
+
+	/*
+	 * Try to use the new mapping, but if we cannot, then
+	 * do it with the routine that maps the page explicitly.
+	 */
+	if (needszero) {
+		if ((((unsigned)pmap->pm_pdir[PTDPTDI]) & PG_FRAME) ==
+			(((unsigned) PTDpde) & PG_FRAME)) {
+			pteva = UPT_MIN_ADDRESS + i386_ptob(ptepindex);
+			bzero((caddr_t) pteva, PAGE_SIZE);
+		} else {
+			pmap_zero_page(ptepa);
+		}
+	}
+
+	m->valid = VM_PAGE_BITS_ALL;
 	m->flags |= PG_MAPPED;
 
 	return m;
 }
 
-static __inline vm_page_t
+static vm_page_t
 pmap_allocpte(pmap, va)
 	pmap_t	pmap;
 	vm_offset_t va;
 {
-	int ptepindex;
+	unsigned ptepindex;
 	vm_offset_t ptepa;
 	vm_page_t m;
 
@@ -896,7 +1040,21 @@ pmap_allocpte(pmap, va)
 	 * hold count, and activate it.
 	 */
 	if (ptepa) {
-		m = PHYS_TO_VM_PAGE(ptepa);
+#if defined(PTPHINT)
+		/*
+		 * In order to get the page table page, try the
+		 * hint first.
+		 */
+		if (pmap->pm_ptphint &&
+			(pmap->pm_ptphint->pindex == ptepindex)) {
+			m = pmap->pm_ptphint;
+		} else {
+			m = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
+			pmap->pm_ptphint = m;
+		}
+#else
+		m = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
+#endif
 		++m->hold_count;
 		return m;
 	}
@@ -926,6 +1084,7 @@ pmap_release(pmap)
 	if (object->ref_count != 1)
 		panic("pmap_release: pteobj reference count != 1");
 	
+	pmap_lock(pmap);
 	ptdpg = NULL;
 retry:
 	for (p = TAILQ_FIRST(&object->memq); p != NULL; p = n) {
@@ -937,10 +1096,8 @@ retry:
 		if (!pmap_release_free_page(pmap, p))
 			goto retry;
 	}
-	if (ptdpg == NULL)
-		panic("pmap_release: missing page table directory page");
 
-	if (!pmap_release_free_page(pmap, ptdpg))
+	if (ptdpg && !pmap_release_free_page(pmap, ptdpg))
 		goto retry;
 		
 	vm_object_deallocate(object);
@@ -950,6 +1107,8 @@ retry:
 	} else {
 		kmem_free(kernel_map, (vm_offset_t) pmap->pm_pdir, PAGE_SIZE);
 	}
+	pmap->pm_pdir = 0;
+	pmap_update();
 }
 
 /*
@@ -979,7 +1138,13 @@ pmap_growkernel(vm_offset_t addr)
 		}
 		++nkpt;
 		if (!nkpg) {
-			nkpg = vm_page_alloc(kernel_object, 0, VM_ALLOC_SYSTEM);
+			vm_offset_t ptpkva = (vm_offset_t) vtopte(addr);
+			/*
+			 * This index is bogus, but out of the way
+			 */
+			vm_pindex_t ptpidx = (ptpkva >> PAGE_SHIFT); 
+			nkpg = vm_page_alloc(kernel_object,
+				ptpidx, VM_ALLOC_SYSTEM);
 			if (!nkpg)
 				panic("pmap_growkernel: no memory to grow kernel");
 			vm_page_wire(nkpg);
@@ -1041,13 +1206,12 @@ pmap_reference(pmap)
 /*
  * free the pv_entry back to the free list
  */
-static __inline void
+static PMAP_INLINE void
 free_pv_entry(pv)
 	pv_entry_t pv;
 {
 	++pv_freelistcnt;
-	pv->pv_next = pv_freelist;
-	pv_freelist = pv;
+	TAILQ_INSERT_HEAD(&pv_freelist, pv, pv_list);
 }
 
 /*
@@ -1056,7 +1220,7 @@ free_pv_entry(pv)
  * the memory allocation is performed bypassing the malloc code
  * because of the possibility of allocations at interrupt time.
  */
-static __inline pv_entry_t
+static pv_entry_t
 get_pv_entry()
 {
 	pv_entry_t tmp;
@@ -1064,15 +1228,15 @@ get_pv_entry()
 	/*
 	 * get more pv_entry pages if needed
 	 */
-	if (pv_freelistcnt < PV_FREELIST_MIN || pv_freelist == 0) {
+	if (pv_freelistcnt < PV_FREELIST_MIN || !TAILQ_FIRST(&pv_freelist)) {
 		pmap_alloc_pv_entry();
 	}
 	/*
 	 * get a pv_entry off of the free list
 	 */
 	--pv_freelistcnt;
-	tmp = pv_freelist;
-	pv_freelist = tmp->pv_next;
+	tmp = TAILQ_FIRST(&pv_freelist);
+	TAILQ_REMOVE(&pv_freelist, tmp, pv_list);
 	return tmp;
 }
 
@@ -1129,7 +1293,7 @@ pmap_alloc_pv_entry()
 			}
 		}
 	}
-	if (!pv_freelist)
+	if (!TAILQ_FIRST(&pv_freelist))
 		panic("get_pv_entry: cannot get a pv_entry_t");
 }
 
@@ -1161,34 +1325,52 @@ init_pv_entries(npg)
  * to the header.  Otherwise we must search the list for
  * the entry.  In either case we free the now unused entry.
  */
-static __inline int
+
+static int
 pmap_remove_entry(pmap, ppv, va)
 	struct pmap *pmap;
-	pv_entry_t *ppv;
+	pv_table_t *ppv;
 	vm_offset_t va;
 {
-	pv_entry_t npv;
+	pv_entry_t pv;
+	int rtval;
 	int s;
 
 	s = splvm();
-	for (npv = *ppv; npv; (ppv = &npv->pv_next, npv = *ppv)) {
-		if (pmap == npv->pv_pmap && va == npv->pv_va) {
-			int rtval = pmap_unuse_pt(pmap, va, npv->pv_ptem);
-			*ppv = npv->pv_next;
-			free_pv_entry(npv);
-			splx(s);
-			return rtval;
+	if (ppv->pv_list_count < pmap->pm_stats.resident_count) {
+		for (pv = TAILQ_FIRST(&ppv->pv_list);
+			pv;
+			pv = TAILQ_NEXT(pv, pv_list)) {
+			if (pmap == pv->pv_pmap && va == pv->pv_va) 
+				break;
+		}
+	} else {
+		for (pv = TAILQ_FIRST(&pmap->pm_pvlist);
+			pv;
+			pv = TAILQ_NEXT(pv, pv_plist)) {
+			if (va == pv->pv_va) 
+				break;
 		}
 	}
+
+	rtval = 0;
+	if (pv) {
+		rtval = pmap_unuse_pt(pmap, va, pv->pv_ptem);
+		TAILQ_REMOVE(&ppv->pv_list, pv, pv_list);
+		--ppv->pv_list_count;
+		TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist);
+		free_pv_entry(pv);
+	}
+			
 	splx(s);
-	return 0;
+	return rtval;
 }
 
 /*
  * Create a pv entry for page at pa for
  * (pmap, va).
  */
-static __inline void
+static void
 pmap_insert_entry(pmap, va, mpte, pa)
 	pmap_t pmap;
 	vm_offset_t va;
@@ -1197,7 +1379,8 @@ pmap_insert_entry(pmap, va, mpte, pa)
 {
 
 	int s;
-	pv_entry_t *ppv, pv;
+	pv_entry_t pv;
+	pv_table_t *ppv;
 
 	s = splvm();
 	pv = get_pv_entry();
@@ -1205,12 +1388,12 @@ pmap_insert_entry(pmap, va, mpte, pa)
 	pv->pv_pmap = pmap;
 	pv->pv_ptem = mpte;
 
+	TAILQ_INSERT_TAIL(&pmap->pm_pvlist, pv, pv_plist);
+
 	ppv = pa_to_pvh(pa);
-	if (*ppv)
-		pv->pv_next = *ppv;
-	else
-		pv->pv_next = NULL;
-	*ppv = pv;
+	TAILQ_INSERT_TAIL(&ppv->pv_list, pv, pv_list);
+	++ppv->pv_list_count;
+
 	splx(s);
 }
 
@@ -1224,7 +1407,7 @@ pmap_remove_pte(pmap, ptq, va)
 	vm_offset_t va;
 {
 	unsigned oldpte;
-	pv_entry_t *ppv;
+	pv_table_t *ppv;
 
 	oldpte = *ptq;
 	*ptq = 0;
@@ -1232,6 +1415,7 @@ pmap_remove_pte(pmap, ptq, va)
 		pmap->pm_stats.wired_count -= 1;
 	pmap->pm_stats.resident_count -= 1;
 	if (oldpte & PG_MANAGED) {
+		ppv = pa_to_pvh(oldpte);
 		if (oldpte & PG_M) {
 #if defined(PMAP_DIAGNOSTIC)
 			if (pmap_nw_modified((pt_entry_t) oldpte)) {
@@ -1239,9 +1423,8 @@ pmap_remove_pte(pmap, ptq, va)
 			}
 #endif
 			if (pmap_track_modified(va))
-				PHYS_TO_VM_PAGE(oldpte)->dirty = VM_PAGE_BITS_ALL;
+				ppv->pv_vm_page->dirty = VM_PAGE_BITS_ALL;
 		}
-		ppv = pa_to_pvh(oldpte);
 		return pmap_remove_entry(pmap, ppv, va);
 	} else {
 		return pmap_unuse_pt(pmap, va, NULL);
@@ -1294,13 +1477,12 @@ pmap_remove(pmap, sva, eva)
 	vm_offset_t pdnxt;
 	vm_offset_t ptpaddr;
 	vm_offset_t sindex, eindex;
-	vm_page_t mpte;
 	int anyvalid;
-	vm_offset_t vachanged[VATRACK];
 
 	if (pmap == NULL)
 		return;
 
+	pmap_lock(pmap);
 	/*
 	 * special handling of removing one page.  a very
 	 * common operation and easy to short circuit some
@@ -1308,6 +1490,7 @@ pmap_remove(pmap, sva, eva)
 	 */
 	if ((sva + PAGE_SIZE) == eva) {
 		pmap_remove_page(pmap, sva);
+		pmap_unlock(pmap);
 		return;
 	}
 
@@ -1337,19 +1520,6 @@ pmap_remove(pmap, sva, eva)
 		if (ptpaddr == 0)
 			continue;
 
-		if (sindex < i386_btop(UPT_MIN_ADDRESS)) {
-		/*
-		 * get the vm_page_t for the page table page
-		 */
-			mpte = PHYS_TO_VM_PAGE(ptpaddr);
-
-		/*
-		 * if the pte isn't wired, just skip it.
-		 */
-			if (mpte->wire_count == 0)
-				continue;
-		}
-
 		/*
 		 * Limit our scan to either the end of the va represented
 		 * by the current page table page, or to the end of the
@@ -1366,8 +1536,6 @@ pmap_remove(pmap, sva, eva)
 			}
 			va = i386_ptob(sindex);
 			
-			if (anyvalid < VATRACK)
-				vachanged[anyvalid] = va;
 			anyvalid++;
 			if (pmap_remove_pte(pmap,
 				ptbase + sindex, va))
@@ -1376,15 +1544,9 @@ pmap_remove(pmap, sva, eva)
 	}
 
 	if (anyvalid) {
-		if (anyvalid <= VATRACK) {
-			int i;
-			for(i=0;i<anyvalid;i++)
-				pmap_update_1pg(vachanged[i]);
-		} else {
-			pmap_update();
-		}
+		pmap_update();
 	}
-			
+	pmap_unlock(pmap);
 }
 
 /*
@@ -1399,15 +1561,20 @@ pmap_remove(pmap, sva, eva)
  *		inefficient because they iteratively called
  *		pmap_remove (slow...)
  */
+
 static void
 pmap_remove_all(pa)
 	vm_offset_t pa;
 {
-	register pv_entry_t pv, *ppv, npv;
+	register pv_entry_t pv;
+	pv_table_t *ppv;
 	register unsigned *pte, tpte;
-	vm_page_t m;
+	int nmodify;
+	int update_needed;
 	int s;
 
+	nmodify = 0;
+	update_needed = 0;
 #if defined(PMAP_DIAGNOSTIC)
 	/*
 	 * XXX this makes pmap_page_protect(NONE) illegal for non-managed
@@ -1419,9 +1586,9 @@ pmap_remove_all(pa)
 #endif
 
 	s = splvm();
-	m = NULL;
 	ppv = pa_to_pvh(pa);
-	for (pv = *ppv; pv; pv=pv->pv_next) {
+	while ((pv = TAILQ_FIRST(&ppv->pv_list)) != NULL) {
+		pmap_lock(pv->pv_pmap);
 		pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
 		if (tpte = *pte) {
 			pv->pv_pmap->pm_stats.resident_count--;
@@ -1437,22 +1604,27 @@ pmap_remove_all(pa)
 					printf("pmap_remove_all: modified page not writable: va: 0x%lx, pte: 0x%lx\n", pv->pv_va, tpte);
 				}
 #endif
-				if (pmap_track_modified(pv->pv_va)) {
-					if (m == NULL)
-						m = PHYS_TO_VM_PAGE(pa);
-					m->dirty = VM_PAGE_BITS_ALL;
-				}
+				if (pmap_track_modified(pv->pv_va))
+					ppv->pv_vm_page->dirty = VM_PAGE_BITS_ALL;
+			}
+			if (!update_needed &&
+				((!curproc || (&curproc->p_vmspace->vm_pmap == pv->pv_pmap)) ||
+				(pv->pv_pmap == kernel_pmap))) {
+				update_needed = 1;
 			}
 		}
-	}
-
-	for (pv = *ppv; pv; pv = npv) {
-		npv = pv->pv_next;
+		TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
+		TAILQ_REMOVE(&ppv->pv_list, pv, pv_list);
+		--ppv->pv_list_count;
 		pmap_unuse_pt(pv->pv_pmap, pv->pv_va, pv->pv_ptem);
+		pmap_unlock(pv->pv_pmap);
 		free_pv_entry(pv);
 	}
-	*ppv = NULL;
+
+	if (update_needed)
+		pmap_update();
 	splx(s);
+	return;
 }
 
 /*
@@ -1469,8 +1641,7 @@ pmap_protect(pmap, sva, eva, prot)
 	vm_offset_t pdnxt;
 	vm_offset_t ptpaddr;
 	vm_offset_t sindex, eindex;
-	vm_page_t mpte;
-	int anyvalid;
+	int anychanged;
 
 
 	if (pmap == NULL)
@@ -1480,10 +1651,12 @@ pmap_protect(pmap, sva, eva, prot)
 		pmap_remove(pmap, sva, eva);
 		return;
 	}
-	if (prot & VM_PROT_WRITE)
+	if (prot & VM_PROT_WRITE) {
 		return;
+	}
 
-	anyvalid = 0;
+	pmap_lock(pmap);
+	anychanged = 0;
 
 	ptbase = get_ptbase(pmap);
 
@@ -1502,18 +1675,6 @@ pmap_protect(pmap, sva, eva, prot)
 		if (ptpaddr == 0)
 			continue;
 
-		/*
-		 * Skip page ranges, where the page table page isn't wired.
-		 * If the page table page is not wired, there are no page mappings
-		 * there.
-		 */
-		if (sindex < i386_btop(UPT_MIN_ADDRESS)) {
-			mpte = PHYS_TO_VM_PAGE(ptpaddr);
-
-			if (mpte->wire_count == 0)
-				continue;
-		}
-
 		if (pdnxt > eindex) {
 			pdnxt = eindex;
 		}
@@ -1531,11 +1692,12 @@ pmap_protect(pmap, sva, eva, prot)
 					}
 				}
 				ptbase[sindex] = pbits & ~(PG_M|PG_RW);
-				anyvalid = 1;
+				anychanged = 1;
 			}
 		}
 	}
-	if (anyvalid)
+	pmap_unlock(pmap);
+	if (anychanged)
 		pmap_update();
 }
 
@@ -1567,6 +1729,7 @@ pmap_enter(pmap, va, pa, prot, wired)
 	if (pmap == NULL)
 		return;
 
+	pmap_lock(pmap);
 	va &= PG_FRAME;
 #ifdef PMAP_DIAGNOSTIC
 	if (va > VM_MAX_KERNEL_ADDRESS)
@@ -1583,7 +1746,7 @@ pmap_enter(pmap, va, pa, prot, wired)
 	if (va < UPT_MIN_ADDRESS)
 		mpte = pmap_allocpte(pmap, va);
 
-	pte = pmap_pte_quick(pmap, va);
+	pte = pmap_pte(pmap, va);
 	/*
 	 * Page Directory table entry not valid, we need a new PT page
 	 */
@@ -1599,7 +1762,7 @@ pmap_enter(pmap, va, pa, prot, wired)
 	/*
 	 * Mapping has not changed, must be protection or wiring change.
 	 */
-	if (opa == pa) {
+	if (origpte && (opa == pa)) {
 		/*
 		 * Wiring change, just update stats. We don't worry about
 		 * wiring PT pages as they remain resident as long as there
@@ -1685,6 +1848,7 @@ validate:
 		if (origpte)
 			pmap_update_1pg(va);
 	}
+	pmap_unlock(pmap);
 }
 
 /*
@@ -1698,22 +1862,62 @@ validate:
  * but is *MUCH* faster than pmap_enter...
  */
 
-static void
-pmap_enter_quick(pmap, va, pa)
+static vm_page_t
+pmap_enter_quick(pmap, va, pa, mpte)
 	register pmap_t pmap;
 	vm_offset_t va;
 	register vm_offset_t pa;
+	vm_page_t mpte;
 {
 	register unsigned *pte;
-	vm_page_t mpte;
 
-	mpte = NULL;
 	/*
 	 * In the case that a page table page is not
 	 * resident, we are creating it here.
 	 */
-	if (va < UPT_MIN_ADDRESS)
-		mpte = pmap_allocpte(pmap, va);
+	if (va < UPT_MIN_ADDRESS) {
+		unsigned ptepindex;
+		vm_offset_t ptepa;
+
+		/*
+		 * Calculate pagetable page index
+		 */
+		ptepindex = va >> PDRSHIFT;
+		if (mpte && (mpte->pindex == ptepindex)) {
+			++mpte->hold_count;
+		} else {
+retry:
+			/*
+			 * Get the page directory entry
+			 */
+			ptepa = (vm_offset_t) pmap->pm_pdir[ptepindex];
+
+			/*
+			 * If the page table page is mapped, we just increment
+			 * the hold count, and activate it.
+			 */
+			if (ptepa) {
+#if defined(PTPHINT)
+				if (pmap->pm_ptphint &&
+					(pmap->pm_ptphint->pindex == ptepindex)) {
+					mpte = pmap->pm_ptphint;
+				} else {
+					mpte = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
+					pmap->pm_ptphint = mpte;
+				}
+#else
+				mpte = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
+#endif
+				if (mpte == NULL)
+					goto retry;
+				++mpte->hold_count;
+			} else {
+				mpte = _pmap_allocpte(pmap, ptepindex);
+			}
+		}
+	} else {
+		mpte = NULL;
+	}
 
 	/*
 	 * This call to vtopte makes the assumption that we are
@@ -1725,7 +1929,7 @@ pmap_enter_quick(pmap, va, pa)
 	if (*pte) {
 		if (mpte)
 			pmap_unwire_pte_hold(pmap, mpte);
-		return;
+		return 0;
 	}
 
 	/*
@@ -1745,7 +1949,7 @@ pmap_enter_quick(pmap, va, pa)
 	 */
 	*pte = pa | PG_V | PG_U | PG_MANAGED;
 
-	return;
+	return mpte;
 }
 
 #define MAX_INIT_PT (96)
@@ -1765,7 +1969,7 @@ pmap_object_init_pt(pmap, addr, object, pindex, size, limit)
 {
 	vm_offset_t tmpidx;
 	int psize;
-	vm_page_t p;
+	vm_page_t p, mpte;
 	int objpgs;
 
 	psize = i386_btop(size);
@@ -1776,9 +1980,11 @@ pmap_object_init_pt(pmap, addr, object, pindex, size, limit)
 		return;
 	}
 
+	pmap_lock(pmap);
 	if (psize + pindex > object->size)
 		psize = object->size - pindex;
 
+	mpte = NULL;
 	/*
 	 * if we are processing a major portion of the object, then scan the
 	 * entire thing.
@@ -1801,12 +2007,12 @@ pmap_object_init_pt(pmap, addr, object, pindex, size, limit)
 			if (((p->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
 			    (p->busy == 0) &&
 			    (p->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
-				if (p->queue == PQ_CACHE)
+				if ((p->queue - p->pc) == PQ_CACHE)
 					vm_page_deactivate(p);
 				p->flags |= PG_BUSY;
-				pmap_enter_quick(pmap, 
+				mpte = pmap_enter_quick(pmap, 
 					addr + i386_ptob(tmpidx),
-					VM_PAGE_TO_PHYS(p));
+					VM_PAGE_TO_PHYS(p), mpte);
 				p->flags |= PG_MAPPED;
 				PAGE_WAKEUP(p);
 			}
@@ -1822,17 +2028,18 @@ pmap_object_init_pt(pmap, addr, object, pindex, size, limit)
 			    ((p->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
 			    (p->busy == 0) &&
 			    (p->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
-				if (p->queue == PQ_CACHE)
+				if ((p->queue - p->pc) == PQ_CACHE)
 					vm_page_deactivate(p);
 				p->flags |= PG_BUSY;
-				pmap_enter_quick(pmap, 
+				mpte = pmap_enter_quick(pmap, 
 					addr + i386_ptob(tmpidx),
-					VM_PAGE_TO_PHYS(p));
+					VM_PAGE_TO_PHYS(p), mpte);
 				p->flags |= PG_MAPPED;
 				PAGE_WAKEUP(p);
 			}
 		}
 	}
+	pmap_unlock(pmap);
 	return;
 }
 
@@ -1861,7 +2068,7 @@ pmap_prefault(pmap, addra, entry, object)
 	vm_offset_t starta;
 	vm_offset_t addr;
 	vm_pindex_t pindex;
-	vm_page_t m;
+	vm_page_t m, mpte;
 
 	if (entry->object.vm_object != object)
 		return;
@@ -1869,6 +2076,7 @@ pmap_prefault(pmap, addra, entry, object)
 	if (!curproc || (pmap != &curproc->p_vmspace->vm_pmap))
 		return;
 
+	pmap_lock(pmap);
 	starta = addra - PFBAK * PAGE_SIZE;
 	if (starta < entry->start) {
 		starta = entry->start;
@@ -1876,6 +2084,7 @@ pmap_prefault(pmap, addra, entry, object)
 		starta = 0;
 	}
 
+	mpte = NULL;
 	for (i = 0; i < PAGEORDER_SIZE; i++) {
 		vm_object_t lobject;
 		unsigned *pte;
@@ -1912,15 +2121,17 @@ pmap_prefault(pmap, addra, entry, object)
 		    (m->busy == 0) &&
 		    (m->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
 
-			if (m->queue == PQ_CACHE) {
+			if ((m->queue - m->pc) == PQ_CACHE) {
 				vm_page_deactivate(m);
 			}
 			m->flags |= PG_BUSY;
-			pmap_enter_quick(pmap, addr, VM_PAGE_TO_PHYS(m));
+			mpte = pmap_enter_quick(pmap, addr,
+				VM_PAGE_TO_PHYS(m), mpte);
 			m->flags |= PG_MAPPED;
 			PAGE_WAKEUP(m);
 		}
 	}
+	pmap_unlock(pmap);
 }
 
 /*
@@ -1941,6 +2152,7 @@ pmap_change_wiring(pmap, va, wired)
 	if (pmap == NULL)
 		return;
 
+	pmap_lock(pmap);
 	pte = pmap_pte(pmap, va);
 
 	if (wired && !pmap_pte_w(pte))
@@ -1953,6 +2165,7 @@ pmap_change_wiring(pmap, va, wired)
 	 * invalidate TLB.
 	 */
 	pmap_pte_set_w(pte, wired);
+	pmap_unlock(pmap);
 }
 
 
@@ -1964,6 +2177,7 @@ pmap_change_wiring(pmap, va, wired)
  *
  *	This routine is only advisory and need not do anything.
  */
+
 void
 pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
 	pmap_t dst_pmap, src_pmap;
@@ -1979,9 +2193,13 @@ pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
 	if (dst_addr != src_addr)
 		return;
 
+	pmap_lock2(src_pmap, dst_pmap);
 	src_frame = ((unsigned) src_pmap->pm_pdir[PTDPTDI]) & PG_FRAME;
-	if (src_frame != (((unsigned) PTDpde) & PG_FRAME))
+	if (src_frame != (((unsigned) PTDpde) & PG_FRAME)) {
+		pmap_unlock(src_pmap);
+		pmap_unlock(dst_pmap);
 		return;
+	}
 
 	dst_frame = ((unsigned) dst_pmap->pm_pdir[PTDPTDI]) & PG_FRAME;
 	if (dst_frame != (((unsigned) APTDpde) & PG_FRAME)) {
@@ -1993,17 +2211,20 @@ pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
 		unsigned *src_pte, *dst_pte;
 		vm_page_t dstmpte, srcmpte;
 		vm_offset_t srcptepaddr;
+		unsigned ptepindex;
 
 		if (addr >= UPT_MIN_ADDRESS)
 			panic("pmap_copy: invalid to pmap_copy page tables\n");
-		pdnxt = ((addr + PAGE_SIZE*NPTEPG) & ~(PAGE_SIZE*NPTEPG - 1));
-		srcptepaddr = (vm_offset_t) src_pmap->pm_pdir[addr >> PDRSHIFT];
-		if (srcptepaddr == 0) {
-			continue;
-		}
 
-		srcmpte = PHYS_TO_VM_PAGE(srcptepaddr);
-		if (srcmpte->hold_count == 0)
+		pdnxt = ((addr + PAGE_SIZE*NPTEPG) & ~(PAGE_SIZE*NPTEPG - 1));
+		ptepindex = addr >> PDRSHIFT;
+
+		srcptepaddr = (vm_offset_t) src_pmap->pm_pdir[ptepindex];
+		if (srcptepaddr == 0)
+			continue;
+
+		srcmpte = vm_page_lookup(src_pmap->pm_pteobj, ptepindex);
+		if ((srcmpte->hold_count == 0) || (srcmpte->flags & PG_BUSY))
 			continue;
 
 		if (pdnxt > end_addr)
@@ -2026,12 +2247,14 @@ pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
 				dstmpte = pmap_allocpte(dst_pmap, addr);
 				if ((*dst_pte == 0) && (ptetemp = *src_pte)) {
 					/*
-					 * Simply clear the modified and accessed (referenced)
-					 * bits.
+					 * Clear the modified and
+					 * accessed (referenced) bits
+					 * during the copy.
 					 */
 					*dst_pte = ptetemp & ~(PG_M|PG_A);
 					dst_pmap->pm_stats.resident_count++;
-					pmap_insert_entry(dst_pmap, addr, dstmpte,
+					pmap_insert_entry(dst_pmap, addr,
+						dstmpte,
 						(ptetemp & PG_FRAME));
 	 			} else {
 					pmap_unwire_pte_hold(dst_pmap, dstmpte);
@@ -2044,6 +2267,8 @@ pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
 			++dst_pte;
 		}
 	}
+	pmap_unlock(src_pmap);
+	pmap_unlock(dst_pmap);
 }	
 
 /*
@@ -2132,7 +2357,8 @@ pmap_page_exists(pmap, pa)
 	pmap_t pmap;
 	vm_offset_t pa;
 {
-	register pv_entry_t *ppv, pv;
+	register pv_entry_t pv;
+	pv_table_t *ppv;
 	int s;
 
 	if (!pmap_is_managed(pa))
@@ -2144,7 +2370,9 @@ pmap_page_exists(pmap, pa)
 	/*
 	 * Not found, check current mappings returning immediately if found.
 	 */
-	for (pv = *ppv; pv; pv = pv->pv_next) {
+	for (pv = TAILQ_FIRST(&ppv->pv_list);
+		pv;
+		pv = TAILQ_NEXT(pv, pv_list)) {
 		if (pv->pv_pmap == pmap) {
 			splx(s);
 			return TRUE;
@@ -2154,17 +2382,91 @@ pmap_page_exists(pmap, pa)
 	return (FALSE);
 }
 
+#ifdef NOT_USED_YET
+#define PMAP_REMOVE_PAGES_CURPROC_ONLY
+/*
+ * Remove all pages from specified address space
+ * this aids process exit speeds.  Also, this code
+ * is special cased for current process only.
+ */
+void
+pmap_remove_pages(pmap, sva, eva)
+	pmap_t pmap;
+	vm_offset_t sva, eva;
+{
+	unsigned *pte, tpte;
+	pv_table_t *ppv;
+	pv_entry_t pv, npv;
+	int s;
+
+#ifdef PMAP_REMOVE_PAGES_CURPROC_ONLY
+	if (!curproc || (pmap != &curproc->p_vmspace->vm_pmap)) {
+		printf("warning: pmap_remove_pages called with non-current pmap\n");
+		return;
+	}
+#endif
+
+	pmap_lock(pmap);
+	s = splhigh();
+
+	for(pv = TAILQ_FIRST(&pmap->pm_pvlist);
+		pv;
+		pv = npv) {
+
+		if (pv->pv_va >= eva || pv->pv_va < sva) {
+			npv = TAILQ_NEXT(pv, pv_plist);
+			continue;
+		}
+
+#ifdef PMAP_REMOVE_PAGES_CURPROC_ONLY
+		pte = (unsigned *)vtopte(pv->pv_va);
+#else
+		pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
+#endif
+		tpte = *pte;
+		*pte = 0;
+
+		ppv = pa_to_pvh(tpte);
+
+		if (tpte) {
+			pv->pv_pmap->pm_stats.resident_count--;
+			if (tpte & PG_W)
+				pv->pv_pmap->pm_stats.wired_count--;
+			/*
+			 * Update the vm_page_t clean and reference bits.
+			 */
+			if (tpte & PG_M) {
+				ppv->pv_vm_page->dirty = VM_PAGE_BITS_ALL;
+			}
+		}
+
+		npv = TAILQ_NEXT(pv, pv_plist);
+		TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
+
+		--ppv->pv_list_count;
+		TAILQ_REMOVE(&ppv->pv_list, pv, pv_list);
+
+		pmap_unuse_pt(pv->pv_pmap, pv->pv_va, pv->pv_ptem);
+		free_pv_entry(pv);
+	}
+	splx(s);
+	pmap_update();
+	pmap_unlock(pmap);
+}
+#endif
+
 /*
  * pmap_testbit tests bits in pte's
  * note that the testbit/changebit routines are inline,
  * and a lot of things compile-time evaluate.
  */
-static __inline boolean_t
+static boolean_t
 pmap_testbit(pa, bit)
 	register vm_offset_t pa;
 	int bit;
 {
-	register pv_entry_t *ppv, pv;
+	register pv_entry_t pv;
+	pv_table_t *ppv;
 	unsigned *pte;
 	int s;
 
@@ -2172,14 +2474,14 @@ pmap_testbit(pa, bit)
 		return FALSE;
 
 	ppv = pa_to_pvh(pa);
-	if (*ppv == NULL)
+	if (TAILQ_FIRST(&ppv->pv_list) == NULL)
 		return FALSE;
 
 	s = splvm();
-	/*
-	 * Not found, check current mappings returning immediately if found.
-	 */
-	for (pv = *ppv ;pv; pv = pv->pv_next) {
+
+	for (pv = TAILQ_FIRST(&ppv->pv_list);
+		pv;
+		pv = TAILQ_NEXT(pv, pv_list)) {
 
 		/*
 		 * if the bit being tested is the modified bit, then
@@ -2191,19 +2493,24 @@ pmap_testbit(pa, bit)
 				continue;
 		}
 
-		if (!pv->pv_pmap) {
 #if defined(PMAP_DIAGNOSTIC)
+		if (!pv->pv_pmap) {
 			printf("Null pmap (tb) at va: 0x%lx\n", pv->pv_va);
-#endif
 			continue;
 		}
+#endif
+		pmap_lock(pv->pv_pmap);
 		pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
-		if (pte == NULL)
+		if (pte == NULL) {
+			pmap_unlock(pv->pv_pmap);
 			continue;
+		}
 		if (*pte & bit) {
+			pmap_unlock(pv->pv_pmap);
 			splx(s);
 			return TRUE;
 		}
+		pmap_unlock(pv->pv_pmap);
 	}
 	splx(s);
 	return (FALSE);
@@ -2212,13 +2519,14 @@ pmap_testbit(pa, bit)
 /*
  * this routine is used to modify bits in ptes
  */
-static __inline void
+static void
 pmap_changebit(pa, bit, setem)
 	vm_offset_t pa;
 	int bit;
 	boolean_t setem;
 {
-	register pv_entry_t pv, *ppv;
+	register pv_entry_t pv;
+	pv_table_t *ppv;
 	register unsigned *pte;
 	vm_offset_t va;
 	int changed;
@@ -2230,49 +2538,56 @@ pmap_changebit(pa, bit, setem)
 	s = splvm();
 	changed = 0;
 	ppv = pa_to_pvh(pa);
+
 	/*
 	 * Loop over all current mappings setting/clearing as appropos If
 	 * setting RO do we need to clear the VAC?
 	 */
-	for ( pv = *ppv; pv; pv = pv->pv_next) {
+	for (pv = TAILQ_FIRST(&ppv->pv_list);
+		pv;
+		pv = TAILQ_NEXT(pv, pv_list)) {
+
 		va = pv->pv_va;
 
 		/*
 		 * don't write protect pager mappings
 		 */
 		if (!setem && (bit == PG_RW)) {
-			if (va >= clean_sva && va < clean_eva)
+			if (!pmap_track_modified(pv->pv_va))
 				continue;
 		}
-		if (!pv->pv_pmap) {
+
 #if defined(PMAP_DIAGNOSTIC)
+		if (!pv->pv_pmap) {
 			printf("Null pmap (cb) at va: 0x%lx\n", va);
-#endif
 			continue;
 		}
+#endif
 
+		pmap_lock(pv->pv_pmap);
 		pte = pmap_pte_quick(pv->pv_pmap, va);
-		if (pte == NULL)
+		if (pte == NULL) {
+			pmap_unlock(pv->pv_pmap);
 			continue;
+		}
 		if (setem) {
 			*(int *)pte |= bit;
 			changed = 1;
 		} else {
 			vm_offset_t pbits = *(vm_offset_t *)pte;
-			if (pbits & bit)
+			if (pbits & bit) {
 				changed = 1;
-			if (bit == PG_RW) {
-				if (pbits & PG_M) {
-					vm_page_t m;
-					vm_offset_t pa = pbits & PG_FRAME;
-					m = PHYS_TO_VM_PAGE(pa);
-					m->dirty = VM_PAGE_BITS_ALL;
+				if (bit == PG_RW) {
+					if (pbits & PG_M) {
+						ppv->pv_vm_page->dirty = VM_PAGE_BITS_ALL;
+					}
+					*(int *)pte = pbits & ~(PG_M|PG_RW);
+				} else {
+					*(int *)pte = pbits & ~bit;
 				}
-				*(int *)pte = pbits & ~(PG_M|PG_RW);
-			} else {
-				*(int *)pte = pbits & ~bit;
 			}
 		}
+		pmap_unlock(pv->pv_pmap);
 	}
 	splx(s);
 	if (changed)
@@ -2294,7 +2609,6 @@ pmap_page_protect(phys, prot)
 			pmap_changebit(phys, PG_RW, FALSE);
 		} else {
 			pmap_remove_all(phys);
-			pmap_update();
 		}
 	}
 }
@@ -2315,7 +2629,8 @@ pmap_phys_address(ppn)
 boolean_t
 pmap_is_referenced(vm_offset_t pa)
 {
-	register pv_entry_t *ppv, pv, lpv;
+	register pv_entry_t pv;
+	pv_table_t *ppv;
 	unsigned *pte;
 	int s;
 
@@ -2328,7 +2643,10 @@ pmap_is_referenced(vm_offset_t pa)
 	/*
 	 * Not found, check current mappings returning immediately if found.
 	 */
-	for (lpv = NULL, pv = *ppv ;pv; lpv = pv, pv = pv->pv_next) {
+	for (pv = TAILQ_FIRST(&ppv->pv_list);
+		pv;
+		pv = TAILQ_NEXT(pv, pv_list)) {
+
 		/*
 		 * if the bit being tested is the modified bit, then
 		 * mark clean_map and ptes as never
@@ -2336,21 +2654,19 @@ pmap_is_referenced(vm_offset_t pa)
 		 */
 		if (!pmap_track_modified(pv->pv_va))
 			continue;
-		if (!pv->pv_pmap) {
+
+		pmap_lock(pv->pv_pmap);
+		pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
+		if (pte == NULL) {
+			pmap_unlock(pv->pv_pmap);
 			continue;
 		}
-		pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
-		if (pte == NULL)
-			continue;
 		if ((int) *pte & PG_A) {
-			if (lpv) {
-				lpv->pv_next = pv->pv_next;
-				pv->pv_next = *ppv;
-				*ppv = pv;
-			}
+			pmap_unlock(pv->pv_pmap);
 			splx(s);
 			return TRUE;
 		}
+		pmap_unlock(pv->pv_pmap);
 	}
 	splx(s);
 	return (FALSE);
@@ -2365,11 +2681,11 @@ pmap_is_referenced(vm_offset_t pa)
 int
 pmap_ts_referenced(vm_offset_t pa)
 {
-	register pv_entry_t *ppv, pv;
+	register pv_entry_t pv;
+	pv_table_t *ppv;
 	unsigned *pte;
 	int s;
 	int rtval = 0;
-	vm_offset_t vachanged[VATRACK];
 
 	if (!pmap_is_managed(pa))
 		return FALSE;
@@ -2378,7 +2694,7 @@ pmap_ts_referenced(vm_offset_t pa)
 
 	ppv = pa_to_pvh(pa);
 
-	if (*ppv == NULL) {
+	if (TAILQ_FIRST(&ppv->pv_list) == NULL) {
 		splx(s);
 		return 0;
 	}
@@ -2386,7 +2702,9 @@ pmap_ts_referenced(vm_offset_t pa)
 	/*
 	 * Not found, check current mappings returning immediately if found.
 	 */
-	for (pv = *ppv ;pv; pv = pv->pv_next) {
+	for (pv = TAILQ_FIRST(&ppv->pv_list);
+		pv;
+		pv = TAILQ_NEXT(pv, pv_list)) {
 		/*
 		 * if the bit being tested is the modified bit, then
 		 * mark clean_map and ptes as never
@@ -2395,28 +2713,21 @@ pmap_ts_referenced(vm_offset_t pa)
 		if (!pmap_track_modified(pv->pv_va))
 			continue;
 
-		if (!pv->pv_pmap) {
+		pmap_lock(pv->pv_pmap);
+		pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
+		if (pte == NULL) {
+			pmap_unlock(pv->pv_pmap);
 			continue;
 		}
-		pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
-		if (pte == NULL)
-			continue;
 		if (*pte & PG_A) {
-			if (rtval < VATRACK)
-				vachanged[rtval] = pv->pv_va;
 			rtval++;
 			*pte &= ~PG_A;
 		}
+		pmap_unlock(pv->pv_pmap);
 	}
 	splx(s);
 	if (rtval) {
-		if (rtval <= VATRACK) {
-			int i;
-			for(i=0;i<rtval;i++)
-				pmap_update_1pg(vachanged[i]);
-		} else {
-			pmap_update();
-		}
+		pmap_update();
 	}
 	return (rtval);
 }
@@ -2453,6 +2764,17 @@ pmap_clear_reference(vm_offset_t pa)
 	pmap_changebit((pa), PG_A, FALSE);
 }
 
+#if 0
+void
+pmap_update_map(pmap_t pmap) {
+	unsigned frame = (unsigned) pmap->pm_pdir[PTDPTDI] & PG_FRAME;
+	if ((pmap == kernel_pmap) ||
+		(frame == (((unsigned) PTDpde) & PG_FRAME))) {
+		pmap_update();
+	}
+}
+#endif
+
 /*
  * Miscellaneous support routines follow
  */
@@ -2531,8 +2853,10 @@ pmap_mincore(pmap, addr)
 	unsigned *ptep, pte;
 	int val = 0;
 	
+	pmap_lock(pmap);
 	ptep = pmap_pte(pmap, addr);
 	if (ptep == 0) {
+		pmap_unlock(pmap);
 		return 0;
 	}
 
@@ -2565,6 +2889,7 @@ pmap_mincore(pmap, addr)
 			pmap_is_referenced(pa))
 			val |= MINCORE_REFERENCED_OTHER;
 	} 
+	pmap_unlock(pmap);
 	return val;
 }
 
@@ -2598,7 +2923,7 @@ pmap_pid_dump(int pid) {
 							}
 							return npte;
 						}
-						pte = pmap_pte( pmap, va);
+						pte = pmap_pte_quick( pmap, va);
 						if (pte && pmap_pte_v(pte)) {
 							vm_offset_t pa;
 							vm_page_t m;
@@ -2647,7 +2972,7 @@ pads(pm)
 					continue;
 				if (pm != kernel_pmap && va > UPT_MAX_ADDRESS)
 					continue;
-				ptep = pmap_pte(pm, va);
+				ptep = pmap_pte_quick(pm, va);
 				if (pmap_pte_v(ptep))
 					printf("%x:%x ", va, *(int *) ptep);
 			};
@@ -2661,7 +2986,9 @@ pmap_pvdump(pa)
 	register pv_entry_t pv;
 
 	printf("pa %x", pa);
-	for (pv = pa_to_pvh(pa); pv; pv = pv->pv_next) {
+	for (pv = TAILQ_FIRST(pa_to_pvh(pa));
+		pv;
+		pv = TAILQ_NEXT(pv, pv_list)) {
 #ifdef used_to_be
 		printf(" -> pmap %x, va %x, flags %x",
 		    pv->pv_pmap, pv->pv_va, pv->pv_flags);
diff --git a/sys/pc98/i386/trap.c b/sys/pc98/i386/trap.c
index b5bf1604f9bb..72f5badca077 100644
--- a/sys/pc98/i386/trap.c
+++ b/sys/pc98/i386/trap.c
@@ -35,7 +35,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)trap.c	7.4 (Berkeley) 5/13/91
- *	$Id: trap.c,v 1.5 1996/09/04 09:52:19 asami Exp $
+ *	$Id: trap.c,v 1.6 1996/09/07 02:13:36 asami Exp $
  */
 
 /*
@@ -80,8 +80,8 @@
 #include "isa.h"
 
 #ifdef POWERFAIL_NMI
-# include <syslog.h>
-# include <machine/clock.h>
+#include <sys/syslog.h>
+#include <machine/clock.h>
 #endif
 
 #include "npx.h"
diff --git a/sys/pc98/i386/userconfig.c b/sys/pc98/i386/userconfig.c
index 7ff39612284b..48f989da8374 100644
--- a/sys/pc98/i386/userconfig.c
+++ b/sys/pc98/i386/userconfig.c
@@ -46,7 +46,7 @@
  ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  **
- **      $Id: userconfig.c,v 1.4 1996/09/03 10:23:18 asami Exp $
+ **      $Id: userconfig.c,v 1.5 1996/09/10 09:37:38 asami Exp $
  **/
 
 /**
@@ -122,10 +122,14 @@
 
 #include <pci/pcivar.h>
 
+#include <opt_userconfig.h>
+
+static struct isa_device *isa_devlist;	/* list read by dset to extract changes */
+
+#ifdef VISUAL_USERCONFIG
 static struct isa_device *devtabs[] = { isa_devtab_bio, isa_devtab_tty, isa_devtab_net,
 				     isa_devtab_null, NULL };
 
-static struct isa_device *isa_devlist;	/* list read by dset to extract changes */
 
 #define putchar(x)	cnputc(x)
 #define getchar()	cngetc()
@@ -2160,6 +2164,7 @@ visuserconfig(void)
     }
 }
 
+#endif /* VISUAL_USERCONFIG */
 /*
  * Copyright (c) 1991 Regents of the University of California.
  * All rights reserved.
@@ -2202,7 +2207,7 @@ visuserconfig(void)
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *      $Id: userconfig.c,v 1.4 1996/09/03 10:23:18 asami Exp $
+ *      $Id: userconfig.c,v 1.5 1996/09/10 09:37:38 asami Exp $
  */
 
 #include "scbus.h"
@@ -2294,7 +2299,9 @@ static Cmd CmdList[] = {
 #if NSCBUS > 0
     { "s",	list_scsi,		NULL },		/* scsi */
 #endif
+#ifdef VISUAL_USERCONFIG
     { "v",	(CmdFunc)visuserconfig,	NULL },		/* visual mode */
+#endif
     { NULL,	NULL,			NULL },
 };
 
diff --git a/sys/pc98/i386/vm_machdep.c b/sys/pc98/i386/vm_machdep.c
index 3b14248168a3..408af5a49424 100644
--- a/sys/pc98/i386/vm_machdep.c
+++ b/sys/pc98/i386/vm_machdep.c
@@ -38,7 +38,7 @@
  *
  *	from: @(#)vm_machdep.c	7.3 (Berkeley) 5/13/91
  *	Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
- *	$Id: vm_machdep.c,v 1.2 1996/07/23 07:46:03 asami Exp $
+ *	$Id: vm_machdep.c,v 1.3 1996/09/03 10:23:21 asami Exp $
  */
 
 #include "npx.h"
@@ -845,14 +845,18 @@ grow(p, sp)
 int
 vm_page_zero_idle() {
 	vm_page_t m;
+	static int free_rover = 0;
 	if ((cnt.v_free_count > cnt.v_interrupt_free_min) &&
-		(m = TAILQ_FIRST(&vm_page_queue_free))) {
-		TAILQ_REMOVE(&vm_page_queue_free, m, pageq);
+		(m = vm_page_list_find(PQ_FREE, free_rover))) {
+		--(*vm_page_queues[m->queue].lcnt);
+		TAILQ_REMOVE(vm_page_queues[m->queue].pl, m, pageq);
 		enable_intr();
 		pmap_zero_page(VM_PAGE_TO_PHYS(m));
 		disable_intr();
-		TAILQ_INSERT_HEAD(&vm_page_queue_zero, m, pageq);
-		m->queue = PQ_ZERO;
+		m->queue = PQ_ZERO + m->pc;
+		++(*vm_page_queues[m->queue].lcnt);
+		TAILQ_INSERT_HEAD(vm_page_queues[m->queue].pl, m, pageq);
+		free_rover = (free_rover + PQ_PRIME3) & PQ_L2_MASK;
 		++vm_page_zero_count;
 		return 1;
 	}
diff --git a/sys/pc98/pc98/atapi.c b/sys/pc98/pc98/atapi.c
index ae702965fc8b..dc5e1c73e68d 100644
--- a/sys/pc98/pc98/atapi.c
+++ b/sys/pc98/pc98/atapi.c
@@ -138,12 +138,11 @@ struct atapidrv atapi_drvtab[4];
 int atapi_ndrv;
 struct atapi *atapi_tab;
 
-int atapi_attach (int ctlr, int unit, int port, struct kern_devconf *parent)
+int atapi_attach (int ctlr, int unit, int port)
 {
 	atapi_drvtab[atapi_ndrv].ctlr     = ctlr;
 	atapi_drvtab[atapi_ndrv].unit     = unit;
 	atapi_drvtab[atapi_ndrv].port     = port;
-	atapi_drvtab[atapi_ndrv].parent   = parent;
 	atapi_drvtab[atapi_ndrv].attached = 0;
 	++atapi_ndrv;
 	return (1);
@@ -1011,7 +1010,7 @@ static int atapi_load (struct lkm_table *lkmtp, int cmd)
 			tsleep (&atapi_locked, PRIBIO, "atach", 0);
 
 		/* Probe the drive. */
-		if (atapi_attach (d->ctlr, d->unit, d->port, d->parent)) {
+		if (atapi_attach (d->ctlr, d->unit, d->port)) {
 			d->attached = 1;
 			++n;
 		}
diff --git a/sys/pc98/pc98/ic/i8237.h b/sys/pc98/pc98/ic/i8237.h
deleted file mode 100644
index 464e5583fee3..000000000000
--- a/sys/pc98/pc98/ic/i8237.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Intel 8237 DMA Controller
- *
- *	i8237.h,v 1.3 1994/11/01 17:26:47 ache Exp
- */
-
-#define	DMA37MD_SINGLE	0x40	/* single pass mode */
-#define	DMA37MD_CASCADE	0xc0	/* cascade mode */
-#define	DMA37MD_AUTO	0x50	/* autoinitialise single pass mode */
-#define	DMA37MD_WRITE	0x04	/* read the device, write memory operation */
-#define	DMA37MD_READ	0x08	/* write the device, read memory operation */
diff --git a/sys/pc98/pc98/ic/ns16550.h b/sys/pc98/pc98/ic/ns16550.h
deleted file mode 100644
index 49bfafd2e2c6..000000000000
--- a/sys/pc98/pc98/ic/ns16550.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*-
- * Copyright (c) 1991 The Regents of the University of California.
- * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 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.
- *
- *	from: @(#)ns16550.h	7.1 (Berkeley) 5/9/91
- *	ns16550.h,v 1.2 1993/10/16 13:48:52 rgrimes Exp
- */
-
-/*
- * NS16550 UART registers
- */
-/*
- * modified for MC16550II
- */
-
-#ifdef PC98
-#define	com_data	0x000	/* data register (R/W) */
-#define	com_dlbl	0x000	/* divisor latch low (W) */
-#define	com_dlbh	0x100	/* divisor latch high (W) */
-#define	com_ier		0x100	/* interrupt enable (W) */
-#define	com_iir		0x200	/* interrupt identification (R) */
-#define	com_fifo	0x200	/* FIFO control (W) */
-#define	com_lctl	0x300	/* line control register (R/W) */
-#define	com_cfcr	0x300	/* line control register (R/W) */
-#define	com_mcr		0x400	/* modem control register (R/W) */
-#define	com_lsr		0x500	/* line status register (R/W) */
-#define	com_msr		0x600	/* modem status register (R/W) */
-#else
-#define	com_data	0	/* data register (R/W) */
-#define	com_dlbl	0	/* divisor latch low (W) */
-#define	com_dlbh	1	/* divisor latch high (W) */
-#define	com_ier		1	/* interrupt enable (W) */
-#define	com_iir		2	/* interrupt identification (R) */
-#define	com_fifo	2	/* FIFO control (W) */
-#define	com_lctl	3	/* line control register (R/W) */
-#define	com_cfcr	3	/* line control register (R/W) */
-#define	com_mcr		4	/* modem control register (R/W) */
-#define	com_lsr		5	/* line status register (R/W) */
-#define	com_msr		6	/* modem status register (R/W) */
-#endif
diff --git a/sys/pc98/pc98/if_fe.c b/sys/pc98/pc98/if_fe.c
index fa96ccce3580..85f8033e6f77 100644
--- a/sys/pc98/pc98/if_fe.c
+++ b/sys/pc98/pc98/if_fe.c
@@ -21,7 +21,7 @@
  */
 
 /*
- * $Id: if_fe.c,v 1.6 1996/09/07 02:13:52 asami Exp $
+ * $Id: if_fe.c,v 1.7 1996/09/10 09:38:08 asami Exp $
  *
  * Device driver for Fujitsu MB86960A/MB86965A based Ethernet cards.
  * To be used with FreeBSD 2.x
@@ -238,7 +238,6 @@ static struct fe_softc {
 
 }       fe_softc[NFE];
 
-/* Frequently accessed members in arpcom and kdc.  */
 #define sc_if		arpcom.ac_if
 #define sc_unit		arpcom.ac_if.if_unit
 #define sc_enaddr	arpcom.ac_enaddr
diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c
index bf21b7bb0b1d..d1b723df405b 100644
--- a/sys/pc98/pc98/machdep.c
+++ b/sys/pc98/pc98/machdep.c
@@ -35,7 +35,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)machdep.c	7.4 (Berkeley) 6/3/91
- *	$Id: machdep.c,v 1.6 1996/09/07 02:13:32 asami Exp $
+ *	$Id: machdep.c,v 1.7 1996/09/10 09:37:35 asami Exp $
  */
 
 #include "npx.h"
@@ -44,6 +44,7 @@
 #include "opt_bounce.h"
 #include "opt_machdep.h"
 #include "opt_perfmon.h"
+#include "opt_userconfig.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -387,8 +388,12 @@ again:
 		callout[i-1].c_next = &callout[i];
 
         if (boothowto & RB_CONFIG) {
+#ifdef USERCONFIG
 		userconfig();
 		cninit();	/* the preferred console may have changed */
+#else
+		printf("Sorry! no userconfig in this kernel\n");
+#endif 
 	}
 
 #ifdef BOUNCE_BUFFERS
@@ -1169,19 +1174,6 @@ init386(first)
 	}
 #endif
 
-	/*
-	 * Some 386 machines might give us a bogus number for extended
-	 *	mem. If this happens, stop now.
-	 */
-#ifndef PC98
-#ifndef LARGEMEM
-	if (biosextmem > 65536) {
-		panic("extended memory beyond limit of 64MB");
-		/* NOTREACHED */
-	}
-#endif
-#endif
-
 	pagesinbase = biosbasemem * 1024 / PAGE_SIZE;
 	pagesinext = biosextmem * 1024 / PAGE_SIZE;
 
diff --git a/sys/pc98/pc98/pc98.c b/sys/pc98/pc98/pc98.c
index 6b7adf3fede0..b77aa8c6a6cc 100644
--- a/sys/pc98/pc98/pc98.c
+++ b/sys/pc98/pc98/pc98.c
@@ -34,7 +34,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)isa.c	7.2 (Berkeley) 5/13/91
- *	$Id: pc98.c,v 1.5 1996/09/07 02:14:09 asami Exp $
+ *	$Id: pc98.c,v 1.6 1996/09/10 09:38:19 asami Exp $
  */
 
 /*
@@ -57,7 +57,6 @@
 
 #include <sys/param.h>
 #include <sys/systm.h>
-#include <sys/sysctl.h>
 #include <sys/buf.h>
 #include <sys/syslog.h>
 #include <sys/malloc.h>
diff --git a/sys/pc98/pc98/pc98.h b/sys/pc98/pc98/pc98.h
index 79614792fc6e..edc90330f1fa 100644
--- a/sys/pc98/pc98/pc98.h
+++ b/sys/pc98/pc98/pc98.h
@@ -34,7 +34,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)isa.h	5.7 (Berkeley) 5/9/91
- *	$Id: pc98.h,v 1.2 1996/09/03 10:23:48 asami Exp $
+ *	$Id: pc98.h,v 1.3 1996/09/10 09:38:21 asami Exp $
  */
 
 #ifndef _PC98_PC98_PC98_H_
@@ -213,6 +213,53 @@ extern unsigned char	pc98_system_parameter[]; /* in locore.c */
 #define epson_system_type	(pc98_system_parameter[OFS_epson_system_type])
 
 # define PC98_TYPE_CHECK(x)	((pc98_machine_type & (x)) == (x))
+
+#include <machine/spl.h>
+
+static inline u_char
+epson_inb(u_int port)
+{
+	u_char	data;
+
+	outb(0x43f, 0x42);
+	data = inb(port);
+	outb(0x43f, 0x40);
+	return (data);
+}
+
+static inline void
+epson_outb(u_int port, u_char data)
+{
+	outb(0x43f, 0x42);
+	outb(port,data);
+	outb(0x43f, 0x40);
+}
+
+static inline void
+epson_insw(u_int port, void *addr, size_t cnt)
+{
+	int	s;
+
+	s = splbio();
+	outb(0x43f, 0x42);
+	disable_intr();
+	insw((u_int)port, (void *)addr, (size_t)cnt);
+	outb(0x43f, 0x40);
+	splx(s);
+}
+
+static inline void
+epson_outsw(u_int port, void *addr, size_t cnt)
+{
+	int	s;
+
+	s = splbio();
+	outb(0x43f, 0x42);
+	disable_intr();
+	outsw((u_int)port, (void *)addr, (size_t)cnt);
+	outb(0x43f, 0x40);
+	splx(s);
+}
 #endif /* KERNEL */
 
 /*
diff --git a/sys/pc98/pc98/sio.c b/sys/pc98/pc98/sio.c
index c14452401862..aacf54c0617e 100644
--- a/sys/pc98/pc98/sio.c
+++ b/sys/pc98/pc98/sio.c
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)com.c	7.5 (Berkeley) 5/16/91
- *	$Id: sio.c,v 1.5 1996/09/07 02:14:23 asami Exp $
+ *	$Id: sio.c,v 1.6 1996/09/10 09:38:34 asami Exp $
  */
 
 #include "opt_comconsole.h"
@@ -141,18 +141,17 @@
 #include <i386/isa/icu.h>
 #include <i386/isa/isa_device.h>
 #include <pc98/pc98/sioreg.h>
-#include <pc98/pc98/ic/i8251.h>
-#include <pc98/pc98/ic/ns16550.h>
+#include <i386/isa/ic/i8251.h>
 #else
 #include <i386/isa/isa.h>
 #include <i386/isa/isa_device.h>
 #include <i386/isa/sioreg.h>
+#endif
 
 #ifdef COM_ESP
 #include <i386/isa/ic/esp.h>
 #endif
 #include <i386/isa/ic/ns16550.h>
-#endif
 
 #include "crd.h"
 #if NCRD > 0
diff --git a/sys/pc98/pc98/sound/ad1848.c b/sys/pc98/pc98/sound/ad1848.c
index eeeddae8163e..73e0edc3ff91 100644
--- a/sys/pc98/pc98/sound/ad1848.c
+++ b/sys/pc98/pc98/sound/ad1848.c
@@ -36,11 +36,11 @@
 
 #define DEB(x)
 #define DEB1(x)
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_AD1848)
 
-#include "ad1848_mixer.h"
+#include <i386/isa/sound/ad1848_mixer.h>
 
 #define IMODE_NONE		0
 #define IMODE_OUTPUT		1
@@ -1397,7 +1397,7 @@ mozart_init (int io_base)
 #endif /* MOZART_PORT */
 
 #ifdef OPTI_MAD16_PORT
-#include "mad16.h"
+#include <i386/isa/sound/mad16.h>
 #endif
 
 /*
diff --git a/sys/pc98/pc98/sound/adlib_card.c b/sys/pc98/pc98/sound/adlib_card.c
index 6365069384a5..aabd8379cde2 100644
--- a/sys/pc98/pc98/sound/adlib_card.c
+++ b/sys/pc98/pc98/sound/adlib_card.c
@@ -27,7 +27,7 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_YM3812)
 
diff --git a/sys/pc98/pc98/sound/aedsp16.c b/sys/pc98/pc98/sound/aedsp16.c
index b14a24618f0c..a292d9e584da 100644
--- a/sys/pc98/pc98/sound/aedsp16.c
+++ b/sys/pc98/pc98/sound/aedsp16.c
@@ -225,7 +225,7 @@
  * Include the main voxware header file. It include all the os/voxware/etc
  * headers needed by this source.
  */
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 /*
  * all but ioport.h :)
  */
diff --git a/sys/pc98/pc98/sound/audio.c b/sys/pc98/pc98/sound/audio.c
index 770babc05982..c6f7972bc377 100644
--- a/sys/pc98/pc98/sound/audio.c
+++ b/sys/pc98/pc98/sound/audio.c
@@ -27,13 +27,13 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #ifdef CONFIGURE_SOUNDCARD
 #ifndef EXCLUDE_AUDIO
 
-#include "ulaw.h"
-#include "coproc.h"
+#include <i386/isa/sound/ulaw.h>
+#include <i386/isa/sound/coproc.h>
 
 #define ON		1
 #define OFF		0
diff --git a/sys/pc98/pc98/sound/dev_table.c b/sys/pc98/pc98/sound/dev_table.c
index bfd8e58e1a74..49023249a6be 100644
--- a/sys/pc98/pc98/sound/dev_table.c
+++ b/sys/pc98/pc98/sound/dev_table.c
@@ -28,7 +28,7 @@
  */
 
 #define _DEV_TABLE_C_
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #ifdef CONFIGURE_SOUNDCARD
 
diff --git a/sys/pc98/pc98/sound/dmabuf.c b/sys/pc98/pc98/sound/dmabuf.c
index bb64d7d8103e..20095d211ab7 100644
--- a/sys/pc98/pc98/sound/dmabuf.c
+++ b/sys/pc98/pc98/sound/dmabuf.c
@@ -27,7 +27,7 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #ifdef CONFIGURE_SOUNDCARD
 
diff --git a/sys/pc98/pc98/sound/gus_card.c b/sys/pc98/pc98/sound/gus_card.c
index 4a07fd3155d4..0e96df105539 100644
--- a/sys/pc98/pc98/sound/gus_card.c
+++ b/sys/pc98/pc98/sound/gus_card.c
@@ -27,11 +27,11 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS)
 
-#include "gus_hw.h"
+#include <i386/isa/sound/gus_hw.h>
 
 int             gus_base, gus_irq, gus_dma;
 extern int      gus_wave_volume;
diff --git a/sys/pc98/pc98/sound/gus_midi.c b/sys/pc98/pc98/sound/gus_midi.c
index 66c81df470cb..876c665ff032 100644
--- a/sys/pc98/pc98/sound/gus_midi.c
+++ b/sys/pc98/pc98/sound/gus_midi.c
@@ -27,11 +27,11 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #ifdef CONFIGURE_SOUNDCARD
 
-#include "gus_hw.h"
+#include <i386/isa/sound/gus_hw.h>
 
 #if !defined(EXCLUDE_GUS) && !defined(EXCLUDE_MIDI)
 
@@ -225,7 +225,7 @@ gus_midi_buffer_status (int dev)
 
 #define MIDI_SYNTH_NAME	"Gravis Ultrasound Midi"
 #define MIDI_SYNTH_CAPS	SYNTH_CAP_INPUT
-#include "midi_synth.h"
+#include <i386/isa/sound/midi_synth.h>
 
 static struct midi_operations gus_midi_operations =
 {
diff --git a/sys/pc98/pc98/sound/gus_vol.c b/sys/pc98/pc98/sound/gus_vol.c
index 3e58dce3fc9f..a8f11211026a 100644
--- a/sys/pc98/pc98/sound/gus_vol.c
+++ b/sys/pc98/pc98/sound/gus_vol.c
@@ -3,9 +3,9 @@
  *
  * Greg Lee 1993.
  */
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 #ifndef EXCLUDE_GUS
-#include "gus_linearvol.h"
+#include <i386/isa/sound/gus_linearvol.h>
 
 extern unsigned short gus_adagio_vol (int vel, int mainv, int xpn, int voicev);
 extern unsigned short gus_linear_vol (int vol, int mainvol);
diff --git a/sys/pc98/pc98/sound/gus_wave.c b/sys/pc98/pc98/sound/gus_wave.c
index fe88539b06e1..e0f946d6de7b 100644
--- a/sys/pc98/pc98/sound/gus_wave.c
+++ b/sys/pc98/pc98/sound/gus_wave.c
@@ -27,9 +27,9 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 #include <machine/ultrasound.h>
-#include "gus_hw.h"
+#include <i386/isa/sound/gus_hw.h>
 
 static unsigned char gus_look8 __P((int reg));
 static unsigned short gus_read16 __P((int reg));
diff --git a/sys/pc98/pc98/sound/ics2101.c b/sys/pc98/pc98/sound/ics2101.c
index 3a76ea966494..cec1e511af12 100644
--- a/sys/pc98/pc98/sound/ics2101.c
+++ b/sys/pc98/pc98/sound/ics2101.c
@@ -27,11 +27,11 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_GUS)
 
 #include <machine/ultrasound.h>
-#include "gus_hw.h"
+#include <i386/isa/sound/gus_hw.h>
 
 #define MIX_DEVS	(SOUND_MASK_MIC|SOUND_MASK_LINE| \
 			 SOUND_MASK_SYNTH| \
diff --git a/sys/pc98/pc98/sound/midi_synth.c b/sys/pc98/pc98/sound/midi_synth.c
index e2a1c2cd01a5..fb1fdc42707a 100644
--- a/sys/pc98/pc98/sound/midi_synth.c
+++ b/sys/pc98/pc98/sound/midi_synth.c
@@ -30,7 +30,7 @@
 #define USE_SEQ_MACROS
 #define USE_SIMPLE_MACROS
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_MIDI)
 
@@ -38,7 +38,7 @@
 
 DEFINE_WAIT_QUEUE (sysex_sleeper, sysex_sleep_flag);
 
-#include "midi_synth.h"
+#include <i386/isa/sound/midi_synth.h>
 
 static int      midi2synth[MAX_MIDI_DEV];
 static unsigned char prev_out_status[MAX_MIDI_DEV];
diff --git a/sys/pc98/pc98/sound/midibuf.c b/sys/pc98/pc98/sound/midibuf.c
index f1a5cf2ae8f2..c05d44000e86 100644
--- a/sys/pc98/pc98/sound/midibuf.c
+++ b/sys/pc98/pc98/sound/midibuf.c
@@ -27,7 +27,7 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 static void drain_midi_queue __P((int dev));
 
diff --git a/sys/pc98/pc98/sound/mpu401.c b/sys/pc98/pc98/sound/mpu401.c
index 7b1616d7dd79..eaee157ebb2a 100644
--- a/sys/pc98/pc98/sound/mpu401.c
+++ b/sys/pc98/pc98/sound/mpu401.c
@@ -33,12 +33,12 @@
 #define USE_SEQ_MACROS
 #define USE_SIMPLE_MACROS
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #ifdef CONFIGURE_SOUNDCARD
 
 #if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
-#include "coproc.h"
+#include <i386/isa/sound/coproc.h>
 
 static int      init_sequence[20];	/* NOTE! pos 0 = len, start pos 1. */
 static int      timer_mode = TMR_INTERNAL, timer_caps = TMR_INTERNAL;
@@ -937,7 +937,7 @@ mpu_synth_close (int dev)
 
 #define MIDI_SYNTH_NAME	"MPU-401 UART Midi"
 #define MIDI_SYNTH_CAPS	SYNTH_CAP_INPUT
-#include "midi_synth.h"
+#include <i386/isa/sound/midi_synth.h>
 
 static struct synth_operations mpu401_synth_proto =
 {
diff --git a/sys/pc98/pc98/sound/opl3.c b/sys/pc98/pc98/sound/opl3.c
index 4b30e0a6acc3..42379cd32c47 100644
--- a/sys/pc98/pc98/sound/opl3.c
+++ b/sys/pc98/pc98/sound/opl3.c
@@ -34,11 +34,11 @@
  * hooft@chem.ruu.nl
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_YM3812)
 
-#include "opl3.h"
+#include <i386/isa/sound/opl3.h>
 
 #define MAX_VOICE	18
 #define OFFS_4OP	11	/*
diff --git a/sys/pc98/pc98/sound/pas2_card.c b/sys/pc98/pc98/sound/pas2_card.c
index 3f72359e9f1b..eeff8ae22802 100644
--- a/sys/pc98/pc98/sound/pas2_card.c
+++ b/sys/pc98/pc98/sound/pas2_card.c
@@ -28,12 +28,12 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_PAS)
 
 #define DEFINE_TRANSLATIONS
-#include "pas.h"
+#include <i386/isa/sound/pas.h>
 
 static int config_pas_hw __P((struct address_info *hw_config));
 static int detect_pas_hw __P((struct address_info *hw_config));
diff --git a/sys/pc98/pc98/sound/pas2_midi.c b/sys/pc98/pc98/sound/pas2_midi.c
index 6db884b4ecd2..a83158e44d45 100644
--- a/sys/pc98/pc98/sound/pas2_midi.c
+++ b/sys/pc98/pc98/sound/pas2_midi.c
@@ -27,11 +27,11 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #ifdef CONFIGURE_SOUNDCARD
 
-#include "pas.h"
+#include <i386/isa/sound/pas.h>
 
 #if !defined(EXCLUDE_PAS) && !defined(EXCLUDE_MIDI) && defined(EXCLUDE_PRO_MIDI)
 
@@ -233,7 +233,7 @@ pas_buffer_status (int dev)
 
 #define MIDI_SYNTH_NAME	"Pro Audio Spectrum Midi"
 #define MIDI_SYNTH_CAPS	SYNTH_CAP_INPUT
-#include "midi_synth.h"
+#include <i386/isa/sound/midi_synth.h>
 
 static struct midi_operations pas_midi_operations =
 {
diff --git a/sys/pc98/pc98/sound/pas2_mixer.c b/sys/pc98/pc98/sound/pas2_mixer.c
index f6fd0b6fd67c..c1ba76b7df57 100644
--- a/sys/pc98/pc98/sound/pas2_mixer.c
+++ b/sys/pc98/pc98/sound/pas2_mixer.c
@@ -29,11 +29,11 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_PAS)
 
-#include "pas.h"
+#include <i386/isa/sound/pas.h>
 
 extern void mix_write __P((unsigned char data, int ioaddr));
 static int pas_mixer_ioctl __P((int dev, unsigned int cmd, unsigned int arg));
diff --git a/sys/pc98/pc98/sound/pas2_pcm.c b/sys/pc98/pc98/sound/pas2_pcm.c
index 8a9c17290d40..97ae76cf0fc6 100644
--- a/sys/pc98/pc98/sound/pas2_pcm.c
+++ b/sys/pc98/pc98/sound/pas2_pcm.c
@@ -28,11 +28,11 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #ifdef CONFIGURE_SOUNDCARD
 
-#include "pas.h"
+#include <i386/isa/sound/pas.h>
 
 static int pcm_set_bits __P((int arg));
 static int pcm_set_channels __P((int arg));
diff --git a/sys/pc98/pc98/sound/patmgr.c b/sys/pc98/pc98/sound/patmgr.c
index fc201dd9c9b4..f0139846b385 100644
--- a/sys/pc98/pc98/sound/patmgr.c
+++ b/sys/pc98/pc98/sound/patmgr.c
@@ -28,7 +28,7 @@
  */
 
 #define PATMGR_C
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SEQUENCER)
 
diff --git a/sys/pc98/pc98/sound/sb16_dsp.c b/sys/pc98/pc98/sound/sb16_dsp.c
index 5d9ee5343aaf..405777425168 100644
--- a/sys/pc98/pc98/sound/sb16_dsp.c
+++ b/sys/pc98/pc98/sound/sb16_dsp.c
@@ -34,9 +34,9 @@
 /*
  * #define DEB_DMARES
  */
-#include "sound_config.h"
-#include "sb.h"
-#include "sb_mixer.h"
+#include <i386/isa/sound/sound_config.h>
+#include <i386/isa/sound/sb.h>
+#include <i386/isa/sound/sb_mixer.h>
 
 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB16) && !defined(EXCLUDE_SB) && !defined(EXCLUDE_AUDIO) && !defined(EXCLUDE_SBPRO)
 
diff --git a/sys/pc98/pc98/sound/sb16_midi.c b/sys/pc98/pc98/sound/sb16_midi.c
index 8a8ac731bb41..7dae75011248 100644
--- a/sys/pc98/pc98/sound/sb16_midi.c
+++ b/sys/pc98/pc98/sound/sb16_midi.c
@@ -27,13 +27,13 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #ifdef CONFIGURE_SOUNDCARD
 
 #if !defined(EXCLUDE_SB) && !defined(EXCLUDE_SB16) && !defined(EXCLUDE_MIDI)
 
-#include "sb.h"
+#include <i386/isa/sound/sb.h>
 
 #ifdef PC98
 #define	DATAPORT   (sb16midi_base)
@@ -182,7 +182,7 @@ sb16midi_buffer_status (int dev)
 
 #define MIDI_SYNTH_NAME	"SoundBlaster 16 Midi"
 #define MIDI_SYNTH_CAPS	SYNTH_CAP_INPUT
-#include "midi_synth.h"
+#include <i386/isa/sound/midi_synth.h>
 
 static struct midi_operations sb16midi_operations =
 {
diff --git a/sys/pc98/pc98/sound/sb_card.c b/sys/pc98/pc98/sound/sb_card.c
index b8e5af2745f7..37455d10d665 100644
--- a/sys/pc98/pc98/sound/sb_card.c
+++ b/sys/pc98/pc98/sound/sb_card.c
@@ -30,7 +30,7 @@
  *  - Added the Audio Excel DSP 16 initialization routine.
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB)
 
diff --git a/sys/pc98/pc98/sound/sb_dsp.c b/sys/pc98/pc98/sound/sb_dsp.c
index 608158521b2e..82a2178317a4 100644
--- a/sys/pc98/pc98/sound/sb_dsp.c
+++ b/sys/pc98/pc98/sound/sb_dsp.c
@@ -33,12 +33,12 @@
  *      Code added for MV ProSonic/Jazz 16 in 16 bit mode
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB)
 
-#include "sb.h"
-#include "sb_mixer.h"
+#include <i386/isa/sound/sb.h>
+#include <i386/isa/sound/sb_mixer.h>
 #undef SB_TEST_IRQ
 
 int             sbc_base = 0;
@@ -901,7 +901,7 @@ static int
 initialize_smw (void)
 {
 #ifdef SMW_MIDI0001_INCLUDED
-#include "smw-midi0001.h"
+#include <i386/isa/sound/smw-midi0001.h>
 #else
   unsigned char   smw_ucode[1];
   int             smw_ucodeLen = 0;
diff --git a/sys/pc98/pc98/sound/sb_midi.c b/sys/pc98/pc98/sound/sb_midi.c
index f94f2c4ad35b..de661ac35903 100644
--- a/sys/pc98/pc98/sound/sb_midi.c
+++ b/sys/pc98/pc98/sound/sb_midi.c
@@ -27,11 +27,11 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB) && !defined(EXCLUDE_MIDI)
 
-#include "sb.h"
+#include <i386/isa/sound/sb.h>
 #undef SB_TEST_IRQ
 
 /*
@@ -211,7 +211,7 @@ sb_midi_interrupt (int dummy)
 
 #define MIDI_SYNTH_NAME	"SoundBlaster Midi"
 #define MIDI_SYNTH_CAPS	0
-#include "midi_synth.h"
+#include <i386/isa/sound/midi_synth.h>
 
 static struct midi_operations sb_midi_operations =
 {
diff --git a/sys/pc98/pc98/sound/sb_mixer.c b/sys/pc98/pc98/sound/sb_mixer.c
index b96c24c3c59d..4fd2db20a2fc 100644
--- a/sys/pc98/pc98/sound/sb_mixer.c
+++ b/sys/pc98/pc98/sound/sb_mixer.c
@@ -32,13 +32,13 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB) && !defined(EXCLUDE_SBPRO)
 #define __SB_MIXER_C__
 
-#include "sb.h"
-#include "sb_mixer.h"
+#include <i386/isa/sound/sb.h>
+#include <i386/isa/sound/sb_mixer.h>
 #undef SB_TEST_IRQ
 
 extern int      sbc_base;
diff --git a/sys/pc98/pc98/sound/sequencer.c b/sys/pc98/pc98/sound/sequencer.c
index f6356f1e67df..b49baed2e919 100644
--- a/sys/pc98/pc98/sound/sequencer.c
+++ b/sys/pc98/pc98/sound/sequencer.c
@@ -28,8 +28,8 @@
  */
 
 #define SEQUENCER_C
-#include "sound_config.h"
-#include "midi_ctrl.h"
+#include <i386/isa/sound/sound_config.h>
+#include <i386/isa/sound/midi_ctrl.h>
 
 extern void seq_drain_midi_queues __P((void));
 
@@ -71,7 +71,7 @@ static unsigned long   prev_input_time = 0;
 static int             prev_event_time;
 static unsigned long   seq_time = 0;
 
-#include "tuning.h"
+#include <i386/isa/sound/tuning.h>
 
 #define EV_SZ	8
 #define IEV_SZ	8
diff --git a/sys/pc98/pc98/sound/sound_config.h b/sys/pc98/pc98/sound/sound_config.h
index 76b455803e7b..2330fa94b1a1 100644
--- a/sys/pc98/pc98/sound/sound_config.h
+++ b/sys/pc98/pc98/sound/sound_config.h
@@ -28,9 +28,9 @@
  *
  */
 
-#include "local.h"
-#include "os.h"
-#include "soundvers.h"
+#include <i386/isa/sound/local.h>
+#include <i386/isa/sound/os.h>
+#include <i386/isa/sound/soundvers.h>
 
 #if !defined(PSS_MPU_BASE) && defined(EXCLUDE_SSCAPE) && defined(EXCLUDE_TRIX)
 #define EXCLUDE_MPU_EMU
@@ -358,8 +358,8 @@ struct channel_info {
 #define OPEN_WRITE	2
 #define OPEN_READWRITE	3
 
-#include "sound_calls.h"
-#include "dev_table.h"
+#include <i386/isa/sound/sound_calls.h>
+#include <i386/isa/sound/dev_table.h>
 
 #ifndef DEB
 #define DEB(x)
diff --git a/sys/pc98/pc98/sound/sound_switch.c b/sys/pc98/pc98/sound/sound_switch.c
index fb665c61912e..83994e0daa5c 100644
--- a/sys/pc98/pc98/sound/sound_switch.c
+++ b/sys/pc98/pc98/sound/sound_switch.c
@@ -27,7 +27,7 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #ifdef CONFIGURE_SOUNDCARD
 
diff --git a/sys/pc98/pc98/sound/sound_timer.c b/sys/pc98/pc98/sound/sound_timer.c
index e31877967356..8e4e002f803f 100644
--- a/sys/pc98/pc98/sound/sound_timer.c
+++ b/sys/pc98/pc98/sound/sound_timer.c
@@ -29,7 +29,7 @@
  */
 
 #define SEQUENCER_C
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #ifdef CONFIGURE_SOUNDCARD
 
diff --git a/sys/pc98/pc98/sound/soundcard.c b/sys/pc98/pc98/sound/soundcard.c
index 5d37b3e5e5d4..3a06b6cd4efc 100644
--- a/sys/pc98/pc98/sound/soundcard.c
+++ b/sys/pc98/pc98/sound/soundcard.c
@@ -26,16 +26,16 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: soundcard.c,v 1.3 1996/09/03 10:24:21 asami Exp $
+ * $Id: soundcard.c,v 1.43 1996/09/10 08:26:06 bde Exp $
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 #include <vm/vm.h>
 #include <vm/vm_extern.h>
 
 #ifdef CONFIGURE_SOUNDCARD
 
-#include "dev_table.h"
+#include <i386/isa/sound/dev_table.h>
 #include <i386/isa/isa_device.h>
 #include <sys/conf.h>
 #include <sys/kernel.h>
diff --git a/sys/pc98/pc98/sound/sscape.c b/sys/pc98/pc98/sound/sscape.c
index 9204b188aab8..23d39ce2da81 100644
--- a/sys/pc98/pc98/sound/sscape.c
+++ b/sys/pc98/pc98/sound/sscape.c
@@ -27,11 +27,11 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SSCAPE)
 
-#include "coproc.h"
+#include <i386/isa/sound/coproc.h>
 
 /*
  *    I/O ports
diff --git a/sys/pc98/pc98/sound/sys_timer.c b/sys/pc98/pc98/sound/sys_timer.c
index 6366c22e3cb3..2c752f7bb89b 100644
--- a/sys/pc98/pc98/sound/sys_timer.c
+++ b/sys/pc98/pc98/sound/sys_timer.c
@@ -29,7 +29,7 @@
  */
 
 #define SEQUENCER_C
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #ifdef CONFIGURE_SOUNDCARD
 
diff --git a/sys/pc98/pc98/sound/trix.c b/sys/pc98/pc98/sound/trix.c
index 6e3db0fa7c90..21ca20a6311c 100644
--- a/sys/pc98/pc98/sound/trix.c
+++ b/sys/pc98/pc98/sound/trix.c
@@ -28,12 +28,12 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_TRIX)
 
 #ifdef INCLUDE_TRIX_BOOT
-#include "trix_boot.h"
+#include <i386/isa/sound/trix_boot.h>
 #endif
 
 static int      kilroy_was_here = 0;	/* Don't detect twice */
diff --git a/sys/pc98/pc98/sound/uart6850.c b/sys/pc98/pc98/sound/uart6850.c
index ba5aac6b5106..d925727b86de 100644
--- a/sys/pc98/pc98/sound/uart6850.c
+++ b/sys/pc98/pc98/sound/uart6850.c
@@ -28,7 +28,7 @@
  *
  */
 
-#include "sound_config.h"
+#include <i386/isa/sound/sound_config.h>
 
 #ifdef CONFIGURE_SOUNDCARD
 
@@ -236,7 +236,7 @@ uart6850_buffer_status (int dev)
 
 #define MIDI_SYNTH_NAME	"6850 UART Midi"
 #define MIDI_SYNTH_CAPS	SYNTH_CAP_INPUT
-#include "midi_synth.h"
+#include <i386/isa/sound/midi_synth.h>
 
 static struct midi_operations uart6850_operations =
 {
diff --git a/sys/pc98/pc98/syscons.c b/sys/pc98/pc98/syscons.c
index 2bc443ca4c43..87ada76daa7e 100644
--- a/sys/pc98/pc98/syscons.c
+++ b/sys/pc98/pc98/syscons.c
@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- *  $Id: syscons.c,v 1.166 1996/09/06 23:35:54 pst Exp $
+ *  $Id: syscons.c,v 1.8 1996/09/10 09:38:39 asami Exp $
  */
 
 #include "sc.h"
@@ -166,14 +166,17 @@ void    (*current_saver) __P((int blank)) = none_saver;
 #ifdef not_yet_done
 #define VIRTUAL_TTY(x)  (sccons[x] = ttymalloc(sccons[x]))
 struct  CONSOLE_TTY 	(sccons[MAXCONS] = ttymalloc(sccons[MAXCONS]))
-static const int	nsccons = MAXCONS+1;
-struct  tty         	*sccons[MAXCONS+1];
+struct  MOUSE_TTY 	(sccons[MAXCONS+1] = ttymalloc(sccons[MAXCONS+1]))
+struct  tty         	*sccons[MAXCONS+2];
 #else
 #define VIRTUAL_TTY(x)  &sccons[x]
 #define CONSOLE_TTY 	&sccons[MAXCONS]
-static struct tty     	sccons[MAXCONS+1];
+#define MOUSE_TTY 	&sccons[MAXCONS+1]
+static struct tty     	sccons[MAXCONS+2];
 #endif
 
+#define SC_MOUSE 	128
+#define SC_CONSOLE	255
 #ifdef PC98
 static u_char		default_kanji = UJIS;
 u_short         	*Crtat;
@@ -183,6 +186,7 @@ u_short			*Atrat;
 #define CGA_BUF     	pa_to_va(0xB8000)
 u_short         	*Crtat;
 #endif
+static const int	nsccons = MAXCONS+2;
 
 #define WRAPHIST(scp, pointer, offset)\
     ((scp->history) + ((((pointer) - (scp->history)) + (scp->history_size)\
@@ -198,6 +202,7 @@ static int scattach(struct isa_device *dev);
 static int scparam(struct tty *tp, struct termios *t);
 static int scprobe(struct isa_device *dev);
 static void scstart(struct tty *tp);
+static void scmousestart(struct tty *tp);
 static void scinit(void);
 static u_int scgetc(int noblock);
 static scr_stat *get_scr_stat(dev_t dev);
@@ -589,10 +594,12 @@ struct tty
 
     if (init_done == COLD)
 	return(NULL);
-    if (unit > MAXCONS || unit < 0)
-	return(NULL);
-    if (unit == MAXCONS)
+    if (unit == SC_CONSOLE)
 	return CONSOLE_TTY;
+    if (unit == SC_MOUSE)
+	return MOUSE_TTY;
+    if (unit >= MAXCONS || unit < 0)
+	return(NULL);
     return VIRTUAL_TTY(unit);
 }
 
@@ -601,10 +608,10 @@ static scr_stat
 {
     int unit = minor(dev);
 
-    if (unit > MAXCONS || unit < 0)
-	return(NULL);
-    if (unit == MAXCONS)
+    if (unit == SC_CONSOLE)
 	return console[0];
+    if (unit >= MAXCONS || unit < 0)
+	return(NULL);
     return console[unit];
 }
 
@@ -626,7 +633,7 @@ scopen(dev_t dev, int flag, int mode, struct proc *p)
     if (!tp)
 	return(ENXIO);
 
-    tp->t_oproc = scstart;
+    tp->t_oproc = (minor(dev) == SC_MOUSE) ? scmousestart : scstart;
     tp->t_param = scparam;
     tp->t_dev = dev;
     if (!(tp->t_state & TS_ISOPEN)) {
@@ -643,7 +650,7 @@ scopen(dev_t dev, int flag, int mode, struct proc *p)
     else
 	if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0)
 	    return(EBUSY);
-    if (!console[minor(dev)])
+    if (minor(dev) < MAXCONS && !console[minor(dev)])
 	console[minor(dev)] = alloc_scp();
     return((*linesw[tp->t_line].l_open)(dev, tp));
 }
@@ -887,7 +894,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
 		scp->mouse_proc = NULL;
 		scp->mouse_pid = 0;
 	    }
-	    return 0;
+	    break;
 
 	case MOUSE_SHOW:
 	    if (!(scp->status & MOUSE_ENABLED)) {
@@ -924,10 +931,23 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
 	    mouse->u.data.x = scp->mouse_xpos;
 	    mouse->u.data.y = scp->mouse_ypos;
 	    mouse->u.data.buttons = scp->mouse_buttons;
-	    return 0;
+	    break;
 
 	case MOUSE_ACTION:
-	    /* this should maybe only be settable from /dev/console SOS */
+	    /* this should maybe only be settable from /dev/mouse SOS */
+	    /* send out mouse event on /dev/mouse */
+	    if ((MOUSE_TTY)->t_state & TS_ISOPEN) {
+		u_char buf[5];
+		int i;
+
+		buf[0] = 0x80 | ((~mouse->u.data.buttons) & 0x07);
+		buf[1] = (mouse->u.data.x & 0x1fe >> 1);
+		buf[3] = (mouse->u.data.x & 0x1ff) - buf[1];
+		buf[2] = -(mouse->u.data.y & 0x1fe >> 1);
+		buf[4] = -(mouse->u.data.y & 0x1ff) - buf[2];
+		for (i=0; i<5; i++)
+	    		(*linesw[(MOUSE_TTY)->t_line].l_rint)(buf[i],MOUSE_TTY);
+	    }
 	    cur_console->mouse_xpos += mouse->u.data.x;
 	    cur_console->mouse_ypos += mouse->u.data.y;
 	    if (cur_console->mouse_signal) {
@@ -1514,9 +1534,8 @@ scstart(struct tty *tp)
     u_char buf[PCBURST];
     scr_stat *scp = get_scr_stat(tp->t_dev);
 
-    /* XXX who repeats the call when the above flags are cleared? */
     if (scp->status & SLKED || blink_in_progress)
-	return;
+	return; /* XXX who repeats the call when the above flags are cleared? */
     s = spltty();
     if (!(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))) {
 	tp->t_state |= TS_BUSY;
@@ -1533,6 +1552,26 @@ scstart(struct tty *tp)
     splx(s);
 }
 
+static void
+scmousestart(struct tty *tp)
+{
+    struct clist *rbp;
+    int s;
+    u_char buf[PCBURST];
+
+    s = spltty();
+    if (!(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))) {
+	tp->t_state |= TS_BUSY;
+	rbp = &tp->t_outq;
+	while (rbp->c_cc) {
+	    q_to_b(rbp, buf, PCBURST);
+	}
+	tp->t_state &= ~TS_BUSY;
+	ttwwakeup(tp);
+    }
+    splx(s);
+}
+
 void
 sccnprobe(struct consdev *cp)
 {
@@ -1548,7 +1587,7 @@ sccnprobe(struct consdev *cp)
     }
 
     /* initialize required fields */
-    cp->cn_dev = makedev(CDEV_MAJOR, MAXCONS);
+    cp->cn_dev = makedev(CDEV_MAJOR, SC_CONSOLE);
     cp->cn_pri = CN_INTERNAL;
 }
 
@@ -2945,7 +2984,7 @@ scinit(void)
     was = *cp;
     *cp = (u_short) 0xA55A;
     if (*cp == 0xA55A) {
-	Crtat = (u_short *)cp;
+	Crtat = (u_short *)CGA_BUF;
 	crtc_addr = COLOR_BASE;
     }
     *cp = was;
diff --git a/sys/pc98/pc98/wcd.c b/sys/pc98/pc98/wcd.c
index d6d08ddbf364..c0908170d54e 100644
--- a/sys/pc98/pc98/wcd.c
+++ b/sys/pc98/pc98/wcd.c
@@ -1135,7 +1135,7 @@ int wcd_load (struct lkm_table *lkmtp, int cmd)
 				/* Probing controller ata->ctrlr, unit u. */
 				if (ata->params[u] && ! ata->attached[u] &&
 				    wcdattach (ata, u, ata->params[u],
-				    ata->debug, ata->parent) >= 0)
+				    ata->debug) >= 0)
 				{
 					/* Drive found. */
 					ata->attached[u] = 1;