home *** CD-ROM | disk | FTP | other *** search
- page 61,132
- title Bstrap - update fixed disk bootstrap
- subttl Code
- page +
- Code segment
- assume cs:Code, ds:Code, es:Code, ss:Code
- org 80h
- parmLen db ?
- parm db ?
- org 100h
- include bootany.inc
- Bstrap proc far
- mov SI,DS ; Get data segment
- mov ES,SI ; Make sure the same
- ;
- ; Read current bootstrap record
- ;
- mov AX,201h ; read 1 sector
- lea BX,Boot ; buffer address
- mov CX,1 ; cyl 0, sector 1
- mov DX,80h ; head 0, drive 0
- int 13h ; read fixed disk boot
- jnc ReadOk ; Go on if ok
- mov bx,2 ; write to stderr
- mov cx,Err1l ; length of message
- lea dx,Err1 ; message address
- mov ah,40h ; write to stream
- int 21h ; send message
- jmp Exit ; Exit program
- ReadOk:
- ;
- ; Read in file named as parm (boot program)
- ; First find the program name
- ;
- sub CX,CX ; clear register
- sub SI,SI ; clear register
- mov CL,parmLen ; Get length of parm
- cmp CL,0 ; Better be there
- jbe NameError ; its not
- lea DI,parm ; get name address
- mov AL,' ' ; what we will ignore
- repe scasb
- jcxz NameError ; No parm - write msg
- jmp NameThere ; it is
- NameError:
- mov bx,2 ; write to stderr
- mov cx,NameErrl ; length of message
- lea dx,NameErr ; message address
- mov ah,40h ; write to stream
- int 21h ; send message
- jmp Exit
- ;
- ; Found the name - Open and Read the file
- ;
- NameThere:
- dec DI ; Point to first byte
- inc CX ; Correct the count
- mov BX,CX ; get bytes left
- mov [BX+DI],BYTE PTR 0 ; move in terminator
- mov DX,DI ; Get file name start
- sub AL,AL ; Open for read
- mov AH,3dh ; Open function
- int 21h ; Call DOS
- jc FileError
- lea DX,Boot ; buffer address
- mov CX,PartAddr ; maximum boot length
- mov BX,AX ; read from file
- mov AH,3fh ; read from stream
- int 21h ; dos service
- jnc FileOk ; continue if file ok
- FileError:
- mov AH,3Eh ; Close the file
- int 21h ; dos service
- mov BX,2 ; write to stderr
- mov CX,Err2l ; length of message
- lea DX,Err2 ; message address
- mov AH,40h ; write to stream
- int 21h ; send message
- jmp Exit ; Exit program
- ;
- ; The new boot program is not in our "in-memory" copy of the
- ; boot sector
- ;
- FileOk:
- ;
- ; Close the file
- ;
- mov AH,3Eh ; Close the file
- int 21h ; dos service
- ;
- ; Update the boot sector with User Data
- ; Put out first message
- ;
- mov bx,2 ; write to stderr
- mov cx,Msg1l ; length of message
- lea dx,Msg1 ; message address
- mov ah,40h ; write to stream
- int 21h ; send message
-
- mov CX,max_partitions ; get loop count
-
- PartLoop:
- ;
- ; Find out what partition this Function Key will be for
- ;
- mov Index,CX ; Save index
- sub CL,max_partitions+1 ; get negative index
- neg CL ; turn positive
- add CL,Numeric ; make displayable
- mov Q1FKey,CL ; move into message
- mov Q2FKey,CL ; move into message
- mov Q3FKey,CL ; move into message
- mov AL,max_partitions ; get max value
- add AL,Numeric ; make displayable
- mov Q1Max,AL ; move into message
- mov BX,2 ; write to stderr
- mov CX,Q1l ; length of message
- lea DX,Q1 ; message address
- mov AH,40h ; write to stream
- int 21h ; send message
- call GetChar ; Get the number
- cmp AL,'0' ; See if '0'
- jne NoExit ; If not continue
- jmp TestNumLock ; Exit loop
- NoExit:
- cmp AL,'1' ; See if valid value
- jl PartError ; No - reprompt
- cmp AL,Numeric+max_partitions ; Check max value
- ja PartError ; Too big - reprompt
- mov Q2Pnum,AL ; Save part number
- mov Err3P,AL ; Save part number
- sub AL,Numeric+1 ; Turn into index
- push AX ; Save for later
- mov AH,SIZE PartData ; Get entry size
- mul AH ; Get offset into table
- mov Data,AX ; Get data address
- mov BX,AX ; Get data address
- pop AX ; Restore value
- mov AH,SIZE PartitionEntry ; Get entry size
- mul AH ; Get offset into table
- mov Entry,AX ; Get entry address
- cmp part.partition[BX],0 ; Already in use?
- je BootTest ; No - use it
- mov BX,2 ; write to stderr
- mov CX,Err3l ; length of message
- lea DX,Err3 ; message address
- mov AH,40h ; write to stream
- int 21h ; send message
- PartError:
- mov CX,Index ; restore index
- jmp Partloop
-
- BootTest:
- ; Check to see if the partition is marked bootable -
- ; If not, see if it should be made bootable
- ;
- mov BX,Entry ; Get Entry address
- cmp partitionTable.BootIndicator[BX],0 ; Can partition boot
- jne PartBoot ; Yes - use it
- push AX ; Save for later
- mov BX,2 ; write to stderr
- mov CX,Q2l ; length of message
- lea DX,Q2 ; message address
- mov AH,40h ; write to stream
- int 21h ; send message
- call GetChar ; Get the number
- pop CX ; Restore value
- and AL,0DFh ; Convert to upper case
- cmp AL,'Y' ; See if 'Y'
- je MakeBoot ; Make it bootable
- cmp AL,'N' ; See if 'N'
- jne BootTest ; Bad reply
- jmp PartError ; Don't make it boot
- MakeBoot:
- mov partitionTable.BootIndicator[BX],80h ; Turn on boot flag
- mov AX,CX ; Restore part #
-
- PartBoot:
- mov BX,Data ; Get table offset
- mov AL,Q2Pnum ; Get part number
- sub AL,Numeric ; Convert to binary
- mov part.partition[BX],AL ; Save partition #
-
- PartBootLoop:
- ;
- ; Get partitition description from user
- ;
- mov BX,2 ; write to stderr
- mov CX,Q3l ; length of message
- lea DX,Q3 ; message address
- mov AH,40h ; write to stream
- int 21h ; send message
-
- mov CX,part_text_len ; set to text length
- cld ; copy forward
- lea DI,part.text ; Get base
- add DI,Data ; Add entry offset
- mov AL,' ' ; Get data start
- rep stosb ; Copy the data
- lea DX,TextBuffer ; get input area addr
- mov AH,10 ; Buffered Input Code
- int 21h ; Get data
- sub CX,CX ; Clear register
- mov CL,TextBuffer+1 ; Get length entered
- jcxz PartBootLoop ; Reprompt if null
- cld ; copy forward
- lea DI,part.text ; Get base
- add DI,Data ; Add entry offset
- lea SI,TextBuffer+2 ; Get data start
- rep movsb ; Copy the data
- mov CX,Index ; Restore loop index
- loop NextPart ; Set up next partition
- jmp TestNumLock
- NextPart:
- jmp PartLoop
- ;
- ; See if Num Lock should be turned off
- ;
- TestNumLock:
- mov bx,2 ; write to stderr
- mov cx,Q4l ; length of message
- lea dx,Q4 ; message address
- mov ah,40h ; write to stream
- int 21h ; send message
- call GetChar ; Get the number
- and AL,0DFh ; Convert to upper case
- cmp AL,'Y' ; See if 'Y'
- je ResetTable ; Off is default
- cmp AL,'N' ; See if 'N'
- jne TestNumLock ; Bad reply
- mov AL,NumLockOn ; Get NumLock on mask
- mov bootOpts.numlockMask,AL ; Reset Mask
- ;
- ; Swap the BootIndicator with the System Id to insure that there
- ; will be only one bootable partition at a time.
- ;
- ResetTable:
- mov CX,max_partitions ; Get number of parts
- sub BX,BX ; Clear index
- ResetTableLoop:
- mov AL,partitionTable.BootIndicator[BX] ; get indicator
- cmp AL,80h ; bootable partition?
- jne PartOk ; don't mess with it
- mov AL,partitionTable.SystemId[BX] ; Get System ID
- mov partitionTable.BootIndicator[BX],AL ; Save here
- mov partitionTable.SystemId[BX],80h ; Make System ID inv.
- PartOk:
- add BX,SIZE PartitionEntry ; Next Entry
- loop ResetTableLoop
- ;
- ; Rewrite the boot record
- ;
- lea BX,Boot ; buffer address
- mov CX,1 ; cyl 0, sector 1
- mov DX,80h ; head 0, drive 0
- mov AX,301h ; write 1 sector
- int 13h ; update boot record
- jc Exit ; exit if error
- ;
- ; Write out message
- ;
- mov BX,2 ; write to stderr
- mov CX,Msgl ; length of message
- lea DX,Msg ; message address
- mov AH,40h ; write to stream
- int 21h ; send message
- Exit:
- int 20h ; exit program
-
- TextBuffer db 16,0
- db 16 dup(0)
-
- Msg1 db 13,10,'<CTRL><BREAK> may be used to end the install '
- db 'at any time',10
- Msg1l equ $-Msg1
-
- Q1 db 13,10,'What partition should be assigned to F'
- Q1Fkey db '#? (1-'
- Q1Max db '#, 0 to end) '
- Q1l equ $-Q1
-
- Q2 db 13,10,'Partition '
- Q2Pnum db '# is not bootable.',13,10
- db ' Reply Y to make it bootable, '
- db 'N to assign F'
- Q2Fkey db '# to a new partition. '
- Q2l equ $-Q2
-
- Q3 db 13,10,'Enter partition description to be assigned to F'
- Q3Fkey db '# (15 chars max) '
- Q3l equ $-Q3
-
- Q4 db 13,10,'Do you want Num Lock turned off at boot? '
- db '(Y or N) '
- Q4l equ $-Q4
-
- Err1 db 13,10,'Error Reading Boot Sector'
- Err1l equ $-Err1
-
- NameErr db 13,10,'Invalid file name for new boot program'
- NameErrl equ $-NameErr
-
- Err2 db 13,10,'Error Reading New Boot Program'
- Err2l equ $-Err2
-
- Err3 db 13,10,'Partition '
- Err3P db '# is already defined'
- Err3l equ $-Err3
-
- msg db 13,10,'Boot record updated.',13,10
- msgl equ $-msg
-
- Index dw 0
- Entry dw 0
- Data dw 0
-
- Boot db DataAddr dup(?)
- part PartData max_partitions dup(<>)
- bootOpts BootData <>
- partitionTable PartitionEntry 4 dup(<>)
- Validation db 2 dup(0)
-
- Bstrap endp
-
- GetChar proc near
- mov AH,1 ; Get keyboard input
- int 21h
- cmp AL,0
- jne GetCharRet
- mov AH,1 ; Get extended code
- int 21h
- sub AL,AL ; show bad, not ASCII
- GetCharRet:
- ret
- GetChar endp
-
- Code ends
- end Bstrap