Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDPT.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDPT.asm	(revision 622)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeDPT.asm	(revision 623)
@@ -133,14 +133,10 @@
 	mov		[di+DPT_ADVANCED_ATA.wMinPioCycleTime], bx
 
-	; We have detected 32-bit controller so change Device Type since
-	; it might have been set to 16-bit on IDEVARS
-	;
-	; Change to 32-bit on 386 builds only. We leave AT builds unchanged for faster troubleshooting
-	; and for uncommon systems, like IBM 486SLC2 processors that can have VLB motherboard even though
-	; the IBM 486SLC2 is externally 16-bit CPU
+	; We have detected 32-bit controller so change Device Type
+	; since it might have been set to 16-bit on IDEVARS
 .ChangeTo32bitDevice:
-%ifdef USE_386
+	; *FIXME* We might need to add code to detect the IBM 486SLC2 CPU (and possibly other
+	; 386+ class CPUs with a 16-bit external bus?) to avoid changing to DEVICE_32BIT_ATA.
 	mov		BYTE [di+DPT_ATA.bDevice], DEVICE_32BIT_ATA
-%endif
 .NoAdvancedControllerDetected:
 %endif	; MODULE_ADVANCED_ATA
Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdePioBlock.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdePioBlock.asm	(revision 622)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdePioBlock.asm	(revision 623)
@@ -43,12 +43,48 @@
 ALIGN JUMP_ALIGN
 IdePioBlock_ReadFromXtideRev1:
-	UNROLL_SECTORS_IN_CX_TO_OWORDS
+%ifdef EXTRA_LOOP_UNROLLING_LARGE
+	UNROLL_SECTORS_IN_CX_TO_32WORDS
+%elifdef EXTRA_LOOP_UNROLLING_SMALL
+	UNROLL_SECTORS_IN_CX_TO_16WORDS
+%else
+	UNROLL_SECTORS_IN_CX_TO_OWORDS
+%endif
 	mov		bl, 8		; Bit mask for toggling data low/high reg
 ALIGN JUMP_ALIGN
-.InswLoop:
-	%rep 8	; WORDs
+.NextIteration:
+%ifdef EXTRA_LOOP_UNROLLING_LARGE
+	%rep 32	; WORDs
 		XTIDE_INSW
 	%endrep
-	loop	.InswLoop
+	dec		cx
+%ifdef USE_386
+	jnz		.NextIteration
+%else
+	jz		SHORT .BlockTransferred
+	jmp		.NextIteration
+
+ALIGN JUMP_ALIGN
+.BlockTransferred:
+%endif
+%elifdef EXTRA_LOOP_UNROLLING_SMALL
+	%rep 16	; WORDs
+		XTIDE_INSW
+	%endrep
+%ifdef USE_186
+	loop	.NextIteration
+%else
+	dec		cx
+	jz		SHORT .BlockTransferred
+	jmp		.NextIteration
+
+ALIGN JUMP_ALIGN
+.BlockTransferred:
+%endif
+%else
+	%rep 8	; WORDs
+		XTIDE_INSW
+	%endrep
+	loop	.NextIteration
+%endif
 	ret
 
@@ -67,11 +103,38 @@
 ALIGN JUMP_ALIGN
 IdePioBlock_ReadFromXtideRev2_Olivetti:
-	UNROLL_SECTORS_IN_CX_TO_OWORDS
-ALIGN JUMP_ALIGN
-.InswLoop:
-	%rep 8	; WORDs
+%ifdef EXTRA_LOOP_UNROLLING_LARGE
+	UNROLL_SECTORS_IN_CX_TO_32WORDS
+%elifdef EXTRA_LOOP_UNROLLING_SMALL
+	UNROLL_SECTORS_IN_CX_TO_16WORDS
+%else
+	UNROLL_SECTORS_IN_CX_TO_OWORDS
+%endif
+ALIGN JUMP_ALIGN
+.NextIteration:
+%ifdef EXTRA_LOOP_UNROLLING_LARGE
+	%rep 32	; WORDs
 		XTIDE_MOD_OLIVETTI_INSW
 	%endrep
-	loop	.InswLoop
+	dec		cx
+%ifdef USE_386
+	jnz		.NextIteration
+%else
+	jz		SHORT .BlockTransferred
+	jmp		.NextIteration
+
+ALIGN JUMP_ALIGN
+.BlockTransferred:
+%endif
+%elifdef EXTRA_LOOP_UNROLLING_SMALL
+	%rep 16	; WORDs
+		XTIDE_MOD_OLIVETTI_INSW
+	%endrep
+	loop	.NextIteration
+%else
+	%rep 8	; WORDs
+		XTIDE_MOD_OLIVETTI_INSW
+	%endrep
+	loop	.NextIteration
+%endif
 	ret
 
@@ -96,13 +159,39 @@
 	rep insb
 	ret
+
 %else ; 808x
-	UNROLL_SECTORS_IN_CX_TO_OWORDS
-ALIGN JUMP_ALIGN
-.ReadNextOword:
+%ifdef EXTRA_LOOP_UNROLLING_LARGE
+	UNROLL_SECTORS_IN_CX_TO_32WORDS
+%elifdef EXTRA_LOOP_UNROLLING_SMALL
+	UNROLL_SECTORS_IN_CX_TO_16WORDS
+%else
+	UNROLL_SECTORS_IN_CX_TO_OWORDS
+%endif
+ALIGN JUMP_ALIGN
+.NextIteration:
+%ifdef EXTRA_LOOP_UNROLLING_LARGE
+	%rep 64	; BYTEs
+		in		al, dx	; Read BYTE
+		stosb			; Store BYTE to [ES:DI]
+	%endrep
+	dec		cx
+	jz		SHORT .BlockTransferred
+	jmp		.NextIteration
+
+ALIGN JUMP_ALIGN
+.BlockTransferred:
+%elifdef EXTRA_LOOP_UNROLLING_SMALL
+	%rep 32	; BYTEs
+		in		al, dx	; Read BYTE
+		stosb			; Store BYTE to [ES:DI]
+	%endrep
+	loop	.NextIteration
+%else
 	%rep 16	; BYTEs
 		in		al, dx	; Read BYTE
 		stosb			; Store BYTE to [ES:DI]
 	%endrep
-	loop	.ReadNextOword
+	loop	.NextIteration
+%endif
 	ret
 %endif
@@ -132,12 +221,30 @@
 
 %else ; 808x
-	UNROLL_SECTORS_IN_CX_TO_OWORDS
-ALIGN JUMP_ALIGN
-.ReadNextOword:
-	%rep 8	; WORDs
+%ifdef EXTRA_LOOP_UNROLLING_LARGE
+	UNROLL_SECTORS_IN_CX_TO_32WORDS
+%elifdef EXTRA_LOOP_UNROLLING_SMALL
+	UNROLL_SECTORS_IN_CX_TO_16WORDS
+%else
+	UNROLL_SECTORS_IN_CX_TO_OWORDS
+%endif
+ALIGN JUMP_ALIGN
+.NextIteration:
+%ifdef EXTRA_LOOP_UNROLLING_LARGE
+	%rep 32	; WORDs
 		in		ax, dx	; Read WORD
 		stosw			; Store WORD to [ES:DI]
 	%endrep
-	loop	.ReadNextOword
+%elifdef EXTRA_LOOP_UNROLLING_SMALL
+	%rep 16	; WORDs
+		in		ax, dx	; Read WORD
+		stosw			; Store WORD to [ES:DI]
+	%endrep
+%else
+	%rep 8	; WORDs
+		in		ax, dx	; Read WORD
+		stosw			; Store WORD to [ES:DI]
+	%endrep
+%endif
+	loop	.NextIteration
 	ret
 %endif
@@ -174,12 +281,39 @@
 ALIGN JUMP_ALIGN
 IdePioBlock_WriteToXtideRev1:
+%ifdef EXTRA_LOOP_UNROLLING_LARGE
+	UNROLL_SECTORS_IN_CX_TO_16WORDS
+%elifdef EXTRA_LOOP_UNROLLING_SMALL
+	UNROLL_SECTORS_IN_CX_TO_OWORDS
+%else
 	UNROLL_SECTORS_IN_CX_TO_QWORDS
+%endif
 	mov		bl, 8		; Bit mask for toggling data low/high reg
 ALIGN JUMP_ALIGN
-.OutswLoop:
+.NextIteration:
+%ifdef EXTRA_LOOP_UNROLLING_LARGE
+	%rep 16	; WORDs
+		XTIDE_OUTSW
+	%endrep
+%ifdef USE_186
+	loop	.NextIteration
+%else
+	dec		cx
+	jz		SHORT .BlockTransferred
+	jmp		.NextIteration
+
+ALIGN JUMP_ALIGN
+.BlockTransferred:
+%endif
+%elifdef EXTRA_LOOP_UNROLLING_SMALL
+	%rep 8	; WORDs
+		XTIDE_OUTSW
+	%endrep
+	loop	.NextIteration
+%else
 	%rep 4	; WORDs
 		XTIDE_OUTSW
 	%endrep
-	loop	.OutswLoop
+	loop	.NextIteration
+%endif
 	ret
 
@@ -198,11 +332,38 @@
 ALIGN JUMP_ALIGN
 IdePioBlock_WriteToXtideRev2:
+%ifdef EXTRA_LOOP_UNROLLING_LARGE
+	UNROLL_SECTORS_IN_CX_TO_16WORDS
+%elifdef EXTRA_LOOP_UNROLLING_SMALL
+	UNROLL_SECTORS_IN_CX_TO_OWORDS
+%else
 	UNROLL_SECTORS_IN_CX_TO_QWORDS
-ALIGN JUMP_ALIGN
-.WriteNextQword:
+%endif
+ALIGN JUMP_ALIGN
+.NextIteration:
+%ifdef EXTRA_LOOP_UNROLLING_LARGE
+	%rep 16	; WORDs
+		XTIDE_MOD_OUTSW
+	%endrep
+%ifdef USE_186
+	loop	.NextIteration
+%else
+	dec		cx
+	jz		SHORT .BlockTransferred
+	jmp		.NextIteration
+
+ALIGN JUMP_ALIGN
+.BlockTransferred:
+%endif
+%elifdef EXTRA_LOOP_UNROLLING_SMALL
+	%rep 8	; WORDs
+		XTIDE_MOD_OUTSW
+	%endrep
+	loop	.NextIteration
+%else
 	%rep 4	; WORDs
 		XTIDE_MOD_OUTSW
 	%endrep
-	loop	.WriteNextQword
+	loop	.NextIteration
+%endif
 	ret
 
@@ -227,12 +388,30 @@
 
 %else ; 808x
+%ifdef EXTRA_LOOP_UNROLLING_LARGE
+	UNROLL_SECTORS_IN_CX_TO_16WORDS
+%elifdef EXTRA_LOOP_UNROLLING_SMALL
+	UNROLL_SECTORS_IN_CX_TO_OWORDS
+%else
 	UNROLL_SECTORS_IN_CX_TO_QWORDS
-ALIGN JUMP_ALIGN
-.WriteNextQword:
+%endif
+ALIGN JUMP_ALIGN
+.NextIteration:
+%ifdef EXTRA_LOOP_UNROLLING_LARGE
+	%rep 32	; BYTEs
+		lodsb			; Load BYTE from [DS:SI]
+		out		dx, al	; Write BYTE
+	%endrep
+%elifdef EXTRA_LOOP_UNROLLING_SMALL
+	%rep 16	; BYTEs
+		lodsb			; Load BYTE from [DS:SI]
+		out		dx, al	; Write BYTE
+	%endrep
+%else
 	%rep 8	; BYTEs
 		lodsb			; Load BYTE from [DS:SI]
 		out		dx, al	; Write BYTE
 	%endrep
-	loop	.WriteNextQword
+%endif
+	loop	.NextIteration
 	ret
 %endif
@@ -260,12 +439,30 @@
 
 %else ; 808x
+%ifdef EXTRA_LOOP_UNROLLING_LARGE
+	UNROLL_SECTORS_IN_CX_TO_16WORDS
+%elifdef EXTRA_LOOP_UNROLLING_SMALL
+	UNROLL_SECTORS_IN_CX_TO_OWORDS
+%else
 	UNROLL_SECTORS_IN_CX_TO_QWORDS
-ALIGN JUMP_ALIGN
-.WriteNextQword:
+%endif
+ALIGN JUMP_ALIGN
+.NextIteration:
+%ifdef EXTRA_LOOP_UNROLLING_LARGE
+	%rep 16	; WORDs
+		lodsw			; Load WORD from [DS:SI]
+		out		dx, ax	; Write WORD
+	%endrep
+%elifdef EXTRA_LOOP_UNROLLING_SMALL
+	%rep 8	; WORDs
+		lodsw			; Load WORD from [DS:SI]
+		out		dx, ax	; Write WORD
+	%endrep
+%else
 	%rep 4	; WORDs
 		lodsw			; Load WORD from [DS:SI]
 		out		dx, ax	; Write WORD
 	%endrep
-	loop	.WriteNextQword
+%endif
+	loop	.NextIteration
 	ret
 %endif
