mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
161 lines
3.8 KiB
161 lines
3.8 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
isr.c
|
|
|
|
Abstract:
|
|
|
|
This module contains code for the interrupt service routine
|
|
for the Jazz Sound device driver.
|
|
|
|
Author:
|
|
|
|
Robin Speed (robinsp) 20-March-1992
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History:
|
|
|
|
Sameer Dekate ([email protected]) 19-Aug-1992
|
|
- Changes to support the MIPS sound board
|
|
|
|
--*/
|
|
|
|
#include "sound.h"
|
|
|
|
//
|
|
// Driver ISR
|
|
//
|
|
// When we get here, we acknowledge the interrupt from the
|
|
// MIPSSND and simply let the defered processing routine take over
|
|
// to complete the task.
|
|
//
|
|
|
|
|
|
|
|
BOOLEAN
|
|
SoundISR(
|
|
IN PKINTERRUPT pInterrupt,
|
|
IN PVOID Context
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Interrupt service routine for the MIPS sound card.
|
|
|
|
Arguments:
|
|
|
|
pInterrupt - our interrupt
|
|
Contest - Pointer to our global device info
|
|
|
|
|
|
Return Value:
|
|
|
|
TRUE if we handled the interrupt
|
|
|
|
--*/
|
|
{
|
|
PGLOBAL_DEVICE_INFO pGDI;
|
|
UCHAR configval, endianval, regval ;
|
|
PSOUND_REGISTERS pSoundRegisters;
|
|
|
|
pGDI = (PGLOBAL_DEVICE_INFO)Context;
|
|
ASSERT(pGDI->Key == GDI_KEY);
|
|
|
|
//
|
|
// Save current Sound state, and then clear the interrupt(s) by writing
|
|
// back the saved value. This works and is safe because the Interrupt bits
|
|
// are "write zero to clear", the enable bit can't be set if DeviceInterrupt
|
|
// bit is set, and the Channel bit can't be changed unless interrupts and
|
|
// the enable bit are clear.
|
|
//
|
|
|
|
pSoundRegisters = pGDI->SoundHardware.SoundVirtualBase;
|
|
|
|
// Clear the terminal count interrupt, disable interrupts
|
|
endianval = READAUDIO_ENDIAN(&pSoundRegisters);
|
|
WRITEAUDIO_ENDIAN(&pSoundRegisters,
|
|
(endianval & ~(DMA_TCINTR | DMA_TCINTR_ENABLE)));
|
|
|
|
// Turn of Overflow and Underflow interrupts
|
|
regval = READAUDIO_DMACNTRL(&pSoundRegisters);
|
|
configval = READAUDIO_CONFIG(&pSoundRegisters);
|
|
WRITEAUDIO_CONFIG(&pSoundRegisters,
|
|
(configval & ~(REC_OVF_INTR | PLAY_UND_INTR)));
|
|
|
|
|
|
dprintf5("SoundISR:d=0x%x c=0x%x e=0x%x",regval,configval,endianval);
|
|
|
|
if (configval & PLAY_UND_INTR) {
|
|
|
|
dprintf4("U");
|
|
pGDI->GotUnderFlow = 1;
|
|
|
|
// Make sure we stop playing immediately
|
|
WRITEAUDIO_DMACNTRL(&pSoundRegisters, (regval & ~PLAY_ENABLE));
|
|
|
|
}
|
|
|
|
//
|
|
// If a terminal count interrupt has occured (TcInterrupt), then decrement
|
|
// the pending interrupt count and schedule a Dpc to complete the transfer.
|
|
//
|
|
|
|
if ((endianval & DMA_TCINTR) || (configval & PLAY_UND_INTR)) {
|
|
|
|
if ((configval & PLAY_UND_INTR) == 0)
|
|
pGDI->SoundHardware.TcInterruptsPending -= 1;
|
|
|
|
switch (pGDI->Usage) {
|
|
case SoundInterruptUsageWaveIn:
|
|
dprintf5("i");
|
|
IoRequestDpc(pGDI->pWaveInDevObj,
|
|
pGDI->pWaveInDevObj->CurrentIrp,
|
|
NULL);
|
|
break;
|
|
|
|
case SoundInterruptUsageWaveOut:
|
|
dprintf5("o");
|
|
IoRequestDpc(pGDI->pWaveOutDevObj,
|
|
pGDI->pWaveOutDevObj->CurrentIrp,
|
|
NULL);
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
//
|
|
// If DeviceInterrupt (data overflow or underflow), and there are still
|
|
// terminal count interrupts pending, restart controller, else set
|
|
// DeviceBusy flag to false.
|
|
//
|
|
|
|
// if (configval & REC_INTR) {
|
|
// if (pGDI->SoundHardware.TcInterruptsPending != 0) {
|
|
// WRITEAUDIO_DMACNTRL(&pSoundRegisters, (regval | REC_ENABLE));
|
|
// }
|
|
// }
|
|
|
|
//
|
|
// Re-Enable the interrupts
|
|
//
|
|
|
|
WRITEAUDIO_ENDIAN(&pSoundRegisters,
|
|
(endianval & (~DMA_TCINTR | DMA_TCINTR_ENABLE)));
|
|
|
|
//
|
|
// Execution continues in the Deferred Procedure Call when it is scheduled
|
|
// Runs SoundInDeferred() or SoundOutDeferred() depending on REC or PLAY
|
|
//
|
|
|
|
return TRUE;
|
|
|
|
DBG_UNREFERENCED_PARAMETER(pInterrupt);
|
|
}
|
|
|