audio: SN76496 fixes

This commit is contained in:
kub 2020-04-24 19:05:27 +02:00
parent fe43bdc334
commit 70aecd15b0
5 changed files with 43 additions and 10 deletions

View file

@ -883,7 +883,7 @@ static void m68k_mem_setup(void)
static int get_scanline(int is_from_z80) static int get_scanline(int is_from_z80)
{ {
if (is_from_z80) { if (is_from_z80) {
int mclk_z80 = z80_cyclesDone() * 15; int mclk_z80 = (z80_cyclesLeft<0 ? Pico.t.z80c_aim : z80_cyclesDone()) * 15;
int mclk_line = Pico.t.z80_scanline * 488 * 7; int mclk_line = Pico.t.z80_scanline * 488 * 7;
while (mclk_z80 - mclk_line >= 488 * 7) while (mclk_z80 - mclk_line >= 488 * 7)
Pico.t.z80_scanline++, mclk_line += 488 * 7; Pico.t.z80_scanline++, mclk_line += 488 * 7;

View file

@ -213,7 +213,7 @@ extern struct DrZ80 drZ80;
#define z80_cyclesDone() \ #define z80_cyclesDone() \
(Pico.t.z80c_aim - z80_cyclesLeft) (Pico.t.z80c_aim - z80_cyclesLeft)
#define cycles_68k_to_z80(x) ((x) * 3823 >> 13) #define cycles_68k_to_z80(x) ((x) * 3822 >> 13)
// ----------------------- SH2 CPU ----------------------- // ----------------------- SH2 CPU -----------------------

View file

@ -152,7 +152,7 @@ static void z80_sms_out(unsigned short a, unsigned char d)
case 0x40: case 0x40:
case 0x41: case 0x41:
if ((d & 0x90) == 0x90); if ((d & 0x90) == 0x90)
PsndDoPSG(Pico.m.scanline); PsndDoPSG(Pico.m.scanline);
SN76496Write(d); SN76496Write(d);
break; break;

View file

@ -173,9 +173,12 @@ void SN76496Update(short *buffer, int length, int stereo)
/* If we exit the loop in the middle, Output[i] has to be inverted */ /* If we exit the loop in the middle, Output[i] has to be inverted */
/* and vol[i] incremented only if the exit status of the square */ /* and vol[i] incremented only if the exit status of the square */
/* wave is 1. */ /* wave is 1. */
left = 0;
while (R->Count[i] <= 0) while (R->Count[i] <= 0)
{ {
R->Count[i] += R->Period[i]; if (R->Count[i] + R->Period[i]*4 < R->Period[i])
left+= 4, R->Count[i] += R->Period[i]*4;
else left++, R->Count[i] += R->Period[i];
if (R->Count[i] > 0) if (R->Count[i] > 0)
{ {
R->Output[i] ^= 1; R->Output[i] ^= 1;
@ -186,6 +189,9 @@ void SN76496Update(short *buffer, int length, int stereo)
vol[i] += R->Period[i]; vol[i] += R->Period[i];
} }
if (R->Output[i]) vol[i] -= R->Count[i]; if (R->Output[i]) vol[i] -= R->Count[i];
/* Cut of anything above the sample freqency. It will only create */
/* aliasing and hearable distortions anyway. */
if (left > 1) vol[i] = STEP/2;
} }
left = STEP; left = STEP;

View file

@ -259,6 +259,7 @@ static int PsndRender(int offset, int length)
int stereo = (PicoIn.opt & 8) >> 3; int stereo = (PicoIn.opt & 8) >> 3;
int fmlen = ((Pico.snd.fm_pos+0x80000) >> 20); int fmlen = ((Pico.snd.fm_pos+0x80000) >> 20);
int daclen = ((Pico.snd.dac_pos+0x80000) >> 20); int daclen = ((Pico.snd.dac_pos+0x80000) >> 20);
int psglen = ((Pico.snd.psg_pos+0x8000) >> 16);
buf32 = PsndBuffer+(offset<<stereo); buf32 = PsndBuffer+(offset<<stereo);
@ -282,6 +283,14 @@ static int PsndRender(int offset, int length)
Pico.snd.dac_val2 = Pico.snd.dac_val; Pico.snd.dac_val2 = Pico.snd.dac_val;
} }
// Add in parts of the PSG output not yet done
if (length-psglen > 0) {
short *psgbuf = PicoIn.sndOut + (psglen << stereo);
Pico.snd.psg_pos += (length-psglen) << 16;
if (PicoIn.opt & POPT_EN_PSG)
SN76496Update(psgbuf, length-psglen, stereo);
}
// Add in parts of the FM buffer not yet done // Add in parts of the FM buffer not yet done
if (length-fmlen > 0) { if (length-fmlen > 0) {
int *fmbuf = buf32 + ((fmlen-offset) << stereo); int *fmbuf = buf32 + ((fmlen-offset) << stereo);
@ -323,8 +332,6 @@ PICO_INTERNAL void PsndGetSamples(int y)
{ {
static int curr_pos = 0; static int curr_pos = 0;
PsndDoPSG(y - 1);
curr_pos = PsndRender(0, Pico.snd.len_use); curr_pos = PsndRender(0, Pico.snd.len_use);
if (PicoIn.writeSound) if (PicoIn.writeSound)
@ -333,11 +340,20 @@ PICO_INTERNAL void PsndGetSamples(int y)
PsndClear(); PsndClear();
} }
PICO_INTERNAL void PsndGetSamplesMS(int y) static int PsndRenderMS(int offset, int length)
{ {
int length = Pico.snd.len_use; int stereo = (PicoIn.opt & 8) >> 3;
int psglen = ((Pico.snd.psg_pos+0x8000) >> 16);
PsndDoPSG(y - 1); pprof_start(sound);
// Add in parts of the PSG output not yet done
if (length-psglen > 0) {
short *psgbuf = PicoIn.sndOut + (psglen << stereo);
Pico.snd.psg_pos += (length-psglen) << 16;
if (PicoIn.opt & POPT_EN_PSG)
SN76496Update(psgbuf, length-psglen, stereo);
}
// upmix to "stereo" if needed // upmix to "stereo" if needed
if (PicoIn.opt & POPT_EN_STEREO) { if (PicoIn.opt & POPT_EN_STEREO) {
@ -346,8 +362,19 @@ PICO_INTERNAL void PsndGetSamplesMS(int y)
*p |= *p << 16; *p |= *p << 16;
} }
pprof_end(sound);
return length;
}
PICO_INTERNAL void PsndGetSamplesMS(int y)
{
static int curr_pos = 0;
curr_pos = PsndRenderMS(0, Pico.snd.len_use);
if (PicoIn.writeSound != NULL) if (PicoIn.writeSound != NULL)
PicoIn.writeSound(length * ((PicoIn.opt & POPT_EN_STEREO) ? 4 : 2)); PicoIn.writeSound(curr_pos * ((PicoIn.opt & POPT_EN_STEREO) ? 4 : 2));
PsndClear(); PsndClear();
} }