Index: trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm	(revision 238)
+++ trunk/XTIDE_Universal_BIOS/Src/Device/IDE/IdeTransfer.asm	(revision 242)
@@ -35,32 +35,21 @@
 ALIGN JUMP_ALIGN
 IdeTransfer_StartWithCommandInAL:
-	mov		ah, [bp+IDEPACK.bSectorCount]
-
 	; 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
-	jnz		SHORT .PrepareToWriteDataFromESSI
+	mov		ah, [bp+IDEPACK.bSectorCount]
+	jnz		SHORT WriteToDrive
 	cmp		al, COMMAND_WRITE_MULTIPLE
-	je		SHORT .PrepareToWriteDataFromESSI
-
-	; Prepare to read data to ESSI
-	mov		bx, g_rgfnPioRead
-	call	InitializePiovarsInSSBPwithSectorCountInAH
-	xchg	si, di
-	jmp		SHORT ReadFromDrive
-
-ALIGN JUMP_ALIGN
-.PrepareToWriteDataFromESSI:
-	mov		bx, g_rgfnPioWrite
-	call	InitializePiovarsInSSBPwithSectorCountInAH
-	; Fall to WriteToDrive
-
-
-;--------------------------------------------------------------------
-; WriteToDrive
-;	Parameters:
+	je		SHORT WriteToDrive
+	; Fall to ReadFromDrive
+
+;--------------------------------------------------------------------
+; ReadFromDrive
+;	Parameters:
+;		AH:		Number of sectors to transfer (1...128)
+;		ES:SI:	Normalized ptr to buffer to receive data
 ;		DS:DI:	Ptr to DPT (in RAMVARS segment)
-;		ES:SI:	Normalized ptr to buffer containing data
 ;		SS:BP:	Ptr to PIOVARS
 ;	Returns:
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
 ;		AH:		BIOS Error code
 ;		CX:		Number of successfully transferred sectors
@@ -70,5 +59,77 @@
 ;		AL, BX, DX, SI, ES
 ;--------------------------------------------------------------------
+ReadFromDrive:
+	; Prepare to read data to ESSI
+	mov		bx, g_rgfnPioRead
+	call	InitializePiovarsInSSBPwithSectorCountInAH
+
+	; Wait until drive is ready to transfer
+	call	IdeWait_IRQorDRQ					; Wait until ready to transfer
+	jc		SHORT ReturnWithTransferErrorInAH
+	xchg	si, di								; ES:DI now points buffer
+
+	mov		cx, [bp+PIOVARS.wWordsInBlock]
+
+ALIGN JUMP_ALIGN
+.ReadNextBlockFromDrive:
+	mov		dx, [bp+PIOVARS.wDataPort]
+	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		cx, [bp+PIOVARS.wWordsInBlock]
+	sub		[bp+PIOVARS.wWordsLeft], cx
+	add		[bp+PIOVARS.wWordsDone], cx
+	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
+CheckErrorsAfterTransferringLastBlock:
+	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRDY)
+	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
+
+
+;--------------------------------------------------------------------
+; WriteToDrive
+;	Parameters:
+;		AH:		Number of sectors to transfer (1...128)
+;		DS:DI:	Ptr to DPT (in RAMVARS segment)
+;		ES:SI:	Normalized ptr to buffer containing data
+;		SS:BP:	Ptr to PIOVARS
+;	Returns:
+;		AH:		BIOS Error code
+;		CX:		Number of successfully transferred sectors
+;		CF:		0 if transfer succesfull
+;				1 if any error
+;	Corrupts registers:
+;		AL, BX, DX, SI, ES
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
 WriteToDrive:
+	; Prepare to write data from ESSI
+	mov		bx, g_rgfnPioWrite
+	call	InitializePiovarsInSSBPwithSectorCountInAH
+
 	; Always poll when writing first block (IRQs are generated for following blocks)
 	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRQ)
@@ -76,7 +137,8 @@
 	jc		SHORT ReturnWithTransferErrorInAH
 
+	mov		cx, [bp+PIOVARS.wWordsInBlock]
+
 ALIGN JUMP_ALIGN
 .WriteNextBlockToDrive:
-	mov		cx, [bp+PIOVARS.wWordsInBlock]
 	mov		dx, [bp+PIOVARS.wDataPort]
 	cmp		[bp+PIOVARS.wWordsLeft], cx
@@ -89,7 +151,7 @@
 
 	; Increment number of successfully written WORDs
-	mov		ax, [bp+PIOVARS.wWordsInBlock]
-	sub		[bp+PIOVARS.wWordsLeft], ax
-	add		[bp+PIOVARS.wWordsDone], ax
+	mov		cx, [bp+PIOVARS.wWordsInBlock]
+	sub		[bp+PIOVARS.wWordsLeft], cx
+	add		[bp+PIOVARS.wWordsDone], cx
 	jmp		SHORT .WriteNextBlockToDrive
 
@@ -107,68 +169,4 @@
 
 ;--------------------------------------------------------------------
-; ReadFromDrive
-;	Parameters:
-;		ES:DI:	Normalized ptr to buffer to recieve data
-;		DS:SI:	Ptr to DPT (in RAMVARS segment)
-;		SS:BP:	Ptr to PIOVARS
-;	Returns:
-;		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, DX, SI, ES
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-ReadFromDrive:
-	; Wait until drive is ready to transfer
-	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
-
-ALIGN JUMP_ALIGN
-.ReadNextBlockFromDrive:
-	mov		cx, [bp+PIOVARS.wWordsInBlock]
-	mov		dx, [bp+PIOVARS.wDataPort]
-	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
-CheckErrorsAfterTransferringLastBlock:
-	mov		bx, TIMEOUT_AND_STATUS_TO_WAIT(TIMEOUT_DRQ, FLG_STATUS_DRDY)
-	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:
@@ -180,5 +178,5 @@
 ;		Nothing
 ;	Corrupts registers:
-;		AX, BX, CX, DX
+;		AX, BX, DX
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
@@ -187,17 +185,17 @@
 	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		ah, [di+DPT_ATA.bSetBlock]
-	mov		[bp+PIOVARS.wWordsInBlock], ax
 
 	; Get transfer function based on bus type
 	xchg	ax, bx								; Lookup table offset to AX
-	eMOVZX	bx, BYTE [di+DPT.bIdevarsOffset]	; CS:BX now points to IDEVARS
+	mov		bl, [di+DPT.bIdevarsOffset]			; CS:BX now points to IDEVARS
 	mov		dx, [cs:bx+IDEVARS.wPort]			; Load IDE Data port address
 	mov		bl, [cs:bx+IDEVARS.bDevice]			; Load device type to BX
 	add		bx, ax
+	mov		[bp+PIOVARS.wDataPort], dx
 	mov		ax, [cs:bx]							; Load offset to transfer function
-	mov		[bp+PIOVARS.wDataPort], dx
 	mov		[bp+PIOVARS.fnXfer], ax
 	ret
@@ -213,5 +211,5 @@
 ;		CX:		Block size in WORDs
 ;		DX:		IDE Data port address
-;		ES:DI:	Normalized ptr to buffer to recieve data
+;		ES:DI:	Normalized ptr to buffer to receive data
 ;	Returns:
 ;		Nothing
@@ -236,6 +234,9 @@
 SingleByteRead:
 %ifdef USE_186	; INS instruction available
+	dec		cx			; Avoid overflowing CX on a 128 sector transfer
 	shl		cx, 1		; WORD count to BYTE count
+	inc		cx
 	rep insb
+	insb
 %else			; If 8088/8086
 	shr		cx, 1		; WORD count to DWORD count
@@ -328,7 +329,10 @@
 SingleByteWrite:
 %ifdef USE_186	; OUTS instruction available
+	dec		cx			; Avoid overflowing CX on a 128 sector transfer
 	shl		cx, 1		; WORD count to BYTE count
+	inc		cx
 	es					; Source is ES segment
 	rep outsb
+	es outsb
 %else			; If 8088/8086
 	shr		cx, 1		; WORD count to DWORD count
@@ -386,5 +390,4 @@
 
 
-
 ; Lookup tables to get transfer function based on bus type
 ALIGN WORD_ALIGN
