Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm	(revision 361)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeCommand.asm	(revision 363)
@@ -56,4 +56,7 @@
 	mov		[di+DPT.bIdevarsOffset], bp
 	mov		BYTE [di+DPT_ATA.bSetBlock], 1	; Block = 1 sector
+%ifdef MODULE_ADVANCED_ATA
+	call	IdeDPT_StoreDeviceTypeFromIdevarsInCSBPtoDPTinDSDI
+%endif
 %ifdef ASSEMBLE_SHARED_IDE_DEVICE_FUNCTIONS
 	call	IdeDPT_StoreReversedAddressLinesFlagIfNecessary
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDPT.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDPT.asm	(revision 361)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDPT.asm	(revision 363)
@@ -14,8 +14,7 @@
 ;		CF:		Clear, IDE interface only supports hard disks
 ;	Corrupts registers:
-;		AX
+;		AX, BX, CX, DX
 ;--------------------------------------------------------------------
 IdeDPT_Finalize:
-	; Fall to .StoreBlockMode
 
 ;--------------------------------------------------------------------
@@ -34,5 +33,71 @@
 	mov		ah, [es:si+ATA1.bBlckSize]		; Max block size in sectors
 	mov		[di+DPT_ATA.wSetAndMaxBlock], ax
-	; Fall to IdeDPT_StoreReversedAddressLinesFlagIfNecessary
+
+%ifdef MODULE_ADVANCED_ATA
+;--------------------------------------------------------------------
+; .StoreDeviceType
+;	Parameters:
+;		DS:DI:	Ptr to Disk Parameter Table
+;		ES:SI:	Ptr to 512-byte ATA information read from the drive
+;		CS:BP:	Ptr to IDEVARS for the controller
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+.StoreDeviceType:
+	call	IdeDPT_StoreDeviceTypeFromIdevarsInCSBPtoDPTinDSDI
+
+;--------------------------------------------------------------------
+; .StorePioModeAndTimings
+;	Parameters:
+;		DS:DI:	Ptr to Disk Parameter Table
+;		ES:SI:	Ptr to 512-byte ATA information read from the drive
+;		CS:BP:	Ptr to IDEVARS for the controller
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, CX, DX
+;--------------------------------------------------------------------
+.StorePioMode:
+	call	AtaID_GetMaxPioModeToAXandMinCycleTimeToDX
+	call	AtaID_ConvertPioModeFromAXandMinCycleTimeFromDXtoActiveAndRecoveryTime
+	mov		[di+DPT_ATA.bPioMode], al
+	mov		[di+DPT_ADVANCED_ATA.wMinPioActiveTimeNs], cx
+	mov		[di+DPT_ADVANCED_ATA.wMinPioRecoveryTimeNs], dx
+
+;--------------------------------------------------------------------
+; .DetectAdvancedIdeController
+;	Parameters:
+;		DS:DI:	Ptr to Disk Parameter Table
+;		ES:SI:	Ptr to 512-byte ATA information read from the drive
+;		CS:BP:	Ptr to IDEVARS for the controller
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, CX, DX
+;--------------------------------------------------------------------
+.DetectAdvancedIdeController:
+	mov		dx, [cs:bp+IDEVARS.wPort]
+	mov		[di+DPT_ADVANCED_ATA.wIdeBasePort], dx
+	call	AdvAtaInit_DetectControllerForIdeBaseInDX
+	mov		[di+DPT_ADVANCED_ATA.wControllerID], ax	; Store zero if none detected
+	mov		[di+DPT_ADVANCED_ATA.wControllerBasePort], cx
+	jnc		SHORT .NoAdvancedControllerDetected
+
+	; Use highest common PIO mode from controller and drive.
+	; Many VLB controllers support PIO modes up to 2.
+	call	AdvAtaInit_GetControllerMaxPioModeToAL
+	jnc		SHORT .ChangeTo32bitDevice
+	MIN_U	[di+DPT_ATA.bPioMode], al
+
+	; We have detected 32-bit controller so change Device Type since
+	; it might have been set to 16-bit on IDEVARS
+.ChangeTo32bitDevice:
+	mov		BYTE [di+DPT_ATA.bDevice], DEVICE_32BIT_ATA
+
+.NoAdvancedControllerDetected:
+
+%endif ; MODULE_ADVANCED_ATA
 
 ;--------------------------------------------------------------------
@@ -42,5 +107,5 @@
 ;		CS:BP:	Ptr to IDEVARS for the controller
 ;	Returns:
-;		CF:		Always clear, we don't support floppies on the IDE inteface
+;		CF:		Always clear
 ;	Corrupts registers:
 ;		Nothing
@@ -53,6 +118,23 @@
 .SetFlagForSwappedA0andA3:
 	or		BYTE [di+DPT.bFlagsHigh], FLGH_DPT_REVERSED_A0_AND_A3
-
 .EndDPT:
 	clc
 	ret
+
+
+%ifdef MODULE_ADVANCED_ATA
+;--------------------------------------------------------------------
+; IdeDPT_StoreDeviceTypeFromIdevarsInCSBPtoDPTinDSDI
+;	Parameters:
+;		DS:DI:	Ptr to Disk Parameter Table
+;		CS:BP:	Ptr to IDEVARS for the controller
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AL
+;--------------------------------------------------------------------
+IdeDPT_StoreDeviceTypeFromIdevarsInCSBPtoDPTinDSDI:
+	mov		al, [cs:bp+IDEVARS.bDevice]
+	mov		[di+DPT_ATA.bDevice], al
+	ret
+%endif
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm	(revision 361)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm	(revision 363)
@@ -5,11 +5,10 @@
 ; This struct must not be larger than IDEPACK without INTPACK.
 struc PIOVARS
-	.wWordsInBlock			resb	2	; 0, Block size in WORDs
-	.wWordsLeft				resb	2	; 2, WORDs left to transfer
-	.wWordsDone				resb	2	; 4, Number of sectors xferred
-							resb	1	; 6,
+	.wDataPort				resb	2	; 0, IDE Data Port
+	.fnXfer					resb	2	; 2, Offset to transfer function
+	.wSectorsInBlock		resb	2	; 4, Block size in sectors
+	.bSectorsLeft			resb	1	; 6, Sectors left to transfer
 							resb	1	; 7, IDEPACK.bDeviceControl
-	.wDataPort				resb	2	; 8, IDE Data Port
-	.fnXfer					resb	2	; 10, Offset to transfer function
+	.bSectorsDone			resb	1	; 8, Number of sectors xferred
 endstruc
 
@@ -69,10 +68,10 @@
 	xchg	si, di								; ES:DI now points buffer
 
-	mov		cx, [bp+PIOVARS.wWordsInBlock]
+	mov		cx, [bp+PIOVARS.wSectorsInBlock]	; Max 128
 
 ALIGN JUMP_ALIGN
 .ReadNextBlockFromDrive:
 	mov		dx, [bp+PIOVARS.wDataPort]
-	cmp		[bp+PIOVARS.wWordsLeft], cx
+	cmp		[bp+PIOVARS.bSectorsLeft], cl
 	jbe		SHORT .ReadLastBlockFromDrive
 	call	[bp+PIOVARS.fnXfer]
@@ -84,13 +83,13 @@
 	xchg	si, di								; ES:DI now points buffer
 
-	; Increment number of successfully read WORDs
-	mov		cx, [bp+PIOVARS.wWordsInBlock]
-	sub		[bp+PIOVARS.wWordsLeft], cx
-	add		[bp+PIOVARS.wWordsDone], cx
+	; Increment number of successfully read sectors
+	mov		cx, [bp+PIOVARS.wSectorsInBlock]
+	sub		[bp+PIOVARS.bSectorsLeft], cl
+	add		[bp+PIOVARS.bSectorsDone], cl
 	jmp		SHORT .ReadNextBlockFromDrive
 
 ALIGN JUMP_ALIGN
 .ReadLastBlockFromDrive:
-	mov		cx, [bp+PIOVARS.wWordsLeft]
+	mov		cl, [bp+PIOVARS.bSectorsLeft]		; CH is already zero
 	call	[bp+PIOVARS.fnXfer]					; Transfer possibly partial block
 
@@ -103,9 +102,6 @@
 	; Return number of successfully read sectors
 ReturnWithTransferErrorInAH:
-	mov		cx, [bp+PIOVARS.wWordsDone]
-	jc		SHORT .ConvertTransferredWordsInCXtoSectors
-	add		cx, [bp+PIOVARS.wWordsLeft]			; Never sets CF
-.ConvertTransferredWordsInCXtoSectors:
-	xchg	cl, ch
+	mov		cl, [bp+PIOVARS.bSectorsDone]
+	mov		ch, 0								; Preserve CF
 	ret
 
@@ -137,10 +133,10 @@
 	jc		SHORT ReturnWithTransferErrorInAH
 
-	mov		cx, [bp+PIOVARS.wWordsInBlock]
+	mov		cx, [bp+PIOVARS.wSectorsInBlock]	; Max 128
 
 ALIGN JUMP_ALIGN
 .WriteNextBlockToDrive:
 	mov		dx, [bp+PIOVARS.wDataPort]
-	cmp		[bp+PIOVARS.wWordsLeft], cx
+	cmp		[bp+PIOVARS.bSectorsLeft], cl
 	jbe		SHORT .WriteLastBlockToDrive
 	call	[bp+PIOVARS.fnXfer]
@@ -150,13 +146,13 @@
 	jc		SHORT ReturnWithTransferErrorInAH
 
-	; Increment number of successfully written WORDs
-	mov		cx, [bp+PIOVARS.wWordsInBlock]
-	sub		[bp+PIOVARS.wWordsLeft], cx
-	add		[bp+PIOVARS.wWordsDone], cx
+	; Increment number of successfully written sectors
+	mov		cx, [bp+PIOVARS.wSectorsInBlock]
+	sub		[bp+PIOVARS.bSectorsLeft], cl
+	add		[bp+PIOVARS.bSectorsDone], cl
 	jmp		SHORT .WriteNextBlockToDrive
 
 ALIGN JUMP_ALIGN
 .WriteLastBlockToDrive:
-	mov		cx, [bp+PIOVARS.wWordsLeft]
+	mov		cl, [bp+PIOVARS.bSectorsLeft]		; CH is already zero
 %ifdef USE_186
 	push	CheckErrorsAfterTransferringLastBlock
@@ -183,10 +179,8 @@
 InitializePiovarsInSSBPwithSectorCountInAH:
 	; Store sizes
-	xor		al, al
-	mov		[bp+PIOVARS.wWordsLeft], ax
-	mov		ah, [di+DPT_ATA.bSetBlock]
-	mov		[bp+PIOVARS.wWordsInBlock], ax
-	cbw
-	mov		[bp+PIOVARS.wWordsDone], ax			; Zero
+	mov		[bp+PIOVARS.bSectorsLeft], ah
+	eMOVZX	ax, BYTE [di+DPT_ATA.bSetBlock]
+	mov		[bp+PIOVARS.wSectorsInBlock], ax
+	mov		[bp+PIOVARS.bSectorsDone], ah		; Zero
 
 	; Get transfer function based on bus type
@@ -194,6 +188,11 @@
 	mov		bl, [di+DPT.bIdevarsOffset]			; CS:BX now points to IDEVARS
 	mov		dx, [cs:bx+IDEVARS.wPort]			; Load IDE Data port address
+%ifdef MODULE_ADVANCED_ATA
+	mov		bl, [di+DPT_ATA.bDevice]
+%else
 	mov		bl, [cs:bx+IDEVARS.bDevice]			; Load device type to BX
+%endif
 	add		bx, ax
+
 	mov		[bp+PIOVARS.wDataPort], dx
 	mov		ax, [cs:bx]							; Load offset to transfer function
@@ -208,5 +207,5 @@
 ; ReadBlockFrom32bitDataPort	VLB/PCI 32-bit IDE
 ;	Parameters:
-;		CX:		Block size in WORDs
+;		CX:		Block size in 512 byte sectors
 ;		DX:		IDE Data port address
 ;		ES:DI:	Normalized ptr to buffer to receive data
@@ -218,5 +217,5 @@
 ALIGN JUMP_ALIGN
 ReadBlockFromXtideRev1:
-	eSHR_IM	cx, 2		; Loop unrolling
+	UNROLL_SECTORS_IN_CX_TO_QWORDS
 	mov		bx, 8		; Bit mask for toggling data low/high reg
 ALIGN JUMP_ALIGN
@@ -233,5 +232,5 @@
 ALIGN JUMP_ALIGN
 ReadBlockFromXtideRev2:
-	times 2 shr	cx, 1	; WORD count to QWORD count
+	UNROLL_SECTORS_IN_CX_TO_QWORDS
 ALIGN JUMP_ALIGN
 .ReadNextQword:
@@ -251,4 +250,5 @@
 ALIGN JUMP_ALIGN
 ReadBlockFrom16bitDataPort:
+	xchg	cl, ch		; Sectors to WORDs
 	rep
 	db		6Dh			; INSW (we want this in XT build)
@@ -258,5 +258,7 @@
 ALIGN JUMP_ALIGN
 ReadBlockFrom32bitDataPort:
-	shr		cx, 1		; WORD count to DWORD count
+	db		0C1h		; SHL
+	db		0E1h		; CX
+	db		7			; 7	(Sectors to DWORDs)
 	rep
 	db		66h			; Override operand size to 32-bit
@@ -272,5 +274,5 @@
 ; WriteBlockTo32bitDataPort		VLB/PCI 32-bit IDE
 ;	Parameters:
-;		CX:		Block size in WORDs
+;		CX:		Block size in 512-byte sectors
 ;		DX:		IDE Data port address
 ;		ES:SI:	Normalized ptr to buffer containing data
@@ -284,5 +286,5 @@
 	push	ds
 	push	bx
-	eSHR_IM	cx, 2		; Loop unrolling
+	UNROLL_SECTORS_IN_CX_TO_QWORDS
 	mov		bx, 8		; Bit mask for toggling data low/high reg
 	push	es			; Copy ES...
@@ -302,6 +304,6 @@
 ALIGN JUMP_ALIGN
 WriteBlockToXtideRev2:
+	UNROLL_SECTORS_IN_CX_TO_QWORDS
 	push	ds
-	eSHR_IM	cx, 2		; Loop unrolling
 	push	es			; Copy ES...
 	pop		ds			; ...to DS
@@ -320,5 +322,5 @@
 ALIGN JUMP_ALIGN
 WriteBlockToFastXtide:
-	times 2 shr	cx, 1	; WORD count to QWORD count
+	UNROLL_SECTORS_IN_CX_TO_QWORDS
 	push	ds
 	push	es
@@ -342,4 +344,5 @@
 ALIGN JUMP_ALIGN
 WriteBlockTo16bitDataPort:
+	xchg	cl, ch		; Sectors to WORDs
 	es					; Source is ES segment
 	rep
@@ -350,5 +353,7 @@
 ALIGN JUMP_ALIGN
 WriteBlockTo32bitDataPort:
-	shr		cx, 1		; WORD count to DWORD count
+	db		0C1h		; SHL
+	db		0E1h		; CX
+	db		7			; 7	(Sectors to DWORDs)
 	es					; Source is ES segment
 	rep
