Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h.asm	(revision 27)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h.asm	(revision 28)
@@ -2,5 +2,5 @@
 ; Project name	:	IDE BIOS
 ; Created date	:	21.9.2007
-; Last update	:	12.4.2010
+; Last update	:	1.8.2010
 ; Author		:	Tomi Tilli
 ; Description	:	Int 13h BIOS functions (Floppy and Hard disk).
@@ -57,4 +57,5 @@
 	call	RamVars_IsFunctionHandledByThisBIOS
 	jnc		SHORT Int13h_DirectCallToAnotherBios
+	;DEBUG_PRINT_DRIVE_AND_FUNCTION
 
 	; Jump to correct BIOS function
@@ -147,4 +148,6 @@
 ;
 ; Int13h_ReturnWithoutSwappingDrives
+; Int13h_StoreErrorCodeToBDAandPopDSDIandReturn
+; Int13h_StoreErrorCodeToBDAandPopXRegsAndReturn
 ; Int13h_PopXRegsAndReturn
 ; Int13h_PopDiDsAndReturn
@@ -160,6 +163,16 @@
 Int13h_ReturnWithoutSwappingDrives:
 	pushf
-	dec		BYTE [RAMVARS.xlateVars+XLATEVARS.bRecurCnt]
-	jmp		SHORT Int13h_StoreErrorCodeAndLeave
+	dec		BYTE [RAMVARS.xlateVars+XLATEVARS.bRecurCnt]	; Preserves CF
+	call	HError_StoreBiosErrorCodeFromAHtoBDA
+	jmp		SHORT Int13h_Leave
+
+ALIGN JUMP_ALIGN
+Int13h_StoreErrorCodeToBDAandPopDSDIandReturn:
+	call	HError_StoreBiosErrorCodeFromAHtoBDA
+	jmp		SHORT Int13h_PopDiDsAndReturn
+
+ALIGN JUMP_ALIGN
+Int13h_StoreErrorCodeToBDAandPopXRegsAndReturn:
+	call	HError_StoreBiosErrorCodeFromAHtoBDA
 ALIGN JUMP_ALIGN
 Int13h_PopXRegsAndReturn:
@@ -173,7 +186,4 @@
 	pushf
 	call	DriveXlate_WhenLeavingInt13h
-Int13h_StoreErrorCodeAndLeave:
-	LOAD_BDA_SEGMENT_TO	ds, di
-	mov		[BDA.bHDLastSt], ah			; Store error code
 Int13h_Leave:
 	popf
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH0h_HReset.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH0h_HReset.asm	(revision 27)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH0h_HReset.asm	(revision 28)
@@ -2,5 +2,5 @@
 ; Project name	:	IDE BIOS
 ; Created date	:	27.9.2007
-; Last update	:	28.7.2010
+; Last update	:	29.7.2010
 ; Author		:	Tomi Tilli
 ; Description	:	Int 13h function AH=0h, Disk Controller Reset.
@@ -47,5 +47,5 @@
 	xor		al, al						; Zero AL...
 	cmp		al, bh						; ...and set CF if error
-	jmp		Int13h_PopXRegsAndReturn
+	jmp		Int13h_StoreErrorCodeToBDAandPopXRegsAndReturn
 
 
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH11h_HRecal.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH11h_HRecal.asm	(revision 27)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH11h_HRecal.asm	(revision 28)
@@ -2,5 +2,5 @@
 ; Project name	:	IDE BIOS
 ; Created date	:	28.9.2007
-; Last update	:	12.4.2010
+; Last update	:	29.7.2010
 ; Author		:	Tomi Tilli
 ; Description	:	Int 13h function AH=11h, Recalibrate.
@@ -55,4 +55,3 @@
 	mov		cx, 1						; Seek to Cylinder 0, Sector 1
 	xor		dh, dh						; Head 0
-	call	AHCh_SeekToCylinder
-	ret
+	jmp		AHCh_SeekToCylinder
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH14h_HDiag.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH14h_HDiag.asm	(revision 27)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH14h_HDiag.asm	(revision 28)
@@ -2,5 +2,5 @@
 ; Project name	:	IDE BIOS
 ; Created date	:	28.9.2007
-; Last update	:	12.4.2010
+; Last update	:	1.8.2010
 ; Author		:	Tomi Tilli
 ; Description	:	Int 13h function AH=14h, Controller Internal Diagnostic.
@@ -33,7 +33,7 @@
 	jnz		SHORT .ReturnError
 	xor		ah, ah						; Zero AH and CF since success
-	jmp		Int13h_PopDiDsAndReturn
+	jmp		Int13h_StoreErrorCodeToBDAandPopDSDIandReturn
 .ReturnError:
 	mov		ah, RET_HD_RESETFAIL
 	stc
-	jmp		Int13h_PopDiDsAndReturn
+	jmp		Int13h_StoreErrorCodeToBDAandPopDSDIandReturn
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH1h_HStatus.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH1h_HStatus.asm	(revision 27)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH1h_HStatus.asm	(revision 28)
@@ -2,5 +2,5 @@
 ; Project name	:	IDE BIOS
 ; Created date	:	27.9.2007
-; Last update	:	12.4.2010
+; Last update	:	29.7.2010
 ; Author		:	Tomi Tilli
 ; Description	:	Int 13h function AH=1h, Read Disk Status.
@@ -28,8 +28,10 @@
 AH1h_HandlerForReadDiskStatus:
 	push	ds
+
 	LOAD_BDA_SEGMENT_TO	ds, di
 	xor		ah, ah					; Zero AH
 	cmp		ah, [BDA.bHDLastSt]		; Set CF if error code is non-zero
-	mov		ah, [BDA.bHDLastSt]
+	xchg	ah, [BDA.bHDLastSt]		; Last error to AH, zero to BDA
+
 	pop		ds
 	jmp		Int13h_PopDiDsAndReturn
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH2h_HRead.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH2h_HRead.asm	(revision 27)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH2h_HRead.asm	(revision 28)
@@ -2,5 +2,5 @@
 ; Project name	:	IDE BIOS
 ; Created date	:	27.9.2007
-; Last update	:	12.4.2010
+; Last update	:	1.8.2010
 ; Author		:	Tomi Tilli
 ; Description	:	Int 13h function AH=2h, Read Disk Sectors.
@@ -63,3 +63,3 @@
 	mov		ah, RET_HD_INVALID			; Invalid value passed
 	stc									; Set CF since error
-	jmp		Int13h_PopDiDsAndReturn
+	jmp		Int13h_StoreErrorCodeToBDAandPopDSDIandReturn
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH8h_HParams.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH8h_HParams.asm	(revision 27)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH8h_HParams.asm	(revision 28)
@@ -41,5 +41,5 @@
 ; Returns L-CHS parameters for drive and total hard disk count.
 ;
-; AH8h_HParams
+; AH8h_GetDriveParameters
 ;	Parameters:
 ;		DL:		Drive number
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm	(revision 27)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AH9h_HInit.asm	(revision 28)
@@ -2,5 +2,5 @@
 ; Project name	:	IDE BIOS
 ; Created date	:	9.12.2007
-; Last update	:	26.4.2010
+; Last update	:	1.8.2010
 ; Author		:	Tomi Tilli
 ; Description	:	Int 13h function AH=9h, Initialize Drive Parameters.
@@ -78,7 +78,10 @@
 .InitializeBlockMode:
 	call	AH9h_InitializeBlockMode
-	;mov	dl, [di+DPT.bDrvNum]		; Restore DL
+	;mov		dl, [di+DPT.bDrvNum]		; Restore DL
 	jc		SHORT .ReturnNotSuccessfull
 	and		BYTE [di+DPT.bReset], ~FLG_RESET_nSETBLOCK
+
+	; Force PIO mode 0
+	;call	AH9h_ForcePioMode0
 
 .ReturnNotSuccessfull:
@@ -149,2 +152,27 @@
 .Return:
 	ret
+
+
+;--------------------------------------------------------------------
+; AH9h_ForcePioMode0
+;	Parameters:
+;		DL:		Drive number
+;		DS:DI:	Ptr to DPT
+;	Returns:
+;		AH:		BIOS Error code
+;		CF:		Cleared if succesfull
+;				Set if any error
+;	Corrupts registers:
+;		AX, BX
+;--------------------------------------------------------------------
+;ALIGN JUMP_ALIGN
+;AH9h_ForcePioMode0:
+;	mov		bh, 08h		; Parameter to Sector Count Register (PIO Flow Control Transfer Mode 0)
+;	mov		ax, 2303h	; Feature: Set transfer mode based on value in Sector Count register
+;	int		13h
+;	jc		SHORT .FailedToForcePIO0
+;	; Debug output here
+;	ret
+;.FailedToForcePIO0:
+;	; Debug output here
+;	ret
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AHDh_HReset.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AHDh_HReset.asm	(revision 27)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/AHDh_HReset.asm	(revision 28)
@@ -2,5 +2,5 @@
 ; Project name	:	IDE BIOS
 ; Created date	:	9.12.2007
-; Last update	:	28.7.2010
+; Last update	:	1.8.2010
 ; Author		:	Tomi Tilli
 ; Description	:	Int 13h function AH=Dh, Reset Hard Disk (Alternate reset).
@@ -26,5 +26,5 @@
 AHDh_HandlerForResetHardDisk:
 	call	AHDh_ResetDrive
-	jmp		Int13h_PopDiDsAndReturn
+	jmp		Int13h_StoreErrorCodeToBDAandPopDSDIandReturn
 
 
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HError.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HError.asm	(revision 27)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HError.asm	(revision 28)
@@ -2,5 +2,5 @@
 ; Project name	:	IDE BIOS
 ; Created date	:	30.11.2007
-; Last update	:	28.7.2010
+; Last update	:	1.8.2010
 ; Author		:	Tomi Tilli
 ; Description	:	Error checking functions for BIOS Hard disk functions.
@@ -10,104 +10,152 @@
 
 ;--------------------------------------------------------------------
-; HError_GetErrorCodeToAHforBitPollingTimeout
+; HError_ProcessErrorsAfterPollingTaskFlag
 ;	Parameters:
-;		AL:		IDE Status Register contents
-;		DX:		IDE Status Register Address
+;		DS:		RAMVARS segment
+;		ES:		BDA segment (zero)
+;		CF:		Set if timeout
+;				Cleared if task flag was properly set
 ;	Returns:
-;		AH:		Hard disk BIOS error code
-;		CF:		Set since error
-;	Corrupts registers:
-;		AL, CX
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-HError_GetErrorCodeToAHforBitPollingTimeout:
-	test	al, FLG_IDE_ST_BSY						; Other bits undefined when BSY set
-	jnz		SHORT HError_GetErrorCodeForStatusReg	; Busy, normal timeout
-	test	al, FLG_IDE_ST_DF | FLG_IDE_ST_CORR | FLG_IDE_ST_ERR
-	jnz		SHORT HError_GetErrorCodeForStatusReg	; Not busy but some error
-	or		al, FLG_IDE_ST_BSY						; Polled bit got never set, force timeout
-	; Fall to HError_GetErrorCodeForStatusReg
-
-;--------------------------------------------------------------------
-; Converts Status Register error to BIOS error code.
-;
-; HError_GetErrorCodeForStatusReg
-;	Parameters:
-;		AL:		IDE Status Register contents
-;		DX:		IDE Status Register Address
-;	Returns:
-;		AH:		Hard disk BIOS error code
-;		CF:		0 if no errors (AH=RET_HD_SUCCESS)
-;				1 if some error
-;	Corrupts registers:
-;		AL, CX
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-HError_GetErrorCodeForStatusReg:
-	; Get Error Register contents to AH
-	mov		ah, al								; Backup Status Reg to AH
-	sub		dx, BYTE REGR_IDE_ST-REGR_IDE_ERROR	; Status Reg to Error Reg
-	in		al, dx								; Read Error Register to AL
-	xchg	al, ah								; Swap status and error
-	add		dx, BYTE REGR_IDE_ST-REGR_IDE_ERROR	; Restore DX
-
-	; Store Register contents to BDA
-	push	ds
-	LOAD_BDA_SEGMENT_TO	ds, cx
-	mov		[HDBDA.wHDStAndErr], ax			; Store Status and Error to BDA
-	pop		ds
-	; Fall to HError_ConvertIdeErrorToBiosRet
-
-;--------------------------------------------------------------------
-; Converts error flags from IDE status and error register contents
-; to BIOS Int 13h return value.
-;
-; HError_ConvertIdeErrorToBiosRet
-;	Parameters:
-;		AL:		Status Register Contents
-;		AH:		Error Register Contents
-;	Returns:
-;		AH:		Hard disk BIOS error code
-;		CF:		0 if no errors (AH=RET_HD_SUCCESS)
-;				1 if any error
+;		AH:		BIOS error code
+;		CF:		Set if error
+;				Cleared if no error
 ;	Corrupts registers:
 ;		AL
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
-HError_ConvertIdeErrorToBiosRet:
+HError_ProcessErrorsAfterPollingTaskFlag:
+	jc		SHORT HError_ProcessTimeoutAfterPollingBSYandSomeOtherStatusBit
+	mov		ax, [es:HDBDA.wHDStAndErr]
+	call	GetBiosErrorCodeToAHfromStatusAndErrorRegistersInAX
+	mov		[es:BDA.bHDLastSt], ah
+	mov		BYTE [es:BDA.bHDTaskFlg], 0
+	ret
+
+;--------------------------------------------------------------------
+; HError_ProcessTimeoutAfterPollingBSYandSomeOtherStatusBit
+; HError_ProcessErrorsAfterPollingBSY
+;	Parameters:
+;		DS:		RAMVARS segment
+;	Returns:
+;		AH:		BIOS error code
+;		CF:		Set if error
+;				Cleared if no error
+;	Corrupts registers:
+;		AL
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+HError_ProcessTimeoutAfterPollingBSYandSomeOtherStatusBit:
+	push	ds
+	push	dx
+
+	call	HError_GetStatusAndErrorRegistersToAXandStoreThemToBDA
+	call	GetBiosErrorCodeToAHfromStatusAndErrorRegistersInAX
+	jc		SHORT StoreErrorCodeFromAHtoBDA
+	mov		ah, RET_HD_TIMEOUT			; Force timeout since no actual error...
+	stc									; ...but wanted bit was never set
+	jmp		SHORT StoreErrorCodeFromAHtoBDA
+
+
+ALIGN JUMP_ALIGN
+HError_ProcessErrorsAfterPollingBSY:
+	push	ds
+	push	dx
+
+	call	HError_GetStatusAndErrorRegistersToAXandStoreThemToBDA
+	call	GetBiosErrorCodeToAHfromStatusAndErrorRegistersInAX
+StoreErrorCodeFromAHtoBDA:
+	mov		[BDA.bHDLastSt], ah			; Store BIOS error code to BDA
+
+	pop		dx
+	pop		ds
+	ret
+
+
+;--------------------------------------------------------------------
+; HError_GetStatusAndErrorRegistersToAXandStoreThemToBDA
+;	Parameters:
+;		DS:		RAMVARS segment
+;	Returns:
+;		AL:		IDE Status Register contents
+;		AH:		IDE Error Register contents
+;		DS:		BDA segment
+;	Corrupts registers:
+;		DX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+HError_GetStatusAndErrorRegistersToAXandStoreThemToBDA:
+	mov		dx, [RAMVARS.wIdeBase]		; Load IDE base port address
+	inc		dx							; Increment to Error Register
+	in		al, dx						; Read Error Register...
+	mov		ah, al						; ...and copy it to AH
+	add		dx, BYTE REGR_IDE_ST - REGR_IDE_ERROR
+	in		al, dx						; Read Status Register to AL
+	; Fall to .StoreStatusAndErrorRegistersFromAXtoBDA
+
+;--------------------------------------------------------------------
+; .StoreStatusAndErrorRegistersFromAXtoBDA
+;	Parameters:
+;		AL:		IDE Status Register contents
+;		AH:		IDE Error Register contents
+;	Returns:
+;		DS:		BDA segment (zero)
+;	Corrupts registers:
+;		DX
+;--------------------------------------------------------------------
+.StoreStatusAndErrorRegistersFromAXtoBDA:
+	LOAD_BDA_SEGMENT_TO	ds, dx
+	mov		[HDBDA.wHDStAndErr], ax
+	ret
+
+
+;--------------------------------------------------------------------
+; GetBiosErrorCodeToAHfromStatusAndErrorRegistersInAX
+;	Parameters:
+;		AL:		IDE Status Register contents
+;		AH:		IDE Error Register contents
+;	Returns:
+;		AH:		BIOS INT 13h error code
+;		CF:		Set if error
+;				Cleared if no error
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+GetBiosErrorCodeToAHfromStatusAndErrorRegistersInAX:
 	test	al, FLG_IDE_ST_BSY
-	jnz		SHORT .TimeoutError
+	jz		SHORT .CheckErrorBitsFromStatusRegisterInAL
+	mov		ah, RET_HD_TIMEOUT
+	jmp		SHORT .ReturnBiosErrorCodeInAH
+
+ALIGN JUMP_ALIGN
+.CheckErrorBitsFromStatusRegisterInAL:
 	test	al, FLG_IDE_ST_DF | FLG_IDE_ST_CORR | FLG_IDE_ST_ERR
-	jnz		SHORT .ReadErrorFromStatusReg
+	jnz		SHORT .ProcessErrorFromStatusRegisterInAL
 	xor		ah, ah					; No errors, zero AH and CF
 	ret
 
-.TimeoutError:
-	mov		ah, RET_HD_TIMEOUT
-	stc
-	ret
-
-; Convert error code based on status or error register
-.ReadErrorFromStatusReg:
+.ProcessErrorFromStatusRegisterInAL:
 	test	al, FLG_IDE_ST_ERR		; Error specified in Error register?
-	jnz		SHORT .ReadErrorFromErrorReg
+	jnz		SHORT .ConvertBiosErrorToAHfromErrorRegisterInAH
 	mov		ah, RET_HD_ECC			; Assume ECC corrected error
 	test	al, FLG_IDE_ST_CORR		; ECC corrected error?
-	jnz		SHORT .Return
+	jnz		SHORT .ReturnBiosErrorCodeInAH
 	mov		ah, RET_HD_CONTROLLER	; Must be Device Fault
-	jmp		SHORT .Return
+	jmp		SHORT .ReturnBiosErrorCodeInAH
 
-; Convert error register to bios error code
-.ReadErrorFromErrorReg:
+.ConvertBiosErrorToAHfromErrorRegisterInAH:
 	push	bx
-	mov		al, ah					; Copy error reg to AL...
-	xor		ah, ah					; ...and zero extend to AX
-	eBSF	bx, ax					; Get bit index to BX
-	mov		ah, RET_HD_STATUSERR	; Error code if Error Reg is zero
-	jz		SHORT .SkipLookup		; Return if error register is zero
+	mov		bx, .rgbRetCodeLookup
+.ErrorBitLoop:
+	rcr		ah, 1					; Set CF if error bit set
+	jc		SHORT .LookupErrorCode
+	inc		bx
+	cmp		bx, .rgbRetCodeLookup + 8
+	jb		SHORT .ErrorBitLoop		; Loop until all bits checked
+.LookupErrorCode:
 	mov		ah, [cs:bx+.rgbRetCodeLookup]
-.SkipLookup:
 	pop		bx
-.Return:
+
+.ReturnBiosErrorCodeInAH:
 	stc								; Set CF since error
 	ret
@@ -122,2 +170,22 @@
 	db	RET_HD_UNCORRECC	; Bit6=UNC, Uncorrectable Data Error
 	db	RET_HD_BADSECTOR	; Bit7=BBK, Bad Block Detected
+	db	RET_HD_STATUSERR	; When Error Register is zero
+
+
+;--------------------------------------------------------------------
+; HError_StoreBiosErrorCodeFromAHtoBDA
+;	Parameters:
+;		AH:		BIOS error code
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		DI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+HError_StoreBiosErrorCodeFromAHtoBDA:
+	push	ds
+	mov		di, 0					; Zero DI and preserve FLAGS
+	mov		ds, di					; Copy BDA segment to DS
+	mov		[BDA.bHDLastSt], ah
+	pop		ds
+	ret
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HIRQ.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HIRQ.asm	(revision 27)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HIRQ.asm	(revision 28)
@@ -2,5 +2,5 @@
 ; Project name	:	IDE BIOS
 ; Created date	:	11.12.2009
-; Last update	:	28.3.2010
+; Last update	:	1.8.2010
 ; Author		:	Tomi Tilli
 ; Description	:	Interrupt handling related functions.
@@ -20,61 +20,72 @@
 ;				Set if any error
 ;	Corrupts registers:
-;		AL, CX
+;		AL
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
 HIRQ_WaitIRQ:
-	; Load BDA segment to ES
 	push	es
-	xor		ax, ax						; Zero AX and clear CF
-	mov		es, ax						; Copy BDA segment (zero) to ES
 
-	; Check if interrupt has already occurred
+	LOAD_BDA_SEGMENT_TO	es, ax
+%ifdef USE_AT	; OS hook only available on AT+ machines
+	call	.NotifyOperatingSystemAboutWaitingForIRQ
+	cmc
+	jnc		SHORT .TaskFlagPollingComplete
+%endif
+	call	.WaitUntilTaskFlagIsSet		; Process errors
+
+ALIGN JUMP_ALIGN
+.TaskFlagPollingComplete:
+	call	HError_ProcessErrorsAfterPollingTaskFlag
+	pop		es
+	ret
+
+;--------------------------------------------------------------------
+; .NotifyOperatingSystemAboutWaitingForIRQ
+;	Parameters:
+;		ES:		BDA segment (zero)
+;	Returns:
+;		CF:		Set if wait done by operating system
+;				Cleared if BIOS must perform task flag polling
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+%ifdef USE_AT
+ALIGN JUMP_ALIGN
+.NotifyOperatingSystemAboutWaitingForIRQ:
 	cli									; Disable interrupts
-	cmp		[es:BDA.bHDTaskFlg], al		; Interrupt ready?
-	jne		SHORT .CheckIdeErrors		;  If so, return
+	xor		ax, ax
+	cmp		al, [es:BDA.bHDTaskFlg]		; Task flag already set?
+	jc		SHORT .ReturnFromWaitNotify	;  If so, skip OS notification
 
-%ifdef USE_AT	; OS hook only available on AT+ machines
-	; OS device busy notification
 	mov		ah, 90h						; Hard disk busy (AX=9000h)
 	int		INTV_SYSTEM_SERVICES		; OS hook, device busy
-	jnc		SHORT .WaitUntilTaskFlagSet	; CF cleared, BIOS handles waiting
-	test	ah, ah						; OS hook supported? (clear CF)
-	jz		SHORT .CheckIdeErrors		;  If so, waiting completed
-ALIGN JUMP_ALIGN
-.WaitUntilTaskFlagSet:
-%endif
+	jnc		SHORT .ReturnFromWaitNotify	; CF cleared, BIOS handles waiting
 
-	; Poll task flag until it has been set by interrupt service routine
-	call	HIRQ_WaitUntilTaskFlagIsSet
-	jc		SHORT .ReturnTimeout		; Return if timeout
-
-ALIGN JUMP_ALIGN
-.CheckIdeErrors:
-	mov		ax, [es:HDBDA.wHDStAndErr]	; Load Status and Error regs stored by ISR
-	call	HError_ConvertIdeErrorToBiosRet
-.ReturnTimeout:
-	mov		BYTE [es:BDA.bHDTaskFlg], 0	; Clear Task Flag
-	pop		es
+	; Make sure that OS hooks are supported, otherwise the CF means unsupported function
+	test	ah, ah						; OS hook supported? (clears CF)
+	jnz		SHORT .ReturnFromWaitNotify	; AH has error, BIOS must do the wait
+	stc									; Set CF since wait done by OS
+.ReturnFromWaitNotify:
 	sti									; Enable interrupts
 	ret
-
+%endif
 
 ;--------------------------------------------------------------------
 ; Polls IRQ Task Flag until it has been set or timeout.
 ;
-; HIRQ_WaitUntilTaskFlagIsSet
+; .WaitUntilTaskFlagIsSet
 ;	Parameters:
 ;		DS:		RAMVARS segment
 ;		ES:		BDA segment
 ;	Returns:
-;		AH:		BIOS Error code
-;		CF:		Cleared if wait succesfull
-;				Set if timeout
+;		CF:		Set if timeout
+;				Cleared if Task Flag set
 ;	Corrupts registers:
-;		AL, CX
+;		AX
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
-HIRQ_WaitUntilTaskFlagIsSet:
-	sti								; Enable interrupts
+.WaitUntilTaskFlagIsSet:
+	push	cx
+
 	mov		cl, B_TIMEOUT_DRQ		; Load timeout ticks
 	call	SoftDelay_InitTimeout	; Initialize timeout counter
@@ -82,19 +93,16 @@
 ALIGN JUMP_ALIGN
 .PollIrqFlag:
-	cli								; Disable interrupts
-	cmp		[es:BDA.bHDTaskFlg], al	; Task flag set?
-	jne		SHORT .TaskFlagIsSet	;  If so, return
+	cli								; Disable interrupt until next HLT
+	cmp		[es:BDA.bHDTaskFlg], al	; Task flag set? (clears CF)
+	jne		SHORT .Return
 	call	SoftDelay_UpdTimeout	; Update timeout
-	jc		SHORT .Timeout			; Return if timeout
-	sti								; Enable interrupts (one instruction delay)
+	jc		SHORT .Return			; Return if timeout
+	sti								; Enable interrupts (STI has delay so HLT will catch all interrupts)
 	hlt								; Sleep until any interrupt
 	jmp		SHORT .PollIrqFlag		; Jump to check if IDE interrupt
-
 ALIGN JUMP_ALIGN
-.TaskFlagIsSet:
-	xor		ah, ah					; Zero AH, clear CF
-	ret
-.Timeout:
-	mov		ah, RET_HD_TIMEOUT		; Load error code for timeout
+.Return:
+	pop		cx
+	sti
 	ret
 
@@ -134,18 +142,18 @@
 ALIGN JUMP_ALIGN
 HIRQ_InterruptServiceRoutineForIrqs2to7:
-	; Acknowledge IDE interrupt by reading status register
 	push	ax
-	call	ISR_IDE_AcknowledgeIdeAndStoreStatusToBDA
+	call	AcknowledgeIdeInterruptAndStoreStatusAndErrorRegistersToBDA
+
 	mov		al, CMD_END_OF_INTERRUPT
-	jmp		SHORT HIRQ_AcknowledgeMasterController
+	jmp		SHORT AcknowledgeMasterInterruptController
 
 ALIGN JUMP_ALIGN
 HIRQ_InterruptServiceRoutineForIrqs8to15:
 	push	ax
-	call	ISR_IDE_AcknowledgeIdeAndStoreStatusToBDA
+	call	AcknowledgeIdeInterruptAndStoreStatusAndErrorRegistersToBDA
 
 	mov		al, CMD_END_OF_INTERRUPT	; Load EOI command to AL
 	out		WPORT_8259SL_COMMAND, al	; Acknowledge Slave 8259
-HIRQ_AcknowledgeMasterController:
+AcknowledgeMasterInterruptController:
 	out		WPORT_8259MA_COMMAND, al	; Acknowledge Master 8259
 
@@ -156,8 +164,6 @@
 %endif
 
-	; Restore registers and return from interrupt
 	pop		ax							; Restore AX
 	iret
-
 
 ;--------------------------------------------------------------------
@@ -166,5 +172,5 @@
 ; also be set.
 ;
-; ISR_IDE_AcknowledgeIdeAndStoreStatusToBDA
+; AcknowledgeIdeInterruptAndStoreStatusAndErrorRegistersToBDA
 ;	Parameters:
 ;		Nothing
@@ -175,23 +181,13 @@
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
-ISR_IDE_AcknowledgeIdeAndStoreStatusToBDA:
+AcknowledgeIdeInterruptAndStoreStatusAndErrorRegistersToBDA:
 	push	ds
 	push	di
 	push	dx
 
-	; Read Status and Error registers.
 	; Reading Status Register acknowledges IDE interrupt
 	call	RamVars_GetSegmentToDS
-	mov		dx, [RAMVARS.wIdeBase]		; Load IDE base port address
-	inc		dx							; Increment to Error Register
-	in		al, dx						; Read Error Register...
-	mov		ah, al						; ...and copy it to AH
-	add		dx, REGR_IDE_ST-REGR_IDE_ERROR
-	in		al, dx						; Read Status Register to AL
-
-	; Store Status and Error register to BDA and set task flag
-	LOAD_BDA_SEGMENT_TO	ds, dx
-	mov		[HDBDA.wHDStAndErr], ax		; Store Status and Error Registers
-	mov		BYTE [BDA.bHDTaskFlg], 0FFh	; Set task flag
+	call	HError_GetStatusAndErrorRegistersToAXandStoreThemToBDA
+	mov		BYTE [BDA.bHDTaskFlg], 0FFh		; Set task flag
 
 	pop		dx
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HPIO.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HPIO.asm	(revision 27)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HPIO.asm	(revision 28)
@@ -2,5 +2,5 @@
 ; Project name	:	IDE BIOS
 ; Created date	:	14.12.2007
-; Last update	:	14.4.2010
+; Last update	:	1.8.2010
 ; Author		:	Tomi Tilli
 ; Description	:	PIO transfer functions.
@@ -168,5 +168,4 @@
 	add		cx, [bp+PIOVARS.wWordsLeft]	; CX to partial block size
 	call	[bp+PIOVARS.fnXfer]			; Transfer possibly partial block
-	call	HStatus_ReadAndIgnoreAlternateStatus
 	jmp		HStatus_WaitBsyDefTime		; Check for errors
 .RetError:
@@ -232,5 +231,5 @@
 HPIO_WriteToDrive:
 	cld										; OUTS to increment SI
-	call	HStatus_WaitDrqDefTime			; Always poll DRQ for first block, get data port to DX
+	call	HStatus_WaitDrqDefTime			; Always poll DRQ for first block, get status reg to DX
 	jc		SHORT .RetError					; Return if error (code in AH)
 	sub		dx, BYTE REGR_IDE_ST			; DX to Data Port address
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HStatus.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HStatus.asm	(revision 27)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HStatus.asm	(revision 28)
@@ -2,5 +2,5 @@
 ; Project name	:	IDE BIOS
 ; Created date	:	15.12.2009
-; Last update	:	28.7.2010
+; Last update	:	1.8.2010
 ; Author		:	Tomi Tilli
 ; Description	:	IDE Status Register polling functions.
@@ -26,9 +26,9 @@
 HStatus_WaitIrqOrRdy:
 	test	BYTE [bx+DPT.bDrvCtrl], FLG_IDE_CTRL_nIEN
-	jnz		SHORT .PollRdySinceIrqsAreDisabled
+	jnz		SHORT .PollRdySinceInterruptsAreDisabled
 	jmp		HIRQ_WaitIRQ
-ALIGN JUMP_ALIGN
-.PollRdySinceIrqsAreDisabled:
-	call	HStatus_ReadAndIgnoreAlternateStatus
+
+ALIGN JUMP_ALIGN
+.PollRdySinceInterruptsAreDisabled:
 	mov		cl, B_TIMEOUT_DRQ				; Load DRQ (not RDY) timeout
 	jmp		SHORT HStatus_WaitRdy			; Jump to poll RDY
@@ -36,28 +36,4 @@
 
 ;--------------------------------------------------------------------
-; Reads Alternate Status Register and ignores result.
-; Alternate Status Register is read to prevent polling host from
-; reading status before it is valid.
-;
-; HStatus_ReadAndIgnoreAlternateStatus
-;	Parameters:
-;		DS:BX:	Ptr to DPT
-;	Returns:
-;		Nothing
-;	Corrupts registers:
-;		AL, CX, DX
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-HStatus_ReadAndIgnoreAlternateStatus:
-	mov		cx, bx							; Backup BX
-	eMOVZX	bx, BYTE [bx+DPT.bIdeOff]		; CS:BX now points to IDEVARS
-	mov		dx, [cs:bx+IDEVARS.wPortCtrl]	; DX = Control Block base port
-	add		dx, BYTE REGR_IDEC_AST			; DX = Alternate Status Register address
-	in		al, dx							; Read Alternate Status Register
-	mov		bx, cx							; Restore BX
-	ret
-
-
-;--------------------------------------------------------------------
 ; Waits until Hard Disk is ready to transfer data.
 ;
@@ -74,19 +50,13 @@
 ALIGN JUMP_ALIGN
 HStatus_WaitIrqOrDrq:
+	test	BYTE [bx+DPT.bDrvCtrl], FLG_IDE_CTRL_nIEN
+	jnz		SHORT .PollDrqSinceInterruptsAreDisabled
+	jmp		HIRQ_WaitIRQ
+
+ALIGN JUMP_ALIGN
+.PollDrqSinceInterruptsAreDisabled:
 	push	dx
 	push	cx
-
-	; Check if interrupts are enabled
-	test	BYTE [bx+DPT.bDrvCtrl], FLG_IDE_CTRL_nIEN
-	jnz		SHORT .PollDRQ					; Poll DRQ if IRQ disabled
-	call	HIRQ_WaitIRQ					; Wait for IRQ
-	jmp		SHORT .Return
-
-ALIGN JUMP_ALIGN
-.PollDRQ:
-	call	HStatus_ReadAndIgnoreAlternateStatus
 	call	HStatus_WaitDrqDefTime
-ALIGN JUMP_ALIGN
-.Return:
 	pop		cx
 	pop		dx
@@ -207,4 +177,6 @@
 HStatus_PollBsyAndFlg:
 	call	SoftDelay_InitTimeout				; Initialize timeout counter
+	in		al, dx								; Discard contents for first read
+												; (should read Alternate Status Register)
 ALIGN JUMP_ALIGN
 .PollLoop:
@@ -218,5 +190,5 @@
 	call	SoftDelay_UpdTimeout				; Update timeout counter
 	jnc		SHORT .PollLoop						; Loop if time left (sets CF on timeout)
-	jmp		HError_GetErrorCodeToAHforBitPollingTimeout
+	jmp		HError_ProcessTimeoutAfterPollingBSYandSomeOtherStatusBit
 
 ;--------------------------------------------------------------------
@@ -239,4 +211,6 @@
 HStatus_PollBsy:
 	call	SoftDelay_InitTimeout				; Initialize timeout counter
+	in		al, dx								; Discard contents for first read
+												; (should read Alternate Status Register)
 ALIGN JUMP_ALIGN
 .PollLoop:
@@ -248,3 +222,3 @@
 ALIGN JUMP_ALIGN
 GetErrorCodeFromPollingToAH:
-	jmp		HError_GetErrorCodeForStatusReg
+	jmp		HError_ProcessErrorsAfterPollingBSY
Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int19h.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int19h.asm	(revision 27)
+++ trunk/XTIDE_Universal_BIOS/Src/Handlers/Int19h.asm	(revision 28)
@@ -2,5 +2,5 @@
 ; Project name	:	IDE BIOS
 ; Created date	:	3.8.2007
-; Last update	:	2.5.2010
+; Last update	:	1.8.2010
 ; Author		:	Tomi Tilli
 ; Description	:	Int 19h BIOS functions (Boot Strap Loader).
@@ -10,5 +10,4 @@
 
 B_READ_RETRY_TIMES	EQU	3	; Number of times to retry
-B_READ_RETRY_DELAY	EQU	3	; Timer ticks between retries
 
 
@@ -110,7 +109,7 @@
 ALIGN JUMP_ALIGN
 .ReadRetryLoop:
-	call	Int19h_LoadFirstSectorFromDLToESBX
+	call	.ResetBootDriveFromDL
+	call	.LoadFirstSectorFromDLtoESBX
 	jnc		SHORT .Return
-	call	Int19h_ResetDriveOrWait
 	dec		di								; Decrement retry counter
 	jnz		SHORT .ReadRetryLoop			; Loop while retries left
@@ -121,7 +120,28 @@
 
 ;--------------------------------------------------------------------
+; .ResetBootDriveFromDL
+;	Parameters:
+;		DL:		Drive to boot from (translated, 00h or 80h)
+;	Returns:
+;		AH:		INT 13h error code
+;		CF:		Cleared if read successfull
+;				Set if any error
+;	Corrupts registers:
+;		AL
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+.ResetBootDriveFromDL:
+	xor		ax, ax							; AH=0h, Disk Controller Reset
+	test	dl, 80h							; Floppy drive?
+	jz		SHORT .ResetDriveFromDL			;  If so, jump to reset
+	mov		ah, 0Dh							; AH=Dh, Reset Hard Disk (Alternate reset)
+.ResetDriveFromDL:
+	int		INTV_DISK_FUNC
+	ret
+
+;--------------------------------------------------------------------
 ; Reads first sector (boot sector) from drive DL to ES:BX.
 ;
-; Int19h_LoadFirstSectorFromDLToESBX
+; .LoadFirstSectorFromDLtoESBX
 ;	Parameters:
 ;		DL:		Drive to boot from (translated, 00h or 80h)
@@ -136,37 +156,9 @@
 ;--------------------------------------------------------------------
 ALIGN JUMP_ALIGN
-Int19h_LoadFirstSectorFromDLToESBX:
+.LoadFirstSectorFromDLtoESBX:
 	mov		ax, 0201h						; Read 1 sector
 	mov		cx, 1							; Cylinder 0, Sector 1
 	xor		dh, dh							; Head 0
 	int		INTV_DISK_FUNC
-	ret
-
-
-;--------------------------------------------------------------------
-; Reset drive controller or waits a while before retrying
-; to load boot sector.
-;
-; Int19h_ResetDriveOrWait
-;	Parameters:
-;		DL:		Drive to boot from (translated, 00h or 80h)
-;		DI:		Retry counter
-;	Returns:
-;		Nothing
-;	Corrupts registers:
-;		CX
-;--------------------------------------------------------------------
-ALIGN JUMP_ALIGN
-Int19h_ResetDriveOrWait:
-	test	di, 1<<0						; Reset on every other retry
-	jnz		SHORT .ResetDrive
-	mov		cx, B_READ_RETRY_DELAY			; Wait for a while
-	jmp		SoftDelay_TimerTicks
-ALIGN JUMP_ALIGN
-.ResetDrive:
-	xor		cx, cx
-	xchg	cx, ax							; AH=0h, Disk Controller Reset
-	int		INTV_DISK_FUNC
-	xchg	ax, cx							; Restore AX
 	ret
 
