Index: /trunk/XTIDE_Universal_BIOS/Inc/BootVars.inc
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Inc/BootVars.inc	(revision 420)
+++ /trunk/XTIDE_Universal_BIOS/Inc/BootVars.inc	(revision 421)
@@ -66,10 +66,14 @@
 							resb	2	; Zero word (ensures string terminates)
 	.wInitErrorFlags		resb	2	; Errors during initialization
-	
-%ifdef MODULE_ADVANCED_ATA
-							resb	6	; padding to make DRVDETECTINFO size an even multiple of DPT size
-%else
-							resb	2	; padding to make DRVDETECTINFO size an even multiple of DPT size
-%endif				
+
+%if LARGEST_DPT_SIZE == 28
+							resb	22	; padding to make DRVDETECTINFO size an even multiple of DPT size
+%elif LARGEST_DPT_SIZE == 20
+							resb	6
+%elif LARGEST_DPT_SIZE == 18
+							resb	2
+%else	; LARGEST_DPT_SIZE == 10
+							resb	6
+%endif
 endstruc
 
Index: /trunk/XTIDE_Universal_BIOS/Inc/CustomDPT.inc
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Inc/CustomDPT.inc	(revision 420)
+++ /trunk/XTIDE_Universal_BIOS/Inc/CustomDPT.inc	(revision 421)
@@ -23,5 +23,5 @@
 
 ; Base DPT for all device types
-struc DPT	; 10 bytes
+struc DPT	; 8 or 18 bytes
 	; General Disk Parameter Table related
 	.wFlags:
@@ -30,39 +30,51 @@
 	.bIdevarsOffset			resb	1	; Offset to IDEVARS for this drive
 
-	; IDE Drive related
-	; .bLbaHeads and .twLbaSectors are used for LBA addressing only.
-	.bLbaHeads:				resb	1	; Number of LBA assisted heads (1...255)
-	.twLbaSectors			resb	2	; 48-bit sector count for LBA addressing
+	.bPchsHeads				resb	1	; (1...16)
+	.wLchsCylinders			resb	2	; (1...1027, yes 1027)
+	.wLchsHeadsAndSectors:
+	.bLchsHeads				resb	1	; (1...255)
+	.bLchsSectorsPerTrack	resb	1	; (1...63)
 
-	; .wPchsCylinders and .bPchsSectors are used for CHS addressing only.
-	.wPchsCylinders			resb	2	; Number of P-CHS Cylinders (1...16383)
-	.wPchsHeadsAndSectors:
-	.bPchsHeads				resb	1	; Number of P-CHS heads (1...16)
-	.bPchsSectors			resb	1	; Number of P-CHS Sectors per Track (1...63)
+%ifdef MODULE_EBIOS
+	.twLbaSectors			resb	6	; 48-bit sector count for LBA addressing
+	.wPchsCylinders			resb	2
+	.bPchsSectorsPerTrack	resb	1
+							resb	1
+%endif
 endstruc
 
 	; Bit definitions for DPT.bFlagsLow
-	MASKL_DPT_CHS_SHIFT_COUNT					EQU	(7<<0)	; Bits 0...2, P-CHS to L-CHS bit shift count (0...4)
-	FLGL_DPT_SLAVE								EQU	FLG_DRVNHEAD_DRV	; (1<<4), Drive is slave drive
-	MASKL_DPT_ADDRESSING_MODE					EQU	(3<<ADDRESSING_MODE_FIELD_POSITION)	; Bits 5..6, Addressing Mode (bit 6 == FLG_DRVNHEAD_LBA)
+	MASKL_DPT_CHS_SHIFT_COUNT			EQU	(3<<0)				; Bits 0...1, P-CHS to L-CHS bit shift count (0...3)
+	MASKL_DPT_ADDRESSING_MODE			EQU	(3<<ADDRESSING_MODE_FIELD_POSITION)	; Bits 2...3, NORMAL, LARGE or Assisted LBA addressing mode
+	FLGL_DPT_ASSISTED_LBA				EQU	(1<<(ADDRESSING_MODE_FIELD_POSITION+1))
+	FLGL_DPT_SLAVE						EQU	FLG_DRVNHEAD_DRV	; Bit 4, Drive is a Slave Drive
 %ifdef MODULE_IRQ
-	FLGL_DPT_ENABLE_IRQ							EQU	(1<<7)
+	FLGL_DPT_ENABLE_IRQ					EQU	(1<<5)				; Bit 5, Enable IRQ
+%endif
+%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
 
+	; Addressing modes for DPT.bFlagsLow
+	ADDRESSING_MODE_FIELD_POSITION		EQU		2
+	ADDRESSING_MODE_NORMAL				EQU		0
+	ADDRESSING_MODE_LARGE				EQU		1
+	ADDRESSING_MODE_ASSISTED_LBA		EQU		2	; 28-bit or 48-bit LBA
+
+
 	; Bit definitions for DPT.bFlagsHigh
-	FLGH_DPT_BLOCK_MODE_SUPPORTED				EQU	(1<<1)	; Use block transfer commands (must be bit 1!)
+	FLGH_DPT_BLOCK_MODE_SUPPORTED		EQU	(1<<1)	; Bit 1, Use block transfer commands (must be bit 1!)
 %ifdef MODULE_SERIAL
-	FLGH_DPT_SERIAL_DEVICE						EQU	(1<<2)	; Serial Port Device
+	FLGH_DPT_SERIAL_DEVICE				EQU	(1<<2)	; Bit 2, Serial Port Device
 %endif
 %ifdef MODULE_IRQ
-	FLGH_DPT_INTERRUPT_IN_SERVICE				EQU	(1<<3)	; Set when waiting for IRQ
+	FLGH_DPT_INTERRUPT_IN_SERVICE		EQU	(1<<3)	; Bit 3, Set when waiting for IRQ
 %endif
 %ifdef MODULE_FEATURE_SETS
-	FLGH_DPT_POWER_MANAGEMENT_SUPPORTED			EQU (1<<5)
+	FLGH_DPT_POWER_MANAGEMENT_SUPPORTED	EQU (1<<5)	; Bit 4, Drive supports power management
 %endif
-
-	; IDE device only
 %ifdef MODULE_ADVANCED_ATA
-	FLGH_DPT_IORDY								EQU	(1<<7)	; Controller and Drive supports IORDY
+	FLGH_DPT_IORDY						EQU	(1<<7)	; Bit 5, Controller and Drive supports IORDY
 %endif
 
@@ -74,16 +86,8 @@
 %endif
 
-	; Addressing modes for DPT.wFlags
-	ADDRESSING_MODE_FIELD_POSITION				EQU		5
-	ADDRESSING_MODE_LCHS						EQU		0	; L-CHS Addressing Mode (NORMAL in many other BIOSes)
-	ADDRESSING_MODE_PCHS						EQU		1	; P-CHS Addressing Mode (LARGE in many other BIOSes)
-	ADDRESSING_MODE_LBA28						EQU		2	; 28-bit LBA Addressing Mode
-%ifdef MODULE_EBIOS
-	ADDRESSING_MODE_LBA48						EQU		3	; 48-bit LBA Addressing Mode
-%endif
 
 
 ; DPT for ATA devices
-struc DPT_ATA	; 10 + 2 bytes = 12 bytes
+struc DPT_ATA	; 8/18 bytes + 2 bytes = 10/20 bytes
 	.dpt					resb	DPT_size
 	.bBlockSize				resb	1	; Current block size in sectors (do not set to zero!)
@@ -92,8 +96,9 @@
 
 
+
 ; Additional variables needed to initialize and reset Advanced IDE Controllers.
 ; EBDA must be reserved for DPTs when using these!
 %ifdef MODULE_ADVANCED_ATA
-struc DPT_ADVANCED_ATA
+struc DPT_ADVANCED_ATA	; 10/20 bytes + 8 bytes = 18/28 bytes
 	.dpt_ata				resb	DPT_ATA_size
 	.wControllerID			resb	2	; Controller specific ID WORD (from Advanced Controller detection)
@@ -117,5 +122,5 @@
 ; DPT for Serial devices
 %ifdef MODULE_SERIAL
-struc DPT_SERIAL
+struc DPT_SERIAL	; 8/18 bytes + 2 bytes = 10/20 bytes
 	.dpt					resb	DPT_size
 	.wSerialPortAndBaud:
@@ -140,23 +145,3 @@
 
 
-;--------------------------------------------------------------------
-; LIMIT_LBA_CYLINDERS_IN_DXAX_TO_LCHS_CYLINDERS
-;	Parameters:
-;		DX:AX:	Number of LBA cylinders
-;	Returns:
-;		AX:		Number of L-CHS cylinders
-;	Corrupts registers:
-;		Nothing
-;--------------------------------------------------------------------
-%macro LIMIT_LBA_CYLINDERS_IN_DXAX_TO_LCHS_CYLINDERS 0
-	test	dx, dx
-	jnz		SHORT %%LoadMaxValueToAX
-	cmp		ax, MAX_LCHS_CYLINDERS
-	jb		SHORT %%NoNeedToModify
-%%LoadMaxValueToAX:
-	mov		ax, MAX_LCHS_CYLINDERS
-%%NoNeedToModify:
-%endmacro
-
-
 %endif ; CUSTOMDPT_INC
Index: /trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm	(revision 420)
+++ /trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm	(revision 421)
@@ -79,5 +79,5 @@
 	test	bh, FLG_DRVNHEAD_DRV
 	jnz		SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
-	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MOTOR_STARTUP, FLG_STATUS_BSY)
+	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MOTOR_STARTUP, FLG_STATUS_DRDY)
 	call	IdeWait_PollStatusFlagInBLwithTimeoutInBH
 .SkipLongWaitSinceDriveIsNotPrimaryMaster:
@@ -195,4 +195,5 @@
 ALIGN JUMP_ALIGN
 IdeCommand_SelectDrive:
+%if 0
 	; Wait until neither Master or Slave Drive is busy
 	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_BSY, FLG_STATUS_BSY)
@@ -200,4 +201,5 @@
 	eCMOVE	bh, TIMEOUT_IDENTIFY_DEVICE
 	call	IdeWait_PollStatusFlagInBLwithTimeoutInBH
+%endif
 
 	; Select Master or Slave Drive
Index: /trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm	(revision 420)
+++ /trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm	(revision 421)
@@ -119,5 +119,5 @@
 	jc		SHORT ReturnWithTransferErrorInAH
 
-	; All rectors succesfully transferred
+	; All sectors succesfully transferred
 	add		cx, [bp+PIOVARS.bSectorsDone]		; Never sets CF
 	ret
@@ -371,6 +371,6 @@
 	pop		ds
 	ret
-
 %endif	; MODULE_8BIT_IDE
+
 
 ;--------------------------------------------------------------------
@@ -395,5 +395,5 @@
 	db		6Fh			; OUTSW/OUTSD
 	ret
-%endif
+%endif ; USE_AT
 
 
Index: /trunk/XTIDE_Universal_BIOS/Src/Device/Idepack.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/Device/Idepack.asm	(revision 420)
+++ /trunk/XTIDE_Universal_BIOS/Src/Device/Idepack.asm	(revision 421)
@@ -70,5 +70,5 @@
 
 	and		ah, 0Fh						; Limit bits for LBA28
-	call	AccessDPT_GetDriveSelectByteToAL
+	call	AccessDPT_GetDriveSelectByteForEbiosToAL
 	or		al, ah
 	mov		[bp+IDEPACK.bDrvAndHead], al
@@ -83,5 +83,5 @@
 	and		si, BYTE 0Fh						; Offset normalized
 	jmp		SHORT GetDeviceControlByteToIdepackAndStartTransfer
-%endif
+%endif ; MODULE_EBIOS
 
 
@@ -114,5 +114,5 @@
 	push	bx
 	call	Address_OldInt13hAddressToIdeAddress
-	call	AccessDPT_GetDriveSelectByteToAL
+	call	AccessDPT_GetDriveSelectByteForOldInt13hToAL
 	or		al, bh			; AL now has Drive and Head Select Byte
 	mov		[bp+IDEPACK.bDrvAndHead], al
@@ -156,5 +156,5 @@
 	; Drive and Head select byte
 	and		ah, MASK_DRVNHEAD_HEAD		; Keep head bits only
-	call	AccessDPT_GetDriveSelectByteToAL
+	call	AccessDPT_GetDriveSelectByteForOldInt13hToAL
 	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 420)
+++ /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 420)
+++ /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 420)
+++ /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 420)
+++ /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 420)
+++ /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 420)
+++ /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
Index: /trunk/XTIDE_Universal_BIOS/Src/Initialization/AtaID.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/Initialization/AtaID.asm	(revision 420)
+++ /trunk/XTIDE_Universal_BIOS/Src/Initialization/AtaID.asm	(revision 421)
@@ -21,76 +21,4 @@
 ; Section containing code
 SECTION .text
-
-;--------------------------------------------------------------------
-; AtaID_GetPCHStoAXBLBHfromAtaInfoInESSI
-;	Parameters:
-;		ES:SI:	Ptr to 512-byte ATA information read from the drive
-;	Returns:
-;		AX:		Number of user specified P-CHS cylinders
-;		BH:		Number of user specified P-CHS sectors per track
-;		BL:		Number of user specified P-CHS heads
-;	Corrupts registers:
-;		Nothing
-;--------------------------------------------------------------------
-AtaID_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
-
-
-;--------------------------------------------------------------------
-; AtaID_GetTotalSectorCountToBXDXAXfromAtaInfoInESSI
-;	Parameters:
-;		ES:SI:	Ptr to 512-byte ATA information read from the drive
-;	Returns:
-;		BX:DX:AX:	48-bit sector count
-;	Corrupts registers:
-;		Nothing
-;--------------------------------------------------------------------
-AtaID_GetTotalSectorCountToBXDXAXfromAtaInfoInESSI:
-	mov		bx, Registers_ExchangeDSSIwithESDI
-	call	bx	; ATA info now in DS:DI
-	push	bx	; We will return via Registers_ExchangeDSSIwithESDI
-	xor		bx, bx
-	test	BYTE [di+ATA1.wCaps+1], A1_wCaps_LBA>>8
-	jz		SHORT .GetChsSectorCount
-	; Fall to .GetLbaSectorCount
-
-;--------------------------------------------------------------------
-; .GetLbaSectorCount
-; .GetLba28SectorCount
-; .GetChsSectorCount
-;	Parameters:
-;		BX:		Zero
-;		DS:DI:	Ptr to 512-byte ATA information read from the drive
-;	Returns:
-;		BX:DX:AX:	48-bit sector count
-;	Corrupts registers:
-;		Nothing
-;--------------------------------------------------------------------
-.GetLbaSectorCount:
-%ifdef MODULE_EBIOS
-	test	BYTE [di+ATA6.wSetSup83+1], A6_wSetSup83_LBA48>>8
-	jz		SHORT .GetLba28SectorCount
-
-	; Get LBA48 sector count
-	mov		ax, [di+ATA6.qwLBACnt]
-	mov		dx, [di+ATA6.qwLBACnt+2]
-	mov		bx, [di+ATA6.qwLBACnt+4]
-	ret
-%endif
-
-.GetLba28SectorCount:
-	mov		ax, [di+ATA1.dwLBACnt]
-	mov		dx, [di+ATA1.dwLBACnt+2]
-	ret
-
-.GetChsSectorCount:
-	mov		al, [di+ATA1.wSPT]		; AL=Sectors per track
-	mul		BYTE [di+ATA1.wHeadCnt]	; AX=Sectors per track * number of heads
-	mul		WORD [di+ATA1.wCylCnt]	; DX:AX=Sectors per track * number of heads * number of cylinders
-	ret
-
 
 %ifdef MODULE_ADVANCED_ATA
Index: /trunk/XTIDE_Universal_BIOS/Src/Main.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/Main.asm	(revision 420)
+++ /trunk/XTIDE_Universal_BIOS/Src/Main.asm	(revision 421)
@@ -186,5 +186,5 @@
 	%include "FindDPT.asm"			; For finding DPTs
 	%include "AccessDPT.asm"		; For accessing DPTs
-	%include "LbaAssist.asm"		; For generating L-CHS parameters to LBA drives
+	%include "AtaGeometry.asm"		; For generating L-CHS parameters
 	%include "DrvDetectInfo.asm"	; For creating DRVDETECTINFO structs
 	%include "AtaID.asm"			; For ATA Identify Device information
Index: /trunk/XTIDE_Universal_BIOS/Src/Menus/BootMenu/BootMenuPrint.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/Menus/BootMenu/BootMenuPrint.asm	(revision 420)
+++ /trunk/XTIDE_Universal_BIOS/Src/Menus/BootMenu/BootMenuPrint.asm	(revision 421)
@@ -202,5 +202,5 @@
 	push	dx						; Magnitude character
 
-	test	di, di
+	test	di, di					; Zero if foreign drive
 	jz		SHORT BootMenuPrint_RefreshInformation.FormatRelay
 
@@ -229,8 +229,7 @@
 ;		CX
 ;--------------------------------------------------------------------
-GetTotalSectorCount:
-	test	BYTE [di+DPT.bFlagsLow], FLG_DRVNHEAD_LBA
-	jnz		SHORT .ReturnFullCapacity
-	jmp		AH15h_GetSectorCountToBXDXAX
-.ReturnFullCapacity:
-	jmp		AccessDPT_GetLbaSectorCountToBXDXAX
+%ifdef MODULE_EBIOS
+GetTotalSectorCount		EQU		AccessDPT_GetLbaSectorCountToBXDXAX
+%else
+GetTotalSectorCount		EQU		AH15h_GetSectorCountToBXDXAX
+%endif
Index: /trunk/XTIDE_Universal_BIOS/Src/Menus/BootMenu/BootMenuPrintCfg.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/Menus/BootMenu/BootMenuPrintCfg.asm	(revision 420)
+++ /trunk/XTIDE_Universal_BIOS/Src/Menus/BootMenu/BootMenuPrintCfg.asm	(revision 421)
@@ -43,8 +43,8 @@
 	eMOVZX	ax, [di+DPT.bIdevarsOffset]
 	xchg	bx, ax						; CS:BX now points to IDEVARS
-	; Fall to .PushAndFormatCfgString
+	; Fall to .PushAddressingMode
 
 ;--------------------------------------------------------------------
-; PushAddressingMode
+; .PushAddressingMode
 ;	Parameters:
 ;		DS:DI:	Ptr to DPT
@@ -53,8 +53,8 @@
 ;		Nothing (jumps to next push below)
 ;	Corrupts registers:
-;		AX, CX
+;		AX, CX, DX
 ;--------------------------------------------------------------------
 .PushAddressingMode:
-	AccessDPT_GetUnshiftedAddressModeToALZF
+	ACCESSDPT__GET_UNSHIFTED_ADDRESS_MODE_TO_AXZF
 	;;
 	;; This multiply both shifts the addressing mode bits down to low order bits, and
@@ -62,12 +62,13 @@
 	;; with AL clear, and so we exchange AL and AH after the multiply for the final result.
 	;;
-	mov		cl,(1<<(8-ADDRESSING_MODE_FIELD_POSITION)) * g_szAddressingModes_Displacement
-	mul		cl
-	xchg	al,ah
-	add		ax,g_szAddressingModes
+	mov		cx, g_szAddressingModes_Displacement << (8-ADDRESSING_MODE_FIELD_POSITION)
+	mul		cx
+	xchg	al, ah		; AL = always zero after above multiplication
+	add		ax, g_szAddressingModes
 	push	ax
+	; Fall to .PushBlockMode
 
 ;--------------------------------------------------------------------
-; PushBlockMode
+; .PushBlockMode
 ;	Parameters:
 ;		DS:DI:	Ptr to DPT
Index: /trunk/XTIDE_Universal_BIOS/Src/Strings.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/Strings.asm	(revision 420)
+++ /trunk/XTIDE_Universal_BIOS/Src/Strings.asm	(revision 421)
@@ -97,24 +97,21 @@
 
 g_szAddressingModes:
-g_szLCHS:		db	"L-CHS",NULL
-g_szPCHS:		db	"P-CHS",NULL
-g_szLBA28:		db	"LBA28",NULL
-g_szLBA48:		db	"LBA48",NULL
-g_szAddressingModes_Displacement equ (g_szPCHS - g_szAddressingModes)
+g_szNORMAL:		db	"NORMAL",NULL
+g_szLARGE:		db	"LARGE ",NULL
+g_szLBA:		db	"LBA   ",NULL
+wantToRemoveThis:	db	"4",NULL	; String compression want '4' somewhere
+g_szAddressingModes_Displacement equ (g_szLARGE - g_szAddressingModes)
 ;
 ; Ensure that addressing modes are correctly spaced in memory
 ;
 %ifndef CHECK_FOR_UNUSED_ENTRYPOINTS
-	%if g_szLCHS <> g_szAddressingModes
+	%if g_szNORMAL <> g_szAddressingModes
 		%error "g_szAddressingModes Displacement Incorrect 1"
 	%endif
-	%if g_szPCHS <> g_szLCHS + g_szAddressingModes_Displacement
+	%if g_szLARGE <> g_szNORMAL + g_szAddressingModes_Displacement
 		%error "g_szAddressingModes Displacement Incorrect 2"
 	%endif
-	%if g_szLBA28 <> g_szPCHS + g_szAddressingModes_Displacement
+	%if g_szLBA <> g_szLARGE + g_szAddressingModes_Displacement
 		%error "g_szAddressingModes Displacement Incorrect 3"
-	%endif
-	%if g_szLBA48 <> g_szLBA28 + g_szAddressingModes_Displacement
-		%error "g_szAddressingModes Displacement Incorrect 4"
 	%endif
 %endif
@@ -166,5 +163,5 @@
 g_szCapacityNum:		db	"%5-u.%u %ciB",NULL
 g_szInformation:		db	"%s",LF,CR
-	db	"Addr.",SINGLE_VERTICAL,"Block",SINGLE_VERTICAL,"Bus",SINGLE_VERTICAL,  "IRQ",SINGLE_VERTICAL,"Reset",LF,CR
+	db	"Addr. ",SINGLE_VERTICAL,"Block",SINGLE_VERTICAL,"Bus",SINGLE_VERTICAL,  "IRQ",SINGLE_VERTICAL,"Reset",LF,CR
 	db	   "%s",SINGLE_VERTICAL, "%5-u",SINGLE_VERTICAL, "%s",SINGLE_VERTICAL," %2-I",SINGLE_VERTICAL,"%5-x" ,NULL
 
@@ -211,5 +208,5 @@
 ;$translate{ord('2')} = 12;
 ;$translate{ord('3')} = 13;
-;$translate{ord('4')} = 14;
+;$translate{ord('4')} = 14;	; Not used at the moment
 ;$translate{ord('5')} = 15;
 ;$translate{ord('6')} = 16;
Index: /trunk/XTIDE_Universal_BIOS/Src/StringsCompressed.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/StringsCompressed.asm	(revision 420)
+++ /trunk/XTIDE_Universal_BIOS/Src/StringsCompressed.asm	(revision 421)
@@ -185,36 +185,33 @@
 
 g_szAddressingModes:
-g_szLCHS:		; db	"L-CHS",NULL
-         		; db	 4ch,  2dh,  43h,  48h,  53h,  00h    ; uncompressed
-         		  db	 52h,  28h,  49h,  4eh,  99h          ; compressed
-
-g_szPCHS:		; db	"P-CHS",NULL
-         		; db	 50h,  2dh,  43h,  48h,  53h,  00h    ; uncompressed
-         		  db	 56h,  28h,  49h,  4eh,  99h          ; compressed
-
-g_szLBA28:		; db	"LBA28",NULL
-          		; db	 4ch,  42h,  41h,  32h,  38h,  00h    ; uncompressed
-          		  db	 52h,  48h,  47h,  2ch,  11h          ; compressed
-
-g_szLBA48:		; db	"LBA48",NULL
-          		; db	 4ch,  42h,  41h,  34h,  38h,  00h    ; uncompressed
-          		  db	 52h,  48h,  47h,  2eh,  11h          ; compressed
-
-g_szAddressingModes_Displacement equ (g_szPCHS - g_szAddressingModes)
+g_szNORMAL:		; db	"NORMAL",NULL
+           		; db	 4eh,  4fh,  52h,  4dh,  41h,  4ch,  00h    ; uncompressed
+           		  db	 54h,  55h,  58h,  53h,  47h,  92h          ; compressed
+
+g_szLARGE:		; db	"LARGE ",NULL
+          		; db	 4ch,  41h,  52h,  47h,  45h,  20h,  00h    ; uncompressed
+          		  db	 52h,  47h,  58h,  4dh,  4bh,  00h          ; compressed
+
+g_szLBA:		; db	"LBA   ",NULL
+        		; db	 4ch,  42h,  41h,  20h,  20h,  20h,  00h    ; uncompressed
+        		  db	 52h,  48h, 0c7h,  20h,  00h                ; compressed
+
+wantToRemoveThis:	; db	"4",NULL	; String compression want '4' somewhere
+                 	; db	 34h,  00h    ; uncompressed
+                 	  db	 0eh          ; compressed
+
+g_szAddressingModes_Displacement equ (g_szLARGE - g_szAddressingModes)
 ;
 ; Ensure that addressing modes are correctly spaced in memory
 ;
 %ifndef CHECK_FOR_UNUSED_ENTRYPOINTS
-%if g_szLCHS <> g_szAddressingModes
+%if g_szNORMAL <> g_szAddressingModes
 %error "g_szAddressingModes Displacement Incorrect 1"
 %endif
-%if g_szPCHS <> g_szLCHS + g_szAddressingModes_Displacement
+%if g_szLARGE <> g_szNORMAL + g_szAddressingModes_Displacement
 %error "g_szAddressingModes Displacement Incorrect 2"
 %endif
-%if g_szLBA28 <> g_szPCHS + g_szAddressingModes_Displacement
+%if g_szLBA <> g_szLARGE + g_szAddressingModes_Displacement
 %error "g_szAddressingModes Displacement Incorrect 3"
-%endif
-%if g_szLBA48 <> g_szLBA28 + g_szAddressingModes_Displacement
-%error "g_szAddressingModes Displacement Incorrect 4"
 %endif
 %endif
@@ -299,7 +296,7 @@
                 		  db	 3eh,  3bh                ; compressed
 
-	; db	"Addr.",SINGLE_VERTICAL,"Block",SINGLE_VERTICAL,"Bus",SINGLE_VERTICAL,  "IRQ",SINGLE_VERTICAL,"Reset",LF,CR
-	; db	 41h,  64h,  64h,  72h,  2eh, 0b3h,  42h,  6ch,  6fh,  63h,  6bh, 0b3h,  42h,  75h,  73h, 0b3h,  49h,  52h,  51h, 0b3h,  52h,  65h,  73h,  65h,  74h,  0ah,  0dh    ; uncompressed
-	  db	 47h,  6ah,  6ah,  78h,  29h,  23h,  48h,  72h,  75h,  69h,  71h,  23h,  48h,  7bh,  79h,  23h,  4fh,  58h,  57h,  23h,  58h,  6bh,  79h,  6bh,  7ah,  3bh          ; compressed
+	; db	"Addr. ",SINGLE_VERTICAL,"Block",SINGLE_VERTICAL,"Bus",SINGLE_VERTICAL,  "IRQ",SINGLE_VERTICAL,"Reset",LF,CR
+	; db	 41h,  64h,  64h,  72h,  2eh,  20h, 0b3h,  42h,  6ch,  6fh,  63h,  6bh, 0b3h,  42h,  75h,  73h, 0b3h,  49h,  52h,  51h, 0b3h,  52h,  65h,  73h,  65h,  74h,  0ah,  0dh    ; uncompressed
+	  db	 47h,  6ah,  6ah,  78h,  29h,  20h,  23h,  48h,  72h,  75h,  69h,  71h,  23h,  48h,  7bh,  79h,  23h,  4fh,  58h,  57h,  23h,  58h,  6bh,  79h,  6bh,  7ah,  3bh          ; compressed
 
 	; db	   "%s",SINGLE_VERTICAL, "%5-u",SINGLE_VERTICAL, "%s",SINGLE_VERTICAL," %2-I",SINGLE_VERTICAL,"%5-x" ,NULL
@@ -362,5 +359,5 @@
 ;$translate{ord('2')} = 12;    [StringsCompress Processed]
 ;$translate{ord('3')} = 13;    [StringsCompress Processed]
-;$translate{ord('4')} = 14;    [StringsCompress Processed]
+;$translate{ord('4')} = 14;	; Not used at the moment    [StringsCompress Processed]
 ;$translate{ord('5')} = 15;    [StringsCompress Processed]
 ;$translate{ord('6')} = 16;    [StringsCompress Processed]
@@ -478,5 +475,5 @@
 ;; translated usage stats
 ;; 33:1
-;; 32:22
+;; 32:26
 ;; 181:1
 ;; 53:2
@@ -486,5 +483,5 @@
 ;; 179:8
 ;; 44:1
-;; 50:3
+;; 50:2
 ;; 51:3
 ;; 47:2
@@ -493,6 +490,6 @@
 ;; 34:3
 ;; 49:1
-;; 56:6
-;; 45:3
+;; 56:4
+;; 45:1
 ;; 175:1
 ;; 171:2
@@ -522,23 +519,23 @@
 ;; 63,?:
 ;; 64,@:1
-;; 65,A:3
-;; 66,B:9
-;; 67,C:4
+;; 65,A:4
+;; 66,B:8
+;; 67,C:2
 ;; 68,D:10
-;; 69,E:2
+;; 69,E:3
 ;; 70,F:4
-;; 71,G:2
-;; 72,H:4
+;; 71,G:3
+;; 72,H:2
 ;; 73,I:1
 ;; 74,J:
 ;; 75,K:1
 ;; 76,L:4
-;; 77,M:4
-;; 78,N:1
-;; 79,O:1
-;; 80,P:2
+;; 77,M:5
+;; 78,N:2
+;; 79,O:2
+;; 80,P:1
 ;; 81,Q:1
-;; 82,R:5
-;; 83,S:5
+;; 82,R:7
+;; 83,S:3
 ;; 84,T:
 ;; 85,U:2
Index: /trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AccessDPT.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AccessDPT.asm	(revision 420)
+++ /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 420)
+++ /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: unk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/LbaAssist.asm
===================================================================
--- /trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/LbaAssist.asm	(revision 420)
+++ 	(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
Index: /trunk/XTIDE_Universal_BIOS/makefile
===================================================================
--- /trunk/XTIDE_Universal_BIOS/makefile	(revision 420)
+++ /trunk/XTIDE_Universal_BIOS/makefile	(revision 421)
@@ -30,4 +30,5 @@
 # ELIMINATE_CGA_SNOW        Prevents CGA snowing at the cost of a few bytes                      #
 # RELOCATE_INT13H_STACK     Relocates INT 13h stack to top of stolen conventional memory         #
+# RESERVE_DIAGNOSTIC_CYLINDER Reserve one L-CHS cylinder for compatibility with old BIOSes       #
 # USE_186                   Use instructions supported by 80188/80186 and V20/V30 and later      #
 # USE_286                   Use instructions supported by 286 and later                          #
@@ -94,5 +95,5 @@
 # Assembler preprocessor defines.                               #
 #################################################################
-DEFINES_COMMON = MODULE_STRINGS_COMPRESSED MODULE_HOTKEYS MODULE_EBIOS MODULE_FEATURE_SETS
+DEFINES_COMMON = MODULE_STRINGS_COMPRESSED MODULE_HOTKEYS MODULE_EBIOS MODULE_FEATURE_SETS RESERVE_DIAGNOSTIC_CYLINDER
 DEFINES_COMMON_LARGE = MODULE_BOOT_MENU MODULE_SERIAL MODULE_SERIAL_FLOPPY
 
