Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH25h_HDrvID.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH25h_HDrvID.asm	(revision 162)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH25h_HDrvID.asm	(revision 165)
@@ -22,7 +22,32 @@
 ALIGN JUMP_ALIGN
 AH25h_HandlerForGetDriveInformation:
+	mov		si, [bp+IDEPACK.intpack+INTPACK.bx]
+%ifdef USE_186
+	push	Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
+	; Fall to AH25h_GetDriveInformationToBufferInESSIfromDriveInDL
+%else
+	call	AH25h_GetDriveInformationToBufferInESSIfromDriveInDL
+	jmp		Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
+%endif
+
+
+;--------------------------------------------------------------------
+; AH25h_GetDriveInformationToBufferInESSIfromDriveInDL
+;	Parameters:
+;		DL:		Translated Drive number
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;		ES:SI:	Ptr to buffer to receive 512-byte drive information
+;	Returns with INTPACK:
+;		AH:		Int 13h return status
+;		CF:		0 if succesfull, 1 if error
+;	Corrupts registers:
+;		AL, BX, CX, DX
+;--------------------------------------------------------------------
+AH25h_GetDriveInformationToBufferInESSIfromDriveInDL:
+	push	es
 	push	bp
+	push	di
+	push	si
 
-	mov		si, [bp+IDEPACK.intpack+INTPACK.bx]
 	call	AccessDPT_GetDriveSelectByteToAL
 	mov		bh, al
@@ -31,4 +56,7 @@
 	call	Device_IdentifyToBufferInESSIwithDriveSelectByteInBH
 
+	pop		si
+	pop		di
 	pop		bp
-	jmp		Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
+	pop		es
+	ret
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH2h_HRead.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH2h_HRead.asm	(revision 162)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH2h_HRead.asm	(revision 165)
@@ -15,5 +15,5 @@
 ;		SS:BP:	Ptr to IDEPACK
 ;	Parameters on INTPACK:
-;		AL:		Number of sectors to read (1...255)
+;		AL:		Number of sectors to read (1...127)
 ;		CH:		Cylinder number, bits 7...0
 ;		CL:		Bits 7...6: Cylinder number bits 9 and 8
@@ -29,9 +29,9 @@
 AH2h_HandlerForReadDiskSectors:
 	cmp		BYTE [bp+IDEPACK.intpack+INTPACK.al], 0
-	je		SHORT AH2h_ExitInt13hSinceSectorCountInIntpackIsZero
+	jle		SHORT AH2h_ExitInt13hSinceSectorCountInIntpackIsZero
 
-	mov		ah, COMMAND_READ_SECTORS	; Load sector mode command
-	test	BYTE [di+DPT.bFlagsHigh], FLGH_DPT_BLOCK_MODE_SUPPORTED
-	eCMOVNZ	ah, COMMAND_READ_MULTIPLE	; Load block mode command
+	xor		bx, bx
+	call	CommandLookup_OrOldInt13hIndexToBL
+	mov		ah, [cs:bx+g_rgbReadCommandLookup]
 	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRQ)
 	mov		si, [bp+IDEPACK.intpack+INTPACK.bx]
@@ -55,2 +55,3 @@
 	mov		ah, RET_HD_INVALID
 	jmp		Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
+
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH3h_HWrite.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH3h_HWrite.asm	(revision 162)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH3h_HWrite.asm	(revision 165)
@@ -15,5 +15,5 @@
 ;		SS:BP:	Ptr to IDEREGS_AND_INTPACK
 ;	Parameters on INTPACK:
-;		AL:		Number of sectors to write
+;		AL:		Number of sectors to write (1...127)
 ;		CH:		Cylinder number, bits 7...0
 ;		CL:		Bits 7...6: Cylinder number bits 9 and 8
@@ -28,9 +28,9 @@
 AH3h_HandlerForWriteDiskSectors:
 	cmp		BYTE [bp+IDEPACK.intpack+INTPACK.al], 0
-	je		SHORT AH2h_ExitInt13hSinceSectorCountInIntpackIsZero
+	jle		SHORT AH2h_ExitInt13hSinceSectorCountInIntpackIsZero
 
-	mov		ah, COMMAND_WRITE_SECTORS	; Load sector mode command
-	test	BYTE [di+DPT.bFlagsHigh], FLGH_DPT_BLOCK_MODE_SUPPORTED
-	eCMOVNZ	ah, COMMAND_WRITE_MULTIPLE	; Load block mode command
+	xor		bx, bx
+	call	CommandLookup_OrOldInt13hIndexToBL
+	mov		ah, [cs:bx+g_rgbWriteCommandLookup]
 	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRQ)
 	mov		si, [bp+IDEPACK.intpack+INTPACK.bx]
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH4h_HVerify.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH4h_HVerify.asm	(revision 162)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH4h_HVerify.asm	(revision 165)
@@ -15,5 +15,5 @@
 ;		SS:BP:	Ptr to INTPACK
 ;	Parameters on INTPACK in SS:BP:
-;		AL:		Number of sectors to verify
+;		AL:		Number of sectors to verify (1...127)
 ;		CH:		Cylinder number, bits 7...0
 ;		CL:		Bits 7...6: Cylinder number bits 9 and 8
@@ -27,5 +27,5 @@
 AH4h_HandlerForVerifyDiskSectors:
 	cmp		BYTE [bp+IDEPACK.intpack+INTPACK.al], 0
-	je		SHORT AH2h_ExitInt13hSinceSectorCountInIntpackIsZero
+	jle		SHORT AH2h_ExitInt13hSinceSectorCountInIntpackIsZero
 
 	mov		ah, COMMAND_VERIFY_SECTORS
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH41h_CheckIfExtensionsPresent.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH41h_CheckIfExtensionsPresent.asm	(revision 165)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH41h_CheckIfExtensionsPresent.asm	(revision 165)
@@ -0,0 +1,33 @@
+; Project name	:	XTIDE Universal BIOS
+; Description	:	Int 13h function AH=41h, Check if Extensions Present.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Int 13h function AH=41h, Check if Extensions Present.
+;
+; AH41h_HandlerForCheckIfExtensionsPresent
+;	Parameters:
+;		DL:		Translated Drive number
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;		SS:BP:	Ptr to IDEPACK
+;	Parameters on INTPACK:
+;		BX:		55AAh
+;	Returns with INTPACK:
+;		AH:		Major version of EBIOS extensions
+;		BX:		55AAh
+;		CX:		Support bits
+;		CF:		0 if succesfull, 1 if error
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+AH41h_HandlerForCheckIfExtensionsPresent:
+	cmp		WORD [bp+IDEPACK.intpack+INTPACK.bx], 55AAh
+	jne		SHORT .EbiosNotSupported
+
+	mov		WORD [bp+IDEPACK.intpack+INTPACK.cx], ENHANCED_DRIVE_ACCESS_SUPPORT
+	mov		ah, EBIOS_VERSION
+	and		BYTE [bp+IDEPACK.intpack+INTPACK.flags], ~FLG_FLAGS_CF	; Return with CF cleared
+	jmp		Int13h_ReturnFromHandlerWithoutStoringErrorCode
+.EbiosNotSupported:
+	jmp		Int13h_UnsupportedFunction
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH42h_ExtendedReadSectors.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH42h_ExtendedReadSectors.asm	(revision 165)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH42h_ExtendedReadSectors.asm	(revision 165)
@@ -0,0 +1,61 @@
+; Project name	:	XTIDE Universal BIOS
+; Description	:	Int 13h function AH=42h, Extended Read Sectors.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Int 13h function AH=42h, Extended Read Sectors.
+;
+; AH42h_HandlerForExtendedReadSectors
+;	Parameters:
+;		SI:		Same as in INTPACK
+;		DL:		Translated Drive number
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;		SS:BP:	Ptr to IDEPACK
+;	Parameters on INTPACK:
+;		DS:SI:	Ptr to Disk Address Packet
+;	Returns with INTPACK:
+;		AH:		Int 13h return status
+;		CF:		0 if succesfull, 1 if error
+;	Return with Disk Address Packet in INTPACK:
+;		.bSectorCount	Number of sectors read successfully
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+AH42h_HandlerForExtendedReadSectors:
+	call	AH42h_LoadDapToESSIandVerifyForTransfer
+	call	CommandLookup_GetEbiosIndexToBX
+	mov		ah, [cs:bx+g_rgbReadCommandLookup]
+	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRQ)
+%ifdef USE_186
+	push	Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
+	jmp		Idepack_ConvertDapToIdepackAndIssueCommandFromAH
+%else
+	call	Idepack_ConvertDapToIdepackAndIssueCommandFromAH
+	jmp		Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
+%endif
+
+
+;--------------------------------------------------------------------
+; AH42h_LoadDapToESSIandVerifyForTransfer
+;	Parameters:
+;		SI:		Same as in INTPACK
+;		SS:BP:	Ptr to IDEPACK
+;	Parameters on INTPACK:
+;		DS:SI:	Ptr to Disk Address Packet
+;	Returns:
+;		ES:SI:	Ptr to Disk Address Packet (DAP)
+;		Exits from INT 13h if invalid DAP
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+AH42h_LoadDapToESSIandVerifyForTransfer:
+	mov		es, [bp+IDEPACK.intpack+INTPACK.ds]	; ES:SI to point Disk Address Packet
+	cmp		BYTE [es:si+DAP.bSize], MINIMUM_DAP_SIZE
+	jb		SHORT .DapContentsNotValid
+	cmp		BYTE [es:si+DAP.bSectorCount], 0
+	jle		SHORT .DapContentsNotValid			; Must be 1...127
+	ret
+.DapContentsNotValid:
+	jmp		AH2h_ExitInt13hSinceSectorCountInIntpackIsZero
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH43h_ExtendedWriteSectors.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH43h_ExtendedWriteSectors.asm	(revision 165)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH43h_ExtendedWriteSectors.asm	(revision 165)
@@ -0,0 +1,44 @@
+; Project name	:	XTIDE Universal BIOS
+; Description	:	Int 13h function AH=43h, Extended Write Sectors.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Int 13h function AH=43h, Extended Write Sectors.
+;
+; AH43h_HandlerForExtendedWriteSectors
+;	Parameters:
+;		SI:		Same as in INTPACK
+;		DL:		Translated Drive number
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;		SS:BP:	Ptr to IDEPACK
+;	Parameters on INTPACK:
+;		AL:		0 or 1 to write with verify off
+;				2 to write with verify (if supported)
+;		DS:SI:	Ptr to Disk Address Packet
+;	Returns with INTPACK:
+;		AH:		Int 13h return status
+;		CF:		0 if succesfull, 1 if error
+;	Return with Disk Address Packet in INTPACK:
+;		.bSectorCount	Number of sectors written successfully
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+AH43h_HandlerForExtendedWriteSectors:
+	cmp		BYTE [bp+IDEPACK.intpack+INTPACK.al], 2	; Verify requested?
+	jae		SHORT .WriteWithVerifyNotSupported
+
+	call	AH42h_LoadDapToESSIandVerifyForTransfer
+	call	CommandLookup_GetEbiosIndexToBX
+	mov		ah, [cs:bx+g_rgbWriteCommandLookup]
+	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRQ)
+%ifdef USE_186
+	push	Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
+	jmp		Idepack_ConvertDapToIdepackAndIssueCommandFromAH
+%else
+	call	Idepack_ConvertDapToIdepackAndIssueCommandFromAH
+	jmp		Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
+%endif
+
+.WriteWithVerifyNotSupported:
+	jmp		AH2h_ExitInt13hSinceSectorCountInIntpackIsZero
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH44h_ExtendedVerifySectors.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH44h_ExtendedVerifySectors.asm	(revision 165)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH44h_ExtendedVerifySectors.asm	(revision 165)
@@ -0,0 +1,36 @@
+; Project name	:	XTIDE Universal BIOS
+; Description	:	Int 13h function AH=44h, Extended Verify Sectors.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Int 13h function AH=44h, Extended Verify Sectors.
+;
+; AH44h_HandlerForExtendedVerifySectors
+;	Parameters:
+;		SI:		Same as in INTPACK
+;		DL:		Translated Drive number
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;		SS:BP:	Ptr to IDEPACK
+;	Parameters on INTPACK:
+;		DS:SI:	Ptr to Disk Address Packet
+;	Returns with INTPACK:
+;		AH:		Int 13h return status
+;		CF:		0 if succesfull, 1 if error
+;	Return with Disk Address Packet in INTPACK:
+;		.bSectorCount	Number of sectors verified successfully
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+AH44h_HandlerForExtendedVerifySectors:
+	call	AH42h_LoadDapToESSIandVerifyForTransfer
+	call	CommandLookup_GetEbiosIndexToBX
+	mov		ah, [cs:bx+g_rgbVerifyCommandLookup]
+	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRDY)
+%ifdef USE_186
+	push	Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
+	jmp		Idepack_ConvertDapToIdepackAndIssueCommandFromAH
+%else
+	call	Idepack_ConvertDapToIdepackAndIssueCommandFromAH
+	jmp		Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
+%endif
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH47h_ExtendedSeek.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH47h_ExtendedSeek.asm	(revision 165)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH47h_ExtendedSeek.asm	(revision 165)
@@ -0,0 +1,40 @@
+; Project name	:	XTIDE Universal BIOS
+; Description	:	Int 13h function AH=47h, Extended Seek.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Int 13h function AH=47h, Extended Seek.
+;
+; AH47h_HandlerForExtendedSeek
+;	Parameters:
+;		SI:		Same as in INTPACK
+;		DL:		Translated Drive number
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;		SS:BP:	Ptr to IDEPACK
+;	Parameters on INTPACK:
+;		DS:SI:	Ptr to Disk Address Packet
+;	Returns with INTPACK:
+;		AH:		Int 13h return status
+;		CF:		0 if succesfull, 1 if error
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+AH47h_HandlerForExtendedSeek:
+	; Note that there is no Seek command for LBA48 addressing!
+	mov		es, [bp+IDEPACK.intpack+INTPACK.ds]	; ES:SI to point Disk Address Packet
+	cmp		BYTE [es:si+DAP.bSize], MINIMUM_DAP_SIZE
+	jb		SHORT .DapContentsNotValid
+
+	mov		ah, COMMAND_SEEK
+	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRDY)
+%ifdef USE_186
+	push	Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
+	jmp		Idepack_ConvertDapToIdepackAndIssueCommandFromAH
+%else
+	call	Idepack_ConvertDapToIdepackAndIssueCommandFromAH
+	jmp		Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
+%endif
+
+.DapContentsNotValid:
+	jmp		AH2h_ExitInt13hSinceSectorCountInIntpackIsZero
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH48h_GetExtendedDriveParameters.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH48h_GetExtendedDriveParameters.asm	(revision 165)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH48h_GetExtendedDriveParameters.asm	(revision 165)
@@ -0,0 +1,65 @@
+; Project name	:	XTIDE Universal BIOS
+; Description	:	Int 13h function AH=48h, Get Extended Drive Parameters.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; Int 13h function AH=48h, Get Extended Drive Parameters.
+;
+; AH48h_GetExtendedDriveParameters
+;	Parameters:
+;		SI:		Same as in INTPACK
+;		DL:		Translated Drive number
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;		SS:BP:	Ptr to IDEPACK
+;	Parameters on INTPACK:
+;		DS:SI:	Ptr to Extended Drive Information Table to fill
+;	Returns with INTPACK:
+;		AH:		Int 13h return status
+;		DS:SI:	Ptr to Extended Drive Information Table
+;		CF:		0 if succesfull, 1 if error
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+AH48h_HandlerForGetExtendedDriveParameters:
+	; Get ATA Drive Information and total sector count from it
+	push	ds
+	pop		es			; ES now points RAMVARS segment
+	mov		si, [cs:ROMVARS.bStealSize]
+	and		si, BYTE 7Fh
+	eSHL_IM	si, 10		; Kilobytes to bytes
+	sub		si, 512		; Subtract buffer size for offset in RAMVARS
+	call	AH25h_GetDriveInformationToBufferInESSIfromDriveInDL
+	call	AtaID_GetTotalSectorCountToBXDXAXfromAtaInfoInESSI
+	xchg	cx, ax
+
+	; Point ES:DI to Destination buffer
+	mov		di, [bp+IDEPACK.intpack+INTPACK.si]
+	mov		es, [bp+IDEPACK.intpack+INTPACK.ds]
+	cmp		WORD [es:di+EDRIVE_INFO.wSize], MINIMUM_EDRIVEINFO_SIZE
+	jb		SHORT .BufferTooSmall
+
+	; Fill Extended Drive Information Table in ES:DI
+	mov		ax, MINIMUM_EDRIVEINFO_SIZE
+	stosw
+	mov		al, FLG_DMA_BOUNDARY_ERRORS_HANDLED_BY_BIOS
+	stosw
+	add		di, BYTE 12	; Skip CHS parameters
+	xchg	ax, cx
+	stosw				; LBA WORD 0
+	xchg	ax, dx
+	stosw				; LBA WORD 1
+	xchg	ax, bx
+	stosw				; LBA WORD 2
+	xor		ax, ax
+	stosw				; LBA WORD 3 always zero since 48-bit address
+	mov		ah, 512>>8
+	stosw				; Always 512-byte sectors
+
+	; Return with success
+	xor		ah, ah
+	jmp		Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
+
+.BufferTooSmall:
+	mov		ah, RET_HD_INVALID
+	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 165)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/Address.asm	(revision 165)
@@ -0,0 +1,154 @@
+; Project name	:	XTIDE Universal BIOS
+; Description	:	Functions for address translations.
+
+; Section containing code
+SECTION .text
+
+; Jump table for conversion functions
+ALIGN WORD_ALIGN
+g_rgfnAddressTranslation:
+	dw		DoNotConvertLCHS					; 0, ADDR_DPT_LCHS
+	dw		ConvertLCHStoPCHS					; 1, ADDR_DPT_PCHS
+	dw		ConvertLCHStoLBARegisterValues		; 2, ADDR_DPT_LBA28
+	dw		ConvertLCHStoLBARegisterValues		; 3, ADDR_DPT_LBA48
+
+
+;--------------------------------------------------------------------
+; Address_OldInt13hAddressToIdeAddress
+;	Parameters:
+;		CH:		Cylinder number, bits 7...0
+;		CL:		Bits 7...6: Cylinder number bits 9 and 8
+;				Bits 5...0:	Starting sector number (1...63)
+;		DH:		Starting head number (0...255)
+;		DS:DI:	Ptr to DPT
+;	Returns:
+;		BL:		LBA Low Register / Sector Number Register (LBA 7...0)
+;		CL:		LBA Mid Register / Low Cylinder Register (LBA 15...8)
+;		CH:		LBA High Register / High Cylinder Register (LBA 23...16)
+;		BH:		Drive and Head Register (LBA 27...24)
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+Address_OldInt13hAddressToIdeAddress:
+	call	AccessDPT_GetAddressingModeForWordLookToBX
+	push	WORD [cs:bx+g_rgfnAddressTranslation]		; Push return address
+	; Fall to Address_ExtractLCHSparametersFromOldInt13hAddress
+
+;---------------------------------------------------------------------
+; Address_ExtractLCHSparametersFromOldInt13hAddress
+;	Parameters:
+;		CH:		Cylinder number, bits 7...0
+;		CL:		Bits 7...6: Cylinder number bits 9 and 8
+;				Bits 5...0:	Sector number
+;		DH:		Head number
+;	Returns:
+;		BL:		Sector number (1...63)
+;		BH:		Head number (0...255)
+;		CX:		Cylinder number (0...1023)
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+Address_ExtractLCHSparametersFromOldInt13hAddress:
+	mov		bl, cl				; Copy sector number...
+	and		bl, 3Fh				; ...and limit to 1...63
+	sub		cl, bl				; Remove from cylinder number high
+	eROL_IM	cl, 2				; High bits to beginning
+	mov		bh, dh				; Copy Head number
+	xchg	cl, ch				; Cylinder number now in CX
+	ret
+
+
+;---------------------------------------------------------------------
+; Converts LCHS parameters to IDE P-CHS parameters.
+; PCylinder	= (LCylinder << n) + (LHead / PHeadCount)
+; PHead		= LHead % PHeadCount
+; PSector	= LSector
+;
+; Address_ConvertLCHStoPCHS:
+;	Parameters:
+;		BL:		Sector number (1...63)
+;		BH:		Head number (0...255)
+;		CX:		Cylinder number (0...1023)
+;		DS:DI:	Ptr to Disk Parameter Table
+;	Returns:
+;		BL:		Sector number (1...63)
+;		BH:		Head number (0...15)
+;		CX:		Cylinder number (0...16382)
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ConvertLCHStoPCHS:
+	; LHead / PHeadCount and LHead % PHeadCount
+	eMOVZX	ax, bh					; Copy L-CHS Head number to AX
+	div		BYTE [di+DPT.bPchsHeads]; AL = LHead / PHeadCount, AH = LHead % PHeadCount
+	mov		bh, ah					; Copy P-CHS Head number to BH
+	xor		ah, ah					; AX = LHead / PHeadCount
+
+	; (LCylinder << n) + (LHead / PHeadCount)
+	mov		dx, cx					; Copy L-CHS Cylinder number to DX
+	mov		cl, [di+DPT.bFlagsLow]	; Load shift count
+	and		cl, MASKL_DPT_CHS_SHIFT_COUNT
+	shl		dx, cl					; DX = LCylinder << n
+	add		ax, dx					; AX = P-CHS Cylinder number
+	xchg	cx, ax					; Move P-CHS Cylinder number to CX
+DoNotConvertLCHS:
+	ret
+
+
+;---------------------------------------------------------------------
+; Converts LCHS parameters to 28-bit LBA address.
+; Only 24-bits are used since LHCS to LBA28 conversion has 8.4GB limit.
+; LBA = ((cylToSeek*headsPerCyl+headToSeek)*sectPerTrack)+sectToSeek-1
+;
+; Returned address is in same registers that
+; Address_DoNotConvertLCHS and Address_ConvertLCHStoPCHS returns.
+;
+; ConvertLCHStoLBARegisterValues:
+;	Parameters:
+;		BL:		Sector number (1...63)
+;		BH:		Head number (0...255)
+;		CX:		Cylinder number (0...1023)
+;		DS:DI:	Ptr to Disk Parameter Table
+;	Returns:
+;		BL:		LBA Low Register / Sector Number Register (LBA 7...0)
+;		CL:		LBA Mid Register / Low Cylinder Register (LBA 15...8)
+;		CH:		LBA High Register / High Cylinder Register (LBA 23...16)
+;		BH:		Drive and Head Register (LBA 27...24)
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ConvertLCHStoLBARegisterValues:
+	; cylToSeek*headsPerCyl (18-bit result)
+	mov		ax, cx					; Copy Cylinder number to AX
+	eMOVZX	dx, BYTE [di+DPT.bLchsHeads]
+	mul		dx						; DX:AX = cylToSeek*headsPerCyl
+
+	; +=headToSeek (18-bit result)
+	add		al, bh					; Add Head number to DX:AX
+	adc		ah, dh					; DH = Zero after previous multiplication
+	adc		dl, dh
+
+	; *=sectPerTrack (18-bit by 6-bit multiplication with 24-bit result)
+	eMOVZX	cx, BYTE [di+DPT.bPchsSectors]	; Load Sectors per Track
+	xchg	ax, dx					; Hiword to AX, loword to DX
+	mul		cl						; AX = hiword * Sectors per Track
+	mov		bh, al					; Backup hiword * Sectors per Track
+	xchg	ax, dx					; Loword back to AX
+	mul		cx						; DX:AX = loword * Sectors per Track
+	add		dl, bh					; DX:AX = (cylToSeek*headsPerCyl+headToSeek)*sectPerTrack
+
+	; +=sectToSeek-1 (24-bit result)
+	xor		bh, bh					; Sector number now in BX
+	dec		bx						; sectToSeek-=1
+	add		ax, bx					; Add to loword
+	adc		dl, bh					; Add possible carry to byte2, BH=zero
+
+	; Copy DX:AX to proper return registers
+	xchg	bx, ax					; BL = Sector Number Register (LBA 7...0)
+	mov		cl, bh					; Low Cylinder Register (LBA 15...8)
+	mov		ch, dl					; High Cylinder Register (LBA 23...16)
+	mov		bh, dh					; Drive and Head Register (LBA 27...24)
+	ret
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/CommandLookup.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/CommandLookup.asm	(revision 165)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/CommandLookup.asm	(revision 165)
@@ -0,0 +1,54 @@
+; Project name	:	XTIDE Universal BIOS
+; Description	:	Functions for loading correct transfer command.
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; CommandLookup_GetEbiosIndexToBX
+; CommandLookup_OrOldInt13hIndexToBL
+;	Parameters:
+;		DS:DI:	Ptr to DPT
+;		ES:SI:	Ptr to DAP (Disk Address Packet)
+;	Returns:
+;		BX:		Index to command lookup table
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+CommandLookup_GetEbiosIndexToBX:
+	; LBA28 or LBA48 command
+	xor		bx, bx
+	mov		ax, [es:si+DAP.qwLBA+3]	; Load LBA48 bytes 3 and 4
+	and		al, ~0Fh				; Clear LBA28 bits 24...27
+	or		al, [es:si+DAP.qwLBA+5]
+	cmp		bx, ax					; Set CF if any of bits 28...47 set
+	rcl		bx, 1					; BX = 0 for LBA28, BX = 1 for LBA48
+
+	; Block mode or single sector
+ALIGN JUMP_ALIGN
+CommandLookup_OrOldInt13hIndexToBL:
+	mov		al, FLGH_DPT_BLOCK_MODE_SUPPORTED	; Bit 1
+	and		al, [di+DPT.bFlagsHigh]
+	or		bl, al					; BX = index to lookup table
+	ret
+
+
+g_rgbReadCommandLookup:
+	db		COMMAND_READ_SECTORS		; 00b, CHS or LBA28 single sector
+	db		COMMAND_READ_SECTORS_EXT	; 01b, LBA48 single sector
+	db		COMMAND_READ_MULTIPLE		; 10b, CHS or LBA28 block mode
+	db		COMMAND_READ_MULTIPLE_EXT	; 11b, LBA48 block mode
+
+g_rgbWriteCommandLookup:
+	db		COMMAND_WRITE_SECTORS
+	db		COMMAND_WRITE_SECTORS_EXT
+	db		COMMAND_WRITE_MULTIPLE
+	db		COMMAND_WRITE_MULTIPLE_EXT
+
+g_rgbVerifyCommandLookup:
+	db		COMMAND_VERIFY_SECTORS
+	db		COMMAND_VERIFY_SECTORS_EXT
+	db		COMMAND_VERIFY_SECTORS
+	db		COMMAND_VERIFY_SECTORS_EXT		
+
