Speech fixes:

. Fix for MB/Phasor for short phonemes - bug in DirectSound in WinXP (see KB327698)
. Removed NMI generation for soundcards (they only generate IRQ)
This commit is contained in:
tomch 2006-12-27 19:11:19 +00:00
parent 8a96d655c6
commit 686ae4dc96
1 changed files with 43 additions and 21 deletions

View File

@ -149,6 +149,7 @@ static USHORT g_nMBTimerDevice = 0; // SY6522 device# which is generating timer
// SSI263 vars:
static USHORT g_nSSI263Device = 0; // SSI263 device# which is generating phoneme-complete IRQ
static int g_nCurrentActivePhoneme = -1;
static bool g_bStopPhoneme = false;
static bool g_bVotraxPhoneme = false;
static const DWORD SAMPLE_RATE = 44100; // Use a base freq so that DirectX (or sound h/w) doesn't have to up/down-sample
@ -303,16 +304,20 @@ static void UpdateIFR(SY6522_AY8910* pMB)
for(UINT i=0; i<NUM_SY6522; i++)
bIRQ |= g_MB[i].sy6522.IFR & 0x80;
// NB. Mockingboard generates IRQ on both 6522s:
// . SSI263's IRQ (A/!R) is routed via the 2nd 6522 (at $Cx80) and must generate a 6502 IRQ (not NMI)
// . SC-01's IRQ (A/!R) is also routed via a (2nd?) 6522
// Phasor's SSI263 appears to be wired directly to the 6502's IRQ (ie. not via a 6522)
// . I assume Phasor's 6522s just generate 6502 IRQs (not NMIs)
if (bIRQ)
if (pMB->nAY8910Number & 1)
CpuNmiAssert(IS_6522);
else
CpuIrqAssert(IS_6522);
{
CpuIrqAssert(IS_6522);
}
else
if (pMB->nAY8910Number & 1)
CpuNmiDeassert(IS_6522);
else
CpuIrqDeassert(IS_6522);
{
CpuIrqDeassert(IS_6522);
}
}
static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
@ -574,16 +579,20 @@ static void SSI263_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
// Datasheet is not clear, but a write to DURPHON must clear the IRQ
if(g_bPhasorEnable)
if (pMB->nAY8910Number & 1)
CpuNmiDeassert(IS_SPEECH);
else
CpuIrqDeassert(IS_SPEECH);
pMB->sy6522.IFR &= ~IxR_PERIPHERAL;
UpdateIFR(pMB);
{
CpuIrqDeassert(IS_SPEECH);
}
else
{
pMB->sy6522.IFR &= ~IxR_PERIPHERAL;
UpdateIFR(pMB);
}
pMB->SpeechChip.CurrentMode &= ~1; // Clear SSI263's D7 pin
pMB->SpeechChip.DurationPhonome = nValue;
g_nSSI263Device = nDevice;
// Phoneme output not dependent on CONTROL bit
if(g_bPhasorEnable)
{
@ -594,7 +603,6 @@ static void SSI263_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
{
SSI263_Play(nValue & PHONEME_MASK);
}
g_nSSI263Device = nDevice;
break;
case SSI_INFLECT:
#if LOG_SSI263
@ -709,6 +717,8 @@ static void Votrax_Write(BYTE nDevice, BYTE nValue)
pMB->sy6522.IFR &= ~IxR_VOTRAX;
UpdateIFR(pMB);
g_nSSI263Device = nDevice;
SSI263_Play(Votrax2SSI263[nValue & PHONEME_MASK]);
}
@ -891,6 +901,16 @@ static DWORD WINAPI SSI263Thread(LPVOID lpParameter)
// Phoneme completed playing
if (g_bStopPhoneme)
{
g_bStopPhoneme = false;
continue;
}
#if LOG_SSI263
//if(g_fh) fprintf(g_fh, "IRQ: Phoneme complete (0x%02X)\n\n", g_nCurrentActivePhoneme);
#endif
SSI263Voice[g_nCurrentActivePhoneme].bActive = false;
g_nCurrentActivePhoneme = -1;
@ -903,11 +923,8 @@ static DWORD WINAPI SSI263Thread(LPVOID lpParameter)
{
pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin
// Is Phasor's SSI263.IRQ wired directly to IRQ? (Bypassing the 6522)
if (pMB->nAY8910Number & 1)
CpuNmiAssert(IS_SPEECH);
else
CpuIrqAssert(IS_SPEECH);
// Phasor's SSI263.IRQ line appears to be wired directly to IRQ (Bypassing the 6522)
CpuIrqAssert(IS_SPEECH);
}
}
else
@ -944,7 +961,11 @@ static void SSI263_Play(unsigned int nPhoneme)
HRESULT hr;
if(g_nCurrentActivePhoneme >= 0)
{
// A write to DURPHON before previous phoneme has completed
g_bStopPhoneme = true;
hr = SSI263Voice[g_nCurrentActivePhoneme].lpDSBvoice->Stop();
}
g_nCurrentActivePhoneme = nPhoneme;
@ -1106,7 +1127,8 @@ static bool MB_DSInit()
unsigned int nPhonemeByteLength = g_nPhonemeInfo[nPhoneme].nLength * sizeof(SHORT);
hr = DSGetSoundBuffer(&SSI263Voice[i], DSBCAPS_CTRLVOLUME+DSBCAPS_CTRLPOSITIONNOTIFY, nPhonemeByteLength, 22050, 1);
// NB. DSBCAPS_LOCSOFTWARE required for Phoneme+2==0x28 - sample too short (see KB327698)
hr = DSGetSoundBuffer(&SSI263Voice[i], DSBCAPS_CTRLVOLUME+DSBCAPS_CTRLPOSITIONNOTIFY+DSBCAPS_LOCSOFTWARE, nPhonemeByteLength, 22050, 1);
if(FAILED(hr))
{
if(g_fh) fprintf(g_fh, "SSI263: DSGetSoundBuffer failed (%08X)\n",hr);