Index: arch/i386/stand/libsa/apmprobe.c
===================================================================
RCS file: /home/mdw/cvs.sys/sys/arch/i386/stand/libsa/apmprobe.c,v
retrieving revision 1.1.1.3
retrieving revision 1.3
diff -u -r1.1.1.3 -r1.3
--- arch/i386/stand/libsa/apmprobe.c	30 Jun 2002 22:31:15 -0000	1.1.1.3
+++ arch/i386/stand/libsa/apmprobe.c	27 Jul 2002 00:35:32 -0000	1.3
@@ -68,6 +68,8 @@
 
 extern int debug;
 
+static int apm_is_connected;
+
 static __inline u_int
 apm_check()
 {
@@ -101,6 +103,7 @@
 			 : "=a" (rv)
 			 : "0" (APM_DISCONNECT), "b" (APM_DEV_APM_BIOS)
 			 : "%ecx", "%edx", "cc");
+	if (!(rv & 0xff)) apm_is_connected = 0;
 	return (rv & 0xff)? rv >> 8 : 0;
 }
 
@@ -145,6 +148,7 @@
 			ai->apm_code16_base, ai->apm_code16_len,
 			ai->apm_data_base,   ai->apm_data_len);
 #endif
+	apm_is_connected = 2;
 	/* inform apm bios about our driver version */
 	__asm __volatile (DOINT(0x15) "\n\t"
 			  "setc %b1\n\t"
@@ -158,8 +162,61 @@
 	return 0;
 }
 
+static __inline int
+apm_driver_version(v)
+{
+	register u_int16_t rv;
+	__asm __volatile(DOINT(0x15) "\n\t"
+			 "setc %b0"
+			 : "=a" (rv)
+			 : "0" (APM_DRIVER_VERSION), "b" (APM_DEV_APM_BIOS), "c" (v)
+			 : "%edx", "cc");
+	return (rv & 0xff)? rv >> 8 : 0;
+}
+
+static __inline int
+apm_connect_real(ai)
+	bios_apminfo_t *ai;
+{
+	register u_int16_t f;
+	__asm __volatile (DOINT(0x15) "\n\t"
+			  "setc %b1\n\t"
+			  "movb %%ah, %h1\n\t"
+			  "movzwl %%ax, %%eax\n\tshll $4, %0\n\t"
+			  "movzwl %%cx, %%ecx\n\tshll $4, %2\n\t"
+			  "movzwl %%dx, %%edx\n\tshll $4, %3\n\t"
+			  : "=a" (ai->apm_code32_base),
+			    "=b" (f),
+			    "=c" (ai->apm_code16_base),
+			    "=d" (ai->apm_data_base)
+			  : "0" (APM_REAL_CONNECT), "1" (APM_DEV_APM_BIOS)
+			  : "cc");
+	ai->apm_entry    = BIOS_regs.biosr_bx;
+#if 0
+	ai->apm_code_len = BIOS_regs.biosr_si & 0xffff;
+	ai->apm_data_len = BIOS_regs.biosr_di & 0xffff;
+#else
+	ai->apm_code_len = 0x10000;
+	ai->apm_data_len = 0x10000;
+#endif
+	if (!(f & 0xff)) apm_is_connected = 1;
+	return (f & 0xff)? f >> 8 : 0;
+}
+
 static bios_apminfo_t ai;
 
+static __inline int
+apm_set_power_state(devices, how)
+{
+	register u_int16_t rv;
+	__asm __volatile(DOINT(0x15) "\n\t"
+			 "setc %b0"
+			 : "=a" (rv)
+			 : "0" (APM_SET_PWR_STATE), "b" (devices), "c" (how)
+			 : "%edx", "cc");
+	return (rv & 0xff)? rv >> 8 : 0;
+}
+
 void
 apmprobe()
 {
@@ -196,3 +253,49 @@
 			i386_round_page(ai.apm_data_base + ai.apm_data_len));
 }
 
+void
+apmturnoff(a1,a2)
+	int a1, a2;
+{
+	bios_apminfo_t ai;
+	int f;
+
+	if (a1 == -1) a1 = APM_DEV_ALLDEVS;
+	if (a2 == -1) a2 = APM_SYS_OFF;
+	if ((ai.apm_detail = apm_check())) {
+
+		apm_disconnect();
+		if (apm_connect_real(&ai) != 0)
+			printf("apmturnoff: connect error\n");
+		else {
+			f = apm_driver_version(0x0102);
+			if (f)
+			{
+			f = apm_driver_version(0x0101);
+			if (f)
+			printf ("apmturnoff: driver_version returned %x\n", f);
+			else printf ("apmturnoff: 1.1 connection\n");
+			}
+			
+			f = apm_set_power_state(a1, a2);
+			printf ("apmturnoff: apm_set_power_state returned %x\n",
+				 f);
+			printf ("apmturnoff: detail=%x\n",
+				ai.apm_detail);
+		}
+	} else
+		printf ("apmturnoff: apm_check returned 0\n");
+}
+
+/*
+ *	if we are booting into dos, we should not
+ *	leave apm connected in "real mode".  Try to
+ *	leave apm in the "reset" state.
+ */
+
+void
+apm_reset()
+{
+	if (apm_is_connected)
+		apm_disconnect();
+}
Index: arch/i386/stand/libsa/cmd_i386.c
===================================================================
RCS file: /home/mdw/cvs.sys/sys/arch/i386/stand/libsa/cmd_i386.c,v
retrieving revision 1.1.1.2
retrieving revision 1.3
diff -u -r1.1.1.2 -r1.3
--- arch/i386/stand/libsa/cmd_i386.c	24 Apr 2002 12:38:01 -0000	1.1.1.2
+++ arch/i386/stand/libsa/cmd_i386.c	27 Jul 2002 00:35:58 -0000	1.3
@@ -50,6 +50,7 @@
 int Xdiskinfo(void);
 int Xmemory(void);
 int Xregs(void);
+int Xturnoff (void);
 
 /* From gidt.S */
 int bootbuf(void *, int);
@@ -61,6 +62,7 @@
 #ifdef DEBUG
 	{ "regs",     CMDT_CMD, Xregs },
 #endif
+	{ "off",     CMDT_CMD, Xturnoff },
 	{ NULL, 0 }
 };
 
@@ -83,6 +85,27 @@
 #endif
 
 int
+Xturnoff()
+{
+	int a1, a2;
+	a1 = a2 = -1;
+	switch(cmd.argc)
+	{
+	case 0:
+		printf("machine off [dev [how] ]\n");
+		return 0;
+	case 1:
+		break;
+	case 3:
+		a2 = strtol(cmd.argv[2], NULL, 0);
+	case 2:
+		a1 = strtol(cmd.argv[1], NULL, 0);
+	}
+	apmturnoff(a1, a2);
+	return 0;
+}
+
+int
 Xboot()
 {
 #ifndef _TEST
@@ -112,7 +135,7 @@
 	dev += (cmd.argv[1][2] - '0');
 	part = (cmd.argv[1][3] - 'a');
 
-	if (part > 0)
+	if (part >= 0)
 		printf("[%x,%d]\n", dev, part);
 	else
 		printf("[%x]\n", dev);
@@ -122,7 +145,7 @@
 	if(st) goto bad;
 
 	/* Frob boot flag in buffer from HD */
-	if((dev & 0x80) && (part > 0)){
+	if((dev & 0x80) && (part >= 0)){
 		int i, j;
 
 		for(i = 0, j = DOSPARTOFF; i < 4; i++, j += 16)
@@ -131,6 +154,7 @@
 			else
 				buf[j] &= ~0x80;
 	}
+	apm_reset();
 
 	/* Load %dl, ljmp */
 	bcopy(buf, dest, DEV_BSIZE);
Index: arch/i386/stand/libsa/diskprobe.c
===================================================================
RCS file: /home/mdw/cvs.sys/sys/arch/i386/stand/libsa/diskprobe.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -u -r1.1.1.2 -r1.2
--- arch/i386/stand/libsa/diskprobe.c	24 Apr 2002 12:38:02 -0000	1.1.1.2
+++ arch/i386/stand/libsa/diskprobe.c	6 Jul 2002 22:43:18 -0000	1.2
@@ -84,10 +84,17 @@
 
 		/* Fill out best we can - (fd?) */
 		dip->bios_info.bsd_dev = MAKEBOOTDEV(2, 0, 0, i, RAW_PART);
+#if 0
 		if((bios_getdisklabel(&dip->bios_info, &dip->disklabel)) != 0) 
 			dip->bios_info.flags |= BDI_BADLABEL;
 		else
 			dip->bios_info.flags |= BDI_GOODLABEL;
+#else
+	/* don't try to read the (missing) floppy drive on my laptop;
+	 * I might have the cd-rom drive inserted instead.  -mdw
+	 */
+		dip->bios_info.flags |= BDI_BADLABEL;
+#endif
 
 		/* Add to queue of disks */
 		TAILQ_INSERT_TAIL(&disklist, dip, list);
Index: arch/i386/stand/libsa/libsa.h
===================================================================
RCS file: /home/mdw/cvs.sys/sys/arch/i386/stand/libsa/libsa.h,v
retrieving revision 1.1.1.3
retrieving revision 1.2
diff -u -r1.1.1.3 -r1.2
--- arch/i386/stand/libsa/libsa.h	30 Jun 2002 22:31:15 -0000	1.1.1.3
+++ arch/i386/stand/libsa/libsa.h	6 Jul 2002 22:43:18 -0000	1.2
@@ -57,6 +57,12 @@
 void *getSYSCONFaddr(void);
 void *getEBDAaddr(void);
 
+void apmturnoff (int, int);
+void apm_reset (void);
+
+void devboot (dev_t, char *);
+void machdep (void);
+
 extern const char bdevs[][4];
 extern const int nbdevs;
 extern u_int cnvmem, extmem; /* XXX global pass memprobe()->machdep_start() */
Index: stand/boot/cmd.c
===================================================================
RCS file: /home/mdw/cvs.sys/sys/stand/boot/cmd.c,v
retrieving revision 1.1.1.3
retrieving revision 1.4
diff -u -r1.1.1.3 -r1.4
--- stand/boot/cmd.c	26 Jul 2002 20:53:52 -0000	1.1.1.3
+++ stand/boot/cmd.c	11 Aug 2002 05:29:58 -0000	1.4
@@ -86,8 +86,19 @@
 {
 	cmd.cmd = NULL;
 
-	if (!readline(cmd_buf, sizeof(cmd_buf), cmd.timeout))
+	switch (readline(cmd_buf, sizeof(cmd_buf), cmd.timeout))
+	{
+	default:
+		cmd.timeout = 0;
+		break;
+	case 0:
+		cmd.timeout = 0;
 		cmd.cmd = cmd_table;
+		break;
+	case -1:
+		strncpy(cmd_buf, "boot", 5);
+		break;
+	}
 
 	return docmd();
 }
@@ -238,11 +249,16 @@
 			if (!(i++ % 1000) && (getsecs() >= tt))
 				break;
 
+#if 0
 		if (!cnischar()) {
 			strncpy(buf, "boot", 5);
 			putchar('\n');
 			return strlen(buf);
 		}
+#else
+		if (!cnischar())
+			return -1;
+#endif
 	} else
 		while (!cnischar()) ;
 
