home *** CD-ROM | disk | FTP | other *** search
- 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 (while DS is still 0)
- ;
- 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
-
- mov AH,01h ; SetTickCount
- sub CX,CX ; hi-order tick count
- sub DX,DX ; lo-order tick count
- int 1ah ; BiosTimerService
- ;
- ; 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 DX,192*reply_interval/10 ; 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
- sub DH,DH ; head 0
- mov DL,80h ; 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 '?',' '+80h
- defaultPart dw -1
- used equ $ - bootany
- clearAmt equ DataAddr - used ; Assembly error if code too big
-
- db clearAmt dup(0) ; clear rest of record
-
- part PartData max_partitions dup(<>)
-
- bootOpts BootData <>
-
- partitionTable PartitionEntry 4 dup(<>)
-
- bootany endp
- code ends
-
- end