www.pudn.com > bootmenu.zip > 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