Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH15h_HSize.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH15h_HSize.asm	(revision 386)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH15h_HSize.asm	(revision 392)
@@ -81,8 +81,10 @@
 ;		CX
 ;--------------------------------------------------------------------
+%ifdef MODULE_BOOT_MENU
 AH15h_GetSectorCountFromForeignDriveToDXAX:
 	mov		ah, GET_DRIVE_PARAMETERS
 	call	Int13h_CallPreviousInt13hHandler
 	jmp		SHORT ConvertAH08hReturnValuesToSectorCount
+%endif
 
 AH15h_GetSectorCountToBXDXAX:
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int19h.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int19h.asm	(revision 386)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int19h.asm	(revision 392)
@@ -22,19 +22,4 @@
 
 ;--------------------------------------------------------------------
-; INT 19h handler that properly reboots the computer when
-; INT 19h is called.
-;
-; Int19h_ResetHandler
-;	Parameters:
-;		Nothing
-;	Returns:
-;		Never returns (reboots computer)
-;--------------------------------------------------------------------
-Int19h_ResetHandler:
-	mov		ax, BOOT_FLAG_WARM				; Skip memory tests
-	jmp		Reboot_ComputerWithBootFlagInAX
-
-
-;--------------------------------------------------------------------
 ; Int19h_BootLoaderHandler
 ;	Parameters:
@@ -44,15 +29,16 @@
 ;--------------------------------------------------------------------
 Int19h_BootLoaderHandler:
-	sti
-	; Install INT 19h handler for proper reboot
-	LOAD_BDA_SEGMENT_TO	es, ax
-	mov		al, BIOS_BOOT_LOADER_INTERRUPT_19h	; INT 19h interrupt vector offset
-	mov		si, Int19h_ResetHandler				; INT 19h handler to reboot the system
-	call	Interrupts_InstallHandlerToVectorInALFromCSSI
-	call	Initialize_AndDetectDrives			; Installs new boot menu loader
-	; Fall to .PrepareStackAndSelectDriveFromBootMenu
+	sti											; Allow timer interrupts
+	LOAD_BDA_SEGMENT_TO	es, ax					; Load BDA segment (zero) to ES
+	; Fall to .PrepareBootLoaderStack
+
 
 ;--------------------------------------------------------------------
-; .PrepareStackAndSelectDriveFromBootMenu
+; Drive detection and boot menu use lots of stack so it is
+; wise to relocate stack. Otherwise something important from
+; interrupt vectors are likely corrupted, likely our own DPTs if
+; they are located to 30:0h.
+;
+; .PrepareBootLoaderStack
 ;	Parameters:
 ;		ES:		BDA and interrupt vector segment (zero)
@@ -60,13 +46,14 @@
 ;		Never returns (loads operating system)
 ;--------------------------------------------------------------------
-.PrepareStackAndSelectDriveFromBootMenu:
+.PrepareBootLoaderStack:
 	STORE_POST_STACK_POINTER
 	SWITCH_TO_BOOT_MENU_STACK
 	; Fall to .InitializeDisplay
 
+
 ;--------------------------------------------------------------------
 ; .InitializeDisplay
 ;	Parameters:
-;		Nothing
+;		ES:		BDA and interrupt vector segment (zero)
 ;	Returns:
 ;		Never returns (loads operating system)
@@ -79,57 +66,65 @@
 	int		BIOS_VIDEO_INTERRUPT_10h
 .InitializeDisplayLibrary:
-	call	BootMenuPrint_InitializeDisplayContext
-	; Fall to .SelectDriveToBootFrom
+	call	DetectPrint_InitializeDisplayContext
+	; Fall to .InitializeBiosAndDetectDrives
+
 
 ;--------------------------------------------------------------------
-; .SelectDriveToBootFrom
+; .InitializeBiosAndDetectDrives
 ;	Parameters:
-;		Nothing
+;		ES:		BDA and interrupt vector segment (zero)
+;	Returns:
+;		DS:		RAMVARS segment
+;--------------------------------------------------------------------
+	call	Initialize_AndDetectDrives	
+	; Fall to SelectDriveToBootFrom
+
+
+;--------------------------------------------------------------------
+; SelectDriveToBootFrom
+;	Parameters:
+;		DS:		RAMVARS segment
+;		ES:		BDA and interrupt vector segment (zero)
 ;	Returns:
 ;		Never returns (loads operating system)
 ;--------------------------------------------------------------------
-.SelectDriveToBootFrom:
-	call	RamVars_GetSegmentToDS
+SelectDriveToBootFrom:
+	call	HotkeyBar_UpdateDuringDriveDetection
+
 %ifdef MODULE_BOOT_MENU
-	cmp		WORD [cs:ROMVARS.wfDisplayBootMenu], BYTE 0
-	jne		SHORT ProcessBootMenuSelectionsUntilBootableDriveSelected	; Display boot menu
+	mov		di, BOOTVARS.hotkeyVars+HOTKEYVARS.bScancode
+	cmp		BYTE [es:di], BOOT_MENU_HOTKEY_SCANCODE
+	jne		SHORT .DoNotDisplayBootMenu
+
+	; Stop blinking the Boot Menu hotkey and display menu
+	mov		BYTE [es:di], 0
+	call	HotkeyBar_DrawToTopOfScreen
+	call	BootMenu_DisplayAndStoreSelectionAsHotkey
+.DoNotDisplayBootMenu:
 %endif
-	; Fall to BootFromDriveAthenTryDriveC
+
+	; Check if ROM boot (INT 18h) wanted
+	cmp		BYTE [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bScancode], ROM_BOOT_HOTKEY_SCANCODE
+	je		SHORT JumpToBootSector_or_RomBoot	; CF clear so ROM boot
+
+	; Try to boot from Primary boot drive (00h by default)
+	call	HotkeyBar_GetPrimaryBootDriveNumberToDL
+	call	TryToBootFromPrimaryOrSecondaryBootDevice
+	jc		SHORT JumpToBootSector_or_RomBoot
+
+	; Try to boot from Secondary boot device (80h by default)
+	call	HotkeyBar_GetSecondaryBootDriveNumberToDL
+	call	TryToBootFromPrimaryOrSecondaryBootDevice
+
+%ifdef MODULE_BOOT_MENU
+	; Force Boot Menu hotkey to display boot menu
+	mov		BYTE [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bScancode], BOOT_MENU_HOTKEY_SCANCODE
+	jnc		SHORT SelectDriveToBootFrom
+%endif
+	; Fall to JumpToBootSector_or_RomBoot
+
 
 ;--------------------------------------------------------------------
-; BootFromDriveAthenTryDriveC
-;	Parameters:
-;		DS:		RAMVARS segment
-;	Returns:
-;		Never returns (loads operating system)
-;--------------------------------------------------------------------
-BootFromDriveAthenTryDriveC:
-	xor		dx, dx				; DL = 00h = Floppy Drive A
-	call	BootSector_TryToLoadFromDriveDL
-	jc		SHORT Int19hMenu_JumpToBootSector_or_RomBoot
-	mov		dl, 80h				; DL = 80h = First Hard Drive (usually C)
-	call	BootSector_TryToLoadFromDriveDL
-	jmp		SHORT Int19hMenu_JumpToBootSector_or_RomBoot	; ROM Boot if error
-
-
-%ifdef MODULE_BOOT_MENU
-;--------------------------------------------------------------------
-; ProcessBootMenuSelectionsUntilBootableDriveSelected
-;	Parameters:
-;		DS:		RAMVARS segment
-;	Returns:
-;		Never returns
-;--------------------------------------------------------------------
-ProcessBootMenuSelectionsUntilBootableDriveSelected:
-	call	BootMenu_DisplayAndReturnSelectionInDX
-	call	DriveXlate_ToOrBack											; Translate drive number
-	call	BootSector_TryToLoadFromDriveDL
-	jnc		SHORT ProcessBootMenuSelectionsUntilBootableDriveSelected	; Boot failure, show menu again
-	; Fall to Int19hMenu_JumpToBootSector_or_RomBoot
-	; (CF is set or we wouldn't be here, see "jnc" immediately above)
-%endif
-
-;--------------------------------------------------------------------
-; Int19hMenu_JumpToBootSector_or_RomBoot
+; JumpToBootSector_or_RomBoot
 ;
 ; Switches back to the POST stack, clears the DS and ES registers,
@@ -140,5 +135,5 @@
 ;		DL:		Drive to boot from (translated, 00h or 80h)
 ;       CF:     Set for Boot Sector Boot 
-;               Clear for Rom Boot
+;               Clear for ROM Boot
 ;	   	ES:BX:	(if CF set) Ptr to boot sector
 ;
@@ -146,5 +141,5 @@
 ;		Never returns
 ;--------------------------------------------------------------------
-Int19hMenu_JumpToBootSector_or_RomBoot:
+JumpToBootSector_or_RomBoot:
 	mov		cx, es		; Preserve MBR segment (can't push because of stack change)
 	mov		ax, 0		; NOTE: can't use XOR (LOAD_BDA_SEGMENT_TO) as it impacts CF
@@ -167,3 +162,23 @@
 ; Boot by calling INT 18h (ROM Basic of ROM DOS)
 .romboot:
-	int		BIOS_BOOT_FAILURE_INTERRUPT_18h	; Never returns		
+	int		BIOS_BOOT_FAILURE_INTERRUPT_18h	; Never returns	
+
+
+;--------------------------------------------------------------------
+; TryToBootFromPrimaryOrSecondaryBootDevice
+;	Parameters
+;		DL:		Drive selected as boot device
+;		DS:		RAMVARS segment
+;		ES:		BDA and interrupt vector segment (zero)
+;	Returns:
+;		DL:		Drive to boot from (translated, 00h or 80h)
+;       CF:     Set for Boot Sector Boot
+;               Clear for ROM Boot
+;	   	ES:BX:	(if CF set) Ptr to boot sector
+;	Corrupts registers:
+;		AX, CX, DH, SI, DI, (DL if failed to read boot sector)
+;--------------------------------------------------------------------
+TryToBootFromPrimaryOrSecondaryBootDevice:
+	call	DriveXlate_SetDriveToSwap
+	call	DriveXlate_ToOrBack
+	jmp		BootSector_TryToLoadFromDriveDL
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int19h/BootSector.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int19h/BootSector.asm	(revision 392)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int19h/BootSector.asm	(revision 392)
@@ -0,0 +1,121 @@
+; Project name	:	XTIDE Universal BIOS
+; Description	:	Reading and jumping to boot sector.
+
+;
+; XTIDE Universal BIOS and Associated Tools 
+; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2012 by XTIDE Universal BIOS Team.
+;
+; This program is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation; either version 2 of the License, or
+; (at your option) any later version.
+; 
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+; GNU General Public License for more details.
+; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html				
+;		
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; BootSector_TryToLoadFromDriveDL
+;	Parameters:
+;		DL:		Drive to boot from (translated, 00h or 80h)
+;		DS:		RAMVARS segment
+;	Returns:
+;		ES:BX:	Ptr to boot sector (if successful)
+;		CF:		Set if boot sector loaded successfully
+;				Cleared if failed to load boot sector
+;	Corrupts registers:
+;		AX, CX, DH, SI, DI, (DL if failed to read boot sector)
+;--------------------------------------------------------------------
+BootSector_TryToLoadFromDriveDL:
+	call	DetectPrint_TryToBootFromDL
+	call	LoadFirstSectorFromDriveDL
+	jc		SHORT .FailedToLoadFirstSector
+
+	test	dl, dl
+	jns		SHORT .AlwaysBootFromFloppyDriveForBooterGames
+	cmp		WORD [es:bx+510], 0AA55h		; Valid boot sector?
+	jne		SHORT .FirstHardDiskSectorNotBootable
+.AlwaysBootFromFloppyDriveForBooterGames:
+	stc
+	ret
+.FailedToLoadFirstSector:
+	call	DetectPrint_FailedToLoadFirstSector
+	clc
+	ret
+.FirstHardDiskSectorNotBootable:
+	mov		si, g_szBootSectorNotFound
+	call	DetectPrint_NullTerminatedStringFromCSSIandSetCF
+	clc
+	ret
+
+;--------------------------------------------------------------------
+; LoadFirstSectorFromDriveDL
+;	Parameters:
+;		DL:		Drive to boot from (translated, 00h or 80h)
+;	Returns:
+;		AH:		INT 13h error code
+;		ES:BX:	Ptr to boot sector (if successful)
+;		CF:		Cleared if read successful
+;				Set if any error
+;	Corrupts registers:
+;		AL, CX, DH, DI
+;--------------------------------------------------------------------
+LoadFirstSectorFromDriveDL:
+	LOAD_BDA_SEGMENT_TO	es, bx				; ES:BX now points to...
+	mov		bx, BOOTVARS.rgbBootSect		; ...boot sector location
+	mov		di, BOOT_READ_RETRY_TIMES		; Initialize retry counter
+
+.ReadRetryLoop:
+	call	.ResetBootDriveFromDL
+	call	.LoadFirstSectorFromDLtoESBX
+	jnc		SHORT .Return
+	dec		di								; Decrement retry counter
+	jnz		SHORT .ReadRetryLoop			; Loop while retries left
+.Return:
+	ret
+
+;--------------------------------------------------------------------
+; .ResetBootDriveFromDL
+;	Parameters:
+;		DL:		Drive to boot from (translated, 00h or 80h)
+;	Returns:
+;		AH:		INT 13h error code
+;		CF:		Cleared if read successful
+;				Set if any error
+;	Corrupts registers:
+;		AL
+;--------------------------------------------------------------------
+.ResetBootDriveFromDL:
+	xor		ax, ax							; AH=0h, Disk Controller Reset
+	test	dl, dl							; Floppy drive?
+	jns		SHORT .SkipAltReset
+	mov		ah, 0Dh							; AH=Dh, Reset Hard Disk (Alternate reset)
+.SkipAltReset:
+	int		BIOS_DISK_INTERRUPT_13h
+	ret
+
+;--------------------------------------------------------------------
+; .LoadFirstSectorFromDLtoESBX
+;	Parameters:
+;		DL:		Drive to boot from (translated, 00h or 80h)
+;		ES:BX:	Destination buffer for boot sector
+;	Returns:
+;		AH:		INT 13h error code
+;		ES:BX:	Ptr to boot sector
+;		CF:		Cleared if read successful
+;				Set if any error
+;	Corrupts registers:
+;		AL, CX, DH
+;--------------------------------------------------------------------
+.LoadFirstSectorFromDLtoESBX:
+	mov		ax, 0201h						; Read 1 sector
+	mov		cx, 1							; Cylinder 0, Sector 1
+	xor		dh, dh							; Head 0
+	int		BIOS_DISK_INTERRUPT_13h
+	ret
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int19h/Int19hReset.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int19h/Int19hReset.asm	(revision 392)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int19h/Int19hReset.asm	(revision 392)
@@ -0,0 +1,35 @@
+; Project name	:	XTIDE Universal BIOS
+; Description	:	Int 19h Handler (Boot Loader).
+
+;
+; XTIDE Universal BIOS and Associated Tools 
+; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2012 by XTIDE Universal BIOS Team.
+;
+; This program is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation; either version 2 of the License, or
+; (at your option) any later version.
+; 
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+; GNU General Public License for more details.		
+; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+;		
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; INT 19h handler that properly reboots the computer when
+; INT 19h is called.
+;
+; Int19hReset_Handler
+;	Parameters:
+;		Nothing
+;	Returns:
+;		Never returns (reboots computer)
+;--------------------------------------------------------------------
+Int19hReset_Handler:
+	mov		ax, BOOT_FLAG_WARM				; Skip memory tests
+	jmp		Reboot_ComputerWithBootFlagInAX
