Index: trunk/XTIDE_Universal_BIOS/Src/Device/Device.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/Device.asm	(revision 479)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/Device.asm	(revision 480)
@@ -84,5 +84,5 @@
 ;		DX:		Autodetected port (for devices that support autodetection)
 ;		DS:		Segment to RAMVARS
-;		ES:SI:	Ptr to normalized buffer to receive 512-byte IDE Information
+;		ES:SI:	Ptr to buffer to receive 512-byte IDE Information
 ;		CS:BP:	Ptr to IDEVARS
 ;	Returns:
@@ -109,5 +109,5 @@
 ;		BH:		Default system timer ticks for timeout (can be ignored)
 ;		BL:		IDE Status Register bit to poll after command
-;		ES:SI:	Ptr to normalized buffer (for data transfer commands)
+;		ES:SI:	Ptr to buffer (for data transfer commands)
 ;		DS:DI:	Ptr to DPT (in RAMVARS segment)
 ;		SS:BP:	Ptr to IDEPACK
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm	(revision 479)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm	(revision 480)
@@ -88,15 +88,10 @@
 
 %ifdef MODULE_8BIT_IDE
-	; We set XT-CF to 8-bit PIO mode for Identify Device command.
-	; Correct XT-CF mode is later set on AH=09h (after all drives are detected).
-	call	AccessDPT_IsThisDeviceXTCF
-	jne		SHORT .SkipXTCFmodeChange
-
+	; Enable 8-bit PIO mode for 8-bit ATA and XT-CF
+	push	si
+	call	AH9h_Enable8bitModeForDevice8bitAta
 	xor		al, al						; XTCF_8BIT_PIO_MODE
-	push	si
-	call	AH1Eh_ChangeXTCFmodeBasedOnControlRegisterInAL
+	call	AH9h_SetModeFromALtoXTCF
 	pop		si
-	jc		SHORT .FailedToSet8bitMode
-.SkipXTCFmodeChange:
 %endif ; MODULE_8BIT_IDE
 
@@ -178,13 +173,8 @@
 	jne		SHORT .WaitUntilNonTransferCommandCompletes
 %ifdef MODULE_8BIT_IDE
-	cmp		BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_XTCF_DMA
-	je		SHORT .StartDmaTransfer
-	ja		SHORT JrIdeTransfer_StartWithCommandInAL	; DEVICE_8BIT_XTCF_MEMMAP or DEVICE_8BIT_JRIDE_ISA
+	cmp		BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_XTCF_MEMMAP
+	jae		SHORT JrIdeTransfer_StartWithCommandInAL	; DEVICE_8BIT_XTCF_MEMMAP or DEVICE_8BIT_JRIDE_ISA
+%endif
 	jmp		IdeTransfer_StartWithCommandInAL
-.StartDmaTransfer:
-	jmp		IdeDmaTransfer_StartWithCommandInAL
-%else
-	jmp		IdeTransfer_StartWithCommandInAL
-%endif
 
 .WaitUntilNonTransferCommandCompletes:
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDmaBlock.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDmaBlock.asm	(revision 480)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDmaBlock.asm	(revision 480)
@@ -0,0 +1,175 @@
+; Project name	:	XTIDE Universal BIOS
+; Description	:	IDE Read/Write functions for transferring
+;					block using DMA.
+;					These functions should only be called from IdeTransfer.asm.
+
+;
+; 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
+
+;--------------------------------------------------------------------
+; IdeDmaBlock_WriteToXTCF
+;	Parameters:
+;		CX:		Block size in 512 byte sectors
+;		DX:		XTCF Base Port Address
+;		ES:SI:	Physical address to buffer to receive data
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+IdeDmaBlock_WriteToXTCF:
+	xchg	si, di
+	mov		bl, CHANNEL_3 | READ | AUTOINIT_DISABLE | ADDRESS_INCREMENT | DEMAND_MODE
+	call	TransferBlockToOrFromXTCF
+	xchg	di, si
+	ret
+
+
+;--------------------------------------------------------------------
+; IdeDmaBlock_ReadFromXTCF
+;	Parameters:
+;		CX:		Block size in 512 byte sectors
+;		DX:		XTCF Base Port Address
+;		ES:DI:	Physical address to buffer to receive data
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+IdeDmaBlock_ReadFromXTCF:
+	mov		bl, CHANNEL_3 | WRITE | AUTOINIT_DISABLE | ADDRESS_INCREMENT | DEMAND_MODE
+	; Fall to TransferBlockToOrFromXTCF
+
+
+;--------------------------------------------------------------------
+; TransferBlockToOrFromXTCF
+;	Parameters:
+;		BL:		Mode byte for DMA Mode Register
+;		CX:		Block size in 512 byte sectors
+;		DX:		XTCF Base Port Address
+;		ES:DI:	Physical address to buffer to receive data
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX
+;--------------------------------------------------------------------
+TransferBlockToOrFromXTCF:
+	; 8-bit DMA transfers must be done withing 64k physical page.
+	; We support maximum of 128 sectors (65536 bytes) per one INT 13h call
+	; so we might need to separate transfer to 2 separate DMA operations.
+
+	; Load XT-CF Control Register port to DX
+	add		dl, XTCF_CONTROL_REGISTER
+
+	; Calculate bytes for first page
+	mov		ax, di
+	neg		ax										; AX = Max BYTEs for first page
+%ifdef USE_186
+	shl		cx, 9									; CX = Block size in BYTEs
+%else
+	xchg	cl, ch
+	shl		cx, 1
+%endif
+	cmp		cx, ax
+	jbe		SHORT .TransferLastDmaPageWithSizeInCX
+
+	; Push size for second DMA page
+	xchg	cx, ax									; CX = BYTEs for first page
+	sub		ax, cx									; AX = BYTEs for second page
+	push	ax
+
+	; Transfer first DMA page
+	call	StartDMAtransferForXTCFwithDmaModeInBL
+	pop		cx										; Pop size for second DMA page
+
+.TransferLastDmaPageWithSizeInCX:
+	; Fall to StartDMAtransferForXTCFwithDmaModeInBL
+
+
+;--------------------------------------------------------------------
+; StartDMAtransferForXTCFwithDmaModeInBL
+;	Parameters:
+;		CX:		Number of BYTEs to transfer
+;		BL:		Byte for DMA Mode Register
+;		DX:		XTCF Control Register
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+StartDMAtransferForXTCFwithDmaModeInBL:
+	; Program 8-bit DMA Controller
+	; Disable Interrupts and DMA Channel 3 during DMA setup
+	mov		al, SET_CH3_MASK_BIT
+	cli										; Disable interrupts
+	out		MASK_REGISTER_DMA8_out, al		; Disable DMA Channel 3
+
+	; Set DMA Mode (read or write using channel 3)
+	mov		al, bl
+	out		MODE_REGISTER_DMA8_out, al
+
+	; Set address to DMA controller
+	out		CLEAR_FLIPFLOP_DMA8_out, al		; Reset flip-flop to low byte
+	mov		ax, es
+	out		PAGE_DMA8_CH_3, al
+	mov		ax, di
+	out		BASE_AND_CURRENT_ADDRESS_REGISTER_DMA8_CH3_out, al	; Low byte
+	mov		al, ah
+	out		BASE_AND_CURRENT_ADDRESS_REGISTER_DMA8_CH3_out, al	; High byte
+
+	; Set number of bytes to transfer (DMA controller must be programmed number of bytes - 1)
+	mov		ax, cx
+	dec		ax								; DMA controller is programmed for one byte less
+	out		BASE_AND_CURRENT_COUNT_REGISTER_DMA8_CH3_out, al	; Low byte
+	mov		al, ah
+	out		BASE_AND_CURRENT_COUNT_REGISTER_DMA8_CH3_out, al	; High byte
+
+	; Enable DMA Channel 3
+	mov		al, CLEAR_CH3_MASK_BIT
+	out		MASK_REGISTER_DMA8_out, al		; Enable DMA Channel 3
+	sti										; Enable interrupts
+
+
+	; XT-CF transfers 16 bytes at a time. We need to manually
+	; start transfer for every block.
+ALIGN JUMP_ALIGN
+.TransferNextBlock:
+	mov		al, RAISE_DRQ_AND_CLEAR_XTCF_XFER_COUNTER
+	cli									; We want no ISR to read DMA Status Register before we do
+	out		dx, al						; Transfer up to 16 bytes to/from XT-CF card
+	; * Here XT-CF sets CPU to wait states during transfer *
+	in		al, STATUS_REGISTER_DMA8_in
+	sti
+	test	al, FLG_CH3_HAS_REACHED_TERMINAL_COUNT
+	jz		SHORT .TransferNextBlock	; All bytes transferred?
+
+	; Restore XT-CF to normal operation
+	mov		al, XTCF_DMA_MODE
+	out		dx, al
+
+	; Increment physical address in ES:DI
+	mov		ax, es
+	add		di, cx
+	adc		al, ah
+	mov		es, ax
+	ret
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDmaTransfer.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDmaTransfer.asm	(revision 479)
+++ 	(revision )
@@ -1,217 +1,0 @@
-; Project name	:	XTIDE Universal BIOS
-; Description	:	IDE Device DMA transfer functions.
-
-;
-; 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
-;
-
-; Structure containing variables for DMA transfer functions.
-; This struct must not be larger than IDEPACK without INTPACK.
-struc DMAVARS	; Must not be larger than 9 bytes! See IDEPACK in RamVars.inc.
-	.wTotalBytesXferred			resb	2	; 0-1, 
-	.wBytesLeftToXfer			resb	2	; 2-3, 0 = 65536
-	.bbbPhysicalAddress			resb	3	; 4-6, 
-								resb	1	; 7, IDEPACK.bDeviceControl
-endstruc
-
-
-; Section containing code
-SECTION .text
-
-;--------------------------------------------------------------------
-; IdeDmaTransfer_StartWithCommandInAL
-;	Parameters:
-;		AL:		IDE command that was used to start the transfer
-;				(all PIO read and write commands including Identify Device)
-;		ES:SI:	Ptr to data buffer (not normalized)
-;		DS:DI:	Ptr to DPT (in RAMVARS segment)
-;		SS:BP:	Ptr to IDEPACK
-;	Returns:
-;		AH:		INT 13h Error Code
-;		CX:		Number of successfully transferred sectors
-;		CF:		Cleared if success, Set if error
-;	Corrupts registers:
-;		AL, BX, DX
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-IdeDmaTransfer_StartWithCommandInAL:
-	; Initialize DMAVARS
-	xor		cx, cx
-	mov		[bp+DMAVARS.wTotalBytesXferred], cx
-	mov		ch, [bp+IDEPACK.bSectorCount]	; CX = WORDs to transfer
-	shl		cx, 1							; WORDs to BYTEs, 0 = 65536
-	mov		[bp+DMAVARS.wBytesLeftToXfer], cx
-
-	; Convert Segment:Offset type pointer to physical address
-	xor		bx, bx
-	mov		cx, es
-%rep 4
-	shl		cx, 1
-	rcl		bx, 1
-%endrep
-	add		cx, si
-	adc		bl, bh
-	mov		[bp+DMAVARS.bbbPhysicalAddress], cx
-	mov		[bp+DMAVARS.bbbPhysicalAddress+2], bl
-
-	; Calculate bytes for first page
-	neg		cx	; Max number of bytes for first page, 0 = 65536
-	MIN_U	cx, [bp+DMAVARS.wBytesLeftToXfer]
-
-	; Are we reading or writing?
-	mov		bl, CHANNEL_3 | READ | AUTOINIT_DISABLE | ADDRESS_INCREMENT | DEMAND_MODE	; Assume write command
-	test	al, 16	; Bit 4 is cleared on all the read commands but set on 3 of the 4 write commands
-	jnz		SHORT TransferBlockToOrFromXTCF
-	cmp		al, COMMAND_WRITE_MULTIPLE
-	je		SHORT TransferBlockToOrFromXTCF
-
-	; Read command
-	mov		bl, CHANNEL_3 | WRITE | AUTOINIT_DISABLE | ADDRESS_INCREMENT | DEMAND_MODE
-	; Fall to TransferBlockToOrFromXTCF
-
-
-;--------------------------------------------------------------------
-; TransferBlockToOrFromXTCF
-;	Parameters:
-;		BX:		Mode byte for DMA Mode Register
-;		CX:		Bytes in first page
-;		DS:DI:	Ptr to DPT (in RAMVARS segment)
-;		SS:BP:	Ptr to DMAVARS
-;	Returns:
-;		DS:DI:	Ptr to DPT (in RAMVARS segment)
-;		AH:		BIOS Error code
-;		CX:		Number of successfully transferred sectors
-;		CF:		0 if transfer successful
-;				1 if any error
-;	Corrupts registers:
-;		AL, BX, DX
-;--------------------------------------------------------------------
-TransferBlockToOrFromXTCF:
-	; 8-bit DMA transfers must be done withing 64k physical page.
-	; We support maximum of 128 sectors (65536 bytes) per one INT 13h call
-	; so we might need to separate transfer to 2 separate DMA operations.
-
-	; Transfer first DMA page
-	call	StartDMAtransferForXTCFwithDmaModeInBL
-	jcxz	.ReturnNumberOfSectorsXferred			; One page was enough (128 sectors)
-	mov		[bp+DMAVARS.wTotalBytesXferred], cx		; Store total BYTEs transferred so far
-
-	; Get bytes left to transfer for second DMA page
-	mov		ax, [bp+DMAVARS.wBytesLeftToXfer]
-	sub		ax, cx
-	jz		SHORT .ReturnNumberOfSectorsXferred		; Transfer was within 64k page
-
-	; Increment address
-	xchg	cx, ax
-	add		[bp+DMAVARS.bbbPhysicalAddress], ax
-	adc		[bp+DMAVARS.bbbPhysicalAddress+2], bh	; Never sets CF
-
-	; Transfer second DMA page if necessary (always less than 64k)
-	call	StartDMAtransferForXTCFwithDmaModeInBL
-	add		[bp+DMAVARS.wTotalBytesXferred], cx
-
-.ReturnNumberOfSectorsXferred:
-	; Check errors
-	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_BSY)
-	call	IdeWait_PollStatusFlagInBLwithTimeoutInBH
-	jc		SHORT .ErrorInTransfer
-
-	; Return number of sectors transferred
-	mov		cx, [bp+DMAVARS.wTotalBytesXferred]
-	jcxz	.FullPageOf128SectorsXferred
-%ifdef USE_186
-	shr		cx, 9		; BYTEs to sectors
-%else
-	xchg	cl, ch		; BYTEs to WORDs
-	shr		cx, 1		; WORDs to sectors
-%endif
-	clc
-	ret
-
-.FullPageOf128SectorsXferred:
-	mov		cx, 128
-	ret
-
-.ErrorInTransfer:
-	mov		cx, 0		; No way to know how many sectors got transferred
-	ret
-
-
-;--------------------------------------------------------------------
-; StartDMAtransferForXTCFwithDmaModeInBL
-;	Parameters:
-;		BL:		Byte for DMA Mode Register
-;		CX:		Number of BYTEs to transfer
-;		DS:DI:	Ptr to DPT (in RAMVARS segment)
-;		SS:BP:	Ptr to DMAVARS
-;	Returns:
-;		Nothing
-;	Corrupts registers:
-;		AL, DX
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-StartDMAtransferForXTCFwithDmaModeInBL:
-	; Program 8-bit DMA Controller
-	; Disable Interrupts and DMA Channel 3 during DMA setup
-	cli										; Disable interrupts
-	mov		al, SET_CH3_MASK_BIT
-	out		MASK_REGISTER_DMA8_out, al		; Disable DMA Channel 3
-
-	; Set DMA Mode (read or write using channel 3)
-	mov		al, bl
-	out		MODE_REGISTER_DMA8_out, al
-
-	; Set address to DMA controller
-	out		CLEAR_FLIPFLOP_DMA8_out, al		; Reset flip-flop to low byte
-	mov		ax, [bp+DMAVARS.bbbPhysicalAddress]
-	out		BASE_AND_CURRENT_ADDRESS_REGISTER_DMA8_CH3_out, al	; Low byte
-	mov		al, ah
-	out		BASE_AND_CURRENT_ADDRESS_REGISTER_DMA8_CH3_out, al	; High byte
-	mov		al, [bp+DMAVARS.bbbPhysicalAddress+2]
-	out		PAGE_DMA8_CH_3, al
-
-	; Set number of bytes to transfer (DMA controller must be programmed number of bytes - 1)
-	out		CLEAR_FLIPFLOP_DMA8_out, al		; Reset flip-flop to low byte
-	mov		ax, cx
-	dec		ax								; DMA controller is programmed for one byte less
-	out		BASE_AND_CURRENT_COUNT_REGISTER_DMA8_CH3_out, al	; Low byte
-	mov		al, ah
-	out		BASE_AND_CURRENT_COUNT_REGISTER_DMA8_CH3_out, al	; High byte
-
-	; Enable DMA Channel 3
-	mov		al, CLEAR_CH3_MASK_BIT
-	out		MASK_REGISTER_DMA8_out, al		; Enable DMA Channel 3
-	sti										; Enable interrupts
-
-
-	; XT-CF transfers 16 bytes at a time. We need to manually
-	; start transfer for every block.
-	mov		dx, [di+DPT.wBasePort]
-	add		dl, XTCF_CONTROL_REGISTER
-ALIGN JUMP_ALIGN
-.TransferNextBlock:
-	mov		al, RAISE_DRQ_AND_CLEAR_XTCF_XFER_COUNTER
-	cli									; We want no ISR to read DMA Status Register before we do
-	out		dx, al						; Transfer up to 16 bytes to/from XT-CF card
-	; * Here XT-CF sets CPU to wait states during transfer *
-	in		al, STATUS_REGISTER_DMA8_in
-	sti
-	test	al, FLG_CH3_HAS_REACHED_TERMINAL_COUNT
-	jz		SHORT .TransferNextBlock	; All bytes transferred?
-
-	; Restore XT-CF to normal operation
-	mov		al, XTCF_DMA_MODE
-	out		dx, al
-	ret
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdePioBlock.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdePioBlock.asm	(revision 479)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdePioBlock.asm	(revision 480)
@@ -215,23 +215,24 @@
 ;		AX, BX, CX
 ;--------------------------------------------------------------------
-%ifdef USE_186	; Also used by XTIDE rev 2 when 80186/80188 commands allowed
-ALIGN JUMP_ALIGN
+ALIGN JUMP_ALIGN
+%ifdef USE_186
 IdePioBlock_ReadFromXtideRev2:
+%endif
 IdePioBlock_ReadFrom16bitDataPort:
 	xchg	cl, ch		; Sectors to WORDs
-	rep insw
-	ret
-%endif
-
-;--------------------------------------------------------------------
-%ifdef USE_AT
+	rep
+	db		6Dh			; INSW
+	ret
+
+;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
 IdePioBlock_ReadFrom32bitDataPort:
-	shl		cx, 7		; Sectors to DWORDs
+	db		0C1h		; SHL
+	db		0E1h		; CX
+	db		7			; 7	(Sectors to DWORDs)
 	rep
 	db		66h			; Override operand size to 32-bit
 	db		6Dh			; INSW/INSD
 	ret
-%endif
 
 
@@ -248,11 +249,10 @@
 ;		AX, BX, CX, DX
 ;--------------------------------------------------------------------
-%ifdef USE_AT
-
 ALIGN JUMP_ALIGN
 IdePioBlock_WriteTo16bitDataPort:
 	xchg	cl, ch		; Sectors to WORDs
 	es					; Source is ES segment
-	rep outsw
+	rep
+	db		6Fh			; OUTSW
 	ret
 
@@ -260,5 +260,7 @@
 ALIGN JUMP_ALIGN
 IdePioBlock_WriteTo32bitDataPort:
-	shl		cx, 7		; Sectors to DWORDs
+	db		0C1h		; SHL
+	db		0E1h		; CX
+	db		7			; 7	(Sectors to DWORDs)
 	es					; Source is ES segment
 	rep
@@ -266,4 +268,2 @@
 	db		6Fh			; OUTSW/OUTSD
 	ret
-
-%endif ; USE_AT
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm	(revision 479)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm	(revision 480)
@@ -38,5 +38,5 @@
 ;		AL:		IDE command that was used to start the transfer
 ;				(all PIO read and write commands including Identify Device)
-;		ES:SI:	Ptr to normalized data buffer
+;		ES:SI:	Ptr to data buffer
 ;		DS:DI:	Ptr to DPT (in RAMVARS segment)
 ;		SS:BP:	Ptr to IDEPACK
@@ -62,5 +62,5 @@
 ;	Parameters:
 ;		AH:		Number of sectors to transfer (1...128)
-;		ES:SI:	Normalized ptr to buffer to receive data
+;		ES:SI:	Ptr to buffer to receive data
 ;		DS:DI:	Ptr to DPT (in RAMVARS segment)
 ;		SS:BP:	Ptr to PIOVARS
@@ -139,5 +139,5 @@
 ;		AH:		Number of sectors to transfer (1...128)
 ;		DS:DI:	Ptr to DPT (in RAMVARS segment)
-;		ES:SI:	Normalized ptr to buffer containing data
+;		ES:SI:	Ptr to buffer containing data
 ;		SS:BP:	Ptr to PIOVARS
 ;	Returns:
@@ -198,4 +198,5 @@
 ;		BX:		Offset to transfer function lookup table
 ;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;		ES:SI:	Ptr to data buffer
 ;		SS:BP:	Ptr to PIOVARS
 ;	Returns:
@@ -217,9 +218,43 @@
 	xchg	ax, bx								; Lookup table offset to AX
 	mov		bl, [di+DPT_ATA.bDevice]
+%ifdef MODULE_8BIT_IDE
+	mov		dl, bl
+%endif
 	add		bx, ax
 	mov		ax, [cs:bx]							; Load offset to transfer function
 	mov		[bp+PIOVARS.fnXfer], ax
-	ret
-
+
+	; Normalize pointer for PIO-transfers and convert to physical address for DMA transfers
+%ifdef MODULE_8BIT_IDE
+	cmp		dl, DEVICE_8BIT_XTCF_DMA
+	jb		SHORT IdeTransfer_NormalizePointerInESSI
+
+	; Convert ES:SI to physical address
+	xor		dx, dx
+	mov		ax, es
+%rep 4
+	shl		ax, 1
+	rcl		dx, 1
+%endrep
+	add		si, ax
+	adc		dl, dh
+	mov		es, dx
+	ret
+%endif ; MODULE_8BIT_IDE
+	; Fall to IdeTransfer_NormalizePointerInESSI if no MODULE_8BIT_IDE
+
+
+;--------------------------------------------------------------------
+; IdeTransfer_NormalizePointerInESSI
+;	Parameters:
+;		ES:SI:	Ptr to be normalized
+;	Returns:
+;		ES:SI:	Normalized pointer (SI = 0...15)
+;	Corrupts registers:
+;		AX, DX
+;--------------------------------------------------------------------
+IdeTransfer_NormalizePointerInESSI:
+	NORMALIZE_FAR_POINTER	es, si, ax, dx
+	ret
 
 
@@ -227,27 +262,23 @@
 ALIGN WORD_ALIGN
 g_rgfnPioRead:
-%ifdef USE_AT
 		dw		IdePioBlock_ReadFrom16bitDataPort	; 0, DEVICE_16BIT_ATA
 		dw		IdePioBlock_ReadFrom32bitDataPort	; 1, DEVICE_32BIT_ATA
-%else
-		dd		0
-%endif
-%ifdef MODULE_8BIT_IDE
-		dw		IdePioBlock_ReadFromXtideRev1		; 2, DEVICE_8BIT_XTIDE_REV1
-	%ifndef USE_AT
-		g_rgfnPioWrite:
-	%endif
-		dw		IdePioBlock_ReadFromXtideRev2		; 3, DEVICE_8BIT_XTIDE_REV2
-		dw		IdePioBlock_ReadFrom8bitDataPort	; 4, DEVICE_8BIT_XTCF_PIO8
-%endif
-
-%ifdef USE_AT
+%ifdef MODULE_8BIT_IDE
+		dw		IdePioBlock_ReadFrom8bitDataPort	; 2, DEVICE_8BIT_ATA
+		dw		IdePioBlock_ReadFromXtideRev1		; 3, DEVICE_8BIT_XTIDE_REV1		
+		dw		IdePioBlock_ReadFromXtideRev2		; 4, DEVICE_8BIT_XTIDE_REV2
+		dw		IdePioBlock_ReadFrom8bitDataPort	; 5, DEVICE_8BIT_XTCF_PIO8
+		dw		IdeDmaBlock_ReadFromXTCF			; 6, DEVICE_8BIT_XTCF_DMA
+%endif
+
+
 g_rgfnPioWrite:
 		dw		IdePioBlock_WriteTo16bitDataPort	; 0, DEVICE_16BIT_ATA
 		dw		IdePioBlock_WriteTo32bitDataPort	; 1, DEVICE_32BIT_ATA
-%endif
-%ifdef MODULE_8BIT_IDE
-		dw		IdePioBlock_WriteToXtideRev1		; 2, DEVICE_8BIT_XTIDE_REV1
-		dw		IdePioBlock_WriteToXtideRev2		; 3, DEVICE_8BIT_XTIDE_REV2
-		dw		IdePioBlock_WriteTo8bitDataPort		; 4, DEVICE_8BIT_XTCF_PIO8
-%endif
+%ifdef MODULE_8BIT_IDE
+		dw		IdePioBlock_WriteTo8bitDataPort		; 2, DEVICE_8BIT_ATA
+		dw		IdePioBlock_WriteToXtideRev1		; 3, DEVICE_8BIT_XTIDE_REV1
+		dw		IdePioBlock_WriteToXtideRev2		; 4, DEVICE_8BIT_XTIDE_REV2
+		dw		IdePioBlock_WriteTo8bitDataPort		; 5, DEVICE_8BIT_XTCF_PIO8
+		dw		IdeDmaBlock_WriteToXTCF				; 6, DEVICE_8BIT_XTCF_DMA
+%endif
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/JrIdeTransfer.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/JrIdeTransfer.asm	(revision 479)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/JrIdeTransfer.asm	(revision 480)
@@ -39,5 +39,5 @@
 ;		AL:		IDE command that was used to start the transfer
 ;				(all PIO read and write commands including Identify Device)
-;		ES:SI:	Ptr to normalized data buffer
+;		ES:SI:	Ptr to data buffer
 ;		DS:DI:	Ptr to DPT (in RAMVARS segment)
 ;		SS:BP:	Ptr to IDEPACK
@@ -61,4 +61,7 @@
 	mov		[bp+MEMPIOVARS.fpDPT], di
 	mov		[bp+MEMPIOVARS.fpDPT+2], ds
+
+	; Normalize pointer
+	call	IdeTransfer_NormalizePointerInESSI
 
 	; Get far pointer to Sector Access Window
Index: trunk/XTIDE_Universal_BIOS/Src/Device/Idepack.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/Idepack.asm	(revision 479)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/Idepack.asm	(revision 480)
@@ -74,23 +74,6 @@
 	mov		[bp+IDEPACK.bDrvAndHead], al
 
-	; Normalize data buffer pointer to ES:SI
-%ifdef MODULE_8BIT_IDE
-	cmp		BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_XTCF_DMA
-	jne		SHORT .NormalizeForSmallestPossibleOffset
-
-	; DMA transfers do not need to normalize pointer
-	; (it will be converted to physical address in IdeDmaTransfer.asm)
+	; Load data buffer pointer to ES:SI
 	les		si, [es:si+DAP.dwMemoryAddress]
-	jmp		SHORT GetDeviceControlByteToIdepackAndStartTransfer
-%endif ; MODULE_8BIT_IDE
-
-.NormalizeForSmallestPossibleOffset:
-	mov		ax, [es:si+DAP.wOffset]
-	mov		cx, ax
-	eSHR_IM	ax, 4								; Divide offset by 16
-	add		ax, [es:si+DAP.wSegment]			; Add segment
-	mov		es, ax								; Segment normalized
-	mov		si, cx
-	and		si, BYTE 0Fh						; Offset normalized
 	jmp		SHORT GetDeviceControlByteToIdepackAndStartTransfer
 %endif ; MODULE_EBIOS
Index: trunk/XTIDE_Universal_BIOS/Src/Device/Serial/SerialCommand.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/Serial/SerialCommand.asm	(revision 479)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/Serial/SerialCommand.asm	(revision 480)
@@ -61,4 +61,5 @@
 
 .readOrWrite:
+		call	IdeTransfer_NormalizePointerInESSI
 		mov		[bp+IDEPACK.bFeatures],ah		; store protocol command
 				
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm	(revision 479)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm	(revision 480)
@@ -108,13 +108,16 @@
 ;;; Set XT-CF mode
 %ifdef MODULE_8BIT_IDE
-	call	AccessDPT_IsThisDeviceXTCF
-	jne		SHORT .DoNotSetXTCFmode
-
 	call	AccessDPT_GetIdevarsToCSBX
 	mov		al, [cs:bx+IDEVARS.bXTCFcontrolRegister]
-	call	AH1Eh_ChangeXTCFmodeBasedOnControlRegisterInAL
+	call	AH9h_SetModeFromALtoXTCF
 	STORE_ERROR_FLAG_TO_DPT		FLG_INITERROR_FAILED_TO_SET_XTCF_MODE
 .DoNotSetXTCFmode:
-%endif
+
+
+;;; Set 8-bit PIO mode
+	call	AH9h_Enable8bitModeForDevice8bitAta
+	STORE_ERROR_FLAG_TO_DPT		FLG_INITERROR_FAILED_TO_SET_8BIT_MODE
+.DoNotSet8bitMode:
+%endif ; MODULE_8BIT_IDE
 
 
@@ -261,2 +264,41 @@
 .NoErrorFlagToSet:
 	ret
+
+
+%ifdef MODULE_8BIT_IDE
+;--------------------------------------------------------------------
+; AH9h_SetModeFromALtoXTCF
+;	Parameters:
+;		AL:		XT-CF Mode to set
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;		SS:BP:	Ptr to IDEPACK
+;	Returns:
+;		AH:		Int 13h return status
+;		CF:		Clear if successful or device is not XT-CF
+;				Set if failed to set mode for XT-CF
+;	Corrupts registers:
+;		AL, BX, CX, DX, SI
+;--------------------------------------------------------------------
+AH9h_SetModeFromALtoXTCF:
+	call	AccessDPT_IsThisDeviceXTCF
+	jne		SHORT IgnoreInvalidCommandError
+	jmp		AH1Eh_ChangeXTCFmodeBasedOnControlRegisterInAL
+
+
+;--------------------------------------------------------------------
+; AH9h_Enable8bitModeForDevice8bitAta
+;	Parameters:
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;		SS:BP:	Ptr to IDEPACK
+;	Returns:
+;		AH:		Int 13h return status
+;		CF:		Clear if successful or device is not DEVICE_8BIT_ATA
+;				Set if failed to set 8-bit mode for DEVICE_8BIT_ATA
+;	Corrupts registers:
+;		AL, BX, CX, DX, SI
+;--------------------------------------------------------------------
+AH9h_Enable8bitModeForDevice8bitAta:
+	cmp		BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_ATA
+	jne		SHORT IgnoreInvalidCommandError
+	jmp		AH23h_Enable8bitPioMode
+%endif ; MODULE_8BIT_IDE
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/Prepare.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/Prepare.asm	(revision 479)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Tools/Prepare.asm	(revision 480)
@@ -95,24 +95,6 @@
 Prepare_BufferToESSIforOldInt13hTransfer:
 	mov		si, [bp+IDEPACK.intpack+INTPACK.bx]	; Load offset
-
-%ifdef MODULE_8BIT_IDE
-	cmp		BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_XTCF_DMA
-	jne		SHORT .NormalizeForSmallestPossibleOffset
-
-	; DMA transfers do not need to normalize pointer
-	; (it will be converted to physical address in IdeDmaTransfer.asm)
-	mov		es, [bp+IDEPACK.intpack+INTPACK.es]
-	jmp		SHORT Prepare_ByValidatingSectorsInALforOldInt13h
-%endif ; MODULE_8BIT_IDE
-
-	; Normalize segment for 16b pages
-.NormalizeForSmallestPossibleOffset:
-	mov		bx, si
-	eSHR_IM	bx, 4								; Divide offset by 16
-	add		bx, [bp+IDEPACK.intpack+INTPACK.es]
-	mov		es, bx								; Segment normalized
-	and		si, BYTE 0Fh						; Offset normalized
+	mov		es, [bp+IDEPACK.intpack+INTPACK.es]	; Load segment
 	; Fall to Prepare_ByValidatingSectorsInALforOldInt13h
-
 
 ;---------------------------------------------------------------------
Index: trunk/XTIDE_Universal_BIOS/Src/Main.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Main.asm	(revision 479)
+++ trunk/XTIDE_Universal_BIOS/Src/Main.asm	(revision 480)
@@ -232,5 +232,5 @@
 %ifdef MODULE_8BIT_IDE
 	%include "JrIdeTransfer.asm"	; Must be included after IdeCommand.asm
-	%include "IdeDmaTransfer.asm"
+	%include "IdeDmaBlock.asm"
 %endif
 	%include "IdeTransfer.asm"
