home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 11 Util
/
11-Util.zip
/
BOOTANY1.ZIP
/
BOOTANY.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-12-28
|
11KB
|
238 lines
F1_scancode equ 59
reply_interval equ 5 ; wait up to 5 seconds for reply
include bootany.inc
code segment
assume cs:Code, ds:Code, es:Code, ss:Code
org 0
bootany proc near
;
; Setup the stack
;
mov AX,CS ; Get current segment
mov DS,AX ; Set DS temporarily
cli ; disable interrupts
mov SS,AX ; set stack segment
mov SP,NewBootLocation ; initialize stack pointer
sti ; reenable interrupts
;
; DOS loads this pgm at 0000:7C00. Any boot routine
; we call also expects to execute there so the first
; exercise is to move this code somewhere else.
;
mov CX,512 ; bytes to move
mov SI,BootLocation ; Get boot address
les DI,DWORD PTR SecBoot[SI] ; Load ES=07A0,DI=0000
rep movsb ; Copy to new location
lea SI,down+NewBootLocation ; address relocated e.p.
jmp SI
down equ $
;
; Turn off Numlock (Insure DS is still 0)
;
sub AX,AX ; Clear register
mov DS,AX ; Set Data segment
mov AL,DS:[KeyboardFlags] ; Get keyboard flags
and AL,bootOpts.numlockMask[DI] ; Mask numlock flag
mov DS:[KeyboardFlags],AL ; Save keyboard flags
;
; Set up data segment
;
mov AX,ES ; Get current segment
mov DS,AX ; Set data segment
prompt:
;
; Display the menu
;
call Clear ; clear the screen
mov CX,max_partitions ; set to max partitions
xor BX,BX ; set base offset into table
mov SI,-1 ; set index
mov DL,Numeric ; get first numeric value
promptloop:
inc DL ; Increment Func Key number
cmp part.partition[BX],0 ; any entry?
je finishPrompt ; No skip rest
mov key,DL ; save in message
lea SI,FkeyMsg ; get msg addr
call Send
lea SI,part.text[BX] ; get data addr
call Send
add BX,SIZE PartData ; next entry address
loop promptloop
finishPrompt:
inc DL ; get Func key number
mov basicKey,DL ; save in message
lea SI,rombasic ; get msg address
call Send
sub AH,AH ; GetTickCount
int 1ah ; BiosTimerService
add DX,182*reply_interval/10 ; Set timeout time
mov BX,DX ; Save the timeout value
;
; Get the reply
;
reply:
mov AH,1 ; keyboard status
int 16h ; keybd bios service
jnz read_scancode ; jump if reply
sub AH,AH ; GetTickCount
int 1ah ; BiosTimerService
cmp AL,1 ; check for passing midnight
je prompt ; Reprompt if we did
cmp DX,BX ; check for timeout
jb reply ; wait for scancode
mov AL,default ; prior system id
cmp AL,'?' ; validate key
je error ; no default
jmp system ; boot default system
read_scancode:
sub AH,AH ; read keyboard
int 16h ; keybd bios service
sub AH,F1_scancode-1 ; Turn into index
jbe error ; Invalid code check
mov AL,AH ; Copy to AL
add AL,Numeric ; Make numeric
cmp AL,basicKey ; max Function key
ja error ; branch if bad response
jne system ; if not basic, branch
int 18h ; else invoke rom basic
error:
jmp prompt ; reissue prompt
;
; A valid function key was depressed (or defaulted)
; Attempt to boot the corresponding partition.
;
system:
mov key,AL ; save function key number
dec AL ; subtract for offset
sub AL,Numeric ; convert to binary
mov AH,SIZE PartData ; Get entry size
mul AH ; Get offset
mov BX,AX ; move to usable register
mov AL,part.partition[BX] ; get partition number
dec AL ; subtract for offset
mov BL,SIZE PartitionEntry ; Get entry size
mul BL ; Get offset
mov BX,AX ; move to usable register
;
; Only boot bootable partitions.
;
check:
cmp partitionTable.BootIndicator[BX],0
; bootable partition?
je error ; No - display menu again
;
; Read in and validate the partition's boot sector.
;
select:
mov DH,partitionTable.BeginHead[BX]
; head from partition table
mov DL,80h ; drive 0
mov CL,partitionTable.BeginSector[BX]
; sector from table
mov CH,partitionTable.BeginCyl[BX]
; cylinder from partition table
push BX ; Save index
les BX,DWORD PTR PrimBoot ; address primary boot loc
mov AX,201h ; function, # of sectors
int 13h ; read system boot record
pop BX ; Restore index
jc error ; exit if error
cmp word ptr ES:510,0aa55h ; test signature
jne error ; reprompt if invalid
;
; Hide the previously booted partition and unhide the
; partition to be booted.
;
mov AL,key ; get depressed key number
mov DL,default ; get last booted
mov default,AL ; save Function key number
mov DI,defaultPart ; Get default index
mov defaultPart,BX ; Save new index
cmp DL,'?' ; any default?
je SetCurrent ; no - Only set up current
cmp AL,DL ; current = default?
je EndBoot ; yes - skip reset
mov AL,partitionTable.SystemId[DI]
; Get partition type
mov partitionTable.BootIndicator[DI],AL
; Save as boot indicator
mov partitionTable.SystemId[DI],80h
; Booted part. won't see it now
SetCurrent:
mov AL,partitionTable.BootIndicator[BX]
; Get partition type
mov partitionTable.SystemId[BX],AL
; Put it where it belongs
mov partitionTable.BootIndicator[BX],80h
; Show partition is bootable
;
; Clear the screen, update the boot sector with new
; values, and give control to the partitions boot program
;
EndBoot:
call Clear ; clear the screen
mov AX,301h ; write sector
les BX,DWORD PTR SecBoot ; buffer address
mov CX,1 ; cylinder 0, sector 1
mov DX,80h ; head 0, drive 0
int 13h ; replace boot record
cli ; disable interrupts
mov SI,BootLocation ; get address of area read
jmp SI ; enter second level boot
Clear:
mov AH,15 ; return current video mode
int 10h ; bios service
sub AH,AH ; set mode
int 10h ; reset video mode
ret
Send:
cld ; reset direction flag
lodsb ; load argument from string
test AL,80h ; test for end of string
pushf ; save flags
and AL,7fh ; insure valid character
mov AH,14 ; write tty
int 10h ; bios video service
popf ; restore flags
jz Send ; do until end of string
ret ; return to caller
SecBoot dw 0,NewBootSeg ; ES=7A0, BX=0
PrimBoot dw 0,BootSeg ; ES=7C0, BX=0
FkeyMsg db 13,10,'F'
key db 'X . . .',+0A0h
rombasic db 13,10,'F'
basicKey db 'X . . . ROM BASIC',13,10,10
db 'Default: F'
default db '?',+0A0h
defaultPart dw -1
used equ $ - bootany
clearAmt equ DataAddr - used ; Assembly error if code too big
IF clearAmt
db clearAmt dup(0) ; clear rest of record
ENDIF
part PartData max_partitions dup(<>)
bootOpts BootData <>
partitionTable PartitionEntry 4 dup(<>)
bootany endp
code ends
end