;******************************************************************************
	page    58,132
	title   IWIRQ
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;   NAME:  IWIRQ.ASM $Revision: 1.4 $
;;  COPYRIGHT:
;;  "Copyright (c) 1994,1995 by e-Tek Labs"
;;
;;       "This software is furnished under a license and may be used,
;;       copied, or disclosed only in accordance with the terms of such
;;       license and with the inclusion of the above copyright notice.
;;       This software or any other copies thereof may not be provided or
;;       otherwise made available to any other person. No title to and
;;       ownership of the software is hereby transfered."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $Log: iwirq.asm $
; Revision 1.4  1995/09/08 11:03:53  teckert
; Rolled in the windows 95 modifications
; Revision 1.3  1995/04/06 18:42:13  teckert
; Added "Boss in a box" to driver
; Revision 1.2  1995/03/20 16:27:01  teckert
; Added file header
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;******************************************************************************
;
;   Functional Description:
;      Provides Virtual Interrupt Handlers for DOS apps or Windows driver.
;
;******************************************************************************

	.386p

;==============================================================================
;                             I N C L U D E S
;==============================================================================

.xlist
	include vmm.inc
	include debug.inc
	include vdmad.inc
	include vpicd.inc
.list
	include viwd.inc

;==============================================================================
;                           I N I T   D A T A
;==============================================================================

VxD_IDATA_SEG

;------------------------------------------------------------------------------
;          G L O B A L   I N I T   D A T A   D E C L A R A T I O N S
;------------------------------------------------------------------------------

VxD_IDATA_ENDS



VxD_LOCKED_DATA_SEG

;------------------------------------------------------------------------------
;                 E X T E R N A L    R E F E R E N C E S
;------------------------------------------------------------------------------

EXTRN _gIWI:NEAR         ; InterWave Info structure
EXTRN _gIW_ResTbl:NEAR   ; Resource Table

VxD_LOCKED_DATA_ENDS


VxD_ICODE_SEG

VxD_ICODE_ENDS

;===========================================================================;
;                   N O N P A G E A B L E   C O D E
;===========================================================================;

VxD_LOCKED_CODE_SEG

;---------------------------------------------------------------------------;
;
;   IW_IRQ_Hw_Int_Proc
;
;   DESCRIPTION:
;       Reflects interrupt to current owner or handles it if no owner.
;
;   ENTRY:
;       EAX = IRQ Handle
;       EBX = Current VM Handle
;
;   EXIT:
;
;   USES:
;       Flags, EAX, EBX
;
;---------------------------------------------------------------------------;

BeginProc IW_IRQ_Hw_Int_Proc, High_Freq
	
	push    eax                             ; save IRQ handle
	
	; find the resource associated with this IRQ
	mov     edi,offset32 _gIW_ResTbl
	mov     ecx,IWAR_NUMIRQRESOURCES
	
IWIP_RESOURCE_LOOP:           
	mov     dx,[edi.iwri_wStatus]
	test    dx,IWRIS_DISABLED
	jnz     short IWIP_NEXT_RESOURCE
	and     dx,IWRIS_TYPE
	cmp     dx,IWRIS_IRQ
	jne     short IWIP_NEXT_RESOURCE
	cmp     eax,[edi.iwri_dwResourceHandle]
	jne     short IWIP_NEXT_RESOURCE
	jmp     short IWIP_FOUND_RESOURCE             
IWIP_NEXT_RESOURCE:     
	add     edi,(size IWRESOURCEINFO)
	loop    IWIP_RESOURCE_LOOP
IWIP_NO_RESOURCE:
	jmp     short IW_Int_Unowned
		
IWIP_FOUND_RESOURCE:
	; EDI points to the resource structure

	mov     eax, [edi.iwri_dwCurOwner]      ; all interrupts go to owner
	or      eax, eax                        ; Q: is there an owner?
	jz      short IW_Int_Unowned            ;   N: set int request to curVM
	mov     ebx, eax                        ;   Y: set int request to owner

IW_Int_Unowned:

	pop     eax                             ; restore IRQ handle

	Assert_VM_Handle ebx

	Trace_Out "<i"

	VxDcall VPICD_Set_Int_Request           ; set int request and return
	clc
	ret

EndProc IW_IRQ_Hw_Int_Proc

;---------------------------------------------------------------------------;
;
;   IW_IRQ_EOI_Proc
;
;   DESCRIPTION:
;       Clears the interrupt request and does the physical EOI
;
;   ENTRY:
;       EAX = IRQ Handle
;       EBX = Current VM Handle
;
;   EXIT:
;
;   USES:
;       Flags
;
;---------------------------------------------------------------------------;

BeginProc IW_IRQ_EOI_Proc, High_Freq

	Trace_Out "i>"

	;
	; Clear int request but make sure that IRQ was physically
	; in service before physically EOI'ing the PIC.
	;

	push    ecx

	VxDCall VPICD_Clear_Int_Request     ; clear virtual IRQ request
	VxDCall VPICD_Get_Complete_Status
	test    ecx, VPICD_Stat_Phys_In_Serv
	jz      SHORT @F
	VxDCall VPICD_Phys_EOI

@@:
	pop     ecx
	clc
	ret

EndProc IW_IRQ_EOI_Proc


;---------------------------------------------------------------------------;
;
;   IW_IRQ_Mask_Changed_Proc
;
;   DESCRIPTION:
;       If the _owning_ VM is masking or unmasking the IRQ, then we need
;       to set the physical state accordingly.  It is perfectly OK for
;       a non-owning VM to mask/unmask the IRQ and not disturb the owning
;       VM.  We can *NOT* assign ownership when the IRQ is [un]masked
;       because some apps will mask all IRQs so they can perform some
;       operations and then reset the PIC to the previous state.  This
;       operation has nothing to do with the SndSys.
;
;       Ownership will only be assigned if someone _asks_ for it through
;       the provided API, or if someone touches ports on the card.
;
;   ENTRY:
;       EAX = IRQ Handle
;       EBX = Current VM Handle
;       ECX = 0 if VM is unmasking
;
;   EXIT:
;
;   USES:
;       Flags
;
;---------------------------------------------------------------------------;

BeginProc IW_IRQ_Mask_Changed_Proc, High_Freq

	push    ecx
	; find the resource associated with this IRQ
	mov     edi,offset32 _gIW_ResTbl
	mov     ecx,IWAR_NUMIRQRESOURCES
	
IWMCP_RESOURCE_LOOP:           
	mov     dx,[edi.iwri_wStatus]
	test    dx,IWRIS_DISABLED
	jnz     short IWMCP_NEXT_RESOURCE
	and     dx,IWRIS_TYPE
	cmp     dx,IWRIS_IRQ
	jne     short IWMCP_NEXT_RESOURCE
	cmp     eax,[edi.iwri_dwResourceHandle]
	jne     short IWMCP_NEXT_RESOURCE
	pop     ecx
	jmp     short IWMCP_FOUND_RESOURCE            
IWMCP_NEXT_RESOURCE:    
	add     edi,(size IWRESOURCEINFO)
	loop    IWMCP_RESOURCE_LOOP
IWMCP_NO_RESOURCE:
	pop     ecx
	jmp     short IW_Auto_Mask
		
IWMCP_FOUND_RESOURCE:
	; EDI points to the resource structure
	
	cmp     [edi.iwri_dwCurOwner], 0   ; Q: is there no owner?
	jz      short IW_Auto_Mask         ;   Y: Auto Mask
	cmp     [edi.iwri_dwCurOwner], ebx ; Q: is this the owner?
	jne     short IW_Mask_Exit         ;   N: hmm...

	jecxz   IW_Mask_Unmasking

IW_Mask_Masking:

	Trace_Out "IW_IRQ_Mask_Changed_Proc: MASKING!"

	VxDcall VPICD_Physically_Mask
	jmp     short IW_Mask_Exit

IW_Mask_Unmasking:

	Trace_Out "IW_IRQ_Mask_Changed_Proc: *UN*MASKING!"

	VxDcall VPICD_Physically_Unmask
	jmp     short IW_Mask_Exit


IW_Auto_Mask:

	Trace_Out "IW_IRQ_Mask_Changed_Proc: Auto-Masking(#ECX)"

ifdef IW_NEW_IRQ_STUFF
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
;   there is no 'owner' of the InterWave hardware--so we will FORCE the mask
;   to the default state (ignoring the caller's request). this is only for
;   the PHYSICAL state--the virtual state remains whatever the VM expects
;   it to be set to...
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;

	test    [gSSI.ssi_wFlags], SSI_FLAG_IRQWASUNMASKED
	jnz     short IW_Mask_Unmasking
	jz      short IW_Mask_Masking
else
	VxDcall VPICD_Set_Auto_Masking
	Assumes_Fall_Through IW_Mask_Exit
endif

IW_Mask_Exit:

	clc
	ret

EndProc IW_IRQ_Mask_Changed_Proc

VxD_LOCKED_CODE_ENDS    

	end

