--- hatari/src/falcon/crossbar.c 2019/04/09 08:55:48 1.1.1.7 +++ hatari/src/falcon/crossbar.c 2019/04/09 08:57:00 1.1.1.8 @@ -95,6 +95,7 @@ const char crossbar_fileid[] = "Hatari C #include "audio.h" #include "configuration.h" #include "cycInt.h" +#include "m68000.h" #include "ioMem.h" #include "log.h" #include "memorySnapShot.h" @@ -104,6 +105,8 @@ const char crossbar_fileid[] = "Hatari C #include "microphone.h" #include "stMemory.h" #include "dsp.h" +#include "clocks_timings.h" + #define DACBUFFER_SIZE 2048 @@ -112,7 +115,6 @@ const char crossbar_fileid[] = "Hatari C /* Crossbar internal functions */ static int Crossbar_DetectSampleRate(Uint16 clock); -static void Crossbar_Recalculate_Clocks_Cycles(void); static void Crossbar_Start_InterruptHandler_25Mhz(void); static void Crossbar_Start_InterruptHandler_32Mhz(void); @@ -321,7 +323,7 @@ void Crossbar_Reset(bool bCold) memset(dac.buffer_right, 0, sizeof(dac.buffer_right)); dac.readPosition_float = 0; dac.readPosition = 0; - dac.writePosition = 0; + dac.writePosition = (dac.readPosition+DACBUFFER_SIZE/2)%DACBUFFER_SIZE; /* ADC inits */ memset(adc.buffer_left, 0, sizeof(adc.buffer_left)); @@ -403,6 +405,10 @@ void Crossbar_MemorySnapShot_Capture(boo MemorySnapShot_Store(&adc, sizeof(adc)); MemorySnapShot_Store(&dspXmit, sizeof(dspXmit)); MemorySnapShot_Store(&dspReceive, sizeof(dspReceive)); + + /* After restoring, update the clock/freq counters */ + if ( !bSave ) + Crossbar_Recalculate_Clocks_Cycles(); } @@ -1108,7 +1114,7 @@ void Crossbar_CodecStatus_WriteWord(void /** * Recalculates internal clocks 25 Mhz and 32 Mhz cycles */ -static void Crossbar_Recalculate_Clocks_Cycles(void) +void Crossbar_Recalculate_Clocks_Cycles(void) { double cyclesClk; @@ -1116,12 +1122,22 @@ static void Crossbar_Recalculate_Clocks_ crossbar.clock32_cycles_counter = 0; /* Calculate 25 Mhz clock cycles */ +#ifdef OLD_CPU_SHIFT cyclesClk = ((double)CPU_FREQ / Crossbar_DetectSampleRate(25)) / (double)(crossbar.playTracks) / 2.0; +#else + /* Take nCpuFreqShift into account to keep a constant sound rate at all cpu freq */ + cyclesClk = ((double)( ( CPU_FREQ << nCpuFreqShift ) ) / Crossbar_DetectSampleRate(25)) / (double)(crossbar.playTracks) / 2.0; +#endif crossbar.clock25_cycles = (int)(cyclesClk); crossbar.clock25_cycles_decimal = (int)((cyclesClk - (double)(crossbar.clock25_cycles)) * (double)DECIMAL_PRECISION); /* Calculate 32 Mhz clock cycles */ +#ifdef OLD_CPU_SHIFT cyclesClk = ((double)CPU_FREQ / Crossbar_DetectSampleRate(32)) / (double)(crossbar.playTracks) / 2.0; +#else + /* Take nCpuFreqShift into account to keep a constant sound rate at all cpu freq */ + cyclesClk = ((double)( ( CPU_FREQ << nCpuFreqShift ) ) / Crossbar_DetectSampleRate(32)) / (double)(crossbar.playTracks) / 2.0; +#endif crossbar.clock32_cycles = (int)(cyclesClk); crossbar.clock32_cycles_decimal = (int)((cyclesClk - (double)(crossbar.clock32_cycles)) * (double)DECIMAL_PRECISION); @@ -1142,6 +1158,10 @@ static void Crossbar_Recalculate_Clocks_ // Compute Ratio between host computer sound frequency and Hatari's sound frequency. Crossbar_Compute_Ratio(); + + // Ensure dac.writePosition is correctly set based on current dac.readPosition + // -> force dac.wordCount=0 to update dac.writePosition on next call to Crossbar_GenerateSamples() + dac.wordCount = 0; } /** @@ -1185,6 +1205,7 @@ static void Crossbar_Start_InterruptHand { Uint32 cycles_25; +//fprintf ( stderr , "start int25 %x %x %x %x\n" , crossbar.clock25_cycles, crossbar.clock25_cycles_counter, crossbar.clock25_cycles_decimal, crossbar.pendingCyclesOver25 ); cycles_25 = crossbar.clock25_cycles; crossbar.clock25_cycles_counter += crossbar.clock25_cycles_decimal; @@ -1212,6 +1233,7 @@ static void Crossbar_Start_InterruptHand { Uint32 cycles_32; +//fprintf ( stderr , "start int32 %x %x %x %x\n" , crossbar.clock32_cycles, crossbar.clock32_cycles_counter, crossbar.clock32_cycles_decimal, crossbar.pendingCyclesOver32 ); cycles_32 = crossbar.clock32_cycles; crossbar.clock32_cycles_counter += crossbar.clock32_cycles_decimal; @@ -1238,6 +1260,7 @@ static void Crossbar_Start_InterruptHand */ void Crossbar_InterruptHandler_25Mhz(void) { +//fprintf ( stderr , "int25 %x\n" , crossbar.pendingCyclesOver25 ); /* How many cycle was this sound interrupt delayed (>= 0) */ crossbar.pendingCyclesOver25 += -INT_CONVERT_FROM_INTERNAL ( PendingInterruptCount , INT_CPU_CYCLE ); @@ -1276,6 +1299,7 @@ void Crossbar_InterruptHandler_25Mhz(voi */ void Crossbar_InterruptHandler_32Mhz(void) { +//fprintf ( stderr , "int32 %x\n" , crossbar.pendingCyclesOver32 ); /* How many cycle was this sound interrupt delayed (>= 0) */ crossbar.pendingCyclesOver32 += -INT_CONVERT_FROM_INTERNAL ( PendingInterruptCount , INT_CPU_CYCLE ); @@ -1457,6 +1481,7 @@ static void Crossbar_Process_DMAPlay_Tra } } +//fprintf ( stderr , "cbar %x %x %x\n" , dmaPlay.frameCounter , value , increment_frame ); if (dmaPlay.isConnectedToDspInHandShakeMode) { /* Handshake mode */ if (dmaPlay.handshakeMode_Frame == 0) @@ -1758,6 +1783,10 @@ static void Crossbar_SendDataToDAC(Sint1 { Uint16 track = crossbar.track_monitored * 2; +//fprintf ( stderr , "datadac %x %x\n" , value , dac.writePosition ); + /* Increase counter for each sample received by the DAC */ + dac.wordCount++; + if (sample_pos == track) { /* Left channel */ dac.buffer_left[dac.writePosition] = value; @@ -1776,9 +1805,12 @@ static void Crossbar_SendDataToDAC(Sint1 */ void Crossbar_GenerateSamples(int nMixBufIdx, int nSamplesToGenerate) { - int i, j, nBufIdx; + int i, nBufIdx; int n; Sint16 adc_leftData, adc_rightData, dac_LeftData, dac_RightData; + Sint16 dac_read_left, dac_read_right; + +//fprintf ( stderr , "gen %03x %03x %03x %03x\n" , dac.writePosition , dac.readPosition , (dac.writePosition-dac.readPosition)%DACBUFFER_SIZE , nSamplesToGenerate ); if (crossbar.isDacMuted) { /* Output sound = 0 */ @@ -1789,7 +1821,7 @@ void Crossbar_GenerateSamples(int nMixBu } /* Counters are refreshed for when DAC becomes unmuted */ - dac.readPosition = dac.writePosition; + dac.readPosition = (dac.writePosition-DACBUFFER_SIZE/2)%DACBUFFER_SIZE; crossbar.adc2dac_readBufferPosition = adc.writePosition; return; } @@ -1824,6 +1856,17 @@ void Crossbar_GenerateSamples(int nMixBu } /* DAC mixing (direct ADC + crossbar) */ + /* If DAC didn't receive any data, we force left/right value to 0 */ + if ( dac.wordCount == 0 ) /* Nothing received */ + { + dac_read_left = 0; + dac_read_right = 0; + } + else + { + dac_read_left = dac.buffer_left[dac.readPosition]; + dac_read_right = dac.buffer_right[dac.readPosition]; + } switch (crossbar.codecInputSource) { case 0: default: /* Just here to remove compiler's warnings */ @@ -1838,15 +1881,15 @@ void Crossbar_GenerateSamples(int nMixBu break; case 2: /* Crossbar->DAC sound only */ - dac_LeftData = dac.buffer_left[dac.readPosition]; - dac_RightData = dac.buffer_right[dac.readPosition]; + dac_LeftData = dac_read_left; + dac_RightData = dac_read_right; break; case 3: /* Mixing Direct ADC sound with Crossbar->DMA sound */ dac_LeftData = ((adc_leftData * crossbar.gainSettingLeft) >> 14) + - dac.buffer_left[dac.readPosition]; - dac_RightData = ((adc_rightData * crossbar.gainSettingRight) >> 14) + - dac.buffer_right[dac.readPosition]; + dac_read_left; + dac_RightData = ((adc_rightData * crossbar.gainSettingRight) >> 14) + + dac_read_right; break; } @@ -1857,6 +1900,7 @@ void Crossbar_GenerateSamples(int nMixBu dac.readPosition_float += crossbar.frequence_ratio; n = dac.readPosition_float >> 32; /* number of samples to skip */ +#if 0 if (n) { // It becomes safe to zero old data if tail has moved for (j=0; j> 4) & 0x7) { - case 0 : strcpy(matrixDSP, "OOHO"); break; - case 1 : strcpy(matrixDSP, "OOXO"); break; - case 2 : strcpy(matrixDSP, "OHOO"); break; - case 3 : strcpy(matrixDSP, "OXOO"); break; - case 4 : strcpy(matrixDSP, "HOOO"); break; - case 5 : strcpy(matrixDSP, "XOOO"); break; - case 6 : strcpy(matrixDSP, "OOOH"); break; - case 7 : strcpy(matrixDSP, "OOOX"); break; - } + matrixDSP = matrix_tab[(IoMem_ReadWord(0xff8932) >> 4) & 0x7]; /* External input connexion */ - switch ((IoMem_ReadWord(0xff8932) >> 8) & 0x7) { - case 0 : strcpy(matrixEXT, "OOHO"); break; - case 1 : strcpy(matrixEXT, "OOXO"); break; - case 2 : strcpy(matrixEXT, "OHOO"); break; - case 3 : strcpy(matrixEXT, "OXOO"); break; - case 4 : strcpy(matrixEXT, "HOOO"); break; - case 5 : strcpy(matrixEXT, "XOOO"); break; - case 6 : strcpy(matrixEXT, "OOOH"); break; - case 7 : strcpy(matrixEXT, "OOOX"); break; - } + matrixEXT = matrix_tab[(IoMem_ReadWord(0xff8932) >> 8) & 0x7]; if ((IoMem_ReadByte(0xff8935) & 0xf) == 0) { strcpy(frqDSP, "(STe Freq)");