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