From a5a9ccfa400b49d212f90ee16d090ef53b476b4a Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Thu, 17 Nov 2022 19:57:24 +0200 Subject: [PATCH] Fix audio timing (previous interrupt timing fix made previously fixed values incorrect) --- audio.cpp | 63 ++++++++++++++++++++++-------------------------------- custom.cpp | 28 +++++++++++++----------- 2 files changed, 40 insertions(+), 51 deletions(-) diff --git a/audio.cpp b/audio.cpp index 74385f23..3c08caa2 100644 --- a/audio.cpp +++ b/audio.cpp @@ -1402,55 +1402,46 @@ static void update_volume(int nr, uae_u16 v) cdp->data.audvol = v; } -uae_u16 audio_dmal (void) +uae_u16 audio_dmal(void) { uae_u16 dmal = 0; for (int nr = 0; nr < AUDIO_CHANNELS_PAULA; nr++) { struct audio_channel_data *cdp = audio_channel + nr; if (cdp->dr) - dmal |= 1 << (nr * 2); - if (cdp->dsr) dmal |= 1 << (nr * 2 + 1); + if (cdp->dsr) + dmal |= 1 << (nr * 2 + 0); cdp->dr = cdp->dsr = false; } return dmal; } -static int isirq (int nr) +static int isirq(int nr) { - return INTREQR () & (0x80 << nr); + return INTREQR() & (0x80 << nr); } -static void audio_setirq_event(uae_u32 nr) -{ - INTREQ_0 (0x8000 | (0x80 << nr)); -} - -static void setirq (int nr, int which) +static void setirq(int nr, int which) { #if DEBUG_AUDIO > 0 struct audio_channel_data *cdp = audio_channel + nr; if (debugchannel (nr) && cdp->wlen > 1) write_log (_T("SETIRQ%d (%d,%d) PC=%08X\n"), nr, which, isirq (nr) ? 1 : 0, M68K_GETPC); #endif - // audio interrupts are delayed by 2 cycles - if (!currprefs.cachesize && currprefs.cpu_compatible) { - event2_newevent_xx (-1, 2 * CYCLE_UNIT + CYCLE_UNIT / 2, nr, audio_setirq_event); - } else { - audio_setirq_event(nr); - } + // audio interrupts are delayed by 1 CCK + INTREQ_INT(nr + 7, CYCLE_UNIT); } -static void newsample (int nr, sample8_t sample) +static void newsample(int nr, sample8_t sample) { struct audio_channel_data *cdp = audio_channel + nr; #if DEBUG_AUDIO > 0 - if (!debugchannel (nr)) + if (!debugchannel(nr)) sample = 0; #endif #if DEBUG_AUDIO > 2 - if (debugchannel (nr)) - write_log (_T("SAMPLE%d: %02x\n"), nr, sample & 0xff); + if (debugchannel(nr)) + write_log(_T("SAMPLE%d: %02x\n"), nr, sample & 0xff); #endif if (!(audio_channel_mask & (1 << nr))) sample = 0; @@ -2380,7 +2371,7 @@ static void audxdat_func(uae_u32 v) cdp->dat_written = false; } -void AUDxDAT (int nr, uae_u16 v, uaecptr addr) +void AUDxDAT(int nr, uae_u16 v, uaecptr addr) { struct audio_channel_data *cdp = audio_channel + nr; int chan_ena = (dmacon & DMA_MASTER) && (dmacon & (1 << nr)); @@ -2412,13 +2403,9 @@ void AUDxDAT (int nr, uae_u16 v, uaecptr addr) } uae_u32 vv = nr | (chan_ena ? 0x80 : 0) | (v << 8); if (!currprefs.cachesize && (cdp->per < PERIOD_LOW * CYCLE_UNIT || currprefs.cpu_compatible)) { - int cyc; + int cyc = 0; if (chan_ena) { - // AUDxLEN is processed after 2 cycle delay - cyc = 2 * CYCLE_UNIT; - } else if (cdp->state == 0) { - cyc = 1 * CYCLE_UNIT; - } else { + // AUDxLEN is processed after 1 CCK delay cyc = 1 * CYCLE_UNIT; } if (cyc > 0) { @@ -2430,12 +2417,12 @@ void AUDxDAT (int nr, uae_u16 v, uaecptr addr) audxdat_func(vv); } } -void AUDxDAT (int nr, uae_u16 v) +void AUDxDAT(int nr, uae_u16 v) { - AUDxDAT (nr, v, 0xffffffff); + AUDxDAT(nr, v, 0xffffffff); } -uaecptr audio_getpt (int nr, bool reset) +uaecptr audio_getpt(int nr, bool reset) { struct audio_channel_data *cdp = audio_channel + nr; uaecptr p = cdp->pt; @@ -2443,14 +2430,14 @@ uaecptr audio_getpt (int nr, bool reset) if (reset) cdp->pt = cdp->lc; cdp->ptx_tofetch = false; - return p; + return p & ~1; } -void AUDxLCH (int nr, uae_u16 v) +void AUDxLCH(int nr, uae_u16 v) { struct audio_channel_data *cdp = audio_channel + nr; - audio_activate (); - update_audio (); + audio_activate(); + update_audio(); // someone wants to update PT but DSR has not yet been processed. // too fast CPU and some tracker players: enable DMA, CPU delay, update AUDxPT with loop position @@ -2475,11 +2462,11 @@ void AUDxLCH (int nr, uae_u16 v) } } -void AUDxLCL (int nr, uae_u16 v) +void AUDxLCL(int nr, uae_u16 v) { struct audio_channel_data *cdp = audio_channel + nr; - audio_activate (); - update_audio (); + audio_activate(); + update_audio(); if (usehacks() && ((cdp->ptx_tofetch && cdp->state == 1) || cdp->ptx_written)) { static int warned = 100; cdp->ptx = cdp->lc; diff --git a/custom.cpp b/custom.cpp index 6d9a612a..767ca08d 100644 --- a/custom.cpp +++ b/custom.cpp @@ -11484,7 +11484,7 @@ static void hsync_scandoubler(int hpos) reset_scandoubler_sync(hpos); } -static void dmal_emu(uae_u32 v) +static void dmal_emu(uae_u32 val) { // Disk and Audio DMA bits are ignored by Agnus. Including DMA master bit. int hpos = current_hpos(); @@ -11495,11 +11495,13 @@ static void dmal_emu(uae_u32 v) return; } } + int dmalbits = val & 3; + int dmalpos = val >> 8; - if (v >= 6 && v < 14) { - v -= 6; - int nr = v / 2; - uaecptr pt = audio_getpt(nr, (v & 1) != 0); + if (dmalpos >= 6 && dmalpos < 14) { + dmalpos -= 6; + int nr = dmalpos / 2; + uaecptr pt = audio_getpt(nr, (dmalbits & 1) != 0); if (dmal_ce) { #ifdef DEBUGGER if (debug_dma) { @@ -11523,9 +11525,9 @@ static void dmal_emu(uae_u32 v) } regs.chipset_latch_rw = last_custom_value = dat; AUDxDAT(nr, dat, pt); - } else if (v >= 0 && v < 6) { + } else if (dmalpos >= 0 && dmalpos < 6) { uae_u16 dat = 0; - int w = v & 1; + int w = (dmalbits & 3) == 3; // disk_fifostatus() needed in >100% disk speed modes if (w) { // write to disk @@ -11534,7 +11536,7 @@ static void dmal_emu(uae_u32 v) if (dmal_ce) { #ifdef DEBUGGER if (debug_dma) { - record_dma_read(0x26, pt, hpos, vpos, DMARECORD_DISK, v / 2); + record_dma_read(0x26, pt, hpos, vpos, DMARECORD_DISK, dmalpos / 2); } if (memwatch_enabled) { debug_getpeekdma_chipram(pt, MW_MASK_DISK, 0x26, 0x20); @@ -11563,7 +11565,7 @@ static void dmal_emu(uae_u32 v) if (dmal_ce) { #ifdef DEBUGGER if (debug_dma) { - record_dma_write(0x08, dat, pt, hpos, vpos, DMARECORD_DISK, v / 2); + record_dma_write(0x08, dat, pt, hpos, vpos, DMARECORD_DISK, dmalpos / 2); } if (memwatch_enabled) { debug_putpeekdma_chipram(pt, dat, MW_MASK_DISK, 0x08, 0x20); @@ -11575,7 +11577,7 @@ static void dmal_emu(uae_u32 v) } } } else { - write_log(_T("invalid DMAL position %d\n"), v); + write_log(_T("invalid DMAL position %d\n"), dmalpos); } } @@ -11589,7 +11591,7 @@ static void dmal_func2(uae_u32 v) { while (dmal) { if (dmal & 3) { - dmal_emu(dmal_hpos + ((dmal & 2) ? 1 : 0)); + dmal_emu((dmal_hpos << 8) | (dmal & 3)); } dmal_hpos += 2; dmal >>= 2; @@ -11612,10 +11614,10 @@ static void events_dmal(int hpos) dmal_hpos += 2; } dmal_ce = true; - event2_newevent2(hpos, dmal_hpos + ((dmal & 2) ? 1 : 0), dmal_func); + event2_newevent2(hpos, (dmal_hpos << 8) | (dmal & 3), dmal_func); dmal &= ~3; } else { - event2_newevent2(hpos, dmal_hpos, dmal_func2); + event2_newevent2(hpos, 0, dmal_func2); } } -- 2.47.3