Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h.asm	(revision 417)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h.asm	(revision 421)
@@ -115,5 +115,5 @@
 ALIGN JUMP_ALIGN
 .JumpToEbiosFunction:
-	test	BYTE [di+DPT.bFlagsLow], FLG_DRVNHEAD_LBA
+	test	BYTE [di+DPT.bFlagsLow], FLGL_DPT_LBA_AND_EBIOS_SUPPORTED
 	jz		SHORT UnsupportedFunction	; No eINT 13h for CHS drives
 	sub		bl, 41h<<1					; BX = Offset to eINT 13h jump table
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH8h_HParams.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH8h_HParams.asm	(revision 417)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH8h_HParams.asm	(revision 421)
@@ -101,4 +101,8 @@
 AH8h_GetDriveParameters:
 	call	AccessDPT_GetLCHStoAXBLBH
+%ifdef RESERVE_DIAGNOSTIC_CYLINDER
+	dec		ax
+%endif
+	MIN_U	ax, MAX_LCHS_CYLINDERS
 	; Fall to .PackReturnValues
 
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm	(revision 417)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm	(revision 421)
@@ -99,5 +99,5 @@
 ;;;	SelectDrive
 	; Try to select drive and wait until ready
-	call	AccessDPT_GetDriveSelectByteToAL
+	call	AccessDPT_GetDriveSelectByteForOldInt13hToAL
 	mov		[bp+IDEPACK.bDrvAndHead], al
 	call	Device_SelectDrive
@@ -109,12 +109,17 @@
 
 ;;;	InitializeDeviceParameters
-	; Initialize CHS parameters if LBA is not used
-	test	BYTE [di+DPT.bFlagsLow], FLG_DRVNHEAD_LBA
+	; Initialize CHS parameters if LBA is not used and
+	; user has specified P-CHS parameters
+	test	BYTE [di+DPT.bFlagsLow], FLGL_DPT_ASSISTED_LBA
 	jnz		SHORT .SkipInitializeDeviceParameters		; No need to initialize CHS parameters if LBA mode enabled
+	call	AccessDPT_GetPointerToDRVPARAMStoCSBX
+	test	BYTE [cs:bx+DRVPARAMS.wFlags], FLG_DRVPARAMS_USERCHS    ; User specified P-CHS?
+	jz		SHORT .SkipInitializeDeviceParameters
 
 	; Initialize Logical Sectors per Track and Max Head number
-	mov		ah, [di+DPT.bPchsHeads]
-	dec		ah							; Max Head number
-	mov		dl, [di+DPT.bPchsSectors]	; Sectors per Track
+	mov		ax, [cs:bx+DRVPARAMS.wHeadsAndSectors]
+	dec		ax							; Max Head number
+	xchg	al, ah						; Heads now in AH
+	mov		dx, ax						; Sectors per Track now in DL
 	mov		al, COMMAND_INITIALIZE_DEVICE_PARAMETERS
 	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_BSY, FLG_STATUS_BSY)
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH48h_GetExtendedDriveParameters.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH48h_GetExtendedDriveParameters.asm	(revision 417)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH48h_GetExtendedDriveParameters.asm	(revision 421)
@@ -38,10 +38,9 @@
 ;--------------------------------------------------------------------
 AH48h_HandlerForGetExtendedDriveParameters:
-	call	AccessDPT_GetPointerToDRVPARAMStoCSBX
-	push	bx
 	call	AccessDPT_GetLbaSectorCountToBXDXAX
-	pop		di			; CS:DI now points to DRVPARAMS
 
 	; Point DS:SI to Extended Drive Information Table to fill
+	push	ds
+	pop		es			; DPT now in ES:DI
 	mov		ds, [bp+IDEPACK.intpack+INTPACK.ds]
 	mov		cx, MINIMUM_EDRIVEINFO_SIZE
@@ -51,5 +50,5 @@
 
 	; We do not support EDD Configuration Parameters so set to FFFF:FFFFh
-	mov		cx, -1		; FFFFh
+	sub		cx, BYTE MINIMUM_EDRIVEINFO_SIZE+1	; CX => FFFFh
 	mov		[si+EDRIVE_INFO.fpEDDparams], cx
 	mov		[si+EDRIVE_INFO.fpEDDparams+2], cx
@@ -59,5 +58,5 @@
 .SkipEddConfigurationParameters:
 	mov		[si+EDRIVE_INFO.wSize], cx
-	mov		WORD [si+EDRIVE_INFO.wFlags], FLG_DMA_BOUNDARY_ERRORS_HANDLED_BY_BIOS
+	mov		WORD [si+EDRIVE_INFO.wFlags], FLG_DMA_BOUNDARY_ERRORS_HANDLED_BY_BIOS | FLG_CHS_INFORMATION_IS_VALID
 
 	; Store total sector count
@@ -69,4 +68,18 @@
 	mov		WORD [si+EDRIVE_INFO.wSectorSize], 512
 
+	; Store P-CHS
+	eMOVZX	dx, BYTE [es:di+DPT.bPchsHeads]
+	xor		ax, ax									; Also a return code
+	mov		[si+EDRIVE_INFO.dwHeads], dx
+	mov		[si+EDRIVE_INFO.dwHeads+2], ax
+
+	mov		dl, [es:di+DPT.bPchsSectorsPerTrack]
+	mov		[si+EDRIVE_INFO.dwSectorsPerTrack], dx
+	mov		[si+EDRIVE_INFO.dwSectorsPerTrack+2], ax
+
+	mov		dx, [es:di+DPT.wPchsCylinders]
+	mov		[si+EDRIVE_INFO.dwCylinders], dx
+	mov		[si+EDRIVE_INFO.dwCylinders+2], ax
+
 .ReturnWithError:
 	jmp		Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/Address.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/Address.asm	(revision 417)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/Address.asm	(revision 421)
@@ -47,13 +47,13 @@
 
 ;---------------------------------------------------------------------
-; Converts LCHS parameters to IDE P-CHS parameters.
+; Converts LARGE addressing mode LCHS parameters to IDE P-CHS parameters.
 ; PCylinder	= (LCylinder << n) + (LHead / PHeadCount)
 ; PHead		= LHead % PHeadCount
 ; PSector	= LSector
 ;
-; Address_ConvertLCHStoPCHS:
+; ConvertLargeModeLCHStoPCHS:
 ;	Parameters:
 ;		BL:		Sector number (1...63)
-;		BH:		Head number (0...255)
+;		BH:		Head number (0...239)
 ;		CX:		Cylinder number (0...1023)
 ;		DS:DI:	Ptr to Disk Parameter Table
@@ -66,5 +66,5 @@
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
-ConvertLCHStoPCHS:
+ConvertLargeModeLCHStoPCHS:
 	; LHead / PHeadCount and LHead % PHeadCount
 	eMOVZX	ax, bh					; Copy L-CHS Head number to AX
@@ -82,4 +82,5 @@
 DoNotConvertLCHS:
 	ret
+
 
 ;--------------------------------------------------------------------
@@ -102,20 +103,16 @@
 Address_OldInt13hAddressToIdeAddress:
 		call	Address_ExtractLCHSparametersFromOldInt13hAddress
+		ACCESSDPT__GET_UNSHIFTED_ADDRESS_MODE_TO_AXZF
 
-		AccessDPT_GetUnshiftedAddressModeToALZF
+;;; 0: ADDRESSING_MODE_NORMAL
+		jz		SHORT DoNotConvertLCHS
 
-;;; 0: ADDR_DPT_LCHS
-		jz		DoNotConvertLCHS
+;;; 1: ADDRESSING_MODE_LARGE
+		test	al, FLGL_DPT_ASSISTED_LBA
+		jz		SHORT ConvertLargeModeLCHStoPCHS
 
-;;; 1: ADDR_DPT_PCHS
-		;
-		; Since we are only checking for zero, we can do our math in the high order bits,
-		; in this case effectively subtracting 1 from the address mode.
-		;
-		sub		al,(1<<ADDRESSING_MODE_FIELD_POSITION)
-		jz		ConvertLCHStoPCHS
+;;; 2: ADDRESSING_MODE_ASSISTED_LBA
+		; Fall through to ConvertAssistedLBAModeLCHStoLBARegisterValues
 
-;;; 2: ADDR_DPT_LBA28 and 3: ADDR_DPT_LBA48
-		; Fall through to ConvertLCHStoLBARegisterValues
 
 ;---------------------------------------------------------------------
@@ -125,10 +122,10 @@
 ;
 ; Returned address is in same registers that
-; Address_DoNotConvertLCHS and Address_ConvertLCHStoPCHS returns.
+; DoNotConvertLCHS and ConvertLargeModeLCHStoPCHS returns.
 ;
-; ConvertLCHStoLBARegisterValues:
+; ConvertAssistedLBAModeLCHStoLBARegisterValues:
 ;	Parameters:
 ;		BL:		Sector number (1...63)
-;		BH:		Head number (0...255)
+;		BH:		Head number (0...254)
 ;		CX:		Cylinder number (0...1023)
 ;		DS:DI:	Ptr to Disk Parameter Table
@@ -141,19 +138,19 @@
 ;		AX, DX
 ;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-ConvertLCHStoLBARegisterValues:
+ConvertAssistedLBAModeLCHStoLBARegisterValues:
 	; cylToSeek*headsPerCyl (18-bit result)
+	; Max = 1023 * 255 = 260,865 = 3FB01h
 	mov		ax, LBA_ASSIST_SPT		; Load Sectors per Track
 	xchg	cx, ax					; Cylinder number to AX, Sectors per Track to CX
-
 %ifdef USE_386
-	movzx	dx, [di+DPT.bLbaHeads]
+	movzx	dx, [di+DPT.bLchsHeads]
 %else
 	cwd
-	mov		dl, [di+DPT.bLbaHeads]
+	mov		dl, [di+DPT.bLchsHeads]
 %endif
 	mul		dx						; DX:AX = cylToSeek*headsPerCyl
 
 	; +=headToSeek (18-bit result)
+	; Max = 260,865 + 254 = 261,119 = 3FBFFh
 	add		al, bh					; Add Head number to DX:AX
 	adc		ah, dh					; DH = Zero after previous multiplication
@@ -161,4 +158,5 @@
 
 	; *=sectPerTrack (18-bit by 6-bit multiplication with 24-bit result)
+	; Max = 261,119 * 63 = 16,450,497 = FB03C1h
 	xchg	ax, dx					; Hiword to AX, loword to DX
 	mul		cl						; AX = hiword * Sectors per Track
@@ -169,4 +167,5 @@
 
 	; +=sectToSeek-1 (24-bit result)
+	; Max = 16,450,497 + 63 - 1 = 16,450,559 = FB03FFh
 	xor		bh, bh					; Sector number now in BX
 	dec		bx						; sectToSeek-=1
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/Prepare.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/Prepare.asm	(revision 417)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/Prepare.asm	(revision 421)
@@ -53,14 +53,10 @@
 	; Get EBIOS command index to BX
 	; LBA28 or LBA48 command
-	cwd
-	mov		al, [es:si+DAP.qwLBA+3]	; Load LBA48 byte 3 (bits 24...31)
-	and		al, 0F0h				; Clear LBA28 bits 24...27
-	or		ax, [es:si+DAP.qwLBA+4]	; Set bits from LBA bytes 4 and 5
-	cmp		dx, ax					; Set CF if any of bits 28...47 set
-	rcl		dx, 1					; DX = 0 for LBA28, DX = 1 for LBA48
 	call	Prepare_GetOldInt13hCommandIndexToBX
-	or		bx, dx					; Set block mode / single sector bit
+	mov		al, [di+DPT.bFlagsLow]
+	shl		al, 1					; Set CF if LBA48 supported
+	adc		bl, bh					; LBA48 EXT commands
 	ret
-%endif
+%endif ; MODULE_EBIOS
 
 
@@ -116,5 +112,4 @@
 ;		Nothing
 ;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
 Prepare_ByValidatingSectorsInALforOldInt13h:
 	test	al, al
