Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeError.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeError.asm	(revision 322)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeError.asm	(revision 324)
@@ -29,8 +29,8 @@
 
 	; I don't think anything actually reads these from BDA
-	push	ds
-	LOAD_BDA_SEGMENT_TO	ds, dx
-	mov		[HDBDA.wHDStAndErr], ax
-	pop		ds
+	;push	ds
+	;LOAD_BDA_SEGMENT_TO	ds, dx
+	;mov		[HDBDA.wHDStAndErr], ax
+	;pop		ds
 
 	; Fall to GetBiosErrorCodeToAHfromStatusAndErrorRegistersInAX
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH48h_GetExtendedDriveParameters.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH48h_GetExtendedDriveParameters.asm	(revision 322)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH48h_GetExtendedDriveParameters.asm	(revision 324)
@@ -45,26 +45,5 @@
 	mov		WORD [si+EDRIVE_INFO.wFlags], FLG_DMA_BOUNDARY_ERRORS_HANDLED_BY_BIOS
 
-	push	ds	; Move CS to DS to avoid segment overrides
-	push	cs
-	pop		ds
-
-	; Limit LBA if necessary
-	test	BYTE [di+DRVPARAMS.wFlags], FLG_DRVPARAMS_USERLBA
-	jz		SHORT .StoreTotalSectorsFromBXDXAX
-	test	bx, bx
-	jnz		SHORT .LimitTotalSectors
-	cmp		dx, [di+DRVPARAMS.dwMaximumLBA+2]
-	jb		SHORT .StoreTotalSectorsFromBXDXAX		; Real size less than max
-	ja		SHORT .LimitTotalSectors
-	cmp		ax, [di+DRVPARAMS.dwMaximumLBA]
-	jbe		SHORT .StoreTotalSectorsFromBXDXAX		; Real size less than max
-
-.LimitTotalSectors:
-	xor		bx, bx
-	mov		ax, [di+DRVPARAMS.dwMaximumLBA]
-	mov		dx, [di+DRVPARAMS.dwMaximumLBA+2]
-
-.StoreTotalSectorsFromBXDXAX:
-	pop		ds	; Restore DS from the change above
+	; Store total sector count
 	mov		[si+EDRIVE_INFO.qwTotalSectors], ax
 	xor		ax, ax									; Return with success
Index: trunk/XTIDE_Universal_BIOS/Src/Initialization/AtaID.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Initialization/AtaID.asm	(revision 322)
+++ trunk/XTIDE_Universal_BIOS/Src/Initialization/AtaID.asm	(revision 324)
@@ -5,91 +5,4 @@
 ; Section containing code
 SECTION .text
-
-;--------------------------------------------------------------------
-; LBA assist calculation:
-; this is how to fit a big drive into INT13's skimpy size requirements,
-; with a maximum of 8.4G available.
-;
-; total LBAs (as obtained by words 60+61)
-; divided by 63 (sectors per track) (save as value A)
-; Sub 1 from A
-; divide A by 1024 + truncate.
-; == total number of heads to use.
-; add 1
-; this value must be either 16, 32, 64, 128, or 256 (round up)
-; then take the value A above and divide by # of heads
-; to get the # of cylinders to use.
-;
-;
-; so a LBA28 drive will have 268,435,456 as maximum LBAs
-;
-; 10000000h / 63   = 410410h (total cylinders or tracks)
-;   410410h / 1024 = 1041h, which is way more than 256 heads, but 256 is max.
-;   410410h / 256  = 4104h cylinders
-;
-; there's a wealth of information at: http://www.mossywell.com/boot-sequence
-; they show a slightly different approach to LBA assist calulations, but
-; the method here provides compatibility with phoenix BIOS
-;
-; we're using the values from 60+61 here because we're topping out at 8.4G
-; anyway, so there's no need to use the 48bit LBA values.
-;
-; AtaID_GetLbaAssistedCHStoDXAXBLBH:
-;	Parameters:
-;		BX:DX:AX:	Total number of sectors
-;	Returns:
-;		DX:AX:	Number of cylinders
-;		BH:		Number of sectors per track (always 63)
-;		BL:		Number of heads (16, 32, 64, 128 or 255)
-;	Corrupts registers:
-;		CX
-;--------------------------------------------------------------------
-AtaID_GetLbaAssistedCHStoDXAXBLBH:
-	push	bp
-	push	si
-
-	; Value A = Total sector count / 63
-	xor		cx, cx
-	push	cx		; Push zero for bits 48...63
-	push	bx
-	push	dx
-	push	ax						; 64-bit sector count now in stack
-	mov		cl, LBA_ASSIST_SPT
-	mov		bp, sp					; SS:BP now points sector count
-	call	Math_DivQWatSSBPbyCX	; Temporary value A now in stack
-
-	; BX = Number of heads =  A / 1024
-	mov		ax, [bp]
-	mov		dx, [bp+2]
-	mov		bx, [bp+4]
-	call	Size_DivideSizeInBXDXAXby1024andIncrementMagnitudeInCX
-
-	; Heads must be 16, 32, 64, 128 or 256 (round up)
-	mov		bx, 256						; Max number of heads
-	test	dx, dx						; 65536 or more heads?
-	jnz		SHORT .GetNumberOfCylinders
-	mov		cx, 128						; Half BX for rounding up
-.FindMostSignificantBitForHeadSize:
-	cmp		ax, cx
-	jae		SHORT .GetNumberOfCylinders
-	shr		cx, 1
-	shr		bx, 1						; Halve number of heads
-	jmp		SHORT .FindMostSignificantBitForHeadSize
-
-	; DX:AX = Number of cylinders = A / number of heads
-.GetNumberOfCylinders:
-	mov		cx, bx
-	call	Math_DivQWatSSBPbyCX
-	mov		ax, [bp]
-	mov		dx, [bp+2]					; Cylinders now in DX:AX
-
-	; Return LBA assisted CHS
-	add		sp, BYTE 8					; Clean stack
-	sub		bl, bh						; Limit heads to 255
-	mov		bh, LBA_ASSIST_SPT
-	pop		si
-	pop		bp
-	ret
-
 
 ;--------------------------------------------------------------------
Index: trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AccessDPT.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AccessDPT.asm	(revision 322)
+++ trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AccessDPT.asm	(revision 324)
@@ -58,5 +58,5 @@
 
 	call	AccessDPT_GetLbaSectorCountToBXDXAX
-	call	AtaID_GetLbaAssistedCHStoDXAXBLBH
+	call	AccessDPT_ConvertSectorCountFromBXDXAXtoLbaAssistedCHSinDXAXBLBH
 	test	dx, dx
 	jnz		SHORT .LimitAXtoMaxLCHScylinders
@@ -157,2 +157,89 @@
 	and		al, MASKL_DPT_ADDRESSING_MODE
 %endmacro
+
+
+;--------------------------------------------------------------------
+; LBA assist calculation:
+; this is how to fit a big drive into INT13's skimpy size requirements,
+; with a maximum of 8.4G available.
+;
+; total LBAs (as obtained by words 60+61)
+; divided by 63 (sectors per track) (save as value A)
+; Sub 1 from A
+; divide A by 1024 + truncate.
+; == total number of heads to use.
+; add 1
+; this value must be either 16, 32, 64, 128, or 256 (round up)
+; then take the value A above and divide by # of heads
+; to get the # of cylinders to use.
+;
+;
+; so a LBA28 drive will have 268,435,456 as maximum LBAs
+;
+; 10000000h / 63   = 410410h (total cylinders or tracks)
+;   410410h / 1024 = 1041h, which is way more than 256 heads, but 256 is max.
+;   410410h / 256  = 4104h cylinders
+;
+; there's a wealth of information at: http://www.mossywell.com/boot-sequence
+; they show a slightly different approach to LBA assist calulations, but
+; the method here provides compatibility with phoenix BIOS
+;
+; we're using the values from 60+61 here because we're topping out at 8.4G
+; anyway, so there's no need to use the 48bit LBA values.
+;
+; AccessDPT_ConvertSectorCountFromBXDXAXtoLbaAssistedCHStoDXAXBLBH:
+;	Parameters:
+;		BX:DX:AX:	Total number of sectors
+;	Returns:
+;		DX:AX:	Number of cylinders
+;		BH:		Number of sectors per track (always 63)
+;		BL:		Number of heads (16, 32, 64, 128 or 255)
+;	Corrupts registers:
+;		CX
+;--------------------------------------------------------------------
+AccessDPT_ConvertSectorCountFromBXDXAXtoLbaAssistedCHSinDXAXBLBH:
+	push	bp
+	push	si
+
+	; Value A = Total sector count / 63
+	xor		cx, cx
+	push	cx		; Push zero for bits 48...63
+	push	bx
+	push	dx
+	push	ax						; 64-bit sector count now in stack
+	mov		cl, LBA_ASSIST_SPT
+	mov		bp, sp					; SS:BP now points sector count
+	call	Math_DivQWatSSBPbyCX	; Temporary value A now in stack
+
+	; BX = Number of heads =  A / 1024
+	mov		ax, [bp]
+	mov		dx, [bp+2]
+	mov		bx, [bp+4]
+	call	Size_DivideSizeInBXDXAXby1024andIncrementMagnitudeInCX
+
+	; Heads must be 16, 32, 64, 128 or 256 (round up)
+	mov		bx, 256						; Max number of heads
+	test	dx, dx						; 65536 or more heads?
+	jnz		SHORT .GetNumberOfCylinders
+	mov		cx, 128						; Half BX for rounding up
+.FindMostSignificantBitForHeadSize:
+	cmp		ax, cx
+	jae		SHORT .GetNumberOfCylinders
+	shr		cx, 1
+	shr		bx, 1						; Halve number of heads
+	jmp		SHORT .FindMostSignificantBitForHeadSize
+
+	; DX:AX = Number of cylinders = A / number of heads
+.GetNumberOfCylinders:
+	mov		cx, bx
+	call	Math_DivQWatSSBPbyCX
+	mov		ax, [bp]
+	mov		dx, [bp+2]					; Cylinders now in DX:AX
+
+	; Return LBA assisted CHS
+	add		sp, BYTE 8					; Clean stack
+	sub		bl, bh						; Limit heads to 255
+	mov		bh, LBA_ASSIST_SPT
+	pop		si
+	pop		bp
+	ret
Index: trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm	(revision 322)
+++ trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm	(revision 324)
@@ -87,15 +87,31 @@
 	jz		SHORT .StoreCHSfromAXBHBL		; Small old drive with CHS addressing only
 
-	; Check if 48-bit LBA supported
-	test	BYTE [es:si+ATA6.wSetSup83+1], A6_wSetSup83_LBA48>>8
-	jz		SHORT .StoreLBA28addressing
-	or		BYTE [di+DPT.bFlagsLow], ADDRESSING_MODE_LBA48<<ADDRESSING_MODE_FIELD_POSITION
-.StoreLBA28addressing:
-	or		BYTE [di+DPT.bFlagsLow], ADDRESSING_MODE_LBA28<<ADDRESSING_MODE_FIELD_POSITION
+	; Store LBA 28/48 addressing and total sector count
 	call	AtaID_GetTotalSectorCountToBXDXAXfromAtaInfoInESSI
-	mov		[di+DPT.twLbaSectors], ax
-	mov		[di+DPT.twLbaSectors+2], dx
-	mov		[di+DPT.twLbaSectors+4], bx
-	call	AtaID_GetLbaAssistedCHStoDXAXBLBH
+	call	StoreLbaAddressingAndTotalSectorCountFromBXDXAX
+
+	; Replace sector count with user defined if necessary
+	call	AccessDPT_GetPointerToDRVPARAMStoCSBX
+	test	BYTE [cs:bx+DRVPARAMS.wFlags], FLG_DRVPARAMS_USERLBA
+	jz		SHORT .KeepTotalSectorsFromAtaID
+	mov		ax, [cs:bx+DRVPARAMS.dwMaximumLBA]
+	mov		dx, [cs:bx+DRVPARAMS.dwMaximumLBA+2]
+	xor		bx, bx
+
+	; Compare user defined and ATA-ID sector count and select smaller
+	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:
+	call	StoreLbaAddressingAndTotalSectorCountFromBXDXAX
+
+	; Calculate L-CHS for old INT 13h
+.KeepTotalSectorsFromAtaID:
+	mov		bx, [di+DPT.twLbaSectors+4]		; Restore BX
+	call	AccessDPT_ConvertSectorCountFromBXDXAXtoLbaAssistedCHSinDXAXBLBH
 	mov		[di+DPT.bLbaHeads], bl
 	jmp		SHORT .StoreBlockMode
@@ -233,2 +249,28 @@
 	ret
 
+
+;--------------------------------------------------------------------
+; StoreLbaAddressingAndTotalSectorCountFromBXDXAX
+;	Parameters:
+;		BX:DX:AX:	Total Sector Count
+;		DS:DI:		Ptr to Disk Parameter Table
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		CX
+;--------------------------------------------------------------------
+StoreLbaAddressingAndTotalSectorCountFromBXDXAX:
+	mov		[di+DPT.twLbaSectors], ax
+	mov		[di+DPT.twLbaSectors+2], dx
+	mov		[di+DPT.twLbaSectors+4], bx
+
+	and		BYTE [di+DPT.bFlagsLow], ~MASKL_DPT_ADDRESSING_MODE
+	test	bx, bx
+	jnz		SHORT .SetLba48AddressingToDPT
+	test	dh, 0F0h
+	jz		SHORT .SetLba28AddressingToDPT
+.SetLba48AddressingToDPT:
+	or		BYTE [di+DPT.bFlagsLow], ADDRESSING_MODE_LBA48<<ADDRESSING_MODE_FIELD_POSITION
+.SetLba28AddressingToDPT:
+	or		BYTE [di+DPT.bFlagsLow], ADDRESSING_MODE_LBA28<<ADDRESSING_MODE_FIELD_POSITION
+	ret
