home *** CD-ROM | disk | FTP | other *** search
- 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
-