From 5d638db094e6677240fb4766f2168c7b0791b677 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 30 Sep 2017 22:55:57 +0300 Subject: [PATCH] handle frequent psg updates --- pico/memory.c | 38 +++++++++++++++++++++++++++----------- pico/pico_cmn.c | 2 ++ pico/pico_int.h | 3 ++- pico/sound/sound.c | 44 +++++++++++++++++++++++++++++++++++--------- 4 files changed, 66 insertions(+), 21 deletions(-) diff --git a/pico/memory.c b/pico/memory.c index fb5fa9be..0907696a 100644 --- a/pico/memory.c +++ b/pico/memory.c @@ -385,6 +385,28 @@ void NOINLINE ctl_write_z80reset(u32 d) } } +static int get_scanline(int is_from_z80); + +static void psg_write_68k(u32 d) +{ + // look for volume write and update if needed + if ((d & 0x90) == 0x90 && PsndPsgLine < Pico.m.scanline) + PsndDoPSG(Pico.m.scanline); + + SN76496Write(d); +} + +static void psg_write_z80(u32 d) +{ + if ((d & 0x90) == 0x90) { + int scanline = get_scanline(1); + if (PsndPsgLine < scanline) + PsndDoPSG(scanline); + } + + SN76496Write(d); +} + // ----------------------------------------------------------------- #ifndef _ASM_MEMORY_C @@ -528,8 +550,7 @@ static void PicoWrite8_z80(u32 a, u32 d) } // TODO: probably other VDP access too? Maybe more mirrors? if ((a & 0x7ff9) == 0x7f11) { // PSG Sound - if (PicoOpt & POPT_EN_PSG) - SN76496Write(d); + psg_write_68k(d); return; } if ((a & 0x7f00) == 0x6000) // Z80 BANK register @@ -703,8 +724,7 @@ static u32 PicoRead16_vdp(u32 a) static void PicoWrite8_vdp(u32 a, u32 d) { if ((a & 0x00f9) == 0x0011) { // PSG Sound - if (PicoOpt & POPT_EN_PSG) - SN76496Write(d); + psg_write_68k(d); return; } if ((a & 0x00e0) == 0x0000) { @@ -718,11 +738,8 @@ static void PicoWrite8_vdp(u32 a, u32 d) static void PicoWrite16_vdp(u32 a, u32 d) { - if ((a & 0x00f9) == 0x0010) { // PSG Sound - if (PicoOpt & POPT_EN_PSG) - SN76496Write(d); - return; - } + if ((a & 0x00f9) == 0x0010) // PSG Sound + psg_write_68k(d); if ((a & 0x00e0) == 0x0000) { PicoVideoWrite(a, d); return; @@ -1198,8 +1215,7 @@ static void z80_md_vdp_br_write(unsigned int a, unsigned char data) { if ((a&0xfff9) == 0x7f11) // 7f11 7f13 7f15 7f17 { - if (PicoOpt & POPT_EN_PSG) - SN76496Write(data); + psg_write_z80(data); return; } // at least VDP data writes hang my machine diff --git a/pico/pico_cmn.c b/pico/pico_cmn.c index b39cfdb2..78fdd120 100644 --- a/pico/pico_cmn.c +++ b/pico/pico_cmn.c @@ -264,6 +264,8 @@ static int PicoFrameHints(void) PicoSyncZ80(cycles); if (PsndOut && ym2612.dacen && PsndDacLine < lines) PsndDoDAC(lines - 1); + if (PsndOut && PsndPsgLine < lines) + PsndDoPSG(lines - 1); #ifdef PICO_CD if (PicoAHW & PAHW_MCD) diff --git a/pico/pico_int.h b/pico/pico_int.h index 551dcbc7..12769315 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -822,10 +822,11 @@ PICO_INTERNAL_ASM void wram_1M_to_2M(unsigned char *m); PICO_INTERNAL void PsndReset(void); PICO_INTERNAL void PsndStartFrame(void); PICO_INTERNAL void PsndDoDAC(int line_to); +PICO_INTERNAL void PsndDoPSG(int line_to); PICO_INTERNAL void PsndClear(void); PICO_INTERNAL void PsndGetSamples(int y); PICO_INTERNAL void PsndGetSamplesMS(void); -extern int PsndDacLine; +extern int PsndDacLine, PsndPsgLine; // sms.c #ifndef NO_SMS diff --git a/pico/sound/sound.c b/pico/sound/sound.c index 8f88dd7c..510a9aba 100644 --- a/pico/sound/sound.c +++ b/pico/sound/sound.c @@ -19,7 +19,7 @@ void (*PsndMix_32_to_16l)(short *dest, int *src, int count) = mix_32_to_16l_ster // master int buffer to mix to static int PsndBuffer[2*(44100+100)/50]; -// dac +// dac, psg static unsigned short dac_info[312+4]; // pos in sample buffer // cdda output buffer @@ -30,7 +30,7 @@ int PsndRate=0; int PsndLen=0; // number of mono samples, multiply by 2 for stereo int PsndLen_exc_add=0; // this is for non-integer sample counts per line, eg. 22050/60 int PsndLen_exc_cnt=0; -int PsndDacLine=0; +int PsndDacLine, PsndPsgLine; short *PsndOut=NULL; // PCM data buffer static int PsndLen_use; @@ -158,7 +158,7 @@ PICO_INTERNAL void PsndStartFrame(void) PsndLen_use++; } - PsndDacLine = 0; + PsndDacLine = PsndPsgLine = 0; emustatus &= ~1; dac_info[224] = PsndLen_use; } @@ -185,13 +185,42 @@ PICO_INTERNAL void PsndDoDAC(int line_to) if (PicoOpt & POPT_EN_STEREO) { short *d = PsndOut + pos*2; - for (; len > 0; len--, d+=2) *d = dout; + for (; len > 0; len--, d+=2) *d += dout; } else { short *d = PsndOut + pos; - for (; len > 0; len--, d++) *d = dout; + for (; len > 0; len--, d++) *d += dout; } } +PICO_INTERNAL void PsndDoPSG(int line_to) +{ + int line_from = PsndPsgLine; + int pos, pos1, len; + int stereo = 0; + + if (line_to >= 312) + line_to = 311; + + pos = dac_info[line_from]; + pos1 = dac_info[line_to + 1]; + len = pos1 - pos; + //elprintf(EL_STATUS, "%3d %3d %3d %3d %3d", + // pos, pos1, len, line_from, line_to); + if (len <= 0) + return; + + PsndPsgLine = line_to + 1; + + if (!PsndOut || !(PicoOpt & POPT_EN_PSG)) + return; + + if (PicoOpt & POPT_EN_STEREO) { + stereo = 1; + pos <<= 1; + } + SN76496Update(PsndOut + pos, len, stereo); +} + // cdda static void cdda_raw_update(int *buffer, int length) { @@ -264,10 +293,6 @@ static int PsndRender(int offset, int length) pprof_start(sound); - // PSG - if (PicoOpt & POPT_EN_PSG) - SN76496Update(PsndOut+offset, length, stereo); - if (PicoAHW & PAHW_PICO) { PicoPicoPCMUpdate(PsndOut+offset, length, stereo); return length; @@ -319,6 +344,7 @@ PICO_INTERNAL void PsndGetSamples(int y) if (ym2612.dacen && PsndDacLine < y) PsndDoDAC(y - 1); + PsndDoPSG(y - 1); if (y == 224) { -- 2.39.5