Subject: Re: NetBSD bootloader startable from DOS
To: None <niklas@appli.se>
From: None <Havard.Eidnes@runit.sintef.no>
List: port-i386
Date: 06/18/1995 18:13:13
Subject: port-i386/1002: Booting netbsd kernel from a DOS file
From: Havard.Eidnes@runit.sintef.no
To: gnats-admin@sun-lamp.cs.berkeley.edu
Cc: gnats-admin@sun-lamp.cs.berkeley.edu, netbsd-bugs@NetBSD.ORG
Date: Sat, 29 Apr 1995 09:50:08 -0700
Reply-To: Havard.Eidnes@runit.sintef.no


>Number:         1002
>Category:       port-i386
>Synopsis:       This adds new functionality: booting from a DOS file
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Apr 29 09:50:04 1995
>Originator:     Havard Eidnes
>Organization:
"	SINTEF RUNIT"
>Release:        1.0
>Environment:
	i486, NetBSD
System: NetBSD rype.runit.sintef.no 1.0 NetBSD 1.0 (RYPE) #60: Sat Mar 25 14:56:18 MET 1995 he@rype.runit.sintef.no:/usr/src/sys/arch/i386/compile/RYPE i386


>Description:
	This adds new functionality: boot from a DOS file with slight
	modification (mostly #ifdef'ed) to the -current boot blocks.
>How-To-Repeat:
	Can't boot from DOS files...
>Fix:
	This code is courtesy of Tor.Egge@idt.unit.no, I'm only
	responsible for the packaging and this message.

	The resulting new ordinary boot blocks have been cursorily tested,
	and they seem to work fine.

	This code implements some changes that are not #ifdef'ed:

	 - if the user typed a key during booting and e.g. made an error
	   so that the boot failed and the boot block prompts again, it
	   will now not time out and use the default the second time
	   around.

	 - a number of pushl and popl instructions have been added to
	   protect against DOS trashing these registers.

	 - the code in io.c can now avoid doing seeks in the input (which
	   made the DOS boot code easier to write).

	 - the size of the boot code and data segments have been trimmed
	   down to 64KB.

	I'm not sure about the naming conventions for directories, I've
	called the new one boot.dos, and the Makefile in that directory
	installs boot.com in /usr/mdec.

Apply this diff in /sys/arch/i386 with patch -p0:

diff -rc2 boot.old/asm.S boot/asm.S
*** boot.old/asm.S	Mon Mar 20 08:36:49 1995
--- boot/asm.S	Sat Apr 29 17:37:23 1995
***************
*** 104,111 ****
  ENTRY(prot_to_real)
  	# set up a dummy stack frame for the second seg change.
! 	movl 	_ourseg, %eax
! 	pushw	%ax
! 	movl	$xreal, %eax	# gas botches pushw $xreal - extra bytes 0, 0
! 	pushw	%ax		# decode to add %al, (%eax) (%al usually 0)
  
  	# Change to use16 mode.
--- 104,114 ----
  ENTRY(prot_to_real)
  	# set up a dummy stack frame for the second seg change.
! 	# Adjust the intersegment jump instruction following 
! 	# the clearing of protected mode bit.
! 	# This is self-modifying code, but we need a writable
! 	# code segment, and an intersegment return does not give us that.
! 
! 	movl	_ourseg, %eax
! 	movw	%ax, xreal-2
  
  	# Change to use16 mode.
***************
*** 118,126 ****
  	andl 	$~CR0_PE, %eax
  	movl	%eax, %cr0
! 
! 	# make intersegment jmp to flush the processor pipeline
! 	# using the fake stack frame set up earlier
! 	# and reload CS register
! 	lret
  
  xreal:
--- 121,128 ----
  	andl 	$~CR0_PE, %eax
  	movl	%eax, %cr0
! 	# Here we have an 16 bits intersegment jump.
! 	.byte 0xea
! 	.word xreal
! 	.word 0
  
  xreal:
diff -rc2 boot.old/bios.S boot/bios.S
*** boot.old/bios.S	Mon Mar 20 08:36:49 1995
--- boot/bios.S	Sat Apr 29 17:37:23 1995
***************
*** 56,59 ****
--- 56,192 ----
  #define	data32	.byte 0x66
  
+ #ifdef DOSREAD
+ /*
+ # MSDOS call "INT 0x21 Function 0x3d" to open a file.
+ # Call with	%ah = 0x3d
+ # 		%al = 0x0  (access and sharing modes)
+ #		%ds:%dx = ASCIZ filename
+ #		%cl = attribute mask of files to look for
+ */
+ ENTRY(dosexit)
+ 	pushl %ebp
+ 	movl  %esp, %ebp
+ 	pushl	%ebx
+ 	pushl	%esi
+ 	pushl	%edi
+ 	
+ 	movl	0x8(%ebp), %ebx # exit code
+ 
+ 	call	_C_LABEL(prot_to_real)	# enter real mode
+ 
+ 	movb	%bl, %al	# exit code
+ 	movb	$0x4c , %ah	# Exit
+ 	int	$0x21
+ 
+ 	cli
+ 	hlt
+ 
+ ENTRY(dosopen)
+ 	pushl %ebp
+ 	movl  %esp, %ebp
+ 	pushl	%ebx
+ 	pushl	%esi
+ 	pushl	%edi
+ 	
+ 	movl	0x8(%ebp), %edx # File name.
+ 	movb	$0x0 , %cl	# Attribute mask.
+ 
+ 	call	_C_LABEL(prot_to_real)	# enter real mode
+ 
+ 	movb	$0x3d, %ah	# Open existing file.
+ 	movb	$0x0 , %al	# Compatibility mode
+ 
+ 	int	$0x21
+ 
+ 	jnc	ok1
+ 	addr32
+ 	movl	%eax, _C_LABEL(doserrno)
+ 	data32
+ 	movl	$-1, %eax
+ ok1:
+ 	pushl	%eax
+ 	data32
+ 	call	_C_LABEL(real_to_prot) # back to protected mode
+ 
+ 	xorl	%eax, %eax
+ 	popw	%ax		# return value in %eax
+ 
+ 	popl	%edi
+ 	popl	%esi
+ 	popl	%ebx
+ 	popl	%ebp
+ 	ret
+ 
+ ENTRY(dosread)
+ 	pushl %ebp
+ 	movl  %esp, %ebp
+ 	pushl	%ebx
+ 	pushl	%esi
+ 	pushl	%edi
+ 	
+ 	movl	0x8(%ebp), %ebx # File handle
+ 	movl	0xc(%ebp), %edx # Buffer.
+ 	movl	0x10(%ebp) , %ecx	# Bytes to read
+ 
+ 	call	_C_LABEL(prot_to_real)	# enter real mode
+ 
+ 	movb	$0x3f, %ah	# Read from file or device
+ 	movb	$0x0 , %al	# Compatibility mode
+ 
+ 	int	$0x21
+ 	jnc	ok2
+ 	addr32
+ 	movl	%eax, _C_LABEL(doserrno)
+ 	data32
+ 	movl	$-1, %eax
+ ok2:
+ 	pushl	%eax
+ 	data32
+ 	call	_C_LABEL(real_to_prot) # back to protected mode
+ 
+ 	xorl	%eax, %eax
+ 	popw	%ax		# return value in %eax
+ 
+ 	popl	%edi
+ 	popl	%esi
+ 	popl	%ebx
+ 	popl	%ebp
+ 	ret
+ 
+ ENTRY(dosclose)
+ 	pushl %ebp
+ 	movl  %esp, %ebp
+ 	pushl	%ebx
+ 	pushl	%esi
+ 	pushl	%edi
+ 	
+ 	movl	0x8(%ebp), %ebx # File handle
+ 
+ 	call	_C_LABEL(prot_to_real)	# enter real mode
+ 
+ 	movb	$0x3e, %ah	# Close file.
+ 	movb	$0x0 , %al	# Compatibility mode
+ 
+ 	int	$0x21
+ 	jnc	ok3
+ 	addr32
+ 	movl	%eax, _C_LABEL(doserrno)
+ 	data32
+ 	movl	$-1, %eax
+ ok3:
+ 	pushl	%eax
+ 	data32
+ 	call	_C_LABEL(real_to_prot) # back to protected mode
+ 
+ 	xorl	%eax, %eax
+ 	popw	%ax		# return value in %eax
+ 	popl	%edi
+ 	popl	%esi
+ 	popl	%ebx
+ 	popl	%ebp
+ 	ret
+ 
+ #endif
+ 
  /*
  # BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
***************
*** 72,75 ****
--- 205,210 ----
  	movl	%esp, %ebp
  	pushl	%ebx
+ 	pushl	%esi
+ 	pushl	%edi
  
  	movb	16(%ebp), %dh
***************
*** 98,101 ****
--- 233,238 ----
  	movb	%bl, %al	# return value in %ax
  
+ 	popl	%edi
+ 	popl	%esi
  	popl	%ebx
  	popl	%ebp
***************
*** 121,125 ****
  	movl	%esp, %ebp
  	pushl	%ebx
! 	pushl	%ecx
  
  	movb	8(%ebp), %cl
--- 258,263 ----
  	movl	%esp, %ebp
  	pushl	%ebx
! 	pushl	%esi
! 	pushl	%edi
  
  	movb	8(%ebp), %cl
***************
*** 143,147 ****
  	call	_C_LABEL(real_to_prot)
  
! 	popl	%ecx
  	popl	%ebx
  	popl	%ebp
--- 281,286 ----
  	call	_C_LABEL(real_to_prot)
  
! 	popl	%edi
! 	popl	%esi
  	popl	%ebx
  	popl	%ebp
***************
*** 167,170 ****
--- 306,311 ----
  	movl	%esp, %ebp
  	pushl	%ebx
+ 	pushl	%esi
+ 	pushl	%edi
  
  	call	_C_LABEL(prot_to_real)
***************
*** 187,190 ****
--- 328,333 ----
  	movb	%bl, %al
  
+ 	popl	%edi
+ 	popl	%esi
  	popl	%ebx
  	popl	%ebp
***************
*** 215,218 ****
--- 358,363 ----
  	movl	%esp, %ebp
  	pushl	%ebx
+ 	pushl	%esi	
+ 	pushl	%edi
  
  	call	_C_LABEL(prot_to_real)
***************
*** 237,240 ****
--- 382,387 ----
  	movb	%bl, %al
  
+ 	popl	%edi
+ 	popl	%esi
  	popl	%ebx
  	popl	%ebp
***************
*** 252,255 ****
--- 399,404 ----
  	movl	%esp, %ebp
  	pushl	%ebx
+ 	pushl	%esi
+ 	pushl	%edi
  
  	movb	8(%ebp), %dl		# diskinfo(drive #)
***************
*** 287,290 ****
--- 436,441 ----
  	movb	%cl, %al		# max sector (and # sectors)
  
+ 	popl	%edi
+ 	popl	%esi
  	popl	%ebx
  	popl	%ebp
***************
*** 305,308 ****
--- 456,461 ----
  	movl	%esp, %ebp
  	pushl	%ebx
+ 	pushl	%esi
+ 	pushl	%edi
  
  	movl	8(%ebp), %ebx
***************
*** 329,332 ****
--- 482,487 ----
  
  	movl	%ebx, %eax
+ 	popl	%edi
+ 	popl	%esi
  	popl	%ebx
  	popl	%ebp
diff -rc2 boot.old/boot.c boot/boot.c
*** boot.old/boot.c	Mon Mar 20 08:36:50 1995
--- boot/boot.c	Sat Apr 29 17:37:23 1995
***************
*** 89,95 ****
  	* floppy or hard drive						*
  	\***************************************************************/
! 	part = 0;
! 	unit = drive&0x7f;
! 	maj = (drive&0x80 ? 0 : 2);		/* a good first bet */
  
  	name = names[currname++];
--- 89,104 ----
  	* floppy or hard drive						*
  	\***************************************************************/
! #ifdef DOSREAD
! 	if (drive== 0xff) {
! 	  maj = 5;
! 	  part = 0;
! 	  unit = 0;
! 	} else
! #endif
! 	  {
! 	    part = 0;
! 	    unit = drive&0x7f;
! 	    maj = (drive&0x80 ? 0 : 2);		/* a good first bet */
! 	  }
  
  	name = names[currname++];
***************
*** 121,126 ****
  	}
  
- 	poff = N_TXTOFF(head);
- 
  	startaddr = (int)head.a_entry;
  	addr = (startaddr & 0x00f00000); /* some MEG boundary */
--- 130,133 ----
***************
*** 142,146 ****
  	/********************************************************/
  	printf("%d", head.a_text);
! 	xread(addr, head.a_text);
  #ifdef CHECKSUM
  	if (cflag)
--- 149,154 ----
  	/********************************************************/
  	printf("%d", head.a_text);
! 	pcpy(&head, addr, sizeof(head));
! 	xread(addr+sizeof(head), head.a_text - sizeof(head));
  #ifdef CHECKSUM
  	if (cflag)
***************
*** 216,219 ****
--- 224,230 ----
  
  	putchar(']');
+ #ifdef DOSREAD
+ 	doclose();
+ #endif
  
  	/********************************************************/
***************
*** 254,258 ****
  	startaddr &= 0xffffff;
  	argv[1] = howto;
! 	argv[2] = (MAKEBOOTDEV(maj, 0, 0, unit, part));
  	argv[5] = startaddr;
  	argv[6] = (int) &x_entry;
--- 265,274 ----
  	startaddr &= 0xffffff;
  	argv[1] = howto;
! #ifdef DOSREAD
! 	if (maj==5)
! 	  argv[2] = 0;
! 	else
! #endif
! 	  argv[2] = (MAKEBOOTDEV(maj, 0, 0, unit, part));
  	argv[5] = startaddr;
  	argv[6] = (int) &x_entry;
diff -rc2 boot.old/disk.c boot/disk.c
*** boot.old/disk.c	Mon Mar 20 08:36:51 1995
--- boot/disk.c	Sat Apr 29 17:37:23 1995
***************
*** 42,46 ****
--- 42,50 ----
  #define	HEADS(di)	((((di)>>8)&0xff)+1)
  
+ #ifdef DOSREAD
+ char *devs[] = {"wd", "hd", "fd", "wt", "sd", "dos", 0};
+ #else
  char *devs[] = {"wd", "hd", "fd", "wt", "sd", 0};
+ #endif
  
  #ifdef DO_BAD144
***************
*** 149,152 ****
--- 153,158 ----
  static int ra_end;
  static int ra_first;
+ static int ra_sectors;
+ static int ra_skip;
  
  Bread(sector, addr)
***************
*** 154,157 ****
--- 160,178 ----
  	void *addr;
  {
+ 	extern int ourseg;
+ 	int dmalimit = ((((ourseg<<4)+(int)ra_buf)+65536) & ~65535)
+ 	  - ((ourseg<<4)+ (int)ra_buf);
+ 	if (dmalimit<RA_SECTORS*BPS) {
+ 	  if (dmalimit*2<RA_SECTORS*BPS) {
+ 	    ra_sectors = (RA_SECTORS*BPS-dmalimit)/BPS;
+ 	    ra_skip = RA_SECTORS - ra_sectors;
+ 	    } else {
+ 	      ra_sectors = dmalimit/BPS;
+ 	      ra_skip = 0;
+ 	    }
+ 	} else {
+ 	  ra_sectors = RA_SECTORS;
+ 	  ra_skip=0;
+ 	}
  
  	if (dosdev != ra_dev || sector < ra_first || sector >= ra_end) {
***************
*** 162,169 ****
  		sec = sector % spt;
  		nsec = spt - sec;
! 		if (nsec > RA_SECTORS)
! 			nsec = RA_SECTORS;
  		twiddle();
! 		while (biosread(dosdev, cyl, head, sec, nsec, ra_buf)) {
  			printf("Error: C:%d H:%d S:%d\n", cyl, head, sec);
  			nsec = 1;
--- 183,190 ----
  		sec = sector % spt;
  		nsec = spt - sec;
! 		if (nsec > ra_sectors)
! 		  nsec = ra_sectors;
  		twiddle();
! 		while (biosread(dosdev, cyl, head, sec, nsec, ra_buf+ra_skip*BPS)) {
  			printf("Error: C:%d H:%d S:%d\n", cyl, head, sec);
  			nsec = 1;
***************
*** 174,178 ****
  		ra_end = sector + nsec;
  	}
! 	bcopy(ra_buf + (sector - ra_first) * BPS, addr, BPS);
  }
  
--- 195,199 ----
  		ra_end = sector + nsec;
  	}
! 	bcopy(ra_buf + (sector - ra_first+ra_skip) * BPS, addr, BPS);
  }
  
diff -rc2 boot.old/io.c boot/io.c
*** boot.old/io.c	Mon Mar 20 08:36:51 1995
--- boot/io.c	Sat Apr 29 17:37:23 1995
***************
*** 138,146 ****
  	int	i;
  	char *ptr = buf;
  
  	for (i = 240000; i > 0; i--)
! 		if (ischar())
  			for (;;) {
  				register int c = getc();
  				if (c == '\n' || c == '\r') {
  					putchar('\n');
--- 138,179 ----
  	int	i;
  	char *ptr = buf;
+ 	static char hadchar=0;
  
+ #ifdef DOSREAD
+ 	/*
+ 	 *	Simulate keyboard input of the command line arguments.
+ 	 */
+ 	static int first=1;
+ 	int hadarg=0;
+ 
+ 	if (first) {
+ 	  char *arg = (char *) 0x80;
+ 	  int argcnt = *arg++;
+ 	  while (argcnt && *arg==' ') {
+ 	    arg++;
+ 	    argcnt--;
+ 	  }
+ 	  while (argcnt--) {
+ 	    if (*arg>='A' && *arg<='Z')
+ 	      *arg += 'a' - 'A';
+ 	    putchar(*arg);
+ 	    *ptr++ = *arg++;
+ 	    hadarg=1;
+ 	  }
+ 	  first=0;
+ 	}
+ #endif
  	for (i = 240000; i > 0; i--)
! 		if (ischar() || hadchar)
  			for (;;) {
  				register int c = getc();
+ 				hadchar=1;
+ #ifdef DOSREAD
+ 				if (c == 3 || c== 27 ) {
+ 				  printf("Exiting\n");
+ 				  dosexit(0);
+ 				  printf("Exiting failed\n");
+ 				}
+ #endif
  				if (c == '\n' || c == '\r') {
  					putchar('\n');
***************
*** 159,162 ****
--- 192,202 ----
  				}
  			}
+ #ifdef DOSREAD
+ 	if (hadarg) {
+ 	  putchar('\n');
+ 	  *ptr=0;
+ 	  return 1;
+ 	}
+ #endif
  	return 0;
  }
diff -rc2 boot.old/start.S boot/start.S
*** boot.old/start.S	Mon Mar 20 08:36:52 1995
--- boot/start.S	Sat Apr 29 17:37:23 1995
***************
*** 71,74 ****
--- 71,75 ----
  ENTRY(boot1)
  start:
+ #ifndef DOSREAD
  	# start (aka boot1) is loaded at 0x0:0x7c00 but we want 0x7c0:0
  	# ljmp to the next instruction to adjust %cs
***************
*** 225,229 ****
--- 226,235 ----
  	data32
  	ljmp	$BOOTSEG, $_C_LABEL(boot2)
+ #else /* !DOSREAD */
+ 	movb	$0xff, %dl
+ 	jmp	_C_LABEL(boot2)
+ #endif /* DOSREAD */
  
+ #ifndef DOSREAD
  #
  #	read_error
***************
*** 296,299 ****
--- 302,306 ----
  	ret
  
+ #endif
  
  /* Conventional GDT indexes. */
diff -rc2 boot.old/sys.c boot/sys.c
*** boot.old/sys.c	Mon Mar 20 08:36:52 1995
--- boot/sys.c	Sat Apr 29 17:37:23 1995
***************
*** 61,64 ****
--- 61,69 ----
  	int cnt2;
  
+ #ifdef DOSREAD
+ 	extern short doshandle;
+ 	if (doshandle>=0)
+ 	  return __dosread(buffer,count,copy);
+ #endif
  	while (count) {
  		off = blkoff(fs, poff);
***************
*** 213,216 ****
--- 218,226 ----
  		return 1;
  	}
+ #ifdef DOSREAD 
+ 	else if (maj == 5) {
+ 	  return dosopenrd(cp);
+ 	}
+ #endif
  	inode.i_dev = dosdev;
  	/***********************************************\
diff -rc2 boot.old/table.c boot/table.c
*** boot.old/table.c	Mon Mar 20 08:36:53 1995
--- boot/table.c	Sat Apr 29 17:37:23 1995
***************
*** 83,88 ****
  	{0xFFFF, 0x0, 0x0, 0x93, 0xCF, 0x0},	/* 0x10 : kernel data */
  			/* 0x92? */
! 	{0xFFFF, RUN, RUN, 0x9E, 0xCF, 0x0},	/* 0x18 : boot code */
! 	{0xFFFF, RUN, RUN, 0x92, 0xCF, 0x0},	/* 0x20 : boot data */
  	{0xFFFF, RUN, RUN, 0x9E, 0x0, 0x0},	/* 0x28 : boot code, 16 bits */
  };
--- 83,88 ----
  	{0xFFFF, 0x0, 0x0, 0x93, 0xCF, 0x0},	/* 0x10 : kernel data */
  			/* 0x92? */
! 	{0xFFFF, RUN, RUN, 0x9E, 0x40, 0x0},	/* 0x18 : boot code */
! 	{0xFFFF, RUN, RUN, 0x92, 0x0,  0x0},	/* 0x20 : boot data */
  	{0xFFFF, RUN, RUN, 0x9E, 0x0, 0x0},	/* 0x28 : boot code, 16 bits */
  };
diff -rc2 boot.old/version.c boot/version.c
*** boot.old/version.c	Mon Mar 20 08:36:53 1995
--- boot/version.c	Sat Apr 29 18:07:52 1995
***************
*** 4,7 ****
--- 4,10 ----
   *	NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.
   *
+  *	1.27 -> 1.27.1
+  *		adding program for booting from DOS file
+  *
   *	1.26 -> 1.27
   *		size reduction and code cleanup. (mycroft)
***************
*** 50,52 ****
   */
  
! char *version = "1.27";
--- 53,55 ----
   */
  
! char *version = "1.27.1";
*** /dev/null	Sat Apr 29 03:31:39 1995
--- boot/dossys.c	Sat Apr 29 17:37:24 1995
***************
*** 0 ****
--- 1,168 ----
+ #ifdef DOSREAD
+ 
+ #include "boot.h"
+ short doserrno;
+ short doshandle = -1;
+ void bcopy(), pcpy();
+ 
+ void _read();
+ 
+ char iobuf[MAXBSIZE];
+ 
+ char *doserrors[] ={
+   /* 00 */ "no error",
+ 	   /* 01 */ "function number invalid",
+ 	   /* 02 */ "file not found",
+ 	   /* 03 */ "path not found",
+ 	   /* 04 */ "too many open files (no handles available)",
+ 	   /* 05 */ "access denied",
+ 	   /* 06 */ "invalid handle",
+ 	   /* 07 */ "memory control block destroyed",
+ 	   /* 08 */ "insufficient memory",
+ 	   /* 09 */ "memory block address invalid",
+ 	   /* 0A */ "environment invalid (usually >32K in length)",
+ 	   /* 0B */ "format invalid",
+ 	   /* 0C */ "access code invalid",
+ 	   /* 0D */ "data invalid",
+ 	   /* 0E */ "reserved",
+ 	   /* 0F */ "invalid drive",
+ 	   /* 10 */ "attempted to remove current directory",
+ 	   /* 11 */ "not same device",
+ 	   /* 12 */ "no more files",
+ 	   /* 13 */ "disk write-protected",
+ 	   /* 14 */ "unknown unit",
+ 	   /* 15 */ "drive not ready",
+ 	   /* 16 */ "unknown command",
+ 	   /* 17 */ "data error (CRC)",
+ 	   /* 18 */ "bad request structure length",
+ 	   /* 19 */ "seek error",
+ 	   /* 1A */ "unknown media type (non-DOS disk)",
+ 	   /* 1B */ "sector not found",
+ 	   /* 1C */ "printer out of paper",
+ 	   /* 1D */ "write fault",
+ 	   /* 1E */ "read fault",
+ 	   /* 1F */ "general failure",
+ 	   /* 20 */ "sharing violation",
+ 	   /* 21 */ "lock violation",
+ 	   /* 22 */ "disk change invalid (ES:DI -> media ID structure)(see #0839)",
+ 	   /* 23 */ "FCB unavailable",
+ 	   /* 24 */ "sharing buffer overflow",
+ 	   /* 25 */ "(DOS 4+) code page mismatch",
+ 	   /* 26 */ "(DOS 4+) cannot complete file operation (out of input)",
+ 	   /* 27 */ "(DOS 4+) insufficient disk space",
+ 	   /* 28 */ "Reserved error (0x28)",
+ 	   /* 29 */ "Reserved error (0x29)",
+ 	   /* 2A */ "Reserved error (0x2A)",
+ 	   /* 2B */ "Reserved error (0x2B)",
+ 	   /* 2C */ "Reserved error (0x2C)",
+ 	   /* 2D */ "Reserved error (0x2D)",
+ 	   /* 2E */ "Reserved error (0x2E)",
+ 	   /* 2F */ "Reserved error (0x2F)",
+ 	   /* 30 */ "Reserved error (0x30)",
+ 	   /* 31 */ "Reserved error (0x31)",
+ 	   /* 32 */ "network request not supported",
+ 	   /* 33 */ "remote computer not listening",
+ 	   /* 34 */ "duplicate name on network",
+ 	   /* 35 */ "network name not found",
+ 	   /* 36 */ "network busy",
+ 	   /* 37 */ "network device no longer exists",
+ 	   /* 38 */ "network BIOS command limit exceeded",
+ 	   /* 39 */ "network adapter hardware error",
+ 	   /* 3A */ "incorrect response from network",
+ 	   /* 3B */ "unexpected network error",
+ 	   /* 3C */ "incompatible remote adapter",
+ 	   /* 3D */ "print queue full",
+ 	   /* 3E */ "queue not full",
+ 	   /* 3F */ "not enough space to print file",
+ 	   /* 40 */ "network name was deleted",
+ 	   /* 41 */ "network: Access denied",
+ 	   /* 42 */ "network device type incorrect",
+ 	   /* 43 */ "network name not found",
+ 	   /* 44 */ "network name limit exceeded",
+ 	   /* 45 */ "network BIOS session limit exceeded",
+ 	   /* 46 */ "temporarily paused",
+ 	   /* 47 */ "network request not accepted",
+ 	   /* 48 */ "network print/disk redirection paused",
+ 	   /* 49 */ "network software not installed",
+ 	   /* 4A */ "unexpected adapter close",
+ 	   /* 4B */ "(LANtastic) password expired",
+ 	   /* 4C */ "(LANtastic) login attempt invalid at this time",
+ 	   /* 4D */ "(LANtastic v3+) disk limit exceeded on network node",
+ 	   /* 4E */ "(LANtastic v3+) not logged in to network node",
+ 	   /* 4F */ "reserved",
+ 	   /* 50 */ "file exists",
+ 	   /* 51 */ "reserved",
+ 	   /* 52 */ "cannot make directory",
+ 	   /* 53 */ "fail on INT 24h",
+ 	   /* 54 */ "(DOS 3.3+) too many redirections",
+ 	   /* 55 */ "(DOS 3.3+) duplicate redirection",
+ 	   /* 56 */ "(DOS 3.3+) invalid password",
+ 	   /* 57 */ "(DOS 3.3+) invalid parameter",
+ 	   /* 58 */ "(DOS 3.3+) network write fault",
+ 	   /* 59 */ "(DOS 4+) function not supported on network",
+ 	   /* 5A */ "(DOS 4+) required system component not installed",
+ 	   /* 64 */ "(MSCDEX) unknown error",
+ 	   /* 65 */ "(MSCDEX) not ready",
+ 	   /* 66 */ "(MSCDEX) EMS memory no longer valid",
+ 	   /* 67 */ "(MSCDEX) not High Sierra or ISO-9660 format",
+ 	   /* 68 */ "(MSCDEX) door open",
+ 	 };
+ 
+ 
+ void __dosread(buffer, count, copy)
+ 	char *buffer;
+ 	int count;
+ 	void (*copy)();
+ {
+   int size;
+   int cnt2;
+   
+   while (count) {
+     size=count;
+     
+     if (size>MAXBSIZE)
+       size=MAXBSIZE;
+     
+     size=dosread(doshandle,iobuf,size);
+     twiddle();
+     copy(iobuf , buffer, size);
+     buffer += size;
+     count -= size;
+   }
+ }
+ 
+ char *printdoserror(char *header)
+ {
+   static char buf[32];
+   int max=sizeof(doserrors)/sizeof(doserrors[0]);
+   if (doserrno<max && doserrno>=0)
+     printf("%s: %s\n",header,doserrors[doserrno]);
+   else
+     printf("%s: Unknown error %d\n",header,doserrno);
+ }
+ 
+ doclose()
+ {
+   if (doshandle>=0) {
+     if (dosclose(doshandle)<0) {
+       printdoserror("Dosclose");
+       doshandle = -1;
+       return -1;
+     }
+   }
+   return 0;
+ }
+ 
+ dosopenrd(char *cp)
+ {
+   if (doshandle<0) {
+     doshandle=dosopen(cp);
+     if (doshandle<0) {
+       printdoserror("dosopen");
+       return -1;
+     }
+   }
+   return 0;
+ }
+ 
+ #endif
*** /dev/null	Sat Apr 29 03:31:39 1995
--- boot.dos/Makefile	Sat Apr 29 17:57:32 1995
***************
*** 0 ****
--- 1,74 ----
+ #	$NetBSD: Makefile,v 1.18 1995/03/23 19:46:45 jtc Exp $
+ #
+ # Ported to boot 386BSD by Julian Elischer (julian@tfs.com)
+ # September 1992
+ #
+ # 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
+ # software, derivative works or modified versions, and any portions
+ # thereof, and that both notices appear in supporting documentation.
+ #
+ # CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ # CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ # ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ #
+ # Carnegie Mellon requests users of this software to return to
+ #
+ #  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
+ #  School of Computer Science
+ #  Carnegie Mellon University
+ #  Pittsburgh PA 15213-3890
+ #
+ # any improvements or extensions that they make and grant Carnegie Mellon
+ # the rights to redistribute these changes.
+ #
+ 
+ S=	${.CURDIR}/../../..
+ 
+ ### find out what to use for libkern
+ .include "$S/lib/libkern/Makefile.inc"
+ .ifndef PROF
+ LIBKERN=	${KERNLIB}
+ .else
+ LIBKERN=	${KERNLIB_PROF}
+ .endif
+ 
+ machine-links:
+ 	-rm -f machine && \
+ 	    ln -s ${.CURDIR}/../include machine
+ 	-rm -f ${MACHINE_ARCH} && \
+ 	    ln -s ${.CURDIR}/../include ${MACHINE_ARCH}
+ 
+ all: machine-links boot.com
+ 
+ NOPROG=	noprog
+ NOMAN=	noman
+ 
+ CFLAGS=	-O6 -DKERNEL -D_KERNEL -DI386_CPU -DI486_CPU -DI586_CPU
+ CFLAGS+=-DDO_BAD144 -I. -I${.CURDIR} -I$S -I${.CURDIR}/../..
+ 
+ # Uncomment this to make the boot block talk to a serial port.
+ #CPPFLAGS+=-DSERIAL
+ # Uncomment this to make boot blocks read DOS files
+ CPPFLAGS+= -DDOSREAD
+ 
+ # start.o should be first
+ OBJS=	start.o table.o boot.o asm.o bios.o dossys.o io.o disk.o sys.o version.o
+ VPATH=	${.CURDIR}/../boot
+ 
+ boot.com: ${OBJS} ${LIBKERN}
+ 	${LD} -Bstatic -e start -N -T 0x100 -o dosboot ${OBJS} ${LIBKERN}
+ 	cp dosboot dosboot.sym
+ 	@strip dosboot
+ 	@sh ${.CURDIR}/../boot/rmaouthdr dosboot dosboot.tmp
+ 	@mv -f dosboot.tmp boot.com
+ 	@ls -l boot.com
+ 
+ install: boot.com
+ 	cp boot.com ${DESTDIR}/usr/mdec/boot.com
+ 
+ 
+ CLEANFILES+=boot.com dosboot dosboot.sym machine ${MACHINE_ARCH}
+ 
+ .include <bsd.prog.mk>
*** Makefile.old	Mon Mar 20 08:36:46 1995
--- Makefile	Sat Apr 29 18:06:13 1995
***************
*** 7,11 ****
  NOMAN=	noman
  
! SUBDIR=	boot
  
  TI386=	../i386/tags
--- 7,11 ----
  NOMAN=	noman
  
! SUBDIR=	boot boot.dos
  
  TI386=	../i386/tags
>Audit-Trail:
>Unformatted:



----Next_Part(Sun_Jun_18_18:06:45_1995)----