📄 mpu.cpp
字号:
_DbgPrintF(DEBUGLVL_TERSE,("SynchronizedMPUWrite failed (0x%08x)",ntStatus));
break;
}
}
// if (context->Miniport->m_NumCaptureStreams)
{
readStatus = MPUInterruptServiceRoutine(InterruptSync,PVOID(context->Miniport));
}
return ntStatus;
}
#define kMPUPollTimeout 2
#pragma code_seg()
/*****************************************************************************
* TryLegacyMPU()
*****************************************************************************
* See if the MPU401 is free.
*/
BOOLEAN
TryLegacyMPU
(
IN PUCHAR PortBase
)
{
BOOLEAN success;
USHORT numPolls;
UCHAR status;
_DbgPrintF(DEBUGLVL_BLAB, ("TryLegacyMPU"));
numPolls = 0;
while (numPolls < kMPUPollTimeout)
{
status = READ_PORT_UCHAR(PortBase + MPU401_REG_STATUS);
if (UartFifoOkForWrite(status)) // Is this a good time to write data?
{
break;
}
numPolls++;
}
if (numPolls >= kMPUPollTimeout)
{
success = FALSE;
_DbgPrintF(DEBUGLVL_BLAB, ("TryLegacyMPU failed"));
}
else
{
success = TRUE;
}
return success;
}
#pragma code_seg()
/*****************************************************************************
* WriteLegacyMPU()
*****************************************************************************
* Write a byte out to the MPU401.
*/
NTSTATUS
WriteLegacyMPU
(
IN PUCHAR PortBase,
IN BOOLEAN IsCommand,
IN UCHAR Value
)
{
_DbgPrintF(DEBUGLVL_BLAB, ("WriteLegacyMPU"));
NTSTATUS ntStatus = STATUS_IO_DEVICE_ERROR;
if (!PortBase)
{
_DbgPrintF(DEBUGLVL_TERSE, ("O: PortBase is zero\n"));
return ntStatus;
}
PUCHAR deviceAddr = PortBase + MPU401_REG_DATA;
if (IsCommand)
{
deviceAddr = PortBase + MPU401_REG_COMMAND;
}
ULONGLONG startTime = PcGetTimeInterval(0);
while (PcGetTimeInterval(startTime) < GTI_MILLISECONDS(50))
{
UCHAR status
= READ_PORT_UCHAR(PortBase + MPU401_REG_STATUS);
if (UartFifoOkForWrite(status)) // Is this a good time to write data?
{ // yep (Jon comment)
WRITE_PORT_UCHAR(deviceAddr,Value);
#if kTurnOnKdPrint
KdPrint(("'Mi:O: %02X\n",Value));
#endif // kTurnOnKdPrint
_DbgPrintF(DEBUGLVL_BLAB, ("WriteLegacyMPU emitted 0x%02x",Value));
ntStatus = STATUS_SUCCESS;
break;
}
}
return ntStatus;
}
#pragma code_seg()
/*****************************************************************************
* CMiniportMidiStreamUart::Read()
*****************************************************************************
* Reads incoming MIDI data.
*/
STDMETHODIMP
CMiniportMidiStreamUart::
Read
(
IN PVOID BufferAddress,
IN ULONG Length,
OUT PULONG BytesRead
)
{
ASSERT(BufferAddress);
ASSERT(BytesRead);
*BytesRead = 0;
if (m_fCapture)
{
DEFERREDREADCONTEXT context;
context.BufferAddress = BufferAddress;
context.Length = Length;
context.BytesRead = BytesRead;
context.pMPUInputBufferHead = &(m_pMiniport->m_MPUInputBufferHead);
context.MPUInputBufferTail = m_pMiniport->m_MPUInputBufferTail;
context.MPUInputBuffer = m_pMiniport->m_MPUInputBuffer;
if (*(context.pMPUInputBufferHead) != context.MPUInputBufferTail)
{
//
// More data is available.
// No need to touch the hardware, just read from our SW FIFO.
//
return (DeferredLegacyRead(m_pMiniport->m_pInterruptSync,PVOID(&context)));
}
else
{
return STATUS_SUCCESS;
}
}
else
{
return STATUS_INVALID_DEVICE_REQUEST;
}
}
#pragma code_seg()
/*****************************************************************************
* DeferredLegacyRead()
*****************************************************************************
* Synchronized routine to read incoming MIDI data.
* We have already read the bytes in, and now the Port wants them.
*/
NTSTATUS
DeferredLegacyRead
(
IN PINTERRUPTSYNC InterruptSync,
IN PVOID DynamicContext
)
{
ASSERT(InterruptSync);
ASSERT(DynamicContext);
PDEFERREDREADCONTEXT context = PDEFERREDREADCONTEXT(DynamicContext);
ASSERT(context->BufferAddress);
ASSERT(context->BytesRead);
NTSTATUS ntStatus = STATUS_SUCCESS;
PUCHAR pDest = PUCHAR(context->BufferAddress);
PULONG pMPUInputBufferHead = context->pMPUInputBufferHead;
ULONG MPUInputBufferTail = context->MPUInputBufferTail;
ULONG bytesRead = 0;
ASSERT(pMPUInputBufferHead);
ASSERT(context->MPUInputBuffer);
while ( (*pMPUInputBufferHead != MPUInputBufferTail)
&& (bytesRead < context->Length) )
{
*pDest = context->MPUInputBuffer[*pMPUInputBufferHead];
pDest++;
bytesRead++;
*pMPUInputBufferHead = *pMPUInputBufferHead + 1;
//
// Wrap FIFO position when reaching the buffer size.
//
if (*pMPUInputBufferHead >= kMPUInputBufferSize)
{
*pMPUInputBufferHead = 0;
}
}
*context->BytesRead = bytesRead;
return ntStatus;
}
#pragma code_seg()
/*****************************************************************************
* MPUInterruptServiceRoutine()
*****************************************************************************
* ISR.
*/
NTSTATUS
MPUInterruptServiceRoutine
(
IN PINTERRUPTSYNC InterruptSync,
IN PVOID DynamicContext
)
{
_DbgPrintF(DEBUGLVL_BLAB, ("MPUInterruptServiceRoutine"));
ULONGLONG startTime;
ASSERT(DynamicContext);
NTSTATUS ntStatus;
BOOL newBytesAvailable;
CMiniportMidiUart *that;
that = (CMiniportMidiUart *) DynamicContext;
newBytesAvailable = FALSE;
ntStatus = STATUS_UNSUCCESSFUL;
UCHAR portStatus = 0xff;
//
// Read the MPU status byte.
//
if (that->m_pPortBase)
{
portStatus =
READ_PORT_UCHAR(that->m_pPortBase + MPU401_REG_STATUS);
//
// If there is outstanding work to do and there is a port-driver for
// the MPU miniport...
//
if (UartFifoOkForRead(portStatus) && that->m_pPort)
{
startTime = PcGetTimeInterval(0);
while ( (PcGetTimeInterval(startTime) < GTI_MILLISECONDS(50))
&& (UartFifoOkForRead(portStatus)) )
{
UCHAR uDest = READ_PORT_UCHAR(that->m_pPortBase + MPU401_REG_DATA);
if ( (that->m_KSStateInput == KSSTATE_RUN)
&& (that->m_NumCaptureStreams)
)
{
#if kTurnOnKdPrint
KdPrint(("'Mi:\t\tI: %02X\n",uDest));
#endif // kTurnOnKdPrint
ULONG buffHead = that->m_MPUInputBufferHead;
if ( (that->m_MPUInputBufferTail + 1 == buffHead)
|| (that->m_MPUInputBufferTail + 1 - kMPUInputBufferSize == buffHead))
{
_DbgPrintF(DEBUGLVL_TERSE,("*****MPU Input Buffer Overflow*****"));
}
else
{
newBytesAvailable = TRUE;
// ...place the data in our FIFO...
that->m_MPUInputBuffer[that->m_MPUInputBufferTail] = uDest;
ASSERT(that->m_MPUInputBufferTail < kMPUInputBufferSize);
that->m_MPUInputBufferTail++;
if (that->m_MPUInputBufferTail >= kMPUInputBufferSize)
{
that->m_MPUInputBufferTail = 0;
}
}
}
#if kTurnOnKdPrint
else
{
KdPrint(("'Mi:\t\tI: %02X XXX\n",uDest));
}
#endif // kTurnOnKdPrint
//
// Look for more MIDI data.
//
portStatus =
READ_PORT_UCHAR(that->m_pPortBase + MPU401_REG_STATUS);
} // either there's no data or we ran too long
if (newBytesAvailable)
{
//
// ...notify the MPU port driver that we have bytes.
//
that->m_pPort->Notify(that->m_pServiceGroup);
}
ntStatus = STATUS_SUCCESS;
}
}
return ntStatus;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -