Index: trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AccessDPT.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AccessDPT.asm	(revision 419)
+++ trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AccessDPT.asm	(revision 421)
@@ -36,10 +36,10 @@
 	mov		bx, [cs:bx+IDEVARS.wPort]
 	ret
-
-%endif
+%endif	; MODULE_ADVANCED_ATA
 
 
 ;--------------------------------------------------------------------
-; AccessDPT_GetDriveSelectByteToAL
+; AccessDPT_GetDriveSelectByteForOldInt13hToAL
+; AccessDPT_GetDriveSelectByteForEbiosToAL
 ;	Parameters:
 ;		DS:DI:	Ptr to Disk Parameter Table
@@ -50,8 +50,24 @@
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
-AccessDPT_GetDriveSelectByteToAL:
+AccessDPT_GetDriveSelectByteForOldInt13hToAL:
+	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
+	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.wFlags]
-	and		al, FLG_DRVNHEAD_LBA | FLG_DRVNHEAD_DRV
-	or		al, MASK_DRVNHEAD_SET	; Bits set to 1 for old drives
+	; 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
 
@@ -89,49 +105,13 @@
 ;		BH:		Number of L-CHS sectors per track
 ;	Corrupts registers:
-;		CX, DX
+;		Nothing
 ;--------------------------------------------------------------------
 AccessDPT_GetLCHStoAXBLBH:
-	; Return LBA-assisted CHS if LBA addressing used
-	test	BYTE [di+DPT.bFlagsLow], FLG_DRVNHEAD_LBA
-	jz		SHORT .ConvertPchsToLchs
-
-	call	AccessDPT_GetLbaSectorCountToBXDXAX
-	call	LbaAssist_ConvertSectorCountFromBXDXAXtoLbaAssistedCHSinDXAXBLBH
-	LIMIT_LBA_CYLINDERS_IN_DXAX_TO_LCHS_CYLINDERS
-	ret
-
-.ConvertPchsToLchs:
-	mov		ax, [di+DPT.wPchsCylinders]
-	mov		bx, [di+DPT.wPchsHeadsAndSectors]
-	; Fall to AccessDPT_ShiftPCHinAXBLtoLCH
-
-
-;--------------------------------------------------------------------
-; AccessDPT_ShiftPCHinAXBLtoLCH
-;	Parameters:
-;		AX:		P-CHS cylinders (1...16383)
-;		BL:		P-CHS heads (1...16)
-;	Returns:
-;		AX:		Number of L-CHS cylinders (1...1024)
-;		BL:		Number of L-CHS heads (1...255)
-;		CX:		Number of bits shifted (4 at most)
-;	Corrupts registers:
-;		Nothing
-;--------------------------------------------------------------------
-AccessDPT_ShiftPCHinAXBLtoLCH:
-	xor		cx, cx
-.ShiftLoop:
-	cmp		ax, MAX_LCHS_CYLINDERS		; Need to shift?
-	jbe		SHORT .Return				;  If not, return
-	inc		cx							; Increment shift count
-	shr		ax, 1						; Halve cylinders
-	shl		bl, 1						; Double heads
-	jnz		SHORT .ShiftLoop			; Falls through only on the last (4th) iteration and only if BL was 16 on entry
-	dec		bl							; DOS doesn't support drives with 256 heads so we limit heads to 255
-	; We can save a byte here by using DEC BX if we don't care about BH
-.Return:
+	mov		ax, [di+DPT.wLchsCylinders]
+	mov		bx, [di+DPT.wLchsHeadsAndSectors]
 	ret
 
 
+%ifdef MODULE_EBIOS
 ;--------------------------------------------------------------------
 ; AccessDPT_GetLbaSectorCountToBXDXAX
@@ -148,4 +128,5 @@
 	mov		bx, [di+DPT.twLbaSectors+4]
 	ret
+%endif ; MODULE_EBIOS
 
 
@@ -171,14 +152,15 @@
 	ret
 
+
 ;--------------------------------------------------------------------
-; AccessDPT_GetUnshiftedAddressModeToALZF
+; ACCESSDPT__GET_UNSHIFTED_ADDRESS_MODE_TO_AXZF
 ;	Parameters:
 ;		DS:DI:	Ptr to Disk Parameter Table
 ;	Returns:
-;		AL:		Addressing Mode (L-CHS, P-CHS, LBA28, LBA48)
+;		AX:		Addressing Mode (ADDRESSING_MODE_NORMAL, ADDRESSING_MODE_LARGE or ADDRESSING_MODE_ASSISTED_LBA)
 ;               unshifted (still shifted where it is in bFlagsLow)
 ;       ZF:     Set based on value in AL
 ;	Corrupts registers:
-;		AL
+;		Nothing
 ;--------------------------------------------------------------------
 ;
@@ -186,6 +168,6 @@
 ; is not worth it for these two instructions (4 bytes total)
 ;
-%macro AccessDPT_GetUnshiftedAddressModeToALZF 0
+%macro ACCESSDPT__GET_UNSHIFTED_ADDRESS_MODE_TO_AXZF 0
 	mov		al, [di+DPT.bFlagsLow]
-	and		al, MASKL_DPT_ADDRESSING_MODE
+	and		ax, BYTE MASKL_DPT_ADDRESSING_MODE
 %endmacro
Index: trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AtaGeometry.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AtaGeometry.asm	(revision 421)
+++ trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AtaGeometry.asm	(revision 421)
@@ -0,0 +1,299 @@
+; Project name	:	XTIDE Universal BIOS
+; Description	:	Functions for generating L-CHS parameters for
+;					drives with more than 1024 cylinders.
+;
+; 					These algorithms are taken from: http://www.mossywell.com/boot-sequence
+; 					Take a look at it for more detailed information.		
+;
+;					This file is shared with BIOS Drive Information Tool.
+
+;
+; 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
+
+%ifdef MODULE_EBIOS
+;--------------------------------------------------------------------
+; AtaGeometry_GetLbaSectorCountToBXDXAXfromAtaInfoInESSI
+;	Parameters:
+;		ES:SI:	Ptr to 512-byte ATA information read from the drive
+;	Returns:
+;		BX:DX:AX:	48-bit sector count
+;		CL:			FLGL_DPT_LBA48 if LBA48 supported, zero otherwise
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+AtaGeometry_GetLbaSectorCountToBXDXAXfromAtaInfoInESSI:
+	mov		bx, Registers_ExchangeDSSIwithESDI
+	call	bx	; ATA info now in DS:DI
+	push	bx	; We will return via Registers_ExchangeDSSIwithESDI
+
+	; Check if LBA48 supported
+	test	BYTE [di+ATA6.wSetSup83+1], A6_wSetSup83_LBA48>>8
+	jz		SHORT .GetLba28SectorCount
+
+	; Get LBA48 sector count
+	mov		cl, FLGL_DPT_LBA48
+	mov		ax, [di+ATA6.qwLBACnt]
+	mov		dx, [di+ATA6.qwLBACnt+2]
+	mov		bx, [di+ATA6.qwLBACnt+4]
+	ret
+
+.GetLba28SectorCount:
+	xor		cl, cl
+	xor		bx, bx
+	mov		ax, [di+ATA1.dwLBACnt]
+	mov		dx, [di+ATA1.dwLBACnt+2]
+	ret
+%endif	; MODULE_EBIOS
+
+
+;--------------------------------------------------------------------
+; AtaGeometry_GetLCHStoAXBLBHfromAtaInfoInESSI:
+;	Parameters:
+;		ES:SI:	Ptr to 512-byte ATA information read from the drive
+;	Returns:
+;		AX:		Number of L-CHS cylinders (1...1027, yes 1027)
+;		BL:		Number of L-CHS heads (1...255)
+;		BH:		Number of L-CHS sectors per track (1...63)
+;		CX:		Number of bits shifted (0...3)
+;		DL:		Addressing mode
+;	Corrupts registers:
+;		DH
+;--------------------------------------------------------------------
+AtaGeometry_GetLCHStoAXBLBHfromAtaInfoInESSI:
+	call	AtaGeometry_GetPCHStoAXBLBHfromAtaInfoInESSI
+	; Fall to AtaGeometry_GetLCHStoAXBLBHfromPCHSinAXBLBH
+
+AtaGeometry_GetLCHStoAXBLBHfromPCHSinAXBLBH:
+	; Generate L-CHS using simple bit shift algorithm (ECHS) if
+	; 8192 or less cylinders.
+	cmp		ax, 8192
+	jbe		SHORT ConvertPCHfromAXBXtoEnhancedCHinAXBX
+
+	; We have 8193 or more cylinders so two algorithms are available:
+	; Revised ECHS or Assisted LBA. The Assisted LBA provides larger
+	; capacity but requires LBA support from drive (drives this large
+	; always support LBA but we may have intentionally cleared the LBA
+	; bit to force CHS addressing).
+	test	BYTE [es:si+ATA1.wCaps+1], A1_wCaps_LBA>>8
+	jz		SHORT ConvertPCHfromAXBXtoRevisedEnhancedCHinAXBX
+
+	; Drive supports LBA
+	call	AtaGeometry_GetSectorCountToDXAXfromCHSinAXBLBH
+	call	ConvertChsSectorCountFromDXAXtoLbaAssistedLCHSinAXBLBH
+	xor		cx, cx		; No bits to shift
+	mov		dl, ADDRESSING_MODE_ASSISTED_LBA
+	ret
+
+
+;--------------------------------------------------------------------
+; AtaGeometry_GetPCHStoAXBLBHfromAtaInfoInESSI
+;	Parameters:
+;		ES:SI:	Ptr to 512-byte ATA information read from the drive
+;	Returns:
+;		AX:		Number of P-CHS cylinders (1...16383)
+;		BL:		Number of P-CHS heads (1...16)
+;		BH:		Number of P-CHS sectors per track (1...63)
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+AtaGeometry_GetPCHStoAXBLBHfromAtaInfoInESSI:
+	mov		ax, [es:si+ATA1.wCylCnt]	; Cylinders (1...16383)
+	mov		bl, [es:si+ATA1.wHeadCnt]	; Heads (1...16)
+	mov		bh, [es:si+ATA1.wSPT]		; Sectors per Track (1...63)
+	ret
+
+
+;--------------------------------------------------------------------
+; AtaGeometry_GetSectorCountToDXAXfromCHSinAXBLBH
+;	Parameters:
+;		ES:SI:	Ptr to 512-byte ATA information read from the drive
+;		AX:		Number of cylinders (1...16383)
+;		BL:		Number of heads (1...255)
+;		BH:		Number of sectors per track (1...63)
+;	Returns:
+;		DX:AX:	Total number of CHS addressable sectors
+;	Corrupts registers:
+;		BX
+;--------------------------------------------------------------------
+AtaGeometry_GetSectorCountToDXAXfromCHSinAXBLBH:
+	xchg	ax, bx
+	mul		ah			; AX = Heads * Sectors per track
+	mul		bx
+	ret
+
+
+;--------------------------------------------------------------------
+; Revised Enhanced CHS calculation (Revised ECHS)
+;
+; This algorithm translates P-CHS sector count to L-CHS sector count
+; with bit shift algorithm. Since 256 heads are not allowed
+; (DOS limit), this algorithm makes translations so that maximum of
+; 240 L-CHS heads can be used. This makes the maximum addressable capacity
+; to 7,927,234,560 bytes ~ 7.38 GiB. LBA addressing needs to be used to
+; get more capacity.
+;
+; L-CHS parameters generated here require the drive to use CHS addressing.
+;
+; Here is the algorithm:
+; If cylinders > 8192 and heads = 16
+;  Heads = 15
+;  Cylinders = cylinders * 16 / 15 (losing the fraction component)
+;  Do a standard ECHS translation
+;
+; ConvertPCHfromAXBXtoRevisedEnhancedCHinAXBX:
+;	Parameters:
+;		AX:		Number of P-CHS cylinders (8193...16383)
+;		BL:		Number of P-CHS heads (1...16)
+;	Returns:
+;		AX:		Number of L-CHS cylinders (?...1024)
+;		BL:		Number of L-CHS heads (?...240)
+;		CX:		Number of bits shifted (0...3)
+;		DL:		ADDRESSING_MODE_NORMAL or ADDRESSING_MODE_LARGE
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ConvertPCHfromAXBXtoRevisedEnhancedCHinAXBX:
+	cmp		bl, 16	; Drives with 8193 or more cylinders can report 15 heads
+	jb		SHORT ConvertPCHfromAXBXtoEnhancedCHinAXBX
+
+	eMOVZX	cx, bl	; CX = 16
+	dec		bx		; Heads = 15
+	mul		cx		; DX:AX = Cylinders * 16
+	dec		cx		; CX = 15
+	div		cx		; AX = (Cylinders * 16) / 15
+	; Fall to ConvertPCHfromAXBXtoEnhancedCHinAXBX
+
+
+;--------------------------------------------------------------------
+; Enhanced CHS calculation (ECHS)
+;
+; This algorithm translates P-CHS sector count to L-CHS sector count
+; with simple bit shift algorithm. Since 256 heads are not allowed
+; (DOS limit), this algorithm require that there are at most 8192
+; P-CHS cylinders. This makes the maximum addressable capacity
+; to 4,227,858,432 bytes ~ 3.94 GiB. Use Revised ECHS or Assisted LBA
+; algorithms if there are more than 8192 P-CHS cylinders.
+;
+; L-CHS parameters generated here require the drive to use CHS addressing.
+;
+; Here is the algorithm:
+;  Multiplier = 1
+;  Cylinder = Cylinder - 1
+;  Is Cylinder < 1024? If not:
+;  Do a right bitwise rotation on the cylinder (i.e., divide by 2)
+;  Do a left bitwise rotation on the multiplier (i.e., multiply by 2)
+;  Use the multiplier on the Cylinder and Head values to obtain the translated values.
+;
+; ConvertPCHfromAXBXtoEnhancedCHinAXBX:
+;	Parameters:
+;		AX:		Number of P-CHS cylinders (1...8192)
+;		BL:		Number of P-CHS heads (1...16)
+;	Returns:
+;		AX:		Number of L-CHS cylinders (?...1024)
+;		BL:		Number of L-CHS heads (?...128)
+;		CX:		Number of bits shifted (0...3)
+;		DL:		ADDRESSING_MODE_NORMAL or ADDRESSING_MODE_LARGE
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ConvertPCHfromAXBXtoEnhancedCHinAXBX:
+	xor		cx, cx		; No bits to shift initially
+	xor		dl, dl		; Assume ADDRESSING_MODE_NORMAL
+.ShiftIfMoreThan1024Cylinder:
+	cmp		ax, MAX_LCHS_CYLINDERS
+	jbe		SHORT ReturnLCHSinAXBLBH
+	shr		ax, 1
+	shl		bl, 1
+	inc		cx			; Increment bit shift count
+	mov		dl, ADDRESSING_MODE_LARGE
+	jmp		SHORT .ShiftIfMoreThan1024Cylinder
+
+
+;--------------------------------------------------------------------
+; LBA assist calculation (or Assisted LBA)
+;
+; This algorithm translates P-CHS sector count up to largest possible
+; L-CHS sector count (1024, 255, 63). Note that INT 13h interface allows
+; 256 heads but DOS supports up to 255 head. That is why BIOSes never
+; use 256 heads.
+;
+; L-CHS parameters generated here require the drive to use LBA addressing.
+;
+; Here is the algorithm:
+; If cylinders > 8192
+;  Variable CH = Total CHS Sectors / 63
+;  Divide (CH  1) by 1024 and add 1
+;  Round the result up to the nearest of 16, 32, 64, 128 and 255. This is the value to be used for the number of heads.
+;  Divide CH by the number of heads. This is the value to be used for the number of cylinders.
+;
+; ConvertChsSectorCountFromDXAXtoLbaAssistedLCHSinAXBLBH:
+;	Parameters:
+;		DX:AX:	Total number of P-CHS sectors for CHS addressing
+;				(max = 16383 * 16 * 63 = 16,514,064)
+;	Returns:
+;		AX:		Number of cylinders (?...1027)
+;		BL:		Number of heads (16, 32, 64, 128 or 255)
+;		BH:		Number of sectors per track (always 63)
+;	Corrupts registers:
+;		CX, DX
+;--------------------------------------------------------------------
+ConvertChsSectorCountFromDXAXtoLbaAssistedLCHSinAXBLBH:
+	; Value CH = Total sector count / 63
+	; Max = 16,514,064 / 63 = 262128
+	mov		cx, LBA_ASSIST_SPT			; CX = 63
+	call	Math_DivDXAXbyCX
+	push	dx
+	push	ax							; Value CH stored for later use
+
+	; BX:DX:AX = Value CH - 1
+	; Max = 262128 - 1 = 262127
+	xor		bx, bx
+	sub		ax, BYTE 1
+	sbb		dx, bx
+
+	; AX = Number of heads = ((Value CH - 1) / 1024) + 1
+	; Max = (262127 / 1024) + 1 = 256
+	push	si
+	call	Size_DivideSizeInBXDXAXby1024andIncrementMagnitudeInCX
+	pop		si
+	inc		ax							; + 1
+
+	; Heads must be 16, 32, 64, 128 or 255 (round up to the nearest)
+	; Max = 255
+	mov		cx, 16						; Min number of heads
+.CompareNextValidNumberOfHeads:
+	cmp		ax, cx
+	jbe		SHORT .NumberOfHeadsNowInCX
+	shl		cx, 1						; Double number of heads
+	test	ch, ch						; Reached 256 heads?
+	jz		SHORT .CompareNextValidNumberOfHeads
+	dec		cx							;  If so, limit heads to 255
+.NumberOfHeadsNowInCX:
+	mov		bx, cx						; Number of heads are returned in BL
+	mov		bh, LBA_ASSIST_SPT			; Sectors per Track
+
+	; DX:AX = Number of cylinders = Value CH (without - 1) / number of heads
+	; Max = 262128 / 255 = 1027
+	pop		ax
+	pop		dx							; Value CH back to DX:AX
+	div		cx
+
+	; Return L-CHS
+ReturnLCHSinAXBLBH:
+	ret
Index: trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm	(revision 419)
+++ trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm	(revision 421)
@@ -33,5 +33,4 @@
 ;		ES:		BDA Segment
 ;	Returns:
-;		DL:		Drive number for new drive
 ;		DS:DI:	Ptr to Disk Parameter Table (if successful)
 ;		CF:		Cleared if DPT created successfully
@@ -81,8 +80,8 @@
 %endif
 	mov		[di+DPT.wFlags], ax
-	; Fall to .StoreAddressing
-
-;--------------------------------------------------------------------
-; .StoreAddressing
+	; Fall to .StoreCHSparametersAndAddressingMode
+
+;--------------------------------------------------------------------
+; .StoreCHSparametersAndAddressingMode
 ;	Parameters:
 ;		DS:DI:	Ptr to Disk Parameter Table
@@ -94,20 +93,55 @@
 ;		AX, BX, CX, DX
 ;--------------------------------------------------------------------
-.StoreAddressing:
+.StoreCHSparametersAndAddressingMode:
 	; Check if CHS defined in ROMVARS
 	call	AccessDPT_GetPointerToDRVPARAMStoCSBX
-	test	byte [cs:bx+DRVPARAMS.wFlags], FLG_DRVPARAMS_USERCHS    ; User specified CHS?
-	jnz		SHORT .StoreUserDefinedPCHS
-
+	test	byte [cs:bx+DRVPARAMS.wFlags], FLG_DRVPARAMS_USERCHS    ; User specified P-CHS?
+	jz		SHORT .AutodetectPCHSvalues
+
+	; Use DRVPARAMS P-CHS values instead of autodetected
+	mov		ax, [cs:bx+DRVPARAMS.wCylinders]
+	mov		bx, [cs:bx+DRVPARAMS.wHeadsAndSectors]
+	call	AtaGeometry_GetLCHStoAXBLBHfromPCHSinAXBLBH
+	jmp		SHORT .StoreLCHStoDPT
+
+	; Get L-CHS parameters and addressing mode
+.AutodetectPCHSvalues:
+	call	AtaGeometry_GetLCHStoAXBLBHfromAtaInfoInESSI
+
+.StoreLCHStoDPT:
+	eSHL_IM	dl, ADDRESSING_MODE_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
+	call	AtaGeometry_GetPCHStoAXBLBHfromAtaInfoInESSI
+	mov		[di+DPT.bPchsHeads], bl
+%ifdef MODULE_EBIOS
+	mov		[di+DPT.wPchsCylinders], ax
+	mov		[di+DPT.bPchsSectorsPerTrack], bh
+	; Fall to .StoreNumberOfLbaSectors
+
+;--------------------------------------------------------------------
+; .StoreNumberOfLbaSectors
+;	Parameters:
+;		DS:DI:	Ptr to Disk Parameter Table
+;		ES:SI:	Ptr to 512-byte ATA information read from the drive
+;		CS:BP:	Ptr to IDEVARS for the controller
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX
+;--------------------------------------------------------------------
 	; Check if LBA supported
-	call	AtaID_GetPCHStoAXBLBHfromAtaInfoInESSI
 	test	BYTE [es:si+ATA1.wCaps+1], A1_wCaps_LBA>>8
-	jz		SHORT .StoreCHSfromAXBHBL		; Small old drive with CHS addressing only
-
-	; Store LBA 28/48 addressing and total sector count
-	call	AtaID_GetTotalSectorCountToBXDXAXfromAtaInfoInESSI
-	call	StoreLbaAddressingAndTotalSectorCountFromBXDXAX
-
-	; Replace sector count with user defined if necessary
+	jz		SHORT .NoLbaSupportedSoNoEBIOS
+
+	; Store LBA 28/48 total sector count
+	call	AtaGeometry_GetLbaSectorCountToBXDXAXfromAtaInfoInESSI
+	call	StoreLba48AddressingFromCLandTotalSectorCountFromBXDXAX
+
+	; Load user defined LBA
 	call	AccessDPT_GetPointerToDRVPARAMStoCSBX
 	test	BYTE [cs:bx+DRVPARAMS.wFlags], FLG_DRVPARAMS_USERLBA
@@ -126,78 +160,10 @@
 	jae		SHORT .KeepTotalSectorsFromAtaID
 .StoreUserDefinedSectorCountToDPT:
-	call	StoreLbaAddressingAndTotalSectorCountFromBXDXAX
-
-	; Calculate L-CHS for old INT 13h
+	xor		cx, cx		; Always LBA28 for user defined values
+	call	StoreLba48AddressingFromCLandTotalSectorCountFromBXDXAX
+
 .KeepTotalSectorsFromAtaID:
-	mov		bx, [di+DPT.twLbaSectors+4]		; Restore BX
-	call	LbaAssist_ConvertSectorCountFromBXDXAXtoLbaAssistedCHSinDXAXBLBH
-	mov		[di+DPT.bLbaHeads], bl
-	jmp		SHORT .StoreBlockMode
-
-;--------------------------------------------------------------------
-; .StoreUserDefinedPCHS
-;	Parameters:
-;		DS:DI:	Ptr to Disk Parameter Table
-;		ES:SI:	Ptr to 512-byte ATA information read from the drive
-;		CS:BP:	Ptr to IDEVARS for the controller
-;	Returns:
-;		AX:		Number of P-CHS cylinders
-;		BH:		Number of P-CHS sectors per track
-;		BL:		Number of P-CHS heads
-;	Corrupts registers:
-;		Nothing
-;--------------------------------------------------------------------
-.StoreUserDefinedPCHS:
-	call	AccessDPT_GetPointerToDRVPARAMStoCSBX
-	mov		ax, [cs:bx+DRVPARAMS.wCylinders]
-	mov		bx, [cs:bx+DRVPARAMS.wHeadsAndSectors]
-	; Fall to .StoreCHSfromAXBHBL
-
-;--------------------------------------------------------------------
-; .StoreCHSfromAXBHBL
-;	Parameters:
-;		AX:		Number of P-CHS cylinders
-;		BH:		Number of P-CHS sectors per track
-;		BL:		Number of P-CHS heads
-;		DS:DI:	Ptr to Disk Parameter Table
-;		ES:SI:	Ptr to 512-byte ATA information read from the drive
-;		CS:BP:	Ptr to IDEVARS for the controller
-;	Returns:
-;		AX:		Number of P-CHS cylinders
-;		BH:		Number of P-CHS sectors per track
-;		BL:		Number of P-CHS heads
-;	Corrupts registers:
-;		CX
-;--------------------------------------------------------------------
-.StoreCHSfromAXBHBL:
-	push	ax
-	push	bx
-	call	AccessDPT_ShiftPCHinAXBLtoLCH	; Get number of bits to shift
-	pop		bx
-	pop		ax
-	jcxz	.StorePCHSfromAXDX				; Small drive so use L-CHS addressing
-
-	; Store P-CHS addressing mode and number of bits to shift in L-CHS to P-CHS translation
-	or		cl, ADDRESSING_MODE_PCHS<<ADDRESSING_MODE_FIELD_POSITION
-	or		[di+DPT.bFlagsLow], cl
-	; Fall to .StoreChsFromAXBLBH
-
-;--------------------------------------------------------------------
-; .StoreChsFromAXBLBH
-;	Parameters:
-;		AX:		Number of P-CHS cylinders
-;		BH:		Number of P-CHS sectors per track
-;		BL:		Number of P-CHS heads
-;		DS:DI:	Ptr to Disk Parameter Table
-;		ES:SI:	Ptr to 512-byte ATA information read from the drive
-;		CS:BP:	Ptr to IDEVARS for the controller
-;	Returns:
-;		Nothing
-;	Corrupts registers:
-;		Nothing
-;--------------------------------------------------------------------
-.StorePCHSfromAXDX:
-	mov		[di+DPT.wPchsCylinders], ax
-	mov		[di+DPT.wPchsHeadsAndSectors], bx
+.NoLbaSupportedSoNoEBIOS:
+%endif ; MODULE_EBIOS
 	; Fall to .StoreBlockMode
 
@@ -268,32 +234,23 @@
 
 
-;--------------------------------------------------------------------
-; StoreLbaAddressingAndTotalSectorCountFromBXDXAX
+%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:
-;		CX
-;--------------------------------------------------------------------
-StoreLbaAddressingAndTotalSectorCountFromBXDXAX:
+;		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
-
-%ifdef MODULE_EBIOS
-	and		BYTE [di+DPT.bFlagsLow], ~MASKL_DPT_ADDRESSING_MODE
-	test	bx, bx
-	jnz		SHORT .SetLba48AddressingToDPT	; Must be LBA48
-
-	; Drives can report at most 0FFF FFFFh LBA28 sectors according to ATA specification.
-	; That is (2^28)-1 so we can simply check if DH is zero or not.
-	test	dh, dh
-	jz		SHORT .SetLba28AddressingToDPT
-.SetLba48AddressingToDPT:
-	or		BYTE [di+DPT.bFlagsLow], ADDRESSING_MODE_LBA48<<ADDRESSING_MODE_FIELD_POSITION
-.SetLba28AddressingToDPT:
-%endif
-	or		BYTE [di+DPT.bFlagsLow], ADDRESSING_MODE_LBA28<<ADDRESSING_MODE_FIELD_POSITION
 	ret
+%endif ; MODULE_EBIOS
Index: trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/LbaAssist.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/LbaAssist.asm	(revision 419)
+++ 	(revision )
@@ -1,103 +1,0 @@
-; Project name	:	XTIDE Universal BIOS
-; Description	:	Functions for generating L-CHS parameters for
-;					LBA drives.
-;
-;					This file is shared with BIOS Drive Information Tool.
-
-;
-; 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
-
-;--------------------------------------------------------------------
-; LBA assist calculation:
-; this is how to fit a big drive into INT13's skimpy size requirements,
-; with a maximum of 8.4G available.
-;
-; If cylinders > 8192
-;  Variable CH = Total Sectors / 63
-;  Divide (CH  1) by 1024 (as an assembler bitwise right shift) and add 1
-;  Round the result up to the nearest of 16, 32, 64, 128 and 255. This is the value to be used for the number of heads.
-;  Divide CH by the number of heads. This is the value to be used for the number of 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.
-;
-; LbaAssist_ConvertSectorCountFromBXDXAXtoLbaAssistedCHSinDXAXBLBH:
-;	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
-;--------------------------------------------------------------------
-LbaAssist_ConvertSectorCountFromBXDXAXtoLbaAssistedCHSinDXAXBLBH:
-	push	bp
-	push	si
-
-	; Value CH = 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:DX:AX = Value CH - 1
-	mov		ax, [bp]
-	mov		dx, [bp+2]
-	mov		bx, [bp+4]
-	sub		ax, BYTE 1					; Subtract 1
-	sbb		dx, BYTE 0
-	sbb		bx, BYTE 0
-
-	; DX:AX = Number of heads = ((Value CH - 1) / 1024) + 1
-	call	Size_DivideSizeInBXDXAXby1024andIncrementMagnitudeInCX
-	add		ax, BYTE 1					; Add 1
-	adc		dx, bx						; BX = 0
-
-	; Heads must be 16, 32, 64, 128 or 255 (round up to the nearest)
-	test	dx, dx						; 65536 or more heads?
-	jnz		SHORT .LimitHeadsTo255
-	mov		cx, 16						; Min number of heads
-.CompareNextValidNumberOfHeads:
-	cmp		ax, cx
-	jbe		SHORT .NumberOfHeadsNowInCX
-	shl		cx, 1						; Double number of heads
-	test	ch, ch						; Reached 256 heads?
-	jnz		SHORT .CompareNextValidNumberOfHeads
-.LimitHeadsTo255:
-	mov		cx, 255
-.NumberOfHeadsNowInCX:
-	mov		bx, cx						; Number of heads are returned in BL
-	mov		bh, LBA_ASSIST_SPT			; Sectors per Track
-
-	; DX:AX = Number of cylinders = Value CH (without - 1) / number of heads
-	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
-	pop		si
-	pop		bp
-	ret
