Index: trunk/XTIDE_Universal_BIOS/Inc/CustomDPT.inc
===================================================================
--- trunk/XTIDE_Universal_BIOS/Inc/CustomDPT.inc	(revision 541)
+++ trunk/XTIDE_Universal_BIOS/Inc/CustomDPT.inc	(revision 542)
@@ -37,9 +37,10 @@
 	.bLchsHeads				resb	1	; (1...255)
 	.bLchsSectorsPerTrack	resb	1	; (1...63)
+	.wPchsHeadsAndSectors:
 	.bPchsHeads				resb	1	; (1...16)
+	.bPchsSectorsPerTrack	resb	1	; (1...63)
 
 	; LBA and remaining P-CHS variables
 %ifdef MODULE_EBIOS
-	.bPchsSectorsPerTrack	resb	1
 	.wPchsCylinders			resb	2
 	.twLbaSectors			resb	6	; 48-bit sector count for LBA addressing
@@ -56,6 +57,6 @@
 	FLGL_DPT_ENABLE_IRQ					EQU	(1<<5)				; Bit 5, Enable IRQ
 %endif
+	FLGL_DPT_LBA						EQU	FLG_DRVNHEAD_LBA	; Bit 6, Drive supports LBA and so EBIOS functions can be supported
 %ifdef MODULE_EBIOS
-	FLGL_DPT_LBA_AND_EBIOS_SUPPORTED	EQU	FLG_DRVNHEAD_LBA	; Bit 6, Drive supports LBA and so EBIOS functions can be supported
 	FLGL_DPT_LBA48						EQU	(1<<7)				; Bit 7, Drive supports 48-bit LBA (Must be bit 7!)
 %endif
Index: trunk/XTIDE_Universal_BIOS/Inc/EBIOS.inc
===================================================================
--- trunk/XTIDE_Universal_BIOS/Inc/EBIOS.inc	(revision 541)
+++ trunk/XTIDE_Universal_BIOS/Inc/EBIOS.inc	(revision 542)
@@ -44,6 +44,7 @@
 endstruc
 
-MINIMUM_EDRIVEINFO_SIZE		EQU		26	; 26 bytes does not include EDD pointer
-EDRIVEINFO_SIZE_WITH_DPTE	EQU		EDRIVE_INFO_size
+MINIMUM_EDRIVEINFO_SIZE			EQU		26	; 26 bytes does not include EDD pointer
+EDRIVEINFO_SIZE_WITH_DPTE		EQU		EDRIVE_INFO_size
+MAX_SECTOR_COUNT_TO_RETURN_PCHS	EQU		15482880
 
 ; Flags for EDRIVE_INFO.wFlags
Index: trunk/XTIDE_Universal_BIOS/Inc/RomVars.inc
===================================================================
--- trunk/XTIDE_Universal_BIOS/Inc/RomVars.inc	(revision 541)
+++ trunk/XTIDE_Universal_BIOS/Inc/RomVars.inc	(revision 542)
@@ -194,6 +194,7 @@
 	MAX_USER_HEADS					EQU	16
 	MAX_USER_SECTORS_PER_TRACK		EQU	63
+	MAX_USER_CHS_COUNT				EQU	(MAX_USER_CYLINDERS * MAX_USER_HEADS * MAX_USER_SECTORS_PER_TRACK)
 FLG_DRVPARAMS_USERLBA			EQU	(1<<6)	; User specified LBA value
-	MIN_USER_LBA_COUNT				EQU	((MAX_USER_CYLINDERS*MAX_USER_HEADS*MAX_USER_SECTORS_PER_TRACK)+1)
+	MIN_USER_LBA_COUNT				EQU	(MAX_USER_CHS_COUNT+1)
 	MAX_USER_LBA_COUNT				EQU	((2^28)-1)
 
Index: trunk/XTIDE_Universal_BIOS/Src/Device/Idepack.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/Idepack.asm	(revision 541)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/Idepack.asm	(revision 542)
@@ -70,5 +70,5 @@
 
 	and		ah, 0Fh						; Limit bits for LBA28
-	call	AccessDPT_GetDriveSelectByteForEbiosToAL
+	call	AccessDPT_GetDriveSelectByteToAL
 	or		al, ah
 	mov		[bp+IDEPACK.bDrvAndHead], al
@@ -108,5 +108,5 @@
 	push	bx
 	call	Address_OldInt13hAddressToIdeAddress
-	call	AccessDPT_GetDriveSelectByteForOldInt13hToAL
+	call	AccessDPT_GetDriveSelectByteToAL
 	or		al, bh			; AL now has Drive and Head Select Byte
 	mov		[bp+IDEPACK.bDrvAndHead], al
@@ -150,5 +150,5 @@
 	; Drive and Head select byte
 	and		ah, MASK_DRVNHEAD_HEAD		; Keep head bits only
-	call	AccessDPT_GetDriveSelectByteForOldInt13hToAL
+	call	AccessDPT_GetDriveSelectByteToAL
 	or		al, ah
 	mov		[bp+IDEPACK.bDrvAndHead], al
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h.asm	(revision 541)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h.asm	(revision 542)
@@ -123,5 +123,5 @@
 ALIGN JUMP_ALIGN
 .JumpToEbiosFunction:
-	test	BYTE [di+DPT.bFlagsLow], FLGL_DPT_LBA_AND_EBIOS_SUPPORTED
+	test	BYTE [di+DPT.bFlagsLow], FLGL_DPT_LBA
 	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/AH9h_HInit.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm	(revision 541)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm	(revision 542)
@@ -99,5 +99,5 @@
 ;;;	SelectDrive
 	; Try to select drive and wait until ready
-	call	AccessDPT_GetDriveSelectByteForOldInt13hToAL
+	call	AccessDPT_GetDriveSelectByteToAL
 	mov		[bp+IDEPACK.bDrvAndHead], al
 	call	Device_SelectDrive
@@ -130,17 +130,9 @@
 
 ;;;	InitializeDeviceParameters
-	; 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		ax, [cs:bx+DRVPARAMS.wHeadsAndSectors]
+	mov		ax, [di+DPT.wPchsHeadsAndSectors]
 	dec		ax							; Max Head number
-	xchg	al, ah						; Heads now in AH
-	mov		dx, ax						; Sectors per Track now in DL
+	xchg	ah, al
+	mov		dl, al						; Sectors per track
 	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 541)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH48h_GetExtendedDriveParameters.asm	(revision 542)
@@ -52,13 +52,10 @@
 ;    AH=48h Total Sector Count: 11873* 16*63 = 11,967,984
 ;
-; Notice how AH=48h returns lesser total sector count than AH=8h! The only
+; Notice how AH=48h returns lesser total sector count than AH=08h! The only
 ; way I could think of to get 11873 cylinders is to divide AH=08h sector
 ; count with P-CHS heads and sectors: (745*255*63) / (16*63) = 11873
 ;
-; I have no idea what is the reasoning behind it but at least there is one
-; BIOS that does just that.
-;
-; I decided that we multiply P-CHS values and do not waste space like the
-; Award BIOS does.
+; The only reason I can think of is that the Award BIOS has a bug and
+; uses L-CHS when it should use P-CHS values in the calculation.
 ;
 ;
@@ -139,9 +136,9 @@
 	; Store P-CHS. Based on phoenix specification this is returned only if
 	; total sector count is 15,482,880 or less.
-	sub		ax, 4001h
-	sbb		dx, 0ECh
+	sub		ax, MAX_SECTOR_COUNT_TO_RETURN_PCHS & 0FFFFh
+	sbb		dx, MAX_SECTOR_COUNT_TO_RETURN_PCHS >> 16
 	sbb		bx, cx		; Zero
-	jnc		SHORT .ReturnWithSuccess	; More than EC4000h
-	or		WORD [di+EDRIVE_INFO.wFlags], FLG_CHS_INFORMATION_IS_VALID
+	ja		SHORT .ReturnWithSuccess
+	or		BYTE [di+EDRIVE_INFO.wFlags], FLG_CHS_INFORMATION_IS_VALID
 
 	eMOVZX	dx, BYTE [es:si+DPT.bPchsHeads]
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/Address.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/Address.asm	(revision 541)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/Address.asm	(revision 542)
@@ -120,4 +120,5 @@
 ; Only 24-bits are used since LHCS to LBA28 conversion has 8.4GB limit.
 ; LBA = ((cylToSeek*headsPerCyl+headToSeek)*sectPerTrack)+sectToSeek-1
+; headsPerCyl and sectPerTrack are the current translation values (L-CHS).
 ;
 ; Returned address is in same registers that
Index: trunk/XTIDE_Universal_BIOS/Src/Initialization/AdvancedAta/Vision.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Initialization/AdvancedAta/Vision.asm	(revision 541)
+++ trunk/XTIDE_Universal_BIOS/Src/Initialization/AdvancedAta/Vision.asm	(revision 542)
@@ -41,5 +41,5 @@
 	in		al, QD65XX_BASE_PORT + QD65XX_CONFIG_REGISTER_in
 
-%if 0
+%ifdef DANGEROUS_DETECTION
 	; Checking alternative base port is currently commented away
 	; since Intel PIIX4 south bridge mirrors Interrupt Controller registers
@@ -51,5 +51,5 @@
 	or		dl, QD65XX_ALTERNATIVE_BASE_PORT
 	in		al, QD65XX_ALTERNATIVE_BASE_PORT + QD65XX_CONFIG_REGISTER_in
-%endif ; 0
+%endif ; DANGEROUS_DETECTION
 	; Fall to IsConfigRegisterWithIDinAL
 
@@ -65,5 +65,5 @@
 ;		Nothing
 ;--------------------------------------------------------------------
-;IsConfigRegisterWithIDinAL:
+IsConfigRegisterWithIDinAL:
 	mov		ah, al
 	and		al, MASK_QDCONFIG_CONTROLLER_ID
Index: trunk/XTIDE_Universal_BIOS/Src/Initialization/AtaID.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Initialization/AtaID.asm	(revision 541)
+++ trunk/XTIDE_Universal_BIOS/Src/Initialization/AtaID.asm	(revision 542)
@@ -95,4 +95,74 @@
 
 
+;--------------------------------------------------------------------
+; Writes user defined limits from ROMVARS to ATA ID read from the drive.
+; Modifying the ATA ID reduces code and possibilites for bugs since
+; only little furher checks are needed elsewhere.
+;
+; AtaID_ModifyESSIforUserDefinedLimitsAndReturnTranslateModeInDX
+;	Parameters:
+;		DS:DI:	Ptr to incomplete Disk Parameter Table
+;		ES:SI:	Ptr to 512-byte ATA information read from the drive
+;		CS:BP:	Ptr to IDEVARS for the controller
+;	Returns:
+;		DX:		User defined P-CHS to L-CHS translate mode
+;	Corrupts registers:
+;		AX, BX, CX
+;--------------------------------------------------------------------
+AtaID_ModifyESSIforUserDefinedLimitsAndReturnTranslateModeInDX:
+	call	AccessDPT_GetPointerToDRVPARAMStoCSBX
+	push	ds
+	push	es
+	pop		ds		; DS:SI now points to ATA information
+
+	; Load User Defined CHS or LBA to CX:AX
+	mov		dx, [cs:bx+DRVPARAMS.wFlags]
+	mov		ax, [cs:bx+DRVPARAMS.wCylinders]		; Or .dwMaximumLBA
+	mov		cx, [cs:bx+DRVPARAMS.wHeadsAndSectors]	; Or .dwMaximumLBA+2
+
+	; * User defined CHS *
+	test	dl, FLG_DRVPARAMS_USERCHS
+	jz		SHORT .NoUserDefinedCHS
+
+	; Apply new CHS and disable LBA (we also want to set CHS addressing)
+	mov		[si+ATA1.wCylCnt], ax
+	eMOVZX	ax, cl
+	mov		[si+ATA1.wHeadCnt], ax
+	mov		al, ch
+	mov		[si+ATA1.wSPT], ax
+	and		BYTE [si+ATA1.wCaps+1], ~(A1_wCaps_LBA>>8)
+	and		BYTE [si+ATA6.wSetSup83+1], ~(A6_wSetSup83_LBA48>>8)
+.NoUserDefinedCHS:
+
+	; * User defined LBA *
+	test	dl, FLG_DRVPARAMS_USERLBA
+	jz		SHORT .NoUserDefinedLBA
+
+	; Apply new LBA and disable LBA48
+	cmp		cx, [si+ATA1.dwLBACnt+2]
+	ja		SHORT .NoUserDefinedLBA		; Do not set larger than drive
+	jb		SHORT .StoreNewLBA
+	cmp		ax, [si+ATA1.dwLBACnt]
+	ja		SHORT .NoUserDefinedLBA		; Allow same size to disable LBA48
+.StoreNewLBA:
+	mov		[si+ATA1.dwLBACnt], ax
+	mov		[si+ATA1.dwLBACnt+2], cx
+	and		BYTE [si+ATA6.wSetSup83+1], ~(A6_wSetSup83_LBA48>>8)
+.NoUserDefinedLBA:
+
+	; * Disable Block Mode transfers *
+	test	dl, FLG_DRVPARAMS_BLOCKMODE
+	jnz		SHORT .NoNeedToDisableBlockMode
+	mov		BYTE [si+ATA1.bBlckSize], 1	; sectors
+.NoNeedToDisableBlockMode:
+
+	; * Load P-CHS to L-CHS translate mode to DX *
+	and		dx, BYTE MASK_DRVPARAMS_TRANSLATEMODE
+	eSHR_IM	dx, TRANSLATEMODE_FIELD_POSITION
+
+	pop		ds
+	ret
+
+
 %ifdef MODULE_ADVANCED_ATA
 ;--------------------------------------------------------------------
Index: trunk/XTIDE_Universal_BIOS/Src/Initialization/Initialize.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Initialization/Initialize.asm	(revision 541)
+++ trunk/XTIDE_Universal_BIOS/Src/Initialization/Initialize.asm	(revision 542)
@@ -95,4 +95,9 @@
 ;--------------------------------------------------------------------
 .StoreDptPointersToIntVectors:
+%ifndef USE_AT
+	test	BYTE [cs:ROMVARS.wFlags], FLG_ROMVARS_FULLMODE
+	jz		SHORT .CompatibleDPTsCreated	; Only Full operating mode has extra RAM to spare
+%endif
+
 	mov		dl, 80h
 	call	FindDPT_ForDriveNumberInDL	; DPT to DS:DI
Index: trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AccessDPT.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AccessDPT.asm	(revision 541)
+++ trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AccessDPT.asm	(revision 542)
@@ -22,6 +22,5 @@
 
 ;--------------------------------------------------------------------
-; AccessDPT_GetDriveSelectByteForOldInt13hToAL
-; AccessDPT_GetDriveSelectByteForEbiosToAL
+; AccessDPT_GetDriveSelectByteToAL
 ;	Parameters:
 ;		DS:DI:	Ptr to Disk Parameter Table
@@ -32,24 +31,8 @@
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
-AccessDPT_GetDriveSelectByteForOldInt13hToAL:
+AccessDPT_GetDriveSelectByteToAL:
 	mov		al, [di+DPT.bFlagsLow]
-	test	al, FLGL_DPT_ASSISTED_LBA
-	jnz		SHORT GetDriveSelectByteForAssistedLBAtoAL
-
-	and		al, FLG_DRVNHEAD_DRV	; Clear all but drive select bit
+	and		al, FLGL_DPT_SLAVE | FLGL_DPT_LBA
 	or		al, MASK_DRVNHEAD_SET	; Bits set to 1 for old drives
-	ret
-
-%ifdef MODULE_EBIOS
-ALIGN JUMP_ALIGN
-AccessDPT_GetDriveSelectByteForEbiosToAL:
-	mov		al, [di+DPT.bFlagsLow]
-	; Fall to GetDriveSelectByteForAssistedLBAtoAL
-%endif ; MODULE_EBIOS
-
-ALIGN JUMP_ALIGN
-GetDriveSelectByteForAssistedLBAtoAL:
-	and		al, FLG_DRVNHEAD_DRV	; Master / Slave select
-	or		al, FLG_DRVNHEAD_LBA | MASK_DRVNHEAD_SET
 	ret
 
Index: trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AtaGeometry.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AtaGeometry.asm	(revision 541)
+++ trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AtaGeometry.asm	(revision 542)
@@ -66,5 +66,4 @@
 ;--------------------------------------------------------------------
 ; AtaGeometry_GetLCHStoAXBLBHfromAtaInfoInESSIandTranslateModeInDX
-; AtaGeometry_GetLCHStoAXBLBHfromPCHSinAXBLBHandTranslateModeInDX
 ;	Parameters:
 ;		DX:		Wanted translate mode or TRANSLATEMODE_AUTO to autodetect
@@ -81,7 +80,5 @@
 AtaGeometry_GetLCHStoAXBLBHfromAtaInfoInESSIandTranslateModeInDX:
 	call	AtaGeometry_GetPCHStoAXBLBHfromAtaInfoInESSI
-	; Fall to AtaGeometry_GetLCHStoAXBLBHfromPCHSinAXBLBHandTranslateModeInDX
-
-AtaGeometry_GetLCHStoAXBLBHfromPCHSinAXBLBHandTranslateModeInDX:
+
 	; Check if user defined translate mode
 	dec		dx						; Set ZF if TRANSLATEMODE_LARGE, SF if TRANSLATEMODE_NORMAL
Index: trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CompatibleDPT.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CompatibleDPT.asm	(revision 541)
+++ trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CompatibleDPT.asm	(revision 542)
@@ -107,5 +107,5 @@
 	xor		dx, dx						; Clear for checksum
 	mov		ax, [si+DPT.wLchsCylinders]
-	MIN_U	ax, MAX_LCHS_CYLINDERS		; Our DPT can have up to 1027
+	;MIN_U	ax, MAX_LCHS_CYLINDERS		; Our DPT can have up to 1027
 	call	StoswThenAddALandAHtoDL		; Bytes 0 and 1 (Logical number of cylinders)
 
@@ -201,5 +201,5 @@
 	; DPTE.bDrvnhead and DPTE.bBiosVendor
 	xchg	di, si
-	call	AccessDPT_GetDriveSelectByteForEbiosToAL
+	call	AccessDPT_GetDriveSelectByteToAL
 	xchg	si, di
 	call	StoswThenAddALandAHtoDL			; Bytes 4 and 5
Index: trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm	(revision 541)
+++ trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm	(revision 542)
@@ -38,5 +38,5 @@
 ;				Set if any error
 ;	Corrupts registers:
-;		AX, BX, CX, DH
+;		AX, BX, CX, DX
 ;--------------------------------------------------------------------
 CreateDPT_FromAtaInformation:
@@ -96,45 +96,59 @@
 ;--------------------------------------------------------------------
 .StoreCHSparametersAndAddressingMode:
-	; Check if CHS defined in ROMVARS
-	call	GetUserDefinedCapacityToBXAXandFlagsToCXandModeToDXfromROMVARS
-	test	cl, FLG_DRVPARAMS_USERCHS
-	jz		SHORT .AutodetectPCHSvalues
+	; Apply any user limited values to ATA ID
+	call	AtaID_ModifyESSIforUserDefinedLimitsAndReturnTranslateModeInDX
 
 	; Translate P-CHS to L-CHS
-	call	AtaGeometry_GetLCHStoAXBLBHfromPCHSinAXBLBHandTranslateModeInDX
-	jmp		SHORT .StoreLCHStoDPT
-.AutodetectPCHSvalues:
 	call	AtaGeometry_GetLCHStoAXBLBHfromAtaInfoInESSIandTranslateModeInDX
-
-.StoreLCHStoDPT:
-	eSHL_IM	dl, TRANSLATEMODE_FIELD_POSITION
-	or		cl, dl
-	or		[di+DPT.bFlagsLow], cl		; Shift count and addressing mode
 	mov		[di+DPT.wLchsCylinders], ax
 	mov		[di+DPT.wLchsHeadsAndSectors], bx
-
-	; Store P-CHS to DPT
+	mov		al, dl
+	eSHL_IM	al, TRANSLATEMODE_FIELD_POSITION
+	or		cl, al
+
+	; Store P-CHS and flags
 	call	AtaGeometry_GetPCHStoAXBLBHfromAtaInfoInESSI
-	mov		[di+DPT.bPchsHeads], bl
+	dec		dx						; Set ZF if TRANSLATEMODE_LARGE, SF if TRANSLATEMODE_NORMAL
+	js		SHORT .NothingToChange
+	jz		SHORT .LimitHeadsForLargeAddressingMode
+
+	or		cl, FLGL_DPT_LBA		; Set LBA bit for Assisted LBA
+	jmp		SHORT .NothingToChange
+.LimitHeadsForLargeAddressingMode:
+	MIN_U	bl, 15					; Cannot have 16 P-Heads in LARGE addressing mode
+.NothingToChange:
+	or		[di+DPT.bFlagsLow], cl	; Shift count and addressing mode
+	mov		[di+DPT.wPchsHeadsAndSectors], bx
+
 %ifdef MODULE_EBIOS
-	mov		[di+DPT.bPchsSectorsPerTrack], bh
-
-; This is what Award BIOS from 1997 Pentium motherboard does. I can't think
-; of any good reason to do the same but let's keep this here just in case,
-; at least for a while.
-%if 0
-%ifdef RESERVE_DIAGNOSTIC_CYLINDER
-	; Do not store P-Cylinders, instead calculate it from L-CHS total sector count.
-	; Read AH=48h_GetExtendedDriveParameters.asm for more info.
-	xchg	ax, bx
-	mul		ah
-	push	ax							; P-Heads * P-Sectors per track
-	call	AH15h_GetSectorCountToBXDXAX
-	pop		bx
-	div		bx							; AX = Calculated cylinders
-%endif ; RESERVE_DIAGNOSTIC_CYLINDER
-%endif ; 0
-
+	test	cl, FLGL_DPT_LBA
+	jz		SHORT .NoLbaSoNoEBIOS
+
+	; Store P-Cylinders but only if we have 15,482,880 or less sectors since
+	; we only need P-Cylinders so we can return it from AH=48h
+	call	AtaGeometry_GetLbaSectorCountToBXDXAXfromAtaInfoInESSI
+	sub		ax, MAX_SECTOR_COUNT_TO_RETURN_PCHS & 0FFFFh
+	sbb		dx, MAX_SECTOR_COUNT_TO_RETURN_PCHS >> 16
+	sbb		bx, BYTE 0
+	ja		SHORT .StoreNumberOfLbaSectors
+
+	; Since we might have altered the default P-CHS parameters to be
+	; presented to the drive (AH=09h), we need to calculate new
+	; P-Cylinders. It could be read from the ATA ID after
+	; COMMAND_INITIALIZE_DEVICE_PARAMETERS but that is too much trouble.
+	; P-Cyls = MIN(16383*16*63, LBA sector count) / (P-Heads * P-Sectors per track)
+	call	AtaGeometry_GetLbaSectorCountToBXDXAXfromAtaInfoInESSI
+	xchg	cx, ax							; Sector count to DX:CX
+	mov		al, [di+DPT.bPchsHeads]
+	mul		BYTE [di+DPT.bPchsSectorsPerTrack]
+	xchg	cx, ax
+	div		cx								; AX = new P-Cylinders
 	mov		[di+DPT.wPchsCylinders], ax
+
+	; Store CHS sector count as total sector count
+	mul		cx
+	xor		bx, bx
+	xor		cx, cx							; Clear LBA48 flag
+	jmp		SHORT .StoreTotalSectorsFromBXDXAXandLBA48flagFromCL
 	; Fall to .StoreNumberOfLbaSectors
 
@@ -150,48 +164,13 @@
 ;		AX, BX, CX, DX
 ;--------------------------------------------------------------------
-	; Check if LBA supported
-	test	BYTE [es:si+ATA1.wCaps+1], A1_wCaps_LBA>>8
-	jz		SHORT .NoLbaSupportedSoNoEBIOS
-
+.StoreNumberOfLbaSectors:
 	; Store LBA 28/48 total sector count
 	call	AtaGeometry_GetLbaSectorCountToBXDXAXfromAtaInfoInESSI
-	call	StoreLba48AddressingFromCLandTotalSectorCountFromBXDXAX
-
-	; If we have 15,482,880 or less sectors, we multiply P-CHS values
-	; and use that as total sector count.
-	; Read AH=48h_GetExtendedDriveParameters.asm for more info.
-	sub		ax, 4001h
-	sbb		dx, 0ECh
-	sbb		bx, BYTE 0
-	jnc		SHORT .NoNeedToUseCHSsectorCount	; More than EC4000h
-
-	mov		al, [di+DPT.bPchsHeads]
-	mul		BYTE [di+DPT.bPchsSectorsPerTrack]
-	mul		WORD [di+DPT.wPchsCylinders]
-	xor		bx, bx
-	call	StoreLba48AddressingFromCLandTotalSectorCountFromBXDXAX
-
-	; Load user defined LBA
-.NoNeedToUseCHSsectorCount:
-	call	GetUserDefinedCapacityToBXAXandFlagsToCXandModeToDXfromROMVARS
-	test	cl, FLG_DRVPARAMS_USERLBA
-	jz		SHORT .KeepTotalSectorsFromAtaID
-
-	; Compare user defined and ATA-ID sector count and select smaller
-	mov		dx, bx
-	xor		bx, bx		; User defined LBA now in BX:DX:AX
-	cmp		bx, [di+DPT.twLbaSectors+4]
-	jb		SHORT .StoreUserDefinedSectorCountToDPT
-	cmp		dx, [di+DPT.twLbaSectors+2]
-	jb		SHORT .StoreUserDefinedSectorCountToDPT
-	ja		SHORT .KeepTotalSectorsFromAtaID
-	cmp		ax, [di+DPT.twLbaSectors]
-	jae		SHORT .KeepTotalSectorsFromAtaID
-.StoreUserDefinedSectorCountToDPT:
-	; CL bit FLGL_DPT_LBA48 is clear at this point
-	call	StoreLba48AddressingFromCLandTotalSectorCountFromBXDXAX
-
-.KeepTotalSectorsFromAtaID:
-.NoLbaSupportedSoNoEBIOS:
+.StoreTotalSectorsFromBXDXAXandLBA48flagFromCL:
+	or		[di+DPT.bFlagsLow], cl
+	mov		[di+DPT.twLbaSectors], ax
+	mov		[di+DPT.twLbaSectors+2], dx
+	mov		[di+DPT.twLbaSectors+4], bx
+.NoLbaSoNoEBIOS:
 %endif ; MODULE_EBIOS
 	; Fall to .StoreBlockMode
@@ -288,55 +267,2 @@
 	mov		[di+DPT.wBasePort], ax
 	ret
-
-
-;--------------------------------------------------------------------
-; GetUserDefinedCapacityToBXAXandFlagsToCXandModeToDXfromROMVARS
-;	Parameters:
-;		DS:DI:		Ptr to Disk Parameter Table
-;	Returns:
-;		AX:			User defined P-CHS Cylinders or LBA low word
-;		BX:			User defined P-CHS Heads and Sectors or LBA high word
-;		DX:			Translate mode or TRANSLATEMODE_AUTO
-;		CX:			FLG_DRVPARAMS_USERCHS if user defined CHS in BX:AX
-;					FLG_DRVPARAMS_USERLBA if user defined LBA in BX:AX
-;					Zero if user has not defined capacity
-;	Corrupts registers:
-;		Nothing
-;--------------------------------------------------------------------
-GetUserDefinedCapacityToBXAXandFlagsToCXandModeToDXfromROMVARS:
-	call	AccessDPT_GetPointerToDRVPARAMStoCSBX
-
-	; Get settings
-	mov		cx, [cs:bx+DRVPARAMS.wFlags]
-	mov		dx, cx
-	and		cx, BYTE FLG_DRVPARAMS_USERCHS | FLG_DRVPARAMS_USERLBA
-	and		dx, BYTE MASK_DRVPARAMS_TRANSLATEMODE
-	eSHR_IM	dx, TRANSLATEMODE_FIELD_POSITION
-
-	; Get capacity
-	mov		ax, [cs:bx+DRVPARAMS.wCylinders]		; Or .dwMaximumLBA
-	mov		bx, [cs:bx+DRVPARAMS.wHeadsAndSectors]	; Or .dwMaximumLBA+2
-	ret
-
-
-%ifdef MODULE_EBIOS
-;--------------------------------------------------------------------
-; StoreLba48AddressingFromCLandTotalSectorCountFromBXDXAX
-;	Parameters:
-;		BX:DX:AX:	Total Sector Count
-;		CL:			FLGL_DPT_LBA48 if LBA48 supported
-;		DS:DI:		Ptr to Disk Parameter Table
-;	Returns:
-;		Nothing
-;	Corrupts registers:
-;		CL
-;--------------------------------------------------------------------
-StoreLba48AddressingFromCLandTotalSectorCountFromBXDXAX:
-	or		cl, FLGL_DPT_LBA_AND_EBIOS_SUPPORTED
-	and		BYTE [di+DPT.bFlagsLow], ~FLGL_DPT_LBA48
-	or		[di+DPT.bFlagsLow], cl
-	mov		[di+DPT.twLbaSectors], ax
-	mov		[di+DPT.twLbaSectors+2], dx
-	mov		[di+DPT.twLbaSectors+4], bx
-	ret
-%endif ; MODULE_EBIOS
