Index: trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HIRQ.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS/Src/Handlers/Int13h/Common/HIRQ.asm	(revision 3)
+++ 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
