diff --git a/bin/History.txt b/bin/History.txt index 4890c6b6..dd588ab6 100644 --- a/bin/History.txt +++ b/bin/History.txt @@ -24,6 +24,7 @@ Changes: . Unit tests added for 6502 and 65C02 opcodes . Added -load-state command line option . New repo created with test save-state images: https://github.com/AppleWin/AppleWin-Test +. Remove unsupported PC speaker sound types Fixes: . [Bug #129] Tight loop page-flipping causing heavy CPU load (fixed by NTSC / cycle-accurate video emulation) diff --git a/help/cfg-sound.html b/help/cfg-sound.html index 4acf2a65..3372ca3d 100644 --- a/help/cfg-sound.html +++ b/help/cfg-sound.html @@ -19,15 +19,8 @@ This option allows you to choose how sound is output for the system. Your choices are:
Volume Control:
diff --git a/source/Applewin.cpp b/source/Applewin.cpp index 3e3096ed..3b8aef53 100644 --- a/source/Applewin.cpp +++ b/source/Applewin.cpp @@ -510,7 +510,20 @@ void LoadConfiguration(void) else LoadConfigOldJoystick(JN_JOYSTICK1); - REGLOAD(TEXT("Sound Emulation") ,&soundtype); + DWORD dwSoundType; + REGLOAD(TEXT("Sound Emulation"), &dwSoundType); + switch (dwSoundType) + { + case REG_SOUNDTYPE_NONE: + case REG_SOUNDTYPE_DIRECT: // Not supported from 1.26 + case REG_SOUNDTYPE_SMART: // Not supported from 1.26 + default: + soundtype = SOUND_NONE; + break; + case REG_SOUNDTYPE_WAVE: + soundtype = SOUND_WAVE; + break; + } char aySerialPortName[ CSuperSerialCard::SIZEOF_SERIALCHOICE_ITEM ]; if (RegLoadString( TEXT("Configuration"), diff --git a/source/Configuration/PageSound.cpp b/source/Configuration/PageSound.cpp index 540bdb1a..5e94acf7 100644 --- a/source/Configuration/PageSound.cpp +++ b/source/Configuration/PageSound.cpp @@ -35,8 +35,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA CPageSound* CPageSound::ms_this = 0; // reinit'd in ctor const TCHAR CPageSound::m_soundchoices[] = TEXT("Disabled\0") - TEXT("PC Speaker (direct)\0") - TEXT("PC Speaker (translated)\0") TEXT("Sound Card\0"); @@ -106,7 +104,7 @@ BOOL CPageSound::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM case WM_INITDIALOG: { - m_PropertySheetHelper.FillComboBox(hWnd,IDC_SOUNDTYPE,m_soundchoices,soundtype); + m_PropertySheetHelper.FillComboBox(hWnd,IDC_SOUNDTYPE, m_soundchoices, (int)soundtype); SendDlgItemMessage(hWnd,IDC_SPKR_VOLUME,TBM_SETRANGE,1,MAKELONG(VOLUME_MIN,VOLUME_MAX)); SendDlgItemMessage(hWnd,IDC_SPKR_VOLUME,TBM_SETPAGESIZE,0,10); @@ -134,14 +132,15 @@ BOOL CPageSound::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM void CPageSound::DlgOK(HWND hWnd) { - const DWORD dwNewSoundType = (DWORD) SendDlgItemMessage(hWnd, IDC_SOUNDTYPE, CB_GETCURSEL, 0, 0); + const SoundType_e newSoundType = (SoundType_e) SendDlgItemMessage(hWnd, IDC_SOUNDTYPE, CB_GETCURSEL, 0, 0); const DWORD dwSpkrVolume = SendDlgItemMessage(hWnd, IDC_SPKR_VOLUME, TBM_GETPOS, 0, 0); const DWORD dwMBVolume = SendDlgItemMessage(hWnd, IDC_MB_VOLUME, TBM_GETPOS, 0, 0); - if (SpkrSetEmulationType(hWnd, dwNewSoundType)) + if (SpkrSetEmulationType(hWnd, newSoundType)) { - REGSAVE(TEXT("Sound Emulation"), soundtype); + DWORD dwSoundType = (soundtype == SOUND_NONE) ? REG_SOUNDTYPE_NONE : REG_SOUNDTYPE_WAVE; + REGSAVE(TEXT("Sound Emulation"), dwSoundType); } // NB. Volume: 0=Loudest, VOLUME_MAX=Silence diff --git a/source/Speaker.cpp b/source/Speaker.cpp index e93c0948..ff58a7fd 100644 --- a/source/Speaker.cpp +++ b/source/Speaker.cpp @@ -70,7 +70,7 @@ static UINT g_nRemainderBufferSize; // Setup in SpkrInitialize() static UINT g_nRemainderBufferIdx; // Setup in SpkrInitialize() // Application-wide globals: -DWORD soundtype = SOUND_WAVE; +SoundType_e soundtype = SOUND_WAVE; double g_fClksPerSpkrSample; // Setup in SetClksPerSpkrSample() // Allow temporary quietening of speaker (8 bit DAC) @@ -85,14 +85,6 @@ static bool g_bSpkrToggleFlag = false; static VOICE SpeakerVoice = {0}; static bool g_bSpkrAvailable = false; - -// Globals (SOUND_DIRECT/SOUND_SMART) -static BOOL directio = 0; -static DWORD lastdelta[2] = {0,0}; -static DWORD quietcycles = 0; -static DWORD soundeffect = 0; -static DWORD totaldelta = 0; - //----------------------------------------------------------------------------- // Forward refs: @@ -119,63 +111,6 @@ static void DisplayBenchmarkResults () //============================================================================= -static void InternalBeep (DWORD frequency, DWORD duration) -{ -#ifdef _X86_ - if (directio) - if (duration) { - frequency = 1193180/frequency; - __asm { - push eax - mov al,0B6h - out 43h,al - mov eax,frequency - out 42h,al - mov al,ah - out 42h,al - in al,61h - or al,3 - out 61h,al - pop eax - } - } - else - __asm { - push eax - in al,61h - and al,0FCh - out 61h,al - pop eax - } - else -#endif - Beep(frequency,duration); -} - -//============================================================================= - -static void InternalClick () -{ -#ifdef _X86_ - if (directio) - __asm { - push eax - in al,0x61 - xor al,2 - out 0x61,al - pop eax - } - else { -#endif - Beep(37,(DWORD)-1); - Beep(0,0); -#ifdef _X86_ - } -#endif -} - -//============================================================================= - static void SetClksPerSpkrSample() { // // 23.191 clks for 44.1Khz (when 6502 CLK=1.0Mhz) @@ -224,10 +159,6 @@ void SpkrDestroy () g_pSpeakerBuffer = NULL; g_pRemainderBuffer = NULL; } - else if (soundtype == SOUND_DIRECT || soundtype == SOUND_SMART) - { - InternalBeep(0,0); - } } //============================================================================= @@ -240,8 +171,6 @@ void SpkrInitialize () switch(soundtype) { case SOUND_NONE: fprintf(g_fh, "(NONE)\n"); break; - case SOUND_DIRECT: fprintf(g_fh, "(DIRECT)\n"); break; - case SOUND_SMART: fprintf(g_fh, "(SMART)\n"); break; case SOUND_WAVE: fprintf(g_fh, "(WAVE)\n"); break; default: fprintf(g_fh, "(UNDEFINED!)\n"); break; } @@ -264,37 +193,6 @@ void SpkrInitialize () g_pSpeakerBuffer = new short [SPKR_SAMPLE_RATE]; // Buffer can hold a max of 1 seconds worth of samples } - - // - - // IF NONE IS, THEN DETERMINE WHETHER WE HAVE DIRECT ACCESS TO THE PC SPEAKER PORT - if (soundtype != SOUND_WAVE) // *** TO DO: Need way of determining if DirectX init failed *** - { - if (soundtype == SOUND_WAVE) - soundtype = SOUND_SMART; -#ifdef _X86_ - _try - { - __asm { - in al,0x61 - xor al,2 - out 0x61,al - xor al,2 - out 0x61,al - } - directio = 1; - } - _except (EXCEPTION_EXECUTE_HANDLER) - { - directio = 0; - } -#else - directio = 0; -#endif - if ((!directio) && (soundtype == SOUND_DIRECT)) - soundtype = SOUND_SMART; - } - } //============================================================================= @@ -324,25 +222,17 @@ void SpkrReset() //============================================================================= -BOOL SpkrSetEmulationType (HWND window, DWORD newtype) +BOOL SpkrSetEmulationType (HWND window, SoundType_e newtype) { SpkrDestroy(); // GH#295: Destroy for all types (even SOUND_NONE) soundtype = newtype; if (soundtype != SOUND_NONE) SpkrInitialize(); + if (soundtype != newtype) switch (newtype) { - case SOUND_DIRECT: - MessageBox(window, - TEXT("Direct emulation is not available because the ") - TEXT("operating system you are using does not allow ") - TEXT("direct control of the speaker."), - TEXT("Configuration"), - MB_ICONEXCLAMATION | MB_SETFOREGROUND); - return 0; - case SOUND_WAVE: MessageBox(window, TEXT("The emulator is unable to initialize a waveform ") @@ -356,6 +246,7 @@ BOOL SpkrSetEmulationType (HWND window, DWORD newtype) return 0; } + return 1; } @@ -461,56 +352,6 @@ BYTE __stdcall SpkrToggle (WORD, WORD, BYTE, BYTE, ULONG nCyclesLeft) g_nSpeakerData = SPKR_DATA_INIT; } } - else if (soundtype != SOUND_NONE) - { - - // IF WE ARE CURRENTLY PLAYING A SOUND EFFECT OR ARE IN DIRECT - // EMULATION MODE, TOGGLE THE SPEAKER - if ((soundeffect > 2) || (soundtype == SOUND_DIRECT)) - { - if (directio) - { - __asm - { - push eax - in al,0x61 - xor al,2 - out 0x61,al - pop eax - } - } - else - { - Beep(37,(DWORD)-1); - Beep(0,0); - } - } - - // SAVE INFORMATION ABOUT THE FREQUENCY OF SPEAKER TOGGLING FOR POSSIBLE - // LATER USE BY SOUND AVERAGING - if (lastcyclenum) - { - toggles++; - //DWORD delta = cyclenum-lastcyclenum; // [TC: 14/09/2014] Looks broken, since 'cyclenum' is cycles executed in previous call to CpuExecute() - CpuCalcCycles(nCyclesLeft); - DWORD delta = (DWORD)g_nCumulativeCycles - lastcyclenum; - - // DETERMINE WHETHER WE ARE PLAYING A SOUND EFFECT - if (directio && - ((delta < 250) || - (lastdelta[0] && lastdelta[1] && - (delta-lastdelta[0] > 250) && (lastdelta[0]-delta > 250) && - (delta-lastdelta[1] > 250) && (lastdelta[1]-delta > 250)))) - soundeffect = MIN(35,soundeffect+2); - - lastdelta[1] = lastdelta[0]; - lastdelta[0] = delta; - totaldelta += delta; - } - //lastcyclenum = cyclenum; - lastcyclenum = (DWORD)g_nCumulativeCycles; - - } return MemReadFloatingBus(nCyclesLeft); } @@ -555,63 +396,6 @@ void SpkrUpdate (DWORD totalcycles) memmove(g_pSpeakerBuffer, &g_pSpeakerBuffer[nSamplesUsed], g_nBufferIdx-nSamplesUsed); // FIXME-TC: _Size * 2 g_nBufferIdx -= nSamplesUsed; } - else - { - - // IF WE ARE NOT PLAYING A SOUND EFFECT, PERFORM FREQUENCY AVERAGING - static DWORD currenthertz = 0; - static BOOL lastfull = 0; - static DWORD lasttoggles = 0; - static DWORD lastval = 0; - if ((soundeffect > 2) || (soundtype == SOUND_DIRECT)) { - lastval = 0; - if (currenthertz && (soundeffect > 4)) { - InternalBeep(0,0); - currenthertz = 0; - } - } - else if (toggles && totaldelta) { - DWORD newval = 1000000*toggles/totaldelta; - if (lastval && lastfull && - (newval-currenthertz > 50) && - (currenthertz-newval > 50)) { - InternalBeep(newval,(DWORD)-1); - currenthertz = newval; - lasttoggles = 0; - } - lastfull = (totaldelta+((totaldelta/toggles) << 1) >= totalcycles); - lasttoggles += toggles; - lastval = newval; - } - else if (currenthertz) { - InternalBeep(0,0); - currenthertz = 0; - lastfull = 0; - lasttoggles = 0; - lastval = 0; - } - else if (lastval) { - currenthertz = (lasttoggles > 4) ? lastval : 0; - if (currenthertz) - InternalBeep(lastval,(DWORD)-1); - else - InternalClick(); - lastfull = 0; - lasttoggles = 0; - lastval = 0; - } - - // RESET THE FREQUENCY GATHERING VARIABLES - lastcyclenum = 0; - lastdelta[0] = 0; - lastdelta[1] = 0; - quietcycles = toggles ? 0 : (quietcycles+totalcycles); - toggles = 0; - totaldelta = 0; - if (soundeffect) - soundeffect--; - - } } // Called from SoundCore_TimerFunc() for FADE_OUT diff --git a/source/Speaker.h b/source/Speaker.h index 2e6312bd..1ed5a368 100644 --- a/source/Speaker.h +++ b/source/Speaker.h @@ -1,11 +1,18 @@ #pragma once -#define SOUND_NONE 0 -#define SOUND_DIRECT 1 -#define SOUND_SMART 2 -#define SOUND_WAVE 3 +// Registry soundtype: +#define REG_SOUNDTYPE_NONE 0 +#define REG_SOUNDTYPE_DIRECT 1 // Not supported from 1.26 +#define REG_SOUNDTYPE_SMART 2 // Not supported from 1.26 +#define REG_SOUNDTYPE_WAVE 3 -extern DWORD soundtype; +enum SoundType_e +{ + SOUND_NONE = 0, + SOUND_WAVE +}; + +extern SoundType_e soundtype; extern double g_fClksPerSpkrSample; extern bool g_bQuieterSpeaker; extern short g_nSpeakerData; @@ -14,7 +21,7 @@ void SpkrDestroy (); void SpkrInitialize (); void SpkrReinitialize (); void SpkrReset(); -BOOL SpkrSetEmulationType (HWND,DWORD); +BOOL SpkrSetEmulationType (HWND window, SoundType_e newSoundType); void SpkrUpdate (DWORD); void SpkrUpdate_Timer(); void Spkr_SetErrorInc(const int nErrorInc);