Index: trunk/XTIDE_Universal_BIOS/Src/Device/Device.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/Device.asm	(revision 445)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/Device.asm	(revision 473)
@@ -82,4 +82,5 @@
 ;	Parameters:
 ;		BH:		Drive Select byte for Drive and Head Select Register
+;		DX:		Autodetected port (for devices that support autodetection)
 ;		DS:		Segment to RAMVARS
 ;		ES:SI:	Ptr to normalized buffer to receive 512-byte IDE Information
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm	(revision 445)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm	(revision 473)
@@ -56,4 +56,5 @@
 ;	Parameters:
 ;		BH:		Drive Select byte for Drive and Head Select Register
+;		DX:		Autodetected port for XT-CF
 ;		DS:		Segment to RAMVARS
 ;		ES:SI:	Ptr to buffer to receive 512-byte IDE Information
@@ -70,12 +71,12 @@
 	eMOVZX	ax, bh
 	mov		[di+DPT.wFlags], ax
-	mov		[di+DPT.bIdevarsOffset], bp
+	call	CreateDPT_StoreIdevarsOffsetAndBasePortFromCSBPtoDPTinDSDI
+	call	IdeDPT_StoreDeviceTypeToDPTinDSDIfromIdevarsInCSBP
 	mov		BYTE [di+DPT_ATA.bBlockSize], 1	; Block = 1 sector
-	call	IdeDPT_StoreDeviceTypeFromIdevarsInCSBPtoDPTinDSDI
 
 	; Wait until drive motors have reached full speed
-	cmp		bp, BYTE ROMVARS.ideVars0		; First controller?
+	cmp		bp, BYTE ROMVARS.ideVars0	; First controller?
 	jne		SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
-	test	bh, FLG_DRVNHEAD_DRV			; Wait already done for Master
+	test	bh, FLG_DRVNHEAD_DRV		; Wait already done for Master
 	jnz		SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
 	call	AHDh_WaitUntilDriveMotorHasReachedFullSpeed
@@ -87,10 +88,16 @@
 
 %ifdef MODULE_8BIT_IDE
-	; Enable 8-bit PIO mode for Lo-tech XT-CF
+	; 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
+
+	xor		al, al						; XTCF_8BIT_PIO_MODE
 	push	si
-	call	AH9h_Enable8bitPioModeForXTCF
+	call	AH1Eh_ChangeXTCFmodeBasedOnControlRegisterInAL
 	pop		si
 	jc		SHORT .FailedToSet8bitMode
-%endif
+.SkipXTCFmodeChange:
+%endif ; MODULE_8BIT_IDE
 
 	; Prepare to output Identify Device command
@@ -170,7 +177,8 @@
 	cmp		bl, FLG_STATUS_DRQ				; Data transfer started?
 	jne		SHORT .WaitUntilNonTransferCommandCompletes
-%ifdef MODULE_JRIDE
-	cmp		BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_JRIDE_ISA
-	je		SHORT JrIdeTransfer_StartWithCommandInAL
+%ifdef MODULE_8BIT_IDE
+	cmp		BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_XTCF_DMA
+	je		SHORT 0 ; IdeDma_StartTransferWithCommandInAL
+	ja		SHORT JrIdeTransfer_StartWithCommandInAL	; DEVICE_8BIT_XTCF_MEMMAP or DEVICE_8BIT_JRIDE_ISA
 %endif
 	jmp		IdeTransfer_StartWithCommandInAL
@@ -205,11 +213,12 @@
 	; We use different timeout value when detecting drives.
 	; This prevents unnecessary long delays when drive is not present.
-	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRDY, FLG_STATUS_DRDY)
+	mov		cx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRDY, FLG_STATUS_DRDY)
 	cmp		WORD [RAMVARS.wDrvDetectSignature], RAMVARS_DRV_DETECT_SIGNATURE
-	eCMOVE	bh, TIMEOUT_SELECT_DRIVE_DURING_DRIVE_DETECTION
+	eCMOVE	ch, TIMEOUT_SELECT_DRIVE_DURING_DRIVE_DETECTION
 
 	; Select Master or Slave Drive
 	mov		al, [bp+IDEPACK.bDrvAndHead]
 	OUTPUT_AL_TO_IDE_REGISTER	DRIVE_AND_HEAD_SELECT_REGISTER
+	mov		bx, cx
 	call	IdeWait_PollStatusFlagInBLwithTimeoutInBH
 
@@ -248,3 +257,4 @@
 
 	mov		al, ch
-	JUMP_TO_OUTPUT_AL_TO_IDE_REGISTER	LBA_HIGH_REGISTER
+	OUTPUT_AL_TO_IDE_REGISTER	LBA_HIGH_REGISTER
+	ret
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDPT.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDPT.asm	(revision 445)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDPT.asm	(revision 473)
@@ -64,5 +64,5 @@
 ;--------------------------------------------------------------------
 .StoreDeviceType:
-	call	IdeDPT_StoreDeviceTypeFromIdevarsInCSBPtoDPTinDSDI
+	call	IdeDPT_StoreDeviceTypeToDPTinDSDIfromIdevarsInCSBP
 
 
@@ -111,5 +111,5 @@
 ;--------------------------------------------------------------------
 .DetectAdvancedIdeController:
-	call	AccessDPT_GetIdeBasePortToBX
+	mov		bx, [di+DPT.wBasePort]
 	call	AdvAtaInit_DetectControllerForIdeBaseInBX
 	mov		[di+DPT_ADVANCED_ATA.wControllerID], ax	; Store zero if none detected
@@ -138,5 +138,5 @@
 
 ;--------------------------------------------------------------------
-; IdeDPT_StoreDeviceTypeFromIdevarsInCSBPtoDPTinDSDI
+; IdeDPT_StoreDeviceTypeToDPTinDSDIfromIdevarsInCSBP
 ;	Parameters:
 ;		DS:DI:	Ptr to Disk Parameter Table
@@ -147,5 +147,5 @@
 ;		AL
 ;--------------------------------------------------------------------
-IdeDPT_StoreDeviceTypeFromIdevarsInCSBPtoDPTinDSDI:
+IdeDPT_StoreDeviceTypeToDPTinDSDIfromIdevarsInCSBP:
 	mov		al, [cs:bp+IDEVARS.bDevice]
 	mov		[di+DPT_ATA.bDevice], al
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeIO.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeIO.asm	(revision 445)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeIO.asm	(revision 473)
@@ -1,4 +1,5 @@
 ; Project name	:	XTIDE Universal BIOS
-; Description	:	IDE Register I/O functions.
+; Description	:	IDE Register I/O functions when supporting 8-bit
+;					devices that need address translations.
 
 ;
@@ -22,4 +23,68 @@
 
 ;--------------------------------------------------------------------
+; IdeIO_InputStatusRegisterToAL
+;	Parameters:
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;	Returns:
+;		AL:		IDE Status Register contents
+;	Corrupts registers:
+;		BX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+IdeIO_InputStatusRegisterToAL:
+%ifndef MODULE_8BIT_IDE
+	INPUT_TO_AL_FROM_IDE_REGISTER STATUS_REGISTER_in
+	ret
+
+%else
+	mov		dl, STATUS_REGISTER_in
+	; Fall to IdeIO_InputToALfromIdeRegisterInDL
+
+;--------------------------------------------------------------------
+; IdeIO_InputToALfromIdeRegisterInDL
+;	Parameters:
+;		DL:		IDE Register
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;	Returns:
+;		AL:		Inputted byte
+;	Corrupts registers:
+;		BX, DX
+;--------------------------------------------------------------------
+IdeIO_InputToALfromIdeRegisterInDL:
+	xor		dh, dh	; IDE Register index now in DX
+
+	mov		al, [di+DPT_ATA.bDevice]
+	cmp		al, DEVICE_8BIT_XTIDE_REV2
+	je		SHORT .ReverseA0andA3fromRegisterIndexInDX
+	jb		SHORT .InputToALfromRegisterInDX	; Standard IDE controllers and XTIDE rev 1
+	cmp		al, DEVICE_8BIT_JRIDE_ISA
+	jne		SHORT .ShlRegisterIndexInDX			; All XT-CF modes
+	; Fall to .InputToALfromMemoryMappedRegisterInDX
+
+.InputToALfromMemoryMappedRegisterInDX:
+	mov		bx, JRIDE_COMMAND_BLOCK_REGISTER_WINDOW_OFFSET
+	add		bx, dx
+	push	ds
+	mov		ds, [di+DPT.wBasePort]	; Segment for JR-IDE/ISA
+	mov		al, [bx]
+	pop		ds
+	ret
+
+.ReverseA0andA3fromRegisterIndexInDX:
+	mov		bx, dx
+	mov		dl, [cs:bx+g_rgbSwapA0andA3fromIdeRegisterIndex]
+	SKIP2B	bx	; Skip shl dx, 1
+
+.ShlRegisterIndexInDX:
+	shl		dx, 1
+	; Fall to .InputToALfromRegisterInDX
+
+.InputToALfromRegisterInDX:
+	add		dx, [di+DPT.wBasePort]
+	in		al, dx
+	ret
+
+
+;--------------------------------------------------------------------
 ; IdeIO_OutputALtoIdeControlBlockRegisterInDL
 ;	Parameters:
@@ -33,18 +98,29 @@
 ;--------------------------------------------------------------------
 IdeIO_OutputALtoIdeControlBlockRegisterInDL:
-	%ifdef MODULE_8BIT_IDE
-		mov		dh, [di+DPT_ATA.bDevice]
-		%ifdef MODULE_JRIDE
-			test	dh, dh
-			jnz		SHORT .OutputToIoMappedIde
-		
-			add		dx, JRIDE_CONTROL_BLOCK_REGISTER_WINDOW_OFFSET
-			jmp		SHORT OutputToJrIdeRegister
-		.OutputToIoMappedIde:
-		%endif	; MODULE_JRIDE
-	%endif	; MODULE_8BIT_IDE
+	; Note! We do not need to reverse A0 and A3 for XTIDE rev 2 since
+	; the only Control Block Register we access is DEVICE_CONTROL_REGISTER_out
+	; at offset 6 (0110b).
+	xor		dh, dh	; IDE Register index now in DX
 
-	mov		bl, IDEVARS.wPortCtrl
-	jmp		SHORT OutputALtoIdeRegisterInDLwithIdevarsOffsetToBasePortInBL
+	mov		bl, [di+DPT_ATA.bDevice]
+	cmp		bl, DEVICE_8BIT_XTIDE_REV2
+	jbe		SHORT .OutputALtoControlBlockRegisterInDX	; Standard IDE controllers and XTIDE rev 1
+	cmp		bl, DEVICE_8BIT_JRIDE_ISA
+	jne		SHORT .ShlRegisterIndexInDX		; All XT-CF modes
+	; Fall to .OutputALtoMemoryMappedRegisterInDX
+
+.OutputALtoMemoryMappedRegisterInDX:
+	mov		bx, JRIDE_CONTROL_BLOCK_REGISTER_WINDOW_OFFSET
+	jmp 	SHORT IdeIO_OutputALtoIdeRegisterInDL.OutputALtoMemoryMappedRegisterInDXwithWindowOffsetInBX
+
+.ShlRegisterIndexInDX:
+	add		dl, OFFSET_TO_CONTROL_BLOCK_REGISTERS
+	shl		dx, 1
+	jmp		SHORT OutputALtoRegisterInDX
+
+.OutputALtoControlBlockRegisterInDX:
+	call	AccessDPT_GetIdevarsToCSBX
+	add		dx, [cs:bx+IDEVARS.wControlBlockPort]
+	jmp		SHORT OutputALtoPortInDX
 
 
@@ -62,123 +138,52 @@
 ALIGN JUMP_ALIGN
 IdeIO_OutputALtoIdeRegisterInDL:
-	%ifdef MODULE_8BIT_IDE
-		mov		dh, [di+DPT_ATA.bDevice]
-		%ifdef MODULE_JRIDE
-			test	dh, dh
-			jnz		SHORT OutputALtoIOmappedIdeRegisterInDL
-		
-		%if JRIDE_COMMAND_BLOCK_REGISTER_WINDOW_OFFSET & 0FFh = 0
-			mov		dh, JRIDE_COMMAND_BLOCK_REGISTER_WINDOW_OFFSET >> 8
-		%else
-			add		dx, JRIDE_COMMAND_BLOCK_REGISTER_WINDOW_OFFSET
-		%endif
-		OutputToJrIdeRegister:
-			mov		bx, dx
-			mov		[cs:bx], al
-			ret
-		ALIGN JUMP_ALIGN
-		OutputALtoIOmappedIdeRegisterInDL:
-		%endif	; MODULE_JRIDE
-	%endif	; MODULE_8BIT_IDE
+	xor		dh, dh	; IDE Register index now in DX
 
-	mov		bl, IDEVARS.wPort
-OutputALtoIdeRegisterInDLwithIdevarsOffsetToBasePortInBL:
-	call	GetIdePortToDX
+	mov		bl, [di+DPT_ATA.bDevice]
+	cmp		bl, DEVICE_8BIT_XTIDE_REV2
+	je		SHORT .ReverseA0andA3fromRegisterIndexInDX
+	jb		SHORT OutputALtoRegisterInDX	; Standard IDE controllers and XTIDE rev 1
+	cmp		bl, DEVICE_8BIT_JRIDE_ISA
+	jne		SHORT .ShlRegisterIndexInDX		; All XT-CF modes
+	; Fall to .OutputALtoMemoryMappedRegisterInDX
+
+.OutputALtoMemoryMappedRegisterInDX:
+	mov		bx, JRIDE_COMMAND_BLOCK_REGISTER_WINDOW_OFFSET
+.OutputALtoMemoryMappedRegisterInDXwithWindowOffsetInBX:
+	add		bx, dx
+	push	ds
+	mov		ds, [di+DPT.wBasePort]	; Segment for JR-IDE/ISA
+	mov		[bx], al
+	pop		ds
+	ret
+
+.ReverseA0andA3fromRegisterIndexInDX:
+	mov		bx, dx
+	mov		dl, [cs:bx+g_rgbSwapA0andA3fromIdeRegisterIndex]
+	SKIP2B	bx	; Skip shl dx, 1
+
+.ShlRegisterIndexInDX:
+	shl		dx, 1
+	; Fall to OutputALtoRegisterInDX
+
+ALIGN JUMP_ALIGN
+OutputALtoRegisterInDX:
+	add		dx, [di+DPT.wBasePort]
+OutputALtoPortInDX:
 	out		dx, al
 	ret
 
 
-;--------------------------------------------------------------------
-; IdeIO_InputStatusRegisterToAL
-;	Parameters:
-;		DS:DI:	Ptr to DPT (in RAMVARS segment)
-;	Returns:
-;		AL:		IDE Status Register contents
-;	Corrupts registers:
-;		BX, DX
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-IdeIO_InputStatusRegisterToAL:
-	mov		dl, STATUS_REGISTER_in
-	; Fall to IdeIO_InputToALfromIdeRegisterInDL
 
-;--------------------------------------------------------------------
-; IdeIO_InputToALfromIdeRegisterInDL
-;	Parameters:
-;		DL:		IDE Register
-;		DS:DI:	Ptr to DPT (in RAMVARS segment)
-;	Returns:
-;		AL:		Inputted byte
-;	Corrupts registers:
-;		BX, DX
-;--------------------------------------------------------------------
-IdeIO_InputToALfromIdeRegisterInDL:
-	%ifdef MODULE_8BIT_IDE
-		mov		dh, [di+DPT_ATA.bDevice]
-		%ifdef MODULE_JRIDE
-			test	dh, dh
-			jnz		SHORT .InputToALfromIOmappedIdeRegisterInDL
-		
-		%if JRIDE_COMMAND_BLOCK_REGISTER_WINDOW_OFFSET & 0FFh = 0
-			mov		dh, JRIDE_COMMAND_BLOCK_REGISTER_WINDOW_OFFSET >> 8
-		%else
-			add		dx, JRIDE_COMMAND_BLOCK_REGISTER_WINDOW_OFFSET
-		%endif
-			mov		bx, dx
-			mov		al, [cs:bx]
-			ret
-		.InputToALfromIOmappedIdeRegisterInDL:
-		%endif	; MODULE_JRIDE
-	%endif	; MODULE_8BIT_IDE
-	mov		bl, IDEVARS.wPort
-	call	GetIdePortToDX
-	in		al, dx
-	ret
+; A0 <-> A3 lookup table
+g_rgbSwapA0andA3fromIdeRegisterIndex:
+	db	0000b	; <-> 0000b, 0
+	db	1000b	; <-> 0001b, 1
+	db	0010b	; <-> 0010b, 2
+	db	1010b	; <-> 0011b, 3
+	db	0100b	; <-> 0100b, 4
+	db	1100b	; <-> 0101b, 5
+	db	0110b	; <-> 0110b, 6
+	db	1110b	; <-> 0111b, 7
 
-
-;--------------------------------------------------------------------
-; GetIdePortToDX
-;	Parameters:
-;		BL:		Offset to port in IDEVARS (IDEVARS.wPort or IDEVARS.wPortCtrl)
-;		DH:		Device Type (IDEVARS.bDevice)
-;		DL:		IDE Register
-;		DS:DI:	Ptr to DPT (in RAMVARS segment)
-;	Returns:
-;		DX:		Source/Destination Port
-;	Corrupts registers:
-;		BX
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-GetIdePortToDX:
-%ifdef MODULE_8BIT_IDE
-	; Point CS:BX to IDEVARS
-	xor		bh, bh
-	add		bl, [di+DPT.bIdevarsOffset]			; CS:BX now points port address
-
-	; Load port address and check if A0 and A3 address lines need to be reversed
-	cmp		dh, DEVICE_8BIT_XTIDE_REV1
-	mov		dh, bh								; DX now has IDE register offset
-	jae		SHORT .ReturnUntranslatedPortInDX	; No need to swap address lines
-
-	; Exchange address lines A0 and A3 from DL
-	add		dx, [cs:bx]							; DX now has port address
-	mov		bl, dl								; Port low byte to BL
-	and		bl, MASK_A3_AND_A0_ADDRESS_LINES	; Clear all bits except A0 and A3
-	jz		SHORT .ReturnTranslatedPortInDX		; A0 and A3 both zeroes, no change needed
-	cmp		bl, MASK_A3_AND_A0_ADDRESS_LINES
-	je		SHORT .ReturnTranslatedPortInDX		; A0 and A3 both ones, no change needed
-	xor		dl, MASK_A3_AND_A0_ADDRESS_LINES	; Invert A0 and A3
-.ReturnTranslatedPortInDX:
-	ret
-
-.ReturnUntranslatedPortInDX:
-	add		dx, [cs:bx]
-	ret
-
-%else	; Only standard IDE devices
-	xor		bh, bh
-	add		bl, [di+DPT.bIdevarsOffset]			; CS:BX now points port address
-	xor		dh, dh
-	add		dx, [cs:bx]							; DX now has port address
-	ret
-%endif
+%endif ; MODULE_8BIT_IDE
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdePioBlock.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdePioBlock.asm	(revision 473)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdePioBlock.asm	(revision 473)
@@ -0,0 +1,269 @@
+; Project name	:	XTIDE Universal BIOS
+; Description	:	IDE Read/Write functions for transferring
+;					block using PIO modes.
+;					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
+
+%ifdef MODULE_8BIT_IDE
+
+;--------------------------------------------------------------------
+; IdePioBlock_ReadFromXtideRev1
+;	Parameters:
+;		CX:		Block size in 512 byte sectors
+;		DX:		IDE Data port address
+;		ES:DI:	Normalized ptr to buffer to receive data
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+IdePioBlock_ReadFromXtideRev1:
+	UNROLL_SECTORS_IN_CX_TO_OWORDS
+	mov		bl, 8		; Bit mask for toggling data low/high reg
+ALIGN JUMP_ALIGN
+.InswLoop:
+	%rep 8 ; WORDs
+		XTIDE_INSW
+	%endrep
+	loop	.InswLoop
+	ret
+
+
+;--------------------------------------------------------------------
+; IdePioBlock_ReadFromXtideRev2		or rev 1 with swapped A0 and A3 (chuck-mod)
+;	Parameters:
+;		CX:		Block size in 512 byte sectors
+;		DX:		IDE Data port address
+;		ES:DI:	Normalized ptr to buffer to receive data
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX
+;--------------------------------------------------------------------
+%ifndef USE_186			; 8086/8088 compatible WORD read
+
+ALIGN JUMP_ALIGN
+IdePioBlock_ReadFromXtideRev2:
+	UNROLL_SECTORS_IN_CX_TO_OWORDS
+ALIGN JUMP_ALIGN
+.ReadNextOword:
+	%rep 8	; WORDs
+		in		ax, dx		; Read WORD
+		stosw				; Store WORD to [ES:DI]
+	%endrep
+		loop	.ReadNextOword
+		ret
+
+%endif
+
+
+;--------------------------------------------------------------------
+; IdePioBlock_ReadFrom8bitDataPort		CF-XT when using 8-bit PIO
+;	Parameters:
+;		CX:		Block size in 512 byte sectors
+;		DX:		IDE Data port address
+;		ES:DI:	Normalized ptr to buffer to receive data
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+IdePioBlock_ReadFrom8bitDataPort:
+%ifdef USE_186
+	shl		cx, 9		; Sectors to BYTEs
+	rep insb
+	ret
+
+%else ; If 8088/8086
+	UNROLL_SECTORS_IN_CX_TO_OWORDS
+ALIGN JUMP_ALIGN
+.ReadNextOword:
+	%rep 16	; BYTEs
+		in		al, dx		; Read BYTE
+		stosb				; Store BYTE to [ES:DI]
+	%endrep
+	loop	.ReadNextOword
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; IdePioBlock_WriteToXtideRev1
+;	Parameters:
+;		CX:		Block size in 512-byte sectors
+;		DX:		IDE Data port address
+;		ES:SI:	Normalized ptr to buffer containing data
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+IdePioBlock_WriteToXtideRev1:
+	push	ds
+	UNROLL_SECTORS_IN_CX_TO_QWORDS
+	mov		bl, 8		; Bit mask for toggling data low/high reg
+	push	es			; Copy ES...
+	pop		ds			; ...to DS
+ALIGN JUMP_ALIGN
+.OutswLoop:
+	%rep 4	; WORDs
+		XTIDE_OUTSW
+	%endrep
+	loop	.OutswLoop
+	pop		ds
+	ret
+
+
+;--------------------------------------------------------------------
+; IdePioBlock_WriteToXtideRev2	or rev 1 with swapped A0 and A3 (chuck-mod)
+;	Parameters:
+;		CX:		Block size in 512-byte sectors
+;		DX:		IDE Data port address
+;		ES:SI:	Normalized ptr to buffer containing data
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+IdePioBlock_WriteToXtideRev2:
+	UNROLL_SECTORS_IN_CX_TO_QWORDS
+	push	ds
+	push	es			; Copy ES...
+	pop		ds			; ...to DS
+ALIGN JUMP_ALIGN
+.WriteNextQword:
+	%rep 4	; WORDs
+		XTIDE_MOD_OUTSW
+	%endrep
+	loop	.WriteNextQword
+	pop		ds
+	ret
+
+
+;--------------------------------------------------------------------
+; IdePioBlock_WriteTo8bitDataPort		XT-CF when using 8-bit PIO
+;	Parameters:
+;		CX:		Block size in 512-byte sectors
+;		DX:		IDE Data port address
+;		ES:SI:	Normalized ptr to buffer containing data
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+IdePioBlock_WriteTo8bitDataPort:
+
+%ifdef USE_186
+	shl		cx, 9		; Sectors to BYTEs
+	es					; Source is ES segment
+	rep outsb
+	ret
+
+%else ; If 8088/8086
+	UNROLL_SECTORS_IN_CX_TO_DWORDS
+	push	ds
+	push	es
+	pop		ds
+ALIGN JUMP_ALIGN
+.WriteNextDword:
+	%rep 4	; BYTEs
+		lodsb				; Load BYTE from [DS:SI]
+		out		dx, al		; Write BYTE
+	%endrep
+	loop	.WriteNextDword
+	pop		ds
+	ret
+%endif
+
+%endif ; MODULE_8BIT_IDE
+
+
+;--------------------------------------------------------------------
+; IdePioBlock_ReadFromXtideRev2			(when 80186/80188 instructions are available)
+; IdePioBlock_ReadFrom16bitDataPort		Normal 16-bit IDE
+; IdePioBlock_ReadFrom32bitDataPort		VLB/PCI 32-bit IDE
+;	Parameters:
+;		CX:		Block size in 512 byte sectors
+;		DX:		IDE Data port address
+;		ES:DI:	Normalized ptr to buffer to receive data
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX
+;--------------------------------------------------------------------
+%ifdef USE_186	; Also used by XTIDE rev 2 when 80186/80188 commands allowed
+ALIGN JUMP_ALIGN
+IdePioBlock_ReadFromXtideRev2:
+IdePioBlock_ReadFrom16bitDataPort:
+	xchg	cl, ch		; Sectors to WORDs
+	rep insw
+	ret
+%endif
+
+;--------------------------------------------------------------------
+%ifdef USE_AT
+ALIGN JUMP_ALIGN
+IdePioBlock_ReadFrom32bitDataPort:
+	shl		cx, 7		; Sectors to DWORDs
+	rep
+	db		66h			; Override operand size to 32-bit
+	db		6Dh			; INSW/INSD
+	ret
+%endif
+
+
+;--------------------------------------------------------------------
+; IdePioBlock_WriteTo16bitDataPort		Normal 16-bit IDE
+; IdePioBlock_WriteTo32bitDataPort		VLB/PCI 32-bit IDE
+;	Parameters:
+;		CX:		Block size in 512-byte sectors
+;		DX:		IDE Data port address
+;		ES:SI:	Normalized ptr to buffer containing data
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		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
+	ret
+
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+IdePioBlock_WriteTo32bitDataPort:
+	shl		cx, 7		; Sectors to DWORDs
+	es					; Source is ES segment
+	rep
+	db		66h			; Override operand size to 32-bit
+	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 445)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm	(revision 473)
@@ -206,6 +206,8 @@
 ALIGN JUMP_ALIGN
 InitializePiovarsInSSBPwithSectorCountInAH:
-	; Store sizes
+	; Store sizes and Data Port
 	mov		[bp+PIOVARS.bSectorsLeft], ah
+	mov		ax, [di+DPT.wBasePort]
+	mov		[bp+PIOVARS.wDataPort], ax
 	eMOVZX	ax, [di+DPT_ATA.bBlockSize]
 	mov		[bp+PIOVARS.wSectorsInBlock], ax
@@ -214,10 +216,6 @@
 	; Get transfer function based on bus type
 	xchg	ax, bx								; Lookup table offset to AX
-	mov		bl, [di+DPT.bIdevarsOffset]			; CS:BX now points to IDEVARS
-	mov		dx, [cs:bx+IDEVARS.wPort]			; Load IDE Data port address
 	mov		bl, [di+DPT_ATA.bDevice]
 	add		bx, ax
-
-	mov		[bp+PIOVARS.wDataPort], dx
 	mov		ax, [cs:bx]							; Load offset to transfer function
 	mov		[bp+PIOVARS.fnXfer], ax
@@ -225,225 +223,31 @@
 
 
-;--------------------------------------------------------------------
-; ReadBlockFromXtideRev1		XTIDE rev 1
-; ReadBlockFromXtideRev2		XTIDE rev 2 or rev 1 with swapped A0 and A3 (chuck-mod)
-; ReadBlockFrom8bitDataPort		CF-XT when using 8-bit PIO
-; ReadBlockFrom16bitDataPort	Normal 16-bit IDE
-; ReadBlockFrom32bitDataPort	VLB/PCI 32-bit IDE
-;	Parameters:
-;		CX:		Block size in 512 byte sectors
-;		DX:		IDE Data port address
-;		ES:DI:	Normalized ptr to buffer to receive data
-;	Returns:
-;		Nothing
-;	Corrupts registers:
-;		AX, BX, CX
-;--------------------------------------------------------------------
-%ifdef MODULE_8BIT_IDE
-
-	ALIGN JUMP_ALIGN
-	ReadBlockFromXtideRev1:
-		UNROLL_SECTORS_IN_CX_TO_OWORDS
-		mov		bl, 8		; Bit mask for toggling data low/high reg
-	ALIGN JUMP_ALIGN
-	.InswLoop:
-	%rep 8	; WORDs
-		XTIDE_INSW
-	%endrep
-		loop	.InswLoop
-		ret
-
-	;--------------------------------------------------------------------
-	%ifndef USE_186			; 8086/8088 compatible WORD read
-		ALIGN JUMP_ALIGN
-		ReadBlockFromXtideRev2:
-			UNROLL_SECTORS_IN_CX_TO_OWORDS
-		ALIGN JUMP_ALIGN
-		.ReadNextOword:
-		%rep 8	; WORDs
-			in		ax, dx		; Read WORD
-			stosw				; Store WORD to [ES:DI]
-		%endrep
-			loop	.ReadNextOword
-			ret
-	%endif
-
-	;--------------------------------------------------------------------
-	%ifdef USE_186
-		ALIGN JUMP_ALIGN
-		ReadBlockFrom8bitDataPort:
-			shl		cx, 9		; Sectors to BYTEs
-			rep insb
-			ret
-
-	%else ; If 8088/8086
-		ALIGN JUMP_ALIGN
-		ReadBlockFrom8bitDataPort:
-			UNROLL_SECTORS_IN_CX_TO_OWORDS
-		ALIGN JUMP_ALIGN
-		.ReadNextOword:
-		%rep 16	; BYTEs
-			in		al, dx		; Read BYTE
-			stosb				; Store BYTE to [ES:DI]
-		%endrep
-			loop	.ReadNextOword
-			ret
-	%endif
-%endif	; MODULE_8BIT_IDE
-
-;--------------------------------------------------------------------
-%ifdef USE_186
-	ALIGN JUMP_ALIGN
-	ReadBlockFrom16bitDataPort:
-		xchg	cl, ch		; Sectors to WORDs
-		rep insw
-		ret
-%endif
-
-;--------------------------------------------------------------------
-%ifdef USE_AT
-	ALIGN JUMP_ALIGN
-	ReadBlockFrom32bitDataPort:
-		shl		cx, 7		; Sectors to DWORDs
-		rep
-		db		66h			; Override operand size to 32-bit
-		db		6Dh			; INSW/INSD
-		ret
-%endif
-
-
-;--------------------------------------------------------------------
-; WriteBlockToXtideRev1			XTIDE rev 1
-; WriteBlockToXtideRev2			XTIDE rev 2 or rev 1 with swapped A0 and A3 (chuck-mod)
-; WriteBlockTo8bitDataPort		XT-CF when using 8-bit PIO
-; WriteBlockTo16bitDataPort		Normal 16-bit IDE
-; WriteBlockTo32bitDataPort		VLB/PCI 32-bit IDE
-;	Parameters:
-;		CX:		Block size in 512-byte sectors
-;		DX:		IDE Data port address
-;		ES:SI:	Normalized ptr to buffer containing data
-;	Returns:
-;		Nothing
-;	Corrupts registers:
-;		AX, BX, CX, DX
-;--------------------------------------------------------------------
-%ifdef MODULE_8BIT_IDE
-
-	ALIGN JUMP_ALIGN
-	WriteBlockToXtideRev1:
-		push	ds
-		UNROLL_SECTORS_IN_CX_TO_QWORDS
-		mov		bl, 8		; Bit mask for toggling data low/high reg
-		push	es			; Copy ES...
-		pop		ds			; ...to DS
-	ALIGN JUMP_ALIGN
-	.OutswLoop:
-	%rep 4	; WORDs
-		XTIDE_OUTSW
-	%endrep
-		loop	.OutswLoop
-		pop		ds
-		ret
-
-	;--------------------------------------------------------------------
-	ALIGN JUMP_ALIGN
-	WriteBlockToXtideRev2:
-		UNROLL_SECTORS_IN_CX_TO_QWORDS
-		push	ds
-		push	es			; Copy ES...
-		pop		ds			; ...to DS
-	ALIGN JUMP_ALIGN
-	.WriteNextQword:
-	%rep 4	; WORDs
-		XTIDE_MOD_OUTSW
-	%endrep
-		loop	.WriteNextQword
-		pop		ds
-		ret
-
-	;--------------------------------------------------------------------
-	%ifdef USE_186
-		ALIGN JUMP_ALIGN
-		WriteBlockTo8bitDataPort:
-			shl		cx, 9		; Sectors to BYTEs
-			es					; Source is ES segment
-			rep outsb
-			ret
-
-	%else ; If 8088/8086
-		ALIGN JUMP_ALIGN
-		WriteBlockTo8bitDataPort:
-			UNROLL_SECTORS_IN_CX_TO_DWORDS
-			push	ds
-			push	es
-			pop		ds
-		ALIGN JUMP_ALIGN
-		.WriteNextDword:
-		%rep 4	; BYTEs
-			lodsb				; Load BYTE from [DS:SI]
-			out		dx, al		; Write BYTE
-		%endrep
-			loop	.WriteNextDword
-			pop		ds
-			ret
-	%endif
-%endif	; MODULE_8BIT_IDE
-
-;--------------------------------------------------------------------
-%ifdef USE_AT
-ALIGN JUMP_ALIGN
-WriteBlockTo16bitDataPort:
-	xchg	cl, ch		; Sectors to WORDs
-	es					; Source is ES segment
-	rep outsw
-	ret
-
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-WriteBlockTo32bitDataPort:
-	shl		cx, 7		; Sectors to DWORDs
-	es					; Source is ES segment
-	rep
-	db		66h			; Override operand size to 32-bit
-	db		6Fh			; OUTSW/OUTSD
-	ret
-%endif ; USE_AT
-
-
 
 ; Lookup tables to get transfer function based on bus type
 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		0							; 0, DEVICE_8BIT_JRIDE_ISA
-		dw		ReadBlockFrom8bitDataPort	; 1, DEVICE_8BIT_XTCF
-	%ifdef USE_186
-		dw		ReadBlockFrom16bitDataPort	; 2, DEVICE_8BIT_XTIDE_REV2
-	%else
-		dw		ReadBlockFromXtideRev2		; 2, DEVICE_8BIT_XTIDE_REV2
+		dw		IdePioBlock_ReadFromXtideRev1		; 2, DEVICE_8BIT_XTIDE_REV1
+	%ifndef USE_AT
+		g_rgfnPioWrite:
 	%endif
-		dw		ReadBlockFromXtideRev1		; 3, DEVICE_XTIDE_REV1
-
-%else
-		times	COUNT_OF_8BIT_IDE_DEVICES	dw	0
-%endif
+		dw		IdePioBlock_ReadFromXtideRev2		; 3, DEVICE_8BIT_XTIDE_REV2
+		dw		IdePioBlock_ReadFrom8bitDataPort	; 4, DEVICE_8BIT_XTCF_PIO8
+%endif
+
 %ifdef USE_AT
-		dw		ReadBlockFrom16bitDataPort	; 4, DEVICE_16BIT_ATA
-		dw		ReadBlockFrom32bitDataPort	; 5, DEVICE_32BIT_ATA
-%endif
-
-
 g_rgfnPioWrite:
+		dw		IdePioBlock_WriteTo16bitDataPort	; 0, DEVICE_16BIT_ATA
+		dw		IdePioBlock_WriteTo32bitDataPort	; 1, DEVICE_32BIT_ATA
+%endif
 %ifdef MODULE_8BIT_IDE
-		dw		0							; 0, DEVICE_8BIT_JRIDE_ISA
-		dw		WriteBlockTo8bitDataPort	; 1, DEVICE_8BIT_XTCF
-		dw		WriteBlockToXtideRev2		; 2, DEVICE_XTIDE_REV2
-		dw		WriteBlockToXtideRev1		; 3, DEVICE_XTIDE_REV1
-
-%else
-		times	COUNT_OF_8BIT_IDE_DEVICES	dw	0
-%endif
-%ifdef USE_AT
-		dw		WriteBlockTo16bitDataPort	; 4, DEVICE_16BIT_ATA
-		dw		WriteBlockTo32bitDataPort	; 5, DEVICE_32BIT_ATA
-%endif
+		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
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/JrIdeTransfer.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/JrIdeTransfer.asm	(revision 445)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/JrIdeTransfer.asm	(revision 473)
@@ -28,4 +28,6 @@
 endstruc
 
+SECTOR_ACCESS_WINDOW_SIZE	EQU		512	; 512 bytes
+
 
 ; Section containing code
@@ -37,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 normalized data buffer (SI 0...15)
 ;		DS:DI:	Ptr to DPT (in RAMVARS segment)
 ;		SS:BP:	Ptr to IDEPACK
@@ -49,20 +51,37 @@
 ALIGN JUMP_ALIGN
 JrIdeTransfer_StartWithCommandInAL:
-	push	cs	; We push CS here (segment of SAW) and later pop it to DS (reads) or ES (writes)
-
-	; Initialize PIOVARS
-	xor		cx, cx
-	mov		[bp+MEMPIOVARS.bSectorsDone], cl
-	mov		cl, [bp+IDEPACK.bSectorCount]
-	mov		[bp+MEMPIOVARS.bSectorsLeft], cl
-	mov		cl, [di+DPT_ATA.bBlockSize]
-	mov		[bp+MEMPIOVARS.wSectorsInBlock], cx
+	; Initialize MEMPIOVARS
+	xchg	cx, ax			; IDE command to CL
+	xor		ax, ax
+	mov		[bp+MEMPIOVARS.bSectorsDone], al
+	mov		al, [bp+IDEPACK.bSectorCount]
+	mov		[bp+MEMPIOVARS.bSectorsLeft], al
+	mov		al, [di+DPT_ATA.bBlockSize]
+	mov		[bp+MEMPIOVARS.wSectorsInBlock], ax
 	mov		[bp+MEMPIOVARS.fpDPT], di
 	mov		[bp+MEMPIOVARS.fpDPT+2], ds
 
+	; Get far pointer to Sector Access Window
+	mov		dx, [di+DPT.wBasePort]
+	cmp		BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_JRIDE_ISA
+	jne		SHORT .GetSectorAccessWindowForXTCF
+
+	; Get Sector Access Window for JR-IDE/ISA
+	mov		di, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET
+	mov		ds, dx		; Segment for JR-IDE/ISA
+	jmp		SHORT .SectorAccessWindowLoadedToDSDI
+
+.GetSectorAccessWindowForXTCF:
+	xor		di, di
+	add		dl, XTCF_CONTROL_REGISTER
+	in		al, dx					; Read high byte for Sector Access Window segment
+	xchg	ah, al
+	mov		ds, ax
+
 	; Are we reading or writing?
-	test	al, 16	; Bit 4 is cleared on all the read commands but set on 3 of the 4 write commands
+.SectorAccessWindowLoadedToDSDI:
+	test	cl, 16	; Bit 4 is cleared on all the read commands but set on 3 of the 4 write commands
 	jnz		SHORT WriteToSectorAccessWindow
-	cmp		al, COMMAND_WRITE_MULTIPLE
+	cmp		cl, COMMAND_WRITE_MULTIPLE
 	je		SHORT WriteToSectorAccessWindow
 	; Fall to ReadFromSectorAccessWindow
@@ -71,5 +90,5 @@
 ; ReadFromSectorAccessWindow
 ;	Parameters:
-;		Stack:	Segment part of ptr to Sector Access Window
+;		DS:DI:	Ptr to Sector Access Window
 ;		ES:SI:	Normalized ptr to buffer to receive data
 ;		SS:BP:	Ptr to MEMPIOVARS
@@ -84,8 +103,5 @@
 ;--------------------------------------------------------------------
 ReadFromSectorAccessWindow:
-	pop		ds		; CS -> DS
-	mov		di, si	; ES:DI = destination
-	mov		si, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET	; DS:SI = source
-
+	xchg	si, di	; DS:SI = source, ES:DI = Destination
 	call	WaitUntilReadyToTransferNextBlock
 	jc		SHORT ReturnWithMemoryIOtransferErrorInAH
@@ -140,5 +156,5 @@
 ; WriteToSectorAccessWindow
 ;	Parameters:
-;		Stack:	Segment part of ptr to Sector Access Window
+;		DS:DI:	Ptr to Sector Access Window
 ;		ES:SI:	Normalized ptr to buffer containing data
 ;		SS:BP:	Ptr to MEMPIOVARS
@@ -155,7 +171,7 @@
 WriteToSectorAccessWindow:
 	push	es
-	pop		ds
-	pop		es	; CS -> ES
-	mov		di, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET
+	push	ds
+	pop		es		; ES:DI = Sector Access Window (destination)
+	pop		ds		; DS:SI = Ptr to source buffer
 
 	; Always poll when writing first block (IRQs are generated for following blocks)
@@ -205,5 +221,5 @@
 ALIGN JUMP_ALIGN
 .WriteBlock:
-	mov		ch, JRIDE_SECTOR_ACCESS_WINDOW_SIZE >> 9
+	mov		ch, SECTOR_ACCESS_WINDOW_SIZE >> 9
 	rep movsw
 	mov		di, bx	; Reset for next sector
@@ -232,5 +248,5 @@
 ALIGN JUMP_ALIGN
 .ReadBlock:
-	mov		ch, JRIDE_SECTOR_ACCESS_WINDOW_SIZE >> 9
+	mov		ch, SECTOR_ACCESS_WINDOW_SIZE >> 9
 	rep movsw
 	mov		si, bx	; Reset for next sector
@@ -261,5 +277,5 @@
 
 
-%if JRIDE_SECTOR_ACCESS_WINDOW_SIZE <> 512
-	%error "JRIDE_SECTOR_ACCESS_WINDOW_SIZE is no longer equal to 512. JrIdeTransfer.asm needs changes."
+%if SECTOR_ACCESS_WINDOW_SIZE <> 512
+	%error "SECTOR_ACCESS_WINDOW_SIZE is no longer equal to 512. JrIdeTransfer.asm needs changes."
 %endif
