--- uae/src/audio.c 2018/04/24 16:58:09 1.1.1.7 +++ uae/src/audio.c 2018/04/24 17:01:43 1.1.1.9 @@ -21,6 +21,7 @@ #include "sounddep/sound.h" #include "events.h" #include "audio.h" +#include "savestate.h" struct audio_channel_data audio_channel[6]; int sound_available = 0; @@ -631,7 +632,7 @@ static void audio_handler (int nr) cdp->state = 5; INTREQ(0x8000 | (0x80 << nr)); if (cdp->wlen != 1) - cdp->wlen--; + cdp->wlen = (cdp->wlen - 1) & 0xFFFF; cdp->nextdat = chipmem_bank.wget(cdp->pt); cdp->pt += 2; @@ -671,7 +672,7 @@ static void audio_handler (int nr) /* Period attachment? */ if (adkcon & (0x10 << nr)) { if (cdp->intreq2 && cdp->dmaen) - INTREQ(0x8000 | (0x80 << nr)); + INTREQ (0x8000 | (0x80 << nr)); cdp->intreq2 = 0; cdp->dat = cdp->nextdat; @@ -752,8 +753,8 @@ static void ahi_handler (int nr) cdp->state = 5; INTREQ (0xA000); if (cdp->wlen != 1) - cdp->wlen--; - cdp->nextdat = chipmem_bank.wget(cdp->pt); + cdp->wlen = (cdp->wlen - 1) & 0xFFFF; + cdp->nextdat = chipmem_bank.wget (cdp->pt); cdp->pt += 2; break; @@ -811,22 +812,37 @@ void aud3_handler (void) void audio_reset (void) { - memset (audio_channel, 0, sizeof audio_channel); - audio_channel[0].per = PERIOD_MAX; - audio_channel[1].per = PERIOD_MAX; - audio_channel[2].per = PERIOD_MAX; - audio_channel[3].per = PERIOD_MAX; + int i; + if (savestate_state != STATE_RESTORE) { + memset (audio_channel, 0, 4 * sizeof *audio_channel); + audio_channel[0].per = PERIOD_MAX; + audio_channel[1].per = PERIOD_MAX; + audio_channel[2].per = PERIOD_MAX; + audio_channel[3].per = PERIOD_MAX; + audio_channel[0].voltbl = sound_table[0]; + audio_channel[1].voltbl = sound_table[0]; + audio_channel[2].voltbl = sound_table[0]; + audio_channel[3].voltbl = sound_table[0]; + } else + for (i = 0; i < 4; i++) + audio_channel[i].dmaen = (dmacon & 0x200) && (dmacon & (1 << i)); + + + memset (audio_channel + 4, 0, 2 * sizeof *audio_channel); audio_channel[4].per = PERIOD_MAX; audio_channel[5].per = PERIOD_MAX; - audio_channel[0].voltbl = sound_table[0]; - audio_channel[1].voltbl = sound_table[0]; - audio_channel[2].voltbl = sound_table[0]; - audio_channel[3].voltbl = sound_table[0]; + +#ifndef MULTIPLICATION_PROFITABLE + for (i = 0; i < 6; i++) + audio_channel[nr].voltbl = sound_table[audio_channel[nr].vol]; +#endif last_cycles = 0; ahi_enabled = 0; ahi_interrupt_state = 0; next_sample_evtime = scaled_sample_evtime; + + schedule_audio (); } STATIC_INLINE int sound_prefs_changed (void) @@ -834,6 +850,7 @@ STATIC_INLINE int sound_prefs_changed (v return (changed_prefs.produce_sound != currprefs.produce_sound || changed_prefs.stereo != currprefs.stereo || changed_prefs.mixed_stereo != currprefs.mixed_stereo + || changed_prefs.sound_maxbsiz != currprefs.sound_maxbsiz || changed_prefs.sound_freq != currprefs.sound_freq || changed_prefs.sound_bits != currprefs.sound_bits); } @@ -848,7 +865,7 @@ void check_prefs_changed_audio (void) currprefs.mixed_stereo = changed_prefs.mixed_stereo; currprefs.sound_bits = changed_prefs.sound_bits; currprefs.sound_freq = changed_prefs.sound_freq; - + currprefs.sound_maxbsiz = changed_prefs.sound_maxbsiz; if (currprefs.produce_sound >= 2) { if (init_audio ()) { last_cycles = get_cycles () - 1; @@ -878,7 +895,6 @@ void check_prefs_changed_audio (void) : currprefs.sound_interpol == 1 ? sample16si_rh_handler : sample16si_crux_handler); if (currprefs.produce_sound == 0) { - memset (audio_channel, 0, sizeof audio_channel); eventtab[ev_audio].active = 0; events_schedule (); } @@ -888,7 +904,7 @@ void update_audio (void) { unsigned long int n_cycles; - if (currprefs.produce_sound == 0) + if (currprefs.produce_sound == 0 || savestate_state == STATE_RESTORE) return; n_cycles = get_cycles () - last_cycles; @@ -995,6 +1011,15 @@ void AUDxPER (int nr, uae_u16 v) if (per < maxhpos * CYCLE_UNIT / 2 && currprefs.produce_sound < 3) per = maxhpos * CYCLE_UNIT / 2; + if (audio_channel[nr].per == PERIOD_MAX + && per != PERIOD_MAX) + { + audio_channel[nr].evtime = CYCLE_UNIT; + if (currprefs.produce_sound > 0) { + schedule_audio (); + events_schedule (); + } + } audio_channel[nr].per = per; } @@ -1066,6 +1091,8 @@ static uae_u32 ahi_entry (void) return 1; case 5: return ahi_interrupt_state; + default: + return 0; } } @@ -1077,3 +1104,55 @@ void ahi_install (void) dw (RTS); org (a); } + +/* audio save/restore code FIXME: not working correctly */ +/* help needed */ + +uae_u8 *restore_audio (uae_u8 *src, int i) +{ + struct audio_channel_data *acd; + uae_u16 p; + + acd = audio_channel + i; + acd->state = restore_u8 (); + acd->vol = restore_u8 (); + acd->intreq2 = restore_u8 (); + acd->data_written = restore_u8 (); + acd->len = restore_u16 (); + acd->wlen = restore_u16 (); + p = restore_u16 (); + acd->per = p ? p * CYCLE_UNIT : PERIOD_MAX; + p = restore_u16 (); + acd->wper = p ? p * CYCLE_UNIT : PERIOD_MAX; + acd->lc = restore_u32 (); + acd->pt = restore_u32 (); + acd->evtime = restore_u32 (); + + return src; +} + + +uae_u8 *save_audio (int *len, int i) +{ + struct audio_channel_data *acd; + uae_u8 *dst = malloc (100); + uae_u8 *dstbak = dst; + uae_u16 p; + + acd = audio_channel + i; + save_u8 ((uae_u8)acd->state); + save_u8 (acd->vol); + save_u8 (acd->intreq2); + save_u8 (acd->data_written); + save_u16 (acd->len); + save_u16 (acd->wlen); + p = acd->per == PERIOD_MAX ? 0 : acd->per / CYCLE_UNIT; + save_u16 (p); + p = acd->per == PERIOD_MAX ? 0 : acd->wper / CYCLE_UNIT; + save_u16 (p); + save_u32 (acd->lc); + save_u32 (acd->pt); + save_u32 (acd->evtime); + *len = dst - dstbak; + return dstbak; +}