Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm	(revision 544)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm	(revision 545)
@@ -80,5 +80,5 @@
 	test	bh, FLG_DRVNHEAD_DRV		; Wait already done for Master
 	jnz		SHORT .SkipLongWaitSinceDriveIsNotPrimaryMaster
-	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MOTOR_STARTUP, FLG_STATUS_DRDY)
+	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_MOTOR_STARTUP, FLG_STATUS_BSY)
 	call	IdeWait_PollStatusFlagInBLwithTimeoutInBH
 .SkipLongWaitSinceDriveIsNotPrimaryMaster:
@@ -88,12 +88,14 @@
 	call	Idepack_FakeToSSBP
 
-%ifdef MODULE_8BIT_IDE_ADVANCED
+%ifdef MODULE_8BIT_IDE
 	; Enable 8-bit PIO mode for 8-bit ATA and XT-CF
 	push	si
 	call	AH9h_Enable8bitModeForDevice8bitAta
-	xor		al, al						; XTCF_8BIT_PIO_MODE
+%ifdef MODULE_8BIT_IDE_ADVANCED
+	mov		al, XTCF_8BIT_PIO_MODE		; initialise with most basic transfer mode
 	call	AH9h_SetModeFromALtoXTCF
+%endif ; MODULE_8BIT_IDE_ADVANCED
 	pop		si
-%endif ; MODULE_8BIT_IDE_ADVANCED
+%endif ; MODULE_8BIT_IDE
 
 	; Prepare to output Identify Device command
@@ -173,6 +175,6 @@
 	jne		SHORT .WaitUntilNonTransferCommandCompletes
 %ifdef MODULE_8BIT_IDE_ADVANCED
-	cmp		BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_XTCF_MEMMAP
-	jae		SHORT JrIdeTransfer_StartWithCommandInAL	; DEVICE_8BIT_XTCF_MEMMAP, DEVICE_8BIT_JRIDE_ISA or DEVICE_8BIT_ADP50L
+	cmp		BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_JRIDE_ISA
+	jae		SHORT JrIdeTransfer_StartWithCommandInAL	; DEVICE_8BIT_JRIDE_ISA or DEVICE_8BIT_ADP50L
 %endif
 	jmp		IdeTransfer_StartWithCommandInAL
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDmaBlock.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDmaBlock.asm	(revision 544)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDmaBlock.asm	(revision 545)
@@ -78,5 +78,5 @@
 	; so we never need to separate transfer to more than 2 separate DMA operations.
 
-	; Load XT-CF Control Register port to DX
+	; Load XT-CFv3 Control Register port to DX
 	add		dl, XTCF_CONTROL_REGISTER
 
@@ -90,11 +90,11 @@
 	shl		cx, 1
 %endif
-	cmp		cx, ax
-	jbe		SHORT .TransferLastDmaPageWithSizeInCX
+	cmp		cx, ax									; if we won't cross a physical page boundary...
+	jbe		SHORT .TransferLastDmaPageWithSizeInCX	; ...perform the transfer in one operation
 
-	; Push size for second DMA page
+	; Calculate how much we can transfer on first and second rounds
 	xchg	cx, ax									; CX = BYTEs for first page
 	sub		ax, cx									; AX = BYTEs for second page
-	push	ax
+	push	ax										; Save bytes for second transfer on stack
 
 	; Transfer first DMA page
@@ -108,10 +108,13 @@
 ;--------------------------------------------------------------------
 ; StartDMAtransferForXTCFwithDmaModeInBL
+; Updated for XT-CFv3, 11-Apr-13
 ;	Parameters:
 ;		BL:		Byte for DMA Mode Register
-;		CX:		Number of BYTEs to transfer (1...32768 since max block size is limited to 64)
-;		DX:		XTCF Control Register
+;		CX:		Number of BYTEs to transfer (512...32768 since max block size is limited to 64)
+;		DX:		XT-CFv3 Control Register
+;		ES:		Bits 3..0 have physical address bits 19..16
+;		DI:		Physical address bits 15..0
 ;	Returns:
-;		Nothing
+;		ES:DI updated (CX is added)
 ;	Corrupts registers:
 ;		AX
@@ -122,6 +125,6 @@
 	; 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
+	cli									; Disable interrupts - programming must be atomic
+	out		MASK_REGISTER_DMA8_out, al	; Disable DMA Channel 3
 
 	; Set DMA Mode (read or write using channel 3)
@@ -129,9 +132,9 @@
 	out		MODE_REGISTER_DMA8_out, al
 
-	; Set address to DMA controller
-	out		CLEAR_FLIPFLOP_DMA8_out, al		; Reset flip-flop to low byte
+	; Send start address to DMA controller
 	mov		ax, es
 	out		PAGE_DMA8_CH_3, al
 	mov		ax, di
+	out		CLEAR_FLIPFLOP_DMA8_out, al							; Reset flip-flop to low byte
 	out		BASE_AND_CURRENT_ADDRESS_REGISTER_DMA8_CH3_out, al	; Low byte
 	mov		al, ah
@@ -140,5 +143,5 @@
 	; 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
+	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
@@ -147,52 +150,46 @@
 	; Enable DMA Channel 3
 	mov		al, CLEAR_CH3_MASK_BIT
-	out		MASK_REGISTER_DMA8_out, al		; Enable DMA Channel 3
-	sti										; Enable interrupts
+	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 by writing (anything)
+	; to the XT-CFv3 Control Register, which raises DRQ thereby passing system control to the 8237 DMA controller.
+	; The XT-CFv3 logic releases DRQ after 16 transfers, thereby handing control back to the CPU and allowing any other IRQs or
+	; DRQs to be serviced (which, on the PC and PC/XT will include DRAM refresh via DMA channel 0).  The 16-byte transfers can
+	; also be interrupted by the DMA controller raising TC (i.e. when done).  Each transfer cannot be otherwise interrupted
+	; and is therefore atomic (and hence fast).
 
-%if 0 ; Slow DMA code
-	; 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?
+%if 0	; Slow DMA code - works by checking 8237 status register after each 16-byte transfer, until it reports TC has been raised.
+;ALIGN JUMP_ALIGN
+;.TransferNextBlock:
+;	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
+;	in		al, STATUS_REGISTER_DMA8_in
+;	sti
+;	test	al, FLG_CH3_HAS_REACHED_TERMINAL_COUNT
+;	jz		SHORT .TransferNextBlock	; All bytes transferred?
 %endif ; Slow DMA code
 
-
-%if 1 ; Fast DMA code
-	push	cx
-	add		cx, BYTE 15					; Include any partial DMA block (since we had to divide transfer to 64k physical pages)
-	eSHR_IM	cx, 4						; Drive Block size to 16 Byte DMA Block Size
-
-.JustOneMoreDmaBlock:
-	mov		al, RAISE_DRQ_AND_CLEAR_XTCF_XFER_COUNTER
-ALIGN JUMP_ALIGN
+%if 1	; Fast DMA code - perform computed number of transfers, then check DMA status register to be sure
+	push	cx							; need byte count to update pointer at the end
+	add		cx, BYTE 15					; We'll divide transfers in 16-byte atomic transfers,
+	eSHR_IM	cx, 4						; so include any partial block, which will be terminated
+ALIGN JUMP_ALIGN						; by the DMA controller raising T/C
 .TransferNextDmaBlock:
-	out		dx, al						; Transfer 16 bytes to/from XT-CF card
-	loop	.TransferNextDmaBlock
-
+	out		dx, al						; Transfer up to 16 bytes to/from XT-CF card
+	loop	.TransferNextDmaBlock		; dec CX and loop if CX > 0, also adds required wait-state
 	inc		cx							; set up CX, in case we need to do an extra iteration
-	in		al, STATUS_REGISTER_DMA8_in
-	test	al, FLG_CH3_HAS_REACHED_TERMINAL_COUNT
-	jz		SHORT .JustOneMoreDmaBlock			; it wasn't set so get more bytes
-	pop		cx
+	in		al, STATUS_REGISTER_DMA8_in	; check 8237 DMA controller status flags...
+	test	al, FLG_CH3_HAS_REACHED_TERMINAL_COUNT	; ... for channel 3 terminal count
+	jz		SHORT .TransferNextDmaBlock	; If not set, get more bytes
+	pop		cx							; get back requested bytes
 %endif ; Fast DMA code
 
+	; Update physical address in ES:DI - since IO might need several calls through this function either from here
+	; if crossing a physical page boundary, and from IdeTransfer.asm if requested sectors was > PIOVARS.wSectorsInBlock
+	mov		ax, es						; copy physical page address to ax
+	add		di, cx						; add requested bytes to di
+	adc		al, 0						; and increment physical page address, if required
+	mov		es, ax						; and save it back in es
 
-	; 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/IdeIO.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeIO.asm	(revision 544)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeIO.asm	(revision 545)
@@ -52,9 +52,9 @@
 ;--------------------------------------------------------------------
 IdeIO_InputToALfromIdeRegisterInDL:
-	xor		dh, dh	; IDE Register index now in DX
-	mov		bx, dx	; and BX
+	xor		dh, dh	; IDE Register index now in DX...
 	mov		al, [di+DPT_ATA.bDevice]
 	cmp		al, DEVICE_8BIT_XTIDE_REV2
 	jb		SHORT .InputToALfromRegisterInDX	; Standard IDE controllers and XTIDE rev 1
+	mov		bx, dx	; ...and BX for A0<->A3 swap and for memory mapped I/O
 
 %ifdef MODULE_8BIT_IDE_ADVANCED
@@ -109,5 +109,5 @@
 	; At this point remaining controllers (JRIDE, XTCF and ADP50L) all have a control
 	; block offset of 8 or (8<<1) so we add 8 here and do the SHL 1 later if needed.
-	add		dx, 8
+	add		dx, BYTE 8
 	cmp		bl, DEVICE_8BIT_JRIDE_ISA
 	jb		SHORT IdeIO_OutputALtoIdeRegisterInDL.ShlRegisterIndexInDXandOutputAL	; All XT-CF modes
@@ -127,5 +127,5 @@
 	; a small trick since we only access Device Control Register at
 	; offset 6h: Always clear A3 and set A0.
-	mov		bh, dh	; Zero BH
+	call	AccessDPT_GetIdevarsToCSBX
 	add		dx, [cs:bx+IDEVARS.wControlBlockPort]
 	xor		dl, 1001b						; Clear A3, Set A0
@@ -134,5 +134,5 @@
 
 .OutputALtoControlBlockRegisterInDX:
-	call	AccessDPT_GetIdevarsToCSBX		; *FIXME* Why is this call here but not in the above block?
+	call	AccessDPT_GetIdevarsToCSBX
 	add		dx, [cs:bx+IDEVARS.wControlBlockPort]
 	out		dx, al
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdePioBlock.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdePioBlock.asm	(revision 544)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdePioBlock.asm	(revision 545)
@@ -20,6 +20,16 @@
 ;
 
+; Modified by JJP for XT-CFv3 support, Mar-13
+
 ; Section containing code
 SECTION .text
+
+
+; --------------------------------------------------------------------------------------------------
+;
+; READ routines follow
+;
+; --------------------------------------------------------------------------------------------------
+
 
 %ifdef MODULE_8BIT_IDE
@@ -50,8 +60,11 @@
 
 ;--------------------------------------------------------------------
-; 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
+; IdePioBlock_ReadFrom8bitDataPort
+;
+; 8-bit PIO from a single data port.
+;
+;	Parameters:
+;		CX:	Block size in 512 byte sectors
+;		DX:	IDE Data port address
 ;		ES:DI:	Normalized ptr to buffer to receive data
 ;	Returns:
@@ -60,170 +73,58 @@
 ;		AX, BX, CX
 ;--------------------------------------------------------------------
-%ifndef USE_186			; 8086/8088 compatible WORD read
-
-ALIGN JUMP_ALIGN
-IdePioBlock_ReadFromXtideRev2:
+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
+
+%endif	; MODULE_8BIT_IDE
+
+
+;--------------------------------------------------------------------
+; IdePioBlock_ReadFrom16bitDataPort
+;
+; 16-bit PIO from a single data port.
+;
+;	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_ReadFrom16bitDataPort:
+%ifdef USE_186
+	xchg		cl, ch	; Sectors to WORDs
+	rep insw
+	ret
+
+%else ; If 8088/8086
 	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
-
+		in		ax, dx	; Read BYTE
+		stosw			; Store BYTE 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
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-%ifdef USE_186
-%ifdef MODULE_8BIT_IDE
-IdePioBlock_ReadFromXtideRev2:
-%endif
-%endif
-IdePioBlock_ReadFrom16bitDataPort:
-	xchg	cl, ch		; Sectors to WORDs
-	rep
-	db		6Dh			; INSW
-	ret
 
 ;--------------------------------------------------------------------
@@ -239,10 +140,114 @@
 
 
-;--------------------------------------------------------------------
-; IdePioBlock_WriteTo16bitDataPort		Normal 16-bit IDE
+
+; --------------------------------------------------------------------------------------------------
+;
+; WRITE routines follow
+;
+; --------------------------------------------------------------------------------------------------
+
+%ifdef MODULE_8BIT_IDE
+
+;--------------------------------------------------------------------
+; 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	; special macro
+	%endrep
+	loop	.WriteNextQword
+	pop		ds
+	ret
+
+
+;--------------------------------------------------------------------
+; IdePioBlock_WriteTo8bitDataPort
+;	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_QWORDS
+	push		ds
+	;mov		ax, es
+	;mov		ds, ax	; move es to ds via ax (does this run faster on 8088?)
+	push		es
+	pop			ds
+ALIGN JUMP_ALIGN
+.WriteNextQword:
+	%rep 8	; BYTEs
+		lodsb			; Load BYTE from [DS:SI]
+		out	dx, al		; Write BYTE
+	%endrep
+	loop	.WriteNextQword
+	pop		ds
+	ret
+%endif
+
+%endif ; MODULE_8BIT_IDE
+
+
+;--------------------------------------------------------------------
+; IdePioBlock_WriteTo16bitDataPort		Normal 16-bit IDE, XT-CFv3 in BIU Mode
 ; IdePioBlock_WriteTo32bitDataPort		VLB/PCI 32-bit IDE
 ;	Parameters:
-;		CX:		Block size in 512-byte sectors
-;		DX:		IDE Data port address
+;		CX:	Block size in 512-byte sectors
+;		DX:	IDE Data port address
 ;		ES:SI:	Normalized ptr to buffer containing data
 ;	Returns:
@@ -253,9 +258,27 @@
 ALIGN JUMP_ALIGN
 IdePioBlock_WriteTo16bitDataPort:
+%ifdef USE_186
 	xchg	cl, ch		; Sectors to WORDs
 	es					; Source is ES segment
-	rep
-	db		6Fh			; OUTSW
-	ret
+	rep outsw
+	ret
+
+%else ; If 8088/8086
+	UNROLL_SECTORS_IN_CX_TO_QWORDS
+	push	ds
+	;mov	ax, es
+	;mov	ds, ax		; move es to ds via ax (does this run faster on 8088?)
+	push	es
+	pop		ds
+ALIGN JUMP_ALIGN
+.WriteNextQword:
+	%rep 4	; WORDs
+		lodsw			; Load BYTE from [DS:SI]
+		out	dx, ax		; Write BYTE
+	%endrep
+	loop	.WriteNextQword
+	pop		ds
+	ret
+%endif	; if/else USE_186
 
 ;--------------------------------------------------------------------
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm	(revision 544)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm	(revision 545)
@@ -346,10 +346,11 @@
 		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_ReadFrom16bitDataPort	; 4, DEVICE_8BIT_XTIDE_REV2
+		dw		IdePioBlock_ReadFrom8bitDataPort	; 5, DEVICE_8BIT_XTCF_PIO8
+		dw		IdePioBlock_ReadFrom16bitDataPort	; 6, DEVICE_8BIT_XTCF_PIO8_WITH_BIU_OFFLOAD
 %ifdef MODULE_8BIT_IDE_ADVANCED
-		dw		IdePioBlock_ReadFrom8bitDataPort	; 5, DEVICE_8BIT_XTCF_PIO8
-		dw		IdeDmaBlock_ReadFromXTCF			; 6, DEVICE_8BIT_XTCF_DMA
-%endif
-%endif
+		dw		IdeDmaBlock_ReadFromXTCF			; 7, DEVICE_8BIT_XTCF_DMA
+%endif ; MODULE_8BIT_IDE_ADVANCED
+%endif ; MODULE_8BIT_IDE
 
 
@@ -361,7 +362,8 @@
 		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		IdePioBlock_WriteTo16bitDataPort	; 6, DEVICE_8BIT_XTCF_PIO8_WITH_BIU_OFFLOAD
 %ifdef MODULE_8BIT_IDE_ADVANCED
-		dw		IdePioBlock_WriteTo8bitDataPort		; 5, DEVICE_8BIT_XTCF_PIO8
-		dw		IdeDmaBlock_WriteToXTCF				; 6, DEVICE_8BIT_XTCF_DMA
-%endif
-%endif
+		dw		IdeDmaBlock_WriteToXTCF				; 7, DEVICE_8BIT_XTCF_DMA
+%endif ; MODULE_8BIT_IDE_ADVANCED
+%endif ; MODULE_8BIT_IDE
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/JrIdeTransfer.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/JrIdeTransfer.asm	(revision 544)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/JrIdeTransfer.asm	(revision 545)
@@ -67,21 +67,8 @@
 
 	; Get far pointer to Sector Access Window
-	mov		dx, [di+DPT.wBasePort]
 	cmp		BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_JRIDE_ISA
-	jb		SHORT .GetSectorAccessWindowForXTCF
-
-	; Get Sector Access Window for JR-IDE/ISA and ADP50L
-	mov		ds, dx		; Segment for JR-IDE/ISA and ADP50L
-	mov		di, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET
-	je		SHORT .SectorAccessWindowLoadedToDSDI
+	mov		ds, [di+DPT.wBasePort]	; Segment for JR-IDE/ISA and ADP50L
 	mov		di, ADP50L_SECTOR_ACCESS_WINDOW_OFFSET
-	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
+	eCMOVE	di, JRIDE_SECTOR_ACCESS_WINDOW_OFFSET
 
 	; Are we reading or writing?
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH1Eh_XTCF.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH1Eh_XTCF.asm	(revision 544)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH1Eh_XTCF.asm	(revision 545)
@@ -1,4 +1,6 @@
 ; Project name	:	XTIDE Universal BIOS
-; Description	:	Int 13h function AH=1Eh, Lo-tech XT-CF features.
+; Description	:	Int 13h function AH=1Eh, Lo-tech XT-CF features
+;
+; More information at http://www.lo-tech.co.uk/XT-CF
 
 ;
@@ -17,4 +19,6 @@
 ; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 ;
+
+; Modified by JJP for XT-CFv3 support, Mar-13
 
 ; Section containing code
@@ -42,5 +46,5 @@
 	jmp		Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
 %else
-	push	Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
+	push		Int13h_ReturnFromHandlerAfterStoringErrorCodeFromAH
 	; Fall to ProcessXTCFsubcommandFromAL
 %endif
@@ -56,4 +60,5 @@
 ;		AH:		Int 13h return status
 ;		CF:		0 if successful, 1 if error
+;		DX		Command return values (see XTCF.inc)
 ;	Corrupts registers:
 ;		AL, BX, CX, DX, SI
@@ -62,33 +67,40 @@
 	; IS_THIS_DRIVE_XTCF. We check this for all commands.
 	call	AccessDPT_IsThisDeviceXTCF
-	jne		SHORT XTCFnotFound
+	jne		SHORT .XTCFnotFound
 	and		ax, BYTE 7Fh				; Subcommand now in AX (clears AH and CF)
-	jz		SHORT .ReturnWithSuccess	; IS_THIS_DRIVE_XTCF
+	jz		SHORT .XTCFfound			; Sub-function IS_THIS_DRIVE_XTCF (=0)
 
-	; READ_XTCF_CONTROL_REGISTER_TO_DH
-	dec		ax							; Subcommand
-	jnz		SHORT .SkipReadXtcfControlRegisterToDH
-	mov		dx, [di+DPT.wBasePort]
-	add		dl, XTCF_CONTROL_REGISTER	; Will never overflow (keeps CF cleared)
-	in		al, dx
-	mov		[bp+IDEPACK.intpack+INTPACK.dh], al
-.ReturnWithSuccess:
-	ret		; With AH and CF cleared
+	dec		ax							; Test subcommand...
+	jz		SHORT .SetXTCFtransferMode	; ...for value 1 (SET_XTCF_TRANSFER_MODE)
 
-.SkipReadXtcfControlRegisterToDH:
-	; WRITE_DH_TO_XTCF_CONTROL_REGISTER
-	dec		ax							; Subcommand
-	jnz		SHORT XTCFnotFound			; Invalid subcommand
-	mov		al, [bp+IDEPACK.intpack+INTPACK.dh]
-	; Fall to AH1Eh_ChangeXTCFmodeBasedOnControlRegisterInAL
+	dec		ax							; Test subcommand for value 2 (GET_XTCF_TRANSFER_MODE)
+	jnz		SHORT .XTCFnotFound			; Invalid subcommand
+
+	; GET_XTCF_TRANSFER_MODE
+	call	AH1Eh_GetCurrentXTCFmodeToAX
+	mov		dl, [di+DPT_ATA.bBlockSize]
+	mov		[bp+IDEPACK.intpack+INTPACK.dh], al	; return mode value...
+	mov		[bp+IDEPACK.intpack+INTPACK.dl], dl	; ...and block size, via INTPACK...
+.XTCFfound:
+	ret											; ...with AH and CF cleared
+
+.XTCFnotFound:
+.AH1Eh_LoadInvalidCommandToAHandSetCF:
+	stc					; set carry flag since XT-CF not found
+	mov		ah, RET_HD_INVALID
+	ret					; and return
+
+.SetXTCFtransferMode:
+	mov		al, [bp+IDEPACK.intpack+INTPACK.dh]	; get specified mode (eg XTCF_DMA_MODE) 
+	; and fall to AH1Eh_ChangeXTCFmodeBasedOnControlRegisterInAL
 
 
 ;--------------------------------------------------------------------
-; AH1Eh_ChangeXTCFmodeBasedOnControlRegisterInAL
+; AH1Eh_ChangeXTCFmodeBasedOnModeInAL
 ;	Parameters:
-;		AL:		XT-CF Control Register
+;		AL:		XT-CF Mode (see XTCF.inc)
 ;		DS:DI:	Ptr to DPT (in RAMVARS segment)
 ;		SS:BP:	Ptr to IDEPACK
-;	Returns:
+;	Returns:	
 ;		AH:		Int 13h return status
 ;		CF:		0 if successful, 1 if error
@@ -96,66 +108,65 @@
 ;		AL, BX, CX, DX, SI
 ;--------------------------------------------------------------------
-AH1Eh_ChangeXTCFmodeBasedOnControlRegisterInAL:
-	; Output Control Register
-	mov		dx, [di+DPT.wBasePort]
-	add		dl, XTCF_CONTROL_REGISTER
-	out		dx, al
+AH1Eh_ChangeXTCFmodeBasedOnModeInAL:
+	; Note: Control register (as of XT-CFv3) is now a write-only register,
+	;       whos purpose is *only* to raise DRQ.  The register cannot be read.
+	;       Selected transfer mode is stored in BIOS variable (DPT_ATA.bDevice).
 
 	; We always need to enable 8-bit mode since 16-bit mode is restored
 	; when controller is reset (AH=00h or 0Dh)
+	; 
+	; Note that when selecting 'DEVICE_8BIT_PIO_MODE_WITH_BIU_OFFLOAD' mode,
+	; the ATA device (i.e. CompactFlash card) will operate in 8-bit mode, but
+	; data will be transferred from it's data register using 16-bit CPU instructions
+	; like REP INSW.  This works because XT-CF adapters are 8-bit cards, and
+	; the BIU in the machine splits each WORD requested by the CPU into two 8-bit
+	; ISA cycles at base+0h and base+1h.  The XT-CF cards do not decode A0, hence
+	; both accesses appear the same to the card and the BIU then re-constructs
+	; the data for presentation to the CPU.
+	;
+	; Also note though that some machines, noteably AT&T PC6300, have hardware
+	; errors in the BIU logic, resulting in reversed byte ordering.  Therefore,
+	; mode DEVICE_8BIT_PIO is the default transfer mode for best system
+	; compatibility.
+
 	ePUSH_T	bx, AH23h_Enable8bitPioMode
 
-	; Convert Control Register Contents to device code
-	test	al, al
-	jz		SHORT .Set8bitPioMode
-	cmp		al, XTCF_MEMORY_MAPPED_MODE
-	jae		SHORT .SetMemoryMappedMode
+	; Convert mode to device type (see XTCF.inc for full details)
+	and		ax, 3
+	jz	SHORT .Set8bitPioMode	; XTCF_8BIT_PIO_MODE = 0
+	dec		ax					; XTCF_8BIT_PIO_MODE_WITH_BIU_OFFLOAD = 1
+	jz	SHORT .Set8bitPioModeWithBIUOffload
 
-	; Set DMA Mode
+	; XTCF_DMA_MODE = 2 (allow 3 as well for more optimized code)
 	mov		BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_XTCF_DMA
+
+	; DMA transfers have limited block sizee
 	mov		al, [di+DPT_ATA.bBlockSize]
-	cmp		al, XTCF_DMA_MODE_MAX_BLOCK_SIZE
-	jbe		SHORT AH24h_SetBlockSize
-	mov		al, XTCF_DMA_MODE_MAX_BLOCK_SIZE
-	jmp		SHORT AH24h_SetBlockSize
-
-.SetMemoryMappedMode:
-	mov		al, DEVICE_8BIT_XTCF_MEMMAP
-	SKIP2B	bx
+	MIN_U	al, XTCF_DMA_MODE_MAX_BLOCK_SIZE
+	jmp		AH24h_SetBlockSize
+	; exit via ret in AH24_SetBlockSize then through AH23h_Enable8bitPioMode
 
 .Set8bitPioMode:
-	mov		al, DEVICE_8BIT_XTCF_PIO8
-	mov		[di+DPT_ATA.bDevice], al
-	ret		; Via AH23h_Enable8bitPioMode
+	mov		BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_XTCF_PIO8
+	ret		; through AH23h_Enable8bitPioMode
+
+.Set8bitPioModeWithBIUOffload:
+	mov		BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_XTCF_PIO8_WITH_BIU_OFFLOAD
+	ret		; through AH23h_Enable8bitPioMode
 
 
 ;--------------------------------------------------------------------
-; AH1Eh_DetectXTCFwithBasePortInDX
+; AH1Eh_GetCurrentXTCFmodeToAX
 ;	Parameters:
-;		DX:		Base I/O port address to check
-;	Returns:
-;		AH:		RET_HD_SUCCESS if XT-CF is found from port
-;				RET_HD_INVALID if XT-CF is not found
-;		CF:		Cleared if XT-CF found
-;				Set if XT-CF not found
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;	Returns:	
+;		AX:		XT-CF mode (XTCF_8BIT_PIO_MODE, XTCF_8BIT_PIO_MODE_WITH_BIU_OFFLOAD or XTCF_DMA_MODE)
+;		CF:		Clear
 ;	Corrupts registers:
-;		AL
+;		Nothing
 ;--------------------------------------------------------------------
-AH1Eh_DetectXTCFwithBasePortInDX:
-	push	dx
-	add		dl, XTCF_CONTROL_REGISTER_INVERTED_in	; set DX to XT-CF config register (inverted)
-	in		al, dx		; get value
-	mov		ah, al		; save in ah
-	inc		dx			; set DX to XT-CF config register (non-inverted)
-	in		al, dx		; get value
-	not		al			; invert value
-	pop		dx
-	sub		ah, al		; do they match? (clear AH if they do)
-	jz		SHORT XTCFfound
-
-XTCFnotFound:
-AH1Eh_LoadInvalidCommandToAHandSetCF:
-	stc					; set carry flag since XT-CF not found
-	mov		ah, RET_HD_INVALID
-XTCFfound:
-	ret					; and return
+AH1Eh_GetCurrentXTCFmodeToAX:
+	eMOVZX	ax, BYTE [di+DPT_ATA.bDevice]	; get current mode from DPT
+	sub		al, DEVICE_8BIT_XTCF_PIO8
+	shr		ax, 1							; Device type to XT-CF mode
+	ret
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH24h_HSetBlocks.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH24h_HSetBlocks.asm	(revision 544)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH24h_HSetBlocks.asm	(revision 545)
@@ -63,6 +63,10 @@
 	cmp		al, XTCF_DMA_MODE_MAX_BLOCK_SIZE
 	jbe		SHORT .NoNeedToLimitBlockSize
+
+	; Return error if we tried too large block for XT-CF.
+	; Do not limit it to maximum supported since software calling AH=24h
+	; must know what the actual block size is.
 	cmp		BYTE [di+DPT_ATA.bDevice], DEVICE_8BIT_XTCF_DMA
-	je		SHORT AH1Eh_LoadInvalidCommandToAHandSetCF
+	je		SHORT ProcessXTCFsubcommandFromAL.AH1Eh_LoadInvalidCommandToAHandSetCF
 .NoNeedToLimitBlockSize:
 %endif ; MODULE_8BIT_IDE_ADVANCED
@@ -77,5 +81,8 @@
 	pop		bx
 	jnc		SHORT .StoreBlockSize
-	mov		bl, 1		; Block size 1 will always work
+
+	; Drive disabled block mode since we tried unsupported block size.
+	; We must adjust DPT accordingly.
+	mov		bl, 1		; Block size 1 will always work (=Block mode disabled)
 .StoreBlockSize:		; Store new block size to DPT and return
 	mov		[di+DPT_ATA.bBlockSize], bl
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH8h_HParams.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH8h_HParams.asm	(revision 544)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH8h_HParams.asm	(revision 545)
@@ -58,5 +58,5 @@
 
 	test	byte [bp+IDEPACK.intpack+INTPACK.dl], 080h
-	jnz		.Done
+	jnz		SHORT .CalledForHardDrive
 
 	mov		[bp+IDEPACK.intpack+INTPACK.bl], bl
@@ -67,5 +67,5 @@
 	call	FloppyDrive_GetCountToAX
 
-.Done:
+.CalledForHardDrive:
 	mov		ah, dh
 
@@ -133,7 +133,5 @@
 %ifdef MODULE_SERIAL_FLOPPY
 	mov		bl, [di+DPT.bFlagsHigh]
-%ifndef CHECK_FOR_UNUSED_ENTRYPOINTS             ; not sure why this is needed for preprocessor-only
 	eSHR_IM	bl, FLGH_DPT_SERIAL_FLOPPY_TYPE_FIELD_POSITION
-%endif
 %endif
 	ret
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm	(revision 544)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm	(revision 545)
@@ -114,6 +114,5 @@
 ;;; Set XT-CF mode
 %ifdef MODULE_8BIT_IDE_ADVANCED
-	call	AccessDPT_GetIdevarsToCSBX
-	mov		al, [cs:bx+IDEVARS.bXTCFcontrolRegister]
+	call	AH1Eh_GetCurrentXTCFmodeToAX
 	call	AH9h_SetModeFromALtoXTCF
 	STORE_ERROR_FLAG_TO_DPT		FLG_INITERROR_FAILED_TO_SET_XTCF_MODE
@@ -284,5 +283,5 @@
 	call	AccessDPT_IsThisDeviceXTCF
 	jne		SHORT IgnoreInvalidCommandError
-	jmp		AH1Eh_ChangeXTCFmodeBasedOnControlRegisterInAL
+	jmp		AH1Eh_ChangeXTCFmodeBasedOnModeInAL
 %endif ; MODULE_8BIT_IDE_ADVANCED
 
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH48h_GetExtendedDriveParameters.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH48h_GetExtendedDriveParameters.asm	(revision 544)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/EBIOS/AH48h_GetExtendedDriveParameters.asm	(revision 545)
@@ -139,7 +139,12 @@
 	sbb		dx, (MAX_SECTOR_COUNT_TO_RETURN_PCHS+1) >> 16
 	sbb		bx, cx		; Zero
-	jnc		SHORT .ReturnWithSuccess
+	jnc		SHORT .DoNotSetChsFlag
 	or		BYTE [di+EDRIVE_INFO.wFlags], FLG_CHS_INFORMATION_IS_VALID
 
+	; We store something to P-CHS anyway since some HW detection programs
+	; ignore the CHS flag. And we should at least clear the variables anyway
+	; since the same buffer is used for all drives so it contains parameters
+	; from previously scanned drive.
+.DoNotSetChsFlag:
 	eMOVZX	dx, BYTE [es:si+DPT.bPchsHeads]
 	mov		[di+EDRIVE_INFO.dwHeads], dx
Index: trunk/XTIDE_Universal_BIOS/Src/Initialization/DetectDrives.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Initialization/DetectDrives.asm	(revision 544)
+++ trunk/XTIDE_Universal_BIOS/Src/Initialization/DetectDrives.asm	(revision 545)
@@ -158,38 +158,13 @@
 ;--------------------------------------------------------------------
 StartDetectionWithDriveSelectByteInBHandStringInCX:
-%ifdef MODULE_8BIT_IDE_ADVANCED
-	; Autodetect port for XT-CF
+%ifdef MODULE_8BIT_IDE
 	call	DetectDrives_DoesIdevarsInCSBPbelongToXTCF
-	jne		SHORT .SkipXTCFportDetection
+	jne		SHORT .ShouldNotSkipSlaveDriveDetection
 
 	; XT-CF do not support slave drives so skip detection
 	test	bh, FLG_DRVNHEAD_DRV
 	jnz		SHORT NoSlaveDriveAvailable
-
-	; XT-CF do not support slave drives so we can safely update port
-	; for next drive (another XT-CF card on same system)
-.DetectNextPort:
-	mov		dx, [es:BOOTVARS.wNextXTCFportToScan]
-	xor		dl, 40h
-	jnz		SHORT .StoreNextXTCFportToScan
-	inc		dh
-	cmp		dh, XTCF_BASE_PORT_4 >> 8
-	ja		SHORT .SkipXTCFportDetection		; XT-CF not found from any port
-.StoreNextXTCFportToScan:
-	mov		[es:BOOTVARS.wNextXTCFportToScan], dx
-
-	call	AH1Eh_DetectXTCFwithBasePortInDX
-	jc		SHORT .DetectNextPort				; XT-CF not found from this port
-
-	; We now have autodetected port in DX
-	push	dx
-	xchg	ax, dx								; Port to print in AX
-	call	DetectPrint_StartDetectWithAutodetectedBasePortInAXandIdeVarsInCSBP
-	jmp		SHORT .DriveDetectionStringPrintedOnScreen
-
-	; Print detect string for devices that do not support autodetection
-.SkipXTCFportDetection:
-	push	dx
-%endif ; MODULE_8BIT_IDE_ADVANCED
+.ShouldNotSkipSlaveDriveDetection:
+%endif ; MODULE_8BIT_IDE
 
 	call	DetectPrint_StartDetectWithMasterOrSlaveStringInCXandIdeVarsInCSBP
@@ -197,8 +172,4 @@
 %ifdef MODULE_HOTKEYS
 	call	HotkeyBar_UpdateDuringDriveDetection
-%endif
-
-%ifdef MODULE_8BIT_IDE_ADVANCED
-	pop		dx
 %endif
 	; Fall to .ReadAtaInfoFromHardDisk
@@ -278,5 +249,5 @@
 
 
-%ifdef MODULE_8BIT_IDE_ADVANCED
+%ifdef MODULE_8BIT_IDE
 ;--------------------------------------------------------------------
 ; DetectDrives_DoesIdevarsInCSBPbelongToXTCF
@@ -292,10 +263,14 @@
 	mov		al, [cs:bp+IDEVARS.bDevice]
 	cmp		al, DEVICE_8BIT_XTCF_PIO8
-	je		SHORT .DeviceIsXTCF
+	je		SHORT .Done
+	cmp		al, DEVICE_8BIT_XTCF_PIO8_WITH_BIU_OFFLOAD
+
+%ifdef MODULE_8BIT_IDE_ADVANCED
+	je		SHORT .Done
 	cmp		al, DEVICE_8BIT_XTCF_DMA
-	je		SHORT .DeviceIsXTCF
-	cmp		al, DEVICE_8BIT_XTCF_MEMMAP
-.DeviceIsXTCF:
+%endif ; MODULE_8BIT_IDE_ADVANCED
+
+.Done:		; return state via ZF, set from the cmp instructions
 NoSlaveDriveAvailable:
 	ret
-%endif ; MODULE_8BIT_IDE_ADVANCED
+%endif ; MODULE_8BIT_IDE
Index: trunk/XTIDE_Universal_BIOS/Src/Main.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Main.asm	(revision 544)
+++ trunk/XTIDE_Universal_BIOS/Src/Main.asm	(revision 545)
@@ -145,5 +145,4 @@
 
 %ifdef MODULE_8BIT_IDE_ADVANCED
-	at	ROMVARS.ideVars1+IDEVARS.bXTCFcontrolRegister,	db	XTCF_8BIT_PIO_MODE
 	at	ROMVARS.ideVars1+IDEVARS.bDevice,				db	DEVICE_8BIT_XTCF_PIO8
 %endif
Index: trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AccessDPT.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AccessDPT.asm	(revision 544)
+++ trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/AccessDPT.asm	(revision 545)
@@ -103,7 +103,7 @@
 	cmp		ah, DEVICE_8BIT_XTCF_PIO8
 	je		SHORT .DeviceIsXTCF
+	cmp		ah, DEVICE_8BIT_XTCF_PIO8_WITH_BIU_OFFLOAD
+	je		SHORT .DeviceIsXTCF
 	cmp		ah, DEVICE_8BIT_XTCF_DMA
-	je		SHORT .DeviceIsXTCF
-	cmp		ah, DEVICE_8BIT_XTCF_MEMMAP
 .DeviceIsXTCF:
 	ret
Index: trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/BootVars.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/BootVars.asm	(revision 544)
+++ trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/BootVars.asm	(revision 545)
@@ -32,8 +32,4 @@
 ;--------------------------------------------------------------------
 BootVars_Initialize:
-%ifdef MODULE_8BIT_IDE_ADVANCED
-	mov		WORD [es:BOOTVARS.wNextXTCFportToScan], XTCF_BASE_PORT_DETECTION_SEED
-%endif
-
 	; Clear all DRVDETECTINFO structs to zero
 	mov		al, DRVDETECTINFO_size
Index: trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm	(revision 544)
+++ trunk/XTIDE_Universal_BIOS/Src/VariablesAndDPTs/CreateDPT.asm	(revision 545)
@@ -122,9 +122,7 @@
 
 %ifdef MODULE_EBIOS
-%ifdef CREATE_COMPATIBLE_DPT
 	; Store P-Cylinders here for Compatible DPTs when FLGL_DPT_LBA is not set
 	; or when drive has over 15,482,880 sectors
 	mov		[di+DPT.wPchsCylinders], ax
-%endif
 	test	cl, FLGL_DPT_LBA
 	jz		SHORT .NoLbaSoNoEBIOS
@@ -263,13 +261,4 @@
 CreateDPT_StoreIdevarsOffsetAndBasePortFromCSBPtoDPTinDSDI:
 	mov		[di+DPT.bIdevarsOffset], bp		; IDEVARS must start in first 256 bytes of ROM
-
-%ifdef MODULE_8BIT_IDE_ADVANCED
-	call	DetectDrives_DoesIdevarsInCSBPbelongToXTCF
-	jne		SHORT .DeviceUsesPortSpecifiedInIDEVARS
-	mov		[di+DPT.wBasePort], dx
-	ret
-.DeviceUsesPortSpecifiedInIDEVARS:
-%endif ; MODULE_8BIT_IDE_ADVANCED
-
 	mov		ax, [cs:bp+IDEVARS.wBasePort]
 	mov		[di+DPT.wBasePort], ax
