Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm	(revision 181)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm	(revision 218)
@@ -5,10 +5,11 @@
 ; This struct must not be larger than IDEPACK without INTPACK.
 struc PIOVARS
-	.wBlocksLeft			resb	2
-	.wBlockSize				resb	2	; Block size in WORDs (256...32768)
-	.wDataPort				resb	2
-	.bSectorsInLastBlock:	resb	1
-							resb	1	; Offset 7 = IDEPACK.bDeviceControl
-	.fnXfer					resb	2	; Offset to transfer function
+	.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, 
+							resb	1	; 7, IDEPACK.bDeviceControl
+	.wDataPort				resb	2	; 8, IDE Data Port
+	.fnXfer					resb	2	; 10, Offset to transfer function
 endstruc
 
@@ -22,16 +23,17 @@
 ;		AL:		IDE command that was used to start the transfer
 ;				(all PIO read and write commands including Identify Device)
-;		ES:SI:	Ptr to destination buffer or source data
+;		ES:SI:	Ptr to normalized data buffer
 ;		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, CX, DX, SI, ES
+;		AL, BX, DX, SI, ES
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
 IdeTransfer_StartWithCommandInAL:
-	mov		ah, [bp+IDEPACK.bSectorCountHighExt]
+	mov		ah, [bp+IDEPACK.bSectorCount]
 
 	; Are we reading or writing?
@@ -43,8 +45,6 @@
 	; Prepare to read data to ESSI
 	mov		bx, g_rgfnPioRead
-	mov		al, [bp+IDEPACK.bSectorCount]
-	call	InitializePiovarsInSSBPwithSectorCountInAX
+	call	InitializePiovarsInSSBPwithSectorCountInAH
 	xchg	si, di
-	call	Registers_NormalizeESDI
 	jmp		SHORT ReadFromDrive
 
@@ -52,7 +52,5 @@
 .PrepareToWriteDataFromESSI:
 	mov		bx, g_rgfnPioWrite
-	mov		al, [bp+IDEPACK.bSectorCount]
-	call	InitializePiovarsInSSBPwithSectorCountInAX
-	call	Registers_NormalizeESSI
+	call	InitializePiovarsInSSBPwithSectorCountInAH
 	; Fall to WriteToDrive
 
@@ -66,8 +64,9 @@
 ;	Returns:
 ;		AH:		BIOS Error code
+;		CX:		Number of successfully transferred sectors
 ;		CF:		0 if transfer succesfull
 ;				1 if any error
 ;	Corrupts registers:
-;		AL, BX, CX, DX, SI, ES
+;		AL, BX, DX, SI, ES
 ;--------------------------------------------------------------------
 WriteToDrive:
@@ -75,44 +74,33 @@
 	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRQ)
 	call	IdeWait_PollStatusFlagInBLwithTimeoutInBH
-	jc		SHORT .ReturnWithTransferErrorInAH
-ALIGN JUMP_ALIGN
-.WriteNextBlock:
+	jc		SHORT ReturnWithTransferErrorInAH
+
+ALIGN JUMP_ALIGN
+.WriteNextBlockToDrive:
+	mov		cx, [bp+PIOVARS.wWordsInBlock]
 	mov		dx, [bp+PIOVARS.wDataPort]
-	dec		WORD [bp+PIOVARS.wBlocksLeft]		; Transferring last (possibly partial) block?
-	jz		SHORT .XferLastBlock				;  If so, jump to transfer
-	mov		cx, [bp+PIOVARS.wBlockSize]			; Load block size in WORDs
-	call	[bp+PIOVARS.fnXfer]					; Transfer full block
-
-	; Normalize pointer when necessary
-	mov		ax, si
-	shr		ax, 1								; WORD offset
-	add		ax, [bp+PIOVARS.wBlockSize]
-	jns		SHORT .WaitUntilReadyToTransferNextBlock
-	call	Registers_NormalizeESSI
-
-ALIGN JUMP_ALIGN
-.WaitUntilReadyToTransferNextBlock:
-%ifdef USE_186
-	push	.WriteNextBlock
-	jmp		IdeWait_IRQorDRQ
-%else
-	call	IdeWait_IRQorDRQ
-	jnc		SHORT .WriteNextBlock
-%endif
-.ReturnWithTransferErrorInAH:
-	ret
-
-ALIGN JUMP_ALIGN
-.XferLastBlock:
-	xor		cx, cx
+	cmp		[bp+PIOVARS.wWordsLeft], cx
+	jbe		SHORT .WriteLastBlockToDrive
+	call	[bp+PIOVARS.fnXfer]
+
+	; Wait until ready for next block and check for errors
+	call	IdeWait_IRQorDRQ					; Wait until ready to transfer
+	jc		SHORT ReturnWithTransferErrorInAH
+
+	; Increment number of successfully written WORDs
+	mov		ax, [bp+PIOVARS.wWordsInBlock]
+	sub		[bp+PIOVARS.wWordsLeft], ax
+	add		[bp+PIOVARS.wWordsDone], ax
+	jmp		SHORT .WriteNextBlockToDrive
+
+ALIGN JUMP_ALIGN
+.WriteLastBlockToDrive:
+	mov		cx, [bp+PIOVARS.wWordsLeft]
+	call	[bp+PIOVARS.fnXfer]					; Transfer possibly partial block
+
+	; Check for errors in last block
 	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRDY)
-	mov		ch, [bp+PIOVARS.bSectorsInLastBlock]; CX = Partial block size in WORDs
-%ifdef USE_186
-	push	IdeWait_IRQorStatusFlagInBLwithTimeoutInBH
-	jmp		[bp+PIOVARS.fnXfer]
-%else
-	call	[bp+PIOVARS.fnXfer]					; Transfer possibly partial block
-	jmp		IdeWait_IRQorStatusFlagInBLwithTimeoutInBH	; Check for errors
-%endif
+	call	IdeWait_PollStatusFlagInBLwithTimeoutInBH
+	jmp		SHORT ReturnWithTransferErrorInAH
 
 
@@ -126,8 +114,9 @@
 ;		DS:DI:	Ptr to DPT (in RAMVARS segment)
 ;		AH:		BIOS Error code
+;		CX:		Number of successfully transferred sectors
 ;		CF:		0 if transfer succesfull
 ;				1 if any error
 ;	Corrupts registers:
-;		AL, BX, CX, DX, SI, ES
+;		AL, BX, DX, SI, ES
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
@@ -136,42 +125,51 @@
 	xchg	di, si								; DS:DI now points DPT
 	call	IdeWait_IRQorDRQ					; Wait until ready to transfer
-	jc		SHORT WriteToDrive.ReturnWithTransferErrorInAH
+	jc		SHORT ReturnWithTransferErrorInAH
 	xchg	si, di								; ES:DI now points buffer
 
-	; Transfer full or last (possible partial) block
+ALIGN JUMP_ALIGN
+.ReadNextBlockFromDrive:
+	mov		cx, [bp+PIOVARS.wWordsInBlock]
 	mov		dx, [bp+PIOVARS.wDataPort]
-	dec		WORD [bp+PIOVARS.wBlocksLeft]
-	jz		SHORT .XferLastBlock
-	mov		cx, [bp+PIOVARS.wBlockSize]			; Load block size in WORDs
-	call	[bp+PIOVARS.fnXfer]					; Transfer full block
-
-	; Normalize pointer when necessary
-	mov		ax, di
-	shr		ax, 1								; WORD offset
-	add		ax, [bp+PIOVARS.wBlockSize]
-	jns		SHORT ReadFromDrive
-%ifdef USE_186
-	push	ReadFromDrive
-	jmp		Registers_NormalizeESDI
-%else
-	call	Registers_NormalizeESDI
-	jmp		SHORT ReadFromDrive					; Loop while blocks left
-%endif
-
-
-ALIGN JUMP_ALIGN
-.XferLastBlock:
-	xor		cx, cx
-	mov		ch, [bp+PIOVARS.bSectorsInLastBlock]; CX = Partial block size in WORDs
+	cmp		[bp+PIOVARS.wWordsLeft], cx
+	jbe		SHORT .ReadLastBlockFromDrive
+	call	[bp+PIOVARS.fnXfer]
+
+	; Wait until ready for next block and check for errors
+	xchg	di, si								; DS:DI now points DPT
+	call	IdeWait_IRQorDRQ					; Wait until ready to transfer
+	jc		SHORT ReturnWithTransferErrorInAH
+	xchg	si, di								; ES:DI now points buffer
+
+	; Increment number of successfully read WORDs
+	mov		ax, [bp+PIOVARS.wWordsInBlock]
+	sub		[bp+PIOVARS.wWordsLeft], ax
+	add		[bp+PIOVARS.wWordsDone], ax
+	jmp		SHORT .ReadNextBlockFromDrive
+
+ALIGN JUMP_ALIGN
+.ReadLastBlockFromDrive:
+	mov		cx, [bp+PIOVARS.wWordsLeft]
 	call	[bp+PIOVARS.fnXfer]					; Transfer possibly partial block
+
+	; Check for errors in last block
 	mov		di, si								; DS:DI now points DPT
 	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRDY)
-	jmp		IdeWait_PollStatusFlagInBLwithTimeoutInBH
-
-
-;--------------------------------------------------------------------
-; InitializePiovarsInSSBPwithSectorCountInAX
-;	Parameters:
-;		AX:		Number of sectors to transfer (1...65535)
+	call	IdeWait_PollStatusFlagInBLwithTimeoutInBH
+
+	; 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
+	ret
+
+
+;--------------------------------------------------------------------
+; InitializePiovarsInSSBPwithSectorCountInAH
+;	Parameters:
+;		AH:		Number of sectors to transfer (1...128)
 ;		BX:		Offset to transfer function lookup table
 ;		DS:DI:	Ptr to DPT (in RAMVARS segment)
@@ -183,21 +181,12 @@
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
-InitializePiovarsInSSBPwithSectorCountInAX:
-	; Store number of blocks to transfer
-	eMOVZX	cx, BYTE [di+DPT_ATA.bSetBlock]		; Block size in sectors
-	xor		dx, dx		; DX:AX = Sectors to transfer (1...65535)
-	div		cx			; AX = Full blocks to transfer
-	test	dx, dx
-	mov		dh, cl		; DH = Full block size if no partial blocks to transfer
-	jz		SHORT .NoPartialBlocksToTransfer
-	inc		ax			; Partial block
-	mov		dh, dl		; DH = Size of partial block in sectors
-.NoPartialBlocksToTransfer:
-	mov		[bp+PIOVARS.wBlocksLeft], ax
-	mov		[bp+PIOVARS.bSectorsInLastBlock], dh
-
-	; Store block size in WORDs
-	xchg	ch, cl		; CX = Block size in WORDs
-	mov		[bp+PIOVARS.wBlockSize], cx
+InitializePiovarsInSSBPwithSectorCountInAH:
+	; Store sizes
+	xor		al, al
+	mov		[bp+PIOVARS.wWordsLeft], ax
+	cbw
+	mov		[bp+PIOVARS.wWordsDone], ax			; Zero
+	mov		ah, [di+DPT_ATA.bSetBlock]
+	mov		[bp+PIOVARS.wWordsInBlock], ax
 
 	; Get transfer function based on bus type
