From 2ec448a8ce6b0d929ba43748462109e46ca0bed4 Mon Sep 17 00:00:00 2001 From: kub Date: Wed, 11 May 2022 00:18:47 +0200 Subject: [PATCH] sound, fix ym2413 fm sound load/save --- pico/pico_int.h | 2 ++ pico/sound/sound.c | 30 ++++++++++++++++++++++++++---- pico/state.c | 23 ++++++++++++++--------- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/pico/pico_int.h b/pico/pico_int.h index 837953cf..15d151ba 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -879,6 +879,8 @@ void ym2612_unpack_state(void); Pico.t.timer_b_step = TIMER_B_TICK_ZCYCLES * 256; \ ym2612.OPN.ST.status &= ~3; +void *YM2413GetRegs(void); +void YM2413UnpackState(void); // videoport.c extern u32 SATaddr, SATmask; diff --git a/pico/sound/sound.c b/pico/sound/sound.c index 456d211b..74a40b58 100644 --- a/pico/sound/sound.c +++ b/pico/sound/sound.c @@ -29,11 +29,33 @@ extern int *sn76496_regs; // ym2413 #define YM2413_CLK 3579545 -OPLL old_opll; static OPLL *opll = NULL; -unsigned YM2413_reg; +static OPLL old_opll; +static struct { + uint32_t adr; + uint8_t reg[sizeof(opll->reg)]; +} opll_buf; + +PICO_INTERNAL void *YM2413GetRegs(void) +{ + memcpy(opll_buf.reg, opll->reg, sizeof(opll->reg)); + opll_buf.adr = opll->adr; + return &opll_buf; +} + +PICO_INTERNAL void YM2413UnpackState(void) +{ + int i; + + for (i = sizeof(opll->reg)-1; i >= 0; i--) { + OPLL_writeIO(opll, 0, i); + OPLL_writeIO(opll, 1, opll_buf.reg[i]); + } + opll->adr = opll_buf.adr; +} static resampler_t *fmresampler; +static int (*PsndFMUpdate)(s32 *buffer, int length, int stereo, int is_buf_empty); PICO_INTERNAL void PsndInit(void) { @@ -57,8 +79,6 @@ PICO_INTERNAL void PsndReset(void) timers_reset(); } -int (*PsndFMUpdate)(s32 *buffer, int length, int stereo, int is_buf_empty); - // FM polyphase FIR resampling #define FMFIR_TAPS 9 @@ -142,6 +162,8 @@ void PsndRerate(int preserve_state) if (preserve_state) memcpy(&old_opll, opll, sizeof(OPLL)); // remember old state OPLL_setRate(opll, PicoIn.sndRate); OPLL_reset(opll); + if (preserve_state) memcpy(&opll->adr, &old_opll.adr, sizeof(OPLL)-20); // restore old state + OPLL_forceRefresh(opll); } if (state) diff --git a/pico/state.c b/pico/state.c index cd6d4de2..63d2b377 100644 --- a/pico/state.c +++ b/pico/state.c @@ -16,7 +16,6 @@ // sn76496 & ym2413 extern int *sn76496_regs; -extern OPLL old_opll; static arearw *areaRead; static arearw *areaWrite; @@ -125,7 +124,6 @@ typedef enum { CHUNK_DRAM, CHUNK_32XPAL, CHUNK_32X_EVT, - CHUNK_YM2413, //40 //rename CHUNK_32X_FIRST = CHUNK_MSH2, CHUNK_32X_LAST = CHUNK_32X_EVT, @@ -134,6 +132,7 @@ typedef enum { CHUNK_CD_GFX, CHUNK_CD_CDC, CHUNK_CD_CDD, + CHUNK_YM2413, // CHUNK_DEFAULT_COUNT, CHUNK_CARTHW_ = CHUNK_CARTHW, // 64 (defined in PicoInt) @@ -225,7 +224,7 @@ static int state_save(void *file) { char sbuff[32] = "Saving.. "; unsigned char buff[0x60], buff_z80[Z80_STATE_SIZE]; - void *ym2612_regs = YM2612GetRegs(); + void *ym_regs = YM2612GetRegs(); void *buf2 = NULL; int ver = 0x0191; // not really used.. int retval = -1; @@ -245,14 +244,16 @@ static int state_save(void *file) CHECKED_WRITE_BUFF(CHUNK_VSRAM, PicoMem.vsram); CHECKED_WRITE_BUFF(CHUNK_IOPORTS, PicoMem.ioports); ym2612_pack_state(); - CHECKED_WRITE(CHUNK_FM, 0x200+4, ym2612_regs); + ym_regs = YM2612GetRegs(); + CHECKED_WRITE(CHUNK_FM, 0x200+4, ym_regs); if (!(PicoIn.opt & POPT_DIS_IDLE_DET)) SekInitIdleDet(); } else { CHECKED_WRITE_BUFF(CHUNK_SMS, Pico.ms); - CHECKED_WRITE_BUFF(CHUNK_YM2413, old_opll); + ym_regs = YM2413GetRegs(); + CHECKED_WRITE(CHUNK_YM2413, 0x40+4, ym_regs); } CHECKED_WRITE_BUFF(CHUNK_VRAM, PicoMem.vram); @@ -395,7 +396,7 @@ static int state_load(void *file) unsigned char buff_sh2[SH2_STATE_SIZE]; unsigned char *buf = NULL; unsigned char chunk; - void *ym2612_regs; + void *ym_regs; int len_check; int retval = -1; char header[8]; @@ -452,10 +453,14 @@ static int state_load(void *file) case CHUNK_IOPORTS: CHECKED_READ_BUFF(PicoMem.ioports); break; case CHUNK_PSG: CHECKED_READ2(28*4, sn76496_regs); break; - case CHUNK_YM2413: CHECKED_READ_BUFF(old_opll); break; + case CHUNK_YM2413: + ym_regs = YM2413GetRegs(); + CHECKED_READ2(0x40+4, ym_regs); + YM2413UnpackState(); + break; case CHUNK_FM: - ym2612_regs = YM2612GetRegs(); - CHECKED_READ2(0x200+4, ym2612_regs); + ym_regs = YM2612GetRegs(); + CHECKED_READ2(0x200+4, ym_regs); ym2612_unpack_state(); break; -- 2.39.2