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
