📄 waveoutpdd.cpp
字号:
/*
Copyright(c) 1998,1999 SIC/Hitachi,Ltd.
Module Name:
waveOutpdd.c
Revision History:
26th April 1999 Released
30th June 1999 Modified audio out buffer address
Added AudioOutInterrupt Flag
suppress playback recording
6th July 1999 Fixed minor bug
21th September 1999 Modified audio volume
Added audio pause and Audio restart process
Fixed L-R turn bug
Added PCML(R) FIFO buffer clear in WaveOutStop & WaveOutEndOfData & WaveOutPause process
8th October 1999 Modified WaveData length extend
29-Nov-1999 cea Changed for SH3 (7709A) DMA control
*/
#include <windows.h>
#include <types.h>
#include <memory.h>
#include <excpt.h>
#include <waveddsi.h>
#include <wavedbg.h>
#include <mmsystem.h>
#include "waveOutpddMacros.h"
#include "wavepdd.h"
#include "waveOutpdd.h"
#include "cc.h"
#include "macros.h"
#include "wavecpud.h"
DmaObject * pDmaOutObject=NULL;
extern DWORD dwCCCodecRegBase;//CC_CODEC_REGBASE
extern DWORD dwCCSysSMCR;//CC_SYS_SMSCR
static PVUSHORT pCODEC_CR; // virtual addrs of C.C. registers
static PVULONG pCODEC_ACR, pCODEC_CAR, pCODEC_CDR;
static PVULONG pCODEC_ATAGR;
static PVULONG pCODEC_PCML;
static PVULONG pSMSCR;
static PVUSHORT pCODEC_FSR;
extern "C" PUCHAR GetVirtualAddressOfUncachedMemory( PVOID base, ULONG sz, char* cID );
extern PWAVEFORMATEX g_pwfx[2];
extern PCM_TYPE g_pcmtype[2];
// Software Volume Control
#define scaleForVolume(sample) ((sample * multiplier) >> log2ofDivisor)
const struct { // table facilitates multiplying by fraction:
UINT16 multiplier; // multiply by "multiplier"
UINT16 divisor; // then shift right by "log2ofDivisor"
} VOL[] = { {0, 0}, // 0/1
{3, 5}, // 3/32
{7, 6}, // 7/64
{1, 3}, // 1/8
{5, 5}, // 5/32
{3, 4}, // 3/16
{7, 5}, // 7/32
{1, 2}, // 1/4
{5, 4}, // etc.
{3, 3},
{7, 4},
{1, 1},
{5, 3},
{3, 2},
{7, 3},
{1, 0}
};
// Double Buffer for Audio Playback
static ULONG v_nNextPage;
static PBYTE pCC_CODEC_RegBase; // Companion chip SERIAL CODEC register offsets
static PBYTE pCC_SYS_RegBase; // Companion chip SMSCR
static PBYTE pAudioBufferBase; // Audio buffer
//PDRIVER_GLOBALS pDriverGlobals; // Drivers Globals
static ULONG v_nVolume; // current volume setting
static volatile BOOL v_fMoreData[2];// TRUE iff MDD layer has called StopPlay
// v_fMoreData was volatile on D9000
// It could be involved in controlling
// multiple threads.
/*****************************************************************************
* FUNCTION : private_AudioOutGetInterruptType
* DESCRIPTION : decodes type of audio interrupt
* INPUTS : None
* OUTPUTS : interrupt type
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
AUDIO_STATE
private_AudioOutGetInterruptType(
VOID
)
{
FUNC_WPDD("+PDD_AudioOutGetInterruptType");
// An audio interrupt has occured. We need to tell the MDD who owns it
// and what state that puts us in.
// if ( pDriverGlobals->aud.outInt == (USHORT)NULL )
if (pDmaOutObject==NULL || pDmaOutObject->GetGlobalOutInt()==NULL)
{
DEBUGMSG(ZONE_TEST, (TEXT("PDD_AudioOutGetInterruptType: ignore")));
FUNC_WPDD("-PDD_AudioOutGetInterruptType");
return AUDIO_STATE_IGNORE; // assume audio-in generated interrupt
}
pDmaOutObject->ResetGlobalOutInt(TRUE); //decrement interrupt count.
if (!v_fMoreData[WAPI_OUT])
{
DEBUGMSG(ZONE_TEST, (TEXT("PDD_AudioOutGetInterruptType: stopped")));
FUNC_WPDD("-PDD_AudioOutGetInterruptType");
return AUDIO_STATE_OUT_STOPPED;
}
else if (pDmaOutObject->GetGlobalPlayAddress()!=NULL)//(pDriverGlobals->aud.play_address != (ULONG)NULL)
{
DEBUGMSG(ZONE_TEST, (TEXT("PDD_AudioOutGetInterruptType: playing")));
FUNC_WPDD("-PDD_AudioOutGetInterruptType");
return AUDIO_STATE_OUT_PLAYING;
}
else
{
DEBUGMSG(ZONE_TEST, (TEXT("PDD_AudioOutGetInterruptType:underflow")));
FUNC_WPDD("-PDD_AudioOutGetInterruptType");
return AUDIO_STATE_OUT_UNDERFLOW;
}
}
/*****************************************************************************
* FUNCTION : private_AudioOutInitialize
* DESCRIPTION : sets up register access for audio-out
* sets DA, DMA, and CMT registers that remain constant
* sets volume to maximum (default)
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
BOOL
private_AudioOutInitialize(
VOID
)
{
ULONG ACR_VALUE;
USHORT CR_VALUE;
volatile DWORD dwIndex;
//ULONG SizeOfBuffer;
char here[] = "PDD_AudioOutInitialize";
FUNC_WPDD("+PDD_AudioOutInitialize");
RETAILMSG( 1, (TEXT("WaveOutpdd.c private_AudioOutInitialize: START\r\n")));
// Set pointers to virtual addresses of playback registers
/*
pDMAC_RegBase =(PBYTE)GetVirtualAddressOfUncachedMemory(
(PBYTE)DMAC_REGBASE,
(DWORD)DMAC_REGSIZE,
"PDD_AudioInitialize, pDMAC_RegBase");
if (pDMAC_RegBase == NULL) return FALSE;
pDMAOR = (PVUSHORT)(pDMAC_RegBase + DMAC_DMAOR_OFFSET );
pSAR1 = (PVULONG)(pDMAC_RegBase + DMAC_SAR1_OFFSET );
pDAR1 = (PVULONG)(pDMAC_RegBase + DMAC_DAR1_OFFSET );
pDMATCR1 = (PVULONG)(pDMAC_RegBase + DMAC_DMATCR1_OFFSET);
pCHCR1 = (PVULONG)(pDMAC_RegBase + DMAC_CHCR1_OFFSET );
pCHCR0 = (PVULONG)(pDMAC_RegBase + DMAC_CHCR0_OFFSET );
pCHCR2 = (PVULONG)(pDMAC_RegBase + DMAC_CHCR2_OFFSET );
pCHCR3 = (PVULONG)(pDMAC_RegBase + DMAC_CHCR3_OFFSET );
pINTC_Area_1_RegBase =(PBYTE)GetVirtualAddressOfUncachedMemory(
(PBYTE)INTC_AREA_1_REGBASE,
(DWORD)INTC_AREA_1_REGSIZE,
"PDD_AudioInitialize, pINTC_Area_1_RegBase");
if (pINTC_Area_1_RegBase == NULL) return FALSE;
pINTC_Area_7_RegBase =(PBYTE)GetVirtualAddressOfUncachedMemory(
(PBYTE)INTC_AREA_7_REGBASE,
(DWORD)INTC_AREA_7_REGSIZE,
"PDD_AudioInitialize, pINTC_Area_7_RegBase");
if (pINTC_Area_7_RegBase == NULL) return FALSE;
*/
pCC_CODEC_RegBase =(PBYTE)GetVirtualAddressOfUncachedMemory(
(PBYTE)dwCCCodecRegBase,//CC_CODEC_REGBASE,
(DWORD)CC_CODEC_REGSIZE,
"PDD_AudioInitialize, pCC_CODEC_RegBase");
if (pCC_CODEC_RegBase == NULL) return FALSE;
pCODEC_CR = (PVUSHORT) (pCC_CODEC_RegBase + CC_CODEC_CR_OFFSET );
pCODEC_CAR = (PVULONG ) (pCC_CODEC_RegBase + CC_CODEC_CAR_OFFSET );
pCODEC_CDR = (PVULONG ) (pCC_CODEC_RegBase + CC_CODEC_CDR_OFFSET );
pCODEC_ACR = (PVULONG ) (pCC_CODEC_RegBase + CC_CODEC_ACR_OFFSET );
pCODEC_ATAGR = (PVULONG ) (pCC_CODEC_RegBase + CC_CODEC_ATAGR_OFFSET );
pCODEC_PCML = (PVULONG ) (pCC_CODEC_RegBase + CC_CODEC_PCML_OFFSET );
pCODEC_FSR = (PVUSHORT) (pCC_CODEC_RegBase + CC_CODEC_FSR_OFFSET );
pCC_SYS_RegBase =(PBYTE)GetVirtualAddressOfUncachedMemory(
(PBYTE)dwCCSysSMCR,//CC_SYS_SMSCR,
(DWORD)CC_SYS_REGSIZE,
"PDD_AudioInitialize, pCC_SYS_RegBase");
if (pCC_SYS_RegBase == NULL) return FALSE;
pSMSCR = (PVULONG ) (pCC_SYS_RegBase );
// Set pointers to virtual addresses of audio buffers
/* SizeOfBuffer = (AUDIO_DMA_PAGE_SIZE * 2);
pAudioBufferBase = VirtualAlloc(
NULL,
SizeOfBuffer,
MEM_RESERVE,
PAGE_NOACCESS);
if (pAudioBufferBase == NULL) return FALSE;
if (!VirtualCopy((PVOID)pAudioBufferBase,
(PVOID)dma_pagePhysicalAddress[0],
(DWORD)SizeOfBuffer,
PAGE_READWRITE | PAGE_NOCACHE))
{
VirtualFree((PVOID)pAudioBufferBase, 0, MEM_RELEASE);
return FALSE;
}
*/
if (pDmaOutObject==NULL) {
pDmaOutObject= CreateDmaObject(FALSE); // false for play dma buffer
ASSERT(pDmaOutObject);
};
pAudioBufferBase=(PBYTE)pDmaOutObject->GetDmaVirtualAddr();
if (pAudioBufferBase == NULL)
{
RETAILMSG( 1, (TEXT("pAudioBufferBase ---error---\r\n")));
return FALSE;
}
// Setup a Access to AudioPlayingAddress and AudioOutInterrupt
/*
pDriverGlobals = VirtualAlloc(
NULL,
DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
MEM_RESERVE,
PAGE_NOACCESS);
if (pDriverGlobals == NULL) return FALSE;
if (!VirtualCopy((PVOID)pDriverGlobals,
(PVOID)DRIVER_GLOBALS_PHYSICAL_MEMORY_START,
(DWORD)DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
PAGE_READWRITE | PAGE_NOCACHE))
{
VirtualFree((PVOID)pDriverGlobals, 0, MEM_RELEASE);
return FALSE;
}
*/
//
// AC97 Setting
//
//Reset AC97
WRITE_REGISTER_USHORT((PUSHORT)pCODEC_CR, 0x0a00 );
Delay_AC();
WRITE_REGISTER_USHORT((PUSHORT)pCODEC_FSR, 0x0000 );
Delay_AC();
WRITE_REGISTER_USHORT((PUSHORT)pCODEC_CR, 0x0235 );
Delay_AC();
//Init_Codec
ACR_VALUE = (ULONG)READ_REGISTER_ULONG((PULONG)pCODEC_ACR );
ACR_VALUE &= 0x7fffffff;
ACR_VALUE |= 0x001fffff;
WRITE_REGISTER_USHORT((PUSHORT)pCODEC_FSR, 0x0000 );
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_ACR, ACR_VALUE );
Delay_AC();
//AC_Init
CR_VALUE = (USHORT)READ_REGISTER_USHORT((PUSHORT)pCODEC_CR );
CR_VALUE &= 0xf7ff;
CR_VALUE |= 0x0035;
WRITE_REGISTER_USHORT((PUSHORT)pCODEC_FSR, 0x0000 );
Delay_AC();
WRITE_REGISTER_USHORT((PUSHORT)pCODEC_CR, CR_VALUE );
Delay_AC();
RETAILMSG( 1, (TEXT("Control register =%08x\r\n"), (USHORT)READ_REGISTER_USHORT((PUSHORT)pCODEC_CR )));
//Codec Ready?
RETAILMSG( 1, (TEXT("ATAGR =%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pCODEC_ATAGR )));
RETAILMSG( 1, (TEXT("WAIT Condec Ready..............\r\n")));
for (dwIndex=0;dwIndex<0x100;dwIndex++) {
if (( (ULONG)READ_REGISTER_ULONG((PULONG)pCODEC_ATAGR ) & 0x80000000 ))
break;
Delay_AC();
};
RETAILMSG( 1, (TEXT("codec ready with cound 0x%lx !! \r\n"),dwIndex));
//RX TX Valid Slot
WRITE_REGISTER_ULONG((PULONG)pCODEC_ATAGR, 0x00001ff8 );
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x000a6000 );
Delay_AC();
RETAILMSG( 1, (TEXT("WAIT ADC DAC ANL Ready?..............\r\n")));
while(( (ULONG)READ_REGISTER_ULONG((PULONG)pCODEC_CDR ) & 0x000000f0 ) != 0x000000f0)
{
WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x000a6000 );
Delay_AC();
}
RETAILMSG( 1, (TEXT("111accept Data!!\r\n")));
WRITE_REGISTER_USHORT((PUSHORT)pCODEC_FSR, 0x0000 );
Delay_AC();
WRITE_REGISTER_USHORT((PUSHORT)pCODEC_CR, 0x0200 );
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x00002000 ); // Set Master Volume address
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x00018000 ); // Set PCM Out Volume address
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x00078000 ); // Set Sample rate address
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CDR, (ULONG)0x00015150 );// Set Master Volume data
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CDR, (ULONG)0x00008080 );// Set PCM Out Volume data
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CDR, 48000 << 4 ); // Set Sample rate data
Delay_AC();
WRITE_REGISTER_USHORT((PUSHORT)pCODEC_FSR, 0x0000 );
Delay_AC();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -