[comp.sources.misc] v15i085: BOOTMENU and PFDISK 1.3

gwr@linus.mitre.org (12/17/90)

Posting-number: Volume 15, Issue 85
Submitted-by: gwr@linus.mitre.org
Archive-name: bootmenu/part02

Here is part 2 of the BOOTMENU and PFDISK 1.3 distribution.

See the README file at the beginning of part 1 for a general
description of this package.  Program documentation for both
BOOTMENU and PFDISK are at the beginning of the shar file below.

Gordon W. Ross  (M/S E095)	internet: gwr@linus.mitre.org
The MITRE Corporation    	uucp: {decvax|philabs}!linus!gwr
Burlington Road          	office phone: 617-271-3205
Bedford, MA 01730 (U.S.A.)

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	bootmenu.doc
#	pfdisk.doc
#	SStor.txt
#	bootmenu.asm
#	bootauto.asm
#	asm2bin.bat
#	make_msc.bat
#	bootmenu.hex
#	bootauto.hex
#	hex2bin.c
# This archive created: Tue Oct 23 13:53:20 1990
# By:	Gordon W. Ross (The MITRE Corporation, Bedford, MA.)
export PATH; PATH=/bin:$PATH
echo shar: extracting "'bootmenu.doc'" '(3923 characters)'
if test -f 'bootmenu.doc'
then
	echo shar: will not over-write existing file "'bootmenu.doc'"
else
cat << \SHAR_EOF > 'bootmenu.doc'

	BOOTMENU -- a BOOT sector program with a MENU
	---------------------------------------------
		by Gordon W. Ross, Aug 1990

	This program is loaded by the PC ROM BIOS and is responsible
	for selecting one of four partitions to boot from.  The normal
	(MS-DOS) version of this program always boots the "active"
	partition, but this version allows any partition to be
	selected for booting, wether marked "active" or not.

	Two versions of this program are now distributed:

	BOOTMENU is small (less than 256 bytes of code) and compatible
	with the SpeedStor hard disk formatting package.  (Note that
	SpeedStor writes in several locations in the boot sector!)
	This version, however, does not allow unattended reboots.
	After BOOTMENU displays its partition menu, it waits
	indefinitely for someone to select a boot partition.

	BOOTAUTO (previously called "boot-hdp") is a full-featured
	boot program which allows boot-time partition selection, but
	also provides a default selection which is used if no user
	input arrives within five seconds.

	The behaviour of BOOTAUTO is as follows:

	BOOTAUTO displays the message:
		Booting device: hd0,
	and then pauses for a five second delay.

	If the user presses any key before the delay expires, a menu
	of bootable partitions is displayed, and the user is prompted
	for the number of the partition to boot from.  If no key is
	pressed before the delay ends, the first partition marked as
	"active" is used.  If no partition is marked as active, the
	boot menu is presented without delay, as if a key were struck.
	In essence, this program interprets the "active" mark (if
	present) as a default choice indicator.

	Once a partition has been selected this program displays the
	selected partition number and loads its secondary boot
	program.  Errors are printed if (1) the selected partition is
	empty, (2) the secondary boot program lacks a valid signature,
	or (3) an error occurs while reading the secondary boot sector.

	Installation:
	------------
	The "pfdisk" utility included with this program simplifies
	installation of BOOTAUTO into the primary boot sector.
	Instructions for using "pfdisk" are in the pfdisk.doc file.

	Limitations:
	-----------
	Names in the boot menu:

	BOOTMENU and BOOTAUTO contain a name table that is used to
	generate the boot menu.  This name table is recognized (using
	a signature) and updated by pfdisk but not by other fdisk
	programs. If another fdisk program is used to modify the
	partition table, the name table may be left with misleading
	entries.  Note that pfdisk only updates the name field for any
	entry when the entry is set using the optional name field, i.e:

		pfdisk> 1 4 0 127 MS-LOSS

	Furthermore, the name supplied as the fourth arg. is truncated
	to eight characters.  (Space is tight in the boot sector.)

	The signature which flags the presence of a name table is
	written into any boot sector every time the name argument is
	given in a partition setting command (1,2,3,4).  This
	signature occupies locations 0x1A0 -- 0x1AD which does not
	clobber anything used by any of: UNIX or DOS boot programs,
	SpeedStor or WesternDigital Auto-configuring controllers.

	Booting inactive partitions:

	MS-DOS will boot from an inactive partition without needing
	any modifications.  Unfortunately, some systems refuse to boot
	from a partition which is not marked as active.

	ESIX (from Everex Systems) Sys.V Rel.3.2 will not (as shipped)
	boot unless its partition is marked active.  Other versions of
	Sys.V/386 are similar in this regard.  The easiest solution is
	to mark the UNIX partition as active, and use BOOTMENU to
	offer you a choice between DOS and UNIX.

	If you wish, it is also possible to patch UNIX so that it will
	boot without demanding that its partition be marked active.
	These patches (called "esix-boot") are available from the
	author.  Send EMAIL to gwr@linus.mitre.org if you want them.

SHAR_EOF
if test 3923 -ne "`wc -c < 'bootmenu.doc'`"
then
	echo shar: error transmitting "'bootmenu.doc'" '(should have been 3923 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'pfdisk.doc'" '(6755 characters)'
if test -f 'pfdisk.doc'
then
	echo shar: will not over-write existing file "'pfdisk.doc'"
else
cat << \SHAR_EOF > 'pfdisk.doc'





PFDISK(8)	      MAINTENANCE COMMANDS		PFDISK(8)





NAME
	pfdisk - partition fixed disk

SYNOPSIS
	pfdisk device

DESCRIPTION
	pfdisk partitions the fixed disk identified as device  into  (at
	most) four parts, each of which	may be independently loaded with
	an operating system.  The actual name of device	depends	 on  the
	operating  system  in  use.   For ESIX (System V/386) the device
	name is	either "/dev/rdsk/0s0" or "/dev/rdsk/1s0".   For  Minix,
	it is "/dev/hd0" or "/dev/hd5".	 For MS-DOS it is a single digit
	(zero or one).

	pfdisk reads the hard disk partition table from	 block	zero  of
	device	into  memory  and allows the user to examine, modify, or
	save the partition table.  A regular file may be used instead of
	a  real	 device	for testing purposes, though the device	geometry
	must be	specified manually, and	some  systems  will  requrire  a
	file-name argument with	the "R"	and "W"	commands (DOS, ESIX).

	The partition table on device is NOT modified unless  the  write
	command	(W) is used with no argument.

USAGE
  Commands
	All pfdisk commands  consist  of  a  command  word  followed  by
	optional  blank-separated command arguments.  Note that	only the
	first letter of	a command word is significant (except  for  "wq"
	and  "q!").  All command letters are accepted in either	upper or
	lower case.  Numeric arguments are  specified  using  C	 syntax.
	Extra arguments	are silently ignored.

	The commands are:

	?	Prints a command summary (help).

	1 sys_id first last sys_name
		Set the	partition  table  entry	 for  part  one,  using:
		sys_id	as  its	system ID code,	first as the lowest num-
		bered cylinder it uses,	last  as  the  highest	numbered
		cylinder  it uses, and sys_name	(optional) as the system
		name (in the menu name table).

	2|3|4 sys-id first last	sys-name
		Similar	to 1 but sets partition	 two,  three,  or  four,
		respectively.





Release	1.3	      Last change: Oct 1990			1






PFDISK(8)	      MAINTENANCE COMMANDS		PFDISK(8)





	A number
		Mark partition number as active	(so it will be used  for
		booting).   If	number	is  zero,  no  partition will be
		active.

	G cylinders heads sectors
		Inform pfdisk what the geometry	of the device is.

	I	Print a	summary	of the known ID	codes.

	L	List the partition table.  See Output Format below.

	Q	Quit without saving.  If the memory copy of  the  parti-
		tion  table  was  modified, a warning will be issued and
		the command ignored.

	Q!	Quit, even if the memory copy of the partition table was
		not saved.

	R file-name
		Read boot sector from  file-name  (if  given)  otherwise
		read from device.

	W file-name
		Write boot sector to  file-name.  (if  given)  otherwise
		write to device.

	WQ	Same as	"write"	followed by "quit".

	#	This line is a comment (to be ignored).

  Output Format
	Here is	a sample of the	output from the	L command:

	# Partition table on device: /dev/rdsk/0s0
	geometry 1222 15 34 (cyls heads	sectors)
	#  ID  First(cyl)  Last(cyl)  Name     # start,	length (sectors)
	1   4	   0	    127	      MS-LOSS  # 34, 65246
	2 129	 128	    255	      Minix    # 65280,	65280
	3   0	   0	      0		       # 0, 0
	4  99	 256	   1220	      ESIX     # 130560, 492150
	# note:	 last(4): phys=(1023,14,34) logical=(1220,14,34)
	active:	4

	This output format is carefully	constructed so that  it	 may  be
	saved in a file	 (by redirecting standard output) and later used
	as input (by redirecting standard input).  On a	UNIX system, one
	can save this output using the command:





Release	1.3	      Last change: Oct 1990			2






PFDISK(8)	      MAINTENANCE COMMANDS		PFDISK(8)





		(echo L) | pfdisk device-name >	save-file

	save-file is a complete	record of the  partition  table.   On  a
	UNIX system, one could use save-file to	re-initialize the parti-
	tion table using the command:

		(cat save-file ; echo wq) | pfdisk device-name

	Consistency of each partition table entry is checked  while  the
	table is listed.  Any inconsistencies discovered are reported in
	a commentary note as shown above.

  Physical vs. Logical
	Each partition table entry has both "physical" and  a  "logical"
	fields.	  The  physical	 fields	 specify  the lowest and highest
	cylinder,head,sector combinations to be	used in	that  partition.
	The  logical  start  field has the total number	of sectors which
	precede	this partition,	and the	logical	 length	 field	has  the
	total  number  of  sectors  contained  in this partition.  These
	fields should be self consistent unless	the disk has  more  than
	1024 cylinders.

	The physical cylinder fields are only ten-bits wide so the  con-
	tents are limited to 1023. The logical sector fields are 32 bits
	wide and always	show the true logical beginning	 and  length  of
	the partition.	Generally, the physical	start field is used only
	to locate the secondary	boot sector, and the logical  start  and
	length fields are used to actually delimit the partition used by
	a particular system.

  Partition Names
	The Name field in the partition	table is  treated  specially  if
	the  bootmenu  program	is installed in	the primary boot sector.
	(See the file bootmenu.doc for	more  information.)  pfdisk  can
	recognize  the	name  table  used  by bootmenu and will	show the
	actual names present in	that name table.  If any other boot pro-
	gram  is  used	then  the  Name	 field	reflects the result of a
	table-lookup of	the system ID.

	If you provide a name when  setting  any  partition  entry,  the
	boot-sector  is	 marked	as using a name	table, so that on subse-
	quent uses of pfdisk you will see the partition	names  you  have
	specified.

  Boot program replacement
	You can	replace	the boot program in  your  boot	 sector	 without
	affecting  the	partition  table  by  using  pfdisk  as	follows.
	First, (as always) save	a copy of the current boot sector (on  a





Release	1.3	      Last change: Oct 1990			3






PFDISK(8)	      MAINTENANCE COMMANDS		PFDISK(8)





	floppy)	using the "W file" command.  Then, use the "R file" com-
	mand to	read the new boot program.  If the boot	program	read  in
	is  less  than	446  bytes  long,  the	partition  table will be
	unchanged.

	Unlike the DOS or UNIX fdisk programs, pfdisk has NO  boot  pro-
	gram  compiled	into  its  executable image.  If you wish to use
	pfdisk to partition a newly formatted hard disk, you must have a
	boot  program image available to read in using the "r file" com-
	mand.  Two boot	programs, "bootmenu.bin" and "bootauto.bin"  are
	distributed  with  pfdisk  and	should	be found with its source
	files.	See the	file bootmenu.doc for further information  about
	these boot programs.

AUTHOR
	Gordon W. Ross





































Release	1.3	      Last change: Oct 1990			4

SHAR_EOF
if test 6755 -ne "`wc -c < 'pfdisk.doc'`"
then
	echo shar: error transmitting "'pfdisk.doc'" '(should have been 6755 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'SStor.txt'" '(1041 characters)'
if test -f 'SStor.txt'
then
	echo shar: will not over-write existing file "'SStor.txt'"
else
cat << \SHAR_EOF > 'SStor.txt'

Note: SpeedStor (sstor) modifies SEVERAL locations in the boot sector!

The SpeedStor manual says it does not modify locations 0xEA -- 0x17D
BUT THEY LIE!  If you use the "Parameter Override" feature, "sstor"
(evidently) puts the new disk parameters in locations 0xEA -- 0xF9.

If you install BOOTAUTO and then run sstor, using the parameter
override feature, you will have clobbered the BOOTAUTO program in a
way such that it hangs or repeats its menu when you make a selection!
(Yes, I learned this the hard way...)

To get around this problem, I wrote a slimmed-down version of the boot
program, called BOOTMENU, which has unused "holes" strategicly placed
in the locations known to be clobbered by SpeedStor.  Though this
version has the advantage of SpeedStor compatibility, it does not have
the ability to do automatic, unattended reboots like BOOTAUTO can.

For future reference, also note that sstor will modify locations
0x17E -- 0x1BD if you create SpeedStor partitions.  To their credit,
this is indeed mentioned in the manual.

SHAR_EOF
if test 1041 -ne "`wc -c < 'SStor.txt'`"
then
	echo shar: error transmitting "'SStor.txt'" '(should have been 1041 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'bootmenu.asm'" '(5005 characters)'
if test -f 'bootmenu.asm'
then
	echo shar: will not over-write existing file "'bootmenu.asm'"
else
cat << \SHAR_EOF > 'bootmenu.asm'
	PAGE 60,132
;	bootmenu: BOOT Hard Disk Partition
;	by Gordon W. Ross, Aug 1990
;
;	See the file bootmenu.doc for user instructions.
;
;	This version of bootmenu is compatible with SpeedStor.
;	See the file sstor-bug.txt for the gory details.
;
;	The following is an outline of the program:
;
;	Relocate self from 0x7c00 to 0x0600
;	Display partition menu
;	Prompt for and read user selection
;
;	Boot from the selected partition:
;	(was selected by user, or was active)
;	Read first sector of selected partition into 0x7c00
;	Verify good second-stage boot sector (magic word)
;	Set-up correct register values and jump to it.
;

CODEORG	equ 0600h	; offset of this code in code seg
; All values computed from offsets in codeseg need to be
; adjusted by adding CODEORG to each.  The obvious method,
; using "org CODEORG" causes MASM/LINK to fill in the space.

codeseg	segment
	assume cs:codeseg, ds:codeseg

; Initial program entry point
; (Assembler is told this is at offset zero.)

main:
	; Set up the stack
	xor	ax,ax
	mov	si,7C00h	; just before load location
	cli
	mov	ss,ax
	mov	sp,si
	sti

; Relocate this code from 0:7C00h to 0:CODEORG
	mov	ds,ax
	mov	es,ax
	mov	si,7C00h	; where this program is initially loaded
	mov	di,CODEORG
	mov	cx,0100h
	cld
	rep	movsw

; Jump to relocated code (0:CODEORG)
	jmp	far ptr begin1
begin	equ	$	; The above jump lands here.

; Print partition menu from name table
menu:
	call	putnl		; print newline
	mov	si, offset pnames ; no org fix-up here!
	mov	al, '1'
prname:
	push	si
	push	ax

	call	putc
	mov	al,' '
	call	putc
	mov	cx,8		; maximum name length
	call	putn
	call	putnl

	pop	ax
	pop	si
	add	si,8
	inc	al
	cmp	al,'4'
	jbe	prname

; Prompt for and read user selection
select:
	call	putnl	; print prompt
	mov	si, offset prompt + CODEORG
	call	puts

	mov	ah,0	; Read a keystroke and print it
	int	16h
	push	ax
	call	putc
	call	putnl
	pop	ax

	sub	al,'1'	; range check and convert to index
	cmp	al,04
	jnb	select

boot:
; Boot from the selected partition.
; On entry to this section:  AL = index of ptable element

	; get address of ptable element (si = & ptable[AL])
	mov	si, offset ptable ; no org fix-up here
	mov	cl,16	; size of array element
	mul	cl		; ax = al * cl
	add	si,ax

; Check for valid system ID (non-zero)

	mov	al,[si+4]
	cmp	al,0
	jnz	id_ok
	mov	si, offset msgempty + CODEORG
	jmp	error
id_ok:

; Read first sector of selected partition into 0x7c00
; Also, mark this entry active (in RAM only) in case the
; secondary boot program looks at it (which it may).

	mov	al,80h	; active flag
	mov	[si], al
	mov	cx,5	; retry count
retry:	push	cx
	mov	dx,[si]	; drive, head
	mov	cx,[si+2]	; cyl, sector
	mov	bx,7C00h	; destination (es=0)
	mov	ax,0201h	; BIOS read one sector
	int	13h
	jnc	rd_ok
	xor	ax,ax	; reset disk
	int	13h
	pop	cx
	loop	retry
	mov	si, offset msgread + CODEORG
	jmp	error
rd_ok:	pop	cx

; Check for valid magic number in secondary boot sector
	mov	ax, 0AA55h
	assume	ds:seg0		; Actually, codeseg == seg0
	cmp	ax, magic2
	assume	ds:codeseg
	jz	magic_ok
	mov	si, offset msginvalid + CODEORG
	jmp	error
magic_ok:

; Make sure ds:si points to the booted partition, and
; Jump to the secondary boot program.
	jmp	far ptr begin2

; Jump here with si=error-message
error:
	call	puts
	call	putnl
	jmp	menu

;*************************************************************
; Subroutines
;*************************************************************
CR	EQU	13
LF	EQU	10
TAB	EQU	 9

putc	proc	near		; print char in AL
	mov	ah, 0Eh		; uses: ax, bx
	mov	bx, 07
	int	10h
	ret
putc	endp

putnl	proc	near		; print a newline
	mov	al, CR		; uses: ax, bx
	call	putc
	mov	al, LF
	call	putc
	ret
putnl	endp

puts	proc	near		; print string at address SI
	mov	cx,80		; Stop at null or CX chars
putn:	lodsb			; uses: ax, bx, cx, si
	cmp	al,0
	jz	puts_e
	push	cx
	call	putc
	pop	cx
	loop	putn
puts_e:	ret
puts	endp

;**********************************************************
; A little space here makes this program live happily with
; SpeedStor, which wants to write type-override stuff here.
;**********************************************************

	org	100h
;**********************************************************
; Strings
;**********************************************************

prompt		db	"Boot partition? (1-4) ",0
msgempty	db	"Empty!",0
msgread		db	"Read error!",0
msginvalid	db	"Invalid!",0

codeseg	ends

; Declares some offsets in segment zero
seg0	segment	at 0

	org	CODEORG + (offset begin - offset main)
begin1	equ	$

; Here is the name table used for the partition menu.
; The accompanying fdisk program updates this table.
	org	CODEORG + 180h
pnames	db	32 dup(?)

; The locations after 1AE are (reportedly) used by some
; Western Digital controllers in "auto-configure" mode.
; Don't put anything critical between here and ptable.

; Here is the partition table
	org	CODEORG + 1BEh
ptable	db	(4 * 16) dup(?)

; Here is where the secondary boot sector is loaded.
	org	7C00h
begin2	equ	$
	org	7DFEh
magic2	dw	?
seg0	ends

	end	main
SHAR_EOF
if test 5005 -ne "`wc -c < 'bootmenu.asm'`"
then
	echo shar: error transmitting "'bootmenu.asm'" '(should have been 5005 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'bootauto.asm'" '(6427 characters)'
if test -f 'bootauto.asm'
then
	echo shar: will not over-write existing file "'bootauto.asm'"
else
cat << \SHAR_EOF > 'bootauto.asm'
	PAGE 60,132
;	bootauto:  Auto-boot version of BOOTMENU program
;	by Gordon W. Ross, Aug 1990
;
;	See the file bootmenu.doc for user instructions.
;
;	The following is an outline of the program:
;
;	Relocate self from 0x7C00 to 0x0600
;	Display message "Booting from HD0,"
;	Search partition table for an active entry
;	If an active partition is found,
;		Delay while watching for key press (5 sec.)
;		If (key pressed) GOTO menu:
;		Else GOTO boot:
;		EndIf
;	Else (no active partition)
; menu:		Display partition menu
;		Prompt for and read user selection
;	EndIf
; boot:	Boot from the selected partition:
;	(was selected by user, or was active)
;	Read first sector of selected partition into 0x7c00
;	Verify good second-stage boot sector (magic word)
;	Set-up correct register values and jump to it.
;	If (Errors during boot) { complain; GOTO menu: }
;

DELAY	equ	5*18	; in ticks (1/18 sec.)
CODEORG	equ 0600h	; offset of this code in code seg
; All values computed from offsets in codeseg need to be
; adjusted by adding CODEORG to each.  The obvious method,
; using "org CODEORG" causes MASM/LINK to fill in the space.

codeseg	segment
	assume cs:codeseg, ds:codeseg

; Initial program entry point
; (Assembler is told this is at offset zero.)

main:
	; Set up the stack
	xor	ax,ax
	mov	si,7C00h	; just before load location
	cli
	mov	ss,ax
	mov	sp,si
	sti

; Relocate this code from 0:7C00h to 0:CODEORG
	mov	ds,ax
	mov	es,ax
	mov	si,7C00h	; where this program is initially loaded
	mov	di,CODEORG
	mov	cx,0100h
	cld
	rep	movsw

; Jump to relocated code (0:CODEORG)
	jmp	far ptr begin1
begin	equ	$
	mov	bp,sp	; frame pointer = 0x7C00
	sub	sp,4
; 2 words of local storage:
;	[bp-2] = ptable index [0-3]
;	[bp-4] = temporary value

; Display message "Boot device: HD0"
	mov	si, offset bootdev + CODEORG
	call	puts

; Search partition table for an active entry
	mov	al,0
search:
	call	addr_pt	; si = & ptable[AL]
	mov	DL,[si]
	cmp	DL,80h
	jz	found
	inc	al
	cmp	al,04
	jb	search
; Active partition not found
	jmp	menu

found:	; Found a partition marked active.
	mov	[bp-2],ax	; Save the ptable array index

; Delay while watching for key press (2 sec.)
; Get start time, compute end time.
	mov	ah,00
	int	1Ah		; BIOS get time of day
	add	dx, DELAY	; compute end time
	mov	[bp-4],dx	; save expiration time

; Check for key press
waitkey:
	mov	ah,1
	int	16h		; BIOS Keyboard
	jnz	menu	; key pressed

; Check for expiration of delay
	mov	ah,00
	int	1Ah		; BIOS get time of day
	sub	dx,[bp-4]
	js	waitkey	; delay not expired

; Delay has expired, so boot the active partition
	mov	al,','
	call	putc
	mov	ax,[bp-2]	; ptable index
	; the index and newline are printed later
	jmp	boot

; Display partition menu
menu:
	mov	ah,1		; flush input
	int	16h
	jz	fl_done
	mov	ah,0
	int	16h
	jmp	menu
fl_done:

; Print partition menu from name table

	call	putnl		; print newline
	mov	si, offset pnames ; no org fix-up here
	mov	al, '1'
prname:
	push	si
	push	ax

	call	putc
	mov	al,' '
	call	putc
	mov	cx,8		; maximum name length
	call	putn
	call	putnl

	pop	ax
	pop	si
	add	si,8
	inc	al
	cmp	al,'4'
	jbe	prname

; Prompt for and read user selection
select:
	call	putnl
	mov	si, offset prompt + CODEORG
	call	puts
	; Read a key and convert it to a number
	mov	ah,0
	int	16h
	sub	al,'1'
	cmp	al,04
	jnb	select
	; The key and a newline are printed below

boot:
; Boot from the selected partition.
; On entry to this section:  AL = index of ptable element

	; get address of ptable element
	call	addr_pt	; si = & ptable[AL]

	; print the parition index and a newline
	add	al,'1'
	call	putc
	call	putnl

; Check for valid system ID (non-zero)

	mov	al,[si+4]
	cmp	al,0
	jnz	id_ok
	mov	si, offset msgempty + CODEORG
	jmp	error
id_ok:

; Read first sector of selected partition into 0x7c00
; Also, mark this entry active (in RAM only) in case the
; secondary boot program looks at it (which it may).

	mov	al,80h	; active flag
	mov	[si], al
	mov	cx,5	; retry count
retry:	push	cx
	mov	dx,[si]	; drive, head
	mov	cx,[si+2]	; cyl, sector
	mov	bx,7C00h	; destination (es=0)
	mov	ax,0201h	; BIOS read one sector
	int	13h
	jnc	rd_ok
	xor	ax,ax	; reset disk
	int	13h
	pop	cx
	loop	retry
	mov	si, offset msgread + CODEORG
	jmp	error
rd_ok:	pop	cx

; Check for valid magic number in secondary boot sector
	mov	ax, 0AA55h
	assume	ds:seg0		; Actually, codeseg == seg0
	cmp	ax, magic2
	assume	ds:codeseg
	jz	magic_ok
	mov	si, offset msginvalid + CODEORG
	jmp	error
magic_ok:

; Make sure ds:si points to the booted partition, and
; Jump to the secondary boot program.
	jmp	far ptr begin2

; Jump here with si=error-message
error:
	call	puts
	call	putnl
	jmp	menu

;*************************************************************
; Subroutines
;*************************************************************
CR	EQU	13
LF	EQU	10
TAB	EQU	 9

putc	proc	near		; print char in AL
	mov	ah, 0Eh		; uses: ax, bx
	mov	bx, 07
	int	10h
	ret
putc	endp

putnl	proc	near		; print a newline
	mov	al, CR		; uses: ax, bx
	call	putc
	mov	al, LF
	call	putc
	ret
putnl	endp

puts	proc	near		; print string at address SI
	mov	cx,80		; Stop at null or CX chars
putn:	lodsb			; uses: ax, bx, cx, si
	cmp	al,0
	jz	puts_e
	push	cx
	call	putc
	pop	cx
	loop	putn
puts_e:	ret
puts	endp

addr_pt	proc	near		; set SI = address of ptable[al]
	push	ax		; uses: cx (but preserves ax)
	mov	si, offset ptable ; no org fix-up here
	mov	cl,16	; size of array element
	mul	cl		; ax = al * cl
	add	si,ax
	pop	ax
	ret
addr_pt	endp

;**********************************************************
; Strings
;**********************************************************

bootdev		db	"Boot device: hd0",0
prompt		db	"Boot partition? (1-4) ",0
msgempty	db	"Empty!",0
msgread		db	"Read error!",0
msginvalid	db	"Invalid!",0
	org	180h	; this pads the length (it seems)
codeseg	ends

; Declares some offsets in segment zero
seg0	segment	at 0

	org	CODEORG + (offset begin - offset main)
begin1	equ	$

; Here is the name table used for the partition menu.
; The accompanying fdisk program updates this table.
	org	CODEORG + 180h
pnames	db	32 dup(?)

; The locations after 1AE are (reportedly) used by some
; Western Digital controllers in "auto-configure" mode.
; Don't put anything critical between here and ptable.

; Here is the partition table
	org	CODEORG + 1BEh
ptable	db	(4 * 16) dup(?)

; Here is where the secondary boot sector is loaded.
	org	7C00h
begin2	equ	$

	org	7DFEh
magic2	dw	?

seg0	ends

	end	main
SHAR_EOF
if test 6427 -ne "`wc -c < 'bootauto.asm'`"
then
	echo shar: error transmitting "'bootauto.asm'" '(should have been 6427 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'asm2bin.bat'" '(262 characters)'
if test -f 'asm2bin.bat'
then
	echo shar: will not over-write existing file "'asm2bin.bat'"
else
cat << \SHAR_EOF > 'asm2bin.bat'
@echo off
REM This batch file builds file.bin from file.asm
if not arg%1==arg%1 goto arg
echo supply base name of file.asm, i.e. file
goto exit
:arg
echo on
masm %1,,;
link boot-hdp,;
@echo Ignore the 'no stack...' warning
del %1.obj
exe2bin %1
del %1.exe
:exit
SHAR_EOF
if test 262 -ne "`wc -c < 'asm2bin.bat'`"
then
	echo shar: error transmitting "'asm2bin.bat'" '(should have been 262 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'make_msc.bat'" '(162 characters)'
if test -f 'make_msc.bat'
then
	echo shar: will not over-write existing file "'make_msc.bat'"
else
cat << \SHAR_EOF > 'make_msc.bat'
@echo This batch file uses Microsoft C to build pfdisk.exe
@echo Note that only SMALL model has been tested...
cl -AS -o pfdisk.exe pfdisk.c syscodes.c s_msdos.c
SHAR_EOF
if test 162 -ne "`wc -c < 'make_msc.bat'`"
then
	echo shar: error transmitting "'make_msc.bat'" '(should have been 162 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'bootmenu.hex'" '(1177 characters)'
if test -f 'bootmenu.hex'
then
	echo shar: will not over-write existing file "'bootmenu.hex'"
else
cat << \SHAR_EOF > 'bootmenu.hex'
 33 C0 BE 00 7C FA 8E D0 8B E6 FB 8E D8 8E C0 BE
 00 7C BF 00 06 B9 00 01 FC F3 A5 EA 20 06 00 00
 E8 9E 00 BE 80 07 B0 31 56 50 E8 8C 00 B0 20 E8
 87 00 B9 08 00 E8 97 00 E8 86 00 58 5E 83 C6 08
 FE C0 3C 34 76 E2 E8 78 00 BE 00 07 E8 7D 00 B4
 00 CD 16 50 E8 62 00 E8 67 00 58 2C 31 3C 04 73
 E5 BE BE 07 B1 10 F6 E1 03 F0 8A 44 04 3C 00 75
 06 BE 17 07 EB 3A 90 B0 80 88 04 B9 05 00 51 8B
 14 8B 4C 02 BB 00 7C B8 01 02 CD 13 73 0D 33 C0
 CD 13 59 E2 E9 BE 1E 07 EB 16 90 59 B8 55 AA 3B
 06 FE 7D 74 06 BE 2A 07 EB 06 90 EA 00 7C 00 00
 E8 19 00 E8 0B 00 E9 67 FF B4 0E BB 07 00 CD 10
 C3 B0 0D E8 F3 FF B0 0A E8 EE FF C3 B9 50 00 AC
 3C 00 74 07 51 E8 E1 FF 59 E2 F4 C3 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 42 6F 6F 74 20 70 61 72 74 69 74 69 6F 6E 3F 20
 28 31 2D 34 29 20 00 45 6D 70 74 79 21 00 52 65
 61 64 20 65 72 72 6F 72 21 00 49 6E 76 61 6C 69
 64 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

SHAR_EOF
if test 1177 -ne "`wc -c < 'bootmenu.hex'`"
then
	echo shar: error transmitting "'bootmenu.hex'" '(should have been 1177 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'bootauto.hex'" '(1177 characters)'
if test -f 'bootauto.hex'
then
	echo shar: will not over-write existing file "'bootauto.hex'"
else
cat << \SHAR_EOF > 'bootauto.hex'
 33 C0 BE 00 7C FA 8E D0 8B E6 FB 8E D8 8E C0 BE
 00 7C BF 00 06 B9 00 01 FC F3 A5 EA 20 06 00 00
 8B EC 83 EC 04 BE 35 07 E8 EE 00 B0 00 E8 F9 00
 8A 14 80 FA 80 74 09 FE C0 3C 04 72 F0 EB 28 90
 89 46 FE B4 00 CD 1A 83 C2 5A 89 56 FC B4 01 CD
 16 75 14 B4 00 CD 1A 2B 56 FC 78 F1 B0 2C E8 A5
 00 8B 46 FE EB 46 90 B4 01 CD 16 74 06 B4 00 CD
 16 EB F4 E8 98 00 BE 80 07 B0 31 56 50 E8 86 00
 B0 20 E8 81 00 B9 08 00 E8 91 00 E8 80 00 58 5E
 83 C6 08 FE C0 3C 34 76 E2 E8 72 00 BE 46 07 E8
 77 00 B4 00 CD 16 2C 31 3C 04 73 ED E8 7A 00 04
 31 E8 52 00 E8 57 00 8A 44 04 3C 00 75 06 BE 5D
 07 EB 3A 90 B0 80 88 04 B9 05 00 51 8B 14 8B 4C
 02 BB 00 7C B8 01 02 CD 13 73 0D 33 C0 CD 13 59
 E2 E9 BE 64 07 EB 16 90 59 B8 55 AA 3B 06 FE 7D
 74 06 BE 70 07 EB 06 90 EA 00 7C 00 00 E8 19 00
 E8 0B 00 E9 61 FF B4 0E BB 07 00 CD 10 C3 B0 0D
 E8 F3 FF B0 0A E8 EE FF C3 B9 50 00 AC 3C 00 74
 07 51 E8 E1 FF 59 E2 F4 C3 50 BE BE 07 B1 10 F6
 E1 03 F0 58 C3 42 6F 6F 74 20 64 65 76 69 63 65
 3A 20 68 64 30 00 42 6F 6F 74 20 70 61 72 74 69
 74 69 6F 6E 3F 20 28 31 2D 34 29 20 00 45 6D 70
 74 79 21 00 52 65 61 64 20 65 72 72 6F 72 21 00
 49 6E 76 61 6C 69 64 21 00 00 00 00 00 00 00 00

SHAR_EOF
if test 1177 -ne "`wc -c < 'bootauto.hex'`"
then
	echo shar: error transmitting "'bootauto.hex'" '(should have been 1177 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'hex2bin.c'" '(200 characters)'
if test -f 'hex2bin.c'
then
	echo shar: will not over-write existing file "'hex2bin.c'"
else
cat << \SHAR_EOF > 'hex2bin.c'
/*
 * hex2bin - a simple hex to binary converter
 */
#include <stdio.h>
main()
{
  int c;

#ifdef MSDOS
  setmode(stdout,O_BINARY);
#endif

  while (scanf("%x", &c) == 1)
    putchar(c);
  exit(0);
}
SHAR_EOF
if test 200 -ne "`wc -c < 'hex2bin.c'`"
then
	echo shar: error transmitting "'hex2bin.c'" '(should have been 200 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0